static struct regulator *_devm_regulator_get(struct device *dev, const char *id, int get_type) { struct regulator **ptr, *regulator; ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return ERR_PTR(-ENOMEM); switch (get_type) { case NORMAL_GET: regulator = regulator_get(dev, id); break; case EXCLUSIVE_GET: regulator = regulator_get_exclusive(dev, id); break; case OPTIONAL_GET: regulator = regulator_get_optional(dev, id); break; default: regulator = ERR_PTR(-EINVAL); } if (!IS_ERR(regulator)) { *ptr = regulator; devres_add(dev, ptr); } else { devres_free(ptr); } return regulator; }
static int resources_available(void) { struct device *cpu_dev; struct regulator *cpu_reg; struct clk *cpu_clk; int ret = 0; const char *name; cpu_dev = get_cpu_device(0); if (!cpu_dev) { pr_err("failed to get cpu0 device\n"); return -ENODEV; } cpu_clk = clk_get(cpu_dev, NULL); ret = PTR_ERR_OR_ZERO(cpu_clk); if (ret) { /* * If cpu's clk node is present, but clock is not yet * registered, we should try defering probe. */ if (ret == -EPROBE_DEFER) dev_dbg(cpu_dev, "clock not ready, retry\n"); else dev_err(cpu_dev, "failed to get clock: %d\n", ret); return ret; } clk_put(cpu_clk); name = find_supply_name(cpu_dev); /* Platform doesn't require regulator */ if (!name) return 0; cpu_reg = regulator_get_optional(cpu_dev, name); ret = PTR_ERR_OR_ZERO(cpu_reg); if (ret) { /* * If cpu's regulator supply node is present, but regulator is * not yet registered, we should try defering probe. */ if (ret == -EPROBE_DEFER) dev_dbg(cpu_dev, "cpu0 regulator not ready, retry\n"); else dev_dbg(cpu_dev, "no regulator for cpu0: %d\n", ret); return ret; } regulator_put(cpu_reg); return 0; }
static inline u8 get_vbus_power(struct device *dev) { struct regulator *vbus_supply; int current_uA; vbus_supply = regulator_get_optional(dev, "vbus"); if (IS_ERR(vbus_supply)) return 255; current_uA = regulator_get_current_limit(vbus_supply); regulator_put(vbus_supply); if (current_uA <= 0 || current_uA > 510000) return 255; return current_uA / 1000 / 2; }
static int imx6q_cpufreq_probe(struct platform_device *pdev) { struct device_node *np; struct dev_pm_opp *opp; unsigned long min_volt, max_volt; int num, ret; const struct property *prop; const __be32 *val; u32 nr, i, j; cpu_dev = get_cpu_device(0); if (!cpu_dev) { pr_err("failed to get cpu0 device\n"); return -ENODEV; } np = of_node_get(cpu_dev->of_node); if (!np) { dev_err(cpu_dev, "failed to find cpu0 node\n"); return -ENOENT; } arm_clk = clk_get(cpu_dev, "arm"); pll1_sys_clk = clk_get(cpu_dev, "pll1_sys"); pll1_sw_clk = clk_get(cpu_dev, "pll1_sw"); step_clk = clk_get(cpu_dev, "step"); pll2_pfd2_396m_clk = clk_get(cpu_dev, "pll2_pfd2_396m"); if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) || IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) { dev_err(cpu_dev, "failed to get clocks\n"); ret = -ENOENT; goto put_clk; } arm_reg = regulator_get(cpu_dev, "arm"); pu_reg = regulator_get_optional(cpu_dev, "pu"); soc_reg = regulator_get(cpu_dev, "soc"); if (IS_ERR(arm_reg) || IS_ERR(soc_reg)) { dev_err(cpu_dev, "failed to get regulators\n"); ret = -ENOENT; goto put_reg; } /* * We expect an OPP table supplied by platform. * Just, incase the platform did not supply the OPP * table, it will try to get it. */ num = dev_pm_opp_get_opp_count(cpu_dev); if (num < 0) { ret = dev_pm_opp_of_add_table(cpu_dev); if (ret < 0) { dev_err(cpu_dev, "failed to init OPP table: %d\n", ret); goto put_reg; } /* Because we have added the OPPs here, we must free them */ free_opp = true; num = dev_pm_opp_get_opp_count(cpu_dev); if (num < 0) { ret = num; dev_err(cpu_dev, "no OPP table is found: %d\n", ret); goto out_free_opp; } } ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); if (ret) { dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); goto put_reg; } /* Make imx6_soc_volt array's size same as arm opp number */ imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL); if (imx6_soc_volt == NULL) { ret = -ENOMEM; goto free_freq_table; } prop = of_find_property(np, "fsl,soc-operating-points", NULL); if (!prop || !prop->value) goto soc_opp_out; /* * Each OPP is a set of tuples consisting of frequency and * voltage like <freq-kHz vol-uV>. */ nr = prop->length / sizeof(u32); if (nr % 2 || (nr / 2) < num) goto soc_opp_out; for (j = 0; j < num; j++) { val = prop->value; for (i = 0; i < nr / 2; i++) { unsigned long freq = be32_to_cpup(val++); unsigned long volt = be32_to_cpup(val++); if (freq_table[j].frequency == freq) { imx6_soc_volt[soc_opp_count++] = volt; break; } } } soc_opp_out: /* use fixed soc opp volt if no valid soc opp info found in dtb */ if (soc_opp_count != num) { dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n"); for (j = 0; j < num; j++) imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL; if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ) imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH; } if (of_property_read_u32(np, "clock-latency", &transition_latency)) transition_latency = CPUFREQ_ETERNAL; /* * Calculate the ramp time for max voltage change in the * VDDSOC and VDDPU regulators. */ ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]); if (ret > 0) transition_latency += ret * 1000; if (!IS_ERR(pu_reg)) { ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]); if (ret > 0) transition_latency += ret * 1000; } /* * OPP is maintained in order of increasing frequency, and * freq_table initialised from OPP is therefore sorted in the * same order. */ rcu_read_lock(); opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[0].frequency * 1000, true); min_volt = dev_pm_opp_get_voltage(opp); opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[--num].frequency * 1000, true); max_volt = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt); if (ret > 0) transition_latency += ret * 1000; ret = cpufreq_register_driver(&imx6q_cpufreq_driver); if (ret) { dev_err(cpu_dev, "failed register driver: %d\n", ret); goto free_freq_table; } of_node_put(np); return 0; free_freq_table: dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); out_free_opp: if (free_opp) dev_pm_opp_of_remove_table(cpu_dev); put_reg: if (!IS_ERR(arm_reg)) regulator_put(arm_reg); if (!IS_ERR(pu_reg)) regulator_put(pu_reg); if (!IS_ERR(soc_reg)) regulator_put(soc_reg); put_clk: if (!IS_ERR(arm_clk)) clk_put(arm_clk); if (!IS_ERR(pll1_sys_clk)) clk_put(pll1_sys_clk); if (!IS_ERR(pll1_sw_clk)) clk_put(pll1_sw_clk); if (!IS_ERR(step_clk)) clk_put(step_clk); if (!IS_ERR(pll2_pfd2_396m_clk)) clk_put(pll2_pfd2_396m_clk); of_node_put(np); return ret; }
static int allocate_resources(int cpu, struct device **cdev, struct regulator **creg, struct clk **cclk) { struct device *cpu_dev; struct regulator *cpu_reg; struct clk *cpu_clk; int ret = 0; char *reg_cpu0 = "cpu0", *reg_cpu = "cpu", *reg; cpu_dev = get_cpu_device(cpu); if (!cpu_dev) { pr_err("failed to get cpu%d device\n", cpu); return -ENODEV; } /* Try "cpu0" for older DTs */ if (!cpu) reg = reg_cpu0; else reg = reg_cpu; try_again: cpu_reg = regulator_get_optional(cpu_dev, reg); if (IS_ERR(cpu_reg)) { /* * If cpu's regulator supply node is present, but regulator is * not yet registered, we should try defering probe. */ if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { dev_dbg(cpu_dev, "cpu%d regulator not ready, retry\n", cpu); return -EPROBE_DEFER; } /* Try with "cpu-supply" */ if (reg == reg_cpu0) { reg = reg_cpu; goto try_again; } dev_dbg(cpu_dev, "no regulator for cpu%d: %ld\n", cpu, PTR_ERR(cpu_reg)); } cpu_clk = clk_get(cpu_dev, NULL); if (IS_ERR(cpu_clk)) { /* put regulator */ if (!IS_ERR(cpu_reg)) regulator_put(cpu_reg); ret = PTR_ERR(cpu_clk); /* * If cpu's clk node is present, but clock is not yet * registered, we should try defering probe. */ if (ret == -EPROBE_DEFER) dev_dbg(cpu_dev, "cpu%d clock not ready, retry\n", cpu); else dev_err(cpu_dev, "failed to get cpu%d clock: %d\n", ret, cpu); } else { *cdev = cpu_dev; *creg = cpu_reg; *cclk = cpu_clk; } return ret; }