dect
/
linux-2.6
Archived
13
0
Fork 0

davinci: gpio bugfixes

Update the DaVinci GPIO code to work better on non-dm6446 parts,
notably the dm355:

 - Only handle the number of GPIOs the chip actually has.  So
   for example on dm6467, GPIO-42 is the last GPIO, and trying
   to use GPIO-43 now fails cleanly; or GPIO-72 on dm6446.

 - Enable GPIO interrupts on each 16-bit GPIO-irq bank ...
   previously, only the first five were enabled, so GPIO-80
   and above (on dm355) wouldn't trigger IRQs.

 - Use the right IRQ for each GPIO bank.  The wrong values were
   used for dm355 chips, so GPIO IRQs got routed incorrectly.

 - Handle up to four pairs of 16-bit GPIO banks ... previously
   only three were handled, so accessing GPIO-96 and up (e.g. on
   dm355) would oops.

 - Update several comments that were dm6446-specific.

Verified by receiving GPIO-1 (dm9000) and GPIO-5 (msp430) IRQs
on the DM355 EVM.

One thing this doesn't do is handle the way some of the GPIO
numbers on dm6467 are reserved but aren't valid as GPIOs.  Some
bitmap logic could fix that if needed.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
This commit is contained in:
David Brownell 2008-12-07 11:46:23 -08:00 committed by Kevin Hilman
parent a4768d2275
commit 474dad54ba
2 changed files with 69 additions and 36 deletions

View File

@ -20,6 +20,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <mach/cputype.h>
#include <mach/irqs.h> #include <mach/irqs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio.h> #include <mach/gpio.h>
@ -36,9 +37,10 @@ struct davinci_gpio {
static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
static unsigned __initdata ngpio;
/* create a non-inlined version */ /* create a non-inlined version */
static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio) static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
{ {
return __gpio_to_controller(gpio); return __gpio_to_controller(gpio);
} }
@ -114,9 +116,30 @@ static int __init davinci_gpio_setup(void)
{ {
int i, base; int i, base;
for (i = 0, base = 0; /* The gpio banks conceptually expose a segmented bitmap,
i < ARRAY_SIZE(chips); * and "ngpio" is one more than the largest zero-based
i++, base += 32) { * bit index that's valid.
*/
if (cpu_is_davinci_dm355()) { /* or dm335() */
ngpio = 104;
} else if (cpu_is_davinci_dm644x()) { /* or dm337() */
ngpio = 71;
} else if (cpu_is_davinci_dm646x()) {
/* NOTE: each bank has several "reserved" bits,
* unusable as GPIOs. Only 33 of the GPIO numbers
* are usable, and we're not rejecting the others.
*/
ngpio = 43;
} else {
/* if cpu_is_davinci_dm643x() ngpio = 111 */
pr_err("GPIO setup: how many GPIOs?\n");
return -EINVAL;
}
if (WARN_ON(DAVINCI_N_GPIO < ngpio))
ngpio = DAVINCI_N_GPIO;
for (i = 0, base = 0; base < ngpio; i++, base += 32) {
chips[i].chip.label = "DaVinci"; chips[i].chip.label = "DaVinci";
chips[i].chip.direction_input = davinci_direction_in; chips[i].chip.direction_input = davinci_direction_in;
@ -125,7 +148,7 @@ static int __init davinci_gpio_setup(void)
chips[i].chip.set = davinci_gpio_set; chips[i].chip.set = davinci_gpio_set;
chips[i].chip.base = base; chips[i].chip.base = base;
chips[i].chip.ngpio = DAVINCI_N_GPIO - base; chips[i].chip.ngpio = ngpio - base;
if (chips[i].chip.ngpio > 32) if (chips[i].chip.ngpio > 32)
chips[i].chip.ngpio = 32; chips[i].chip.ngpio = 32;
@ -143,11 +166,11 @@ pure_initcall(davinci_gpio_setup);
* We expect irqs will normally be set up as input pins, but they can also be * We expect irqs will normally be set up as input pins, but they can also be
* used as output pins ... which is convenient for testing. * used as output pins ... which is convenient for testing.
* *
* NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition * NOTE: The first few GPIOs also have direct INTC hookups in addition
* to their GPIOBNK0 irq (but with a bit less overhead). But we don't have * to their GPIOBNK0 irq, with a bit less overhead but less flexibility
* a good way to hook those up ... * on triggering (e.g. no edge options). We don't try to use those.
* *
* All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also * All those INTC hookups (direct, plus several IRQ banks) can also
* serve as EDMA event triggers. * serve as EDMA event triggers.
*/ */
@ -235,29 +258,42 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
} }
/* /*
* NOTE: for suspend/resume, probably best to make a sysdev (and class) * NOTE: for suspend/resume, probably best to make a platform_device with
* with its suspend/resume calls hooking into the results of the set_wake() * suspend_late/resume_resume calls hooking into results of the set_wake()
* calls ... so if no gpios are wakeup events the clock can be disabled, * calls ... so if no gpios are wakeup events the clock can be disabled,
* with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0 * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
* can be set appropriately for GPIOV33 pins. * (dm6446) can be set appropriately for GPIOV33 pins.
*/ */
static int __init davinci_gpio_irq_setup(void) static int __init davinci_gpio_irq_setup(void)
{ {
unsigned gpio, irq, bank; unsigned gpio, irq, bank;
unsigned bank_irq;
struct clk *clk; struct clk *clk;
u32 binten = 0;
if (cpu_is_davinci_dm355()) { /* or dm335() */
bank_irq = IRQ_DM355_GPIOBNK0;
} else if (cpu_is_davinci_dm644x()) {
bank_irq = IRQ_GPIOBNK0;
} else if (cpu_is_davinci_dm646x()) {
bank_irq = IRQ_DM646X_GPIOBNK0;
} else {
printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
return -EINVAL;
}
clk = clk_get(NULL, "gpio"); clk = clk_get(NULL, "gpio");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
printk(KERN_ERR "Error %ld getting gpio clock?\n", printk(KERN_ERR "Error %ld getting gpio clock?\n",
PTR_ERR(clk)); PTR_ERR(clk));
return 0; return PTR_ERR(clk);
} }
clk_enable(clk); clk_enable(clk);
for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0; for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
gpio < DAVINCI_N_GPIO; bank++) { gpio < ngpio;
bank++, bank_irq++) {
struct gpio_controller *__iomem g = gpio2controller(gpio); struct gpio_controller *__iomem g = gpio2controller(gpio);
unsigned i; unsigned i;
@ -265,28 +301,28 @@ static int __init davinci_gpio_irq_setup(void)
__raw_writel(~0, &g->clr_rising); __raw_writel(~0, &g->clr_rising);
/* set up all irqs in this bank */ /* set up all irqs in this bank */
set_irq_chained_handler(bank, gpio_irq_handler); set_irq_chained_handler(bank_irq, gpio_irq_handler);
set_irq_chip_data(bank, g); set_irq_chip_data(bank_irq, g);
set_irq_data(bank, (void *)irq); set_irq_data(bank_irq, (void *)irq);
for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO; for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
i++, irq++, gpio++) {
set_irq_chip(irq, &gpio_irqchip); set_irq_chip(irq, &gpio_irqchip);
set_irq_chip_data(irq, g); set_irq_chip_data(irq, g);
set_irq_handler(irq, handle_simple_irq); set_irq_handler(irq, handle_simple_irq);
set_irq_flags(irq, IRQF_VALID); set_irq_flags(irq, IRQF_VALID);
} }
binten |= BIT(bank);
} }
/* BINTEN -- per-bank interrupt enable. genirq would also let these /* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set/cleared dynamically. * bits be set/cleared dynamically.
*/ */
__raw_writel(0x1f, (void *__iomem) __raw_writel(binten, (void *__iomem)
IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08)); IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
return 0; return 0;
} }
arch_initcall(davinci_gpio_irq_setup); arch_initcall(davinci_gpio_irq_setup);

