[ARM] tegra: add GPIO support

v2: fixes from Mike Rapoport:
- move gpio-names.h to arch/arm/mach-tegra
fixes from Russell King
- include linux/io.h and linux/gpio.h instead of asm/io.h
and asm/gpio.h
additional changes:
- add macros to convert between irq and gpio numbers for platform data
- change for_each_bit to for_each_set_bit in gpio.c
v3:
- minor bugfixes

Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: Erik Gilling <konkers@android.com>

+650
+1
arch/arm/mach-tegra/Kconfig
··· 9 bool "Tegra 2 family" 10 select CPU_V7 11 select ARM_GIC 12 help 13 Support for NVIDIA Tegra AP20 and T20 processors, based on the 14 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
··· 9 bool "Tegra 2 family" 10 select CPU_V7 11 select ARM_GIC 12 + select ARCH_REQUIRE_GPIOLIB 13 help 14 Support for NVIDIA Tegra AP20 and T20 processors, based on the 15 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
+1
arch/arm/mach-tegra/Makefile
··· 3 obj-y += irq.o 4 obj-y += clock.o 5 obj-y += timer.o 6 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 7 obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o 8 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
··· 3 obj-y += irq.o 4 obj-y += clock.o 5 obj-y += timer.o 6 + obj-y += gpio.o 7 obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 8 obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o 9 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+247
arch/arm/mach-tegra/gpio-names.h
···
··· 1 + /* 2 + * arch/arm/mach-tegra/include/mach/gpio-names.h 3 + * 4 + * Copyright (c) 2010 Google, Inc 5 + * 6 + * Author: 7 + * Erik Gilling <konkers@google.com> 8 + * 9 + * This software is licensed under the terms of the GNU General Public 10 + * License version 2, as published by the Free Software Foundation, and 11 + * may be copied, distributed, and modified under those terms. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + */ 18 + 19 + #ifndef __MACH_TEGRA_GPIO_NAMES_H 20 + #define __MACH_TEGRA_GPIO_NAMES_H 21 + 22 + #define TEGRA_GPIO_PA0 0 23 + #define TEGRA_GPIO_PA1 1 24 + #define TEGRA_GPIO_PA2 2 25 + #define TEGRA_GPIO_PA3 3 26 + #define TEGRA_GPIO_PA4 4 27 + #define TEGRA_GPIO_PA5 5 28 + #define TEGRA_GPIO_PA6 6 29 + #define TEGRA_GPIO_PA7 7 30 + #define TEGRA_GPIO_PB0 8 31 + #define TEGRA_GPIO_PB1 9 32 + #define TEGRA_GPIO_PB2 10 33 + #define TEGRA_GPIO_PB3 11 34 + #define TEGRA_GPIO_PB4 12 35 + #define TEGRA_GPIO_PB5 13 36 + #define TEGRA_GPIO_PB6 14 37 + #define TEGRA_GPIO_PB7 15 38 + #define TEGRA_GPIO_PC0 16 39 + #define TEGRA_GPIO_PC1 17 40 + #define TEGRA_GPIO_PC2 18 41 + #define TEGRA_GPIO_PC3 19 42 + #define TEGRA_GPIO_PC4 20 43 + #define TEGRA_GPIO_PC5 21 44 + #define TEGRA_GPIO_PC6 22 45 + #define TEGRA_GPIO_PC7 23 46 + #define TEGRA_GPIO_PD0 24 47 + #define TEGRA_GPIO_PD1 25 48 + #define TEGRA_GPIO_PD2 26 49 + #define TEGRA_GPIO_PD3 27 50 + #define TEGRA_GPIO_PD4 28 51 + #define TEGRA_GPIO_PD5 29 52 + #define TEGRA_GPIO_PD6 30 53 + #define TEGRA_GPIO_PD7 31 54 + #define TEGRA_GPIO_PE0 32 55 + #define TEGRA_GPIO_PE1 33 56 + #define TEGRA_GPIO_PE2 34 57 + #define TEGRA_GPIO_PE3 35 58 + #define TEGRA_GPIO_PE4 36 59 + #define TEGRA_GPIO_PE5 37 60 + #define TEGRA_GPIO_PE6 38 61 + #define TEGRA_GPIO_PE7 39 62 + #define TEGRA_GPIO_PF0 40 63 + #define TEGRA_GPIO_PF1 41 64 + #define TEGRA_GPIO_PF2 42 65 + #define TEGRA_GPIO_PF3 43 66 + #define TEGRA_GPIO_PF4 44 67 + #define TEGRA_GPIO_PF5 45 68 + #define TEGRA_GPIO_PF6 46 69 + #define TEGRA_GPIO_PF7 47 70 + #define TEGRA_GPIO_PG0 48 71 + #define TEGRA_GPIO_PG1 49 72 + #define TEGRA_GPIO_PG2 50 73 + #define TEGRA_GPIO_PG3 51 74 + #define TEGRA_GPIO_PG4 52 75 + #define TEGRA_GPIO_PG5 53 76 + #define TEGRA_GPIO_PG6 54 77 + #define TEGRA_GPIO_PG7 55 78 + #define TEGRA_GPIO_PH0 56 79 + #define TEGRA_GPIO_PH1 57 80 + #define TEGRA_GPIO_PH2 58 81 + #define TEGRA_GPIO_PH3 59 82 + #define TEGRA_GPIO_PH4 60 83 + #define TEGRA_GPIO_PH5 61 84 + #define TEGRA_GPIO_PH6 62 85 + #define TEGRA_GPIO_PH7 63 86 + #define TEGRA_GPIO_PI0 64 87 + #define TEGRA_GPIO_PI1 65 88 + #define TEGRA_GPIO_PI2 66 89 + #define TEGRA_GPIO_PI3 67 90 + #define TEGRA_GPIO_PI4 68 91 + #define TEGRA_GPIO_PI5 69 92 + #define TEGRA_GPIO_PI6 70 93 + #define TEGRA_GPIO_PI7 71 94 + #define TEGRA_GPIO_PJ0 72 95 + #define TEGRA_GPIO_PJ1 73 96 + #define TEGRA_GPIO_PJ2 74 97 + #define TEGRA_GPIO_PJ3 75 98 + #define TEGRA_GPIO_PJ4 76 99 + #define TEGRA_GPIO_PJ5 77 100 + #define TEGRA_GPIO_PJ6 78 101 + #define TEGRA_GPIO_PJ7 79 102 + #define TEGRA_GPIO_PK0 80 103 + #define TEGRA_GPIO_PK1 81 104 + #define TEGRA_GPIO_PK2 82 105 + #define TEGRA_GPIO_PK3 83 106 + #define TEGRA_GPIO_PK4 84 107 + #define TEGRA_GPIO_PK5 85 108 + #define TEGRA_GPIO_PK6 86 109 + #define TEGRA_GPIO_PK7 87 110 + #define TEGRA_GPIO_PL0 88 111 + #define TEGRA_GPIO_PL1 89 112 + #define TEGRA_GPIO_PL2 90 113 + #define TEGRA_GPIO_PL3 91 114 + #define TEGRA_GPIO_PL4 92 115 + #define TEGRA_GPIO_PL5 93 116 + #define TEGRA_GPIO_PL6 94 117 + #define TEGRA_GPIO_PL7 95 118 + #define TEGRA_GPIO_PM0 96 119 + #define TEGRA_GPIO_PM1 97 120 + #define TEGRA_GPIO_PM2 98 121 + #define TEGRA_GPIO_PM3 99 122 + #define TEGRA_GPIO_PM4 100 123 + #define TEGRA_GPIO_PM5 101 124 + #define TEGRA_GPIO_PM6 102 125 + #define TEGRA_GPIO_PM7 103 126 + #define TEGRA_GPIO_PN0 104 127 + #define TEGRA_GPIO_PN1 105 128 + #define TEGRA_GPIO_PN2 106 129 + #define TEGRA_GPIO_PN3 107 130 + #define TEGRA_GPIO_PN4 108 131 + #define TEGRA_GPIO_PN5 109 132 + #define TEGRA_GPIO_PN6 110 133 + #define TEGRA_GPIO_PN7 111 134 + #define TEGRA_GPIO_PO0 112 135 + #define TEGRA_GPIO_PO1 113 136 + #define TEGRA_GPIO_PO2 114 137 + #define TEGRA_GPIO_PO3 115 138 + #define TEGRA_GPIO_PO4 116 139 + #define TEGRA_GPIO_PO5 117 140 + #define TEGRA_GPIO_PO6 118 141 + #define TEGRA_GPIO_PO7 119 142 + #define TEGRA_GPIO_PP0 120 143 + #define TEGRA_GPIO_PP1 121 144 + #define TEGRA_GPIO_PP2 122 145 + #define TEGRA_GPIO_PP3 123 146 + #define TEGRA_GPIO_PP4 124 147 + #define TEGRA_GPIO_PP5 125 148 + #define TEGRA_GPIO_PP6 126 149 + #define TEGRA_GPIO_PP7 127 150 + #define TEGRA_GPIO_PQ0 128 151 + #define TEGRA_GPIO_PQ1 129 152 + #define TEGRA_GPIO_PQ2 130 153 + #define TEGRA_GPIO_PQ3 131 154 + #define TEGRA_GPIO_PQ4 132 155 + #define TEGRA_GPIO_PQ5 133 156 + #define TEGRA_GPIO_PQ6 134 157 + #define TEGRA_GPIO_PQ7 135 158 + #define TEGRA_GPIO_PR0 136 159 + #define TEGRA_GPIO_PR1 137 160 + #define TEGRA_GPIO_PR2 138 161 + #define TEGRA_GPIO_PR3 139 162 + #define TEGRA_GPIO_PR4 140 163 + #define TEGRA_GPIO_PR5 141 164 + #define TEGRA_GPIO_PR6 142 165 + #define TEGRA_GPIO_PR7 143 166 + #define TEGRA_GPIO_PS0 144 167 + #define TEGRA_GPIO_PS1 145 168 + #define TEGRA_GPIO_PS2 146 169 + #define TEGRA_GPIO_PS3 147 170 + #define TEGRA_GPIO_PS4 148 171 + #define TEGRA_GPIO_PS5 149 172 + #define TEGRA_GPIO_PS6 150 173 + #define TEGRA_GPIO_PS7 151 174 + #define TEGRA_GPIO_PT0 152 175 + #define TEGRA_GPIO_PT1 153 176 + #define TEGRA_GPIO_PT2 154 177 + #define TEGRA_GPIO_PT3 155 178 + #define TEGRA_GPIO_PT4 156 179 + #define TEGRA_GPIO_PT5 157 180 + #define TEGRA_GPIO_PT6 158 181 + #define TEGRA_GPIO_PT7 159 182 + #define TEGRA_GPIO_PU0 160 183 + #define TEGRA_GPIO_PU1 161 184 + #define TEGRA_GPIO_PU2 162 185 + #define TEGRA_GPIO_PU3 163 186 + #define TEGRA_GPIO_PU4 164 187 + #define TEGRA_GPIO_PU5 165 188 + #define TEGRA_GPIO_PU6 166 189 + #define TEGRA_GPIO_PU7 167 190 + #define TEGRA_GPIO_PV0 168 191 + #define TEGRA_GPIO_PV1 169 192 + #define TEGRA_GPIO_PV2 170 193 + #define TEGRA_GPIO_PV3 171 194 + #define TEGRA_GPIO_PV4 172 195 + #define TEGRA_GPIO_PV5 173 196 + #define TEGRA_GPIO_PV6 174 197 + #define TEGRA_GPIO_PV7 175 198 + #define TEGRA_GPIO_PW0 176 199 + #define TEGRA_GPIO_PW1 177 200 + #define TEGRA_GPIO_PW2 178 201 + #define TEGRA_GPIO_PW3 179 202 + #define TEGRA_GPIO_PW4 180 203 + #define TEGRA_GPIO_PW5 181 204 + #define TEGRA_GPIO_PW6 182 205 + #define TEGRA_GPIO_PW7 183 206 + #define TEGRA_GPIO_PX0 184 207 + #define TEGRA_GPIO_PX1 185 208 + #define TEGRA_GPIO_PX2 186 209 + #define TEGRA_GPIO_PX3 187 210 + #define TEGRA_GPIO_PX4 188 211 + #define TEGRA_GPIO_PX5 189 212 + #define TEGRA_GPIO_PX6 190 213 + #define TEGRA_GPIO_PX7 191 214 + #define TEGRA_GPIO_PY0 192 215 + #define TEGRA_GPIO_PY1 193 216 + #define TEGRA_GPIO_PY2 194 217 + #define TEGRA_GPIO_PY3 195 218 + #define TEGRA_GPIO_PY4 196 219 + #define TEGRA_GPIO_PY5 197 220 + #define TEGRA_GPIO_PY6 198 221 + #define TEGRA_GPIO_PY7 199 222 + #define TEGRA_GPIO_PZ0 200 223 + #define TEGRA_GPIO_PZ1 201 224 + #define TEGRA_GPIO_PZ2 202 225 + #define TEGRA_GPIO_PZ3 203 226 + #define TEGRA_GPIO_PZ4 204 227 + #define TEGRA_GPIO_PZ5 205 228 + #define TEGRA_GPIO_PZ6 206 229 + #define TEGRA_GPIO_PZ7 207 230 + #define TEGRA_GPIO_PAA0 208 231 + #define TEGRA_GPIO_PAA1 209 232 + #define TEGRA_GPIO_PAA2 210 233 + #define TEGRA_GPIO_PAA3 211 234 + #define TEGRA_GPIO_PAA4 212 235 + #define TEGRA_GPIO_PAA5 213 236 + #define TEGRA_GPIO_PAA6 214 237 + #define TEGRA_GPIO_PAA7 215 238 + #define TEGRA_GPIO_PBB0 216 239 + #define TEGRA_GPIO_PBB1 217 240 + #define TEGRA_GPIO_PBB2 218 241 + #define TEGRA_GPIO_PBB3 219 242 + #define TEGRA_GPIO_PBB4 220 243 + #define TEGRA_GPIO_PBB5 221 244 + #define TEGRA_GPIO_PBB6 222 245 + #define TEGRA_GPIO_PBB7 223 246 + 247 + #endif
+348
arch/arm/mach-tegra/gpio.c
···
··· 1 + /* 2 + * arch/arm/mach-tegra/gpio.c 3 + * 4 + * Copyright (c) 2010 Google, Inc 5 + * 6 + * Author: 7 + * Erik Gilling <konkers@google.com> 8 + * 9 + * This software is licensed under the terms of the GNU General Public 10 + * License version 2, as published by the Free Software Foundation, and 11 + * may be copied, distributed, and modified under those terms. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + */ 19 + 20 + #include <linux/init.h> 21 + #include <linux/irq.h> 22 + 23 + #include <linux/io.h> 24 + #include <linux/gpio.h> 25 + 26 + #include <mach/iomap.h> 27 + 28 + #define GPIO_BANK(x) ((x) >> 5) 29 + #define GPIO_PORT(x) (((x) >> 3) & 0x3) 30 + #define GPIO_BIT(x) ((x) & 0x7) 31 + 32 + #define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ 33 + GPIO_BANK(x) * 0x80 + \ 34 + GPIO_PORT(x) * 4) 35 + 36 + #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) 37 + #define GPIO_OE(x) (GPIO_REG(x) + 0x10) 38 + #define GPIO_OUT(x) (GPIO_REG(x) + 0X20) 39 + #define GPIO_IN(x) (GPIO_REG(x) + 0x30) 40 + #define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40) 41 + #define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50) 42 + #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) 43 + #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) 44 + 45 + #define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) 46 + #define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) 47 + #define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) 48 + #define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) 49 + #define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) 50 + #define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) 51 + 52 + #define GPIO_INT_LVL_MASK 0x010101 53 + #define GPIO_INT_LVL_EDGE_RISING 0x000101 54 + #define GPIO_INT_LVL_EDGE_FALLING 0x000100 55 + #define GPIO_INT_LVL_EDGE_BOTH 0x010100 56 + #define GPIO_INT_LVL_LEVEL_HIGH 0x000001 57 + #define GPIO_INT_LVL_LEVEL_LOW 0x000000 58 + 59 + struct tegra_gpio_bank { 60 + int bank; 61 + int irq; 62 + spinlock_t lvl_lock[4]; 63 + }; 64 + 65 + 66 + static struct tegra_gpio_bank tegra_gpio_banks[] = { 67 + {.bank = 0, .irq = INT_GPIO1}, 68 + {.bank = 1, .irq = INT_GPIO2}, 69 + {.bank = 2, .irq = INT_GPIO3}, 70 + {.bank = 3, .irq = INT_GPIO4}, 71 + {.bank = 4, .irq = INT_GPIO5}, 72 + {.bank = 5, .irq = INT_GPIO6}, 73 + {.bank = 6, .irq = INT_GPIO7}, 74 + }; 75 + 76 + static int tegra_gpio_compose(int bank, int port, int bit) 77 + { 78 + return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7); 79 + } 80 + 81 + static void tegra_gpio_mask_write(u32 reg, int gpio, int value) 82 + { 83 + u32 val; 84 + 85 + val = 0x100 << GPIO_BIT(gpio); 86 + if (value) 87 + val |= 1 << GPIO_BIT(gpio); 88 + __raw_writel(val, reg); 89 + } 90 + 91 + void tegra_gpio_enable(int gpio) 92 + { 93 + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); 94 + } 95 + 96 + void tegra_gpio_disable(int gpio) 97 + { 98 + tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); 99 + } 100 + 101 + static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 102 + { 103 + tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value); 104 + } 105 + 106 + static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) 107 + { 108 + return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; 109 + } 110 + 111 + static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 112 + { 113 + tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0); 114 + return 0; 115 + } 116 + 117 + static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, 118 + int value) 119 + { 120 + tegra_gpio_set(chip, offset, value); 121 + tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1); 122 + return 0; 123 + } 124 + 125 + 126 + 127 + static struct gpio_chip tegra_gpio_chip = { 128 + .label = "tegra-gpio", 129 + .direction_input = tegra_gpio_direction_input, 130 + .get = tegra_gpio_get, 131 + .direction_output = tegra_gpio_direction_output, 132 + .set = tegra_gpio_set, 133 + .base = 0, 134 + .ngpio = ARCH_NR_GPIOS, 135 + }; 136 + 137 + static void tegra_gpio_irq_ack(unsigned int irq) 138 + { 139 + int gpio = irq - INT_GPIO_BASE; 140 + 141 + __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); 142 + } 143 + 144 + static void tegra_gpio_irq_mask(unsigned int irq) 145 + { 146 + int gpio = irq - INT_GPIO_BASE; 147 + 148 + tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0); 149 + } 150 + 151 + static void tegra_gpio_irq_unmask(unsigned int irq) 152 + { 153 + int gpio = irq - INT_GPIO_BASE; 154 + 155 + tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1); 156 + } 157 + 158 + static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type) 159 + { 160 + int gpio = irq - INT_GPIO_BASE; 161 + struct tegra_gpio_bank *bank = get_irq_chip_data(irq); 162 + int port = GPIO_PORT(gpio); 163 + int lvl_type; 164 + int val; 165 + unsigned long flags; 166 + 167 + switch (type & IRQ_TYPE_SENSE_MASK) { 168 + case IRQ_TYPE_EDGE_RISING: 169 + lvl_type = GPIO_INT_LVL_EDGE_RISING; 170 + break; 171 + 172 + case IRQ_TYPE_EDGE_FALLING: 173 + lvl_type = GPIO_INT_LVL_EDGE_FALLING; 174 + break; 175 + 176 + case IRQ_TYPE_EDGE_BOTH: 177 + lvl_type = GPIO_INT_LVL_EDGE_BOTH; 178 + break; 179 + 180 + case IRQ_TYPE_LEVEL_HIGH: 181 + lvl_type = GPIO_INT_LVL_LEVEL_HIGH; 182 + break; 183 + 184 + case IRQ_TYPE_LEVEL_LOW: 185 + lvl_type = GPIO_INT_LVL_LEVEL_LOW; 186 + break; 187 + 188 + default: 189 + return -EINVAL; 190 + } 191 + 192 + spin_lock_irqsave(&bank->lvl_lock[port], flags); 193 + 194 + val = __raw_readl(GPIO_INT_LVL(gpio)); 195 + val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); 196 + val |= lvl_type << GPIO_BIT(gpio); 197 + __raw_writel(val, GPIO_INT_LVL(gpio)); 198 + 199 + spin_unlock_irqrestore(&bank->lvl_lock[port], flags); 200 + 201 + if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 202 + __set_irq_handler_unlocked(irq, handle_level_irq); 203 + else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) 204 + __set_irq_handler_unlocked(irq, handle_edge_irq); 205 + 206 + return 0; 207 + } 208 + 209 + static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 210 + { 211 + struct tegra_gpio_bank *bank; 212 + int port; 213 + int pin; 214 + int unmasked = 0; 215 + 216 + desc->chip->ack(irq); 217 + 218 + bank = get_irq_data(irq); 219 + 220 + for (port = 0; port < 4; port++) { 221 + int gpio = tegra_gpio_compose(bank->bank, port, 0); 222 + unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & 223 + __raw_readl(GPIO_INT_ENB(gpio)); 224 + u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); 225 + 226 + for_each_set_bit(pin, &sta, 8) { 227 + __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); 228 + 229 + /* if gpio is edge triggered, clear condition 230 + * before executing the hander so that we don't 231 + * miss edges 232 + */ 233 + if (lvl & (0x100 << pin)) { 234 + unmasked = 1; 235 + desc->chip->unmask(irq); 236 + } 237 + 238 + generic_handle_irq(gpio_to_irq(gpio + pin)); 239 + } 240 + } 241 + 242 + if (!unmasked) 243 + desc->chip->unmask(irq); 244 + 245 + } 246 + 247 + 248 + static struct irq_chip tegra_gpio_irq_chip = { 249 + .name = "GPIO", 250 + .ack = tegra_gpio_irq_ack, 251 + .mask = tegra_gpio_irq_mask, 252 + .unmask = tegra_gpio_irq_unmask, 253 + .set_type = tegra_gpio_irq_set_type, 254 + }; 255 + 256 + 257 + /* This lock class tells lockdep that GPIO irqs are in a different 258 + * category than their parents, so it won't report false recursion. 259 + */ 260 + static struct lock_class_key gpio_lock_class; 261 + 262 + static int __init tegra_gpio_init(void) 263 + { 264 + struct tegra_gpio_bank *bank; 265 + int i; 266 + int j; 267 + 268 + for (i = 0; i < 7; i++) { 269 + for (j = 0; j < 4; j++) { 270 + int gpio = tegra_gpio_compose(i, j, 0); 271 + __raw_writel(0x00, GPIO_INT_ENB(gpio)); 272 + } 273 + } 274 + 275 + gpiochip_add(&tegra_gpio_chip); 276 + 277 + for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) { 278 + bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))]; 279 + 280 + lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class); 281 + set_irq_chip_data(i, bank); 282 + set_irq_chip(i, &tegra_gpio_irq_chip); 283 + set_irq_handler(i, handle_simple_irq); 284 + set_irq_flags(i, IRQF_VALID); 285 + } 286 + 287 + for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { 288 + bank = &tegra_gpio_banks[i]; 289 + 290 + set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler); 291 + set_irq_data(bank->irq, bank); 292 + 293 + for (j = 0; j < 4; j++) 294 + spin_lock_init(&bank->lvl_lock[j]); 295 + } 296 + 297 + return 0; 298 + } 299 + 300 + postcore_initcall(tegra_gpio_init); 301 + 302 + #ifdef CONFIG_DEBUG_FS 303 + 304 + #include <linux/debugfs.h> 305 + #include <linux/seq_file.h> 306 + 307 + static int dbg_gpio_show(struct seq_file *s, void *unused) 308 + { 309 + int i; 310 + int j; 311 + 312 + for (i = 0; i < 7; i++) { 313 + for (j = 0; j < 4; j++) { 314 + int gpio = tegra_gpio_compose(i, j, 0); 315 + seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", 316 + i, j, 317 + __raw_readl(GPIO_CNF(gpio)), 318 + __raw_readl(GPIO_OE(gpio)), 319 + __raw_readl(GPIO_OUT(gpio)), 320 + __raw_readl(GPIO_IN(gpio)), 321 + __raw_readl(GPIO_INT_STA(gpio)), 322 + __raw_readl(GPIO_INT_ENB(gpio)), 323 + __raw_readl(GPIO_INT_LVL(gpio))); 324 + } 325 + } 326 + return 0; 327 + } 328 + 329 + static int dbg_gpio_open(struct inode *inode, struct file *file) 330 + { 331 + return single_open(file, dbg_gpio_show, &inode->i_private); 332 + } 333 + 334 + static const struct file_operations debug_fops = { 335 + .open = dbg_gpio_open, 336 + .read = seq_read, 337 + .llseek = seq_lseek, 338 + .release = single_release, 339 + }; 340 + 341 + static int __init tegra_gpio_debuginit(void) 342 + { 343 + (void) debugfs_create_file("tegra_gpio", S_IRUGO, 344 + NULL, NULL, &debug_fops); 345 + return 0; 346 + } 347 + late_initcall(tegra_gpio_debuginit); 348 + #endif
+53
arch/arm/mach-tegra/include/mach/gpio.h
···
··· 1 + /* 2 + * arch/arm/mach-tegra/include/mach/gpio.h 3 + * 4 + * Copyright (C) 2010 Google, Inc. 5 + * 6 + * Author: 7 + * Erik Gilling <konkers@google.com> 8 + * 9 + * This software is licensed under the terms of the GNU General Public 10 + * License version 2, as published by the Free Software Foundation, and 11 + * may be copied, distributed, and modified under those terms. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + */ 19 + 20 + #ifndef __MACH_TEGRA_GPIO_H 21 + #define __MACH_TEGRA_GPIO_H 22 + 23 + #include <mach/irqs.h> 24 + 25 + #define ARCH_NR_GPIOS INT_GPIO_NR 26 + 27 + #include <asm-generic/gpio.h> 28 + 29 + #define gpio_get_value __gpio_get_value 30 + #define gpio_set_value __gpio_set_value 31 + #define gpio_cansleep __gpio_cansleep 32 + 33 + #define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio)) 34 + #define TEGRA_IRQ_TO_GPIO(irq) ((gpio) - INT_GPIO_BASE) 35 + 36 + static inline int gpio_to_irq(unsigned int gpio) 37 + { 38 + if (gpio < ARCH_NR_GPIOS) 39 + return INT_GPIO_BASE + gpio; 40 + return -EINVAL; 41 + } 42 + 43 + static inline int irq_to_gpio(unsigned int irq) 44 + { 45 + if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR)) 46 + return irq - INT_GPIO_BASE; 47 + return -EINVAL; 48 + } 49 + 50 + void tegra_gpio_enable(int gpio); 51 + void tegra_gpio_disable(int gpio); 52 + 53 + #endif