GPIO driver updates for DaVinci

-------------------------------
 
 This pull request moves DaVinci GPIO
 driver to use platform device framework
 and the corresponding changes needed to
 keep GPIO working on existing DaVinci
 boards. This is a pre-requisite to DT
 support for GPIO.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.10 (GNU/Linux)
 
 iQIcBAABAgAGBQJSQhn5AAoJEGFBu2jqvgRNxD8P/2nIza204tA9AWtre7Y7FBjb
 c4Mya2Lv9xHVZltBks4YFJ54+SwfABzYw1+SanDGXUjl9CuduCGo1XCjPlOjjYGq
 wY+7MNJ7PAHlPoEQy1L/Mg8lEnH0Bp1v8O0zlYDmU/Vr8ozueEwuHxfn+DtXSbe9
 Y1Y2w9mcLcD5BF3SC8erTatzpcCB9k/nSEvR9s5iyclFzIoSHPtAWhn0tHNcgJPo
 rGaWWzn4mK3IZ0IfOggjt2D/i1VXXIkzKIRJn0JT10tqd5gtjAvksS7EHKADIM5O
 kPiTiSPyNRWmU+ddtriv1Vhgy5J8g+RsI846UACo3OuRmOD7iCYADyEFEeH5p6y1
 +yZs2eMKwYqa24urwMUg/U+GuiNrtQGSl9ti31Yh2OOCYExV/cFNmGyo1DMiS7kX
 um+Q4mnL8JKdLBhpgnUGBo3slp7a1P7iFn4tsnQbyCx8ZtFuWER7eAAYxWu1FpxK
 +D/WNjQEJCcxWta+SX5AywYAlHziDfbpQxT+zsZvol4JA4u+8atQDcOf7GWODIHd
 h6WP1VsJAkinCyuMn1exIP485ZM7f3FcOlDurrCQNoOa/fZQdz7V8Uh8QHcKknlL
 qdOLB9kISKNKs94DvInkFrQB/2lQwac6oepTlkTysRlhdAe4dYN8LZKOz8mbo4r6
 LYjBy6W8+LikbP4LQI83
 =TjOR
 -----END PGP SIGNATURE-----

Merge tag 'davinci-for-v3.13/gpio' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into next/drivers

From Sekhar Nori, GPIO driver updates for DaVinci:

This pull request moves DaVinci GPIO driver to use platform device
framework and the corresponding changes needed to keep GPIO working on
existing DaVinci boards. This is a pre-requisite to DT support for GPIO.

* tag 'davinci-for-v3.13/gpio' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci:
  ARM: davinci: gpio: use gpiolib API instead of inline functions
  ARM: davinci: board: gpio device creation
  ARM: davinci: da8xx boards: gpio device creation
  ARM: davinci: support gpio platform device
  ARM: davinci: da8xx: support gpio platform device
  gpio: davinci: move to platform device
  gpio: davinci: coding style correction

Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2013-10-07 09:29:10 -07:00
commit 3d729d33ee
25 changed files with 402 additions and 277 deletions

View file

@ -847,7 +847,6 @@ config ARCH_DAVINCI
select GENERIC_CLOCKEVENTS
select GENERIC_IRQ_CHIP
select HAVE_IDE
select NEED_MACH_GPIO_H
select TI_PRIV_EDMA
select USE_OF
select ZONE_DMA

View file

