ARM: tegra: move wakeup APIs to common file
Laxman Dewangan [Wed, 30 Oct 2013 07:11:07 +0000 (12:11 +0530)]
Instead of implementing some common api for every chip on
same way n different files, moving this code to a single file
to avoid code duplication.

Change-Id: I0a7ed15f63d7034533deb07da0bd7e8e650d682a
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/304931
Reviewed-by: Automatic_Commit_Validation_User

arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/tegra-wakeups.c [new file with mode: 0644]
arch/arm/mach-tegra/wakeups-t11x.c
arch/arm/mach-tegra/wakeups-t12x.c
arch/arm/mach-tegra/wakeups-t14x.c
arch/arm/mach-tegra/wakeups-t2.c
arch/arm/mach-tegra/wakeups-t3.c
include/linux/irqchip/tegra.h

index 2948fe3..c59e641 100644 (file)
@@ -21,6 +21,8 @@ obj-y                                   += mipi-cal.o
 endif
 endif
 
+obj-$(CONFIG_PM_SLEEP)                  += tegra-wakeups.o
+
 ifeq ($(CONFIG_ARCH_TEGRA_2x_SOC),y)
 obj-y                                   += common-t2.o
 obj-y                                   += pm-t2.o
diff --git a/arch/arm/mach-tegra/tegra-wakeups.c b/arch/arm/mach-tegra/tegra-wakeups.c
new file mode 100644 (file)
index 0000000..5c39dbf
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Tegra Wakeups for NVIDIA SoCs Tegra
+ *
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irqchip/tegra.h>
+
+#include <mach/irqs.h>
+#include <mach/gpio-tegra.h>
+
+int *tegra_gpio_wake_table;
+EXPORT_SYMBOL_GPL(tegra_gpio_wake_table);
+
+int *tegra_irq_wake_table;
+EXPORT_SYMBOL_GPL(tegra_irq_wake_table);
+
+int tegra_wake_table_len;
+EXPORT_SYMBOL_GPL(tegra_wake_table_len);
+
+static int last_gpio = -1;
+
+int tegra_set_wake_gpio(unsigned int wake, int gpio)
+{
+       if (wake < 0 || wake >= tegra_wake_table_len)
+               return -EINVAL;
+
+       tegra_irq_wake_table[wake] = -EAGAIN;
+       tegra_gpio_wake_table[wake] = gpio;
+
+       return 0;
+}
+
+int tegra_set_wake_irq(unsigned int wake, int irq)
+{
+       if (wake < 0 || wake >= tegra_wake_table_len)
+               return -EINVAL;
+
+       tegra_irq_wake_table[wake] = irq;
+
+       return 0;
+}
+
+int tegra_gpio_to_wake(int gpio)
+{
+       int i;
+
+       for (i = 0; i < tegra_wake_table_len; i++) {
+               if (tegra_gpio_wake_table[i] == gpio) {
+                       pr_info("gpio wake%d for gpio=%d\n", i, gpio);
+                       last_gpio = i;
+                       return i;
+               }
+       }
+
+       return -EINVAL;
+}
+
+void tegra_irq_to_wake(int irq, int *wak_list, int *wak_size)
+{
+       int i;
+       int bank_irq;
+
+       *wak_size = 0;
+       for (i = 0; i < tegra_wake_table_len; i++) {
+               if (tegra_irq_wake_table[i] == irq) {
+                       pr_info("Wake%d for irq=%d\n", i, irq);
+                       wak_list[*wak_size] = i;
+                       *wak_size = *wak_size + 1;
+               }
+       }
+       if (*wak_size)
+               goto out;
+
+       /* The gpio set_wake code bubbles the set_wake call up to the irq
+        * set_wake code. This insures that the nested irq set_wake call
+        * succeeds, even though it doesn't have to do any pm setup for the
+        * bank.
+        *
+        * This is very fragile - there's no locking, so two callers could
+        * cause issues with this.
+        */
+       if (last_gpio < 0)
+               goto out;
+
+       bank_irq = tegra_gpio_get_bank_int_nr(tegra_gpio_wake_table[last_gpio]);
+       if (bank_irq == irq) {
+               pr_info("gpio bank wake found: wake%d for irq=%d\n", i, irq);
+               wak_list[*wak_size] = last_gpio;
+               *wak_size = 1;
+       }
+
+out:
+       return;
+}
+
+int tegra_wake_to_irq(int wake)
+{
+       int ret;
+
+       if (wake < 0)
+               return -EINVAL;
+
+       if (wake >= tegra_wake_table_len)
+               return -EINVAL;
+
+       ret = tegra_irq_wake_table[wake];
+       if (ret == -EAGAIN) {
+               ret = tegra_gpio_wake_table[wake];
+               if (ret != -EINVAL)
+                       ret = gpio_to_irq(ret);
+       }
+
+       return ret;
+}
+
+int tegra_set_wake_source(int wake, int irq)
+{
+       if (wake < 0)
+               return -EINVAL;
+
+       if (wake >= tegra_wake_table_len)
+               return -EINVAL;
+
+       tegra_irq_wake_table[wake] = irq;
+       return 0;
+}
+
+int tegra_disable_wake_source(int wake)
+{
+       return tegra_set_wake_source(wake, -EINVAL);
+}
index d3ae390..6e3be66 100644 (file)
@@ -161,29 +161,6 @@ static int tegra_wake_event_irq[] = {
        INT_XUSB_PADCTL, /* XUSB superspeed wake */     /* wake58 */
 };
 
