diff options
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/at91/clk-usb.c | 35 | ||||
-rw-r--r-- | drivers/clk/clk-divider.c | 18 | ||||
-rw-r--r-- | drivers/clk/clk-s2mps11.c | 24 | ||||
-rw-r--r-- | drivers/clk/pxa/clk-pxa27x.c | 4 | ||||
-rw-r--r-- | drivers/clk/qcom/mmcc-apq8084.c | 2 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.c | 4 | ||||
-rw-r--r-- | drivers/clk/versatile/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-vexpress-osc.c | 7 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-vexpress.c | 86 |
9 files changed, 55 insertions, 126 deletions
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 24b5b020753a..a23ac0c724f0 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -52,29 +52,26 @@ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, tmp = pmc_read(pmc, AT91_PMC_USB); usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; - return parent_rate / (usbdiv + 1); + + return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); } static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { unsigned long div; - unsigned long bestrate; - unsigned long tmp; + + if (!rate) + return -EINVAL; if (rate >= *parent_rate) return *parent_rate; - div = *parent_rate / rate; - if (div >= SAM9X5_USB_MAX_DIV) - return *parent_rate / (SAM9X5_USB_MAX_DIV + 1); - - bestrate = *parent_rate / div; - tmp = *parent_rate / (div + 1); - if (bestrate - rate > rate - tmp) - bestrate = tmp; + div = DIV_ROUND_CLOSEST(*parent_rate, rate); + if (div > SAM9X5_USB_MAX_DIV + 1) + div = SAM9X5_USB_MAX_DIV + 1; - return bestrate; + return DIV_ROUND_CLOSEST(*parent_rate, div); } static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) @@ -106,9 +103,13 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, u32 tmp; struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); struct at91_pmc *pmc = usb->pmc; - unsigned long div = parent_rate / rate; + unsigned long div; + + if (!rate) + return -EINVAL; - if (parent_rate % rate || div < 1 || div >= SAM9X5_USB_MAX_DIV) + div = DIV_ROUND_CLOSEST(parent_rate, rate); + if (div > SAM9X5_USB_MAX_DIV + 1 || !div) return -EINVAL; tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; @@ -253,7 +254,7 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, tmp_parent_rate = rate * usb->divisors[i]; tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate); - tmprate = tmp_parent_rate / usb->divisors[i]; + tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]); if (tmprate < rate) tmpdiff = rate - tmprate; else @@ -281,10 +282,10 @@ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, struct at91_pmc *pmc = usb->pmc; unsigned long div; - if (!rate || parent_rate % rate) + if (!rate) return -EINVAL; - div = parent_rate / rate; + div = DIV_ROUND_CLOSEST(parent_rate, rate); for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { if (usb->divisors[i] == div) { diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 18a9de29df0e..c0a842b335c5 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -263,6 +263,14 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, if (!rate) rate = 1; + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + bestdiv = readl(divider->reg) >> divider->shift; + bestdiv &= div_mask(divider); + bestdiv = _get_div(divider, bestdiv); + return bestdiv; + } + maxdiv = _get_maxdiv(divider); if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { @@ -361,11 +369,6 @@ const struct clk_ops clk_divider_ops = { }; EXPORT_SYMBOL_GPL(clk_divider_ops); -const struct clk_ops clk_divider_ro_ops = { - .recalc_rate = clk_divider_recalc_rate, -}; -EXPORT_SYMBOL_GPL(clk_divider_ro_ops); - static struct clk *_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, @@ -391,10 +394,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, } init.name = name; - if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) - init.ops = &clk_divider_ro_ops; - else - init.ops = &clk_divider_ops; + init.ops = &clk_divider_ops; init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index b7797fb12e12..7bb13af8e214 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -23,6 +23,7 @@ #include <linux/clk-provider.h> #include <linux/platform_device.h> #include <linux/mfd/samsung/s2mps11.h> +#include <linux/mfd/samsung/s2mps13.h> #include <linux/mfd/samsung/s2mps14.h> #include <linux/mfd/samsung/s5m8767.h> #include <linux/mfd/samsung/core.h> @@ -120,6 +121,24 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { }, }; +static struct clk_init_data s2mps13_clks_init[S2MPS11_CLKS_NUM] = { + [S2MPS11_CLK_AP] = { + .name = "s2mps13_ap", + .ops = &s2mps11_clk_ops, + .flags = CLK_IS_ROOT, + }, + [S2MPS11_CLK_CP] = { + .name = "s2mps13_cp", + .ops = &s2mps11_clk_ops, + .flags = CLK_IS_ROOT, + }, + [S2MPS11_CLK_BT] = { + .name = "s2mps13_bt", + .ops = &s2mps11_clk_ops, + .flags = CLK_IS_ROOT, + }, +}; + static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { [S2MPS11_CLK_AP] = { .name = "s2mps14_ap", @@ -184,6 +203,10 @@ static int s2mps11_clk_probe(struct platform_device *pdev) s2mps11_reg = S2MPS11_REG_RTC_CTRL; clks_init = s2mps11_clks_init; break; + case S2MPS13X: + s2mps11_reg = S2MPS13_REG_RTCCTRL; + clks_init = s2mps13_clks_init; + break; case S2MPS14X: s2mps11_reg = S2MPS14_REG_RTCCTRL; clks_init = s2mps14_clks_init; @@ -279,6 +302,7 @@ static int s2mps11_clk_remove(struct platform_device *pdev) static const struct platform_device_id s2mps11_clk_id[] = { { "s2mps11-clk", S2MPS11X}, + { "s2mps13-clk", S2MPS13X}, { "s2mps14-clk", S2MPS14X}, { "s5m8767-clk", S5M8767X}, { }, diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index b345cc791e5d..88b9fe13fa44 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -322,7 +322,7 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, unsigned long ccsr = CCSR; osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); - a = cccr & CCCR_A_BIT; + a = cccr & (1 << CCCR_A_BIT); l = ccsr & CCSR_L_MASK; if (osc_forced || a) @@ -341,7 +341,7 @@ static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) unsigned long ccsr = CCSR; osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); - a = cccr & CCCR_A_BIT; + a = cccr & (1 << CCCR_A_BIT); if (osc_forced) return PXA_MEM_13Mhz; if (a) diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index dab988ab8cf1..157139a5c1ca 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c @@ -3122,7 +3122,7 @@ static struct clk_regmap *mmcc_apq8084_clocks[] = { [ESC1_CLK_SRC] = &esc1_clk_src.clkr, [HDMI_CLK_SRC] = &hdmi_clk_src.clkr, [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, - [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, + [MMSS_RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, [MAPLE_CLK_SRC] = &maple_clk_src.clkr, [VDP_CLK_SRC] = &vdp_clk_src.clkr, diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 1e68bff481b8..880a266f0143 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -90,9 +90,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, div->width = div_width; div->lock = lock; div->table = div_table; - div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) - ? &clk_divider_ro_ops - : &clk_divider_ops; + div_ops = &clk_divider_ops; } clk = clk_register_composite(NULL, name, parent_names, num_parents, diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index 162e519cb0f9..8ff03744fe98 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -2,6 +2,5 @@ obj-$(CONFIG_ICST) += clk-icst.o clk-versatile.o obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o -obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o obj-$(CONFIG_CLK_SP810) += clk-sp810.o obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk-vexpress-osc.o diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 529a59c0fbfa..765f1e0eeeb2 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -70,7 +70,6 @@ static struct clk_ops vexpress_osc_ops = { static int vexpress_osc_probe(struct platform_device *pdev) { - struct clk_lookup *cl = pdev->dev.platform_data; /* Non-DT lookup */ struct clk_init_data init; struct vexpress_osc *osc; struct clk *clk; @@ -106,12 +105,6 @@ static int vexpress_osc_probe(struct platform_device *pdev) of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk); - /* Only happens for non-DT cases */ - if (cl) { - cl->clk = clk; - clkdev_add(cl); - } - dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name); return 0; diff --git a/drivers/clk/versatile/clk-vexpress.c b/drivers/clk/versatile/clk-vexpress.c deleted file mode 100644 index 2d5e1b4820e0..000000000000 --- a/drivers/clk/versatile/clk-vexpress.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Copyright (C) 2012 ARM Limited - */ - -#include <linux/amba/sp810.h> -#include <linux/clkdev.h> -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/vexpress.h> - -static struct clk *vexpress_sp810_timerclken[4]; -static DEFINE_SPINLOCK(vexpress_sp810_lock); - -static void __init vexpress_sp810_init(void __iomem *base) -{ - int i; - - if (WARN_ON(!base)) - return; - - for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) { - char name[12]; - const char *parents[] = { - "v2m:refclk32khz", /* REFCLK */ - "v2m:refclk1mhz" /* TIMCLK */ - }; - - snprintf(name, ARRAY_SIZE(name), "timerclken%d", i); - - vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name, - parents, 2, CLK_SET_RATE_NO_REPARENT, - base + SCCTRL, SCCTRL_TIMERENnSEL_SHIFT(i), 1, - 0, &vexpress_sp810_lock); - - if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i]))) - break; - } -} - - -static const char * const vexpress_clk_24mhz_periphs[] __initconst = { - "mb:uart0", "mb:uart1", "mb:uart2", "mb:uart3", - "mb:mmci", "mb:kmi0", "mb:kmi1" -}; - -void __init vexpress_clk_init(void __iomem *sp810_base) -{ - struct clk *clk; - int i; - - clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL, - CLK_IS_ROOT, 0); - WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL)); - - clk = clk_register_fixed_rate(NULL, "v2m:clk_24mhz", NULL, - CLK_IS_ROOT, 24000000); - for (i = 0; i < ARRAY_SIZE(vexpress_clk_24mhz_periphs); i++) - WARN_ON(clk_register_clkdev(clk, NULL, - vexpress_clk_24mhz_periphs[i])); - - clk = clk_register_fixed_rate(NULL, "v2m:refclk32khz", NULL, - CLK_IS_ROOT, 32768); - WARN_ON(clk_register_clkdev(clk, NULL, "v2m:wdt")); - - clk = clk_register_fixed_rate(NULL, "v2m:refclk1mhz", NULL, - CLK_IS_ROOT, 1000000); - - vexpress_sp810_init(sp810_base); - - for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) - WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], clk)); - - WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0], - "v2m-timer0", "sp804")); - WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], - "v2m-timer1", "sp804")); -} |