brintos

brintos / linux-shallow public Read only

0
0
Text · 18.1 KiB · 57f2674 Raw
766 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Sophgo CV18XX SoCs pinctrl driver.4 *5 * Copyright (C) 2024 Inochi Amaoto <inochiama@outlook.com>6 *7 */8 9#include <linux/bitfield.h>10#include <linux/export.h>11#include <linux/io.h>12#include <linux/of.h>13#include <linux/platform_device.h>14#include <linux/bsearch.h>15#include <linux/seq_file.h>16#include <linux/spinlock.h>17 18#include <linux/pinctrl/consumer.h>19#include <linux/pinctrl/machine.h>20#include <linux/pinctrl/pinconf-generic.h>21#include <linux/pinctrl/pinconf.h>22#include <linux/pinctrl/pinctrl.h>23#include <linux/pinctrl/pinmux.h>24 25#include <dt-bindings/pinctrl/pinctrl-cv18xx.h>26 27#include "../core.h"28#include "../pinctrl-utils.h"29#include "../pinconf.h"30#include "../pinmux.h"31#include "pinctrl-cv18xx.h"32 33struct cv1800_pinctrl {34	struct device				*dev;35	struct pinctrl_dev			*pctl_dev;36	const struct cv1800_pinctrl_data	*data;37	struct pinctrl_desc			pdesc;38	u32					*power_cfg;39 40	struct mutex				mutex;41	raw_spinlock_t				lock;42 43	void __iomem				*regs[2];44};45 46struct cv1800_pin_mux_config {47	struct cv1800_pin	*pin;48	u32			config;49};50 51static unsigned int cv1800_dt_get_pin(u32 value)52{53	return value & GENMASK(15, 0);54}55 56static unsigned int cv1800_dt_get_pin_mux(u32 value)57{58	return (value >> 16) & GENMASK(7, 0);59}60 61static unsigned int cv1800_dt_get_pin_mux2(u32 value)62{63	return (value >> 24) & GENMASK(7, 0);64}65 66#define cv1800_pinctrl_get_component_addr(pctrl, _comp)		\67	((pctrl)->regs[(_comp)->area] + (_comp)->offset)68 69static int cv1800_cmp_pin(const void *key, const void *pivot)70{71	const struct cv1800_pin *pin = pivot;72	int pin_id = (long)key;73	int pivid = pin->pin;74 75	return pin_id - pivid;76}77 78static int cv1800_set_power_cfg(struct cv1800_pinctrl *pctrl,79				u8 domain, u32 cfg)80{81	if (domain >= pctrl->data->npd)82		return -ENOTSUPP;83 84	if (pctrl->power_cfg[domain] && pctrl->power_cfg[domain] != cfg)85		return -EINVAL;86 87	pctrl->power_cfg[domain] = cfg;88 89	return 0;90}91 92static int cv1800_get_power_cfg(struct cv1800_pinctrl *pctrl,93				u8 domain)94{95	return pctrl->power_cfg[domain];96}97 98static struct cv1800_pin *cv1800_get_pin(struct cv1800_pinctrl *pctrl,99					 unsigned long pin)100{101	return bsearch((void *)pin, pctrl->data->pindata, pctrl->data->npins,102		       sizeof(struct cv1800_pin), cv1800_cmp_pin);103}104 105#define PIN_BGA_ID_OFFSET		8106#define PIN_BGA_ID_MASK			0xff107 108static const char *const io_type_desc[] = {109	"1V8",110	"18OD33",111	"AUDIO",112	"ETH"113};114 115static const char *cv1800_get_power_cfg_desc(struct cv1800_pinctrl *pctrl,116					     u8 domain)117{118	return pctrl->data->pdnames[domain];119}120 121static void cv1800_pctrl_dbg_show(struct pinctrl_dev *pctldev,122				  struct seq_file *seq, unsigned int pin_id)123{124	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);125	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);126	enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);127	u32 value;128	void __iomem *reg;129 130	if (pin->pin >> PIN_BGA_ID_OFFSET)131		seq_printf(seq, "pos: %c%u ",132			   'A' + (pin->pin >> PIN_BGA_ID_OFFSET) - 1,133			   pin->pin & PIN_BGA_ID_MASK);134	else135		seq_printf(seq, "pos: %u ", pin->pin);136 137	seq_printf(seq, "power-domain: %s ",138		   cv1800_get_power_cfg_desc(pctrl, pin->power_domain));139	seq_printf(seq, "type: %s ", io_type_desc[type]);140 141	reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);142	value = readl(reg);143	seq_printf(seq, "mux: 0x%08x ", value);144 145	if (pin->flags & CV1800_PIN_HAVE_MUX2) {146		reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);147		value = readl(reg);148		seq_printf(seq, "mux2: 0x%08x ", value);149	}150 151	if (type == IO_TYPE_1V8_ONLY || type == IO_TYPE_1V8_OR_3V3) {152		reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);153		value = readl(reg);154		seq_printf(seq, "conf: 0x%08x ", value);155	}156}157 158static int cv1800_verify_pinmux_config(const struct cv1800_pin_mux_config *config)159{160	unsigned int mux = cv1800_dt_get_pin_mux(config->config);161	unsigned int mux2 = cv1800_dt_get_pin_mux2(config->config);162 163	if (mux > config->pin->mux.max)164		return -EINVAL;165 166	if (config->pin->flags & CV1800_PIN_HAVE_MUX2) {167		if (mux != config->pin->mux2.pfunc)168			return -EINVAL;169 170		if (mux2 > config->pin->mux2.max)171			return -EINVAL;172	} else {173		if (mux2 != PIN_MUX_INVALD)174			return -ENOTSUPP;175	}176 177	return 0;178}179 180static int cv1800_verify_pin_group(const struct cv1800_pin_mux_config *mux,181				   unsigned long npins)182{183	enum cv1800_pin_io_type type;184	u8 power_domain;185	int i;186 187	if (npins == 1)188		return 0;189 190	type = cv1800_pin_io_type(mux[0].pin);191	power_domain = mux[0].pin->power_domain;192 193	for (i = 0; i < npins; i++) {194		if (type != cv1800_pin_io_type(mux[i].pin) ||195		    power_domain != mux[i].pin->power_domain)196			return -ENOTSUPP;197	}198 199	return 0;200}201 202static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,203				       struct device_node *np,204				       struct pinctrl_map **maps,205				       unsigned int *num_maps)206{207	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);208	struct device *dev = pctrl->dev;209	struct device_node *child;210	struct pinctrl_map *map;211	const char **grpnames;212	const char *grpname;213	int ngroups = 0;214	int nmaps = 0;215	int ret;216 217	for_each_available_child_of_node(np, child)218		ngroups += 1;219 220	grpnames = devm_kcalloc(dev, ngroups, sizeof(*grpnames), GFP_KERNEL);221	if (!grpnames)222		return -ENOMEM;223 224	map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL);225	if (!map)226		return -ENOMEM;227 228	ngroups = 0;229	mutex_lock(&pctrl->mutex);230	for_each_available_child_of_node(np, child) {231		int npins = of_property_count_u32_elems(child, "pinmux");232		unsigned int *pins;233		struct cv1800_pin_mux_config *pinmuxs;234		u32 config, power;235		int i;236 237		if (npins < 1) {238			dev_err(dev, "invalid pinctrl group %pOFn.%pOFn\n",239				np, child);240			ret = -EINVAL;241			goto dt_failed;242		}243 244		grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn",245					 np, child);246		if (!grpname) {247			ret = -ENOMEM;248			goto dt_failed;249		}250 251		grpnames[ngroups++] = grpname;252 253		pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);254		if (!pins) {255			ret = -ENOMEM;256			goto dt_failed;257		}258 259		pinmuxs = devm_kcalloc(dev, npins, sizeof(*pinmuxs), GFP_KERNEL);260		if (!pinmuxs) {261			ret = -ENOMEM;262			goto dt_failed;263		}264 265		for (i = 0; i < npins; i++) {266			ret = of_property_read_u32_index(child, "pinmux",267							 i, &config);268			if (ret)269				goto dt_failed;270 271			pins[i] = cv1800_dt_get_pin(config);272			pinmuxs[i].config = config;273			pinmuxs[i].pin = cv1800_get_pin(pctrl, pins[i]);274 275			if (!pinmuxs[i].pin) {276				dev_err(dev, "failed to get pin %d\n", pins[i]);277				ret = -ENODEV;278				goto dt_failed;279			}280 281			ret = cv1800_verify_pinmux_config(&pinmuxs[i]);282			if (ret) {283				dev_err(dev, "group %s pin %d is invalid\n",284					grpname, i);285				goto dt_failed;286			}287		}288 289		ret = cv1800_verify_pin_group(pinmuxs, npins);290		if (ret) {291			dev_err(dev, "group %s is invalid\n", grpname);292			goto dt_failed;293		}294 295		ret = of_property_read_u32(child, "power-source", &power);296		if (ret)297			goto dt_failed;298 299		if (!(power == PIN_POWER_STATE_3V3 || power == PIN_POWER_STATE_1V8)) {300			dev_err(dev, "group %s have unsupported power: %u\n",301				grpname, power);302			ret = -ENOTSUPP;303			goto dt_failed;304		}305 306		ret = cv1800_set_power_cfg(pctrl, pinmuxs[0].pin->power_domain,307					   power);308		if (ret)309			goto dt_failed;310 311		map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;312		map[nmaps].data.mux.function = np->name;313		map[nmaps].data.mux.group = grpname;314		nmaps += 1;315 316		ret = pinconf_generic_parse_dt_config(child, pctldev,317						      &map[nmaps].data.configs.configs,318						      &map[nmaps].data.configs.num_configs);319		if (ret) {320			dev_err(dev, "failed to parse pin config of group %s: %d\n",321				grpname, ret);322			goto dt_failed;323		}324 325		ret = pinctrl_generic_add_group(pctldev, grpname,326						pins, npins, pinmuxs);327		if (ret < 0) {328			dev_err(dev, "failed to add group %s: %d\n", grpname, ret);329			goto dt_failed;330		}331 332		/* don't create a map if there are no pinconf settings */333		if (map[nmaps].data.configs.num_configs == 0)334			continue;335 336		map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;337		map[nmaps].data.configs.group_or_pin = grpname;338		nmaps += 1;339	}340 341	ret = pinmux_generic_add_function(pctldev, np->name,342					  grpnames, ngroups, NULL);343	if (ret < 0) {344		dev_err(dev, "error adding function %s: %d\n", np->name, ret);345		goto function_failed;346	}347 348	*maps = map;349	*num_maps = nmaps;350	mutex_unlock(&pctrl->mutex);351 352	return 0;353 354dt_failed:355	of_node_put(child);356function_failed:357	pinctrl_utils_free_map(pctldev, map, nmaps);358	mutex_unlock(&pctrl->mutex);359	return ret;360}361 362static const struct pinctrl_ops cv1800_pctrl_ops = {363	.get_groups_count	= pinctrl_generic_get_group_count,364	.get_group_name		= pinctrl_generic_get_group_name,365	.get_group_pins		= pinctrl_generic_get_group_pins,366	.pin_dbg_show		= cv1800_pctrl_dbg_show,367	.dt_node_to_map		= cv1800_pctrl_dt_node_to_map,368	.dt_free_map		= pinctrl_utils_free_map,369};370 371static int cv1800_pmx_set_mux(struct pinctrl_dev *pctldev,372			      unsigned int fsel, unsigned int gsel)373{374	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);375	const struct group_desc *group;376	const struct cv1800_pin_mux_config *configs;377	unsigned int i;378 379	group = pinctrl_generic_get_group(pctldev, gsel);380	if (!group)381		return -EINVAL;382 383	configs = group->data;384 385	for (i = 0; i < group->grp.npins; i++) {386		const struct cv1800_pin *pin = configs[i].pin;387		u32 value = configs[i].config;388		void __iomem *reg_mux;389		void __iomem *reg_mux2;390		unsigned long flags;391		u32 mux;392		u32 mux2;393 394		reg_mux = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);395		reg_mux2 = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);396		mux = cv1800_dt_get_pin_mux(value);397		mux2 = cv1800_dt_get_pin_mux2(value);398 399		raw_spin_lock_irqsave(&pctrl->lock, flags);400		writel_relaxed(mux, reg_mux);401		if (mux2 != PIN_MUX_INVALD)402			writel_relaxed(mux2, reg_mux2);403		raw_spin_unlock_irqrestore(&pctrl->lock, flags);404	}405 406	return 0;407}408 409static const struct pinmux_ops cv1800_pmx_ops = {410	.get_functions_count	= pinmux_generic_get_function_count,411	.get_function_name	= pinmux_generic_get_function_name,412	.get_function_groups	= pinmux_generic_get_function_groups,413	.set_mux		= cv1800_pmx_set_mux,414	.strict			= true,415};416 417#define PIN_IO_PULLUP		BIT(2)418#define PIN_IO_PULLDOWN		BIT(3)419#define PIN_IO_DRIVE		GENMASK(7, 5)420#define PIN_IO_SCHMITT		GENMASK(9, 8)421#define PIN_IO_BUS_HOLD		BIT(10)422#define PIN_IO_OUT_FAST_SLEW	BIT(11)423 424static u32 cv1800_pull_down_typical_resistor(struct cv1800_pinctrl *pctrl,425					     struct cv1800_pin *pin)426{427	return pctrl->data->vddio_ops->get_pull_down(pin, pctrl->power_cfg);428}429 430static u32 cv1800_pull_up_typical_resistor(struct cv1800_pinctrl *pctrl,431					   struct cv1800_pin *pin)432{433	return pctrl->data->vddio_ops->get_pull_up(pin, pctrl->power_cfg);434}435 436static int cv1800_pinctrl_oc2reg(struct cv1800_pinctrl *pctrl,437				 struct cv1800_pin *pin, u32 target)438{439	const u32 *map;440	int i, len;441 442	len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);443	if (len < 0)444		return len;445 446	for (i = 0; i < len; i++) {447		if (map[i] >= target)448			return i;449	}450 451	return -EINVAL;452}453 454static int cv1800_pinctrl_reg2oc(struct cv1800_pinctrl *pctrl,455				 struct cv1800_pin *pin, u32 reg)456{457	const u32 *map;458	int len;459 460	len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);461	if (len < 0)462		return len;463 464	if (reg >= len)465		return -EINVAL;466 467	return map[reg];468}469 470static int cv1800_pinctrl_schmitt2reg(struct cv1800_pinctrl *pctrl,471				      struct cv1800_pin *pin, u32 target)472{473	const u32 *map;474	int i, len;475 476	len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,477						      &map);478	if (len < 0)479		return len;480 481	for (i = 0; i < len; i++) {482		if (map[i] == target)483			return i;484	}485 486	return -EINVAL;487}488 489static int cv1800_pinctrl_reg2schmitt(struct cv1800_pinctrl *pctrl,490				      struct cv1800_pin *pin, u32 reg)491{492	const u32 *map;493	int len;494 495	len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,496						      &map);497	if (len < 0)498		return len;499 500	if (reg >= len)501		return -EINVAL;502 503	return map[reg];504}505 506static int cv1800_pconf_get(struct pinctrl_dev *pctldev,507			    unsigned int pin_id, unsigned long *config)508{509	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);510	int param = pinconf_to_config_param(*config);511	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);512	enum cv1800_pin_io_type type;513	u32 value;514	u32 arg;515	bool enabled;516	int ret;517 518	if (!pin)519		return -EINVAL;520 521	type = cv1800_pin_io_type(pin);522	if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)523		return -ENOTSUPP;524 525	value = readl(cv1800_pinctrl_get_component_addr(pctrl, &pin->conf));526 527	switch (param) {528	case PIN_CONFIG_BIAS_PULL_DOWN:529		enabled = FIELD_GET(PIN_IO_PULLDOWN, value);530		arg = cv1800_pull_down_typical_resistor(pctrl, pin);531		break;532	case PIN_CONFIG_BIAS_PULL_UP:533		enabled = FIELD_GET(PIN_IO_PULLUP, value);534		arg = cv1800_pull_up_typical_resistor(pctrl, pin);535		break;536	case PIN_CONFIG_DRIVE_STRENGTH_UA:537		enabled = true;538		arg = FIELD_GET(PIN_IO_DRIVE, value);539		ret = cv1800_pinctrl_reg2oc(pctrl, pin, arg);540		if (ret < 0)541			return ret;542		arg = ret;543		break;544	case PIN_CONFIG_INPUT_SCHMITT_UV:545		arg = FIELD_GET(PIN_IO_SCHMITT, value);546		ret = cv1800_pinctrl_reg2schmitt(pctrl, pin, arg);547		if (ret < 0)548			return ret;549		arg = ret;550		enabled = arg != 0;551		break;552	case PIN_CONFIG_POWER_SOURCE:553		enabled = true;554		arg = cv1800_get_power_cfg(pctrl, pin->power_domain);555		break;556	case PIN_CONFIG_SLEW_RATE:557		enabled = true;558		arg = FIELD_GET(PIN_IO_OUT_FAST_SLEW, value);559		break;560	case PIN_CONFIG_BIAS_BUS_HOLD:561		arg = FIELD_GET(PIN_IO_BUS_HOLD, value);562		enabled = arg != 0;563		break;564	default:565		return -ENOTSUPP;566	}567 568	*config = pinconf_to_config_packed(param, arg);569 570	return enabled ? 0 : -EINVAL;571}572 573static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,574					 struct cv1800_pin *pin,575					 unsigned long *configs,576					 unsigned int num_configs,577					 u32 *value)578{579	int i;580	u32 v = 0;581	enum cv1800_pin_io_type type;582	int ret;583 584	if (!pin)585		return -EINVAL;586 587	type = cv1800_pin_io_type(pin);588	if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)589		return -ENOTSUPP;590 591	for (i = 0; i < num_configs; i++) {592		int param = pinconf_to_config_param(configs[i]);593		u32 arg = pinconf_to_config_argument(configs[i]);594 595		switch (param) {596		case PIN_CONFIG_BIAS_PULL_DOWN:597			v &= ~PIN_IO_PULLDOWN;598			v |= FIELD_PREP(PIN_IO_PULLDOWN, arg);599			break;600		case PIN_CONFIG_BIAS_PULL_UP:601			v &= ~PIN_IO_PULLUP;602			v |= FIELD_PREP(PIN_IO_PULLUP, arg);603			break;604		case PIN_CONFIG_DRIVE_STRENGTH_UA:605			ret = cv1800_pinctrl_oc2reg(pctrl, pin, arg);606			if (ret < 0)607				return ret;608			v &= ~PIN_IO_DRIVE;609			v |= FIELD_PREP(PIN_IO_DRIVE, ret);610			break;611		case PIN_CONFIG_INPUT_SCHMITT_UV:612			ret = cv1800_pinctrl_schmitt2reg(pctrl, pin, arg);613			if (ret < 0)614				return ret;615			v &= ~PIN_IO_SCHMITT;616			v |= FIELD_PREP(PIN_IO_SCHMITT, ret);617			break;618		case PIN_CONFIG_POWER_SOURCE:619			/* Ignore power source as it is always fixed */620			break;621		case PIN_CONFIG_SLEW_RATE:622			v &= ~PIN_IO_OUT_FAST_SLEW;623			v |= FIELD_PREP(PIN_IO_OUT_FAST_SLEW, arg);624			break;625		case PIN_CONFIG_BIAS_BUS_HOLD:626			v &= ~PIN_IO_BUS_HOLD;627			v |= FIELD_PREP(PIN_IO_BUS_HOLD, arg);628			break;629		default:630			return -ENOTSUPP;631		}632	}633 634	*value = v;635 636	return 0;637}638 639static int cv1800_pin_set_config(struct cv1800_pinctrl *pctrl,640				 unsigned int pin_id,641				 u32 value)642{643	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);644	unsigned long flags;645	void __iomem *addr;646 647	if (!pin)648		return -EINVAL;649 650	addr = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);651 652	raw_spin_lock_irqsave(&pctrl->lock, flags);653	writel(value, addr);654	raw_spin_unlock_irqrestore(&pctrl->lock, flags);655 656	return 0;657}658 659static int cv1800_pconf_set(struct pinctrl_dev *pctldev,660			    unsigned int pin_id, unsigned long *configs,661			    unsigned int num_configs)662{663	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);664	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);665	u32 value;666 667	if (!pin)668		return -ENODEV;669 670	if (cv1800_pinconf_compute_config(pctrl, pin,671					  configs, num_configs, &value))672		return -ENOTSUPP;673 674	return cv1800_pin_set_config(pctrl, pin_id, value);675}676 677static int cv1800_pconf_group_set(struct pinctrl_dev *pctldev,678				  unsigned int gsel,679				  unsigned long *configs,680				  unsigned int num_configs)681{682	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);683	const struct group_desc *group;684	const struct cv1800_pin_mux_config *pinmuxs;685	u32 value;686	int i;687 688	group = pinctrl_generic_get_group(pctldev, gsel);689	if (!group)690		return -EINVAL;691 692	pinmuxs = group->data;693 694	if (cv1800_pinconf_compute_config(pctrl, pinmuxs[0].pin,695					  configs, num_configs, &value))696		return -ENOTSUPP;697 698	for (i = 0; i < group->grp.npins; i++)699		cv1800_pin_set_config(pctrl, group->grp.pins[i], value);700 701	return 0;702}703 704static const struct pinconf_ops cv1800_pconf_ops = {705	.pin_config_get			= cv1800_pconf_get,706	.pin_config_set			= cv1800_pconf_set,707	.pin_config_group_set		= cv1800_pconf_group_set,708	.is_generic			= true,709};710 711int cv1800_pinctrl_probe(struct platform_device *pdev)712{713	struct device *dev = &pdev->dev;714	struct cv1800_pinctrl *pctrl;715	const struct cv1800_pinctrl_data *pctrl_data;716	int ret;717 718	pctrl_data = device_get_match_data(dev);719	if (!pctrl_data)720		return -ENODEV;721 722	if (pctrl_data->npins == 0 || pctrl_data->npd == 0)723		return dev_err_probe(dev, -EINVAL, "invalid pin data\n");724 725	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);726	if (!pctrl)727		return -ENOMEM;728 729	pctrl->power_cfg = devm_kcalloc(dev, pctrl_data->npd,730					sizeof(u32), GFP_KERNEL);731	if (!pctrl->power_cfg)732		return -ENOMEM;733 734	pctrl->regs[0] = devm_platform_ioremap_resource_byname(pdev, "sys");735	if (IS_ERR(pctrl->regs[0]))736		return PTR_ERR(pctrl->regs[0]);737 738	pctrl->regs[1] = devm_platform_ioremap_resource_byname(pdev, "rtc");739	if (IS_ERR(pctrl->regs[1]))740		return PTR_ERR(pctrl->regs[1]);741 742	pctrl->pdesc.name = dev_name(dev);743	pctrl->pdesc.pins = pctrl_data->pins;744	pctrl->pdesc.npins = pctrl_data->npins;745	pctrl->pdesc.pctlops = &cv1800_pctrl_ops;746	pctrl->pdesc.pmxops = &cv1800_pmx_ops;747	pctrl->pdesc.confops = &cv1800_pconf_ops;748	pctrl->pdesc.owner = THIS_MODULE;749 750	pctrl->data = pctrl_data;751	pctrl->dev = dev;752	raw_spin_lock_init(&pctrl->lock);753	mutex_init(&pctrl->mutex);754 755	platform_set_drvdata(pdev, pctrl);756 757	ret = devm_pinctrl_register_and_init(dev, &pctrl->pdesc,758					     pctrl, &pctrl->pctl_dev);759	if (ret)760		return dev_err_probe(dev, ret,761				     "fail to register pinctrl driver\n");762 763	return pinctrl_enable(pctrl->pctl_dev);764}765EXPORT_SYMBOL_GPL(cv1800_pinctrl_probe);766