7a932e5702
This cleans up two ancient timer features that were never completed in the past, CONFIG_GENERIC_CLOCKEVENTS and CONFIG_ARCH_USES_GETTIMEOFFSET. There was only one user left for the ARCH_USES_GETTIMEOFFSET variant of clocksource implementations, the ARM EBSA110 platform. Rather than changing to use modern timekeeping, we remove the platform entirely as Russell no longer uses his machine and nobody else seems to have one any more. The conditional code for using arch_gettimeoffset() is removed as a result. For CONFIG_GENERIC_CLOCKEVENTS, there are still a couple of platforms not using clockevent drivers: parisc, ia64, most of m68k, and one Arm platform. These all do timer ticks slighly differently, and this gets cleaned up to the point they at least all call the same helper function. Instead of most platforms using 'select GENERIC_CLOCKEVENTS' in Kconfig, the polarity is now reversed, with the few remaining ones selecting LEGACY_TIMER_TICK instead. Signed-off-by: Arnd Bergmann <arnd@arndb.de> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAl/Y1v8ACgkQmmx57+YA GNmCvQ/9EDlgCt92r8SB+LGafDtgB8TUQZeIrs9S2mByzdxwnw0lxObIXFCnhQgh RpG3dR+ONRDnC5eI149B377JOEFMZWe2+BtYHUHkFARtUEWatslQcz7yAGvVRK/l TS/qReb6piKltlzuanF1bMZbjy2OhlaDRcm+OlC3y5mALR33M4emb+rJ6cSdfk3K v1iZhrxtfQT77ztesh/oPkPiyQ6kNcz7SfpyYOb6f5VLlml2BZ7YwBSVyGY7urHk RL3XqOUP4KKlMEAI8w0E2nvft6Fk+luziBhrMYWK0GvbmI1OESENuX/c6tgT2OQ1 DRaVHvcPG/EAY8adOKxxVyHhEJDSoz5GJV/EtjlOegsJk6RomczR1uuiT3Kvm7Ah PktMKv4xQht1E15KPSKbOvNIEP18w2s5z6gw+jVDv8pw42pVEQManm1D+BICqrhl fcpw6T1drf9UxAjwX4+zXtmNs+a+mqiFG8puU4VVgT4GpQ8umHvunXz2WUjZO0jc 3m8ErJHBvtJwW5TOHGyXnjl9SkwPzHOfF6IcXTYWEDU4/gQIK9TwUvCjLc0lE27t FMCV2ds7/K1CXwRgpa5IrefSkb8yOXSbRZ56NqqF7Ekxw4J5bYRSaY7jb+qD/e+3 5O1y+iPxFrpH+16hSahvzrtcdFNbLQvBBuRtEQOYuHLt2UJrNoU= =QpNs -----END PGP SIGNATURE----- Merge tag 'asm-generic-timers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic Pull asm-generic cross-architecture timer cleanup from Arnd Bergmann: "This cleans up two ancient timer features that were never completed in the past, CONFIG_GENERIC_CLOCKEVENTS and CONFIG_ARCH_USES_GETTIMEOFFSET. There was only one user left for the ARCH_USES_GETTIMEOFFSET variant of clocksource implementations, the ARM EBSA110 platform. Rather than changing to use modern timekeeping, we remove the platform entirely as Russell no longer uses his machine and nobody else seems to have one any more. The conditional code for using arch_gettimeoffset() is removed as a result. For CONFIG_GENERIC_CLOCKEVENTS, there are still a couple of platforms not using clockevent drivers: parisc, ia64, most of m68k, and one Arm platform. These all do timer ticks slighly differently, and this gets cleaned up to the point they at least all call the same helper function. Instead of most platforms using 'select GENERIC_CLOCKEVENTS' in Kconfig, the polarity is now reversed, with the few remaining ones selecting LEGACY_TIMER_TICK instead" * tag 'asm-generic-timers-5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic: timekeeping: default GENERIC_CLOCKEVENTS to enabled timekeeping: remove xtime_update m68k: remove timer_interrupt() function m68k: change remaining timers to legacy_timer_tick m68k: m68328: use legacy_timer_tick() m68k: sun3/sun3c: use legacy_timer_tick m68k: split heartbeat out of timer function m68k: coldfire: use legacy_timer_tick() parisc: use legacy_timer_tick ARM: rpc: use legacy_timer_tick ia64: convert to legacy_timer_tick timekeeping: add CONFIG_LEGACY_TIMER_TICK timekeeping: remove arch_gettimeoffset net: remove am79c961a driver ARM: remove ebsa110 platform
269 lines
5.8 KiB
C
269 lines
5.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/init.h>
|
|
#include <linux/types.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/tty.h>
|
|
#include <linux/console.h>
|
|
#include <linux/rtc.h>
|
|
#include <linux/vt_kern.h>
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <asm/setup.h>
|
|
#include <asm/bootinfo.h>
|
|
#include <asm/bootinfo-apollo.h>
|
|
#include <asm/byteorder.h>
|
|
#include <asm/apollohw.h>
|
|
#include <asm/irq.h>
|
|
#include <asm/machdep.h>
|
|
|
|
u_long sio01_physaddr;
|
|
u_long sio23_physaddr;
|
|
u_long rtc_physaddr;
|
|
u_long pica_physaddr;
|
|
u_long picb_physaddr;
|
|
u_long cpuctrl_physaddr;
|
|
u_long timer_physaddr;
|
|
u_long apollo_model;
|
|
|
|
extern void dn_sched_init(void);
|
|
extern void dn_init_IRQ(void);
|
|
extern int dn_dummy_hwclk(int, struct rtc_time *);
|
|
extern void dn_dummy_reset(void);
|
|
#ifdef CONFIG_HEARTBEAT
|
|
static void dn_heartbeat(int on);
|
|
#endif
|
|
static irqreturn_t dn_timer_int(int irq,void *);
|
|
static void dn_get_model(char *model);
|
|
static const char *apollo_models[] = {
|
|
[APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)",
|
|
[APOLLO_DN3010-APOLLO_DN3000] = "DN3010 (Otter)",
|
|
[APOLLO_DN3500-APOLLO_DN3000] = "DN3500 (Cougar II)",
|
|
[APOLLO_DN4000-APOLLO_DN3000] = "DN4000 (Mink)",
|
|
[APOLLO_DN4500-APOLLO_DN3000] = "DN4500 (Roadrunner)"
|
|
};
|
|
|
|
int __init apollo_parse_bootinfo(const struct bi_record *record)
|
|
{
|
|
int unknown = 0;
|
|
const void *data = record->data;
|
|
|
|
switch (be16_to_cpu(record->tag)) {
|
|
case BI_APOLLO_MODEL:
|
|
apollo_model = be32_to_cpup(data);
|
|
break;
|
|
|
|
default:
|
|
unknown=1;
|
|
}
|
|
|
|
return unknown;
|
|
}
|
|
|
|
static void __init dn_setup_model(void)
|
|
{
|
|
pr_info("Apollo hardware found: [%s]\n",
|
|
apollo_models[apollo_model - APOLLO_DN3000]);
|
|
|
|
switch(apollo_model) {
|
|
case APOLLO_UNKNOWN:
|
|
panic("Unknown apollo model");
|
|
break;
|
|
case APOLLO_DN3000:
|
|
case APOLLO_DN3010:
|
|
sio01_physaddr=SAU8_SIO01_PHYSADDR;
|
|
rtc_physaddr=SAU8_RTC_PHYSADDR;
|
|
pica_physaddr=SAU8_PICA;
|
|
picb_physaddr=SAU8_PICB;
|
|
cpuctrl_physaddr=SAU8_CPUCTRL;
|
|
timer_physaddr=SAU8_TIMER;
|
|
break;
|
|
case APOLLO_DN4000:
|
|
sio01_physaddr=SAU7_SIO01_PHYSADDR;
|
|
sio23_physaddr=SAU7_SIO23_PHYSADDR;
|
|
rtc_physaddr=SAU7_RTC_PHYSADDR;
|
|
pica_physaddr=SAU7_PICA;
|
|
picb_physaddr=SAU7_PICB;
|
|
cpuctrl_physaddr=SAU7_CPUCTRL;
|
|
timer_physaddr=SAU7_TIMER;
|
|
break;
|
|
case APOLLO_DN4500:
|
|
panic("Apollo model not yet supported");
|
|
break;
|
|
case APOLLO_DN3500:
|
|
sio01_physaddr=SAU7_SIO01_PHYSADDR;
|
|
sio23_physaddr=SAU7_SIO23_PHYSADDR;
|
|
rtc_physaddr=SAU7_RTC_PHYSADDR;
|
|
pica_physaddr=SAU7_PICA;
|
|
picb_physaddr=SAU7_PICB;
|
|
cpuctrl_physaddr=SAU7_CPUCTRL;
|
|
timer_physaddr=SAU7_TIMER;
|
|
break;
|
|
default:
|
|
panic("Undefined apollo model");
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
int dn_serial_console_wait_key(struct console *co) {
|
|
|
|
while(!(sio01.srb_csrb & 1))
|
|
barrier();
|
|
return sio01.rhrb_thrb;
|
|
}
|
|
|
|
void dn_serial_console_write (struct console *co, const char *str,unsigned int count)
|
|
{
|
|
while(count--) {
|
|
if (*str == '\n') {
|
|
sio01.rhrb_thrb = (unsigned char)'\r';
|
|
while (!(sio01.srb_csrb & 0x4))
|
|
;
|
|
}
|
|
sio01.rhrb_thrb = (unsigned char)*str++;
|
|
while (!(sio01.srb_csrb & 0x4))
|
|
;
|
|
}
|
|
}
|
|
|
|
void dn_serial_print (const char *str)
|
|
{
|
|
while (*str) {
|
|
if (*str == '\n') {
|
|
sio01.rhrb_thrb = (unsigned char)'\r';
|
|
while (!(sio01.srb_csrb & 0x4))
|
|
;
|
|
}
|
|
sio01.rhrb_thrb = (unsigned char)*str++;
|
|
while (!(sio01.srb_csrb & 0x4))
|
|
;
|
|
}
|
|
}
|
|
|
|
void __init config_apollo(void)
|
|
{
|
|
int i;
|
|
|
|
dn_setup_model();
|
|
|
|
mach_sched_init=dn_sched_init; /* */
|
|
mach_init_IRQ=dn_init_IRQ;
|
|
mach_hwclk = dn_dummy_hwclk; /* */
|
|
mach_reset = dn_dummy_reset; /* */
|
|
#ifdef CONFIG_HEARTBEAT
|
|
mach_heartbeat = dn_heartbeat;
|
|
#endif
|
|
mach_get_model = dn_get_model;
|
|
|
|
cpuctrl=0xaa00;
|
|
|
|
/* clear DMA translation table */
|
|
for(i=0;i<0x400;i++)
|
|
addr_xlat_map[i]=0;
|
|
|
|
}
|
|
|
|
irqreturn_t dn_timer_int(int irq, void *dev_id)
|
|
{
|
|
volatile unsigned char x;
|
|
|
|
legacy_timer_tick(1);
|
|
timer_heartbeat();
|
|
|
|
x = *(volatile unsigned char *)(apollo_timer + 3);
|
|
x = *(volatile unsigned char *)(apollo_timer + 5);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
void dn_sched_init(void)
|
|
{
|
|
/* program timer 1 */
|
|
*(volatile unsigned char *)(apollo_timer + 3) = 0x01;
|
|
*(volatile unsigned char *)(apollo_timer + 1) = 0x40;
|
|
*(volatile unsigned char *)(apollo_timer + 5) = 0x09;
|
|
*(volatile unsigned char *)(apollo_timer + 7) = 0xc4;
|
|
|
|
/* enable IRQ of PIC B */
|
|
*(volatile unsigned char *)(pica+1)&=(~8);
|
|
|
|
#if 0
|
|
pr_info("*(0x10803) %02x\n",
|
|
*(volatile unsigned char *)(apollo_timer + 0x3));
|
|
pr_info("*(0x10803) %02x\n",
|
|
*(volatile unsigned char *)(apollo_timer + 0x3));
|
|
#endif
|
|
|
|
if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", NULL))
|
|
pr_err("Couldn't register timer interrupt\n");
|
|
}
|
|
|
|
int dn_dummy_hwclk(int op, struct rtc_time *t) {
|
|
|
|
|
|
if(!op) { /* read */
|
|
t->tm_sec=rtc->second;
|
|
t->tm_min=rtc->minute;
|
|
t->tm_hour=rtc->hours;
|
|
t->tm_mday=rtc->day_of_month;
|
|
t->tm_wday=rtc->day_of_week;
|
|
t->tm_mon = rtc->month - 1;
|
|
t->tm_year=rtc->year;
|
|
if (t->tm_year < 70)
|
|
t->tm_year += 100;
|
|
} else {
|
|
rtc->second=t->tm_sec;
|
|
rtc->minute=t->tm_min;
|
|
rtc->hours=t->tm_hour;
|
|
rtc->day_of_month=t->tm_mday;
|
|
if(t->tm_wday!=-1)
|
|
rtc->day_of_week=t->tm_wday;
|
|
rtc->month = t->tm_mon + 1;
|
|
rtc->year = t->tm_year % 100;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
void dn_dummy_reset(void) {
|
|
|
|
dn_serial_print("The end !\n");
|
|
|
|
for(;;);
|
|
|
|
}
|
|
|
|
void dn_dummy_waitbut(void) {
|
|
|
|
dn_serial_print("waitbut\n");
|
|
|
|
}
|
|
|
|
static void dn_get_model(char *model)
|
|
{
|
|
strcpy(model, "Apollo ");
|
|
if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500)
|
|
strcat(model, apollo_models[apollo_model - APOLLO_DN3000]);
|
|
}
|
|
|
|
#ifdef CONFIG_HEARTBEAT
|
|
static int dn_cpuctrl=0xff00;
|
|
|
|
static void dn_heartbeat(int on) {
|
|
|
|
if(on) {
|
|
dn_cpuctrl&=~0x100;
|
|
cpuctrl=dn_cpuctrl;
|
|
}
|
|
else {
|
|
dn_cpuctrl&=~0x100;
|
|
dn_cpuctrl|=0x100;
|
|
cpuctrl=dn_cpuctrl;
|
|
}
|
|
}
|
|
#endif
|
|
|