Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6
* 'gpio/next' of git://git.secretlab.ca/git/linux-2.6: (61 commits) gpio/mxc/mxs: fix build error introduced by the irq_gc_ack() renaming mcp23s08: add i2c support mcp23s08: isolate spi specific parts mcp23s08: get rid of setup/teardown callbacks gpio/tegra: dt: add binding for gpio polarity mcp23s08: remove unused work queue gpio/da9052: remove a redundant assignment for gpio->da9052 gpio/mxc: add device tree probe support ARM: mxc: use ARCH_NR_GPIOS to define gpio number gpio/mxc: get rid of the uses of cpu_is_mx() gpio/mxc: add missing initialization of basic_mmio_gpio shadow variables gpio: Move mpc5200 gpio driver to drivers/gpio GPIO: DA9052 GPIO module v3 gpio/tegra: Use engineering names in DT compatible property of/gpio: Add new method for getting gpios under different property names gpio/dt: Refine GPIO device tree binding gpio/ml-ioh: fix off-by-one for displaying variable i in dev_err gpio/pca953x: Deprecate meaningless device-tree bindings gpio/pca953x: Remove dynamic platform data pointer gpio/pca953x: Fix IRQ support. ...
This commit is contained in:
commit
c7c8518498
22
Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
Normal file
22
Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
Normal file
@ -0,0 +1,22 @@
|
||||
* Freescale i.MX/MXC GPIO controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "fsl,<soc>-gpio"
|
||||
- reg : Address and length of the register set for the device
|
||||
- interrupts : Should be the port interrupt shared by all 32 pins, if
|
||||
one number. If two numbers, the first one is the interrupt shared
|
||||
by low 16 pins and the second one is for high 16 pins.
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify optional parameters (currently
|
||||
unused).
|
||||
|
||||
Example:
|
||||
|
||||
gpio0: gpio@73f84000 {
|
||||
compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
|
||||
reg = <0x73f84000 0x4000>;
|
||||
interrupts = <50 51>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
@ -4,17 +4,45 @@ Specifying GPIO information for devices
|
||||
1) gpios property
|
||||
-----------------
|
||||
|
||||
Nodes that makes use of GPIOs should define them using `gpios' property,
|
||||
format of which is: <&gpio-controller1-phandle gpio1-specifier
|
||||
&gpio-controller2-phandle gpio2-specifier
|
||||
0 /* holes are permitted, means no GPIO 3 */
|
||||
&gpio-controller4-phandle gpio4-specifier
|
||||
...>;
|
||||
Nodes that makes use of GPIOs should specify them using one or more
|
||||
properties, each containing a 'gpio-list':
|
||||
|
||||
Note that gpio-specifier length is controller dependent.
|
||||
gpio-list ::= <single-gpio> [gpio-list]
|
||||
single-gpio ::= <gpio-phandle> <gpio-specifier>
|
||||
gpio-phandle : phandle to gpio controller node
|
||||
gpio-specifier : Array of #gpio-cells specifying specific gpio
|
||||
(controller specific)
|
||||
|
||||
GPIO properties should be named "[<name>-]gpios". Exact
|
||||
meaning of each gpios property must be documented in the device tree
|
||||
binding for each device.
|
||||
|
||||
For example, the following could be used to describe gpios pins to use
|
||||
as chip select lines; with chip selects 0, 1 and 3 populated, and chip
|
||||
select 2 left empty:
|
||||
|
||||
gpio1: gpio1 {
|
||||
gpio-controller
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
gpio2: gpio2 {
|
||||
gpio-controller
|
||||
#gpio-cells = <1>;
|
||||
};
|
||||
[...]
|
||||
chipsel-gpios = <&gpio1 12 0>,
|
||||
<&gpio1 13 0>,
|
||||
<0>, /* holes are permitted, means no GPIO 2 */
|
||||
<&gpio2 2>;
|
||||
|
||||
Note that gpio-specifier length is controller dependent. In the
|
||||
above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2
|
||||
only uses one.
|
||||
|
||||
gpio-specifier may encode: bank, pin position inside the bank,
|
||||
whether pin is open-drain and whether pin is logically inverted.
|
||||
Exact meaning of each specifier cell is controller specific, and must
|
||||
be documented in the device tree binding for the device.
|
||||
|
||||
Example of the node using GPIOs:
|
||||
|
||||
@ -28,8 +56,8 @@ and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller.
|
||||
2) gpio-controller nodes
|
||||
------------------------
|
||||
|
||||
Every GPIO controller node must have #gpio-cells property defined,
|
||||
this information will be used to translate gpio-specifiers.
|
||||
Every GPIO controller node must both an empty "gpio-controller"
|
||||
property, and have #gpio-cells contain the size of the gpio-specifier.
|
||||
|
||||
Example of two SOC GPIO banks defined as gpio-controller nodes:
|
||||
|
||||
|
8
Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
Normal file
8
Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
Normal file
@ -0,0 +1,8 @@
|
||||
NVIDIA Tegra 2 GPIO controller
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra20-gpio"
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters:
|
||||
- bit 0 specifies polarity (0 for normal, 1 for inverted)
|
||||
- gpio-controller : Marks the device node as a GPIO controller.
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
obj-y := core.o clock.o dma-m2p.o gpio.o
|
||||
obj-y := core.o clock.o dma-m2p.o
|
||||
obj-m :=
|
||||
obj-n :=
|
||||
obj- :=
|
||||
|
@ -174,14 +174,10 @@ struct sys_timer ep93xx_timer = {
|
||||
/*************************************************************************
|
||||
* EP93xx IRQ handling
|
||||
*************************************************************************/
|
||||
extern void ep93xx_gpio_init_irq(void);
|
||||
|
||||
void __init ep93xx_init_irq(void)
|
||||
{
|
||||
vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
|
||||
vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
|
||||
|
||||
ep93xx_gpio_init_irq();
|
||||
}
|
||||
|
||||
|
||||
@ -240,6 +236,24 @@ unsigned int ep93xx_chip_revision(void)
|
||||
return v;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* EP93xx GPIO
|
||||
*************************************************************************/
|
||||
static struct resource ep93xx_gpio_resource[] = {
|
||||
{
|
||||
.start = EP93XX_GPIO_PHYS_BASE,
|
||||
.end = EP93XX_GPIO_PHYS_BASE + 0xcc - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device ep93xx_gpio_device = {
|
||||
.name = "gpio-ep93xx",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(ep93xx_gpio_resource),
|
||||
.resource = ep93xx_gpio_resource,
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
* EP93xx peripheral handling
|
||||
*************************************************************************/
|
||||
@ -870,14 +884,13 @@ void __init ep93xx_register_ac97(void)
|
||||
platform_device_register(&ep93xx_pcm_device);
|
||||
}
|
||||
|
||||
extern void ep93xx_gpio_init(void);
|
||||
|
||||
void __init ep93xx_init_devices(void)
|
||||
{
|
||||
/* Disallow access to MaverickCrunch initially */
|
||||
ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
|
||||
|
||||
ep93xx_gpio_init();
|
||||
/* Get the GPIO working early, other devices need it */
|
||||
platform_device_register(&ep93xx_gpio_device);
|
||||
|
||||
amba_device_register(&uart1_device, &iomem_resource);
|
||||
amba_device_register(&uart2_device, &iomem_resource);
|
||||
|
@ -98,6 +98,7 @@
|
||||
|
||||
#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
|
||||
|
||||
#define EP93XX_GPIO_PHYS_BASE EP93XX_APB_PHYS(0x00040000)
|
||||
#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
|
||||
#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
|
||||
#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
|
||||
|
@ -115,6 +115,8 @@ static struct platform_device *devices[] __initdata = {
|
||||
|
||||
static void __init apf9328_init(void)
|
||||
{
|
||||
imx1_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(apf9328_pins,
|
||||
ARRAY_SIZE(apf9328_pins),
|
||||
"APF9328");
|
||||
|
@ -490,6 +490,8 @@ static struct platform_device *devices[] __initdata = {
|
||||
*/
|
||||
static void __init armadillo5x0_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
|
||||
ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
|
||||
|
||||
|
@ -42,6 +42,8 @@ static const unsigned int bug_pins[] __initconst = {
|
||||
|
||||
static void __init bug_board_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_iomux_setup_multiple_pins(bug_pins,
|
||||
ARRAY_SIZE(bug_pins), "uart-4");
|
||||
imx31_add_imx_uart4(&uart_pdata);
|
||||
|
@ -250,6 +250,8 @@ __setup("otg_mode=", eukrea_cpuimx27_otg_mode);
|
||||
|
||||
static void __init eukrea_cpuimx27_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
|
||||
ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
|
||||
|
||||
|
@ -156,6 +156,8 @@ __setup("otg_mode=", eukrea_cpuimx35_otg_mode);
|
||||
*/
|
||||
static void __init eukrea_cpuimx35_init(void)
|
||||
{
|
||||
imx35_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
|
||||
ARRAY_SIZE(eukrea_cpuimx35_pads));
|
||||
|
||||
|
@ -125,6 +125,8 @@ __setup("otg_mode=", eukrea_cpuimx25_otg_mode);
|
||||
|
||||
static void __init eukrea_cpuimx25_init(void)
|
||||
{
|
||||
imx25_soc_init();
|
||||
|
||||
if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
|
||||
ARRAY_SIZE(eukrea_cpuimx25_pads)))
|
||||
printk(KERN_ERR "error setting cpuimx25 pads !\n");
|
||||
|
@ -231,6 +231,8 @@ static void __init visstrim_m10_board_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
imx27_soc_init();
|
||||
|
||||
ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
|
||||
ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
|
||||
if (ret)
|
||||
|
@ -50,6 +50,8 @@ static const int mx27ipcam_pins[] __initconst = {
|
||||
|
||||
static void __init mx27ipcam_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins),
|
||||
"mx27ipcam");
|
||||
|
||||
|
@ -59,6 +59,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
|
||||
|
||||
static void __init mx27lite_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
|
||||
"imx27lite");
|
||||
imx27_add_imx_uart0(&uart_pdata);
|
||||
|
@ -223,6 +223,8 @@ static int kzm_pins[] __initdata = {
|
||||
*/
|
||||
static void __init kzm_board_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_iomux_setup_multiple_pins(kzm_pins,
|
||||
ARRAY_SIZE(kzm_pins), "kzm");
|
||||
kzm_init_ext_uart();
|
||||
|
@ -115,6 +115,8 @@ static struct i2c_board_info mx1ads_i2c_devices[] = {
|
||||
*/
|
||||
static void __init mx1ads_init(void)
|
||||
{
|
||||
imx1_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mx1ads_pins,
|
||||
ARRAY_SIZE(mx1ads_pins), "mx1ads");
|
||||
|
||||
|
@ -279,6 +279,8 @@ static struct platform_device *platform_devices[] __initdata = {
|
||||
|
||||
static void __init mx21ads_board_init(void)
|
||||
{
|
||||
imx21_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
|
||||
"mx21ads");
|
||||
|
||||
|
@ -219,6 +219,8 @@ static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
|
||||
|
||||
static void __init mx25pdk_init(void)
|
||||
{
|
||||
imx25_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
|
||||
ARRAY_SIZE(mx25pdk_pads));
|
||||
|
||||
|
@ -267,6 +267,8 @@ static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
|
||||
|
||||
static void __init mx27pdk_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
|
||||
"mx27pdk");
|
||||
mx27_3ds_sdhc1_enable_level_translator();
|
||||
|
@ -288,6 +288,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
|
||||
|
||||
static void __init mx27ads_board_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
|
||||
"mx27ads");
|
||||
|
||||
|
@ -690,6 +690,8 @@ static void __init mx31_3ds_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
|
||||
"mx31_3ds");
|
||||
|
||||
|
@ -516,6 +516,8 @@ static void __init mx31ads_init_irq(void)
|
||||
|
||||
static void __init mx31ads_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_init_extuart();
|
||||
mxc_init_imx_uart();
|
||||
mxc_init_i2c();
|
||||
|
@ -243,6 +243,8 @@ core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
|
||||
|
||||
static void __init mx31lilly_board_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
switch (mx31lilly_baseboard) {
|
||||
case MX31LILLY_NOBOARD:
|
||||
break;
|
||||
|
@ -230,6 +230,8 @@ static void __init mx31lite_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
imx31_soc_init();
|
||||
|
||||
switch (mx31lite_baseboard) {
|
||||
case MX31LITE_NOBOARD:
|
||||
break;
|
||||
|
@ -507,6 +507,8 @@ core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
|
||||
*/
|
||||
static void __init mx31moboard_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
|
||||
"moboard");
|
||||
|
||||
|
@ -179,6 +179,8 @@ static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
|
||||
*/
|
||||
static void __init mx35_3ds_init(void)
|
||||
{
|
||||
imx35_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
|
||||
|
||||
imx35_add_fec(NULL);
|
||||
|
@ -233,6 +233,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
|
||||
|
||||
static void __init mxt_td60_board_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
|
||||
"MXT_TD60");
|
||||
|
||||
|
@ -357,6 +357,8 @@ static void __init pca100_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
imx27_soc_init();
|
||||
|
||||
/* SSI unit */
|
||||
mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
|
||||
MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
|
||||
|
@ -576,6 +576,8 @@ static void __init pcm037_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
|
||||
|
||||
mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
|
||||
|
@ -295,6 +295,8 @@ static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
|
||||
|
||||
static void __init pcm038_init(void)
|
||||
{
|
||||
imx27_soc_init();
|
||||
|
||||
mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
|
||||
"PCM038");
|
||||
|
||||
|
@ -356,6 +356,8 @@ static struct esdhc_platform_data sd1_pdata = {
|
||||
*/
|
||||
static void __init pcm043_init(void)
|
||||
{
|
||||
imx35_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
|
||||
|
||||
mxc_audmux_v2_configure_port(3,
|
||||
|
@ -244,6 +244,8 @@ static void __init qong_init_fpga(void)
|
||||
*/
|
||||
static void __init qong_init(void)
|
||||
{
|
||||
imx31_soc_init();
|
||||
|
||||
mxc_init_imx_uart();
|
||||
qong_init_nor_mtd();
|
||||
qong_init_fpga();
|
||||
|
@ -129,6 +129,8 @@ static struct platform_device *devices[] __initdata = {
|
||||
*/
|
||||
static void __init scb9328_init(void)
|
||||
{
|
||||
imx1_soc_init();
|
||||
|
||||
imx1_add_imx_uart0(&uart_pdata);
|
||||
|
||||
printk(KERN_INFO"Scb9328: Adding devices\n");
|
||||
|
@ -267,6 +267,8 @@ static struct platform_device *devices[] __initdata = {
|
||||
*/
|
||||
static void __init vpr200_board_init(void)
|
||||
{
|
||||
imx35_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
|
||||
|
||||
imx35_add_fec(NULL);
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include <mach/common.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/iomux-v1.h>
|
||||
|
||||
@ -44,15 +43,19 @@ void __init imx1_init_early(void)
|
||||
MX1_NUM_GPIO_PORT);
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx1_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD),
|
||||
};
|
||||
|
||||
void __init mx1_init_irq(void)
|
||||
{
|
||||
mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx1_gpio_ports, ARRAY_SIZE(imx1_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx1_soc_init(void)
|
||||
{
|
||||
mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
|
||||
MX1_GPIO_INT_PORTA, 0);
|
||||
mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256,
|
||||
MX1_GPIO_INT_PORTB, 0);
|
||||
mxc_register_gpio("imx1-gpio", 2, MX1_GPIO3_BASE_ADDR, SZ_256,
|
||||
MX1_GPIO_INT_PORTC, 0);
|
||||
mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
|
||||
MX1_GPIO_INT_PORTD, 0);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <mach/common.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/iomux-v1.h>
|
||||
|
||||
@ -70,17 +69,17 @@ void __init imx21_init_early(void)
|
||||
MX21_NUM_GPIO_PORT);
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx21_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO),
|
||||
DEFINE_IMX_GPIO_PORT(MX21, 1, 2),
|
||||
DEFINE_IMX_GPIO_PORT(MX21, 2, 3),
|
||||
DEFINE_IMX_GPIO_PORT(MX21, 3, 4),
|
||||
DEFINE_IMX_GPIO_PORT(MX21, 4, 5),
|
||||
DEFINE_IMX_GPIO_PORT(MX21, 5, 6),
|
||||
};
|
||||
|
||||
void __init mx21_init_irq(void)
|
||||
{
|
||||
mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx21_soc_init(void)
|
||||
{
|
||||
mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 1, MX21_GPIO2_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 2, MX21_GPIO3_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 3, MX21_GPIO4_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/mx25.h>
|
||||
#include <mach/iomux-v3.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
/*
|
||||
@ -57,16 +56,16 @@ void __init imx25_init_early(void)
|
||||
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx25_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4),
|
||||
};
|
||||
|
||||
void __init mx25_init_irq(void)
|
||||
{
|
||||
mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx25_gpio_ports, ARRAY_SIZE(imx25_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx25_soc_init(void)
|
||||
{
|
||||
/* i.mx25 has the i.mx31 type gpio */
|
||||
mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
|
||||
mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
|
||||
mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <mach/common.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/iomux-v1.h>
|
||||
|
||||
@ -70,17 +69,18 @@ void __init imx27_init_early(void)
|
||||
MX27_NUM_GPIO_PORT);
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx27_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO),
|
||||
DEFINE_IMX_GPIO_PORT(MX27, 1, 2),
|
||||
DEFINE_IMX_GPIO_PORT(MX27, 2, 3),
|
||||
DEFINE_IMX_GPIO_PORT(MX27, 3, 4),
|
||||
DEFINE_IMX_GPIO_PORT(MX27, 4, 5),
|
||||
DEFINE_IMX_GPIO_PORT(MX27, 5, 6),
|
||||
};
|
||||
|
||||
void __init mx27_init_irq(void)
|
||||
{
|
||||
mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx27_soc_init(void)
|
||||
{
|
||||
/* i.mx27 has the i.mx21 type gpio */
|
||||
mxc_register_gpio("imx21-gpio", 0, MX27_GPIO1_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 1, MX27_GPIO2_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 2, MX27_GPIO3_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 3, MX27_GPIO4_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <mach/common.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/iomux-v3.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
static struct map_desc mx31_io_desc[] __initdata = {
|
||||
@ -53,14 +52,14 @@ void __init imx31_init_early(void)
|
||||
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx31_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
|
||||
};
|
||||
|
||||
void __init mx31_init_irq(void)
|
||||
{
|
||||
mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx31_gpio_ports, ARRAY_SIZE(imx31_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx31_soc_init(void)
|
||||
{
|
||||
mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
|
||||
mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <mach/common.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/iomux-v3.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
static struct map_desc mx35_io_desc[] __initdata = {
|
||||
@ -50,14 +49,15 @@ void __init imx35_init_early(void)
|
||||
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx35_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
|
||||
};
|
||||
|
||||
void __init mx35_init_irq(void)
|
||||
{
|
||||
mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx35_gpio_ports, ARRAY_SIZE(imx35_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx35_soc_init(void)
|
||||
{
|
||||
/* i.mx35 has the i.mx31 type gpio */
|
||||
mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
|
||||
mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
|
||||
}
|
||||
|
@ -245,6 +245,8 @@ __setup("otg_mode=", eukrea_cpuimx51_otg_mode);
|
||||
*/
|
||||
static void __init eukrea_cpuimx51_init(void)
|
||||
{
|
||||
imx51_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,
|
||||
ARRAY_SIZE(eukrea_cpuimx51_pads));
|
||||
|
||||
|
@ -264,6 +264,8 @@ static struct platform_device *platform_devices[] __initdata = {
|
||||
|
||||
static void __init eukrea_cpuimx51sd_init(void)
|
||||
{
|
||||
imx51_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
|
||||
ARRAY_SIZE(eukrea_cpuimx51sd_pads));
|
||||
|
||||
|
@ -192,6 +192,8 @@ static const struct imxi2c_platform_data i2c_data __initconst = {
|
||||
*/
|
||||
static void __init mx50_rdp_board_init(void)
|
||||
{
|
||||
imx50_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads,
|
||||
ARRAY_SIZE(mx50_rdp_pads));
|
||||
|
||||
|
@ -135,6 +135,8 @@ static struct spi_board_info mx51_3ds_spi_nor_device[] = {
|
||||
*/
|
||||
static void __init mx51_3ds_init(void)
|
||||
{
|
||||
imx51_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads,
|
||||
ARRAY_SIZE(mx51_3ds_pads));
|
||||
|
||||
|
@ -340,6 +340,8 @@ static void __init mx51_babbage_init(void)
|
||||
iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 |
|
||||
MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP);
|
||||
|
||||
imx51_soc_init();
|
||||
|
||||
#if defined(CONFIG_CPU_FREQ_IMX)
|
||||
get_cpu_op = mx51_get_cpu_op;
|
||||
#endif
|
||||
|
@ -236,6 +236,8 @@ late_initcall(mx51_efikamx_power_init);
|
||||
|
||||
static void __init mx51_efikamx_init(void)
|
||||
{
|
||||
imx51_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
|
||||
ARRAY_SIZE(mx51efikamx_pads));
|
||||
efika_board_common_init();
|
||||
|
@ -248,6 +248,8 @@ static void __init mx51_efikasb_board_id(void)
|
||||
|
||||
static void __init efikasb_board_init(void)
|
||||
{
|
||||
imx51_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads,
|
||||
ARRAY_SIZE(mx51efikasb_pads));
|
||||
efika_board_common_init();
|
||||
|
@ -117,6 +117,8 @@ static const struct spi_imx_master mx53_evk_spi_data __initconst = {
|
||||
|
||||
static void __init mx53_evk_board_init(void)
|
||||
{
|
||||
imx53_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads,
|
||||
ARRAY_SIZE(mx53_evk_pads));
|
||||
mx53_evk_init_uart();
|
||||
|
@ -227,6 +227,8 @@ static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = {
|
||||
|
||||
static void __init mx53_loco_board_init(void)
|
||||
{
|
||||
imx53_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
|
||||
ARRAY_SIZE(mx53_loco_pads));
|
||||
imx53_add_imx_uart(0, NULL);
|
||||
|
@ -113,6 +113,8 @@ static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = {
|
||||
|
||||
static void __init mx53_smd_board_init(void)
|
||||
{
|
||||
imx53_soc_init();
|
||||
|
||||
mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads,
|
||||
ARRAY_SIZE(mx53_smd_pads));
|
||||
mx53_smd_init_uart();
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/imx-uart.h>
|
||||
#include <mach/irqs.h>
|
||||
@ -119,66 +118,3 @@ struct platform_device mxc_usbh2_device = {
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
};
|
||||
|
||||
static struct mxc_gpio_port mxc_gpio_ports[] = {
|
||||
{
|
||||
.chip.label = "gpio-0",
|
||||
.base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
|
||||
.irq = MX51_MXC_INT_GPIO1_LOW,
|
||||
.irq_high = MX51_MXC_INT_GPIO1_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START
|
||||
},
|
||||
{
|
||||
.chip.label = "gpio-1",
|
||||
.base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
|
||||
.irq = MX51_MXC_INT_GPIO2_LOW,
|
||||
.irq_high = MX51_MXC_INT_GPIO2_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
|
||||
},
|
||||
{
|
||||
.chip.label = "gpio-2",
|
||||
.base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
|
||||
.irq = MX51_MXC_INT_GPIO3_LOW,
|
||||
.irq_high = MX51_MXC_INT_GPIO3_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
|
||||
},
|
||||
{
|
||||
.chip.label = "gpio-3",
|
||||
.base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
|
||||
.irq = MX51_MXC_INT_GPIO4_LOW,
|
||||
.irq_high = MX51_MXC_INT_GPIO4_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
|
||||
},
|
||||
{
|
||||
.chip.label = "gpio-4",
|
||||
.base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
|
||||
.irq = MX53_INT_GPIO5_LOW,
|
||||
.irq_high = MX53_INT_GPIO5_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
|
||||
},
|
||||
{
|
||||
.chip.label = "gpio-5",
|
||||
.base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
|
||||
.irq = MX53_INT_GPIO6_LOW,
|
||||
.irq_high = MX53_INT_GPIO6_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
|
||||
},
|
||||
{
|
||||
.chip.label = "gpio-6",
|
||||
.base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
|
||||
.irq = MX53_INT_GPIO7_LOW,
|
||||
.irq_high = MX53_INT_GPIO7_HIGH,
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
|
||||
},
|
||||
};
|
||||
|
||||
int __init imx51_register_gpios(void)
|
||||
{
|
||||
return mxc_gpio_init(mxc_gpio_ports, 4);
|
||||
}
|
||||
|
||||
int __init imx53_register_gpios(void)
|
||||
{
|
||||
return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/common.h>
|
||||
#include <mach/iomux-v3.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
/*
|
||||
@ -56,17 +55,18 @@ void __init imx50_init_early(void)
|
||||
mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
|
||||
}
|
||||
|
||||
static struct mxc_gpio_port imx50_gpio_ports[] = {
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
|
||||
};
|
||||
|
||||
void __init mx50_init_irq(void)
|
||||
{
|
||||
tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
|
||||
mxc_gpio_init(imx50_gpio_ports, ARRAY_SIZE(imx50_gpio_ports));
|
||||
}
|
||||
|
||||
void __init imx50_soc_init(void)
|
||||
{
|
||||
/* i.mx50 has the i.mx31 type gpio */
|
||||
mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
|
||||
}
|
||||
|
@ -69,8 +69,6 @@ void __init imx53_init_early(void)
|
||||
mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
|
||||
}
|
||||
|
||||
int imx51_register_gpios(void);
|
||||
|
||||
void __init mx51_init_irq(void)
|
||||
{
|
||||
unsigned long tzic_addr;
|
||||
@ -86,11 +84,8 @@ void __init mx51_init_irq(void)
|
||||
panic("unable to map TZIC interrupt controller\n");
|
||||
|
||||
tzic_init_irq(tzic_virt);
|
||||
imx51_register_gpios();
|
||||
}
|
||||
|
||||
int imx53_register_gpios(void);
|
||||
|
||||
void __init mx53_init_irq(void)
|
||||
{
|
||||
unsigned long tzic_addr;
|
||||
@ -103,5 +98,25 @@ void __init mx53_init_irq(void)
|
||||
panic("unable to map TZIC interrupt controller\n");
|
||||
|
||||
tzic_init_irq(tzic_virt);
|
||||
imx53_register_gpios();
|
||||
}
|
||||
|
||||
void __init imx51_soc_init(void)
|
||||
{
|
||||
/* i.mx51 has the i.mx31 type gpio */
|
||||
mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
|
||||
}
|
||||
|
||||
void __init imx53_soc_init(void)
|
||||
{
|
||||
/* i.mx53 has the i.mx31 type gpio */
|
||||
mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
|
||||
mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Common support
|
||||
obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
|
||||
obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o
|
||||
|
||||
obj-$(CONFIG_MXS_OCOTP) += ocotp.o
|
||||
obj-$(CONFIG_PM) += pm.o
|
||||
|
@ -88,3 +88,14 @@ int __init mxs_add_amba_device(const struct amba_device *dev)
|
||||
|
||||
return amba_device_register(adev, &iomem_resource);
|
||||
}
|
||||
|
||||
struct device mxs_apbh_bus = {
|
||||
.init_name = "mxs_apbh",
|
||||
.parent = &platform_bus,
|
||||
};
|
||||
|
||||
static int __init mxs_device_init(void)
|
||||
{
|
||||
return device_register(&mxs_apbh_bus);
|
||||
}
|
||||
core_initcall(mxs_device_init);
|
||||
|
@ -6,4 +6,5 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
|
||||
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
|
||||
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
|
||||
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
|
||||
obj-y += platform-gpio-mxs.o
|
||||
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
|
||||
|
53
arch/arm/mach-mxs/devices/platform-gpio-mxs.c
Normal file
53
arch/arm/mach-mxs/devices/platform-gpio-mxs.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <mach/mx23.h>
|
||||
#include <mach/mx28.h>
|
||||
#include <mach/devices-common.h>
|
||||
|
||||
struct platform_device *__init mxs_add_gpio(
|
||||
int id, resource_size_t iobase, int irq)
|
||||
{
|
||||
struct resource res[] = {
|
||||
{
|
||||
.start = iobase,
|
||||
.end = iobase + SZ_8K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = irq,
|
||||
.end = irq,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
return platform_device_register_resndata(&mxs_apbh_bus,
|
||||
"gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0);
|
||||
}
|
||||
|
||||
static int __init mxs_add_mxs_gpio(void)
|
||||
{
|
||||
if (cpu_is_mx23()) {
|
||||
mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
|
||||
mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
|
||||
mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
|
||||
}
|
||||
|
||||
if (cpu_is_mx28()) {
|
||||
mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
|
||||
mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
|
||||
mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
|
||||
mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
|
||||
mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(mxs_add_mxs_gpio);
|
@ -1,331 +0,0 @@
|
||||
/*
|
||||
* MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
|
||||
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
|
||||
*
|
||||
* Based on code from Freescale,
|
||||
* Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/mx23.h>
|
||||
#include <mach/mx28.h>
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
static struct mxs_gpio_port *mxs_gpio_ports;
|
||||
static int gpio_table_size;
|
||||
|
||||
#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
|
||||
#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
|
||||
#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
|
||||
#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
|
||||
#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
|
||||
#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
|
||||
#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
|
||||
#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
|
||||
|
||||
#define GPIO_INT_FALL_EDGE 0x0
|
||||
#define GPIO_INT_LOW_LEV 0x1
|
||||
#define GPIO_INT_RISE_EDGE 0x2
|
||||
#define GPIO_INT_HIGH_LEV 0x3
|
||||
#define GPIO_INT_LEV_MASK (1 << 0)
|
||||
#define GPIO_INT_POL_MASK (1 << 1)
|
||||
|
||||
/* Note: This driver assumes 32 GPIOs are handled in one register */
|
||||
|
||||
static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
|
||||
{
|
||||
__mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id));
|
||||
}
|
||||
|
||||
static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
|
||||
int enable)
|
||||
{
|
||||
if (enable) {
|
||||
__mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id));
|
||||
__mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id));
|
||||
} else {
|
||||
__mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id));
|
||||
}
|
||||
}
|
||||
|
||||
static void mxs_gpio_ack_irq(struct irq_data *d)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
|
||||
}
|
||||
|
||||
static void mxs_gpio_mask_irq(struct irq_data *d)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
|
||||
}
|
||||
|
||||
static void mxs_gpio_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
|
||||
}
|
||||
|
||||
static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
|
||||
|
||||
static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
u32 pin_mask = 1 << (gpio & 31);
|
||||
struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
|
||||
void __iomem *pin_addr;
|
||||
int edge;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
edge = GPIO_INT_RISE_EDGE;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
edge = GPIO_INT_FALL_EDGE;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
edge = GPIO_INT_LOW_LEV;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
edge = GPIO_INT_HIGH_LEV;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* set level or edge */
|
||||
pin_addr = port->base + PINCTRL_IRQLEV(port->id);
|
||||
if (edge & GPIO_INT_LEV_MASK)
|
||||
__mxs_setl(pin_mask, pin_addr);
|
||||
else
|
||||
__mxs_clrl(pin_mask, pin_addr);
|
||||
|
||||
/* set polarity */
|
||||
pin_addr = port->base + PINCTRL_IRQPOL(port->id);
|
||||
if (edge & GPIO_INT_POL_MASK)
|
||||
__mxs_setl(pin_mask, pin_addr);
|
||||
else
|
||||
__mxs_clrl(pin_mask, pin_addr);
|
||||
|
||||
clear_gpio_irqstatus(port, gpio & 0x1f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MXS has one interrupt *per* gpio port */
|
||||
static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 irq_stat;
|
||||
struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq);
|
||||
u32 gpio_irq_no_base = port->virtual_irq_start;
|
||||
|
||||
desc->irq_data.chip->irq_ack(&desc->irq_data);
|
||||
|
||||
irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
|
||||
__raw_readl(port->base + PINCTRL_IRQEN(port->id));
|
||||
|
||||
while (irq_stat != 0) {
|
||||
int irqoffset = fls(irq_stat) - 1;
|
||||
generic_handle_irq(gpio_irq_no_base + irqoffset);
|
||||
irq_stat &= ~(1 << irqoffset);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set interrupt number "irq" in the GPIO as a wake-up source.
|
||||
* While system is running, all registered GPIO interrupts need to have
|
||||
* wake-up enabled. When system is suspended, only selected GPIO interrupts
|
||||
* need to have wake-up enabled.
|
||||
* @param irq interrupt source number
|
||||
* @param enable enable as wake-up if equal to non-zero
|
||||
* @return This function returns 0 on success.
|
||||
*/
|
||||
static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
u32 gpio_idx = gpio & 0x1f;
|
||||
struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
|
||||
|
||||
if (enable) {
|
||||
if (port->irq_high && (gpio_idx >= 16))
|
||||
enable_irq_wake(port->irq_high);
|
||||
else
|
||||
enable_irq_wake(port->irq);
|
||||
} else {
|
||||
if (port->irq_high && (gpio_idx >= 16))
|
||||
disable_irq_wake(port->irq_high);
|
||||
else
|
||||
disable_irq_wake(port->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip gpio_irq_chip = {
|
||||
.name = "mxs gpio",
|
||||
.irq_ack = mxs_gpio_ack_irq,
|
||||
.irq_mask = mxs_gpio_mask_irq,
|
||||
.irq_unmask = mxs_gpio_unmask_irq,
|
||||
.irq_set_type = mxs_gpio_set_irq_type,
|
||||
.irq_set_wake = mxs_gpio_set_wake_irq,
|
||||
};
|
||||
|
||||
static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
|
||||
int dir)
|
||||
{
|
||||
struct mxs_gpio_port *port =
|
||||
container_of(chip, struct mxs_gpio_port, chip);
|
||||
void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id);
|
||||
|
||||
if (dir)
|
||||
__mxs_setl(1 << offset, pin_addr);
|
||||
else
|
||||
__mxs_clrl(1 << offset, pin_addr);
|
||||
}
|
||||
|
||||
static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct mxs_gpio_port *port =
|
||||
container_of(chip, struct mxs_gpio_port, chip);
|
||||
|
||||
return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
|
||||
}
|
||||
|
||||
static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct mxs_gpio_port *port =
|
||||
container_of(chip, struct mxs_gpio_port, chip);
|
||||
void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id);
|
||||
|
||||
if (value)
|
||||
__mxs_setl(1 << offset, pin_addr);
|
||||
else
|
||||
__mxs_clrl(1 << offset, pin_addr);
|
||||
}
|
||||
|
||||
static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct mxs_gpio_port *port =
|
||||
container_of(chip, struct mxs_gpio_port, chip);
|
||||
|
||||
return port->virtual_irq_start + offset;
|
||||
}
|
||||
|
||||
static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
mxs_set_gpio_direction(chip, offset, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxs_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
mxs_gpio_set(chip, offset, value);
|
||||
mxs_set_gpio_direction(chip, offset, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* save for local usage */
|
||||
mxs_gpio_ports = port;
|
||||
gpio_table_size = cnt;
|
||||
|
||||
pr_info("MXS GPIO hardware\n");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
/* disable the interrupt and clear the status */
|
||||
__raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i));
|
||||
__raw_writel(0, port[i].base + PINCTRL_IRQEN(i));
|
||||
|
||||
/* clear address has to be used to clear IRQSTAT bits */
|
||||
__mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i));
|
||||
|
||||
for (j = port[i].virtual_irq_start;
|
||||
j < port[i].virtual_irq_start + 32; j++) {
|
||||
irq_set_chip_and_handler(j, &gpio_irq_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(j, IRQF_VALID);
|
||||
}
|
||||
|
||||
/* setup one handler for each entry */
|
||||
irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler);
|
||||
irq_set_handler_data(port[i].irq, &port[i]);
|
||||
|
||||
/* register gpio chip */
|
||||
port[i].chip.direction_input = mxs_gpio_direction_input;
|
||||
port[i].chip.direction_output = mxs_gpio_direction_output;
|
||||
port[i].chip.get = mxs_gpio_get;
|
||||
port[i].chip.set = mxs_gpio_set;
|
||||
port[i].chip.to_irq = mxs_gpio_to_irq;
|
||||
port[i].chip.base = i * 32;
|
||||
port[i].chip.ngpio = 32;
|
||||
|
||||
/* its a serious configuration bug when it fails */
|
||||
BUG_ON(gpiochip_add(&port[i].chip) < 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MX23_GPIO_BASE MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR)
|
||||
#define MX28_GPIO_BASE MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR)
|
||||
|
||||
#define DEFINE_MXS_GPIO_PORT(_base, _irq, _id) \
|
||||
{ \
|
||||
.chip.label = "gpio-" #_id, \
|
||||
.id = _id, \
|
||||
.irq = _irq, \
|
||||
.base = _base, \
|
||||
.virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOC_IMX23
|
||||
static struct mxs_gpio_port mx23_gpio_ports[] = {
|
||||
DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO0, 0),
|
||||
DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO1, 1),
|
||||
DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO2, 2),
|
||||
};
|
||||
|
||||
int __init mx23_register_gpios(void)
|
||||
{
|
||||
return mxs_gpio_init(mx23_gpio_ports, ARRAY_SIZE(mx23_gpio_ports));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_IMX28
|
||||
static struct mxs_gpio_port mx28_gpio_ports[] = {
|
||||
DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO0, 0),
|
||||
DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO1, 1),
|
||||
DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO2, 2),
|
||||
DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO3, 3),
|
||||
DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO4, 4),
|
||||
};
|
||||
|
||||
int __init mx28_register_gpios(void)
|
||||
{
|
||||
return mxs_gpio_init(mx28_gpio_ports, ARRAY_SIZE(mx28_gpio_ports));
|
||||
}
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
|
||||
*
|
||||
* 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.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MXS_GPIO_H__
|
||||
#define __MXS_GPIO_H__
|
||||
|
||||
struct mxs_gpio_port {
|
||||
void __iomem *base;
|
||||
int id;
|
||||
int irq;
|
||||
int irq_high;
|
||||
int virtual_irq_start;
|
||||
struct gpio_chip chip;
|
||||
};
|
||||
|
||||
int mxs_gpio_init(struct mxs_gpio_port*, int);
|
||||
|
||||
#endif /* __MXS_GPIO_H__ */
|
@ -11,6 +11,8 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/amba/bus.h>
|
||||
|
||||
extern struct device mxs_apbh_bus;
|
||||
|
||||
struct platform_device *mxs_add_platform_device_dmamask(
|
||||
const char *name, int id,
|
||||
const struct resource *res, unsigned int num_resources,
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <mach/iomux-mx28.h>
|
||||
|
||||
#include "devices-mx28.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13)
|
||||
#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
|
||||
|
@ -41,5 +41,4 @@ void __init mx23_map_io(void)
|
||||
void __init mx23_init_irq(void)
|
||||
{
|
||||
icoll_init_irq();
|
||||
mx23_register_gpios();
|
||||
}
|
||||
|
@ -41,5 +41,4 @@ void __init mx28_map_io(void)
|
||||
void __init mx28_init_irq(void)
|
||||
{
|
||||
icoll_init_irq();
|
||||
mx28_register_gpios();
|
||||
}
|
||||
|
@ -34,11 +34,22 @@ static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap15xx_mpuio_regs = {
|
||||
.revision = USHRT_MAX,
|
||||
.direction = OMAP_MPUIO_IO_CNTL,
|
||||
.datain = OMAP_MPUIO_INPUT_LATCH,
|
||||
.dataout = OMAP_MPUIO_OUTPUT,
|
||||
.irqstatus = OMAP_MPUIO_GPIO_INT,
|
||||
.irqenable = OMAP_MPUIO_GPIO_MASKIT,
|
||||
.irqenable_inv = true,
|
||||
};
|
||||
|
||||
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,
|
||||
.regs = &omap15xx_mpuio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap15xx_mpu_gpio = {
|
||||
@ -64,10 +75,21 @@ static struct __initdata resource omap15xx_gpio_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap15xx_gpio_regs = {
|
||||
.revision = USHRT_MAX,
|
||||
.direction = OMAP1510_GPIO_DIR_CONTROL,
|
||||
.datain = OMAP1510_GPIO_DATA_INPUT,
|
||||
.dataout = OMAP1510_GPIO_DATA_OUTPUT,
|
||||
.irqstatus = OMAP1510_GPIO_INT_STATUS,
|
||||
.irqenable = OMAP1510_GPIO_INT_MASK,
|
||||
.irqenable_inv = true,
|
||||
};
|
||||
|
||||
static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
|
||||
.virtual_irq_start = IH_GPIO_BASE,
|
||||
.bank_type = METHOD_GPIO_1510,
|
||||
.bank_width = 16,
|
||||
.regs = &omap15xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap15xx_gpio = {
|
||||
|
@ -37,11 +37,22 @@ static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap16xx_mpuio_regs = {
|
||||
.revision = USHRT_MAX,
|
||||
.direction = OMAP_MPUIO_IO_CNTL,
|
||||
.datain = OMAP_MPUIO_INPUT_LATCH,
|
||||
.dataout = OMAP_MPUIO_OUTPUT,
|
||||
.irqstatus = OMAP_MPUIO_GPIO_INT,
|
||||
.irqenable = OMAP_MPUIO_GPIO_MASKIT,
|
||||
.irqenable_inv = true,
|
||||
};
|
||||
|
||||
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,
|
||||
.regs = &omap16xx_mpuio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap16xx_mpu_gpio = {
|
||||
@ -67,10 +78,24 @@ static struct __initdata resource omap16xx_gpio1_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap16xx_gpio_regs = {
|
||||
.revision = OMAP1610_GPIO_REVISION,
|
||||
.direction = OMAP1610_GPIO_DIRECTION,
|
||||
.set_dataout = OMAP1610_GPIO_SET_DATAOUT,
|
||||
.clr_dataout = OMAP1610_GPIO_CLEAR_DATAOUT,
|
||||
.datain = OMAP1610_GPIO_DATAIN,
|
||||
.dataout = OMAP1610_GPIO_DATAOUT,
|
||||
.irqstatus = OMAP1610_GPIO_IRQSTATUS1,
|
||||
.irqenable = OMAP1610_GPIO_IRQENABLE1,
|
||||
.set_irqenable = OMAP1610_GPIO_SET_IRQENABLE1,
|
||||
.clr_irqenable = OMAP1610_GPIO_CLEAR_IRQENABLE1,
|
||||
};
|
||||
|
||||
static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
|
||||
.virtual_irq_start = IH_GPIO_BASE,
|
||||
.bank_type = METHOD_GPIO_1610,
|
||||
.bank_width = 16,
|
||||
.regs = &omap16xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap16xx_gpio1 = {
|
||||
@ -100,6 +125,7 @@ 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,
|
||||
.regs = &omap16xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap16xx_gpio2 = {
|
||||
@ -129,6 +155,7 @@ 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,
|
||||
.regs = &omap16xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap16xx_gpio3 = {
|
||||
@ -158,6 +185,7 @@ 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,
|
||||
.regs = &omap16xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap16xx_gpio4 = {
|
||||
|
@ -39,11 +39,22 @@ static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap7xx_mpuio_regs = {
|
||||
.revision = USHRT_MAX,
|
||||
.direction = OMAP_MPUIO_IO_CNTL / 2,
|
||||
.datain = OMAP_MPUIO_INPUT_LATCH / 2,
|
||||
.dataout = OMAP_MPUIO_OUTPUT / 2,
|
||||
.irqstatus = OMAP_MPUIO_GPIO_INT / 2,
|
||||
.irqenable = OMAP_MPUIO_GPIO_MASKIT / 2,
|
||||
.irqenable_inv = true,
|
||||
};
|
||||
|
||||
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,
|
||||
.regs = &omap7xx_mpuio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_mpu_gpio = {
|
||||
@ -69,10 +80,21 @@ static struct __initdata resource omap7xx_gpio1_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_gpio_reg_offs omap7xx_gpio_regs = {
|
||||
.revision = USHRT_MAX,
|
||||
.direction = OMAP7XX_GPIO_DIR_CONTROL,
|
||||
.datain = OMAP7XX_GPIO_DATA_INPUT,
|
||||
.dataout = OMAP7XX_GPIO_DATA_OUTPUT,
|
||||
.irqstatus = OMAP7XX_GPIO_INT_STATUS,
|
||||
.irqenable = OMAP7XX_GPIO_INT_MASK,
|
||||
.irqenable_inv = true,
|
||||
};
|
||||
|
||||
static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
|
||||
.virtual_irq_start = IH_GPIO_BASE,
|
||||
.bank_type = METHOD_GPIO_7XX,
|
||||
.bank_width = 32,
|
||||
.regs = &omap7xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_gpio1 = {
|
||||
@ -102,6 +124,7 @@ 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,
|
||||
.regs = &omap7xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_gpio2 = {
|
||||
@ -131,6 +154,7 @@ 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,
|
||||
.regs = &omap7xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_gpio3 = {
|
||||
@ -160,6 +184,7 @@ 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,
|
||||
.regs = &omap7xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_gpio4 = {
|
||||
@ -189,6 +214,7 @@ 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,
|
||||
.regs = &omap7xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_gpio5 = {
|
||||
@ -218,6 +244,7 @@ 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,
|
||||
.regs = &omap7xx_gpio_regs,
|
||||
};
|
||||
|
||||
static struct platform_device omap7xx_gpio6 = {
|
||||
|
@ -61,13 +61,45 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
|
||||
pdata->dbck_flag = dev_attr->dbck_flag;
|
||||
pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
|
||||
|
||||
pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
pr_err("gpio%d: Memory allocation failed\n", id);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
switch (oh->class->rev) {
|
||||
case 0:
|
||||
case 1:
|
||||
pdata->bank_type = METHOD_GPIO_24XX;
|
||||
pdata->regs->revision = OMAP24XX_GPIO_REVISION;
|
||||
pdata->regs->direction = OMAP24XX_GPIO_OE;
|
||||
pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
|
||||
pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
|
||||
pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
|
||||
pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
|
||||
pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
|
||||
pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
|
||||
pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
|
||||
pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
|
||||
pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
|
||||
pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
|
||||
pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
|
||||
break;
|
||||
case 2:
|
||||
pdata->bank_type = METHOD_GPIO_44XX;
|
||||
pdata->regs->revision = OMAP4_GPIO_REVISION;
|
||||
pdata->regs->direction = OMAP4_GPIO_OE;
|
||||
pdata->regs->datain = OMAP4_GPIO_DATAIN;
|
||||
pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
|
||||
pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
|
||||
pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
|
||||
pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
|
||||
pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
|
||||
pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
|
||||
pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
|
||||
pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
|
||||
pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
|
||||
pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
|
||||
break;
|
||||
default:
|
||||
WARN(1, "Invalid gpio bank_type\n");
|
||||
|
@ -4,7 +4,6 @@ obj-y += io.o
|
||||
obj-y += irq.o
|
||||
obj-y += clock.o
|
||||
obj-y += timer.o
|
||||
obj-y += gpio.o
|
||||
obj-y += pinmux.o
|
||||
obj-y += powergate.o
|
||||
obj-y += fuse.o
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o
|
||||
obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
|
||||
|
||||
# MX51 uses the TZIC interrupt controller, older platforms use AVIC
|
||||
obj-$(CONFIG_MXC_TZIC) += tzic.o
|
||||
|
@ -89,3 +89,14 @@ err:
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
struct device mxc_aips_bus = {
|
||||
.init_name = "mxc_aips",
|
||||
.parent = &platform_bus,
|
||||
};
|
||||
|
||||
static int __init mxc_device_init(void)
|
||||
{
|
||||
return device_register(&mxc_aips_bus);
|
||||
}
|
||||
core_initcall(mxc_device_init);
|
||||
|
@ -2,6 +2,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
|
||||
obj-y += platform-gpio-mxc.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
|
||||
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
|
||||
|
32
arch/arm/plat-mxc/devices/platform-gpio-mxc.c
Normal file
32
arch/arm/plat-mxc/devices/platform-gpio-mxc.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2011 Linaro Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*/
|
||||
#include <mach/devices-common.h>
|
||||
|
||||
struct platform_device *__init mxc_register_gpio(char *name, int id,
|
||||
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
|
||||
{
|
||||
struct resource res[] = {
|
||||
{
|
||||
.start = iobase,
|
||||
.end = iobase + iosize - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = irq,
|
||||
.end = irq,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.start = irq_high,
|
||||
.end = irq_high,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
return platform_device_register_resndata(&mxc_aips_bus,
|
||||
name, id, res, ARRAY_SIZE(res), NULL, 0);
|
||||
}
|
@ -1,361 +0,0 @@
|
||||
/*
|
||||
* MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
|
||||
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
|
||||
*
|
||||
* Based on code from Freescale,
|
||||
* Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm-generic/bug.h>
|
||||
|
||||
static struct mxc_gpio_port *mxc_gpio_ports;
|
||||
static int gpio_table_size;
|
||||
|
||||
#define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2())
|
||||
|
||||
#define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00)
|
||||
#define GPIO_GDIR (cpu_is_mx1_mx2() ? 0x00 : 0x04)
|
||||
#define GPIO_PSR (cpu_is_mx1_mx2() ? 0x24 : 0x08)
|
||||
#define GPIO_ICR1 (cpu_is_mx1_mx2() ? 0x28 : 0x0C)
|
||||
#define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10)
|
||||
#define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14)
|
||||
#define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
|
||||
|
||||
#define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0)
|
||||
#define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1)
|
||||
#define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2)
|
||||
#define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3)
|
||||
#define GPIO_INT_NONE 0x4
|
||||
|
||||
/* Note: This driver assumes 32 GPIOs are handled in one register */
|
||||
|
||||
static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
|
||||
{
|
||||
__raw_writel(1 << index, port->base + GPIO_ISR);
|
||||
}
|
||||
|
||||
static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
|
||||
int enable)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
l = __raw_readl(port->base + GPIO_IMR);
|
||||
l = (l & (~(1 << index))) | (!!enable << index);
|
||||
__raw_writel(l, port->base + GPIO_IMR);
|
||||
}
|
||||
|
||||
static void gpio_ack_irq(struct irq_data *d)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
_clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
|
||||
}
|
||||
|
||||
static void gpio_mask_irq(struct irq_data *d)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
|
||||
}
|
||||
|
||||
static void gpio_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
_set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
|
||||
}
|
||||
|
||||
static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
|
||||
|
||||
static int gpio_set_irq_type(struct irq_data *d, u32 type)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
|
||||
u32 bit, val;
|
||||
int edge;
|
||||
void __iomem *reg = port->base;
|
||||
|
||||
port->both_edges &= ~(1 << (gpio & 31));
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
edge = GPIO_INT_RISE_EDGE;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
edge = GPIO_INT_FALL_EDGE;
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
val = mxc_gpio_get(&port->chip, gpio & 31);
|
||||
if (val) {
|
||||
edge = GPIO_INT_LOW_LEV;
|
||||
pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
|
||||
} else {
|
||||
edge = GPIO_INT_HIGH_LEV;
|
||||
pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
|
||||
}
|
||||
port->both_edges |= 1 << (gpio & 31);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
edge = GPIO_INT_LOW_LEV;
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
edge = GPIO_INT_HIGH_LEV;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
|
||||
bit = gpio & 0xf;
|
||||
val = __raw_readl(reg) & ~(0x3 << (bit << 1));
|
||||
__raw_writel(val | (edge << (bit << 1)), reg);
|
||||
_clear_gpio_irqstatus(port, gpio & 0x1f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
|
||||
{
|
||||
void __iomem *reg = port->base;
|
||||
u32 bit, val;
|
||||
int edge;
|
||||
|
||||
reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
|
||||
bit = gpio & 0xf;
|
||||
val = __raw_readl(reg);
|
||||
edge = (val >> (bit << 1)) & 3;
|
||||
val &= ~(0x3 << (bit << 1));
|
||||
if (edge == GPIO_INT_HIGH_LEV) {
|
||||
edge = GPIO_INT_LOW_LEV;
|
||||
pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
|
||||
} else if (edge == GPIO_INT_LOW_LEV) {
|
||||
edge = GPIO_INT_HIGH_LEV;
|
||||
pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
|
||||
} else {
|
||||
pr_err("mxc: invalid configuration for GPIO %d: %x\n",
|
||||
gpio, edge);
|
||||
return;
|
||||
}
|
||||
__raw_writel(val | (edge << (bit << 1)), reg);
|
||||
}
|
||||
|
||||
/* handle 32 interrupts in one status register */
|
||||
static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
|
||||
{
|
||||
u32 gpio_irq_no_base = port->virtual_irq_start;
|
||||
|
||||
while (irq_stat != 0) {
|
||||
int irqoffset = fls(irq_stat) - 1;
|
||||
|
||||
if (port->both_edges & (1 << irqoffset))
|
||||
mxc_flip_edge(port, irqoffset);
|
||||
|
||||
generic_handle_irq(gpio_irq_no_base + irqoffset);
|
||||
|
||||
irq_stat &= ~(1 << irqoffset);
|
||||
}
|
||||
}
|
||||
|
||||
/* MX1 and MX3 has one interrupt *per* gpio port */
|
||||
static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
|
||||
{
|
||||
u32 irq_stat;
|
||||
struct mxc_gpio_port *port = irq_get_handler_data(irq);
|
||||
|
||||
irq_stat = __raw_readl(port->base + GPIO_ISR) &
|
||||
__raw_readl(port->base + GPIO_IMR);
|
||||
|
||||
mxc_gpio_irq_handler(port, irq_stat);
|
||||
}
|
||||
|
||||
/* MX2 has one interrupt *for all* gpio ports */
|
||||
static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
|
||||
{
|
||||
int i;
|
||||
u32 irq_msk, irq_stat;
|
||||
struct mxc_gpio_port *port = irq_get_handler_data(irq);
|
||||
|
||||
/* walk through all interrupt status registers */
|
||||
for (i = 0; i < gpio_table_size; i++) {
|
||||
irq_msk = __raw_readl(port[i].base + GPIO_IMR);
|
||||
if (!irq_msk)
|
||||
continue;
|
||||
|
||||
irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk;
|
||||
if (irq_stat)
|
||||
mxc_gpio_irq_handler(&port[i], irq_stat);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set interrupt number "irq" in the GPIO as a wake-up source.
|
||||
* While system is running, all registered GPIO interrupts need to have
|
||||
* wake-up enabled. When system is suspended, only selected GPIO interrupts
|
||||
* need to have wake-up enabled.
|
||||
* @param irq interrupt source number
|
||||
* @param enable enable as wake-up if equal to non-zero
|
||||
* @return This function returns 0 on success.
|
||||
*/
|
||||
static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
|
||||
{
|
||||
u32 gpio = irq_to_gpio(d->irq);
|
||||
u32 gpio_idx = gpio & 0x1F;
|
||||
struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
|
||||
|
||||
if (enable) {
|
||||
if (port->irq_high && (gpio_idx >= 16))
|
||||
enable_irq_wake(port->irq_high);
|
||||
else
|
||||
enable_irq_wake(port->irq);
|
||||
} else {
|
||||
if (port->irq_high && (gpio_idx >= 16))
|
||||
disable_irq_wake(port->irq_high);
|
||||
else
|
||||
disable_irq_wake(port->irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip gpio_irq_chip = {
|
||||
.name = "GPIO",
|
||||
.irq_ack = gpio_ack_irq,
|
||||
.irq_mask = gpio_mask_irq,
|
||||
.irq_unmask = gpio_unmask_irq,
|
||||
.irq_set_type = gpio_set_irq_type,
|
||||
.irq_set_wake = gpio_set_wake_irq,
|
||||
};
|
||||
|
||||
static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
|
||||
int dir)
|
||||
{
|
||||
struct mxc_gpio_port *port =
|
||||
container_of(chip, struct mxc_gpio_port, chip);
|
||||
u32 l;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
l = __raw_readl(port->base + GPIO_GDIR);
|
||||
if (dir)
|
||||
l |= 1 << offset;
|
||||
else
|
||||
l &= ~(1 << offset);
|
||||
__raw_writel(l, port->base + GPIO_GDIR);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct mxc_gpio_port *port =
|
||||
container_of(chip, struct mxc_gpio_port, chip);
|
||||
void __iomem *reg = port->base + GPIO_DR;
|
||||
u32 l;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
|
||||
__raw_writel(l, reg);
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
}
|
||||
|
||||
static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct mxc_gpio_port *port =
|
||||
container_of(chip, struct mxc_gpio_port, chip);
|
||||
|
||||
return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
|
||||
}
|
||||
|
||||
static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
_set_gpio_direction(chip, offset, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
mxc_gpio_set(chip, offset, value);
|
||||
_set_gpio_direction(chip, offset, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This lock class tells lockdep that GPIO irqs are in a different
|
||||
* category than their parents, so it won't report false recursion.
|
||||
*/
|
||||
static struct lock_class_key gpio_lock_class;
|
||||
|
||||
int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* save for local usage */
|
||||
mxc_gpio_ports = port;
|
||||
gpio_table_size = cnt;
|
||||
|
||||
printk(KERN_INFO "MXC GPIO hardware\n");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
/* disable the interrupt and clear the status */
|
||||
__raw_writel(0, port[i].base + GPIO_IMR);
|
||||
__raw_writel(~0, port[i].base + GPIO_ISR);
|
||||
for (j = port[i].virtual_irq_start;
|
||||
j < port[i].virtual_irq_start + 32; j++) {
|
||||
irq_set_lockdep_class(j, &gpio_lock_class);
|
||||
irq_set_chip_and_handler(j, &gpio_irq_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(j, IRQF_VALID);
|
||||
}
|
||||
|
||||
/* register gpio chip */
|
||||
port[i].chip.direction_input = mxc_gpio_direction_input;
|
||||
port[i].chip.direction_output = mxc_gpio_direction_output;
|
||||
port[i].chip.get = mxc_gpio_get;
|
||||
port[i].chip.set = mxc_gpio_set;
|
||||
port[i].chip.base = i * 32;
|
||||
port[i].chip.ngpio = 32;
|
||||
|
||||
spin_lock_init(&port[i].lock);
|
||||
|
||||
/* its a serious configuration bug when it fails */
|
||||
BUG_ON( gpiochip_add(&port[i].chip) < 0 );
|
||||
|
||||
if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) {
|
||||
/* setup one handler for each entry */
|
||||
irq_set_chained_handler(port[i].irq,
|
||||
mx3_gpio_irq_handler);
|
||||
irq_set_handler_data(port[i].irq, &port[i]);
|
||||
if (port[i].irq_high) {
|
||||
/* setup handler for GPIO 16 to 31 */
|
||||
irq_set_chained_handler(port[i].irq_high,
|
||||
mx3_gpio_irq_handler);
|
||||
irq_set_handler_data(port[i].irq_high,
|
||||
&port[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu_is_mx2()) {
|
||||
/* setup one handler for all GPIO interrupts */
|
||||
irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler);
|
||||
irq_set_handler_data(port[0].irq, port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -43,6 +43,15 @@ extern void mx35_init_irq(void);
|
||||
extern void mx50_init_irq(void);
|
||||
extern void mx51_init_irq(void);
|
||||
extern void mx53_init_irq(void);
|
||||
extern void imx1_soc_init(void);
|
||||
extern void imx21_soc_init(void);
|
||||
extern void imx25_soc_init(void);
|
||||
extern void imx27_soc_init(void);
|
||||
extern void imx31_soc_init(void);
|
||||
extern void imx35_soc_init(void);
|
||||
extern void imx50_soc_init(void);
|
||||
extern void imx51_soc_init(void);
|
||||
extern void imx53_soc_init(void);
|
||||
extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
|
||||
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
|
||||
extern int mx1_clocks_init(unsigned long fref);
|
||||
@ -55,7 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
|
||||
unsigned long ckih1, unsigned long ckih2);
|
||||
extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
|
||||
unsigned long ckih1, unsigned long ckih2);
|
||||
extern int mxc_register_gpios(void);
|
||||
extern struct platform_device *mxc_register_gpio(char *name, int id,
|
||||
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
|
||||
extern int mxc_register_device(struct platform_device *pdev, void *data);
|
||||
extern void mxc_set_cpu_type(unsigned int type);
|
||||
extern void mxc_arch_reset_init(void __iomem *);
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
extern struct device mxc_aips_bus;
|
||||
|
||||
struct platform_device *imx_add_platform_device_dmamask(
|
||||
const char *name, int id,
|
||||
const struct resource *res, unsigned int num_resources,
|
||||
|
@ -36,31 +36,4 @@
|
||||
#define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio))
|
||||
#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START)
|
||||
|
||||
struct mxc_gpio_port {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
int irq_high;
|
||||
int virtual_irq_start;
|
||||
struct gpio_chip chip;
|
||||
u32 both_edges;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
#define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high) \
|
||||
{ \
|
||||
.chip.label = "gpio-" #_id, \
|
||||
.irq = _irq, \
|
||||
.irq_high = _irq_high, \
|
||||
.base = soc ## _IO_ADDRESS( \
|
||||
soc ## _GPIO ## _hwid ## _BASE_ADDR), \
|
||||
.virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32, \
|
||||
}
|
||||
|
||||
#define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq) \
|
||||
DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0)
|
||||
#define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid) \
|
||||
DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0)
|
||||
|
||||
int mxc_gpio_init(struct mxc_gpio_port*, int);
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,8 @@
|
||||
#ifndef __ASM_ARCH_MXC_IRQS_H__
|
||||
#define __ASM_ARCH_MXC_IRQS_H__
|
||||
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
/*
|
||||
* SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
|
||||
*/
|
||||
@ -22,30 +24,13 @@
|
||||
|
||||
#define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
|
||||
|
||||
/* these are ordered by size to support multi-SoC kernels */
|
||||
#if defined CONFIG_SOC_IMX53
|
||||
#define MXC_GPIO_IRQS (32 * 7)
|
||||
#elif defined CONFIG_ARCH_MX2
|
||||
#define MXC_GPIO_IRQS (32 * 6)
|
||||
#elif defined CONFIG_SOC_IMX50
|
||||
#define MXC_GPIO_IRQS (32 * 6)
|
||||
#elif defined CONFIG_ARCH_MX1
|
||||
#define MXC_GPIO_IRQS (32 * 4)
|
||||
#elif defined CONFIG_ARCH_MX25
|
||||
#define MXC_GPIO_IRQS (32 * 4)
|
||||
#elif defined CONFIG_SOC_IMX51
|
||||
#define MXC_GPIO_IRQS (32 * 4)
|
||||
#elif defined CONFIG_ARCH_MX3
|
||||
#define MXC_GPIO_IRQS (32 * 3)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The next 16 interrupts are for board specific purposes. Since
|
||||
* the kernel can only run on one machine at a time, we can re-use
|
||||
* these. If you need more, increase MXC_BOARD_IRQS, but keep it
|
||||
* within sensible limits.
|
||||
*/
|
||||
#define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS)
|
||||
#define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + ARCH_NR_GPIOS)
|
||||
|
||||
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
|
||||
#define MXC_BOARD_IRQS 80
|
||||
|
@ -174,12 +174,32 @@ struct omap_gpio_dev_attr {
|
||||
bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
|
||||
};
|
||||
|
||||
struct omap_gpio_reg_offs {
|
||||
u16 revision;
|
||||
u16 direction;
|
||||
u16 datain;
|
||||
u16 dataout;
|
||||
u16 set_dataout;
|
||||
u16 clr_dataout;
|
||||
u16 irqstatus;
|
||||
u16 irqstatus2;
|
||||
u16 irqenable;
|
||||
u16 set_irqenable;
|
||||
u16 clr_irqenable;
|
||||
u16 debounce;
|
||||
u16 debounce_en;
|
||||
|
||||
bool irqenable_inv;
|
||||
};
|
||||
|
||||
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 */
|
||||
|
||||
struct omap_gpio_reg_offs *regs;
|
||||
};
|
||||
|
||||
/* TODO: Analyze removing gpio_bank_count usage from driver code */
|
||||
|
@ -55,14 +55,6 @@ config PPC_MPC5200_BUGFIX
|
||||
|
||||
It is safe to say 'Y' here
|
||||
|
||||
config PPC_MPC5200_GPIO
|
||||
bool "MPC5200 GPIO support"
|
||||
depends on PPC_MPC52xx
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select GENERIC_GPIO
|
||||
help
|
||||
Enable gpiolib support for mpc5200 based boards
|
||||
|
||||
config PPC_MPC5200_LPBFIFO
|
||||
tristate "MPC5200 LocalPlus bus FIFO driver"
|
||||
depends on PPC_MPC52xx
|
||||
|
@ -14,5 +14,4 @@ ifeq ($(CONFIG_PPC_LITE5200),y)
|
||||
obj-$(CONFIG_PM) += lite5200_sleep.o lite5200_pm.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o
|
||||
obj-$(CONFIG_PPC_MPC5200_LPBFIFO) += mpc52xx_lpbfifo.o
|
||||
|
@ -63,33 +63,58 @@ config GPIO_SYSFS
|
||||
Kernel drivers may also request that a particular GPIO be
|
||||
exported to userspace; this can be useful when debugging.
|
||||
|
||||
config GPIO_GENERIC
|
||||
tristate
|
||||
|
||||
# put drivers in the right section, in alphabetical order
|
||||
|
||||
config GPIO_DA9052
|
||||
tristate "Dialog DA9052 GPIO"
|
||||
depends on PMIC_DA9052
|
||||
help
|
||||
Say yes here to enable the GPIO driver for the DA9052 chip.
|
||||
|
||||
config GPIO_MAX730X
|
||||
tristate
|
||||
|
||||
comment "Memory mapped GPIO drivers:"
|
||||
|
||||
config GPIO_BASIC_MMIO_CORE
|
||||
tristate
|
||||
config GPIO_GENERIC_PLATFORM
|
||||
tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
|
||||
select GPIO_GENERIC
|
||||
help
|
||||
Provides core functionality for basic memory-mapped GPIO controllers.
|
||||
|
||||
config GPIO_BASIC_MMIO
|
||||
tristate "Basic memory-mapped GPIO controllers support"
|
||||
select GPIO_BASIC_MMIO_CORE
|
||||
help
|
||||
Say yes here to support basic memory-mapped GPIO controllers.
|
||||
Say yes here to support basic platform_device memory-mapped GPIO controllers.
|
||||
|
||||
config GPIO_IT8761E
|
||||
tristate "IT8761E GPIO support"
|
||||
help
|
||||
Say yes here to support GPIO functionality of IT8761E super I/O chip.
|
||||
|
||||
config GPIO_EP93XX
|
||||
def_bool y
|
||||
depends on ARCH_EP93XX
|
||||
select GPIO_GENERIC
|
||||
|
||||
config GPIO_EXYNOS4
|
||||
def_bool y
|
||||
depends on CPU_EXYNOS4210
|
||||
|
||||
config GPIO_MPC5200
|
||||
def_bool y
|
||||
depends on PPC_MPC52xx
|
||||
|
||||
config GPIO_MXC
|
||||
def_bool y
|
||||
depends on ARCH_MXC
|
||||
select GPIO_GENERIC
|
||||
select GENERIC_IRQ_CHIP
|
||||
|
||||
config GPIO_MXS
|
||||
def_bool y
|
||||
depends on ARCH_MXS
|
||||
select GPIO_GENERIC
|
||||
select GENERIC_IRQ_CHIP
|
||||
|
||||
config GPIO_PLAT_SAMSUNG
|
||||
def_bool y
|
||||
depends on SAMSUNG_GPIOLIB_4BIT
|
||||
@ -137,9 +162,6 @@ config GPIO_SCH
|
||||
The Intel Tunnel Creek processor has 5 GPIOs powered by the
|
||||
core power rail and 9 from suspend power supply.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called sch-gpio.
|
||||
|
||||
config GPIO_VX855
|
||||
tristate "VIA VX855/VX875 GPIO"
|
||||
depends on MFD_SUPPORT && PCI
|
||||
@ -202,9 +224,6 @@ config GPIO_PCA953X
|
||||
|
||||
16 bits: pca9535, pca9539, pca9555, tca6416
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called pca953x.
|
||||
|
||||
config GPIO_PCA953X_IRQ
|
||||
bool "Interrupt controller support for PCA953x"
|
||||
depends on GPIO_PCA953X=y
|
||||
@ -296,17 +315,12 @@ config GPIO_ADP5520
|
||||
This option enables support for on-chip GPIO found
|
||||
on Analog Devices ADP5520 PMICs.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called adp5520-gpio.
|
||||
|
||||
config GPIO_ADP5588
|
||||
tristate "ADP5588 I2C GPIO expander"
|
||||
depends on I2C
|
||||
help
|
||||
This option enables support for 18 GPIOs found
|
||||
on Analog Devices ADP5588 GPIO Expanders.
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called adp5588-gpio.
|
||||
|
||||
config GPIO_ADP5588_IRQ
|
||||
bool "Interrupt controller support for ADP5588"
|
||||
@ -398,10 +412,11 @@ config GPIO_MAX7301
|
||||
GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
|
||||
|
||||
config GPIO_MCP23S08
|
||||
tristate "Microchip MCP23Sxx I/O expander"
|
||||
depends on SPI_MASTER
|
||||
tristate "Microchip MCP23xxx I/O expander"
|
||||
depends on SPI_MASTER || I2C
|
||||
help
|
||||
SPI driver for Microchip MCP23S08/MPC23S17 I/O expanders.
|
||||
SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017
|
||||
I/O expanders.
|
||||
This provides a GPIO interface supporting inputs and outputs.
|
||||
|
||||
config GPIO_MC33880
|
||||
@ -428,9 +443,6 @@ config GPIO_UCB1400
|
||||
This enables support for the Philips UCB1400 GPIO pins.
|
||||
The UCB1400 is an AC97 audio codec.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ucb1400_gpio.
|
||||
|
||||
comment "MODULbus GPIO expanders:"
|
||||
|
||||
config GPIO_JANZ_TTL
|
||||
@ -441,7 +453,7 @@ config GPIO_JANZ_TTL
|
||||
This driver provides support for driving the pins in output
|
||||
mode only. Input mode is not supported.
|
||||
|
||||
config AB8500_GPIO
|
||||
config GPIO_AB8500
|
||||
bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
|
||||
depends on AB8500_CORE && BROKEN
|
||||
help
|
||||
|
@ -4,47 +4,56 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
|
||||
|
||||
obj-$(CONFIG_GPIOLIB) += gpiolib.o
|
||||
|
||||
obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
|
||||
obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
|
||||
obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o
|
||||
obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o
|
||||
# Device drivers. Generally keep list sorted alphabetically
|
||||
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
|
||||
|
||||
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
|
||||
obj-$(CONFIG_GPIO_AB8500) += gpio-ab8500.o
|
||||
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
|
||||
obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o
|
||||
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
|
||||
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
|
||||
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
|
||||
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
|
||||
obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
|
||||
obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
|
||||
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
|
||||
obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o
|
||||
obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
|
||||
obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
|
||||
obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o
|
||||
obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o
|
||||
obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
|
||||
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
|
||||
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
|
||||
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
|
||||
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
|
||||
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
|
||||
obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o
|
||||
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
|
||||
obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
|
||||
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
|
||||
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
|
||||
|
||||
obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
|
||||
obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
|
||||
obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
|
||||
obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
|
||||
obj-$(CONFIG_GPIO_MAX730X) += max730x.o
|
||||
obj-$(CONFIG_GPIO_MAX7300) += max7300.o
|
||||
obj-$(CONFIG_GPIO_MAX7301) += max7301.o
|
||||
obj-$(CONFIG_GPIO_MAX732X) += max732x.o
|
||||
obj-$(CONFIG_GPIO_MC33880) += mc33880.o
|
||||
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
|
||||
obj-$(CONFIG_GPIO_74X164) += 74x164.o
|
||||
obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o
|
||||
obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
|
||||
obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
|
||||
obj-$(CONFIG_GPIO_PCH) += pch_gpio.o
|
||||
obj-$(CONFIG_GPIO_PL061) += pl061.o
|
||||
obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o
|
||||
obj-$(CONFIG_GPIO_TC3589X) += tc3589x-gpio.o
|
||||
obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o
|
||||
obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o
|
||||
obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
|
||||
obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
|
||||
obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o
|
||||
obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
|
||||
obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o
|
||||
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
|
||||
obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o
|
||||
obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o
|
||||
obj-$(CONFIG_GPIO_SCH) += sch_gpio.o
|
||||
|
||||
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
|
||||
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
|
||||
obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
|
||||
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
|
||||
obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
|
||||
obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
|
||||
obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
|
||||
obj-$(CONFIG_MACH_U300) += gpio-u300.o
|
||||
obj-$(CONFIG_PLAT_NOMADIK) += gpio-nomadik.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o
|
||||
obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o
|
||||
obj-$(CONFIG_GPIO_SX150X) += sx150x.o
|
||||
obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o
|
||||
obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o
|
||||
obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += tps65910-gpio.o
|
||||
obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
|
||||
obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
|
||||
obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o
|
||||
obj-$(CONFIG_GPIO_WM831X) += gpio-wm831x.o
|
||||
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
|
||||
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
|
||||
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
|
||||
|
@ -16,9 +16,6 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define GEN_74X164_GPIO_COUNT 8
|
||||
|
||||
|
||||
struct gen_74x164_chip {
|
||||
struct spi_device *spi;
|
||||
struct gpio_chip gpio_chip;
|
||||
@ -26,9 +23,7 @@ struct gen_74x164_chip {
|
||||
u8 port_config;
|
||||
};
|
||||
|
||||
static void gen_74x164_set_value(struct gpio_chip *, unsigned, int);
|
||||
|
||||
static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc)
|
||||
static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc)
|
||||
{
|
||||
return container_of(gc, struct gen_74x164_chip, gpio_chip);
|
||||
}
|
||||
@ -39,16 +34,9 @@ static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
|
||||
&chip->port_config, sizeof(chip->port_config));
|
||||
}
|
||||
|
||||
static int gen_74x164_direction_output(struct gpio_chip *gc,
|
||||
unsigned offset, int val)
|
||||
{
|
||||
gen_74x164_set_value(gc, offset, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct gen_74x164_chip *chip = gpio_to_chip(gc);
|
||||
struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
@ -61,7 +49,7 @@ static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
|
||||
static void gen_74x164_set_value(struct gpio_chip *gc,
|
||||
unsigned offset, int val)
|
||||
{
|
||||
struct gen_74x164_chip *chip = gpio_to_chip(gc);
|
||||
struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc);
|
||||
|
||||
mutex_lock(&chip->lock);
|
||||
if (val)
|
||||
@ -73,6 +61,13 @@ static void gen_74x164_set_value(struct gpio_chip *gc,
|
||||
mutex_unlock(&chip->lock);
|
||||
}
|
||||
|
||||
static int gen_74x164_direction_output(struct gpio_chip *gc,
|
||||
unsigned offset, int val)
|
||||
{
|
||||
gen_74x164_set_value(gc, offset, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit gen_74x164_probe(struct spi_device *spi)
|
||||
{
|
||||
struct gen_74x164_chip *chip;
|
||||
@ -104,12 +99,12 @@ static int __devinit gen_74x164_probe(struct spi_device *spi)
|
||||
|
||||
chip->spi = spi;
|
||||
|
||||
chip->gpio_chip.label = GEN_74X164_DRIVER_NAME,
|
||||
chip->gpio_chip.label = spi->modalias;
|
||||
chip->gpio_chip.direction_output = gen_74x164_direction_output;
|
||||
chip->gpio_chip.get = gen_74x164_get_value;
|
||||
chip->gpio_chip.set = gen_74x164_set_value;
|
||||
chip->gpio_chip.base = pdata->base;
|
||||
chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT;
|
||||
chip->gpio_chip.ngpio = 8;
|
||||
chip->gpio_chip.can_sleep = 1;
|
||||
chip->gpio_chip.dev = &spi->dev;
|
||||
chip->gpio_chip.owner = THIS_MODULE;
|
||||
@ -157,7 +152,7 @@ static int __devexit gen_74x164_remove(struct spi_device *spi)
|
||||
|
||||
static struct spi_driver gen_74x164_driver = {
|
||||
.driver = {
|
||||
.name = GEN_74X164_DRIVER_NAME,
|
||||
.name = "74x164",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = gen_74x164_probe,
|
277
drivers/gpio/gpio-da9052.c
Normal file
277
drivers/gpio/gpio-da9052.c
Normal file
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* GPIO Driver for Dialog DA9052 PMICs.
|
||||
*
|
||||
* Copyright(c) 2011 Dialog Semiconductor Ltd.
|
||||
*
|
||||
* Author: David Dajun Chen <dchen@diasemi.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.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include <linux/mfd/da9052/da9052.h>
|
||||
#include <linux/mfd/da9052/reg.h>
|
||||
#include <linux/mfd/da9052/pdata.h>
|
||||
#include <linux/mfd/da9052/gpio.h>
|
||||
|
||||
#define DA9052_INPUT 1
|
||||
#define DA9052_OUTPUT_OPENDRAIN 2
|
||||
#define DA9052_OUTPUT_PUSHPULL 3
|
||||
|
||||
#define DA9052_SUPPLY_VDD_IO1 0
|
||||
|
||||
#define DA9052_DEBOUNCING_OFF 0
|
||||
#define DA9052_DEBOUNCING_ON 1
|
||||
|
||||
#define DA9052_OUTPUT_LOWLEVEL 0
|
||||
|
||||
#define DA9052_ACTIVE_LOW 0
|
||||
#define DA9052_ACTIVE_HIGH 1
|
||||
|
||||
#define DA9052_GPIO_MAX_PORTS_PER_REGISTER 8
|
||||
#define DA9052_GPIO_SHIFT_COUNT(no) (no%8)
|
||||
#define DA9052_GPIO_MASK_UPPER_NIBBLE 0xF0
|
||||
#define DA9052_GPIO_MASK_LOWER_NIBBLE 0x0F
|
||||
#define DA9052_GPIO_NIBBLE_SHIFT 4
|
||||
|
||||
struct da9052_gpio {
|
||||
struct da9052 *da9052;
|
||||
struct gpio_chip gp;
|
||||
};
|
||||
|
||||
static inline struct da9052_gpio *to_da9052_gpio(struct gpio_chip *chip)
|
||||
{
|
||||
return container_of(chip, struct da9052_gpio, gp);
|
||||
}
|
||||
|
||||
static unsigned char da9052_gpio_port_odd(unsigned offset)
|
||||
{
|
||||
return offset % 2;
|
||||
}
|
||||
|
||||
static int da9052_gpio_get(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct da9052_gpio *gpio = to_da9052_gpio(gc);
|
||||
int da9052_port_direction = 0;
|
||||
int ret;
|
||||
|
||||
ret = da9052_reg_read(gpio->da9052,
|
||||
DA9052_GPIO_0_1_REG + (offset >> 1));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (da9052_gpio_port_odd(offset)) {
|
||||
da9052_port_direction = ret & DA9052_GPIO_ODD_PORT_PIN;
|
||||
da9052_port_direction >>= 4;
|
||||
} else {
|
||||
da9052_port_direction = ret & DA9052_GPIO_EVEN_PORT_PIN;
|
||||
}
|
||||
|
||||
switch (da9052_port_direction) {
|
||||
case DA9052_INPUT:
|
||||
if (offset < DA9052_GPIO_MAX_PORTS_PER_REGISTER)
|
||||
ret = da9052_reg_read(gpio->da9052,
|
||||
DA9052_STATUS_C_REG);
|
||||
else
|
||||
ret = da9052_reg_read(gpio->da9052,
|
||||
DA9052_STATUS_D_REG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret & (1 << DA9052_GPIO_SHIFT_COUNT(offset)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
case DA9052_OUTPUT_PUSHPULL:
|
||||
if (da9052_gpio_port_odd(offset))
|
||||
return ret & DA9052_GPIO_ODD_PORT_MODE;
|
||||
else
|
||||
return ret & DA9052_GPIO_EVEN_PORT_MODE;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void da9052_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
|
||||
{
|
||||
struct da9052_gpio *gpio = to_da9052_gpio(gc);
|
||||
unsigned char register_value = 0;
|
||||
int ret;
|
||||
|
||||
if (da9052_gpio_port_odd(offset)) {
|
||||
if (value) {
|
||||
register_value = DA9052_GPIO_ODD_PORT_MODE;
|
||||
ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
|
||||
DA9052_GPIO_0_1_REG,
|
||||
DA9052_GPIO_ODD_PORT_MODE,
|
||||
register_value);
|
||||
if (ret != 0)
|
||||
dev_err(gpio->da9052->dev,
|
||||
"Failed to updated gpio odd reg,%d",
|
||||
ret);
|
||||
}
|
||||
} else {
|
||||
if (value) {
|
||||
register_value = DA9052_GPIO_EVEN_PORT_MODE;
|
||||
ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
|
||||
DA9052_GPIO_0_1_REG,
|
||||
DA9052_GPIO_EVEN_PORT_MODE,
|
||||
register_value);
|
||||
if (ret != 0)
|
||||
dev_err(gpio->da9052->dev,
|
||||
"Failed to updated gpio even reg,%d",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int da9052_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct da9052_gpio *gpio = to_da9052_gpio(gc);
|
||||
unsigned char register_value;
|
||||
int ret;
|
||||
|
||||
/* Format: function - 2 bits type - 1 bit mode - 1 bit */
|
||||
register_value = DA9052_INPUT | DA9052_ACTIVE_LOW << 2 |
|
||||
DA9052_DEBOUNCING_ON << 3;
|
||||
|
||||
if (da9052_gpio_port_odd(offset))
|
||||
ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
|
||||
DA9052_GPIO_0_1_REG,
|
||||
DA9052_GPIO_MASK_UPPER_NIBBLE,
|
||||
(register_value <<
|
||||
DA9052_GPIO_NIBBLE_SHIFT));
|
||||
else
|
||||
ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
|
||||
DA9052_GPIO_0_1_REG,
|
||||
DA9052_GPIO_MASK_LOWER_NIBBLE,
|
||||
register_value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_gpio_direction_output(struct gpio_chip *gc,
|
||||
unsigned offset, int value)
|
||||
{
|
||||
struct da9052_gpio *gpio = to_da9052_gpio(gc);
|
||||
unsigned char register_value;
|
||||
int ret;
|
||||
|
||||
/* Format: Function - 2 bits Type - 1 bit Mode - 1 bit */
|
||||
register_value = DA9052_OUTPUT_PUSHPULL | DA9052_SUPPLY_VDD_IO1 << 2 |
|
||||
value << 3;
|
||||
|
||||
if (da9052_gpio_port_odd(offset))
|
||||
ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
|
||||
DA9052_GPIO_0_1_REG,
|
||||
DA9052_GPIO_MASK_UPPER_NIBBLE,
|
||||
(register_value <<
|
||||
DA9052_GPIO_NIBBLE_SHIFT));
|
||||
else
|
||||
ret = da9052_reg_update(gpio->da9052, (offset >> 1) +
|
||||
DA9052_GPIO_0_1_REG,
|
||||
DA9052_GPIO_MASK_LOWER_NIBBLE,
|
||||
register_value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset)
|
||||
{
|
||||
struct da9052_gpio *gpio = to_da9052_gpio(gc);
|
||||
struct da9052 *da9052 = gpio->da9052;
|
||||
|
||||
return da9052->irq_base + DA9052_IRQ_GPI0 + offset;
|
||||
}
|
||||
|
||||
static struct gpio_chip reference_gp __devinitdata = {
|
||||
.label = "da9052-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
.get = da9052_gpio_get,
|
||||
.set = da9052_gpio_set,
|
||||
.direction_input = da9052_gpio_direction_input,
|
||||
.direction_output = da9052_gpio_direction_output,
|
||||
.to_irq = da9052_gpio_to_irq,
|
||||
.can_sleep = 1;
|
||||
.ngpio = 16;
|
||||
.base = -1;
|
||||
};
|
||||
|
||||
static int __devinit da9052_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct da9052_gpio *gpio;
|
||||
struct da9052_pdata *pdata;
|
||||
int ret;
|
||||
|
||||
gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
|
||||
if (gpio == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
gpio->da9052 = dev_get_drvdata(pdev->dev.parent);
|
||||
pdata = gpio->da9052->dev->platform_data;
|
||||
|
||||
gpio->gp = reference_gp;
|
||||
if (pdata && pdata->gpio_base)
|
||||
gpio->gp.base = pdata->gpio_base;
|
||||
|
||||
ret = gpiochip_add(&gpio->gp);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
|
||||
goto err_mem;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, gpio);
|
||||
|
||||
return 0;
|
||||
|
||||
err_mem:
|
||||
kfree(gpio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit da9052_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct da9052_gpio *gpio = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_remove(&gpio->gp);
|
||||
if (ret == 0)
|
||||
kfree(gpio);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver da9052_gpio_driver = {
|
||||
.probe = da9052_gpio_probe,
|
||||
.remove = __devexit_p(da9052_gpio_remove),
|
||||
.driver = {
|
||||
.name = "da9052-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init da9052_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&da9052_gpio_driver);
|
||||
}
|
||||
module_init(da9052_gpio_init);
|
||||
|
||||
static void __exit da9052_gpio_exit(void)
|
||||
{
|
||||
return platform_driver_unregister(&da9052_gpio_driver);
|
||||
}
|
||||
module_exit(da9052_gpio_exit);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_DESCRIPTION("DA9052 GPIO Device Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:da9052-gpio");
|
@ -1,9 +1,8 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-ep93xx/gpio.c
|
||||
*
|
||||
* Generic EP93xx GPIO handling
|
||||
*
|
||||
* Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com>
|
||||
* Copyright (c) 2011 H Hartley Sweeten <hsweeten@visionengravers.com>
|
||||
*
|
||||
* Based on code originally from:
|
||||
* linux/arch/arm/mach-ep93xx/core.c
|
||||
@ -13,17 +12,23 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/basic_mmio_gpio.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
struct ep93xx_gpio {
|
||||
void __iomem *mmio_base;
|
||||
struct bgpio_chip bgc[8];
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
* Interrupt handling for EP93xx on-chip GPIOs
|
||||
*************************************************************************/
|
||||
@ -225,7 +230,7 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
|
||||
.irq_set_type = ep93xx_gpio_irq_type,
|
||||
};
|
||||
|
||||
void __init ep93xx_gpio_init_irq(void)
|
||||
static void ep93xx_gpio_init_irq(void)
|
||||
{
|
||||
int gpio_irq;
|
||||
|
||||
@ -260,87 +265,33 @@ void __init ep93xx_gpio_init_irq(void)
|
||||
/*************************************************************************
|
||||
* gpiolib interface for EP93xx on-chip GPIOs
|
||||
*************************************************************************/
|
||||
struct ep93xx_gpio_chip {
|
||||
struct gpio_chip chip;
|
||||
|
||||
void __iomem *data_reg;
|
||||
void __iomem *data_dir_reg;
|
||||
struct ep93xx_gpio_bank {
|
||||
const char *label;
|
||||
int data;
|
||||
int dir;
|
||||
int base;
|
||||
bool has_debounce;
|
||||
};
|
||||
|
||||
#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
|
||||
|
||||
static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
|
||||
unsigned long flags;
|
||||
u8 v;
|
||||
|
||||
local_irq_save(flags);
|
||||
v = __raw_readb(ep93xx_chip->data_dir_reg);
|
||||
v &= ~(1 << offset);
|
||||
__raw_writeb(v, ep93xx_chip->data_dir_reg);
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _debounce) \
|
||||
{ \
|
||||
.label = _label, \
|
||||
.data = _data, \
|
||||
.dir = _dir, \
|
||||
.base = _base, \
|
||||
.has_debounce = _debounce, \
|
||||
}
|
||||
|
||||
static int ep93xx_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned offset, int val)
|
||||
{
|
||||
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
|
||||
unsigned long flags;
|
||||
int line;
|
||||
u8 v;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Set the value */
|
||||
v = __raw_readb(ep93xx_chip->data_reg);
|
||||
if (val)
|
||||
v |= (1 << offset);
|
||||
else
|
||||
v &= ~(1 << offset);
|
||||
__raw_writeb(v, ep93xx_chip->data_reg);
|
||||
|
||||
/* Drive as an output */
|
||||
line = chip->base + offset;
|
||||
if (line <= EP93XX_GPIO_LINE_MAX_IRQ) {
|
||||
/* Ports A/B/F */
|
||||
ep93xx_gpio_int_mask(line);
|
||||
ep93xx_gpio_update_int_params(line >> 3);
|
||||
}
|
||||
|
||||
v = __raw_readb(ep93xx_chip->data_dir_reg);
|
||||
v |= (1 << offset);
|
||||
__raw_writeb(v, ep93xx_chip->data_dir_reg);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ep93xx_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
|
||||
|
||||
return !!(__raw_readb(ep93xx_chip->data_reg) & (1 << offset));
|
||||
}
|
||||
|
||||
static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
|
||||
{
|
||||
struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
|
||||
unsigned long flags;
|
||||
u8 v;
|
||||
|
||||
local_irq_save(flags);
|
||||
v = __raw_readb(ep93xx_chip->data_reg);
|
||||
if (val)
|
||||
v |= (1 << offset);
|
||||
else
|
||||
v &= ~(1 << offset);
|
||||
__raw_writeb(v, ep93xx_chip->data_reg);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
|
||||
EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true),
|
||||
EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true),
|
||||
EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false),
|
||||
EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false),
|
||||
EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false),
|
||||
EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true),
|
||||
EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false),
|
||||
EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
|
||||
};
|
||||
|
||||
static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
|
||||
unsigned offset, unsigned debounce)
|
||||
@ -356,37 +307,57 @@ static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \
|
||||
{ \
|
||||
.chip = { \
|
||||
.label = name, \
|
||||
.direction_input = ep93xx_gpio_direction_input, \
|
||||
.direction_output = ep93xx_gpio_direction_output, \
|
||||
.get = ep93xx_gpio_get, \
|
||||
.set = ep93xx_gpio_set, \
|
||||
.base = base_gpio, \
|
||||
.ngpio = 8, \
|
||||
}, \
|
||||
.data_reg = EP93XX_GPIO_REG(dr), \
|
||||
.data_dir_reg = EP93XX_GPIO_REG(ddr), \
|
||||
static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev,
|
||||
void __iomem *mmio_base, struct ep93xx_gpio_bank *bank)
|
||||
{
|
||||
void __iomem *data = mmio_base + bank->data;
|
||||
void __iomem *dir = mmio_base + bank->dir;
|
||||
int err;
|
||||
|
||||
err = bgpio_init(bgc, dev, 1, data, NULL, NULL, dir, NULL, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
bgc->gc.label = bank->label;
|
||||
bgc->gc.base = bank->base;
|
||||
|
||||
if (bank->has_debounce)
|
||||
bgc->gc.set_debounce = ep93xx_gpio_set_debounce;
|
||||
|
||||
return gpiochip_add(&bgc->gc);
|
||||
}
|
||||
|
||||
static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = {
|
||||
EP93XX_GPIO_BANK("A", 0x00, 0x10, 0),
|
||||
EP93XX_GPIO_BANK("B", 0x04, 0x14, 8),
|
||||
EP93XX_GPIO_BANK("C", 0x08, 0x18, 40),
|
||||
EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24),
|
||||
EP93XX_GPIO_BANK("E", 0x20, 0x24, 32),
|
||||
EP93XX_GPIO_BANK("F", 0x30, 0x34, 16),
|
||||
EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48),
|
||||
EP93XX_GPIO_BANK("H", 0x40, 0x44, 56),
|
||||
};
|
||||
|
||||
void __init ep93xx_gpio_init(void)
|
||||
static int __devinit ep93xx_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ep93xx_gpio *ep93xx_gpio;
|
||||
struct resource *res;
|
||||
void __iomem *mmio;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
/* Set Ports C, D, E, G, and H for GPIO use */
|
||||
ep93xx_gpio = kzalloc(sizeof(*ep93xx_gpio), GFP_KERNEL);
|
||||
if (!ep93xx_gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
ret = -ENXIO;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
|
||||
ret = -EBUSY;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
mmio = ioremap(res->start, resource_size(res));
|
||||
if (!mmio) {
|
||||
ret = -ENXIO;
|
||||
goto exit_release;
|
||||
}
|
||||
ep93xx_gpio->mmio_base = mmio;
|
||||
|
||||
/* Default all ports to GPIO */
|
||||
ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
|
||||
EP93XX_SYSCON_DEVCFG_GONK |
|
||||
EP93XX_SYSCON_DEVCFG_EONIDE |
|
||||
@ -394,17 +365,41 @@ void __init ep93xx_gpio_init(void)
|
||||
EP93XX_SYSCON_DEVCFG_HONIDE);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
|
||||
struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip;
|
||||
struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i];
|
||||
struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
|
||||
|
||||
/*
|
||||
* Ports A, B, and F support input debouncing when
|
||||
* used as interrupts.
|
||||
*/
|
||||
if (!strcmp(chip->label, "A") ||
|
||||
!strcmp(chip->label, "B") ||
|
||||
!strcmp(chip->label, "F"))
|
||||
chip->set_debounce = ep93xx_gpio_set_debounce;
|
||||
if (ep93xx_gpio_add_bank(bgc, &pdev->dev, mmio, bank))
|
||||
dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
|
||||
bank->label);
|
||||
}
|
||||
|
||||
gpiochip_add(chip);
|
||||
ep93xx_gpio_init_irq();
|
||||
|
||||
return 0;
|
||||
|
||||
exit_release:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
exit_free:
|
||||
kfree(ep93xx_gpio);
|
||||
dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver ep93xx_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "gpio-ep93xx",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ep93xx_gpio_probe,
|
||||
};
|
||||
|
||||
static int __init ep93xx_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&ep93xx_gpio_driver);
|
||||
}
|
||||
postcore_initcall(ep93xx_gpio_init);
|
||||
|
||||
MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com> "
|
||||
"H Hartley Sweeten <hsweeten@visionengravers.com>");
|
||||
MODULE_DESCRIPTION("EP93XX GPIO driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -1,10 +1,9 @@
|
||||
/* linux/arch/arm/mach-exynos4/gpiolib.c
|
||||
/*
|
||||
* EXYNOS4 - GPIOlib support
|
||||
*
|
||||
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* EXYNOS4 - GPIOlib support
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Driver for basic memory-mapped GPIO controllers.
|
||||
* Generic driver for memory-mapped GPIO controllers.
|
||||
*
|
||||
* Copyright 2008 MontaVista Software, Inc.
|
||||
* Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com>
|
||||
@ -404,7 +404,7 @@ int __devinit bgpio_init(struct bgpio_chip *bgc,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bgpio_init);
|
||||
|
||||
#ifdef CONFIG_GPIO_BASIC_MMIO
|
||||
#ifdef CONFIG_GPIO_GENERIC_PLATFORM
|
||||
|
||||
static void __iomem *bgpio_map(struct platform_device *pdev,
|
||||
const char *name,
|
||||
@ -541,7 +541,7 @@ static void __exit bgpio_platform_exit(void)
|
||||
}
|
||||
module_exit(bgpio_platform_exit);
|
||||
|
||||
#endif /* CONFIG_GPIO_BASIC_MMIO */
|
||||
#endif /* CONFIG_GPIO_GENERIC_PLATFORM */
|
||||
|
||||
MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
|
||||
MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* it8761_gpio.c - GPIO interface for IT8761E Super I/O chip
|
||||
* GPIO interface for IT8761E Super I/O chip
|
||||
*
|
||||
* Author: Denis Turischev <denis@compulab.co.il>
|
||||
*
|
@ -1,4 +1,6 @@
|
||||
/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
|
||||
/*
|
||||
* Moorestown platform Langwell chip GPIO driver
|
||||
*
|
||||
* Copyright (c) 2008 - 2009, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* drivers/gpio/max7300.c
|
||||
*
|
||||
* Copyright (C) 2009 Wolfram Sang, Pengutronix
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* drivers/gpio/max7301.c
|
||||
*
|
||||
* Copyright (C) 2006 Juergen Beisert, Pengutronix
|
||||
* Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
|
||||
* Copyright (C) 2009 Wolfram Sang, Pengutronix
|
@ -1,6 +1,4 @@
|
||||
/**
|
||||
* drivers/gpio/max7301.c
|
||||
*
|
||||
* Copyright (C) 2006 Juergen Beisert, Pengutronix
|
||||
* Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
|
||||
* Copyright (C) 2009 Wolfram Sang, Pengutronix
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* max732x.c - I2C Port Expander with 8/16 I/O
|
||||
* MAX732x I2C Port Expander with 8/16 I/O
|
||||
*
|
||||
* Copyright (C) 2007 Marvell International Ltd.
|
||||
* Copyright (C) 2008 Jack Ren <jack.ren@marvell.com>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user