X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=drivers%2Fpinctrl%2Fpinctrl-sunxi.c;h=119d2ddedfe70c2aed27398289c8d1b2b484b160;hb=35e787510064604f98f3bcc3647c470ab6114e3b;hp=94716c779800ea099bfd580c627a93345af7d1db;hpb=0df03a30c333d67ee9b4c37f32d423624f48fe05;p=karo-tx-linux.git 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);