diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index d65810108bc3..11899f06bf06 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -58,11 +58,11 @@ config 6xx
help
There are four types of PowerPC chips supported. The more common
types (601, 603, 604, 740, 750, 7400), the Motorola embedded
- versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM embedded
- versions (403 and 405) and the high end 64 bit Power processors
- (POWER 3, POWER4, and IBM 970 also known as G5)
+ versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM
+ embedded versions (403 and 405) and the POWER3 processor.
+ (For support for more recent 64-bit processors, set ARCH=powerpc.)
Unless you are building a kernel for one of the embedded processor
- systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
+ systems or a POWER3-based IBM RS/6000, choose 6xx.
Note that the kernel runs in 32-bit mode even on 64-bit chips.
Also note that because the 52xx, 82xx, & 83xx family has a 603e core,
specific support for that chipset is asked later on.
@@ -77,10 +77,6 @@ config POWER3
select PPC_FPU
bool "POWER3"
-config POWER4
- select PPC_FPU
- bool "POWER4 and 970 (G5)"
-
config 8xx
bool "8xx"
@@ -123,7 +119,7 @@ config PHYS_64BIT
config ALTIVEC
bool "AltiVec Support"
- depends on 6xx || POWER4
+ depends on 6xx
depends on !8260 && !83xx
---help---
This option enables kernel support for the Altivec extensions to the
@@ -235,18 +231,9 @@ config KEXEC
source "drivers/cpufreq/Kconfig"
-config CPU_FREQ_PMAC
- bool "Support for Apple PowerBooks"
- depends on CPU_FREQ && ADB_PMU
- select CPU_FREQ_TABLE
- help
- This adds support for frequency switching on Apple PowerBooks,
- this currently includes some models of iBook & Titanium
- PowerBook.
-
config PPC601_SYNC_FIX
bool "Workarounds for PPC601 bugs"
- depends on 6xx && (PPC_PREP || PPC_PMAC)
+ depends on 6xx && PPC_PREP
help
Some versions of the PPC601 (the first PowerPC chip) have bugs which
mean that extra synchronization instructions are required near
@@ -258,26 +245,17 @@ config PPC601_SYNC_FIX
If in doubt, say Y here.
-config HOTPLUG_CPU
- bool "Support for enabling/disabling CPUs"
- depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PMAC
- ---help---
- Say Y here to be able to disable and re-enable individual
- CPUs at runtime on SMP machines.
-
- Say N if you are unsure.
-
source arch/ppc/platforms/4xx/Kconfig
source arch/ppc/platforms/85xx/Kconfig
config PPC64BRIDGE
bool
- depends on POWER3 || POWER4
+ depends on POWER3
default y
config PPC_STD_MMU
bool
- depends on 6xx || POWER3 || POWER4
+ depends on 6xx || POWER3
default y
config NOT_COHERENT_CACHE
@@ -505,7 +483,7 @@ endchoice
choice
prompt "Machine Type"
- depends on 6xx || POWER3 || POWER4
+ depends on 6xx || POWER3
default PPC_MULTIPLATFORM
---help---
Linux currently supports several different kinds of PowerPC-based
@@ -516,11 +494,15 @@ choice
Platform) machines (including all of the recent IBM RS/6000 and
pSeries machines), and several embedded PowerPC systems containing
4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the
- default option is to build a kernel which works on the first three.
+ default option is to build a kernel which works on PReP and CHRP.
- Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or
- pSeries machine, a Power Macintosh (including iMacs, iBooks and
- Powerbooks), or a PReP machine.
+ Note that support for Apple machines is now only available with
+ ARCH=powerpc, and has been removed from this menu. If you wish
+ to build a kernel for an Apple machine, exit this configuration
+ process and re-run it with ARCH=powerpc.
+
+ Select CHRP/PReP if configuring for an IBM RS/6000 or
+ pSeries machine, or a PReP machine.
Select Gemini if configuring for a Synergy Microsystems' Gemini
series Single Board Computer. More information is available at:
@@ -530,7 +512,7 @@ choice
available at: .
config PPC_MULTIPLATFORM
- bool "CHRP/PowerMac/PReP"
+ bool "CHRP/PReP"
config APUS
bool "Amiga-APUS"
@@ -768,25 +750,14 @@ config CPM2
on it (826x, 827x, 8560).
config PPC_CHRP
- bool
+ bool "Support for CHRP (Common Hardware Reference Platform) machines"
depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI
default y
-config PPC_PMAC
- bool
- depends on PPC_MULTIPLATFORM
- select PPC_INDIRECT_PCI
- default y
-
-config PPC_PMAC64
- bool
- depends on PPC_PMAC && POWER4
- default y
-
config PPC_PREP
- bool
+ bool "Support for PReP (PowerPC Reference Platform) machines"
depends on PPC_MULTIPLATFORM
select PPC_I8259
select PPC_INDIRECT_PCI
@@ -794,7 +765,7 @@ config PPC_PREP
config PPC_OF
bool
- depends on PPC_PMAC || PPC_CHRP
+ depends on PPC_CHRP
default y
config PPC_GEN550
@@ -1166,7 +1137,7 @@ config ISA
config GENERIC_ISA_DMA
bool
- depends on POWER3 || POWER4 || 6xx && !CPM2
+ depends on POWER3 || 6xx && !CPM2
default y
config PPC_I8259
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 995f89bb049c..efd8ce515d5f 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -18,7 +18,7 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
bootdir-y := simple
bootdir-$(CONFIG_PPC_OF) += openfirmware
subdir-y := lib common images
-subdir-$(CONFIG_PPC_OF) += of1275
+subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275
# for cleaning
subdir- += simple openfirmware
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
index 83a6433459ce..2a411ec2e650 100644
--- a/arch/ppc/boot/openfirmware/Makefile
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -21,26 +21,16 @@ bootlib := $(boot)/lib
of1275 := $(boot)/of1275
images := $(boot)/images
-OBJCOPY_ARGS := -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
-COFF_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \
- -Bstatic
CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
-NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000
COMMONOBJS := start.o misc.o common.o
-COFFOBJS := coffcrt0.o $(COMMONOBJS) coffmain.o
CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o
-NEWWORLDOBJS := crt0.o $(COMMONOBJS) newworldmain.o
-targets := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o
-COFFOBJS := $(addprefix $(obj)/, $(COFFOBJS))
+targets := $(CHRPOBJS) dummy.o
CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS))
-NEWWORLDOBJS := $(addprefix $(obj)/, $(NEWWORLDOBJS))
LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
-HACKCOFF := $(utils)/hack-coff
-
ifdef CONFIG_SMP
END := .smp
endif
@@ -72,56 +62,11 @@ targets += image.initrd.o
$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE
$(call if_changed,genimage-initrd)
-# Create the note section for New-World PowerMacs.
-quiet_cmd_mknote = MKNOTE $@
- cmd_mknote = $(utils)/mknote > $@
-targets += note
-$(obj)/note: $(utils)/mknote FORCE
- $(call if_changed,mknote)
-
-$(obj)/coffcrt0.o: EXTRA_AFLAGS := -DXCOFF
-targets += coffcrt0.o crt0.o
-$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
+targets += crt0.o
+$(obj)/crt0.o: $(common)/crt0.S FORCE
$(call if_changed_dep,as_o_S)
-quiet_cmd_gencoffb = COFF $@
- cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \
- $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
-targets += coffboot
-$(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE
- $(call if_changed,gencoffb)
-targets += coffboot.initrd
-$(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \
- $(srctree)/$(boot)/ld.script FORCE
- $(call if_changed,gencoffb)
-
-
-quiet_cmd_gen-coff = COFF $@
- cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \
- $(HACKCOFF) $@ && \
- ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac
-
-$(images)/vmlinux.coff: $(obj)/coffboot
- $(call cmd,gen-coff)
-
-$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd
- $(call cmd,gen-coff)
-
-quiet_cmd_gen-elf-pmac = ELF $@
- cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \
- $(NEWWORLDOBJS) $(LIBS) $< && \
- $(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \
- -R .comment $(del-ramdisk-sec)
-
-$(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \
- $(obj)/note $(srctree)/$(boot)/ld.script
- $(call cmd,gen-elf-pmac)
-$(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \
- $(LIBS) $(obj)/note \
- $(srctree)/$(boot)/ld.script
- $(call cmd,gen-elf-pmac)
-
quiet_cmd_gen-chrp = CHRP $@
cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \
$(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
@@ -139,46 +84,23 @@ $(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \
%-rs6k: %
$(call cmd,addnote)
-quiet_cmd_gen-miboot = GEN $@
- cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \
- --add-section=$1=$(word 2, $^) $< $@
-$(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz
- $(call cmd,gen-miboot,image)
-
-$(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz
- $(call cmd,gen-miboot,initrd)
-
# The targets used on the make command-line
.PHONY: zImage zImage.initrd
-zImage: $(images)/vmlinux.coff \
- $(images)/vmlinux.elf-pmac \
- $(images)/zImage.chrp \
- $(images)/zImage.chrp-rs6k \
- $(images)/miboot.image
+zImage: $(images)/zImage.chrp \
+ $(images)/zImage.chrp-rs6k
@echo ' kernel: $@ is ready ($<)'
-zImage.initrd: $(images)/vmlinux.initrd.coff \
- $(images)/vmlinux.initrd.elf-pmac \
- $(images)/zImage.initrd.chrp \
- $(images)/zImage.initrd.chrp-rs6k \
- $(images)/miboot.initrd.image
+zImage.initrd: $(images)/zImage.initrd.chrp \
+ $(images)/zImage.initrd.chrp-rs6k
@echo ' kernel: $@ is ready ($<)'
TFTPIMAGE := /tftpboot/zImage
.PHONY: znetboot znetboot.initrd
-znetboot: $(images)/vmlinux.coff \
- $(images)/vmlinux.elf-pmac \
- $(images)/zImage.chrp
- cp $(images)/vmlinux.coff $(TFTPIMAGE).pmac$(END)
- cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf
+znetboot: $(images)/zImage.chrp
cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)'
-znetboot.initrd:$(images)/vmlinux.initrd.coff \
- $(images)/vmlinux.initrd.elf-pmac \
- $(images)/zImage.initrd.chrp
- cp $(images)/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END)
- cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf
+znetboot.initrd:$(images)/zImage.initrd.chrp
cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END)
@echo ' kernel: $@ is ready ($<)'
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
deleted file mode 100644
index 2da8855e2be0..000000000000
--- a/arch/ppc/boot/openfirmware/coffmain.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include
-#include
-#include
-
-#include "nonstdio.h"
-#include "of1275.h"
-
-/* Passed from the linker */
-extern char __image_begin, __image_end;
-extern char __ramdisk_begin[], __ramdisk_end;
-extern char _start, _end;
-
-extern char image_data[], initrd_data[];
-extern int initrd_len, image_len;
-extern unsigned int heap_max;
-extern void flush_cache(void *start, unsigned int len);
-extern void gunzip(void *, int, unsigned char *, int *);
-extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
- unsigned int progend);
-extern void setup_bats(unsigned long start);
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-
-#define SCRATCH_SIZE (128 << 10)
-
-static char heap[SCRATCH_SIZE];
-
-static unsigned long ram_start = 0;
-static unsigned long ram_end = 0x1000000;
-
-static unsigned long prog_start = 0x800000;
-static unsigned long prog_size = 0x700000;
-
-typedef void (*kernel_start_t)(int, int, void *);
-
-void boot(int a1, int a2, void *prom)
-{
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
-
- printf("coffboot starting: loaded at 0x%p\n", &_start);
- setup_bats(ram_start);
-
- initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
- if (initrd_size) {
- initrd_start = (ram_end - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start, ram_end - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
- initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- prog_size = initrd_start - prog_start;
- } else
- a2 = 0xdeadbeef;
-
- im = (char *)(&__image_begin);
- len = (char *)(&__image_end) - (char *)(&__image_begin);
- /* claim 4MB starting at PROG_START */
- claim(prog_start, prog_size, 0);
- map(prog_start, prog_start, prog_size);
- dst = (void *) prog_start;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- /* set up scratch space */
- begin_avail = avail_high = avail_ram = heap;
- end_avail = heap + sizeof(heap);
- printf("heap at 0x%p\n", avail_ram);
- printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
- gunzip(dst, prog_size, im, &len);
- printf("done %u bytes\n", len);
- printf("%u bytes of heap consumed, max in use %u\n",
- avail_high - begin_avail, heap_max);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
- make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac,
- (prog_start + prog_size));
-
- sa = (unsigned long)prog_start;
- printf("start address = 0x%x\n", sa);
-
- (*(kernel_start_t)sa)(a1, a2, prom);
-
- printf("returned?\n");
-
- pause();
-}
diff --git a/arch/ppc/boot/openfirmware/newworldmain.c b/arch/ppc/boot/openfirmware/newworldmain.c
deleted file mode 100644
index fa8a8f9313f9..000000000000
--- a/arch/ppc/boot/openfirmware/newworldmain.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include
-#include "nonstdio.h"
-#include "of1275.h"
-#include
-#include
-
-/* Passed from the linker */
-extern char __image_begin, __image_end;
-extern char __ramdisk_begin[], __ramdisk_end;
-extern char _start, _end;
-
-extern unsigned int heap_max;
-extern void flush_cache(void *start, unsigned int len);
-extern void gunzip(void *, int, unsigned char *, int *);
-extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
- unsigned int progend);
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-
-
-#define RAM_END (16 << 20)
-
-#define PROG_START 0x00010000
-#define PROG_SIZE 0x007f0000
-
-#define SCRATCH_SIZE (128 << 10)
-
-typedef void (*kernel_start_t)(int, int, void *);
-
-void boot(int a1, int a2, void *prom)
-{
- unsigned sa, len;
- void *dst;
- unsigned char *im;
- unsigned initrd_start, initrd_size;
-
- printf("chrpboot starting: loaded at 0x%p\n", &_start);
-
- initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
- if (initrd_size) {
- initrd_start = (RAM_END - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
- claim(initrd_start, RAM_END - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
- initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
- } else
- a2 = 0xdeadbeef;
-
- im = (char *)(&__image_begin);
- len = (char *)(&__image_end) - (char *)(&__image_begin);
- /* claim 3MB starting at PROG_START */
- claim(PROG_START, PROG_SIZE, 0);
- dst = (void *) PROG_START;
- if (im[0] == 0x1f && im[1] == 0x8b) {
- /* claim some memory for scratch space */
- avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
- begin_avail = avail_high = avail_ram;
- end_avail = avail_ram + SCRATCH_SIZE;
- printf("heap at 0x%p\n", avail_ram);
- printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
- gunzip(dst, PROG_SIZE, im, &len);
- printf("done %u bytes\n", len);
- printf("%u bytes of heap consumed, max in use %u\n",
- avail_high - begin_avail, heap_max);
- release(begin_avail, SCRATCH_SIZE);
- } else {
- memmove(dst, im, len);
- }
-
- flush_cache(dst, len);
- make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
- (PROG_START + PROG_SIZE));
-
- sa = (unsigned long)PROG_START;
- printf("start address = 0x%x\n", sa);
-
- (*(kernel_start_t)sa)(a1, a2, prom);
-
- printf("returned?\n");
-
- pause();
-}
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index ca0201300868..647da4c1d219 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -9,7 +9,6 @@ extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
-extra-$(CONFIG_POWER4) += idle_power4.o
extra-y += vmlinux.lds
obj-y := entry.o traps.o idle.o time.o misc.o \
@@ -17,7 +16,6 @@ obj-y := entry.o traps.o idle.o time.o misc.o \
ppc_htab.o
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
-obj-$(CONFIG_POWER4) += cpu_setup_power4.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index fb5658bba285..c3427eed8345 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -204,78 +204,6 @@ _GLOBAL(call_setup_cpu)
mtctr r5
bctr
-#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)
-
-/* This gets called by via-pmu.c to switch the PLL selection
- * on 750fx CPU. This function should really be moved to some
- * other place (as most of the cpufreq code in via-pmu
- */
-_GLOBAL(low_choose_750fx_pll)
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* If switching to PLL1, disable HID0:BTIC */
- cmplwi cr0,r3,0
- beq 1f
- mfspr r5,SPRN_HID0
- rlwinm r5,r5,0,27,25
- sync
- mtspr SPRN_HID0,r5
- isync
- sync
-
-1:
- /* Calc new HID1 value */
- mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */
- rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */
- rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */
- or r4,r4,r5
- mtspr SPRN_HID1,r4
-
- /* Store new HID1 image */
- rlwinm r6,r1,0,0,18
- lwz r6,TI_CPU(r6)
- slwi r6,r6,2
- addis r6,r6,nap_save_hid1@ha
- stw r4,nap_save_hid1@l(r6)
-
- /* If switching to PLL0, enable HID0:BTIC */
- cmplwi cr0,r3,0
- bne 1f
- mfspr r5,SPRN_HID0
- ori r5,r5,HID0_BTIC
- sync
- mtspr SPRN_HID0,r5
- isync
- sync
-
-1:
- /* Return */
- mtmsr r7
- blr
-
-_GLOBAL(low_choose_7447a_dfs)
- /* Clear MSR:EE */
- mfmsr r7
- rlwinm r0,r7,0,17,15
- mtmsr r0
-
- /* Calc new HID1 value */
- mfspr r4,SPRN_HID1
- insrwi r4,r3,1,9 /* insert parameter into bit 9 */
- sync
- mtspr SPRN_HID1,r4
- sync
- isync
-
- /* Return */
- mtmsr r7
- blr
-
-#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
-
/*
* complement mask on the msr then "or" some values on.
* _nmask_and_or_msr(nmask, value_to_or)
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 704c846b2b0f..04d04c5bfdd0 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1,5 +1,5 @@
/*
- * Common pmac/prep/chrp pci routines. -- Cort
+ * Common prep/chrp pci routines. -- Cort
*/
#include
@@ -50,8 +50,7 @@ static void fixup_cpc710_pci64(struct pci_dev* dev);
static u8* pci_to_OF_bus_map;
#endif
-/* By default, we don't re-assign bus numbers. We do this only on
- * some pmacs
+/* By default, we don't re-assign bus numbers.
*/
int pci_assign_all_buses;
@@ -780,17 +779,6 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
return NULL;
/* Fixup bus number according to what OF think it is. */
-#ifdef CONFIG_PPC_PMAC
- /* The G5 need a special case here. Basically, we don't remap all
- * busses on it so we don't create the pci-OF-map. However, we do
- * remap the AGP bus and so have to deal with it. A future better
- * fix has to be done by making the remapping per-host and always
- * filling the pci_to_OF map. --BenH
- */
- if (_machine == _MACH_Pmac && busnr >= 0xf0)
- busnr -= 0xf0;
- else
-#endif
if (pci_to_OF_bus_map)
busnr = pci_to_OF_bus_map[busnr];
if (busnr == 0xff)
@@ -1040,216 +1028,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev)
}
-#ifdef CONFIG_PPC_PMAC
-/*
- * This set of routines checks for PCI<->PCI bridges that have closed
- * IO resources and have child devices. It tries to re-open an IO
- * window on them.
- *
- * This is a _temporary_ fix to workaround a problem with Apple's OF
- * closing IO windows on P2P bridges when the OF drivers of cards
- * below this bridge don't claim any IO range (typically ATI or
- * Adaptec).
- *
- * A more complete fix would be to use drivers/pci/setup-bus.c, which
- * involves a working pcibios_fixup_pbus_ranges(), some more care about
- * ordering when creating the host bus resources, and maybe a few more
- * minor tweaks
- */
-
-/* Initialize bridges with base/limit values we have collected */
-static void __init
-do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
-{
- struct pci_dev *bridge = bus->self;
- struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
- u32 l;
- u16 w;
- struct resource res;
-
- if (bus->resource[0] == NULL)
- return;
- res = *(bus->resource[0]);
-
- DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
- res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
- res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
- DBG(" IO window: %08lx-%08lx\n", res.start, res.end);
-
- /* Set up the top and bottom of the PCI I/O segment for this bus. */
- pci_read_config_dword(bridge, PCI_IO_BASE, &l);
- l &= 0xffff000f;
- l |= (res.start >> 8) & 0x00f0;
- l |= res.end & 0xf000;
- pci_write_config_dword(bridge, PCI_IO_BASE, l);
-
- if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
- l = (res.start >> 16) | (res.end & 0xffff0000);
- pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
- }
-
- pci_read_config_word(bridge, PCI_COMMAND, &w);
- w |= PCI_COMMAND_IO;
- pci_write_config_word(bridge, PCI_COMMAND, w);
-
-#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
- if (enable_vga) {
- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
- w |= PCI_BRIDGE_CTL_VGA;
- pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
- }
-#endif
-}
-
-/* This function is pretty basic and actually quite broken for the
- * general case, it's enough for us right now though. It's supposed
- * to tell us if we need to open an IO range at all or not and what
- * size.
- */
-static int __init
-check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
-{
- struct pci_dev *dev;
- int i;
- int rc = 0;
-
-#define push_end(res, size) do { unsigned long __sz = (size) ; \
- res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
- } while (0)
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- u16 class = dev->class >> 8;
-
- if (class == PCI_CLASS_DISPLAY_VGA ||
- class == PCI_CLASS_NOT_DEFINED_VGA)
- *found_vga = 1;
- if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
- rc |= check_for_io_childs(dev->subordinate, res, found_vga);
- if (class == PCI_CLASS_BRIDGE_CARDBUS)
- push_end(res, 0xfff);
-
- for (i=0; iclass >> 8 == PCI_CLASS_BRIDGE_PCI
- && i >= PCI_BRIDGE_RESOURCES)
- continue;
- r = &dev->resource[i];
- r_size = r->end - r->start;
- if (r_size < 0xfff)
- r_size = 0xfff;
- if (r->flags & IORESOURCE_IO && (r_size) != 0) {
- rc = 1;
- push_end(res, r_size);
- }
- }
- }
-
- return rc;
-}
-
-/* Here we scan all P2P bridges of a given level that have a closed
- * IO window. Note that the test for the presence of a VGA card should
- * be improved to take into account already configured P2P bridges,
- * currently, we don't see them and might end up configuring 2 bridges
- * with VGA pass through enabled
- */
-static void __init
-do_fixup_p2p_level(struct pci_bus *bus)
-{
- struct pci_bus *b;
- int i, parent_io;
- int has_vga = 0;
-
- for (parent_io=0; parent_io<4; parent_io++)
- if (bus->resource[parent_io]
- && bus->resource[parent_io]->flags & IORESOURCE_IO)
- break;
- if (parent_io >= 4)
- return;
-
- list_for_each_entry(b, &bus->children, node) {
- struct pci_dev *d = b->self;
- struct pci_controller* hose = (struct pci_controller *)d->sysdata;
- struct resource *res = b->resource[0];
- struct resource tmp_res;
- unsigned long max;
- int found_vga = 0;
-
- memset(&tmp_res, 0, sizeof(tmp_res));
- tmp_res.start = bus->resource[parent_io]->start;
-
- /* We don't let low addresses go through that closed P2P bridge, well,
- * that may not be necessary but I feel safer that way
- */
- if (tmp_res.start == 0)
- tmp_res.start = 0x1000;
-
- if (!list_empty(&b->devices) && res && res->flags == 0 &&
- res != bus->resource[parent_io] &&
- (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
- check_for_io_childs(b, &tmp_res, &found_vga)) {
- u8 io_base_lo;
-
- printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
-
- if (found_vga) {
- if (has_vga) {
- printk(KERN_WARNING "Skipping VGA, already active"
- " on bus segment\n");
- found_vga = 0;
- } else
- has_vga = 1;
- }
- pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
-
- if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
- max = ((unsigned long) hose->io_base_virt
- - isa_io_base) + 0xffffffff;
- else
- max = ((unsigned long) hose->io_base_virt
- - isa_io_base) + 0xffff;
-
- *res = tmp_res;
- res->flags = IORESOURCE_IO;
- res->name = b->name;
-
- /* Find a resource in the parent where we can allocate */
- for (i = 0 ; i < 4; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
- if ((r->flags & IORESOURCE_IO) == 0)
- continue;
- DBG("Trying to allocate from %08lx, size %08lx from parent"
- " res %d: %08lx -> %08lx\n",
- res->start, res->end, i, r->start, r->end);
-
- if (allocate_resource(r, res, res->end + 1, res->start, max,
- res->end + 1, NULL, NULL) < 0) {
- DBG("Failed !\n");
- continue;
- }
- do_update_p2p_io_resource(b, found_vga);
- break;
- }
- }
- do_fixup_p2p_level(b);
- }
-}
-
-static void
-pcibios_fixup_p2p_bridges(void)
-{
- struct pci_bus *b;
-
- list_for_each_entry(b, &pci_root_buses, node)
- do_fixup_p2p_level(b);
-}
-
-#endif /* CONFIG_PPC_PMAC */
-
static int __init
pcibios_init(void)
{
@@ -1290,9 +1068,6 @@ pcibios_init(void)
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
-#ifdef CONFIG_PPC_PMAC
- pcibios_fixup_p2p_bridges();
-#endif /* CONFIG_PPC_PMAC */
pcibios_assign_resources();
/* Call machine dependent post-init code */
@@ -1722,17 +1497,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
struct pci_controller* hose;
long result = -EOPNOTSUPP;
- /* Argh ! Please forgive me for that hack, but that's the
- * simplest way to get existing XFree to not lockup on some
- * G5 machines... So when something asks for bus 0 io base
- * (bus 0 is HT root), we return the AGP one instead.
- */
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))
- if (bus == 0)
- bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
-
hose = pci_bus_to_hose(bus);
if (!hose)
return -ENODEV;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index fb0da7c209db..3a6e4bcb3c53 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -34,7 +34,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -58,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
extern void alignment_exception(struct pt_regs *regs);
extern void program_check_exception(struct pt_regs *regs);
extern void single_step_exception(struct pt_regs *regs);
-extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs);
long long __ashrdi3(long long, int);
@@ -213,10 +211,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll);
#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_PPC_PMAC
-EXPORT_SYMBOL(sys_ctrler);
-EXPORT_SYMBOL(pmac_newworld);
-#endif
#ifdef CONFIG_PPC_OF
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
@@ -241,9 +235,6 @@ EXPORT_SYMBOL(of_node_put);
#if defined(CONFIG_BOOTX_TEXT)
EXPORT_SYMBOL(btext_update_display);
#endif
-#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC)
-EXPORT_SYMBOL(note_scsi_host);
-#endif
#ifdef CONFIG_VT
EXPORT_SYMBOL(kd_mksound);
#endif
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index e707c6f6e61b..c08ab432e958 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -1,5 +1,5 @@
/*
- * Common prep/pmac/chrp boot and setup code.
+ * Common prep/chrp boot and setup code.
*/
#include
@@ -35,7 +35,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -55,7 +54,6 @@
extern void platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
-extern void bootx_init(unsigned long r4, unsigned long phys);
extern void identify_cpu(unsigned long offset, unsigned long cpu);
extern void do_cpu_ftr_fixups(unsigned long offset);
extern void reloc_got2(unsigned long offset);
@@ -80,8 +78,6 @@ EXPORT_SYMBOL(_machine);
extern void prep_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
-extern void pmac_init(unsigned long r3, unsigned long r4,
- unsigned long r5, unsigned long r6, unsigned long r7);
extern void chrp_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
@@ -324,20 +320,15 @@ early_init(int r3, int r4, int r5)
identify_cpu(offset, 0);
do_cpu_ftr_fixups(offset);
-#if defined(CONFIG_PPC_MULTIPLATFORM)
+#if defined(CONFIG_PPC_OF)
reloc_got2(offset);
- /* If we came here from BootX, clear the screen,
- * set up some pointers and return. */
- if ((r3 == 0x426f6f58) && (r5 == 0))
- bootx_init(r4, phys);
-
/*
* don't do anything on prep
* for now, don't use bootinfo because it breaks yaboot 0.5
* and assume that if we didn't find a magic number, we have OF
*/
- else if (*(unsigned long *)(0) != 0xdeadc0de)
+ if (*(unsigned long *)(0) != 0xdeadc0de)
phys = prom_init(r3, r4, (prom_entry)r5);
reloc_got2(-offset);
@@ -424,6 +415,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
}
#endif
+#ifdef CONFIG_PPC_OF
have_of = 1;
/* prom_init has already been called from __start */
@@ -495,19 +487,17 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
#endif /* CONFIG_ADB */
switch (_machine) {
-#ifdef CONFIG_PPC_PMAC
- case _MACH_Pmac:
- pmac_init(r3, r4, r5, r6, r7);
- break;
-#endif
#ifdef CONFIG_PPC_CHRP
case _MACH_chrp:
chrp_init(r3, r4, r5, r6, r7);
break;
#endif
}
+#endif /* CONFIG_PPC_OF */
}
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+#ifdef CONFIG_PPC_OF
#ifdef CONFIG_SERIAL_CORE_CONSOLE
extern char *of_stdout_device;
@@ -564,7 +554,7 @@ static int __init set_preferred_console(void)
}
console_initcall(set_preferred_console);
#endif /* CONFIG_SERIAL_CORE_CONSOLE */
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_PPC_OF */
struct bi_record *find_bootinfo(void)
{
@@ -747,14 +737,6 @@ void __init setup_arch(char **cmdline_p)
if (ppc_md.init_early)
ppc_md.init_early();
-#ifdef CONFIG_PPC_MULTIPLATFORM
- /* This could be called "early setup arch", it must be done
- * now because xmon need it
- */
- if (_machine == _MACH_Pmac)
- pmac_feature_init(); /* New cool way */
-#endif
-
#ifdef CONFIG_XMON
xmon_init(1);
if (strstr(cmd_line, "xmon"))
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 9dbc4d28fa28..6d0a1838d94c 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -38,9 +38,6 @@
#include
#include
#include
-#ifdef CONFIG_PMAC_BACKLIGHT
-#include
-#endif
#include
#ifdef CONFIG_XMON
@@ -85,12 +82,6 @@ int die(const char * str, struct pt_regs * fp, long err)
int nl = 0;
console_verbose();
spin_lock_irq(&die_lock);
-#ifdef CONFIG_PMAC_BACKLIGHT
- if (_machine == _MACH_Pmac) {
- set_backlight_enable(1);
- set_backlight_level(BACKLIGHT_MAX);
- }
-#endif
printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
#ifdef CONFIG_PREEMPT
printk("PREEMPT ");
@@ -159,7 +150,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
*/
static inline int check_io_access(struct pt_regs *regs)
{
-#if defined CONFIG_PPC_PMAC || defined CONFIG_8xx
+#if defined CONFIG_8xx
unsigned long msr = regs->msr;
const struct exception_table_entry *entry;
unsigned int *nip = (unsigned int *)regs->nip;
@@ -196,7 +187,7 @@ static inline int check_io_access(struct pt_regs *regs)
return 1;
}
}
-#endif /* CONFIG_PPC_PMAC */
+#endif /* CONFIG_8xx */
return 0;
}
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 45f0782059f1..134db5c04203 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -67,10 +67,6 @@ unsigned long ppc_memoffset = PAGE_OFFSET;
int mem_init_done;
int init_bootmem_done;
int boot_mapsize;
-#ifdef CONFIG_PPC_PMAC
-unsigned long agp_special_page;
-EXPORT_SYMBOL(agp_special_page);
-#endif
extern char _end[];
extern char etext[], _stext[];
@@ -423,10 +419,6 @@ void __init mem_init(void)
addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
addr += PAGE_SIZE)
SetPageReserved(virt_to_page(addr));
-#endif
-#ifdef CONFIG_PPC_PMAC
- if (agp_special_page)
- SetPageReserved(virt_to_page(agp_special_page));
#endif
for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;
addr += PAGE_SIZE) {
@@ -463,11 +455,6 @@ void __init mem_init(void)
initpages<< (PAGE_SHIFT-10),
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
-#ifdef CONFIG_PPC_PMAC
- if (agp_special_page)
- printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page);
-#endif
-
mem_init_done = 1;
}
@@ -512,22 +499,6 @@ set_phys_avail(unsigned long total_memory)
if (rtas_data)
mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
#endif
-#ifdef CONFIG_PPC_PMAC
- /* Because of some uninorth weirdness, we need a page of
- * memory as high as possible (it must be outside of the
- * bus address seen as the AGP aperture). It will be used
- * by the r128 DRM driver
- *
- * FIXME: We need to make sure that page doesn't overlap any of the\
- * above. This could be done by improving mem_pieces_find to be able
- * to do a backward search from the end of the list.
- */
- if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) {
- agp_special_page = (total_memory - PAGE_SIZE);
- mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);
- agp_special_page = (unsigned long)__va(agp_special_page);
- }
-#endif /* CONFIG_PPC_PMAC */
}
/* Mark some memory as reserved by removing it from phys_avail. */
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 7c5cdabf6f3c..51430e294b32 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -3,26 +3,18 @@
#
# Extra CFLAGS so we don't have to do relative includes
-CFLAGS_pmac_setup.o += -Iarch/$(ARCH)/mm
+CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm
obj-$(CONFIG_APUS) += apus_setup.o
ifeq ($(CONFIG_APUS),y)
obj-$(CONFIG_PCI) += apus_pci.o
endif
-obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \
- pmac_feature.o pmac_pci.o pmac_sleep.o \
- pmac_low_i2c.o pmac_cache.o
obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \
chrp_pegasos_eth.o
ifeq ($(CONFIG_PPC_CHRP),y)
obj-$(CONFIG_NVRAM) += chrp_nvram.o
endif
obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o
-ifeq ($(CONFIG_PPC_PMAC),y)
-obj-$(CONFIG_NVRAM) += pmac_nvram.o
-obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o
-endif
-obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o
obj-$(CONFIG_PREP_RESIDUAL) += residual.o
obj-$(CONFIG_PQ2ADS) += pq2ads.o
obj-$(CONFIG_TQM8260) += tqm8260_setup.o
@@ -47,6 +39,5 @@ obj-$(CONFIG_LITE5200) += lite5200.o
obj-$(CONFIG_EV64360) += ev64360.o
ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
obj-$(CONFIG_PPC_CHRP) += chrp_smp.o
endif
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
index bd047aac01b1..c7fe6182bb77 100644
--- a/arch/ppc/platforms/chrp_pci.c
+++ b/arch/ppc/platforms/chrp_pci.c
@@ -275,7 +275,7 @@ chrp_find_bridges(void)
setup_python(hose, dev);
} else if (is_mot
|| strncmp(model, "Motorola, Grackle", 17) == 0) {
- setup_grackle(hose);
+ setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
} else if (is_longtrail) {
void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
hose->ops = &gg2_pci_ops;
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 056ac2a7b5c1..48996b787378 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -53,6 +53,7 @@
#include
#include
#include
+#include "mem_pieces.h"
unsigned long chrp_get_rtc_time(void);
int chrp_set_rtc_time(unsigned long nowtime);
@@ -65,7 +66,6 @@ void rtas_display_progress(char *, unsigned short);
void rtas_indicator_progress(char *, unsigned short);
void btext_progress(char *, unsigned short);
-extern unsigned long pmac_find_end_of_memory(void);
extern int of_show_percpuinfo(struct seq_file *, int);
int _chrp_type;
@@ -467,6 +467,75 @@ chrp_init2(void)
ppc_md.progress(" Have fun! ", 0x7777);
}
+static struct device_node *memory_node;
+
+static int __init get_mem_prop(char *name, struct mem_pieces *mp)
+{
+ struct reg_property *rp;
+ int i, s;
+ unsigned int *ip;
+ int nac = prom_n_addr_cells(memory_node);
+ int nsc = prom_n_size_cells(memory_node);
+
+ ip = (unsigned int *) get_property(memory_node, name, &s);
+ if (ip == NULL) {
+ printk(KERN_ERR "error: couldn't get %s property on /memory\n",
+ name);
+ return 0;
+ }
+ s /= (nsc + nac) * 4;
+ rp = mp->regions;
+ for (i = 0; i < s; ++i, ip += nac+nsc) {
+ if (nac >= 2 && ip[nac-2] != 0)
+ continue;
+ rp->address = ip[nac-1];
+ if (nsc >= 2 && ip[nac+nsc-2] != 0)
+ rp->size = ~0U;
+ else
+ rp->size = ip[nac+nsc-1];
+ ++rp;
+ }
+ mp->n_regions = rp - mp->regions;
+
+ /* Make sure the pieces are sorted. */
+ mem_pieces_sort(mp);
+ mem_pieces_coalesce(mp);
+ return 1;
+}
+
+static unsigned long __init chrp_find_end_of_memory(void)
+{
+ unsigned long a, total;
+ struct mem_pieces phys_mem;
+
+ /*
+ * Find out where physical memory is, and check that it
+ * starts at 0 and is contiguous. It seems that RAM is
+ * always physically contiguous on Power Macintoshes.
+ *
+ * Supporting discontiguous physical memory isn't hard,
+ * it just makes the virtual <-> physical mapping functions
+ * more complicated (or else you end up wasting space
+ * in mem_map).
+ */
+ memory_node = find_devices("memory");
+ if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
+ || phys_mem.n_regions == 0)
+ panic("No RAM??");
+ a = phys_mem.regions[0].address;
+ if (a != 0)
+ panic("RAM doesn't start at physical address 0");
+ total = phys_mem.regions[0].size;
+
+ if (phys_mem.n_regions > 1) {
+ printk("RAM starting at 0x%x is not contiguous\n",
+ phys_mem.regions[1].address);
+ printk("Using RAM from 0 to 0x%lx\n", total-1);
+ }
+
+ return total;
+}
+
void __init
chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
@@ -525,7 +594,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.get_rtc_time = chrp_get_rtc_time;
ppc_md.calibrate_decr = chrp_calibrate_decr;
- ppc_md.find_end_of_memory = pmac_find_end_of_memory;
+ ppc_md.find_end_of_memory = chrp_find_end_of_memory;
if (rtas_data) {
struct device_node *rtas;
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 29d074c305f0..57753a55b580 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -163,13 +163,75 @@ unsigned long chrp_get_rtc_time(void)
return mktime(year, mon, day, hour, min, sec);
}
+/*
+ * Calibrate the decrementer frequency with the VIA timer 1.
+ */
+#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
+
+/* VIA registers */
+#define RS 0x200 /* skip between registers */
+#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
+#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
+#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
+#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
+#define ACR (11*RS) /* Auxiliary control register */
+#define IFR (13*RS) /* Interrupt flag register */
+
+/* Bits in ACR */
+#define T1MODE 0xc0 /* Timer 1 mode */
+#define T1MODE_CONT 0x40 /* continuous interrupts */
+
+/* Bits in IFR and IER */
+#define T1_INT 0x40 /* Timer 1 interrupt */
+
+static int __init chrp_via_calibrate_decr(void)
+{
+ struct device_node *vias;
+ volatile unsigned char __iomem *via;
+ int count = VIA_TIMER_FREQ_6 / 100;
+ unsigned int dstart, dend;
+
+ vias = find_devices("via-cuda");
+ if (vias == 0)
+ vias = find_devices("via");
+ if (vias == 0 || vias->n_addrs == 0)
+ return 0;
+ via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
+
+ /* set timer 1 for continuous interrupts */
+ out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
+ /* set the counter to a small value */
+ out_8(&via[T1CH], 2);
+ /* set the latch to `count' */
+ out_8(&via[T1LL], count);
+ out_8(&via[T1LH], count >> 8);
+ /* wait until it hits 0 */
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dstart = get_dec();
+ /* clear the interrupt & wait until it hits 0 again */
+ in_8(&via[T1CL]);
+ while ((in_8(&via[IFR]) & T1_INT) == 0)
+ ;
+ dend = get_dec();
+
+ tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
+ tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
+
+ printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
+ tb_ticks_per_jiffy, dstart - dend);
+
+ iounmap(via);
+
+ return 1;
+}
void __init chrp_calibrate_decr(void)
{
struct device_node *cpu;
unsigned int freq, *fp;
- if (via_calibrate_decr())
+ if (chrp_via_calibrate_decr())
return;
/*
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
deleted file mode 100644
index 8be2f7d071f0..000000000000
--- a/arch/ppc/platforms/pmac_backlight.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Miscellaneous procedures for dealing with the PowerMac hardware.
- * Contains support for the backlight.
- *
- * Copyright (C) 2000 Benjamin Herrenschmidt
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-static struct backlight_controller *backlighter;
-static void* backlighter_data;
-static int backlight_autosave;
-static int backlight_level = BACKLIGHT_MAX;
-static int backlight_enabled = 1;
-static int backlight_req_level = -1;
-static int backlight_req_enable = -1;
-
-static void backlight_callback(void *);
-static DECLARE_WORK(backlight_work, backlight_callback, NULL);
-
-void register_backlight_controller(struct backlight_controller *ctrler,
- void *data, char *type)
-{
- struct device_node* bk_node;
- char *prop;
- int valid = 0;
-
- /* There's already a matching controller, bail out */
- if (backlighter != NULL)
- return;
-
- bk_node = find_devices("backlight");
-
-#ifdef CONFIG_ADB_PMU
- /* Special case for the old PowerBook since I can't test on it */
- backlight_autosave = machine_is_compatible("AAPL,3400/2400")
- || machine_is_compatible("AAPL,3500");
- if ((backlight_autosave
- || machine_is_compatible("AAPL,PowerBook1998")
- || machine_is_compatible("PowerBook1,1"))
- && !strcmp(type, "pmu"))
- valid = 1;
-#endif
- if (bk_node) {
- prop = get_property(bk_node, "backlight-control", NULL);
- if (prop && !strncmp(prop, type, strlen(type)))
- valid = 1;
- }
- if (!valid)
- return;
- backlighter = ctrler;
- backlighter_data = data;
-
- if (bk_node && !backlight_autosave)
- prop = get_property(bk_node, "bklt", NULL);
- else
- prop = NULL;
- if (prop) {
- backlight_level = ((*prop)+1) >> 1;
- if (backlight_level > BACKLIGHT_MAX)
- backlight_level = BACKLIGHT_MAX;
- }
-
-#ifdef CONFIG_ADB_PMU
- if (backlight_autosave) {
- struct adb_request req;
- pmu_request(&req, NULL, 2, 0xd9, 0);
- while (!req.complete)
- pmu_poll();
- backlight_level = req.reply[0] >> 4;
- }
-#endif
- acquire_console_sem();
- if (!backlighter->set_enable(1, backlight_level, data))
- backlight_enabled = 1;
- release_console_sem();
-
- printk(KERN_INFO "Registered \"%s\" backlight controller,"
- "level: %d/15\n", type, backlight_level);
-}
-EXPORT_SYMBOL(register_backlight_controller);
-
-void unregister_backlight_controller(struct backlight_controller
- *ctrler, void *data)
-{
- /* We keep the current backlight level (for now) */
- if (ctrler == backlighter && data == backlighter_data)
- backlighter = NULL;
-}
-EXPORT_SYMBOL(unregister_backlight_controller);
-
-static int __set_backlight_enable(int enable)
-{
- int rc;
-
- if (!backlighter)
- return -ENODEV;
- acquire_console_sem();
- rc = backlighter->set_enable(enable, backlight_level,
- backlighter_data);
- if (!rc)
- backlight_enabled = enable;
- release_console_sem();
- return rc;
-}
-int set_backlight_enable(int enable)
-{
- if (!backlighter)
- return -ENODEV;
- backlight_req_enable = enable;
- schedule_work(&backlight_work);
- return 0;
-}
-
-EXPORT_SYMBOL(set_backlight_enable);
-
-int get_backlight_enable(void)
-{
- if (!backlighter)
- return -ENODEV;
- return backlight_enabled;
-}
-EXPORT_SYMBOL(get_backlight_enable);
-
-static int __set_backlight_level(int level)
-{
- int rc = 0;
-
- if (!backlighter)
- return -ENODEV;
- if (level < BACKLIGHT_MIN)
- level = BACKLIGHT_OFF;
- if (level > BACKLIGHT_MAX)
- level = BACKLIGHT_MAX;
- acquire_console_sem();
- if (backlight_enabled)
- rc = backlighter->set_level(level, backlighter_data);
- if (!rc)
- backlight_level = level;
- release_console_sem();
- if (!rc && !backlight_autosave) {
- level <<=1;
- if (level & 0x10)
- level |= 0x01;
- // -- todo: save to property "bklt"
- }
- return rc;
-}
-int set_backlight_level(int level)
-{
- if (!backlighter)
- return -ENODEV;
- backlight_req_level = level;
- schedule_work(&backlight_work);
- return 0;
-}
-
-EXPORT_SYMBOL(set_backlight_level);
-
-int get_backlight_level(void)
-{
- if (!backlighter)
- return -ENODEV;
- return backlight_level;
-}
-EXPORT_SYMBOL(get_backlight_level);
-
-static void backlight_callback(void *dummy)
-{
- int level, enable;
-
- do {
- level = backlight_req_level;
- enable = backlight_req_enable;
- mb();
-
- if (level >= 0)
- __set_backlight_level(level);
- if (enable >= 0)
- __set_backlight_enable(enable);
- } while(cmpxchg(&backlight_req_level, level, -1) != level ||
- cmpxchg(&backlight_req_enable, enable, -1) != enable);
-}
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S
deleted file mode 100644
index fb977de6b704..000000000000
--- a/arch/ppc/platforms/pmac_cache.S
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * This file contains low-level cache management functions
- * used for sleep and CPU speed changes on Apple machines.
- * (In fact the only thing that is Apple-specific is that we assume
- * that we can read from ROM at physical address 0xfff00000.)
- *
- * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
- * Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include
-#include
-#include
-#include
-
-/*
- * Flush and disable all data caches (dL1, L2, L3). This is used
- * when going to sleep, when doing a PMU based cpufreq transition,
- * or when "offlining" a CPU on SMP machines. This code is over
- * paranoid, but I've had enough issues with various CPU revs and
- * bugs that I decided it was worth beeing over cautious
- */
-
-_GLOBAL(flush_disable_caches)
-#ifndef CONFIG_6xx
- blr
-#else
-BEGIN_FTR_SECTION
- b flush_disable_745x
-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
-BEGIN_FTR_SECTION
- b flush_disable_75x
-END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
- b __flush_disable_L1
-
-/* This is the code for G3 and 74[01]0 */
-flush_disable_75x:
- mflr r10
-
- /* Turn off EE and DR in MSR */
- mfmsr r11
- rlwinm r0,r11,0,~MSR_EE
- rlwinm r0,r0,0,~MSR_DR
- sync
- mtmsr r0
- isync
-
- /* Stop DST streams */
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-
- /* Stop DPM */
- mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
- rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
- sync
- mtspr SPRN_HID0,r4 /* Disable DPM */
- sync
-
- /* Disp-flush L1. We have a weird problem here that I never
- * totally figured out. On 750FX, using the ROM for the flush
- * results in a non-working flush. We use that workaround for
- * now until I finally understand what's going on. --BenH
- */
-
- /* ROM base by default */
- lis r4,0xfff0
- mfpvr r3
- srwi r3,r3,16
- cmplwi cr0,r3,0x7000
- bne+ 1f
- /* RAM base on 750FX */
- li r4,0
-1: li r4,0x4000
- mtctr r4
-1: lwz r0,0(r4)
- addi r4,r4,32
- bdnz 1b
- sync
- isync
-
- /* Disable / invalidate / enable L1 data */
- mfspr r3,SPRN_HID0
- rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
- mtspr SPRN_HID0,r3
- sync
- isync
- ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
- sync
- isync
- mtspr SPRN_HID0,r3
- xori r3,r3,(HID0_DCI|HID0_ICFI)
- mtspr SPRN_HID0,r3
- sync
-
- /* Get the current enable bit of the L2CR into r4 */
- mfspr r5,SPRN_L2CR
- /* Set to data-only (pre-745x bit) */
- oris r3,r5,L2CR_L2DO@h
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r3
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: /* disp-flush L2. The interesting thing here is that the L2 can be
- * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
- * but that is probbaly fine. We disp-flush over 4Mb to be safe
- */
- lis r4,2
- mtctr r4
- lis r4,0xfff0
-1: lwz r0,0(r4)
- addi r4,r4,32
- bdnz 1b
- sync
- isync
- lis r4,2
- mtctr r4
- lis r4,0xfff0
-1: dcbf 0,r4
- addi r4,r4,32
- bdnz 1b
- sync
- isync
-
- /* now disable L2 */
- rlwinm r5,r5,0,~L2CR_L2E
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r5
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
- oris r4,r5,L2CR_L2I@h
- mtspr SPRN_L2CR,r4
- sync
- isync
-
- /* Wait for the invalidation to complete */
-1: mfspr r3,SPRN_L2CR
- rlwinm. r0,r3,0,31,31
- bne 1b
-
- /* Clear L2I */
- xoris r4,r4,L2CR_L2I@h
- sync
- mtspr SPRN_L2CR,r4
- sync
-
- /* now disable the L1 data cache */
- mfspr r0,SPRN_HID0
- rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
- mtspr SPRN_HID0,r0
- sync
- isync
-
- /* Restore HID0[DPM] to whatever it was before */
- sync
- mfspr r0,SPRN_HID0
- rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
- mtspr SPRN_HID0,r0
- sync
-
- /* restore DR and EE */
- sync
- mtmsr r11
- isync
-
- mtlr r10
- blr
-
-/* This code is for 745x processors */
-flush_disable_745x:
- /* Turn off EE and DR in MSR */
- mfmsr r11
- rlwinm r0,r11,0,~MSR_EE
- rlwinm r0,r0,0,~MSR_DR
- sync
- mtmsr r0
- isync
-
- /* Stop prefetch streams */
- DSSALL
- sync
-
- /* Disable L2 prefetching */
- mfspr r0,SPRN_MSSCR0
- rlwinm r0,r0,0,0,29
- mtspr SPRN_MSSCR0,r0
- sync
- isync
- lis r4,0
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
-
- /* Due to a bug with the HW flush on some CPU revs, we occasionally
- * experience data corruption. I'm adding a displacement flush along
- * with a dcbf loop over a few Mb to "help". The problem isn't totally
- * fixed by this in theory, but at least, in practice, I couldn't reproduce
- * it even with a big hammer...
- */
-
- lis r4,0x0002
- mtctr r4
- li r4,0
-1:
- lwz r0,0(r4)
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
- isync
-
- /* Now, flush the first 4MB of memory */
- lis r4,0x0002
- mtctr r4
- li r4,0
- sync
-1:
- dcbf 0,r4
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
-
- /* Flush and disable the L1 data cache */
- mfspr r6,SPRN_LDSTCR
- lis r3,0xfff0 /* read from ROM for displacement flush */
- li r4,0xfe /* start with only way 0 unlocked */
- li r5,128 /* 128 lines in each way */
-1: mtctr r5
- rlwimi r6,r4,0,24,31
- mtspr SPRN_LDSTCR,r6
- sync
- isync
-2: lwz r0,0(r3) /* touch each cache line */
- addi r3,r3,32
- bdnz 2b
- rlwinm r4,r4,1,24,30 /* move on to the next way */
- ori r4,r4,1
- cmpwi r4,0xff /* all done? */
- bne 1b
- /* now unlock the L1 data cache */
- li r4,0
- rlwimi r6,r4,0,24,31
- sync
- mtspr SPRN_LDSTCR,r6
- sync
- isync
-
- /* Flush the L2 cache using the hardware assist */
- mfspr r3,SPRN_L2CR
- cmpwi r3,0 /* check if it is enabled first */
- bge 4f
- oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
- b 2f
- /* When disabling/locking L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- ori r0,r3,L2CR_L2HWF_745x
- sync
- mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
-3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
- andi. r0,r0,L2CR_L2HWF_745x
- bne 3b
- sync
- rlwinm r3,r3,0,~L2CR_L2E
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- oris r4,r3,L2CR_L2I@h
- mtspr SPRN_L2CR,r4
- sync
- isync
-1: mfspr r4,SPRN_L2CR
- andis. r0,r4,L2CR_L2I@h
- bne 1b
- sync
-
-BEGIN_FTR_SECTION
- /* Flush the L3 cache using the hardware assist */
-4: mfspr r3,SPRN_L3CR
- cmpwi r3,0 /* check if it is enabled */
- bge 6f
- oris r0,r3,L3CR_L3IO@h
- ori r0,r0,L3CR_L3DO
- sync
- mtspr SPRN_L3CR,r0 /* lock the L3 cache */
- sync
- isync
- ori r0,r0,L3CR_L3HWF
- sync
- mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
-5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
- andi. r0,r0,L3CR_L3HWF
- bne 5b
- rlwinm r3,r3,0,~L3CR_L3E
- sync
- mtspr SPRN_L3CR,r3 /* disable the L3 cache */
- sync
- ori r4,r3,L3CR_L3I
- mtspr SPRN_L3CR,r4
-1: mfspr r4,SPRN_L3CR
- andi. r0,r4,L3CR_L3I
- bne 1b
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
-
-6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
- rlwinm r0,r0,0,~HID0_DCE
- mtspr SPRN_HID0,r0
- sync
- isync
- mtmsr r11 /* restore DR and EE */
- isync
- blr
-#endif /* CONFIG_6xx */
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
deleted file mode 100644
index fba7e4d7c0bf..000000000000
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_cpufreq.c
- *
- * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt
- * Copyright (C) 2004 John Steele Scott
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO: Need a big cleanup here. Basically, we need to have different
- * cpufreq_driver structures for the different type of HW instead of the
- * current mess. We also need to better deal with the detection of the
- * type of machine.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* WARNING !!! This will cause calibrate_delay() to be called,
- * but this is an __init function ! So you MUST go edit
- * init/main.c to make it non-init before enabling DEBUG_FREQ
- */
-#undef DEBUG_FREQ
-
-/*
- * There is a problem with the core cpufreq code on SMP kernels,
- * it won't recalculate the Bogomips properly
- */
-#ifdef CONFIG_SMP
-#warning "WARNING, CPUFREQ not recommended on SMP kernels"
-#endif
-
-extern void low_choose_7447a_dfs(int dfs);
-extern void low_choose_750fx_pll(int pll);
-extern void low_sleep_handler(void);
-
-/*
- * Currently, PowerMac cpufreq supports only high & low frequencies
- * that are set by the firmware
- */
-static unsigned int low_freq;
-static unsigned int hi_freq;
-static unsigned int cur_freq;
-static unsigned int sleep_freq;
-
-/*
- * Different models uses different mecanisms to switch the frequency
- */
-static int (*set_speed_proc)(int low_speed);
-static unsigned int (*get_speed_proc)(void);
-
-/*
- * Some definitions used by the various speedprocs
- */
-static u32 voltage_gpio;
-static u32 frequency_gpio;
-static u32 slew_done_gpio;
-static int no_schedule;
-static int has_cpu_l2lve;
-static int is_pmu_based;
-
-/* There are only two frequency states for each processor. Values
- * are in kHz for the time being.
- */
-#define CPUFREQ_HIGH 0
-#define CPUFREQ_LOW 1
-
-static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
- {CPUFREQ_HIGH, 0},
- {CPUFREQ_LOW, 0},
- {0, CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr* pmac_cpu_freqs_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-static inline void local_delay(unsigned long ms)
-{
- if (no_schedule)
- mdelay(ms);
- else
- msleep(ms);
-}
-
-static inline void wakeup_decrementer(void)
-{
- set_dec(tb_ticks_per_jiffy);
- /* No currently-supported powerbook has a 601,
- * so use get_tbl, not native
- */
- last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
-}
-
-#ifdef DEBUG_FREQ
-static inline void debug_calc_bogomips(void)
-{
- /* This will cause a recalc of bogomips and display the
- * result. We backup/restore the value to avoid affecting the
- * core cpufreq framework's own calculation.
- */
- extern void calibrate_delay(void);
-
- unsigned long save_lpj = loops_per_jiffy;
- calibrate_delay();
- loops_per_jiffy = save_lpj;
-}
-#endif /* DEBUG_FREQ */
-
-/* Switch CPU speed under 750FX CPU control
- */
-static int cpu_750fx_cpu_speed(int low_speed)
-{
- u32 hid2;
-
- if (low_speed == 0) {
- /* ramping up, set voltage first */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Make sure we sleep for at least 1ms */
- local_delay(10);
-
- /* tweak L2 for high voltage */
- if (has_cpu_l2lve) {
- hid2 = mfspr(SPRN_HID2);
- hid2 &= ~0x2000;
- mtspr(SPRN_HID2, hid2);
- }
- }
-#ifdef CONFIG_6xx
- low_choose_750fx_pll(low_speed);
-#endif
- if (low_speed == 1) {
- /* tweak L2 for low voltage */
- if (has_cpu_l2lve) {
- hid2 = mfspr(SPRN_HID2);
- hid2 |= 0x2000;
- mtspr(SPRN_HID2, hid2);
- }
-
- /* ramping down, set voltage last */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- local_delay(10);
- }
-
- return 0;
-}
-
-static unsigned int cpu_750fx_get_cpu_speed(void)
-{
- if (mfspr(SPRN_HID1) & HID1_PS)
- return low_freq;
- else
- return hi_freq;
-}
-
-/* Switch CPU speed using DFS */
-static int dfs_set_cpu_speed(int low_speed)
-{
- if (low_speed == 0) {
- /* ramping up, set voltage first */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Make sure we sleep for at least 1ms */
- local_delay(1);
- }
-
- /* set frequency */
-#ifdef CONFIG_6xx
- low_choose_7447a_dfs(low_speed);
-#endif
- udelay(100);
-
- if (low_speed == 1) {
- /* ramping down, set voltage last */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- local_delay(1);
- }
-
- return 0;
-}
-
-static unsigned int dfs_get_cpu_speed(void)
-{
- if (mfspr(SPRN_HID1) & HID1_DFS)
- return low_freq;
- else
- return hi_freq;
-}
-
-
-/* Switch CPU speed using slewing GPIOs
- */
-static int gpios_set_cpu_speed(int low_speed)
-{
- int gpio, timeout = 0;
-
- /* If ramping up, set voltage first */
- if (low_speed == 0) {
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Delay is way too big but it's ok, we schedule */
- local_delay(10);
- }
-
- /* Set frequency */
- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- if (low_speed == ((gpio & 0x01) == 0))
- goto skip;
-
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
- low_speed ? 0x04 : 0x05);
- udelay(200);
- do {
- if (++timeout > 100)
- break;
- local_delay(1);
- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
- } while((gpio & 0x02) == 0);
- skip:
- /* If ramping down, set voltage last */
- if (low_speed == 1) {
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- /* Delay is way too big but it's ok, we schedule */
- local_delay(10);
- }
-
-#ifdef DEBUG_FREQ
- debug_calc_bogomips();
-#endif
-
- return 0;
-}
-
-/* Switch CPU speed under PMU control
- */
-static int pmu_set_cpu_speed(int low_speed)
-{
- struct adb_request req;
- unsigned long save_l2cr;
- unsigned long save_l3cr;
- unsigned int pic_prio;
- unsigned long flags;
-
- preempt_disable();
-
-#ifdef DEBUG_FREQ
- printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
-#endif
- pmu_suspend();
-
- /* Disable all interrupt sources on openpic */
- pic_prio = openpic_get_priority();
- openpic_set_priority(0xf);
-
- /* Make sure the decrementer won't interrupt us */
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- /* Make sure any pending DEC interrupt occuring while we did
- * the above didn't re-enable the DEC */
- mb();
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
- /* We can now disable MSR_EE */
- local_irq_save(flags);
-
- /* Giveup the FPU & vec */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- /* Save & disable L2 and L3 caches */
- save_l3cr = _get_L3CR(); /* (returns -1 if not available) */
- save_l2cr = _get_L2CR(); /* (returns -1 if not available) */
-
- /* Send the new speed command. My assumption is that this command
- * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
- */
- pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
- while (!req.complete)
- pmu_poll();
-
- /* Prepare the northbridge for the speed transition */
- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
-
- /* Call low level code to backup CPU state and recover from
- * hardware reset
- */
- low_sleep_handler();
-
- /* Restore the northbridge */
- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
-
- /* Restore L2 cache */
- if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
- _set_L2CR(save_l2cr);
- /* Restore L3 cache */
- if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
- _set_L3CR(save_l3cr);
-
- /* Restore userland MMU context */
- set_context(current->active_mm->context, current->active_mm->pgd);
-
-#ifdef DEBUG_FREQ
- printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
-#endif
-
- /* Restore low level PMU operations */
- pmu_unlock();
-
- /* Restore decrementer */
- wakeup_decrementer();
-
- /* Restore interrupts */
- openpic_set_priority(pic_prio);
-
- /* Let interrupts flow again ... */
- local_irq_restore(flags);
-
-#ifdef DEBUG_FREQ
- debug_calc_bogomips();
-#endif
-
- pmu_resume();
-
- preempt_enable();
-
- return 0;
-}
-
-static int do_set_cpu_speed(int speed_mode, int notify)
-{
- struct cpufreq_freqs freqs;
- unsigned long l3cr;
- static unsigned long prev_l3cr;
-
- freqs.old = cur_freq;
- freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
- freqs.cpu = smp_processor_id();
-
- if (freqs.old == freqs.new)
- return 0;
-
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- if (speed_mode == CPUFREQ_LOW &&
- cpu_has_feature(CPU_FTR_L3CR)) {
- l3cr = _get_L3CR();
- if (l3cr & L3CR_L3E) {
- prev_l3cr = l3cr;
- _set_L3CR(0);
- }
- }
- set_speed_proc(speed_mode == CPUFREQ_LOW);
- if (speed_mode == CPUFREQ_HIGH &&
- cpu_has_feature(CPU_FTR_L3CR)) {
- l3cr = _get_L3CR();
- if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
- _set_L3CR(prev_l3cr);
- }
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
-
- return 0;
-}
-
-static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
-{
- return cur_freq;
-}
-
-static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
-}
-
-static int pmac_cpufreq_target( struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- unsigned int newstate = 0;
-
- if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
- target_freq, relation, &newstate))
- return -EINVAL;
-
- return do_set_cpu_speed(newstate, 1);
-}
-
-unsigned int pmac_get_one_cpufreq(int i)
-{
- /* Supports only one CPU for now */
- return (i == 0) ? cur_freq : 0;
-}
-
-static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- if (policy->cpu != 0)
- return -ENODEV;
-
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
- policy->cur = cur_freq;
-
- cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
- return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
-}
-
-static u32 read_gpio(struct device_node *np)
-{
- u32 *reg = (u32 *)get_property(np, "reg", NULL);
- u32 offset;
-
- if (reg == NULL)
- return 0;
- /* That works for all keylargos but shall be fixed properly
- * some day... The problem is that it seems we can't rely
- * on the "reg" property of the GPIO nodes, they are either
- * relative to the base of KeyLargo or to the base of the
- * GPIO space, and the device-tree doesn't help.
- */
- offset = *reg;
- if (offset < KEYLARGO_GPIO_LEVELS0)
- offset += KEYLARGO_GPIO_LEVELS0;
- return offset;
-}
-
-static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
-{
- /* Ok, this could be made a bit smarter, but let's be robust for now. We
- * always force a speed change to high speed before sleep, to make sure
- * we have appropriate voltage and/or bus speed for the wakeup process,
- * and to make sure our loops_per_jiffies are "good enough", that is will
- * not cause too short delays if we sleep in low speed and wake in high
- * speed..
- */
- no_schedule = 1;
- sleep_freq = cur_freq;
- if (cur_freq == low_freq && !is_pmu_based)
- do_set_cpu_speed(CPUFREQ_HIGH, 0);
- return 0;
-}
-
-static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
-{
- /* If we resume, first check if we have a get() function */
- if (get_speed_proc)
- cur_freq = get_speed_proc();
- else
- cur_freq = 0;
-
- /* We don't, hrm... we don't really know our speed here, best
- * is that we force a switch to whatever it was, which is
- * probably high speed due to our suspend() routine
- */
- do_set_cpu_speed(sleep_freq == low_freq ?
- CPUFREQ_LOW : CPUFREQ_HIGH, 0);
-
- no_schedule = 0;
- return 0;
-}
-
-static struct cpufreq_driver pmac_cpufreq_driver = {
- .verify = pmac_cpufreq_verify,
- .target = pmac_cpufreq_target,
- .get = pmac_cpufreq_get_speed,
- .init = pmac_cpufreq_cpu_init,
- .suspend = pmac_cpufreq_suspend,
- .resume = pmac_cpufreq_resume,
- .flags = CPUFREQ_PM_NO_WARN,
- .attr = pmac_cpu_freqs_attr,
- .name = "powermac",
- .owner = THIS_MODULE,
-};
-
-
-static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
- "voltage-gpio");
- struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
- "frequency-gpio");
- struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
- "slewing-done");
- u32 *value;
-
- /*
- * Check to see if it's GPIO driven or PMU only
- *
- * The way we extract the GPIO address is slightly hackish, but it
- * works well enough for now. We need to abstract the whole GPIO
- * stuff sooner or later anyway
- */
-
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (freq_gpio_np)
- frequency_gpio = read_gpio(freq_gpio_np);
- if (slew_done_gpio_np)
- slew_done_gpio = read_gpio(slew_done_gpio_np);
-
- /* If we use the frequency GPIOs, calculate the min/max speeds based
- * on the bus frequencies
- */
- if (frequency_gpio && slew_done_gpio) {
- int lenp, rc;
- u32 *freqs, *ratio;
-
- freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
- lenp /= sizeof(u32);
- if (freqs == NULL || lenp != 2) {
- printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
- return 1;
- }
- ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
- if (ratio == NULL) {
- printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
- return 1;
- }
-
- /* Get the min/max bus frequencies */
- low_freq = min(freqs[0], freqs[1]);
- hi_freq = max(freqs[0], freqs[1]);
-
- /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
- * frequency, it claims it to be around 84Mhz on some models while
- * it appears to be approx. 101Mhz on all. Let's hack around here...
- * fortunately, we don't need to be too precise
- */
- if (low_freq < 98000000)
- low_freq = 101000000;
-
- /* Convert those to CPU core clocks */
- low_freq = (low_freq * (*ratio)) / 2000;
- hi_freq = (hi_freq * (*ratio)) / 2000;
-
- /* Now we get the frequencies, we read the GPIO to see what is out current
- * speed
- */
- rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- cur_freq = (rc & 0x01) ? hi_freq : low_freq;
-
- set_speed_proc = gpios_set_cpu_speed;
- return 1;
- }
-
- /* If we use the PMU, look for the min & max frequencies in the
- * device-tree
- */
- value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
- if (!value)
- return 1;
- low_freq = (*value) / 1000;
- /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
- * here */
- if (low_freq < 100000)
- low_freq *= 10;
-
- value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
- if (!value)
- return 1;
- hi_freq = (*value) / 1000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
-
- return 0;
-}
-
-static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np;
-
- if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
- return 1;
-
- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (!voltage_gpio){
- printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
- return 1;
- }
-
- /* OF only reports the high frequency */
- hi_freq = cur_freq;
- low_freq = cur_freq/2;
-
- /* Read actual frequency from CPU */
- cur_freq = dfs_get_cpu_speed();
- set_speed_proc = dfs_set_cpu_speed;
- get_speed_proc = dfs_get_cpu_speed;
-
- return 0;
-}
-
-static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np;
- u32 pvr, *value;
-
- if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
- return 1;
-
- hi_freq = cur_freq;
- value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
- if (!value)
- return 1;
- low_freq = (*value) / 1000;
-
- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
-
- pvr = mfspr(SPRN_PVR);
- has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
-
- set_speed_proc = cpu_750fx_cpu_speed;
- get_speed_proc = cpu_750fx_get_cpu_speed;
- cur_freq = cpu_750fx_get_cpu_speed();
-
- return 0;
-}
-
-/* Currently, we support the following machines:
- *
- * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
- * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
- * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
- * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
- * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
- * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
- * - Recent MacRISC3 laptops
- * - All new machines with 7447A CPUs
- */
-static int __init pmac_cpufreq_setup(void)
-{
- struct device_node *cpunode;
- u32 *value;
-
- if (strstr(cmd_line, "nocpufreq"))
- return 0;
-
- /* Assume only one CPU */
- cpunode = find_type_devices("cpu");
- if (!cpunode)
- goto out;
-
- /* Get current cpu clock freq */
- value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
- if (!value)
- goto out;
- cur_freq = (*value) / 1000;
-
- /* Check for 7447A based MacRISC3 */
- if (machine_is_compatible("MacRISC3") &&
- get_property(cpunode, "dynamic-power-step", NULL) &&
- PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
- pmac_cpufreq_init_7447A(cpunode);
- /* Check for other MacRISC3 machines */
- } else if (machine_is_compatible("PowerBook3,4") ||
- machine_is_compatible("PowerBook3,5") ||
- machine_is_compatible("MacRISC3")) {
- pmac_cpufreq_init_MacRISC3(cpunode);
- /* Else check for iBook2 500/600 */
- } else if (machine_is_compatible("PowerBook4,1")) {
- hi_freq = cur_freq;
- low_freq = 400000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for TiPb 550 */
- else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
- hi_freq = cur_freq;
- low_freq = 500000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for TiPb 400 & 500 */
- else if (machine_is_compatible("PowerBook3,2")) {
- /* We only know about the 400 MHz and the 500Mhz model
- * they both have 300 MHz as low frequency
- */
- if (cur_freq < 350000 || cur_freq > 550000)
- goto out;
- hi_freq = cur_freq;
- low_freq = 300000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for 750FX */
- else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
- pmac_cpufreq_init_750FX(cpunode);
-out:
- if (set_speed_proc == NULL)
- return -ENODEV;
-
- pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
- pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
-
- printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
- low_freq/1000, hi_freq/1000, cur_freq/1000);
-
- return cpufreq_register_driver(&pmac_cpufreq_driver);
-}
-
-module_init(pmac_cpufreq_setup);
-
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
deleted file mode 100644
index 6b7b3a150631..000000000000
--- a/arch/ppc/platforms/pmac_feature.c
+++ /dev/null
@@ -1,3023 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_feature.c
- *
- * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
- * Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * TODO:
- *
- * - Replace mdelay with some schedule loop if possible
- * - Shorten some obfuscated delays on some routines (like modem
- * power)
- * - Refcount some clocks (see darwin)
- * - Split split split...
- *
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#undef DEBUG_FEATURE
-
-#ifdef DEBUG_FEATURE
-#define DBG(fmt,...) printk(KERN_DEBUG fmt)
-#else
-#define DBG(fmt,...)
-#endif
-
-#ifdef CONFIG_6xx
-extern int powersave_lowspeed;
-#endif
-
-extern int powersave_nap;
-extern struct device_node *k2_skiplist[2];
-
-
-/*
- * We use a single global lock to protect accesses. Each driver has
- * to take care of its own locking
- */
-static DEFINE_SPINLOCK(feature_lock);
-
-#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
-
-
-/*
- * Instance of some macio stuffs
- */
-struct macio_chip macio_chips[MAX_MACIO_CHIPS];
-
-struct macio_chip* macio_find(struct device_node* child, int type)
-{
- while(child) {
- int i;
-
- for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
- if (child == macio_chips[i].of_node &&
- (!type || macio_chips[i].type == type))
- return &macio_chips[i];
- child = child->parent;
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(macio_find);
-
-static const char* macio_names[] =
-{
- "Unknown",
- "Grand Central",
- "OHare",
- "OHareII",
- "Heathrow",
- "Gatwick",
- "Paddington",
- "Keylargo",
- "Pangea",
- "Intrepid",
- "K2"
-};
-
-
-
-/*
- * Uninorth reg. access. Note that Uni-N regs are big endian
- */
-
-#define UN_REG(r) (uninorth_base + ((r) >> 2))
-#define UN_IN(r) (in_be32(UN_REG(r)))
-#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
-#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
-#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
-
-static struct device_node* uninorth_node;
-static u32 __iomem * uninorth_base;
-static u32 uninorth_rev;
-static int uninorth_u3;
-static void __iomem *u3_ht;
-
-/*
- * For each motherboard family, we have a table of functions pointers
- * that handle the various features.
- */
-
-typedef long (*feature_call)(struct device_node* node, long param, long value);
-
-struct feature_table_entry {
- unsigned int selector;
- feature_call function;
-};
-
-struct pmac_mb_def
-{
- const char* model_string;
- const char* model_name;
- int model_id;
- struct feature_table_entry* features;
- unsigned long board_flags;
-};
-static struct pmac_mb_def pmac_mb;
-
-/*
- * Here are the chip specific feature functions
- */
-
-static inline int
-simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, type);
- if (!macio)
- return -ENODEV;
- LOCK(flags);
- if (value)
- MACIO_BIS(reg, mask);
- else
- MACIO_BIC(reg, mask);
- (void)MACIO_IN32(reg);
- UNLOCK(flags);
-
- return 0;
-}
-
-#ifndef CONFIG_POWER4
-
-static long
-ohare_htw_scc_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long chan_mask;
- unsigned long fcr;
- unsigned long flags;
- int htw, trans;
- unsigned long rmask;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (!strcmp(node->name, "ch-a"))
- chan_mask = MACIO_FLAG_SCCA_ON;
- else if (!strcmp(node->name, "ch-b"))
- chan_mask = MACIO_FLAG_SCCB_ON;
- else
- return -ENODEV;
-
- htw = (macio->type == macio_heathrow || macio->type == macio_paddington
- || macio->type == macio_gatwick);
- /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
- trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
- pmac_mb.model_id != PMAC_TYPE_YIKES);
- if (value) {
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(1);
-#endif /* CONFIG_ADB_PMU */
- LOCK(flags);
- fcr = MACIO_IN32(OHARE_FCR);
- /* Check if scc cell need enabling */
- if (!(fcr & OH_SCC_ENABLE)) {
- fcr |= OH_SCC_ENABLE;
- if (htw) {
- /* Side effect: this will also power up the
- * modem, but it's too messy to figure out on which
- * ports this controls the tranceiver and on which
- * it controls the modem
- */
- if (trans)
- fcr &= ~HRW_SCC_TRANS_EN_N;
- MACIO_OUT32(OHARE_FCR, fcr);
- fcr |= (rmask = HRW_RESET_SCC);
- MACIO_OUT32(OHARE_FCR, fcr);
- } else {
- fcr |= (rmask = OH_SCC_RESET);
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- UNLOCK(flags);
- (void)MACIO_IN32(OHARE_FCR);
- mdelay(15);
- LOCK(flags);
- fcr &= ~rmask;
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr |= OH_SCCA_IO;
- if (chan_mask & MACIO_FLAG_SCCB_ON)
- fcr |= OH_SCCB_IO;
- MACIO_OUT32(OHARE_FCR, fcr);
- macio->flags |= chan_mask;
- UNLOCK(flags);
- if (param & PMAC_SCC_FLAG_XMON)
- macio->flags |= MACIO_FLAG_SCC_LOCKED;
- } else {
- if (macio->flags & MACIO_FLAG_SCC_LOCKED)
- return -EPERM;
- LOCK(flags);
- fcr = MACIO_IN32(OHARE_FCR);
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr &= ~OH_SCCA_IO;
- if (chan_mask & MACIO_FLAG_SCCB_ON)
- fcr &= ~OH_SCCB_IO;
- MACIO_OUT32(OHARE_FCR, fcr);
- if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
- fcr &= ~OH_SCC_ENABLE;
- if (htw && trans)
- fcr |= HRW_SCC_TRANS_EN_N;
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- macio->flags &= ~(chan_mask);
- UNLOCK(flags);
- mdelay(10);
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */
- }
- return 0;
-}
-
-static long
-ohare_floppy_enable(struct device_node* node, long param, long value)
-{
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_FLOPPY_ENABLE, value);
-}
-
-static long
-ohare_mesh_enable(struct device_node* node, long param, long value)
-{
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_MESH_ENABLE, value);
-}
-
-static long
-ohare_ide_enable(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- /* For some reason, setting the bit in set_initial_features()
- * doesn't stick. I'm still investigating... --BenH.
- */
- if (value)
- simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IOBUS_ENABLE, 1);
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_BAY_IDE_ENABLE, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-ohare_ide_reset(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE1_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-ohare_sleep_state(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
- if (value == 1) {
- MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
- } else if (value == 0) {
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- }
-
- return 0;
-}
-
-static long
-heathrow_modem_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- macio = macio_find(node, macio_unknown);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- mdelay(250);
- }
- if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
- pmac_mb.model_id != PMAC_TYPE_YIKES) {
- LOCK(flags);
- if (value)
- MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- else
- MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(250);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-heathrow_floppy_enable(struct device_node* node, long param, long value)
-{
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR,
- HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
- value);
-}
-
-static long
-heathrow_mesh_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, macio_unknown);
- if (!macio)
- return -ENODEV;
- LOCK(flags);
- /* Set clear mesh cell enable */
- if (value)
- MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
- else
- MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
- (void)MACIO_IN32(HEATHROW_FCR);
- udelay(10);
- /* Set/Clear termination power */
- if (value)
- MACIO_BIC(HEATHROW_MBCR, 0x04000000);
- else
- MACIO_BIS(HEATHROW_MBCR, 0x04000000);
- (void)MACIO_IN32(HEATHROW_MBCR);
- udelay(10);
- UNLOCK(flags);
-
- return 0;
-}
-
-static long
-heathrow_ide_enable(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-heathrow_ide_reset(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-heathrow_bmac_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (value) {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
- MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(10);
- LOCK(flags);
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(10);
- } else {
- LOCK(flags);
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static long
-heathrow_sound_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- /* B&W G3 and Yikes don't support that properly (the
- * sound appear to never come back after beeing shut down).
- */
- if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
- pmac_mb.model_id == PMAC_TYPE_YIKES)
- return 0;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (value) {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- } else {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static u32 save_fcr[6];
-static u32 save_mbcr;
-static u32 save_gpio_levels[2];
-static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
-static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
-static u32 save_unin_clock_ctl;
-static struct dbdma_regs save_dbdma[13];
-static struct dbdma_regs save_alt_dbdma[13];
-
-static void
-dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
-{
- int i;
-
- /* Save state & config of DBDMA channels */
- for (i=0; i<13; i++) {
- volatile struct dbdma_regs __iomem * chan = (void __iomem *)
- (macio->base + ((0x8000+i*0x100)>>2));
- save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
- save[i].cmdptr = in_le32(&chan->cmdptr);
- save[i].intr_sel = in_le32(&chan->intr_sel);
- save[i].br_sel = in_le32(&chan->br_sel);
- save[i].wait_sel = in_le32(&chan->wait_sel);
- }
-}
-
-static void
-dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
-{
- int i;
-
- /* Save state & config of DBDMA channels */
- for (i=0; i<13; i++) {
- volatile struct dbdma_regs __iomem * chan = (void __iomem *)
- (macio->base + ((0x8000+i*0x100)>>2));
- out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
- while (in_le32(&chan->status) & ACTIVE)
- mb();
- out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
- out_le32(&chan->cmdptr, save[i].cmdptr);
- out_le32(&chan->intr_sel, save[i].intr_sel);
- out_le32(&chan->br_sel, save[i].br_sel);
- out_le32(&chan->wait_sel, save[i].wait_sel);
- }
-}
-
-static void
-heathrow_sleep(struct macio_chip* macio, int secondary)
-{
- if (secondary) {
- dbdma_save(macio, save_alt_dbdma);
- save_fcr[2] = MACIO_IN32(0x38);
- save_fcr[3] = MACIO_IN32(0x3c);
- } else {
- dbdma_save(macio, save_dbdma);
- save_fcr[0] = MACIO_IN32(0x38);
- save_fcr[1] = MACIO_IN32(0x3c);
- save_mbcr = MACIO_IN32(0x34);
- /* Make sure sound is shut down */
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- /* This seems to be necessary as well or the fan
- * keeps coming up and battery drains fast */
- MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
- /* Make sure eth is down even if module or sleep
- * won't work properly */
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
- }
- /* Make sure modem is shut down */
- MACIO_OUT8(HRW_GPIO_MODEM_RESET,
- MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
- MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
-
- /* Let things settle */
- (void)MACIO_IN32(HEATHROW_FCR);
-}
-
-static void
-heathrow_wakeup(struct macio_chip* macio, int secondary)
-{
- if (secondary) {
- MACIO_OUT32(0x38, save_fcr[2]);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x3c, save_fcr[3]);
- (void)MACIO_IN32(0x38);
- mdelay(10);
- dbdma_restore(macio, save_alt_dbdma);
- } else {
- MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x3c, save_fcr[1]);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x34, save_mbcr);
- (void)MACIO_IN32(0x38);
- mdelay(10);
- dbdma_restore(macio, save_dbdma);
- }
-}
-
-static long
-heathrow_sleep_state(struct device_node* node, long param, long value)
-{
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
- if (value == 1) {
- if (macio_chips[1].type == macio_gatwick)
- heathrow_sleep(&macio_chips[0], 1);
- heathrow_sleep(&macio_chips[0], 0);
- } else if (value == 0) {
- heathrow_wakeup(&macio_chips[0], 0);
- if (macio_chips[1].type == macio_gatwick)
- heathrow_wakeup(&macio_chips[0], 1);
- }
- return 0;
-}
-
-static long
-core99_scc_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- unsigned long chan_mask;
- u32 fcr;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (!strcmp(node->name, "ch-a"))
- chan_mask = MACIO_FLAG_SCCA_ON;
- else if (!strcmp(node->name, "ch-b"))
- chan_mask = MACIO_FLAG_SCCB_ON;
- else
- return -ENODEV;
-
- if (value) {
- int need_reset_scc = 0;
- int need_reset_irda = 0;
-
- LOCK(flags);
- fcr = MACIO_IN32(KEYLARGO_FCR0);
- /* Check if scc cell need enabling */
- if (!(fcr & KL0_SCC_CELL_ENABLE)) {
- fcr |= KL0_SCC_CELL_ENABLE;
- need_reset_scc = 1;
- }
- if (chan_mask & MACIO_FLAG_SCCA_ON) {
- fcr |= KL0_SCCA_ENABLE;
- /* Don't enable line drivers for I2S modem */
- if ((param & 0xfff) == PMAC_SCC_I2S1)
- fcr &= ~KL0_SCC_A_INTF_ENABLE;
- else
- fcr |= KL0_SCC_A_INTF_ENABLE;
- }
- if (chan_mask & MACIO_FLAG_SCCB_ON) {
- fcr |= KL0_SCCB_ENABLE;
- /* Perform irda specific inits */
- if ((param & 0xfff) == PMAC_SCC_IRDA) {
- fcr &= ~KL0_SCC_B_INTF_ENABLE;
- fcr |= KL0_IRDA_ENABLE;
- fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
- fcr |= KL0_IRDA_SOURCE1_SEL;
- fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
- fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
- need_reset_irda = 1;
- } else
- fcr |= KL0_SCC_B_INTF_ENABLE;
- }
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- macio->flags |= chan_mask;
- if (need_reset_scc) {
- MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(15);
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
- }
- if (need_reset_irda) {
- MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(15);
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
- }
- UNLOCK(flags);
- if (param & PMAC_SCC_FLAG_XMON)
- macio->flags |= MACIO_FLAG_SCC_LOCKED;
- } else {
- if (macio->flags & MACIO_FLAG_SCC_LOCKED)
- return -EPERM;
- LOCK(flags);
- fcr = MACIO_IN32(KEYLARGO_FCR0);
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr &= ~KL0_SCCA_ENABLE;
- if (chan_mask & MACIO_FLAG_SCCB_ON) {
- fcr &= ~KL0_SCCB_ENABLE;
- /* Perform irda specific clears */
- if ((param & 0xfff) == PMAC_SCC_IRDA) {
- fcr &= ~KL0_IRDA_ENABLE;
- fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
- fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
- fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
- }
- }
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
- fcr &= ~KL0_SCC_CELL_ENABLE;
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- }
- macio->flags &= ~(chan_mask);
- UNLOCK(flags);
- mdelay(10);
- }
- return 0;
-}
-
-static long
-core99_modem_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- /* Hack for internal USB modem */
- if (node == NULL) {
- if (macio_chips[0].type != macio_keylargo)
- return -ENODEV;
- node = macio_chips[0].of_node;
- }
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
- gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
- gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- mdelay(250);
- }
- LOCK(flags);
- if (value) {
- MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- mdelay(250);
- } else {
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- UNLOCK(flags);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-pangea_modem_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- /* Hack for internal USB modem */
- if (node == NULL) {
- if (macio_chips[0].type != macio_pangea &&
- macio_chips[0].type != macio_intrepid)
- return -ENODEV;
- node = macio_chips[0].of_node;
- }
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
- gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
- gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- mdelay(250);
- }
- LOCK(flags);
- if (value) {
- MACIO_OUT8(KL_GPIO_MODEM_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE);
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- mdelay(250);
- } else {
- MACIO_OUT8(KL_GPIO_MODEM_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- UNLOCK(flags);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-core99_ata100_enable(struct device_node* node, long value)
-{
- unsigned long flags;
- struct pci_dev *pdev = NULL;
- u8 pbus, pid;
-
- if (uninorth_rev < 0x24)
- return -ENODEV;
-
- LOCK(flags);
- if (value)
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
- else
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- UNLOCK(flags);
- udelay(20);
-
- if (value) {
- if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
- pdev = pci_find_slot(pbus, pid);
- if (pdev == NULL)
- return 0;
- pci_enable_device(pdev);
- pci_set_master(pdev);
- }
- return 0;
-}
-
-static long
-core99_ide_enable(struct device_node* node, long param, long value)
-{
- /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
- * based ata-100
- */
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
- case 2:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
- case 3:
- return core99_ata100_enable(node, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-core99_ide_reset(struct device_node* node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
- case 2:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-core99_gmac_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- LOCK(flags);
- if (value)
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
- else
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- UNLOCK(flags);
- udelay(20);
-
- return 0;
-}
-
-static long
-core99_gmac_phy_reset(struct device_node* node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip* macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
- UNLOCK(flags);
- mdelay(10);
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
- KEYLARGO_GPIO_OUTOUT_DATA);
- UNLOCK(flags);
- mdelay(10);
-
- return 0;
-}
-
-static long
-core99_sound_chip_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
-
- /* Do a better probe code, screamer G4 desktops &
- * iMacs can do that too, add a recalibrate in
- * the driver as well
- */
- if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
- pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
- LOCK(flags);
- if (value)
- MACIO_OUT8(KL_GPIO_SOUND_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE |
- KEYLARGO_GPIO_OUTOUT_DATA);
- else
- MACIO_OUT8(KL_GPIO_SOUND_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static long
-core99_airport_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- int state;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
-
- /* Hint: we allow passing of macio itself for the sake of the
- * sleep code
- */
- if (node != macio->of_node &&
- (!node->parent || node->parent != macio->of_node))
- return -ENODEV;
- state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
- if (value == state)
- return 0;
- if (value) {
- /* This code is a reproduction of OF enable-cardslot
- * and init-wireless methods, slightly hacked until
- * I got it working.
- */
- LOCK(flags);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
- UNLOCK(flags);
- mdelay(10);
- LOCK(flags);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
- UNLOCK(flags);
-
- mdelay(10);
-
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
- UNLOCK(flags);
- udelay(10);
- MACIO_OUT32(0x1c000, 0);
- mdelay(1);
- MACIO_OUT8(0x1a3e0, 0x41);
- (void)MACIO_IN8(0x1a3e0);
- udelay(10);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- UNLOCK(flags);
- mdelay(100);
-
- macio->flags |= MACIO_FLAG_AIRPORT_ON;
- } else {
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
- (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
- UNLOCK(flags);
-
- macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
- }
- return 0;
-}
-
-#ifdef CONFIG_SMP
-static long
-core99_reset_cpu(struct device_node* node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip* macio;
- struct device_node* np;
- const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0,
- KL_GPIO_RESET_CPU1,
- KL_GPIO_RESET_CPU2,
- KL_GPIO_RESET_CPU3 };
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo)
- return -ENODEV;
-
- np = find_path_device("/cpus");
- if (np == NULL)
- return -ENODEV;
- for (np = np->child; np != NULL; np = np->sibling) {
- u32* num = (u32 *)get_property(np, "reg", NULL);
- u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- if (np == NULL || reset_io == 0)
- reset_io = dflt_reset_lines[param];
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-static long
-core99_usb_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- char* prop;
- int number;
- u32 reg;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- prop = (char *)get_property(node, "AAPL,clock-id", NULL);
- if (!prop)
- return -ENODEV;
- if (strncmp(prop, "usb0u048", 8) == 0)
- number = 0;
- else if (strncmp(prop, "usb1u148", 8) == 0)
- number = 2;
- else if (strncmp(prop, "usb2u248", 8) == 0)
- number = 4;
- else
- return -ENODEV;
-
- /* Sorry for the brute-force locking, but this is only used during
- * sleep and the timing seem to be critical
- */
- LOCK(flags);
- if (value) {
- /* Turn ON */
- if (number == 0) {
- MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
- } else if (number == 2) {
- MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
- } else if (number == 4) {
- MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR1);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
- }
- if (number < 4) {
- reg = MACIO_IN32(KEYLARGO_FCR4);
- reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
- KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
- reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
- KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
- MACIO_OUT32(KEYLARGO_FCR4, reg);
- (void)MACIO_IN32(KEYLARGO_FCR4);
- udelay(10);
- } else {
- reg = MACIO_IN32(KEYLARGO_FCR3);
- reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
- KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
- reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
- KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
- MACIO_OUT32(KEYLARGO_FCR3, reg);
- (void)MACIO_IN32(KEYLARGO_FCR3);
- udelay(10);
- }
- if (macio->type == macio_intrepid) {
- /* wait for clock stopped bits to clear */
- u32 test0 = 0, test1 = 0;
- u32 status0, status1;
- int timeout = 1000;
-
- UNLOCK(flags);
- switch (number) {
- case 0:
- test0 = UNI_N_CLOCK_STOPPED_USB0;
- test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
- break;
- case 2:
- test0 = UNI_N_CLOCK_STOPPED_USB1;
- test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
- break;
- case 4:
- test0 = UNI_N_CLOCK_STOPPED_USB2;
- test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
- break;
- }
- do {
- if (--timeout <= 0) {
- printk(KERN_ERR "core99_usb_enable: "
- "Timeout waiting for clocks\n");
- break;
- }
- mdelay(1);
- status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
- status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
- } while ((status0 & test0) | (status1 & test1));
- LOCK(flags);
- }
- } else {
- /* Turn OFF */
- if (number < 4) {
- reg = MACIO_IN32(KEYLARGO_FCR4);
- reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
- KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
- reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
- KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
- MACIO_OUT32(KEYLARGO_FCR4, reg);
- (void)MACIO_IN32(KEYLARGO_FCR4);
- udelay(1);
- } else {
- reg = MACIO_IN32(KEYLARGO_FCR3);
- reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
- KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
- reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
- KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
- MACIO_OUT32(KEYLARGO_FCR3, reg);
- (void)MACIO_IN32(KEYLARGO_FCR3);
- udelay(1);
- }
- if (number == 0) {
- if (macio->type != macio_intrepid)
- MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- } else if (number == 2) {
- if (macio->type != macio_intrepid)
- MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- } else if (number == 4) {
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR1);
- }
- udelay(1);
- }
- UNLOCK(flags);
-
- return 0;
-}
-
-static long
-core99_firewire_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip* macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
- if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- } else {
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- }
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-core99_firewire_cable_power(struct device_node* node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip* macio;
-
- /* Trick: we allow NULL node */
- if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
- return -ENODEV;
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
- if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
- MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
- udelay(10);
- } else {
- MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
- MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
- }
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-intrepid_aack_delay_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- if (uninorth_rev < 0xd2)
- return -ENODEV;
-
- LOCK(flags);
- if (param)
- UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
- else
- UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-
-#endif /* CONFIG_POWER4 */
-
-static long
-core99_read_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- return MACIO_IN8(param);
-}
-
-
-static long
-core99_write_gpio(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- MACIO_OUT8(param, (u8)(value & 0xff));
- return 0;
-}
-
-#ifdef CONFIG_POWER4
-
-static long
-g5_gmac_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
- u8 pbus, pid;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- mb();
- k2_skiplist[0] = NULL;
- } else {
- k2_skiplist[0] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-g5_fw_enable(struct device_node* node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
- unsigned long flags;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- mb();
- k2_skiplist[1] = NULL;
- } else {
- k2_skiplist[1] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-g5_mpic_enable(struct device_node* node, long param, long value)
-{
- unsigned long flags;
-
- if (node->parent == NULL || strcmp(node->parent->name, "u3"))
- return 0;
-
- LOCK(flags);
- UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-#ifdef CONFIG_SMP
-static long
-g5_reset_cpu(struct device_node* node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip* macio;
- struct device_node* np;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo2)
- return -ENODEV;
-
- np = find_path_device("/cpus");
- if (np == NULL)
- return -ENODEV;
- for (np = np->child; np != NULL; np = np->sibling) {
- u32* num = (u32 *)get_property(np, "reg", NULL);
- u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- if (np == NULL || reset_io == 0)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * This can be called from pmac_smp so isn't static
- *
- * This takes the second CPU off the bus on dual CPU machines
- * running UP
- */
-void g5_phy_disable_cpu1(void)
-{
- UN_OUT(U3_API_PHY_CONFIG_1, 0);
-}
-
-#endif /* CONFIG_POWER4 */
-
-#ifndef CONFIG_POWER4
-
-static void
-keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
-{
- u32 temp;
-
- if (sleep_mode) {
- mdelay(1);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(1);
- }
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE |
- KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
- KL0_IRDA_CLK19_ENABLE);
-
- MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
- MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
- KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
- KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
- KL1_UIDE_ENABLE);
-
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- if (macio->rev >= 2) {
- temp |= KL3_SHUTDOWN_PLL2X;
- if (sleep_mode)
- temp |= KL3_SHUTDOWN_PLL_TOTAL;
- }
-
- temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
- KL3_SHUTDOWN_PLLKW35;
- if (sleep_mode)
- temp |= KL3_SHUTDOWN_PLLKW12;
- temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
- | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
-}
-
-static void
-pangea_shutdown(struct macio_chip* macio, int sleep_mode)
-{
- u32 temp;
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE |
- KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
- KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_UIDE_ENABLE);
- if (pmac_mb.board_flags & PMAC_MB_MOBILE)
- MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
-
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
- KL3_SHUTDOWN_PLLKW35;
- temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
- | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
-}
-
-static void
-intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
-{
- u32 temp;
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- /*KL1_USB2_CELL_ENABLE |*/
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
- if (pmac_mb.board_flags & PMAC_MB_MOBILE)
- MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
- KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(10);
-}
-
-
-void pmac_tweak_clock_spreading(int enable)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- /* Hack for doing clock spreading on some machines PowerBooks and
- * iBooks. This implements the "platform-do-clockspreading" OF
- * property as decoded manually on various models. For safety, we also
- * check the product ID in the device-tree in cases we'll whack the i2c
- * chip to make reasonably sure we won't set wrong values in there
- *
- * Of course, ultimately, we have to implement a real parser for
- * the platform-do-* stuff...
- */
-
- if (macio->type == macio_intrepid) {
- struct device_node *clock =
- of_find_node_by_path("/uni-n@f8000000/hw-clock");
- if (clock && get_property(clock, "platform-do-clockspreading",
- NULL)) {
- printk(KERN_INFO "%sabling clock spreading on Intrepid"
- " ASIC\n", enable ? "En" : "Dis");
- if (enable)
- UN_OUT(UNI_N_CLOCK_SPREADING, 2);
- else
- UN_OUT(UNI_N_CLOCK_SPREADING, 0);
- mdelay(40);
- }
- of_node_put(clock);
- }
-
- while (machine_is_compatible("PowerBook5,2") ||
- machine_is_compatible("PowerBook5,3") ||
- machine_is_compatible("PowerBook6,2") ||
- machine_is_compatible("PowerBook6,3")) {
- struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
- struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
- u8 buffer[9];
- u32 *productID;
- int i, rc, changed = 0;
-
- if (dt == NULL)
- break;
- productID = (u32 *)get_property(dt, "pid#", NULL);
- if (productID == NULL)
- break;
- while(ui2c) {
- struct device_node *p = of_get_parent(ui2c);
- if (p && !strcmp(p->name, "uni-n"))
- break;
- ui2c = of_find_node_by_type(ui2c, "i2c");
- }
- if (ui2c == NULL)
- break;
- DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
- rc = pmac_low_i2c_open(ui2c, 1);
- if (rc != 0)
- break;
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
- DBG("read result: %d,", rc);
- if (rc != 0) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- for (i=0; i<9; i++)
- DBG(" %02x", buffer[i]);
- DBG("\n");
-
- switch(*productID) {
- case 0x1182: /* AlBook 12" rev 2 */
- case 0x1183: /* iBook G4 12" */
- buffer[0] = (buffer[0] & 0x8f) | 0x70;
- buffer[2] = (buffer[2] & 0x7f) | 0x00;
- buffer[5] = (buffer[5] & 0x80) | 0x31;
- buffer[6] = (buffer[6] & 0x40) | 0xb0;
- buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
- buffer[8] = (buffer[8] & 0x00) | 0x30;
- changed = 1;
- break;
- case 0x3142: /* AlBook 15" (ATI M10) */
- case 0x3143: /* AlBook 17" (ATI M10) */
- buffer[0] = (buffer[0] & 0xaf) | 0x50;
- buffer[2] = (buffer[2] & 0x7f) | 0x00;
- buffer[5] = (buffer[5] & 0x80) | 0x31;
- buffer[6] = (buffer[6] & 0x40) | 0xb0;
- buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
- buffer[8] = (buffer[8] & 0x00) | 0x30;
- changed = 1;
- break;
- default:
- DBG("i2c-hwclock: Machine model not handled\n");
- break;
- }
- if (!changed) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n",
- enable ? "En" : "Dis");
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
- DBG("write result: %d,", rc);
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
- DBG("read result: %d,", rc);
- if (rc != 0) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- for (i=0; i<9; i++)
- DBG(" %02x", buffer[i]);
- pmac_low_i2c_close(ui2c);
- break;
- }
-}
-
-
-static int
-core99_sleep(void)
-{
- struct macio_chip* macio;
- int i;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- /* We power off the wireless slot in case it was not done
- * by the driver. We don't power it on automatically however
- */
- if (macio->flags & MACIO_FLAG_AIRPORT_ON)
- core99_airport_enable(macio->of_node, 0, 0);
-
- /* We power off the FW cable. Should be done by the driver... */
- if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
- core99_firewire_enable(NULL, 0, 0);
- core99_firewire_cable_power(NULL, 0, 0);
- }
-
- /* We make sure int. modem is off (in case driver lost it) */
- if (macio->type == macio_keylargo)
- core99_modem_enable(macio->of_node, 0, 0);
- else
- pangea_modem_enable(macio->of_node, 0, 0);
-
- /* We make sure the sound is off as well */
- core99_sound_chip_enable(macio->of_node, 0, 0);
-
- /*
- * Save various bits of KeyLargo
- */
-
- /* Save the state of the various GPIOs */
- save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
- save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
- for (i=0; itype == macio_keylargo)
- save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
- save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
- save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
- save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
- save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
- save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
- if (macio->type == macio_pangea || macio->type == macio_intrepid)
- save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
-
- /* Save state & config of DBDMA channels */
- dbdma_save(macio, save_dbdma);
-
- /*
- * Turn off as much as we can
- */
- if (macio->type == macio_pangea)
- pangea_shutdown(macio, 1);
- else if (macio->type == macio_intrepid)
- intrepid_shutdown(macio, 1);
- else if (macio->type == macio_keylargo)
- keylargo_shutdown(macio, 1);
-
- /*
- * Put the host bridge to sleep
- */
-
- save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
- /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
- * enabled !
- */
- UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
- ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
- udelay(100);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
- mdelay(10);
-
- /*
- * FIXME: A bit of black magic with OpenPIC (don't ask me why)
- */
- if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
- MACIO_BIS(0x506e0, 0x00400000);
- MACIO_BIS(0x506e0, 0x80000000);
- }
- return 0;
-}
-
-static int
-core99_wake_up(void)
-{
- struct macio_chip* macio;
- int i;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- /*
- * Wakeup the host bridge
- */
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
- udelay(10);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
- udelay(10);
-
- /*
- * Restore KeyLargo
- */
-
- if (macio->type == macio_keylargo) {
- MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
- (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
- }
- MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
- (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
- (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
- (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
- (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
- (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
- if (macio->type == macio_pangea || macio->type == macio_intrepid) {
- MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
- (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
- }
-
- dbdma_restore(macio, save_dbdma);
-
- MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
- MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
- for (i=0; itype) {
-#ifndef CONFIG_POWER4
- case macio_grand_central:
- pmac_mb.model_id = PMAC_TYPE_PSURGE;
- pmac_mb.model_name = "Unknown PowerSurge";
- break;
- case macio_ohare:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
- pmac_mb.model_name = "Unknown OHare-based";
- break;
- case macio_heathrow:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
- pmac_mb.model_name = "Unknown Heathrow-based";
- pmac_mb.features = heathrow_desktop_features;
- break;
- case macio_paddington:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
- pmac_mb.model_name = "Unknown Paddington-based";
- pmac_mb.features = paddington_features;
- break;
- case macio_keylargo:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
- pmac_mb.model_name = "Unknown Keylargo-based";
- pmac_mb.features = core99_features;
- break;
- case macio_pangea:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
- pmac_mb.model_name = "Unknown Pangea-based";
- pmac_mb.features = pangea_features;
- break;
- case macio_intrepid:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
- pmac_mb.model_name = "Unknown Intrepid-based";
- pmac_mb.features = intrepid_features;
- break;
-#else /* CONFIG_POWER4 */
- case macio_keylargo2:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
- pmac_mb.model_name = "Unknown G5";
- pmac_mb.features = g5_features;
- break;
-#endif /* CONFIG_POWER4 */
- default:
- return -ENODEV;
- }
-found:
-#ifndef CONFIG_POWER4
- /* Fixup Hooper vs. Comet */
- if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
- u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
- if (!mach_id_ptr)
- return -ENODEV;
- /* Here, I used to disable the media-bay on comet. It
- * appears this is wrong, the floppy connector is actually
- * a kind of media-bay and works with the current driver.
- */
- if (__raw_readl(mach_id_ptr) & 0x20000000UL)
- pmac_mb.model_id = PMAC_TYPE_COMET;
- iounmap(mach_id_ptr);
- }
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_6xx
- /* Set default value of powersave_nap on machines that support it.
- * It appears that uninorth rev 3 has a problem with it, we don't
- * enable it on those. In theory, the flush-on-lock property is
- * supposed to be set when not supported, but I'm not very confident
- * that all Apple OF revs did it properly, I do it the paranoid way.
- */
- while (uninorth_base && uninorth_rev > 3) {
- struct device_node* np = find_path_device("/cpus");
- if (!np || !np->child) {
- printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
- break;
- }
- np = np->child;
- /* Nap mode not supported on SMP */
- if (np->sibling)
- break;
- /* Nap mode not supported if flush-on-lock property is present */
- if (get_property(np, "flush-on-lock", NULL))
- break;
- powersave_nap = 1;
- printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
- break;
- }
-
- /* On CPUs that support it (750FX), lowspeed by default during
- * NAP mode
- */
- powersave_lowspeed = 1;
-#endif /* CONFIG_6xx */
-#ifdef CONFIG_POWER4
- powersave_nap = 1;
-#endif
- /* Check for "mobile" machine */
- if (model && (strncmp(model, "PowerBook", 9) == 0
- || strncmp(model, "iBook", 5) == 0))
- pmac_mb.board_flags |= PMAC_MB_MOBILE;
-
-
- printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
- return 0;
-}
-
-/* Initialize the Core99 UniNorth host bridge and memory controller
- */
-static void __init
-probe_uninorth(void)
-{
- unsigned long actrl;
-
- /* Locate core99 Uni-N */
- uninorth_node = of_find_node_by_name(NULL, "uni-n");
- /* Locate G5 u3 */
- if (uninorth_node == NULL) {
- uninorth_node = of_find_node_by_name(NULL, "u3");
- uninorth_u3 = 1;
- }
- if (uninorth_node && uninorth_node->n_addrs > 0) {
- unsigned long address = uninorth_node->addrs[0].address;
- uninorth_base = ioremap(address, 0x40000);
- uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
- if (uninorth_u3)
- u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
- } else
- uninorth_node = NULL;
-
- if (!uninorth_node)
- return;
-
- printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
- uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
- printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
-
- /* Set the arbitrer QAck delay according to what Apple does
- */
- if (uninorth_rev < 0x11) {
- actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
- actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
- UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
- UN_OUT(UNI_N_ARB_CTRL, actrl);
- }
-
- /* Some more magic as done by them in recent MacOS X on UniNorth
- * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
- * memory timeout
- */
- if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
- UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
-}
-
-static void __init
-probe_one_macio(const char* name, const char* compat, int type)
-{
- struct device_node* node;
- int i;
- volatile u32 __iomem * base;
- u32* revp;
-
- node = find_devices(name);
- if (!node || !node->n_addrs)
- return;
- if (compat)
- do {
- if (device_is_compatible(node, compat))
- break;
- node = node->next;
- } while (node);
- if (!node)
- return;
- for(i=0; i= MAX_MACIO_CHIPS) {
- printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
- printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
- return;
- }
- base = ioremap(node->addrs[0].address, node->addrs[0].size);
- if (!base) {
- printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
- return;
- }
- if (type == macio_keylargo) {
- u32* did = (u32 *)get_property(node, "device-id", NULL);
- if (*did == 0x00000025)
- type = macio_pangea;
- if (*did == 0x0000003e)
- type = macio_intrepid;
- }
- macio_chips[i].of_node = node;
- macio_chips[i].type = type;
- macio_chips[i].base = base;
- macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
- macio_chips[i].name = macio_names[type];
- revp = (u32 *)get_property(node, "revision-id", NULL);
- if (revp)
- macio_chips[i].rev = *revp;
- printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
- macio_names[type], macio_chips[i].rev, macio_chips[i].base);
-}
-
-static int __init
-probe_macios(void)
-{
- /* Warning, ordering is important */
- probe_one_macio("gc", NULL, macio_grand_central);
- probe_one_macio("ohare", NULL, macio_ohare);
- probe_one_macio("pci106b,7", NULL, macio_ohareII);
- probe_one_macio("mac-io", "keylargo", macio_keylargo);
- probe_one_macio("mac-io", "paddington", macio_paddington);
- probe_one_macio("mac-io", "gatwick", macio_gatwick);
- probe_one_macio("mac-io", "heathrow", macio_heathrow);
- probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
-
- /* Make sure the "main" macio chip appear first */
- if (macio_chips[0].type == macio_gatwick
- && macio_chips[1].type == macio_heathrow) {
- struct macio_chip temp = macio_chips[0];
- macio_chips[0] = macio_chips[1];
- macio_chips[1] = temp;
- }
- if (macio_chips[0].type == macio_ohareII
- && macio_chips[1].type == macio_ohare) {
- struct macio_chip temp = macio_chips[0];
- macio_chips[0] = macio_chips[1];
- macio_chips[1] = temp;
- }
- macio_chips[0].lbus.index = 0;
- macio_chips[1].lbus.index = 1;
-
- return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
-}
-
-static void __init
-initial_serial_shutdown(struct device_node* np)
-{
- int len;
- struct slot_names_prop {
- int count;
- char name[1];
- } *slots;
- char *conn;
- int port_type = PMAC_SCC_ASYNC;
- int modem = 0;
-
- slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
- conn = get_property(np, "AAPL,connector", &len);
- if (conn && (strcmp(conn, "infrared") == 0))
- port_type = PMAC_SCC_IRDA;
- else if (device_is_compatible(np, "cobalt"))
- modem = 1;
- else if (slots && slots->count > 0) {
- if (strcmp(slots->name, "IrDA") == 0)
- port_type = PMAC_SCC_IRDA;
- else if (strcmp(slots->name, "Modem") == 0)
- modem = 1;
- }
- if (modem)
- pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
- pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
-}
-
-static void __init
-set_initial_features(void)
-{
- struct device_node* np;
-
- /* That hack appears to be necessary for some StarMax motherboards
- * but I'm not too sure it was audited for side-effects on other
- * ohare based machines...
- * Since I still have difficulties figuring the right way to
- * differenciate them all and since that hack was there for a long
- * time, I'll keep it around
- */
- if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
- struct macio_chip* macio = &macio_chips[0];
- MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
- } else if (macio_chips[0].type == macio_ohare) {
- struct macio_chip* macio = &macio_chips[0];
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- } else if (macio_chips[1].type == macio_ohare) {
- struct macio_chip* macio = &macio_chips[1];
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- }
-
-#ifdef CONFIG_POWER4
- if (macio_chips[0].type == macio_keylargo2) {
-#ifndef CONFIG_SMP
- /* On SMP machines running UP, we have the second CPU eating
- * bus cycles. We need to take it off the bus. This is done
- * from pmac_smp for SMP kernels running on one CPU
- */
- np = of_find_node_by_type(NULL, "cpu");
- if (np != NULL)
- np = of_find_node_by_type(np, "cpu");
- if (np != NULL) {
- g5_phy_disable_cpu1();
- of_node_put(np);
- }
-#endif /* CONFIG_SMP */
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (device_is_compatible(np, "K2-GMAC"))
- g5_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (device_is_compatible(np, "pci106b,5811")) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- g5_fw_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
- }
-#else /* CONFIG_POWER4 */
-
- if (macio_chips[0].type == macio_keylargo ||
- macio_chips[0].type == macio_pangea ||
- macio_chips[0].type == macio_intrepid) {
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "gmac"))
- core99_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && (device_is_compatible(np, "pci106b,18") ||
- device_is_compatible(np, "pci106b,30") ||
- device_is_compatible(np, "pci11c1,5811"))) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- core99_firewire_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
-
- /* Enable ATA-100 before PCI probe. */
- np = of_find_node_by_name(NULL, "ata-6");
- while(np) {
- if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "kauai-ata")) {
- core99_ata100_enable(np, 1);
- }
- np = of_find_node_by_name(np, "ata-6");
- }
-
- /* Switch airport off */
- np = find_devices("radio");
- while(np) {
- if (np && np->parent == macio_chips[0].of_node) {
- macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
- core99_airport_enable(np, 0, 0);
- }
- np = np->next;
- }
- }
-
- /* On all machines that support sound PM, switch sound off */
- if (macio_chips[0].of_node)
- pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
- macio_chips[0].of_node, 0, 0);
-
- /* While on some desktop G3s, we turn it back on */
- if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
- && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
- pmac_mb.model_id == PMAC_TYPE_SILK)) {
- struct macio_chip* macio = &macio_chips[0];
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
- }
-
- /* Some machine models need the clock chip to be properly setup for
- * clock spreading now. This should be a platform function but we
- * don't do these at the moment
- */
- pmac_tweak_clock_spreading(1);
-
-#endif /* CONFIG_POWER4 */
-
- /* On all machines, switch modem & serial ports off */
- np = find_devices("ch-a");
- while(np) {
- initial_serial_shutdown(np);
- np = np->next;
- }
- np = find_devices("ch-b");
- while(np) {
- initial_serial_shutdown(np);
- np = np->next;
- }
-}
-
-void __init
-pmac_feature_init(void)
-{
- /* Detect the UniNorth memory controller */
- probe_uninorth();
-
- /* Probe mac-io controllers */
- if (probe_macios()) {
- printk(KERN_WARNING "No mac-io chip found\n");
- return;
- }
-
- /* Setup low-level i2c stuffs */
- pmac_init_low_i2c();
-
- /* Probe machine type */
- if (probe_motherboard())
- printk(KERN_WARNING "Unknown PowerMac !\n");
-
- /* Set some initial features (turn off some chips that will
- * be later turned on)
- */
- set_initial_features();
-}
-
-int __init
-pmac_feature_late_init(void)
-{
- struct device_node* np;
-
- /* Request some resources late */
- if (uninorth_node)
- request_OF_resource(uninorth_node, 0, NULL);
- np = find_devices("hammerhead");
- if (np)
- request_OF_resource(np, 0, NULL);
- np = find_devices("interrupt-controller");
- if (np)
- request_OF_resource(np, 0, NULL);
- return 0;
-}
-
-device_initcall(pmac_feature_late_init);
-
-#ifdef CONFIG_POWER4
-
-static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
-{
- int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
- int bits[8] = { 8,16,0,32,2,4,0,0 };
- int freq = (frq >> 8) & 0xf;
-
- if (freqs[freq] == 0)
- printk("%s: Unknown HT link frequency %x\n", name, freq);
- else
- printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
- name, freqs[freq],
- bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
-}
-
-void __init pmac_check_ht_link(void)
-{
- u32 ufreq, freq, ucfg, cfg;
- struct device_node *pcix_node;
- u8 px_bus, px_devfn;
- struct pci_controller *px_hose;
-
- (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
- ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
- ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
- dump_HT_speeds("U3 HyperTransport", cfg, freq);
-
- pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
- if (pcix_node == NULL) {
- printk("No PCI-X bridge found\n");
- return;
- }
- if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
- printk("PCI-X bridge found but not matched to pci\n");
- return;
- }
- px_hose = pci_find_hose_for_OF_device(pcix_node);
- if (px_hose == NULL) {
- printk("PCI-X bridge found but not matched to host\n");
- return;
- }
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
- dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
- dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
-}
-
-#endif /* CONFIG_POWER4 */
-
-/*
- * Early video resume hook
- */
-
-static void (*pmac_early_vresume_proc)(void *data);
-static void *pmac_early_vresume_data;
-
-void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
-{
- if (_machine != _MACH_Pmac)
- return;
- preempt_disable();
- pmac_early_vresume_proc = proc;
- pmac_early_vresume_data = data;
- preempt_enable();
-}
-EXPORT_SYMBOL(pmac_set_early_video_resume);
-
-void pmac_call_early_video_resume(void)
-{
- if (pmac_early_vresume_proc)
- pmac_early_vresume_proc(pmac_early_vresume_data);
-}
-
-/*
- * AGP related suspend/resume code
- */
-
-static struct pci_dev *pmac_agp_bridge;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge);
-static int (*pmac_agp_resume)(struct pci_dev *bridge);
-
-void pmac_register_agp_pm(struct pci_dev *bridge,
- int (*suspend)(struct pci_dev *bridge),
- int (*resume)(struct pci_dev *bridge))
-{
- if (suspend || resume) {
- pmac_agp_bridge = bridge;
- pmac_agp_suspend = suspend;
- pmac_agp_resume = resume;
- return;
- }
- if (bridge != pmac_agp_bridge)
- return;
- pmac_agp_suspend = pmac_agp_resume = NULL;
- return;
-}
-EXPORT_SYMBOL(pmac_register_agp_pm);
-
-void pmac_suspend_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_suspend(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-
-void pmac_resume_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_resume(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_resume_agp_for_card);
diff --git a/arch/ppc/platforms/pmac_low_i2c.c b/arch/ppc/platforms/pmac_low_i2c.c
deleted file mode 100644
index 08583fce1692..000000000000
--- a/arch/ppc/platforms/pmac_low_i2c.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_low_i2c.c
- *
- * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * This file contains some low-level i2c access routines that
- * need to be used by various bits of the PowerMac platform code
- * at times where the real asynchronous & interrupt driven driver
- * cannot be used. The API borrows some semantics from the darwin
- * driver in order to ease the implementation of the platform
- * properties parser
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define MAX_LOW_I2C_HOST 4
-
-#if 1
-#define DBG(x...) do {\
- printk(KERN_DEBUG "KW:" x); \
- } while(0)
-#else
-#define DBGG(x...)
-#endif
-
-struct low_i2c_host;
-
-typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len);
-
-struct low_i2c_host
-{
- struct device_node *np; /* OF device node */
- struct semaphore mutex; /* Access mutex for use by i2c-keywest */
- low_i2c_func_t func; /* Access function */
- int is_open : 1; /* Poor man's access control */
- int mode; /* Current mode */
- int channel; /* Current channel */
- int num_channels; /* Number of channels */
- void __iomem * base; /* For keywest-i2c, base address */
- int bsteps; /* And register stepping */
- int speed; /* And speed */
-};
-
-static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST];
-
-/* No locking is necessary on allocation, we are running way before
- * anything can race with us
- */
-static struct low_i2c_host *find_low_i2c_host(struct device_node *np)
-{
- int i;
-
- for (i = 0; i < MAX_LOW_I2C_HOST; i++)
- if (low_i2c_hosts[i].np == np)
- return &low_i2c_hosts[i];
- return NULL;
-}
-
-/*
- *
- * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
- *
- */
-
-/*
- * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h,
- * should be moved somewhere in include/asm-ppc/
- */
-/* Register indices */
-typedef enum {
- reg_mode = 0,
- reg_control,
- reg_status,
- reg_isr,
- reg_ier,
- reg_addr,
- reg_subaddr,
- reg_data
-} reg_t;
-
-
-/* Mode register */
-#define KW_I2C_MODE_100KHZ 0x00
-#define KW_I2C_MODE_50KHZ 0x01
-#define KW_I2C_MODE_25KHZ 0x02
-#define KW_I2C_MODE_DUMB 0x00
-#define KW_I2C_MODE_STANDARD 0x04
-#define KW_I2C_MODE_STANDARDSUB 0x08
-#define KW_I2C_MODE_COMBINED 0x0C
-#define KW_I2C_MODE_MODE_MASK 0x0C
-#define KW_I2C_MODE_CHAN_MASK 0xF0
-
-/* Control register */
-#define KW_I2C_CTL_AAK 0x01
-#define KW_I2C_CTL_XADDR 0x02
-#define KW_I2C_CTL_STOP 0x04
-#define KW_I2C_CTL_START 0x08
-
-/* Status register */
-#define KW_I2C_STAT_BUSY 0x01
-#define KW_I2C_STAT_LAST_AAK 0x02
-#define KW_I2C_STAT_LAST_RW 0x04
-#define KW_I2C_STAT_SDA 0x08
-#define KW_I2C_STAT_SCL 0x10
-
-/* IER & ISR registers */
-#define KW_I2C_IRQ_DATA 0x01
-#define KW_I2C_IRQ_ADDR 0x02
-#define KW_I2C_IRQ_STOP 0x04
-#define KW_I2C_IRQ_START 0x08
-#define KW_I2C_IRQ_MASK 0x0F
-
-/* State machine states */
-enum {
- state_idle,
- state_addr,
- state_read,
- state_write,
- state_stop,
- state_dead
-};
-
-#define WRONG_STATE(name) do {\
- printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
- name, __kw_state_names[state], isr); \
- } while(0)
-
-static const char *__kw_state_names[] = {
- "state_idle",
- "state_addr",
- "state_read",
- "state_write",
- "state_stop",
- "state_dead"
-};
-
-static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg)
-{
- return in_8(host->base + (((unsigned)reg) << host->bsteps));
-}
-
-static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val)
-{
- out_8(host->base + (((unsigned)reg) << host->bsteps), val);
- (void)__kw_read_reg(host, reg_subaddr);
-}
-
-#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val)
-#define kw_read_reg(reg) __kw_read_reg(host, reg)
-
-
-/* Don't schedule, the g5 fan controller is too
- * timing sensitive
- */
-static u8 kw_wait_interrupt(struct low_i2c_host* host)
-{
- int i;
- u8 isr;
-
- for (i = 0; i < 200000; i++) {
- isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
- if (isr != 0)
- return isr;
- udelay(1);
- }
- return isr;
-}
-
-static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr)
-{
- u8 ack;
-
- if (isr == 0) {
- if (state != state_stop) {
- DBG("KW: Timeout !\n");
- *rc = -EIO;
- goto stop;
- }
- if (state == state_stop) {
- ack = kw_read_reg(reg_status);
- if (!(ack & KW_I2C_STAT_BUSY)) {
- state = state_idle;
- kw_write_reg(reg_ier, 0x00);
- }
- }
- return state;
- }
-
- if (isr & KW_I2C_IRQ_ADDR) {
- ack = kw_read_reg(reg_status);
- if (state != state_addr) {
- kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
- WRONG_STATE("KW_I2C_IRQ_ADDR");
- *rc = -EIO;
- goto stop;
- }
- if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
- *rc = -ENODEV;
- DBG("KW: NAK on address\n");
- return state_stop;
- } else {
- if (rw) {
- state = state_read;
- if (*len > 1)
- kw_write_reg(reg_control, KW_I2C_CTL_AAK);
- } else {
- state = state_write;
- kw_write_reg(reg_data, **data);
- (*data)++; (*len)--;
- }
- }
- kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
- }
-
- if (isr & KW_I2C_IRQ_DATA) {
- if (state == state_read) {
- **data = kw_read_reg(reg_data);
- (*data)++; (*len)--;
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- if ((*len) == 0)
- state = state_stop;
- else if ((*len) == 1)
- kw_write_reg(reg_control, 0);
- } else if (state == state_write) {
- ack = kw_read_reg(reg_status);
- if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
- DBG("KW: nack on data write\n");
- *rc = -EIO;
- goto stop;
- } else if (*len) {
- kw_write_reg(reg_data, **data);
- (*data)++; (*len)--;
- } else {
- kw_write_reg(reg_control, KW_I2C_CTL_STOP);
- state = state_stop;
- *rc = 0;
- }
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- } else {
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- WRONG_STATE("KW_I2C_IRQ_DATA");
- if (state != state_stop) {
- *rc = -EIO;
- goto stop;
- }
- }
- }
-
- if (isr & KW_I2C_IRQ_STOP) {
- kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
- if (state != state_stop) {
- WRONG_STATE("KW_I2C_IRQ_STOP");
- *rc = -EIO;
- }
- return state_idle;
- }
-
- if (isr & KW_I2C_IRQ_START)
- kw_write_reg(reg_isr, KW_I2C_IRQ_START);
-
- return state;
-
- stop:
- kw_write_reg(reg_control, KW_I2C_CTL_STOP);
- return state_stop;
-}
-
-static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len)
-{
- u8 mode_reg = host->speed;
- int state = state_addr;
- int rc = 0;
-
- /* Setup mode & subaddress if any */
- switch(host->mode) {
- case pmac_low_i2c_mode_dumb:
- printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
- return -EINVAL;
- case pmac_low_i2c_mode_std:
- mode_reg |= KW_I2C_MODE_STANDARD;
- break;
- case pmac_low_i2c_mode_stdsub:
- mode_reg |= KW_I2C_MODE_STANDARDSUB;
- kw_write_reg(reg_subaddr, subaddr);
- break;
- case pmac_low_i2c_mode_combined:
- mode_reg |= KW_I2C_MODE_COMBINED;
- kw_write_reg(reg_subaddr, subaddr);
- break;
- }
-
- /* Setup channel & clear pending irqs */
- kw_write_reg(reg_isr, kw_read_reg(reg_isr));
- kw_write_reg(reg_mode, mode_reg | (host->channel << 4));
- kw_write_reg(reg_status, 0);
-
- /* Set up address and r/w bit */
- kw_write_reg(reg_addr, addr);
-
- /* Start sending address & disable interrupt*/
- kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/);
- kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
-
- /* State machine, to turn into an interrupt handler */
- while(state != state_idle) {
- u8 isr = kw_wait_interrupt(host);
- state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr);
- }
-
- return rc;
-}
-
-static void keywest_low_i2c_add(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(NULL);
- unsigned long *psteps, *prate, steps, aoffset = 0;
- struct device_node *parent;
-
- if (host == NULL) {
- printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
- np->full_name);
- return;
- }
- memset(host, 0, sizeof(*host));
-
- init_MUTEX(&host->mutex);
- host->np = of_node_get(np);
- psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL);
- steps = psteps ? (*psteps) : 0x10;
- for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
- steps >>= 1;
- parent = of_get_parent(np);
- host->num_channels = 1;
- if (parent && parent->name[0] == 'u') {
- host->num_channels = 2;
- aoffset = 3;
- }
- /* Select interface rate */
- host->speed = KW_I2C_MODE_100KHZ;
- prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL);
- if (prate) switch(*prate) {
- case 100:
- host->speed = KW_I2C_MODE_100KHZ;
- break;
- case 50:
- host->speed = KW_I2C_MODE_50KHZ;
- break;
- case 25:
- host->speed = KW_I2C_MODE_25KHZ;
- break;
- }
- host->mode = pmac_low_i2c_mode_std;
- host->base = ioremap(np->addrs[0].address + aoffset,
- np->addrs[0].size);
- host->func = keywest_low_i2c_func;
-}
-
-/*
- *
- * PMU implementation
- *
- */
-
-
-#ifdef CONFIG_ADB_PMU
-
-static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len)
-{
- // TODO
- return -ENODEV;
-}
-
-static void pmu_low_i2c_add(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(NULL);
-
- if (host == NULL) {
- printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
- np->full_name);
- return;
- }
- memset(host, 0, sizeof(*host));
-
- init_MUTEX(&host->mutex);
- host->np = of_node_get(np);
- host->num_channels = 3;
- host->mode = pmac_low_i2c_mode_std;
- host->func = pmu_low_i2c_func;
-}
-
-#endif /* CONFIG_ADB_PMU */
-
-void __init pmac_init_low_i2c(void)
-{
- struct device_node *np;
-
- /* Probe keywest-i2c busses */
- np = of_find_compatible_node(NULL, "i2c", "keywest-i2c");
- while(np) {
- keywest_low_i2c_add(np);
- np = of_find_compatible_node(np, "i2c", "keywest-i2c");
- }
-
-#ifdef CONFIG_ADB_PMU
- /* Probe PMU busses */
- np = of_find_node_by_name(NULL, "via-pmu");
- if (np)
- pmu_low_i2c_add(np);
-#endif /* CONFIG_ADB_PMU */
-
- /* TODO: Add CUDA support as well */
-}
-
-int pmac_low_i2c_lock(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- down(&host->mutex);
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_lock);
-
-int pmac_low_i2c_unlock(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- up(&host->mutex);
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_unlock);
-
-
-int pmac_low_i2c_open(struct device_node *np, int channel)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
-
- if (channel >= host->num_channels)
- return -EINVAL;
-
- down(&host->mutex);
- host->is_open = 1;
- host->channel = channel;
-
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_open);
-
-int pmac_low_i2c_close(struct device_node *np)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
-
- host->is_open = 0;
- up(&host->mutex);
-
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_close);
-
-int pmac_low_i2c_setmode(struct device_node *np, int mode)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- WARN_ON(!host->is_open);
- host->mode = mode;
-
- return 0;
-}
-EXPORT_SYMBOL(pmac_low_i2c_setmode);
-
-int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len)
-{
- struct low_i2c_host *host = find_low_i2c_host(np);
-
- if (!host)
- return -ENODEV;
- WARN_ON(!host->is_open);
-
- return host->func(host, addrdir, subaddr, data, len);
-}
-EXPORT_SYMBOL(pmac_low_i2c_xfer);
-
diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
deleted file mode 100644
index 8c9b008c7226..000000000000
--- a/arch/ppc/platforms/pmac_nvram.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * arch/ppc/platforms/pmac_nvram.c
- *
- * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Todo: - add support for the OF persistent properties
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */
-
-#define CORE99_SIGNATURE 0x5a
-#define CORE99_ADLER_START 0x14
-
-/* On Core99, nvram is either a sharp, a micron or an AMD flash */
-#define SM_FLASH_STATUS_DONE 0x80
-#define SM_FLASH_STATUS_ERR 0x38
-#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0
-#define SM_FLASH_CMD_ERASE_SETUP 0x20
-#define SM_FLASH_CMD_RESET 0xff
-#define SM_FLASH_CMD_WRITE_SETUP 0x40
-#define SM_FLASH_CMD_CLEAR_STATUS 0x50
-#define SM_FLASH_CMD_READ_STATUS 0x70
-
-/* CHRP NVRAM header */
-struct chrp_header {
- u8 signature;
- u8 cksum;
- u16 len;
- char name[12];
- u8 data[0];
-};
-
-struct core99_header {
- struct chrp_header hdr;
- u32 adler;
- u32 generation;
- u32 reserved[2];
-};
-
-/*
- * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
- */
-static int nvram_naddrs;
-static volatile unsigned char *nvram_addr;
-static volatile unsigned char *nvram_data;
-static int nvram_mult, is_core_99;
-static int core99_bank = 0;
-static int nvram_partitions[3];
-static DEFINE_SPINLOCK(nv_lock);
-
-extern int pmac_newworld;
-extern int system_running;
-
-static int (*core99_write_bank)(int bank, u8* datas);
-static int (*core99_erase_bank)(int bank);
-
-static char *nvram_image;
-
-
-static unsigned char core99_nvram_read_byte(int addr)
-{
- if (nvram_image == NULL)
- return 0xff;
- return nvram_image[addr];
-}
-
-static void core99_nvram_write_byte(int addr, unsigned char val)
-{
- if (nvram_image == NULL)
- return;
- nvram_image[addr] = val;
-}
-
-
-static unsigned char direct_nvram_read_byte(int addr)
-{
- return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
-}
-
-static void direct_nvram_write_byte(int addr, unsigned char val)
-{
- out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
-}
-
-
-static unsigned char indirect_nvram_read_byte(int addr)
-{
- unsigned char val;
- unsigned long flags;
-
- spin_lock_irqsave(&nv_lock, flags);
- out_8(nvram_addr, addr >> 5);
- val = in_8(&nvram_data[(addr & 0x1f) << 4]);
- spin_unlock_irqrestore(&nv_lock, flags);
-
- return val;
-}
-
-static void indirect_nvram_write_byte(int addr, unsigned char val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&nv_lock, flags);
- out_8(nvram_addr, addr >> 5);
- out_8(&nvram_data[(addr & 0x1f) << 4], val);
- spin_unlock_irqrestore(&nv_lock, flags);
-}
-
-
-#ifdef CONFIG_ADB_PMU
-
-static void pmu_nvram_complete(struct adb_request *req)
-{
- if (req->arg)
- complete((struct completion *)req->arg);
-}
-
-static unsigned char pmu_nvram_read_byte(int addr)
-{
- struct adb_request req;
- DECLARE_COMPLETION(req_complete);
-
- req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
- if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
- (addr >> 8) & 0xff, addr & 0xff))
- return 0xff;
- if (system_state == SYSTEM_RUNNING)
- wait_for_completion(&req_complete);
- while (!req.complete)
- pmu_poll();
- return req.reply[0];
-}
-
-static void pmu_nvram_write_byte(int addr, unsigned char val)
-{
- struct adb_request req;
- DECLARE_COMPLETION(req_complete);
-
- req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
- if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
- (addr >> 8) & 0xff, addr & 0xff, val))
- return;
- if (system_state == SYSTEM_RUNNING)
- wait_for_completion(&req_complete);
- while (!req.complete)
- pmu_poll();
-}
-
-#endif /* CONFIG_ADB_PMU */
-
-
-static u8 chrp_checksum(struct chrp_header* hdr)
-{
- u8 *ptr;
- u16 sum = hdr->signature;
- for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
- sum += *ptr;
- while (sum > 0xFF)
- sum = (sum & 0xFF) + (sum>>8);
- return sum;
-}
-
-static u32 core99_calc_adler(u8 *buffer)
-{
- int cnt;
- u32 low, high;
-
- buffer += CORE99_ADLER_START;
- low = 1;
- high = 0;
- for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
- if ((cnt % 5000) == 0) {
- high %= 65521UL;
- high %= 65521UL;
- }
- low += buffer[cnt];
- high += low;
- }
- low %= 65521UL;
- high %= 65521UL;
-
- return (high << 16) | low;
-}
-
-static u32 core99_check(u8* datas)
-{
- struct core99_header* hdr99 = (struct core99_header*)datas;
-
- if (hdr99->hdr.signature != CORE99_SIGNATURE) {
- DBG("Invalid signature\n");
- return 0;
- }
- if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
- DBG("Invalid checksum\n");
- return 0;
- }
- if (hdr99->adler != core99_calc_adler(datas)) {
- DBG("Invalid adler\n");
- return 0;
- }
- return hdr99->generation;
-}
-
-static int sm_erase_bank(int bank)
-{
- int stat, i;
- unsigned long timeout;
-
- u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
-
- out_8(base, SM_FLASH_CMD_ERASE_SETUP);
- out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n");
- break;
- }
- out_8(base, SM_FLASH_CMD_READ_STATUS);
- stat = in_8(base);
- } while (!(stat & SM_FLASH_STATUS_DONE));
-
- out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
- out_8(base, SM_FLASH_CMD_RESET);
-
- for (i=0; i 1000000) {
- printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
- break;
- }
- out_8(base, SM_FLASH_CMD_READ_STATUS);
- stat = in_8(base);
- } while (!(stat & SM_FLASH_STATUS_DONE));
- if (!(stat & SM_FLASH_STATUS_DONE))
- break;
- }
- out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
- out_8(base, SM_FLASH_CMD_RESET);
- for (i=0; i 1000000) {
- printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
- break;
- }
- stat = in_8(base) ^ in_8(base);
- } while (stat != 0);
-
- /* Reset */
- out_8(base, 0xf0);
- udelay(1);
-
- for (i=0; i 1000000) {
- printk(KERN_ERR "nvram: AMD flash write timeout !\n");
- break;
- }
- stat = in_8(base) ^ in_8(base);
- } while (stat != 0);
- if (stat != 0)
- break;
- }
-
- /* Reset */
- out_8(base, 0xf0);
- udelay(1);
-
- for (i=0; iname, "common"))
- nvram_partitions[pmac_nvram_OF] = offset + 0x10;
- if (!strcmp(hdr->name, "APL,MacOS75")) {
- nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
- nvram_partitions[pmac_nvram_NR] = offset + 0x110;
- }
- offset += (hdr->len * 0x10);
- } while(offset < NVRAM_SIZE);
- } else {
- nvram_partitions[pmac_nvram_OF] = 0x1800;
- nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
- nvram_partitions[pmac_nvram_NR] = 0x1400;
- }
- DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
- DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
- DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
-}
-
-static void core99_nvram_sync(void)
-{
- struct core99_header* hdr99;
- unsigned long flags;
-
- if (!is_core_99 || !nvram_data || !nvram_image)
- return;
-
- spin_lock_irqsave(&nv_lock, flags);
- if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
- NVRAM_SIZE))
- goto bail;
-
- DBG("Updating nvram...\n");
-
- hdr99 = (struct core99_header*)nvram_image;
- hdr99->generation++;
- hdr99->hdr.signature = CORE99_SIGNATURE;
- hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
- hdr99->adler = core99_calc_adler(nvram_image);
- core99_bank = core99_bank ? 0 : 1;
- if (core99_erase_bank)
- if (core99_erase_bank(core99_bank)) {
- printk("nvram: Error erasing bank %d\n", core99_bank);
- goto bail;
- }
- if (core99_write_bank)
- if (core99_write_bank(core99_bank, nvram_image))
- printk("nvram: Error writing bank %d\n", core99_bank);
- bail:
- spin_unlock_irqrestore(&nv_lock, flags);
-
-#ifdef DEBUG
- mdelay(2000);
-#endif
-}
-
-void __init pmac_nvram_init(void)
-{
- struct device_node *dp;
-
- nvram_naddrs = 0;
-
- dp = find_devices("nvram");
- if (dp == NULL) {
- printk(KERN_ERR "Can't find NVRAM device\n");
- return;
- }
- nvram_naddrs = dp->n_addrs;
- is_core_99 = device_is_compatible(dp, "nvram,flash");
- if (is_core_99) {
- int i;
- u32 gen_bank0, gen_bank1;
-
- if (nvram_naddrs < 1) {
- printk(KERN_ERR "nvram: no address\n");
- return;
- }
- nvram_image = alloc_bootmem(NVRAM_SIZE);
- if (nvram_image == NULL) {
- printk(KERN_ERR "nvram: can't allocate ram image\n");
- return;
- }
- nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
- nvram_naddrs = 1; /* Make sure we get the correct case */
-
- DBG("nvram: Checking bank 0...\n");
-
- gen_bank0 = core99_check((u8 *)nvram_data);
- gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
- core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
-
- DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
- DBG("nvram: Active bank is: %d\n", core99_bank);
-
- for (i=0; iaddrs[0].address + isa_mem_base,
- dp->addrs[0].size);
- nvram_mult = 1;
- ppc_md.nvram_read_val = direct_nvram_read_byte;
- ppc_md.nvram_write_val = direct_nvram_write_byte;
- } else if (nvram_naddrs == 1) {
- nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
- nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
- ppc_md.nvram_read_val = direct_nvram_read_byte;
- ppc_md.nvram_write_val = direct_nvram_write_byte;
- } else if (nvram_naddrs == 2) {
- nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
- nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
- ppc_md.nvram_read_val = indirect_nvram_read_byte;
- ppc_md.nvram_write_val = indirect_nvram_write_byte;
- } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
-#ifdef CONFIG_ADB_PMU
- nvram_naddrs = -1;
- ppc_md.nvram_read_val = pmu_nvram_read_byte;
- ppc_md.nvram_write_val = pmu_nvram_write_byte;
-#endif /* CONFIG_ADB_PMU */
- } else {
- printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
- nvram_naddrs);
- }
- lookup_partitions();
-}
-
-int pmac_get_partition(int partition)
-{
- return nvram_partitions[partition];
-}
-
-u8 pmac_xpram_read(int xpaddr)
-{
- int offset = nvram_partitions[pmac_nvram_XPRAM];
-
- if (offset < 0)
- return 0xff;
-
- return ppc_md.nvram_read_val(xpaddr + offset);
-}
-
-void pmac_xpram_write(int xpaddr, u8 data)
-{
- int offset = nvram_partitions[pmac_nvram_XPRAM];
-
- if (offset < 0)
- return;
-
- ppc_md.nvram_write_val(xpaddr + offset, data);
-}
-
-EXPORT_SYMBOL(pmac_get_partition);
-EXPORT_SYMBOL(pmac_xpram_read);
-EXPORT_SYMBOL(pmac_xpram_write);
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
deleted file mode 100644
index 786295b6ddd0..000000000000
--- a/arch/ppc/platforms/pmac_pci.c
+++ /dev/null
@@ -1,1124 +0,0 @@
-/*
- * Support for PCI bridges found on Power Macintoshes.
- * At present the "bandit" and "chaos" bridges are supported.
- * Fortunately you access configuration space in the same
- * way with either bridge.
- *
- * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#undef DEBUG
-
-#ifdef DEBUG
-#ifdef CONFIG_XMON
-extern void xmon_printf(const char *fmt, ...);
-#define DBG(x...) xmon_printf(x)
-#else
-#define DBG(x...) printk(x)
-#endif
-#else
-#define DBG(x...)
-#endif
-
-static int add_bridge(struct device_node *dev);
-extern void pmac_check_ht_link(void);
-
-/* XXX Could be per-controller, but I don't think we risk anything by
- * assuming we won't have both UniNorth and Bandit */
-static int has_uninorth;
-#ifdef CONFIG_POWER4
-static struct pci_controller *u3_agp;
-#endif /* CONFIG_POWER4 */
-
-extern u8 pci_cache_line_size;
-extern int pcibios_assign_bus_offset;
-
-struct device_node *k2_skiplist[2];
-
-/*
- * Magic constants for enabling cache coherency in the bandit/PSX bridge.
- */
-#define BANDIT_DEVID_2 8
-#define BANDIT_REVID 3
-
-#define BANDIT_DEVNUM 11
-#define BANDIT_MAGIC 0x50
-#define BANDIT_COHERENT 0x40
-
-static int __init
-fixup_one_level_bus_range(struct device_node *node, int higher)
-{
- for (; node != 0;node = node->sibling) {
- int * bus_range;
- unsigned int *class_code;
- int len;
-
- /* For PCI<->PCI bridges or CardBus bridges, we go down */
- class_code = (unsigned int *) get_property(node, "class-code", NULL);
- if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
- (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
- continue;
- bus_range = (int *) get_property(node, "bus-range", &len);
- if (bus_range != NULL && len > 2 * sizeof(int)) {
- if (bus_range[1] > higher)
- higher = bus_range[1];
- }
- higher = fixup_one_level_bus_range(node->child, higher);
- }
- return higher;
-}
-
-/* This routine fixes the "bus-range" property of all bridges in the
- * system since they tend to have their "last" member wrong on macs
- *
- * Note that the bus numbers manipulated here are OF bus numbers, they
- * are not Linux bus numbers.
- */
-static void __init
-fixup_bus_range(struct device_node *bridge)
-{
- int * bus_range;
- int len;
-
- /* Lookup the "bus-range" property for the hose */
- bus_range = (int *) get_property(bridge, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s\n",
- bridge->full_name);
- return;
- }
- bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
-}
-
-/*
- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
- *
- * The "Bandit" version is present in all early PCI PowerMacs,
- * and up to the first ones using Grackle. Some machines may
- * have 2 bandit controllers (2 PCI busses).
- *
- * "Chaos" is used in some "Bandit"-type machines as a bridge
- * for the separate display bus. It is accessed the same
- * way as bandit, but cannot be probed for devices. It therefore
- * has its own config access functions.
- *
- * The "UniNorth" version is present in all Core99 machines
- * (iBook, G4, new IMacs, and all the recent Apple machines).
- * It contains 3 controllers in one ASIC.
- *
- * The U3 is the bridge used on G5 machines. It contains an
- * AGP bus which is dealt with the old UniNorth access routines
- * and a HyperTransport bus which uses its own set of access
- * functions.
- */
-
-#define MACRISC_CFA0(devfn, off) \
- ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
- | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
- | (((unsigned long)(off)) & 0xFCUL))
-
-#define MACRISC_CFA1(bus, devfn, off) \
- ((((unsigned long)(bus)) << 16) \
- |(((unsigned long)(devfn)) << 8) \
- |(((unsigned long)(off)) & 0xFCUL) \
- |1UL)
-
-static void volatile __iomem *
-macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
-{
- unsigned int caddr;
-
- if (bus == hose->first_busno) {
- if (dev_fn < (11 << 3))
- return NULL;
- caddr = MACRISC_CFA0(dev_fn, offset);
- } else
- caddr = MACRISC_CFA1(bus, dev_fn, offset);
-
- /* Uninorth will return garbage if we don't read back the value ! */
- do {
- out_le32(hose->cfg_addr, caddr);
- } while (in_le32(hose->cfg_addr) != caddr);
-
- offset &= has_uninorth ? 0x07 : 0x03;
- return hose->cfg_data + offset;
-}
-
-static int
-macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = in_le16(addr);
- break;
- default:
- *val = in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
-
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- (void) in_8(addr);
- break;
- case 2:
- out_le16(addr, val);
- (void) in_le16(addr);
- break;
- default:
- out_le32(addr, val);
- (void) in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macrisc_pci_ops =
-{
- macrisc_read_config,
- macrisc_write_config
-};
-
-/*
- * Verifiy that a specific (bus, dev_fn) exists on chaos
- */
-static int
-chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
-{
- struct device_node *np;
- u32 *vendor, *device;
-
- np = pci_busdev_to_OF_node(bus, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- vendor = (u32 *)get_property(np, "vendor-id", NULL);
- device = (u32 *)get_property(np, "device-id", NULL);
- if (vendor == NULL || device == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
- && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- int result = chaos_validate_dev(bus, devfn, offset);
- if (result == PCIBIOS_BAD_REGISTER_NUMBER)
- *val = ~0U;
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
- return macrisc_read_config(bus, devfn, offset, len, val);
-}
-
-static int
-chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- int result = chaos_validate_dev(bus, devfn, offset);
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
- return macrisc_write_config(bus, devfn, offset, len, val);
-}
-
-static struct pci_ops chaos_pci_ops =
-{
- chaos_read_config,
- chaos_write_config
-};
-
-#ifdef CONFIG_POWER4
-
-/*
- * These versions of U3 HyperTransport config space access ops do not
- * implement self-view of the HT host yet
- */
-
-#define U3_HT_CFA0(devfn, off) \
- ((((unsigned long)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off) \
- (U3_HT_CFA0(devfn, off) \
- + (((unsigned long)bus) << 16) \
- + 0x01000000UL)
-
-static void volatile __iomem *
-u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
-{
- if (bus == hose->first_busno) {
- /* For now, we don't self probe U3 HT bridge */
- if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||
- PCI_SLOT(devfn) < 1)
- return 0;
- return hose->cfg_data + U3_HT_CFA0(devfn, offset);
- } else
- return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
-}
-
-static int
-u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
- int i;
-
- struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == np) {
- switch (len) {
- case 1:
- *val = 0xff; break;
- case 2:
- *val = 0xffff; break;
- default:
- *val = 0xfffffffful; break;
- }
- return PCIBIOS_SUCCESSFUL;
- }
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = in_le16(addr);
- break;
- default:
- *val = in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- struct pci_controller *hose = bus->sysdata;
- void volatile __iomem *addr;
- int i;
-
- struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == np)
- return PCIBIOS_SUCCESSFUL;
-
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- (void) in_8(addr);
- break;
- case 2:
- out_le16(addr, val);
- (void) in_le16(addr);
- break;
- default:
- out_le32(addr, val);
- (void) in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_ht_pci_ops =
-{
- u3_ht_read_config,
- u3_ht_write_config
-};
-
-#endif /* CONFIG_POWER4 */
-
-/*
- * For a bandit bridge, turn on cache coherency if necessary.
- * N.B. we could clean this up using the hose ops directly.
- */
-static void __init
-init_bandit(struct pci_controller *bp)
-{
- unsigned int vendev, magic;
- int rev;
-
- /* read the word at offset 0 in config space for device 11 */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
- udelay(2);
- vendev = in_le32(bp->cfg_data);
- if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
- PCI_VENDOR_ID_APPLE) {
- /* read the revision id */
- out_le32(bp->cfg_addr,
- (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
- udelay(2);
- rev = in_8(bp->cfg_data);
- if (rev != BANDIT_REVID)
- printk(KERN_WARNING
- "Unknown revision %d for bandit\n", rev);
- } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
- printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
- return;
- }
-
- /* read the word at offset 0x50 */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
- udelay(2);
- magic = in_le32(bp->cfg_data);
- if ((magic & BANDIT_COHERENT) != 0)
- return;
- magic |= BANDIT_COHERENT;
- udelay(2);
- out_le32(bp->cfg_data, magic);
- printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
-}
-
-
-/*
- * Tweak the PCI-PCI bridge chip on the blue & white G3s.
- */
-static void __init
-init_p2pbridge(void)
-{
- struct device_node *p2pbridge;
- struct pci_controller* hose;
- u8 bus, devfn;
- u16 val;
-
- /* XXX it would be better here to identify the specific
- PCI-PCI bridge chip we have. */
- if ((p2pbridge = find_devices("pci-bridge")) == 0
- || p2pbridge->parent == NULL
- || strcmp(p2pbridge->parent->name, "pci") != 0)
- return;
- if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
- DBG("Can't find PCI infos for PCI<->PCI bridge\n");
- return;
- }
- /* Warning: At this point, we have not yet renumbered all busses.
- * So we must use OF walking to find out hose
- */
- hose = pci_find_hose_for_OF_device(p2pbridge);
- if (!hose) {
- DBG("Can't find hose for PCI<->PCI bridge\n");
- return;
- }
- if (early_read_config_word(hose, bus, devfn,
- PCI_BRIDGE_CONTROL, &val) < 0) {
- printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
- return;
- }
- val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
- early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
-}
-
-/*
- * Some Apple desktop machines have a NEC PD720100A USB2 controller
- * on the motherboard. Open Firmware, on these, will disable the
- * EHCI part of it so it behaves like a pair of OHCI's. This fixup
- * code re-enables it ;)
- */
-static void __init
-fixup_nec_usb2(void)
-{
- struct device_node *nec;
-
- for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
- struct pci_controller *hose;
- u32 data, *prop;
- u8 bus, devfn;
-
- prop = (u32 *)get_property(nec, "vendor-id", NULL);
- if (prop == NULL)
- continue;
- if (0x1033 != *prop)
- continue;
- prop = (u32 *)get_property(nec, "device-id", NULL);
- if (prop == NULL)
- continue;
- if (0x0035 != *prop)
- continue;
- prop = (u32 *)get_property(nec, "reg", NULL);
- if (prop == NULL)
- continue;
- devfn = (prop[0] >> 8) & 0xff;
- bus = (prop[0] >> 16) & 0xff;
- if (PCI_FUNC(devfn) != 0)
- continue;
- hose = pci_find_hose_for_OF_device(nec);
- if (!hose)
- continue;
- early_read_config_dword(hose, bus, devfn, 0xe4, &data);
- if (data & 1UL) {
- printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");
- data &= ~1UL;
- early_write_config_dword(hose, bus, devfn, 0xe4, data);
- early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
- nec->intrs[0].line);
- }
- }
-}
-
-void __init
-pmac_find_bridges(void)
-{
- struct device_node *np, *root;
- struct device_node *ht = NULL;
-
- root = of_find_node_by_path("/");
- if (root == NULL) {
- printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
- return;
- }
- for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
- if (np->name == NULL)
- continue;
- if (strcmp(np->name, "bandit") == 0
- || strcmp(np->name, "chaos") == 0
- || strcmp(np->name, "pci") == 0) {
- if (add_bridge(np) == 0)
- of_node_get(np);
- }
- if (strcmp(np->name, "ht") == 0) {
- of_node_get(np);
- ht = np;
- }
- }
- of_node_put(root);
-
- /* Probe HT last as it relies on the agp resources to be already
- * setup
- */
- if (ht && add_bridge(ht) != 0)
- of_node_put(ht);
-
- init_p2pbridge();
- fixup_nec_usb2();
-
- /* We are still having some issues with the Xserve G4, enabling
- * some offset between bus number and domains for now when we
- * assign all busses should help for now
- */
- if (pci_assign_all_buses)
- pcibios_assign_bus_offset = 0x10;
-
-#ifdef CONFIG_POWER4
- /* There is something wrong with DMA on U3/HT. I haven't figured out
- * the details yet, but if I set the cache line size to 128 bytes like
- * it should, I'm getting memory corruption caused by devices like
- * sungem (even without the MWI bit set, but maybe sungem doesn't
- * care). Right now, it appears that setting up a 64 bytes line size
- * works properly, 64 bytes beeing the max transfer size of HT, I
- * suppose this is related the way HT/PCI are hooked together. I still
- * need to dive into more specs though to be really sure of what's
- * going on. --BenH.
- *
- * Ok, apparently, it's just that HT can't do more than 64 bytes
- * transactions. MWI seem to be meaningless there as well, it may
- * be worth nop'ing out pci_set_mwi too though I haven't done that
- * yet.
- *
- * Note that it's a bit different for whatever is in the AGP slot.
- * For now, I don't care, but this can become a real issue, we
- * should probably hook pci_set_mwi anyway to make sure it sets
- * the real cache line size in there.
- */
- if (machine_is_compatible("MacRISC4"))
- pci_cache_line_size = 16; /* 64 bytes */
-
- pmac_check_ht_link();
-#endif /* CONFIG_POWER4 */
-}
-
-#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
- | (((o) & ~3) << 24))
-
-#define GRACKLE_PICR1_STG 0x00000040
-#define GRACKLE_PICR1_LOOPSNOOP 0x00000010
-
-/* N.B. this is called before bridges is initialized, so we can't
- use grackle_pcibios_{read,write}_config_dword. */
-static inline void grackle_set_stg(struct pci_controller* bp, int enable)
-{
- unsigned int val;
-
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- val = in_le32(bp->cfg_data);
- val = enable? (val | GRACKLE_PICR1_STG) :
- (val & ~GRACKLE_PICR1_STG);
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- out_le32(bp->cfg_data, val);
- (void)in_le32(bp->cfg_data);
-}
-
-static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
-{
- unsigned int val;
-
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- val = in_le32(bp->cfg_data);
- val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
- (val & ~GRACKLE_PICR1_LOOPSNOOP);
- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
- out_le32(bp->cfg_data, val);
- (void)in_le32(bp->cfg_data);
-}
-
-static int __init
-setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
-{
- pci_assign_all_buses = 1;
- has_uninorth = 1;
- hose->ops = ¯isc_pci_ops;
- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
- /* We "know" that the bridge at f2000000 has the PCI slots. */
- return addr->address == 0xf2000000;
-}
-
-static void __init
-setup_bandit(struct pci_controller* hose, struct reg_property* addr)
-{
- hose->ops = ¯isc_pci_ops;
- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
- init_bandit(hose);
-}
-
-static void __init
-setup_chaos(struct pci_controller* hose, struct reg_property* addr)
-{
- /* assume a `chaos' bridge */
- hose->ops = &chaos_pci_ops;
- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
-}
-
-#ifdef CONFIG_POWER4
-
-static void __init
-setup_u3_agp(struct pci_controller* hose, struct reg_property* addr)
-{
- /* On G5, we move AGP up to high bus number so we don't need
- * to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_buses to the
- * pci_controller structure so we enable it for AGP and not for
- * HT childs.
- * We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->first_busno = 0xf0;
- hose->last_busno = 0xff;
- has_uninorth = 1;
- hose->ops = ¯isc_pci_ops;
- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
-
- u3_agp = hose;
-}
-
-static void __init
-setup_u3_ht(struct pci_controller* hose, struct reg_property *addr)
-{
- struct device_node *np = (struct device_node *)hose->arch_data;
- int i, cur;
-
- hose->ops = &u3_ht_pci_ops;
-
- /* We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->cfg_data = ioremap(0xf2000000, 0x02000000);
-
- /*
- * /ht node doesn't expose a "ranges" property, so we "remove" regions that
- * have been allocated to AGP. So far, this version of the code doesn't assign
- * any of the 0xfxxxxxxx "fine" memory regions to /ht.
- * We need to fix that sooner or later by either parsing all child "ranges"
- * properties or figuring out the U3 address space decoding logic and
- * then read its configuration register (if any).
- */
- hose->io_base_phys = 0xf4000000;
- hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
- isa_io_base = (unsigned long) hose->io_base_virt;
- hose->io_resource.name = np->full_name;
- hose->io_resource.start = 0;
- hose->io_resource.end = 0x003fffff;
- hose->io_resource.flags = IORESOURCE_IO;
- hose->pci_mem_offset = 0;
- hose->first_busno = 0;
- hose->last_busno = 0xef;
- hose->mem_resources[0].name = np->full_name;
- hose->mem_resources[0].start = 0x80000000;
- hose->mem_resources[0].end = 0xefffffff;
- hose->mem_resources[0].flags = IORESOURCE_MEM;
-
- if (u3_agp == NULL) {
- DBG("U3 has no AGP, using full resource range\n");
- return;
- }
-
- /* We "remove" the AGP resources from the resources allocated to HT, that
- * is we create "holes". However, that code does assumptions that so far
- * happen to be true (cross fingers...), typically that resources in the
- * AGP node are properly ordered
- */
- cur = 0;
- for (i=0; i<3; i++) {
- struct resource *res = &u3_agp->mem_resources[i];
- if (res->flags != IORESOURCE_MEM)
- continue;
- /* We don't care about "fine" resources */
- if (res->start >= 0xf0000000)
- continue;
- /* Check if it's just a matter of "shrinking" us in one direction */
- if (hose->mem_resources[cur].start == res->start) {
- DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].start, res->end + 1);
- hose->mem_resources[cur].start = res->end + 1;
- continue;
- }
- if (hose->mem_resources[cur].end == res->end) {
- DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
- cur, hose->mem_resources[cur].end, res->start - 1);
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- /* No, it's not the case, we need a hole */
- if (cur == 2) {
- /* not enough resources to make a hole, we drop part of the range */
- printk(KERN_WARNING "Running out of resources for /ht host !\n");
- hose->mem_resources[cur].end = res->start - 1;
- continue;
- }
- cur++;
- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
- cur-1, res->start - 1, cur, res->end + 1);
- hose->mem_resources[cur].name = np->full_name;
- hose->mem_resources[cur].flags = IORESOURCE_MEM;
- hose->mem_resources[cur].start = res->end + 1;
- hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
- hose->mem_resources[cur-1].end = res->start - 1;
- }
-}
-
-#endif /* CONFIG_POWER4 */
-
-void __init
-setup_grackle(struct pci_controller *hose)
-{
- setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
- if (machine_is_compatible("AAPL,PowerBook1998"))
- grackle_set_loop_snoop(hose, 1);
-#if 0 /* Disabled for now, HW problems ??? */
- grackle_set_stg(hose, 1);
-#endif
-}
-
-/*
- * We assume that if we have a G3 powermac, we have one bridge called
- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
- * if we have one or more bandit or chaos bridges, we don't have a MPC106.
- */
-static int __init
-add_bridge(struct device_node *dev)
-{
- int len;
- struct pci_controller *hose;
- struct reg_property *addr;
- char* disp_name;
- int *bus_range;
- int primary = 1;
-
- DBG("Adding PCI host bridge %s\n", dev->full_name);
-
- addr = (struct reg_property *) get_property(dev, "reg", &len);
- if (addr == NULL || len < sizeof(*addr)) {
- printk(KERN_WARNING "Can't use %s: no address\n",
- dev->full_name);
- return -ENODEV;
- }
- bus_range = (int *) get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
- dev->full_name);
- }
-
- hose = pcibios_alloc_controller();
- if (!hose)
- return -ENOMEM;
- hose->arch_data = dev;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- disp_name = NULL;
-#ifdef CONFIG_POWER4
- if (device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose, addr);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose, addr);
- disp_name = "U3-HT";
- primary = 1;
- } else
-#endif /* CONFIG_POWER4 */
- if (device_is_compatible(dev, "uni-north")) {
- primary = setup_uninorth(hose, addr);
- disp_name = "UniNorth";
- } else if (strcmp(dev->name, "pci") == 0) {
- /* XXX assume this is a mpc106 (grackle) */
- setup_grackle(hose);
- disp_name = "Grackle (MPC106)";
- } else if (strcmp(dev->name, "bandit") == 0) {
- setup_bandit(hose, addr);
- disp_name = "Bandit";
- } else if (strcmp(dev->name, "chaos") == 0) {
- setup_chaos(hose, addr);
- disp_name = "Chaos";
- primary = 0;
- }
- printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",
- disp_name, addr->address, hose->first_busno, hose->last_busno);
- DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev, primary);
-
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
-
- return 0;
-}
-
-static void __init
-pcibios_fixup_OF_interrupts(void)
-{
- struct pci_dev* dev = NULL;
-
- /*
- * Open Firmware often doesn't initialize the
- * PCI_INTERRUPT_LINE config register properly, so we
- * should find the device node and apply the interrupt
- * obtained from the OF device-tree
- */
- for_each_pci_dev(dev) {
- struct device_node *node;
- node = pci_device_to_OF_node(dev);
- /* this is the node, see if it has interrupts */
- if (node && node->n_intrs > 0)
- dev->irq = node->intrs[0].line;
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
- }
-}
-
-void __init
-pmac_pcibios_fixup(void)
-{
- /* Fixup interrupts according to OF tree */
- pcibios_fixup_OF_interrupts();
-}
-
-int
-pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
-{
- struct device_node* node;
- int updatecfg = 0;
- int uninorth_child;
-
- node = pci_device_to_OF_node(dev);
-
- /* We don't want to enable USB controllers absent from the OF tree
- * (iBook second controller)
- */
- if (dev->vendor == PCI_VENDOR_ID_APPLE
- && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
- && !node) {
- printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
- pci_name(dev));
- return -EINVAL;
- }
-
- if (!node)
- return 0;
-
- uninorth_child = node->parent &&
- device_is_compatible(node->parent, "uni-north");
-
- /* Firewire & GMAC were disabled after PCI probe, the driver is
- * claiming them, we must re-enable them now.
- */
- if (uninorth_child && !strcmp(node->name, "firewire") &&
- (device_is_compatible(node, "pci106b,18") ||
- device_is_compatible(node, "pci106b,30") ||
- device_is_compatible(node, "pci11c1,5811"))) {
- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
- pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
- updatecfg = 1;
- }
- if (uninorth_child && !strcmp(node->name, "ethernet") &&
- device_is_compatible(node, "gmac")) {
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
- updatecfg = 1;
- }
-
- if (updatecfg) {
- u16 cmd;
-
- /*
- * Make sure PCI is correctly configured
- *
- * We use old pci_bios versions of the function since, by
- * default, gmac is not powered up, and so will be absent
- * from the kernel initial PCI lookup.
- *
- * Should be replaced by 2.4 new PCI mechanisms and really
- * register the device.
- */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
- }
-
- return 0;
-}
-
-/* We power down some devices after they have been probed. They'll
- * be powered back on later on
- */
-void __init
-pmac_pcibios_after_init(void)
-{
- struct device_node* nd;
-
-#ifdef CONFIG_BLK_DEV_IDE
- struct pci_dev *dev = NULL;
-
- /* OF fails to initialize IDE controllers on macs
- * (and maybe other machines)
- *
- * Ideally, this should be moved to the IDE layer, but we need
- * to check specifically with Andre Hedrick how to do it cleanly
- * since the common IDE code seem to care about the fact that the
- * BIOS may have disabled a controller.
- *
- * -- BenH
- */
- for_each_pci_dev(dev) {
- if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
- pci_enable_device(dev);
- }
-#endif /* CONFIG_BLK_DEV_IDE */
-
- nd = find_devices("firewire");
- while (nd) {
- if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
- device_is_compatible(nd, "pci106b,30") ||
- device_is_compatible(nd, "pci11c1,5811"))
- && device_is_compatible(nd->parent, "uni-north")) {
- pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
- }
- nd = nd->next;
- }
- nd = find_devices("ethernet");
- while (nd) {
- if (nd->parent && device_is_compatible(nd, "gmac")
- && device_is_compatible(nd->parent, "uni-north"))
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
- nd = nd->next;
- }
-}
-
-void pmac_pci_fixup_cardbus(struct pci_dev* dev)
-{
- if (_machine != _MACH_Pmac)
- return;
- /*
- * Fix the interrupt routing on the various cardbus bridges
- * used on powerbooks
- */
- if (dev->vendor != PCI_VENDOR_ID_TI)
- return;
- if (dev->device == PCI_DEVICE_ID_TI_1130 ||
- dev->device == PCI_DEVICE_ID_TI_1131) {
- u8 val;
- /* Enable PCI interrupt */
- if (pci_read_config_byte(dev, 0x91, &val) == 0)
- pci_write_config_byte(dev, 0x91, val | 0x30);
- /* Disable ISA interrupt mode */
- if (pci_read_config_byte(dev, 0x92, &val) == 0)
- pci_write_config_byte(dev, 0x92, val & ~0x06);
- }
- if (dev->device == PCI_DEVICE_ID_TI_1210 ||
- dev->device == PCI_DEVICE_ID_TI_1211 ||
- dev->device == PCI_DEVICE_ID_TI_1410 ||
- dev->device == PCI_DEVICE_ID_TI_1510) {
- u8 val;
- /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
- signal out the MFUNC0 pin */
- if (pci_read_config_byte(dev, 0x8c, &val) == 0)
- pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
- /* Disable ISA interrupt mode */
- if (pci_read_config_byte(dev, 0x92, &val) == 0)
- pci_write_config_byte(dev, 0x92, val & ~0x06);
- }
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
-
-void pmac_pci_fixup_pciata(struct pci_dev* dev)
-{
- u8 progif = 0;
-
- /*
- * On PowerMacs, we try to switch any PCI ATA controller to
- * fully native mode
- */
- if (_machine != _MACH_Pmac)
- return;
- /* Some controllers don't have the class IDE */
- if (dev->vendor == PCI_VENDOR_ID_PROMISE)
- switch(dev->device) {
- case PCI_DEVICE_ID_PROMISE_20246:
- case PCI_DEVICE_ID_PROMISE_20262:
- case PCI_DEVICE_ID_PROMISE_20263:
- case PCI_DEVICE_ID_PROMISE_20265:
- case PCI_DEVICE_ID_PROMISE_20267:
- case PCI_DEVICE_ID_PROMISE_20268:
- case PCI_DEVICE_ID_PROMISE_20269:
- case PCI_DEVICE_ID_PROMISE_20270:
- case PCI_DEVICE_ID_PROMISE_20271:
- case PCI_DEVICE_ID_PROMISE_20275:
- case PCI_DEVICE_ID_PROMISE_20276:
- case PCI_DEVICE_ID_PROMISE_20277:
- goto good;
- }
- /* Others, check PCI class */
- if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- good:
- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
- if ((progif & 5) != 5) {
- printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));
- (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
- if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
- (progif & 5) != 5)
- printk(KERN_ERR "Rewrite of PROGIF failed !\n");
- }
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
-
-
-/*
- * Disable second function on K2-SATA, it's broken
- * and disable IO BARs on first one
- */
-void pmac_pci_fixup_k2_sata(struct pci_dev* dev)
-{
- int i;
- u16 cmd;
-
- if (PCI_FUNC(dev->devfn) > 0) {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 6; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- } else {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_IO;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 5; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, pmac_pci_fixup_k2_sata);
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
deleted file mode 100644
index 4742bf609357..000000000000
--- a/arch/ppc/platforms/pmac_pic.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Support for the interrupt controllers found on Power Macintosh,
- * currently Apple's "Grand Central" interrupt controller in all
- * it's incarnations. OpenPIC support used on newer machines is
- * in a separate file
- *
- * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "pmac_pic.h"
-
-/*
- * XXX this should be in xmon.h, but putting it there means xmon.h
- * has to include (to get irqreturn_t), which
- * causes all sorts of problems. -- paulus
- */
-extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
-
-struct pmac_irq_hw {
- unsigned int event;
- unsigned int enable;
- unsigned int ack;
- unsigned int level;
-};
-
-/* Default addresses */
-static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
- (struct pmac_irq_hw *) 0xf3000020,
- (struct pmac_irq_hw *) 0xf3000010,
- (struct pmac_irq_hw *) 0xf4000020,
- (struct pmac_irq_hw *) 0xf4000010,
-};
-
-#define GC_LEVEL_MASK 0x3ff00000
-#define OHARE_LEVEL_MASK 0x1ff00000
-#define HEATHROW_LEVEL_MASK 0x1ff00000
-
-static int max_irqs;
-static int max_real_irqs;
-static u32 level_mask[4];
-
-static DEFINE_SPINLOCK(pmac_pic_lock);
-
-
-#define GATWICK_IRQ_POOL_SIZE 10
-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
-
-#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-
-/*
- * Mark an irq as "lost". This is only used on the pmac
- * since it can lose interrupts (see pmac_set_irq_mask).
- * -- Cort
- */
-void
-__set_lost(unsigned long irq_nr, int nokick)
-{
- if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
- atomic_inc(&ppc_n_lost_interrupts);
- if (!nokick)
- set_dec(1);
- }
-}
-
-static void
-pmac_mask_and_ack_irq(unsigned int irq_nr)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
- unsigned long flags;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- clear_bit(irq_nr, ppc_cached_irq_mask);
- if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
- atomic_dec(&ppc_n_lost_interrupts);
- spin_lock_irqsave(&pmac_pic_lock, flags);
- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
- out_le32(&pmac_irq_hw[i]->ack, bit);
- do {
- /* make sure ack gets to controller before we enable
- interrupts */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (ppc_cached_irq_mask[i] & bit));
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
- unsigned long flags;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- spin_lock_irqsave(&pmac_pic_lock, flags);
- /* enable unmasked interrupts */
- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
-
- do {
- /* make sure mask gets to controller before we
- return to user */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (ppc_cached_irq_mask[i] & bit));
-
- /*
- * Unfortunately, setting the bit in the enable register
- * when the device interrupt is already on *doesn't* set
- * the bit in the flag register or request another interrupt.
- */
- if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
- __set_lost((ulong)irq_nr, nokicklost);
- spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-/* When an irq gets requested for the first client, if it's an
- * edge interrupt, we clear any previous one on the controller
- */
-static unsigned int pmac_startup_irq(unsigned int irq_nr)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
-
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
- out_le32(&pmac_irq_hw[i]->ack, bit);
- set_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 0);
-
- return 0;
-}
-
-static void pmac_mask_irq(unsigned int irq_nr)
-{
- clear_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 0);
- mb();
-}
-
-static void pmac_unmask_irq(unsigned int irq_nr)
-{
- set_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 0);
-}
-
-static void pmac_end_irq(unsigned int irq_nr)
-{
- if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
- && irq_desc[irq_nr].action) {
- set_bit(irq_nr, ppc_cached_irq_mask);
- pmac_set_irq_mask(irq_nr, 1);
- }
-}
-
-
-struct hw_interrupt_type pmac_pic = {
- .typename = " PMAC-PIC ",
- .startup = pmac_startup_irq,
- .enable = pmac_unmask_irq,
- .disable = pmac_mask_irq,
- .ack = pmac_mask_and_ack_irq,
- .end = pmac_end_irq,
-};
-
-struct hw_interrupt_type gatwick_pic = {
- .typename = " GATWICK ",
- .startup = pmac_startup_irq,
- .enable = pmac_unmask_irq,
- .disable = pmac_mask_irq,
- .ack = pmac_mask_and_ack_irq,
- .end = pmac_end_irq,
-};
-
-static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int irq, bits;
-
- for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
- int i = irq >> 5;
- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
- /* We must read level interrupts from the level register */
- bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
- bits &= ppc_cached_irq_mask[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- __do_IRQ(irq, regs);
- return IRQ_HANDLED;
- }
- printk("gatwick irq not from gatwick pic\n");
- return IRQ_NONE;
-}
-
-int
-pmac_get_irq(struct pt_regs *regs)
-{
- int irq;
- unsigned long bits = 0;
-
-#ifdef CONFIG_SMP
- void psurge_smp_message_recv(struct pt_regs *);
-
- /* IPI's are a hack on the powersurge -- Cort */
- if ( smp_processor_id() != 0 ) {
- psurge_smp_message_recv(regs);
- return -2; /* ignore, already handled */
- }
-#endif /* CONFIG_SMP */
- for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
- int i = irq >> 5;
- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
- /* We must read level interrupts from the level register */
- bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
- bits &= ppc_cached_irq_mask[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- break;
- }
-
- return irq;
-}
-
-/* This routine will fix some missing interrupt values in the device tree
- * on the gatwick mac-io controller used by some PowerBooks
- */
-static void __init
-pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
-{
- struct device_node *node;
- int count;
-
- memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
- node = gw->child;
- count = 0;
- while(node)
- {
- /* Fix SCC */
- if (strcasecmp(node->name, "escc") == 0)
- if (node->child) {
- if (node->child->n_intrs < 3) {
- node->child->intrs = &gatwick_int_pool[count];
- count += 3;
- }
- node->child->n_intrs = 3;
- node->child->intrs[0].line = 15+irq_base;
- node->child->intrs[1].line = 4+irq_base;
- node->child->intrs[2].line = 5+irq_base;
- printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
- node->child->intrs[0].line,
- node->child->intrs[1].line,
- node->child->intrs[2].line);
- }
- /* Fix media-bay & left SWIM */
- if (strcasecmp(node->name, "media-bay") == 0) {
- struct device_node* ya_node;
-
- if (node->n_intrs == 0)
- node->intrs = &gatwick_int_pool[count++];
- node->n_intrs = 1;
- node->intrs[0].line = 29+irq_base;
- printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
- node->intrs[0].line);
-
- ya_node = node->child;
- while(ya_node)
- {
- if (strcasecmp(ya_node->name, "floppy") == 0) {
- if (ya_node->n_intrs < 2) {
- ya_node->intrs = &gatwick_int_pool[count];
- count += 2;
- }
- ya_node->n_intrs = 2;
- ya_node->intrs[0].line = 19+irq_base;
- ya_node->intrs[1].line = 1+irq_base;
- printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
- ya_node->intrs[0].line, ya_node->intrs[1].line);
- }
- if (strcasecmp(ya_node->name, "ata4") == 0) {
- if (ya_node->n_intrs < 2) {
- ya_node->intrs = &gatwick_int_pool[count];
- count += 2;
- }
- ya_node->n_intrs = 2;
- ya_node->intrs[0].line = 14+irq_base;
- ya_node->intrs[1].line = 3+irq_base;
- printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
- ya_node->intrs[0].line, ya_node->intrs[1].line);
- }
- ya_node = ya_node->sibling;
- }
- }
- node = node->sibling;
- }
- if (count > 10) {
- printk("WARNING !! Gatwick interrupt pool overflow\n");
- printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
- printk(" requested = %d\n", count);
- }
-}
-
-/*
- * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
- * card which includes an ohare chip that acts as a second interrupt
- * controller. If we find this second ohare, set it up and fix the
- * interrupt value in the device tree for the ethernet chip.
- */
-static int __init enable_second_ohare(void)
-{
- unsigned char bus, devfn;
- unsigned short cmd;
- unsigned long addr;
- struct device_node *irqctrler = find_devices("pci106b,7");
- struct device_node *ether;
-
- if (irqctrler == NULL || irqctrler->n_addrs <= 0)
- return -1;
- addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
- pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
- max_irqs = 64;
- if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
- struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
- if (!hose)
- printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
- else {
- early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- cmd &= ~PCI_COMMAND_IO;
- early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
- }
- }
-
- /* Fix interrupt for the modem/ethernet combo controller. The number
- in the device tree (27) is bogus (correct for the ethernet-only
- board but not the combo ethernet/modem board).
- The real interrupt is 28 on the second controller -> 28+32 = 60.
- */
- ether = find_devices("pci1011,14");
- if (ether && ether->n_intrs > 0) {
- ether->intrs[0].line = 60;
- printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
- ether->intrs[0].line);
- }
-
- /* Return the interrupt number of the cascade */
- return irqctrler->intrs[0].line;
-}
-
-#ifdef CONFIG_POWER4
-static irqreturn_t k2u3_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int irq;
-
- irq = openpic2_get_irq(regs);
- if (irq != -1)
- __do_IRQ(irq, regs);
- return IRQ_HANDLED;
-}
-
-static struct irqaction k2u3_cascade_action = {
- .handler = k2u3_action,
- .flags = 0,
- .mask = CPU_MASK_NONE,
- .name = "U3->K2 Cascade",
-};
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_XMON
-static struct irqaction xmon_action = {
- .handler = xmon_irq,
- .flags = 0,
- .mask = CPU_MASK_NONE,
- .name = "NMI - XMON"
-};
-#endif
-
-static struct irqaction gatwick_cascade_action = {
- .handler = gatwick_action,
- .flags = SA_INTERRUPT,
- .mask = CPU_MASK_NONE,
- .name = "cascade",
-};
-
-void __init pmac_pic_init(void)
-{
- int i;
- struct device_node *irqctrler = NULL;
- struct device_node *irqctrler2 = NULL;
- struct device_node *np;
- unsigned long addr;
- int irq_cascade = -1;
-
- /* We first try to detect Apple's new Core99 chipset, since mac-io
- * is quite different on those machines and contains an IBM MPIC2.
- */
- np = find_type_devices("open-pic");
- while(np) {
- if (np->parent && !strcmp(np->parent->name, "u3"))
- irqctrler2 = np;
- else
- irqctrler = np;
- np = np->next;
- }
- if (irqctrler != NULL)
- {
- if (irqctrler->n_addrs > 0)
- {
- unsigned char senses[128];
-
- printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
- irqctrler->addrs[0].address);
-
- prom_get_irq_senses(senses, 0, 128);
- OpenPIC_InitSenses = senses;
- OpenPIC_NumInitSenses = 128;
- ppc_md.get_irq = openpic_get_irq;
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
- OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
- irqctrler->addrs[0].size);
- openpic_init(0);
-
-#ifdef CONFIG_POWER4
- if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
- irqctrler2->n_addrs > 0) {
- printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
- irqctrler2->addrs[0].address,
- irqctrler2->intrs[0].line);
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
- OpenPIC2_Addr = ioremap(irqctrler2->addrs[0].address,
- irqctrler2->addrs[0].size);
- prom_get_irq_senses(senses, PMAC_OPENPIC2_OFFSET,
- PMAC_OPENPIC2_OFFSET+128);
- OpenPIC_InitSenses = senses;
- OpenPIC_NumInitSenses = 128;
- openpic2_init(PMAC_OPENPIC2_OFFSET);
-
- if (setup_irq(irqctrler2->intrs[0].line,
- &k2u3_cascade_action))
- printk("Unable to get OpenPIC IRQ for cascade\n");
- }
-#endif /* CONFIG_POWER4 */
-
-#ifdef CONFIG_XMON
- {
- struct device_node* pswitch;
- int nmi_irq;
-
- pswitch = find_devices("programmer-switch");
- if (pswitch && pswitch->n_intrs) {
- nmi_irq = pswitch->intrs[0].line;
- openpic_init_nmi_irq(nmi_irq);
- setup_irq(nmi_irq, &xmon_action);
- }
- }
-#endif /* CONFIG_XMON */
- return;
- }
- irqctrler = NULL;
- }
-
- /* Get the level/edge settings, assume if it's not
- * a Grand Central nor an OHare, then it's an Heathrow
- * (or Paddington).
- */
- if (find_devices("gc"))
- level_mask[0] = GC_LEVEL_MASK;
- else if (find_devices("ohare")) {
- level_mask[0] = OHARE_LEVEL_MASK;
- /* We might have a second cascaded ohare */
- level_mask[1] = OHARE_LEVEL_MASK;
- } else {
- level_mask[0] = HEATHROW_LEVEL_MASK;
- level_mask[1] = 0;
- /* We might have a second cascaded heathrow */
- level_mask[2] = HEATHROW_LEVEL_MASK;
- level_mask[3] = 0;
- }
-
- /*
- * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
- * 1998 G3 Series PowerBooks have 128,
- * other powermacs have 32.
- * The combo ethernet/modem card for the Powerstar powerbooks
- * (2400/3400/3500, ohare based) has a second ohare chip
- * effectively making a total of 64.
- */
- max_irqs = max_real_irqs = 32;
- irqctrler = find_devices("mac-io");
- if (irqctrler)
- {
- max_real_irqs = 64;
- if (irqctrler->next)
- max_irqs = 128;
- else
- max_irqs = 64;
- }
- for ( i = 0; i < max_real_irqs ; i++ )
- irq_desc[i].handler = &pmac_pic;
-
- /* get addresses of first controller */
- if (irqctrler) {
- if (irqctrler->n_addrs > 0) {
- addr = (unsigned long)
- ioremap(irqctrler->addrs[0].address, 0x40);
- for (i = 0; i < 2; ++i)
- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
- (addr + (2 - i) * 0x10);
- }
-
- /* get addresses of second controller */
- irqctrler = irqctrler->next;
- if (irqctrler && irqctrler->n_addrs > 0) {
- addr = (unsigned long)
- ioremap(irqctrler->addrs[0].address, 0x40);
- for (i = 2; i < 4; ++i)
- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
- (addr + (4 - i) * 0x10);
- irq_cascade = irqctrler->intrs[0].line;
- if (device_is_compatible(irqctrler, "gatwick"))
- pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
- }
- } else {
- /* older powermacs have a GC (grand central) or ohare at
- f3000000, with interrupt control registers at f3000020. */
- addr = (unsigned long) ioremap(0xf3000000, 0x40);
- pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);
- }
-
- /* PowerBooks 3400 and 3500 can have a second controller in a second
- ohare chip, on the combo ethernet/modem card */
- if (machine_is_compatible("AAPL,3400/2400")
- || machine_is_compatible("AAPL,3500"))
- irq_cascade = enable_second_ohare();
-
- /* disable all interrupts in all controllers */
- for (i = 0; i * 32 < max_irqs; ++i)
- out_le32(&pmac_irq_hw[i]->enable, 0);
- /* mark level interrupts */
- for (i = 0; i < max_irqs; i++)
- if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
- irq_desc[i].status = IRQ_LEVEL;
-
- /* get interrupt line of secondary interrupt controller */
- if (irq_cascade >= 0) {
- printk(KERN_INFO "irq: secondary controller on irq %d\n",
- (int)irq_cascade);
- for ( i = max_real_irqs ; i < max_irqs ; i++ )
- irq_desc[i].handler = &gatwick_pic;
- setup_irq(irq_cascade, &gatwick_cascade_action);
- }
- printk("System has %d possible interrupts\n", max_irqs);
- if (max_irqs != max_real_irqs)
- printk(KERN_DEBUG "%d interrupts on main controller\n",
- max_real_irqs);
-
-#ifdef CONFIG_XMON
- setup_irq(20, &xmon_action);
-#endif /* CONFIG_XMON */
-}
-
-#ifdef CONFIG_PM
-/*
- * These procedures are used in implementing sleep on the powerbooks.
- * sleep_save_intrs() saves the states of all interrupt enables
- * and disables all interrupts except for the nominated one.
- * sleep_restore_intrs() restores the states of all interrupt enables.
- */
-unsigned long sleep_save_mask[2];
-
-/* This used to be passed by the PMU driver but that link got
- * broken with the new driver model. We use this tweak for now...
- */
-static int pmacpic_find_viaint(void)
-{
- int viaint = -1;
-
-#ifdef CONFIG_ADB_PMU
- struct device_node *np;
-
- if (pmu_get_model() != PMU_OHARE_BASED)
- goto not_found;
- np = of_find_node_by_name(NULL, "via-pmu");
- if (np == NULL)
- goto not_found;
- viaint = np->intrs[0].line;
-#endif /* CONFIG_ADB_PMU */
-
-not_found:
- return viaint;
-}
-
-static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
-{
- int viaint = pmacpic_find_viaint();
-
- sleep_save_mask[0] = ppc_cached_irq_mask[0];
- sleep_save_mask[1] = ppc_cached_irq_mask[1];
- ppc_cached_irq_mask[0] = 0;
- ppc_cached_irq_mask[1] = 0;
- if (viaint > 0)
- set_bit(viaint, ppc_cached_irq_mask);
- out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
- if (max_real_irqs > 32)
- out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
- (void)in_le32(&pmac_irq_hw[0]->event);
- /* make sure mask gets to controller before we return to caller */
- mb();
- (void)in_le32(&pmac_irq_hw[0]->enable);
-
- return 0;
-}
-
-static int pmacpic_resume(struct sys_device *sysdev)
-{
- int i;
-
- out_le32(&pmac_irq_hw[0]->enable, 0);
- if (max_real_irqs > 32)
- out_le32(&pmac_irq_hw[1]->enable, 0);
- mb();
- for (i = 0; i < max_real_irqs; ++i)
- if (test_bit(i, sleep_save_mask))
- pmac_unmask_irq(i);
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-static struct sysdev_class pmacpic_sysclass = {
- set_kset_name("pmac_pic"),
-};
-
-static struct sys_device device_pmacpic = {
- .id = 0,
- .cls = &pmacpic_sysclass,
-};
-
-static struct sysdev_driver driver_pmacpic = {
-#ifdef CONFIG_PM
- .suspend = &pmacpic_suspend,
- .resume = &pmacpic_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init init_pmacpic_sysfs(void)
-{
- if (max_irqs == 0)
- return -ENODEV;
-
- printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
- sysdev_class_register(&pmacpic_sysclass);
- sysdev_register(&device_pmacpic);
- sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
- return 0;
-}
-
-subsys_initcall(init_pmacpic_sysfs);
-
diff --git a/arch/ppc/platforms/pmac_pic.h b/arch/ppc/platforms/pmac_pic.h
deleted file mode 100644
index 664103dfeef9..000000000000
--- a/arch/ppc/platforms/pmac_pic.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __PPC_PLATFORMS_PMAC_PIC_H
-#define __PPC_PLATFORMS_PMAC_PIC_H
-
-#include
-
-extern struct hw_interrupt_type pmac_pic;
-
-void pmac_pic_init(void);
-int pmac_get_irq(struct pt_regs *regs);
-
-#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
deleted file mode 100644
index 55d2beffe560..000000000000
--- a/arch/ppc/platforms/pmac_setup.c
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * arch/ppc/platforms/setup.c
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Adapted for Power Macintosh by Paul Mackerras
- * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *
- * Derived from "arch/alpha/kernel/setup.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-/*
- * bootup setup stuff..
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "pmac_pic.h"
-#include "mem_pieces.h"
-
-#undef SHOW_GATWICK_IRQS
-
-extern long pmac_time_init(void);
-extern unsigned long pmac_get_rtc_time(void);
-extern int pmac_set_rtc_time(unsigned long nowtime);
-extern void pmac_read_rtc_time(void);
-extern void pmac_calibrate_decr(void);
-extern void pmac_pcibios_fixup(void);
-extern void pmac_find_bridges(void);
-extern unsigned long pmac_ide_get_base(int index);
-extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
- unsigned long data_port, unsigned long ctrl_port, int *irq);
-
-extern void pmac_nvram_update(void);
-extern unsigned char pmac_nvram_read_byte(int addr);
-extern void pmac_nvram_write_byte(int addr, unsigned char val);
-extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
-extern void pmac_pcibios_after_init(void);
-extern int of_show_percpuinfo(struct seq_file *m, int i);
-
-struct device_node *memory_node;
-
-unsigned char drive_info;
-
-int ppc_override_l2cr = 0;
-int ppc_override_l2cr_value;
-int has_l2cache = 0;
-
-static int current_root_goodness = -1;
-
-extern int pmac_newworld;
-
-#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
-
-extern void zs_kgdb_hook(int tty_num);
-static void ohare_init(void);
-#ifdef CONFIG_BOOTX_TEXT
-static void pmac_progress(char *s, unsigned short hex);
-#endif
-
-sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
-
-#ifdef CONFIG_SMP
-extern struct smp_ops_t psurge_smp_ops;
-extern struct smp_ops_t core99_smp_ops;
-#endif /* CONFIG_SMP */
-
-static int
-pmac_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *np;
- char *pp;
- int plen;
- int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
- NULL, PMAC_MB_INFO_MODEL, 0);
- unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
- NULL, PMAC_MB_INFO_FLAGS, 0);
- char* mbname;
-
- if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
- mbname = "Unknown";
-
- /* find motherboard type */
- seq_printf(m, "machine\t\t: ");
- np = find_devices("device-tree");
- if (np != NULL) {
- pp = (char *) get_property(np, "model", NULL);
- if (pp != NULL)
- seq_printf(m, "%s\n", pp);
- else
- seq_printf(m, "PowerMac\n");
- pp = (char *) get_property(np, "compatible", &plen);
- if (pp != NULL) {
- seq_printf(m, "motherboard\t:");
- while (plen > 0) {
- int l = strlen(pp) + 1;
- seq_printf(m, " %s", pp);
- plen -= l;
- pp += l;
- }
- seq_printf(m, "\n");
- }
- } else
- seq_printf(m, "PowerMac\n");
-
- /* print parsed model */
- seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
- seq_printf(m, "pmac flags\t: %08x\n", mbflags);
-
- /* find l2 cache info */
- np = find_devices("l2-cache");
- if (np == 0)
- np = find_type_devices("cache");
- if (np != 0) {
- unsigned int *ic = (unsigned int *)
- get_property(np, "i-cache-size", NULL);
- unsigned int *dc = (unsigned int *)
- get_property(np, "d-cache-size", NULL);
- seq_printf(m, "L2 cache\t:");
- has_l2cache = 1;
- if (get_property(np, "cache-unified", NULL) != 0 && dc) {
- seq_printf(m, " %dK unified", *dc / 1024);
- } else {
- if (ic)
- seq_printf(m, " %dK instruction", *ic / 1024);
- if (dc)
- seq_printf(m, "%s %dK data",
- (ic? " +": ""), *dc / 1024);
- }
- pp = get_property(np, "ram-type", NULL);
- if (pp)
- seq_printf(m, " %s", pp);
- seq_printf(m, "\n");
- }
-
- /* find ram info */
- np = find_devices("memory");
- if (np != 0) {
- int n;
- struct reg_property *reg = (struct reg_property *)
- get_property(np, "reg", &n);
-
- if (reg != 0) {
- unsigned long total = 0;
-
- for (n /= sizeof(struct reg_property); n > 0; --n)
- total += (reg++)->size;
- seq_printf(m, "memory\t\t: %luMB\n", total >> 20);
- }
- }
-
- /* Checks "l2cr-value" property in the registry */
- np = find_devices("cpus");
- if (np == 0)
- np = find_type_devices("cpu");
- if (np != 0) {
- unsigned int *l2cr = (unsigned int *)
- get_property(np, "l2cr-value", NULL);
- if (l2cr != 0) {
- seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr);
- }
- }
-
- /* Indicate newworld/oldworld */
- seq_printf(m, "pmac-generation\t: %s\n",
- pmac_newworld ? "NewWorld" : "OldWorld");
-
-
- return 0;
-}
-
-static int
-pmac_show_percpuinfo(struct seq_file *m, int i)
-{
-#ifdef CONFIG_CPU_FREQ_PMAC
- extern unsigned int pmac_get_one_cpufreq(int i);
- unsigned int freq = pmac_get_one_cpufreq(i);
- if (freq != 0) {
- seq_printf(m, "clock\t\t: %dMHz\n", freq/1000);
- return 0;
- }
-#endif /* CONFIG_CPU_FREQ_PMAC */
- return of_show_percpuinfo(m, i);
-}
-
-static volatile u32 *sysctrl_regs;
-
-void __init
-pmac_setup_arch(void)
-{
- struct device_node *cpu;
- int *fp;
- unsigned long pvr;
-
- pvr = PVR_VER(mfspr(SPRN_PVR));
-
- /* Set loops_per_jiffy to a half-way reasonable value,
- for use until calibrate_delay gets called. */
- cpu = find_type_devices("cpu");
- if (cpu != 0) {
- fp = (int *) get_property(cpu, "clock-frequency", NULL);
- if (fp != 0) {
- if (pvr == 4 || pvr >= 8)
- /* 604, G3, G4 etc. */
- loops_per_jiffy = *fp / HZ;
- else
- /* 601, 603, etc. */
- loops_per_jiffy = *fp / (2*HZ);
- } else
- loops_per_jiffy = 50000000 / HZ;
- }
-
- /* this area has the CPU identification register
- and some registers used by smp boards */
- sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
- ohare_init();
-
- /* Lookup PCI hosts */
- pmac_find_bridges();
-
- /* Checks "l2cr-value" property in the registry */
- if (cpu_has_feature(CPU_FTR_L2CR)) {
- struct device_node *np = find_devices("cpus");
- if (np == 0)
- np = find_type_devices("cpu");
- if (np != 0) {
- unsigned int *l2cr = (unsigned int *)
- get_property(np, "l2cr-value", NULL);
- if (l2cr != 0) {
- ppc_override_l2cr = 1;
- ppc_override_l2cr_value = *l2cr;
- _set_L2CR(0);
- _set_L2CR(ppc_override_l2cr_value);
- }
- }
- }
-
- if (ppc_override_l2cr)
- printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
- ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
- ? "enabled" : "disabled");
-
-#ifdef CONFIG_KGDB
- zs_kgdb_hook(0);
-#endif
-
-#ifdef CONFIG_ADB_CUDA
- find_via_cuda();
-#else
- if (find_devices("via-cuda")) {
- printk("WARNING ! Your machine is Cuda based but your kernel\n");
- printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n");
- }
-#endif
-#ifdef CONFIG_ADB_PMU
- find_via_pmu();
-#else
- if (find_devices("via-pmu")) {
- printk("WARNING ! Your machine is PMU based but your kernel\n");
- printk(" wasn't compiled with CONFIG_ADB_PMU option !\n");
- }
-#endif
-#ifdef CONFIG_NVRAM
- pmac_nvram_init();
-#endif
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
- ROOT_DEV = Root_RAM0;
- else
-#endif
- ROOT_DEV = DEFAULT_ROOT_DEVICE;
-
-#ifdef CONFIG_SMP
- /* Check for Core99 */
- if (find_devices("uni-n") || find_devices("u3"))
- smp_ops = &core99_smp_ops;
- else
- smp_ops = &psurge_smp_ops;
-#endif /* CONFIG_SMP */
-
- pci_create_OF_bus_map();
-}
-
-static void __init ohare_init(void)
-{
- /*
- * Turn on the L2 cache.
- * We assume that we have a PSX memory controller iff
- * we have an ohare I/O controller.
- */
- if (find_devices("ohare") != NULL) {
- if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
- if (sysctrl_regs[4] & 0x10)
- sysctrl_regs[4] |= 0x04000020;
- else
- sysctrl_regs[4] |= 0x04000000;
- if(has_l2cache)
- printk(KERN_INFO "Level 2 cache enabled\n");
- }
- }
-}
-
-extern char *bootpath;
-extern char *bootdevice;
-void *boot_host;
-int boot_target;
-int boot_part;
-extern dev_t boot_dev;
-
-#ifdef CONFIG_SCSI
-void __init
-note_scsi_host(struct device_node *node, void *host)
-{
- int l;
- char *p;
-
- l = strlen(node->full_name);
- if (bootpath != NULL && bootdevice != NULL
- && strncmp(node->full_name, bootdevice, l) == 0
- && (bootdevice[l] == '/' || bootdevice[l] == 0)) {
- boot_host = host;
- /*
- * There's a bug in OF 1.0.5. (Why am I not surprised.)
- * If you pass a path like scsi/sd@1:0 to canon, it returns
- * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0
- * That is, the scsi target number doesn't get preserved.
- * So we pick the target number out of bootpath and use that.
- */
- p = strstr(bootpath, "/sd@");
- if (p != NULL) {
- p += 4;
- boot_target = simple_strtoul(p, NULL, 10);
- p = strchr(p, ':');
- if (p != NULL)
- boot_part = simple_strtoul(p + 1, NULL, 10);
- }
- }
-}
-#endif
-
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-static dev_t __init
-find_ide_boot(void)
-{
- char *p;
- int n;
- dev_t __init pmac_find_ide_boot(char *bootdevice, int n);
-
- if (bootdevice == NULL)
- return 0;
- p = strrchr(bootdevice, '/');
- if (p == NULL)
- return 0;
- n = p - bootdevice;
-
- return pmac_find_ide_boot(bootdevice, n);
-}
-#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
-
-static void __init
-find_boot_device(void)
-{
-#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
- boot_dev = find_ide_boot();
-#endif
-}
-
-static int initializing = 1;
-/* TODO: Merge the suspend-to-ram with the common code !!!
- * currently, this is a stub implementation for suspend-to-disk
- * only
- */
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-
-static int pmac_pm_prepare(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- return 0;
-}
-
-static int pmac_pm_enter(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Giveup the lazy FPU & vec so we don't have to back them
- * up from the low level code
- */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- return 0;
-}
-
-static int pmac_pm_finish(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Restore userland MMU context */
- set_context(current->active_mm->context, current->active_mm->pgd);
-
- return 0;
-}
-
-static struct pm_ops pmac_pm_ops = {
- .pm_disk_mode = PM_DISK_SHUTDOWN,
- .prepare = pmac_pm_prepare,
- .enter = pmac_pm_enter,
- .finish = pmac_pm_finish,
-};
-
-#endif /* CONFIG_SOFTWARE_SUSPEND */
-
-static int pmac_late_init(void)
-{
- initializing = 0;
-#ifdef CONFIG_SOFTWARE_SUSPEND
- pm_set_ops(&pmac_pm_ops);
-#endif /* CONFIG_SOFTWARE_SUSPEND */
- return 0;
-}
-
-late_initcall(pmac_late_init);
-
-/* can't be __init - can be called whenever a disk is first accessed */
-void
-note_bootable_part(dev_t dev, int part, int goodness)
-{
- static int found_boot = 0;
- char *p;
-
- if (!initializing)
- return;
- if ((goodness <= current_root_goodness) &&
- ROOT_DEV != DEFAULT_ROOT_DEVICE)
- return;
- p = strstr(saved_command_line, "root=");
- if (p != NULL && (p == saved_command_line || p[-1] == ' '))
- return;
-
- if (!found_boot) {
- find_boot_device();
- found_boot = 1;
- }
- if (!boot_dev || dev == boot_dev) {
- ROOT_DEV = dev + part;
- boot_dev = 0;
- current_root_goodness = goodness;
- }
-}
-
-static void
-pmac_restart(char *cmd)
-{
-#ifdef CONFIG_ADB_CUDA
- struct adb_request req;
-#endif /* CONFIG_ADB_CUDA */
-
- switch (sys_ctrler) {
-#ifdef CONFIG_ADB_CUDA
- case SYS_CTRLER_CUDA:
- cuda_request(&req, NULL, 2, CUDA_PACKET,
- CUDA_RESET_SYSTEM);
- for (;;)
- cuda_poll();
- break;
-#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_restart();
- break;
-#endif /* CONFIG_ADB_PMU */
- default: ;
- }
-}
-
-static void
-pmac_power_off(void)
-{
-#ifdef CONFIG_ADB_CUDA
- struct adb_request req;
-#endif /* CONFIG_ADB_CUDA */
-
- switch (sys_ctrler) {
-#ifdef CONFIG_ADB_CUDA
- case SYS_CTRLER_CUDA:
- cuda_request(&req, NULL, 2, CUDA_PACKET,
- CUDA_POWERDOWN);
- for (;;)
- cuda_poll();
- break;
-#endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU
- case SYS_CTRLER_PMU:
- pmu_shutdown();
- break;
-#endif /* CONFIG_ADB_PMU */
- default: ;
- }
-}
-
-static void
-pmac_halt(void)
-{
- pmac_power_off();
-}
-
-/*
- * Read in a property describing some pieces of memory.
- */
-
-static int __init
-get_mem_prop(char *name, struct mem_pieces *mp)
-{
- struct reg_property *rp;
- int i, s;
- unsigned int *ip;
- int nac = prom_n_addr_cells(memory_node);
- int nsc = prom_n_size_cells(memory_node);
-
- ip = (unsigned int *) get_property(memory_node, name, &s);
- if (ip == NULL) {
- printk(KERN_ERR "error: couldn't get %s property on /memory\n",
- name);
- return 0;
- }
- s /= (nsc + nac) * 4;
- rp = mp->regions;
- for (i = 0; i < s; ++i, ip += nac+nsc) {
- if (nac >= 2 && ip[nac-2] != 0)
- continue;
- rp->address = ip[nac-1];
- if (nsc >= 2 && ip[nac+nsc-2] != 0)
- rp->size = ~0U;
- else
- rp->size = ip[nac+nsc-1];
- ++rp;
- }
- mp->n_regions = rp - mp->regions;
-
- /* Make sure the pieces are sorted. */
- mem_pieces_sort(mp);
- mem_pieces_coalesce(mp);
- return 1;
-}
-
-/*
- * On systems with Open Firmware, collect information about
- * physical RAM and which pieces are already in use.
- * At this point, we have (at least) the first 8MB mapped with a BAT.
- * Our text, data, bss use something over 1MB, starting at 0.
- * Open Firmware may be using 1MB at the 4MB point.
- */
-unsigned long __init
-pmac_find_end_of_memory(void)
-{
- unsigned long a, total;
- struct mem_pieces phys_mem;
-
- /*
- * Find out where physical memory is, and check that it
- * starts at 0 and is contiguous. It seems that RAM is
- * always physically contiguous on Power Macintoshes.
- *
- * Supporting discontiguous physical memory isn't hard,
- * it just makes the virtual <-> physical mapping functions
- * more complicated (or else you end up wasting space
- * in mem_map).
- */
- memory_node = find_devices("memory");
- if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
- || phys_mem.n_regions == 0)
- panic("No RAM??");
- a = phys_mem.regions[0].address;
- if (a != 0)
- panic("RAM doesn't start at physical address 0");
- total = phys_mem.regions[0].size;
-
- if (phys_mem.n_regions > 1) {
- printk("RAM starting at 0x%x is not contiguous\n",
- phys_mem.regions[1].address);
- printk("Using RAM from 0 to 0x%lx\n", total-1);
- }
-
- return total;
-}
-
-void __init
-pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7)
-{
- /* isa_io_base gets set in pmac_find_bridges */
- isa_mem_base = PMAC_ISA_MEM_BASE;
- pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
- ISA_DMA_THRESHOLD = ~0L;
- DMA_MODE_READ = 1;
- DMA_MODE_WRITE = 2;
-
- ppc_md.setup_arch = pmac_setup_arch;
- ppc_md.show_cpuinfo = pmac_show_cpuinfo;
- ppc_md.show_percpuinfo = pmac_show_percpuinfo;
- ppc_md.init_IRQ = pmac_pic_init;
- ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
-
- ppc_md.pcibios_fixup = pmac_pcibios_fixup;
- ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
- ppc_md.pcibios_after_init = pmac_pcibios_after_init;
- ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
-
- ppc_md.restart = pmac_restart;
- ppc_md.power_off = pmac_power_off;
- ppc_md.halt = pmac_halt;
-
- ppc_md.time_init = pmac_time_init;
- ppc_md.set_rtc_time = pmac_set_rtc_time;
- ppc_md.get_rtc_time = pmac_get_rtc_time;
- ppc_md.calibrate_decr = pmac_calibrate_decr;
-
- ppc_md.find_end_of_memory = pmac_find_end_of_memory;
-
- ppc_md.feature_call = pmac_do_feature_call;
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-#ifdef CONFIG_BLK_DEV_IDE_PMAC
- ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
- ppc_ide_md.default_io_base = pmac_ide_get_base;
-#endif /* CONFIG_BLK_DEV_IDE_PMAC */
-#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
-
-#ifdef CONFIG_BOOTX_TEXT
- ppc_md.progress = pmac_progress;
-#endif /* CONFIG_BOOTX_TEXT */
-
- if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
-
-}
-
-#ifdef CONFIG_BOOTX_TEXT
-static void __init
-pmac_progress(char *s, unsigned short hex)
-{
- if (boot_text_mapped) {
- btext_drawstring(s);
- btext_drawchar('\n');
- }
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-static int __init
-pmac_declare_of_platform_devices(void)
-{
- struct device_node *np;
-
- np = find_devices("uni-n");
- if (np) {
- for (np = np->child; np != NULL; np = np->sibling)
- if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "uni-n-i2c",
- NULL);
- break;
- }
- }
- np = find_devices("u3");
- if (np) {
- for (np = np->child; np != NULL; np = np->sibling)
- if (strncmp(np->name, "i2c", 3) == 0) {
- of_platform_device_create(np, "u3-i2c",
- NULL);
- break;
- }
- }
-
- np = find_devices("valkyrie");
- if (np)
- of_platform_device_create(np, "valkyrie", NULL);
- np = find_devices("platinum");
- if (np)
- of_platform_device_create(np, "platinum", NULL);
-
- return 0;
-}
-
-device_initcall(pmac_declare_of_platform_devices);
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
deleted file mode 100644
index 22b113d19b24..000000000000
--- a/arch/ppc/platforms/pmac_sleep.S
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * This file contains sleep low-level functions for PowerBook G3.
- * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- * and Paul Mackerras (paulus@samba.org).
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define MAGIC 0x4c617273 /* 'Lars' */
-
-/*
- * Structure for storing CPU registers on the stack.
- */
-#define SL_SP 0
-#define SL_PC 4
-#define SL_MSR 8
-#define SL_SDR1 0xc
-#define SL_SPRG0 0x10 /* 4 sprg's */
-#define SL_DBAT0 0x20
-#define SL_IBAT0 0x28
-#define SL_DBAT1 0x30
-#define SL_IBAT1 0x38
-#define SL_DBAT2 0x40
-#define SL_IBAT2 0x48
-#define SL_DBAT3 0x50
-#define SL_IBAT3 0x58
-#define SL_TB 0x60
-#define SL_R2 0x68
-#define SL_CR 0x6c
-#define SL_R12 0x70 /* r12 to r31 */
-#define SL_SIZE (SL_R12 + 80)
-
- .section .text
- .align 5
-
-#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
-
-/* This gets called by via-pmu.c late during the sleep process.
- * The PMU was already send the sleep command and will shut us down
- * soon. We need to save all that is needed and setup the wakeup
- * vector that will be called by the ROM on wakeup
- */
-_GLOBAL(low_sleep_handler)
-#ifndef CONFIG_6xx
- blr
-#else
- mflr r0
- stw r0,4(r1)
- stwu r1,-SL_SIZE(r1)
- mfcr r0
- stw r0,SL_CR(r1)
- stw r2,SL_R2(r1)
- stmw r12,SL_R12(r1)
-
- /* Save MSR & SDR1 */
- mfmsr r4
- stw r4,SL_MSR(r1)
- mfsdr1 r4
- stw r4,SL_SDR1(r1)
-
- /* Get a stable timebase and save it */
-1: mftbu r4
- stw r4,SL_TB(r1)
- mftb r5
- stw r5,SL_TB+4(r1)
- mftbu r3
- cmpw r3,r4
- bne 1b
-
- /* Save SPRGs */
- mfsprg r4,0
- stw r4,SL_SPRG0(r1)
- mfsprg r4,1
- stw r4,SL_SPRG0+4(r1)
- mfsprg r4,2
- stw r4,SL_SPRG0+8(r1)
- mfsprg r4,3
- stw r4,SL_SPRG0+12(r1)
-
- /* Save BATs */
- mfdbatu r4,0
- stw r4,SL_DBAT0(r1)
- mfdbatl r4,0
- stw r4,SL_DBAT0+4(r1)
- mfdbatu r4,1
- stw r4,SL_DBAT1(r1)
- mfdbatl r4,1
- stw r4,SL_DBAT1+4(r1)
- mfdbatu r4,2
- stw r4,SL_DBAT2(r1)
- mfdbatl r4,2
- stw r4,SL_DBAT2+4(r1)
- mfdbatu r4,3
- stw r4,SL_DBAT3(r1)
- mfdbatl r4,3
- stw r4,SL_DBAT3+4(r1)
- mfibatu r4,0
- stw r4,SL_IBAT0(r1)
- mfibatl r4,0
- stw r4,SL_IBAT0+4(r1)
- mfibatu r4,1
- stw r4,SL_IBAT1(r1)
- mfibatl r4,1
- stw r4,SL_IBAT1+4(r1)
- mfibatu r4,2
- stw r4,SL_IBAT2(r1)
- mfibatl r4,2
- stw r4,SL_IBAT2+4(r1)
- mfibatu r4,3
- stw r4,SL_IBAT3(r1)
- mfibatl r4,3
- stw r4,SL_IBAT3+4(r1)
-
- /* Backup various CPU config stuffs */
- bl __save_cpu_setup
-
- /* The ROM can wake us up via 2 different vectors:
- * - On wallstreet & lombard, we must write a magic
- * value 'Lars' at address 4 and a pointer to a
- * memory location containing the PC to resume from
- * at address 0.
- * - On Core99, we must store the wakeup vector at
- * address 0x80 and eventually it's parameters
- * at address 0x84. I've have some trouble with those
- * parameters however and I no longer use them.
- */
- lis r5,grackle_wake_up@ha
- addi r5,r5,grackle_wake_up@l
- tophys(r5,r5)
- stw r5,SL_PC(r1)
- lis r4,KERNELBASE@h
- tophys(r5,r1)
- addi r5,r5,SL_PC
- lis r6,MAGIC@ha
- addi r6,r6,MAGIC@l
- stw r5,0(r4)
- stw r6,4(r4)
- /* Setup stuffs at 0x80-0x84 for Core99 */
- lis r3,core99_wake_up@ha
- addi r3,r3,core99_wake_up@l
- tophys(r3,r3)
- stw r3,0x80(r4)
- stw r5,0x84(r4)
- /* Store a pointer to our backup storage into
- * a kernel global
- */
- lis r3,sleep_storage@ha
- addi r3,r3,sleep_storage@l
- stw r5,0(r3)
-
- .globl low_cpu_die
-low_cpu_die:
- /* Flush & disable all caches */
- bl flush_disable_caches
-
- /* Turn off data relocation. */
- mfmsr r3 /* Save MSR in r7 */
- rlwinm r3,r3,0,28,26 /* Turn off DR bit */
- sync
- mtmsr r3
- isync
-
-BEGIN_FTR_SECTION
- /* Flush any pending L2 data prefetches to work around HW bug */
- sync
- lis r3,0xfff0
- lwz r0,0(r3) /* perform cache-inhibited load to ROM */
- sync /* (caches are disabled at this point) */
-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
-
-/*
- * Set the HID0 and MSR for sleep.
- */
- mfspr r2,SPRN_HID0
- rlwinm r2,r2,0,10,7 /* clear doze, nap */
- oris r2,r2,HID0_SLEEP@h
- sync
- isync
- mtspr SPRN_HID0,r2
- sync
-
-/* This loop puts us back to sleep in case we have a spurrious
- * wakeup so that the host bridge properly stays asleep. The
- * CPU will be turned off, either after a known time (about 1
- * second) on wallstreet & lombard, or as soon as the CPU enters
- * SLEEP mode on core99
- */
- mfmsr r2
- oris r2,r2,MSR_POW@h
-1: sync
- mtmsr r2
- isync
- b 1b
-
-/*
- * Here is the resume code.
- */
-
-
-/*
- * Core99 machines resume here
- * r4 has the physical address of SL_PC(sp) (unused)
- */
-_GLOBAL(core99_wake_up)
- /* Make sure HID0 no longer contains any sleep bit and that data cache
- * is disabled
- */
- mfspr r3,SPRN_HID0
- rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
- rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
- mtspr SPRN_HID0,r3
- sync
- isync
-
- /* sanitize MSR */
- mfmsr r3
- ori r3,r3,MSR_EE|MSR_IP
- xori r3,r3,MSR_EE|MSR_IP
- sync
- isync
- mtmsr r3
- sync
- isync
-
- /* Recover sleep storage */
- lis r3,sleep_storage@ha
- addi r3,r3,sleep_storage@l
- tophys(r3,r3)
- lwz r1,0(r3)
-
- /* Pass thru to older resume code ... */
-/*
- * Here is the resume code for older machines.
- * r1 has the physical address of SL_PC(sp).
- */
-
-grackle_wake_up:
-
- /* Restore the kernel's segment registers before
- * we do any r1 memory access as we are not sure they
- * are in a sane state above the first 256Mb region
- */
- li r0,16 /* load up segment register values */
- mtctr r0 /* for context 0 */
- lis r3,0x2000 /* Ku = 1, VSID = 0 */
- li r4,0
-3: mtsrin r3,r4
- addi r3,r3,0x111 /* increment VSID */
- addis r4,r4,0x1000 /* address of next segment */
- bdnz 3b
- sync
- isync
-
- subi r1,r1,SL_PC
-
- /* Restore various CPU config stuffs */
- bl __restore_cpu_setup
-
- /* Make sure all FPRs have been initialized */
- bl reloc_offset
- bl __init_fpu_registers
-
- /* Invalidate & enable L1 cache, we don't care about
- * whatever the ROM may have tried to write to memory
- */
- bl __inval_enable_L1
-
- /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
- lwz r4,SL_SDR1(r1)
- mtsdr1 r4
- lwz r4,SL_SPRG0(r1)
- mtsprg 0,r4
- lwz r4,SL_SPRG0+4(r1)
- mtsprg 1,r4
- lwz r4,SL_SPRG0+8(r1)
- mtsprg 2,r4
- lwz r4,SL_SPRG0+12(r1)
- mtsprg 3,r4
-
- lwz r4,SL_DBAT0(r1)
- mtdbatu 0,r4
- lwz r4,SL_DBAT0+4(r1)
- mtdbatl 0,r4
- lwz r4,SL_DBAT1(r1)
- mtdbatu 1,r4
- lwz r4,SL_DBAT1+4(r1)
- mtdbatl 1,r4
- lwz r4,SL_DBAT2(r1)
- mtdbatu 2,r4
- lwz r4,SL_DBAT2+4(r1)
- mtdbatl 2,r4
- lwz r4,SL_DBAT3(r1)
- mtdbatu 3,r4
- lwz r4,SL_DBAT3+4(r1)
- mtdbatl 3,r4
- lwz r4,SL_IBAT0(r1)
- mtibatu 0,r4
- lwz r4,SL_IBAT0+4(r1)
- mtibatl 0,r4
- lwz r4,SL_IBAT1(r1)
- mtibatu 1,r4
- lwz r4,SL_IBAT1+4(r1)
- mtibatl 1,r4
- lwz r4,SL_IBAT2(r1)
- mtibatu 2,r4
- lwz r4,SL_IBAT2+4(r1)
- mtibatl 2,r4
- lwz r4,SL_IBAT3(r1)
- mtibatu 3,r4
- lwz r4,SL_IBAT3+4(r1)
- mtibatl 3,r4
-
-BEGIN_FTR_SECTION
- li r4,0
- mtspr SPRN_DBAT4U,r4
- mtspr SPRN_DBAT4L,r4
- mtspr SPRN_DBAT5U,r4
- mtspr SPRN_DBAT5L,r4
- mtspr SPRN_DBAT6U,r4
- mtspr SPRN_DBAT6L,r4
- mtspr SPRN_DBAT7U,r4
- mtspr SPRN_DBAT7L,r4
- mtspr SPRN_IBAT4U,r4
- mtspr SPRN_IBAT4L,r4
- mtspr SPRN_IBAT5U,r4
- mtspr SPRN_IBAT5L,r4
- mtspr SPRN_IBAT6U,r4
- mtspr SPRN_IBAT6L,r4
- mtspr SPRN_IBAT7U,r4
- mtspr SPRN_IBAT7L,r4
-END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
-
- /* Flush all TLBs */
- lis r4,0x1000
-1: addic. r4,r4,-0x1000
- tlbie r4
- blt 1b
- sync
-
- /* restore the MSR and turn on the MMU */
- lwz r3,SL_MSR(r1)
- bl turn_on_mmu
-
- /* get back the stack pointer */
- tovirt(r1,r1)
-
- /* Restore TB */
- li r3,0
- mttbl r3
- lwz r3,SL_TB(r1)
- lwz r4,SL_TB+4(r1)
- mttbu r3
- mttbl r4
-
- /* Restore the callee-saved registers and return */
- lwz r0,SL_CR(r1)
- mtcr r0
- lwz r2,SL_R2(r1)
- lmw r12,SL_R12(r1)
- addi r1,r1,SL_SIZE
- lwz r0,4(r1)
- mtlr r0
- blr
-
-turn_on_mmu:
- mflr r4
- tovirt(r4,r4)
- mtsrr0 r4
- mtsrr1 r3
- sync
- isync
- rfi
-
-#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
-
- .section .data
- .balign L1_CACHE_BYTES
-sleep_storage:
- .long 0
- .balign L1_CACHE_BYTES, 0
-
-#endif /* CONFIG_6xx */
- .section .text
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
deleted file mode 100644
index 26ff26238f03..000000000000
--- a/arch/ppc/platforms/pmac_smp.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * SMP support for power macintosh.
- *
- * We support both the old "powersurge" SMP architecture
- * and the current Core99 (G4 PowerMac) machines.
- *
- * Note that we don't support the very first rev. of
- * Apple/DayStar 2 CPUs board, the one with the funky
- * watchdog. Hopefully, none of these should be there except
- * maybe internally to Apple. I should probably still add some
- * code to detect this card though and disable SMP. --BenH.
- *
- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
- * and Ben Herrenschmidt .
- *
- * Support for DayStar quad CPU cards
- * Copyright (C) XLR8, Inc. 1994-2000
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include