summaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/kernel')
-rw-r--r--arch/ppc/kernel/chrp_pci.c3
-rw-r--r--arch/ppc/kernel/chrp_setup.c8
-rw-r--r--arch/ppc/kernel/gemini_setup.c13
-rw-r--r--arch/ppc/kernel/irq.c7
-rw-r--r--arch/ppc/kernel/local_irq.h2
-rw-r--r--arch/ppc/kernel/m8xx_setup.c4
-rw-r--r--arch/ppc/kernel/mbx_pci.c269
-rw-r--r--arch/ppc/kernel/mbx_setup.c486
-rw-r--r--arch/ppc/kernel/open_pic.c49
-rw-r--r--arch/ppc/kernel/open_pic.h1
-rw-r--r--arch/ppc/kernel/pci.c16
-rw-r--r--arch/ppc/kernel/pmac_pci.c2
-rw-r--r--arch/ppc/kernel/pmac_pic.c8
-rw-r--r--arch/ppc/kernel/pmac_setup.c24
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c3
-rw-r--r--arch/ppc/kernel/prep_pci.c5
-rw-r--r--arch/ppc/kernel/prep_setup.c4
-rw-r--r--arch/ppc/kernel/process.c9
-rw-r--r--arch/ppc/kernel/smp.c174
19 files changed, 173 insertions, 914 deletions
diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c
index 88686acc4..b93bc45f7 100644
--- a/arch/ppc/kernel/chrp_pci.c
+++ b/arch/ppc/kernel/chrp_pci.c
@@ -282,8 +282,7 @@ chrp_pcibios_fixup(void)
}
/* PCI interrupts are controlled by the OpenPIC */
- for( dev=pci_devices ; dev; dev=dev->next )
- {
+ pci_for_each_dev(dev) {
if ( dev->irq )
dev->irq = openpic_to_irq( dev->irq );
/* these need to be absolute addrs for OF and Matrox FB -- Cort */
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index 938cea36d..e76aa8dd9 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -249,7 +249,7 @@ chrp_setup_arch(void)
else
#endif
ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
-
+sprintf(cmd_line, "console=ttyS0,9600 console=tty0");
printk("Boot arguments: %s\n", cmd_line);
request_region(0x20,0x20,"pic1");
@@ -391,7 +391,7 @@ void chrp_post_irq(int irq)
* openpic irq. So we just check to make sure the controller
* is an openpic and if it is then eoi
*
- * We do it this way since our irq_desc[irq].ctl can change
+ * We do it this way since our irq_desc[irq].handler can change
* with RTL and no longer be open_pic -- Cort
*/
if ( irq >= open_pic.irq_offset)
@@ -413,10 +413,10 @@ void __init chrp_init_IRQ(void)
}
open_pic.irq_offset = 16;
for ( i = 16 ; i < NR_IRQS ; i++ )
- irq_desc[i].ctl = &open_pic;
+ irq_desc[i].handler = &open_pic;
openpic_init(1);
for ( i = 0 ; i < 16 ; i++ )
- irq_desc[i].ctl = &i8259_pic;
+ irq_desc[i].handler = &i8259_pic;
i8259_init();
#ifdef CONFIG_XMON
request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c
index 57ea34687..fadddda8b 100644
--- a/arch/ppc/kernel/gemini_setup.c
+++ b/arch/ppc/kernel/gemini_setup.c
@@ -332,10 +332,17 @@ void __init gemini_init_IRQ(void)
/* gemini has no 8259 */
open_pic.irq_offset = 0;
for( i=0; i < NR_IRQS; i++ )
- irq_desc[i].ctl = &open_pic;
+ irq_desc[i].handler = &open_pic;
openpic_init(1);
#ifdef __SMP__
- request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, 0, "IPI0", 0);
+ request_irq(OPENPIC_VEC_IPI, openpic_ipi_action,
+ 0, "IPI0", 0);
+ request_irq(OPENPIC_VEC_IPI+1, openpic_ipi_action,
+ 0, "IPI1 (invalidate TLB)", 0);
+ request_irq(OPENPIC_VEC_IPI+2, openpic_ipi_action,
+ 0, "IPI2 (stop CPU)", 0);
+ request_irq(OPENPIC_VEC_IPI+3, openpic_ipi_action,
+ 0, "IPI3 (reschedule)", 0);
#endif /* __SMP__ */
}
@@ -505,7 +512,7 @@ void gemini_post_irq(int irq)
* openpic irq. So we just check to make sure the controller
* is an openpic and if it is then eoi
*
- * We do it this way since our irq_desc[irq].ctl can change
+ * We do it this way since our irq_desc[irq].handler can change
* with RTL and no longer be open_pic -- Cort
*/
if ( irq >= open_pic.irq_offset)
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 4427e801f..a09d6ad98 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -44,6 +44,7 @@
#include <linux/openpic.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/irq.h>
#include <asm/bitops.h>
#include <asm/hydra.h>
@@ -71,7 +72,7 @@ volatile unsigned char *chrp_int_ack_special;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-struct irqdesc irq_desc[NR_IRQS] = {{0, 0}, };
+irq_desc_t irq_desc[NR_IRQS];
int ppc_spurious_interrupts = 0;
unsigned int ppc_local_bh_count[NR_CPUS];
unsigned int ppc_local_irq_count[NR_CPUS];
@@ -244,8 +245,8 @@ int get_irq_list(char *buf)
#else
len += sprintf(buf+len, "%10u ", kstat_irqs(i));
#endif /* __SMP__ */
- if ( irq_desc[i].ctl )
- len += sprintf(buf+len, " %s ", irq_desc[i].ctl->typename );
+ if ( irq_desc[i].handler )
+ len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
else
len += sprintf(buf+len, " None ");
len += sprintf(buf+len, " %s",action->name);
diff --git a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h
index 8e9fe6df6..602192013 100644
--- a/arch/ppc/kernel/local_irq.h
+++ b/arch/ppc/kernel/local_irq.h
@@ -4,7 +4,7 @@
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
-#include <asm/irq_control.h>
+#include <linux/irq.h>
void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
index 4d510612b..36e886d0c 100644
--- a/arch/ppc/kernel/m8xx_setup.c
+++ b/arch/ppc/kernel/m8xx_setup.c
@@ -278,7 +278,7 @@ m8xx_init_IRQ(void)
ppc8xx_pic.irq_offset = 0;
for ( i = 0 ; i < NR_SIU_INTS ; i++ )
- irq_desc[i].ctl = &ppc8xx_pic;
+ irq_desc[i].handler = &ppc8xx_pic;
/* We could probably incorporate the CPM into the multilevel
* interrupt structure.
@@ -288,7 +288,7 @@ m8xx_init_IRQ(void)
#if defined(CONFIG_PCI)
for ( i = NR_SIU_INTS ; i < (NR_SIU_INTS + NR_8259_INTS) ; i++ )
- irq_desc[i].ctl = &i8259_pic;
+ irq_desc[i].handler = &i8259_pic;
i8259_pic.irq_offset = NR_SIU_INTS;
i8259_init();
request_8xxirq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
diff --git a/arch/ppc/kernel/mbx_pci.c b/arch/ppc/kernel/mbx_pci.c
deleted file mode 100644
index d7473e128..000000000
--- a/arch/ppc/kernel/mbx_pci.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * MBX pci routines.
- * The MBX uses the QSpan PCI bridge. The config address register
- * is located 0x500 from the base of the bridge control/status registers.
- * The data register is located at 0x504.
- * This is a two step operation. First, the address register is written,
- * then the data register is read/written as required.
- * I don't know what to do about interrupts (yet).
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/mbx.h>
-
-
-/*
- * This blows......The MBX uses the Tundra QSpan PCI bridge. When
- * reading the configuration space, if something does not respond
- * the bus times out and we get a machine check interrupt. So, the
- * good ol' exception tables come to mind to trap it and return some
- * value.
- *
- * On an error we just return a -1, since that is what the caller wants
- * returned if nothing is present. I copied this from __get_user_asm,
- * with the only difference of returning -1 instead of EFAULT.
- * There is an associated hack in the machine check trap code.
- *
- * The QSPAN is also a big endian device, that is it makes the PCI
- * look big endian to us. This presents a problem for the Linux PCI
- * functions, which assume little endian. For example, we see the
- * first 32-bit word like this:
- * ------------------------
- * | Device ID | Vendor ID |
- * ------------------------
- * If we read/write as a double word, that's OK. But in our world,
- * when read as a word, device ID is at location 0, not location 2 as
- * the little endian PCI would believe. We have to switch bits in
- * the PCI addresses given to us to get the data to/from the correct
- * byte lanes.
- *
- * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
- * It always forces the MS bit to zero. Therefore, dev_fn values
- * greater than 128 are returned as "no device found" errors.
- *
- * The QSPAN can only perform long word (32-bit) configuration cycles.
- * The "offset" must have the two LS bits set to zero. Read operations
- * require we read the entire word and then sort out what should be
- * returned. Write operations other than long word require that we
- * read the long word, update the proper word or byte, then write the
- * entire long word back.
- *
- * PCI Bridge hack. We assume (correctly) that bus 0 is the primary
- * PCI bus from the QSPAN. If we are called with a bus number other
- * than zero, we create a Type 1 configuration access that a downstream
- * PCI bridge will interpret.
- */
-
-#define __get_mbx_pci_config(x, addr, op) \
- __asm__ __volatile__( \
- "1: "op" %0,0(%1)\n" \
- " eieio\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,-1\n" \
- " b 2b\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,3b\n" \
- ".text" \
- : "=r"(x) : "r"(addr))
-
-#define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500))
-#define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504))
-
-#define mk_config_addr(bus, dev, offset) \
- (((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
-
-#define mk_config_type1(bus, dev, offset) \
- mk_config_addr(bus, dev, offset) | 1;
-
-int mbx_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- uint temp;
- u_char *cp;
-
- if ((bus > 7) || (dev_fn > 127)) {
- *val = 0xff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- __get_mbx_pci_config(temp, QS_CONFIG_DATA, "lwz");
-
- offset ^= 0x03;
- cp = ((u_char *)&temp) + (offset & 0x03);
- *val = *cp;
- return PCIBIOS_SUCCESSFUL;
-}
-
-int mbx_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- uint temp;
- ushort *sp;
-
- if ((bus > 7) || (dev_fn > 127)) {
- *val = 0xffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- __get_mbx_pci_config(temp, QS_CONFIG_DATA, "lwz");
- offset ^= 0x02;
-
- sp = ((ushort *)&temp) + ((offset >> 1) & 1);
- *val = *sp;
- return PCIBIOS_SUCCESSFUL;
-}
-
-int mbx_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- if ((bus > 7) || (dev_fn > 127)) {
- *val = 0xffffffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- __get_mbx_pci_config(*val, QS_CONFIG_DATA, "lwz");
- return PCIBIOS_SUCCESSFUL;
-}
-
-int mbx_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- uint temp;
- u_char *cp;
-
- if ((bus > 7) || (dev_fn > 127))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- mbx_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
-
- offset ^= 0x03;
- cp = ((u_char *)&temp) + (offset & 0x03);
- *cp = val;
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- *QS_CONFIG_DATA = temp;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int mbx_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- uint temp;
- ushort *sp;
-
- if ((bus > 7) || (dev_fn > 127))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- mbx_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
-
- offset ^= 0x02;
- sp = ((ushort *)&temp) + ((offset >> 1) & 1);
- *sp = val;
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- *QS_CONFIG_DATA = temp;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int mbx_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- if ((bus > 7) || (dev_fn > 127))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- if (bus == 0)
- *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
- else
- *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
- *(unsigned int *)QS_CONFIG_DATA = val;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int mbx_pcibios_find_device(unsigned short vendor, unsigned short dev_id,
- unsigned short index, unsigned char *bus_ptr,
- unsigned char *dev_fn_ptr)
-{
- int num, devfn;
- unsigned int x, vendev;
-
- if (vendor == 0xffff)
- return PCIBIOS_BAD_VENDOR_ID;
- vendev = (dev_id << 16) + vendor;
- num = 0;
- for (devfn = 0; devfn < 32; devfn++) {
- mbx_pcibios_read_config_dword(0, devfn<<3, PCI_VENDOR_ID, &x);
- if (x == vendev) {
- if (index == num) {
- *bus_ptr = 0;
- *dev_fn_ptr = devfn<<3;
- return PCIBIOS_SUCCESSFUL;
- }
- ++num;
- }
- }
- return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-int mbx_pcibios_find_class(unsigned int class_code, unsigned short index,
- unsigned char *bus_ptr, unsigned char *dev_fn_ptr)
-{
- int devnr, x, num;
-
- num = 0;
- for (devnr = 0; devnr < 32; devnr++) {
- mbx_pcibios_read_config_dword(0, devnr<<3, PCI_CLASS_REVISION, &x);
- if ((x>>8) == class_code) {
- if (index == num) {
- *bus_ptr = 0;
- *dev_fn_ptr = devnr<<3;
- return PCIBIOS_SUCCESSFUL;
- }
- ++num;
- }
- }
- return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-void __init
-mbx_pcibios_fixup(void)
-{
- /* Nothing to do here? */
-}
-
-void __init
-mbx_setup_pci_ptrs(void)
-{
- set_config_access_method(mbx);
-
- ppc_md.pcibios_fixup = mbx_pcibios_fixup;
-}
-
diff --git a/arch/ppc/kernel/mbx_setup.c b/arch/ppc/kernel/mbx_setup.c
deleted file mode 100644
index f6487783b..000000000
--- a/arch/ppc/kernel/mbx_setup.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * $Id: mbx_setup.c,v 1.12 1999/08/31 06:53:56 davem Exp $
- *
- * linux/arch/ppc/kernel/setup.c
- *
- * Copyright (C) 1995 Linus Torvalds
- * Adapted from 'alpha' version by Gary Thomas
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- * Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net)
- */
-
-/*
- * bootup setup stuff..
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/malloc.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/major.h>
-#include <linux/interrupt.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/blk.h>
-#include <linux/ide.h>
-#include <linux/ioport.h>
-
-#include <asm/mmu.h>
-#include <asm/processor.h>
-#include <asm/residual.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/mbx.h>
-#include <asm/machdep.h>
-
-#include "time.h"
-#include "local_irq.h"
-
-static int mbx_set_rtc_time(unsigned long time);
-unsigned long mbx_get_rtc_time(void);
-void mbx_calibrate_decr(void);
-
-extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int mackbd_getkeycode(unsigned int scancode);
-extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode);
-extern char mackbd_unexpected_up(unsigned char keycode);
-extern void mackbd_leds(unsigned char leds);
-extern void mackbd_init_hw(void);
-
-extern unsigned long loops_per_sec;
-
-unsigned long empty_zero_page[1024];
-
-#ifdef CONFIG_BLK_DEV_RAM
-extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
-extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start; /* starting block # of image */
-#endif
-
-extern char saved_command_line[256];
-
-extern unsigned long find_available_memory(void);
-extern void m8xx_cpm_reset(uint);
-
-void __init adbdev_init(void)
-{
-}
-
-void __init
-mbx_setup_arch(void)
-{
- int cpm_page;
- extern char cmd_line[];
-
- cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
-
- sprintf(cmd_line,
-"%s root=/dev/nfs nfsroot=/sys/mbxroot",
- cmd_line);
- printk("Boot arguments: %s\n", cmd_line);
-
- /* Reset the Communication Processor Module.
- */
- m8xx_cpm_reset(cpm_page);
-
-#ifdef notdef
- ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
-#if 0
- ROOT_DEV = to_kdev_t(0x0200); /* floppy */
- rd_prompt = 1;
- rd_doload = 1;
- rd_image_start = 0;
-#endif
-#if 0 /* XXX this may need to be updated for the new bootmem stuff,
- or possibly just deleted (see set_phys_avail() in init.c).
- - paulus. */
- /* initrd_start and size are setup by boot/head.S and kernel/head.S */
- if ( initrd_start )
- {
- if (initrd_end > *memory_end_p)
- {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end,*memory_end_p);
- initrd_start = 0;
- }
- }
-#endif
-#endif
-
-#ifdef notdef
- request_region(0x20,0x20,"pic1");
- request_region(0xa0,0x20,"pic2");
- request_region(0x00,0x20,"dma1");
- request_region(0x40,0x20,"timer");
- request_region(0x80,0x10,"dma page reg");
- request_region(0xc0,0x20,"dma2");
-#endif
-}
-
-void
-abort(void)
-{
-#ifdef CONFIG_XMON
- extern void xmon(void *);
- xmon(0);
-#endif
- machine_restart(NULL);
-}
-
-/* The decrementer counts at the system (internal) clock frequency divided by
- * sixteen, or external oscillator divided by four. Currently, we only
- * support the MBX, which is system clock divided by sixteen.
- */
-void __init mbx_calibrate_decr(void)
-{
- bd_t *binfo = (bd_t *)&res;
- int freq, fp, divisor;
-
- if ((((immap_t *)MBX_IMAP_ADDR)->im_clkrst.car_sccr & 0x02000000) == 0)
- printk("WARNING: Wrong decrementer source clock.\n");
-
- /* The manual says the frequency is in Hz, but it is really
- * as MHz. The value 'fp' is the number of decrementer ticks
- * per second.
- */
- fp = (binfo->bi_intfreq * 1000000) / 16;
- freq = fp*60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
-}
-
-/* A place holder for time base interrupts, if they are ever enabled.
-*/
-void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
-{
- printk("timebase_interrupt()\n");
-}
-
-/* The RTC on the MPC8xx is an internal register.
- * We want to protect this during power down, so we need to unlock,
- * modify, and re-lock.
- */
-static int
-mbx_set_rtc_time(unsigned long time)
-{
- ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
- ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc = time;
- ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
- return(0);
-}
-
-unsigned long __init mbx_get_rtc_time(void)
-{
- /* First, unlock all of the registers we are going to modify.
- * To protect them from corruption during power down, registers
- * that are maintained by keep alive power are "locked". To
- * modify these registers we have to write the key value to
- * the key location associated with the register.
- */
- ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
- ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
-
-
- /* Disable the RTC one second and alarm interrupts.
- */
- ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtcsc &=
- ~(RTCSC_SIE | RTCSC_ALE);
-
- /* Enabling the decrementer also enables the timebase interrupts
- * (or from the other point of view, to get decrementer interrupts
- * we have to enable the timebase). The decrementer interrupt
- * is wired into the vector table, nothing to do here for that.
- */
- ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_tbscr =
- ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
- (TBSCR_TBF | TBSCR_TBE));
- if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0)
- panic("Could not allocate timer IRQ!");
-
- /* Get time from the RTC.
- */
- return ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc;
-}
-
-void
-mbx_restart(char *cmd)
-{
- extern void MBX_gorom(void);
-
- MBX_gorom();
-}
-
-void
-mbx_power_off(void)
-{
- mbx_restart(NULL);
-}
-
-void
-mbx_halt(void)
-{
- mbx_restart(NULL)
-}
-
-
-int mbx_setup_residual(char *buffer)
-{
- int len = 0;
- bd_t *bp;
- extern RESIDUAL *res;
-
- bp = (bd_t *)res;
-
- len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
- "bus clock\t: %dMHz\n",
- bp->bi_intfreq /*/ 1000000*/,
- bp->bi_busfreq /*/ 1000000*/);
-
- return len;
-}
-
-void
-mbx_do_IRQ(struct pt_regs *regs,
- int cpu,
- int isfake)
-{
- int irq;
- unsigned long bits = 0;
-
- /* For MPC8xx, read the SIVEC register and shift the bits down
- * to get the irq number. */
- bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec;
- irq = bits >> 26;
- irq += ppc8xx_pic.irq_offset;
- bits = 1UL << irq;
-
- if (irq < 0) {
- printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
- irq, regs->nip);
- spurious_interrupts++;
- }
- else {
- ppc_irq_dispatch_handler( regs, irq );
- }
-
-}
-
-static void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int bits, irq;
-
- /* A bug in the QSpan chip causes it to give us 0xff always
- * when doing a character read. So read 32 bits and shift.
- * This doesn't seem to return useful values anyway, but
- * read it to make sure things are acked.
- * -- Cort
- */
- irq = (inl(0x508) >> 24)&0xff;
- if ( irq != 0xff ) printk("iack %d\n", irq);
-
- outb(0x0C, 0x20);
- irq = inb(0x20) & 7;
- if (irq == 2)
- {
- outb(0x0C, 0xA0);
- irq = inb(0xA0);
- irq = (irq&7) + 8;
- }
- bits = 1UL << irq;
- irq += i8259_pic.irq_offset;
- ppc_irq_dispatch_handler( regs, irq );
-}
-
-
-/* On MBX8xx, the interrupt control (SIEL) was set by EPPC-bug. External
- * interrupts can be either edge or level triggered, but there is no
- * reason for us to change the EPPC-bug values (it would not work if we did).
- */
-void __init
-mbx_init_IRQ(void)
-{
- int i;
-
- ppc8xx_pic.irq_offset = 16;
- for ( i = 16 ; i < 32 ; i++ )
- irq_desc[i].ctl = &ppc8xx_pic;
- unmask_irq(CPM_INTERRUPT);
-
- for ( i = 0 ; i < 16 ; i++ )
- irq_desc[i].ctl = &i8259_pic;
- i8259_init();
- request_irq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
- enable_irq(ISA_BRIDGE_INT);
-}
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-/*
- * IDE stuff.
- */
-void
-mbx_ide_insw(ide_ioreg_t port, void *buf, int ns)
-{
- ide_insw(port+_IO_BASE), buf, ns);
-}
-
-void
-mbx_ide_outsw(ide_ioreg_t port, void *buf, int ns)
-{
- ide_outsw(port+_IO_BASE, buf, ns);
-}
-
-int
-mbx_ide_default_irq(ide_ioreg_t base)
-{
- return 14;
-}
-
-ide_ioreg_t
-mbx_ide_default_io_base(int index)
-{
- return index;
-}
-
-int
-mbx_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
- return 0
-}
-
-void
-mbx_ide_request_region(ide_ioreg_t from,
- unsigned int extent,
- const char *name)
-{
-}
-
-void
-mbx_ide_release_region(ide_ioreg_t from,
- unsigned int extent)
-{
-}
-
-void
-mbx_ide_fix_driveid(struct hd_driveid *id)
-{
- ppc_generic_ide_fix_driveid(id);
-}
-
-void
-mbx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
-{
- ide_ioreg_t reg = data_port;
- int i;
-
- *irq = 0;
-
- if (data_port != 0) /* Only map the first ATA flash drive */
- return;
-
-#ifdef ATA_FLASH
-
- reg = (ide_ioreg_t) ioremap(PCMCIA_MEM_ADDR, 0x200);
-
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += 1;
- }
-
- /* Does not matter */
-
- if (ctrl_port) {
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
- } else {
- hw->io_ports[IDE_CONTROL_OFFSET] = reg;
- }
- if (irq)
- hw->irq = 13;
-#endif
-}
-#endif
-
-void __init
-mbx_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
-
- if ( r3 )
- memcpy( (void *)&res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
-
-#ifdef CONFIG_PCI
- mbx_setup_pci_ptrs();
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
- /* take care of initrd if we have one */
- if ( r4 )
- {
- initrd_start = r4 + KERNELBASE;
- initrd_end = r5 + KERNELBASE;
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
- /* take care of cmd line */
- if ( r6 )
- {
-
- *(char *)(r7+KERNELBASE) = 0;
- strcpy(cmd_line, (char *)(r6+KERNELBASE));
- }
-
- ppc_md.setup_arch = mbx_setup_arch;
- ppc_md.setup_residual = mbx_setup_residual;
- ppc_md.get_cpuinfo = NULL;
- ppc_md.irq_cannonicalize = NULL;
- ppc_md.init_IRQ = mbx_init_IRQ;
- ppc_md.do_IRQ = mbx_do_IRQ;
- ppc_md.init = NULL;
-
- ppc_md.restart = mbx_restart;
- ppc_md.power_off = mbx_power_off;
- ppc_md.halt = mbx_halt;
-
- ppc_md.time_init = NULL;
- ppc_md.set_rtc_time = mbx_set_rtc_time;
- ppc_md.get_rtc_time = mbx_get_rtc_time;
- ppc_md.calibrate_decr = mbx_calibrate_decr;
-
- ppc_md.kbd_setkeycode = pckbd_setkeycode;
- ppc_md.kbd_getkeycode = pckbd_getkeycode;
- ppc_md.kbd_translate = pckbd_translate;
- ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
- ppc_md.kbd_leds = pckbd_leds;
- ppc_md.kbd_init_hw = pckbd_init_hw;
-#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
-#endif
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
- ppc_ide_md.insw = mbx_ide_insw;
- ppc_ide_md.outsw = mbx_ide_outsw;
- ppc_ide_md.default_irq = mbx_ide_default_irq;
- ppc_ide_md.default_io_base = mbx_ide_default_io_base;
- ppc_ide_md.ide_check_region = mbx_ide_check_region;
- ppc_ide_md.ide_request_region = mbx_ide_request_region;
- ppc_ide_md.ide_release_region = mbx_ide_release_region;
- ppc_ide_md.fix_driveid = mbx_ide_fix_driveid;
- ppc_ide_md.ide_init_hwif = mbx_ide_init_hwif_ports;
-
- ppc_ide_md.io_base = _IO_BASE;
-#endif
-}
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 4b0375433..02e276729 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -64,14 +64,13 @@ struct hw_interrupt_type open_pic = {
if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri);
/*
- * Turned this check off since the IPI's are treated as irqs
- * but they're above NumSources -- Cort
- */
-#define check_arg_irq(irq)
-#if 0
- if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \
- printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);
-#endif
+ * I changed this to return to keep us from from trying to use irq #'s
+ * that we're using for IPI's.
+ * -- Cort
+ */
+#define check_arg_irq(irq) \
+ /*if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \
+ printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/
#define check_arg_cpu(cpu) \
if (cpu < 0 || cpu >= NumProcessors) \
printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu);
@@ -91,8 +90,7 @@ static void no_action(int ir1, void *dev, struct pt_regs *regs)
#ifdef __SMP__
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
{
-printk("openpic_ipi_action\n");
- smp_message_recv();
+ smp_message_recv(cpl-OPENPIC_VEC_IPI);
}
#endif /* __SMP__ */
@@ -213,6 +211,9 @@ void __init openpic_init(int main_pic)
/* Initialize external interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc);
+ /* SIOint (8259 cascade) is special */
+ openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
+ openpic_mapirq(0, 1<<0);
for (i = 1; i < NumSources; i++) {
/* Enabled, Priority 8 */
openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
@@ -226,9 +227,6 @@ void __init openpic_init(int main_pic)
openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
if ( _machine != _MACH_gemini )
{
- /* SIOint (8259 cascade) is special */
- openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
- openpic_mapirq(0, 1<<0);
if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT,
"82c59 cascade", NULL))
printk("Unable to get OpenPIC IRQ 0 for cascade\n");
@@ -366,6 +364,27 @@ void openpic_enable_IPI(u_int ipi)
}
/*
+ * Do per-cpu setup for SMP systems.
+ *
+ * Get IPI's working and start taking interrupts.
+ * -- Cort
+ */
+void do_openpic_setup_cpu(void)
+{
+ int i;
+
+ for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
+ openpic_enable_IPI(i);
+#if 0
+ /* let the openpic know we want intrs */
+ for ( i = 0; i < NumSources ; i++ )
+ openpic_mapirq(i, openpic_read(&OpenPIC->Source[i].Destination)
+ | (1<<smp_processor_id()) );
+#endif
+ openpic_set_priority(smp_processor_id(), 0);
+}
+
+/*
* Initialize a timer interrupt (and disable it)
*
* timer: OpenPIC timer number
@@ -397,13 +416,13 @@ void openpic_maptimer(u_int timer, u_int cpumask)
void openpic_enable_irq(u_int irq)
{
check_arg_irq(irq);
- openpic_clearfield(&OpenPIC->Source[irq-irq_desc[irq].ctl->irq_offset].Vector_Priority, OPENPIC_MASK);
+ openpic_clearfield(&OpenPIC->Source[irq-irq_desc[irq].handler->irq_offset].Vector_Priority, OPENPIC_MASK);
}
void openpic_disable_irq(u_int irq)
{
check_arg_irq(irq);
- openpic_setfield(&OpenPIC->Source[irq-irq_desc[irq].ctl->irq_offset].Vector_Priority, OPENPIC_MASK);
+ openpic_setfield(&OpenPIC->Source[irq-irq_desc[irq].handler->irq_offset].Vector_Priority, OPENPIC_MASK);
}
/*
diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h
index 1097c70bf..2673263cf 100644
--- a/arch/ppc/kernel/open_pic.h
+++ b/arch/ppc/kernel/open_pic.h
@@ -5,5 +5,6 @@ extern struct hw_interrupt_type open_pic;
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
void openpic_enable_IPI(u_int ipi);
+void do_openpic_setup_cpu(void);
#endif /* _PPC_KERNEL_OPEN_PIC_H */
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 054eee918..ec1ff3565 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -91,15 +91,17 @@ unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
return start;
}
-static void __init pcibios_claim_resources(struct pci_bus *bus)
+static void __init pcibios_claim_resources(struct list_head *bus_list)
{
+ struct list_head *ln, *dn;
+ struct pci_bus *bus;
struct pci_dev *dev;
int idx;
- while (bus)
- {
- for (dev=bus->devices; dev; dev=dev->sibling)
- {
+ for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
+ bus = pci_bus_b(ln);
+ for (dn=bus->devices.next; dn != &bus->devices; dn=dn->next) {
+ dev = pci_dev_b(dn);
for (idx = 0; idx < PCI_NUM_RESOURCES; idx++)
{
struct resource *r = &dev->resource[idx];
@@ -114,9 +116,7 @@ static void __init pcibios_claim_resources(struct pci_bus *bus)
}
}
}
- if (bus->children)
- pcibios_claim_resources(bus->children);
- bus = bus->next;
+ pcibios_claim_resources(&bus->children);
}
}
diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c
index a9166da34..75f8097fd 100644
--- a/arch/ppc/kernel/pmac_pci.c
+++ b/arch/ppc/kernel/pmac_pci.c
@@ -476,7 +476,7 @@ pmac_pcibios_fixup(void)
* honor the existence of multi-function devices where
* different functions have different interrupt pins. [mj]
*/
- for(dev=pci_devices; dev; dev=dev->next)
+ pci_for_each_dev(dev)
{
/*
* Open Firmware often doesn't initialize the,
diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c
index f7224f5dd..385e23327 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -135,7 +135,7 @@ static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
* don't. Put this here to check for it.
* -- Cort
*/
- if ( irq_desc[irq].ctl != &gatwick_pic )
+ if ( irq_desc[irq].handler != &gatwick_pic )
printk("gatwick irq not from gatwick pic\n");
else
ppc_irq_dispatch_handler( regs, irq );
@@ -159,7 +159,7 @@ pmac_do_IRQ(struct pt_regs *regs,
if (xmon_2nd)
xmon(regs);
#endif
- smp_message_recv();
+ pmac_smp_message_recv();
return -1;
}
@@ -361,7 +361,7 @@ pmac_pic_init(void)
max_irqs = 64;
}
for ( i = 0; i < max_real_irqs ; i++ )
- irq_desc[i].ctl = &pmac_pic;
+ irq_desc[i].handler = &pmac_pic;
/* get addresses of first controller */
if (irqctrler) {
@@ -401,7 +401,7 @@ pmac_pic_init(void)
if (device_is_compatible(irqctrler, "gatwick"))
pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
for ( i = max_real_irqs ; i < max_irqs ; i++ )
- irq_desc[i].ctl = &gatwick_pic;
+ irq_desc[i].handler = &gatwick_pic;
request_irq( second_irq, gatwick_action, SA_INTERRUPT,
"gatwick cascade", 0 );
}
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 4c3e9a790..72d23a934 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -198,32 +198,12 @@ pmac_get_cpuinfo(char *buffer)
#ifdef CONFIG_SCSI
/* Find the device number for the disk (if any) at target tgt
- on host adaptor host.
- XXX this really really should be in drivers/scsi/sd.c. */
+ on host adaptor host. We just need to get the prototype from
+ sd.h */
#include <linux/blkdev.h>
#include "../../../drivers/scsi/scsi.h"
#include "../../../drivers/scsi/sd.h"
-#include "../../../drivers/scsi/hosts.h"
-#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
-#define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8)
-#define SD_MINOR_NUMBER(i) ((i) & 255)
-#define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), SD_MINOR_NUMBER(i))
-#define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4)
-
-__init
-kdev_t sd_find_target(void *host, int tgt)
-{
- Scsi_Disk *dp;
- int i;
-#ifdef CONFIG_BLK_DEV_SD
- for (dp = rscsi_disks, i = 0; i < sd_template.dev_max; ++i, ++dp)
- if (dp->device != NULL && dp->device->host == host
- && dp->device->id == tgt)
- return MKDEV_SD(i);
-#endif /* CONFIG_BLK_DEV_SD */
- return 0;
-}
#endif
/*
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 11d2cd114..397685d43 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -9,6 +9,8 @@
#include <linux/vt_kern.h>
#include <linux/nvram.h>
#include <linux/spinlock.h>
+#include <linux/console.h>
+#include <linux/irq.h>
#include <asm/page.h>
#include <asm/semaphore.h>
@@ -269,3 +271,4 @@ void ppc_irq_dispatch_handler(struct pt_regs *, int);
EXPORT_SYMBOL(ppc_irq_dispatch_handler);
EXPORT_SYMBOL(decrementer_count);
EXPORT_SYMBOL(get_wchan);
+EXPORT_SYMBOL(console_drivers);
diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c
index a01962b12..633757875 100644
--- a/arch/ppc/kernel/prep_pci.c
+++ b/arch/ppc/kernel/prep_pci.c
@@ -998,7 +998,7 @@ prep_pcibios_fixup(void)
printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
if (OpenPIC) {
/* PCI interrupts are controlled by the OpenPIC */
- for(dev=pci_devices; dev; dev=dev->next) {
+ pci_for_each_dev(dev) {
if (dev->bus->number == 0) {
dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_PIN, dev->irq);
@@ -1007,8 +1007,7 @@ prep_pcibios_fixup(void)
return;
}
- for(dev=pci_devices; dev; dev=dev->next)
- {
+ pci_for_each_dev(dev) {
/*
* Use our old hard-coded kludge to figure out what
* irq this device uses. This is necessary on things
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index e7f62c429..19ae61450 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -617,12 +617,12 @@ prep_init_IRQ(void)
if (OpenPIC != NULL) {
for ( i = 16 ; i < 36 ; i++ )
- irq_desc[i].ctl = &open_pic;
+ irq_desc[i].handler = &open_pic;
openpic_init(1);
}
for ( i = 0 ; i < 16 ; i++ )
- irq_desc[i].ctl = &i8259_pic;
+ irq_desc[i].handler = &i8259_pic;
i8259_init();
#ifdef __SMP__
request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action,
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 403213883..64b171042 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -204,15 +204,6 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
prev->thread.vrsave )
giveup_altivec(prev);
- /*
- * The 750 doesn't broadcast invalidates with tlbie's
- * so flush every processor switch.
- * -- Cort
- */
- if ( ((_get_PVR()>>16) == 8) &&
- (new->last_processor != NO_PROC_ID) &&
- (new->last_processor != new->processor) && new->mm )
- flush_tlb_mm(new->mm);
prev->last_processor = prev->processor;
current_set[smp_processor_id()] = new;
#endif /* __SMP__ */
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index fad7c7c1d..c2891e21f 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -108,34 +108,8 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
}
}
-/*
- * Dirty hack to get smp message passing working.
- *
- * As it is now, if we're sending two message at the same time
- * we have race conditions. The PowerSurge doesn't easily
- * allow us to send IPI messages so we put the messages in
- * smp_message[].
- *
- * This is because don't have several IPI's on the PowerSurge even though
- * we do on the chrp. It would be nice to use the actual IPI's on the chrp
- * rather than this but having two methods of doing IPI isn't a good idea
- * right now.
- * -- Cort
- */
-int smp_message[NR_CPUS];
-void smp_message_recv(void)
+void smp_message_recv(int msg)
{
- int msg = smp_message[smp_processor_id()];
-
- if ( _machine == _MACH_Pmac )
- {
- /* clear interrupt */
- out_be32(PSURGE_INTR, ~0);
- }
-
- /* make sure msg is for us */
- if ( msg == -1 ) return;
-
ipi_count++;
switch( msg )
@@ -147,15 +121,54 @@ void smp_message_recv(void)
case MSG_RESCHEDULE:
current->need_resched = 1;
break;
- case 0xf0f0: /* syncing time bases - just return */
+ case MSG_INVALIDATE_TLB:
+ _tlbia();
+ case 0xf0f0: /* pmac syncing time bases - just return */
break;
default:
printk("SMP %d: smp_message_recv(): unknown msg %d\n",
smp_processor_id(), msg);
break;
}
- /* reset message */
- smp_message[smp_processor_id()] = -1;
+}
+
+/*
+ * As it is now, if we're sending two message at the same time
+ * we have race conditions on Pmac. The PowerSurge doesn't easily
+ * allow us to send IPI messages so we put the messages in
+ * smp_message[].
+ *
+ * This is because don't have several IPI's on the PowerSurge even though
+ * we do on the chrp. It would be nice to use actual IPI's such as with openpic
+ * rather than this.
+ * -- Cort
+ */
+int pmac_smp_message[NR_CPUS];
+void pmac_smp_message_recv(void)
+{
+ int msg = pmac_smp_message[smp_processor_id()];
+
+ /* clear interrupt */
+ out_be32(PSURGE_INTR, ~0);
+
+ /* make sure msg is for us */
+ if ( msg == -1 ) return;
+
+ smp_message_recv(msg);
+
+ /* reset message */
+ pmac_smp_message[smp_processor_id()] = -1;
+}
+
+/*
+ * 750's don't broadcast tlb invalidates so
+ * we have to emulate that behavior.
+ * -- Cort
+ */
+void smp_send_tlb_invalidate(int cpu)
+{
+ if ( (_get_PVR()>>16) == 8 )
+ smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0);
}
void smp_send_reschedule(int cpu)
@@ -169,6 +182,8 @@ void smp_send_reschedule(int cpu)
* as the timer).
* -- Cort
*/
+ /* This is only used if `cpu' is running an idle task,
+ so it will reschedule itself anyway... */
smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);
}
@@ -177,38 +192,39 @@ void smp_send_stop(void)
smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0);
}
-spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED;
void smp_message_pass(int target, int msg, unsigned long data, int wait)
{
int i;
- if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) )
+
+ if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) )
return;
- spin_lock(&mesg_pass_lock);
-
- /*
- * We assume here that the msg is not -1. If it is,
- * the recipient won't know the message was destined
- * for it. -- Cort
- */
-
- switch( target )
- {
- case MSG_ALL:
- smp_message[smp_processor_id()] = msg;
- /* fall through */
- case MSG_ALL_BUT_SELF:
- for ( i = 0 ; i < smp_num_cpus ; i++ )
- if ( i != smp_processor_id () )
- smp_message[i] = msg;
- break;
- default:
- smp_message[target] = msg;
- break;
- }
-
- if ( _machine == _MACH_Pmac )
- {
+ switch (_machine) {
+ case _MACH_Pmac:
+ /*
+ * IPI's on the Pmac are a hack but without reasonable
+ * IPI hardware SMP on Pmac is a hack.
+ *
+ * We assume here that the msg is not -1. If it is,
+ * the recipient won't know the message was destined
+ * for it. -- Cort
+ */
+ for ( i = 0; i <= smp_num_cpus ; i++ )
+ pmac_smp_message[i] = -1;
+ switch( target )
+ {
+ case MSG_ALL:
+ pmac_smp_message[smp_processor_id()] = msg;
+ /* fall through */
+ case MSG_ALL_BUT_SELF:
+ for ( i = 0 ; i < smp_num_cpus ; i++ )
+ if ( i != smp_processor_id () )
+ pmac_smp_message[i] = msg;
+ break;
+ default:
+ pmac_smp_message[target] = msg;
+ break;
+ }
/* interrupt secondary processor */
out_be32(PSURGE_INTR, ~0);
out_be32(PSURGE_INTR, 0);
@@ -218,40 +234,28 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
*/
/* interrupt primary */
/**(volatile unsigned long *)(0xf3019000);*/
- }
-
- if ( _machine == _MACH_chrp )
- {
- /*
- * There has to be some way of doing this better -
- * perhaps a send-to-all or send-to-all-but-self
- * in the openpic. This gets us going for now, though.
- * -- Cort
- */
+ break;
+ case _MACH_chrp:
+ case _MACH_prep:
+ case _MACH_gemini:
+ /* make sure we're sending something that translates to an IPI */
+ if ( msg > 0x3 )
+ break;
switch ( target )
{
case MSG_ALL:
- openpic_cause_IPI(smp_processor_id(), 0, 0x0 );
- openpic_cause_IPI(smp_processor_id(), 0, 0xffffffff );
+ openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff);
break;
case MSG_ALL_BUT_SELF:
- for ( i = 0 ; i < smp_num_cpus ; i++ )
- if ( i != smp_processor_id () )
- {
- openpic_cause_IPI(smp_processor_id(), 0,
- 0x0 );
- openpic_cause_IPI(smp_processor_id(), 0,
+ openpic_cause_IPI(smp_processor_id(), msg,
0xffffffff & ~(1 << smp_processor_id()));
- }
break;
default:
- openpic_cause_IPI(smp_processor_id(), 0, 0x0 );
- openpic_cause_IPI(target, 0, 1U << target );
+ openpic_cause_IPI(smp_processor_id(), msg, 1<<target);
break;
}
+ break;
}
-
- spin_unlock(&mesg_pass_lock);
}
void __init smp_boot_cpus(void)
@@ -387,6 +391,9 @@ void __init smp_boot_cpus(void)
}
}
+ if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+ do_openpic_setup_cpu();
+
if ( _machine == _MACH_Pmac )
{
/* reset the entry point so if we get another intr we won't
@@ -432,6 +439,13 @@ void __init smp_callin(void)
current->mm->mmap->vm_end = init_mm.mmap->vm_end;
#endif
cpu_callin_map[current->processor] = 1;
+ /*
+ * Each processor has to do this and this is the best
+ * place to stick it for now.
+ * -- Cort
+ */
+ if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+ do_openpic_setup_cpu();
while(!smp_commenced)
barrier();
__sti();