core.c (82045dd85566d87128dcc66277cf1177d9930a4a) | core.c (6319aee10e530315689db7609a7d4c444124ff22) |
---|---|
1/* 2 * Generic OPP Interface 3 * 4 * Copyright (C) 2009-2010 Texas Instruments Incorporated. 5 * Nishanth Menon 6 * Romit Dasgupta 7 * Kevin Hilman 8 * --- 1730 unchanged lines hidden (view full) --- 1739 /* Make sure there are no concurrent readers while updating opp_table */ 1740 WARN_ON(!list_empty(&opp_table->opp_list)); 1741 1742 opp_table->set_opp = NULL; 1743 dev_pm_opp_put_opp_table(opp_table); 1744} 1745EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper); 1746 | 1/* 2 * Generic OPP Interface 3 * 4 * Copyright (C) 2009-2010 Texas Instruments Incorporated. 5 * Nishanth Menon 6 * Romit Dasgupta 7 * Kevin Hilman 8 * --- 1730 unchanged lines hidden (view full) --- 1739 /* Make sure there are no concurrent readers while updating opp_table */ 1740 WARN_ON(!list_empty(&opp_table->opp_list)); 1741 1742 opp_table->set_opp = NULL; 1743 dev_pm_opp_put_opp_table(opp_table); 1744} 1745EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper); 1746 |
1747static void _opp_detach_genpd(struct opp_table *opp_table) 1748{ 1749 int index; 1750 1751 for (index = 0; index < opp_table->required_opp_count; index++) { 1752 if (!opp_table->genpd_virt_devs[index]) 1753 continue; 1754 1755 dev_pm_domain_detach(opp_table->genpd_virt_devs[index], false); 1756 opp_table->genpd_virt_devs[index] = NULL; 1757 } 1758} 1759 |
|
1747/** | 1760/** |
1748 * dev_pm_opp_set_genpd_virt_dev - Set virtual genpd device for an index 1749 * @dev: Consumer device for which the genpd device is getting set. 1750 * @virt_dev: virtual genpd device. 1751 * @index: index. | 1761 * dev_pm_opp_attach_genpd - Attach genpd(s) for the device and save virtual device pointer 1762 * @dev: Consumer device for which the genpd is getting attached. 1763 * @names: Null terminated array of pointers containing names of genpd to attach. |
1752 * 1753 * Multiple generic power domains for a device are supported with the help of 1754 * virtual genpd devices, which are created for each consumer device - genpd 1755 * pair. These are the device structures which are attached to the power domain 1756 * and are required by the OPP core to set the performance state of the genpd. | 1764 * 1765 * Multiple generic power domains for a device are supported with the help of 1766 * virtual genpd devices, which are created for each consumer device - genpd 1767 * pair. These are the device structures which are attached to the power domain 1768 * and are required by the OPP core to set the performance state of the genpd. |
1769 * The same API also works for the case where single genpd is available and so 1770 * we don't need to support that separately. |
|
1757 * 1758 * This helper will normally be called by the consumer driver of the device | 1771 * 1772 * This helper will normally be called by the consumer driver of the device |
1759 * "dev", as only that has details of the genpd devices. | 1773 * "dev", as only that has details of the genpd names. |
1760 * | 1774 * |
1761 * This helper needs to be called once for each of those virtual devices, but 1762 * only if multiple domains are available for a device. Otherwise the original 1763 * device structure will be used instead by the OPP core. | 1775 * This helper needs to be called once with a list of all genpd to attach. 1776 * Otherwise the original device structure will be used instead by the OPP core. |
1764 */ | 1777 */ |
1765struct opp_table *dev_pm_opp_set_genpd_virt_dev(struct device *dev, 1766 struct device *virt_dev, 1767 int index) | 1778struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names) |
1768{ 1769 struct opp_table *opp_table; | 1779{ 1780 struct opp_table *opp_table; |
1781 struct device *virt_dev; 1782 int index, ret = -EINVAL; 1783 const char **name = names; |
|
1770 1771 opp_table = dev_pm_opp_get_opp_table(dev); 1772 if (!opp_table) 1773 return ERR_PTR(-ENOMEM); 1774 | 1784 1785 opp_table = dev_pm_opp_get_opp_table(dev); 1786 if (!opp_table) 1787 return ERR_PTR(-ENOMEM); 1788 |
1789 /* 1790 * If the genpd's OPP table isn't already initialized, parsing of the 1791 * required-opps fail for dev. We should retry this after genpd's OPP 1792 * table is added. 1793 */ 1794 if (!opp_table->required_opp_count) { 1795 ret = -EPROBE_DEFER; 1796 goto put_table; 1797 } 1798 |
|
1775 mutex_lock(&opp_table->genpd_virt_dev_lock); 1776 | 1799 mutex_lock(&opp_table->genpd_virt_dev_lock); 1800 |
1777 if (unlikely(!opp_table->genpd_virt_devs || 1778 index >= opp_table->required_opp_count || 1779 opp_table->genpd_virt_devs[index])) { | 1801 while (*name) { 1802 index = of_property_match_string(dev->of_node, 1803 "power-domain-names", *name); 1804 if (index < 0) { 1805 dev_err(dev, "Failed to find power domain: %s (%d)\n", 1806 *name, index); 1807 goto err; 1808 } |
1780 | 1809 |
1781 dev_err(dev, "Invalid request to set required device\n"); 1782 dev_pm_opp_put_opp_table(opp_table); 1783 mutex_unlock(&opp_table->genpd_virt_dev_lock); | 1810 if (index >= opp_table->required_opp_count) { 1811 dev_err(dev, "Index can't be greater than required-opp-count - 1, %s (%d : %d)\n", 1812 *name, opp_table->required_opp_count, index); 1813 goto err; 1814 } |
1784 | 1815 |
1785 return ERR_PTR(-EINVAL); | 1816 if (opp_table->genpd_virt_devs[index]) { 1817 dev_err(dev, "Genpd virtual device already set %s\n", 1818 *name); 1819 goto err; 1820 } 1821 1822 virt_dev = dev_pm_domain_attach_by_name(dev, *name); 1823 if (IS_ERR(virt_dev)) { 1824 ret = PTR_ERR(virt_dev); 1825 dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret); 1826 goto err; 1827 } 1828 1829 opp_table->genpd_virt_devs[index] = virt_dev; 1830 name++; |
1786 } 1787 | 1831 } 1832 |
1788 opp_table->genpd_virt_devs[index] = virt_dev; | |
1789 mutex_unlock(&opp_table->genpd_virt_dev_lock); 1790 1791 return opp_table; | 1833 mutex_unlock(&opp_table->genpd_virt_dev_lock); 1834 1835 return opp_table; |
1836 1837err: 1838 _opp_detach_genpd(opp_table); 1839 mutex_unlock(&opp_table->genpd_virt_dev_lock); 1840 1841put_table: 1842 dev_pm_opp_put_opp_table(opp_table); 1843 1844 return ERR_PTR(ret); |
|
1792} | 1845} |
1846EXPORT_SYMBOL_GPL(dev_pm_opp_attach_genpd); |
|
1793 1794/** | 1847 1848/** |
1795 * dev_pm_opp_put_genpd_virt_dev() - Releases resources blocked for genpd device. 1796 * @opp_table: OPP table returned by dev_pm_opp_set_genpd_virt_dev(). 1797 * @virt_dev: virtual genpd device. | 1849 * dev_pm_opp_detach_genpd() - Detach genpd(s) from the device. 1850 * @opp_table: OPP table returned by dev_pm_opp_attach_genpd(). |
1798 * | 1851 * |
1799 * This releases the resource previously acquired with a call to 1800 * dev_pm_opp_set_genpd_virt_dev(). The consumer driver shall call this helper 1801 * if it doesn't want OPP core to update performance state of a power domain 1802 * anymore. | 1852 * This detaches the genpd(s), resets the virtual device pointers, and puts the 1853 * OPP table. |
1803 */ | 1854 */ |
1804void dev_pm_opp_put_genpd_virt_dev(struct opp_table *opp_table, 1805 struct device *virt_dev) | 1855void dev_pm_opp_detach_genpd(struct opp_table *opp_table) |
1806{ | 1856{ |
1807 int i; 1808 | |
1809 /* 1810 * Acquire genpd_virt_dev_lock to make sure virt_dev isn't getting 1811 * used in parallel. 1812 */ 1813 mutex_lock(&opp_table->genpd_virt_dev_lock); | 1857 /* 1858 * Acquire genpd_virt_dev_lock to make sure virt_dev isn't getting 1859 * used in parallel. 1860 */ 1861 mutex_lock(&opp_table->genpd_virt_dev_lock); |
1814 1815 for (i = 0; i < opp_table->required_opp_count; i++) { 1816 if (opp_table->genpd_virt_devs[i] != virt_dev) 1817 continue; 1818 1819 opp_table->genpd_virt_devs[i] = NULL; 1820 dev_pm_opp_put_opp_table(opp_table); 1821 1822 /* Drop the vote */ 1823 dev_pm_genpd_set_performance_state(virt_dev, 0); 1824 break; 1825 } 1826 | 1862 _opp_detach_genpd(opp_table); |
1827 mutex_unlock(&opp_table->genpd_virt_dev_lock); 1828 | 1863 mutex_unlock(&opp_table->genpd_virt_dev_lock); 1864 |
1829 if (unlikely(i == opp_table->required_opp_count)) 1830 dev_err(virt_dev, "Failed to find required device entry\n"); | 1865 dev_pm_opp_put_opp_table(opp_table); |
1831} | 1866} |
1867EXPORT_SYMBOL_GPL(dev_pm_opp_detach_genpd); |
|
1832 1833/** 1834 * dev_pm_opp_xlate_performance_state() - Find required OPP's pstate for src_table. 1835 * @src_table: OPP table which has dst_table as one of its required OPP table. 1836 * @dst_table: Required OPP table of the src_table. 1837 * @pstate: Current performance state of the src_table. 1838 * 1839 * This Returns pstate of the OPP (present in @dst_table) pointed out by the --- 289 unchanged lines hidden --- | 1868 1869/** 1870 * dev_pm_opp_xlate_performance_state() - Find required OPP's pstate for src_table. 1871 * @src_table: OPP table which has dst_table as one of its required OPP table. 1872 * @dst_table: Required OPP table of the src_table. 1873 * @pstate: Current performance state of the src_table. 1874 * 1875 * This Returns pstate of the OPP (present in @dst_table) pointed out by the --- 289 unchanged lines hidden --- |