-static int last_gpio = -1;
-
-int tegra_set_wake_gpio(unsigned int wake, int gpio)
-{
-       if (wake < 0 || wake >= ARRAY_SIZE(tegra_gpio_wakes))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = -EAGAIN;
-       tegra_gpio_wakes[wake] = gpio;
-
-       return 0;
-}
-
-int tegra_set_wake_irq(unsigned int wake, int irq)
-{
-       if (wake < 0 || wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = irq;
-
-       return 0;
-}
-
 #ifdef CONFIG_TEGRA_INTERNAL_USB_CABLE_WAKE_SUPPORT
 /* USB1 VBUS and ID wake sources are handled as special case
  * Note: SD card detect is an ANY wake source but is
@@ -229,21 +206,6 @@ int get_vbus_id_cable_connect_state(bool *is_vbus_connected,
 }
 #endif
 
-int tegra_gpio_to_wake(int gpio)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) {
-               if (tegra_gpio_wakes[i] == gpio) {
-                       pr_info("gpio wake%d for gpio=%d\n", i, gpio);
-                       last_gpio = i;
-                       return i;
-               }
-       }
-
-       return -EINVAL;
-}
-
 void tegra_set_usb_wake_source(void)
 {
        struct board_info board_info;
@@ -256,67 +218,11 @@ void tegra_set_usb_wake_source(void)
        }
 }
 
-void tegra_irq_to_wake(int irq, int *wak_list, int *wak_size)
+static int __init tegra11x_wakeup_table_init(void)
 {
-       int i;
-
-       *wak_size = 0;
-       for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
-               if (tegra_wake_event_irq[i] == irq) {
-                       pr_info("Wake%d for irq=%d\n", i, irq);
-                       wak_list[*wak_size] = i;
-                       *wak_size = *wak_size + 1;
-               }
-       }
-       if (*wak_size)
-               goto out;
-
-       /* The gpio set_wake code bubbles the set_wake call up to the irq
-        * set_wake code. This insures that the nested irq set_wake call
-        * succeeds, even though it doesn't have to do any pm setup for the
-        * bank.
-        *
-        * This is very fragile - there's no locking, so two callers could
-        * cause issues with this.
-        */
-       if (last_gpio < 0)
-               goto out;
-
-       if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) {
-               pr_info("gpio bank wake found: wake%d for irq=%d\n", i, irq);
-               wak_list[*wak_size] = last_gpio;
-               *wak_size = 1;
-       }
-
-out:
-       return;
-}
-
-int tegra_wake_to_irq(int wake)
-{
-       int ret;
-
-       if (wake < 0)
-               return -EINVAL;
-
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       ret = tegra_wake_event_irq[wake];
-       if (ret == -EAGAIN) {
-               ret = tegra_gpio_wakes[wake];
-               if (ret != -EINVAL)
-                       ret = gpio_to_irq(ret);
-       }
-
-       return ret;
-}
-
-int tegra_disable_wake_source(int wake)
-{
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = -EINVAL;
+       tegra_gpio_wake_table = tegra_gpio_wakes;
+       tegra_irq_wake_table = tegra_wake_event_irq;
+       tegra_wake_table_len = ARRAY_SIZE(tegra_gpio_wakes);
        return 0;
 }
