rk29: usb detect plug in/out both
author黄涛 <huangtao@rock-chips.com>
Wed, 13 Apr 2011 07:09:58 +0000 (15:09 +0800)
committer黄涛 <huangtao@rock-chips.com>
Wed, 13 Apr 2011 07:09:58 +0000 (15:09 +0800)
arch/arm/mach-rk29/board-rk29-ddr3sdk.c
arch/arm/mach-rk29/board-rk29-fih.c
arch/arm/mach-rk29/board-rk29sdk.c
arch/arm/mach-rk29/include/mach/board.h
arch/arm/mach-rk29/usb_detect.c

index d72a6767e93de6cbaec151fd0314b2eb811e5f47..574c598ea60ccce2813122a4a0c77de9339e1153 100755 (executable)
@@ -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,
index 1247f8c8d35c6b285a5d0da7834761fa548dcb50..f796e1dd7b3f72a8e41e8f6c0773a6a8f0bfedec 100755 (executable)
@@ -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,
index 6c57cb461bc03049532d67296777d2033c6d4e4b..018cdf2b036d01b91dbeb6b70d589820cad2742a 100755 (executable)
@@ -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,
index fe03a22769ed9badb9b12e7688059e43209a93fb..29d90dedbbef32480da8df7d71b33316add3674e 100755 (executable)
@@ -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 */
index 51339a5208992e4d6bb38c35af8baf8f6951a1b6..a71a60c8a8234540ab9c3b9a20575dd937d1d450 100644 (file)
@@ -4,26 +4,45 @@
 #include <linux/gpio.h>
 #include <mach/board.h>
 
-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);