10.11.2020 23:50, Thierry Reding пишет: > On Thu, Nov 05, 2020 at 02:44:15AM +0300, Dmitry Osipenko wrote: > [...] >> +static void tegra_pwm_deinit_opp_table(void *data) >> +{ >> + struct device *dev = data; >> + struct opp_table *opp_table; >> + >> + opp_table = dev_pm_opp_get_opp_table(dev); >> + dev_pm_opp_of_remove_table(dev); >> + dev_pm_opp_put_regulators(opp_table); >> + dev_pm_opp_put_opp_table(opp_table); >> +} >> + >> +static int devm_tegra_pwm_init_opp_table(struct device *dev) >> +{ >> + struct opp_table *opp_table; >> + const char *rname = "core"; >> + int err; >> + >> + /* voltage scaling is optional */ >> + if (device_property_present(dev, "core-supply")) >> + opp_table = dev_pm_opp_set_regulators(dev, &rname, 1); >> + else >> + opp_table = dev_pm_opp_get_opp_table(dev); >> + >> + if (IS_ERR(opp_table)) >> + return dev_err_probe(dev, PTR_ERR(opp_table), >> + "failed to prepare OPP table\n"); >> + >> + /* >> + * OPP table presence is optional and we want the set_rate() of OPP >> + * API to work similarly to clk_set_rate() if table is missing in a >> + * device-tree. The add_table() errors out if OPP is missing in DT. >> + */ >> + if (device_property_present(dev, "operating-points-v2")) { >> + err = dev_pm_opp_of_add_table(dev); >> + if (err) { >> + dev_err(dev, "failed to add OPP table: %d\n", err); >> + goto put_table; >> + } >> + } >> + >> + err = devm_add_action(dev, tegra_pwm_deinit_opp_table, dev); >> + if (err) >> + goto remove_table; >> + >> + return 0; >> + >> +remove_table: >> + dev_pm_opp_of_remove_table(dev); >> +put_table: >> + dev_pm_opp_put_regulators(opp_table); >> + >> + return err; >> +} > > These two functions seem to be heavily boilerplate across all these > drivers. Have you considered splitting these out into separate helpers? The helper is already prepared for v2.