Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

soc/tegra: pmc: Add PMC contextual functions

Add implementations that take as argument a struct tegra_pmc * for most
public APIs, as well as a function to obtain the PMC for any given
device. This will allow transitioning away users from relying on a
global variable storing the PMC context.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+221 -17
+162 -16
drivers/soc/tegra/pmc.c
··· 957 957 return err; 958 958 } 959 959 960 + static void tegra_pmc_put_device(void *data) 961 + { 962 + struct tegra_pmc *pmc = data; 963 + 964 + put_device(pmc->dev); 965 + } 966 + 967 + static const struct of_device_id tegra_pmc_match[]; 968 + 969 + static struct tegra_pmc *tegra_pmc_get(struct device *dev) 970 + { 971 + struct platform_device *pdev; 972 + struct device_node *np; 973 + struct tegra_pmc *pmc; 974 + 975 + np = of_parse_phandle(dev->of_node, "nvidia,pmc", 0); 976 + if (!np) { 977 + struct device_node *parent = of_node_get(dev->of_node); 978 + 979 + while ((parent = of_get_next_parent(parent)) != NULL) { 980 + np = of_find_matching_node(parent, tegra_pmc_match); 981 + if (np) 982 + break; 983 + } 984 + 985 + of_node_put(parent); 986 + 987 + if (!np) 988 + return ERR_PTR(-ENODEV); 989 + } 990 + 991 + pdev = of_find_device_by_node(np); 992 + of_node_put(np); 993 + 994 + if (!pdev) 995 + return ERR_PTR(-ENODEV); 996 + 997 + pmc = platform_get_drvdata(pdev); 998 + if (!pmc) { 999 + put_device(&pdev->dev); 1000 + return ERR_PTR(-EPROBE_DEFER); 1001 + } 1002 + 1003 + return pmc; 1004 + } 1005 + 960 1006 /** 961 - * tegra_powergate_power_on() - power on partition 1007 + * tegra_pmc_get() - find the PMC for a given device 1008 + * @dev: device for which to find the PMC 1009 + * 1010 + * Returns a pointer to the PMC on success or an ERR_PTR()-encoded error code 1011 + * otherwise. 1012 + */ 1013 + struct tegra_pmc *devm_tegra_pmc_get(struct device *dev) 1014 + { 1015 + struct tegra_pmc *pmc; 1016 + int err; 1017 + 1018 + pmc = tegra_pmc_get(dev); 1019 + if (IS_ERR(pmc)) 1020 + return pmc; 1021 + 1022 + err = devm_add_action_or_reset(dev, tegra_pmc_put_device, pmc); 1023 + if (err < 0) 1024 + return ERR_PTR(err); 1025 + 1026 + return pmc; 1027 + } 1028 + EXPORT_SYMBOL(devm_tegra_pmc_get); 1029 + 1030 + /** 1031 + * tegra_pmc_powergate_power_on() - power on partition 1032 + * @pmc: power management controller 962 1033 * @id: partition ID 963 1034 */ 964 - int tegra_powergate_power_on(unsigned int id) 1035 + int tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id) 965 1036 { 966 1037 if (!tegra_powergate_is_available(pmc, id)) 967 1038 return -EINVAL; 968 1039 969 1040 return tegra_powergate_set(pmc, id, true); 970 1041 } 1042 + EXPORT_SYMBOL(tegra_pmc_powergate_power_on); 1043 + 1044 + /** 1045 + * tegra_powergate_power_on() - power on partition 1046 + * @id: partition ID 1047 + */ 1048 + int tegra_powergate_power_on(unsigned int id) 1049 + { 1050 + return tegra_pmc_powergate_power_on(pmc, id); 1051 + } 971 1052 EXPORT_SYMBOL(tegra_powergate_power_on); 1053 + 1054 + /** 1055 + * tegra_pmc_powergate_power_off() - power off partition 1056 + * @pmc: power management controller 1057 + * @id: partition ID 1058 + */ 1059 + int tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id) 1060 + { 1061 + if (!tegra_powergate_is_available(pmc, id)) 1062 + return -EINVAL; 1063 + 1064 + return tegra_powergate_set(pmc, id, false); 1065 + } 1066 + EXPORT_SYMBOL(tegra_pmc_powergate_power_off); 972 1067 973 1068 /** 974 1069 * tegra_powergate_power_off() - power off partition ··· 1071 976 */ 1072 977 int tegra_powergate_power_off(unsigned int id) 1073 978 { 1074 - if (!tegra_powergate_is_available(pmc, id)) 1075 - return -EINVAL; 1076 - 1077 - return tegra_powergate_set(pmc, id, false); 979 + return tegra_pmc_powergate_power_off(pmc, id); 1078 980 } 1079 981 EXPORT_SYMBOL(tegra_powergate_power_off); 1080 982 ··· 1089 997 } 1090 998 1091 999 /** 1092 - * tegra_powergate_remove_clamping() - remove power clamps for partition 1000 + * tegra_pmc_powergate_remove_clamping() - remove power clamps for partition 1001 + * @pmc: power management controller 1093 1002 * @id: partition ID 1094 1003 */ 1095 - int tegra_powergate_remove_clamping(unsigned int id) 1004 + int tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id) 1096 1005 { 1097 1006 if (!tegra_powergate_is_available(pmc, id)) 1098 1007 return -EINVAL; 1099 1008 1100 1009 return __tegra_powergate_remove_clamping(pmc, id); 1101 1010 } 1011 + EXPORT_SYMBOL(tegra_pmc_powergate_remove_clamping); 1012 + 1013 + /** 1014 + * tegra_powergate_remove_clamping() - remove power clamps for partition 1015 + * @id: partition ID 1016 + */ 1017 + int tegra_powergate_remove_clamping(unsigned int id) 1018 + { 1019 + return tegra_pmc_powergate_remove_clamping(pmc, id); 1020 + } 1102 1021 EXPORT_SYMBOL(tegra_powergate_remove_clamping); 1103 1022 1104 1023 /** 1105 - * tegra_powergate_sequence_power_up() - power up partition 1024 + * tegra_pmc_powergate_sequence_power_up() - power up partition 1025 + * @pmc: power management controller 1106 1026 * @id: partition ID 1107 1027 * @clk: clock for partition 1108 1028 * @rst: reset for partition 1109 1029 * 1110 1030 * Must be called with clk disabled, and returns with clk enabled. 1111 1031 */ 1112 - int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 1113 - struct reset_control *rst) 1032 + int tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc, 1033 + unsigned int id, struct clk *clk, 1034 + struct reset_control *rst) 1114 1035 { 1115 1036 struct tegra_powergate *pg; 1116 1037 int err; ··· 1156 1051 kfree(pg); 1157 1052 1158 1053 return err; 1054 + } 1055 + EXPORT_SYMBOL(tegra_pmc_powergate_sequence_power_up); 1056 + 1057 + /** 1058 + * tegra_powergate_sequence_power_up() - power up partition 1059 + * @id: partition ID 1060 + * @clk: clock for partition 1061 + * @rst: reset for partition 1062 + * 1063 + * Must be called with clk disabled, and returns with clk enabled. 1064 + */ 1065 + int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 1066 + struct reset_control *rst) 1067 + { 1068 + return tegra_pmc_powergate_sequence_power_up(pmc, id, clk, rst); 1159 1069 } 1160 1070 EXPORT_SYMBOL(tegra_powergate_sequence_power_up); 1161 1071 ··· 1747 1627 1748 1628 /** 1749 1629 * tegra_io_pad_power_enable() - enable power to I/O pad 1630 + * @pmc: power management controller 1750 1631 * @id: Tegra I/O pad ID for which to enable power 1751 1632 * 1752 1633 * Returns: 0 on success or a negative error code on failure. 1753 1634 */ 1754 - int tegra_io_pad_power_enable(enum tegra_io_pad id) 1635 + int tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id) 1755 1636 { 1756 1637 const struct tegra_io_pad_soc *pad; 1757 1638 unsigned long request, status; ··· 1787 1666 mutex_unlock(&pmc->powergates_lock); 1788 1667 return err; 1789 1668 } 1669 + EXPORT_SYMBOL(tegra_pmc_io_pad_power_enable); 1670 + 1671 + /** 1672 + * tegra_io_pad_power_enable() - enable power to I/O pad 1673 + * @id: Tegra I/O pad ID for which to enable power 1674 + * 1675 + * Returns: 0 on success or a negative error code on failure. 1676 + */ 1677 + int tegra_io_pad_power_enable(enum tegra_io_pad id) 1678 + { 1679 + return tegra_pmc_io_pad_power_enable(pmc, id); 1680 + } 1790 1681 EXPORT_SYMBOL(tegra_io_pad_power_enable); 1791 1682 1792 1683 /** 1793 - * tegra_io_pad_power_disable() - disable power to I/O pad 1684 + * tegra_pmc_io_pad_power_disable() - disable power to I/O pad 1685 + * @pmc: power management controller 1794 1686 * @id: Tegra I/O pad ID for which to disable power 1795 1687 * 1796 1688 * Returns: 0 on success or a negative error code on failure. 1797 1689 */ 1798 - int tegra_io_pad_power_disable(enum tegra_io_pad id) 1690 + int tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id) 1799 1691 { 1800 1692 const struct tegra_io_pad_soc *pad; 1801 1693 unsigned long request, status; ··· 1842 1708 unlock: 1843 1709 mutex_unlock(&pmc->powergates_lock); 1844 1710 return err; 1711 + } 1712 + EXPORT_SYMBOL(tegra_pmc_io_pad_power_disable); 1713 + 1714 + /** 1715 + * tegra_io_pad_power_disable() - disable power to I/O pad 1716 + * @id: Tegra I/O pad ID for which to disable power 1717 + * 1718 + * Returns: 0 on success or a negative error code on failure. 1719 + */ 1720 + int tegra_io_pad_power_disable(enum tegra_io_pad id) 1721 + { 1722 + return tegra_pmc_io_pad_power_disable(pmc, id); 1845 1723 } 1846 1724 EXPORT_SYMBOL(tegra_io_pad_power_disable); 1847 1725 ··· 2330 2184 switch (param) { 2331 2185 case PIN_CONFIG_MODE_LOW_POWER: 2332 2186 if (arg) 2333 - err = tegra_io_pad_power_disable(pad->id); 2187 + err = tegra_pmc_io_pad_power_disable(pmc, pad->id); 2334 2188 else 2335 - err = tegra_io_pad_power_enable(pad->id); 2189 + err = tegra_pmc_io_pad_power_enable(pmc, pad->id); 2336 2190 if (err) 2337 2191 return err; 2338 2192 break;
+59 -1
include/soc/tegra/pmc.h
··· 16 16 17 17 struct clk; 18 18 struct reset_control; 19 + struct tegra_pmc; 19 20 20 21 bool tegra_pmc_cpu_is_powered(unsigned int cpuid); 21 22 int tegra_pmc_cpu_power_on(unsigned int cpuid); ··· 150 149 }; 151 150 152 151 #ifdef CONFIG_SOC_TEGRA_PMC 152 + struct tegra_pmc *devm_tegra_pmc_get(struct device *dev); 153 + 154 + int tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id); 155 + int tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id); 156 + int tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id); 157 + 158 + /* Must be called with clk disabled, and returns with clk enabled */ 159 + int tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc, 160 + unsigned int id, struct clk *clk, 161 + struct reset_control *rst); 162 + int tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id); 163 + int tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id); 164 + 165 + /* legacy */ 153 166 int tegra_powergate_power_on(unsigned int id); 154 167 int tegra_powergate_power_off(unsigned int id); 155 168 int tegra_powergate_remove_clamping(unsigned int id); 156 169 157 - /* Must be called with clk disabled, and returns with clk enabled */ 158 170 int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 159 171 struct reset_control *rst); 160 172 ··· 180 166 bool tegra_pmc_core_domain_state_synced(void); 181 167 182 168 #else 169 + static inline struct tegra_pmc *devm_tegra_pmc_get(struct device *dev) 170 + { 171 + return ERR_PTR(-ENOSYS); 172 + } 173 + 174 + static inline int 175 + tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id) 176 + { 177 + return -ENOSYS; 178 + } 179 + 180 + static inline int 181 + tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id) 182 + { 183 + return -ENOSYS; 184 + } 185 + 186 + static inline int 187 + tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id) 188 + { 189 + return -ENOSYS; 190 + } 191 + 192 + /* Must be called with clk disabled, and returns with clk enabled */ 193 + static inline int 194 + tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc, unsigned int id, 195 + struct clk *clk, 196 + struct reset_control *rst) 197 + { 198 + return -ENOSYS; 199 + } 200 + 201 + static inline int 202 + tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id) 203 + { 204 + return -ENOSYS; 205 + } 206 + 207 + static inline int 208 + tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id) 209 + { 210 + return -ENOSYS; 211 + } 212 + 183 213 static inline int tegra_powergate_power_on(unsigned int id) 184 214 { 185 215 return -ENOSYS;