Commit 2afbbab4 authored by Colin Foster's avatar Colin Foster Committed by Linus Walleij

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: default avatarColin Foster <colin.foster@in-advantage.com>
Link: https://lore.kernel.org/r/20211119195928.2498441-5-colin.foster@in-advantage.comSigned-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 076d9e71
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/regmap.h>
#include <linux/reset.h> #include <linux/reset.h>
#include "core.h" #include "core.h"
...@@ -113,7 +114,7 @@ struct sgpio_priv { ...@@ -113,7 +114,7 @@ struct sgpio_priv {
u32 bitcount; u32 bitcount;
u32 ports; u32 ports;
u32 clock; u32 clock;
u32 __iomem *regs; struct regmap *regs;
const struct sgpio_properties *properties; const struct sgpio_properties *properties;
}; };
...@@ -134,31 +135,42 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit) ...@@ -134,31 +135,42 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
return bit + port * priv->bitcount; 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)
{
return priv->properties->regoff[rno] + off;
}
static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
{ {
u32 __iomem *reg = &priv->regs[priv->properties->regoff[rno] + off]; u32 addr = sgpio_get_addr(priv, rno, off);
u32 val = 0;
int ret;
return readl(reg); ret = regmap_read(priv->regs, addr, &val);
WARN_ONCE(ret, "error reading sgpio reg %d\n", ret);
return val;
} }
static inline void sgpio_writel(struct sgpio_priv *priv, static void sgpio_writel(struct sgpio_priv *priv,
u32 val, u32 rno, u32 off) 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, static inline void sgpio_clrsetbits(struct sgpio_priv *priv,
u32 rno, u32 off, u32 clear, u32 set) u32 rno, u32 off, u32 clear, u32 set)
{ {
u32 __iomem *reg = &priv->regs[priv->properties->regoff[rno] + off]; u32 val = sgpio_readl(priv, rno, off);
u32 val = readl(reg);
val &= ~clear; val &= ~clear;
val |= set; val |= set;
writel(val, reg); sgpio_writel(priv, val, rno, off);
} }
static inline void sgpio_configure_bitstream(struct sgpio_priv *priv) static inline void sgpio_configure_bitstream(struct sgpio_priv *priv)
...@@ -807,7 +819,13 @@ static int microchip_sgpio_probe(struct platform_device *pdev) ...@@ -807,7 +819,13 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
struct reset_control *reset; struct reset_control *reset;
struct sgpio_priv *priv; struct sgpio_priv *priv;
struct clk *clk; struct clk *clk;
u32 __iomem *regs;
u32 val; u32 val;
struct regmap_config regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
...@@ -832,9 +850,14 @@ static int microchip_sgpio_probe(struct platform_device *pdev) ...@@ -832,9 +850,14 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
return -EINVAL; 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, &regmap_config);
if (IS_ERR(priv->regs)) if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs); return PTR_ERR(priv->regs);
priv->properties = device_get_match_data(dev); priv->properties = device_get_match_data(dev);
priv->in.is_input = true; priv->in.is_input = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment