提交 91550f71 编写于 作者: P Paul Mundt

sh: Kill off the rest of the legacy rtc mess.

With the new RTC class driver, we can get rid of most of the
old left over cruft.
Signed-off-by: NPaul Mundt <lethal@linux-sh.org>
上级 51e22e7a
......@@ -296,19 +296,6 @@ config CPU_LITTLE_ENDIAN
endian byte order. These modes require different kernels. Say Y if
your machine is little endian, N if it's a big endian machine.
# The SH7750 RTC module is disabled in the Dreamcast
config SH_RTC
bool
depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \
!SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \
!SH_R7780RP && !SH_SHMIN
default y
help
Selecting this option will allow the Linux kernel to emulate
PC's RTC.
If unsure, say N.
config SH_FPU
bool "FPU support"
depends on !CPU_SH3
......
......@@ -19,9 +19,7 @@
#include <linux/mc146818rtc.h>
#include <asm/io.h>
/****************************************************************************/
static int use_ds1302 = 0;
static int use_ds1302;
/****************************************************************************/
/*
......@@ -79,10 +77,6 @@ static unsigned int ds1302_readbyte(unsigned int addr)
unsigned int val;
unsigned long flags;
#if 0
printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr);
#endif
local_irq_save(flags);
set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
......@@ -101,10 +95,6 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val)
{
unsigned long flags;
#if 0
printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr);
#endif
local_irq_save(flags);
set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
......@@ -167,9 +157,6 @@ void __init secureedge5410_rtc_init(void)
if (use_ds1302) {
rtc_sh_get_time = snapgear_rtc_gettimeofday;
rtc_sh_set_time = snapgear_rtc_settimeofday;
} else {
rtc_sh_get_time = sh_rtc_gettimeofday;
rtc_sh_set_time = sh_rtc_settimeofday;
}
printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal");
......@@ -184,10 +171,8 @@ void snapgear_rtc_gettimeofday(struct timespec *ts)
{
unsigned int sec, min, hr, day, mon, yr;
if (!use_ds1302) {
sh_rtc_gettimeofday(ts);
if (!use_ds1302)
return;
}
sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
......@@ -228,7 +213,7 @@ int snapgear_rtc_settimeofday(const time_t secs)
unsigned long nowtime;
if (!use_ds1302)
return sh_rtc_settimeofday(secs);
return 0;
/*
* This is called direct from the kernel timer handling code.
......@@ -237,10 +222,6 @@ int snapgear_rtc_settimeofday(const time_t secs)
nowtime = secs;
#if 1
printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime);
#endif
/* STOP RTC */
ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
......@@ -326,5 +307,3 @@ void secureedge5410_cmos_write(unsigned char val, int addr)
default: break;
}
}
/****************************************************************************/
......@@ -8,6 +8,5 @@ obj-$(CONFIG_CPU_SH2) += sh2/
obj-$(CONFIG_CPU_SH3) += sh3/
obj-$(CONFIG_CPU_SH4) += sh4/
obj-$(CONFIG_SH_RTC) += rtc.o
obj-$(CONFIG_UBC_WAKEUP) += ubc.o
obj-$(CONFIG_SH_ADC) += adc.o
......@@ -124,7 +124,7 @@ void __init init_IRQ(void)
#ifndef CONFIG_CPU_SUBTYPE_SH7780
make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
#if defined(CONFIG_SH_RTC)
#ifdef RTC_IRQ
make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
#endif
......
/*
* linux/arch/sh/kernel/rtc.c -- SH3 / SH4 on-chip RTC support
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/bcd.h>
#include <asm/io.h>
#include <asm/rtc.h>
void sh_rtc_gettimeofday(struct timespec *ts)
{
unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit;
unsigned long flags;
again:
do {
local_irq_save(flags);
ctrl_outb(0, RCR1); /* Clear CF-bit */
sec128 = ctrl_inb(R64CNT);
sec = ctrl_inb(RSECCNT);
min = ctrl_inb(RMINCNT);
hr = ctrl_inb(RHRCNT);
wk = ctrl_inb(RWKCNT);
day = ctrl_inb(RDAYCNT);
mon = ctrl_inb(RMONCNT);
#if defined(CONFIG_CPU_SH4)
yr = ctrl_inw(RYRCNT);
yr100 = (yr >> 8);
yr &= 0xff;
#else
yr = ctrl_inb(RYRCNT);
yr100 = (yr == 0x99) ? 0x19 : 0x20;
#endif
sec2 = ctrl_inb(R64CNT);
cf_bit = ctrl_inb(RCR1) & RCR1_CF;
local_irq_restore(flags);
} while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
BCD_TO_BIN(yr100);
BCD_TO_BIN(yr);
BCD_TO_BIN(mon);
BCD_TO_BIN(day);
BCD_TO_BIN(hr);
BCD_TO_BIN(min);
BCD_TO_BIN(sec);
if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
hr > 23 || min > 59 || sec > 59) {
printk(KERN_ERR
"SH RTC: invalid value, resetting to 1 Jan 2000\n");
local_irq_save(flags);
ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */
ctrl_outb(0, RSECCNT);
ctrl_outb(0, RMINCNT);
ctrl_outb(0, RHRCNT);
ctrl_outb(6, RWKCNT);
ctrl_outb(1, RDAYCNT);
ctrl_outb(1, RMONCNT);
#if defined(CONFIG_CPU_SH4)
ctrl_outw(0x2000, RYRCNT);
#else
ctrl_outb(0, RYRCNT);
#endif
ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */
goto again;
}
#if RTC_BIT_INVERTED != 0
if ((sec128 & RTC_BIT_INVERTED))
sec--;
#endif
ts->tv_sec = mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
ts->tv_nsec = ((sec128 * 1000000) / 128) * 1000;
}
/*
* Changed to only care about tv_sec, and not the full timespec struct
* (i.e. tv_nsec). It can easily be switched to timespec for future cpus
* that support setting usec or nsec RTC values.
*/
int sh_rtc_settimeofday(const time_t secs)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned long flags;
local_irq_save(flags);
ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */
cmos_minutes = ctrl_inb(RMINCNT);
BCD_TO_BIN(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
* don't interfere with hour overflow. This avoids
* messing with unknown time zones but requires your
* RTC not to be off by more than 15 minutes
*/
real_seconds = secs % 60;
real_minutes = secs / 60;
if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
real_minutes += 30; /* correct for half hour time zone */
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
BIN_TO_BCD(real_seconds);
BIN_TO_BCD(real_minutes);
ctrl_outb(real_seconds, RSECCNT);
ctrl_outb(real_minutes, RMINCNT);
} else {
printk(KERN_WARNING
"set_rtc_time: can't update from %d to %d\n",
cmos_minutes, real_minutes);
retval = -1;
}
ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */
local_irq_restore(flags);
return retval;
}
......@@ -3,13 +3,12 @@
*
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
* Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt
* Copyright (C) 2002 - 2006 Paul Mundt
* Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
*
* Some code taken from i386 version.
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
......@@ -26,15 +25,20 @@ struct sys_timer *sys_timer;
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
/* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want
* these routines anywhere... */
#ifdef CONFIG_SH_RTC
void (*rtc_sh_get_time)(struct timespec *) = sh_rtc_gettimeofday;
int (*rtc_sh_set_time)(const time_t) = sh_rtc_settimeofday;
#else
void (*rtc_sh_get_time)(struct timespec *);
int (*rtc_sh_set_time)(const time_t);
#endif
/* Dummy RTC ops */
static void null_rtc_get_time(struct timespec *tv)
{
tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
tv->tv_nsec = 0;
}
static int null_rtc_set_time(const time_t secs)
{
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;
/*
* Scheduler clock - returns current time in nanosec units.
......@@ -70,7 +74,6 @@ void do_gettimeofday(struct timeval *tv)
tv->tv_sec = sec;
tv->tv_usec = usec;
}
EXPORT_SYMBOL(do_gettimeofday);
int do_settimeofday(struct timespec *tv)
......@@ -103,7 +106,6 @@ int do_settimeofday(struct timespec *tv)
return 0;
}
EXPORT_SYMBOL(do_settimeofday);
/* last time the RTC clock got updated */
......@@ -181,7 +183,6 @@ static int __init timer_init_sysfs(void)
sys_timer->dev.cls = &timer_sysclass;
return sysdev_register(&sys_timer->dev);
}
device_initcall(timer_init_sysfs);
void (*board_time_init)(void);
......@@ -193,13 +194,7 @@ void __init time_init(void)
clk_init();
if (rtc_sh_get_time) {
rtc_sh_get_time(&xtime);
} else {
xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0);
xtime.tv_nsec = 0;
}
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
......
......@@ -739,7 +739,7 @@ config NVRAM
config RTC
tristate "Enhanced Real Time Clock Support"
depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM
depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
......
......@@ -4,173 +4,4 @@
#ifndef _ASM_MC146818RTC_H
#define _ASM_MC146818RTC_H
#ifdef CONFIG_SH_MPC1211
#undef _ASM_MC146818RTC_H
#undef RTC_IRQ
#include <asm/mpc1211/mc146818rtc.h>
#else
#include <asm/rtc.h>
#define RTC_ALWAYS_BCD 1
/* FIXME:RTC Interrupt feature is not implemented yet. */
#undef RTC_IRQ
#define RTC_IRQ 0
#if defined(CONFIG_CPU_SH3)
#define RTC_PORT(n) (R64CNT+(n)*2)
#define CMOS_READ(addr) __CMOS_READ(addr,b)
#define CMOS_WRITE(val,addr) __CMOS_WRITE(val,addr,b)
#elif defined(CONFIG_SH_SECUREEDGE5410)
#include <asm/snapgear.h>
#define RTC_PORT(n) SECUREEDGE_IOPORT_ADDR
#define CMOS_READ(addr) secureedge5410_cmos_read(addr)
#define CMOS_WRITE(val,addr) secureedge5410_cmos_write(val,addr)
extern unsigned char secureedge5410_cmos_read(int addr);
extern void secureedge5410_cmos_write(unsigned char val, int addr);
#elif defined(CONFIG_CPU_SH4)
#define RTC_PORT(n) (R64CNT+(n)*4)
#define CMOS_READ(addr) __CMOS_READ(addr,w)
#define CMOS_WRITE(val,addr) __CMOS_WRITE(val,addr,w)
#endif
#define __CMOS_READ(addr, s) ({ \
unsigned char val=0, rcr1, rcr2, r64cnt, retry; \
switch(addr) { \
case RTC_SECONDS: \
val = ctrl_inb(RSECCNT); \
break; \
case RTC_SECONDS_ALARM: \
val = ctrl_inb(RSECAR); \
break; \
case RTC_MINUTES: \
val = ctrl_inb(RMINCNT); \
break; \
case RTC_MINUTES_ALARM: \
val = ctrl_inb(RMINAR); \
break; \
case RTC_HOURS: \
val = ctrl_inb(RHRCNT); \
break; \
case RTC_HOURS_ALARM: \
val = ctrl_inb(RHRAR); \
break; \
case RTC_DAY_OF_WEEK: \
val = ctrl_inb(RWKCNT); \
break; \
case RTC_DAY_OF_MONTH: \
val = ctrl_inb(RDAYCNT); \
break; \
case RTC_MONTH: \
val = ctrl_inb(RMONCNT); \
break; \
case RTC_YEAR: \
val = ctrl_in##s(RYRCNT); \
break; \
case RTC_REG_A: /* RTC_FREQ_SELECT */ \
rcr2 = ctrl_inb(RCR2); \
val = (rcr2 & RCR2_PESMASK) >> 4; \
rcr1 = ctrl_inb(RCR1); \
rcr1 = (rcr1 & (RCR1_CIE | RCR1_AIE)) | RCR1_AF;\
retry = 0; \
do { \
ctrl_outb(rcr1, RCR1); /* clear CF */ \
r64cnt = ctrl_inb(R64CNT); \
} while((ctrl_inb(RCR1) & RCR1_CF) && retry++ < 1000);\
r64cnt ^= RTC_BIT_INVERTED; \
if(r64cnt == 0x7f || r64cnt == 0) \
val |= RTC_UIP; \
break; \
case RTC_REG_B: /* RTC_CONTROL */ \
rcr1 = ctrl_inb(RCR1); \
rcr2 = ctrl_inb(RCR2); \
if(rcr1 & RCR1_CIE) val |= RTC_UIE; \
if(rcr1 & RCR1_AIE) val |= RTC_AIE; \
if(rcr2 & RCR2_PESMASK) val |= RTC_PIE; \
if(!(rcr2 & RCR2_START))val |= RTC_SET; \
val |= RTC_24H; \
break; \
case RTC_REG_C: /* RTC_INTR_FLAGS */ \
rcr1 = ctrl_inb(RCR1); \
rcr1 &= ~(RCR1_CF | RCR1_AF); \
ctrl_outb(rcr1, RCR1); \
rcr2 = ctrl_inb(RCR2); \
rcr2 &= ~RCR2_PEF; \
ctrl_outb(rcr2, RCR2); \
break; \
case RTC_REG_D: /* RTC_VALID */ \
/* Always valid ... */ \
val = RTC_VRT; \
break; \
default: \
break; \
} \
val; \
})
#define __CMOS_WRITE(val, addr, s) ({ \
unsigned char rcr1,rcr2; \
switch(addr) { \
case RTC_SECONDS: \
ctrl_outb(val, RSECCNT); \
break; \
case RTC_SECONDS_ALARM: \
ctrl_outb(val, RSECAR); \
break; \
case RTC_MINUTES: \
ctrl_outb(val, RMINCNT); \
break; \
case RTC_MINUTES_ALARM: \
ctrl_outb(val, RMINAR); \
break; \
case RTC_HOURS: \
ctrl_outb(val, RHRCNT); \
break; \
case RTC_HOURS_ALARM: \
ctrl_outb(val, RHRAR); \
break; \
case RTC_DAY_OF_WEEK: \
ctrl_outb(val, RWKCNT); \
break; \
case RTC_DAY_OF_MONTH: \
ctrl_outb(val, RDAYCNT); \
break; \
case RTC_MONTH: \
ctrl_outb(val, RMONCNT); \
break; \
case RTC_YEAR: \
ctrl_out##s((ctrl_in##s(RYRCNT) & 0xff00) | (val & 0xff), RYRCNT);\
break; \
case RTC_REG_A: /* RTC_FREQ_SELECT */ \
rcr2 = ctrl_inb(RCR2); \
if((val & RTC_DIV_CTL) == RTC_DIV_RESET2) \
rcr2 |= RCR2_RESET; \
ctrl_outb(rcr2, RCR2); \
break; \
case RTC_REG_B: /* RTC_CONTROL */ \
rcr1 = (ctrl_inb(RCR1) & 0x99) | RCR1_AF; \
if(val & RTC_AIE) rcr1 |= RCR1_AIE; \
else rcr1 &= ~RCR1_AIE; \
if(val & RTC_UIE) rcr1 |= RCR1_CIE; \
else rcr1 &= ~RCR1_CIE; \
ctrl_outb(rcr1, RCR1); \
rcr2 = ctrl_inb(RCR2); \
if(val & RTC_SET) rcr2 &= ~RCR2_START; \
else rcr2 |= RCR2_START; \
ctrl_outb(rcr2, RCR2); \
break; \
case RTC_REG_C: /* RTC_INTR_FLAGS */ \
break; \
case RTC_REG_D: /* RTC_VALID */ \
break; \
default: \
break; \
} \
})
#endif /* CONFIG_SH_MPC1211 */
#endif /* _ASM_MC146818RTC_H */
#ifndef _ASM_RTC_H
#define _ASM_RTC_H
#ifdef __KERNEL__
#include <asm/machvec.h>
#include <asm/cpu/rtc.h>
extern void sh_rtc_gettimeofday(struct timespec *ts);
extern int sh_rtc_settimeofday(const time_t secs);
extern void (*board_time_init)(void);
extern void (*rtc_sh_get_time)(struct timespec *);
extern int (*rtc_sh_set_time)(const time_t);
/* RCR1 Bits */
#define RCR1_CF 0x80 /* Carry Flag */
#define RCR1_CIE 0x10 /* Carry Interrupt Enable */
#define RCR1_AIE 0x08 /* Alarm Interrupt Enable */
#define RCR1_AF 0x01 /* Alarm Flag */
/* RCR2 Bits */
#define RCR2_PEF 0x80 /* PEriodic interrupt Flag */
#define RCR2_PESMASK 0x70 /* Periodic interrupt Set */
#define RCR2_RTCEN 0x08 /* ENable RTC */
#define RCR2_ADJ 0x04 /* ADJustment (30-second) */
#define RCR2_RESET 0x02 /* Reset bit */
#define RCR2_START 0x01 /* Start bit */
#endif /* __KERNEL__ */
#endif /* _ASM_RTC_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册