Lines Matching +full:clkout +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Clock driver for Exynos clock output
11 #include <linux/clk-provider.h>
20 #define DRV_NAME "exynos-clkout"
55 .compatible = "samsung,exynos3250-pmu",
58 .compatible = "samsung,exynos4210-pmu",
61 .compatible = "samsung,exynos4212-pmu",
64 .compatible = "samsung,exynos4412-pmu",
67 .compatible = "samsung,exynos5250-pmu",
70 .compatible = "samsung,exynos5410-pmu",
73 .compatible = "samsung,exynos5420-pmu",
76 .compatible = "samsung,exynos5433-pmu",
90 if (!dev->parent) { in exynos_clkout_match_parent_dev()
92 return -EINVAL; in exynos_clkout_match_parent_dev()
97 * the dev->parent driver, so of_device_get_match_data() or in exynos_clkout_match_parent_dev()
100 match = of_match_device(exynos_clkout_ids, dev->parent); in exynos_clkout_match_parent_dev()
103 return -EINVAL; in exynos_clkout_match_parent_dev()
105 variant = match->data; in exynos_clkout_match_parent_dev()
107 *mux_mask = variant->mux_mask; in exynos_clkout_match_parent_dev()
116 struct exynos_clkout *clkout; in exynos_clkout_probe() local
120 clkout = devm_kzalloc(&pdev->dev, in exynos_clkout_probe()
121 struct_size(clkout, data.hws, EXYNOS_CLKOUT_NR_CLKS), in exynos_clkout_probe()
123 if (!clkout) in exynos_clkout_probe()
124 return -ENOMEM; in exynos_clkout_probe()
126 ret = exynos_clkout_match_parent_dev(&pdev->dev, &mux_mask); in exynos_clkout_probe()
130 clkout->np = pdev->dev.of_node; in exynos_clkout_probe()
131 if (!clkout->np) { in exynos_clkout_probe()
133 * pdev->dev.parent was checked by exynos_clkout_match_parent_dev() in exynos_clkout_probe()
136 clkout->np = pdev->dev.parent->of_node; in exynos_clkout_probe()
139 platform_set_drvdata(pdev, clkout); in exynos_clkout_probe()
141 spin_lock_init(&clkout->slock); in exynos_clkout_probe()
147 snprintf(name, sizeof(name), "clkout%d", i); in exynos_clkout_probe()
148 parents[i] = of_clk_get_by_name(clkout->np, name); in exynos_clkout_probe()
159 return -EINVAL; in exynos_clkout_probe()
161 clkout->reg = of_iomap(clkout->np, 0); in exynos_clkout_probe()
162 if (!clkout->reg) { in exynos_clkout_probe()
163 ret = -ENODEV; in exynos_clkout_probe()
167 clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG; in exynos_clkout_probe()
168 clkout->gate.bit_idx = EXYNOS_CLKOUT_DISABLE_SHIFT; in exynos_clkout_probe()
169 clkout->gate.flags = CLK_GATE_SET_TO_DISABLE; in exynos_clkout_probe()
170 clkout->gate.lock = &clkout->slock; in exynos_clkout_probe()
172 clkout->mux.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG; in exynos_clkout_probe()
173 clkout->mux.mask = mux_mask; in exynos_clkout_probe()
174 clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; in exynos_clkout_probe()
175 clkout->mux.lock = &clkout->slock; in exynos_clkout_probe()
177 clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout", in exynos_clkout_probe()
178 parent_names, parent_count, &clkout->mux.hw, in exynos_clkout_probe()
179 &clk_mux_ops, NULL, NULL, &clkout->gate.hw, in exynos_clkout_probe()
182 if (IS_ERR(clkout->data.hws[0])) { in exynos_clkout_probe()
183 ret = PTR_ERR(clkout->data.hws[0]); in exynos_clkout_probe()
187 clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; in exynos_clkout_probe()
188 ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data); in exynos_clkout_probe()
195 clk_hw_unregister(clkout->data.hws[0]); in exynos_clkout_probe()
197 iounmap(clkout->reg); in exynos_clkout_probe()
203 dev_err(&pdev->dev, "failed to register clkout clock\n"); in exynos_clkout_probe()
210 struct exynos_clkout *clkout = platform_get_drvdata(pdev); in exynos_clkout_remove() local
212 of_clk_del_provider(clkout->np); in exynos_clkout_remove()
213 clk_hw_unregister(clkout->data.hws[0]); in exynos_clkout_remove()
214 iounmap(clkout->reg); in exynos_clkout_remove()
219 struct exynos_clkout *clkout = dev_get_drvdata(dev); in exynos_clkout_suspend() local
221 clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG); in exynos_clkout_suspend()
228 struct exynos_clkout *clkout = dev_get_drvdata(dev); in exynos_clkout_resume() local
230 writel(clkout->pmu_debug_save, clkout->reg + EXYNOS_PMU_DEBUG_REG); in exynos_clkout_resume()
250 MODULE_DESCRIPTION("Samsung Exynos clock output driver");