diff options
Diffstat (limited to 'drivers/nvmem')
-rw-r--r-- | drivers/nvmem/Kconfig | 4 | ||||
-rw-r--r-- | drivers/nvmem/imx-ocotp.c | 17 | ||||
-rw-r--r-- | drivers/nvmem/mtk-efuse.c | 47 | ||||
-rw-r--r-- | drivers/nvmem/mxs-ocotp.c | 83 |
4 files changed, 71 insertions, 80 deletions
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 3041d48e7155..f550c4596a7a 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -15,7 +15,8 @@ if NVMEM config NVMEM_IMX_OCOTP tristate "i.MX6 On-Chip OTP Controller support" - depends on SOC_IMX6 + depends on SOC_IMX6 || COMPILE_TEST + depends on HAS_IOMEM help This is a driver for the On-Chip OTP Controller (OCOTP) available on i.MX6 SoCs, providing access to 4 Kbits of one-time programmable @@ -50,7 +51,6 @@ config MTK_EFUSE tristate "Mediatek SoCs EFUSE support" depends on ARCH_MEDIATEK || COMPILE_TEST depends on HAS_IOMEM - select REGMAP_MMIO help This is a driver to access hardware related data like sensor calibration, HDMI impedance etc. diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c index 75e66ef5b0ec..ac27b9bac3b9 100644 --- a/drivers/nvmem/imx-ocotp.c +++ b/drivers/nvmem/imx-ocotp.c @@ -15,6 +15,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <linux/clk.h> #include <linux/device.h> #include <linux/io.h> #include <linux/module.h> @@ -26,6 +27,7 @@ struct ocotp_priv { struct device *dev; + struct clk *clk; void __iomem *base; unsigned int nregs; }; @@ -36,7 +38,7 @@ static int imx_ocotp_read(void *context, unsigned int offset, struct ocotp_priv *priv = context; unsigned int count; u32 *buf = val; - int i; + int i, ret; u32 index; index = offset >> 2; @@ -45,9 +47,16 @@ static int imx_ocotp_read(void *context, unsigned int offset, if (count > (priv->nregs - index)) count = priv->nregs - index; + ret = clk_prepare_enable(priv->clk); + if (ret < 0) { + dev_err(priv->dev, "failed to prepare/enable ocotp clk\n"); + return ret; + } for (i = index; i < (index + count); i++) *buf++ = readl(priv->base + 0x400 + i * 0x10); + clk_disable_unprepare(priv->clk); + return 0; } @@ -85,8 +94,12 @@ static int imx_ocotp_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + priv->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + of_id = of_match_device(imx_ocotp_dt_ids, dev); - priv->nregs = (unsigned int)of_id->data; + priv->nregs = (unsigned long)of_id->data; imx_ocotp_nvmem_config.size = 4 * priv->nregs; imx_ocotp_nvmem_config.dev = dev; imx_ocotp_nvmem_config.priv = priv; diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c index 9c49369beea5..32fd572e18c5 100644 --- a/drivers/nvmem/mtk-efuse.c +++ b/drivers/nvmem/mtk-efuse.c @@ -14,15 +14,35 @@ #include <linux/device.h> #include <linux/module.h> +#include <linux/io.h> #include <linux/nvmem-provider.h> #include <linux/platform_device.h> -#include <linux/regmap.h> -static struct regmap_config mtk_regmap_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, -}; +static int mtk_reg_read(void *context, + unsigned int reg, void *_val, size_t bytes) +{ + void __iomem *base = context; + u32 *val = _val; + int i = 0, words = bytes / 4; + + while (words--) + *val++ = readl(base + reg + (i++ * 4)); + + return 0; +} + +static int mtk_reg_write(void *context, + unsigned int reg, void *_val, size_t bytes) +{ + void __iomem *base = context; + u32 *val = _val; + int i = 0, words = bytes / 4; + + while (words--) + writel(*val++, base + reg + (i++ * 4)); + + return 0; +} static int mtk_efuse_probe(struct platform_device *pdev) { @@ -30,7 +50,6 @@ static int mtk_efuse_probe(struct platform_device *pdev) struct resource *res; struct nvmem_device *nvmem; struct nvmem_config *econfig; - struct regmap *regmap; void __iomem *base; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -42,14 +61,12 @@ static int mtk_efuse_probe(struct platform_device *pdev) if (!econfig) return -ENOMEM; - mtk_regmap_config.max_register = resource_size(res) - 1; - - regmap = devm_regmap_init_mmio(dev, base, &mtk_regmap_config); - if (IS_ERR(regmap)) { - dev_err(dev, "regmap init failed\n"); - return PTR_ERR(regmap); - } - + econfig->stride = 4; + econfig->word_size = 4; + econfig->reg_read = mtk_reg_read; + econfig->reg_write = mtk_reg_write; + econfig->size = resource_size(res); + econfig->priv = base; econfig->dev = dev; econfig->owner = THIS_MODULE; nvmem = nvmem_register(econfig); diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c index 2bb3c5799ac4..d26dd03cec80 100644 --- a/drivers/nvmem/mxs-ocotp.c +++ b/drivers/nvmem/mxs-ocotp.c @@ -25,7 +25,6 @@ #include <linux/nvmem-provider.h> #include <linux/of_device.h> #include <linux/platform_device.h> -#include <linux/regmap.h> #include <linux/slab.h> #include <linux/stmp_device.h> @@ -66,11 +65,10 @@ static int mxs_ocotp_wait(struct mxs_ocotp *otp) return 0; } -static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size, - void *val, size_t val_size) +static int mxs_ocotp_read(void *context, unsigned int offset, + void *val, size_t bytes) { struct mxs_ocotp *otp = context; - unsigned int offset = *(u32 *)reg; u32 *buf = val; int ret; @@ -94,17 +92,16 @@ static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size, if (ret) goto close_banks; - while (val_size >= reg_size) { + while (bytes) { if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) { /* fill up non-data register */ - *buf = 0; + *buf++ = 0; } else { - *buf = readl(otp->base + offset); + *buf++ = readl(otp->base + offset); } - buf++; - val_size -= reg_size; - offset += reg_size; + bytes -= 4; + offset += 4; } close_banks: @@ -117,57 +114,29 @@ disable_clk: return ret; } -static int mxs_ocotp_write(void *context, const void *data, size_t count) -{ - /* We don't want to support writing */ - return 0; -} - -static bool mxs_ocotp_writeable_reg(struct device *dev, unsigned int reg) -{ - return false; -} - static struct nvmem_config ocotp_config = { .name = "mxs-ocotp", + .stride = 16, + .word_size = 4, .owner = THIS_MODULE, + .reg_read = mxs_ocotp_read, }; -static const struct regmap_range imx23_ranges[] = { - regmap_reg_range(OCOTP_DATA_OFFSET, 0x210), -}; - -static const struct regmap_access_table imx23_access = { - .yes_ranges = imx23_ranges, - .n_yes_ranges = ARRAY_SIZE(imx23_ranges), -}; - -static const struct regmap_range imx28_ranges[] = { - regmap_reg_range(OCOTP_DATA_OFFSET, 0x290), -}; - -static const struct regmap_access_table imx28_access = { - .yes_ranges = imx28_ranges, - .n_yes_ranges = ARRAY_SIZE(imx28_ranges), +struct mxs_data { + int size; }; -static struct regmap_bus mxs_ocotp_bus = { - .read = mxs_ocotp_read, - .write = mxs_ocotp_write, /* make regmap_init() happy */ - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, - .val_format_endian_default = REGMAP_ENDIAN_NATIVE, +static const struct mxs_data imx23_data = { + .size = 0x220, }; -static struct regmap_config mxs_ocotp_config = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 16, - .writeable_reg = mxs_ocotp_writeable_reg, +static const struct mxs_data imx28_data = { + .size = 0x2a0, }; static const struct of_device_id mxs_ocotp_match[] = { - { .compatible = "fsl,imx23-ocotp", .data = &imx23_access }, - { .compatible = "fsl,imx28-ocotp", .data = &imx28_access }, + { .compatible = "fsl,imx23-ocotp", .data = &imx23_data }, + { .compatible = "fsl,imx28-ocotp", .data = &imx28_data }, { /* sentinel */}, }; MODULE_DEVICE_TABLE(of, mxs_ocotp_match); @@ -175,11 +144,10 @@ MODULE_DEVICE_TABLE(of, mxs_ocotp_match); static int mxs_ocotp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const struct mxs_data *data; struct mxs_ocotp *otp; struct resource *res; const struct of_device_id *match; - struct regmap *regmap; - const struct regmap_access_table *access; int ret; match = of_match_device(dev->driver->of_match_table, dev); @@ -205,17 +173,10 @@ static int mxs_ocotp_probe(struct platform_device *pdev) return ret; } - access = match->data; - mxs_ocotp_config.rd_table = access; - mxs_ocotp_config.max_register = access->yes_ranges[0].range_max; - - regmap = devm_regmap_init(dev, &mxs_ocotp_bus, otp, &mxs_ocotp_config); - if (IS_ERR(regmap)) { - dev_err(dev, "regmap init failed\n"); - ret = PTR_ERR(regmap); - goto err_clk; - } + data = match->data; + ocotp_config.size = data->size; + ocotp_config.priv = otp; ocotp_config.dev = dev; otp->nvmem = nvmem_register(&ocotp_config); if (IS_ERR(otp->nvmem)) { |