in k3_bandgap.c [158:233]
static int k3_bandgap_probe(struct platform_device *pdev)
{
int ret = 0, cnt, val, id;
struct resource *res;
struct device *dev = &pdev->dev;
struct k3_bandgap *bgp;
struct k3_thermal_data *data;
if (ARRAY_SIZE(k3_adc_to_temp) != (K3_VTM_ADC_END_VAL + 1 -
K3_VTM_ADC_BEGIN_VAL))
return -EINVAL;
bgp = devm_kzalloc(&pdev->dev, sizeof(*bgp), GFP_KERNEL);
if (!bgp)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bgp->base = devm_ioremap_resource(dev, res);
if (IS_ERR(bgp->base))
return PTR_ERR(bgp->base);
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
pm_runtime_disable(dev);
return ret;
}
/* Get the sensor count in the VTM */
val = readl(bgp->base + K3_VTM_DEVINFO_PWR0_OFFSET);
cnt = val & K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK;
cnt >>= __ffs(K3_VTM_DEVINFO_PWR0_TEMPSENS_CT_MASK);
data = devm_kcalloc(dev, cnt, sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto err_alloc;
}
/* Register the thermal sensors */
for (id = 0; id < cnt; id++) {
data[id].sensor_id = id;
data[id].bgp = bgp;
data[id].ctrl_offset = K3_VTM_TMPSENS0_CTRL_OFFSET +
id * K3_VTM_REGS_PER_TS;
data[id].stat_offset = data[id].ctrl_offset + 0x8;
val = readl(data[id].bgp->base + data[id].ctrl_offset);
val |= (K3_VTM_TMPSENS_CTRL_SOC |
K3_VTM_TMPSENS_CTRL_CLRZ |
K3_VTM_TMPSENS_CTRL_CLKON_REQ);
val &= ~K3_VTM_TMPSENS_CTRL_CBIASSEL;
writel(val, data[id].bgp->base + data[id].ctrl_offset);
data[id].tzd =
devm_thermal_zone_of_sensor_register(dev, id,
&data[id],
&k3_of_thermal_ops);
if (IS_ERR(data[id].tzd)) {
dev_err(dev, "thermal zone device is NULL\n");
ret = PTR_ERR(data[id].tzd);
goto err_alloc;
}
}
platform_set_drvdata(pdev, bgp);
return 0;
err_alloc:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
return ret;
}