Commit cd984a5b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xtensa-20190201' of git://github.com/jcmvbkbc/linux-xtensa

Pull xtensa fixes from Max Filippov:

 - fix ccount_timer_shutdown for secondary CPUs

 - fix secondary CPU initialization

 - fix secondary CPU reset vector clash with double exception vector

 - fix present CPUs when booting with 'maxcpus' parameter

 - limit possible CPUs by configured NR_CPUS

 - issue a warning if xtensa PIC is asked to retrigger anything other
   than software IRQ

 - fix masking/unmasking of the first two IRQs on xtensa MX PIC

 - fix typo in Kconfig description for user space unaligned access
   feature

 - fix Kconfig warning for selecting BUILTIN_DTB

* tag 'xtensa-20190201' of git://github.com/jcmvbkbc/linux-xtensa:
  xtensa: SMP: limit number of possible CPUs by NR_CPUS
  xtensa: rename BUILTIN_DTB to BUILTIN_DTB_SOURCE
  xtensa: Fix typo use space=>user space
  drivers/irqchip: xtensa-mx: fix mask and unmask
  drivers/irqchip: xtensa: add warning to irq_retrigger
  xtensa: SMP: mark each possible CPU as present
  xtensa: smp_lx200_defconfig: fix vectors clash
  xtensa: SMP: fix secondary CPU initialization
  xtensa: SMP: fix ccount_timer_shutdown
