* [PATCH 03/05] sh: timer base code, early timer support
@ 2008-12-10 15:12 Magnus Damm
0 siblings, 0 replies; only message in thread
From: Magnus Damm @ 2008-12-10 15:12 UTC (permalink / raw)
To: linux-sh
From: Magnus Damm <damm@igel.co.jp>
SuperH timer rewrite V4 supporting:
- platform timer drivers
- hardware configuration kept as platform data
- early timer support using sh_timer_register()/sh_timer_early_probe()
- compile time CONFIG_SH_TIMER switch
- using CONFIG_GENERIC_TIME and CONFIG_GENERIC_CLOCKEVENTS
- sharing of drivers with other architectures
- built without the need of, but on top of the arch_gettimeoffset patches
Signed-off-by: Magnus Damm <damm@igel.co.jp>
---
arch/sh/Kconfig | 13 +++++--
arch/sh/kernel/time_32.c | 27 +++++++++------
drivers/clocksource/Makefile | 1
drivers/clocksource/sh_timer.c | 72 ++++++++++++++++++++++++++++++++++++++++
include/linux/sh_timer.h | 26 ++++++++++++++
5 files changed, 125 insertions(+), 14 deletions(-)
--- 0004/arch/sh/Kconfig
+++ work/arch/sh/Kconfig 2008-12-10 23:06:16.000000000 +0900
@@ -395,33 +395,38 @@ source "arch/sh/boards/Kconfig"
menu "Timer and clock configuration"
+config SH_TIMER
+ def_bool n
+ select GENERIC_CLOCKEVENTS
+
config SH_TMU
def_bool y
prompt "TMU timer support"
- depends on CPU_SH3 || CPU_SH4
+ depends on !SH_TIMER && (CPU_SH3 || CPU_SH4)
select GENERIC_CLOCKEVENTS
help
This enables the use of the TMU as the system timer.
config ARCH_USES_GETTIMEOFFSET
def_bool y
- depends on !SH_TMU
+ depends on !SH_TMU && !SH_TIMER
config SH_CMT
def_bool y
prompt "CMT timer support"
- depends on CPU_SH2 && !CPU_SUBTYPE_MXG
+ depends on !SH_TIMER && CPU_SH2 && !CPU_SUBTYPE_MXG
help
This enables the use of the CMT as the system timer.
config SH_MTU2
def_bool n
prompt "MTU2 timer support"
- depends on CPU_SH2A
+ depends on !SH_TIMER && CPU_SH2A
help
This enables the use of the MTU2 as the system timer.
config SH_TIMER_IRQ
+ depends on !SH_TIMER
int
default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || \
CPU_SUBTYPE_SH7763
--- 0003/arch/sh/kernel/time_32.c
+++ work/arch/sh/kernel/time_32.c 2008-12-10 23:06:16.000000000 +0900
@@ -18,6 +18,7 @@
#include <linux/clockchips.h>
#include <linux/mc146818rtc.h> /* for rtc_lock */
#include <linux/smp.h>
+#include <linux/sh_timer.h>
#include <asm/clock.h>
#include <asm/rtc.h>
#include <asm/timer.h>
@@ -41,14 +42,6 @@ static int null_rtc_set_time(const time_
return 0;
}
-/*
- * Null high precision timer functions for systems lacking one.
- */
-static cycle_t null_hpt_read(void)
-{
- return 0;
-}
-
void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
@@ -133,6 +126,9 @@ int timer_resume(struct sys_device *dev)
#define timer_resume NULL
#endif
+void (*board_time_init)(void);
+
+#ifndef CONFIG_SH_TIMER
static struct sysdev_class timer_sysclass = {
.name = "timer",
.suspend = timer_suspend,
@@ -150,8 +146,6 @@ static int __init timer_init_sysfs(void)
}
device_initcall(timer_init_sysfs);
-void (*board_time_init)(void);
-
/*
* Shamelessly based on the MIPS and Sparc64 work.
*/
@@ -160,6 +154,14 @@ unsigned long sh_hpt_frequency = 0;
#define NSEC_PER_CYC_SHIFT 10
+/*
+ * Null high precision timer functions for systems lacking one.
+ */
+static cycle_t null_hpt_read(void)
+{
+ return 0;
+}
+
static struct clocksource clocksource_sh = {
.name = "SuperH",
.rating = 200,
@@ -190,6 +192,7 @@ unsigned long long sched_clock(void)
return (ticks * timer_ticks_per_nsec_quotient) >> NSEC_PER_CYC_SHIFT;
}
#endif
+#endif
void __init time_init(void)
{
@@ -206,6 +209,9 @@ void __init time_init(void)
local_timer_setup(smp_processor_id());
#endif
+#ifdef CONFIG_SH_TIMER
+ sh_timer_init();
+#else
/*
* Find the timer to use as the system timer, it will be
* initialized for us.
@@ -224,6 +230,7 @@ void __init time_init(void)
((sh_hpt_frequency + 500) / 1000) / 1000,
((sh_hpt_frequency + 500) / 1000) % 1000);
+#endif
#if defined(CONFIG_SH_KGDB)
/*
* Set up kgdb as requested. We do it here because the serial
--- 0001/drivers/clocksource/Makefile
+++ work/drivers/clocksource/Makefile 2008-12-10 23:06:16.000000000 +0900
@@ -2,3 +2,4 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_cl
obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
+obj-$(CONFIG_SH_TIMER) += sh_timer.o
--- /dev/null
+++ work/drivers/clocksource/sh_timer.c 2008-12-10 23:22:07.000000000 +0900
@@ -0,0 +1,72 @@
+/*
+ * SuperH Timer Support
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <linux/bootmem.h>
+#include <linux/sh_timer.h>
+
+static struct platform_device **sh_timer_pdevs;
+static int sh_timer_nr_pdevs;
+
+void sh_timer_register(struct platform_device **pdevs, int nr_pdevs)
+{
+ sh_timer_pdevs = pdevs;
+ sh_timer_nr_pdevs = nr_pdevs;
+}
+
+struct sh_timer_early * __weak sh_timer_early_probe(struct platform_device *pd)
+{
+ return NULL;
+}
+
+void __init sh_timer_free_early(void *priv, int priv_size)
+{
+ free_bootmem(__pa(priv), priv_size);
+}
+
+int __init sh_timer_init(void)
+{
+ struct platform_device *pdev;
+ struct sh_timer_early *etp;
+ void *vp;
+ int k;
+
+ plat_timer_setup();
+
+ for (k = 0; k < sh_timer_nr_pdevs; k++) {
+ pdev = sh_timer_pdevs[k];
+
+ etp = sh_timer_early_probe(pdev);
+ if (etp) {
+ vp = alloc_bootmem(etp->priv_size);
+
+ if (etp->setup(vp, pdev)) {
+ sh_timer_free_early(vp, etp->priv_size);
+ pr_warning("sh_timer: unable to setup "
+ "early timer\n");
+ }
+ }
+ }
+
+ if (!sh_timer_nr_pdevs)
+ pr_warning("sh_timer: no early timer devices registered\n");
+
+ return 0;
+}
--- /dev/null
+++ work/include/linux/sh_timer.h 2008-12-10 23:06:16.000000000 +0900
@@ -0,0 +1,26 @@
+#ifndef __SH_TIMER_H__
+#define __SH_TIMER_H__
+#include <linux/platform_device.h>
+
+struct sh_timer_config {
+ char *name;
+ unsigned long channel_offset;
+ int timer_bit;
+ char *clk;
+ unsigned long clockevent_rating;
+ unsigned long clocksource_rating;
+};
+
+void sh_timer_register(struct platform_device **pdevs, int nr_pdevs);
+
+struct sh_timer_early {
+ int priv_size;
+ int (*setup)(void *priv, struct platform_device *pdev);
+};
+
+void sh_timer_free_early(void *priv, int priv_size);
+
+int sh_timer_init(void);
+void plat_timer_setup(void);
+
+#endif /* __SH_TIMER_H__ */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-12-10 15:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-10 15:12 [PATCH 03/05] sh: timer base code, early timer support Magnus Damm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).