mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-17 06:46:38 +07:00
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. ...
This commit is contained in:
commit
82798a17ad
@ -583,6 +583,7 @@ config SNI_RM
|
||||
|
||||
config TOSHIBA_JMR3927
|
||||
bool "Toshiba JMR-TX3927 board"
|
||||
select CEVT_TXX9
|
||||
select DMA_NONCOHERENT
|
||||
select HW_HAS_PCI
|
||||
select MIPS_TX3927
|
||||
@ -597,6 +598,7 @@ config TOSHIBA_JMR3927
|
||||
config TOSHIBA_RBTX4927
|
||||
bool "Toshiba RBTX49[23]7 board"
|
||||
select CEVT_R4K
|
||||
select CEVT_TXX9
|
||||
select DMA_NONCOHERENT
|
||||
select HAS_TXX9_SERIAL
|
||||
select HW_HAS_PCI
|
||||
@ -618,6 +620,7 @@ config TOSHIBA_RBTX4927
|
||||
config TOSHIBA_RBTX4938
|
||||
bool "Toshiba RBTX4938 board"
|
||||
select CEVT_R4K
|
||||
select CEVT_TXX9
|
||||
select DMA_NONCOHERENT
|
||||
select HAS_TXX9_SERIAL
|
||||
select HW_HAS_PCI
|
||||
@ -736,6 +739,9 @@ config CEVT_GT641XX
|
||||
config CEVT_R4K
|
||||
bool
|
||||
|
||||
config CEVT_TXX9
|
||||
bool
|
||||
|
||||
config CFE
|
||||
bool
|
||||
|
||||
|
@ -318,38 +318,6 @@ static struct irq_chip level_irq_type = {
|
||||
.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)
|
||||
{
|
||||
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
|
||||
|
@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(time_lock);
|
||||
unsigned long wtimer;
|
||||
|
||||
#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;
|
||||
int time_elapsed;
|
||||
@ -117,6 +117,13 @@ irqreturn_t counter0_irq(int irq, void *dev_id)
|
||||
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
|
||||
* timer ticks we have missed.
|
||||
*/
|
||||
@ -221,7 +228,7 @@ unsigned long cal_r4koff(void)
|
||||
return (cpu_speed / HZ);
|
||||
}
|
||||
|
||||
void __init plat_timer_setup(struct irqaction *irq)
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
unsigned int est_freq;
|
||||
|
||||
@ -255,15 +262,10 @@ void __init plat_timer_setup(struct irqaction *irq)
|
||||
* we do this.
|
||||
*/
|
||||
if (no_au1xxx_32khz) {
|
||||
unsigned int c0_status;
|
||||
|
||||
printk("WARNING: no 32KHz clock found.\n");
|
||||
|
||||
/* Ensure we get CPO_COUNTER interrupts.
|
||||
*/
|
||||
c0_status = read_c0_status();
|
||||
c0_status |= IE_IRQ5;
|
||||
write_c0_status(c0_status);
|
||||
/* Ensure we get CPO_COUNTER interrupts. */
|
||||
set_c0_status(IE_IRQ5);
|
||||
}
|
||||
else {
|
||||
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
|
||||
@ -280,7 +282,7 @@ void __init plat_timer_setup(struct irqaction *irq)
|
||||
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
|
||||
au_sync();
|
||||
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.
|
||||
*/
|
||||
|
@ -8,3 +8,4 @@
|
||||
#
|
||||
|
||||
lib-y := init.o board_setup.o irqmap.o
|
||||
obj-y := platform.o
|
||||
|
86
arch/mips/au1000/mtx-1/platform.c
Normal file
86
arch/mips/au1000/mtx-1/platform.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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);
|
||||
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)
|
||||
{
|
||||
const u32 modebit5 = ocd_readl(0x00e4);
|
||||
unsigned int
|
||||
mult = ((modebit5 >> 11) & 0x1f) + 2,
|
||||
div = ((modebit5 >> 16) & 0x1f) + 2;
|
||||
unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2,
|
||||
unsigned int 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#if defined(CONFIG_SERIAL_8250)
|
||||
|
@ -738,7 +738,6 @@ CONFIG_HW_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -714,7 +714,6 @@ CONFIG_HW_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -775,7 +775,6 @@ CONFIG_HW_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -811,7 +811,6 @@ CONFIG_SERIO_RAW=m
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -856,7 +856,6 @@ CONFIG_SERIO_RAW=m
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -731,7 +731,6 @@ CONFIG_HW_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -849,7 +849,6 @@ CONFIG_SERIO_RAW=m
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -842,7 +842,6 @@ CONFIG_SERIO_RAW=m
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
# CONFIG_AU1X00_GPIO is not set
|
||||
# CONFIG_TS_AU1X00_ADS7846 is not set
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
|
@ -468,7 +468,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
|
||||
#
|
||||
CONFIG_IDE_GENERIC=y
|
||||
# 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_BLK_DEV_IDEDMA is not set
|
||||
# CONFIG_IDEDMA_AUTO is not set
|
||||
|
@ -19,12 +19,6 @@
|
||||
|
||||
#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
|
||||
*
|
||||
|
@ -27,17 +27,13 @@
|
||||
* Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
|
||||
*/
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/ide.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/param.h> /* for HZ */
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -48,17 +44,13 @@
|
||||
#endif
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/txx9tmr.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/jmr3927/jmr3927.h>
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
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 */
|
||||
static int jmr3927_ccfg_toeon;
|
||||
|
||||
@ -93,66 +85,12 @@ static void jmr3927_machine_power_off(void)
|
||||
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)
|
||||
{
|
||||
struct clock_event_device *cd;
|
||||
|
||||
clocksource_mips.read = jmr3927_hpt_read;
|
||||
mips_hpt_frequency = JMR3927_TIMER_CLK;
|
||||
|
||||
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);
|
||||
txx9_clockevent_init(TX3927_TMR_REG(0),
|
||||
TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0),
|
||||
JMR3927_IMCLK);
|
||||
txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK);
|
||||
}
|
||||
|
||||
#define DO_WRITE_THROUGH
|
||||
@ -317,15 +255,8 @@ static void __init tx3927_setup(void)
|
||||
tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
|
||||
|
||||
/* TMR */
|
||||
/* disable all timers */
|
||||
for (i = 0; i < TX3927_NR_TMR; 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;
|
||||
}
|
||||
for (i = 0; i < TX3927_NR_TMR; i++)
|
||||
txx9_tmr_init(TX3927_TMR_REG(i));
|
||||
|
||||
/* DMA */
|
||||
tx3927_dmaptr->mcr = 0;
|
||||
|
@ -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_GT641XX) += cevt-gt641xx.o
|
||||
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
|
||||
|
||||
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
|
||||
irix5sys.o sysirix.o
|
||||
|
@ -49,10 +49,9 @@ int gt641xx_timer0_state(void)
|
||||
static int gt641xx_timer0_set_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 ctrl;
|
||||
|
||||
spin_lock_irqsave(>641xx_timer_lock, flags);
|
||||
spin_lock(>641xx_timer_lock);
|
||||
|
||||
ctrl = GT_READ(GT_TC_CONTROL_OFS);
|
||||
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,
|
||||
GT_WRITE(GT_TC0_OFS, delta);
|
||||
GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
|
||||
|
||||
spin_unlock_irqrestore(>641xx_timer_lock, flags);
|
||||
spin_unlock(>641xx_timer_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -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,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 ctrl;
|
||||
|
||||
spin_lock_irqsave(>641xx_timer_lock, flags);
|
||||
spin_lock(>641xx_timer_lock);
|
||||
|
||||
ctrl = GT_READ(GT_TC_CONTROL_OFS);
|
||||
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,
|
||||
|
||||
GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
|
||||
|
||||
spin_unlock_irqrestore(>641xx_timer_lock, flags);
|
||||
spin_unlock(>641xx_timer_lock);
|
||||
}
|
||||
|
||||
static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
|
||||
@ -133,9 +131,9 @@ static int __init gt641xx_timer0_clockevent_init(void)
|
||||
|
||||
cd = >641xx_timer0_clockevent;
|
||||
cd->rating = 200 + gt641xx_base_clock / 10000000;
|
||||
clockevent_set_clock(cd, gt641xx_base_clock);
|
||||
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
|
||||
cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
|
||||
clockevent_set_clock(cd, gt641xx_base_clock);
|
||||
|
||||
clockevents_register_device(>641xx_timer0_clockevent);
|
||||
|
||||
|
@ -28,7 +28,7 @@ static int mips_next_event(unsigned long delta,
|
||||
cnt = read_c0_count();
|
||||
cnt += delta;
|
||||
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
|
||||
evpe(vpflags);
|
||||
local_irq_restore(flags);
|
||||
@ -179,7 +179,7 @@ static int c0_compare_int_pending(void)
|
||||
|
||||
static int c0_compare_int_usable(void)
|
||||
{
|
||||
const unsigned int delta = 0x300000;
|
||||
unsigned int delta;
|
||||
unsigned int cnt;
|
||||
|
||||
/*
|
||||
@ -192,11 +192,17 @@ static int c0_compare_int_usable(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnt = read_c0_count();
|
||||
cnt += delta;
|
||||
write_c0_compare(cnt);
|
||||
for (delta = 0x10; delta <= 0x400000; delta <<= 1) {
|
||||
cnt = read_c0_count();
|
||||
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 */
|
||||
|
||||
if (!c0_compare_int_pending())
|
||||
@ -218,9 +224,9 @@ void __cpuinit mips_clockevent_init(void)
|
||||
uint64_t mips_freq = mips_hpt_frequency;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
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;
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
@ -237,6 +243,15 @@ void __cpuinit mips_clockevent_init(void)
|
||||
if (!c0_compare_int_usable())
|
||||
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->name = "MIPS";
|
||||
@ -261,13 +276,15 @@ void __cpuinit mips_clockevent_init(void)
|
||||
|
||||
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
|
||||
#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
|
||||
setup_irq(irq, &c0_compare_irqaction);
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
cp0_timer_irq_installed = 1;
|
||||
}
|
||||
setup_irq(irq, &c0_compare_irqaction);
|
||||
#endif
|
||||
}
|
||||
|
171
arch/mips/kernel/cevt-txx9.c
Normal file
171
arch/mips/kernel/cevt-txx9.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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 @@
|
||||
|
||||
#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 {
|
||||
unsigned long sig[4];
|
||||
unsigned long sig[_IRIX_NSIG_WORDS];
|
||||
} irix_sigset_t;
|
||||
|
||||
struct sigctx_irix5 {
|
||||
@ -527,7 +531,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
|
||||
|
||||
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]);
|
||||
|
||||
if (tmp)
|
||||
|
@ -65,13 +65,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)
|
||||
regs = task_pt_regs(child);
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
__put_user(regs->regs[i], data + i);
|
||||
__put_user(regs->lo, data + EF_LO - EF_R0);
|
||||
__put_user(regs->hi, data + EF_HI - EF_R0);
|
||||
__put_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
|
||||
__put_user(regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
|
||||
__put_user(regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
|
||||
__put_user(regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
|
||||
__put_user((long)regs->regs[i], data + i);
|
||||
__put_user((long)regs->lo, data + EF_LO - EF_R0);
|
||||
__put_user((long)regs->hi, data + EF_HI - EF_R0);
|
||||
__put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
|
||||
__put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
|
||||
__put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
|
||||
__put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -390,11 +390,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
}
|
||||
|
||||
case PTRACE_GETREGS:
|
||||
ret = ptrace_getregs(child, (__u64 __user *) data);
|
||||
ret = ptrace_getregs(child, (__s64 __user *) data);
|
||||
break;
|
||||
|
||||
case PTRACE_SETREGS:
|
||||
ret = ptrace_setregs(child, (__u64 __user *) data);
|
||||
ret = ptrace_setregs(child, (__s64 __user *) data);
|
||||
break;
|
||||
|
||||
case PTRACE_GETFPREGS:
|
||||
|
@ -346,11 +346,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
|
||||
}
|
||||
|
||||
case PTRACE_GETREGS:
|
||||
ret = ptrace_getregs(child, (__u64 __user *) (__u64) data);
|
||||
ret = ptrace_getregs(child, (__s64 __user *) (__u64) data);
|
||||
break;
|
||||
|
||||
case PTRACE_SETREGS:
|
||||
ret = ptrace_setregs(child, (__u64 __user *) (__u64) data);
|
||||
ret = ptrace_setregs(child, (__s64 __user *) (__u64) data);
|
||||
break;
|
||||
|
||||
case PTRACE_GETFPREGS:
|
||||
|
@ -88,11 +88,19 @@ unsigned int smtc_status = 0;
|
||||
|
||||
/* Boot command line configuration overrides */
|
||||
|
||||
static int vpe0limit;
|
||||
static int ipibuffers = 0;
|
||||
static int nostlb = 0;
|
||||
static int asidmask = 0;
|
||||
unsigned long smtc_asid_mask = 0xff;
|
||||
|
||||
static int __init vpe0tcs(char *str)
|
||||
{
|
||||
get_option(&str, &vpe0limit);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __init ipibufs(char *str)
|
||||
{
|
||||
get_option(&str, &ipibuffers);
|
||||
@ -125,6 +133,7 @@ static int __init asidmask_set(char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("vpe0tcs=", vpe0tcs);
|
||||
__setup("ipibufs=", ipibufs);
|
||||
__setup("nostlb", stlb_disable);
|
||||
__setup("asidmask=", asidmask_set);
|
||||
@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
|
||||
|
||||
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 val;
|
||||
int nipi;
|
||||
@ -401,8 +410,39 @@ void mipsmt_prepare_cpus(void)
|
||||
ntc = NR_CPUS;
|
||||
if (tclimit > 0 && ntc > tclimit)
|
||||
ntc = tclimit;
|
||||
tcpervpe = ntc / nvpe;
|
||||
slop = ntc % nvpe; /* Residual TCs, < NVPE */
|
||||
slop = ntc % 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 */
|
||||
smtc_configure_tlb();
|
||||
@ -416,7 +456,7 @@ void mipsmt_prepare_cpus(void)
|
||||
if (vpe != 0)
|
||||
printk(", ");
|
||||
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,
|
||||
* and is presumably executing this
|
||||
@ -429,15 +469,6 @@ void mipsmt_prepare_cpus(void)
|
||||
printk(" %d", tc);
|
||||
tc++;
|
||||
}
|
||||
if (slop) {
|
||||
if (tc != 0) {
|
||||
smtc_tc_setup(vpe, tc, cpu);
|
||||
cpu++;
|
||||
}
|
||||
printk(" %d", tc);
|
||||
tc++;
|
||||
slop--;
|
||||
}
|
||||
if (vpe != 0) {
|
||||
/*
|
||||
* 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,
|
||||
|
||||
task_size = STACK_TOP;
|
||||
|
||||
if (len > task_size)
|
||||
return -ENOMEM;
|
||||
|
||||
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
|
||||
* cache aliasing constraints.
|
||||
@ -83,8 +90,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
return addr;
|
||||
}
|
||||
|
||||
if (len > task_size)
|
||||
return -ENOMEM;
|
||||
do_color_align = 0;
|
||||
if (filp || (flags & MAP_SHARED))
|
||||
do_color_align = 1;
|
||||
|
@ -11,6 +11,7 @@
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -115,10 +116,6 @@ EXPORT_SYMBOL(perf_irq);
|
||||
* (only needed if you intended to use cpu counter as timer interrupt
|
||||
* source)
|
||||
* 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;
|
||||
@ -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)
|
||||
|
@ -63,21 +63,23 @@ SECTIONS
|
||||
|
||||
/* writeable */
|
||||
.data : { /* Data */
|
||||
. = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */
|
||||
/*
|
||||
* This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which
|
||||
* limits the maximum alignment 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’
|
||||
* is greater than maximum object file alignment. Using 32768
|
||||
*/
|
||||
. = ALIGN(_PAGE_SIZE);
|
||||
*(.data.init_task)
|
||||
. = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */
|
||||
/*
|
||||
* This ALIGN is needed as a workaround for a bug a
|
||||
* gcc bug upto 4.1 which limits the maximum alignment
|
||||
* 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’ is greater than maximum
|
||||
* object file alignment. Using 32768
|
||||
*/
|
||||
. = ALIGN(_PAGE_SIZE);
|
||||
*(.data.init_task)
|
||||
|
||||
DATA_DATA
|
||||
CONSTRUCTORS
|
||||
DATA_DATA
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_gp = . + 0x8000;
|
||||
.lit8 : {
|
||||
|
@ -942,8 +942,8 @@ static int vpe_elfload(struct vpe * v)
|
||||
if (phdr->p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
memcpy((void *)phdr->p_vaddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
|
||||
memset((void *)phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
|
||||
memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
|
||||
memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
|
||||
phdr++;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
void __init plat_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
|
||||
change_c0_status(ST0_IM, IE_IRQ0);
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
|
@ -127,26 +127,6 @@ unsigned long read_persistent_clock(void)
|
||||
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)
|
||||
{
|
||||
cp0_perfcount_irq = -1;
|
||||
@ -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
|
||||
if (cpu_has_veic) {
|
||||
set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
|
||||
mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
|
||||
}
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (cpu_has_vint)
|
||||
@ -181,13 +160,26 @@ void __init plat_timer_setup(struct irqaction *irq)
|
||||
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << cp0_compare_irq);
|
||||
#else
|
||||
setup_irq(mips_cpu_timer_irq, irq);
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
#ifdef CONFIG_SMP
|
||||
set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq);
|
||||
return mips_cpu_timer_irq;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
plat_perf_setup();
|
||||
|
@ -75,6 +75,30 @@ static unsigned int __init estimate_cpu_frequency(void)
|
||||
return count;
|
||||
}
|
||||
|
||||
static int mips_cpu_timer_irq;
|
||||
|
||||
static void mips_timer_dispatch(void)
|
||||
{
|
||||
do_IRQ(mips_cpu_timer_irq);
|
||||
}
|
||||
|
||||
|
||||
unsigned __init get_c0_compare_int(void)
|
||||
{
|
||||
#ifdef MSC01E_INT_BASE
|
||||
if (cpu_has_veic) {
|
||||
set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
|
||||
mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
|
||||
} else {
|
||||
#endif
|
||||
if (cpu_has_vint)
|
||||
set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
|
||||
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
|
||||
}
|
||||
|
||||
return mips_cpu_timer_irq;
|
||||
}
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
unsigned int est_freq, flags;
|
||||
@ -93,35 +117,3 @@ void __init plat_time_init(void)
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static int mips_cpu_timer_irq;
|
||||
|
||||
static void mips_timer_dispatch(void)
|
||||
{
|
||||
do_IRQ(mips_cpu_timer_irq);
|
||||
}
|
||||
|
||||
|
||||
void __init plat_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
if (cpu_has_veic) {
|
||||
set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
|
||||
mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
|
||||
} else {
|
||||
if (cpu_has_vint)
|
||||
set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
|
||||
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
|
||||
}
|
||||
|
||||
/* we are using the cpu counter for timer interrupts */
|
||||
setup_irq(mips_cpu_timer_irq, irq);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* irq_desc(riptor) is a global resource, when the interrupt overlaps
|
||||
on seperate cpu's the first one tries to handle the second interrupt.
|
||||
The effect is that the int remains disabled on the second cpu.
|
||||
Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
|
||||
irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU;
|
||||
set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq);
|
||||
#endif
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Tx39XX R4k style caches added. HK
|
||||
* Copyright (C) 1998, 1999, 2000 Harald Koerfgen
|
||||
* 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/kernel.h>
|
||||
@ -26,8 +26,6 @@
|
||||
static unsigned long icache_size, dcache_size; /* 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 flags, status, dummy, size;
|
||||
@ -217,26 +215,6 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
|
||||
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)
|
||||
{
|
||||
}
|
||||
@ -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,
|
||||
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)
|
||||
@ -272,9 +278,7 @@ static void r3k_flush_cache_sigtramp(unsigned long addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
#ifdef DEBUG_CACHE
|
||||
printk("csigtramp[%08lx]", addr);
|
||||
#endif
|
||||
pr_debug("csigtramp[%08lx]\n", addr);
|
||||
|
||||
flags = read_c0_status();
|
||||
|
||||
|
@ -345,11 +345,26 @@ static void r4k___flush_cache_all(void)
|
||||
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)
|
||||
{
|
||||
struct vm_area_struct *vma = args;
|
||||
|
||||
if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
|
||||
if (!(has_valid_asid(vma->vm_mm)))
|
||||
return;
|
||||
|
||||
r4k_blast_dcache();
|
||||
@ -368,7 +383,7 @@ static inline void local_r4k_flush_cache_mm(void * args)
|
||||
{
|
||||
struct mm_struct *mm = args;
|
||||
|
||||
if (!cpu_context(smp_processor_id(), mm))
|
||||
if (!has_valid_asid(mm))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -420,7 +435,7 @@ static inline void local_r4k_flush_cache_page(void *args)
|
||||
* If ownes no valid ASID yet, cannot possibly have gotten
|
||||
* this page into the cache.
|
||||
*/
|
||||
if (cpu_context(smp_processor_id(), mm) == 0)
|
||||
if (!has_valid_asid(mm))
|
||||
return;
|
||||
|
||||
addr &= PAGE_MASK;
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
* 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)
|
||||
printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n");
|
||||
|
@ -2,7 +2,7 @@
|
||||
* fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
|
||||
*
|
||||
* 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
|
||||
* 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,
|
||||
if (pciirqflag == 0) {
|
||||
request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
|
||||
bpci_interrupt,
|
||||
SA_SHIRQ | SA_INTERRUPT,
|
||||
IRQF_SHARED | IRQF_DISABLED,
|
||||
"PMC MSP PCI Host",
|
||||
preg);
|
||||
pciirqflag = ~0;
|
||||
|
@ -122,7 +122,7 @@ void __init msp_serial_setup(void)
|
||||
up.uartclk = uartclk;
|
||||
up.regshift = 2;
|
||||
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.line = 0;
|
||||
up.private_data = (void*)UART0_STATUS_REG;
|
||||
|
@ -131,12 +131,12 @@ static struct irq_chip rt_irq_type = {
|
||||
static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
int slice = cputoslice(cpu) == 0;
|
||||
int slice putoslice(cpu);
|
||||
unsigned long cnt;
|
||||
|
||||
cnt = LOCAL_HUB_L(PI_RT_COUNT);
|
||||
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;
|
||||
}
|
||||
@ -164,9 +164,12 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *cd = dev_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);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -40,13 +40,6 @@ static void inline flush_mace_bus(void)
|
||||
mace->perif.ctrl.misc;
|
||||
}
|
||||
|
||||
#undef DEBUG_IRQ
|
||||
#ifdef DEBUG_IRQ
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* O2 irq map
|
||||
*
|
||||
@ -125,6 +118,7 @@ struct irqaction memerr_irq = {
|
||||
.mask = CPU_MASK_NONE,
|
||||
.name = "CRIME memory error",
|
||||
};
|
||||
|
||||
struct irqaction cpuerr_irq = {
|
||||
.handler = crime_cpuerr_intr,
|
||||
.flags = IRQF_DISABLED,
|
||||
@ -139,46 +133,70 @@ struct irqaction cpuerr_irq = {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
flush_crime_bus();
|
||||
}
|
||||
|
||||
static void mask_and_ack_crime_irq(unsigned int irq)
|
||||
static void crime_level_mask_and_ack_irq(unsigned int irq)
|
||||
{
|
||||
/* 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)
|
||||
|| (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) {
|
||||
uint64_t crime_int;
|
||||
crime_int = crime->hard_int;
|
||||
crime_int &= ~(1 << (irq - 1));
|
||||
crime->hard_int = crime_int;
|
||||
}
|
||||
disable_crime_irq(irq);
|
||||
crime_disable_irq(irq);
|
||||
}
|
||||
|
||||
static void end_crime_irq(unsigned int irq)
|
||||
static void crime_level_end_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
enable_crime_irq(irq);
|
||||
crime_enable_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip ip32_crime_interrupt = {
|
||||
.name = "IP32 CRIME",
|
||||
.ack = mask_and_ack_crime_irq,
|
||||
.mask = disable_crime_irq,
|
||||
.mask_ack = mask_and_ack_crime_irq,
|
||||
.unmask = enable_crime_irq,
|
||||
.end = end_crime_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. */
|
||||
|
||||
crime_int = crime->hard_int;
|
||||
crime_int &= ~(1 << bit);
|
||||
crime->hard_int = crime_int;
|
||||
|
||||
crime_disable_irq(irq);
|
||||
}
|
||||
|
||||
static void crime_edge_end_irq(unsigned int irq)
|
||||
{
|
||||
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
|
||||
crime_enable_irq(irq);
|
||||
}
|
||||
|
||||
static struct irq_chip crime_edge_interrupt = {
|
||||
.name = "IP32 CRIME",
|
||||
.ack = crime_edge_mask_and_ack_irq,
|
||||
.mask = crime_disable_irq,
|
||||
.mask_ack = crime_edge_mask_and_ack_irq,
|
||||
.unmask = crime_enable_irq,
|
||||
.end = crime_edge_end_irq,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -265,7 +283,7 @@ static void enable_maceisa_irq(unsigned int irq)
|
||||
{
|
||||
unsigned int crime_int = 0;
|
||||
|
||||
DBG("maceisa enable: %u\n", irq);
|
||||
pr_debug("maceisa enable: %u\n", irq);
|
||||
|
||||
switch (irq) {
|
||||
case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
|
||||
@ -278,7 +296,7 @@ static void enable_maceisa_irq(unsigned int irq)
|
||||
crime_int = MACE_SUPERIO_INT;
|
||||
break;
|
||||
}
|
||||
DBG("crime_int %08x enabled\n", crime_int);
|
||||
pr_debug("crime_int %08x enabled\n", crime_int);
|
||||
crime_mask |= crime_int;
|
||||
crime->imask = crime_mask;
|
||||
maceisa_mask |= 1 << (irq - 33);
|
||||
@ -290,11 +308,11 @@ static void disable_maceisa_irq(unsigned int irq)
|
||||
unsigned int crime_int = 0;
|
||||
|
||||
maceisa_mask &= ~(1 << (irq - 33));
|
||||
if(!(maceisa_mask & MACEISA_AUDIO_INT))
|
||||
if (!(maceisa_mask & MACEISA_AUDIO_INT))
|
||||
crime_int |= MACE_AUDIO_INT;
|
||||
if(!(maceisa_mask & MACEISA_MISC_INT))
|
||||
if (!(maceisa_mask & MACEISA_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_mask &= ~crime_int;
|
||||
crime->imask = crime_mask;
|
||||
@ -327,12 +345,12 @@ static void end_maceisa_irq(unsigned irq)
|
||||
}
|
||||
|
||||
static struct irq_chip ip32_maceisa_interrupt = {
|
||||
.name = "IP32 MACE ISA",
|
||||
.ack = mask_and_ack_maceisa_irq,
|
||||
.mask = disable_maceisa_irq,
|
||||
.mask_ack = mask_and_ack_maceisa_irq,
|
||||
.unmask = enable_maceisa_irq,
|
||||
.end = end_maceisa_irq,
|
||||
.name = "IP32 MACE ISA",
|
||||
.ack = mask_and_ack_maceisa_irq,
|
||||
.mask = disable_maceisa_irq,
|
||||
.mask_ack = mask_and_ack_maceisa_irq,
|
||||
.unmask = enable_maceisa_irq,
|
||||
.end = end_maceisa_irq,
|
||||
};
|
||||
|
||||
/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
|
||||
@ -411,7 +429,7 @@ static void ip32_irq0(void)
|
||||
irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
|
||||
}
|
||||
|
||||
DBG("*irq %u*\n", irq);
|
||||
pr_debug("*irq %u*\n", irq);
|
||||
do_IRQ(irq);
|
||||
}
|
||||
|
||||
@ -472,23 +490,31 @@ void __init arch_init_irq(void)
|
||||
|
||||
mips_cpu_irq_init();
|
||||
for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) {
|
||||
struct irq_chip *chip;
|
||||
|
||||
switch (irq) {
|
||||
case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
|
||||
chip = &ip32_mace_interrupt;
|
||||
set_irq_chip(irq, &ip32_mace_interrupt);
|
||||
break;
|
||||
case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
|
||||
chip = &ip32_macepci_interrupt;
|
||||
set_irq_chip(irq, &ip32_macepci_interrupt);
|
||||
break;
|
||||
case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ:
|
||||
chip = &ip32_crime_interrupt;
|
||||
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;
|
||||
case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
|
||||
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;
|
||||
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_CPUERR_IRQ, &cpuerr_irq);
|
||||
|
@ -280,27 +280,6 @@ static struct irqaction bcm1480_dummy_action = {
|
||||
.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
|
||||
* is responsible for setting up the interrupt mapper and installing the
|
||||
@ -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)));
|
||||
}
|
||||
|
||||
bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
|
||||
|
||||
/*
|
||||
* Note that the timer interrupts are also mapped, but this is
|
||||
* done in bcm1480_time_init(). Also, the profiling driver
|
||||
@ -411,7 +388,6 @@ void __init arch_init_irq(void)
|
||||
/* QQQ FIXME */
|
||||
__raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
|
||||
|
||||
bcm1480_steal_irq(kgdb_irq);
|
||||
__raw_writeq(IMR_IP6_VAL,
|
||||
IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
|
||||
(kgdb_irq<<3));
|
||||
|
@ -37,8 +37,6 @@
|
||||
#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
|
||||
#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 rest of the system
|
||||
@ -121,7 +119,7 @@ void __cpuinit sb1480_clockevent_init(void)
|
||||
sprintf(name, "bcm1480-counter %d", cpu);
|
||||
cd->name = name;
|
||||
cd->features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_MODE_ONESHOT;
|
||||
CLOCK_EVT_FEAT_ONESHOT;
|
||||
clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
|
||||
cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
|
||||
cd->min_delta_ns = clockevent_delta2ns(1, cd);
|
||||
@ -142,7 +140,6 @@ void __cpuinit sb1480_clockevent_init(void)
|
||||
R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
|
||||
|
||||
bcm1480_unmask_irq(cpu, irq);
|
||||
bcm1480_steal_irq(irq);
|
||||
|
||||
action->handler = sibyte_counter_handler;
|
||||
action->flags = IRQF_DISABLED | IRQF_PERCPU;
|
||||
|
@ -250,27 +250,6 @@ static struct irqaction sb1250_dummy_action = {
|
||||
.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
|
||||
* init_IRQ. It is responsible for setting up the interrupt mapper and
|
||||
@ -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(1, R_IMR_INTERRUPT_MASK)));
|
||||
|
||||
sb1250_steal_irq(K_INT_MBOX_0);
|
||||
|
||||
/*
|
||||
* Note that the timer interrupts are also mapped, but this is
|
||||
* done in sb1250_time_init(). Also, the profiling driver
|
||||
@ -367,7 +344,6 @@ void __init arch_init_irq(void)
|
||||
__raw_writeq(M_DUART_IMR_BRK,
|
||||
IOADDR(A_DUART_IMRREG(kgdb_port)));
|
||||
|
||||
sb1250_steal_irq(kgdb_irq);
|
||||
__raw_writeq(IMR_IP6_VAL,
|
||||
IOADDR(A_IMR_REGISTER(0,
|
||||
R_IMR_INTERRUPT_MAP_BASE) +
|
||||
|
@ -50,8 +50,6 @@
|
||||
#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 rest of the system
|
||||
@ -139,7 +137,7 @@ void __cpuinit sb1250_clockevent_init(void)
|
||||
sprintf(name, "bcm1480-counter %d", cpu);
|
||||
cd->name = name;
|
||||
cd->features = CLOCK_EVT_FEAT_PERIODIC |
|
||||
CLOCK_EVT_MODE_ONESHOT;
|
||||
CLOCK_EVT_FEAT_ONESHOT;
|
||||
clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
|
||||
cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
|
||||
cd->min_delta_ns = clockevent_delta2ns(1, cd);
|
||||
@ -159,7 +157,6 @@ void __cpuinit sb1250_clockevent_init(void)
|
||||
cd->cpumask = cpumask_of_cpu(0);
|
||||
|
||||
sb1250_unmask_irq(cpu, irq);
|
||||
sb1250_steal_irq(irq);
|
||||
|
||||
action->handler = sibyte_counter_handler;
|
||||
action->flags = IRQF_DISABLED | IRQF_PERCPU;
|
||||
|
@ -11,27 +11,78 @@
|
||||
#define SNI_COUNTER2_DIV 64
|
||||
#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.
|
||||
* 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();
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV) & 0xff; wmb();
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb();
|
||||
struct clock_event_device *cd = &a20r_clockevent_device;
|
||||
struct irqaction *action = &a20r_irqaction;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb();
|
||||
*(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();
|
||||
cd->cpumask = cpumask_of_cpu(cpu);
|
||||
|
||||
setup_irq(SNI_A20R_IRQ_TIMER, irq);
|
||||
mips_timer_ack = sni_a20r_timer_ack;
|
||||
action->dev_id = cd;
|
||||
setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction);
|
||||
}
|
||||
|
||||
#define SNI_8254_TICK_RATE 1193182UL
|
||||
@ -119,17 +170,14 @@ void __init plat_time_init(void)
|
||||
mips_hpt_frequency = r4k_tick * HZ;
|
||||
|
||||
setup_pit_timer();
|
||||
}
|
||||
|
||||
void __init plat_timer_setup(struct irqaction *irq)
|
||||
{
|
||||
switch (sni_brd_type) {
|
||||
case SNI_BRD_10:
|
||||
case SNI_BRD_10NEW:
|
||||
case SNI_BRD_TOWER_OASIC:
|
||||
case SNI_BRD_MINITOWER:
|
||||
sni_a20r_timer_setup(irq);
|
||||
break;
|
||||
sni_a20r_timer_setup();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <asm/processor.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/txx9tmr.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/blkdev.h>
|
||||
#ifdef CONFIG_TOSHIBA_FPCIB0
|
||||
@ -93,7 +94,6 @@
|
||||
|
||||
#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )
|
||||
#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_PCI1 ( 1 << 8 )
|
||||
#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )
|
||||
@ -130,7 +130,6 @@ extern void toshiba_rbtx4927_power_off(void);
|
||||
|
||||
int tx4927_using_backplane = 0;
|
||||
|
||||
extern void gt64120_time_init(void);
|
||||
extern void toshiba_rbtx4927_irq_setup(void);
|
||||
|
||||
char *prom_getcmdline(void);
|
||||
@ -721,6 +720,7 @@ void toshiba_rbtx4927_power_off(void)
|
||||
|
||||
void __init toshiba_rbtx4927_setup(void)
|
||||
{
|
||||
int i;
|
||||
u32 cp0_config;
|
||||
char *argptr;
|
||||
|
||||
@ -764,6 +764,9 @@ void __init toshiba_rbtx4927_setup(void)
|
||||
_machine_halt = toshiba_rbtx4927_halt;
|
||||
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
|
||||
|
||||
/* PCIC */
|
||||
@ -892,7 +895,6 @@ void __init toshiba_rbtx4927_setup(void)
|
||||
#ifdef CONFIG_SERIAL_TXX9
|
||||
{
|
||||
extern int early_serial_txx9_setup(struct uart_port *port);
|
||||
int i;
|
||||
struct uart_port req;
|
||||
for(i = 0; i < 2; i++) {
|
||||
memset(&req, 0, sizeof(req));
|
||||
@ -937,12 +939,11 @@ void __init toshiba_rbtx4927_setup(void)
|
||||
void __init
|
||||
toshiba_rbtx4927_time_init(void)
|
||||
{
|
||||
TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n");
|
||||
|
||||
mips_hpt_frequency = tx4927_cpu_clock / 2;
|
||||
|
||||
TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n");
|
||||
|
||||
if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS)
|
||||
txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL,
|
||||
TXX9_IRQ_BASE + 17,
|
||||
50000000);
|
||||
}
|
||||
|
||||
static int __init toshiba_rbtx4927_rtc_init(void)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/txx9tmr.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/bootinfo.h>
|
||||
@ -773,15 +774,8 @@ void __init tx4938_board_setup(void)
|
||||
}
|
||||
|
||||
/* TMR */
|
||||
/* disable all timers */
|
||||
for (i = 0; i < TX4938_NR_TMR; i++) {
|
||||
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;
|
||||
}
|
||||
for (i = 0; i < TX4938_NR_TMR; i++)
|
||||
txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
|
||||
|
||||
/* enable DMA */
|
||||
TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
|
||||
@ -852,12 +846,13 @@ void tx4938_report_pcic_status(void)
|
||||
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
|
@ -22,10 +22,12 @@ enum ip32_irq_no {
|
||||
* CPU interrupts are 0 ... 7
|
||||
*/
|
||||
|
||||
CRIME_IRQ_BASE = MIPS_CPU_IRQ_BASE,
|
||||
|
||||
/*
|
||||
* MACE
|
||||
*/
|
||||
MACE_VID_IN1_IRQ = MIPS_CPU_IRQ_BASE + 8,
|
||||
MACE_VID_IN1_IRQ = CRIME_IRQ_BASE,
|
||||
MACE_VID_IN2_IRQ,
|
||||
MACE_VID_OUT_IRQ,
|
||||
MACE_ETHERNET_IRQ,
|
||||
|
@ -132,9 +132,7 @@
|
||||
#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_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI)
|
||||
#define JMR3927_IRQ_IRC_TMR0 (JMR3927_IRQ_IRC + TX3927_IR_TMR0)
|
||||
#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_IRC_TMR(ch) (JMR3927_IRQ_IRC + TX3927_IR_TMR(ch))
|
||||
#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_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC)
|
||||
@ -148,17 +146,12 @@
|
||||
#define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1
|
||||
/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */
|
||||
#define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3
|
||||
/* Clock Tick (10ms) */
|
||||
#define JMR3927_IRQ_TICK JMR3927_IRQ_IRC_TMR0
|
||||
|
||||
/* Clocks */
|
||||
#define JMR3927_CORECLK 132710400 /* 132.7MHz */
|
||||
#define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */
|
||||
#define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */
|
||||
|
||||
#define jmr3927_tmrptr tx3927_tmrptr(0) /* TMR0 */
|
||||
|
||||
|
||||
/*
|
||||
* TX3927 Pin Configuration:
|
||||
*
|
||||
|
@ -222,9 +222,7 @@ struct tx3927_ccfg_reg {
|
||||
#define TX3927_IR_DMA 8
|
||||
#define TX3927_IR_PIO 9
|
||||
#define TX3927_IR_PCI 10
|
||||
#define TX3927_IR_TMR0 13
|
||||
#define TX3927_IR_TMR1 14
|
||||
#define TX3927_IR_TMR2 15
|
||||
#define TX3927_IR_TMR(ch) (13 + (ch))
|
||||
#define TX3927_NUM_IR 16
|
||||
|
||||
/*
|
||||
|
@ -10,22 +10,6 @@
|
||||
#ifndef __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 {
|
||||
volatile unsigned long lcr;
|
||||
volatile unsigned long dicr;
|
||||
@ -50,27 +34,6 @@ struct txx927_pio_reg {
|
||||
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
|
||||
*/
|
||||
|
@ -58,7 +58,6 @@ extern void local_timer_interrupt(int irq, void *dev_id);
|
||||
*/
|
||||
struct irqaction;
|
||||
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
|
||||
@ -78,6 +77,7 @@ extern int (*perf_irq)(void);
|
||||
*/
|
||||
#ifdef CONFIG_CEVT_R4K
|
||||
extern void mips_clockevent_init(void);
|
||||
extern unsigned int __weak get_c0_compare_int(void);
|
||||
#else
|
||||
static inline void mips_clockevent_init(void)
|
||||
{
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define __ASM_TX4927_TX4927_PCI_H
|
||||
|
||||
#define TX4927_CCFG_TOE 0x00004000
|
||||
#define TX4927_CCFG_TINTDIS 0x01000000
|
||||
|
||||
#define TX4927_PCIMEM 0x08000000
|
||||
#define TX4927_PCIMEM_SIZE 0x08000000
|
||||
@ -20,6 +21,8 @@
|
||||
#define TX4927_PCIC_REG 0xff1fd000
|
||||
#define TX4927_CCFG_REG 0xff1fe000
|
||||
#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_PCIRESET_ADDR 0xbc00f006
|
||||
#define TX4927_PCI_CLK_ADDR (KSEG1 + TX4927_CE3 + 0x00040020)
|
||||
|
@ -641,7 +641,6 @@ struct tx4938_ccfg_reg {
|
||||
#define tx4938_pcicptr ((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
|
||||
#define tx4938_pcic1ptr ((struct tx4938_pcic_reg *)TX4938_PCIC1_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_pioptr ((struct tx4938_pio_reg *)TX4938_PIO_REG)
|
||||
#define tx4938_aclcptr ((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
|
||||
|
67
include/asm-mips/txx9tmr.h
Normal file
67
include/asm-mips/txx9tmr.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 */
|
Loading…
Reference in New Issue
Block a user