Commit b0495e4b authored by Arnd Bergmann's avatar Arnd Bergmann

sh: dreamcast: rtc: push down rtc class ops into driver

The SH RTC support has an extra level of indirection to provide
either the old read_persistent_clock/update_persistent_clock
interface or the rtc-generic device for hctosys/systohc.

Both do the same thing for dreamcast, so we can do away with the
abstraction and simply let the RTC core code to take care of it.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 2367c4b5
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
# Makefile for the Sega Dreamcast specific parts of the kernel # Makefile for the Sega Dreamcast specific parts of the kernel
# #
obj-y := setup.o irq.o rtc.o obj-y := setup.o irq.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc.o
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
*/ */
#include <linux/time.h> #include <linux/time.h>
#include <asm/rtc.h> #include <linux/rtc.h>
#include <asm/io.h> #include <linux/io.h>
#include <linux/platform_device.h>
/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in /* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
seconds) to get the standard Unix Epoch when getting the time, and add seconds) to get the standard Unix Epoch when getting the time, and add
...@@ -26,13 +27,15 @@ ...@@ -26,13 +27,15 @@
/** /**
* aica_rtc_gettimeofday - Get the time from the AICA RTC * aica_rtc_gettimeofday - Get the time from the AICA RTC
* @ts: pointer to resulting timespec * @dev: the RTC device (ignored)
* @tm: pointer to resulting RTC time structure
* *
* Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
*/ */
static void aica_rtc_gettimeofday(struct timespec *ts) static int aica_rtc_gettimeofday(struct device *dev, struct rtc_time *tm)
{ {
unsigned long val1, val2; unsigned long val1, val2;
time64_t t;
do { do {
val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) |
...@@ -42,22 +45,26 @@ static void aica_rtc_gettimeofday(struct timespec *ts) ...@@ -42,22 +45,26 @@ static void aica_rtc_gettimeofday(struct timespec *ts)
(__raw_readl(AICA_RTC_SECS_L) & 0xffff); (__raw_readl(AICA_RTC_SECS_L) & 0xffff);
} while (val1 != val2); } while (val1 != val2);
ts->tv_sec = val1 - TWENTY_YEARS; /* normalize to 1970..2106 time range */
t = (u32)(val1 - TWENTY_YEARS);
/* Can't get nanoseconds with just a seconds counter. */ rtc_time64_to_tm(t, tm);
ts->tv_nsec = 0;
return 0;
} }
/** /**
* aica_rtc_settimeofday - Set the AICA RTC to the current time * aica_rtc_settimeofday - Set the AICA RTC to the current time
* @secs: contains the time_t to set * @dev: the RTC device (ignored)
* @tm: pointer to new RTC time structure
* *
* Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
*/ */
static int aica_rtc_settimeofday(const time_t secs) static int aica_rtc_settimeofday(struct device *dev, struct rtc_time *tm)
{ {
unsigned long val1, val2; unsigned long val1, val2;
unsigned long adj = secs + TWENTY_YEARS; time64_t secs = rtc_tm_to_time64(tm);
u32 adj = secs + TWENTY_YEARS;
do { do {
__raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H); __raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H);
...@@ -73,9 +80,19 @@ static int aica_rtc_settimeofday(const time_t secs) ...@@ -73,9 +80,19 @@ static int aica_rtc_settimeofday(const time_t secs)
return 0; return 0;
} }
void aica_time_init(void) static const struct rtc_class_ops rtc_generic_ops = {
.read_time = aica_rtc_gettimeofday,
.set_time = aica_rtc_settimeofday,
};
static int __init aica_time_init(void)
{ {
rtc_sh_get_time = aica_rtc_gettimeofday; struct platform_device *pdev;
rtc_sh_set_time = aica_rtc_settimeofday;
} pdev = platform_device_register_data(NULL, "rtc-generic", -1,
&rtc_generic_ops,
sizeof(rtc_generic_ops));
return PTR_ERR_OR_ZERO(pdev);
}
arch_initcall(aica_time_init);
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
static void __init dreamcast_setup(char **cmdline_p) static void __init dreamcast_setup(char **cmdline_p)
{ {
board_time_init = aica_time_init;
} }
static struct sh_machine_vector mv_dreamcast __initmv = { static struct sh_machine_vector mv_dreamcast __initmv = {
......
...@@ -70,3 +70,5 @@ CONFIG_PROC_KCORE=y ...@@ -70,3 +70,5 @@ CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y CONFIG_HUGETLBFS=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_GENERIC=y
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
/* arch/sh/boards/mach-dreamcast/irq.c */ /* arch/sh/boards/mach-dreamcast/irq.c */
extern int systemasic_irq_demux(int); extern int systemasic_irq_demux(int);
extern void systemasic_irq_init(void); extern void systemasic_irq_init(void);
extern void aica_time_init(void);
#endif /* __ASM_SH_DREAMCAST_SYSASIC_H */ #endif /* __ASM_SH_DREAMCAST_SYSASIC_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment