diff options
Diffstat (limited to 'drivers/nvmem/layerscape-sfp.c')
-rw-r--r-- | drivers/nvmem/layerscape-sfp.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/nvmem/layerscape-sfp.c b/drivers/nvmem/layerscape-sfp.c index e591c1511e33..e2b424561949 100644 --- a/drivers/nvmem/layerscape-sfp.c +++ b/drivers/nvmem/layerscape-sfp.c @@ -13,15 +13,17 @@ #include <linux/nvmem-provider.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/regmap.h> #define LAYERSCAPE_SFP_OTP_OFFSET 0x0200 struct layerscape_sfp_priv { - void __iomem *base; + struct regmap *regmap; }; struct layerscape_sfp_data { int size; + enum regmap_endian endian; }; static int layerscape_sfp_read(void *context, unsigned int offset, void *val, @@ -29,15 +31,16 @@ static int layerscape_sfp_read(void *context, unsigned int offset, void *val, { struct layerscape_sfp_priv *priv = context; - memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, - bytes); - - return 0; + return regmap_bulk_read(priv->regmap, + LAYERSCAPE_SFP_OTP_OFFSET + offset, val, + bytes / 4); } static struct nvmem_config layerscape_sfp_nvmem_config = { .name = "fsl-sfp", .reg_read = layerscape_sfp_read, + .word_size = 4, + .stride = 4, }; static int layerscape_sfp_probe(struct platform_device *pdev) @@ -45,16 +48,26 @@ static int layerscape_sfp_probe(struct platform_device *pdev) const struct layerscape_sfp_data *data; struct layerscape_sfp_priv *priv; struct nvmem_device *nvmem; + struct regmap_config config = { 0 }; + void __iomem *base; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); data = device_get_match_data(&pdev->dev); + config.reg_bits = 32; + config.reg_stride = 4; + config.val_bits = 32; + config.val_format_endian = data->endian; + config.max_register = LAYERSCAPE_SFP_OTP_OFFSET + data->size - 4; + priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, &config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); layerscape_sfp_nvmem_config.size = data->size; layerscape_sfp_nvmem_config.dev = &pdev->dev; @@ -65,11 +78,18 @@ static int layerscape_sfp_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(nvmem); } +static const struct layerscape_sfp_data ls1021a_data = { + .size = 0x88, + .endian = REGMAP_ENDIAN_BIG, +}; + static const struct layerscape_sfp_data ls1028a_data = { .size = 0x88, + .endian = REGMAP_ENDIAN_LITTLE, }; static const struct of_device_id layerscape_sfp_dt_ids[] = { + { .compatible = "fsl,ls1021a-sfp", .data = &ls1021a_data }, { .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, {}, }; |