1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * System Control and Power Interface (SCMI) Protocol based pinctrl driver
4  *
5  * Copyright (C) 2024 EPAM
6  * Copyright 2024 NXP
7  */
8 
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/errno.h>
12 #include <linux/module.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/of.h>
15 #include <linux/scmi_protocol.h>
16 #include <linux/slab.h>
17 #include <linux/types.h>
18 
19 #include <linux/pinctrl/machine.h>
20 #include <linux/pinctrl/pinconf.h>
21 #include <linux/pinctrl/pinconf-generic.h>
22 #include <linux/pinctrl/pinctrl.h>
23 #include <linux/pinctrl/pinmux.h>
24 
25 #include "pinctrl-utils.h"
26 #include "core.h"
27 #include "pinconf.h"
28 
29 #define DRV_NAME "scmi-pinctrl"
30 
31 /* Define num configs, if not large than 4 use stack, else use kcalloc() */
32 #define SCMI_NUM_CONFIGS	4
33 
34 static const struct scmi_pinctrl_proto_ops *pinctrl_ops;
35 
36 struct scmi_pinctrl {
37 	struct device *dev;
38 	struct scmi_protocol_handle *ph;
39 	struct pinctrl_dev *pctldev;
40 	struct pinctrl_desc pctl_desc;
41 	struct pinfunction *functions;
42 	unsigned int nr_functions;
43 	struct pinctrl_pin_desc *pins;
44 	unsigned int nr_pins;
45 };
46 
pinctrl_scmi_get_groups_count(struct pinctrl_dev * pctldev)47 static int pinctrl_scmi_get_groups_count(struct pinctrl_dev *pctldev)
48 {
49 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
50 
51 	return pinctrl_ops->count_get(pmx->ph, GROUP_TYPE);
52 }
53 
pinctrl_scmi_get_group_name(struct pinctrl_dev * pctldev,unsigned int selector)54 static const char *pinctrl_scmi_get_group_name(struct pinctrl_dev *pctldev,
55 					       unsigned int selector)
56 {
57 	int ret;
58 	const char *name;
59 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
60 
61 	ret = pinctrl_ops->name_get(pmx->ph, selector, GROUP_TYPE, &name);
62 	if (ret) {
63 		dev_err(pmx->dev, "get name failed with err %d", ret);
64 		return NULL;
65 	}
66 
67 	return name;
68 }
69 
pinctrl_scmi_get_group_pins(struct pinctrl_dev * pctldev,unsigned int selector,const unsigned int ** pins,unsigned int * num_pins)70 static int pinctrl_scmi_get_group_pins(struct pinctrl_dev *pctldev,
71 				       unsigned int selector,
72 				       const unsigned int **pins,
73 				       unsigned int *num_pins)
74 {
75 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
76 
77 	return pinctrl_ops->group_pins_get(pmx->ph, selector, pins, num_pins);
78 }
79 
80 static const struct pinctrl_ops pinctrl_scmi_pinctrl_ops = {
81 	.get_groups_count = pinctrl_scmi_get_groups_count,
82 	.get_group_name = pinctrl_scmi_get_group_name,
83 	.get_group_pins = pinctrl_scmi_get_group_pins,
84 #ifdef CONFIG_OF
85 	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
86 	.dt_free_map = pinconf_generic_dt_free_map,
87 #endif
88 };
89 
pinctrl_scmi_get_functions_count(struct pinctrl_dev * pctldev)90 static int pinctrl_scmi_get_functions_count(struct pinctrl_dev *pctldev)
91 {
92 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
93 
94 	return pinctrl_ops->count_get(pmx->ph, FUNCTION_TYPE);
95 }
96 
pinctrl_scmi_get_function_name(struct pinctrl_dev * pctldev,unsigned int selector)97 static const char *pinctrl_scmi_get_function_name(struct pinctrl_dev *pctldev,
98 						  unsigned int selector)
99 {
100 	int ret;
101 	const char *name;
102 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
103 
104 	ret = pinctrl_ops->name_get(pmx->ph, selector, FUNCTION_TYPE, &name);
105 	if (ret) {
106 		dev_err(pmx->dev, "get name failed with err %d", ret);
107 		return NULL;
108 	}
109 
110 	return name;
111 }
112 
pinctrl_scmi_get_function_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** p_groups,unsigned int * const p_num_groups)113 static int pinctrl_scmi_get_function_groups(struct pinctrl_dev *pctldev,
114 					    unsigned int selector,
115 					    const char * const **p_groups,
116 					    unsigned int * const p_num_groups)
117 {
118 	struct pinfunction *func;
119 	const unsigned int *group_ids;
120 	unsigned int num_groups;
121 	const char **groups;
122 	int ret, i;
123 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
124 
125 	if (!p_groups || !p_num_groups)
126 		return -EINVAL;
127 
128 	if (selector >= pmx->nr_functions)
129 		return -EINVAL;
130 
131 	func = &pmx->functions[selector];
132 	if (func->ngroups)
133 		goto done;
134 
135 	ret = pinctrl_ops->function_groups_get(pmx->ph, selector, &num_groups,
136 					       &group_ids);
137 	if (ret) {
138 		dev_err(pmx->dev, "Unable to get function groups, err %d", ret);
139 		return ret;
140 	}
141 	if (!num_groups)
142 		return -EINVAL;
143 
144 	groups = kcalloc(num_groups, sizeof(*groups), GFP_KERNEL);
145 	if (!groups)
146 		return -ENOMEM;
147 
148 	for (i = 0; i < num_groups; i++) {
149 		groups[i] = pinctrl_scmi_get_group_name(pctldev, group_ids[i]);
150 		if (!groups[i]) {
151 			ret = -EINVAL;
152 			goto err_free;
153 		}
154 	}
155 
156 	func->ngroups = num_groups;
157 	func->groups = groups;
158 done:
159 	*p_groups = func->groups;
160 	*p_num_groups = func->ngroups;
161 
162 	return 0;
163 
164 err_free:
165 	kfree(groups);
166 
167 	return ret;
168 }
169 
pinctrl_scmi_func_set_mux(struct pinctrl_dev * pctldev,unsigned int selector,unsigned int group)170 static int pinctrl_scmi_func_set_mux(struct pinctrl_dev *pctldev,
171 				     unsigned int selector, unsigned int group)
172 {
173 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
174 
175 	return pinctrl_ops->mux_set(pmx->ph, selector, group);
176 }
177 
pinctrl_scmi_request(struct pinctrl_dev * pctldev,unsigned int offset)178 static int pinctrl_scmi_request(struct pinctrl_dev *pctldev,
179 				unsigned int offset)
180 {
181 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
182 
183 	return pinctrl_ops->pin_request(pmx->ph, offset);
184 }
185 
pinctrl_scmi_free(struct pinctrl_dev * pctldev,unsigned int offset)186 static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int offset)
187 {
188 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
189 
190 	return pinctrl_ops->pin_free(pmx->ph, offset);
191 }
192 
193 static const struct pinmux_ops pinctrl_scmi_pinmux_ops = {
194 	.request = pinctrl_scmi_request,
195 	.free = pinctrl_scmi_free,
196 	.get_functions_count = pinctrl_scmi_get_functions_count,
197 	.get_function_name = pinctrl_scmi_get_function_name,
198 	.get_function_groups = pinctrl_scmi_get_function_groups,
199 	.set_mux = pinctrl_scmi_func_set_mux,
200 };
201 
pinctrl_scmi_map_pinconf_type(enum pin_config_param param,enum scmi_pinctrl_conf_type * type)202 static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param,
203 					 enum scmi_pinctrl_conf_type *type)
204 {
205 	u32 arg = param;
206 
207 	switch (arg) {
208 	case PIN_CONFIG_BIAS_BUS_HOLD:
209 		*type = SCMI_PIN_BIAS_BUS_HOLD;
210 		break;
211 	case PIN_CONFIG_BIAS_DISABLE:
212 		*type = SCMI_PIN_BIAS_DISABLE;
213 		break;
214 	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
215 		*type = SCMI_PIN_BIAS_HIGH_IMPEDANCE;
216 		break;
217 	case PIN_CONFIG_BIAS_PULL_DOWN:
218 		*type = SCMI_PIN_BIAS_PULL_DOWN;
219 		break;
220 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
221 		*type = SCMI_PIN_BIAS_PULL_DEFAULT;
222 		break;
223 	case PIN_CONFIG_BIAS_PULL_UP:
224 		*type = SCMI_PIN_BIAS_PULL_UP;
225 		break;
226 	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
227 		*type = SCMI_PIN_DRIVE_OPEN_DRAIN;
228 		break;
229 	case PIN_CONFIG_DRIVE_OPEN_SOURCE:
230 		*type = SCMI_PIN_DRIVE_OPEN_SOURCE;
231 		break;
232 	case PIN_CONFIG_DRIVE_PUSH_PULL:
233 		*type = SCMI_PIN_DRIVE_PUSH_PULL;
234 		break;
235 	case PIN_CONFIG_DRIVE_STRENGTH:
236 		*type = SCMI_PIN_DRIVE_STRENGTH;
237 		break;
238 	case PIN_CONFIG_DRIVE_STRENGTH_UA:
239 		*type = SCMI_PIN_DRIVE_STRENGTH;
240 		break;
241 	case PIN_CONFIG_INPUT_DEBOUNCE:
242 		*type = SCMI_PIN_INPUT_DEBOUNCE;
243 		break;
244 	case PIN_CONFIG_INPUT_ENABLE:
245 		*type = SCMI_PIN_INPUT_MODE;
246 		break;
247 	case PIN_CONFIG_INPUT_SCHMITT:
248 		*type = SCMI_PIN_INPUT_SCHMITT;
249 		break;
250 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
251 		*type = SCMI_PIN_INPUT_MODE;
252 		break;
253 	case PIN_CONFIG_MODE_LOW_POWER:
254 		*type = SCMI_PIN_LOW_POWER_MODE;
255 		break;
256 	case PIN_CONFIG_OUTPUT:
257 		*type = SCMI_PIN_OUTPUT_VALUE;
258 		break;
259 	case PIN_CONFIG_OUTPUT_ENABLE:
260 		*type = SCMI_PIN_OUTPUT_MODE;
261 		break;
262 	case PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS:
263 		*type = SCMI_PIN_OUTPUT_VALUE;
264 		break;
265 	case PIN_CONFIG_POWER_SOURCE:
266 		*type = SCMI_PIN_POWER_SOURCE;
267 		break;
268 	case PIN_CONFIG_SLEW_RATE:
269 		*type = SCMI_PIN_SLEW_RATE;
270 		break;
271 	case SCMI_PIN_OEM_START ... SCMI_PIN_OEM_END:
272 		*type = arg;
273 		break;
274 	default:
275 		return -EINVAL;
276 	}
277 
278 	return 0;
279 }
280 
pinctrl_scmi_pinconf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)281 static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev,
282 				    unsigned int pin, unsigned long *config)
283 {
284 	int ret;
285 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
286 	enum pin_config_param config_type;
287 	enum scmi_pinctrl_conf_type type;
288 	u32 config_value;
289 
290 	if (!config)
291 		return -EINVAL;
292 
293 	config_type = pinconf_to_config_param(*config);
294 
295 	ret = pinctrl_scmi_map_pinconf_type(config_type, &type);
296 	if (ret)
297 		return ret;
298 
299 	ret = pinctrl_ops->settings_get_one(pmx->ph, pin, PIN_TYPE, type,
300 					    &config_value);
301 	/* Convert SCMI error code to PINCTRL expected error code */
302 	if (ret == -EOPNOTSUPP)
303 		return -ENOTSUPP;
304 	if (ret)
305 		return ret;
306 
307 	*config = pinconf_to_config_packed(config_type, config_value);
308 
309 	return 0;
310 }
311 
312 static int
pinctrl_scmi_alloc_configs(struct pinctrl_dev * pctldev,u32 num_configs,u32 ** p_config_value,enum scmi_pinctrl_conf_type ** p_config_type)313 pinctrl_scmi_alloc_configs(struct pinctrl_dev *pctldev, u32 num_configs,
314 			   u32 **p_config_value,
315 			   enum scmi_pinctrl_conf_type **p_config_type)
316 {
317 	if (num_configs <= SCMI_NUM_CONFIGS)
318 		return 0;
319 
320 	*p_config_value = kcalloc(num_configs, sizeof(**p_config_value), GFP_KERNEL);
321 	if (!*p_config_value)
322 		return -ENOMEM;
323 
324 	*p_config_type = kcalloc(num_configs, sizeof(**p_config_type), GFP_KERNEL);
325 	if (!*p_config_type) {
326 		kfree(*p_config_value);
327 		return -ENOMEM;
328 	}
329 
330 	return 0;
331 }
332 
333 static void
pinctrl_scmi_free_configs(struct pinctrl_dev * pctldev,u32 num_configs,u32 ** p_config_value,enum scmi_pinctrl_conf_type ** p_config_type)334 pinctrl_scmi_free_configs(struct pinctrl_dev *pctldev, u32 num_configs,
335 			  u32 **p_config_value,
336 			  enum scmi_pinctrl_conf_type **p_config_type)
337 {
338 	if (num_configs <= SCMI_NUM_CONFIGS)
339 		return;
340 
341 	kfree(*p_config_value);
342 	kfree(*p_config_type);
343 }
344 
pinctrl_scmi_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)345 static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev,
346 				    unsigned int pin,
347 				    unsigned long *configs,
348 				    unsigned int num_configs)
349 {
350 	int i, ret;
351 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
352 	enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
353 	u32 config_value[SCMI_NUM_CONFIGS];
354 	enum scmi_pinctrl_conf_type *p_config_type = config_type;
355 	u32 *p_config_value = config_value;
356 	enum pin_config_param param;
357 
358 	if (!configs || !num_configs)
359 		return -EINVAL;
360 
361 	ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
362 					 &p_config_value);
363 	if (ret)
364 		return ret;
365 
366 	for (i = 0; i < num_configs; i++) {
367 		param = pinconf_to_config_param(configs[i]);
368 		ret = pinctrl_scmi_map_pinconf_type(param, &p_config_type[i]);
369 		if (ret) {
370 			dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
371 			goto free_config;
372 		}
373 		p_config_value[i] = pinconf_to_config_argument(configs[i]);
374 	}
375 
376 	ret = pinctrl_ops->settings_conf(pmx->ph, pin, PIN_TYPE, num_configs,
377 					 p_config_type,  p_config_value);
378 	if (ret)
379 		dev_err(pmx->dev, "Error parsing config %d\n", ret);
380 
381 free_config:
382 	pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
383 				  &p_config_value);
384 	return ret;
385 }
386 
pinctrl_scmi_pinconf_group_set(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * configs,unsigned int num_configs)387 static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev,
388 					  unsigned int group,
389 					  unsigned long *configs,
390 					  unsigned int num_configs)
391 {
392 	int i, ret;
393 	struct scmi_pinctrl *pmx =  pinctrl_dev_get_drvdata(pctldev);
394 	enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
395 	u32 config_value[SCMI_NUM_CONFIGS];
396 	enum scmi_pinctrl_conf_type *p_config_type = config_type;
397 	u32 *p_config_value = config_value;
398 	enum pin_config_param param;
399 
400 	if (!configs || !num_configs)
401 		return -EINVAL;
402 
403 	ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
404 					 &p_config_value);
405 	if (ret)
406 		return ret;
407 
408 	for (i = 0; i < num_configs; i++) {
409 		param = pinconf_to_config_param(configs[i]);
410 		ret = pinctrl_scmi_map_pinconf_type(param, &p_config_type[i]);
411 		if (ret) {
412 			dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
413 			goto free_config;
414 		}
415 
416 		p_config_value[i] = pinconf_to_config_argument(configs[i]);
417 	}
418 
419 	ret = pinctrl_ops->settings_conf(pmx->ph, group, GROUP_TYPE,
420 					 num_configs, p_config_type,
421 					 p_config_value);
422 	if (ret)
423 		dev_err(pmx->dev, "Error parsing config %d", ret);
424 
425 free_config:
426 	pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
427 				  &p_config_value);
428 	return ret;
429 };
430 
pinctrl_scmi_pinconf_group_get(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * config)431 static int pinctrl_scmi_pinconf_group_get(struct pinctrl_dev *pctldev,
432 					  unsigned int group,
433 					  unsigned long *config)
434 {
435 	int ret;
436 	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
437 	enum pin_config_param config_type;
438 	enum scmi_pinctrl_conf_type type;
439 	u32 config_value;
440 
441 	if (!config)
442 		return -EINVAL;
443 
444 	config_type = pinconf_to_config_param(*config);
445 	ret = pinctrl_scmi_map_pinconf_type(config_type, &type);
446 	if (ret) {
447 		dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
448 		return ret;
449 	}
450 
451 	ret = pinctrl_ops->settings_get_one(pmx->ph, group, GROUP_TYPE, type,
452 					    &config_value);
453 	/* Convert SCMI error code to PINCTRL expected error code */
454 	if (ret == -EOPNOTSUPP)
455 		return -ENOTSUPP;
456 	if (ret)
457 		return ret;
458 
459 	*config = pinconf_to_config_packed(config_type, config_value);
460 
461 	return 0;
462 }
463 
464 static const struct pinconf_ops pinctrl_scmi_pinconf_ops = {
465 	.is_generic = true,
466 	.pin_config_get = pinctrl_scmi_pinconf_get,
467 	.pin_config_set = pinctrl_scmi_pinconf_set,
468 	.pin_config_group_set = pinctrl_scmi_pinconf_group_set,
469 	.pin_config_group_get = pinctrl_scmi_pinconf_group_get,
470 	.pin_config_config_dbg_show = pinconf_generic_dump_config,
471 };
472 
pinctrl_scmi_get_pins(struct scmi_pinctrl * pmx,struct pinctrl_desc * desc)473 static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
474 				 struct pinctrl_desc *desc)
475 {
476 	struct pinctrl_pin_desc *pins;
477 	unsigned int npins;
478 	int ret, i;
479 
480 	npins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE);
481 	/*
482 	 * npins will never be zero, the scmi pinctrl driver has bailed out
483 	 * if npins is zero.
484 	 */
485 	pins = devm_kmalloc_array(pmx->dev, npins, sizeof(*pins), GFP_KERNEL);
486 	if (!pins)
487 		return -ENOMEM;
488 
489 	for (i = 0; i < npins; i++) {
490 		pins[i].number = i;
491 		/*
492 		 * The memory for name is handled by the scmi firmware driver,
493 		 * no need free here
494 		 */
495 		ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE, &pins[i].name);
496 		if (ret)
497 			return dev_err_probe(pmx->dev, ret,
498 					     "Can't get name for pin %d", i);
499 	}
500 
501 	desc->npins = npins;
502 	desc->pins = pins;
503 	dev_dbg(pmx->dev, "got pins %u", npins);
504 
505 	return 0;
506 }
507 
508 static const char * const scmi_pinctrl_blocklist[] = {
509 	"fsl,imx95",
510 	NULL
511 };
512 
scmi_pinctrl_probe(struct scmi_device * sdev)513 static int scmi_pinctrl_probe(struct scmi_device *sdev)
514 {
515 	int ret;
516 	struct device *dev = &sdev->dev;
517 	struct scmi_pinctrl *pmx;
518 	const struct scmi_handle *handle;
519 	struct scmi_protocol_handle *ph;
520 
521 	if (!sdev->handle)
522 		return -EINVAL;
523 
524 	if (of_machine_compatible_match(scmi_pinctrl_blocklist))
525 		return -ENODEV;
526 
527 	handle = sdev->handle;
528 
529 	pinctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL, &ph);
530 	if (IS_ERR(pinctrl_ops))
531 		return PTR_ERR(pinctrl_ops);
532 
533 	pmx = devm_kzalloc(dev, sizeof(*pmx), GFP_KERNEL);
534 	if (!pmx)
535 		return -ENOMEM;
536 
537 	pmx->ph = ph;
538 
539 	pmx->dev = dev;
540 	pmx->pctl_desc.name = DRV_NAME;
541 	pmx->pctl_desc.owner = THIS_MODULE;
542 	pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops;
543 	pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops;
544 	pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops;
545 
546 	ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc);
547 	if (ret)
548 		return ret;
549 
550 	ret = devm_pinctrl_register_and_init(dev, &pmx->pctl_desc, pmx,
551 					     &pmx->pctldev);
552 	if (ret)
553 		return dev_err_probe(dev, ret, "Failed to register pinctrl\n");
554 
555 	pmx->nr_functions = pinctrl_scmi_get_functions_count(pmx->pctldev);
556 	pmx->functions = devm_kcalloc(dev, pmx->nr_functions,
557 				      sizeof(*pmx->functions), GFP_KERNEL);
558 	if (!pmx->functions)
559 		return -ENOMEM;
560 
561 	return pinctrl_enable(pmx->pctldev);
562 }
563 
564 static const struct scmi_device_id scmi_id_table[] = {
565 	{ SCMI_PROTOCOL_PINCTRL, "pinctrl" },
566 	{ }
567 };
568 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
569 
570 static struct scmi_driver scmi_pinctrl_driver = {
571 	.name = DRV_NAME,
572 	.probe = scmi_pinctrl_probe,
573 	.id_table = scmi_id_table,
574 };
575 module_scmi_driver(scmi_pinctrl_driver);
576 
577 MODULE_AUTHOR("Oleksii Moisieiev <oleksii_moisieiev@epam.com>");
578 MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
579 MODULE_DESCRIPTION("ARM SCMI pin controller driver");
580 MODULE_LICENSE("GPL");
581