static struct tps51632_regulator_platform_data * of_get_tps51632_platform_data(struct device *dev) { struct tps51632_regulator_platform_data *pdata; struct device_node *np = dev->of_node; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(dev, "Memory alloc failed for platform data\n"); return NULL; } pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); if (!pdata->reg_init_data) { dev_err(dev, "Not able to get OF regulator init data\n"); return NULL; } pdata->enable_pwm_dvfs = of_property_read_bool(np, "ti,enable-pwm-dvfs"); pdata->dvfs_step_20mV = of_property_read_bool(np, "ti,dvfs-step-20mV"); pdata->base_voltage_uV = pdata->reg_init_data->constraints.min_uV ? : TPS51632_MIN_VOLATGE; pdata->max_voltage_uV = pdata->reg_init_data->constraints.max_uV ? : TPS51632_MAX_VOLATGE; return pdata; }
static int arizona_micsupp_of_get_pdata(struct arizona *arizona, struct regulator_config *config) { struct arizona_pdata *pdata = &arizona->pdata; struct arizona_micsupp *micsupp = config->driver_data; struct device_node *np; struct regulator_init_data *init_data; np = of_get_child_by_name(arizona->dev->of_node, "micvdd"); if (np) { config->of_node = np; init_data = of_get_regulator_init_data(arizona->dev, np); if (init_data) { init_data->consumer_supplies = &micsupp->supply; init_data->num_consumer_supplies = 1; pdata->micvdd = init_data; } } return 0; }
static int arizona_ldo1_of_get_pdata(struct arizona *arizona, struct regulator_config *config) { struct arizona_pdata *pdata = &arizona->pdata; struct arizona_ldo1 *ldo1 = config->driver_data; struct device_node *init_node, *dcvdd_node; struct regulator_init_data *init_data; pdata->ldoena = arizona_of_get_named_gpio(arizona, "wlf,ldoena", true); init_node = of_get_child_by_name(arizona->dev->of_node, "ldo1"); dcvdd_node = of_parse_phandle(arizona->dev->of_node, "DCVDD-supply", 0); if (init_node) { config->of_node = init_node; init_data = of_get_regulator_init_data(arizona->dev, init_node); if (init_data) { init_data->consumer_supplies = &ldo1->supply; init_data->num_consumer_supplies = 1; if (dcvdd_node && dcvdd_node != init_node) arizona->external_dcvdd = true; pdata->ldo1 = init_data; } } else if (dcvdd_node) { arizona->external_dcvdd = true; } of_node_put(dcvdd_node); return 0; }
static int stw481x_vmmc_regulator_probe(struct platform_device *pdev) { struct stw481x *stw481x = dev_get_platdata(&pdev->dev); struct regulator_config config = { }; int ret; /* First disable the external VMMC if it's active */ ret = regmap_update_bits(stw481x->map, STW_CONF2, STW_CONF2_VMMC_EXT, 0); if (ret) { dev_err(&pdev->dev, "could not disable external VMMC\n"); return ret; } /* Register VMMC regulator */ config.dev = &pdev->dev; config.driver_data = stw481x; config.regmap = stw481x->map; config.of_node = pdev->dev.of_node; config.init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); stw481x->vmmc_regulator = regulator_register(&vmmc_regulator, &config); if (IS_ERR(stw481x->vmmc_regulator)) { dev_err(&pdev->dev, "error initializing STw481x VMMC regulator\n"); return PTR_ERR(stw481x->vmmc_regulator); } dev_info(&pdev->dev, "initialized STw481x VMMC regulator\n"); return 0; }
static int pm8607_regulator_dt_init(struct platform_device *pdev, struct pm8607_regulator_info *info, struct regulator_config *config) { struct device_node *nproot, *np; nproot = pdev->dev.parent->of_node; if (!nproot) return -ENODEV; nproot = of_get_child_by_name(nproot, "regulators"); if (!nproot) { dev_err(&pdev->dev, "failed to find regulators node\n"); return -ENODEV; } for_each_child_of_node(nproot, np) { if (!of_node_cmp(np->name, info->desc.name)) { config->init_data = of_get_regulator_init_data(&pdev->dev, np, &info->desc); config->of_node = np; break; } } of_node_put(nproot); return 0; }
static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata, struct regulator_config *config, const struct regulator_desc *desc, bool *external_dcvdd) { struct arizona_ldo1 *ldo1 = config->driver_data; struct device_node *np = config->dev->of_node; struct device_node *init_node, *dcvdd_node; struct regulator_init_data *init_data; init_node = of_get_child_by_name(np, "ldo1"); dcvdd_node = of_parse_phandle(np, "DCVDD-supply", 0); if (init_node) { config->of_node = init_node; init_data = of_get_regulator_init_data(config->dev, init_node, desc); if (init_data) { init_data->consumer_supplies = &ldo1->supply; init_data->num_consumer_supplies = 1; if (dcvdd_node && dcvdd_node != init_node) *external_dcvdd = true; pdata->init_data = init_data; } } else if (dcvdd_node) { *external_dcvdd = true; } of_node_put(dcvdd_node); return 0; }
/** * of_regulator_match - extract multiple regulator init data from device tree. * @dev: device requesting the data * @node: parent device node of the regulators * @matches: match table for the regulators * @num_matches: number of entries in match table * * This function uses a match table specified by the regulator driver to * parse regulator init data from the device tree. @node is expected to * contain a set of child nodes, each providing the init data for one * regulator. The data parsed from a child node will be matched to a regulator * based on either the deprecated property regulator-compatible if present, * or otherwise the child node's name. Note that the match table is modified * in place and an additional of_node reference is taken for each matched * regulator. * * Returns the number of matches found or a negative error code on failure. */ int of_regulator_match(struct device *dev, struct device_node *node, struct of_regulator_match *matches, unsigned int num_matches) { unsigned int count = 0; unsigned int i; const char *name; struct device_node *child; struct devm_of_regulator_matches *devm_matches; if (!dev || !node) return -EINVAL; devm_matches = devres_alloc(devm_of_regulator_put_matches, sizeof(struct devm_of_regulator_matches), GFP_KERNEL); if (!devm_matches) return -ENOMEM; devm_matches->matches = matches; devm_matches->num_matches = num_matches; devres_add(dev, devm_matches); for (i = 0; i < num_matches; i++) { struct of_regulator_match *match = &matches[i]; match->init_data = NULL; match->of_node = NULL; } for_each_child_of_node(node, child) { name = of_get_property(child, "regulator-compatible", NULL); if (!name) name = child->name; for (i = 0; i < num_matches; i++) { struct of_regulator_match *match = &matches[i]; if (match->of_node) continue; if (strcmp(match->name, name)) continue; match->init_data = of_get_regulator_init_data(dev, child, match->desc); if (!match->init_data) { dev_err(dev, "failed to parse DT for regulator %pOFn\n", child); of_node_put(child); return -EINVAL; } match->of_node = of_node_get(child); count++; break; } }
/** * of_get_fixed_voltage_config - extract fixed_voltage_config structure info * @dev: device requesting for fixed_voltage_config * * Populates fixed_voltage_config structure by extracting data from device * tree node, returns a pointer to the populated structure of NULL if memory * alloc fails. */ static struct fixed_voltage_config * of_get_fixed_voltage_config(struct device *dev) { struct fixed_voltage_config *config; struct device_node *np = dev->of_node; const __be32 *delay; struct regulator_init_data *init_data; config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), GFP_KERNEL); if (!config) return ERR_PTR(-ENOMEM); config->init_data = of_get_regulator_init_data(dev, dev->of_node); if (!config->init_data) return ERR_PTR(-EINVAL); init_data = config->init_data; init_data->constraints.apply_uV = 0; config->supply_name = init_data->constraints.name; if (init_data->constraints.min_uV == init_data->constraints.max_uV) { config->microvolts = init_data->constraints.min_uV; } else { dev_err(dev, "Fixed regulator specified with variable voltages\n"); return ERR_PTR(-EINVAL); } if (init_data->constraints.boot_on) config->enabled_at_boot = true; config->gpio = of_get_named_gpio(np, "gpio", 0); /* * of_get_named_gpio() currently returns ENODEV rather than * EPROBE_DEFER. This code attempts to be compatible with both * for now; the ENODEV check can be removed once the API is fixed. * of_get_named_gpio() doesn't differentiate between a missing * property (which would be fine here, since the GPIO is optional) * and some other error. Patches have been posted for both issues. * Once they are check in, we should replace this with: * if (config->gpio < 0 && config->gpio != -ENOENT) */ if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER)) return ERR_PTR(-EPROBE_DEFER); delay = of_get_property(np, "startup-delay-us", NULL); if (delay) config->startup_delay = be32_to_cpu(*delay); if (of_find_property(np, "enable-active-high", NULL)) config->enable_high = true; if (of_find_property(np, "parent-supply", NULL)) init_data->supply_regulator = "parent"; return config; }
static int s2mps13_pmic_dt_parse_pdata(struct sec_pmic_dev *iodev, struct sec_platform_data *pdata) { struct device_node *pmic_np, *regulators_np, *reg_np; struct sec_regulator_data *rdata; unsigned int i; pmic_np = iodev->dev->of_node; if (!pmic_np) { dev_err(iodev->dev, "could not find pmic sub-node\n"); return -ENODEV; } regulators_np = of_find_node_by_name(pmic_np, "regulators"); if (!regulators_np) { dev_err(iodev->dev, "could not find regulators sub-node\n"); return -EINVAL; } /* count the number of regulators to be supported in pmic */ pdata->num_regulators = 0; for_each_child_of_node(regulators_np, reg_np) { pdata->num_regulators++; } rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * pdata->num_regulators, GFP_KERNEL); if (!rdata) { dev_err(iodev->dev, "could not allocate memory for regulator data\n"); return -ENOMEM; } pdata->regulators = rdata; s2mps13_desc_type = iodev->rev_num ? S2MPS13_DESC_TYPE1 : S2MPS13_DESC_TYPE0; for_each_child_of_node(regulators_np, reg_np) { for (i = 0; i < ARRAY_SIZE(regulators[s2mps13_desc_type]); i++) if (!of_node_cmp(reg_np->name, regulators[s2mps13_desc_type][i].name)) break; if (i == ARRAY_SIZE(regulators[s2mps13_desc_type])) { dev_warn(iodev->dev, "don't know how to configure regulator %s\n", reg_np->name); continue; } rdata->id = i; rdata->initdata = of_get_regulator_init_data( iodev->dev, reg_np); rdata->reg_node = reg_np; rdata++; } return 0; }
static int mem_acc_regulator_probe(struct platform_device *pdev) { struct mem_acc_regulator *mem_acc_vreg; struct regulator_desc *rdesc; struct regulator_init_data *init_data; int rc; if (!pdev->dev.of_node) { pr_err("Device tree node is missing\n"); return -EINVAL; } init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); if (!init_data) { pr_err("regulator init data is missing\n"); return -EINVAL; } else { init_data->constraints.input_uV = init_data->constraints.max_uV; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; } mem_acc_vreg = devm_kzalloc(&pdev->dev, sizeof(*mem_acc_vreg), GFP_KERNEL); if (!mem_acc_vreg) { pr_err("Can't allocate mem_acc_vreg memory\n"); return -ENOMEM; } mem_acc_vreg->dev = &pdev->dev; rc = mem_acc_init(pdev, mem_acc_vreg); if (rc) { pr_err("Unable to initialize mem_acc configuration rc=%d\n", rc); return rc; } rdesc = &mem_acc_vreg->rdesc; rdesc->owner = THIS_MODULE; rdesc->type = REGULATOR_VOLTAGE; rdesc->ops = &mem_acc_corner_ops; rdesc->name = init_data->constraints.name; mem_acc_vreg->rdev = regulator_register(rdesc, &pdev->dev, init_data, mem_acc_vreg, pdev->dev.of_node); if (IS_ERR(mem_acc_vreg->rdev)) { rc = PTR_ERR(mem_acc_vreg->rdev); if (rc != -EPROBE_DEFER) pr_err("regulator_register failed: rc=%d\n", rc); return rc; } platform_set_drvdata(pdev, mem_acc_vreg); return 0; }
static int pwm_regulator_probe(struct platform_device *pdev) { const struct regulator_init_data *init_data; struct pwm_regulator_data *drvdata; struct regulator_dev *regulator; struct regulator_config config = { }; struct device_node *np = pdev->dev.of_node; int ret; if (!np) { dev_err(&pdev->dev, "Device Tree node missing\n"); return -EINVAL; } drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; if (of_find_property(np, "voltage-table", NULL)) ret = pwm_regulator_init_table(pdev, drvdata); else ret = pwm_regulator_init_continuous(pdev, drvdata); if (ret) return ret; init_data = of_get_regulator_init_data(&pdev->dev, np, &pwm_regulator_desc); if (!init_data) return -ENOMEM; config.of_node = np; config.dev = &pdev->dev; config.driver_data = drvdata; config.init_data = init_data; drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(drvdata->pwm)) { dev_err(&pdev->dev, "Failed to get PWM\n"); return PTR_ERR(drvdata->pwm); } regulator = devm_regulator_register(&pdev->dev, &pwm_regulator_desc, &config); if (IS_ERR(regulator)) { dev_err(&pdev->dev, "Failed to register regulator %s\n", pwm_regulator_desc.name); return PTR_ERR(regulator); } return 0; }
struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( struct platform_device *pdev, struct mc13xxx_regulator *regulators, int num_regulators) { struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); struct mc13xxx_regulator_init_data *data, *p; struct device_node *parent, *child; int i, parsed = 0; if (!pdev->dev.parent->of_node) return NULL; parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); if (!parent) return NULL; data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators, GFP_KERNEL); if (!data) { of_node_put(parent); return NULL; } p = data; for_each_child_of_node(parent, child) { int found = 0; for (i = 0; i < num_regulators; i++) { if (!regulators[i].desc.name) continue; if (!of_node_cmp(child->name, regulators[i].desc.name)) { p->id = i; p->init_data = of_get_regulator_init_data( &pdev->dev, child, ®ulators[i].desc); p->node = child; p++; parsed++; found = 1; break; } } if (!found) dev_warn(&pdev->dev, "Unknown regulator: %s\n", child->name); }
static int stm32_vrefbuf_probe(struct platform_device *pdev) { struct resource *res; struct stm32_vrefbuf *priv; struct regulator_config config = { }; struct regulator_dev *rdev; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); priv->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); ret = clk_prepare_enable(priv->clk); if (ret) { dev_err(&pdev->dev, "clk prepare failed with error %d\n", ret); return ret; } config.dev = &pdev->dev; config.driver_data = priv; config.of_node = pdev->dev.of_node; config.init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, &stm32_vrefbuf_regu); rdev = regulator_register(&stm32_vrefbuf_regu, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(&pdev->dev, "register failed with error %d\n", ret); goto err_clk_dis; } platform_set_drvdata(pdev, rdev); return 0; err_clk_dis: clk_disable_unprepare(priv->clk); return ret; }
static struct max8952_platform_data *max8952_parse_dt(struct device *dev) { struct max8952_platform_data *pd; struct device_node *np = dev->of_node; int ret; int i; pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); if (!pd) return NULL; pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0); pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1); pd->gpio_en = of_get_named_gpio(np, "max8952,en-gpio", 0); if (of_property_read_u32(np, "max8952,default-mode", &pd->default_mode)) dev_warn(dev, "Default mode not specified, assuming 0\n"); ret = of_property_read_u32_array(np, "max8952,dvs-mode-microvolt", pd->dvs_mode, ARRAY_SIZE(pd->dvs_mode)); if (ret) { dev_err(dev, "max8952,dvs-mode-microvolt property not specified"); return NULL; } for (i = 0; i < ARRAY_SIZE(pd->dvs_mode); ++i) { if (pd->dvs_mode[i] < 770000 || pd->dvs_mode[i] > 1400000) { dev_err(dev, "DVS voltage %d out of range\n", i); return NULL; } pd->dvs_mode[i] = (pd->dvs_mode[i] - 770000) / 10000; } if (of_property_read_u32(np, "max8952,sync-freq", &pd->sync_freq)) dev_warn(dev, "max8952,sync-freq property not specified, defaulting to 26MHz\n"); if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed)) dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n"); pd->reg_data = of_get_regulator_init_data(dev, np, ®ulator); if (!pd->reg_data) { dev_err(dev, "Failed to parse regulator init data\n"); return NULL; } return pd; }
static int arizona_ldo1_of_get_pdata(struct arizona *arizona, struct regulator_config *config, const struct regulator_desc *desc) { struct arizona_pdata *pdata = &arizona->pdata; struct arizona_ldo1 *ldo1 = config->driver_data; struct device_node *np = arizona->dev->of_node; struct device_node *init_node, *dcvdd_node; struct regulator_init_data *init_data; pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0); if (pdata->ldoena < 0) { dev_warn(arizona->dev, "LDOENA GPIO property missing/malformed: %d\n", pdata->ldoena); pdata->ldoena = 0; } else { config->ena_gpio_initialized = true; } init_node = of_get_child_by_name(np, "ldo1"); dcvdd_node = of_parse_phandle(np, "DCVDD-supply", 0); if (init_node) { config->of_node = init_node; init_data = of_get_regulator_init_data(arizona->dev, init_node, desc); if (init_data) { init_data->consumer_supplies = &ldo1->supply; init_data->num_consumer_supplies = 1; if (dcvdd_node && dcvdd_node != init_node) arizona->external_dcvdd = true; pdata->ldo1 = init_data; } } else if (dcvdd_node) { arizona->external_dcvdd = true; } of_node_put(dcvdd_node); return 0; }
/** * of_get_fixed_voltage_config - extract fixed_voltage_config structure info * @dev: device requesting for fixed_voltage_config * * Populates fixed_voltage_config structure by extracting data from device * tree node, returns a pointer to the populated structure of NULL if memory * alloc fails. */ static struct fixed_voltage_config * of_get_fixed_voltage_config(struct device *dev) { struct fixed_voltage_config *config; struct device_node *np = dev->of_node; const __be32 *delay; struct regulator_init_data *init_data; config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), GFP_KERNEL); if (!config) return NULL; config->init_data = of_get_regulator_init_data(dev, dev->of_node); if (!config->init_data) return NULL; init_data = config->init_data; init_data->constraints.apply_uV = 0; config->supply_name = init_data->constraints.name; if (init_data->constraints.min_uV == init_data->constraints.max_uV) { config->microvolts = init_data->constraints.min_uV; } else { dev_err(dev, "Fixed regulator specified with variable voltages\n"); return NULL; } if (init_data->constraints.boot_on) config->enabled_at_boot = true; config->gpio = of_get_named_gpio(np, "gpio", 0); delay = of_get_property(np, "startup-delay-us", NULL); if (delay) config->startup_delay = be32_to_cpu(*delay); if (of_find_property(np, "enable-active-high", NULL)) config->enable_high = true; return config; }
static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, struct device_node *np, const struct regulator_desc *desc) { struct fan53555_platform_data *pdata; int ret; u32 tmp; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; pdata->regulator = of_get_regulator_init_data(dev, np, desc); ret = of_property_read_u32(np, "fcs,suspend-voltage-selector", &tmp); if (!ret) pdata->sleep_vsel_id = tmp; return pdata; }
static struct fan53555_platform_data * fan53555_get_of_platform_data(struct i2c_client *client) { struct fan53555_platform_data *pdata = NULL; struct regulator_init_data *init_data; u32 sleep_sel; init_data = of_get_regulator_init_data(&client->dev, client->dev.of_node); if (!init_data) { dev_err(&client->dev, "regulator init data is missing\n"); return pdata; } if (fan53555_parse_backup_reg(client, &sleep_sel)) return pdata; pdata = devm_kzalloc(&client->dev, sizeof(struct fan53555_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "fan53555_platform_data allocation failed.\n"); return pdata; } init_data->constraints.input_uV = init_data->constraints.max_uV; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE; init_data->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST; init_data->constraints.initial_mode = REGULATOR_MODE_NORMAL; pdata->regulator = init_data; pdata->sleep_vsel_id = sleep_sel; return pdata; }
static int smb349_regulator_init(struct smb349_charger *chip) { int rc = 0; struct regulator_init_data *init_data; struct regulator_config cfg = {}; init_data = of_get_regulator_init_data(chip->dev, chip->dev->of_node); if (!init_data) { dev_err(chip->dev, "Unable to allocate memory\n"); return -ENOMEM; } if (init_data->constraints.name) { chip->otg_vreg.rdesc.owner = THIS_MODULE; chip->otg_vreg.rdesc.type = REGULATOR_VOLTAGE; chip->otg_vreg.rdesc.ops = &smb349_chg_otg_reg_ops; chip->otg_vreg.rdesc.name = init_data->constraints.name; cfg.dev = chip->dev; cfg.init_data = init_data; cfg.driver_data = chip; cfg.of_node = chip->dev->of_node; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS; chip->otg_vreg.rdev = regulator_register( &chip->otg_vreg.rdesc, &cfg); if (IS_ERR(chip->otg_vreg.rdev)) { rc = PTR_ERR(chip->otg_vreg.rdev); chip->otg_vreg.rdev = NULL; if (rc != -EPROBE_DEFER) dev_err(chip->dev, "OTG reg failed, rc=%d\n", rc); } } return rc; }
struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( struct platform_device *pdev, struct mc13xxx_regulator *regulators, int num_regulators) { struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); struct mc13xxx_regulator_init_data *data, *p; struct device_node *parent, *child; int i; of_node_get(pdev->dev.parent->of_node); parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); if (!parent) return NULL; data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators, GFP_KERNEL); if (!data) return NULL; p = data; for_each_child_of_node(parent, child) { for (i = 0; i < num_regulators; i++) { if (!of_node_cmp(child->name, regulators[i].desc.name)) { p->id = i; p->init_data = of_get_regulator_init_data( &pdev->dev, child); p->node = child; p++; break; } } } return data; }
static int __devinit anatop_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct regulator_desc *rdesc; struct regulator_dev *rdev; struct anatop_regulator *sreg; struct regulator_init_data *initdata; struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent); int ret = 0; initdata = of_get_regulator_init_data(dev, np); sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); if (!sreg) return -ENOMEM; sreg->initdata = initdata; sreg->name = kstrdup(of_get_property(np, "regulator-name", NULL), GFP_KERNEL); rdesc = &sreg->rdesc; memset(rdesc, 0, sizeof(*rdesc)); rdesc->name = sreg->name; rdesc->ops = &anatop_rops; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; sreg->mfd = anatopmfd; ret = of_property_read_u32(np, "anatop-reg-offset", &sreg->control_reg); if (ret) { dev_err(dev, "no anatop-reg-offset property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-vol-bit-width", &sreg->vol_bit_width); if (ret) { dev_err(dev, "no anatop-vol-bit-width property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-vol-bit-shift", &sreg->vol_bit_shift); if (ret) { dev_err(dev, "no anatop-vol-bit-shift property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-min-bit-val", &sreg->min_bit_val); if (ret) { dev_err(dev, "no anatop-min-bit-val property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-min-voltage", &sreg->min_voltage); if (ret) { dev_err(dev, "no anatop-min-voltage property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-max-voltage", &sreg->max_voltage); if (ret) { dev_err(dev, "no anatop-max-voltage property set\n"); goto anatop_probe_end; } rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1; rdev = regulator_register(rdesc, dev, initdata, sreg, pdev->dev.of_node); if (IS_ERR(rdev)) { dev_err(dev, "failed to register %s\n", rdesc->name); ret = PTR_ERR(rdev); goto anatop_probe_end; } platform_set_drvdata(pdev, rdev); anatop_probe_end: if (ret) kfree(sreg->name); return ret; }
static int regulator_stub_probe(struct platform_device *pdev) { struct regulator_config reg_config = {}; struct regulator_init_data *init_data = NULL; struct device *dev = &pdev->dev; struct stub_regulator_pdata *vreg_pdata; struct regulator_desc *rdesc; struct regulator_stub *vreg_priv; int rc; vreg_priv = kzalloc(sizeof(*vreg_priv), GFP_KERNEL); if (!vreg_priv) { dev_err(dev, "%s: Unable to allocate memory\n", __func__); return -ENOMEM; } if (dev->of_node) { /* Use device tree. */ init_data = of_get_regulator_init_data(dev, dev->of_node); if (!init_data) { dev_err(dev, "%s: unable to allocate memory\n", __func__); rc = -ENOMEM; goto err_probe; } if (init_data->constraints.name == NULL) { dev_err(dev, "%s: regulator name not specified\n", __func__); rc = -EINVAL; goto err_probe; } if (of_get_property(dev->of_node, "parent-supply", NULL)) init_data->supply_regulator = "parent"; of_property_read_u32(dev->of_node, "qcom,system-load", &vreg_priv->system_uA); of_property_read_u32(dev->of_node, "qcom,hpm-min-load", &vreg_priv->hpm_min_load); init_data->constraints.input_uV = init_data->constraints.max_uV; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_DRMS; init_data->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE; } else { /* Use platform data. */ vreg_pdata = dev->platform_data; if (!vreg_pdata) { dev_err(dev, "%s: no platform data\n", __func__); rc = -EINVAL; goto err_probe; } init_data = &vreg_pdata->init_data; vreg_priv->system_uA = vreg_pdata->system_uA; vreg_priv->hpm_min_load = vreg_pdata->hpm_min_load; } dev_set_drvdata(dev, vreg_priv); rdesc = &vreg_priv->rdesc; strlcpy(vreg_priv->name, init_data->constraints.name, STUB_REGULATOR_MAX_NAME); rdesc->name = vreg_priv->name; rdesc->ops = ®ulator_stub_ops; /* * Ensure that voltage set points are handled correctly for regulators * which have a specified voltage constraint range, as well as those * that do not. */ if (init_data->constraints.min_uV == 0 && init_data->constraints.max_uV == 0) rdesc->n_voltages = 0; else rdesc->n_voltages = 2; rdesc->id = pdev->id; rdesc->owner = THIS_MODULE; rdesc->type = REGULATOR_VOLTAGE; vreg_priv->voltage = init_data->constraints.min_uV; if (vreg_priv->system_uA >= vreg_priv->hpm_min_load) vreg_priv->mode = REGULATOR_MODE_NORMAL; else vreg_priv->mode = REGULATOR_MODE_IDLE; reg_config.dev = dev; reg_config.init_data = init_data; reg_config.driver_data = vreg_priv; reg_config.of_node = dev->of_node; vreg_priv->rdev = regulator_register(rdesc, ®_config); if (IS_ERR(vreg_priv->rdev)) { rc = PTR_ERR(vreg_priv->rdev); vreg_priv->rdev = NULL; if (rc != -EPROBE_DEFER) dev_err(dev, "%s: regulator_register failed\n", __func__); goto err_probe; } return 0; err_probe: regulator_stub_cleanup(vreg_priv); return rc; }
static int gdsc_probe(struct platform_device *pdev) { static atomic_t gdsc_count = ATOMIC_INIT(-1); struct regulator_config reg_config = {}; struct regulator_init_data *init_data; struct resource *res; struct gdsc *sc; uint32_t regval; bool retain_mem, retain_periph, support_hw_trigger; int i, ret; sc = devm_kzalloc(&pdev->dev, sizeof(struct gdsc), GFP_KERNEL); if (sc == NULL) return -ENOMEM; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); if (init_data == NULL) return -ENOMEM; if (of_get_property(pdev->dev.of_node, "parent-supply", NULL)) init_data->supply_regulator = "parent"; ret = of_property_read_string(pdev->dev.of_node, "regulator-name", &sc->rdesc.name); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) return -EINVAL; sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (sc->gdscr == NULL) return -ENOMEM; sc->clock_count = of_property_count_strings(pdev->dev.of_node, "clock-names"); if (sc->clock_count == -EINVAL) { sc->clock_count = 0; } else if (IS_ERR_VALUE(sc->clock_count)) { dev_err(&pdev->dev, "Failed to get clock names\n"); return -EINVAL; } sc->clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * sc->clock_count, GFP_KERNEL); if (!sc->clocks) return -ENOMEM; sc->root_en = of_property_read_bool(pdev->dev.of_node, "qcom,enable-root-clk"); for (i = 0; i < sc->clock_count; i++) { const char *clock_name; of_property_read_string_index(pdev->dev.of_node, "clock-names", i, &clock_name); sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name); if (IS_ERR(sc->clocks[i])) { int rc = PTR_ERR(sc->clocks[i]); if (rc != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to get %s\n", clock_name); return rc; } } sc->rdesc.id = atomic_inc_return(&gdsc_count); sc->rdesc.ops = &gdsc_ops; sc->rdesc.type = REGULATOR_VOLTAGE; sc->rdesc.owner = THIS_MODULE; platform_set_drvdata(pdev, sc); /* * Disable HW trigger: collapse/restore occur based on registers writes. * Disable SW override: Use hardware state-machine for sequencing. */ regval = readl_relaxed(sc->gdscr); regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK); /* Configure wait time between states. */ regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK); regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; writel_relaxed(regval, sc->gdscr); retain_mem = of_property_read_bool(pdev->dev.of_node, "qcom,retain-mem"); sc->toggle_mem = !retain_mem; retain_periph = of_property_read_bool(pdev->dev.of_node, "qcom,retain-periph"); sc->toggle_periph = !retain_periph; sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node, "qcom,skip-logic-collapse"); support_hw_trigger = of_property_read_bool(pdev->dev.of_node, "qcom,support-hw-trigger"); if (support_hw_trigger) { init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE; init_data->constraints.valid_modes_mask |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST; } if (!sc->toggle_logic) { regval &= ~SW_COLLAPSE_MASK; writel_relaxed(regval, sc->gdscr); ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK, TIMEOUT_US); if (ret) { dev_err(&pdev->dev, "%s enable timed out: 0x%x\n", sc->rdesc.name, regval); return ret; } } for (i = 0; i < sc->clock_count; i++) { if (retain_mem || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM); if (retain_periph || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH); } reg_config.dev = &pdev->dev; reg_config.init_data = init_data; reg_config.driver_data = sc; reg_config.of_node = pdev->dev.of_node; sc->rdev = regulator_register(&sc->rdesc, ®_config); if (IS_ERR(sc->rdev)) { dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n", sc->rdesc.name); return PTR_ERR(sc->rdev); } return 0; }
static struct ncp6335d_platform_data * ncp6335d_get_of_platform_data(struct i2c_client *client) { struct ncp6335d_platform_data *pdata = NULL; struct regulator_init_data *init_data; const char *mode_name; int rc; init_data = of_get_regulator_init_data(&client->dev, client->dev.of_node); if (!init_data) { dev_err(&client->dev, "regulator init data is missing\n"); return pdata; } pdata = devm_kzalloc(&client->dev, sizeof(struct ncp6335d_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "ncp6335d_platform_data allocation failed.\n"); return pdata; } rc = of_property_read_u32(client->dev.of_node, "onnn,vsel", &pdata->default_vsel); if (rc < 0) { dev_err(&client->dev, "onnn,vsel property missing: rc = %d.\n", rc); return NULL; } rc = of_property_read_u32(client->dev.of_node, "onnn,slew-ns", &pdata->slew_rate_ns); if (rc < 0) { dev_err(&client->dev, "onnn,slew-ns property missing: rc = %d.\n", rc); return NULL; } pdata->discharge_enable = of_property_read_bool(client->dev.of_node, "onnn,discharge-enable"); pdata->sleep_enable = of_property_read_bool(client->dev.of_node, "onnn,sleep-enable"); pdata->init_data = init_data; init_data->constraints.input_uV = init_data->constraints.max_uV; init_data->constraints.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE; init_data->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST; rc = of_property_read_string(client->dev.of_node, "onnn,mode", &mode_name); if (!rc) { if (strcmp("pwm", mode_name) == 0) { init_data->constraints.initial_mode = REGULATOR_MODE_FAST; } else if (strcmp("auto", mode_name) == 0) { init_data->constraints.initial_mode = REGULATOR_MODE_NORMAL; } else { dev_err(&client->dev, "onnn,mode, unknown regulator mode: %s\n", mode_name); return NULL; } } return pdata; }
static struct gpio_regulator_config * of_get_gpio_regulator_config(struct device *dev, struct device_node *np) { struct gpio_regulator_config *config; struct property *prop; const char *regtype; int proplen, gpio, i; int ret; config = devm_kzalloc(dev, sizeof(struct gpio_regulator_config), GFP_KERNEL); if (!config) return ERR_PTR(-ENOMEM); config->init_data = of_get_regulator_init_data(dev, np); if (!config->init_data) return ERR_PTR(-EINVAL); config->supply_name = config->init_data->constraints.name; if (of_property_read_bool(np, "enable-active-high")) config->enable_high = true; if (of_property_read_bool(np, "enable-at-boot")) config->enabled_at_boot = true; of_property_read_u32(np, "startup-delay-us", &config->startup_delay); config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); /* Fetch GPIOs. */ config->nr_gpios = of_gpio_count(np); config->gpios = devm_kzalloc(dev, sizeof(struct gpio) * config->nr_gpios, GFP_KERNEL); if (!config->gpios) return ERR_PTR(-ENOMEM); prop = of_find_property(np, "gpios-states", NULL); if (prop) { proplen = prop->length / sizeof(int); if (proplen != config->nr_gpios) { /* gpios <-> gpios-states mismatch */ prop = NULL; } } for (i = 0; i < config->nr_gpios; i++) { gpio = of_get_named_gpio(np, "gpios", i); if (gpio < 0) break; config->gpios[i].gpio = gpio; if (prop && be32_to_cpup((int *)prop->value + i)) config->gpios[i].flags = GPIOF_OUT_INIT_HIGH; } /* Fetch states. */ prop = of_find_property(np, "states", NULL); if (!prop) { dev_err(dev, "No 'states' property found\n"); return ERR_PTR(-EINVAL); } proplen = prop->length / sizeof(int); config->states = devm_kzalloc(dev, sizeof(struct gpio_regulator_state) * (proplen / 2), GFP_KERNEL); if (!config->states) return ERR_PTR(-ENOMEM); for (i = 0; i < proplen / 2; i++) { config->states[i].value = be32_to_cpup((int *)prop->value + (i * 2)); config->states[i].gpios = be32_to_cpup((int *)prop->value + (i * 2 + 1)); } config->nr_states = i; config->type = REGULATOR_VOLTAGE; ret = of_property_read_string(np, "regulator-type", ®type); if (ret >= 0) { if (!strncmp("voltage", regtype, 7)) config->type = REGULATOR_VOLTAGE; else if (!strncmp("current", regtype, 7)) config->type = REGULATOR_CURRENT; else dev_warn(dev, "Unknown regulator-type '%s'\n", regtype); } return config; }
{ int i, id; struct twlreg_info *info; const struct twlreg_info *template; struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; struct twl_regulator_driver_data *drvdata; const struct of_device_id *match; struct regulator_config config = { }; match = of_match_device(twl_of_match, &pdev->dev); if (match) { template = match->data; id = template->desc.id; initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); drvdata = NULL; } else { id = pdev->id; initdata = pdev->dev.platform_data; for (i = 0, template = NULL; i < ARRAY_SIZE(twl_of_match); i++) { template = twl_of_match[i].data; if (template && template->desc.id == id) break; } if (i == ARRAY_SIZE(twl_of_match)) return -ENODEV; drvdata = initdata->driver_data; if (!drvdata) return -EINVAL;
static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev, struct max17135_platform_data *pdata) { struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent); struct device_node *pmic_np, *regulators_np, *reg_np; struct max17135_regulator_data *rdata; int i, ret; pmic_np = of_node_get(max17135->dev->of_node); if (!pmic_np) { dev_err(&pdev->dev, "could not find pmic sub-node\n"); return -ENODEV; } regulators_np = of_find_node_by_name(pmic_np, "regulators"); if (!regulators_np) { dev_err(&pdev->dev, "could not find regulators sub-node\n"); return -EINVAL; } pdata->num_regulators = of_get_child_count(regulators_np); dev_dbg(&pdev->dev, "num_regulators %d\n", pdata->num_regulators); rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * pdata->num_regulators, GFP_KERNEL); if (!rdata) { of_node_put(regulators_np); dev_err(&pdev->dev, "could not allocate memory for" "regulator data\n"); return -ENOMEM; } pdata->regulators = rdata; for_each_child_of_node(regulators_np, reg_np) { for (i = 0; i < ARRAY_SIZE(max17135_reg); i++) if (!of_node_cmp(reg_np->name, max17135_reg[i].name)) break; if (i == ARRAY_SIZE(max17135_reg)) { dev_warn(&pdev->dev, "don't know how to configure" "regulator %s\n", reg_np->name); continue; } rdata->id = i; rdata->initdata = of_get_regulator_init_data(&pdev->dev, reg_np, &max17135_reg[i]); rdata->reg_node = reg_np; rdata++; } of_node_put(regulators_np); CHECK_PROPERTY_ERROR_KFREE(vneg_pwrup); CHECK_PROPERTY_ERROR_KFREE(gvee_pwrup); CHECK_PROPERTY_ERROR_KFREE(vpos_pwrup); CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrup); CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrdn); CHECK_PROPERTY_ERROR_KFREE(vpos_pwrdn); CHECK_PROPERTY_ERROR_KFREE(gvee_pwrdn); CHECK_PROPERTY_ERROR_KFREE(vneg_pwrdn); dev_dbg(&pdev->dev, "vneg_pwrup %d, vneg_pwrdn %d, vpos_pwrup %d," "vpos_pwrdn %d, gvdd_pwrup %d, gvdd_pwrdn %d, gvee_pwrup %d," "gvee_pwrdn %d\n", max17135->vneg_pwrup, max17135->vneg_pwrdn, max17135->vpos_pwrup, max17135->vpos_pwrdn, max17135->gvdd_pwrup, max17135->gvdd_pwrdn, max17135->gvee_pwrup, max17135->gvee_pwrdn); max17135->max_wait = max17135->vpos_pwrup + max17135->vneg_pwrup + max17135->gvdd_pwrup + max17135->gvee_pwrup; max17135->gpio_pmic_wakeup = of_get_named_gpio(pmic_np, "gpio_pmic_wakeup", 0); if (!gpio_is_valid(max17135->gpio_pmic_wakeup)) { dev_err(&pdev->dev, "no epdc pmic wakeup pin available\n"); goto err; } ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_wakeup, GPIOF_OUT_INIT_LOW, "epdc-pmic-wake"); if (ret < 0) goto err; max17135->gpio_pmic_vcom_ctrl = of_get_named_gpio(pmic_np, "gpio_pmic_vcom_ctrl", 0); if (!gpio_is_valid(max17135->gpio_pmic_vcom_ctrl)) { dev_err(&pdev->dev, "no epdc pmic vcom_ctrl pin available\n"); goto err; } ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_vcom_ctrl, GPIOF_OUT_INIT_LOW, "epdc-vcom"); if (ret < 0) goto err; max17135->gpio_pmic_v3p3 = of_get_named_gpio(pmic_np, "gpio_pmic_v3p3", 0); if (!gpio_is_valid(max17135->gpio_pmic_v3p3)) { dev_err(&pdev->dev, "no epdc pmic v3p3 pin available\n"); goto err; } ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_v3p3, GPIOF_OUT_INIT_LOW, "epdc-v3p3"); if (ret < 0) goto err; max17135->gpio_pmic_intr = of_get_named_gpio(pmic_np, "gpio_pmic_intr", 0); if (!gpio_is_valid(max17135->gpio_pmic_intr)) { dev_err(&pdev->dev, "no epdc pmic intr pin available\n"); goto err; } ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_intr, GPIOF_IN, "epdc-pmic-int"); if (ret < 0) goto err; max17135->gpio_pmic_pwrgood = of_get_named_gpio(pmic_np, "gpio_pmic_pwrgood", 0); if (!gpio_is_valid(max17135->gpio_pmic_pwrgood)) { dev_err(&pdev->dev, "no epdc pmic pwrgood pin available\n"); goto err; } ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_pwrgood, GPIOF_IN, "epdc-pwrstat"); if (ret < 0) goto err; err: return 0; }
/** * ti_abb_probe() - Initialize an ABB ldo instance * @pdev: ABB platform device * * Initializes an individual ABB LDO for required Body-Bias. ABB is used to * addional bias supply to SoC modules for power savings or mandatory stability * configuration at certain Operating Performance Points(OPPs). * * Return: 0 on success or appropriate error value when fails */ static int ti_abb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct of_device_id *match; struct resource *res; struct ti_abb *abb; struct regulator_init_data *initdata = NULL; struct regulator_dev *rdev = NULL; struct regulator_desc *desc; struct regulation_constraints *c; struct regulator_config config = { }; char *pname; int ret = 0; match = of_match_device(ti_abb_of_match, dev); if (!match) { /* We do not expect this to happen */ dev_err(dev, "%s: Unable to match device\n", __func__); return -ENODEV; } if (!match->data) { dev_err(dev, "%s: Bad data in match\n", __func__); return -EINVAL; } abb = devm_kzalloc(dev, sizeof(struct ti_abb), GFP_KERNEL); if (!abb) return -ENOMEM; abb->regs = match->data; /* Map ABB resources */ if (abb->regs->setup_off || abb->regs->control_off) { pname = "base-address"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); abb->base = devm_ioremap_resource(dev, res); if (IS_ERR(abb->base)) return PTR_ERR(abb->base); abb->setup_reg = abb->base + abb->regs->setup_off; abb->control_reg = abb->base + abb->regs->control_off; } else { pname = "control-address"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); abb->control_reg = devm_ioremap_resource(dev, res); if (IS_ERR(abb->control_reg)) return PTR_ERR(abb->control_reg); pname = "setup-address"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); abb->setup_reg = devm_ioremap_resource(dev, res); if (IS_ERR(abb->setup_reg)) return PTR_ERR(abb->setup_reg); } pname = "int-address"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); if (!res) { dev_err(dev, "Missing '%s' IO resource\n", pname); return -ENODEV; } /* * We may have shared interrupt register offsets which are * write-1-to-clear between domains ensuring exclusivity. */ abb->int_base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!abb->int_base) { dev_err(dev, "Unable to map '%s'\n", pname); return -ENOMEM; } /* Map Optional resources */ pname = "efuse-address"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); if (!res) { dev_dbg(dev, "Missing '%s' IO resource\n", pname); ret = -ENODEV; goto skip_opt; } /* * We may have shared efuse register offsets which are read-only * between domains */ abb->efuse_base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!abb->efuse_base) { dev_err(dev, "Unable to map '%s'\n", pname); return -ENOMEM; } pname = "ldo-address"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); if (!res) { dev_dbg(dev, "Missing '%s' IO resource\n", pname); ret = -ENODEV; goto skip_opt; } abb->ldo_base = devm_ioremap_resource(dev, res); if (IS_ERR(abb->ldo_base)) return PTR_ERR(abb->ldo_base); /* IF ldo_base is set, the following are mandatory */ pname = "ti,ldovbb-override-mask"; ret = of_property_read_u32(pdev->dev.of_node, pname, &abb->ldovbb_override_mask); if (ret) { dev_err(dev, "Missing '%s' (%d)\n", pname, ret); return ret; } if (!abb->ldovbb_override_mask) { dev_err(dev, "Invalid property:'%s' set as 0!\n", pname); return -EINVAL; } pname = "ti,ldovbb-vset-mask"; ret = of_property_read_u32(pdev->dev.of_node, pname, &abb->ldovbb_vset_mask); if (ret) { dev_err(dev, "Missing '%s' (%d)\n", pname, ret); return ret; } if (!abb->ldovbb_vset_mask) { dev_err(dev, "Invalid property:'%s' set as 0!\n", pname); return -EINVAL; } skip_opt: pname = "ti,tranxdone-status-mask"; ret = of_property_read_u32(pdev->dev.of_node, pname, &abb->txdone_mask); if (ret) { dev_err(dev, "Missing '%s' (%d)\n", pname, ret); return ret; } if (!abb->txdone_mask) { dev_err(dev, "Invalid property:'%s' set as 0!\n", pname); return -EINVAL; } initdata = of_get_regulator_init_data(dev, pdev->dev.of_node); if (!initdata) { dev_err(dev, "%s: Unable to alloc regulator init data\n", __func__); return -ENOMEM; } /* init ABB opp_sel table */ ret = ti_abb_init_table(dev, abb, initdata); if (ret) return ret; /* init ABB timing */ ret = ti_abb_init_timings(dev, abb); if (ret) return ret; desc = &abb->rdesc; desc->name = dev_name(dev); desc->owner = THIS_MODULE; desc->type = REGULATOR_VOLTAGE; desc->ops = &ti_abb_reg_ops; c = &initdata->constraints; if (desc->n_voltages > 1) c->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; c->always_on = true; config.dev = dev; config.init_data = initdata; config.driver_data = abb; config.of_node = pdev->dev.of_node; rdev = devm_regulator_register(dev, desc, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(dev, "%s: failed to register regulator(%d)\n", __func__, ret); return ret; } platform_set_drvdata(pdev, rdev); /* Enable the ldo if not already done by bootloader */ ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg); return 0; }
static int s2mps13_pmic_dt_parse_pdata(struct sec_pmic_dev *iodev, struct sec_platform_data *pdata) { struct device_node *pmic_np, *regulators_np, *reg_np; struct sec_regulator_data *rdata; unsigned int i, s2mps13_desc_type; int ret; u32 val; pmic_np = iodev->dev->of_node; if (!pmic_np) { dev_err(iodev->dev, "could not find pmic sub-node\n"); return -ENODEV; } /* If pmic revision number over 0x02, get 3 gpio values */ if (SEC_PMIC_REV(iodev) > 0x02) { if (of_gpio_count(pmic_np) < 3) { dev_err(iodev->dev, "could not find pmic gpios\n"); return -EINVAL; } pdata->smpl_warn = of_get_gpio(pmic_np, 0); pdata->g3d_pin = of_get_gpio(pmic_np, 1); pdata->dvs_pin = of_get_gpio(pmic_np, 2); ret = of_property_read_u32(pmic_np, "g3d_en", &val); if (ret) return -EINVAL; pdata->g3d_en = !!val; ret = of_property_read_u32(pmic_np, "dvs_en", &val); if (ret) return -EINVAL; pdata->dvs_en = !!val; ret = of_property_read_u32(pmic_np, "smpl_warn_en", &val); if (ret) return -EINVAL; pdata->smpl_warn_en = !!val; } else { dev_err(iodev->dev, "cannot control g3d_en & dvs_en\n"); } pdata->ap_buck_avp_en = false; pdata->sub_buck_avp_en = false; if (of_find_property(pmic_np, "ap-buck-avp-en", NULL)) pdata->ap_buck_avp_en = true; if (of_find_property(pmic_np, "sub-buck-avp-en", NULL)) pdata->sub_buck_avp_en = true; regulators_np = of_find_node_by_name(pmic_np, "regulators"); if (!regulators_np) { dev_err(iodev->dev, "could not find regulators sub-node\n"); return -EINVAL; } /* count the number of regulators to be supported in pmic */ pdata->num_regulators = 0; for_each_child_of_node(regulators_np, reg_np) { pdata->num_regulators++; } rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) * pdata->num_regulators, GFP_KERNEL); if (!rdata) { dev_err(iodev->dev, "could not allocate memory for regulator data\n"); return -ENOMEM; } pdata->regulators = rdata; s2mps13_desc_type = SEC_PMIC_REV(iodev) ? S2MPS13_DESC_TYPE1 : S2MPS13_DESC_TYPE0; for_each_child_of_node(regulators_np, reg_np) { for (i = 0; i < ARRAY_SIZE(regulators[s2mps13_desc_type]); i++) if (!of_node_cmp(reg_np->name, regulators[s2mps13_desc_type][i].name)) break; if (i == ARRAY_SIZE(regulators[s2mps13_desc_type])) { dev_warn(iodev->dev, "don't know how to configure regulator %s\n", reg_np->name); continue; } rdata->id = i; rdata->initdata = of_get_regulator_init_data( iodev->dev, reg_np); rdata->reg_node = reg_np; rdata++; } return 0; }
static int __devinit gdsc_probe(struct platform_device *pdev) { static atomic_t gdsc_count = ATOMIC_INIT(-1); struct regulator_init_data *init_data; struct resource *res; struct gdsc *sc; uint32_t regval; bool retain_mem, retain_periph; int i, ret; #ifdef CONFIG_MACH_LGE int use_lge_workaround = 0; /* default: all not applied */ #endif sc = devm_kzalloc(&pdev->dev, sizeof(struct gdsc), GFP_KERNEL); if (sc == NULL) return -ENOMEM; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); if (init_data == NULL) return -ENOMEM; if (of_get_property(pdev->dev.of_node, "parent-supply", NULL)) init_data->supply_regulator = "parent"; ret = of_property_read_string(pdev->dev.of_node, "regulator-name", &sc->rdesc.name); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) return -EINVAL; sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (sc->gdscr == NULL) return -ENOMEM; sc->clock_count = of_property_count_strings(pdev->dev.of_node, "qcom,clock-names"); if (sc->clock_count == -EINVAL) { sc->clock_count = 0; } else if (IS_ERR_VALUE(sc->clock_count)) { dev_err(&pdev->dev, "Failed to get clock names\n"); return -EINVAL; } sc->clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * sc->clock_count, GFP_KERNEL); if (!sc->clocks) return -ENOMEM; for (i = 0; i < sc->clock_count; i++) { const char *clock_name; of_property_read_string_index(pdev->dev.of_node, "qcom,clock-names", i, &clock_name); sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name); if (IS_ERR(sc->clocks[i])) { int rc = PTR_ERR(sc->clocks[i]); if (rc != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to get %s\n", clock_name); return rc; } } #ifdef CONFIG_MACH_LGE of_property_read_u32(pdev->dev.of_node, "lge,use_workaround", &use_lge_workaround); sc->use_lge_workaround = !(!use_lge_workaround); #endif sc->rdesc.id = atomic_inc_return(&gdsc_count); sc->rdesc.ops = &gdsc_ops; sc->rdesc.type = REGULATOR_VOLTAGE; sc->rdesc.owner = THIS_MODULE; platform_set_drvdata(pdev, sc); /* * Disable HW trigger: collapse/restore occur based on registers writes. * Disable SW override: Use hardware state-machine for sequencing. */ regval = readl_relaxed(sc->gdscr); regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK); /* Configure wait time between states. */ regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK); regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; writel_relaxed(regval, sc->gdscr); retain_mem = of_property_read_bool(pdev->dev.of_node, "qcom,retain-mem"); retain_periph = of_property_read_bool(pdev->dev.of_node, "qcom,retain-periph"); for (i = 0; i < sc->clock_count; i++) { if (retain_mem || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM); if (retain_periph || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH); } sc->toggle_mem = !retain_mem; sc->toggle_periph = !retain_periph; sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node, "qcom,skip-logic-collapse"); if (!sc->toggle_logic) { #ifdef CONFIG_MACH_LGE /* LGE workaround is not used if a device is good pdn revision */ if (lge_get_board_revno() >= use_lge_workaround) { regval &= ~SW_COLLAPSE_MASK; writel_relaxed(regval, sc->gdscr); ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK, TIMEOUT_US); if (ret) { dev_err(&pdev->dev, "%s enable timed out\n", sc->rdesc.name); return ret; } } else { pr_info("%s: %s is enabled only at first by lge workaround\n", __func__, sc->rdesc.name); ret = lge_gdsc_enable(sc); if (ret) { dev_err(&pdev->dev, "%s enable timed out\n", sc->rdesc.name); return ret; } } #else /* qmc */ regval &= ~SW_COLLAPSE_MASK; writel_relaxed(regval, sc->gdscr); ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK, TIMEOUT_US); if (ret) { dev_err(&pdev->dev, "%s enable timed out\n", sc->rdesc.name); return ret; } #endif } sc->rdev = regulator_register(&sc->rdesc, &pdev->dev, init_data, sc, pdev->dev.of_node); if (IS_ERR(sc->rdev)) { dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n", sc->rdesc.name); return PTR_ERR(sc->rdev); } return 0; }