Commit 8754a7e6 authored by Linus Walleij's avatar Linus Walleij

soc: ixp4xx-npe: Access syscon regs using regmap

If we access the syscon (expansion bus config registers) using the
syscon regmap instead of relying on direct accessor functions,
we do not need to call this static code in the machine
(arch/arm/mach-ixp4xx/common.c) which makes things less dependent
on custom machine-dependent code.

Look up the syscon regmap and handle the error: this will make
deferred probe work with relation to the syscon.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20220211223238.648934-8-linus.walleij@linaro.orgSigned-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent b50113cb
...@@ -12,6 +12,7 @@ config IXP4XX_QMGR ...@@ -12,6 +12,7 @@ config IXP4XX_QMGR
config IXP4XX_NPE config IXP4XX_NPE
tristate "IXP4xx Network Processor Engine support" tristate "IXP4xx Network Processor Engine support"
select FW_LOADER select FW_LOADER
select MFD_SYSCON
help help
This driver supports IXP4xx built-in network coprocessors This driver supports IXP4xx built-in network coprocessors
and is automatically selected by Ethernet and HSS drivers. and is automatically selected by Ethernet and HSS drivers.
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
...@@ -284,6 +285,7 @@ static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr, ...@@ -284,6 +285,7 @@ static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
static int npe_reset(struct npe *npe) static int npe_reset(struct npe *npe)
{ {
u32 reset_bit = (IXP4XX_FEATURE_RESET_NPEA << npe->id);
u32 val, ctl, exec_count, ctx_reg2; u32 val, ctl, exec_count, ctx_reg2;
int i; int i;
...@@ -380,16 +382,19 @@ static int npe_reset(struct npe *npe) ...@@ -380,16 +382,19 @@ static int npe_reset(struct npe *npe)
__raw_writel(0, &npe->regs->action_points[3]); __raw_writel(0, &npe->regs->action_points[3]);
__raw_writel(0, &npe->regs->watch_count); __raw_writel(0, &npe->regs->watch_count);
val = ixp4xx_read_feature_bits(); /*
* We need to work on cached values here because the register
* will read inverted but needs to be written non-inverted.
*/
val = cpu_ixp4xx_features(npe->rmap);
/* reset the NPE */ /* reset the NPE */
ixp4xx_write_feature_bits(val & regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val & ~reset_bit);
~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
/* deassert reset */ /* deassert reset */
ixp4xx_write_feature_bits(val | regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val | reset_bit);
(IXP4XX_FEATURE_RESET_NPEA << npe->id));
for (i = 0; i < MAX_RETRIES; i++) { for (i = 0; i < MAX_RETRIES; i++) {
if (ixp4xx_read_feature_bits() & val = cpu_ixp4xx_features(npe->rmap);
(IXP4XX_FEATURE_RESET_NPEA << npe->id)) if (val & reset_bit)
break; /* NPE is back alive */ break; /* NPE is back alive */
udelay(1); udelay(1);
} }
...@@ -683,6 +688,14 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) ...@@ -683,6 +688,14 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct resource *res; struct resource *res;
struct regmap *rmap;
u32 val;
/* This system has only one syscon, so fetch it */
rmap = syscon_regmap_lookup_by_compatible("syscon");
if (IS_ERR(rmap))
return dev_err_probe(dev, PTR_ERR(rmap),
"failed to look up syscon\n");
for (i = 0; i < NPE_COUNT; i++) { for (i = 0; i < NPE_COUNT; i++) {
struct npe *npe = &npe_tab[i]; struct npe *npe = &npe_tab[i];
...@@ -691,8 +704,9 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) ...@@ -691,8 +704,9 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
if (!res) if (!res)
return -ENODEV; return -ENODEV;
if (!(ixp4xx_read_feature_bits() & val = cpu_ixp4xx_features(rmap);
(IXP4XX_FEATURE_RESET_NPEA << i))) {
if (!(val & (IXP4XX_FEATURE_RESET_NPEA << i))) {
dev_info(dev, "NPE%d at %pR not available\n", dev_info(dev, "NPE%d at %pR not available\n",
i, res); i, res);
continue; /* NPE already disabled or not present */ continue; /* NPE already disabled or not present */
...@@ -700,6 +714,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) ...@@ -700,6 +714,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
npe->regs = devm_ioremap_resource(dev, res); npe->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(npe->regs)) if (IS_ERR(npe->regs))
return PTR_ERR(npe->regs); return PTR_ERR(npe->regs);
npe->rmap = rmap;
if (npe_reset(npe)) { if (npe_reset(npe)) {
dev_info(dev, "NPE%d at %pR does not reset\n", dev_info(dev, "NPE%d at %pR does not reset\n",
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#define __IXP4XX_NPE_H #define __IXP4XX_NPE_H
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/regmap.h>
extern const char *npe_names[]; extern const char *npe_names[];
...@@ -17,6 +18,7 @@ struct npe_regs { ...@@ -17,6 +18,7 @@ struct npe_regs {
struct npe { struct npe {
struct npe_regs __iomem *regs; struct npe_regs __iomem *regs;
struct regmap *rmap;
int id; int id;
int valid; int valid;
}; };
......
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