From eee62cb9f190ce9b3afecaf6b500b4547c9b13c3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Wed, 13 Apr 2011 15:09:58 +0800 Subject: [PATCH] rk29: usb detect plug in/out both --- arch/arm/mach-rk29/board-rk29-ddr3sdk.c | 2 +- arch/arm/mach-rk29/board-rk29-fih.c | 2 +- arch/arm/mach-rk29/board-rk29sdk.c | 2 +- arch/arm/mach-rk29/include/mach/board.h | 4 +-- arch/arm/mach-rk29/usb_detect.c | 42 ++++++++++++++++++++----- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c index d72a6767e93d..574c598ea60c 100755 --- a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c +++ b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c @@ -1855,7 +1855,7 @@ static void __init machine_rk29_board_init(void) rk29sdk_init_wifi_mem(); #endif - board_usb_detect_init(RK29_PIN0_PA0, IRQF_TRIGGER_FALLING); + board_usb_detect_init(RK29_PIN0_PA0); } static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tags, diff --git a/arch/arm/mach-rk29/board-rk29-fih.c b/arch/arm/mach-rk29/board-rk29-fih.c index 1247f8c8d35c..f796e1dd7b3f 100755 --- a/arch/arm/mach-rk29/board-rk29-fih.c +++ b/arch/arm/mach-rk29/board-rk29-fih.c @@ -2292,7 +2292,7 @@ static void __init machine_rk29_board_init(void) rk29sdk_init_wifi_mem(); #endif - board_usb_detect_init(RK29_PIN0_PA0, IRQF_TRIGGER_FALLING); + board_usb_detect_init(RK29_PIN0_PA0); } static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tags, diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 6c57cb461bc0..018cdf2b036d 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -1879,7 +1879,7 @@ static void __init machine_rk29_board_init(void) rk29sdk_init_wifi_mem(); #endif - board_usb_detect_init(RK29_PIN0_PA0, IRQF_TRIGGER_FALLING); + board_usb_detect_init(RK29_PIN0_PA0); } static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tags, diff --git a/arch/arm/mach-rk29/include/mach/board.h b/arch/arm/mach-rk29/include/mach/board.h index fe03a22769ed..29d90dedbbef 100755 --- a/arch/arm/mach-rk29/include/mach/board.h +++ b/arch/arm/mach-rk29/include/mach/board.h @@ -252,9 +252,9 @@ enum periph_pll{ /* for USB detection */ #ifdef CONFIG_USB_GADGET -int board_usb_detect_init(unsigned gpio, unsigned long flags); +int board_usb_detect_init(unsigned gpio); #else -static int inline board_usb_detect_init(unsigned gpio, unsigned long flags) { return 0; } +static int inline board_usb_detect_init(unsigned gpio) { return 0; } #endif /* for wakeup Android */ diff --git a/arch/arm/mach-rk29/usb_detect.c b/arch/arm/mach-rk29/usb_detect.c index 51339a520899..a71a60c8a823 100644 --- a/arch/arm/mach-rk29/usb_detect.c +++ b/arch/arm/mach-rk29/usb_detect.c @@ -4,26 +4,45 @@ #include #include -static void do_wakeup(struct work_struct *work) +static irqreturn_t usb_detect_irq_handler(int irq, void *dev_id); +static int detect_gpio = INVALID_GPIO; + +static void usb_detect_do_wakeup(struct work_struct *work) { + int ret; + int irq = gpio_to_irq(detect_gpio); + unsigned long flags; + rk28_send_wakeup_key(); + free_irq(irq, NULL); + flags = gpio_get_value(detect_gpio) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; + ret = request_irq(irq, usb_detect_irq_handler, flags, "usb_detect", NULL); + if (ret < 0) { + pr_err("%s: request_irq(%d) failed\n", __func__, irq); + } } -static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup); +static DECLARE_DELAYED_WORK(wakeup_work, usb_detect_do_wakeup); static bool wakelock_inited; static struct wake_lock usb_wakelock; -static irqreturn_t detect_irq_handler(int irq, void *dev_id) +static irqreturn_t usb_detect_irq_handler(int irq, void *dev_id) { - wake_lock_timeout(&usb_wakelock, 10 * HZ); + wake_lock_timeout(&usb_wakelock, 10 * HZ); schedule_delayed_work(&wakeup_work, HZ / 10); - return IRQ_HANDLED; + return IRQ_HANDLED; } -int board_usb_detect_init(unsigned gpio, unsigned long flags) +int board_usb_detect_init(unsigned gpio) { int ret; int irq = gpio_to_irq(gpio); + unsigned long flags; + + if (detect_gpio != INVALID_GPIO) { + pr_err("only support call %s once\n", __func__); + return -EINVAL; + } ret = gpio_request(gpio, "usb_detect"); if (ret < 0) { @@ -31,14 +50,21 @@ int board_usb_detect_init(unsigned gpio, unsigned long flags) return ret; } - if (!wakelock_inited) + if (!wakelock_inited) { wake_lock_init(&usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect"); + wakelock_inited = true; + } gpio_direction_input(gpio); - ret = request_irq(irq, detect_irq_handler, flags, "usb_detect", NULL); + + detect_gpio = gpio; + + flags = gpio_get_value(gpio) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; + ret = request_irq(irq, usb_detect_irq_handler, flags, "usb_detect", NULL); if (ret < 0) { pr_err("%s: request_irq(%d) failed\n", __func__, irq); gpio_free(gpio); + detect_gpio = INVALID_GPIO; return ret; } enable_irq_wake(irq); -- 2.34.1