diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-14 18:21:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-02-14 18:21:25 -0500 |
commit | ebf4bcbd5f249afc8f48a7aa32255f8ebbff5876 (patch) | |
tree | 47fdb196fc109411d4524bf2c25d88a6d5470477 /arch | |
parent | 8b36ac50da8e12d0469a7268ddbd6cab29307deb (diff) | |
parent | 778a785f02ad846446e91dab49331bd7d853c514 (diff) |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Quoth BenH:
"Here are a few powerpc fixes for 3.3, all pretty trivial. I also
added the patch to define GET_IP/SET_IP so we can use some more
asm-generic goodness."
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
powerpc/pseries/eeh: Fix crash when error happens during device probe
powerpc/pseries: Fix partition migration hang in stop_topology_update
powerpc/powernv: Disable interrupts while taking phb->lock
powerpc: Fix WARN_ON in decrementer_check_overflow
powerpc/wsp: Fix IRQ affinity setting
powerpc: Implement GET_IP/SET_IP
powerpc/wsp: Permanently enable PCI class code workaround
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/ppc-pci.h | 5 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ptrace.h | 20 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 22 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/suspend.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/wsp/ics.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/wsp/wsp_pci.c | 8 |
9 files changed, 51 insertions, 27 deletions
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index 43268f15004e..6d422979ebaf 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h | |||
@@ -142,6 +142,11 @@ static inline const char *eeh_pci_name(struct pci_dev *pdev) | |||
142 | return pdev ? pci_name(pdev) : "<null>"; | 142 | return pdev ? pci_name(pdev) : "<null>"; |
143 | } | 143 | } |
144 | 144 | ||
145 | static inline const char *eeh_driver_name(struct pci_dev *pdev) | ||
146 | { | ||
147 | return (pdev && pdev->driver) ? pdev->driver->name : "<null>"; | ||
148 | } | ||
149 | |||
145 | #endif /* CONFIG_EEH */ | 150 | #endif /* CONFIG_EEH */ |
146 | 151 | ||
147 | #else /* CONFIG_PCI */ | 152 | #else /* CONFIG_PCI */ |
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 78a205162fd7..84cc7840cd18 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -83,8 +83,18 @@ struct pt_regs { | |||
83 | 83 | ||
84 | #ifndef __ASSEMBLY__ | 84 | #ifndef __ASSEMBLY__ |
85 | 85 | ||
86 | #define instruction_pointer(regs) ((regs)->nip) | 86 | #define GET_IP(regs) ((regs)->nip) |
87 | #define user_stack_pointer(regs) ((regs)->gpr[1]) | 87 | #define GET_USP(regs) ((regs)->gpr[1]) |
88 | #define GET_FP(regs) (0) | ||
89 | #define SET_FP(regs, val) | ||
90 | |||
91 | #ifdef CONFIG_SMP | ||
92 | extern unsigned long profile_pc(struct pt_regs *regs); | ||
93 | #define profile_pc profile_pc | ||
94 | #endif | ||
95 | |||
96 | #include <asm-generic/ptrace.h> | ||
97 | |||
88 | #define kernel_stack_pointer(regs) ((regs)->gpr[1]) | 98 | #define kernel_stack_pointer(regs) ((regs)->gpr[1]) |
89 | static inline int is_syscall_success(struct pt_regs *regs) | 99 | static inline int is_syscall_success(struct pt_regs *regs) |
90 | { | 100 | { |
@@ -99,12 +109,6 @@ static inline long regs_return_value(struct pt_regs *regs) | |||
99 | return -regs->gpr[3]; | 109 | return -regs->gpr[3]; |
100 | } | 110 | } |
101 | 111 | ||
102 | #ifdef CONFIG_SMP | ||
103 | extern unsigned long profile_pc(struct pt_regs *regs); | ||
104 | #else | ||
105 | #define profile_pc(regs) instruction_pointer(regs) | ||
106 | #endif | ||
107 | |||
108 | #ifdef __powerpc64__ | 112 | #ifdef __powerpc64__ |
109 | #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1) | 113 | #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1) |
110 | #else | 114 | #else |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 701d4aceb4f4..01e2877e8e04 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -118,10 +118,14 @@ static inline notrace void set_soft_enabled(unsigned long enable) | |||
118 | static inline notrace void decrementer_check_overflow(void) | 118 | static inline notrace void decrementer_check_overflow(void) |
119 | { | 119 | { |
120 | u64 now = get_tb_or_rtc(); | 120 | u64 now = get_tb_or_rtc(); |
121 | u64 *next_tb = &__get_cpu_var(decrementers_next_tb); | 121 | u64 *next_tb; |
122 | |||
123 | preempt_disable(); | ||
124 | next_tb = &__get_cpu_var(decrementers_next_tb); | ||
122 | 125 | ||
123 | if (now >= *next_tb) | 126 | if (now >= *next_tb) |
124 | set_dec(1); | 127 | set_dec(1); |
128 | preempt_enable(); | ||
125 | } | 129 | } |
126 | 130 | ||
127 | notrace void arch_local_irq_restore(unsigned long en) | 131 | notrace void arch_local_irq_restore(unsigned long en) |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 517b1d8f455b..9f843cdfee9e 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -716,7 +716,6 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w | |||
716 | int cpu; | 716 | int cpu; |
717 | 717 | ||
718 | slb_set_size(SLB_MIN_SIZE); | 718 | slb_set_size(SLB_MIN_SIZE); |
719 | stop_topology_update(); | ||
720 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id()); | 719 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id()); |
721 | 720 | ||
722 | while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) && | 721 | while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) && |
@@ -732,7 +731,6 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w | |||
732 | rc = atomic_read(&data->error); | 731 | rc = atomic_read(&data->error); |
733 | 732 | ||
734 | atomic_set(&data->error, rc); | 733 | atomic_set(&data->error, rc); |
735 | start_topology_update(); | ||
736 | pSeries_coalesce_init(); | 734 | pSeries_coalesce_init(); |
737 | 735 | ||
738 | if (wake_when_done) { | 736 | if (wake_when_done) { |
@@ -846,6 +844,7 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
846 | atomic_set(&data.error, 0); | 844 | atomic_set(&data.error, 0); |
847 | data.token = rtas_token("ibm,suspend-me"); | 845 | data.token = rtas_token("ibm,suspend-me"); |
848 | data.complete = &done; | 846 | data.complete = &done; |
847 | stop_topology_update(); | ||
849 | 848 | ||
850 | /* Call function on all CPUs. One of us will make the | 849 | /* Call function on all CPUs. One of us will make the |
851 | * rtas call | 850 | * rtas call |
@@ -858,6 +857,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
858 | if (atomic_read(&data.error) != 0) | 857 | if (atomic_read(&data.error) != 0) |
859 | printk(KERN_ERR "Error doing global join\n"); | 858 | printk(KERN_ERR "Error doing global join\n"); |
860 | 859 | ||
860 | start_topology_update(); | ||
861 | |||
861 | return atomic_read(&data.error); | 862 | return atomic_read(&data.error); |
862 | } | 863 | } |
863 | #else /* CONFIG_PPC_PSERIES */ | 864 | #else /* CONFIG_PPC_PSERIES */ |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index a70bc1e385eb..f92b9ef7340e 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -52,32 +52,38 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) | |||
52 | 52 | ||
53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) | 53 | static unsigned int pnv_get_one_msi(struct pnv_phb *phb) |
54 | { | 54 | { |
55 | unsigned int id; | 55 | unsigned long flags; |
56 | unsigned int id, rc; | ||
57 | |||
58 | spin_lock_irqsave(&phb->lock, flags); | ||
56 | 59 | ||
57 | spin_lock(&phb->lock); | ||
58 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); | 60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next); |
59 | if (id >= phb->msi_count && phb->msi_next) | 61 | if (id >= phb->msi_count && phb->msi_next) |
60 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); | 62 | id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0); |
61 | if (id >= phb->msi_count) { | 63 | if (id >= phb->msi_count) { |
62 | spin_unlock(&phb->lock); | 64 | rc = 0; |
63 | return 0; | 65 | goto out; |
64 | } | 66 | } |
65 | __set_bit(id, phb->msi_map); | 67 | __set_bit(id, phb->msi_map); |
66 | spin_unlock(&phb->lock); | 68 | rc = id + phb->msi_base; |
67 | return id + phb->msi_base; | 69 | out: |
70 | spin_unlock_irqrestore(&phb->lock, flags); | ||
71 | return rc; | ||
68 | } | 72 | } |
69 | 73 | ||
70 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) | 74 | static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq) |
71 | { | 75 | { |
76 | unsigned long flags; | ||
72 | unsigned int id; | 77 | unsigned int id; |
73 | 78 | ||
74 | if (WARN_ON(hwirq < phb->msi_base || | 79 | if (WARN_ON(hwirq < phb->msi_base || |
75 | hwirq >= (phb->msi_base + phb->msi_count))) | 80 | hwirq >= (phb->msi_base + phb->msi_count))) |
76 | return; | 81 | return; |
77 | id = hwirq - phb->msi_base; | 82 | id = hwirq - phb->msi_base; |
78 | spin_lock(&phb->lock); | 83 | |
84 | spin_lock_irqsave(&phb->lock, flags); | ||
79 | __clear_bit(id, phb->msi_map); | 85 | __clear_bit(id, phb->msi_map); |
80 | spin_unlock(&phb->lock); | 86 | spin_unlock_irqrestore(&phb->lock, flags); |
81 | } | 87 | } |
82 | 88 | ||
83 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 89 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 565869022e3d..c0b40af4ce4f 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -551,9 +551,9 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
551 | printk (KERN_ERR "EEH: %d reads ignored for recovering device at " | 551 | printk (KERN_ERR "EEH: %d reads ignored for recovering device at " |
552 | "location=%s driver=%s pci addr=%s\n", | 552 | "location=%s driver=%s pci addr=%s\n", |
553 | pdn->eeh_check_count, location, | 553 | pdn->eeh_check_count, location, |
554 | dev->driver->name, eeh_pci_name(dev)); | 554 | eeh_driver_name(dev), eeh_pci_name(dev)); |
555 | printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n", | 555 | printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n", |
556 | dev->driver->name); | 556 | eeh_driver_name(dev)); |
557 | dump_stack(); | 557 | dump_stack(); |
558 | } | 558 | } |
559 | goto dn_unlock; | 559 | goto dn_unlock; |
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index b84a8b2238dd..47226e04126d 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/machdep.h> | 24 | #include <asm/machdep.h> |
25 | #include <asm/mmu.h> | 25 | #include <asm/mmu.h> |
26 | #include <asm/rtas.h> | 26 | #include <asm/rtas.h> |
27 | #include <asm/topology.h> | ||
27 | 28 | ||
28 | static u64 stream_id; | 29 | static u64 stream_id; |
29 | static struct device suspend_dev; | 30 | static struct device suspend_dev; |
@@ -138,8 +139,11 @@ static ssize_t store_hibernate(struct device *dev, | |||
138 | ssleep(1); | 139 | ssleep(1); |
139 | } while (rc == -EAGAIN); | 140 | } while (rc == -EAGAIN); |
140 | 141 | ||
141 | if (!rc) | 142 | if (!rc) { |
143 | stop_topology_update(); | ||
142 | rc = pm_suspend(PM_SUSPEND_MEM); | 144 | rc = pm_suspend(PM_SUSPEND_MEM); |
145 | start_topology_update(); | ||
146 | } | ||
143 | 147 | ||
144 | stream_id = 0; | 148 | stream_id = 0; |
145 | 149 | ||
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c index 576874392543..97fe82ee8633 100644 --- a/arch/powerpc/platforms/wsp/ics.c +++ b/arch/powerpc/platforms/wsp/ics.c | |||
@@ -346,7 +346,7 @@ static int wsp_chip_set_affinity(struct irq_data *d, | |||
346 | * For the moment only implement delivery to all cpus or one cpu. | 346 | * For the moment only implement delivery to all cpus or one cpu. |
347 | * Get current irq_server for the given irq | 347 | * Get current irq_server for the given irq |
348 | */ | 348 | */ |
349 | ret = cache_hwirq_map(ics, d->irq, cpumask); | 349 | ret = cache_hwirq_map(ics, hw_irq, cpumask); |
350 | if (ret == -1) { | 350 | if (ret == -1) { |
351 | char cpulist[128]; | 351 | char cpulist[128]; |
352 | cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); | 352 | cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); |
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c index e0262cd0e2d3..d24b3acf858e 100644 --- a/arch/powerpc/platforms/wsp/wsp_pci.c +++ b/arch/powerpc/platforms/wsp/wsp_pci.c | |||
@@ -468,15 +468,15 @@ static void __init wsp_pcie_configure_hw(struct pci_controller *hose) | |||
468 | #define DUMP_REG(x) \ | 468 | #define DUMP_REG(x) \ |
469 | pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x)) | 469 | pr_debug("%-30s : 0x%016llx\n", #x, in_be64(hose->cfg_data + x)) |
470 | 470 | ||
471 | #ifdef CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS | 471 | /* |
472 | /* WSP DD1 has a bogus class code by default in the PCI-E | 472 | * Some WSP variants has a bogus class code by default in the PCI-E |
473 | * root complex's built-in P2P bridge */ | 473 | * root complex's built-in P2P bridge |
474 | */ | ||
474 | val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1); | 475 | val = in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1); |
475 | pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val); | 476 | pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", val); |
476 | out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1, | 477 | out_be64(hose->cfg_data + PCIE_REG_SYS_CFG1, |
477 | (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8)); | 478 | (val & ~PCIE_REG_SYS_CFG1_CLASS_CODE) | (PCI_CLASS_BRIDGE_PCI << 8)); |
478 | pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1)); | 479 | pr_debug("PCI-E SYS_CFG1 : 0x%llx\n", in_be64(hose->cfg_data + PCIE_REG_SYS_CFG1)); |
479 | #endif /* CONFIG_WSP_DD1_WORKAROUND_BAD_PCIE_CLASS */ | ||
480 | 480 | ||
481 | #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS | 481 | #ifdef CONFIG_WSP_DD1_WORKAROUND_DD1_TCE_BUGS |
482 | /* XXX Disable TCE caching, it doesn't work on DD1 */ | 482 | /* XXX Disable TCE caching, it doesn't work on DD1 */ |