内核定时器的使用

来源:互联网 发布:印刷调色软件 编辑:程序博客网 时间:2024/04/25 08:07
From dc7013bdf97c15b8438370d70979628e1dd87f05 Mon Sep 17 00:00:00 2001
From: raymond.wang <raymond1860@gmail.com>
Date: Mon, 28 Apr 2014 12:25:18 +0800
Subject: [PATCH] Fix #1 issue on bitbucket that we add a workaround for ehci hallted state

---
 .../linux-2.6.34/drivers/usb/host/ehci-pxau2h.c    |   34 ++++++++++++++++++-
 .../linux-2.6.34/drivers/usb/host/ehci-pxau2o.c    |   35 +++++++++++++++++++-
 2 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2h.c b/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2h.c
index d1227e7..920b005 100755
--- a/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2h.c
+++ b/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2h.c
@@ -23,10 +23,33 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <plat/pxa_u2o.h>
-
+#include <linux/timer.h>
+#include <linux/reboot.h>
+#ifndef EHCI_WATCHDOG_MSECS
+#define EHCI_WATCHDOG_MSECS 5000
+#endif
 static struct pxa_usb_plat_info *info;
 static const char *pxau2h_driver_name = "pxau2h-ehci";
 
+static struct timer_list pxau2h_watchdog;
+
+static void pxau2h_watchdog_handler(unsigned long param)
+{
+    struct usb_hcd *hcd=(struct usb_hcd *)param;
+    //check
+    if(hcd->state==HC_STATE_HALT){
+        printk("\n\nEHCI halted,restart\n\n");
+        /*
+         * This will not be a clean reboot, with everything
+         * shutting down.  But if there is a chance of
+         * rebooting the system it will be rebooted.
+         */
+        emergency_restart();
+    }else {
+        mod_timer(&pxau2h_watchdog,
+                jiffies + msecs_to_jiffies(EHCI_WATCHDOG_MSECS));
+    }
+}
 static int pxau2h_ehci_clk_set(int en)
 {
     struct clk *clk = NULL;
@@ -229,6 +252,13 @@ static int pxau2h_ehci_probe(struct platform_device *pdev)
         goto err2;
     }
     platform_set_drvdata(pdev, hcd);
+
+    init_timer(&pxau2h_watchdog);
+    pxau2h_watchdog.function = pxau2h_watchdog_handler;
+    pxau2h_watchdog.data = (unsigned long)hcd;
+    mod_timer(&pxau2h_watchdog,
+            jiffies + msecs_to_jiffies(EHCI_WATCHDOG_MSECS));
+
     return retval;
 
 err2:
@@ -245,6 +275,8 @@ static int pxau2h_ehci_remove(struct platform_device *pdev)
     if (HC_IS_RUNNING(hcd->state))
         hcd->state = HC_STATE_QUIESCING;
 
+    del_timer_sync(&pxau2h_watchdog);
+
     usb_disconnect(&hcd->self.root_hub);
     hcd->driver->stop(hcd);
 
diff --git a/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2o.c b/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2o.c
index a03c19d..6620c6d 100755
--- a/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2o.c
+++ b/src/preview-kit/linux-2.6.34/drivers/usb/host/ehci-pxau2o.c
@@ -21,7 +21,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-
+#include <linux/timer.h>
+#include <linux/reboot.h>
 #include <plat/pxa_u2o.h>
 #include <linux/clk.h>
 
@@ -29,9 +30,32 @@
 #include <linux/usb/otg.h>
 #endif
 
+#ifndef EHCI_WATCHDOG_MSECS
+#define EHCI_WATCHDOG_MSECS 5000
+#endif
 static struct pxa_usb_plat_info *u2o_info;
 static struct ehci_hcd         *g_ehci;
 
+static struct timer_list pxau2o_watchdog;
+
+static void pxau2o_watchdog_handler(unsigned long param)
+{
+    struct usb_hcd *hcd=(struct usb_hcd *)param;
+    //check
+    if(hcd->state==HC_STATE_HALT){
+        printk("\n\nEHCI_U2O halted,restart\n\n");
+        /*
+         * This will not be a clean reboot, with everything
+         * shutting down.  But if there is a chance of
+         * rebooting the system it will be rebooted.
+         */
+        emergency_restart();
+    }else {
+        mod_timer(&pxau2o_watchdog,
+                jiffies + msecs_to_jiffies(EHCI_WATCHDOG_MSECS));
+    }
+}
+
 void pxa9xx_u2o_host_enable (void)
 {
     unsigned base = (unsigned)(&g_ehci->regs->command) & 0xfffff000;
@@ -325,6 +349,13 @@ static int pxa9xx_ehci_probe(struct platform_device *pdev)
         ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 
     clk_disable(clk_get(NULL, "U2OCLK"));
+
+    init_timer(&pxau2o_watchdog);
+    pxau2o_watchdog.function = pxau2o_watchdog_handler;
+    pxau2o_watchdog.data = (unsigned long)hcd;
+    mod_timer(&pxau2o_watchdog,
+            jiffies + msecs_to_jiffies(EHCI_WATCHDOG_MSECS));
+
     return 0;
 
 err2:
@@ -343,6 +374,8 @@ static int pxa9xx_ehci_remove(struct platform_device *dev)
     if (HC_IS_RUNNING(hcd->state))
         hcd->state = HC_STATE_QUIESCING;
 
+    del_timer_sync(&pxau2o_watchdog);
+
     usb_disconnect(&hcd->self.root_hub);
     hcd->driver->stop (hcd);
     
--
1.7.0.4



例子如上:

其实就是三个步骤:

1.定义一个内核定时器

2.初始化内核定时器,已经内核定时器的数据和定时行数以及超时时间

3.把定时器加入链表(有两种加法,int add_timer(struct timer_list *timer);   int mod_timer(struct timer_list *timer, unsigned long expires);)


4,在不需要的时候,删除定时器即可(int del_timer_sync(struct timer_list *timer);int del_timer(struct timer_list *timer);)

0 0