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 ---