···151SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \152 -e s/arm.*/arm/ -e s/sa110/arm/ \153 -e s/s390x/s390/ -e s/parisc64/parisc/ \154- -e s/ppc64/powerpc/ )155156# Cross compiling and selecting different set of gcc/bin-utils157# ---------------------------------------------------------------------------
···151SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \152 -e s/arm.*/arm/ -e s/sa110/arm/ \153 -e s/s390x/s390/ -e s/parisc64/parisc/ \154+ -e s/ppc.*/powerpc/ )155156# Cross compiling and selecting different set of gcc/bin-utils157# ---------------------------------------------------------------------------
+10-11
arch/powerpc/Kconfig
···78 bool79 default n8081-config CRASH_DUMP82- bool "kernel crash dumps (EXPERIMENTAL)"83- depends on PPC_MULTIPLATFORM84- depends on EXPERIMENTAL85- help86- Build a kernel suitable for use as a kdump capture kernel.87- The kernel will be linked at a different address than normal, and88- so can only be used for Kdump.89-90- Don't change this unless you know what you are doing.91-92config GENERIC_TBSYNC93 bool94 default y if PPC32 && SMP···572 initially work for you. It may help to enable device hotplugging573 support. As of this writing the exact hardware interface is574 strongly in flux, so no good recommendation can be made.0000000000575576config EMBEDDEDBOOT577 bool
···78 bool79 default n800000000000081config GENERIC_TBSYNC82 bool83 default y if PPC32 && SMP···583 initially work for you. It may help to enable device hotplugging584 support. As of this writing the exact hardware interface is585 strongly in flux, so no good recommendation can be made.586+587+config CRASH_DUMP588+ bool "kernel crash dumps (EXPERIMENTAL)"589+ depends on PPC_MULTIPLATFORM && PPC64 && EXPERIMENTAL590+ help591+ Build a kernel suitable for use as a kdump capture kernel.592+ The kernel will be linked at a different address than normal, and593+ so can only be used for Kdump.594+595+ Don't change this unless you know what you are doing.596597config EMBEDDEDBOOT598 bool
···1#2# Automatically generated make config: don't edit3-# Linux kernel version: 2.6.15-rc54-# Tue Dec 13 17:24:05 20055#6# CONFIG_PPC64 is not set7CONFIG_PPC32=y···15CONFIG_GENERIC_NVRAM=y16CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y17CONFIG_ARCH_MAY_HAVE_PC_FDC=y00001819#20# Processor support21#22-CONFIG_6xx=y23# CONFIG_PPC_52xx is not set24# CONFIG_PPC_82xx is not set25# CONFIG_PPC_83xx is not set···32# CONFIG_8xx is not set33# CONFIG_E200 is not set34# CONFIG_E500 is not set035CONFIG_PPC_FPU=y36CONFIG_ALTIVEC=y37CONFIG_PPC_STD_MMU=y···58# CONFIG_BSD_PROCESS_ACCT is not set59CONFIG_SYSCTL=y60# CONFIG_AUDIT is not set61-CONFIG_HOTPLUG=y62-CONFIG_KOBJECT_UEVENT=y63CONFIG_IKCONFIG=y64CONFIG_IKCONFIG_PROC=y65CONFIG_INITRAMFS_SOURCE=""066# CONFIG_EMBEDDED is not set67CONFIG_KALLSYMS=y68# CONFIG_KALLSYMS_ALL is not set69# CONFIG_KALLSYMS_EXTRA_PASS is not set070CONFIG_PRINTK=y71CONFIG_BUG=y072CONFIG_BASE_FULL=y73CONFIG_FUTEX=y74CONFIG_EPOLL=y···78CONFIG_CC_ALIGN_LABELS=079CONFIG_CC_ALIGN_LOOPS=080CONFIG_CC_ALIGN_JUMPS=0081# CONFIG_TINY_SHMEM is not set82CONFIG_BASE_SMALL=008384#85# Loadable module support···121# CONFIG_APUS is not set122# CONFIG_PPC_CHRP is not set123CONFIG_PPC_PMAC=y124-CONFIG_PPC_OF=y125CONFIG_MPIC=y126# CONFIG_PPC_RTAS is not set127# CONFIG_MMIO_NVRAM is not set128-# CONFIG_CRASH_DUMP is not set129CONFIG_PPC_MPC106=y130-# CONFIG_GENERIC_TBSYNC is not set131CONFIG_CPU_FREQ=y132CONFIG_CPU_FREQ_TABLE=y133# CONFIG_CPU_FREQ_DEBUG is not set···200# PC-card bridges201#202CONFIG_YENTA=m00000203# CONFIG_PD6729 is not set204# CONFIG_I82092 is not set205CONFIG_PCCARD_NONSTATIC=m···474#475# CONFIG_STANDALONE is not set476CONFIG_PREVENT_FIRMWARE_BUILD=y477-CONFIG_FW_LOADER=m478# CONFIG_DEBUG_DRIVER is not set479480#···501# Block devices502#503# CONFIG_BLK_DEV_FD is not set504-CONFIG_MAC_FLOPPY=y505# CONFIG_BLK_CPQ_DA is not set506# CONFIG_BLK_CPQ_CISS_DA is not set507# CONFIG_BLK_DEV_DAC960 is not set···613# SCSI Transport Attributes614#615CONFIG_SCSI_SPI_ATTRS=y616-# CONFIG_SCSI_FC_ATTRS is not set617# CONFIG_SCSI_ISCSI_ATTRS is not set618# CONFIG_SCSI_SAS_ATTRS is not set619···655# CONFIG_SCSI_QLOGIC_FC is not set656# CONFIG_SCSI_QLOGIC_1280 is not set657CONFIG_SCSI_QLA2XXX=y658-# CONFIG_SCSI_QLA21XX is not set659-# CONFIG_SCSI_QLA22XX is not set660-# CONFIG_SCSI_QLA2300 is not set661-# CONFIG_SCSI_QLA2322 is not set662-# CONFIG_SCSI_QLA6312 is not set663-# CONFIG_SCSI_QLA24XX is not set664# CONFIG_SCSI_LPFC is not set665# CONFIG_SCSI_DC395x is not set666# CONFIG_SCSI_DC390T is not set···663# CONFIG_SCSI_DEBUG is not set664CONFIG_SCSI_MESH=y665CONFIG_SCSI_MESH_SYNC_RATE=5666-CONFIG_SCSI_MESH_RESET_DELAY_MS=1000667CONFIG_SCSI_MAC53C94=y668669#···732CONFIG_IEEE1394_ETH1394=m733CONFIG_IEEE1394_DV1394=m734CONFIG_IEEE1394_RAWIO=m735-# CONFIG_IEEE1394_CMP is not set736737#738# I2O device support···744CONFIG_ADB=y745CONFIG_ADB_CUDA=y746CONFIG_ADB_PMU=y747-CONFIG_PMAC_APM_EMU=y748CONFIG_PMAC_MEDIABAY=y749CONFIG_PMAC_BACKLIGHT=y750CONFIG_INPUT_ADBHID=y···823# CONFIG_R8169 is not set824# CONFIG_SIS190 is not set825# CONFIG_SKGE is not set0826# CONFIG_SK98LIN is not set827# CONFIG_VIA_VELOCITY is not set828# CONFIG_TIGON3 is not set···983CONFIG_SERIAL_8250=m984# CONFIG_SERIAL_8250_CS is not set985CONFIG_SERIAL_8250_NR_UARTS=40986# CONFIG_SERIAL_8250_EXTENDED is not set987988#989# Non-8250 serial port support990#991CONFIG_SERIAL_CORE=m992-# CONFIG_SERIAL_PMACZILOG is not set993-# CONFIG_SERIAL_JSM is not set994CONFIG_UNIX98_PTYS=y995CONFIG_LEGACY_PTYS=y996CONFIG_LEGACY_PTY_COUNT=256···1063# CONFIG_I2C_I801 is not set1064# CONFIG_I2C_I810 is not set1065# CONFIG_I2C_PIIX4 is not set1066-CONFIG_I2C_KEYWEST=m1067# CONFIG_I2C_MPC is not set1068# CONFIG_I2C_NFORCE2 is not set1069# CONFIG_I2C_PARPORT_LIGHT is not set···1165CONFIG_FB_ATY=y1166CONFIG_FB_ATY_CT=y1167# CONFIG_FB_ATY_GENERIC_LCD is not set1168-# CONFIG_FB_ATY_XL_INIT is not set1169CONFIG_FB_ATY_GX=y1170# CONFIG_FB_SAVAGE is not set1171# CONFIG_FB_SIS is not set···1173CONFIG_FB_3DFX=y1174# CONFIG_FB_3DFX_ACCEL is not set1175# CONFIG_FB_VOODOO1 is not set1176-# CONFIG_FB_CYBLA is not set1177# CONFIG_FB_TRIDENT is not set1178# CONFIG_FB_VIRTUAL is not set1179···1217CONFIG_SND_MIXER_OSS=m1218CONFIG_SND_PCM_OSS=m1219CONFIG_SND_SEQUENCER_OSS=y001220# CONFIG_SND_VERBOSE_PRINTK is not set1221# CONFIG_SND_DEBUG is not set1222-CONFIG_SND_GENERIC_DRIVER=y12231224#1225# Generic devices···1234#1235# PCI devices1236#001237# CONFIG_SND_ALI5451 is not set1238# CONFIG_SND_ATIIXP is not set1239# CONFIG_SND_ATIIXP_MODEM is not set···1244# CONFIG_SND_AU8830 is not set1245# CONFIG_SND_AZT3328 is not set1246# CONFIG_SND_BT87X is not set1247-# CONFIG_SND_CS46XX is not set01248# CONFIG_SND_CS4281 is not set01249# CONFIG_SND_EMU10K1 is not set1250# CONFIG_SND_EMU10K1X is not set1251-# CONFIG_SND_CA0106 is not set1252-# CONFIG_SND_KORG1212 is not set1253-# CONFIG_SND_MIXART is not set1254-# CONFIG_SND_NM256 is not set1255-# CONFIG_SND_RME32 is not set1256-# CONFIG_SND_RME96 is not set1257-# CONFIG_SND_RME9652 is not set1258-# CONFIG_SND_HDSP is not set1259-# CONFIG_SND_HDSPM is not set1260-# CONFIG_SND_TRIDENT is not set1261-# CONFIG_SND_YMFPCI is not set1262-# CONFIG_SND_AD1889 is not set1263-# CONFIG_SND_ALS4000 is not set1264-# CONFIG_SND_CMIPCI is not set1265# CONFIG_SND_ENS1370 is not set1266# CONFIG_SND_ENS1371 is not set1267# CONFIG_SND_ES1938 is not set1268# CONFIG_SND_ES1968 is not set1269-# CONFIG_SND_MAESTRO3 is not set1270# CONFIG_SND_FM801 is not set0001271# CONFIG_SND_ICE1712 is not set1272# CONFIG_SND_ICE1724 is not set1273# CONFIG_SND_INTEL8X0 is not set1274# CONFIG_SND_INTEL8X0M is not set000000001275# CONFIG_SND_SONICVIBES is not set01276# CONFIG_SND_VIA82XX is not set1277# CONFIG_SND_VIA82XX_MODEM is not set1278# CONFIG_SND_VX222 is not set1279-# CONFIG_SND_HDA_INTEL is not set12801281#1282# ALSA PowerMac devices1283#1284CONFIG_SND_POWERMAC=m1285-# CONFIG_SND_POWERMAC_AUTO_DRC is not set12861287#1288# USB devices···1341# may also be needed; see USB_STORAGE Help for more information1342#1343# CONFIG_USB_STORAGE is not set013441345#1346# USB Input Devices···1361# CONFIG_USB_YEALINK is not set1362# CONFIG_USB_XPAD is not set1363# CONFIG_USB_ATI_REMOTE is not set01364# CONFIG_USB_KEYSPAN_REMOTE is not set1365CONFIG_USB_APPLETOUCH=y1366···1508# CONFIG_JFS_FS is not set1509# CONFIG_FS_POSIX_ACL is not set1510# CONFIG_XFS_FS is not set01511# CONFIG_MINIX_FS is not set1512# CONFIG_ROMFS_FS is not set1513CONFIG_INOTIFY=y···1548# CONFIG_HUGETLB_PAGE is not set1549CONFIG_RAMFS=y1550CONFIG_RELAYFS_FS=m015511552#1553# Miscellaneous filesystems···1679# Kernel hacking1680#1681# CONFIG_PRINTK_TIME is not set1682-CONFIG_DEBUG_KERNEL=y1683# CONFIG_MAGIC_SYSRQ is not set01684CONFIG_LOG_BUF_SHIFT=141685CONFIG_DETECT_SOFTLOCKUP=y1686# CONFIG_SCHEDSTATS is not set1687# CONFIG_DEBUG_SLAB is not set01688# CONFIG_DEBUG_SPINLOCK is not set1689# CONFIG_DEBUG_SPINLOCK_SLEEP is not set1690# CONFIG_DEBUG_KOBJECT is not set···1698CONFIG_XMON_DEFAULT=y1699# CONFIG_BDI_SWITCH is not set1700CONFIG_BOOTX_TEXT=y0000017011702#1703# Security options
···1#2# Automatically generated make config: don't edit3+# Linux kernel version: 2.6.154+# Sat Jan 14 16:26:08 20065#6# CONFIG_PPC64 is not set7CONFIG_PPC32=y···15CONFIG_GENERIC_NVRAM=y16CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y17CONFIG_ARCH_MAY_HAVE_PC_FDC=y18+CONFIG_PPC_OF=y19+# CONFIG_PPC_UDBG_16550 is not set20+# CONFIG_CRASH_DUMP is not set21+# CONFIG_GENERIC_TBSYNC is not set2223#24# Processor support25#26+CONFIG_CLASSIC32=y27# CONFIG_PPC_52xx is not set28# CONFIG_PPC_82xx is not set29# CONFIG_PPC_83xx is not set···28# CONFIG_8xx is not set29# CONFIG_E200 is not set30# CONFIG_E500 is not set31+CONFIG_6xx=y32CONFIG_PPC_FPU=y33CONFIG_ALTIVEC=y34CONFIG_PPC_STD_MMU=y···53# CONFIG_BSD_PROCESS_ACCT is not set54CONFIG_SYSCTL=y55# CONFIG_AUDIT is not set0056CONFIG_IKCONFIG=y57CONFIG_IKCONFIG_PROC=y58CONFIG_INITRAMFS_SOURCE=""59+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set60# CONFIG_EMBEDDED is not set61CONFIG_KALLSYMS=y62# CONFIG_KALLSYMS_ALL is not set63# CONFIG_KALLSYMS_EXTRA_PASS is not set64+CONFIG_HOTPLUG=y65CONFIG_PRINTK=y66CONFIG_BUG=y67+CONFIG_ELF_CORE=y68CONFIG_BASE_FULL=y69CONFIG_FUTEX=y70CONFIG_EPOLL=y···72CONFIG_CC_ALIGN_LABELS=073CONFIG_CC_ALIGN_LOOPS=074CONFIG_CC_ALIGN_JUMPS=075+CONFIG_SLAB=y76# CONFIG_TINY_SHMEM is not set77CONFIG_BASE_SMALL=078+# CONFIG_SLOB is not set7980#81# Loadable module support···113# CONFIG_APUS is not set114# CONFIG_PPC_CHRP is not set115CONFIG_PPC_PMAC=y0116CONFIG_MPIC=y117# CONFIG_PPC_RTAS is not set118# CONFIG_MMIO_NVRAM is not set0119CONFIG_PPC_MPC106=y0120CONFIG_CPU_FREQ=y121CONFIG_CPU_FREQ_TABLE=y122# CONFIG_CPU_FREQ_DEBUG is not set···195# PC-card bridges196#197CONFIG_YENTA=m198+CONFIG_YENTA_O2=y199+CONFIG_YENTA_RICOH=y200+CONFIG_YENTA_TI=y201+CONFIG_YENTA_ENE_TUNE=y202+CONFIG_YENTA_TOSHIBA=y203# CONFIG_PD6729 is not set204# CONFIG_I82092 is not set205CONFIG_PCCARD_NONSTATIC=m···464#465# CONFIG_STANDALONE is not set466CONFIG_PREVENT_FIRMWARE_BUILD=y467+CONFIG_FW_LOADER=y468# CONFIG_DEBUG_DRIVER is not set469470#···491# Block devices492#493# CONFIG_BLK_DEV_FD is not set494+CONFIG_MAC_FLOPPY=m495# CONFIG_BLK_CPQ_DA is not set496# CONFIG_BLK_CPQ_CISS_DA is not set497# CONFIG_BLK_DEV_DAC960 is not set···603# SCSI Transport Attributes604#605CONFIG_SCSI_SPI_ATTRS=y606+CONFIG_SCSI_FC_ATTRS=y607# CONFIG_SCSI_ISCSI_ATTRS is not set608# CONFIG_SCSI_SAS_ATTRS is not set609···645# CONFIG_SCSI_QLOGIC_FC is not set646# CONFIG_SCSI_QLOGIC_1280 is not set647CONFIG_SCSI_QLA2XXX=y648+# CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set00000649# CONFIG_SCSI_LPFC is not set650# CONFIG_SCSI_DC395x is not set651# CONFIG_SCSI_DC390T is not set···658# CONFIG_SCSI_DEBUG is not set659CONFIG_SCSI_MESH=y660CONFIG_SCSI_MESH_SYNC_RATE=5661+CONFIG_SCSI_MESH_RESET_DELAY_MS=4000662CONFIG_SCSI_MAC53C94=y663664#···727CONFIG_IEEE1394_ETH1394=m728CONFIG_IEEE1394_DV1394=m729CONFIG_IEEE1394_RAWIO=m0730731#732# I2O device support···740CONFIG_ADB=y741CONFIG_ADB_CUDA=y742CONFIG_ADB_PMU=y743+CONFIG_PMAC_APM_EMU=m744CONFIG_PMAC_MEDIABAY=y745CONFIG_PMAC_BACKLIGHT=y746CONFIG_INPUT_ADBHID=y···819# CONFIG_R8169 is not set820# CONFIG_SIS190 is not set821# CONFIG_SKGE is not set822+# CONFIG_SKY2 is not set823# CONFIG_SK98LIN is not set824# CONFIG_VIA_VELOCITY is not set825# CONFIG_TIGON3 is not set···978CONFIG_SERIAL_8250=m979# CONFIG_SERIAL_8250_CS is not set980CONFIG_SERIAL_8250_NR_UARTS=4981+CONFIG_SERIAL_8250_RUNTIME_UARTS=4982# CONFIG_SERIAL_8250_EXTENDED is not set983984#985# Non-8250 serial port support986#987CONFIG_SERIAL_CORE=m988+CONFIG_SERIAL_PMACZILOG=m0989CONFIG_UNIX98_PTYS=y990CONFIG_LEGACY_PTYS=y991CONFIG_LEGACY_PTY_COUNT=256···1058# CONFIG_I2C_I801 is not set1059# CONFIG_I2C_I810 is not set1060# CONFIG_I2C_PIIX4 is not set1061+CONFIG_I2C_POWERMAC=y1062# CONFIG_I2C_MPC is not set1063# CONFIG_I2C_NFORCE2 is not set1064# CONFIG_I2C_PARPORT_LIGHT is not set···1160CONFIG_FB_ATY=y1161CONFIG_FB_ATY_CT=y1162# CONFIG_FB_ATY_GENERIC_LCD is not set01163CONFIG_FB_ATY_GX=y1164# CONFIG_FB_SAVAGE is not set1165# CONFIG_FB_SIS is not set···1169CONFIG_FB_3DFX=y1170# CONFIG_FB_3DFX_ACCEL is not set1171# CONFIG_FB_VOODOO1 is not set01172# CONFIG_FB_TRIDENT is not set1173# CONFIG_FB_VIRTUAL is not set1174···1214CONFIG_SND_MIXER_OSS=m1215CONFIG_SND_PCM_OSS=m1216CONFIG_SND_SEQUENCER_OSS=y1217+# CONFIG_SND_DYNAMIC_MINORS is not set1218+CONFIG_SND_SUPPORT_OLD_API=y1219# CONFIG_SND_VERBOSE_PRINTK is not set1220# CONFIG_SND_DEBUG is not set012211222#1223# Generic devices···1230#1231# PCI devices1232#1233+# CONFIG_SND_AD1889 is not set1234+# CONFIG_SND_ALS4000 is not set1235# CONFIG_SND_ALI5451 is not set1236# CONFIG_SND_ATIIXP is not set1237# CONFIG_SND_ATIIXP_MODEM is not set···1238# CONFIG_SND_AU8830 is not set1239# CONFIG_SND_AZT3328 is not set1240# CONFIG_SND_BT87X is not set1241+# CONFIG_SND_CA0106 is not set1242+# CONFIG_SND_CMIPCI is not set1243# CONFIG_SND_CS4281 is not set1244+# CONFIG_SND_CS46XX is not set1245# CONFIG_SND_EMU10K1 is not set1246# CONFIG_SND_EMU10K1X is not set000000000000001247# CONFIG_SND_ENS1370 is not set1248# CONFIG_SND_ENS1371 is not set1249# CONFIG_SND_ES1938 is not set1250# CONFIG_SND_ES1968 is not set01251# CONFIG_SND_FM801 is not set1252+# CONFIG_SND_HDA_INTEL is not set1253+# CONFIG_SND_HDSP is not set1254+# CONFIG_SND_HDSPM is not set1255# CONFIG_SND_ICE1712 is not set1256# CONFIG_SND_ICE1724 is not set1257# CONFIG_SND_INTEL8X0 is not set1258# CONFIG_SND_INTEL8X0M is not set1259+# CONFIG_SND_KORG1212 is not set1260+# CONFIG_SND_MAESTRO3 is not set1261+# CONFIG_SND_MIXART is not set1262+# CONFIG_SND_NM256 is not set1263+# CONFIG_SND_PCXHR is not set1264+# CONFIG_SND_RME32 is not set1265+# CONFIG_SND_RME96 is not set1266+# CONFIG_SND_RME9652 is not set1267# CONFIG_SND_SONICVIBES is not set1268+# CONFIG_SND_TRIDENT is not set1269# CONFIG_SND_VIA82XX is not set1270# CONFIG_SND_VIA82XX_MODEM is not set1271# CONFIG_SND_VX222 is not set1272+# CONFIG_SND_YMFPCI is not set12731274#1275# ALSA PowerMac devices1276#1277CONFIG_SND_POWERMAC=m1278+CONFIG_SND_POWERMAC_AUTO_DRC=y12791280#1281# USB devices···1336# may also be needed; see USB_STORAGE Help for more information1337#1338# CONFIG_USB_STORAGE is not set1339+# CONFIG_USB_LIBUSUAL is not set13401341#1342# USB Input Devices···1355# CONFIG_USB_YEALINK is not set1356# CONFIG_USB_XPAD is not set1357# CONFIG_USB_ATI_REMOTE is not set1358+# CONFIG_USB_ATI_REMOTE2 is not set1359# CONFIG_USB_KEYSPAN_REMOTE is not set1360CONFIG_USB_APPLETOUCH=y1361···1501# CONFIG_JFS_FS is not set1502# CONFIG_FS_POSIX_ACL is not set1503# CONFIG_XFS_FS is not set1504+# CONFIG_OCFS2_FS is not set1505# CONFIG_MINIX_FS is not set1506# CONFIG_ROMFS_FS is not set1507CONFIG_INOTIFY=y···1540# CONFIG_HUGETLB_PAGE is not set1541CONFIG_RAMFS=y1542CONFIG_RELAYFS_FS=m1543+# CONFIG_CONFIGFS_FS is not set15441545#1546# Miscellaneous filesystems···1670# Kernel hacking1671#1672# CONFIG_PRINTK_TIME is not set01673# CONFIG_MAGIC_SYSRQ is not set1674+CONFIG_DEBUG_KERNEL=y1675CONFIG_LOG_BUF_SHIFT=141676CONFIG_DETECT_SOFTLOCKUP=y1677# CONFIG_SCHEDSTATS is not set1678# CONFIG_DEBUG_SLAB is not set1679+# CONFIG_DEBUG_MUTEXES is not set1680# CONFIG_DEBUG_SPINLOCK is not set1681# CONFIG_DEBUG_SPINLOCK_SLEEP is not set1682# CONFIG_DEBUG_KOBJECT is not set···1688CONFIG_XMON_DEFAULT=y1689# CONFIG_BDI_SWITCH is not set1690CONFIG_BOOTX_TEXT=y1691+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set1692+# CONFIG_PPC_EARLY_DEBUG_G5 is not set1693+# CONFIG_PPC_EARLY_DEBUG_RTAS is not set1694+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set1695+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set16961697#1698# Security options
···1+/*2+ * Common pmac/prep/chrp pci routines. -- Cort3+ */4+5+#include <linux/config.h>6+#include <linux/kernel.h>7+#include <linux/pci.h>8+#include <linux/delay.h>9+#include <linux/string.h>10+#include <linux/init.h>11+#include <linux/capability.h>12+#include <linux/sched.h>13+#include <linux/errno.h>14+#include <linux/bootmem.h>15+16+#include <asm/processor.h>17+#include <asm/io.h>18+#include <asm/prom.h>19+#include <asm/sections.h>20+#include <asm/pci-bridge.h>21+#include <asm/byteorder.h>22+#include <asm/irq.h>23+#include <asm/uaccess.h>24+#include <asm/machdep.h>25+26+#undef DEBUG27+28+#ifdef DEBUG29+#define DBG(x...) printk(x)30+#else31+#define DBG(x...)32+#endif33+34+unsigned long isa_io_base = 0;35+unsigned long isa_mem_base = 0;36+unsigned long pci_dram_offset = 0;37+int pcibios_assign_bus_offset = 1;38+39+void pcibios_make_OF_bus_map(void);40+41+static int pci_relocate_bridge_resource(struct pci_bus *bus, int i);42+static int probe_resource(struct pci_bus *parent, struct resource *pr,43+ struct resource *res, struct resource **conflict);44+static void update_bridge_base(struct pci_bus *bus, int i);45+static void pcibios_fixup_resources(struct pci_dev* dev);46+static void fixup_broken_pcnet32(struct pci_dev* dev);47+static int reparent_resources(struct resource *parent, struct resource *res);48+static void fixup_cpc710_pci64(struct pci_dev* dev);49+#ifdef CONFIG_PPC_OF50+static u8* pci_to_OF_bus_map;51+#endif52+53+/* By default, we don't re-assign bus numbers. We do this only on54+ * some pmacs55+ */56+int pci_assign_all_buses;57+58+struct pci_controller* hose_head;59+struct pci_controller** hose_tail = &hose_head;60+61+static int pci_bus_count;62+63+static void64+fixup_broken_pcnet32(struct pci_dev* dev)65+{66+ if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {67+ dev->vendor = PCI_VENDOR_ID_AMD;68+ pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);69+ }70+}71+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);72+73+static void74+fixup_cpc710_pci64(struct pci_dev* dev)75+{76+ /* Hide the PCI64 BARs from the kernel as their content doesn't77+ * fit well in the resource management78+ */79+ dev->resource[0].start = dev->resource[0].end = 0;80+ dev->resource[0].flags = 0;81+ dev->resource[1].start = dev->resource[1].end = 0;82+ dev->resource[1].flags = 0;83+}84+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64);85+86+static void87+pcibios_fixup_resources(struct pci_dev *dev)88+{89+ struct pci_controller* hose = (struct pci_controller *)dev->sysdata;90+ int i;91+ unsigned long offset;92+93+ if (!hose) {94+ printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));95+ return;96+ }97+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {98+ struct resource *res = dev->resource + i;99+ if (!res->flags)100+ continue;101+ if (res->end == 0xffffffff) {102+ DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",103+ pci_name(dev), i, res->start, res->end);104+ res->end -= res->start;105+ res->start = 0;106+ res->flags |= IORESOURCE_UNSET;107+ continue;108+ }109+ offset = 0;110+ if (res->flags & IORESOURCE_MEM) {111+ offset = hose->pci_mem_offset;112+ } else if (res->flags & IORESOURCE_IO) {113+ offset = (unsigned long) hose->io_base_virt114+ - isa_io_base;115+ }116+ if (offset != 0) {117+ res->start += offset;118+ res->end += offset;119+#ifdef DEBUG120+ printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n",121+ i, res->flags, pci_name(dev),122+ res->start - offset, res->start);123+#endif124+ }125+ }126+127+ /* Call machine specific resource fixup */128+ if (ppc_md.pcibios_fixup_resources)129+ ppc_md.pcibios_fixup_resources(dev);130+}131+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);132+133+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,134+ struct resource *res)135+{136+ unsigned long offset = 0;137+ struct pci_controller *hose = dev->sysdata;138+139+ if (hose && res->flags & IORESOURCE_IO)140+ offset = (unsigned long)hose->io_base_virt - isa_io_base;141+ else if (hose && res->flags & IORESOURCE_MEM)142+ offset = hose->pci_mem_offset;143+ region->start = res->start - offset;144+ region->end = res->end - offset;145+}146+EXPORT_SYMBOL(pcibios_resource_to_bus);147+148+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,149+ struct pci_bus_region *region)150+{151+ unsigned long offset = 0;152+ struct pci_controller *hose = dev->sysdata;153+154+ if (hose && res->flags & IORESOURCE_IO)155+ offset = (unsigned long)hose->io_base_virt - isa_io_base;156+ else if (hose && res->flags & IORESOURCE_MEM)157+ offset = hose->pci_mem_offset;158+ res->start = region->start + offset;159+ res->end = region->end + offset;160+}161+EXPORT_SYMBOL(pcibios_bus_to_resource);162+163+/*164+ * We need to avoid collisions with `mirrored' VGA ports165+ * and other strange ISA hardware, so we always want the166+ * addresses to be allocated in the 0x000-0x0ff region167+ * modulo 0x400.168+ *169+ * Why? Because some silly external IO cards only decode170+ * the low 10 bits of the IO address. The 0x00-0xff region171+ * is reserved for motherboard devices that decode all 16172+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,173+ * but we want to try to avoid allocating at 0x2900-0x2bff174+ * which might have be mirrored at 0x0100-0x03ff..175+ */176+void pcibios_align_resource(void *data, struct resource *res, unsigned long size,177+ unsigned long align)178+{179+ struct pci_dev *dev = data;180+181+ if (res->flags & IORESOURCE_IO) {182+ unsigned long start = res->start;183+184+ if (size > 0x100) {185+ printk(KERN_ERR "PCI: I/O Region %s/%d too large"186+ " (%ld bytes)\n", pci_name(dev),187+ dev->resource - res, size);188+ }189+190+ if (start & 0x300) {191+ start = (start + 0x3ff) & ~0x3ff;192+ res->start = start;193+ }194+ }195+}196+EXPORT_SYMBOL(pcibios_align_resource);197+198+/*199+ * Handle resources of PCI devices. If the world were perfect, we could200+ * just allocate all the resource regions and do nothing more. It isn't.201+ * On the other hand, we cannot just re-allocate all devices, as it would202+ * require us to know lots of host bridge internals. So we attempt to203+ * keep as much of the original configuration as possible, but tweak it204+ * when it's found to be wrong.205+ *206+ * Known BIOS problems we have to work around:207+ * - I/O or memory regions not configured208+ * - regions configured, but not enabled in the command register209+ * - bogus I/O addresses above 64K used210+ * - expansion ROMs left enabled (this may sound harmless, but given211+ * the fact the PCI specs explicitly allow address decoders to be212+ * shared between expansion ROMs and other resource regions, it's213+ * at least dangerous)214+ *215+ * Our solution:216+ * (1) Allocate resources for all buses behind PCI-to-PCI bridges.217+ * This gives us fixed barriers on where we can allocate.218+ * (2) Allocate resources for all enabled devices. If there is219+ * a collision, just mark the resource as unallocated. Also220+ * disable expansion ROMs during this step.221+ * (3) Try to allocate resources for disabled devices. If the222+ * resources were assigned correctly, everything goes well,223+ * if they weren't, they won't disturb allocation of other224+ * resources.225+ * (4) Assign new addresses to resources which were either226+ * not configured at all or misconfigured. If explicitly227+ * requested by the user, configure expansion ROM address228+ * as well.229+ */230+231+static void __init232+pcibios_allocate_bus_resources(struct list_head *bus_list)233+{234+ struct pci_bus *bus;235+ int i;236+ struct resource *res, *pr;237+238+ /* Depth-First Search on bus tree */239+ list_for_each_entry(bus, bus_list, node) {240+ for (i = 0; i < 4; ++i) {241+ if ((res = bus->resource[i]) == NULL || !res->flags242+ || res->start > res->end)243+ continue;244+ if (bus->parent == NULL)245+ pr = (res->flags & IORESOURCE_IO)?246+ &ioport_resource: &iomem_resource;247+ else {248+ pr = pci_find_parent_resource(bus->self, res);249+ if (pr == res) {250+ /* this happens when the generic PCI251+ * code (wrongly) decides that this252+ * bridge is transparent -- paulus253+ */254+ continue;255+ }256+ }257+258+ DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n",259+ res->start, res->end, res->flags, pr);260+ if (pr) {261+ if (request_resource(pr, res) == 0)262+ continue;263+ /*264+ * Must be a conflict with an existing entry.265+ * Move that entry (or entries) under the266+ * bridge resource and try again.267+ */268+ if (reparent_resources(pr, res) == 0)269+ continue;270+ }271+ printk(KERN_ERR "PCI: Cannot allocate resource region "272+ "%d of PCI bridge %d\n", i, bus->number);273+ if (pci_relocate_bridge_resource(bus, i))274+ bus->resource[i] = NULL;275+ }276+ pcibios_allocate_bus_resources(&bus->children);277+ }278+}279+280+/*281+ * Reparent resource children of pr that conflict with res282+ * under res, and make res replace those children.283+ */284+static int __init285+reparent_resources(struct resource *parent, struct resource *res)286+{287+ struct resource *p, **pp;288+ struct resource **firstpp = NULL;289+290+ for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {291+ if (p->end < res->start)292+ continue;293+ if (res->end < p->start)294+ break;295+ if (p->start < res->start || p->end > res->end)296+ return -1; /* not completely contained */297+ if (firstpp == NULL)298+ firstpp = pp;299+ }300+ if (firstpp == NULL)301+ return -1; /* didn't find any conflicting entries? */302+ res->parent = parent;303+ res->child = *firstpp;304+ res->sibling = *pp;305+ *firstpp = res;306+ *pp = NULL;307+ for (p = res->child; p != NULL; p = p->sibling) {308+ p->parent = res;309+ DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n",310+ p->name, p->start, p->end, res->name);311+ }312+ return 0;313+}314+315+/*316+ * A bridge has been allocated a range which is outside the range317+ * of its parent bridge, so it needs to be moved.318+ */319+static int __init320+pci_relocate_bridge_resource(struct pci_bus *bus, int i)321+{322+ struct resource *res, *pr, *conflict;323+ unsigned long try, size;324+ int j;325+ struct pci_bus *parent = bus->parent;326+327+ if (parent == NULL) {328+ /* shouldn't ever happen */329+ printk(KERN_ERR "PCI: can't move host bridge resource\n");330+ return -1;331+ }332+ res = bus->resource[i];333+ if (res == NULL)334+ return -1;335+ pr = NULL;336+ for (j = 0; j < 4; j++) {337+ struct resource *r = parent->resource[j];338+ if (!r)339+ continue;340+ if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))341+ continue;342+ if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) {343+ pr = r;344+ break;345+ }346+ if (res->flags & IORESOURCE_PREFETCH)347+ pr = r;348+ }349+ if (pr == NULL)350+ return -1;351+ size = res->end - res->start;352+ if (pr->start > pr->end || size > pr->end - pr->start)353+ return -1;354+ try = pr->end;355+ for (;;) {356+ res->start = try - size;357+ res->end = try;358+ if (probe_resource(bus->parent, pr, res, &conflict) == 0)359+ break;360+ if (conflict->start <= pr->start + size)361+ return -1;362+ try = conflict->start - 1;363+ }364+ if (request_resource(pr, res)) {365+ DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n",366+ res->start, res->end);367+ return -1; /* "can't happen" */368+ }369+ update_bridge_base(bus, i);370+ printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n",371+ bus->number, i, res->start, res->end);372+ return 0;373+}374+375+static int __init376+probe_resource(struct pci_bus *parent, struct resource *pr,377+ struct resource *res, struct resource **conflict)378+{379+ struct pci_bus *bus;380+ struct pci_dev *dev;381+ struct resource *r;382+ int i;383+384+ for (r = pr->child; r != NULL; r = r->sibling) {385+ if (r->end >= res->start && res->end >= r->start) {386+ *conflict = r;387+ return 1;388+ }389+ }390+ list_for_each_entry(bus, &parent->children, node) {391+ for (i = 0; i < 4; ++i) {392+ if ((r = bus->resource[i]) == NULL)393+ continue;394+ if (!r->flags || r->start > r->end || r == res)395+ continue;396+ if (pci_find_parent_resource(bus->self, r) != pr)397+ continue;398+ if (r->end >= res->start && res->end >= r->start) {399+ *conflict = r;400+ return 1;401+ }402+ }403+ }404+ list_for_each_entry(dev, &parent->devices, bus_list) {405+ for (i = 0; i < 6; ++i) {406+ r = &dev->resource[i];407+ if (!r->flags || (r->flags & IORESOURCE_UNSET))408+ continue;409+ if (pci_find_parent_resource(dev, r) != pr)410+ continue;411+ if (r->end >= res->start && res->end >= r->start) {412+ *conflict = r;413+ return 1;414+ }415+ }416+ }417+ return 0;418+}419+420+static void __init421+update_bridge_base(struct pci_bus *bus, int i)422+{423+ struct resource *res = bus->resource[i];424+ u8 io_base_lo, io_limit_lo;425+ u16 mem_base, mem_limit;426+ u16 cmd;427+ unsigned long start, end, off;428+ struct pci_dev *dev = bus->self;429+ struct pci_controller *hose = dev->sysdata;430+431+ if (!hose) {432+ printk("update_bridge_base: no hose?\n");433+ return;434+ }435+ pci_read_config_word(dev, PCI_COMMAND, &cmd);436+ pci_write_config_word(dev, PCI_COMMAND,437+ cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));438+ if (res->flags & IORESOURCE_IO) {439+ off = (unsigned long) hose->io_base_virt - isa_io_base;440+ start = res->start - off;441+ end = res->end - off;442+ io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK;443+ io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK;444+ if (end > 0xffff) {445+ pci_write_config_word(dev, PCI_IO_BASE_UPPER16,446+ start >> 16);447+ pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,448+ end >> 16);449+ io_base_lo |= PCI_IO_RANGE_TYPE_32;450+ } else451+ io_base_lo |= PCI_IO_RANGE_TYPE_16;452+ pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo);453+ pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo);454+455+ } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))456+ == IORESOURCE_MEM) {457+ off = hose->pci_mem_offset;458+ mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK;459+ mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK;460+ pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base);461+ pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit);462+463+ } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH))464+ == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) {465+ off = hose->pci_mem_offset;466+ mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK;467+ mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK;468+ pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base);469+ pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit);470+471+ } else {472+ DBG(KERN_ERR "PCI: ugh, bridge %s res %d has flags=%lx\n",473+ pci_name(dev), i, res->flags);474+ }475+ pci_write_config_word(dev, PCI_COMMAND, cmd);476+}477+478+static inline void alloc_resource(struct pci_dev *dev, int idx)479+{480+ struct resource *pr, *r = &dev->resource[idx];481+482+ DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n",483+ pci_name(dev), idx, r->start, r->end, r->flags);484+ pr = pci_find_parent_resource(dev, r);485+ if (!pr || request_resource(pr, r) < 0) {486+ printk(KERN_ERR "PCI: Cannot allocate resource region %d"487+ " of device %s\n", idx, pci_name(dev));488+ if (pr)489+ DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n",490+ pr, pr->start, pr->end, pr->flags);491+ /* We'll assign a new address later */492+ r->flags |= IORESOURCE_UNSET;493+ r->end -= r->start;494+ r->start = 0;495+ }496+}497+498+static void __init499+pcibios_allocate_resources(int pass)500+{501+ struct pci_dev *dev = NULL;502+ int idx, disabled;503+ u16 command;504+ struct resource *r;505+506+ for_each_pci_dev(dev) {507+ pci_read_config_word(dev, PCI_COMMAND, &command);508+ for (idx = 0; idx < 6; idx++) {509+ r = &dev->resource[idx];510+ if (r->parent) /* Already allocated */511+ continue;512+ if (!r->flags || (r->flags & IORESOURCE_UNSET))513+ continue; /* Not assigned at all */514+ if (r->flags & IORESOURCE_IO)515+ disabled = !(command & PCI_COMMAND_IO);516+ else517+ disabled = !(command & PCI_COMMAND_MEMORY);518+ if (pass == disabled)519+ alloc_resource(dev, idx);520+ }521+ if (pass)522+ continue;523+ r = &dev->resource[PCI_ROM_RESOURCE];524+ if (r->flags & IORESOURCE_ROM_ENABLE) {525+ /* Turn the ROM off, leave the resource region, but keep it unregistered. */526+ u32 reg;527+ DBG("PCI: Switching off ROM of %s\n", pci_name(dev));528+ r->flags &= ~IORESOURCE_ROM_ENABLE;529+ pci_read_config_dword(dev, dev->rom_base_reg, ®);530+ pci_write_config_dword(dev, dev->rom_base_reg,531+ reg & ~PCI_ROM_ADDRESS_ENABLE);532+ }533+ }534+}535+536+static void __init537+pcibios_assign_resources(void)538+{539+ struct pci_dev *dev = NULL;540+ int idx;541+ struct resource *r;542+543+ for_each_pci_dev(dev) {544+ int class = dev->class >> 8;545+546+ /* Don't touch classless devices and host bridges */547+ if (!class || class == PCI_CLASS_BRIDGE_HOST)548+ continue;549+550+ for (idx = 0; idx < 6; idx++) {551+ r = &dev->resource[idx];552+553+ /*554+ * We shall assign a new address to this resource,555+ * either because the BIOS (sic) forgot to do so556+ * or because we have decided the old address was557+ * unusable for some reason.558+ */559+ if ((r->flags & IORESOURCE_UNSET) && r->end &&560+ (!ppc_md.pcibios_enable_device_hook ||561+ !ppc_md.pcibios_enable_device_hook(dev, 1))) {562+ r->flags &= ~IORESOURCE_UNSET;563+ pci_assign_resource(dev, idx);564+ }565+ }566+567+#if 0 /* don't assign ROMs */568+ r = &dev->resource[PCI_ROM_RESOURCE];569+ r->end -= r->start;570+ r->start = 0;571+ if (r->end)572+ pci_assign_resource(dev, PCI_ROM_RESOURCE);573+#endif574+ }575+}576+577+578+int579+pcibios_enable_resources(struct pci_dev *dev, int mask)580+{581+ u16 cmd, old_cmd;582+ int idx;583+ struct resource *r;584+585+ pci_read_config_word(dev, PCI_COMMAND, &cmd);586+ old_cmd = cmd;587+ for (idx=0; idx<6; idx++) {588+ /* Only set up the requested stuff */589+ if (!(mask & (1<<idx)))590+ continue;591+592+ r = &dev->resource[idx];593+ if (r->flags & IORESOURCE_UNSET) {594+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));595+ return -EINVAL;596+ }597+ if (r->flags & IORESOURCE_IO)598+ cmd |= PCI_COMMAND_IO;599+ if (r->flags & IORESOURCE_MEM)600+ cmd |= PCI_COMMAND_MEMORY;601+ }602+ if (dev->resource[PCI_ROM_RESOURCE].start)603+ cmd |= PCI_COMMAND_MEMORY;604+ if (cmd != old_cmd) {605+ printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);606+ pci_write_config_word(dev, PCI_COMMAND, cmd);607+ }608+ return 0;609+}610+611+static int next_controller_index;612+613+struct pci_controller * __init614+pcibios_alloc_controller(void)615+{616+ struct pci_controller *hose;617+618+ hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));619+ memset(hose, 0, sizeof(struct pci_controller));620+621+ *hose_tail = hose;622+ hose_tail = &hose->next;623+624+ hose->index = next_controller_index++;625+626+ return hose;627+}628+629+#ifdef CONFIG_PPC_OF630+/*631+ * Functions below are used on OpenFirmware machines.632+ */633+static void634+make_one_node_map(struct device_node* node, u8 pci_bus)635+{636+ int *bus_range;637+ int len;638+639+ if (pci_bus >= pci_bus_count)640+ return;641+ bus_range = (int *) get_property(node, "bus-range", &len);642+ if (bus_range == NULL || len < 2 * sizeof(int)) {643+ printk(KERN_WARNING "Can't get bus-range for %s, "644+ "assuming it starts at 0\n", node->full_name);645+ pci_to_OF_bus_map[pci_bus] = 0;646+ } else647+ pci_to_OF_bus_map[pci_bus] = bus_range[0];648+649+ for (node=node->child; node != 0;node = node->sibling) {650+ struct pci_dev* dev;651+ unsigned int *class_code, *reg;652+653+ class_code = (unsigned int *) get_property(node, "class-code", NULL);654+ if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&655+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))656+ continue;657+ reg = (unsigned int *)get_property(node, "reg", NULL);658+ if (!reg)659+ continue;660+ dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));661+ if (!dev || !dev->subordinate)662+ continue;663+ make_one_node_map(node, dev->subordinate->number);664+ }665+}666+667+void668+pcibios_make_OF_bus_map(void)669+{670+ int i;671+ struct pci_controller* hose;672+ u8* of_prop_map;673+674+ pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);675+ if (!pci_to_OF_bus_map) {676+ printk(KERN_ERR "Can't allocate OF bus map !\n");677+ return;678+ }679+680+ /* We fill the bus map with invalid values, that helps681+ * debugging.682+ */683+ for (i=0; i<pci_bus_count; i++)684+ pci_to_OF_bus_map[i] = 0xff;685+686+ /* For each hose, we begin searching bridges */687+ for(hose=hose_head; hose; hose=hose->next) {688+ struct device_node* node; 689+ node = (struct device_node *)hose->arch_data;690+ if (!node)691+ continue;692+ make_one_node_map(node, hose->first_busno);693+ }694+ of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL);695+ if (of_prop_map)696+ memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);697+#ifdef DEBUG698+ printk("PCI->OF bus map:\n");699+ for (i=0; i<pci_bus_count; i++) {700+ if (pci_to_OF_bus_map[i] == 0xff)701+ continue;702+ printk("%d -> %d\n", i, pci_to_OF_bus_map[i]);703+ }704+#endif705+}706+707+typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);708+709+static struct device_node*710+scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)711+{712+ struct device_node* sub_node;713+714+ for (; node != 0;node = node->sibling) {715+ unsigned int *class_code;716+717+ if (filter(node, data))718+ return node;719+720+ /* For PCI<->PCI bridges or CardBus bridges, we go down721+ * Note: some OFs create a parent node "multifunc-device" as722+ * a fake root for all functions of a multi-function device,723+ * we go down them as well.724+ */725+ class_code = (unsigned int *) get_property(node, "class-code", NULL);726+ if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&727+ (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&728+ strcmp(node->name, "multifunc-device"))729+ continue;730+ sub_node = scan_OF_pci_childs(node->child, filter, data);731+ if (sub_node)732+ return sub_node;733+ }734+ return NULL;735+}736+737+static int738+scan_OF_pci_childs_iterator(struct device_node* node, void* data)739+{740+ unsigned int *reg;741+ u8* fdata = (u8*)data;742+743+ reg = (unsigned int *) get_property(node, "reg", NULL);744+ if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]745+ && ((reg[0] >> 16) & 0xff) == fdata[0])746+ return 1;747+ return 0;748+}749+750+static struct device_node*751+scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)752+{753+ u8 filter_data[2] = {bus, dev_fn};754+755+ return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data);756+}757+758+/*759+ * Scans the OF tree for a device node matching a PCI device760+ */761+struct device_node *762+pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)763+{764+ struct pci_controller *hose;765+ struct device_node *node;766+ int busnr;767+768+ if (!have_of)769+ return NULL;770+771+ /* Lookup the hose */772+ busnr = bus->number;773+ hose = pci_bus_to_hose(busnr);774+ if (!hose)775+ return NULL;776+777+ /* Check it has an OF node associated */778+ node = (struct device_node *) hose->arch_data;779+ if (!node)780+ return NULL;781+782+ /* Fixup bus number according to what OF think it is. */783+#ifdef CONFIG_PPC_PMAC784+ /* The G5 need a special case here. Basically, we don't remap all785+ * busses on it so we don't create the pci-OF-map. However, we do786+ * remap the AGP bus and so have to deal with it. A future better787+ * fix has to be done by making the remapping per-host and always788+ * filling the pci_to_OF map. --BenH789+ */790+ if (_machine == _MACH_Pmac && busnr >= 0xf0)791+ busnr -= 0xf0;792+ else793+#endif794+ if (pci_to_OF_bus_map)795+ busnr = pci_to_OF_bus_map[busnr];796+ if (busnr == 0xff)797+ return NULL;798+799+ /* Now, lookup childs of the hose */800+ return scan_OF_childs_for_device(node->child, busnr, devfn);801+}802+EXPORT_SYMBOL(pci_busdev_to_OF_node);803+804+struct device_node*805+pci_device_to_OF_node(struct pci_dev *dev)806+{807+ return pci_busdev_to_OF_node(dev->bus, dev->devfn);808+}809+EXPORT_SYMBOL(pci_device_to_OF_node);810+811+/* This routine is meant to be used early during boot, when the812+ * PCI bus numbers have not yet been assigned, and you need to813+ * issue PCI config cycles to an OF device.814+ * It could also be used to "fix" RTAS config cycles if you want815+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI816+ * config cycles.817+ */818+struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)819+{820+ if (!have_of)821+ return NULL;822+ while(node) {823+ struct pci_controller* hose;824+ for (hose=hose_head;hose;hose=hose->next)825+ if (hose->arch_data == node)826+ return hose;827+ node=node->parent;828+ }829+ return NULL;830+}831+832+static int833+find_OF_pci_device_filter(struct device_node* node, void* data)834+{835+ return ((void *)node == data);836+}837+838+/*839+ * Returns the PCI device matching a given OF node840+ */841+int842+pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)843+{844+ unsigned int *reg;845+ struct pci_controller* hose;846+ struct pci_dev* dev = NULL;847+848+ if (!have_of)849+ return -ENODEV;850+ /* Make sure it's really a PCI device */851+ hose = pci_find_hose_for_OF_device(node);852+ if (!hose || !hose->arch_data)853+ return -ENODEV;854+ if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,855+ find_OF_pci_device_filter, (void *)node))856+ return -ENODEV;857+ reg = (unsigned int *) get_property(node, "reg", NULL);858+ if (!reg)859+ return -ENODEV;860+ *bus = (reg[0] >> 16) & 0xff;861+ *devfn = ((reg[0] >> 8) & 0xff);862+863+ /* Ok, here we need some tweak. If we have already renumbered864+ * all busses, we can't rely on the OF bus number any more.865+ * the pci_to_OF_bus_map is not enough as several PCI busses866+ * may match the same OF bus number.867+ */868+ if (!pci_to_OF_bus_map)869+ return 0;870+871+ for_each_pci_dev(dev)872+ if (pci_to_OF_bus_map[dev->bus->number] == *bus &&873+ dev->devfn == *devfn) {874+ *bus = dev->bus->number;875+ pci_dev_put(dev);876+ return 0;877+ }878+879+ return -ENODEV;880+}881+EXPORT_SYMBOL(pci_device_from_OF_node);882+883+void __init884+pci_process_bridge_OF_ranges(struct pci_controller *hose,885+ struct device_node *dev, int primary)886+{887+ static unsigned int static_lc_ranges[256] __initdata;888+ unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;889+ unsigned int size;890+ int rlen = 0, orig_rlen;891+ int memno = 0;892+ struct resource *res;893+ int np, na = prom_n_addr_cells(dev);894+ np = na + 5;895+896+ /* First we try to merge ranges to fix a problem with some pmacs897+ * that can have more than 3 ranges, fortunately using contiguous898+ * addresses -- BenH899+ */900+ dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);901+ if (!dt_ranges)902+ return;903+ /* Sanity check, though hopefully that never happens */904+ if (rlen > sizeof(static_lc_ranges)) {905+ printk(KERN_WARNING "OF ranges property too large !\n");906+ rlen = sizeof(static_lc_ranges);907+ }908+ lc_ranges = static_lc_ranges;909+ memcpy(lc_ranges, dt_ranges, rlen);910+ orig_rlen = rlen;911+912+ /* Let's work on a copy of the "ranges" property instead of damaging913+ * the device-tree image in memory914+ */915+ ranges = lc_ranges;916+ prev = NULL;917+ while ((rlen -= np * sizeof(unsigned int)) >= 0) {918+ if (prev) {919+ if (prev[0] == ranges[0] && prev[1] == ranges[1] &&920+ (prev[2] + prev[na+4]) == ranges[2] &&921+ (prev[na+2] + prev[na+4]) == ranges[na+2]) {922+ prev[na+4] += ranges[na+4];923+ ranges[0] = 0;924+ ranges += np;925+ continue;926+ }927+ }928+ prev = ranges;929+ ranges += np;930+ }931+932+ /*933+ * The ranges property is laid out as an array of elements,934+ * each of which comprises:935+ * cells 0 - 2: a PCI address936+ * cells 3 or 3+4: a CPU physical address937+ * (size depending on dev->n_addr_cells)938+ * cells 4+5 or 5+6: the size of the range939+ */940+ ranges = lc_ranges;941+ rlen = orig_rlen;942+ while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {943+ res = NULL;944+ size = ranges[na+4];945+ switch ((ranges[0] >> 24) & 0x3) {946+ case 1: /* I/O space */947+ if (ranges[2] != 0)948+ break;949+ hose->io_base_phys = ranges[na+2];950+ /* limit I/O space to 16MB */951+ if (size > 0x01000000)952+ size = 0x01000000;953+ hose->io_base_virt = ioremap(ranges[na+2], size);954+ if (primary)955+ isa_io_base = (unsigned long) hose->io_base_virt;956+ res = &hose->io_resource;957+ res->flags = IORESOURCE_IO;958+ res->start = ranges[2];959+ DBG("PCI: IO 0x%lx -> 0x%lx\n",960+ res->start, res->start + size - 1);961+ break;962+ case 2: /* memory space */963+ memno = 0;964+ if (ranges[1] == 0 && ranges[2] == 0965+ && ranges[na+4] <= (16 << 20)) {966+ /* 1st 16MB, i.e. ISA memory area */967+ if (primary)968+ isa_mem_base = ranges[na+2];969+ memno = 1;970+ }971+ while (memno < 3 && hose->mem_resources[memno].flags)972+ ++memno;973+ if (memno == 0)974+ hose->pci_mem_offset = ranges[na+2] - ranges[2];975+ if (memno < 3) {976+ res = &hose->mem_resources[memno];977+ res->flags = IORESOURCE_MEM;978+ if(ranges[0] & 0x40000000)979+ res->flags |= IORESOURCE_PREFETCH;980+ res->start = ranges[na+2];981+ DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno,982+ res->start, res->start + size - 1);983+ }984+ break;985+ }986+ if (res != NULL) {987+ res->name = dev->full_name;988+ res->end = res->start + size - 1;989+ res->parent = NULL;990+ res->sibling = NULL;991+ res->child = NULL;992+ }993+ ranges += np;994+ }995+}996+997+/* We create the "pci-OF-bus-map" property now so it appears in the998+ * /proc device tree999+ */1000+void __init1001+pci_create_OF_bus_map(void)1002+{1003+ struct property* of_prop;1004+1005+ of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256);1006+ if (of_prop && find_path_device("/")) {1007+ memset(of_prop, -1, sizeof(struct property) + 256);1008+ of_prop->name = "pci-OF-bus-map";1009+ of_prop->length = 256;1010+ of_prop->value = (unsigned char *)&of_prop[1];1011+ prom_add_property(find_path_device("/"), of_prop);1012+ }1013+}1014+1015+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)1016+{1017+ struct pci_dev *pdev;1018+ struct device_node *np;1019+1020+ pdev = to_pci_dev (dev);1021+ np = pci_device_to_OF_node(pdev);1022+ if (np == NULL || np->full_name == NULL)1023+ return 0;1024+ return sprintf(buf, "%s", np->full_name);1025+}1026+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);1027+1028+#else /* CONFIG_PPC_OF */1029+void pcibios_make_OF_bus_map(void)1030+{1031+}1032+#endif /* CONFIG_PPC_OF */1033+1034+/* Add sysfs properties */1035+void pcibios_add_platform_entries(struct pci_dev *pdev)1036+{1037+#ifdef CONFIG_PPC_OF1038+ device_create_file(&pdev->dev, &dev_attr_devspec);1039+#endif /* CONFIG_PPC_OF */1040+}1041+1042+1043+#ifdef CONFIG_PPC_PMAC1044+/*1045+ * This set of routines checks for PCI<->PCI bridges that have closed1046+ * IO resources and have child devices. It tries to re-open an IO1047+ * window on them.1048+ *1049+ * This is a _temporary_ fix to workaround a problem with Apple's OF1050+ * closing IO windows on P2P bridges when the OF drivers of cards1051+ * below this bridge don't claim any IO range (typically ATI or1052+ * Adaptec).1053+ *1054+ * A more complete fix would be to use drivers/pci/setup-bus.c, which1055+ * involves a working pcibios_fixup_pbus_ranges(), some more care about1056+ * ordering when creating the host bus resources, and maybe a few more1057+ * minor tweaks1058+ */1059+1060+/* Initialize bridges with base/limit values we have collected */1061+static void __init1062+do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)1063+{1064+ struct pci_dev *bridge = bus->self;1065+ struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;1066+ u32 l;1067+ u16 w;1068+ struct resource res;1069+1070+ if (bus->resource[0] == NULL)1071+ return;1072+ res = *(bus->resource[0]);1073+1074+ DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));1075+ res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);1076+ res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);1077+ DBG(" IO window: %08lx-%08lx\n", res.start, res.end);1078+1079+ /* Set up the top and bottom of the PCI I/O segment for this bus. */1080+ pci_read_config_dword(bridge, PCI_IO_BASE, &l);1081+ l &= 0xffff000f;1082+ l |= (res.start >> 8) & 0x00f0;1083+ l |= res.end & 0xf000;1084+ pci_write_config_dword(bridge, PCI_IO_BASE, l);1085+1086+ if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {1087+ l = (res.start >> 16) | (res.end & 0xffff0000);1088+ pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);1089+ }1090+1091+ pci_read_config_word(bridge, PCI_COMMAND, &w);1092+ w |= PCI_COMMAND_IO;1093+ pci_write_config_word(bridge, PCI_COMMAND, w);1094+1095+#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */1096+ if (enable_vga) {1097+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);1098+ w |= PCI_BRIDGE_CTL_VGA;1099+ pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);1100+ }1101+#endif1102+}1103+1104+/* This function is pretty basic and actually quite broken for the1105+ * general case, it's enough for us right now though. It's supposed1106+ * to tell us if we need to open an IO range at all or not and what1107+ * size.1108+ */1109+static int __init1110+check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)1111+{1112+ struct pci_dev *dev;1113+ int i;1114+ int rc = 0;1115+1116+#define push_end(res, size) do { unsigned long __sz = (size) ; \1117+ res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \1118+ } while (0)1119+1120+ list_for_each_entry(dev, &bus->devices, bus_list) {1121+ u16 class = dev->class >> 8;1122+1123+ if (class == PCI_CLASS_DISPLAY_VGA ||1124+ class == PCI_CLASS_NOT_DEFINED_VGA)1125+ *found_vga = 1;1126+ if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)1127+ rc |= check_for_io_childs(dev->subordinate, res, found_vga);1128+ if (class == PCI_CLASS_BRIDGE_CARDBUS)1129+ push_end(res, 0xfff);1130+1131+ for (i=0; i<PCI_NUM_RESOURCES; i++) {1132+ struct resource *r;1133+ unsigned long r_size;1134+1135+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI1136+ && i >= PCI_BRIDGE_RESOURCES)1137+ continue;1138+ r = &dev->resource[i];1139+ r_size = r->end - r->start;1140+ if (r_size < 0xfff)1141+ r_size = 0xfff;1142+ if (r->flags & IORESOURCE_IO && (r_size) != 0) {1143+ rc = 1;1144+ push_end(res, r_size);1145+ }1146+ }1147+ }1148+1149+ return rc;1150+}1151+1152+/* Here we scan all P2P bridges of a given level that have a closed1153+ * IO window. Note that the test for the presence of a VGA card should1154+ * be improved to take into account already configured P2P bridges,1155+ * currently, we don't see them and might end up configuring 2 bridges1156+ * with VGA pass through enabled1157+ */1158+static void __init1159+do_fixup_p2p_level(struct pci_bus *bus)1160+{1161+ struct pci_bus *b;1162+ int i, parent_io;1163+ int has_vga = 0;1164+1165+ for (parent_io=0; parent_io<4; parent_io++)1166+ if (bus->resource[parent_io]1167+ && bus->resource[parent_io]->flags & IORESOURCE_IO)1168+ break;1169+ if (parent_io >= 4)1170+ return;1171+1172+ list_for_each_entry(b, &bus->children, node) {1173+ struct pci_dev *d = b->self;1174+ struct pci_controller* hose = (struct pci_controller *)d->sysdata;1175+ struct resource *res = b->resource[0];1176+ struct resource tmp_res;1177+ unsigned long max;1178+ int found_vga = 0;1179+1180+ memset(&tmp_res, 0, sizeof(tmp_res));1181+ tmp_res.start = bus->resource[parent_io]->start;1182+1183+ /* We don't let low addresses go through that closed P2P bridge, well,1184+ * that may not be necessary but I feel safer that way1185+ */1186+ if (tmp_res.start == 0)1187+ tmp_res.start = 0x1000;1188+1189+ if (!list_empty(&b->devices) && res && res->flags == 0 &&1190+ res != bus->resource[parent_io] &&1191+ (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&1192+ check_for_io_childs(b, &tmp_res, &found_vga)) {1193+ u8 io_base_lo;1194+1195+ printk(KERN_INFO "Fixing up IO bus %s\n", b->name);1196+1197+ if (found_vga) {1198+ if (has_vga) {1199+ printk(KERN_WARNING "Skipping VGA, already active"1200+ " on bus segment\n");1201+ found_vga = 0;1202+ } else1203+ has_vga = 1;1204+ }1205+ pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);1206+1207+ if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)1208+ max = ((unsigned long) hose->io_base_virt1209+ - isa_io_base) + 0xffffffff;1210+ else1211+ max = ((unsigned long) hose->io_base_virt1212+ - isa_io_base) + 0xffff;1213+1214+ *res = tmp_res;1215+ res->flags = IORESOURCE_IO;1216+ res->name = b->name;1217+1218+ /* Find a resource in the parent where we can allocate */1219+ for (i = 0 ; i < 4; i++) {1220+ struct resource *r = bus->resource[i];1221+ if (!r)1222+ continue;1223+ if ((r->flags & IORESOURCE_IO) == 0)1224+ continue;1225+ DBG("Trying to allocate from %08lx, size %08lx from parent"1226+ " res %d: %08lx -> %08lx\n",1227+ res->start, res->end, i, r->start, r->end);1228+1229+ if (allocate_resource(r, res, res->end + 1, res->start, max,1230+ res->end + 1, NULL, NULL) < 0) {1231+ DBG("Failed !\n");1232+ continue;1233+ }1234+ do_update_p2p_io_resource(b, found_vga);1235+ break;1236+ }1237+ }1238+ do_fixup_p2p_level(b);1239+ }1240+}1241+1242+static void1243+pcibios_fixup_p2p_bridges(void)1244+{1245+ struct pci_bus *b;1246+1247+ list_for_each_entry(b, &pci_root_buses, node)1248+ do_fixup_p2p_level(b);1249+}1250+1251+#endif /* CONFIG_PPC_PMAC */1252+1253+static int __init1254+pcibios_init(void)1255+{1256+ struct pci_controller *hose;1257+ struct pci_bus *bus;1258+ int next_busno;1259+1260+ printk(KERN_INFO "PCI: Probing PCI hardware\n");1261+1262+ /* Scan all of the recorded PCI controllers. */1263+ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {1264+ if (pci_assign_all_buses)1265+ hose->first_busno = next_busno;1266+ hose->last_busno = 0xff;1267+ bus = pci_scan_bus(hose->first_busno, hose->ops, hose);1268+ hose->last_busno = bus->subordinate;1269+ if (pci_assign_all_buses || next_busno <= hose->last_busno)1270+ next_busno = hose->last_busno + pcibios_assign_bus_offset;1271+ }1272+ pci_bus_count = next_busno;1273+1274+ /* OpenFirmware based machines need a map of OF bus1275+ * numbers vs. kernel bus numbers since we may have to1276+ * remap them.1277+ */1278+ if (pci_assign_all_buses && have_of)1279+ pcibios_make_OF_bus_map();1280+1281+ /* Do machine dependent PCI interrupt routing */1282+ if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)1283+ pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);1284+1285+ /* Call machine dependent fixup */1286+ if (ppc_md.pcibios_fixup)1287+ ppc_md.pcibios_fixup();1288+1289+ /* Allocate and assign resources */1290+ pcibios_allocate_bus_resources(&pci_root_buses);1291+ pcibios_allocate_resources(0);1292+ pcibios_allocate_resources(1);1293+#ifdef CONFIG_PPC_PMAC1294+ pcibios_fixup_p2p_bridges();1295+#endif /* CONFIG_PPC_PMAC */1296+ pcibios_assign_resources();1297+1298+ /* Call machine dependent post-init code */1299+ if (ppc_md.pcibios_after_init)1300+ ppc_md.pcibios_after_init();1301+1302+ return 0;1303+}1304+1305+subsys_initcall(pcibios_init);1306+1307+unsigned char __init1308+common_swizzle(struct pci_dev *dev, unsigned char *pinp)1309+{1310+ struct pci_controller *hose = dev->sysdata;1311+1312+ if (dev->bus->number != hose->first_busno) {1313+ u8 pin = *pinp;1314+ do {1315+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));1316+ /* Move up the chain of bridges. */1317+ dev = dev->bus->self;1318+ } while (dev->bus->self);1319+ *pinp = pin;1320+1321+ /* The slot is the idsel of the last bridge. */1322+ }1323+ return PCI_SLOT(dev->devfn);1324+}1325+1326+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,1327+ unsigned long start, unsigned long size)1328+{1329+ return start;1330+}1331+1332+void __init pcibios_fixup_bus(struct pci_bus *bus)1333+{1334+ struct pci_controller *hose = (struct pci_controller *) bus->sysdata;1335+ unsigned long io_offset;1336+ struct resource *res;1337+ int i;1338+1339+ io_offset = (unsigned long)hose->io_base_virt - isa_io_base;1340+ if (bus->parent == NULL) {1341+ /* This is a host bridge - fill in its resources */1342+ hose->bus = bus;1343+1344+ bus->resource[0] = res = &hose->io_resource;1345+ if (!res->flags) {1346+ if (io_offset)1347+ printk(KERN_ERR "I/O resource not set for host"1348+ " bridge %d\n", hose->index);1349+ res->start = 0;1350+ res->end = IO_SPACE_LIMIT;1351+ res->flags = IORESOURCE_IO;1352+ }1353+ res->start += io_offset;1354+ res->end += io_offset;1355+1356+ for (i = 0; i < 3; ++i) {1357+ res = &hose->mem_resources[i];1358+ if (!res->flags) {1359+ if (i > 0)1360+ continue;1361+ printk(KERN_ERR "Memory resource not set for "1362+ "host bridge %d\n", hose->index);1363+ res->start = hose->pci_mem_offset;1364+ res->end = ~0U;1365+ res->flags = IORESOURCE_MEM;1366+ }1367+ bus->resource[i+1] = res;1368+ }1369+ } else {1370+ /* This is a subordinate bridge */1371+ pci_read_bridge_bases(bus);1372+1373+ for (i = 0; i < 4; ++i) {1374+ if ((res = bus->resource[i]) == NULL)1375+ continue;1376+ if (!res->flags)1377+ continue;1378+ if (io_offset && (res->flags & IORESOURCE_IO)) {1379+ res->start += io_offset;1380+ res->end += io_offset;1381+ } else if (hose->pci_mem_offset1382+ && (res->flags & IORESOURCE_MEM)) {1383+ res->start += hose->pci_mem_offset;1384+ res->end += hose->pci_mem_offset;1385+ }1386+ }1387+ }1388+1389+ if (ppc_md.pcibios_fixup_bus)1390+ ppc_md.pcibios_fixup_bus(bus);1391+}1392+1393+char __init *pcibios_setup(char *str)1394+{1395+ return str;1396+}1397+1398+/* the next one is stolen from the alpha port... */1399+void __init1400+pcibios_update_irq(struct pci_dev *dev, int irq)1401+{1402+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);1403+ /* XXX FIXME - update OF device tree node interrupt property */1404+}1405+1406+int pcibios_enable_device(struct pci_dev *dev, int mask)1407+{1408+ u16 cmd, old_cmd;1409+ int idx;1410+ struct resource *r;1411+1412+ if (ppc_md.pcibios_enable_device_hook)1413+ if (ppc_md.pcibios_enable_device_hook(dev, 0))1414+ return -EINVAL;1415+1416+ pci_read_config_word(dev, PCI_COMMAND, &cmd);1417+ old_cmd = cmd;1418+ for (idx=0; idx<6; idx++) {1419+ r = &dev->resource[idx];1420+ if (r->flags & IORESOURCE_UNSET) {1421+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));1422+ return -EINVAL;1423+ }1424+ if (r->flags & IORESOURCE_IO)1425+ cmd |= PCI_COMMAND_IO;1426+ if (r->flags & IORESOURCE_MEM)1427+ cmd |= PCI_COMMAND_MEMORY;1428+ }1429+ if (cmd != old_cmd) {1430+ printk("PCI: Enabling device %s (%04x -> %04x)\n",1431+ pci_name(dev), old_cmd, cmd);1432+ pci_write_config_word(dev, PCI_COMMAND, cmd);1433+ }1434+ return 0;1435+}1436+1437+struct pci_controller*1438+pci_bus_to_hose(int bus)1439+{1440+ struct pci_controller* hose = hose_head;1441+1442+ for (; hose; hose = hose->next)1443+ if (bus >= hose->first_busno && bus <= hose->last_busno)1444+ return hose;1445+ return NULL;1446+}1447+1448+void __iomem *1449+pci_bus_io_base(unsigned int bus)1450+{1451+ struct pci_controller *hose;1452+1453+ hose = pci_bus_to_hose(bus);1454+ if (!hose)1455+ return NULL;1456+ return hose->io_base_virt;1457+}1458+1459+unsigned long1460+pci_bus_io_base_phys(unsigned int bus)1461+{1462+ struct pci_controller *hose;1463+1464+ hose = pci_bus_to_hose(bus);1465+ if (!hose)1466+ return 0;1467+ return hose->io_base_phys;1468+}1469+1470+unsigned long1471+pci_bus_mem_base_phys(unsigned int bus)1472+{1473+ struct pci_controller *hose;1474+1475+ hose = pci_bus_to_hose(bus);1476+ if (!hose)1477+ return 0;1478+ return hose->pci_mem_offset;1479+}1480+1481+unsigned long1482+pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)1483+{1484+ /* Hack alert again ! See comments in chrp_pci.c1485+ */1486+ struct pci_controller* hose =1487+ (struct pci_controller *)pdev->sysdata;1488+ if (hose && res->flags & IORESOURCE_MEM)1489+ return res->start - hose->pci_mem_offset;1490+ /* We may want to do something with IOs here... */1491+ return res->start;1492+}1493+1494+1495+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,1496+ unsigned long *offset,1497+ enum pci_mmap_state mmap_state)1498+{1499+ struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);1500+ unsigned long io_offset = 0;1501+ int i, res_bit;1502+1503+ if (hose == 0)1504+ return NULL; /* should never happen */1505+1506+ /* If memory, add on the PCI bridge address offset */1507+ if (mmap_state == pci_mmap_mem) {1508+ *offset += hose->pci_mem_offset;1509+ res_bit = IORESOURCE_MEM;1510+ } else {1511+ io_offset = hose->io_base_virt - ___IO_BASE;1512+ *offset += io_offset;1513+ res_bit = IORESOURCE_IO;1514+ }1515+1516+ /*1517+ * Check that the offset requested corresponds to one of the1518+ * resources of the device.1519+ */1520+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {1521+ struct resource *rp = &dev->resource[i];1522+ int flags = rp->flags;1523+1524+ /* treat ROM as memory (should be already) */1525+ if (i == PCI_ROM_RESOURCE)1526+ flags |= IORESOURCE_MEM;1527+1528+ /* Active and same type? */1529+ if ((flags & res_bit) == 0)1530+ continue;1531+1532+ /* In the range of this resource? */1533+ if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)1534+ continue;1535+1536+ /* found it! construct the final physical address */1537+ if (mmap_state == pci_mmap_io)1538+ *offset += hose->io_base_phys - io_offset;1539+ return rp;1540+ }1541+1542+ return NULL;1543+}1544+1545+/*1546+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci1547+ * device mapping.1548+ */1549+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,1550+ pgprot_t protection,1551+ enum pci_mmap_state mmap_state,1552+ int write_combine)1553+{1554+ unsigned long prot = pgprot_val(protection);1555+1556+ /* Write combine is always 0 on non-memory space mappings. On1557+ * memory space, if the user didn't pass 1, we check for a1558+ * "prefetchable" resource. This is a bit hackish, but we use1559+ * this to workaround the inability of /sysfs to provide a write1560+ * combine bit1561+ */1562+ if (mmap_state != pci_mmap_mem)1563+ write_combine = 0;1564+ else if (write_combine == 0) {1565+ if (rp->flags & IORESOURCE_PREFETCH)1566+ write_combine = 1;1567+ }1568+1569+ /* XXX would be nice to have a way to ask for write-through */1570+ prot |= _PAGE_NO_CACHE;1571+ if (write_combine)1572+ prot &= ~_PAGE_GUARDED;1573+ else1574+ prot |= _PAGE_GUARDED;1575+1576+ printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,1577+ prot);1578+1579+ return __pgprot(prot);1580+}1581+1582+/*1583+ * This one is used by /dev/mem and fbdev who have no clue about the1584+ * PCI device, it tries to find the PCI device first and calls the1585+ * above routine1586+ */1587+pgprot_t pci_phys_mem_access_prot(struct file *file,1588+ unsigned long pfn,1589+ unsigned long size,1590+ pgprot_t protection)1591+{1592+ struct pci_dev *pdev = NULL;1593+ struct resource *found = NULL;1594+ unsigned long prot = pgprot_val(protection);1595+ unsigned long offset = pfn << PAGE_SHIFT;1596+ int i;1597+1598+ if (page_is_ram(pfn))1599+ return prot;1600+1601+ prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;1602+1603+ for_each_pci_dev(pdev) {1604+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {1605+ struct resource *rp = &pdev->resource[i];1606+ int flags = rp->flags;1607+1608+ /* Active and same type? */1609+ if ((flags & IORESOURCE_MEM) == 0)1610+ continue;1611+ /* In the range of this resource? */1612+ if (offset < (rp->start & PAGE_MASK) ||1613+ offset > rp->end)1614+ continue;1615+ found = rp;1616+ break;1617+ }1618+ if (found)1619+ break;1620+ }1621+ if (found) {1622+ if (found->flags & IORESOURCE_PREFETCH)1623+ prot &= ~_PAGE_GUARDED;1624+ pci_dev_put(pdev);1625+ }1626+1627+ DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);1628+1629+ return __pgprot(prot);1630+}1631+1632+1633+/*1634+ * Perform the actual remap of the pages for a PCI device mapping, as1635+ * appropriate for this architecture. The region in the process to map1636+ * is described by vm_start and vm_end members of VMA, the base physical1637+ * address is found in vm_pgoff.1638+ * The pci device structure is provided so that architectures may make mapping1639+ * decisions on a per-device or per-bus basis.1640+ *1641+ * Returns a negative error code on failure, zero on success.1642+ */1643+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,1644+ enum pci_mmap_state mmap_state,1645+ int write_combine)1646+{1647+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;1648+ struct resource *rp;1649+ int ret;1650+1651+ rp = __pci_mmap_make_offset(dev, &offset, mmap_state);1652+ if (rp == NULL)1653+ return -EINVAL;1654+1655+ vma->vm_pgoff = offset >> PAGE_SHIFT;1656+ vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;1657+ vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,1658+ vma->vm_page_prot,1659+ mmap_state, write_combine);1660+1661+ ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,1662+ vma->vm_end - vma->vm_start, vma->vm_page_prot);1663+1664+ return ret;1665+}1666+1667+/* Obsolete functions. Should be removed once the symbios driver1668+ * is fixed1669+ */1670+unsigned long1671+phys_to_bus(unsigned long pa)1672+{1673+ struct pci_controller *hose;1674+ int i;1675+1676+ for (hose = hose_head; hose; hose = hose->next) {1677+ for (i = 0; i < 3; ++i) {1678+ if (pa >= hose->mem_resources[i].start1679+ && pa <= hose->mem_resources[i].end) {1680+ /*1681+ * XXX the hose->pci_mem_offset really1682+ * only applies to mem_resources[0].1683+ * We need a way to store an offset for1684+ * the others. -- paulus1685+ */1686+ if (i == 0)1687+ pa -= hose->pci_mem_offset;1688+ return pa;1689+ }1690+ }1691+ }1692+ /* hmmm, didn't find it */1693+ return 0;1694+}1695+1696+unsigned long1697+pci_phys_to_bus(unsigned long pa, int busnr)1698+{1699+ struct pci_controller* hose = pci_bus_to_hose(busnr);1700+ if (!hose)1701+ return pa;1702+ return pa - hose->pci_mem_offset;1703+}1704+1705+unsigned long1706+pci_bus_to_phys(unsigned int ba, int busnr)1707+{1708+ struct pci_controller* hose = pci_bus_to_hose(busnr);1709+ if (!hose)1710+ return ba;1711+ return ba + hose->pci_mem_offset;1712+}1713+1714+/* Provide information on locations of various I/O regions in physical1715+ * memory. Do this on a per-card basis so that we choose the right1716+ * root bridge.1717+ * Note that the returned IO or memory base is a physical address1718+ */1719+1720+long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)1721+{1722+ struct pci_controller* hose;1723+ long result = -EOPNOTSUPP;1724+1725+ /* Argh ! Please forgive me for that hack, but that's the1726+ * simplest way to get existing XFree to not lockup on some1727+ * G5 machines... So when something asks for bus 0 io base1728+ * (bus 0 is HT root), we return the AGP one instead.1729+ */1730+#ifdef CONFIG_PPC_PMAC1731+ if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))1732+ if (bus == 0)1733+ bus = 0xf0;1734+#endif /* CONFIG_PPC_PMAC */1735+1736+ hose = pci_bus_to_hose(bus);1737+ if (!hose)1738+ return -ENODEV;1739+1740+ switch (which) {1741+ case IOBASE_BRIDGE_NUMBER:1742+ return (long)hose->first_busno;1743+ case IOBASE_MEMORY:1744+ return (long)hose->pci_mem_offset;1745+ case IOBASE_IO:1746+ return (long)hose->io_base_phys;1747+ case IOBASE_ISA_IO:1748+ return (long)isa_io_base;1749+ case IOBASE_ISA_MEM:1750+ return (long)isa_mem_base;1751+ }1752+1753+ return result;1754+}1755+1756+void pci_resource_to_user(const struct pci_dev *dev, int bar,1757+ const struct resource *rsrc,1758+ u64 *start, u64 *end)1759+{1760+ struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);1761+ unsigned long offset = 0;1762+1763+ if (hose == NULL)1764+ return;1765+1766+ if (rsrc->flags & IORESOURCE_IO)1767+ offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;1768+1769+ *start = rsrc->start + offset;1770+ *end = rsrc->end + offset;1771+}1772+1773+void __init1774+pci_init_resource(struct resource *res, unsigned long start, unsigned long end,1775+ int flags, char *name)1776+{1777+ res->start = start;1778+ res->end = end;1779+ res->flags = flags;1780+ res->name = name;1781+ res->parent = NULL;1782+ res->sibling = NULL;1783+ res->child = NULL;1784+}1785+1786+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)1787+{1788+ unsigned long start = pci_resource_start(dev, bar);1789+ unsigned long len = pci_resource_len(dev, bar);1790+ unsigned long flags = pci_resource_flags(dev, bar);1791+1792+ if (!len)1793+ return NULL;1794+ if (max && len > max)1795+ len = max;1796+ if (flags & IORESOURCE_IO)1797+ return ioport_map(start, len);1798+ if (flags & IORESOURCE_MEM)1799+ /* Not checking IORESOURCE_CACHEABLE because PPC does1800+ * not currently distinguish between ioremap and1801+ * ioremap_nocache.1802+ */1803+ return ioremap(start, len);1804+ /* What? */1805+ return NULL;1806+}1807+1808+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)1809+{1810+ /* Nothing to do */1811+}1812+EXPORT_SYMBOL(pci_iomap);1813+EXPORT_SYMBOL(pci_iounmap);1814+1815+unsigned long pci_address_to_pio(phys_addr_t address)1816+{1817+ struct pci_controller* hose = hose_head;1818+1819+ for (; hose; hose = hose->next) {1820+ unsigned int size = hose->io_resource.end -1821+ hose->io_resource.start + 1;1822+ if (address >= hose->io_base_phys &&1823+ address < (hose->io_base_phys + size)) {1824+ unsigned long base =1825+ (unsigned long)hose->io_base_virt - _IO_BASE;1826+ return base + (address - hose->io_base_phys);1827+ }1828+ }1829+ return (unsigned int)-1;1830+}1831+EXPORT_SYMBOL(pci_address_to_pio);1832+1833+/*1834+ * Null PCI config access functions, for the case when we can't1835+ * find a hose.1836+ */1837+#define NULL_PCI_OP(rw, size, type) \1838+static int \1839+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \1840+{ \1841+ return PCIBIOS_DEVICE_NOT_FOUND; \1842+}1843+1844+static int1845+null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,1846+ int len, u32 *val)1847+{1848+ return PCIBIOS_DEVICE_NOT_FOUND;1849+}1850+1851+static int1852+null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,1853+ int len, u32 val)1854+{1855+ return PCIBIOS_DEVICE_NOT_FOUND;1856+}1857+1858+static struct pci_ops null_pci_ops =1859+{1860+ null_read_config,1861+ null_write_config1862+};1863+1864+/*1865+ * These functions are used early on before PCI scanning is done1866+ * and all of the pci_dev and pci_bus structures have been created.1867+ */1868+static struct pci_bus *1869+fake_pci_bus(struct pci_controller *hose, int busnr)1870+{1871+ static struct pci_bus bus;1872+1873+ if (hose == 0) {1874+ hose = pci_bus_to_hose(busnr);1875+ if (hose == 0)1876+ printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);1877+ }1878+ bus.number = busnr;1879+ bus.sysdata = hose;1880+ bus.ops = hose? hose->ops: &null_pci_ops;1881+ return &bus;1882+}1883+1884+#define EARLY_PCI_OP(rw, size, type) \1885+int early_##rw##_config_##size(struct pci_controller *hose, int bus, \1886+ int devfn, int offset, type value) \1887+{ \1888+ return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \1889+ devfn, offset, value); \1890+}1891+1892+EARLY_PCI_OP(read, byte, u8 *)1893+EARLY_PCI_OP(read, word, u16 *)1894+EARLY_PCI_OP(read, dword, u32 *)1895+EARLY_PCI_OP(write, byte, u8)1896+EARLY_PCI_OP(write, word, u16)1897+EARLY_PCI_OP(write, dword, u32)
···316 char* disp_name;317 int *bus_range;318 int primary = 1;319- struct property *of_prop;320321 DBG("Adding PCI host bridge %s\n", dev->full_name);322
···316 char* disp_name;317 int *bus_range;318 int primary = 1;0319320 DBG("Adding PCI host bridge %s\n", dev->full_name);321
+50-35
arch/powerpc/platforms/maple/setup.c
···71#define DBG(fmt...)72#endif730000000000000000000000000074static void maple_restart(char *cmd)75{76 unsigned int maple_nvram_base;77 unsigned int maple_nvram_offset;78 unsigned int maple_nvram_command;79- struct device_node *rtcs;8081- /* find NVRAM device */82- rtcs = find_compatible_devices("nvram", "AMD8111");83- if (rtcs && rtcs->addrs) {84- maple_nvram_base = rtcs->addrs[0].address;85- } else {86- printk(KERN_EMERG "Maple: Unable to find NVRAM\n");87- printk(KERN_EMERG "Maple: Manual Restart Required\n");88- return;89- }9091 /* find service processor device */92- rtcs = find_devices("service-processor");93- if (!rtcs) {94 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");95- printk(KERN_EMERG "Maple: Manual Restart Required\n");96- return;97 }98- maple_nvram_offset = *(unsigned int*) get_property(rtcs,99 "restart-addr", NULL);100- maple_nvram_command = *(unsigned int*) get_property(rtcs,101 "restart-value", NULL);0102103 /* send command */104 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);105 for (;;) ;00106}107108static void maple_power_off(void)···132 unsigned int maple_nvram_base;133 unsigned int maple_nvram_offset;134 unsigned int maple_nvram_command;135- struct device_node *rtcs;136137- /* find NVRAM device */138- rtcs = find_compatible_devices("nvram", "AMD8111");139- if (rtcs && rtcs->addrs) {140- maple_nvram_base = rtcs->addrs[0].address;141- } else {142- printk(KERN_EMERG "Maple: Unable to find NVRAM\n");143- printk(KERN_EMERG "Maple: Manual Power-Down Required\n");144- return;145- }146147 /* find service processor device */148- rtcs = find_devices("service-processor");149- if (!rtcs) {150 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");151- printk(KERN_EMERG "Maple: Manual Power-Down Required\n");152- return;153 }154- maple_nvram_offset = *(unsigned int*) get_property(rtcs,155 "power-off-addr", NULL);156- maple_nvram_command = *(unsigned int*) get_property(rtcs,157 "power-off-value", NULL);0158159 /* send command */160 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);161 for (;;) ;00162}163164static void maple_halt(void)···197 */198static void __init maple_init_early(void)199{200- unsigned int default_speed;201- u64 physport;202-203 DBG(" -> maple_init_early\n");204205 /* Initialize hash table, from now on, we can take hash faults
···71#define DBG(fmt...)72#endif7374+static unsigned long maple_find_nvram_base(void)75+{76+ struct device_node *rtcs;77+ unsigned long result = 0;78+79+ /* find NVRAM device */80+ rtcs = of_find_compatible_node(NULL, "nvram", "AMD8111");81+ if (rtcs) {82+ struct resource r;83+ if (of_address_to_resource(rtcs, 0, &r)) {84+ printk(KERN_EMERG "Maple: Unable to translate NVRAM"85+ " address\n");86+ goto bail;87+ }88+ if (!(r.flags & IORESOURCE_IO)) {89+ printk(KERN_EMERG "Maple: NVRAM address isn't PIO!\n");90+ goto bail;91+ }92+ result = r.start;93+ } else94+ printk(KERN_EMERG "Maple: Unable to find NVRAM\n");95+ bail:96+ of_node_put(rtcs);97+ return result;98+}99+100static void maple_restart(char *cmd)101{102 unsigned int maple_nvram_base;103 unsigned int maple_nvram_offset;104 unsigned int maple_nvram_command;105+ struct device_node *sp;106107+ maple_nvram_base = maple_find_nvram_base();108+ if (maple_nvram_base == 0)109+ goto fail;000000110111 /* find service processor device */112+ sp = of_find_node_by_name(NULL, "service-processor");113+ if (!sp) {114 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");115+ goto fail;0116 }117+ maple_nvram_offset = *(unsigned int*) get_property(sp,118 "restart-addr", NULL);119+ maple_nvram_command = *(unsigned int*) get_property(sp,120 "restart-value", NULL);121+ of_node_put(sp);122123 /* send command */124 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);125 for (;;) ;126+ fail:127+ printk(KERN_EMERG "Maple: Manual Restart Required\n");128}129130static void maple_power_off(void)···110 unsigned int maple_nvram_base;111 unsigned int maple_nvram_offset;112 unsigned int maple_nvram_command;113+ struct device_node *sp;114115+ maple_nvram_base = maple_find_nvram_base();116+ if (maple_nvram_base == 0)117+ goto fail;000000118119 /* find service processor device */120+ sp = of_find_node_by_name(NULL, "service-processor");121+ if (!sp) {122 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");123+ goto fail;0124 }125+ maple_nvram_offset = *(unsigned int*) get_property(sp,126 "power-off-addr", NULL);127+ maple_nvram_command = *(unsigned int*) get_property(sp,128 "power-off-value", NULL);129+ of_node_put(sp);130131 /* send command */132 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);133 for (;;) ;134+ fail:135+ printk(KERN_EMERG "Maple: Manual Power-Down Required\n");136}137138static void maple_halt(void)···179 */180static void __init maple_init_early(void)181{000182 DBG(" -> maple_init_early\n");183184 /* Initialize hash table, from now on, we can take hash faults
+18-5
arch/powerpc/platforms/maple/time.c
···168 struct rtc_time tm;169 struct device_node *rtcs;170171- rtcs = find_compatible_devices("rtc", "pnpPNP,b00");172- if (rtcs && rtcs->addrs) {173- maple_rtc_addr = rtcs->addrs[0].address;174- printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr);175- } else {0000000000000176 maple_rtc_addr = RTC_PORT(0); /* legacy address */177 printk(KERN_INFO "Maple: No device node for RTC, assuming "178 "legacy address (0x%x)\n", maple_rtc_addr);
···168 struct rtc_time tm;169 struct device_node *rtcs;170171+ rtcs = of_find_compatible_node(NULL, "rtc", "pnpPNP,b00");172+ if (rtcs) {173+ struct resource r;174+ if (of_address_to_resource(rtcs, 0, &r)) {175+ printk(KERN_EMERG "Maple: Unable to translate RTC"176+ " address\n");177+ goto bail;178+ }179+ if (!(r.flags & IORESOURCE_IO)) {180+ printk(KERN_EMERG "Maple: RTC address isn't PIO!\n");181+ goto bail;182+ }183+ maple_rtc_addr = r.start;184+ printk(KERN_INFO "Maple: Found RTC at IO 0x%x\n",185+ maple_rtc_addr);186+ }187+ bail:188+ if (maple_rtc_addr == 0) {189 maple_rtc_addr = RTC_PORT(0); /* legacy address */190 printk(KERN_INFO "Maple: No device node for RTC, assuming "191 "legacy address (0x%x)\n", maple_rtc_addr);
+22-51
arch/ppc/Kconfig
···58 help59 There are four types of PowerPC chips supported. The more common60 types (601, 603, 604, 740, 750, 7400), the Motorola embedded61- versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM embedded62- versions (403 and 405) and the high end 64 bit Power processors63- (POWER 3, POWER4, and IBM 970 also known as G5)64 Unless you are building a kernel for one of the embedded processor65- systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.66 Note that the kernel runs in 32-bit mode even on 64-bit chips.67 Also note that because the 52xx, 82xx, & 83xx family has a 603e core,68 specific support for that chipset is asked later on.···76config POWER377 select PPC_FPU78 bool "POWER3"79-80-config POWER481- select PPC_FPU82- bool "POWER4 and 970 (G5)"8384config 8xx85 bool "8xx"···119120config ALTIVEC121 bool "AltiVec Support"122- depends on 6xx || POWER4123 depends on !8260 && !83xx124 ---help---125 This option enables kernel support for the Altivec extensions to the···231232source "drivers/cpufreq/Kconfig"233234-config CPU_FREQ_PMAC235- bool "Support for Apple PowerBooks"236- depends on CPU_FREQ && ADB_PMU237- select CPU_FREQ_TABLE238- help239- This adds support for frequency switching on Apple PowerBooks,240- this currently includes some models of iBook & Titanium241- PowerBook.242-243config PPC601_SYNC_FIX244 bool "Workarounds for PPC601 bugs"245- depends on 6xx && (PPC_PREP || PPC_PMAC)246 help247 Some versions of the PPC601 (the first PowerPC chip) have bugs which248 mean that extra synchronization instructions are required near···245246 If in doubt, say Y here.247248-config HOTPLUG_CPU249- bool "Support for enabling/disabling CPUs"250- depends on SMP && HOTPLUG && EXPERIMENTAL && PPC_PMAC251- ---help---252- Say Y here to be able to disable and re-enable individual253- CPUs at runtime on SMP machines.254-255- Say N if you are unsure.256-257source arch/ppc/platforms/4xx/Kconfig258source arch/ppc/platforms/85xx/Kconfig259260config PPC64BRIDGE261 bool262- depends on POWER3 || POWER4263 default y264265config PPC_STD_MMU266 bool267- depends on 6xx || POWER3 || POWER4268 default y269270config NOT_COHERENT_CACHE···483484choice485 prompt "Machine Type"486- depends on 6xx || POWER3 || POWER4487 default PPC_MULTIPLATFORM488 ---help---489 Linux currently supports several different kinds of PowerPC-based···494 Platform) machines (including all of the recent IBM RS/6000 and495 pSeries machines), and several embedded PowerPC systems containing496 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the497- default option is to build a kernel which works on the first three.498499- Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or500- pSeries machine, a Power Macintosh (including iMacs, iBooks and501- Powerbooks), or a PReP machine.0000502503 Select Gemini if configuring for a Synergy Microsystems' Gemini504 series Single Board Computer. More information is available at:···512 available at: <http://linux-apus.sourceforge.net/>.513514config PPC_MULTIPLATFORM515- bool "CHRP/PowerMac/PReP"516517config APUS518 bool "Amiga-APUS"···750 on it (826x, 827x, 8560).751752config PPC_CHRP753- bool754 depends on PPC_MULTIPLATFORM755 select PPC_I8259756 select PPC_INDIRECT_PCI757 default y758759-config PPC_PMAC760- bool761- depends on PPC_MULTIPLATFORM762- select PPC_INDIRECT_PCI763- default y764-765-config PPC_PMAC64766- bool767- depends on PPC_PMAC && POWER4768- default y769-770config PPC_PREP771- bool772 depends on PPC_MULTIPLATFORM773 select PPC_I8259774 select PPC_INDIRECT_PCI···765766config PPC_OF767 bool768- depends on PPC_PMAC || PPC_CHRP769 default y770771config PPC_GEN550···11371138config GENERIC_ISA_DMA1139 bool1140- depends on POWER3 || POWER4 || 6xx && !CPM21141 default y11421143config PPC_I8259
···58 help59 There are four types of PowerPC chips supported. The more common60 types (601, 603, 604, 740, 750, 7400), the Motorola embedded61+ versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM62+ embedded versions (403 and 405) and the POWER3 processor.63+ (For support for more recent 64-bit processors, set ARCH=powerpc.)64 Unless you are building a kernel for one of the embedded processor65+ systems or a POWER3-based IBM RS/6000, choose 6xx.66 Note that the kernel runs in 32-bit mode even on 64-bit chips.67 Also note that because the 52xx, 82xx, & 83xx family has a 603e core,68 specific support for that chipset is asked later on.···76config POWER377 select PPC_FPU78 bool "POWER3"00007980config 8xx81 bool "8xx"···123124config ALTIVEC125 bool "AltiVec Support"126+ depends on 6xx127 depends on !8260 && !83xx128 ---help---129 This option enables kernel support for the Altivec extensions to the···235236source "drivers/cpufreq/Kconfig"237000000000238config PPC601_SYNC_FIX239 bool "Workarounds for PPC601 bugs"240+ depends on 6xx && PPC_PREP241 help242 Some versions of the PPC601 (the first PowerPC chip) have bugs which243 mean that extra synchronization instructions are required near···258259 If in doubt, say Y here.260000000000261source arch/ppc/platforms/4xx/Kconfig262source arch/ppc/platforms/85xx/Kconfig263264config PPC64BRIDGE265 bool266+ depends on POWER3267 default y268269config PPC_STD_MMU270 bool271+ depends on 6xx || POWER3272 default y273274config NOT_COHERENT_CACHE···505506choice507 prompt "Machine Type"508+ depends on 6xx || POWER3509 default PPC_MULTIPLATFORM510 ---help---511 Linux currently supports several different kinds of PowerPC-based···516 Platform) machines (including all of the recent IBM RS/6000 and517 pSeries machines), and several embedded PowerPC systems containing518 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the519+ default option is to build a kernel which works on PReP and CHRP.520521+ Note that support for Apple machines is now only available with522+ ARCH=powerpc, and has been removed from this menu. If you wish523+ to build a kernel for an Apple machine, exit this configuration524+ process and re-run it with ARCH=powerpc.525+526+ Select CHRP/PReP if configuring for an IBM RS/6000 or527+ pSeries machine, or a PReP machine.528529 Select Gemini if configuring for a Synergy Microsystems' Gemini530 series Single Board Computer. More information is available at:···530 available at: <http://linux-apus.sourceforge.net/>.531532config PPC_MULTIPLATFORM533+ bool "CHRP/PReP"534535config APUS536 bool "Amiga-APUS"···768 on it (826x, 827x, 8560).769770config PPC_CHRP771+ bool "Support for CHRP (Common Hardware Reference Platform) machines"772 depends on PPC_MULTIPLATFORM773 select PPC_I8259774 select PPC_INDIRECT_PCI775 default y77600000000000777config PPC_PREP778+ bool "Support for PReP (PowerPC Reference Platform) machines"779 depends on PPC_MULTIPLATFORM780 select PPC_I8259781 select PPC_INDIRECT_PCI···794795config PPC_OF796 bool797+ depends on PPC_CHRP798 default y799800config PPC_GEN550···11661167config GENERIC_ISA_DMA1168 bool1169+ depends on POWER3 || 6xx && !CPM21170 default y11711172config PPC_I8259
+1-1
arch/ppc/boot/Makefile
···18bootdir-y := simple19bootdir-$(CONFIG_PPC_OF) += openfirmware20subdir-y := lib common images21-subdir-$(CONFIG_PPC_OF) += of12752223# for cleaning24subdir- += simple openfirmware
···18bootdir-y := simple19bootdir-$(CONFIG_PPC_OF) += openfirmware20subdir-y := lib common images21+subdir-$(CONFIG_PPC_MULTIPLATFORM) += of12752223# for cleaning24subdir- += simple openfirmware
···204 mtctr r5205 bctr206207-#if defined(CONFIG_CPU_FREQ_PMAC) && defined(CONFIG_6xx)208-209-/* This gets called by via-pmu.c to switch the PLL selection210- * on 750fx CPU. This function should really be moved to some211- * other place (as most of the cpufreq code in via-pmu212- */213-_GLOBAL(low_choose_750fx_pll)214- /* Clear MSR:EE */215- mfmsr r7216- rlwinm r0,r7,0,17,15217- mtmsr r0218-219- /* If switching to PLL1, disable HID0:BTIC */220- cmplwi cr0,r3,0221- beq 1f222- mfspr r5,SPRN_HID0223- rlwinm r5,r5,0,27,25224- sync225- mtspr SPRN_HID0,r5226- isync227- sync228-229-1:230- /* Calc new HID1 value */231- mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */232- rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */233- rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */234- or r4,r4,r5235- mtspr SPRN_HID1,r4236-237- /* Store new HID1 image */238- rlwinm r6,r1,0,0,18239- lwz r6,TI_CPU(r6)240- slwi r6,r6,2241- addis r6,r6,nap_save_hid1@ha242- stw r4,nap_save_hid1@l(r6)243-244- /* If switching to PLL0, enable HID0:BTIC */245- cmplwi cr0,r3,0246- bne 1f247- mfspr r5,SPRN_HID0248- ori r5,r5,HID0_BTIC249- sync250- mtspr SPRN_HID0,r5251- isync252- sync253-254-1:255- /* Return */256- mtmsr r7257- blr258-259-_GLOBAL(low_choose_7447a_dfs)260- /* Clear MSR:EE */261- mfmsr r7262- rlwinm r0,r7,0,17,15263- mtmsr r0264-265- /* Calc new HID1 value */266- mfspr r4,SPRN_HID1267- insrwi r4,r3,1,9 /* insert parameter into bit 9 */268- sync269- mtspr SPRN_HID1,r4270- sync271- isync272-273- /* Return */274- mtmsr r7275- blr276-277-#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */278-279/*280 * complement mask on the msr then "or" some values on.281 * _nmask_and_or_msr(nmask, value_to_or)
···204 mtctr r5205 bctr206000000000000000000000000000000000000000000000000000000000000000000000000207/*208 * complement mask on the msr then "or" some values on.209 * _nmask_and_or_msr(nmask, value_to_or)
+2-238
arch/ppc/kernel/pci.c
···1/*2- * Common pmac/prep/chrp pci routines. -- Cort3 */45#include <linux/config.h>···50static u8* pci_to_OF_bus_map;51#endif5253-/* By default, we don't re-assign bus numbers. We do this only on54- * some pmacs55 */56int pci_assign_all_buses;57···779 return NULL;780781 /* Fixup bus number according to what OF think it is. */782-#ifdef CONFIG_PPC_PMAC783- /* The G5 need a special case here. Basically, we don't remap all784- * busses on it so we don't create the pci-OF-map. However, we do785- * remap the AGP bus and so have to deal with it. A future better786- * fix has to be done by making the remapping per-host and always787- * filling the pci_to_OF map. --BenH788- */789- if (_machine == _MACH_Pmac && busnr >= 0xf0)790- busnr -= 0xf0;791- else792-#endif793 if (pci_to_OF_bus_map)794 busnr = pci_to_OF_bus_map[busnr];795 if (busnr == 0xff)···1028}102910301031-#ifdef CONFIG_PPC_PMAC1032-/*1033- * This set of routines checks for PCI<->PCI bridges that have closed1034- * IO resources and have child devices. It tries to re-open an IO1035- * window on them.1036- *1037- * This is a _temporary_ fix to workaround a problem with Apple's OF1038- * closing IO windows on P2P bridges when the OF drivers of cards1039- * below this bridge don't claim any IO range (typically ATI or1040- * Adaptec).1041- *1042- * A more complete fix would be to use drivers/pci/setup-bus.c, which1043- * involves a working pcibios_fixup_pbus_ranges(), some more care about1044- * ordering when creating the host bus resources, and maybe a few more1045- * minor tweaks1046- */1047-1048-/* Initialize bridges with base/limit values we have collected */1049-static void __init1050-do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)1051-{1052- struct pci_dev *bridge = bus->self;1053- struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;1054- u32 l;1055- u16 w;1056- struct resource res;1057-1058- if (bus->resource[0] == NULL)1059- return;1060- res = *(bus->resource[0]);1061-1062- DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));1063- res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);1064- res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);1065- DBG(" IO window: %08lx-%08lx\n", res.start, res.end);1066-1067- /* Set up the top and bottom of the PCI I/O segment for this bus. */1068- pci_read_config_dword(bridge, PCI_IO_BASE, &l);1069- l &= 0xffff000f;1070- l |= (res.start >> 8) & 0x00f0;1071- l |= res.end & 0xf000;1072- pci_write_config_dword(bridge, PCI_IO_BASE, l);1073-1074- if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {1075- l = (res.start >> 16) | (res.end & 0xffff0000);1076- pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);1077- }1078-1079- pci_read_config_word(bridge, PCI_COMMAND, &w);1080- w |= PCI_COMMAND_IO;1081- pci_write_config_word(bridge, PCI_COMMAND, w);1082-1083-#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */1084- if (enable_vga) {1085- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);1086- w |= PCI_BRIDGE_CTL_VGA;1087- pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);1088- }1089-#endif1090-}1091-1092-/* This function is pretty basic and actually quite broken for the1093- * general case, it's enough for us right now though. It's supposed1094- * to tell us if we need to open an IO range at all or not and what1095- * size.1096- */1097-static int __init1098-check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)1099-{1100- struct pci_dev *dev;1101- int i;1102- int rc = 0;1103-1104-#define push_end(res, size) do { unsigned long __sz = (size) ; \1105- res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \1106- } while (0)1107-1108- list_for_each_entry(dev, &bus->devices, bus_list) {1109- u16 class = dev->class >> 8;1110-1111- if (class == PCI_CLASS_DISPLAY_VGA ||1112- class == PCI_CLASS_NOT_DEFINED_VGA)1113- *found_vga = 1;1114- if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)1115- rc |= check_for_io_childs(dev->subordinate, res, found_vga);1116- if (class == PCI_CLASS_BRIDGE_CARDBUS)1117- push_end(res, 0xfff);1118-1119- for (i=0; i<PCI_NUM_RESOURCES; i++) {1120- struct resource *r;1121- unsigned long r_size;1122-1123- if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI1124- && i >= PCI_BRIDGE_RESOURCES)1125- continue;1126- r = &dev->resource[i];1127- r_size = r->end - r->start;1128- if (r_size < 0xfff)1129- r_size = 0xfff;1130- if (r->flags & IORESOURCE_IO && (r_size) != 0) {1131- rc = 1;1132- push_end(res, r_size);1133- }1134- }1135- }1136-1137- return rc;1138-}1139-1140-/* Here we scan all P2P bridges of a given level that have a closed1141- * IO window. Note that the test for the presence of a VGA card should1142- * be improved to take into account already configured P2P bridges,1143- * currently, we don't see them and might end up configuring 2 bridges1144- * with VGA pass through enabled1145- */1146-static void __init1147-do_fixup_p2p_level(struct pci_bus *bus)1148-{1149- struct pci_bus *b;1150- int i, parent_io;1151- int has_vga = 0;1152-1153- for (parent_io=0; parent_io<4; parent_io++)1154- if (bus->resource[parent_io]1155- && bus->resource[parent_io]->flags & IORESOURCE_IO)1156- break;1157- if (parent_io >= 4)1158- return;1159-1160- list_for_each_entry(b, &bus->children, node) {1161- struct pci_dev *d = b->self;1162- struct pci_controller* hose = (struct pci_controller *)d->sysdata;1163- struct resource *res = b->resource[0];1164- struct resource tmp_res;1165- unsigned long max;1166- int found_vga = 0;1167-1168- memset(&tmp_res, 0, sizeof(tmp_res));1169- tmp_res.start = bus->resource[parent_io]->start;1170-1171- /* We don't let low addresses go through that closed P2P bridge, well,1172- * that may not be necessary but I feel safer that way1173- */1174- if (tmp_res.start == 0)1175- tmp_res.start = 0x1000;1176-1177- if (!list_empty(&b->devices) && res && res->flags == 0 &&1178- res != bus->resource[parent_io] &&1179- (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&1180- check_for_io_childs(b, &tmp_res, &found_vga)) {1181- u8 io_base_lo;1182-1183- printk(KERN_INFO "Fixing up IO bus %s\n", b->name);1184-1185- if (found_vga) {1186- if (has_vga) {1187- printk(KERN_WARNING "Skipping VGA, already active"1188- " on bus segment\n");1189- found_vga = 0;1190- } else1191- has_vga = 1;1192- }1193- pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);1194-1195- if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)1196- max = ((unsigned long) hose->io_base_virt1197- - isa_io_base) + 0xffffffff;1198- else1199- max = ((unsigned long) hose->io_base_virt1200- - isa_io_base) + 0xffff;1201-1202- *res = tmp_res;1203- res->flags = IORESOURCE_IO;1204- res->name = b->name;1205-1206- /* Find a resource in the parent where we can allocate */1207- for (i = 0 ; i < 4; i++) {1208- struct resource *r = bus->resource[i];1209- if (!r)1210- continue;1211- if ((r->flags & IORESOURCE_IO) == 0)1212- continue;1213- DBG("Trying to allocate from %08lx, size %08lx from parent"1214- " res %d: %08lx -> %08lx\n",1215- res->start, res->end, i, r->start, r->end);1216-1217- if (allocate_resource(r, res, res->end + 1, res->start, max,1218- res->end + 1, NULL, NULL) < 0) {1219- DBG("Failed !\n");1220- continue;1221- }1222- do_update_p2p_io_resource(b, found_vga);1223- break;1224- }1225- }1226- do_fixup_p2p_level(b);1227- }1228-}1229-1230-static void1231-pcibios_fixup_p2p_bridges(void)1232-{1233- struct pci_bus *b;1234-1235- list_for_each_entry(b, &pci_root_buses, node)1236- do_fixup_p2p_level(b);1237-}1238-1239-#endif /* CONFIG_PPC_PMAC */1240-1241static int __init1242pcibios_init(void)1243{···1068 pcibios_allocate_bus_resources(&pci_root_buses);1069 pcibios_allocate_resources(0);1070 pcibios_allocate_resources(1);1071-#ifdef CONFIG_PPC_PMAC1072- pcibios_fixup_p2p_bridges();1073-#endif /* CONFIG_PPC_PMAC */1074 pcibios_assign_resources();10751076 /* Call machine dependent post-init code */···1496{1497 struct pci_controller* hose;1498 long result = -EOPNOTSUPP;1499-1500- /* Argh ! Please forgive me for that hack, but that's the1501- * simplest way to get existing XFree to not lockup on some1502- * G5 machines... So when something asks for bus 0 io base1503- * (bus 0 is HT root), we return the AGP one instead.1504- */1505-#ifdef CONFIG_PPC_PMAC1506- if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))1507- if (bus == 0)1508- bus = 0xf0;1509-#endif /* CONFIG_PPC_PMAC */15101511 hose = pci_bus_to_hose(bus);1512 if (!hose)
···1/*2+ * Common prep/chrp pci routines. -- Cort3 */45#include <linux/config.h>···50static u8* pci_to_OF_bus_map;51#endif5253+/* By default, we don't re-assign bus numbers.054 */55int pci_assign_all_buses;56···780 return NULL;781782 /* Fixup bus number according to what OF think it is. */00000000000783 if (pci_to_OF_bus_map)784 busnr = pci_to_OF_bus_map[busnr];785 if (busnr == 0xff)···1040}104110420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001043static int __init1044pcibios_init(void)1045{···1290 pcibios_allocate_bus_resources(&pci_root_buses);1291 pcibios_allocate_resources(0);1292 pcibios_allocate_resources(1);0001293 pcibios_assign_resources();12941295 /* Call machine dependent post-init code */···1721{1722 struct pci_controller* hose;1723 long result = -EOPNOTSUPP;0000000000017241725 hose = pci_bus_to_hose(bus);1726 if (!hose)
···1/*2- * Common prep/pmac/chrp boot and setup code.3 */45#include <linux/config.h>···35#include <asm/machdep.h>36#include <asm/uaccess.h>37#include <asm/system.h>38-#include <asm/pmac_feature.h>39#include <asm/sections.h>40#include <asm/nvram.h>41#include <asm/xmon.h>···5455extern void platform_init(unsigned long r3, unsigned long r4,56 unsigned long r5, unsigned long r6, unsigned long r7);57-extern void bootx_init(unsigned long r4, unsigned long phys);58extern void identify_cpu(unsigned long offset, unsigned long cpu);59extern void do_cpu_ftr_fixups(unsigned long offset);60extern void reloc_got2(unsigned long offset);···77EXPORT_SYMBOL(_machine);7879extern void prep_init(unsigned long r3, unsigned long r4,80- unsigned long r5, unsigned long r6, unsigned long r7);81-extern void pmac_init(unsigned long r3, unsigned long r4,82 unsigned long r5, unsigned long r6, unsigned long r7);83extern void chrp_init(unsigned long r3, unsigned long r4,84 unsigned long r5, unsigned long r6, unsigned long r7);···320 identify_cpu(offset, 0);321 do_cpu_ftr_fixups(offset);322323-#if defined(CONFIG_PPC_MULTIPLATFORM)324 reloc_got2(offset);325-326- /* If we came here from BootX, clear the screen,327- * set up some pointers and return. */328- if ((r3 == 0x426f6f58) && (r5 == 0))329- bootx_init(r4, phys);330331 /*332 * don't do anything on prep333 * for now, don't use bootinfo because it breaks yaboot 0.5334 * and assume that if we didn't find a magic number, we have OF335 */336- else if (*(unsigned long *)(0) != 0xdeadc0de)337 phys = prom_init(r3, r4, (prom_entry)r5);338339 reloc_got2(-offset);···415 }416#endif4170418 have_of = 1;419420 /* prom_init has already been called from __start */···487#endif /* CONFIG_ADB */488489 switch (_machine) {490-#ifdef CONFIG_PPC_PMAC491- case _MACH_Pmac:492- pmac_init(r3, r4, r5, r6, r7);493- break;494-#endif495#ifdef CONFIG_PPC_CHRP496 case _MACH_chrp:497 chrp_init(r3, r4, r5, r6, r7);498 break;499#endif500 }0501}05020503#ifdef CONFIG_SERIAL_CORE_CONSOLE504extern char *of_stdout_device;505···554}555console_initcall(set_preferred_console);556#endif /* CONFIG_SERIAL_CORE_CONSOLE */557-#endif /* CONFIG_PPC_MULTIPLATFORM */558559struct bi_record *find_bootinfo(void)560{···736737 if (ppc_md.init_early)738 ppc_md.init_early();739-740-#ifdef CONFIG_PPC_MULTIPLATFORM741- /* This could be called "early setup arch", it must be done742- * now because xmon need it743- */744- if (_machine == _MACH_Pmac)745- pmac_feature_init(); /* New cool way */746-#endif747748#ifdef CONFIG_XMON749 xmon_init(1);
···1/*2+ * Common prep/chrp boot and setup code.3 */45#include <linux/config.h>···35#include <asm/machdep.h>36#include <asm/uaccess.h>37#include <asm/system.h>038#include <asm/sections.h>39#include <asm/nvram.h>40#include <asm/xmon.h>···5556extern void platform_init(unsigned long r3, unsigned long r4,57 unsigned long r5, unsigned long r6, unsigned long r7);058extern void identify_cpu(unsigned long offset, unsigned long cpu);59extern void do_cpu_ftr_fixups(unsigned long offset);60extern void reloc_got2(unsigned long offset);···79EXPORT_SYMBOL(_machine);8081extern void prep_init(unsigned long r3, unsigned long r4,0082 unsigned long r5, unsigned long r6, unsigned long r7);83extern void chrp_init(unsigned long r3, unsigned long r4,84 unsigned long r5, unsigned long r6, unsigned long r7);···324 identify_cpu(offset, 0);325 do_cpu_ftr_fixups(offset);326327+#if defined(CONFIG_PPC_OF)328 reloc_got2(offset);00000329330 /*331 * don't do anything on prep332 * for now, don't use bootinfo because it breaks yaboot 0.5333 * and assume that if we didn't find a magic number, we have OF334 */335+ if (*(unsigned long *)(0) != 0xdeadc0de)336 phys = prom_init(r3, r4, (prom_entry)r5);337338 reloc_got2(-offset);···424 }425#endif426427+#ifdef CONFIG_PPC_OF428 have_of = 1;429430 /* prom_init has already been called from __start */···495#endif /* CONFIG_ADB */496497 switch (_machine) {00000498#ifdef CONFIG_PPC_CHRP499 case _MACH_chrp:500 chrp_init(r3, r4, r5, r6, r7);501 break;502#endif503 }504+#endif /* CONFIG_PPC_OF */505}506+#endif /* CONFIG_PPC_MULTIPLATFORM */507508+#ifdef CONFIG_PPC_OF509#ifdef CONFIG_SERIAL_CORE_CONSOLE510extern char *of_stdout_device;511···564}565console_initcall(set_preferred_console);566#endif /* CONFIG_SERIAL_CORE_CONSOLE */567+#endif /* CONFIG_PPC_OF */568569struct bi_record *find_bootinfo(void)570{···746747 if (ppc_md.init_early)748 ppc_md.init_early();00000000749750#ifdef CONFIG_XMON751 xmon_init(1);
+2-11
arch/ppc/kernel/traps.c
···38#include <asm/io.h>39#include <asm/reg.h>40#include <asm/xmon.h>41-#ifdef CONFIG_PMAC_BACKLIGHT42-#include <asm/backlight.h>43-#endif44#include <asm/pmc.h>4546#ifdef CONFIG_XMON···82 int nl = 0;83 console_verbose();84 spin_lock_irq(&die_lock);85-#ifdef CONFIG_PMAC_BACKLIGHT86- if (_machine == _MACH_Pmac) {87- set_backlight_enable(1);88- set_backlight_level(BACKLIGHT_MAX);89- }90-#endif91 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);92#ifdef CONFIG_PREEMPT93 printk("PREEMPT ");···150 */151static inline int check_io_access(struct pt_regs *regs)152{153-#if defined CONFIG_PPC_PMAC || defined CONFIG_8xx154 unsigned long msr = regs->msr;155 const struct exception_table_entry *entry;156 unsigned int *nip = (unsigned int *)regs->nip;···187 return 1;188 }189 }190-#endif /* CONFIG_PPC_PMAC */191 return 0;192}193
···38#include <asm/io.h>39#include <asm/reg.h>40#include <asm/xmon.h>00041#include <asm/pmc.h>4243#ifdef CONFIG_XMON···85 int nl = 0;86 console_verbose();87 spin_lock_irq(&die_lock);00000088 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);89#ifdef CONFIG_PREEMPT90 printk("PREEMPT ");···159 */160static inline int check_io_access(struct pt_regs *regs)161{162+#if defined CONFIG_8xx163 unsigned long msr = regs->msr;164 const struct exception_table_entry *entry;165 unsigned int *nip = (unsigned int *)regs->nip;···196 return 1;197 }198 }199+#endif /* CONFIG_8xx */200 return 0;201}202
-29
arch/ppc/mm/init.c
···67int mem_init_done;68int init_bootmem_done;69int boot_mapsize;70-#ifdef CONFIG_PPC_PMAC71-unsigned long agp_special_page;72-EXPORT_SYMBOL(agp_special_page);73-#endif7475extern char _end[];76extern char etext[], _stext[];···420 addr += PAGE_SIZE)421 SetPageReserved(virt_to_page(addr));422#endif423-#ifdef CONFIG_PPC_PMAC424- if (agp_special_page)425- SetPageReserved(virt_to_page(agp_special_page));426-#endif427 for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;428 addr += PAGE_SIZE) {429 if (!PageReserved(virt_to_page(addr)))···454 codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),455 initpages<< (PAGE_SHIFT-10),456 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));457-458-#ifdef CONFIG_PPC_PMAC459- if (agp_special_page)460- printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page);461-#endif462463 mem_init_done = 1;464}···499 if (rtas_data)500 mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);501#endif502-#ifdef CONFIG_PPC_PMAC503- /* Because of some uninorth weirdness, we need a page of504- * memory as high as possible (it must be outside of the505- * bus address seen as the AGP aperture). It will be used506- * by the r128 DRM driver507- *508- * FIXME: We need to make sure that page doesn't overlap any of the\509- * above. This could be done by improving mem_pieces_find to be able510- * to do a backward search from the end of the list.511- */512- if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) {513- agp_special_page = (total_memory - PAGE_SIZE);514- mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);515- agp_special_page = (unsigned long)__va(agp_special_page);516- }517-#endif /* CONFIG_PPC_PMAC */518}519520/* Mark some memory as reserved by removing it from phys_avail. */
···67int mem_init_done;68int init_bootmem_done;69int boot_mapsize;00007071extern char _end[];72extern char etext[], _stext[];···424 addr += PAGE_SIZE)425 SetPageReserved(virt_to_page(addr));426#endif0000427 for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;428 addr += PAGE_SIZE) {429 if (!PageReserved(virt_to_page(addr)))···462 codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),463 initpages<< (PAGE_SHIFT-10),464 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));00000465466 mem_init_done = 1;467}···512 if (rtas_data)513 mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);514#endif0000000000000000515}516517/* Mark some memory as reserved by removing it from phys_avail. */
···53#include <asm/i8259.h>54#include <asm/open_pic.h>55#include <asm/xmon.h>05657unsigned long chrp_get_rtc_time(void);58int chrp_set_rtc_time(unsigned long nowtime);···66void rtas_indicator_progress(char *, unsigned short);67void btext_progress(char *, unsigned short);6869-extern unsigned long pmac_find_end_of_memory(void);70extern int of_show_percpuinfo(struct seq_file *, int);7172int _chrp_type;···467 ppc_md.progress(" Have fun! ", 0x7777);468}469000000000000000000000000000000000000000000000000000000000000000000000470void __init471chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,472 unsigned long r6, unsigned long r7)···594 ppc_md.get_rtc_time = chrp_get_rtc_time;595 ppc_md.calibrate_decr = chrp_calibrate_decr;596597- ppc_md.find_end_of_memory = pmac_find_end_of_memory;598599 if (rtas_data) {600 struct device_node *rtas;
···53#include <asm/i8259.h>54#include <asm/open_pic.h>55#include <asm/xmon.h>56+#include "mem_pieces.h"5758unsigned long chrp_get_rtc_time(void);59int chrp_set_rtc_time(unsigned long nowtime);···65void rtas_indicator_progress(char *, unsigned short);66void btext_progress(char *, unsigned short);67068extern int of_show_percpuinfo(struct seq_file *, int);6970int _chrp_type;···467 ppc_md.progress(" Have fun! ", 0x7777);468}469470+static struct device_node *memory_node;471+472+static int __init get_mem_prop(char *name, struct mem_pieces *mp)473+{474+ struct reg_property *rp;475+ int i, s;476+ unsigned int *ip;477+ int nac = prom_n_addr_cells(memory_node);478+ int nsc = prom_n_size_cells(memory_node);479+480+ ip = (unsigned int *) get_property(memory_node, name, &s);481+ if (ip == NULL) {482+ printk(KERN_ERR "error: couldn't get %s property on /memory\n",483+ name);484+ return 0;485+ }486+ s /= (nsc + nac) * 4;487+ rp = mp->regions;488+ for (i = 0; i < s; ++i, ip += nac+nsc) {489+ if (nac >= 2 && ip[nac-2] != 0)490+ continue;491+ rp->address = ip[nac-1];492+ if (nsc >= 2 && ip[nac+nsc-2] != 0)493+ rp->size = ~0U;494+ else495+ rp->size = ip[nac+nsc-1];496+ ++rp;497+ }498+ mp->n_regions = rp - mp->regions;499+500+ /* Make sure the pieces are sorted. */501+ mem_pieces_sort(mp);502+ mem_pieces_coalesce(mp);503+ return 1;504+}505+506+static unsigned long __init chrp_find_end_of_memory(void)507+{508+ unsigned long a, total;509+ struct mem_pieces phys_mem;510+511+ /*512+ * Find out where physical memory is, and check that it513+ * starts at 0 and is contiguous. It seems that RAM is514+ * always physically contiguous on Power Macintoshes.515+ *516+ * Supporting discontiguous physical memory isn't hard,517+ * it just makes the virtual <-> physical mapping functions518+ * more complicated (or else you end up wasting space519+ * in mem_map).520+ */521+ memory_node = find_devices("memory");522+ if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)523+ || phys_mem.n_regions == 0)524+ panic("No RAM??");525+ a = phys_mem.regions[0].address;526+ if (a != 0)527+ panic("RAM doesn't start at physical address 0");528+ total = phys_mem.regions[0].size;529+530+ if (phys_mem.n_regions > 1) {531+ printk("RAM starting at 0x%x is not contiguous\n",532+ phys_mem.regions[1].address);533+ printk("Using RAM from 0 to 0x%lx\n", total-1);534+ }535+536+ return total;537+}538+539void __init540chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,541 unsigned long r6, unsigned long r7)···525 ppc_md.get_rtc_time = chrp_get_rtc_time;526 ppc_md.calibrate_decr = chrp_calibrate_decr;527528+ ppc_md.find_end_of_memory = chrp_find_end_of_memory;529530 if (rtas_data) {531 struct device_node *rtas;
···1-/*2- * This file contains low-level cache management functions3- * used for sleep and CPU speed changes on Apple machines.4- * (In fact the only thing that is Apple-specific is that we assume5- * that we can read from ROM at physical address 0xfff00000.)6- *7- * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and8- * Benjamin Herrenschmidt (benh@kernel.crashing.org)9- *10- * This program is free software; you can redistribute it and/or11- * modify it under the terms of the GNU General Public License12- * as published by the Free Software Foundation; either version13- * 2 of the License, or (at your option) any later version.14- *15- */16-17-#include <linux/config.h>18-#include <asm/processor.h>19-#include <asm/ppc_asm.h>20-#include <asm/cputable.h>21-22-/*23- * Flush and disable all data caches (dL1, L2, L3). This is used24- * when going to sleep, when doing a PMU based cpufreq transition,25- * or when "offlining" a CPU on SMP machines. This code is over26- * paranoid, but I've had enough issues with various CPU revs and27- * bugs that I decided it was worth beeing over cautious28- */29-30-_GLOBAL(flush_disable_caches)31-#ifndef CONFIG_6xx32- blr33-#else34-BEGIN_FTR_SECTION35- b flush_disable_745x36-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)37-BEGIN_FTR_SECTION38- b flush_disable_75x39-END_FTR_SECTION_IFSET(CPU_FTR_L2CR)40- b __flush_disable_L141-42-/* This is the code for G3 and 74[01]0 */43-flush_disable_75x:44- mflr r1045-46- /* Turn off EE and DR in MSR */47- mfmsr r1148- rlwinm r0,r11,0,~MSR_EE49- rlwinm r0,r0,0,~MSR_DR50- sync51- mtmsr r052- isync53-54- /* Stop DST streams */55-BEGIN_FTR_SECTION56- DSSALL57- sync58-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)59-60- /* Stop DPM */61- mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */62- rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */63- sync64- mtspr SPRN_HID0,r4 /* Disable DPM */65- sync66-67- /* Disp-flush L1. We have a weird problem here that I never68- * totally figured out. On 750FX, using the ROM for the flush69- * results in a non-working flush. We use that workaround for70- * now until I finally understand what's going on. --BenH71- */72-73- /* ROM base by default */74- lis r4,0xfff075- mfpvr r376- srwi r3,r3,1677- cmplwi cr0,r3,0x700078- bne+ 1f79- /* RAM base on 750FX */80- li r4,081-1: li r4,0x400082- mtctr r483-1: lwz r0,0(r4)84- addi r4,r4,3285- bdnz 1b86- sync87- isync88-89- /* Disable / invalidate / enable L1 data */90- mfspr r3,SPRN_HID091- rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)92- mtspr SPRN_HID0,r393- sync94- isync95- ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)96- sync97- isync98- mtspr SPRN_HID0,r399- xori r3,r3,(HID0_DCI|HID0_ICFI)100- mtspr SPRN_HID0,r3101- sync102-103- /* Get the current enable bit of the L2CR into r4 */104- mfspr r5,SPRN_L2CR105- /* Set to data-only (pre-745x bit) */106- oris r3,r5,L2CR_L2DO@h107- b 2f108- /* When disabling L2, code must be in L1 */109- .balign 32110-1: mtspr SPRN_L2CR,r3111-3: sync112- isync113- b 1f114-2: b 3f115-3: sync116- isync117- b 1b118-1: /* disp-flush L2. The interesting thing here is that the L2 can be119- * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory120- * but that is probbaly fine. We disp-flush over 4Mb to be safe121- */122- lis r4,2123- mtctr r4124- lis r4,0xfff0125-1: lwz r0,0(r4)126- addi r4,r4,32127- bdnz 1b128- sync129- isync130- lis r4,2131- mtctr r4132- lis r4,0xfff0133-1: dcbf 0,r4134- addi r4,r4,32135- bdnz 1b136- sync137- isync138-139- /* now disable L2 */140- rlwinm r5,r5,0,~L2CR_L2E141- b 2f142- /* When disabling L2, code must be in L1 */143- .balign 32144-1: mtspr SPRN_L2CR,r5145-3: sync146- isync147- b 1f148-2: b 3f149-3: sync150- isync151- b 1b152-1: sync153- isync154- /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */155- oris r4,r5,L2CR_L2I@h156- mtspr SPRN_L2CR,r4157- sync158- isync159-160- /* Wait for the invalidation to complete */161-1: mfspr r3,SPRN_L2CR162- rlwinm. r0,r3,0,31,31163- bne 1b164-165- /* Clear L2I */166- xoris r4,r4,L2CR_L2I@h167- sync168- mtspr SPRN_L2CR,r4169- sync170-171- /* now disable the L1 data cache */172- mfspr r0,SPRN_HID0173- rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)174- mtspr SPRN_HID0,r0175- sync176- isync177-178- /* Restore HID0[DPM] to whatever it was before */179- sync180- mfspr r0,SPRN_HID0181- rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */182- mtspr SPRN_HID0,r0183- sync184-185- /* restore DR and EE */186- sync187- mtmsr r11188- isync189-190- mtlr r10191- blr192-193-/* This code is for 745x processors */194-flush_disable_745x:195- /* Turn off EE and DR in MSR */196- mfmsr r11197- rlwinm r0,r11,0,~MSR_EE198- rlwinm r0,r0,0,~MSR_DR199- sync200- mtmsr r0201- isync202-203- /* Stop prefetch streams */204- DSSALL205- sync206-207- /* Disable L2 prefetching */208- mfspr r0,SPRN_MSSCR0209- rlwinm r0,r0,0,0,29210- mtspr SPRN_MSSCR0,r0211- sync212- isync213- lis r4,0214- dcbf 0,r4215- dcbf 0,r4216- dcbf 0,r4217- dcbf 0,r4218- dcbf 0,r4219- dcbf 0,r4220- dcbf 0,r4221- dcbf 0,r4222-223- /* Due to a bug with the HW flush on some CPU revs, we occasionally224- * experience data corruption. I'm adding a displacement flush along225- * with a dcbf loop over a few Mb to "help". The problem isn't totally226- * fixed by this in theory, but at least, in practice, I couldn't reproduce227- * it even with a big hammer...228- */229-230- lis r4,0x0002231- mtctr r4232- li r4,0233-1:234- lwz r0,0(r4)235- addi r4,r4,32 /* Go to start of next cache line */236- bdnz 1b237- isync238-239- /* Now, flush the first 4MB of memory */240- lis r4,0x0002241- mtctr r4242- li r4,0243- sync244-1:245- dcbf 0,r4246- addi r4,r4,32 /* Go to start of next cache line */247- bdnz 1b248-249- /* Flush and disable the L1 data cache */250- mfspr r6,SPRN_LDSTCR251- lis r3,0xfff0 /* read from ROM for displacement flush */252- li r4,0xfe /* start with only way 0 unlocked */253- li r5,128 /* 128 lines in each way */254-1: mtctr r5255- rlwimi r6,r4,0,24,31256- mtspr SPRN_LDSTCR,r6257- sync258- isync259-2: lwz r0,0(r3) /* touch each cache line */260- addi r3,r3,32261- bdnz 2b262- rlwinm r4,r4,1,24,30 /* move on to the next way */263- ori r4,r4,1264- cmpwi r4,0xff /* all done? */265- bne 1b266- /* now unlock the L1 data cache */267- li r4,0268- rlwimi r6,r4,0,24,31269- sync270- mtspr SPRN_LDSTCR,r6271- sync272- isync273-274- /* Flush the L2 cache using the hardware assist */275- mfspr r3,SPRN_L2CR276- cmpwi r3,0 /* check if it is enabled first */277- bge 4f278- oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h279- b 2f280- /* When disabling/locking L2, code must be in L1 */281- .balign 32282-1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */283-3: sync284- isync285- b 1f286-2: b 3f287-3: sync288- isync289- b 1b290-1: sync291- isync292- ori r0,r3,L2CR_L2HWF_745x293- sync294- mtspr SPRN_L2CR,r0 /* set the hardware flush bit */295-3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */296- andi. r0,r0,L2CR_L2HWF_745x297- bne 3b298- sync299- rlwinm r3,r3,0,~L2CR_L2E300- b 2f301- /* When disabling L2, code must be in L1 */302- .balign 32303-1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */304-3: sync305- isync306- b 1f307-2: b 3f308-3: sync309- isync310- b 1b311-1: sync312- isync313- oris r4,r3,L2CR_L2I@h314- mtspr SPRN_L2CR,r4315- sync316- isync317-1: mfspr r4,SPRN_L2CR318- andis. r0,r4,L2CR_L2I@h319- bne 1b320- sync321-322-BEGIN_FTR_SECTION323- /* Flush the L3 cache using the hardware assist */324-4: mfspr r3,SPRN_L3CR325- cmpwi r3,0 /* check if it is enabled */326- bge 6f327- oris r0,r3,L3CR_L3IO@h328- ori r0,r0,L3CR_L3DO329- sync330- mtspr SPRN_L3CR,r0 /* lock the L3 cache */331- sync332- isync333- ori r0,r0,L3CR_L3HWF334- sync335- mtspr SPRN_L3CR,r0 /* set the hardware flush bit */336-5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */337- andi. r0,r0,L3CR_L3HWF338- bne 5b339- rlwinm r3,r3,0,~L3CR_L3E340- sync341- mtspr SPRN_L3CR,r3 /* disable the L3 cache */342- sync343- ori r4,r3,L3CR_L3I344- mtspr SPRN_L3CR,r4345-1: mfspr r4,SPRN_L3CR346- andi. r0,r4,L3CR_L3I347- bne 1b348- sync349-END_FTR_SECTION_IFSET(CPU_FTR_L3CR)350-351-6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */352- rlwinm r0,r0,0,~HID0_DCE353- mtspr SPRN_HID0,r0354- sync355- isync356- mtmsr r11 /* restore DR and EE */357- isync358- blr359-#endif /* CONFIG_6xx */
···1-/*2- * arch/ppc/platforms/pmac_cpufreq.c3- *4- * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>5- * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>6- *7- * This program is free software; you can redistribute it and/or modify8- * it under the terms of the GNU General Public License version 2 as9- * published by the Free Software Foundation.10- *11- * TODO: Need a big cleanup here. Basically, we need to have different12- * cpufreq_driver structures for the different type of HW instead of the13- * current mess. We also need to better deal with the detection of the14- * type of machine.15- *16- */17-18-#include <linux/config.h>19-#include <linux/module.h>20-#include <linux/types.h>21-#include <linux/errno.h>22-#include <linux/kernel.h>23-#include <linux/delay.h>24-#include <linux/sched.h>25-#include <linux/adb.h>26-#include <linux/pmu.h>27-#include <linux/slab.h>28-#include <linux/cpufreq.h>29-#include <linux/init.h>30-#include <linux/sysdev.h>31-#include <linux/i2c.h>32-#include <linux/hardirq.h>33-#include <asm/prom.h>34-#include <asm/machdep.h>35-#include <asm/irq.h>36-#include <asm/pmac_feature.h>37-#include <asm/mmu_context.h>38-#include <asm/sections.h>39-#include <asm/cputable.h>40-#include <asm/time.h>41-#include <asm/system.h>42-#include <asm/open_pic.h>43-#include <asm/keylargo.h>44-45-/* WARNING !!! This will cause calibrate_delay() to be called,46- * but this is an __init function ! So you MUST go edit47- * init/main.c to make it non-init before enabling DEBUG_FREQ48- */49-#undef DEBUG_FREQ50-51-/*52- * There is a problem with the core cpufreq code on SMP kernels,53- * it won't recalculate the Bogomips properly54- */55-#ifdef CONFIG_SMP56-#warning "WARNING, CPUFREQ not recommended on SMP kernels"57-#endif58-59-extern void low_choose_7447a_dfs(int dfs);60-extern void low_choose_750fx_pll(int pll);61-extern void low_sleep_handler(void);62-63-/*64- * Currently, PowerMac cpufreq supports only high & low frequencies65- * that are set by the firmware66- */67-static unsigned int low_freq;68-static unsigned int hi_freq;69-static unsigned int cur_freq;70-static unsigned int sleep_freq;71-72-/*73- * Different models uses different mecanisms to switch the frequency74- */75-static int (*set_speed_proc)(int low_speed);76-static unsigned int (*get_speed_proc)(void);77-78-/*79- * Some definitions used by the various speedprocs80- */81-static u32 voltage_gpio;82-static u32 frequency_gpio;83-static u32 slew_done_gpio;84-static int no_schedule;85-static int has_cpu_l2lve;86-static int is_pmu_based;87-88-/* There are only two frequency states for each processor. Values89- * are in kHz for the time being.90- */91-#define CPUFREQ_HIGH 092-#define CPUFREQ_LOW 193-94-static struct cpufreq_frequency_table pmac_cpu_freqs[] = {95- {CPUFREQ_HIGH, 0},96- {CPUFREQ_LOW, 0},97- {0, CPUFREQ_TABLE_END},98-};99-100-static struct freq_attr* pmac_cpu_freqs_attr[] = {101- &cpufreq_freq_attr_scaling_available_freqs,102- NULL,103-};104-105-static inline void local_delay(unsigned long ms)106-{107- if (no_schedule)108- mdelay(ms);109- else110- msleep(ms);111-}112-113-static inline void wakeup_decrementer(void)114-{115- set_dec(tb_ticks_per_jiffy);116- /* No currently-supported powerbook has a 601,117- * so use get_tbl, not native118- */119- last_jiffy_stamp(0) = tb_last_stamp = get_tbl();120-}121-122-#ifdef DEBUG_FREQ123-static inline void debug_calc_bogomips(void)124-{125- /* This will cause a recalc of bogomips and display the126- * result. We backup/restore the value to avoid affecting the127- * core cpufreq framework's own calculation.128- */129- extern void calibrate_delay(void);130-131- unsigned long save_lpj = loops_per_jiffy;132- calibrate_delay();133- loops_per_jiffy = save_lpj;134-}135-#endif /* DEBUG_FREQ */136-137-/* Switch CPU speed under 750FX CPU control138- */139-static int cpu_750fx_cpu_speed(int low_speed)140-{141- u32 hid2;142-143- if (low_speed == 0) {144- /* ramping up, set voltage first */145- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);146- /* Make sure we sleep for at least 1ms */147- local_delay(10);148-149- /* tweak L2 for high voltage */150- if (has_cpu_l2lve) {151- hid2 = mfspr(SPRN_HID2);152- hid2 &= ~0x2000;153- mtspr(SPRN_HID2, hid2);154- }155- }156-#ifdef CONFIG_6xx157- low_choose_750fx_pll(low_speed);158-#endif159- if (low_speed == 1) {160- /* tweak L2 for low voltage */161- if (has_cpu_l2lve) {162- hid2 = mfspr(SPRN_HID2);163- hid2 |= 0x2000;164- mtspr(SPRN_HID2, hid2);165- }166-167- /* ramping down, set voltage last */168- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);169- local_delay(10);170- }171-172- return 0;173-}174-175-static unsigned int cpu_750fx_get_cpu_speed(void)176-{177- if (mfspr(SPRN_HID1) & HID1_PS)178- return low_freq;179- else180- return hi_freq;181-}182-183-/* Switch CPU speed using DFS */184-static int dfs_set_cpu_speed(int low_speed)185-{186- if (low_speed == 0) {187- /* ramping up, set voltage first */188- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);189- /* Make sure we sleep for at least 1ms */190- local_delay(1);191- }192-193- /* set frequency */194-#ifdef CONFIG_6xx195- low_choose_7447a_dfs(low_speed);196-#endif197- udelay(100);198-199- if (low_speed == 1) {200- /* ramping down, set voltage last */201- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);202- local_delay(1);203- }204-205- return 0;206-}207-208-static unsigned int dfs_get_cpu_speed(void)209-{210- if (mfspr(SPRN_HID1) & HID1_DFS)211- return low_freq;212- else213- return hi_freq;214-}215-216-217-/* Switch CPU speed using slewing GPIOs218- */219-static int gpios_set_cpu_speed(int low_speed)220-{221- int gpio, timeout = 0;222-223- /* If ramping up, set voltage first */224- if (low_speed == 0) {225- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);226- /* Delay is way too big but it's ok, we schedule */227- local_delay(10);228- }229-230- /* Set frequency */231- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);232- if (low_speed == ((gpio & 0x01) == 0))233- goto skip;234-235- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,236- low_speed ? 0x04 : 0x05);237- udelay(200);238- do {239- if (++timeout > 100)240- break;241- local_delay(1);242- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);243- } while((gpio & 0x02) == 0);244- skip:245- /* If ramping down, set voltage last */246- if (low_speed == 1) {247- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);248- /* Delay is way too big but it's ok, we schedule */249- local_delay(10);250- }251-252-#ifdef DEBUG_FREQ253- debug_calc_bogomips();254-#endif255-256- return 0;257-}258-259-/* Switch CPU speed under PMU control260- */261-static int pmu_set_cpu_speed(int low_speed)262-{263- struct adb_request req;264- unsigned long save_l2cr;265- unsigned long save_l3cr;266- unsigned int pic_prio;267- unsigned long flags;268-269- preempt_disable();270-271-#ifdef DEBUG_FREQ272- printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));273-#endif274- pmu_suspend();275-276- /* Disable all interrupt sources on openpic */277- pic_prio = openpic_get_priority();278- openpic_set_priority(0xf);279-280- /* Make sure the decrementer won't interrupt us */281- asm volatile("mtdec %0" : : "r" (0x7fffffff));282- /* Make sure any pending DEC interrupt occuring while we did283- * the above didn't re-enable the DEC */284- mb();285- asm volatile("mtdec %0" : : "r" (0x7fffffff));286-287- /* We can now disable MSR_EE */288- local_irq_save(flags);289-290- /* Giveup the FPU & vec */291- enable_kernel_fp();292-293-#ifdef CONFIG_ALTIVEC294- if (cpu_has_feature(CPU_FTR_ALTIVEC))295- enable_kernel_altivec();296-#endif /* CONFIG_ALTIVEC */297-298- /* Save & disable L2 and L3 caches */299- save_l3cr = _get_L3CR(); /* (returns -1 if not available) */300- save_l2cr = _get_L2CR(); /* (returns -1 if not available) */301-302- /* Send the new speed command. My assumption is that this command303- * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep304- */305- pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);306- while (!req.complete)307- pmu_poll();308-309- /* Prepare the northbridge for the speed transition */310- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);311-312- /* Call low level code to backup CPU state and recover from313- * hardware reset314- */315- low_sleep_handler();316-317- /* Restore the northbridge */318- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);319-320- /* Restore L2 cache */321- if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)322- _set_L2CR(save_l2cr);323- /* Restore L3 cache */324- if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)325- _set_L3CR(save_l3cr);326-327- /* Restore userland MMU context */328- set_context(current->active_mm->context, current->active_mm->pgd);329-330-#ifdef DEBUG_FREQ331- printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));332-#endif333-334- /* Restore low level PMU operations */335- pmu_unlock();336-337- /* Restore decrementer */338- wakeup_decrementer();339-340- /* Restore interrupts */341- openpic_set_priority(pic_prio);342-343- /* Let interrupts flow again ... */344- local_irq_restore(flags);345-346-#ifdef DEBUG_FREQ347- debug_calc_bogomips();348-#endif349-350- pmu_resume();351-352- preempt_enable();353-354- return 0;355-}356-357-static int do_set_cpu_speed(int speed_mode, int notify)358-{359- struct cpufreq_freqs freqs;360- unsigned long l3cr;361- static unsigned long prev_l3cr;362-363- freqs.old = cur_freq;364- freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;365- freqs.cpu = smp_processor_id();366-367- if (freqs.old == freqs.new)368- return 0;369-370- if (notify)371- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);372- if (speed_mode == CPUFREQ_LOW &&373- cpu_has_feature(CPU_FTR_L3CR)) {374- l3cr = _get_L3CR();375- if (l3cr & L3CR_L3E) {376- prev_l3cr = l3cr;377- _set_L3CR(0);378- }379- }380- set_speed_proc(speed_mode == CPUFREQ_LOW);381- if (speed_mode == CPUFREQ_HIGH &&382- cpu_has_feature(CPU_FTR_L3CR)) {383- l3cr = _get_L3CR();384- if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)385- _set_L3CR(prev_l3cr);386- }387- if (notify)388- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);389- cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;390-391- return 0;392-}393-394-static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)395-{396- return cur_freq;397-}398-399-static int pmac_cpufreq_verify(struct cpufreq_policy *policy)400-{401- return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);402-}403-404-static int pmac_cpufreq_target( struct cpufreq_policy *policy,405- unsigned int target_freq,406- unsigned int relation)407-{408- unsigned int newstate = 0;409-410- if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,411- target_freq, relation, &newstate))412- return -EINVAL;413-414- return do_set_cpu_speed(newstate, 1);415-}416-417-unsigned int pmac_get_one_cpufreq(int i)418-{419- /* Supports only one CPU for now */420- return (i == 0) ? cur_freq : 0;421-}422-423-static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)424-{425- if (policy->cpu != 0)426- return -ENODEV;427-428- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;429- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;430- policy->cur = cur_freq;431-432- cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);433- return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);434-}435-436-static u32 read_gpio(struct device_node *np)437-{438- u32 *reg = (u32 *)get_property(np, "reg", NULL);439- u32 offset;440-441- if (reg == NULL)442- return 0;443- /* That works for all keylargos but shall be fixed properly444- * some day... The problem is that it seems we can't rely445- * on the "reg" property of the GPIO nodes, they are either446- * relative to the base of KeyLargo or to the base of the447- * GPIO space, and the device-tree doesn't help.448- */449- offset = *reg;450- if (offset < KEYLARGO_GPIO_LEVELS0)451- offset += KEYLARGO_GPIO_LEVELS0;452- return offset;453-}454-455-static int pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)456-{457- /* Ok, this could be made a bit smarter, but let's be robust for now. We458- * always force a speed change to high speed before sleep, to make sure459- * we have appropriate voltage and/or bus speed for the wakeup process,460- * and to make sure our loops_per_jiffies are "good enough", that is will461- * not cause too short delays if we sleep in low speed and wake in high462- * speed..463- */464- no_schedule = 1;465- sleep_freq = cur_freq;466- if (cur_freq == low_freq && !is_pmu_based)467- do_set_cpu_speed(CPUFREQ_HIGH, 0);468- return 0;469-}470-471-static int pmac_cpufreq_resume(struct cpufreq_policy *policy)472-{473- /* If we resume, first check if we have a get() function */474- if (get_speed_proc)475- cur_freq = get_speed_proc();476- else477- cur_freq = 0;478-479- /* We don't, hrm... we don't really know our speed here, best480- * is that we force a switch to whatever it was, which is481- * probably high speed due to our suspend() routine482- */483- do_set_cpu_speed(sleep_freq == low_freq ?484- CPUFREQ_LOW : CPUFREQ_HIGH, 0);485-486- no_schedule = 0;487- return 0;488-}489-490-static struct cpufreq_driver pmac_cpufreq_driver = {491- .verify = pmac_cpufreq_verify,492- .target = pmac_cpufreq_target,493- .get = pmac_cpufreq_get_speed,494- .init = pmac_cpufreq_cpu_init,495- .suspend = pmac_cpufreq_suspend,496- .resume = pmac_cpufreq_resume,497- .flags = CPUFREQ_PM_NO_WARN,498- .attr = pmac_cpu_freqs_attr,499- .name = "powermac",500- .owner = THIS_MODULE,501-};502-503-504-static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)505-{506- struct device_node *volt_gpio_np = of_find_node_by_name(NULL,507- "voltage-gpio");508- struct device_node *freq_gpio_np = of_find_node_by_name(NULL,509- "frequency-gpio");510- struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,511- "slewing-done");512- u32 *value;513-514- /*515- * Check to see if it's GPIO driven or PMU only516- *517- * The way we extract the GPIO address is slightly hackish, but it518- * works well enough for now. We need to abstract the whole GPIO519- * stuff sooner or later anyway520- */521-522- if (volt_gpio_np)523- voltage_gpio = read_gpio(volt_gpio_np);524- if (freq_gpio_np)525- frequency_gpio = read_gpio(freq_gpio_np);526- if (slew_done_gpio_np)527- slew_done_gpio = read_gpio(slew_done_gpio_np);528-529- /* If we use the frequency GPIOs, calculate the min/max speeds based530- * on the bus frequencies531- */532- if (frequency_gpio && slew_done_gpio) {533- int lenp, rc;534- u32 *freqs, *ratio;535-536- freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);537- lenp /= sizeof(u32);538- if (freqs == NULL || lenp != 2) {539- printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");540- return 1;541- }542- ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);543- if (ratio == NULL) {544- printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");545- return 1;546- }547-548- /* Get the min/max bus frequencies */549- low_freq = min(freqs[0], freqs[1]);550- hi_freq = max(freqs[0], freqs[1]);551-552- /* Grrrr.. It _seems_ that the device-tree is lying on the low bus553- * frequency, it claims it to be around 84Mhz on some models while554- * it appears to be approx. 101Mhz on all. Let's hack around here...555- * fortunately, we don't need to be too precise556- */557- if (low_freq < 98000000)558- low_freq = 101000000;559-560- /* Convert those to CPU core clocks */561- low_freq = (low_freq * (*ratio)) / 2000;562- hi_freq = (hi_freq * (*ratio)) / 2000;563-564- /* Now we get the frequencies, we read the GPIO to see what is out current565- * speed566- */567- rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);568- cur_freq = (rc & 0x01) ? hi_freq : low_freq;569-570- set_speed_proc = gpios_set_cpu_speed;571- return 1;572- }573-574- /* If we use the PMU, look for the min & max frequencies in the575- * device-tree576- */577- value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);578- if (!value)579- return 1;580- low_freq = (*value) / 1000;581- /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree582- * here */583- if (low_freq < 100000)584- low_freq *= 10;585-586- value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);587- if (!value)588- return 1;589- hi_freq = (*value) / 1000;590- set_speed_proc = pmu_set_cpu_speed;591- is_pmu_based = 1;592-593- return 0;594-}595-596-static int pmac_cpufreq_init_7447A(struct device_node *cpunode)597-{598- struct device_node *volt_gpio_np;599-600- if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)601- return 1;602-603- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");604- if (volt_gpio_np)605- voltage_gpio = read_gpio(volt_gpio_np);606- if (!voltage_gpio){607- printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");608- return 1;609- }610-611- /* OF only reports the high frequency */612- hi_freq = cur_freq;613- low_freq = cur_freq/2;614-615- /* Read actual frequency from CPU */616- cur_freq = dfs_get_cpu_speed();617- set_speed_proc = dfs_set_cpu_speed;618- get_speed_proc = dfs_get_cpu_speed;619-620- return 0;621-}622-623-static int pmac_cpufreq_init_750FX(struct device_node *cpunode)624-{625- struct device_node *volt_gpio_np;626- u32 pvr, *value;627-628- if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)629- return 1;630-631- hi_freq = cur_freq;632- value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);633- if (!value)634- return 1;635- low_freq = (*value) / 1000;636-637- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");638- if (volt_gpio_np)639- voltage_gpio = read_gpio(volt_gpio_np);640-641- pvr = mfspr(SPRN_PVR);642- has_cpu_l2lve = !((pvr & 0xf00) == 0x100);643-644- set_speed_proc = cpu_750fx_cpu_speed;645- get_speed_proc = cpu_750fx_get_cpu_speed;646- cur_freq = cpu_750fx_get_cpu_speed();647-648- return 0;649-}650-651-/* Currently, we support the following machines:652- *653- * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)654- * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)655- * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)656- * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)657- * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)658- * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)659- * - Recent MacRISC3 laptops660- * - All new machines with 7447A CPUs661- */662-static int __init pmac_cpufreq_setup(void)663-{664- struct device_node *cpunode;665- u32 *value;666-667- if (strstr(cmd_line, "nocpufreq"))668- return 0;669-670- /* Assume only one CPU */671- cpunode = find_type_devices("cpu");672- if (!cpunode)673- goto out;674-675- /* Get current cpu clock freq */676- value = (u32 *)get_property(cpunode, "clock-frequency", NULL);677- if (!value)678- goto out;679- cur_freq = (*value) / 1000;680-681- /* Check for 7447A based MacRISC3 */682- if (machine_is_compatible("MacRISC3") &&683- get_property(cpunode, "dynamic-power-step", NULL) &&684- PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {685- pmac_cpufreq_init_7447A(cpunode);686- /* Check for other MacRISC3 machines */687- } else if (machine_is_compatible("PowerBook3,4") ||688- machine_is_compatible("PowerBook3,5") ||689- machine_is_compatible("MacRISC3")) {690- pmac_cpufreq_init_MacRISC3(cpunode);691- /* Else check for iBook2 500/600 */692- } else if (machine_is_compatible("PowerBook4,1")) {693- hi_freq = cur_freq;694- low_freq = 400000;695- set_speed_proc = pmu_set_cpu_speed;696- is_pmu_based = 1;697- }698- /* Else check for TiPb 550 */699- else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {700- hi_freq = cur_freq;701- low_freq = 500000;702- set_speed_proc = pmu_set_cpu_speed;703- is_pmu_based = 1;704- }705- /* Else check for TiPb 400 & 500 */706- else if (machine_is_compatible("PowerBook3,2")) {707- /* We only know about the 400 MHz and the 500Mhz model708- * they both have 300 MHz as low frequency709- */710- if (cur_freq < 350000 || cur_freq > 550000)711- goto out;712- hi_freq = cur_freq;713- low_freq = 300000;714- set_speed_proc = pmu_set_cpu_speed;715- is_pmu_based = 1;716- }717- /* Else check for 750FX */718- else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)719- pmac_cpufreq_init_750FX(cpunode);720-out:721- if (set_speed_proc == NULL)722- return -ENODEV;723-724- pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;725- pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;726-727- printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");728- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",729- low_freq/1000, hi_freq/1000, cur_freq/1000);730-731- return cpufreq_register_driver(&pmac_cpufreq_driver);732-}733-734-module_init(pmac_cpufreq_setup);735-
···1-/*2- * Support for PCI bridges found on Power Macintoshes.3- * At present the "bandit" and "chaos" bridges are supported.4- * Fortunately you access configuration space in the same5- * way with either bridge.6- *7- * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)8- *9- * This program is free software; you can redistribute it and/or10- * modify it under the terms of the GNU General Public License11- * as published by the Free Software Foundation; either version12- * 2 of the License, or (at your option) any later version.13- */14-15-#include <linux/kernel.h>16-#include <linux/pci.h>17-#include <linux/delay.h>18-#include <linux/string.h>19-#include <linux/init.h>20-21-#include <asm/sections.h>22-#include <asm/io.h>23-#include <asm/prom.h>24-#include <asm/pci-bridge.h>25-#include <asm/machdep.h>26-#include <asm/pmac_feature.h>27-28-#undef DEBUG29-30-#ifdef DEBUG31-#ifdef CONFIG_XMON32-extern void xmon_printf(const char *fmt, ...);33-#define DBG(x...) xmon_printf(x)34-#else35-#define DBG(x...) printk(x)36-#endif37-#else38-#define DBG(x...)39-#endif40-41-static int add_bridge(struct device_node *dev);42-extern void pmac_check_ht_link(void);43-44-/* XXX Could be per-controller, but I don't think we risk anything by45- * assuming we won't have both UniNorth and Bandit */46-static int has_uninorth;47-#ifdef CONFIG_POWER448-static struct pci_controller *u3_agp;49-#endif /* CONFIG_POWER4 */50-51-extern u8 pci_cache_line_size;52-extern int pcibios_assign_bus_offset;53-54-struct device_node *k2_skiplist[2];55-56-/*57- * Magic constants for enabling cache coherency in the bandit/PSX bridge.58- */59-#define BANDIT_DEVID_2 860-#define BANDIT_REVID 361-62-#define BANDIT_DEVNUM 1163-#define BANDIT_MAGIC 0x5064-#define BANDIT_COHERENT 0x4065-66-static int __init67-fixup_one_level_bus_range(struct device_node *node, int higher)68-{69- for (; node != 0;node = node->sibling) {70- int * bus_range;71- unsigned int *class_code;72- int len;73-74- /* For PCI<->PCI bridges or CardBus bridges, we go down */75- class_code = (unsigned int *) get_property(node, "class-code", NULL);76- if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&77- (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))78- continue;79- bus_range = (int *) get_property(node, "bus-range", &len);80- if (bus_range != NULL && len > 2 * sizeof(int)) {81- if (bus_range[1] > higher)82- higher = bus_range[1];83- }84- higher = fixup_one_level_bus_range(node->child, higher);85- }86- return higher;87-}88-89-/* This routine fixes the "bus-range" property of all bridges in the90- * system since they tend to have their "last" member wrong on macs91- *92- * Note that the bus numbers manipulated here are OF bus numbers, they93- * are not Linux bus numbers.94- */95-static void __init96-fixup_bus_range(struct device_node *bridge)97-{98- int * bus_range;99- int len;100-101- /* Lookup the "bus-range" property for the hose */102- bus_range = (int *) get_property(bridge, "bus-range", &len);103- if (bus_range == NULL || len < 2 * sizeof(int)) {104- printk(KERN_WARNING "Can't get bus-range for %s\n",105- bridge->full_name);106- return;107- }108- bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);109-}110-111-/*112- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.113- *114- * The "Bandit" version is present in all early PCI PowerMacs,115- * and up to the first ones using Grackle. Some machines may116- * have 2 bandit controllers (2 PCI busses).117- *118- * "Chaos" is used in some "Bandit"-type machines as a bridge119- * for the separate display bus. It is accessed the same120- * way as bandit, but cannot be probed for devices. It therefore121- * has its own config access functions.122- *123- * The "UniNorth" version is present in all Core99 machines124- * (iBook, G4, new IMacs, and all the recent Apple machines).125- * It contains 3 controllers in one ASIC.126- *127- * The U3 is the bridge used on G5 machines. It contains an128- * AGP bus which is dealt with the old UniNorth access routines129- * and a HyperTransport bus which uses its own set of access130- * functions.131- */132-133-#define MACRISC_CFA0(devfn, off) \134- ((1 << (unsigned long)PCI_SLOT(dev_fn)) \135- | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \136- | (((unsigned long)(off)) & 0xFCUL))137-138-#define MACRISC_CFA1(bus, devfn, off) \139- ((((unsigned long)(bus)) << 16) \140- |(((unsigned long)(devfn)) << 8) \141- |(((unsigned long)(off)) & 0xFCUL) \142- |1UL)143-144-static void volatile __iomem *145-macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)146-{147- unsigned int caddr;148-149- if (bus == hose->first_busno) {150- if (dev_fn < (11 << 3))151- return NULL;152- caddr = MACRISC_CFA0(dev_fn, offset);153- } else154- caddr = MACRISC_CFA1(bus, dev_fn, offset);155-156- /* Uninorth will return garbage if we don't read back the value ! */157- do {158- out_le32(hose->cfg_addr, caddr);159- } while (in_le32(hose->cfg_addr) != caddr);160-161- offset &= has_uninorth ? 0x07 : 0x03;162- return hose->cfg_data + offset;163-}164-165-static int166-macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,167- int len, u32 *val)168-{169- struct pci_controller *hose = bus->sysdata;170- void volatile __iomem *addr;171-172- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);173- if (!addr)174- return PCIBIOS_DEVICE_NOT_FOUND;175- /*176- * Note: the caller has already checked that offset is177- * suitably aligned and that len is 1, 2 or 4.178- */179- switch (len) {180- case 1:181- *val = in_8(addr);182- break;183- case 2:184- *val = in_le16(addr);185- break;186- default:187- *val = in_le32(addr);188- break;189- }190- return PCIBIOS_SUCCESSFUL;191-}192-193-static int194-macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,195- int len, u32 val)196-{197- struct pci_controller *hose = bus->sysdata;198- void volatile __iomem *addr;199-200- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);201- if (!addr)202- return PCIBIOS_DEVICE_NOT_FOUND;203- /*204- * Note: the caller has already checked that offset is205- * suitably aligned and that len is 1, 2 or 4.206- */207- switch (len) {208- case 1:209- out_8(addr, val);210- (void) in_8(addr);211- break;212- case 2:213- out_le16(addr, val);214- (void) in_le16(addr);215- break;216- default:217- out_le32(addr, val);218- (void) in_le32(addr);219- break;220- }221- return PCIBIOS_SUCCESSFUL;222-}223-224-static struct pci_ops macrisc_pci_ops =225-{226- macrisc_read_config,227- macrisc_write_config228-};229-230-/*231- * Verifiy that a specific (bus, dev_fn) exists on chaos232- */233-static int234-chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)235-{236- struct device_node *np;237- u32 *vendor, *device;238-239- np = pci_busdev_to_OF_node(bus, devfn);240- if (np == NULL)241- return PCIBIOS_DEVICE_NOT_FOUND;242-243- vendor = (u32 *)get_property(np, "vendor-id", NULL);244- device = (u32 *)get_property(np, "device-id", NULL);245- if (vendor == NULL || device == NULL)246- return PCIBIOS_DEVICE_NOT_FOUND;247-248- if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)249- && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))250- return PCIBIOS_BAD_REGISTER_NUMBER;251-252- return PCIBIOS_SUCCESSFUL;253-}254-255-static int256-chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,257- int len, u32 *val)258-{259- int result = chaos_validate_dev(bus, devfn, offset);260- if (result == PCIBIOS_BAD_REGISTER_NUMBER)261- *val = ~0U;262- if (result != PCIBIOS_SUCCESSFUL)263- return result;264- return macrisc_read_config(bus, devfn, offset, len, val);265-}266-267-static int268-chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,269- int len, u32 val)270-{271- int result = chaos_validate_dev(bus, devfn, offset);272- if (result != PCIBIOS_SUCCESSFUL)273- return result;274- return macrisc_write_config(bus, devfn, offset, len, val);275-}276-277-static struct pci_ops chaos_pci_ops =278-{279- chaos_read_config,280- chaos_write_config281-};282-283-#ifdef CONFIG_POWER4284-285-/*286- * These versions of U3 HyperTransport config space access ops do not287- * implement self-view of the HT host yet288- */289-290-#define U3_HT_CFA0(devfn, off) \291- ((((unsigned long)devfn) << 8) | offset)292-#define U3_HT_CFA1(bus, devfn, off) \293- (U3_HT_CFA0(devfn, off) \294- + (((unsigned long)bus) << 16) \295- + 0x01000000UL)296-297-static void volatile __iomem *298-u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)299-{300- if (bus == hose->first_busno) {301- /* For now, we don't self probe U3 HT bridge */302- if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||303- PCI_SLOT(devfn) < 1)304- return 0;305- return hose->cfg_data + U3_HT_CFA0(devfn, offset);306- } else307- return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);308-}309-310-static int311-u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,312- int len, u32 *val)313-{314- struct pci_controller *hose = bus->sysdata;315- void volatile __iomem *addr;316- int i;317-318- struct device_node *np = pci_busdev_to_OF_node(bus, devfn);319- if (np == NULL)320- return PCIBIOS_DEVICE_NOT_FOUND;321-322- /*323- * When a device in K2 is powered down, we die on config324- * cycle accesses. Fix that here.325- */326- for (i=0; i<2; i++)327- if (k2_skiplist[i] == np) {328- switch (len) {329- case 1:330- *val = 0xff; break;331- case 2:332- *val = 0xffff; break;333- default:334- *val = 0xfffffffful; break;335- }336- return PCIBIOS_SUCCESSFUL;337- }338-339- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);340- if (!addr)341- return PCIBIOS_DEVICE_NOT_FOUND;342- /*343- * Note: the caller has already checked that offset is344- * suitably aligned and that len is 1, 2 or 4.345- */346- switch (len) {347- case 1:348- *val = in_8(addr);349- break;350- case 2:351- *val = in_le16(addr);352- break;353- default:354- *val = in_le32(addr);355- break;356- }357- return PCIBIOS_SUCCESSFUL;358-}359-360-static int361-u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,362- int len, u32 val)363-{364- struct pci_controller *hose = bus->sysdata;365- void volatile __iomem *addr;366- int i;367-368- struct device_node *np = pci_busdev_to_OF_node(bus, devfn);369- if (np == NULL)370- return PCIBIOS_DEVICE_NOT_FOUND;371- /*372- * When a device in K2 is powered down, we die on config373- * cycle accesses. Fix that here.374- */375- for (i=0; i<2; i++)376- if (k2_skiplist[i] == np)377- return PCIBIOS_SUCCESSFUL;378-379- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);380- if (!addr)381- return PCIBIOS_DEVICE_NOT_FOUND;382- /*383- * Note: the caller has already checked that offset is384- * suitably aligned and that len is 1, 2 or 4.385- */386- switch (len) {387- case 1:388- out_8(addr, val);389- (void) in_8(addr);390- break;391- case 2:392- out_le16(addr, val);393- (void) in_le16(addr);394- break;395- default:396- out_le32(addr, val);397- (void) in_le32(addr);398- break;399- }400- return PCIBIOS_SUCCESSFUL;401-}402-403-static struct pci_ops u3_ht_pci_ops =404-{405- u3_ht_read_config,406- u3_ht_write_config407-};408-409-#endif /* CONFIG_POWER4 */410-411-/*412- * For a bandit bridge, turn on cache coherency if necessary.413- * N.B. we could clean this up using the hose ops directly.414- */415-static void __init416-init_bandit(struct pci_controller *bp)417-{418- unsigned int vendev, magic;419- int rev;420-421- /* read the word at offset 0 in config space for device 11 */422- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);423- udelay(2);424- vendev = in_le32(bp->cfg_data);425- if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +426- PCI_VENDOR_ID_APPLE) {427- /* read the revision id */428- out_le32(bp->cfg_addr,429- (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);430- udelay(2);431- rev = in_8(bp->cfg_data);432- if (rev != BANDIT_REVID)433- printk(KERN_WARNING434- "Unknown revision %d for bandit\n", rev);435- } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {436- printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);437- return;438- }439-440- /* read the word at offset 0x50 */441- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);442- udelay(2);443- magic = in_le32(bp->cfg_data);444- if ((magic & BANDIT_COHERENT) != 0)445- return;446- magic |= BANDIT_COHERENT;447- udelay(2);448- out_le32(bp->cfg_data, magic);449- printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");450-}451-452-453-/*454- * Tweak the PCI-PCI bridge chip on the blue & white G3s.455- */456-static void __init457-init_p2pbridge(void)458-{459- struct device_node *p2pbridge;460- struct pci_controller* hose;461- u8 bus, devfn;462- u16 val;463-464- /* XXX it would be better here to identify the specific465- PCI-PCI bridge chip we have. */466- if ((p2pbridge = find_devices("pci-bridge")) == 0467- || p2pbridge->parent == NULL468- || strcmp(p2pbridge->parent->name, "pci") != 0)469- return;470- if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {471- DBG("Can't find PCI infos for PCI<->PCI bridge\n");472- return;473- }474- /* Warning: At this point, we have not yet renumbered all busses.475- * So we must use OF walking to find out hose476- */477- hose = pci_find_hose_for_OF_device(p2pbridge);478- if (!hose) {479- DBG("Can't find hose for PCI<->PCI bridge\n");480- return;481- }482- if (early_read_config_word(hose, bus, devfn,483- PCI_BRIDGE_CONTROL, &val) < 0) {484- printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");485- return;486- }487- val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;488- early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);489-}490-491-/*492- * Some Apple desktop machines have a NEC PD720100A USB2 controller493- * on the motherboard. Open Firmware, on these, will disable the494- * EHCI part of it so it behaves like a pair of OHCI's. This fixup495- * code re-enables it ;)496- */497-static void __init498-fixup_nec_usb2(void)499-{500- struct device_node *nec;501-502- for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {503- struct pci_controller *hose;504- u32 data, *prop;505- u8 bus, devfn;506-507- prop = (u32 *)get_property(nec, "vendor-id", NULL);508- if (prop == NULL)509- continue;510- if (0x1033 != *prop)511- continue;512- prop = (u32 *)get_property(nec, "device-id", NULL);513- if (prop == NULL)514- continue;515- if (0x0035 != *prop)516- continue;517- prop = (u32 *)get_property(nec, "reg", NULL);518- if (prop == NULL)519- continue;520- devfn = (prop[0] >> 8) & 0xff;521- bus = (prop[0] >> 16) & 0xff;522- if (PCI_FUNC(devfn) != 0)523- continue;524- hose = pci_find_hose_for_OF_device(nec);525- if (!hose)526- continue;527- early_read_config_dword(hose, bus, devfn, 0xe4, &data);528- if (data & 1UL) {529- printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");530- data &= ~1UL;531- early_write_config_dword(hose, bus, devfn, 0xe4, data);532- early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,533- nec->intrs[0].line);534- }535- }536-}537-538-void __init539-pmac_find_bridges(void)540-{541- struct device_node *np, *root;542- struct device_node *ht = NULL;543-544- root = of_find_node_by_path("/");545- if (root == NULL) {546- printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");547- return;548- }549- for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {550- if (np->name == NULL)551- continue;552- if (strcmp(np->name, "bandit") == 0553- || strcmp(np->name, "chaos") == 0554- || strcmp(np->name, "pci") == 0) {555- if (add_bridge(np) == 0)556- of_node_get(np);557- }558- if (strcmp(np->name, "ht") == 0) {559- of_node_get(np);560- ht = np;561- }562- }563- of_node_put(root);564-565- /* Probe HT last as it relies on the agp resources to be already566- * setup567- */568- if (ht && add_bridge(ht) != 0)569- of_node_put(ht);570-571- init_p2pbridge();572- fixup_nec_usb2();573-574- /* We are still having some issues with the Xserve G4, enabling575- * some offset between bus number and domains for now when we576- * assign all busses should help for now577- */578- if (pci_assign_all_buses)579- pcibios_assign_bus_offset = 0x10;580-581-#ifdef CONFIG_POWER4 582- /* There is something wrong with DMA on U3/HT. I haven't figured out583- * the details yet, but if I set the cache line size to 128 bytes like584- * it should, I'm getting memory corruption caused by devices like585- * sungem (even without the MWI bit set, but maybe sungem doesn't586- * care). Right now, it appears that setting up a 64 bytes line size587- * works properly, 64 bytes beeing the max transfer size of HT, I588- * suppose this is related the way HT/PCI are hooked together. I still589- * need to dive into more specs though to be really sure of what's590- * going on. --BenH.591- *592- * Ok, apparently, it's just that HT can't do more than 64 bytes593- * transactions. MWI seem to be meaningless there as well, it may594- * be worth nop'ing out pci_set_mwi too though I haven't done that595- * yet.596- *597- * Note that it's a bit different for whatever is in the AGP slot.598- * For now, I don't care, but this can become a real issue, we599- * should probably hook pci_set_mwi anyway to make sure it sets600- * the real cache line size in there.601- */602- if (machine_is_compatible("MacRISC4"))603- pci_cache_line_size = 16; /* 64 bytes */604-605- pmac_check_ht_link();606-#endif /* CONFIG_POWER4 */607-}608-609-#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \610- | (((o) & ~3) << 24))611-612-#define GRACKLE_PICR1_STG 0x00000040613-#define GRACKLE_PICR1_LOOPSNOOP 0x00000010614-615-/* N.B. this is called before bridges is initialized, so we can't616- use grackle_pcibios_{read,write}_config_dword. */617-static inline void grackle_set_stg(struct pci_controller* bp, int enable)618-{619- unsigned int val;620-621- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));622- val = in_le32(bp->cfg_data);623- val = enable? (val | GRACKLE_PICR1_STG) :624- (val & ~GRACKLE_PICR1_STG);625- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));626- out_le32(bp->cfg_data, val);627- (void)in_le32(bp->cfg_data);628-}629-630-static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)631-{632- unsigned int val;633-634- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));635- val = in_le32(bp->cfg_data);636- val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :637- (val & ~GRACKLE_PICR1_LOOPSNOOP);638- out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));639- out_le32(bp->cfg_data, val);640- (void)in_le32(bp->cfg_data);641-}642-643-static int __init644-setup_uninorth(struct pci_controller* hose, struct reg_property* addr)645-{646- pci_assign_all_buses = 1;647- has_uninorth = 1;648- hose->ops = ¯isc_pci_ops;649- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);650- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);651- /* We "know" that the bridge at f2000000 has the PCI slots. */652- return addr->address == 0xf2000000;653-}654-655-static void __init656-setup_bandit(struct pci_controller* hose, struct reg_property* addr)657-{658- hose->ops = ¯isc_pci_ops;659- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);660- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);661- init_bandit(hose);662-}663-664-static void __init665-setup_chaos(struct pci_controller* hose, struct reg_property* addr)666-{667- /* assume a `chaos' bridge */668- hose->ops = &chaos_pci_ops;669- hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);670- hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);671-}672-673-#ifdef CONFIG_POWER4674-675-static void __init676-setup_u3_agp(struct pci_controller* hose, struct reg_property* addr)677-{678- /* On G5, we move AGP up to high bus number so we don't need679- * to reassign bus numbers for HT. If we ever have P2P bridges680- * on AGP, we'll have to move pci_assign_all_buses to the681- * pci_controller structure so we enable it for AGP and not for682- * HT childs.683- * We hard code the address because of the different size of684- * the reg address cell, we shall fix that by killing struct685- * reg_property and using some accessor functions instead686- */687- hose->first_busno = 0xf0;688- hose->last_busno = 0xff;689- has_uninorth = 1;690- hose->ops = ¯isc_pci_ops;691- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);692- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);693-694- u3_agp = hose;695-}696-697-static void __init698-setup_u3_ht(struct pci_controller* hose, struct reg_property *addr)699-{700- struct device_node *np = (struct device_node *)hose->arch_data;701- int i, cur;702-703- hose->ops = &u3_ht_pci_ops;704-705- /* We hard code the address because of the different size of706- * the reg address cell, we shall fix that by killing struct707- * reg_property and using some accessor functions instead708- */709- hose->cfg_data = ioremap(0xf2000000, 0x02000000);710-711- /*712- * /ht node doesn't expose a "ranges" property, so we "remove" regions that713- * have been allocated to AGP. So far, this version of the code doesn't assign714- * any of the 0xfxxxxxxx "fine" memory regions to /ht.715- * We need to fix that sooner or later by either parsing all child "ranges"716- * properties or figuring out the U3 address space decoding logic and717- * then read its configuration register (if any).718- */719- hose->io_base_phys = 0xf4000000;720- hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);721- isa_io_base = (unsigned long) hose->io_base_virt;722- hose->io_resource.name = np->full_name;723- hose->io_resource.start = 0;724- hose->io_resource.end = 0x003fffff;725- hose->io_resource.flags = IORESOURCE_IO;726- hose->pci_mem_offset = 0;727- hose->first_busno = 0;728- hose->last_busno = 0xef;729- hose->mem_resources[0].name = np->full_name;730- hose->mem_resources[0].start = 0x80000000;731- hose->mem_resources[0].end = 0xefffffff;732- hose->mem_resources[0].flags = IORESOURCE_MEM;733-734- if (u3_agp == NULL) {735- DBG("U3 has no AGP, using full resource range\n");736- return;737- }738-739- /* We "remove" the AGP resources from the resources allocated to HT, that740- * is we create "holes". However, that code does assumptions that so far741- * happen to be true (cross fingers...), typically that resources in the742- * AGP node are properly ordered743- */744- cur = 0;745- for (i=0; i<3; i++) {746- struct resource *res = &u3_agp->mem_resources[i];747- if (res->flags != IORESOURCE_MEM)748- continue;749- /* We don't care about "fine" resources */750- if (res->start >= 0xf0000000)751- continue;752- /* Check if it's just a matter of "shrinking" us in one direction */753- if (hose->mem_resources[cur].start == res->start) {754- DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",755- cur, hose->mem_resources[cur].start, res->end + 1);756- hose->mem_resources[cur].start = res->end + 1;757- continue;758- }759- if (hose->mem_resources[cur].end == res->end) {760- DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",761- cur, hose->mem_resources[cur].end, res->start - 1);762- hose->mem_resources[cur].end = res->start - 1;763- continue;764- }765- /* No, it's not the case, we need a hole */766- if (cur == 2) {767- /* not enough resources to make a hole, we drop part of the range */768- printk(KERN_WARNING "Running out of resources for /ht host !\n");769- hose->mem_resources[cur].end = res->start - 1;770- continue;771- } 772- cur++;773- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",774- cur-1, res->start - 1, cur, res->end + 1);775- hose->mem_resources[cur].name = np->full_name;776- hose->mem_resources[cur].flags = IORESOURCE_MEM;777- hose->mem_resources[cur].start = res->end + 1;778- hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;779- hose->mem_resources[cur-1].end = res->start - 1;780- }781-}782-783-#endif /* CONFIG_POWER4 */784-785-void __init786-setup_grackle(struct pci_controller *hose)787-{788- setup_indirect_pci(hose, 0xfec00000, 0xfee00000);789- if (machine_is_compatible("AAPL,PowerBook1998"))790- grackle_set_loop_snoop(hose, 1);791-#if 0 /* Disabled for now, HW problems ??? */792- grackle_set_stg(hose, 1);793-#endif794-}795-796-/*797- * We assume that if we have a G3 powermac, we have one bridge called798- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,799- * if we have one or more bandit or chaos bridges, we don't have a MPC106.800- */801-static int __init802-add_bridge(struct device_node *dev)803-{804- int len;805- struct pci_controller *hose;806- struct reg_property *addr;807- char* disp_name;808- int *bus_range;809- int primary = 1;810-811- DBG("Adding PCI host bridge %s\n", dev->full_name);812-813- addr = (struct reg_property *) get_property(dev, "reg", &len);814- if (addr == NULL || len < sizeof(*addr)) {815- printk(KERN_WARNING "Can't use %s: no address\n",816- dev->full_name);817- return -ENODEV;818- }819- bus_range = (int *) get_property(dev, "bus-range", &len);820- if (bus_range == NULL || len < 2 * sizeof(int)) {821- printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",822- dev->full_name);823- }824-825- hose = pcibios_alloc_controller();826- if (!hose)827- return -ENOMEM;828- hose->arch_data = dev;829- hose->first_busno = bus_range ? bus_range[0] : 0;830- hose->last_busno = bus_range ? bus_range[1] : 0xff;831-832- disp_name = NULL;833-#ifdef CONFIG_POWER4834- if (device_is_compatible(dev, "u3-agp")) {835- setup_u3_agp(hose, addr);836- disp_name = "U3-AGP";837- primary = 0;838- } else if (device_is_compatible(dev, "u3-ht")) {839- setup_u3_ht(hose, addr);840- disp_name = "U3-HT";841- primary = 1;842- } else843-#endif /* CONFIG_POWER4 */844- if (device_is_compatible(dev, "uni-north")) {845- primary = setup_uninorth(hose, addr);846- disp_name = "UniNorth";847- } else if (strcmp(dev->name, "pci") == 0) {848- /* XXX assume this is a mpc106 (grackle) */849- setup_grackle(hose);850- disp_name = "Grackle (MPC106)";851- } else if (strcmp(dev->name, "bandit") == 0) {852- setup_bandit(hose, addr);853- disp_name = "Bandit";854- } else if (strcmp(dev->name, "chaos") == 0) {855- setup_chaos(hose, addr);856- disp_name = "Chaos";857- primary = 0;858- }859- printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",860- disp_name, addr->address, hose->first_busno, hose->last_busno);861- DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",862- hose, hose->cfg_addr, hose->cfg_data);863-864- /* Interpret the "ranges" property */865- /* This also maps the I/O region and sets isa_io/mem_base */866- pci_process_bridge_OF_ranges(hose, dev, primary);867-868- /* Fixup "bus-range" OF property */869- fixup_bus_range(dev);870-871- return 0;872-}873-874-static void __init875-pcibios_fixup_OF_interrupts(void)876-{877- struct pci_dev* dev = NULL;878-879- /*880- * Open Firmware often doesn't initialize the881- * PCI_INTERRUPT_LINE config register properly, so we882- * should find the device node and apply the interrupt883- * obtained from the OF device-tree884- */885- for_each_pci_dev(dev) {886- struct device_node *node;887- node = pci_device_to_OF_node(dev);888- /* this is the node, see if it has interrupts */889- if (node && node->n_intrs > 0)890- dev->irq = node->intrs[0].line;891- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);892- }893-}894-895-void __init896-pmac_pcibios_fixup(void)897-{898- /* Fixup interrupts according to OF tree */899- pcibios_fixup_OF_interrupts();900-}901-902-int903-pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)904-{905- struct device_node* node;906- int updatecfg = 0;907- int uninorth_child;908-909- node = pci_device_to_OF_node(dev);910-911- /* We don't want to enable USB controllers absent from the OF tree912- * (iBook second controller)913- */914- if (dev->vendor == PCI_VENDOR_ID_APPLE915- && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))916- && !node) {917- printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",918- pci_name(dev));919- return -EINVAL;920- }921-922- if (!node)923- return 0;924-925- uninorth_child = node->parent &&926- device_is_compatible(node->parent, "uni-north");927-928- /* Firewire & GMAC were disabled after PCI probe, the driver is929- * claiming them, we must re-enable them now.930- */931- if (uninorth_child && !strcmp(node->name, "firewire") &&932- (device_is_compatible(node, "pci106b,18") ||933- device_is_compatible(node, "pci106b,30") ||934- device_is_compatible(node, "pci11c1,5811"))) {935- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);936- pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);937- updatecfg = 1;938- }939- if (uninorth_child && !strcmp(node->name, "ethernet") &&940- device_is_compatible(node, "gmac")) {941- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);942- updatecfg = 1;943- }944-945- if (updatecfg) {946- u16 cmd;947-948- /*949- * Make sure PCI is correctly configured950- *951- * We use old pci_bios versions of the function since, by952- * default, gmac is not powered up, and so will be absent953- * from the kernel initial PCI lookup.954- *955- * Should be replaced by 2.4 new PCI mechanisms and really956- * register the device.957- */958- pci_read_config_word(dev, PCI_COMMAND, &cmd);959- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;960- pci_write_config_word(dev, PCI_COMMAND, cmd);961- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);962- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);963- }964-965- return 0;966-}967-968-/* We power down some devices after they have been probed. They'll969- * be powered back on later on970- */971-void __init972-pmac_pcibios_after_init(void)973-{974- struct device_node* nd;975-976-#ifdef CONFIG_BLK_DEV_IDE977- struct pci_dev *dev = NULL;978-979- /* OF fails to initialize IDE controllers on macs980- * (and maybe other machines)981- *982- * Ideally, this should be moved to the IDE layer, but we need983- * to check specifically with Andre Hedrick how to do it cleanly984- * since the common IDE code seem to care about the fact that the985- * BIOS may have disabled a controller.986- *987- * -- BenH988- */989- for_each_pci_dev(dev) {990- if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)991- pci_enable_device(dev);992- }993-#endif /* CONFIG_BLK_DEV_IDE */994-995- nd = find_devices("firewire");996- while (nd) {997- if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||998- device_is_compatible(nd, "pci106b,30") ||999- device_is_compatible(nd, "pci11c1,5811"))1000- && device_is_compatible(nd->parent, "uni-north")) {1001- pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);1002- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);1003- }1004- nd = nd->next;1005- }1006- nd = find_devices("ethernet");1007- while (nd) {1008- if (nd->parent && device_is_compatible(nd, "gmac")1009- && device_is_compatible(nd->parent, "uni-north"))1010- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);1011- nd = nd->next;1012- }1013-}1014-1015-void pmac_pci_fixup_cardbus(struct pci_dev* dev)1016-{1017- if (_machine != _MACH_Pmac)1018- return;1019- /*1020- * Fix the interrupt routing on the various cardbus bridges1021- * used on powerbooks1022- */1023- if (dev->vendor != PCI_VENDOR_ID_TI)1024- return;1025- if (dev->device == PCI_DEVICE_ID_TI_1130 ||1026- dev->device == PCI_DEVICE_ID_TI_1131) {1027- u8 val;1028- /* Enable PCI interrupt */1029- if (pci_read_config_byte(dev, 0x91, &val) == 0)1030- pci_write_config_byte(dev, 0x91, val | 0x30);1031- /* Disable ISA interrupt mode */1032- if (pci_read_config_byte(dev, 0x92, &val) == 0)1033- pci_write_config_byte(dev, 0x92, val & ~0x06);1034- }1035- if (dev->device == PCI_DEVICE_ID_TI_1210 ||1036- dev->device == PCI_DEVICE_ID_TI_1211 ||1037- dev->device == PCI_DEVICE_ID_TI_1410 ||1038- dev->device == PCI_DEVICE_ID_TI_1510) {1039- u8 val;1040- /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA1041- signal out the MFUNC0 pin */1042- if (pci_read_config_byte(dev, 0x8c, &val) == 0)1043- pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);1044- /* Disable ISA interrupt mode */1045- if (pci_read_config_byte(dev, 0x92, &val) == 0)1046- pci_write_config_byte(dev, 0x92, val & ~0x06);1047- }1048-}1049-1050-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);1051-1052-void pmac_pci_fixup_pciata(struct pci_dev* dev)1053-{1054- u8 progif = 0;1055-1056- /*1057- * On PowerMacs, we try to switch any PCI ATA controller to1058- * fully native mode1059- */1060- if (_machine != _MACH_Pmac)1061- return;1062- /* Some controllers don't have the class IDE */1063- if (dev->vendor == PCI_VENDOR_ID_PROMISE)1064- switch(dev->device) {1065- case PCI_DEVICE_ID_PROMISE_20246:1066- case PCI_DEVICE_ID_PROMISE_20262:1067- case PCI_DEVICE_ID_PROMISE_20263:1068- case PCI_DEVICE_ID_PROMISE_20265:1069- case PCI_DEVICE_ID_PROMISE_20267:1070- case PCI_DEVICE_ID_PROMISE_20268:1071- case PCI_DEVICE_ID_PROMISE_20269:1072- case PCI_DEVICE_ID_PROMISE_20270:1073- case PCI_DEVICE_ID_PROMISE_20271:1074- case PCI_DEVICE_ID_PROMISE_20275:1075- case PCI_DEVICE_ID_PROMISE_20276:1076- case PCI_DEVICE_ID_PROMISE_20277:1077- goto good;1078- }1079- /* Others, check PCI class */1080- if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)1081- return;1082- good:1083- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);1084- if ((progif & 5) != 5) {1085- printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));1086- (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);1087- if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||1088- (progif & 5) != 5)1089- printk(KERN_ERR "Rewrite of PROGIF failed !\n");1090- }1091-}1092-DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);1093-1094-1095-/*1096- * Disable second function on K2-SATA, it's broken1097- * and disable IO BARs on first one1098- */1099-void pmac_pci_fixup_k2_sata(struct pci_dev* dev)1100-{1101- int i;1102- u16 cmd;1103-1104- if (PCI_FUNC(dev->devfn) > 0) {1105- pci_read_config_word(dev, PCI_COMMAND, &cmd);1106- cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);1107- pci_write_config_word(dev, PCI_COMMAND, cmd);1108- for (i = 0; i < 6; i++) {1109- dev->resource[i].start = dev->resource[i].end = 0;1110- dev->resource[i].flags = 0;1111- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);1112- }1113- } else {1114- pci_read_config_word(dev, PCI_COMMAND, &cmd);1115- cmd &= ~PCI_COMMAND_IO;1116- pci_write_config_word(dev, PCI_COMMAND, cmd);1117- for (i = 0; i < 5; i++) {1118- dev->resource[i].start = dev->resource[i].end = 0;1119- dev->resource[i].flags = 0;1120- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);1121- }1122- }1123-}1124-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, pmac_pci_fixup_k2_sata);
···1-/*2- * Support for the interrupt controllers found on Power Macintosh,3- * currently Apple's "Grand Central" interrupt controller in all4- * it's incarnations. OpenPIC support used on newer machines is5- * in a separate file6- *7- * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)8- *9- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)10- *11- * This program is free software; you can redistribute it and/or12- * modify it under the terms of the GNU General Public License13- * as published by the Free Software Foundation; either version14- * 2 of the License, or (at your option) any later version.15- *16- */17-18-#include <linux/config.h>19-#include <linux/stddef.h>20-#include <linux/init.h>21-#include <linux/sched.h>22-#include <linux/signal.h>23-#include <linux/pci.h>24-#include <linux/interrupt.h>25-#include <linux/sysdev.h>26-#include <linux/adb.h>27-#include <linux/pmu.h>28-29-#include <asm/sections.h>30-#include <asm/io.h>31-#include <asm/smp.h>32-#include <asm/prom.h>33-#include <asm/pci-bridge.h>34-#include <asm/time.h>35-#include <asm/open_pic.h>36-#include <asm/xmon.h>37-#include <asm/pmac_feature.h>38-#include <asm/machdep.h>39-40-#include "pmac_pic.h"41-42-/*43- * XXX this should be in xmon.h, but putting it there means xmon.h44- * has to include <linux/interrupt.h> (to get irqreturn_t), which45- * causes all sorts of problems. -- paulus46- */47-extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);48-49-struct pmac_irq_hw {50- unsigned int event;51- unsigned int enable;52- unsigned int ack;53- unsigned int level;54-};55-56-/* Default addresses */57-static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {58- (struct pmac_irq_hw *) 0xf3000020,59- (struct pmac_irq_hw *) 0xf3000010,60- (struct pmac_irq_hw *) 0xf4000020,61- (struct pmac_irq_hw *) 0xf4000010,62-};63-64-#define GC_LEVEL_MASK 0x3ff0000065-#define OHARE_LEVEL_MASK 0x1ff0000066-#define HEATHROW_LEVEL_MASK 0x1ff0000067-68-static int max_irqs;69-static int max_real_irqs;70-static u32 level_mask[4];71-72-static DEFINE_SPINLOCK(pmac_pic_lock);73-74-75-#define GATWICK_IRQ_POOL_SIZE 1076-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];77-78-#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)79-static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];80-81-/*82- * Mark an irq as "lost". This is only used on the pmac83- * since it can lose interrupts (see pmac_set_irq_mask).84- * -- Cort85- */86-void87-__set_lost(unsigned long irq_nr, int nokick)88-{89- if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {90- atomic_inc(&ppc_n_lost_interrupts);91- if (!nokick)92- set_dec(1);93- }94-}95-96-static void97-pmac_mask_and_ack_irq(unsigned int irq_nr)98-{99- unsigned long bit = 1UL << (irq_nr & 0x1f);100- int i = irq_nr >> 5;101- unsigned long flags;102-103- if ((unsigned)irq_nr >= max_irqs)104- return;105-106- clear_bit(irq_nr, ppc_cached_irq_mask);107- if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))108- atomic_dec(&ppc_n_lost_interrupts);109- spin_lock_irqsave(&pmac_pic_lock, flags);110- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);111- out_le32(&pmac_irq_hw[i]->ack, bit);112- do {113- /* make sure ack gets to controller before we enable114- interrupts */115- mb();116- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)117- != (ppc_cached_irq_mask[i] & bit));118- spin_unlock_irqrestore(&pmac_pic_lock, flags);119-}120-121-static void pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)122-{123- unsigned long bit = 1UL << (irq_nr & 0x1f);124- int i = irq_nr >> 5;125- unsigned long flags;126-127- if ((unsigned)irq_nr >= max_irqs)128- return;129-130- spin_lock_irqsave(&pmac_pic_lock, flags);131- /* enable unmasked interrupts */132- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);133-134- do {135- /* make sure mask gets to controller before we136- return to user */137- mb();138- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)139- != (ppc_cached_irq_mask[i] & bit));140-141- /*142- * Unfortunately, setting the bit in the enable register143- * when the device interrupt is already on *doesn't* set144- * the bit in the flag register or request another interrupt.145- */146- if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))147- __set_lost((ulong)irq_nr, nokicklost);148- spin_unlock_irqrestore(&pmac_pic_lock, flags);149-}150-151-/* When an irq gets requested for the first client, if it's an152- * edge interrupt, we clear any previous one on the controller153- */154-static unsigned int pmac_startup_irq(unsigned int irq_nr)155-{156- unsigned long bit = 1UL << (irq_nr & 0x1f);157- int i = irq_nr >> 5;158-159- if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)160- out_le32(&pmac_irq_hw[i]->ack, bit);161- set_bit(irq_nr, ppc_cached_irq_mask);162- pmac_set_irq_mask(irq_nr, 0);163-164- return 0;165-}166-167-static void pmac_mask_irq(unsigned int irq_nr)168-{169- clear_bit(irq_nr, ppc_cached_irq_mask);170- pmac_set_irq_mask(irq_nr, 0);171- mb();172-}173-174-static void pmac_unmask_irq(unsigned int irq_nr)175-{176- set_bit(irq_nr, ppc_cached_irq_mask);177- pmac_set_irq_mask(irq_nr, 0);178-}179-180-static void pmac_end_irq(unsigned int irq_nr)181-{182- if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))183- && irq_desc[irq_nr].action) {184- set_bit(irq_nr, ppc_cached_irq_mask);185- pmac_set_irq_mask(irq_nr, 1);186- }187-}188-189-190-struct hw_interrupt_type pmac_pic = {191- .typename = " PMAC-PIC ",192- .startup = pmac_startup_irq,193- .enable = pmac_unmask_irq,194- .disable = pmac_mask_irq,195- .ack = pmac_mask_and_ack_irq,196- .end = pmac_end_irq,197-};198-199-struct hw_interrupt_type gatwick_pic = {200- .typename = " GATWICK ",201- .startup = pmac_startup_irq,202- .enable = pmac_unmask_irq,203- .disable = pmac_mask_irq,204- .ack = pmac_mask_and_ack_irq,205- .end = pmac_end_irq,206-};207-208-static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)209-{210- int irq, bits;211-212- for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {213- int i = irq >> 5;214- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];215- /* We must read level interrupts from the level register */216- bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);217- bits &= ppc_cached_irq_mask[i];218- if (bits == 0)219- continue;220- irq += __ilog2(bits);221- __do_IRQ(irq, regs);222- return IRQ_HANDLED;223- }224- printk("gatwick irq not from gatwick pic\n");225- return IRQ_NONE;226-}227-228-int229-pmac_get_irq(struct pt_regs *regs)230-{231- int irq;232- unsigned long bits = 0;233-234-#ifdef CONFIG_SMP235- void psurge_smp_message_recv(struct pt_regs *);236-237- /* IPI's are a hack on the powersurge -- Cort */238- if ( smp_processor_id() != 0 ) {239- psurge_smp_message_recv(regs);240- return -2; /* ignore, already handled */241- }242-#endif /* CONFIG_SMP */243- for (irq = max_real_irqs; (irq -= 32) >= 0; ) {244- int i = irq >> 5;245- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];246- /* We must read level interrupts from the level register */247- bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);248- bits &= ppc_cached_irq_mask[i];249- if (bits == 0)250- continue;251- irq += __ilog2(bits);252- break;253- }254-255- return irq;256-}257-258-/* This routine will fix some missing interrupt values in the device tree259- * on the gatwick mac-io controller used by some PowerBooks260- */261-static void __init262-pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)263-{264- struct device_node *node;265- int count;266-267- memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));268- node = gw->child;269- count = 0;270- while(node)271- {272- /* Fix SCC */273- if (strcasecmp(node->name, "escc") == 0)274- if (node->child) {275- if (node->child->n_intrs < 3) {276- node->child->intrs = &gatwick_int_pool[count];277- count += 3;278- }279- node->child->n_intrs = 3;280- node->child->intrs[0].line = 15+irq_base;281- node->child->intrs[1].line = 4+irq_base;282- node->child->intrs[2].line = 5+irq_base;283- printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",284- node->child->intrs[0].line,285- node->child->intrs[1].line,286- node->child->intrs[2].line);287- }288- /* Fix media-bay & left SWIM */289- if (strcasecmp(node->name, "media-bay") == 0) {290- struct device_node* ya_node;291-292- if (node->n_intrs == 0)293- node->intrs = &gatwick_int_pool[count++];294- node->n_intrs = 1;295- node->intrs[0].line = 29+irq_base;296- printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",297- node->intrs[0].line);298-299- ya_node = node->child;300- while(ya_node)301- {302- if (strcasecmp(ya_node->name, "floppy") == 0) {303- if (ya_node->n_intrs < 2) {304- ya_node->intrs = &gatwick_int_pool[count];305- count += 2;306- }307- ya_node->n_intrs = 2;308- ya_node->intrs[0].line = 19+irq_base;309- ya_node->intrs[1].line = 1+irq_base;310- printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",311- ya_node->intrs[0].line, ya_node->intrs[1].line);312- }313- if (strcasecmp(ya_node->name, "ata4") == 0) {314- if (ya_node->n_intrs < 2) {315- ya_node->intrs = &gatwick_int_pool[count];316- count += 2;317- }318- ya_node->n_intrs = 2;319- ya_node->intrs[0].line = 14+irq_base;320- ya_node->intrs[1].line = 3+irq_base;321- printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",322- ya_node->intrs[0].line, ya_node->intrs[1].line);323- }324- ya_node = ya_node->sibling;325- }326- }327- node = node->sibling;328- }329- if (count > 10) {330- printk("WARNING !! Gatwick interrupt pool overflow\n");331- printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);332- printk(" requested = %d\n", count);333- }334-}335-336-/*337- * The PowerBook 3400/2400/3500 can have a combo ethernet/modem338- * card which includes an ohare chip that acts as a second interrupt339- * controller. If we find this second ohare, set it up and fix the340- * interrupt value in the device tree for the ethernet chip.341- */342-static int __init enable_second_ohare(void)343-{344- unsigned char bus, devfn;345- unsigned short cmd;346- unsigned long addr;347- struct device_node *irqctrler = find_devices("pci106b,7");348- struct device_node *ether;349-350- if (irqctrler == NULL || irqctrler->n_addrs <= 0)351- return -1;352- addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);353- pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);354- max_irqs = 64;355- if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {356- struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);357- if (!hose)358- printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");359- else {360- early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);361- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;362- cmd &= ~PCI_COMMAND_IO;363- early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);364- }365- }366-367- /* Fix interrupt for the modem/ethernet combo controller. The number368- in the device tree (27) is bogus (correct for the ethernet-only369- board but not the combo ethernet/modem board).370- The real interrupt is 28 on the second controller -> 28+32 = 60.371- */372- ether = find_devices("pci1011,14");373- if (ether && ether->n_intrs > 0) {374- ether->intrs[0].line = 60;375- printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",376- ether->intrs[0].line);377- }378-379- /* Return the interrupt number of the cascade */380- return irqctrler->intrs[0].line;381-}382-383-#ifdef CONFIG_POWER4384-static irqreturn_t k2u3_action(int cpl, void *dev_id, struct pt_regs *regs)385-{386- int irq;387-388- irq = openpic2_get_irq(regs);389- if (irq != -1)390- __do_IRQ(irq, regs);391- return IRQ_HANDLED;392-}393-394-static struct irqaction k2u3_cascade_action = {395- .handler = k2u3_action,396- .flags = 0,397- .mask = CPU_MASK_NONE,398- .name = "U3->K2 Cascade",399-};400-#endif /* CONFIG_POWER4 */401-402-#ifdef CONFIG_XMON403-static struct irqaction xmon_action = {404- .handler = xmon_irq,405- .flags = 0,406- .mask = CPU_MASK_NONE,407- .name = "NMI - XMON"408-};409-#endif410-411-static struct irqaction gatwick_cascade_action = {412- .handler = gatwick_action,413- .flags = SA_INTERRUPT,414- .mask = CPU_MASK_NONE,415- .name = "cascade",416-};417-418-void __init pmac_pic_init(void)419-{420- int i;421- struct device_node *irqctrler = NULL;422- struct device_node *irqctrler2 = NULL;423- struct device_node *np;424- unsigned long addr;425- int irq_cascade = -1;426-427- /* We first try to detect Apple's new Core99 chipset, since mac-io428- * is quite different on those machines and contains an IBM MPIC2.429- */430- np = find_type_devices("open-pic");431- while(np) {432- if (np->parent && !strcmp(np->parent->name, "u3"))433- irqctrler2 = np;434- else435- irqctrler = np;436- np = np->next;437- }438- if (irqctrler != NULL)439- {440- if (irqctrler->n_addrs > 0)441- {442- unsigned char senses[128];443-444- printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",445- irqctrler->addrs[0].address);446-447- prom_get_irq_senses(senses, 0, 128);448- OpenPIC_InitSenses = senses;449- OpenPIC_NumInitSenses = 128;450- ppc_md.get_irq = openpic_get_irq;451- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);452- OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,453- irqctrler->addrs[0].size);454- openpic_init(0);455-456-#ifdef CONFIG_POWER4457- if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&458- irqctrler2->n_addrs > 0) {459- printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",460- irqctrler2->addrs[0].address,461- irqctrler2->intrs[0].line);462- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);463- OpenPIC2_Addr = ioremap(irqctrler2->addrs[0].address,464- irqctrler2->addrs[0].size);465- prom_get_irq_senses(senses, PMAC_OPENPIC2_OFFSET,466- PMAC_OPENPIC2_OFFSET+128);467- OpenPIC_InitSenses = senses;468- OpenPIC_NumInitSenses = 128;469- openpic2_init(PMAC_OPENPIC2_OFFSET);470-471- if (setup_irq(irqctrler2->intrs[0].line,472- &k2u3_cascade_action))473- printk("Unable to get OpenPIC IRQ for cascade\n");474- }475-#endif /* CONFIG_POWER4 */476-477-#ifdef CONFIG_XMON478- {479- struct device_node* pswitch;480- int nmi_irq;481-482- pswitch = find_devices("programmer-switch");483- if (pswitch && pswitch->n_intrs) {484- nmi_irq = pswitch->intrs[0].line;485- openpic_init_nmi_irq(nmi_irq);486- setup_irq(nmi_irq, &xmon_action);487- }488- }489-#endif /* CONFIG_XMON */490- return;491- }492- irqctrler = NULL;493- }494-495- /* Get the level/edge settings, assume if it's not496- * a Grand Central nor an OHare, then it's an Heathrow497- * (or Paddington).498- */499- if (find_devices("gc"))500- level_mask[0] = GC_LEVEL_MASK;501- else if (find_devices("ohare")) {502- level_mask[0] = OHARE_LEVEL_MASK;503- /* We might have a second cascaded ohare */504- level_mask[1] = OHARE_LEVEL_MASK;505- } else {506- level_mask[0] = HEATHROW_LEVEL_MASK;507- level_mask[1] = 0;508- /* We might have a second cascaded heathrow */509- level_mask[2] = HEATHROW_LEVEL_MASK;510- level_mask[3] = 0;511- }512-513- /*514- * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,515- * 1998 G3 Series PowerBooks have 128,516- * other powermacs have 32.517- * The combo ethernet/modem card for the Powerstar powerbooks518- * (2400/3400/3500, ohare based) has a second ohare chip519- * effectively making a total of 64.520- */521- max_irqs = max_real_irqs = 32;522- irqctrler = find_devices("mac-io");523- if (irqctrler)524- {525- max_real_irqs = 64;526- if (irqctrler->next)527- max_irqs = 128;528- else529- max_irqs = 64;530- }531- for ( i = 0; i < max_real_irqs ; i++ )532- irq_desc[i].handler = &pmac_pic;533-534- /* get addresses of first controller */535- if (irqctrler) {536- if (irqctrler->n_addrs > 0) {537- addr = (unsigned long)538- ioremap(irqctrler->addrs[0].address, 0x40);539- for (i = 0; i < 2; ++i)540- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)541- (addr + (2 - i) * 0x10);542- }543-544- /* get addresses of second controller */545- irqctrler = irqctrler->next;546- if (irqctrler && irqctrler->n_addrs > 0) {547- addr = (unsigned long)548- ioremap(irqctrler->addrs[0].address, 0x40);549- for (i = 2; i < 4; ++i)550- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)551- (addr + (4 - i) * 0x10);552- irq_cascade = irqctrler->intrs[0].line;553- if (device_is_compatible(irqctrler, "gatwick"))554- pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);555- }556- } else {557- /* older powermacs have a GC (grand central) or ohare at558- f3000000, with interrupt control registers at f3000020. */559- addr = (unsigned long) ioremap(0xf3000000, 0x40);560- pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);561- }562-563- /* PowerBooks 3400 and 3500 can have a second controller in a second564- ohare chip, on the combo ethernet/modem card */565- if (machine_is_compatible("AAPL,3400/2400")566- || machine_is_compatible("AAPL,3500"))567- irq_cascade = enable_second_ohare();568-569- /* disable all interrupts in all controllers */570- for (i = 0; i * 32 < max_irqs; ++i)571- out_le32(&pmac_irq_hw[i]->enable, 0);572- /* mark level interrupts */573- for (i = 0; i < max_irqs; i++)574- if (level_mask[i >> 5] & (1UL << (i & 0x1f)))575- irq_desc[i].status = IRQ_LEVEL;576-577- /* get interrupt line of secondary interrupt controller */578- if (irq_cascade >= 0) {579- printk(KERN_INFO "irq: secondary controller on irq %d\n",580- (int)irq_cascade);581- for ( i = max_real_irqs ; i < max_irqs ; i++ )582- irq_desc[i].handler = &gatwick_pic;583- setup_irq(irq_cascade, &gatwick_cascade_action);584- }585- printk("System has %d possible interrupts\n", max_irqs);586- if (max_irqs != max_real_irqs)587- printk(KERN_DEBUG "%d interrupts on main controller\n",588- max_real_irqs);589-590-#ifdef CONFIG_XMON591- setup_irq(20, &xmon_action);592-#endif /* CONFIG_XMON */593-}594-595-#ifdef CONFIG_PM596-/*597- * These procedures are used in implementing sleep on the powerbooks.598- * sleep_save_intrs() saves the states of all interrupt enables599- * and disables all interrupts except for the nominated one.600- * sleep_restore_intrs() restores the states of all interrupt enables.601- */602-unsigned long sleep_save_mask[2];603-604-/* This used to be passed by the PMU driver but that link got605- * broken with the new driver model. We use this tweak for now...606- */607-static int pmacpic_find_viaint(void)608-{609- int viaint = -1;610-611-#ifdef CONFIG_ADB_PMU612- struct device_node *np;613-614- if (pmu_get_model() != PMU_OHARE_BASED)615- goto not_found;616- np = of_find_node_by_name(NULL, "via-pmu");617- if (np == NULL)618- goto not_found;619- viaint = np->intrs[0].line;620-#endif /* CONFIG_ADB_PMU */621-622-not_found:623- return viaint;624-}625-626-static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)627-{628- int viaint = pmacpic_find_viaint();629-630- sleep_save_mask[0] = ppc_cached_irq_mask[0];631- sleep_save_mask[1] = ppc_cached_irq_mask[1];632- ppc_cached_irq_mask[0] = 0;633- ppc_cached_irq_mask[1] = 0;634- if (viaint > 0)635- set_bit(viaint, ppc_cached_irq_mask);636- out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);637- if (max_real_irqs > 32)638- out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);639- (void)in_le32(&pmac_irq_hw[0]->event);640- /* make sure mask gets to controller before we return to caller */641- mb();642- (void)in_le32(&pmac_irq_hw[0]->enable);643-644- return 0;645-}646-647-static int pmacpic_resume(struct sys_device *sysdev)648-{649- int i;650-651- out_le32(&pmac_irq_hw[0]->enable, 0);652- if (max_real_irqs > 32)653- out_le32(&pmac_irq_hw[1]->enable, 0);654- mb();655- for (i = 0; i < max_real_irqs; ++i)656- if (test_bit(i, sleep_save_mask))657- pmac_unmask_irq(i);658-659- return 0;660-}661-662-#endif /* CONFIG_PM */663-664-static struct sysdev_class pmacpic_sysclass = {665- set_kset_name("pmac_pic"),666-};667-668-static struct sys_device device_pmacpic = {669- .id = 0,670- .cls = &pmacpic_sysclass,671-};672-673-static struct sysdev_driver driver_pmacpic = {674-#ifdef CONFIG_PM675- .suspend = &pmacpic_suspend,676- .resume = &pmacpic_resume,677-#endif /* CONFIG_PM */678-};679-680-static int __init init_pmacpic_sysfs(void)681-{682- if (max_irqs == 0)683- return -ENODEV;684-685- printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");686- sysdev_class_register(&pmacpic_sysclass);687- sysdev_register(&device_pmacpic);688- sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);689- return 0;690-}691-692-subsys_initcall(init_pmacpic_sysfs);693-
···1-/*2- * This file contains sleep low-level functions for PowerBook G3.3- * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)4- * and Paul Mackerras (paulus@samba.org).5- *6- * This program is free software; you can redistribute it and/or7- * modify it under the terms of the GNU General Public License8- * as published by the Free Software Foundation; either version9- * 2 of the License, or (at your option) any later version.10- *11- */12-13-#include <linux/config.h>14-#include <asm/processor.h>15-#include <asm/page.h>16-#include <asm/ppc_asm.h>17-#include <asm/cputable.h>18-#include <asm/cache.h>19-#include <asm/thread_info.h>20-#include <asm/asm-offsets.h>21-22-#define MAGIC 0x4c617273 /* 'Lars' */23-24-/*25- * Structure for storing CPU registers on the stack.26- */27-#define SL_SP 028-#define SL_PC 429-#define SL_MSR 830-#define SL_SDR1 0xc31-#define SL_SPRG0 0x10 /* 4 sprg's */32-#define SL_DBAT0 0x2033-#define SL_IBAT0 0x2834-#define SL_DBAT1 0x3035-#define SL_IBAT1 0x3836-#define SL_DBAT2 0x4037-#define SL_IBAT2 0x4838-#define SL_DBAT3 0x5039-#define SL_IBAT3 0x5840-#define SL_TB 0x6041-#define SL_R2 0x6842-#define SL_CR 0x6c43-#define SL_R12 0x70 /* r12 to r31 */44-#define SL_SIZE (SL_R12 + 80)45-46- .section .text47- .align 548-49-#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)50-51-/* This gets called by via-pmu.c late during the sleep process.52- * The PMU was already send the sleep command and will shut us down53- * soon. We need to save all that is needed and setup the wakeup54- * vector that will be called by the ROM on wakeup55- */56-_GLOBAL(low_sleep_handler)57-#ifndef CONFIG_6xx58- blr59-#else60- mflr r061- stw r0,4(r1)62- stwu r1,-SL_SIZE(r1)63- mfcr r064- stw r0,SL_CR(r1)65- stw r2,SL_R2(r1)66- stmw r12,SL_R12(r1)67-68- /* Save MSR & SDR1 */69- mfmsr r470- stw r4,SL_MSR(r1)71- mfsdr1 r472- stw r4,SL_SDR1(r1)73-74- /* Get a stable timebase and save it */75-1: mftbu r476- stw r4,SL_TB(r1)77- mftb r578- stw r5,SL_TB+4(r1)79- mftbu r380- cmpw r3,r481- bne 1b82-83- /* Save SPRGs */84- mfsprg r4,085- stw r4,SL_SPRG0(r1)86- mfsprg r4,187- stw r4,SL_SPRG0+4(r1)88- mfsprg r4,289- stw r4,SL_SPRG0+8(r1)90- mfsprg r4,391- stw r4,SL_SPRG0+12(r1)92-93- /* Save BATs */94- mfdbatu r4,095- stw r4,SL_DBAT0(r1)96- mfdbatl r4,097- stw r4,SL_DBAT0+4(r1)98- mfdbatu r4,199- stw r4,SL_DBAT1(r1)100- mfdbatl r4,1101- stw r4,SL_DBAT1+4(r1)102- mfdbatu r4,2103- stw r4,SL_DBAT2(r1)104- mfdbatl r4,2105- stw r4,SL_DBAT2+4(r1)106- mfdbatu r4,3107- stw r4,SL_DBAT3(r1)108- mfdbatl r4,3109- stw r4,SL_DBAT3+4(r1)110- mfibatu r4,0111- stw r4,SL_IBAT0(r1)112- mfibatl r4,0113- stw r4,SL_IBAT0+4(r1)114- mfibatu r4,1115- stw r4,SL_IBAT1(r1)116- mfibatl r4,1117- stw r4,SL_IBAT1+4(r1)118- mfibatu r4,2119- stw r4,SL_IBAT2(r1)120- mfibatl r4,2121- stw r4,SL_IBAT2+4(r1)122- mfibatu r4,3123- stw r4,SL_IBAT3(r1)124- mfibatl r4,3125- stw r4,SL_IBAT3+4(r1)126-127- /* Backup various CPU config stuffs */128- bl __save_cpu_setup129-130- /* The ROM can wake us up via 2 different vectors:131- * - On wallstreet & lombard, we must write a magic132- * value 'Lars' at address 4 and a pointer to a133- * memory location containing the PC to resume from134- * at address 0.135- * - On Core99, we must store the wakeup vector at136- * address 0x80 and eventually it's parameters137- * at address 0x84. I've have some trouble with those138- * parameters however and I no longer use them.139- */140- lis r5,grackle_wake_up@ha141- addi r5,r5,grackle_wake_up@l142- tophys(r5,r5)143- stw r5,SL_PC(r1)144- lis r4,KERNELBASE@h145- tophys(r5,r1)146- addi r5,r5,SL_PC147- lis r6,MAGIC@ha148- addi r6,r6,MAGIC@l149- stw r5,0(r4)150- stw r6,4(r4)151- /* Setup stuffs at 0x80-0x84 for Core99 */152- lis r3,core99_wake_up@ha153- addi r3,r3,core99_wake_up@l154- tophys(r3,r3)155- stw r3,0x80(r4)156- stw r5,0x84(r4)157- /* Store a pointer to our backup storage into158- * a kernel global159- */160- lis r3,sleep_storage@ha161- addi r3,r3,sleep_storage@l162- stw r5,0(r3)163-164- .globl low_cpu_die165-low_cpu_die:166- /* Flush & disable all caches */167- bl flush_disable_caches168-169- /* Turn off data relocation. */170- mfmsr r3 /* Save MSR in r7 */171- rlwinm r3,r3,0,28,26 /* Turn off DR bit */172- sync173- mtmsr r3174- isync175-176-BEGIN_FTR_SECTION177- /* Flush any pending L2 data prefetches to work around HW bug */178- sync179- lis r3,0xfff0180- lwz r0,0(r3) /* perform cache-inhibited load to ROM */181- sync /* (caches are disabled at this point) */182-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)183-184-/*185- * Set the HID0 and MSR for sleep.186- */187- mfspr r2,SPRN_HID0188- rlwinm r2,r2,0,10,7 /* clear doze, nap */189- oris r2,r2,HID0_SLEEP@h190- sync191- isync192- mtspr SPRN_HID0,r2193- sync194-195-/* This loop puts us back to sleep in case we have a spurrious196- * wakeup so that the host bridge properly stays asleep. The197- * CPU will be turned off, either after a known time (about 1198- * second) on wallstreet & lombard, or as soon as the CPU enters199- * SLEEP mode on core99200- */201- mfmsr r2202- oris r2,r2,MSR_POW@h203-1: sync204- mtmsr r2205- isync206- b 1b207-208-/*209- * Here is the resume code.210- */211-212-213-/*214- * Core99 machines resume here215- * r4 has the physical address of SL_PC(sp) (unused)216- */217-_GLOBAL(core99_wake_up)218- /* Make sure HID0 no longer contains any sleep bit and that data cache219- * is disabled220- */221- mfspr r3,SPRN_HID0222- rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */223- rlwinm 3,r3,0,18,15 /* clear DCE, ICE */224- mtspr SPRN_HID0,r3225- sync226- isync227-228- /* sanitize MSR */229- mfmsr r3230- ori r3,r3,MSR_EE|MSR_IP231- xori r3,r3,MSR_EE|MSR_IP232- sync233- isync234- mtmsr r3235- sync236- isync237-238- /* Recover sleep storage */239- lis r3,sleep_storage@ha240- addi r3,r3,sleep_storage@l241- tophys(r3,r3)242- lwz r1,0(r3)243-244- /* Pass thru to older resume code ... */245-/*246- * Here is the resume code for older machines.247- * r1 has the physical address of SL_PC(sp).248- */249-250-grackle_wake_up:251-252- /* Restore the kernel's segment registers before253- * we do any r1 memory access as we are not sure they254- * are in a sane state above the first 256Mb region255- */256- li r0,16 /* load up segment register values */257- mtctr r0 /* for context 0 */258- lis r3,0x2000 /* Ku = 1, VSID = 0 */259- li r4,0260-3: mtsrin r3,r4261- addi r3,r3,0x111 /* increment VSID */262- addis r4,r4,0x1000 /* address of next segment */263- bdnz 3b264- sync265- isync266-267- subi r1,r1,SL_PC268-269- /* Restore various CPU config stuffs */270- bl __restore_cpu_setup271-272- /* Make sure all FPRs have been initialized */273- bl reloc_offset274- bl __init_fpu_registers275-276- /* Invalidate & enable L1 cache, we don't care about277- * whatever the ROM may have tried to write to memory278- */279- bl __inval_enable_L1280-281- /* Restore the BATs, and SDR1. Then we can turn on the MMU. */282- lwz r4,SL_SDR1(r1)283- mtsdr1 r4284- lwz r4,SL_SPRG0(r1)285- mtsprg 0,r4286- lwz r4,SL_SPRG0+4(r1)287- mtsprg 1,r4288- lwz r4,SL_SPRG0+8(r1)289- mtsprg 2,r4290- lwz r4,SL_SPRG0+12(r1)291- mtsprg 3,r4292-293- lwz r4,SL_DBAT0(r1)294- mtdbatu 0,r4295- lwz r4,SL_DBAT0+4(r1)296- mtdbatl 0,r4297- lwz r4,SL_DBAT1(r1)298- mtdbatu 1,r4299- lwz r4,SL_DBAT1+4(r1)300- mtdbatl 1,r4301- lwz r4,SL_DBAT2(r1)302- mtdbatu 2,r4303- lwz r4,SL_DBAT2+4(r1)304- mtdbatl 2,r4305- lwz r4,SL_DBAT3(r1)306- mtdbatu 3,r4307- lwz r4,SL_DBAT3+4(r1)308- mtdbatl 3,r4309- lwz r4,SL_IBAT0(r1)310- mtibatu 0,r4311- lwz r4,SL_IBAT0+4(r1)312- mtibatl 0,r4313- lwz r4,SL_IBAT1(r1)314- mtibatu 1,r4315- lwz r4,SL_IBAT1+4(r1)316- mtibatl 1,r4317- lwz r4,SL_IBAT2(r1)318- mtibatu 2,r4319- lwz r4,SL_IBAT2+4(r1)320- mtibatl 2,r4321- lwz r4,SL_IBAT3(r1)322- mtibatu 3,r4323- lwz r4,SL_IBAT3+4(r1)324- mtibatl 3,r4325-326-BEGIN_FTR_SECTION327- li r4,0328- mtspr SPRN_DBAT4U,r4329- mtspr SPRN_DBAT4L,r4330- mtspr SPRN_DBAT5U,r4331- mtspr SPRN_DBAT5L,r4332- mtspr SPRN_DBAT6U,r4333- mtspr SPRN_DBAT6L,r4334- mtspr SPRN_DBAT7U,r4335- mtspr SPRN_DBAT7L,r4336- mtspr SPRN_IBAT4U,r4337- mtspr SPRN_IBAT4L,r4338- mtspr SPRN_IBAT5U,r4339- mtspr SPRN_IBAT5L,r4340- mtspr SPRN_IBAT6U,r4341- mtspr SPRN_IBAT6L,r4342- mtspr SPRN_IBAT7U,r4343- mtspr SPRN_IBAT7L,r4344-END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)345-346- /* Flush all TLBs */347- lis r4,0x1000348-1: addic. r4,r4,-0x1000349- tlbie r4350- blt 1b351- sync352-353- /* restore the MSR and turn on the MMU */354- lwz r3,SL_MSR(r1)355- bl turn_on_mmu356-357- /* get back the stack pointer */358- tovirt(r1,r1)359-360- /* Restore TB */361- li r3,0362- mttbl r3363- lwz r3,SL_TB(r1)364- lwz r4,SL_TB+4(r1)365- mttbu r3366- mttbl r4367-368- /* Restore the callee-saved registers and return */369- lwz r0,SL_CR(r1)370- mtcr r0371- lwz r2,SL_R2(r1)372- lmw r12,SL_R12(r1)373- addi r1,r1,SL_SIZE374- lwz r0,4(r1)375- mtlr r0376- blr377-378-turn_on_mmu:379- mflr r4380- tovirt(r4,r4)381- mtsrr0 r4382- mtsrr1 r3383- sync384- isync385- rfi386-387-#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */388-389- .section .data390- .balign L1_CACHE_BYTES391-sleep_storage:392- .long 0393- .balign L1_CACHE_BYTES, 0394-395-#endif /* CONFIG_6xx */396- .section .text
···1-/*2- * SMP support for power macintosh.3- *4- * We support both the old "powersurge" SMP architecture5- * and the current Core99 (G4 PowerMac) machines.6- *7- * Note that we don't support the very first rev. of8- * Apple/DayStar 2 CPUs board, the one with the funky9- * watchdog. Hopefully, none of these should be there except10- * maybe internally to Apple. I should probably still add some11- * code to detect this card though and disable SMP. --BenH.12- *13- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)14- * and Ben Herrenschmidt <benh@kernel.crashing.org>.15- *16- * Support for DayStar quad CPU cards17- * Copyright (C) XLR8, Inc. 1994-200018- *19- * This program is free software; you can redistribute it and/or20- * modify it under the terms of the GNU General Public License21- * as published by the Free Software Foundation; either version22- * 2 of the License, or (at your option) any later version.23- */24-#include <linux/config.h>25-#include <linux/kernel.h>26-#include <linux/sched.h>27-#include <linux/smp.h>28-#include <linux/smp_lock.h>29-#include <linux/interrupt.h>30-#include <linux/kernel_stat.h>31-#include <linux/delay.h>32-#include <linux/init.h>33-#include <linux/spinlock.h>34-#include <linux/errno.h>35-#include <linux/hardirq.h>36-#include <linux/cpu.h>37-38-#include <asm/ptrace.h>39-#include <asm/atomic.h>40-#include <asm/irq.h>41-#include <asm/page.h>42-#include <asm/pgtable.h>43-#include <asm/sections.h>44-#include <asm/io.h>45-#include <asm/prom.h>46-#include <asm/smp.h>47-#include <asm/residual.h>48-#include <asm/machdep.h>49-#include <asm/pmac_feature.h>50-#include <asm/time.h>51-#include <asm/open_pic.h>52-#include <asm/cacheflush.h>53-#include <asm/keylargo.h>54-55-/*56- * Powersurge (old powermac SMP) support.57- */58-59-extern void __secondary_start_pmac_0(void);60-61-/* Addresses for powersurge registers */62-#define HAMMERHEAD_BASE 0xf800000063-#define HHEAD_CONFIG 0x9064-#define HHEAD_SEC_INTR 0xc065-66-/* register for interrupting the primary processor on the powersurge */67-/* N.B. this is actually the ethernet ROM! */68-#define PSURGE_PRI_INTR 0xf301900069-70-/* register for storing the start address for the secondary processor */71-/* N.B. this is the PCI config space address register for the 1st bridge */72-#define PSURGE_START 0xf280000073-74-/* Daystar/XLR8 4-CPU card */75-#define PSURGE_QUAD_REG_ADDR 0xf880000076-77-#define PSURGE_QUAD_IRQ_SET 078-#define PSURGE_QUAD_IRQ_CLR 179-#define PSURGE_QUAD_IRQ_PRIMARY 280-#define PSURGE_QUAD_CKSTOP_CTL 381-#define PSURGE_QUAD_PRIMARY_ARB 482-#define PSURGE_QUAD_BOARD_ID 683-#define PSURGE_QUAD_WHICH_CPU 784-#define PSURGE_QUAD_CKSTOP_RDBK 885-#define PSURGE_QUAD_RESET_CTL 1186-87-#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))88-#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)89-#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))90-#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))91-92-/* virtual addresses for the above */93-static volatile u8 __iomem *hhead_base;94-static volatile u8 __iomem *quad_base;95-static volatile u32 __iomem *psurge_pri_intr;96-static volatile u8 __iomem *psurge_sec_intr;97-static volatile u32 __iomem *psurge_start;98-99-/* values for psurge_type */100-#define PSURGE_NONE -1101-#define PSURGE_DUAL 0102-#define PSURGE_QUAD_OKEE 1103-#define PSURGE_QUAD_COTTON 2104-#define PSURGE_QUAD_ICEGRASS 3105-106-/* what sort of powersurge board we have */107-static int psurge_type = PSURGE_NONE;108-109-/* L2 and L3 cache settings to pass from CPU0 to CPU1 */110-volatile static long int core99_l2_cache;111-volatile static long int core99_l3_cache;112-113-/* Timebase freeze GPIO */114-static unsigned int core99_tb_gpio;115-116-/* Sync flag for HW tb sync */117-static volatile int sec_tb_reset = 0;118-static unsigned int pri_tb_hi, pri_tb_lo;119-static unsigned int pri_tb_stamp;120-121-static void __devinit core99_init_caches(int cpu)122-{123- if (!cpu_has_feature(CPU_FTR_L2CR))124- return;125-126- if (cpu == 0) {127- core99_l2_cache = _get_L2CR();128- printk("CPU0: L2CR is %lx\n", core99_l2_cache);129- } else {130- printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());131- _set_L2CR(0);132- _set_L2CR(core99_l2_cache);133- printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);134- }135-136- if (!cpu_has_feature(CPU_FTR_L3CR))137- return;138-139- if (cpu == 0){140- core99_l3_cache = _get_L3CR();141- printk("CPU0: L3CR is %lx\n", core99_l3_cache);142- } else {143- printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());144- _set_L3CR(0);145- _set_L3CR(core99_l3_cache);146- printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);147- }148-}149-150-/*151- * Set and clear IPIs for powersurge.152- */153-static inline void psurge_set_ipi(int cpu)154-{155- if (psurge_type == PSURGE_NONE)156- return;157- if (cpu == 0)158- in_be32(psurge_pri_intr);159- else if (psurge_type == PSURGE_DUAL)160- out_8(psurge_sec_intr, 0);161- else162- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);163-}164-165-static inline void psurge_clr_ipi(int cpu)166-{167- if (cpu > 0) {168- switch(psurge_type) {169- case PSURGE_DUAL:170- out_8(psurge_sec_intr, ~0);171- case PSURGE_NONE:172- break;173- default:174- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);175- }176- }177-}178-179-/*180- * On powersurge (old SMP powermac architecture) we don't have181- * separate IPIs for separate messages like openpic does. Instead182- * we have a bitmap for each processor, where a 1 bit means that183- * the corresponding message is pending for that processor.184- * Ideally each cpu's entry would be in a different cache line.185- * -- paulus.186- */187-static unsigned long psurge_smp_message[NR_CPUS];188-189-void psurge_smp_message_recv(struct pt_regs *regs)190-{191- int cpu = smp_processor_id();192- int msg;193-194- /* clear interrupt */195- psurge_clr_ipi(cpu);196-197- if (num_online_cpus() < 2)198- return;199-200- /* make sure there is a message there */201- for (msg = 0; msg < 4; msg++)202- if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))203- smp_message_recv(msg, regs);204-}205-206-irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)207-{208- psurge_smp_message_recv(regs);209- return IRQ_HANDLED;210-}211-212-static void smp_psurge_message_pass(int target, int msg)213-{214- int i;215-216- if (num_online_cpus() < 2)217- return;218-219- for (i = 0; i < NR_CPUS; i++) {220- if (!cpu_online(i))221- continue;222- if (target == MSG_ALL223- || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())224- || target == i) {225- set_bit(msg, &psurge_smp_message[i]);226- psurge_set_ipi(i);227- }228- }229-}230-231-/*232- * Determine a quad card presence. We read the board ID register, we233- * force the data bus to change to something else, and we read it again.234- * It it's stable, then the register probably exist (ugh !)235- */236-static int __init psurge_quad_probe(void)237-{238- int type;239- unsigned int i;240-241- type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);242- if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS243- || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))244- return PSURGE_DUAL;245-246- /* looks OK, try a slightly more rigorous test */247- /* bogus is not necessarily cacheline-aligned,248- though I don't suppose that really matters. -- paulus */249- for (i = 0; i < 100; i++) {250- volatile u32 bogus[8];251- bogus[(0+i)%8] = 0x00000000;252- bogus[(1+i)%8] = 0x55555555;253- bogus[(2+i)%8] = 0xFFFFFFFF;254- bogus[(3+i)%8] = 0xAAAAAAAA;255- bogus[(4+i)%8] = 0x33333333;256- bogus[(5+i)%8] = 0xCCCCCCCC;257- bogus[(6+i)%8] = 0xCCCCCCCC;258- bogus[(7+i)%8] = 0x33333333;259- wmb();260- asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");261- mb();262- if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))263- return PSURGE_DUAL;264- }265- return type;266-}267-268-static void __init psurge_quad_init(void)269-{270- int procbits;271-272- if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);273- procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);274- if (psurge_type == PSURGE_QUAD_ICEGRASS)275- PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);276- else277- PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);278- mdelay(33);279- out_8(psurge_sec_intr, ~0);280- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);281- PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);282- if (psurge_type != PSURGE_QUAD_ICEGRASS)283- PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);284- PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);285- mdelay(33);286- PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);287- mdelay(33);288- PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);289- mdelay(33);290-}291-292-static int __init smp_psurge_probe(void)293-{294- int i, ncpus;295-296- /* We don't do SMP on the PPC601 -- paulus */297- if (PVR_VER(mfspr(SPRN_PVR)) == 1)298- return 1;299-300- /*301- * The powersurge cpu board can be used in the generation302- * of powermacs that have a socket for an upgradeable cpu card,303- * including the 7500, 8500, 9500, 9600.304- * The device tree doesn't tell you if you have 2 cpus because305- * OF doesn't know anything about the 2nd processor.306- * Instead we look for magic bits in magic registers,307- * in the hammerhead memory controller in the case of the308- * dual-cpu powersurge board. -- paulus.309- */310- if (find_devices("hammerhead") == NULL)311- return 1;312-313- hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);314- quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);315- psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;316-317- psurge_type = psurge_quad_probe();318- if (psurge_type != PSURGE_DUAL) {319- psurge_quad_init();320- /* All released cards using this HW design have 4 CPUs */321- ncpus = 4;322- } else {323- iounmap(quad_base);324- if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {325- /* not a dual-cpu card */326- iounmap(hhead_base);327- psurge_type = PSURGE_NONE;328- return 1;329- }330- ncpus = 2;331- }332-333- psurge_start = ioremap(PSURGE_START, 4);334- psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);335-336- /* this is not actually strictly necessary -- paulus. */337- for (i = 1; i < ncpus; ++i)338- smp_hw_index[i] = i;339-340- if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);341-342- return ncpus;343-}344-345-static void __init smp_psurge_kick_cpu(int nr)346-{347- unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;348- unsigned long a;349-350- /* may need to flush here if secondary bats aren't setup */351- for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)352- asm volatile("dcbf 0,%0" : : "r" (a) : "memory");353- asm volatile("sync");354-355- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);356-357- out_be32(psurge_start, start);358- mb();359-360- psurge_set_ipi(nr);361- udelay(10);362- psurge_clr_ipi(nr);363-364- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);365-}366-367-/*368- * With the dual-cpu powersurge board, the decrementers and timebases369- * of both cpus are frozen after the secondary cpu is started up,370- * until we give the secondary cpu another interrupt. This routine371- * uses this to get the timebases synchronized.372- * -- paulus.373- */374-static void __init psurge_dual_sync_tb(int cpu_nr)375-{376- int t;377-378- set_dec(tb_ticks_per_jiffy);379- set_tb(0, 0);380- last_jiffy_stamp(cpu_nr) = 0;381-382- if (cpu_nr > 0) {383- mb();384- sec_tb_reset = 1;385- return;386- }387-388- /* wait for the secondary to have reset its TB before proceeding */389- for (t = 10000000; t > 0 && !sec_tb_reset; --t)390- ;391-392- /* now interrupt the secondary, starting both TBs */393- psurge_set_ipi(1);394-395- smp_tb_synchronized = 1;396-}397-398-static struct irqaction psurge_irqaction = {399- .handler = psurge_primary_intr,400- .flags = SA_INTERRUPT,401- .mask = CPU_MASK_NONE,402- .name = "primary IPI",403-};404-405-static void __init smp_psurge_setup_cpu(int cpu_nr)406-{407-408- if (cpu_nr == 0) {409- /* If we failed to start the second CPU, we should still410- * send it an IPI to start the timebase & DEC or we might411- * have them stuck.412- */413- if (num_online_cpus() < 2) {414- if (psurge_type == PSURGE_DUAL)415- psurge_set_ipi(1);416- return;417- }418- /* reset the entry point so if we get another intr we won't419- * try to startup again */420- out_be32(psurge_start, 0x100);421- if (setup_irq(30, &psurge_irqaction))422- printk(KERN_ERR "Couldn't get primary IPI interrupt");423- }424-425- if (psurge_type == PSURGE_DUAL)426- psurge_dual_sync_tb(cpu_nr);427-}428-429-void __init smp_psurge_take_timebase(void)430-{431- /* Dummy implementation */432-}433-434-void __init smp_psurge_give_timebase(void)435-{436- /* Dummy implementation */437-}438-439-static int __init smp_core99_probe(void)440-{441-#ifdef CONFIG_6xx442- extern int powersave_nap;443-#endif444- struct device_node *cpus, *firstcpu;445- int i, ncpus = 0, boot_cpu = -1;446- u32 *tbprop = NULL;447-448- if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);449- cpus = firstcpu = find_type_devices("cpu");450- while(cpus != NULL) {451- u32 *regprop = (u32 *)get_property(cpus, "reg", NULL);452- char *stateprop = (char *)get_property(cpus, "state", NULL);453- if (regprop != NULL && stateprop != NULL &&454- !strncmp(stateprop, "running", 7))455- boot_cpu = *regprop;456- ++ncpus;457- cpus = cpus->next;458- }459- if (boot_cpu == -1)460- printk(KERN_WARNING "Couldn't detect boot CPU !\n");461- if (boot_cpu != 0)462- printk(KERN_WARNING "Boot CPU is %d, unsupported setup !\n", boot_cpu);463-464- if (machine_is_compatible("MacRISC4")) {465- extern struct smp_ops_t core99_smp_ops;466-467- core99_smp_ops.take_timebase = smp_generic_take_timebase;468- core99_smp_ops.give_timebase = smp_generic_give_timebase;469- } else {470- if (firstcpu != NULL)471- tbprop = (u32 *)get_property(firstcpu, "timebase-enable", NULL);472- if (tbprop)473- core99_tb_gpio = *tbprop;474- else475- core99_tb_gpio = KL_GPIO_TB_ENABLE;476- }477-478- if (ncpus > 1) {479- openpic_request_IPIs();480- for (i = 1; i < ncpus; ++i)481- smp_hw_index[i] = i;482-#ifdef CONFIG_6xx483- powersave_nap = 0;484-#endif485- core99_init_caches(0);486- }487-488- return ncpus;489-}490-491-static void __devinit smp_core99_kick_cpu(int nr)492-{493- unsigned long save_vector, new_vector;494- unsigned long flags;495-496- volatile unsigned long *vector497- = ((volatile unsigned long *)(KERNELBASE+0x100));498- if (nr < 0 || nr > 3)499- return;500- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);501-502- local_irq_save(flags);503- local_irq_disable();504-505- /* Save reset vector */506- save_vector = *vector;507-508- /* Setup fake reset vector that does 509- * b __secondary_start_pmac_0 + nr*8 - KERNELBASE510- */511- new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8;512- *vector = 0x48000002 + new_vector - KERNELBASE;513-514- /* flush data cache and inval instruction cache */515- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);516-517- /* Put some life in our friend */518- pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);519-520- /* FIXME: We wait a bit for the CPU to take the exception, I should521- * instead wait for the entry code to set something for me. Well,522- * ideally, all that crap will be done in prom.c and the CPU left523- * in a RAM-based wait loop like CHRP.524- */525- mdelay(1);526-527- /* Restore our exception vector */528- *vector = save_vector;529- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);530-531- local_irq_restore(flags);532- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);533-}534-535-static void __devinit smp_core99_setup_cpu(int cpu_nr)536-{537- /* Setup L2/L3 */538- if (cpu_nr != 0)539- core99_init_caches(cpu_nr);540-541- /* Setup openpic */542- do_openpic_setup_cpu();543-544- if (cpu_nr == 0) {545-#ifdef CONFIG_POWER4546- extern void g5_phy_disable_cpu1(void);547-548- /* If we didn't start the second CPU, we must take549- * it off the bus550- */551- if (machine_is_compatible("MacRISC4") &&552- num_online_cpus() < 2) 553- g5_phy_disable_cpu1();554-#endif /* CONFIG_POWER4 */555- if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);556- }557-}558-559-/* not __init, called in sleep/wakeup code */560-void smp_core99_take_timebase(void)561-{562- unsigned long flags;563-564- /* tell the primary we're here */565- sec_tb_reset = 1;566- mb();567-568- /* wait for the primary to set pri_tb_hi/lo */569- while (sec_tb_reset < 2)570- mb();571-572- /* set our stuff the same as the primary */573- local_irq_save(flags);574- set_dec(1);575- set_tb(pri_tb_hi, pri_tb_lo);576- last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp;577- mb();578-579- /* tell the primary we're done */580- sec_tb_reset = 0;581- mb();582- local_irq_restore(flags);583-}584-585-/* not __init, called in sleep/wakeup code */586-void smp_core99_give_timebase(void)587-{588- unsigned long flags;589- unsigned int t;590-591- /* wait for the secondary to be in take_timebase */592- for (t = 100000; t > 0 && !sec_tb_reset; --t)593- udelay(10);594- if (!sec_tb_reset) {595- printk(KERN_WARNING "Timeout waiting sync on second CPU\n");596- return;597- }598-599- /* freeze the timebase and read it */600- /* disable interrupts so the timebase is disabled for the601- shortest possible time */602- local_irq_save(flags);603- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);604- pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);605- mb();606- pri_tb_hi = get_tbu();607- pri_tb_lo = get_tbl();608- pri_tb_stamp = last_jiffy_stamp(smp_processor_id());609- mb();610-611- /* tell the secondary we're ready */612- sec_tb_reset = 2;613- mb();614-615- /* wait for the secondary to have taken it */616- for (t = 100000; t > 0 && sec_tb_reset; --t)617- udelay(10);618- if (sec_tb_reset)619- printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");620- else621- smp_tb_synchronized = 1;622-623- /* Now, restart the timebase by leaving the GPIO to an open collector */624- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);625- pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);626- local_irq_restore(flags);627-}628-629-630-/* PowerSurge-style Macs */631-struct smp_ops_t psurge_smp_ops = {632- .message_pass = smp_psurge_message_pass,633- .probe = smp_psurge_probe,634- .kick_cpu = smp_psurge_kick_cpu,635- .setup_cpu = smp_psurge_setup_cpu,636- .give_timebase = smp_psurge_give_timebase,637- .take_timebase = smp_psurge_take_timebase,638-};639-640-/* Core99 Macs (dual G4s) */641-struct smp_ops_t core99_smp_ops = {642- .message_pass = smp_openpic_message_pass,643- .probe = smp_core99_probe,644- .kick_cpu = smp_core99_kick_cpu,645- .setup_cpu = smp_core99_setup_cpu,646- .give_timebase = smp_core99_give_timebase,647- .take_timebase = smp_core99_take_timebase,648-};649-650-#ifdef CONFIG_HOTPLUG_CPU651-652-int __cpu_disable(void)653-{654- cpu_clear(smp_processor_id(), cpu_online_map);655-656- /* XXX reset cpu affinity here */657- openpic_set_priority(0xf);658- asm volatile("mtdec %0" : : "r" (0x7fffffff));659- mb();660- udelay(20);661- asm volatile("mtdec %0" : : "r" (0x7fffffff));662- return 0;663-}664-665-extern void low_cpu_die(void) __attribute__((noreturn)); /* in pmac_sleep.S */666-static int cpu_dead[NR_CPUS];667-668-void cpu_die(void)669-{670- local_irq_disable();671- cpu_dead[smp_processor_id()] = 1;672- mb();673- low_cpu_die();674-}675-676-void __cpu_die(unsigned int cpu)677-{678- int timeout;679-680- timeout = 1000;681- while (!cpu_dead[cpu]) {682- if (--timeout == 0) {683- printk("CPU %u refused to die!\n", cpu);684- break;685- }686- msleep(1);687- }688- cpu_callin_map[cpu] = 0;689- cpu_dead[cpu] = 0;690-}691-692-#endif
···167extern int of_pci_address_to_resource(struct device_node *dev, int bar,168 struct resource *r);16900000000170171#endif /* _PPC_PROM_H */172#endif /* __KERNEL__ */
···167extern int of_pci_address_to_resource(struct device_node *dev, int bar,168 struct resource *r);169170+#ifndef CONFIG_PPC_OF171+/*172+ * Fallback definitions for builds where we don't have prom.c included.173+ */174+#define machine_is_compatible(x) 0175+#define of_find_compatible_node(f, t, c) NULL176+#define get_property(p, n, l) NULL177+#endif178179#endif /* _PPC_PROM_H */180#endif /* __KERNEL__ */