Commit e31a94ed authored by Linus Torvalds's avatar Linus Torvalds

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

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (45 commits)
  [MIPS] Pb1200/DBAu1200: move platform code to its proper place
  [MIPS] Fix handling of trap and breakpoint instructions
  [MIPS] Pb1200: do register SMC 91C111
  [MIPS] DBAu1200: fix bad SMC 91C111 resource size
  [NET] Kconfig: Rename MIKROTIK_RB500 -> MIKROTIK_RB532
  [MIPS] IP27: Fix build bug due to missing include
  [MIPS] Fix some sparse warnings on traps.c and irq-msc01.c
  [MIPS] cevt-gt641xx: Kill unnecessary include
  [MIPS] DS1287: Add clockevent driver
  [MIPS] add DECstation I/O ASIC clocksource
  [MIPS] rbtx4938: minor cleanup
  [MIPS] Alchemy: kill unused PCI_IRQ_TABLE_LOOKUP macro
  [MIPS] rbtx4938: misc cleanups
  [MIPS] jmr3927: use generic txx9 gpio
  [MIPS] rbhma4500: use generic txx9 gpio
  [MIPS] generic txx9 gpio support
  [MIPS] make fallback gpio.h gpiolib-friendly
  [MIPS] unexport null_perf_irq() and make it static
  [MIPS] unexport rtc_mips_set_time()
  [MIPS] unexport copy_from_user_page()
  ...