+postcore_initcall(tegra11x_wakeup_table_init);
index 36ace0c..804fd66 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
 #include <mach/gpio-tegra.h>
@@ -151,92 +152,11 @@ static int tegra_wake_event_irq[] = {
        -EINVAL,                                /* wake60 */
 };
 
-static int last_gpio = -1;
-
-int tegra_gpio_to_wake(int gpio)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) {
-               if (tegra_gpio_wakes[i] == gpio) {
-                       pr_info("gpio wake%d for gpio=%d\n", i, gpio);
-                       last_gpio = i;
-                       return i;
-               }
-       }
-
-       return -EINVAL;
-}
-
-void tegra_irq_to_wake(int irq, int *wak_list, int *wak_size)
-{
-       int i;
-
-       *wak_size = 0;
-       for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
-               if (tegra_wake_event_irq[i] == irq) {
-                       pr_info("Wake%d for irq=%d\n", i, irq);
-                       wak_list[*wak_size] = i;
-                       *wak_size = *wak_size + 1;
-               }
-       }
-       if (*wak_size)
-               goto out;
-
-       /* The gpio set_wake code bubbles the set_wake call up to the irq
-        * set_wake code. This insures that the nested irq set_wake call
-        * succeeds, even though it doesn't have to do any pm setup for the
-        * bank.
-        *
-        * This is very fragile - there's no locking, so two callers could
-        * cause issues with this.
-        */
-       if (last_gpio < 0)
-               goto out;
-
-       if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) {
-               pr_info("gpio bank wake found: wake%d for irq=%d\n", i, irq);
-               wak_list[*wak_size] = last_gpio;
-               *wak_size = 1;
-       }
-
-out:
-       return;
-}
-
-int tegra_wake_to_irq(int wake)
+static int __init tegra12x_wakeup_table_init(void)
 {
-       int ret;
-
-       if (wake < 0)
-               return -EINVAL;
-
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       ret = tegra_wake_event_irq[wake];
-       if (ret == -EAGAIN) {
-               ret = tegra_gpio_wakes[wake];
-               if (ret != -EINVAL)
-                       ret = gpio_to_irq(ret);
-       }
-
-       return ret;
-}
-
-int tegra_set_wake_source(int wake, int irq)
-{
-       if (wake < 0)
-               return -EINVAL;
-
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = irq;
+       tegra_gpio_wake_table = tegra_gpio_wakes;
+       tegra_irq_wake_table = tegra_wake_event_irq;
+       tegra_wake_table_len = ARRAY_SIZE(tegra_gpio_wakes);
        return 0;
 }
-
-int tegra_disable_wake_source(int wake)
-{
-       return tegra_set_wake_source(wake, -EINVAL);
-}
+postcore_initcall(tegra12x_wakeup_table_init);
index a10b00d..99b4dc7 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
 #include <mach/gpio-tegra.h>
@@ -160,84 +161,11 @@ static int tegra_wake_event_irq[] = {
        -EINVAL,                                /* wake63 */
 };
 
