change mdelay with workqueue of gps resume
authorlinjh <linjh@rock-chips.com>
Wed, 20 Apr 2011 02:09:36 +0000 (10:09 +0800)
committerlinjh <linjh@rock-chips.com>
Wed, 20 Apr 2011 02:12:01 +0000 (10:12 +0800)
drivers/misc/gps/rk29_gps.c
drivers/misc/gps/rk29_gps.h

index a40e342c1190a920be4e7f5518bc840ac3728290..f36b9cc43e0250014d616d48f13e5e619ff87c2b 100644 (file)
@@ -11,6 +11,8 @@
 #include <mach/gpio.h>\r
 #include <mach/iomux.h>\r
 #include <linux/platform_device.h>\r
+#include <asm/uaccess.h>\r
+#include <linux/wait.h>\r
 #include "rk29_gps.h"\r
 #if 0\r
 #define DBG(x...)      printk(KERN_INFO x)\r
@@ -111,9 +113,8 @@ int rk29_gps_suspend(struct platform_device *pdev,  pm_message_t state)
                \r
        if(pdata->power_flag == 1)\r
        {\r
-               rk29_gps_uart_to_gpio(pdata->uart_id);\r
-               pdata->power_down();    \r
-               pdata->reset(GPIO_LOW);\r
+               pdata->suspend = 1;\r
+               queue_work(pdata->wq, &pdata->work);\r
        }\r
        \r
        printk("%s\n",__FUNCTION__);\r
@@ -130,6 +131,36 @@ int rk29_gps_resume(struct platform_device *pdev)
        \r
        if(pdata->power_flag == 1)\r
        {\r
+               pdata->suspend = 0;\r
+               queue_work(pdata->wq, &pdata->work);\r
+       }\r
+       \r
+       printk("%s\n",__FUNCTION__);\r
+\r
+       return 0;\r
+}\r
+\r
+static void rk29_gps_delay_power_downup(struct work_struct *work)\r
+{\r
+       //int ret;\r
+       struct rk29_gps_data *pdata = container_of(work, struct rk29_gps_data, work);\r
+       if (pdata == NULL) {\r
+               printk("%s: pdata = NULL\n", __func__);\r
+               return;\r
+       }\r
+\r
+       down(&pdata->power_sem);\r
+       //if (ret < 0) {\r
+       //      printk("%s: down power_sem error ret = %d\n", __func__, ret);\r
+       //      return ;\r
+       //}\r
+       \r
+    if (pdata->suspend) {\r
+               rk29_gps_uart_to_gpio(pdata->uart_id);\r
+               pdata->power_down();    \r
+               pdata->reset(GPIO_LOW);\r
+       }\r
+       else {\r
                pdata->reset(GPIO_LOW);\r
                mdelay(10);\r
                pdata->power_up();\r
@@ -137,10 +168,7 @@ int rk29_gps_resume(struct platform_device *pdev)
                pdata->reset(GPIO_HIGH);\r
                rk29_gps_gpio_to_uart(pdata->uart_id);\r
        }\r
-       \r
-       printk("%s\n",__FUNCTION__);\r
-\r
-       return 0;\r
+       up(&pdata->power_sem);\r
 }\r
 \r
 int rk29_gps_open(struct inode *inode, struct file *filp)\r
@@ -150,6 +178,18 @@ int rk29_gps_open(struct inode *inode, struct file *filp)
        return 0;\r
 }\r
 \r
+ssize_t rk29_gps_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos)\r
+{\r
+       if (ptr == NULL)\r
+               printk("%s: user space address is NULL\n", __func__);\r
+       if (pgps == NULL)\r
+               printk("%s: pgps addr is NULL\n", __func__);\r
+\r
+       put_user(pgps->uart_id, ptr);\r
+       \r
+       return sizeof(int);\r
+}\r
+\r
 int rk29_gps_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)\r
 {\r
        int ret = 0;\r
@@ -181,7 +221,7 @@ int rk29_gps_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, uns
                        pdata->reset(GPIO_LOW);\r
                        pdata->power_flag = 0;\r
                        break;\r
-                       \r
+\r
                default:\r
                        printk("unknown ioctl cmd!\n");\r
                        up(&pdata->power_sem);\r
@@ -205,6 +245,7 @@ int rk29_gps_release(struct inode *inode, struct file *filp)
 static struct file_operations rk29_gps_fops = {\r
        .owner   = THIS_MODULE,\r
        .open    = rk29_gps_open,\r
+       .read    = rk29_gps_read,\r
        .ioctl   = rk29_gps_ioctl,\r
        .release = rk29_gps_release,\r
 };\r
@@ -219,7 +260,6 @@ static struct miscdevice rk29_gps_dev =
 static int rk29_gps_probe(struct platform_device *pdev)\r
 {\r
        int ret = 0;\r
-       printk("\n\n=========================\n%s\n", __func__);\r
        struct rk29_gps_data *pdata = pdev->dev.platform_data;\r
        if(!pdata)\r
                return -1;\r
@@ -231,7 +271,10 @@ static int rk29_gps_probe(struct platform_device *pdev)
        }\r
        \r
        init_MUTEX(&pdata->power_sem);\r
+       pdata->wq = create_freezeable_workqueue("rk29_gps");\r
+       INIT_WORK(&pdata->work, rk29_gps_delay_power_downup);\r
        pdata->power_flag = 0;\r
+       pdata->suspend = 0;\r
 \r
        pgps = pdata;\r
 \r
@@ -241,8 +284,21 @@ static int rk29_gps_probe(struct platform_device *pdev)
        return ret;\r
 }\r
 \r
+static int rk29_gps_remove(struct platform_device *pdev)\r
+{\r
+       struct rk29_gps_data *pdata = pdev->dev.platform_data;\r
+       if(!pdata)\r
+               return -1;\r
+\r
+       misc_deregister(&rk29_gps_dev);\r
+       destroy_workqueue(pdata->wq);\r
+\r
+       return 0;\r
+}\r
+\r
 static struct platform_driver rk29_gps_driver = {\r
        .probe  = rk29_gps_probe,\r
+       .remove = rk29_gps_remove,\r
        .suspend        = rk29_gps_suspend,\r
        .resume         = rk29_gps_resume,\r
        .driver = {\r
index 9e22ff5fd51729ff36dddb884652db84c38da9e5..75ce567a35b8257c2667ad06f8a2e2995d59e32a 100644 (file)
@@ -11,7 +11,10 @@ struct rk29_gps_data {
        int (*reset)(int);\r
        int uart_id;\r
        int power_flag;\r
+       int suspend;\r
        struct semaphore power_sem;\r
+       struct workqueue_struct *wq;\r
+       struct work_struct work;\r
 };\r
 \r
 #endif\r