X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fnvmem%2Frockchip-efuse.c;h=4d3f391f0a0bb21f09a514cfa07d9c517a89b6f5;hb=9042cdf4e1105ad5742db4e2dcf5355435476d5b;hp=f552134242223959301a419a78fc08b0c65ec207;hpb=f28a1b0df7adcc981e5ce5a5daf3d638dd019c0e;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index f55213424222..4d3f391f0a0b 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -14,16 +14,15 @@ * more details. */ -#include -#include -#include -#include +#include +#include #include #include #include -#include +#include +#include #include -#include +#include #define EFUSE_A_SHIFT 6 #define EFUSE_A_MASK 0x3ff @@ -35,127 +34,91 @@ #define REG_EFUSE_CTRL 0x0000 #define REG_EFUSE_DOUT 0x0004 -struct rockchip_efuse_context { +struct rockchip_efuse_chip { struct device *dev; void __iomem *base; - struct clk *efuse_clk; + struct clk *clk; }; -static int rockchip_efuse_write(void *context, const void *data, size_t count) -{ - /* Nothing TBD, Read-Only */ - return 0; -} - -static int rockchip_efuse_read(void *context, - const void *reg, size_t reg_size, - void *val, size_t val_size) +static int rockchip_efuse_read(void *context, unsigned int offset, + void *val, size_t bytes) { - unsigned int offset = *(u32 *)reg; - struct rockchip_efuse_context *_context = context; - void __iomem *base = _context->base; - struct clk *clk = _context->efuse_clk; + struct rockchip_efuse_chip *efuse = context; u8 *buf = val; int ret; - ret = clk_prepare_enable(clk); + ret = clk_prepare_enable(efuse->clk); if (ret < 0) { - dev_err(_context->dev, "failed to prepare/enable efuse clk\n"); + dev_err(efuse->dev, "failed to prepare/enable efuse clk\n"); return ret; } - writel(EFUSE_LOAD | EFUSE_PGENB, base + REG_EFUSE_CTRL); + writel(EFUSE_LOAD | EFUSE_PGENB, efuse->base + REG_EFUSE_CTRL); udelay(1); - while (val_size) { - writel(readl(base + REG_EFUSE_CTRL) & + while (bytes--) { + writel(readl(efuse->base + REG_EFUSE_CTRL) & (~(EFUSE_A_MASK << EFUSE_A_SHIFT)), - base + REG_EFUSE_CTRL); - writel(readl(base + REG_EFUSE_CTRL) | - ((offset & EFUSE_A_MASK) << EFUSE_A_SHIFT), - base + REG_EFUSE_CTRL); + efuse->base + REG_EFUSE_CTRL); + writel(readl(efuse->base + REG_EFUSE_CTRL) | + ((offset++ & EFUSE_A_MASK) << EFUSE_A_SHIFT), + efuse->base + REG_EFUSE_CTRL); udelay(1); - writel(readl(base + REG_EFUSE_CTRL) | - EFUSE_STROBE, base + REG_EFUSE_CTRL); + writel(readl(efuse->base + REG_EFUSE_CTRL) | + EFUSE_STROBE, efuse->base + REG_EFUSE_CTRL); udelay(1); - *buf++ = readb(base + REG_EFUSE_DOUT); - writel(readl(base + REG_EFUSE_CTRL) & - (~EFUSE_STROBE), base + REG_EFUSE_CTRL); + *buf++ = readb(efuse->base + REG_EFUSE_DOUT); + writel(readl(efuse->base + REG_EFUSE_CTRL) & + (~EFUSE_STROBE), efuse->base + REG_EFUSE_CTRL); udelay(1); - - val_size -= 1; - offset += 1; } /* Switch to standby mode */ - writel(EFUSE_PGENB | EFUSE_CSB, base + REG_EFUSE_CTRL); + writel(EFUSE_PGENB | EFUSE_CSB, efuse->base + REG_EFUSE_CTRL); - clk_disable_unprepare(clk); + clk_disable_unprepare(efuse->clk); return 0; } -static struct regmap_bus rockchip_efuse_bus = { - .read = rockchip_efuse_read, - .write = rockchip_efuse_write, - .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, - .val_format_endian_default = REGMAP_ENDIAN_NATIVE, -}; - -static struct regmap_config rockchip_efuse_regmap_config = { - .reg_bits = 32, - .reg_stride = 1, - .val_bits = 8, -}; - static struct nvmem_config econfig = { .name = "rockchip-efuse", .owner = THIS_MODULE, + .stride = 1, + .word_size = 1, .read_only = true, }; static const struct of_device_id rockchip_efuse_match[] = { - { .compatible = "rockchip,rockchip-efuse",}, + { .compatible = "rockchip,rockchip-efuse", }, { /* sentinel */}, }; MODULE_DEVICE_TABLE(of, rockchip_efuse_match); static int rockchip_efuse_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; struct resource *res; struct nvmem_device *nvmem; - struct regmap *regmap; - void __iomem *base; - struct clk *clk; - struct rockchip_efuse_context *context; + struct rockchip_efuse_chip *efuse; + + efuse = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_efuse_chip), + GFP_KERNEL); + if (!efuse) + return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - context = devm_kzalloc(dev, sizeof(struct rockchip_efuse_context), - GFP_KERNEL); - if (IS_ERR(context)) - return PTR_ERR(context); - - clk = devm_clk_get(dev, "pclk_efuse"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - context->dev = dev; - context->base = base; - context->efuse_clk = clk; - - rockchip_efuse_regmap_config.max_register = resource_size(res) - 1; - - regmap = devm_regmap_init(dev, &rockchip_efuse_bus, - context, &rockchip_efuse_regmap_config); - if (IS_ERR(regmap)) { - dev_err(dev, "regmap init failed\n"); - return PTR_ERR(regmap); - } - econfig.dev = dev; + efuse->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(efuse->base)) + return PTR_ERR(efuse->base); + + efuse->clk = devm_clk_get(&pdev->dev, "pclk_efuse"); + if (IS_ERR(efuse->clk)) + return PTR_ERR(efuse->clk); + + efuse->dev = &pdev->dev; + econfig.size = resource_size(res); + econfig.reg_read = rockchip_efuse_read; + econfig.priv = efuse; + econfig.dev = efuse->dev; nvmem = nvmem_register(&econfig); if (IS_ERR(nvmem)) return PTR_ERR(nvmem);