diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2019-06-01 00:37:56 +0200 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2019-06-12 13:20:23 +0200 |
commit | fdb7e884ad617f8aa69abdd7f39e3fdac85e081e (patch) | |
tree | 8040de47cccdb9797aa15272df7d0afde3431307 /arch/arm | |
parent | ed7357c9f9b6a560992446c37260be25e514c4ab (diff) | |
download | linux-fdb7e884ad617f8aa69abdd7f39e3fdac85e081e.tar.bz2 |
i2c: iop: Use GPIO descriptors
The IOP3xx has some elaborate code to directly slam the
GPIO lines multiplexed with I2C down low before enablement,
apparently a workaround for a hardware bug found in the
early chips.
After consulting the developer documentation for IOP80321
and IOP80331 I can clearly see that this may be useful for
IOP80321 family (mach-iop32x) but it is highly dubious for
any 80331 series or later chip: in these chips the lines
are not multiplexed for UARTs.
We convert the code to pass optional GPIO descriptors
and register these only on the 80321-based boards where
it makes sense, optionally obtain them in the driver and
use the gpiod_set_raw_value() to ascertain the line gets
driven low when needed.
The GPIO driver does not give the GPIO chip a reasonable
label so the patch also adds that so that these machine
descriptor tables can be used.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/hardware/iop3xx.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/em7210.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/glantank.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/iq31244.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/iq80321.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/n2100.c | 2 | ||||
-rw-r--r-- | arch/arm/plat-iop/i2c.c | 24 |
7 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 2594a95ff19a..a15d08160e8f 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h @@ -305,6 +305,8 @@ extern struct platform_device iop3xx_dma_1_channel; extern struct platform_device iop3xx_aau_channel; extern struct platform_device iop3xx_i2c0_device; extern struct platform_device iop3xx_i2c1_device; +extern struct gpiod_lookup_table iop3xx_i2c0_gpio_lookup; +extern struct gpiod_lookup_table iop3xx_i2c1_gpio_lookup; #endif diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c index 77e1ff057303..d2bcbac6b7f2 100644 --- a/arch/arm/mach-iop32x/em7210.c +++ b/arch/arm/mach-iop32x/em7210.c @@ -24,6 +24,7 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <linux/io.h> #include <linux/irq.h> @@ -211,6 +212,8 @@ static void __init em7210_init_machine(void) { register_iop32x_gpio(); platform_device_register(&em7210_serial_device); + gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); + gpiod_add_lookup_table(&iop3xx_i2c1_gpio_lookup); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&em7210_flash_device); diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index 547b2342d61a..4c4995007d17 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -25,6 +25,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach/arch.h> @@ -189,6 +190,8 @@ static void glantank_power_off(void) static void __init glantank_init_machine(void) { register_iop32x_gpio(); + gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); + gpiod_add_lookup_table(&iop3xx_i2c1_gpio_lookup); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&glantank_flash_device); diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index 0e1392b20d18..56a64ffd3824 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -26,6 +26,7 @@ #include <linux/mtd/physmap.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <asm/cputype.h> #include <asm/irq.h> @@ -285,6 +286,8 @@ void ep80219_power_off(void) static void __init iq31244_init_machine(void) { register_iop32x_gpio(); + gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); + gpiod_add_lookup_table(&iop3xx_i2c1_gpio_lookup); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&iq31244_flash_device); diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 66782ff1f46a..02abbf9efd54 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -23,6 +23,7 @@ #include <linux/mtd/physmap.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach/arch.h> @@ -172,6 +173,8 @@ static struct platform_device iq80321_serial_device = { static void __init iq80321_init_machine(void) { register_iop32x_gpio(); + gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); + gpiod_add_lookup_table(&iop3xx_i2c1_gpio_lookup); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&iop3xx_i2c1_device); platform_device_register(&iq80321_flash_device); diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 23e8c93515d4..c780b6e82ad9 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -31,6 +31,7 @@ #include <linux/reboot.h> #include <linux/io.h> #include <linux/gpio.h> +#include <linux/gpio/machine.h> #include <mach/hardware.h> #include <asm/irq.h> #include <asm/mach/arch.h> @@ -345,6 +346,7 @@ device_initcall(n2100_request_gpios); static void __init n2100_init_machine(void) { register_iop32x_gpio(); + gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); platform_device_register(&iop3xx_i2c0_device); platform_device_register(&n2100_flash_device); platform_device_register(&n2100_serial_device); diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/plat-iop/i2c.c index 88215ad031a2..bac20f7f5f8a 100644 --- a/arch/arm/plat-iop/i2c.c +++ b/arch/arm/plat-iop/i2c.c @@ -19,6 +19,7 @@ #include <linux/tty.h> #include <linux/serial_core.h> #include <linux/io.h> +#include <linux/gpio/machine.h> #include <asm/pgtable.h> #include <asm/page.h> #include <asm/mach/map.h> @@ -37,6 +38,29 @@ #define IRQ_IOP3XX_I2C_1 IRQ_IOP33X_I2C_1 #endif +/* + * Each of the I2C busses have corresponding GPIO lines, and the driver + * need to access these directly to drive the bus low at times. + */ + +struct gpiod_lookup_table iop3xx_i2c0_gpio_lookup = { + .dev_id = "IOP3xx-I2C.0", + .table = { + GPIO_LOOKUP("gpio-iop", 7, "scl", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-iop", 6, "sda", GPIO_ACTIVE_HIGH), + { } + }, +}; + +struct gpiod_lookup_table iop3xx_i2c1_gpio_lookup = { + .dev_id = "IOP3xx-I2C.1", + .table = { + GPIO_LOOKUP("gpio-iop", 5, "scl", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-iop", 4, "sda", GPIO_ACTIVE_HIGH), + { } + }, +}; + static struct resource iop3xx_i2c0_resources[] = { [0] = { .start = 0xfffff680, |