diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-11 20:34:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-11 20:34:00 -0400 |
commit | fd9879b9bb3258ebc27a4cc6d2d29f528f71901f (patch) | |
tree | 48b68994f5e8083aafe116533e8143cb2bf30c85 /arch/powerpc/kernel | |
parent | 81ae31d78239318610d7c2acb3e2610d622a5aa4 (diff) | |
parent | d53ba6b3bba33432cc37b7101a86f8f3392c46e7 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux
Pull powerpc updates from Michael Ellerman:
"Here's a first pull request for powerpc updates for 3.18.
The bulk of the additions are for the "cxl" driver, for IBM's Coherent
Accelerator Processor Interface (CAPI). Most of it's in drivers/misc,
which Greg & Arnd maintain, Greg said he was happy for us to take it
through our tree.
There's the usual minor cleanups and fixes, including a bit of noise
in drivers from some of those. A bunch of updates to our EEH code,
which has been getting more testing. Several nice speedups from
Anton, including 20% in clear_page().
And a bunch of updates for freescale from Scott"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux: (130 commits)
cxl: Fix afu_read() not doing finish_wait() on signal or non-blocking
cxl: Add documentation for userspace APIs
cxl: Add driver to Kbuild and Makefiles
cxl: Add userspace header file
cxl: Driver code for powernv PCIe based cards for userspace access
cxl: Add base builtin support
powerpc/mm: Add hooks for cxl
powerpc/opal: Add PHB to cxl mode call
powerpc/mm: Add new hash_page_mm()
powerpc/powerpc: Add new PCIe functions for allocating cxl interrupts
cxl: Add new header for call backs and structs
powerpc/powernv: Split out set MSI IRQ chip code
powerpc/mm: Export mmu_kernel_ssize and mmu_linear_psize
powerpc/msi: Improve IRQ bitmap allocator
powerpc/cell: Make spu_flush_all_slbs() generic
powerpc/cell: Move data segment faulting code out of cell platform
powerpc/cell: Move spu_handle_mm_fault() out of cell platform
powerpc/pseries: Use new defines when calling H_SET_MODE
powerpc: Update contact info in Documentation files
powerpc/perf/hv-24x7: Simplify catalog_read()
...
Diffstat (limited to 'arch/powerpc/kernel')
32 files changed, 641 insertions, 448 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 670c312d914e..502cf69b6c89 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -93,6 +93,9 @@ obj-$(CONFIG_PPC32) += entry_32.o setup_32.o | |||
93 | obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o | 93 | obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o |
94 | obj-$(CONFIG_KGDB) += kgdb.o | 94 | obj-$(CONFIG_KGDB) += kgdb.o |
95 | obj-$(CONFIG_MODULES) += ppc_ksyms.o | 95 | obj-$(CONFIG_MODULES) += ppc_ksyms.o |
96 | ifeq ($(CONFIG_PPC32),y) | ||
97 | obj-$(CONFIG_MODULES) += ppc_ksyms_32.o | ||
98 | endif | ||
96 | obj-$(CONFIG_BOOTX_TEXT) += btext.o | 99 | obj-$(CONFIG_BOOTX_TEXT) += btext.o |
97 | obj-$(CONFIG_SMP) += smp.o | 100 | obj-$(CONFIG_SMP) += smp.o |
98 | obj-$(CONFIG_KPROBES) += kprobes.o | 101 | obj-$(CONFIG_KPROBES) += kprobes.o |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 7a13f378ca2c..c78e6dac4d7d 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/crash_dump.h> | 14 | #include <linux/crash_dump.h> |
15 | #include <linux/bootmem.h> | 15 | #include <linux/bootmem.h> |
16 | #include <linux/io.h> | ||
16 | #include <linux/memblock.h> | 17 | #include <linux/memblock.h> |
17 | #include <asm/code-patching.h> | 18 | #include <asm/code-patching.h> |
18 | #include <asm/kdump.h> | 19 | #include <asm/kdump.h> |
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index bd1a2aba599f..735979764cd4 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
@@ -106,10 +106,14 @@ int __init swiotlb_setup_bus_notifier(void) | |||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | void swiotlb_detect_4g(void) | 109 | void __init swiotlb_detect_4g(void) |
110 | { | 110 | { |
111 | if ((memblock_end_of_DRAM() - 1) > 0xffffffff) | 111 | if ((memblock_end_of_DRAM() - 1) > 0xffffffff) { |
112 | ppc_swiotlb_enable = 1; | 112 | ppc_swiotlb_enable = 1; |
113 | #ifdef CONFIG_ZONE_DMA32 | ||
114 | limit_zone_pfn(ZONE_DMA32, (1ULL << 32) >> PAGE_SHIFT); | ||
115 | #endif | ||
116 | } | ||
113 | } | 117 | } |
114 | 118 | ||
115 | static int __init swiotlb_late_init(void) | 119 | static int __init swiotlb_late_init(void) |
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index ee78f6e49d64..adac9dc54aee 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/vio.h> | 15 | #include <asm/vio.h> |
16 | #include <asm/bug.h> | 16 | #include <asm/bug.h> |
17 | #include <asm/machdep.h> | 17 | #include <asm/machdep.h> |
18 | #include <asm/swiotlb.h> | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * Generic direct DMA implementation | 21 | * Generic direct DMA implementation |
@@ -25,6 +26,18 @@ | |||
25 | * default the offset is PCI_DRAM_OFFSET. | 26 | * default the offset is PCI_DRAM_OFFSET. |
26 | */ | 27 | */ |
27 | 28 | ||
29 | static u64 __maybe_unused get_pfn_limit(struct device *dev) | ||
30 | { | ||
31 | u64 pfn = (dev->coherent_dma_mask >> PAGE_SHIFT) + 1; | ||
32 | struct dev_archdata __maybe_unused *sd = &dev->archdata; | ||
33 | |||
34 | #ifdef CONFIG_SWIOTLB | ||
35 | if (sd->max_direct_dma_addr && sd->dma_ops == &swiotlb_dma_ops) | ||
36 | pfn = min_t(u64, pfn, sd->max_direct_dma_addr >> PAGE_SHIFT); | ||
37 | #endif | ||
38 | |||
39 | return pfn; | ||
40 | } | ||
28 | 41 | ||
29 | void *dma_direct_alloc_coherent(struct device *dev, size_t size, | 42 | void *dma_direct_alloc_coherent(struct device *dev, size_t size, |
30 | dma_addr_t *dma_handle, gfp_t flag, | 43 | dma_addr_t *dma_handle, gfp_t flag, |
@@ -40,6 +53,26 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, | |||
40 | #else | 53 | #else |
41 | struct page *page; | 54 | struct page *page; |
42 | int node = dev_to_node(dev); | 55 | int node = dev_to_node(dev); |
56 | u64 pfn = get_pfn_limit(dev); | ||
57 | int zone; | ||
58 | |||
59 | zone = dma_pfn_limit_to_zone(pfn); | ||
60 | if (zone < 0) { | ||
61 | dev_err(dev, "%s: No suitable zone for pfn %#llx\n", | ||
62 | __func__, pfn); | ||
63 | return NULL; | ||
64 | } | ||
65 | |||
66 | switch (zone) { | ||
67 | case ZONE_DMA: | ||
68 | flag |= GFP_DMA; | ||
69 | break; | ||
70 | #ifdef CONFIG_ZONE_DMA32 | ||
71 | case ZONE_DMA32: | ||
72 | flag |= GFP_DMA32; | ||
73 | break; | ||
74 | #endif | ||
75 | }; | ||
43 | 76 | ||
44 | /* ignore region specifiers */ | 77 | /* ignore region specifiers */ |
45 | flag &= ~(__GFP_HIGHMEM); | 78 | flag &= ~(__GFP_HIGHMEM); |
@@ -202,6 +235,7 @@ int __dma_set_mask(struct device *dev, u64 dma_mask) | |||
202 | *dev->dma_mask = dma_mask; | 235 | *dev->dma_mask = dma_mask; |
203 | return 0; | 236 | return 0; |
204 | } | 237 | } |
238 | |||
205 | int dma_set_mask(struct device *dev, u64 dma_mask) | 239 | int dma_set_mask(struct device *dev, u64 dma_mask) |
206 | { | 240 | { |
207 | if (ppc_md.dma_set_mask) | 241 | if (ppc_md.dma_set_mask) |
@@ -210,13 +244,10 @@ int dma_set_mask(struct device *dev, u64 dma_mask) | |||
210 | } | 244 | } |
211 | EXPORT_SYMBOL(dma_set_mask); | 245 | EXPORT_SYMBOL(dma_set_mask); |
212 | 246 | ||
213 | u64 dma_get_required_mask(struct device *dev) | 247 | u64 __dma_get_required_mask(struct device *dev) |
214 | { | 248 | { |
215 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 249 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
216 | 250 | ||
217 | if (ppc_md.dma_get_required_mask) | ||
218 | return ppc_md.dma_get_required_mask(dev); | ||
219 | |||
220 | if (unlikely(dma_ops == NULL)) | 251 | if (unlikely(dma_ops == NULL)) |
221 | return 0; | 252 | return 0; |
222 | 253 | ||
@@ -225,6 +256,14 @@ u64 dma_get_required_mask(struct device *dev) | |||
225 | 256 | ||
226 | return DMA_BIT_MASK(8 * sizeof(dma_addr_t)); | 257 | return DMA_BIT_MASK(8 * sizeof(dma_addr_t)); |
227 | } | 258 | } |
259 | |||
260 | u64 dma_get_required_mask(struct device *dev) | ||
261 | { | ||
262 | if (ppc_md.dma_get_required_mask) | ||
263 | return ppc_md.dma_get_required_mask(dev); | ||
264 | |||
265 | return __dma_get_required_mask(dev); | ||
266 | } | ||
228 | EXPORT_SYMBOL_GPL(dma_get_required_mask); | 267 | EXPORT_SYMBOL_GPL(dma_get_required_mask); |
229 | 268 | ||
230 | static int __init dma_init(void) | 269 | static int __init dma_init(void) |
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 59a64f8dc85f..d543e4179c18 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
@@ -117,7 +117,7 @@ static DEFINE_MUTEX(eeh_dev_mutex); | |||
117 | * not dynamically alloced, so that it ends up in RMO where RTAS | 117 | * not dynamically alloced, so that it ends up in RMO where RTAS |
118 | * can access it. | 118 | * can access it. |
119 | */ | 119 | */ |
120 | #define EEH_PCI_REGS_LOG_LEN 4096 | 120 | #define EEH_PCI_REGS_LOG_LEN 8192 |
121 | static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN]; | 121 | static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN]; |
122 | 122 | ||
123 | /* | 123 | /* |
@@ -148,16 +148,12 @@ static int __init eeh_setup(char *str) | |||
148 | } | 148 | } |
149 | __setup("eeh=", eeh_setup); | 149 | __setup("eeh=", eeh_setup); |
150 | 150 | ||
151 | /** | 151 | /* |
152 | * eeh_gather_pci_data - Copy assorted PCI config space registers to buff | 152 | * This routine captures assorted PCI configuration space data |
153 | * @edev: device to report data for | 153 | * for the indicated PCI device, and puts them into a buffer |
154 | * @buf: point to buffer in which to log | 154 | * for RTAS error logging. |
155 | * @len: amount of room in buffer | ||
156 | * | ||
157 | * This routine captures assorted PCI configuration space data, | ||
158 | * and puts them into a buffer for RTAS error logging. | ||
159 | */ | 155 | */ |
160 | static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len) | 156 | static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len) |
161 | { | 157 | { |
162 | struct device_node *dn = eeh_dev_to_of_node(edev); | 158 | struct device_node *dn = eeh_dev_to_of_node(edev); |
163 | u32 cfg; | 159 | u32 cfg; |
@@ -255,6 +251,19 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len) | |||
255 | return n; | 251 | return n; |
256 | } | 252 | } |
257 | 253 | ||
254 | static void *eeh_dump_pe_log(void *data, void *flag) | ||
255 | { | ||
256 | struct eeh_pe *pe = data; | ||
257 | struct eeh_dev *edev, *tmp; | ||
258 | size_t *plen = flag; | ||
259 | |||
260 | eeh_pe_for_each_dev(pe, edev, tmp) | ||
261 | *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen, | ||
262 | EEH_PCI_REGS_LOG_LEN - *plen); | ||
263 | |||
264 | return NULL; | ||
265 | } | ||
266 | |||
258 | /** | 267 | /** |
259 | * eeh_slot_error_detail - Generate combined log including driver log and error log | 268 | * eeh_slot_error_detail - Generate combined log including driver log and error log |
260 | * @pe: EEH PE | 269 | * @pe: EEH PE |
@@ -268,7 +277,6 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len) | |||
268 | void eeh_slot_error_detail(struct eeh_pe *pe, int severity) | 277 | void eeh_slot_error_detail(struct eeh_pe *pe, int severity) |
269 | { | 278 | { |
270 | size_t loglen = 0; | 279 | size_t loglen = 0; |
271 | struct eeh_dev *edev, *tmp; | ||
272 | 280 | ||
273 | /* | 281 | /* |
274 | * When the PHB is fenced or dead, it's pointless to collect | 282 | * When the PHB is fenced or dead, it's pointless to collect |
@@ -286,10 +294,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity) | |||
286 | eeh_pe_restore_bars(pe); | 294 | eeh_pe_restore_bars(pe); |
287 | 295 | ||
288 | pci_regs_buf[0] = 0; | 296 | pci_regs_buf[0] = 0; |
289 | eeh_pe_for_each_dev(pe, edev, tmp) { | 297 | eeh_pe_traverse(pe, eeh_dump_pe_log, &loglen); |
290 | loglen += eeh_gather_pci_data(edev, pci_regs_buf + loglen, | ||
291 | EEH_PCI_REGS_LOG_LEN - loglen); | ||
292 | } | ||
293 | } | 298 | } |
294 | 299 | ||
295 | eeh_ops->get_log(pe, severity, pci_regs_buf, loglen); | 300 | eeh_ops->get_log(pe, severity, pci_regs_buf, loglen); |
@@ -410,7 +415,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) | |||
410 | } | 415 | } |
411 | dn = eeh_dev_to_of_node(edev); | 416 | dn = eeh_dev_to_of_node(edev); |
412 | dev = eeh_dev_to_pci_dev(edev); | 417 | dev = eeh_dev_to_pci_dev(edev); |
413 | pe = edev->pe; | 418 | pe = eeh_dev_to_pe(edev); |
414 | 419 | ||
415 | /* Access to IO BARs might get this far and still not want checking. */ | 420 | /* Access to IO BARs might get this far and still not want checking. */ |
416 | if (!pe) { | 421 | if (!pe) { |
@@ -542,17 +547,16 @@ EXPORT_SYMBOL_GPL(eeh_dev_check_failure); | |||
542 | 547 | ||
543 | /** | 548 | /** |
544 | * eeh_check_failure - Check if all 1's data is due to EEH slot freeze | 549 | * eeh_check_failure - Check if all 1's data is due to EEH slot freeze |
545 | * @token: I/O token, should be address in the form 0xA.... | 550 | * @token: I/O address |
546 | * @val: value, should be all 1's (XXX why do we need this arg??) | ||
547 | * | 551 | * |
548 | * Check for an EEH failure at the given token address. Call this | 552 | * Check for an EEH failure at the given I/O address. Call this |
549 | * routine if the result of a read was all 0xff's and you want to | 553 | * routine if the result of a read was all 0xff's and you want to |
550 | * find out if this is due to an EEH slot freeze event. This routine | 554 | * find out if this is due to an EEH slot freeze event. This routine |
551 | * will query firmware for the EEH status. | 555 | * will query firmware for the EEH status. |
552 | * | 556 | * |
553 | * Note this routine is safe to call in an interrupt context. | 557 | * Note this routine is safe to call in an interrupt context. |
554 | */ | 558 | */ |
555 | unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) | 559 | int eeh_check_failure(const volatile void __iomem *token) |
556 | { | 560 | { |
557 | unsigned long addr; | 561 | unsigned long addr; |
558 | struct eeh_dev *edev; | 562 | struct eeh_dev *edev; |
@@ -562,13 +566,11 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon | |||
562 | edev = eeh_addr_cache_get_dev(addr); | 566 | edev = eeh_addr_cache_get_dev(addr); |
563 | if (!edev) { | 567 | if (!edev) { |
564 | eeh_stats.no_device++; | 568 | eeh_stats.no_device++; |
565 | return val; | 569 | return 0; |
566 | } | 570 | } |
567 | 571 | ||
568 | eeh_dev_check_failure(edev); | 572 | return eeh_dev_check_failure(edev); |
569 | return val; | ||
570 | } | 573 | } |
571 | |||
572 | EXPORT_SYMBOL(eeh_check_failure); | 574 | EXPORT_SYMBOL(eeh_check_failure); |
573 | 575 | ||
574 | 576 | ||
@@ -582,25 +584,51 @@ EXPORT_SYMBOL(eeh_check_failure); | |||
582 | */ | 584 | */ |
583 | int eeh_pci_enable(struct eeh_pe *pe, int function) | 585 | int eeh_pci_enable(struct eeh_pe *pe, int function) |
584 | { | 586 | { |
585 | int rc, flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); | 587 | int active_flag, rc; |
586 | 588 | ||
587 | /* | 589 | /* |
588 | * pHyp doesn't allow to enable IO or DMA on unfrozen PE. | 590 | * pHyp doesn't allow to enable IO or DMA on unfrozen PE. |
589 | * Also, it's pointless to enable them on unfrozen PE. So | 591 | * Also, it's pointless to enable them on unfrozen PE. So |
590 | * we have the check here. | 592 | * we have to check before enabling IO or DMA. |
591 | */ | 593 | */ |
592 | if (function == EEH_OPT_THAW_MMIO || | 594 | switch (function) { |
593 | function == EEH_OPT_THAW_DMA) { | 595 | case EEH_OPT_THAW_MMIO: |
596 | active_flag = EEH_STATE_MMIO_ACTIVE; | ||
597 | break; | ||
598 | case EEH_OPT_THAW_DMA: | ||
599 | active_flag = EEH_STATE_DMA_ACTIVE; | ||
600 | break; | ||
601 | case EEH_OPT_DISABLE: | ||
602 | case EEH_OPT_ENABLE: | ||
603 | case EEH_OPT_FREEZE_PE: | ||
604 | active_flag = 0; | ||
605 | break; | ||
606 | default: | ||
607 | pr_warn("%s: Invalid function %d\n", | ||
608 | __func__, function); | ||
609 | return -EINVAL; | ||
610 | } | ||
611 | |||
612 | /* | ||
613 | * Check if IO or DMA has been enabled before | ||
614 | * enabling them. | ||
615 | */ | ||
616 | if (active_flag) { | ||
594 | rc = eeh_ops->get_state(pe, NULL); | 617 | rc = eeh_ops->get_state(pe, NULL); |
595 | if (rc < 0) | 618 | if (rc < 0) |
596 | return rc; | 619 | return rc; |
597 | 620 | ||
598 | /* Needn't to enable or already enabled */ | 621 | /* Needn't enable it at all */ |
599 | if ((rc == EEH_STATE_NOT_SUPPORT) || | 622 | if (rc == EEH_STATE_NOT_SUPPORT) |
600 | ((rc & flags) == flags)) | 623 | return 0; |
624 | |||
625 | /* It's already enabled */ | ||
626 | if (rc & active_flag) | ||
601 | return 0; | 627 | return 0; |
602 | } | 628 | } |
603 | 629 | ||
630 | |||
631 | /* Issue the request */ | ||
604 | rc = eeh_ops->set_option(pe, function); | 632 | rc = eeh_ops->set_option(pe, function); |
605 | if (rc) | 633 | if (rc) |
606 | pr_warn("%s: Unexpected state change %d on " | 634 | pr_warn("%s: Unexpected state change %d on " |
@@ -608,17 +636,17 @@ int eeh_pci_enable(struct eeh_pe *pe, int function) | |||
608 | __func__, function, pe->phb->global_number, | 636 | __func__, function, pe->phb->global_number, |
609 | pe->addr, rc); | 637 | pe->addr, rc); |
610 | 638 | ||
611 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); | 639 | /* Check if the request is finished successfully */ |
612 | if (rc <= 0) | 640 | if (active_flag) { |
613 | return rc; | 641 | rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); |
642 | if (rc <= 0) | ||
643 | return rc; | ||
614 | 644 | ||
615 | if ((function == EEH_OPT_THAW_MMIO) && | 645 | if (rc & active_flag) |
616 | (rc & EEH_STATE_MMIO_ENABLED)) | 646 | return 0; |
617 | return 0; | ||
618 | 647 | ||
619 | if ((function == EEH_OPT_THAW_DMA) && | 648 | return -EIO; |
620 | (rc & EEH_STATE_DMA_ENABLED)) | 649 | } |
621 | return 0; | ||
622 | 650 | ||
623 | return rc; | 651 | return rc; |
624 | } | 652 | } |
@@ -634,7 +662,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function) | |||
634 | int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) | 662 | int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) |
635 | { | 663 | { |
636 | struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); | 664 | struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); |
637 | struct eeh_pe *pe = edev->pe; | 665 | struct eeh_pe *pe = eeh_dev_to_pe(edev); |
638 | 666 | ||
639 | if (!pe) { | 667 | if (!pe) { |
640 | pr_err("%s: No PE found on PCI device %s\n", | 668 | pr_err("%s: No PE found on PCI device %s\n", |
@@ -645,14 +673,18 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat | |||
645 | switch (state) { | 673 | switch (state) { |
646 | case pcie_deassert_reset: | 674 | case pcie_deassert_reset: |
647 | eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); | 675 | eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); |
676 | eeh_pe_state_clear(pe, EEH_PE_RESET); | ||
648 | break; | 677 | break; |
649 | case pcie_hot_reset: | 678 | case pcie_hot_reset: |
679 | eeh_pe_state_mark(pe, EEH_PE_RESET); | ||
650 | eeh_ops->reset(pe, EEH_RESET_HOT); | 680 | eeh_ops->reset(pe, EEH_RESET_HOT); |
651 | break; | 681 | break; |
652 | case pcie_warm_reset: | 682 | case pcie_warm_reset: |
683 | eeh_pe_state_mark(pe, EEH_PE_RESET); | ||
653 | eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); | 684 | eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); |
654 | break; | 685 | break; |
655 | default: | 686 | default: |
687 | eeh_pe_state_clear(pe, EEH_PE_RESET); | ||
656 | return -EINVAL; | 688 | return -EINVAL; |
657 | }; | 689 | }; |
658 | 690 | ||
@@ -1141,6 +1173,85 @@ void eeh_remove_device(struct pci_dev *dev) | |||
1141 | edev->mode &= ~EEH_DEV_SYSFS; | 1173 | edev->mode &= ~EEH_DEV_SYSFS; |
1142 | } | 1174 | } |
1143 | 1175 | ||
1176 | int eeh_unfreeze_pe(struct eeh_pe *pe, bool sw_state) | ||
1177 | { | ||
1178 | int ret; | ||
1179 | |||
1180 | ret = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); | ||
1181 | if (ret) { | ||
1182 | pr_warn("%s: Failure %d enabling IO on PHB#%x-PE#%x\n", | ||
1183 | __func__, ret, pe->phb->global_number, pe->addr); | ||
1184 | return ret; | ||
1185 | } | ||
1186 | |||
1187 | ret = eeh_pci_enable(pe, EEH_OPT_THAW_DMA); | ||
1188 | if (ret) { | ||
1189 | pr_warn("%s: Failure %d enabling DMA on PHB#%x-PE#%x\n", | ||
1190 | __func__, ret, pe->phb->global_number, pe->addr); | ||
1191 | return ret; | ||
1192 | } | ||
1193 | |||
1194 | /* Clear software isolated state */ | ||
1195 | if (sw_state && (pe->state & EEH_PE_ISOLATED)) | ||
1196 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | ||
1197 | |||
1198 | return ret; | ||
1199 | } | ||
1200 | |||
1201 | |||
1202 | static struct pci_device_id eeh_reset_ids[] = { | ||
1203 | { PCI_DEVICE(0x19a2, 0x0710) }, /* Emulex, BE */ | ||
1204 | { PCI_DEVICE(0x10df, 0xe220) }, /* Emulex, Lancer */ | ||
1205 | { 0 } | ||
1206 | }; | ||
1207 | |||
1208 | static int eeh_pe_change_owner(struct eeh_pe *pe) | ||
1209 | { | ||
1210 | struct eeh_dev *edev, *tmp; | ||
1211 | struct pci_dev *pdev; | ||
1212 | struct pci_device_id *id; | ||
1213 | int flags, ret; | ||
1214 | |||
1215 | /* Check PE state */ | ||
1216 | flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); | ||
1217 | ret = eeh_ops->get_state(pe, NULL); | ||
1218 | if (ret < 0 || ret == EEH_STATE_NOT_SUPPORT) | ||
1219 | return 0; | ||
1220 | |||
1221 | /* Unfrozen PE, nothing to do */ | ||
1222 | if ((ret & flags) == flags) | ||
1223 | return 0; | ||
1224 | |||
1225 | /* Frozen PE, check if it needs PE level reset */ | ||
1226 | eeh_pe_for_each_dev(pe, edev, tmp) { | ||
1227 | pdev = eeh_dev_to_pci_dev(edev); | ||
1228 | if (!pdev) | ||
1229 | continue; | ||
1230 | |||
1231 | for (id = &eeh_reset_ids[0]; id->vendor != 0; id++) { | ||
1232 | if (id->vendor != PCI_ANY_ID && | ||
1233 | id->vendor != pdev->vendor) | ||
1234 | continue; | ||
1235 | if (id->device != PCI_ANY_ID && | ||
1236 | id->device != pdev->device) | ||
1237 | continue; | ||
1238 | if (id->subvendor != PCI_ANY_ID && | ||
1239 | id->subvendor != pdev->subsystem_vendor) | ||
1240 | continue; | ||
1241 | if (id->subdevice != PCI_ANY_ID && | ||
1242 | id->subdevice != pdev->subsystem_device) | ||
1243 | continue; | ||
1244 | |||
1245 | goto reset; | ||
1246 | } | ||
1247 | } | ||
1248 | |||
1249 | return eeh_unfreeze_pe(pe, true); | ||
1250 | |||
1251 | reset: | ||
1252 | return eeh_pe_reset_and_recover(pe); | ||
1253 | } | ||
1254 | |||
1144 | /** | 1255 | /** |
1145 | * eeh_dev_open - Increase count of pass through devices for PE | 1256 | * eeh_dev_open - Increase count of pass through devices for PE |
1146 | * @pdev: PCI device | 1257 | * @pdev: PCI device |
@@ -1153,6 +1264,7 @@ void eeh_remove_device(struct pci_dev *dev) | |||
1153 | int eeh_dev_open(struct pci_dev *pdev) | 1264 | int eeh_dev_open(struct pci_dev *pdev) |
1154 | { | 1265 | { |
1155 | struct eeh_dev *edev; | 1266 | struct eeh_dev *edev; |
1267 | int ret = -ENODEV; | ||
1156 | 1268 | ||
1157 | mutex_lock(&eeh_dev_mutex); | 1269 | mutex_lock(&eeh_dev_mutex); |
1158 | 1270 | ||
@@ -1165,6 +1277,16 @@ int eeh_dev_open(struct pci_dev *pdev) | |||
1165 | if (!edev || !edev->pe) | 1277 | if (!edev || !edev->pe) |
1166 | goto out; | 1278 | goto out; |
1167 | 1279 | ||
1280 | /* | ||
1281 | * The PE might have been put into frozen state, but we | ||
1282 | * didn't detect that yet. The passed through PCI devices | ||
1283 | * in frozen PE won't work properly. Clear the frozen state | ||
1284 | * in advance. | ||
1285 | */ | ||
1286 | ret = eeh_pe_change_owner(edev->pe); | ||
1287 | if (ret) | ||
1288 | goto out; | ||
1289 | |||
1168 | /* Increase PE's pass through count */ | 1290 | /* Increase PE's pass through count */ |
1169 | atomic_inc(&edev->pe->pass_dev_cnt); | 1291 | atomic_inc(&edev->pe->pass_dev_cnt); |
1170 | mutex_unlock(&eeh_dev_mutex); | 1292 | mutex_unlock(&eeh_dev_mutex); |
@@ -1172,7 +1294,7 @@ int eeh_dev_open(struct pci_dev *pdev) | |||
1172 | return 0; | 1294 | return 0; |
1173 | out: | 1295 | out: |
1174 | mutex_unlock(&eeh_dev_mutex); | 1296 | mutex_unlock(&eeh_dev_mutex); |
1175 | return -ENODEV; | 1297 | return ret; |
1176 | } | 1298 | } |
1177 | EXPORT_SYMBOL_GPL(eeh_dev_open); | 1299 | EXPORT_SYMBOL_GPL(eeh_dev_open); |
1178 | 1300 | ||
@@ -1202,6 +1324,7 @@ void eeh_dev_release(struct pci_dev *pdev) | |||
1202 | /* Decrease PE's pass through count */ | 1324 | /* Decrease PE's pass through count */ |
1203 | atomic_dec(&edev->pe->pass_dev_cnt); | 1325 | atomic_dec(&edev->pe->pass_dev_cnt); |
1204 | WARN_ON(atomic_read(&edev->pe->pass_dev_cnt) < 0); | 1326 | WARN_ON(atomic_read(&edev->pe->pass_dev_cnt) < 0); |
1327 | eeh_pe_change_owner(edev->pe); | ||
1205 | out: | 1328 | out: |
1206 | mutex_unlock(&eeh_dev_mutex); | 1329 | mutex_unlock(&eeh_dev_mutex); |
1207 | } | 1330 | } |
@@ -1281,8 +1404,10 @@ int eeh_pe_set_option(struct eeh_pe *pe, int option) | |||
1281 | */ | 1404 | */ |
1282 | switch (option) { | 1405 | switch (option) { |
1283 | case EEH_OPT_ENABLE: | 1406 | case EEH_OPT_ENABLE: |
1284 | if (eeh_enabled()) | 1407 | if (eeh_enabled()) { |
1408 | ret = eeh_pe_change_owner(pe); | ||
1285 | break; | 1409 | break; |
1410 | } | ||
1286 | ret = -EIO; | 1411 | ret = -EIO; |
1287 | break; | 1412 | break; |
1288 | case EEH_OPT_DISABLE: | 1413 | case EEH_OPT_DISABLE: |
@@ -1294,7 +1419,7 @@ int eeh_pe_set_option(struct eeh_pe *pe, int option) | |||
1294 | break; | 1419 | break; |
1295 | } | 1420 | } |
1296 | 1421 | ||
1297 | ret = eeh_ops->set_option(pe, option); | 1422 | ret = eeh_pci_enable(pe, option); |
1298 | break; | 1423 | break; |
1299 | default: | 1424 | default: |
1300 | pr_debug("%s: Option %d out of range (%d, %d)\n", | 1425 | pr_debug("%s: Option %d out of range (%d, %d)\n", |
@@ -1345,6 +1470,36 @@ int eeh_pe_get_state(struct eeh_pe *pe) | |||
1345 | } | 1470 | } |
1346 | EXPORT_SYMBOL_GPL(eeh_pe_get_state); | 1471 | EXPORT_SYMBOL_GPL(eeh_pe_get_state); |
1347 | 1472 | ||
1473 | static int eeh_pe_reenable_devices(struct eeh_pe *pe) | ||
1474 | { | ||
1475 | struct eeh_dev *edev, *tmp; | ||
1476 | struct pci_dev *pdev; | ||
1477 | int ret = 0; | ||
1478 | |||
1479 | /* Restore config space */ | ||
1480 | eeh_pe_restore_bars(pe); | ||
1481 | |||
1482 | /* | ||
1483 | * Reenable PCI devices as the devices passed | ||
1484 | * through are always enabled before the reset. | ||
1485 | */ | ||
1486 | eeh_pe_for_each_dev(pe, edev, tmp) { | ||
1487 | pdev = eeh_dev_to_pci_dev(edev); | ||
1488 | if (!pdev) | ||
1489 | continue; | ||
1490 | |||
1491 | ret = pci_reenable_device(pdev); | ||
1492 | if (ret) { | ||
1493 | pr_warn("%s: Failure %d reenabling %s\n", | ||
1494 | __func__, ret, pci_name(pdev)); | ||
1495 | return ret; | ||
1496 | } | ||
1497 | } | ||
1498 | |||
1499 | /* The PE is still in frozen state */ | ||
1500 | return eeh_unfreeze_pe(pe, true); | ||
1501 | } | ||
1502 | |||
1348 | /** | 1503 | /** |
1349 | * eeh_pe_reset - Issue PE reset according to specified type | 1504 | * eeh_pe_reset - Issue PE reset according to specified type |
1350 | * @pe: EEH PE | 1505 | * @pe: EEH PE |
@@ -1368,23 +1523,22 @@ int eeh_pe_reset(struct eeh_pe *pe, int option) | |||
1368 | switch (option) { | 1523 | switch (option) { |
1369 | case EEH_RESET_DEACTIVATE: | 1524 | case EEH_RESET_DEACTIVATE: |
1370 | ret = eeh_ops->reset(pe, option); | 1525 | ret = eeh_ops->reset(pe, option); |
1526 | eeh_pe_state_clear(pe, EEH_PE_RESET); | ||
1371 | if (ret) | 1527 | if (ret) |
1372 | break; | 1528 | break; |
1373 | 1529 | ||
1374 | /* | 1530 | ret = eeh_pe_reenable_devices(pe); |
1375 | * The PE is still in frozen state and we need to clear | ||
1376 | * that. It's good to clear frozen state after deassert | ||
1377 | * to avoid messy IO access during reset, which might | ||
1378 | * cause recursive frozen PE. | ||
1379 | */ | ||
1380 | ret = eeh_ops->set_option(pe, EEH_OPT_THAW_MMIO); | ||
1381 | if (!ret) | ||
1382 | ret = eeh_ops->set_option(pe, EEH_OPT_THAW_DMA); | ||
1383 | if (!ret) | ||
1384 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | ||
1385 | break; | 1531 | break; |
1386 | case EEH_RESET_HOT: | 1532 | case EEH_RESET_HOT: |
1387 | case EEH_RESET_FUNDAMENTAL: | 1533 | case EEH_RESET_FUNDAMENTAL: |
1534 | /* | ||
1535 | * Proactively freeze the PE to drop all MMIO access | ||
1536 | * during reset, which should be banned as it's always | ||
1537 | * cause recursive EEH error. | ||
1538 | */ | ||
1539 | eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); | ||
1540 | |||
1541 | eeh_pe_state_mark(pe, EEH_PE_RESET); | ||
1388 | ret = eeh_ops->reset(pe, option); | 1542 | ret = eeh_ops->reset(pe, option); |
1389 | break; | 1543 | break; |
1390 | default: | 1544 | default: |
@@ -1413,9 +1567,6 @@ int eeh_pe_configure(struct eeh_pe *pe) | |||
1413 | if (!pe) | 1567 | if (!pe) |
1414 | return -ENODEV; | 1568 | return -ENODEV; |
1415 | 1569 | ||
1416 | /* Restore config space for the affected devices */ | ||
1417 | eeh_pe_restore_bars(pe); | ||
1418 | |||
1419 | return ret; | 1570 | return ret; |
1420 | } | 1571 | } |
1421 | EXPORT_SYMBOL_GPL(eeh_pe_configure); | 1572 | EXPORT_SYMBOL_GPL(eeh_pe_configure); |
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 6a0dcee8e931..3fd514f8e4b2 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c | |||
@@ -180,6 +180,22 @@ static bool eeh_dev_removed(struct eeh_dev *edev) | |||
180 | return false; | 180 | return false; |
181 | } | 181 | } |
182 | 182 | ||
183 | static void *eeh_dev_save_state(void *data, void *userdata) | ||
184 | { | ||
185 | struct eeh_dev *edev = data; | ||
186 | struct pci_dev *pdev; | ||
187 | |||
188 | if (!edev) | ||
189 | return NULL; | ||
190 | |||
191 | pdev = eeh_dev_to_pci_dev(edev); | ||
192 | if (!pdev) | ||
193 | return NULL; | ||
194 | |||
195 | pci_save_state(pdev); | ||
196 | return NULL; | ||
197 | } | ||
198 | |||
183 | /** | 199 | /** |
184 | * eeh_report_error - Report pci error to each device driver | 200 | * eeh_report_error - Report pci error to each device driver |
185 | * @data: eeh device | 201 | * @data: eeh device |
@@ -303,6 +319,22 @@ static void *eeh_report_reset(void *data, void *userdata) | |||
303 | return NULL; | 319 | return NULL; |
304 | } | 320 | } |
305 | 321 | ||
322 | static void *eeh_dev_restore_state(void *data, void *userdata) | ||
323 | { | ||
324 | struct eeh_dev *edev = data; | ||
325 | struct pci_dev *pdev; | ||
326 | |||
327 | if (!edev) | ||
328 | return NULL; | ||
329 | |||
330 | pdev = eeh_dev_to_pci_dev(edev); | ||
331 | if (!pdev) | ||
332 | return NULL; | ||
333 | |||
334 | pci_restore_state(pdev); | ||
335 | return NULL; | ||
336 | } | ||
337 | |||
306 | /** | 338 | /** |
307 | * eeh_report_resume - Tell device to resume normal operations | 339 | * eeh_report_resume - Tell device to resume normal operations |
308 | * @data: eeh device | 340 | * @data: eeh device |
@@ -450,38 +482,82 @@ static void *eeh_pe_detach_dev(void *data, void *userdata) | |||
450 | static void *__eeh_clear_pe_frozen_state(void *data, void *flag) | 482 | static void *__eeh_clear_pe_frozen_state(void *data, void *flag) |
451 | { | 483 | { |
452 | struct eeh_pe *pe = (struct eeh_pe *)data; | 484 | struct eeh_pe *pe = (struct eeh_pe *)data; |
453 | int i, rc; | 485 | bool *clear_sw_state = flag; |
486 | int i, rc = 1; | ||
454 | 487 | ||
455 | for (i = 0; i < 3; i++) { | 488 | for (i = 0; rc && i < 3; i++) |
456 | rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); | 489 | rc = eeh_unfreeze_pe(pe, clear_sw_state); |
457 | if (rc) | ||
458 | continue; | ||
459 | rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA); | ||
460 | if (!rc) | ||
461 | break; | ||
462 | } | ||
463 | 490 | ||
464 | /* The PE has been isolated, clear it */ | 491 | /* Stop immediately on any errors */ |
465 | if (rc) { | 492 | if (rc) { |
466 | pr_warn("%s: Can't clear frozen PHB#%x-PE#%x (%d)\n", | 493 | pr_warn("%s: Failure %d unfreezing PHB#%x-PE#%x\n", |
467 | __func__, pe->phb->global_number, pe->addr, rc); | 494 | __func__, rc, pe->phb->global_number, pe->addr); |
468 | return (void *)pe; | 495 | return (void *)pe; |
469 | } | 496 | } |
470 | 497 | ||
471 | return NULL; | 498 | return NULL; |
472 | } | 499 | } |
473 | 500 | ||
474 | static int eeh_clear_pe_frozen_state(struct eeh_pe *pe) | 501 | static int eeh_clear_pe_frozen_state(struct eeh_pe *pe, |
502 | bool clear_sw_state) | ||
475 | { | 503 | { |
476 | void *rc; | 504 | void *rc; |
477 | 505 | ||
478 | rc = eeh_pe_traverse(pe, __eeh_clear_pe_frozen_state, NULL); | 506 | rc = eeh_pe_traverse(pe, __eeh_clear_pe_frozen_state, &clear_sw_state); |
479 | if (!rc) | 507 | if (!rc) |
480 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); | 508 | eeh_pe_state_clear(pe, EEH_PE_ISOLATED); |
481 | 509 | ||
482 | return rc ? -EIO : 0; | 510 | return rc ? -EIO : 0; |
483 | } | 511 | } |
484 | 512 | ||
513 | int eeh_pe_reset_and_recover(struct eeh_pe *pe) | ||
514 | { | ||
515 | int result, ret; | ||
516 | |||
517 | /* Bail if the PE is being recovered */ | ||
518 | if (pe->state & EEH_PE_RECOVERING) | ||
519 | return 0; | ||
520 | |||
521 | /* Put the PE into recovery mode */ | ||
522 | eeh_pe_state_mark(pe, EEH_PE_RECOVERING); | ||
523 | |||
524 | /* Save states */ | ||
525 | eeh_pe_dev_traverse(pe, eeh_dev_save_state, NULL); | ||
526 | |||
527 | /* Report error */ | ||
528 | eeh_pe_dev_traverse(pe, eeh_report_error, &result); | ||
529 | |||
530 | /* Issue reset */ | ||
531 | eeh_pe_state_mark(pe, EEH_PE_RESET); | ||
532 | ret = eeh_reset_pe(pe); | ||
533 | if (ret) { | ||
534 | eeh_pe_state_clear(pe, EEH_PE_RECOVERING | EEH_PE_RESET); | ||
535 | return ret; | ||
536 | } | ||
537 | eeh_pe_state_clear(pe, EEH_PE_RESET); | ||
538 | |||
539 | /* Unfreeze the PE */ | ||
540 | ret = eeh_clear_pe_frozen_state(pe, true); | ||
541 | if (ret) { | ||
542 | eeh_pe_state_clear(pe, EEH_PE_RECOVERING); | ||
543 | return ret; | ||
544 | } | ||
545 | |||
546 | /* Notify completion of reset */ | ||
547 | eeh_pe_dev_traverse(pe, eeh_report_reset, &result); | ||
548 | |||
549 | /* Restore device state */ | ||
550 | eeh_pe_dev_traverse(pe, eeh_dev_restore_state, NULL); | ||
551 | |||
552 | /* Resume */ | ||
553 | eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); | ||
554 | |||
555 | /* Clear recovery mode */ | ||
556 | eeh_pe_state_clear(pe, EEH_PE_RECOVERING); | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
485 | /** | 561 | /** |
486 | * eeh_reset_device - Perform actual reset of a pci slot | 562 | * eeh_reset_device - Perform actual reset of a pci slot |
487 | * @pe: EEH PE | 563 | * @pe: EEH PE |
@@ -540,7 +616,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
540 | eeh_pe_state_clear(pe, EEH_PE_RESET); | 616 | eeh_pe_state_clear(pe, EEH_PE_RESET); |
541 | 617 | ||
542 | /* Clear frozen state */ | 618 | /* Clear frozen state */ |
543 | rc = eeh_clear_pe_frozen_state(pe); | 619 | rc = eeh_clear_pe_frozen_state(pe, false); |
544 | if (rc) | 620 | if (rc) |
545 | return rc; | 621 | return rc; |
546 | 622 | ||
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 00e3844525a6..53dd0915e690 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c | |||
@@ -428,7 +428,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev) | |||
428 | } | 428 | } |
429 | 429 | ||
430 | /* Remove the EEH device */ | 430 | /* Remove the EEH device */ |
431 | pe = edev->pe; | 431 | pe = eeh_dev_to_pe(edev); |
432 | edev->pe = NULL; | 432 | edev->pe = NULL; |
433 | list_del(&edev->list); | 433 | list_del(&edev->list); |
434 | 434 | ||
@@ -584,6 +584,8 @@ static void *__eeh_pe_state_clear(void *data, void *flag) | |||
584 | { | 584 | { |
585 | struct eeh_pe *pe = (struct eeh_pe *)data; | 585 | struct eeh_pe *pe = (struct eeh_pe *)data; |
586 | int state = *((int *)flag); | 586 | int state = *((int *)flag); |
587 | struct eeh_dev *edev, *tmp; | ||
588 | struct pci_dev *pdev; | ||
587 | 589 | ||
588 | /* Keep the state of permanently removed PE intact */ | 590 | /* Keep the state of permanently removed PE intact */ |
589 | if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) && | 591 | if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) && |
@@ -592,9 +594,22 @@ static void *__eeh_pe_state_clear(void *data, void *flag) | |||
592 | 594 | ||
593 | pe->state &= ~state; | 595 | pe->state &= ~state; |
594 | 596 | ||
595 | /* Clear check count since last isolation */ | 597 | /* |
596 | if (state & EEH_PE_ISOLATED) | 598 | * Special treatment on clearing isolated state. Clear |
597 | pe->check_count = 0; | 599 | * check count since last isolation and put all affected |
600 | * devices to normal state. | ||
601 | */ | ||
602 | if (!(state & EEH_PE_ISOLATED)) | ||
603 | return NULL; | ||
604 | |||
605 | pe->check_count = 0; | ||
606 | eeh_pe_for_each_dev(pe, edev, tmp) { | ||
607 | pdev = eeh_dev_to_pci_dev(edev); | ||
608 | if (!pdev) | ||
609 | continue; | ||
610 | |||
611 | pdev->error_state = pci_channel_io_normal; | ||
612 | } | ||
598 | 613 | ||
599 | return NULL; | 614 | return NULL; |
600 | } | 615 | } |
diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index e2595ba4b720..f19b1e5cb060 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c | |||
@@ -54,6 +54,43 @@ EEH_SHOW_ATTR(eeh_mode, mode, "0x%x"); | |||
54 | EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); | 54 | EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); |
55 | EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); | 55 | EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); |
56 | 56 | ||
57 | static ssize_t eeh_pe_state_show(struct device *dev, | ||
58 | struct device_attribute *attr, char *buf) | ||
59 | { | ||
60 | struct pci_dev *pdev = to_pci_dev(dev); | ||
61 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | ||
62 | int state; | ||
63 | |||
64 | if (!edev || !edev->pe) | ||
65 | return -ENODEV; | ||
66 | |||
67 | state = eeh_ops->get_state(edev->pe, NULL); | ||
68 | return sprintf(buf, "%0x08x %0x08x\n", | ||
69 | state, edev->pe->state); | ||
70 | } | ||
71 | |||
72 | static ssize_t eeh_pe_state_store(struct device *dev, | ||
73 | struct device_attribute *attr, | ||
74 | const char *buf, size_t count) | ||
75 | { | ||
76 | struct pci_dev *pdev = to_pci_dev(dev); | ||
77 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | ||
78 | |||
79 | if (!edev || !edev->pe) | ||
80 | return -ENODEV; | ||
81 | |||
82 | /* Nothing to do if it's not frozen */ | ||
83 | if (!(edev->pe->state & EEH_PE_ISOLATED)) | ||
84 | return count; | ||
85 | |||
86 | if (eeh_unfreeze_pe(edev->pe, true)) | ||
87 | return -EIO; | ||
88 | |||
89 | return count; | ||
90 | } | ||
91 | |||
92 | static DEVICE_ATTR_RW(eeh_pe_state); | ||
93 | |||
57 | void eeh_sysfs_add_device(struct pci_dev *pdev) | 94 | void eeh_sysfs_add_device(struct pci_dev *pdev) |
58 | { | 95 | { |
59 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); | 96 | struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); |
@@ -68,9 +105,10 @@ void eeh_sysfs_add_device(struct pci_dev *pdev) | |||
68 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); | 105 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); |
69 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); | 106 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); |
70 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); | 107 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); |
108 | rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_state); | ||
71 | 109 | ||
72 | if (rc) | 110 | if (rc) |
73 | printk(KERN_WARNING "EEH: Unable to create sysfs entries\n"); | 111 | pr_warn("EEH: Unable to create sysfs entries\n"); |
74 | else if (edev) | 112 | else if (edev) |
75 | edev->mode |= EEH_DEV_SYSFS; | 113 | edev->mode |= EEH_DEV_SYSFS; |
76 | } | 114 | } |
@@ -92,6 +130,7 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev) | |||
92 | device_remove_file(&pdev->dev, &dev_attr_eeh_mode); | 130 | device_remove_file(&pdev->dev, &dev_attr_eeh_mode); |
93 | device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); | 131 | device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); |
94 | device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); | 132 | device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); |
133 | device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state); | ||
95 | 134 | ||
96 | if (edev) | 135 | if (edev) |
97 | edev->mode &= ~EEH_DEV_SYSFS; | 136 | edev->mode &= ~EEH_DEV_SYSFS; |
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 7ee876d2adb5..fafff8dbd5d9 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -104,12 +104,15 @@ turn_on_mmu: | |||
104 | * task's thread_struct. | 104 | * task's thread_struct. |
105 | */ | 105 | */ |
106 | #define EXCEPTION_PROLOG \ | 106 | #define EXCEPTION_PROLOG \ |
107 | mtspr SPRN_SPRG_SCRATCH0,r10; \ | 107 | EXCEPTION_PROLOG_0; \ |
108 | mtspr SPRN_SPRG_SCRATCH1,r11; \ | ||
109 | mfcr r10; \ | ||
110 | EXCEPTION_PROLOG_1; \ | 108 | EXCEPTION_PROLOG_1; \ |
111 | EXCEPTION_PROLOG_2 | 109 | EXCEPTION_PROLOG_2 |
112 | 110 | ||
111 | #define EXCEPTION_PROLOG_0 \ | ||
112 | mtspr SPRN_SPRG_SCRATCH0,r10; \ | ||
113 | mtspr SPRN_SPRG_SCRATCH1,r11; \ | ||
114 | mfcr r10 | ||
115 | |||
113 | #define EXCEPTION_PROLOG_1 \ | 116 | #define EXCEPTION_PROLOG_1 \ |
114 | mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \ | 117 | mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \ |
115 | andi. r11,r11,MSR_PR; \ | 118 | andi. r11,r11,MSR_PR; \ |
@@ -145,6 +148,14 @@ turn_on_mmu: | |||
145 | SAVE_2GPRS(7, r11) | 148 | SAVE_2GPRS(7, r11) |
146 | 149 | ||
147 | /* | 150 | /* |
151 | * Exception exit code. | ||
152 | */ | ||
153 | #define EXCEPTION_EPILOG_0 \ | ||
154 | mtcr r10; \ | ||
155 | mfspr r10,SPRN_SPRG_SCRATCH0; \ | ||
156 | mfspr r11,SPRN_SPRG_SCRATCH1 | ||
157 | |||
158 | /* | ||
148 | * Note: code which follows this uses cr0.eq (set if from kernel), | 159 | * Note: code which follows this uses cr0.eq (set if from kernel), |
149 | * r11, r12 (SRR0), and r9 (SRR1). | 160 | * r11, r12 (SRR0), and r9 (SRR1). |
150 | * | 161 | * |
@@ -293,16 +304,8 @@ InstructionTLBMiss: | |||
293 | #ifdef CONFIG_8xx_CPU6 | 304 | #ifdef CONFIG_8xx_CPU6 |
294 | stw r3, 8(r0) | 305 | stw r3, 8(r0) |
295 | #endif | 306 | #endif |
296 | DO_8xx_CPU6(0x3f80, r3) | 307 | EXCEPTION_PROLOG_0 |
297 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ | 308 | mtspr SPRN_SPRG_SCRATCH2, r10 |
298 | mfcr r10 | ||
299 | #ifdef CONFIG_8xx_CPU6 | ||
300 | stw r10, 0(r0) | ||
301 | stw r11, 4(r0) | ||
302 | #else | ||
303 | mtspr SPRN_DAR, r10 | ||
304 | mtspr SPRN_SPRG2, r11 | ||
305 | #endif | ||
306 | mfspr r10, SPRN_SRR0 /* Get effective address of fault */ | 309 | mfspr r10, SPRN_SRR0 /* Get effective address of fault */ |
307 | #ifdef CONFIG_8xx_CPU15 | 310 | #ifdef CONFIG_8xx_CPU15 |
308 | addi r11, r10, 0x1000 | 311 | addi r11, r10, 0x1000 |
@@ -359,18 +362,11 @@ InstructionTLBMiss: | |||
359 | mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ | 362 | mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ |
360 | 363 | ||
361 | /* Restore registers */ | 364 | /* Restore registers */ |
362 | #ifndef CONFIG_8xx_CPU6 | 365 | #ifdef CONFIG_8xx_CPU6 |
363 | mfspr r10, SPRN_DAR | ||
364 | mtcr r10 | ||
365 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
366 | mfspr r11, SPRN_SPRG2 | ||
367 | #else | ||
368 | lwz r11, 0(r0) | ||
369 | mtcr r11 | ||
370 | lwz r11, 4(r0) | ||
371 | lwz r3, 8(r0) | 366 | lwz r3, 8(r0) |
372 | #endif | 367 | #endif |
373 | mfspr r10, SPRN_M_TW | 368 | mfspr r10, SPRN_SPRG_SCRATCH2 |
369 | EXCEPTION_EPILOG_0 | ||
374 | rfi | 370 | rfi |
375 | 2: | 371 | 2: |
376 | mfspr r11, SPRN_SRR1 | 372 | mfspr r11, SPRN_SRR1 |
@@ -381,19 +377,11 @@ InstructionTLBMiss: | |||
381 | mtspr SPRN_SRR1, r11 | 377 | mtspr SPRN_SRR1, r11 |
382 | 378 | ||
383 | /* Restore registers */ | 379 | /* Restore registers */ |
384 | #ifndef CONFIG_8xx_CPU6 | 380 | #ifdef CONFIG_8xx_CPU6 |
385 | mfspr r10, SPRN_DAR | ||
386 | mtcr r10 | ||
387 | li r11, 0x00f0 | ||
388 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
389 | mfspr r11, SPRN_SPRG2 | ||
390 | #else | ||
391 | lwz r11, 0(r0) | ||
392 | mtcr r11 | ||
393 | lwz r11, 4(r0) | ||
394 | lwz r3, 8(r0) | 381 | lwz r3, 8(r0) |
395 | #endif | 382 | #endif |
396 | mfspr r10, SPRN_M_TW | 383 | mfspr r10, SPRN_SPRG_SCRATCH2 |
384 | EXCEPTION_EPILOG_0 | ||
397 | b InstructionAccess | 385 | b InstructionAccess |
398 | 386 | ||
399 | . = 0x1200 | 387 | . = 0x1200 |
@@ -401,16 +389,8 @@ DataStoreTLBMiss: | |||
401 | #ifdef CONFIG_8xx_CPU6 | 389 | #ifdef CONFIG_8xx_CPU6 |
402 | stw r3, 8(r0) | 390 | stw r3, 8(r0) |
403 | #endif | 391 | #endif |
404 | DO_8xx_CPU6(0x3f80, r3) | 392 | EXCEPTION_PROLOG_0 |
405 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ | 393 | mtspr SPRN_SPRG_SCRATCH2, r10 |
406 | mfcr r10 | ||
407 | #ifdef CONFIG_8xx_CPU6 | ||
408 | stw r10, 0(r0) | ||
409 | stw r11, 4(r0) | ||
410 | #else | ||
411 | mtspr SPRN_DAR, r10 | ||
412 | mtspr SPRN_SPRG2, r11 | ||
413 | #endif | ||
414 | mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ | 394 | mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ |
415 | 395 | ||
416 | /* If we are faulting a kernel address, we have to use the | 396 | /* If we are faulting a kernel address, we have to use the |
@@ -483,19 +463,12 @@ DataStoreTLBMiss: | |||
483 | mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ | 463 | mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ |
484 | 464 | ||
485 | /* Restore registers */ | 465 | /* Restore registers */ |
486 | #ifndef CONFIG_8xx_CPU6 | 466 | #ifdef CONFIG_8xx_CPU6 |
487 | mfspr r10, SPRN_DAR | ||
488 | mtcr r10 | ||
489 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
490 | mfspr r11, SPRN_SPRG2 | ||
491 | #else | ||
492 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
493 | lwz r11, 0(r0) | ||
494 | mtcr r11 | ||
495 | lwz r11, 4(r0) | ||
496 | lwz r3, 8(r0) | 467 | lwz r3, 8(r0) |
497 | #endif | 468 | #endif |
498 | mfspr r10, SPRN_M_TW | 469 | mtspr SPRN_DAR, r11 /* Tag DAR */ |
470 | mfspr r10, SPRN_SPRG_SCRATCH2 | ||
471 | EXCEPTION_EPILOG_0 | ||
499 | rfi | 472 | rfi |
500 | 473 | ||
501 | /* This is an instruction TLB error on the MPC8xx. This could be due | 474 | /* This is an instruction TLB error on the MPC8xx. This could be due |
@@ -507,35 +480,18 @@ InstructionTLBError: | |||
507 | b InstructionAccess | 480 | b InstructionAccess |
508 | 481 | ||
509 | /* This is the data TLB error on the MPC8xx. This could be due to | 482 | /* This is the data TLB error on the MPC8xx. This could be due to |
510 | * many reasons, including a dirty update to a pte. We can catch that | 483 | * many reasons, including a dirty update to a pte. We bail out to |
511 | * one here, but anything else is an error. First, we track down the | 484 | * a higher level function that can handle it. |
512 | * Linux pte. If it is valid, write access is allowed, but the | ||
513 | * page dirty bit is not set, we will set it and reload the TLB. For | ||
514 | * any other case, we bail out to a higher level function that can | ||
515 | * handle it. | ||
516 | */ | 485 | */ |
517 | . = 0x1400 | 486 | . = 0x1400 |
518 | DataTLBError: | 487 | DataTLBError: |
519 | #ifdef CONFIG_8xx_CPU6 | 488 | EXCEPTION_PROLOG_0 |
520 | stw r3, 8(r0) | ||
521 | #endif | ||
522 | DO_8xx_CPU6(0x3f80, r3) | ||
523 | mtspr SPRN_M_TW, r10 /* Save a couple of working registers */ | ||
524 | mfcr r10 | ||
525 | stw r10, 0(r0) | ||
526 | stw r11, 4(r0) | ||
527 | 489 | ||
528 | mfspr r10, SPRN_DAR | 490 | mfspr r11, SPRN_DAR |
529 | cmpwi cr0, r10, 0x00f0 | 491 | cmpwi cr0, r11, 0x00f0 |
530 | beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ | 492 | beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ |
531 | DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */ | 493 | DARFixed:/* Return from dcbx instruction bug workaround */ |
532 | mfspr r10, SPRN_M_TW /* Restore registers */ | 494 | EXCEPTION_EPILOG_0 |
533 | lwz r11, 0(r0) | ||
534 | mtcr r11 | ||
535 | lwz r11, 4(r0) | ||
536 | #ifdef CONFIG_8xx_CPU6 | ||
537 | lwz r3, 8(r0) | ||
538 | #endif | ||
539 | b DataAccess | 495 | b DataAccess |
540 | 496 | ||
541 | EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) | 497 | EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) |
@@ -559,11 +515,15 @@ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR | |||
559 | 515 | ||
560 | /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions | 516 | /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions |
561 | * by decoding the registers used by the dcbx instruction and adding them. | 517 | * by decoding the registers used by the dcbx instruction and adding them. |
562 | * DAR is set to the calculated address and r10 also holds the EA on exit. | 518 | * DAR is set to the calculated address. |
563 | */ | 519 | */ |
564 | /* define if you don't want to use self modifying code */ | 520 | /* define if you don't want to use self modifying code */ |
565 | #define NO_SELF_MODIFYING_CODE | 521 | #define NO_SELF_MODIFYING_CODE |
566 | FixupDAR:/* Entry point for dcbx workaround. */ | 522 | FixupDAR:/* Entry point for dcbx workaround. */ |
523 | #ifdef CONFIG_8xx_CPU6 | ||
524 | stw r3, 8(r0) | ||
525 | #endif | ||
526 | mtspr SPRN_SPRG_SCRATCH2, r10 | ||
567 | /* fetch instruction from memory. */ | 527 | /* fetch instruction from memory. */ |
568 | mfspr r10, SPRN_SRR0 | 528 | mfspr r10, SPRN_SRR0 |
569 | andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ | 529 | andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ |
@@ -579,16 +539,17 @@ FixupDAR:/* Entry point for dcbx workaround. */ | |||
579 | mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ | 539 | mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ |
580 | mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ | 540 | mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ |
581 | lwz r11, 0(r11) /* Get the pte */ | 541 | lwz r11, 0(r11) /* Get the pte */ |
542 | #ifdef CONFIG_8xx_CPU6 | ||
543 | lwz r3, 8(r0) /* restore r3 from memory */ | ||
544 | #endif | ||
582 | /* concat physical page address(r11) and page offset(r10) */ | 545 | /* concat physical page address(r11) and page offset(r10) */ |
583 | rlwimi r11, r10, 0, 20, 31 | 546 | rlwimi r11, r10, 0, 20, 31 |
584 | lwz r11,0(r11) | 547 | lwz r11,0(r11) |
585 | /* Check if it really is a dcbx instruction. */ | 548 | /* Check if it really is a dcbx instruction. */ |
586 | /* dcbt and dcbtst does not generate DTLB Misses/Errors, | 549 | /* dcbt and dcbtst does not generate DTLB Misses/Errors, |
587 | * no need to include them here */ | 550 | * no need to include them here */ |
588 | srwi r10, r11, 26 /* check if major OP code is 31 */ | 551 | xoris r10, r11, 0x7c00 /* check if major OP code is 31 */ |
589 | cmpwi cr0, r10, 31 | 552 | rlwinm r10, r10, 0, 21, 5 |
590 | bne- 141f | ||
591 | rlwinm r10, r11, 0, 21, 30 | ||
592 | cmpwi cr0, r10, 2028 /* Is dcbz? */ | 553 | cmpwi cr0, r10, 2028 /* Is dcbz? */ |
593 | beq+ 142f | 554 | beq+ 142f |
594 | cmpwi cr0, r10, 940 /* Is dcbi? */ | 555 | cmpwi cr0, r10, 940 /* Is dcbi? */ |
@@ -599,16 +560,13 @@ FixupDAR:/* Entry point for dcbx workaround. */ | |||
599 | beq+ 142f | 560 | beq+ 142f |
600 | cmpwi cr0, r10, 1964 /* Is icbi? */ | 561 | cmpwi cr0, r10, 1964 /* Is icbi? */ |
601 | beq+ 142f | 562 | beq+ 142f |
602 | 141: mfspr r10, SPRN_DAR /* r10 must hold DAR at exit */ | 563 | 141: mfspr r10,SPRN_SPRG_SCRATCH2 |
603 | b DARFixed /* Nope, go back to normal TLB processing */ | 564 | b DARFixed /* Nope, go back to normal TLB processing */ |
604 | 565 | ||
605 | 144: mfspr r10, SPRN_DSISR | 566 | 144: mfspr r10, SPRN_DSISR |
606 | rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ | 567 | rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ |
607 | mtspr SPRN_DSISR, r10 | 568 | mtspr SPRN_DSISR, r10 |
608 | 142: /* continue, it was a dcbx, dcbi instruction. */ | 569 | 142: /* continue, it was a dcbx, dcbi instruction. */ |
609 | #ifdef CONFIG_8xx_CPU6 | ||
610 | lwz r3, 8(r0) /* restore r3 from memory */ | ||
611 | #endif | ||
612 | #ifndef NO_SELF_MODIFYING_CODE | 570 | #ifndef NO_SELF_MODIFYING_CODE |
613 | andis. r10,r11,0x1f /* test if reg RA is r0 */ | 571 | andis. r10,r11,0x1f /* test if reg RA is r0 */ |
614 | li r10,modified_instr@l | 572 | li r10,modified_instr@l |
@@ -619,14 +577,15 @@ FixupDAR:/* Entry point for dcbx workaround. */ | |||
619 | stw r11,0(r10) /* store add/and instruction */ | 577 | stw r11,0(r10) /* store add/and instruction */ |
620 | dcbf 0,r10 /* flush new instr. to memory. */ | 578 | dcbf 0,r10 /* flush new instr. to memory. */ |
621 | icbi 0,r10 /* invalidate instr. cache line */ | 579 | icbi 0,r10 /* invalidate instr. cache line */ |
622 | lwz r11, 4(r0) /* restore r11 from memory */ | 580 | mfspr r11, SPRN_SPRG_SCRATCH1 /* restore r11 */ |
623 | mfspr r10, SPRN_M_TW /* restore r10 from M_TW */ | 581 | mfspr r10, SPRN_SPRG_SCRATCH0 /* restore r10 */ |
624 | isync /* Wait until new instr is loaded from memory */ | 582 | isync /* Wait until new instr is loaded from memory */ |
625 | modified_instr: | 583 | modified_instr: |
626 | .space 4 /* this is where the add instr. is stored */ | 584 | .space 4 /* this is where the add instr. is stored */ |
627 | bne+ 143f | 585 | bne+ 143f |
628 | subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */ | 586 | subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */ |
629 | 143: mtdar r10 /* store faulting EA in DAR */ | 587 | 143: mtdar r10 /* store faulting EA in DAR */ |
588 | mfspr r10,SPRN_SPRG_SCRATCH2 | ||
630 | b DARFixed /* Go back to normal TLB handling */ | 589 | b DARFixed /* Go back to normal TLB handling */ |
631 | #else | 590 | #else |
632 | mfctr r10 | 591 | mfctr r10 |
@@ -680,13 +639,16 @@ modified_instr: | |||
680 | mfdar r11 | 639 | mfdar r11 |
681 | mtctr r11 /* restore ctr reg from DAR */ | 640 | mtctr r11 /* restore ctr reg from DAR */ |
682 | mtdar r10 /* save fault EA to DAR */ | 641 | mtdar r10 /* save fault EA to DAR */ |
642 | mfspr r10,SPRN_SPRG_SCRATCH2 | ||
683 | b DARFixed /* Go back to normal TLB handling */ | 643 | b DARFixed /* Go back to normal TLB handling */ |
684 | 644 | ||
685 | /* special handling for r10,r11 since these are modified already */ | 645 | /* special handling for r10,r11 since these are modified already */ |
686 | 153: lwz r11, 4(r0) /* load r11 from memory */ | 646 | 153: mfspr r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */ |
687 | b 155f | 647 | add r10, r10, r11 /* add it */ |
688 | 154: mfspr r11, SPRN_M_TW /* load r10 from M_TW */ | 648 | mfctr r11 /* restore r11 */ |
689 | 155: add r10, r10, r11 /* add it */ | 649 | b 151b |
650 | 154: mfspr r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */ | ||
651 | add r10, r10, r11 /* add it */ | ||
690 | mfctr r11 /* restore r11 */ | 652 | mfctr r11 /* restore r11 */ |
691 | b 151b | 653 | b 151b |
692 | #endif | 654 | #endif |
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 0bb5918faaaf..1f7d84e2e8b2 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c | |||
@@ -293,7 +293,7 @@ out: | |||
293 | /* | 293 | /* |
294 | * Handle single-step exceptions following a DABR hit. | 294 | * Handle single-step exceptions following a DABR hit. |
295 | */ | 295 | */ |
296 | int __kprobes single_step_dabr_instruction(struct die_args *args) | 296 | static int __kprobes single_step_dabr_instruction(struct die_args *args) |
297 | { | 297 | { |
298 | struct pt_regs *regs = args->regs; | 298 | struct pt_regs *regs = args->regs; |
299 | struct perf_event *bp = NULL; | 299 | struct perf_event *bp = NULL; |
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 1114d13ac19f..ac86c53e2542 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -55,7 +55,7 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */ | |||
55 | struct bus_type ibmebus_bus_type; | 55 | struct bus_type ibmebus_bus_type; |
56 | 56 | ||
57 | /* These devices will automatically be added to the bus during init */ | 57 | /* These devices will automatically be added to the bus during init */ |
58 | static struct of_device_id __initdata ibmebus_matches[] = { | 58 | static const struct of_device_id ibmebus_matches[] __initconst = { |
59 | { .compatible = "IBM,lhca" }, | 59 | { .compatible = "IBM,lhca" }, |
60 | { .compatible = "IBM,lhea" }, | 60 | { .compatible = "IBM,lhea" }, |
61 | {}, | 61 | {}, |
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index be05841396cf..c0754bbf8118 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S | |||
@@ -73,7 +73,7 @@ _GLOBAL(power7_powersave_common) | |||
73 | 73 | ||
74 | /* Check if something happened while soft-disabled */ | 74 | /* Check if something happened while soft-disabled */ |
75 | lbz r0,PACAIRQHAPPENED(r13) | 75 | lbz r0,PACAIRQHAPPENED(r13) |
76 | cmpwi cr0,r0,0 | 76 | andi. r0,r0,~PACA_IRQ_HARD_DIS@l |
77 | beq 1f | 77 | beq 1f |
78 | cmpwi cr0,r4,0 | 78 | cmpwi cr0,r4,0 |
79 | beq 1f | 79 | beq 1f |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 4c5891de162e..8eb857f216c1 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -444,13 +444,13 @@ void migrate_irqs(void) | |||
444 | 444 | ||
445 | cpumask_and(mask, data->affinity, map); | 445 | cpumask_and(mask, data->affinity, map); |
446 | if (cpumask_any(mask) >= nr_cpu_ids) { | 446 | if (cpumask_any(mask) >= nr_cpu_ids) { |
447 | printk("Breaking affinity for irq %i\n", irq); | 447 | pr_warn("Breaking affinity for irq %i\n", irq); |
448 | cpumask_copy(mask, map); | 448 | cpumask_copy(mask, map); |
449 | } | 449 | } |
450 | if (chip->irq_set_affinity) | 450 | if (chip->irq_set_affinity) |
451 | chip->irq_set_affinity(data, mask, true); | 451 | chip->irq_set_affinity(data, mask, true); |
452 | else if (desc->action && !(warned++)) | 452 | else if (desc->action && !(warned++)) |
453 | printk("Cannot set affinity for irq %i\n", irq); | 453 | pr_err("Cannot set affinity for irq %i\n", irq); |
454 | } | 454 | } |
455 | 455 | ||
456 | free_cpumask_var(mask); | 456 | free_cpumask_var(mask); |
@@ -470,7 +470,7 @@ static inline void check_stack_overflow(void) | |||
470 | 470 | ||
471 | /* check for stack overflow: is there less than 2KB free? */ | 471 | /* check for stack overflow: is there less than 2KB free? */ |
472 | if (unlikely(sp < (sizeof(struct thread_info) + 2048))) { | 472 | if (unlikely(sp < (sizeof(struct thread_info) + 2048))) { |
473 | printk("do_IRQ: stack overflow: %ld\n", | 473 | pr_err("do_IRQ: stack overflow: %ld\n", |
474 | sp - sizeof(struct thread_info)); | 474 | sp - sizeof(struct thread_info)); |
475 | dump_stack(); | 475 | dump_stack(); |
476 | } | 476 | } |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 936258881c98..7b750c4ed5c7 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -35,7 +35,7 @@ static struct legacy_serial_info { | |||
35 | phys_addr_t taddr; | 35 | phys_addr_t taddr; |
36 | } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; | 36 | } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; |
37 | 37 | ||
38 | static struct of_device_id legacy_serial_parents[] __initdata = { | 38 | static const struct of_device_id legacy_serial_parents[] __initconst = { |
39 | {.type = "soc",}, | 39 | {.type = "soc",}, |
40 | {.type = "tsi-bridge",}, | 40 | {.type = "tsi-bridge",}, |
41 | {.type = "opb", }, | 41 | {.type = "opb", }, |
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 6cff040bf456..c94d2e018d84 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c | |||
@@ -15,6 +15,9 @@ | |||
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
18 | #include <linux/module.h> | 21 | #include <linux/module.h> |
19 | #include <linux/moduleloader.h> | 22 | #include <linux/moduleloader.h> |
20 | #include <linux/elf.h> | 23 | #include <linux/elf.h> |
@@ -28,12 +31,6 @@ | |||
28 | #include <linux/sort.h> | 31 | #include <linux/sort.h> |
29 | #include <asm/setup.h> | 32 | #include <asm/setup.h> |
30 | 33 | ||
31 | #if 0 | ||
32 | #define DEBUGP printk | ||
33 | #else | ||
34 | #define DEBUGP(fmt , ...) | ||
35 | #endif | ||
36 | |||
37 | /* Count how many different relocations (different symbol, different | 34 | /* Count how many different relocations (different symbol, different |
38 | addend) */ | 35 | addend) */ |
39 | static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) | 36 | static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) |
@@ -121,8 +118,8 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr, | |||
121 | continue; | 118 | continue; |
122 | 119 | ||
123 | if (sechdrs[i].sh_type == SHT_RELA) { | 120 | if (sechdrs[i].sh_type == SHT_RELA) { |
124 | DEBUGP("Found relocations in section %u\n", i); | 121 | pr_debug("Found relocations in section %u\n", i); |
125 | DEBUGP("Ptr: %p. Number: %u\n", | 122 | pr_debug("Ptr: %p. Number: %u\n", |
126 | (void *)hdr + sechdrs[i].sh_offset, | 123 | (void *)hdr + sechdrs[i].sh_offset, |
127 | sechdrs[i].sh_size / sizeof(Elf32_Rela)); | 124 | sechdrs[i].sh_size / sizeof(Elf32_Rela)); |
128 | 125 | ||
@@ -161,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr, | |||
161 | me->arch.core_plt_section = i; | 158 | me->arch.core_plt_section = i; |
162 | } | 159 | } |
163 | if (!me->arch.core_plt_section || !me->arch.init_plt_section) { | 160 | if (!me->arch.core_plt_section || !me->arch.init_plt_section) { |
164 | printk("Module doesn't contain .plt or .init.plt sections.\n"); | 161 | pr_err("Module doesn't contain .plt or .init.plt sections.\n"); |
165 | return -ENOEXEC; | 162 | return -ENOEXEC; |
166 | } | 163 | } |
167 | 164 | ||
@@ -189,7 +186,7 @@ static uint32_t do_plt_call(void *location, | |||
189 | { | 186 | { |
190 | struct ppc_plt_entry *entry; | 187 | struct ppc_plt_entry *entry; |
191 | 188 | ||
192 | DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); | 189 | pr_debug("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); |
193 | /* Init, or core PLT? */ | 190 | /* Init, or core PLT? */ |
194 | if (location >= mod->module_core | 191 | if (location >= mod->module_core |
195 | && location < mod->module_core + mod->core_size) | 192 | && location < mod->module_core + mod->core_size) |
@@ -208,7 +205,7 @@ static uint32_t do_plt_call(void *location, | |||
208 | entry->jump[2] = 0x7d8903a6; /* mtctr r12 */ | 205 | entry->jump[2] = 0x7d8903a6; /* mtctr r12 */ |
209 | entry->jump[3] = 0x4e800420; /* bctr */ | 206 | entry->jump[3] = 0x4e800420; /* bctr */ |
210 | 207 | ||
211 | DEBUGP("Initialized plt for 0x%x at %p\n", val, entry); | 208 | pr_debug("Initialized plt for 0x%x at %p\n", val, entry); |
212 | return (uint32_t)entry; | 209 | return (uint32_t)entry; |
213 | } | 210 | } |
214 | 211 | ||
@@ -224,7 +221,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
224 | uint32_t *location; | 221 | uint32_t *location; |
225 | uint32_t value; | 222 | uint32_t value; |
226 | 223 | ||
227 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, | 224 | pr_debug("Applying ADD relocate section %u to %u\n", relsec, |
228 | sechdrs[relsec].sh_info); | 225 | sechdrs[relsec].sh_info); |
229 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { | 226 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { |
230 | /* This is where to make the change */ | 227 | /* This is where to make the change */ |
@@ -268,17 +265,17 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
268 | sechdrs, module); | 265 | sechdrs, module); |
269 | 266 | ||
270 | /* Only replace bits 2 through 26 */ | 267 | /* Only replace bits 2 through 26 */ |
271 | DEBUGP("REL24 value = %08X. location = %08X\n", | 268 | pr_debug("REL24 value = %08X. location = %08X\n", |
272 | value, (uint32_t)location); | 269 | value, (uint32_t)location); |
273 | DEBUGP("Location before: %08X.\n", | 270 | pr_debug("Location before: %08X.\n", |
274 | *(uint32_t *)location); | 271 | *(uint32_t *)location); |
275 | *(uint32_t *)location | 272 | *(uint32_t *)location |
276 | = (*(uint32_t *)location & ~0x03fffffc) | 273 | = (*(uint32_t *)location & ~0x03fffffc) |
277 | | ((value - (uint32_t)location) | 274 | | ((value - (uint32_t)location) |
278 | & 0x03fffffc); | 275 | & 0x03fffffc); |
279 | DEBUGP("Location after: %08X.\n", | 276 | pr_debug("Location after: %08X.\n", |
280 | *(uint32_t *)location); | 277 | *(uint32_t *)location); |
281 | DEBUGP("ie. jump to %08X+%08X = %08X\n", | 278 | pr_debug("ie. jump to %08X+%08X = %08X\n", |
282 | *(uint32_t *)location & 0x03fffffc, | 279 | *(uint32_t *)location & 0x03fffffc, |
283 | (uint32_t)location, | 280 | (uint32_t)location, |
284 | (*(uint32_t *)location & 0x03fffffc) | 281 | (*(uint32_t *)location & 0x03fffffc) |
@@ -291,7 +288,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
291 | break; | 288 | break; |
292 | 289 | ||
293 | default: | 290 | default: |
294 | printk("%s: unknown ADD relocation: %u\n", | 291 | pr_err("%s: unknown ADD relocation: %u\n", |
295 | module->name, | 292 | module->name, |
296 | ELF32_R_TYPE(rela[i].r_info)); | 293 | ELF32_R_TYPE(rela[i].r_info)); |
297 | return -ENOEXEC; | 294 | return -ENOEXEC; |
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index d807ee626af9..68384514506b 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c | |||
@@ -15,6 +15,9 @@ | |||
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
18 | #include <linux/module.h> | 21 | #include <linux/module.h> |
19 | #include <linux/elf.h> | 22 | #include <linux/elf.h> |
20 | #include <linux/moduleloader.h> | 23 | #include <linux/moduleloader.h> |
@@ -36,11 +39,6 @@ | |||
36 | Using a magic allocator which places modules within 32MB solves | 39 | Using a magic allocator which places modules within 32MB solves |
37 | this, and makes other things simpler. Anton? | 40 | this, and makes other things simpler. Anton? |
38 | --RR. */ | 41 | --RR. */ |
39 | #if 0 | ||
40 | #define DEBUGP printk | ||
41 | #else | ||
42 | #define DEBUGP(fmt , ...) | ||
43 | #endif | ||
44 | 42 | ||
45 | #if defined(_CALL_ELF) && _CALL_ELF == 2 | 43 | #if defined(_CALL_ELF) && _CALL_ELF == 2 |
46 | #define R2_STACK_OFFSET 24 | 44 | #define R2_STACK_OFFSET 24 |
@@ -279,8 +277,8 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, | |||
279 | /* Every relocated section... */ | 277 | /* Every relocated section... */ |
280 | for (i = 1; i < hdr->e_shnum; i++) { | 278 | for (i = 1; i < hdr->e_shnum; i++) { |
281 | if (sechdrs[i].sh_type == SHT_RELA) { | 279 | if (sechdrs[i].sh_type == SHT_RELA) { |
282 | DEBUGP("Found relocations in section %u\n", i); | 280 | pr_debug("Found relocations in section %u\n", i); |
283 | DEBUGP("Ptr: %p. Number: %lu\n", | 281 | pr_debug("Ptr: %p. Number: %Lu\n", |
284 | (void *)sechdrs[i].sh_addr, | 282 | (void *)sechdrs[i].sh_addr, |
285 | sechdrs[i].sh_size / sizeof(Elf64_Rela)); | 283 | sechdrs[i].sh_size / sizeof(Elf64_Rela)); |
286 | 284 | ||
@@ -304,7 +302,7 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, | |||
304 | relocs++; | 302 | relocs++; |
305 | #endif | 303 | #endif |
306 | 304 | ||
307 | DEBUGP("Looks like a total of %lu stubs, max\n", relocs); | 305 | pr_debug("Looks like a total of %lu stubs, max\n", relocs); |
308 | return relocs * sizeof(struct ppc64_stub_entry); | 306 | return relocs * sizeof(struct ppc64_stub_entry); |
309 | } | 307 | } |
310 | 308 | ||
@@ -390,7 +388,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr, | |||
390 | } | 388 | } |
391 | 389 | ||
392 | if (!me->arch.stubs_section) { | 390 | if (!me->arch.stubs_section) { |
393 | printk("%s: doesn't contain .stubs.\n", me->name); | 391 | pr_err("%s: doesn't contain .stubs.\n", me->name); |
394 | return -ENOEXEC; | 392 | return -ENOEXEC; |
395 | } | 393 | } |
396 | 394 | ||
@@ -434,11 +432,11 @@ static inline int create_stub(Elf64_Shdr *sechdrs, | |||
434 | /* Stub uses address relative to r2. */ | 432 | /* Stub uses address relative to r2. */ |
435 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); | 433 | reladdr = (unsigned long)entry - my_r2(sechdrs, me); |
436 | if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { | 434 | if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { |
437 | printk("%s: Address %p of stub out of range of %p.\n", | 435 | pr_err("%s: Address %p of stub out of range of %p.\n", |
438 | me->name, (void *)reladdr, (void *)my_r2); | 436 | me->name, (void *)reladdr, (void *)my_r2); |
439 | return 0; | 437 | return 0; |
440 | } | 438 | } |
441 | DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); | 439 | pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); |
442 | 440 | ||
443 | entry->jump[0] |= PPC_HA(reladdr); | 441 | entry->jump[0] |= PPC_HA(reladdr); |
444 | entry->jump[1] |= PPC_LO(reladdr); | 442 | entry->jump[1] |= PPC_LO(reladdr); |
@@ -477,7 +475,7 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, | |||
477 | static int restore_r2(u32 *instruction, struct module *me) | 475 | static int restore_r2(u32 *instruction, struct module *me) |
478 | { | 476 | { |
479 | if (*instruction != PPC_INST_NOP) { | 477 | if (*instruction != PPC_INST_NOP) { |
480 | printk("%s: Expect noop after relocate, got %08x\n", | 478 | pr_err("%s: Expect noop after relocate, got %08x\n", |
481 | me->name, *instruction); | 479 | me->name, *instruction); |
482 | return 0; | 480 | return 0; |
483 | } | 481 | } |
@@ -498,7 +496,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
498 | unsigned long *location; | 496 | unsigned long *location; |
499 | unsigned long value; | 497 | unsigned long value; |
500 | 498 | ||
501 | DEBUGP("Applying ADD relocate section %u to %u\n", relsec, | 499 | pr_debug("Applying ADD relocate section %u to %u\n", relsec, |
502 | sechdrs[relsec].sh_info); | 500 | sechdrs[relsec].sh_info); |
503 | 501 | ||
504 | /* First time we're called, we can fix up .TOC. */ | 502 | /* First time we're called, we can fix up .TOC. */ |
@@ -519,7 +517,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
519 | sym = (Elf64_Sym *)sechdrs[symindex].sh_addr | 517 | sym = (Elf64_Sym *)sechdrs[symindex].sh_addr |
520 | + ELF64_R_SYM(rela[i].r_info); | 518 | + ELF64_R_SYM(rela[i].r_info); |
521 | 519 | ||
522 | DEBUGP("RELOC at %p: %li-type as %s (%lu) + %li\n", | 520 | pr_debug("RELOC at %p: %li-type as %s (0x%lx) + %li\n", |
523 | location, (long)ELF64_R_TYPE(rela[i].r_info), | 521 | location, (long)ELF64_R_TYPE(rela[i].r_info), |
524 | strtab + sym->st_name, (unsigned long)sym->st_value, | 522 | strtab + sym->st_name, (unsigned long)sym->st_value, |
525 | (long)rela[i].r_addend); | 523 | (long)rela[i].r_addend); |
@@ -546,7 +544,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
546 | /* Subtract TOC pointer */ | 544 | /* Subtract TOC pointer */ |
547 | value -= my_r2(sechdrs, me); | 545 | value -= my_r2(sechdrs, me); |
548 | if (value + 0x8000 > 0xffff) { | 546 | if (value + 0x8000 > 0xffff) { |
549 | printk("%s: bad TOC16 relocation (%lu)\n", | 547 | pr_err("%s: bad TOC16 relocation (0x%lx)\n", |
550 | me->name, value); | 548 | me->name, value); |
551 | return -ENOEXEC; | 549 | return -ENOEXEC; |
552 | } | 550 | } |
@@ -567,7 +565,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
567 | /* Subtract TOC pointer */ | 565 | /* Subtract TOC pointer */ |
568 | value -= my_r2(sechdrs, me); | 566 | value -= my_r2(sechdrs, me); |
569 | if ((value & 3) != 0 || value + 0x8000 > 0xffff) { | 567 | if ((value & 3) != 0 || value + 0x8000 > 0xffff) { |
570 | printk("%s: bad TOC16_DS relocation (%lu)\n", | 568 | pr_err("%s: bad TOC16_DS relocation (0x%lx)\n", |
571 | me->name, value); | 569 | me->name, value); |
572 | return -ENOEXEC; | 570 | return -ENOEXEC; |
573 | } | 571 | } |
@@ -580,7 +578,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
580 | /* Subtract TOC pointer */ | 578 | /* Subtract TOC pointer */ |
581 | value -= my_r2(sechdrs, me); | 579 | value -= my_r2(sechdrs, me); |
582 | if ((value & 3) != 0) { | 580 | if ((value & 3) != 0) { |
583 | printk("%s: bad TOC16_LO_DS relocation (%lu)\n", | 581 | pr_err("%s: bad TOC16_LO_DS relocation (0x%lx)\n", |
584 | me->name, value); | 582 | me->name, value); |
585 | return -ENOEXEC; | 583 | return -ENOEXEC; |
586 | } | 584 | } |
@@ -613,7 +611,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
613 | /* Convert value to relative */ | 611 | /* Convert value to relative */ |
614 | value -= (unsigned long)location; | 612 | value -= (unsigned long)location; |
615 | if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){ | 613 | if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){ |
616 | printk("%s: REL24 %li out of range!\n", | 614 | pr_err("%s: REL24 %li out of range!\n", |
617 | me->name, (long int)value); | 615 | me->name, (long int)value); |
618 | return -ENOEXEC; | 616 | return -ENOEXEC; |
619 | } | 617 | } |
@@ -655,7 +653,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
655 | break; | 653 | break; |
656 | 654 | ||
657 | default: | 655 | default: |
658 | printk("%s: Unknown ADD relocation: %lu\n", | 656 | pr_err("%s: Unknown ADD relocation: %lu\n", |
659 | me->name, | 657 | me->name, |
660 | (unsigned long)ELF64_R_TYPE(rela[i].r_info)); | 658 | (unsigned long)ELF64_R_TYPE(rela[i].r_info)); |
661 | return -ENOEXEC; | 659 | return -ENOEXEC; |
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 28b898e68185..34f7c9b7cd96 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c | |||
@@ -567,7 +567,7 @@ static int __init nvram_init(void) | |||
567 | return rc; | 567 | return rc; |
568 | } | 568 | } |
569 | 569 | ||
570 | void __exit nvram_cleanup(void) | 570 | static void __exit nvram_cleanup(void) |
571 | { | 571 | { |
572 | misc_deregister( &nvram_dev ); | 572 | misc_deregister( &nvram_dev ); |
573 | } | 573 | } |
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index a7b743076720..f87bc1b4bdda 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
@@ -97,7 +97,7 @@ static int of_pci_phb_probe(struct platform_device *dev) | |||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | static struct of_device_id of_pci_phb_ids[] = { | 100 | static const struct of_device_id of_pci_phb_ids[] = { |
101 | { .type = "pci", }, | 101 | { .type = "pci", }, |
102 | { .type = "pcix", }, | 102 | { .type = "pcix", }, |
103 | { .type = "pcie", }, | 103 | { .type = "pcie", }, |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index b2814e23e1ed..bd70a51d5747 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -1140,7 +1140,7 @@ static int reparent_resources(struct resource *parent, | |||
1140 | * as well. | 1140 | * as well. |
1141 | */ | 1141 | */ |
1142 | 1142 | ||
1143 | void pcibios_allocate_bus_resources(struct pci_bus *bus) | 1143 | static void pcibios_allocate_bus_resources(struct pci_bus *bus) |
1144 | { | 1144 | { |
1145 | struct pci_bus *b; | 1145 | struct pci_bus *b; |
1146 | int i; | 1146 | int i; |
@@ -1561,7 +1561,6 @@ EARLY_PCI_OP(write, byte, u8) | |||
1561 | EARLY_PCI_OP(write, word, u16) | 1561 | EARLY_PCI_OP(write, word, u16) |
1562 | EARLY_PCI_OP(write, dword, u32) | 1562 | EARLY_PCI_OP(write, dword, u32) |
1563 | 1563 | ||
1564 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | ||
1565 | int early_find_capability(struct pci_controller *hose, int bus, int devfn, | 1564 | int early_find_capability(struct pci_controller *hose, int bus, int devfn, |
1566 | int cap) | 1565 | int cap) |
1567 | { | 1566 | { |
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 44562aa97f16..e6245e9c7d8d 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -38,7 +38,7 @@ static u32 get_int_prop(struct device_node *np, const char *name, u32 def) | |||
38 | * @addr0: value of 1st cell of a device tree PCI address. | 38 | * @addr0: value of 1st cell of a device tree PCI address. |
39 | * @bridge: Set this flag if the address is from a bridge 'ranges' property | 39 | * @bridge: Set this flag if the address is from a bridge 'ranges' property |
40 | */ | 40 | */ |
41 | unsigned int pci_parse_of_flags(u32 addr0, int bridge) | 41 | static unsigned int pci_parse_of_flags(u32 addr0, int bridge) |
42 | { | 42 | { |
43 | unsigned int flags = 0; | 43 | unsigned int flags = 0; |
44 | 44 | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 48d17d6fca5b..c4dfff6c2719 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -1,207 +1,41 @@ | |||
1 | #include <linux/export.h> | 1 | #include <linux/ftrace.h> |
2 | #include <linux/threads.h> | 2 | #include <linux/mm.h> |
3 | #include <linux/smp.h> | ||
4 | #include <linux/sched.h> | ||
5 | #include <linux/elfcore.h> | ||
6 | #include <linux/string.h> | ||
7 | #include <linux/interrupt.h> | ||
8 | #include <linux/screen_info.h> | ||
9 | #include <linux/vt_kern.h> | ||
10 | #include <linux/nvram.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/pci.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/bitops.h> | ||
15 | 3 | ||
16 | #include <asm/page.h> | ||
17 | #include <asm/processor.h> | 4 | #include <asm/processor.h> |
18 | #include <asm/cacheflush.h> | ||
19 | #include <asm/uaccess.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <linux/atomic.h> | ||
22 | #include <asm/checksum.h> | ||
23 | #include <asm/pgtable.h> | ||
24 | #include <asm/tlbflush.h> | ||
25 | #include <linux/adb.h> | ||
26 | #include <linux/cuda.h> | ||
27 | #include <linux/pmu.h> | ||
28 | #include <asm/prom.h> | ||
29 | #include <asm/pci-bridge.h> | ||
30 | #include <asm/irq.h> | ||
31 | #include <asm/pmac_feature.h> | ||
32 | #include <asm/dma.h> | ||
33 | #include <asm/machdep.h> | ||
34 | #include <asm/hw_irq.h> | ||
35 | #include <asm/nvram.h> | ||
36 | #include <asm/mmu_context.h> | ||
37 | #include <asm/backlight.h> | ||
38 | #include <asm/time.h> | ||
39 | #include <asm/cputable.h> | ||
40 | #include <asm/btext.h> | ||
41 | #include <asm/div64.h> | ||
42 | #include <asm/signal.h> | ||
43 | #include <asm/dcr.h> | ||
44 | #include <asm/ftrace.h> | ||
45 | #include <asm/switch_to.h> | 5 | #include <asm/switch_to.h> |
6 | #include <asm/cacheflush.h> | ||
46 | #include <asm/epapr_hcalls.h> | 7 | #include <asm/epapr_hcalls.h> |
47 | 8 | ||
48 | #ifdef CONFIG_PPC32 | 9 | EXPORT_SYMBOL(flush_dcache_range); |
49 | extern void transfer_to_handler(void); | 10 | EXPORT_SYMBOL(flush_icache_range); |
50 | extern void do_IRQ(struct pt_regs *regs); | ||
51 | extern void machine_check_exception(struct pt_regs *regs); | ||
52 | extern void alignment_exception(struct pt_regs *regs); | ||
53 | extern void program_check_exception(struct pt_regs *regs); | ||
54 | extern void single_step_exception(struct pt_regs *regs); | ||
55 | extern int sys_sigreturn(struct pt_regs *regs); | ||
56 | 11 | ||
57 | EXPORT_SYMBOL(clear_pages); | 12 | EXPORT_SYMBOL(empty_zero_page); |
58 | EXPORT_SYMBOL(ISA_DMA_THRESHOLD); | ||
59 | EXPORT_SYMBOL(DMA_MODE_READ); | ||
60 | EXPORT_SYMBOL(DMA_MODE_WRITE); | ||
61 | 13 | ||
62 | EXPORT_SYMBOL(transfer_to_handler); | 14 | long long __bswapdi2(long long); |
63 | EXPORT_SYMBOL(do_IRQ); | 15 | EXPORT_SYMBOL(__bswapdi2); |
64 | EXPORT_SYMBOL(machine_check_exception); | ||
65 | EXPORT_SYMBOL(alignment_exception); | ||
66 | EXPORT_SYMBOL(program_check_exception); | ||
67 | EXPORT_SYMBOL(single_step_exception); | ||
68 | EXPORT_SYMBOL(sys_sigreturn); | ||
69 | #endif | ||
70 | 16 | ||
71 | #ifdef CONFIG_FUNCTION_TRACER | 17 | #ifdef CONFIG_FUNCTION_TRACER |
72 | EXPORT_SYMBOL(_mcount); | 18 | EXPORT_SYMBOL(_mcount); |
73 | #endif | 19 | #endif |
74 | 20 | ||
75 | EXPORT_SYMBOL(strcpy); | ||
76 | EXPORT_SYMBOL(strncpy); | ||
77 | EXPORT_SYMBOL(strcat); | ||
78 | EXPORT_SYMBOL(strlen); | ||
79 | EXPORT_SYMBOL(strcmp); | ||
80 | EXPORT_SYMBOL(strncmp); | ||
81 | |||
82 | #ifndef CONFIG_GENERIC_CSUM | ||
83 | EXPORT_SYMBOL(csum_partial); | ||
84 | EXPORT_SYMBOL(csum_partial_copy_generic); | ||
85 | EXPORT_SYMBOL(ip_fast_csum); | ||
86 | EXPORT_SYMBOL(csum_tcpudp_magic); | ||
87 | #endif | ||
88 | |||
89 | EXPORT_SYMBOL(__copy_tofrom_user); | ||
90 | EXPORT_SYMBOL(__clear_user); | ||
91 | EXPORT_SYMBOL(copy_page); | ||
92 | |||
93 | #if defined(CONFIG_PCI) && defined(CONFIG_PPC32) | ||
94 | EXPORT_SYMBOL(isa_io_base); | ||
95 | EXPORT_SYMBOL(isa_mem_base); | ||
96 | EXPORT_SYMBOL(pci_dram_offset); | ||
97 | #endif /* CONFIG_PCI */ | ||
98 | |||
99 | EXPORT_SYMBOL(start_thread); | ||
100 | |||
101 | #ifdef CONFIG_PPC_FPU | 21 | #ifdef CONFIG_PPC_FPU |
102 | EXPORT_SYMBOL(giveup_fpu); | 22 | EXPORT_SYMBOL(giveup_fpu); |
103 | EXPORT_SYMBOL(load_fp_state); | 23 | EXPORT_SYMBOL(load_fp_state); |
104 | EXPORT_SYMBOL(store_fp_state); | 24 | EXPORT_SYMBOL(store_fp_state); |
105 | #endif | 25 | #endif |
26 | |||
106 | #ifdef CONFIG_ALTIVEC | 27 | #ifdef CONFIG_ALTIVEC |
107 | EXPORT_SYMBOL(giveup_altivec); | 28 | EXPORT_SYMBOL(giveup_altivec); |
108 | EXPORT_SYMBOL(load_vr_state); | 29 | EXPORT_SYMBOL(load_vr_state); |
109 | EXPORT_SYMBOL(store_vr_state); | 30 | EXPORT_SYMBOL(store_vr_state); |
110 | #endif /* CONFIG_ALTIVEC */ | ||
111 | #ifdef CONFIG_VSX | ||
112 | EXPORT_SYMBOL(giveup_vsx); | ||
113 | EXPORT_SYMBOL_GPL(__giveup_vsx); | ||
114 | #endif /* CONFIG_VSX */ | ||
115 | #ifdef CONFIG_SPE | ||
116 | EXPORT_SYMBOL(giveup_spe); | ||
117 | #endif /* CONFIG_SPE */ | ||
118 | |||
119 | #ifndef CONFIG_PPC64 | ||
120 | EXPORT_SYMBOL(flush_instruction_cache); | ||
121 | #endif | 31 | #endif |
122 | EXPORT_SYMBOL(flush_dcache_range); | ||
123 | EXPORT_SYMBOL(flush_icache_range); | ||
124 | 32 | ||
125 | #ifdef CONFIG_SMP | 33 | #ifdef CONFIG_VSX |
126 | #ifdef CONFIG_PPC32 | 34 | EXPORT_SYMBOL_GPL(__giveup_vsx); |
127 | EXPORT_SYMBOL(smp_hw_index); | ||
128 | #endif | ||
129 | #endif | ||
130 | |||
131 | #ifdef CONFIG_ADB | ||
132 | EXPORT_SYMBOL(adb_request); | ||
133 | EXPORT_SYMBOL(adb_register); | ||
134 | EXPORT_SYMBOL(adb_unregister); | ||
135 | EXPORT_SYMBOL(adb_poll); | ||
136 | EXPORT_SYMBOL(adb_try_handler_change); | ||
137 | #endif /* CONFIG_ADB */ | ||
138 | #ifdef CONFIG_ADB_CUDA | ||
139 | EXPORT_SYMBOL(cuda_request); | ||
140 | EXPORT_SYMBOL(cuda_poll); | ||
141 | #endif /* CONFIG_ADB_CUDA */ | ||
142 | EXPORT_SYMBOL(to_tm); | ||
143 | |||
144 | #ifdef CONFIG_PPC32 | ||
145 | long long __ashrdi3(long long, int); | ||
146 | long long __ashldi3(long long, int); | ||
147 | long long __lshrdi3(long long, int); | ||
148 | EXPORT_SYMBOL(__ashrdi3); | ||
149 | EXPORT_SYMBOL(__ashldi3); | ||
150 | EXPORT_SYMBOL(__lshrdi3); | ||
151 | int __ucmpdi2(unsigned long long, unsigned long long); | ||
152 | EXPORT_SYMBOL(__ucmpdi2); | ||
153 | int __cmpdi2(long long, long long); | ||
154 | EXPORT_SYMBOL(__cmpdi2); | ||
155 | #endif | ||
156 | long long __bswapdi2(long long); | ||
157 | EXPORT_SYMBOL(__bswapdi2); | ||
158 | EXPORT_SYMBOL(memcpy); | ||
159 | EXPORT_SYMBOL(memset); | ||
160 | EXPORT_SYMBOL(memmove); | ||
161 | EXPORT_SYMBOL(memcmp); | ||
162 | EXPORT_SYMBOL(memchr); | ||
163 | |||
164 | #if defined(CONFIG_FB_VGA16_MODULE) | ||
165 | EXPORT_SYMBOL(screen_info); | ||
166 | #endif | ||
167 | |||
168 | #ifdef CONFIG_PPC32 | ||
169 | EXPORT_SYMBOL(timer_interrupt); | ||
170 | EXPORT_SYMBOL(tb_ticks_per_jiffy); | ||
171 | EXPORT_SYMBOL(cacheable_memcpy); | ||
172 | EXPORT_SYMBOL(cacheable_memzero); | ||
173 | #endif | ||
174 | |||
175 | #ifdef CONFIG_PPC32 | ||
176 | EXPORT_SYMBOL(switch_mmu_context); | ||
177 | #endif | ||
178 | |||
179 | #ifdef CONFIG_PPC_STD_MMU_32 | ||
180 | extern long mol_trampoline; | ||
181 | EXPORT_SYMBOL(mol_trampoline); /* For MOL */ | ||
182 | EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ | ||
183 | #ifdef CONFIG_SMP | ||
184 | extern int mmu_hash_lock; | ||
185 | EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ | ||
186 | #endif /* CONFIG_SMP */ | ||
187 | extern long *intercept_table; | ||
188 | EXPORT_SYMBOL(intercept_table); | ||
189 | #endif /* CONFIG_PPC_STD_MMU_32 */ | ||
190 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
191 | EXPORT_SYMBOL(__mtdcr); | ||
192 | EXPORT_SYMBOL(__mfdcr); | ||
193 | #endif | ||
194 | EXPORT_SYMBOL(empty_zero_page); | ||
195 | |||
196 | #ifdef CONFIG_PPC64 | ||
197 | EXPORT_SYMBOL(__arch_hweight8); | ||
198 | EXPORT_SYMBOL(__arch_hweight16); | ||
199 | EXPORT_SYMBOL(__arch_hweight32); | ||
200 | EXPORT_SYMBOL(__arch_hweight64); | ||
201 | #endif | 35 | #endif |
202 | 36 | ||
203 | #ifdef CONFIG_PPC_BOOK3S_64 | 37 | #ifdef CONFIG_SPE |
204 | EXPORT_SYMBOL_GPL(mmu_psize_defs); | 38 | EXPORT_SYMBOL(giveup_spe); |
205 | #endif | 39 | #endif |
206 | 40 | ||
207 | #ifdef CONFIG_EPAPR_PARAVIRT | 41 | #ifdef CONFIG_EPAPR_PARAVIRT |
diff --git a/arch/powerpc/kernel/ppc_ksyms_32.c b/arch/powerpc/kernel/ppc_ksyms_32.c new file mode 100644 index 000000000000..30ddd8a24eee --- /dev/null +++ b/arch/powerpc/kernel/ppc_ksyms_32.c | |||
@@ -0,0 +1,61 @@ | |||
1 | #include <linux/export.h> | ||
2 | #include <linux/smp.h> | ||
3 | |||
4 | #include <asm/page.h> | ||
5 | #include <asm/dma.h> | ||
6 | #include <asm/io.h> | ||
7 | #include <asm/hw_irq.h> | ||
8 | #include <asm/time.h> | ||
9 | #include <asm/mmu_context.h> | ||
10 | #include <asm/pgtable.h> | ||
11 | #include <asm/dcr.h> | ||
12 | |||
13 | EXPORT_SYMBOL(clear_pages); | ||
14 | EXPORT_SYMBOL(ISA_DMA_THRESHOLD); | ||
15 | EXPORT_SYMBOL(DMA_MODE_READ); | ||
16 | EXPORT_SYMBOL(DMA_MODE_WRITE); | ||
17 | |||
18 | #if defined(CONFIG_PCI) | ||
19 | EXPORT_SYMBOL(isa_io_base); | ||
20 | EXPORT_SYMBOL(isa_mem_base); | ||
21 | EXPORT_SYMBOL(pci_dram_offset); | ||
22 | #endif | ||
23 | |||
24 | #ifdef CONFIG_SMP | ||
25 | EXPORT_SYMBOL(smp_hw_index); | ||
26 | #endif | ||
27 | |||
28 | long long __ashrdi3(long long, int); | ||
29 | long long __ashldi3(long long, int); | ||
30 | long long __lshrdi3(long long, int); | ||
31 | int __ucmpdi2(unsigned long long, unsigned long long); | ||
32 | int __cmpdi2(long long, long long); | ||
33 | EXPORT_SYMBOL(__ashrdi3); | ||
34 | EXPORT_SYMBOL(__ashldi3); | ||
35 | EXPORT_SYMBOL(__lshrdi3); | ||
36 | EXPORT_SYMBOL(__ucmpdi2); | ||
37 | EXPORT_SYMBOL(__cmpdi2); | ||
38 | |||
39 | EXPORT_SYMBOL(timer_interrupt); | ||
40 | EXPORT_SYMBOL(tb_ticks_per_jiffy); | ||
41 | |||
42 | EXPORT_SYMBOL(switch_mmu_context); | ||
43 | |||
44 | #ifdef CONFIG_PPC_STD_MMU_32 | ||
45 | extern long mol_trampoline; | ||
46 | EXPORT_SYMBOL(mol_trampoline); /* For MOL */ | ||
47 | EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ | ||
48 | #ifdef CONFIG_SMP | ||
49 | extern int mmu_hash_lock; | ||
50 | EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ | ||
51 | #endif /* CONFIG_SMP */ | ||
52 | extern long *intercept_table; | ||
53 | EXPORT_SYMBOL(intercept_table); | ||
54 | #endif /* CONFIG_PPC_STD_MMU_32 */ | ||
55 | |||
56 | #ifdef CONFIG_PPC_DCR_NATIVE | ||
57 | EXPORT_SYMBOL(__mtdcr); | ||
58 | EXPORT_SYMBOL(__mfdcr); | ||
59 | #endif | ||
60 | |||
61 | EXPORT_SYMBOL(flush_instruction_cache); | ||
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index bf44ae962ab8..aa1df89c8b2a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -228,6 +228,7 @@ void giveup_vsx(struct task_struct *tsk) | |||
228 | giveup_altivec_maybe_transactional(tsk); | 228 | giveup_altivec_maybe_transactional(tsk); |
229 | __giveup_vsx(tsk); | 229 | __giveup_vsx(tsk); |
230 | } | 230 | } |
231 | EXPORT_SYMBOL(giveup_vsx); | ||
231 | 232 | ||
232 | void flush_vsx_to_thread(struct task_struct *tsk) | 233 | void flush_vsx_to_thread(struct task_struct *tsk) |
233 | { | 234 | { |
@@ -1316,6 +1317,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) | |||
1316 | current->thread.tm_tfiar = 0; | 1317 | current->thread.tm_tfiar = 0; |
1317 | #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ | 1318 | #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ |
1318 | } | 1319 | } |
1320 | EXPORT_SYMBOL(start_thread); | ||
1319 | 1321 | ||
1320 | #define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \ | 1322 | #define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \ |
1321 | | PR_FP_EXC_RES | PR_FP_EXC_INV) | 1323 | | PR_FP_EXC_RES | PR_FP_EXC_INV) |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 4e139f8a69ef..099f27e6d1b0 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -386,8 +386,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
386 | return 0; | 386 | return 0; |
387 | } | 387 | } |
388 | 388 | ||
389 | int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname, | 389 | static int __init early_init_dt_scan_chosen_ppc(unsigned long node, |
390 | int depth, void *data) | 390 | const char *uname, |
391 | int depth, void *data) | ||
391 | { | 392 | { |
392 | const unsigned long *lprop; /* All these set by kernel, so no need to convert endian */ | 393 | const unsigned long *lprop; /* All these set by kernel, so no need to convert endian */ |
393 | 394 | ||
@@ -641,6 +642,10 @@ void __init early_init_devtree(void *params) | |||
641 | 642 | ||
642 | DBG(" -> early_init_devtree(%p)\n", params); | 643 | DBG(" -> early_init_devtree(%p)\n", params); |
643 | 644 | ||
645 | /* Too early to BUG_ON(), do it by hand */ | ||
646 | if (!early_init_dt_verify(params)) | ||
647 | panic("BUG: Failed verifying flat device tree, bad version?"); | ||
648 | |||
644 | /* Setup flat device-tree pointer */ | 649 | /* Setup flat device-tree pointer */ |
645 | initial_boot_params = params; | 650 | initial_boot_params = params; |
646 | 651 | ||
@@ -663,14 +668,12 @@ void __init early_init_devtree(void *params) | |||
663 | * device-tree, including the platform type, initrd location and | 668 | * device-tree, including the platform type, initrd location and |
664 | * size, TCE reserve, and more ... | 669 | * size, TCE reserve, and more ... |
665 | */ | 670 | */ |
666 | of_scan_flat_dt(early_init_dt_scan_chosen_ppc, cmd_line); | 671 | of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line); |
667 | 672 | ||
668 | /* Scan memory nodes and rebuild MEMBLOCKs */ | 673 | /* Scan memory nodes and rebuild MEMBLOCKs */ |
669 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | 674 | of_scan_flat_dt(early_init_dt_scan_root, NULL); |
670 | of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); | 675 | of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); |
671 | 676 | ||
672 | /* Save command line for /proc/cmdline and then parse parameters */ | ||
673 | strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); | ||
674 | parse_early_param(); | 677 | parse_early_param(); |
675 | 678 | ||
676 | /* make sure we've parsed cmdline for mem= before this */ | 679 | /* make sure we've parsed cmdline for mem= before this */ |
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index fe8e54b9ef7d..12640f7e726b 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh | |||
@@ -50,24 +50,14 @@ do | |||
50 | done | 50 | done |
51 | 51 | ||
52 | # ignore register save/restore funcitons | 52 | # ignore register save/restore funcitons |
53 | if [ "${UNDEF:0:9}" = "_restgpr_" ]; then | 53 | case $UNDEF in |
54 | _restgpr_*|_restgpr0_*|_rest32gpr_*) | ||
54 | OK=1 | 55 | OK=1 |
55 | fi | 56 | ;; |
56 | if [ "${UNDEF:0:10}" = "_restgpr0_" ]; then | 57 | _savegpr_*|_savegpr0_*|_save32gpr_*) |
57 | OK=1 | ||
58 | fi | ||
59 | if [ "${UNDEF:0:11}" = "_rest32gpr_" ]; then | ||
60 | OK=1 | ||
61 | fi | ||
62 | if [ "${UNDEF:0:9}" = "_savegpr_" ]; then | ||
63 | OK=1 | 58 | OK=1 |
64 | fi | 59 | ;; |
65 | if [ "${UNDEF:0:10}" = "_savegpr0_" ]; then | 60 | esac |
66 | OK=1 | ||
67 | fi | ||
68 | if [ "${UNDEF:0:11}" = "_save32gpr_" ]; then | ||
69 | OK=1 | ||
70 | fi | ||
71 | 61 | ||
72 | if [ $OK -eq 0 ]; then | 62 | if [ $OK -eq 0 ]; then |
73 | ERROR=1 | 63 | ERROR=1 |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 2e3d2bf536c5..cdb404ea3468 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -932,7 +932,7 @@ void ptrace_triggered(struct perf_event *bp, | |||
932 | } | 932 | } |
933 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | 933 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ |
934 | 934 | ||
935 | int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | 935 | static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, |
936 | unsigned long data) | 936 | unsigned long data) |
937 | { | 937 | { |
938 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 938 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index e736387fee6a..5a2c049c1c61 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c | |||
@@ -286,7 +286,7 @@ static void prrn_work_fn(struct work_struct *work) | |||
286 | 286 | ||
287 | static DECLARE_WORK(prrn_work, prrn_work_fn); | 287 | static DECLARE_WORK(prrn_work, prrn_work_fn); |
288 | 288 | ||
289 | void prrn_schedule_update(u32 scope) | 289 | static void prrn_schedule_update(u32 scope) |
290 | { | 290 | { |
291 | flush_work(&prrn_work); | 291 | flush_work(&prrn_work); |
292 | prrn_update_scope = scope; | 292 | prrn_update_scope = scope; |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 1b0e26013a62..1362cd62b3fa 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -81,8 +81,6 @@ EXPORT_SYMBOL_GPL(boot_cpuid); | |||
81 | 81 | ||
82 | unsigned long klimit = (unsigned long) _end; | 82 | unsigned long klimit = (unsigned long) _end; |
83 | 83 | ||
84 | char cmd_line[COMMAND_LINE_SIZE]; | ||
85 | |||
86 | /* | 84 | /* |
87 | * This still seems to be needed... -- paulus | 85 | * This still seems to be needed... -- paulus |
88 | */ | 86 | */ |
@@ -94,6 +92,9 @@ struct screen_info screen_info = { | |||
94 | .orig_video_isVGA = 1, | 92 | .orig_video_isVGA = 1, |
95 | .orig_video_points = 16 | 93 | .orig_video_points = 16 |
96 | }; | 94 | }; |
95 | #if defined(CONFIG_FB_VGA16_MODULE) | ||
96 | EXPORT_SYMBOL(screen_info); | ||
97 | #endif | ||
97 | 98 | ||
98 | /* Variables required to store legacy IO irq routing */ | 99 | /* Variables required to store legacy IO irq routing */ |
99 | int of_i8042_kbd_irq; | 100 | int of_i8042_kbd_irq; |
@@ -382,7 +383,7 @@ void __init check_for_initrd(void) | |||
382 | initrd_start = initrd_end = 0; | 383 | initrd_start = initrd_end = 0; |
383 | 384 | ||
384 | if (initrd_start) | 385 | if (initrd_start) |
385 | printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end); | 386 | pr_info("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end); |
386 | 387 | ||
387 | DBG(" <- check_for_initrd()\n"); | 388 | DBG(" <- check_for_initrd()\n"); |
388 | #endif /* CONFIG_BLK_DEV_INITRD */ | 389 | #endif /* CONFIG_BLK_DEV_INITRD */ |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index ea4fda60e57b..07831ed0d9ef 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -268,7 +268,7 @@ static void __init exc_lvl_early_init(void) | |||
268 | /* Warning, IO base is not yet inited */ | 268 | /* Warning, IO base is not yet inited */ |
269 | void __init setup_arch(char **cmdline_p) | 269 | void __init setup_arch(char **cmdline_p) |
270 | { | 270 | { |
271 | *cmdline_p = cmd_line; | 271 | *cmdline_p = boot_command_line; |
272 | 272 | ||
273 | /* so udelay does something sensible, assume <= 1000 bogomips */ | 273 | /* so udelay does something sensible, assume <= 1000 bogomips */ |
274 | loops_per_jiffy = 500000000 / HZ; | 274 | loops_per_jiffy = 500000000 / HZ; |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 75d62d63fe68..cd07d79ad21c 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -525,21 +525,31 @@ void __init setup_system(void) | |||
525 | printk("Starting Linux PPC64 %s\n", init_utsname()->version); | 525 | printk("Starting Linux PPC64 %s\n", init_utsname()->version); |
526 | 526 | ||
527 | printk("-----------------------------------------------------\n"); | 527 | printk("-----------------------------------------------------\n"); |
528 | printk("ppc64_pft_size = 0x%llx\n", ppc64_pft_size); | 528 | printk("ppc64_pft_size = 0x%llx\n", ppc64_pft_size); |
529 | printk("physicalMemorySize = 0x%llx\n", memblock_phys_mem_size()); | 529 | printk("phys_mem_size = 0x%llx\n", memblock_phys_mem_size()); |
530 | |||
530 | if (ppc64_caches.dline_size != 0x80) | 531 | if (ppc64_caches.dline_size != 0x80) |
531 | printk("ppc64_caches.dcache_line_size = 0x%x\n", | 532 | printk("dcache_line_size = 0x%x\n", ppc64_caches.dline_size); |
532 | ppc64_caches.dline_size); | ||
533 | if (ppc64_caches.iline_size != 0x80) | 533 | if (ppc64_caches.iline_size != 0x80) |
534 | printk("ppc64_caches.icache_line_size = 0x%x\n", | 534 | printk("icache_line_size = 0x%x\n", ppc64_caches.iline_size); |
535 | ppc64_caches.iline_size); | 535 | |
536 | printk("cpu_features = 0x%016lx\n", cur_cpu_spec->cpu_features); | ||
537 | printk(" possible = 0x%016lx\n", CPU_FTRS_POSSIBLE); | ||
538 | printk(" always = 0x%016lx\n", CPU_FTRS_ALWAYS); | ||
539 | printk("cpu_user_features = 0x%08x 0x%08x\n", cur_cpu_spec->cpu_user_features, | ||
540 | cur_cpu_spec->cpu_user_features2); | ||
541 | printk("mmu_features = 0x%08x\n", cur_cpu_spec->mmu_features); | ||
542 | printk("firmware_features = 0x%016lx\n", powerpc_firmware_features); | ||
543 | |||
536 | #ifdef CONFIG_PPC_STD_MMU_64 | 544 | #ifdef CONFIG_PPC_STD_MMU_64 |
537 | if (htab_address) | 545 | if (htab_address) |
538 | printk("htab_address = 0x%p\n", htab_address); | 546 | printk("htab_address = 0x%p\n", htab_address); |
539 | printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); | 547 | |
540 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 548 | printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); |
549 | #endif | ||
550 | |||
541 | if (PHYSICAL_START > 0) | 551 | if (PHYSICAL_START > 0) |
542 | printk("physical_start = 0x%llx\n", | 552 | printk("physical_start = 0x%llx\n", |
543 | (unsigned long long)PHYSICAL_START); | 553 | (unsigned long long)PHYSICAL_START); |
544 | printk("-----------------------------------------------------\n"); | 554 | printk("-----------------------------------------------------\n"); |
545 | 555 | ||
@@ -657,7 +667,7 @@ void __init setup_arch(char **cmdline_p) | |||
657 | { | 667 | { |
658 | ppc64_boot_msg(0x12, "Setup Arch"); | 668 | ppc64_boot_msg(0x12, "Setup Arch"); |
659 | 669 | ||
660 | *cmdline_p = cmd_line; | 670 | *cmdline_p = boot_command_line; |
661 | 671 | ||
662 | /* | 672 | /* |
663 | * Set cache line size based on type of cpu as a default. | 673 | * Set cache line size based on type of cpu as a default. |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a0738af4aba6..71e186d5f331 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #endif | 52 | #endif |
53 | #include <asm/vdso.h> | 53 | #include <asm/vdso.h> |
54 | #include <asm/debug.h> | 54 | #include <asm/debug.h> |
55 | #include <asm/kexec.h> | ||
55 | 56 | ||
56 | #ifdef DEBUG | 57 | #ifdef DEBUG |
57 | #include <asm/udbg.h> | 58 | #include <asm/udbg.h> |
@@ -379,8 +380,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
379 | /* | 380 | /* |
380 | * numa_node_id() works after this. | 381 | * numa_node_id() works after this. |
381 | */ | 382 | */ |
382 | set_cpu_numa_node(cpu, numa_cpu_lookup_table[cpu]); | 383 | if (cpu_present(cpu)) { |
383 | set_cpu_numa_mem(cpu, local_memory_node(numa_cpu_lookup_table[cpu])); | 384 | set_cpu_numa_node(cpu, numa_cpu_lookup_table[cpu]); |
385 | set_cpu_numa_mem(cpu, | ||
386 | local_memory_node(numa_cpu_lookup_table[cpu])); | ||
387 | } | ||
384 | } | 388 | } |
385 | 389 | ||
386 | cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); | 390 | cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); |
@@ -728,6 +732,9 @@ void start_secondary(void *unused) | |||
728 | } | 732 | } |
729 | traverse_core_siblings(cpu, true); | 733 | traverse_core_siblings(cpu, true); |
730 | 734 | ||
735 | set_numa_node(numa_cpu_lookup_table[cpu]); | ||
736 | set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); | ||
737 | |||
731 | smp_wmb(); | 738 | smp_wmb(); |
732 | notify_cpu_starting(cpu); | 739 | notify_cpu_starting(cpu); |
733 | set_cpu_online(cpu, true); | 740 | set_cpu_online(cpu, true); |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 368ab374d33c..7505599c2593 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -479,7 +479,7 @@ void arch_irq_work_raise(void) | |||
479 | 479 | ||
480 | #endif /* CONFIG_IRQ_WORK */ | 480 | #endif /* CONFIG_IRQ_WORK */ |
481 | 481 | ||
482 | void __timer_interrupt(void) | 482 | static void __timer_interrupt(void) |
483 | { | 483 | { |
484 | struct pt_regs *regs = get_irq_regs(); | 484 | struct pt_regs *regs = get_irq_regs(); |
485 | u64 *next_tb = &__get_cpu_var(decrementers_next_tb); | 485 | u64 *next_tb = &__get_cpu_var(decrementers_next_tb); |
@@ -643,7 +643,7 @@ static int __init get_freq(char *name, int cells, unsigned long *val) | |||
643 | return found; | 643 | return found; |
644 | } | 644 | } |
645 | 645 | ||
646 | void start_cpu_decrementer(void) | 646 | static void start_cpu_decrementer(void) |
647 | { | 647 | { |
648 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | 648 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
649 | /* Clear any pending timer interrupts */ | 649 | /* Clear any pending timer interrupts */ |
@@ -1024,6 +1024,7 @@ void to_tm(int tim, struct rtc_time * tm) | |||
1024 | */ | 1024 | */ |
1025 | GregorianDay(tm); | 1025 | GregorianDay(tm); |
1026 | } | 1026 | } |
1027 | EXPORT_SYMBOL(to_tm); | ||
1027 | 1028 | ||
1028 | /* | 1029 | /* |
1029 | * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit | 1030 | * Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit |