Skip to content

Commit f28cbab

Browse files
Sean AndersonLinus Walleij
authored andcommitted
pinctrl: zynqmp: Support muxing individual pins
While muxing groups of pins at once can be convenient for large interfaces, it can also be rigid. This is because the group is set to all pins which support a particular function, even though not all pins may be used. For example, the sdhci0 function may be used with a 8-bit eMMC, 4-bit SD card, or even a 1-bit SD card. In these cases, the extra pins may be repurposed for other uses, but this is not currently allowed. There is not too much point in pin "groups" when there are not actual pin groups at the hardware level. The pins can all be muxed individually, so there's no point in adding artificial groups on top. Just mux the pins like the hardware allows. To this effect, add a new group for each pin which can be muxed. These groups are part of each function the pin can be muxed to. We treat group selectors beyond the number of groups as "pin" groups. To set this up, we initialize groups before functions, and then create a bitmap of used pins for each function. These used pins are appended to the function's list of groups. Signed-off-by: Sean Anderson <sean.anderson@linux.dev> Reviewed-by: Sai Krishna Potthuri <sai.krishna.potthuri@amd.com> Acked-by: Michal Simek <michal.simek@amd.com> Link: https://lore.kernel.org/r/20240610223550.2449230-3-sean.anderson@linux.dev Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 58ba921 commit f28cbab

1 file changed

Lines changed: 54 additions & 29 deletions

File tree

drivers/pinctrl/pinctrl-zynqmp.c

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
1212

13+
#include <linux/bitmap.h>
1314
#include <linux/init.h>
1415
#include <linux/module.h>
1516
#include <linux/of_address.h>
@@ -97,15 +98,18 @@ static int zynqmp_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
9798
{
9899
struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
99100

100-
return pctrl->ngroups;
101+
return pctrl->ngroups + zynqmp_desc.npins;
101102
}
102103

103104
static const char *zynqmp_pctrl_get_group_name(struct pinctrl_dev *pctldev,
104105
unsigned int selector)
105106
{
106107
struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
107108

108-
return pctrl->groups[selector].name;
109+
if (selector < pctrl->ngroups)
110+
return pctrl->groups[selector].name;
111+
112+
return zynqmp_desc.pins[selector - pctrl->ngroups].name;
109113
}
110114

111115
static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
@@ -115,8 +119,13 @@ static int zynqmp_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
115119
{
116120
struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
117121

118-
*pins = pctrl->groups[selector].pins;
119-
*npins = pctrl->groups[selector].npins;
122+
if (selector < pctrl->ngroups) {
123+
*pins = pctrl->groups[selector].pins;
124+
*npins = pctrl->groups[selector].npins;
125+
} else {
126+
*pins = &zynqmp_desc.pins[selector - pctrl->ngroups].number;
127+
*npins = 1;
128+
}
120129

121130
return 0;
122131
}
@@ -197,17 +206,16 @@ static int zynqmp_pinmux_set_mux(struct pinctrl_dev *pctldev,
197206
unsigned int function,
198207
unsigned int group)
199208
{
200-
struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
201-
const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[group];
209+
const unsigned int *pins;
210+
unsigned int npins;
202211
int ret, i;
203212

204-
for (i = 0; i < pgrp->npins; i++) {
205-
unsigned int pin = pgrp->pins[i];
206-
207-
ret = zynqmp_pm_pinctrl_set_function(pin, function);
213+
zynqmp_pctrl_get_group_pins(pctldev, group, &pins, &npins);
214+
for (i = 0; i < npins; i++) {
215+
ret = zynqmp_pm_pinctrl_set_function(pins[i], function);
208216
if (ret) {
209217
dev_err(pctldev->dev, "set mux failed for pin %u\n",
210-
pin);
218+
pins[i]);
211219
return ret;
212220
}
213221
}
@@ -467,12 +475,13 @@ static int zynqmp_pinconf_group_set(struct pinctrl_dev *pctldev,
467475
unsigned long *configs,
468476
unsigned int num_configs)
469477
{
478+
const unsigned int *pins;
479+
unsigned int npins;
470480
int i, ret;
471-
struct zynqmp_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
472-
const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[selector];
473481

474-
for (i = 0; i < pgrp->npins; i++) {
475-
ret = zynqmp_pinconf_cfg_set(pctldev, pgrp->pins[i], configs,
482+
zynqmp_pctrl_get_group_pins(pctldev, selector, &pins, &npins);
483+
for (i = 0; i < npins; i++) {
484+
ret = zynqmp_pinconf_cfg_set(pctldev, pins[i], configs,
476485
num_configs);
477486
if (ret)
478487
return ret;
@@ -560,10 +569,12 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
560569
{
561570
u16 resp[NUM_GROUPS_PER_RESP] = {0};
562571
const char **fgroups;
563-
int ret, index, i;
572+
int ret, index, i, pin;
573+
unsigned int npins;
574+
unsigned long *used_pins __free(bitmap) =
575+
bitmap_zalloc(zynqmp_desc.npins, GFP_KERNEL);
564576

565-
fgroups = devm_kcalloc(dev, func->ngroups, sizeof(*fgroups), GFP_KERNEL);
566-
if (!fgroups)
577+
if (!used_pins)
567578
return -ENOMEM;
568579

569580
for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) {
@@ -578,23 +589,37 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid,
578589
if (resp[i] == RESERVED_GROUP)
579590
continue;
580591

581-
fgroups[index + i] = devm_kasprintf(dev, GFP_KERNEL,
582-
"%s_%d_grp",
583-
func->name,
584-
index + i);
585-
if (!fgroups[index + i])
586-
return -ENOMEM;
587-
588592
groups[resp[i]].name = devm_kasprintf(dev, GFP_KERNEL,
589593
"%s_%d_grp",
590594
func->name,
591595
index + i);
592596
if (!groups[resp[i]].name)
593597
return -ENOMEM;
598+
599+
for (pin = 0; pin < groups[resp[i]].npins; pin++)
600+
__set_bit(groups[resp[i]].pins[pin], used_pins);
594601
}
595602
}
596603
done:
604+
npins = bitmap_weight(used_pins, zynqmp_desc.npins);
605+
fgroups = devm_kcalloc(dev, size_add(func->ngroups, npins),
606+
sizeof(*fgroups), GFP_KERNEL);
607+
if (!fgroups)
608+
return -ENOMEM;
609+
610+
for (i = 0; i < func->ngroups; i++) {
611+
fgroups[i] = devm_kasprintf(dev, GFP_KERNEL, "%s_%d_grp",
612+
func->name, i);
613+
if (!fgroups[i])
614+
return -ENOMEM;
615+
}
616+
617+
pin = 0;
618+
for_each_set_bit(pin, used_pins, zynqmp_desc.npins)
619+
fgroups[i++] = zynqmp_desc.pins[pin].name;
620+
597621
func->groups = fgroups;
622+
func->ngroups += npins;
598623

599624
return 0;
600625
}
@@ -772,17 +797,17 @@ static int zynqmp_pinctrl_prepare_function_info(struct device *dev,
772797
if (!groups)
773798
return -ENOMEM;
774799

800+
ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups);
801+
if (ret)
802+
return ret;
803+
775804
for (i = 0; i < pctrl->nfuncs; i++) {
776805
ret = zynqmp_pinctrl_prepare_func_groups(dev, i, &funcs[i],
777806
groups);
778807
if (ret)
779808
return ret;
780809
}
781810

782-
ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups);
783-
if (ret)
784-
return ret;
785-
786811
pctrl->funcs = funcs;
787812
pctrl->groups = groups;
788813

0 commit comments

Comments
 (0)