diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-u300/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/core.c | 84 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/syscon.h | 136 | ||||
-rw-r--r-- | arch/arm/mach-u300/mmc.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-u300/padmux.c | 367 | ||||
-rw-r--r-- | arch/arm/mach-u300/padmux.h | 39 | ||||
-rw-r--r-- | arch/arm/mach-u300/spi.c | 20 |
8 files changed, 85 insertions, 581 deletions
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 32a7b0f7e9f..449fd6a8dbd 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig | |||
@@ -6,6 +6,8 @@ comment "ST-Ericsson Mobile Platform Products" | |||
6 | 6 | ||
7 | config MACH_U300 | 7 | config MACH_U300 |
8 | bool "U300" | 8 | bool "U300" |
9 | select PINCTRL | ||
10 | select PINMUX_U300 | ||
9 | 11 | ||
10 | comment "ST-Ericsson U300/U330/U335/U365 Feature Selections" | 12 | comment "ST-Ericsson U300/U330/U335/U365 Feature Selections" |
11 | 13 | ||
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 8fd354aaf0a..285538124e5 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux kernel, U300 machine. | 2 | # Makefile for the linux kernel, U300 machine. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := core.o clock.o timer.o padmux.o | 5 | obj-y := core.o clock.o timer.o |
6 | obj-m := | 6 | obj-m := |
7 | obj-n := | 7 | obj-n := |
8 | obj- := | 8 | obj- := |
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 399c89f14df..2f5929bdeaa 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/mtd/nand.h> | 26 | #include <linux/mtd/nand.h> |
27 | #include <linux/mtd/fsmc.h> | 27 | #include <linux/mtd/fsmc.h> |
28 | #include <linux/pinctrl/machine.h> | ||
29 | #include <linux/pinctrl/pinmux.h> | ||
28 | 30 | ||
29 | #include <asm/types.h> | 31 | #include <asm/types.h> |
30 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
@@ -1535,6 +1537,14 @@ static struct coh901318_platform coh901318_platform = { | |||
1535 | .max_channels = U300_DMA_CHANNELS, | 1537 | .max_channels = U300_DMA_CHANNELS, |
1536 | }; | 1538 | }; |
1537 | 1539 | ||
1540 | static struct resource pinmux_resources[] = { | ||
1541 | { | ||
1542 | .start = U300_SYSCON_BASE, | ||
1543 | .end = U300_SYSCON_BASE + SZ_4K - 1, | ||
1544 | .flags = IORESOURCE_MEM, | ||
1545 | }, | ||
1546 | }; | ||
1547 | |||
1538 | static struct platform_device wdog_device = { | 1548 | static struct platform_device wdog_device = { |
1539 | .name = "coh901327_wdog", | 1549 | .name = "coh901327_wdog", |
1540 | .id = -1, | 1550 | .id = -1, |
@@ -1630,6 +1640,72 @@ static struct platform_device dma_device = { | |||
1630 | }, | 1640 | }, |
1631 | }; | 1641 | }; |
1632 | 1642 | ||
1643 | static struct platform_device pinmux_device = { | ||
1644 | .name = "pinmux-u300", | ||
1645 | .id = -1, | ||
1646 | .num_resources = ARRAY_SIZE(pinmux_resources), | ||
1647 | .resource = pinmux_resources, | ||
1648 | }; | ||
1649 | |||
1650 | /* Pinmux settings */ | ||
1651 | static struct pinmux_map u300_pinmux_map[] = { | ||
1652 | /* anonymous maps for chip power and EMIFs */ | ||
1653 | PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"), | ||
1654 | PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"), | ||
1655 | PINMUX_MAP_PRIMARY_SYS_HOG("EMIF1", "emif1"), | ||
1656 | /* per-device maps for MMC/SD, SPI and UART */ | ||
1657 | PINMUX_MAP_PRIMARY("MMCSD", "mmc0", "mmci"), | ||
1658 | PINMUX_MAP_PRIMARY("SPI", "spi0", "pl022"), | ||
1659 | PINMUX_MAP_PRIMARY("UART0", "uart0", "uart0"), | ||
1660 | }; | ||
1661 | |||
1662 | struct u300_mux_hog { | ||
1663 | const char *name; | ||
1664 | struct device *dev; | ||
1665 | struct pinmux *pmx; | ||
1666 | }; | ||
1667 | |||
1668 | static struct u300_mux_hog u300_mux_hogs[] = { | ||
1669 | { | ||
1670 | .name = "uart0", | ||
1671 | .dev = &uart0_device.dev, | ||
1672 | }, | ||
1673 | { | ||
1674 | .name = "spi0", | ||
1675 | .dev = &pl022_device.dev, | ||
1676 | }, | ||
1677 | { | ||
1678 | .name = "mmc0", | ||
1679 | .dev = &mmcsd_device.dev, | ||
1680 | }, | ||
1681 | }; | ||
1682 | |||
1683 | static int __init u300_pinmux_fetch(void) | ||
1684 | { | ||
1685 | int i; | ||
1686 | |||
1687 | for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) { | ||
1688 | struct pinmux *pmx; | ||
1689 | int ret; | ||
1690 | |||
1691 | pmx = pinmux_get(u300_mux_hogs[i].dev, NULL); | ||
1692 | if (IS_ERR(pmx)) { | ||
1693 | pr_err("u300: could not get pinmux hog %s\n", | ||
1694 | u300_mux_hogs[i].name); | ||
1695 | continue; | ||
1696 | } | ||
1697 | ret = pinmux_enable(pmx); | ||
1698 | if (ret) { | ||
1699 | pr_err("u300: could enable pinmux hog %s\n", | ||
1700 | u300_mux_hogs[i].name); | ||
1701 | continue; | ||
1702 | } | ||
1703 | u300_mux_hogs[i].pmx = pmx; | ||
1704 | } | ||
1705 | return 0; | ||
1706 | } | ||
1707 | subsys_initcall(u300_pinmux_fetch); | ||
1708 | |||
1633 | /* | 1709 | /* |
1634 | * Notice that AMBA devices are initialized before platform devices. | 1710 | * Notice that AMBA devices are initialized before platform devices. |
1635 | * | 1711 | * |
@@ -1643,10 +1719,10 @@ static struct platform_device *platform_devs[] __initdata = { | |||
1643 | &gpio_device, | 1719 | &gpio_device, |
1644 | &nand_device, | 1720 | &nand_device, |
1645 | &wdog_device, | 1721 | &wdog_device, |
1646 | &ave_device | 1722 | &ave_device, |
1723 | &pinmux_device, | ||
1647 | }; | 1724 | }; |
1648 | 1725 | ||
1649 | |||
1650 | /* | 1726 | /* |
1651 | * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected | 1727 | * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected |
1652 | * together so some interrupts are connected to the first one and some | 1728 | * together so some interrupts are connected to the first one and some |
@@ -1828,6 +1904,10 @@ void __init u300_init_devices(void) | |||
1828 | 1904 | ||
1829 | u300_assign_physmem(); | 1905 | u300_assign_physmem(); |
1830 | 1906 | ||
1907 | /* Initialize pinmuxing */ | ||
1908 | pinmux_register_mappings(u300_pinmux_map, | ||
1909 | ARRAY_SIZE(u300_pinmux_map)); | ||
1910 | |||
1831 | /* Register subdevices on the I2C buses */ | 1911 | /* Register subdevices on the I2C buses */ |
1832 | u300_i2c_register_board_devices(); | 1912 | u300_i2c_register_board_devices(); |
1833 | 1913 | ||
diff --git a/arch/arm/mach-u300/include/mach/syscon.h b/arch/arm/mach-u300/include/mach/syscon.h index 7444f5c7da9..6e84f07a7c6 100644 --- a/arch/arm/mach-u300/include/mach/syscon.h +++ b/arch/arm/mach-u300/include/mach/syscon.h | |||
@@ -234,91 +234,6 @@ | |||
234 | #define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004) | 234 | #define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004) |
235 | #define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002) | 235 | #define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002) |
236 | #define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001) | 236 | #define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001) |
237 | /* PAD MUX Control register 1 (LOW) 16bit (R/W) */ | ||
238 | #define U300_SYSCON_PMC1LR (0x007C) | ||
239 | #define U300_SYSCON_PMC1LR_MASK (0xFFFF) | ||
240 | #define U300_SYSCON_PMC1LR_CDI_MASK (0xC000) | ||
241 | #define U300_SYSCON_PMC1LR_CDI_CDI (0x0000) | ||
242 | #define U300_SYSCON_PMC1LR_CDI_EMIF (0x4000) | ||
243 | #ifdef CONFIG_MACH_U300_BS335 | ||
244 | #define U300_SYSCON_PMC1LR_CDI_CDI2 (0x8000) | ||
245 | #define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO (0xC000) | ||
246 | #elif CONFIG_MACH_U300_BS365 | ||
247 | #define U300_SYSCON_PMC1LR_CDI_GPIO (0x8000) | ||
248 | #define U300_SYSCON_PMC1LR_CDI_WCDMA (0xC000) | ||
249 | #endif | ||
250 | #define U300_SYSCON_PMC1LR_PDI_MASK (0x3000) | ||
251 | #define U300_SYSCON_PMC1LR_PDI_PDI (0x0000) | ||
252 | #define U300_SYSCON_PMC1LR_PDI_EGG (0x1000) | ||
253 | #define U300_SYSCON_PMC1LR_PDI_WCDMA (0x3000) | ||
254 | #define U300_SYSCON_PMC1LR_MMCSD_MASK (0x0C00) | ||
255 | #define U300_SYSCON_PMC1LR_MMCSD_MMCSD (0x0000) | ||
256 | #define U300_SYSCON_PMC1LR_MMCSD_MSPRO (0x0400) | ||
257 | #define U300_SYSCON_PMC1LR_MMCSD_DSP (0x0800) | ||
258 | #define U300_SYSCON_PMC1LR_MMCSD_WCDMA (0x0C00) | ||
259 | #define U300_SYSCON_PMC1LR_ETM_MASK (0x0300) | ||
260 | #define U300_SYSCON_PMC1LR_ETM_ACC (0x0000) | ||
261 | #define U300_SYSCON_PMC1LR_ETM_APP (0x0100) | ||
262 | #define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK (0x00C0) | ||
263 | #define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC (0x0000) | ||
264 | #define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF (0x0040) | ||
265 | #define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM (0x0080) | ||
266 | #define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB (0x00C0) | ||
267 | #define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK (0x0030) | ||
268 | #define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC (0x0000) | ||
269 | #define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF (0x0010) | ||
270 | #define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM (0x0020) | ||
271 | #define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI (0x0030) | ||
272 | #define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK (0x000C) | ||
273 | #define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC (0x0000) | ||
274 | #define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF (0x0004) | ||
275 | #define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM (0x0008) | ||
276 | #define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI (0x000C) | ||
277 | #define U300_SYSCON_PMC1LR_EMIF_1_MASK (0x0003) | ||
278 | #define U300_SYSCON_PMC1LR_EMIF_1_STATIC (0x0000) | ||
279 | #define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 (0x0001) | ||
280 | #define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 (0x0002) | ||
281 | #define U300_SYSCON_PMC1LR_EMIF_1 (0x0003) | ||
282 | /* PAD MUX Control register 2 (HIGH) 16bit (R/W) */ | ||
283 | #define U300_SYSCON_PMC1HR (0x007E) | ||
284 | #define U300_SYSCON_PMC1HR_MASK (0xFFFF) | ||
285 | #define U300_SYSCON_PMC1HR_MISC_2_MASK (0xC000) | ||
286 | #define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO (0x0000) | ||
287 | #define U300_SYSCON_PMC1HR_MISC_2_MSPRO (0x4000) | ||
288 | #define U300_SYSCON_PMC1HR_MISC_2_DSP (0x8000) | ||
289 | #define U300_SYSCON_PMC1HR_MISC_2_AAIF (0xC000) | ||
290 | #define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK (0x3000) | ||
291 | #define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO (0x0000) | ||
292 | #define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF (0x1000) | ||
293 | #define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP (0x2000) | ||
294 | #define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF (0x3000) | ||
295 | #define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK (0x0C00) | ||
296 | #define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO (0x0000) | ||
297 | #define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC (0x0400) | ||
298 | #define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP (0x0800) | ||
299 | #define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF (0x0C00) | ||
300 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK (0x0300) | ||
301 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO (0x0000) | ||
302 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI (0x0100) | ||
303 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF (0x0300) | ||
304 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK (0x00C0) | ||
305 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO (0x0000) | ||
306 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI (0x0040) | ||
307 | #define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF (0x00C0) | ||
308 | #define U300_SYSCON_PMC1HR_APP_SPI_2_MASK (0x0030) | ||
309 | #define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO (0x0000) | ||
310 | #define U300_SYSCON_PMC1HR_APP_SPI_2_SPI (0x0010) | ||
311 | #define U300_SYSCON_PMC1HR_APP_SPI_2_DSP (0x0020) | ||
312 | #define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF (0x0030) | ||
313 | #define U300_SYSCON_PMC1HR_APP_UART0_2_MASK (0x000C) | ||
314 | #define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO (0x0000) | ||
315 | #define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 (0x0004) | ||
316 | #define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS (0x0008) | ||
317 | #define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF (0x000C) | ||
318 | #define U300_SYSCON_PMC1HR_APP_UART0_1_MASK (0x0003) | ||
319 | #define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO (0x0000) | ||
320 | #define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 (0x0001) | ||
321 | #define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF (0x0003) | ||
322 | /* Step one for killing the applications system 16bit (-/W) */ | 237 | /* Step one for killing the applications system 16bit (-/W) */ |
323 | #define U300_SYSCON_KA1R (0x0080) | 238 | #define U300_SYSCON_KA1R (0x0080) |
324 | #define U300_SYSCON_KA1R_MASK (0xFFFF) | 239 | #define U300_SYSCON_KA1R_MASK (0xFFFF) |
@@ -357,57 +272,6 @@ | |||
357 | #define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080) | 272 | #define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080) |
358 | #define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040) | 273 | #define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040) |
359 | #define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK (0x003F) | 274 | #define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK (0x003F) |
360 | /* Padmux 2 control */ | ||
361 | #define U300_SYSCON_PMC2R (0x100) | ||
362 | #define U300_SYSCON_PMC2R_APP_MISC_0_MASK (0x00C0) | ||
363 | #define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO (0x0000) | ||
364 | #define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM (0x0040) | ||
365 | #define U300_SYSCON_PMC2R_APP_MISC_0_MMC (0x0080) | ||
366 | #define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 (0x00C0) | ||
367 | #define U300_SYSCON_PMC2R_APP_MISC_1_MASK (0x0300) | ||
368 | #define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO (0x0000) | ||
369 | #define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM (0x0100) | ||
370 | #define U300_SYSCON_PMC2R_APP_MISC_1_MMC (0x0200) | ||
371 | #define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 (0x0300) | ||
372 | #define U300_SYSCON_PMC2R_APP_MISC_2_MASK (0x0C00) | ||
373 | #define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO (0x0000) | ||
374 | #define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM (0x0400) | ||
375 | #define U300_SYSCON_PMC2R_APP_MISC_2_MMC (0x0800) | ||
376 | #define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 (0x0C00) | ||
377 | #define U300_SYSCON_PMC2R_APP_MISC_3_MASK (0x3000) | ||
378 | #define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO (0x0000) | ||
379 | #define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM (0x1000) | ||
380 | #define U300_SYSCON_PMC2R_APP_MISC_3_MMC (0x2000) | ||
381 | #define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 (0x3000) | ||
382 | #define U300_SYSCON_PMC2R_APP_MISC_4_MASK (0xC000) | ||
383 | #define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO (0x0000) | ||
384 | #define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM (0x4000) | ||
385 | #define U300_SYSCON_PMC2R_APP_MISC_4_MMC (0x8000) | ||
386 | #define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO (0xC000) | ||
387 | /* TODO: More SYSCON registers missing */ | ||
388 | #define U300_SYSCON_PMC3R (0x10c) | ||
389 | #define U300_SYSCON_PMC3R_APP_MISC_11_MASK (0xc000) | ||
390 | #define U300_SYSCON_PMC3R_APP_MISC_11_SPI (0x4000) | ||
391 | #define U300_SYSCON_PMC3R_APP_MISC_10_MASK (0x3000) | ||
392 | #define U300_SYSCON_PMC3R_APP_MISC_10_SPI (0x1000) | ||
393 | /* TODO: Missing other configs */ | ||
394 | #define U300_SYSCON_PMC4R (0x168) | ||
395 | #define U300_SYSCON_PMC4R_APP_MISC_12_MASK (0x0003) | ||
396 | #define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO (0x0000) | ||
397 | #define U300_SYSCON_PMC4R_APP_MISC_13_MASK (0x000C) | ||
398 | #define U300_SYSCON_PMC4R_APP_MISC_13_CDI (0x0000) | ||
399 | #define U300_SYSCON_PMC4R_APP_MISC_13_SMIA (0x0004) | ||
400 | #define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 (0x0008) | ||
401 | #define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO (0x000C) | ||
402 | #define U300_SYSCON_PMC4R_APP_MISC_14_MASK (0x0030) | ||
403 | #define U300_SYSCON_PMC4R_APP_MISC_14_CDI (0x0000) | ||
404 | #define U300_SYSCON_PMC4R_APP_MISC_14_SMIA (0x0010) | ||
405 | #define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 (0x0020) | ||
406 | #define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO (0x0030) | ||
407 | #define U300_SYSCON_PMC4R_APP_MISC_16_MASK (0x0300) | ||
408 | #define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 (0x0000) | ||
409 | #define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS (0x0100) | ||
410 | #define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N (0x0200) | ||
411 | /* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */ | 275 | /* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */ |
412 | #define U300_SYSCON_S0CCR (0x120) | 276 | #define U300_SYSCON_S0CCR (0x120) |
413 | #define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF) | 277 | #define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF) |
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index 677ccef5cd3..d5e4a98a9ab 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <mach/dma_channels.h> | 21 | #include <mach/dma_channels.h> |
22 | 22 | ||
23 | #include "mmc.h" | 23 | #include "mmc.h" |
24 | #include "padmux.h" | ||
25 | 24 | ||
26 | static struct mmci_platform_data mmc0_plat_data = { | 25 | static struct mmci_platform_data mmc0_plat_data = { |
27 | /* | 26 | /* |
@@ -45,24 +44,9 @@ static struct mmci_platform_data mmc0_plat_data = { | |||
45 | int __devinit mmc_init(struct amba_device *adev) | 44 | int __devinit mmc_init(struct amba_device *adev) |
46 | { | 45 | { |
47 | struct device *mmcsd_device = &adev->dev; | 46 | struct device *mmcsd_device = &adev->dev; |
48 | struct pmx *pmx; | ||
49 | int ret = 0; | 47 | int ret = 0; |
50 | 48 | ||
51 | mmcsd_device->platform_data = &mmc0_plat_data; | 49 | mmcsd_device->platform_data = &mmc0_plat_data; |
52 | 50 | ||
53 | /* | ||
54 | * Setup padmuxing for MMC. Since this must always be | ||
55 | * compiled into the kernel, pmx is never released. | ||
56 | */ | ||
57 | pmx = pmx_get(mmcsd_device, U300_APP_PMX_MMC_SETTING); | ||
58 | |||
59 | if (IS_ERR(pmx)) | ||
60 | pr_warning("Could not get padmux handle\n"); | ||
61 | else { | ||
62 | ret = pmx_activate(mmcsd_device, pmx); | ||
63 | if (IS_ERR_VALUE(ret)) | ||
64 | pr_warning("Could not activate padmuxing\n"); | ||
65 | } | ||
66 | |||
67 | return ret; | 51 | return ret; |
68 | } | 52 | } |
diff --git a/arch/arm/mach-u300/padmux.c b/arch/arm/mach-u300/padmux.c deleted file mode 100644 index 4c93c6cefd3..00000000000 --- a/arch/arm/mach-u300/padmux.c +++ /dev/null | |||
@@ -1,367 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * arch/arm/mach-u300/padmux.c | ||
4 | * | ||
5 | * | ||
6 | * Copyright (C) 2009 ST-Ericsson AB | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | * U300 PADMUX functions | ||
9 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/bug.h> | ||
21 | #include <linux/debugfs.h> | ||
22 | #include <linux/seq_file.h> | ||
23 | #include <mach/u300-regs.h> | ||
24 | #include <mach/syscon.h> | ||
25 | #include "padmux.h" | ||
26 | |||
27 | static DEFINE_MUTEX(pmx_mutex); | ||
28 | |||
29 | const u32 pmx_registers[] = { | ||
30 | (U300_SYSCON_VBASE + U300_SYSCON_PMC1LR), | ||
31 | (U300_SYSCON_VBASE + U300_SYSCON_PMC1HR), | ||
32 | (U300_SYSCON_VBASE + U300_SYSCON_PMC2R), | ||
33 | (U300_SYSCON_VBASE + U300_SYSCON_PMC3R), | ||
34 | (U300_SYSCON_VBASE + U300_SYSCON_PMC4R) | ||
35 | }; | ||
36 | |||
37 | /* High level functionality */ | ||
38 | |||
39 | /* Lazy dog: | ||
40 | * onmask = { | ||
41 | * {"PMC1LR" mask, "PMC1LR" value}, | ||
42 | * {"PMC1HR" mask, "PMC1HR" value}, | ||
43 | * {"PMC2R" mask, "PMC2R" value}, | ||
44 | * {"PMC3R" mask, "PMC3R" value}, | ||
45 | * {"PMC4R" mask, "PMC4R" value} | ||
46 | * } | ||
47 | */ | ||
48 | static struct pmx mmc_setting = { | ||
49 | .setting = U300_APP_PMX_MMC_SETTING, | ||
50 | .default_on = false, | ||
51 | .activated = false, | ||
52 | .name = "MMC", | ||
53 | .onmask = { | ||
54 | {U300_SYSCON_PMC1LR_MMCSD_MASK, | ||
55 | U300_SYSCON_PMC1LR_MMCSD_MMCSD}, | ||
56 | {0, 0}, | ||
57 | {0, 0}, | ||
58 | {0, 0}, | ||
59 | {U300_SYSCON_PMC4R_APP_MISC_12_MASK, | ||
60 | U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO} | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static struct pmx spi_setting = { | ||
65 | .setting = U300_APP_PMX_SPI_SETTING, | ||
66 | .default_on = false, | ||
67 | .activated = false, | ||
68 | .name = "SPI", | ||
69 | .onmask = {{0, 0}, | ||
70 | {U300_SYSCON_PMC1HR_APP_SPI_2_MASK | | ||
71 | U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK | | ||
72 | U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK, | ||
73 | U300_SYSCON_PMC1HR_APP_SPI_2_SPI | | ||
74 | U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI | | ||
75 | U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI}, | ||
76 | {0, 0}, | ||
77 | {0, 0}, | ||
78 | {0, 0} | ||
79 | }, | ||
80 | }; | ||
81 | |||
82 | /* Available padmux settings */ | ||
83 | static struct pmx *pmx_settings[] = { | ||
84 | &mmc_setting, | ||
85 | &spi_setting, | ||
86 | }; | ||
87 | |||
88 | static void update_registers(struct pmx *pmx, bool activate) | ||
89 | { | ||
90 | u16 regval, val, mask; | ||
91 | int i; | ||
92 | |||
93 | for (i = 0; i < ARRAY_SIZE(pmx_registers); i++) { | ||
94 | if (activate) | ||
95 | val = pmx->onmask[i].val; | ||
96 | else | ||
97 | val = 0; | ||
98 | |||
99 | mask = pmx->onmask[i].mask; | ||
100 | if (mask != 0) { | ||
101 | regval = readw(pmx_registers[i]); | ||
102 | regval &= ~mask; | ||
103 | regval |= val; | ||
104 | writew(regval, pmx_registers[i]); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | struct pmx *pmx_get(struct device *dev, enum pmx_settings setting) | ||
110 | { | ||
111 | int i; | ||
112 | struct pmx *pmx = ERR_PTR(-ENOENT); | ||
113 | |||
114 | if (dev == NULL) | ||
115 | return ERR_PTR(-EINVAL); | ||
116 | |||
117 | mutex_lock(&pmx_mutex); | ||
118 | for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { | ||
119 | |||
120 | if (setting == pmx_settings[i]->setting) { | ||
121 | |||
122 | if (pmx_settings[i]->dev != NULL) { | ||
123 | WARN(1, "padmux: required setting " | ||
124 | "in use by another consumer\n"); | ||
125 | } else { | ||
126 | pmx = pmx_settings[i]; | ||
127 | pmx->dev = dev; | ||
128 | dev_dbg(dev, "padmux: setting nr %d is now " | ||
129 | "bound to %s and ready to use\n", | ||
130 | setting, dev_name(dev)); | ||
131 | break; | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | mutex_unlock(&pmx_mutex); | ||
136 | |||
137 | return pmx; | ||
138 | } | ||
139 | EXPORT_SYMBOL(pmx_get); | ||
140 | |||
141 | int pmx_put(struct device *dev, struct pmx *pmx) | ||
142 | { | ||
143 | int i; | ||
144 | int ret = -ENOENT; | ||
145 | |||
146 | if (pmx == NULL || dev == NULL) | ||
147 | return -EINVAL; | ||
148 | |||
149 | mutex_lock(&pmx_mutex); | ||
150 | for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { | ||
151 | |||
152 | if (pmx->setting == pmx_settings[i]->setting) { | ||
153 | |||
154 | if (dev != pmx->dev) { | ||
155 | WARN(1, "padmux: cannot release handle as " | ||
156 | "it is bound to another consumer\n"); | ||
157 | ret = -EINVAL; | ||
158 | break; | ||
159 | } else { | ||
160 | pmx_settings[i]->dev = NULL; | ||
161 | ret = 0; | ||
162 | break; | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | mutex_unlock(&pmx_mutex); | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | EXPORT_SYMBOL(pmx_put); | ||
171 | |||
172 | int pmx_activate(struct device *dev, struct pmx *pmx) | ||
173 | { | ||
174 | int i, j, ret; | ||
175 | ret = 0; | ||
176 | |||
177 | if (pmx == NULL || dev == NULL) | ||
178 | return -EINVAL; | ||
179 | |||
180 | mutex_lock(&pmx_mutex); | ||
181 | |||
182 | /* Make sure the required bits are not used */ | ||
183 | for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { | ||
184 | |||
185 | if (pmx_settings[i]->dev == NULL || pmx_settings[i] == pmx) | ||
186 | continue; | ||
187 | |||
188 | for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) { | ||
189 | |||
190 | if (pmx_settings[i]->onmask[j].mask & pmx-> | ||
191 | onmask[j].mask) { | ||
192 | /* More than one entry on the same bits */ | ||
193 | WARN(1, "padmux: cannot activate " | ||
194 | "setting. Bit conflict with " | ||
195 | "an active setting\n"); | ||
196 | |||
197 | ret = -EUSERS; | ||
198 | goto exit; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | update_registers(pmx, true); | ||
203 | pmx->activated = true; | ||
204 | dev_dbg(dev, "padmux: setting nr %d is activated\n", | ||
205 | pmx->setting); | ||
206 | |||
207 | exit: | ||
208 | mutex_unlock(&pmx_mutex); | ||
209 | return ret; | ||
210 | } | ||
211 | EXPORT_SYMBOL(pmx_activate); | ||
212 | |||
213 | int pmx_deactivate(struct device *dev, struct pmx *pmx) | ||
214 | { | ||
215 | int i; | ||
216 | int ret = -ENOENT; | ||
217 | |||
218 | if (pmx == NULL || dev == NULL) | ||
219 | return -EINVAL; | ||
220 | |||
221 | mutex_lock(&pmx_mutex); | ||
222 | for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { | ||
223 | |||
224 | if (pmx_settings[i]->dev == NULL) | ||
225 | continue; | ||
226 | |||
227 | if (pmx->setting == pmx_settings[i]->setting) { | ||
228 | |||
229 | if (dev != pmx->dev) { | ||
230 | WARN(1, "padmux: cannot deactivate " | ||
231 | "pmx setting as it was activated " | ||
232 | "by another consumer\n"); | ||
233 | |||
234 | ret = -EBUSY; | ||
235 | continue; | ||
236 | } else { | ||
237 | update_registers(pmx, false); | ||
238 | pmx_settings[i]->dev = NULL; | ||
239 | pmx->activated = false; | ||
240 | ret = 0; | ||
241 | dev_dbg(dev, "padmux: setting nr %d is deactivated", | ||
242 | pmx->setting); | ||
243 | break; | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | mutex_unlock(&pmx_mutex); | ||
248 | |||
249 | return ret; | ||
250 | } | ||
251 | EXPORT_SYMBOL(pmx_deactivate); | ||
252 | |||
253 | /* | ||
254 | * For internal use only. If it is to be exported, | ||
255 | * it should be reentrant. Notice that pmx_activate | ||
256 | * (i.e. runtime settings) always override default settings. | ||
257 | */ | ||
258 | static int pmx_set_default(void) | ||
259 | { | ||
260 | /* Used to identify several entries on the same bits */ | ||
261 | u16 modbits[ARRAY_SIZE(pmx_registers)]; | ||
262 | |||
263 | int i, j; | ||
264 | |||
265 | memset(modbits, 0, ARRAY_SIZE(pmx_registers) * sizeof(u16)); | ||
266 | |||
267 | for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { | ||
268 | |||
269 | if (!pmx_settings[i]->default_on) | ||
270 | continue; | ||
271 | |||
272 | for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) { | ||
273 | |||
274 | /* Make sure there is only one entry on the same bits */ | ||
275 | if (modbits[j] & pmx_settings[i]->onmask[j].mask) { | ||
276 | BUG(); | ||
277 | return -EUSERS; | ||
278 | } | ||
279 | modbits[j] |= pmx_settings[i]->onmask[j].mask; | ||
280 | } | ||
281 | update_registers(pmx_settings[i], true); | ||
282 | } | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG)) | ||
287 | static int pmx_show(struct seq_file *s, void *data) | ||
288 | { | ||
289 | int i; | ||
290 | seq_printf(s, "-------------------------------------------------\n"); | ||
291 | seq_printf(s, "SETTING BOUND TO DEVICE STATE\n"); | ||
292 | seq_printf(s, "-------------------------------------------------\n"); | ||
293 | mutex_lock(&pmx_mutex); | ||
294 | for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) { | ||
295 | /* Format pmx and device name nicely */ | ||
296 | char cdp[33]; | ||
297 | int chars; | ||
298 | |||
299 | chars = snprintf(&cdp[0], 17, "%s", pmx_settings[i]->name); | ||
300 | while (chars < 16) { | ||
301 | cdp[chars] = ' '; | ||
302 | chars++; | ||
303 | } | ||
304 | chars = snprintf(&cdp[16], 17, "%s", pmx_settings[i]->dev ? | ||
305 | dev_name(pmx_settings[i]->dev) : "N/A"); | ||
306 | while (chars < 16) { | ||
307 | cdp[chars+16] = ' '; | ||
308 | chars++; | ||
309 | } | ||
310 | cdp[32] = '\0'; | ||
311 | |||
312 | seq_printf(s, | ||
313 | "%s\t%s\n", | ||
314 | &cdp[0], | ||
315 | pmx_settings[i]->activated ? | ||
316 | "ACTIVATED" : "DEACTIVATED" | ||
317 | ); | ||
318 | |||
319 | } | ||
320 | mutex_unlock(&pmx_mutex); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int pmx_open(struct inode *inode, struct file *file) | ||
325 | { | ||
326 | return single_open(file, pmx_show, NULL); | ||
327 | } | ||
328 | |||
329 | static const struct file_operations pmx_operations = { | ||
330 | .owner = THIS_MODULE, | ||
331 | .open = pmx_open, | ||
332 | .read = seq_read, | ||
333 | .llseek = seq_lseek, | ||
334 | .release = single_release, | ||
335 | }; | ||
336 | |||
337 | static int __init init_pmx_read_debugfs(void) | ||
338 | { | ||
339 | /* Expose a simple debugfs interface to view pmx settings */ | ||
340 | (void) debugfs_create_file("padmux", S_IFREG | S_IRUGO, | ||
341 | NULL, NULL, | ||
342 | &pmx_operations); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * This needs to come in after the core_initcall(), | ||
348 | * because debugfs is not available until | ||
349 | * the subsystems come up. | ||
350 | */ | ||
351 | module_init(init_pmx_read_debugfs); | ||
352 | #endif | ||
353 | |||
354 | static int __init pmx_init(void) | ||
355 | { | ||
356 | int ret; | ||
357 | |||
358 | ret = pmx_set_default(); | ||
359 | |||
360 | if (IS_ERR_VALUE(ret)) | ||
361 | pr_crit("padmux: default settings could not be set\n"); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | /* Should be initialized before consumers */ | ||
367 | core_initcall(pmx_init); | ||
diff --git a/arch/arm/mach-u300/padmux.h b/arch/arm/mach-u300/padmux.h deleted file mode 100644 index 6e8b8606409..00000000000 --- a/arch/arm/mach-u300/padmux.h +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * arch/arm/mach-u300/padmux.h | ||
4 | * | ||
5 | * | ||
6 | * Copyright (C) 2009 ST-Ericsson AB | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | * U300 PADMUX API | ||
9 | * Author: Martin Persson <martin.persson@stericsson.com> | ||
10 | */ | ||
11 | |||
12 | #ifndef __MACH_U300_PADMUX_H | ||
13 | #define __MACH_U300_PADMUX_H | ||
14 | |||
15 | enum pmx_settings { | ||
16 | U300_APP_PMX_MMC_SETTING, | ||
17 | U300_APP_PMX_SPI_SETTING | ||
18 | }; | ||
19 | |||
20 | struct pmx_onmask { | ||
21 | u16 mask; /* Mask bits */ | ||
22 | u16 val; /* Value when active */ | ||
23 | }; | ||
24 | |||
25 | struct pmx { | ||
26 | struct device *dev; | ||
27 | enum pmx_settings setting; | ||
28 | char *name; | ||
29 | bool activated; | ||
30 | bool default_on; | ||
31 | struct pmx_onmask onmask[]; | ||
32 | }; | ||
33 | |||
34 | struct pmx *pmx_get(struct device *dev, enum pmx_settings setting); | ||
35 | int pmx_put(struct device *dev, struct pmx *pmx); | ||
36 | int pmx_activate(struct device *dev, struct pmx *pmx); | ||
37 | int pmx_deactivate(struct device *dev, struct pmx *pmx); | ||
38 | |||
39 | #endif | ||
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c index 7b597e2b19e..a1affacfa59 100644 --- a/arch/arm/mach-u300/spi.c +++ b/arch/arm/mach-u300/spi.c | |||
@@ -14,8 +14,6 @@ | |||
14 | #include <mach/coh901318.h> | 14 | #include <mach/coh901318.h> |
15 | #include <mach/dma_channels.h> | 15 | #include <mach/dma_channels.h> |
16 | 16 | ||
17 | #include "padmux.h" | ||
18 | |||
19 | /* | 17 | /* |
20 | * The following is for the actual devices on the SSP/SPI bus | 18 | * The following is for the actual devices on the SSP/SPI bus |
21 | */ | 19 | */ |
@@ -95,25 +93,7 @@ static struct pl022_ssp_controller ssp_platform_data = { | |||
95 | 93 | ||
96 | void __init u300_spi_init(struct amba_device *adev) | 94 | void __init u300_spi_init(struct amba_device *adev) |
97 | { | 95 | { |
98 | struct pmx *pmx; | ||
99 | |||
100 | adev->dev.platform_data = &ssp_platform_data; | 96 | adev->dev.platform_data = &ssp_platform_data; |
101 | /* | ||
102 | * Setup padmuxing for SPI. Since this must always be | ||
103 | * compiled into the kernel, pmx is never released. | ||
104 | */ | ||
105 | pmx = pmx_get(&adev->dev, U300_APP_PMX_SPI_SETTING); | ||
106 | |||
107 | if (IS_ERR(pmx)) | ||
108 | dev_warn(&adev->dev, "Could not get padmux handle\n"); | ||
109 | else { | ||
110 | int ret; | ||
111 | |||
112 | ret = pmx_activate(&adev->dev, pmx); | ||
113 | if (IS_ERR_VALUE(ret)) | ||
114 | dev_warn(&adev->dev, "Could not activate padmuxing\n"); | ||
115 | } | ||
116 | |||
117 | } | 97 | } |
118 | 98 | ||
119 | void __init u300_spi_register_board_devices(void) | 99 | void __init u300_spi_register_board_devices(void) |