diff options
Diffstat (limited to 'arch/powerpc/platforms/pasemi')
-rw-r--r-- | arch/powerpc/platforms/pasemi/Kconfig | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/idle.c | 88 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/iommu.c | 281 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/pasemi.h | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/pci.c | 13 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/powersave.S | 80 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/setup.c | 105 |
8 files changed, 572 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig new file mode 100644 index 000000000000..68dc529dfd2f --- /dev/null +++ b/arch/powerpc/platforms/pasemi/Kconfig @@ -0,0 +1,10 @@ +menu "PA Semi PWRficient options" + depends on PPC_PASEMI + +config PPC_PASEMI_IOMMU + bool "PA Semi IOMMU support" + depends on PPC_PASEMI + help + IOMMU support for PA6T-1682M + +endmenu diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile index 1be1a993c5f5..e657ccae90a9 100644 --- a/arch/powerpc/platforms/pasemi/Makefile +++ b/arch/powerpc/platforms/pasemi/Makefile @@ -1 +1,2 @@ -obj-y += setup.o pci.o time.o +obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o + diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c new file mode 100644 index 000000000000..1ca3ff381591 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/idle.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006-2007 PA Semi, Inc + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#undef DEBUG + +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/machdep.h> +#include <asm/reg.h> + +#include "pasemi.h" + +struct sleep_mode { + char *name; + void (*entry)(void); +}; + +static struct sleep_mode modes[] = { + { .name = "spin", .entry = &idle_spin }, + { .name = "doze", .entry = &idle_doze }, +}; + +static int current_mode = 0; + +static int pasemi_system_reset_exception(struct pt_regs *regs) +{ + /* If we were woken up from power savings, we need to return + * to the calling function, since nip is not saved across + * all modes. + */ + + if (regs->msr & SRR1_WAKEMASK) + regs->nip = regs->link; + + switch (regs->msr & SRR1_WAKEMASK) { + case SRR1_WAKEEE: + do_IRQ(regs); + break; + case SRR1_WAKEDEC: + timer_interrupt(regs); + break; + default: + /* do system reset */ + return 0; + } + /* everything handled */ + regs->msr |= MSR_RI; + return 1; +} + +void __init pasemi_idle_init(void) +{ + ppc_md.system_reset_exception = pasemi_system_reset_exception; + ppc_md.power_save = modes[current_mode].entry; + printk(KERN_INFO "Using PA6T idle loop (%s)\n", modes[current_mode].name); +} + +static int __init idle_param(char *p) +{ + int i; + for (i = 0; i < sizeof(modes)/sizeof(struct sleep_mode); i++) { + if (!strcmp(modes[i].name, p)) { + current_mode = i; + break; + } + } + return 0; +} + +early_param("idle", idle_param); diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c new file mode 100644 index 000000000000..459a53b7d24d --- /dev/null +++ b/arch/powerpc/platforms/pasemi/iommu.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2005-2007, PA Semi, Inc + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#undef DEBUG + +#include <linux/types.h> +#include <linux/spinlock.h> +#include <linux/pci.h> +#include <asm/iommu.h> +#include <asm/machdep.h> +#include <asm/abs_addr.h> + + +#define IOBMAP_PAGE_SHIFT 12 +#define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT) +#define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1) + +#define IOBMAP_PAGE_FACTOR (PAGE_SHIFT - IOBMAP_PAGE_SHIFT) + +#define IOB_BASE 0xe0000000 +#define IOB_SIZE 0x3000 +/* Configuration registers */ +#define IOBCAP_REG 0x10 +#define IOBCOM_REG 0x40 +/* Enable IOB address translation */ +#define IOBCOM_ATEN 0x00000100 + +/* Address decode configuration register */ +#define IOB_AD_REG 0x53 +/* IOBCOM_AD_REG fields */ +#define IOB_AD_VGPRT 0x00000e00 +#define IOB_AD_VGAEN 0x00000100 +/* Direct mapping settings */ +#define IOB_AD_MPSEL_MASK 0x00000030 +#define IOB_AD_MPSEL_B38 0x00000000 +#define IOB_AD_MPSEL_B40 0x00000010 +#define IOB_AD_MPSEL_B42 0x00000020 +/* Translation window size / enable */ +#define IOB_AD_TRNG_MASK 0x00000003 +#define IOB_AD_TRNG_256M 0x00000000 +#define IOB_AD_TRNG_2G 0x00000001 +#define IOB_AD_TRNG_128G 0x00000003 + +#define IOB_TABLEBASE_REG 0x55 + +/* Base of the 64 4-byte L1 registers */ +#define IOB_XLT_L1_REGBASE 0xac0 + +/* Register to invalidate TLB entries */ +#define IOB_AT_INVAL_TLB_REG 0xb40 + +/* The top two bits of the level 1 entry contains valid and type flags */ +#define IOBMAP_L1E_V 0x40000000 +#define IOBMAP_L1E_V_B 0x80000000 + +/* For big page entries, the bottom two bits contains flags */ +#define IOBMAP_L1E_BIG_CACHED 0x00000002 +#define IOBMAP_L1E_BIG_PRIORITY 0x00000001 + +/* For regular level 2 entries, top 2 bits contain valid and cache flags */ +#define IOBMAP_L2E_V 0x80000000 +#define IOBMAP_L2E_V_CACHED 0xc0000000 + +static u32 *iob; +static u32 iob_l1_emptyval; +static u32 iob_l2_emptyval; +static u32 *iob_l2_base; + +static struct iommu_table iommu_table_iobmap; +static int iommu_table_iobmap_inited; + +static void iobmap_build(struct iommu_table *tbl, long index, + long npages, unsigned long uaddr, + enum dma_data_direction direction) +{ + u32 *ip; + u32 rpn; + unsigned long bus_addr; + + pr_debug("iobmap: build at: %lx, %lx, addr: %lx\n", index, npages, uaddr); + + bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; + + npages <<= IOBMAP_PAGE_FACTOR; + index <<= IOBMAP_PAGE_FACTOR; + + ip = ((u32 *)tbl->it_base) + index; + + while (npages--) { + rpn = virt_to_abs(uaddr) >> IOBMAP_PAGE_SHIFT; + + *(ip++) = IOBMAP_L2E_V | rpn; + /* invalidate tlb, can be optimized more */ + out_le32(iob+IOB_AT_INVAL_TLB_REG, bus_addr >> 14); + + uaddr += IOBMAP_PAGE_SIZE; + bus_addr += IOBMAP_PAGE_SIZE; + } +} + + +static void iobmap_free(struct iommu_table *tbl, long index, + long npages) +{ + u32 *ip; + unsigned long bus_addr; + + pr_debug("iobmap: free at: %lx, %lx\n", index, npages); + + bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; + + npages <<= IOBMAP_PAGE_FACTOR; + index <<= IOBMAP_PAGE_FACTOR; + + ip = ((u32 *)tbl->it_base) + index; + + while (npages--) { + *(ip++) = iob_l2_emptyval; + /* invalidate tlb, can be optimized more */ + out_le32(iob+IOB_AT_INVAL_TLB_REG, bus_addr >> 14); + bus_addr += IOBMAP_PAGE_SIZE; + } +} + + +static void iommu_table_iobmap_setup(void) +{ + pr_debug(" -> %s\n", __func__); + iommu_table_iobmap.it_busno = 0; + iommu_table_iobmap.it_offset = 0; + /* it_size is in number of entries */ + iommu_table_iobmap.it_size = 0x80000000 >> PAGE_SHIFT; + + /* Initialize the common IOMMU code */ + iommu_table_iobmap.it_base = (unsigned long)iob_l2_base; + iommu_table_iobmap.it_index = 0; + /* XXXOJN tune this to avoid IOB cache invals. + * Should probably be 8 (64 bytes) + */ + iommu_table_iobmap.it_blocksize = 4; + iommu_init_table(&iommu_table_iobmap, 0); + pr_debug(" <- %s\n", __func__); +} + + + +static void pci_dma_bus_setup_pasemi(struct pci_bus *bus) +{ + struct device_node *dn; + + pr_debug("pci_dma_bus_setup, bus %p, bus->self %p\n", bus, bus->self); + + if (!iommu_table_iobmap_inited) { + iommu_table_iobmap_inited = 1; + iommu_table_iobmap_setup(); + } + + dn = pci_bus_to_OF_node(bus); + + if (dn) + PCI_DN(dn)->iommu_table = &iommu_table_iobmap; + +} + + +static void pci_dma_dev_setup_pasemi(struct pci_dev *dev) +{ + pr_debug("pci_dma_dev_setup, dev %p (%s)\n", dev, pci_name(dev)); + + /* DMA device is untranslated, but all other PCI-e goes through + * the IOMMU + */ + if (dev->vendor == 0x1959 && dev->device == 0xa007) + dev->dev.archdata.dma_ops = &dma_direct_ops; + else + dev->dev.archdata.dma_data = &iommu_table_iobmap; +} + +static void pci_dma_bus_setup_null(struct pci_bus *b) { } +static void pci_dma_dev_setup_null(struct pci_dev *d) { } + +int iob_init(struct device_node *dn) +{ + unsigned long tmp; + u32 regword; + int i; + + pr_debug(" -> %s\n", __func__); + + /* Allocate a spare page to map all invalid IOTLB pages. */ + tmp = lmb_alloc(IOBMAP_PAGE_SIZE, IOBMAP_PAGE_SIZE); + if (!tmp) + panic("IOBMAP: Cannot allocate spare page!"); + /* Empty l1 is marked invalid */ + iob_l1_emptyval = 0; + /* Empty l2 is mapped to dummy page */ + iob_l2_emptyval = IOBMAP_L2E_V | (tmp >> IOBMAP_PAGE_SHIFT); + + iob = ioremap(IOB_BASE, IOB_SIZE); + if (!iob) + panic("IOBMAP: Cannot map registers!"); + + /* setup direct mapping of the L1 entries */ + for (i = 0; i < 64; i++) { + /* Each L1 covers 32MB, i.e. 8K entries = 32K of ram */ + regword = IOBMAP_L1E_V | (__pa(iob_l2_base + i*0x2000) >> 12); + out_le32(iob+IOB_XLT_L1_REGBASE+i, regword); + } + + /* set 2GB translation window, based at 0 */ + regword = in_le32(iob+IOB_AD_REG); + regword &= ~IOB_AD_TRNG_MASK; + regword |= IOB_AD_TRNG_2G; + out_le32(iob+IOB_AD_REG, regword); + + /* Enable translation */ + regword = in_le32(iob+IOBCOM_REG); + regword |= IOBCOM_ATEN; + out_le32(iob+IOBCOM_REG, regword); + + pr_debug(" <- %s\n", __func__); + + return 0; +} + + +/* These are called very early. */ +void iommu_init_early_pasemi(void) +{ + int iommu_off; + +#ifndef CONFIG_PPC_PASEMI_IOMMU + iommu_off = 1; +#else + iommu_off = of_chosen && + get_property(of_chosen, "linux,iommu-off", NULL); +#endif + if (iommu_off) { + /* Direct I/O, IOMMU off */ + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_null; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_null; + pci_dma_ops = &dma_direct_ops; + + return; + } + + iob_init(NULL); + + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pasemi; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pasemi; + ppc_md.tce_build = iobmap_build; + ppc_md.tce_free = iobmap_free; + pci_dma_ops = &dma_iommu_ops; +} + +void __init alloc_iobmap_l2(void) +{ +#ifndef CONFIG_PPC_PASEMI_IOMMU + return; +#endif + /* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */ + iob_l2_base = (u32 *)abs_to_virt(lmb_alloc_base(1UL<<21, 1UL<<21, 0x80000000)); + + printk(KERN_INFO "IOBMAP L2 allocated at: %p\n", iob_l2_base); +} diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h index 51c2a2397ecf..2d3927e6edb0 100644 --- a/arch/powerpc/platforms/pasemi/pasemi.h +++ b/arch/powerpc/platforms/pasemi/pasemi.h @@ -3,5 +3,17 @@ extern unsigned long pas_get_boot_time(void); extern void pas_pci_init(void); +extern void __devinit pas_pci_irq_fixup(struct pci_dev *dev); +extern void __devinit pas_pci_dma_dev_setup(struct pci_dev *dev); + +extern void __init alloc_iobmap_l2(void); + +extern void __init pasemi_idle_init(void); + +/* Power savings modes, implemented in asm */ +extern void idle_spin(void); +extern void idle_doze(void); + + #endif /* _PASEMI_PASEMI_H */ diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c index faa618e04047..7ecb2ba24db9 100644 --- a/arch/powerpc/platforms/pasemi/pci.c +++ b/arch/powerpc/platforms/pasemi/pci.c @@ -163,6 +163,19 @@ static void __init pas_fixup_phb_resources(void) } +void __devinit pas_pci_irq_fixup(struct pci_dev *dev) +{ + /* DMA is special, 84 interrupts (128 -> 211), all but 128 + * need to be mapped by hand here. + */ + if (dev->vendor == 0x1959 && dev->device == 0xa007) { + int i; + for (i = 129; i < 212; i++) + irq_create_mapping(NULL, i); + } +} + + void __init pas_pci_init(void) { struct device_node *np, *root; diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S new file mode 100644 index 000000000000..6d0fba6aab17 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/powersave.S @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006-2007 PA Semi, Inc + * + * Maintained by: Olof Johansson <olof@lixom.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <asm/processor.h> +#include <asm/page.h> +#include <asm/ppc_asm.h> +#include <asm/cputable.h> +#include <asm/cache.h> +#include <asm/thread_info.h> +#include <asm/asm-offsets.h> + +/* Power savings opcodes since not all binutils have them at this time */ +#define DOZE .long 0x4c000324 +#define NAP .long 0x4c000364 +#define SLEEP .long 0x4c0003a4 +#define RVW .long 0x4c0003e4 + +/* Common sequence to do before going to any of the + * powersavings modes. + */ + +#define PRE_SLEEP_SEQUENCE \ + std r3,8(r1); \ + ptesync ; \ + ld r3,8(r1); \ +1: cmpd r3,r3; \ + bne 1b + +_doze: + PRE_SLEEP_SEQUENCE + DOZE + b . + + +_GLOBAL(idle_spin) + blr + +_GLOBAL(idle_doze) + LOAD_REG_ADDR(r3, _doze) + b sleep_common + +/* Add more modes here later */ + +sleep_common: + mflr r0 + std r0, 16(r1) + stdu r1,-64(r1) + + LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) + mfmsr r4 + andc r5,r4,r6 + mtmsrd r5,0 + + mtctr r3 + bctrl + + mtmsrd r4,0 + + addi r1,r1,64 + ld r0,16(r1) + mtlr r0 + blr + diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index bea7d1bb1a3b..449cf1a08291 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 PA Semi, Inc + * Copyright (C) 2006-2007 PA Semi, Inc * * Authors: Kip Walker, PA Semi * Olof Johansson, PA Semi @@ -38,31 +38,46 @@ #include "pasemi.h" +static void __iomem *reset_reg; + static void pas_restart(char *cmd) { - printk("restart unimplemented, looping...\n"); - for (;;) ; + printk("Restarting...\n"); + while (1) + out_le32(reset_reg, 0x6000000); } -static void pas_power_off(void) +#ifdef CONFIG_SMP +static DEFINE_SPINLOCK(timebase_lock); + +static void __devinit pas_give_timebase(void) { - printk("power off unimplemented, looping...\n"); - for (;;) ; + unsigned long tb; + + spin_lock(&timebase_lock); + mtspr(SPRN_TBCTL, TBCTL_FREEZE); + tb = mftb(); + mtspr(SPRN_TBCTL, TBCTL_UPDATE_LOWER | (tb & 0xffffffff)); + mtspr(SPRN_TBCTL, TBCTL_UPDATE_UPPER | (tb >> 32)); + mtspr(SPRN_TBCTL, TBCTL_RESTART); + spin_unlock(&timebase_lock); + pr_debug("pas_give_timebase: cpu %d gave tb %lx\n", + smp_processor_id(), tb); } -static void pas_halt(void) +static void __devinit pas_take_timebase(void) { - pas_power_off(); + pr_debug("pas_take_timebase: cpu %d has tb %lx\n", + smp_processor_id(), mftb()); } -#ifdef CONFIG_SMP struct smp_ops_t pas_smp_ops = { .probe = smp_mpic_probe, .message_pass = smp_mpic_message_pass, .kick_cpu = smp_generic_kick_cpu, .setup_cpu = smp_mpic_setup_cpu, - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, + .give_timebase = pas_give_timebase, + .take_timebase = pas_take_timebase, }; #endif /* CONFIG_SMP */ @@ -72,9 +87,6 @@ void __init pas_setup_arch(void) /* Setup SMP callback */ smp_ops = &pas_smp_ops; #endif - /* no iommu yet */ - pci_dma_ops = &dma_direct_ops; - /* Lookup PCI hosts */ pas_pci_init(); @@ -82,7 +94,11 @@ void __init pas_setup_arch(void) conswitchp = &dummy_con; #endif - printk(KERN_DEBUG "Using default idle loop\n"); + /* Remap SDC register for doing reset */ + /* XXXOJN This should maybe come out of the device tree */ + reset_reg = ioremap(0xfc101100, 4); + + pasemi_idle_init(); } /* No legacy IO on our parts */ @@ -130,8 +146,9 @@ static __init void pas_init_IRQ(void) openpic_addr = of_read_number(opprop, naddr); printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); - mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0, - " PAS-OPIC "); + mpic = mpic_alloc(mpic_node, openpic_addr, + MPIC_PRIMARY|MPIC_LARGE_VECTORS, + 0, 0, " PAS-OPIC "); BUG_ON(!mpic); mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); @@ -146,6 +163,53 @@ static void __init pas_progress(char *s, unsigned short hex) } +static int pas_machine_check_handler(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + unsigned long srr0, srr1, dsisr; + + srr0 = regs->nip; + srr1 = regs->msr; + dsisr = mfspr(SPRN_DSISR); + printk(KERN_ERR "Machine Check on CPU %d\n", cpu); + printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1); + printk(KERN_ERR "DSISR 0x%016lx DAR 0x%016lx\n", dsisr, regs->dar); + printk(KERN_ERR "Cause:\n"); + + if (srr1 & 0x200000) + printk(KERN_ERR "Signalled by SDC\n"); + if (srr1 & 0x100000) { + printk(KERN_ERR "Load/Store detected error:\n"); + if (dsisr & 0x8000) + printk(KERN_ERR "D-cache ECC double-bit error or bus error\n"); + if (dsisr & 0x4000) + printk(KERN_ERR "LSU snoop response error\n"); + if (dsisr & 0x2000) + printk(KERN_ERR "MMU SLB multi-hit or invalid B field\n"); + if (dsisr & 0x1000) + printk(KERN_ERR "Recoverable Duptags\n"); + if (dsisr & 0x800) + printk(KERN_ERR "Recoverable D-cache parity error count overflow\n"); + if (dsisr & 0x400) + printk(KERN_ERR "TLB parity error count overflow\n"); + } + if (srr1 & 0x80000) + printk(KERN_ERR "Bus Error\n"); + if (srr1 & 0x40000) + printk(KERN_ERR "I-side SLB multiple hit\n"); + if (srr1 & 0x20000) + printk(KERN_ERR "I-cache parity error hit\n"); + + /* SRR1[62] is from MSR[62] if recoverable, so pass that back */ + return !!(srr1 & 0x2); +} + +static void __init pas_init_early(void) +{ + iommu_init_early_pasemi(); +} + + /* * Called very early, MMU is off, device-tree isn't unflattened */ @@ -158,6 +222,8 @@ static int __init pas_probe(void) hpte_init_native(); + alloc_iobmap_l2(); + return 1; } @@ -165,13 +231,14 @@ define_machine(pas) { .name = "PA Semi PA6T-1682M", .probe = pas_probe, .setup_arch = pas_setup_arch, + .init_early = pas_init_early, .init_IRQ = pas_init_IRQ, .get_irq = mpic_get_irq, .restart = pas_restart, - .power_off = pas_power_off, - .halt = pas_halt, .get_boot_time = pas_get_boot_time, .calibrate_decr = generic_calibrate_decr, .check_legacy_ioport = pas_check_legacy_ioport, .progress = pas_progress, + .machine_check_exception = pas_machine_check_handler, + .pci_irq_fixup = pas_pci_irq_fixup, }; |