brintos

brintos / linux-shallow public Read only

0
0
Text · 17.9 KiB · aad4891 Raw
730 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * MediaTek Pinctrl Moore Driver, which implement the generic dt-binding4 * pinctrl-bindings.txt for MediaTek SoC.5 *6 * Copyright (C) 2017-2018 MediaTek Inc.7 * Author: Sean Wang <sean.wang@mediatek.com>8 *9 */10 11#include <dt-bindings/pinctrl/mt65xx.h>12#include <linux/gpio/driver.h>13 14#include <linux/pinctrl/consumer.h>15 16#include "pinctrl-moore.h"17 18#define PINCTRL_PINCTRL_DEV		KBUILD_MODNAME19 20/* Custom pinconf parameters */21#define MTK_PIN_CONFIG_TDSEL	(PIN_CONFIG_END + 1)22#define MTK_PIN_CONFIG_RDSEL	(PIN_CONFIG_END + 2)23#define MTK_PIN_CONFIG_PU_ADV	(PIN_CONFIG_END + 3)24#define MTK_PIN_CONFIG_PD_ADV	(PIN_CONFIG_END + 4)25 26static const struct pinconf_generic_params mtk_custom_bindings[] = {27	{"mediatek,tdsel",	MTK_PIN_CONFIG_TDSEL,		0},28	{"mediatek,rdsel",	MTK_PIN_CONFIG_RDSEL,		0},29	{"mediatek,pull-up-adv", MTK_PIN_CONFIG_PU_ADV,		1},30	{"mediatek,pull-down-adv", MTK_PIN_CONFIG_PD_ADV,	1},31};32 33#ifdef CONFIG_DEBUG_FS34static const struct pin_config_item mtk_conf_items[] = {35	PCONFDUMP(MTK_PIN_CONFIG_TDSEL, "tdsel", NULL, true),36	PCONFDUMP(MTK_PIN_CONFIG_RDSEL, "rdsel", NULL, true),37	PCONFDUMP(MTK_PIN_CONFIG_PU_ADV, "pu-adv", NULL, true),38	PCONFDUMP(MTK_PIN_CONFIG_PD_ADV, "pd-adv", NULL, true),39};40#endif41 42static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,43			      unsigned int selector, unsigned int group)44{45	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);46	struct function_desc *func;47	struct group_desc *grp;48	int i, err;49 50	func = pinmux_generic_get_function(pctldev, selector);51	if (!func)52		return -EINVAL;53 54	grp = pinctrl_generic_get_group(pctldev, group);55	if (!grp)56		return -EINVAL;57 58	dev_dbg(pctldev->dev, "enable function %s group %s\n",59		func->func.name, grp->grp.name);60 61	for (i = 0; i < grp->grp.npins; i++) {62		const struct mtk_pin_desc *desc;63		int *pin_modes = grp->data;64		int pin = grp->grp.pins[i];65 66		desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];67		if (!desc->name)68			return -ENOTSUPP;69 70		err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,71				       pin_modes[i]);72 73		if (err)74			return err;75	}76 77	return 0;78}79 80static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,81					  struct pinctrl_gpio_range *range,82					  unsigned int pin)83{84	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);85	const struct mtk_pin_desc *desc;86 87	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];88	if (!desc->name)89		return -ENOTSUPP;90 91	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,92				hw->soc->gpio_m);93}94 95static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,96					 struct pinctrl_gpio_range *range,97					 unsigned int pin, bool input)98{99	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);100	const struct mtk_pin_desc *desc;101 102	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];103	if (!desc->name)104		return -ENOTSUPP;105 106	/* hardware would take 0 as input direction */107	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);108}109 110static int mtk_pinconf_get(struct pinctrl_dev *pctldev,111			   unsigned int pin, unsigned long *config)112{113	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);114	u32 param = pinconf_to_config_param(*config);115	int val, val2, err, pullup, reg, ret = 1;116	const struct mtk_pin_desc *desc;117 118	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];119	if (!desc->name)120		return -ENOTSUPP;121 122	switch (param) {123	case PIN_CONFIG_BIAS_DISABLE:124		if (hw->soc->bias_get_combo) {125			err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);126			if (err)127				return err;128			if (ret != MTK_PUPD_SET_R1R0_00 && ret != MTK_DISABLE)129				return -EINVAL;130		} else if (hw->soc->bias_disable_get) {131			err = hw->soc->bias_disable_get(hw, desc, &ret);132			if (err)133				return err;134		} else {135			return -ENOTSUPP;136		}137		break;138	case PIN_CONFIG_BIAS_PULL_UP:139		if (hw->soc->bias_get_combo) {140			err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);141			if (err)142				return err;143			if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)144				return -EINVAL;145			if (!pullup)146				return -EINVAL;147		} else if (hw->soc->bias_get) {148			err = hw->soc->bias_get(hw, desc, 1, &ret);149			if (err)150				return err;151		} else {152			return -ENOTSUPP;153		}154		break;155	case PIN_CONFIG_BIAS_PULL_DOWN:156		if (hw->soc->bias_get_combo) {157			err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);158			if (err)159				return err;160			if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)161				return -EINVAL;162			if (pullup)163				return -EINVAL;164		} else if (hw->soc->bias_get) {165			err = hw->soc->bias_get(hw, desc, 0, &ret);166			if (err)167				return err;168		} else {169			return -ENOTSUPP;170		}171		break;172	case PIN_CONFIG_SLEW_RATE:173		err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);174		if (err)175			return err;176 177		if (!val)178			return -EINVAL;179 180		break;181	case PIN_CONFIG_INPUT_ENABLE:182	case PIN_CONFIG_OUTPUT_ENABLE:183		err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);184		if (err)185			return err;186 187		/* HW takes input mode as zero; output mode as non-zero */188		if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||189		    (!val && param == PIN_CONFIG_OUTPUT_ENABLE))190			return -EINVAL;191 192		break;193	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:194		err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);195		if (err)196			return err;197 198		err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);199		if (err)200			return err;201 202		if (val || !val2)203			return -EINVAL;204 205		break;206	case PIN_CONFIG_DRIVE_STRENGTH:207		if (hw->soc->drive_get) {208			err = hw->soc->drive_get(hw, desc, &ret);209			if (err)210				return err;211		} else {212			err = -ENOTSUPP;213		}214		break;215	case MTK_PIN_CONFIG_TDSEL:216	case MTK_PIN_CONFIG_RDSEL:217		reg = (param == MTK_PIN_CONFIG_TDSEL) ?218		       PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;219 220		err = mtk_hw_get_value(hw, desc, reg, &val);221		if (err)222			return err;223 224		ret = val;225 226		break;227	case MTK_PIN_CONFIG_PU_ADV:228	case MTK_PIN_CONFIG_PD_ADV:229		if (hw->soc->adv_pull_get) {230			bool pullup;231 232			pullup = param == MTK_PIN_CONFIG_PU_ADV;233			err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);234			if (err)235				return err;236		} else {237			return -ENOTSUPP;238		}239		break;240	default:241		return -ENOTSUPP;242	}243 244	*config = pinconf_to_config_packed(param, ret);245 246	return 0;247}248 249static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,250			   unsigned long *configs, unsigned int num_configs)251{252	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);253	const struct mtk_pin_desc *desc;254	u32 reg, param, arg;255	int cfg, err = 0;256 257	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];258	if (!desc->name)259		return -ENOTSUPP;260 261	for (cfg = 0; cfg < num_configs; cfg++) {262		param = pinconf_to_config_param(configs[cfg]);263		arg = pinconf_to_config_argument(configs[cfg]);264 265		switch (param) {266		case PIN_CONFIG_BIAS_DISABLE:267			if (hw->soc->bias_set_combo) {268				err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);269				if (err)270					return err;271			} else if (hw->soc->bias_disable_set) {272				err = hw->soc->bias_disable_set(hw, desc);273				if (err)274					return err;275			} else {276				return -ENOTSUPP;277			}278			break;279		case PIN_CONFIG_BIAS_PULL_UP:280			if (hw->soc->bias_set_combo) {281				err = hw->soc->bias_set_combo(hw, desc, 1, arg);282				if (err)283					return err;284			} else if (hw->soc->bias_set) {285				err = hw->soc->bias_set(hw, desc, 1);286				if (err)287					return err;288			} else {289				return -ENOTSUPP;290			}291			break;292		case PIN_CONFIG_BIAS_PULL_DOWN:293			if (hw->soc->bias_set_combo) {294				err = hw->soc->bias_set_combo(hw, desc, 0, arg);295				if (err)296					return err;297			} else if (hw->soc->bias_set) {298				err = hw->soc->bias_set(hw, desc, 0);299				if (err)300					return err;301			} else {302				return -ENOTSUPP;303			}304			break;305		case PIN_CONFIG_OUTPUT_ENABLE:306			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,307					       MTK_DISABLE);308			if (err)309				goto err;310 311			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,312					       MTK_OUTPUT);313			if (err)314				goto err;315			break;316		case PIN_CONFIG_INPUT_ENABLE:317 318			if (hw->soc->ies_present) {319				mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,320						 MTK_ENABLE);321			}322 323			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,324					       MTK_INPUT);325			if (err)326				goto err;327			break;328		case PIN_CONFIG_SLEW_RATE:329			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,330					       arg);331			if (err)332				goto err;333 334			break;335		case PIN_CONFIG_OUTPUT:336			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,337					       MTK_OUTPUT);338			if (err)339				goto err;340 341			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,342					       arg);343			if (err)344				goto err;345			break;346		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:347			/* arg = 1: Input mode & SMT enable ;348			 * arg = 0: Output mode & SMT disable349			 */350			arg = arg ? 2 : 1;351			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,352					       arg & 1);353			if (err)354				goto err;355 356			err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,357					       !!(arg & 2));358			if (err)359				goto err;360			break;361		case PIN_CONFIG_DRIVE_STRENGTH:362			if (hw->soc->drive_set) {363				err = hw->soc->drive_set(hw, desc, arg);364				if (err)365					return err;366			} else {367				err = -ENOTSUPP;368			}369			break;370		case MTK_PIN_CONFIG_TDSEL:371		case MTK_PIN_CONFIG_RDSEL:372			reg = (param == MTK_PIN_CONFIG_TDSEL) ?373			       PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;374 375			err = mtk_hw_set_value(hw, desc, reg, arg);376			if (err)377				goto err;378			break;379		case MTK_PIN_CONFIG_PU_ADV:380		case MTK_PIN_CONFIG_PD_ADV:381			if (hw->soc->adv_pull_set) {382				bool pullup;383 384				pullup = param == MTK_PIN_CONFIG_PU_ADV;385				err = hw->soc->adv_pull_set(hw, desc, pullup,386							    arg);387				if (err)388					return err;389			} else {390				return -ENOTSUPP;391			}392			break;393		default:394			err = -ENOTSUPP;395		}396	}397err:398	return err;399}400 401static int mtk_pinconf_group_get(struct pinctrl_dev *pctldev,402				 unsigned int group, unsigned long *config)403{404	const unsigned int *pins;405	unsigned int i, npins, old = 0;406	int ret;407 408	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);409	if (ret)410		return ret;411 412	for (i = 0; i < npins; i++) {413		if (mtk_pinconf_get(pctldev, pins[i], config))414			return -ENOTSUPP;415 416		/* configs do not match between two pins */417		if (i && old != *config)418			return -ENOTSUPP;419 420		old = *config;421	}422 423	return 0;424}425 426static int mtk_pinconf_group_set(struct pinctrl_dev *pctldev,427				 unsigned int group, unsigned long *configs,428				 unsigned int num_configs)429{430	const unsigned int *pins;431	unsigned int i, npins;432	int ret;433 434	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);435	if (ret)436		return ret;437 438	for (i = 0; i < npins; i++) {439		ret = mtk_pinconf_set(pctldev, pins[i], configs, num_configs);440		if (ret)441			return ret;442	}443 444	return 0;445}446 447static const struct pinctrl_ops mtk_pctlops = {448	.get_groups_count = pinctrl_generic_get_group_count,449	.get_group_name = pinctrl_generic_get_group_name,450	.get_group_pins = pinctrl_generic_get_group_pins,451	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,452	.dt_free_map = pinconf_generic_dt_free_map,453};454 455static const struct pinmux_ops mtk_pmxops = {456	.get_functions_count = pinmux_generic_get_function_count,457	.get_function_name = pinmux_generic_get_function_name,458	.get_function_groups = pinmux_generic_get_function_groups,459	.set_mux = mtk_pinmux_set_mux,460	.gpio_request_enable = mtk_pinmux_gpio_request_enable,461	.gpio_set_direction = mtk_pinmux_gpio_set_direction,462	.strict = true,463};464 465static const struct pinconf_ops mtk_confops = {466	.is_generic = true,467	.pin_config_get = mtk_pinconf_get,468	.pin_config_set = mtk_pinconf_set,469	.pin_config_group_get = mtk_pinconf_group_get,470	.pin_config_group_set = mtk_pinconf_group_set,471	.pin_config_config_dbg_show = pinconf_generic_dump_config,472};473 474static struct pinctrl_desc mtk_desc = {475	.name = PINCTRL_PINCTRL_DEV,476	.pctlops = &mtk_pctlops,477	.pmxops = &mtk_pmxops,478	.confops = &mtk_confops,479	.owner = THIS_MODULE,480};481 482static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)483{484	struct mtk_pinctrl *hw = gpiochip_get_data(chip);485	const struct mtk_pin_desc *desc;486	int value, err;487 488	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];489	if (!desc->name)490		return -ENOTSUPP;491 492	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);493	if (err)494		return err;495 496	return !!value;497}498 499static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)500{501	struct mtk_pinctrl *hw = gpiochip_get_data(chip);502	const struct mtk_pin_desc *desc;503 504	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];505	if (!desc->name) {506		dev_err(hw->dev, "Failed to set gpio %d\n", gpio);507		return;508	}509 510	mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);511}512 513static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,514				     int value)515{516	mtk_gpio_set(chip, gpio, value);517 518	return pinctrl_gpio_direction_output(chip, gpio);519}520 521static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)522{523	struct mtk_pinctrl *hw = gpiochip_get_data(chip);524	const struct mtk_pin_desc *desc;525 526	if (!hw->eint)527		return -ENOTSUPP;528 529	desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];530 531	if (desc->eint.eint_n == (u16)EINT_NA)532		return -ENOTSUPP;533 534	return mtk_eint_find_irq(hw->eint, desc->eint.eint_n);535}536 537static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,538			       unsigned long config)539{540	struct mtk_pinctrl *hw = gpiochip_get_data(chip);541	const struct mtk_pin_desc *desc;542	u32 debounce;543 544	desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];545	if (!desc->name)546		return -ENOTSUPP;547 548	if (!hw->eint ||549	    pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||550	    desc->eint.eint_n == (u16)EINT_NA)551		return -ENOTSUPP;552 553	debounce = pinconf_to_config_argument(config);554 555	return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, debounce);556}557 558static int mtk_build_gpiochip(struct mtk_pinctrl *hw)559{560	struct gpio_chip *chip = &hw->chip;561	int ret;562 563	chip->label		= PINCTRL_PINCTRL_DEV;564	chip->parent		= hw->dev;565	chip->request		= gpiochip_generic_request;566	chip->free		= gpiochip_generic_free;567	chip->direction_input	= pinctrl_gpio_direction_input;568	chip->direction_output	= mtk_gpio_direction_output;569	chip->get		= mtk_gpio_get;570	chip->set		= mtk_gpio_set;571	chip->to_irq		= mtk_gpio_to_irq;572	chip->set_config	= mtk_gpio_set_config;573	chip->base		= -1;574	chip->ngpio		= hw->soc->npins;575 576	ret = gpiochip_add_data(chip, hw);577	if (ret < 0)578		return ret;579 580	/* Just for backward compatible for these old pinctrl nodes without581	 * "gpio-ranges" property. Otherwise, called directly from a582	 * DeviceTree-supported pinctrl driver is DEPRECATED.583	 * Please see Section 2.1 of584	 * Documentation/devicetree/bindings/gpio/gpio.txt on how to585	 * bind pinctrl and gpio drivers via the "gpio-ranges" property.586	 */587	if (!of_property_present(hw->dev->of_node, "gpio-ranges")) {588		ret = gpiochip_add_pin_range(chip, dev_name(hw->dev), 0, 0,589					     chip->ngpio);590		if (ret < 0) {591			gpiochip_remove(chip);592			return ret;593		}594	}595 596	return 0;597}598 599static int mtk_build_groups(struct mtk_pinctrl *hw)600{601	int err, i;602 603	for (i = 0; i < hw->soc->ngrps; i++) {604		const struct group_desc *group = hw->soc->grps + i;605		const struct pingroup *grp = &group->grp;606 607		err = pinctrl_generic_add_group(hw->pctrl, grp->name, grp->pins, grp->npins,608						group->data);609		if (err < 0) {610			dev_err(hw->dev, "Failed to register group %s\n", grp->name);611			return err;612		}613	}614 615	return 0;616}617 618static int mtk_build_functions(struct mtk_pinctrl *hw)619{620	int i, err;621 622	for (i = 0; i < hw->soc->nfuncs ; i++) {623		const struct function_desc *function = hw->soc->funcs + i;624		const struct pinfunction *func = &function->func;625 626		err = pinmux_generic_add_function(hw->pctrl, func->name,627						  func->groups, func->ngroups,628						  function->data);629		if (err < 0) {630			dev_err(hw->dev, "Failed to register function %s\n",631				func->name);632			return err;633		}634	}635 636	return 0;637}638 639int mtk_moore_pinctrl_probe(struct platform_device *pdev,640			    const struct mtk_pin_soc *soc)641{642	struct device *dev = &pdev->dev;643	struct pinctrl_pin_desc *pins;644	struct mtk_pinctrl *hw;645	int err, i;646 647	hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);648	if (!hw)649		return -ENOMEM;650 651	hw->soc = soc;652	hw->dev = &pdev->dev;653 654	if (!hw->soc->nbase_names)655		return dev_err_probe(dev, -EINVAL,656			"SoC should be assigned at least one register base\n");657 658	hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,659				      sizeof(*hw->base), GFP_KERNEL);660	if (!hw->base)661		return -ENOMEM;662 663	for (i = 0; i < hw->soc->nbase_names; i++) {664		hw->base[i] = devm_platform_ioremap_resource_byname(pdev,665						hw->soc->base_names[i]);666		if (IS_ERR(hw->base[i]))667			return PTR_ERR(hw->base[i]);668	}669 670	hw->nbase = hw->soc->nbase_names;671 672	spin_lock_init(&hw->lock);673 674	/* Copy from internal struct mtk_pin_desc to register to the core */675	pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),676				  GFP_KERNEL);677	if (!pins)678		return -ENOMEM;679 680	for (i = 0; i < hw->soc->npins; i++) {681		pins[i].number = hw->soc->pins[i].number;682		pins[i].name = hw->soc->pins[i].name;683	}684 685	/* Setup pins descriptions per SoC types */686	mtk_desc.pins = (const struct pinctrl_pin_desc *)pins;687	mtk_desc.npins = hw->soc->npins;688	mtk_desc.num_custom_params = ARRAY_SIZE(mtk_custom_bindings);689	mtk_desc.custom_params = mtk_custom_bindings;690#ifdef CONFIG_DEBUG_FS691	mtk_desc.custom_conf_items = mtk_conf_items;692#endif693 694	err = devm_pinctrl_register_and_init(&pdev->dev, &mtk_desc, hw,695					     &hw->pctrl);696	if (err)697		return err;698 699	/* Setup groups descriptions per SoC types */700	err = mtk_build_groups(hw);701	if (err)702		return dev_err_probe(dev, err, "Failed to build groups\n");703 704	/* Setup functions descriptions per SoC types */705	err = mtk_build_functions(hw);706	if (err)707		return dev_err_probe(dev, err, "Failed to build functions\n");708 709	/* For able to make pinctrl_claim_hogs, we must not enable pinctrl710	 * until all groups and functions are being added one.711	 */712	err = pinctrl_enable(hw->pctrl);713	if (err)714		return err;715 716	err = mtk_build_eint(hw, pdev);717	if (err)718		dev_warn(&pdev->dev,719			 "Failed to add EINT, but pinctrl still can work\n");720 721	/* Build gpiochip should be after pinctrl_enable is done */722	err = mtk_build_gpiochip(hw);723	if (err)724		return dev_err_probe(dev, err, "Failed to add gpio_chip\n");725 726	platform_set_drvdata(pdev, hw);727 728	return 0;729}730