diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 4d6681dce8163c98f2f2f48828f67cf985dc49f6..c571cd3c14532db29777c07977582e736be5a9aa 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -575,13 +575,19 @@ __secondary_start: /* Initialize the kernel stack. Just a repeat for iSeries. */ LOAD_REG_ADDR(r3, current_set) sldi r28,r24,3 /* get current_set[cpu#] */ - ldx r1,r3,r28 - addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD - std r1,PACAKSAVE(r13) + ldx r14,r3,r28 + addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD + std r14,PACAKSAVE(r13) /* Do early setup for that CPU (stab, slb, hash table pointer) */ bl .early_setup_secondary + /* + * setup the new stack pointer, but *don't* use this until + * translation is on. + */ + mr r1, r14 + /* Clear backchain so we get nice backtraces */ li r7,0 mtlr r7 diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 6bbd7a604d243c9f8f9f906d683a9a20df2f9a43..a7a570dcdd571c8fb861562e549dbf094147fb32 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -810,6 +810,9 @@ relocate_new_kernel: isync sync + mfspr r3, SPRN_PIR /* current core we are running on */ + mr r4, r5 /* load physical address of chunk called */ + /* jump to the entry point, usually the setup routine */ mtlr r5 blrl diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index ce53dfa7130dfc74f551c2360746f206154cf925..8533b3b83f5d0e35b50fb39eefb663e6d81975b0 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -577,20 +577,11 @@ void timer_interrupt(struct pt_regs * regs) * some CPUs will continuue to take decrementer exceptions */ set_dec(DECREMENTER_MAX); -#ifdef CONFIG_PPC32 +#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); #endif - now = get_tb_or_rtc(); - if (now < decrementer->next_tb) { - /* not time for this event yet */ - now = decrementer->next_tb - now; - if (now <= DECREMENTER_MAX) - set_dec((int)now); - trace_timer_interrupt_exit(regs); - return; - } old_regs = set_irq_regs(regs); irq_enter(); @@ -606,8 +597,16 @@ void timer_interrupt(struct pt_regs * regs) get_lppaca()->int_dword.fields.decr_int = 0; #endif - if (evt->event_handler) - evt->event_handler(evt); + now = get_tb_or_rtc(); + if (now >= decrementer->next_tb) { + decrementer->next_tb = ~(u64)0; + if (evt->event_handler) + evt->event_handler(evt); + } else { + now = decrementer->next_tb - now; + if (now <= DECREMENTER_MAX) + set_dec((int)now); + } #ifdef CONFIG_PPC_ISERIES if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index f9751c8905be5db684a25555975a60b3b574d881..83068322abd154004325093e1db9a7b24b9da8d7 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -48,8 +48,10 @@ static int mpc837xmds_usb_cfg(void) return -1; np = of_find_node_by_name(NULL, "usb"); - if (!np) - return -ENODEV; + if (!np) { + ret = -ENODEV; + goto out; + } phy_type = of_get_property(np, "phy_type", NULL); if (phy_type && !strcmp(phy_type, "ulpi")) { clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); @@ -65,8 +67,9 @@ static int mpc837xmds_usb_cfg(void) } of_node_put(np); +out: iounmap(bcsr_regs); - return 0; + return ret; } /* ************************************************************************ diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index da64be19d0997b75518ea1cdde2ecd6a16cbf884..aa34cac4eb5cc5db47db0e233c32ea9dcf0c09f6 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -357,6 +357,7 @@ static void __init mpc85xx_mds_setup_arch(void) { #ifdef CONFIG_PCI struct pci_controller *hose; + struct device_node *np; #endif dma_addr_t max = 0xffffffff; diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index e1467c937450791af1ca1355176e780e22b6b86b..34e00902ce86229bf7aafe28eb5e5c9ae4a632e0 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -97,7 +97,7 @@ static void __init p1022_ds_setup_arch(void) #endif #ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() > max) { + if (memblock_end_of_DRAM() > max) { ppc_swiotlb_enable = 1; set_pci_dma_ops(&swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 227c1c3d585e028874cc895afc3241afff0b3caf..72d8054fa739055ddc03521aaa6e0ff961ca3670 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -129,20 +129,35 @@ struct device_node *dlpar_configure_connector(u32 drc_index) struct property *property; struct property *last_property = NULL; struct cc_workarea *ccwa; + char *data_buf; int cc_token; - int rc; + int rc = -1; cc_token = rtas_token("ibm,configure-connector"); if (cc_token == RTAS_UNKNOWN_SERVICE) return NULL; - spin_lock(&rtas_data_buf_lock); - ccwa = (struct cc_workarea *)&rtas_data_buf[0]; + data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); + if (!data_buf) + return NULL; + + ccwa = (struct cc_workarea *)&data_buf[0]; ccwa->drc_index = drc_index; ccwa->zero = 0; - rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); - while (rc) { + do { + /* Since we release the rtas_data_buf lock between configure + * connector calls we want to re-populate the rtas_data_buffer + * with the contents of the previous call. + */ + spin_lock(&rtas_data_buf_lock); + + memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE); + rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); + memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); + + spin_unlock(&rtas_data_buf_lock); + switch (rc) { case NEXT_SIBLING: dn = dlpar_parse_cc_node(ccwa); @@ -197,18 +212,19 @@ struct device_node *dlpar_configure_connector(u32 drc_index) "returned from configure-connector\n", rc); goto cc_error; } + } while (rc); - rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); +cc_error: + kfree(data_buf); + + if (rc) { + if (first_dn) + dlpar_free_cc_nodes(first_dn); + + return NULL; } - spin_unlock(&rtas_data_buf_lock); return first_dn; - -cc_error: - if (first_dn) - dlpar_free_cc_nodes(first_dn); - spin_unlock(&rtas_data_buf_lock); - return NULL; } static struct device_node *derive_parent(const char *path) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 209384b6e0396e232be5c0a53ed0519d3b5e6a3b..4ae933225251e0ae7312ea55f4e00732fc899911 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -399,6 +399,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header); diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 6425abe5b7dbfe809cd41d8a06634a56367d9d1d..3017532319c8d0df73ba36e3858c5368c17cccaf 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -240,12 +240,13 @@ struct rio_priv { static void __iomem *rio_regs_win; +#ifdef CONFIG_E500 static int (*saved_mcheck_exception)(struct pt_regs *regs); static int fsl_rio_mcheck_exception(struct pt_regs *regs) { const struct exception_table_entry *entry = NULL; - unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK); + unsigned long reason = mfspr(SPRN_MCSR); if (reason & MCSR_BUS_RBERR) { reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); @@ -269,6 +270,7 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs) else return cur_cpu_spec->machine_check(regs); } +#endif /** * fsl_rio_doorbell_send - Send a MPC85xx doorbell message @@ -1517,8 +1519,10 @@ int fsl_rio_setup(struct platform_device *dev) fsl_rio_doorbell_init(port); fsl_rio_port_write_init(port); +#ifdef CONFIG_E500 saved_mcheck_exception = ppc_md.machine_check_exception; ppc_md.machine_check_exception = fsl_rio_mcheck_exception; +#endif /* Ensure that RFXE is set */ mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000)); diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 3da8014931c9c7a99afcebf52814b50d03d02f35..90020de4dcf2c7570e371569997506e5642c8c5f 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -640,6 +640,7 @@ unsigned int qe_get_num_of_snums(void) if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { /* No QE ever has fewer than 28 SNUMs */ pr_err("QE: number of snum is invalid\n"); + of_node_put(qe); return -EINVAL; } } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f6a3b2d36cadde8e1a6684d1c9fdc408eebef9b2..10d33309e9a61351aa4d3597540f201c97dc9294 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2300,6 +2300,8 @@ #define PCI_DEVICE_ID_P2010 0x0079 #define PCI_DEVICE_ID_P1020E 0x0100 #define PCI_DEVICE_ID_P1020 0x0101 +#define PCI_DEVICE_ID_P1021E 0x0102 +#define PCI_DEVICE_ID_P1021 0x0103 #define PCI_DEVICE_ID_P1011E 0x0108 #define PCI_DEVICE_ID_P1011 0x0109 #define PCI_DEVICE_ID_P1022E 0x0110