aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2017-07-15 22:50:41 +0200
committerHauke Mehrtens <hauke@hauke-m.de>2017-09-18 20:34:55 +0200
commit34a422794ddab738408edc7e3980ccbc14f28af4 (patch)
tree06f99aeb1acab719dea0a5743d44c2026613edbb /target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch
parente080a7ce07ee8cd63c71e1469853a233d9bc7a4c (diff)
downloadupstream-34a422794ddab738408edc7e3980ccbc14f28af4.tar.gz
upstream-34a422794ddab738408edc7e3980ccbc14f28af4.tar.bz2
upstream-34a422794ddab738408edc7e3980ccbc14f28af4.zip
sunxi: Backport patches needed for A64
This backports multiple patches from kernel 4.10 which are adding missing support for the A64 and the pine64 board. These are the device tree files, the pinctlk and the clock driver. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Diffstat (limited to 'target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch')
-rw-r--r--target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch122
1 files changed, 122 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch b/target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch
new file mode 100644
index 0000000000..7555933f63
--- /dev/null
+++ b/target/linux/sunxi/patches-4.9/0039-pinctrl-sunxi-Make-sunxi_pconf_group_set-use-sunxi_p.patch
@@ -0,0 +1,122 @@
+From 51814827190214986c452a166718bf12d32211c7 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Fri, 11 Nov 2016 17:50:36 +0800
+Subject: pinctrl: sunxi: Make sunxi_pconf_group_set use sunxi_pconf_reg helper
+
+The sunxi_pconf_reg helper introduced in the last patch gives us the
+chance to rework sunxi_pconf_group_set to have it match the structure
+of sunxi_pconf_(group_)get and make it easier to understand.
+
+For each config to set, it:
+
+ 1. checks if the parameter is supported.
+ 2. checks if the argument is within limits.
+ 3. converts argument to the register value.
+ 4. writes to the register with spinlock held.
+
+As a result the function now blocks unsupported config parameters,
+instead of silently ignoring them.
+
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c | 64 +++++++++++++++++------------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -532,23 +532,27 @@ static int sunxi_pconf_group_set(struct
+ {
+ struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct sunxi_pinctrl_group *g = &pctl->groups[group];
+- unsigned long flags;
+ unsigned pin = g->pin - pctl->desc->pin_base;
+- u32 val, mask;
+- u16 strength;
+- u8 dlevel;
+ int i;
+
+- spin_lock_irqsave(&pctl->lock, flags);
+-
+ for (i = 0; i < num_configs; i++) {
+- switch (pinconf_to_config_param(configs[i])) {
++ enum pin_config_param param;
++ unsigned long flags;
++ u32 offset, shift, mask, reg;
++ u16 arg, val;
++ int ret;
++
++ param = pinconf_to_config_param(configs[i]);
++ arg = pinconf_to_config_argument(configs[i]);
++
++ ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
++ if (ret < 0)
++ return ret;
++
++ switch (param) {
+ case PIN_CONFIG_DRIVE_STRENGTH:
+- strength = pinconf_to_config_argument(configs[i]);
+- if (strength > 40) {
+- spin_unlock_irqrestore(&pctl->lock, flags);
++ if (arg < 10 || arg > 40)
+ return -EINVAL;
+- }
+ /*
+ * We convert from mA to what the register expects:
+ * 0: 10mA
+@@ -556,37 +560,33 @@ static int sunxi_pconf_group_set(struct
+ * 2: 30mA
+ * 3: 40mA
+ */
+- dlevel = strength / 10 - 1;
+- val = readl(pctl->membase + sunxi_dlevel_reg(pin));
+- mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(pin);
+- writel((val & ~mask)
+- | dlevel << sunxi_dlevel_offset(pin),
+- pctl->membase + sunxi_dlevel_reg(pin));
++ val = arg / 10 - 1;
+ break;
+ case PIN_CONFIG_BIAS_DISABLE:
+- val = readl(pctl->membase + sunxi_pull_reg(pin));
+- mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
+- writel((val & ~mask),
+- pctl->membase + sunxi_pull_reg(pin));
++ val = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+- val = readl(pctl->membase + sunxi_pull_reg(pin));
+- mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
+- writel((val & ~mask) | 1 << sunxi_pull_offset(pin),
+- pctl->membase + sunxi_pull_reg(pin));
++ if (arg == 0)
++ return -EINVAL;
++ val = 1;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+- val = readl(pctl->membase + sunxi_pull_reg(pin));
+- mask = PULL_PINS_MASK << sunxi_pull_offset(pin);
+- writel((val & ~mask) | 2 << sunxi_pull_offset(pin),
+- pctl->membase + sunxi_pull_reg(pin));
++ if (arg == 0)
++ return -EINVAL;
++ val = 2;
+ break;
+ default:
+- break;
++ /* sunxi_pconf_reg should catch anything unsupported */
++ WARN_ON(1);
++ return -ENOTSUPP;
+ }
+- } /* for each config */
+
+- spin_unlock_irqrestore(&pctl->lock, flags);
++ spin_lock_irqsave(&pctl->lock, flags);
++ reg = readl(pctl->membase + offset);
++ reg &= ~(mask << shift);
++ writel(reg | val << shift, pctl->membase + offset);
++ spin_unlock_irqrestore(&pctl->lock, flags);
++ } /* for each config */
+
+ return 0;
+ }