static int k3_bandgap_probe()

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;
}