Skip to content

Commit

Permalink
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-…
Browse files Browse the repository at this point in the history
…linus

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
  [MIPS] SB1: Check for -mno-sched-prolog if building corelis debug kernel.
  [MIPS] Sibyte: Fix race in sb1250_gettimeoffset().
  [MIPS] Sibyte: Fix interrupt timer off by one bug.
  [MIPS] Sibyte: Fix M_SCD_TIMER_INIT and M_SCD_TIMER_CNT wrong field width.
  [MIPS] Protect more of timer_interrupt() by xtime_lock.
  [MIPS] Work around bad code generation for <asm/io.h>.
  [MIPS] Simple patch to power off DBAU1200
  [MIPS] Fix DBAu1550 software power off.
  [MIPS] local_r4k_flush_cache_page fix
  [MIPS] SB1: Fix interrupt disable hazard.
  [MIPS] Get rid of the IP22-specific code in arclib.
  Update MAINTAINERS entry for MIPS.
  • Loading branch information
Linus Torvalds committed Mar 20, 2006
2 parents 4a29cc2 + 9007c9a commit 4657190
Show file tree
Hide file tree
Showing 16 changed files with 217 additions and 134 deletions.
3 changes: 2 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1752,7 +1752,8 @@ P: Ralf Baechle
M: ralf@linux-mips.org
W: http://www.linux-mips.org/
L: linux-mips@linux-mips.org
S: Maintained
T: git www.linux-mips.org:/pub/scm/linux.git
S: Supported

MISCELLANEOUS MCA-SUPPORT
P: James Bottomley
Expand Down
3 changes: 2 additions & 1 deletion arch/mips/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ MODFLAGS += -mlong-calls
cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB)
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL)

cflags-$(CONFIG_SB1XXX_CORELIS) += -mno-sched-prolog -fno-omit-frame-pointer
cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \
-fno-omit-frame-pointer

#
# Use: $(call set_gccflags,<cpu0>,<isa0>,<cpu1>,<isa1>,<isa2>)
Expand Down
19 changes: 0 additions & 19 deletions arch/mips/arc/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
* Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>

Expand All @@ -20,17 +19,11 @@
#include <asm/bootinfo.h>
#include <asm/system.h>

extern void *sgiwd93_host;
extern void reset_wd33c93(void *instance);

VOID
ArcHalt(VOID)
{
bc_disable();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(halt);
never: goto never;
}
Expand All @@ -40,9 +33,6 @@ ArcPowerDown(VOID)
{
bc_disable();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(pdown);
never: goto never;
}
Expand All @@ -53,9 +43,6 @@ ArcRestart(VOID)
{
bc_disable();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(restart);
never: goto never;
}
Expand All @@ -65,9 +52,6 @@ ArcReboot(VOID)
{
bc_disable();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(reboot);
never: goto never;
}
Expand All @@ -77,9 +61,6 @@ ArcEnterInteractiveMode(VOID)
{
bc_disable();
local_irq_disable();
#ifdef CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
#endif
ARC_CALL0(imode);
never: goto never;
}
Expand Down
10 changes: 7 additions & 3 deletions arch/mips/au1000/common/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,20 @@ void au1000_restart(char *command)

void au1000_halt(void)
{
#if defined(CONFIG_MIPS_PB1550)
#if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
/* power off system */
printk("\n** Powering off Pb1550\n");
printk("\n** Powering off...\n");
au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
au_sync();
while(1); /* should not get here */
#endif
#else
printk(KERN_NOTICE "\n** You can safely turn off the power\n");
#ifdef CONFIG_MIPS_MIRAGE
au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
#endif
#ifdef CONFIG_MIPS_DB1200
au_writew(au_readw(0xB980001C) | (1<<14), 0xB980001C);
#endif
#ifdef CONFIG_PM
au_sleep();

Expand All @@ -187,6 +190,7 @@ void au1000_halt(void)
"wait\n\t"
".set\tmips0");
#endif
#endif /* defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550) */
}

void au1000_power_off(void)
Expand Down
6 changes: 4 additions & 2 deletions arch/mips/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned long j;
unsigned int count;

write_seqlock(&xtime_lock);

count = mips_hpt_read();
mips_timer_ack();

Expand All @@ -441,7 +443,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
* called as close as possible to 500 ms before the new second starts.
*/
write_seqlock(&xtime_lock);
if (ntp_synced() &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
Expand All @@ -453,7 +454,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
last_rtc_update = xtime.tv_sec - 600;
}
}
write_sequnlock(&xtime_lock);

