in jz4780-efuse.c [139:216]
static int jz4780_efuse_probe(struct platform_device *pdev)
{
struct nvmem_device *nvmem;
struct jz4780_efuse *efuse;
struct nvmem_config cfg;
unsigned long clk_rate;
unsigned long rd_adj;
unsigned long rd_strobe;
struct device *dev = &pdev->dev;
void __iomem *regs;
int ret;
efuse = devm_kzalloc(dev, sizeof(*efuse), GFP_KERNEL);
if (!efuse)
return -ENOMEM;
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
efuse->map = devm_regmap_init_mmio(dev, regs,
&jz4780_efuse_regmap_config);
if (IS_ERR(efuse->map))
return PTR_ERR(efuse->map);
efuse->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(efuse->clk))
return PTR_ERR(efuse->clk);
ret = clk_prepare_enable(efuse->clk);
if (ret < 0)
return ret;
ret = devm_add_action_or_reset(&pdev->dev,
clk_disable_unprepare_helper,
efuse->clk);
if (ret < 0)
return ret;
clk_rate = clk_get_rate(efuse->clk);
efuse->dev = dev;
/*
* rd_adj and rd_strobe are 4 bit values
* conditions:
* bus clk_period * (rd_adj + 1) > 6.5ns
* bus clk_period * (rd_adj + 5 + rd_strobe) > 35ns
* i.e. rd_adj >= 6.5ns / clk_period
* i.e. rd_strobe >= 35 ns / clk_period - 5 - rd_adj + 1
* constants:
* 1 / 6.5ns == 153846154 Hz
* 1 / 35ns == 28571429 Hz
*/
rd_adj = clk_rate / 153846154;
rd_strobe = clk_rate / 28571429 - 5 - rd_adj + 1;
if (rd_adj > EFUCFG_RD_ADJ_MASK ||
rd_strobe > EFUCFG_RD_STR_MASK) {
dev_err(&pdev->dev, "Cannot set clock configuration\n");
return -EINVAL;
}
regmap_update_bits(efuse->map, JZ_EFUCFG,
(EFUCFG_RD_ADJ_MASK << EFUCFG_RD_ADJ_SHIFT) |
(EFUCFG_RD_STR_MASK << EFUCFG_RD_STR_SHIFT),
(rd_adj << EFUCFG_RD_ADJ_SHIFT) |
(rd_strobe << EFUCFG_RD_STR_SHIFT));
cfg = jz4780_efuse_nvmem_config;
cfg.dev = &pdev->dev;
cfg.priv = efuse;
nvmem = devm_nvmem_register(dev, &cfg);
return PTR_ERR_OR_ZERO(nvmem);
}