From: 黄涛 <huangtao@rock-chips.com>
Date: Mon, 20 Aug 2012 12:52:44 +0000 (+0800)
Subject: rk2928: usb_detect: support bvalid irq wake up system
X-Git-Tag: firefly_0821_release~8886^2~10
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d663394000152d4cd86ee8568762a46ecdc65189;p=firefly-linux-kernel-4.4.55.git

rk2928: usb_detect: support bvalid irq wake up system
---

diff --git a/arch/arm/plat-rk/usb_detect.c b/arch/arm/plat-rk/usb_detect.c
index a71a60c8a823..411b0dd5aa6d 100644
--- a/arch/arm/plat-rk/usb_detect.c
+++ b/arch/arm/plat-rk/usb_detect.c
@@ -4,6 +4,8 @@
 #include <linux/gpio.h>
 #include <mach/board.h>
 
+#define WAKE_LOCK_TIMEOUT	(10 * HZ)
+
 static irqreturn_t usb_detect_irq_handler(int irq, void *dev_id);
 static int detect_gpio = INVALID_GPIO;
 
@@ -28,7 +30,7 @@ static struct wake_lock usb_wakelock;
 
 static irqreturn_t usb_detect_irq_handler(int irq, void *dev_id)
 {
-	wake_lock_timeout(&usb_wakelock, 10 * HZ);
+	wake_lock_timeout(&usb_wakelock, WAKE_LOCK_TIMEOUT);
 	schedule_delayed_work(&wakeup_work, HZ / 10);
 	return IRQ_HANDLED;
 }
@@ -72,3 +74,52 @@ int board_usb_detect_init(unsigned gpio)
 	return 0;
 }
 
+#if defined(CONFIG_ARCH_RK2928)
+#include <linux/io.h>
+#include <mach/iomux.h>
+
+static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
+{
+	/* clear irq */
+#ifdef CONFIG_ARCH_RK2928
+	writel_relaxed((1 << 31) | (1 << 15), RK2928_GRF_BASE + GRF_UOC0_CON5);
+#endif
+
+	wake_lock_timeout(&usb_wakelock, WAKE_LOCK_TIMEOUT);
+	rk28_send_wakeup_key();
+
+	return IRQ_HANDLED;
+}
+
+static int bvalid_init(void)
+{
+	int ret;
+	int irq = IRQ_OTG_BVALID;
+
+	if (detect_gpio != INVALID_GPIO) {
+		printk("usb detect inited by board_usb_detect_init, disable detect by bvalid irq\n");
+		return 0;
+	}
+
+	if (!wakelock_inited) {
+		wake_lock_init(&usb_wakelock, WAKE_LOCK_SUSPEND, "usb_detect");
+		wakelock_inited = true;
+	}
+
+	ret = request_irq(irq, bvalid_irq_handler, 0, "bvalid", NULL);
+	if (ret < 0) {
+		pr_err("%s: request_irq(%d) failed\n", __func__, irq);
+		return ret;
+	}
+
+	/* enable bvalid irq */
+#ifdef CONFIG_ARCH_RK2928
+	writel_relaxed((1 << 30) | (1 << 14), RK2928_GRF_BASE + GRF_UOC0_CON5);
+#endif
+
+	enable_irq_wake(irq);
+
+	return 0;
+}
+late_initcall(bvalid_init);
+#endif