diff options
Diffstat (limited to 'drivers/clk')
78 files changed, 4445 insertions, 2555 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index fc1e0cf44995..b97974662a1f 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -215,7 +215,7 @@ config CLK_QORIQ config COMMON_CLK_XGENE bool "Clock driver for APM XGene SoC" - default y + default ARCH_XGENE depends on ARM64 || COMPILE_TEST ---help--- Sypport for the APM X-Gene SoC reference, PLL, and device clocks. diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index 4c4bd85f707c..0eb281d597fc 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig @@ -1,3 +1,12 @@ +config CLK_BCM2835 + bool "Broadcom BCM2835 clock support" + depends on ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST + depends on COMMON_CLK + default ARCH_BCM2835 || ARCH_BRCMSTB + help + Enable common clock framework support for Broadcom BCM2835 + SoCs. + config CLK_BCM_63XX bool "Broadcom BCM63xx clock support" depends on ARCH_BCM_63XX || COMPILE_TEST diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 002661d39128..e924f25bc6c8 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile @@ -5,8 +5,8 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o -obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o -obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835-aux.o +obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835.o +obj-$(CONFIG_CLK_BCM2835) += clk-bcm2835-aux.o obj-$(CONFIG_ARCH_BCM_53573) += clk-bcm53573-ilp.o obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygnus.o obj-$(CONFIG_CLK_BCM_HR2) += clk-hr2.o diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c index 02b472a1f9b0..c0cd6a0ff7f8 100644 --- a/drivers/clk/clk-pwm.c +++ b/drivers/clk/clk-pwm.c @@ -47,10 +47,24 @@ static unsigned long clk_pwm_recalc_rate(struct clk_hw *hw, return clk_pwm->fixed_rate; } +static int clk_pwm_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) +{ + struct clk_pwm *clk_pwm = to_clk_pwm(hw); + struct pwm_state state; + + pwm_get_state(clk_pwm->pwm, &state); + + duty->num = state.duty_cycle; + duty->den = state.period; + + return 0; +} + static const struct clk_ops clk_pwm_ops = { .prepare = clk_pwm_prepare, .unprepare = clk_pwm_unprepare, .recalc_rate = clk_pwm_recalc_rate, + .get_duty_cycle = clk_pwm_get_duty_cycle, }; static int clk_pwm_probe(struct platform_device *pdev) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index aa51756fd4d6..09d8e84a1968 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2997,15 +2997,49 @@ static int clk_flags_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(clk_flags); +static void possible_parent_show(struct seq_file *s, struct clk_core *core, + unsigned int i, char terminator) +{ + struct clk_core *parent; + + /* + * Go through the following options to fetch a parent's name. + * + * 1. Fetch the registered parent clock and use its name + * 2. Use the global (fallback) name if specified + * 3. Use the local fw_name if provided + * 4. Fetch parent clock's clock-output-name if DT index was set + * + * This may still fail in some cases, such as when the parent is + * specified directly via a struct clk_hw pointer, but it isn't + * registered (yet). + */ + parent = clk_core_get_parent_by_index(core, i); + if (parent) + seq_printf(s, "%s", parent->name); + else if (core->parents[i].name) + seq_printf(s, "%s", core->parents[i].name); + else if (core->parents[i].fw_name) + seq_printf(s, "<%s>(fw)", core->parents[i].fw_name); + else if (core->parents[i].index >= 0) + seq_printf(s, "%s", + of_clk_get_parent_name(core->of_node, + core->parents[i].index)); + else + seq_puts(s, "(missing)"); + + seq_putc(s, terminator); +} + static int possible_parents_show(struct seq_file *s, void *data) { struct clk_core *core = s->private; int i; for (i = 0; i < core->num_parents - 1; i++) - seq_printf(s, "%s ", core->parents[i].name); + possible_parent_show(s, core, i, ' '); - seq_printf(s, "%s\n", core->parents[i].name); + possible_parent_show(s, core, i, '\n'); return 0; } diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index e695622c5aa5..51f75500ab85 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -78,13 +78,14 @@ static const struct clk_ops clk_busy_divider_ops = { .set_rate = clk_busy_divider_set_rate, }; -struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, void __iomem *reg, u8 shift, u8 width, void __iomem *busy_reg, u8 busy_shift) { struct clk_busy_divider *busy; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; busy = kzalloc(sizeof(*busy), GFP_KERNEL); if (!busy) @@ -107,11 +108,15 @@ struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, busy->div.hw.init = &init; - clk = clk_register(NULL, &busy->div.hw); - if (IS_ERR(clk)) + hw = &busy->div.hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(busy); + return ERR_PTR(ret); + } - return clk; + return hw; } struct clk_busy_mux { @@ -152,13 +157,14 @@ static const struct clk_ops clk_busy_mux_ops = { .set_parent = clk_busy_mux_set_parent, }; -struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, +struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift, u8 width, void __iomem *busy_reg, u8 busy_shift, const char * const *parent_names, int num_parents) { struct clk_busy_mux *busy; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; busy = kzalloc(sizeof(*busy), GFP_KERNEL); if (!busy) @@ -181,9 +187,13 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, busy->mux.hw.init = &init; - clk = clk_register(NULL, &busy->mux.hw); - if (IS_ERR(clk)) + hw = &busy->mux.hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(busy); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index ed1b7e97a0d3..a7b90059716e 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -75,13 +75,14 @@ static const struct clk_ops clk_cpu_ops = { .set_rate = clk_cpu_set_rate, }; -struct clk *imx_clk_cpu(const char *name, const char *parent_name, +struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk *div, struct clk *mux, struct clk *pll, struct clk *step) { struct clk_cpu *cpu; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); if (!cpu) @@ -99,10 +100,13 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name, init.num_parents = 1; cpu->hw.init = &init; + hw = &cpu->hw; - clk = clk_register(NULL, &cpu->hw); - if (IS_ERR(clk)) + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(cpu); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index ce5722732715..287539baa301 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -91,13 +91,14 @@ static const struct clk_ops clk_fixup_div_ops = { .set_rate = clk_fixup_div_set_rate, }; -struct clk *imx_clk_fixup_divider(const char *name, const char *parent, +struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, void __iomem *reg, u8 shift, u8 width, void (*fixup)(u32 *val)) { struct clk_fixup_div *fixup_div; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; if (!fixup) return ERR_PTR(-EINVAL); @@ -120,9 +121,13 @@ struct clk *imx_clk_fixup_divider(const char *name, const char *parent, fixup_div->ops = &clk_divider_ops; fixup_div->fixup = fixup; - clk = clk_register(NULL, &fixup_div->divider.hw); - if (IS_ERR(clk)) + hw = &fixup_div->divider.hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(fixup_div); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 44817c1b0b88..f3c4ec2c2670 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -69,13 +69,14 @@ static const struct clk_ops clk_fixup_mux_ops = { .set_parent = clk_fixup_mux_set_parent, }; -struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, +struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, int num_parents, void (*fixup)(u32 *val)) { struct clk_fixup_mux *fixup_mux; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; if (!fixup) return ERR_PTR(-EINVAL); @@ -98,9 +99,13 @@ struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, fixup_mux->ops = &clk_mux_ops; fixup_mux->fixup = fixup; - clk = clk_register(NULL, &fixup_mux->mux.hw); - if (IS_ERR(clk)) + hw = &fixup_mux->mux.hw; + + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(fixup_mux); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index 3bd9dee618b2..7bd9f1409701 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -58,13 +58,14 @@ static const struct clk_ops clk_gate_exclusive_ops = { .is_enabled = clk_gate_exclusive_is_enabled, }; -struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, +struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, void __iomem *reg, u8 shift, u32 exclusive_mask) { struct clk_gate_exclusive *exgate; struct clk_gate *gate; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; if (exclusive_mask == 0) return ERR_PTR(-EINVAL); @@ -86,9 +87,13 @@ struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, gate->hw.init = &init; exgate->exclusive_mask = exclusive_mask; - clk = clk_register(NULL, &gate->hw); - if (IS_ERR(clk)) - kfree(exgate); + hw = &gate->hw; - return clk; + ret = clk_hw_register(NULL, hw); + if (ret) { + kfree(gate); + return ERR_PTR(ret); + } + + return hw; } diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 60fc9d7a9723..14551fd36ae5 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -125,15 +125,16 @@ static const struct clk_ops clk_gate2_ops = { .is_enabled = clk_gate2_is_enabled, }; -struct clk *clk_register_gate2(struct device *dev, const char *name, +struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 clk_gate2_flags, spinlock_t *lock, unsigned int *share_count) { struct clk_gate2 *gate; - struct clk *clk; + struct clk_hw *hw; struct clk_init_data init; + int ret; gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL); if (!gate) @@ -154,10 +155,13 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, init.num_parents = parent_name ? 1 : 0; gate->hw.init = &init; + hw = &gate->hw; - clk = clk_register(dev, &gate->hw); - if (IS_ERR(clk)) + ret = clk_hw_register(NULL, hw); + if (ret) { kfree(gate); + return ERR_PTR(ret); + } - return clk; + return hw; } diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index 70 |
