Commit 497c01dd authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS fixes from Ralf Baechle:
 "Pretty much all across the field so with this we should be in
  reasonable shape for the upcoming -rc2"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  MIPS: OCTEON: make get_system_type() thread-safe
  MIPS: CPS: Initialize EVA before bringing up VPEs from secondary cores
  MIPS: Malta: EVA: Rename 'eva_entry' to 'platform_eva_init'
  MIPS: EVA: Add new EVA header
  MIPS: scall64-o32: Fix indirect syscall detection
  MIPS: syscall: Fix AUDIT value for O32 processes on MIPS64
  MIPS: Loongson: Fix COP2 usage for preemptible kernel
  MIPS: NL: Fix nlm_xlp_defconfig build error
  MIPS: Remove race window in page fault handling
  MIPS: Malta: Improve system memory detection for '{e, }memsize' >= 2G
  MIPS: Alchemy: Fix db1200 PSC clock enablement
  MIPS: BCM47XX: Fix reboot problem on BCM4705/BCM4785
  MIPS: Remove duplicated include from numa.c
  MIPS: Add common plat_irq_dispatch declaration
  MIPS: MSP71xx: remove unused plat_irq_dispatch() argument
  MIPS: GIC: Remove useless parens from GICBIS().
  MIPS: perf: Mark pmu interupt IRQF_NO_THREAD
