summaryrefslogtreecommitdiffstats
path: root/arch/ppc/amiga
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /arch/ppc/amiga
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (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/Makefile15
-rw-r--r--arch/ppc/amiga/amiga_ksyms.c1
-rw-r--r--arch/ppc/amiga/amiints.c5
-rw-r--r--arch/ppc/amiga/amisound.c1
-rw-r--r--arch/ppc/amiga/bootinfo.c74
-rw-r--r--arch/ppc/amiga/chipram.c1
-rw-r--r--arch/ppc/amiga/cia.c1
-rw-r--r--arch/ppc/amiga/config.c7
-rw-r--r--arch/ppc/amiga/ints.c156
-rw-r--r--arch/ppc/amiga/time.c70
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 */
+}
+
+