diff options
Diffstat (limited to 'drivers/nvmem/qfprom.c')
| -rw-r--r-- | drivers/nvmem/qfprom.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c index c1e893c8a247..a872c640b8c5 100644 --- a/drivers/nvmem/qfprom.c +++ b/drivers/nvmem/qfprom.c @@ -321,19 +321,32 @@ static int qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes) { struct qfprom_priv *priv = context; - u8 *val = _val; - int i = 0, words = bytes; + u32 *val = _val; void __iomem *base = priv->qfpcorrected; + int words = DIV_ROUND_UP(bytes, sizeof(u32)); + int i; if (read_raw_data && priv->qfpraw) base = priv->qfpraw; - while (words--) - *val++ = readb(base + reg + i++); + for (i = 0; i < words; i++) + *val++ = readl(base + reg + i * sizeof(u32)); return 0; } +/* Align reads to word boundary */ +static void qfprom_fixup_dt_cell_info(struct nvmem_device *nvmem, + struct nvmem_cell_info *cell) +{ + unsigned int byte_offset = cell->offset % sizeof(u32); + + cell->bit_offset += byte_offset * BITS_PER_BYTE; + cell->offset -= byte_offset; + if (byte_offset && !cell->nbits) + cell->nbits = cell->bytes * BITS_PER_BYTE; +} + static void qfprom_runtime_disable(void *data) { pm_runtime_disable(data); @@ -357,10 +370,12 @@ static int qfprom_probe(struct platform_device *pdev) { struct nvmem_config econfig = { .name = "qfprom", - .stride = 1, - .word_size = 1, + .add_legacy_fixed_of_cells = true, + .stride = 4, + .word_size = 4, .id = NVMEM_DEVID_AUTO, .reg_read = qfprom_reg_read, + .fixup_dt_cell_info = qfprom_fixup_dt_cell_info, }; struct device *dev = &pdev->dev; struct resource *res; @@ -374,8 +389,7 @@ static int qfprom_probe(struct platform_device *pdev) return -ENOMEM; /* The corrected section is always provided */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->qfpcorrected = devm_ioremap_resource(dev, res); + priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->qfpcorrected)) return PTR_ERR(priv->qfpcorrected); @@ -402,12 +416,10 @@ static int qfprom_probe(struct platform_device *pdev) priv->qfpraw = devm_ioremap_resource(dev, res); if (IS_ERR(priv->qfpraw)) return PTR_ERR(priv->qfpraw); - res = platform_get_resource(pdev, IORESOURCE_MEM, 2); - priv->qfpconf = devm_ioremap_resource(dev, res); + priv->qfpconf = devm_platform_ioremap_resource(pdev, 2); if (IS_ERR(priv->qfpconf)) return PTR_ERR(priv->qfpconf); - res = platform_get_resource(pdev, IORESOURCE_MEM, 3); - priv->qfpsecurity = devm_ioremap_resource(dev, res); + priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3); if (IS_ERR(priv->qfpsecurity)) return PTR_ERR(priv->qfpsecurity); @@ -426,16 +438,12 @@ static int qfprom_probe(struct platform_device *pdev) if (IS_ERR(priv->vcc)) return PTR_ERR(priv->vcc); - priv->secclk = devm_clk_get(dev, "core"); - if (IS_ERR(priv->secclk)) { - ret = PTR_ERR(priv->secclk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Error getting clock: %d\n", ret); - return ret; - } + priv->secclk = devm_clk_get_optional(dev, "core"); + if (IS_ERR(priv->secclk)) + return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); - /* Only enable writing if we have SoC data. */ - if (priv->soc_data) + /* Only enable writing if we have SoC data and a valid clock */ + if (priv->soc_data && priv->secclk) econfig.reg_write = qfprom_reg_write; } |