parents 9d9ad4b5 fcbd3b4b
......@@ -81,7 +81,9 @@ config MIPS_COBALT
config MACH_DECSTATION
bool "DECstations"
select BOOT_ELF32
select CEVT_DS1287
select CEVT_R4K
select CSRC_IOASIC
select CSRC_R4K
select CPU_DADDI_WORKAROUNDS if 64BIT
select CPU_R4000_WORKAROUNDS if 64BIT
......@@ -221,6 +223,7 @@ config MIPS_MALTA
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select IRQ_CPU
select IRQ_GIC
select HW_HAS_PCI
select I8253
select I8259
......@@ -309,12 +312,12 @@ config MACH_VR41XX
select GENERIC_HARDIRQS_NO__DO_IRQ
config PNX8550_JBS
bool "Philips PNX8550 based JBS board"
bool "NXP PNX8550 based JBS board"
select PNX8550
select SYS_SUPPORTS_LITTLE_ENDIAN
config PNX8550_STB810
bool "Philips PNX8550 based STB810 board"
bool "NXP PNX8550 based STB810 board"
select PNX8550
select SYS_SUPPORTS_LITTLE_ENDIAN
......@@ -612,6 +615,7 @@ config TOSHIBA_JMR3927
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
select GENERIC_HARDIRQS_NO__DO_IRQ
select GPIO_TXX9
config TOSHIBA_RBTX4927
bool "Toshiba RBTX49[23]7 board"
......@@ -653,7 +657,7 @@ config TOSHIBA_RBTX4938
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_KGDB
select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_GPIO
select GPIO_TXX9
help
This Toshiba board is based on the TX4938 processor. Say Y here to
support this machine type
......@@ -767,6 +771,9 @@ config BOOT_RAW
config CEVT_BCM1480
bool
config CEVT_DS1287
bool
config CEVT_GT641XX
bool
......@@ -782,12 +789,20 @@ config CEVT_TXX9
config CSRC_BCM1480
bool
config CSRC_IOASIC
bool
config CSRC_R4K
bool
config CSRC_SB1250
bool
config GPIO_TXX9
select GENERIC_GPIO
select HAVE_GPIO_LIB
bool
config CFE
bool
......@@ -840,6 +855,9 @@ config MIPS_NILE4
config MIPS_DISABLE_OBSOLETE_IDE
bool
config SYNC_R4K
bool
config NO_IOPORT
def_bool n
......@@ -909,6 +927,9 @@ config IRQ_TXX9
config IRQ_GT641XX
bool
config IRQ_GIC
bool
config MIPS_BOARDS_GEN
bool
......@@ -1811,6 +1832,17 @@ config NR_CPUS
performance should round up your number of processors to the next
power of two.
config MIPS_CMP
bool "MIPS CMP framework support"
depends on SMP
select SYNC_R4K
select SYS_SUPPORTS_SCHED_SMT
select WEAK_ORDERING
default n
help
This is a placeholder option for the GCMP work. It will need to
be handled differently...
source "kernel/time/Kconfig"
#
......
......@@ -73,14 +73,4 @@ config RUNTIME_DEBUG
include/asm-mips/debug.h for debuging macros.
If unsure, say N.
config MIPS_UNCACHED
bool "Run uncached"
depends on DEBUG_KERNEL && !SMP && !SGI_IP27
help
If you say Y here there kernel will disable all CPU caches. This will
reduce the system's performance dramatically but can help finding
otherwise hard to track bugs. It can also useful if you're doing
hardware debugging with a logic analyzer and need to see all traffic
on the bus.
endmenu
......@@ -410,21 +410,21 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
#
# Common Philips PNX8550
# Common NXP PNX8550
#
core-$(CONFIG_SOC_PNX8550) += arch/mips/philips/pnx8550/common/
core-$(CONFIG_SOC_PNX8550) += arch/mips/nxp/pnx8550/common/
cflags-$(CONFIG_SOC_PNX8550) += -Iinclude/asm-mips/mach-pnx8550
#
# Philips PNX8550 JBS board
# NXP PNX8550 JBS board
#
libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/
libs-$(CONFIG_PNX8550_JBS) += arch/mips/nxp/pnx8550/jbs/
#cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550
load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
# Philips PNX8550 STB810 board
# NXP PNX8550 STB810 board
#
libs-$(CONFIG_PNX8550_STB810) += arch/mips/philips/pnx8550/stb810/
libs-$(CONFIG_PNX8550_STB810) += arch/mips/nxp/pnx8550/stb810/
load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000
# NEC EMMA2RH boards
......
......@@ -11,10 +11,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/init.h>
#include <asm/mach-au1x00/au1000.h>
struct cpu_spec* cur_cpu_spec[NR_CPUS];
......
......@@ -31,18 +31,12 @@
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/system.h>
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
......
#include <asm/io.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_KGDB
......@@ -55,8 +54,7 @@ typedef unsigned int uint32;
#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff)
#define UART16550_WRITE(y, z) (au_writel(z&0xff, DEBUG_BASE + y))
extern unsigned long get_au1x00_uart_baud_base(void);
extern unsigned long cal_r4koff(void);
extern unsigned long calc_clock(void);
void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
{
......@@ -64,7 +62,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
if (UART16550_READ(UART_MOD_CNTRL) != 0x3) {
UART16550_WRITE(UART_MOD_CNTRL, 3);
}
cal_r4koff();
calc_clock();
/* disable interrupts */
UART16550_WRITE(UART_IER, 0);
......
......@@ -33,12 +33,9 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>
......
......@@ -27,13 +27,8 @@
* others have a second one : GPIO2
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/types.h>
#include <linux/module.h>
#include <asm/addrspace.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/gpio.h>
......
/*
* Copyright 2001 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
* ppopov@mvista.com or source@mvista.com
* Copyright 2001, 2007-2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
*
......@@ -27,7 +26,6 @@
*/
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
......@@ -591,7 +589,7 @@ void __init arch_init_irq(void)
imp++;
}
set_c0_status(ALLINTS);
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
/* Board specific IRQ initialization.
*/
......
......@@ -30,7 +30,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
......
......@@ -3,18 +3,65 @@
*
* Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
*
* (C) Copyright Embedded Alley Solutions, Inc 2005
* Author: Pantelis Antoniou <pantelis@embeddedalley.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/serial_8250.h>
#include <linux/init.h>
#include <linux/resource.h>
#include <asm/mach-au1x00/au1xxx.h>
#define PORT(_base, _irq) \
{ \
.iobase = _base, \
.membase = (void __iomem *)_base,\
.mapbase = CPHYSADDR(_base), \
.irq = _irq, \
.regshift = 2, \
.iotype = UPIO_AU, \
.flags = UPF_SKIP_TEST \
}
static struct plat_serial8250_port au1x00_uart_data[] = {
#if defined(CONFIG_SERIAL_8250_AU1X00)
#if defined(CONFIG_SOC_AU1000)
PORT(UART0_ADDR, AU1000_UART0_INT),
PORT(UART1_ADDR, AU1000_UART1_INT),
PORT(UART2_ADDR, AU1000_UART2_INT),
PORT(UART3_ADDR, AU1000_UART3_INT),
#elif defined(CONFIG_SOC_AU1500)
PORT(UART0_ADDR, AU1500_UART0_INT),
PORT(UART3_ADDR, AU1500_UART3_INT),
#elif defined(CONFIG_SOC_AU1100)
PORT(UART0_ADDR, AU1100_UART0_INT),
PORT(UART1_ADDR, AU1100_UART1_INT),
PORT(UART3_ADDR, AU1100_UART3_INT),
#elif defined(CONFIG_SOC_AU1550)
PORT(UART0_ADDR, AU1550_UART0_INT),
PORT(UART1_ADDR, AU1550_UART1_INT),
PORT(UART3_ADDR, AU1550_UART3_INT),
#elif defined(CONFIG_SOC_AU1200)
PORT(UART0_ADDR, AU1200_UART0_INT),
PORT(UART1_ADDR, AU1200_UART1_INT),
#endif
#endif /* CONFIG_SERIAL_8250_AU1X00 */
{ },
};
static struct platform_device au1xx0_uart_device = {
.name = "serial8250",
.id = PLAT8250_DEV_AU1X00,
.dev = {
.platform_data = au1x00_uart_data,
},
};
/* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = {
[0] = {
......@@ -186,19 +233,6 @@ static struct resource au1200_lcd_resources[] = {
}
};
static struct resource au1200_ide0_resources[] = {
[0] = {
.start = AU1XXX_ATA_PHYS_ADDR,
.end = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1XXX_ATA_INT,
.end = AU1XXX_ATA_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1200_lcd_dmamask = ~(u32)0;
static struct platform_device au1200_lcd_device = {
......@@ -212,20 +246,6 @@ static struct platform_device au1200_lcd_device = {
.resource = au1200_lcd_resources,
};
static u64 ide0_dmamask = ~(u32)0;
static struct platform_device au1200_ide0_device = {
.name = "au1200-ide",
.id = 0,
.dev = {
.dma_mask = &ide0_dmamask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(au1200_ide0_resources),
.resource = au1200_ide0_resources,
};
static u64 au1xxx_mmc_dmamask = ~(u32)0;
static struct platform_device au1xxx_mmc_device = {
......@@ -245,31 +265,6 @@ static struct platform_device au1x00_pcmcia_device = {
.id = 0,
};
#ifdef CONFIG_MIPS_DB1200
static struct resource smc91x_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = AU1XXX_SMC91111_PHYS_ADDR,
.end = AU1XXX_SMC91111_PHYS_ADDR + 0xfffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1XXX_SMC91111_IRQ,
.end = AU1XXX_SMC91111_IRQ,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
};
#endif
/* All Alchemy demoboards with I2C have this #define in their headers */
#ifdef SMBUS_PSC_BASE
static struct resource pbdb_smbus_resources[] = {
......@@ -289,6 +284,7 @@ static struct platform_device pbdb_smbus_device = {
#endif
static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xx0_uart_device,
&au1xxx_usb_ohci_device,
&au1x00_pcmcia_device,
#ifdef CONFIG_FB_AU1100
......@@ -299,12 +295,8 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xxx_usb_gdt_device,
&au1xxx_usb_otg_device,
&au1200_lcd_device,
&au1200_ide0_device,
&au1xxx_mmc_device,
#endif
#ifdef CONFIG_MIPS_DB1200
&smc91x_device,
#endif
#ifdef SMBUS_PSC_BASE
&pbdb_smbus_device,
#endif
......@@ -312,6 +304,13 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
int __init au1xxx_platform_init(void)
{
unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
int i;
/* Fill up uartclk. */
for (i = 0; au1x00_uart_data[i].flags ; i++)
au1x00_uart_data[i].uartclk = uartclk;
return platform_add_devices(au1xxx_platform_devices, ARRAY_SIZE(au1xxx_platform_devices));
}
......
......@@ -29,17 +29,14 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/pm_legacy.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/jiffies.h>
#include <asm/string.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/cacheflush.h>
#include <asm/mach-au1x00/au1000.h>
......@@ -47,17 +44,13 @@
#define DEBUG 1
#ifdef DEBUG
# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
# define DPRINTK(fmt, args...) printk("%s: " fmt, __func__, ## args)
#else
# define DPRINTK(fmt, args...)
#endif
static void au1000_calibrate_delay(void);
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
extern unsigned long get_au1x00_uart_baud_base(void);
extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
extern unsigned long save_local_and_disable(int controller);
extern void restore_local_and_enable(int controller, unsigned long mask);
extern void local_enable_irq(unsigned int irq_nr);
......
......@@ -33,8 +33,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
......
......@@ -28,7 +28,6 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <asm/mach-au1x00/au1000.h>
#define SERIAL_BASE UART_BASE
......
......@@ -27,13 +27,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/reboot.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
extern int au_sleep(void);
......
......@@ -25,21 +25,14 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/time.h>
#include <au1000.h>
......@@ -49,8 +42,6 @@ extern void __init board_setup(void);
extern void au1000_restart(char *);
extern void au1000_halt(void);
extern void au1000_power_off(void);
extern void au1x_time_init(void);
extern void au1x_timer_setup(struct irqaction *irq);
extern void set_cpuspec(void);
void __init plat_mem_setup(void)
......
......@@ -9,9 +9,9 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <asm/asm.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
......
/*
*
* Copyright (C) 2001 MontaVista Software, ppopov@mvista.com
* Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
* Copied and modified Carsten Langgaard's time.c
*
* Carsten Langgaard, carstenl@mips.com
......@@ -34,23 +34,13 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/hardirq.h>
#include <asm/compiler.h>
#include <asm/mipsregs.h>
#include <asm/time.h>
#include <asm/div64.h>
#include <asm/mach-au1x00/au1000.h>
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
static unsigned long r4k_offset; /* Amount to increment compare reg each time */
static unsigned long r4k_cur; /* What counter should be at next timer irq */
int no_au1xxx_32khz;
static int no_au1xxx_32khz;
extern int allow_au1k_wait; /* default off for CP0 Counter */
#ifdef CONFIG_PM
......@@ -184,7 +174,7 @@ wakeup_counter0_set(int ticks)
* "wait" is enabled, and we need to detect if the 32KHz isn't present
* but requested......got it? :-) -- Dan
*/
unsigned long cal_r4koff(void)
unsigned long calc_clock(void)
{
unsigned long cpu_speed;
unsigned long flags;
......@@ -229,19 +219,13 @@ unsigned long cal_r4koff(void)
// Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
spin_unlock_irqrestore(&time_lock, flags);
return (cpu_speed / HZ);
return cpu_speed;
}
void __init plat_time_init(void)
{
unsigned int est_freq;
printk("calculating r4koff... ");
r4k_offset = cal_r4koff();
printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
unsigned int est_freq = calc_clock();
//est_freq = 2*r4k_offset*HZ;
est_freq = r4k_offset*HZ;
est_freq += 5000; /* round */
est_freq -= est_freq%10000;
printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
......@@ -249,9 +233,6 @@ void __init plat_time_init(void)
set_au1x00_speed(est_freq);
set_au1x00_lcd_clock(); // program the LCD clock
r4k_cur = (read_c0_count() + r4k_offset);
write_c0_compare(r4k_cur);
#ifdef CONFIG_PM
/*
* setup counter 0, since it keeps ticking after a
......@@ -265,12 +246,8 @@ void __init plat_time_init(void)
* Check to ensure we really have a 32KHz oscillator before
* we do this.
*/
if (no_au1xxx_32khz) {
if (no_au1xxx_32khz)
printk("WARNING: no 32KHz clock found.\n");
/* Ensure we get CPO_COUNTER interrupts. */
set_c0_status(IE_IRQ5);
}
else {
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
au_writel(0, SYS_TOYWRITE);
......
......@@ -27,20 +27,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/mc146818rtc.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/db1x00.h>
......
......@@ -28,13 +28,8 @@
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_MIPS_DB1500
......
......@@ -28,19 +28,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
......
......@@ -28,14 +28,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
......
......@@ -19,7 +19,6 @@
*/
#include <linux/init.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio_keys.h>
......
......@@ -23,19 +23,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1000.h>
......
......@@ -26,14 +26,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
......
......@@ -23,19 +23,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1100.h>
......
......@@ -27,14 +27,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
......
......@@ -3,5 +3,6 @@
#
lib-y := init.o board_setup.o irqmap.o
obj-y += platform.o
EXTRA_CFLAGS += -Werror
......@@ -23,27 +23,11 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/mc146818rtc.h>
#include <linux/delay.h>
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
#include <linux/ide.h>
#endif
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <au1000.h>
#include <au1xxx_dbdma.h>
#include <prom.h>
#ifdef CONFIG_MIPS_PB1200
......@@ -52,8 +36,6 @@
#ifdef CONFIG_MIPS_DB1200
#include <asm/mach-db1x00/db1200.h>
#define PB1200_ETH_INT DB1200_ETH_INT
#define PB1200_IDE_INT DB1200_IDE_INT
#endif
extern void _board_init_irq(void);
......
......@@ -27,14 +27,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -22,26 +22,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_MIPS_PB1200
......
/*
* Pb1200/DBAu1200 board platform device registration
*
* Copyright (C) 2008 MontaVista Software Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1xxx.h>
static struct resource ide_resources[] = {
[0] = {
.start = IDE_PHYS_ADDR,
.end = IDE_PHYS_ADDR + IDE_PHYS_LEN - 1,
.flags = IORESOURCE_MEM
},
[1] = {
.start = IDE_INT,
.end = IDE_INT,
.flags = IORESOURCE_IRQ
}
};
static u64 ide_dmamask = ~(u32)0;
static struct platform_device ide_device = {
.name = "au1200-ide",
.id = 0,
.dev = {
.dma_mask = &ide_dmamask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = ARRAY_SIZE(ide_resources),
.resource = ide_resources
};
static struct resource smc91c111_resources[] = {
[0] = {
.name = "smc91x-regs",
.start = SMC91C111_PHYS_ADDR,
.end = SMC91C111_PHYS_ADDR + 0xf,
.flags = IORESOURCE_MEM
},
[1] = {
.start = SMC91C111_INT,
.end = SMC91C111_INT,
.flags = IORESOURCE_IRQ
},
};
static struct platform_device smc91c111_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91c111_resources),
.resource = smc91c111_resources
};
static struct platform_device *board_platform_devices[] __initdata = {
&ide_device,
&smc91c111_device
};
static int __init board_register_devices(void)
{
return platform_add_devices(board_platform_devices,
ARRAY_SIZE(board_platform_devices));
}
arch_initcall(board_register_devices);
......@@ -23,19 +23,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1500.h>
......
......@@ -27,14 +27,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
......
......@@ -27,20 +27,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/mc146818rtc.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1550.h>
......
......@@ -27,14 +27,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
......
......@@ -23,19 +23,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
void board_reset(void)
......
......@@ -26,14 +26,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
......
......@@ -25,26 +25,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
......
......@@ -641,7 +641,6 @@ CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_RUNTIME_DEBUG is not set
# CONFIG_MIPS_UNCACHED is not set
#
# Security options
......
......@@ -1223,7 +1223,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
# CONFIG_KGDB is not set
CONFIG_SYS_SUPPORTS_KGDB=y
# CONFIG_RUNTIME_DEBUG is not set
# CONFIG_MIPS_UNCACHED is not set
#
# Security options
......
......@@ -1213,7 +1213,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
# CONFIG_KGDB is not set
CONFIG_SYS_SUPPORTS_KGDB=y
# CONFIG_RUNTIME_DEBUG is not set
# CONFIG_MIPS_UNCACHED is not set
#
# Security options
......
......@@ -9,30 +9,15 @@
*
*/
#include <linux/bcd.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mc146818rtc.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/param.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/types.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/sections.h>
#include <asm/time.h>
#include <asm/cpu-features.h>
#include <asm/ds1287.h>
#include <asm/time.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/machtype.h>
unsigned long read_persistent_clock(void)
......@@ -139,42 +124,32 @@ int rtc_mips_set_mmss(unsigned long nowtime)
return retval;
}
static int dec_timer_state(void)
void __init plat_time_init(void)
{
return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0;
}
u32 start, end;
int i = HZ / 10;
static void dec_timer_ack(void)
{
CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */
}
static cycle_t dec_ioasic_hpt_read(void)
{
/*
* The free-running counter is 32-bit which is good for about
* 2 minutes, 50 seconds at possible count rates of up to 25MHz.
*/
return ioasic_read(IO_REG_FCTR);
}
/* Set up the rate of periodic DS1287 interrupts. */
ds1287_set_base_clock(HZ);
if (cpu_has_counter) {
while (!ds1287_timer_state())
;
void __init plat_time_init(void)
{
mips_timer_ack = dec_timer_ack;
start = read_c0_count();
if (!cpu_has_counter && IOASIC)
/* For pre-R4k systems we use the I/O ASIC's counter. */
clocksource_mips.read = dec_ioasic_hpt_read;
while (i--)
while (!ds1287_timer_state())
;
/* Set up the rate of periodic DS1287 interrupts. */
CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
}
end = read_c0_count();
void __init plat_timer_setup(struct irqaction *irq)
{
setup_irq(dec_interrupt[DEC_IRQ_RTC], irq);
mips_hpt_frequency = (end - start) * 10;
printk(KERN_INFO "MIPS counter frequency %dHz\n",
mips_hpt_frequency);
} else if (IOASIC)
/* For pre-R4k systems we use the I/O ASIC's counter. */
dec_ioasic_clocksource_init();
/* Enable periodic DS1287 interrupts. */
CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B);
ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]);
}
......@@ -36,11 +36,13 @@
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#ifdef CONFIG_SERIAL_TXX9
#include <linux/serial_core.h>
#endif
#include <asm/txx9tmr.h>
#include <asm/txx9pio.h>
#include <asm/reboot.h>
#include <asm/jmr3927/jmr3927.h>
#include <asm/mipsregs.h>
......@@ -340,9 +342,12 @@ static void __init tx3927_setup(void)
/* PIO */
/* PIO[15:12] connected to LEDs */
tx3927_pioptr->dir = 0x0000f000;
tx3927_pioptr->maskcpu = 0;
tx3927_pioptr->maskext = 0;
__raw_writel(0x0000f000, &tx3927_pioptr->dir);
__raw_writel(0, &tx3927_pioptr->maskcpu);
__raw_writel(0, &tx3927_pioptr->maskext);
txx9_gpio_init(TX3927_PIO_REG, 0, 16);
gpio_request(11, "dipsw1");
gpio_request(10, "dipsw2");
{
unsigned int conf;
......
......@@ -10,12 +10,15 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o
......@@ -50,6 +53,8 @@ obj-$(CONFIG_MIPS_MT) += mips-mt.o
obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o
obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
obj-$(CONFIG_MIPS_CMP) += smp-cmp.o
obj-$(CONFIG_CPU_MIPSR2) += spram.o
obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
......@@ -62,6 +67,7 @@ obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o
obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o
obj-$(CONFIG_IRQ_GIC) += irq-gic.o
obj-$(CONFIG_32BIT) += scall32-o32.o
obj-$(CONFIG_64BIT) += scall64-64.o
......@@ -77,6 +83,8 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o
obj-$(CONFIG_I8253) += i8253.o
obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
......
/*
* DS1287 clockevent driver
*
* Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <asm/time.h>
int ds1287_timer_state(void)
{
return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0;
}
int ds1287_set_base_clock(unsigned int hz)
{
u8 rate;
switch (hz) {
case 128:
rate = 0x9;
break;
case 256:
rate = 0x8;
break;
case 1024:
rate = 0x6;
break;
default:
return -EINVAL;
}
CMOS_WRITE(RTC_REF_CLCK_32KHZ | rate, RTC_REG_A);
return 0;
}
static int ds1287_set_next_event(unsigned long delta,
struct clock_event_device *evt)
{
return -EINVAL;
}
static void ds1287_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
u8 val;
spin_lock(&rtc_lock);
val = CMOS_READ(RTC_REG_B);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
val |= RTC_PIE;
break;
default:
val &= ~RTC_PIE;
break;
}
CMOS_WRITE(val, RTC_REG_B);
spin_unlock(&rtc_lock);
}
static void ds1287_event_handler(struct clock_event_device *dev)
{
}
static struct clock_event_device ds1287_clockevent = {
.name = "ds1287",
.features = CLOCK_EVT_FEAT_PERIODIC,
.cpumask = CPU_MASK_CPU0,
.set_next_event = ds1287_set_next_event,
.set_mode = ds1287_set_mode,
.event_handler = ds1287_event_handler,
};
static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd = &ds1287_clockevent;
/* Ack the RTC interrupt. */
CMOS_READ(RTC_REG_C);
cd->event_handler(cd);
return IRQ_HANDLED;
}
static struct irqaction ds1287_irqaction = {
.handler = ds1287_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU,
.name = "ds1287",
};
int __init ds1287_clockevent_init(int irq)
{
struct clock_event_device *cd;
cd = &ds1287_clockevent;
cd->rating = 100;
cd->irq = irq;
clockevent_set_clock(cd, 32768);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
clockevents_register_device(&ds1287_clockevent);
return setup_irq(irq, &ds1287_irqaction);
}
......@@ -25,8 +25,6 @@
#include <asm/gt64120.h>
#include <asm/time.h>
#include <irq.h>
static DEFINE_SPINLOCK(gt641xx_timer_lock);
static unsigned int gt641xx_base_clock;
......
......@@ -169,6 +169,7 @@ static inline void check_wait(void)
case CPU_24K:
case CPU_34K:
case CPU_1004K:
cpu_wait = r4k_wait;
if (read_c0_config7() & MIPS_CONF7_WII)
cpu_wait = r4k_wait_irqoff;
......@@ -675,6 +676,12 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
return;
}
#ifdef CONFIG_CPU_MIPSR2
extern void spram_config(void);
#else
static inline void spram_config(void) {}
#endif
static inline void cpu_probe_mips(struct cpuinfo_mips *c)
{
decode_configs(c);
......@@ -711,7 +718,12 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c)
case PRID_IMP_74K:
c->cputype = CPU_74K;
break;
case PRID_IMP_1004K:
c->cputype = CPU_1004K;
break;
}
spram_config();
}
static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
......@@ -778,7 +790,7 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
}
}
static inline void cpu_probe_philips(struct cpuinfo_mips *c)
static inline void cpu_probe_nxp(struct cpuinfo_mips *c)
{
decode_configs(c);
switch (c->processor_id & 0xff00) {
......@@ -787,7 +799,7 @@ static inline void cpu_probe_philips(struct cpuinfo_mips *c)
c->isa_level = MIPS_CPU_ISA_M32R1;
break;
default:
panic("Unknown Philips Core!"); /* REVISIT: die? */
panic("Unknown NXP Core!"); /* REVISIT: die? */
break;
}
}
......@@ -876,6 +888,7 @@ static __cpuinit const char *cpu_to_name(struct cpuinfo_mips *c)
case CPU_24K: name = "MIPS 24K"; break;
case CPU_25KF: name = "MIPS 25Kf"; break;
case CPU_34K: name = "MIPS 34K"; break;
case CPU_1004K: name = "MIPS 1004K"; break;
case CPU_74K: name = "MIPS 74K"; break;
case CPU_VR4111: name = "NEC VR4111"; break;
case CPU_VR4121: name = "NEC VR4121"; break;
......@@ -925,8 +938,8 @@ __cpuinit void cpu_probe(void)
case PRID_COMP_SANDCRAFT:
cpu_probe_sandcraft(c);
break;
case PRID_COMP_PHILIPS:
cpu_probe_philips(c);
case PRID_COMP_NXP:
cpu_probe_nxp(c);
break;
default:
c->cputype = CPU_UNKNOWN;
......
/*
* DEC I/O ASIC's counter clocksource
*
* Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clocksource.h>
#include <linux/init.h>
#include <asm/ds1287.h>
#include <asm/time.h>
#include <asm/dec/ioasic.h>
#include <asm/dec/ioasic_addrs.h>
static cycle_t dec_ioasic_hpt_read(void)
{
return ioasic_read(IO_REG_FCTR);
}
static struct clocksource clocksource_dec = {
.name = "dec-ioasic",
.read = dec_ioasic_hpt_read,
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
void __init dec_ioasic_clocksource_init(void)
{
unsigned int freq;
u32 start, end;
int i = HZ / 10;
while (!ds1287_timer_state())
;
start = dec_ioasic_hpt_read();
while (i--)
while (!ds1287_timer_state())
;
end = dec_ioasic_hpt_read();
freq = (end - start) * 10;
printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
clocksource_dec.rating = 200 + freq / 10000000;
clocksource_set_clock(&clocksource_dec, freq);
clocksource_register(&clocksource_dec);
}
/*
* A gpio chip driver for TXx9 SoCs
*
* Copyright (C) 2008 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/gpio.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <asm/txx9pio.h>
static DEFINE_SPINLOCK(txx9_gpio_lock);
static struct txx9_pio_reg __iomem *txx9_pioptr;
static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
return __raw_readl(&txx9_pioptr->din) & (1 << offset);
}
static void txx9_gpio_set_raw(unsigned int offset, int value)
{
u32 val;
val = __raw_readl(&txx9_pioptr->dout);
if (value)
val |= 1 << offset;
else
val &= ~(1 << offset);
__raw_writel(val, &txx9_pioptr->dout);
}
static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
int value)
{
unsigned long flags;
spin_lock_irqsave(&txx9_gpio_lock, flags);
txx9_gpio_set_raw(offset, value);
mmiowb();
spin_unlock_irqrestore(&txx9_gpio_lock, flags);
}
static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
{
spin_lock_irq(&txx9_gpio_lock);
__raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset),
&txx9_pioptr->dir);
mmiowb();
spin_unlock_irq(&txx9_gpio_lock);
return 0;
}
static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
int value)
{
spin_lock_irq(&txx9_gpio_lock);
txx9_gpio_set_raw(offset, value);
__raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset),
&txx9_pioptr->dir);
mmiowb();
spin_unlock_irq(&txx9_gpio_lock);
return 0;
}
static struct gpio_chip txx9_gpio_chip = {
.get = txx9_gpio_get,
.set = txx9_gpio_set,
.direction_input = txx9_gpio_dir_in,
.direction_output = txx9_gpio_dir_out,
.label = "TXx9",
};
int __init txx9_gpio_init(unsigned long baseaddr,
unsigned int base, unsigned int num)
{
txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg));
if (!txx9_pioptr)
return -ENODEV;
txx9_gpio_chip.base = base;
txx9_gpio_chip.ngpio = num;
return gpiochip_add(&txx9_gpio_chip);
}
#undef DEBUG
#include <linux/bitmap.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/gic.h>
#include <asm/gcmpregs.h>
#include <asm/mips-boards/maltaint.h>
#include <asm/irq.h>
#include <linux/hardirq.h>
#include <asm-generic/bitops/find.h>
static unsigned long _gic_base;
static unsigned int _irqbase, _mapsize, numvpes, numintrs;
static struct gic_intr_map *_intrmap;
static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
static struct gic_pending_regs pending_regs[NR_CPUS];
static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
#define gic_wedgeb2bok 0 /*
* Can GIC handle b2b writes to wedge register?
*/
#if gic_wedgeb2bok == 0
static DEFINE_SPINLOCK(gic_wedgeb2b_lock);
#endif
void gic_send_ipi(unsigned int intr)
{
#if gic_wedgeb2bok == 0
unsigned long flags;
#endif
pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
read_c0_status());
if (!gic_wedgeb2bok)
spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
if (!gic_wedgeb2bok) {
(void) GIC_REG(SHARED, GIC_SH_CONFIG);
spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
}
}
/* This is Malta specific and needs to be exported */
static void vpe_local_setup(unsigned int numvpes)
{
int i;
unsigned long timer_interrupt = 5, perf_interrupt = 5;
unsigned int vpe_ctl;
/*
* Setup the default performance counter timer interrupts
* for all VPEs
*/
for (i = 0; i < numvpes; i++) {
GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
/* Are Interrupts locally routable? */
GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
GIC_MAP_TO_PIN_MSK | timer_interrupt);
if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
GIC_MAP_TO_PIN_MSK | perf_interrupt);
}
}
unsigned int gic_get_int(void)
{
unsigned int i;
unsigned long *pending, *intrmask, *pcpu_mask;
unsigned long *pending_abs, *intrmask_abs;
/* Get per-cpu bitmaps */
pending = pending_regs[smp_processor_id()].pending;
intrmask = intrmask_regs[smp_processor_id()].intrmask;
pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
GIC_SH_PEND_31_0_OFS);
intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
GIC_SH_MASK_31_0_OFS);
for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) {
GICREAD(*pending_abs, pending[i]);
GICREAD(*intrmask_abs, intrmask[i]);
pending_abs++;
intrmask_abs++;
}
bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
i = find_first_bit(pending, GIC_NUM_INTRS);
pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i);
return i;
}
static unsigned int gic_irq_startup(unsigned int irq)
{
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
/* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))),
1 << (irq % 32));
return 0;
}
static void gic_irq_ack(unsigned int irq)
{
#if gic_wedgeb2bok == 0
unsigned long flags;
#endif
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))),
1 << (irq % 32));
if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) {
if (!gic_wedgeb2bok)
spin_lock_irqsave(&gic_wedgeb2b_lock, flags);
GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
if (!gic_wedgeb2bok) {
(void) GIC_REG(SHARED, GIC_SH_CONFIG);
spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags);
}
}
}
static void gic_mask_irq(unsigned int irq)
{
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
/* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))),
1 << (irq % 32));
}
static void gic_unmask_irq(unsigned int irq)
{
pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
irq -= _irqbase;
/* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */
GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))),
1 << (irq % 32));
}
#ifdef CONFIG_SMP
static DEFINE_SPINLOCK(gic_lock);
static void gic_set_affinity(unsigned int irq, cpumask_t cpumask)
{
cpumask_t tmp = CPU_MASK_NONE;
unsigned long flags;
int i;
pr_debug(KERN_DEBUG "%s called\n", __func__);
irq -= _irqbase;
cpus_and(tmp, cpumask, cpu_online_map);
if (cpus_empty(tmp))
return;
/* Assumption : cpumask refers to a single CPU */
spin_lock_irqsave(&gic_lock, flags);
for (;;) {
/* Re-route this IRQ */
GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
/*
* FIXME: assumption that _intrmap is ordered and has no holes
*/
/* Update the intr_map */
_intrmap[irq].cpunum = first_cpu(tmp);
/* Update the pcpu_masks */
for (i = 0; i < NR_CPUS; i++)
clear_bit(irq, pcpu_masks[i].pcpu_mask);
set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
}
irq_desc[irq].affinity = cpumask;
spin_unlock_irqrestore(&gic_lock, flags);
}
#endif
static struct irq_chip gic_irq_controller = {
.name = "MIPS GIC",
.startup = gic_irq_startup,
.ack = gic_irq_ack,
.mask = gic_mask_irq,
.mask_ack = gic_mask_irq,
.unmask = gic_unmask_irq,
.eoi = gic_unmask_irq,
#ifdef CONFIG_SMP
.set_affinity = gic_set_affinity,
#endif
};
static void __init setup_intr(unsigned int intr, unsigned int cpu,
unsigned int pin, unsigned int polarity, unsigned int trigtype)
{
/* Setup Intr to Pin mapping */
if (pin & GIC_MAP_TO_NMI_MSK) {
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
/* FIXME: hack to route NMI to all cpu's */
for (cpu = 0; cpu < NR_CPUS; cpu += 32) {
GICWRITE(GIC_REG_ADDR(SHARED,
GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)),
0xffffffff);
}
} else {
GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
GIC_MAP_TO_PIN_MSK | pin);
/* Setup Intr to CPU mapping */
GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
}
/* Setup Intr Polarity */
GIC_SET_POLARITY(intr, polarity);
/* Setup Intr Trigger Type */
GIC_SET_TRIGGER(intr, trigtype);
/* Init Intr Masks */
GIC_SET_INTR_MASK(intr, 0);
}
static void __init gic_basic_init(void)
{
unsigned int i, cpu;
/* Setup defaults */
for (i = 0; i < GIC_NUM_INTRS; i++) {
GIC_SET_POLARITY(i, GIC_POL_POS);
GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
GIC_SET_INTR_MASK(i, 0);
}
/* Setup specifics */
for (i = 0; i < _mapsize; i++) {
cpu = _intrmap[i].cpunum;
if (cpu == X)
continue;
setup_intr(_intrmap[i].intrnum,
_intrmap[i].cpunum,
_intrmap[i].pin,
_intrmap[i].polarity,
_intrmap[i].trigtype);
/* Initialise per-cpu Interrupt software masks */
if (_intrmap[i].ipiflag)
set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask);
}
vpe_local_setup(numvpes);
for (i = _irqbase; i < (_irqbase + numintrs); i++)
set_irq_chip(i, &gic_irq_controller);
}
void __init gic_init(unsigned long gic_base_addr,
unsigned long gic_addrspace_size,
struct gic_intr_map *intr_map, unsigned int intr_map_size,
unsigned int irqbase)
{
unsigned int gicconfig;
_gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
gic_addrspace_size);
_irqbase = irqbase;
_intrmap = intr_map;
_mapsize = intr_map_size;
GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
GIC_SH_CONFIG_NUMINTRS_SHF;
numintrs = ((numintrs + 1) * 8);
numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
GIC_SH_CONFIG_NUMVPES_SHF;
pr_debug("%s called\n", __func__);
gic_basic_init();
}
......@@ -17,6 +17,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/msc01_ic.h>
#include <asm/traps.h>
static unsigned long _icctrl_msc;
#define MSC01_IC_REG_BASE _icctrl_msc
......@@ -98,14 +99,13 @@ void ll_msc_irq(void)
}
}
void
msc_bind_eic_interrupt(unsigned int irq, unsigned int set)
static void msc_bind_eic_interrupt(int irq, int set)
{
MSCIC_WRITE(MSC01_IC_RAMW,
(irq<<MSC01_IC_RAMW_ADDR_SHF) | (set<<MSC01_IC_RAMW_DATA_SHF));
}
struct irq_chip msc_levelirq_type = {
static struct irq_chip msc_levelirq_type = {
.name = "SOC-it-Level",
.ack = level_mask_and_ack_msc_irq,
.mask = mask_msc_irq,
......@@ -115,7 +115,7 @@ struct irq_chip msc_levelirq_type = {
.end = end_msc_irq,
};
struct irq_chip msc_edgeirq_type = {
static struct irq_chip msc_edgeirq_type = {
.name = "SOC-it-Edge",
.ack = edge_mask_and_ack_msc_irq,
.mask = mask_msc_irq,
......@@ -128,8 +128,6 @@ struct irq_chip msc_edgeirq_type = {
void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqmap_t *imp, int nirq)
{
extern void (*board_bind_eic_interrupt)(unsigned int irq, unsigned int regset);
_icctrl_msc = (unsigned long) ioremap(icubase, 0x40000);
/* Reset interrupt controller - initialises all registers to 0 */
......
......@@ -14,7 +14,7 @@
/* #define DEBUG_SIG */
#ifdef DEBUG_SIG
# define DEBUGP(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
# define DEBUGP(fmt, args...) printk("%s: " fmt, __func__, ##args)
#else
# define DEBUGP(fmt, args...)
#endif
......
/*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Copyright (C) 2007 MIPS Technologies, Inc.
* Chris Dearman (chris@mips.com)
*/
#undef DEBUG
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/compiler.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/hardirq.h>
#include <asm/mmu_context.h>
#include <asm/smp.h>
#include <asm/time.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/mips_mt.h>
/*
* Crude manipulation of the CPU masks to control which
* which CPU's are brought online during initialisation
*
* Beware... this needs to be called after CPU discovery
* but before CPU bringup
*/
static int __init allowcpus(char *str)
{
cpumask_t cpu_allow_map;
char buf[256];
int len;
cpus_clear(cpu_allow_map);
if (cpulist_parse(str, cpu_allow_map) == 0) {
cpu_set(0, cpu_allow_map);
cpus_and(cpu_possible_map, cpu_possible_map, cpu_allow_map);
len = cpulist_scnprintf(buf, sizeof(buf)-1, cpu_possible_map);
buf[len] = '\0';
pr_debug("Allowable CPUs: %s\n", buf);
return 1;
} else
return 0;
}
__setup("allowcpus=", allowcpus);
static void ipi_call_function(unsigned int cpu)
{
unsigned int action = 0;
pr_debug("CPU%d: %s cpu %d status %08x\n",
smp_processor_id(), __func__, cpu, read_c0_status());
switch (cpu) {
case 0:
action = GIC_IPI_EXT_INTR_CALLFNC_VPE0;
break;
case 1:
action = GIC_IPI_EXT_INTR_CALLFNC_VPE1;
break;
case 2:
action = GIC_IPI_EXT_INTR_CALLFNC_VPE2;
break;
case 3:
action = GIC_IPI_EXT_INTR_CALLFNC_VPE3;
break;
}
gic_send_ipi(action);
}
static void ipi_resched(unsigned int cpu)
{
unsigned int action = 0;
pr_debug("CPU%d: %s cpu %d status %08x\n",
smp_processor_id(), __func__, cpu, read_c0_status());
switch (cpu) {
case 0:
action = GIC_IPI_EXT_INTR_RESCHED_VPE0;
break;
case 1:
action = GIC_IPI_EXT_INTR_RESCHED_VPE1;
break;
case 2:
action = GIC_IPI_EXT_INTR_RESCHED_VPE2;
break;
case 3:
action = GIC_IPI_EXT_INTR_RESCHED_VPE3;
break;
}
gic_send_ipi(action);
}
/*
* FIXME: This isn't restricted to CMP
* The SMVP kernel could use GIC interrupts if available
*/
void cmp_send_ipi_single(int cpu, unsigned int action)
{
unsigned long flags;
local_irq_save(flags);
switch (action) {
case SMP_CALL_FUNCTION:
ipi_call_function(cpu);
break;
case SMP_RESCHEDULE_YOURSELF:
ipi_resched(cpu);
break;
}
local_irq_restore(flags);
}
static void cmp_send_ipi_mask(cpumask_t mask, unsigned int action)
{
unsigned int i;
for_each_cpu_mask(i, mask)
cmp_send_ipi_single(i, action);
}
static void cmp_init_secondary(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
/* Assume GIC is present */
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP6 |
STATUSF_IP7);
/* Enable per-cpu interrupts: platform specific */
c->core = (read_c0_ebase() >> 1) & 0xff;
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
#endif
#ifdef CONFIG_MIPS_MT_SMTC
c->tc_id = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
#endif
}
static void cmp_smp_finish(void)
{
pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
/* CDFIXME: remove this? */
write_c0_compare(read_c0_count() + (8 * mips_hpt_frequency / HZ));
#ifdef CONFIG_MIPS_MT_FPAFF
/* If we have an FPU, enroll ourselves in the FPU-full mask */
if (cpu_has_fpu)
cpu_set(smp_processor_id(), mt_fpu_cpumask);
#endif /* CONFIG_MIPS_MT_FPAFF */
local_irq_enable();
}
static void cmp_cpus_done(void)
{
pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
}
/*
* Setup the PC, SP, and GP of a secondary processor and start it running
* smp_bootstrap is the place to resume from
* __KSTK_TOS(idle) is apparently the stack pointer
* (unsigned long)idle->thread_info the gp
*/
static void cmp_boot_secondary(int cpu, struct task_struct *idle)
{
struct thread_info *gp = task_thread_info(idle);
unsigned long sp = __KSTK_TOS(idle);
unsigned long pc = (unsigned long)&smp_bootstrap;
unsigned long a0 = 0;
pr_debug("SMPCMP: CPU%d: %s cpu %d\n", smp_processor_id(),
__func__, cpu);
#if 0
/* Needed? */
flush_icache_range((unsigned long)gp,
(unsigned long)(gp + sizeof(struct thread_info)));
#endif
amon_cpu_start(cpu, pc, sp, gp, a0);
}
/*
* Common setup before any secondaries are started
*/
void __init cmp_smp_setup(void)
{
int i;
int ncpu = 0;
pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
#ifdef CONFIG_MIPS_MT_FPAFF
/* If we have an FPU, enroll ourselves in the FPU-full mask */
if (cpu_has_fpu)
cpu_set(0, mt_fpu_cpumask);
#endif /* CONFIG_MIPS_MT_FPAFF */
for (i = 1; i < NR_CPUS; i++) {
if (amon_cpu_avail(i)) {
cpu_set(i, phys_cpu_present_map);
__cpu_number_map[i] = ++ncpu;
__cpu_logical_map[ncpu] = i;
}
}
if (cpu_has_mipsmt) {
unsigned int nvpe, mvpconf0 = read_c0_mvpconf0();
nvpe = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
smp_num_siblings = nvpe;
}
pr_info("Detected %i available secondary CPU(s)\n", ncpu);
}
void __init cmp_prepare_cpus(unsigned int max_cpus)
{
pr_debug("SMPCMP: CPU%d: %s max_cpus=%d\n",
smp_processor_id(), __func__, max_cpus);
/*
* FIXME: some of these options are per-system, some per-core and
* some per-cpu
*/
mips_mt_set_cpuoptions();
}
struct plat_smp_ops cmp_smp_ops = {
.send_ipi_single = cmp_send_ipi_single,
.send_ipi_mask = cmp_send_ipi_mask,
.init_secondary = cmp_init_secondary,
.smp_finish = cmp_smp_finish,
.cpus_done = cmp_cpus_done,
.boot_secondary = cmp_boot_secondary,
.smp_setup = cmp_smp_setup,
.prepare_cpus = cmp_prepare_cpus,
};
......@@ -36,110 +36,7 @@
#include <asm/mipsmtregs.h>
#include <asm/mips_mt.h>
#define MIPS_CPU_IPI_RESCHED_IRQ 0
#define MIPS_CPU_IPI_CALL_IRQ 1
static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
#if 0
static void dump_mtregisters(int vpe, int tc)
{
printk("vpe %d tc %d\n", vpe, tc);
settc(tc);
printk(" c0 status 0x%lx\n", read_vpe_c0_status());
printk(" vpecontrol 0x%lx\n", read_vpe_c0_vpecontrol());
printk(" vpeconf0 0x%lx\n", read_vpe_c0_vpeconf0());
printk(" tcstatus 0x%lx\n", read_tc_c0_tcstatus());
printk(" tcrestart 0x%lx\n", read_tc_c0_tcrestart());
printk(" tcbind 0x%lx\n", read_tc_c0_tcbind());
printk(" tchalt 0x%lx\n", read_tc_c0_tchalt());
}
#endif
void __init sanitize_tlb_entries(void)
{
int i, tlbsiz;
unsigned long mvpconf0, ncpu;
if (!cpu_has_mipsmt)
return;
/* Enable VPC */
set_c0_mvpcontrol(MVPCONTROL_VPC);
back_to_back_c0_hazard();
/* Disable TLB sharing */
clear_c0_mvpcontrol(MVPCONTROL_STLB);
mvpconf0 = read_c0_mvpconf0();
printk(KERN_INFO "MVPConf0 0x%lx TLBS %lx PTLBE %ld\n", mvpconf0,
(mvpconf0 & MVPCONF0_TLBS) >> MVPCONF0_TLBS_SHIFT,
(mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT);
tlbsiz = (mvpconf0 & MVPCONF0_PTLBE) >> MVPCONF0_PTLBE_SHIFT;
ncpu = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
printk(" tlbsiz %d ncpu %ld\n", tlbsiz, ncpu);
if (tlbsiz > 0) {
/* share them out across the vpe's */
tlbsiz /= ncpu;
printk(KERN_INFO "setting Config1.MMU_size to %d\n", tlbsiz);
for (i = 0; i < ncpu; i++) {
settc(i);
if (i == 0)
write_c0_config1((read_c0_config1() & ~(0x3f << 25)) | (tlbsiz << 25));
else
write_vpe_c0_config1((read_vpe_c0_config1() & ~(0x3f << 25)) |
(tlbsiz << 25));
}
}
clear_c0_mvpcontrol(MVPCONTROL_VPC);
}
static void ipi_resched_dispatch(void)
{
do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
}
static void ipi_call_dispatch(void)
{
do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
}
static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
{
return IRQ_HANDLED;
}
static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
{
smp_call_function_interrupt();
return IRQ_HANDLED;
}
static struct irqaction irq_resched = {
.handler = ipi_resched_interrupt,
.flags = IRQF_DISABLED|IRQF_PERCPU,
.name = "IPI_resched"
};
static struct irqaction irq_call = {
.handler = ipi_call_interrupt,
.flags = IRQF_DISABLED|IRQF_PERCPU,
.name = "IPI_call"
};
static void __init smp_copy_vpe_config(void)
static void __init smvp_copy_vpe_config(void)
{
write_vpe_c0_status(
(read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
......@@ -156,7 +53,7 @@ static void __init smp_copy_vpe_config(void)
write_vpe_c0_count(read_c0_count());
}
static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
unsigned int ncpu)
{
if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
......@@ -182,12 +79,12 @@ static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
if (tc != 0)
smp_copy_vpe_config();
smvp_copy_vpe_config();
return ncpu;
}
static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0)
static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
{
unsigned long tmp;
......@@ -254,15 +151,20 @@ static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
static void __cpuinit vsmp_init_secondary(void)
{
/* Enable per-cpu interrupts */
extern int gic_present;
/* This is Malta specific: IPI,performance and timer inetrrupts */
write_c0_status((read_c0_status() & ~ST0_IM ) |
(STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
if (gic_present)
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
STATUSF_IP6 | STATUSF_IP7);
else
change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
STATUSF_IP6 | STATUSF_IP7);
}
static void __cpuinit vsmp_smp_finish(void)
{
/* CDFIXME: remove this? */
write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
#ifdef CONFIG_MIPS_MT_FPAFF
......@@ -323,7 +225,7 @@ static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
/*
* Common setup before any secondaries are started
* Make sure all CPU's are in a sensible state before we boot any of the
* secondarys
* secondaries
*/
static void __init vsmp_smp_setup(void)
{
......@@ -356,8 +258,8 @@ static void __init vsmp_smp_setup(void)
for (tc = 0; tc <= ntc; tc++) {
settc(tc);
smp_tc_init(tc, mvpconf0);
ncpu = smp_vpe_init(tc, mvpconf0, ncpu);
smvp_tc_init(tc, mvpconf0);
ncpu = smvp_vpe_init(tc, mvpconf0, ncpu);
}
/* Release config state */
......@@ -371,21 +273,6 @@ static void __init vsmp_smp_setup(void)
static void __init vsmp_prepare_cpus(unsigned int max_cpus)
{
mips_mt_set_cpuoptions();
/* set up ipi interrupts */
if (cpu_has_vint) {
set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
}
cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
setup_irq(cpu_ipi_resched_irq, &irq_resched);
setup_irq(cpu_ipi_call_irq, &irq_call);
set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
}
struct plat_smp_ops vsmp_smp_ops = {
......
......@@ -35,6 +35,7 @@
#include <asm/atomic.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/r4k-timer.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/time.h>
......@@ -125,6 +126,8 @@ asmlinkage __cpuinit void start_secondary(void)
cpu_set(cpu, cpu_callin_map);
synchronise_count_slave();
cpu_idle();
}
......@@ -287,6 +290,7 @@ void smp_send_stop(void)
void __init smp_cpus_done(unsigned int max_cpus)
{
mp_ops->cpus_done();
synchronise_count_master();
}
/* called from main before smp_init() */
......
......@@ -174,14 +174,6 @@ static int clock_hang_reported[NR_CPUS];
#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
/* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */
void __init sanitize_tlb_entries(void)
{
printk("Deprecated sanitize_tlb_entries() invoked\n");
}
/*
* Configure shared TLB - VPC configuration bit must be set by caller
*/
......@@ -339,7 +331,8 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
/* In general, all TCs should have the same cpu_data indications */
memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
/* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */
if (cpu_data[0].cputype == CPU_34K)
if (cpu_data[0].cputype == CPU_34K ||
cpu_data[0].cputype == CPU_1004K)
cpu_data[cpu].options &= ~MIPS_CPU_FPU;
cpu_data[cpu].vpe_id = vpe;
cpu_data[cpu].tc_id = tc;
......
/*
* MIPS SPRAM support
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Copyright (C) 2007, 2008 MIPS Technologies, Inc.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/stddef.h>
#include <asm/cpu.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/r4kcache.h>
#include <asm/hazards.h>
/*
* These definitions are correct for the 24K/34K/74K SPRAM sample
* implementation. The 4KS interpreted the tags differently...
*/
#define SPRAM_TAG0_ENABLE 0x00000080
#define SPRAM_TAG0_PA_MASK 0xfffff000
#define SPRAM_TAG1_SIZE_MASK 0xfffff000
#define SPRAM_TAG_STRIDE 8
#define ERRCTL_SPRAM (1 << 28)
/* errctl access */
#define read_c0_errctl(x) read_c0_ecc(x)
#define write_c0_errctl(x) write_c0_ecc(x)
/*
* Different semantics to the set_c0_* function built by __BUILD_SET_C0
*/
static __cpuinit unsigned int bis_c0_errctl(unsigned int set)
{
unsigned int res;
res = read_c0_errctl();
write_c0_errctl(res | set);
return res;
}
static __cpuinit void ispram_store_tag(unsigned int offset, unsigned int data)
{
unsigned int errctl;
/* enable SPRAM tag access */
errctl = bis_c0_errctl(ERRCTL_SPRAM);
ehb();
write_c0_taglo(data);
ehb();
cache_op(Index_Store_Tag_I, CKSEG0|offset);
ehb();
write_c0_errctl(errctl);
ehb();
}
static __cpuinit unsigned int ispram_load_tag(unsigned int offset)
{
unsigned int data;
unsigned int errctl;
/* enable SPRAM tag access */
errctl = bis_c0_errctl(ERRCTL_SPRAM);
ehb();
cache_op(Index_Load_Tag_I, CKSEG0 | offset);
ehb();
data = read_c0_taglo();
ehb();
write_c0_errctl(errctl);
ehb();
return data;
}
static __cpuinit void dspram_store_tag(unsigned int offset, unsigned int data)
{
unsigned int errctl;
/* enable SPRAM tag access */
errctl = bis_c0_errctl(ERRCTL_SPRAM);
ehb();
write_c0_dtaglo(data);
ehb();
cache_op(Index_Store_Tag_D, CKSEG0 | offset);
ehb();
write_c0_errctl(errctl);
ehb();
}
static __cpuinit unsigned int dspram_load_tag(unsigned int offset)
{
unsigned int data;
unsigned int errctl;
errctl = bis_c0_errctl(ERRCTL_SPRAM);
ehb();
cache_op(Index_Load_Tag_D, CKSEG0 | offset);
ehb();
data = read_c0_dtaglo();
ehb();
write_c0_errctl(errctl);
ehb();
return data;
}
static __cpuinit void probe_spram(char *type,
unsigned int base,
unsigned int (*read)(unsigned int),
void (*write)(unsigned int, unsigned int))
{
unsigned int firstsize = 0, lastsize = 0;
unsigned int firstpa = 0, lastpa = 0, pa = 0;
unsigned int offset = 0;
unsigned int size, tag0, tag1;
unsigned int enabled;
int i;
/*
* The limit is arbitrary but avoids the loop running away if
* the SPRAM tags are implemented differently
*/
for (i = 0; i < 8; i++) {
tag0 = read(offset);
tag1 = read(offset+SPRAM_TAG_STRIDE);
pr_debug("DBG %s%d: tag0=%08x tag1=%08x\n",
type, i, tag0, tag1);
size = tag1 & SPRAM_TAG1_SIZE_MASK;
if (size == 0)
break;
if (i != 0) {
/* tags may repeat... */
if ((pa == firstpa && size == firstsize) ||
(pa == lastpa && size == lastsize))
break;
}
/* Align base with size */
base = (base + size - 1) & ~(size-1);
/* reprogram the base address base address and enable */
tag0 = (base & SPRAM_TAG0_PA_MASK) | SPRAM_TAG0_ENABLE;
write(offset, tag0);
base += size;
/* reread the tag */
tag0 = read(offset);
pa = tag0 & SPRAM_TAG0_PA_MASK;
enabled = tag0 & SPRAM_TAG0_ENABLE;
if (i == 0) {
firstpa = pa;
firstsize = size;
}
lastpa = pa;
lastsize = size;
if (strcmp(type, "DSPRAM") == 0) {
unsigned int *vp = (unsigned int *)(CKSEG1 | pa);
unsigned int v;
#define TDAT 0x5a5aa5a5
vp[0] = TDAT;
vp[1] = ~TDAT;
mb();
v = vp[0];
if (v != TDAT)
printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
vp, TDAT, v);
v = vp[1];
if (v != ~TDAT)
printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
vp+1, ~TDAT, v);
}
pr_info("%s%d: PA=%08x,Size=%08x%s\n",
type, i, pa, size, enabled ? ",enabled" : "");
offset += 2 * SPRAM_TAG_STRIDE;
}
}
__cpuinit void spram_config(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
unsigned int config0;
switch (c->cputype) {
case CPU_24K:
case CPU_34K:
case CPU_74K:
config0 = read_c0_config();
/* FIXME: addresses are Malta specific */
if (config0 & (1<<24)) {
probe_spram("ISPRAM", 0x1c000000,
&ispram_load_tag, &ispram_store_tag);
}
if (config0 & (1<<23))
probe_spram("DSPRAM", 0x1c100000,
&dspram_load_tag, &dspram_store_tag);
}
}
/*
* Count register synchronisation.
*
* All CPUs will have their count registers synchronised to the CPU0 expirelo
* value. This can cause a small timewarp for CPU0. All other CPU's should
* not have done anything significant (but they may have had interrupts
* enabled briefly - prom_smp_finish() should not be responsible for enabling
* interrupts...)
*
* FIXME: broken for SMTC
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irqflags.h>
#include <linux/r4k-timer.h>
#include <asm/atomic.h>
#include <asm/barrier.h>
#include <asm/cpumask.h>
#include <asm/mipsregs.h>
static atomic_t __initdata count_start_flag = ATOMIC_INIT(0);
static atomic_t __initdata count_count_start = ATOMIC_INIT(0);
static atomic_t __initdata count_count_stop = ATOMIC_INIT(0);
#define COUNTON 100
#define NR_LOOPS 5
void __init synchronise_count_master(void)
{
int i;
unsigned long flags;
unsigned int initcount;
int nslaves;
#ifdef CONFIG_MIPS_MT_SMTC
/*
* SMTC needs to synchronise per VPE, not per CPU
* ignore for now
*/
return;
#endif
pr_info("Checking COUNT synchronization across %u CPUs: ",
num_online_cpus());
local_irq_save(flags);
/*
* Notify the slaves that it's time to start
*/
atomic_set(&count_start_flag, 1);
smp_wmb();
/* Count will be initialised to expirelo for all CPU's */
initcount = expirelo;
/*
* We loop a few times to get a primed instruction cache,
* then the last pass is more or less synchronised and
* the master and slaves each set their cycle counters to a known
* value all at once. This reduces the chance of having random offsets
* between the processors, and guarantees that the maximum
* delay between the cycle counters is never bigger than
* the latency of information-passing (cachelines) between
* two CPUs.
*/
nslaves = num_online_cpus()-1;
for (i = 0; i < NR_LOOPS; i++) {
/* slaves loop on '!= ncpus' */
while (atomic_read(&count_count_start) != nslaves)
mb();
atomic_set(&count_count_stop, 0);
smp_wmb();
/* this lets the slaves write their count register */
atomic_inc(&count_count_start);
/*
* Everyone initialises count in the last loop:
*/
if (i == NR_LOOPS-1)
write_c0_count(initcount);
/*
* Wait for all slaves to leave the synchronization point:
*/
while (atomic_read(&count_count_stop) != nslaves)
mb();
atomic_set(&count_count_start, 0);
smp_wmb();
atomic_inc(&count_count_stop);
}
/* Arrange for an interrupt in a short while */
write_c0_compare(read_c0_count() + COUNTON);
local_irq_restore(flags);
/*
* i386 code reported the skew here, but the
* count registers were almost certainly out of sync
* so no point in alarming people
*/
printk("done.\n");
}
void __init synchronise_count_slave(void)
{
int i;
unsigned long flags;
unsigned int initcount;
int ncpus;
#ifdef CONFIG_MIPS_MT_SMTC
/*
* SMTC needs to synchronise per VPE, not per CPU
* ignore for now
*/
return;
#endif
local_irq_save(flags);
/*
* Not every cpu is online at the time this gets called,
* so we first wait for the master to say everyone is ready
*/
while (!atomic_read(&count_start_flag))
mb();
/* Count will be initialised to expirelo for all CPU's */
initcount = expirelo;
ncpus = num_online_cpus();
for (i = 0; i < NR_LOOPS; i++) {
atomic_inc(&count_count_start);
while (atomic_read(&count_count_start) != ncpus)
mb();
/*
* Everyone initialises count in the last loop:
*/
if (i == NR_LOOPS-1)
write_c0_count(initcount);
atomic_inc(&count_count_stop);
while (atomic_read(&count_count_stop) != ncpus)
mb();
}
/* Arrange for an interrupt in a short while */
write_c0_compare(read_c0_count() + COUNTON);
local_irq_restore(flags);
}
#undef NR_LOOPS
#endif
......@@ -38,7 +38,6 @@ int __weak rtc_mips_set_time(unsigned long sec)
{
return 0;
}
EXPORT_SYMBOL(rtc_mips_set_time);
int __weak rtc_mips_set_mmss(unsigned long nowtime)
{
......@@ -50,13 +49,11 @@ int update_persistent_clock(struct timespec now)
return rtc_mips_set_mmss(now.tv_sec);
}
int null_perf_irq(void)
static int null_perf_irq(void)
{
return 0;
}
EXPORT_SYMBOL(null_perf_irq);
int (*perf_irq)(void) = null_perf_irq;
EXPORT_SYMBOL(perf_irq);
......
......@@ -22,6 +22,7 @@
#include <linux/kallsyms.h>
#include <linux/bootmem.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/bootinfo.h>
#include <asm/branch.h>
......@@ -80,19 +81,22 @@ void (*board_bind_eic_interrupt)(int irq, int regset);
static void show_raw_backtrace(unsigned long reg29)
{
unsigned long *sp = (unsigned long *)reg29;
unsigned long *sp = (unsigned long *)(reg29 & ~3);
unsigned long addr;
printk("Call Trace:");
#ifdef CONFIG_KALLSYMS
printk("\n");
#endif
while (!kstack_end(sp)) {
addr = *sp++;
if (__kernel_text_address(addr))
print_ip_sym(addr);
#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000)
if (IS_KVA01(sp)) {
while (!kstack_end(sp)) {
addr = *sp++;
if (__kernel_text_address(addr))
print_ip_sym(addr);
}
printk("\n");
}
printk("\n");
}
#ifdef CONFIG_KALLSYMS
......@@ -192,16 +196,19 @@ EXPORT_SYMBOL(dump_stack);
static void show_code(unsigned int __user *pc)
{
long i;
unsigned short __user *pc16 = NULL;
printk("\nCode:");
if ((unsigned long)pc & 1)
pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
for(i = -3 ; i < 6 ; i++) {
unsigned int insn;
if (__get_user(insn, pc + i)) {
if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
printk(" (Bad address in epc)\n");
break;
}
printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>'));
printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>'));
}
}
......@@ -311,10 +318,21 @@ void show_regs(struct pt_regs *regs)
void show_registers(const struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
__show_regs(regs);
print_modules();
printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
current->comm, task_pid_nr(current), current_thread_info(), current);
printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
current->comm, current->pid, current_thread_info(), current,
field, current_thread_info()->tp_value);
if (cpu_has_userlocal) {
unsigned long tls;
tls = read_c0_userlocal();
if (tls != current_thread_info()->tp_value)
printk("*HwTLS: %0*lx\n", field, tls);
}
show_stacktrace(current, regs);
show_code((unsigned int __user *) regs->cp0_epc);
printk("\n");
......@@ -657,35 +675,24 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
force_sig_info(SIGFPE, &info, current);
}
asmlinkage void do_bp(struct pt_regs *regs)
static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
const char *str)
{
unsigned int opcode, bcode;
siginfo_t info;
if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
goto out_sigsegv;
/*
* There is the ancient bug in the MIPS assemblers that the break
* code starts left to bit 16 instead to bit 6 in the opcode.
* Gas is bug-compatible, but not always, grrr...
* We handle both cases with a simple heuristics. --macro
*/
bcode = ((opcode >> 6) & ((1 << 20) - 1));
if (bcode < (1 << 10))
bcode <<= 10;
char b[40];
/*
* (A short test says that IRIX 5.3 sends SIGTRAP for all break
* insns, even for break codes that indicate arithmetic failures.
* Weird ...)
* A short test says that IRIX 5.3 sends SIGTRAP for all trap
* insns, even for trap and break codes that indicate arithmetic
* failures. Weird ...
* But should we continue the brokenness??? --macro
*/
switch (bcode) {
case BRK_OVERFLOW << 10:
case BRK_DIVZERO << 10:
die_if_kernel("Break instruction in kernel code", regs);
if (bcode == (BRK_DIVZERO << 10))
switch (code) {
case BRK_OVERFLOW:
case BRK_DIVZERO:
scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
die_if_kernel(b, regs);
if (code == BRK_DIVZERO)
info.si_code = FPE_INTDIV;
else
info.si_code = FPE_INTOVF;
......@@ -695,12 +702,34 @@ asmlinkage void do_bp(struct pt_regs *regs)
force_sig_info(SIGFPE, &info, current);
break;
case BRK_BUG:
die("Kernel bug detected", regs);
die_if_kernel("Kernel bug detected", regs);
force_sig(SIGTRAP, current);
break;
default:
die_if_kernel("Break instruction in kernel code", regs);
scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
die_if_kernel(b, regs);
force_sig(SIGTRAP, current);
}
}
asmlinkage void do_bp(struct pt_regs *regs)
{
unsigned int opcode, bcode;
if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
goto out_sigsegv;
/*
* There is the ancient bug in the MIPS assemblers that the break
* code starts left to bit 16 instead to bit 6 in the opcode.
* Gas is bug-compatible, but not always, grrr...
* We handle both cases with a simple heuristics. --macro
*/
bcode = ((opcode >> 6) & ((1 << 20) - 1));
if (bcode >= (1 << 10))
bcode >>= 10;
do_trap_or_bp(regs, bcode, "Break");
return;
out_sigsegv:
......@@ -710,7 +739,6 @@ asmlinkage void do_bp(struct pt_regs *regs)
asmlinkage void do_tr(struct pt_regs *regs)
{
unsigned int opcode, tcode = 0;
siginfo_t info;
if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
goto out_sigsegv;
......@@ -719,32 +747,7 @@ asmlinkage void do_tr(struct pt_regs *regs)
if (!(opcode & OPCODE))
tcode = ((opcode >> 6) & ((1 << 10) - 1));
/*
* (A short test says that IRIX 5.3 sends SIGTRAP for all trap
* insns, even for trap codes that indicate arithmetic failures.
* Weird ...)
* But should we continue the brokenness??? --macro
*/
switch (tcode) {
case BRK_OVERFLOW:
case BRK_DIVZERO:
die_if_kernel("Trap instruction in kernel code", regs);
if (tcode == BRK_DIVZERO)
info.si_code = FPE_INTDIV;
else
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;
case BRK_BUG:
die("Kernel bug detected", regs);
break;
default:
die_if_kernel("Trap instruction in kernel code", regs);
force_sig(SIGTRAP, current);
}
do_trap_or_bp(regs, tcode, "Trap");
return;
out_sigsegv:
......@@ -985,6 +988,21 @@ asmlinkage void do_reserved(struct pt_regs *regs)
(regs->cp0_cause & 0x7f) >> 2);
}
static int __initdata l1parity = 1;
static int __init nol1parity(char *s)
{
l1parity = 0;
return 1;
}
__setup("nol1par", nol1parity);
static int __initdata l2parity = 1;
static int __init nol2parity(char *s)
{
l2parity = 0;
return 1;
}
__setup("nol2par", nol2parity);
/*
* Some MIPS CPUs can enable/disable for cache parity detection, but do
* it different ways.
......@@ -994,6 +1012,62 @@ static inline void parity_protection_init(void)
switch (current_cpu_type()) {
case CPU_24K:
case CPU_34K:
case CPU_74K:
case CPU_1004K:
{
#define ERRCTL_PE 0x80000000
#define ERRCTL_L2P 0x00800000
unsigned long errctl;
unsigned int l1parity_present, l2parity_present;
errctl = read_c0_ecc();
errctl &= ~(ERRCTL_PE|ERRCTL_L2P);
/* probe L1 parity support */
write_c0_ecc(errctl | ERRCTL_PE);
back_to_back_c0_hazard();
l1parity_present = (read_c0_ecc() & ERRCTL_PE);
/* probe L2 parity support */
write_c0_ecc(errctl|ERRCTL_L2P);
back_to_back_c0_hazard();
l2parity_present = (read_c0_ecc() & ERRCTL_L2P);
if (l1parity_present && l2parity_present) {
if (l1parity)
errctl |= ERRCTL_PE;
if (l1parity ^ l2parity)
errctl |= ERRCTL_L2P;
} else if (l1parity_present) {
if (l1parity)
errctl |= ERRCTL_PE;
} else if (l2parity_present) {
if (l2parity)
errctl |= ERRCTL_L2P;
} else {
/* No parity available */
}
printk(KERN_INFO "Writing ErrCtl register=%08lx\n", errctl);
write_c0_ecc(errctl);
back_to_back_c0_hazard();
errctl = read_c0_ecc();
printk(KERN_INFO "Readback ErrCtl register=%08lx\n", errctl);
if (l1parity_present)
printk(KERN_INFO "Cache parity protection %sabled\n",
(errctl & ERRCTL_PE) ? "en" : "dis");
if (l2parity_present) {
if (l1parity_present && l1parity)
errctl ^= ERRCTL_L2P;
printk(KERN_INFO "L2 cache parity protection %sabled\n",
(errctl & ERRCTL_L2P) ? "en" : "dis");
}
}
break;
case CPU_5KC:
write_c0_ecc(0x80000000);
back_to_back_c0_hazard();
......@@ -1306,6 +1380,17 @@ int cp0_compare_irq;
int cp0_perfcount_irq;
EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
static int __cpuinitdata noulri;
static int __init ulri_disable(char *s)
{
pr_info("Disabling ulri\n");
noulri = 1;
return 1;
}
__setup("noulri", ulri_disable);
void __cpuinit per_cpu_trap_init(void)
{
unsigned int cpu = smp_processor_id();
......@@ -1342,16 +1427,14 @@ void __cpuinit per_cpu_trap_init(void)
change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
status_set);
#ifdef CONFIG_CPU_MIPSR2
if (cpu_has_mips_r2) {
unsigned int enable = 0x0000000f;
if (cpu_has_userlocal)
if (!noulri && cpu_has_userlocal)
enable |= (1 << 29);
write_c0_hwrena(enable);
}
#endif
#ifdef CONFIG_MIPS_MT_SMTC
if (!secondaryTC) {
......
......@@ -46,7 +46,7 @@
#define DPDNORMX DPDNORMx(xm, xe)
#define DPDNORMY DPDNORMx(ym, ye)
static __inline ieee754dp builddp(int s, int bx, u64 m)
static inline ieee754dp builddp(int s, int bx, u64 m)
{
ieee754dp r;
......
......@@ -51,7 +51,7 @@
#define SPDNORMX SPDNORMx(xm, xe)
#define SPDNORMY SPDNORMx(ym, ye)
static __inline ieee754sp buildsp(int s, int bx, unsigned m)
static inline ieee754sp buildsp(int s, int bx, unsigned m)
{
ieee754sp r;
......
......@@ -20,6 +20,7 @@
obj-y := reset.o display.o init.o memory.o \
cmdline.o time.o
obj-y += amon.o
obj-$(CONFIG_EARLY_PRINTK) += console.o
obj-$(CONFIG_PCI) += pci.o
......
/*
* Copyright (C) 2007 MIPS Technologies, Inc.
* All rights reserved.
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Arbitrary Monitor interface
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <asm-mips/addrspace.h>
#include <asm-mips/mips-boards/launch.h>
#include <asm-mips/mipsmtregs.h>
int amon_cpu_avail(int cpu)
{
struct cpulaunch *launch = (struct cpulaunch *)KSEG0ADDR(CPULAUNCH);
if (cpu < 0 || cpu >= NCPULAUNCH) {
pr_debug("avail: cpu%d is out of range\n", cpu);
return 0;
}
launch += cpu;
if (!(launch->flags & LAUNCH_FREADY)) {
pr_debug("avail: cpu%d is not ready\n", cpu);
return 0;
}
if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) {
pr_debug("avail: too late.. cpu%d is already gone\n", cpu);
return 0;
}
return 1;
}
void amon_cpu_start(int cpu,
unsigned long pc, unsigned long sp,
unsigned long gp, unsigned long a0)
{
volatile struct cpulaunch *launch =
(struct cpulaunch *)KSEG0ADDR(CPULAUNCH);
if (!amon_cpu_avail(cpu))
return;
if (cpu == smp_processor_id()) {
pr_debug("launch: I am cpu%d!\n", cpu);
return;
}
launch += cpu;
pr_debug("launch: starting cpu%d\n", cpu);
launch->pc = pc;
launch->gp = gp;
launch->sp = sp;
launch->a0 = a0;
/* Make sure target sees parameters before the go bit */
smp_mb();
launch->flags |= LAUNCH_FGO;
while ((launch->flags & LAUNCH_FGONE) == 0)
;
pr_debug("launch: cpu%d gone!\n", cpu);
}
......@@ -226,7 +226,7 @@ void __init kgdb_config(void)
}
#endif
void __init mips_nmi_setup(void)
static void __init mips_nmi_setup(void)
{
void *base;
extern char except_vec_nmi;
......@@ -238,7 +238,7 @@ void __init mips_nmi_setup(void)
flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
}
void __init mips_ejtag_setup(void)
static void __init mips_ejtag_setup(void)
{
void *base;
extern char except_vec_ejtag_debug;
......@@ -295,15 +295,21 @@ void __init prom_init(void)
break;
case MIPS_REVISION_CORID_CORE_MSC:
case MIPS_REVISION_CORID_CORE_FPGA2:
case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_FPGA4:
case MIPS_REVISION_CORID_CORE_24K:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
/*
* SOCit/ROCit support is essentially identical
* but make an attempt to distinguish them
*/
mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
break;
case MIPS_REVISION_CORID_CORE_FPGA3:
case MIPS_REVISION_CORID_CORE_FPGA4:
case MIPS_REVISION_CORID_CORE_FPGA5:
case MIPS_REVISION_CORID_CORE_EMUL_MSC:
default:
mips_display_message("CC Error");
while (1); /* We die here... */
/* See above */
mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
break;
}
}
......@@ -418,6 +424,9 @@ void __init prom_init(void)
#ifdef CONFIG_SERIAL_8250_CONSOLE
console_config();
#endif
#ifdef CONFIG_MIPS_CMP
register_smp_ops(&cmp_smp_ops);
#endif
#ifdef CONFIG_MIPS_MT_SMP
register_smp_ops(&vsmp_smp_ops);
#endif
......
......@@ -37,7 +37,7 @@ enum yamon_memtypes {
yamon_prom,
yamon_free,
};
struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
#ifdef DEBUG
static char *mtypes[3] = {
......@@ -50,7 +50,7 @@ static char *mtypes[3] = {
/* determined physical memory size, not overridden by command line args */
unsigned long physical_memsize = 0L;
struct prom_pmemblock * __init prom_getmdesc(void)
static struct prom_pmemblock * __init prom_getmdesc(void)
{
char *memsize_str;
unsigned int memsize;
......
......@@ -55,16 +55,36 @@
unsigned long cpu_khz;
static int mips_cpu_timer_irq;
static int mips_cpu_perf_irq;
extern int cp0_perfcount_irq;
DEFINE_PER_CPU(unsigned int, tickcount);
#define tickcount_this_cpu __get_cpu_var(tickcount)
static unsigned long ledbitmask;
static void mips_timer_dispatch(void)
{
#if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_ATLAS)
/*
* Yes, this is very tacky, won't work as expected with SMTC and
* dyntick will break it,
* but it gives me a nice warm feeling during debug
*/
#define LEDBAR 0xbf000408
if (tickcount_this_cpu++ >= HZ) {
tickcount_this_cpu = 0;
change_bit(smp_processor_id(), &ledbitmask);
smp_wmb(); /* Make sure every one else sees the change */
/* This will pick up any recent changes made by other CPU's */
*(unsigned int *)LEDBAR = ledbitmask;
}
#endif
do_IRQ(mips_cpu_timer_irq);
}
static void mips_perf_dispatch(void)
{
do_IRQ(cp0_perfcount_irq);
do_IRQ(mips_cpu_perf_irq);
}
/*
......@@ -127,21 +147,20 @@ unsigned long read_persistent_clock(void)
return mc146818_get_cmos_time();
}
void __init plat_perf_setup(void)
static void __init plat_perf_setup(void)
{
cp0_perfcount_irq = -1;
#ifdef MSC01E_INT_BASE
if (cpu_has_veic) {
set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
cp0_perfcount_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
} else
#endif
if (cp0_perfcount_irq >= 0) {
if (cpu_has_vint)
set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
#ifdef CONFIG_SMP
set_irq_handler(cp0_perfcount_irq, handle_percpu_irq);
set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq);
#endif
}
}
......
......@@ -22,6 +22,7 @@
obj-y := malta_int.o malta_platform.o malta_setup.o
obj-$(CONFIG_MTD) += malta_mtd.o
# FIXME FIXME FIXME
obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o
EXTRA_CFLAGS += -Werror
This diff is collapsed.
/*
* Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) Dmitri Vorobiev
* Copyright (C) 2008 Dmitri Vorobiev
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
......@@ -36,7 +36,10 @@
#include <linux/console.h>
#endif
struct resource standard_io_resources[] = {
extern void malta_be_init(void);
extern int malta_be_handler(struct pt_regs *regs, int is_fixup);
static struct resource standard_io_resources[] = {
{
.name = "dma1",
.start = 0x00,
......@@ -220,4 +223,7 @@ void __init plat_mem_setup(void)
screen_info_setup();
#endif
mips_reboot_setup();
board_be_init = malta_be_init;
board_be_handler = malta_be_handler;
}
......@@ -39,9 +39,6 @@
static void __init serial_init(void);
unsigned int _isbonito = 0;
extern void __init sanitize_tlb_entries(void);
const char *get_system_type(void)
{
return "MIPSsim";
......@@ -55,9 +52,6 @@ void __init plat_mem_setup(void)
pr_info("Linux started...\n");
#ifdef CONFIG_MIPS_MT_SMP
sanitize_tlb_entries();
#endif
}
extern struct plat_smp_ops ssmtc_smp_ops;
......
......@@ -4,30 +4,29 @@
obj-y += cache.o dma-default.o extable.o fault.o \
init.o pgtable.o tlbex.o tlbex-fault.o \
uasm.o
uasm.o page.o
obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o pg-r4k.o
obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r8k.o
obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o pg-sb1.o \
tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o pg-r4k.o tlb-r3k.o
obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o
obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o
obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
......
......@@ -14,6 +14,7 @@
#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <asm/bcache.h>
......@@ -53,6 +54,12 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
preempt_enable();
}
#if defined(CONFIG_MIPS_CMP)
#define cpu_has_safe_index_cacheops 0
#else
#define cpu_has_safe_index_cacheops 1
#endif
/*
* Must die.
*/
......@@ -481,6 +488,8 @@ static inline void local_r4k_flush_cache_page(void *args)
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
r4k_blast_dcache_page(addr);
if (exec && !cpu_icache_snoops_remote_store)
r4k_blast_scache_page(addr);
}
if (exec) {
if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
......@@ -583,7 +592,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
* subset property so we have to flush the primary caches
* explicitly
*/
if (size >= dcache_size) {
if (cpu_has_safe_index_cacheops && size >= dcache_size) {
r4k_blast_dcache();
} else {
R4600_HIT_CACHEOP_WAR_IMPL;
......@@ -606,7 +615,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
return;
}
if (size >= dcache_size) {
if (cpu_has_safe_index_cacheops && size >= dcache_size) {
r4k_blast_dcache();
} else {
R4600_HIT_CACHEOP_WAR_IMPL;
......@@ -968,6 +977,7 @@ static void __cpuinit probe_pcache(void)
case CPU_24K:
case CPU_34K:
case CPU_74K:
case CPU_1004K:
if ((read_c0_config7() & (1 << 16))) {
/* effectively physically indexed dcache,
thus no virtual aliases. */
......@@ -1216,9 +1226,25 @@ void au1x00_fixup_config_od(void)
}
}
static int __cpuinitdata cca = -1;
static int __init cca_setup(char *str)
{
get_option(&str, &cca);
return 1;
}
__setup("cca=", cca_setup);
static void __cpuinit coherency_setup(void)
{
change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
if (cca < 0 || cca > 7)
cca = read_c0_config() & CONF_CM_CMASK;
_page_cachable_default = cca << _CACHE_SHIFT;
pr_debug("Using cache attribute %d\n", cca);
change_c0_config(CONF_CM_CMASK, cca);
/*
* c0_status.cu=0 specifies that updates by the sc instruction use
......@@ -1248,6 +1274,20 @@ static void __cpuinit coherency_setup(void)
}
}
#if defined(CONFIG_DMA_NONCOHERENT)
static int __cpuinitdata coherentio;
static int __init setcoherentio(char *str)
{
coherentio = 1;
return 1;
}
__setup("coherentio", setcoherentio);
#endif
void __cpuinit r4k_cache_init(void)
{
extern void build_clear_page(void);
......@@ -1307,14 +1347,22 @@ void __cpuinit r4k_cache_init(void)
flush_data_cache_page = r4k_flush_data_cache_page;
flush_icache_range = r4k_flush_icache_range;
#ifdef CONFIG_DMA_NONCOHERENT
_dma_cache_wback_inv = r4k_dma_cache_wback_inv;
_dma_cache_wback = r4k_dma_cache_wback_inv;
_dma_cache_inv = r4k_dma_cache_inv;
#if defined(CONFIG_DMA_NONCOHERENT)
if (coherentio) {
_dma_cache_wback_inv = (void *)cache_noop;
_dma_cache_wback = (void *)cache_noop;
_dma_cache_inv = (void *)cache_noop;
} else {
_dma_cache_wback_inv = r4k_dma_cache_wback_inv;
_dma_cache_wback = r4k_dma_cache_wback_inv;
_dma_cache_inv = r4k_dma_cache_inv;
}
#endif
build_clear_page();
build_copy_page();
#if !defined(CONFIG_MIPS_CMP)
local_r4k___flush_cache_all(NULL);
#endif
coherency_setup();
}
......@@ -130,8 +130,28 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
}
}
static char cache_panic[] __cpuinitdata =
"Yeee, unsupported cache architecture.";
unsigned long _page_cachable_default;
EXPORT_SYMBOL_GPL(_page_cachable_default);
static inline void setup_protection_map(void)
{
protection_map[0] = PAGE_NONE;
protection_map[1] = PAGE_READONLY;
protection_map[2] = PAGE_COPY;
protection_map[3] = PAGE_COPY;
protection_map[4] = PAGE_READONLY;
protection_map[5] = PAGE_READONLY;
protection_map[6] = PAGE_COPY;
protection_map[7] = PAGE_COPY;
protection_map[8] = PAGE_NONE;
protection_map[9] = PAGE_READONLY;
protection_map[10] = PAGE_SHARED;
protection_map[11] = PAGE_SHARED;
protection_map[12] = PAGE_READONLY;
protection_map[13] = PAGE_READONLY;
protection_map[14] = PAGE_SHARED;
protection_map[15] = PAGE_SHARED;
}
void __devinit cpu_cache_init(void)
{
......@@ -139,34 +159,29 @@ void __devinit cpu_cache_init(void)
extern void __weak r3k_cache_init(void);
r3k_cache_init();
return;
}
if (cpu_has_6k_cache) {
extern void __weak r6k_cache_init(void);
r6k_cache_init();
return;
}
if (cpu_has_4k_cache) {
extern void __weak r4k_cache_init(void);
r4k_cache_init();
return;
}
if (cpu_has_8k_cache) {
extern void __weak r8k_cache_init(void);
r8k_cache_init();
return;
}
if (cpu_has_tx39_cache) {
extern void __weak tx39_cache_init(void);
tx39_cache_init();
return;
}
panic(cache_panic);
setup_protection_map();
}
int __weak __uncached_access(struct file *file, unsigned long addr)
......
......@@ -142,7 +142,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)
#endif
vaddr = __fix_to_virt(FIX_CMAP_END - idx);
pte = mk_pte(page, PAGE_KERNEL);
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
entrylo = pte.pte_high;
#else
entrylo = pte_val(pte) >> 6;
......@@ -221,7 +221,7 @@ void copy_user_highpage(struct page *to, struct page *from,
copy_page(vto, vfrom);
kunmap_atomic(vfrom, KM_USER0);
}
if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) ||
if ((!cpu_has_ic_fills_f_dc) ||
pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
flush_data_cache_page((unsigned long)vto);
kunmap_atomic(vto, KM_USER1);
......@@ -229,8 +229,6 @@ void copy_user_highpage(struct page *to, struct page *from,
smp_wmb();
}
EXPORT_SYMBOL(copy_user_highpage);
void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
......@@ -249,8 +247,6 @@ void copy_to_user_page(struct vm_area_struct *vma,
flush_cache_page(vma, vaddr, page_to_pfn(page));
}
EXPORT_SYMBOL(copy_to_user_page);
void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
......@@ -267,9 +263,6 @@ void copy_from_user_page(struct vm_area_struct *vma,
}
}
EXPORT_SYMBOL(copy_from_user_page);
#ifdef CONFIG_HIGHMEM
unsigned long highstart_pfn, highend_pfn;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -12,7 +12,6 @@ void show_mem(void)
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
pfn = max_mapnr;
while (pfn-- > 0) {
if (!pfn_valid(pfn))
......
......@@ -299,7 +299,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
idx = read_c0_index();
ptep = pte_offset_map(pmdp, address);
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
write_c0_entrylo0(ptep->pte_high);
ptep++;
write_c0_entrylo1(ptep->pte_high);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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