# # PowerPC/Apus support patch # Needed support for Amiga PowerUP boards. # Author: mostly Roman Zippel # Upstream status: got synced with 2.6.12 recently, so in better status than # previous apus patches. Only 81k left. # This is the part which do not interact with non-apus powerpc subarche, either # in amiga subdirectories, #ifdefed CONFIG_APUS or mostly a no-op in the absence # of CONFIG_APUS. Another patch is left which is of more dubious quality, and which # i will not apply by default. # diff -Nur -x CVS linux-2.6.13/arch/ppc/amiga/amiints.c linux-2.6.13-apus/arch/ppc/amiga/amiints.c --- linux-2.6.13/arch/ppc/amiga/amiints.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/amiga/amiints.c 2004-02-04 22:21:34.000000000 +0100 @@ -67,9 +67,10 @@ static short ami_ablecount[AMI_IRQS]; -static void ami_badint(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp) { /* num_spurious += 1;*/ + return IRQ_NONE; } /* @@ -206,7 +207,7 @@ * The builtin Amiga hardware interrupt handlers. */ -static void ami_int1(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = custom.intreqr & custom.intenar; @@ -227,9 +228,10 @@ custom.intreq = IF_SOFT; amiga_do_irq(IRQ_AMIGA_SOFT, fp); } + return IRQ_HANDLED; } -static void ami_int3(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = custom.intreqr & custom.intenar; @@ -248,9 +250,11 @@ /* if a vertical blank interrupt */ if (ints & IF_VERTB) amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); + + return IRQ_HANDLED; } -static void ami_int4(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = custom.intreqr & custom.intenar; @@ -277,9 +281,10 @@ custom.intreq = IF_AUD3; amiga_do_irq(IRQ_AMIGA_AUD3, fp); } + return IRQ_HANDLED; } -static void ami_int5(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = custom.intreqr & custom.intenar; @@ -294,11 +299,13 @@ custom.intreq = IF_DSKSYN; amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); } + return IRQ_HANDLED; } -static void ami_int7(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) { panic ("level 7 interrupt received\n"); + return IRQ_NONE; } #ifdef CONFIG_APUS diff -Nur -x CVS linux-2.6.13/arch/ppc/amiga/cia.c linux-2.6.13-apus/arch/ppc/amiga/cia.c --- linux-2.6.13/arch/ppc/amiga/cia.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/amiga/cia.c 2004-02-04 22:21:34.000000000 +0100 @@ -134,7 +134,7 @@ return cia_able_irq_private(base, mask); } -static void cia_handler(int irq, void *dev_id, struct pt_regs *fp) +static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) { struct ciabase *base = (struct ciabase *)dev_id; irq_desc_t *desc; @@ -156,6 +156,7 @@ desc++; } amiga_do_irq_list(base->server_irq, fp); + return IRQ_HANDLED; } void __init cia_init_IRQ(struct ciabase *base) diff -Nur -x CVS linux-2.6.13/arch/ppc/amiga/config.c linux-2.6.13-apus/arch/ppc/amiga/config.c --- linux-2.6.13/arch/ppc/amiga/config.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/amiga/config.c 2005-07-30 20:52:47.000000000 +0200 @@ -20,11 +20,12 @@ #include #include #include +#include #include #include -#ifdef CONFIG_ZORRO +#include #include -#endif +#include #include #include @@ -71,29 +72,9 @@ extern char m68k_debug_device[]; -static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); -/* amiga specific irq functions */ -extern void amiga_init_IRQ (void); -extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *); -extern int amiga_request_irq (unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, - void *dev_id); -extern void amiga_free_irq (unsigned int irq, void *dev_id); -extern void amiga_enable_irq (unsigned int); -extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); /* amiga specific timer functions */ -static unsigned long amiga_gettimeoffset (void); -static void a3000_gettod (int *, int *, int *, int *, int *, int *); -static void a2000_gettod (int *, int *, int *, int *, int *, int *); -static int amiga_hwclk (int, struct hwclk_time *); -static int amiga_set_clock_mmss (unsigned long); -#ifdef CONFIG_AMIGA_FLOPPY -extern void amiga_floppy_setup(char *, int *); -#endif -static void amiga_reset (void); extern void amiga_init_sound(void); static void amiga_savekmsg_init(void); static void amiga_mem_console_write(struct console *co, const char *b, @@ -101,9 +82,6 @@ void amiga_serial_console_write(struct console *co, const char *s, unsigned int count); static void amiga_debug_init(void); -#ifdef CONFIG_HEARTBEAT -static void amiga_heartbeat(int on); -#endif static struct console amiga_console_driver = { .name = "debug", @@ -384,48 +362,15 @@ for (i = 0; i < 4; i++) request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); - mach_sched_init = amiga_sched_init; - mach_init_IRQ = amiga_init_IRQ; -#ifndef CONFIG_APUS - mach_default_handler = &amiga_default_handler; - mach_request_irq = amiga_request_irq; - mach_free_irq = amiga_free_irq; - enable_irq = amiga_enable_irq; - disable_irq = amiga_disable_irq; -#endif - mach_get_model = amiga_get_model; - mach_get_hardware_list = amiga_get_hardware_list; - mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ - mach_gettod = a3000_gettod; rtc_resource.name = "A3000 RTC"; request_resource(&iomem_resource, &rtc_resource); } else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ - mach_gettod = a2000_gettod; rtc_resource.name = "A2000 RTC"; request_resource(&iomem_resource, &rtc_resource); } - mach_max_dma_address = 0xffffffff; /* - * default MAX_DMA=0xffffffff - * on all machines. If we don't - * do so, the SCSI code will not - * be able to allocate any mem - * for transfers, unless we are - * dealing with a Z2 mem only - * system. /Jes - */ - - mach_hwclk = amiga_hwclk; - mach_set_clock_mmss = amiga_set_clock_mmss; -#ifdef CONFIG_AMIGA_FLOPPY - mach_floppy_setup = amiga_floppy_setup; -#endif - mach_reset = amiga_reset; -#ifdef CONFIG_HEARTBEAT - mach_heartbeat = amiga_heartbeat; -#endif /* Fill in the clock values (based on the 700 kHz E-Clock) */ amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ @@ -473,242 +418,141 @@ *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; } -static unsigned short jiffy_ticks; - -static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *, - struct pt_regs *)) -{ - static struct resource sched_res = { - "timer", 0x00bfd400, 0x00bfd5ff, - }; - jiffy_ticks = (amiga_eclock+HZ/2)/HZ; - - if (request_resource(&mb_resources._ciab, &sched_res)) - printk("Cannot allocate ciab.ta{lo,hi}\n"); - ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ - ciab.talo = jiffy_ticks % 256; - ciab.tahi = jiffy_ticks / 256; - - /* install interrupt service routine for CIAB Timer A - * - * Please don't change this to use ciaa, as it interferes with the - * SCSI code. We'll have to take a look at this later - */ - request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL); - /* start timer */ - ciab.cra |= 0x11; -} - #define TICK_SIZE 10000 -extern unsigned char cia_get_irq_mask(unsigned int irq); - -/* This is always executed with interrupts disabled. */ -static unsigned long amiga_gettimeoffset (void) -{ - unsigned short hi, lo, hi2; - unsigned long ticks, offset = 0; - - /* read CIA B timer A current value */ - hi = ciab.tahi; - lo = ciab.talo; - hi2 = ciab.tahi; - - if (hi != hi2) { - lo = ciab.talo; - hi = hi2; - } - - ticks = hi << 8 | lo; - - if (ticks > jiffy_ticks / 2) - /* check for pending interrupt */ - if (cia_get_irq_mask(IRQ_AMIGA_CIAB) & CIA_ICR_TA) - offset = 10000; - - ticks = jiffy_ticks - ticks; - ticks = (10000 * ticks) / jiffy_ticks; - - return ticks + offset; -} - -static void a3000_gettod (int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp) -{ - volatile struct tod3000 *tod = TOD_3000; - - tod->cntrl1 = TOD3000_CNTRL1_HOLD; - - *secp = tod->second1 * 10 + tod->second2; - *minp = tod->minute1 * 10 + tod->minute2; - *hourp = tod->hour1 * 10 + tod->hour2; - *dayp = tod->day1 * 10 + tod->day2; - *monp = tod->month1 * 10 + tod->month2; - *yearp = tod->year1 * 10 + tod->year2; - - tod->cntrl1 = TOD3000_CNTRL1_FREE; -} - -static void a2000_gettod (int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp) -{ - volatile struct tod2000 *tod = TOD_2000; - - tod->cntrl1 = TOD2000_CNTRL1_HOLD; - - while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) - ; - - *secp = tod->second1 * 10 + tod->second2; - *minp = tod->minute1 * 10 + tod->minute2; - *hourp = (tod->hour1 & 3) * 10 + tod->hour2; - *dayp = tod->day1 * 10 + tod->day2; - *monp = tod->month1 * 10 + tod->month2; - *yearp = tod->year1 * 10 + tod->year2; - - if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){ - if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12) - *hourp = 0; - else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12) - *hourp += 12; - } - - tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; -} - -static int amiga_hwclk(int op, struct hwclk_time *t) +int amiga_hwclk(int op, struct rtc_time *t) { if (AMIGAHW_PRESENT(A3000_CLK)) { - volatile struct tod3000 *tod = TOD_3000; - - tod->cntrl1 = TOD3000_CNTRL1_HOLD; + tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD; if (!op) { /* read */ - t->sec = tod->second1 * 10 + tod->second2; - t->min = tod->minute1 * 10 + tod->minute2; - t->hour = tod->hour1 * 10 + tod->hour2; - t->day = tod->day1 * 10 + tod->day2; - t->wday = tod->weekday; - t->mon = tod->month1 * 10 + tod->month2 - 1; - t->year = tod->year1 * 10 + tod->year2; - if (t->year <= 69) - t->year += 100; + t->tm_sec = tod_3000.second1 * 10 + tod_3000.second2; + t->tm_min = tod_3000.minute1 * 10 + tod_3000.minute2; + t->tm_hour = tod_3000.hour1 * 10 + tod_3000.hour2; + t->tm_mday = tod_3000.day1 * 10 + tod_3000.day2; + t->tm_wday = tod_3000.weekday; + t->tm_mon = tod_3000.month1 * 10 + tod_3000.month2 - 1; + t->tm_year = tod_3000.year1 * 10 + tod_3000.year2; + if (t->tm_year <= 69) + t->tm_year += 100; } else { - tod->second1 = t->sec / 10; - tod->second2 = t->sec % 10; - tod->minute1 = t->min / 10; - tod->minute2 = t->min % 10; - tod->hour1 = t->hour / 10; - tod->hour2 = t->hour % 10; - tod->day1 = t->day / 10; - tod->day2 = t->day % 10; - if (t->wday != -1) - tod->weekday = t->wday; - tod->month1 = (t->mon + 1) / 10; - tod->month2 = (t->mon + 1) % 10; - if (t->year >= 100) - t->year -= 100; - tod->year1 = t->year / 10; - tod->year2 = t->year % 10; + tod_3000.second1 = t->tm_sec / 10; + tod_3000.second2 = t->tm_sec % 10; + tod_3000.minute1 = t->tm_min / 10; + tod_3000.minute2 = t->tm_min % 10; + tod_3000.hour1 = t->tm_hour / 10; + tod_3000.hour2 = t->tm_hour % 10; + tod_3000.day1 = t->tm_mday / 10; + tod_3000.day2 = t->tm_mday % 10; + if (t->tm_wday != -1) + tod_3000.weekday = t->tm_wday; + tod_3000.month1 = (t->tm_mon + 1) / 10; + tod_3000.month2 = (t->tm_mon + 1) % 10; + if (t->tm_year >= 100) + t->tm_year -= 100; + tod_3000.year1 = t->tm_year / 10; + tod_3000.year2 = t->tm_year % 10; } - tod->cntrl1 = TOD3000_CNTRL1_FREE; + tod_3000.cntrl1 = TOD3000_CNTRL1_FREE; } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { - volatile struct tod2000 *tod = TOD_2000; + int cnt = 5; - tod->cntrl1 = TOD2000_CNTRL1_HOLD; - - while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) - ; + tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; + + while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { + tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; + udelay(70); + tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; + } + + if (!cnt) + printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1); if (!op) { /* read */ - t->sec = tod->second1 * 10 + tod->second2; - t->min = tod->minute1 * 10 + tod->minute2; - t->hour = (tod->hour1 & 3) * 10 + tod->hour2; - t->day = tod->day1 * 10 + tod->day2; - t->wday = tod->weekday; - t->mon = tod->month1 * 10 + tod->month2 - 1; - t->year = tod->year1 * 10 + tod->year2; - if (t->year <= 69) - t->year += 100; - - if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){ - if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12) - t->hour = 0; - else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12) - t->hour += 12; + t->tm_sec = tod_2000.second1 * 10 + tod_2000.second2; + t->tm_min = tod_2000.minute1 * 10 + tod_2000.minute2; + t->tm_hour = (tod_2000.hour1 & 3) * 10 + tod_2000.hour2; + t->tm_mday = tod_2000.day1 * 10 + tod_2000.day2; + t->tm_wday = tod_2000.weekday; + t->tm_mon = tod_2000.month1 * 10 + tod_2000.month2 - 1; + t->tm_year = tod_2000.year1 * 10 + tod_2000.year2; + if (t->tm_year <= 69) + t->tm_year += 100; + + if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){ + if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) + t->tm_hour = 0; + else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) + t->tm_hour += 12; } } else { - tod->second1 = t->sec / 10; - tod->second2 = t->sec % 10; - tod->minute1 = t->min / 10; - tod->minute2 = t->min % 10; - if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE) - tod->hour1 = t->hour / 10; - else if (t->hour >= 12) - tod->hour1 = TOD2000_HOUR1_PM + - (t->hour - 12) / 10; + tod_2000.second1 = t->tm_sec / 10; + tod_2000.second2 = t->tm_sec % 10; + tod_2000.minute1 = t->tm_min / 10; + tod_2000.minute2 = t->tm_min % 10; + if (tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE) + tod_2000.hour1 = t->tm_hour / 10; + else if (t->tm_hour >= 12) + tod_2000.hour1 = TOD2000_HOUR1_PM + + (t->tm_hour - 12) / 10; else - tod->hour1 = t->hour / 10; - tod->hour2 = t->hour % 10; - tod->day1 = t->day / 10; - tod->day2 = t->day % 10; - if (t->wday != -1) - tod->weekday = t->wday; - tod->month1 = (t->mon + 1) / 10; - tod->month2 = (t->mon + 1) % 10; - if (t->year >= 100) - t->year -= 100; - tod->year1 = t->year / 10; - tod->year2 = t->year % 10; + tod_2000.hour1 = t->tm_hour / 10; + tod_2000.hour2 = t->tm_hour % 10; + tod_2000.day1 = t->tm_mday / 10; + tod_2000.day2 = t->tm_mday % 10; + if (t->tm_wday != -1) + tod_2000.weekday = t->tm_wday; + tod_2000.month1 = (t->tm_mon + 1) / 10; + tod_2000.month2 = (t->tm_mon + 1) % 10; + if (t->tm_year >= 100) + t->tm_year -= 100; + tod_2000.year1 = t->tm_year / 10; + tod_2000.year2 = t->tm_year % 10; } - tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; + tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; } return 0; } -static int amiga_set_clock_mmss (unsigned long nowtime) +int amiga_set_clock_mmss(unsigned long nowtime) { short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; if (AMIGAHW_PRESENT(A3000_CLK)) { - volatile struct tod3000 *tod = TOD_3000; - - tod->cntrl1 = TOD3000_CNTRL1_HOLD; + tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD; - tod->second1 = real_seconds / 10; - tod->second2 = real_seconds % 10; - tod->minute1 = real_minutes / 10; - tod->minute2 = real_minutes % 10; + tod_3000.second1 = real_seconds / 10; + tod_3000.second2 = real_seconds % 10; + tod_3000.minute1 = real_minutes / 10; + tod_3000.minute2 = real_minutes % 10; - tod->cntrl1 = TOD3000_CNTRL1_FREE; + tod_3000.cntrl1 = TOD3000_CNTRL1_FREE; } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { - volatile struct tod2000 *tod = TOD_2000; + int cnt = 5; - tod->cntrl1 = TOD2000_CNTRL1_HOLD; - - while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) - ; - - tod->second1 = real_seconds / 10; - tod->second2 = real_seconds % 10; - tod->minute1 = real_minutes / 10; - tod->minute2 = real_minutes % 10; + tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; - tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; - } + while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { + tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; + udelay(70); + tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; + } - return 0; -} + if (!cnt) + printk(KERN_INFO "set_clock_mmss: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1); -static NORET_TYPE void amiga_reset( void ) - ATTRIB_NORET; + tod_2000.second1 = real_seconds / 10; + tod_2000.second2 = real_seconds % 10; + tod_2000.minute1 = real_minutes / 10; + tod_2000.minute2 = real_minutes % 10; -static void amiga_reset (void) -{ - for (;;); + tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; + } + + return 0; } @@ -841,16 +685,6 @@ } } -#ifdef CONFIG_HEARTBEAT -static void amiga_heartbeat(int on) -{ - if (on) - ciaa.pra &= ~2; - else - ciaa.pra |= 2; -} -#endif - /* * Amiga specific parts of /proc */ @@ -943,19 +777,14 @@ u_long mem; int i; - if (mach_get_model) - mach_get_model(model); - else - strcpy(model, "Unknown PowerPC"); + amiga_get_model(model); len += sprintf(buffer+len, "Model:\t\t%s\n", model); - len += get_cpuinfo(buffer+len); + //len += get_cpuinfo(buffer+len); for (mem = 0, i = 0; i < m68k_realnum_memory; i++) mem += m68k_memory[i].size; len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10); - - if (mach_get_hardware_list) - len += mach_get_hardware_list(buffer+len); + len += amiga_get_hardware_list(buffer+len); return(len); } diff -Nur -x CVS linux-2.6.13/arch/ppc/amiga/Makefile linux-2.6.13-apus/arch/ppc/amiga/Makefile --- linux-2.6.13/arch/ppc/amiga/Makefile 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/amiga/Makefile 2004-07-03 19:53:51.000000000 +0200 @@ -1,8 +1,8 @@ # -# Makefile for Linux arch/m68k/amiga source directory +# Makefile for Linux arch/ppc/amiga source directory # -obj-y := config.o amiints.o cia.o time.o bootinfo.o amisound.o \ - chipram.o amiga_ksyms.o +obj-y := config.o amiints.o cia.o bootinfo.o \ + amisound.o chipram.o amiga_ksyms.o obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o diff -Nur -x CVS linux-2.6.13/arch/ppc/amiga/time.c linux-2.6.13-apus/arch/ppc/amiga/time.c --- linux-2.6.13/arch/ppc/amiga/time.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/amiga/time.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,58 +0,0 @@ -#include /* CONFIG_HEARTBEAT */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -unsigned long m68k_get_rtc_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - - extern void arch_gettod(int *year, int *mon, int *day, int *hour, - int *min, int *sec); - - arch_gettod (&year, &mon, &day, &hour, &min, &sec); - - if ((year += 1900) < 1970) - year += 100; - - return mktime(year, mon, day, hour, min, sec); -} - -int m68k_set_rtc_time(unsigned long nowtime) -{ - if (mach_set_clock_mmss) - return mach_set_clock_mmss (nowtime); - return -1; -} - -void apus_heartbeat (void) -{ -#ifdef CONFIG_HEARTBEAT - static unsigned cnt = 0, period = 0, dist = 0; - - if (cnt == 0 || cnt == dist) - mach_heartbeat( 1 ); - else if (cnt == 7 || cnt == dist+7) - mach_heartbeat( 0 ); - - if (++cnt > period) { - cnt = 0; - /* The hyperbolic function below modifies the heartbeat period - * length in dependency of the current (5min) load. It goes - * through the points f(0)=126, f(1)=86, f(5)=51, - * f(inf)->30. */ - period = ((672< #include #include +#include +#include #include +#include #include /* Needs INITSERIAL call in head.S! */ -#undef APUS_DEBUG +#define APUS_DEBUG #include #include @@ -32,52 +35,26 @@ #include #include #include +#include unsigned long m68k_machtype; char debug_device[6] = ""; -extern void amiga_init_IRQ(void); - -extern void apus_setup_pci_ptrs(void); - -void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; -/* machine dependent irq functions */ -void (*mach_init_IRQ) (void) __initdata = NULL; -void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL; -void (*mach_get_model) (char *model) = NULL; -int (*mach_get_hardware_list) (char *buffer) = NULL; -int (*mach_get_irq_list) (struct seq_file *, void *) = NULL; -void (*mach_process_int) (int, struct pt_regs *) = NULL; -/* machine dependent timer functions */ -unsigned long (*mach_gettimeoffset) (void); -void (*mach_gettod) (int*, int*, int*, int*, int*, int*); -int (*mach_hwclk) (int, struct hwclk_time*) = NULL; -int (*mach_set_clock_mmss) (unsigned long) = NULL; -void (*mach_reset)( void ); -long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ -#if defined(CONFIG_AMIGA_FLOPPY) -void (*mach_floppy_setup) (char *, int *) __initdata = NULL; -#endif -#ifdef CONFIG_HEARTBEAT -void (*mach_heartbeat) (int) = NULL; -extern void apus_heartbeat (void); -#endif - -extern unsigned long amiga_model; -extern unsigned decrementer_count;/* count value for 1e6/HZ microseconds */ -extern unsigned count_period_num; /* 1 decrementer count equals */ -extern unsigned count_period_den; /* count_period_num / count_period_den us */ - int num_memory = 0; struct mem_info memory[NUM_MEMINFO];/* memory description */ /* FIXME: Duplicate memory data to avoid conflicts with m68k shared code. */ int m68k_realnum_memory = 0; struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */ +unsigned long ppc_memstart; +unsigned long ppc_pgstart; +unsigned long ppc_memoffset; + +EXPORT_SYMBOL(ppc_memoffset); +EXPORT_SYMBOL(ppc_pgstart); + struct mem_info ramdisk; -extern void amiga_floppy_setup(char *, int *); -extern void config_amiga(void); static int __60nsram = 0; @@ -92,25 +69,43 @@ */ unsigned long apus_get_rtc_time(void) { -#ifdef CONFIG_APUS - extern unsigned long m68k_get_rtc_time(void); + struct rtc_time t; - return m68k_get_rtc_time (); -#else - return 0; -#endif + amiga_hwclk(0, &t); + t.tm_year += 1900; + + return mktime(t.tm_year, t.tm_mon, t.tm_mday, + t.tm_hour, t.tm_min, t.tm_sec); } int apus_set_rtc_time(unsigned long nowtime) { -#ifdef CONFIG_APUS - extern int m68k_set_rtc_time(unsigned long nowtime); + return amiga_set_clock_mmss(nowtime); +} - return m68k_set_rtc_time (nowtime); -#else - return 0; -#endif +#ifdef CONFIG_HEARTBEAT +static void apus_heartbeat(void) +{ + static unsigned cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) + ciaa.pra &= ~2; + else if (cnt == 7 || cnt == dist + 7) + ciaa.pra |= 2; + + if (++cnt > period) { + cnt = 0; + /* The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, + * f(inf)->30. */ + period = ((672<= 63) && (bus_speed < 69)) { bus_speed = 67; - freq = 16666667; + freq = 16500000; } else { printk ("APUS: Unable to determine bus speed (%d). " - "Defaulting to 50MHz", bus_speed); + "Defaulting to 50MHz\n", bus_speed); bus_speed = 50; freq = 12500000; speed_test_failed = 1; } + ciab.cra = (ciab.cra & 0xc0) | 0x08; + ciab.icr; + wmb(); + ciab.talo = 0; + wmb(); + ciab.tahi = 0x80; + wmb(); + + get_current_tb(&start); + while (!(ciab.icr & 1)) + barrier(); + get_current_tb(&stop); + + tmp = stop - start; + start = tmp * amiga_eclock; + stop = mulhwu(tmp, amiga_eclock); + start += stop << 32; + freq = start / 0x8000; + /* Ease diagnostics... */ { extern int __map_without_bats; @@ -285,36 +299,8 @@ __bus_speed = bus_speed; __speed_test_failed = speed_test_failed; -#endif -} - -void arch_gettod(int *year, int *mon, int *day, int *hour, - int *min, int *sec) -{ -#ifdef CONFIG_APUS - if (mach_gettod) - mach_gettod(year, mon, day, hour, min, sec); - else - *year = *mon = *day = *hour = *min = *sec = 0; -#endif } -/* for "kbd-reset" cmdline param */ -__init -void kbd_reset_setup(char *str, int *ints) -{ -} - -/*********************************************************** FLOPPY */ -#if defined(CONFIG_AMIGA_FLOPPY) -__init -void floppy_setup(char *str, int *ints) -{ - if (mach_floppy_setup) - mach_floppy_setup (str, ints); -} -#endif - /*********************************************************** MEMORY */ #define KMAP_MAX 32 unsigned long kmap_chunks[KMAP_MAX*3]; @@ -330,26 +316,22 @@ va &= PAGE_MASK; dir = pgd_offset( mm, va ); - if (dir) - { + if (dir) { pmd = pmd_offset(dir, va & PAGE_MASK); if (pmd && pmd_present(*pmd)) - { - pte = pte_offset(pmd, va); - } + pte = pte_offset_kernel(pmd, va); } return pte; } /* Again simulating an m68k/mm/kmap.c function. */ -void kernel_set_cachemode( unsigned long address, unsigned long size, - unsigned int cmode ) +void kernel_set_cachemode(unsigned long address, unsigned long size, + unsigned int cmode) { - unsigned long mask, flags; + unsigned long mask, flags, end; - switch (cmode) - { + switch (cmode) { case IOMAP_FULL_CACHING: mask = ~(_PAGE_NO_CACHE | _PAGE_GUARDED); flags = 0; @@ -359,60 +341,29 @@ flags = (_PAGE_NO_CACHE | _PAGE_GUARDED); break; default: - panic ("kernel_set_cachemode() doesn't support mode %d\n", - cmode); + panic("kernel_set_cachemode() doesn't support mode %d\n", cmode); break; } - size /= PAGE_SIZE; + end = address + size; address &= PAGE_MASK; - while (size--) - { + while (address < end) { pte_t *pte; pte = my_find_pte(&init_mm, address); - if ( !pte ) - { + if (!pte) { printk("pte NULL in kernel_set_cachemode()\n"); return; } - pte_val (*pte) &= mask; - pte_val (*pte) |= flags; + pte_val(*pte) &= mask; + pte_val(*pte) |= flags; flush_tlb_page(find_vma(&init_mm,address),address); address += PAGE_SIZE; } } -unsigned long mm_ptov (unsigned long paddr) -{ - unsigned long ret; - if (paddr < 16*1024*1024) - ret = ZTWO_VADDR(paddr); - else { - int i; - - for (i = 0; i < kmap_chunk_count;){ - unsigned long phys = kmap_chunks[i++]; - unsigned long size = kmap_chunks[i++]; - unsigned long virt = kmap_chunks[i++]; - if (paddr >= phys - && paddr < (phys + size)){ - ret = virt + paddr - phys; - goto exit; - } - } - - ret = (unsigned long) __va(paddr); - } -exit: -#ifdef DEBUGPV - printk ("PTOV(%lx)=%lx\n", paddr, ret); -#endif - return ret; -} - int mm_end_of_chunk (unsigned long addr, int len) { if (memory[0].addr + memory[0].size == addr + len) @@ -422,11 +373,10 @@ /*********************************************************** CACHE */ -#define L1_CACHE_BYTES 32 #define MAX_CACHE_SIZE 8192 -void cache_push(__u32 addr, int length) +void cache_push(u32 paddr, int length) { - addr = mm_ptov(addr); + char *addr = __va(paddr); if (MAX_CACHE_SIZE < length) length = MAX_CACHE_SIZE; @@ -443,12 +393,14 @@ : : "r" (addr)); } -void cache_clear(__u32 addr, int length) +void cache_clear(u32 paddr, int length) { + char *addr; + if (MAX_CACHE_SIZE < length) length = MAX_CACHE_SIZE; - addr = mm_ptov(addr); + addr = __va(paddr); __asm ("dcbf 0,%0\n\t" "sync \n\t" @@ -518,6 +470,8 @@ level = (ipl_emu >> 3) & IPLEMU_IPLMASK; mask = IPLEMU_SETRESET|IPLEMU_DISABLEINT|level; level ^= 7; + if (!level) + return -1; /* Save previous IPL value */ if (last_ipl[level]) @@ -535,6 +489,15 @@ return level + IRQ_AMIGA_AUTO; } +unsigned int apus_startup_irq(unsigned int irq) +{ + return 0; +} + +void apus_ack_irq(unsigned int irq) +{ +} + void apus_end_irq(unsigned int irq) { unsigned char ipl_emu; @@ -646,10 +609,12 @@ __debug_ser_out('\r'); } +#ifdef APUS_DEBUG static void apus_progress(char *s, unsigned short value) { __debug_print_string(s); } +#endif /****************************************************** init */ @@ -664,6 +629,8 @@ struct hw_interrupt_type amiga_sys_irqctrl = { .typename = "Amiga IPL", + .startup = apus_startup_irq, + .ack = apus_ack_irq, .end = apus_end_irq, }; @@ -677,33 +644,32 @@ unsigned long __init apus_find_end_of_memory(void) { int shadow = 0; - unsigned long total; + unsigned long total, size; /* The memory size reported by ADOS excludes the 512KB reserved for PPC exception registers and possibly 512KB containing a shadow of the ADOS ROM. */ - { - unsigned long size = memory[0].size; - - /* If 2MB aligned, size was probably user - specified. We can't tell anything about shadowing - in this case so skip shadow assignment. */ - if (0 != (size & 0x1fffff)){ - /* Align to 512KB to ensure correct handling - of both memfile and system specified - sizes. */ - size = ((size+0x0007ffff) & 0xfff80000); - /* If memory is 1MB aligned, assume - shadowing. */ - shadow = !(size & 0x80000); - } + size = memory[0].size; - /* Add the chunk that ADOS does not see. by aligning - the size to the nearest 2MB limit upwards. */ - memory[0].size = ((size+0x001fffff) & 0xffe00000); - } + /* If 2MB aligned, size was probably user + specified. We can't tell anything about shadowing + in this case so skip shadow assignment. */ + if (size & 0x1fffff){ + /* Align to 512KB to ensure correct handling + of both memfile and system specified + sizes. */ + size = ((size+0x0007ffff) & 0xfff80000); + /* If memory is 1MB aligned, assume + shadowing. */ + shadow = !(size & 0x80000); + } + + /* Add the chunk that ADOS does not see. by aligning + the size to the nearest 2MB limit upwards. */ + memory[0].size = (size + 0x001fffff) & 0xffe00000; ppc_memstart = memory[0].addr; + ppc_pgstart = memory[0].addr >> PAGE_SHIFT; ppc_memoffset = PAGE_OFFSET - PPC_MEMSTART; total = memory[0].size; diff -Nur -x CVS linux-2.6.13/include/asm-ppc/zorro.h linux-2.6.13-apus/include/asm-ppc/zorro.h --- linux-2.6.13/include/asm-ppc/zorro.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/zorro.h 2005-08-04 01:48:26.000000000 +0200 @@ -3,13 +3,50 @@ #include -#define z_readb in_8 -#define z_readw in_be16 -#define z_readl in_be32 - -#define z_writeb(val, port) out_8((port), (val)) -#define z_writew(val, port) out_be16((port), (val)) -#define z_writel(val, port) out_be32((port), (val)) +static inline unsigned int z_readb(unsigned long addr) +{ + unsigned int ret; + + ret = *(volatile u8 *)addr; + eieio(); + return ret; +} + +static inline unsigned int z_readw(unsigned long addr) +{ + unsigned int ret; + + ret = *(volatile u16 *)addr; + eieio(); + return ret; +} + +static inline unsigned int z_readl(unsigned long addr) +{ + unsigned int ret; + + ret = *(volatile u32 *)addr; + eieio(); + return ret; +} + +static inline void z_writeb(unsigned int val, unsigned long addr) +{ + *(volatile u8 *)addr = val; + eieio(); +} + +static inline void z_writew(unsigned int val, unsigned long addr) +{ + *(volatile u16 *)addr = val; + eieio(); +} + +static inline void z_writel(unsigned int val,unsigned long addr) +{ + *(volatile u32 *)addr = val; + eieio(); +} #define z_memset_io(a,b,c) memset((void *)(a),(b),(c)) #define z_memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) @@ -19,7 +56,6 @@ unsigned long flags); extern void *ioremap(unsigned long address, unsigned long size); -extern void iounmap(void *addr); extern void *__ioremap(unsigned long address, unsigned long size, unsigned long flags); diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/head.S linux-2.6.13-apus/arch/ppc/kernel/head.S --- linux-2.6.13/arch/ppc/kernel/head.S 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/head.S 2005-08-04 01:40:55.000000000 +0200 @@ -353,6 +353,28 @@ #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) . = 0x100 b __secondary_start_gemini +#elif defined(CONFIG_APUS) + . = 0x100 + mfspr r4,SPRN_HID0 + li r3,0 + ori r3,r3,0xc000 + andc r4,r4,r3 + mtspr SPRN_HID0,r4 + isync + sync + lis r8,0x6170 + ori r8,r8,0x7573 + lis r9,0xfff0 + lwz r9,0x1f8(r9) + lis r1,init_thread_union@ha + addi r1,r1,init_thread_union@l + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + subis r1,r1,KERNELBASE@h + add r1,r1,r9 + mr r3,r8 + mr r4,r9 + mtlr r4 + blrl #else EXCEPTION(0x100, Reset, UnknownException, EXC_XFER_STD) #endif @@ -408,7 +430,15 @@ bne 1f /* if not, try to put a PTE */ mfspr r4,SPRN_DAR /* into the hash table */ rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ +#ifndef CONFIG_APUS bl hash_page +#else + lis r5,hash_page@h + ori r5,r5,hash_page@l + tophys(r5,r5) + mtlr r5 + blrl +#endif 1: stw r10,_DSISR(r11) mr r5,r10 mfspr r4,SPRN_DAR @@ -433,7 +463,15 @@ beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ mr r4,r12 /* SRR0 is fault address */ +#ifndef CONFIG_APUS bl hash_page +#else + lis r5,hash_page@h + ori r5,r5,hash_page@l + tophys(r5,r5) + mtlr r5 + blrl +#endif 1: mr r4,r12 mr r5,r9 EXC_XFER_EE_LITE(0x400, handle_page_fault) @@ -1201,19 +1239,6 @@ bl machine_init bl MMU_init -#ifdef CONFIG_APUS - /* Copy exception code to exception vector base on APUS. */ - lis r4,KERNELBASE@h -#ifdef CONFIG_APUS_FAST_EXCEPT - lis r3,0xfff0 /* Copy to 0xfff00000 */ -#else - lis r3,0 /* Copy to 0x00000000 */ -#endif - li r5,0x4000 /* # bytes of memory to copy */ - li r6,0 - bl copy_and_flush /* copy the first 0x4000 bytes */ -#endif /* CONFIG_APUS */ - /* * Go back to running unmapped so we can load up new values * for SDR1 (hash table pointer) and the segment registers @@ -1231,6 +1256,22 @@ /* Load up the kernel context */ 2: bl load_up_mmu +#ifdef CONFIG_APUS + /* Copy exception code to exception vector base on APUS. */ + lis r4,KERNELBASE@h + tophys(r4,r4) +#ifdef CONFIG_APUS_FAST_EXCEPT + lis r3,0xfff0 /* Copy to 0xfff00000 */ +#else + lis r3,0 /* Copy to 0x00000000 */ +#endif + lis r5,__head_end@h /* # bytes of memory to copy */ + ori r5,r5,__head_end@l + subis r5,r5,KERNELBASE@h + li r6,0 + bl copy_and_flush /* copy the first 0x4000 bytes */ +#endif /* CONFIG_APUS */ + #ifdef CONFIG_BDI_SWITCH /* Add helper information for the Abatron bdiGDB debugger. * We do this here because we know the mmu is disabled, and @@ -1411,6 +1452,17 @@ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ mtspr SPRN_IBAT0L,r8 mtspr SPRN_IBAT0U,r11 +#ifdef CONFIG_APUS + /* map ZII space for early debug prints */ + lis r8,0x8000 + ori r8,r8,0x01ff + mtspr SPRN_DBAT2U,r8 + mtspr SPRN_IBAT2U,r8 + lis r8,0x0000 + ori r8,r8,0x002a + mtspr SPRN_DBAT2L,r8 + mtspr SPRN_IBAT2L,r8 +#endif isync blr diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/setup.c linux-2.6.13-apus/arch/ppc/kernel/setup.c --- linux-2.6.13/arch/ppc/kernel/setup.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/setup.c 2005-09-18 15:03:35.000000000 +0200 @@ -542,6 +542,7 @@ #endif /* CONFIG_SERIAL_CORE_CONSOLE */ #endif /* CONFIG_PPC_MULTIPLATFORM */ +#ifndef CONFIG_APUS struct bi_record *find_bootinfo(void) { struct bi_record *rec; @@ -588,6 +589,7 @@ rec = (struct bi_record *)((ulong)rec + rec->size); } } +#endif /* * Find out what kind of machine we're on and save any data we need diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/time.c linux-2.6.13-apus/arch/ppc/kernel/time.c --- linux-2.6.13/arch/ppc/kernel/time.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/time.c 2005-09-18 15:03:35.000000000 +0200 @@ -153,6 +153,7 @@ tb_last_stamp = jiffy_stamp; do_timer(regs); +#ifndef CONFIG_APUS /* * update the rtc when needed, this should be performed on the * right fraction of a second. Half or full second ? @@ -179,6 +180,7 @@ /* Try again one minute later */ last_rtc_update += 60; } +#endif write_sequnlock(&xtime_lock); } if ( !disarm_decr[smp_processor_id()] ) diff -Nur -x CVS linux-2.6.13/include/asm-ppc/machdep.h linux-2.6.13-apus/include/asm-ppc/machdep.h --- linux-2.6.13/include/asm-ppc/machdep.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/machdep.h 2005-09-18 15:03:36.000000000 +0200 @@ -9,10 +9,6 @@ #include #include -#ifdef CONFIG_APUS -#include -#endif - struct pt_regs; struct pci_bus; struct pci_dev; diff -Nur -x CVS linux-2.6.13/include/asm-m68k/bootinfo.h linux-2.6.13-apus/include/asm-m68k/bootinfo.h --- linux-2.6.13/include/asm-m68k/bootinfo.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-m68k/bootinfo.h 2005-07-30 22:49:24.000000000 +0200 @@ -81,6 +81,8 @@ #define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */ #define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */ #define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */ +#define BI_AMIGA_PUP_BRIDGE 0x8008 /* powerup bridge (u_short) */ +#define BI_AMIGA_BPPC_SCSI 0x8009 /* blizzard ppc scsi*/ /* * Atari-specific tags diff -Nur -x CVS linux-2.6.13/include/asm-ppc/amigahw.h linux-2.6.13-apus/include/asm-ppc/amigahw.h --- linux-2.6.13/include/asm-ppc/amigahw.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/amigahw.h 2004-07-03 19:59:46.000000000 +0200 @@ -1,6 +1,6 @@ -#ifdef __KERNEL__ #ifndef __ASMPPC_AMIGAHW_H #define __ASMPPC_AMIGAHW_H +#ifdef __KERNEL__ #include #include @@ -12,6 +12,13 @@ #define CHIP_PHYSADDR (0x004000) #endif +struct rtc_time; + +extern void amiga_init_IRQ(void); +extern int amiga_hwclk(int, struct rtc_time *); +extern int amiga_set_clock_mmss (unsigned long nowtime); +extern void config_amiga(void); +extern void apus_setup_pci_ptrs(void); -#endif /* __ASMPPC_AMIGAHW_H */ #endif /* __KERNEL__ */ +#endif /* __ASMPPC_AMIGAHW_H */ diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/entry.S linux-2.6.13-apus/arch/ppc/kernel/entry.S --- linux-2.6.13/arch/ppc/kernel/entry.S 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/entry.S 2005-09-18 15:03:35.000000000 +0200 @@ -1000,3 +1000,6 @@ /* XXX load up BATs and panic */ #endif /* CONFIG_PPC_OF */ + + .global __head_end +__head_end: diff -Nur -x CVS linux-2.6.13/include/asm-ppc/bootinfo.h linux-2.6.13-apus/include/asm-ppc/bootinfo.h --- linux-2.6.13/include/asm-ppc/bootinfo.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/bootinfo.h 2004-02-21 22:42:00.000000000 +0100 @@ -36,7 +36,6 @@ extern void bootinfo_init(struct bi_record *rec); extern void bootinfo_append(unsigned long tag, unsigned long size, void * data); extern void parse_bootinfo(struct bi_record *rec); -extern unsigned long boot_mem_size; static inline struct bi_record * bootinfo_addr(unsigned long offset) @@ -47,6 +46,7 @@ } #endif /* CONFIG_APUS */ +extern unsigned long boot_mem_size; #endif /* _PPC_BOOTINFO_H */ #endif /* __KERNEL__ */ diff -Nur -x CVS linux-2.6.13/include/asm-ppc/current.h linux-2.6.13-apus/include/asm-ppc/current.h --- linux-2.6.13/include/asm-ppc/current.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/current.h 2004-02-04 22:21:36.000000000 +0100 @@ -1,11 +1,11 @@ -#ifdef __KERNEL__ #ifndef _PPC_CURRENT_H #define _PPC_CURRENT_H +#ifdef __KERNEL__ /* * We keep `current' in r2 for speed. */ register struct task_struct *current asm ("r2"); -#endif /* !(_PPC_CURRENT_H) */ #endif /* __KERNEL__ */ +#endif /* !(_PPC_CURRENT_H) */ diff -Nur -x CVS linux-2.6.13/arch/ppc/mm/init.c linux-2.6.13-apus/arch/ppc/mm/init.c --- linux-2.6.13/arch/ppc/mm/init.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/mm/init.c 2005-09-18 15:03:35.000000000 +0200 @@ -61,9 +61,6 @@ unsigned long total_memory; unsigned long total_lowmem; -unsigned long ppc_memstart; -unsigned long ppc_memoffset = PAGE_OFFSET; - int mem_init_done; int init_bootmem_done; int boot_mapsize; diff -Nur -x CVS linux-2.6.13/arch/ppc/mm/Makefile linux-2.6.13-apus/arch/ppc/mm/Makefile --- linux-2.6.13/arch/ppc/mm/Makefile 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/mm/Makefile 2004-09-25 23:09:43.000000000 +0200 @@ -5,7 +5,8 @@ obj-y := fault.o init.o mem_pieces.o \ mmu_context.o pgtable.o -obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o +extra-$(CONFIG_PPC_STD_MMU) := hashtable.o +obj-$(CONFIG_PPC_STD_MMU) += ppc_mmu.o tlb.o obj-$(CONFIG_40x) += 4xx_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o diff -Nur -x CVS linux-2.6.13/arch/ppc/mm/pgtable.c linux-2.6.13-apus/arch/ppc/mm/pgtable.c --- linux-2.6.13/arch/ppc/mm/pgtable.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/mm/pgtable.c 2005-09-18 15:03:35.000000000 +0200 @@ -190,8 +190,8 @@ * Don't allow anybody to remap normal RAM that we're using. * mem_init() sets high_memory so only do the check after that. */ - if ( mem_init_done && (p < virt_to_phys(high_memory)) ) - { + if (mem_init_done && (p + size >= virt_to_phys(KERNELBASE)) && + (p < virt_to_phys(high_memory))) { printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p, __builtin_return_address(0)); return NULL; @@ -429,42 +429,3 @@ return(pa); } - -/* This is will find the virtual address for a physical one.... - * Swiped from APUS, could be dangerous :-). - * This is only a placeholder until I really find a way to make this - * work. -- Dan - */ -unsigned long -mm_ptov (unsigned long paddr) -{ - unsigned long ret; -#if 0 - if (paddr < 16*1024*1024) - ret = ZTWO_VADDR(paddr); - else { - int i; - - for (i = 0; i < kmap_chunk_count;){ - unsigned long phys = kmap_chunks[i++]; - unsigned long size = kmap_chunks[i++]; - unsigned long virt = kmap_chunks[i++]; - if (paddr >= phys - && paddr < (phys + size)){ - ret = virt + paddr - phys; - goto exit; - } - } - - ret = (unsigned long) __va(paddr); - } -exit: -#ifdef DEBUGPV - printk ("PTOV(%lx)=%lx\n", paddr, ret); -#endif -#else - ret = (unsigned long)paddr + KERNELBASE; -#endif - return ret; -} - diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/ppc_ksyms.c linux-2.6.13-apus/arch/ppc/kernel/ppc_ksyms.c --- linux-2.6.13/arch/ppc/kernel/ppc_ksyms.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/ppc_ksyms.c 2005-09-18 15:03:35.000000000 +0200 @@ -68,8 +68,6 @@ long long __ashldi3(long long, int); long long __lshrdi3(long long, int); -extern unsigned long mm_ptov (unsigned long paddr); - EXPORT_SYMBOL(clear_pages); EXPORT_SYMBOL(clear_user_page); EXPORT_SYMBOL(do_signal); @@ -145,7 +143,6 @@ EXPORT_SYMBOL(_insl_ns); EXPORT_SYMBOL(_outsl_ns); EXPORT_SYMBOL(iopa); -EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(ioremap); #ifdef CONFIG_44x EXPORT_SYMBOL(ioremap64); diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/Makefile linux-2.6.13-apus/arch/ppc/kernel/Makefile --- linux-2.6.13/arch/ppc/kernel/Makefile 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/Makefile 2005-09-18 15:03:35.000000000 +0200 @@ -9,10 +9,11 @@ extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o extra-$(CONFIG_POWER4) += idle_power4.o +extra-y += entry.o extra-$(CONFIG_PPC_FPU) += fpu.o extra-y += vmlinux.lds -obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ +obj-y := traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ semaphore.o syscalls.o setup.o \ cputable.o ppc_htab.o perfmon.o diff -Nur -x CVS linux-2.6.13/arch/ppc/Makefile linux-2.6.13-apus/arch/ppc/Makefile --- linux-2.6.13/arch/ppc/Makefile 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/Makefile 2005-09-18 15:03:35.000000000 +0200 @@ -52,6 +52,8 @@ head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o +head-y += arch/ppc/mm/hashtable.o +head-y += arch/ppc/kernel/entry.o head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o @@ -74,7 +76,9 @@ .PHONY: $(BOOT_TARGETS) +ifndef CONFIG_APUS all: uImage zImage +endif CPPFLAGS_vmlinux.lds := -Upowerpc diff -Nur -x CVS linux-2.6.13/arch/ppc/kernel/misc.S linux-2.6.13-apus/arch/ppc/kernel/misc.S --- linux-2.6.13/arch/ppc/kernel/misc.S 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/arch/ppc/kernel/misc.S 2005-09-18 15:03:35.000000000 +0200 @@ -1377,7 +1377,11 @@ .long sys_fstat64 .long sys_pciconfig_read .long sys_pciconfig_write +#ifdef CONFIG_PCI .long sys_pciconfig_iobase /* 200 */ +#else + .long sys_ni_syscall +#endif .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ .long sys_getdents64 .long sys_pivot_root diff -Nur -x CVS linux-2.6.13/include/asm-ppc/pgtable.h linux-2.6.13-apus/include/asm-ppc/pgtable.h --- linux-2.6.13/include/asm-ppc/pgtable.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/pgtable.h 2005-09-18 15:03:36.000000000 +0200 @@ -723,7 +723,7 @@ #define pmd_page_kernel(pmd) \ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) #define pmd_page(pmd) \ - (mem_map + (pmd_val(pmd) >> PAGE_SHIFT)) + pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) #else #define pmd_page_kernel(pmd) \ ((unsigned long) (pmd_val(pmd) & PAGE_MASK)) diff -Nur -x CVS linux-2.6.13/drivers/block/amiflop.c linux-2.6.13-apus/drivers/block/amiflop.c --- linux-2.6.13/drivers/block/amiflop.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/drivers/block/amiflop.c 2005-07-31 01:06:43.000000000 +0200 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include diff -Nur -x CVS linux-2.6.13/arch/ppc/Kconfig linux-2.6.13-apus/arch/ppc/Kconfig --- linux-2.6.13/arch/ppc/Kconfig 2005-08-28 23:41:01.000000000 +0000 +++ linux-2.6.13-apus/arch/ppc/Kconfig 2005-09-25 07:08:31.000000000 +0000 @@ -558,7 +576,6 @@ config APUS bool "Amiga-APUS" - depends on BROKEN help Select APUS if configuring for a PowerUP Amiga. More information is available at: diff -Nur -x CVS linux-2.6.13/include/asm-ppc/io.h linux-2.6.13-apus/include/asm-ppc/io.h --- linux-2.6.13/include/asm-ppc/io.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/asm-ppc/io.h 2005-07-31 03:18:36.000000000 +0200 @@ -1,6 +1,6 @@ -#ifdef __KERNEL__ #ifndef _PPC_IO_H #define _PPC_IO_H +#ifdef __KERNEL__ #include #include @@ -294,10 +294,10 @@ __do_out_asm(outb, "stbx") #ifdef CONFIG_APUS __do_in_asm(inb, "lbzx") -__do_in_asm(inw, "lhz%U1%X1") -__do_in_asm(inl, "lwz%U1%X1") -__do_out_asm(outl,"stw%U0%X0") -__do_out_asm(outw, "sth%U0%X0") +__do_in_asm(inw, "lhzx") +__do_in_asm(inl, "lwzx") +__do_out_asm(outl,"stwx") +__do_out_asm(outw, "sthx") #elif defined (CONFIG_8260_PCI9) /* in asm cannot be defined if PCI9 workaround is used */ #define inb(port) in_8((port)+___IO_BASE) @@ -377,12 +377,19 @@ extern void __iomem *ioremap64(unsigned long long address, unsigned long size); #endif #define ioremap_nocache(addr, size) ioremap((addr), (size)) +#define ioremap_writethrough(addr, size) __ioremap((addr), (size), _PAGE_WRITETHRU) extern void iounmap(volatile void __iomem *addr); extern unsigned long iopa(unsigned long addr); extern unsigned long mm_ptov(unsigned long addr) __attribute_const__; extern void io_block_mapping(unsigned long virt, phys_addr_t phys, unsigned int size, int flags); +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + /* * The PCI bus is inherently Little-Endian. The PowerPC is being * run Big-Endian. Thus all values which cross the [PCI] barrier @@ -392,24 +399,16 @@ */ extern inline unsigned long virt_to_bus(volatile void * address) { -#ifndef CONFIG_APUS if (address == (void *)0) return 0; - return (unsigned long)address - KERNELBASE + PCI_DRAM_OFFSET; -#else - return iopa ((unsigned long) address); -#endif + return __pa(address) + PCI_DRAM_OFFSET; } extern inline void * bus_to_virt(unsigned long address) { -#ifndef CONFIG_APUS if (address == 0) return NULL; - return (void *)(address - PCI_DRAM_OFFSET + KERNELBASE); -#else - return (void*) mm_ptov (address); -#endif + return __va(address) - PCI_DRAM_OFFSET; } /* @@ -418,20 +417,12 @@ */ extern inline unsigned long virt_to_phys(volatile void * address) { -#ifndef CONFIG_APUS - return (unsigned long) address - KERNELBASE; -#else - return iopa ((unsigned long) address); -#endif + return __pa(address); } extern inline void * phys_to_virt(unsigned long address) { -#ifndef CONFIG_APUS - return (void *) (address + KERNELBASE); -#else - return (void*) mm_ptov (address); -#endif + return __va(address); } /* @@ -546,8 +537,6 @@ extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); extern void pci_iounmap(struct pci_dev *dev, void __iomem *); -#endif /* _PPC_IO_H */ - #ifdef CONFIG_8260_PCI9 #include #endif @@ -564,3 +553,4 @@ #define xlate_dev_kmem_ptr(p) p #endif /* __KERNEL__ */ +#endif /* _PPC_IO_H */ diff -Nur -x CVS linux-2.6.13/include/video/vga.h linux-2.6.13-apus/include/video/vga.h --- linux-2.6.13/include/video/vga.h 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/include/video/vga.h 2005-07-30 20:52:54.000000000 +0200 @@ -28,6 +28,9 @@ * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space * for MMIO accesses. This should make cirrusfb work again on Amiga */ +#ifdef CONFIG_APUS +#include +#endif #undef inb_p #undef inw_p #undef outb_p --- linux-2.6.13/sound/oss/dmasound/dmasound_paula.c 2005-08-29 01:41:01.000000000 +0200 +++ linux-2.6.13-apus/sound/oss/dmasound/dmasound_paula.c 2005-09-25 21:50:11.000000000 +0200 @@ -244,6 +244,7 @@ u_char frame[], ssize_t *frameUsed, \ ssize_t frameLeft) \ { \ + const u_short *ptr = (const u_short *)userPtr; \ ssize_t count, used; \ u_short data; \ \ @@ -253,7 +254,7 @@ count = min_t(size_t, userCount, frameLeft)>>1 & ~1; \ used = count*2; \ while (count > 0) { \ - if (get_user(data, ((u_short *)userPtr)++)) \ + if (get_user(data, ptr++)) \ return -EFAULT; \ data = convsample(data); \ *high++ = data>>8; \ @@ -268,12 +269,12 @@ count = min_t(size_t, userCount, frameLeft)>>2 & ~1; \ used = count*4; \ while (count > 0) { \ - if (get_user(data, ((u_short *)userPtr)++)) \ + if (get_user(data, ptr++)) \ return -EFAULT; \ data = convsample(data); \ *lefth++ = data>>8; \ *leftl++ = (data>>2) & 0x3f; \ - if (get_user(data, ((u_short *)userPtr)++)) \ + if (get_user(data, ptr++)) \ return -EFAULT; \ data = convsample(data); \ *righth++ = data>>8; \