diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /arch/ppc/amiga | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff) |
o Merge with Linux 2.1.116.
o New Newport console code.
o New G364 console code.
Diffstat (limited to 'arch/ppc/amiga')
-rw-r--r-- | arch/ppc/amiga/Makefile | 15 | ||||
-rw-r--r-- | arch/ppc/amiga/amiga_ksyms.c | 1 | ||||
-rw-r--r-- | arch/ppc/amiga/amiints.c | 5 | ||||
-rw-r--r-- | arch/ppc/amiga/amisound.c | 1 | ||||
-rw-r--r-- | arch/ppc/amiga/bootinfo.c | 74 | ||||
-rw-r--r-- | arch/ppc/amiga/chipram.c | 1 | ||||
-rw-r--r-- | arch/ppc/amiga/cia.c | 1 | ||||
-rw-r--r-- | arch/ppc/amiga/config.c | 7 | ||||
-rw-r--r-- | arch/ppc/amiga/ints.c | 156 | ||||
-rw-r--r-- | arch/ppc/amiga/time.c | 70 |
10 files changed, 331 insertions, 0 deletions
diff --git a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile new file mode 100644 index 000000000..2658af4c7 --- /dev/null +++ b/arch/ppc/amiga/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for Linux arch/m68k/amiga source directory +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +O_TARGET := amiga.o +O_OBJS := config.o amiints.o cia.o time.o \ + bootinfo.o amisound.o chipram.o ints.o +OX_OBJS := amiga_ksyms.o + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/amiga/amiga_ksyms.c b/arch/ppc/amiga/amiga_ksyms.c new file mode 100644 index 000000000..ec74e5b7a --- /dev/null +++ b/arch/ppc/amiga/amiga_ksyms.c @@ -0,0 +1 @@ +#include "../../m68k/amiga/amiga_ksyms.c" diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c new file mode 100644 index 000000000..a9a6b218d --- /dev/null +++ b/arch/ppc/amiga/amiints.c @@ -0,0 +1,5 @@ +/* Rename a few functions. */ +#define amiga_request_irq request_irq +#define amiga_free_irq free_irq + +#include "../../m68k/amiga/amiints.c" diff --git a/arch/ppc/amiga/amisound.c b/arch/ppc/amiga/amisound.c new file mode 100644 index 000000000..2b86cbef7 --- /dev/null +++ b/arch/ppc/amiga/amisound.c @@ -0,0 +1 @@ +#include "../../m68k/amiga/amisound.c" diff --git a/arch/ppc/amiga/bootinfo.c b/arch/ppc/amiga/bootinfo.c new file mode 100644 index 000000000..f24a0c5b8 --- /dev/null +++ b/arch/ppc/amiga/bootinfo.c @@ -0,0 +1,74 @@ +/* + * linux/arch/ppc/amiga/bootinfo.c + * + * Extracted from arch/m68k/kernel/setup.c. + * Should be properly generalized and put somewhere else. + * Jesper + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/init.h> + +#include <asm/setup.h> +#include <asm/bootinfo.h> + +extern char cmd_line[CL_SIZE]; + +int num_memory = 0; +extern struct mem_info memory[NUM_MEMINFO]; +extern struct mem_info ramdisk; + +extern int amiga_parse_bootinfo(const struct bi_record *); +extern int atari_parse_bootinfo(const struct bi_record *); +extern int mac_parse_bootinfo(const struct bi_record *); + +__initfunc(void parse_bootinfo(const struct bi_record *record)) +{ + while (record->tag != BI_LAST) { + int unknown = 0; + const u_long *data = record->data; + switch (record->tag) { + case BI_MACHTYPE: + case BI_CPUTYPE: + case BI_FPUTYPE: + case BI_MMUTYPE: + /* Already set up by head.S */ + break; + + case BI_MEMCHUNK: + if (num_memory < NUM_MEMINFO) { + memory[num_memory].addr = data[0]; + memory[num_memory].size = data[1]; + num_memory++; + } else + printk("parse_bootinfo: too many memory chunks\n"); + break; + + case BI_RAMDISK: + ramdisk.addr = data[0]; + ramdisk.size = data[1]; + break; + + case BI_COMMAND_LINE: + strncpy(cmd_line, (const char *)data, CL_SIZE); + cmd_line[CL_SIZE-1] = '\0'; + break; + + default: + if (MACH_IS_AMIGA) + unknown = amiga_parse_bootinfo(record); + else if (MACH_IS_ATARI) + unknown = atari_parse_bootinfo(record); + else if (MACH_IS_MAC) + unknown = mac_parse_bootinfo(record); + else + unknown = 1; + } + if (unknown) + printk("parse_bootinfo: unknown tag 0x%04x ignored\n", + record->tag); + record = (struct bi_record *)((u_long)record+record->size); + } +} diff --git a/arch/ppc/amiga/chipram.c b/arch/ppc/amiga/chipram.c new file mode 100644 index 000000000..e6ab3c6b2 --- /dev/null +++ b/arch/ppc/amiga/chipram.c @@ -0,0 +1 @@ +#include "../../m68k/amiga/chipram.c" diff --git a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c new file mode 100644 index 000000000..ea35c79b3 --- /dev/null +++ b/arch/ppc/amiga/cia.c @@ -0,0 +1 @@ +#include "../../m68k/amiga/cia.c" diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c new file mode 100644 index 000000000..d24aeb621 --- /dev/null +++ b/arch/ppc/amiga/config.c @@ -0,0 +1,7 @@ +#define m68k_debug_device debug_device +#define m68k_num_memory num_memory +#define m68k_memory memory + +#include <asm/io.h> + +#include "../../m68k/amiga/config.c" diff --git a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c new file mode 100644 index 000000000..d13ce5db7 --- /dev/null +++ b/arch/ppc/amiga/ints.c @@ -0,0 +1,156 @@ +/* + * linux/arch/ppc/amiga/ints.c + * + * Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c + * Needed to drive the m68k emulating IRQ hardware on the PowerUp boards. + */ + +#include <linux/types.h> +#include <linux/kernel_stat.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/init.h> + +#include <asm/setup.h> +#include <asm/irq.h> +#include <asm/traps.h> +#include <asm/machdep.h> + +/* table for system interrupt handlers */ +irq_handler_t irq_list[SYS_IRQS]; + +static const char *default_names[SYS_IRQS] = { + "spurious int", "int1 handler", "int2 handler", "int3 handler", + "int4 handler", "int5 handler", "int6 handler", "int7 handler" +}; + +/* The number of spurious interrupts */ +volatile unsigned int num_spurious; + +#define NUM_IRQ_NODES 100 +static irq_node_t nodes[NUM_IRQ_NODES]; + + +/* + * void init_IRQ(void) + * + * Parameters: None + * + * Returns: Nothing + * + * This function should be called during kernel startup to initialize + * the IRQ handling routines. + */ + +__initfunc(void apus_init_IRQ(void)) +{ + int i; + + for (i = 0; i < SYS_IRQS; i++) { + if (mach_default_handler) + irq_list[i].handler = (*mach_default_handler)[i]; + irq_list[i].flags = IRQ_FLG_STD; + irq_list[i].dev_id = NULL; + irq_list[i].devname = default_names[i]; + } + + for (i = 0; i < NUM_IRQ_NODES; i++) + nodes[i].handler = NULL; + + mach_init_IRQ (); +} + +irq_node_t *new_irq_node(void) +{ + irq_node_t *node; + short i; + + for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) + if (!node->handler) + return node; + + printk ("new_irq_node: out of nodes\n"); + return NULL; +} + +int sys_request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) +{ + if (irq < IRQ1 || irq > IRQ7) { + printk("%s: Incorrect IRQ %d from %s\n", + __FUNCTION__, irq, devname); + return -ENXIO; + } + + if (!(irq_list[irq].flags & IRQ_FLG_STD)) { + if (irq_list[irq].flags & IRQ_FLG_LOCK) { + printk("%s: IRQ %d from %s is not replaceable\n", + __FUNCTION__, irq, irq_list[irq].devname); + return -EBUSY; + } + if (!(flags & IRQ_FLG_REPLACE)) { + printk("%s: %s can't replace IRQ %d from %s\n", + __FUNCTION__, devname, irq, irq_list[irq].devname); + return -EBUSY; + } + } + irq_list[irq].handler = handler; + irq_list[irq].flags = flags; + irq_list[irq].dev_id = dev_id; + irq_list[irq].devname = devname; + return 0; +} + +void sys_free_irq(unsigned int irq, void *dev_id) +{ + if (irq < IRQ1 || irq > IRQ7) { + printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); + return; + } + + if (irq_list[irq].dev_id != dev_id) + printk("%s: Removing probably wrong IRQ %d from %s\n", + __FUNCTION__, irq, irq_list[irq].devname); + + irq_list[irq].handler = (*mach_default_handler)[irq]; + irq_list[irq].flags = IRQ_FLG_STD; + irq_list[irq].dev_id = NULL; + irq_list[irq].devname = default_names[irq]; +} + +asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) +{ + if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) { + vec -= VEC_SPUR; + kstat.irqs[0][vec]++; + irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); + } else { + if (mach_process_int) + mach_process_int(vec, fp); + else + panic("Can't process interrupt vector %ld\n", vec); + return; + } +} + +int get_irq_list(char *buf) +{ + int i, len = 0; + + /* autovector interrupts */ + if (mach_default_handler) { + for (i = 0; i < SYS_IRQS; i++) { + len += sprintf(buf+len, "auto %2d: %10u ", i, + i ? kstat.irqs[0][i] : num_spurious); + if (irq_list[i].flags & IRQ_FLG_LOCK) + len += sprintf(buf+len, "L "); + else + len += sprintf(buf+len, " "); + len += sprintf(buf+len, "%s\n", irq_list[i].devname); + } + } + + len += mach_get_irq_list(buf+len); + return len; +} diff --git a/arch/ppc/amiga/time.c b/arch/ppc/amiga/time.c new file mode 100644 index 000000000..b14a59b53 --- /dev/null +++ b/arch/ppc/amiga/time.c @@ -0,0 +1,70 @@ +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/mm.h> + +#include <asm/machdep.h> +#include <asm/io.h> + +#include <linux/timex.h> + +static inline unsigned long mktime(unsigned int year, unsigned int mon, + unsigned int day, unsigned int hour, + unsigned int min, unsigned int sec); + +unsigned long apus_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 apus_set_rtc_time(unsigned long nowtime) +{ + if (mach_set_clock_mmss) + return mach_set_clock_mmss (nowtime); + return -1; +} + +/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. + * + * [For the Julian calendar (which was used in Russia before 1917, + * Britain & colonies before 1752, anywhere else before 1582, + * and is still in use by some communities) leave out the + * -year/100+year/400 terms, and add 10.] + * + * This algorithm was first published by Gauss (I think). + * + * WARNING: this function will overflow on 2106-02-07 06:28:16 on + * machines were long is 32-bit! (However, as time_t is signed, we + * will already get problems at other places on 2038-01-19 03:14:08) + */ +static inline unsigned long mktime(unsigned int year, unsigned int mon, + unsigned int day, unsigned int hour, + unsigned int min, unsigned int sec) +{ + if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ + mon += 12; /* Puts Feb last since it has leap day */ + year -= 1; + } + return ((( + (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + + year*365 - 719499 + )*24 + hour /* now have hours */ + )*60 + min /* now have minutes */ + )*60 + sec; /* finally seconds */ +} + + |