Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+27 -9
+1
drivers/soc/ixp4xx/Kconfig
··· 12 12 config IXP4XX_NPE 13 13 tristate "IXP4xx Network Processor Engine support" 14 14 select FW_LOADER 15 + select MFD_SYSCON 15 16 help 16 17 This driver supports IXP4xx built-in network coprocessors 17 18 and is automatically selected by Ethernet and HSS drivers.
+24 -9
drivers/soc/ixp4xx/ixp4xx-npe.c
··· 16 16 #include <linux/firmware.h> 17 17 #include <linux/io.h> 18 18 #include <linux/kernel.h> 19 + #include <linux/mfd/syscon.h> 19 20 #include <linux/module.h> 20 21 #include <linux/of.h> 21 22 #include <linux/of_platform.h> ··· 285 284 286 285 static int npe_reset(struct npe *npe) 287 286 { 287 + u32 reset_bit = (IXP4XX_FEATURE_RESET_NPEA << npe->id); 288 288 u32 val, ctl, exec_count, ctx_reg2; 289 289 int i; 290 290 ··· 382 380 __raw_writel(0, &npe->regs->action_points[3]); 383 381 __raw_writel(0, &npe->regs->watch_count); 384 382 385 - val = ixp4xx_read_feature_bits(); 383 + /* 384 + * We need to work on cached values here because the register 385 + * will read inverted but needs to be written non-inverted. 386 + */ 387 + val = cpu_ixp4xx_features(npe->rmap); 386 388 /* reset the NPE */ 387 - ixp4xx_write_feature_bits(val & 388 - ~(IXP4XX_FEATURE_RESET_NPEA << npe->id)); 389 + regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val & ~reset_bit); 389 390 /* deassert reset */ 390 - ixp4xx_write_feature_bits(val | 391 - (IXP4XX_FEATURE_RESET_NPEA << npe->id)); 391 + regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val | reset_bit); 392 + 392 393 for (i = 0; i < MAX_RETRIES; i++) { 393 - if (ixp4xx_read_feature_bits() & 394 - (IXP4XX_FEATURE_RESET_NPEA << npe->id)) 394 + val = cpu_ixp4xx_features(npe->rmap); 395 + if (val & reset_bit) 395 396 break; /* NPE is back alive */ 396 397 udelay(1); 397 398 } ··· 688 683 struct device *dev = &pdev->dev; 689 684 struct device_node *np = dev->of_node; 690 685 struct resource *res; 686 + struct regmap *rmap; 687 + u32 val; 688 + 689 + /* This system has only one syscon, so fetch it */ 690 + rmap = syscon_regmap_lookup_by_compatible("syscon"); 691 + if (IS_ERR(rmap)) 692 + return dev_err_probe(dev, PTR_ERR(rmap), 693 + "failed to look up syscon\n"); 691 694 692 695 for (i = 0; i < NPE_COUNT; i++) { 693 696 struct npe *npe = &npe_tab[i]; ··· 704 691 if (!res) 705 692 return -ENODEV; 706 693 707 - if (!(ixp4xx_read_feature_bits() & 708 - (IXP4XX_FEATURE_RESET_NPEA << i))) { 694 + val = cpu_ixp4xx_features(rmap); 695 + 696 + if (!(val & (IXP4XX_FEATURE_RESET_NPEA << i))) { 709 697 dev_info(dev, "NPE%d at %pR not available\n", 710 698 i, res); 711 699 continue; /* NPE already disabled or not present */ ··· 714 700 npe->regs = devm_ioremap_resource(dev, res); 715 701 if (IS_ERR(npe->regs)) 716 702 return PTR_ERR(npe->regs); 703 + npe->rmap = rmap; 717 704 718 705 if (npe_reset(npe)) { 719 706 dev_info(dev, "NPE%d at %pR does not reset\n",
+2
include/linux/soc/ixp4xx/npe.h
··· 3 3 #define __IXP4XX_NPE_H 4 4 5 5 #include <linux/kernel.h> 6 + #include <linux/regmap.h> 6 7 7 8 extern const char *npe_names[]; 8 9 ··· 18 17 19 18 struct npe { 20 19 struct npe_regs __iomem *regs; 20 + struct regmap *rmap; 21 21 int id; 22 22 int valid; 23 23 };