in ti-opp-supply.c [73:167]
static int _store_optimized_voltages(struct device *dev,
struct ti_opp_supply_data *data)
{
void __iomem *base;
struct property *prop;
struct resource *res;
const __be32 *val;
int proplen, i;
int ret = 0;
struct ti_opp_supply_optimum_voltage_table *table;
const struct ti_opp_supply_of_data *of_data = dev_get_drvdata(dev);
/* pick up Efuse based voltages */
res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "Unable to get IO resource\n");
ret = -ENODEV;
goto out_map;
}
base = ioremap(res->start, resource_size(res));
if (!base) {
dev_err(dev, "Unable to map Efuse registers\n");
ret = -ENOMEM;
goto out_map;
}
/* Fetch efuse-settings. */
prop = of_find_property(dev->of_node, "ti,efuse-settings", NULL);
if (!prop) {
dev_err(dev, "No 'ti,efuse-settings' property found\n");
ret = -EINVAL;
goto out;
}
proplen = prop->length / sizeof(int);
data->num_vdd_table = proplen / 2;
/* Verify for corrupted OPP entries in dt */
if (data->num_vdd_table * 2 * sizeof(int) != prop->length) {
dev_err(dev, "Invalid 'ti,efuse-settings'\n");
ret = -EINVAL;
goto out;
}
ret = of_property_read_u32(dev->of_node, "ti,absolute-max-voltage-uv",
&data->vdd_absolute_max_voltage_uv);
if (ret) {
dev_err(dev, "ti,absolute-max-voltage-uv is missing\n");
ret = -EINVAL;
goto out;
}
table = kcalloc(data->num_vdd_table, sizeof(*data->vdd_table),
GFP_KERNEL);
if (!table) {
ret = -ENOMEM;
goto out;
}
data->vdd_table = table;
val = prop->value;
for (i = 0; i < data->num_vdd_table; i++, table++) {
u32 efuse_offset;
u32 tmp;
table->reference_uv = be32_to_cpup(val++);
efuse_offset = be32_to_cpup(val++);
tmp = readl(base + efuse_offset);
tmp &= of_data->efuse_voltage_mask;
tmp >>= __ffs(of_data->efuse_voltage_mask);
table->optimized_uv = of_data->efuse_voltage_uv ? tmp :
tmp * 1000;
dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d vset=%d\n",
i, efuse_offset, table->reference_uv,
table->optimized_uv);
/*
* Some older samples might not have optimized efuse
* Use reference voltage for those - just add debug message
* for them.
*/
if (!table->optimized_uv) {
dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d:vset0\n",
i, efuse_offset, table->reference_uv);
table->optimized_uv = table->reference_uv;
}
}
out:
iounmap(base);
out_map:
return ret;
}