Commit c9d6329c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-next' of git://git.linaro.org/people/triad/linux-pinctrl

* 'for-next' of git://git.linaro.org/people/triad/linux-pinctrl:
  pinctrl/sirf: fix sirfsoc_get_group_pins prototype
  pinctrl: Don't copy function name when requesting a pin
  pinctrl: Don't copy pin names when registering them
  pinctrl: Remove unsafe __refdata
  pinctrl: get_group_pins() const fixes
  pinctrl: add a driver for the CSR SiRFprimaII pinmux
  pinctrl: add a driver for the U300 pinmux
  drivers: create a pin control subsystem
parents 4e7e2a20 ad7761ab
This diff is collapsed.
...@@ -5042,6 +5042,11 @@ L: linux-mtd@lists.infradead.org ...@@ -5042,6 +5042,11 @@ L: linux-mtd@lists.infradead.org
S: Maintained S: Maintained
F: drivers/mtd/devices/phram.c F: drivers/mtd/devices/phram.c
PIN CONTROL SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
F: drivers/pinmux/
PKTCDVD DRIVER PKTCDVD DRIVER
M: Peter Osterlund <petero2@telia.com> M: Peter Osterlund <petero2@telia.com>
S: Maintained S: Maintained
......
...@@ -6,6 +6,8 @@ comment "ST-Ericsson Mobile Platform Products" ...@@ -6,6 +6,8 @@ comment "ST-Ericsson Mobile Platform Products"
config MACH_U300 config MACH_U300
bool "U300" bool "U300"
select PINCTRL
select PINMUX_U300
comment "ST-Ericsson U300/U330/U335/U365 Feature Selections" comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the linux kernel, U300 machine. # Makefile for the linux kernel, U300 machine.
# #
obj-y := core.o clock.o timer.o padmux.o obj-y := core.o clock.o timer.o
obj-m := obj-m :=
obj-n := obj-n :=
obj- := obj- :=
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h> #include <linux/mtd/fsmc.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -1535,6 +1537,14 @@ static struct coh901318_platform coh901318_platform = { ...@@ -1535,6 +1537,14 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS, .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 = { static struct platform_device wdog_device = {
.name = "coh901327_wdog", .name = "coh901327_wdog",
.id = -1, .id = -1,
...@@ -1630,6 +1640,72 @@ static struct platform_device dma_device = { ...@@ -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. * Notice that AMBA devices are initialized before platform devices.
* *
...@@ -1643,10 +1719,10 @@ static struct platform_device *platform_devs[] __initdata = { ...@@ -1643,10 +1719,10 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device, &gpio_device,
&nand_device, &nand_device,
&wdog_device, &wdog_device,
&ave_device &ave_device,
&pinmux_device,
}; };
/* /*
* Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
* together so some interrupts are connected to the first one and some * together so some interrupts are connected to the first one and some
...@@ -1828,6 +1904,10 @@ void __init u300_init_devices(void) ...@@ -1828,6 +1904,10 @@ void __init u300_init_devices(void)
u300_assign_physmem(); u300_assign_physmem();
/* Initialize pinmuxing */
pinmux_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map));
/* Register subdevices on the I2C buses */ /* Register subdevices on the I2C buses */
u300_i2c_register_board_devices(); u300_i2c_register_board_devices();
......
...@@ -234,91 +234,6 @@ ...@@ -234,91 +234,6 @@
#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004) #define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004)
#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002) #define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002)
#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001) #define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001)
/* PAD MUX Control register 1 (LOW) 16bit (R/W) */
#define U300_SYSCON_PMC1LR (0x007C)
#define U300_SYSCON_PMC1LR_MASK (0xFFFF)
#define U300_SYSCON_PMC1LR_CDI_MASK (0xC000)
#define U300_SYSCON_PMC1LR_CDI_CDI (0x0000)
#define U300_SYSCON_PMC1LR_CDI_EMIF (0x4000)
#ifdef CONFIG_MACH_U300_BS335
#define U300_SYSCON_PMC1LR_CDI_CDI2 (0x8000)
#define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO (0xC000)
#elif CONFIG_MACH_U300_BS365
#define U300_SYSCON_PMC1LR_CDI_GPIO (0x8000)
#define U300_SYSCON_PMC1LR_CDI_WCDMA (0xC000)
#endif
#define U300_SYSCON_PMC1LR_PDI_MASK (0x3000)
#define U300_SYSCON_PMC1LR_PDI_PDI (0x0000)
#define U300_SYSCON_PMC1LR_PDI_EGG (0x1000)
#define U300_SYSCON_PMC1LR_PDI_WCDMA (0x3000)
#define U300_SYSCON_PMC1LR_MMCSD_MASK (0x0C00)
#define U300_SYSCON_PMC1LR_MMCSD_MMCSD (0x0000)
#define U300_SYSCON_PMC1LR_MMCSD_MSPRO (0x0400)
#define U300_SYSCON_PMC1LR_MMCSD_DSP (0x0800)
#define U300_SYSCON_PMC1LR_MMCSD_WCDMA (0x0C00)
#define U300_SYSCON_PMC1LR_ETM_MASK (0x0300)
#define U300_SYSCON_PMC1LR_ETM_ACC (0x0000)
#define U300_SYSCON_PMC1LR_ETM_APP (0x0100)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK (0x00C0)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF (0x0040)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM (0x0080)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB (0x00C0)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK (0x0030)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF (0x0010)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM (0x0020)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI (0x0030)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK (0x000C)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF (0x0004)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM (0x0008)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI (0x000C)
#define U300_SYSCON_PMC1LR_EMIF_1_MASK (0x0003)
#define U300_SYSCON_PMC1LR_EMIF_1_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 (0x0001)
#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 (0x0002)
#define U300_SYSCON_PMC1LR_EMIF_1 (0x0003)
/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */
#define U300_SYSCON_PMC1HR (0x007E)
#define U300_SYSCON_PMC1HR_MASK (0xFFFF)
#define U300_SYSCON_PMC1HR_MISC_2_MASK (0xC000)
#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_MISC_2_MSPRO (0x4000)
#define U300_SYSCON_PMC1HR_MISC_2_DSP (0x8000)
#define U300_SYSCON_PMC1HR_MISC_2_AAIF (0xC000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK (0x3000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF (0x1000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP (0x2000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF (0x3000)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK (0x0C00)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC (0x0400)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP (0x0800)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF (0x0C00)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK (0x0300)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI (0x0100)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF (0x0300)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK (0x00C0)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI (0x0040)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF (0x00C0)
#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK (0x0030)
#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI (0x0010)
#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP (0x0020)
#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF (0x0030)
#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK (0x000C)
#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 (0x0004)
#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS (0x0008)
#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF (0x000C)
#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK (0x0003)
#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 (0x0001)
#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF (0x0003)
/* Step one for killing the applications system 16bit (-/W) */ /* Step one for killing the applications system 16bit (-/W) */
#define U300_SYSCON_KA1R (0x0080) #define U300_SYSCON_KA1R (0x0080)
#define U300_SYSCON_KA1R_MASK (0xFFFF) #define U300_SYSCON_KA1R_MASK (0xFFFF)
...@@ -357,57 +272,6 @@ ...@@ -357,57 +272,6 @@
#define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080) #define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080)
#define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040) #define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040)
#define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK (0x003F) #define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK (0x003F)
/* Padmux 2 control */
#define U300_SYSCON_PMC2R (0x100)
#define U300_SYSCON_PMC2R_APP_MISC_0_MASK (0x00C0)
#define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM (0x0040)
#define U300_SYSCON_PMC2R_APP_MISC_0_MMC (0x0080)
#define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 (0x00C0)
#define U300_SYSCON_PMC2R_APP_MISC_1_MASK (0x0300)
#define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM (0x0100)
#define U300_SYSCON_PMC2R_APP_MISC_1_MMC (0x0200)
#define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 (0x0300)
#define U300_SYSCON_PMC2R_APP_MISC_2_MASK (0x0C00)
#define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM (0x0400)
#define U300_SYSCON_PMC2R_APP_MISC_2_MMC (0x0800)
#define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 (0x0C00)
#define U300_SYSCON_PMC2R_APP_MISC_3_MASK (0x3000)
#define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM (0x1000)
#define U300_SYSCON_PMC2R_APP_MISC_3_MMC (0x2000)
#define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 (0x3000)
#define U300_SYSCON_PMC2R_APP_MISC_4_MASK (0xC000)
#define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM (0x4000)
#define U300_SYSCON_PMC2R_APP_MISC_4_MMC (0x8000)
#define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO (0xC000)
/* TODO: More SYSCON registers missing */
#define U300_SYSCON_PMC3R (0x10c)
#define U300_SYSCON_PMC3R_APP_MISC_11_MASK (0xc000)
#define U300_SYSCON_PMC3R_APP_MISC_11_SPI (0x4000)
#define U300_SYSCON_PMC3R_APP_MISC_10_MASK (0x3000)
#define U300_SYSCON_PMC3R_APP_MISC_10_SPI (0x1000)
/* TODO: Missing other configs */
#define U300_SYSCON_PMC4R (0x168)
#define U300_SYSCON_PMC4R_APP_MISC_12_MASK (0x0003)
#define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_13_MASK (0x000C)
#define U300_SYSCON_PMC4R_APP_MISC_13_CDI (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA (0x0004)
#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 (0x0008)
#define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO (0x000C)
#define U300_SYSCON_PMC4R_APP_MISC_14_MASK (0x0030)
#define U300_SYSCON_PMC4R_APP_MISC_14_CDI (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_14_SMIA (0x0010)
#define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 (0x0020)
#define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO (0x0030)
#define U300_SYSCON_PMC4R_APP_MISC_16_MASK (0x0300)
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS (0x0100)
#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N (0x0200)
/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */ /* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */
#define U300_SYSCON_S0CCR (0x120) #define U300_SYSCON_S0CCR (0x120)
#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF) #define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF)
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <mach/dma_channels.h> #include <mach/dma_channels.h>
#include "mmc.h" #include "mmc.h"
#include "padmux.h"
static struct mmci_platform_data mmc0_plat_data = { static struct mmci_platform_data mmc0_plat_data = {
/* /*
...@@ -45,24 +44,9 @@ static struct mmci_platform_data mmc0_plat_data = { ...@@ -45,24 +44,9 @@ static struct mmci_platform_data mmc0_plat_data = {
int __devinit mmc_init(struct amba_device *adev) int __devinit mmc_init(struct amba_device *adev)
{ {
struct device *mmcsd_device = &adev->dev; struct device *mmcsd_device = &adev->dev;
struct pmx *pmx;
int ret = 0; int ret = 0;
mmcsd_device->platform_data = &mmc0_plat_data; mmcsd_device->platform_data = &mmc0_plat_data;
/*
* Setup padmuxing for MMC. Since this must always be
* compiled into the kernel, pmx is never released.
*/
pmx = pmx_get(mmcsd_device, U300_APP_PMX_MMC_SETTING);
if (IS_ERR(pmx))
pr_warning("Could not get padmux handle\n");
else {
ret = pmx_activate(mmcsd_device, pmx);
if (IS_ERR_VALUE(ret))
pr_warning("Could not activate padmuxing\n");
}
return ret; return ret;
} }
/*
*
* arch/arm/mach-u300/padmux.c
*
*
* Copyright (C) 2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* U300 PADMUX functions
* Author: Martin Persson <martin.persson@stericsson.com>
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/bug.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <mach/u300-regs.h>
#include <mach/syscon.h>
#include "padmux.h"
static DEFINE_MUTEX(pmx_mutex);
const u32 pmx_registers[] = {
(U300_SYSCON_VBASE + U300_SYSCON_PMC1LR),
(U300_SYSCON_VBASE + U300_SYSCON_PMC1HR),
(U300_SYSCON_VBASE + U300_SYSCON_PMC2R),
(U300_SYSCON_VBASE + U300_SYSCON_PMC3R),
(U300_SYSCON_VBASE + U300_SYSCON_PMC4R)
};
/* High level functionality */
/* Lazy dog:
* onmask = {
* {"PMC1LR" mask, "PMC1LR" value},
* {"PMC1HR" mask, "PMC1HR" value},
* {"PMC2R" mask, "PMC2R" value},
* {"PMC3R" mask, "PMC3R" value},
* {"PMC4R" mask, "PMC4R" value}
* }
*/
static struct pmx mmc_setting = {
.setting = U300_APP_PMX_MMC_SETTING,
.default_on = false,
.activated = false,
.name = "MMC",
.onmask = {
{U300_SYSCON_PMC1LR_MMCSD_MASK,
U300_SYSCON_PMC1LR_MMCSD_MMCSD},
{0, 0},
{0, 0},
{0, 0},
{U300_SYSCON_PMC4R_APP_MISC_12_MASK,
U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO}
},
};
static struct pmx spi_setting = {
.setting = U300_APP_PMX_SPI_SETTING,
.default_on = false,
.activated = false,
.name = "SPI",
.onmask = {{0, 0},
{U300_SYSCON_PMC1HR_APP_SPI_2_MASK |
U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK |
U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK,
U300_SYSCON_PMC1HR_APP_SPI_2_SPI |
U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI |
U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI},
{0, 0},
{0, 0},
{0, 0}
},
};
/* Available padmux settings */
static struct pmx *pmx_settings[] = {
&mmc_setting,
&spi_setting,
};
static void update_registers(struct pmx *pmx, bool activate)
{
u16 regval, val, mask;
int i;
for (i = 0; i < ARRAY_SIZE(pmx_registers); i++) {
if (activate)
val = pmx->onmask[i].val;
else
val = 0;
mask = pmx->onmask[i].mask;
if (mask != 0) {
regval = readw(pmx_registers[i]);
regval &= ~mask;
regval |= val;
writew(regval, pmx_registers[i]);
}
}
}
struct pmx *pmx_get(struct device *dev, enum pmx_settings setting)
{
int i;
struct pmx *pmx = ERR_PTR(-ENOENT);
if (dev == NULL)
return ERR_PTR(-EINVAL);
mutex_lock(&pmx_mutex);
for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
if (setting == pmx_settings[i]->setting) {
if (pmx_settings[i]->dev != NULL) {
WARN(1, "padmux: required setting "
"in use by another consumer\n");
} else {
pmx = pmx_settings[i];
pmx->dev = dev;
dev_dbg(dev, "padmux: setting nr %d is now "
"bound to %s and ready to use\n",
setting, dev_name(dev));
break;
}
}
}
mutex_unlock(&pmx_mutex);
return pmx;
}
EXPORT_SYMBOL(pmx_get);
int pmx_put(struct device *dev, struct pmx *pmx)
{
int i;
int ret = -ENOENT;
if (pmx == NULL || dev == NULL)
return -EINVAL;
mutex_lock(&pmx_mutex);
for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
if (pmx->setting == pmx_settings[i]->setting) {
if (dev != pmx->dev) {
WARN(1, "padmux: cannot release handle as "
"it is bound to another consumer\n");
ret = -EINVAL;
break;
} else {
pmx_settings[i]->dev = NULL;
ret = 0;
break;
}
}
}
mutex_unlock(&pmx_mutex);
return ret;
}
EXPORT_SYMBOL(pmx_put);
int pmx_activate(struct device *dev, struct pmx *pmx)
{
int i, j, ret;
ret = 0;
if (pmx == NULL || dev == NULL)
return -EINVAL;
mutex_lock(&pmx_mutex);
/* Make sure the required bits are not used */
for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
if (pmx_settings[i]->dev == NULL || pmx_settings[i] == pmx)
continue;
for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) {
if (pmx_settings[i]->onmask[j].mask & pmx->
onmask[j].mask) {
/* More than one entry on the same bits */
WARN(1, "padmux: cannot activate "
"setting. Bit conflict with "
"an active setting\n");
ret = -EUSERS;
goto exit;
}
}
}
update_registers(pmx, true);
pmx->activated = true;
dev_dbg(dev, "padmux: setting nr %d is activated\n",
pmx->setting);
exit:
mutex_unlock(&pmx_mutex);
return ret;
}
EXPORT_SYMBOL(pmx_activate);
int pmx_deactivate(struct device *dev, struct pmx *pmx)
{
int i;
int ret = -ENOENT;
if (pmx == NULL || dev == NULL)
return -EINVAL;
mutex_lock(&pmx_mutex);
for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
if (pmx_settings[i]->dev == NULL)
continue;
if (pmx->setting == pmx_settings[i]->setting) {
if (dev != pmx->dev) {
WARN(1, "padmux: cannot deactivate "
"pmx setting as it was activated "
"by another consumer\n");
ret = -EBUSY;
continue;
} else {
update_registers(pmx, false);
pmx_settings[i]->dev = NULL;
pmx->activated = false;
ret = 0;
dev_dbg(dev, "padmux: setting nr %d is deactivated",
pmx->setting);
break;
}
}
}
mutex_unlock(&pmx_mutex);
return ret;
}
EXPORT_SYMBOL(pmx_deactivate);
/*
* For internal use only. If it is to be exported,
* it should be reentrant. Notice that pmx_activate
* (i.e. runtime settings) always override default settings.
*/
static int pmx_set_default(void)
{
/* Used to identify several entries on the same bits */
u16 modbits[ARRAY_SIZE(pmx_registers)];
int i, j;
memset(modbits, 0, ARRAY_SIZE(pmx_registers) * sizeof(u16));
for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
if (!pmx_settings[i]->default_on)
continue;
for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) {
/* Make sure there is only one entry on the same bits */
if (modbits[j] & pmx_settings[i]->onmask[j].mask) {
BUG();
return -EUSERS;
}
modbits[j] |= pmx_settings[i]->onmask[j].mask;
}
update_registers(pmx_settings[i], true);
}
return 0;
}
#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
static int pmx_show(struct seq_file *s, void *data)
{
int i;
seq_printf(s, "-------------------------------------------------\n");
seq_printf(s, "SETTING BOUND TO DEVICE STATE\n");
seq_printf(s, "-------------------------------------------------\n");
mutex_lock(&pmx_mutex);
for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
/* Format pmx and device name nicely */
char cdp[33];
int chars;
chars = snprintf(&cdp[0], 17, "%s", pmx_settings[i]->name);
while (chars < 16) {
cdp[chars] = ' ';
chars++;
}
chars = snprintf(&cdp[16], 17, "%s", pmx_settings[i]->dev ?
dev_name(pmx_settings[i]->dev) : "N/A");
while (chars < 16) {
cdp[chars+16] = ' ';
chars++;
}
cdp[32] = '\0';
seq_printf(s,
"%s\t%s\n",
&cdp[0],
pmx_settings[i]->activated ?
"ACTIVATED" : "DEACTIVATED"
);
}
mutex_unlock(&pmx_mutex);
return 0;
}
static int pmx_open(struct inode *inode, struct file *file)
{
return single_open(file, pmx_show, NULL);
}
static const struct file_operations pmx_operations = {
.owner = THIS_MODULE,
.open = pmx_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init init_pmx_read_debugfs(void)
{
/* Expose a simple debugfs interface to view pmx settings */
(void) debugfs_create_file("padmux", S_IFREG | S_IRUGO,
NULL, NULL,
&pmx_operations);
return 0;
}
/*
* This needs to come in after the core_initcall(),
* because debugfs is not available until
* the subsystems come up.
*/
module_init(init_pmx_read_debugfs);
#endif
static int __init pmx_init(void)
{
int ret;
ret = pmx_set_default();
if (IS_ERR_VALUE(ret))
pr_crit("padmux: default settings could not be set\n");
return 0;
}
/* Should be initialized before consumers */
core_initcall(pmx_init);
/*
*
* arch/arm/mach-u300/padmux.h
*
*
* Copyright (C) 2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* U300 PADMUX API
* Author: Martin Persson <martin.persson@stericsson.com>
*/
#ifndef __MACH_U300_PADMUX_H
#define __MACH_U300_PADMUX_H
enum pmx_settings {
U300_APP_PMX_MMC_SETTING,
U300_APP_PMX_SPI_SETTING
};
struct pmx_onmask {
u16 mask; /* Mask bits */
u16 val; /* Value when active */
};
struct pmx {
struct device *dev;
enum pmx_settings setting;
char *name;
bool activated;
bool default_on;
struct pmx_onmask onmask[];
};
struct pmx *pmx_get(struct device *dev, enum pmx_settings setting);
int pmx_put(struct device *dev, struct pmx *pmx);
int pmx_activate(struct device *dev, struct pmx *pmx);
int pmx_deactivate(struct device *dev, struct pmx *pmx);
#endif
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
#include <mach/coh901318.h> #include <mach/coh901318.h>
#include <mach/dma_channels.h> #include <mach/dma_channels.h>
#include "padmux.h"
/* /*
* The following is for the actual devices on the SSP/SPI bus * The following is for the actual devices on the SSP/SPI bus
*/ */
...@@ -95,25 +93,7 @@ static struct pl022_ssp_controller ssp_platform_data = { ...@@ -95,25 +93,7 @@ static struct pl022_ssp_controller ssp_platform_data = {
void __init u300_spi_init(struct amba_device *adev) void __init u300_spi_init(struct amba_device *adev)
{ {
struct pmx *pmx;
adev->dev.platform_data = &ssp_platform_data; adev->dev.platform_data = &ssp_platform_data;
/*
* Setup padmuxing for SPI. Since this must always be
* compiled into the kernel, pmx is never released.
*/
pmx = pmx_get(&adev->dev, U300_APP_PMX_SPI_SETTING);
if (IS_ERR(pmx))
dev_warn(&adev->dev, "Could not get padmux handle\n");
else {
int ret;
ret = pmx_activate(&adev->dev, pmx);
if (IS_ERR_VALUE(ret))
dev_warn(&adev->dev, "Could not activate padmuxing\n");
}
} }
void __init u300_spi_register_board_devices(void) void __init u300_spi_register_board_devices(void)
......
...@@ -56,6 +56,8 @@ source "drivers/pps/Kconfig" ...@@ -56,6 +56,8 @@ source "drivers/pps/Kconfig"
source "drivers/ptp/Kconfig" source "drivers/ptp/Kconfig"
source "drivers/pinctrl/Kconfig"
source "drivers/gpio/Kconfig" source "drivers/gpio/Kconfig"
source "drivers/w1/Kconfig" source "drivers/w1/Kconfig"
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
# Rewritten to use lists instead of if-statements. # Rewritten to use lists instead of if-statements.
# #
# GPIO must come after pinctrl as gpios may need to mux pins etc
obj-y += pinctrl/
obj-y += gpio/ obj-y += gpio/
obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_PARISC) += parisc/
......
#
# PINCTRL infrastructure and drivers
#
menuconfig PINCTRL
bool "PINCTRL Support"
depends on EXPERIMENTAL
help
This enables the PINCTRL subsystem for controlling pins
on chip packages, for example multiplexing pins on primarily
PGA and BGA packages for systems on chip.
If unsure, say N.
if PINCTRL
config PINMUX
bool "Support pinmux controllers"
help
Say Y here if you want the pincontrol subsystem to handle pin
multiplexing drivers.
config DEBUG_PINCTRL
bool "Debug PINCTRL calls"
depends on DEBUG_KERNEL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINMUX_SIRF
bool "CSR SiRFprimaII pinmux driver"
depends on ARCH_PRIMA2
select PINMUX
help
Say Y here to enable the SiRFprimaII pinmux driver
config PINMUX_U300
bool "U300 pinmux driver"
depends on ARCH_U300
select PINMUX
help
Say Y here to enable the U300 pinmux driver
endif
# generic pinmux support
ccflags-$(CONFIG_DEBUG_PINMUX) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINMUX_SIRF) += pinmux-sirf.o
obj-$(CONFIG_PINMUX_U300) += pinmux-u300.o
This diff is collapsed.
/*
* Core private header for the pin control subsystem
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
/**
* struct pinctrl_dev - pin control class device
* @node: node to include this pin controller in the global pin controller list
* @desc: the pin controller descriptor supplied when initializing this pin
* controller
* @pin_desc_tree: each pin descriptor for this pin controller is stored in
* this radix tree
* @pin_desc_tree_lock: lock for the descriptor tree
* @gpio_ranges: a list of GPIO ranges that is handled by this pin controller,
* ranges are added to this list at runtime
* @gpio_ranges_lock: lock for the GPIO ranges list
* @dev: the device entry for this pin controller
* @owner: module providing the pin controller, used for refcounting
* @driver_data: driver data for drivers registering to the pin controller
* subsystem
* @pinmux_hogs_lock: lock for the pinmux hog list
* @pinmux_hogs: list of pinmux maps hogged by this device
*/
struct pinctrl_dev {
struct list_head node;
struct pinctrl_desc *desc;
struct radix_tree_root pin_desc_tree;
spinlock_t pin_desc_tree_lock;
struct list_head gpio_ranges;
struct mutex gpio_ranges_lock;
struct device dev;
struct module *owner;
void *driver_data;
#ifdef CONFIG_PINMUX
struct mutex pinmux_hogs_lock;
struct list_head pinmux_hogs;
#endif
};
/**
* struct pin_desc - pin descriptor for each physical pin in the arch
* @pctldev: corresponding pin control device
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such
* @lock: a lock to protect the descriptor structure
* @mux_requested: whether the pin is already requested by pinmux or not
* @mux_function: a named muxing function for the pin that will be passed to
* subdrivers and shown in debugfs etc
*/
struct pin_desc {
struct pinctrl_dev *pctldev;
const char *name;
spinlock_t lock;
/* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX
const char *mux_function;
#endif
};
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
const char *dev_name);
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin);
int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_dev **outdev,
struct pinctrl_gpio_range **outrange);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Internal interface between the core pin control system and the
* pinmux portions
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifdef CONFIG_PINMUX
int pinmux_check_ops(const struct pinmux_ops *ops);
void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
void pinmux_init_debugfs(struct dentry *subsys_root);
int pinmux_hog_maps(struct pinctrl_dev *pctldev);
void pinmux_unhog_maps(struct pinctrl_dev *pctldev);
#else
static inline int pinmux_check_ops(const struct pinmux_ops *ops)
{
return 0;
}
static inline void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
}
static inline void pinmux_init_debugfs(struct dentry *subsys_root)
{
}
static inline int pinmux_hog_maps(struct pinctrl_dev *pctldev)
{
return 0;
}
static inline void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
{
}
#endif
/*
* Machine interface for the pinctrl subsystem.
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef __LINUX_PINMUX_MACHINE_H
#define __LINUX_PINMUX_MACHINE_H
/**
* struct pinmux_map - boards/machines shall provide this map for devices
* @name: the name of this specific map entry for the particular machine.
* This is the second parameter passed to pinmux_get() when you want
* to have several mappings to the same device
* @ctrl_dev: the pin control device to be used by this mapping, may be NULL
* if you provide .ctrl_dev_name instead (this is more common)
* @ctrl_dev_name: the name of the device controlling this specific mapping,
* the name must be the same as in your struct device*, may be NULL if
* you provide .ctrl_dev instead
* @function: a function in the driver to use for this mapping, the driver
* will lookup the function referenced by this ID on the specified
* pin control device
* @group: sometimes a function can map to different pin groups, so this
* selects a certain specific pin group to activate for the function, if
* left as NULL, the first applicable group will be used
* @dev: the device using this specific mapping, may be NULL if you provide
* .dev_name instead (this is more common)
* @dev_name: the name of the device using this specific mapping, the name
* must be the same as in your struct device*, may be NULL if you
* provide .dev instead
* @hog_on_boot: if this is set to true, the pin control subsystem will itself
* hog the mappings as the pinmux device drivers are attached, so this is
* typically used with system maps (mux mappings without an assigned
* device) that you want to get hogged and enabled by default as soon as
* a pinmux device supporting it is registered. These maps will not be
* disabled and put until the system shuts down.
*/
struct pinmux_map {
const char *name;
struct device *ctrl_dev;
const char *ctrl_dev_name;
const char *function;
const char *group;
struct device *dev;
const char *dev_name;
const bool hog_on_boot;
};
/*
* Convenience macro to set a simple map from a certain pin controller and a
* certain function to a named device
*/
#define PINMUX_MAP(a, b, c, d) \
{ .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d }
/*
* Convenience macro to map a system function onto a certain pinctrl device.
* System functions are not assigned to a particular device.
*/
#define PINMUX_MAP_SYS(a, b, c) \
{ .name = a, .ctrl_dev_name = b, .function = c }
/*
* Convenience macro to map a function onto the primary device pinctrl device
* this is especially helpful on systems that have only one pin controller
* or need to set up a lot of mappings on the primary controller.
*/
#define PINMUX_MAP_PRIMARY(a, b, c) \
{ .name = a, .ctrl_dev_name = "pinctrl.0", .function = b, \
.dev_name = c }
/*
* Convenience macro to map a system function onto the primary pinctrl device.
* System functions are not assigned to a particular device.
*/
#define PINMUX_MAP_PRIMARY_SYS(a, b) \
{ .name = a, .ctrl_dev_name = "pinctrl.0", .function = b }
/*
* Convenience macro to map a system function onto the primary pinctrl device,
* to be hogged by the pinmux core until the system shuts down.
*/
#define PINMUX_MAP_PRIMARY_SYS_HOG(a, b) \
{ .name = a, .ctrl_dev_name = "pinctrl.0", .function = b, \
.hog_on_boot = true }
#ifdef CONFIG_PINMUX
extern int pinmux_register_mappings(struct pinmux_map const *map,
unsigned num_maps);
#else
static inline int pinmux_register_mappings(struct pinmux_map const *map,
unsigned num_maps)
{
return 0;
}
#endif /* !CONFIG_PINMUX */
#endif
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment