diff options
Diffstat (limited to 'drivers/clk')
33 files changed, 613 insertions, 105 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 68ca2d9fcd73..a874b72612d0 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -210,14 +210,14 @@ config COMMON_CLK_OXNAS Support for the OXNAS SoC Family clocks. config COMMON_CLK_VC5 - tristate "Clock driver for IDT VersaClock5 devices" + tristate "Clock driver for IDT VersaClock 5,6 devices" depends on I2C depends on OF select REGMAP_I2C help ---help--- - This driver supports the IDT VersaClock5 programmable clock - generator. + This driver supports the IDT VersaClock 5 and VersaClock 6 + programmable clock generators. source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile index 01996b871b06..d747deafbf1e 100644 --- a/drivers/clk/axs10x/Makefile +++ b/drivers/clk/axs10x/Makefile @@ -1 +1,2 @@ obj-y += i2s_pll_clock.o +obj-y += pll_clock.o diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c new file mode 100644 index 000000000000..25d8c240ddfb --- /dev/null +++ b/drivers/clk/axs10x/pll_clock.c @@ -0,0 +1,346 @@ +/* + * Synopsys AXS10X SDP Generic PLL clock driver + * + * Copyright (C) 2017 Synopsys + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/device.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/slab.h> +#include <linux/of.h> + +/* PLL registers addresses */ +#define PLL_REG_IDIV 0x0 +#define PLL_REG_FBDIV 0x4 +#define PLL_REG_ODIV 0x8 + +/* + * Bit fields of the PLL IDIV/FBDIV/ODIV registers: + * ________________________________________________________________________ + * |31 15| 14 | 13 | 12 |11 6|5 0| + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| + * |____________________|__________|________|______|____________|___________| + * + * Following macros determine the way of access to these registers + * They should be set up only using the macros. + * reg should be an u32 variable. + */ + +#define PLL_REG_GET_LOW(reg) \ + (((reg) & (0x3F << 0)) >> 0) +#define PLL_REG_GET_HIGH(reg) \ + (((reg) & (0x3F << 6)) >> 6) +#define PLL_REG_GET_EDGE(reg) \ + (((reg) & (BIT(12))) ? 1 : 0) +#define PLL_REG_GET_BYPASS(reg) \ + (((reg) & (BIT(13))) ? 1 : 0) +#define PLL_REG_GET_NOUPD(reg) \ + (((reg) & (BIT(14))) ? 1 : 0) +#define PLL_REG_GET_PAD(reg) \ + (((reg) & (0x1FFFF << 15)) >> 15) + +#define PLL_REG_SET_LOW(reg, value) \ + { reg |= (((value) & 0x3F) << 0); } +#define PLL_REG_SET_HIGH(reg, value) \ + { reg |= (((value) & 0x3F) << 6); } +#define PLL_REG_SET_EDGE(reg, value) \ + { reg |= (((value) & 0x01) << 12); } +#define PLL_REG_SET_BYPASS(reg, value) \ + { reg |= (((value) & 0x01) << 13); } +#define PLL_REG_SET_NOUPD(reg, value) \ + { reg |= (((value) & 0x01) << 14); } +#define PLL_REG_SET_PAD(reg, value) \ + { reg |= (((value) & 0x1FFFF) << 15); } + +#define PLL_LOCK BIT(0) +#define PLL_ERROR BIT(1) +#define PLL_MAX_LOCK_TIME 100 /* 100 us */ + +struct axs10x_pll_cfg { + u32 rate; + u32 idiv; + u32 fbdiv; + u32 odiv; +}; + +static const struct axs10x_pll_cfg arc_pll_cfg[] = { + { 33333333, 1, 1, 1 }, + { 50000000, 1, 30, 20 }, + { 75000000, 2, 45, 10 }, + { 90000000, 2, 54, 10 }, + { 100000000, 1, 30, 10 }, + { 125000000, 2, 45, 6 }, + {} +}; + +static const struct axs10x_pll_cfg pgu_pll_cfg[] = { + { 25200000, 1, 84, 90 }, + { 50000000, 1, 100, 54 }, + { 74250000, 1, 44, 16 }, + {} +}; + +struct axs10x_pll_clk { + struct clk_hw hw; + void __iomem *base; + void __iomem *lock; + const struct axs10x_pll_cfg *pll_cfg; + struct device *dev; +}; + +static inline void axs10x_pll_write(struct axs10x_pll_clk *clk, u32 reg, + u32 val) +{ + iowrite32(val, clk->base + reg); +} + +static inline u32 axs10x_pll_read(struct axs10x_pll_clk *clk, u32 reg) +{ + return ioread32(clk->base + reg); +} + +static inline struct axs10x_pll_clk *to_axs10x_pll_clk(struct clk_hw *hw) +{ + return container_of(hw, struct axs10x_pll_clk, hw); +} + +static inline u32 axs10x_div_get_value(u32 reg) +{ + if (PLL_REG_GET_BYPASS(reg)) + return 1; + + return PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg); +} + +static inline u32 axs10x_encode_div(unsigned int id, int upd) +{ + u32 div = 0; + + PLL_REG_SET_LOW(div, (id % 2 == 0) ? id >> 1 : (id >> 1) + 1); + PLL_REG_SET_HIGH(div, id >> 1); + PLL_REG_SET_EDGE(div, id % 2); + PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); + PLL_REG_SET_NOUPD(div, upd == 0 ? 1 : 0); + + return div; +} + +static unsigned long axs10x_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + u64 rate; + u32 idiv, fbdiv, odiv; + struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); + + idiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_IDIV)); + fbdiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_FBDIV)); + odiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_ODIV)); + + rate = (u64)parent_rate * fbdiv; + do_div(rate, idiv * odiv); + + return rate; +} + +static long axs10x_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + int i; + long best_rate; + struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); + const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg; + + if (pll_cfg[0].rate == 0) + return -EINVAL; + + best_rate = pll_cfg[0].rate; + + for (i = 1; pll_cfg[i].rate != 0; i++) { + if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) + best_rate = pll_cfg[i].rate; + } + + return best_rate; +} + +static int axs10x_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + int i; + struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); + const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg; + + for (i = 0; pll_cfg[i].rate != 0; i++) { + if (pll_cfg[i].rate == rate) { + axs10x_pll_write(clk, PLL_REG_IDIV, + axs10x_encode_div(pll_cfg[i].idiv, 0)); + axs10x_pll_write(clk, PLL_REG_FBDIV, + axs10x_encode_div(pll_cfg[i].fbdiv, 0)); + axs10x_pll_write(clk, PLL_REG_ODIV, + axs10x_encode_div(pll_cfg[i].odiv, 1)); + + /* + * Wait until CGU relocks and check error status. + * If after timeout CGU is unlocked yet return error + */ + udelay(PLL_MAX_LOCK_TIME); + if (!(ioread32(clk->lock) & PLL_LOCK)) + return -ETIMEDOUT; + + if (ioread32(clk->lock) & PLL_ERROR) + return -EINVAL; + + return 0; + } + } + + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, + parent_rate); + return -EINVAL; +} + +static const struct clk_ops axs10x_pll_ops = { + .recalc_rate = axs10x_pll_recalc_rate, + .round_rate = axs10x_pll_round_rate, + .set_rate = axs10x_pll_set_rate, +}; + +static int axs10x_pll_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const char *parent_name; + struct axs10x_pll_clk *pll_clk; + struct resource *mem; + struct clk_init_data init = { }; + int ret; + + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) + return -ENOMEM; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pll_clk->base = devm_ioremap_resource(dev, mem); + if (IS_ERR(pll_clk->base)) + return PTR_ERR(pll_clk->base); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + pll_clk->lock = devm_ioremap_resource(dev, mem); + if (IS_ERR(pll_clk->lock)) + return PTR_ERR(pll_clk->lock); + + init.name = dev->of_node->name; + init.ops = &axs10x_pll_ops; + parent_name = of_clk_get_parent_name(dev->of_node, 0); + init.parent_names = &parent_name; + init.num_parents = 1; + pll_clk->hw.init = &init; + pll_clk->dev = dev; + pll_clk->pll_cfg = of_device_get_match_data(dev); + + if (!pll_clk->pll_cfg) { + dev_err(dev, "No OF match data provided\n"); + return -EINVAL; + } + + ret = devm_clk_hw_register(dev, &pll_clk->hw); + if (ret) { + dev_err(dev, "failed to register %s clock\n", init.name); + return ret; + } + + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, + &pll_clk->hw); +} + +static int axs10x_pll_clk_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + return 0; +} + +static void __init of_axs10x_pll_clk_setup(struct device_node *node) +{ + const char *parent_name; + struct axs10x_pll_clk *pll_clk; + struct clk_init_data init = { }; + int ret; + + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) + return; + + pll_clk->base = of_iomap(node, 0); + if (!pll_clk->base) { + pr_err("failed to map pll div registers\n"); + goto err_free_pll_clk; + } + + pll_clk->lock = of_iomap(node, 1); + if (!pll_clk->lock) { + pr_err("failed to map pll lock register\n"); + goto err_unmap_base; + } + + init.name = node->name; + init.ops = &axs10x_pll_ops; + parent_name = of_clk_get_parent_name(node, 0); + init.parent_names = &parent_name; + init.num_parents = parent_name ? 1 : 0; + pll_clk->hw.init = &init; + pll_clk->pll_cfg = arc_pll_cfg; + + ret = clk_hw_register(NULL, &pll_clk->hw); + if (ret) { + pr_err("failed to register %s clock\n", node->name); + goto err_unmap_lock; + } + + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); + if (ret) { + pr_err("failed to add hw provider for %s clock\n", node->name); + goto err_unregister_clk; + } + + return; + +err_unregister_clk: + clk_hw_unregister(&pll_clk->hw); +err_unmap_lock: + iounmap(pll_clk->lock); +err_unmap_base: + iounmap(pll_clk->base); +err_free_pll_clk: + kfree(pll_clk); +} +CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", + of_axs10x_pll_clk_setup); + +static const struct of_device_id axs10x_pll_clk_id[] = { + { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_cfg}, + { } +}; +MODULE_DEVICE_TABLE(of, axs10x_pll_clk_id); + +static struct platform_driver axs10x_pll_clk_driver = { + .driver = { + .name = "axs10x-pll-clock", + .of_match_table = axs10x_pll_clk_id, + }, + .probe = axs10x_pll_clk_probe, + .remove = axs10x_pll_clk_remove, +}; +builtin_platform_driver(axs10x_pll_clk_driver); + +MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>"); +MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index 1d99292e2039..e7331ace0337 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c @@ -679,8 +679,7 @@ static void __init berlin2_clock_setup(struct device_node *np) if (!IS_ERR(hws[n])) continue; - pr_err("%s: Unable to register leaf clock %d\n", - np->full_name, n); + pr_err("%pOF: Unable to register leaf clock %d\n", np, n); goto bg2_fail; } diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 3b784b593afd..67c270b143f7 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -304,14 +304,14 @@ static void __init berlin2q_clock_setup(struct device_node *np) gbase = of_iomap(parent_np, 0); if (!gbase) { - pr_err("%s: Unable to map global base\n", np->full_name); + pr_err("%pOF: Unable to map global base\n", np); return; } /* BG2Q CPU PLL is not part of global registers */ cpupll_base = of_iomap(parent_np, 1); if (!cpupll_base) { - pr_err("%s: Unable to map cpupll base\n", np->full_name); + pr_err("%pOF: Unable to map cpupll base\n", np); iounmap(gbase); return; } @@ -376,8 +376,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) if (!IS_ERR(hws[n])) continue; - pr_err("%s: Unable to register leaf clock %d\n", - np->full_name, n); + pr_err("%pOF: Unable to register leaf clock %d\n", np, n); goto bg2q_fail; } diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index ea8568536193..bf0582cbbf38 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c @@ -338,8 +338,8 @@ static void __init asm9260_acc_init(struct device_node *np) if (!IS_ERR(hws[n])) continue; - pr_err("%s: Unable to register leaf clock %d\n", - np->full_name, n); + pr_err("%pOF: Unable to register leaf clock %d\n", + np, n); goto fail; } diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 7ec36722f8ab..49819b546134 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c @@ -23,8 +23,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) num_parents = of_count_phandle_with_args(node, "assigned-clock-parents", "#clock-cells"); if (num_parents == -EINVAL) - pr_err("clk: invalid value of clock-parents property at %s\n", - node->full_name); + pr_err("clk: invalid value of clock-parents property at %pOF\n", + node); for (index = 0; index < num_parents; index++) { rc = of_parse_phandle_with_args(node, "assigned-clock-parents", @@ -41,8 +41,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) pclk = of_clk_get_from_provider(&clkspec); if (IS_ERR(pclk)) { if (PTR_ERR(pclk) != -EPROBE_DEFER) - pr_warn("clk: couldn't get parent clock %d for %s\n", - index, node->full_name); + pr_warn("clk: couldn't get parent clock %d for %pOF\n", + index, node); return PTR_ERR(pclk); } @@ -57,8 +57,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) clk = of_clk_get_from_provider(&clkspec); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) - pr_warn("clk: couldn't get assigned clock %d for %s\n", - index, node->full_name); + pr_warn("clk: couldn't get assigned clock %d for %pOF\n", + index, node); rc = PTR_ERR(clk); goto err; } @@ -102,8 +102,8 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) clk = of_clk_get_from_provider(&clkspec); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) - pr_warn("clk: couldn't get clock %d for %s\n", - index, node->full_name); + pr_warn("clk: couldn't get clock %d for %pOF\n", + index, node); return PTR_ERR(clk); } diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index c391a49aaaff..b4cf2f699a21 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -237,6 +237,18 @@ static int gemini_reset(struct reset_controller_dev *rcdev, BIT(GEMINI_RESET_CPU1) | BIT(id)); } +static int gemini_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return 0; +} + +static int gemini_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return 0; +} + static int gemini_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { @@ -253,6 +265,8 @@ static int gemini_reset_status(struct reset_controller_dev *rcdev, static const struct reset_control_ops gemini_reset_ops = { .reset = gemini_reset, + .assert = gemini_reset_assert, + .deassert = gemini_reset_deassert, .status = gemini_reset_status, }; diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c index b86dac851116..58428d0043fd 100644 --- a/drivers/clk/clk-moxart.c +++ b/drivers/clk/clk-moxart.c @@ -18,7 +18,7 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) { - static void __iomem *base; + void __iomem *base; struct clk_hw *hw; struct clk *ref_clk; unsigned int mul; @@ -30,7 +30,7 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) base = of_iomap(node, 0); if (!base) { - pr_err("%s: of_iomap failed\n", node->full_name); + pr_err("%pOF: of_iomap failed\n", node); return; } @@ -39,13 +39,13 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) ref_clk = of_clk_get(node, 0); if (IS_ERR(ref_clk)) { - pr_err("%s: of_clk_get failed\n", node->full_name); + pr_err("%pOF: of_clk_get failed\n", node); return; } hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); if (IS_ERR(hw)) { - pr_err("%s: failed to register clock\n", node->full_name); + pr_err("%pOF: failed to register clock\n", node); return; } @@ -57,7 +57,7 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", static void __init moxart_of_apb_clk_init(struct device_node *node) { - static void __iomem *base; + void __iomem *base; struct clk_hw *hw; struct clk *pll_clk; unsigned int div, val; @@ -70,7 +70,7 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) base = of_iomap(node, 0); if (!base) { - pr_err("%s: of_iomap failed\n", node->full_name); + pr_err("%pOF: of_iomap failed\n", node); return; } @@ -83,13 +83,13 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) pll_clk = of_clk_get(node, 0); if (IS_ERR(pll_clk)) { - pr_err("%s: of_clk_get failed\n", node->full_name); + pr_err("%pOF: of_clk_get failed\n", node); return; } hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); if (IS_ERR(hw)) { - pr_err("%s: failed to register clock\n", node->full_name); + pr_err("%pOF: failed to register clock\n", node); return; } diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index f3931e38fac0..b0ea753b8709 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -12,6 +12,7 @@ #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/clkdev.h> #include <linux/fsl/guts.h> #include <linux/io.h> #include <linux/kernel.h> @@ -537,6 +538,17 @@ static const struct clockgen_chipinfo chipinfo[] = { .flags = CG_PLL_8BIT, }, { + .compat = "fsl,ls1088a-clockgen", + .cmux_groups = { + &clockgen2_cmux_cga12 + }, + .cmux_to_group = { + 0, 0, -1 + }, + .pll_mask = 0x07, + .flags = CG_VER3 | CG_LITTLE_ENDIAN, + }, + { .compat = "fsl,ls1012a-clockgen", .cmux_groups = { &ls1012a_cmux @@ -1113,6 +1125,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx) for (i = 0; i < ARRAY_SIZE(pll->div); i++) { struct clk *clk; + int ret; snprintf(pll->div[i].name, sizeof(pll->div[i].name), "cg-pll%d-div%d", idx, i + 1); @@ -1126,6 +1139,11 @@ static void __init create_one_pll(struct clockgen *cg, int idx) } pll->div[i].clk = clk; + ret = clk_register_clkdev(clk, pll->div[i].name, NULL); + if (ret != 0) + pr_err("%s: %s: register to lookup table failed %ld\n", + __func__, pll->div[i].name, PTR_ERR(clk)); + } } @@ -1348,8 +1366,7 @@ static void __init clockgen_init(struct device_node *np) } if (i == ARRAY_SIZE(chipinfo)) { - pr_err("%s: unknown clockgen node %s\n", __func__, - np->full_name); + pr_err("%s: unknown clockgen node %pOF\n", __func__, np); goto err; } clockgen.info = chipinfo[i]; @@ -1362,8 +1379,8 @@ static void __init clockgen_init(struct device_node *np) if (guts) { clockgen.guts = of_iomap(guts, 0); if (!clockgen.guts) { - pr_err("%s: Couldn't map %s regs\n", __func__, - guts->full_name); + pr_err("%s: Couldn't map %pOF regs\n", __func__, + guts); } } @@ -1398,6 +1415,7 @@ CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); /* Legacy nodes */ diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 68e2a4e499f1..96c6b6bc8f0e 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -1541,8 +1541,8 @@ static void __init stm32f4_rcc_init(struct device_node *np) base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock); if (IS_ERR(clks[idx])) { - pr_err("%s: Unable to register leaf clock %s\n", - np->full_name, gd->name); + pr_err("%pOF: Unable to register leaf clock %s\n", + np, gd->name); goto fail; } } diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index ea7d552a2f2b..decffb3826ec 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -57,6 +57,7 @@ #define VC5_PRIM_SRC_SHDN 0x10 #define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7) #define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6) +#define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ BIT(3) #define VC5_PRIM_SRC_SHDN_SP BIT(1) #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0) @@ -122,12 +123,16 @@ /* flags to describe chip features */ /* chip has built-in oscilator */ #define VC5_HAS_INTERNAL_XTAL BIT(0) +/* chip has PFD requency doubler */ +#define VC5_HAS_PFD_FREQ_DBL BIT(1) /* Supported IDT VC5 models. */ enum vc5_model { IDT_VC5_5P49V5923, + IDT_VC5_5P49V5925, IDT_VC5_5P49V5933, IDT_VC5_5P49V5935, + IDT_VC6_5P49V6901, }; /* Structure to describe features of a particular VC5 model */ @@ -157,6 +162,8 @@ struct vc5_driver_data { struct clk *pin_clkin; unsigned char clk_mux_ins; struct clk_hw clk_mux; + struct clk_hw clk_mul; + struct clk_hw clk_pfd; struct vc5_hw_data clk_pll; struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM]; struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; @@ -166,6 +173,14 @@ static const char * const vc5_mux_names[] = { "mux" }; +static const char * const vc5_dbl_names[] = { + "dbl" +}; + +static const char * const vc5_pfd_names[] = { + "pfd" +}; + static const char * const vc5_pll_names[] = { "pll" }; @@ -254,11 +269,64 @@ static int vc5_mux_set_parent(struct clk_hw *hw, u8 index) return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src); } -static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw, +static const struct clk_ops vc5_mux_ops = { + .set_parent = vc5_mux_set_parent, + .get_parent = vc5_mux_get_parent, +}; + +static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct vc5_driver_data *vc5 = - container_of(hw, struct vc5_driver_data, clk_mux); + container_of(hw, struct vc5_driver_data, clk_mul); + unsigned int premul; + + regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul); + if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ) + parent_rate *= 2; + + return parent_rate; +} + +static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + if ((*parent_rate == rate) || ((*parent_rate * 2) == rate)) + return rate; + else + return -EINVAL; +} + +static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct vc5_driver_data *vc5 = + container_of(hw, struct vc5_driver_data, clk_mul); + u32 mask; + + if ((parent_rate * 2) == rate) + mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ; + else + mask = 0; + + regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, + VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ, + mask); + + return 0; +} + +static const struct clk_ops vc5_dbl_ops = { + .recalc_rate = vc5_dbl_recalc_rate, + .round_rate = vc5_dbl_round_rate, + .set_rate = vc5_dbl_set_rate, +}; + +static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct vc5_driver_data *vc5 = + container_of(hw, struct vc5_driver_data, clk_pfd); unsigned int prediv, div; regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv); @@ -276,7 +344,7 @@ static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw, return parent_rate / VC5_REF_DIVIDER_REF_DIV(div); } -static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, +static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { unsigned long idiv; @@ -296,11 +364,11 @@ static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, return *parent_rate / idiv; } -static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, +static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct vc5_driver_data *vc5 = - container_of(hw, struct vc5_driver_data, clk_mux); + container_of(hw, struct vc5_driver_data, clk_pfd); unsigned long idiv; u8 div; @@ -328,12 +396,10 @@ static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static const struct clk_ops vc5_mux_ops = { - .set_parent = vc5_mux_set_parent, - .get_parent = vc5_mux_get_parent, - .recalc_rate = vc5_mux_recalc_rate, - .round_rate = vc5_mux_round_rate, - .set_rate = vc5_mux_set_rate, +static const struct clk_ops vc5_pfd_ops = { + .recalc_rate = vc5_pfd_recalc_rate, + .round_rate = vc5_pfd_round_rate, + .set_rate = vc5_pfd_set_rate, }; /* @@ -426,6 +492,10 @@ static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw, div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) | (od_frc[2] << 6) | (od_frc[3] >> 2); + /* Avoid division by zero if the output is not configured. */ + if (div_int == 0 && div_frc == 0) + return 0; + /* The PLL divider has 12 integer bits and 30 fractional bits */ return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); } @@ -503,6 +573,25 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) { struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); struct vc5_driver_data *vc5 = hwdata->vc5; + const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM | + VC5_OUT_DIV_CONTROL_SEL_EXT | + VC5_OUT_DIV_CONTROL_EN_FOD; + unsigned int src; + int ret; + + /* + * If the input mux is disabled, enable it first and + * select source from matching FOD. + */ + regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); + if ((src & mask) == 0) { + src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD; + ret = regmap_update_bits(vc5->regmap, + VC5_OUT_DIV_CONTROL(hwdata->num), + mask | VC5_OUT_DIV_CONTROL_RESET, src); + if (ret) + return ret; + } /* Enable the clock buffer */ regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), @@ -516,7 +605,7 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw) struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); struct vc5_driver_data *vc5 = hwdata->vc5; - /* Enable the clock buffer */ + /* Disable the clock buffer */ regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0); } @@ -537,6 +626,9 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw) regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); src &= mask; + if (src == 0) /* Input mux set to DISABLED */ + return 0; + if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD) return 0; @@ -595,7 +687,9 @@ static int vc5_map_index_to_output(const enum vc5_model model, case IDT_VC5_5P49V5933: return (n == 0) ? 0 : 3; case IDT_VC5_5P49V5923: + case IDT_VC5_5P49V5925: case IDT_VC5_5P49V5935: + case IDT_VC6_5P49V6901: default: return n; } @@ -672,12 +766,46 @@ static int vc5_probe(struct i2c_client *client, goto err_clk; } + if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) { + /* Register frequency doubler */ + memset(&init, 0, sizeof(init)); + init.name = vc5_dbl_names[0]; + init.ops = &vc5_dbl_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = vc5_mux_names; + init.num_parents = 1; + vc5->clk_mul.init = &init; + ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul); + if (ret) { + dev_err(&client->dev, "unable to register %s\n", + init.name); + goto err_clk; + } + } + + /* Register PFD */ + memset(&init, 0, sizeof(init)); + init.name = vc5_pfd_names[0]; + init.ops = &vc5_pfd_ops; + init.flags = CLK_SET_RATE_PARENT; + if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) + init.parent_names = vc5_dbl_names; + else + init.parent_names = vc5_mux_names; + init.num_parents = 1; + vc5->clk_pfd.init = &init; + ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd); + if (ret) { + dev_err(&client->dev, "unable to register %s\n", init.name); + goto err_clk; + } + /* Register PLL */ memset(&init, 0, sizeof(init)); init.name = vc5_pll_names[0]; init.ops = &vc5_pll_ops; init.flags = CLK_SET_RATE_PARENT; - init.parent_names = vc5_mux_names; + init.parent_names = vc5_pfd_names; init.num_parents = 1; vc5->clk_pll.num = 0; vc5->clk_pll.vc5 = vc5; @@ -785,6 +913,13 @@ static const struct vc5_chip_info idt_5p49v5923_info = { .flags = 0, }; +static const struct vc5_chip_info idt_5p49v5925_info = { + .model = IDT_VC5_5P49V5925, + .clk_fod_cnt = 4, + .clk_out_cnt = 5, + .flags = 0, +}; + static const struct vc5_chip_info idt_5p49v5933_info = { .model = IDT_VC5_5P49V5933, .clk_fod_cnt = 2, @@ -799,18 +934,29 @@ static const struct vc5_chip_info idt_5p49v5935_info = { .flags = VC5_HAS_INTERNAL_XTAL, }; +static const struct vc5_chip_info idt_5p49v6901_info = { + .model = IDT_VC6_5P49V6901, + .clk_fod_cnt = 4, + .clk_out_cnt = 5, + .flags = VC5_HAS_PFD_FREQ_DBL, +}; + static const struct i2c_device_id vc5_id[] = { { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 }, + { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 }, { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 }, { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 }, + { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 }, { } }; MODULE_DEVICE_TABLE(i2c, vc5_id); static const struct of_device_id clk_vc5_of_match[] = { { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info }, + { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info }, { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info }, { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info }, + { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info }, { }, }; MODULE_DEVICE_TABLE(of, clk_vc5_of_match); diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index bc37030e38ba..4c75821a3933 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -192,7 +192,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty reg = of_iomap(np, 0); if (reg == NULL) { - pr_err("Unable to map CSR register for %s\n", np->full_name); + pr_err("Unable to map CSR register for %pOF\n", np); return; } of_property_read_string(np, "clock-output-names", &clk_name); @@ -409,12 +409,12 @@ static void xgene_pmdclk_init(struct device_node *np) /* Parse the DTS register for resource */ rc = of_address_to_resource(np, 0, &res); if (rc != 0) { - pr_err("no DTS register for %s\n", np->full_name); + pr_err("no DTS register for %pOF\n", np); return; } csr_reg = of_iomap(np, 0); if (!csr_reg) { - pr_err("Unable to map resource for %s\n", np->full_name); + pr_err("Unable to map resource for %pOF\n", np); return; } of_property_read_string(np, "clock-output-names", &clk_name); @@ -703,16 +703,14 @@ static void __init xgene_devclk_init(struct device_node *np) rc = of_address_to_resource(np, i, &res); if (rc != 0) { if (i == 0) { - pr_err("no DTS register for %s\n", - np->full_name); + pr_err("no DTS register for %pOF\n", np); return; } break; } map_res = of_iomap(np, i); if (map_res == NULL) { - pr_err("Unable to map resource %d for %s\n", - i, np->full_name); + pr_err("Unable to map resource %d for %pOF\n", i, np); goto err; } if (strcmp(res.name, "div-reg") == 0) @@ -747,8 +745,7 @@ static void __init xgene_devclk_init(struct device_node *np) pr_debug("Add %s clock\n", clk_name); rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); if (rc != 0) - pr_err("%s: could register provider clk %s\n", __func__, - np->full_name); + pr_err("%s: could register provider clk %pOF\n", __func__, np); return; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fc58c52a26b4..c8d83acda006 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3132,7 +3132,7 @@ int of_clk_add_provider(struct device_node *np, mutex_lock(&of_clk_mutex); list_add(&cp->link, &of_clk_providers); mutex_unlock(&of_clk_mutex); - pr_debug("Added clock from %s\n", np->full_name); + pr_debug("Added clock from %pOF\n", np); ret = of_clk_set_defaults(np, true); if (ret < 0) @@ -3167,7 +3167,7 @@ int of_clk_add_hw_provider(struct device_node *np, mutex_lock(&of_clk_mutex); list_add(&cp->link, &of_clk_providers); mutex_unlock(&of_clk_mutex); - pr_debug("Added clk_hw provider from %s\n", np->full_name); + pr_debug("Added clk_hw provider from %pOF\n", np); ret = of_clk_set_defaults(np, true); if (ret < 0) diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index bb8a77a5985f..6b2f29df3f70 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -77,8 +77,8 @@ static struct clk *__of_clk_get_by_name(struct device_node *np, break; } else if (name && index >= 0) { if (PTR_ERR(clk) != -EPROBE_DEFER) - pr_err("ERROR: could not get clock %s:%s(%i)\n", - np->full_name, name ? name : "", index); + pr_err("ERROR: could not get clock %pOF:%s(%i)\n", + np, name ? name : "", index); return clk; } diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index edd8e6918050..16e56772d280 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -27,7 +27,6 @@ static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw) static u8 clk_cpumux_get_parent(struct clk_hw *hw) { struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); - int num_parents = clk_hw_get_num_parents(hw); unsigned int val; regmap_read(mux->regmap, mux->reg, &val); @@ -35,9 +34,6 @@ static u8 clk_cpumux_get_parent(struct clk_hw *hw) val >>= mux->shift; val &= mux->mask; - if (val >= num_parents) - return -EINVAL; - return val; } @@ -98,7 +94,7 @@ int __init mtk_clk_register_cpumuxes(struct device_node *node, regmap = syscon_node_to_regmap(node); if (IS_ERR(regmap)) { - pr_err("Cannot find regmap for %s: %ld\n", node->full_name, + pr_err("Cannot find regmap for %pOF: %ld\n", node, PTR_ERR(regmap)); return PTR_ERR(regmap); } diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 0541df78141c..9c0ae4278a94 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -114,7 +114,7 @@ int mtk_clk_register_gates(struct device_node *node, regmap = syscon_node_to_regmap(node); if (IS_ERR(regmap)) { - pr_err("Cannot find regmap for %s: %ld\n", node->full_name, + pr_err("Cannot find regmap for %pOF: %ld\n", node, PTR_ERR(regmap)); return PTR_ERR(regmap); } diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index 309049d41f1b..d3551d5efef2 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -72,7 +72,7 @@ void mtk_register_reset_controller(struct device_node *np, regmap = syscon_node_to_regmap(np); if (IS_ERR(regmap)) { - pr_err("Cannot find regmap for %s: %ld\n", np->full_name, + pr_err("Cannot find regmap for %pOF: %ld\n", np, PTR_ERR(regmap)); return; } diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c index 61893fe73251..089927e4cda2 100644 --- a/drivers/clk/mmp/clk.c +++ b/drivers/clk/mmp/clk.c @@ -9,7 +9,7 @@ void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, int nr_clks) { - static struct clk **clk_table; + struct clk **clk_table; clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); if (!clk_table) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index d990fe44aef3..cc03d5508627 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -412,8 +412,6 @@ static const struct clk_ops clk_smd_rpm_ops = { static const struct clk_ops clk_smd_rpm_branch_ops = { .prepare = clk_smd_rpm_prepare, .unprepare = clk_smd_rpm_unprepare, - .round_rate = clk_smd_rpm_round_rate, - .recalc_rate = clk_smd_rpm_recalc_rate, }; /* msm8916 */ diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index f1617dd044cb..500a9e4e03c4 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -335,7 +335,7 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np) u32 ncells; if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { - pr_warn("%s lacks #power-domain-cells\n", np->full_name); + pr_warn("%pOF lacks #power-domain-cells\n", np); return; } diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 51a2479ed5d7..0b2e56d0d94b 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -407,8 +407,7 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) if (rcar_rst_read_mode_pins(&cpg_mode)) { /* Backward-compatibility with old DT */ - pr_warn("%s: failed to obtain mode pins from RST\n", - np->full_name); + pr_warn("%pOF: failed to obtain mode pins from RST\n", np); cpg_mode = rcar_gen2_read_mode_pins(); } diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index 5372bf8be5e6..194d7bfffa53 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c @@ -976,8 +976,7 @@ static void __init sun5i_ccu_init(struct device_node *node, reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 4d6078fca9ac..8af434815fba 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -1217,8 +1217,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index 8a753ed0426d..d93b452f0df9 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c @@ -716,8 +716,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 10b38dc46f75..13eb5b23c5e7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c @@ -777,8 +777,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 62e4f0d2b2fc..d1ab0d713fa6 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -1118,8 +1118,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index e54816ec1dbe..71feb7b24e8a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c @@ -290,8 +290,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index a34a78d7fb28..621b1cd996db 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -575,8 +575,7 @@ static void __init sun8i_v3s_ccu_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("%s: Could not map the clock registers\n", - of_node_full_name(node)); + pr_err("%pOF: Could not map the clock registers\n", node); return; } diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index f2c9274b8bd5..aa4add580516 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -666,15 +666,14 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, reg = of_iomap(node, 0); if (!reg) { - pr_err("Could not map registers for mux-clk: %s\n", - of_node_full_name(node)); + pr_err("Could not map registers for mux-clk: %pOF\n", node); return NULL; } i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); if (of_property_read_string(node, "clock-output-names", &clk_name)) { - pr_err("%s: could not read clock-output-names from \"%s\"\n", - __func__, of_node_full_name(node)); + pr_err("%s: could not read clock-output-names from \"%pOF\"\n", + __func__, node); goto out_unmap; } @@ -797,16 +796,15 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, reg = of_iomap(node, 0); if (!reg) { - pr_err("Could not map registers for mux-clk: %s\n", - of_node_full_name(node)); + pr_err("Could not map registers for mux-clk: %pOF\n", node); return; } clk_parent = of_clk_get_parent_name(node, 0); if (of_property_read_string(node, "clock-output-names", &clk_name)) { - pr_err("%s: could not read clock-output-names from \"%s\"\n", - __func__, of_node_full_name(node)); + pr_err("%s: could not read clock-output-names from \"%pOF\"\n", + __func__, node); goto out_unmap; } @@ -1010,8 +1008,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, reg = of_iomap(node, 0); if (!reg) { - pr_err("Could not map registers for divs-clk: %s\n", - of_node_full_name(node)); + pr_err("Could not map registers for divs-clk: %pOF\n", node); return NULL; } diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index 74e7544f861b..11a5066e5c27 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c @@ -378,7 +378,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, err = of_property_read_u32(node, "clock-frequency", &tmp); if (err) { - pr_err("timing %s: failed to read rate\n", node->full_name); + pr_err("timing %pOF: failed to read rate\n", node); return err; } @@ -386,8 +386,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp); if (err) { - pr_err("timing %s: failed to read parent rate\n", - node->full_name); + pr_err("timing %pOF: failed to read parent rate\n", node); return err; } @@ -395,8 +394,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, timing->parent = of_clk_get_by_name(node, "emc-parent"); if (IS_ERR(timing->parent)) { - pr_err("timing %s: failed to get parent clock\n", - node->full_name); + pr_err("timing %pOF: failed to get parent clock\n", node); return PTR_ERR(timing->parent); } @@ -409,8 +407,8 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, } } if (timing->parent_index == 0xff) { - pr_err("timing %s: %s is not a valid parent\n", - node->full_name, __clk_get_name(timing->parent)); + pr_err("timing %pOF: %s is not a valid parent\n", + node, __clk_get_name(timing->parent)); clk_put(timing->parent); return -EINVAL; } diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index fbedc6a9fed0..07a805125e98 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c @@ -138,8 +138,8 @@ static void __init of_ti_clockdomain_setup(struct device_node *node) for (i = 0; i < num_clks; i++) { clk = of_clk_get(node, i); if (IS_ERR(clk)) { - pr_err("%s: Failed get %s' clock nr %d (%ld)\n", - __func__, node->full_name, i, PTR_ERR(clk)); + pr_err("%s: Failed get %pOF' clock nr %d (%ld)\n", + __func__, node, i, PTR_ERR(clk)); continue; } clk_hw = __clk_get_hw(clk); diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c index f99abc1106f0..08ef69945ffb 100644 --- a/drivers/clk/x86/clk-pmc-atom.c +++ b/drivers/clk/x86/clk-pmc-atom.c @@ -186,6 +186,13 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id, pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE; spin_lock_init(&pclk->lock); + /* + * If the clock was already enabled by the firmware mark it as critical + * to avoid it being gated by the clock framework if no driver owns it. + */ + if (plt_clk_is_enabled(&pclk->hw)) + init.flags |= CLK_IS_CRITICAL; + ret = devm_clk_hw_register(&pdev->dev, &pclk->hw); if (ret) { pclk = ERR_PTR(ret); |