From 2afbbab45c261abf5a03584b164a526933995efd Mon Sep 17 00:00:00 2001 From: Colin Foster Date: Fri, 19 Nov 2021 11:59:28 -0800 Subject: [PATCH] pinctrl: microchip-sgpio: update to support regmap Adopt regmap instead of a direct memory map so that custom regmaps and other interfaces can be supported. Signed-off-by: Colin Foster Link: https://lore.kernel.org/r/20211119195928.2498441-5-colin.foster@in-advantage.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-microchip-sgpio.c | 47 +++++++++++++++++------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index 78765faa245a..8e081c90bdb2 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "core.h" @@ -113,7 +114,7 @@ struct sgpio_priv { u32 bitcount; u32 ports; u32 clock; - u32 __iomem *regs; + struct regmap *regs; const struct sgpio_properties *properties; }; @@ -134,31 +135,42 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit) return bit + port * priv->bitcount; } -static inline u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off) +static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off) { - u32 __iomem *reg = &priv->regs[priv->properties->regoff[rno] + off]; - - return readl(reg); + return priv->properties->regoff[rno] + off; } -static inline void sgpio_writel(struct sgpio_priv *priv, +static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off) +{ + u32 addr = sgpio_get_addr(priv, rno, off); + u32 val = 0; + int ret; + + ret = regmap_read(priv->regs, addr, &val); + WARN_ONCE(ret, "error reading sgpio reg %d\n", ret); + + return val; +} + +static void sgpio_writel(struct sgpio_priv *priv, u32 val, u32 rno, u32 off) { - u32 __iomem *reg = &priv->regs[priv->properties->regoff[rno] + off]; + u32 addr = sgpio_get_addr(priv, rno, off); + int ret; - writel(val, reg); + ret = regmap_write(priv->regs, addr, val); + WARN_ONCE(ret, "error writing sgpio reg %d\n", ret); } static inline void sgpio_clrsetbits(struct sgpio_priv *priv, u32 rno, u32 off, u32 clear, u32 set) { - u32 __iomem *reg = &priv->regs[priv->properties->regoff[rno] + off]; - u32 val = readl(reg); + u32 val = sgpio_readl(priv, rno, off); val &= ~clear; val |= set; - writel(val, reg); + sgpio_writel(priv, val, rno, off); } static inline void sgpio_configure_bitstream(struct sgpio_priv *priv) @@ -807,7 +819,13 @@ static int microchip_sgpio_probe(struct platform_device *pdev) struct reset_control *reset; struct sgpio_priv *priv; struct clk *clk; + u32 __iomem *regs; u32 val; + struct regmap_config regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + }; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -832,9 +850,14 @@ static int microchip_sgpio_probe(struct platform_device *pdev) return -EINVAL; } - priv->regs = devm_platform_ioremap_resource(pdev, 0); + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + priv->regs = devm_regmap_init_mmio(dev, regs, ®map_config); if (IS_ERR(priv->regs)) return PTR_ERR(priv->regs); + priv->properties = device_get_match_data(dev); priv->in.is_input = true;