diff options
Diffstat (limited to 'target/linux/sunxi/patches-4.9/0030-pinctrl-sunxi-Rework-the-pin-config-building-code.patch')
-rw-r--r-- | target/linux/sunxi/patches-4.9/0030-pinctrl-sunxi-Rework-the-pin-config-building-code.patch | 251 |
1 files changed, 0 insertions, 251 deletions
diff --git a/target/linux/sunxi/patches-4.9/0030-pinctrl-sunxi-Rework-the-pin-config-building-code.patch b/target/linux/sunxi/patches-4.9/0030-pinctrl-sunxi-Rework-the-pin-config-building-code.patch deleted file mode 100644 index 498581712d..0000000000 --- a/target/linux/sunxi/patches-4.9/0030-pinctrl-sunxi-Rework-the-pin-config-building-code.patch +++ /dev/null @@ -1,251 +0,0 @@ -From f233dbca6227703eaae2f67d6d9c79819773f16b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime.ripard@free-electrons.com> -Date: Tue, 11 Oct 2016 17:45:59 +0200 -Subject: pinctrl: sunxi: Rework the pin config building code - -In order to support more easily the generic pinctrl properties, rework the -pinctrl maps configuration and split it into several sub-functions. - -One of the side-effects from that rework is that we only parse the pin -configuration once, since it's going to be common to every pin, instead of -having to parsing once for each pin. - -Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> -Signed-off-by: Linus Walleij <linus.walleij@linaro.org> ---- - drivers/pinctrl/sunxi/pinctrl-sunxi.c | 178 +++++++++++++++++++++++++--------- - 1 file changed, 130 insertions(+), 48 deletions(-) - ---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c -+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c -@@ -145,6 +145,110 @@ static int sunxi_pctrl_get_group_pins(st - return 0; - } - -+static bool sunxi_pctrl_has_bias_prop(struct device_node *node) -+{ -+ return of_find_property(node, "allwinner,pull", NULL); -+} -+ -+static bool sunxi_pctrl_has_drive_prop(struct device_node *node) -+{ -+ return of_find_property(node, "allwinner,drive", NULL); -+} -+ -+static int sunxi_pctrl_parse_bias_prop(struct device_node *node) -+{ -+ u32 val; -+ -+ if (of_property_read_u32(node, "allwinner,pull", &val)) -+ return -EINVAL; -+ -+ switch (val) { -+ case 1: -+ return PIN_CONFIG_BIAS_PULL_UP; -+ case 2: -+ return PIN_CONFIG_BIAS_PULL_DOWN; -+ } -+ -+ return -EINVAL; -+} -+ -+static int sunxi_pctrl_parse_drive_prop(struct device_node *node) -+{ -+ u32 val; -+ -+ if (of_property_read_u32(node, "allwinner,drive", &val)) -+ return -EINVAL; -+ -+ return (val + 1) * 10; -+} -+ -+static const char *sunxi_pctrl_parse_function_prop(struct device_node *node) -+{ -+ const char *function; -+ int ret; -+ -+ ret = of_property_read_string(node, "allwinner,function", &function); -+ if (!ret) -+ return function; -+ -+ return NULL; -+} -+ -+static const char *sunxi_pctrl_find_pins_prop(struct device_node *node, -+ int *npins) -+{ -+ int count; -+ -+ count = of_property_count_strings(node, "allwinner,pins"); -+ if (count > 0) { -+ *npins = count; -+ return "allwinner,pins"; -+ } -+ -+ return NULL; -+} -+ -+static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node, -+ unsigned int *len) -+{ -+ unsigned long *pinconfig; -+ unsigned int configlen = 0, idx = 0; -+ -+ if (sunxi_pctrl_has_drive_prop(node)) -+ configlen++; -+ if (sunxi_pctrl_has_bias_prop(node)) -+ configlen++; -+ -+ pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL); -+ if (!pinconfig) -+ return NULL; -+ -+ if (sunxi_pctrl_has_drive_prop(node)) { -+ int drive = sunxi_pctrl_parse_drive_prop(node); -+ if (drive < 0) -+ goto err_free; -+ -+ pinconfig[idx++] = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, -+ drive); -+ } -+ -+ if (sunxi_pctrl_has_bias_prop(node)) { -+ int pull = sunxi_pctrl_parse_bias_prop(node); -+ if (pull < 0) -+ goto err_free; -+ -+ pinconfig[idx++] = pinconf_to_config_packed(pull, 0); -+ } -+ -+ -+ *len = configlen; -+ return pinconfig; -+ -+err_free: -+ kfree(pinconfig); -+ return NULL; -+} -+ - static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *node, - struct pinctrl_map **map, -@@ -153,38 +257,45 @@ static int sunxi_pctrl_dt_node_to_map(st - struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - unsigned long *pinconfig; - struct property *prop; -- const char *function; -+ const char *function, *pin_prop; - const char *group; -- int ret, nmaps, i = 0; -- u32 val; -+ int ret, npins, nmaps, configlen = 0, i = 0; - - *map = NULL; - *num_maps = 0; - -- ret = of_property_read_string(node, "allwinner,function", &function); -- if (ret) { -- dev_err(pctl->dev, -- "missing allwinner,function property in node %s\n", -+ function = sunxi_pctrl_parse_function_prop(node); -+ if (!function) { -+ dev_err(pctl->dev, "missing function property in node %s\n", - node->name); - return -EINVAL; - } - -- nmaps = of_property_count_strings(node, "allwinner,pins") * 2; -- if (nmaps < 0) { -- dev_err(pctl->dev, -- "missing allwinner,pins property in node %s\n", -+ pin_prop = sunxi_pctrl_find_pins_prop(node, &npins); -+ if (!pin_prop) { -+ dev_err(pctl->dev, "missing pins property in node %s\n", - node->name); - return -EINVAL; - } - -+ /* -+ * We have two maps for each pin: one for the function, one -+ * for the configuration (bias, strength, etc) -+ */ -+ nmaps = npins * 2; - *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); - if (!*map) - return -ENOMEM; - -- of_property_for_each_string(node, "allwinner,pins", prop, group) { -+ pinconfig = sunxi_pctrl_build_pin_config(node, &configlen); -+ if (!pinconfig) { -+ ret = -EINVAL; -+ goto err_free_map; -+ } -+ -+ of_property_for_each_string(node, pin_prop, prop, group) { - struct sunxi_pinctrl_group *grp = - sunxi_pinctrl_find_group_by_name(pctl, group); -- int j = 0, configlen = 0; - - if (!grp) { - dev_err(pctl->dev, "unknown pin %s", group); -@@ -207,34 +318,6 @@ static int sunxi_pctrl_dt_node_to_map(st - - (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; - (*map)[i].data.configs.group_or_pin = group; -- -- if (of_find_property(node, "allwinner,drive", NULL)) -- configlen++; -- if (of_find_property(node, "allwinner,pull", NULL)) -- configlen++; -- -- pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL); -- if (!pinconfig) { -- kfree(*map); -- return -ENOMEM; -- } -- -- if (!of_property_read_u32(node, "allwinner,drive", &val)) { -- u16 strength = (val + 1) * 10; -- pinconfig[j++] = -- pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, -- strength); -- } -- -- if (!of_property_read_u32(node, "allwinner,pull", &val)) { -- enum pin_config_param pull = PIN_CONFIG_END; -- if (val == 1) -- pull = PIN_CONFIG_BIAS_PULL_UP; -- else if (val == 2) -- pull = PIN_CONFIG_BIAS_PULL_DOWN; -- pinconfig[j++] = pinconf_to_config_packed(pull, 0); -- } -- - (*map)[i].data.configs.configs = pinconfig; - (*map)[i].data.configs.num_configs = configlen; - -@@ -244,19 +327,18 @@ static int sunxi_pctrl_dt_node_to_map(st - *num_maps = nmaps; - - return 0; -+ -+err_free_map: -+ kfree(map); -+ return ret; - } - - static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, - unsigned num_maps) - { -- int i; -- -- for (i = 0; i < num_maps; i++) { -- if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) -- kfree(map[i].data.configs.configs); -- } -- -+ /* All the maps have the same pin config, free only the first one */ -+ kfree(map[0].data.configs.configs); - kfree(map); - } - |