summaryrefslogtreecommitdiff
path: root/arch/arm/mach-u300/core.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2011-05-02 20:54:38 +0200
committerLinus Walleij <linus.walleij@stericsson.com>2011-10-13 12:57:45 +0200
commit98da3529536ed3c78ae493f4cc3d7ac8d43fc72c (patch)
tree4d10ff569e1cbea384c7e0e162b0481be4766e30 /arch/arm/mach-u300/core.c
parent2744e8afb3b76343e7eb8197e8b3e085036010a5 (diff)
pinctrl: add a driver for the U300 pinmux
This adds a driver for the U300 pinmux portions of the system controller "SYSCON". It also serves as an example of how to use the pinmux subsystem. This driver also houses the platform data for the only supported platform. This deletes the old U300 driver in arch/arm/mach-u300 and replace it with a driver using the new subsystem. The new driver is considerably fatter than the old one, but it also registers all 467 pins of the system and adds the power and EMIF pin groups and corresponding functions. The idea is to use this driver as a a reference for other implementation so it needs to be as complete and verbose as possible. Reviewed-by: Barry Song <21cnbao@gmail.com> [Fixup for changed function names and semantics in the v10 patch] Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch/arm/mach-u300/core.c')
-rw-r--r--arch/arm/mach-u300/core.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 399c89f14dfb..2f5929bdeaa2 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -25,6 +25,8 @@
#include <linux/err.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinmux.h>
#include <asm/types.h>
#include <asm/setup.h>
@@ -1535,6 +1537,14 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS,
};
+static struct resource pinmux_resources[] = {
+ {
+ .start = U300_SYSCON_BASE,
+ .end = U300_SYSCON_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
static struct platform_device wdog_device = {
.name = "coh901327_wdog",
.id = -1,
@@ -1630,6 +1640,72 @@ static struct platform_device dma_device = {
},
};
+static struct platform_device pinmux_device = {
+ .name = "pinmux-u300",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pinmux_resources),
+ .resource = pinmux_resources,
+};
+
+/* Pinmux settings */
+static struct pinmux_map u300_pinmux_map[] = {
+ /* anonymous maps for chip power and EMIFs */
+ PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"),
+ PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"),
+ PINMUX_MAP_PRIMARY_SYS_HOG("EMIF1", "emif1"),
+ /* per-device maps for MMC/SD, SPI and UART */
+ PINMUX_MAP_PRIMARY("MMCSD", "mmc0", "mmci"),
+ PINMUX_MAP_PRIMARY("SPI", "spi0", "pl022"),
+ PINMUX_MAP_PRIMARY("UART0", "uart0", "uart0"),
+};
+
+struct u300_mux_hog {
+ const char *name;
+ struct device *dev;
+ struct pinmux *pmx;
+};
+
+static struct u300_mux_hog u300_mux_hogs[] = {
+ {
+ .name = "uart0",
+ .dev = &uart0_device.dev,
+ },
+ {
+ .name = "spi0",
+ .dev = &pl022_device.dev,
+ },
+ {
+ .name = "mmc0",
+ .dev = &mmcsd_device.dev,
+ },
+};
+
+static int __init u300_pinmux_fetch(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
+ struct pinmux *pmx;
+ int ret;
+
+ pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
+ if (IS_ERR(pmx)) {
+ pr_err("u300: could not get pinmux hog %s\n",
+ u300_mux_hogs[i].name);
+ continue;
+ }
+ ret = pinmux_enable(pmx);
+ if (ret) {
+ pr_err("u300: could enable pinmux hog %s\n",
+ u300_mux_hogs[i].name);
+ continue;
+ }
+ u300_mux_hogs[i].pmx = pmx;
+ }
+ return 0;
+}
+subsys_initcall(u300_pinmux_fetch);
+
/*
* Notice that AMBA devices are initialized before platform devices.
*
@@ -1643,10 +1719,10 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device,
&nand_device,
&wdog_device,
- &ave_device
+ &ave_device,
+ &pinmux_device,
};
-
/*
* Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
* together so some interrupts are connected to the first one and some
@@ -1828,6 +1904,10 @@ void __init u300_init_devices(void)
u300_assign_physmem();
+ /* Initialize pinmuxing */
+ pinmux_register_mappings(u300_pinmux_map,
+ ARRAY_SIZE(u300_pinmux_map));
+
/* Register subdevices on the I2C buses */
u300_i2c_register_board_devices();