-static int last_gpio = -1;
-
-int tegra_gpio_to_wake(int gpio)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) {
-               if (tegra_gpio_wakes[i] == gpio) {
-                       pr_info("gpio wake%d for gpio=%d\n", i, gpio);
-                       last_gpio = i;
-                       return i;
-               }
-       }
-
-       return -EINVAL;
-}
-
-void tegra_irq_to_wake(int irq, int *wak_list, int *wak_size)
+static int __init tegra14x_wakeup_table_init(void)
 {
-       int i;
-
-       *wak_size = 0;
-       for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
-               if (tegra_wake_event_irq[i] == irq) {
-                       pr_info("Wake%d for irq=%d\n", i, irq);
-                       wak_list[*wak_size] = i;
-                       *wak_size = *wak_size + 1;
-               }
-       }
-       if (*wak_size)
-                       goto out;
-
-       /* The gpio set_wake code bubbles the set_wake call up to the irq
-        * set_wake code. This insures that the nested irq set_wake call
-        * succeeds, even though it doesn't have to do any pm setup for the
-        * bank.
-        *
-        * This is very fragile - there's no locking, so two callers could
-        * cause issues with this.
-        */
-       if (last_gpio < 0)
-               goto out;
-
-       if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) {
-               pr_info("gpio bank wake found: wake%d for irq=%d\n", i, irq);
-               wak_list[*wak_size] = last_gpio;
-               *wak_size = 1;
-       }
-
-out:
-       return;
-}
-
-int tegra_wake_to_irq(int wake)
-{
-       int ret;
-
-       if (wake < 0)
-               return -EINVAL;
-
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       ret = tegra_wake_event_irq[wake];
-       if (ret == -EAGAIN) {
-               ret = tegra_gpio_wakes[wake];
-               if (ret != -EINVAL)
-                       ret = gpio_to_irq(ret);
-       }
-
-       return ret;
-}
-
-int tegra_disable_wake_source(int wake)
-{
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = -EINVAL;
+       tegra_gpio_wake_table = tegra_gpio_wakes;
+       tegra_irq_wake_table = tegra_wake_event_irq;
+       tegra_wake_table_len = ARRAY_SIZE(tegra_gpio_wakes);
        return 0;
 }
+postcore_initcall(tegra14x_wakeup_table_init);
index 329c8c7..2c7b5fb 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip/tegra.h>
 
 #include <mach/gpio-tegra.h>
 #include <mach/irqs.h>
@@ -97,84 +98,11 @@ static int tegra_wake_event_irq[] = {
        [30] = -EAGAIN,
 };
 
-static int last_gpio = -1;
-
-int tegra_gpio_to_wake(int gpio)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) {
-               if (tegra_gpio_wakes[i] == gpio) {
-                       pr_info("gpio wake%d for gpio=%d\n", i, gpio);
-                       last_gpio = i;
-                       return i;
-               }
-       }
-
-       return -EINVAL;
-}
-
-void tegra_irq_to_wake(int irq, int *wak_list, int *wak_size)
+static int __init tegra2_wakeup_table_init(void)
 {
-       int i;
-
-       *wak_size = 0;
-       for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
-               if (tegra_wake_event_irq[i] == irq) {
-                       pr_info("Wake %d for irq=%d\n", i, irq);
-                       wak_list[*wak_size] = i;
-                       *wak_size = *wak_size + 1;
-               }
-       }
-       if (*wak_size)
-               goto out;
-
-       /* The gpio set_wake code bubbles the set_wake call up to the irq
-        * set_wake code. This insures that the nested irq set_wake call
-        * succeeds, even though it doesn't have to do any pm setup for the
-        * bank.
-        *
-        * This is very fragile - there's no locking, so two callers could
-        * cause issues with this.
-        */
-       if (last_gpio < 0)
-               goto out;
-
-       if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) {
-               pr_info("gpio bank wake found: wake %d for irq=%d\n", i, irq);
-               wak_list[*wak_size] = last_gpio;
-               *wak_size = 1;
-       }
-
-out:
-       return;
-}
-
-int tegra_wake_to_irq(int wake)
-{
-       int ret;
-
-       if (wake < 0)
-               return -EINVAL;
-
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       ret = tegra_wake_event_irq[wake];
-       if (ret == -EAGAIN) {
-               ret = tegra_gpio_wakes[wake];
-               if (ret != -EINVAL)
-                       ret = gpio_to_irq(ret);
-       }
-
-       return ret;
-}
-
-int tegra_disable_wake_source(int wake)
-{
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = -EINVAL;
+       tegra_gpio_wake_table = tegra_gpio_wakes;
+       tegra_irq_wake_table = tegra_wake_event_irq;
+       tegra_wake_table_len = ARRAY_SIZE(tegra_gpio_wakes);
        return 0;
 }
