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.

Merge tag 'tegra-for-6.20-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/drivers

soc/tegra: Changes for v6.20-rc1

This series primarily refactors the Tegra PMC driver to eliminate
reliance on a global variable, transitioning to passing the tegra_pmc
context explicitly across clocks, powergates, sysfs/debugfs interfaces,
and power management callbacks. Additionally, it resolves a warning
during system resume by deferring an unsafe generic_handle_irq() call to
a hard IRQ context using irq_work.

* tag 'tegra-for-6.20-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
soc/tegra: pmc: Add PMC contextual functions
soc/tegra: pmc: Do not rely on global variable
soc/tegra: pmc: Use driver-private data
soc/tegra: pmc: Use PMC context embedded in powergates
soc/tegra: pmc: Pass PMC context as debugfs data
soc/tegra: pmc: Pass PMC context via sys-off callback data
soc/tegra: pmc: Embed reboot notifier in PMC context
soc/tegra: pmc: Store PMC context in clocks
soc/tegra: pmc: Pass struct tegra_pmc to tegra_powergate_state()
soc/tegra: pmc: Use contextual data instead of global variable
soc/tegra: pmc: Fix unsafe generic_handle_irq() call

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+388 -105
+329 -104
drivers/soc/tegra/pmc.c
··· 28 28 #include <linux/iopoll.h> 29 29 #include <linux/irqdomain.h> 30 30 #include <linux/irq.h> 31 + #include <linux/irq_work.h> 31 32 #include <linux/kernel.h> 32 33 #include <linux/of_address.h> 33 34 #include <linux/of_clk.h> ··· 202 201 #define TEGRA_SMC_PMC_WRITE 0xbb 203 202 204 203 struct pmc_clk { 205 - struct clk_hw hw; 206 - unsigned long offs; 207 - u32 mux_shift; 208 - u32 force_en_shift; 204 + struct clk_hw hw; 205 + struct tegra_pmc *pmc; 206 + unsigned long offs; 207 + u32 mux_shift; 208 + u32 force_en_shift; 209 209 }; 210 210 211 211 #define to_pmc_clk(_hw) container_of(_hw, struct pmc_clk, hw) 212 212 213 213 struct pmc_clk_gate { 214 - struct clk_hw hw; 215 - unsigned long offs; 216 - u32 shift; 214 + struct clk_hw hw; 215 + struct tegra_pmc *pmc; 216 + unsigned long offs; 217 + u32 shift; 217 218 }; 218 219 219 220 #define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw) ··· 267 264 .force_en_shift = 18, 268 265 }, 269 266 }; 267 + 268 + struct tegra_pmc_core_pd { 269 + struct generic_pm_domain genpd; 270 + struct tegra_pmc *pmc; 271 + }; 272 + 273 + static inline struct tegra_pmc_core_pd * 274 + to_core_pd(struct generic_pm_domain *genpd) 275 + { 276 + return container_of(genpd, struct tegra_pmc_core_pd, genpd); 277 + } 270 278 271 279 struct tegra_powergate { 272 280 struct generic_pm_domain genpd; ··· 481 467 unsigned long *wake_type_dual_edge_map; 482 468 unsigned long *wake_sw_status_map; 483 469 unsigned long *wake_cntrl_level_map; 470 + 471 + struct notifier_block reboot_notifier; 484 472 struct syscore syscore; 473 + 474 + /* Pending wake IRQ processing */ 475 + struct irq_work wake_work; 476 + u32 *wake_status; 485 477 }; 486 478 487 479 static struct tegra_pmc *pmc = &(struct tegra_pmc) { ··· 561 541 writel(value, pmc->scratch + offset); 562 542 } 563 543 564 - /* 565 - * TODO Figure out a way to call this with the struct tegra_pmc * passed in. 566 - * This currently doesn't work because readx_poll_timeout() can only operate 567 - * on functions that take a single argument. 568 - */ 569 - static inline bool tegra_powergate_state(int id) 544 + static inline bool tegra_powergate_state(struct tegra_pmc *pmc, int id) 570 545 { 571 546 if (id == TEGRA_POWERGATE_3D && pmc->soc->has_gpu_clamps) 572 547 return (tegra_pmc_readl(pmc, GPU_RG_CNTRL) & 0x1) == 0; ··· 613 598 tegra_pmc_writel(pmc, PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); 614 599 615 600 /* wait for PMC to execute the command */ 616 - ret = readx_poll_timeout(tegra_powergate_state, id, status, 617 - status == new_state, 1, 10); 601 + ret = read_poll_timeout(tegra_powergate_state, status, 602 + status == new_state, 1, 10, false, 603 + pmc, id); 618 604 } while (ret == -ETIMEDOUT && retries--); 619 605 620 606 return ret; ··· 647 631 return err; 648 632 649 633 /* wait for PMC to execute the command */ 650 - err = readx_poll_timeout(tegra_powergate_state, id, status, 651 - status == new_state, 10, 100000); 634 + err = read_poll_timeout(tegra_powergate_state, status, 635 + status == new_state, 10, 100000, false, 636 + pmc, id); 652 637 if (err) 653 638 return err; 654 639 ··· 672 655 673 656 mutex_lock(&pmc->powergates_lock); 674 657 675 - if (tegra_powergate_state(id) == new_state) { 658 + if (tegra_powergate_state(pmc, id) == new_state) { 676 659 mutex_unlock(&pmc->powergates_lock); 677 660 return 0; 678 661 } ··· 957 940 return err; 958 941 } 959 942 943 + static void tegra_pmc_put_device(void *data) 944 + { 945 + struct tegra_pmc *pmc = data; 946 + 947 + put_device(pmc->dev); 948 + } 949 + 950 + static const struct of_device_id tegra_pmc_match[]; 951 + 952 + static struct tegra_pmc *tegra_pmc_get(struct device *dev) 953 + { 954 + struct platform_device *pdev; 955 + struct device_node *np; 956 + struct tegra_pmc *pmc; 957 + 958 + np = of_parse_phandle(dev->of_node, "nvidia,pmc", 0); 959 + if (!np) { 960 + struct device_node *parent = of_node_get(dev->of_node); 961 + 962 + while ((parent = of_get_next_parent(parent)) != NULL) { 963 + np = of_find_matching_node(parent, tegra_pmc_match); 964 + if (np) 965 + break; 966 + } 967 + 968 + of_node_put(parent); 969 + 970 + if (!np) 971 + return ERR_PTR(-ENODEV); 972 + } 973 + 974 + pdev = of_find_device_by_node(np); 975 + of_node_put(np); 976 + 977 + if (!pdev) 978 + return ERR_PTR(-ENODEV); 979 + 980 + pmc = platform_get_drvdata(pdev); 981 + if (!pmc) { 982 + put_device(&pdev->dev); 983 + return ERR_PTR(-EPROBE_DEFER); 984 + } 985 + 986 + return pmc; 987 + } 988 + 960 989 /** 961 - * tegra_powergate_power_on() - power on partition 990 + * tegra_pmc_get() - find the PMC for a given device 991 + * @dev: device for which to find the PMC 992 + * 993 + * Returns a pointer to the PMC on success or an ERR_PTR()-encoded error code 994 + * otherwise. 995 + */ 996 + struct tegra_pmc *devm_tegra_pmc_get(struct device *dev) 997 + { 998 + struct tegra_pmc *pmc; 999 + int err; 1000 + 1001 + pmc = tegra_pmc_get(dev); 1002 + if (IS_ERR(pmc)) 1003 + return pmc; 1004 + 1005 + err = devm_add_action_or_reset(dev, tegra_pmc_put_device, pmc); 1006 + if (err < 0) 1007 + return ERR_PTR(err); 1008 + 1009 + return pmc; 1010 + } 1011 + EXPORT_SYMBOL(devm_tegra_pmc_get); 1012 + 1013 + /** 1014 + * tegra_pmc_powergate_power_on() - power on partition 1015 + * @pmc: power management controller 962 1016 * @id: partition ID 963 1017 */ 964 - int tegra_powergate_power_on(unsigned int id) 1018 + int tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id) 965 1019 { 966 1020 if (!tegra_powergate_is_available(pmc, id)) 967 1021 return -EINVAL; 968 1022 969 1023 return tegra_powergate_set(pmc, id, true); 970 1024 } 1025 + EXPORT_SYMBOL(tegra_pmc_powergate_power_on); 1026 + 1027 + /** 1028 + * tegra_powergate_power_on() - power on partition 1029 + * @id: partition ID 1030 + */ 1031 + int tegra_powergate_power_on(unsigned int id) 1032 + { 1033 + return tegra_pmc_powergate_power_on(pmc, id); 1034 + } 971 1035 EXPORT_SYMBOL(tegra_powergate_power_on); 1036 + 1037 + /** 1038 + * tegra_pmc_powergate_power_off() - power off partition 1039 + * @pmc: power management controller 1040 + * @id: partition ID 1041 + */ 1042 + int tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id) 1043 + { 1044 + if (!tegra_powergate_is_available(pmc, id)) 1045 + return -EINVAL; 1046 + 1047 + return tegra_powergate_set(pmc, id, false); 1048 + } 1049 + EXPORT_SYMBOL(tegra_pmc_powergate_power_off); 972 1050 973 1051 /** 974 1052 * tegra_powergate_power_off() - power off partition ··· 1071 959 */ 1072 960 int tegra_powergate_power_off(unsigned int id) 1073 961 { 1074 - if (!tegra_powergate_is_available(pmc, id)) 1075 - return -EINVAL; 1076 - 1077 - return tegra_powergate_set(pmc, id, false); 962 + return tegra_pmc_powergate_power_off(pmc, id); 1078 963 } 1079 964 EXPORT_SYMBOL(tegra_powergate_power_off); 1080 965 ··· 1085 976 if (!tegra_powergate_is_valid(pmc, id)) 1086 977 return -EINVAL; 1087 978 1088 - return tegra_powergate_state(id); 979 + return tegra_powergate_state(pmc, id); 1089 980 } 981 + 982 + /** 983 + * tegra_pmc_powergate_remove_clamping() - remove power clamps for partition 984 + * @pmc: power management controller 985 + * @id: partition ID 986 + */ 987 + int tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id) 988 + { 989 + if (!tegra_powergate_is_available(pmc, id)) 990 + return -EINVAL; 991 + 992 + return __tegra_powergate_remove_clamping(pmc, id); 993 + } 994 + EXPORT_SYMBOL(tegra_pmc_powergate_remove_clamping); 1090 995 1091 996 /** 1092 997 * tegra_powergate_remove_clamping() - remove power clamps for partition ··· 1108 985 */ 1109 986 int tegra_powergate_remove_clamping(unsigned int id) 1110 987 { 1111 - if (!tegra_powergate_is_available(pmc, id)) 1112 - return -EINVAL; 1113 - 1114 - return __tegra_powergate_remove_clamping(pmc, id); 988 + return tegra_pmc_powergate_remove_clamping(pmc, id); 1115 989 } 1116 990 EXPORT_SYMBOL(tegra_powergate_remove_clamping); 1117 991 1118 992 /** 1119 - * tegra_powergate_sequence_power_up() - power up partition 993 + * tegra_pmc_powergate_sequence_power_up() - power up partition 994 + * @pmc: power management controller 1120 995 * @id: partition ID 1121 996 * @clk: clock for partition 1122 997 * @rst: reset for partition 1123 998 * 1124 999 * Must be called with clk disabled, and returns with clk enabled. 1125 1000 */ 1126 - int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 1127 - struct reset_control *rst) 1001 + int tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc, 1002 + unsigned int id, struct clk *clk, 1003 + struct reset_control *rst) 1128 1004 { 1129 1005 struct tegra_powergate *pg; 1130 1006 int err; ··· 1156 1034 kfree(pg); 1157 1035 1158 1036 return err; 1037 + } 1038 + EXPORT_SYMBOL(tegra_pmc_powergate_sequence_power_up); 1039 + 1040 + /** 1041 + * tegra_powergate_sequence_power_up() - power up partition 1042 + * @id: partition ID 1043 + * @clk: clock for partition 1044 + * @rst: reset for partition 1045 + * 1046 + * Must be called with clk disabled, and returns with clk enabled. 1047 + */ 1048 + int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk, 1049 + struct reset_control *rst) 1050 + { 1051 + return tegra_pmc_powergate_sequence_power_up(pmc, id, clk, rst); 1159 1052 } 1160 1053 EXPORT_SYMBOL(tegra_powergate_sequence_power_up); 1161 1054 ··· 1236 1099 return tegra_powergate_remove_clamping(id); 1237 1100 } 1238 1101 1239 - static void tegra_pmc_program_reboot_reason(const char *cmd) 1102 + static void tegra_pmc_program_reboot_reason(struct tegra_pmc *pmc, 1103 + const char *cmd) 1240 1104 { 1241 1105 u32 value; 1242 1106 ··· 1261 1123 static int tegra_pmc_reboot_notify(struct notifier_block *this, 1262 1124 unsigned long action, void *data) 1263 1125 { 1126 + struct tegra_pmc *pmc = container_of(this, struct tegra_pmc, 1127 + reboot_notifier); 1264 1128 if (action == SYS_RESTART) 1265 - tegra_pmc_program_reboot_reason(data); 1129 + tegra_pmc_program_reboot_reason(pmc, data); 1266 1130 1267 1131 return NOTIFY_DONE; 1268 1132 } 1269 1133 1270 - static struct notifier_block tegra_pmc_reboot_notifier = { 1271 - .notifier_call = tegra_pmc_reboot_notify, 1272 - }; 1273 - 1274 - static void tegra_pmc_restart(void) 1134 + static void tegra_pmc_restart(struct tegra_pmc *pmc) 1275 1135 { 1276 1136 u32 value; 1277 1137 ··· 1281 1145 1282 1146 static int tegra_pmc_restart_handler(struct sys_off_data *data) 1283 1147 { 1284 - tegra_pmc_restart(); 1148 + struct tegra_pmc *pmc = data->cb_data; 1149 + 1150 + tegra_pmc_restart(pmc); 1285 1151 1286 1152 return NOTIFY_DONE; 1287 1153 } 1288 1154 1289 1155 static int tegra_pmc_power_off_handler(struct sys_off_data *data) 1290 1156 { 1157 + struct tegra_pmc *pmc = data->cb_data; 1158 + 1291 1159 /* 1292 1160 * Reboot Nexus 7 into special bootloader mode if USB cable is 1293 1161 * connected in order to display battery status and power off. ··· 1301 1161 const u32 go_to_charger_mode = 0xa5a55a5a; 1302 1162 1303 1163 tegra_pmc_writel(pmc, go_to_charger_mode, PMC_SCRATCH37); 1304 - tegra_pmc_restart(); 1164 + tegra_pmc_restart(pmc); 1305 1165 } 1306 1166 1307 1167 return NOTIFY_DONE; ··· 1309 1169 1310 1170 static int powergate_show(struct seq_file *s, void *data) 1311 1171 { 1172 + struct tegra_pmc *pmc = data; 1312 1173 unsigned int i; 1313 1174 int status; 1314 1175 ··· 1518 1377 tegra_pmc_core_pd_set_performance_state(struct generic_pm_domain *genpd, 1519 1378 unsigned int level) 1520 1379 { 1380 + struct tegra_pmc_core_pd *pd = to_core_pd(genpd); 1381 + struct tegra_pmc *pmc = pd->pmc; 1521 1382 struct dev_pm_opp *opp; 1522 1383 int err; 1523 1384 ··· 1547 1404 1548 1405 static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np) 1549 1406 { 1550 - struct generic_pm_domain *genpd; 1551 1407 const char *rname[] = { "core", NULL}; 1408 + struct tegra_pmc_core_pd *pd; 1552 1409 int err; 1553 1410 1554 - genpd = devm_kzalloc(pmc->dev, sizeof(*genpd), GFP_KERNEL); 1555 - if (!genpd) 1411 + pd = devm_kzalloc(pmc->dev, sizeof(*pd), GFP_KERNEL); 1412 + if (!pd) 1556 1413 return -ENOMEM; 1557 1414 1558 - genpd->name = "core"; 1559 - genpd->flags = GENPD_FLAG_NO_SYNC_STATE; 1560 - genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state; 1415 + pd->genpd.name = "core"; 1416 + pd->genpd.flags = GENPD_FLAG_NO_SYNC_STATE; 1417 + pd->genpd.set_performance_state = tegra_pmc_core_pd_set_performance_state; 1418 + pd->pmc = pmc; 1561 1419 1562 1420 err = devm_pm_opp_set_regulators(pmc->dev, rname); 1563 1421 if (err) 1564 1422 return dev_err_probe(pmc->dev, err, 1565 1423 "failed to set core OPP regulator\n"); 1566 1424 1567 - err = pm_genpd_init(genpd, NULL, false); 1425 + err = pm_genpd_init(&pd->genpd, NULL, false); 1568 1426 if (err) { 1569 1427 dev_err(pmc->dev, "failed to init core genpd: %d\n", err); 1570 1428 return err; 1571 1429 } 1572 1430 1573 - err = of_genpd_add_provider_simple(np, genpd); 1431 + err = of_genpd_add_provider_simple(np, &pd->genpd); 1574 1432 if (err) { 1575 1433 dev_err(pmc->dev, "failed to add core genpd: %d\n", err); 1576 1434 goto remove_genpd; ··· 1580 1436 return 0; 1581 1437 1582 1438 remove_genpd: 1583 - pm_genpd_remove(genpd); 1439 + pm_genpd_remove(&pd->genpd); 1584 1440 1585 1441 return err; 1586 1442 } ··· 1643 1499 1644 1500 kfree(pg->clks); 1645 1501 1646 - set_bit(pg->id, pmc->powergates_available); 1502 + set_bit(pg->id, pg->pmc->powergates_available); 1647 1503 1648 1504 kfree(pg); 1649 1505 } ··· 1747 1603 1748 1604 /** 1749 1605 * tegra_io_pad_power_enable() - enable power to I/O pad 1606 + * @pmc: power management controller 1750 1607 * @id: Tegra I/O pad ID for which to enable power 1751 1608 * 1752 1609 * Returns: 0 on success or a negative error code on failure. 1753 1610 */ 1754 - int tegra_io_pad_power_enable(enum tegra_io_pad id) 1611 + int tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id) 1755 1612 { 1756 1613 const struct tegra_io_pad_soc *pad; 1757 1614 unsigned long request, status; ··· 1787 1642 mutex_unlock(&pmc->powergates_lock); 1788 1643 return err; 1789 1644 } 1645 + EXPORT_SYMBOL(tegra_pmc_io_pad_power_enable); 1646 + 1647 + /** 1648 + * tegra_io_pad_power_enable() - enable power to I/O pad 1649 + * @id: Tegra I/O pad ID for which to enable power 1650 + * 1651 + * Returns: 0 on success or a negative error code on failure. 1652 + */ 1653 + int tegra_io_pad_power_enable(enum tegra_io_pad id) 1654 + { 1655 + return tegra_pmc_io_pad_power_enable(pmc, id); 1656 + } 1790 1657 EXPORT_SYMBOL(tegra_io_pad_power_enable); 1791 1658 1792 1659 /** 1793 - * tegra_io_pad_power_disable() - disable power to I/O pad 1660 + * tegra_pmc_io_pad_power_disable() - disable power to I/O pad 1661 + * @pmc: power management controller 1794 1662 * @id: Tegra I/O pad ID for which to disable power 1795 1663 * 1796 1664 * Returns: 0 on success or a negative error code on failure. 1797 1665 */ 1798 - int tegra_io_pad_power_disable(enum tegra_io_pad id) 1666 + int tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id) 1799 1667 { 1800 1668 const struct tegra_io_pad_soc *pad; 1801 1669 unsigned long request, status; ··· 1842 1684 unlock: 1843 1685 mutex_unlock(&pmc->powergates_lock); 1844 1686 return err; 1687 + } 1688 + EXPORT_SYMBOL(tegra_pmc_io_pad_power_disable); 1689 + 1690 + /** 1691 + * tegra_io_pad_power_disable() - disable power to I/O pad 1692 + * @id: Tegra I/O pad ID for which to disable power 1693 + * 1694 + * Returns: 0 on success or a negative error code on failure. 1695 + */ 1696 + int tegra_io_pad_power_disable(enum tegra_io_pad id) 1697 + { 1698 + return tegra_pmc_io_pad_power_disable(pmc, id); 1845 1699 } 1846 1700 EXPORT_SYMBOL(tegra_io_pad_power_disable); 1847 1701 ··· 2075 1905 return 0; 2076 1906 } 2077 1907 1908 + /* translate sc7 wake sources back into IRQs to catch edge triggered wakeups */ 1909 + static void tegra186_pmc_wake_handler(struct irq_work *work) 1910 + { 1911 + struct tegra_pmc *pmc = container_of(work, struct tegra_pmc, wake_work); 1912 + unsigned int i, wake; 1913 + 1914 + for (i = 0; i < pmc->soc->max_wake_vectors; i++) { 1915 + unsigned long status = pmc->wake_status[i]; 1916 + 1917 + for_each_set_bit(wake, &status, 32) { 1918 + irq_hw_number_t hwirq = wake + (i * 32); 1919 + struct irq_desc *desc; 1920 + unsigned int irq; 1921 + 1922 + irq = irq_find_mapping(pmc->domain, hwirq); 1923 + if (!irq) { 1924 + dev_warn(pmc->dev, 1925 + "No IRQ found for WAKE#%lu!\n", 1926 + hwirq); 1927 + continue; 1928 + } 1929 + 1930 + dev_dbg(pmc->dev, 1931 + "Resume caused by WAKE#%lu mapped to IRQ#%u\n", 1932 + hwirq, irq); 1933 + 1934 + desc = irq_to_desc(irq); 1935 + if (!desc) { 1936 + dev_warn(pmc->dev, 1937 + "No descriptor found for IRQ#%u\n", 1938 + irq); 1939 + continue; 1940 + } 1941 + 1942 + if (!desc->action || !desc->action->name) 1943 + continue; 1944 + 1945 + generic_handle_irq(irq); 1946 + } 1947 + 1948 + pmc->wake_status[i] = 0; 1949 + } 1950 + } 1951 + 2078 1952 static int tegra_pmc_init(struct tegra_pmc *pmc) 2079 1953 { 2080 1954 if (pmc->soc->max_wake_events > 0) { ··· 2137 1923 pmc->wake_cntrl_level_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); 2138 1924 if (!pmc->wake_cntrl_level_map) 2139 1925 return -ENOMEM; 1926 + 1927 + pmc->wake_status = kcalloc(pmc->soc->max_wake_vectors, sizeof(u32), GFP_KERNEL); 1928 + if (!pmc->wake_status) 1929 + return -ENOMEM; 1930 + 1931 + /* 1932 + * Initialize IRQ work for processing wake IRQs. Must use 1933 + * HARD_IRQ variant to run in hard IRQ context on PREEMPT_RT 1934 + * because we call generic_handle_irq() which requires hard 1935 + * IRQ context. 1936 + */ 1937 + pmc->wake_work = IRQ_WORK_INIT_HARD(tegra186_pmc_wake_handler); 2140 1938 } 2141 1939 2142 1940 if (pmc->soc->init) ··· 2330 2104 switch (param) { 2331 2105 case PIN_CONFIG_MODE_LOW_POWER: 2332 2106 if (arg) 2333 - err = tegra_io_pad_power_disable(pad->id); 2107 + err = tegra_pmc_io_pad_power_disable(pmc, pad->id); 2334 2108 else 2335 - err = tegra_io_pad_power_enable(pad->id); 2109 + err = tegra_pmc_io_pad_power_enable(pmc, pad->id); 2336 2110 if (err) 2337 2111 return err; 2338 2112 break; ··· 2389 2163 static ssize_t reset_reason_show(struct device *dev, 2390 2164 struct device_attribute *attr, char *buf) 2391 2165 { 2166 + struct tegra_pmc *pmc = dev_get_drvdata(dev); 2392 2167 u32 value; 2393 2168 2394 2169 value = tegra_pmc_readl(pmc, pmc->soc->regs->rst_status); ··· 2407 2180 static ssize_t reset_level_show(struct device *dev, 2408 2181 struct device_attribute *attr, char *buf) 2409 2182 { 2183 + struct tegra_pmc *pmc = dev_get_drvdata(dev); 2410 2184 u32 value; 2411 2185 2412 2186 value = tegra_pmc_readl(pmc, pmc->soc->regs->rst_status); ··· 2771 2543 return NOTIFY_OK; 2772 2544 } 2773 2545 2774 - static void pmc_clk_fence_udelay(u32 offset) 2546 + static void pmc_clk_fence_udelay(struct tegra_pmc *pmc, u32 offset) 2775 2547 { 2776 2548 tegra_pmc_readl(pmc, offset); 2777 2549 /* pmc clk propagation delay 2 us */ ··· 2783 2555 struct pmc_clk *clk = to_pmc_clk(hw); 2784 2556 u32 val; 2785 2557 2786 - val = tegra_pmc_readl(pmc, clk->offs) >> clk->mux_shift; 2558 + val = tegra_pmc_readl(clk->pmc, clk->offs) >> clk->mux_shift; 2787 2559 val &= PMC_CLK_OUT_MUX_MASK; 2788 2560 2789 2561 return val; ··· 2794 2566 struct pmc_clk *clk = to_pmc_clk(hw); 2795 2567 u32 val; 2796 2568 2797 - val = tegra_pmc_readl(pmc, clk->offs); 2569 + val = tegra_pmc_readl(clk->pmc, clk->offs); 2798 2570 val &= ~(PMC_CLK_OUT_MUX_MASK << clk->mux_shift); 2799 2571 val |= index << clk->mux_shift; 2800 - tegra_pmc_writel(pmc, val, clk->offs); 2801 - pmc_clk_fence_udelay(clk->offs); 2572 + tegra_pmc_writel(clk->pmc, val, clk->offs); 2573 + pmc_clk_fence_udelay(clk->pmc, clk->offs); 2802 2574 2803 2575 return 0; 2804 2576 } ··· 2808 2580 struct pmc_clk *clk = to_pmc_clk(hw); 2809 2581 u32 val; 2810 2582 2811 - val = tegra_pmc_readl(pmc, clk->offs) & BIT(clk->force_en_shift); 2583 + val = tegra_pmc_readl(clk->pmc, clk->offs) & BIT(clk->force_en_shift); 2812 2584 2813 2585 return val ? 1 : 0; 2814 2586 } 2815 2587 2816 - static void pmc_clk_set_state(unsigned long offs, u32 shift, int state) 2588 + static void pmc_clk_set_state(struct tegra_pmc *pmc, unsigned long offs, 2589 + u32 shift, int state) 2817 2590 { 2818 2591 u32 val; 2819 2592 2820 2593 val = tegra_pmc_readl(pmc, offs); 2821 2594 val = state ? (val | BIT(shift)) : (val & ~BIT(shift)); 2822 2595 tegra_pmc_writel(pmc, val, offs); 2823 - pmc_clk_fence_udelay(offs); 2596 + pmc_clk_fence_udelay(pmc, offs); 2824 2597 } 2825 2598 2826 2599 static int pmc_clk_enable(struct clk_hw *hw) 2827 2600 { 2828 2601 struct pmc_clk *clk = to_pmc_clk(hw); 2829 2602 2830 - pmc_clk_set_state(clk->offs, clk->force_en_shift, 1); 2603 + pmc_clk_set_state(clk->pmc, clk->offs, clk->force_en_shift, 1); 2831 2604 2832 2605 return 0; 2833 2606 } ··· 2837 2608 { 2838 2609 struct pmc_clk *clk = to_pmc_clk(hw); 2839 2610 2840 - pmc_clk_set_state(clk->offs, clk->force_en_shift, 0); 2611 + pmc_clk_set_state(clk->pmc, clk->offs, clk->force_en_shift, 0); 2841 2612 } 2842 2613 2843 2614 static const struct clk_ops pmc_clk_ops = { ··· 2869 2640 CLK_SET_PARENT_GATE; 2870 2641 2871 2642 pmc_clk->hw.init = &init; 2643 + pmc_clk->pmc = pmc; 2872 2644 pmc_clk->offs = offset; 2873 2645 pmc_clk->mux_shift = data->mux_shift; 2874 2646 pmc_clk->force_en_shift = data->force_en_shift; ··· 2880 2650 static int pmc_clk_gate_is_enabled(struct clk_hw *hw) 2881 2651 { 2882 2652 struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); 2653 + u32 value = tegra_pmc_readl(gate->pmc, gate->offs); 2883 2654 2884 - return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0; 2655 + return value & BIT(gate->shift) ? 1 : 0; 2885 2656 } 2886 2657 2887 2658 static int pmc_clk_gate_enable(struct clk_hw *hw) 2888 2659 { 2889 2660 struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); 2890 2661 2891 - pmc_clk_set_state(gate->offs, gate->shift, 1); 2662 + pmc_clk_set_state(gate->pmc, gate->offs, gate->shift, 1); 2892 2663 2893 2664 return 0; 2894 2665 } ··· 2898 2667 { 2899 2668 struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); 2900 2669 2901 - pmc_clk_set_state(gate->offs, gate->shift, 0); 2670 + pmc_clk_set_state(gate->pmc, gate->offs, gate->shift, 0); 2902 2671 } 2903 2672 2904 2673 static const struct clk_ops pmc_clk_gate_ops = { ··· 2926 2695 init.flags = 0; 2927 2696 2928 2697 gate->hw.init = &init; 2698 + gate->pmc = pmc; 2929 2699 gate->offs = offset; 2930 2700 gate->shift = shift; 2931 2701 ··· 3090 2858 3091 2859 static void tegra_pmc_reset_suspend_mode(void *data) 3092 2860 { 2861 + struct tegra_pmc *pmc = data; 2862 + 3093 2863 pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY; 3094 2864 } 3095 2865 ··· 3114 2880 return err; 3115 2881 3116 2882 err = devm_add_action_or_reset(&pdev->dev, tegra_pmc_reset_suspend_mode, 3117 - NULL); 2883 + pmc); 3118 2884 if (err) 3119 2885 return err; 3120 2886 ··· 3165 2931 * CPU without resetting everything else. 3166 2932 */ 3167 2933 if (pmc->scratch) { 2934 + pmc->reboot_notifier.notifier_call = tegra_pmc_reboot_notify; 2935 + 3168 2936 err = devm_register_reboot_notifier(&pdev->dev, 3169 - &tegra_pmc_reboot_notifier); 2937 + &pmc->reboot_notifier); 3170 2938 if (err) { 3171 2939 dev_err(&pdev->dev, 3172 2940 "unable to register reboot notifier, %d\n", ··· 3180 2944 err = devm_register_sys_off_handler(&pdev->dev, 3181 2945 SYS_OFF_MODE_RESTART, 3182 2946 SYS_OFF_PRIO_LOW, 3183 - tegra_pmc_restart_handler, NULL); 2947 + tegra_pmc_restart_handler, 2948 + pmc); 3184 2949 if (err) { 3185 2950 dev_err(&pdev->dev, "failed to register sys-off handler: %d\n", 3186 2951 err); ··· 3195 2958 err = devm_register_sys_off_handler(&pdev->dev, 3196 2959 SYS_OFF_MODE_POWER_OFF, 3197 2960 SYS_OFF_PRIO_FIRMWARE, 3198 - tegra_pmc_power_off_handler, NULL); 2961 + tegra_pmc_power_off_handler, 2962 + pmc); 3199 2963 if (err) { 3200 2964 dev_err(&pdev->dev, "failed to register sys-off handler: %d\n", 3201 2965 err); ··· 3262 3024 if (pmc->soc->set_wake_filters) 3263 3025 pmc->soc->set_wake_filters(pmc); 3264 3026 3265 - debugfs_create_file("powergate", 0444, NULL, NULL, &powergate_fops); 3027 + debugfs_create_file("powergate", 0444, NULL, pmc, &powergate_fops); 3266 3028 3267 3029 return 0; 3268 3030 ··· 3367 3129 } 3368 3130 } 3369 3131 3370 - /* translate sc7 wake sources back into IRQs to catch edge triggered wakeups */ 3371 - static void tegra186_pmc_process_wake_events(struct tegra_pmc *pmc, unsigned int index, 3372 - unsigned long status) 3373 - { 3374 - unsigned int wake; 3375 - 3376 - dev_dbg(pmc->dev, "Wake[%d:%d] status=%#lx\n", (index * 32) + 31, index * 32, status); 3377 - 3378 - for_each_set_bit(wake, &status, 32) { 3379 - irq_hw_number_t hwirq = wake + 32 * index; 3380 - struct irq_desc *desc; 3381 - unsigned int irq; 3382 - 3383 - irq = irq_find_mapping(pmc->domain, hwirq); 3384 - 3385 - desc = irq_to_desc(irq); 3386 - if (!desc || !desc->action || !desc->action->name) { 3387 - dev_dbg(pmc->dev, "Resume caused by WAKE%ld, IRQ %d\n", hwirq, irq); 3388 - continue; 3389 - } 3390 - 3391 - dev_dbg(pmc->dev, "Resume caused by WAKE%ld, %s\n", hwirq, desc->action->name); 3392 - generic_handle_irq(irq); 3393 - } 3394 - } 3395 - 3396 3132 static void tegra186_pmc_wake_syscore_resume(void *data) 3397 3133 { 3398 - u32 status, mask; 3134 + struct tegra_pmc *pmc = data; 3399 3135 unsigned int i; 3136 + u32 mask; 3400 3137 3401 3138 for (i = 0; i < pmc->soc->max_wake_vectors; i++) { 3402 3139 mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i)); 3403 - status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask; 3404 - 3405 - tegra186_pmc_process_wake_events(pmc, i, status); 3140 + pmc->wake_status[i] = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask; 3406 3141 } 3142 + 3143 + /* Schedule IRQ work to process wake IRQs (if any) */ 3144 + irq_work_queue(&pmc->wake_work); 3407 3145 } 3408 3146 3409 3147 static int tegra186_pmc_wake_syscore_suspend(void *data) 3410 3148 { 3149 + struct tegra_pmc *pmc = data; 3150 + unsigned int i; 3151 + 3152 + /* Check if there are unhandled wake IRQs */ 3153 + for (i = 0; i < pmc->soc->max_wake_vectors; i++) 3154 + if (pmc->wake_status[i]) 3155 + dev_warn(pmc->dev, 3156 + "Unhandled wake IRQs pending vector[%u]: 0x%x\n", 3157 + i, pmc->wake_status[i]); 3158 + 3411 3159 wke_read_sw_wake_status(pmc); 3412 3160 3413 3161 /* flip the wakeup trigger for dual-edge triggered pads ··· 4067 3843 static void tegra186_pmc_init(struct tegra_pmc *pmc) 4068 3844 { 4069 3845 pmc->syscore.ops = &tegra186_pmc_wake_syscore_ops; 3846 + pmc->syscore.data = pmc; 4070 3847 register_syscore(&pmc->syscore); 4071 3848 } 4072 3849
+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;