Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a994955c authored by Mark A. Greer's avatar Mark A. Greer Committed by Kevin Hilman
Browse files

davinci: Make GPIO code more generic



The current gpio code needs to know the number of
gpio irqs there are and what the bank irq number is.
To determine those values, it checks the SoC type.

It also assumes that the base address and the number
of irqs the interrupt controller uses is fixed.

To clean up the SoC checks and make it support
different base addresses and interrupt controllers,
have the SoC-specific code set those values in
the soc_info structure and have the gpio code
reference them there.

Signed-off-by: default avatarMark A. Greer <mgreer@mvista.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent 951d6f6d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>

#include <linux/spi/spi.h>

@@ -647,6 +648,9 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
	.timer_info		= &dm355_timer_info,
	.wdt_base		= IO_ADDRESS(DAVINCI_WDOG_BASE),
	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
	.gpio_num		= 104,
	.gpio_irq		= IRQ_DM355_GPIOBNK0,
};

void __init dm355_init(void)
+4 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>

#include <asm/mach/map.h>

@@ -590,6 +591,9 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
	.timer_info		= &dm644x_timer_info,
	.wdt_base		= IO_ADDRESS(DAVINCI_WDOG_BASE),
	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
	.gpio_num		= 71,
	.gpio_irq		= IRQ_GPIOBNK0,
};

void __init dm644x_init(void)
+4 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>

#include <asm/mach/map.h>

@@ -569,6 +570,9 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
	.timer_info		= &dm646x_timer_info,
	.wdt_base		= IO_ADDRESS(DAVINCI_WDOG_BASE),
	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
	.gpio_num		= 43, /* Only 33 usable */
	.gpio_irq		= IRQ_DM646X_GPIOBNK0,
};

void __init dm646x_init(void)
+14 −25
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <mach/cputype.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/gpio.h>

#include <asm/mach/irq.h>
@@ -37,8 +38,6 @@ struct davinci_gpio {

static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];

static unsigned __initdata ngpio;

/* create a non-inlined version */
static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
{
@@ -116,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int __init davinci_gpio_setup(void)
{
	int i, base;
	unsigned ngpio;
	struct davinci_soc_info *soc_info = &davinci_soc_info;

	/* The gpio banks conceptually expose a segmented bitmap,
	/*
	 * The gpio banks conceptually expose a segmented bitmap,
	 * and "ngpio" is one more than the largest zero-based
	 * 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 */
	ngpio = soc_info->gpio_num;
	if (ngpio == 0) {
		pr_err("GPIO setup:  how many GPIOs?\n");
		return -EINVAL;
	}
@@ -279,17 +271,15 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
static int __init davinci_gpio_irq_setup(void)
{
	unsigned	gpio, irq, bank;
	unsigned	bank_irq;
	struct clk	*clk;
	u32		binten = 0;
	unsigned	ngpio, bank_irq;
	struct davinci_soc_info *soc_info = &davinci_soc_info;

	ngpio = soc_info->gpio_num;

	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 {
	bank_irq = soc_info->gpio_irq;
	if (bank_irq == 0) {
		printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
		return -EINVAL;
	}
@@ -329,8 +319,7 @@ static int __init davinci_gpio_irq_setup(void)
	/* BINTEN -- per-bank interrupt enable. genirq would also let these
	 * bits be set/cleared dynamically.
	 */
	__raw_writel(binten, (void *__iomem)
		     IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
	__raw_writel(binten, soc_info->gpio_base + 0x08);

	printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));

+3 −0
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ struct davinci_soc_info {
	unsigned long			intc_irq_num;
	struct davinci_timer_info	*timer_info;
	void __iomem			*wdt_base;
	void __iomem			*gpio_base;
	unsigned			gpio_num;
	unsigned			gpio_irq;
};

extern struct davinci_soc_info davinci_soc_info;
Loading