aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc/ixp4xx/ixp4xx-npe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc/ixp4xx/ixp4xx-npe.c')
-rw-r--r--drivers/soc/ixp4xx/ixp4xx-npe.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index ec90b44fa0cd..58240e320c13 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -16,10 +16,13 @@
#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>
#include <linux/platform_device.h>
#include <linux/soc/ixp4xx/npe.h>
+#include <linux/soc/ixp4xx/cpu.h>
#define DEBUG_MSG 0
#define DEBUG_FW 0
@@ -282,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;
@@ -378,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);
}
@@ -679,7 +686,16 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
{
int i, found = 0;
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];
@@ -688,29 +704,35 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
if (!res)
return -ENODEV;
- if (!(ixp4xx_read_feature_bits() &
- (IXP4XX_FEATURE_RESET_NPEA << i))) {
- dev_info(dev, "NPE%d at 0x%08x-0x%08x not available\n",
- i, res->start, res->end);
+ 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 */
}
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 0x%08x-0x%08x does not reset\n",
- i, res->start, res->end);
+ dev_info(dev, "NPE%d at %pR does not reset\n",
+ i, res);
continue;
}
npe->valid = 1;
- dev_info(dev, "NPE%d at 0x%08x-0x%08x registered\n",
- i, res->start, res->end);
+ dev_info(dev, "NPE%d at %pR registered\n", i, res);
found++;
}
if (!found)
return -ENODEV;
+
+ /* Spawn crypto subdevice if using device tree */
+ if (IS_ENABLED(CONFIG_OF) && np)
+ devm_of_platform_populate(dev);
+
return 0;
}
@@ -736,7 +758,7 @@ static const struct of_device_id ixp4xx_npe_of_match[] = {
static struct platform_driver ixp4xx_npe_driver = {
.driver = {
.name = "ixp4xx-npe",
- .of_match_table = of_match_ptr(ixp4xx_npe_of_match),
+ .of_match_table = ixp4xx_npe_of_match,
},
.probe = ixp4xx_npe_probe,
.remove = ixp4xx_npe_remove,