mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
clk: tegra: Changes for v6.20-rc1
This series updates the Tegra clock driver to improve hardware support and code correctness. Key changes include fixing camera and display clock hierarchies for Tegra20/30 (adding CSI pad gates, reparenting DSI/CSUS), resolving a memory leak in the Tegra124 EMC driver, and optimizing system suspend/resume callbacks to remove redundant runtime PM overhead. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmlsj9AACgkQ3SOs138+ s6EN7w//dYLyM/NEnwmFYs+8TaGJ0VfxTrhs9W3N55E2Q3NPmQ3m4GbBe7IXM2W3 5LnNPwEdCgqadhUbFSCj+0APchm42xIEJNa96VaPEb91NWVUk73WVN1SWctdwyC5 DV6e8fhsgOCv0sI5DpkJ8qOBms3vq0LiIVSCXXjFrUiYF95XAGEENKRHHNj3I7tb Nh3/DjQ95xohbCJxJ8D1KWkZi81LSET3nLO4GSxBHqg/7Hb3dbnRQYK5nnG2QUnk eEbnTr2Nn7MFl04Wp50tor5TTi4levCNfYoU+Gw3KuL+KkmrMgf75mzRDpmD+0h/ KDYqOILwVZVjJdmz02tvrZ5E//MxkCpgeG42k2Kq7Rk2ECXQu6MF0NfUyu+miVVS tjZ+cQJnMRTXpd3dog5vYdcwNSiHitLtVWmPCj8LACFLZQxjfvwYFBiQbeZXdnts 7WjZ8IcUybRf3KLXwpqZLXfiYjky6GVpo8YRag1IrzsIf6AQLRFfVoOIbw9ToGrY SUht6ljmCfoxP0KzcySXxg9gdNWCCnZCfOOss+I7rT4lSGPRwWLxlEaVTFR7fFGm Z87hdH7nS9Zzq3/uorXyCCUoQovAuxyb8H+xv3FSnqX2e4reMk66/mASiyAGaltK Hs1EKrvhfmxm81q2JAALQbQ8eaaUWa1cK2ad7tGUmX6pDSI7dZg= =HyTR -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmlxJiAUHHN3Ym95ZEBj aHJvbWl1bS5vcmcACgkQrQKIl8bklSWNKRAA1AB4NDDoCvLkB7VKwfY8U/102Plj aXkoBPJj0E7zMEBPFmLqbv4K3zh/gdSjBAR55kZYWYRzScUwH4JI/HK/o7OEsa/b ndhePL7ehuVIni3Ga9+70Zh940LcRftRCfOYqs87Zxta74wvl5sopdHnooHuZODS LMOzylOMDKQvJtsrpvq47cGdU+e0Gsw1h6XCS+T2B3qMhU0LpSRIMtmuwiwoVM5k 2YBWHb7gP/dXkSd58o3K8KKVPiQn2+7PlTdhoatjO4p7errLA1QZHFzqpJ4WiWnb Wpav4z5Uq5vWxlo481hRpkbgvewi3DGnbw0pM2EXLYDn4XKwEbKItGI698OJN3EB GMXti5wnx49f4XYSBBSn+UDFlgF9FvyQ7bnuylwCUZxuvjnNZBkil8Ar97lmrGRf 0owptxV6jNmS/8Sfp/N/hYv+WW2qyleMV9fg+FHa5/x0tzLfxko5hxjaf/tI7b6l W6L4cJYJwTHUf2nN+C9/tBVIBlNI6jrJSYtFR0fPGu5BbK179nJY70jQS6A2usEP 0kwuJl0XwZ4Hh5Pvhb6C8w1M6lnZhlKw7WHycZb1BGJOuVoRr1TuTzJJXz46eKzl KpP7GCTNY0v3nlcElI56GctOhoSj/BEdQ8IKtN+AWVJmctLMX6roLoSnwozsMJJu EImeu0e9TSqrsGE= =Nh6Y -----END PGP SIGNATURE----- Merge tag 'for-6.20-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-tegra Pull Tegra clk driver updates from Thierry Reding: This series updates the Tegra clock driver to improve hardware support and code correctness. Key changes include fixing camera and display clock hierarchies for Tegra20/30 (adding CSI pad gates, reparenting DSI/CSUS), resolving a memory leak in the Tegra124 EMC driver, and optimizing system suspend/resume callbacks to remove redundant runtime PM overhead. * tag 'for-6.20-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: clk: tegra30: Add CSI pad clock gates clk: tegra: Set CSUS as vi_sensor's gate for Tegra20, Tegra30 and Tegra114 clk: tegra20: Reparent dsi clock to pll_d_out0 clk: tegra: tegra124-emc: Simplify with scoped for each OF child loop clk: tegra: Adjust callbacks in tegra_clock_pm clk: tegra: tegra124-emc: Fix potential memory leak in tegra124_clk_register_emc()
This commit is contained in:
commit
2d4235b189
|
|
@ -174,8 +174,19 @@ static int tegra_clock_probe(struct platform_device *pdev)
|
|||
* problem. In practice this makes no difference from a power management
|
||||
* perspective since voltage is kept at a nominal level during suspend anyways.
|
||||
*/
|
||||
static inline int tegra_clock_suspend(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops tegra_clock_pm = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_resume_and_get, pm_runtime_put)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(tegra_clock_suspend, NULL)
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_clock_match[] = {
|
||||
|
|
|
|||
|
|
@ -690,7 +690,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
|
|||
[tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true },
|
||||
[tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true },
|
||||
[tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true },
|
||||
[tegra_clk_csus] = { .dt_id = TEGRA114_CLK_CSUS, .present = true },
|
||||
[tegra_clk_mselect] = { .dt_id = TEGRA114_CLK_MSELECT, .present = true },
|
||||
[tegra_clk_tsensor] = { .dt_id = TEGRA114_CLK_TSENSOR, .present = true },
|
||||
[tegra_clk_i2s3] = { .dt_id = TEGRA114_CLK_I2S3, .present = true },
|
||||
|
|
@ -1046,6 +1045,12 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
|
|||
0, 82, periph_clk_enb_refcnt);
|
||||
clks[TEGRA114_CLK_DSIB] = clk;
|
||||
|
||||
/* csus */
|
||||
clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0,
|
||||
clk_base, 0, TEGRA114_CLK_CSUS,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA114_CLK_CSUS] = clk;
|
||||
|
||||
/* emc mux */
|
||||
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
|
|
|
|||
|
|
@ -444,7 +444,6 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
|
|||
u32 ram_code)
|
||||
{
|
||||
struct emc_timing *timings_ptr;
|
||||
struct device_node *child;
|
||||
int child_count = of_get_child_count(node);
|
||||
int i = 0, err;
|
||||
size_t size;
|
||||
|
|
@ -458,12 +457,11 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra,
|
|||
timings_ptr = tegra->timings + tegra->num_timings;
|
||||
tegra->num_timings += child_count;
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
for_each_child_of_node_scoped(node, child) {
|
||||
struct emc_timing *timing = timings_ptr + (i++);
|
||||
|
||||
err = load_one_timing_from_dt(tegra, timing, child);
|
||||
if (err) {
|
||||
of_node_put(child);
|
||||
kfree(tegra->timings);
|
||||
return err;
|
||||
}
|
||||
|
|
@ -538,8 +536,10 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np
|
|||
tegra->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &tegra->hw);
|
||||
if (IS_ERR(clk))
|
||||
if (IS_ERR(clk)) {
|
||||
kfree(tegra);
|
||||
return clk;
|
||||
}
|
||||
|
||||
tegra->prev_parent = clk_hw_get_parent_by_index(
|
||||
&tegra->hw, emc_get_parent(&tegra->hw))->clk;
|
||||
|
|
|
|||
|
|
@ -530,7 +530,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
|
|||
[tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true },
|
||||
[tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true },
|
||||
[tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true },
|
||||
[tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true },
|
||||
[tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true },
|
||||
[tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true },
|
||||
[tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true },
|
||||
|
|
@ -802,9 +801,9 @@ static void __init tegra20_periph_clk_init(void)
|
|||
clks[TEGRA20_CLK_MC] = clk;
|
||||
|
||||
/* dsi */
|
||||
clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,
|
||||
48, periph_clk_enb_refcnt);
|
||||
clk_register_clkdev(clk, NULL, "dsi");
|
||||
clk = tegra_clk_register_periph_gate("dsi", "pll_d_out0", 0,
|
||||
clk_base, 0, TEGRA20_CLK_DSI,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_DSI] = clk;
|
||||
|
||||
/* pex */
|
||||
|
|
@ -834,6 +833,12 @@ static void __init tegra20_periph_clk_init(void)
|
|||
clk_base, 0, 93, periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_CDEV2] = clk;
|
||||
|
||||
/* csus */
|
||||
clk = tegra_clk_register_periph_gate("csus", "csus_mux", 0,
|
||||
clk_base, 0, TEGRA20_CLK_CSUS,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_CSUS] = clk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
|
||||
data = &tegra_periph_clk_list[i];
|
||||
clk = tegra_clk_register_periph_data(clk_base, data);
|
||||
|
|
@ -1093,14 +1098,15 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
|
|||
hw = __clk_get_hw(clk);
|
||||
|
||||
/*
|
||||
* Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent
|
||||
* clock is created by the pinctrl driver. It is possible for clk user
|
||||
* to request these clocks before pinctrl driver got probed and hence
|
||||
* user will get an orphaned clock. That might be undesirable because
|
||||
* user may expect parent clock to be enabled by the child.
|
||||
* Tegra20 CDEV1, CDEV2 and CSUS clocks are a bit special case, their
|
||||
* parent clock is created by the pinctrl driver. It is possible for
|
||||
* clk user to request these clocks before pinctrl driver got probed
|
||||
* and hence user will get an orphaned clock. That might be undesirable
|
||||
* because user may expect parent clock to be enabled by the child.
|
||||
*/
|
||||
if (clkspec->args[0] == TEGRA20_CLK_CDEV1 ||
|
||||
clkspec->args[0] == TEGRA20_CLK_CDEV2) {
|
||||
clkspec->args[0] == TEGRA20_CLK_CDEV2 ||
|
||||
clkspec->args[0] == TEGRA20_CLK_CSUS) {
|
||||
parent_hw = clk_hw_get_parent(hw);
|
||||
if (!parent_hw)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ static unsigned long input_freq;
|
|||
|
||||
static DEFINE_SPINLOCK(cml_lock);
|
||||
static DEFINE_SPINLOCK(pll_d_lock);
|
||||
static DEFINE_SPINLOCK(pll_d2_lock);
|
||||
|
||||
#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \
|
||||
_clk_num, _gate_flags, _clk_id) \
|
||||
|
|
@ -780,7 +781,6 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
|
|||
[tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true },
|
||||
[tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true },
|
||||
[tegra_clk_kbc] = { .dt_id = TEGRA30_CLK_KBC, .present = true },
|
||||
[tegra_clk_csus] = { .dt_id = TEGRA30_CLK_CSUS, .present = true },
|
||||
[tegra_clk_vcp] = { .dt_id = TEGRA30_CLK_VCP, .present = true },
|
||||
[tegra_clk_bsea] = { .dt_id = TEGRA30_CLK_BSEA, .present = true },
|
||||
[tegra_clk_bsev] = { .dt_id = TEGRA30_CLK_BSEV, .present = true },
|
||||
|
|
@ -860,7 +860,7 @@ static void __init tegra30_pll_init(void)
|
|||
|
||||
/* PLLD2 */
|
||||
clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0,
|
||||
&pll_d2_params, NULL);
|
||||
&pll_d2_params, &pll_d2_lock);
|
||||
clks[TEGRA30_CLK_PLL_D2] = clk;
|
||||
|
||||
/* PLLD2_OUT0 */
|
||||
|
|
@ -1009,6 +1009,22 @@ static void __init tegra30_periph_clk_init(void)
|
|||
0, 48, periph_clk_enb_refcnt);
|
||||
clks[TEGRA30_CLK_DSIA] = clk;
|
||||
|
||||
/* csia_pad */
|
||||
clk = clk_register_gate(NULL, "csia_pad", "pll_d", CLK_SET_RATE_PARENT,
|
||||
clk_base + PLLD_BASE, 26, 0, &pll_d_lock);
|
||||
clks[TEGRA30_CLK_CSIA_PAD] = clk;
|
||||
|
||||
/* csib_pad */
|
||||
clk = clk_register_gate(NULL, "csib_pad", "pll_d2", CLK_SET_RATE_PARENT,
|
||||
clk_base + PLLD2_BASE, 26, 0, &pll_d2_lock);
|
||||
clks[TEGRA30_CLK_CSIB_PAD] = clk;
|
||||
|
||||
/* csus */
|
||||
clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0,
|
||||
clk_base, 0, TEGRA30_CLK_CSUS,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA30_CLK_CSUS] = clk;
|
||||
|
||||
/* pcie */
|
||||
clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0,
|
||||
70, periph_clk_enb_refcnt);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user