diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-14 08:19:08 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-14 08:19:08 -0400 |
| commit | 905ec87e93bc9e01b15c60035cd6a50c636cbaef (patch) | |
| tree | 46fd7618d6511611ffc19eb0dd4d7bc6b90a41c2 /arch/ppc64 | |
| parent | 1d6ae775d7a948c9575658eb41184fd2e506c0df (diff) | |
| parent | 2f4ba45a75d6383b4a1201169a808ffea416ffa0 (diff) | |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'arch/ppc64')
54 files changed, 964 insertions, 488 deletions
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 8189953a372c..17d2c1eac3b8 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
| @@ -56,7 +56,7 @@ LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) | |||
| 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ | 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ |
| 57 | -mcall-aixdesc | 57 | -mcall-aixdesc |
| 58 | # Temporary hack until we have migrated to asm-powerpc | 58 | # Temporary hack until we have migrated to asm-powerpc |
| 59 | CPPFLAGS += -Iinclude3 | 59 | CPPFLAGS += -Iarch/$(ARCH)/include |
| 60 | 60 | ||
| 61 | GCC_VERSION := $(call cc-version) | 61 | GCC_VERSION := $(call cc-version) |
| 62 | GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) | 62 | GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) |
| @@ -89,11 +89,12 @@ drivers-$(CONFIG_OPROFILE) += arch/ppc64/oprofile/ | |||
| 89 | 89 | ||
| 90 | boot := arch/ppc64/boot | 90 | boot := arch/ppc64/boot |
| 91 | 91 | ||
| 92 | boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd | 92 | boottargets-$(CONFIG_PPC_PSERIES) += zImage zImage.initrd |
| 93 | boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd | 93 | boottargets-$(CONFIG_PPC_PMAC) += zImage.vmode zImage.initrd.vmode |
| 94 | boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm | 94 | boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd |
| 95 | boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd | 95 | boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm |
| 96 | $(boottarget-y): vmlinux | 96 | boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd |
| 97 | $(boottargets-y): vmlinux | ||
| 97 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | 98 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 98 | 99 | ||
| 99 | bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage | 100 | bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage |
| @@ -114,27 +115,21 @@ all: $(KBUILD_IMAGE) | |||
| 114 | 115 | ||
| 115 | archclean: | 116 | archclean: |
| 116 | $(Q)$(MAKE) $(clean)=$(boot) | 117 | $(Q)$(MAKE) $(clean)=$(boot) |
| 117 | $(Q)rm -rf include3 | 118 | # Temporary hack until we have migrated to asm-powerpc |
| 119 | $(Q)rm -rf arch/$(ARCH)/include | ||
| 118 | 120 | ||
| 119 | prepare: include/asm-ppc64/offsets.h | ||
| 120 | |||
| 121 | arch/ppc64/kernel/asm-offsets.s: include/asm include/linux/version.h \ | ||
| 122 | include/config/MARKER | ||
| 123 | |||
| 124 | include/asm-ppc64/offsets.h: arch/ppc64/kernel/asm-offsets.s | ||
| 125 | $(call filechk,gen-asm-offsets) | ||
| 126 | 121 | ||
| 127 | # Temporary hack until we have migrated to asm-powerpc | 122 | # Temporary hack until we have migrated to asm-powerpc |
| 128 | include/asm: include3/asm | 123 | include/asm: arch/$(ARCH)/include/asm |
| 129 | include3/asm: | 124 | arch/$(ARCH)/include/asm: |
| 130 | $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi; | 125 | $(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi |
| 131 | $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm | 126 | $(Q)ln -fsn $(srctree)/include/asm-powerpc arch/$(ARCH)/include/asm |
| 132 | 127 | ||
| 133 | define archhelp | 128 | define archhelp |
| 134 | echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' | 129 | echo ' zImage.vmode - Compressed kernel image (arch/$(ARCH)/boot/zImage.vmode)' |
| 135 | echo ' zImage.initrd- Compressed kernel image with initrd attached,' | 130 | echo ' zImage.initrd.vmode - Compressed kernel image with initrd attached,' |
| 136 | echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' | 131 | echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' |
| 137 | echo ' (arch/$(ARCH)/boot/zImage.initrd)' | 132 | echo ' (arch/$(ARCH)/boot/zImage.initrd.vmode)' |
| 133 | echo ' zImage - zImage for pSeries machines' | ||
| 134 | echo ' zImage.initrd - zImage with initrd for pSeries machines' | ||
| 138 | endef | 135 | endef |
| 139 | |||
| 140 | CLEAN_FILES += include/asm-ppc64/offsets.h | ||
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index 2c5f5e73d00c..33fdc8710891 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile | |||
| @@ -37,6 +37,9 @@ quiet_cmd_bootcc = BOOTCC $@ | |||
| 37 | quiet_cmd_bootas = BOOTAS $@ | 37 | quiet_cmd_bootas = BOOTAS $@ |
| 38 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< | 38 | cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< |
| 39 | 39 | ||
| 40 | quiet_cmd_bootld = BOOTLD $@ | ||
| 41 | cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) | ||
| 42 | |||
| 40 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c | 43 | $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c |
| 41 | $(call if_changed_dep,bootcc) | 44 | $(call if_changed_dep,bootcc) |
| 42 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S | 45 | $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S |
| @@ -53,7 +56,7 @@ src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) | |||
| 53 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) | 56 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) |
| 54 | 57 | ||
| 55 | hostprogs-y := addnote addRamDisk | 58 | hostprogs-y := addnote addRamDisk |
| 56 | targets += zImage zImage.initrd imagesize.c \ | 59 | targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \ |
| 57 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ | 60 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ |
| 58 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ | 61 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ |
| 59 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ | 62 | $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ |
| @@ -63,7 +66,7 @@ extra-y := initrd.o | |||
| 63 | quiet_cmd_ramdisk = RAMDISK $@ | 66 | quiet_cmd_ramdisk = RAMDISK $@ |
| 64 | cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ | 67 | cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ |
| 65 | 68 | ||
| 66 | quiet_cmd_stripvm = STRIP $@ | 69 | quiet_cmd_stripvm = STRIP $@ |
| 67 | cmd_stripvm = $(STRIP) -s $< -o $@ | 70 | cmd_stripvm = $(STRIP) -s $< -o $@ |
| 68 | 71 | ||
| 69 | vmlinux.strip: vmlinux FORCE | 72 | vmlinux.strip: vmlinux FORCE |
| @@ -71,12 +74,20 @@ vmlinux.strip: vmlinux FORCE | |||
| 71 | $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE | 74 | $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE |
| 72 | $(call if_changed,ramdisk) | 75 | $(call if_changed,ramdisk) |
| 73 | 76 | ||
| 74 | addsection = $(CROSS32OBJCOPY) $(1) \ | 77 | quiet_cmd_addsection = ADDSEC $@ |
| 75 | --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ | 78 | cmd_addsection = $(CROSS32OBJCOPY) $@ \ |
| 76 | --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) | 79 | --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ |
| 80 | --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) | ||
| 81 | |||
| 82 | quiet_cmd_imagesize = GENSIZE $@ | ||
| 83 | cmd_imagesize = ls -l vmlinux.strip | \ | ||
| 84 | awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \ | ||
| 85 | > $(obj)/imagesize.c && \ | ||
| 86 | $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ | ||
| 87 | awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c | ||
| 77 | 88 | ||
| 78 | quiet_cmd_addnote = ADDNOTE $@ | 89 | quiet_cmd_addnote = ADDNOTE $@ |
| 79 | cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ | 90 | cmd_addnote = $(obj)/addnote $@ |
| 80 | 91 | ||
| 81 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE | 92 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE |
| 82 | $(call if_changed,gzip) | 93 | $(call if_changed,gzip) |
| @@ -85,28 +96,30 @@ $(obj)/kernel-initrd.gz: $(obj)/ramdisk.image.gz | |||
| 85 | cp -f $(obj)/ramdisk.image.gz $@ | 96 | cp -f $(obj)/ramdisk.image.gz $@ |
| 86 | 97 | ||
| 87 | $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE | 98 | $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE |
| 88 | touch $@ | 99 | @touch $@ |
| 89 | 100 | ||
| 90 | $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE | 101 | $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE |
| 91 | $(call if_changed_dep,bootcc) | 102 | $(call if_changed_dep,bootcc) |
| 92 | $(call addsection, $@) | 103 | $(call cmd,addsection) |
| 104 | |||
| 105 | $(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) | ||
| 106 | $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE | ||
| 107 | $(call cmd,bootld,$(obj-boot)) | ||
| 108 | |||
| 109 | $(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) | ||
| 110 | $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE | ||
| 111 | $(call cmd,bootld,$(obj-boot)) | ||
| 93 | 112 | ||
| 94 | $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) | 113 | $(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE |
| 95 | $(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE | 114 | @cp -f $< $@ |
| 96 | $(call if_changed,addnote) | 115 | $(call if_changed,addnote) |
| 97 | 116 | ||
| 98 | $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) | 117 | $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE |
| 99 | $(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE | 118 | @cp -f $< $@ |
| 100 | $(call if_changed,addnote) | 119 | $(call if_changed,addnote) |
| 101 | 120 | ||
| 102 | $(obj)/imagesize.c: vmlinux.strip | 121 | $(obj)/imagesize.c: vmlinux.strip |
| 103 | @echo Generating $@ | 122 | $(call cmd,imagesize) |
| 104 | ls -l vmlinux.strip | \ | ||
| 105 | awk '{printf "/* generated -- do not edit! */\n" \ | ||
| 106 | "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c | ||
| 107 | $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ | ||
| 108 | awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \ | ||
| 109 | >> $(obj)/imagesize.c | ||
| 110 | 123 | ||
| 111 | install: $(CONFIGURE) $(BOOTIMAGE) | 124 | install: $(CONFIGURE) $(BOOTIMAGE) |
| 112 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" | 125 | sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" |
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 99e68cfbe688..f7ec19a2d0b0 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c | |||
| @@ -23,7 +23,8 @@ extern void flush_cache(void *, unsigned long); | |||
| 23 | 23 | ||
| 24 | /* Value picked to match that used by yaboot */ | 24 | /* Value picked to match that used by yaboot */ |
| 25 | #define PROG_START 0x01400000 | 25 | #define PROG_START 0x01400000 |
| 26 | #define RAM_END (256<<20) // Fixme: use OF */ | 26 | #define RAM_END (512<<20) // Fixme: use OF */ |
| 27 | #define ONE_MB 0x100000 | ||
| 27 | 28 | ||
| 28 | static char *avail_ram; | 29 | static char *avail_ram; |
| 29 | static char *begin_avail, *end_avail; | 30 | static char *begin_avail, *end_avail; |
| @@ -32,6 +33,7 @@ static unsigned int heap_use; | |||
| 32 | static unsigned int heap_max; | 33 | static unsigned int heap_max; |
| 33 | 34 | ||
| 34 | extern char _start[]; | 35 | extern char _start[]; |
| 36 | extern char _end[]; | ||
| 35 | extern char _vmlinux_start[]; | 37 | extern char _vmlinux_start[]; |
| 36 | extern char _vmlinux_end[]; | 38 | extern char _vmlinux_end[]; |
| 37 | extern char _initrd_start[]; | 39 | extern char _initrd_start[]; |
| @@ -58,13 +60,13 @@ typedef void (*kernel_entry_t)( unsigned long, | |||
| 58 | 60 | ||
| 59 | #undef DEBUG | 61 | #undef DEBUG |
| 60 | 62 | ||
| 61 | static unsigned long claim_base = PROG_START; | 63 | static unsigned long claim_base; |
| 62 | 64 | ||
| 63 | static unsigned long try_claim(unsigned long size) | 65 | static unsigned long try_claim(unsigned long size) |
| 64 | { | 66 | { |
| 65 | unsigned long addr = 0; | 67 | unsigned long addr = 0; |
| 66 | 68 | ||
| 67 | for(; claim_base < RAM_END; claim_base += 0x100000) { | 69 | for(; claim_base < RAM_END; claim_base += ONE_MB) { |
| 68 | #ifdef DEBUG | 70 | #ifdef DEBUG |
| 69 | printf(" trying: 0x%08lx\n\r", claim_base); | 71 | printf(" trying: 0x%08lx\n\r", claim_base); |
| 70 | #endif | 72 | #endif |
| @@ -95,7 +97,26 @@ void start(unsigned long a1, unsigned long a2, void *promptr) | |||
| 95 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | 97 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) |
| 96 | exit(); | 98 | exit(); |
| 97 | 99 | ||
| 98 | printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start); | 100 | printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) _start); |
| 101 | |||
| 102 | /* | ||
| 103 | * The first available claim_base must be above the end of the | ||
| 104 | * the loaded kernel wrapper file (_start to _end includes the | ||
| 105 | * initrd image if it is present) and rounded up to a nice | ||
| 106 | * 1 MB boundary for good measure. | ||
| 107 | */ | ||
| 108 | |||
| 109 | claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); | ||
| 110 | |||
| 111 | #if defined(PROG_START) | ||
| 112 | /* | ||
| 113 | * Maintain a "magic" minimum address. This keeps some older | ||
| 114 | * firmware platforms running. | ||
| 115 | */ | ||
| 116 | |||
| 117 | if (claim_base < PROG_START) | ||
| 118 | claim_base = PROG_START; | ||
| 119 | #endif | ||
| 99 | 120 | ||
| 100 | /* | 121 | /* |
| 101 | * Now we try to claim some memory for the kernel itself | 122 | * Now we try to claim some memory for the kernel itself |
| @@ -105,7 +126,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr) | |||
| 105 | * size... In practice we add 1Mb, that is enough, but we should really | 126 | * size... In practice we add 1Mb, that is enough, but we should really |
| 106 | * consider fixing the Makefile to put a _raw_ kernel in there ! | 127 | * consider fixing the Makefile to put a _raw_ kernel in there ! |
| 107 | */ | 128 | */ |
| 108 | vmlinux_memsize += 0x100000; | 129 | vmlinux_memsize += ONE_MB; |
| 109 | printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); | 130 | printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux_memsize); |
| 110 | vmlinux.addr = try_claim(vmlinux_memsize); | 131 | vmlinux.addr = try_claim(vmlinux_memsize); |
| 111 | if (vmlinux.addr == 0) { | 132 | if (vmlinux.addr == 0) { |
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c index c8f3dc3fad70..0aaa878e19d3 100644 --- a/arch/ppc64/kernel/bpa_iic.c +++ b/arch/ppc64/kernel/bpa_iic.c | |||
| @@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic(int cpu) | |||
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | #ifdef CONFIG_SMP | 207 | #ifdef CONFIG_SMP |
| 208 | |||
| 209 | /* Use the highest interrupt priorities for IPI */ | ||
| 210 | static inline int iic_ipi_to_irq(int ipi) | ||
| 211 | { | ||
| 212 | return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi; | ||
| 213 | } | ||
| 214 | |||
| 215 | static inline int iic_irq_to_ipi(int irq) | ||
| 216 | { | ||
| 217 | return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET); | ||
| 218 | } | ||
| 219 | |||
| 208 | void iic_setup_cpu(void) | 220 | void iic_setup_cpu(void) |
| 209 | { | 221 | { |
| 210 | out_be64(&__get_cpu_var(iic).regs->prio, 0xff); | 222 | out_be64(&__get_cpu_var(iic).regs->prio, 0xff); |
| @@ -212,18 +224,20 @@ void iic_setup_cpu(void) | |||
| 212 | 224 | ||
| 213 | void iic_cause_IPI(int cpu, int mesg) | 225 | void iic_cause_IPI(int cpu, int mesg) |
| 214 | { | 226 | { |
| 215 | out_be64(&per_cpu(iic, cpu).regs->generate, mesg); | 227 | out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); |
| 216 | } | 228 | } |
| 217 | 229 | ||
| 218 | static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) | 230 | static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) |
| 219 | { | 231 | { |
| 220 | 232 | smp_message_recv(iic_irq_to_ipi(irq), regs); | |
| 221 | smp_message_recv(irq - IIC_IPI_OFFSET, regs); | ||
| 222 | return IRQ_HANDLED; | 233 | return IRQ_HANDLED; |
| 223 | } | 234 | } |
| 224 | 235 | ||
| 225 | static void iic_request_ipi(int irq, const char *name) | 236 | static void iic_request_ipi(int ipi, const char *name) |
| 226 | { | 237 | { |
| 238 | int irq; | ||
| 239 | |||
| 240 | irq = iic_ipi_to_irq(ipi); | ||
| 227 | /* IPIs are marked SA_INTERRUPT as they must run with irqs | 241 | /* IPIs are marked SA_INTERRUPT as they must run with irqs |
| 228 | * disabled */ | 242 | * disabled */ |
| 229 | get_irq_desc(irq)->handler = &iic_pic; | 243 | get_irq_desc(irq)->handler = &iic_pic; |
| @@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, const char *name) | |||
| 233 | 247 | ||
| 234 | void iic_request_IPIs(void) | 248 | void iic_request_IPIs(void) |
| 235 | { | 249 | { |
| 236 | iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call"); | 250 | iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call"); |
| 237 | iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched"); | 251 | iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched"); |
| 238 | #ifdef CONFIG_DEBUGGER | 252 | #ifdef CONFIG_DEBUGGER |
| 239 | iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); | 253 | iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); |
| 240 | #endif /* CONFIG_DEBUGGER */ | 254 | #endif /* CONFIG_DEBUGGER */ |
| 241 | } | 255 | } |
| 242 | #endif /* CONFIG_SMP */ | 256 | #endif /* CONFIG_SMP */ |
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S index 0482c063c26e..1fb673c511ff 100644 --- a/arch/ppc64/kernel/cpu_setup_power4.S +++ b/arch/ppc64/kernel/cpu_setup_power4.S | |||
| @@ -12,10 +12,9 @@ | |||
| 12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
| 15 | #include <asm/ppc_asm.h> | ||
| 16 | #include <asm/cputable.h> | 15 | #include <asm/cputable.h> |
| 17 | #include <asm/ppc_asm.h> | 16 | #include <asm/ppc_asm.h> |
| 18 | #include <asm/offsets.h> | 17 | #include <asm/asm-offsets.h> |
| 19 | #include <asm/cache.h> | 18 | #include <asm/cache.h> |
| 20 | 19 | ||
| 21 | _GLOBAL(__970_cpu_preinit) | 20 | _GLOBAL(__970_cpu_preinit) |
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index af5272fedadf..ba93fd731222 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c | |||
| @@ -202,10 +202,9 @@ static void pci_addr_cache_print(struct pci_io_addr_cache *cache) | |||
| 202 | while (n) { | 202 | while (n) { |
| 203 | struct pci_io_addr_range *piar; | 203 | struct pci_io_addr_range *piar; |
| 204 | piar = rb_entry(n, struct pci_io_addr_range, rb_node); | 204 | piar = rb_entry(n, struct pci_io_addr_range, rb_node); |
| 205 | printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s %s\n", | 205 | printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n", |
| 206 | (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt, | 206 | (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt, |
| 207 | piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev), | 207 | piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev)); |
| 208 | pci_pretty_name(piar->pcidev)); | ||
| 209 | cnt++; | 208 | cnt++; |
| 210 | n = rb_next(n); | 209 | n = rb_next(n); |
| 211 | } | 210 | } |
| @@ -255,22 +254,24 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo, | |||
| 255 | static void __pci_addr_cache_insert_device(struct pci_dev *dev) | 254 | static void __pci_addr_cache_insert_device(struct pci_dev *dev) |
| 256 | { | 255 | { |
| 257 | struct device_node *dn; | 256 | struct device_node *dn; |
| 257 | struct pci_dn *pdn; | ||
| 258 | int i; | 258 | int i; |
| 259 | int inserted = 0; | 259 | int inserted = 0; |
| 260 | 260 | ||
| 261 | dn = pci_device_to_OF_node(dev); | 261 | dn = pci_device_to_OF_node(dev); |
| 262 | if (!dn) { | 262 | if (!dn) { |
| 263 | printk(KERN_WARNING "PCI: no pci dn found for dev=%s %s\n", | 263 | printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", |
| 264 | pci_name(dev), pci_pretty_name(dev)); | 264 | pci_name(dev)); |
| 265 | return; | 265 | return; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | /* Skip any devices for which EEH is not enabled. */ | 268 | /* Skip any devices for which EEH is not enabled. */ |
| 269 | if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || | 269 | pdn = dn->data; |
| 270 | dn->eeh_mode & EEH_MODE_NOCHECK) { | 270 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || |
| 271 | pdn->eeh_mode & EEH_MODE_NOCHECK) { | ||
| 271 | #ifdef DEBUG | 272 | #ifdef DEBUG |
| 272 | printk(KERN_INFO "PCI: skip building address cache for=%s %s\n", | 273 | printk(KERN_INFO "PCI: skip building address cache for=%s\n", |
| 273 | pci_name(dev), pci_pretty_name(dev)); | 274 | pci_name(dev)); |
| 274 | #endif | 275 | #endif |
| 275 | return; | 276 | return; |
| 276 | } | 277 | } |
| @@ -416,6 +417,7 @@ int eeh_unregister_notifier(struct notifier_block *nb) | |||
| 416 | static int read_slot_reset_state(struct device_node *dn, int rets[]) | 417 | static int read_slot_reset_state(struct device_node *dn, int rets[]) |
| 417 | { | 418 | { |
| 418 | int token, outputs; | 419 | int token, outputs; |
| 420 | struct pci_dn *pdn = dn->data; | ||
| 419 | 421 | ||
| 420 | if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { | 422 | if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { |
| 421 | token = ibm_read_slot_reset_state2; | 423 | token = ibm_read_slot_reset_state2; |
| @@ -425,8 +427,8 @@ static int read_slot_reset_state(struct device_node *dn, int rets[]) | |||
| 425 | outputs = 3; | 427 | outputs = 3; |
| 426 | } | 428 | } |
| 427 | 429 | ||
| 428 | return rtas_call(token, 3, outputs, rets, dn->eeh_config_addr, | 430 | return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr, |
| 429 | BUID_HI(dn->phb->buid), BUID_LO(dn->phb->buid)); | 431 | BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid)); |
| 430 | } | 432 | } |
| 431 | 433 | ||
| 432 | /** | 434 | /** |
| @@ -447,12 +449,12 @@ static void eeh_panic(struct pci_dev *dev, int reset_state) | |||
| 447 | * in light of potential corruption, we can use it here. | 449 | * in light of potential corruption, we can use it here. |
| 448 | */ | 450 | */ |
| 449 | if (panic_on_oops) | 451 | if (panic_on_oops) |
| 450 | panic("EEH: MMIO failure (%d) on device:%s %s\n", reset_state, | 452 | panic("EEH: MMIO failure (%d) on device:%s\n", reset_state, |
| 451 | pci_name(dev), pci_pretty_name(dev)); | 453 | pci_name(dev)); |
| 452 | else { | 454 | else { |
| 453 | __get_cpu_var(ignored_failures)++; | 455 | __get_cpu_var(ignored_failures)++; |
| 454 | printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s %s\n", | 456 | printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n", |
| 455 | reset_state, pci_name(dev), pci_pretty_name(dev)); | 457 | reset_state, pci_name(dev)); |
| 456 | } | 458 | } |
| 457 | } | 459 | } |
| 458 | 460 | ||
| @@ -482,8 +484,8 @@ static void eeh_event_handler(void *dummy) | |||
| 482 | break; | 484 | break; |
| 483 | 485 | ||
| 484 | printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device " | 486 | printk(KERN_INFO "EEH: MMIO failure (%d), notifiying device " |
| 485 | "%s %s\n", event->reset_state, | 487 | "%s\n", event->reset_state, |
| 486 | pci_name(event->dev), pci_pretty_name(event->dev)); | 488 | pci_name(event->dev)); |
| 487 | 489 | ||
| 488 | atomic_set(&eeh_fail_count, 0); | 490 | atomic_set(&eeh_fail_count, 0); |
| 489 | notifier_call_chain (&eeh_notifier_chain, | 491 | notifier_call_chain (&eeh_notifier_chain, |
| @@ -535,6 +537,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 535 | unsigned long flags; | 537 | unsigned long flags; |
| 536 | int rc, reset_state; | 538 | int rc, reset_state; |
| 537 | struct eeh_event *event; | 539 | struct eeh_event *event; |
| 540 | struct pci_dn *pdn; | ||
| 538 | 541 | ||
| 539 | __get_cpu_var(total_mmio_ffs)++; | 542 | __get_cpu_var(total_mmio_ffs)++; |
| 540 | 543 | ||
| @@ -543,14 +546,15 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 543 | 546 | ||
| 544 | if (!dn) | 547 | if (!dn) |
| 545 | return 0; | 548 | return 0; |
| 549 | pdn = dn->data; | ||
| 546 | 550 | ||
| 547 | /* Access to IO BARs might get this far and still not want checking. */ | 551 | /* Access to IO BARs might get this far and still not want checking. */ |
| 548 | if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || | 552 | if (!pdn->eeh_capable || !(pdn->eeh_mode & EEH_MODE_SUPPORTED) || |
| 549 | dn->eeh_mode & EEH_MODE_NOCHECK) { | 553 | pdn->eeh_mode & EEH_MODE_NOCHECK) { |
| 550 | return 0; | 554 | return 0; |
| 551 | } | 555 | } |
| 552 | 556 | ||
| 553 | if (!dn->eeh_config_addr) { | 557 | if (!pdn->eeh_config_addr) { |
| 554 | return 0; | 558 | return 0; |
| 555 | } | 559 | } |
| 556 | 560 | ||
| @@ -558,7 +562,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 558 | * If we already have a pending isolation event for this | 562 | * If we already have a pending isolation event for this |
| 559 | * slot, we know it's bad already, we don't need to check... | 563 | * slot, we know it's bad already, we don't need to check... |
| 560 | */ | 564 | */ |
| 561 | if (dn->eeh_mode & EEH_MODE_ISOLATED) { | 565 | if (pdn->eeh_mode & EEH_MODE_ISOLATED) { |
| 562 | atomic_inc(&eeh_fail_count); | 566 | atomic_inc(&eeh_fail_count); |
| 563 | if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { | 567 | if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { |
| 564 | /* re-read the slot reset state */ | 568 | /* re-read the slot reset state */ |
| @@ -583,7 +587,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 583 | } | 587 | } |
| 584 | 588 | ||
| 585 | /* prevent repeated reports of this failure */ | 589 | /* prevent repeated reports of this failure */ |
| 586 | dn->eeh_mode |= EEH_MODE_ISOLATED; | 590 | pdn->eeh_mode |= EEH_MODE_ISOLATED; |
| 587 | 591 | ||
| 588 | reset_state = rets[0]; | 592 | reset_state = rets[0]; |
| 589 | 593 | ||
| @@ -591,9 +595,9 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
| 591 | memset(slot_errbuf, 0, eeh_error_buf_size); | 595 | memset(slot_errbuf, 0, eeh_error_buf_size); |
| 592 | 596 | ||
| 593 | rc = rtas_call(ibm_slot_error_detail, | 597 | rc = rtas_call(ibm_slot_error_detail, |
| 594 | 8, 1, NULL, dn->eeh_config_addr, | 598 | 8, 1, NULL, pdn->eeh_config_addr, |
| 595 | BUID_HI(dn->phb->buid), | 599 | BUID_HI(pdn->phb->buid), |
| 596 | BUID_LO(dn->phb->buid), NULL, 0, | 600 | BUID_LO(pdn->phb->buid), NULL, 0, |
| 597 | virt_to_phys(slot_errbuf), | 601 | virt_to_phys(slot_errbuf), |
| 598 | eeh_error_buf_size, | 602 | eeh_error_buf_size, |
| 599 | 1 /* Temporary Error */); | 603 | 1 /* Temporary Error */); |
| @@ -680,8 +684,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 680 | u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); | 684 | u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); |
| 681 | u32 *regs; | 685 | u32 *regs; |
| 682 | int enable; | 686 | int enable; |
| 687 | struct pci_dn *pdn = dn->data; | ||
| 683 | 688 | ||
| 684 | dn->eeh_mode = 0; | 689 | pdn->eeh_mode = 0; |
| 685 | 690 | ||
| 686 | if (status && strcmp(status, "ok") != 0) | 691 | if (status && strcmp(status, "ok") != 0) |
| 687 | return NULL; /* ignore devices with bad status */ | 692 | return NULL; /* ignore devices with bad status */ |
| @@ -692,7 +697,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 692 | 697 | ||
| 693 | /* There is nothing to check on PCI to ISA bridges */ | 698 | /* There is nothing to check on PCI to ISA bridges */ |
| 694 | if (dn->type && !strcmp(dn->type, "isa")) { | 699 | if (dn->type && !strcmp(dn->type, "isa")) { |
| 695 | dn->eeh_mode |= EEH_MODE_NOCHECK; | 700 | pdn->eeh_mode |= EEH_MODE_NOCHECK; |
| 696 | return NULL; | 701 | return NULL; |
| 697 | } | 702 | } |
| 698 | 703 | ||
| @@ -709,7 +714,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 709 | enable = 0; | 714 | enable = 0; |
| 710 | 715 | ||
| 711 | if (!enable) | 716 | if (!enable) |
| 712 | dn->eeh_mode |= EEH_MODE_NOCHECK; | 717 | pdn->eeh_mode |= EEH_MODE_NOCHECK; |
| 713 | 718 | ||
| 714 | /* Ok... see if this device supports EEH. Some do, some don't, | 719 | /* Ok... see if this device supports EEH. Some do, some don't, |
| 715 | * and the only way to find out is to check each and every one. */ | 720 | * and the only way to find out is to check each and every one. */ |
| @@ -722,8 +727,8 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 722 | EEH_ENABLE); | 727 | EEH_ENABLE); |
| 723 | if (ret == 0) { | 728 | if (ret == 0) { |
| 724 | eeh_subsystem_enabled = 1; | 729 | eeh_subsystem_enabled = 1; |
| 725 | dn->eeh_mode |= EEH_MODE_SUPPORTED; | 730 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
| 726 | dn->eeh_config_addr = regs[0]; | 731 | pdn->eeh_config_addr = regs[0]; |
| 727 | #ifdef DEBUG | 732 | #ifdef DEBUG |
| 728 | printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); | 733 | printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name); |
| 729 | #endif | 734 | #endif |
| @@ -731,10 +736,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
| 731 | 736 | ||
| 732 | /* This device doesn't support EEH, but it may have an | 737 | /* This device doesn't support EEH, but it may have an |
| 733 | * EEH parent, in which case we mark it as supported. */ | 738 | * EEH parent, in which case we mark it as supported. */ |
| 734 | if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) { | 739 | if (dn->parent && dn->parent->data |
| 740 | && (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) { | ||
| 735 | /* Parent supports EEH. */ | 741 | /* Parent supports EEH. */ |
| 736 | dn->eeh_mode |= EEH_MODE_SUPPORTED; | 742 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
| 737 | dn->eeh_config_addr = dn->parent->eeh_config_addr; | 743 | pdn->eeh_config_addr = PCI_DN(dn->parent)->eeh_config_addr; |
| 738 | return NULL; | 744 | return NULL; |
| 739 | } | 745 | } |
| 740 | } | 746 | } |
| @@ -791,11 +797,13 @@ void __init eeh_init(void) | |||
| 791 | for (phb = of_find_node_by_name(NULL, "pci"); phb; | 797 | for (phb = of_find_node_by_name(NULL, "pci"); phb; |
| 792 | phb = of_find_node_by_name(phb, "pci")) { | 798 | phb = of_find_node_by_name(phb, "pci")) { |
| 793 | unsigned long buid; | 799 | unsigned long buid; |
| 800 | struct pci_dn *pci; | ||
| 794 | 801 | ||
| 795 | buid = get_phb_buid(phb); | 802 | buid = get_phb_buid(phb); |
| 796 | if (buid == 0) | 803 | if (buid == 0 || phb->data == NULL) |
| 797 | continue; | 804 | continue; |
| 798 | 805 | ||
| 806 | pci = phb->data; | ||
| 799 | info.buid_lo = BUID_LO(buid); | 807 | info.buid_lo = BUID_LO(buid); |
| 800 | info.buid_hi = BUID_HI(buid); | 808 | info.buid_hi = BUID_HI(buid); |
| 801 | traverse_pci_devices(phb, early_enable_eeh, &info); | 809 | traverse_pci_devices(phb, early_enable_eeh, &info); |
| @@ -824,9 +832,9 @@ void eeh_add_device_early(struct device_node *dn) | |||
| 824 | struct pci_controller *phb; | 832 | struct pci_controller *phb; |
| 825 | struct eeh_early_enable_info info; | 833 | struct eeh_early_enable_info info; |
| 826 | 834 | ||
| 827 | if (!dn) | 835 | if (!dn || !dn->data) |
| 828 | return; | 836 | return; |
| 829 | phb = dn->phb; | 837 | phb = PCI_DN(dn)->phb; |
| 830 | if (NULL == phb || 0 == phb->buid) { | 838 | if (NULL == phb || 0 == phb->buid) { |
| 831 | printk(KERN_WARNING "EEH: Expected buid but found none\n"); | 839 | printk(KERN_WARNING "EEH: Expected buid but found none\n"); |
| 832 | return; | 840 | return; |
| @@ -851,8 +859,7 @@ void eeh_add_device_late(struct pci_dev *dev) | |||
| 851 | return; | 859 | return; |
| 852 | 860 | ||
| 853 | #ifdef DEBUG | 861 | #ifdef DEBUG |
| 854 | printk(KERN_DEBUG "EEH: adding device %s %s\n", pci_name(dev), | 862 | printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev)); |
| 855 | pci_pretty_name(dev)); | ||
| 856 | #endif | 863 | #endif |
| 857 | 864 | ||
| 858 | pci_addr_cache_insert_device (dev); | 865 | pci_addr_cache_insert_device (dev); |
| @@ -873,8 +880,7 @@ void eeh_remove_device(struct pci_dev *dev) | |||
| 873 | 880 | ||
| 874 | /* Unregister the device with the EEH/PCI address search system */ | 881 | /* Unregister the device with the EEH/PCI address search system */ |
| 875 | #ifdef DEBUG | 882 | #ifdef DEBUG |
| 876 | printk(KERN_DEBUG "EEH: remove device %s %s\n", pci_name(dev), | 883 | printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); |
| 877 | pci_pretty_name(dev)); | ||
| 878 | #endif | 884 | #endif |
| 879 | pci_addr_cache_remove_device(dev); | 885 | pci_addr_cache_remove_device(dev); |
| 880 | } | 886 | } |
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index bf99b4a92f20..d133a49cdf89 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <asm/mmu.h> | 28 | #include <asm/mmu.h> |
| 29 | #include <asm/thread_info.h> | 29 | #include <asm/thread_info.h> |
| 30 | #include <asm/ppc_asm.h> | 30 | #include <asm/ppc_asm.h> |
| 31 | #include <asm/offsets.h> | 31 | #include <asm/asm-offsets.h> |
| 32 | #include <asm/cputable.h> | 32 | #include <asm/cputable.h> |
| 33 | 33 | ||
| 34 | #ifdef CONFIG_PPC_ISERIES | 34 | #ifdef CONFIG_PPC_ISERIES |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index b436206e317d..58c314738c99 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <asm/mmu.h> | 30 | #include <asm/mmu.h> |
| 31 | #include <asm/systemcfg.h> | 31 | #include <asm/systemcfg.h> |
| 32 | #include <asm/ppc_asm.h> | 32 | #include <asm/ppc_asm.h> |
| 33 | #include <asm/offsets.h> | 33 | #include <asm/asm-offsets.h> |
| 34 | #include <asm/bug.h> | 34 | #include <asm/bug.h> |
| 35 | #include <asm/cputable.h> | 35 | #include <asm/cputable.h> |
| 36 | #include <asm/setup.h> | 36 | #include <asm/setup.h> |
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c index d11c732daf81..5d921792571f 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/ppc64/kernel/iSeries_VpdInfo.c | |||
| @@ -264,8 +264,5 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) | |||
| 264 | printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", | 264 | printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", |
| 265 | count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, | 265 | count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, |
| 266 | frame, card); | 266 | frame, card); |
| 267 | if (pci_class_name(PciDev->class >> 8) == 0) | 267 | printk("0x%04X\n", (int)(PciDev->class >> 8)); |
| 268 | printk("0x%04X\n", (int)(PciDev->class >> 8)); | ||
| 269 | else | ||
| 270 | printk("%s\n", pci_class_name(PciDev->class >> 8)); | ||
| 271 | } | 268 | } |
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index 356e4fd9a94f..fbc273c32bcc 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c | |||
| @@ -252,7 +252,7 @@ unsigned long __init find_and_init_phbs(void) | |||
| 252 | phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL); | 252 | phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL); |
| 253 | if (phb == NULL) | 253 | if (phb == NULL) |
| 254 | return -ENOMEM; | 254 | return -ENOMEM; |
| 255 | pci_setup_pci_controller(phb); | 255 | pci_setup_pci_controller(phb); |
| 256 | 256 | ||
| 257 | phb->pci_mem_offset = phb->local_number = bus; | 257 | phb->pci_mem_offset = phb->local_number = bus; |
| 258 | phb->first_busno = bus; | 258 | phb->first_busno = bus; |
diff --git a/arch/ppc64/kernel/idle_power4.S b/arch/ppc64/kernel/idle_power4.S index 97e4a2655040..ca02afe2a795 100644 --- a/arch/ppc64/kernel/idle_power4.S +++ b/arch/ppc64/kernel/idle_power4.S | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
| 21 | #include <asm/thread_info.h> | 21 | #include <asm/thread_info.h> |
| 22 | #include <asm/ppc_asm.h> | 22 | #include <asm/ppc_asm.h> |
| 23 | #include <asm/offsets.h> | 23 | #include <asm/asm-offsets.h> |
| 24 | 24 | ||
| 25 | #undef DEBUG | 25 | #undef DEBUG |
| 26 | 26 | ||
diff --git a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c index 153cc8b0f136..6160c8dbb7c5 100644 --- a/arch/ppc64/kernel/iomap.c +++ b/arch/ppc64/kernel/iomap.c | |||
| @@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __iomem *addr) | |||
| 22 | { | 22 | { |
| 23 | return readw(addr); | 23 | return readw(addr); |
| 24 | } | 24 | } |
| 25 | unsigned int fastcall ioread16be(void __iomem *addr) | ||
| 26 | { | ||
| 27 | return in_be16(addr); | ||
| 28 | } | ||
| 25 | unsigned int fastcall ioread32(void __iomem *addr) | 29 | unsigned int fastcall ioread32(void __iomem *addr) |
| 26 | { | 30 | { |
| 27 | return readl(addr); | 31 | return readl(addr); |
| 28 | } | 32 | } |
| 33 | unsigned int fastcall ioread32be(void __iomem *addr) | ||
| 34 | { | ||
| 35 | return in_be32(addr); | ||
| 36 | } | ||
| 29 | EXPORT_SYMBOL(ioread8); | 37 | EXPORT_SYMBOL(ioread8); |
| 30 | EXPORT_SYMBOL(ioread16); | 38 | EXPORT_SYMBOL(ioread16); |
| 39 | EXPORT_SYMBOL(ioread16be); | ||
| 31 | EXPORT_SYMBOL(ioread32); | 40 | EXPORT_SYMBOL(ioread32); |
| 41 | EXPORT_SYMBOL(ioread32be); | ||
| 32 | 42 | ||
| 33 | void fastcall iowrite8(u8 val, void __iomem *addr) | 43 | void fastcall iowrite8(u8 val, void __iomem *addr) |
| 34 | { | 44 | { |
| @@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __iomem *addr) | |||
| 38 | { | 48 | { |
| 39 | writew(val, addr); | 49 | writew(val, addr); |
| 40 | } | 50 | } |
| 51 | void fastcall iowrite16be(u16 val, void __iomem *addr) | ||
| 52 | { | ||
| 53 | out_be16(addr, val); | ||
| 54 | } | ||
| 41 | void fastcall iowrite32(u32 val, void __iomem *addr) | 55 | void fastcall iowrite32(u32 val, void __iomem *addr) |
| 42 | { | 56 | { |
| 43 | writel(val, addr); | 57 | writel(val, addr); |
| 44 | } | 58 | } |
| 59 | void fastcall iowrite32be(u32 val, void __iomem *addr) | ||
| 60 | { | ||
| 61 | out_be32(addr, val); | ||
| 62 | } | ||
| 45 | EXPORT_SYMBOL(iowrite8); | 63 | EXPORT_SYMBOL(iowrite8); |
| 46 | EXPORT_SYMBOL(iowrite16); | 64 | EXPORT_SYMBOL(iowrite16); |
| 65 | EXPORT_SYMBOL(iowrite16be); | ||
| 47 | EXPORT_SYMBOL(iowrite32); | 66 | EXPORT_SYMBOL(iowrite32); |
| 67 | EXPORT_SYMBOL(iowrite32be); | ||
| 48 | 68 | ||
| 49 | /* | 69 | /* |
| 50 | * These are the "repeat read/write" functions. Note the | 70 | * These are the "repeat read/write" functions. Note the |
| @@ -56,15 +76,15 @@ EXPORT_SYMBOL(iowrite32); | |||
| 56 | */ | 76 | */ |
| 57 | void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) | 77 | void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) |
| 58 | { | 78 | { |
| 59 | _insb((u8 __force *) addr, dst, count); | 79 | _insb((u8 __iomem *) addr, dst, count); |
| 60 | } | 80 | } |
| 61 | void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) | 81 | void ioread16_rep(void __iomem *addr, void *dst, unsigned long count) |
| 62 | { | 82 | { |
| 63 | _insw_ns((u16 __force *) addr, dst, count); | 83 | _insw_ns((u16 __iomem *) addr, dst, count); |
| 64 | } | 84 | } |
| 65 | void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) | 85 | void ioread32_rep(void __iomem *addr, void *dst, unsigned long count) |
| 66 | { | 86 | { |
| 67 | _insl_ns((u32 __force *) addr, dst, count); | 87 | _insl_ns((u32 __iomem *) addr, dst, count); |
| 68 | } | 88 | } |
| 69 | EXPORT_SYMBOL(ioread8_rep); | 89 | EXPORT_SYMBOL(ioread8_rep); |
| 70 | EXPORT_SYMBOL(ioread16_rep); | 90 | EXPORT_SYMBOL(ioread16_rep); |
| @@ -72,15 +92,15 @@ EXPORT_SYMBOL(ioread32_rep); | |||
| 72 | 92 | ||
| 73 | void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) | 93 | void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) |
| 74 | { | 94 | { |
| 75 | _outsb((u8 __force *) addr, src, count); | 95 | _outsb((u8 __iomem *) addr, src, count); |
| 76 | } | 96 | } |
| 77 | void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) | 97 | void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) |
| 78 | { | 98 | { |
| 79 | _outsw_ns((u16 __force *) addr, src, count); | 99 | _outsw_ns((u16 __iomem *) addr, src, count); |
| 80 | } | 100 | } |
| 81 | void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) | 101 | void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) |
| 82 | { | 102 | { |
| 83 | _outsl_ns((u32 __force *) addr, src, count); | 103 | _outsl_ns((u32 __iomem *) addr, src, count); |
| 84 | } | 104 | } |
| 85 | EXPORT_SYMBOL(iowrite8_rep); | 105 | EXPORT_SYMBOL(iowrite8_rep); |
| 86 | EXPORT_SYMBOL(iowrite16_rep); | 106 | EXPORT_SYMBOL(iowrite16_rep); |
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c index 845eebd1e28d..9032b6bfe036 100644 --- a/arch/ppc64/kernel/iommu.c +++ b/arch/ppc64/kernel/iommu.c | |||
| @@ -438,7 +438,8 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl) | |||
| 438 | 438 | ||
| 439 | void iommu_free_table(struct device_node *dn) | 439 | void iommu_free_table(struct device_node *dn) |
| 440 | { | 440 | { |
| 441 | struct iommu_table *tbl = dn->iommu_table; | 441 | struct pci_dn *pdn = dn->data; |
| 442 | struct iommu_table *tbl = pdn->iommu_table; | ||
| 442 | unsigned long bitmap_sz, i; | 443 | unsigned long bitmap_sz, i; |
| 443 | unsigned int order; | 444 | unsigned int order; |
| 444 | 445 | ||
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c index 53993999b265..1d297e0edfc0 100644 --- a/arch/ppc64/kernel/maple_pci.c +++ b/arch/ppc64/kernel/maple_pci.c | |||
| @@ -283,7 +283,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) | |||
| 283 | * the reg address cell, we shall fix that by killing struct | 283 | * the reg address cell, we shall fix that by killing struct |
| 284 | * reg_property and using some accessor functions instead | 284 | * reg_property and using some accessor functions instead |
| 285 | */ | 285 | */ |
| 286 | hose->first_busno = 0xf0; | 286 | hose->first_busno = 0xf0; |
| 287 | hose->last_busno = 0xff; | 287 | hose->last_busno = 0xff; |
| 288 | hose->ops = &u3_agp_pci_ops; | 288 | hose->ops = &u3_agp_pci_ops; |
| 289 | hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); | 289 | hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); |
| @@ -315,24 +315,24 @@ static int __init add_bridge(struct device_node *dev) | |||
| 315 | char* disp_name; | 315 | char* disp_name; |
| 316 | int *bus_range; | 316 | int *bus_range; |
| 317 | int primary = 1; | 317 | int primary = 1; |
| 318 | struct property *of_prop; | 318 | struct property *of_prop; |
| 319 | 319 | ||
| 320 | DBG("Adding PCI host bridge %s\n", dev->full_name); | 320 | DBG("Adding PCI host bridge %s\n", dev->full_name); |
| 321 | 321 | ||
| 322 | bus_range = (int *) get_property(dev, "bus-range", &len); | 322 | bus_range = (int *) get_property(dev, "bus-range", &len); |
| 323 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 323 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
| 324 | printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", | 324 | printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", |
| 325 | dev->full_name); | 325 | dev->full_name); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | hose = alloc_bootmem(sizeof(struct pci_controller)); | 328 | hose = alloc_bootmem(sizeof(struct pci_controller)); |
| 329 | if (hose == NULL) | 329 | if (hose == NULL) |
| 330 | return -ENOMEM; | 330 | return -ENOMEM; |
| 331 | pci_setup_pci_controller(hose); | 331 | pci_setup_pci_controller(hose); |
| 332 | 332 | ||
| 333 | hose->arch_data = dev; | 333 | hose->arch_data = dev; |
| 334 | hose->first_busno = bus_range ? bus_range[0] : 0; | 334 | hose->first_busno = bus_range ? bus_range[0] : 0; |
| 335 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 335 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
| 336 | 336 | ||
| 337 | of_prop = alloc_bootmem(sizeof(struct property) + | 337 | of_prop = alloc_bootmem(sizeof(struct property) + |
| 338 | sizeof(hose->global_number)); | 338 | sizeof(hose->global_number)); |
| @@ -346,25 +346,25 @@ static int __init add_bridge(struct device_node *dev) | |||
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | disp_name = NULL; | 348 | disp_name = NULL; |
| 349 | if (device_is_compatible(dev, "u3-agp")) { | 349 | if (device_is_compatible(dev, "u3-agp")) { |
| 350 | setup_u3_agp(hose); | 350 | setup_u3_agp(hose); |
| 351 | disp_name = "U3-AGP"; | 351 | disp_name = "U3-AGP"; |
| 352 | primary = 0; | 352 | primary = 0; |
| 353 | } else if (device_is_compatible(dev, "u3-ht")) { | 353 | } else if (device_is_compatible(dev, "u3-ht")) { |
| 354 | setup_u3_ht(hose); | 354 | setup_u3_ht(hose); |
| 355 | disp_name = "U3-HT"; | 355 | disp_name = "U3-HT"; |
| 356 | primary = 1; | 356 | primary = 1; |
| 357 | } | 357 | } |
| 358 | printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", | 358 | printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", |
| 359 | disp_name, hose->first_busno, hose->last_busno); | 359 | disp_name, hose->first_busno, hose->last_busno); |
| 360 | 360 | ||
| 361 | /* Interpret the "ranges" property */ | 361 | /* Interpret the "ranges" property */ |
| 362 | /* This also maps the I/O region and sets isa_io/mem_base */ | 362 | /* This also maps the I/O region and sets isa_io/mem_base */ |
| 363 | pci_process_bridge_OF_ranges(hose, dev); | 363 | pci_process_bridge_OF_ranges(hose, dev); |
| 364 | pci_setup_phb_io(hose, primary); | 364 | pci_setup_phb_io(hose, primary); |
| 365 | 365 | ||
| 366 | /* Fixup "bus-range" OF property */ | 366 | /* Fixup "bus-range" OF property */ |
| 367 | fixup_bus_range(dev); | 367 | fixup_bus_range(dev); |
| 368 | 368 | ||
| 369 | return 0; | 369 | return 0; |
| 370 | } | 370 | } |
| @@ -447,9 +447,9 @@ void __init maple_pci_init(void) | |||
| 447 | */ | 447 | */ |
| 448 | if (u3_agp) { | 448 | if (u3_agp) { |
| 449 | struct device_node *np = u3_agp->arch_data; | 449 | struct device_node *np = u3_agp->arch_data; |
| 450 | np->busno = 0xf0; | 450 | PCI_DN(np)->busno = 0xf0; |
| 451 | for (np = np->child; np; np = np->sibling) | 451 | for (np = np->child; np; np = np->sibling) |
| 452 | np->busno = 0xf0; | 452 | PCI_DN(np)->busno = 0xf0; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | /* Tell pci.c to use the common resource allocation mecanism */ | 455 | /* Tell pci.c to use the common resource allocation mecanism */ |
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 6d860c1d9fa0..e7241ad80a08 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <asm/page.h> | 26 | #include <asm/page.h> |
| 27 | #include <asm/cache.h> | 27 | #include <asm/cache.h> |
| 28 | #include <asm/ppc_asm.h> | 28 | #include <asm/ppc_asm.h> |
| 29 | #include <asm/offsets.h> | 29 | #include <asm/asm-offsets.h> |
| 30 | #include <asm/cputable.h> | 30 | #include <asm/cputable.h> |
| 31 | 31 | ||
| 32 | .text | 32 | .text |
| @@ -1431,9 +1431,9 @@ _GLOBAL(sys_call_table) | |||
| 1431 | .llong .sys_ni_syscall /* 195 - 32bit only stat64 */ | 1431 | .llong .sys_ni_syscall /* 195 - 32bit only stat64 */ |
| 1432 | .llong .sys_ni_syscall /* 32bit only lstat64 */ | 1432 | .llong .sys_ni_syscall /* 32bit only lstat64 */ |
| 1433 | .llong .sys_ni_syscall /* 32bit only fstat64 */ | 1433 | .llong .sys_ni_syscall /* 32bit only fstat64 */ |
| 1434 | .llong .sys_ni_syscall /* 32bit only pciconfig_read */ | 1434 | .llong .sys_pciconfig_read |
| 1435 | .llong .sys_ni_syscall /* 32bit only pciconfig_write */ | 1435 | .llong .sys_pciconfig_write |
| 1436 | .llong .sys_ni_syscall /* 32bit only pciconfig_iobase */ | 1436 | .llong .sys_pciconfig_iobase /* 200 - pciconfig_iobase */ |
| 1437 | .llong .sys_ni_syscall /* reserved for MacOnLinux */ | 1437 | .llong .sys_ni_syscall /* reserved for MacOnLinux */ |
| 1438 | .llong .sys_getdents64 | 1438 | .llong .sys_getdents64 |
| 1439 | .llong .sys_pivot_root | 1439 | .llong .sys_pivot_root |
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 9d5e1e7fc389..f0fd7fbd6531 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c | |||
| @@ -295,7 +295,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, | |||
| 295 | struct iommu_table *tbl, | 295 | struct iommu_table *tbl, |
| 296 | unsigned int *dma_window) | 296 | unsigned int *dma_window) |
| 297 | { | 297 | { |
| 298 | tbl->it_busno = dn->bussubno; | 298 | tbl->it_busno = PCI_DN(dn)->bussubno; |
| 299 | 299 | ||
| 300 | /* TODO: Parse field size properties properly. */ | 300 | /* TODO: Parse field size properties properly. */ |
| 301 | tbl->it_size = (((unsigned long)dma_window[4] << 32) | | 301 | tbl->it_size = (((unsigned long)dma_window[4] << 32) | |
| @@ -311,6 +311,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, | |||
| 311 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) | 311 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) |
| 312 | { | 312 | { |
| 313 | struct device_node *dn, *pdn; | 313 | struct device_node *dn, *pdn; |
| 314 | struct pci_dn *pci; | ||
| 314 | struct iommu_table *tbl; | 315 | struct iommu_table *tbl; |
| 315 | 316 | ||
| 316 | DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); | 317 | DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); |
| @@ -325,6 +326,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
| 325 | */ | 326 | */ |
| 326 | 327 | ||
| 327 | dn = pci_bus_to_OF_node(bus); | 328 | dn = pci_bus_to_OF_node(bus); |
| 329 | pci = dn->data; | ||
| 328 | 330 | ||
| 329 | if (!bus->self) { | 331 | if (!bus->self) { |
| 330 | /* Root bus */ | 332 | /* Root bus */ |
| @@ -341,18 +343,18 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
| 341 | * alltogether. This leaves 768MB for the window. | 343 | * alltogether. This leaves 768MB for the window. |
| 342 | */ | 344 | */ |
| 343 | DBG("PHB has io-hole, reserving 256MB\n"); | 345 | DBG("PHB has io-hole, reserving 256MB\n"); |
| 344 | dn->phb->dma_window_size = 3 << 28; | 346 | pci->phb->dma_window_size = 3 << 28; |
| 345 | dn->phb->dma_window_base_cur = 1 << 28; | 347 | pci->phb->dma_window_base_cur = 1 << 28; |
| 346 | } else { | 348 | } else { |
| 347 | /* 1GB window by default */ | 349 | /* 1GB window by default */ |
| 348 | dn->phb->dma_window_size = 1 << 30; | 350 | pci->phb->dma_window_size = 1 << 30; |
| 349 | dn->phb->dma_window_base_cur = 0; | 351 | pci->phb->dma_window_base_cur = 0; |
| 350 | } | 352 | } |
| 351 | 353 | ||
| 352 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 354 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
| 353 | 355 | ||
| 354 | iommu_table_setparms(dn->phb, dn, tbl); | 356 | iommu_table_setparms(pci->phb, dn, tbl); |
| 355 | dn->iommu_table = iommu_init_table(tbl); | 357 | pci->iommu_table = iommu_init_table(tbl); |
| 356 | } else { | 358 | } else { |
| 357 | /* Do a 128MB table at root. This is used for the IDE | 359 | /* Do a 128MB table at root. This is used for the IDE |
| 358 | * controller on some SMP-mode POWER4 machines. It | 360 | * controller on some SMP-mode POWER4 machines. It |
| @@ -363,16 +365,16 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
| 363 | * Allocate at offset 128MB to avoid having to deal | 365 | * Allocate at offset 128MB to avoid having to deal |
| 364 | * with ISA holes; 128MB table for IDE is plenty. | 366 | * with ISA holes; 128MB table for IDE is plenty. |
| 365 | */ | 367 | */ |
| 366 | dn->phb->dma_window_size = 1 << 27; | 368 | pci->phb->dma_window_size = 1 << 27; |
| 367 | dn->phb->dma_window_base_cur = 1 << 27; | 369 | pci->phb->dma_window_base_cur = 1 << 27; |
| 368 | 370 | ||
| 369 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 371 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
| 370 | 372 | ||
| 371 | iommu_table_setparms(dn->phb, dn, tbl); | 373 | iommu_table_setparms(pci->phb, dn, tbl); |
| 372 | dn->iommu_table = iommu_init_table(tbl); | 374 | pci->iommu_table = iommu_init_table(tbl); |
| 373 | 375 | ||
| 374 | /* All child buses have 256MB tables */ | 376 | /* All child buses have 256MB tables */ |
| 375 | dn->phb->dma_window_size = 1 << 28; | 377 | pci->phb->dma_window_size = 1 << 28; |
| 376 | } | 378 | } |
| 377 | } else { | 379 | } else { |
| 378 | pdn = pci_bus_to_OF_node(bus->parent); | 380 | pdn = pci_bus_to_OF_node(bus->parent); |
| @@ -386,12 +388,12 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
| 386 | 388 | ||
| 387 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 389 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
| 388 | 390 | ||
| 389 | iommu_table_setparms(dn->phb, dn, tbl); | 391 | iommu_table_setparms(pci->phb, dn, tbl); |
| 390 | 392 | ||
| 391 | dn->iommu_table = iommu_init_table(tbl); | 393 | pci->iommu_table = iommu_init_table(tbl); |
| 392 | } else { | 394 | } else { |
| 393 | /* Lower than first child or under python, use parent table */ | 395 | /* Lower than first child or under python, use parent table */ |
| 394 | dn->iommu_table = pdn->iommu_table; | 396 | pci->iommu_table = PCI_DN(pdn)->iommu_table; |
| 395 | } | 397 | } |
| 396 | } | 398 | } |
| 397 | } | 399 | } |
| @@ -401,6 +403,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
| 401 | { | 403 | { |
| 402 | struct iommu_table *tbl; | 404 | struct iommu_table *tbl; |
| 403 | struct device_node *dn, *pdn; | 405 | struct device_node *dn, *pdn; |
| 406 | struct pci_dn *ppci; | ||
| 404 | unsigned int *dma_window = NULL; | 407 | unsigned int *dma_window = NULL; |
| 405 | 408 | ||
| 406 | DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); | 409 | DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); |
| @@ -419,22 +422,24 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
| 419 | return; | 422 | return; |
| 420 | } | 423 | } |
| 421 | 424 | ||
| 422 | if (!pdn->iommu_table) { | 425 | ppci = pdn->data; |
| 426 | if (!ppci->iommu_table) { | ||
| 423 | /* Bussubno hasn't been copied yet. | 427 | /* Bussubno hasn't been copied yet. |
| 424 | * Do it now because iommu_table_setparms_lpar needs it. | 428 | * Do it now because iommu_table_setparms_lpar needs it. |
| 425 | */ | 429 | */ |
| 426 | pdn->bussubno = bus->number; | 430 | |
| 431 | ppci->bussubno = bus->number; | ||
| 427 | 432 | ||
| 428 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), | 433 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), |
| 429 | GFP_KERNEL); | 434 | GFP_KERNEL); |
| 430 | 435 | ||
| 431 | iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); | 436 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); |
| 432 | 437 | ||
| 433 | pdn->iommu_table = iommu_init_table(tbl); | 438 | ppci->iommu_table = iommu_init_table(tbl); |
| 434 | } | 439 | } |
| 435 | 440 | ||
| 436 | if (pdn != dn) | 441 | if (pdn != dn) |
| 437 | dn->iommu_table = pdn->iommu_table; | 442 | PCI_DN(dn)->iommu_table = ppci->iommu_table; |
| 438 | } | 443 | } |
| 439 | 444 | ||
| 440 | 445 | ||
| @@ -449,11 +454,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) | |||
| 449 | */ | 454 | */ |
| 450 | mydn = dn = pci_device_to_OF_node(dev); | 455 | mydn = dn = pci_device_to_OF_node(dev); |
| 451 | 456 | ||
| 452 | while (dn && dn->iommu_table == NULL) | 457 | while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL) |
| 453 | dn = dn->parent; | 458 | dn = dn->parent; |
| 454 | 459 | ||
| 455 | if (dn) { | 460 | if (dn && dn->data) { |
| 456 | mydn->iommu_table = dn->iommu_table; | 461 | PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; |
| 457 | } else { | 462 | } else { |
| 458 | DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); | 463 | DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); |
| 459 | } | 464 | } |
| @@ -463,10 +468,11 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti | |||
| 463 | { | 468 | { |
| 464 | int err = NOTIFY_OK; | 469 | int err = NOTIFY_OK; |
| 465 | struct device_node *np = node; | 470 | struct device_node *np = node; |
| 471 | struct pci_dn *pci = np->data; | ||
| 466 | 472 | ||
| 467 | switch (action) { | 473 | switch (action) { |
| 468 | case PSERIES_RECONFIG_REMOVE: | 474 | case PSERIES_RECONFIG_REMOVE: |
| 469 | if (np->iommu_table && | 475 | if (pci->iommu_table && |
| 470 | get_property(np, "ibm,dma-window", NULL)) | 476 | get_property(np, "ibm,dma-window", NULL)) |
| 471 | iommu_free_table(np); | 477 | iommu_free_table(np); |
| 472 | break; | 478 | break; |
| @@ -486,6 +492,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
| 486 | struct device_node *pdn, *dn; | 492 | struct device_node *pdn, *dn; |
| 487 | struct iommu_table *tbl; | 493 | struct iommu_table *tbl; |
| 488 | int *dma_window = NULL; | 494 | int *dma_window = NULL; |
| 495 | struct pci_dn *pci; | ||
| 489 | 496 | ||
| 490 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); | 497 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); |
| 491 | 498 | ||
| @@ -497,8 +504,10 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
| 497 | */ | 504 | */ |
| 498 | dn = pci_device_to_OF_node(dev); | 505 | dn = pci_device_to_OF_node(dev); |
| 499 | 506 | ||
| 500 | for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) { | 507 | for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table; |
| 501 | dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); | 508 | pdn = pdn->parent) { |
| 509 | dma_window = (unsigned int *) | ||
| 510 | get_property(pdn, "ibm,dma-window", NULL); | ||
| 502 | if (dma_window) | 511 | if (dma_window) |
| 503 | break; | 512 | break; |
| 504 | } | 513 | } |
| @@ -515,20 +524,21 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
| 515 | DBG("Found DMA window, allocating table\n"); | 524 | DBG("Found DMA window, allocating table\n"); |
| 516 | } | 525 | } |
| 517 | 526 | ||
| 518 | if (!pdn->iommu_table) { | 527 | pci = pdn->data; |
| 528 | if (!pci->iommu_table) { | ||
| 519 | /* iommu_table_setparms_lpar needs bussubno. */ | 529 | /* iommu_table_setparms_lpar needs bussubno. */ |
| 520 | pdn->bussubno = pdn->phb->bus->number; | 530 | pci->bussubno = pci->phb->bus->number; |
| 521 | 531 | ||
| 522 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), | 532 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), |
| 523 | GFP_KERNEL); | 533 | GFP_KERNEL); |
| 524 | 534 | ||
| 525 | iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); | 535 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); |
| 526 | 536 | ||
| 527 | pdn->iommu_table = iommu_init_table(tbl); | 537 | pci->iommu_table = iommu_init_table(tbl); |
| 528 | } | 538 | } |
| 529 | 539 | ||
| 530 | if (pdn != dn) | 540 | if (pdn != dn) |
| 531 | dn->iommu_table = pdn->iommu_table; | 541 | PCI_DN(dn)->iommu_table = pci->iommu_table; |
| 532 | } | 542 | } |
| 533 | 543 | ||
| 534 | static void iommu_bus_setup_null(struct pci_bus *b) { } | 544 | static void iommu_bus_setup_null(struct pci_bus *b) { } |
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index 9490b6c5b173..bfadccc7b8be 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c | |||
| @@ -590,6 +590,13 @@ static int pseries_shared_idle(void) | |||
| 590 | return 0; | 590 | return 0; |
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | static int pSeries_pci_probe_mode(struct pci_bus *bus) | ||
| 594 | { | ||
| 595 | if (systemcfg->platform & PLATFORM_LPAR) | ||
| 596 | return PCI_PROBE_DEVTREE; | ||
| 597 | return PCI_PROBE_NORMAL; | ||
| 598 | } | ||
| 599 | |||
| 593 | struct machdep_calls __initdata pSeries_md = { | 600 | struct machdep_calls __initdata pSeries_md = { |
| 594 | .probe = pSeries_probe, | 601 | .probe = pSeries_probe, |
| 595 | .setup_arch = pSeries_setup_arch, | 602 | .setup_arch = pSeries_setup_arch, |
| @@ -597,6 +604,7 @@ struct machdep_calls __initdata pSeries_md = { | |||
| 597 | .get_cpuinfo = pSeries_get_cpuinfo, | 604 | .get_cpuinfo = pSeries_get_cpuinfo, |
| 598 | .log_error = pSeries_log_error, | 605 | .log_error = pSeries_log_error, |
| 599 | .pcibios_fixup = pSeries_final_fixup, | 606 | .pcibios_fixup = pSeries_final_fixup, |
| 607 | .pci_probe_mode = pSeries_pci_probe_mode, | ||
| 600 | .irq_bus_setup = pSeries_irq_bus_setup, | 608 | .irq_bus_setup = pSeries_irq_bus_setup, |
| 601 | .restart = rtas_restart, | 609 | .restart = rtas_restart, |
| 602 | .power_off = rtas_power_off, | 610 | .power_off = rtas_power_off, |
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index 79c7f3223665..d2c7e2c4733b 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
| @@ -272,6 +272,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) | |||
| 272 | unsigned long start_here = __pa((u32)*((unsigned long *) | 272 | unsigned long start_here = __pa((u32)*((unsigned long *) |
| 273 | pSeries_secondary_smp_init)); | 273 | pSeries_secondary_smp_init)); |
| 274 | unsigned int pcpu; | 274 | unsigned int pcpu; |
| 275 | int start_cpu; | ||
| 275 | 276 | ||
| 276 | if (cpu_isset(lcpu, of_spin_map)) | 277 | if (cpu_isset(lcpu, of_spin_map)) |
| 277 | /* Already started by OF and sitting in spin loop */ | 278 | /* Already started by OF and sitting in spin loop */ |
| @@ -282,12 +283,20 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) | |||
| 282 | /* Fixup atomic count: it exited inside IRQ handler. */ | 283 | /* Fixup atomic count: it exited inside IRQ handler. */ |
| 283 | paca[lcpu].__current->thread_info->preempt_count = 0; | 284 | paca[lcpu].__current->thread_info->preempt_count = 0; |
| 284 | 285 | ||
| 285 | status = rtas_call(rtas_token("start-cpu"), 3, 1, NULL, | 286 | /* |
| 286 | pcpu, start_here, lcpu); | 287 | * If the RTAS start-cpu token does not exist then presume the |
| 288 | * cpu is already spinning. | ||
| 289 | */ | ||
| 290 | start_cpu = rtas_token("start-cpu"); | ||
| 291 | if (start_cpu == RTAS_UNKNOWN_SERVICE) | ||
| 292 | return 1; | ||
| 293 | |||
| 294 | status = rtas_call(start_cpu, 3, 1, NULL, pcpu, start_here, lcpu); | ||
| 287 | if (status != 0) { | 295 | if (status != 0) { |
| 288 | printk(KERN_ERR "start-cpu failed: %i\n", status); | 296 | printk(KERN_ERR "start-cpu failed: %i\n", status); |
| 289 | return 0; | 297 | return 0; |
| 290 | } | 298 | } |
| 299 | |||
| 291 | return 1; | 300 | return 1; |
| 292 | } | 301 | } |
| 293 | 302 | ||
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index d0d55c7908ef..861138ad092c 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/bootmem.h> | 21 | #include <linux/bootmem.h> |
| 22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
| 23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
| 24 | #include <linux/syscalls.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
| 26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
| @@ -50,6 +51,10 @@ unsigned long io_page_mask; | |||
| 50 | 51 | ||
| 51 | EXPORT_SYMBOL(io_page_mask); | 52 | EXPORT_SYMBOL(io_page_mask); |
| 52 | 53 | ||
| 54 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 55 | static void fixup_resource(struct resource *res, struct pci_dev *dev); | ||
| 56 | static void do_bus_setup(struct pci_bus *bus); | ||
| 57 | #endif | ||
| 53 | 58 | ||
| 54 | unsigned int pcibios_assign_all_busses(void) | 59 | unsigned int pcibios_assign_all_busses(void) |
| 55 | { | 60 | { |
| @@ -84,7 +89,6 @@ static void fixup_broken_pcnet32(struct pci_dev* dev) | |||
| 84 | if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { | 89 | if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { |
| 85 | dev->vendor = PCI_VENDOR_ID_AMD; | 90 | dev->vendor = PCI_VENDOR_ID_AMD; |
| 86 | pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); | 91 | pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); |
| 87 | pci_name_device(dev); | ||
| 88 | } | 92 | } |
| 89 | } | 93 | } |
| 90 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); | 94 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); |
| @@ -225,10 +229,287 @@ static void __init pcibios_claim_of_setup(void) | |||
| 225 | } | 229 | } |
| 226 | #endif | 230 | #endif |
| 227 | 231 | ||
| 232 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 233 | static u32 get_int_prop(struct device_node *np, const char *name, u32 def) | ||
| 234 | { | ||
| 235 | u32 *prop; | ||
| 236 | int len; | ||
| 237 | |||
| 238 | prop = (u32 *) get_property(np, name, &len); | ||
| 239 | if (prop && len >= 4) | ||
| 240 | return *prop; | ||
| 241 | return def; | ||
| 242 | } | ||
| 243 | |||
| 244 | static unsigned int pci_parse_of_flags(u32 addr0) | ||
| 245 | { | ||
| 246 | unsigned int flags = 0; | ||
| 247 | |||
| 248 | if (addr0 & 0x02000000) { | ||
| 249 | flags |= IORESOURCE_MEM; | ||
| 250 | if (addr0 & 0x40000000) | ||
| 251 | flags |= IORESOURCE_PREFETCH; | ||
| 252 | } else if (addr0 & 0x01000000) | ||
| 253 | flags |= IORESOURCE_IO; | ||
| 254 | return flags; | ||
| 255 | } | ||
| 256 | |||
| 257 | #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) | ||
| 258 | |||
| 259 | static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | ||
| 260 | { | ||
| 261 | u64 base, size; | ||
| 262 | unsigned int flags; | ||
| 263 | struct resource *res; | ||
| 264 | u32 *addrs, i; | ||
| 265 | int proplen; | ||
| 266 | |||
| 267 | addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); | ||
| 268 | if (!addrs) | ||
| 269 | return; | ||
| 270 | for (; proplen >= 20; proplen -= 20, addrs += 5) { | ||
| 271 | flags = pci_parse_of_flags(addrs[0]); | ||
| 272 | if (!flags) | ||
| 273 | continue; | ||
| 274 | base = GET_64BIT(addrs, 1); | ||
| 275 | size = GET_64BIT(addrs, 3); | ||
| 276 | if (!size) | ||
| 277 | continue; | ||
| 278 | i = addrs[0] & 0xff; | ||
| 279 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { | ||
| 280 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; | ||
| 281 | } else if (i == dev->rom_base_reg) { | ||
| 282 | res = &dev->resource[PCI_ROM_RESOURCE]; | ||
| 283 | flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; | ||
| 284 | } else { | ||
| 285 | printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); | ||
| 286 | continue; | ||
| 287 | } | ||
| 288 | res->start = base; | ||
| 289 | res->end = base + size - 1; | ||
| 290 | res->flags = flags; | ||
| 291 | res->name = pci_name(dev); | ||
| 292 | fixup_resource(res, dev); | ||
| 293 | } | ||
| 294 | } | ||
| 295 | |||
| 296 | static struct pci_dev *of_create_pci_dev(struct device_node *node, | ||
| 297 | struct pci_bus *bus, int devfn) | ||
| 298 | { | ||
| 299 | struct pci_dev *dev; | ||
| 300 | const char *type; | ||
| 301 | |||
| 302 | dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); | ||
| 303 | if (!dev) | ||
| 304 | return NULL; | ||
| 305 | type = get_property(node, "device_type", NULL); | ||
| 306 | if (type == NULL) | ||
| 307 | type = ""; | ||
| 308 | |||
| 309 | memset(dev, 0, sizeof(struct pci_dev)); | ||
| 310 | dev->bus = bus; | ||
| 311 | dev->sysdata = node; | ||
| 312 | dev->dev.parent = bus->bridge; | ||
| 313 | dev->dev.bus = &pci_bus_type; | ||
| 314 | dev->devfn = devfn; | ||
| 315 | dev->multifunction = 0; /* maybe a lie? */ | ||
| 316 | |||
| 317 | dev->vendor = get_int_prop(node, "vendor-id", 0xffff); | ||
| 318 | dev->device = get_int_prop(node, "device-id", 0xffff); | ||
| 319 | dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); | ||
| 320 | dev->subsystem_device = get_int_prop(node, "subsystem-id", 0); | ||
| 321 | |||
| 322 | dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/ | ||
| 323 | |||
| 324 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), | ||
| 325 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||
| 326 | dev->class = get_int_prop(node, "class-code", 0); | ||
| 327 | |||
| 328 | dev->current_state = 4; /* unknown power state */ | ||
| 329 | |||
| 330 | if (!strcmp(type, "pci")) { | ||
| 331 | /* a PCI-PCI bridge */ | ||
| 332 | dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; | ||
| 333 | dev->rom_base_reg = PCI_ROM_ADDRESS1; | ||
| 334 | } else if (!strcmp(type, "cardbus")) { | ||
| 335 | dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; | ||
| 336 | } else { | ||
| 337 | dev->hdr_type = PCI_HEADER_TYPE_NORMAL; | ||
| 338 | dev->rom_base_reg = PCI_ROM_ADDRESS; | ||
| 339 | dev->irq = NO_IRQ; | ||
| 340 | if (node->n_intrs > 0) { | ||
| 341 | dev->irq = node->intrs[0].line; | ||
| 342 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, | ||
| 343 | dev->irq); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | pci_parse_of_addrs(node, dev); | ||
| 348 | |||
| 349 | pci_device_add(dev, bus); | ||
| 350 | |||
| 351 | /* XXX pci_scan_msi_device(dev); */ | ||
| 352 | |||
| 353 | return dev; | ||
| 354 | } | ||
| 355 | |||
| 356 | static void of_scan_pci_bridge(struct device_node *node, struct pci_dev *dev); | ||
| 357 | |||
| 358 | static void __devinit of_scan_bus(struct device_node *node, | ||
| 359 | struct pci_bus *bus) | ||
| 360 | { | ||
| 361 | struct device_node *child = NULL; | ||
| 362 | u32 *reg; | ||
| 363 | int reglen, devfn; | ||
| 364 | struct pci_dev *dev; | ||
| 365 | |||
| 366 | while ((child = of_get_next_child(node, child)) != NULL) { | ||
| 367 | reg = (u32 *) get_property(child, "reg", ®len); | ||
| 368 | if (reg == NULL || reglen < 20) | ||
| 369 | continue; | ||
| 370 | devfn = (reg[0] >> 8) & 0xff; | ||
| 371 | /* create a new pci_dev for this device */ | ||
| 372 | dev = of_create_pci_dev(child, bus, devfn); | ||
| 373 | if (!dev) | ||
| 374 | continue; | ||
| 375 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
| 376 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
| 377 | of_scan_pci_bridge(child, dev); | ||
| 378 | } | ||
| 379 | |||
| 380 | do_bus_setup(bus); | ||
| 381 | } | ||
| 382 | |||
| 383 | static void __devinit of_scan_pci_bridge(struct device_node *node, | ||
| 384 | struct pci_dev *dev) | ||
| 385 | { | ||
| 386 | struct pci_bus *bus; | ||
| 387 | u32 *busrange, *ranges; | ||
| 388 | int len, i, mode; | ||
| 389 | struct resource *res; | ||
| 390 | unsigned int flags; | ||
| 391 | u64 size; | ||
| 392 | |||
| 393 | /* parse bus-range property */ | ||
| 394 | busrange = (u32 *) get_property(node, "bus-range", &len); | ||
| 395 | if (busrange == NULL || len != 8) { | ||
| 396 | printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n", | ||
| 397 | node->full_name); | ||
| 398 | return; | ||
| 399 | } | ||
| 400 | ranges = (u32 *) get_property(node, "ranges", &len); | ||
| 401 | if (ranges == NULL) { | ||
| 402 | printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n", | ||
| 403 | node->full_name); | ||
| 404 | return; | ||
| 405 | } | ||
| 406 | |||
| 407 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); | ||
| 408 | if (!bus) { | ||
| 409 | printk(KERN_ERR "Failed to create pci bus for %s\n", | ||
| 410 | node->full_name); | ||
| 411 | return; | ||
| 412 | } | ||
| 413 | |||
| 414 | bus->primary = dev->bus->number; | ||
| 415 | bus->subordinate = busrange[1]; | ||
| 416 | bus->bridge_ctl = 0; | ||
| 417 | bus->sysdata = node; | ||
| 418 | |||
| 419 | /* parse ranges property */ | ||
| 420 | /* PCI #address-cells == 3 and #size-cells == 2 always */ | ||
| 421 | res = &dev->resource[PCI_BRIDGE_RESOURCES]; | ||
| 422 | for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { | ||
| 423 | res->flags = 0; | ||
| 424 | bus->resource[i] = res; | ||
| 425 | ++res; | ||
| 426 | } | ||
| 427 | i = 1; | ||
| 428 | for (; len >= 32; len -= 32, ranges += 8) { | ||
| 429 | flags = pci_parse_of_flags(ranges[0]); | ||
| 430 | size = GET_64BIT(ranges, 6); | ||
| 431 | if (flags == 0 || size == 0) | ||
| 432 | continue; | ||
| 433 | if (flags & IORESOURCE_IO) { | ||
| 434 | res = bus->resource[0]; | ||
| 435 | if (res->flags) { | ||
| 436 | printk(KERN_ERR "PCI: ignoring extra I/O range" | ||
| 437 | " for bridge %s\n", node->full_name); | ||
| 438 | continue; | ||
| 439 | } | ||
| 440 | } else { | ||
| 441 | if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { | ||
| 442 | printk(KERN_ERR "PCI: too many memory ranges" | ||
| 443 | " for bridge %s\n", node->full_name); | ||
| 444 | continue; | ||
| 445 | } | ||
| 446 | res = bus->resource[i]; | ||
| 447 | ++i; | ||
| 448 | } | ||
| 449 | res->start = GET_64BIT(ranges, 1); | ||
| 450 | res->end = res->start + size - 1; | ||
| 451 | res->flags = flags; | ||
| 452 | fixup_resource(res, dev); | ||
| 453 | } | ||
| 454 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | ||
| 455 | bus->number); | ||
| 456 | |||
| 457 | mode = PCI_PROBE_NORMAL; | ||
| 458 | if (ppc_md.pci_probe_mode) | ||
| 459 | mode = ppc_md.pci_probe_mode(bus); | ||
| 460 | if (mode == PCI_PROBE_DEVTREE) | ||
| 461 | of_scan_bus(node, bus); | ||
| 462 | else if (mode == PCI_PROBE_NORMAL) | ||
| 463 | pci_scan_child_bus(bus); | ||
| 464 | } | ||
| 465 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
| 466 | |||
| 467 | static void __devinit scan_phb(struct pci_controller *hose) | ||
| 468 | { | ||
| 469 | struct pci_bus *bus; | ||
| 470 | struct device_node *node = hose->arch_data; | ||
| 471 | int i, mode; | ||
| 472 | struct resource *res; | ||
| 473 | |||
| 474 | bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); | ||
| 475 | if (bus == NULL) { | ||
| 476 | printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", | ||
| 477 | hose->global_number); | ||
| 478 | return; | ||
| 479 | } | ||
| 480 | bus->secondary = hose->first_busno; | ||
| 481 | hose->bus = bus; | ||
| 482 | |||
| 483 | bus->resource[0] = res = &hose->io_resource; | ||
| 484 | if (res->flags && request_resource(&ioport_resource, res)) | ||
| 485 | printk(KERN_ERR "Failed to request PCI IO region " | ||
| 486 | "on PCI domain %04x\n", hose->global_number); | ||
| 487 | |||
| 488 | for (i = 0; i < 3; ++i) { | ||
| 489 | res = &hose->mem_resources[i]; | ||
| 490 | bus->resource[i+1] = res; | ||
| 491 | if (res->flags && request_resource(&iomem_resource, res)) | ||
| 492 | printk(KERN_ERR "Failed to request PCI memory region " | ||
| 493 | "on PCI domain %04x\n", hose->global_number); | ||
| 494 | } | ||
| 495 | |||
| 496 | mode = PCI_PROBE_NORMAL; | ||
| 497 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
| 498 | if (ppc_md.pci_probe_mode) | ||
| 499 | mode = ppc_md.pci_probe_mode(bus); | ||
| 500 | if (mode == PCI_PROBE_DEVTREE) { | ||
| 501 | bus->subordinate = hose->last_busno; | ||
| 502 | of_scan_bus(node, bus); | ||
| 503 | } | ||
| 504 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
| 505 | if (mode == PCI_PROBE_NORMAL) | ||
| 506 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | ||
| 507 | pci_bus_add_devices(bus); | ||
| 508 | } | ||
| 509 | |||
| 228 | static int __init pcibios_init(void) | 510 | static int __init pcibios_init(void) |
| 229 | { | 511 | { |
| 230 | struct pci_controller *hose, *tmp; | 512 | struct pci_controller *hose, *tmp; |
| 231 | struct pci_bus *bus; | ||
| 232 | 513 | ||
| 233 | /* For now, override phys_mem_access_prot. If we need it, | 514 | /* For now, override phys_mem_access_prot. If we need it, |
| 234 | * later, we may move that initialization to each ppc_md | 515 | * later, we may move that initialization to each ppc_md |
| @@ -242,13 +523,8 @@ static int __init pcibios_init(void) | |||
| 242 | printk("PCI: Probing PCI hardware\n"); | 523 | printk("PCI: Probing PCI hardware\n"); |
| 243 | 524 | ||
| 244 | /* Scan all of the recorded PCI controllers. */ | 525 | /* Scan all of the recorded PCI controllers. */ |
| 245 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { | 526 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) |
| 246 | hose->last_busno = 0xff; | 527 | scan_phb(hose); |
| 247 | bus = pci_scan_bus(hose->first_busno, hose->ops, | ||
| 248 | hose->arch_data); | ||
| 249 | hose->bus = bus; | ||
| 250 | hose->last_busno = bus->subordinate; | ||
| 251 | } | ||
| 252 | 528 | ||
| 253 | #ifndef CONFIG_PPC_ISERIES | 529 | #ifndef CONFIG_PPC_ISERIES |
| 254 | if (pci_probe_only) | 530 | if (pci_probe_only) |
| @@ -820,118 +1096,89 @@ void phbs_remap_io(void) | |||
| 820 | /* | 1096 | /* |
| 821 | * ppc64 can have multifunction devices that do not respond to function 0. | 1097 | * ppc64 can have multifunction devices that do not respond to function 0. |
| 822 | * In this case we must scan all functions. | 1098 | * In this case we must scan all functions. |
| 1099 | * XXX this can go now, we use the OF device tree in all the | ||
| 1100 | * cases that caused problems. -- paulus | ||
| 823 | */ | 1101 | */ |
| 824 | int pcibios_scan_all_fns(struct pci_bus *bus, int devfn) | 1102 | int pcibios_scan_all_fns(struct pci_bus *bus, int devfn) |
| 825 | { | 1103 | { |
| 826 | struct device_node *busdn, *dn; | 1104 | return 0; |
| 1105 | } | ||
| 1106 | |||
| 1107 | static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) | ||
| 1108 | { | ||
| 1109 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
| 1110 | unsigned long start, end, mask, offset; | ||
| 827 | 1111 | ||
| 828 | if (bus->self) | 1112 | if (res->flags & IORESOURCE_IO) { |
| 829 | busdn = pci_device_to_OF_node(bus->self); | 1113 | offset = (unsigned long)hose->io_base_virt - pci_io_base; |
| 830 | else | ||
| 831 | busdn = bus->sysdata; /* must be a phb */ | ||
| 832 | 1114 | ||
| 833 | if (busdn == NULL) | 1115 | start = res->start += offset; |
| 834 | return 0; | 1116 | end = res->end += offset; |
| 835 | 1117 | ||
| 836 | /* | 1118 | /* Need to allow IO access to pages that are in the |
| 837 | * Check to see if there is any of the 8 functions are in the | 1119 | ISA range */ |
| 838 | * device tree. If they are then we need to scan all the | 1120 | if (start < MAX_ISA_PORT) { |
| 839 | * functions of this slot. | 1121 | if (end > MAX_ISA_PORT) |
| 840 | */ | 1122 | end = MAX_ISA_PORT; |
| 841 | for (dn = busdn->child; dn; dn = dn->sibling) | ||
| 842 | if ((dn->devfn >> 3) == (devfn >> 3)) | ||
| 843 | return 1; | ||
| 844 | 1123 | ||
| 845 | return 0; | 1124 | start >>= PAGE_SHIFT; |
| 846 | } | 1125 | end >>= PAGE_SHIFT; |
| 847 | 1126 | ||
| 1127 | /* get the range of pages for the map */ | ||
| 1128 | mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1); | ||
| 1129 | io_page_mask |= mask; | ||
| 1130 | } | ||
| 1131 | } else if (res->flags & IORESOURCE_MEM) { | ||
| 1132 | res->start += hose->pci_mem_offset; | ||
| 1133 | res->end += hose->pci_mem_offset; | ||
| 1134 | } | ||
| 1135 | } | ||
| 848 | 1136 | ||
| 849 | void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, | 1137 | void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, |
| 850 | struct pci_bus *bus) | 1138 | struct pci_bus *bus) |
| 851 | { | 1139 | { |
| 852 | /* Update device resources. */ | 1140 | /* Update device resources. */ |
| 853 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
| 854 | int i; | 1141 | int i; |
| 855 | 1142 | ||
| 856 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | 1143 | for (i = 0; i < PCI_NUM_RESOURCES; i++) |
| 857 | if (dev->resource[i].flags & IORESOURCE_IO) { | 1144 | if (dev->resource[i].flags) |
| 858 | unsigned long offset = (unsigned long)hose->io_base_virt | 1145 | fixup_resource(&dev->resource[i], dev); |
| 859 | - pci_io_base; | ||
| 860 | unsigned long start, end, mask; | ||
| 861 | |||
| 862 | start = dev->resource[i].start += offset; | ||
| 863 | end = dev->resource[i].end += offset; | ||
| 864 | |||
| 865 | /* Need to allow IO access to pages that are in the | ||
| 866 | ISA range */ | ||
| 867 | if (start < MAX_ISA_PORT) { | ||
| 868 | if (end > MAX_ISA_PORT) | ||
| 869 | end = MAX_ISA_PORT; | ||
| 870 | |||
| 871 | start >>= PAGE_SHIFT; | ||
| 872 | end >>= PAGE_SHIFT; | ||
| 873 | |||
| 874 | /* get the range of pages for the map */ | ||
| 875 | mask = ((1 << (end+1))-1) ^ ((1 << start)-1); | ||
| 876 | io_page_mask |= mask; | ||
| 877 | } | ||
| 878 | } | ||
| 879 | else if (dev->resource[i].flags & IORESOURCE_MEM) { | ||
| 880 | dev->resource[i].start += hose->pci_mem_offset; | ||
| 881 | dev->resource[i].end += hose->pci_mem_offset; | ||
| 882 | } | ||
| 883 | } | ||
| 884 | } | 1146 | } |
| 885 | EXPORT_SYMBOL(pcibios_fixup_device_resources); | 1147 | EXPORT_SYMBOL(pcibios_fixup_device_resources); |
| 886 | 1148 | ||
| 887 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 1149 | static void __devinit do_bus_setup(struct pci_bus *bus) |
| 888 | { | 1150 | { |
| 889 | struct pci_controller *hose = pci_bus_to_host(bus); | 1151 | struct pci_dev *dev; |
| 890 | struct pci_dev *dev = bus->self; | ||
| 891 | struct resource *res; | ||
| 892 | int i; | ||
| 893 | 1152 | ||
| 894 | if (!dev) { | 1153 | ppc_md.iommu_bus_setup(bus); |
| 895 | /* Root bus. */ | ||
| 896 | 1154 | ||
| 897 | hose->bus = bus; | 1155 | list_for_each_entry(dev, &bus->devices, bus_list) |
| 898 | bus->resource[0] = res = &hose->io_resource; | 1156 | ppc_md.iommu_dev_setup(dev); |
| 899 | 1157 | ||
| 900 | if (res->flags && request_resource(&ioport_resource, res)) | 1158 | if (ppc_md.irq_bus_setup) |
| 901 | printk(KERN_ERR "Failed to request IO on " | 1159 | ppc_md.irq_bus_setup(bus); |
| 902 | "PCI domain %d\n", pci_domain_nr(bus)); | 1160 | } |
| 903 | 1161 | ||
| 904 | for (i = 0; i < 3; ++i) { | 1162 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
| 905 | res = &hose->mem_resources[i]; | 1163 | { |
| 906 | bus->resource[i+1] = res; | 1164 | struct pci_dev *dev = bus->self; |
| 907 | if (res->flags && request_resource(&iomem_resource, res)) | 1165 | |
| 908 | printk(KERN_ERR "Failed to request MEM on " | 1166 | if (dev && pci_probe_only && |
| 909 | "PCI domain %d\n", | 1167 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { |
| 910 | pci_domain_nr(bus)); | ||
| 911 | } | ||
| 912 | } else if (pci_probe_only && | ||
| 913 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
| 914 | /* This is a subordinate bridge */ | 1168 | /* This is a subordinate bridge */ |
| 915 | 1169 | ||
| 916 | pci_read_bridge_bases(bus); | 1170 | pci_read_bridge_bases(bus); |
| 917 | pcibios_fixup_device_resources(dev, bus); | 1171 | pcibios_fixup_device_resources(dev, bus); |
| 918 | } | 1172 | } |
| 919 | 1173 | ||
| 920 | ppc_md.iommu_bus_setup(bus); | 1174 | do_bus_setup(bus); |
| 921 | |||
| 922 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
| 923 | ppc_md.iommu_dev_setup(dev); | ||
| 924 | |||
| 925 | if (ppc_md.irq_bus_setup) | ||
| 926 | ppc_md.irq_bus_setup(bus); | ||
| 927 | 1175 | ||
| 928 | if (!pci_probe_only) | 1176 | if (!pci_probe_only) |
| 929 | return; | 1177 | return; |
| 930 | 1178 | ||
| 931 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1179 | list_for_each_entry(dev, &bus->devices, bus_list) |
| 932 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | 1180 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) |
| 933 | pcibios_fixup_device_resources(dev, bus); | 1181 | pcibios_fixup_device_resources(dev, bus); |
| 934 | } | ||
| 935 | } | 1182 | } |
| 936 | EXPORT_SYMBOL(pcibios_fixup_bus); | 1183 | EXPORT_SYMBOL(pcibios_fixup_bus); |
| 937 | 1184 | ||
| @@ -983,3 +1230,62 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
| 983 | } | 1230 | } |
| 984 | 1231 | ||
| 985 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 1232 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
| 1233 | |||
| 1234 | |||
| 1235 | #define IOBASE_BRIDGE_NUMBER 0 | ||
| 1236 | #define IOBASE_MEMORY 1 | ||
| 1237 | #define IOBASE_IO 2 | ||
| 1238 | #define IOBASE_ISA_IO 3 | ||
| 1239 | #define IOBASE_ISA_MEM 4 | ||
| 1240 | |||
| 1241 | long sys_pciconfig_iobase(long which, unsigned long in_bus, | ||
| 1242 | unsigned long in_devfn) | ||
| 1243 | { | ||
| 1244 | struct pci_controller* hose; | ||
| 1245 | struct list_head *ln; | ||
| 1246 | struct pci_bus *bus = NULL; | ||
| 1247 | struct device_node *hose_node; | ||
| 1248 | |||
| 1249 | /* Argh ! Please forgive me for that hack, but that's the | ||
| 1250 | * simplest way to get existing XFree to not lockup on some | ||
| 1251 | * G5 machines... So when something asks for bus 0 io base | ||
| 1252 | * (bus 0 is HT root), we return the AGP one instead. | ||
| 1253 | */ | ||
| 1254 | #ifdef CONFIG_PPC_PMAC | ||
| 1255 | if (systemcfg->platform == PLATFORM_POWERMAC && | ||
| 1256 | machine_is_compatible("MacRISC4")) | ||
| 1257 | if (in_bus == 0) | ||
| 1258 | in_bus = 0xf0; | ||
| 1259 | #endif /* CONFIG_PPC_PMAC */ | ||
| 1260 | |||
| 1261 | /* That syscall isn't quite compatible with PCI domains, but it's | ||
| 1262 | * used on pre-domains setup. We return the first match | ||
| 1263 | */ | ||
| 1264 | |||
| 1265 | for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { | ||
| 1266 | bus = pci_bus_b(ln); | ||
| 1267 | if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate)) | ||
| 1268 | break; | ||
| 1269 | bus = NULL; | ||
| 1270 | } | ||
| 1271 | if (bus == NULL || bus->sysdata == NULL) | ||
| 1272 | return -ENODEV; | ||
| 1273 | |||
| 1274 | hose_node = (struct device_node *)bus->sysdata; | ||
| 1275 | hose = PCI_DN(hose_node)->phb; | ||
| 1276 | |||
| 1277 | switch (which) { | ||
| 1278 | case IOBASE_BRIDGE_NUMBER: | ||
| 1279 | return (long)hose->first_busno; | ||
| 1280 | case IOBASE_MEMORY: | ||
| 1281 | return (long)hose->pci_mem_offset; | ||
| 1282 | case IOBASE_IO: | ||
| 1283 | return (long)hose->io_base_phys; | ||
| 1284 | case IOBASE_ISA_IO: | ||
| 1285 | return (long)isa_io_base; | ||
| 1286 | case IOBASE_ISA_MEM: | ||
| 1287 | return -EINVAL; | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | return -EOPNOTSUPP; | ||
| 1291 | } | ||
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h index 26be78b13af1..5eb2cc320566 100644 --- a/arch/ppc64/kernel/pci.h +++ b/arch/ppc64/kernel/pci.h | |||
| @@ -34,7 +34,6 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, | |||
| 34 | 34 | ||
| 35 | void pci_devs_phb_init(void); | 35 | void pci_devs_phb_init(void); |
| 36 | void pci_devs_phb_init_dynamic(struct pci_controller *phb); | 36 | void pci_devs_phb_init_dynamic(struct pci_controller *phb); |
| 37 | struct device_node *fetch_dev_dn(struct pci_dev *dev); | ||
| 38 | 37 | ||
| 39 | /* PCI address cache management routines */ | 38 | /* PCI address cache management routines */ |
| 40 | void pci_addr_cache_insert_device(struct pci_dev *dev); | 39 | void pci_addr_cache_insert_device(struct pci_dev *dev); |
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c index ec345462afc3..a86389d07d57 100644 --- a/arch/ppc64/kernel/pci_dn.c +++ b/arch/ppc64/kernel/pci_dn.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/slab.h> | ||
| 27 | #include <linux/bootmem.h> | ||
| 26 | 28 | ||
| 27 | #include <asm/io.h> | 29 | #include <asm/io.h> |
| 28 | #include <asm/prom.h> | 30 | #include <asm/prom.h> |
| @@ -40,16 +42,26 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) | |||
| 40 | struct pci_controller *phb = data; | 42 | struct pci_controller *phb = data; |
| 41 | int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); | 43 | int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); |
| 42 | u32 *regs; | 44 | u32 *regs; |
| 43 | 45 | struct pci_dn *pdn; | |
| 44 | dn->phb = phb; | 46 | |
| 47 | if (phb->is_dynamic) | ||
| 48 | pdn = kmalloc(sizeof(*pdn), GFP_KERNEL); | ||
| 49 | else | ||
| 50 | pdn = alloc_bootmem(sizeof(*pdn)); | ||
| 51 | if (pdn == NULL) | ||
| 52 | return NULL; | ||
| 53 | memset(pdn, 0, sizeof(*pdn)); | ||
| 54 | dn->data = pdn; | ||
| 55 | pdn->node = dn; | ||
| 56 | pdn->phb = phb; | ||
| 45 | regs = (u32 *)get_property(dn, "reg", NULL); | 57 | regs = (u32 *)get_property(dn, "reg", NULL); |
| 46 | if (regs) { | 58 | if (regs) { |
| 47 | /* First register entry is addr (00BBSS00) */ | 59 | /* First register entry is addr (00BBSS00) */ |
| 48 | dn->busno = (regs[0] >> 16) & 0xff; | 60 | pdn->busno = (regs[0] >> 16) & 0xff; |
| 49 | dn->devfn = (regs[0] >> 8) & 0xff; | 61 | pdn->devfn = (regs[0] >> 8) & 0xff; |
| 50 | } | 62 | } |
| 51 | 63 | ||
| 52 | dn->pci_ext_config_space = (type && *type == 1); | 64 | pdn->pci_ext_config_space = (type && *type == 1); |
| 53 | return NULL; | 65 | return NULL; |
| 54 | } | 66 | } |
| 55 | 67 | ||
| @@ -112,10 +124,15 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, | |||
| 112 | void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) | 124 | void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) |
| 113 | { | 125 | { |
| 114 | struct device_node * dn = (struct device_node *) phb->arch_data; | 126 | struct device_node * dn = (struct device_node *) phb->arch_data; |
| 127 | struct pci_dn *pdn; | ||
| 115 | 128 | ||
| 116 | /* PHB nodes themselves must not match */ | 129 | /* PHB nodes themselves must not match */ |
| 117 | dn->devfn = dn->busno = -1; | 130 | update_dn_pci_info(dn, phb); |
| 118 | dn->phb = phb; | 131 | pdn = dn->data; |
| 132 | if (pdn) { | ||
| 133 | pdn->devfn = pdn->busno = -1; | ||
| 134 | pdn->phb = phb; | ||
| 135 | } | ||
| 119 | 136 | ||
| 120 | /* Update dn->phb ptrs for new phb and children devices */ | 137 | /* Update dn->phb ptrs for new phb and children devices */ |
| 121 | traverse_pci_devices(dn, update_dn_pci_info, phb); | 138 | traverse_pci_devices(dn, update_dn_pci_info, phb); |
| @@ -123,14 +140,17 @@ void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) | |||
| 123 | 140 | ||
| 124 | /* | 141 | /* |
| 125 | * Traversal func that looks for a <busno,devfcn> value. | 142 | * Traversal func that looks for a <busno,devfcn> value. |
| 126 | * If found, the device_node is returned (thus terminating the traversal). | 143 | * If found, the pci_dn is returned (thus terminating the traversal). |
| 127 | */ | 144 | */ |
| 128 | static void *is_devfn_node(struct device_node *dn, void *data) | 145 | static void *is_devfn_node(struct device_node *dn, void *data) |
| 129 | { | 146 | { |
| 130 | int busno = ((unsigned long)data >> 8) & 0xff; | 147 | int busno = ((unsigned long)data >> 8) & 0xff; |
| 131 | int devfn = ((unsigned long)data) & 0xff; | 148 | int devfn = ((unsigned long)data) & 0xff; |
| 149 | struct pci_dn *pci = dn->data; | ||
| 132 | 150 | ||
| 133 | return ((devfn == dn->devfn) && (busno == dn->busno)) ? dn : NULL; | 151 | if (pci && (devfn == pci->devfn) && (busno == pci->busno)) |
| 152 | return dn; | ||
| 153 | return NULL; | ||
| 134 | } | 154 | } |
| 135 | 155 | ||
| 136 | /* | 156 | /* |
| @@ -149,13 +169,10 @@ static void *is_devfn_node(struct device_node *dn, void *data) | |||
| 149 | struct device_node *fetch_dev_dn(struct pci_dev *dev) | 169 | struct device_node *fetch_dev_dn(struct pci_dev *dev) |
| 150 | { | 170 | { |
| 151 | struct device_node *orig_dn = dev->sysdata; | 171 | struct device_node *orig_dn = dev->sysdata; |
| 152 | struct pci_controller *phb = orig_dn->phb; /* assume same phb as orig_dn */ | ||
| 153 | struct device_node *phb_dn; | ||
| 154 | struct device_node *dn; | 172 | struct device_node *dn; |
| 155 | unsigned long searchval = (dev->bus->number << 8) | dev->devfn; | 173 | unsigned long searchval = (dev->bus->number << 8) | dev->devfn; |
| 156 | 174 | ||
| 157 | phb_dn = phb->arch_data; | 175 | dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval); |
| 158 | dn = traverse_pci_devices(phb_dn, is_devfn_node, (void *)searchval); | ||
| 159 | if (dn) | 176 | if (dn) |
| 160 | dev->sysdata = dn; | 177 | dev->sysdata = dn; |
| 161 | return dn; | 178 | return dn; |
| @@ -165,11 +182,13 @@ EXPORT_SYMBOL(fetch_dev_dn); | |||
| 165 | static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) | 182 | static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) |
| 166 | { | 183 | { |
| 167 | struct device_node *np = node; | 184 | struct device_node *np = node; |
| 185 | struct pci_dn *pci; | ||
| 168 | int err = NOTIFY_OK; | 186 | int err = NOTIFY_OK; |
| 169 | 187 | ||
| 170 | switch (action) { | 188 | switch (action) { |
| 171 | case PSERIES_RECONFIG_ADD: | 189 | case PSERIES_RECONFIG_ADD: |
| 172 | update_dn_pci_info(np, np->parent->phb); | 190 | pci = np->parent->data; |
| 191 | update_dn_pci_info(np, pci->phb); | ||
| 173 | break; | 192 | break; |
| 174 | default: | 193 | default: |
| 175 | err = NOTIFY_DONE; | 194 | err = NOTIFY_DONE; |
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c index ef0a62b916be..14647e09c9cd 100644 --- a/arch/ppc64/kernel/pci_iommu.c +++ b/arch/ppc64/kernel/pci_iommu.c | |||
| @@ -66,7 +66,7 @@ static inline struct iommu_table *devnode_table(struct device *dev) | |||
| 66 | #endif /* CONFIG_PPC_ISERIES */ | 66 | #endif /* CONFIG_PPC_ISERIES */ |
| 67 | 67 | ||
| 68 | #ifdef CONFIG_PPC_MULTIPLATFORM | 68 | #ifdef CONFIG_PPC_MULTIPLATFORM |
| 69 | return PCI_GET_DN(pdev)->iommu_table; | 69 | return PCI_DN(PCI_GET_DN(pdev))->iommu_table; |
| 70 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 70 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
| 71 | } | 71 | } |
| 72 | 72 | ||
diff --git a/arch/ppc64/kernel/pmac_feature.c b/arch/ppc64/kernel/pmac_feature.c index 98ed2bccab1a..eb4e6c3f694d 100644 --- a/arch/ppc64/kernel/pmac_feature.c +++ b/arch/ppc64/kernel/pmac_feature.c | |||
| @@ -674,6 +674,7 @@ void __init pmac_check_ht_link(void) | |||
| 674 | #if 0 /* Disabled for now */ | 674 | #if 0 /* Disabled for now */ |
| 675 | u32 ufreq, freq, ucfg, cfg; | 675 | u32 ufreq, freq, ucfg, cfg; |
| 676 | struct device_node *pcix_node; | 676 | struct device_node *pcix_node; |
| 677 | struct pci_dn *pdn; | ||
| 677 | u8 px_bus, px_devfn; | 678 | u8 px_bus, px_devfn; |
| 678 | struct pci_controller *px_hose; | 679 | struct pci_controller *px_hose; |
| 679 | 680 | ||
| @@ -687,9 +688,10 @@ void __init pmac_check_ht_link(void) | |||
| 687 | printk("No PCI-X bridge found\n"); | 688 | printk("No PCI-X bridge found\n"); |
| 688 | return; | 689 | return; |
| 689 | } | 690 | } |
| 690 | px_hose = pcix_node->phb; | 691 | pdn = pcix_node->data; |
| 691 | px_bus = pcix_node->busno; | 692 | px_hose = pdn->phb; |
| 692 | px_devfn = pcix_node->devfn; | 693 | px_bus = pdn->busno; |
| 694 | px_devfn = pdn->devfn; | ||
| 693 | 695 | ||
| 694 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); | 696 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg); |
| 695 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); | 697 | early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq); |
diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index 71fe911ad183..dc40a0cad0b4 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c | |||
| @@ -242,7 +242,7 @@ static int u3_ht_skip_device(struct pci_controller *hose, | |||
| 242 | else | 242 | else |
| 243 | busdn = hose->arch_data; | 243 | busdn = hose->arch_data; |
| 244 | for (dn = busdn->child; dn; dn = dn->sibling) | 244 | for (dn = busdn->child; dn; dn = dn->sibling) |
| 245 | if (dn->devfn == devfn) | 245 | if (dn->data && PCI_DN(dn)->devfn == devfn) |
| 246 | break; | 246 | break; |
| 247 | if (dn == NULL) | 247 | if (dn == NULL) |
| 248 | return -1; | 248 | return -1; |
| @@ -388,7 +388,7 @@ static void __init setup_u3_agp(struct pci_controller* hose) | |||
| 388 | * the reg address cell, we shall fix that by killing struct | 388 | * the reg address cell, we shall fix that by killing struct |
| 389 | * reg_property and using some accessor functions instead | 389 | * reg_property and using some accessor functions instead |
| 390 | */ | 390 | */ |
| 391 | hose->first_busno = 0xf0; | 391 | hose->first_busno = 0xf0; |
| 392 | hose->last_busno = 0xff; | 392 | hose->last_busno = 0xff; |
| 393 | has_uninorth = 1; | 393 | has_uninorth = 1; |
| 394 | hose->ops = ¯isc_pci_ops; | 394 | hose->ops = ¯isc_pci_ops; |
| @@ -473,7 +473,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
| 473 | continue; | 473 | continue; |
| 474 | } | 474 | } |
| 475 | cur++; | 475 | cur++; |
| 476 | DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", | 476 | DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", |
| 477 | cur-1, res->start - 1, cur, res->end + 1); | 477 | cur-1, res->start - 1, cur, res->end + 1); |
| 478 | hose->mem_resources[cur].name = np->full_name; | 478 | hose->mem_resources[cur].name = np->full_name; |
| 479 | hose->mem_resources[cur].flags = IORESOURCE_MEM; | 479 | hose->mem_resources[cur].flags = IORESOURCE_MEM; |
| @@ -603,24 +603,24 @@ static int __init add_bridge(struct device_node *dev) | |||
| 603 | char* disp_name; | 603 | char* disp_name; |
| 604 | int *bus_range; | 604 | int *bus_range; |
| 605 | int primary = 1; | 605 | int primary = 1; |
| 606 | struct property *of_prop; | 606 | struct property *of_prop; |
| 607 | 607 | ||
| 608 | DBG("Adding PCI host bridge %s\n", dev->full_name); | 608 | DBG("Adding PCI host bridge %s\n", dev->full_name); |
| 609 | 609 | ||
| 610 | bus_range = (int *) get_property(dev, "bus-range", &len); | 610 | bus_range = (int *) get_property(dev, "bus-range", &len); |
| 611 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 611 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
| 612 | printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", | 612 | printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", |
| 613 | dev->full_name); | 613 | dev->full_name); |
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | hose = alloc_bootmem(sizeof(struct pci_controller)); | 616 | hose = alloc_bootmem(sizeof(struct pci_controller)); |
| 617 | if (hose == NULL) | 617 | if (hose == NULL) |
| 618 | return -ENOMEM; | 618 | return -ENOMEM; |
| 619 | pci_setup_pci_controller(hose); | 619 | pci_setup_pci_controller(hose); |
| 620 | 620 | ||
| 621 | hose->arch_data = dev; | 621 | hose->arch_data = dev; |
| 622 | hose->first_busno = bus_range ? bus_range[0] : 0; | 622 | hose->first_busno = bus_range ? bus_range[0] : 0; |
| 623 | hose->last_busno = bus_range ? bus_range[1] : 0xff; | 623 | hose->last_busno = bus_range ? bus_range[1] : 0xff; |
| 624 | 624 | ||
| 625 | of_prop = alloc_bootmem(sizeof(struct property) + | 625 | of_prop = alloc_bootmem(sizeof(struct property) + |
| 626 | sizeof(hose->global_number)); | 626 | sizeof(hose->global_number)); |
| @@ -634,24 +634,24 @@ static int __init add_bridge(struct device_node *dev) | |||
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | disp_name = NULL; | 636 | disp_name = NULL; |
| 637 | if (device_is_compatible(dev, "u3-agp")) { | 637 | if (device_is_compatible(dev, "u3-agp")) { |
| 638 | setup_u3_agp(hose); | 638 | setup_u3_agp(hose); |
| 639 | disp_name = "U3-AGP"; | 639 | disp_name = "U3-AGP"; |
| 640 | primary = 0; | 640 | primary = 0; |
| 641 | } else if (device_is_compatible(dev, "u3-ht")) { | 641 | } else if (device_is_compatible(dev, "u3-ht")) { |
| 642 | setup_u3_ht(hose); | 642 | setup_u3_ht(hose); |
| 643 | disp_name = "U3-HT"; | 643 | disp_name = "U3-HT"; |
| 644 | primary = 1; | 644 | primary = 1; |
| 645 | } | 645 | } |
| 646 | printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", | 646 | printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", |
| 647 | disp_name, hose->first_busno, hose->last_busno); | 647 | disp_name, hose->first_busno, hose->last_busno); |
| 648 | 648 | ||
| 649 | /* Interpret the "ranges" property */ | 649 | /* Interpret the "ranges" property */ |
| 650 | /* This also maps the I/O region and sets isa_io/mem_base */ | 650 | /* This also maps the I/O region and sets isa_io/mem_base */ |
| 651 | pmac_process_bridge_OF_ranges(hose, dev, primary); | 651 | pmac_process_bridge_OF_ranges(hose, dev, primary); |
| 652 | 652 | ||
| 653 | /* Fixup "bus-range" OF property */ | 653 | /* Fixup "bus-range" OF property */ |
| 654 | fixup_bus_range(dev); | 654 | fixup_bus_range(dev); |
| 655 | 655 | ||
| 656 | return 0; | 656 | return 0; |
| 657 | } | 657 | } |
| @@ -746,9 +746,9 @@ void __init pmac_pci_init(void) | |||
| 746 | */ | 746 | */ |
| 747 | if (u3_agp) { | 747 | if (u3_agp) { |
| 748 | struct device_node *np = u3_agp->arch_data; | 748 | struct device_node *np = u3_agp->arch_data; |
| 749 | np->busno = 0xf0; | 749 | PCI_DN(np)->busno = 0xf0; |
| 750 | for (np = np->child; np; np = np->sibling) | 750 | for (np = np->child; np; np = np->sibling) |
| 751 | np->busno = 0xf0; | 751 | PCI_DN(np)->busno = 0xf0; |
| 752 | } | 752 | } |
| 753 | 753 | ||
| 754 | pmac_check_ht_link(); | 754 | pmac_check_ht_link(); |
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index e7f695dcd8c8..325426c7bed0 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c | |||
| @@ -477,6 +477,18 @@ static int __init pmac_probe(int platform) | |||
| 477 | return 1; | 477 | return 1; |
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | static int pmac_probe_mode(struct pci_bus *bus) | ||
| 481 | { | ||
| 482 | struct device_node *node = bus->sysdata; | ||
| 483 | |||
| 484 | /* We need to use normal PCI probing for the AGP bus, | ||
| 485 | since the device for the AGP bridge isn't in the tree. */ | ||
| 486 | if (bus->self == NULL && device_is_compatible(node, "u3-agp")) | ||
| 487 | return PCI_PROBE_NORMAL; | ||
| 488 | |||
| 489 | return PCI_PROBE_DEVTREE; | ||
| 490 | } | ||
| 491 | |||
| 480 | struct machdep_calls __initdata pmac_md = { | 492 | struct machdep_calls __initdata pmac_md = { |
| 481 | #ifdef CONFIG_HOTPLUG_CPU | 493 | #ifdef CONFIG_HOTPLUG_CPU |
| 482 | .cpu_die = generic_mach_cpu_die, | 494 | .cpu_die = generic_mach_cpu_die, |
| @@ -488,6 +500,7 @@ struct machdep_calls __initdata pmac_md = { | |||
| 488 | .init_IRQ = pmac_init_IRQ, | 500 | .init_IRQ = pmac_init_IRQ, |
| 489 | .get_irq = mpic_get_irq, | 501 | .get_irq = mpic_get_irq, |
| 490 | .pcibios_fixup = pmac_pcibios_fixup, | 502 | .pcibios_fixup = pmac_pcibios_fixup, |
| 503 | .pci_probe_mode = pmac_probe_mode, | ||
| 491 | .restart = pmac_restart, | 504 | .restart = pmac_restart, |
| 492 | .power_off = pmac_power_off, | 505 | .power_off = pmac_power_off, |
| 493 | .halt = pmac_halt, | 506 | .halt = pmac_halt, |
diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c index cdfec7438d01..63d9481c3ec2 100644 --- a/arch/ppc64/kernel/pmc.c +++ b/arch/ppc64/kernel/pmc.c | |||
| @@ -26,7 +26,7 @@ static void dummy_perf(struct pt_regs *regs) | |||
| 26 | mtspr(SPRN_MMCR0, mmcr0); | 26 | mtspr(SPRN_MMCR0, mmcr0); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | static spinlock_t pmc_owner_lock = SPIN_LOCK_UNLOCKED; | 29 | static DEFINE_SPINLOCK(pmc_owner_lock); |
| 30 | static void *pmc_owner_caller; /* mostly for debugging */ | 30 | static void *pmc_owner_caller; /* mostly for debugging */ |
| 31 | perf_irq_t perf_irq = dummy_perf; | 31 | perf_irq_t perf_irq = dummy_perf; |
| 32 | 32 | ||
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index 7a7e027653ad..887005358eb1 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #include <asm/sections.h> | 54 | #include <asm/sections.h> |
| 55 | #include <asm/tlbflush.h> | 55 | #include <asm/tlbflush.h> |
| 56 | #include <asm/time.h> | 56 | #include <asm/time.h> |
| 57 | #include <asm/plpar_wrappers.h> | ||
| 57 | 58 | ||
| 58 | #ifndef CONFIG_SMP | 59 | #ifndef CONFIG_SMP |
| 59 | struct task_struct *last_task_used_math = NULL; | 60 | struct task_struct *last_task_used_math = NULL; |
| @@ -163,7 +164,30 @@ int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs) | |||
| 163 | 164 | ||
| 164 | #endif /* CONFIG_ALTIVEC */ | 165 | #endif /* CONFIG_ALTIVEC */ |
| 165 | 166 | ||
| 167 | static void set_dabr_spr(unsigned long val) | ||
| 168 | { | ||
| 169 | mtspr(SPRN_DABR, val); | ||
| 170 | } | ||
| 171 | |||
| 172 | int set_dabr(unsigned long dabr) | ||
| 173 | { | ||
| 174 | int ret = 0; | ||
| 175 | |||
| 176 | if (firmware_has_feature(FW_FEATURE_XDABR)) { | ||
| 177 | /* We want to catch accesses from kernel and userspace */ | ||
| 178 | unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER; | ||
| 179 | ret = plpar_set_xdabr(dabr, flags); | ||
| 180 | } else if (firmware_has_feature(FW_FEATURE_DABR)) { | ||
| 181 | ret = plpar_set_dabr(dabr); | ||
| 182 | } else { | ||
| 183 | set_dabr_spr(dabr); | ||
| 184 | } | ||
| 185 | |||
| 186 | return ret; | ||
| 187 | } | ||
| 188 | |||
| 166 | DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); | 189 | DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); |
| 190 | static DEFINE_PER_CPU(unsigned long, current_dabr); | ||
| 167 | 191 | ||
| 168 | struct task_struct *__switch_to(struct task_struct *prev, | 192 | struct task_struct *__switch_to(struct task_struct *prev, |
| 169 | struct task_struct *new) | 193 | struct task_struct *new) |
| @@ -198,6 +222,11 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
| 198 | new->thread.regs->msr |= MSR_VEC; | 222 | new->thread.regs->msr |= MSR_VEC; |
| 199 | #endif /* CONFIG_ALTIVEC */ | 223 | #endif /* CONFIG_ALTIVEC */ |
| 200 | 224 | ||
| 225 | if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) { | ||
| 226 | set_dabr(new->thread.dabr); | ||
| 227 | __get_cpu_var(current_dabr) = new->thread.dabr; | ||
| 228 | } | ||
| 229 | |||
| 201 | flush_tlb_pending(); | 230 | flush_tlb_pending(); |
| 202 | 231 | ||
| 203 | new_thread = &new->thread; | 232 | new_thread = &new->thread; |
| @@ -334,6 +363,11 @@ void flush_thread(void) | |||
| 334 | last_task_used_altivec = NULL; | 363 | last_task_used_altivec = NULL; |
| 335 | #endif /* CONFIG_ALTIVEC */ | 364 | #endif /* CONFIG_ALTIVEC */ |
| 336 | #endif /* CONFIG_SMP */ | 365 | #endif /* CONFIG_SMP */ |
| 366 | |||
| 367 | if (current->thread.dabr) { | ||
| 368 | current->thread.dabr = 0; | ||
| 369 | set_dabr(0); | ||
| 370 | } | ||
| 337 | } | 371 | } |
| 338 | 372 | ||
| 339 | void | 373 | void |
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 6ad5a8467f87..7035deb6de92 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
| @@ -1733,6 +1733,7 @@ static void of_node_release(struct kref *kref) | |||
| 1733 | kfree(node->intrs); | 1733 | kfree(node->intrs); |
| 1734 | kfree(node->addrs); | 1734 | kfree(node->addrs); |
| 1735 | kfree(node->full_name); | 1735 | kfree(node->full_name); |
| 1736 | kfree(node->data); | ||
| 1736 | kfree(node); | 1737 | kfree(node); |
| 1737 | } | 1738 | } |
| 1738 | 1739 | ||
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c index 2993f108d96d..85ed3188a91d 100644 --- a/arch/ppc64/kernel/ptrace.c +++ b/arch/ppc64/kernel/ptrace.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * this archive for more details. | 17 | * this archive for more details. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/config.h> | ||
| 20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 21 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
| 22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| @@ -206,6 +207,19 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
| 206 | break; | 207 | break; |
| 207 | } | 208 | } |
| 208 | 209 | ||
| 210 | case PTRACE_GET_DEBUGREG: { | ||
| 211 | ret = -EINVAL; | ||
| 212 | /* We only support one DABR and no IABRS at the moment */ | ||
| 213 | if (addr > 0) | ||
| 214 | break; | ||
| 215 | ret = put_user(child->thread.dabr, | ||
| 216 | (unsigned long __user *)data); | ||
| 217 | break; | ||
| 218 | } | ||
| 219 | |||
| 220 | case PTRACE_SET_DEBUGREG: | ||
| 221 | ret = ptrace_set_debugreg(child, addr, data); | ||
| 222 | |||
| 209 | case PTRACE_DETACH: | 223 | case PTRACE_DETACH: |
| 210 | ret = ptrace_detach(child, data); | 224 | ret = ptrace_detach(child, data); |
| 211 | break; | 225 | break; |
| @@ -274,6 +288,20 @@ int sys_ptrace(long request, long pid, long addr, long data) | |||
| 274 | break; | 288 | break; |
| 275 | } | 289 | } |
| 276 | 290 | ||
| 291 | #ifdef CONFIG_ALTIVEC | ||
| 292 | case PTRACE_GETVRREGS: | ||
| 293 | /* Get the child altivec register state. */ | ||
| 294 | flush_altivec_to_thread(child); | ||
| 295 | ret = get_vrregs((unsigned long __user *)data, child); | ||
| 296 | break; | ||
| 297 | |||
| 298 | case PTRACE_SETVRREGS: | ||
| 299 | /* Set the child altivec register state. */ | ||
| 300 | flush_altivec_to_thread(child); | ||
| 301 | ret = set_vrregs(child, (unsigned long __user *)data); | ||
| 302 | break; | ||
| 303 | #endif | ||
| 304 | |||
| 277 | default: | 305 | default: |
| 278 | ret = ptrace_request(child, request, addr, data); | 306 | ret = ptrace_request(child, request, addr, data); |
| 279 | break; | 307 | break; |
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c index 16436426c7e2..fb8c22d6084a 100644 --- a/arch/ppc64/kernel/ptrace32.c +++ b/arch/ppc64/kernel/ptrace32.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * this archive for more details. | 17 | * this archive for more details. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/config.h> | ||
| 20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 21 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
| 22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| @@ -337,6 +338,19 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) | |||
| 337 | break; | 338 | break; |
| 338 | } | 339 | } |
| 339 | 340 | ||
| 341 | case PTRACE_GET_DEBUGREG: { | ||
| 342 | ret = -EINVAL; | ||
| 343 | /* We only support one DABR and no IABRS at the moment */ | ||
| 344 | if (addr > 0) | ||
| 345 | break; | ||
| 346 | ret = put_user(child->thread.dabr, (u32 __user *)data); | ||
| 347 | break; | ||
| 348 | } | ||
| 349 | |||
| 350 | case PTRACE_SET_DEBUGREG: | ||
| 351 | ret = ptrace_set_debugreg(child, addr, data); | ||
| 352 | break; | ||
| 353 | |||
| 340 | case PTRACE_DETACH: | 354 | case PTRACE_DETACH: |
| 341 | ret = ptrace_detach(child, data); | 355 | ret = ptrace_detach(child, data); |
| 342 | break; | 356 | break; |
| @@ -405,9 +419,23 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) | |||
| 405 | break; | 419 | break; |
| 406 | } | 420 | } |
| 407 | 421 | ||
| 408 | case PTRACE_GETEVENTMSG: | 422 | case PTRACE_GETEVENTMSG: |
| 409 | ret = put_user(child->ptrace_message, (unsigned int __user *) data); | 423 | ret = put_user(child->ptrace_message, (unsigned int __user *) data); |
| 410 | break; | 424 | break; |
| 425 | |||
| 426 | #ifdef CONFIG_ALTIVEC | ||
| 427 | case PTRACE_GETVRREGS: | ||
| 428 | /* Get the child altivec register state. */ | ||
| 429 | flush_altivec_to_thread(child); | ||
| 430 | ret = get_vrregs((unsigned long __user *)data, child); | ||
| 431 | break; | ||
| 432 | |||
| 433 | case PTRACE_SETVRREGS: | ||
| 434 | /* Set the child altivec register state. */ | ||
| 435 | flush_altivec_to_thread(child); | ||
| 436 | ret = set_vrregs(child, (unsigned long __user *)data); | ||
| 437 | break; | ||
| 438 | #endif | ||
| 411 | 439 | ||
| 412 | default: | 440 | default: |
| 413 | ret = ptrace_request(child, request, addr, data); | 441 | ret = ptrace_request(child, request, addr, data); |
diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c index 3c00f7bfc1b5..41b97dc9cc0a 100644 --- a/arch/ppc64/kernel/ras.c +++ b/arch/ppc64/kernel/ras.c | |||
| @@ -59,8 +59,6 @@ char mce_data_buf[RTAS_ERROR_LOG_MAX] | |||
| 59 | /* This is true if we are using the firmware NMI handler (typically LPAR) */ | 59 | /* This is true if we are using the firmware NMI handler (typically LPAR) */ |
| 60 | extern int fwnmi_active; | 60 | extern int fwnmi_active; |
| 61 | 61 | ||
| 62 | extern void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr); | ||
| 63 | |||
| 64 | static int ras_get_sensor_state_token; | 62 | static int ras_get_sensor_state_token; |
| 65 | static int ras_check_exception_token; | 63 | static int ras_check_exception_token; |
| 66 | 64 | ||
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c index 1dccadaddd1d..4a9719b48abe 100644 --- a/arch/ppc64/kernel/rtas_pci.c +++ b/arch/ppc64/kernel/rtas_pci.c | |||
| @@ -48,7 +48,7 @@ static int write_pci_config; | |||
| 48 | static int ibm_read_pci_config; | 48 | static int ibm_read_pci_config; |
| 49 | static int ibm_write_pci_config; | 49 | static int ibm_write_pci_config; |
| 50 | 50 | ||
| 51 | static int config_access_valid(struct device_node *dn, int where) | 51 | static int config_access_valid(struct pci_dn *dn, int where) |
| 52 | { | 52 | { |
| 53 | if (where < 256) | 53 | if (where < 256) |
| 54 | return 1; | 54 | return 1; |
| @@ -78,15 +78,17 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va | |||
| 78 | int returnval = -1; | 78 | int returnval = -1; |
| 79 | unsigned long buid, addr; | 79 | unsigned long buid, addr; |
| 80 | int ret; | 80 | int ret; |
| 81 | struct pci_dn *pdn; | ||
| 81 | 82 | ||
| 82 | if (!dn) | 83 | if (!dn || !dn->data) |
| 83 | return PCIBIOS_DEVICE_NOT_FOUND; | 84 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 84 | if (!config_access_valid(dn, where)) | 85 | pdn = dn->data; |
| 86 | if (!config_access_valid(pdn, where)) | ||
| 85 | return PCIBIOS_BAD_REGISTER_NUMBER; | 87 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 86 | 88 | ||
| 87 | addr = ((where & 0xf00) << 20) | (dn->busno << 16) | | 89 | addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | |
| 88 | (dn->devfn << 8) | (where & 0xff); | 90 | (pdn->devfn << 8) | (where & 0xff); |
| 89 | buid = dn->phb->buid; | 91 | buid = pdn->phb->buid; |
| 90 | if (buid) { | 92 | if (buid) { |
| 91 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, | 93 | ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, |
| 92 | addr, buid >> 32, buid & 0xffffffff, size); | 94 | addr, buid >> 32, buid & 0xffffffff, size); |
| @@ -98,8 +100,8 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va | |||
| 98 | if (ret) | 100 | if (ret) |
| 99 | return PCIBIOS_DEVICE_NOT_FOUND; | 101 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 100 | 102 | ||
| 101 | if (returnval == EEH_IO_ERROR_VALUE(size) | 103 | if (returnval == EEH_IO_ERROR_VALUE(size) && |
| 102 | && eeh_dn_check_failure (dn, NULL)) | 104 | eeh_dn_check_failure (dn, NULL)) |
| 103 | return PCIBIOS_DEVICE_NOT_FOUND; | 105 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 104 | 106 | ||
| 105 | return PCIBIOS_SUCCESSFUL; | 107 | return PCIBIOS_SUCCESSFUL; |
| @@ -118,24 +120,28 @@ static int rtas_pci_read_config(struct pci_bus *bus, | |||
| 118 | 120 | ||
| 119 | /* Search only direct children of the bus */ | 121 | /* Search only direct children of the bus */ |
| 120 | for (dn = busdn->child; dn; dn = dn->sibling) | 122 | for (dn = busdn->child; dn; dn = dn->sibling) |
| 121 | if (dn->devfn == devfn && of_device_available(dn)) | 123 | if (dn->data && PCI_DN(dn)->devfn == devfn |
| 124 | && of_device_available(dn)) | ||
| 122 | return rtas_read_config(dn, where, size, val); | 125 | return rtas_read_config(dn, where, size, val); |
| 126 | |||
| 123 | return PCIBIOS_DEVICE_NOT_FOUND; | 127 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 124 | } | 128 | } |
| 125 | 129 | ||
| 126 | static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) | 130 | int rtas_write_config(struct device_node *dn, int where, int size, u32 val) |
| 127 | { | 131 | { |
| 128 | unsigned long buid, addr; | 132 | unsigned long buid, addr; |
| 129 | int ret; | 133 | int ret; |
| 134 | struct pci_dn *pdn; | ||
| 130 | 135 | ||
| 131 | if (!dn) | 136 | if (!dn || !dn->data) |
| 132 | return PCIBIOS_DEVICE_NOT_FOUND; | 137 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 133 | if (!config_access_valid(dn, where)) | 138 | pdn = dn->data; |
| 139 | if (!config_access_valid(pdn, where)) | ||
| 134 | return PCIBIOS_BAD_REGISTER_NUMBER; | 140 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 135 | 141 | ||
| 136 | addr = ((where & 0xf00) << 20) | (dn->busno << 16) | | 142 | addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | |
| 137 | (dn->devfn << 8) | (where & 0xff); | 143 | (pdn->devfn << 8) | (where & 0xff); |
| 138 | buid = dn->phb->buid; | 144 | buid = pdn->phb->buid; |
| 139 | if (buid) { | 145 | if (buid) { |
| 140 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); | 146 | ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val); |
| 141 | } else { | 147 | } else { |
| @@ -161,7 +167,8 @@ static int rtas_pci_write_config(struct pci_bus *bus, | |||
| 161 | 167 | ||
| 162 | /* Search only direct children of the bus */ | 168 | /* Search only direct children of the bus */ |
| 163 | for (dn = busdn->child; dn; dn = dn->sibling) | 169 | for (dn = busdn->child; dn; dn = dn->sibling) |
| 164 | if (dn->devfn == devfn && of_device_available(dn)) | 170 | if (dn->data && PCI_DN(dn)->devfn == devfn |
| 171 | && of_device_available(dn)) | ||
| 165 | return rtas_write_config(dn, where, size, val); | 172 | return rtas_write_config(dn, where, size, val); |
| 166 | return PCIBIOS_DEVICE_NOT_FOUND; | 173 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 167 | } | 174 | } |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index d0bb68af0ea4..5ac48bd64891 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
| @@ -1064,8 +1064,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 1064 | #define PPC64_LINUX_FUNCTION 0x0f000000 | 1064 | #define PPC64_LINUX_FUNCTION 0x0f000000 |
| 1065 | #define PPC64_IPL_MESSAGE 0xc0000000 | 1065 | #define PPC64_IPL_MESSAGE 0xc0000000 |
| 1066 | #define PPC64_TERM_MESSAGE 0xb0000000 | 1066 | #define PPC64_TERM_MESSAGE 0xb0000000 |
| 1067 | #define PPC64_ATTN_MESSAGE 0xa0000000 | ||
| 1068 | #define PPC64_DUMP_MESSAGE 0xd0000000 | ||
| 1069 | 1067 | ||
| 1070 | static void ppc64_do_msg(unsigned int src, const char *msg) | 1068 | static void ppc64_do_msg(unsigned int src, const char *msg) |
| 1071 | { | 1069 | { |
| @@ -1093,20 +1091,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg) | |||
| 1093 | printk("[terminate]%04x %s\n", src, msg); | 1091 | printk("[terminate]%04x %s\n", src, msg); |
| 1094 | } | 1092 | } |
| 1095 | 1093 | ||
| 1096 | /* Print something that needs attention (device error, etc) */ | ||
| 1097 | void ppc64_attention_msg(unsigned int src, const char *msg) | ||
| 1098 | { | ||
| 1099 | ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg); | ||
| 1100 | printk("[attention]%04x %s\n", src, msg); | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | /* Print a dump progress message. */ | ||
| 1104 | void ppc64_dump_msg(unsigned int src, const char *msg) | ||
| 1105 | { | ||
| 1106 | ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg); | ||
| 1107 | printk("[dump]%04x %s\n", src, msg); | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | /* This should only be called on processor 0 during calibrate decr */ | 1094 | /* This should only be called on processor 0 during calibrate decr */ |
| 1111 | void __init setup_default_decr(void) | 1095 | void __init setup_default_decr(void) |
| 1112 | { | 1096 | { |
| @@ -1283,7 +1267,7 @@ void __init generic_find_legacy_serial_ports(u64 *physport, | |||
| 1283 | 1267 | ||
| 1284 | static struct platform_device serial_device = { | 1268 | static struct platform_device serial_device = { |
| 1285 | .name = "serial8250", | 1269 | .name = "serial8250", |
| 1286 | .id = 0, | 1270 | .id = PLAT8250_DEV_PLATFORM, |
| 1287 | .dev = { | 1271 | .dev = { |
| 1288 | .platform_data = serial_ports, | 1272 | .platform_data = serial_ports, |
| 1289 | }, | 1273 | }, |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index 49a79a55c32d..347112cca3c0 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
| @@ -550,6 +550,15 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 550 | /* Whee! Actually deliver the signal. */ | 550 | /* Whee! Actually deliver the signal. */ |
| 551 | if (TRAP(regs) == 0x0C00) | 551 | if (TRAP(regs) == 0x0C00) |
| 552 | syscall_restart(regs, &ka); | 552 | syscall_restart(regs, &ka); |
| 553 | |||
| 554 | /* | ||
| 555 | * Reenable the DABR before delivering the signal to | ||
| 556 | * user space. The DABR will have been cleared if it | ||
| 557 | * triggered inside the kernel. | ||
| 558 | */ | ||
| 559 | if (current->thread.dabr) | ||
| 560 | set_dabr(current->thread.dabr); | ||
| 561 | |||
| 553 | return handle_signal(signr, &ka, &info, oldset, regs); | 562 | return handle_signal(signr, &ka, &info, oldset, regs); |
| 554 | } | 563 | } |
| 555 | 564 | ||
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index 46f4d6cc7fc9..a8b7a5a56bb4 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c | |||
| @@ -970,6 +970,14 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) | |||
| 970 | newsp = regs->gpr[1]; | 970 | newsp = regs->gpr[1]; |
| 971 | newsp &= ~0xfUL; | 971 | newsp &= ~0xfUL; |
| 972 | 972 | ||
| 973 | /* | ||
| 974 | * Reenable the DABR before delivering the signal to | ||
| 975 | * user space. The DABR will have been cleared if it | ||
| 976 | * triggered inside the kernel. | ||
| 977 | */ | ||
| 978 | if (current->thread.dabr) | ||
| 979 | set_dabr(current->thread.dabr); | ||
| 980 | |||
| 973 | /* Whee! Actually deliver the signal. */ | 981 | /* Whee! Actually deliver the signal. */ |
| 974 | if (ka.sa.sa_flags & SA_SIGINFO) | 982 | if (ka.sa.sa_flags & SA_SIGINFO) |
| 975 | ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp); | 983 | ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp); |
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 214914a95a50..e93c13458910 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c | |||
| @@ -708,62 +708,9 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu | |||
| 708 | compat_ptr(ubuf)); | 708 | compat_ptr(ubuf)); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | #define IOBASE_BRIDGE_NUMBER 0 | ||
| 712 | #define IOBASE_MEMORY 1 | ||
| 713 | #define IOBASE_IO 2 | ||
| 714 | #define IOBASE_ISA_IO 3 | ||
| 715 | #define IOBASE_ISA_MEM 4 | ||
| 716 | |||
| 717 | asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) | 711 | asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) |
| 718 | { | 712 | { |
| 719 | #ifdef CONFIG_PCI | 713 | return sys_pciconfig_iobase(which, in_bus, in_devfn); |
| 720 | struct pci_controller* hose; | ||
| 721 | struct list_head *ln; | ||
| 722 | struct pci_bus *bus = NULL; | ||
| 723 | struct device_node *hose_node; | ||
| 724 | |||
| 725 | /* Argh ! Please forgive me for that hack, but that's the | ||
| 726 | * simplest way to get existing XFree to not lockup on some | ||
| 727 | * G5 machines... So when something asks for bus 0 io base | ||
| 728 | * (bus 0 is HT root), we return the AGP one instead. | ||
| 729 | */ | ||
| 730 | #ifdef CONFIG_PPC_PMAC | ||
| 731 | if (systemcfg->platform == PLATFORM_POWERMAC && | ||
| 732 | machine_is_compatible("MacRISC4")) | ||
| 733 | if (in_bus == 0) | ||
| 734 | in_bus = 0xf0; | ||
| 735 | #endif /* CONFIG_PPC_PMAC */ | ||
| 736 | |||
| 737 | /* That syscall isn't quite compatible with PCI domains, but it's | ||
| 738 | * used on pre-domains setup. We return the first match | ||
| 739 | */ | ||
| 740 | |||
| 741 | for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { | ||
| 742 | bus = pci_bus_b(ln); | ||
| 743 | if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate)) | ||
| 744 | break; | ||
| 745 | bus = NULL; | ||
| 746 | } | ||
| 747 | if (bus == NULL || bus->sysdata == NULL) | ||
| 748 | return -ENODEV; | ||
| 749 | |||
| 750 | hose_node = (struct device_node *)bus->sysdata; | ||
| 751 | hose = hose_node->phb; | ||
| 752 | |||
| 753 | switch (which) { | ||
| 754 | case IOBASE_BRIDGE_NUMBER: | ||
| 755 | return (long)hose->first_busno; | ||
| 756 | case IOBASE_MEMORY: | ||
| 757 | return (long)hose->pci_mem_offset; | ||
| 758 | case IOBASE_IO: | ||
| 759 | return (long)hose->io_base_phys; | ||
| 760 | case IOBASE_ISA_IO: | ||
| 761 | return (long)isa_io_base; | ||
| 762 | case IOBASE_ISA_MEM: | ||
| 763 | return -EINVAL; | ||
| 764 | } | ||
| 765 | #endif /* CONFIG_PCI */ | ||
| 766 | return -EOPNOTSUPP; | ||
| 767 | } | 714 | } |
| 768 | 715 | ||
| 769 | 716 | ||
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index a8cbb202b8cd..05f16633bd2c 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c | |||
| @@ -46,10 +46,6 @@ | |||
| 46 | 46 | ||
| 47 | extern unsigned long wall_jiffies; | 47 | extern unsigned long wall_jiffies; |
| 48 | 48 | ||
| 49 | void | ||
| 50 | check_bugs(void) | ||
| 51 | { | ||
| 52 | } | ||
| 53 | 49 | ||
| 54 | /* | 50 | /* |
| 55 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | 51 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. |
diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c index b6e3bca4102d..41ea09cb9ac7 100644 --- a/arch/ppc64/kernel/u3_iommu.c +++ b/arch/ppc64/kernel/u3_iommu.c | |||
| @@ -276,7 +276,7 @@ static void iommu_dev_setup_u3(struct pci_dev *dev) | |||
| 276 | dn = pci_device_to_OF_node(dev); | 276 | dn = pci_device_to_OF_node(dev); |
| 277 | 277 | ||
| 278 | if (dn) | 278 | if (dn) |
| 279 | dn->iommu_table = &iommu_table_u3; | 279 | PCI_DN(dn)->iommu_table = &iommu_table_u3; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void iommu_bus_setup_u3(struct pci_bus *bus) | 282 | static void iommu_bus_setup_u3(struct pci_bus *bus) |
| @@ -291,7 +291,7 @@ static void iommu_bus_setup_u3(struct pci_bus *bus) | |||
| 291 | dn = pci_bus_to_OF_node(bus); | 291 | dn = pci_bus_to_OF_node(bus); |
| 292 | 292 | ||
| 293 | if (dn) | 293 | if (dn) |
| 294 | dn->iommu_table = &iommu_table_u3; | 294 | PCI_DN(dn)->iommu_table = &iommu_table_u3; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | static void iommu_dev_setup_null(struct pci_dev *dev) { } | 297 | static void iommu_dev_setup_null(struct pci_dev *dev) { } |
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c index ed6766e21f5a..d49c3613c8ec 100644 --- a/arch/ppc64/kernel/udbg.c +++ b/arch/ppc64/kernel/udbg.c | |||
| @@ -158,14 +158,20 @@ static struct console udbg_console = { | |||
| 158 | .index = -1, | 158 | .index = -1, |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | static int early_console_initialized; | ||
| 162 | |||
| 161 | void __init disable_early_printk(void) | 163 | void __init disable_early_printk(void) |
| 162 | { | 164 | { |
| 165 | if (!early_console_initialized) | ||
| 166 | return; | ||
| 163 | unregister_console(&udbg_console); | 167 | unregister_console(&udbg_console); |
| 168 | early_console_initialized = 0; | ||
| 164 | } | 169 | } |
| 165 | 170 | ||
| 166 | /* called by setup_system */ | 171 | /* called by setup_system */ |
| 167 | void register_early_udbg_console(void) | 172 | void register_early_udbg_console(void) |
| 168 | { | 173 | { |
| 174 | early_console_initialized = 1; | ||
| 169 | register_console(&udbg_console); | 175 | register_console(&udbg_console); |
| 170 | } | 176 | } |
| 171 | 177 | ||
diff --git a/arch/ppc64/kernel/vdso32/cacheflush.S b/arch/ppc64/kernel/vdso32/cacheflush.S index 0ed7ea721715..c8db993574ee 100644 --- a/arch/ppc64/kernel/vdso32/cacheflush.S +++ b/arch/ppc64/kernel/vdso32/cacheflush.S | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/ppc_asm.h> | 14 | #include <asm/ppc_asm.h> |
| 15 | #include <asm/vdso.h> | 15 | #include <asm/vdso.h> |
| 16 | #include <asm/offsets.h> | 16 | #include <asm/asm-offsets.h> |
| 17 | 17 | ||
| 18 | .text | 18 | .text |
| 19 | 19 | ||
diff --git a/arch/ppc64/kernel/vdso32/datapage.S b/arch/ppc64/kernel/vdso32/datapage.S index 29b6bd32e1f1..4f4eb0be3992 100644 --- a/arch/ppc64/kernel/vdso32/datapage.S +++ b/arch/ppc64/kernel/vdso32/datapage.S | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/ppc_asm.h> | 14 | #include <asm/ppc_asm.h> |
| 15 | #include <asm/offsets.h> | 15 | #include <asm/asm-offsets.h> |
| 16 | #include <asm/unistd.h> | 16 | #include <asm/unistd.h> |
| 17 | #include <asm/vdso.h> | 17 | #include <asm/vdso.h> |
| 18 | 18 | ||
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S index 2b48bf1fb109..07f1c1c650c8 100644 --- a/arch/ppc64/kernel/vdso32/gettimeofday.S +++ b/arch/ppc64/kernel/vdso32/gettimeofday.S | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/ppc_asm.h> | 14 | #include <asm/ppc_asm.h> |
| 15 | #include <asm/vdso.h> | 15 | #include <asm/vdso.h> |
| 16 | #include <asm/offsets.h> | 16 | #include <asm/asm-offsets.h> |
| 17 | #include <asm/unistd.h> | 17 | #include <asm/unistd.h> |
| 18 | 18 | ||
| 19 | .text | 19 | .text |
diff --git a/arch/ppc64/kernel/vdso64/cacheflush.S b/arch/ppc64/kernel/vdso64/cacheflush.S index e0725b7b7003..d4a0ad28d534 100644 --- a/arch/ppc64/kernel/vdso64/cacheflush.S +++ b/arch/ppc64/kernel/vdso64/cacheflush.S | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/ppc_asm.h> | 14 | #include <asm/ppc_asm.h> |
| 15 | #include <asm/vdso.h> | 15 | #include <asm/vdso.h> |
| 16 | #include <asm/offsets.h> | 16 | #include <asm/asm-offsets.h> |
| 17 | 17 | ||
| 18 | .text | 18 | .text |
| 19 | 19 | ||
diff --git a/arch/ppc64/kernel/vdso64/datapage.S b/arch/ppc64/kernel/vdso64/datapage.S index 18afd971c9d9..ed6e599ae824 100644 --- a/arch/ppc64/kernel/vdso64/datapage.S +++ b/arch/ppc64/kernel/vdso64/datapage.S | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
| 13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
| 14 | #include <asm/ppc_asm.h> | 14 | #include <asm/ppc_asm.h> |
| 15 | #include <asm/offsets.h> | 15 | #include <asm/asm-offsets.h> |
| 16 | #include <asm/unistd.h> | 16 | #include <asm/unistd.h> |
| 17 | #include <asm/vdso.h> | 17 | #include <asm/vdso.h> |
| 18 | 18 | ||
diff --git a/arch/ppc64/kernel/vdso64/gettimeofday.S b/arch/ppc64/kernel/vdso64/gettimeofday.S index ed3f970ff05e..f6df8028570a 100644 --- a/arch/ppc64/kernel/vdso64/gettimeofday.S +++ b/arch/ppc64/kernel/vdso64/gettimeofday.S | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <asm/processor.h> | 14 | #include <asm/processor.h> |
| 15 | #include <asm/ppc_asm.h> | 15 | #include <asm/ppc_asm.h> |
| 16 | #include <asm/vdso.h> | 16 | #include <asm/vdso.h> |
| 17 | #include <asm/offsets.h> | 17 | #include <asm/asm-offsets.h> |
| 18 | 18 | ||
| 19 | .text | 19 | .text |
| 20 | /* | 20 | /* |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index d9dc6f28d050..daf93885dcfa 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
| @@ -38,7 +38,7 @@ static void xics_mask_and_ack_irq(unsigned int irq); | |||
| 38 | static void xics_end_irq(unsigned int irq); | 38 | static void xics_end_irq(unsigned int irq); |
| 39 | static void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask); | 39 | static void xics_set_affinity(unsigned int irq_nr, cpumask_t cpumask); |
| 40 | 40 | ||
| 41 | struct hw_interrupt_type xics_pic = { | 41 | static struct hw_interrupt_type xics_pic = { |
| 42 | .typename = " XICS ", | 42 | .typename = " XICS ", |
| 43 | .startup = xics_startup, | 43 | .startup = xics_startup, |
| 44 | .enable = xics_enable_irq, | 44 | .enable = xics_enable_irq, |
| @@ -48,7 +48,7 @@ struct hw_interrupt_type xics_pic = { | |||
| 48 | .set_affinity = xics_set_affinity | 48 | .set_affinity = xics_set_affinity |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | struct hw_interrupt_type xics_8259_pic = { | 51 | static struct hw_interrupt_type xics_8259_pic = { |
| 52 | .typename = " XICS/8259", | 52 | .typename = " XICS/8259", |
| 53 | .ack = xics_mask_and_ack_irq, | 53 | .ack = xics_mask_and_ack_irq, |
| 54 | }; | 54 | }; |
| @@ -89,9 +89,8 @@ static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; | |||
| 89 | static int xics_irq_8259_cascade = 0; | 89 | static int xics_irq_8259_cascade = 0; |
| 90 | static int xics_irq_8259_cascade_real = 0; | 90 | static int xics_irq_8259_cascade_real = 0; |
| 91 | static unsigned int default_server = 0xFF; | 91 | static unsigned int default_server = 0xFF; |
| 92 | /* also referenced in smp.c... */ | 92 | static unsigned int default_distrib_server = 0; |
| 93 | unsigned int default_distrib_server = 0; | 93 | static unsigned int interrupt_server_size = 8; |
| 94 | unsigned int interrupt_server_size = 8; | ||
| 95 | 94 | ||
| 96 | /* | 95 | /* |
| 97 | * XICS only has a single IPI, so encode the messages per CPU | 96 | * XICS only has a single IPI, so encode the messages per CPU |
| @@ -99,10 +98,10 @@ unsigned int interrupt_server_size = 8; | |||
| 99 | struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | 98 | struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; |
| 100 | 99 | ||
| 101 | /* RTAS service tokens */ | 100 | /* RTAS service tokens */ |
| 102 | int ibm_get_xive; | 101 | static int ibm_get_xive; |
| 103 | int ibm_set_xive; | 102 | static int ibm_set_xive; |
| 104 | int ibm_int_on; | 103 | static int ibm_int_on; |
| 105 | int ibm_int_off; | 104 | static int ibm_int_off; |
| 106 | 105 | ||
| 107 | typedef struct { | 106 | typedef struct { |
| 108 | int (*xirr_info_get)(int cpu); | 107 | int (*xirr_info_get)(int cpu); |
| @@ -284,16 +283,17 @@ static void xics_enable_irq(unsigned int virq) | |||
| 284 | call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, | 283 | call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, |
| 285 | DEFAULT_PRIORITY); | 284 | DEFAULT_PRIORITY); |
| 286 | if (call_status != 0) { | 285 | if (call_status != 0) { |
| 287 | printk(KERN_ERR "xics_enable_irq: irq=%d: ibm_set_xive " | 286 | printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive " |
| 288 | "returned %x\n", irq, call_status); | 287 | "returned %d\n", irq, call_status); |
| 288 | printk("set_xive %x, server %x\n", ibm_set_xive, server); | ||
| 289 | return; | 289 | return; |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | /* Now unmask the interrupt (often a no-op) */ | 292 | /* Now unmask the interrupt (often a no-op) */ |
| 293 | call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); | 293 | call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); |
| 294 | if (call_status != 0) { | 294 | if (call_status != 0) { |
| 295 | printk(KERN_ERR "xics_enable_irq: irq=%d: ibm_int_on " | 295 | printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on " |
| 296 | "returned %x\n", irq, call_status); | 296 | "returned %d\n", irq, call_status); |
| 297 | return; | 297 | return; |
| 298 | } | 298 | } |
| 299 | } | 299 | } |
| @@ -308,8 +308,8 @@ static void xics_disable_real_irq(unsigned int irq) | |||
| 308 | 308 | ||
| 309 | call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); | 309 | call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); |
| 310 | if (call_status != 0) { | 310 | if (call_status != 0) { |
| 311 | printk(KERN_ERR "xics_disable_real_irq: irq=%d: " | 311 | printk(KERN_ERR "xics_disable_real_irq: irq=%u: " |
| 312 | "ibm_int_off returned %x\n", irq, call_status); | 312 | "ibm_int_off returned %d\n", irq, call_status); |
| 313 | return; | 313 | return; |
| 314 | } | 314 | } |
| 315 | 315 | ||
| @@ -317,8 +317,8 @@ static void xics_disable_real_irq(unsigned int irq) | |||
| 317 | /* Have to set XIVE to 0xff to be able to remove a slot */ | 317 | /* Have to set XIVE to 0xff to be able to remove a slot */ |
| 318 | call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff); | 318 | call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff); |
| 319 | if (call_status != 0) { | 319 | if (call_status != 0) { |
| 320 | printk(KERN_ERR "xics_disable_irq: irq=%d: ibm_set_xive(0xff)" | 320 | printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)" |
| 321 | " returned %x\n", irq, call_status); | 321 | " returned %d\n", irq, call_status); |
| 322 | return; | 322 | return; |
| 323 | } | 323 | } |
| 324 | } | 324 | } |
| @@ -380,7 +380,7 @@ int xics_get_irq(struct pt_regs *regs) | |||
| 380 | if (irq == NO_IRQ) | 380 | if (irq == NO_IRQ) |
| 381 | irq = real_irq_to_virt_slowpath(vec); | 381 | irq = real_irq_to_virt_slowpath(vec); |
| 382 | if (irq == NO_IRQ) { | 382 | if (irq == NO_IRQ) { |
| 383 | printk(KERN_ERR "Interrupt %d (real) is invalid," | 383 | printk(KERN_ERR "Interrupt %u (real) is invalid," |
| 384 | " disabling it.\n", vec); | 384 | " disabling it.\n", vec); |
| 385 | xics_disable_real_irq(vec); | 385 | xics_disable_real_irq(vec); |
| 386 | } else | 386 | } else |
| @@ -622,7 +622,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | |||
| 622 | status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); | 622 | status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); |
| 623 | 623 | ||
| 624 | if (status) { | 624 | if (status) { |
| 625 | printk(KERN_ERR "xics_set_affinity: irq=%d ibm,get-xive " | 625 | printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive " |
| 626 | "returns %d\n", irq, status); | 626 | "returns %d\n", irq, status); |
| 627 | return; | 627 | return; |
| 628 | } | 628 | } |
| @@ -641,7 +641,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | |||
| 641 | irq, newmask, xics_status[1]); | 641 | irq, newmask, xics_status[1]); |
| 642 | 642 | ||
| 643 | if (status) { | 643 | if (status) { |
| 644 | printk(KERN_ERR "xics_set_affinity: irq=%d ibm,set-xive " | 644 | printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " |
| 645 | "returns %d\n", irq, status); | 645 | "returns %d\n", irq, status); |
| 646 | return; | 646 | return; |
| 647 | } | 647 | } |
| @@ -720,7 +720,7 @@ void xics_migrate_irqs_away(void) | |||
| 720 | 720 | ||
| 721 | status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); | 721 | status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); |
| 722 | if (status) { | 722 | if (status) { |
| 723 | printk(KERN_ERR "migrate_irqs_away: irq=%d " | 723 | printk(KERN_ERR "migrate_irqs_away: irq=%u " |
| 724 | "ibm,get-xive returns %d\n", | 724 | "ibm,get-xive returns %d\n", |
| 725 | virq, status); | 725 | virq, status); |
| 726 | goto unlock; | 726 | goto unlock; |
| @@ -734,7 +734,7 @@ void xics_migrate_irqs_away(void) | |||
| 734 | if (xics_status[0] != get_hard_smp_processor_id(cpu)) | 734 | if (xics_status[0] != get_hard_smp_processor_id(cpu)) |
| 735 | goto unlock; | 735 | goto unlock; |
| 736 | 736 | ||
| 737 | printk(KERN_WARNING "IRQ %d affinity broken off cpu %u\n", | 737 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", |
| 738 | virq, cpu); | 738 | virq, cpu); |
| 739 | 739 | ||
| 740 | /* Reset affinity to all cpus */ | 740 | /* Reset affinity to all cpus */ |
diff --git a/arch/ppc64/lib/dec_and_lock.c b/arch/ppc64/lib/dec_and_lock.c index 6e8d8591708c..7b9d4da5cf92 100644 --- a/arch/ppc64/lib/dec_and_lock.c +++ b/arch/ppc64/lib/dec_and_lock.c | |||
| @@ -20,14 +20,7 @@ | |||
| 20 | * has a cmpxchg, and where atomic->value is an int holding | 20 | * has a cmpxchg, and where atomic->value is an int holding |
| 21 | * the value of the atomic (i.e. the high bits aren't used | 21 | * the value of the atomic (i.e. the high bits aren't used |
| 22 | * for a lock or anything like that). | 22 | * for a lock or anything like that). |
| 23 | * | ||
| 24 | * N.B. ATOMIC_DEC_AND_LOCK gets defined in include/linux/spinlock.h | ||
| 25 | * if spinlocks are empty and thus atomic_dec_and_lock is defined | ||
| 26 | * to be atomic_dec_and_test - in that case we don't need it | ||
| 27 | * defined here as well. | ||
| 28 | */ | 23 | */ |
| 29 | |||
| 30 | #ifndef ATOMIC_DEC_AND_LOCK | ||
| 31 | int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) | 24 | int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) |
| 32 | { | 25 | { |
| 33 | int counter; | 26 | int counter; |
| @@ -52,4 +45,3 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) | |||
| 52 | } | 45 | } |
| 53 | 46 | ||
| 54 | EXPORT_SYMBOL(_atomic_dec_and_lock); | 47 | EXPORT_SYMBOL(_atomic_dec_and_lock); |
| 55 | #endif /* ATOMIC_DEC_AND_LOCK */ | ||
diff --git a/arch/ppc64/lib/locks.c b/arch/ppc64/lib/locks.c index ef70ef91abe2..033643ab69e0 100644 --- a/arch/ppc64/lib/locks.c +++ b/arch/ppc64/lib/locks.c | |||
| @@ -23,12 +23,12 @@ | |||
| 23 | /* waiting for a spinlock... */ | 23 | /* waiting for a spinlock... */ |
| 24 | #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) | 24 | #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) |
| 25 | 25 | ||
| 26 | void __spin_yield(spinlock_t *lock) | 26 | void __spin_yield(raw_spinlock_t *lock) |
| 27 | { | 27 | { |
| 28 | unsigned int lock_value, holder_cpu, yield_count; | 28 | unsigned int lock_value, holder_cpu, yield_count; |
| 29 | struct paca_struct *holder_paca; | 29 | struct paca_struct *holder_paca; |
| 30 | 30 | ||
| 31 | lock_value = lock->lock; | 31 | lock_value = lock->slock; |
| 32 | if (lock_value == 0) | 32 | if (lock_value == 0) |
| 33 | return; | 33 | return; |
| 34 | holder_cpu = lock_value & 0xffff; | 34 | holder_cpu = lock_value & 0xffff; |
| @@ -38,7 +38,7 @@ void __spin_yield(spinlock_t *lock) | |||
| 38 | if ((yield_count & 1) == 0) | 38 | if ((yield_count & 1) == 0) |
| 39 | return; /* virtual cpu is currently running */ | 39 | return; /* virtual cpu is currently running */ |
| 40 | rmb(); | 40 | rmb(); |
| 41 | if (lock->lock != lock_value) | 41 | if (lock->slock != lock_value) |
| 42 | return; /* something has changed */ | 42 | return; /* something has changed */ |
| 43 | #ifdef CONFIG_PPC_ISERIES | 43 | #ifdef CONFIG_PPC_ISERIES |
| 44 | HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, | 44 | HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, |
| @@ -54,7 +54,7 @@ void __spin_yield(spinlock_t *lock) | |||
| 54 | * This turns out to be the same for read and write locks, since | 54 | * This turns out to be the same for read and write locks, since |
| 55 | * we only know the holder if it is write-locked. | 55 | * we only know the holder if it is write-locked. |
| 56 | */ | 56 | */ |
| 57 | void __rw_yield(rwlock_t *rw) | 57 | void __rw_yield(raw_rwlock_t *rw) |
| 58 | { | 58 | { |
| 59 | int lock_value; | 59 | int lock_value; |
| 60 | unsigned int holder_cpu, yield_count; | 60 | unsigned int holder_cpu, yield_count; |
| @@ -82,9 +82,9 @@ void __rw_yield(rwlock_t *rw) | |||
| 82 | } | 82 | } |
| 83 | #endif | 83 | #endif |
| 84 | 84 | ||
| 85 | void spin_unlock_wait(spinlock_t *lock) | 85 | void __raw_spin_unlock_wait(raw_spinlock_t *lock) |
| 86 | { | 86 | { |
| 87 | while (lock->lock) { | 87 | while (lock->slock) { |
| 88 | HMT_low(); | 88 | HMT_low(); |
| 89 | if (SHARED_PROCESSOR) | 89 | if (SHARED_PROCESSOR) |
| 90 | __spin_yield(lock); | 90 | __spin_yield(lock); |
| @@ -92,4 +92,4 @@ void spin_unlock_wait(spinlock_t *lock) | |||
| 92 | HMT_medium(); | 92 | HMT_medium(); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | EXPORT_SYMBOL(spin_unlock_wait); | 95 | EXPORT_SYMBOL(__raw_spin_unlock_wait); |
diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c index 772f0714a5b7..7fbc68bbb739 100644 --- a/arch/ppc64/mm/fault.c +++ b/arch/ppc64/mm/fault.c | |||
| @@ -77,6 +77,28 @@ static int store_updates_sp(struct pt_regs *regs) | |||
| 77 | return 0; | 77 | return 0; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static void do_dabr(struct pt_regs *regs, unsigned long error_code) | ||
| 81 | { | ||
| 82 | siginfo_t info; | ||
| 83 | |||
| 84 | if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, | ||
| 85 | 11, SIGSEGV) == NOTIFY_STOP) | ||
| 86 | return; | ||
| 87 | |||
| 88 | if (debugger_dabr_match(regs)) | ||
| 89 | return; | ||
| 90 | |||
| 91 | /* Clear the DABR */ | ||
| 92 | set_dabr(0); | ||
| 93 | |||
| 94 | /* Deliver the signal to userspace */ | ||
| 95 | info.si_signo = SIGTRAP; | ||
| 96 | info.si_errno = 0; | ||
| 97 | info.si_code = TRAP_HWBKPT; | ||
| 98 | info.si_addr = (void __user *)regs->nip; | ||
| 99 | force_sig_info(SIGTRAP, &info, current); | ||
| 100 | } | ||
| 101 | |||
| 80 | /* | 102 | /* |
| 81 | * The error_code parameter is | 103 | * The error_code parameter is |
| 82 | * - DSISR for a non-SLB data access fault, | 104 | * - DSISR for a non-SLB data access fault, |
| @@ -111,12 +133,9 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 111 | if (!user_mode(regs) && (address >= TASK_SIZE)) | 133 | if (!user_mode(regs) && (address >= TASK_SIZE)) |
| 112 | return SIGSEGV; | 134 | return SIGSEGV; |
| 113 | 135 | ||
| 114 | if (error_code & DSISR_DABRMATCH) { | 136 | if (error_code & DSISR_DABRMATCH) { |
| 115 | if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, | 137 | do_dabr(regs, error_code); |
| 116 | 11, SIGSEGV) == NOTIFY_STOP) | 138 | return 0; |
| 117 | return 0; | ||
| 118 | if (debugger_dabr_match(regs)) | ||
| 119 | return 0; | ||
| 120 | } | 139 | } |
| 121 | 140 | ||
| 122 | if (in_atomic() || mm == NULL) { | 141 | if (in_atomic() || mm == NULL) { |
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S index 35eb49e1b890..ee5a5d36bfa8 100644 --- a/arch/ppc64/mm/hash_low.S +++ b/arch/ppc64/mm/hash_low.S | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
| 17 | #include <asm/types.h> | 17 | #include <asm/types.h> |
| 18 | #include <asm/ppc_asm.h> | 18 | #include <asm/ppc_asm.h> |
| 19 | #include <asm/offsets.h> | 19 | #include <asm/asm-offsets.h> |
| 20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
| 21 | 21 | ||
| 22 | .text | 22 | .text |
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index a14ab87df491..c2157c9c3acb 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c | |||
| @@ -554,12 +554,12 @@ void __init do_init_bootmem(void) | |||
| 554 | * present. | 554 | * present. |
| 555 | */ | 555 | */ |
| 556 | for (i=0; i < lmb.memory.cnt; i++) | 556 | for (i=0; i < lmb.memory.cnt; i++) |
| 557 | free_bootmem(lmb_start_pfn(&lmb.memory, i), | 557 | free_bootmem(lmb.memory.region[i].base, |
| 558 | lmb_size_bytes(&lmb.memory, i)); | 558 | lmb_size_bytes(&lmb.memory, i)); |
| 559 | 559 | ||
| 560 | /* reserve the sections we're already using */ | 560 | /* reserve the sections we're already using */ |
| 561 | for (i=0; i < lmb.reserved.cnt; i++) | 561 | for (i=0; i < lmb.reserved.cnt; i++) |
| 562 | reserve_bootmem(lmb_start_pfn(&lmb.reserved, i), | 562 | reserve_bootmem(lmb.reserved.region[i].base, |
| 563 | lmb_size_bytes(&lmb.reserved, i)); | 563 | lmb_size_bytes(&lmb.reserved, i)); |
| 564 | 564 | ||
| 565 | for (i=0; i < lmb.memory.cnt; i++) | 565 | for (i=0; i < lmb.memory.cnt; i++) |
diff --git a/arch/ppc64/mm/slb_low.S b/arch/ppc64/mm/slb_low.S index 698d6b9ed6d1..a3a03da503bc 100644 --- a/arch/ppc64/mm/slb_low.S +++ b/arch/ppc64/mm/slb_low.S | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
| 22 | #include <asm/mmu.h> | 22 | #include <asm/mmu.h> |
| 23 | #include <asm/ppc_asm.h> | 23 | #include <asm/ppc_asm.h> |
| 24 | #include <asm/offsets.h> | 24 | #include <asm/asm-offsets.h> |
| 25 | #include <asm/cputable.h> | 25 | #include <asm/cputable.h> |
| 26 | 26 | ||
| 27 | /* void slb_allocate(unsigned long ea); | 27 | /* void slb_allocate(unsigned long ea); |
diff --git a/arch/ppc64/xmon/privinst.h b/arch/ppc64/xmon/privinst.h index 183c3e400258..02eb40dac0b3 100644 --- a/arch/ppc64/xmon/privinst.h +++ b/arch/ppc64/xmon/privinst.h | |||
| @@ -46,7 +46,6 @@ GSETSPR(287, pvr) | |||
| 46 | GSETSPR(1008, hid0) | 46 | GSETSPR(1008, hid0) |
| 47 | GSETSPR(1009, hid1) | 47 | GSETSPR(1009, hid1) |
| 48 | GSETSPR(1010, iabr) | 48 | GSETSPR(1010, iabr) |
| 49 | GSETSPR(1013, dabr) | ||
| 50 | GSETSPR(1023, pir) | 49 | GSETSPR(1023, pir) |
| 51 | 50 | ||
| 52 | static inline void store_inst(void *p) | 51 | static inline void store_inst(void *p) |
diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index 45908b10acd3..74e63a886a69 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c | |||
| @@ -586,6 +586,8 @@ int xmon_dabr_match(struct pt_regs *regs) | |||
| 586 | { | 586 | { |
| 587 | if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) | 587 | if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) |
| 588 | return 0; | 588 | return 0; |
| 589 | if (dabr.enabled == 0) | ||
| 590 | return 0; | ||
| 589 | xmon_core(regs, 0); | 591 | xmon_core(regs, 0); |
| 590 | return 1; | 592 | return 1; |
| 591 | } | 593 | } |
| @@ -628,20 +630,6 @@ int xmon_fault_handler(struct pt_regs *regs) | |||
| 628 | return 0; | 630 | return 0; |
| 629 | } | 631 | } |
| 630 | 632 | ||
| 631 | /* On systems with a hypervisor, we can't set the DABR | ||
| 632 | (data address breakpoint register) directly. */ | ||
| 633 | static void set_controlled_dabr(unsigned long val) | ||
| 634 | { | ||
| 635 | #ifdef CONFIG_PPC_PSERIES | ||
| 636 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR) { | ||
| 637 | int rc = plpar_hcall_norets(H_SET_DABR, val); | ||
| 638 | if (rc != H_Success) | ||
| 639 | xmon_printf("Warning: setting DABR failed (%d)\n", rc); | ||
| 640 | } else | ||
| 641 | #endif | ||
| 642 | set_dabr(val); | ||
| 643 | } | ||
| 644 | |||
| 645 | static struct bpt *at_breakpoint(unsigned long pc) | 633 | static struct bpt *at_breakpoint(unsigned long pc) |
| 646 | { | 634 | { |
| 647 | int i; | 635 | int i; |
| @@ -728,7 +716,7 @@ static void insert_bpts(void) | |||
| 728 | static void insert_cpu_bpts(void) | 716 | static void insert_cpu_bpts(void) |
| 729 | { | 717 | { |
| 730 | if (dabr.enabled) | 718 | if (dabr.enabled) |
| 731 | set_controlled_dabr(dabr.address | (dabr.enabled & 7)); | 719 | set_dabr(dabr.address | (dabr.enabled & 7)); |
| 732 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) | 720 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) |
| 733 | set_iabr(iabr->address | 721 | set_iabr(iabr->address |
| 734 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); | 722 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); |
| @@ -756,7 +744,7 @@ static void remove_bpts(void) | |||
| 756 | 744 | ||
| 757 | static void remove_cpu_bpts(void) | 745 | static void remove_cpu_bpts(void) |
| 758 | { | 746 | { |
| 759 | set_controlled_dabr(0); | 747 | set_dabr(0); |
| 760 | if (cpu_has_feature(CPU_FTR_IABR)) | 748 | if (cpu_has_feature(CPU_FTR_IABR)) |
| 761 | set_iabr(0); | 749 | set_iabr(0); |
| 762 | } | 750 | } |
