u32 intstat;
};
-static DEFINE_SPINLOCK(gpio_lock);
-
#define chip2controller(chip) \
container_of(chip, struct davinci_gpio_controller, chip)
static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
+static void __iomem *gpio_base;
static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
{
void __iomem *ptr;
- void __iomem *base = davinci_soc_info.gpio_base;
if (gpio < 32 * 1)
- ptr = base + 0x10;
+ ptr = gpio_base + 0x10;
else if (gpio < 32 * 2)
- ptr = base + 0x38;
+ ptr = gpio_base + 0x38;
else if (gpio < 32 * 3)
- ptr = base + 0x60;
+ ptr = gpio_base + 0x60;
else if (gpio < 32 * 4)
- ptr = base + 0x88;
+ ptr = gpio_base + 0x88;
else if (gpio < 32 * 5)
- ptr = base + 0xb0;
+ ptr = gpio_base + 0xb0;
else
ptr = NULL;
return ptr;
/*--------------------------------------------------------------------------*/
-/*
- * board setup code *MUST* set PINMUX0 and PINMUX1 as
- * needed, and enable the GPIO clock.
- */
-
+/* board setup code *MUST* setup pinmux and enable the GPIO clock. */
static inline int __davinci_direction(struct gpio_chip *chip,
unsigned offset, bool out, int value)
{
struct davinci_gpio_controller *d = chip2controller(chip);
struct davinci_gpio_regs __iomem *g = d->regs;
+ unsigned long flags;
u32 temp;
u32 mask = 1 << offset;
- spin_lock(&gpio_lock);
+ spin_lock_irqsave(&d->lock, flags);
temp = __raw_readl(&g->dir);
if (out) {
temp &= ~mask;
temp |= mask;
}
__raw_writel(temp, &g->dir);
- spin_unlock(&gpio_lock);
+ spin_unlock_irqrestore(&d->lock, flags);
return 0;
}
struct davinci_soc_info *soc_info = &davinci_soc_info;
struct davinci_gpio_regs *regs;
+ if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
+ return 0;
+
/*
* The gpio banks conceptually expose a segmented bitmap,
* and "ngpio" is one more than the largest zero-based
if (WARN_ON(DAVINCI_N_GPIO < ngpio))
ngpio = DAVINCI_N_GPIO;
+ gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
+ if (WARN_ON(!gpio_base))
+ return -ENOMEM;
+
for (i = 0, base = 0; base < ngpio; i++, base += 32) {
chips[i].chip.label = "DaVinci";
if (chips[i].chip.ngpio > 32)
chips[i].chip.ngpio = 32;
+ spin_lock_init(&chips[i].lock);
+
regs = gpio2regs(base);
chips[i].regs = regs;
chips[i].set_data = ®s->set_data;
/* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set/cleared dynamically.
*/
- __raw_writel(binten, soc_info->gpio_base + 0x08);
+ __raw_writel(binten, gpio_base + 0x08);
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));