parents 01e9982a 60830868
...@@ -847,6 +847,7 @@ int __init db1200_dev_setup(void) ...@@ -847,6 +847,7 @@ int __init db1200_dev_setup(void)
pr_warn("DB1200: cant get I2C close to 50MHz\n"); pr_warn("DB1200: cant get I2C close to 50MHz\n");
else else
clk_set_rate(c, pfc); clk_set_rate(c, pfc);
clk_prepare_enable(c);
clk_put(c); clk_put(c);
} }
...@@ -922,11 +923,6 @@ int __init db1200_dev_setup(void) ...@@ -922,11 +923,6 @@ int __init db1200_dev_setup(void)
} }
/* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
c = clk_get(NULL, "psc1_intclk");
if (!IS_ERR(c)) {
clk_prepare_enable(c);
clk_put(c);
}
__raw_writel(PSC_SEL_CLK_SERCLK, __raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb(); wmb();
......
...@@ -59,12 +59,21 @@ static void bcm47xx_machine_restart(char *command) ...@@ -59,12 +59,21 @@ static void bcm47xx_machine_restart(char *command)
switch (bcm47xx_bus_type) { switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB #ifdef CONFIG_BCM47XX_SSB
case BCM47XX_BUS_TYPE_SSB: case BCM47XX_BUS_TYPE_SSB:
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 3); if (bcm47xx_bus.ssb.chip_id == 0x4785)
write_c0_diag4(1 << 22);
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
if (bcm47xx_bus.ssb.chip_id == 0x4785) {
__asm__ __volatile__(
".set\tmips3\n\t"
"sync\n\t"
"wait\n\t"
".set\tmips0");
}
break; break;
#endif #endif
#ifdef CONFIG_BCM47XX_BCMA #ifdef CONFIG_BCM47XX_BCMA
case BCM47XX_BUS_TYPE_BCMA: case BCM47XX_BUS_TYPE_BCMA:
bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 3); bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
break; break;
#endif #endif
} }
......
...@@ -263,7 +263,6 @@ static uint64_t crashk_size, crashk_base; ...@@ -263,7 +263,6 @@ static uint64_t crashk_size, crashk_base;
static int octeon_uart; static int octeon_uart;
extern asmlinkage void handle_int(void); extern asmlinkage void handle_int(void);
extern asmlinkage void plat_irq_dispatch(void);
/** /**
* Return non zero if we are currently running in the Octeon simulator * Return non zero if we are currently running in the Octeon simulator
...@@ -458,6 +457,18 @@ static void octeon_halt(void) ...@@ -458,6 +457,18 @@ static void octeon_halt(void)
octeon_kill_core(NULL); octeon_kill_core(NULL);
} }
static char __read_mostly octeon_system_type[80];
static int __init init_octeon_system_type(void)
{
snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)",
cvmx_board_type_to_string(octeon_bootinfo->board_type),
octeon_model_get_string(read_c0_prid()));
return 0;
}
early_initcall(init_octeon_system_type);
/** /**
* Return a string representing the system type * Return a string representing the system type
* *
...@@ -465,11 +476,7 @@ static void octeon_halt(void) ...@@ -465,11 +476,7 @@ static void octeon_halt(void)
*/ */
const char *octeon_board_type_string(void) const char *octeon_board_type_string(void)
{ {
static char name[80]; return octeon_system_type;
sprintf(name, "%s (%s)",
cvmx_board_type_to_string(octeon_bootinfo->board_type),
octeon_model_get_string(read_c0_prid()));
return name;
} }
const char *get_system_type(void) const char *get_system_type(void)
......
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2014, Imagination Technologies Ltd.
*
* EVA functions for generic code
*/
#ifndef _ASM_EVA_H
#define _ASM_EVA_H
#include <kernel-entry-init.h>
#ifdef __ASSEMBLY__
#ifdef CONFIG_EVA
/*
* EVA early init code
*
* Platforms must define their own 'platform_eva_init' macro in
* their kernel-entry-init.h header. This macro usually does the
* platform specific configuration of the segmentation registers,
* and it is normally called from assembly code.
*
*/
.macro eva_init
platform_eva_init
.endm
#else
.macro eva_init
.endm
#endif /* CONFIG_EVA */
#endif /* __ASSEMBLY__ */
#endif
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#endif #endif
#define GICBIS(reg, mask, bits) \ #define GICBIS(reg, mask, bits) \
do { u32 data; \ do { u32 data; \
GICREAD((reg), data); \ GICREAD(reg, data); \
data &= ~(mask); \ data &= ~(mask); \
data |= ((bits) & (mask)); \ data |= ((bits) & (mask)); \
GICWRITE((reg), data); \ GICWRITE((reg), data); \
......
...@@ -26,6 +26,8 @@ static inline int irq_canonicalize(int irq) ...@@ -26,6 +26,8 @@ static inline int irq_canonicalize(int irq)
#define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */
#endif #endif
asmlinkage void plat_irq_dispatch(void);
extern void do_IRQ(unsigned int irq); extern void do_IRQ(unsigned int irq);
extern void arch_init_irq(void); extern void arch_init_irq(void);
......
...@@ -10,14 +10,15 @@ ...@@ -10,14 +10,15 @@
#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H #ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H #define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
#include <asm/regdef.h>
#include <asm/mipsregs.h>
/* /*
* Prepare segments for EVA boot: * Prepare segments for EVA boot:
* *
* This is in case the processor boots in legacy configuration * This is in case the processor boots in legacy configuration
* (SI_EVAReset is de-asserted and CONFIG5.K == 0) * (SI_EVAReset is de-asserted and CONFIG5.K == 0)
* *
* On entry, t1 is loaded with CP0_CONFIG
*
* ========================= Mappings ============================= * ========================= Mappings =============================
* Virtual memory Physical memory Mapping * Virtual memory Physical memory Mapping
* 0x00000000 - 0x7fffffff 0x80000000 - 0xfffffffff MUSUK (kuseg) * 0x00000000 - 0x7fffffff 0x80000000 - 0xfffffffff MUSUK (kuseg)
...@@ -30,12 +31,20 @@ ...@@ -30,12 +31,20 @@
* *
* *
* Lowmem is expanded to 2GB * Lowmem is expanded to 2GB
*
* The following code uses the t0, t1, t2 and ra registers without
* previously preserving them.
*
*/ */
.macro eva_entry .macro platform_eva_init
.set push
.set reorder
/* /*
* Get Config.K0 value and use it to program * Get Config.K0 value and use it to program
* the segmentation registers * the segmentation registers
*/ */
mfc0 t1, CP0_CONFIG
andi t1, 0x7 /* CCA */ andi t1, 0x7 /* CCA */
move t2, t1 move t2, t1
ins t2, t1, 16, 3 ins t2, t1, 16, 3
...@@ -77,6 +86,8 @@ ...@@ -77,6 +86,8 @@
mtc0 t0, $16, 5 mtc0 t0, $16, 5
sync sync
jal mips_ihb jal mips_ihb
.set pop
.endm .endm
.macro kernel_entry_setup .macro kernel_entry_setup
...@@ -95,7 +106,7 @@ ...@@ -95,7 +106,7 @@
sll t0, t0, 6 /* SC bit */ sll t0, t0, 6 /* SC bit */
bgez t0, 9f bgez t0, 9f
eva_entry platform_eva_init
b 0f b 0f
9: 9:
/* Assume we came from YAMON... */ /* Assume we came from YAMON... */
...@@ -127,8 +138,7 @@ ...@@ -127,8 +138,7 @@
#ifdef CONFIG_EVA #ifdef CONFIG_EVA
sync sync
ehb ehb
mfc0 t1, CP0_CONFIG platform_eva_init
eva_entry
#endif #endif
.endm .endm
......
...@@ -10,13 +10,6 @@ ...@@ -10,13 +10,6 @@
#include <asm/mach-netlogic/multi-node.h> #include <asm/mach-netlogic/multi-node.h>
#ifdef CONFIG_SMP
#define topology_physical_package_id(cpu) cpu_to_node(cpu)
#define topology_core_id(cpu) (cpu_logical_map(cpu) / NLM_THREADS_PER_CORE)
#define topology_thread_cpumask(cpu) (&cpu_sibling_map[cpu])
#define topology_core_cpumask(cpu) cpumask_of_node(cpu_to_node(cpu))
#endif
#include <asm-generic/topology.h> #include <asm-generic/topology.h>
#endif /* _ASM_MACH_NETLOGIC_TOPOLOGY_H */ #endif /* _ASM_MACH_NETLOGIC_TOPOLOGY_H */
...@@ -122,6 +122,9 @@ do { \ ...@@ -122,6 +122,9 @@ do { \
} \ } \
} while(0) } while(0)
extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
pte_t pteval);
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
...@@ -145,7 +148,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte) ...@@ -145,7 +148,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
} }
} }
} }
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{ {
...@@ -183,7 +185,6 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) ...@@ -183,7 +185,6 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
} }
#endif #endif
} }
#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{ {
...@@ -390,15 +391,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ...@@ -390,15 +391,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
pte_t pte); pte_t pte);
extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
pte_t pte);
static inline void update_mmu_cache(struct vm_area_struct *vma, static inline void update_mmu_cache(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep) unsigned long address, pte_t *ptep)
{ {
pte_t pte = *ptep; pte_t pte = *ptep;
__update_tlb(vma, address, pte); __update_tlb(vma, address, pte);
__update_cache(vma, address, pte);
} }
static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
......
...@@ -131,10 +131,12 @@ static inline int syscall_get_arch(void) ...@@ -131,10 +131,12 @@ static inline int syscall_get_arch(void)
{ {
int arch = EM_MIPS; int arch = EM_MIPS;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
if (!test_thread_flag(TIF_32BIT_REGS)) if (!test_thread_flag(TIF_32BIT_REGS)) {
arch |= __AUDIT_ARCH_64BIT; arch |= __AUDIT_ARCH_64BIT;
if (test_thread_flag(TIF_32BIT_ADDR)) /* N32 sets only TIF_32BIT_ADDR */
arch |= __AUDIT_ARCH_CONVENTION_MIPS64_N32; if (test_thread_flag(TIF_32BIT_ADDR))
arch |= __AUDIT_ARCH_CONVENTION_MIPS64_N32;
}
#endif #endif
#if defined(__LITTLE_ENDIAN) #if defined(__LITTLE_ENDIAN)
arch |= __AUDIT_ARCH_LE; arch |= __AUDIT_ARCH_LE;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/asmmacro.h> #include <asm/asmmacro.h>
#include <asm/cacheops.h> #include <asm/cacheops.h>
#include <asm/eva.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/mipsmtregs.h> #include <asm/mipsmtregs.h>
#include <asm/pm.h> #include <asm/pm.h>
...@@ -166,6 +167,9 @@ dcache_done: ...@@ -166,6 +167,9 @@ dcache_done:
1: jal mips_cps_core_init 1: jal mips_cps_core_init
nop nop
/* Do any EVA initialization if necessary */
eva_init
/* /*
* Boot any other VPEs within this core that should be online, and * Boot any other VPEs within this core that should be online, and
* deactivate this VPE if it should be offline. * deactivate this VPE if it should be offline.
......
...@@ -558,7 +558,7 @@ static int mipspmu_get_irq(void) ...@@ -558,7 +558,7 @@ static int mipspmu_get_irq(void)
if (mipspmu.irq >= 0) { if (mipspmu.irq >= 0) {
/* Request my own irq handler. */ /* Request my own irq handler. */
err = request_irq(mipspmu.irq, mipsxx_pmu_handle_irq, err = request_irq(mipspmu.irq, mipsxx_pmu_handle_irq,
IRQF_PERCPU | IRQF_NOBALANCING, IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD,
"mips_perf_pmu", NULL); "mips_perf_pmu", NULL);
if (err) { if (err) {
pr_warning("Unable to request IRQ%d for MIPS " pr_warning("Unable to request IRQ%d for MIPS "
......
...@@ -113,15 +113,19 @@ trace_a_syscall: ...@@ -113,15 +113,19 @@ trace_a_syscall:
move s0, t2 # Save syscall pointer move s0, t2 # Save syscall pointer
move a0, sp move a0, sp
/* /*
* syscall number is in v0 unless we called syscall(__NR_###) * absolute syscall number is in v0 unless we called syscall(__NR_###)
* where the real syscall number is in a0 * where the real syscall number is in a0
* note: NR_syscall is the first O32 syscall but the macro is * note: NR_syscall is the first O32 syscall but the macro is
* only defined when compiling with -mabi=32 (CONFIG_32BIT) * only defined when compiling with -mabi=32 (CONFIG_32BIT)
* therefore __NR_O32_Linux is used (4000) * therefore __NR_O32_Linux is used (4000)
*/ */
addiu a1, v0, __NR_O32_Linux .set push
bnez v0, 1f /* __NR_syscall at offset 0 */ .set reorder
lw a1, PT_R4(sp) subu t1, v0, __NR_O32_Linux
move a1, v0
bnez t1, 1f /* __NR_syscall at offset 0 */
lw a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
.set pop
1: jal syscall_trace_enter 1: jal syscall_trace_enter
......
...@@ -22,13 +22,13 @@ ...@@ -22,13 +22,13 @@
static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
void *data) void *data)
{ {
int fpu_enabled; int fpu_owned;
int fr = !test_thread_flag(TIF_32BIT_FPREGS); int fr = !test_thread_flag(TIF_32BIT_FPREGS);
switch (action) { switch (action) {
case CU2_EXCEPTION: case CU2_EXCEPTION:
preempt_disable(); preempt_disable();
fpu_enabled = read_c0_status() & ST0_CU1; fpu_owned = __is_fpu_owner();
if (!fr) if (!fr)
set_c0_status(ST0_CU1 | ST0_CU2); set_c0_status(ST0_CU1 | ST0_CU2);
else else
...@@ -39,8 +39,8 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, ...@@ -39,8 +39,8 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
KSTK_STATUS(current) |= ST0_FR; KSTK_STATUS(current) |= ST0_FR;
else else
KSTK_STATUS(current) &= ~ST0_FR; KSTK_STATUS(current) &= ~ST0_FR;
/* If FPU is enabled, we needn't init or restore fp */ /* If FPU is owned, we needn't init or restore fp */
if(!fpu_enabled) { if (!fpu_owned) {
set_thread_flag(TIF_USEDFPU); set_thread_flag(TIF_USEDFPU);
if (!used_math()) { if (!used_math()) {
_init_fpu(); _init_fpu();
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <linux/bootmem.h>
#include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/mc146818-time.h> #include <asm/mc146818-time.h>
......
...@@ -119,25 +119,36 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) ...@@ -119,25 +119,36 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
EXPORT_SYMBOL(__flush_anon_page); EXPORT_SYMBOL(__flush_anon_page);
void __update_cache(struct vm_area_struct *vma, unsigned long address, static void mips_flush_dcache_from_pte(pte_t pteval, unsigned long address)
pte_t pte)
{ {
struct page *page; struct page *page;
unsigned long pfn, addr; unsigned long pfn = pte_pfn(pteval);
int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
pfn = pte_pfn(pte);
if (unlikely(!pfn_valid(pfn))) if (unlikely(!pfn_valid(pfn)))
return; return;
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
if (page_mapping(page) && Page_dcache_dirty(page)) { if (page_mapping(page) && Page_dcache_dirty(page)) {
addr = (unsigned long) page_address(page); unsigned long page_addr = (unsigned long) page_address(page);
if (exec || pages_do_alias(addr, address & PAGE_MASK))
flush_data_cache_page(addr); if (!cpu_has_ic_fills_f_dc ||
pages_do_alias(page_addr, address & PAGE_MASK))
flush_data_cache_page(page_addr);
ClearPageDcacheDirty(page); ClearPageDcacheDirty(page);
} }
} }
void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) {
if (pte_present(pteval))
mips_flush_dcache_from_pte(pteval, addr);
}
set_pte(ptep, pteval);
}
unsigned long _page_cachable_default; unsigned long _page_cachable_default;
EXPORT_SYMBOL(_page_cachable_default); EXPORT_SYMBOL(_page_cachable_default);
......
...@@ -35,13 +35,19 @@ fw_memblock_t * __init fw_getmdesc(int eva) ...@@ -35,13 +35,19 @@ fw_memblock_t * __init fw_getmdesc(int eva)
/* otherwise look in the environment */ /* otherwise look in the environment */
memsize_str = fw_getenv("memsize"); memsize_str = fw_getenv("memsize");
if (memsize_str) if (memsize_str) {
tmp = kstrtol(memsize_str, 0, &memsize); tmp = kstrtoul(memsize_str, 0, &memsize);
if (tmp)
pr_warn("Failed to read the 'memsize' env variable.\n");
}
if (eva) { if (eva) {
/* Look for ememsize for EVA */ /* Look for ememsize for EVA */
ememsize_str = fw_getenv("ememsize"); ememsize_str = fw_getenv("ememsize");
if (ememsize_str) if (ememsize_str) {
tmp = kstrtol(ememsize_str, 0, &ememsize); tmp = kstrtoul(ememsize_str, 0, &ememsize);
if (tmp)
pr_warn("Failed to read the 'ememsize' env variable.\n");
}
} }
if (!memsize && !ememsize) { if (!memsize && !ememsize) {
pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); pr_warn("memsize not set in YAMON, set to default (32Mb)\n");
......
...@@ -51,7 +51,7 @@ static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); } ...@@ -51,7 +51,7 @@ static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); }
* the range 40-71. * the range 40-71.
*/ */
asmlinkage void plat_irq_dispatch(struct pt_regs *regs) asmlinkage void plat_irq_dispatch(void)
{ {
u32 pending; u32 pending;
......
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