Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965869AbbLPQz6 (ORCPT ); Wed, 16 Dec 2015 11:55:58 -0500 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:39840 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934283AbbLPQzz (ORCPT ); Wed, 16 Dec 2015 11:55:55 -0500 Subject: Re: [PATCH v3 4/9] pinctrl: Add STM32 MCUs support To: Maxime Coquelin , Linus Walleij , Mark Rutland , Rob Herring , , References: <1449822306-9035-1-git-send-email-mcoquelin.stm32@gmail.com> <1449822306-9035-5-git-send-email-mcoquelin.stm32@gmail.com> CC: , , , , Daniel Thompson , From: Patrice Chotard Message-ID: <5671976D.2050706@st.com> Date: Wed, 16 Dec 2015 17:55:09 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: <1449822306-9035-5-git-send-email-mcoquelin.stm32@gmail.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [10.48.0.153] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.15.21,1.0.33,0.0.0000 definitions=2015-12-16_07:2015-12-16,2015-12-16,1970-01-01 signatures=0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5156 Lines: 195 Hi Maxime On 12/11/2015 09:25 AM, Maxime Coquelin wrote: > This patch adds pinctrl and GPIO support to STMicroelectronic's STM32 > family of MCUs. > > While it only supports STM32F429 for now, it has been designed to enable > support of other MCUs of the family (e.g. STM32F746). > > Signed-off-by: Maxime Coquelin > --- > drivers/pinctrl/Kconfig | 1 + > drivers/pinctrl/Makefile | 1 + > drivers/pinctrl/stm32/Kconfig | 16 + > drivers/pinctrl/stm32/Makefile | 5 + > drivers/pinctrl/stm32/pinctrl-stm32.c | 856 +++++++++++++++ > drivers/pinctrl/stm32/pinctrl-stm32.h | 43 + > drivers/pinctrl/stm32/pinctrl-stm32f429.c | 1598 +++++++++++++++++++++++++++++ > 7 files changed, 2520 insertions(+) > create mode 100644 drivers/pinctrl/stm32/Kconfig > create mode 100644 drivers/pinctrl/stm32/Makefile > create mode 100644 drivers/pinctrl/stm32/pinctrl-stm32.c > create mode 100644 drivers/pinctrl/stm32/pinctrl-stm32.h > create mode 100644 drivers/pinctrl/stm32/pinctrl-stm32f429.c > [...] > + > +static int stm32_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, > + struct device_node *node, > + struct pinctrl_map **map, > + unsigned *reserved_maps, > + unsigned *num_maps) > +{ > + struct stm32_pinctrl *pctl; > + struct stm32_pinctrl_group *grp; > + struct property *pins; > + u32 pinfunc, pin, func; > + unsigned long *configs; > + unsigned int num_configs; > + bool has_config = 0; > + unsigned reserve = 0; > + int num_pins, num_funcs, maps_per_pin, i, err; > + > + pctl = pinctrl_dev_get_drvdata(pctldev); > + > + pins = of_find_property(node, "pinmux", NULL); > + if (!pins) { > + dev_err(pctl->dev, "missing pins property in node %s .\n", > + node->name); > + return -EINVAL; > + } > + > + err = pinconf_generic_parse_dt_config(node, pctldev, &configs, > + &num_configs); > + if (num_configs) > + has_config = 1; > + > + num_pins = pins->length / sizeof(u32); > + num_funcs = num_pins; > + maps_per_pin = 0; > + if (num_funcs) > + maps_per_pin++; > + if (has_config && num_pins >= 1) > + maps_per_pin++; > + > + if (!num_pins || !maps_per_pin) > + return -EINVAL; > + > + reserve = num_pins * maps_per_pin; > + > + err = pinctrl_utils_reserve_map(pctldev, map, > + reserved_maps, num_maps, reserve); > + if (err < 0) > + goto fail; > + > + for (i = 0; i < num_pins; i++) { > + err = of_property_read_u32_index(node, "pinmux", > + i, &pinfunc); > + if (err) > + goto fail; as a "goto fail" doesn't do more than a return, here do directly "return err;" > + > + pin = STM32_GET_PIN_NO(pinfunc); > + func = STM32_GET_PIN_FUNC(pinfunc); > + > + if (pin >= pctl->match_data->npins) { > + dev_err(pctl->dev, "invalid pin number.\n"); > + err = -EINVAL; > + goto fail; ditto, return -EINVAL > + } > + > + if (!stm32_pctrl_is_function_valid(pctl, pin, func)) { > + dev_err(pctl->dev, "invalid function.\n"); > + err = -EINVAL; > + goto fail; ditto > + } > + > + grp = stm32_pctrl_find_group_by_pin(pctl, pin); > + if (!grp) { > + dev_err(pctl->dev, "unable to match pin %d to group\n", > + pin); > + return -EINVAL; > + } > + > + err = stm32_pctrl_dt_node_to_map_func(pctl, pin, func, grp, map, > + reserved_maps, num_maps); > + if (err < 0) > + goto fail; ditto > + > + if (has_config) { > + err = pinctrl_utils_add_map_configs(pctldev, map, > + reserved_maps, num_maps, grp->name, > + configs, num_configs, > + PIN_MAP_TYPE_CONFIGS_GROUP); > + if (err < 0) > + goto fail; ditto > + } > + } > + > + return 0; > + > +fail: > + return err; > +} > + [...] > + > +static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, > + unsigned function, > + unsigned group) > +{ > + bool ret; > + const struct stm32_desc_function *desc; > + struct stm32_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); > + struct stm32_pinctrl_group *g = pctl->groups + group; > + struct pinctrl_gpio_range *range; > + struct stm32_gpio_bank *bank; > + u32 mode, alt; > + int pin; > + > + ret = stm32_pctrl_is_function_valid(pctl, g->pin, function); > + if (!ret) { > + dev_err(pctl->dev, "invalid function %d on group %d .\n", > + function, group); > + return -EINVAL; > + } > + > + desc = stm32_pctrl_find_function_by_pin(pctl, g->pin, function); > + if (!desc) > + return -EINVAL; stm32_pctrl_find_function_by_pin() is useless, desc is never used stm32_pctrl_is_function_valid(), above, already checks that function exists for the requested pins > + > + range = pinctrl_find_gpio_range_from_pin(pctldev, g->pin); > + bank = gpio_range_to_bank(range); > + pin = stm32_gpio_pin(g->pin); > + > + mode = stm32_gpio_get_mode(function); > + alt = stm32_gpio_get_alt(function); > + > + stm32_pmx_set_mode(bank, pin, mode, alt); > + > + return 0; > +} > + > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/