summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-09-05 07:32:54 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-09-05 07:32:54 +0200
commitd12cc92639690db63a95cc76542121a6da0995c2 (patch)
tree92764013b712c13d76b86803ea992915f9edcf6c
parent1202e6e83cb238bcfc15ed09272f62b0643cfc4f (diff)
parent71ff9bfebd7fe99c1720aa829e43fd9270a6b6f4 (diff)
downloadbarebox-d12cc92639690db63a95cc76542121a6da0995c2.tar.gz
barebox-d12cc92639690db63a95cc76542121a6da0995c2.tar.xz
Merge branch 'for-next/at91'
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/boards/at91sam9260ek/init.c2
-rw-r--r--arch/arm/boards/at91sam9261ek/init.c1
-rw-r--r--arch/arm/boards/at91sam9263ek/init.c1
-rw-r--r--arch/arm/boards/at91sam9m10g45ek/init.c1
-rw-r--r--arch/arm/boards/at91sam9m10ihd/init.c1
-rw-r--r--arch/arm/boards/at91sam9n12ek/init.c1
-rw-r--r--arch/arm/boards/at91sam9x5ek/init.c1
-rw-r--r--arch/arm/boards/sama5d3_xplained/init.c1
-rw-r--r--arch/arm/boards/sama5d3xek/init.c1
-rw-r--r--arch/arm/mach-at91/Makefile2
-rw-r--r--arch/arm/mach-at91/gpio.h148
-rw-r--r--arch/arm/mach-at91/include/mach/board.h1
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h149
-rw-r--r--drivers/mtd/nand/atmel_nand.c115
-rw-r--r--drivers/pinctrl/Kconfig6
-rw-r--r--drivers/pinctrl/Makefile1
-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);