diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2014-09-05 07:32:54 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-09-05 07:32:54 +0200 |
commit | d12cc92639690db63a95cc76542121a6da0995c2 (patch) | |
tree | 92764013b712c13d76b86803ea992915f9edcf6c | |
parent | 1202e6e83cb238bcfc15ed09272f62b0643cfc4f (diff) | |
parent | 71ff9bfebd7fe99c1720aa829e43fd9270a6b6f4 (diff) | |
download | barebox-d12cc92639690db63a95cc76542121a6da0995c2.tar.gz barebox-d12cc92639690db63a95cc76542121a6da0995c2.tar.xz |
Merge branch 'for-next/at91'
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9260ek/init.c | 2 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9261ek/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9263ek/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9m10g45ek/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9m10ihd/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9n12ek/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/at91sam9x5ek/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/sama5d3_xplained/init.c | 1 | ||||
-rw-r--r-- | arch/arm/boards/sama5d3xek/init.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/gpio.h | 148 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/board.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/gpio.h | 149 | ||||
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 115 | ||||
-rw-r--r-- | drivers/pinctrl/Kconfig | 6 | ||||
-rw-r--r-- | drivers/pinctrl/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-at91.c (renamed from arch/arm/mach-at91/gpio.c) | 455 |
18 files changed, 515 insertions, 373 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9f34e1089b..13f0bd41be 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -37,6 +37,7 @@ config ARCH_AT91 select HAS_DEBUG_LL select HAVE_MACH_ARM_HEAD select HAVE_CLK + select PINCTRL_AT91 config ARCH_BCM2835 bool "Broadcom BCM2835 boards" diff --git a/arch/arm/boards/at91sam9260ek/init.c b/arch/arm/boards/at91sam9260ek/init.c index 1298dde672..bc0c411d3a 100644 --- a/arch/arm/boards/at91sam9260ek/init.c +++ b/arch/arm/boards/at91sam9260ek/init.c @@ -18,6 +18,7 @@ #include <asm/armlinux.h> #include <generated/mach-types.h> #include <nand.h> +#include <linux/mtd/nand.h> #include <sizes.h> #include <mach/board.h> #include <mach/at91sam9_smc.h> @@ -51,6 +52,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, .on_flash_bbt = 1, }; diff --git a/arch/arm/boards/at91sam9261ek/init.c b/arch/arm/boards/at91sam9261ek/init.c index 9ebc16a6b1..7b8ce98d5d 100644 --- a/arch/arm/boards/at91sam9261ek/init.c +++ b/arch/arm/boards/at91sam9261ek/init.c @@ -46,6 +46,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC15, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) .bus_width_16 = 1, #else diff --git a/arch/arm/boards/at91sam9263ek/init.c b/arch/arm/boards/at91sam9263ek/init.c index 889b4c29cb..c8a9d5c005 100644 --- a/arch/arm/boards/at91sam9263ek/init.c +++ b/arch/arm/boards/at91sam9263ek/init.c @@ -43,6 +43,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, + .ecc_mode = NAND_ECC_SOFT, #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) .bus_width_16 = 1, #else diff --git a/arch/arm/boards/at91sam9m10g45ek/init.c b/arch/arm/boards/at91sam9m10g45ek/init.c index 6503ebbd5d..cdd7806848 100644 --- a/arch/arm/boards/at91sam9m10g45ek/init.c +++ b/arch/arm/boards/at91sam9m10g45ek/init.c @@ -67,6 +67,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC8, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) .bus_width_16 = 1, #else diff --git a/arch/arm/boards/at91sam9m10ihd/init.c b/arch/arm/boards/at91sam9m10ihd/init.c index fc37af4d20..a432e5c411 100644 --- a/arch/arm/boards/at91sam9m10ihd/init.c +++ b/arch/arm/boards/at91sam9m10ihd/init.c @@ -44,6 +44,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC15, .enable_pin = AT91_PIN_PC14, + .ecc_mode = NAND_ECC_SOFT, .bus_width_16 = 0, .on_flash_bbt = 1, }; diff --git a/arch/arm/boards/at91sam9n12ek/init.c b/arch/arm/boards/at91sam9n12ek/init.c index a206d6b731..818a598907 100644 --- a/arch/arm/boards/at91sam9n12ek/init.c +++ b/arch/arm/boards/at91sam9n12ek/init.c @@ -47,6 +47,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PD5, .enable_pin = AT91_PIN_PD4, + .has_pmecc = 1, .ecc_mode = NAND_ECC_HW, .pmecc_sector_size = 512, .pmecc_corr_cap = 2, diff --git a/arch/arm/boards/at91sam9x5ek/init.c b/arch/arm/boards/at91sam9x5ek/init.c index 62e56521ef..183ddc7052 100644 --- a/arch/arm/boards/at91sam9x5ek/init.c +++ b/arch/arm/boards/at91sam9x5ek/init.c @@ -57,6 +57,7 @@ static struct atmel_nand_data nand_pdata = { .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PD5, .enable_pin = AT91_PIN_PD4, + .has_pmecc = 1, .ecc_mode = NAND_ECC_HW, .pmecc_sector_size = 512, .pmecc_corr_cap = 2, diff --git a/arch/arm/boards/sama5d3_xplained/init.c b/arch/arm/boards/sama5d3_xplained/init.c index ae84209cbb..7dfebe8e89 100644 --- a/arch/arm/boards/sama5d3_xplained/init.c +++ b/arch/arm/boards/sama5d3_xplained/init.c @@ -48,6 +48,7 @@ static struct atmel_nand_data nand_pdata = { .rdy_pin = -EINVAL, .enable_pin = -EINVAL, .ecc_mode = NAND_ECC_HW, + .has_pmecc = 1, .pmecc_sector_size = 512, .pmecc_corr_cap = 4, #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) diff --git a/arch/arm/boards/sama5d3xek/init.c b/arch/arm/boards/sama5d3xek/init.c index 743197fe47..49d2b371f5 100644 --- a/arch/arm/boards/sama5d3xek/init.c +++ b/arch/arm/boards/sama5d3xek/init.c @@ -63,6 +63,7 @@ static struct atmel_nand_data nand_pdata = { .rdy_pin = -EINVAL, .enable_pin = -EINVAL, .ecc_mode = NAND_ECC_HW, + .has_pmecc = 1, .pmecc_sector_size = 512, .pmecc_corr_cap = 4, #if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index ab80e5f0aa..8599f507c4 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -1,4 +1,4 @@ -obj-y += setup.o clock.o gpio.o irq_fixup.o +obj-y += setup.o clock.o irq_fixup.o obj-$(CONFIG_CMD_AT91_BOOT_TEST) += boot_test_cmd.o obj-$(CONFIG_AT91_BOOTSTRAP) += bootstrap.o diff --git a/arch/arm/mach-at91/gpio.h b/arch/arm/mach-at91/gpio.h deleted file mode 100644 index d40628b8d9..0000000000 --- a/arch/arm/mach-at91/gpio.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> - * - * Under GPLv2 only - */ - -#ifndef __AT91_GPIO_H__ -#define __AT91_GPIO_H__ - -#ifndef __gpio_init -#define __gpio_init -#endif - -#define MAX_NB_GPIO_PER_BANK 32 - -static inline unsigned pin_to_bank(unsigned pin) -{ - return pin / MAX_NB_GPIO_PER_BANK; -} - -static inline unsigned pin_to_bank_offset(unsigned pin) -{ - return pin % MAX_NB_GPIO_PER_BANK; -} - -static inline unsigned pin_to_mask(unsigned pin) -{ - return 1 << pin_to_bank_offset(pin); -} - -static __gpio_init void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) -{ - __raw_writel(mask, pio + PIO_IDR); -} - -static __gpio_init void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) -{ - __raw_writel(mask, pio + (on ? PIO_PUER : PIO_PUDR)); -} - -static __gpio_init void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on) -{ - __raw_writel(mask, pio + (on ? PIO_MDER : PIO_MDDR)); -} - -static __gpio_init void at91_mux_set_A_periph(void __iomem *pio, unsigned mask) -{ - __raw_writel(mask, pio + PIO_ASR); -} - -static __gpio_init void at91_mux_set_B_periph(void __iomem *pio, unsigned mask) -{ - __raw_writel(mask, pio + PIO_BSR); -} - -static __gpio_init void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask) -{ - - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, - pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, - pio + PIO_ABCDSR2); -} - -static __gpio_init void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask) -{ - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, - pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, - pio + PIO_ABCDSR2); -} - -static __gpio_init void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask) -{ - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); -} - -static __gpio_init void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask) -{ - __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); - __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); -} - -static __gpio_init void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) -{ - __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); -} - -static __gpio_init void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) -{ - if (is_on) - __raw_writel(mask, pio + PIO_IFSCDR); - at91_mux_set_deglitch(pio, mask, is_on); -} - -static __gpio_init void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, - bool is_on, u32 div) -{ - if (is_on) { - __raw_writel(mask, pio + PIO_IFSCER); - __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); - __raw_writel(mask, pio + PIO_IFER); - } else { - __raw_writel(mask, pio + PIO_IFDR); - } -} - -static __gpio_init void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) -{ - __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); -} - -static __gpio_init void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) -{ - __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); -} - -static __gpio_init void at91_mux_gpio_disable(void __iomem *pio, unsigned mask) -{ - __raw_writel(mask, pio + PIO_PDR); -} - -static __gpio_init void at91_mux_gpio_enable(void __iomem *pio, unsigned mask) -{ - __raw_writel(mask, pio + PIO_PER); -} - -static __gpio_init void at91_mux_gpio_input(void __iomem *pio, unsigned mask, bool input) -{ - __raw_writel(mask, pio + (input ? PIO_ODR : PIO_OER)); -} - -static __gpio_init void at91_mux_gpio_set(void __iomem *pio, unsigned mask, -int value) -{ - __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); -} - -static __gpio_init int at91_mux_gpio_get(void __iomem *pio, unsigned mask) -{ - u32 pdsr; - - pdsr = __raw_readl(pio + PIO_PDSR); - return (pdsr & mask) != 0; -} - -#endif /* __AT91_GPIO_H__ */ diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index aa0fdae141..e2307ed8e6 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -63,6 +63,7 @@ struct atmel_nand_data { u8 bus_width_16; /* buswidth is 16 bit */ u8 ecc_mode; /* NAND_ECC_* */ u8 on_flash_bbt; /* Use flash based bbt */ + u8 has_pmecc; /* Use PMECC */ u8 bus_on_d0; u8 pmecc_corr_cap; diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index 306ab4c9f2..6a6b9cd004 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -1 +1,150 @@ +/* + * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 only + */ + +#ifndef __AT91_GPIO_H__ +#define __AT91_GPIO_H__ + #include <asm-generic/gpio.h> + +#ifndef __gpio_init +#define __gpio_init +#endif + +#define MAX_NB_GPIO_PER_BANK 32 + +static inline unsigned pin_to_bank(unsigned pin) +{ + return pin / MAX_NB_GPIO_PER_BANK; +} + +static inline unsigned pin_to_bank_offset(unsigned pin) +{ + return pin % MAX_NB_GPIO_PER_BANK; +} + +static inline unsigned pin_to_mask(unsigned pin) +{ + return 1 << pin_to_bank_offset(pin); +} + +static __gpio_init void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) +{ + __raw_writel(mask, pio + PIO_IDR); +} + +static __gpio_init void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) +{ + __raw_writel(mask, pio + (on ? PIO_PUER : PIO_PUDR)); +} + +static __gpio_init void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on) +{ + __raw_writel(mask, pio + (on ? PIO_MDER : PIO_MDDR)); +} + +static __gpio_init void at91_mux_set_A_periph(void __iomem *pio, unsigned mask) +{ + __raw_writel(mask, pio + PIO_ASR); +} + +static __gpio_init void at91_mux_set_B_periph(void __iomem *pio, unsigned mask) +{ + __raw_writel(mask, pio + PIO_BSR); +} + +static __gpio_init void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask) +{ + + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, + pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); +} + +static __gpio_init void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask) +{ + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, + pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); +} + +static __gpio_init void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask) +{ + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); +} + +static __gpio_init void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask) +{ + __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); + __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); +} + +static __gpio_init void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) +{ + __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); +} + +static __gpio_init void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) +{ + if (is_on) + __raw_writel(mask, pio + PIO_IFSCDR); + at91_mux_set_deglitch(pio, mask, is_on); +} + +static __gpio_init void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, + bool is_on, u32 div) +{ + if (is_on) { + __raw_writel(mask, pio + PIO_IFSCER); + __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); + __raw_writel(mask, pio + PIO_IFER); + } else { + __raw_writel(mask, pio + PIO_IFDR); + } +} + +static __gpio_init void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) +{ + __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); +} + +static __gpio_init void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) +{ + __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); +} + +static __gpio_init void at91_mux_gpio_disable(void __iomem *pio, unsigned mask) +{ + __raw_writel(mask, pio + PIO_PDR); +} + +static __gpio_init void at91_mux_gpio_enable(void __iomem *pio, unsigned mask) +{ + __raw_writel(mask, pio + PIO_PER); +} + +static __gpio_init void at91_mux_gpio_input(void __iomem *pio, unsigned mask, bool input) +{ + __raw_writel(mask, pio + (input ? PIO_ODR : PIO_OER)); +} + +static __gpio_init void at91_mux_gpio_set(void __iomem *pio, unsigned mask, +int value) +{ + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); +} + +static __gpio_init int at91_mux_gpio_get(void __iomem *pio, unsigned mask) +{ + u32 pdsr; + + pdsr = __raw_readl(pio + PIO_PDSR); + return (pdsr & mask) != 0; +} + +#endif /* __AT91_GPIO_H__ */ diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 337e2256e3..1e7c6c6662 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -28,6 +28,10 @@ #include <init.h> #include <gpio.h> +#include <of.h> +#include <of_gpio.h> +#include <of_mtd.h> + #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> @@ -1038,6 +1042,92 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) #endif } +static int atmel_nand_of_init(struct atmel_nand_host *host, struct device_node *np) +{ + u32 val; + u32 offset[2]; + int ecc_mode; + struct atmel_nand_data *board = host->board; + enum of_gpio_flags flags = 0; + + if (!IS_ENABLED(CONFIG_OFDEVICE)) + return -ENOSYS; + + if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) { + if (val >= 32) { + dev_err(host->dev, "invalid addr-offset %u\n", val); + return -EINVAL; + } + board->ale = val; + } + + if (of_property_read_u32(np, "atmel,nand-cmd-offset", &val) == 0) { + if (val >= 32) { + dev_err(host->dev, "invalid cmd-offset %u\n", val); + return -EINVAL; + } + board->cle = val; + } + + ecc_mode = of_get_nand_ecc_mode(np); + + board->ecc_mode = ecc_mode < 0 ? NAND_ECC_SOFT : ecc_mode; + + board->on_flash_bbt = of_get_nand_on_flash_bbt(np); + + if (of_get_nand_bus_width(np) == 16) + board->bus_width_16 = 1; + + board->rdy_pin = of_get_gpio_flags(np, 0, &flags); + board->enable_pin = of_get_gpio(np, 1); + board->det_pin = of_get_gpio(np, 2); + + board->has_pmecc = of_property_read_bool(np, "atmel,has-pmecc"); + + if (!(board->ecc_mode == NAND_ECC_HW) || !board->has_pmecc) + return 0; /* Not using PMECC */ + + /* use PMECC, get correction capability, sector size and lookup + * table offset. + * If correction bits and sector size are not specified, then + * find + * them from NAND ONFI parameters. + */ + if (of_property_read_u32(np, "atmel,pmecc-cap", &val) == 0) { + if ((val != 2) && (val != 4) && (val != 8) && (val != 12) && (val != 24)) { + dev_err(host->dev, "Unsupported PMECC correction capability: %d" + " should be 2, 4, 8, 12 or 24\n", val); + return -EINVAL; + } + + board->pmecc_corr_cap = (u8)val; + } + + if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) == 0) { + if ((val != 512) && (val != 1024)) { + dev_err(host->dev, "Unsupported PMECC sector size: %d" + " should be 512 or 1024 bytes\n", val); + return -EINVAL; + } + + board->pmecc_sector_size = (u16)val; + } + + if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset", offset, 2) != 0) { + dev_err(host->dev, "Cannot get PMECC lookup table offset\n"); + return -EINVAL; + } + + if (!offset[0] && !offset[1]) { + dev_err(host->dev, "Invalid PMECC lookup table offset\n"); + return -EINVAL; + } + + board->pmecc_lookup_table_offset = (board->pmecc_sector_size == 512) ? offset[0] : offset[1]; + + return 0; +} + static int atmel_hw_nand_init_params(struct device_d *dev, struct atmel_nand_host *host) { @@ -1093,7 +1183,7 @@ static int atmel_hw_nand_init_params(struct device_d *dev, */ static int __init atmel_nand_probe(struct device_d *dev) { - struct atmel_nand_data *pdata = dev->platform_data; + struct atmel_nand_data *pdata = NULL; struct atmel_nand_host *host; struct mtd_info *mtd; struct nand_chip *nand_chip; @@ -1104,6 +1194,10 @@ static int __init atmel_nand_probe(struct device_d *dev) if (!host) return -ENOMEM; + pdata = kzalloc(sizeof(struct atmel_nand_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + host->io_base = dev_request_mem_region(dev, 0); mtd = &host->mtd; @@ -1111,6 +1205,14 @@ static int __init atmel_nand_probe(struct device_d *dev) host->board = pdata; host->dev = dev; + if (dev->device_node) { + res = atmel_nand_of_init(host, dev->device_node); + if (res) + goto err_no_card; + } else { + memcpy(host->board, dev->platform_data, sizeof(struct atmel_nand_data)); + } + nand_chip->priv = host; /* link the private data structures */ mtd->priv = nand_chip; mtd->parent = dev; @@ -1157,7 +1259,7 @@ static int __init atmel_nand_probe(struct device_d *dev) } } - nand_chip->ecc.mode = NAND_ECC_SOFT; + nand_chip->ecc.mode = pdata->ecc_mode; if (IS_ENABLED(CONFIG_NAND_ECC_HW) && pdata->ecc_mode == NAND_ECC_HW) { @@ -1219,7 +1321,7 @@ static int __init atmel_nand_probe(struct device_d *dev) if (IS_ENABLED(CONFIG_NAND_ECC_HW) && nand_chip->ecc.mode == NAND_ECC_HW) { - if (IS_ENABLED(CONFIG_NAND_ATMEL_PMECC)) + if (IS_ENABLED(CONFIG_NAND_ATMEL_PMECC) && pdata->has_pmecc) res = atmel_pmecc_nand_init_params(dev, host); else res = atmel_hw_nand_init_params(dev, host); @@ -1245,13 +1347,20 @@ err_hw_ecc: err_scan_ident: err_no_card: atmel_nand_disable(host); + kfree(pdata); kfree(host); return res; } +static struct of_device_id atmel_nand_dt_ids[] = { + { .compatible = "atmel,at91rm9200-nand" }, + { /* sentinel */ } +}; + static struct driver_d atmel_nand_driver = { .name = "atmel_nand", .probe = atmel_nand_probe, + .of_compatible = DRV_OF_COMPAT(atmel_nand_dt_ids), }; device_platform_driver(atmel_nand_driver); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 83ba2b6416..398b931546 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -7,6 +7,12 @@ config PINCTRL from the devicetree. Legacy drivers here may not need this core support but instead provide their own SoC specific APIs +config PINCTRL_AT91 + select PINCTRL if OFDEVICE + bool + help + The pinmux controller found on AT91 SoCs. + config PINCTRL_IMX_IOMUX_V1 select PINCTRL if OFDEVICE bool diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 566ba111d7..3ea8649efb 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o +obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o diff --git a/arch/arm/mach-at91/gpio.c b/drivers/pinctrl/pinctrl-at91.c index 4f2c76e3dd..e212f7a183 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2005 HP Labs * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * Copyright (C) 2014 Raphaƫl Poggi * * See file CREDITS for list of people who contributed to this * project. @@ -24,38 +25,57 @@ #include <linux/err.h> #include <errno.h> #include <io.h> -#include <mach/iomux.h> -#include <mach/io.h> -#include <mach/cpu.h> #include <gpio.h> #include <init.h> #include <driver.h> #include <getopt.h> -#include "gpio.h" +#include <mach/at91_pio.h> +#include <mach/gpio.h> -#define MAX_GPIO_BANKS 5 +#include <pinctrl.h> -static int gpio_banks = 0; +struct at91_pinctrl { + struct pinctrl_device pctl; + struct at91_pinctrl_mux_ops *ops; +}; -/* - * Functionnality can change with newer chips - */ struct at91_gpio_chip { struct gpio_chip chip; void __iomem *regbase; /* PIO bank virtual address */ struct at91_pinctrl_mux_ops *ops; /* ops */ }; +enum at91_mux { + AT91_MUX_GPIO = 0, + AT91_MUX_PERIPH_A = 1, + AT91_MUX_PERIPH_B = 2, + AT91_MUX_PERIPH_C = 3, + AT91_MUX_PERIPH_D = 4, +}; + +#define MAX_GPIO_BANKS 5 +#define to_at91_pinctrl(c) container_of(c, struct at91_pinctrl, pctl); #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) +#define PULL_UP (1 << 0) +#define MULTI_DRIVE (1 << 1) +#define DEGLITCH (1 << 2) +#define PULL_DOWN (1 << 3) +#define DIS_SCHMIT (1 << 4) +#define DEBOUNCE (1 << 16) +#define DEBOUNCE_VAL_SHIFT 17 +#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) + +static int gpio_banks; + static struct at91_gpio_chip gpio_chip[MAX_GPIO_BANKS]; -static inline struct at91_gpio_chip *pin_to_controller(unsigned pin) +static inline void __iomem *pin_to_controller(unsigned pin) { pin /= MAX_NB_GPIO_PER_BANK; if (likely(pin < gpio_banks)) - return &gpio_chip[pin]; + return gpio_chip[pin].regbase; return NULL; } @@ -92,96 +112,6 @@ struct at91_pinctrl_mux_ops { void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask); }; -#ifdef CONFIG_CMD_AT91MUX -static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_PUSR) >> pin) & 0x1; -} - -static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_MDSR) >> pin) & 0x1; -} - -static enum at91_mux at91_mux_pio3_get_periph(void __iomem *pio, unsigned mask) -{ - unsigned select; - - if (__raw_readl(pio + PIO_PSR) & mask) - return AT91_MUX_GPIO; - - select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask); - select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1); - - return select + 1; -} - -static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) -{ - unsigned select; - - if (__raw_readl(pio + PIO_PSR) & mask) - return AT91_MUX_GPIO; - - select = __raw_readl(pio + PIO_ABSR) & mask; - - return select + 1; -} - -static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; -} - -static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) -{ - *div = __raw_readl(pio + PIO_SCDR); - - return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1; -} - -static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; -} - -static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) -{ - return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; -} -#else -#define at91_mux_get_periph NULL -#define at91_mux_pio3_get_periph NULL -#define at91_mux_get_deglitch NULL -#define at91_mux_pio3_get_debounce NULL -#define at91_mux_pio3_get_pulldown NULL -#define at91_mux_pio3_get_schmitt_trig NULL -#endif - -static struct at91_pinctrl_mux_ops at91rm9200_ops = { - .get_periph = at91_mux_get_periph, - .mux_A_periph = at91_mux_set_A_periph, - .mux_B_periph = at91_mux_set_B_periph, - .get_deglitch = at91_mux_get_deglitch, - .set_deglitch = at91_mux_set_deglitch, -}; - -static struct at91_pinctrl_mux_ops at91sam9x5_ops = { - .get_periph = at91_mux_pio3_get_periph, - .mux_A_periph = at91_mux_pio3_set_A_periph, - .mux_B_periph = at91_mux_pio3_set_B_periph, - .mux_C_periph = at91_mux_pio3_set_C_periph, - .mux_D_periph = at91_mux_pio3_set_D_periph, - .get_deglitch = at91_mux_get_deglitch, - .set_deglitch = at91_mux_pio3_set_deglitch, - .get_debounce = at91_mux_pio3_get_debounce, - .set_debounce = at91_mux_pio3_set_debounce, - .get_pulldown = at91_mux_pio3_get_pulldown, - .set_pulldown = at91_mux_pio3_set_pulldown, - .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, - .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, -}; - int at91_mux_pin(unsigned pin, enum at91_mux mux, int use_pullup) { struct at91_gpio_chip *at91_gpio = pin_to_controller(pin); @@ -376,157 +306,232 @@ int at91_disable_schmitt_trig(unsigned pin) } EXPORT_SYMBOL(at91_disable_schmitt_trig); -#ifdef CONFIG_CMD_AT91MUX -static void at91mux_printf_mode(unsigned bank, unsigned pin) +static enum at91_mux at91_mux_pio3_get_periph(void __iomem *pio, unsigned mask) { - struct at91_gpio_chip *at91_gpio = &gpio_chip[bank]; - void __iomem *pio = at91_gpio->regbase; - enum at91_mux mode; - u32 pdsr; - - unsigned mask = pin_to_mask(pin); + unsigned select; - mode = at91_gpio->ops->get_periph(pio, mask); + if (__raw_readl(pio + PIO_PSR) & mask) + return AT91_MUX_GPIO; - if (mode == AT91_MUX_GPIO) { - pdsr = __raw_readl(pio + PIO_PDSR); + select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask); + select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1); - printf("[gpio] %s", pdsr & mask ? "set" : "clear"); - } else { - printf("[periph %c]", mode + 'A' - 1); - } + return select + 1; } -static void at91mux_dump_config(void) +static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) { - int bank, j; - - /* print heading */ - printf("Pin\t"); - for (bank = 0; bank < gpio_banks; bank++) { - printf("PIO%c\t\t", 'A' + bank); - }; - printf("\n\n"); + unsigned select; - /* print pin status */ - for (j = 0; j < 32; j++) { - printf("%i:\t", j); + if (__raw_readl(pio + PIO_PSR) & mask) + return AT91_MUX_GPIO; - for (bank = 0; bank < gpio_banks; bank++) { - at91mux_printf_mode(bank, j); + select = __raw_readl(pio + PIO_ABSR) & mask; - printf("\t"); - } + return select + 1; +} - printf("\n"); - } +static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) +{ + return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; } -static void at91mux_print_en_disable(const char *str, bool is_on) +static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) { - printf("%s = ", str); + *div = __raw_readl(pio + PIO_SCDR); - if (is_on) - printf("enable\n"); - else - printf("disable\n"); + return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1; } -static void at91mux_dump_pio_config(unsigned bank, unsigned pin) +static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) { - struct at91_gpio_chip *at91_gpio = &gpio_chip[bank]; - void __iomem *pio = at91_gpio->regbase; - u32 div; - - printf("pio%c%u configuration\n\n", bank + 'A', pin); + return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; +} - at91mux_printf_mode(bank, pin); - printf("\n"); +static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) +{ + return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; +} - at91mux_print_en_disable("multidrive", - at91_mux_get_multidrive(pio, pin)); +static struct at91_pinctrl_mux_ops at91rm9200_ops = { + .get_periph = at91_mux_get_periph, + .mux_A_periph = at91_mux_set_A_periph, + .mux_B_periph = at91_mux_set_B_periph, + .get_deglitch = at91_mux_get_deglitch, + .set_deglitch = at91_mux_set_deglitch, +}; - at91mux_print_en_disable("pullup", - at91_mux_get_pullup(pio, pin)); +static struct at91_pinctrl_mux_ops at91sam9x5_ops = { + .get_periph = at91_mux_pio3_get_periph, + .mux_A_periph = at91_mux_pio3_set_A_periph, + .mux_B_periph = at91_mux_pio3_set_B_periph, + .mux_C_periph = at91_mux_pio3_set_C_periph, + .mux_D_periph = at91_mux_pio3_set_D_periph, + .get_deglitch = at91_mux_get_deglitch, + .set_deglitch = at91_mux_pio3_set_deglitch, + .get_debounce = at91_mux_pio3_get_debounce, + .set_debounce = at91_mux_pio3_set_debounce, + .get_pulldown = at91_mux_pio3_get_pulldown, + .set_pulldown = at91_mux_pio3_set_pulldown, + .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, + .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, +}; - if (at91_gpio->ops->get_deglitch) - at91mux_print_en_disable("degitch", - at91_gpio->ops->get_deglitch(pio, pin)); +static struct of_device_id at91_pinctrl_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-pinctrl", + .data = (unsigned long)&at91rm9200_ops, + }, { + .compatible = "atmel,at91sam9x5-pinctrl", + .data = (unsigned long)&at91sam9x5_ops, + }, { + /* sentinel */ + } +}; - if (at91_gpio->ops->get_debounce) { - printf("debounce = "); - if (at91_gpio->ops->get_debounce(pio, pin, &div)) - printf("enable at %d\n", div); +static struct at91_pinctrl_mux_ops *at91_pinctrl_get_driver_data(struct device_d *dev) +{ + struct at91_pinctrl_mux_ops *ops_data = NULL; + int rc; + + if (dev->device_node) { + const struct of_device_id *match; + match = of_match_node(at91_pinctrl_dt_ids, dev->device_node); + if (!match) + ops_data = NULL; else - printf("disable\n"); + ops_data = (struct at91_pinctrl_mux_ops *)match->data; + } else { + rc = dev_get_drvdata(dev, (unsigned long *)&ops_data); + if (rc) + ops_data = NULL; } - if (at91_gpio->ops->get_pulldown) - at91mux_print_en_disable("pulldown", - at91_gpio->ops->get_pulldown(pio, pin)); + return ops_data; +} + +static int at91_pinctrl_set_conf(struct at91_pinctrl *info, unsigned int pin_num, unsigned int mux, unsigned int conf) +{ + unsigned int mask; + void __iomem *pio; + + pio = pin_to_controller(pin_num); + mask = pin_to_mask(pin_num); - if (at91_gpio->ops->get_schmitt_trig) - at91mux_print_en_disable("schmitt trigger", - !at91_gpio->ops->get_schmitt_trig(pio, pin)); + if (conf & PULL_UP && conf & PULL_DOWN) + return -EINVAL; + + at91_mux_set_pullup(pio, mask, conf & PULL_UP); + at91_mux_set_multidrive(pio, mask, conf & MULTI_DRIVE); + if (info->ops->set_deglitch) + info->ops->set_deglitch(pio, mask, conf & DEGLITCH); + if (info->ops->set_debounce) + info->ops->set_debounce(pio, mask, conf & DEBOUNCE, + (conf & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT); + if (info->ops->set_pulldown) + info->ops->set_pulldown(pio, mask, conf & PULL_DOWN); + if (info->ops->disable_schmitt_trig && conf & DIS_SCHMIT) + info->ops->disable_schmitt_trig(pio, mask); + + return 0; } -static int do_at91mux(int argc, char *argv[]) +static int at91_pinctrl_set_state(struct pinctrl_device *pdev, struct device_node *np) { - int opt; - unsigned bank = 0; - unsigned pin = 0; + struct at91_pinctrl *info; + const __be32 *list; + int i, size; + int ret = 0; + int bank_num, pin_num, mux, conf; - if (argc < 2) { - at91mux_dump_config(); - return 0; + info = to_at91_pinctrl(pdev); + + list = of_get_property(np, "atmel,pins", &size); + size /= sizeof(*list); + + if (!size || size % 4) { + dev_err(pdev->dev, "wrong pins number or pins and configs should be by 4\n"); + return -EINVAL; } - while ((opt = getopt(argc, argv, "b:p:")) > 0) { - switch (opt) { - case 'b': - bank = simple_strtoul(optarg, NULL, 10); - break; - case 'p': - pin = simple_strtoul(optarg, NULL, 10); - break; + for (i = 0; i < size; i += 4) { + bank_num = be32_to_cpu(*list++); + pin_num = be32_to_cpu(*list++); + mux = be32_to_cpu(*list++); + conf = be32_to_cpu(*list++); + + ret = at91_mux_pin(pin_num, mux, conf & PULL_UP); + if (ret) { + dev_err(pdev->dev, "failed to mux pin %d\n", pin_num); + return ret; } - } - if (bank >= gpio_banks) { - printf("bank %c >= supported %c banks\n", bank + 'A', - gpio_banks + 'A'); - return 1; + ret = at91_pinctrl_set_conf(info, pin_num, mux, conf); + if (ret) { + dev_err(pdev->dev, "failed to set conf on pin %d\n", pin_num); + return ret; + } } - if (pin >= 32) { - printf("pin %u >= supported %d pins\n", pin, 32); - return 1; + return ret; +} + +static struct pinctrl_ops at91_pinctrl_ops = { + .set_state = at91_pinctrl_set_state, +}; + +static int at91_pinctrl_probe(struct device_d *dev) +{ + struct at91_pinctrl *info; + int ret; + + if (!IS_ENABLED(CONFIG_PINCTRL)) + return 0; + + info = xzalloc(sizeof(struct at91_pinctrl)); + + info->ops = at91_pinctrl_get_driver_data(dev); + if (!info->ops) { + dev_err(dev, "failed to retrieve driver data\n"); + return -ENODEV; } - at91mux_dump_pio_config(bank, pin); + info->pctl.dev = dev; + info->pctl.ops = &at91_pinctrl_ops; + + ret = pinctrl_register(&info->pctl); + if (ret) + return ret; + + dev_info(dev, "AT91 pinctrl registered\n"); return 0; } -BAREBOX_CMD_HELP_START(at91mux) -BAREBOX_CMD_HELP_TEXT("Dump current MUX configuration. If a BANK or PIN has been") -BAREBOX_CMD_HELP_TEXT("specified dump pin details.") -BAREBOX_CMD_HELP_TEXT("") -BAREBOX_CMD_HELP_TEXT("Options:") -BAREBOX_CMD_HELP_OPT ("-p PIN", "pin number") -BAREBOX_CMD_HELP_OPT ("-b BANK", "bank number") -BAREBOX_CMD_HELP_END - -BAREBOX_CMD_START(at91mux) - .cmd = do_at91mux, - BAREBOX_CMD_DESC("list MUX configuration") - BAREBOX_CMD_OPTS("[-pb]") - BAREBOX_CMD_GROUP(CMD_GRP_INFO) - BAREBOX_CMD_HELP(cmd_at91mux_help) - BAREBOX_CMD_COMPLETE(empty_complete) -BAREBOX_CMD_END -#endif -/*--------------------------------------------------------------------------*/ +static struct platform_device_id at91_pinctrl_ids[] = { + { + .name = "at91rm9200-pinctrl", + .driver_data = (unsigned long)&at91rm9200_ops, + }, { + .name = "at91sam9x5-pinctrl", + .driver_data = (unsigned long)&at91sam9x5_ops, + }, { + /* sentinel */ + }, +}; + +static struct driver_d at91_pinctrl_driver = { + .name = "pinctrl-at91", + .probe = at91_pinctrl_probe, + .id_table = at91_pinctrl_ids, + .of_compatible = DRV_OF_COMPAT(at91_pinctrl_dt_ids), +}; + +static int at91_pinctrl_init(void) +{ + return platform_driver_register(&at91_pinctrl_driver); +} +coredevice_initcall(at91_pinctrl_init); static int at91_gpio_get(struct gpio_chip *chip, unsigned offset) { @@ -598,21 +603,26 @@ static struct gpio_ops at91_gpio_ops = { .set = at91_gpio_set, }; +static struct of_device_id at91_gpio_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-gpio", + }, { + .compatible = "atmel,at91sam9x5-gpio", + }, { + /* sentinel */ + }, +}; + static int at91_gpio_probe(struct device_d *dev) { struct at91_gpio_chip *at91_gpio; struct clk *clk; int ret; + int alias_idx = of_alias_get_id(dev->device_node, "gpio"); BUG_ON(dev->id > MAX_GPIO_BANKS); - at91_gpio = &gpio_chip[dev->id]; - - ret = dev_get_drvdata(dev, (unsigned long *)&at91_gpio->ops); - if (ret) { - dev_err(dev, "dev_get_drvdata failed: %d\n", ret); - return ret; - } + at91_gpio = &gpio_chip[alias_idx]; clk = clk_get(dev, NULL); if (IS_ERR(clk)) { @@ -628,8 +638,10 @@ static int at91_gpio_probe(struct device_d *dev) return ret; } - gpio_banks = max(gpio_banks, dev->id + 1); + gpio_banks = max(gpio_banks, alias_idx + 1); at91_gpio->regbase = dev_request_mem_region(dev, 0); + if (!at91_gpio->regbase) + return -EBUSY; at91_gpio->chip.ops = &at91_gpio_ops; at91_gpio->chip.ngpio = MAX_NB_GPIO_PER_BANK; @@ -642,29 +654,30 @@ static int at91_gpio_probe(struct device_d *dev) return ret; } + dev_info(dev, "AT91 gpio driver registered\n"); + return 0; } static struct platform_device_id at91_gpio_ids[] = { { .name = "at91rm9200-gpio", - .driver_data = (unsigned long)&at91rm9200_ops, }, { .name = "at91sam9x5-gpio", - .driver_data = (unsigned long)&at91sam9x5_ops, }, { /* sentinel */ }, }; static struct driver_d at91_gpio_driver = { - .name = "at91-gpio", + .name = "gpio-at91", .probe = at91_gpio_probe, .id_table = at91_gpio_ids, + .of_compatible = DRV_OF_COMPAT(at91_gpio_dt_ids), }; static int at91_gpio_init(void) { return platform_driver_register(&at91_gpio_driver); } -postcore_initcall(at91_gpio_init); +coredevice_initcall(at91_gpio_init); |