Commit 82798a17 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: (34 commits)
  [MIPS] tb0219: Update copyright message.
  [MIPS] MT: Fix bug in multithreaded kernels.
  [MIPS] Alchemy: Remove CONFIG_TS_AU1X00_ADS7846 from defconfigs.
  Author: Ralf Baechle <ralf@linux-mips.org>
  [MIPS] sb1250: Enable GenBus IDE in defconfig.
  [MIPS] vmlinux.ld.S: correctly indent .data section
  [MIPS] c-r3k: Implement flush_cache_range()
  [MIPS] Store sign-extend register values for PTRACE_GETREGS
  [MIPS] Alchemy: Register platform devices
  [MIPS] Add len and addr validation for MAP_FIXED mappings.
  [MIPS] IRIX: Fix off-by-one error in signal compat code.
  [MIPS] time: Replace plat_timer_setup with modern APIs.
  [MIPS] time: Fix cut'n'paste bug in Sibyte clockevent driver.
  [MIPS] time: Make c0_compare_int_usable faster
  [MIPS] time: Fix cevt-r4k.c for 64-bit kernel
  [MIPS] Sibyte: Delete {sb1250,bcm1480}_steal_irq().
  [MIPS] txx9tmr clockevent/clocksource driver
  [MIPS] Add mips_hpt_frequency check to mips_clockevent_init().
  [MIPS] IP32: Fixes after interrupt renumbering.
  [MIPS] IP27: Fix slice logic to work for arbitrary number of slices.
  ...
