Unverified Commit 2d4235b1 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'for-6.20-clk' of...

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()
parents 8f0b4cce e897e867
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -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[] = {
+6 −1
Original line number Diff line number Diff line
@@ -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),
+4 −4
Original line number Diff line number Diff line
@@ -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;
+16 −10
Original line number Diff line number Diff line
@@ -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);
+18 −2
Original line number Diff line number Diff line
@@ -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);