in qfprom.c [357:451]
static int qfprom_probe(struct platform_device *pdev)
{
struct nvmem_config econfig = {
.name = "qfprom",
.stride = 1,
.word_size = 1,
.id = NVMEM_DEVID_AUTO,
.reg_read = qfprom_reg_read,
};
struct device *dev = &pdev->dev;
struct resource *res;
struct nvmem_device *nvmem;
const struct qfprom_soc_compatible_data *soc_data;
struct qfprom_priv *priv;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* The corrected section is always provided */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->qfpcorrected = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->qfpcorrected))
return PTR_ERR(priv->qfpcorrected);
econfig.size = resource_size(res);
econfig.dev = dev;
econfig.priv = priv;
priv->dev = dev;
soc_data = device_get_match_data(dev);
if (soc_data) {
econfig.keepout = soc_data->keepout;
econfig.nkeepout = soc_data->nkeepout;
}
/*
* If more than one region is provided then the OS has the ability
* to write.
*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res) {
u32 version;
int major_version, minor_version;
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);
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);
if (IS_ERR(priv->qfpsecurity))
return PTR_ERR(priv->qfpsecurity);
version = readl(priv->qfpsecurity + QFPROM_VERSION_OFFSET);
major_version = (version & QFPROM_MAJOR_VERSION_MASK) >>
QFPROM_MAJOR_VERSION_SHIFT;
minor_version = (version & QFPROM_MINOR_VERSION_MASK) >>
QFPROM_MINOR_VERSION_SHIFT;
if (major_version == 7 && minor_version == 8)
priv->soc_data = &qfprom_7_8_data;
else if (major_version == 7 && minor_version == 15)
priv->soc_data = &qfprom_7_15_data;
priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
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;
}
/* Only enable writing if we have SoC data. */
if (priv->soc_data)
econfig.reg_write = qfprom_reg_write;
}
pm_runtime_enable(dev);
ret = devm_add_action_or_reset(dev, qfprom_runtime_disable, dev);
if (ret)
return ret;
nvmem = devm_nvmem_register(dev, &econfig);
return PTR_ERR_OR_ZERO(nvmem);
}