#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
\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
\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
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
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
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
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
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
}\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
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