Date: Thu, 18 Dec 1997 15:29:06 GMT From: Roman Hodek To: linux-m68k@lists.linux-m68k.org Subject: L68K: Heartbeat cleanup Sender: owner-linux-m68k@phil.uni-sb.de Ok, here is the promised heartbeat cleanup patch. There's now a function pointer mach_heartbeat, as Geert proposed. I also needed a var mach_heartbeat_irq, which tells kernel/time.c which interrupt counter to watch. And while a was at it, I decided that atari/config.c has grown too big now... :-) So I spinned off some parts: all time-related stuff (scheduler_init, hwclk stuff) has been moved to atari/time.c, and all the debugging/serial console functions to atari/debug.c. This also enabled me to clean up all the headers that atari/config.c includes, they were a bit much... I didn't dare doing the same for Amiga... :-), but there also isn't as much clutter as was in atari/config.c. Roman ------------------------------------------------------------------------------ diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/amiga/config.c linux-2.1.72/arch/m68k/amiga/config.c --- linux-2.1.72.orig/arch/m68k/amiga/config.c Thu Dec 18 11:19:38 1997 +++ linux-2.1.72/arch/m68k/amiga/config.c Thu Dec 18 14:20:45 1997 @@ -85,6 +85,7 @@ void amiga_serial_console_write(struct console *co, const char *s, unsigned int count); static void amiga_debug_init(void); +static void amiga_heartbeat(int on); static struct console amiga_console_driver = { "debug", @@ -381,6 +382,10 @@ mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */ mach_sysrq_xlate = amiga_sysrq_xlate; #endif +#ifdef CONFIG_HEARTBEAT + mach_heartbeat = amiga_heartbeat; + mach_heartbeat_irq = SYS_IRQS + IRQ_AMIGA_CIAB_TA; +#endif /* Fill in the clock values (based on the 700 kHz E-Clock) */ amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ @@ -888,6 +893,15 @@ } } +#ifdef CONFIG_HEARTBEAT +static void amiga_heartbeat(int on) +{ + if (on) + ciaa.pra &= ~2; + else + ciaa.pra |= 2; +} +#endif /* * Amiga specific parts of /proc diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/Makefile linux-2.1.72/arch/m68k/atari/Makefile --- linux-2.1.72.orig/arch/m68k/atari/Makefile Sun Sep 14 22:47:02 1997 +++ linux-2.1.72/arch/m68k/atari/Makefile Thu Dec 18 14:03:21 1997 @@ -8,7 +8,8 @@ # Note 2! The CFLAGS definitions are now in the main makefile... O_TARGET := atari.o -O_OBJS := config.o atakeyb.o ataints.o stdma.o atasound.o joystick.o stram.o +O_OBJS := config.o time.o debug.o atakeyb.o ataints.o stdma.o atasound.o \ + joystick.o stram.o OX_OBJS := atari_ksyms.o include $(TOPDIR)/Rules.make diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/config.c linux-2.1.72/arch/m68k/atari/config.c --- linux-2.1.72.orig/arch/m68k/atari/config.c Wed Dec 17 13:36:38 1997 +++ linux-2.1.72/arch/m68k/atari/config.c Thu Dec 18 16:09:49 1997 @@ -27,30 +27,17 @@ #include #include #include -#include -#include -#include #include -#include #include -#include #include #include #include #include #include - #include -#include -#include -#include #include -#ifdef CONFIG_KGDB -#include -#endif - u_long atari_mch_cookie; u_long atari_mch_type = 0; struct atari_hw_present atari_hw_present; @@ -58,9 +45,14 @@ int atari_dont_touch_floppy_select = 0; int atari_rtc_year_offset; -extern char m68k_debug_device[]; +/* local function prototypes */ +static void atari_reset( void ); +#ifdef CONFIG_ATARI_FLOPPY +extern void atari_floppy_setup(char *, int *); +#endif +static void atari_get_model(char *model); +static int atari_get_hardware_list(char *buffer); -static void atari_sched_init(void (*)(int, void *, struct pt_regs *)); /* atari specific keyboard functions */ extern int atari_keyb_init(void); extern int atari_kbdrate (struct kbd_repeat *); @@ -73,45 +65,24 @@ extern void atari_enable_irq (unsigned int); extern void atari_disable_irq (unsigned int); extern int atari_get_irq_list (char *buf); -static void atari_get_model(char *model); -static int atari_get_hardware_list(char *buffer); -/* atari specific timer functions */ -static unsigned long atari_gettimeoffset (void); -static void atari_mste_gettod (int *, int *, int *, int *, int *, int *); -static void atari_gettod (int *, int *, int *, int *, int *, int *); -static int atari_mste_hwclk (int, struct hwclk_time *); -static int atari_hwclk (int, struct hwclk_time *); -static int atari_mste_set_clock_mmss (unsigned long); -static int atari_set_clock_mmss (unsigned long); extern void atari_mksound( unsigned int count, unsigned int ticks ); -static void atari_reset( void ); -#ifdef CONFIG_ATARI_FLOPPY -extern void atari_floppy_setup(char *, int *); +#ifdef CONFIG_HEARTBEAT +static void atari_heartbeat( int on ); #endif extern struct consw fb_con; -static void atari_debug_init(void); -static struct console atari_console_driver = { - "debug", - NULL, /* write */ - NULL, /* read */ - NULL, /* device */ - NULL, /* wait_key */ - NULL, /* unblank */ - NULL, /* setup */ - CON_PRINTBUFFER, - -1, - 0, - NULL -}; - -/* Flag that Modem1 port is already initialized and used */ -int atari_MFP_init_done = 0; -/* Flag that Modem1 port is already initialized and used */ -int atari_SCC_init_done = 0; -/* Can be set somewhere, if a SCC master reset has already be done and should - * not be repeated; used by kgdb */ -int atari_SCC_reset_done = 0; +/* atari specific timer functions (in time.c) */ +extern void atari_sched_init(void (*)(int, void *, struct pt_regs *)); +extern unsigned long atari_gettimeoffset (void); +extern void atari_mste_gettod (int *, int *, int *, int *, int *, int *); +extern void atari_tt_gettod (int *, int *, int *, int *, int *, int *); +extern int atari_mste_hwclk (int, struct hwclk_time *); +extern int atari_tt_hwclk (int, struct hwclk_time *); +extern int atari_mste_set_clock_mmss (unsigned long); +extern int atari_tt_set_clock_mmss (unsigned long); + +/* atari specific debug functions (in debug.c) */ +extern void atari_debug_init(void); #ifdef CONFIG_MAGIC_SYSRQ static char atari_sysrq_xlate[128] = @@ -352,6 +323,10 @@ mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */ mach_sysrq_xlate = atari_sysrq_xlate; #endif +#ifdef CONFIG_HEARTBEAT + mach_heartbeat = atari_heartbeat; + mach_heartbeat_irq = IRQ_MFP_TIMC; +#endif /* Set switches as requested by the user */ if (atari_switches & ATARI_SWITCH_IKBD) @@ -505,9 +480,9 @@ if (hwreg_present( &tt_rtc.regsel )) { ATARIHW_SET(TT_CLK); printk( "TT_CLK " ); - mach_gettod = atari_gettod; - mach_hwclk = atari_hwclk; - mach_set_clock_mmss = atari_set_clock_mmss; + mach_gettod = atari_tt_gettod; + mach_hwclk = atari_tt_hwclk; + mach_set_clock_mmss = atari_tt_set_clock_mmss; } if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) { ATARIHW_SET(MSTE_CLK); @@ -612,704 +587,23 @@ atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68; } -__initfunc(static void -atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))) -{ - /* set Timer C data Register */ - mfp.tim_dt_c = INT_TICKS; - /* start timer C, div = 1:100 */ - mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; - /* install interrupt service routine for MFP Timer C */ - request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW, - "timer", timer_routine); -} - -/* ++andreas: gettimeoffset fixed to check for pending interrupt */ - -#define TICK_SIZE 10000 - -/* This is always executed with interrupts disabled. */ -static unsigned long atari_gettimeoffset (void) -{ - unsigned long ticks, offset = 0; - - /* read MFP timer C current value */ - ticks = mfp.tim_dt_c; - /* The probability of underflow is less than 2% */ - if (ticks > INT_TICKS - INT_TICKS / 50) - /* Check for pending timer interrupt */ - if (mfp.int_pn_b & (1 << 5)) - offset = TICK_SIZE; - - ticks = INT_TICKS - ticks; - ticks = ticks * 10000L / INT_TICKS; - - return ticks + offset; -} - - -static void -mste_read(struct MSTE_RTC *val) -{ -#define COPY(v) val->v=(mste_rtc.v & 0xf) - do { - COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; - COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; - COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; - COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ; - COPY(year_tens) ; - /* prevent from reading the clock while it changed */ - } while (val->sec_ones != (mste_rtc.sec_ones & 0xf)); -#undef COPY -} - -static void -mste_write(struct MSTE_RTC *val) -{ -#define COPY(v) mste_rtc.v=val->v - do { - COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; - COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; - COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; - COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ; - COPY(year_tens) ; - /* prevent from writing the clock while it changed */ - } while (val->sec_ones != (mste_rtc.sec_ones & 0xf)); -#undef COPY -} - -#define RTC_READ(reg) \ - ({ unsigned char __val; \ - outb(reg,&tt_rtc.regsel); \ - __val = tt_rtc.data; \ - __val; \ - }) - -#define RTC_WRITE(reg,val) \ - do { \ - outb(reg,&tt_rtc.regsel); \ - tt_rtc.data = (val); \ - } while(0) - - -static void atari_mste_gettod (int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp) -{ - int hr24=0, hour; - struct MSTE_RTC val; - - mste_rtc.mode=(mste_rtc.mode | 1); - hr24=mste_rtc.mon_tens & 1; - mste_rtc.mode=(mste_rtc.mode & ~1); - - mste_read(&val); - *secp = val.sec_ones + val.sec_tens * 10; - *minp = val.min_ones + val.min_tens * 10; - hour = val.hr_ones + val.hr_tens * 10; - if (!hr24) { - if (hour == 12 || hour == 12 + 20) - hour -= 12; - if (hour >= 20) - hour += 12 - 20; - } - *hourp = hour; - *dayp = val.day_ones + val.day_tens * 10; - *monp = val.mon_ones + val.mon_tens * 10; - *yearp = val.year_ones + val.year_tens * 10 + 80; -} - - -static void atari_gettod (int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp) -{ - unsigned char ctrl; - int hour, pm; - - while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ; - while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ; - - *secp = RTC_READ(RTC_SECONDS); - *minp = RTC_READ(RTC_MINUTES); - hour = RTC_READ(RTC_HOURS); - *dayp = RTC_READ(RTC_DAY_OF_MONTH); - *monp = RTC_READ(RTC_MONTH); - *yearp = RTC_READ(RTC_YEAR); - pm = hour & 0x80; - hour &= ~0x80; - - ctrl = RTC_READ(RTC_CONTROL); - - if (!(ctrl & RTC_DM_BINARY)) { - BCD_TO_BIN(*secp); - BCD_TO_BIN(*minp); - BCD_TO_BIN(hour); - BCD_TO_BIN(*dayp); - BCD_TO_BIN(*monp); - BCD_TO_BIN(*yearp); - } - if (!(ctrl & RTC_24H)) { - if (!pm && hour == 12) - hour = 0; - else if (pm && hour != 12) - hour += 12; - } - *hourp = hour; - - /* Adjust values (let the setup valid) */ - *yearp += atari_rtc_year_offset; -} - -#define HWCLK_POLL_INTERVAL 5 - -static int atari_mste_hwclk( int op, struct hwclk_time *t ) +#ifdef CONFIG_HEARTBEAT +static void atari_heartbeat( int on ) { - int hour, year; - int hr24=0; - struct MSTE_RTC val; - - mste_rtc.mode=(mste_rtc.mode | 1); - hr24=mste_rtc.mon_tens & 1; - mste_rtc.mode=(mste_rtc.mode & ~1); - - if (op) { - /* write: prepare values */ - - val.sec_ones = t->sec % 10; - val.sec_tens = t->sec / 10; - val.min_ones = t->min % 10; - val.min_tens = t->min / 10; - hour = t->hour; - if (!hr24) { - if (hour > 11) - hour += 20 - 12; - if (hour == 0 || hour == 20) - hour += 12; - } - val.hr_ones = hour % 10; - val.hr_tens = hour / 10; - val.day_ones = t->day % 10; - val.day_tens = t->day / 10; - val.mon_ones = (t->mon+1) % 10; - val.mon_tens = (t->mon+1) / 10; - year = t->year - 80; - val.year_ones = year % 10; - val.year_tens = year / 10; - val.weekday = t->wday; - mste_write(&val); - mste_rtc.mode=(mste_rtc.mode | 1); - val.year_ones = (year % 4); /* leap year register */ - mste_rtc.mode=(mste_rtc.mode & ~1); - } - else { - mste_read(&val); - t->sec = val.sec_ones + val.sec_tens * 10; - t->min = val.min_ones + val.min_tens * 10; - hour = val.hr_ones + val.hr_tens * 10; - if (!hr24) { - if (hour == 12 || hour == 12 + 20) - hour -= 12; - if (hour >= 20) - hour += 12 - 20; - } - t->hour = hour; - t->day = val.day_ones + val.day_tens * 10; - t->mon = val.mon_ones + val.mon_tens * 10 - 1; - t->year = val.year_ones + val.year_tens * 10 + 80; - t->wday = val.weekday; - } - return 0; -} + unsigned char tmp; + unsigned long flags; -static int atari_hwclk( int op, struct hwclk_time *t ) -{ - int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; - unsigned long flags; - unsigned char ctrl; - int pm = 0; - - ctrl = RTC_READ(RTC_CONTROL); /* control registers are - * independent from the UIP */ - - if (op) { - /* write: prepare values */ - - sec = t->sec; - min = t->min; - hour = t->hour; - day = t->day; - mon = t->mon + 1; - year = t->year - atari_rtc_year_offset; - wday = t->wday + (t->wday >= 0); - - if (!(ctrl & RTC_24H)) { - if (hour > 11) { - pm = 0x80; - if (hour != 12) - hour -= 12; - } - else if (hour == 0) - hour = 12; - } - - if (!(ctrl & RTC_DM_BINARY)) { - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hour); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(year); - if (wday >= 0) BIN_TO_BCD(wday); - } - } + if (atari_dont_touch_floppy_select) + return; - /* Reading/writing the clock registers is a bit critical due to - * the regular update cycle of the RTC. While an update is in - * progress, registers 0..9 shouldn't be touched. - * The problem is solved like that: If an update is currently in - * progress (the UIP bit is set), the process sleeps for a while - * (50ms). This really should be enough, since the update cycle - * normally needs 2 ms. - * If the UIP bit reads as 0, we have at least 244 usecs until the - * update starts. This should be enough... But to be sure, - * additionally the RTC_SET bit is set to prevent an update cycle. - */ - - while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) { - current->state = TASK_INTERRUPTIBLE; - current->timeout = jiffies + HWCLK_POLL_INTERVAL; - schedule(); - } - save_flags(flags); cli(); - RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET ); - if (!op) { - sec = RTC_READ( RTC_SECONDS ); - min = RTC_READ( RTC_MINUTES ); - hour = RTC_READ( RTC_HOURS ); - day = RTC_READ( RTC_DAY_OF_MONTH ); - mon = RTC_READ( RTC_MONTH ); - year = RTC_READ( RTC_YEAR ); - wday = RTC_READ( RTC_DAY_OF_WEEK ); - } - else { - RTC_WRITE( RTC_SECONDS, sec ); - RTC_WRITE( RTC_MINUTES, min ); - RTC_WRITE( RTC_HOURS, hour + pm); - RTC_WRITE( RTC_DAY_OF_MONTH, day ); - RTC_WRITE( RTC_MONTH, mon ); - RTC_WRITE( RTC_YEAR, year ); - if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday ); - } - RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET ); - restore_flags(flags); - - if (!op) { - /* read: adjust values */ - - if (hour & 0x80) { - hour &= ~0x80; - pm = 1; - } - - if (!(ctrl & RTC_DM_BINARY)) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - BCD_TO_BIN(wday); - } - - if (!(ctrl & RTC_24H)) { - if (!pm && hour == 12) - hour = 0; - else if (pm && hour != 12) - hour += 12; - } - - t->sec = sec; - t->min = min; - t->hour = hour; - t->day = day; - t->mon = mon - 1; - t->year = year + atari_rtc_year_offset; - t->wday = wday - 1; - } - - return( 0 ); -} - - -static int atari_mste_set_clock_mmss (unsigned long nowtime) -{ - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - struct MSTE_RTC val; - unsigned char rtc_minutes; - - mste_read(&val); - rtc_minutes= val.min_ones + val.min_tens * 10; - if ((rtc_minutes < real_minutes - ? real_minutes - rtc_minutes - : rtc_minutes - real_minutes) < 30) - { - val.sec_ones = real_seconds % 10; - val.sec_tens = real_seconds / 10; - val.min_ones = real_minutes % 10; - val.min_tens = real_minutes / 10; - mste_write(&val); - } - else - return -1; - return 0; -} - -static int atari_set_clock_mmss (unsigned long nowtime) -{ - int retval = 0; - short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; - unsigned char save_control, save_freq_select, rtc_minutes; - - save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */ - RTC_WRITE (RTC_CONTROL, save_control | RTC_SET); - - save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */ - RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2); - - rtc_minutes = RTC_READ (RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY)) - BCD_TO_BIN (rtc_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 30 minutes. */ - if ((rtc_minutes < real_minutes - ? real_minutes - rtc_minutes - : rtc_minutes - real_minutes) < 30) - { - if (!(save_control & RTC_DM_BINARY)) - { - BIN_TO_BCD (real_seconds); - BIN_TO_BCD (real_minutes); - } - RTC_WRITE (RTC_SECONDS, real_seconds); - RTC_WRITE (RTC_MINUTES, real_minutes); - } - else - retval = -1; - - RTC_WRITE (RTC_FREQ_SELECT, save_freq_select); - RTC_WRITE (RTC_CONTROL, save_control); - return retval; -} - - -static inline void ata_mfp_out (char c) -{ - while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ - barrier (); - mfp.usart_dta = c; -} - -void atari_mfp_console_write (struct console *co, const char *str, - unsigned int count) -{ - while (count--) { - if (*str == '\n') - ata_mfp_out( '\r' ); - ata_mfp_out( *str++ ); - } -} - -static inline void ata_scc_out (char c) -{ - do { - MFPDELAY(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - MFPDELAY(); - scc.cha_b_data = c; -} - -void atari_scc_console_write (struct console *co, const char *str, - unsigned int count) -{ - while (count--) { - if (*str == '\n') - ata_scc_out( '\r' ); - ata_scc_out( *str++ ); - } -} - -static inline void ata_midi_out (char c) -{ - while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ - barrier (); - acia.mid_data = c; -} - -void atari_midi_console_write (struct console *co, const char *str, - unsigned int count) -{ - while (count--) { - if (*str == '\n') - ata_midi_out( '\r' ); - ata_midi_out( *str++ ); - } -} - -static int ata_par_out (char c) -{ - unsigned char tmp; - /* This a some-seconds timeout in case no printer is connected */ - unsigned long i = loops_per_sec > 1 ? loops_per_sec : 10000000; - - while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */ - ; - if (!i) return( 0 ); - - sound_ym.rd_data_reg_sel = 15; /* select port B */ - sound_ym.wd_data = c; /* put char onto port */ - sound_ym.rd_data_reg_sel = 14; /* select port A */ + sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */ tmp = sound_ym.rd_data_reg_sel; - sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ - MFPDELAY(); /* wait a bit */ - sound_ym.wd_data = tmp | 0x20; /* set strobe H */ - return( 1 ); -} - -static void atari_par_console_write (struct console *co, const char *str, - unsigned int count) -{ - static int printer_present = 1; - - if (!printer_present) - return; - - while (count--) { - if (*str == '\n') - if (!ata_par_out( '\r' )) { - printer_present = 0; - return; - } - if (!ata_par_out( *str++ )) { - printer_present = 0; - return; - } - } -} - -#ifdef CONFIG_SERIAL_CONSOLE -int atari_mfp_console_wait_key(struct console *co) -{ - while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */ - barrier(); - return( mfp.usart_dta ); -} - -int atari_scc_console_wait_key(struct console *co) -{ - do { - MFPDELAY(); - } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ - MFPDELAY(); - return( scc.cha_b_data ); -} - -int atari_midi_console_wait_key(struct console *co) -{ - while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */ - barrier(); - return( acia.mid_data ); -} -#endif - -/* The following two functions do a quick'n'dirty initialization of the MFP or - * SCC serial ports. They're used by the debugging interface, kgdb, and the - * serial console code. */ -#ifndef CONFIG_SERIAL_CONSOLE -__initfunc(static void atari_init_mfp_port( int cflag )) -#else -void atari_init_mfp_port( int cflag ) -#endif -{ - /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 - * bps, resp., and work only correct if there's a RSVE or RSSPEED */ - static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; - int baud = cflag & CBAUD; - int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; - int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* baud_table[] starts at 1200bps */ - - mfp.trn_stat &= ~0x01; /* disable TX */ - mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ - mfp.tim_ct_cd &= 0x70; /* stop timer D */ - mfp.tim_dt_d = baud_table[baud]; - mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ - mfp.trn_stat |= 0x01; /* enable TX */ - - atari_MFP_init_done = 1; -} - -#define SCC_WRITE(reg,val) \ - do { \ - scc.cha_b_ctrl = (reg); \ - MFPDELAY(); \ - scc.cha_b_ctrl = (val); \ - MFPDELAY(); \ - } while(0) - -/* loops_per_sec isn't initialized yet, so we can't use udelay(). This does a - * delay of ~ 60us. */ -#define LONG_DELAY() \ - do { \ - int i; \ - for( i = 100; i > 0; --i ) \ - MFPDELAY(); \ - } while(0) - -#ifndef CONFIG_SERIAL_CONSOLE -__initfunc(static void atari_init_scc_port( int cflag )) -#else -void atari_init_scc_port( int cflag ) -#endif -{ - extern int atari_SCC_reset_done; - static int clksrc_table[9] = - /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ - { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; - static int brgsrc_table[9] = - /* reg 14: 0 = RTxC, 2 = PCLK */ - { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; - static int clkmode_table[9] = - /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ - { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; - static int div_table[9] = - /* reg12 (BRG low) */ - { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; - - int baud = cflag & CBAUD; - int clksrc, clkmode, div, reg3, reg5; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* tables starts at 1200bps */ - - clksrc = clksrc_table[baud]; - clkmode = clkmode_table[baud]; - div = div_table[baud]; - if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { - /* special treatment for TT, where rates >= 38400 are done via TRxC */ - clksrc = 0x28; /* TRxC */ - clkmode = baud == 6 ? 0xc0 : - baud == 7 ? 0x80 : /* really 76800bps */ - 0x40; /* really 153600bps */ - div = 0; - } - - reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; - reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; - - (void)scc.cha_b_ctrl; /* reset reg pointer */ - SCC_WRITE( 9, 0xc0 ); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode ); - SCC_WRITE( 3, reg3 ); - SCC_WRITE( 5, reg5 ); - SCC_WRITE( 9, 0 ); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCC_WRITE( 10, 0 ); /* NRZ mode */ - SCC_WRITE( 11, clksrc ); /* main clock source */ - SCC_WRITE( 12, div ); /* BRG value */ - SCC_WRITE( 13, 0 ); /* BRG high byte */ - SCC_WRITE( 14, brgsrc_table[baud] ); - SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); - SCC_WRITE( 3, reg3 | 1 ); - SCC_WRITE( 5, reg5 | 8 ); - - atari_SCC_reset_done = 1; - atari_SCC_init_done = 1; -} - -#ifndef CONFIG_SERIAL_CONSOLE -__initfunc(static void atari_init_midi_port( int cflag )) -#else -void atari_init_midi_port( int cflag ) -#endif -{ - int baud = cflag & CBAUD; - int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; - /* warning 7N1 isn't possible! (instead 7O2 is used...) */ - int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; - int div; - - /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as - * default) the standard MIDI speed 31250. */ - if (cflag & CBAUDEX) - baud += B38400; - if (baud == B4800) - div = ACIA_DIV64; /* really 7812.5 bps */ - else if (baud == B38400+2 /* 115200 */) - div = ACIA_DIV1; /* really 500 kbps (does that work??) */ - else - div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ - - /* RTS low, ints disabled */ - acia.mid_ctrl = div | csize | parity | - ((atari_switches & ATARI_SWITCH_MIDI) ? - ACIA_RHTID : ACIA_RLTID); + sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02); + restore_flags(flags); } - -__initfunc(static void atari_debug_init(void)) -{ -#ifdef CONFIG_KGDB - /* the m68k_debug_device is used by the GDB stub, do nothing here */ - return; #endif - if (!strcmp( m68k_debug_device, "ser" )) { - /* defaults to ser2 for a Falcon and ser1 otherwise */ - strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" ); - - } - - if (!strcmp( m68k_debug_device, "ser1" )) { - /* ST-MFP Modem1 serial port */ - atari_init_mfp_port( B9600|CS8 ); - atari_console_driver.write = atari_mfp_console_write; - } - else if (!strcmp( m68k_debug_device, "ser2" )) { - /* SCC Modem2 serial port */ - atari_init_scc_port( B9600|CS8 ); - atari_console_driver.write = atari_scc_console_write; - } - else if (!strcmp( m68k_debug_device, "midi" )) { - /* MIDI port */ - atari_init_scc_port( B9600|CS8 ); - atari_console_driver.write = atari_midi_console_write; - } - else if (!strcmp( m68k_debug_device, "par" )) { - /* parallel printer */ - atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */ - sound_ym.rd_data_reg_sel = 7; /* select mixer control */ - sound_ym.wd_data = 0xff; /* sound off, ports are output */ - sound_ym.rd_data_reg_sel = 15; /* select port B */ - sound_ym.wd_data = 0; /* no char */ - sound_ym.rd_data_reg_sel = 14; /* select port A */ - sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ - atari_console_driver.write = atari_par_console_write; - } - if (atari_console_driver.write) - register_console(&atari_console_driver); -} /* ++roman: * @@ -1512,3 +806,10 @@ return(len); } + +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 8 + * End: + */ diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/debug.c linux-2.1.72/arch/m68k/atari/debug.c --- linux-2.1.72.orig/arch/m68k/atari/debug.c Thu Jan 1 01:00:00 1970 +++ linux-2.1.72/arch/m68k/atari/debug.c Thu Dec 18 16:05:32 1997 @@ -0,0 +1,359 @@ +/* + * linux/arch/m68k/atari/debug.c + * + * Atari debugging and serial console stuff + * + * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +extern char m68k_debug_device[]; + +/* Flag that Modem1 port is already initialized and used */ +int atari_MFP_init_done = 0; +/* Flag that Modem1 port is already initialized and used */ +int atari_SCC_init_done = 0; +/* Can be set somewhere, if a SCC master reset has already be done and should + * not be repeated; used by kgdb */ +int atari_SCC_reset_done = 0; + +static struct console atari_console_driver = { + "debug", + NULL, /* write */ + NULL, /* read */ + NULL, /* device */ + NULL, /* wait_key */ + NULL, /* unblank */ + NULL, /* setup */ + CON_PRINTBUFFER, + -1, + 0, + NULL +}; + + +static inline void ata_mfp_out (char c) +{ + while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ + barrier (); + mfp.usart_dta = c; +} + +void atari_mfp_console_write (struct console *co, const char *str, + unsigned int count) +{ + while (count--) { + if (*str == '\n') + ata_mfp_out( '\r' ); + ata_mfp_out( *str++ ); + } +} + +static inline void ata_scc_out (char c) +{ + do { + MFPDELAY(); + } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ + MFPDELAY(); + scc.cha_b_data = c; +} + +void atari_scc_console_write (struct console *co, const char *str, + unsigned int count) +{ + while (count--) { + if (*str == '\n') + ata_scc_out( '\r' ); + ata_scc_out( *str++ ); + } +} + +static inline void ata_midi_out (char c) +{ + while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ + barrier (); + acia.mid_data = c; +} + +void atari_midi_console_write (struct console *co, const char *str, + unsigned int count) +{ + while (count--) { + if (*str == '\n') + ata_midi_out( '\r' ); + ata_midi_out( *str++ ); + } +} + +static int ata_par_out (char c) +{ + unsigned char tmp; + /* This a some-seconds timeout in case no printer is connected */ + unsigned long i = loops_per_sec > 1 ? loops_per_sec : 10000000; + + while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */ + ; + if (!i) return( 0 ); + + sound_ym.rd_data_reg_sel = 15; /* select port B */ + sound_ym.wd_data = c; /* put char onto port */ + sound_ym.rd_data_reg_sel = 14; /* select port A */ + tmp = sound_ym.rd_data_reg_sel; + sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ + MFPDELAY(); /* wait a bit */ + sound_ym.wd_data = tmp | 0x20; /* set strobe H */ + return( 1 ); +} + +static void atari_par_console_write (struct console *co, const char *str, + unsigned int count) +{ + static int printer_present = 1; + + if (!printer_present) + return; + + while (count--) { + if (*str == '\n') + if (!ata_par_out( '\r' )) { + printer_present = 0; + return; + } + if (!ata_par_out( *str++ )) { + printer_present = 0; + return; + } + } +} + +#ifdef CONFIG_SERIAL_CONSOLE +int atari_mfp_console_wait_key(struct console *co) +{ + while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */ + barrier(); + return( mfp.usart_dta ); +} + +int atari_scc_console_wait_key(struct console *co) +{ + do { + MFPDELAY(); + } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ + MFPDELAY(); + return( scc.cha_b_data ); +} + +int atari_midi_console_wait_key(struct console *co) +{ + while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */ + barrier(); + return( acia.mid_data ); +} +#endif + +/* The following two functions do a quick'n'dirty initialization of the MFP or + * SCC serial ports. They're used by the debugging interface, kgdb, and the + * serial console code. */ +#ifndef CONFIG_SERIAL_CONSOLE +__initfunc(static void atari_init_mfp_port( int cflag )) +#else +void atari_init_mfp_port( int cflag ) +#endif +{ + /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 + * bps, resp., and work only correct if there's a RSVE or RSSPEED */ + static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; + int baud = cflag & CBAUD; + int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; + int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* baud_table[] starts at 1200bps */ + + mfp.trn_stat &= ~0x01; /* disable TX */ + mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ + mfp.tim_ct_cd &= 0x70; /* stop timer D */ + mfp.tim_dt_d = baud_table[baud]; + mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ + mfp.trn_stat |= 0x01; /* enable TX */ + + atari_MFP_init_done = 1; +} + +#define SCC_WRITE(reg,val) \ + do { \ + scc.cha_b_ctrl = (reg); \ + MFPDELAY(); \ + scc.cha_b_ctrl = (val); \ + MFPDELAY(); \ + } while(0) + +/* loops_per_sec isn't initialized yet, so we can't use udelay(). This does a + * delay of ~ 60us. */ +#define LONG_DELAY() \ + do { \ + int i; \ + for( i = 100; i > 0; --i ) \ + MFPDELAY(); \ + } while(0) + +#ifndef CONFIG_SERIAL_CONSOLE +__initfunc(static void atari_init_scc_port( int cflag )) +#else +void atari_init_scc_port( int cflag ) +#endif +{ + extern int atari_SCC_reset_done; + static int clksrc_table[9] = + /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ + { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; + static int brgsrc_table[9] = + /* reg 14: 0 = RTxC, 2 = PCLK */ + { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; + static int clkmode_table[9] = + /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ + { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; + static int div_table[9] = + /* reg12 (BRG low) */ + { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; + + int baud = cflag & CBAUD; + int clksrc, clkmode, div, reg3, reg5; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* tables starts at 1200bps */ + + clksrc = clksrc_table[baud]; + clkmode = clkmode_table[baud]; + div = div_table[baud]; + if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { + /* special treatment for TT, where rates >= 38400 are done via TRxC */ + clksrc = 0x28; /* TRxC */ + clkmode = baud == 6 ? 0xc0 : + baud == 7 ? 0x80 : /* really 76800bps */ + 0x40; /* really 153600bps */ + div = 0; + } + + reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; + reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; + + (void)scc.cha_b_ctrl; /* reset reg pointer */ + SCC_WRITE( 9, 0xc0 ); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | + 0x04 /* 1 stopbit */ | + clkmode ); + SCC_WRITE( 3, reg3 ); + SCC_WRITE( 5, reg5 ); + SCC_WRITE( 9, 0 ); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCC_WRITE( 10, 0 ); /* NRZ mode */ + SCC_WRITE( 11, clksrc ); /* main clock source */ + SCC_WRITE( 12, div ); /* BRG value */ + SCC_WRITE( 13, 0 ); /* BRG high byte */ + SCC_WRITE( 14, brgsrc_table[baud] ); + SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); + SCC_WRITE( 3, reg3 | 1 ); + SCC_WRITE( 5, reg5 | 8 ); + + atari_SCC_reset_done = 1; + atari_SCC_init_done = 1; +} + +#ifndef CONFIG_SERIAL_CONSOLE +__initfunc(static void atari_init_midi_port( int cflag )) +#else +void atari_init_midi_port( int cflag ) +#endif +{ + int baud = cflag & CBAUD; + int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; + /* warning 7N1 isn't possible! (instead 7O2 is used...) */ + int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; + int div; + + /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as + * default) the standard MIDI speed 31250. */ + if (cflag & CBAUDEX) + baud += B38400; + if (baud == B4800) + div = ACIA_DIV64; /* really 7812.5 bps */ + else if (baud == B38400+2 /* 115200 */) + div = ACIA_DIV1; /* really 500 kbps (does that work??) */ + else + div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ + + /* RTS low, ints disabled */ + acia.mid_ctrl = div | csize | parity | + ((atari_switches & ATARI_SWITCH_MIDI) ? + ACIA_RHTID : ACIA_RLTID); +} + +__initfunc(void atari_debug_init(void)) +{ +#ifdef CONFIG_KGDB + /* the m68k_debug_device is used by the GDB stub, do nothing here */ + return; +#endif + if (!strcmp( m68k_debug_device, "ser" )) { + /* defaults to ser2 for a Falcon and ser1 otherwise */ + strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" ); + + } + + if (!strcmp( m68k_debug_device, "ser1" )) { + /* ST-MFP Modem1 serial port */ + atari_init_mfp_port( B9600|CS8 ); + atari_console_driver.write = atari_mfp_console_write; + } + else if (!strcmp( m68k_debug_device, "ser2" )) { + /* SCC Modem2 serial port */ + atari_init_scc_port( B9600|CS8 ); + atari_console_driver.write = atari_scc_console_write; + } + else if (!strcmp( m68k_debug_device, "midi" )) { + /* MIDI port */ + atari_init_scc_port( B9600|CS8 ); + atari_console_driver.write = atari_midi_console_write; + } + else if (!strcmp( m68k_debug_device, "par" )) { + /* parallel printer */ + atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */ + sound_ym.rd_data_reg_sel = 7; /* select mixer control */ + sound_ym.wd_data = 0xff; /* sound off, ports are output */ + sound_ym.rd_data_reg_sel = 15; /* select port B */ + sound_ym.wd_data = 0; /* no char */ + sound_ym.rd_data_reg_sel = 14; /* select port A */ + sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ + atari_console_driver.write = atari_par_console_write; + } + if (atari_console_driver.write) + register_console(&atari_console_driver); +} + +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 8 + * End: + */ diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/time.c linux-2.1.72/arch/m68k/atari/time.c --- linux-2.1.72.orig/arch/m68k/atari/time.c Thu Jan 1 01:00:00 1970 +++ linux-2.1.72/arch/m68k/atari/time.c Thu Dec 18 16:03:53 1997 @@ -0,0 +1,416 @@ +/* + * linux/arch/m68k/atari/time.c + * + * Atari time and real time clock stuff + * + * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include + + +__initfunc(void +atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))) +{ + /* set Timer C data Register */ + mfp.tim_dt_c = INT_TICKS; + /* start timer C, div = 1:100 */ + mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; + /* install interrupt service routine for MFP Timer C */ + request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW, + "timer", timer_routine); +} + +/* ++andreas: gettimeoffset fixed to check for pending interrupt */ + +#define TICK_SIZE 10000 + +/* This is always executed with interrupts disabled. */ +unsigned long atari_gettimeoffset (void) +{ + unsigned long ticks, offset = 0; + + /* read MFP timer C current value */ + ticks = mfp.tim_dt_c; + /* The probability of underflow is less than 2% */ + if (ticks > INT_TICKS - INT_TICKS / 50) + /* Check for pending timer interrupt */ + if (mfp.int_pn_b & (1 << 5)) + offset = TICK_SIZE; + + ticks = INT_TICKS - ticks; + ticks = ticks * 10000L / INT_TICKS; + + return ticks + offset; +} + + +static void mste_read(struct MSTE_RTC *val) +{ +#define COPY(v) val->v=(mste_rtc.v & 0xf) + do { + COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; + COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; + COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; + COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ; + COPY(year_tens) ; + /* prevent from reading the clock while it changed */ + } while (val->sec_ones != (mste_rtc.sec_ones & 0xf)); +#undef COPY +} + +static void mste_write(struct MSTE_RTC *val) +{ +#define COPY(v) mste_rtc.v=val->v + do { + COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; + COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; + COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; + COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ; + COPY(year_tens) ; + /* prevent from writing the clock while it changed */ + } while (val->sec_ones != (mste_rtc.sec_ones & 0xf)); +#undef COPY +} + +#define RTC_READ(reg) \ + ({ unsigned char __val; \ + outb(reg,&tt_rtc.regsel); \ + __val = tt_rtc.data; \ + __val; \ + }) + +#define RTC_WRITE(reg,val) \ + do { \ + outb(reg,&tt_rtc.regsel); \ + tt_rtc.data = (val); \ + } while(0) + + +void atari_mste_gettod (int *yearp, int *monp, int *dayp, + int *hourp, int *minp, int *secp) +{ + int hr24=0, hour; + struct MSTE_RTC val; + + mste_rtc.mode=(mste_rtc.mode | 1); + hr24=mste_rtc.mon_tens & 1; + mste_rtc.mode=(mste_rtc.mode & ~1); + + mste_read(&val); + *secp = val.sec_ones + val.sec_tens * 10; + *minp = val.min_ones + val.min_tens * 10; + hour = val.hr_ones + val.hr_tens * 10; + if (!hr24) { + if (hour == 12 || hour == 12 + 20) + hour -= 12; + if (hour >= 20) + hour += 12 - 20; + } + *hourp = hour; + *dayp = val.day_ones + val.day_tens * 10; + *monp = val.mon_ones + val.mon_tens * 10; + *yearp = val.year_ones + val.year_tens * 10 + 80; +} + + +void atari_tt_gettod (int *yearp, int *monp, int *dayp, + int *hourp, int *minp, int *secp) +{ + unsigned char ctrl; + int hour, pm; + + while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ; + while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ; + + *secp = RTC_READ(RTC_SECONDS); + *minp = RTC_READ(RTC_MINUTES); + hour = RTC_READ(RTC_HOURS); + *dayp = RTC_READ(RTC_DAY_OF_MONTH); + *monp = RTC_READ(RTC_MONTH); + *yearp = RTC_READ(RTC_YEAR); + pm = hour & 0x80; + hour &= ~0x80; + + ctrl = RTC_READ(RTC_CONTROL); + + if (!(ctrl & RTC_DM_BINARY)) { + BCD_TO_BIN(*secp); + BCD_TO_BIN(*minp); + BCD_TO_BIN(hour); + BCD_TO_BIN(*dayp); + BCD_TO_BIN(*monp); + BCD_TO_BIN(*yearp); + } + if (!(ctrl & RTC_24H)) { + if (!pm && hour == 12) + hour = 0; + else if (pm && hour != 12) + hour += 12; + } + *hourp = hour; + + /* Adjust values (let the setup valid) */ + *yearp += atari_rtc_year_offset; +} + +#define HWCLK_POLL_INTERVAL 5 + +int atari_mste_hwclk( int op, struct hwclk_time *t ) +{ + int hour, year; + int hr24=0; + struct MSTE_RTC val; + + mste_rtc.mode=(mste_rtc.mode | 1); + hr24=mste_rtc.mon_tens & 1; + mste_rtc.mode=(mste_rtc.mode & ~1); + + if (op) { + /* write: prepare values */ + + val.sec_ones = t->sec % 10; + val.sec_tens = t->sec / 10; + val.min_ones = t->min % 10; + val.min_tens = t->min / 10; + hour = t->hour; + if (!hr24) { + if (hour > 11) + hour += 20 - 12; + if (hour == 0 || hour == 20) + hour += 12; + } + val.hr_ones = hour % 10; + val.hr_tens = hour / 10; + val.day_ones = t->day % 10; + val.day_tens = t->day / 10; + val.mon_ones = (t->mon+1) % 10; + val.mon_tens = (t->mon+1) / 10; + year = t->year - 80; + val.year_ones = year % 10; + val.year_tens = year / 10; + val.weekday = t->wday; + mste_write(&val); + mste_rtc.mode=(mste_rtc.mode | 1); + val.year_ones = (year % 4); /* leap year register */ + mste_rtc.mode=(mste_rtc.mode & ~1); + } + else { + mste_read(&val); + t->sec = val.sec_ones + val.sec_tens * 10; + t->min = val.min_ones + val.min_tens * 10; + hour = val.hr_ones + val.hr_tens * 10; + if (!hr24) { + if (hour == 12 || hour == 12 + 20) + hour -= 12; + if (hour >= 20) + hour += 12 - 20; + } + t->hour = hour; + t->day = val.day_ones + val.day_tens * 10; + t->mon = val.mon_ones + val.mon_tens * 10 - 1; + t->year = val.year_ones + val.year_tens * 10 + 80; + t->wday = val.weekday; + } + return 0; +} + +int atari_tt_hwclk( int op, struct hwclk_time *t ) +{ + int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; + unsigned long flags; + unsigned char ctrl; + int pm = 0; + + ctrl = RTC_READ(RTC_CONTROL); /* control registers are + * independent from the UIP */ + + if (op) { + /* write: prepare values */ + + sec = t->sec; + min = t->min; + hour = t->hour; + day = t->day; + mon = t->mon + 1; + year = t->year - atari_rtc_year_offset; + wday = t->wday + (t->wday >= 0); + + if (!(ctrl & RTC_24H)) { + if (hour > 11) { + pm = 0x80; + if (hour != 12) + hour -= 12; + } + else if (hour == 0) + hour = 12; + } + + if (!(ctrl & RTC_DM_BINARY)) { + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hour); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(year); + if (wday >= 0) BIN_TO_BCD(wday); + } + } + + /* Reading/writing the clock registers is a bit critical due to + * the regular update cycle of the RTC. While an update is in + * progress, registers 0..9 shouldn't be touched. + * The problem is solved like that: If an update is currently in + * progress (the UIP bit is set), the process sleeps for a while + * (50ms). This really should be enough, since the update cycle + * normally needs 2 ms. + * If the UIP bit reads as 0, we have at least 244 usecs until the + * update starts. This should be enough... But to be sure, + * additionally the RTC_SET bit is set to prevent an update cycle. + */ + + while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) { + current->state = TASK_INTERRUPTIBLE; + current->timeout = jiffies + HWCLK_POLL_INTERVAL; + schedule(); + } + + save_flags(flags); + cli(); + RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET ); + if (!op) { + sec = RTC_READ( RTC_SECONDS ); + min = RTC_READ( RTC_MINUTES ); + hour = RTC_READ( RTC_HOURS ); + day = RTC_READ( RTC_DAY_OF_MONTH ); + mon = RTC_READ( RTC_MONTH ); + year = RTC_READ( RTC_YEAR ); + wday = RTC_READ( RTC_DAY_OF_WEEK ); + } + else { + RTC_WRITE( RTC_SECONDS, sec ); + RTC_WRITE( RTC_MINUTES, min ); + RTC_WRITE( RTC_HOURS, hour + pm); + RTC_WRITE( RTC_DAY_OF_MONTH, day ); + RTC_WRITE( RTC_MONTH, mon ); + RTC_WRITE( RTC_YEAR, year ); + if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday ); + } + RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET ); + restore_flags(flags); + + if (!op) { + /* read: adjust values */ + + if (hour & 0x80) { + hour &= ~0x80; + pm = 1; + } + + if (!(ctrl & RTC_DM_BINARY)) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + BCD_TO_BIN(wday); + } + + if (!(ctrl & RTC_24H)) { + if (!pm && hour == 12) + hour = 0; + else if (pm && hour != 12) + hour += 12; + } + + t->sec = sec; + t->min = min; + t->hour = hour; + t->day = day; + t->mon = mon - 1; + t->year = year + atari_rtc_year_offset; + t->wday = wday - 1; + } + + return( 0 ); +} + + +int atari_mste_set_clock_mmss (unsigned long nowtime) +{ + short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; + struct MSTE_RTC val; + unsigned char rtc_minutes; + + mste_read(&val); + rtc_minutes= val.min_ones + val.min_tens * 10; + if ((rtc_minutes < real_minutes + ? real_minutes - rtc_minutes + : rtc_minutes - real_minutes) < 30) + { + val.sec_ones = real_seconds % 10; + val.sec_tens = real_seconds / 10; + val.min_ones = real_minutes % 10; + val.min_tens = real_minutes / 10; + mste_write(&val); + } + else + return -1; + return 0; +} + +int atari_tt_set_clock_mmss (unsigned long nowtime) +{ + int retval = 0; + short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; + unsigned char save_control, save_freq_select, rtc_minutes; + + save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */ + RTC_WRITE (RTC_CONTROL, save_control | RTC_SET); + + save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */ + RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2); + + rtc_minutes = RTC_READ (RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY)) + BCD_TO_BIN (rtc_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 30 minutes. */ + if ((rtc_minutes < real_minutes + ? real_minutes - rtc_minutes + : rtc_minutes - real_minutes) < 30) + { + if (!(save_control & RTC_DM_BINARY)) + { + BIN_TO_BCD (real_seconds); + BIN_TO_BCD (real_minutes); + } + RTC_WRITE (RTC_SECONDS, real_seconds); + RTC_WRITE (RTC_MINUTES, real_minutes); + } + else + retval = -1; + + RTC_WRITE (RTC_FREQ_SELECT, save_freq_select); + RTC_WRITE (RTC_CONTROL, save_control); + return retval; +} + +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 8 + * End: + */ diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/kernel/setup.c linux-2.1.72/arch/m68k/kernel/setup.c --- linux-2.1.72.orig/arch/m68k/kernel/setup.c Thu Dec 18 13:14:32 1997 +++ linux-2.1.72/arch/m68k/kernel/setup.c Thu Dec 18 13:23:33 1997 @@ -79,6 +79,10 @@ void (*mach_floppy_setup) (char *, int *) __initdata = NULL; void (*mach_floppy_eject) (void) = NULL; #endif +#ifdef CONFIG_HEARTBEAT +void (*mach_heartbeat) (int) = NULL; +int mach_heartbeat_irq; +#endif extern void base_trap_init(void); diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/kernel/time.c linux-2.1.72/arch/m68k/kernel/time.c --- linux-2.1.72.orig/arch/m68k/kernel/time.c Tue Dec 16 16:20:09 1997 +++ linux-2.1.72/arch/m68k/kernel/time.c Thu Dec 18 15:48:58 1997 @@ -19,16 +19,7 @@ #ifdef CONFIG_HEARTBEAT #include -#include -#ifdef CONFIG_AMIGA -#include -#include #endif -#ifdef CONFIG_ATARI -#include -#include -#endif -#endif /* CONFIG_HEARTBEAT */ #include @@ -89,40 +80,18 @@ /* use power LED as a heartbeat instead -- much more useful for debugging -- based on the version for PReP by Cort */ /* acts like an actual heart beat -- ie thump-thump-pause... */ -#ifdef CONFIG_AMIGA - if (MACH_IS_AMIGA) { - switch(kstat.interrupts[SYS_IRQS + IRQ_AMIGA_CIAB_TA] % 101) { - case 0: - case 20: - ciaa.pra &= ~2; - break; - case 7: - case 27: - ciaa.pra |= 2; - break; - } - } -#endif -#ifdef CONFIG_ATARI - if (MACH_IS_ATARI && !atari_dont_touch_floppy_select) { - unsigned long flags, tmp; - save_flags(flags); - cli(); - sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */ - tmp = sound_ym.rd_data_reg_sel; - switch(kstat.interrupts[IRQ_MFP_TIMC] % 101) { + if (mach_heartbeat) { + switch(kstat.interrupts[mach_heartbeat_irq] % 101) { case 0: case 20: - sound_ym.wd_data = tmp & ~0x02; + mach_heartbeat( 1 ); break; case 7: case 27: - sound_ym.wd_data = tmp | 0x02; + mach_heartbeat( 0 ); break; } - restore_flags(flags); - } -#endif + } #endif /* CONFIG_HEARTBEAT */ } Binary files linux-2.1.72.orig/drivers/sound/configure and linux-2.1.72/drivers/sound/configure differ diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/include/asm-m68k/machdep.h linux-2.1.72/include/asm-m68k/machdep.h --- linux-2.1.72.orig/include/asm-m68k/machdep.h Thu Dec 18 13:14:45 1997 +++ linux-2.1.72/include/asm-m68k/machdep.h Thu Dec 18 13:23:20 1997 @@ -35,6 +35,8 @@ extern long mach_max_dma_address; extern void (*mach_floppy_setup)(char *, int *); extern void (*mach_floppy_eject)(void); +extern void (*mach_heartbeat) (int); +extern int mach_heartbeat_irq; extern int mach_sysrq_key; extern int mach_sysrq_shift_state; extern int mach_sysrq_shift_mask;