parents 8b050fe4 25384ce5
...@@ -164,7 +164,7 @@ config XTENSA_FAKE_NMI ...@@ -164,7 +164,7 @@ config XTENSA_FAKE_NMI
If unsure, say N. If unsure, say N.
config XTENSA_UNALIGNED_USER config XTENSA_UNALIGNED_USER
bool "Unaligned memory access in use space" bool "Unaligned memory access in user space"
help help
The Xtensa architecture currently does not handle unaligned The Xtensa architecture currently does not handle unaligned
memory accesses in hardware but through an exception handler. memory accesses in hardware but through an exception handler.
...@@ -451,7 +451,7 @@ config USE_OF ...@@ -451,7 +451,7 @@ config USE_OF
help help
Include support for flattened device tree machine descriptions. Include support for flattened device tree machine descriptions.
config BUILTIN_DTB config BUILTIN_DTB_SOURCE
string "DTB to build into the kernel image" string "DTB to build into the kernel image"
depends on OF depends on OF
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
# #
# #
BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o BUILTIN_DTB_SOURCE := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o
ifneq ($(CONFIG_BUILTIN_DTB),"") ifneq ($(CONFIG_BUILTIN_DTB_SOURCE),"")
obj-$(CONFIG_OF) += $(BUILTIN_DTB) obj-$(CONFIG_OF) += $(BUILTIN_DTB_SOURCE)
endif endif
# for CONFIG_OF_ALL_DTBS test # for CONFIG_OF_ALL_DTBS test
......
...@@ -34,7 +34,7 @@ CONFIG_XTENSA_PLATFORM_XTFPGA=y ...@@ -34,7 +34,7 @@ CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000@0" CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000@0"
CONFIG_USE_OF=y CONFIG_USE_OF=y
CONFIG_BUILTIN_DTB="kc705" CONFIG_BUILTIN_DTB_SOURCE="kc705"
# CONFIG_COMPACTION is not set # CONFIG_COMPACTION is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_PM=y CONFIG_PM=y
......
...@@ -38,7 +38,7 @@ CONFIG_HIGHMEM=y ...@@ -38,7 +38,7 @@ CONFIG_HIGHMEM=y
# CONFIG_PCI is not set # CONFIG_PCI is not set
CONFIG_XTENSA_PLATFORM_XTFPGA=y CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_USE_OF=y CONFIG_USE_OF=y
CONFIG_BUILTIN_DTB="csp" CONFIG_BUILTIN_DTB_SOURCE="csp"
# CONFIG_COMPACTION is not set # CONFIG_COMPACTION is not set
CONFIG_XTFPGA_LCD=y CONFIG_XTFPGA_LCD=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
......
...@@ -33,7 +33,7 @@ CONFIG_XTENSA_PLATFORM_XTFPGA=y ...@@ -33,7 +33,7 @@ CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000@0" CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000@0"
CONFIG_USE_OF=y CONFIG_USE_OF=y
CONFIG_BUILTIN_DTB="kc705" CONFIG_BUILTIN_DTB_SOURCE="kc705"
# CONFIG_COMPACTION is not set # CONFIG_COMPACTION is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_NET=y CONFIG_NET=y
......
...@@ -39,7 +39,7 @@ CONFIG_XTENSA_PLATFORM_XTFPGA=y ...@@ -39,7 +39,7 @@ CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0x9d050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=256M@0x60000000" CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0x9d050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=256M@0x60000000"
CONFIG_USE_OF=y CONFIG_USE_OF=y
CONFIG_BUILTIN_DTB="kc705_nommu" CONFIG_BUILTIN_DTB_SOURCE="kc705_nommu"
CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_FLAT=y
CONFIG_NET=y CONFIG_NET=y
CONFIG_PACKET=y CONFIG_PACKET=y
......
...@@ -33,11 +33,12 @@ CONFIG_SMP=y ...@@ -33,11 +33,12 @@ CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y CONFIG_HOTPLUG_CPU=y
# CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is not set # CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is not set
# CONFIG_PCI is not set # CONFIG_PCI is not set
CONFIG_VECTORS_OFFSET=0x00002000
CONFIG_XTENSA_PLATFORM_XTFPGA=y CONFIG_XTENSA_PLATFORM_XTFPGA=y
CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=96M@0" CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=96M@0"
CONFIG_USE_OF=y CONFIG_USE_OF=y
CONFIG_BUILTIN_DTB="lx200mx" CONFIG_BUILTIN_DTB_SOURCE="lx200mx"
# CONFIG_COMPACTION is not set # CONFIG_COMPACTION is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_NET=y CONFIG_NET=y
......
...@@ -276,12 +276,13 @@ should_never_return: ...@@ -276,12 +276,13 @@ should_never_return:
movi a2, cpu_start_ccount movi a2, cpu_start_ccount
1: 1:
memw
l32i a3, a2, 0 l32i a3, a2, 0
beqi a3, 0, 1b beqi a3, 0, 1b
movi a3, 0 movi a3, 0
s32i a3, a2, 0 s32i a3, a2, 0
memw
1: 1:
memw
l32i a3, a2, 0 l32i a3, a2, 0
beqi a3, 0, 1b beqi a3, 0, 1b
wsr a3, ccount wsr a3, ccount
...@@ -317,11 +318,13 @@ ENTRY(cpu_restart) ...@@ -317,11 +318,13 @@ ENTRY(cpu_restart)
rsr a0, prid rsr a0, prid
neg a2, a0 neg a2, a0
movi a3, cpu_start_id movi a3, cpu_start_id
memw
s32i a2, a3, 0 s32i a2, a3, 0
#if XCHAL_DCACHE_IS_WRITEBACK #if XCHAL_DCACHE_IS_WRITEBACK
dhwbi a3, 0 dhwbi a3, 0
#endif #endif
1: 1:
memw
l32i a2, a3, 0 l32i a2, a3, 0
dhi a3, 0 dhi a3, 0
bne a2, a0, 1b bne a2, a0, 1b
......
...@@ -83,7 +83,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -83,7 +83,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned i; unsigned i;
for (i = 0; i < max_cpus; ++i) for_each_possible_cpu(i)
set_cpu_present(i, true); set_cpu_present(i, true);
} }
...@@ -96,6 +96,11 @@ void __init smp_init_cpus(void) ...@@ -96,6 +96,11 @@ void __init smp_init_cpus(void)
pr_info("%s: Core Count = %d\n", __func__, ncpus); pr_info("%s: Core Count = %d\n", __func__, ncpus);
pr_info("%s: Core Id = %d\n", __func__, core_id); pr_info("%s: Core Id = %d\n", __func__, core_id);
if (ncpus > NR_CPUS) {
ncpus = NR_CPUS;
pr_info("%s: limiting core count by %d\n", __func__, ncpus);
}
for (i = 0; i < ncpus; ++i) for (i = 0; i < ncpus; ++i)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
...@@ -195,9 +200,11 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts) ...@@ -195,9 +200,11 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts)
int i; int i;
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
cpu_start_id = cpu; WRITE_ONCE(cpu_start_id, cpu);
system_flush_invalidate_dcache_range( /* Pairs with the third memw in the cpu_restart */
(unsigned long)&cpu_start_id, sizeof(cpu_start_id)); mb();
system_flush_invalidate_dcache_range((unsigned long)&cpu_start_id,
sizeof(cpu_start_id));
#endif #endif
smp_call_function_single(0, mx_cpu_start, (void *)cpu, 1); smp_call_function_single(0, mx_cpu_start, (void *)cpu, 1);
...@@ -206,18 +213,21 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts) ...@@ -206,18 +213,21 @@ static int boot_secondary(unsigned int cpu, struct task_struct *ts)
ccount = get_ccount(); ccount = get_ccount();
while (!ccount); while (!ccount);
cpu_start_ccount = ccount; WRITE_ONCE(cpu_start_ccount, ccount);
while (time_before(jiffies, timeout)) { do {
/*
* Pairs with the first two memws in the
* .Lboot_secondary.
*/
mb(); mb();
if (!cpu_start_ccount) ccount = READ_ONCE(cpu_start_ccount);
break; } while (ccount && time_before(jiffies, timeout));
}
if (cpu_start_ccount) { if (ccount) {
smp_call_function_single(0, mx_cpu_stop, smp_call_function_single(0, mx_cpu_stop,
(void *)cpu, 1); (void *)cpu, 1);
cpu_start_ccount = 0; WRITE_ONCE(cpu_start_ccount, 0);
return -EIO; return -EIO;
} }
} }
...@@ -237,6 +247,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) ...@@ -237,6 +247,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
pr_debug("%s: Calling wakeup_secondary(cpu:%d, idle:%p, sp: %08lx)\n", pr_debug("%s: Calling wakeup_secondary(cpu:%d, idle:%p, sp: %08lx)\n",
__func__, cpu, idle, start_info.stack); __func__, cpu, idle, start_info.stack);
init_completion(&cpu_running);
ret = boot_secondary(cpu, idle); ret = boot_secondary(cpu, idle);
if (ret == 0) { if (ret == 0) {
wait_for_completion_timeout(&cpu_running, wait_for_completion_timeout(&cpu_running,
...@@ -298,8 +309,10 @@ void __cpu_die(unsigned int cpu) ...@@ -298,8 +309,10 @@ void __cpu_die(unsigned int cpu)
unsigned long timeout = jiffies + msecs_to_jiffies(1000); unsigned long timeout = jiffies + msecs_to_jiffies(1000);
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
system_invalidate_dcache_range((unsigned long)&cpu_start_id, system_invalidate_dcache_range((unsigned long)&cpu_start_id,
sizeof(cpu_start_id)); sizeof(cpu_start_id));
if (cpu_start_id == -cpu) { /* Pairs with the second memw in the cpu_restart */
mb();
if (READ_ONCE(cpu_start_id) == -cpu) {
platform_cpu_kill(cpu); platform_cpu_kill(cpu);
return; return;
} }
......
...@@ -89,7 +89,7 @@ static int ccount_timer_shutdown(struct clock_event_device *evt) ...@@ -89,7 +89,7 @@ static int ccount_timer_shutdown(struct clock_event_device *evt)
container_of(evt, struct ccount_timer, evt); container_of(evt, struct ccount_timer, evt);
if (timer->irq_enabled) { if (timer->irq_enabled) {
disable_irq(evt->irq); disable_irq_nosync(evt->irq);
timer->irq_enabled = 0; timer->irq_enabled = 0;
} }
return 0; return 0;
......
...@@ -71,14 +71,17 @@ static void xtensa_mx_irq_mask(struct irq_data *d) ...@@ -71,14 +71,17 @@ static void xtensa_mx_irq_mask(struct irq_data *d)
unsigned int mask = 1u << d->hwirq; unsigned int mask = 1u << d->hwirq;
if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE | if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) { XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
set_er(1u << (xtensa_get_ext_irq_no(d->hwirq) - unsigned int ext_irq = xtensa_get_ext_irq_no(d->hwirq);
HW_IRQ_MX_BASE), MIENG);
} else { if (ext_irq >= HW_IRQ_MX_BASE) {
mask = __this_cpu_read(cached_irq_mask) & ~mask; set_er(1u << (ext_irq - HW_IRQ_MX_BASE), MIENG);
__this_cpu_write(cached_irq_mask, mask); return;
xtensa_set_sr(mask, intenable); }
} }
mask = __this_cpu_read(cached_irq_mask) & ~mask;
__this_cpu_write(cached_irq_mask, mask);
xtensa_set_sr(mask, intenable);
} }
static void xtensa_mx_irq_unmask(struct irq_data *d) static void xtensa_mx_irq_unmask(struct irq_data *d)
...@@ -86,14 +89,17 @@ static void xtensa_mx_irq_unmask(struct irq_data *d) ...@@ -86,14 +89,17 @@ static void xtensa_mx_irq_unmask(struct irq_data *d)
unsigned int mask = 1u << d->hwirq; unsigned int mask = 1u << d->hwirq;
if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE | if (mask & (XCHAL_INTTYPE_MASK_EXTERN_EDGE |
XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) { XCHAL_INTTYPE_MASK_EXTERN_LEVEL)) {
set_er(1u << (xtensa_get_ext_irq_no(d->hwirq) - unsigned int ext_irq = xtensa_get_ext_irq_no(d->hwirq);
HW_IRQ_MX_BASE), MIENGSET);
} else { if (ext_irq >= HW_IRQ_MX_BASE) {
mask |= __this_cpu_read(cached_irq_mask); set_er(1u << (ext_irq - HW_IRQ_MX_BASE), MIENGSET);
__this_cpu_write(cached_irq_mask, mask); return;
xtensa_set_sr(mask, intenable); }
} }
mask |= __this_cpu_read(cached_irq_mask);
__this_cpu_write(cached_irq_mask, mask);
xtensa_set_sr(mask, intenable);
} }
static void xtensa_mx_irq_enable(struct irq_data *d) static void xtensa_mx_irq_enable(struct irq_data *d)
...@@ -113,7 +119,11 @@ static void xtensa_mx_irq_ack(struct irq_data *d) ...@@ -113,7 +119,11 @@ static void xtensa_mx_irq_ack(struct irq_data *d)
static int xtensa_mx_irq_retrigger(struct irq_data *d) static int xtensa_mx_irq_retrigger(struct irq_data *d)
{ {
xtensa_set_sr(1 << d->hwirq, intset); unsigned int mask = 1u << d->hwirq;
if (WARN_ON(mask & ~XCHAL_INTTYPE_MASK_SOFTWARE))
return 0;
xtensa_set_sr(mask, intset);
return 1; return 1;
} }
......
...@@ -70,7 +70,11 @@ static void xtensa_irq_ack(struct irq_data *d) ...@@ -70,7 +70,11 @@ static void xtensa_irq_ack(struct irq_data *d)
static int xtensa_irq_retrigger(struct irq_data *d) static int xtensa_irq_retrigger(struct irq_data *d)
{ {
xtensa_set_sr(1 << d->hwirq, intset); unsigned int mask = 1u << d->hwirq;
if (WARN_ON(mask & ~XCHAL_INTTYPE_MASK_SOFTWARE))
return 0;
xtensa_set_sr(mask, intset);
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment