summaryrefslogtreecommitdiff
path: root/drivers/clocksource
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/Kconfig12
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/arm_arch_timer.c27
-rw-r--r--drivers/clocksource/dw_apb_timer_of.c57
-rw-r--r--drivers/clocksource/ingenic-timer.c2
-rw-r--r--drivers/clocksource/sh_cmt.c18
-rw-r--r--drivers/clocksource/timer-cadence-ttc.c18
-rw-r--r--drivers/clocksource/timer-nps.c284
-rw-r--r--drivers/clocksource/timer-orion.c11
-rw-r--r--drivers/clocksource/timer-sp804.c49
10 files changed, 107 insertions, 372 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 68b087bff59c..9f00b8385fd4 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -275,16 +275,6 @@ config CLKSRC_TI_32K
This option enables support for Texas Instruments 32.768 Hz clocksource
available on many OMAP-like platforms.
-config CLKSRC_NPS
- bool "NPS400 clocksource driver" if COMPILE_TEST
- depends on !PHYS_ADDR_T_64BIT
- select CLKSRC_MMIO
- select TIMER_OF if OF
- help
- NPS400 clocksource support.
- It has a 64-bit counter with update rate up to 1000MHz.
- This counter is accessed via couple of 32-bit memory-mapped registers.
-
config CLKSRC_STM32
bool "Clocksource for STM32 SoCs" if !ARCH_STM32
depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
@@ -654,7 +644,7 @@ config ATCPIT100_TIMER
config RISCV_TIMER
bool "Timer for the RISC-V platform" if COMPILE_TEST
- depends on GENERIC_SCHED_CLOCK && RISCV
+ depends on GENERIC_SCHED_CLOCK && RISCV && RISCV_SBI
select TIMER_PROBE
select TIMER_OF
help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 1c444cc3bb44..3c75cbbf8533 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -56,7 +56,6 @@ obj-$(CONFIG_CLKSRC_QCOM) += timer-qcom.o
obj-$(CONFIG_MTK_TIMER) += timer-mediatek.o
obj-$(CONFIG_CLKSRC_PISTACHIO) += timer-pistachio.o
obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o
-obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o
obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o
obj-$(CONFIG_OWL_TIMER) += timer-owl.o
obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 6c3e84180146..d0177824c518 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -396,10 +396,10 @@ static void erratum_set_next_event_tval_generic(const int access, unsigned long
ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
if (access == ARCH_TIMER_PHYS_ACCESS) {
- cval = evt + arch_counter_get_cntpct();
+ cval = evt + arch_counter_get_cntpct_stable();
write_sysreg(cval, cntp_cval_el0);
} else {
- cval = evt + arch_counter_get_cntvct();
+ cval = evt + arch_counter_get_cntvct_stable();
write_sysreg(cval, cntv_cval_el0);
}
@@ -822,15 +822,24 @@ static void arch_timer_evtstrm_enable(int divider)
static void arch_timer_configure_evtstream(void)
{
- int evt_stream_div, pos;
+ int evt_stream_div, lsb;
+
+ /*
+ * As the event stream can at most be generated at half the frequency
+ * of the counter, use half the frequency when computing the divider.
+ */
+ evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ / 2;
+
+ /*
+ * Find the closest power of two to the divisor. If the adjacent bit
+ * of lsb (last set bit, starts from 0) is set, then we use (lsb + 1).
+ */
+ lsb = fls(evt_stream_div) - 1;
+ if (lsb > 0 && (evt_stream_div & BIT(lsb - 1)))
+ lsb++;
- /* Find the closest power of two to the divisor */
- evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ;
- pos = fls(evt_stream_div);
- if (pos > 1 && !(evt_stream_div & (1 << (pos - 2))))
- pos--;
/* enable event stream */
- arch_timer_evtstrm_enable(min(pos, 15));
+ arch_timer_evtstrm_enable(max(0, min(lsb, 15)));
}
static void arch_counter_set_user_access(void)
diff --git a/drivers/clocksource/dw_apb_timer_of.c b/drivers/clocksource/dw_apb_timer_of.c
index ab3ddebe8344..42e7e43b8fcd 100644
--- a/drivers/clocksource/dw_apb_timer_of.c
+++ b/drivers/clocksource/dw_apb_timer_of.c
@@ -14,12 +14,13 @@
#include <linux/reset.h>
#include <linux/sched_clock.h>
-static void __init timer_get_base_and_rate(struct device_node *np,
+static int __init timer_get_base_and_rate(struct device_node *np,
void __iomem **base, u32 *rate)
{
struct clk *timer_clk;
struct clk *pclk;
struct reset_control *rstc;
+ int ret;
*base = of_iomap(np, 0);
@@ -46,55 +47,67 @@ static void __init timer_get_base_and_rate(struct device_node *np,
pr_warn("pclk for %pOFn is present, but could not be activated\n",
np);
+ if (!of_property_read_u32(np, "clock-freq", rate) &&
+ !of_property_read_u32(np, "clock-frequency", rate))
+ return 0;
+
timer_clk = of_clk_get_by_name(np, "timer");
if (IS_ERR(timer_clk))
- goto try_clock_freq;
+ return PTR_ERR(timer_clk);
- if (!clk_prepare_enable(timer_clk)) {
- *rate = clk_get_rate(timer_clk);
- return;
- }
+ ret = clk_prepare_enable(timer_clk);
+ if (ret)
+ return ret;
+
+ *rate = clk_get_rate(timer_clk);
+ if (!(*rate))
+ return -EINVAL;
-try_clock_freq:
- if (of_property_read_u32(np, "clock-freq", rate) &&
- of_property_read_u32(np, "clock-frequency", rate))
- panic("No clock nor clock-frequency property for %pOFn", np);
+ return 0;
}
-static void __init add_clockevent(struct device_node *event_timer)
+static int __init add_clockevent(struct device_node *event_timer)
{
void __iomem *iobase;
struct dw_apb_clock_event_device *ced;
u32 irq, rate;
+ int ret = 0;
irq = irq_of_parse_and_map(event_timer, 0);
if (irq == 0)
panic("No IRQ for clock event timer");
- timer_get_base_and_rate(event_timer, &iobase, &rate);
+ ret = timer_get_base_and_rate(event_timer, &iobase, &rate);
+ if (ret)
+ return ret;
ced = dw_apb_clockevent_init(-1, event_timer->name, 300, iobase, irq,
rate);
if (!ced)
- panic("Unable to initialise clockevent device");
+ return -EINVAL;
dw_apb_clockevent_register(ced);
+
+ return 0;
}
static void __iomem *sched_io_base;
static u32 sched_rate;
-static void __init add_clocksource(struct device_node *source_timer)
+static int __init add_clocksource(struct device_node *source_timer)
{
void __iomem *iobase;
struct dw_apb_clocksource *cs;
u32 rate;
+ int ret;
- timer_get_base_and_rate(source_timer, &iobase, &rate);
+ ret = timer_get_base_and_rate(source_timer, &iobase, &rate);
+ if (ret)
+ return ret;
cs = dw_apb_clocksource_init(300, source_timer->name, iobase, rate);
if (!cs)
- panic("Unable to initialise clocksource device");
+ return -EINVAL;
dw_apb_clocksource_start(cs);
dw_apb_clocksource_register(cs);
@@ -106,6 +119,8 @@ static void __init add_clocksource(struct device_node *source_timer)
*/
sched_io_base = iobase + 0x04;
sched_rate = rate;
+
+ return 0;
}
static u64 notrace read_sched_clock(void)
@@ -146,10 +161,14 @@ static struct delay_timer dw_apb_delay_timer = {
static int num_called;
static int __init dw_apb_timer_init(struct device_node *timer)
{
+ int ret = 0;
+
switch (num_called) {
case 1:
pr_debug("%s: found clocksource timer\n", __func__);
- add_clocksource(timer);
+ ret = add_clocksource(timer);
+ if (ret)
+ return ret;
init_sched_clock();
#ifdef CONFIG_ARM
dw_apb_delay_timer.freq = sched_rate;
@@ -158,7 +177,9 @@ static int __init dw_apb_timer_init(struct device_node *timer)
break;
default:
pr_debug("%s: found clockevent timer\n", __func__);
- add_clockevent(timer);
+ ret = add_clockevent(timer);
+ if (ret)
+ return ret;
break;
}
diff --git a/drivers/clocksource/ingenic-timer.c b/drivers/clocksource/ingenic-timer.c
index 58fd9189fab7..905fd6b163a8 100644
--- a/drivers/clocksource/ingenic-timer.c
+++ b/drivers/clocksource/ingenic-timer.c
@@ -127,7 +127,7 @@ static irqreturn_t ingenic_tcu_cevt_cb(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct clk * __init ingenic_tcu_get_clock(struct device_node *np, int id)
+static struct clk *ingenic_tcu_get_clock(struct device_node *np, int id)
{
struct of_phandle_args args;
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 760777458a90..19fa3ef75e3b 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -319,7 +319,6 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch)
{
int k, ret;
- pm_runtime_get_sync(&ch->cmt->pdev->dev);
dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
/* enable clock */
@@ -394,7 +393,6 @@ static void sh_cmt_disable(struct sh_cmt_channel *ch)
clk_disable(ch->cmt->clk);
dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
- pm_runtime_put(&ch->cmt->pdev->dev);
}
/* private flags */
@@ -562,10 +560,16 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
int ret = 0;
unsigned long flags;
+ if (flag & FLAG_CLOCKSOURCE)
+ pm_runtime_get_sync(&ch->cmt->pdev->dev);
+
raw_spin_lock_irqsave(&ch->lock, flags);
- if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) {
+ if (flag & FLAG_CLOCKEVENT)
+ pm_runtime_get_sync(&ch->cmt->pdev->dev);
ret = sh_cmt_enable(ch);
+ }
if (ret)
goto out;
@@ -590,14 +594,20 @@ static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag)
f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
ch->flags &= ~flag;
- if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) {
sh_cmt_disable(ch);
+ if (flag & FLAG_CLOCKEVENT)
+ pm_runtime_put(&ch->cmt->pdev->dev);
+ }
/* adjust the timeout to maximum if only clocksource left */
if ((flag == FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE))
__sh_cmt_set_next(ch, ch->max_match_value);
raw_spin_unlock_irqrestore(&ch->lock, flags);
+
+ if (flag & FLAG_CLOCKSOURCE)
+ pm_runtime_put(&ch->cmt->pdev->dev);
}
static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c
index 80e960602030..4efd0cf3b602 100644
--- a/drivers/clocksource/timer-cadence-ttc.c
+++ b/drivers/clocksource/timer-cadence-ttc.c
@@ -413,10 +413,8 @@ static int __init ttc_setup_clockevent(struct clk *clk,
ttcce->ttc.clk = clk;
err = clk_prepare_enable(ttcce->ttc.clk);
- if (err) {
- kfree(ttcce);
- return err;
- }
+ if (err)
+ goto out_kfree;
ttcce->ttc.clk_rate_change_nb.notifier_call =
ttc_rate_change_clockevent_cb;
@@ -426,7 +424,7 @@ static int __init ttc_setup_clockevent(struct clk *clk,
&ttcce->ttc.clk_rate_change_nb);
if (err) {
pr_warn("Unable to register clock notifier.\n");
- return err;
+ goto out_kfree;
}
ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk);
@@ -455,15 +453,17 @@ static int __init ttc_setup_clockevent(struct clk *clk,
err = request_irq(irq, ttc_clock_event_interrupt,
IRQF_TIMER, ttcce->ce.name, ttcce);
- if (err) {
- kfree(ttcce);
- return err;
- }
+ if (err)
+ goto out_kfree;
clockevents_config_and_register(&ttcce->ce,
ttcce->ttc.freq / PRESCALE, 1, 0xfffe);
return 0;
+
+out_kfree:
+ kfree(ttcce);
+ return err;
}
static int __init ttc_timer_probe(struct platform_device *pdev)
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
deleted file mode 100644
index 7b6bb0df96ae..000000000000
--- a/drivers/clocksource/timer-nps.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <linux/interrupt.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/cpu.h>
-#include <soc/nps/common.h>
-
-#define NPS_MSU_TICK_LOW 0xC8
-#define NPS_CLUSTER_OFFSET 8
-#define NPS_CLUSTER_NUM 16
-
-/* This array is per cluster of CPUs (Each NPS400 cluster got 256 CPUs) */
-static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
-
-static int __init nps_get_timer_clk(struct device_node *node,
- unsigned long *timer_freq,
- struct clk **clk)
-{
- int ret;
-
- *clk = of_clk_get(node, 0);
- ret = PTR_ERR_OR_ZERO(*clk);
- if (ret) {
- pr_err("timer missing clk\n");
- return ret;
- }
-
- ret = clk_prepare_enable(*clk);
- if (ret) {
- pr_err("Couldn't enable parent clk\n");
- clk_put(*clk);
- return ret;
- }
-
- *timer_freq = clk_get_rate(*clk);
- if (!(*timer_freq)) {
- pr_err("Couldn't get clk rate\n");
- clk_disable_unprepare(*clk);
- clk_put(*clk);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static u64 nps_clksrc_read(struct clocksource *clksrc)
-{
- int cluster = raw_smp_processor_id() >> NPS_CLUSTER_OFFSET;
-
- return (u64)ioread32be(nps_msu_reg_low_addr[cluster]);
-}
-
-static int __init nps_setup_clocksource(struct device_node *node)
-{
- int ret, cluster;
- struct clk *clk;
- unsigned long nps_timer1_freq;
-
-
- for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
- nps_msu_reg_low_addr[cluster] =
- nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
- NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
-
- ret = nps_get_timer_clk(node, &nps_timer1_freq, &clk);
- if (ret)
- return ret;
-
- ret = clocksource_mmio_init(nps_msu_reg_low_addr, "nps-tick",
- nps_timer1_freq, 300, 32, nps_clksrc_read);
- if (ret) {
- pr_err("Couldn't register clock source.\n");
- clk_disable_unprepare(clk);
- }
-
- return ret;
-}
-
-TIMER_OF_DECLARE(ezchip_nps400_clksrc, "ezchip,nps400-timer",
- nps_setup_clocksource);
-TIMER_OF_DECLARE(ezchip_nps400_clk_src, "ezchip,nps400-timer1",
- nps_setup_clocksource);
-
-#ifdef CONFIG_EZNPS_MTM_EXT
-#include <soc/nps/mtm.h>
-
-/* Timer related Aux registers */
-#define NPS_REG_TIMER0_TSI 0xFFFFF850
-#define NPS_REG_TIMER0_LIMIT 0x23
-#define NPS_REG_TIMER0_CTRL 0x22
-#define NPS_REG_TIMER0_CNT 0x21
-
-/*
- * Interrupt Enabled (IE) - re-arm the timer
- * Not Halted (NH) - is cleared when working with JTAG (for debug)
- */
-#define TIMER0_CTRL_IE BIT(0)
-#define TIMER0_CTRL_NH BIT(1)
-
-static unsigned long nps_timer0_freq;
-static unsigned long nps_timer0_irq;
-
-static void nps_clkevent_rm_thread(void)
-{
- int thread;
- unsigned int cflags, enabled_threads;
-
- hw_schd_save(&cflags);
-
- enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI);
-
- /* remove thread from TSI1 */
- thread = read_aux_reg(CTOP_AUX_THREAD_ID);
- enabled_threads &= ~(1 << thread);
- write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads);
-
- /* Acknowledge and if needed re-arm the timer */
- if (!enabled_threads)
- write_aux_reg(NPS_REG_TIMER0_CTRL, TIMER0_CTRL_NH);
- else
- write_aux_reg(NPS_REG_TIMER0_CTRL,
- TIMER0_CTRL_IE | TIMER0_CTRL_NH);
-
- hw_schd_restore(cflags);
-}
-
-static void nps_clkevent_add_thread(unsigned long delta)
-{
- int thread;
- unsigned int cflags, enabled_threads;
-
- hw_schd_save(&cflags);
-
- /* add thread to TSI1 */
- thread = read_aux_reg(CTOP_AUX_THREAD_ID);
- enabled_threads = read_aux_reg(NPS_REG_TIMER0_TSI);
- enabled_threads |= (1 << thread);
- write_aux_reg(NPS_REG_TIMER0_TSI, enabled_threads);
-
- /* set next timer event */
- write_aux_reg(NPS_REG_TIMER0_LIMIT, delta);
- write_aux_reg(NPS_REG_TIMER0_CNT, 0);
- write_aux_reg(NPS_REG_TIMER0_CTRL,
- TIMER0_CTRL_IE | TIMER0_CTRL_NH);
-
- hw_schd_restore(cflags);
-}
-
-/*
- * Whenever anyone tries to change modes, we just mask interrupts
- * and wait for the next event to get set.
- */
-static int nps_clkevent_set_state(struct clock_event_device *dev)
-{
- nps_clkevent_rm_thread();
- disable_percpu_irq(nps_timer0_irq);
-
- return 0;
-}
-
-static int nps_clkevent_set_next_event(unsigned long delta,
- struct clock_event_device *dev)
-{
- nps_clkevent_add_thread(delta);
- enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE);
-
- return 0;
-}
-
-static DEFINE_PER_CPU(struct clock_event_device, nps_clockevent_device) = {
- .name = "NPS Timer0",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .rating = 300,
- .set_next_event = nps_clkevent_set_next_event,
- .set_state_oneshot = nps_clkevent_set_state,
- .set_state_oneshot_stopped = nps_clkevent_set_state,
- .set_state_shutdown = nps_clkevent_set_state,
- .tick_resume = nps_clkevent_set_state,
-};
-
-static irqreturn_t timer_irq_handler(int irq, void *dev_id)
-{
- struct clock_event_device *evt = dev_id;
-
- nps_clkevent_rm_thread();
- evt->event_handler(evt);
-
- return IRQ_HANDLED;
-}
-
-static int nps_timer_starting_cpu(unsigned int cpu)
-{
- struct clock_event_device *evt = this_cpu_ptr(&nps_clockevent_device);
-
- evt->cpumask = cpumask_of(smp_processor_id());
-
- clockevents_config_and_register(evt, nps_timer0_freq, 0, ULONG_MAX);
- enable_percpu_irq(nps_timer0_irq, IRQ_TYPE_NONE);
-
- return 0;
-}
-
-static int nps_timer_dying_cpu(unsigned int cpu)
-{
- disable_percpu_irq(nps_timer0_irq);
- return 0;
-}
-
-static int __init nps_setup_clockevent(struct device_node *node)
-{
- struct clk *clk;
- int ret;
-
- nps_timer0_irq = irq_of_parse_and_map(node, 0);
- if (nps_timer0_irq <= 0) {
- pr_err("clockevent: missing irq\n");
- return -EINVAL;
- }
-
- ret = nps_get_timer_clk(node, &nps_timer0_freq, &clk);
- if (ret)
- return ret;
-
- /* Needs apriori irq_set_percpu_devid() done in intc map function */
- ret = request_percpu_irq(nps_timer0_irq, timer_irq_handler,
- "Timer0 (per-cpu-tick)",
- &nps_clockevent_device);
- if (ret) {
- pr_err("Couldn't request irq\n");
- clk_disable_unprepare(clk);
- return ret;
- }
-
- ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING,
- "clockevents/nps:starting",
- nps_timer_starting_cpu,
- nps_timer_dying_cpu);
- if (ret) {
- pr_err("Failed to setup hotplug state\n");
- clk_disable_unprepare(clk);
- free_percpu_irq(nps_timer0_irq, &nps_clockevent_device);
- return ret;
- }
-
- return 0;
-}
-
-TIMER_OF_DECLARE(ezchip_nps400_clk_evt, "ezchip,nps400-timer0",
- nps_setup_clockevent);
-#endif /* CONFIG_EZNPS_MTM_EXT */
diff --git a/drivers/clocksource/timer-orion.c b/drivers/clocksource/timer-orion.c
index d01ff4181867..5101e834d78f 100644
--- a/drivers/clocksource/timer-orion.c
+++ b/drivers/clocksource/timer-orion.c
@@ -143,7 +143,8 @@ static int __init orion_timer_init(struct device_node *np)
irq = irq_of_parse_and_map(np, 1);
if (irq <= 0) {
pr_err("%pOFn: unable to parse timer1 irq\n", np);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_unprep_clk;
}
rate = clk_get_rate(clk);
@@ -160,7 +161,7 @@ static int __init orion_timer_init(struct device_node *np)
clocksource_mmio_readl_down);
if (ret) {
pr_err("Failed to initialize mmio timer\n");
- return ret;
+ goto out_unprep_clk;
}
sched_clock_register(orion_read_sched_clock, 32, rate);
@@ -170,7 +171,7 @@ static int __init orion_timer_init(struct device_node *np)
"orion_event", NULL);
if (ret) {
pr_err("%pOFn: unable to setup irq\n", np);
- return ret;
+ goto out_unprep_clk;
}
ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ;
@@ -183,5 +184,9 @@ static int __init orion_timer_init(struct device_node *np)
orion_delay_timer_init(rate);
return 0;
+
+out_unprep_clk:
+ clk_disable_unprepare(clk);
+ return ret;
}
TIMER_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init);
diff --git a/drivers/clocksource/timer-sp804.c b/drivers/clocksource/timer-sp804.c
index 6e8ad4a4ea3c..401d592e85f5 100644
--- a/drivers/clocksource/timer-sp804.c
+++ b/drivers/clocksource/timer-sp804.c
@@ -5,6 +5,9 @@
* Copyright (C) 1999 - 2003 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/clk.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
@@ -34,8 +37,7 @@
#define HISI_TIMER_BGLOAD 0x20
#define HISI_TIMER_BGLOAD_H 0x24
-
-struct sp804_timer __initdata arm_sp804_timer = {
+static struct sp804_timer arm_sp804_timer __initdata = {
.load = TIMER_LOAD,
.value = TIMER_VALUE,
.ctrl = TIMER_CTRL,
@@ -44,7 +46,7 @@ struct sp804_timer __initdata arm_sp804_timer = {
.width = 32,
};
-struct sp804_timer __initdata hisi_sp804_timer = {
+static struct sp804_timer hisi_sp804_timer __initdata = {
.load = HISI_TIMER_LOAD,
.load_h = HISI_TIMER_LOAD_H,
.value = HISI_TIMER_VALUE,
@@ -59,40 +61,23 @@ static struct sp804_clkevt sp804_clkevt[NR_TIMERS];
static long __init sp804_get_clock_rate(struct clk *clk, const char *name)
{
- long rate;
int err;
if (!clk)
clk = clk_get_sys("sp804", name);
if (IS_ERR(clk)) {
- pr_err("sp804: %s clock not found: %ld\n", name, PTR_ERR(clk));
+ pr_err("%s clock not found: %ld\n", name, PTR_ERR(clk));
return PTR_ERR(clk);
}
- err = clk_prepare(clk);
- if (err) {
- pr_err("sp804: clock failed to prepare: %d\n", err);
- clk_put(clk);
- return err;
- }
-
- err = clk_enable(clk);
+ err = clk_prepare_enable(clk);
if (err) {
- pr_err("sp804: clock failed to enable: %d\n", err);
- clk_unprepare(clk);
+ pr_err("clock failed to enable: %d\n", err);
clk_put(clk);
return err;
}
- rate = clk_get_rate(clk);
- if (rate < 0) {
- pr_err("sp804: clock failed to get rate: %ld\n", rate);
- clk_disable(clk);
- clk_unprepare(clk);
- clk_put(clk);
- }
-
- return rate;
+ return clk_get_rate(clk);
}
static struct sp804_clkevt * __init sp804_clkevt_get(void __iomem *base)
@@ -117,10 +102,10 @@ static u64 notrace sp804_read(void)
return ~readl_relaxed(sched_clkevt->value);
}
-int __init sp804_clocksource_and_sched_clock_init(void __iomem *base,
- const char *name,
- struct clk *clk,
- int use_sched_clock)
+static int __init sp804_clocksource_and_sched_clock_init(void __iomem *base,
+ const char *name,
+ struct clk *clk,
+ int use_sched_clock)
{
long rate;
struct sp804_clkevt *clkevt;
@@ -216,8 +201,8 @@ static struct clock_event_device sp804_clockevent = {
.rating = 300,
};
-int __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
- struct clk *clk, const char *name)
+static int __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
+ struct clk *clk, const char *name)
{
struct clock_event_device *evt = &sp804_clockevent;
long rate;
@@ -236,7 +221,7 @@ int __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
if (request_irq(irq, sp804_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
"timer", &sp804_clockevent))
- pr_err("%s: request_irq() failed\n", "timer");
+ pr_err("request_irq() failed\n");
clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
return 0;
@@ -298,7 +283,7 @@ static int __init sp804_of_init(struct device_node *np, struct sp804_timer *time
if (of_clk_get_parent_count(np) == 3) {
clk2 = of_clk_get(np, 1);
if (IS_ERR(clk2)) {
- pr_err("sp804: %pOFn clock not found: %d\n", np,
+ pr_err("%pOFn clock not found: %d\n", np,
(int)PTR_ERR(clk2));
clk2 = NULL;
}