+postcore_initcall(tegra2_wakeup_table_init);
index 15682e2..4f012cf 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip/tegra.h>
 
 #include <mach/irqs.h>
 #include <mach/gpio-tegra.h>
@@ -116,85 +117,11 @@ static int tegra_wake_event_irq[] = {
        INT_USB2, /* TEGRA_USB2_UHSIC, */       /* wake42 */
 };
 
-static int last_gpio = -1;
-
-int tegra_gpio_to_wake(int gpio)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(tegra_gpio_wakes); i++) {
-               if (tegra_gpio_wakes[i] == gpio) {
-                       pr_info("gpio wake%d for gpio=%d\n", i, gpio);
-                       last_gpio = i;
-                       return i;
-               }
-       }
-
-       return -EINVAL;
-}
-
-void tegra_irq_to_wake(int irq, int *wak_list, int *wak_size)
+static int __init tegra3_wakeup_table_init(void)
 {
-       int i;
-
-       *wak_size = 0;
-       for (i = 0; i < ARRAY_SIZE(tegra_wake_event_irq); i++) {
-               if (tegra_wake_event_irq[i] == irq) {
-                       pr_info("Wake%d for irq=%d\n", i, irq);
-                       wak_list[*wak_size] = i;
-                       *wak_size = *wak_size + 1;
-               }
-       }
-       if (*wak_size)
-               goto out;
-
-       /* The gpio set_wake code bubbles the set_wake call up to the irq
-        * set_wake code. This insures that the nested irq set_wake call
-        * succeeds, even though it doesn't have to do any pm setup for the
-        * bank.
-        *
-        * This is very fragile - there's no locking, so two callers could
-        * cause issues with this.
-        */
-       if (last_gpio < 0)
-               goto out;
-
-       if (tegra_gpio_get_bank_int_nr(tegra_gpio_wakes[last_gpio]) == irq) {
-               pr_info("gpio bank wake found: wake%d for irq=%d\n", i, irq);
-               wak_list[*wak_size] = last_gpio;
-               *wak_size = 1;
-       }
-
-out:
-       return;
-}
-
-int tegra_wake_to_irq(int wake)
-{
-       int ret;
-
-       if (wake < 0)
-               return -EINVAL;
-
-       if ((wake >= ARRAY_SIZE(tegra_wake_event_irq)) ||
-               (wake >= ARRAY_SIZE(tegra_gpio_wakes)))
-               return -EINVAL;
-
-       ret = tegra_wake_event_irq[wake];
-       if (ret == -EAGAIN) {
-               ret = tegra_gpio_wakes[wake];
-               if (ret != -EINVAL)
-                       ret = gpio_to_irq(ret);
-       }
-
-       return ret;
-}
-
-int tegra_disable_wake_source(int wake)
-{
-       if (wake >= ARRAY_SIZE(tegra_wake_event_irq))
-               return -EINVAL;
-
-       tegra_wake_event_irq[wake] = -EINVAL;
+       tegra_gpio_wake_table = tegra_gpio_wakes;
+       tegra_irq_wake_table = tegra_wake_event_irq;
+       tegra_wake_table_len = ARRAY_SIZE(tegra_gpio_wakes);
        return 0;
 }
+postcore_initcall(tegra3_wakeup_table_init);
index cb968dd..f634e21 100644 (file)
@@ -46,6 +46,10 @@ void tegra_gic_affinity_to_cpu0(void);
 
 u32 tegra_gic_version(void);
 
+extern int *tegra_gpio_wake_table;
+extern int *tegra_irq_wake_table;
+extern int tegra_wake_table_len;
+
 #if defined(CONFIG_PM_SLEEP)
 u64 tegra_read_pmc_wake_status(void);
 int tegra_pm_irq_set_wake(int wake, int enable);