lkml.org 
[lkml]   [2020]   [Dec]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 13/48] opp: Add resource-managed versions of OPP API functions
    Date
    Add resource-managed versions of OPP API functions. This removes a need
    from drivers to store and manage OPP table pointers.

    Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
    ---
    drivers/opp/core.c | 173 +++++++++++++++++++++++++++++++++++++++++
    drivers/opp/of.c | 25 ++++++
    include/linux/pm_opp.h | 51 ++++++++++++
    3 files changed, 249 insertions(+)

    diff --git a/drivers/opp/core.c b/drivers/opp/core.c
    index 4774701ec82d..d9feb7639598 100644
    --- a/drivers/opp/core.c
    +++ b/drivers/opp/core.c
    @@ -2664,3 +2664,176 @@ int dev_pm_opp_set_voltage(struct device *dev, struct dev_pm_opp *opp)
    return ret;
    }
    EXPORT_SYMBOL_GPL(dev_pm_opp_set_voltage);
    +
    +/**
    + * devm_pm_opp_get_opp_table() - Get OPP table of a device
    + * @dev: device for which we do this operation
    + *
    + * This is a resource-managed version of dev_pm_opp_get_opp_table().
    + *
    + * Return: pointer to 'struct opp_table' if found and -ENODEV otherwise.
    + */
    +struct opp_table *devm_pm_opp_get_opp_table(struct device *dev)
    +{
    + struct opp_table *opp_table;
    + int err;
    +
    + opp_table = dev_pm_opp_get_opp_table(dev);
    + if (IS_ERR(opp_table))
    + return opp_table;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_put_opp_table,
    + opp_table);
    + if (err)
    + return ERR_PTR(err);
    +
    + return opp_table;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_get_opp_table);
    +
    +/**
    + * devm_pm_opp_set_regulators() - Set regulator names for the device
    + * @dev: Device for which regulator name is being set.
    + * @names: Array of pointers to the names of the regulator.
    + * @count: Number of regulators.
    + *
    + * This is a resource-managed version of dev_pm_opp_set_regulators().
    + *
    + * Return: pointer to 'struct opp_table' on success and errorno otherwise.
    + */
    +struct opp_table *
    +devm_pm_opp_set_regulators(struct device *dev, const char * const names[],
    + unsigned int count)
    +{
    + struct opp_table *opp_table;
    + int err;
    +
    + opp_table = dev_pm_opp_set_regulators(dev, names, count);
    + if (IS_ERR(opp_table))
    + return opp_table;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_put_regulators,
    + opp_table);
    + if (err)
    + return ERR_PTR(err);
    +
    + return opp_table;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_set_regulators);
    +
    +/**
    + * devm_pm_opp_set_supported_hw() - Set supported platforms
    + * @dev: Device for which supported-hw has to be set.
    + * @versions: Array of hierarchy of versions to match.
    + * @count: Number of elements in the array.
    + *
    + * This is a resource-managed version of dev_pm_opp_set_supported_hw().
    + *
    + * Return: pointer to 'struct opp_table' on success and errorno otherwise.
    + */
    +struct opp_table *
    +devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
    + unsigned int count)
    +{
    + struct opp_table *opp_table;
    + int err;
    +
    + opp_table = dev_pm_opp_set_supported_hw(dev, versions, count);
    + if (IS_ERR(opp_table))
    + return opp_table;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_put_supported_hw,
    + opp_table);
    + if (err)
    + return ERR_PTR(err);
    +
    + return opp_table;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_set_supported_hw);
    +
    +/**
    + * devm_pm_opp_set_clkname() - Set clk name for the device
    + * @dev: Device for which clk name is being set.
    + * @name: Clk name.
    + *
    + * This is a resource-managed version of dev_pm_opp_set_clkname().
    + *
    + * Return: pointer to 'struct opp_table' on success and errorno otherwise.
    + */
    +struct opp_table *
    +devm_pm_opp_set_clkname(struct device *dev, const char *name)
    +{
    + struct opp_table *opp_table;
    + int err;
    +
    + opp_table = dev_pm_opp_set_clkname(dev, name);
    + if (IS_ERR(opp_table))
    + return opp_table;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_put_clkname,
    + opp_table);
    + if (err)
    + return ERR_PTR(err);
    +
    + return opp_table;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_set_clkname);
    +
    +/**
    + * devm_pm_opp_register_set_opp_helper() - Register custom set OPP helper
    + * @dev: Device for which the helper is getting registered.
    + * @set_opp: Custom set OPP helper.
    + *
    + * This is a resource-managed version of dev_pm_opp_register_set_opp_helper().
    + *
    + * Return: pointer to 'struct opp_table' on success and errorno otherwise.
    + */
    +struct opp_table *
    +devm_pm_opp_register_set_opp_helper(struct device *dev,
    + int (*set_opp)(struct dev_pm_set_opp_data *data))
    +{
    + struct opp_table *opp_table;
    + int err;
    +
    + opp_table = dev_pm_opp_register_set_opp_helper(dev, set_opp);
    + if (IS_ERR(opp_table))
    + return opp_table;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_unregister_set_opp_helper,
    + opp_table);
    + if (err)
    + return ERR_PTR(err);
    +
    + return opp_table;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_register_set_opp_helper);
    +
    +/**
    + * devm_pm_opp_attach_genpd - Attach genpd(s) for the device and save virtual device pointer
    + * @dev: Consumer device for which the genpd is getting attached.
    + * @names: Null terminated array of pointers containing names of genpd to attach.
    + * @virt_devs: Pointer to return the array of virtual devices.
    + *
    + * This is a resource-managed version of dev_pm_opp_attach_genpd().
    + *
    + * Return: pointer to 'struct opp_table' on success and errorno otherwise.
    + */
    +struct opp_table *
    +devm_pm_opp_attach_genpd(struct device *dev, const char **names,
    + struct device ***virt_devs)
    +{
    + struct opp_table *opp_table;
    + int err;
    +
    + opp_table = dev_pm_opp_attach_genpd(dev, names, virt_devs);
    + if (IS_ERR(opp_table))
    + return opp_table;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_detach_genpd,
    + opp_table);
    + if (err)
    + return ERR_PTR(err);
    +
    + return opp_table;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_attach_genpd);
    diff --git a/drivers/opp/of.c b/drivers/opp/of.c
    index 03cb387236c4..3b5a4c8bc62f 100644
    --- a/drivers/opp/of.c
    +++ b/drivers/opp/of.c
    @@ -1350,3 +1350,28 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus)
    return ret;
    }
    EXPORT_SYMBOL_GPL(dev_pm_opp_of_register_em);
    +
    +/**
    + * devm_pm_opp_of_add_table() - Initialize opp table from device tree
    + * @dev: device pointer used to lookup OPP table.
    + *
    + * This is a resource-managed version of dev_pm_opp_of_add_table().
    + *
    + * Return: 0 on success and errorno otherwise.
    + */
    +int devm_pm_opp_of_add_table(struct device *dev)
    +{
    + int err;
    +
    + err = dev_pm_opp_of_add_table(dev);
    + if (err)
    + return err;
    +
    + err = devm_add_action_or_reset(dev, (void *)dev_pm_opp_remove_table,
    + dev);
    + if (err)
    + return err;
    +
    + return 0;
    +}
    +EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table);
    diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
    index 0298b426fba3..0d42fbda0134 100644
    --- a/include/linux/pm_opp.h
    +++ b/include/linux/pm_opp.h
    @@ -163,6 +163,12 @@ void dev_pm_opp_remove_table(struct device *dev);
    void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
    int dev_pm_opp_sync_regulators(struct device *dev);
    int dev_pm_opp_set_voltage(struct device *dev, struct dev_pm_opp *opp);
    +struct opp_table *devm_pm_opp_get_opp_table(struct device *dev);
    +struct opp_table *devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
    +struct opp_table *devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
    +struct opp_table *devm_pm_opp_set_clkname(struct device *dev, const char *name);
    +struct opp_table *devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
    +struct opp_table *devm_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
    #else
    static inline struct opp_table *dev_pm_opp_get_opp_table(struct device *dev)
    {
    @@ -396,9 +402,49 @@ static inline int dev_pm_opp_set_voltage(struct device *dev, struct dev_pm_opp *
    return -ENOTSUPP;
    }

    +static inline struct opp_table *devm_pm_opp_get_opp_table(struct device *dev)
    +{
    + return ERR_PTR(-ENOTSUPP);
    +}
    +
    +static inline struct opp_table *
    +devm_pm_opp_set_regulators(struct device *dev, const char * const names[],
    + unsigned int count)
    +{
    + return ERR_PTR(-ENOTSUPP);
    +}
    +
    +static inline struct opp_table *
    +devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
    + unsigned int count)
    +{
    + return ERR_PTR(-ENOTSUPP);
    +}
    +
    +static inline struct opp_table *
    +devm_pm_opp_set_clkname(struct device *dev, const char *name)
    +{
    + return ERR_PTR(-ENOTSUPP);
    +}
    +
    +static inline struct opp_table *
    +devm_pm_opp_register_set_opp_helper(struct device *dev,
    + int (*set_opp)(struct dev_pm_set_opp_data *data))
    +{
    + return ERR_PTR(-ENOTSUPP);
    +}
    +
    +static inline struct opp_table *
    +devm_pm_opp_attach_genpd(struct device *dev, const char **names,
    + struct device ***virt_devs)
    +{
    + return ERR_PTR(-ENOTSUPP);
    +}
    +
    #endif /* CONFIG_PM_OPP */

    #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
    +int devm_pm_opp_of_add_table(struct device *dev);
    int dev_pm_opp_of_add_table(struct device *dev);
    int dev_pm_opp_of_add_table_indexed(struct device *dev, int index);
    void dev_pm_opp_of_remove_table(struct device *dev);
    @@ -472,6 +518,11 @@ static inline int dev_pm_opp_of_find_icc_paths(struct device *dev, struct opp_ta
    {
    return -ENOTSUPP;
    }
    +
    +static inline int devm_pm_opp_of_add_table(struct device *dev)
    +{
    + return -ENOTSUPP;
    +}
    #endif

    #endif /* __LINUX_OPP_H__ */
    --
    2.29.2
    \
     
     \ /
      Last update: 2020-12-17 19:40    [W:4.366 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site