提交 c9d6329c 编写于 作者: L 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
此差异已折叠。
......@@ -5042,6 +5042,11 @@ L: linux-mtd@lists.infradead.org
S: Maintained
F: drivers/mtd/devices/phram.c
PIN CONTROL SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org>
S: Maintained
F: drivers/pinmux/
PKTCDVD DRIVER
M: Peter Osterlund <petero2@telia.com>
S: Maintained
......
......@@ -6,6 +6,8 @@ comment "ST-Ericsson Mobile Platform Products"
config MACH_U300
bool "U300"
select PINCTRL
select PINMUX_U300
comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
......
......@@ -2,7 +2,7 @@
# 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-n :=
obj- :=
......
......@@ -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();
......
......@@ -234,91 +234,6 @@
#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_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) */
#define U300_SYSCON_KA1R (0x0080)
#define U300_SYSCON_KA1R_MASK (0xFFFF)
......@@ -357,57 +272,6 @@
#define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080)
#define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040)
#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) */
#define U300_SYSCON_S0CCR (0x120)
#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF)
......
......@@ -21,7 +21,6 @@
#include <mach/dma_channels.h>
#include "mmc.h"
#include "padmux.h"
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)
{
struct device *mmcsd_device = &adev->dev;
struct pmx *pmx;
int ret = 0;
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;
}
/*
*
* 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 @@
#include <mach/coh901318.h>
#include <mach/dma_channels.h>
#include "padmux.h"
/*
* The following is for the actual devices on the SSP/SPI bus
*/
......@@ -95,25 +93,7 @@ static struct pl022_ssp_controller ssp_platform_data = {
void __init u300_spi_init(struct amba_device *adev)
{
struct pmx *pmx;
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)
......
......@@ -56,6 +56,8 @@ source "drivers/pps/Kconfig"
source "drivers/ptp/Kconfig"
source "drivers/pinctrl/Kconfig"
source "drivers/gpio/Kconfig"
source "drivers/w1/Kconfig"
......
......@@ -5,6 +5,8 @@
# 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-$(CONFIG_PCI) += pci/
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
/*
* Core driver for the pin control 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
*/
#define pr_fmt(fmt) "pinctrl core: " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/radix-tree.h>
#include <linux/err.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/machine.h>
#include "core.h"
#include "pinmux.h"
/* Global list of pin control devices */
static DEFINE_MUTEX(pinctrldev_list_mutex);
static LIST_HEAD(pinctrldev_list);
static void pinctrl_dev_release(struct device *dev)
{
struct pinctrl_dev *pctldev = dev_get_drvdata(dev);
kfree(pctldev);
}
const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
{
/* We're not allowed to register devices without name */
return pctldev->desc->name;
}
EXPORT_SYMBOL_GPL(pinctrl_dev_get_name);
void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
{
return pctldev->driver_data;
}
EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata);
/**
* get_pinctrl_dev_from_dev() - look up pin controller device
* @dev: a device pointer, this may be NULL but then devname needs to be
* defined instead
* @devname: the name of a device instance, as returned by dev_name(), this
* may be NULL but then dev needs to be defined instead
*
* Looks up a pin control device matching a certain device name or pure device
* pointer, the pure device pointer will take precedence.
*/
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
const char *devname)
{
struct pinctrl_dev *pctldev = NULL;
bool found = false;
mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) {
if (dev && &pctldev->dev == dev) {
/* Matched on device pointer */
found = true;
break;
}
if (devname &&
!strcmp(dev_name(&pctldev->dev), devname)) {
/* Matched on device name */
found = true;
break;
}
}
mutex_unlock(&pinctrldev_list_mutex);
return found ? pctldev : NULL;
}
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin)
{
struct pin_desc *pindesc;
unsigned long flags;
spin_lock_irqsave(&pctldev->pin_desc_tree_lock, flags);
pindesc = radix_tree_lookup(&pctldev->pin_desc_tree, pin);
spin_unlock_irqrestore(&pctldev->pin_desc_tree_lock, flags);
return pindesc;
}
/**
* pin_is_valid() - check if pin exists on controller
* @pctldev: the pin control device to check the pin on
* @pin: pin to check, use the local pin controller index number
*
* This tells us whether a certain pin exist on a certain pin controller or
* not. Pin lists may be sparse, so some pins may not exist.
*/
bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
{
struct pin_desc *pindesc;
if (pin < 0)
return false;
pindesc = pin_desc_get(pctldev, pin);
if (pindesc == NULL)
return false;
return true;
}
EXPORT_SYMBOL_GPL(pin_is_valid);
/* Deletes a range of pin descriptors */
static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
const struct pinctrl_pin_desc *pins,
unsigned num_pins)
{
int i;
spin_lock(&pctldev->pin_desc_tree_lock);
for (i = 0; i < num_pins; i++) {
struct pin_desc *pindesc;
pindesc = radix_tree_lookup(&pctldev->pin_desc_tree,
pins[i].number);
if (pindesc != NULL) {
radix_tree_delete(&pctldev->pin_desc_tree,
pins[i].number);
}
kfree(pindesc);
}
spin_unlock(&pctldev->pin_desc_tree_lock);
}
static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
unsigned number, const char *name)
{
struct pin_desc *pindesc;
pindesc = pin_desc_get(pctldev, number);
if (pindesc != NULL) {
pr_err("pin %d already registered on %s\n", number,
pctldev->desc->name);
return -EINVAL;
}
pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL);
if (pindesc == NULL)
return -ENOMEM;
spin_lock_init(&pindesc->lock);
/* Set owner */
pindesc->pctldev = pctldev;
/* Copy basic pin info */
pindesc->name = name;
spin_lock(&pctldev->pin_desc_tree_lock);
radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc);
spin_unlock(&pctldev->pin_desc_tree_lock);
pr_debug("registered pin %d (%s) on %s\n",
number, name ? name : "(unnamed)", pctldev->desc->name);
return 0;
}
static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
struct pinctrl_pin_desc const *pins,
unsigned num_descs)
{
unsigned i;
int ret = 0;
for (i = 0; i < num_descs; i++) {
ret = pinctrl_register_one_pin(pctldev,
pins[i].number, pins[i].name);
if (ret)
return ret;
}
return 0;
}
/**
* pinctrl_match_gpio_range() - check if a certain GPIO pin is in range
* @pctldev: pin controller device to check
* @gpio: gpio pin to check taken from the global GPIO pin space
*
* Tries to match a GPIO pin number to the ranges handled by a certain pin
* controller, return the range or NULL
*/
static struct pinctrl_gpio_range *
pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
{
struct pinctrl_gpio_range *range = NULL;
/* Loop over the ranges */
mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) {
/* Check if we're in the valid range */
if (gpio >= range->base &&
gpio < range->base + range->npins) {
mutex_unlock(&pctldev->gpio_ranges_lock);
return range;
}
}
mutex_unlock(&pctldev->gpio_ranges_lock);
return NULL;
}
/**
* pinctrl_get_device_gpio_range() - find device for GPIO range
* @gpio: the pin to locate the pin controller for
* @outdev: the pin control device if found
* @outrange: the GPIO range if found
*
* Find the pin controller handling a certain GPIO pin from the pinspace of
* the GPIO subsystem, return the device and the matching GPIO range. Returns
* negative if the GPIO range could not be found in any device.
*/
int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_dev **outdev,
struct pinctrl_gpio_range **outrange)
{
struct pinctrl_dev *pctldev = NULL;
/* Loop over the pin controllers */
mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) {
struct pinctrl_gpio_range *range;
range = pinctrl_match_gpio_range(pctldev, gpio);
if (range != NULL) {
*outdev = pctldev;
*outrange = range;
mutex_unlock(&pinctrldev_list_mutex);
return 0;
}
}
mutex_unlock(&pinctrldev_list_mutex);
return -EINVAL;
}
/**
* pinctrl_add_gpio_range() - register a GPIO range for a controller
* @pctldev: pin controller device to add the range to
* @range: the GPIO range to add
*
* This adds a range of GPIOs to be handled by a certain pin controller. Call
* this to register handled ranges after registering your pin controller.
*/
void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range)
{
mutex_lock(&pctldev->gpio_ranges_lock);
list_add(&range->node, &pctldev->gpio_ranges);
mutex_unlock(&pctldev->gpio_ranges_lock);
}
/**
* pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
* @pctldev: pin controller device to remove the range from
* @range: the GPIO range to remove
*/
void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range)
{
mutex_lock(&pctldev->gpio_ranges_lock);
list_del(&range->node);
mutex_unlock(&pctldev->gpio_ranges_lock);
}
#ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
unsigned pin;
seq_printf(s, "registered pins: %d\n", pctldev->desc->npins);
seq_printf(s, "max pin number: %d\n", pctldev->desc->maxpin);
/* The highest pin number need to be included in the loop, thus <= */
for (pin = 0; pin <= pctldev->desc->maxpin; pin++) {
struct pin_desc *desc;
desc = pin_desc_get(pctldev, pin);
/* Pin space may be sparse */
if (desc == NULL)
continue;
seq_printf(s, "pin %d (%s) ", pin,
desc->name ? desc->name : "unnamed");
/* Driver-specific info per pin */
if (ops->pin_dbg_show)
ops->pin_dbg_show(pctldev, s, pin);
seq_puts(s, "\n");
}
return 0;
}
static int pinctrl_groups_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
const struct pinctrl_ops *ops = pctldev->desc->pctlops;
unsigned selector = 0;
/* No grouping */
if (!ops)
return 0;
seq_puts(s, "registered pin groups:\n");
while (ops->list_groups(pctldev, selector) >= 0) {
const unsigned *pins;
unsigned num_pins;
const char *gname = ops->get_group_name(pctldev, selector);
int ret;
int i;
ret = ops->get_group_pins(pctldev, selector,
&pins, &num_pins);
if (ret)
seq_printf(s, "%s [ERROR GETTING PINS]\n",
gname);
else {
seq_printf(s, "group: %s, pins = [ ", gname);
for (i = 0; i < num_pins; i++)
seq_printf(s, "%d ", pins[i]);
seq_puts(s, "]\n");
}
selector++;
}
return 0;
}
static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
struct pinctrl_gpio_range *range = NULL;
seq_puts(s, "GPIO ranges handled:\n");
/* Loop over the ranges */
mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) {
seq_printf(s, "%u: %s [%u - %u]\n", range->id, range->name,
range->base, (range->base + range->npins - 1));
}
mutex_unlock(&pctldev->gpio_ranges_lock);
return 0;
}
static int pinctrl_devices_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev;
seq_puts(s, "name [pinmux]\n");
mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) {
seq_printf(s, "%s ", pctldev->desc->name);
if (pctldev->desc->pmxops)
seq_puts(s, "yes");
else
seq_puts(s, "no");
seq_puts(s, "\n");
}
mutex_unlock(&pinctrldev_list_mutex);
return 0;
}
static int pinctrl_pins_open(struct inode *inode, struct file *file)
{
return single_open(file, pinctrl_pins_show, inode->i_private);
}
static int pinctrl_groups_open(struct inode *inode, struct file *file)
{
return single_open(file, pinctrl_groups_show, inode->i_private);
}
static int pinctrl_gpioranges_open(struct inode *inode, struct file *file)
{
return single_open(file, pinctrl_gpioranges_show, inode->i_private);
}
static int pinctrl_devices_open(struct inode *inode, struct file *file)
{
return single_open(file, pinctrl_devices_show, NULL);
}
static const struct file_operations pinctrl_pins_ops = {
.open = pinctrl_pins_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations pinctrl_groups_ops = {
.open = pinctrl_groups_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations pinctrl_gpioranges_ops = {
.open = pinctrl_gpioranges_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static const struct file_operations pinctrl_devices_ops = {
.open = pinctrl_devices_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static struct dentry *debugfs_root;
static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
{
static struct dentry *device_root;
device_root = debugfs_create_dir(dev_name(&pctldev->dev),
debugfs_root);
if (IS_ERR(device_root) || !device_root) {
pr_warn("failed to create debugfs directory for %s\n",
dev_name(&pctldev->dev));
return;
}
debugfs_create_file("pins", S_IFREG | S_IRUGO,
device_root, pctldev, &pinctrl_pins_ops);
debugfs_create_file("pingroups", S_IFREG | S_IRUGO,
device_root, pctldev, &pinctrl_groups_ops);
debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO,
device_root, pctldev, &pinctrl_gpioranges_ops);
pinmux_init_device_debugfs(device_root, pctldev);
}
static void pinctrl_init_debugfs(void)
{
debugfs_root = debugfs_create_dir("pinctrl", NULL);
if (IS_ERR(debugfs_root) || !debugfs_root) {
pr_warn("failed to create debugfs directory\n");
debugfs_root = NULL;
return;
}
debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO,
debugfs_root, NULL, &pinctrl_devices_ops);
pinmux_init_debugfs(debugfs_root);
}
#else /* CONFIG_DEBUG_FS */
static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
{
}
static void pinctrl_init_debugfs(void)
{
}
#endif
/**
* pinctrl_register() - register a pin controller device
* @pctldesc: descriptor for this pin controller
* @dev: parent device for this pin controller
* @driver_data: private pin controller data for this pin controller
*/
struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
struct device *dev, void *driver_data)
{
static atomic_t pinmux_no = ATOMIC_INIT(0);
struct pinctrl_dev *pctldev;
int ret;
if (pctldesc == NULL)
return NULL;
if (pctldesc->name == NULL)
return NULL;
/* If we're implementing pinmuxing, check the ops for sanity */
if (pctldesc->pmxops) {
ret = pinmux_check_ops(pctldesc->pmxops);
if (ret) {
pr_err("%s pinmux ops lacks necessary functions\n",
pctldesc->name);
return NULL;
}
}
pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
if (pctldev == NULL)
return NULL;
/* Initialize pin control device struct */
pctldev->owner = pctldesc->owner;
pctldev->desc = pctldesc;
pctldev->driver_data = driver_data;
INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
spin_lock_init(&pctldev->pin_desc_tree_lock);
INIT_LIST_HEAD(&pctldev->gpio_ranges);
mutex_init(&pctldev->gpio_ranges_lock);
/* Register device */
pctldev->dev.parent = dev;
dev_set_name(&pctldev->dev, "pinctrl.%d",
atomic_inc_return(&pinmux_no) - 1);
pctldev->dev.release = pinctrl_dev_release;
ret = device_register(&pctldev->dev);
if (ret != 0) {
pr_err("error in device registration\n");
goto out_reg_dev_err;
}
dev_set_drvdata(&pctldev->dev, pctldev);
/* Register all the pins */
pr_debug("try to register %d pins on %s...\n",
pctldesc->npins, pctldesc->name);
ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
if (ret) {
pr_err("error during pin registration\n");
pinctrl_free_pindescs(pctldev, pctldesc->pins,
pctldesc->npins);
goto out_reg_pins_err;
}
pinctrl_init_device_debugfs(pctldev);
mutex_lock(&pinctrldev_list_mutex);
list_add(&pctldev->node, &pinctrldev_list);
mutex_unlock(&pinctrldev_list_mutex);
pinmux_hog_maps(pctldev);
return pctldev;
out_reg_pins_err:
device_del(&pctldev->dev);
out_reg_dev_err:
put_device(&pctldev->dev);
return NULL;
}
EXPORT_SYMBOL_GPL(pinctrl_register);
/**
* pinctrl_unregister() - unregister pinmux
* @pctldev: pin controller to unregister
*
* Called by pinmux drivers to unregister a pinmux.
*/
void pinctrl_unregister(struct pinctrl_dev *pctldev)
{
if (pctldev == NULL)
return;
pinmux_unhog_maps(pctldev);
/* TODO: check that no pinmuxes are still active? */
mutex_lock(&pinctrldev_list_mutex);
list_del(&pctldev->node);
mutex_unlock(&pinctrldev_list_mutex);
/* Destroy descriptor tree */
pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
pctldev->desc->npins);
device_unregister(&pctldev->dev);
}
EXPORT_SYMBOL_GPL(pinctrl_unregister);
static int __init pinctrl_init(void)
{
pr_info("initialized pinctrl subsystem\n");
pinctrl_init_debugfs();
return 0;
}
/* init early since many drivers really need to initialized pinmux early */
core_initcall(pinctrl_init);
/*
* 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);
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* 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
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册