@ -22,17 +22,19 @@
#include <linux/mtd/partitions.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/cp_intc.h>
#include <mach/mux.h>
#include <linux/platform_data/mtd-davinci.h>
#include <mach/da8xx.h>
#include <linux/platform_data/usb-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
#define DA830_EVM_PHY_ID ""
/*
@ -591,6 +593,10 @@ static __init void da830_evm_init(void)
struct davinci_soc_info *soc_info = &davinci_soc_info;
int ret;
ret = da830_register_gpio();
if (ret)
pr_warn("da830_evm_init: GPIO init failed: %d\n", ret);
ret = da830_register_edma(da830_edma_rsv);
if (ret)
pr_warning("da830_evm_init: edma registration failed: %d\n",

View file

@ -28,6 +28,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <linux/platform_data/spi-davinci.h>
@ -38,6 +39,7 @@
#include <linux/spi/flash.h>
#include <linux/wl12xx.h>
#include <mach/common.h>
#include <mach/cp_intc.h>
#include <mach/da8xx.h>
#include <mach/mux.h>
@ -1437,6 +1439,10 @@ static __init void da850_evm_init(void)
{
int ret;
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
ret = pmic_tps65070_init();
if (ret)
pr_warn("%s: TPS65070 PMIC init failed: %d\n", __func__, ret);

View file

@ -22,15 +22,17 @@
#include <media/tvp514x.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <linux/platform_data/i2c-davinci.h>
#include <mach/serial.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <mach/common.h>
#include "davinci.h"
@ -375,6 +377,11 @@ static struct spi_board_info dm355_evm_spi_info[] __initconst = {
static __init void dm355_evm_init(void)
{
struct clk *aemif;
int ret;
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
gpio_request(1, "dm9000");
gpio_direction_input(1);

View file

@ -19,15 +19,16 @@
#include <linux/clk.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <linux/platform_data/i2c-davinci.h>
#include <mach/common.h>
#include <mach/serial.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include "davinci.h"
@ -234,6 +235,11 @@ static struct spi_board_info dm355_leopard_spi_info[] __initconst = {
static __init void dm355_leopard_init(void)
{
struct clk *aemif;
int ret;
ret = dm355_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
gpio_request(9, "dm9000");
gpio_direction_input(9);

View file

@ -743,6 +743,12 @@ static struct spi_board_info dm365_evm_spi_info[] __initconst = {
static __init void dm365_evm_init(void)
{
int ret;
ret = dm365_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
evm_init_i2c();
davinci_serial_init(dm365_serial_device);

View file

@ -754,9 +754,14 @@ static int davinci_phy_fixup(struct phy_device *phydev)
static __init void davinci_evm_init(void)
{
int ret;
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
aemif_clk = clk_get(NULL, "aemif");
clk_prepare_enable(aemif_clk);

View file

@ -33,17 +33,19 @@
#include <linux/mtd/partitions.h>
#include <linux/clk.h>
#include <linux/export.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/irqs.h>
#include <mach/serial.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <mach/clock.h>
#include <mach/cdce949.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
#include "davinci.h"
#include "clock.h"
@ -786,8 +788,13 @@ static struct edma_rsv_info dm646x_edma_rsv[] = {
static __init void evm_init(void)
{
int ret;
struct davinci_soc_info *soc_info = &davinci_soc_info;
ret = dm646x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
evm_init_i2c();
davinci_serial_init(dm646x_serial_device);
dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);

View file

@ -26,17 +26,18 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/i2c-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <linux/platform_data/i2c-davinci.h>
#include <mach/serial.h>
#include <mach/mux.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mmc-davinci.h>
#include <linux/platform_data/usb-davinci.h>
#include "davinci.h"
@ -169,9 +170,14 @@ static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
static __init void davinci_ntosd2_init(void)
{
int ret;
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
aemif_clk = clk_get(NULL, "aemif");
clk_prepare_enable(aemif_clk);

View file

@ -13,10 +13,12 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/gpio.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>
#include <mach/cp_intc.h>
#include <mach/da8xx.h>
#include <mach/mux.h>
@ -290,6 +292,10 @@ static __init void omapl138_hawk_init(void)
{
int ret;
ret = da850_register_gpio();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
davinci_serial_init(da8xx_serial_device);
omapl138_hawk_config_emac();

View file

@ -11,6 +11,7 @@
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
@ -20,7 +21,6 @@
#include <mach/common.h>
#include <mach/time.h>
#include <mach/da8xx.h>
#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
@ -1151,6 +1151,16 @@ static struct davinci_id da830_ids[] = {
},
};
static struct davinci_gpio_platform_data da830_gpio_platform_data = {
.ngpio = 128,
.intc_irq_num = DA830_N_CP_INTC_IRQ,
};
int __init da830_register_gpio(void)
{
return da8xx_register_gpio(&da830_gpio_platform_data);
}
static struct davinci_timer_instance da830_timer_instance[2] = {
{
.base = DA8XX_TIMER64P0_BASE,
@ -1196,10 +1206,6 @@ static struct davinci_soc_info davinci_soc_info_da830 = {
.intc_irq_prios = da830_default_priorities,
.intc_irq_num = DA830_N_CP_INTC_IRQ,
.timer_info = &da830_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DA8XX_GPIO_BASE,
.gpio_num = 128,
.gpio_irq = IRQ_DA8XX_GPIO0,
.emac_pdata = &da8xx_emac_pdata,
};

View file

@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/cpufreq.h>
#include <linux/regulator/consumer.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
@ -28,7 +29,6 @@
#include <mach/da8xx.h>
#include <mach/cpufreq.h>
#include <mach/pm.h>
#include <mach/gpio-davinci.h>
#include "clock.h"
#include "mux.h"
@ -1281,6 +1281,16 @@ int __init da850_register_vpif_capture(struct vpif_capture_config
return platform_device_register(&da850_vpif_capture_dev);
}
static struct davinci_gpio_platform_data da850_gpio_platform_data = {
.ngpio = 144,
.intc_irq_num = DA850_N_CP_INTC_IRQ,
};
int __init da850_register_gpio(void)
{
return da8xx_register_gpio(&da850_gpio_platform_data);
}
static struct davinci_soc_info davinci_soc_info_da850 = {
.io_desc = da850_io_desc,
.io_desc_num = ARRAY_SIZE(da850_io_desc),
@ -1298,10 +1308,6 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
.intc_irq_prios = da850_default_priorities,
.intc_irq_num = DA850_N_CP_INTC_IRQ,
.timer_info = &da850_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DA8XX_GPIO_BASE,
.gpio_num = 144,
.gpio_irq = IRQ_DA8XX_GPIO0,
.emac_pdata = &da8xx_emac_pdata,
.sram_dma = DA8XX_SHARED_RAM_BASE,
.sram_len = SZ_128K,

View file

@ -53,6 +53,9 @@ extern void __iomem *davinci_sysmod_base;
#define DAVINCI_SYSMOD_VIRT(x) (davinci_sysmod_base + (x))
void davinci_map_sysmod(void);
#define DAVINCI_GPIO_BASE 0x01C67000
int davinci_gpio_register(struct resource *res, int size, void *pdata);
/* DM355 base addresses */
#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01e10000
#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
@ -82,6 +85,7 @@ void dm355_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
int dm355_gpio_register(void);
/* DM365 function declarations */
void dm365_init(void);
@ -92,11 +96,13 @@ void dm365_init_rtc(void);
void dm365_init_spi0(unsigned chipselect_mask,
const struct spi_board_info *info, unsigned len);
int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_init(void);
void dm644x_init_asp(struct snd_platform_data *pdata);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
int dm644x_gpio_register(void);
/* DM646x function declarations */
void dm646x_init(void);
@ -106,6 +112,7 @@ int dm646x_init_edma(struct edma_rsv_info *rsv);
void dm646x_video_init(void);
void dm646x_setup_vpif(struct vpif_display_config *,
struct vpif_capture_config *);
int dm646x_gpio_register(void);
extern struct platform_device dm365_serial_device[];
extern struct platform_device dm355_serial_device[];

View file

@ -665,6 +665,32 @@ int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
return platform_device_register(&da8xx_lcdc_device);
}
static struct resource da8xx_gpio_resources[] = {
{ /* registers */
.start = DA8XX_GPIO_BASE,
.end = DA8XX_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_DA8XX_GPIO0,
.end = IRQ_DA8XX_GPIO8,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device da8xx_gpio_device = {
.name = "davinci_gpio",
.id = -1,
.num_resources = ARRAY_SIZE(da8xx_gpio_resources),
.resource = da8xx_gpio_resources,
};
int __init da8xx_register_gpio(void *pdata)
{
da8xx_gpio_device.dev.platform_data = pdata;
return platform_device_register(&da8xx_gpio_device);
}
static struct resource da8xx_mmcsd0_resources[] = {
{ /* registers */
.start = DA8XX_MMCSD0_BASE,

View file

@ -318,6 +318,19 @@ static void davinci_init_wdt(void)
platform_device_register(&davinci_wdt_device);
}
static struct platform_device davinci_gpio_device = {
.name = "davinci_gpio",
.id = -1,
};
int davinci_gpio_register(struct resource *res, int size, void *pdata)
{
davinci_gpio_device.resource = res;
davinci_gpio_device.num_resources = size;
davinci_gpio_device.dev.platform_data = pdata;
return platform_device_register(&davinci_gpio_device);
}
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/

View file

@ -13,8 +13,10 @@
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/spi-davinci.h>
#include <asm/mach/map.h>
@ -25,9 +27,6 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
#include <linux/platform_data/spi-davinci.h>
#include <mach/gpio-davinci.h>
#include <linux/platform_data/edma.h>
#include "davinci.h"
#include "clock.h"
@ -886,6 +885,30 @@ static struct platform_device dm355_vpbe_dev = {
},
};
static struct resource dm355_gpio_resources[] = {
{ /* registers */
.start = DAVINCI_GPIO_BASE,
.end = DAVINCI_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_DM355_GPIOBNK0,
.end = IRQ_DM355_GPIOBNK6,
.flags = IORESOURCE_IRQ,
},
};
static struct davinci_gpio_platform_data dm355_gpio_platform_data = {
.ngpio = 104,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
};
int __init dm355_gpio_register(void)
{
return davinci_gpio_register(dm355_gpio_resources,
sizeof(dm355_gpio_resources),
&dm355_gpio_platform_data);
}
/*----------------------------------------------------------------------*/
static struct map_desc dm355_io_desc[] = {
@ -1005,10 +1028,6 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
.intc_irq_prios = dm355_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
.timer_info = &dm355_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DAVINCI_GPIO_BASE,
.gpio_num = 104,
.gpio_irq = IRQ_DM355_GPIOBNK0,
.sram_dma = 0x00010000,
.sram_len = SZ_32K,
};

View file

@ -19,6 +19,9 @@
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <linux/platform_data/spi-davinci.h>
#include <asm/mach/map.h>
@ -29,9 +32,6 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
#include <linux/platform_data/keyscan-davinci.h>
#include <linux/platform_data/spi-davinci.h>
#include <mach/gpio-davinci.h>
#include "davinci.h"
#include "clock.h"
@ -698,6 +698,32 @@ void __init dm365_init_spi0(unsigned chipselect_mask,
platform_device_register(&dm365_spi0_device);
}
static struct resource dm365_gpio_resources[] = {
{ /* registers */
.start = DAVINCI_GPIO_BASE,
.end = DAVINCI_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_DM365_GPIO0,
.end = IRQ_DM365_GPIO7,
.flags = IORESOURCE_IRQ,
},
};
static struct davinci_gpio_platform_data dm365_gpio_platform_data = {
.ngpio = 104,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
.gpio_unbanked = 8,
};
int __init dm365_gpio_register(void)
{
return davinci_gpio_register(dm365_gpio_resources,
sizeof(dm365_gpio_resources),
&dm365_gpio_platform_data);
}
static struct emac_platform_data dm365_emac_pdata = {
.ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET,
.ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET,
@ -1105,11 +1131,6 @@ static struct davinci_soc_info davinci_soc_info_dm365 = {
.intc_irq_prios = dm365_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
.timer_info = &dm365_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DAVINCI_GPIO_BASE,
.gpio_num = 104,
.gpio_irq = IRQ_DM365_GPIO0,
.gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */
.emac_pdata = &dm365_emac_pdata,
.sram_dma = 0x00010000,
.sram_len = SZ_32K,

View file

@ -13,6 +13,7 @@
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
@ -23,7 +24,6 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
#include <mach/gpio-davinci.h>
#include "davinci.h"
#include "clock.h"
@ -771,6 +771,30 @@ static struct platform_device dm644x_vpbe_dev = {
},
};
static struct resource dm644_gpio_resources[] = {
{ /* registers */
.start = DAVINCI_GPIO_BASE,
.end = DAVINCI_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_GPIOBNK0,
.end = IRQ_GPIOBNK4,
.flags = IORESOURCE_IRQ,
},
};
static struct davinci_gpio_platform_data dm644_gpio_platform_data = {
.ngpio = 71,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
};
int __init dm644x_gpio_register(void)
{
return davinci_gpio_register(dm644_gpio_resources,
sizeof(dm644_gpio_resources),
&dm644_gpio_platform_data);
}
/*----------------------------------------------------------------------*/
static struct map_desc dm644x_io_desc[] = {
@ -897,10 +921,6 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
.intc_irq_prios = dm644x_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
.timer_info = &dm644x_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DAVINCI_GPIO_BASE,
.gpio_num = 71,
.gpio_irq = IRQ_GPIOBNK0,
.emac_pdata = &dm644x_emac_pdata,
.sram_dma = 0x00008000,
.sram_len = SZ_16K,

View file

@ -14,6 +14,7 @@
#include <linux/serial_8250.h>
#include <linux/platform_device.h>
#include <linux/platform_data/edma.h>
#include <linux/platform_data/gpio-davinci.h>
#include <asm/mach/map.h>
@ -24,7 +25,6 @@
#include <mach/time.h>
#include <mach/serial.h>
#include <mach/common.h>
#include <mach/gpio-davinci.h>
#include "davinci.h"
#include "clock.h"
@ -748,6 +748,30 @@ static struct platform_device vpif_capture_dev = {
.num_resources = ARRAY_SIZE(vpif_capture_resource),
};
static struct resource dm646x_gpio_resources[] = {
{ /* registers */
.start = DAVINCI_GPIO_BASE,
.end = DAVINCI_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
{ /* interrupt */
.start = IRQ_DM646X_GPIOBNK0,
.end = IRQ_DM646X_GPIOBNK2,
.flags = IORESOURCE_IRQ,
},
};
static struct davinci_gpio_platform_data dm646x_gpio_platform_data = {
.ngpio = 43,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
};
int __init dm646x_gpio_register(void)
{
return davinci_gpio_register(dm646x_gpio_resources,
sizeof(dm646x_gpio_resources),
&dm646x_gpio_platform_data);
}
/*----------------------------------------------------------------------*/
static struct map_desc dm646x_io_desc[] = {
@ -874,10 +898,6 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
.intc_irq_prios = dm646x_default_priorities,
.intc_irq_num = DAVINCI_N_AINTC_IRQ,
.timer_info = &dm646x_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DAVINCI_GPIO_BASE,
.gpio_num = 43, /* Only 33 usable */
.gpio_irq = IRQ_DM646X_GPIOBNK0,
.emac_pdata = &dm646x_emac_pdata,
.sram_dma = 0x10010000,
.sram_len = SZ_32K,

View file

@ -97,6 +97,7 @@ int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
int da850_register_mmcsd1(struct davinci_mmc_config *config);
void da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
int da8xx_register_rtc(void);
int da8xx_register_gpio(void *pdata);
int da850_register_cpufreq(char *async_clk);
int da8xx_register_cpuidle(void);
void __iomem *da8xx_get_mem_ctlr(void);
@ -110,6 +111,8 @@ int da850_register_vpif_capture
void da8xx_restart(enum reboot_mode mode, const char *cmd);
void da8xx_rproc_reserve_cma(void);
int da8xx_register_rproc(void);
int da850_register_gpio(void);
int da830_register_gpio(void);
extern struct platform_device da8xx_serial_device[];
extern struct emac_platform_data da8xx_emac_pdata;

View file

@ -1,91 +0,0 @@
/*
* TI DaVinci GPIO Support
*
* Copyright (c) 2006 David Brownell
* Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.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; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __DAVINCI_DAVINCI_GPIO_H
#define __DAVINCI_DAVINCI_GPIO_H
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm-generic/gpio.h>
#include <mach/irqs.h>
#include <mach/common.h>
#define DAVINCI_GPIO_BASE 0x01C67000
enum davinci_gpio_type {
GPIO_TYPE_DAVINCI = 0,
GPIO_TYPE_TNETV107X,
};
/*
* basic gpio routines
*
* board-specific init should be done by arch/.../.../board-XXX.c (maybe
* initializing banks together) rather than boot loaders; kexec() won't
* go through boot loaders.
*
* the gpio clock will be turned on when gpios are used, and you may also
* need to pay attention to PINMUX registers to be sure those pins are
* used as gpios, not with other peripherals.
*
* On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
* and maybe for later updates, code may write GPIO(N). These may be
* all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
* may not support all the GPIOs in that range.
*
* GPIOs can also be on external chips, numbered after the ones built-in
* to the DaVinci chip. For now, they won't be usable as IRQ sources.
*/
#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
/* Convert GPIO signal to GPIO pin number */
#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
struct davinci_gpio_controller {
struct gpio_chip chip;
int irq_base;
spinlock_t lock;
void __iomem *regs;
void __iomem *set_data;
void __iomem *clr_data;
void __iomem *in_data;
};
/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
* with constant parameters; or in outlined code they execute at runtime.
*
* You'd access the controller directly when reading or writing more than
* one gpio value at a time, and to support wired logic where the value
* being driven by the cpu need not match the value read back.
*
* These are NOT part of the cross-platform GPIO interface
*/
static inline struct davinci_gpio_controller *
__gpio_to_controller(unsigned gpio)
{
struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
int index = gpio / 32;
if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
return NULL;
return ctlrs + index;
}
static inline u32 __gpio_mask(unsigned gpio)
{
return 1 << (gpio % 32);
}
#endif /* __DAVINCI_DAVINCI_GPIO_H */

View file

@ -1,88 +0,0 @@
/*
* TI DaVinci GPIO Support
*
* Copyright (c) 2006 David Brownell
* Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.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; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __DAVINCI_GPIO_H
#define __DAVINCI_GPIO_H
#include <asm-generic/gpio.h>
#define __ARM_GPIOLIB_COMPLEX
/* The inline versions use the static inlines in the driver header */
#include "gpio-davinci.h"
/*
* The get/set/clear functions will inline when called with constant
* parameters referencing built-in GPIOs, for low-overhead bitbanging.
*
* gpio_set_value() will inline only on traditional Davinci style controllers
* with distinct set/clear registers.
*
* Otherwise, calls with variable parameters or referencing external
* GPIOs (e.g. on GPIO expander chips) use outlined functions.
*/
static inline void gpio_set_value(unsigned gpio, int value)
{
if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) {
struct davinci_gpio_controller *ctlr;
u32 mask;
ctlr = __gpio_to_controller(gpio);
if (ctlr->set_data != ctlr->clr_data) {
mask = __gpio_mask(gpio);
if (value)
__raw_writel(mask, ctlr->set_data);
else
__raw_writel(mask, ctlr->clr_data);
return;
}
}
__gpio_set_value(gpio, value);
}
/* Returns zero or nonzero; works for gpios configured as inputs OR
* as outputs, at least for built-in GPIOs.
*
* NOTE: for built-in GPIOs, changes in reported values are synchronized
* to the GPIO clock. This is easily seen after calling gpio_set_value()
* and then immediately gpio_get_value(), where the gpio_get_value() will
* return the old value until the GPIO clock ticks and the new value gets
* latched.
*/
static inline int gpio_get_value(unsigned gpio)
{
struct davinci_gpio_controller *ctlr;
if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num)
return __gpio_get_value(gpio);
ctlr = __gpio_to_controller(gpio);
return __gpio_mask(gpio) & __raw_readl(ctlr->in_data);
}
static inline int gpio_cansleep(unsigned gpio)
{
if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num)
return 0;
else
return __gpio_cansleep(gpio);
}
static inline int irq_to_gpio(unsigned irq)
{
/* don't support the reverse mapping */
return -ENOSYS;
}
#endif /* __DAVINCI_GPIO_H */

View file

@ -15,8 +15,9 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <asm/mach/irq.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/platform_data/gpio-davinci.h>
struct davinci_gpio_regs {
u32 dir;
@ -31,13 +32,14 @@ struct davinci_gpio_regs {
u32 intstat;
};
#define BINTEN 0x8 /* GPIO Interrupt Per-Bank Enable Register */
#define chip2controller(chip) \
container_of(chip, struct davinci_gpio_controller, chip)
static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
static void __iomem *gpio_base;
static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
static struct davinci_gpio_regs __iomem *gpio2regs(unsigned gpio)
{
void __iomem *ptr;
@ -65,7 +67,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
return g;
}
static int __init davinci_gpio_irq_setup(void);
static int davinci_gpio_irq_setup(struct platform_device *pdev);
/*--------------------------------------------------------------------------*/
@ -131,33 +133,53 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
__raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
}
static int __init davinci_gpio_setup(void)
static int davinci_gpio_probe(struct platform_device *pdev)
{
int i, base;
unsigned ngpio;
struct davinci_soc_info *soc_info = &davinci_soc_info;
struct davinci_gpio_regs *regs;
struct davinci_gpio_controller *chips;
struct davinci_gpio_platform_data *pdata;
struct davinci_gpio_regs __iomem *regs;
struct device *dev = &pdev->dev;
struct resource *res;
if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
return 0;
pdata = dev->platform_data;
if (!pdata) {
dev_err(dev, "No platform data found\n");
return -EINVAL;
}
/*
* The gpio banks conceptually expose a segmented bitmap,
* and "ngpio" is one more than the largest zero-based
* bit index that's valid.
*/
ngpio = soc_info->gpio_num;
ngpio = pdata->ngpio;
if (ngpio == 0) {
pr_err("GPIO setup: how many GPIOs?\n");
dev_err(dev, "How many GPIOs?\n");
return -EINVAL;
}
if (WARN_ON(DAVINCI_N_GPIO < ngpio))
ngpio = DAVINCI_N_GPIO;
gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
if (WARN_ON(!gpio_base))
chips = devm_kzalloc(dev,
ngpio * sizeof(struct davinci_gpio_controller),
GFP_KERNEL);
if (!chips) {
dev_err(dev, "Memory allocation failed\n");
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "Invalid memory resource\n");
return -EBUSY;
}
gpio_base = devm_ioremap_resource(dev, res);
if (IS_ERR(gpio_base))
return PTR_ERR(gpio_base);
for (i = 0, base = 0; base < ngpio; i++, base += 32) {
chips[i].chip.label = "DaVinci";
@ -183,13 +205,10 @@ static int __init davinci_gpio_setup(void)
gpiochip_add(&chips[i].chip);
}
soc_info->gpio_ctlrs = chips;
soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
davinci_gpio_irq_setup();
platform_set_drvdata(pdev, chips);
davinci_gpio_irq_setup(pdev);
return 0;
}
pure_initcall(davinci_gpio_setup);
/*--------------------------------------------------------------------------*/
/*
@ -302,13 +321,14 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
{
struct davinci_soc_info *soc_info = &davinci_soc_info;
struct davinci_gpio_controller *d = chip2controller(chip);
/* NOTE: we assume for now that only irqs in the first gpio_chip
/*
* NOTE: we assume for now that only irqs in the first gpio_chip
* can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
*/
if (offset < soc_info->gpio_unbanked)
return soc_info->gpio_irq + offset;
if (offset < d->irq_base)
return d->gpio_irq + offset;
else
return -ENODEV;
}
@ -317,12 +337,11 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
{
struct davinci_gpio_controller *d;
struct davinci_gpio_regs __iomem *g;
struct davinci_soc_info *soc_info = &davinci_soc_info;
u32 mask;
d = (struct davinci_gpio_controller *)data->handler_data;
g = (struct davinci_gpio_regs __iomem *)d->regs;
mask = __gpio_mask(data->irq - soc_info->gpio_irq);
mask = __gpio_mask(data->irq - d->gpio_irq);
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
@ -343,24 +362,33 @@ static int gpio_irq_type_unbanked(struct irq_data *data, unsigned trigger)
* (dm6446) can be set appropriately for GPIOV33 pins.
*/
static int __init davinci_gpio_irq_setup(void)
static int davinci_gpio_irq_setup(struct platform_device *pdev)
{
unsigned gpio, irq, bank;
struct clk *clk;
u32 binten = 0;
unsigned ngpio, bank_irq;
struct davinci_soc_info *soc_info = &davinci_soc_info;
struct davinci_gpio_regs __iomem *g;
struct device *dev = &pdev->dev;
struct resource *res;
struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
struct davinci_gpio_platform_data *pdata = dev->platform_data;
struct davinci_gpio_regs __iomem *g;
ngpio = soc_info->gpio_num;
bank_irq = soc_info->gpio_irq;
if (bank_irq == 0) {
printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
return -EINVAL;
ngpio = pdata->ngpio;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(dev, "Invalid IRQ resource\n");
return -EBUSY;
}
clk = clk_get(NULL, "gpio");
bank_irq = res->start;
if (!bank_irq) {
dev_err(dev, "Invalid IRQ resource\n");
return -ENODEV;
}
clk = devm_clk_get(dev, "gpio");
if (IS_ERR(clk)) {
printk(KERN_ERR "Error %ld getting gpio clock?\n",
PTR_ERR(clk));
@ -368,16 +396,17 @@ static int __init davinci_gpio_irq_setup(void)
}
clk_prepare_enable(clk);
/* Arrange gpio_to_irq() support, handling either direct IRQs or
/*
* Arrange gpio_to_irq() support, handling either direct IRQs or
* banked IRQs. Having GPIOs in the first GPIO bank use direct
* IRQs, while the others use banked IRQs, would need some setup
* tweaks to recognize hardware which can do that.
*/
for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
chips[bank].chip.to_irq = gpio_to_irq_banked;
chips[bank].irq_base = soc_info->gpio_unbanked
chips[bank].irq_base = pdata->gpio_unbanked
? -EINVAL
: (soc_info->intc_irq_num + gpio);
: (pdata->intc_irq_num + gpio);
}
/*
@ -385,7 +414,7 @@ static int __init davinci_gpio_irq_setup(void)
* controller only handling trigger modes. We currently assume no
* IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
*/
if (soc_info->gpio_unbanked) {
if (pdata->gpio_unbanked) {
static struct irq_chip_type gpio_unbanked;
/* pass "bank 0" GPIO IRQs to AINTC */
@ -405,7 +434,7 @@ static int __init davinci_gpio_irq_setup(void)
__raw_writel(~0, &g->set_rising);
/* set the direct IRQs up to use that irqchip */
for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) {
irq_set_chip(irq, &gpio_unbanked.chip);
irq_set_handler_data(irq, &chips[gpio / 32]);
irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
@ -450,12 +479,31 @@ static int __init davinci_gpio_irq_setup(void)
}
done:
/* BINTEN -- per-bank interrupt enable. genirq would also let these
/*
* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set/cleared dynamically.
*/
__raw_writel(binten, gpio_base + 0x08);
__raw_writel(binten, gpio_base + BINTEN);
printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
return 0;
}
static struct platform_driver davinci_gpio_driver = {
.probe = davinci_gpio_probe,
.driver = {
.name = "davinci_gpio",
.owner = THIS_MODULE,
},
};
/**
* GPIO driver registration needs to be done before machine_init functions
* access GPIO. Hence davinci_gpio_drv_reg() is a postcore_initcall.
*/
static int __init davinci_gpio_drv_reg(void)
{
return platform_driver_register(&davinci_gpio_driver);
}
postcore_initcall(davinci_gpio_drv_reg);

View file

@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/platform_data/gpio-davinci.h>
#include <mach/common.h>
#include <mach/tnetv107x.h>

View file

@ -0,0 +1,60 @@
/*
* DaVinci GPIO Platform Related Defines
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.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.
*/
#ifndef __DAVINCI_GPIO_PLATFORM_H
#define __DAVINCI_GPIO_PLATFORM_H
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm-generic/gpio.h>
enum davinci_gpio_type {
GPIO_TYPE_TNETV107X = 0,
};
struct davinci_gpio_platform_data {
u32 ngpio;
u32 gpio_unbanked;
u32 intc_irq_num;
};
struct davinci_gpio_controller {
struct gpio_chip chip;
int irq_base;
/* Serialize access to GPIO registers */
spinlock_t lock;
void __iomem *regs;
void __iomem *set_data;
void __iomem *clr_data;
void __iomem *in_data;
int gpio_unbanked;
unsigned gpio_irq;
};
/*
* basic gpio routines
*/
#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
/* Convert GPIO signal to GPIO pin number */
#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
static inline u32 __gpio_mask(unsigned gpio)
{
return 1 << (gpio % 32);
}
#endif