diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 03:24:33 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 03:24:33 +0400 |
commit | aa7054f5a5a9ff728ce291cb103afa19f4f849eb (patch) | |
tree | 83ddb460e2dca239f35d64a33054c100fe7f9e5d /drivers/pinctrl/pinctrl-tz1090.c | |
parent | 816434ec4a674fcdb3c2221a6dffdc8f34020550 (diff) | |
parent | c9e3b2d8f75d84c7b333761471f6cef98ec4429a (diff) | |
download | linux-aa7054f5a5a9ff728ce291cb103afa19f4f849eb.tar.xz |
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/pinctrl-tz1090.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-tz1090.c | 162 |
1 files changed, 83 insertions, 79 deletions
diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c index 4edae08a0a61..bc9cd7a7602e 100644 --- a/drivers/pinctrl/pinctrl-tz1090.c +++ b/drivers/pinctrl/pinctrl-tz1090.c @@ -1762,39 +1762,46 @@ static int tz1090_pinconf_get(struct pinctrl_dev *pctldev, } static int tz1090_pinconf_set(struct pinctrl_dev *pctldev, - unsigned int pin, unsigned long config) + unsigned int pin, unsigned long *configs, + unsigned num_configs) { struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); - enum pin_config_param param = pinconf_to_config_param(config); - unsigned int arg = pinconf_to_config_argument(config); + enum pin_config_param param; + unsigned int arg; int ret; u32 reg, width, mask, shift, val, tmp; unsigned long flags; + int i; - dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n", - __func__, tz1090_pins[pin].name, config); + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); - /* Get register information */ - ret = tz1090_pinconf_reg(pctldev, pin, param, true, - ®, &width, &mask, &shift, &val); - if (ret < 0) - return ret; + dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n", + __func__, tz1090_pins[pin].name, configs[i]); - /* Unpack argument and range check it */ - if (arg > 1) { - dev_dbg(pctldev->dev, "%s: arg %u out of range\n", - __func__, arg); - return -EINVAL; - } + /* Get register information */ + ret = tz1090_pinconf_reg(pctldev, pin, param, true, + ®, &width, &mask, &shift, &val); + if (ret < 0) + return ret; - /* Write register field */ - __global_lock2(flags); - tmp = pmx_read(pmx, reg); - tmp &= ~mask; - if (arg) - tmp |= val << shift; - pmx_write(pmx, tmp, reg); - __global_unlock2(flags); + /* Unpack argument and range check it */ + if (arg > 1) { + dev_dbg(pctldev->dev, "%s: arg %u out of range\n", + __func__, arg); + return -EINVAL; + } + + /* Write register field */ + __global_lock2(flags); + tmp = pmx_read(pmx, reg); + tmp &= ~mask; + if (arg) + tmp |= val << shift; + pmx_write(pmx, tmp, reg); + __global_unlock2(flags); + } /* for each config */ return 0; } @@ -1894,68 +1901,81 @@ static int tz1090_pinconf_group_get(struct pinctrl_dev *pctldev, } static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev, - unsigned int group, unsigned long config) + unsigned int group, unsigned long *configs, + unsigned num_configs) { struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); const struct tz1090_pingroup *g; - enum pin_config_param param = pinconf_to_config_param(config); + enum pin_config_param param; unsigned int arg, pin, i; const unsigned int *pit; int ret; u32 reg, width, mask, shift, val; unsigned long flags; const int *map; + int j; if (group >= ARRAY_SIZE(tz1090_groups)) { pin = group - ARRAY_SIZE(tz1090_groups); - return tz1090_pinconf_set(pctldev, pin, config); + return tz1090_pinconf_set(pctldev, pin, configs, num_configs); } g = &tz1090_groups[group]; if (g->npins == 1) { pin = g->pins[0]; - ret = tz1090_pinconf_set(pctldev, pin, config); + ret = tz1090_pinconf_set(pctldev, pin, configs, num_configs); if (ret != -ENOTSUPP) return ret; } - dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n", - __func__, g->name, config); + for (j = 0; j < num_configs; j++) { + param = pinconf_to_config_param(configs[j]); - /* Get register information */ - ret = tz1090_pinconf_group_reg(pctldev, g, param, true, - ®, &width, &mask, &shift, &map); - if (ret < 0) { - /* - * Maybe we're trying to set a per-pin configuration of a group, - * so do the pins one by one. This is mainly as a convenience. - */ - for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) { - ret = tz1090_pinconf_set(pctldev, *pit, config); - if (ret) - return ret; - } - return 0; - } + dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n", + __func__, g->name, configs[j]); - /* Unpack argument and map it to register value */ - arg = pinconf_to_config_argument(config); - for (i = 0; i < BIT(width); ++i) { - if (map[i] == arg || (map[i] == -EINVAL && !arg)) { - /* Write register field */ - __global_lock2(flags); - val = pmx_read(pmx, reg); - val &= ~mask; - val |= i << shift; - pmx_write(pmx, val, reg); - __global_unlock2(flags); + /* Get register information */ + ret = tz1090_pinconf_group_reg(pctldev, g, param, true, ®, + &width, &mask, &shift, &map); + if (ret < 0) { + /* + * Maybe we're trying to set a per-pin configuration + * of a group, so do the pins one by one. This is + * mainly as a convenience. + */ + for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) { + ret = tz1090_pinconf_set(pctldev, *pit, configs, + num_configs); + if (ret) + return ret; + } return 0; } - } - dev_dbg(pctldev->dev, "%s: arg %u not supported\n", - __func__, arg); - return -EINVAL; + /* Unpack argument and map it to register value */ + arg = pinconf_to_config_argument(configs[j]); + for (i = 0; i < BIT(width); ++i) { + if (map[i] == arg || (map[i] == -EINVAL && !arg)) { + /* Write register field */ + __global_lock2(flags); + val = pmx_read(pmx, reg); + val &= ~mask; + val |= i << shift; + pmx_write(pmx, val, reg); + __global_unlock2(flags); + goto next_config; + } + } + + dev_dbg(pctldev->dev, "%s: arg %u not supported\n", + __func__, arg); + return -EINVAL; + +next_config: + ; + } /* for each config */ + + return 0; } static struct pinconf_ops tz1090_pinconf_ops = { @@ -1996,25 +2016,9 @@ static int tz1090_pinctrl_probe(struct platform_device *pdev) tz1090_pinctrl_desc.npins = ARRAY_SIZE(tz1090_pins); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Missing MEM resource\n"); - return -ENODEV; - } - - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), - dev_name(&pdev->dev))) { - dev_err(&pdev->dev, - "Couldn't request MEM resource\n"); - return -ENODEV; - } - - pmx->regs = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!pmx->regs) { - dev_err(&pdev->dev, "Couldn't ioremap regs\n"); - return -ENODEV; - } + pmx->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pmx->regs)) + return PTR_ERR(pmx->regs); pmx->pctl = pinctrl_register(&tz1090_pinctrl_desc, &pdev->dev, pmx); if (!pmx->pctl) { |