diff options
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/kernel/iommu.c | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/ioport.c | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/nmi.c | 44 |
3 files changed, 47 insertions, 5 deletions
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 852a3291db96..9df997995f6b 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c | |||
@@ -415,7 +415,7 @@ static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, | |||
415 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | 415 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; |
416 | 416 | ||
417 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 417 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
418 | if (strbuf->strbuf_enabled) | 418 | if (strbuf->strbuf_enabled && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) |
419 | strbuf_flush(strbuf, iommu, bus_addr, ctx, | 419 | strbuf_flush(strbuf, iommu, bus_addr, ctx, |
420 | npages, direction); | 420 | npages, direction); |
421 | 421 | ||
@@ -640,7 +640,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
640 | base = iommu->page_table + entry; | 640 | base = iommu->page_table + entry; |
641 | 641 | ||
642 | dma_handle &= IO_PAGE_MASK; | 642 | dma_handle &= IO_PAGE_MASK; |
643 | if (strbuf->strbuf_enabled) | 643 | if (strbuf->strbuf_enabled && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) |
644 | strbuf_flush(strbuf, iommu, dma_handle, ctx, | 644 | strbuf_flush(strbuf, iommu, dma_handle, ctx, |
645 | npages, direction); | 645 | npages, direction); |
646 | 646 | ||
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 2344103414d1..6ffaec44931a 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
@@ -527,7 +527,7 @@ static dma_addr_t pci32_map_page(struct device *dev, struct page *page, | |||
527 | static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size, | 527 | static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size, |
528 | enum dma_data_direction dir, unsigned long attrs) | 528 | enum dma_data_direction dir, unsigned long attrs) |
529 | { | 529 | { |
530 | if (dir != PCI_DMA_TODEVICE) | 530 | if (dir != PCI_DMA_TODEVICE && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) |
531 | dma_make_coherent(ba, PAGE_ALIGN(size)); | 531 | dma_make_coherent(ba, PAGE_ALIGN(size)); |
532 | } | 532 | } |
533 | 533 | ||
@@ -572,7 +572,7 @@ static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl, | |||
572 | struct scatterlist *sg; | 572 | struct scatterlist *sg; |
573 | int n; | 573 | int n; |
574 | 574 | ||
575 | if (dir != PCI_DMA_TODEVICE) { | 575 | if (dir != PCI_DMA_TODEVICE && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { |
576 | for_each_sg(sgl, sg, nents, n) { | 576 | for_each_sg(sgl, sg, nents, n) { |
577 | dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length)); | 577 | dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length)); |
578 | } | 578 | } |
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index a9973bb4a1b2..95e73c63c99d 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c | |||
@@ -42,7 +42,7 @@ static int panic_on_timeout; | |||
42 | */ | 42 | */ |
43 | atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ | 43 | atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ |
44 | EXPORT_SYMBOL(nmi_active); | 44 | EXPORT_SYMBOL(nmi_active); |
45 | 45 | static int nmi_init_done; | |
46 | static unsigned int nmi_hz = HZ; | 46 | static unsigned int nmi_hz = HZ; |
47 | static DEFINE_PER_CPU(short, wd_enabled); | 47 | static DEFINE_PER_CPU(short, wd_enabled); |
48 | static int endflag __initdata; | 48 | static int endflag __initdata; |
@@ -153,6 +153,8 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count) | |||
153 | 153 | ||
154 | void stop_nmi_watchdog(void *unused) | 154 | void stop_nmi_watchdog(void *unused) |
155 | { | 155 | { |
156 | if (!__this_cpu_read(wd_enabled)) | ||
157 | return; | ||
156 | pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable); | 158 | pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable); |
157 | __this_cpu_write(wd_enabled, 0); | 159 | __this_cpu_write(wd_enabled, 0); |
158 | atomic_dec(&nmi_active); | 160 | atomic_dec(&nmi_active); |
@@ -207,6 +209,9 @@ error: | |||
207 | 209 | ||
208 | void start_nmi_watchdog(void *unused) | 210 | void start_nmi_watchdog(void *unused) |
209 | { | 211 | { |
212 | if (__this_cpu_read(wd_enabled)) | ||
213 | return; | ||
214 | |||
210 | __this_cpu_write(wd_enabled, 1); | 215 | __this_cpu_write(wd_enabled, 1); |
211 | atomic_inc(&nmi_active); | 216 | atomic_inc(&nmi_active); |
212 | 217 | ||
@@ -259,6 +264,8 @@ int __init nmi_init(void) | |||
259 | } | 264 | } |
260 | } | 265 | } |
261 | 266 | ||
267 | nmi_init_done = 1; | ||
268 | |||
262 | return err; | 269 | return err; |
263 | } | 270 | } |
264 | 271 | ||
@@ -270,3 +277,38 @@ static int __init setup_nmi_watchdog(char *str) | |||
270 | return 0; | 277 | return 0; |
271 | } | 278 | } |
272 | __setup("nmi_watchdog=", setup_nmi_watchdog); | 279 | __setup("nmi_watchdog=", setup_nmi_watchdog); |
280 | |||
281 | /* | ||
282 | * sparc specific NMI watchdog enable function. | ||
283 | * Enables watchdog if it is not enabled already. | ||
284 | */ | ||
285 | int watchdog_nmi_enable(unsigned int cpu) | ||
286 | { | ||
287 | if (atomic_read(&nmi_active) == -1) { | ||
288 | pr_warn("NMI watchdog cannot be enabled or disabled\n"); | ||
289 | return -1; | ||
290 | } | ||
291 | |||
292 | /* | ||
293 | * watchdog thread could start even before nmi_init is called. | ||
294 | * Just Return in that case. Let nmi_init finish the init | ||
295 | * process first. | ||
296 | */ | ||
297 | if (!nmi_init_done) | ||
298 | return 0; | ||
299 | |||
300 | smp_call_function_single(cpu, start_nmi_watchdog, NULL, 1); | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | /* | ||
305 | * sparc specific NMI watchdog disable function. | ||
306 | * Disables watchdog if it is not disabled already. | ||
307 | */ | ||
308 | void watchdog_nmi_disable(unsigned int cpu) | ||
309 | { | ||
310 | if (atomic_read(&nmi_active) == -1) | ||
311 | pr_warn_once("NMI watchdog cannot be enabled or disabled\n"); | ||
312 | else | ||
313 | smp_call_function_single(cpu, stop_nmi_watchdog, NULL, 1); | ||
314 | } | ||