summaryrefslogtreecommitdiffstats
path: root/drivers/soc/ixp4xx
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2022-02-11 23:32:32 +0100
committerLinus Walleij <linus.walleij@linaro.org>2022-02-12 18:20:03 +0100
commit8754a7e61c766fbc533c627b56ff181550dca00e (patch)
tree31bc3db80947e0531c7beb7bb9227e2910ca3e9b /drivers/soc/ixp4xx
parentb50113cbdd1340c31e85e4cfc5f5e81ce9cbb2aa (diff)
downloadlinux-8754a7e61c766fbc533c627b56ff181550dca00e.tar.bz2
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: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20220211223238.648934-8-linus.walleij@linaro.org Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/soc/ixp4xx')
-rw-r--r--drivers/soc/ixp4xx/Kconfig1
-rw-r--r--drivers/soc/ixp4xx/ixp4xx-npe.c33
2 files changed, 25 insertions, 9 deletions
diff --git a/drivers/soc/ixp4xx/Kconfig b/drivers/soc/ixp4xx/Kconfig
index e3eb19b85fa4..c55f0c9ae513 100644
--- a/drivers/soc/ixp4xx/Kconfig
+++ b/drivers/soc/ixp4xx/Kconfig
@@ -12,6 +12,7 @@ config IXP4XX_QMGR
config IXP4XX_NPE
tristate "IXP4xx Network Processor Engine support"
select FW_LOADER
+ select MFD_SYSCON
help
This driver supports IXP4xx built-in network coprocessors
and is automatically selected by Ethernet and HSS drivers.
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index f490c4ca51f5..613935cb6a48 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -16,6 +16,7 @@
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
@@ -284,6 +285,7 @@ static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
static int npe_reset(struct npe *npe)
{
+ u32 reset_bit = (IXP4XX_FEATURE_RESET_NPEA << npe->id);
u32 val, ctl, exec_count, ctx_reg2;
int i;
@@ -380,16 +382,19 @@ static int npe_reset(struct npe *npe)
__raw_writel(0, &npe->regs->action_points[3]);
__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 */
- ixp4xx_write_feature_bits(val &
- ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
+ regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val & ~reset_bit);
/* deassert reset */
- ixp4xx_write_feature_bits(val |
- (IXP4XX_FEATURE_RESET_NPEA << npe->id));
+ regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val | reset_bit);
+
for (i = 0; i < MAX_RETRIES; i++) {
- if (ixp4xx_read_feature_bits() &
- (IXP4XX_FEATURE_RESET_NPEA << npe->id))
+ val = cpu_ixp4xx_features(npe->rmap);
+ if (val & reset_bit)
break; /* NPE is back alive */
udelay(1);
}
@@ -683,6 +688,14 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
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++) {
struct npe *npe = &npe_tab[i];
@@ -691,8 +704,9 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
if (!res)
return -ENODEV;
- if (!(ixp4xx_read_feature_bits() &
- (IXP4XX_FEATURE_RESET_NPEA << i))) {
+ val = cpu_ixp4xx_features(rmap);
+
+ if (!(val & (IXP4XX_FEATURE_RESET_NPEA << i))) {
dev_info(dev, "NPE%d at %pR not available\n",
i, res);
continue; /* NPE already disabled or not present */
@@ -700,6 +714,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
npe->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(npe->regs))
return PTR_ERR(npe->regs);
+ npe->rmap = rmap;
if (npe_reset(npe)) {
dev_info(dev, "NPE%d at %pR does not reset\n",