View File

@ -28,23 +28,18 @@
* go through boot loaders. * go through boot loaders.
* *
* the gpio clock will be turned on when gpios are used, and you may also * the gpio clock will be turned on when gpios are used, and you may also
* need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are * need to pay attention to PINMUX registers to be sure those pins are
* used as gpios, not with other peripherals. * used as gpios, not with other peripherals.
* *
* On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation, * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
* and maybe for later updates, code should write GPIO(N) or: * and maybe for later updates, code may write GPIO(N). These may be
* - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53) * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
* - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70) * may not support all the GPIOs in that range.
*
* For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
* for now, that's != GPIO(N)
* *
* GPIOs can also be on external chips, numbered after the ones built-in * GPIOs can also be on external chips, numbered after the ones built-in
* to the DaVinci chip. For now, they won't be usable as IRQ sources. * to the DaVinci chip. For now, they won't be usable as IRQ sources.
*/ */
#define GPIO(X) (X) /* 0 <= X <= 70 */ #define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
#define GPIOV18(X) (X) /* 1.8V i/o; 0 <= X <= 53 */
#define GPIOV33(X) ((X)+54) /* 3.3V i/o; 0 <= X <= 17 */
struct gpio_controller { struct gpio_controller {
u32 dir; u32 dir;
@ -73,12 +68,14 @@ __gpio_to_controller(unsigned gpio)
{ {
void *__iomem ptr; void *__iomem ptr;
if (gpio < 32) if (gpio < 32 * 1)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10); ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
else if (gpio < 64) else if (gpio < 32 * 2)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38); ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
else if (gpio < DAVINCI_N_GPIO) else if (gpio < 32 * 3)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60); ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
else if (gpio < 32 * 4)
ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
else else
ptr = NULL; ptr = NULL;
return ptr; return ptr;