From 89863e3e232d6b7d66477d5eb7965891de89efad Mon Sep 17 00:00:00 2001 From: linjh Date: Wed, 20 Apr 2011 10:09:36 +0800 Subject: [PATCH] change mdelay with workqueue of gps resume --- drivers/misc/gps/rk29_gps.c | 74 ++++++++++++++++++++++++++++++++----- drivers/misc/gps/rk29_gps.h | 3 ++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/drivers/misc/gps/rk29_gps.c b/drivers/misc/gps/rk29_gps.c index a40e342c1190..f36b9cc43e02 100644 --- a/drivers/misc/gps/rk29_gps.c +++ b/drivers/misc/gps/rk29_gps.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "rk29_gps.h" #if 0 #define DBG(x...) printk(KERN_INFO x) @@ -111,9 +113,8 @@ int rk29_gps_suspend(struct platform_device *pdev, pm_message_t state) if(pdata->power_flag == 1) { - rk29_gps_uart_to_gpio(pdata->uart_id); - pdata->power_down(); - pdata->reset(GPIO_LOW); + pdata->suspend = 1; + queue_work(pdata->wq, &pdata->work); } printk("%s\n",__FUNCTION__); @@ -130,6 +131,36 @@ int rk29_gps_resume(struct platform_device *pdev) if(pdata->power_flag == 1) { + pdata->suspend = 0; + queue_work(pdata->wq, &pdata->work); + } + + printk("%s\n",__FUNCTION__); + + return 0; +} + +static void rk29_gps_delay_power_downup(struct work_struct *work) +{ + //int ret; + struct rk29_gps_data *pdata = container_of(work, struct rk29_gps_data, work); + if (pdata == NULL) { + printk("%s: pdata = NULL\n", __func__); + return; + } + + down(&pdata->power_sem); + //if (ret < 0) { + // printk("%s: down power_sem error ret = %d\n", __func__, ret); + // return ; + //} + + if (pdata->suspend) { + rk29_gps_uart_to_gpio(pdata->uart_id); + pdata->power_down(); + pdata->reset(GPIO_LOW); + } + else { pdata->reset(GPIO_LOW); mdelay(10); pdata->power_up(); @@ -137,10 +168,7 @@ int rk29_gps_resume(struct platform_device *pdev) pdata->reset(GPIO_HIGH); rk29_gps_gpio_to_uart(pdata->uart_id); } - - printk("%s\n",__FUNCTION__); - - return 0; + up(&pdata->power_sem); } int rk29_gps_open(struct inode *inode, struct file *filp) @@ -150,6 +178,18 @@ int rk29_gps_open(struct inode *inode, struct file *filp) return 0; } +ssize_t rk29_gps_read(struct file *filp, char __user *ptr, size_t size, loff_t *pos) +{ + if (ptr == NULL) + printk("%s: user space address is NULL\n", __func__); + if (pgps == NULL) + printk("%s: pgps addr is NULL\n", __func__); + + put_user(pgps->uart_id, ptr); + + return sizeof(int); +} + int rk29_gps_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int ret = 0; @@ -181,7 +221,7 @@ int rk29_gps_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, uns pdata->reset(GPIO_LOW); pdata->power_flag = 0; break; - + default: printk("unknown ioctl cmd!\n"); up(&pdata->power_sem); @@ -205,6 +245,7 @@ int rk29_gps_release(struct inode *inode, struct file *filp) static struct file_operations rk29_gps_fops = { .owner = THIS_MODULE, .open = rk29_gps_open, + .read = rk29_gps_read, .ioctl = rk29_gps_ioctl, .release = rk29_gps_release, }; @@ -219,7 +260,6 @@ static struct miscdevice rk29_gps_dev = static int rk29_gps_probe(struct platform_device *pdev) { int ret = 0; - printk("\n\n=========================\n%s\n", __func__); struct rk29_gps_data *pdata = pdev->dev.platform_data; if(!pdata) return -1; @@ -231,7 +271,10 @@ static int rk29_gps_probe(struct platform_device *pdev) } init_MUTEX(&pdata->power_sem); + pdata->wq = create_freezeable_workqueue("rk29_gps"); + INIT_WORK(&pdata->work, rk29_gps_delay_power_downup); pdata->power_flag = 0; + pdata->suspend = 0; pgps = pdata; @@ -241,8 +284,21 @@ static int rk29_gps_probe(struct platform_device *pdev) return ret; } +static int rk29_gps_remove(struct platform_device *pdev) +{ + struct rk29_gps_data *pdata = pdev->dev.platform_data; + if(!pdata) + return -1; + + misc_deregister(&rk29_gps_dev); + destroy_workqueue(pdata->wq); + + return 0; +} + static struct platform_driver rk29_gps_driver = { .probe = rk29_gps_probe, + .remove = rk29_gps_remove, .suspend = rk29_gps_suspend, .resume = rk29_gps_resume, .driver = { diff --git a/drivers/misc/gps/rk29_gps.h b/drivers/misc/gps/rk29_gps.h index 9e22ff5fd517..75ce567a35b8 100644 --- a/drivers/misc/gps/rk29_gps.h +++ b/drivers/misc/gps/rk29_gps.h @@ -11,7 +11,10 @@ struct rk29_gps_data { int (*reset)(int); int uart_id; int power_flag; + int suspend; struct semaphore power_sem; + struct workqueue_struct *wq; + struct work_struct work; }; #endif -- 2.34.1