diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 11:32:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 11:32:34 -0700 |
commit | 3aa590c6b7c89d844f81c2e96f295cf2c6967773 (patch) | |
tree | 6f18b295b1ff4cd7fd1880db6f56721599d64439 /arch/powerpc/platforms | |
parent | 4d3ce21fa9d2eaeda113aa2f9c2da80d972bef64 (diff) | |
parent | 339d76c54336443f5050b00172beb675f35e3be0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (43 commits)
[POWERPC] Use little-endian bit from firmware ibm,pa-features property
[POWERPC] Make sure smp_processor_id works very early in boot
[POWERPC] U4 DART improvements
[POWERPC] todc: add support for Time-Of-Day-Clock
[POWERPC] Make lparcfg.c work when both iseries and pseries are selected
[POWERPC] Fix idr locking in init_new_context
[POWERPC] mpc7448hpc2 (taiga) board config file
[POWERPC] Add tsi108 pci and platform device data register function
[POWERPC] Add general support for mpc7448hpc2 (Taiga) platform
[POWERPC] Correct the MAX_CONTEXT definition
powerpc: minor cleanups for mpc86xx
[POWERPC] Make sure we select CONFIG_NEW_LEDS if ADB_PMU_LED is set
[POWERPC] Simplify the code defining the 64-bit CPU features
[POWERPC] powerpc: kconfig warning fix
[POWERPC] Consolidate some of kernel/misc*.S
[POWERPC] Remove unused function call_with_mmu_off
[POWERPC] update asm-powerpc/time.h
[POWERPC] Clean up it_lp_queue.h
[POWERPC] Skip the "copy down" of the kernel if it is already at zero.
[POWERPC] Add the use of the firmware soft-reset-nmi to kdump.
...
Diffstat (limited to 'arch/powerpc/platforms')
27 files changed, 620 insertions, 241 deletions
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 3a87863d287..d1ecc0f9ab5 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -7,6 +7,7 @@ choice config MPC8641_HPCN bool "Freescale MPC8641 HPCN" + select PPC_I8259 help This option enables support for the MPC8641 HPCN board. @@ -28,9 +29,4 @@ config PPC_INDIRECT_PCI_BE depends on PPC_86xx default y -config PPC_STD_MMU - bool - depends on PPC_86xx - default y - endmenu diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 7be796c5d5c..476a6eeee71 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -2,9 +2,6 @@ # Makefile for the PowerPC 86xx linux kernel. # - -ifeq ($(CONFIG_PPC_86xx),y) obj-$(CONFIG_SMP) += mpc86xx_smp.o -endif obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 5042253758b..5d2bcf78cef 100644 --- a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h @@ -14,7 +14,6 @@ #ifndef __MPC8641_HPCN_H__ #define __MPC8641_HPCN_H__ -#include <linux/config.h> #include <linux/init.h> /* PCI interrupt controller */ diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index e3c9e4f417d..2834462590b 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h @@ -15,11 +15,13 @@ * mpc86xx_* files. Mostly for use by mpc86xx_setup(). */ -extern int __init add_bridge(struct device_node *dev); +extern int add_bridge(struct device_node *dev); -extern void __init setup_indirect_pcie(struct pci_controller *hose, +extern int mpc86xx_exclude_device(u_char bus, u_char devfn); + +extern void setup_indirect_pcie(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data); -extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, +extern void setup_indirect_pcie_nomap(struct pci_controller *hose, void __iomem *cfg_addr, void __iomem *cfg_data); diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 483c21df181..ebae73eb006 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -12,7 +12,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -36,6 +35,7 @@ #include <sysdev/fsl_soc.h> #include "mpc86xx.h" +#include "mpc8641_hpcn.h" #ifndef CONFIG_PCI unsigned long isa_io_base = 0; @@ -186,17 +186,130 @@ mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; } +static void __devinit quirk_ali1575(struct pci_dev *dev) +{ + unsigned short temp; + + /* + * ALI1575 interrupts route table setup: + * + * IRQ pin IRQ# + * PIRQA ---- 3 + * PIRQB ---- 4 + * PIRQC ---- 5 + * PIRQD ---- 6 + * PIRQE ---- 9 + * PIRQF ---- 10 + * PIRQG ---- 11 + * PIRQH ---- 12 + * + * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD + * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA + */ + pci_write_config_dword(dev, 0x48, 0xb9317542); + + /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ + pci_write_config_byte(dev, 0x86, 0x0c); + + /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ + pci_write_config_byte(dev, 0x87, 0x0d); + + /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ + pci_write_config_byte(dev, 0x88, 0x0f); + + /* USB 2.0 controller, interrupt: PIRQ7 */ + pci_write_config_byte(dev, 0x74, 0x06); + + /* Audio controller, interrupt: PIRQE */ + pci_write_config_byte(dev, 0x8a, 0x0c); + + /* Modem controller, interrupt: PIRQF */ + pci_write_config_byte(dev, 0x8b, 0x0d); + + /* HD audio controller, interrupt: PIRQG */ + pci_write_config_byte(dev, 0x8c, 0x0e); + + /* Serial ATA interrupt: PIRQD */ + pci_write_config_byte(dev, 0x8d, 0x0b); + + /* SMB interrupt: PIRQH */ + pci_write_config_byte(dev, 0x8e, 0x0f); + + /* PMU ACPI SCI interrupt: PIRQH */ + pci_write_config_byte(dev, 0x8f, 0x0f); + + /* Primary PATA IDE IRQ: 14 + * Secondary PATA IDE IRQ: 15 + */ + pci_write_config_byte(dev, 0x44, 0x3d); + pci_write_config_byte(dev, 0x75, 0x0f); + + /* Set IRQ14 and IRQ15 to legacy IRQs */ + pci_read_config_word(dev, 0x46, &temp); + temp |= 0xc000; + pci_write_config_word(dev, 0x46, temp); + + /* Set i8259 interrupt trigger + * IRQ 3: Level + * IRQ 4: Level + * IRQ 5: Level + * IRQ 6: Level + * IRQ 7: Level + * IRQ 9: Level + * IRQ 10: Level + * IRQ 11: Level + * IRQ 12: Level + * IRQ 14: Edge + * IRQ 15: Edge + */ + outb(0xfa, 0x4d0); + outb(0x1e, 0x4d1); +} -int -mpc86xx_exclude_device(u_char bus, u_char devfn) +static void __devinit quirk_uli5288(struct pci_dev *dev) { -#if !defined(CONFIG_PCI) - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; -#endif + unsigned char c; + + pci_read_config_byte(dev,0x83,&c); + c |= 0x80; + pci_write_config_byte(dev, 0x83, c); + + pci_write_config_byte(dev, 0x09, 0x01); + pci_write_config_byte(dev, 0x0a, 0x06); + + pci_read_config_byte(dev,0x83,&c); + c &= 0x7f; + pci_write_config_byte(dev, 0x83, c); - return PCIBIOS_SUCCESSFUL; + pci_read_config_byte(dev,0x84,&c); + c |= 0x01; + pci_write_config_byte(dev, 0x84, c); } + +static void __devinit quirk_uli5229(struct pci_dev *dev) +{ + unsigned short temp; + pci_write_config_word(dev, 0x04, 0x0405); + pci_read_config_word(dev, 0x4a, &temp); + temp |= 0x1000; + pci_write_config_word(dev, 0x4a, temp); +} + +static void __devinit early_uli5249(struct pci_dev *dev) +{ + unsigned char temp; + pci_write_config_word(dev, 0x04, 0x0007); + pci_read_config_byte(dev, 0x7c, &temp); + pci_write_config_byte(dev, 0x7c, 0x80); + pci_write_config_byte(dev, 0x09, 0x01); + pci_write_config_byte(dev, 0x7c, temp); + dev->class |= 0x1; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); #endif /* CONFIG_PCI */ diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c index 944ec4b7141..bb7fb41933a 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> @@ -34,8 +33,8 @@ extern unsigned long __secondary_hold_acknowledge; static void __init smp_86xx_release_core(int nr) { - void *mcm_vaddr; - unsigned long vaddr, pcr; + __be32 __iomem *mcm_vaddr; + unsigned long pcr; if (nr < 0 || nr >= NR_CPUS) return; @@ -45,10 +44,9 @@ smp_86xx_release_core(int nr) */ mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, MPC86xx_MCM_SIZE); - vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; - pcr = in_be32((volatile unsigned *)vaddr); + pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2)); pcr |= 1 << (nr + 24); - out_be32((volatile unsigned *)vaddr, pcr); + out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr); } diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c index 5180df7c75b..bc513904311 100644 --- a/arch/powerpc/platforms/86xx/pci.c +++ b/arch/powerpc/platforms/86xx/pci.c @@ -12,7 +12,6 @@ * option) any later version. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/module.h> #include <linux/init.h> @@ -122,15 +121,12 @@ static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource static void __init mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) { - volatile struct ccsr_pex *pcie; u16 cmd; unsigned int temps; DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", pcie_offset, pcie_size); - pcie = ioremap(pcie_offset, pcie_size); - early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; @@ -144,6 +140,14 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); } +int mpc86xx_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + int __init add_bridge(struct device_node *dev) { int len; @@ -198,128 +202,3 @@ int __init add_bridge(struct device_node *dev) return 0; } - -static void __devinit quirk_ali1575(struct pci_dev *dev) -{ - unsigned short temp; - - /* - * ALI1575 interrupts route table setup: - * - * IRQ pin IRQ# - * PIRQA ---- 3 - * PIRQB ---- 4 - * PIRQC ---- 5 - * PIRQD ---- 6 - * PIRQE ---- 9 - * PIRQF ---- 10 - * PIRQG ---- 11 - * PIRQH ---- 12 - * - * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD - * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA - */ - pci_write_config_dword(dev, 0x48, 0xb9317542); - - /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x86, 0x0c); - - /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x87, 0x0d); - - /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ - pci_write_config_byte(dev, 0x88, 0x0f); - - /* USB 2.0 controller, interrupt: PIRQ7 */ - pci_write_config_byte(dev, 0x74, 0x06); - - /* Audio controller, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x8a, 0x0c); - - /* Modem controller, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x8b, 0x0d); - - /* HD audio controller, interrupt: PIRQG */ - pci_write_config_byte(dev, 0x8c, 0x0e); - - /* Serial ATA interrupt: PIRQD */ - pci_write_config_byte(dev, 0x8d, 0x0b); - - /* SMB interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8e, 0x0f); - - /* PMU ACPI SCI interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8f, 0x0f); - - /* Primary PATA IDE IRQ: 14 - * Secondary PATA IDE IRQ: 15 - */ - pci_write_config_byte(dev, 0x44, 0x3d); - pci_write_config_byte(dev, 0x75, 0x0f); - - /* Set IRQ14 and IRQ15 to legacy IRQs */ - pci_read_config_word(dev, 0x46, &temp); - temp |= 0xc000; - pci_write_config_word(dev, 0x46, temp); - - /* Set i8259 interrupt trigger - * IRQ 3: Level - * IRQ 4: Level - * IRQ 5: Level - * IRQ 6: Level - * IRQ 7: Level - * IRQ 9: Level - * IRQ 10: Level - * IRQ 11: Level - * IRQ 12: Level - * IRQ 14: Edge - * IRQ 15: Edge - */ - outb(0xfa, 0x4d0); - outb(0x1e, 0x4d1); -} - -static void __devinit quirk_uli5288(struct pci_dev *dev) -{ - unsigned char c; - - pci_read_config_byte(dev,0x83,&c); - c |= 0x80; - pci_write_config_byte(dev, 0x83, c); - - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x0a, 0x06); - - pci_read_config_byte(dev,0x83,&c); - c &= 0x7f; - pci_write_config_byte(dev, 0x83, c); - - pci_read_config_byte(dev,0x84,&c); - c |= 0x01; - pci_write_config_byte(dev, 0x84, c); -} - -static void __devinit quirk_uli5229(struct pci_dev *dev) -{ - unsigned short temp; - pci_write_config_word(dev, 0x04, 0x0405); - pci_read_config_word(dev, 0x4a, &temp); - temp |= 0x1000; - pci_write_config_word(dev, 0x4a, temp); -} - -static void __devinit early_uli5249(struct pci_dev *dev) -{ - unsigned char temp; - pci_write_config_word(dev, 0x04, 0x0007); - pci_read_config_byte(dev, 0x7c, &temp); - pci_write_config_byte(dev, 0x7c, 0x80); - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x7c, temp); - dev->class |= 0x1; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 29286369456..5cf46dc5789 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ obj-$(CONFIG_PPC_MAPLE) += maple/ obj-$(CONFIG_PPC_CELL) += cell/ +obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 352bbbacde9..0c8c7b6ab89 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -6,6 +6,7 @@ config SPU_FS default m depends on PPC_CELL select SPU_BASE + select MEMORY_HOTPLUG help The SPU file system is used to access Synergistic Processing Units on machines implementing the Broadband Processor @@ -18,7 +19,6 @@ config SPU_BASE config SPUFS_MMAP bool depends on SPU_FS && SPARSEMEM - select MEMORY_HOTPLUG default y config CBE_RAS diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 3d1831d331e..00d112f9227 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -125,8 +125,6 @@ static void __init cell_init_early(void) { DBG(" -> cell_init_early()\n"); - hpte_init_native(); - cell_init_iommu(); ppc64_interrupt_controller = IC_CELL_PIC; @@ -139,11 +137,17 @@ static int __init cell_probe(void) { unsigned long root = of_get_flat_dt_root(); - if (of_flat_dt_is_compatible(root, "IBM,CBEA") || - of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 1; + if (!of_flat_dt_is_compatible(root, "IBM,CBEA") && + !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + return 0; + +#ifdef CONFIG_UDBG_RTAS_CONSOLE + udbg_init_rtas_console(); +#endif + + hpte_init_native(); - return 0; + return 1; } /* diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index db82f503ba2..b306723abb8 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -168,12 +168,12 @@ spu_irq_class_0_bottom(struct spu *spu) stat &= mask; - if (stat & 1) /* invalid MFC DMA */ - __spu_trap_invalid_dma(spu); - - if (stat & 2) /* invalid DMA alignment */ + if (stat & 1) /* invalid DMA alignment */ __spu_trap_dma_align(spu); + if (stat & 2) /* invalid MFC DMA */ + __spu_trap_invalid_dma(spu); + if (stat & 4) /* error on SPU */ __spu_trap_error(spu); diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7854a380dce..58e794f9da1 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -204,7 +204,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_cntl_mmap_vmops; return 0; @@ -675,7 +675,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_signal1_mmap_vmops; return 0; @@ -762,7 +762,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) /* FIXME: */ vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_signal2_mmap_vmops; return 0; @@ -850,7 +850,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_mss_mmap_vmops; return 0; @@ -899,7 +899,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_mfc_mmap_vmops; return 0; diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index a656d810a44..c7fea2cca53 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -464,7 +464,8 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) * Poll MFC_CNTL[Ps] until value '11' is read * (purge complete). */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_PURGE_DMA_STATUS_MASK) == MFC_CNTL_PURGE_DMA_COMPLETE); } @@ -1028,7 +1029,8 @@ static inline void wait_suspend_mfc_complete(struct spu_state *csa, * Restore, Step 47. * Poll MFC_CNTL[Ss] until 11 is returned. */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == MFC_CNTL_SUSPEND_COMPLETE); } diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 4fdbc9ae876..ba07a9a7c03 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -74,6 +74,16 @@ config SANDPOINT Select SANDPOINT if configuring for a Motorola Sandpoint X3 (any flavor). +config MPC7448HPC2 + bool "Freescale MPC7448HPC2(Taiga)" + select TSI108_BRIDGE + select DEFAULT_UIMAGE + select PPC_UDBG_16550 + select MPIC + help + Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) + platform + config RADSTONE_PPC7D bool "Radstone Technology PPC7D board" select PPC_I8259 @@ -221,6 +231,11 @@ config MV64X60 select PPC_INDIRECT_PCI default y +config TSI108_BRIDGE + bool + depends on MPC7448HPC2 + default y + menu "Set bridge options" depends on MV64X60 diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile new file mode 100644 index 00000000000..fa499fe5929 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the 6xx/7xx/7xxxx linux kernel. +# +obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c new file mode 100644 index 00000000000..d7a4fc7ca23 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -0,0 +1,335 @@ +/* + * mpc7448_hpc2.c + * + * Board setup routines for the Freescale Taiga platform + * + * Author: Jacob Pan + * jacob.pan@freescale.com + * Author: Xianghua Xiao + * x.xiao@freescale.com + * Maintainer: Roy Zang <tie-fei.zang@freescale.com> + * Add Flat Device Tree support fot mpc7448hpc2 board + * + * Copyright 2004-2006 Freescale Semiconductor, Inc. + * + * This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/seq_file.h> +#include <linux/root_dev.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> + +#include <asm/system.h> +#include <asm/time.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <asm/tsi108.h> +#include <asm/pci-bridge.h> +#include <asm/reg.h> +#include <mm/mmu_decl.h> +#include "mpc7448_hpc2.h" +#include <asm/tsi108_irq.h> +#include <asm/mpic.h> + +#undef DEBUG +#ifdef DEBUG +#define DBG(fmt...) do { printk(fmt); } while(0) +#else +#define DBG(fmt...) do { } while(0) +#endif + +#ifndef CONFIG_PCI +isa_io_base = MPC7448_HPC2_ISA_IO_BASE; +isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; +pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; +#endif + +extern int tsi108_setup_pci(struct device_node *dev); +extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); +extern void tsi108_pci_int_init(void); +extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused); + +/* + * Define all of the IRQ senses and polarities. Taken from the + * mpc7448hpc manual. + * Note: Likely, this table and the following function should be + * obtained and derived from the OF Device Tree. + */ + +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = { + /* External on-board sources */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */ + /* Internal Tsi108/109 interrupt sources */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */ +}; + +int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +/* + * find pci slot by devfn in interrupt map of OF tree + */ +u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) +{ + int i; + unsigned int tmp; + for (i = 0; i < 4; i++){ + tmp = interrupt_map[i*4*7]; + if ((tmp >> 11) == (devfn >> 3)) + return i; + } + return i; +} + +/* + * Scans the interrupt map for pci device + */ +void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) +{ + struct pci_controller *hose; + struct device_node *node; + unsigned int *interrupt; + int busnr; + int len; + u8 slot; + u8 pin; + + /* Lookup the hose */ + busnr = dev->bus->number; + hose = pci_bus_to_hose(busnr); + if (!hose) + printk(KERN_ERR "No pci hose found\n"); + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + printk(KERN_ERR "No pci node found\n"); + + interrupt = (unsigned int *) get_property(node, "interrupt-map", &len); + slot = find_slot_by_devfn(interrupt, dev->devfn); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin == 0 || pin > 4) + pin = 1; + pin--; + dev->irq = interrupt[slot*4*7 + pin*7 + 5]; + DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); +} +/* temporary pci irq map fixup*/ + +void __init mpc7448_hpc2_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + for_each_pci_dev(dev) { + mpc7448_hpc2_fixup_irq(dev); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +static void __init mpc7448_hpc2_setup_arch(void) +{ + struct device_node *cpu; + struct device_node *np; + if (ppc_md.progress) + ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); + + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != 0) { + unsigned int *fp; + + fp = (int *)get_property(cpu, "clock-frequency", NULL); + if (fp != 0) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(cpu); + } + tsi108_csr_vir_base = get_vir_csrbase(); + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; +#endif + + /* setup PCI host bridge */ +#ifdef CONFIG_PCI + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) + tsi108_setup_pci(np); + + ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; + if (ppc_md.progress) + ppc_md.progress("tsi108: resources set", 0x100); +#endif + + printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n"); + printk(KERN_INFO + "Jointly ported by Freescale and Tundra Semiconductor\n"); + printk(KERN_INFO + "Enabling L2 cache then enabling the HID0 prefetch engine.\n"); +} + +/* + * Interrupt setup and service. Interrrupts on the mpc7448_hpc2 come + * from the four external INT pins, PCI interrupts are routed via + * PCI interrupt control registers, it generates internal IRQ23 + * + * Interrupt routing on the Taiga Board: + * TSI108:PB_INT[0] -> CPU0:INT# + * TSI108:PB_INT[1] -> CPU0:MCP# + * TSI108:PB_INT[2] -> N/C + * TSI108:PB_INT[3] -> N/C + */ +static void __init mpc7448_hpc2_init_IRQ(void) +{ + struct mpic *mpic; + phys_addr_t mpic_paddr = 0; + struct device_node *tsi_pic; + + tsi_pic = of_find_node_by_type(NULL, "open-pic"); + if (tsi_pic) { + unsigned int size; + void *prop = get_property(tsi_pic, "reg", &size); + mpic_paddr = of_translate_address(tsi_pic, prop); + } + + if (mpic_paddr == 0) { + printk("%s: No tsi108 PIC found !\n", __FUNCTION__); + return; + } + + DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, + (u32) mpic_paddr); + + mpic = mpic_alloc(mpic_paddr, + MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | + MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108), + 0, /* num_sources used */ + TSI108_IRQ_BASE, + 0, /* num_sources used */ + NR_IRQS - 4 /* XXXX */, + mpc7448_hpc2_pic_initsenses, + sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC"); + + BUG_ON(mpic == NULL); /* XXXX */ + + mpic_init(mpic); + mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic); + tsi108_pci_int_init(); + + /* Configure MPIC outputs to CPU0 */ + tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); +} + +void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); + seq_printf(m, "machine\t\t: MPC7448hpc2\n"); +} + +void mpc7448_hpc2_restart(char *cmd) +{ + local_irq_disable(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + for (;;) ; /* Spin until reset happens */ +} + +void mpc7448_hpc2_power_off(void) +{ + local_irq_disable(); + for (;;) ; /* No way to shut power off with software */ +} + +void mpc7448_hpc2_halt(void) +{ + mpc7448_hpc2_power_off(); +} + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init mpc7448_hpc2_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "mpc74xx")) + return 0; + return 1; +} + +static int mpc7448_machine_check_exception(struct pt_regs *regs) +{ + extern void tsi108_clear_pci_cfg_error(void); + const struct exception_table_entry *entry; + + /* Are we prepared to handle this fault */ + if ((entry = search_exception_tables(regs->nip)) != NULL) { + tsi108_clear_pci_cfg_error(); + regs->msr |= MSR_RI; + regs->nip = entry->fixup; + return 1; + } + return 0; + +} +define_machine(mpc7448_hpc2){ + .name = "MPC7448 HPC2", + .probe = mpc7448_hpc2_probe, + .setup_arch = mpc7448_hpc2_setup_arch, + .init_IRQ = mpc7448_hpc2_init_IRQ, + .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, + .get_irq = mpic_get_irq, + .pcibios_fixup = mpc7448_hpc2_pcibios_fixup, + .restart = mpc7448_hpc2_restart, + .calibrate_decr = generic_calibrate_decr, + .machine_check_exception= mpc7448_machine_check_exception, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h new file mode 100644 index 00000000000..a543a5242e3 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h @@ -0,0 +1,26 @@ +/* + * mpc7448_hpc2.h + * + * Definitions for Freescale MPC7448_HPC2 platform + * + * Author: Jacob Pan + * jacob.pan@freescale.com + * Maintainer: Roy Zang <roy.zang@freescale.com> + * + * 2006 (c) Freescale Semiconductor, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef __PPC_PLATFORMS_MPC7448_HPC2_H +#define __PPC_PLATFORMS_MPC7448_HPC2_H + +#include <asm/ppcboot.h> + +/* Base Addresses for the PCI bus + */ +#define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000) +#define MPC7448_HPC2_ISA_IO_BASE (0x00000000) +#define MPC7448_HPC2_ISA_MEM_BASE (0x00000000) +#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index d3444aabe76..d194140c1eb 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c @@ -252,6 +252,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) { char buf[16] = "IBM,"; + /* N.B. lparcfg.c knows about the "IBM," prefixes ... */ /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); @@ -264,6 +265,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) dt_prop_str(dt, "model", buf); dt_prop_str(dt, "compatible", "IBM,iSeries"); + dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); } static void __init dt_do_vdevice(struct iseries_flat_dt *dt, diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c index 30bdcf3925d..ed44dfceaa4 100644 --- a/arch/powerpc/platforms/iseries/htab.c +++ b/arch/powerpc/platforms/iseries/htab.c @@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, local_irq_restore(flags); } -void hpte_init_iSeries(void) +void __init hpte_init_iSeries(void) { ppc_md.hpte_invalidate = iSeries_hpte_invalidate; ppc_md.hpte_updatepp = iSeries_hpte_updatepp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_insert = iSeries_hpte_insert; ppc_md.hpte_remove = iSeries_hpte_remove; - - htab_finish_init(); } diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c index 8ca7b939635..2a9f81ea27d 100644 --- a/arch/powerpc/platforms/iseries/lpevents.c +++ b/arch/powerpc/platforms/iseries/lpevents.c @@ -51,20 +51,21 @@ static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; static struct HvLpEvent * get_next_hvlpevent(void) { struct HvLpEvent * event; - event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; if (hvlpevent_is_valid(event)) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + - LpEventAlign) / LpEventAlign) * LpEventAlign; + hvlpevent_queue.hq_current_event += ((event->xSizeMinus1 + + IT_LP_EVENT_ALIGN) / IT_LP_EVENT_ALIGN) * + IT_LP_EVENT_ALIGN; /* Wrap to beginning if no room at end */ - if (hvlpevent_queue.xSlicCurEventPtr > - hvlpevent_queue.xSlicLastValidEventPtr) { - hvlpevent_queue.xSlicCurEventPtr = - hvlpevent_queue.xSlicEventStackPtr; + if (hvlpevent_queue.hq_current_event > + hvlpevent_queue.hq_last_event) { + hvlpevent_queue.hq_current_event = + hvlpevent_queue.hq_event_stack; } } else { event = NULL; @@ -82,10 +83,10 @@ int hvlpevent_is_pending(void) if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + next_event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; return hvlpevent_is_valid(next_event) || - hvlpevent_queue.xPlicOverflowIntPending; + hvlpevent_queue.hq_overflow_pending; } static void hvlpevent_clear_valid(struct HvLpEvent * event) @@ -95,18 +96,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) * ie. on 64-byte boundaries. */ struct HvLpEvent *tmp; - unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / - LpEventAlign) - 1; + unsigned extra = ((event->xSizeMinus1 + IT_LP_EVENT_ALIGN) / + IT_LP_EVENT_ALIGN) - 1; switch (extra) { case 3: - tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 3 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); case 2: - tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 2 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); case 1: - tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 1 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); } @@ -120,7 +121,7 @@ void process_hvlpevents(struct pt_regs *regs) struct HvLpEvent * event; /* If we have recursed, just return */ - if (!spin_trylock(&hvlpevent_queue.lock)) + if (!spin_trylock(&hvlpevent_queue.hq_lock)) return; for (;;) { @@ -148,17 +149,17 @@ void process_hvlpevents(struct pt_regs *regs) printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); hvlpevent_clear_valid(event); - } else if (hvlpevent_queue.xPlicOverflowIntPending) + } else if (hvlpevent_queue.hq_overflow_pending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.hq_index); else break; } - spin_unlock(&hvlpevent_queue.lock); + spin_unlock(&hvlpevent_queue.hq_lock); } static int set_spread_lpevents(char *str) @@ -184,20 +185,20 @@ void setup_hvlpevent_queue(void) { void *eventStack; - spin_lock_init(&hvlpevent_queue.lock); + spin_lock_init(&hvlpevent_queue.hq_lock); /* Allocate a page for the Event Stack. */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); + eventStack = alloc_bootmem_pages(IT_LP_EVENT_STACK_SIZE); + memset(eventStack, 0, IT_LP_EVENT_STACK_SIZE); /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + HvCallEvent_setLpEventStack(0, eventStack, IT_LP_EVENT_STACK_SIZE); - hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; - hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; - hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - hvlpevent_queue.xIndex = 0; + hvlpevent_queue.hq_event_stack = eventStack; + hvlpevent_queue.hq_current_event = eventStack; + hvlpevent_queue.hq_last_event = (char *)eventStack + + (IT_LP_EVENT_STACK_SIZE - IT_LP_EVENT_MAX_SIZE); + hvlpevent_queue.hq_index = 0; } /* Register a handler for an LpEvent type */ diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c index e68b6b5fa89..c241413629a 100644 --- a/arch/powerpc/platforms/iseries/proc.c +++ b/arch/powerpc/platforms/iseries/proc.c @@ -24,7 +24,6 @@ #include <asm/processor.h> #include <asm/time.h> #include <asm/lppaca.h> -#include <asm/iseries/it_lp_queue.h> #include <asm/iseries/hv_call_xm.h> #include "processor_vpd.h" diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 617c724c459..66c77e4f8ec 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -81,8 +81,6 @@ static void iSeries_pci_final_fixup(void) { } #endif extern int rd_size; /* Defined in drivers/block/rd.c */ -extern unsigned long embedded_sysmap_start; -extern unsigned long embedded_sysmap_end; extern unsigned long iSeries_recal_tb; extern unsigned long iSeries_recal_titan; @@ -321,11 +319,6 @@ static void __init iSeries_init_early(void) iSeries_recal_titan = HvCallXm_loadTod(); /* - * Initialize the hash table management pointers - */ - hpte_init_iSeries(); - - /* * Initialize the DMA/TCE management */ iommu_init_early_iSeries(); @@ -563,16 +556,6 @@ static void __init iSeries_fixup_klimit(void) if (naca.xRamDisk) klimit = KERNELBASE + (u64)naca.xRamDisk + (naca.xRamDiskSize * HW_PAGE_SIZE); - else { - /* - * No ram disk was included - check and see if there - * was an embedded system map. Change klimit to take - * into account any embedded system map - */ - if (embedded_sysmap_end) - klimit = KERNELBASE + ((embedded_sysmap_end + 4095) & - 0xfffffffffffff000); - } } static int __init iSeries_src_init(void) @@ -683,6 +666,8 @@ static int __init iseries_probe(void) */ virt_irq_max = 255; + hpte_init_iSeries(); + return 1; } diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index a0505ea48a8..4e32a5417fd 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -199,11 +199,6 @@ static void __init maple_init_early(void) { DBG(" -> maple_init_early\n"); - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); - /* Setup interrupt mapping options */ ppc64_interrupt_controller = IC_OPEN_PIC; @@ -272,6 +267,8 @@ static int __init maple_probe(void) */ alloc_dart_table(); + hpte_init_native(); + return 1; } diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 9cc7db7a8bd..89c5775f83b 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -600,13 +600,6 @@ pmac_halt(void) */ static void __init pmac_init_early(void) { -#ifdef CONFIG_PPC64 - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); -#endif - /* Enable early btext debug if requested */ if (strstr(cmd_line, "btextdbg")) { udbg_adb_init_early(); @@ -683,6 +676,8 @@ static int __init pmac_probe(void) * part of the cacheable linar mapping */ alloc_dart_table(); + + hpte_init_native(); #endif #ifdef CONFIG_PPC32 diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index d03a8b078f9..8cfb5706790 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -92,6 +92,15 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) *(tcep++) = 0; } +static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) +{ + u64 *tcep; + + index <<= TCE_PAGE_FACTOR; + tcep = ((u64 *)tbl->it_base) + index; + + return *tcep; +} static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, @@ -235,6 +244,25 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n } } +static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) +{ + u64 rc; + unsigned long tce_ret; + + tcenum <<= TCE_PAGE_FACTOR; + rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); + + if (rc && printk_ratelimit()) { + printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", + rc); + printk("\tindex = 0x%lx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%lx\n", (u64)tcenum); + show_stack(current, (unsigned long *)__get_SP()); + } + + return tce_ret; +} + static void iommu_table_setparms(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl) @@ -254,7 +282,10 @@ static void iommu_table_setparms(struct pci_controller *phb, } tbl->it_base = (unsigned long)__va(*basep); + +#ifndef CONFIG_CRASH_DUMP memset((void *)tbl->it_base, 0, *sizep); +#endif tbl->it_busno = phb->bus->number; @@ -560,11 +591,13 @@ void iommu_init_early_pSeries(void) ppc_md.tce_build = tce_build_pSeriesLP; ppc_md.tce_free = tce_free_pSeriesLP; } + ppc_md.tce_get = tce_get_pSeriesLP; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; } else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; + ppc_md.tce_get = tce_get_pseries; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 634b7d06d3c..27480705996 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local) spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); } -void hpte_init_lpar(void) +void __init hpte_init_lpar(void) { ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; @@ -522,6 +522,4 @@ void hpte_init_lpar(void) ppc_md.hpte_remove = pSeries_lpar_hpte_remove; ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; - - htab_finish_init(); } diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 1e28518c612..b3197ff156c 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -322,11 +322,6 @@ static void __init pSeries_init_early(void) DBG(" -> pSeries_init_early()\n"); fw_feature_init(); - - if (firmware_has_feature(FW_FEATURE_LPAR)) - hpte_init_lpar(); - else - hpte_init_native(); if (firmware_has_feature(FW_FEATURE_LPAR)) find_udbg_vterm(); @@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas(unsigned long node, if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) powerpc_firmware_features |= FW_FEATURE_LPAR; + if (firmware_has_feature(FW_FEATURE_LPAR)) + hpte_init_lpar(); + else + hpte_init_native(); + return 1; } |