summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sh-pfc/pinctrl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-04 16:24:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-04 16:24:33 -0700
commitaa7054f5a5a9ff728ce291cb103afa19f4f849eb (patch)
tree83ddb460e2dca239f35d64a33054c100fe7f9e5d /drivers/pinctrl/sh-pfc/pinctrl.c
parent816434ec4a674fcdb3c2221a6dffdc8f34020550 (diff)
parentc9e3b2d8f75d84c7b333761471f6cef98ec4429a (diff)
downloadlinux-aa7054f5a5a9ff728ce291cb103afa19f4f849eb.tar.bz2
Merge tag 'pinctrl-v3.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control changes from Linus Walleij: "Here is the bulk of pin control changes for the v3.12 series. Most of the relevant information is in the tag. I merged in v3.11-rc7 last week to get rid of a largeish conflict within the sunxi (AllWinner) driver in linux-next and fix up the non-trivial merge the right way. That driver had a rather large fix adding locking late in the release cycle. Overall the bulk changes this time is cleanups and refactorings and not much new features, which is nice. - Refactorings for generic pin config handling in the core. - Factor out a set of device tree utilities for use in all drivers, to parse and allocate maps from the device tree. - Some fixes to the core such as more nitpicky locking. - Pushed down config array iteration into the drivers. This patch is necessary for drivers that want to iterate over configs and pile up a stack of alterations to the same register(s), or if the driver wants to take a local spinlock when committing the configuration. - A new driver for the Texas Instruments Palmas PMIC by Laxman Dewangan. This is used on the Tegra systems. - A major cleanup and modernization of the PFC (Super Hitachi and ARM SHmobile) pin controller and subdrivers. - Support for the A20 and A31 sunxi (AllWinner) SoCs. - A huge pile of fixes and cleanups: Axel Lin, Jingoo Han Dan Carpenter, Julia Lawall and Sachin Kamat did an excellent job here" * tag 'pinctrl-v3.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (124 commits) pinctrl: sunxi: Fix off-by-one for valid offset range checking pinctrl: sunxi: drop lock on error path pinctrl: pinconf-generic: Remove ti prefix in dev_err messages pinctrl: rockchip: Implement .request() and .free() callbacks pinctrl: at91: fix get_pullup/down function return pinctrl: sh-pfc: remove unnecessary platform_set_drvdata() pinctrl: Add s5pv210 support to pinctrl-exynos pinctrl: utils: include export.h to avoid warnings pinctrl: s3c24xx: off by one in s3c24xx_eint_init() pinctrl: mvebu: testing the wrong variable pinctrl: abx500: fix bitwise AND test pinctrl: mvebu: Convert to use devm_ioremap_resource pinctrl: Pass all configs to driver on pin_config_set() pinctrl: tz1090-pdc: Convert to devm_ioremap_resource pinctrl: tz1090: Convert to devm_ioremap_resource pinctrl: tegra: Convert to devm_ioremap_resource pinctrl: rockchip: Simplify pin_to_bank equation pinctrl: spear: Convert to devm_ioremap_resource pinctrl: rockchip: Remove of_match_ptr macro for DT only driver pinctrl: palmas: PINCTRL_PALMAS needs to select PINMUX ...
Diffstat (limited to 'drivers/pinctrl/sh-pfc/pinctrl.c')
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c91
1 files changed, 38 insertions, 53 deletions
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
index bc8b028bb5d2..e758af95c209 100644
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -529,38 +529,44 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
}
static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
- unsigned long config)
+ unsigned long *configs, unsigned num_configs)
{
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
struct sh_pfc *pfc = pmx->pfc;
- enum pin_config_param param = pinconf_to_config_param(config);
+ enum pin_config_param param;
unsigned long flags;
+ unsigned int i;
- if (!sh_pfc_pinconf_validate(pfc, _pin, param))
- return -ENOTSUPP;
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
- switch (param) {
- case PIN_CONFIG_BIAS_PULL_UP:
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_BIAS_DISABLE:
- if (!pfc->info->ops || !pfc->info->ops->set_bias)
+ if (!sh_pfc_pinconf_validate(pfc, _pin, param))
return -ENOTSUPP;
- spin_lock_irqsave(&pfc->lock, flags);
- pfc->info->ops->set_bias(pfc, _pin, param);
- spin_unlock_irqrestore(&pfc->lock, flags);
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_DISABLE:
+ if (!pfc->info->ops || !pfc->info->ops->set_bias)
+ return -ENOTSUPP;
- break;
+ spin_lock_irqsave(&pfc->lock, flags);
+ pfc->info->ops->set_bias(pfc, _pin, param);
+ spin_unlock_irqrestore(&pfc->lock, flags);
- default:
- return -ENOTSUPP;
- }
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+ } /* for each config */
return 0;
}
static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
- unsigned long config)
+ unsigned long *configs,
+ unsigned num_configs)
{
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
const unsigned int *pins;
@@ -571,7 +577,7 @@ static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
num_pins = pmx->pfc->info->groups[group].nr_pins;
for (i = 0; i < num_pins; ++i)
- sh_pfc_pinconf_set(pctldev, pins[i], config);
+ sh_pfc_pinconf_set(pctldev, pins[i], configs, num_configs);
return 0;
}
@@ -587,22 +593,9 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = {
/* PFC ranges -> pinctrl pin descs */
static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
{
- const struct pinmux_range *ranges;
- struct pinmux_range def_range;
- unsigned int nr_ranges;
- unsigned int nr_pins;
unsigned int i;
- if (pfc->info->ranges == NULL) {
- def_range.begin = 0;
- def_range.end = pfc->info->nr_pins - 1;
- ranges = &def_range;
- nr_ranges = 1;
- } else {
- ranges = pfc->info->ranges;
- nr_ranges = pfc->info->nr_ranges;
- }
-
+ /* Allocate and initialize the pins and configs arrays. */
pmx->pins = devm_kzalloc(pfc->dev,
sizeof(*pmx->pins) * pfc->info->nr_pins,
GFP_KERNEL);
@@ -615,32 +608,24 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
if (unlikely(!pmx->configs))
return -ENOMEM;
- for (i = 0, nr_pins = 0; i < nr_ranges; ++i) {
- const struct pinmux_range *range = &ranges[i];
- unsigned int number;
-
- for (number = range->begin; number <= range->end;
- number++, nr_pins++) {
- struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins];
- struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins];
- const struct sh_pfc_pin *info =
- &pfc->info->pins[nr_pins];
+ for (i = 0; i < pfc->info->nr_pins; ++i) {
+ const struct sh_pfc_pin *info = &pfc->info->pins[i];
+ struct sh_pfc_pin_config *cfg = &pmx->configs[i];
+ struct pinctrl_pin_desc *pin = &pmx->pins[i];
- pin->number = number;
- pin->name = info->name;
- cfg->type = PINMUX_TYPE_NONE;
- }
+ /* If the pin number is equal to -1 all pins are considered */
+ pin->number = info->pin != (u16)-1 ? info->pin : i;
+ pin->name = info->name;
+ cfg->type = PINMUX_TYPE_NONE;
}
- pfc->nr_pins = ranges[nr_ranges-1].end + 1;
-
- return nr_ranges;
+ return 0;
}
int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
{
struct sh_pfc_pinctrl *pmx;
- int nr_ranges;
+ int ret;
pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL);
if (unlikely(!pmx))
@@ -649,9 +634,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
pmx->pfc = pfc;
pfc->pinctrl = pmx;
- nr_ranges = sh_pfc_map_pins(pfc, pmx);
- if (unlikely(nr_ranges < 0))
- return nr_ranges;
+ ret = sh_pfc_map_pins(pfc, pmx);
+ if (ret < 0)
+ return ret;
pmx->pctl_desc.name = DRV_NAME;
pmx->pctl_desc.owner = THIS_MODULE;