From 38d9029a652cb2925a97a8484f6e8f2c85fd55bb Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 31 Jul 2015 19:34:46 -0700 Subject: parisc: Define ioremap_uc and ioremap_wc Commit 3cc2dac5be3f ("drivers/video/fbdev/atyfb: Replace MTRR UC hole with strong UC") introduces calls to ioremap_wc and ioremap_uc. This causes build failures with parisc:allmodconfig. Map the missing functions to ioremap_nocache. Fixes: 3cc2dac5be3f ("drivers/video/fbdev/atyfb: Replace MTRR UC hole with strong UC") Cc: Luis R. Rodriguez Cc: Paul Gortmaker Signed-off-by: Guenter Roeck Signed-off-by: Helge Deller --- arch/parisc/include/asm/io.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index 8cd0abf28ffb..1a16f1d1075f 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -137,6 +137,8 @@ static inline void __iomem * ioremap(unsigned long offset, unsigned long size) return __ioremap(offset, size, _PAGE_NO_CACHE); } #define ioremap_nocache(off, sz) ioremap((off), (sz)) +#define ioremap_wc ioremap_nocache +#define ioremap_uc ioremap_nocache extern void iounmap(const volatile void __iomem *addr); -- cgit v1.2.3 From 699817c3df46eb209044d8c9eb20c6ff6c67c81d Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 2 Sep 2015 18:18:48 +0200 Subject: parisc: Additionally check for in_atomic() in page fault handler Craig Estey noticed that we didn't checked for in_atomic() in our page fault handler like other architectures. This commit adds this check by using faulthandler_disabled() which includes a check for pagefault_disabled() and in_atomic(). Reported-by: Craig Estey Signed-off-by: Helge Deller --- arch/parisc/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 15503adddf4f..a762864ec92e 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -207,7 +207,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, int fault; unsigned int flags; - if (pagefault_disabled()) + if (faulthandler_disabled()) goto no_context; tsk = current; -- cgit v1.2.3 From b1b4e435e4ef7de77f07bf2a42c8380b960c2d44 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 3 Sep 2015 22:45:21 +0200 Subject: parisc: Filter out spurious interrupts in PA-RISC irq handler When detecting a serial port on newer PA-RISC machines (with iosapic) we have a long way to go to find the right IRQ line, registering it, then registering the serial port and the irq handler for the serial port. During this phase spurious interrupts for the serial port may happen which then crashes the kernel because the action handler might not have been set up yet. So, basically it's a race condition between the serial port hardware and the CPU which sets up the necessary fields in the irq sructs. The main reason for this race is, that we unmask the serial port irqs too early without having set up everything properly before (which isn't easily possible because we need the IRQ number to register the serial ports). This patch is a work-around for this problem. It adds checks to the CPU irq handler to verify if the IRQ action field has been initialized already. If not, we just skip this interrupt (which isn't critical for a serial port at bootup). The real fix would probably involve rewriting all PA-RISC specific IRQ code (for CPU, IOSAPIC, GSC and EISA) to use IRQ domains with proper parenting of the irq chips and proper irq enabling along this line. This bug has been in the PA-RISC port since the beginning, but the crashes happened very rarely with currently used hardware. But on the latest machine which I bought (a C8000 workstation), which uses the fastest CPUs (4 x PA8900, 1GHz) and which has the largest possible L1 cache size (64MB each), the kernel crashed at every boot because of this race. So, without this patch the machine would currently be unuseable. For the record, here is the flow logic: 1. serial_init_chip() in 8250_gsc.c calls iosapic_serial_irq(). 2. iosapic_serial_irq() calls txn_alloc_irq() to find the irq. 3. iosapic_serial_irq() calls cpu_claim_irq() to register the CPU irq 4. cpu_claim_irq() unmasks the CPU irq (which it shouldn't!) 5. serial_init_chip() then registers the 8250 port. Problems: - In step 4 the CPU irq shouldn't have been registered yet, but after step 5 - If serial irq happens between 4 and 5 have finished, the kernel will crash Signed-off-by: Helge Deller --- arch/parisc/kernel/irq.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 413ec3c3f9cc..ba5e1c7b1f17 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -507,8 +507,8 @@ void do_cpu_irq_mask(struct pt_regs *regs) struct pt_regs *old_regs; unsigned long eirr_val; int irq, cpu = smp_processor_id(); -#ifdef CONFIG_SMP struct irq_data *irq_data; +#ifdef CONFIG_SMP cpumask_t dest; #endif @@ -521,8 +521,13 @@ void do_cpu_irq_mask(struct pt_regs *regs) goto set_out; irq = eirr_to_irq(eirr_val); -#ifdef CONFIG_SMP irq_data = irq_get_irq_data(irq); + + /* Filter out spurious interrupts, mostly from serial port at bootup */ + if (unlikely(!irq_desc_has_action(irq_data_to_desc(irq_data)))) + goto set_out; + +#ifdef CONFIG_SMP cpumask_copy(&dest, irq_data_get_affinity_mask(irq_data)); if (irqd_is_per_cpu(irq_data) && !cpumask_test_cpu(smp_processor_id(), &dest)) { -- cgit v1.2.3 From 1b59ddfcf1678de38a1f8ca9fb8ea5eebeff1843 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Mon, 7 Sep 2015 20:13:28 -0400 Subject: parisc: Use double word condition in 64bit CAS operation The attached change fixes the condition used in the "sub" instruction. A double word comparison is needed. This fixes the 64-bit LWS CAS operation on 64-bit kernels. I can now enable 64-bit atomic support in GCC. Cc: Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/syscall.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 7ef22e3387e0..0b8d26d3ba43 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -821,7 +821,7 @@ cas2_action: /* 64bit CAS */ #ifdef CONFIG_64BIT 19: ldd,ma 0(%sr3,%r26), %r29 - sub,= %r29, %r25, %r0 + sub,*= %r29, %r25, %r0 b,n cas2_end 20: std,ma %r24, 0(%sr3,%r26) copy %r0, %r28 -- cgit v1.2.3 From 72581cecee411be2b2c00226c98e0c20aab337a2 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 8 Sep 2015 17:49:31 +0200 Subject: parisc: Drop CONFIG_SMP around update_cr16_clocksource() No need to use CONFIG_SMP around update_cr16_clocksource(). It checks for num_online_cpus() beeing greater than 1, which is always 1 in UP builds. Signed-off-by: Helge Deller --- arch/parisc/kernel/time.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch') diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 70e105d62423..cc68a4fbce6a 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -202,7 +202,6 @@ static struct clocksource clocksource_cr16 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -#ifdef CONFIG_SMP int update_cr16_clocksource(void) { /* since the cr16 cycle counters are not synchronized across CPUs, @@ -214,12 +213,6 @@ int update_cr16_clocksource(void) return 0; } -#else -int update_cr16_clocksource(void) -{ - return 0; /* no change */ -} -#endif /*CONFIG_SMP*/ void __init start_cpu_itimer(void) { -- cgit v1.2.3 From 6dc0dcde406bb0e40ad6a6f45f44534d3a094205 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 8 Sep 2015 17:50:03 +0200 Subject: parisc: Use platform_device_register_simple("rtc-generic") Signed-off-by: Helge Deller --- arch/parisc/kernel/time.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index cc68a4fbce6a..400acac0a304 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -224,20 +224,14 @@ void __init start_cpu_itimer(void) per_cpu(cpu_data, cpu).it_value = next_tick; } -static struct platform_device rtc_generic_dev = { - .name = "rtc-generic", - .id = -1, -}; - static int __init rtc_init(void) { - if (platform_device_register(&rtc_generic_dev) < 0) - printk(KERN_ERR "unable to register rtc device...\n"); + struct platform_device *pdev; - /* not necessarily an error */ - return 0; + pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); + return PTR_ERR_OR_ZERO(pdev); } -module_init(rtc_init); +device_initcall(rtc_init); void read_persistent_clock(struct timespec *ts) { -- cgit v1.2.3