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: Store PMC context in clocks

Clocks exposed by the PMC need to reference the PMC context for register
programming. Store a reference to the context in the data structure for
each clock to avoid the need for a global variable.

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

+26 -20
+26 -20
drivers/soc/tegra/pmc.c
··· 202 202 #define TEGRA_SMC_PMC_WRITE 0xbb 203 203 204 204 struct pmc_clk { 205 - struct clk_hw hw; 206 - unsigned long offs; 207 - u32 mux_shift; 208 - u32 force_en_shift; 205 + struct clk_hw hw; 206 + struct tegra_pmc *pmc; 207 + unsigned long offs; 208 + u32 mux_shift; 209 + u32 force_en_shift; 209 210 }; 210 211 211 212 #define to_pmc_clk(_hw) container_of(_hw, struct pmc_clk, hw) 212 213 213 214 struct pmc_clk_gate { 214 - struct clk_hw hw; 215 - unsigned long offs; 216 - u32 shift; 215 + struct clk_hw hw; 216 + struct tegra_pmc *pmc; 217 + unsigned long offs; 218 + u32 shift; 217 219 }; 218 220 219 221 #define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw) ··· 2603 2601 return NOTIFY_OK; 2604 2602 } 2605 2603 2606 - static void pmc_clk_fence_udelay(u32 offset) 2604 + static void pmc_clk_fence_udelay(struct tegra_pmc *pmc, u32 offset) 2607 2605 { 2608 2606 tegra_pmc_readl(pmc, offset); 2609 2607 /* pmc clk propagation delay 2 us */ ··· 2615 2613 struct pmc_clk *clk = to_pmc_clk(hw); 2616 2614 u32 val; 2617 2615 2618 - val = tegra_pmc_readl(pmc, clk->offs) >> clk->mux_shift; 2616 + val = tegra_pmc_readl(clk->pmc, clk->offs) >> clk->mux_shift; 2619 2617 val &= PMC_CLK_OUT_MUX_MASK; 2620 2618 2621 2619 return val; ··· 2626 2624 struct pmc_clk *clk = to_pmc_clk(hw); 2627 2625 u32 val; 2628 2626 2629 - val = tegra_pmc_readl(pmc, clk->offs); 2627 + val = tegra_pmc_readl(clk->pmc, clk->offs); 2630 2628 val &= ~(PMC_CLK_OUT_MUX_MASK << clk->mux_shift); 2631 2629 val |= index << clk->mux_shift; 2632 - tegra_pmc_writel(pmc, val, clk->offs); 2633 - pmc_clk_fence_udelay(clk->offs); 2630 + tegra_pmc_writel(clk->pmc, val, clk->offs); 2631 + pmc_clk_fence_udelay(clk->pmc, clk->offs); 2634 2632 2635 2633 return 0; 2636 2634 } ··· 2640 2638 struct pmc_clk *clk = to_pmc_clk(hw); 2641 2639 u32 val; 2642 2640 2643 - val = tegra_pmc_readl(pmc, clk->offs) & BIT(clk->force_en_shift); 2641 + val = tegra_pmc_readl(clk->pmc, clk->offs) & BIT(clk->force_en_shift); 2644 2642 2645 2643 return val ? 1 : 0; 2646 2644 } 2647 2645 2648 - static void pmc_clk_set_state(unsigned long offs, u32 shift, int state) 2646 + static void pmc_clk_set_state(struct tegra_pmc *pmc, unsigned long offs, 2647 + u32 shift, int state) 2649 2648 { 2650 2649 u32 val; 2651 2650 2652 2651 val = tegra_pmc_readl(pmc, offs); 2653 2652 val = state ? (val | BIT(shift)) : (val & ~BIT(shift)); 2654 2653 tegra_pmc_writel(pmc, val, offs); 2655 - pmc_clk_fence_udelay(offs); 2654 + pmc_clk_fence_udelay(pmc, offs); 2656 2655 } 2657 2656 2658 2657 static int pmc_clk_enable(struct clk_hw *hw) 2659 2658 { 2660 2659 struct pmc_clk *clk = to_pmc_clk(hw); 2661 2660 2662 - pmc_clk_set_state(clk->offs, clk->force_en_shift, 1); 2661 + pmc_clk_set_state(clk->pmc, clk->offs, clk->force_en_shift, 1); 2663 2662 2664 2663 return 0; 2665 2664 } ··· 2669 2666 { 2670 2667 struct pmc_clk *clk = to_pmc_clk(hw); 2671 2668 2672 - pmc_clk_set_state(clk->offs, clk->force_en_shift, 0); 2669 + pmc_clk_set_state(clk->pmc, clk->offs, clk->force_en_shift, 0); 2673 2670 } 2674 2671 2675 2672 static const struct clk_ops pmc_clk_ops = { ··· 2701 2698 CLK_SET_PARENT_GATE; 2702 2699 2703 2700 pmc_clk->hw.init = &init; 2701 + pmc_clk->pmc = pmc; 2704 2702 pmc_clk->offs = offset; 2705 2703 pmc_clk->mux_shift = data->mux_shift; 2706 2704 pmc_clk->force_en_shift = data->force_en_shift; ··· 2712 2708 static int pmc_clk_gate_is_enabled(struct clk_hw *hw) 2713 2709 { 2714 2710 struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); 2711 + u32 value = tegra_pmc_readl(gate->pmc, gate->offs); 2715 2712 2716 - return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0; 2713 + return value & BIT(gate->shift) ? 1 : 0; 2717 2714 } 2718 2715 2719 2716 static int pmc_clk_gate_enable(struct clk_hw *hw) 2720 2717 { 2721 2718 struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); 2722 2719 2723 - pmc_clk_set_state(gate->offs, gate->shift, 1); 2720 + pmc_clk_set_state(gate->pmc, gate->offs, gate->shift, 1); 2724 2721 2725 2722 return 0; 2726 2723 } ··· 2730 2725 { 2731 2726 struct pmc_clk_gate *gate = to_pmc_clk_gate(hw); 2732 2727 2733 - pmc_clk_set_state(gate->offs, gate->shift, 0); 2728 + pmc_clk_set_state(gate->pmc, gate->offs, gate->shift, 0); 2734 2729 } 2735 2730 2736 2731 static const struct clk_ops pmc_clk_gate_ops = { ··· 2758 2753 init.flags = 0; 2759 2754 2760 2755 gate->hw.init = &init; 2756 + gate->pmc = pmc; 2761 2757 gate->offs = offset; 2762 2758 gate->shift = shift; 2763 2759