/*
* If jiffies has overflown in this timer_interrupt, we must
Expand Down Expand Up @@ -496,6 +496,8 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
}

write_sequnlock(&xtime_lock);

/*
* In UP mode, we call local_timer_interrupt() to do profiling
* and process accouting.
Expand Down
13 changes: 9 additions & 4 deletions arch/mips/mm/c-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,15 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
struct flush_cache_page_args {
struct vm_area_struct *vma;
unsigned long addr;
unsigned long pfn;
};

static inline void local_r4k_flush_cache_page(void *args)
{
struct flush_cache_page_args *fcp_args = args;
struct vm_area_struct *vma = fcp_args->vma;
unsigned long addr = fcp_args->addr;
unsigned long paddr = fcp_args->pfn << PAGE_SHIFT;
int exec = vma->vm_flags & VM_EXEC;
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgdp;
Expand Down Expand Up @@ -431,11 +433,12 @@ static inline void local_r4k_flush_cache_page(void *args)
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
addr = INDEX_BASE + (addr & (dcache_size - 1));
if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
r4k_blast_dcache_page_indexed(addr);
if (exec && !cpu_icache_snoops_remote_store)
r4k_blast_scache_page_indexed(addr);
r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ?
paddr : addr);
if (exec && !cpu_icache_snoops_remote_store) {
r4k_blast_scache_page_indexed(paddr);
}
}
if (exec) {
if (cpu_has_vtag_icache) {
Expand All @@ -455,6 +458,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,

args.vma = vma;
args.addr = addr;
args.pfn = pfn;

on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
}
Expand Down Expand Up @@ -956,6 +960,7 @@ static void __init probe_pcache(void)
switch (c->cputype) {
case CPU_20KC:
case CPU_25KF:
c->dcache.flags |= MIPS_CACHE_PINDEX;
case CPU_R10000:
case CPU_R12000:
case CPU_SB1:
Expand Down
1 change: 0 additions & 1 deletion arch/mips/mm/c-tx39.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
* Do indexed flush, too much work to get the (possible) TLB refills
* to work correctly.
*/
page = (KSEG0 + (page & (dcache_size - 1)));
if (cpu_has_dc_aliases || exec)
tx39_blast_dcache_page_indexed(page);
if (exec)
Expand Down
77 changes: 58 additions & 19 deletions arch/mips/sibyte/sb1250/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,51 @@
#define IMR_IP3_VAL K_INT_MAP_I1
#define IMR_IP4_VAL K_INT_MAP_I2

#define SB1250_HPT_NUM 3
#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */
#define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH)


extern int sb1250_steal_irq(int irq);

static unsigned int sb1250_hpt_read(void);
static void sb1250_hpt_init(unsigned int);

static unsigned int hpt_offset;

void __init sb1250_hpt_setup(void)
{
int cpu = smp_processor_id();

if (!cpu) {
/* Setup hpt using timer #3 but do not enable irq for it */
__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
__raw_writeq(SB1250_HPT_VALUE,
IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_INIT)));
__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));

/*
* we need to fill 32 bits, so just use the upper 23 bits and pretend
* the timer is going 512Mhz instead of 1Mhz
*/
mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT;
mips_hpt_init = sb1250_hpt_init;
mips_hpt_read = sb1250_hpt_read;
}
}


void sb1250_time_init(void)
{
int cpu = smp_processor_id();
int irq = K_INT_TIMER_0+cpu;

/* Only have 4 general purpose timers */
if (cpu > 3) {
/* Only have 4 general purpose timers, and we use last one as hpt */
if (cpu > 2) {
BUG();
}

if (!cpu) {
/* Use our own gettimeoffset() routine */
do_gettimeoffset = sb1250_gettimeoffset;
}

sb1250_mask_irq(cpu, irq);

/* Map the timer interrupt to ip[4] of this cpu */
Expand All @@ -75,10 +103,10 @@ void sb1250_time_init(void)
/* Disable the timer and set up the count */
__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
#ifdef CONFIG_SIMULATION
__raw_writeq(50000 / HZ,
__raw_writeq((50000 / HZ) - 1,
IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#else
__raw_writeq(1000000 / HZ,
__raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1,
IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
#endif

Expand All @@ -103,7 +131,7 @@ void sb1250_timer_interrupt(struct pt_regs *regs)
int cpu = smp_processor_id();
int irq = K_INT_TIMER_0 + cpu;

/* Reset the timer */
/* ACK interrupt */
____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));

Expand All @@ -122,15 +150,26 @@ void sb1250_timer_interrupt(struct pt_regs *regs)
}

/*
* We use our own do_gettimeoffset() instead of the generic one,
* because the generic one does not work for SMP case.
* In addition, since we use general timer 0 for system time,
* we can get accurate intra-jiffy offset without calibration.
* The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
* again. There's no easy way to set to a specific value so store init value
* in hpt_offset and subtract each time.
*
* Note: Timer isn't full 32bits so shift it into the upper part making
* it appear to run at a higher frequency.
*/
unsigned long sb1250_gettimeoffset(void)
static unsigned int sb1250_hpt_read(void)
{
unsigned long count =
__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
unsigned int count;

return 1000000/HZ - count;
}
count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));

count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT;

return count - hpt_offset;
}

static void sb1250_hpt_init(unsigned int count)
{
hpt_offset = count;
return;
}
7 changes: 7 additions & 0 deletions arch/mips/sibyte/swarm/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ const char *get_system_type(void)
return "SiByte " SIBYTE_BOARD_NAME;
}

void __init swarm_time_init(void)
{
/* Setup HPT */
sb1250_hpt_setup();
}

void __init swarm_timer_setup(struct irqaction *irq)
{
/*
Expand Down Expand Up @@ -109,6 +115,7 @@ void __init plat_setup(void)

panic_timeout = 5; /* For debug. */

board_time_init = swarm_time_init;
board_timer_setup = swarm_timer_setup;
board_be_handler = swarm_be_handler;

Expand Down
3 changes: 3 additions & 0 deletions include/asm-mips/cpu-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
#ifndef cpu_has_ic_fills_f_dc
#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
#endif
#ifndef cpu_has_pindexed_dcache
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
#endif

/*
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
Expand Down
1 change: 1 addition & 0 deletions include/asm-mips/cpu-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct cache_desc {
#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */

struct cpuinfo_mips {
unsigned long udelay_val;
Expand Down
Loading

0 comments on commit 4657190

Please sign in to comment.