hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/pinctrl/pinctrl-single.c
....@@ -42,6 +42,7 @@
4242 * struct pcs_func_vals - mux function register offset and value pair
4343 * @reg: register virtual address
4444 * @val: register value
45
+ * @mask: mask
4546 */
4647 struct pcs_func_vals {
4748 void __iomem *reg;
....@@ -83,6 +84,8 @@
8384 * @nvals: number of entries in vals array
8485 * @pgnames: array of pingroup names the function uses
8586 * @npgnames: number of pingroup names the function uses
87
+ * @conf: array of pin configurations
88
+ * @nconfs: number of pin configurations available
8689 * @node: list node
8790 */
8891 struct pcs_function {
....@@ -267,20 +270,44 @@
267270 writel(val, reg);
268271 }
269272
273
+static unsigned int pcs_pin_reg_offset_get(struct pcs_device *pcs,
274
+ unsigned int pin)
275
+{
276
+ unsigned int mux_bytes = pcs->width / BITS_PER_BYTE;
277
+
278
+ if (pcs->bits_per_mux) {
279
+ unsigned int pin_offset_bytes;
280
+
281
+ pin_offset_bytes = (pcs->bits_per_pin * pin) / BITS_PER_BYTE;
282
+ return (pin_offset_bytes / mux_bytes) * mux_bytes;
283
+ }
284
+
285
+ return pin * mux_bytes;
286
+}
287
+
288
+static unsigned int pcs_pin_shift_reg_get(struct pcs_device *pcs,
289
+ unsigned int pin)
290
+{
291
+ return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin;
292
+}
293
+
270294 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
271295 struct seq_file *s,
272296 unsigned pin)
273297 {
274298 struct pcs_device *pcs;
275
- unsigned val, mux_bytes;
299
+ unsigned int val;
276300 unsigned long offset;
277301 size_t pa;
278302
279303 pcs = pinctrl_dev_get_drvdata(pctldev);
280304
281
- mux_bytes = pcs->width / BITS_PER_BYTE;
282
- offset = pin * mux_bytes;
305
+ offset = pcs_pin_reg_offset_get(pcs, pin);
283306 val = pcs->read(pcs->base + offset);
307
+
308
+ if (pcs->bits_per_mux)
309
+ val &= pcs->fmask << pcs_pin_shift_reg_get(pcs, pin);
310
+
284311 pa = pcs->res->start + offset;
285312
286313 seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME);
....@@ -345,6 +372,8 @@
345372 if (!pcs->fmask)
346373 return 0;
347374 function = pinmux_generic_get_function(pctldev, fselector);
375
+ if (!function)
376
+ return -EINVAL;
348377 func = function->data;
349378 if (!func)
350379 return -EINVAL;
....@@ -381,7 +410,6 @@
381410 struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
382411 struct pcs_gpiofunc_range *frange = NULL;
383412 struct list_head *pos, *tmp;
384
- int mux_bytes = 0;
385413 unsigned data;
386414
387415 /* If function mask is null, return directly. */
....@@ -389,29 +417,27 @@
389417 return -ENOTSUPP;
390418
391419 list_for_each_safe(pos, tmp, &pcs->gpiofuncs) {
420
+ u32 offset;
421
+
392422 frange = list_entry(pos, struct pcs_gpiofunc_range, node);
393423 if (pin >= frange->offset + frange->npins
394424 || pin < frange->offset)
395425 continue;
396
- mux_bytes = pcs->width / BITS_PER_BYTE;
426
+
427
+ offset = pcs_pin_reg_offset_get(pcs, pin);
397428
398429 if (pcs->bits_per_mux) {
399
- int byte_num, offset, pin_shift;
400
-
401
- byte_num = (pcs->bits_per_pin * pin) / BITS_PER_BYTE;
402
- offset = (byte_num / mux_bytes) * mux_bytes;
403
- pin_shift = pin % (pcs->width / pcs->bits_per_pin) *
404
- pcs->bits_per_pin;
430
+ int pin_shift = pcs_pin_shift_reg_get(pcs, pin);
405431
406432 data = pcs->read(pcs->base + offset);
407433 data &= ~(pcs->fmask << pin_shift);
408434 data |= frange->gpiofunc << pin_shift;
409435 pcs->write(data, pcs->base + offset);
410436 } else {
411
- data = pcs->read(pcs->base + pin * mux_bytes);
437
+ data = pcs->read(pcs->base + offset);
412438 data &= ~pcs->fmask;
413439 data |= frange->gpiofunc;
414
- pcs->write(data, pcs->base + pin * mux_bytes);
440
+ pcs->write(data, pcs->base + offset);
415441 }
416442 break;
417443 }
....@@ -560,7 +586,7 @@
560586 case PIN_CONFIG_BIAS_PULL_UP:
561587 if (arg)
562588 pcs_pinconf_clear_bias(pctldev, pin);
563
- /* fall through */
589
+ fallthrough;
564590 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
565591 data &= ~func->conf[i].mask;
566592 if (arg)
....@@ -654,8 +680,7 @@
654680 * @pcs: pcs driver instance
655681 * @offset: register offset from base
656682 */
657
-static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
658
- unsigned pin_pos)
683
+static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset)
659684 {
660685 struct pcs_soc_data *pcs_soc = &pcs->socdata;
661686 struct pinctrl_pin_desc *pin;
....@@ -703,7 +728,7 @@
703728
704729 mux_bytes = pcs->width / BITS_PER_BYTE;
705730
706
- if (pcs->bits_per_mux) {
731
+ if (pcs->bits_per_mux && pcs->fmask) {
707732 pcs->bits_per_pin = fls(pcs->fmask);
708733 nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin;
709734 num_pins_in_register = pcs->width / pcs->bits_per_pin;
....@@ -724,17 +749,9 @@
724749 for (i = 0; i < pcs->desc.npins; i++) {
725750 unsigned offset;
726751 int res;
727
- int byte_num;
728
- int pin_pos = 0;
729752
730
- if (pcs->bits_per_mux) {
731
- byte_num = (pcs->bits_per_pin * i) / BITS_PER_BYTE;
732
- offset = (byte_num / mux_bytes) * mux_bytes;
733
- pin_pos = i % num_pins_in_register;
734
- } else {
735
- offset = i * mux_bytes;
736
- }
737
- res = pcs_add_pin(pcs, offset, pin_pos);
753
+ offset = pcs_pin_reg_offset_get(pcs, i);
754
+ res = pcs_add_pin(pcs, offset);
738755 if (res < 0) {
739756 dev_err(pcs->dev, "error adding pins: %i\n", res);
740757 return res;
....@@ -958,8 +975,7 @@
958975 }
959976
960977 /**
961
- * smux_parse_one_pinctrl_entry() - parses a device tree mux entry
962
- * @pctldev: pin controller device
978
+ * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry
963979 * @pcs: pinctrl driver instance
964980 * @np: device node of the mux entry
965981 * @map: map entry
....@@ -1011,25 +1027,32 @@
10111027 if (res)
10121028 return res;
10131029
1014
- if (pinctrl_spec.args_count < 2) {
1030
+ if (pinctrl_spec.args_count < 2 || pinctrl_spec.args_count > 3) {
10151031 dev_err(pcs->dev, "invalid args_count for spec: %i\n",
10161032 pinctrl_spec.args_count);
10171033 break;
10181034 }
10191035
1020
- /* Index plus one value cell */
10211036 offset = pinctrl_spec.args[0];
10221037 vals[found].reg = pcs->base + offset;
1023
- vals[found].val = pinctrl_spec.args[1];
10241038
1025
- dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n",
1026
- pinctrl_spec.np->name, offset, pinctrl_spec.args[1]);
1039
+ switch (pinctrl_spec.args_count) {
1040
+ case 2:
1041
+ vals[found].val = pinctrl_spec.args[1];
1042
+ break;
1043
+ case 3:
1044
+ vals[found].val = (pinctrl_spec.args[1] | pinctrl_spec.args[2]);
1045
+ break;
1046
+ }
1047
+
1048
+ dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n",
1049
+ pinctrl_spec.np, offset, vals[found].val);
10271050
10281051 pin = pcs_get_pin_by_offset(pcs, offset);
10291052 if (pin < 0) {
10301053 dev_err(pcs->dev,
1031
- "could not add functions for %s %ux\n",
1032
- np->name, offset);
1054
+ "could not add functions for %pOFn %ux\n",
1055
+ np, offset);
10331056 break;
10341057 }
10351058 pins[found++] = pin;
....@@ -1138,8 +1161,8 @@
11381161 val = pinctrl_spec.args[1];
11391162 mask = pinctrl_spec.args[2];
11401163
1141
- dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n",
1142
- pinctrl_spec.np->name, offset, val, mask);
1164
+ dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x mask: 0x%x\n",
1165
+ pinctrl_spec.np, offset, val, mask);
11431166
11441167 /* Parse pins in each row from LSB */
11451168 while (mask) {
....@@ -1151,8 +1174,8 @@
11511174
11521175 if ((mask & mask_pos) == 0) {
11531176 dev_err(pcs->dev,
1154
- "Invalid mask for %s at 0x%x\n",
1155
- np->name, offset);
1177
+ "Invalid mask for %pOFn at 0x%x\n",
1178
+ np, offset);
11561179 break;
11571180 }
11581181
....@@ -1160,8 +1183,8 @@
11601183
11611184 if (submask != mask_pos) {
11621185 dev_warn(pcs->dev,
1163
- "Invalid submask 0x%x for %s at 0x%x\n",
1164
- submask, np->name, offset);
1186
+ "Invalid submask 0x%x for %pOFn at 0x%x\n",
1187
+ submask, np, offset);
11651188 continue;
11661189 }
11671190
....@@ -1172,8 +1195,8 @@
11721195 pin = pcs_get_pin_by_offset(pcs, offset);
11731196 if (pin < 0) {
11741197 dev_err(pcs->dev,
1175
- "could not add functions for %s %ux\n",
1176
- np->name, offset);
1198
+ "could not add functions for %pOFn %ux\n",
1199
+ np, offset);
11771200 break;
11781201 }
11791202 pins[found++] = pin + pin_num_from_lsb;
....@@ -1258,16 +1281,16 @@
12581281 ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map,
12591282 num_maps, pgnames);
12601283 if (ret < 0) {
1261
- dev_err(pcs->dev, "no pins entries for %s\n",
1262
- np_config->name);
1284
+ dev_err(pcs->dev, "no pins entries for %pOFn\n",
1285
+ np_config);
12631286 goto free_pgnames;
12641287 }
12651288 } else {
12661289 ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
12671290 num_maps, pgnames);
12681291 if (ret < 0) {
1269
- dev_err(pcs->dev, "no pins entries for %s\n",
1270
- np_config->name);
1292
+ dev_err(pcs->dev, "no pins entries for %pOFn\n",
1293
+ np_config);
12711294 goto free_pgnames;
12721295 }
12731296 }
....@@ -1347,7 +1370,9 @@
13471370 }
13481371 return ret;
13491372 }
1373
+
13501374 /**
1375
+ * struct pcs_interrupt
13511376 * @reg: virtual address of interrupt register
13521377 * @hwirq: hardware irq number
13531378 * @irq: virtual irq number
....@@ -1362,6 +1387,9 @@
13621387
13631388 /**
13641389 * pcs_irq_set() - enables or disables an interrupt
1390
+ * @pcs_soc: SoC specific settings
1391
+ * @irq: interrupt
1392
+ * @enable: enable or disable the interrupt
13651393 *
13661394 * Note that this currently assumes one interrupt per pinctrl
13671395 * register that is typically used for wake-up events.
....@@ -1442,7 +1470,7 @@
14421470
14431471 /**
14441472 * pcs_irq_handle() - common interrupt handler
1445
- * @pcs_irq: interrupt data
1473
+ * @pcs_soc: SoC specific settings
14461474 *
14471475 * Note that this currently assumes we have one interrupt bit per
14481476 * mux register. This interrupt is typically used for wake-up events.
....@@ -1490,7 +1518,6 @@
14901518
14911519 /**
14921520 * pcs_irq_handle() - handler for the dedicated chained interrupt case
1493
- * @irq: interrupt
14941521 * @desc: interrupt descriptor
14951522 *
14961523 * Use this if you have a separate interrupt for each