diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r-- | arch/powerpc/platforms/pseries/Kconfig | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/Makefile | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 204 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_driver.c | 78 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_event.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/firmware.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hotplug-cpu.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 67 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/nvram.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pci.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/ras.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/rtasd.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 44 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 17 |
16 files changed, 243 insertions, 212 deletions
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index a57032cf6f1..16e4e401b82 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -1,3 +1,13 @@ +config PPC_PSERIES + depends on PPC_MULTIPLATFORM && PPC64 + bool "IBM pSeries & new (POWER5-based) iSeries" + select MPIC + select PPC_I8259 + select PPC_RTAS + select RTAS_ERROR_LOGGING + select PPC_UDBG_16550 + select PPC_NATIVE + default y config PPC_SPLPAR depends on PPC_PSERIES diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 2dfd05095a2..90235d59875 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -2,14 +2,15 @@ ifeq ($(CONFIG_PPC64),y) EXTRA_CFLAGS += -mno-minimal-toc endif -obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ - setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ +obj-y := lpar.o hvCall.o nvram.o reconfig.o \ + setup.o iommu.o ras.o rtasd.o \ firmware.o power.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o obj-$(CONFIG_KEXEC) += kexec.o +obj-$(CONFIG_PCI) += pci.o pci_dlpar.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 6cedbc002e0..48fbd442e9d 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -74,7 +74,10 @@ * is broken and panic. This sets the threshold for how many read * attempts we allow before panicking. */ -#define EEH_MAX_FAILS 100000 +#define EEH_MAX_FAILS 2100000 + +/* Time to wait for a PCI slot to retport status, in milliseconds */ +#define PCI_BUS_RESET_WAIT_MSEC (60*1000) /* RTAS tokens */ static int ibm_set_eeh_option; @@ -83,6 +86,7 @@ static int ibm_read_slot_reset_state; static int ibm_read_slot_reset_state2; static int ibm_slot_error_detail; static int ibm_get_config_addr_info; +static int ibm_get_config_addr_info2; static int ibm_configure_bridge; int eeh_subsystem_enabled; @@ -168,6 +172,55 @@ static int read_slot_reset_state(struct pci_dn *pdn, int rets[]) } /** + * eeh_wait_for_slot_status - returns error status of slot + * @pdn pci device node + * @max_wait_msecs maximum number to millisecs to wait + * + * Return negative value if a permanent error, else return + * Partition Endpoint (PE) status value. + * + * If @max_wait_msecs is positive, then this routine will + * sleep until a valid status can be obtained, or until + * the max allowed wait time is exceeded, in which case + * a -2 is returned. + */ +int +eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs) +{ + int rc; + int rets[3]; + int mwait; + + while (1) { + rc = read_slot_reset_state(pdn, rets); + if (rc) return rc; + if (rets[1] == 0) return -1; /* EEH is not supported */ + + if (rets[0] != 5) return rets[0]; /* return actual status */ + + if (rets[2] == 0) return -1; /* permanently unavailable */ + + if (max_wait_msecs <= 0) return -1; + + mwait = rets[2]; + if (mwait <= 0) { + printk (KERN_WARNING + "EEH: Firmware returned bad wait value=%d\n", mwait); + mwait = 1000; + } else if (mwait > 300*1000) { + printk (KERN_WARNING + "EEH: Firmware is taking too long, time=%d\n", mwait); + mwait = 300*1000; + } + max_wait_msecs -= mwait; + msleep (mwait); + } + + printk(KERN_WARNING "EEH: Timed out waiting for slot status\n"); + return -2; +} + +/** * eeh_token_to_phys - convert EEH address token to phys address * @token i/o token, should be address in the form 0xA.... */ @@ -229,7 +282,7 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag) dn = find_device_pe (dn); /* Back up one, since config addrs might be shared */ - if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr) + if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent)) dn = dn->parent; PCI_DN(dn)->eeh_mode |= mode_flag; @@ -263,7 +316,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag) dn = find_device_pe (dn); /* Back up one, since config addrs might be shared */ - if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr) + if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent)) dn = dn->parent; PCI_DN(dn)->eeh_mode &= ~mode_flag; @@ -293,7 +346,6 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) int rets[3]; unsigned long flags; struct pci_dn *pdn; - enum pci_channel_state state; int rc = 0; total_mmio_ffs++; @@ -367,25 +419,25 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) goto dn_unlock; } - /* If EEH is not supported on this device, punt. */ - if (rets[1] != 1) { - printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n", - ret, dn->full_name); + /* Note that config-io to empty slots may fail; + * they are empty when they don't have children. */ + if ((rets[0] == 5) && (dn->child == NULL)) { false_positives++; rc = 0; goto dn_unlock; } - /* If not the kind of error we know about, punt. */ - if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) { + /* If EEH is not supported on this device, punt. */ + if (rets[1] != 1) { + printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n", + ret, dn->full_name); false_positives++; rc = 0; goto dn_unlock; } - /* Note that config-io to empty slots may fail; - * we recognize empty because they don't have children. */ - if ((rets[0] == 5) && (dn->child == NULL)) { + /* If not the kind of error we know about, punt. */ + if (rets[0] != 1 && rets[0] != 2 && rets[0] != 4 && rets[0] != 5) { false_positives++; rc = 0; goto dn_unlock; @@ -399,17 +451,12 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) eeh_mark_slot (dn, EEH_MODE_ISOLATED); spin_unlock_irqrestore(&confirm_error_lock, flags); - state = pci_channel_io_normal; - if ((rets[0] == 2) || (rets[0] == 4)) - state = pci_channel_io_frozen; - if (rets[0] == 5) - state = pci_channel_io_perm_failure; - eeh_send_failure_event (dn, dev, state, rets[2]); + eeh_send_failure_event (dn, dev); /* Most EEH events are due to device driver bugs. Having * a stack trace will help the device-driver authors figure * out what happened. So print that out. */ - if (rets[0] != 5) dump_stack(); + dump_stack(); return 1; dn_unlock: @@ -458,38 +505,6 @@ EXPORT_SYMBOL(eeh_check_failure); /* The code below deals with error recovery */ /** - * eeh_slot_availability - returns error status of slot - * @pdn pci device node - * - * Return negative value if a permanent error, else return - * a number of milliseconds to wait until the PCI slot is - * ready to be used. - */ -static int -eeh_slot_availability(struct pci_dn *pdn) -{ - int rc; - int rets[3]; - - rc = read_slot_reset_state(pdn, rets); - - if (rc) return rc; - - if (rets[1] == 0) return -1; /* EEH is not supported */ - if (rets[0] == 0) return 0; /* Oll Korrect */ - if (rets[0] == 5) { - if (rets[2] == 0) return -1; /* permanently unavailable */ - return rets[2]; /* number of millisecs to wait */ - } - if (rets[0] == 1) - return 250; - - printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", - rc, rets[0], rets[1], rets[2]); - return -2; -} - -/** * rtas_pci_enable - enable MMIO or DMA transfers for this slot * @pdn pci device node */ @@ -512,9 +527,13 @@ rtas_pci_enable(struct pci_dn *pdn, int function) function); if (rc) - printk(KERN_WARNING "EEH: Cannot enable function %d, err=%d dn=%s\n", + printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n", function, rc, pdn->node->full_name); + rc = eeh_wait_for_slot_status (pdn, PCI_BUS_RESET_WAIT_MSEC); + if ((rc == 4) && (function == EEH_THAW_MMIO)) + return 0; + return rc; } @@ -595,36 +614,24 @@ int rtas_set_slot_reset(struct pci_dn *pdn) { int i, rc; - __rtas_set_slot_reset(pdn); + /* Take three shots at resetting the bus */ + for (i=0; i<3; i++) { + __rtas_set_slot_reset(pdn); - /* Now double check with the firmware to make sure the device is - * ready to be used; if not, wait for recovery. */ - for (i=0; i<10; i++) { - rc = eeh_slot_availability (pdn); + rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC); if (rc == 0) return 0; - if (rc == -2) { - printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", - i, pdn->node->full_name); - __rtas_set_slot_reset(pdn); - continue; - } - if (rc < 0) { printk (KERN_ERR "EEH: unrecoverable slot failure %s\n", pdn->node->full_name); return -1; } - - msleep (rc+100); + printk (KERN_ERR "EEH: bus reset %d failed on slot %s\n", + i+1, pdn->node->full_name); } - rc = eeh_slot_availability (pdn); - if (rc) - printk (KERN_ERR "EEH: timeout resetting slot %s\n", pdn->node->full_name); - - return rc; + return -1; } /* ------------------------------------------------------- */ @@ -744,16 +751,48 @@ struct eeh_early_enable_info { unsigned int buid_lo; }; +static int get_pe_addr (int config_addr, + struct eeh_early_enable_info *info) +{ + unsigned int rets[3]; + int ret; + + /* Use latest config-addr token on power6 */ + if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) { + /* Make sure we have a PE in hand */ + ret = rtas_call (ibm_get_config_addr_info2, 4, 2, rets, + config_addr, info->buid_hi, info->buid_lo, 1); + if (ret || (rets[0]==0)) + return 0; + + ret = rtas_call (ibm_get_config_addr_info2, 4, 2, rets, + config_addr, info->buid_hi, info->buid_lo, 0); + if (ret) + return 0; + return rets[0]; + } + + /* Use older config-addr token on power5 */ + if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { + ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets, + config_addr, info->buid_hi, info->buid_lo, 0); + if (ret) + return 0; + return rets[0]; + } + return 0; +} + /* Enable eeh for the given device node. */ static void *early_enable_eeh(struct device_node *dn, void *data) { unsigned int rets[3]; struct eeh_early_enable_info *info = data; int ret; - const char *status = get_property(dn, "status", NULL); - const u32 *class_code = get_property(dn, "class-code", NULL); - const u32 *vendor_id = get_property(dn, "vendor-id", NULL); - const u32 *device_id = get_property(dn, "device-id", NULL); + const char *status = of_get_property(dn, "status", NULL); + const u32 *class_code = of_get_property(dn, "class-code", NULL); + const u32 *vendor_id = of_get_property(dn, "vendor-id", NULL); + const u32 *device_id = of_get_property(dn, "device-id", NULL); const u32 *regs; int enable; struct pci_dn *pdn = PCI_DN(dn); @@ -796,7 +835,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) /* Ok... see if this device supports EEH. Some do, some don't, * and the only way to find out is to check each and every one. */ - regs = get_property(dn, "reg", NULL); + regs = of_get_property(dn, "reg", NULL); if (regs) { /* First register entry is addr (00BBSS00) */ /* Try to enable eeh */ @@ -810,15 +849,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data) /* If the newer, better, ibm,get-config-addr-info is supported, * then use that instead. */ - pdn->eeh_pe_config_addr = 0; - if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { - ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets, - pdn->eeh_config_addr, - info->buid_hi, info->buid_lo, - 0); - if (ret == 0) - pdn->eeh_pe_config_addr = rets[0]; - } + pdn->eeh_pe_config_addr = get_pe_addr(pdn->eeh_config_addr, info); /* Some older systems (Power4) allow the * ibm,set-eeh-option call to succeed even on nodes @@ -889,6 +920,7 @@ void __init eeh_init(void) ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); ibm_slot_error_detail = rtas_token("ibm,slot-error-detail"); ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); + ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); ibm_configure_bridge = rtas_token ("ibm,configure-bridge"); if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index a4c0bf84ef2..3170e003f76 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -158,7 +158,8 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) return; rc = driver->err_handler->slot_reset(dev); - if (*res == PCI_ERS_RESULT_NONE) *res = rc; + if ((*res == PCI_ERS_RESULT_NONE) || + (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc; if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; } @@ -248,6 +249,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) { + struct device_node *dn; int cnt, rc; /* pcibios will clear the counter; save the value */ @@ -263,23 +265,20 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) if (rc) return rc; - /* New-style config addrs might be shared across multiple devices, - * Walk over all functions on this device */ - if (pe_dn->eeh_pe_config_addr) { - struct device_node *pe = pe_dn->node; - pe = pe->parent->child; - while (pe) { - struct pci_dn *ppe = PCI_DN(pe); - if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) { - rtas_configure_bridge(ppe); - eeh_restore_bars(ppe); - } - pe = pe->sibling; + /* Walk over all functions on this device. */ + dn = pe_dn->node; + if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent)) + dn = dn->parent->child; + + while (dn) { + struct pci_dn *ppe = PCI_DN(dn); + /* On Power4, always true because eeh_pe_config_addr=0 */ + if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) { + rtas_configure_bridge(ppe); + eeh_restore_bars(ppe); } - } else { - rtas_configure_bridge(pe_dn); - eeh_restore_bars(pe_dn); - } + dn = dn->sibling; + } /* Give the system 5 seconds to finish running the user-space * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, @@ -299,7 +298,7 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) /* The longest amount of time to wait for a pci device * to come back on line, in seconds. */ -#define MAX_WAIT_FOR_RECOVERY 15 +#define MAX_WAIT_FOR_RECOVERY 150 struct pci_dn * handle_eeh_events (struct eeh_event *event) { @@ -315,14 +314,14 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (!frozen_dn) { - location = get_property(event->dn, "ibm,loc-code", NULL); + location = of_get_property(event->dn, "ibm,loc-code", NULL); location = location ? location : "unknown"; printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " "for location=%s pci addr=%s\n", location, pci_name(event->dev)); return NULL; } - location = get_property(frozen_dn, "ibm,loc-code", NULL); + location = of_get_property(frozen_dn, "ibm,loc-code", NULL); location = location ? location : "unknown"; /* There are two different styles for coming up with the PE. @@ -341,13 +340,6 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) return NULL; } -#if 0 - /* We may get "permanent failure" messages on empty slots. - * These are false alarms. Empty slots have no child dn. */ - if ((event->state == pci_channel_io_perm_failure) && (frozen_device == NULL)) - return; -#endif - frozen_pdn = PCI_DN(frozen_dn); frozen_pdn->eeh_freeze_count++; @@ -362,13 +354,12 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) goto excess_failures; - /* If the reset state is a '5' and the time to reset is 0 (infinity) - * or is more then 15 seconds, then mark this as a permanent failure. - */ - if ((event->state == pci_channel_io_perm_failure) && - ((event->time_unavail <= 0) || - (event->time_unavail > MAX_WAIT_FOR_RECOVERY*1000))) + /* Get the current PCI slot state. */ + rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000); + if (rc < 0) { + printk(KERN_WARNING "EEH: Permanent failure\n"); goto hard_fail; + } eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); printk(KERN_WARNING @@ -390,14 +381,18 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) */ if (result == PCI_ERS_RESULT_NONE) { rc = eeh_reset_device(frozen_pdn, frozen_bus); - if (rc) + if (rc) { + printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc); goto hard_fail; + } } /* If all devices reported they can proceed, then re-enable MMIO */ if (result == PCI_ERS_RESULT_CAN_RECOVER) { rc = rtas_pci_enable(frozen_pdn, EEH_THAW_MMIO); + if (rc < 0) + goto hard_fail; if (rc) { result = PCI_ERS_RESULT_NEED_RESET; } else { @@ -410,6 +405,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (result == PCI_ERS_RESULT_CAN_RECOVER) { rc = rtas_pci_enable(frozen_pdn, EEH_THAW_DMA); + if (rc < 0) + goto hard_fail; if (rc) result = PCI_ERS_RESULT_NEED_RESET; else @@ -417,21 +414,28 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) } /* If any device has a hard failure, then shut off everything. */ - if (result == PCI_ERS_RESULT_DISCONNECT) + if (result == PCI_ERS_RESULT_DISCONNECT) { + printk(KERN_WARNING "EEH: Device driver gave up\n"); goto hard_fail; + } /* If any device called out for a reset, then reset the slot */ if (result == PCI_ERS_RESULT_NEED_RESET) { rc = eeh_reset_device(frozen_pdn, NULL); - if (rc) + if (rc) { + printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc); goto hard_fail; + } result = PCI_ERS_RESULT_NONE; pci_walk_bus(frozen_bus, eeh_report_reset, &result); } /* All devices should claim they have recovered by now. */ - if (result != PCI_ERS_RESULT_RECOVERED) + if ((result != PCI_ERS_RESULT_RECOVERED) && + (result != PCI_ERS_RESULT_NONE)) { + printk(KERN_WARNING "EEH: Not recovered\n"); goto hard_fail; + } /* Tell all device drivers that they can resume operations */ pci_walk_bus(frozen_bus, eeh_report_resume, NULL); diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index 49037edf7d3..ddb80f5d850 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -118,9 +118,7 @@ static void eeh_thread_launcher(struct work_struct *dummy) * (from a workqueue). */ int eeh_send_failure_event (struct device_node *dn, - struct pci_dev *dev, - enum pci_channel_state state, - int time_unavail) + struct pci_dev *dev) { unsigned long flags; struct eeh_event *event; @@ -128,7 +126,7 @@ int eeh_send_failure_event (struct device_node *dn, if (!mem_init_done) { printk(KERN_ERR "EEH: event during early boot not handled\n"); - location = get_property(dn, "ibm,loc-code", NULL); + location = of_get_property(dn, "ibm,loc-code", NULL); printk(KERN_ERR "EEH: device node = %s\n", dn->full_name); printk(KERN_ERR "EEH: PCI location = %s\n", location); return 1; @@ -144,8 +142,6 @@ int eeh_send_failure_event (struct device_node *dn, event->dn = dn; event->dev = dev; - event->state = state; - event->time_unavail = time_unavail; /* We may or may not be called in an interrupt context */ spin_lock_irqsave(&eeh_eventlist_lock, flags); diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index 90522e3c9d4..29bf83bfb1f 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -80,7 +80,7 @@ void __init fw_feature_init(void) goto out; } - hypertas = get_property(dn, "ibm,hypertas-functions", &len); + hypertas = of_get_property(dn, "ibm,hypertas-functions", &len); if (hypertas == NULL) goto out; diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index f460b9cbfd4..9711eb0d549 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -143,7 +143,7 @@ static int pseries_add_processor(struct device_node *np) int err = -ENOSPC, len, nthreads, i; const u32 *intserv; - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); if (!intserv) return 0; @@ -203,7 +203,7 @@ static void pseries_remove_processor(struct device_node *np) int len, nthreads, i; const u32 *intserv; - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); if (!intserv) return; diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index e6653a868b9..66665c82415 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -242,6 +242,7 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) return tce_ret; } +#ifdef CONFIG_PCI static void iommu_table_setparms(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl) @@ -252,8 +253,8 @@ static void iommu_table_setparms(struct pci_controller *phb, node = (struct device_node *)phb->arch_data; - basep = get_property(node, "linux,tce-base", NULL); - sizep = get_property(node, "linux,tce-size", NULL); + basep = of_get_property(node, "linux,tce-base", NULL); + sizep = of_get_property(node, "linux,tce-size", NULL); if (basep == NULL || sizep == NULL) { printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has " "missing tce entries !\n", dn->full_name); @@ -403,7 +404,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) /* Find nearest ibm,dma-window, walking up the device tree */ for (pdn = dn; pdn != NULL; pdn = pdn->parent) { - dma_window = get_property(pdn, "ibm,dma-window", NULL); + dma_window = of_get_property(pdn, "ibm,dma-window", NULL); if (dma_window != NULL) break; } @@ -478,29 +479,6 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) pci_name(dev)); } -static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) -{ - int err = NOTIFY_OK; - struct device_node *np = node; - struct pci_dn *pci = PCI_DN(np); - - switch (action) { - case PSERIES_RECONFIG_REMOVE: - if (pci && pci->iommu_table && - get_property(np, "ibm,dma-window", NULL)) - iommu_free_table(np); - break; - default: - err = NOTIFY_DONE; - break; - } - return err; -} - -static struct notifier_block iommu_reconfig_nb = { - .notifier_call = iommu_reconfig_notifier, -}; - static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) { struct device_node *pdn, *dn; @@ -521,7 +499,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { - dma_window = get_property(pdn, "ibm,dma-window", NULL); + dma_window = of_get_property(pdn, "ibm,dma-window", NULL); if (dma_window) break; } @@ -554,15 +532,44 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) dev->dev.archdata.dma_data = pci->iommu_table; } +#else /* CONFIG_PCI */ +#define pci_dma_bus_setup_pSeries NULL +#define pci_dma_dev_setup_pSeries NULL +#define pci_dma_bus_setup_pSeriesLP NULL +#define pci_dma_dev_setup_pSeriesLP NULL +#endif /* !CONFIG_PCI */ + +static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) +{ + int err = NOTIFY_OK; + struct device_node *np = node; + struct pci_dn *pci = PCI_DN(np); + + switch (action) { + case PSERIES_RECONFIG_REMOVE: + if (pci && pci->iommu_table && + of_get_property(np, "ibm,dma-window", NULL)) + iommu_free_table(np); + break; + default: + err = NOTIFY_DONE; + break; + } + return err; +} + +static struct notifier_block iommu_reconfig_nb = { + .notifier_call = iommu_reconfig_notifier, +}; /* These are called very early. */ void iommu_init_early_pSeries(void) { - if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) { + if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL)) { /* Direct I/O, IOMMU off */ ppc_md.pci_dma_dev_setup = NULL; ppc_md.pci_dma_bus_setup = NULL; - pci_dma_ops = &dma_direct_ops; + set_pci_dma_ops(&dma_direct_ops); return; } @@ -588,6 +595,6 @@ void iommu_init_early_pSeries(void) pSeries_reconfig_notifier_register(&iommu_reconfig_nb); - pci_dma_ops = &dma_iommu_ops; + set_pci_dma_ops(&dma_iommu_ops); } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 843ee964321..3a70e8ad7bc 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -209,13 +209,13 @@ void __init find_udbg_vterm(void) /* find the boot console from /chosen/stdout */ if (!of_chosen) return; - name = get_property(of_chosen, "linux,stdout-path", NULL); + name = of_get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) return; stdout_node = of_find_node_by_path(name); if (!stdout_node) return; - name = get_property(stdout_node, "name", NULL); + name = of_get_property(stdout_node, "name", NULL); if (!name) { printk(KERN_WARNING "stdout node missing 'name' property!\n"); goto out; @@ -226,7 +226,7 @@ void __init find_udbg_vterm(void) /* Check if it's a virtual terminal */ if (strncmp(name, "vty", 3) != 0) goto out; - termno = get_property(stdout_node, "reg", NULL); + termno = of_get_property(stdout_node, "reg", NULL); if (termno == NULL) goto out; vtermno = termno[0]; diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 64163cecdf9..f68903e15bd 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -130,7 +130,7 @@ int __init pSeries_nvram_init(void) if (nvram == NULL) return -ENODEV; - nbytes_p = get_property(nvram, "#bytes", &proplen); + nbytes_p = of_get_property(nvram, "#bytes", &proplen); if (nbytes_p == NULL || proplen != sizeof(unsigned int)) return -EIO; diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index fa59124ce3f..2c6ded29f73 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -25,6 +25,7 @@ #include <linux/pci.h> #include <linux/string.h> +#include <asm/eeh.h> #include <asm/pci-bridge.h> #include <asm/prom.h> #include <asm/ppc-pci.h> @@ -39,7 +40,7 @@ void pcibios_name_device(struct pci_dev *dev) */ dn = pci_device_to_OF_node(dev); if (dn) { - char *loc_code = get_property(dn, "ibm,loc-code", 0); + const char *loc_code = of_get_property(dn, "ibm,loc-code", 0); if (loc_code) { int loc_len = strlen(loc_code); if (loc_len < sizeof(dev->dev.name)) { diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index ac56b868913..fdc1a369f76 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -29,6 +29,7 @@ #include <asm/pci-bridge.h> #include <asm/ppc-pci.h> #include <asm/firmware.h> +#include <asm/eeh.h> static struct pci_bus * find_bus_among_children(struct pci_bus *bus, diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index edc03887311..53aa04101ce 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -85,7 +85,7 @@ static void request_ras_irqs(struct device_node *np, * map those interrupts using the default interrupt host and default * trigger */ - opicprop = get_property(np, "open-pic-interrupt", &opicplen); + opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); if (opicprop) { opicplen /= sizeof(u32); for (i = 0; i < opicplen; i++) { diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index 77d0937d5c0..9797b10b293 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c @@ -363,7 +363,7 @@ static int get_eventscan_parms(void) node = of_find_node_by_path("/rtas"); - ip = get_property(node, "rtas-event-scan-rate", NULL); + ip = of_get_property(node, "rtas-event-scan-rate", NULL); if (ip == NULL) { printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n"); of_node_put(node); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 34aff47b1f5..33eec2822c6 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -65,6 +65,7 @@ #include <asm/udbg.h> #include <asm/smp.h> #include <asm/firmware.h> +#include <asm/eeh.h> #include "plpar_wrappers.h" #include "pseries.h" @@ -92,7 +93,7 @@ static void pSeries_show_cpuinfo(struct seq_file *m) root = of_find_node_by_path("/"); if (root) - model = get_property(root, "model", NULL); + model = of_get_property(root, "model", NULL); seq_printf(m, "machine\t\t: CHRP %s\n", model); of_node_put(root); } @@ -138,8 +139,8 @@ static void __init pseries_mpic_init_IRQ(void) struct mpic *mpic; np = of_find_node_by_path("/"); - naddr = prom_n_addr_cells(np); - opprop = get_property(np, "platform-open-pic", &opplen); + naddr = of_n_addr_cells(np); + opprop = of_get_property(np, "platform-open-pic", &opplen); if (opprop != 0) { openpic_addr = of_read_number(opprop, naddr); printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); @@ -188,11 +189,11 @@ static void __init pseries_mpic_init_IRQ(void) break; if (strcmp(np->name, "pci") != 0) continue; - addrp = get_property(np, "8259-interrupt-acknowledge", + addrp = of_get_property(np, "8259-interrupt-acknowledge", NULL); if (addrp == NULL) continue; - naddr = prom_n_addr_cells(np); + naddr = of_n_addr_cells(np); intack = addrp[naddr-1]; if (naddr > 1) intack |= ((unsigned long)addrp[naddr-2]) << 32; @@ -225,7 +226,7 @@ static void __init pseries_discover_pic(void) for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) { - typep = get_property(np, "compatible", NULL); + typep = of_get_property(np, "compatible", NULL); if (strstr(typep, "open-pic")) { pSeries_mpic_node = of_node_get(np); ppc_md.init_IRQ = pseries_mpic_init_IRQ; @@ -334,32 +335,6 @@ static void __init pSeries_init_early(void) DBG(" <- pSeries_init_early()\n"); } - -static int pSeries_check_legacy_ioport(unsigned int baseport) -{ - struct device_node *np; - -#define I8042_DATA_REG 0x60 -#define FDC_BASE 0x3f0 - - - switch(baseport) { - case I8042_DATA_REG: - np = of_find_node_by_type(NULL, "8042"); - if (np == NULL) - return -ENODEV; - of_node_put(np); - break; - case FDC_BASE: - np = of_find_node_by_type(NULL, "fdc"); - if (np == NULL) - return -ENODEV; - of_node_put(np); - break; - } - return 0; -} - /* * Called very early, MMU is off, device-tree isn't unflattened */ @@ -514,6 +489,10 @@ void pSeries_power_off(void) for (;;); } +#ifndef CONFIG_PCI +void pSeries_final_fixup(void) { } +#endif + define_machine(pseries) { .name = "pSeries", .probe = pSeries_probe, @@ -532,7 +511,6 @@ define_machine(pseries) { .set_rtc_time = rtas_set_rtc_time, .calibrate_decr = generic_calibrate_decr, .progress = rtas_progress, - .check_legacy_ioport = pSeries_check_legacy_ioport, .system_reset_exception = pSeries_system_reset_exception, .machine_check_exception = pSeries_machine_check_exception, }; diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 81d172d6503..896cbf340c4 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -576,7 +576,7 @@ static void __init xics_init_one_node(struct device_node *np, * This happens to be the case so far but we are playing with fire... * should be fixed one of these days. -BenH. */ - ireg = get_property(np, "ibm,interrupt-server-ranges", NULL); + ireg = of_get_property(np, "ibm,interrupt-server-ranges", NULL); /* Do that ever happen ? we'll know soon enough... but even good'old * f80 does have that property .. @@ -588,7 +588,7 @@ static void __init xics_init_one_node(struct device_node *np, */ *indx = *ireg; } - ireg = get_property(np, "reg", &ilen); + ireg = of_get_property(np, "reg", &ilen); if (!ireg) panic("xics_init_IRQ: can't find interrupt reg property"); @@ -640,10 +640,10 @@ static void __init xics_setup_8259_cascade(void) break; if (strcmp(np->name, "pci") != 0) continue; - addrp = get_property(np, "8259-interrupt-acknowledge", NULL); + addrp = of_get_property(np, "8259-interrupt-acknowledge", NULL); if (addrp == NULL) continue; - naddr = prom_n_addr_cells(np); + naddr = of_n_addr_cells(np); intack = addrp[naddr-1]; if (naddr > 1) intack |= ((unsigned long)addrp[naddr-2]) << 32; @@ -664,10 +664,11 @@ static struct device_node *cpuid_to_of_node(int cpu) int i, len; const u32 *intserv; - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", + &len); if (!intserv) - intserv = get_property(np, "reg", &len); + intserv = of_get_property(np, "reg", &len); i = len / sizeof(u32); @@ -709,7 +710,7 @@ void __init xics_init_IRQ(void) /* Find the server numbers for the boot cpu. */ np = cpuid_to_of_node(boot_cpuid); BUG_ON(!np); - ireg = get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); + ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); if (!ireg) goto skip_gserver_check; i = ilen / sizeof(int); @@ -725,7 +726,7 @@ void __init xics_init_IRQ(void) default_server = hcpuid; default_distrib_server = ireg[j+1]; - isize = get_property(np, + isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); if (isize) interrupt_server_size = *isize; |