History

Merge branch 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm

Pull operating performance points (OPP) framework changes for v5.3 from Viresh Kumar: "This pull request contains: - OPP core changes to support a wider range of devices, like IO devices (Rajendra Nayak and Stehpen Boyd). - Fixes around genpd_virt_devs (Viresh Kumar). - Fix for platform with set_opp() callback (Dmitry Osipenko)." * 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: opp: Don't use IS_ERR on invalid supplies opp: Make dev_pm_opp_set_rate() handle freq = 0 to drop performance votes opp: Don't overwrite rounded clk rate opp: Allocate genpd_virt_devs from dev_pm_opp_attach_genpd() opp: Attach genpds to devices from within OPP core

Rafael J. Wysocki committed 7 years ago

Commit 41de2562 parents 4b972a0 560d1bc3 files · +121 −91Browse files

Unified · Split

3 files
  1. drivers/opp/core.c +115 −59
  2. drivers/opp/of.c +2 −28
  3. include/linux/pm_opp.h +4 −4
drivers/opp/core.c+115−59
@@ -682,7 +682,7 @@ static int _set_opp_custom(const struct opp_table *opp_table, · 681 unmodified lines
682682
683683 data->old_opp.rate = old_freq;
684684 size = sizeof(*old_supply) * opp_table->regulator_count;
685− if (IS_ERR(old_supply))
685+ if (!old_supply)
686686 memset(data->old_opp.supplies, 0, size);
687687 else
688688 memcpy(data->old_opp.supplies, old_supply, size);
@@ -708,7 +708,7 @@ static int _set_required_opps(struct device *dev, · 19 unmodified lines
708708
709709 /* Single genpd case */
710710 if (!genpd_virt_devs) {
711− pstate = opp->required_opps[0]->pstate;
711+ pstate = likely(opp) ? opp->required_opps[0]->pstate : 0;
712712 ret = dev_pm_genpd_set_performance_state(dev, pstate);
713713 if (ret) {
714714 dev_err(dev, "Failed to set performance state of %s: %d (%d)\n",
@@ -726,7 +726,7 @@ static int _set_required_opps(struct device *dev, · 11 unmodified lines
726726 mutex_lock(&opp_table->genpd_virt_dev_lock);
727727
728728 for (i = 0; i < opp_table->required_opp_count; i++) {
729− pstate = opp->required_opps[i]->pstate;
729+ pstate = likely(opp) ? opp->required_opps[i]->pstate : 0;
730730
731731 if (!genpd_virt_devs[i])
732732 continue;
@@ -748,29 +748,37 @@ static int _set_required_opps(struct device *dev, · 15 unmodified lines
748748 * @dev: device for which we do this operation
749749 * @target_freq: frequency to achieve
750750 *
751− * This configures the power-supplies and clock source to the levels specified
752− * by the OPP corresponding to the target_freq.
751+ * This configures the power-supplies to the levels specified by the OPP
752+ * corresponding to the target_freq, and programs the clock to a value <=
753+ * target_freq, as rounded by clk_round_rate(). Device wanting to run at fmax
754+ * provided by the opp, should have already rounded to the target OPP's
755+ * frequency.
753756 */
754757 int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
755758 {
756759 struct opp_table *opp_table;
757− unsigned long freq, old_freq;
760+ unsigned long freq, old_freq, temp_freq;
758761 struct dev_pm_opp *old_opp, *opp;
759762 struct clk *clk;
760763 int ret;
761764
762− if (unlikely(!target_freq)) {
763− dev_err(dev, "%s: Invalid target frequency %lu\n", __func__,
764− target_freq);
765− return -EINVAL;
766− }
767−
768765 opp_table = _find_opp_table(dev);
769766 if (IS_ERR(opp_table)) {
770767 dev_err(dev, "%s: device opp doesn't exist\n", __func__);
771768 return PTR_ERR(opp_table);
772769 }
773770
771+ if (unlikely(!target_freq)) {
772+ if (opp_table->required_opp_tables) {
773+ ret = _set_required_opps(dev, opp_table, NULL);
774+ } else {
775+ dev_err(dev, "target frequency can't be 0\n");
776+ ret = -EINVAL;
777+ }
778+
779+ goto put_opp_table;
780+ }
781+
774782 clk = opp_table->clk;
775783 if (IS_ERR(clk)) {
776784 dev_err(dev, "%s: No clock available for the device\n",
@@ -793,13 +801,15 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) · 16 unmodified lines
793801 goto put_opp_table;
794802 }
795803
796− old_opp = _find_freq_ceil(opp_table, &old_freq);
804+ temp_freq = old_freq;
805+ old_opp = _find_freq_ceil(opp_table, &temp_freq);
797806 if (IS_ERR(old_opp)) {
798807 dev_err(dev, "%s: failed to find current OPP for freq %lu (%ld)\n",
799808 __func__, old_freq, PTR_ERR(old_opp));
800809 }
801810
802− opp = _find_freq_ceil(opp_table, &freq);
811+ temp_freq = freq;
812+ opp = _find_freq_ceil(opp_table, &temp_freq);
803813 if (IS_ERR(opp)) {
804814 ret = PTR_ERR(opp);
805815 dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n",
@@ -1741,91 +1751,137 @@ void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) · 935 unmodified lines
17411751 }
17421752 EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);
17431753
1754+static void _opp_detach_genpd(struct opp_table *opp_table)
1755+{
1756+ int index;
1757+
1758+ for (index = 0; index < opp_table->required_opp_count; index++) {
1759+ if (!opp_table->genpd_virt_devs[index])
1760+ continue;
1761+
1762+ dev_pm_domain_detach(opp_table->genpd_virt_devs[index], false);
1763+ opp_table->genpd_virt_devs[index] = NULL;
1764+ }
1765+
1766+ kfree(opp_table->genpd_virt_devs);
1767+ opp_table->genpd_virt_devs = NULL;
1768+}
1769+
17441770 /**
1745− * dev_pm_opp_set_genpd_virt_dev - Set virtual genpd device for an index
1746− * @dev: Consumer device for which the genpd device is getting set.
1747− * @virt_dev: virtual genpd device.
1748− * @index: index.
1771+ * dev_pm_opp_attach_genpd - Attach genpd(s) for the device and save virtual device pointer
1772+ * @dev: Consumer device for which the genpd is getting attached.
1773+ * @names: Null terminated array of pointers containing names of genpd to attach.
17491774 *
17501775 * Multiple generic power domains for a device are supported with the help of
17511776 * virtual genpd devices, which are created for each consumer device - genpd
17521777 * pair. These are the device structures which are attached to the power domain
17531778 * and are required by the OPP core to set the performance state of the genpd.
1779+ * The same API also works for the case where single genpd is available and so
1780+ * we don't need to support that separately.
17541781 *
17551782 * This helper will normally be called by the consumer driver of the device
1756− * "dev", as only that has details of the genpd devices.
1783+ * "dev", as only that has details of the genpd names.
17571784 *
1758− * This helper needs to be called once for each of those virtual devices, but
1759− * only if multiple domains are available for a device. Otherwise the original
1760− * device structure will be used instead by the OPP core.
1785+ * This helper needs to be called once with a list of all genpd to attach.
1786+ * Otherwise the original device structure will be used instead by the OPP core.
17611787 */
1762−struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev,
1763− struct device *virt_dev,
1764− int index)
1788+struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names)
17651789 {
17661790 struct opp_table *opp_table;
1791+ struct device *virt_dev;
1792+ int index, ret = -EINVAL;
1793+ const char **name = names;
17671794
17681795 opp_table = dev_pm_opp_get_opp_table(dev);
17691796 if (!opp_table)
17701797 return ERR_PTR(-ENOMEM);
17711798
1799+ /*
1800+ * If the genpd's OPP table isn't already initialized, parsing of the
1801+ * required-opps fail for dev. We should retry this after genpd's OPP
1802+ * table is added.
1803+ */
1804+ if (!opp_table->required_opp_count) {
1805+ ret = -EPROBE_DEFER;
1806+ goto put_table;
1807+ }
1808+
17721809 mutex_lock(&opp_table->genpd_virt_dev_lock);
17731810
1774− if (unlikely(!opp_table->genpd_virt_devs ||
1775− index >= opp_table->required_opp_count ||
1776− opp_table->genpd_virt_devs[index])) {
1811+ opp_table->genpd_virt_devs = kcalloc(opp_table->required_opp_count,
1812+ sizeof(*opp_table->genpd_virt_devs),
1813+ GFP_KERNEL);
1814+ if (!opp_table->genpd_virt_devs)
1815+ goto unlock;
17771816
1778− dev_err(dev, "Invalid request to set required device\n");
1779− dev_pm_opp_put_opp_table(opp_table);
1780− mutex_unlock(&opp_table->genpd_virt_dev_lock);
1817+ while (*name) {
1818+ index = of_property_match_string(dev->of_node,
1819+ "power-domain-names", *name);
1820+ if (index < 0) {
1821+ dev_err(dev, "Failed to find power domain: %s (%d)\n",
1822+ *name, index);
1823+ goto err;
1824+ }
17811825
1782− return ERR_PTR(-EINVAL);
1826+ if (index >= opp_table->required_opp_count) {
1827+ dev_err(dev, "Index can't be greater than required-opp-count - 1, %s (%d : %d)\n",
1828+ *name, opp_table->required_opp_count, index);
1829+ goto err;
1830+ }
1831+
1832+ if (opp_table->genpd_virt_devs[index]) {
1833+ dev_err(dev, "Genpd virtual device already set %s\n",
1834+ *name);
1835+ goto err;
1836+ }
1837+
1838+ virt_dev = dev_pm_domain_attach_by_name(dev, *name);
1839+ if (IS_ERR(virt_dev)) {
1840+ ret = PTR_ERR(virt_dev);
1841+ dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
1842+ goto err;
1843+ }
1844+
1845+ opp_table->genpd_virt_devs[index] = virt_dev;
1846+ name++;
17831847 }
17841848
1785− opp_table->genpd_virt_devs[index] = virt_dev;
17861849 mutex_unlock(&opp_table->genpd_virt_dev_lock);
17871850
17881851 return opp_table;
1852+
1853+err:
1854+ _opp_detach_genpd(opp_table);
1855+unlock:
1856+ mutex_unlock(&opp_table->genpd_virt_dev_lock);
1857+
1858+put_table:
1859+ dev_pm_opp_put_opp_table(opp_table);
1860+
1861+ return ERR_PTR(ret);
17891862 }
1863+EXPORT_SYMBOL_GPL(dev_pm_opp_attach_genpd);
17901864
17911865 /**
1792− * dev_pm_opp_put_genpd_virt_dev() - Releases resources blocked for genpd device.
1793− * @opp_table: OPP table returned by dev_pm_opp_set_genpd_virt_dev().
1794− * @virt_dev: virtual genpd device.
1866+ * dev_pm_opp_detach_genpd() - Detach genpd(s) from the device.
1867+ * @opp_table: OPP table returned by dev_pm_opp_attach_genpd().
17951868 *
1796− * This releases the resource previously acquired with a call to
1797− * dev_pm_opp_set_genpd_virt_dev(). The consumer driver shall call this helper
1798− * if it doesn't want OPP core to update performance state of a power domain
1799− * anymore.
1869+ * This detaches the genpd(s), resets the virtual device pointers, and puts the
1870+ * OPP table.
18001871 */
1801−void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table,
1802− struct device *virt_dev)
1872+void dev_pm_opp_detach_genpd(struct opp_table *opp_table)
18031873 {
1804− int i;
1805−
18061874 /*
18071875 * Acquire genpd_virt_dev_lock to make sure virt_dev isn't getting
18081876 * used in parallel.
18091877 */
18101878 mutex_lock(&opp_table->genpd_virt_dev_lock);
1811−
1812− for (i = 0; i < opp_table->required_opp_count; i++) {
1813− if (opp_table->genpd_virt_devs[i] != virt_dev)
1814− continue;
1815−
1816− opp_table->genpd_virt_devs[i] = NULL;
1817− dev_pm_opp_put_opp_table(opp_table);
1818−
1819− /* Drop the vote */
1820− dev_pm_genpd_set_performance_state(virt_dev, 0);
1821− break;
1822− }
1823−
1879+ _opp_detach_genpd(opp_table);
18241880 mutex_unlock(&opp_table->genpd_virt_dev_lock);
18251881
1826− if (unlikely(i == opp_table->required_opp_count))
1827− dev_err(virt_dev, "Failed to find required device entry\n");
1882+ dev_pm_opp_put_opp_table(opp_table);
18281883 }
1884+EXPORT_SYMBOL_GPL(dev_pm_opp_detach_genpd);
18291885
18301886 /**
18311887 * dev_pm_opp_xlate_performance_state() - Find required OPP's pstate for src_table.
drivers/opp/of.c+2−28
@@ -138,7 +138,6 @@ err: · 137 unmodified lines
138138 static void _opp_table_free_required_tables(struct opp_table *opp_table)
139139 {
140140 struct opp_table **required_opp_tables = opp_table->required_opp_tables;
141− struct device **genpd_virt_devs = opp_table->genpd_virt_devs;
142141 int i;
143142
144143 if (!required_opp_tables)
@@ -152,10 +151,8 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table) · 7 unmodified lines
152151 }
153152
154153 kfree(required_opp_tables);
155− kfree(genpd_virt_devs);
156154
157155 opp_table->required_opp_count = 0;
158− opp_table->genpd_virt_devs = NULL;
159156 opp_table->required_opp_tables = NULL;
160157 }
161158
@@ -168,9 +165,8 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, · 6 unmodified lines
168165 struct device_node *opp_np)
169166 {
170167 struct opp_table **required_opp_tables;
171− struct device **genpd_virt_devs = NULL;
172168 struct device_node *required_np, *np;
173− int count, count_pd, i;
169+ int count, i;
174170
175171 /* Traversing the first OPP node is all we need */
176172 np = of_get_next_available_child(opp_np, NULL);
@@ -183,33 +179,11 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, · 6 unmodified lines
183179 if (!count)
184180 goto put_np;
185181
186− /*
187− * Check the number of power-domains to know if we need to deal
188− * with virtual devices. In some cases we have devices with multiple
189− * power domains but with only one of them being scalable, hence
190− * 'count' could be 1, but we still have to deal with multiple genpds
191− * and virtual devices.
192− */
193− count_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
194− "#power-domain-cells");
195− if (!count_pd)
196− goto put_np;
197−
198− if (count_pd > 1) {
199− genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs),
200− GFP_KERNEL);
201− if (!genpd_virt_devs)
202− goto put_np;
203− }
204−
205182 required_opp_tables = kcalloc(count, sizeof(*required_opp_tables),
206183 GFP_KERNEL);
207− if (!required_opp_tables) {
208− kfree(genpd_virt_devs);
184+ if (!required_opp_tables)
209185 goto put_np;
210− }
211186
212− opp_table->genpd_virt_devs = genpd_virt_devs;
213187 opp_table->required_opp_tables = required_opp_tables;
214188 opp_table->required_opp_count = count;
215189
include/linux/pm_opp.h+4−4
@@ -128,8 +128,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name); · 127 unmodified lines
128128 void dev_pm_opp_put_clkname(struct opp_table *opp_table);
129129 struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
130130 void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
131−struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev, struct device *virt_dev, int index);
132−void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table, struct device *virt_dev);
131+struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names);
132+void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
133133 int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
134134 int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
135135 int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
@@ -292,12 +292,12 @@ static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const · 156 unmodified lines
292292
293293 static inline void dev_pm_opp_put_clkname(struct opp_table *opp_table) {}
294294
295−static inline struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev, struct device *virt_dev, int index)
295+static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names)
296296 {
297297 return ERR_PTR(-ENOTSUPP);
298298 }
299299
300−static inline void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table, struct device *virt_dev) {}
300+static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {}
301301
302302 static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate)
303303 {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t