Work is being done to convert drivers utilized by the VSC7514 chip to be
externally controlled via SPI instead of MMIO. The first step is to
abstract memory-mapped calls to use regmap.
That patch set has grown to 23 and counting. In order to keep that scope
minimized, I'm submitting this patchset to convert the two pinctrl
drivers to a regmap implementation.
This patch
pinctrl: ocelot: update pinctrl to automatic base address
is the only one that should have any functional changes, and therefore
has been tested. The rest should only impact what would be expected by
normal regmap abstraction.
Colin Foster (4):
pinctrl: ocelot: combine get resource and ioremap into single call
pinctrl: ocelot: update pinctrl to automatic base address
pinctrl: ocelot: convert pinctrl to regmap
pinctrl: microchip-sgpio: update to support regmap
drivers/pinctrl/pinctrl-microchip-sgpio.c | 45 +++++++++++----
drivers/pinctrl/pinctrl-ocelot.c | 69 ++++++++++++++++++-----
2 files changed, 90 insertions(+), 24 deletions(-)
--
2.25.1
In order to allow external control via SPI, memory-mapped areas must be
changed to use the generic regmap interface. This is step 1, and is
followed by an implementation that allows a custom regmap.
Signed-off-by: Colin Foster <[email protected]>
---
drivers/pinctrl/pinctrl-ocelot.c | 65 +++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
index 6941c1b45b00..b9acb80d6b3f 100644
--- a/drivers/pinctrl/pinctrl-ocelot.c
+++ b/drivers/pinctrl/pinctrl-ocelot.c
@@ -152,7 +152,7 @@ struct ocelot_pinctrl {
struct pinctrl_dev *pctl;
struct gpio_chip gpio_chip;
struct regmap *map;
- void __iomem *pincfg;
+ struct regmap *pincfg;
struct pinctrl_desc *desc;
struct ocelot_pmx_func func[FUNC_MAX];
u8 stride;
@@ -819,7 +819,11 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
int ret = -EOPNOTSUPP;
if (info->pincfg) {
- u32 regcfg = readl(info->pincfg + (pin * sizeof(u32)));
+ u32 regcfg;
+
+ ret = regmap_read(info->pincfg, pin, ®cfg);
+ if (ret)
+ return ret;
ret = 0;
switch (reg) {
@@ -843,6 +847,24 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
return ret;
}
+static int ocelot_pincfg_clrsetbits(struct ocelot_pinctrl *info, u32 regaddr,
+ u32 clrbits, u32 setbits)
+{
+ u32 val;
+ int ret;
+
+ ret = regmap_read(info->pincfg, regaddr, &val);
+ if (ret)
+ return ret;
+
+ val &= ~clrbits;
+ val |= setbits;
+
+ ret = regmap_write(info->pincfg, regaddr, val);
+
+ return ret;
+}
+
static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
unsigned int pin,
unsigned int reg,
@@ -851,21 +873,23 @@ static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
int ret = -EOPNOTSUPP;
if (info->pincfg) {
- void __iomem *regaddr = info->pincfg + (pin * sizeof(u32));
ret = 0;
switch (reg) {
case PINCONF_BIAS:
- ocelot_clrsetbits(regaddr, BIAS_BITS, val);
+ ret = ocelot_pincfg_clrsetbits(info, pin, BIAS_BITS,
+ val);
break;
case PINCONF_SCHMITT:
- ocelot_clrsetbits(regaddr, SCHMITT_BIT, val);
+ ret = ocelot_pincfg_clrsetbits(info, pin, SCHMITT_BIT,
+ val);
break;
case PINCONF_DRIVE_STRENGTH:
if (val <= 3)
- ocelot_clrsetbits(regaddr, DRIVE_BITS, val);
+ ret = ocelot_pincfg_clrsetbits(info, pin,
+ DRIVE_BITS, val);
else
ret = -EINVAL;
break;
@@ -1340,10 +1364,31 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
{},
};
+static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
+{
+ void __iomem *base;
+
+ const struct regmap_config regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 32,
+ };
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base)) {
+ dev_dbg(&pdev->dev, "Failed to ioremap config registers (no extended pinconf)\n");
+ return NULL;
+ }
+
+ return devm_regmap_init_mmio(&pdev->dev, base, ®map_config);
+}
+
static int ocelot_pinctrl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ocelot_pinctrl *info;
+ struct regmap *pincfg;
void __iomem *base;
int ret;
struct regmap_config regmap_config = {
@@ -1377,11 +1422,11 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
/* Pinconf registers */
if (info->desc->confops) {
- base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(base))
- dev_dbg(dev, "Failed to ioremap config registers (no extended pinconf)\n");
+ pincfg = ocelot_pinctrl_create_pincfg(pdev);
+ if (IS_ERR(pincfg))
+ dev_dbg(dev, "Failed to create pincfg regmap\n");
else
- info->pincfg = base;
+ info->pincfg = pincfg;
}
ret = ocelot_pinctrl_register(pdev, info);
--
2.25.1
On Fri, Nov 19, 2021 at 8:59 PM Colin Foster
<[email protected]> wrote:
> Colin Foster (4):
> pinctrl: ocelot: combine get resource and ioremap into single call
> pinctrl: ocelot: update pinctrl to automatic base address
> pinctrl: ocelot: convert pinctrl to regmap
> pinctrl: microchip-sgpio: update to support regmap
Patches applied to the pinctrl tree for v5.17!
If reviewers don't like that we can always pull them out or do
some fixes on top.
Yours,
Linus Walleij