parents db818536 1a3b7920
...@@ -583,6 +583,7 @@ config SNI_RM ...@@ -583,6 +583,7 @@ config SNI_RM
config TOSHIBA_JMR3927 config TOSHIBA_JMR3927
bool "Toshiba JMR-TX3927 board" bool "Toshiba JMR-TX3927 board"
select CEVT_TXX9
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select MIPS_TX3927 select MIPS_TX3927
...@@ -597,6 +598,7 @@ config TOSHIBA_JMR3927 ...@@ -597,6 +598,7 @@ config TOSHIBA_JMR3927
config TOSHIBA_RBTX4927 config TOSHIBA_RBTX4927
bool "Toshiba RBTX49[23]7 board" bool "Toshiba RBTX49[23]7 board"
select CEVT_R4K select CEVT_R4K
select CEVT_TXX9
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HAS_TXX9_SERIAL select HAS_TXX9_SERIAL
select HW_HAS_PCI select HW_HAS_PCI
...@@ -618,6 +620,7 @@ config TOSHIBA_RBTX4927 ...@@ -618,6 +620,7 @@ config TOSHIBA_RBTX4927
config TOSHIBA_RBTX4938 config TOSHIBA_RBTX4938
bool "Toshiba RBTX4938 board" bool "Toshiba RBTX4938 board"
select CEVT_R4K select CEVT_R4K
select CEVT_TXX9
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HAS_TXX9_SERIAL select HAS_TXX9_SERIAL
select HW_HAS_PCI select HW_HAS_PCI
...@@ -736,6 +739,9 @@ config CEVT_GT641XX ...@@ -736,6 +739,9 @@ config CEVT_GT641XX
config CEVT_R4K config CEVT_R4K
bool bool
config CEVT_TXX9
bool
config CFE config CFE
bool bool
......
...@@ -318,38 +318,6 @@ static struct irq_chip level_irq_type = { ...@@ -318,38 +318,6 @@ static struct irq_chip level_irq_type = {
.end = end_irq, .end = end_irq,
}; };
#ifdef CONFIG_PM
void startup_match20_interrupt(irq_handler_t handler)
{
struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT];
static struct irqaction action;
memset(&action, 0, sizeof(struct irqaction));
/*
* This is a big problem.... since we didn't use request_irq
* when kernel/irq.c calls probe_irq_xxx this interrupt will
* be probed for usage. This will end up disabling the device :(
* Give it a bogus "action" pointer -- this will keep it from
* getting auto-probed!
*
* By setting the status to match that of request_irq() we
* can avoid it. --cgray
*/
action.dev_id = handler;
action.flags = IRQF_DISABLED;
cpus_clear(action.mask);
action.name = "Au1xxx TOY";
action.handler = handler;
action.next = NULL;
desc->action = &action;
desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
local_enable_irq(AU1000_TOY_MATCH2_INT);
}
#endif
static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req) static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req)
{ {
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
......
...@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(time_lock); ...@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(time_lock);
unsigned long wtimer; unsigned long wtimer;
#ifdef CONFIG_PM #ifdef CONFIG_PM
irqreturn_t counter0_irq(int irq, void *dev_id) static irqreturn_t counter0_irq(int irq, void *dev_id)
{ {
unsigned long pc0; unsigned long pc0;
int time_elapsed; int time_elapsed;
...@@ -117,6 +117,13 @@ irqreturn_t counter0_irq(int irq, void *dev_id) ...@@ -117,6 +117,13 @@ irqreturn_t counter0_irq(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
struct irqaction counter0_action = {
.handler = counter0_irq,
.flags = IRQF_DISABLED,
.name = "alchemy-toy",
.dev_id = NULL,
};
/* When we wakeup from sleep, we have to "catch up" on all of the /* When we wakeup from sleep, we have to "catch up" on all of the
* timer ticks we have missed. * timer ticks we have missed.
*/ */
...@@ -221,7 +228,7 @@ unsigned long cal_r4koff(void) ...@@ -221,7 +228,7 @@ unsigned long cal_r4koff(void)
return (cpu_speed / HZ); return (cpu_speed / HZ);
} }
void __init plat_timer_setup(struct irqaction *irq) void __init plat_time_init(void)
{ {
unsigned int est_freq; unsigned int est_freq;
...@@ -255,15 +262,10 @@ void __init plat_timer_setup(struct irqaction *irq) ...@@ -255,15 +262,10 @@ void __init plat_timer_setup(struct irqaction *irq)
* we do this. * we do this.
*/ */
if (no_au1xxx_32khz) { if (no_au1xxx_32khz) {
unsigned int c0_status;
printk("WARNING: no 32KHz clock found.\n"); printk("WARNING: no 32KHz clock found.\n");
/* Ensure we get CPO_COUNTER interrupts. /* Ensure we get CPO_COUNTER interrupts. */
*/ set_c0_status(IE_IRQ5);
c0_status = read_c0_status();
c0_status |= IE_IRQ5;
write_c0_status(c0_status);
} }
else { else {
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
...@@ -280,7 +282,7 @@ void __init plat_timer_setup(struct irqaction *irq) ...@@ -280,7 +282,7 @@ void __init plat_timer_setup(struct irqaction *irq)
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
au_sync(); au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
startup_match20_interrupt(counter0_irq); setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
/* We can use the real 'wait' instruction. /* We can use the real 'wait' instruction.
*/ */
......
...@@ -8,3 +8,4 @@ ...@@ -8,3 +8,4 @@
# #
lib-y := init.o board_setup.o irqmap.o lib-y := init.o board_setup.o irqmap.o
obj-y := platform.o
/*
* MTX-1 platform devices registration
*
* Copyright (C) 2007, Florian Fainelli <florian@openwrt.org>
*
* 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/types.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <asm/gpio.h>
static struct resource mtx1_wdt_res[] = {
[0] = {
.start = 15,
.end = 15,
.name = "mtx1-wdt-gpio",
.flags = IORESOURCE_IRQ,
}
};
static struct resource mtx1_sys_btn[] = {
[0] = {
.start = 7,
.end = 7,
.name = "mtx1-sys-btn-gpio",
.flags = IORESOURCE_IRQ,
}
};
static struct platform_device mtx1_wdt = {
.name = "mtx1-wdt",
.id = 0,
.num_resources = ARRAY_SIZE(mtx1_wdt_res),
.resource = mtx1_wdt_res,
};
static struct gpio_led default_leds[] = {
{
.name = "mtx1:green",
.gpio = 211,
}, {
.name = "mtx1:red",
.gpio = 212,
},
};
static struct gpio_led_platform_data mtx1_led_data = {
.num_leds = ARRAY_SIZE(default_leds),
.leds = default_leds,
};
static struct platform_device mtx1_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &mtx1_led_data,
}
};
static struct __initdata platform_device * mtx1_devs[] = {
&mtx1_gpio_leds,
&mtx1_wdt
};
static int __init mtx1_register_devices(void)
{
return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
}
arch_initcall(mtx1_register_devices);
...@@ -68,24 +68,23 @@ DEFINE_SPINLOCK(titan_lock); ...@@ -68,24 +68,23 @@ DEFINE_SPINLOCK(titan_lock);
int titan_irqflags; int titan_irqflags;
/*
* The eXcite platform uses the alternate timer interrupt
*
* Fixme: At the time of this writing cevt-r4k.c doesn't yet know about how
* to handle the alternate timer interrupt of the RM9000.
*/
void __init plat_time_init(void) void __init plat_time_init(void)
{ {
const u32 modebit5 = ocd_readl(0x00e4); const u32 modebit5 = ocd_readl(0x00e4);
unsigned int unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2,
mult = ((modebit5 >> 11) & 0x1f) + 2, unsigned int div = ((modebit5 >> 16) & 0x1f) + 2;
div = ((modebit5 >> 16) & 0x1f) + 2;
if (div == 33) div = 1; if (div == 33)
div = 1;
mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2; mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2;
} }
void __init plat_timer_setup(struct irqaction *irq)
{
/* The eXcite platform uses the alternate timer interrupt */
set_c0_intcontrol(0x80);
setup_irq(TIMER_IRQ, irq);
}
static int __init excite_init_console(void) static int __init excite_init_console(void)
{ {
#if defined(CONFIG_SERIAL_8250) #if defined(CONFIG_SERIAL_8250)
......
...@@ -738,7 +738,6 @@ CONFIG_HW_CONSOLE=y ...@@ -738,7 +738,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -714,7 +714,6 @@ CONFIG_HW_CONSOLE=y ...@@ -714,7 +714,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -775,7 +775,6 @@ CONFIG_HW_CONSOLE=y ...@@ -775,7 +775,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -811,7 +811,6 @@ CONFIG_SERIO_RAW=m ...@@ -811,7 +811,6 @@ CONFIG_SERIO_RAW=m
# CONFIG_VT is not set # CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -856,7 +856,6 @@ CONFIG_SERIO_RAW=m ...@@ -856,7 +856,6 @@ CONFIG_SERIO_RAW=m
# CONFIG_VT is not set # CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -731,7 +731,6 @@ CONFIG_HW_CONSOLE=y ...@@ -731,7 +731,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_VT_HW_CONSOLE_BINDING=y
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -849,7 +849,6 @@ CONFIG_SERIO_RAW=m ...@@ -849,7 +849,6 @@ CONFIG_SERIO_RAW=m
# CONFIG_VT is not set # CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -842,7 +842,6 @@ CONFIG_SERIO_RAW=m ...@@ -842,7 +842,6 @@ CONFIG_SERIO_RAW=m
# CONFIG_VT is not set # CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_AU1X00_GPIO is not set # CONFIG_AU1X00_GPIO is not set
# CONFIG_TS_AU1X00_ADS7846 is not set
# #
# Serial drivers # Serial drivers
......
...@@ -468,7 +468,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y ...@@ -468,7 +468,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
# #
CONFIG_IDE_GENERIC=y CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_IDEPCI is not set # CONFIG_BLK_DEV_IDEPCI is not set
# CONFIG_BLK_DEV_IDE_SWARM is not set CONFIG_BLK_DEV_IDE_SWARM=y
# CONFIG_IDE_ARM is not set # CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set # CONFIG_IDEDMA_AUTO is not set
......
...@@ -19,12 +19,6 @@ ...@@ -19,12 +19,6 @@
#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */ #define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
void __init plat_timer_setup(struct irqaction *irq)
{
/* Install ISR for timer interrupt */
setup_irq(WRPPMC_MIPS_TIMER_IRQ, irq);
}
/* /*
* Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
* *
......
...@@ -27,17 +27,13 @@ ...@@ -27,17 +27,13 @@
* Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
*/ */
#include <linux/clockchips.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/irq.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/param.h> /* for HZ */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -48,17 +44,13 @@ ...@@ -48,17 +44,13 @@
#endif #endif
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <asm/time.h> #include <asm/txx9tmr.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/jmr3927/jmr3927.h> #include <asm/jmr3927/jmr3927.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
extern void puts(const char *cp); extern void puts(const char *cp);
/* Tick Timer divider */
#define JMR3927_TIMER_CCD 0 /* 1/2 */
#define JMR3927_TIMER_CLK (JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD))
/* don't enable - see errata */ /* don't enable - see errata */
static int jmr3927_ccfg_toeon; static int jmr3927_ccfg_toeon;
...@@ -93,66 +85,12 @@ static void jmr3927_machine_power_off(void) ...@@ -93,66 +85,12 @@ static void jmr3927_machine_power_off(void)
while (1); while (1);
} }
static cycle_t jmr3927_hpt_read(void)
{
/* We assume this function is called xtime_lock held. */
return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
}
static void jmr3927_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
/* Nothing to do here */
}
struct clock_event_device jmr3927_clock_event_device = {
.name = "MIPS",
.features = CLOCK_EVT_FEAT_PERIODIC,
.shift = 32,
.rating = 300,
.cpumask = CPU_MASK_CPU0,
.irq = JMR3927_IRQ_TICK,
.set_mode = jmr3927_set_mode,
};
static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd = &jmr3927_clock_event_device;
jmr3927_tmrptr->tisr = 0; /* ack interrupt */
cd->event_handler(cd);
return IRQ_HANDLED;
}
static struct irqaction jmr3927_timer_irqaction = {
.handler = jmr3927_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU,
.name = "jmr3927-timer",
};
void __init plat_time_init(void) void __init plat_time_init(void)
{ {
struct clock_event_device *cd; txx9_clockevent_init(TX3927_TMR_REG(0),
TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0),
clocksource_mips.read = jmr3927_hpt_read; JMR3927_IMCLK);
mips_hpt_frequency = JMR3927_TIMER_CLK; txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK);
jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
jmr3927_tmrptr->tcr =
TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
cd = &jmr3927_clock_event_device;
/* Calculate the min / max delta */
cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
clockevents_register_device(cd);
setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction);
} }
#define DO_WRITE_THROUGH #define DO_WRITE_THROUGH
...@@ -317,15 +255,8 @@ static void __init tx3927_setup(void) ...@@ -317,15 +255,8 @@ static void __init tx3927_setup(void)
tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg); tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
/* TMR */ /* TMR */
/* disable all timers */ for (i = 0; i < TX3927_NR_TMR; i++)
for (i = 0; i < TX3927_NR_TMR; i++) { txx9_tmr_init(TX3927_TMR_REG(i));
tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE;
tx3927_tmrptr(i)->tisr = 0;
tx3927_tmrptr(i)->cpra = 0xffffffff;
tx3927_tmrptr(i)->itmr = 0;
tx3927_tmrptr(i)->ccdr = 0;
tx3927_tmrptr(i)->pgmr = 0;
}
/* DMA */ /* DMA */
tx3927_dmaptr->mcr = 0; tx3927_dmaptr->mcr = 0;
......
...@@ -10,6 +10,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ...@@ -10,6 +10,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o irix5sys.o sysirix.o
......
...@@ -49,10 +49,9 @@ int gt641xx_timer0_state(void) ...@@ -49,10 +49,9 @@ int gt641xx_timer0_state(void)
static int gt641xx_timer0_set_next_event(unsigned long delta, static int gt641xx_timer0_set_next_event(unsigned long delta,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long flags;
u32 ctrl; u32 ctrl;
spin_lock_irqsave(&gt641xx_timer_lock, flags); spin_lock(&gt641xx_timer_lock);
ctrl = GT_READ(GT_TC_CONTROL_OFS); ctrl = GT_READ(GT_TC_CONTROL_OFS);
ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
...@@ -61,7 +60,7 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, ...@@ -61,7 +60,7 @@ static int gt641xx_timer0_set_next_event(unsigned long delta,
GT_WRITE(GT_TC0_OFS, delta); GT_WRITE(GT_TC0_OFS, delta);
GT_WRITE(GT_TC_CONTROL_OFS, ctrl); GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
spin_unlock_irqrestore(&gt641xx_timer_lock, flags); spin_unlock(&gt641xx_timer_lock);
return 0; return 0;
} }
...@@ -69,10 +68,9 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, ...@@ -69,10 +68,9 @@ static int gt641xx_timer0_set_next_event(unsigned long delta,
static void gt641xx_timer0_set_mode(enum clock_event_mode mode, static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long flags;
u32 ctrl; u32 ctrl;
spin_lock_irqsave(&gt641xx_timer_lock, flags); spin_lock(&gt641xx_timer_lock);
ctrl = GT_READ(GT_TC_CONTROL_OFS); ctrl = GT_READ(GT_TC_CONTROL_OFS);
ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
...@@ -90,7 +88,7 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode, ...@@ -90,7 +88,7 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
GT_WRITE(GT_TC_CONTROL_OFS, ctrl); GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
spin_unlock_irqrestore(&gt641xx_timer_lock, flags); spin_unlock(&gt641xx_timer_lock);
} }
static void gt641xx_timer0_event_handler(struct clock_event_device *dev) static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
...@@ -133,9 +131,9 @@ static int __init gt641xx_timer0_clockevent_init(void) ...@@ -133,9 +131,9 @@ static int __init gt641xx_timer0_clockevent_init(void)
cd = &gt641xx_timer0_clockevent; cd = &gt641xx_timer0_clockevent;
cd->rating = 200 + gt641xx_base_clock / 10000000; cd->rating = 200 + gt641xx_base_clock / 10000000;
clockevent_set_clock(cd, gt641xx_base_clock);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
clockevent_set_clock(cd, gt641xx_base_clock);
clockevents_register_device(&gt641xx_timer0_clockevent); clockevents_register_device(&gt641xx_timer0_clockevent);
......
...@@ -28,7 +28,7 @@ static int mips_next_event(unsigned long delta, ...@@ -28,7 +28,7 @@ static int mips_next_event(unsigned long delta,
cnt = read_c0_count(); cnt = read_c0_count();
cnt += delta; cnt += delta;
write_c0_compare(cnt); write_c0_compare(cnt);
res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0; res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
#ifdef CONFIG_MIPS_MT_SMTC #ifdef CONFIG_MIPS_MT_SMTC
evpe(vpflags); evpe(vpflags);
local_irq_restore(flags); local_irq_restore(flags);
...@@ -179,7 +179,7 @@ static int c0_compare_int_pending(void) ...@@ -179,7 +179,7 @@ static int c0_compare_int_pending(void)
static int c0_compare_int_usable(void) static int c0_compare_int_usable(void)
{ {
const unsigned int delta = 0x300000; unsigned int delta;
unsigned int cnt; unsigned int cnt;
/* /*
...@@ -192,11 +192,17 @@ static int c0_compare_int_usable(void) ...@@ -192,11 +192,17 @@ static int c0_compare_int_usable(void)
return 0; return 0;
} }
cnt = read_c0_count(); for (delta = 0x10; delta <= 0x400000; delta <<= 1) {
cnt += delta; cnt = read_c0_count();
write_c0_compare(cnt); cnt += delta;
write_c0_compare(cnt);
irq_disable_hazard();
if ((int)(read_c0_count() - cnt) < 0)
break;
/* increase delta if the timer was already expired */
}
while ((long)(read_c0_count() - cnt) <= 0) while ((int)(read_c0_count() - cnt) <= 0)
; /* Wait for expiry */ ; /* Wait for expiry */
if (!c0_compare_int_pending()) if (!c0_compare_int_pending())
...@@ -218,9 +224,9 @@ void __cpuinit mips_clockevent_init(void) ...@@ -218,9 +224,9 @@ void __cpuinit mips_clockevent_init(void)
uint64_t mips_freq = mips_hpt_frequency; uint64_t mips_freq = mips_hpt_frequency;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
struct clock_event_device *cd; struct clock_event_device *cd;
unsigned int irq = MIPS_CPU_IRQ_BASE + 7; unsigned int irq;
if (!cpu_has_counter) if (!cpu_has_counter || !mips_hpt_frequency)
return; return;
#ifdef CONFIG_MIPS_MT_SMTC #ifdef CONFIG_MIPS_MT_SMTC
...@@ -237,6 +243,15 @@ void __cpuinit mips_clockevent_init(void) ...@@ -237,6 +243,15 @@ void __cpuinit mips_clockevent_init(void)
if (!c0_compare_int_usable()) if (!c0_compare_int_usable())
return; return;
/*
* With vectored interrupts things are getting platform specific.
* get_c0_compare_int is a hook to allow a platform to return the
* interrupt number of it's liking.
*/
irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
if (get_c0_compare_int)
irq = get_c0_compare_int();
cd = &per_cpu(mips_clockevent_device, cpu); cd = &per_cpu(mips_clockevent_device, cpu);
cd->name = "MIPS"; cd->name = "MIPS";
...@@ -261,13 +276,15 @@ void __cpuinit mips_clockevent_init(void) ...@@ -261,13 +276,15 @@ void __cpuinit mips_clockevent_init(void)
clockevents_register_device(cd); clockevents_register_device(cd);
if (!cp0_timer_irq_installed) { if (!cp0_timer_irq_installed)
return;
cp0_timer_irq_installed = 1;
#ifdef CONFIG_MIPS_MT_SMTC #ifdef CONFIG_MIPS_MT_SMTC
#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
#else #else
setup_irq(irq, &c0_compare_irqaction); setup_irq(irq, &c0_compare_irqaction);
#endif /* CONFIG_MIPS_MT_SMTC */ #endif
cp0_timer_irq_installed = 1;
}
} }
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Based on linux/arch/mips/kernel/cevt-r4k.c,
* linux/arch/mips/jmr3927/rbhma3100/setup.c
*
* Copyright 2001 MontaVista Software Inc.
* Copyright (C) 2000-2001 Toshiba Corporation
* Copyright (C) 2007 MIPS Technologies, Inc.
* Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/time.h>
#include <asm/txx9tmr.h>
#define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
#define TIMER_CCD 0 /* 1/2 */
#define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD))
static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr;
static cycle_t txx9_cs_read(void)
{
return __raw_readl(&txx9_cs_tmrptr->trr);
}
/* Use 1 bit smaller width to use full bits in that width */
#define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
static struct clocksource txx9_clocksource = {
.name = "TXx9",
.rating = 200,
.read = txx9_cs_read,
.mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
void __init txx9_clocksource_init(unsigned long baseaddr,
unsigned int imbusclk)
{
struct txx9_tmr_reg __iomem *tmrptr;
clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk));
clocksource_register(&txx9_clocksource);
tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
__raw_writel(TCR_BASE, &tmrptr->tcr);
__raw_writel(0, &tmrptr->tisr);
__raw_writel(TIMER_CCD, &tmrptr->ccdr);
__raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
__raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
txx9_cs_tmrptr = tmrptr;
}
static struct txx9_tmr_reg __iomem *txx9_tmrptr;
static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
{
/* stop and reset counter */
__raw_writel(TCR_BASE, &tmrptr->tcr);
/* clear pending interrupt */
__raw_writel(0, &tmrptr->tisr);
}
static void txx9tmr_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
txx9tmr_stop_and_clear(tmrptr);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
__raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,
&tmrptr->itmr);
/* start timer */
__raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>
evt->shift,
&tmrptr->cpra);
__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
__raw_writel(0, &tmrptr->itmr);
break;
case CLOCK_EVT_MODE_ONESHOT:
__raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
break;
case CLOCK_EVT_MODE_RESUME:
__raw_writel(TIMER_CCD, &tmrptr->ccdr);
__raw_writel(0, &tmrptr->itmr);
break;
}
}
static int txx9tmr_set_next_event(unsigned long delta,
struct clock_event_device *evt)
{
struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
txx9tmr_stop_and_clear(tmrptr);
/* start timer */
__raw_writel(delta, &tmrptr->cpra);
__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
return 0;
}
static struct clock_event_device txx9tmr_clock_event_device = {
.name = "TXx9",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.rating = 200,
.cpumask = CPU_MASK_CPU0,
.set_mode = txx9tmr_set_mode,
.set_next_event = txx9tmr_set_next_event,
};
static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd = &txx9tmr_clock_event_device;
struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
__raw_writel(0, &tmrptr->tisr); /* ack interrupt */
cd->event_handler(cd);
return IRQ_HANDLED;
}
static struct irqaction txx9tmr_irq = {
.handler = txx9tmr_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU,
.name = "txx9tmr",
};
void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
unsigned int imbusclk)
{
struct clock_event_device *cd = &txx9tmr_clock_event_device;
struct txx9_tmr_reg __iomem *tmrptr;
tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
txx9tmr_stop_and_clear(tmrptr);
__raw_writel(TIMER_CCD, &tmrptr->ccdr);
__raw_writel(0, &tmrptr->itmr);
txx9_tmrptr = tmrptr;
clockevent_set_clock(cd, TIMER_CLK(imbusclk));
cd->max_delta_ns =
clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
cd->irq = irq;
clockevents_register_device(cd);
setup_irq(irq, &txx9tmr_irq);
printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n",
baseaddr, irq);
}
void __init txx9_tmr_init(unsigned long baseaddr)
{
struct txx9_tmr_reg __iomem *tmrptr;
tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
__raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
__raw_writel(0, &tmrptr->tisr);
__raw_writel(0xffffffff, &tmrptr->cpra);
__raw_writel(0, &tmrptr->itmr);
__raw_writel(0, &tmrptr->ccdr);
__raw_writel(0, &tmrptr->pgmr);
iounmap(tmrptr);
}
...@@ -24,8 +24,12 @@ ...@@ -24,8 +24,12 @@
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
#define _IRIX_NSIG 128
#define _IRIX_NSIG_BPW BITS_PER_LONG
#define _IRIX_NSIG_WORDS (_IRIX_NSIG / _IRIX_NSIG_BPW)
typedef struct { typedef struct {
unsigned long sig[4]; unsigned long sig[_IRIX_NSIG_WORDS];
} irix_sigset_t; } irix_sigset_t;
struct sigctx_irix5 { struct sigctx_irix5 {
...@@ -527,7 +531,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set, ...@@ -527,7 +531,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
expire = schedule_timeout_interruptible(expire); expire = schedule_timeout_interruptible(expire);
for (i=0; i<=4; i++) for (i=0; i < _IRIX_NSIG_WORDS; i++)
tmp |= (current->pending.signal.sig[i] & kset.sig[i]); tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
if (tmp) if (tmp)
......
...@@ -65,13 +65,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) ...@@ -65,13 +65,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)
regs = task_pt_regs(child); regs = task_pt_regs(child);
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
__put_user(regs->regs[i], data + i); __put_user((long)regs->regs[i], data + i);
__put_user(regs->lo, data + EF_LO - EF_R0); __put_user((long)regs->lo, data + EF_LO - EF_R0);
__put_user(regs->hi, data + EF_HI - EF_R0); __put_user((long)regs->hi, data + EF_HI - EF_R0);
__put_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0); __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
__put_user(regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
__put_user(regs->cp0_status, data + EF_CP0_STATUS - EF_R0); __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
__put_user(regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
return 0; return 0;
} }
...@@ -390,11 +390,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -390,11 +390,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
} }
case PTRACE_GETREGS: case PTRACE_GETREGS:
ret = ptrace_getregs(child, (__u64 __user *) data); ret = ptrace_getregs(child, (__s64 __user *) data);
break; break;
case PTRACE_SETREGS: case PTRACE_SETREGS:
ret = ptrace_setregs(child, (__u64 __user *) data); ret = ptrace_setregs(child, (__s64 __user *) data);
break; break;
case PTRACE_GETFPREGS: case PTRACE_GETFPREGS:
......
...@@ -346,11 +346,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) ...@@ -346,11 +346,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
} }
case PTRACE_GETREGS: case PTRACE_GETREGS:
ret = ptrace_getregs(child, (__u64 __user *) (__u64) data); ret = ptrace_getregs(child, (__s64 __user *) (__u64) data);
break; break;
case PTRACE_SETREGS: case PTRACE_SETREGS:
ret = ptrace_setregs(child, (__u64 __user *) (__u64) data); ret = ptrace_setregs(child, (__s64 __user *) (__u64) data);
break; break;
case PTRACE_GETFPREGS: case PTRACE_GETFPREGS:
......
...@@ -88,11 +88,19 @@ unsigned int smtc_status = 0; ...@@ -88,11 +88,19 @@ unsigned int smtc_status = 0;
/* Boot command line configuration overrides */ /* Boot command line configuration overrides */
static int vpe0limit;
static int ipibuffers = 0; static int ipibuffers = 0;
static int nostlb = 0; static int nostlb = 0;
static int asidmask = 0; static int asidmask = 0;
unsigned long smtc_asid_mask = 0xff; unsigned long smtc_asid_mask = 0xff;
static int __init vpe0tcs(char *str)
{
get_option(&str, &vpe0limit);
return 1;
}
static int __init ipibufs(char *str) static int __init ipibufs(char *str)
{ {
get_option(&str, &ipibuffers); get_option(&str, &ipibuffers);
...@@ -125,6 +133,7 @@ static int __init asidmask_set(char *str) ...@@ -125,6 +133,7 @@ static int __init asidmask_set(char *str)
return 1; return 1;
} }
__setup("vpe0tcs=", vpe0tcs);
__setup("ipibufs=", ipibufs); __setup("ipibufs=", ipibufs);
__setup("nostlb", stlb_disable); __setup("nostlb", stlb_disable);
__setup("asidmask=", asidmask_set); __setup("asidmask=", asidmask_set);
...@@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) ...@@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
void mipsmt_prepare_cpus(void) void mipsmt_prepare_cpus(void)
{ {
int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu; int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
unsigned long flags; unsigned long flags;
unsigned long val; unsigned long val;
int nipi; int nipi;
...@@ -401,8 +410,39 @@ void mipsmt_prepare_cpus(void) ...@@ -401,8 +410,39 @@ void mipsmt_prepare_cpus(void)
ntc = NR_CPUS; ntc = NR_CPUS;
if (tclimit > 0 && ntc > tclimit) if (tclimit > 0 && ntc > tclimit)
ntc = tclimit; ntc = tclimit;
tcpervpe = ntc / nvpe; slop = ntc % nvpe;
slop = ntc % nvpe; /* Residual TCs, < NVPE */ for (i = 0; i < nvpe; i++) {
tcpervpe[i] = ntc / nvpe;
if (slop) {
if((slop - i) > 0) tcpervpe[i]++;
}
}
/* Handle command line override for VPE0 */
if (vpe0limit > ntc) vpe0limit = ntc;
if (vpe0limit > 0) {
int slopslop;
if (vpe0limit < tcpervpe[0]) {
/* Reducing TC count - distribute to others */
slop = tcpervpe[0] - vpe0limit;
slopslop = slop % (nvpe - 1);
tcpervpe[0] = vpe0limit;
for (i = 1; i < nvpe; i++) {
tcpervpe[i] += slop / (nvpe - 1);
if(slopslop && ((slopslop - (i - 1) > 0)))
tcpervpe[i]++;
}
} else if (vpe0limit > tcpervpe[0]) {
/* Increasing TC count - steal from others */
slop = vpe0limit - tcpervpe[0];
slopslop = slop % (nvpe - 1);
tcpervpe[0] = vpe0limit;
for (i = 1; i < nvpe; i++) {
tcpervpe[i] -= slop / (nvpe - 1);
if(slopslop && ((slopslop - (i - 1) > 0)))
tcpervpe[i]--;
}
}
}
/* Set up shared TLB */ /* Set up shared TLB */
smtc_configure_tlb(); smtc_configure_tlb();
...@@ -416,7 +456,7 @@ void mipsmt_prepare_cpus(void) ...@@ -416,7 +456,7 @@ void mipsmt_prepare_cpus(void)
if (vpe != 0) if (vpe != 0)
printk(", "); printk(", ");
printk("VPE %d: TC", vpe); printk("VPE %d: TC", vpe);
for (i = 0; i < tcpervpe; i++) { for (i = 0; i < tcpervpe[vpe]; i++) {
/* /*
* TC 0 is bound to VPE 0 at reset, * TC 0 is bound to VPE 0 at reset,
* and is presumably executing this * and is presumably executing this
...@@ -429,15 +469,6 @@ void mipsmt_prepare_cpus(void) ...@@ -429,15 +469,6 @@ void mipsmt_prepare_cpus(void)
printk(" %d", tc); printk(" %d", tc);
tc++; tc++;
} }
if (slop) {
if (tc != 0) {
smtc_tc_setup(vpe, tc, cpu);
cpu++;
}
printk(" %d", tc);
tc++;
slop--;
}
if (vpe != 0) { if (vpe != 0) {
/* /*
* Clear any stale software interrupts from VPE's Cause * Clear any stale software interrupts from VPE's Cause
......
...@@ -73,7 +73,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, ...@@ -73,7 +73,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
task_size = STACK_TOP; task_size = STACK_TOP;
if (len > task_size)
return -ENOMEM;
if (flags & MAP_FIXED) { if (flags & MAP_FIXED) {
/* Even MAP_FIXED mappings must reside within task_size. */
if (task_size - len < addr)
return -EINVAL;
/* /*
* We do not accept a shared mapping if it would violate * We do not accept a shared mapping if it would violate
* cache aliasing constraints. * cache aliasing constraints.
...@@ -83,8 +90,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, ...@@ -83,8 +90,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
return addr; return addr;
} }
if (len > task_size)
return -ENOMEM;
do_color_align = 0; do_color_align = 0;
if (filp || (flags & MAP_SHARED)) if (filp || (flags & MAP_SHARED))
do_color_align = 1; do_color_align = 1;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* Free Software Foundation; either version 2 of the License, or (at your * Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. * option) any later version.
*/ */
#include <linux/bug.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -115,10 +116,6 @@ EXPORT_SYMBOL(perf_irq); ...@@ -115,10 +116,6 @@ EXPORT_SYMBOL(perf_irq);
* (only needed if you intended to use cpu counter as timer interrupt * (only needed if you intended to use cpu counter as timer interrupt
* source) * source)
* 2) calculate a couple of cached variables for later usage * 2) calculate a couple of cached variables for later usage
* 3) plat_timer_setup() -
* a) (optional) over-write any choices made above by time_init().
* b) machine specific code should setup the timer irqaction.
* c) enable the timer interrupt
*/ */
unsigned int mips_hpt_frequency; unsigned int mips_hpt_frequency;
...@@ -221,8 +218,18 @@ void __init __weak plat_time_init(void) ...@@ -221,8 +218,18 @@ void __init __weak plat_time_init(void)
{ {
} }
void __init __weak plat_timer_setup(struct irqaction *irq) /*
* This function exists in order to cause an error due to a duplicate
* definition if platform code should have its own implementation. The hook
* to use instead is plat_time_init. plat_time_init does not receive the
* irqaction pointer argument anymore. This is because any function which
* initializes an interrupt timer now takes care of its own request_irq rsp.
* setup_irq calls and each clock_event_device should use its own
* struct irqrequest.
*/
void __init plat_timer_setup(struct irqaction *irq)
{ {
BUG();
} }
void __init time_init(void) void __init time_init(void)
......
...@@ -63,21 +63,23 @@ SECTIONS ...@@ -63,21 +63,23 @@ SECTIONS
/* writeable */ /* writeable */
.data : { /* Data */ .data : { /* Data */
. = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */
/* /*
* This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which * This ALIGN is needed as a workaround for a bug a
* limits the maximum alignment to at most 32kB and results in the following * gcc bug upto 4.1 which limits the maximum alignment
* warning: * to at most 32kB and results in the following
* * warning:
* CC arch/mips/kernel/init_task.o *
* arch/mips/kernel/init_task.c:30: warning: alignment of init_thread_union * CC arch/mips/kernel/init_task.o
* is greater than maximum object file alignment. Using 32768 * arch/mips/kernel/init_task.c:30: warning: alignment
*/ * of init_thread_union is greater than maximum
. = ALIGN(_PAGE_SIZE); * object file alignment. Using 32768
*(.data.init_task) */
. = ALIGN(_PAGE_SIZE);
DATA_DATA *(.data.init_task)
CONSTRUCTORS
DATA_DATA
CONSTRUCTORS
} }
_gp = . + 0x8000; _gp = . + 0x8000;
.lit8 : { .lit8 : {
......
...@@ -942,8 +942,8 @@ static int vpe_elfload(struct vpe * v) ...@@ -942,8 +942,8 @@ static int vpe_elfload(struct vpe * v)
if (phdr->p_type != PT_LOAD) if (phdr->p_type != PT_LOAD)
continue; continue;
memcpy((void *)phdr->p_vaddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
memset((void *)phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
phdr++; phdr++;
} }
......
...@@ -117,14 +117,11 @@ static struct notifier_block lasat_panic_block[] = ...@@ -117,14 +117,11 @@ static struct notifier_block lasat_panic_block[] =
} }
}; };
void plat_time_init(void) void __init plat_time_init(void)
{ {
mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2; mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2;
}
void __init plat_timer_setup(struct irqaction *irq) change_c0_status(ST0_IM, IE_IRQ0);
{
change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
} }
void __init plat_mem_setup(void) void __init plat_mem_setup(void)
......
...@@ -127,26 +127,6 @@ unsigned long read_persistent_clock(void) ...@@ -127,26 +127,6 @@ unsigned long read_persistent_clock(void)
return mc146818_get_cmos_time(); return mc146818_get_cmos_time();
} }
void __init plat_time_init(void)
{
unsigned int est_freq;
/* Set Data mode - binary. */
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
est_freq = estimate_cpu_frequency();
printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
(est_freq%1000000)*100/1000000);
cpu_khz = est_freq / 1000;
mips_scroll_message();
#ifdef CONFIG_I8253 /* Only Malta has a PIT */
setup_pit_timer();
#endif
}
void __init plat_perf_setup(void) void __init plat_perf_setup(void)
{ {
cp0_perfcount_irq = -1; cp0_perfcount_irq = -1;
...@@ -166,14 +146,13 @@ void __init plat_perf_setup(void) ...@@ -166,14 +146,13 @@ void __init plat_perf_setup(void)
} }
} }
void __init plat_timer_setup(struct irqaction *irq) unsigned int __init get_c0_compare_int(void)
{ {
#ifdef MSC01E_INT_BASE #ifdef MSC01E_INT_BASE
if (cpu_has_veic) { if (cpu_has_veic) {
set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
} } else
else
#endif #endif
{ {
if (cpu_has_vint) if (cpu_has_vint)
...@@ -181,13 +160,26 @@ void __init plat_timer_setup(struct irqaction *irq) ...@@ -181,13 +160,26 @@ void __init plat_timer_setup(struct irqaction *irq)
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
} }
#ifdef CONFIG_MIPS_MT_SMTC return mips_cpu_timer_irq;
setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << cp0_compare_irq); }
#else
setup_irq(mips_cpu_timer_irq, irq); void __init plat_time_init(void)
#endif /* CONFIG_MIPS_MT_SMTC */ {
#ifdef CONFIG_SMP unsigned int est_freq;
set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq);
/* Set Data mode - binary. */
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
est_freq = estimate_cpu_frequency();
printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
(est_freq%1000000)*100/1000000);
cpu_khz = est_freq / 1000;
mips_scroll_message();
#ifdef CONFIG_I8253 /* Only Malta has a PIT */
setup_pit_timer();
#endif #endif
plat_perf_setup(); plat_perf_setup();
......
...@@ -75,25 +75,6 @@ static unsigned int __init estimate_cpu_frequency(void) ...@@ -75,25 +75,6 @@ static unsigned int __init estimate_cpu_frequency(void)
return count; return count;
} }
void __init plat_time_init(void)
{
unsigned int est_freq, flags;
local_irq_save(flags);
/* Set Data mode - binary. */
CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
est_freq = estimate_cpu_frequency();
printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
(est_freq % 1000000) * 100 / 1000000);
cpu_khz = est_freq / 1000;
local_irq_restore(flags);
}
static int mips_cpu_timer_irq; static int mips_cpu_timer_irq;
static void mips_timer_dispatch(void) static void mips_timer_dispatch(void)
...@@ -102,26 +83,37 @@ static void mips_timer_dispatch(void) ...@@ -102,26 +83,37 @@ static void mips_timer_dispatch(void)
} }
void __init plat_timer_setup(struct irqaction *irq) unsigned __init get_c0_compare_int(void)
{ {
#ifdef MSC01E_INT_BASE
if (cpu_has_veic) { if (cpu_has_veic) {
set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
} else { } else {
#endif
if (cpu_has_vint) if (cpu_has_vint)
set_vi_handler(cp0_compare_irq, mips_timer_dispatch); set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
} }
/* we are using the cpu counter for timer interrupts */ return mips_cpu_timer_irq;
setup_irq(mips_cpu_timer_irq, irq); }
#ifdef CONFIG_SMP void __init plat_time_init(void)
/* irq_desc(riptor) is a global resource, when the interrupt overlaps {
on seperate cpu's the first one tries to handle the second interrupt. unsigned int est_freq, flags;
The effect is that the int remains disabled on the second cpu.
Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ local_irq_save(flags);
irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU;
set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); /* Set Data mode - binary. */
#endif CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
est_freq = estimate_cpu_frequency();
printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
(est_freq % 1000000) * 100 / 1000000);
cpu_khz = est_freq / 1000;
local_irq_restore(flags);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Tx39XX R4k style caches added. HK * Tx39XX R4k style caches added. HK
* Copyright (C) 1998, 1999, 2000 Harald Koerfgen * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
* Copyright (C) 2001, 2004 Maciej W. Rozycki * Copyright (C) 2001, 2004, 2007 Maciej W. Rozycki
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
static unsigned long icache_size, dcache_size; /* Size in bytes */ static unsigned long icache_size, dcache_size; /* Size in bytes */
static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */
#undef DEBUG_CACHE
unsigned long __init r3k_cache_size(unsigned long ca_flags) unsigned long __init r3k_cache_size(unsigned long ca_flags)
{ {
unsigned long flags, status, dummy, size; unsigned long flags, status, dummy, size;
...@@ -217,26 +215,6 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end) ...@@ -217,26 +215,6 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
write_c0_status(flags); write_c0_status(flags);
} }
static inline unsigned long get_phys_page(unsigned long addr,
struct mm_struct *mm)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long physpage;
pgd = pgd_offset(mm, addr);
pud = pud_offset(pgd, addr);
pmd = pmd_offset(pud, addr);
pte = pte_offset(pmd, addr);
if ((physpage = pte_val(*pte)) & _PAGE_VALID)
return KSEG0ADDR(physpage & PAGE_MASK);
return 0;
}
static inline void r3k_flush_cache_all(void) static inline void r3k_flush_cache_all(void)
{ {
} }
...@@ -252,12 +230,40 @@ static void r3k_flush_cache_mm(struct mm_struct *mm) ...@@ -252,12 +230,40 @@ static void r3k_flush_cache_mm(struct mm_struct *mm)
} }
static void r3k_flush_cache_range(struct vm_area_struct *vma, static void r3k_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end) unsigned long start, unsigned long end)
{ {
} }
static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn) static void r3k_flush_cache_page(struct vm_area_struct *vma,
unsigned long addr, unsigned long pfn)
{ {
unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT);
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
pr_debug("cpage[%08lx,%08lx]\n",
cpu_context(smp_processor_id(), mm), addr);
/* No ASID => no such page in the cache. */
if (cpu_context(smp_processor_id(), mm) == 0)
return;
pgdp = pgd_offset(mm, addr);
pudp = pud_offset(pgdp, addr);
pmdp = pmd_offset(pudp, addr);
ptep = pte_offset(pmdp, addr);
/* Invalid => no such page in the cache. */
if (!(pte_val(*ptep) & _PAGE_PRESENT))
return;
r3k_flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
if (exec)
r3k_flush_icache_range(kaddr, kaddr + PAGE_SIZE);
} }
static void local_r3k_flush_data_cache_page(void *addr) static void local_r3k_flush_data_cache_page(void *addr)
...@@ -272,9 +278,7 @@ static void r3k_flush_cache_sigtramp(unsigned long addr) ...@@ -272,9 +278,7 @@ static void r3k_flush_cache_sigtramp(unsigned long addr)
{ {
unsigned long flags; unsigned long flags;
#ifdef DEBUG_CACHE pr_debug("csigtramp[%08lx]\n", addr);
printk("csigtramp[%08lx]", addr);
#endif
flags = read_c0_status(); flags = read_c0_status();
......
...@@ -345,11 +345,26 @@ static void r4k___flush_cache_all(void) ...@@ -345,11 +345,26 @@ static void r4k___flush_cache_all(void)
r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1); r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
} }
static inline int has_valid_asid(const struct mm_struct *mm)
{
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
int i;
for_each_online_cpu(i)
if (cpu_context(i, mm))
return 1;
return 0;
#else
return cpu_context(smp_processor_id(), mm);
#endif
}
static inline void local_r4k_flush_cache_range(void * args) static inline void local_r4k_flush_cache_range(void * args)
{ {
struct vm_area_struct *vma = args; struct vm_area_struct *vma = args;
if (!(cpu_context(smp_processor_id(), vma->vm_mm))) if (!(has_valid_asid(vma->vm_mm)))
return; return;
r4k_blast_dcache(); r4k_blast_dcache();
...@@ -368,7 +383,7 @@ static inline void local_r4k_flush_cache_mm(void * args) ...@@ -368,7 +383,7 @@ static inline void local_r4k_flush_cache_mm(void * args)
{ {
struct mm_struct *mm = args; struct mm_struct *mm = args;
if (!cpu_context(smp_processor_id(), mm)) if (!has_valid_asid(mm))
return; return;
/* /*
...@@ -420,7 +435,7 @@ static inline void local_r4k_flush_cache_page(void *args) ...@@ -420,7 +435,7 @@ static inline void local_r4k_flush_cache_page(void *args)
* If ownes no valid ASID yet, cannot possibly have gotten * If ownes no valid ASID yet, cannot possibly have gotten
* this page into the cache. * this page into the cache.
*/ */
if (cpu_context(smp_processor_id(), mm) == 0) if (!has_valid_asid(mm))
return; return;
addr &= PAGE_MASK; addr &= PAGE_MASK;
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/string.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/string.h>
#include <asm/cache.h> #include <asm/cache.h>
#include <asm/io.h> #include <asm/io.h>
......
...@@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) ...@@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
* RETURNS: IRQ number * RETURNS: IRQ number
* *
****************************************************************************/ ****************************************************************************/
int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{ {
#if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) #if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL)
printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n");
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups. * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
* *
* Copyright (C) 2003 Megasolution Inc. <matsu@megasolution.jp> * Copyright (C) 2003 Megasolution Inc. <matsu@megasolution.jp>
* Copyright (C) 2004 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> * Copyright (C) 2004-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
......
...@@ -404,7 +404,7 @@ int msp_pcibios_config_access(unsigned char access_type, ...@@ -404,7 +404,7 @@ int msp_pcibios_config_access(unsigned char access_type,
if (pciirqflag == 0) { if (pciirqflag == 0) {
request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */ request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
bpci_interrupt, bpci_interrupt,
SA_SHIRQ | SA_INTERRUPT, IRQF_SHARED | IRQF_DISABLED,
"PMC MSP PCI Host", "PMC MSP PCI Host",
preg); preg);
pciirqflag = ~0; pciirqflag = ~0;
......
...@@ -122,7 +122,7 @@ void __init msp_serial_setup(void) ...@@ -122,7 +122,7 @@ void __init msp_serial_setup(void)
up.uartclk = uartclk; up.uartclk = uartclk;
up.regshift = 2; up.regshift = 2;
up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ up.iotype = UPIO_DWAPB; /* UPIO_MEM like */
up.flags = STD_COM_FLAGS; up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
up.type = PORT_16550A; up.type = PORT_16550A;
up.line = 0; up.line = 0;
up.private_data = (void*)UART0_STATUS_REG; up.private_data = (void*)UART0_STATUS_REG;
......
...@@ -131,12 +131,12 @@ static struct irq_chip rt_irq_type = { ...@@ -131,12 +131,12 @@ static struct irq_chip rt_irq_type = {
static int rt_next_event(unsigned long delta, struct clock_event_device *evt) static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
int slice = cputoslice(cpu) == 0; int slice putoslice(cpu);
unsigned long cnt; unsigned long cnt;
cnt = LOCAL_HUB_L(PI_RT_COUNT); cnt = LOCAL_HUB_L(PI_RT_COUNT);
cnt += delta; cnt += delta;
LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt); LOCAL_HUB_S(PI_RT_COMPARE_A + PI_COUNT_OFFSET * slice, cnt);
return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0; return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
} }
...@@ -164,9 +164,12 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) ...@@ -164,9 +164,12 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
{ {
struct clock_event_device *cd = dev_id; struct clock_event_device *cd = dev_id;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
int slice = cputoslice(cpu) == 0; int slice = cputoslice(cpu);
LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ /*
* Ack
*/
LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, cnt);
cd->event_handler(cd); cd->event_handler(cd);
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -40,13 +40,6 @@ static void inline flush_mace_bus(void) ...@@ -40,13 +40,6 @@ static void inline flush_mace_bus(void)
mace->perif.ctrl.misc; mace->perif.ctrl.misc;
} }
#undef DEBUG_IRQ
#ifdef DEBUG_IRQ
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
/* /*
* O2 irq map * O2 irq map
* *
...@@ -125,6 +118,7 @@ struct irqaction memerr_irq = { ...@@ -125,6 +118,7 @@ struct irqaction memerr_irq = {
.mask = CPU_MASK_NONE, .mask = CPU_MASK_NONE,
.name = "CRIME memory error", .name = "CRIME memory error",
}; };
struct irqaction cpuerr_irq = { struct irqaction cpuerr_irq = {
.handler = crime_cpuerr_intr, .handler = crime_cpuerr_intr,
.flags = IRQF_DISABLED, .flags = IRQF_DISABLED,
...@@ -139,46 +133,70 @@ struct irqaction cpuerr_irq = { ...@@ -139,46 +133,70 @@ struct irqaction cpuerr_irq = {
static uint64_t crime_mask; static uint64_t crime_mask;
static void enable_crime_irq(unsigned int irq) static inline void crime_enable_irq(unsigned int irq)
{ {
crime_mask |= 1 << (irq - 1); unsigned int bit = irq - CRIME_IRQ_BASE;
crime_mask |= 1 << bit;
crime->imask = crime_mask; crime->imask = crime_mask;
} }
static void disable_crime_irq(unsigned int irq) static inline void crime_disable_irq(unsigned int irq)
{ {
crime_mask &= ~(1 << (irq - 1)); unsigned int bit = irq - CRIME_IRQ_BASE;
crime_mask &= ~(1 << bit);
crime->imask = crime_mask; crime->imask = crime_mask;
flush_crime_bus(); flush_crime_bus();
} }
static void mask_and_ack_crime_irq(unsigned int irq) static void crime_level_mask_and_ack_irq(unsigned int irq)
{
crime_disable_irq(irq);
}
static void crime_level_end_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
crime_enable_irq(irq);
}
static struct irq_chip crime_level_interrupt = {
.name = "IP32 CRIME",
.ack = crime_level_mask_and_ack_irq,
.mask = crime_disable_irq,
.mask_ack = crime_level_mask_and_ack_irq,
.unmask = crime_enable_irq,
.end = crime_level_end_irq,
};
static void crime_edge_mask_and_ack_irq(unsigned int irq)
{ {
unsigned int bit = irq - CRIME_IRQ_BASE;
uint64_t crime_int;
/* Edge triggered interrupts must be cleared. */ /* Edge triggered interrupts must be cleared. */
if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ)
|| (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) crime_int = crime->hard_int;
|| (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { crime_int &= ~(1 << bit);
uint64_t crime_int; crime->hard_int = crime_int;
crime_int = crime->hard_int;
crime_int &= ~(1 << (irq - 1)); crime_disable_irq(irq);
crime->hard_int = crime_int;
}
disable_crime_irq(irq);
} }
static void end_crime_irq(unsigned int irq) static void crime_edge_end_irq(unsigned int irq)
{ {
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_crime_irq(irq); crime_enable_irq(irq);
} }
static struct irq_chip ip32_crime_interrupt = { static struct irq_chip crime_edge_interrupt = {
.name = "IP32 CRIME", .name = "IP32 CRIME",
.ack = mask_and_ack_crime_irq, .ack = crime_edge_mask_and_ack_irq,
.mask = disable_crime_irq, .mask = crime_disable_irq,
.mask_ack = mask_and_ack_crime_irq, .mask_ack = crime_edge_mask_and_ack_irq,
.unmask = enable_crime_irq, .unmask = crime_enable_irq,
.end = end_crime_irq, .end = crime_edge_end_irq,
}; };
/* /*
...@@ -265,7 +283,7 @@ static void enable_maceisa_irq(unsigned int irq) ...@@ -265,7 +283,7 @@ static void enable_maceisa_irq(unsigned int irq)
{ {
unsigned int crime_int = 0; unsigned int crime_int = 0;
DBG("maceisa enable: %u\n", irq); pr_debug("maceisa enable: %u\n", irq);
switch (irq) { switch (irq) {
case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
...@@ -278,7 +296,7 @@ static void enable_maceisa_irq(unsigned int irq) ...@@ -278,7 +296,7 @@ static void enable_maceisa_irq(unsigned int irq)
crime_int = MACE_SUPERIO_INT; crime_int = MACE_SUPERIO_INT;
break; break;
} }
DBG("crime_int %08x enabled\n", crime_int); pr_debug("crime_int %08x enabled\n", crime_int);
crime_mask |= crime_int; crime_mask |= crime_int;
crime->imask = crime_mask; crime->imask = crime_mask;
maceisa_mask |= 1 << (irq - 33); maceisa_mask |= 1 << (irq - 33);
...@@ -290,11 +308,11 @@ static void disable_maceisa_irq(unsigned int irq) ...@@ -290,11 +308,11 @@ static void disable_maceisa_irq(unsigned int irq)
unsigned int crime_int = 0; unsigned int crime_int = 0;
maceisa_mask &= ~(1 << (irq - 33)); maceisa_mask &= ~(1 << (irq - 33));
if(!(maceisa_mask & MACEISA_AUDIO_INT)) if (!(maceisa_mask & MACEISA_AUDIO_INT))
crime_int |= MACE_AUDIO_INT; crime_int |= MACE_AUDIO_INT;
if(!(maceisa_mask & MACEISA_MISC_INT)) if (!(maceisa_mask & MACEISA_MISC_INT))
crime_int |= MACE_MISC_INT; crime_int |= MACE_MISC_INT;
if(!(maceisa_mask & MACEISA_SUPERIO_INT)) if (!(maceisa_mask & MACEISA_SUPERIO_INT))
crime_int |= MACE_SUPERIO_INT; crime_int |= MACE_SUPERIO_INT;
crime_mask &= ~crime_int; crime_mask &= ~crime_int;
crime->imask = crime_mask; crime->imask = crime_mask;
...@@ -327,12 +345,12 @@ static void end_maceisa_irq(unsigned irq) ...@@ -327,12 +345,12 @@ static void end_maceisa_irq(unsigned irq)
} }
static struct irq_chip ip32_maceisa_interrupt = { static struct irq_chip ip32_maceisa_interrupt = {
.name = "IP32 MACE ISA", .name = "IP32 MACE ISA",
.ack = mask_and_ack_maceisa_irq, .ack = mask_and_ack_maceisa_irq,
.mask = disable_maceisa_irq, .mask = disable_maceisa_irq,
.mask_ack = mask_and_ack_maceisa_irq, .mask_ack = mask_and_ack_maceisa_irq,
.unmask = enable_maceisa_irq, .unmask = enable_maceisa_irq,
.end = end_maceisa_irq, .end = end_maceisa_irq,
}; };
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means /* This is used for regular non-ISA, non-PCI MACE interrupts. That means
...@@ -411,7 +429,7 @@ static void ip32_irq0(void) ...@@ -411,7 +429,7 @@ static void ip32_irq0(void)
irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ; irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
} }
DBG("*irq %u*\n", irq); pr_debug("*irq %u*\n", irq);
do_IRQ(irq); do_IRQ(irq);
} }
...@@ -472,23 +490,31 @@ void __init arch_init_irq(void) ...@@ -472,23 +490,31 @@ void __init arch_init_irq(void)
mips_cpu_irq_init(); mips_cpu_irq_init();
for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) { for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) {
struct irq_chip *chip;
switch (irq) { switch (irq) {
case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ: case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
chip = &ip32_mace_interrupt; set_irq_chip(irq, &ip32_mace_interrupt);
break; break;
case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ: case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
chip = &ip32_macepci_interrupt; set_irq_chip(irq, &ip32_macepci_interrupt);
break;
case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
set_irq_chip(irq, &crime_edge_interrupt);
break;
case CRIME_CPUERR_IRQ:
case CRIME_MEMERR_IRQ:
set_irq_chip(irq, &crime_level_interrupt);
break; break;
case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ: case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
chip = &ip32_crime_interrupt; case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
set_irq_chip(irq, &crime_edge_interrupt);
break;
case CRIME_VICE_IRQ:
set_irq_chip(irq, &crime_edge_interrupt);
break; break;
default: default:
chip = &ip32_maceisa_interrupt; set_irq_chip(irq, &ip32_maceisa_interrupt);
break;
} }
set_irq_chip(irq, chip);
} }
setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
......
...@@ -280,27 +280,6 @@ static struct irqaction bcm1480_dummy_action = { ...@@ -280,27 +280,6 @@ static struct irqaction bcm1480_dummy_action = {
.dev_id = 0 .dev_id = 0
}; };
int bcm1480_steal_irq(int irq)
{
struct irq_desc *desc = irq_desc + irq;
unsigned long flags;
int retval = 0;
if (irq >= BCM1480_NR_IRQS)
return -EINVAL;
spin_lock_irqsave(&desc->lock, flags);
/* Don't allow sharing at all for these */
if (desc->action != NULL)
retval = -EBUSY;
else {
desc->action = &bcm1480_dummy_action;
desc->depth = 0;
}
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
/* /*
* init_IRQ is called early in the boot sequence from init/main.c. It * init_IRQ is called early in the boot sequence from init/main.c. It
* is responsible for setting up the interrupt mapper and installing the * is responsible for setting up the interrupt mapper and installing the
...@@ -386,8 +365,6 @@ void __init arch_init_irq(void) ...@@ -386,8 +365,6 @@ void __init arch_init_irq(void)
__raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L))); __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
} }
bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
/* /*
* Note that the timer interrupts are also mapped, but this is * Note that the timer interrupts are also mapped, but this is
* done in bcm1480_time_init(). Also, the profiling driver * done in bcm1480_time_init(). Also, the profiling driver
...@@ -411,7 +388,6 @@ void __init arch_init_irq(void) ...@@ -411,7 +388,6 @@ void __init arch_init_irq(void)
/* QQQ FIXME */ /* QQQ FIXME */
__raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port)); __raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
bcm1480_steal_irq(kgdb_irq);
__raw_writeq(IMR_IP6_VAL, __raw_writeq(IMR_IP6_VAL,
IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
(kgdb_irq<<3)); (kgdb_irq<<3));
......
...@@ -37,8 +37,6 @@ ...@@ -37,8 +37,6 @@
#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
extern int bcm1480_steal_irq(int irq);
/* /*
* The general purpose timer ticks at 1MHz independent if * The general purpose timer ticks at 1MHz independent if
* the rest of the system * the rest of the system
...@@ -121,7 +119,7 @@ void __cpuinit sb1480_clockevent_init(void) ...@@ -121,7 +119,7 @@ void __cpuinit sb1480_clockevent_init(void)
sprintf(name, "bcm1480-counter %d", cpu); sprintf(name, "bcm1480-counter %d", cpu);
cd->name = name; cd->name = name;
cd->features = CLOCK_EVT_FEAT_PERIODIC | cd->features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_MODE_ONESHOT; CLOCK_EVT_FEAT_ONESHOT;
clockevent_set_clock(cd, V_SCD_TIMER_FREQ); clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
cd->min_delta_ns = clockevent_delta2ns(1, cd); cd->min_delta_ns = clockevent_delta2ns(1, cd);
...@@ -142,7 +140,6 @@ void __cpuinit sb1480_clockevent_init(void) ...@@ -142,7 +140,6 @@ void __cpuinit sb1480_clockevent_init(void)
R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3))); R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
bcm1480_unmask_irq(cpu, irq); bcm1480_unmask_irq(cpu, irq);
bcm1480_steal_irq(irq);
action->handler = sibyte_counter_handler; action->handler = sibyte_counter_handler;
action->flags = IRQF_DISABLED | IRQF_PERCPU; action->flags = IRQF_DISABLED | IRQF_PERCPU;
......
...@@ -250,27 +250,6 @@ static struct irqaction sb1250_dummy_action = { ...@@ -250,27 +250,6 @@ static struct irqaction sb1250_dummy_action = {
.dev_id = 0 .dev_id = 0
}; };
int sb1250_steal_irq(int irq)
{
struct irq_desc *desc = irq_desc + irq;
unsigned long flags;
int retval = 0;
if (irq >= SB1250_NR_IRQS)
return -EINVAL;
spin_lock_irqsave(&desc->lock, flags);
/* Don't allow sharing at all for these */
if (desc->action != NULL)
retval = -EBUSY;
else {
desc->action = &sb1250_dummy_action;
desc->depth = 0;
}
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
/* /*
* arch_init_irq is called early in the boot sequence from init/main.c via * arch_init_irq is called early in the boot sequence from init/main.c via
* init_IRQ. It is responsible for setting up the interrupt mapper and * init_IRQ. It is responsible for setting up the interrupt mapper and
...@@ -342,8 +321,6 @@ void __init arch_init_irq(void) ...@@ -342,8 +321,6 @@ void __init arch_init_irq(void)
__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK))); __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK))); __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
sb1250_steal_irq(K_INT_MBOX_0);
/* /*
* Note that the timer interrupts are also mapped, but this is * Note that the timer interrupts are also mapped, but this is
* done in sb1250_time_init(). Also, the profiling driver * done in sb1250_time_init(). Also, the profiling driver
...@@ -367,7 +344,6 @@ void __init arch_init_irq(void) ...@@ -367,7 +344,6 @@ void __init arch_init_irq(void)
__raw_writeq(M_DUART_IMR_BRK, __raw_writeq(M_DUART_IMR_BRK,
IOADDR(A_DUART_IMRREG(kgdb_port))); IOADDR(A_DUART_IMRREG(kgdb_port)));
sb1250_steal_irq(kgdb_irq);
__raw_writeq(IMR_IP6_VAL, __raw_writeq(IMR_IP6_VAL,
IOADDR(A_IMR_REGISTER(0, IOADDR(A_IMR_REGISTER(0,
R_IMR_INTERRUPT_MAP_BASE) + R_IMR_INTERRUPT_MAP_BASE) +
......
...@@ -50,8 +50,6 @@ ...@@ -50,8 +50,6 @@
#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */
extern int sb1250_steal_irq(int irq);
/* /*
* The general purpose timer ticks at 1 Mhz independent if * The general purpose timer ticks at 1 Mhz independent if
* the rest of the system * the rest of the system
...@@ -139,7 +137,7 @@ void __cpuinit sb1250_clockevent_init(void) ...@@ -139,7 +137,7 @@ void __cpuinit sb1250_clockevent_init(void)
sprintf(name, "bcm1480-counter %d", cpu); sprintf(name, "bcm1480-counter %d", cpu);
cd->name = name; cd->name = name;
cd->features = CLOCK_EVT_FEAT_PERIODIC | cd->features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_MODE_ONESHOT; CLOCK_EVT_FEAT_ONESHOT;
clockevent_set_clock(cd, V_SCD_TIMER_FREQ); clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
cd->min_delta_ns = clockevent_delta2ns(1, cd); cd->min_delta_ns = clockevent_delta2ns(1, cd);
...@@ -159,7 +157,6 @@ void __cpuinit sb1250_clockevent_init(void) ...@@ -159,7 +157,6 @@ void __cpuinit sb1250_clockevent_init(void)
cd->cpumask = cpumask_of_cpu(0); cd->cpumask = cpumask_of_cpu(0);
sb1250_unmask_irq(cpu, irq); sb1250_unmask_irq(cpu, irq);
sb1250_steal_irq(irq);
action->handler = sibyte_counter_handler; action->handler = sibyte_counter_handler;
action->flags = IRQF_DISABLED | IRQF_PERCPU; action->flags = IRQF_DISABLED | IRQF_PERCPU;
......
...@@ -11,27 +11,78 @@ ...@@ -11,27 +11,78 @@
#define SNI_COUNTER2_DIV 64 #define SNI_COUNTER2_DIV 64
#define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ) #define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
static void sni_a20r_timer_ack(void) static void a20r_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{ {
*(volatile u8 *)A20R_PT_TIM0_ACK = 0x0; wmb(); switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;
wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV;
wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8;
wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4;
wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV;
wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8;
wmb();
break;
case CLOCK_EVT_MODE_ONESHOT:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
break;
case CLOCK_EVT_MODE_RESUME:
break;
}
} }
static struct clock_event_device a20r_clockevent_device = {
.name = "a20r-timer",
.features = CLOCK_EVT_FEAT_PERIODIC,
/* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
.rating = 300,
.irq = SNI_A20R_IRQ_TIMER,
.set_mode = a20r_set_mode,
};
static irqreturn_t a20r_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd = dev_id;
*(volatile u8 *)A20R_PT_TIM0_ACK = 0;
wmb();
cd->event_handler(cd);
return IRQ_HANDLED;
}
static struct irqaction a20r_irqaction = {
.handler = a20r_interrupt,
.flags = IRQF_DISABLED | IRQF_PERCPU,
.name = "a20r-timer",
};
/* /*
* a20r platform uses 2 counters to divide the input frequency. * a20r platform uses 2 counters to divide the input frequency.
* Counter 2 output is connected to Counter 0 & 1 input. * Counter 2 output is connected to Counter 0 & 1 input.
*/ */
static void __init sni_a20r_timer_setup(struct irqaction *irq) static void __init sni_a20r_timer_setup(void)
{ {
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb(); struct clock_event_device *cd = &a20r_clockevent_device;
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV) & 0xff; wmb(); struct irqaction *action = &a20r_irqaction;
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb(); unsigned int cpu = smp_processor_id();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb(); cd->cpumask = cpumask_of_cpu(cpu);
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV) & 0xff; wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV >> 8) & 0xff; wmb();
setup_irq(SNI_A20R_IRQ_TIMER, irq); action->dev_id = cd;
mips_timer_ack = sni_a20r_timer_ack; setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction);
} }
#define SNI_8254_TICK_RATE 1193182UL #define SNI_8254_TICK_RATE 1193182UL
...@@ -119,17 +170,14 @@ void __init plat_time_init(void) ...@@ -119,17 +170,14 @@ void __init plat_time_init(void)
mips_hpt_frequency = r4k_tick * HZ; mips_hpt_frequency = r4k_tick * HZ;
setup_pit_timer(); setup_pit_timer();
}
void __init plat_timer_setup(struct irqaction *irq)
{
switch (sni_brd_type) { switch (sni_brd_type) {
case SNI_BRD_10: case SNI_BRD_10:
case SNI_BRD_10NEW: case SNI_BRD_10NEW:
case SNI_BRD_TOWER_OASIC: case SNI_BRD_TOWER_OASIC:
case SNI_BRD_MINITOWER: case SNI_BRD_MINITOWER:
sni_a20r_timer_setup(irq); sni_a20r_timer_setup();
break; break;
} }
} }
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/txx9tmr.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#ifdef CONFIG_TOSHIBA_FPCIB0 #ifdef CONFIG_TOSHIBA_FPCIB0
...@@ -93,7 +94,6 @@ ...@@ -93,7 +94,6 @@
#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) #define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )
#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) #define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 )
#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 )
#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) #define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 )
#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) #define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 )
#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) #define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )
...@@ -130,7 +130,6 @@ extern void toshiba_rbtx4927_power_off(void); ...@@ -130,7 +130,6 @@ extern void toshiba_rbtx4927_power_off(void);
int tx4927_using_backplane = 0; int tx4927_using_backplane = 0;
extern void gt64120_time_init(void);
extern void toshiba_rbtx4927_irq_setup(void); extern void toshiba_rbtx4927_irq_setup(void);
char *prom_getcmdline(void); char *prom_getcmdline(void);
...@@ -721,6 +720,7 @@ void toshiba_rbtx4927_power_off(void) ...@@ -721,6 +720,7 @@ void toshiba_rbtx4927_power_off(void)
void __init toshiba_rbtx4927_setup(void) void __init toshiba_rbtx4927_setup(void)
{ {
int i;
u32 cp0_config; u32 cp0_config;
char *argptr; char *argptr;
...@@ -764,6 +764,9 @@ void __init toshiba_rbtx4927_setup(void) ...@@ -764,6 +764,9 @@ void __init toshiba_rbtx4927_setup(void)
_machine_halt = toshiba_rbtx4927_halt; _machine_halt = toshiba_rbtx4927_halt;
pm_power_off = toshiba_rbtx4927_power_off; pm_power_off = toshiba_rbtx4927_power_off;
for (i = 0; i < TX4927_NR_TMR; i++)
txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/* PCIC */ /* PCIC */
...@@ -892,7 +895,6 @@ void __init toshiba_rbtx4927_setup(void) ...@@ -892,7 +895,6 @@ void __init toshiba_rbtx4927_setup(void)
#ifdef CONFIG_SERIAL_TXX9 #ifdef CONFIG_SERIAL_TXX9
{ {
extern int early_serial_txx9_setup(struct uart_port *port); extern int early_serial_txx9_setup(struct uart_port *port);
int i;
struct uart_port req; struct uart_port req;
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
...@@ -937,12 +939,11 @@ void __init toshiba_rbtx4927_setup(void) ...@@ -937,12 +939,11 @@ void __init toshiba_rbtx4927_setup(void)
void __init void __init
toshiba_rbtx4927_time_init(void) toshiba_rbtx4927_time_init(void)
{ {
TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n");
mips_hpt_frequency = tx4927_cpu_clock / 2; mips_hpt_frequency = tx4927_cpu_clock / 2;
if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS)
TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL,
TXX9_IRQ_BASE + 17,
50000000);
} }
static int __init toshiba_rbtx4927_rtc_init(void) static int __init toshiba_rbtx4927_rtc_init(void)
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/time.h> #include <asm/time.h>
#include <asm/txx9tmr.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
...@@ -773,15 +774,8 @@ void __init tx4938_board_setup(void) ...@@ -773,15 +774,8 @@ void __init tx4938_board_setup(void)
} }
/* TMR */ /* TMR */
/* disable all timers */ for (i = 0; i < TX4938_NR_TMR; i++)
for (i = 0; i < TX4938_NR_TMR; i++) { txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
tx4938_tmrptr(i)->tcr = 0x00000020;
tx4938_tmrptr(i)->tisr = 0;
tx4938_tmrptr(i)->cpra = 0xffffffff;
tx4938_tmrptr(i)->itmr = 0;
tx4938_tmrptr(i)->ccdr = 0;
tx4938_tmrptr(i)->pgmr = 0;
}
/* enable DMA */ /* enable DMA */
TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN); TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
...@@ -852,12 +846,13 @@ void tx4938_report_pcic_status(void) ...@@ -852,12 +846,13 @@ void tx4938_report_pcic_status(void)
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
/* We use onchip r4k counter or TMR timer as our system wide timer
* interrupt running at 100HZ. */
void __init plat_time_init(void) void __init plat_time_init(void)
{ {
mips_hpt_frequency = txx9_cpu_clock / 2; mips_hpt_frequency = txx9_cpu_clock / 2;
if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS)
txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL,
TXX9_IRQ_BASE + TX4938_IR_TMR(0),
txx9_gbus_clock / 2);
} }
void __init toshiba_rbtx4938_setup(void) void __init toshiba_rbtx4938_setup(void)
......
...@@ -22,10 +22,12 @@ enum ip32_irq_no { ...@@ -22,10 +22,12 @@ enum ip32_irq_no {
* CPU interrupts are 0 ... 7 * CPU interrupts are 0 ... 7
*/ */
CRIME_IRQ_BASE = MIPS_CPU_IRQ_BASE,
/* /*
* MACE * MACE
*/ */
MACE_VID_IN1_IRQ = MIPS_CPU_IRQ_BASE + 8, MACE_VID_IN1_IRQ = CRIME_IRQ_BASE,
MACE_VID_IN2_IRQ, MACE_VID_IN2_IRQ,
MACE_VID_OUT_IRQ, MACE_VID_OUT_IRQ,
MACE_ETHERNET_IRQ, MACE_ETHERNET_IRQ,
......
...@@ -132,9 +132,7 @@ ...@@ -132,9 +132,7 @@
#define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA) #define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA)
#define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO) #define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO)
#define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI) #define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI)
#define JMR3927_IRQ_IRC_TMR0 (JMR3927_IRQ_IRC + TX3927_IR_TMR0) #define JMR3927_IRQ_IRC_TMR(ch) (JMR3927_IRQ_IRC + TX3927_IR_TMR(ch))
#define JMR3927_IRQ_IRC_TMR1 (JMR3927_IRQ_IRC + TX3927_IR_TMR1)
#define JMR3927_IRQ_IRC_TMR2 (JMR3927_IRQ_IRC + TX3927_IR_TMR2)
#define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA) #define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA)
#define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB) #define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB)
#define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC) #define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC)
...@@ -148,17 +146,12 @@ ...@@ -148,17 +146,12 @@
#define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1 #define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1
/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */ /* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */
#define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3 #define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3
/* Clock Tick (10ms) */
#define JMR3927_IRQ_TICK JMR3927_IRQ_IRC_TMR0
/* Clocks */ /* Clocks */
#define JMR3927_CORECLK 132710400 /* 132.7MHz */ #define JMR3927_CORECLK 132710400 /* 132.7MHz */
#define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */ #define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */
#define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */ #define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */
#define jmr3927_tmrptr tx3927_tmrptr(0) /* TMR0 */
/* /*
* TX3927 Pin Configuration: * TX3927 Pin Configuration:
* *
......
...@@ -222,9 +222,7 @@ struct tx3927_ccfg_reg { ...@@ -222,9 +222,7 @@ struct tx3927_ccfg_reg {
#define TX3927_IR_DMA 8 #define TX3927_IR_DMA 8
#define TX3927_IR_PIO 9 #define TX3927_IR_PIO 9
#define TX3927_IR_PCI 10 #define TX3927_IR_PCI 10
#define TX3927_IR_TMR0 13 #define TX3927_IR_TMR(ch) (13 + (ch))
#define TX3927_IR_TMR1 14
#define TX3927_IR_TMR2 15
#define TX3927_NUM_IR 16 #define TX3927_NUM_IR 16
/* /*
......
...@@ -10,22 +10,6 @@ ...@@ -10,22 +10,6 @@
#ifndef __ASM_TXX927_H #ifndef __ASM_TXX927_H
#define __ASM_TXX927_H #define __ASM_TXX927_H
struct txx927_tmr_reg {
volatile unsigned long tcr;
volatile unsigned long tisr;
volatile unsigned long cpra;
volatile unsigned long cprb;
volatile unsigned long itmr;
volatile unsigned long unused0[3];
volatile unsigned long ccdr;
volatile unsigned long unused1[3];
volatile unsigned long pgmr;
volatile unsigned long unused2[3];
volatile unsigned long wtmr;
volatile unsigned long unused3[43];
volatile unsigned long trr;
};
struct txx927_sio_reg { struct txx927_sio_reg {
volatile unsigned long lcr; volatile unsigned long lcr;
volatile unsigned long dicr; volatile unsigned long dicr;
...@@ -50,27 +34,6 @@ struct txx927_pio_reg { ...@@ -50,27 +34,6 @@ struct txx927_pio_reg {
volatile unsigned long maskext; volatile unsigned long maskext;
}; };
/*
* TMR
*/
/* TMTCR : Timer Control */
#define TXx927_TMTCR_TCE 0x00000080
#define TXx927_TMTCR_CCDE 0x00000040
#define TXx927_TMTCR_CRE 0x00000020
#define TXx927_TMTCR_ECES 0x00000008
#define TXx927_TMTCR_CCS 0x00000004
#define TXx927_TMTCR_TMODE_MASK 0x00000003
#define TXx927_TMTCR_TMODE_ITVL 0x00000000
/* TMTISR : Timer Int. Status */
#define TXx927_TMTISR_TPIBS 0x00000004
#define TXx927_TMTISR_TPIAS 0x00000002
#define TXx927_TMTISR_TIIS 0x00000001
/* TMTITMR : Interval Timer Mode */
#define TXx927_TMTITMR_TIIE 0x00008000
#define TXx927_TMTITMR_TZCE 0x00000001
/* /*
* SIO * SIO
*/ */
......
...@@ -58,7 +58,6 @@ extern void local_timer_interrupt(int irq, void *dev_id); ...@@ -58,7 +58,6 @@ extern void local_timer_interrupt(int irq, void *dev_id);
*/ */
struct irqaction; struct irqaction;
extern void plat_time_init(void); extern void plat_time_init(void);
extern void plat_timer_setup(struct irqaction *irq);
/* /*
* mips_hpt_frequency - must be set if you intend to use an R4k-compatible * mips_hpt_frequency - must be set if you intend to use an R4k-compatible
...@@ -78,6 +77,7 @@ extern int (*perf_irq)(void); ...@@ -78,6 +77,7 @@ extern int (*perf_irq)(void);
*/ */
#ifdef CONFIG_CEVT_R4K #ifdef CONFIG_CEVT_R4K
extern void mips_clockevent_init(void); extern void mips_clockevent_init(void);
extern unsigned int __weak get_c0_compare_int(void);
#else #else
static inline void mips_clockevent_init(void) static inline void mips_clockevent_init(void)
{ {
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define __ASM_TX4927_TX4927_PCI_H #define __ASM_TX4927_TX4927_PCI_H
#define TX4927_CCFG_TOE 0x00004000 #define TX4927_CCFG_TOE 0x00004000
#define TX4927_CCFG_TINTDIS 0x01000000
#define TX4927_PCIMEM 0x08000000 #define TX4927_PCIMEM 0x08000000
#define TX4927_PCIMEM_SIZE 0x08000000 #define TX4927_PCIMEM_SIZE 0x08000000
...@@ -20,6 +21,8 @@ ...@@ -20,6 +21,8 @@
#define TX4927_PCIC_REG 0xff1fd000 #define TX4927_PCIC_REG 0xff1fd000
#define TX4927_CCFG_REG 0xff1fe000 #define TX4927_CCFG_REG 0xff1fe000
#define TX4927_IRC_REG 0xff1ff600 #define TX4927_IRC_REG 0xff1ff600
#define TX4927_NR_TMR 3
#define TX4927_TMR_REG(ch) (0xff1ff000 + (ch) * 0x100)
#define TX4927_CE3 0x17f00000 /* 1M */ #define TX4927_CE3 0x17f00000 /* 1M */
#define TX4927_PCIRESET_ADDR 0xbc00f006 #define TX4927_PCIRESET_ADDR 0xbc00f006
#define TX4927_PCI_CLK_ADDR (KSEG1 + TX4927_CE3 + 0x00040020) #define TX4927_PCI_CLK_ADDR (KSEG1 + TX4927_CE3 + 0x00040020)
......
...@@ -641,7 +641,6 @@ struct tx4938_ccfg_reg { ...@@ -641,7 +641,6 @@ struct tx4938_ccfg_reg {
#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG) #define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG) #define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG)
#define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG) #define tx4938_ccfgptr ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG)
#define tx4938_tmrptr(ch) ((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch))
#define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch)) #define tx4938_sioptr(ch) ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch))
#define tx4938_pioptr ((struct tx4938_pio_reg *)TX4938_PIO_REG) #define tx4938_pioptr ((struct tx4938_pio_reg *)TX4938_PIO_REG)
#define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG) #define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
......
/*
* include/asm-mips/txx9tmr.h
* TX39/TX49 timer controller definitions.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#ifndef __ASM_TXX9TMR_H
#define __ASM_TXX9TMR_H
#include <linux/types.h>
struct txx9_tmr_reg {
u32 tcr;
u32 tisr;
u32 cpra;
u32 cprb;
u32 itmr;
u32 unused0[3];
u32 ccdr;
u32 unused1[3];
u32 pgmr;
u32 unused2[3];
u32 wtmr;
u32 unused3[43];
u32 trr;
};
/* TMTCR : Timer Control */
#define TXx9_TMTCR_TCE 0x00000080
#define TXx9_TMTCR_CCDE 0x00000040
#define TXx9_TMTCR_CRE 0x00000020
#define TXx9_TMTCR_ECES 0x00000008
#define TXx9_TMTCR_CCS 0x00000004
#define TXx9_TMTCR_TMODE_MASK 0x00000003
#define TXx9_TMTCR_TMODE_ITVL 0x00000000
#define TXx9_TMTCR_TMODE_PGEN 0x00000001
#define TXx9_TMTCR_TMODE_WDOG 0x00000002
/* TMTISR : Timer Int. Status */
#define TXx9_TMTISR_TPIBS 0x00000004
#define TXx9_TMTISR_TPIAS 0x00000002
#define TXx9_TMTISR_TIIS 0x00000001
/* TMITMR : Interval Timer Mode */
#define TXx9_TMITMR_TIIE 0x00008000
#define TXx9_TMITMR_TZCE 0x00000001
/* TMWTMR : Watchdog Timer Mode */
#define TXx9_TMWTMR_TWIE 0x00008000
#define TXx9_TMWTMR_WDIS 0x00000080
#define TXx9_TMWTMR_TWC 0x00000001
void txx9_clocksource_init(unsigned long baseaddr,
unsigned int imbusclk);
void txx9_clockevent_init(unsigned long baseaddr, int irq,
unsigned int imbusclk);
void txx9_tmr_init(unsigned long baseaddr);
#ifdef CONFIG_CPU_TX39XX
#define TXX9_TIMER_BITS 24
#else
#define TXX9_TIMER_BITS 32
#endif
#endif /* __ASM_TXX9TMR_H */
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