aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-01 23:31:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-01 23:31:25 -0400
commit16ee792e45cf0c97ce061fce03c36cab5551ec72 (patch)
treedc68af705fbac4b5d71325aa972730199bb187dd /drivers/gpio
parentf906fb1d70e016726fccfb0d978c5d425503db9d (diff)
parentefa62e1355f0495f37f1296754b8880947c8da72 (diff)
Merge branch 'next/devel' of git://git.linaro.org/people/arnd/arm-soc
* 'next/devel' of git://git.linaro.org/people/arnd/arm-soc: (50 commits) ARM: tegra: update defconfig arm/tegra: Harmony: Configure PMC for low-level interrupts arm/tegra: device tree support for ventana board arm/tegra: add support for ventana pinmuxing arm/tegra: prepare Seaboard pinmux code for derived boards arm/tegra: pinmux: ioremap registers gpio/tegra: Convert to a platform device arm/tegra: Convert pinmux driver to a platform device arm/dt: Tegra: Add pinmux node to tegra20.dtsi arm/tegra: Prep boards for gpio/pinmux conversion to pdevs ARM: mx5: fix clock usage for suspend ARM i.MX entry-macro.S: remove now unused code ARM i.MX boards: use CONFIG_MULTI_IRQ_HANDLER ARM i.MX tzic: add handle_irq function ARM i.MX avic: add handle_irq function ARM: mx25: Add the missing IIM base definition ARM i.MX avic: convert to use generic irq chip mx31moboard: Add poweroff support ARM: mach-qong: Add watchdog support ARM: davinci: AM18x: Add wl1271/wlan support ... Fix up conflicts in: arch/arm/mach-at91/at91sam9g45.c arch/arm/mach-mx5/devices-imx53.h arch/arm/plat-mxc/include/mach/memory.h
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-tegra.c143
1 files changed, 95 insertions, 48 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 6b65207c8106..61044c889f7f 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -20,10 +20,11 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23
24#include <linux/io.h> 23#include <linux/io.h>
25#include <linux/gpio.h> 24#include <linux/gpio.h>
26#include <linux/of.h> 25#include <linux/of.h>
26#include <linux/platform_device.h>
27#include <linux/module.h>
27 28
28#include <asm/mach/irq.h> 29#include <asm/mach/irq.h>
29 30
@@ -35,9 +36,7 @@
35#define GPIO_PORT(x) (((x) >> 3) & 0x3) 36#define GPIO_PORT(x) (((x) >> 3) & 0x3)
36#define GPIO_BIT(x) ((x) & 0x7) 37#define GPIO_BIT(x) ((x) & 0x7)
37 38
38#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ 39#define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4)
39 GPIO_BANK(x) * 0x80 + \
40 GPIO_PORT(x) * 4)
41 40
42#define GPIO_CNF(x) (GPIO_REG(x) + 0x00) 41#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
43#define GPIO_OE(x) (GPIO_REG(x) + 0x10) 42#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
@@ -76,15 +75,18 @@ struct tegra_gpio_bank {
76}; 75};
77 76
78 77
79static struct tegra_gpio_bank tegra_gpio_banks[] = { 78static void __iomem *regs;
80 {.bank = 0, .irq = INT_GPIO1}, 79static struct tegra_gpio_bank tegra_gpio_banks[7];
81 {.bank = 1, .irq = INT_GPIO2}, 80
82 {.bank = 2, .irq = INT_GPIO3}, 81static inline void tegra_gpio_writel(u32 val, u32 reg)
83 {.bank = 3, .irq = INT_GPIO4}, 82{
84 {.bank = 4, .irq = INT_GPIO5}, 83 __raw_writel(val, regs + reg);
85 {.bank = 5, .irq = INT_GPIO6}, 84}
86 {.bank = 6, .irq = INT_GPIO7}, 85
87}; 86static inline u32 tegra_gpio_readl(u32 reg)
87{
88 return __raw_readl(regs + reg);
89}
88 90
89static int tegra_gpio_compose(int bank, int port, int bit) 91static int tegra_gpio_compose(int bank, int port, int bit)
90{ 92{
@@ -98,7 +100,7 @@ static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
98 val = 0x100 << GPIO_BIT(gpio); 100 val = 0x100 << GPIO_BIT(gpio);
99 if (value) 101 if (value)
100 val |= 1 << GPIO_BIT(gpio); 102 val |= 1 << GPIO_BIT(gpio);
101 __raw_writel(val, reg); 103 tegra_gpio_writel(val, reg);
102} 104}
103 105
104void tegra_gpio_enable(int gpio) 106void tegra_gpio_enable(int gpio)
@@ -118,7 +120,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
118 120
119static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) 121static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
120{ 122{
121 return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; 123 return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
122} 124}
123 125
124static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 126static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -155,7 +157,7 @@ static void tegra_gpio_irq_ack(struct irq_data *d)
155{ 157{
156 int gpio = d->irq - INT_GPIO_BASE; 158 int gpio = d->irq - INT_GPIO_BASE;
157 159
158 __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); 160 tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
159} 161}
160 162
161static void tegra_gpio_irq_mask(struct irq_data *d) 163static void tegra_gpio_irq_mask(struct irq_data *d)
@@ -208,10 +210,10 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
208 210
209 spin_lock_irqsave(&bank->lvl_lock[port], flags); 211 spin_lock_irqsave(&bank->lvl_lock[port], flags);
210 212
211 val = __raw_readl(GPIO_INT_LVL(gpio)); 213 val = tegra_gpio_readl(GPIO_INT_LVL(gpio));
212 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); 214 val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
213 val |= lvl_type << GPIO_BIT(gpio); 215 val |= lvl_type << GPIO_BIT(gpio);
214 __raw_writel(val, GPIO_INT_LVL(gpio)); 216 tegra_gpio_writel(val, GPIO_INT_LVL(gpio));
215 217
216 spin_unlock_irqrestore(&bank->lvl_lock[port], flags); 218 spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
217 219
@@ -237,12 +239,12 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
237 239
238 for (port = 0; port < 4; port++) { 240 for (port = 0; port < 4; port++) {
239 int gpio = tegra_gpio_compose(bank->bank, port, 0); 241 int gpio = tegra_gpio_compose(bank->bank, port, 0);
240 unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & 242 unsigned long sta = tegra_gpio_readl(GPIO_INT_STA(gpio)) &
241 __raw_readl(GPIO_INT_ENB(gpio)); 243 tegra_gpio_readl(GPIO_INT_ENB(gpio));
242 u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); 244 u32 lvl = tegra_gpio_readl(GPIO_INT_LVL(gpio));
243 245
244 for_each_set_bit(pin, &sta, 8) { 246 for_each_set_bit(pin, &sta, 8) {
245 __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); 247 tegra_gpio_writel(1 << pin, GPIO_INT_CLR(gpio));
246 248
247 /* if gpio is edge triggered, clear condition 249 /* if gpio is edge triggered, clear condition
248 * before executing the hander so that we don't 250 * before executing the hander so that we don't
@@ -276,11 +278,11 @@ void tegra_gpio_resume(void)
276 278
277 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { 279 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
278 unsigned int gpio = (b<<5) | (p<<3); 280 unsigned int gpio = (b<<5) | (p<<3);
279 __raw_writel(bank->cnf[p], GPIO_CNF(gpio)); 281 tegra_gpio_writel(bank->cnf[p], GPIO_CNF(gpio));
280 __raw_writel(bank->out[p], GPIO_OUT(gpio)); 282 tegra_gpio_writel(bank->out[p], GPIO_OUT(gpio));
281 __raw_writel(bank->oe[p], GPIO_OE(gpio)); 283 tegra_gpio_writel(bank->oe[p], GPIO_OE(gpio));
282 __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); 284 tegra_gpio_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
283 __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); 285 tegra_gpio_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
284 } 286 }
285 } 287 }
286 288
@@ -299,11 +301,11 @@ void tegra_gpio_suspend(void)
299 301
300 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { 302 for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
301 unsigned int gpio = (b<<5) | (p<<3); 303 unsigned int gpio = (b<<5) | (p<<3);
302 bank->cnf[p] = __raw_readl(GPIO_CNF(gpio)); 304 bank->cnf[p] = tegra_gpio_readl(GPIO_CNF(gpio));
303 bank->out[p] = __raw_readl(GPIO_OUT(gpio)); 305 bank->out[p] = tegra_gpio_readl(GPIO_OUT(gpio));
304 bank->oe[p] = __raw_readl(GPIO_OE(gpio)); 306 bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio));
305 bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio)); 307 bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio));
306 bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio)); 308 bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio));
307 } 309 }
308 } 310 }
309 local_irq_restore(flags); 311 local_irq_restore(flags);
@@ -333,28 +335,55 @@ static struct irq_chip tegra_gpio_irq_chip = {
333 */ 335 */
334static struct lock_class_key gpio_lock_class; 336static struct lock_class_key gpio_lock_class;
335 337
336static int __init tegra_gpio_init(void) 338static int __devinit tegra_gpio_probe(struct platform_device *pdev)
337{ 339{
340 struct resource *res;
338 struct tegra_gpio_bank *bank; 341 struct tegra_gpio_bank *bank;
339 int gpio; 342 int gpio;
340 int i; 343 int i;
341 int j; 344 int j;
342 345
346 for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
347 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
348 if (!res) {
349 dev_err(&pdev->dev, "Missing IRQ resource\n");
350 return -ENODEV;
351 }
352
353 bank = &tegra_gpio_banks[i];
354 bank->bank = i;
355 bank->irq = res->start;
356 }
357
358 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
359 if (!res) {
360 dev_err(&pdev->dev, "Missing MEM resource\n");
361 return -ENODEV;
362 }
363
364 if (!devm_request_mem_region(&pdev->dev, res->start,
365 resource_size(res),
366 dev_name(&pdev->dev))) {
367 dev_err(&pdev->dev, "Couldn't request MEM resource\n");
368 return -ENODEV;
369 }
370
371 regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
372 if (!regs) {
373 dev_err(&pdev->dev, "Couldn't ioremap regs\n");
374 return -ENODEV;
375 }
376
343 for (i = 0; i < 7; i++) { 377 for (i = 0; i < 7; i++) {
344 for (j = 0; j < 4; j++) { 378 for (j = 0; j < 4; j++) {
345 int gpio = tegra_gpio_compose(i, j, 0); 379 int gpio = tegra_gpio_compose(i, j, 0);
346 __raw_writel(0x00, GPIO_INT_ENB(gpio)); 380 tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
347 } 381 }
348 } 382 }
349 383
350#ifdef CONFIG_OF_GPIO 384#ifdef CONFIG_OF_GPIO
351 /* 385 tegra_gpio_chip.of_node = pdev->dev.of_node;
352 * This isn't ideal, but it gets things hooked up until this 386#endif
353 * driver is converted into a platform_device
354 */
355 tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL,
356 "nvidia,tegra20-gpio");
357#endif /* CONFIG_OF_GPIO */
358 387
359 gpiochip_add(&tegra_gpio_chip); 388 gpiochip_add(&tegra_gpio_chip);
360 389
@@ -384,6 +413,24 @@ static int __init tegra_gpio_init(void)
384 return 0; 413 return 0;
385} 414}
386 415
416static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
417 { .compatible = "nvidia,tegra20-gpio", },
418 { },
419};
420
421static struct platform_driver tegra_gpio_driver = {
422 .driver = {
423 .name = "tegra-gpio",
424 .owner = THIS_MODULE,
425 .of_match_table = tegra_gpio_of_match,
426 },
427 .probe = tegra_gpio_probe,
428};
429
430static int __init tegra_gpio_init(void)
431{
432 return platform_driver_register(&tegra_gpio_driver);
433}
387postcore_initcall(tegra_gpio_init); 434postcore_initcall(tegra_gpio_init);
388 435
389void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) 436void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
@@ -416,13 +463,13 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
416 seq_printf(s, 463 seq_printf(s,
417 "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", 464 "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
418 i, j, 465 i, j,
419 __raw_readl(GPIO_CNF(gpio)), 466 tegra_gpio_readl(GPIO_CNF(gpio)),
420 __raw_readl(GPIO_OE(gpio)), 467 tegra_gpio_readl(GPIO_OE(gpio)),
421 __raw_readl(GPIO_OUT(gpio)), 468 tegra_gpio_readl(GPIO_OUT(gpio)),
422 __raw_readl(GPIO_IN(gpio)), 469 tegra_gpio_readl(GPIO_IN(gpio)),
423 __raw_readl(GPIO_INT_STA(gpio)), 470 tegra_gpio_readl(GPIO_INT_STA(gpio)),
424 __raw_readl(GPIO_INT_ENB(gpio)), 471 tegra_gpio_readl(GPIO_INT_ENB(gpio)),
425 __raw_readl(GPIO_INT_LVL(gpio))); 472 tegra_gpio_readl(GPIO_INT_LVL(gpio)));
426 } 473 }
427 } 474 }
428 return 0; 475 return 0;