diff options
51 files changed, 2172 insertions, 535 deletions
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index de3cc130ab8..0b1c07ffa2f 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -49,6 +49,12 @@ ifeq ($(CONFIG_ARCH_OMAP15XX),y)  obj-$(CONFIG_MACH_OMAP_INNOVATOR)	+= fpga.o  endif +# GPIO +obj-$(CONFIG_ARCH_OMAP730)		+= gpio7xx.o +obj-$(CONFIG_ARCH_OMAP850)		+= gpio7xx.o +obj-$(CONFIG_ARCH_OMAP15XX)		+= gpio15xx.o +obj-$(CONFIG_ARCH_OMAP16XX)		+= gpio16xx.o +  # LEDs support  led-$(CONFIG_MACH_OMAP_H2)		+= leds-h2p2-debug.o  led-$(CONFIG_MACH_OMAP_H3)		+= leds-h2p2-debug.o diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index dc82f3d028b..e1439506eba 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -141,7 +141,6 @@ static void __init ams_delta_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init();  }  static struct map_desc ams_delta_io_desc[] __initdata = { diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index 149fdd32e12..0c3f396328b 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -120,6 +120,15 @@ static struct resource smc91x_resources[] = {  	},  }; +static void __init fsample_init_smc91x(void) +{ +	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); +	mdelay(50); +	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1, +		   H2P2_DBG_FPGA_LAN_RESET); +	mdelay(50); +} +  static struct mtd_partition nor_partitions[] = {  	/* bootloader (U-Boot, etc) in first sector */  	{ @@ -285,6 +294,8 @@ static struct omap_board_config_kernel fsample_config[] = {  static void __init omap_fsample_init(void)  { +	fsample_init_smc91x(); +  	if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0)  		BUG();  	gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN); @@ -312,21 +323,10 @@ static void __init omap_fsample_init(void)  	omap_register_i2c_bus(1, 100, NULL, 0);  } -static void __init fsample_init_smc91x(void) -{ -	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); -	mdelay(50); -	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1, -		   H2P2_DBG_FPGA_LAN_RESET); -	mdelay(50); -} -  static void __init omap_fsample_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init(); -	fsample_init_smc91x();  }  /* Only FPGA needs to be mapped here. All others are done with ioremap */ diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 197adb49dc5..082a73ca556 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -374,8 +374,6 @@ static void __init h2_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init(); -	h2_init_smc91x();  }  static struct omap_usb_config h2_usb_config __initdata = { @@ -403,6 +401,8 @@ static struct omap_board_config_kernel h2_config[] __initdata = {  static void __init h2_init(void)  { +	h2_init_smc91x(); +  	/* Here we assume the NOR boot config:  NOR on CS3 (possibly swapped  	 * to address 0 by a dip switch), NAND on CS2B.  The NAND driver will  	 * notice whether a NAND chip is enabled at probe time. diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 9126e3e37b4..d2cff5022fe 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -264,6 +264,15 @@ static struct platform_device smc91x_device = {  	.resource	= smc91x_resources,  }; +static void __init h3_init_smc91x(void) +{ +	omap_cfg_reg(W15_1710_GPIO40); +	if (gpio_request(40, "SMC91x irq") < 0) { +		printk("Error requesting gpio 40 for smc91x irq\n"); +		return; +	} +} +  #define GPTIMER_BASE		0xFFFB1400  #define GPTIMER_REGS(x)	(0xFFFB1400 + (x * 0x800))  #define GPTIMER_REGS_SIZE	0x46 @@ -376,6 +385,8 @@ static struct i2c_board_info __initdata h3_i2c_board_info[] = {  static void __init h3_init(void)  { +	h3_init_smc91x(); +  	/* Here we assume the NOR boot config:  NOR on CS3 (possibly swapped  	 * to address 0 by a dip switch), NAND on CS2B.  The NAND driver will  	 * notice whether a NAND chip is enabled at probe time. @@ -422,21 +433,10 @@ static void __init h3_init(void)  	h3_mmc_init();  } -static void __init h3_init_smc91x(void) -{ -	omap_cfg_reg(W15_1710_GPIO40); -	if (gpio_request(40, "SMC91x irq") < 0) { -		printk("Error requesting gpio 40 for smc91x irq\n"); -		return; -	} -} -  static void __init h3_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init(); -	h3_init_smc91x();  }  static void __init h3_map_io(void) diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index 071af3e4778..faa344f734d 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -577,8 +577,6 @@ static void __init htcherald_init(void)  	printk(KERN_INFO "HTC Herald init.\n");  	/* Do board initialization before we register all the devices */ -	omap_gpio_init(); -  	omap_board_config = htcherald_config;  	omap_board_config_size = ARRAY_SIZE(htcherald_config);  	platform_add_devices(devices, ARRAY_SIZE(devices)); diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index dc2b86fd66c..a051acdc526 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -290,13 +290,11 @@ static void __init innovator_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init();  #ifdef CONFIG_ARCH_OMAP15XX  	if (cpu_is_omap1510()) {  		omap1510_fpga_init_irq();  	}  #endif -	innovator_init_smc91x();  }  #ifdef CONFIG_ARCH_OMAP15XX @@ -387,6 +385,8 @@ static struct omap_board_config_kernel innovator_config[] = {  static void __init innovator_init(void)  { +	innovator_init_smc91x(); +  #ifdef CONFIG_ARCH_OMAP15XX  	if (cpu_is_omap1510()) {  		unsigned char reg; diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index aa8375b2a0a..605495bbc58 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -246,7 +246,6 @@ static void __init omap_nokia770_init(void)  	platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));  	spi_register_board_info(nokia770_spi_board_info,  				ARRAY_SIZE(nokia770_spi_board_info)); -	omap_gpio_init();  	omap_serial_init();  	omap_register_i2c_bus(1, 100, NULL, 0);  	hwa742_dev_init(); diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index e9dd79149a8..d44e7172efc 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -283,9 +283,6 @@ static void __init osk_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init(); -	osk_init_smc91x(); -	osk_init_cf();  }  static struct omap_usb_config osk_usb_config __initdata = { @@ -541,6 +538,9 @@ static void __init osk_init(void)  {  	u32 l; +	osk_init_smc91x(); +	osk_init_cf(); +  	/* Workaround for wrong CS3 (NOR flash) timing  	 * There are some U-Boot versions out there which configure  	 * wrong CS3 memory timings. This mainly leads to CRC diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index f32738b1eb6..994dc6f5072 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -63,7 +63,6 @@ static void __init omap_palmte_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init();  }  static const int palmte_keymap[] = { diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index d7a245cef9a..2afac598bae 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -62,7 +62,6 @@ omap_palmz71_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init();  }  static int palmz71_keymap[] = { diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index a8d16a255c1..69fda218fb4 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -251,8 +251,19 @@ static struct omap_board_config_kernel perseus2_config[] __initdata = {  	{ OMAP_TAG_LCD,		&perseus2_lcd_config },  }; +static void __init perseus2_init_smc91x(void) +{ +	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); +	mdelay(50); +	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1, +		   H2P2_DBG_FPGA_LAN_RESET); +	mdelay(50); +} +  static void __init omap_perseus2_init(void)  { +	perseus2_init_smc91x(); +  	if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0)  		BUG();  	gpio_direction_input(P2_NAND_RB_GPIO_PIN); @@ -280,21 +291,10 @@ static void __init omap_perseus2_init(void)  	omap_register_i2c_bus(1, 100, NULL, 0);  } -static void __init perseus2_init_smc91x(void) -{ -	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); -	mdelay(50); -	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1, -		   H2P2_DBG_FPGA_LAN_RESET); -	mdelay(50); -} -  static void __init omap_perseus2_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init(); -	perseus2_init_smc91x();  }  /* Only FPGA needs to be mapped here. All others are done with ioremap */  static struct map_desc omap_perseus2_io_desc[] __initdata = { diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index d25f59e5a77..463862c6781 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -409,7 +409,6 @@ static void __init omap_sx1_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init();  }  /*----------------------------------------*/ diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index b2838bfeab8..815a69ce821 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -161,7 +161,6 @@ static void __init voiceblue_init_irq(void)  {  	omap1_init_common_hw();  	omap_init_irq(); -	omap_gpio_init();  }  static void __init voiceblue_init(void) diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index af54114b8f0..423d21d8c19 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -143,7 +143,7 @@ static struct arm_idlect1_clk armper_ck = {   * activation.  [ GPIO code for 1510 ]   */  static struct clk arm_gpio_ck = { -	.name		= "arm_gpio_ck", +	.name		= "ick",  	.ops		= &clkops_generic,  	.parent		= &ck_dpll1,  	.flags		= ENABLE_ON_INIT, @@ -684,7 +684,7 @@ static struct omap_clk omap_clks[] = {  	CLK(NULL,	"ck_sossi",	&sossi_ck,	CK_16XX),  	CLK(NULL,	"arm_ck",	&arm_ck,	CK_16XX | CK_1510 | CK_310),  	CLK(NULL,	"armper_ck",	&armper_ck.clk,	CK_16XX | CK_1510 | CK_310), -	CLK(NULL,	"arm_gpio_ck",	&arm_gpio_ck,	CK_1510 | CK_310), +	CLK("omap_gpio.0", "ick",	&arm_gpio_ck,	CK_1510 | CK_310),  	CLK(NULL,	"armxor_ck",	&armxor_ck.clk,	CK_16XX | CK_1510 | CK_310 | CK_7XX),  	CLK(NULL,	"armtim_ck",	&armtim_ck.clk,	CK_16XX | CK_1510 | CK_310),  	CLK("omap_wdt",	"fck",		&armwdt_ck.clk,	CK_16XX | CK_1510 | CK_310), diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c new file mode 100644 index 00000000000..04c4b04cf54 --- /dev/null +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -0,0 +1,99 @@ +/* + * OMAP15xx specific gpio init + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: + *	Charulatha V <charu@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/gpio.h> + +#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE +#define OMAP1510_GPIO_BASE		0xFFFCE000 + +/* gpio1 */ +static struct __initdata resource omap15xx_mpu_gpio_resources[] = { +	{ +		.start	= OMAP1_MPUIO_VBASE, +		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_MPUIO, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { +	.virtual_irq_start	= IH_MPUIO_BASE, +	.bank_type		= METHOD_MPUIO, +	.bank_width		= 16, +	.bank_stride		= 1, +}; + +static struct __initdata platform_device omap15xx_mpu_gpio = { +	.name           = "omap_gpio", +	.id             = 0, +	.dev            = { +		.platform_data = &omap15xx_mpu_gpio_config, +	}, +	.num_resources = ARRAY_SIZE(omap15xx_mpu_gpio_resources), +	.resource = omap15xx_mpu_gpio_resources, +}; + +/* gpio2 */ +static struct __initdata resource omap15xx_gpio_resources[] = { +	{ +		.start	= OMAP1510_GPIO_BASE, +		.end	= OMAP1510_GPIO_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_GPIO_BANK1, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { +	.virtual_irq_start	= IH_GPIO_BASE, +	.bank_type		= METHOD_GPIO_1510, +	.bank_width		= 16, +}; + +static struct __initdata platform_device omap15xx_gpio = { +	.name           = "omap_gpio", +	.id             = 1, +	.dev            = { +		.platform_data = &omap15xx_gpio_config, +	}, +	.num_resources = ARRAY_SIZE(omap15xx_gpio_resources), +	.resource = omap15xx_gpio_resources, +}; + +/* + * omap15xx_gpio_init needs to be done before + * machine_init functions access gpio APIs. + * Hence omap15xx_gpio_init is a postcore_initcall. + */ +static int __init omap15xx_gpio_init(void) +{ +	if (!cpu_is_omap15xx()) +		return -EINVAL; + +	platform_device_register(&omap15xx_mpu_gpio); +	platform_device_register(&omap15xx_gpio); + +	gpio_bank_count = 2; +	return 0; +} +postcore_initcall(omap15xx_gpio_init); diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c new file mode 100644 index 00000000000..5dd0d4c82b2 --- /dev/null +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -0,0 +1,200 @@ +/* + * OMAP16xx specific gpio init + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: + *	Charulatha V <charu@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/gpio.h> + +#define OMAP1610_GPIO1_BASE		0xfffbe400 +#define OMAP1610_GPIO2_BASE		0xfffbec00 +#define OMAP1610_GPIO3_BASE		0xfffbb400 +#define OMAP1610_GPIO4_BASE		0xfffbbc00 +#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE + +/* mpu gpio */ +static struct __initdata resource omap16xx_mpu_gpio_resources[] = { +	{ +		.start	= OMAP1_MPUIO_VBASE, +		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_MPUIO, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { +	.virtual_irq_start	= IH_MPUIO_BASE, +	.bank_type		= METHOD_MPUIO, +	.bank_width		= 16, +	.bank_stride		= 1, +}; + +static struct __initdata platform_device omap16xx_mpu_gpio = { +	.name           = "omap_gpio", +	.id             = 0, +	.dev            = { +		.platform_data = &omap16xx_mpu_gpio_config, +	}, +	.num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources), +	.resource = omap16xx_mpu_gpio_resources, +}; + +/* gpio1 */ +static struct __initdata resource omap16xx_gpio1_resources[] = { +	{ +		.start	= OMAP1610_GPIO1_BASE, +		.end	= OMAP1610_GPIO1_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_GPIO_BANK1, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { +	.virtual_irq_start	= IH_GPIO_BASE, +	.bank_type		= METHOD_GPIO_1610, +	.bank_width		= 16, +}; + +static struct __initdata platform_device omap16xx_gpio1 = { +	.name           = "omap_gpio", +	.id             = 1, +	.dev            = { +		.platform_data = &omap16xx_gpio1_config, +	}, +	.num_resources = ARRAY_SIZE(omap16xx_gpio1_resources), +	.resource = omap16xx_gpio1_resources, +}; + +/* gpio2 */ +static struct __initdata resource omap16xx_gpio2_resources[] = { +	{ +		.start	= OMAP1610_GPIO2_BASE, +		.end	= OMAP1610_GPIO2_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_1610_GPIO_BANK2, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 16, +	.bank_type		= METHOD_GPIO_1610, +	.bank_width		= 16, +}; + +static struct __initdata platform_device omap16xx_gpio2 = { +	.name           = "omap_gpio", +	.id             = 2, +	.dev            = { +		.platform_data = &omap16xx_gpio2_config, +	}, +	.num_resources = ARRAY_SIZE(omap16xx_gpio2_resources), +	.resource = omap16xx_gpio2_resources, +}; + +/* gpio3 */ +static struct __initdata resource omap16xx_gpio3_resources[] = { +	{ +		.start	= OMAP1610_GPIO3_BASE, +		.end	= OMAP1610_GPIO3_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_1610_GPIO_BANK3, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 32, +	.bank_type		= METHOD_GPIO_1610, +	.bank_width		= 16, +}; + +static struct __initdata platform_device omap16xx_gpio3 = { +	.name           = "omap_gpio", +	.id             = 3, +	.dev            = { +		.platform_data = &omap16xx_gpio3_config, +	}, +	.num_resources = ARRAY_SIZE(omap16xx_gpio3_resources), +	.resource = omap16xx_gpio3_resources, +}; + +/* gpio4 */ +static struct __initdata resource omap16xx_gpio4_resources[] = { +	{ +		.start	= OMAP1610_GPIO4_BASE, +		.end	= OMAP1610_GPIO4_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_1610_GPIO_BANK4, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 48, +	.bank_type		= METHOD_GPIO_1610, +	.bank_width		= 16, +}; + +static struct __initdata platform_device omap16xx_gpio4 = { +	.name           = "omap_gpio", +	.id             = 4, +	.dev            = { +		.platform_data = &omap16xx_gpio4_config, +	}, +	.num_resources = ARRAY_SIZE(omap16xx_gpio4_resources), +	.resource = omap16xx_gpio4_resources, +}; + +static struct __initdata platform_device * omap16xx_gpio_dev[] = { +	&omap16xx_mpu_gpio, +	&omap16xx_gpio1, +	&omap16xx_gpio2, +	&omap16xx_gpio3, +	&omap16xx_gpio4, +}; + +/* + * omap16xx_gpio_init needs to be done before + * machine_init functions access gpio APIs. + * Hence omap16xx_gpio_init is a postcore_initcall. + */ +static int __init omap16xx_gpio_init(void) +{ +	int i; + +	if (!cpu_is_omap16xx()) +		return -EINVAL; + +	for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++) +		platform_device_register(omap16xx_gpio_dev[i]); + +	gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev); + +	return 0; +} +postcore_initcall(omap16xx_gpio_init); diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c new file mode 100644 index 00000000000..1204c8b871a --- /dev/null +++ b/arch/arm/mach-omap1/gpio7xx.c @@ -0,0 +1,262 @@ +/* + * OMAP7xx specific gpio init + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: + *	Charulatha V <charu@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/gpio.h> + +#define OMAP7XX_GPIO1_BASE		0xfffbc000 +#define OMAP7XX_GPIO2_BASE		0xfffbc800 +#define OMAP7XX_GPIO3_BASE		0xfffbd000 +#define OMAP7XX_GPIO4_BASE		0xfffbd800 +#define OMAP7XX_GPIO5_BASE		0xfffbe000 +#define OMAP7XX_GPIO6_BASE		0xfffbe800 +#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE + +/* mpu gpio */ +static struct __initdata resource omap7xx_mpu_gpio_resources[] = { +	{ +		.start	= OMAP1_MPUIO_VBASE, +		.end	= OMAP1_MPUIO_VBASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_MPUIO, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { +	.virtual_irq_start	= IH_MPUIO_BASE, +	.bank_type		= METHOD_MPUIO, +	.bank_width		= 32, +	.bank_stride		= 2, +}; + +static struct __initdata platform_device omap7xx_mpu_gpio = { +	.name           = "omap_gpio", +	.id             = 0, +	.dev            = { +		.platform_data = &omap7xx_mpu_gpio_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_mpu_gpio_resources), +	.resource = omap7xx_mpu_gpio_resources, +}; + +/* gpio1 */ +static struct __initdata resource omap7xx_gpio1_resources[] = { +	{ +		.start	= OMAP7XX_GPIO1_BASE, +		.end	= OMAP7XX_GPIO1_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_GPIO_BANK1, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { +	.virtual_irq_start	= IH_GPIO_BASE, +	.bank_type		= METHOD_GPIO_7XX, +	.bank_width		= 32, +}; + +static struct __initdata platform_device omap7xx_gpio1 = { +	.name           = "omap_gpio", +	.id             = 1, +	.dev            = { +		.platform_data = &omap7xx_gpio1_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_gpio1_resources), +	.resource = omap7xx_gpio1_resources, +}; + +/* gpio2 */ +static struct __initdata resource omap7xx_gpio2_resources[] = { +	{ +		.start	= OMAP7XX_GPIO2_BASE, +		.end	= OMAP7XX_GPIO2_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_GPIO_BANK2, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 32, +	.bank_type		= METHOD_GPIO_7XX, +	.bank_width		= 32, +}; + +static struct __initdata platform_device omap7xx_gpio2 = { +	.name           = "omap_gpio", +	.id             = 2, +	.dev            = { +		.platform_data = &omap7xx_gpio2_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_gpio2_resources), +	.resource = omap7xx_gpio2_resources, +}; + +/* gpio3 */ +static struct __initdata resource omap7xx_gpio3_resources[] = { +	{ +		.start	= OMAP7XX_GPIO3_BASE, +		.end	= OMAP7XX_GPIO3_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_GPIO_BANK3, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 64, +	.bank_type		= METHOD_GPIO_7XX, +	.bank_width		= 32, +}; + +static struct __initdata platform_device omap7xx_gpio3 = { +	.name           = "omap_gpio", +	.id             = 3, +	.dev            = { +		.platform_data = &omap7xx_gpio3_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_gpio3_resources), +	.resource = omap7xx_gpio3_resources, +}; + +/* gpio4 */ +static struct __initdata resource omap7xx_gpio4_resources[] = { +	{ +		.start	= OMAP7XX_GPIO4_BASE, +		.end	= OMAP7XX_GPIO4_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_GPIO_BANK4, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 96, +	.bank_type		= METHOD_GPIO_7XX, +	.bank_width		= 32, +}; + +static struct __initdata platform_device omap7xx_gpio4 = { +	.name           = "omap_gpio", +	.id             = 4, +	.dev            = { +		.platform_data = &omap7xx_gpio4_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_gpio4_resources), +	.resource = omap7xx_gpio4_resources, +}; + +/* gpio5 */ +static struct __initdata resource omap7xx_gpio5_resources[] = { +	{ +		.start	= OMAP7XX_GPIO5_BASE, +		.end	= OMAP7XX_GPIO5_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_GPIO_BANK5, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 128, +	.bank_type		= METHOD_GPIO_7XX, +	.bank_width		= 32, +}; + +static struct __initdata platform_device omap7xx_gpio5 = { +	.name           = "omap_gpio", +	.id             = 5, +	.dev            = { +		.platform_data = &omap7xx_gpio5_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_gpio5_resources), +	.resource = omap7xx_gpio5_resources, +}; + +/* gpio6 */ +static struct __initdata resource omap7xx_gpio6_resources[] = { +	{ +		.start	= OMAP7XX_GPIO6_BASE, +		.end	= OMAP7XX_GPIO6_BASE + SZ_2K - 1, +		.flags	= IORESOURCE_MEM, +	}, +	{ +		.start	= INT_7XX_GPIO_BANK6, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { +	.virtual_irq_start	= IH_GPIO_BASE + 160, +	.bank_type		= METHOD_GPIO_7XX, +	.bank_width		= 32, +}; + +static struct __initdata platform_device omap7xx_gpio6 = { +	.name           = "omap_gpio", +	.id             = 6, +	.dev            = { +		.platform_data = &omap7xx_gpio6_config, +	}, +	.num_resources = ARRAY_SIZE(omap7xx_gpio6_resources), +	.resource = omap7xx_gpio6_resources, +}; + +static struct __initdata platform_device * omap7xx_gpio_dev[] = { +	&omap7xx_mpu_gpio, +	&omap7xx_gpio1, +	&omap7xx_gpio2, +	&omap7xx_gpio3, +	&omap7xx_gpio4, +	&omap7xx_gpio5, +	&omap7xx_gpio6, +}; + +/* + * omap7xx_gpio_init needs to be done before + * machine_init functions access gpio APIs. + * Hence omap7xx_gpio_init is a postcore_initcall. + */ +static int __init omap7xx_gpio_init(void) +{ +	int i; + +	if (!cpu_is_omap7xx()) +		return -EINVAL; + +	for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++) +		platform_device_register(omap7xx_gpio_dev[i]); + +	gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev); + +	return 0; +} +postcore_initcall(omap7xx_gpio_init); diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index ce7b1f01767..fbc87395a02 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -4,7 +4,7 @@  # Common support  obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \ -	 common.o +	 common.o gpio.o  omap-2-3-common				= irq.o sdrc.o prm2xxx_3xxx.o  hwmod-common				= omap_hwmod.o \ diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index ee7ac993a27..c00f26aca0d 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -145,7 +145,6 @@ static void __init omap_2430sdp_init_irq(void)  	omap_board_config_size = ARRAY_SIZE(sdp2430_config);  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  static struct twl4030_gpio_platform_data sdp2430_gpio_data = { diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index ad4cb262719..869fb133c20 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -328,7 +328,6 @@ static void __init omap_3430sdp_init_irq(void)  	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);  	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  static int sdp3430_batt_table[] = { diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 4cd96d70b9c..a8d35ba7781 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -76,7 +76,6 @@ static void __init omap_sdp_init_irq(void)  	omap2_init_common_hw(h8mbx00u0mer0em_sdrc_params,  			h8mbx00u0mer0em_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 94d989bee8a..8842ec5e51e 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -223,7 +223,6 @@ static void __init omap_4430sdp_init_irq(void)  	omap2_gp_clockevent_set_gptimer(1);  #endif  	gic_init_irq(); -	omap_gpio_init();  }  static struct omap_musb_board_data musb_board_data = { diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 13ead330e38..8ba404770e7 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -19,7 +19,6 @@  #include <linux/kernel.h>  #include <linux/init.h> -#include <linux/gpio.h>  #include <mach/hardware.h>  #include <asm/mach-types.h> @@ -50,7 +49,6 @@ static void __init am3517_crane_init_irq(void)  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  static void __init am3517_crane_init(void) diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 63035d8231e..86867138f1e 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -392,7 +392,6 @@ static void __init am3517_evm_init_irq(void)  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  static struct omap_musb_board_data musb_board_data = { diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index b01d6e422d7..4e91f453ea9 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -280,8 +280,6 @@ static void __init omap_apollon_init_irq(void)  	omap_board_config_size = ARRAY_SIZE(apollon_config);  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init(); -	apollon_init_smc91x();  }  static void __init apollon_led_init(void) @@ -322,6 +320,7 @@ static void __init omap_apollon_init(void)  	omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC); +	apollon_init_smc91x();  	apollon_led_init();  	apollon_flash_init();  	apollon_usb_init(); diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 63f764e2af3..78b67fb790b 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -686,7 +686,6 @@ static void __init cm_t35_init_irq(void)  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,  			     mt46h32m32lf6_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  static struct omap_board_mux board_mux[] __initdata = { diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 1dd303e9a26..7ee23dab84f 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -250,7 +250,6 @@ static void __init cm_t3517_init_irq(void)  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  static struct omap_board_mux board_mux[] __initdata = { diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 53ac762518b..a30a7fce8cb 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -450,7 +450,6 @@ static void __init devkit8000_init_irq(void)  #ifdef CONFIG_OMAP_32K_TIMER  	omap2_gp_clockevent_set_gptimer(12);  #endif -	omap_gpio_init();  }  static void __init devkit8000_ads7846_init(void) diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 263da1da181..9ec77a4a6b8 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -293,7 +293,6 @@ static void __init omap_h4_init_irq(void)  	omap_board_config_size = ARRAY_SIZE(h4_config);  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  	h4_init_flash();  } diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 6f8f9b4533f..59b95f2389d 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -484,7 +484,6 @@ static void __init igep2_init_irq(void)  {  	omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  static struct twl4030_codec_audio_data igep2_audio_data = { diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c index 8dc6ed3aa37..886f193a841 100644 --- a/arch/arm/mach-omap2/board-igep0030.c +++ b/arch/arm/mach-omap2/board-igep0030.c @@ -291,7 +291,6 @@ static void __init igep3_init_irq(void)  {  	omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  static struct twl4030_platform_data igep3_twl4030_pdata = { diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 84b4ea67d15..7455b0aadf8 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -294,8 +294,6 @@ static void __init omap_ldp_init_irq(void)  	omap_board_config_size = ARRAY_SIZE(ldp_config);  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init(); -	ldp_init_smsc911x();  }  static struct twl4030_usb_data ldp_usb_data = { @@ -424,6 +422,7 @@ static struct mtd_partition ldp_nand_partitions[] = {  static void __init omap_ldp_init(void)  {  	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); +	ldp_init_smsc911x();  	omap_i2c_init();  	platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));  	ts_gpio = 54; diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 0a4bc7715c3..d4ce96316e3 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -633,7 +633,6 @@ static void __init n8x0_init_irq(void)  {  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index d42c8c93605..f1a8edefa42 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -490,7 +490,6 @@ static void __init omap3_beagle_init_irq(void)  #ifdef CONFIG_OMAP_32K_TIMER  	omap2_gp_clockevent_set_gptimer(12);  #endif -	omap_gpio_init();  }  static struct platform_device *omap3_beagle_devices[] __initdata = { diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 8f1e69a9205..21ffc5c587a 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -625,7 +625,6 @@ static void __init omap3_evm_init_irq(void)  	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  static struct platform_device *omap3_evm_devices[] __initdata = { diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c index e2e9562f4de..cfd618d3bda 100644 --- a/arch/arm/mach-omap2/board-omap3logic.c +++ b/arch/arm/mach-omap2/board-omap3logic.c @@ -199,7 +199,6 @@ static void __init omap3logic_init_irq(void)  {  	omap2_init_common_hw(NULL, NULL);  	omap_init_irq(); -	omap_gpio_init();  }  #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 445b1584321..de8df58b8f1 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -639,7 +639,6 @@ static void __init omap3pandora_init_irq(void)  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,  			     mt46h32m32lf6_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  static void pandora_wl1251_set_power(bool enable) diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index ba65fe8a9e1..1af344b872b 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -589,7 +589,6 @@ static void __init omap3_stalker_init_irq(void)  #ifdef CONFIG_OMAP_32K_TIMER  	omap2_gp_clockevent_set_gptimer(12);  #endif -	omap_gpio_init();  }  static struct platform_device *omap3_stalker_devices[] __initdata = { diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index 8d530a607f8..baa72c507d4 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -426,7 +426,6 @@ static void __init omap3_touchbook_init_irq(void)  #ifdef CONFIG_OMAP_32K_TIMER  	omap2_gp_clockevent_set_gptimer(12);  #endif -	omap_gpio_init();  }  static struct platform_device *omap3_touchbook_devices[] __initdata = { diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 801f8146b00..38f942beb12 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -79,7 +79,6 @@ static void __init omap4_panda_init_irq(void)  {  	omap2_init_common_hw(NULL, NULL);  	gic_init_irq(); -	omap_gpio_init();  }  static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 133b5ead830..b75bdcd4711 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -416,7 +416,6 @@ static void __init overo_init_irq(void)  	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,  			     mt46h32m32lf6_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  static struct platform_device *overo_devices[] __initdata = { diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index f3b6e103b01..6635142d7d0 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -108,7 +108,6 @@ static void __init rx51_init_irq(void)  	sdrc_params = rx51_get_sdram_timings();  	omap2_init_common_hw(sdrc_params, sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  extern void __init rx51_peripherals_init(void); diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index 27979fd527d..0dff9deaa89 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -43,7 +43,6 @@ static void __init omap_zoom_init_irq(void)  				h8mbx00u0mer0em_sdrc_params);  	omap_init_irq(); -	omap_gpio_init();  }  #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c new file mode 100644 index 00000000000..413de18c1d2 --- /dev/null +++ b/arch/arm/mach-omap2/gpio.c @@ -0,0 +1,104 @@ +/* + * OMAP2+ specific gpio initialization + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Author: + *	Charulatha V <charu@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + */ + +#include <linux/gpio.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/interrupt.h> + +#include <plat/omap_hwmod.h> +#include <plat/omap_device.h> + +static struct omap_device_pm_latency omap_gpio_latency[] = { +	[0] = { +		.deactivate_func = omap_device_idle_hwmods, +		.activate_func   = omap_device_enable_hwmods, +		.flags		 = OMAP_DEVICE_LATENCY_AUTO_ADJUST, +	}, +}; + +static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) +{ +	struct omap_device *od; +	struct omap_gpio_platform_data *pdata; +	struct omap_gpio_dev_attr *dev_attr; +	char *name = "omap_gpio"; +	int id; + +	/* +	 * extract the device id from name field available in the +	 * hwmod database and use the same for constructing ids for +	 * gpio devices. +	 * CAUTION: Make sure the name in the hwmod database does +	 * not change. If changed, make corresponding change here +	 * or make use of static variable mechanism to handle this. +	 */ +	sscanf(oh->name, "gpio%d", &id); + +	pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); +	if (!pdata) { +		pr_err("gpio%d: Memory allocation failed\n", id); +		return -ENOMEM; +	} + +	dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr; +	pdata->bank_width = dev_attr->bank_width; +	pdata->dbck_flag = dev_attr->dbck_flag; +	pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1); + +	switch (oh->class->rev) { +	case 0: +	case 1: +		pdata->bank_type = METHOD_GPIO_24XX; +		break; +	case 2: +		pdata->bank_type = METHOD_GPIO_44XX; +		break; +	default: +		WARN(1, "Invalid gpio bank_type\n"); +		kfree(pdata); +		return -EINVAL; +	} + +	od = omap_device_build(name, id - 1, oh, pdata, +				sizeof(*pdata),	omap_gpio_latency, +				ARRAY_SIZE(omap_gpio_latency), +				false); +	kfree(pdata); + +	if (IS_ERR(od)) { +		WARN(1, "Cant build omap_device for %s:%s.\n", +					name, oh->name); +		return PTR_ERR(od); +	} + +	gpio_bank_count++; +	return 0; +} + +/* + * gpio_init needs to be done before + * machine_init functions access gpio APIs. + * Hence gpio_init is a postcore_initcall. + */ +static int __init omap2_gpio_init(void) +{ +	return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, +						NULL); +} +postcore_initcall(omap2_gpio_init); diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a1a3dd6303b..d9534259979 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -17,7 +17,7 @@  #include <plat/dma.h>  #include <plat/serial.h>  #include <plat/i2c.h> -#include <plat/omap24xx.h> +#include <plat/gpio.h>  #include "omap_hwmod_common_data.h" @@ -38,6 +38,10 @@ static struct omap_hwmod omap2420_iva_hwmod;  static struct omap_hwmod omap2420_l3_main_hwmod;  static struct omap_hwmod omap2420_l4_core_hwmod;  static struct omap_hwmod omap2420_wd_timer2_hwmod; +static struct omap_hwmod omap2420_gpio1_hwmod; +static struct omap_hwmod omap2420_gpio2_hwmod; +static struct omap_hwmod omap2420_gpio3_hwmod; +static struct omap_hwmod omap2420_gpio4_hwmod;  /* L3 -> L4_CORE interface */  static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = { @@ -557,6 +561,224 @@ static struct omap_hwmod omap2420_i2c2_hwmod = {  	.flags		= HWMOD_16BIT_REG,  }; +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_addr_space omap2420_gpio1_addr_space[] = { +	{ +		.pa_start	= 0x48018000, +		.pa_end		= 0x480181ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio1 = { +	.master		= &omap2420_l4_wkup_hwmod, +	.slave		= &omap2420_gpio1_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2420_gpio1_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2420_gpio1_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio2 */ +static struct omap_hwmod_addr_space omap2420_gpio2_addr_space[] = { +	{ +		.pa_start	= 0x4801a000, +		.pa_end		= 0x4801a1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio2 = { +	.master		= &omap2420_l4_wkup_hwmod, +	.slave		= &omap2420_gpio2_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2420_gpio2_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2420_gpio2_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio3 */ +static struct omap_hwmod_addr_space omap2420_gpio3_addr_space[] = { +	{ +		.pa_start	= 0x4801c000, +		.pa_end		= 0x4801c1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio3 = { +	.master		= &omap2420_l4_wkup_hwmod, +	.slave		= &omap2420_gpio3_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2420_gpio3_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2420_gpio3_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio4 */ +static struct omap_hwmod_addr_space omap2420_gpio4_addr_space[] = { +	{ +		.pa_start	= 0x4801e000, +		.pa_end		= 0x4801e1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = { +	.master		= &omap2420_l4_wkup_hwmod, +	.slave		= &omap2420_gpio4_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2420_gpio4_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2420_gpio4_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { +	.bank_width = 32, +	.dbck_flag = false, +}; + +static struct omap_hwmod_class_sysconfig omap242x_gpio_sysc = { +	.rev_offs	= 0x0000, +	.sysc_offs	= 0x0010, +	.syss_offs	= 0x0014, +	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | +			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), +	.sysc_fields    = &omap_hwmod_sysc_type1, +}; + +/* + * 'gpio' class + * general purpose io module + */ +static struct omap_hwmod_class omap242x_gpio_hwmod_class = { +	.name = "gpio", +	.sysc = &omap242x_gpio_sysc, +	.rev = 0, +}; + +/* gpio1 */ +static struct omap_hwmod_irq_info omap242x_gpio1_irqs[] = { +	{ .irq = 29 }, /* INT_24XX_GPIO_BANK1 */ +}; + +static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = { +	&omap2420_l4_wkup__gpio1, +}; + +static struct omap_hwmod omap2420_gpio1_hwmod = { +	.name		= "gpio1", +	.mpu_irqs	= omap242x_gpio1_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio1_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2420_gpio1_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio1_slaves), +	.class		= &omap242x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + +/* gpio2 */ +static struct omap_hwmod_irq_info omap242x_gpio2_irqs[] = { +	{ .irq = 30 }, /* INT_24XX_GPIO_BANK2 */ +}; + +static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = { +	&omap2420_l4_wkup__gpio2, +}; + +static struct omap_hwmod omap2420_gpio2_hwmod = { +	.name		= "gpio2", +	.mpu_irqs	= omap242x_gpio2_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio2_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2420_gpio2_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio2_slaves), +	.class		= &omap242x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + +/* gpio3 */ +static struct omap_hwmod_irq_info omap242x_gpio3_irqs[] = { +	{ .irq = 31 }, /* INT_24XX_GPIO_BANK3 */ +}; + +static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = { +	&omap2420_l4_wkup__gpio3, +}; + +static struct omap_hwmod omap2420_gpio3_hwmod = { +	.name		= "gpio3", +	.mpu_irqs	= omap242x_gpio3_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio3_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2420_gpio3_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio3_slaves), +	.class		= &omap242x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + +/* gpio4 */ +static struct omap_hwmod_irq_info omap242x_gpio4_irqs[] = { +	{ .irq = 32 }, /* INT_24XX_GPIO_BANK4 */ +}; + +static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = { +	&omap2420_l4_wkup__gpio4, +}; + +static struct omap_hwmod omap2420_gpio4_hwmod = { +	.name		= "gpio4", +	.mpu_irqs	= omap242x_gpio4_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap242x_gpio4_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2420_gpio4_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2420_gpio4_slaves), +	.class		= &omap242x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; +  static __initdata struct omap_hwmod *omap2420_hwmods[] = {  	&omap2420_l3_main_hwmod,  	&omap2420_l4_core_hwmod, @@ -569,6 +791,12 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {  	&omap2420_uart3_hwmod,  	&omap2420_i2c1_hwmod,  	&omap2420_i2c2_hwmod, + +	/* gpio class */ +	&omap2420_gpio1_hwmod, +	&omap2420_gpio2_hwmod, +	&omap2420_gpio3_hwmod, +	&omap2420_gpio4_hwmod,  	NULL,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 7cf0d3ab2a4..f68409e9fd3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -17,7 +17,7 @@  #include <plat/dma.h>  #include <plat/serial.h>  #include <plat/i2c.h> -#include <plat/omap24xx.h> +#include <plat/gpio.h>  #include "omap_hwmod_common_data.h" @@ -38,6 +38,11 @@ static struct omap_hwmod omap2430_iva_hwmod;  static struct omap_hwmod omap2430_l3_main_hwmod;  static struct omap_hwmod omap2430_l4_core_hwmod;  static struct omap_hwmod omap2430_wd_timer2_hwmod; +static struct omap_hwmod omap2430_gpio1_hwmod; +static struct omap_hwmod omap2430_gpio2_hwmod; +static struct omap_hwmod omap2430_gpio3_hwmod; +static struct omap_hwmod omap2430_gpio4_hwmod; +static struct omap_hwmod omap2430_gpio5_hwmod;  /* L3 -> L4_CORE interface */  static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = { @@ -569,6 +574,272 @@ static struct omap_hwmod omap2430_i2c2_hwmod = {  	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),  }; +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = { +	{ +		.pa_start	= 0x4900C000, +		.pa_end		= 0x4900C1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = { +	.master		= &omap2430_l4_wkup_hwmod, +	.slave		= &omap2430_gpio1_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2430_gpio1_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2430_gpio1_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio2 */ +static struct omap_hwmod_addr_space omap2430_gpio2_addr_space[] = { +	{ +		.pa_start	= 0x4900E000, +		.pa_end		= 0x4900E1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = { +	.master		= &omap2430_l4_wkup_hwmod, +	.slave		= &omap2430_gpio2_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2430_gpio2_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2430_gpio2_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio3 */ +static struct omap_hwmod_addr_space omap2430_gpio3_addr_space[] = { +	{ +		.pa_start	= 0x49010000, +		.pa_end		= 0x490101ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = { +	.master		= &omap2430_l4_wkup_hwmod, +	.slave		= &omap2430_gpio3_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2430_gpio3_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2430_gpio3_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_wkup -> gpio4 */ +static struct omap_hwmod_addr_space omap2430_gpio4_addr_space[] = { +	{ +		.pa_start	= 0x49012000, +		.pa_end		= 0x490121ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = { +	.master		= &omap2430_l4_wkup_hwmod, +	.slave		= &omap2430_gpio4_hwmod, +	.clk		= "gpios_ick", +	.addr		= omap2430_gpio4_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2430_gpio4_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> gpio5 */ +static struct omap_hwmod_addr_space omap2430_gpio5_addr_space[] = { +	{ +		.pa_start	= 0x480B6000, +		.pa_end		= 0x480B61ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = { +	.master		= &omap2430_l4_core_hwmod, +	.slave		= &omap2430_gpio5_hwmod, +	.clk		= "gpio5_ick", +	.addr		= omap2430_gpio5_addr_space, +	.addr_cnt	= ARRAY_SIZE(omap2430_gpio5_addr_space), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { +	.bank_width = 32, +	.dbck_flag = false, +}; + +static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = { +	.rev_offs	= 0x0000, +	.sysc_offs	= 0x0010, +	.syss_offs	= 0x0014, +	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | +			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), +	.sysc_fields    = &omap_hwmod_sysc_type1, +}; + +/* + * 'gpio' class + * general purpose io module + */ +static struct omap_hwmod_class omap243x_gpio_hwmod_class = { +	.name = "gpio", +	.sysc = &omap243x_gpio_sysc, +	.rev = 0, +}; + +/* gpio1 */ +static struct omap_hwmod_irq_info omap243x_gpio1_irqs[] = { +	{ .irq = 29 }, /* INT_24XX_GPIO_BANK1 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = { +	&omap2430_l4_wkup__gpio1, +}; + +static struct omap_hwmod omap2430_gpio1_hwmod = { +	.name		= "gpio1", +	.mpu_irqs	= omap243x_gpio1_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio1_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2430_gpio1_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio1_slaves), +	.class		= &omap243x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* gpio2 */ +static struct omap_hwmod_irq_info omap243x_gpio2_irqs[] = { +	{ .irq = 30 }, /* INT_24XX_GPIO_BANK2 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = { +	&omap2430_l4_wkup__gpio2, +}; + +static struct omap_hwmod omap2430_gpio2_hwmod = { +	.name		= "gpio2", +	.mpu_irqs	= omap243x_gpio2_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio2_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2430_gpio2_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio2_slaves), +	.class		= &omap243x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* gpio3 */ +static struct omap_hwmod_irq_info omap243x_gpio3_irqs[] = { +	{ .irq = 31 }, /* INT_24XX_GPIO_BANK3 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = { +	&omap2430_l4_wkup__gpio3, +}; + +static struct omap_hwmod omap2430_gpio3_hwmod = { +	.name		= "gpio3", +	.mpu_irqs	= omap243x_gpio3_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio3_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2430_gpio3_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio3_slaves), +	.class		= &omap243x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* gpio4 */ +static struct omap_hwmod_irq_info omap243x_gpio4_irqs[] = { +	{ .irq = 32 }, /* INT_24XX_GPIO_BANK4 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = { +	&omap2430_l4_wkup__gpio4, +}; + +static struct omap_hwmod omap2430_gpio4_hwmod = { +	.name		= "gpio4", +	.mpu_irqs	= omap243x_gpio4_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio4_irqs), +	.main_clk	= "gpios_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP24XX_EN_GPIOS_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, +		}, +	}, +	.slaves		= omap2430_gpio4_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio4_slaves), +	.class		= &omap243x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* gpio5 */ +static struct omap_hwmod_irq_info omap243x_gpio5_irqs[] = { +	{ .irq = 33 }, /* INT_24XX_GPIO_BANK5 */ +}; + +static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = { +	&omap2430_l4_core__gpio5, +}; + +static struct omap_hwmod omap2430_gpio5_hwmod = { +	.name		= "gpio5", +	.mpu_irqs	= omap243x_gpio5_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap243x_gpio5_irqs), +	.main_clk	= "gpio5_fck", +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 2, +			.module_bit = OMAP2430_EN_GPIO5_SHIFT, +			.module_offs = CORE_MOD, +			.idlest_reg_id = 2, +			.idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT, +		}, +	}, +	.slaves		= omap2430_gpio5_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap2430_gpio5_slaves), +	.class		= &omap243x_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; +  static __initdata struct omap_hwmod *omap2430_hwmods[] = {  	&omap2430_l3_main_hwmod,  	&omap2430_l4_core_hwmod, @@ -581,6 +852,13 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {  	&omap2430_uart3_hwmod,  	&omap2430_i2c1_hwmod,  	&omap2430_i2c2_hwmod, + +	/* gpio class */ +	&omap2430_gpio1_hwmod, +	&omap2430_gpio2_hwmod, +	&omap2430_gpio3_hwmod, +	&omap2430_gpio4_hwmod, +	&omap2430_gpio5_hwmod,  	NULL,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index a8bed843079..2687be10d7a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -20,7 +20,7 @@  #include <plat/serial.h>  #include <plat/l4_3xxx.h>  #include <plat/i2c.h> -#include <plat/omap34xx.h> +#include <plat/gpio.h>  #include "omap_hwmod_common_data.h" @@ -45,6 +45,12 @@ static struct omap_hwmod omap3xxx_wd_timer2_hwmod;  static struct omap_hwmod omap3xxx_i2c1_hwmod;  static struct omap_hwmod omap3xxx_i2c2_hwmod;  static struct omap_hwmod omap3xxx_i2c3_hwmod; +static struct omap_hwmod omap3xxx_gpio1_hwmod; +static struct omap_hwmod omap3xxx_gpio2_hwmod; +static struct omap_hwmod omap3xxx_gpio3_hwmod; +static struct omap_hwmod omap3xxx_gpio4_hwmod; +static struct omap_hwmod omap3xxx_gpio5_hwmod; +static struct omap_hwmod omap3xxx_gpio6_hwmod;  /* L3 -> L4_CORE interface */  static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { @@ -739,6 +745,351 @@ static struct omap_hwmod omap3xxx_i2c3_hwmod = {  	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),  }; +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_addr_space omap3xxx_gpio1_addrs[] = { +	{ +		.pa_start	= 0x48310000, +		.pa_end		= 0x483101ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__gpio1 = { +	.master		= &omap3xxx_l4_wkup_hwmod, +	.slave		= &omap3xxx_gpio1_hwmod, +	.addr		= omap3xxx_gpio1_addrs, +	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio1_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio2 */ +static struct omap_hwmod_addr_space omap3xxx_gpio2_addrs[] = { +	{ +		.pa_start	= 0x49050000, +		.pa_end		= 0x490501ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio2 = { +	.master		= &omap3xxx_l4_per_hwmod, +	.slave		= &omap3xxx_gpio2_hwmod, +	.addr		= omap3xxx_gpio2_addrs, +	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio2_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio3 */ +static struct omap_hwmod_addr_space omap3xxx_gpio3_addrs[] = { +	{ +		.pa_start	= 0x49052000, +		.pa_end		= 0x490521ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = { +	.master		= &omap3xxx_l4_per_hwmod, +	.slave		= &omap3xxx_gpio3_hwmod, +	.addr		= omap3xxx_gpio3_addrs, +	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio3_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio4 */ +static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = { +	{ +		.pa_start	= 0x49054000, +		.pa_end		= 0x490541ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio4 = { +	.master		= &omap3xxx_l4_per_hwmod, +	.slave		= &omap3xxx_gpio4_hwmod, +	.addr		= omap3xxx_gpio4_addrs, +	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio4_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio5 */ +static struct omap_hwmod_addr_space omap3xxx_gpio5_addrs[] = { +	{ +		.pa_start	= 0x49056000, +		.pa_end		= 0x490561ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio5 = { +	.master		= &omap3xxx_l4_per_hwmod, +	.slave		= &omap3xxx_gpio5_hwmod, +	.addr		= omap3xxx_gpio5_addrs, +	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio5_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_per -> gpio6 */ +static struct omap_hwmod_addr_space omap3xxx_gpio6_addrs[] = { +	{ +		.pa_start	= 0x49058000, +		.pa_end		= 0x490581ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = { +	.master		= &omap3xxx_l4_per_hwmod, +	.slave		= &omap3xxx_gpio6_hwmod, +	.addr		= omap3xxx_gpio6_addrs, +	.addr_cnt	= ARRAY_SIZE(omap3xxx_gpio6_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* + * 'gpio' class + * general purpose io module + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_gpio_sysc = { +	.rev_offs	= 0x0000, +	.sysc_offs	= 0x0010, +	.syss_offs	= 0x0014, +	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | +			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), +	.sysc_fields    = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = { +	.name = "gpio", +	.sysc = &omap3xxx_gpio_sysc, +	.rev = 1, +}; + +/* gpio_dev_attr*/ +static struct omap_gpio_dev_attr gpio_dev_attr = { +	.bank_width = 32, +	.dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod_irq_info omap3xxx_gpio1_irqs[] = { +	{ .irq = 29 }, /* INT_34XX_GPIO_BANK1 */ +}; + +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { +	{ .role = "dbclk", .clk = "gpio1_dbck", }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = { +	&omap3xxx_l4_wkup__gpio1, +}; + +static struct omap_hwmod omap3xxx_gpio1_hwmod = { +	.name		= "gpio1", +	.mpu_irqs	= omap3xxx_gpio1_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio1_irqs), +	.main_clk	= "gpio1_ick", +	.opt_clks	= gpio1_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks), +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_EN_GPIO1_SHIFT, +			.module_offs = WKUP_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_GPIO1_SHIFT, +		}, +	}, +	.slaves		= omap3xxx_gpio1_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio1_slaves), +	.class		= &omap3xxx_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* gpio2 */ +static struct omap_hwmod_irq_info omap3xxx_gpio2_irqs[] = { +	{ .irq = 30 }, /* INT_34XX_GPIO_BANK2 */ +}; + +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { +	{ .role = "dbclk", .clk = "gpio2_dbck", }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = { +	&omap3xxx_l4_per__gpio2, +}; + +static struct omap_hwmod omap3xxx_gpio2_hwmod = { +	.name		= "gpio2", +	.mpu_irqs	= omap3xxx_gpio2_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio2_irqs), +	.main_clk	= "gpio2_ick", +	.opt_clks	= gpio2_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks), +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_EN_GPIO2_SHIFT, +			.module_offs = OMAP3430_PER_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_GPIO2_SHIFT, +		}, +	}, +	.slaves		= omap3xxx_gpio2_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio2_slaves), +	.class		= &omap3xxx_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* gpio3 */ +static struct omap_hwmod_irq_info omap3xxx_gpio3_irqs[] = { +	{ .irq = 31 }, /* INT_34XX_GPIO_BANK3 */ +}; + +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { +	{ .role = "dbclk", .clk = "gpio3_dbck", }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = { +	&omap3xxx_l4_per__gpio3, +}; + +static struct omap_hwmod omap3xxx_gpio3_hwmod = { +	.name		= "gpio3", +	.mpu_irqs	= omap3xxx_gpio3_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio3_irqs), +	.main_clk	= "gpio3_ick", +	.opt_clks	= gpio3_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks), +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_EN_GPIO3_SHIFT, +			.module_offs = OMAP3430_PER_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_GPIO3_SHIFT, +		}, +	}, +	.slaves		= omap3xxx_gpio3_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio3_slaves), +	.class		= &omap3xxx_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* gpio4 */ +static struct omap_hwmod_irq_info omap3xxx_gpio4_irqs[] = { +	{ .irq = 32 }, /* INT_34XX_GPIO_BANK4 */ +}; + +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { +	{ .role = "dbclk", .clk = "gpio4_dbck", }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = { +	&omap3xxx_l4_per__gpio4, +}; + +static struct omap_hwmod omap3xxx_gpio4_hwmod = { +	.name		= "gpio4", +	.mpu_irqs	= omap3xxx_gpio4_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio4_irqs), +	.main_clk	= "gpio4_ick", +	.opt_clks	= gpio4_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks), +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_EN_GPIO4_SHIFT, +			.module_offs = OMAP3430_PER_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_GPIO4_SHIFT, +		}, +	}, +	.slaves		= omap3xxx_gpio4_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio4_slaves), +	.class		= &omap3xxx_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* gpio5 */ +static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = { +	{ .irq = 33 }, /* INT_34XX_GPIO_BANK5 */ +}; + +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { +	{ .role = "dbclk", .clk = "gpio5_dbck", }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = { +	&omap3xxx_l4_per__gpio5, +}; + +static struct omap_hwmod omap3xxx_gpio5_hwmod = { +	.name		= "gpio5", +	.mpu_irqs	= omap3xxx_gpio5_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio5_irqs), +	.main_clk	= "gpio5_ick", +	.opt_clks	= gpio5_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks), +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_EN_GPIO5_SHIFT, +			.module_offs = OMAP3430_PER_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_GPIO5_SHIFT, +		}, +	}, +	.slaves		= omap3xxx_gpio5_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio5_slaves), +	.class		= &omap3xxx_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* gpio6 */ +static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = { +	{ .irq = 34 }, /* INT_34XX_GPIO_BANK6 */ +}; + +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { +	{ .role = "dbclk", .clk = "gpio6_dbck", }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = { +	&omap3xxx_l4_per__gpio6, +}; + +static struct omap_hwmod omap3xxx_gpio6_hwmod = { +	.name		= "gpio6", +	.mpu_irqs	= omap3xxx_gpio6_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap3xxx_gpio6_irqs), +	.main_clk	= "gpio6_ick", +	.opt_clks	= gpio6_opt_clks, +	.opt_clks_cnt	= ARRAY_SIZE(gpio6_opt_clks), +	.prcm		= { +		.omap2 = { +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_EN_GPIO6_SHIFT, +			.module_offs = OMAP3430_PER_MOD, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_GPIO6_SHIFT, +		}, +	}, +	.slaves		= omap3xxx_gpio6_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap3xxx_gpio6_slaves), +	.class		= &omap3xxx_gpio_hwmod_class, +	.dev_attr	= &gpio_dev_attr, +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; +  static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {  	&omap3xxx_l3_main_hwmod,  	&omap3xxx_l4_core_hwmod, @@ -754,6 +1105,14 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {  	&omap3xxx_i2c1_hwmod,  	&omap3xxx_i2c2_hwmod,  	&omap3xxx_i2c3_hwmod, + +	/* gpio class */ +	&omap3xxx_gpio1_hwmod, +	&omap3xxx_gpio2_hwmod, +	&omap3xxx_gpio3_hwmod, +	&omap3xxx_gpio4_hwmod, +	&omap3xxx_gpio5_hwmod, +	&omap3xxx_gpio6_hwmod,  	NULL,  }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0d5c6eb7e4c..d258936410f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -22,6 +22,7 @@  #include <plat/omap_hwmod.h>  #include <plat/cpu.h> +#include <plat/gpio.h>  #include "omap_hwmod_common_data.h" @@ -1043,6 +1044,338 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {  	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),  }; +/* + * 'gpio' class + * general purpose io module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = { +	.rev_offs	= 0x0000, +	.sysc_offs	= 0x0010, +	.syss_offs	= 0x0114, +	.sysc_flags	= (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | +			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), +	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), +	.sysc_fields	= &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_gpio_hwmod_class = { +	.name = "gpio", +	.sysc = &omap44xx_gpio_sysc, +	.rev = 2, +}; + +/* gpio dev_attr */ +static struct omap_gpio_dev_attr gpio_dev_attr = { +	.bank_width = 32, +	.dbck_flag = true, +}; + +/* gpio1 */ +static struct omap_hwmod omap44xx_gpio1_hwmod; +static struct omap_hwmod_irq_info omap44xx_gpio1_irqs[] = { +	{ .irq = 29 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = { +	{ +		.pa_start	= 0x4a310000, +		.pa_end		= 0x4a3101ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +/* l4_wkup -> gpio1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = { +	.master		= &omap44xx_l4_wkup_hwmod, +	.slave		= &omap44xx_gpio1_hwmod, +	.addr		= omap44xx_gpio1_addrs, +	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio1_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio1 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_gpio1_slaves[] = { +	&omap44xx_l4_wkup__gpio1, +}; + +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { +	{ .role = "dbclk", .clk = "sys_32k_ck" }, +}; + +static struct omap_hwmod omap44xx_gpio1_hwmod = { +	.name		= "gpio1", +	.class		= &omap44xx_gpio_hwmod_class, +	.mpu_irqs	= omap44xx_gpio1_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio1_irqs), +	.main_clk	= "gpio1_ick", +	.prcm = { +		.omap4 = { +			.clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL, +		}, +	}, +	.opt_clks	= gpio1_opt_clks, +	.opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), +	.dev_attr	= &gpio_dev_attr, +	.slaves		= omap44xx_gpio1_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio1_slaves), +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* gpio2 */ +static struct omap_hwmod omap44xx_gpio2_hwmod; +static struct omap_hwmod_irq_info omap44xx_gpio2_irqs[] = { +	{ .irq = 30 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = { +	{ +		.pa_start	= 0x48055000, +		.pa_end		= 0x480551ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +/* l4_per -> gpio2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = { +	.master		= &omap44xx_l4_per_hwmod, +	.slave		= &omap44xx_gpio2_hwmod, +	.addr		= omap44xx_gpio2_addrs, +	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio2_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio2 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_gpio2_slaves[] = { +	&omap44xx_l4_per__gpio2, +}; + +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { +	{ .role = "dbclk", .clk = "sys_32k_ck" }, +}; + +static struct omap_hwmod omap44xx_gpio2_hwmod = { +	.name		= "gpio2", +	.class		= &omap44xx_gpio_hwmod_class, +	.mpu_irqs	= omap44xx_gpio2_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio2_irqs), +	.main_clk	= "gpio2_ick", +	.prcm = { +		.omap4 = { +			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL, +		}, +	}, +	.opt_clks	= gpio2_opt_clks, +	.opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), +	.dev_attr	= &gpio_dev_attr, +	.slaves		= omap44xx_gpio2_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio2_slaves), +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* gpio3 */ +static struct omap_hwmod omap44xx_gpio3_hwmod; +static struct omap_hwmod_irq_info omap44xx_gpio3_irqs[] = { +	{ .irq = 31 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = { +	{ +		.pa_start	= 0x48057000, +		.pa_end		= 0x480571ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +/* l4_per -> gpio3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = { +	.master		= &omap44xx_l4_per_hwmod, +	.slave		= &omap44xx_gpio3_hwmod, +	.addr		= omap44xx_gpio3_addrs, +	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio3_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio3 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_gpio3_slaves[] = { +	&omap44xx_l4_per__gpio3, +}; + +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { +	{ .role = "dbclk", .clk = "sys_32k_ck" }, +}; + +static struct omap_hwmod omap44xx_gpio3_hwmod = { +	.name		= "gpio3", +	.class		= &omap44xx_gpio_hwmod_class, +	.mpu_irqs	= omap44xx_gpio3_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio3_irqs), +	.main_clk	= "gpio3_ick", +	.prcm = { +		.omap4 = { +			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL, +		}, +	}, +	.opt_clks	= gpio3_opt_clks, +	.opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), +	.dev_attr	= &gpio_dev_attr, +	.slaves		= omap44xx_gpio3_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio3_slaves), +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* gpio4 */ +static struct omap_hwmod omap44xx_gpio4_hwmod; +static struct omap_hwmod_irq_info omap44xx_gpio4_irqs[] = { +	{ .irq = 32 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = { +	{ +		.pa_start	= 0x48059000, +		.pa_end		= 0x480591ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +/* l4_per -> gpio4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = { +	.master		= &omap44xx_l4_per_hwmod, +	.slave		= &omap44xx_gpio4_hwmod, +	.addr		= omap44xx_gpio4_addrs, +	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio4_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio4 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_gpio4_slaves[] = { +	&omap44xx_l4_per__gpio4, +}; + +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { +	{ .role = "dbclk", .clk = "sys_32k_ck" }, +}; + +static struct omap_hwmod omap44xx_gpio4_hwmod = { +	.name		= "gpio4", +	.class		= &omap44xx_gpio_hwmod_class, +	.mpu_irqs	= omap44xx_gpio4_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio4_irqs), +	.main_clk	= "gpio4_ick", +	.prcm = { +		.omap4 = { +			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL, +		}, +	}, +	.opt_clks	= gpio4_opt_clks, +	.opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), +	.dev_attr	= &gpio_dev_attr, +	.slaves		= omap44xx_gpio4_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio4_slaves), +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* gpio5 */ +static struct omap_hwmod omap44xx_gpio5_hwmod; +static struct omap_hwmod_irq_info omap44xx_gpio5_irqs[] = { +	{ .irq = 33 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = { +	{ +		.pa_start	= 0x4805b000, +		.pa_end		= 0x4805b1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +/* l4_per -> gpio5 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = { +	.master		= &omap44xx_l4_per_hwmod, +	.slave		= &omap44xx_gpio5_hwmod, +	.addr		= omap44xx_gpio5_addrs, +	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio5_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio5 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_gpio5_slaves[] = { +	&omap44xx_l4_per__gpio5, +}; + +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { +	{ .role = "dbclk", .clk = "sys_32k_ck" }, +}; + +static struct omap_hwmod omap44xx_gpio5_hwmod = { +	.name		= "gpio5", +	.class		= &omap44xx_gpio_hwmod_class, +	.mpu_irqs	= omap44xx_gpio5_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio5_irqs), +	.main_clk	= "gpio5_ick", +	.prcm = { +		.omap4 = { +			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL, +		}, +	}, +	.opt_clks	= gpio5_opt_clks, +	.opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), +	.dev_attr	= &gpio_dev_attr, +	.slaves		= omap44xx_gpio5_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio5_slaves), +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* gpio6 */ +static struct omap_hwmod omap44xx_gpio6_hwmod; +static struct omap_hwmod_irq_info omap44xx_gpio6_irqs[] = { +	{ .irq = 34 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = { +	{ +		.pa_start	= 0x4805d000, +		.pa_end		= 0x4805d1ff, +		.flags		= ADDR_TYPE_RT +	}, +}; + +/* l4_per -> gpio6 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = { +	.master		= &omap44xx_l4_per_hwmod, +	.slave		= &omap44xx_gpio6_hwmod, +	.addr		= omap44xx_gpio6_addrs, +	.addr_cnt	= ARRAY_SIZE(omap44xx_gpio6_addrs), +	.user		= OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpio6 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_gpio6_slaves[] = { +	&omap44xx_l4_per__gpio6, +}; + +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { +	{ .role = "dbclk", .clk = "sys_32k_ck" }, +}; + +static struct omap_hwmod omap44xx_gpio6_hwmod = { +	.name		= "gpio6", +	.class		= &omap44xx_gpio_hwmod_class, +	.mpu_irqs	= omap44xx_gpio6_irqs, +	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_gpio6_irqs), +	.main_clk	= "gpio6_ick", +	.prcm = { +		.omap4 = { +			.clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL, +		}, +	}, +	.opt_clks	= gpio6_opt_clks, +	.opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), +	.dev_attr	= &gpio_dev_attr, +	.slaves		= omap44xx_gpio6_slaves, +	.slaves_cnt	= ARRAY_SIZE(omap44xx_gpio6_slaves), +	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +};  static __initdata struct omap_hwmod *omap44xx_hwmods[] = {  	/* dmm class */  	&omap44xx_dmm_hwmod, @@ -1066,6 +1399,14 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {  	/* mpu_bus class */  	&omap44xx_mpu_private_hwmod, +	/* gpio class */ +	&omap44xx_gpio1_hwmod, +	&omap44xx_gpio2_hwmod, +	&omap44xx_gpio3_hwmod, +	&omap44xx_gpio4_hwmod, +	&omap44xx_gpio5_hwmod, +	&omap44xx_gpio6_hwmod, +  	/* mpu class */  	&omap44xx_mpu_hwmod,  	/* wd_timer class */ diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index e0e2fa72526..8d493b992e7 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -21,6 +21,8 @@  #include <linux/err.h>  #include <linux/clk.h>  #include <linux/io.h> +#include <linux/slab.h> +#include <linux/pm_runtime.h>  #include <mach/hardware.h>  #include <asm/irq.h> @@ -32,7 +34,6 @@  /*   * OMAP1510 GPIO registers   */ -#define OMAP1510_GPIO_BASE		0xfffce000  #define OMAP1510_GPIO_DATA_INPUT	0x00  #define OMAP1510_GPIO_DATA_OUTPUT	0x04  #define OMAP1510_GPIO_DIR_CONTROL	0x08 @@ -46,10 +47,6 @@  /*   * OMAP1610 specific GPIO registers   */ -#define OMAP1610_GPIO1_BASE		0xfffbe400 -#define OMAP1610_GPIO2_BASE		0xfffbec00 -#define OMAP1610_GPIO3_BASE		0xfffbb400 -#define OMAP1610_GPIO4_BASE		0xfffbbc00  #define OMAP1610_GPIO_REVISION		0x0000  #define OMAP1610_GPIO_SYSCONFIG		0x0010  #define OMAP1610_GPIO_SYSSTATUS		0x0014 @@ -71,12 +68,6 @@  /*   * OMAP7XX specific GPIO registers   */ -#define OMAP7XX_GPIO1_BASE		0xfffbc000 -#define OMAP7XX_GPIO2_BASE		0xfffbc800 -#define OMAP7XX_GPIO3_BASE		0xfffbd000 -#define OMAP7XX_GPIO4_BASE		0xfffbd800 -#define OMAP7XX_GPIO5_BASE		0xfffbe000 -#define OMAP7XX_GPIO6_BASE		0xfffbe800  #define OMAP7XX_GPIO_DATA_INPUT		0x00  #define OMAP7XX_GPIO_DATA_OUTPUT	0x04  #define OMAP7XX_GPIO_DIR_CONTROL	0x08 @@ -84,25 +75,10 @@  #define OMAP7XX_GPIO_INT_MASK		0x10  #define OMAP7XX_GPIO_INT_STATUS		0x14 -#define OMAP1_MPUIO_VBASE		OMAP1_MPUIO_BASE -  /* - * omap24xx specific GPIO registers + * omap2+ specific GPIO registers   */ -#define OMAP242X_GPIO1_BASE		0x48018000 -#define OMAP242X_GPIO2_BASE		0x4801a000 -#define OMAP242X_GPIO3_BASE		0x4801c000 -#define OMAP242X_GPIO4_BASE		0x4801e000 - -#define OMAP243X_GPIO1_BASE		0x4900C000 -#define OMAP243X_GPIO2_BASE		0x4900E000 -#define OMAP243X_GPIO3_BASE		0x49010000 -#define OMAP243X_GPIO4_BASE		0x49012000 -#define OMAP243X_GPIO5_BASE		0x480B6000 -  #define OMAP24XX_GPIO_REVISION		0x0000 -#define OMAP24XX_GPIO_SYSCONFIG		0x0010 -#define OMAP24XX_GPIO_SYSSTATUS		0x0014  #define OMAP24XX_GPIO_IRQSTATUS1	0x0018  #define OMAP24XX_GPIO_IRQSTATUS2	0x0028  #define OMAP24XX_GPIO_IRQENABLE2	0x002c @@ -126,7 +102,6 @@  #define OMAP24XX_GPIO_SETDATAOUT	0x0094  #define OMAP4_GPIO_REVISION		0x0000 -#define OMAP4_GPIO_SYSCONFIG		0x0010  #define OMAP4_GPIO_EOI			0x0020  #define OMAP4_GPIO_IRQSTATUSRAW0	0x0024  #define OMAP4_GPIO_IRQSTATUSRAW1	0x0028 @@ -138,7 +113,6 @@  #define OMAP4_GPIO_IRQSTATUSCLR1	0x0040  #define OMAP4_GPIO_IRQWAKEN0		0x0044  #define OMAP4_GPIO_IRQWAKEN1		0x0048 -#define OMAP4_GPIO_SYSSTATUS		0x0114  #define OMAP4_GPIO_IRQENABLE1		0x011c  #define OMAP4_GPIO_WAKE_EN		0x0120  #define OMAP4_GPIO_IRQSTATUS2		0x0128 @@ -159,26 +133,6 @@  #define OMAP4_GPIO_SETWKUENA		0x0184  #define OMAP4_GPIO_CLEARDATAOUT		0x0190  #define OMAP4_GPIO_SETDATAOUT		0x0194 -/* - * omap34xx specific GPIO registers - */ - -#define OMAP34XX_GPIO1_BASE		0x48310000 -#define OMAP34XX_GPIO2_BASE		0x49050000 -#define OMAP34XX_GPIO3_BASE		0x49052000 -#define OMAP34XX_GPIO4_BASE		0x49054000 -#define OMAP34XX_GPIO5_BASE		0x49056000 -#define OMAP34XX_GPIO6_BASE		0x49058000 - -/* - * OMAP44XX  specific GPIO registers - */ -#define OMAP44XX_GPIO1_BASE             0x4a310000 -#define OMAP44XX_GPIO2_BASE             0x48055000 -#define OMAP44XX_GPIO3_BASE             0x48057000 -#define OMAP44XX_GPIO4_BASE             0x48059000 -#define OMAP44XX_GPIO5_BASE             0x4805B000 -#define OMAP44XX_GPIO6_BASE             0x4805D000  struct gpio_bank {  	unsigned long pbase; @@ -190,14 +144,12 @@ struct gpio_bank {  	u32 suspend_wakeup;  	u32 saved_wakeup;  #endif -#ifdef CONFIG_ARCH_OMAP2PLUS  	u32 non_wakeup_gpios;  	u32 enabled_non_wakeup_gpios;  	u32 saved_datain;  	u32 saved_fallingdetect;  	u32 saved_risingdetect; -#endif  	u32 level_mask;  	u32 toggle_mask;  	spinlock_t lock; @@ -205,104 +157,13 @@ struct gpio_bank {  	struct clk *dbck;  	u32 mod_usage;  	u32 dbck_enable_mask; +	struct device *dev; +	bool dbck_flag; +	int stride;  }; -#define METHOD_MPUIO		0 -#define METHOD_GPIO_1510	1 -#define METHOD_GPIO_1610	2 -#define METHOD_GPIO_7XX		3 -#define METHOD_GPIO_24XX	5 -#define METHOD_GPIO_44XX	6 - -#ifdef CONFIG_ARCH_OMAP16XX -static struct gpio_bank gpio_bank_1610[5] = { -	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE, -		METHOD_MPUIO }, -	{ OMAP1610_GPIO1_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE, -		METHOD_GPIO_1610 }, -	{ OMAP1610_GPIO2_BASE, NULL, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, -		METHOD_GPIO_1610 }, -	{ OMAP1610_GPIO3_BASE, NULL, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, -		METHOD_GPIO_1610 }, -	{ OMAP1610_GPIO4_BASE, NULL, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, -		METHOD_GPIO_1610 }, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP15XX -static struct gpio_bank gpio_bank_1510[2] = { -	{ OMAP1_MPUIO_VBASE, NULL, INT_MPUIO, IH_MPUIO_BASE, -		METHOD_MPUIO }, -	{ OMAP1510_GPIO_BASE, NULL, INT_GPIO_BANK1, IH_GPIO_BASE, -		METHOD_GPIO_1510 } -}; -#endif - -#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) -static struct gpio_bank gpio_bank_7xx[7] = { -	{ OMAP1_MPUIO_VBASE, NULL, INT_7XX_MPUIO, IH_MPUIO_BASE, -		METHOD_MPUIO }, -	{ OMAP7XX_GPIO1_BASE, NULL, INT_7XX_GPIO_BANK1, IH_GPIO_BASE, -		METHOD_GPIO_7XX }, -	{ OMAP7XX_GPIO2_BASE, NULL, INT_7XX_GPIO_BANK2, IH_GPIO_BASE + 32, -		METHOD_GPIO_7XX }, -	{ OMAP7XX_GPIO3_BASE, NULL, INT_7XX_GPIO_BANK3, IH_GPIO_BASE + 64, -		METHOD_GPIO_7XX }, -	{ OMAP7XX_GPIO4_BASE, NULL, INT_7XX_GPIO_BANK4,  IH_GPIO_BASE + 96, -		METHOD_GPIO_7XX }, -	{ OMAP7XX_GPIO5_BASE, NULL, INT_7XX_GPIO_BANK5,  IH_GPIO_BASE + 128, -		METHOD_GPIO_7XX }, -	{ OMAP7XX_GPIO6_BASE, NULL, INT_7XX_GPIO_BANK6,  IH_GPIO_BASE + 160, -		METHOD_GPIO_7XX }, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP2 - -static struct gpio_bank gpio_bank_242x[4] = { -	{ OMAP242X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, -		METHOD_GPIO_24XX }, -	{ OMAP242X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, -		METHOD_GPIO_24XX }, -	{ OMAP242X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, -		METHOD_GPIO_24XX }, -	{ OMAP242X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, -		METHOD_GPIO_24XX }, -}; - -static struct gpio_bank gpio_bank_243x[5] = { -	{ OMAP243X_GPIO1_BASE, NULL, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, -		METHOD_GPIO_24XX }, -	{ OMAP243X_GPIO2_BASE, NULL, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, -		METHOD_GPIO_24XX }, -	{ OMAP243X_GPIO3_BASE, NULL, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, -		METHOD_GPIO_24XX }, -	{ OMAP243X_GPIO4_BASE, NULL, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, -		METHOD_GPIO_24XX }, -	{ OMAP243X_GPIO5_BASE, NULL, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, -		METHOD_GPIO_24XX }, -}; - -#endif -  #ifdef CONFIG_ARCH_OMAP3 -static struct gpio_bank gpio_bank_34xx[6] = { -	{ OMAP34XX_GPIO1_BASE, NULL, INT_34XX_GPIO_BANK1, IH_GPIO_BASE, -		METHOD_GPIO_24XX }, -	{ OMAP34XX_GPIO2_BASE, NULL, INT_34XX_GPIO_BANK2, IH_GPIO_BASE + 32, -		METHOD_GPIO_24XX }, -	{ OMAP34XX_GPIO3_BASE, NULL, INT_34XX_GPIO_BANK3, IH_GPIO_BASE + 64, -		METHOD_GPIO_24XX }, -	{ OMAP34XX_GPIO4_BASE, NULL, INT_34XX_GPIO_BANK4, IH_GPIO_BASE + 96, -		METHOD_GPIO_24XX }, -	{ OMAP34XX_GPIO5_BASE, NULL, INT_34XX_GPIO_BANK5, IH_GPIO_BASE + 128, -		METHOD_GPIO_24XX }, -	{ OMAP34XX_GPIO6_BASE, NULL, INT_34XX_GPIO_BANK6, IH_GPIO_BASE + 160, -		METHOD_GPIO_24XX }, -}; -  struct omap3_gpio_regs { -	u32 sysconfig;  	u32 irqenable1;  	u32 irqenable2;  	u32 wake_en; @@ -318,26 +179,16 @@ struct omap3_gpio_regs {  static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];  #endif -#ifdef CONFIG_ARCH_OMAP4 -static struct gpio_bank gpio_bank_44xx[6] = { -	{ OMAP44XX_GPIO1_BASE, NULL, OMAP44XX_IRQ_GPIO1, IH_GPIO_BASE, -		METHOD_GPIO_44XX }, -	{ OMAP44XX_GPIO2_BASE, NULL, OMAP44XX_IRQ_GPIO2, IH_GPIO_BASE + 32, -		METHOD_GPIO_44XX }, -	{ OMAP44XX_GPIO3_BASE, NULL, OMAP44XX_IRQ_GPIO3, IH_GPIO_BASE + 64, -		METHOD_GPIO_44XX }, -	{ OMAP44XX_GPIO4_BASE, NULL, OMAP44XX_IRQ_GPIO4, IH_GPIO_BASE + 96, -		METHOD_GPIO_44XX }, -	{ OMAP44XX_GPIO5_BASE, NULL, OMAP44XX_IRQ_GPIO5, IH_GPIO_BASE + 128, -		METHOD_GPIO_44XX }, -	{ OMAP44XX_GPIO6_BASE, NULL, OMAP44XX_IRQ_GPIO6, IH_GPIO_BASE + 160, -		METHOD_GPIO_44XX }, -}; +/* + * TODO: Cleanup gpio_bank usage as it is having information + * related to all instances of the device + */ +static struct gpio_bank *gpio_bank; -#endif +static int bank_width; -static struct gpio_bank *gpio_bank; -static int gpio_bank_count; +/* TODO: Analyze removing gpio_bank_count usage from driver code */ +int gpio_bank_count;  static inline struct gpio_bank *get_gpio_bank(int gpio)  { @@ -417,7 +268,7 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_IO_CNTL; +		reg += OMAP_MPUIO_IO_CNTL / bank->stride;  		break;  #endif  #ifdef CONFIG_ARCH_OMAP15XX @@ -465,7 +316,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_OUTPUT; +		reg += OMAP_MPUIO_OUTPUT / bank->stride;  		l = __raw_readl(reg);  		if (enable)  			l |= 1 << gpio; @@ -537,7 +388,7 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_INPUT_LATCH; +		reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;  		break;  #endif  #ifdef CONFIG_ARCH_OMAP15XX @@ -583,7 +434,7 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_OUTPUT; +		reg += OMAP_MPUIO_OUTPUT / bank->stride;  		break;  #endif  #ifdef CONFIG_ARCH_OMAP15XX @@ -642,6 +493,9 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,  	u32			val;  	u32			l; +	if (!bank->dbck_flag) +		return; +  	if (debounce < 32)  		debounce = 0x01;  	else if (debounce > 7936) @@ -651,7 +505,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,  	l = 1 << get_gpio_index(gpio); -	if (cpu_is_omap44xx()) +	if (bank->method == METHOD_GPIO_44XX)  		reg += OMAP4_GPIO_DEBOUNCINGTIME;  	else  		reg += OMAP24XX_GPIO_DEBOUNCE_VAL; @@ -659,7 +513,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,  	__raw_writel(debounce, reg);  	reg = bank->base; -	if (cpu_is_omap44xx()) +	if (bank->method == METHOD_GPIO_44XX)  		reg += OMAP4_GPIO_DEBOUNCENABLE;  	else  		reg += OMAP24XX_GPIO_DEBOUNCE_EN; @@ -668,12 +522,10 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,  	if (debounce) {  		val |= l; -		if (cpu_is_omap34xx() || cpu_is_omap44xx()) -			clk_enable(bank->dbck); +		clk_enable(bank->dbck);  	} else {  		val &= ~l; -		if (cpu_is_omap34xx() || cpu_is_omap44xx()) -			clk_disable(bank->dbck); +		clk_disable(bank->dbck);  	}  	bank->dbck_enable_mask = val; @@ -769,7 +621,7 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)  	switch (bank->method) {  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_GPIO_INT_EDGE; +		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;  		break;  #ifdef CONFIG_ARCH_OMAP15XX  	case METHOD_GPIO_1510: @@ -803,7 +655,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_GPIO_INT_EDGE; +		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;  		l = __raw_readl(reg);  		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)  			bank->toggle_mask |= 1 << gpio; @@ -989,7 +841,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_GPIO_MASKIT; +		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;  		mask = 0xffff;  		inv = 1;  		break; @@ -1046,7 +898,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab  	switch (bank->method) {  #ifdef CONFIG_ARCH_OMAP1  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_GPIO_MASKIT; +		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;  		l = __raw_readl(reg);  		if (enable)  			l &= ~(gpio_mask); @@ -1296,7 +1148,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)  	bank = get_irq_data(irq);  #ifdef CONFIG_ARCH_OMAP1  	if (bank->method == METHOD_MPUIO) -		isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; +		isr_reg = bank->base + +				OMAP_MPUIO_GPIO_INT / bank->stride;  #endif  #ifdef CONFIG_ARCH_OMAP15XX  	if (bank->method == METHOD_GPIO_1510) @@ -1494,7 +1347,8 @@ static int omap_mpuio_suspend_noirq(struct device *dev)  {  	struct platform_device *pdev = to_platform_device(dev);  	struct gpio_bank	*bank = platform_get_drvdata(pdev); -	void __iomem		*mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; +	void __iomem		*mask_reg = bank->base + +					OMAP_MPUIO_GPIO_MASKIT / bank->stride;  	unsigned long		flags;  	spin_lock_irqsave(&bank->lock, flags); @@ -1509,7 +1363,8 @@ static int omap_mpuio_resume_noirq(struct device *dev)  {  	struct platform_device *pdev = to_platform_device(dev);  	struct gpio_bank	*bank = platform_get_drvdata(pdev); -	void __iomem		*mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; +	void __iomem		*mask_reg = bank->base + +					OMAP_MPUIO_GPIO_MASKIT / bank->stride;  	unsigned long		flags;  	spin_lock_irqsave(&bank->lock, flags); @@ -1545,7 +1400,8 @@ static struct platform_device omap_mpuio_device = {  static inline void mpuio_init(void)  { -	platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]); +	struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0)); +	platform_set_drvdata(&omap_mpuio_device, bank);  	if (platform_driver_register(&omap_mpuio_driver) == 0)  		(void) platform_device_register(&omap_mpuio_device); @@ -1588,7 +1444,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)  	switch (bank->method) {  	case METHOD_MPUIO: -		reg += OMAP_MPUIO_IO_CNTL; +		reg += OMAP_MPUIO_IO_CNTL / bank->stride;  		break;  	case METHOD_GPIO_1510:  		reg += OMAP1510_GPIO_DIR_CONTROL; @@ -1650,6 +1506,13 @@ static int gpio_debounce(struct gpio_chip *chip, unsigned offset,  	unsigned long flags;  	bank = container_of(chip, struct gpio_bank, chip); + +	if (!bank->dbck) { +		bank->dbck = clk_get(bank->dev, "dbclk"); +		if (IS_ERR(bank->dbck)) +			dev_err(bank->dev, "Could not get gpio dbck\n"); +	} +  	spin_lock_irqsave(&bank->lock, flags);  	_set_gpio_debounce(bank, offset, debounce);  	spin_unlock_irqrestore(&bank->lock, flags); @@ -1678,34 +1541,16 @@ static int gpio_2irq(struct gpio_chip *chip, unsigned offset)  /*---------------------------------------------------------------------*/ -static int initialized; -#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2) -static struct clk * gpio_ick; -#endif - -#if defined(CONFIG_ARCH_OMAP2) -static struct clk * gpio_fck; -#endif - -#if defined(CONFIG_ARCH_OMAP2430) -static struct clk * gpio5_ick; -static struct clk * gpio5_fck; -#endif - -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) -static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; -#endif - -static void __init omap_gpio_show_rev(void) +static void __init omap_gpio_show_rev(struct gpio_bank *bank)  {  	u32 rev; -	if (cpu_is_omap16xx()) -		rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION); +	if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO)) +		rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);  	else if (cpu_is_omap24xx() || cpu_is_omap34xx()) -		rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); +		rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);  	else if (cpu_is_omap44xx()) -		rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION); +		rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);  	else  		return; @@ -1718,250 +1563,190 @@ static void __init omap_gpio_show_rev(void)   */  static struct lock_class_key gpio_lock_class; -static int __init _omap_gpio_init(void) +static inline int init_gpio_info(struct platform_device *pdev)  { -	int i; -	int gpio = 0; -	struct gpio_bank *bank; -	int bank_size = SZ_8K;	/* Module 4KB + L4 4KB except on omap1 */ -	char clk_name[11]; - -	initialized = 1; - -#if defined(CONFIG_ARCH_OMAP1) -	if (cpu_is_omap15xx()) { -		gpio_ick = clk_get(NULL, "arm_gpio_ck"); -		if (IS_ERR(gpio_ick)) -			printk("Could not get arm_gpio_ck\n"); -		else -			clk_enable(gpio_ick); +	/* TODO: Analyze removing gpio_bank_count usage from driver code */ +	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank), +				GFP_KERNEL); +	if (!gpio_bank) { +		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n"); +		return -ENOMEM;  	} -#endif -#if defined(CONFIG_ARCH_OMAP2) +	return 0; +} + +/* TODO: Cleanup cpu_is_* checks */ +static void omap_gpio_mod_init(struct gpio_bank *bank, int id) +{  	if (cpu_class_is_omap2()) { -		gpio_ick = clk_get(NULL, "gpios_ick"); -		if (IS_ERR(gpio_ick)) -			printk("Could not get gpios_ick\n"); -		else -			clk_enable(gpio_ick); -		gpio_fck = clk_get(NULL, "gpios_fck"); -		if (IS_ERR(gpio_fck)) -			printk("Could not get gpios_fck\n"); -		else -			clk_enable(gpio_fck); +		if (cpu_is_omap44xx()) { +			__raw_writel(0xffffffff, bank->base + +					OMAP4_GPIO_IRQSTATUSCLR0); +			__raw_writel(0x00000000, bank->base + +					 OMAP4_GPIO_DEBOUNCENABLE); +			/* Initialize interface clk ungated, module enabled */ +			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL); +		} else if (cpu_is_omap34xx()) { +			__raw_writel(0x00000000, bank->base + +					OMAP24XX_GPIO_IRQENABLE1); +			__raw_writel(0xffffffff, bank->base + +					OMAP24XX_GPIO_IRQSTATUS1); +			__raw_writel(0x00000000, bank->base + +					OMAP24XX_GPIO_DEBOUNCE_EN); -		/* -		 * On 2430 & 3430 GPIO 5 uses CORE L4 ICLK -		 */ -#if defined(CONFIG_ARCH_OMAP2430) -		if (cpu_is_omap2430()) { -			gpio5_ick = clk_get(NULL, "gpio5_ick"); -			if (IS_ERR(gpio5_ick)) -				printk("Could not get gpio5_ick\n"); -			else -				clk_enable(gpio5_ick); -			gpio5_fck = clk_get(NULL, "gpio5_fck"); -			if (IS_ERR(gpio5_fck)) -				printk("Could not get gpio5_fck\n"); -			else -				clk_enable(gpio5_fck); +			/* Initialize interface clk ungated, module enabled */ +			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); +		} else if (cpu_is_omap24xx()) { +			static const u32 non_wakeup_gpios[] = { +				0xe203ffc0, 0x08700040 +			}; +			if (id < ARRAY_SIZE(non_wakeup_gpios)) +				bank->non_wakeup_gpios = non_wakeup_gpios[id];  		} -#endif -	} -#endif +	} else if (cpu_class_is_omap1()) { +		if (bank_is_mpuio(bank)) +			__raw_writew(0xffff, bank->base + +				OMAP_MPUIO_GPIO_MASKIT / bank->stride); +		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) { +			__raw_writew(0xffff, bank->base +						+ OMAP1510_GPIO_INT_MASK); +			__raw_writew(0x0000, bank->base +						+ OMAP1510_GPIO_INT_STATUS); +		} +		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) { +			__raw_writew(0x0000, bank->base +						+ OMAP1610_GPIO_IRQENABLE1); +			__raw_writew(0xffff, bank->base +						+ OMAP1610_GPIO_IRQSTATUS1); +			__raw_writew(0x0014, bank->base +						+ OMAP1610_GPIO_SYSCONFIG); -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) -	if (cpu_is_omap34xx() || cpu_is_omap44xx()) { -		for (i = 0; i < OMAP34XX_NR_GPIOS; i++) { -			sprintf(clk_name, "gpio%d_ick", i + 1); -			gpio_iclks[i] = clk_get(NULL, clk_name); -			if (IS_ERR(gpio_iclks[i])) -				printk(KERN_ERR "Could not get %s\n", clk_name); -			else -				clk_enable(gpio_iclks[i]); +			/* +			 * Enable system clock for GPIO module. +			 * The CAM_CLK_CTRL *is* really the right place. +			 */ +			omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, +						ULPD_CAM_CLK_CTRL); +		} +		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) { +			__raw_writel(0xffffffff, bank->base +						+ OMAP7XX_GPIO_INT_MASK); +			__raw_writel(0x00000000, bank->base +						+ OMAP7XX_GPIO_INT_STATUS);  		}  	} -#endif +} +static void __init omap_gpio_chip_init(struct gpio_bank *bank) +{ +	int j; +	static int gpio; -#ifdef CONFIG_ARCH_OMAP15XX -	if (cpu_is_omap15xx()) { -		gpio_bank_count = 2; -		gpio_bank = gpio_bank_1510; -		bank_size = SZ_2K; -	} -#endif -#if defined(CONFIG_ARCH_OMAP16XX) -	if (cpu_is_omap16xx()) { -		gpio_bank_count = 5; -		gpio_bank = gpio_bank_1610; -		bank_size = SZ_2K; -	} -#endif -#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) -	if (cpu_is_omap7xx()) { -		gpio_bank_count = 7; -		gpio_bank = gpio_bank_7xx; -		bank_size = SZ_2K; -	} -#endif -#ifdef CONFIG_ARCH_OMAP2 -	if (cpu_is_omap242x()) { -		gpio_bank_count = 4; -		gpio_bank = gpio_bank_242x; -	} -	if (cpu_is_omap243x()) { -		gpio_bank_count = 5; -		gpio_bank = gpio_bank_243x; -	} +	bank->mod_usage = 0; +	/* +	 * REVISIT eventually switch from OMAP-specific gpio structs +	 * over to the generic ones +	 */ +	bank->chip.request = omap_gpio_request; +	bank->chip.free = omap_gpio_free; +	bank->chip.direction_input = gpio_input; +	bank->chip.get = gpio_get; +	bank->chip.direction_output = gpio_output; +	bank->chip.set_debounce = gpio_debounce; +	bank->chip.set = gpio_set; +	bank->chip.to_irq = gpio_2irq; +	if (bank_is_mpuio(bank)) { +		bank->chip.label = "mpuio"; +#ifdef CONFIG_ARCH_OMAP16XX +		bank->chip.dev = &omap_mpuio_device.dev;  #endif -#ifdef CONFIG_ARCH_OMAP3 -	if (cpu_is_omap34xx()) { -		gpio_bank_count = OMAP34XX_NR_GPIOS; -		gpio_bank = gpio_bank_34xx; +		bank->chip.base = OMAP_MPUIO(0); +	} else { +		bank->chip.label = "gpio"; +		bank->chip.base = gpio; +		gpio += bank_width;  	} -#endif -#ifdef CONFIG_ARCH_OMAP4 -	if (cpu_is_omap44xx()) { -		gpio_bank_count = OMAP34XX_NR_GPIOS; -		gpio_bank = gpio_bank_44xx; +	bank->chip.ngpio = bank_width; + +	gpiochip_add(&bank->chip); + +	for (j = bank->virtual_irq_start; +		     j < bank->virtual_irq_start + bank_width; j++) { +		lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); +		set_irq_chip_data(j, bank); +		if (bank_is_mpuio(bank)) +			set_irq_chip(j, &mpuio_irq_chip); +		else +			set_irq_chip(j, &gpio_irq_chip); +		set_irq_handler(j, handle_simple_irq); +		set_irq_flags(j, IRQF_VALID);  	} -#endif -	for (i = 0; i < gpio_bank_count; i++) { -		int j, gpio_count = 16; +	set_irq_chained_handler(bank->irq, gpio_irq_handler); +	set_irq_data(bank->irq, bank); +} -		bank = &gpio_bank[i]; -		spin_lock_init(&bank->lock); +static int __devinit omap_gpio_probe(struct platform_device *pdev) +{ +	static int gpio_init_done; +	struct omap_gpio_platform_data *pdata; +	struct resource *res; +	int id; +	struct gpio_bank *bank; -		/* Static mapping, never released */ -		bank->base = ioremap(bank->pbase, bank_size); -		if (!bank->base) { -			printk(KERN_ERR "Could not ioremap gpio bank%i\n", i); -			continue; -		} +	if (!pdev->dev.platform_data) +		return -EINVAL; -		if (bank_is_mpuio(bank)) -			__raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT); -		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) { -			__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); -			__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); -		} -		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) { -			__raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1); -			__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); -			__raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG); -		} -		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) { -			__raw_writel(0xffffffff, bank->base + OMAP7XX_GPIO_INT_MASK); -			__raw_writel(0x00000000, bank->base + OMAP7XX_GPIO_INT_STATUS); +	pdata = pdev->dev.platform_data; -			gpio_count = 32; /* 7xx has 32-bit GPIOs */ -		} +	if (!gpio_init_done) { +		int ret; -#ifdef CONFIG_ARCH_OMAP2PLUS -		if ((bank->method == METHOD_GPIO_24XX) || -				(bank->method == METHOD_GPIO_44XX)) { -			static const u32 non_wakeup_gpios[] = { -				0xe203ffc0, 0x08700040 -			}; +		ret = init_gpio_info(pdev); +		if (ret) +			return ret; +	} -			if (cpu_is_omap44xx()) { -				__raw_writel(0xffffffff, bank->base + -						OMAP4_GPIO_IRQSTATUSCLR0); -				__raw_writew(0x0015, bank->base + -						OMAP4_GPIO_SYSCONFIG); -				__raw_writel(0x00000000, bank->base + -						 OMAP4_GPIO_DEBOUNCENABLE); -				/* -				 * Initialize interface clock ungated, -				 * module enabled -				 */ -				__raw_writel(0, bank->base + OMAP4_GPIO_CTRL); -			} else { -				__raw_writel(0x00000000, bank->base + -						OMAP24XX_GPIO_IRQENABLE1); -				__raw_writel(0xffffffff, bank->base + -						OMAP24XX_GPIO_IRQSTATUS1); -				__raw_writew(0x0015, bank->base + -						OMAP24XX_GPIO_SYSCONFIG); -				__raw_writel(0x00000000, bank->base + -						OMAP24XX_GPIO_DEBOUNCE_EN); +	id = pdev->id; +	bank = &gpio_bank[id]; -				/* -				 * Initialize interface clock ungated, -				 * module enabled -				 */ -				__raw_writel(0, bank->base + -						OMAP24XX_GPIO_CTRL); -			} -			if (cpu_is_omap24xx() && -			    i < ARRAY_SIZE(non_wakeup_gpios)) -				bank->non_wakeup_gpios = non_wakeup_gpios[i]; -			gpio_count = 32; -		} -#endif +	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); +	if (unlikely(!res)) { +		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id); +		return -ENODEV; +	} -		bank->mod_usage = 0; -		/* REVISIT eventually switch from OMAP-specific gpio structs -		 * over to the generic ones -		 */ -		bank->chip.request = omap_gpio_request; -		bank->chip.free = omap_gpio_free; -		bank->chip.direction_input = gpio_input; -		bank->chip.get = gpio_get; -		bank->chip.direction_output = gpio_output; -		bank->chip.set_debounce = gpio_debounce; -		bank->chip.set = gpio_set; -		bank->chip.to_irq = gpio_2irq; -		if (bank_is_mpuio(bank)) { -			bank->chip.label = "mpuio"; -#ifdef CONFIG_ARCH_OMAP16XX -			bank->chip.dev = &omap_mpuio_device.dev; -#endif -			bank->chip.base = OMAP_MPUIO(0); -		} else { -			bank->chip.label = "gpio"; -			bank->chip.base = gpio; -			gpio += gpio_count; -		} -		bank->chip.ngpio = gpio_count; +	bank->irq = res->start; +	bank->virtual_irq_start = pdata->virtual_irq_start; +	bank->method = pdata->bank_type; +	bank->dev = &pdev->dev; +	bank->dbck_flag = pdata->dbck_flag; +	bank->stride = pdata->bank_stride; +	bank_width = pdata->bank_width; -		gpiochip_add(&bank->chip); +	spin_lock_init(&bank->lock); -		for (j = bank->virtual_irq_start; -		     j < bank->virtual_irq_start + gpio_count; j++) { -			lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); -			set_irq_chip_data(j, bank); -			if (bank_is_mpuio(bank)) -				set_irq_chip(j, &mpuio_irq_chip); -			else -				set_irq_chip(j, &gpio_irq_chip); -			set_irq_handler(j, handle_simple_irq); -			set_irq_flags(j, IRQF_VALID); -		} -		set_irq_chained_handler(bank->irq, gpio_irq_handler); -		set_irq_data(bank->irq, bank); +	/* Static mapping, never released */ +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (unlikely(!res)) { +		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id); +		return -ENODEV; +	} -		if (cpu_is_omap34xx() || cpu_is_omap44xx()) { -			sprintf(clk_name, "gpio%d_dbck", i + 1); -			bank->dbck = clk_get(NULL, clk_name); -			if (IS_ERR(bank->dbck)) -				printk(KERN_ERR "Could not get %s\n", clk_name); -		} +	bank->base = ioremap(res->start, resource_size(res)); +	if (!bank->base) { +		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id); +		return -ENOMEM;  	} -	/* Enable system clock for GPIO module. -	 * The CAM_CLK_CTRL *is* really the right place. */ -	if (cpu_is_omap16xx()) -		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); +	pm_runtime_enable(bank->dev); +	pm_runtime_get_sync(bank->dev); -	/* Enable autoidle for the OCP interface */ -	if (cpu_is_omap24xx()) -		omap_writel(1 << 0, 0x48019010); -	if (cpu_is_omap34xx()) -		omap_writel(1 << 0, 0x48306814); +	omap_gpio_mod_init(bank, id); +	omap_gpio_chip_init(bank); +	omap_gpio_show_rev(bank); -	omap_gpio_show_rev(); +	if (!gpio_init_done) +		gpio_init_done = 1;  	return 0;  } @@ -2256,8 +2041,6 @@ void omap_gpio_save_context(void)  	/* saving banks from 2-6 only since GPIO1 is in WKUP */  	for (i = 1; i < gpio_bank_count; i++) {  		struct gpio_bank *bank = &gpio_bank[i]; -		gpio_context[i].sysconfig = -			__raw_readl(bank->base + OMAP24XX_GPIO_SYSCONFIG);  		gpio_context[i].irqenable1 =  			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);  		gpio_context[i].irqenable2 = @@ -2288,8 +2071,6 @@ void omap_gpio_restore_context(void)  	for (i = 1; i < gpio_bank_count; i++) {  		struct gpio_bank *bank = &gpio_bank[i]; -		__raw_writel(gpio_context[i].sysconfig, -				bank->base + OMAP24XX_GPIO_SYSCONFIG);  		__raw_writel(gpio_context[i].irqenable1,  				bank->base + OMAP24XX_GPIO_IRQENABLE1);  		__raw_writel(gpio_context[i].irqenable2, @@ -2314,25 +2095,28 @@ void omap_gpio_restore_context(void)  }  #endif +static struct platform_driver omap_gpio_driver = { +	.probe		= omap_gpio_probe, +	.driver		= { +		.name	= "omap_gpio", +	}, +}; +  /* - * This may get called early from board specific init - * for boards that have interrupts routed via FPGA. + * gpio driver register needs to be done before + * machine_init functions access gpio APIs. + * Hence omap_gpio_drv_reg() is a postcore_initcall.   */ -int __init omap_gpio_init(void) +static int __init omap_gpio_drv_reg(void)  { -	if (!initialized) -		return _omap_gpio_init(); -	else -		return 0; +	return platform_driver_register(&omap_gpio_driver);  } +postcore_initcall(omap_gpio_drv_reg);  static int __init omap_gpio_sysinit(void)  {  	int ret = 0; -	if (!initialized) -		ret = _omap_gpio_init(); -  	mpuio_init();  #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index de1c604962e..41ff2f8943f 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -27,26 +27,15 @@  #define __ASM_ARCH_OMAP_GPIO_H  #include <linux/io.h> +#include <linux/platform_device.h>  #include <mach/irqs.h>  #define OMAP1_MPUIO_BASE			0xfffb5000 -#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)) - -#define OMAP_MPUIO_INPUT_LATCH		0x00 -#define OMAP_MPUIO_OUTPUT		0x02 -#define OMAP_MPUIO_IO_CNTL		0x04 -#define OMAP_MPUIO_KBR_LATCH		0x08 -#define OMAP_MPUIO_KBC			0x0a -#define OMAP_MPUIO_GPIO_EVENT_MODE	0x0c -#define OMAP_MPUIO_GPIO_INT_EDGE	0x0e -#define OMAP_MPUIO_KBD_INT		0x10 -#define OMAP_MPUIO_GPIO_INT		0x12 -#define OMAP_MPUIO_KBD_MASKIT		0x14 -#define OMAP_MPUIO_GPIO_MASKIT		0x16 -#define OMAP_MPUIO_GPIO_DEBOUNCING	0x18 -#define OMAP_MPUIO_LATCH		0x1a -#else +/* + * These are the omap15xx/16xx offsets. The omap7xx offset are + * OMAP_MPUIO_ / 2 offsets below. + */  #define OMAP_MPUIO_INPUT_LATCH		0x00  #define OMAP_MPUIO_OUTPUT		0x04  #define OMAP_MPUIO_IO_CNTL		0x08 @@ -60,7 +49,6 @@  #define OMAP_MPUIO_GPIO_MASKIT		0x2c  #define OMAP_MPUIO_GPIO_DEBOUNCING	0x30  #define OMAP_MPUIO_LATCH		0x34 -#endif  #define OMAP34XX_NR_GPIOS		6 @@ -71,7 +59,29 @@  				 IH_MPUIO_BASE + ((nr) & 0x0f) : \  				 IH_GPIO_BASE + (nr)) -extern int omap_gpio_init(void);	/* Call from board init only */ +#define METHOD_MPUIO		0 +#define METHOD_GPIO_1510	1 +#define METHOD_GPIO_1610	2 +#define METHOD_GPIO_7XX		3 +#define METHOD_GPIO_24XX	5 +#define METHOD_GPIO_44XX	6 + +struct omap_gpio_dev_attr { +	int bank_width;		/* GPIO bank width */ +	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */ +}; + +struct omap_gpio_platform_data { +	u16 virtual_irq_start; +	int bank_type; +	int bank_width;		/* GPIO bank width */ +	int bank_stride;	/* Only needed for omap1 MPUIO */ +	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */ +}; + +/* TODO: Analyze removing gpio_bank_count usage from driver code */ +extern int gpio_bank_count; +  extern void omap2_gpio_prepare_for_idle(int power_state);  extern void omap2_gpio_resume_after_idle(void);  extern void omap_set_gpio_debounce(int gpio, int enable);  |