diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 13:50:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 13:50:00 -0400 |
commit | a6f039869ff87e0a8d621e31d14bbb120c1dfa93 (patch) | |
tree | c8975a8d02893633d03efe5435aa8b0635298a93 /arch/arm/plat-omap/gpio.c | |
parent | e0bc5d4a54938eedcde14005210e6c08aa9727e4 (diff) | |
parent | f6304f5804f228b6c2fea9e3dfac25c5b2db9b38 (diff) |
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6
* 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6: (113 commits)
omap4: Add support for i2c init
omap: Fix i2c platform init code for omap4
OMAP2 clock: fix recursive spinlock attempt when CONFIG_CPU_FREQ=y
OMAP powerdomain, hwmod, omap_device: add some credits
OMAP4 powerdomain: Support LOWPOWERSTATECHANGE for powerdomains
OMAP3 clock: add support for setting the divider for sys_clkout2 using clk_set_rate
OMAP4 powerdomain: Fix pwrsts flags for ALWAYS ON domains
OMAP: timers: Fix clock source names for OMAP4
OMAP4 clock: Support clk_set_parent
OMAP4: PRCM: Add offset defines for all CM registers
OMAP4: PRCM: Add offset defines for all PRM registers
OMAP4: PRCM: Remove duplicate definition of base addresses
OMAP4: PRM: Remove MPU internal code name and apply PRCM naming convention
OMAP4: CM: Remove non-functional registers in ES1.0
OMAP: hwmod: Replace WARN by pr_warning for clockdomain check
OMAP: hwmod: Rename hwmod name for the MPU
OMAP: hwmod: Do not exit the iteration if one clock init failed
OMAP: hwmod: Replace WARN by pr_warning if clock lookup failed
OMAP: hwmod: Remove IS_ERR check with omap_clk_get_by_name return value
OMAP: hwmod: Fix wrong pointer iteration in oh->slaves
...
Diffstat (limited to 'arch/arm/plat-omap/gpio.c')
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 236 |
1 files changed, 94 insertions, 142 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 45a225d09125..dc2ac42d6319 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <mach/irqs.h> | 27 | #include <mach/irqs.h> |
28 | #include <mach/gpio.h> | 28 | #include <mach/gpio.h> |
29 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
30 | #include <plat/powerdomain.h> | ||
30 | 31 | ||
31 | /* | 32 | /* |
32 | * OMAP1510 GPIO registers | 33 | * OMAP1510 GPIO registers |
@@ -137,7 +138,11 @@ | |||
137 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 | 138 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 |
138 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 | 139 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 |
139 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 | 140 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 |
140 | #define OMAP4_GPIO_SYSSTATUS 0x0104 | 141 | #define OMAP4_GPIO_SYSSTATUS 0x0114 |
142 | #define OMAP4_GPIO_IRQENABLE1 0x011c | ||
143 | #define OMAP4_GPIO_WAKE_EN 0x0120 | ||
144 | #define OMAP4_GPIO_IRQSTATUS2 0x0128 | ||
145 | #define OMAP4_GPIO_IRQENABLE2 0x012c | ||
141 | #define OMAP4_GPIO_CTRL 0x0130 | 146 | #define OMAP4_GPIO_CTRL 0x0130 |
142 | #define OMAP4_GPIO_OE 0x0134 | 147 | #define OMAP4_GPIO_OE 0x0134 |
143 | #define OMAP4_GPIO_DATAIN 0x0138 | 148 | #define OMAP4_GPIO_DATAIN 0x0138 |
@@ -148,6 +153,10 @@ | |||
148 | #define OMAP4_GPIO_FALLINGDETECT 0x014c | 153 | #define OMAP4_GPIO_FALLINGDETECT 0x014c |
149 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 | 154 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 |
150 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 | 155 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 |
156 | #define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 | ||
157 | #define OMAP4_GPIO_SETIRQENABLE1 0x0164 | ||
158 | #define OMAP4_GPIO_CLEARWKUENA 0x0180 | ||
159 | #define OMAP4_GPIO_SETWKUENA 0x0184 | ||
151 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 | 160 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 |
152 | #define OMAP4_GPIO_SETDATAOUT 0x0194 | 161 | #define OMAP4_GPIO_SETDATAOUT 0x0194 |
153 | /* | 162 | /* |
@@ -195,6 +204,7 @@ struct gpio_bank { | |||
195 | struct gpio_chip chip; | 204 | struct gpio_chip chip; |
196 | struct clk *dbck; | 205 | struct clk *dbck; |
197 | u32 mod_usage; | 206 | u32 mod_usage; |
207 | u32 dbck_enable_mask; | ||
198 | }; | 208 | }; |
199 | 209 | ||
200 | #define METHOD_MPUIO 0 | 210 | #define METHOD_MPUIO 0 |
@@ -303,8 +313,6 @@ struct omap3_gpio_regs { | |||
303 | u32 risingdetect; | 313 | u32 risingdetect; |
304 | u32 fallingdetect; | 314 | u32 fallingdetect; |
305 | u32 dataout; | 315 | u32 dataout; |
306 | u32 setwkuena; | ||
307 | u32 setdataout; | ||
308 | }; | 316 | }; |
309 | 317 | ||
310 | static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; | 318 | static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS]; |
@@ -591,12 +599,16 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | |||
591 | reg += OMAP7XX_GPIO_DATA_OUTPUT; | 599 | reg += OMAP7XX_GPIO_DATA_OUTPUT; |
592 | break; | 600 | break; |
593 | #endif | 601 | #endif |
594 | #ifdef CONFIG_ARCH_OMAP2PLUS | 602 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
595 | case METHOD_GPIO_24XX: | 603 | case METHOD_GPIO_24XX: |
596 | case METHOD_GPIO_44XX: | ||
597 | reg += OMAP24XX_GPIO_DATAOUT; | 604 | reg += OMAP24XX_GPIO_DATAOUT; |
598 | break; | 605 | break; |
599 | #endif | 606 | #endif |
607 | #ifdef CONFIG_ARCH_OMAP4 | ||
608 | case METHOD_GPIO_44XX: | ||
609 | reg += OMAP4_GPIO_DATAOUT; | ||
610 | break; | ||
611 | #endif | ||
600 | default: | 612 | default: |
601 | return -EINVAL; | 613 | return -EINVAL; |
602 | } | 614 | } |
@@ -646,6 +658,7 @@ void omap_set_gpio_debounce(int gpio, int enable) | |||
646 | goto done; | 658 | goto done; |
647 | 659 | ||
648 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { | 660 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { |
661 | bank->dbck_enable_mask = val; | ||
649 | if (enable) | 662 | if (enable) |
650 | clk_enable(bank->dbck); | 663 | clk_enable(bank->dbck); |
651 | else | 664 | else |
@@ -724,15 +737,27 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
724 | OMAP4_GPIO_IRQWAKEN0); | 737 | OMAP4_GPIO_IRQWAKEN0); |
725 | } | 738 | } |
726 | } else { | 739 | } else { |
727 | if (trigger != 0) | 740 | /* |
741 | * GPIO wakeup request can only be generated on edge | ||
742 | * transitions | ||
743 | */ | ||
744 | if (trigger & IRQ_TYPE_EDGE_BOTH) | ||
728 | __raw_writel(1 << gpio, bank->base | 745 | __raw_writel(1 << gpio, bank->base |
729 | + OMAP24XX_GPIO_SETWKUENA); | 746 | + OMAP24XX_GPIO_SETWKUENA); |
730 | else | 747 | else |
731 | __raw_writel(1 << gpio, bank->base | 748 | __raw_writel(1 << gpio, bank->base |
732 | + OMAP24XX_GPIO_CLEARWKUENA); | 749 | + OMAP24XX_GPIO_CLEARWKUENA); |
733 | } | 750 | } |
734 | } else { | 751 | } |
735 | if (trigger != 0) | 752 | /* This part needs to be executed always for OMAP34xx */ |
753 | if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { | ||
754 | /* | ||
755 | * Log the edge gpio and manually trigger the IRQ | ||
756 | * after resume if the input level changes | ||
757 | * to avoid irq lost during PER RET/OFF mode | ||
758 | * Applies for omap2 non-wakeup gpio and all omap3 gpios | ||
759 | */ | ||
760 | if (trigger & IRQ_TYPE_EDGE_BOTH) | ||
736 | bank->enabled_non_wakeup_gpios |= gpio_bit; | 761 | bank->enabled_non_wakeup_gpios |= gpio_bit; |
737 | else | 762 | else |
738 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; | 763 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; |
@@ -1200,11 +1225,17 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) | |||
1200 | #endif | 1225 | #endif |
1201 | if (!cpu_class_is_omap1()) { | 1226 | if (!cpu_class_is_omap1()) { |
1202 | if (!bank->mod_usage) { | 1227 | if (!bank->mod_usage) { |
1228 | void __iomem *reg = bank->base; | ||
1203 | u32 ctrl; | 1229 | u32 ctrl; |
1204 | ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); | 1230 | |
1205 | ctrl &= 0xFFFFFFFE; | 1231 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) |
1232 | reg += OMAP24XX_GPIO_CTRL; | ||
1233 | else if (cpu_is_omap44xx()) | ||
1234 | reg += OMAP4_GPIO_CTRL; | ||
1235 | ctrl = __raw_readl(reg); | ||
1206 | /* Module is enabled, clocks are not gated */ | 1236 | /* Module is enabled, clocks are not gated */ |
1207 | __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); | 1237 | ctrl &= 0xFFFFFFFE; |
1238 | __raw_writel(ctrl, reg); | ||
1208 | } | 1239 | } |
1209 | bank->mod_usage |= 1 << offset; | 1240 | bank->mod_usage |= 1 << offset; |
1210 | } | 1241 | } |
@@ -1226,22 +1257,34 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) | |||
1226 | __raw_writel(1 << offset, reg); | 1257 | __raw_writel(1 << offset, reg); |
1227 | } | 1258 | } |
1228 | #endif | 1259 | #endif |
1229 | #ifdef CONFIG_ARCH_OMAP2PLUS | 1260 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
1230 | if ((bank->method == METHOD_GPIO_24XX) || | 1261 | if (bank->method == METHOD_GPIO_24XX) { |
1231 | (bank->method == METHOD_GPIO_44XX)) { | ||
1232 | /* Disable wake-up during idle for dynamic tick */ | 1262 | /* Disable wake-up during idle for dynamic tick */ |
1233 | void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 1263 | void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
1234 | __raw_writel(1 << offset, reg); | 1264 | __raw_writel(1 << offset, reg); |
1235 | } | 1265 | } |
1236 | #endif | 1266 | #endif |
1267 | #ifdef CONFIG_ARCH_OMAP4 | ||
1268 | if (bank->method == METHOD_GPIO_44XX) { | ||
1269 | /* Disable wake-up during idle for dynamic tick */ | ||
1270 | void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; | ||
1271 | __raw_writel(1 << offset, reg); | ||
1272 | } | ||
1273 | #endif | ||
1237 | if (!cpu_class_is_omap1()) { | 1274 | if (!cpu_class_is_omap1()) { |
1238 | bank->mod_usage &= ~(1 << offset); | 1275 | bank->mod_usage &= ~(1 << offset); |
1239 | if (!bank->mod_usage) { | 1276 | if (!bank->mod_usage) { |
1277 | void __iomem *reg = bank->base; | ||
1240 | u32 ctrl; | 1278 | u32 ctrl; |
1241 | ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); | 1279 | |
1280 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
1281 | reg += OMAP24XX_GPIO_CTRL; | ||
1282 | else if (cpu_is_omap44xx()) | ||
1283 | reg += OMAP4_GPIO_CTRL; | ||
1284 | ctrl = __raw_readl(reg); | ||
1242 | /* Module is disabled, clocks are gated */ | 1285 | /* Module is disabled, clocks are gated */ |
1243 | ctrl |= 1; | 1286 | ctrl |= 1; |
1244 | __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); | 1287 | __raw_writel(ctrl, reg); |
1245 | } | 1288 | } |
1246 | } | 1289 | } |
1247 | _reset_gpio(bank, bank->chip.base + offset); | 1290 | _reset_gpio(bank, bank->chip.base + offset); |
@@ -1570,9 +1613,14 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) | |||
1570 | reg += OMAP7XX_GPIO_DIR_CONTROL; | 1613 | reg += OMAP7XX_GPIO_DIR_CONTROL; |
1571 | break; | 1614 | break; |
1572 | case METHOD_GPIO_24XX: | 1615 | case METHOD_GPIO_24XX: |
1573 | case METHOD_GPIO_44XX: | ||
1574 | reg += OMAP24XX_GPIO_OE; | 1616 | reg += OMAP24XX_GPIO_OE; |
1575 | break; | 1617 | break; |
1618 | case METHOD_GPIO_44XX: | ||
1619 | reg += OMAP4_GPIO_OE; | ||
1620 | break; | ||
1621 | default: | ||
1622 | WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method"); | ||
1623 | return -EINVAL; | ||
1576 | } | 1624 | } |
1577 | return __raw_readl(reg) & mask; | 1625 | return __raw_readl(reg) & mask; |
1578 | } | 1626 | } |
@@ -1845,7 +1893,8 @@ static int __init _omap_gpio_init(void) | |||
1845 | __raw_writel(0, bank->base + | 1893 | __raw_writel(0, bank->base + |
1846 | OMAP24XX_GPIO_CTRL); | 1894 | OMAP24XX_GPIO_CTRL); |
1847 | } | 1895 | } |
1848 | if (i < ARRAY_SIZE(non_wakeup_gpios)) | 1896 | if (cpu_is_omap24xx() && |
1897 | i < ARRAY_SIZE(non_wakeup_gpios)) | ||
1849 | bank->non_wakeup_gpios = non_wakeup_gpios[i]; | 1898 | bank->non_wakeup_gpios = non_wakeup_gpios[i]; |
1850 | gpio_count = 32; | 1899 | gpio_count = 32; |
1851 | } | 1900 | } |
@@ -2028,16 +2077,27 @@ static struct sys_device omap_gpio_device = { | |||
2028 | 2077 | ||
2029 | static int workaround_enabled; | 2078 | static int workaround_enabled; |
2030 | 2079 | ||
2031 | void omap2_gpio_prepare_for_retention(void) | 2080 | void omap2_gpio_prepare_for_idle(int power_state) |
2032 | { | 2081 | { |
2033 | int i, c = 0; | 2082 | int i, c = 0; |
2083 | int min = 0; | ||
2034 | 2084 | ||
2035 | /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious | 2085 | if (cpu_is_omap34xx()) |
2036 | * IRQs will be generated. See OMAP2420 Errata item 1.101. */ | 2086 | min = 1; |
2037 | for (i = 0; i < gpio_bank_count; i++) { | 2087 | |
2088 | for (i = min; i < gpio_bank_count; i++) { | ||
2038 | struct gpio_bank *bank = &gpio_bank[i]; | 2089 | struct gpio_bank *bank = &gpio_bank[i]; |
2039 | u32 l1, l2; | 2090 | u32 l1, l2; |
2040 | 2091 | ||
2092 | if (bank->dbck_enable_mask) | ||
2093 | clk_disable(bank->dbck); | ||
2094 | |||
2095 | if (power_state > PWRDM_POWER_OFF) | ||
2096 | continue; | ||
2097 | |||
2098 | /* If going to OFF, remove triggering for all | ||
2099 | * non-wakeup GPIOs. Otherwise spurious IRQs will be | ||
2100 | * generated. See OMAP2420 Errata item 1.101. */ | ||
2041 | if (!(bank->enabled_non_wakeup_gpios)) | 2101 | if (!(bank->enabled_non_wakeup_gpios)) |
2042 | continue; | 2102 | continue; |
2043 | 2103 | ||
@@ -2085,16 +2145,23 @@ void omap2_gpio_prepare_for_retention(void) | |||
2085 | workaround_enabled = 1; | 2145 | workaround_enabled = 1; |
2086 | } | 2146 | } |
2087 | 2147 | ||
2088 | void omap2_gpio_resume_after_retention(void) | 2148 | void omap2_gpio_resume_after_idle(void) |
2089 | { | 2149 | { |
2090 | int i; | 2150 | int i; |
2151 | int min = 0; | ||
2091 | 2152 | ||
2092 | if (!workaround_enabled) | 2153 | if (cpu_is_omap34xx()) |
2093 | return; | 2154 | min = 1; |
2094 | for (i = 0; i < gpio_bank_count; i++) { | 2155 | for (i = min; i < gpio_bank_count; i++) { |
2095 | struct gpio_bank *bank = &gpio_bank[i]; | 2156 | struct gpio_bank *bank = &gpio_bank[i]; |
2096 | u32 l, gen, gen0, gen1; | 2157 | u32 l, gen, gen0, gen1; |
2097 | 2158 | ||
2159 | if (bank->dbck_enable_mask) | ||
2160 | clk_enable(bank->dbck); | ||
2161 | |||
2162 | if (!workaround_enabled) | ||
2163 | continue; | ||
2164 | |||
2098 | if (!(bank->enabled_non_wakeup_gpios)) | 2165 | if (!(bank->enabled_non_wakeup_gpios)) |
2099 | continue; | 2166 | continue; |
2100 | 2167 | ||
@@ -2119,7 +2186,7 @@ void omap2_gpio_resume_after_retention(void) | |||
2119 | * horribly racy, but it's the best we can do to work around | 2186 | * horribly racy, but it's the best we can do to work around |
2120 | * this silicon bug. */ | 2187 | * this silicon bug. */ |
2121 | l ^= bank->saved_datain; | 2188 | l ^= bank->saved_datain; |
2122 | l &= bank->non_wakeup_gpios; | 2189 | l &= bank->enabled_non_wakeup_gpios; |
2123 | 2190 | ||
2124 | /* | 2191 | /* |
2125 | * No need to generate IRQs for the rising edge for gpio IRQs | 2192 | * No need to generate IRQs for the rising edge for gpio IRQs |
@@ -2207,10 +2274,6 @@ void omap_gpio_save_context(void) | |||
2207 | __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 2274 | __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
2208 | gpio_context[i].dataout = | 2275 | gpio_context[i].dataout = |
2209 | __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); | 2276 | __raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT); |
2210 | gpio_context[i].setwkuena = | ||
2211 | __raw_readl(bank->base + OMAP24XX_GPIO_SETWKUENA); | ||
2212 | gpio_context[i].setdataout = | ||
2213 | __raw_readl(bank->base + OMAP24XX_GPIO_SETDATAOUT); | ||
2214 | } | 2277 | } |
2215 | } | 2278 | } |
2216 | 2279 | ||
@@ -2243,10 +2306,6 @@ void omap_gpio_restore_context(void) | |||
2243 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 2306 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
2244 | __raw_writel(gpio_context[i].dataout, | 2307 | __raw_writel(gpio_context[i].dataout, |
2245 | bank->base + OMAP24XX_GPIO_DATAOUT); | 2308 | bank->base + OMAP24XX_GPIO_DATAOUT); |
2246 | __raw_writel(gpio_context[i].setwkuena, | ||
2247 | bank->base + OMAP24XX_GPIO_SETWKUENA); | ||
2248 | __raw_writel(gpio_context[i].setdataout, | ||
2249 | bank->base + OMAP24XX_GPIO_SETDATAOUT); | ||
2250 | } | 2309 | } |
2251 | } | 2310 | } |
2252 | #endif | 2311 | #endif |
@@ -2286,110 +2345,3 @@ static int __init omap_gpio_sysinit(void) | |||
2286 | } | 2345 | } |
2287 | 2346 | ||
2288 | arch_initcall(omap_gpio_sysinit); | 2347 | arch_initcall(omap_gpio_sysinit); |
2289 | |||
2290 | |||
2291 | #ifdef CONFIG_DEBUG_FS | ||
2292 | |||
2293 | #include <linux/debugfs.h> | ||
2294 | #include <linux/seq_file.h> | ||
2295 | |||
2296 | static int dbg_gpio_show(struct seq_file *s, void *unused) | ||
2297 | { | ||
2298 | unsigned i, j, gpio; | ||
2299 | |||
2300 | for (i = 0, gpio = 0; i < gpio_bank_count; i++) { | ||
2301 | struct gpio_bank *bank = gpio_bank + i; | ||
2302 | unsigned bankwidth = 16; | ||
2303 | u32 mask = 1; | ||
2304 | |||
2305 | if (bank_is_mpuio(bank)) | ||
2306 | gpio = OMAP_MPUIO(0); | ||
2307 | else if (cpu_class_is_omap2() || cpu_is_omap7xx()) | ||
2308 | bankwidth = 32; | ||
2309 | |||
2310 | for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { | ||
2311 | unsigned irq, value, is_in, irqstat; | ||
2312 | const char *label; | ||
2313 | |||
2314 | label = gpiochip_is_requested(&bank->chip, j); | ||
2315 | if (!label) | ||
2316 | continue; | ||
2317 | |||
2318 | irq = bank->virtual_irq_start + j; | ||
2319 | value = gpio_get_value(gpio); | ||
2320 | is_in = gpio_is_input(bank, mask); | ||
2321 | |||
2322 | if (bank_is_mpuio(bank)) | ||
2323 | seq_printf(s, "MPUIO %2d ", j); | ||
2324 | else | ||
2325 | seq_printf(s, "GPIO %3d ", gpio); | ||
2326 | seq_printf(s, "(%-20.20s): %s %s", | ||
2327 | label, | ||
2328 | is_in ? "in " : "out", | ||
2329 | value ? "hi" : "lo"); | ||
2330 | |||
2331 | /* FIXME for at least omap2, show pullup/pulldown state */ | ||
2332 | |||
2333 | irqstat = irq_desc[irq].status; | ||
2334 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) | ||
2335 | if (is_in && ((bank->suspend_wakeup & mask) | ||
2336 | || irqstat & IRQ_TYPE_SENSE_MASK)) { | ||
2337 | char *trigger = NULL; | ||
2338 | |||
2339 | switch (irqstat & IRQ_TYPE_SENSE_MASK) { | ||
2340 | case IRQ_TYPE_EDGE_FALLING: | ||
2341 | trigger = "falling"; | ||
2342 | break; | ||
2343 | case IRQ_TYPE_EDGE_RISING: | ||
2344 | trigger = "rising"; | ||
2345 | break; | ||
2346 | case IRQ_TYPE_EDGE_BOTH: | ||
2347 | trigger = "bothedge"; | ||
2348 | break; | ||
2349 | case IRQ_TYPE_LEVEL_LOW: | ||
2350 | trigger = "low"; | ||
2351 | break; | ||
2352 | case IRQ_TYPE_LEVEL_HIGH: | ||
2353 | trigger = "high"; | ||
2354 | break; | ||
2355 | case IRQ_TYPE_NONE: | ||
2356 | trigger = "(?)"; | ||
2357 | break; | ||
2358 | } | ||
2359 | seq_printf(s, ", irq-%d %-8s%s", | ||
2360 | irq, trigger, | ||
2361 | (bank->suspend_wakeup & mask) | ||
2362 | ? " wakeup" : ""); | ||
2363 | } | ||
2364 | #endif | ||
2365 | seq_printf(s, "\n"); | ||
2366 | } | ||
2367 | |||
2368 | if (bank_is_mpuio(bank)) { | ||
2369 | seq_printf(s, "\n"); | ||
2370 | gpio = 0; | ||
2371 | } | ||
2372 | } | ||
2373 | return 0; | ||
2374 | } | ||
2375 | |||
2376 | static int dbg_gpio_open(struct inode *inode, struct file *file) | ||
2377 | { | ||
2378 | return single_open(file, dbg_gpio_show, &inode->i_private); | ||
2379 | } | ||
2380 | |||
2381 | static const struct file_operations debug_fops = { | ||
2382 | .open = dbg_gpio_open, | ||
2383 | .read = seq_read, | ||
2384 | .llseek = seq_lseek, | ||
2385 | .release = single_release, | ||
2386 | }; | ||
2387 | |||
2388 | static int __init omap_gpio_debuginit(void) | ||
2389 | { | ||
2390 | (void) debugfs_create_file("omap_gpio", S_IRUGO, | ||
2391 | NULL, NULL, &debug_fops); | ||
2392 | return 0; | ||
2393 | } | ||
2394 | late_initcall(omap_gpio_debuginit); | ||
2395 | #endif | ||