diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-sunxi.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-sunxi.c | 99 |
1 files changed, 49 insertions, 50 deletions
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index 94716c779800..119d2ddedfe7 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c @@ -175,7 +175,7 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, } *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); - if (!map) + if (!*map) return -ENOMEM; of_property_for_each_string(node, "allwinner,pins", prop, group) { @@ -274,7 +274,8 @@ static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev, static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, - unsigned long config) + unsigned long *configs, + unsigned num_configs) { struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct sunxi_pinctrl_group *g = &pctl->groups[group]; @@ -282,56 +283,52 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, u32 val, mask; u16 strength; u8 dlevel; + int i; - switch (pinconf_to_config_param(config)) { - case PIN_CONFIG_DRIVE_STRENGTH: - strength = pinconf_to_config_argument(config); - if (strength > 40) - return -EINVAL; - /* - * We convert from mA to what the register expects: - * 0: 10mA - * 1: 20mA - * 2: 30mA - * 3: 40mA - */ - dlevel = strength / 10 - 1; - - spin_lock_irqsave(&pctl->lock, flags); - - val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); - mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); - writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin), - pctl->membase + sunxi_dlevel_reg(g->pin)); - - spin_unlock_irqrestore(&pctl->lock, flags); - break; - case PIN_CONFIG_BIAS_PULL_UP: - spin_lock_irqsave(&pctl->lock, flags); - - val = readl(pctl->membase + sunxi_pull_reg(g->pin)); - mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); - writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin), - pctl->membase + sunxi_pull_reg(g->pin)); - - spin_unlock_irqrestore(&pctl->lock, flags); - break; - case PIN_CONFIG_BIAS_PULL_DOWN: - spin_lock_irqsave(&pctl->lock, flags); - - val = readl(pctl->membase + sunxi_pull_reg(g->pin)); - mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); - writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin), - pctl->membase + sunxi_pull_reg(g->pin)); + spin_lock_irqsave(&pctl->lock, flags); - spin_unlock_irqrestore(&pctl->lock, flags); - break; - default: - break; - } + for (i = 0; i < num_configs; i++) { + switch (pinconf_to_config_param(configs[i])) { + case PIN_CONFIG_DRIVE_STRENGTH: + strength = pinconf_to_config_argument(configs[i]); + if (strength > 40) { + spin_unlock_irqrestore(&pctl->lock, flags); + return -EINVAL; + } + /* + * We convert from mA to what the register expects: + * 0: 10mA + * 1: 20mA + * 2: 30mA + * 3: 40mA + */ + dlevel = strength / 10 - 1; + val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); + mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); + writel((val & ~mask) + | dlevel << sunxi_dlevel_offset(g->pin), + pctl->membase + sunxi_dlevel_reg(g->pin)); + break; + case PIN_CONFIG_BIAS_PULL_UP: + val = readl(pctl->membase + sunxi_pull_reg(g->pin)); + mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); + writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin), + pctl->membase + sunxi_pull_reg(g->pin)); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + val = readl(pctl->membase + sunxi_pull_reg(g->pin)); + mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin); + writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin), + pctl->membase + sunxi_pull_reg(g->pin)); + break; + default: + break; + } + /* cache the config value */ + g->config = configs[i]; + } /* for each config */ - /* cache the config value */ - g->config = config; + spin_unlock_irqrestore(&pctl->lock, flags); return 0; } @@ -524,7 +521,7 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev); struct sunxi_desc_function *desc; - if (offset > chip->ngpio) + if (offset >= chip->ngpio) return -ENXIO; desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq"); @@ -687,6 +684,8 @@ static struct of_device_id sunxi_pinctrl_match[] = { { .compatible = "allwinner,sun4i-a10-pinctrl", .data = (void *)&sun4i_a10_pinctrl_data }, { .compatible = "allwinner,sun5i-a10s-pinctrl", .data = (void *)&sun5i_a10s_pinctrl_data }, { .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data }, + { .compatible = "allwinner,sun6i-a31-pinctrl", .data = (void *)&sun6i_a31_pinctrl_data }, + { .compatible = "allwinner,sun7i-a20-pinctrl", .data = (void *)&sun7i_a20_pinctrl_data }, {} }; MODULE_DEVICE_TABLE(of, sunxi_pinctrl_match); |