Commit f99c6bb6 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: (35 commits)
  sh: rts7751r2d board updates.
  sh: Kill off dead bigsur and ec3104 boards.
  sh: Fixup r7780rp pata_platform for devres conversion.
  sh: Revert TLB miss fast-path changes that broke PTEA parts.
  sh: Compile fix for heartbeat consolidation.
  sh: heartbeat consolidation for banked LEDs.
  sh: define dma noncoherent API functions.
  sh: Missing flush_dcache_all() proto in cacheflush.h.
  sh: Kill dead/unused ISA code from __ioremap().
  sh: Add cpu-features header to asm/Kbuild.
  sh: Move __KERNEL__ up in asm/page.h.
  sh: Fix syscall numbering breakage.
  sh: dcache write-back for R7780RP PIO.
  sh: Switch to local TLB flush variants in additional callsites.
  sh: Local TLB flushing variants for SMP prep.
  sh: Fixup cpu_data references for the non-boot CPUs.
  sh: Use a per-cpu ASID cache.
  sh: add SH_CLK_MD Kconfig default.
  sh: Fixup SHMIN INTC register definitions.
  sh: SH-DMAC compile fixes
  ...
parents e0a04cff 9c57548f
......@@ -135,12 +135,6 @@ config SH_HP6XX
More information (hardware only) at
<http://www.hp.com/jornada/>.
config SH_EC3104
bool "EC3104"
help
Select EC3104 if configuring for a system with an Eclipse
International EC3104 chip, e.g. the Harris AD2000.
config SH_SATURN
bool "Saturn"
select CPU_SUBTYPE_SH7604
......@@ -156,9 +150,6 @@ config SH_DREAMCAST
<http://www.m17n.org/linux-sh/dreamcast/>. There is a
Dreamcast project is at <http://linuxdc.sourceforge.net/>.
config SH_BIGSUR
bool "BigSur"
config SH_MPC1211
bool "Interface MPC1211"
help
......@@ -481,6 +472,7 @@ config SH_PCLK_FREQ
config SH_CLK_MD
int "CPU Mode Pin Setting"
default 0
depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206
help
MD2 - MD0 pin setting.
......@@ -510,8 +502,9 @@ source "arch/sh/cchips/Kconfig"
config HEARTBEAT
bool "Heartbeat LED"
depends on SH_MPC1211 || SH_SH03 || \
SH_BIGSUR || SOLUTION_ENGINE || \
SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK
SOLUTION_ENGINE || \
SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK || \
SH_R7780RP
help
Use the power-on LED on your machine as a load meter. The exact
behavior is platform-dependent, but normally the flash frequency is
......@@ -596,6 +589,8 @@ menu "Boot options"
config ZERO_PAGE_OFFSET
hex "Zero page offset"
default "0x00004000" if SH_MPC1211 || SH_SH03
default "0x00010000" if PAGE_SIZE_64KB
default "0x00002000" if PAGE_SIZE_8KB
default "0x00001000"
help
This sets the default offset of zero page.
......
......@@ -35,6 +35,7 @@ endif
endif
cflags-$(CONFIG_CPU_SH2) := -m2
cflags-$(CONFIG_CPU_SH2A) := -m2a $(call cc-option,-m2a-nofpu,)
cflags-$(CONFIG_CPU_SH3) := -m3
cflags-$(CONFIG_CPU_SH4) := -m4 \
$(call cc-option,-mno-implicit-fp,-m4-nofpu)
......@@ -93,10 +94,8 @@ machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300
machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343
machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180
machdir-$(CONFIG_SH_HP6XX) := hp6xx
machdir-$(CONFIG_SH_EC3104) := ec3104
machdir-$(CONFIG_SH_SATURN) := saturn
machdir-$(CONFIG_SH_DREAMCAST) := dreamcast
machdir-$(CONFIG_SH_BIGSUR) := bigsur
machdir-$(CONFIG_SH_MPC1211) := mpc1211
machdir-$(CONFIG_SH_SH03) := sh03
machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear
......
#
# Makefile for the BigSur specific parts of the kernel
#
obj-y := setup.o io.o irq.o led.o
/*
* arch/sh/boards/bigsur/io.c
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
* Derived from io_hd64465.h, which bore the message:
* By Greg Banks <gbanks@pocketpenguins.com>
* (c) 2000 PocketPenguins Inc.
* and from io_hd64461.h, which bore the message:
* Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* IO functions for a Hitachi Big Sur Evaluation Board.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/bigsur/bigsur.h>
/* Low iomap maps port 0-1K to addresses in 8byte chunks */
#define BIGSUR_IOMAP_LO_THRESH 0x400
#define BIGSUR_IOMAP_LO_SHIFT 3
#define BIGSUR_IOMAP_LO_MASK ((1<<BIGSUR_IOMAP_LO_SHIFT)-1)
#define BIGSUR_IOMAP_LO_NMAP (BIGSUR_IOMAP_LO_THRESH>>BIGSUR_IOMAP_LO_SHIFT)
static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP];
static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP];
/* High iomap maps port 1K-64K to addresses in 1K chunks */
#define BIGSUR_IOMAP_HI_THRESH 0x10000
#define BIGSUR_IOMAP_HI_SHIFT 10
#define BIGSUR_IOMAP_HI_MASK ((1<<BIGSUR_IOMAP_HI_SHIFT)-1)
#define BIGSUR_IOMAP_HI_NMAP (BIGSUR_IOMAP_HI_THRESH>>BIGSUR_IOMAP_HI_SHIFT)
static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP];
static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP];
void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
{
u32 port, endport = baseport + nports;
pr_debug("bigsur_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n",
baseport, nports, addr);
for (port = baseport ;
port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
pr_debug(" maplo[0x%x] = 0x%08x\n", port, addr);
bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = addr;
bigsur_iomap_lo_shift[port>>BIGSUR_IOMAP_LO_SHIFT] = shift;
addr += (1<<(BIGSUR_IOMAP_LO_SHIFT));
}
for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH);
port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
pr_debug(" maphi[0x%x] = 0x%08x\n", port, addr);
bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = addr;
bigsur_iomap_hi_shift[port>>BIGSUR_IOMAP_HI_SHIFT] = shift;
addr += (1<<(BIGSUR_IOMAP_HI_SHIFT));
}
}
EXPORT_SYMBOL(bigsur_port_map);
void bigsur_port_unmap(u32 baseport, u32 nports)
{
u32 port, endport = baseport + nports;
pr_debug("bigsur_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports);
for (port = baseport ;
port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0;
}
for (port = max_t(u32, baseport, BIGSUR_IOMAP_LO_THRESH);
port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0;
}
}
EXPORT_SYMBOL(bigsur_port_unmap);
unsigned long bigsur_isa_port2addr(unsigned long port)
{
unsigned long addr = 0;
unsigned char shift;
/* Physical address not in P0, do nothing */
if (PXSEG(port)) {
addr = port;
/* physical address in P0, map to P2 */
} else if (port >= 0x30000) {
addr = P2SEGADDR(port);
/* Big Sur I/O + HD64465 registers 0x10000-0x30000 */
} else if (port >= BIGSUR_IOMAP_HI_THRESH) {
addr = BIGSUR_INTERNAL_BASE + (port - BIGSUR_IOMAP_HI_THRESH);
/* Handle remapping of high IO/PCI IO ports */
} else if (port >= BIGSUR_IOMAP_LO_THRESH) {
addr = bigsur_iomap_hi[port >> BIGSUR_IOMAP_HI_SHIFT];
shift = bigsur_iomap_hi_shift[port >> BIGSUR_IOMAP_HI_SHIFT];
if (addr != 0)
addr += (port & BIGSUR_IOMAP_HI_MASK) << shift;
} else {
/* Handle remapping of low IO ports */
addr = bigsur_iomap_lo[port >> BIGSUR_IOMAP_LO_SHIFT];
shift = bigsur_iomap_lo_shift[port >> BIGSUR_IOMAP_LO_SHIFT];
if (addr != 0)
addr += (port & BIGSUR_IOMAP_LO_MASK) << shift;
}
pr_debug("%s(0x%08lx) = 0x%08lx\n", __FUNCTION__, port, addr);
return addr;
}
/*
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
*
* Setup and IRQ handling code for the HD64465 companion chip.
* by Greg Banks <gbanks@pocketpenguins.com>
* Copyright (c) 2000 PocketPenguins Inc
*
* Derived from setup_hd64465.c which bore the message:
* Greg Banks <gbanks@pocketpenguins.com>
* Copyright (c) 2000 PocketPenguins Inc and
* Copyright (C) 2000 YAEGASHI Takeshi
* and setup_cqreek.c which bore message:
* Copyright (C) 2000 Niibe Yutaka
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* IRQ functions for a Hitachi Big Sur Evaluation Board.
*
*/
#undef DEBUG
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/bigsur/io.h>
#include <asm/hd64465/hd64465.h>
#include <asm/bigsur/bigsur.h>
//#define BIGSUR_DEBUG 3
#undef BIGSUR_DEBUG
#ifdef BIGSUR_DEBUG
#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
#else
#define DIPRINTK(n, args...)
#endif /* BIGSUR_DEBUG */
#ifdef CONFIG_HD64465
extern int hd64465_irq_demux(int irq);
#endif /* CONFIG_HD64465 */
/*===========================================================*/
// Big Sur CPLD IRQ Routines
/*===========================================================*/
/* Level 1 IRQ routines */
static void disable_bigsur_l1irq(unsigned int irq)
{
unsigned char mask;
unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
pr_debug("Disable L1 IRQ %d\n", irq);
DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
/* Disable IRQ - set mask bit */
mask = inb(mask_port) | bit;
outb(mask, mask_port);
return;
}
pr_debug("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
}
static void enable_bigsur_l1irq(unsigned int irq)
{
unsigned char mask;
unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
pr_debug("Enable L1 IRQ %d\n", irq);
DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
/* Enable L1 IRQ - clear mask bit */
mask = inb(mask_port) & ~bit;
outb(mask, mask_port);
return;
}
pr_debug("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
}
/* Level 2 irq masks and registers for L2 decoding */
/* Level2 bitmasks for each level 1 IRQ */
const u32 bigsur_l2irq_mask[] =
{0x40,0x80,0x08,0x01,0x01,0x3C,0x3E,0xFF,0x40,0x80,0x06,0x03};
/* Level2 to ISR[n] map for each level 1 IRQ */
const u32 bigsur_l2irq_reg[] =
{ 2, 2, 3, 3, 1, 2, 1, 0, 1, 1, 3, 2};
/* Level2 to Level 1 IRQ map */
const u32 bigsur_l2_l1_map[] =
{7,7,7,7,7,7,7,7, 4,6,6,6,6,6,8,9, 11,11,5,5,5,5,0,1, 3,10,10,2,-1,-1,-1,-1};
/* IRQ inactive level (high or low) */
const u32 bigsur_l2_inactv_state[] = {0x00, 0xBE, 0xFC, 0xF7};
/* CPLD external status and mask registers base and offsets */
static const u32 isr_base = BIGSUR_IRQ0;
static const u32 isr_offset = BIGSUR_IRQ0 - BIGSUR_IRQ1;
static const u32 imr_base = BIGSUR_IMR0;
static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
#define REG_NUM(irq) ((irq-BIGSUR_2NDLVL_IRQ_LOW)/8 )
/* Level 2 IRQ routines */
static void disable_bigsur_l2irq(unsigned int irq)
{
unsigned char mask;
unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
pr_debug("Disable L2 IRQ %d\n", irq);
DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
/* Disable L2 IRQ - set mask bit */
mask = inb(mask_port) | bit;
outb(mask, mask_port);
return;
}
pr_debug("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
}
static void enable_bigsur_l2irq(unsigned int irq)
{
unsigned char mask;
unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
pr_debug("Enable L2 IRQ %d\n", irq);
DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
mask_port, bit);
/* Enable L2 IRQ - clear mask bit */
mask = inb(mask_port) & ~bit;
outb(mask, mask_port);
return;
}
pr_debug("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
}
static void mask_and_ack_bigsur(unsigned int irq)
{
pr_debug("mask_and_ack_bigsur IRQ %d\n", irq);
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
disable_bigsur_l1irq(irq);
else
disable_bigsur_l2irq(irq);
}
static void end_bigsur_irq(unsigned int irq)
{
pr_debug("end_bigsur_irq IRQ %d\n", irq);
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
enable_bigsur_l1irq(irq);
else
enable_bigsur_l2irq(irq);
}
}
static unsigned int startup_bigsur_irq(unsigned int irq)
{
u8 mask;
u32 reg;
pr_debug("startup_bigsur_irq IRQ %d\n", irq);
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
/* Enable the L1 IRQ */
enable_bigsur_l1irq(irq);
/* Enable all L2 IRQs in this L1 IRQ */
mask = ~(bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW]);
reg = imr_base - bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW] * imr_offset;
mask &= inb(reg);
outb(mask,reg);
DIPRINTK(2,"startup_bigsur_irq: IMR=0x%08x mask=0x%x\n",reg,inb(reg));
}
else {
/* Enable the L2 IRQ - clear mask bit */
enable_bigsur_l2irq(irq);
/* Enable the L1 bit masking this L2 IRQ */
enable_bigsur_l1irq(bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW]);
DIPRINTK(2,"startup_bigsur_irq: L1=%d L2=%d\n",
bigsur_l2_l1_map[irq-BIGSUR_2NDLVL_IRQ_LOW],irq);
}
return 0;
}
static void shutdown_bigsur_irq(unsigned int irq)
{
pr_debug("shutdown_bigsur_irq IRQ %d\n", irq);
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
disable_bigsur_l1irq(irq);
else
disable_bigsur_l2irq(irq);
}
/* Define the IRQ structures for the L1 and L2 IRQ types */
static struct hw_interrupt_type bigsur_l1irq_type = {
.typename = "BigSur-CPLD-Level1-IRQ",
.startup = startup_bigsur_irq,
.shutdown = shutdown_bigsur_irq,
.enable = enable_bigsur_l1irq,
.disable = disable_bigsur_l1irq,
.ack = mask_and_ack_bigsur,
.end = end_bigsur_irq
};
static struct hw_interrupt_type bigsur_l2irq_type = {
.typename = "BigSur-CPLD-Level2-IRQ",
.startup = startup_bigsur_irq,
.shutdown =shutdown_bigsur_irq,
.enable = enable_bigsur_l2irq,
.disable = disable_bigsur_l2irq,
.ack = mask_and_ack_bigsur,
.end = end_bigsur_irq
};
static void make_bigsur_l1isr(unsigned int irq) {
/* sanity check first */
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
/* save the handler in the main description table */
irq_desc[irq].chip = &bigsur_l1irq_type;
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = 0;
irq_desc[irq].depth = 1;
disable_bigsur_l1irq(irq);
return;
}
pr_debug("make_bigsur_l1isr: bad irq, %d\n", irq);
return;
}
static void make_bigsur_l2isr(unsigned int irq) {
/* sanity check first */
if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
/* save the handler in the main description table */
irq_desc[irq].chip = &bigsur_l2irq_type;
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = 0;
irq_desc[irq].depth = 1;
disable_bigsur_l2irq(irq);
return;
}
pr_debug("make_bigsur_l2isr: bad irq, %d\n", irq);
return;
}
/* The IRQ's will be decoded as follows:
* If a level 2 handler exists and there is an unmasked active
* IRQ, the 2nd level handler will be called.
* If a level 2 handler does not exist for the active IRQ
* the 1st level handler will be called.
*/
int bigsur_irq_demux(int irq)
{
int dmux_irq = irq;
u8 mask, actv_irqs;
u32 reg_num;
DIPRINTK(3,"bigsur_irq_demux, irq=%d\n", irq);
/* decode the 1st level IRQ */
if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
/* Get corresponding L2 ISR bitmask and ISR number */
mask = bigsur_l2irq_mask[irq-BIGSUR_IRQ_LOW];
reg_num = bigsur_l2irq_reg[irq-BIGSUR_IRQ_LOW];
/* find the active IRQ's (XOR with inactive level)*/
actv_irqs = inb(isr_base-reg_num*isr_offset) ^
bigsur_l2_inactv_state[reg_num];
/* decode active IRQ's */
actv_irqs = actv_irqs & mask & ~(inb(imr_base-reg_num*imr_offset));
/* if NEZ then we have an active L2 IRQ */
if(actv_irqs) dmux_irq = ffz(~actv_irqs) + reg_num*8+BIGSUR_2NDLVL_IRQ_LOW;
/* if no 2nd level IRQ action, but has 1st level, use 1st level handler */
if(!irq_desc[dmux_irq].action && irq_desc[irq].action)
dmux_irq = irq;
DIPRINTK(1,"bigsur_irq_demux: irq=%d dmux_irq=%d mask=0x%04x reg=%d\n",
irq, dmux_irq, mask, reg_num);
}
#ifdef CONFIG_HD64465
dmux_irq = hd64465_irq_demux(dmux_irq);
#endif /* CONFIG_HD64465 */
DIPRINTK(3,"bigsur_irq_demux, demux_irq=%d\n", dmux_irq);
return dmux_irq;
}
/*===========================================================*/
// Big Sur Init Routines
/*===========================================================*/
void __init init_bigsur_IRQ(void)
{
int i;
if (!MACH_BIGSUR) return;
/* Create ISR's for Big Sur CPLD IRQ's */
/*==============================================================*/
for(i=BIGSUR_IRQ_LOW;i<BIGSUR_IRQ_HIGH;i++)
make_bigsur_l1isr(i);
printk(KERN_INFO "Big Sur CPLD L1 interrupts %d to %d.\n",
BIGSUR_IRQ_LOW,BIGSUR_IRQ_HIGH);
for(i=BIGSUR_2NDLVL_IRQ_LOW;i<BIGSUR_2NDLVL_IRQ_HIGH;i++)
make_bigsur_l2isr(i);
printk(KERN_INFO "Big Sur CPLD L2 interrupts %d to %d.\n",
BIGSUR_2NDLVL_IRQ_LOW,BIGSUR_2NDLVL_IRQ_HIGH);
}
/*
* linux/arch/sh/boards/bigsur/led.c
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
* Derived from led_se.c and led.c, which bore the message:
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Big Sur specific LED code.
*/
#include <asm/io.h>
#include <asm/bigsur/bigsur.h>
static void mach_led(int position, int value)
{
int word;
word = bigsur_inl(BIGSUR_CSLR);
if (value) {
bigsur_outl(word & ~BIGSUR_LED, BIGSUR_CSLR);
} else {
bigsur_outl(word | BIGSUR_LED, BIGSUR_CSLR);
}
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
/* Cycle the LED on/off */
void heartbeat_bigsur(void)
{
static unsigned cnt = 0, period = 0, dist = 0;
if (cnt == 0 || cnt == dist)
mach_led( -1, 1);
else if (cnt == 7 || cnt == dist+7)
mach_led( -1, 0);
if (++cnt > period) {
cnt = 0;
/* The hyperbolic function below modifies the heartbeat period
* length in dependency of the current (5min) load. It goes
* through the points f(0)=126, f(1)=86, f(5)=51,
* f(inf)->30. */
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
dist = period / 4;
}
}
#endif /* CONFIG_HEARTBEAT */
/*
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
*
* Setup and IRQ handling code for the HD64465 companion chip.
* by Greg Banks <gbanks@pocketpenguins.com>
* Copyright (c) 2000 PocketPenguins Inc
*
* Derived from setup_hd64465.c which bore the message:
* Greg Banks <gbanks@pocketpenguins.com>
* Copyright (c) 2000 PocketPenguins Inc and
* Copyright (C) 2000 YAEGASHI Takeshi
* and setup_cqreek.c which bore message:
* Copyright (C) 2000 Niibe Yutaka
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Setup functions for a Hitachi Big Sur Evaluation Board.
*
*/
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/machvec.h>
#include <asm/bigsur/io.h>
#include <asm/hd64465/hd64465.h>
#include <asm/bigsur/bigsur.h>
/*===========================================================*/
// Big Sur Init Routines
/*===========================================================*/
static void __init bigsur_setup(char **cmdline_p)
{
/* Mask all 2nd level IRQ's */
outb(-1,BIGSUR_IMR0);
outb(-1,BIGSUR_IMR1);
outb(-1,BIGSUR_IMR2);
outb(-1,BIGSUR_IMR3);
/* Mask 1st level interrupts */
outb(-1,BIGSUR_IRLMR0);
outb(-1,BIGSUR_IRLMR1);
#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL)
/* remap IO ports for first ISA serial port to HD64465 UART */
bigsur_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
/* TODO: setup IDE registers */
bigsur_port_map(BIGSUR_IDECTL_IOPORT, 2, BIGSUR_ICTL, 8);
/* Setup the Ethernet port to BIGSUR_ETHER_IOPORT */
bigsur_port_map(BIGSUR_ETHER_IOPORT, 16, BIGSUR_ETHR+BIGSUR_ETHER_IOPORT, 0);
/* set page to 1 */
outw(1, BIGSUR_ETHR+0xe);
/* set the IO port to BIGSUR_ETHER_IOPORT */
outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
}
/*
* The Machine Vector
*/
extern void heartbeat_bigsur(void);
extern void init_bigsur_IRQ(void);
struct sh_machine_vector mv_bigsur __initmv = {
.mv_name = "Big Sur",
.mv_setup = bigsur_setup,
.mv_isa_port2addr = bigsur_isa_port2addr,
.mv_irq_demux = bigsur_irq_demux,
.mv_init_irq = init_bigsur_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_bigsur,
#endif
};
ALIAS_MV(bigsur)
#
# Makefile for the EC3104 specific parts of the kernel
#
obj-y := setup.o io.o irq.o
/*
* linux/arch/sh/boards/ec3104/io.c
* EC3104 companion chip support
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
*
*/
/* EC3104 note:
* This code was written without any documentation about the EC3104 chip. While
* I hope I got most of the basic functionality right, the register names I use
* are most likely completely different from those in the chip documentation.
*
* If you have any further information about the EC3104, please tell me
* (prumpf@tux.org).
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/ec3104/ec3104.h>
/*
* EC3104 has a real ISA bus which we redirect low port accesses to (the
* actual device on mine is a ESS 1868, and I don't want to hack the driver
* more than strictly necessary). I am not going to duplicate the
* hard coding of PC addresses (for the 16550s aso) here though; it's just
* too ugly.
*/
#define low_port(port) ((port) < 0x10000)
static inline unsigned long port2addr(unsigned long port)
{
switch(port >> 16) {
case 0:
return EC3104_ISA_BASE + port * 2;
/* XXX hack. it's unclear what to do about the serial ports */
case 1:
return EC3104_BASE + (port&0xffff) * 4;
default:
/* XXX PCMCIA */
return 0;
}
}
unsigned char ec3104_inb(unsigned long port)
{
u8 ret;
ret = *(volatile u8 *)port2addr(port);
return ret;
}
unsigned short ec3104_inw(unsigned long port)
{
BUG();
}
unsigned long ec3104_inl(unsigned long port)
{
BUG();
}
void ec3104_outb(unsigned char data, unsigned long port)
{
*(volatile u8 *)port2addr(port) = data;
}
void ec3104_outw(unsigned short data, unsigned long port)
{
BUG();
}
void ec3104_outl(unsigned long data, unsigned long port)
{
BUG();
}
/*
* linux/arch/sh/boards/ec3104/irq.c
* EC3104 companion chip support
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
*
*/
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/ec3104/ec3104.h>
/* This is for debugging mostly; here's the table that I intend to keep
* in here:
*
* index function base addr power interrupt bit
* 0 power b0ec0000 --- 00000001 (unused)
* 1 irqs b0ec1000 --- 00000002 (unused)
* 2 ?? b0ec2000 b0ec0008 00000004
* 3 PS2 (1) b0ec3000 b0ec000c 00000008
* 4 PS2 (2) b0ec4000 b0ec0010 00000010
* 5 ?? b0ec5000 b0ec0014 00000020
* 6 I2C b0ec6000 b0ec0018 00000040
* 7 serial (1) b0ec7000 b0ec001c 00000080
* 8 serial (2) b0ec8000 b0ec0020 00000100
* 9 serial (3) b0ec9000 b0ec0024 00000200
* 10 serial (4) b0eca000 b0ec0028 00000400
* 12 GPIO (1) b0ecc000 b0ec0030
* 13 GPIO (2) b0ecc000 b0ec0030
* 16 pcmcia (1) b0ed0000 b0ec0040 00010000
* 17 pcmcia (2) b0ed1000 b0ec0044 00020000
*/
/* I used the register names from another interrupt controller I worked with,
* since it seems to be identical to the ec3104 except that all bits are
* inverted:
*
* IRR: Interrupt Request Register (pending and enabled interrupts)
* IMR: Interrupt Mask Register (which interrupts are enabled)
* IPR: Interrupt Pending Register (pending interrupts, even disabled ones)
*
* 0 bits mean pending or enabled, 1 bits mean not pending or disabled. all
* IRQs seem to be level-triggered.
*/
#define EC3104_IRR (EC3104_BASE + 0x1000)
#define EC3104_IMR (EC3104_BASE + 0x1004)
#define EC3104_IPR (EC3104_BASE + 0x1008)
#define ctrl_readl(addr) (*(volatile u32 *)(addr))
#define ctrl_writel(data,addr) (*(volatile u32 *)(addr) = (data))
#define ctrl_readb(addr) (*(volatile u8 *)(addr))
static char *ec3104_name(unsigned index)
{
switch(index) {
case 0:
return "power management";
case 1:
return "interrupts";
case 3:
return "PS2 (1)";
case 4:
return "PS2 (2)";
case 5:
return "I2C (1)";
case 6:
return "I2C (2)";
case 7:
return "serial (1)";
case 8:
return "serial (2)";
case 9:
return "serial (3)";
case 10:
return "serial (4)";
case 16:
return "pcmcia (1)";
case 17:
return "pcmcia (2)";
default: {
static char buf[32];
sprintf(buf, "unknown (%d)", index);
return buf;
}
}
}
int get_pending_interrupts(char *buf)
{
u32 ipr;
u32 bit;
char *p = buf;
p += sprintf(p, "pending: (");
ipr = ctrl_inl(EC3104_IPR);
for (bit = 1; bit < 32; bit++)
if (!(ipr & (1<<bit)))
p += sprintf(p, "%s ", ec3104_name(bit));
p += sprintf(p, ")\n");
return p - buf;
}
static inline u32 ec3104_irq2mask(unsigned int irq)
{
return (1 << (irq - EC3104_IRQBASE));
}
static inline void mask_ec3104_irq(unsigned int irq)
{
u32 mask;
mask = ctrl_readl(EC3104_IMR);
mask |= ec3104_irq2mask(irq);
ctrl_writel(mask, EC3104_IMR);
}
static inline void unmask_ec3104_irq(unsigned int irq)
{
u32 mask;
mask = ctrl_readl(EC3104_IMR);
mask &= ~ec3104_irq2mask(irq);
ctrl_writel(mask, EC3104_IMR);
}
static void disable_ec3104_irq(unsigned int irq)
{
mask_ec3104_irq(irq);
}
static void enable_ec3104_irq(unsigned int irq)
{
unmask_ec3104_irq(irq);
}
static void mask_and_ack_ec3104_irq(unsigned int irq)
{
mask_ec3104_irq(irq);
}
static void end_ec3104_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
unmask_ec3104_irq(irq);
}
static unsigned int startup_ec3104_irq(unsigned int irq)
{
unmask_ec3104_irq(irq);
return 0;
}
static void shutdown_ec3104_irq(unsigned int irq)
{
mask_ec3104_irq(irq);
}
static struct hw_interrupt_type ec3104_int = {
.typename = "EC3104",
.enable = enable_ec3104_irq,
.disable = disable_ec3104_irq,
.ack = mask_and_ack_ec3104_irq,
.end = end_ec3104_irq,
.startup = startup_ec3104_irq,
.shutdown = shutdown_ec3104_irq,
};
/* Yuck. the _demux API is ugly */
int ec3104_irq_demux(int irq)
{
if (irq == EC3104_IRQ) {
unsigned int mask;
mask = ctrl_readl(EC3104_IRR);
if (mask == 0xffffffff)
return EC3104_IRQ;
else
return EC3104_IRQBASE + ffz(mask);
}
return irq;
}
/*
* linux/arch/sh/boards/ec3104/setup.c
* EC3104 companion chip support
*
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
*
*/
/* EC3104 note:
* This code was written without any documentation about the EC3104 chip. While
* I hope I got most of the basic functionality right, the register names I use
* are most likely completely different from those in the chip documentation.
*
* If you have any further information about the EC3104, please tell me
* (prumpf@tux.org).
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/machvec.h>
#include <asm/mach/ec3104.h>
static void __init ec3104_setup(char **cmdline_p)
{
char str[8];
int i;
for (i=0; i<8; i++)
str[i] = ctrl_readb(EC3104_BASE + i);
for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
irq_desc[i].handler = &ec3104_int;
printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
/* mask all interrupts. this should have been done by the boot
* loader for us but we want to be sure ... */
ctrl_writel(0xffffffff, EC3104_IMR);
}
/*
* The Machine Vector
*/
struct sh_machine_vector mv_ec3104 __initmv = {
.mv_name = "EC3104",
.mv_setup = ec3104_setup,
.mv_nr_irqs = 96,
.mv_inb = ec3104_inb,
.mv_inw = ec3104_inw,
.mv_inl = ec3104_inl,
.mv_outb = ec3104_outb,
.mv_outw = ec3104_outw,
.mv_outl = ec3104_outl,
.mv_irq_demux = ec3104_irq_demux,
};
ALIAS_MV(ec3104)
......@@ -2,7 +2,7 @@
# Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel
#
obj-y := setup.o rtc.o led.o
obj-y := setup.o rtc.o
obj-$(CONFIG_PCI) += pci.o
/*
* linux/arch/sh/boards/mpc1211/led.c
*
* Copyright (C) 2001 Saito.K & Jeanne
*
* This file contains Interface MPC-1211 specific LED code.
*/
static void mach_led(int position, int value)
{
volatile unsigned char* p = (volatile unsigned char*)0xa2000000;
if (value) {
*p |= 1;
} else {
*p &= ~1;
}
}
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_mpc1211(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned char* p = (volatile unsigned char*)0xa2000000;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if (up) {
if (bit == 7) {
bit--;
up=0;
} else {
bit ++;
}
} else {
if (bit == 0) {
bit++;
up=1;
} else {
bit--;
}
}
*p = 1<<bit;
}
#endif /* CONFIG_HEARTBEAT */
......@@ -10,6 +10,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/machvec.h>
#include <asm/mpc1211/mpc1211.h>
......@@ -281,6 +282,32 @@ static int put_smb_blk(unsigned char *p, int address, int command, int no)
return 0;
}
static struct resource heartbeat_resources[] = {
[0] = {
.start = 0xa2000000,
.end = 0xa2000000 + 8 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *mpc1211_devices[] __initdata = {
&heartbeat_device,
};
static int __init mpc1211_devices_setup(void)
{
return platform_add_devices(mpc1211_devices,
ARRAY_SIZE(mpc1211_devices));
}
__initcall(mpc1211_devices_setup);
/* arch/sh/boards/mpc1211/rtc.c */
void mpc1211_time_init(void);
......@@ -317,9 +344,5 @@ struct sh_machine_vector mv_mpc1211 __initmv = {
.mv_nr_irqs = 48,
.mv_irq_demux = mpc1211_irq_demux,
.mv_init_irq = init_mpc1211_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_mpc1211,
#endif
};
ALIAS_MV(mpc1211)
......@@ -4,5 +4,4 @@
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
obj-$(CONFIG_PUSH_SWITCH) += psw.o
......@@ -11,22 +11,9 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/io.h>
#include <asm/r7780rp.h>
#include <asm/addrspace.h>
#include <asm/io.h>
static inline unsigned long port2adr(unsigned int port)
{
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
if (port == 0x3f6)
return (PA_AREA5_IO + 0x80c);
else
return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
else
maybebadio((unsigned long)port);
return port;
}
static inline unsigned long port88796l(unsigned int port, int flag)
{
......@@ -40,18 +27,6 @@ static inline unsigned long port88796l(unsigned int port, int flag)
return addr;
}
/* The 7780 R7780RP-1 seems to have everything hooked */
/* up pretty normally (nothing on high-bytes only...) so this */
/* shouldn't be needed */
static inline int shifted_port(unsigned long port)
{
/* For IDE registers, value is not shifted */
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
return 0;
else
return 1;
}
#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
#define CHECK_AX88796L_PORT(port) \
((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
......@@ -70,12 +45,10 @@ u8 r7780rp_inb(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
return ctrl_inw(port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
return ctrl_inb(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
return ctrl_inb(pci_ioaddr(port));
return ctrl_inw(port2adr(port)) & 0xff;
return ctrl_inw(port) & 0xff;
}
u8 r7780rp_inb_p(unsigned long port)
......@@ -84,12 +57,10 @@ u8 r7780rp_inb_p(unsigned long port)
if (CHECK_AX88796L_PORT(port))
v = ctrl_inw(port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
v = ctrl_inb(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
v = ctrl_inb(pci_ioaddr(port));
else
v = ctrl_inw(port2adr(port)) & 0xff;
v = ctrl_inw(port) & 0xff;
ctrl_delay();
......@@ -98,80 +69,56 @@ u8 r7780rp_inb_p(unsigned long port)
u16 r7780rp_inw(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
return ctrl_inw(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
if (is_pci_ioaddr(port))
return ctrl_inw(pci_ioaddr(port));
else
maybebadio(port);
return 0;
return ctrl_inw(port);
}
u32 r7780rp_inl(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
return ctrl_inl(port);
else if (is_pci_ioaddr(port) || shifted_port(port))
if (is_pci_ioaddr(port))
return ctrl_inl(pci_ioaddr(port));
else
maybebadio(port);
return 0;
return ctrl_inl(port);
}
void r7780rp_outb(u8 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
ctrl_outw(value, port88796l(port, 0));
else if (PXSEG(port))
ctrl_outb(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
ctrl_outb(value, port);
}
void r7780rp_outb_p(u8 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
ctrl_outw(value, port88796l(port, 0));
else if (PXSEG(port))
ctrl_outb(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
ctrl_outb(value, pci_ioaddr(port));
else
ctrl_outw(value, port2adr(port));
ctrl_outb(value, port);
ctrl_delay();
}
void r7780rp_outw(u16 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
ctrl_outw(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
if (is_pci_ioaddr(port))
ctrl_outw(value, pci_ioaddr(port));
else
maybebadio(port);
ctrl_outw(value, port);
}
void r7780rp_outl(u32 value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
ctrl_outl(value, port);
else if (is_pci_ioaddr(port) || shifted_port(port))
if (is_pci_ioaddr(port))
ctrl_outl(value, pci_ioaddr(port));
else
maybebadio(port);
ctrl_outl(value, port);
}
void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
......@@ -183,16 +130,13 @@ void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
p = (volatile u16 *)port88796l(port, 0);
while (count--)
*buf++ = *p & 0xff;
} else if (PXSEG(port)) {
while (count--)
*buf++ = *(volatile u8 *)port;
} else if (is_pci_ioaddr(port) || shifted_port(port)) {
} else if (is_pci_ioaddr(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--)
*buf++ = *bp;
} else {
p = (volatile u16 *)port2adr(port);
p = (volatile u16 *)port;
while (count--)
*buf++ = *p & 0xff;
}
......@@ -205,30 +149,26 @@ void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
if (CHECK_AX88796L_PORT(port))
p = (volatile u16 *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile u16 *)port2adr(port);
p = (volatile u16 *)port;
while (count--)
*buf++ = *p;
flush_dcache_all();
}
void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
{
u32 *buf = dst;
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
if (is_pci_ioaddr(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
u32 *buf = dst;
while (count--)
*buf++ = *p;
} else
maybebadio(port);
}
}
void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
......@@ -240,19 +180,14 @@ void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
p = (volatile u16 *)port88796l(port, 0);
while (count--)
*p = *buf++;
} else if (PXSEG(port))
while (count--)
ctrl_outb(*buf++, port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
} else if (is_pci_ioaddr(port)) {
volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
while (count--)
*bp = *buf++;
} else {
p = (volatile u16 *)port2adr(port);
} else
while (count--)
*p = *buf++;
}
ctrl_outb(*buf++, port);
}
void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
......@@ -262,40 +197,37 @@ void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
if (CHECK_AX88796L_PORT(port))
p = (volatile u16 *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile u16 *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
p = (volatile u16 *)pci_ioaddr(port);
else
p = (volatile u16 *)port2adr(port);
p = (volatile u16 *)port;
while (count--)
*p = *buf++;
flush_dcache_all();
}
void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
{
const u32 *buf = src;
u32 *p;
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
if (is_pci_ioaddr(port))
p = (u32 *)pci_ioaddr(port);
else
p = (u32 *)port;
while (count--)
*p = *buf++;
} else
maybebadio(port);
while (count--)
ctrl_outl(*buf++, (unsigned long)p);
}
void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
{
if (CHECK_AX88796L_PORT(port))
return (void __iomem *)port88796l(port, size > 1);
else if (PXSEG(port))
return (void __iomem *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
else if (is_pci_ioaddr(port))
return (void __iomem *)pci_ioaddr(port);
return (void __iomem *)port2adr(port);
return (void __iomem *)port;
}
/*
* Copyright (C) Atom Create Engineering Co., Ltd.
*
* May be copied or modified under the terms of GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
*/
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/r7780rp/r7780rp.h>
/* Cycle the LED's in the clasic Knightriger/Sun pattern */
void heartbeat_r7780rp(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *)PA_OBLED;
static unsigned bit = 0, up = 1;
unsigned bit_pos[] = {2, 1, 0, 3, 6, 5, 4, 7};
cnt += 1;
if (cnt < period)
return;
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
*/
period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
*p = 1 << bit_pos[bit];
if (up)
if (bit == 7) {
bit--;
up = 0;
} else
bit++;
else if (bit == 0)
up = 1;
else
bit--;
}
......@@ -2,7 +2,7 @@
* arch/sh/boards/renesas/r7780rp/setup.c
*
* Copyright (C) 2002 Atom Create Engineering Co., Ltd.
* Copyright (C) 2005, 2006 Paul Mundt
* Copyright (C) 2005 - 2007 Paul Mundt
*
* Renesas Solutions Highlander R7780RP-1 Support.
*
......@@ -12,12 +12,12 @@
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pata_platform.h>
#include <asm/machvec.h>
#include <asm/r7780rp.h>
#include <asm/clock.h>
#include <asm/io.h>
extern void heartbeat_r7780rp(void);
extern void init_r7780rp_IRQ(void);
static struct resource m66596_usb_host_resources[] = {
......@@ -46,14 +46,14 @@ static struct platform_device m66596_usb_host_device = {
static struct resource cf_ide_resources[] = {
[0] = {
.start = 0x1f0,
.end = 0x1f0 + 8,
.flags = IORESOURCE_IO,
.start = PA_AREA5_IO + 0x1000,
.end = PA_AREA5_IO + 0x1000 + 0x08 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0x1f0 + 0x206,
.end = 0x1f0 + 8 + 0x206 + 8,
.flags = IORESOURCE_IO,
.start = PA_AREA5_IO + 0x80c,
.end = PA_AREA5_IO + 0x80c + 0x16 - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
#ifdef CONFIG_SH_R7780MP
......@@ -65,16 +65,44 @@ static struct resource cf_ide_resources[] = {
},
};
static struct pata_platform_info pata_info = {
.ioport_shift = 1,
};
static struct platform_device cf_ide_device = {
.name = "pata_platform",
.id = -1,
.num_resources = ARRAY_SIZE(cf_ide_resources),
.resource = cf_ide_resources,
.dev = {
.platform_data = &pata_info,
},
};
static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 };
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_OBLED,
.end = PA_OBLED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.dev = {
.platform_data = heartbeat_bit_pos,
},
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *r7780rp_devices[] __initdata = {
&m66596_usb_host_device,
&cf_ide_device,
&heartbeat_device,
};
static int __init r7780rp_devices_setup(void)
......@@ -148,7 +176,7 @@ static void __init r7780rp_setup(char **cmdline_p)
#ifndef CONFIG_SH_R7780MP
ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
#endif
ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x0100, PA_IVDRCTL); /* Si13112 */
ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */
pm_power_off = r7780rp_power_off;
}
......@@ -185,8 +213,5 @@ struct sh_machine_vector mv_r7780rp __initmv = {
.mv_ioport_map = r7780rp_ioport_map,
.mv_init_irq = init_r7780rp_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_r7780rp,
#endif
};
ALIAS_MV(r7780rp)
......@@ -2,5 +2,4 @@
# Makefile for the RTS7751R2D specific parts of the kernel
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
obj-y := setup.o irq.o
/*
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
* I/O routine for Renesas Technology sales RTS7751R2D.
*
* Initial version only to support LAN access; some
* placeholder code from io_rts7751r2d.c left in with the
* expectation of later SuperIO and PCMCIA access.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <asm/rts7751r2d.h>
#include <asm/addrspace.h>
/*
* The 7751R RTS7751R2D uses the built-in PCI controller (PCIC)
* of the 7751R processor, and has a SuperIO accessible via the PCI.
* The board also includes a PCMCIA controller on its memory bus,
* like the other Solution Engine boards.
*/
static inline unsigned long port2adr(unsigned int port)
{
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
if (port == 0x3f6)
return (PA_AREA5_IO + 0x80c);
else
return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
else
maybebadio((unsigned long)port);
return port;
}
static inline unsigned long port88796l(unsigned int port, int flag)
{
unsigned long addr;
if (flag)
addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
else
addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
return addr;
}
/* The 7751R RTS7751R2D seems to have everything hooked */
/* up pretty normally (nothing on high-bytes only...) so this */
/* shouldn't be needed */
static inline int shifted_port(unsigned long port)
{
/* For IDE registers, value is not shifted */
if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
return 0;
else
return 1;
}
#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
#define CHECK_AX88796L_PORT(port) \
((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
#else
#define CHECK_AX88796L_PORT(port) (0)
#endif
/*
* General outline: remap really low stuff [eventually] to SuperIO,
* stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
* is mapped through the PCI IO window. Stuff with high bits (PXSEG)
* should be way beyond the window, and is used w/o translation for
* compatibility.
*/
unsigned char rts7751r2d_inb(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
return *(volatile unsigned char *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
return *(volatile unsigned char *)pci_ioaddr(port);
else
return (*(volatile unsigned short *)port2adr(port) & 0xff);
}
unsigned char rts7751r2d_inb_p(unsigned long port)
{
unsigned char v;
if (CHECK_AX88796L_PORT(port))
v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
else if (PXSEG(port))
v = *(volatile unsigned char *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
v = *(volatile unsigned char *)pci_ioaddr(port);
else
v = (*(volatile unsigned short *)port2adr(port) & 0xff);
ctrl_delay();
return v;
}
unsigned short rts7751r2d_inw(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
return *(volatile unsigned short *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
return *(volatile unsigned short *)pci_ioaddr(port);
else
maybebadio(port);
return 0;
}
unsigned int rts7751r2d_inl(unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
return *(volatile unsigned long *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
return *(volatile unsigned long *)pci_ioaddr(port);
else
maybebadio(port);
return 0;
}
void rts7751r2d_outb(unsigned char value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
*((volatile unsigned short *)port88796l(port, 0)) = value;
else if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned char *)pci_ioaddr(port) = value;
else
*(volatile unsigned short *)port2adr(port) = value;
}
void rts7751r2d_outb_p(unsigned char value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
*((volatile unsigned short *)port88796l(port, 0)) = value;
else if (PXSEG(port))
*(volatile unsigned char *)port = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned char *)pci_ioaddr(port) = value;
else
*(volatile unsigned short *)port2adr(port) = value;
ctrl_delay();
}
void rts7751r2d_outw(unsigned short value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
*(volatile unsigned short *)port = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned short *)pci_ioaddr(port) = value;
else
maybebadio(port);
}
void rts7751r2d_outl(unsigned int value, unsigned long port)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (PXSEG(port))
*(volatile unsigned long *)port = value;
else if (is_pci_ioaddr(port) || shifted_port(port))
*(volatile unsigned long *)pci_ioaddr(port) = value;
else
maybebadio(port);
}
void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u8 *bp;
volatile __u16 *p;
if (CHECK_AX88796L_PORT(port)) {
p = (volatile unsigned short *)port88796l(port, 0);
while (count--)
ctrl_outb(*p & 0xff, a++);
} else if (PXSEG(port))
while (count--)
ctrl_outb(ctrl_inb(port), a++);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
bp = (__u8 *)pci_ioaddr(port);
while (count--)
ctrl_outb(*bp, a++);
} else {
p = (volatile unsigned short *)port2adr(port);
while (count--)
ctrl_outb(*p & 0xff, a++);
}
}
void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u16 *p;
if (CHECK_AX88796L_PORT(port))
p = (volatile unsigned short *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile unsigned short *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile unsigned short *)pci_ioaddr(port);
else
p = (volatile unsigned short *)port2adr(port);
while (count--)
ctrl_outw(*p, a++);
}
void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
unsigned long a = (unsigned long)addr;
while (count--) {
ctrl_outl(ctrl_inl(pci_ioaddr(port)), a);
a += 4;
}
} else
maybebadio(port);
}
void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u8 *bp;
volatile __u16 *p;
if (CHECK_AX88796L_PORT(port)) {
p = (volatile unsigned short *)port88796l(port, 0);
while (count--)
*p = ctrl_inb(a++);
} else if (PXSEG(port))
while (count--)
ctrl_outb(a++, port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
bp = (__u8 *)pci_ioaddr(port);
while (count--)
*bp = ctrl_inb(a++);
} else {
p = (volatile unsigned short *)port2adr(port);
while (count--)
*p = ctrl_inb(a++);
}
}
void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
{
unsigned long a = (unsigned long)addr;
volatile __u16 *p;
if (CHECK_AX88796L_PORT(port))
p = (volatile unsigned short *)port88796l(port, 1);
else if (PXSEG(port))
p = (volatile unsigned short *)port;
else if (is_pci_ioaddr(port) || shifted_port(port))
p = (volatile unsigned short *)pci_ioaddr(port);
else
p = (volatile unsigned short *)port2adr(port);
while (count--) {
ctrl_outw(*p, a);
a += 2;
}
}
void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
{
if (CHECK_AX88796L_PORT(port))
maybebadio(port);
else if (is_pci_ioaddr(port) || shifted_port(port)) {
unsigned long a = (unsigned long)addr;
while (count--) {
ctrl_outl(ctrl_inl(a), pci_ioaddr(port));
a += 4;
}
} else
maybebadio(port);
}
unsigned long rts7751r2d_isa_port2addr(unsigned long offset)
{
return port2adr(offset);
}
......@@ -9,7 +9,9 @@
* Atom Create Engineering Co., Ltd. 2002.
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/rts7751r2d.h>
......@@ -22,79 +24,31 @@ static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0};
extern int voyagergx_irq_demux(int irq);
extern void setup_voyagergx_irq(void);
static void enable_rts7751r2d_irq(unsigned int irq);
static void disable_rts7751r2d_irq(unsigned int irq);
/* shutdown is same as "disable" */
#define shutdown_rts7751r2d_irq disable_rts7751r2d_irq
static void ack_rts7751r2d_irq(unsigned int irq);
static void end_rts7751r2d_irq(unsigned int irq);
static unsigned int startup_rts7751r2d_irq(unsigned int irq)
static void enable_rts7751r2d_irq(unsigned int irq)
{
enable_rts7751r2d_irq(irq);
return 0; /* never anything pending */
/* Set priority in IPR back to original value */
ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1);
}
static void disable_rts7751r2d_irq(unsigned int irq)
{
unsigned short val;
unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
/* Set the priority in IPR to 0 */
val = ctrl_inw(IRLCNTR1);
val &= mask;
ctrl_outw(val, IRLCNTR1);
}
static void enable_rts7751r2d_irq(unsigned int irq)
{
unsigned short val;
unsigned short value = (0x0001 << mask_pos[irq]);
/* Set priority in IPR back to original value */
val = ctrl_inw(IRLCNTR1);
val |= value;
ctrl_outw(val, IRLCNTR1);
ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])),
IRLCNTR1);
}
int rts7751r2d_irq_demux(int irq)
{
int demux_irq;
demux_irq = voyagergx_irq_demux(irq);
return demux_irq;
}
static void ack_rts7751r2d_irq(unsigned int irq)
{
disable_rts7751r2d_irq(irq);
return voyagergx_irq_demux(irq);
}
static void end_rts7751r2d_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_rts7751r2d_irq(irq);
}
static struct hw_interrupt_type rts7751r2d_irq_type = {
.typename = "RTS7751R2D IRQ",
.startup = startup_rts7751r2d_irq,
.shutdown = shutdown_rts7751r2d_irq,
.enable = enable_rts7751r2d_irq,
.disable = disable_rts7751r2d_irq,
.ack = ack_rts7751r2d_irq,
.end = end_rts7751r2d_irq,
static struct irq_chip rts7751r2d_irq_chip __read_mostly = {
.name = "rts7751r2d",
.mask = disable_rts7751r2d_irq,
.unmask = enable_rts7751r2d_irq,
.mask_ack = disable_rts7751r2d_irq,
};
static void make_rts7751r2d_irq(unsigned int irq)
{
disable_irq_nosync(irq);
irq_desc[irq].chip = &rts7751r2d_irq_type;
disable_rts7751r2d_irq(irq);
}
/*
* Initialize IRQ setting
*/
......@@ -119,8 +73,12 @@ void __init init_rts7751r2d_IRQ(void)
* IRL14=Extention #3
*/
for (i=0; i<15; i++)
make_rts7751r2d_irq(i);
for (i=0; i<15; i++) {
disable_irq_nosync(i);
set_irq_chip_and_handler_name(i, &rts7751r2d_irq_chip,
handle_level_irq, "level");
enable_rts7751r2d_irq(i);
}
setup_voyagergx_irq();
}
/*
* linux/arch/sh/boards/renesas/rts7751r2d/led.c
*
* Copyright (C) Atom Create Engineering Co., Ltd.
*
* May be copied or modified under the terms of GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Renesas Technology Sales RTS7751R2D specific LED code.
*/
#include <linux/io.h>
#include <linux/sched.h>
#include <asm/rts7751r2d.h>
/* Cycle the LED's in the clasic Knightriger/Sun pattern */
void heartbeat_rts7751r2d(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *)PA_OUTPORT;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period)
return;
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
*/
period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
*p = 1 << bit;
if (up)
if (bit == 7) {
bit--;
up = 0;
} else
bit++;
else if (bit == 0)
up = 1;
else
bit--;
}
/*
* Renesas Technology Sales RTS7751R2D Support.
*
* Copyright (C) 2002 Atom Create Engineering Co., Ltd.
* Copyright (C) 2004 - 2006 Paul Mundt
* Copyright (C) 2002 - 2006 Atom Create Engineering Co., Ltd.
* Copyright (C) 2004 - 2007 Paul Mundt
*
* 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
......@@ -10,33 +10,13 @@
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pata_platform.h>
#include <linux/serial_8250.h>
#include <linux/pm.h>
#include <asm/machvec.h>
#include <asm/mach/rts7751r2d.h>
#include <asm/io.h>
#include <asm/rts7751r2d.h>
#include <asm/voyagergx.h>
extern void heartbeat_rts7751r2d(void);
extern void init_rts7751r2d_IRQ(void);
extern int rts7751r2d_irq_demux(int irq);
extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
static struct plat_serial8250_port uart_platform_data[] = {
{
.membase = (void *)VOYAGER_UART_BASE,
.mapbase = VOYAGER_UART_BASE,
.iotype = UPIO_MEM,
.irq = VOYAGER_UART0_IRQ,
.flags = UPF_BOOT_AUTOCONF,
.regshift = 2,
.uartclk = (9600 * 16),
}, {
.flags = 0,
},
};
#include <asm/io.h>
static void __init voyagergx_serial_init(void)
{
......@@ -45,32 +25,96 @@ static void __init voyagergx_serial_init(void)
/*
* GPIO Control
*/
val = inl(GPIO_MUX_HIGH);
val = readl((void __iomem *)GPIO_MUX_HIGH);
val |= 0x00001fe0;
outl(val, GPIO_MUX_HIGH);
writel(val, (void __iomem *)GPIO_MUX_HIGH);
/*
* Power Mode Gate
*/
val = inl(POWER_MODE0_GATE);
val = readl((void __iomem *)POWER_MODE0_GATE);
val |= (POWER_MODE0_GATE_U0 | POWER_MODE0_GATE_U1);
outl(val, POWER_MODE0_GATE);
writel(val, (void __iomem *)POWER_MODE0_GATE);
val = inl(POWER_MODE1_GATE);
val = readl((void __iomem *)POWER_MODE1_GATE);
val |= (POWER_MODE1_GATE_U0 | POWER_MODE1_GATE_U1);
outl(val, POWER_MODE1_GATE);
writel(val, (void __iomem *)POWER_MODE1_GATE);
}
static struct resource cf_ide_resources[] = {
[0] = {
.start = PA_AREA5_IO + 0x1000,
.end = PA_AREA5_IO + 0x1000 + 0x08 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = PA_AREA5_IO + 0x80c,
.end = PA_AREA5_IO + 0x80c + 0x16 - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
#ifdef CONFIG_RTS7751R2D_REV11
.start = 1,
#else
.start = 2,
#endif
.flags = IORESOURCE_IRQ,
},
};
static struct pata_platform_info pata_info = {
.ioport_shift = 1,
};
static struct platform_device cf_ide_device = {
.name = "pata_platform",
.id = -1,
.num_resources = ARRAY_SIZE(cf_ide_resources),
.resource = cf_ide_resources,
.dev = {
.platform_data = &pata_info,
},
};
static struct plat_serial8250_port uart_platform_data[] = {
{
.membase = (void __iomem *)VOYAGER_UART_BASE,
.mapbase = VOYAGER_UART_BASE,
.iotype = UPIO_MEM,
.irq = VOYAGER_UART0_IRQ,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
.regshift = 2,
.uartclk = (9600 * 16),
}
};
static struct platform_device uart_device = {
.name = "serial8250",
.id = -1,
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = uart_platform_data,
},
};
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_OUTPORT,
.end = PA_OUTPORT + 8 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *rts7751r2d_devices[] __initdata = {
&uart_device,
&heartbeat_device,
&cf_ide_device,
};
static int __init rts7751r2d_devices_setup(void)
......@@ -78,6 +122,7 @@ static int __init rts7751r2d_devices_setup(void)
return platform_add_devices(rts7751r2d_devices,
ARRAY_SIZE(rts7751r2d_devices));
}
__initcall(rts7751r2d_devices_setup);
static void rts7751r2d_power_off(void)
{
......@@ -89,14 +134,17 @@ static void rts7751r2d_power_off(void)
*/
static void __init rts7751r2d_setup(char **cmdline_p)
{
device_initcall(rts7751r2d_devices_setup);
u16 ver = ctrl_inw(PA_VERREG);
printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
printk(KERN_INFO "FPGA version:%d (revision:%d)\n",
(ver >> 4) & 0xf, ver & 0xf);
ctrl_outw(0x0000, PA_OUTPORT);
pm_power_off = rts7751r2d_power_off;
voyagergx_serial_init();
printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
}
/*
......@@ -107,31 +155,7 @@ struct sh_machine_vector mv_rts7751r2d __initmv = {
.mv_setup = rts7751r2d_setup,
.mv_nr_irqs = 72,
.mv_inb = rts7751r2d_inb,
.mv_inw = rts7751r2d_inw,
.mv_inl = rts7751r2d_inl,
.mv_outb = rts7751r2d_outb,
.mv_outw = rts7751r2d_outw,
.mv_outl = rts7751r2d_outl,
.mv_inb_p = rts7751r2d_inb_p,
.mv_inw_p = rts7751r2d_inw,
.mv_inl_p = rts7751r2d_inl,
.mv_outb_p = rts7751r2d_outb_p,
.mv_outw_p = rts7751r2d_outw,
.mv_outl_p = rts7751r2d_outl,
.mv_insb = rts7751r2d_insb,
.mv_insw = rts7751r2d_insw,
.mv_insl = rts7751r2d_insl,
.mv_outsb = rts7751r2d_outsb,
.mv_outsw = rts7751r2d_outsw,
.mv_outsl = rts7751r2d_outsl,
.mv_init_irq = init_rts7751r2d_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_rts7751r2d,
#endif
.mv_irq_demux = rts7751r2d_irq_demux,
#ifdef CONFIG_USB_SM501
......
......@@ -3,5 +3,3 @@
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
/*
* linux/arch/sh/kernel/led_se.c
*
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Solution Engine specific LED code.
*/
#include <linux/config.h>
#include <asm/se7206.h>
#ifdef CONFIG_HEARTBEAT
#include <linux/sched.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short* p = (volatile unsigned short*)PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if (up) {
if (bit == 7) {
bit--;
up=0;
} else {
bit ++;
}
} else {
if (bit == 0) {
bit++;
up=1;
} else {
bit--;
}
}
*p = 1<<(bit+8);
}
#endif /* CONFIG_HEARTBEAT */
......@@ -3,6 +3,7 @@
* linux/arch/sh/boards/se/7206/setup.c
*
* Copyright (C) 2006 Yoshinori Sato
* Copyright (C) 2007 Paul Mundt
*
* Hitachi 7206 SolutionEngine Support.
*
......@@ -34,15 +35,37 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
.end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.dev = {
.platform_data = heartbeat_bit_pos,
},
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *se7206_devices[] __initdata = {
&smc91x_device,
&heartbeat_device,
};
static int __init se7206_devices_setup(void)
{
return platform_device_register(&smc91x_device);
return platform_add_devices(se7206_devices, ARRAY_SIZE(se7206_devices));
}
__initcall(se7206_devices_setup);
void heartbeat_se(void);
/*
* The Machine Vector
*/
......@@ -72,8 +95,5 @@ struct sh_machine_vector mv_se __initmv = {
.mv_outsl = se7206_outsl,
.mv_init_irq = init_se7206_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_se,
#endif
};
ALIAS_MV(se)
......@@ -3,5 +3,3 @@
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
/*
* linux/arch/sh/boards/se/7300/led.c
*
* Derived from linux/arch/sh/boards/se/770x/led.c
*
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Solution Engine specific LED code.
*/
#include <linux/sched.h>
#include <asm/se7300.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_7300se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *) PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
if (up) {
if (bit == 7) {
bit--;
up = 0;
} else {
bit++;
}
} else {
if (bit == 0) {
bit++;
up = 1;
} else {
bit--;
}
}
*p = 1 << (bit + 8);
}
......@@ -6,14 +6,43 @@
* SH-Mobile SolutionEngine 7300 Support.
*
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/se7300.h>
void heartbeat_7300se(void);
void init_7300se_IRQ(void);
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
.end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.dev = {
.platform_data = heartbeat_bit_pos,
},
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *se7300_devices[] __initdata = {
&heartbeat_device,
};
static int __init se7300_devices_setup(void)
{
return platform_add_devices(se7300_devices, ARRAY_SIZE(se7300_devices));
}
__initcall(se7300_devices_setup);
/*
* The Machine Vector
*/
......@@ -42,8 +71,5 @@ struct sh_machine_vector mv_7300se __initmv = {
.mv_outsl = sh7300se_outsl,
.mv_init_irq = init_7300se_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_7300se,
#endif
};
ALIAS_MV(7300se)
......@@ -3,5 +3,3 @@
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
/*
* arch/sh/boards/se/73180/led.c
*
* Derived from arch/sh/boards/se/770x/led.c
*
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Solution Engine specific LED code.
*/
#include <linux/sched.h>
#include <asm/mach/se73180.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_73180se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *) PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
if (up) {
if (bit == 7) {
bit--;
up = 0;
} else {
bit++;
}
} else {
if (bit == 0) {
bit++;
up = 1;
} else {
bit--;
}
}
*p = 1 << (bit + LED_SHIFT);
}
......@@ -10,13 +10,39 @@
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/se73180.h>
#include <asm/irq.h>
void heartbeat_73180se(void);
void init_73180se_IRQ(void);
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
.end = PA_LED + 8 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *se73180_devices[] __initdata = {
&heartbeat_device,
};
static int __init se73180_devices_setup(void)
{
return platform_add_devices(sh7343se_platform_devices,
ARRAY_SIZE(sh7343se_platform_devices));
}
__initcall(se73180_devices_setup);
/*
* The Machine Vector
*/
......@@ -46,8 +72,5 @@ struct sh_machine_vector mv_73180se __initmv = {
.mv_init_irq = init_73180se_IRQ,
.mv_irq_demux = shmse_irq_demux,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_73180se,
#endif
};
ALIAS_MV(73180se)
......@@ -3,5 +3,3 @@
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
/*
* arch/sh/boards/se/7343/led.c
*
*/
#include <linux/sched.h>
#include <asm/mach/se7343.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_7343se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short *p = (volatile unsigned short *) PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
if (up) {
if (bit == 7) {
bit--;
up = 0;
} else {
bit++;
}
} else {
if (bit == 0) {
bit++;
up = 1;
} else {
bit--;
}
}
*p = 1 << (bit + LED_SHIFT);
}
......@@ -4,7 +4,6 @@
#include <asm/mach/se7343.h>
#include <asm/irq.h>
void heartbeat_7343se(void);
void init_7343se_IRQ(void);
static struct resource smc91x_resources[] = {
......@@ -31,14 +30,30 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
static struct platform_device *smc91x_platform_devices[] __initdata = {
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
.end = PA_LED + 8 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *sh7343se_platform_devices[] __initdata = {
&smc91x_device,
&heartbeat_device,
};
static int __init sh7343se_devices_setup(void)
{
return platform_add_devices(smc91x_platform_devices,
ARRAY_SIZE(smc91x_platform_devices));
return platform_add_devices(sh7343se_platform_devices,
ARRAY_SIZE(sh7343se_platform_devices));
}
static void __init sh7343se_setup(char **cmdline_p)
......@@ -76,8 +91,5 @@ struct sh_machine_vector mv_7343se __initmv = {
.mv_init_irq = init_7343se_IRQ,
.mv_irq_demux = shmse_irq_demux,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_7343se,
#endif
};
ALIAS_MV(7343se)
......@@ -3,4 +3,3 @@
#
obj-y := setup.o io.o irq.o
obj-$(CONFIG_HEARTBEAT) += led.o
......@@ -2,56 +2,96 @@
* linux/arch/sh/boards/se/770x/irq.c
*
* Copyright (C) 2000 Kazumoto Kojima
* Copyright (C) 2006 Nobuhiro Iwamatsu
*
* Hitachi SolutionEngine Support.
*
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/se.h>
/*
* If the problem of make_ipr_irq is solved,
* this code will become unnecessary. :-)
*/
static void se770x_disable_ipr_irq(unsigned int irq)
{
struct ipr_data *p = get_irq_chip_data(irq);
ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
}
static void se770x_enable_ipr_irq(unsigned int irq)
{
struct ipr_data *p = get_irq_chip_data(irq);
ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
}
static struct irq_chip se770x_irq_chip = {
.name = "MS770xSE-FPGA",
.mask = se770x_disable_ipr_irq,
.unmask = se770x_enable_ipr_irq,
.mask_ack = se770x_disable_ipr_irq,
};
void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs)
{
int i;
for (i = 0; i < nr_irqs; i++) {
unsigned int irq = table[i].irq;
disable_irq_nosync(irq);
set_irq_chip_and_handler_name(irq, &se770x_irq_chip,
handle_level_irq, "level");
set_irq_chip_data(irq, &table[i]);
se770x_enable_ipr_irq(irq);
}
}
static struct ipr_data se770x_ipr_map[] = {
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* This is default value */
{ 0xf-0x2, BCR_ILCRA, 2, 0x2 },
{ 0xf-0xa, BCR_ILCRA, 1, 0xa },
{ 0xf-0x5, BCR_ILCRB, 0, 0x5 },
{ 0xf-0x8, BCR_ILCRC, 1, 0x8 },
{ 0xf-0xc, BCR_ILCRC, 0, 0xc },
{ 0xf-0xe, BCR_ILCRD, 3, 0xe },
{ 0xf-0x3, BCR_ILCRD, 1, 0x3 }, /* LAN */
{ 0xf-0xd, BCR_ILCRE, 2, 0xd },
{ 0xf-0x9, BCR_ILCRE, 1, 0x9 },
{ 0xf-0x1, BCR_ILCRE, 0, 0x1 },
{ 0xf-0xf, BCR_ILCRF, 3, 0xf },
{ 0xf-0xb, BCR_ILCRF, 1, 0xb },
{ 0xf-0x7, BCR_ILCRG, 3, 0x7 },
{ 0xf-0x6, BCR_ILCRG, 2, 0x6 },
{ 0xf-0x4, BCR_ILCRG, 1, 0x4 },
{ 0xf-0x2, 0, 8, 0x2 , BCR_ILCRA},
{ 0xf-0xa, 0, 4, 0xa , BCR_ILCRA},
{ 0xf-0x5, 0, 0, 0x5 , BCR_ILCRB},
{ 0xf-0x8, 0, 4, 0x8 , BCR_ILCRC},
{ 0xf-0xc, 0, 0, 0xc , BCR_ILCRC},
{ 0xf-0xe, 0, 12, 0xe , BCR_ILCRD},
{ 0xf-0x3, 0, 4, 0x3 , BCR_ILCRD}, /* LAN */
{ 0xf-0xd, 0, 8, 0xd , BCR_ILCRE},
{ 0xf-0x9, 0, 4, 0x9 , BCR_ILCRE},
{ 0xf-0x1, 0, 0, 0x1 , BCR_ILCRE},
{ 0xf-0xf, 0, 12, 0xf , BCR_ILCRF},
{ 0xf-0xb, 0, 4, 0xb , BCR_ILCRF},
{ 0xf-0x7, 0, 12, 0x7 , BCR_ILCRG},
{ 0xf-0x6, 0, 8, 0x6 , BCR_ILCRG},
{ 0xf-0x4, 0, 4, 0x4 , BCR_ILCRG},
#else
{ 14, BCR_ILCRA, 2, 0x0f-14 },
{ 12, BCR_ILCRA, 1, 0x0f-12 },
{ 8, BCR_ILCRB, 1, 0x0f- 8 },
{ 6, BCR_ILCRC, 3, 0x0f- 6 },
{ 5, BCR_ILCRC, 2, 0x0f- 5 },
{ 4, BCR_ILCRC, 1, 0x0f- 4 },
{ 3, BCR_ILCRC, 0, 0x0f- 3 },
{ 1, BCR_ILCRD, 3, 0x0f- 1 },
{ 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */
{ 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */
{ 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */
{ 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */
{ 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
{ 14, 0, 8, 0x0f-14 ,BCR_ILCRA},
{ 12, 0, 4, 0x0f-12 ,BCR_ILCRA},
{ 8, 0, 4, 0x0f- 8 ,BCR_ILCRB},
{ 6, 0, 12, 0x0f- 6 ,BCR_ILCRC},
{ 5, 0, 8, 0x0f- 5 ,BCR_ILCRC},
{ 4, 0, 4, 0x0f- 4 ,BCR_ILCRC},
{ 3, 0, 0, 0x0f- 3 ,BCR_ILCRC},
{ 1, 0, 12, 0x0f- 1 ,BCR_ILCRD},
/* ST NIC */
{ 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */
/* MRSHPC IRQs setting */
{ 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */
{ 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */
{ 9, 0, 4, 0x0f- 9 ,BCR_ILCRE}, /* PCIRQ1 */
{ 7, 0, 0, 0x0f- 7 ,BCR_ILCRE}, /* PCIRQ0 */
/* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
/* NOTE: #2 and #13 are not used on PC */
{ 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
{ 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */
{ 13, 0, 4, 0x0f-13 ,BCR_ILCRG}, /* SLOTIRQ2 */
{ 2, 0, 0, 0x0f- 2 ,BCR_ILCRG}, /* SLOTIRQ1 */
#endif
};
......@@ -81,5 +121,5 @@ void __init init_se_IRQ(void)
ctrl_outw(0, BCR_ILCRF);
ctrl_outw(0, BCR_ILCRG);
#endif
make_ipr_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
}
/*
* linux/arch/sh/boards/se/770x/led.c
*
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Solution Engine specific LED code.
*/
#include <linux/sched.h>
#include <asm/se.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short* p = (volatile unsigned short*)PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if (up) {
if (bit == 7) {
bit--;
up=0;
} else {
bit ++;
}
} else {
if (bit == 0) {
bit++;
up=1;
} else {
bit--;
}
}
*p = 1<<(bit+8);
}
/* $Id: setup.c,v 1.1.2.4 2002/03/02 21:57:07 lethal Exp $
*
/*
* linux/arch/sh/boards/se/770x/setup.c
*
* Copyright (C) 2000 Kazumoto Kojima
......@@ -8,12 +7,12 @@
*
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/se.h>
#include <asm/io.h>
#include <asm/smc37c93x.h>
void heartbeat_se(void);
void init_se_IRQ(void);
/*
......@@ -36,11 +35,6 @@ static void __init smsc_setup(char **cmdline_p)
smsc_config(ACTIVATE_INDEX, 0x01);
smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
/* IDE1 */
smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
smsc_config(ACTIVATE_INDEX, 0x01);
smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
/* AUXIO (GPIO): to use IDE1 */
smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
......@@ -69,6 +63,36 @@ static void __init smsc_setup(char **cmdline_p)
outb_p(CONFIG_EXIT, CONFIG_PORT);
}
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
.end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.dev = {
.platform_data = heartbeat_bit_pos,
},
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *se_devices[] __initdata = {
&heartbeat_device,
};
static int __init se_devices_setup(void)
{
return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
}
__initcall(se_devices_setup);
/*
* The Machine Vector
*/
......@@ -107,8 +131,5 @@ struct sh_machine_vector mv_se __initmv = {
.mv_outsl = se_outsl,
.mv_init_irq = init_se_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_se,
#endif
};
ALIAS_MV(se)
......@@ -5,4 +5,3 @@
obj-y := setup.o io.o irq.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_HEARTBEAT) += led.o
/*
* linux/arch/sh/boards/se/7751/led.c
*
* Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* This file contains Solution Engine specific LED code.
*/
#include <linux/sched.h>
#include <asm/se7751.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_7751se(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned short* p = (volatile unsigned short*)PA_LED;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if (up) {
if (bit == 7) {
bit--;
up=0;
} else {
bit ++;
}
} else {
if (bit == 0) {
bit++;
up=1;
} else {
bit--;
}
}
*p = 1<<(bit+8);
}
......@@ -9,11 +9,11 @@
* Ian da Silva and Jeremy Siegel, 2001.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/se7751.h>
#include <asm/io.h>
void heartbeat_7751se(void);
void init_7751se_IRQ(void);
#ifdef CONFIG_SH_KGDB
......@@ -161,11 +161,40 @@ static int kgdb_uart_setup(void)
}
#endif /* CONFIG_SH_KGDB */
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
.end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.dev = {
.platform_data = heartbeat_bit_pos,
},
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *se7751_devices[] __initdata = {
&smc91x_device,
&heartbeat_device,
};
static int __init se7751_devices_setup(void)
{
return platform_add_devices(se7751_devices, ARRAY_SIZE(se7751_devices));
}
__initcall(se7751_devices_setup);
/*
* The Machine Vector
*/
struct sh_machine_vector mv_7751se __initmv = {
.mv_name = "7751 SolutionEngine",
.mv_setup = sh7751se_setup,
......@@ -189,8 +218,5 @@ struct sh_machine_vector mv_7751se __initmv = {
.mv_outsl = sh7751se_outsl,
.mv_init_irq = init_7751se_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_7751se,
#endif
};
ALIAS_MV(7751se)
......@@ -3,4 +3,3 @@
#
obj-y := setup.o rtc.o
obj-$(CONFIG_HEARTBEAT) += led.o
/*
* linux/arch/sh/boards/sh03/led.c
*
* Copyright (C) 2004 Saito.K Interface Corporation.
*
* This file contains Interface CTP/PCI-SH03 specific LED code.
*/
#include <linux/sched.h>
/* Cycle the LED's in the clasic Knightrider/Sun pattern */
void heartbeat_sh03(void)
{
static unsigned int cnt = 0, period = 0;
volatile unsigned char* p = (volatile unsigned char*)0xa0800000;
static unsigned bit = 0, up = 1;
cnt += 1;
if (cnt < period) {
return;
}
cnt = 0;
/* Go through the points (roughly!):
* f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
*/
period = 110 - ( (300<<FSHIFT)/
((avenrun[0]/5) + (3<<FSHIFT)) );
if (up) {
if (bit == 7) {
bit--;
up=0;
} else {
bit ++;
}
} else {
if (bit == 0) {
bit++;
up=1;
} else {
bit--;
}
}
*p = 1<<bit;
}
......@@ -8,6 +8,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/rtc.h>
#include <asm/sh03/io.h>
......@@ -48,15 +49,36 @@ static void __init sh03_setup(char **cmdline_p)
board_time_init = sh03_time_init;
}
static struct resource heartbeat_resources[] = {
[0] = {
.start = 0xa0800000,
.end = 0xa0800000 + 8 - 1,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *sh03_devices[] __initdata = {
&heartbeat_device,
};
static int __init sh03_devices_setup(void)
{
return platform_add_devices(sh03_devices, ARRAY_SIZE(sh03_devices));
}
__initcall(sh03_devices_setup);
struct sh_machine_vector mv_sh03 __initmv = {
.mv_name = "Interface (CTP/PCI-SH03)",
.mv_setup = sh03_setup,
.mv_nr_irqs = 48,
.mv_ioport_map = sh03_ioport_map,
.mv_init_irq = init_sh03_IRQ,
#ifdef CONFIG_HEARTBEAT
.mv_heartbeat = heartbeat_sh03,
#endif
};
ALIAS_MV(sh03)
......@@ -12,12 +12,22 @@
#include <asm/irq.h>
#include <asm/io.h>
#define PFC_PHCR 0xa400010e
#define PFC_PHCR 0xa400010eUL
#define INTC_ICR1 0xa4000010UL
#define INTC_IPRC 0xa4000016UL
static struct ipr_data shmin_ipr_map[] = {
{ .irq=32, .addr=INTC_IPRC, .shift= 0, .priority=0 },
{ .irq=33, .addr=INTC_IPRC, .shift= 4, .priority=0 },
{ .irq=34, .addr=INTC_IPRC, .shift= 8, .priority=8 },
{ .irq=35, .addr=INTC_IPRC, .shift=12, .priority=0 },
};
static void __init init_shmin_irq(void)
{
ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active.
make_ipr_irq(shmin_ipr_map, ARRAY_SIZE(shmin_ipr_map));
}
static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size)
......
......@@ -28,21 +28,21 @@ static void disable_voyagergx_irq(unsigned int irq)
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
val = inl(VOYAGER_INT_MASK);
val &= ~mask;
outl(val, VOYAGER_INT_MASK);
pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
val = readl((void __iomem *)VOYAGER_INT_MASK);
val &= ~mask;
writel(val, (void __iomem *)VOYAGER_INT_MASK);
}
static void enable_voyagergx_irq(unsigned int irq)
{
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
val = inl(VOYAGER_INT_MASK);
val |= mask;
outl(val, VOYAGER_INT_MASK);
pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
val = readl((void __iomem *)VOYAGER_INT_MASK);
val |= mask;
writel(val, (void __iomem *)VOYAGER_INT_MASK);
}
static void mask_and_ack_voyagergx(unsigned int irq)
......@@ -68,20 +68,20 @@ static void shutdown_voyagergx_irq(unsigned int irq)
}
static struct hw_interrupt_type voyagergx_irq_type = {
.typename = "VOYAGERGX-IRQ",
.startup = startup_voyagergx_irq,
.shutdown = shutdown_voyagergx_irq,
.enable = enable_voyagergx_irq,
.disable = disable_voyagergx_irq,
.ack = mask_and_ack_voyagergx,
.end = end_voyagergx_irq,
.typename = "VOYAGERGX-IRQ",
.startup = startup_voyagergx_irq,
.shutdown = shutdown_voyagergx_irq,
.enable = enable_voyagergx_irq,
.disable = disable_voyagergx_irq,
.ack = mask_and_ack_voyagergx,
.end = end_voyagergx_irq,
};
static irqreturn_t voyagergx_interrupt(int irq, void *dev_id)
{
printk(KERN_INFO
"VoyagerGX: spurious interrupt, status: 0x%x\n",
inl(INT_STATUS));
(unsigned int)readl((void __iomem *)INT_STATUS));
return IRQ_HANDLED;
}
......@@ -93,13 +93,13 @@ static struct {
void voyagergx_register_irq_demux(int irq,
int (*demux)(int irq, void *dev), void *dev)
{
voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux;
voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev;
voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux;
voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev;
}
void voyagergx_unregister_irq_demux(int irq)
{
voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0;
voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0;
}
int voyagergx_irq_demux(int irq)
......@@ -107,31 +107,25 @@ int voyagergx_irq_demux(int irq)
if (irq == IRQ_VOYAGER ) {
unsigned long i = 0, bit __attribute__ ((unused));
unsigned long val = inl(INT_STATUS);
#if 1
if ( val & ( 1 << 1 )){
unsigned long val = readl((void __iomem *)INT_STATUS);
if (val & (1 << 1))
i = 1;
} else if ( val & ( 1 << 2 )){
else if (val & (1 << 2))
i = 2;
} else if ( val & ( 1 << 6 )){
else if (val & (1 << 6))
i = 6;
} else if( val & ( 1 << 10 )){
else if (val & (1 << 10))
i = 10;
} else if( val & ( 1 << 11 )){
else if (val & (1 << 11))
i = 11;
} else if( val & ( 1 << 12 )){
else if (val & (1 << 12))
i = 12;
} else if( val & ( 1 << 17 )){
else if (val & (1 << 17))
i = 17;
} else {
else
printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
}
pr_debug("voyagergx_irq_demux %ld\n", i);
#else
for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++)
if (val & bit)
break;
#endif
pr_debug("voyagergx_irq_demux %d \n", i);
if (i < VOYAGER_IRQ_NUM) {
irq = VOYAGER_IRQ_BASE + i;
if (voyagergx_demux[i].func != 0)
......
......@@ -19,7 +19,7 @@ static int __init setup_voyagergx(void)
{
unsigned long val;
val = inl(DRAM_CTRL);
val = readl((void __iomem *)DRAM_CTRL);
val |= (DRAM_CTRL_CPU_COLUMN_SIZE_256 |
DRAM_CTRL_CPU_ACTIVE_PRECHARGE |
DRAM_CTRL_CPU_RESET |
......@@ -29,7 +29,7 @@ static int __init setup_voyagergx(void)
DRAM_CTRL_ACTIVE_PRECHARGE |
DRAM_CTRL_RESET |
DRAM_CTRL_REMAIN_ACTIVE);
outl(val, DRAM_CTRL);
writel(val, (void __iomem *)DRAM_CTRL);
return 0;
}
......
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.18
# Tue Oct 3 11:38:36 2006
# Linux kernel version: 2.6.20
# Thu Feb 15 17:17:29 2007
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME is not set
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
......@@ -33,8 +39,8 @@ CONFIG_SYSVIPC=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
......@@ -97,10 +103,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
# CONFIG_SH_HP6XX is not set
# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
# CONFIG_SH_BIGSUR is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
......@@ -113,6 +117,9 @@ CONFIG_SH_RTS7751R2D=y
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
# CONFIG_SH_SHMIN is not set
# CONFIG_SH_7206_SOLUTION_ENGINE is not set
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
# CONFIG_SH_ASDAP310 is not set
# CONFIG_SH_UNKNOWN is not set
#
......@@ -124,6 +131,12 @@ CONFIG_CPU_SH4=y
# SH-2 Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
# CONFIG_CPU_SUBTYPE_SH7619 is not set
#
# SH-2A Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7206 is not set
#
# SH-3 Processor Support
......@@ -159,12 +172,14 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
#
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
#
# SH4AL-DSP Processor Support
#
# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
#
# Memory management options
......@@ -174,6 +189,9 @@ CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x04000000
CONFIG_VSYSCALL=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
......@@ -183,6 +201,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
#
# Cache configuration
......@@ -195,11 +214,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SH_FPU=y
# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_IPR_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
CONFIG_CPU_HAS_PTEA=y
#
# Timer support
......@@ -210,6 +232,8 @@ CONFIG_SH_TMU=y
# RTS7751R2D options
#
CONFIG_RTS7751R2D_REV11=y
CONFIG_SH_TIMER_IRQ=16
# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=60000000
#
......@@ -231,11 +255,17 @@ CONFIG_VOYAGERGX=y
# CONFIG_HD6446X_SERIES is not set
CONFIG_HEARTBEAT=y
#
# Additional SuperH Device Drivers
#
# CONFIG_PUSH_SWITCH is not set
#
# Kernel features
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
......@@ -251,7 +281,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00010000
CONFIG_BOOT_LINK_OFFSET=0x00800000
# CONFIG_UBC_WAKEUP is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="mem=64M console=ttySC0,115200 root=/dev/hda1"
CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
#
# Bus options
......@@ -260,7 +290,6 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCI_MULTITHREAD_PROBE is not set
#
# PCCARD (PCMCIA/CardBus) support
......@@ -302,6 +331,7 @@ CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
......@@ -319,11 +349,13 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
......@@ -380,7 +412,7 @@ CONFIG_WIRELESS_EXT=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
CONFIG_FW_LOADER=m
# CONFIG_SYS_HYPERVISOR is not set
#
......@@ -422,44 +454,145 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
CONFIG_IDE_MAX_HWIFS=4
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
# Misc devices
#
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_IDE_TASK_IOCTL is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
#
# IDE chipset support/bugfixes
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_IDEPCI is not set
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_IDE is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
CONFIG_SCSI=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
#
# CONFIG_ATA is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIL24 is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
CONFIG_PATA_PLATFORM=y
#
# Multi-device support (RAID and LVM)
......@@ -470,6 +603,9 @@ CONFIG_IDE_GENERIC=y
# Fusion MPT device support
#
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
......@@ -540,6 +676,7 @@ CONFIG_8139TOO=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
#
# Ethernet (1000 Mbit)
......@@ -559,14 +696,17 @@ CONFIG_8139TOO=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
......@@ -611,6 +751,7 @@ CONFIG_NET_WIRELESS=y
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
......@@ -646,14 +787,23 @@ CONFIG_NET_WIRELESS=y
#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_CONSOLE is not set
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_SH_SCI is not set
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=1
CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
......@@ -671,10 +821,6 @@ CONFIG_HW_RANDOM=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
......@@ -682,7 +828,6 @@ CONFIG_HW_RANDOM=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
#
# I2C support
......@@ -698,6 +843,7 @@ CONFIG_HW_RANDOM=y
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
......@@ -706,18 +852,14 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
......@@ -759,7 +901,6 @@ CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_MPU401_UART=m
CONFIG_SND_OPL3_LIB=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_AC97_BUS=m
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
......@@ -782,6 +923,18 @@ CONFIG_SND_AC97_BUS=m
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
# CONFIG_SND_DARLA24 is not set
# CONFIG_SND_GINA24 is not set
# CONFIG_SND_LAYLA24 is not set
# CONFIG_SND_MONA is not set
# CONFIG_SND_MIA is not set
# CONFIG_SND_ECHO3G is not set
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
......@@ -801,6 +954,7 @@ CONFIG_SND_AC97_BUS=m
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
......@@ -812,18 +966,23 @@ CONFIG_SND_AC97_BUS=m
CONFIG_SND_YMFPCI=m
# CONFIG_SND_AC97_POWER_SAVE is not set
#
# SoC audio support
#
# CONFIG_SND_SOC is not set
#
# Open Sound System
#
CONFIG_SOUND_PRIME=m
# CONFIG_OSS_OBSOLETE_DRIVER is not set
# CONFIG_OBSOLETE_OSS is not set
# CONFIG_SOUND_BT878 is not set
# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
# CONFIG_SOUND_VIA82CXXX is not set
CONFIG_AC97_BUS=m
#
# USB support
......@@ -872,7 +1031,29 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# Real Time Clock
#
# CONFIG_RTC_CLASS is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
#
# RTC drivers
#
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_M48T86 is not set
CONFIG_RTC_DRV_SH=y
# CONFIG_RTC_DRV_TEST is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# DMA Engine support
......@@ -887,6 +1068,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# DMA Devices
#
#
# Auxiliary Display support
#
#
# Virtualization
#
#
# File systems
#
......@@ -894,10 +1083,12 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_ROMFS_FS is not set
......@@ -932,7 +1123,8 @@ CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
......@@ -1017,6 +1209,11 @@ CONFIG_NLS_CODEPAGE_932=y
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# Distributed Lock Manager
#
# CONFIG_DLM is not set
#
# Profiling support
#
......@@ -1026,16 +1223,20 @@ CONFIG_OPROFILE=y
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
CONFIG_EARLY_SCIF_CONSOLE=y
CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
CONFIG_EARLY_PRINTK=y
# CONFIG_KGDB is not set
#
......@@ -1052,8 +1253,11 @@ CONFIG_LOG_BUF_SHIFT=14
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.18
# Tue Oct 3 11:49:01 2006
# Linux kernel version: 2.6.20-rc2
# Thu Dec 28 23:15:49 2006
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
......@@ -10,6 +10,11 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME is not set
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
......@@ -35,6 +40,7 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
......@@ -116,6 +122,8 @@ CONFIG_SH_SOLUTION_ENGINE=y
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
# CONFIG_SH_SHMIN is not set
# CONFIG_SH_7206_SOLUTION_ENGINE is not set
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
# CONFIG_SH_UNKNOWN is not set
#
......@@ -127,6 +135,12 @@ CONFIG_CPU_SH4=y
# SH-2 Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
# CONFIG_CPU_SUBTYPE_SH7619 is not set
#
# SH-2A Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7206 is not set
#
# SH-3 Processor Support
......@@ -162,12 +176,14 @@ CONFIG_CPU_SUBTYPE_SH7750=y
#
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
#
# SH4AL-DSP Processor Support
#
# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
#
# Memory management options
......@@ -177,6 +193,9 @@ CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x02000000
CONFIG_VSYSCALL=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
......@@ -202,17 +221,22 @@ CONFIG_CF_BASE_ADDR=0xb8000000
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SH_FPU=y
# CONFIG_SH_DSP is not set
# CONFIG_SH_STORE_QUEUES is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_IPR_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
CONFIG_CPU_HAS_PTEA=y
#
# Timer support
#
CONFIG_SH_TMU=y
CONFIG_SH_PCLK_FREQ=50000000
CONFIG_SH_TIMER_IRQ=16
# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
#
# CPU Frequency scaling
......@@ -230,11 +254,17 @@ CONFIG_SH_PCLK_FREQ=50000000
# CONFIG_HD6446X_SERIES is not set
CONFIG_HEARTBEAT=y
#
# Additional SuperH Device Drivers
#
# CONFIG_PUSH_SWITCH is not set
#
# Kernel features
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
......@@ -249,8 +279,7 @@ CONFIG_PREEMPT_NONE=y
CONFIG_ZERO_PAGE_OFFSET=0x00001000
CONFIG_BOOT_LINK_OFFSET=0x00800000
# CONFIG_UBC_WAKEUP is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttySC1,38400 root=/dev/nfs ip=bootp"
# CONFIG_CMDLINE_BOOL is not set
#
# Bus options
......@@ -313,11 +342,13 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
......@@ -479,17 +510,80 @@ CONFIG_MTD_ROM=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
# Misc devices
#
# CONFIG_TIFM_CORE is not set
#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
CONFIG_IDE=y
CONFIG_IDE_MAX_HWIFS=4
CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
CONFIG_SCSI=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
#
# SCSI low-level drivers
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_DEBUG is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
......@@ -633,17 +727,12 @@ CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
#
# I2C support
......@@ -659,6 +748,7 @@ CONFIG_HW_RANDOM=y
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Hardware Monitoring support
......@@ -667,18 +757,14 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
......@@ -757,15 +843,21 @@ CONFIG_FIRMWARE_EDID=y
# DMA Devices
#
#
# Virtualization
#
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
......@@ -814,7 +906,6 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
......@@ -874,6 +965,11 @@ CONFIG_PARTITION_ADVANCED=y
#
# CONFIG_NLS is not set
#
# Distributed Lock Manager
#
# CONFIG_DLM is not set
#
# Profiling support
#
......@@ -882,14 +978,16 @@ CONFIG_PARTITION_ADVANCED=y
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_KGDB is not set
......@@ -908,6 +1006,7 @@ CONFIG_LOG_BUF_SHIFT=14
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
......@@ -915,3 +1014,4 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
CONFIG_IOMAP_COPY=y
......@@ -6,3 +6,4 @@ obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_SH_DMA) += dma/
obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_PUSH_SWITCH) += push-switch.o
obj-$(CONFIG_HEARTBEAT) += heartbeat.o
......@@ -19,34 +19,26 @@
#include <asm/io.h>
#include "dma-sh.h"
#ifdef CONFIG_CPU_SH4
static struct ipr_data dmae_ipr_map[] = {
{ DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
};
static int dmte_irq_map[] = {
DMTE0_IRQ,
DMTE1_IRQ,
DMTE2_IRQ,
DMTE3_IRQ,
#if defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
defined(CONFIG_CPU_SUBTYPE_SH7760) || \
defined(CONFIG_CPU_SUBTYPE_SH7780)
DMTE4_IRQ,
DMTE5_IRQ,
DMTE6_IRQ,
DMTE7_IRQ,
#endif
static struct ipr_data dmte_ipr_map[] = {
/*
* Normally we could just do DMTE0_IRQ + chan outright, though in the
* case of the 7751R, the DMTE IRQs for channels > 4 start right above
* the SCIF
*/
{ DMTE0_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE0_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE0_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE0_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE4_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE4_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE4_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
{ DMTE4_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
};
static inline unsigned int get_dmte_irq(unsigned int chan)
{
unsigned int irq = 0;
if (chan < ARRAY_SIZE(dmte_ipr_map))
irq = dmte_ipr_map[chan].irq;
if (chan < ARRAY_SIZE(dmte_irq_map))
irq = dmte_irq_map[chan];
return irq;
}
......@@ -103,7 +95,7 @@ static void sh_dmac_free_dma(struct dma_channel *chan)
free_irq(get_dmte_irq(chan->chan), chan);
}
static void
static int
sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
{
if (!chcr)
......@@ -119,6 +111,7 @@ sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
ctrl_outl(chcr, CHCR[chan->chan]);
chan->flags |= DMA_CONFIGURED;
return 0;
}
static void sh_dmac_enable_dma(struct dma_channel *chan)
......@@ -262,17 +255,11 @@ static int __init sh_dmac_init(void)
int i;
#ifdef CONFIG_CPU_SH4
make_ipr_irq(dmae_ipr_map, ARRAY_SIZE(dmae_ipr_map));
i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
if (unlikely(i < 0))
return i;
#endif
i = info->nr_channels;
if (i > ARRAY_SIZE(dmte_ipr_map))
i = ARRAY_SIZE(dmte_ipr_map);
make_ipr_irq(dmte_ipr_map, i);
/*
* Initialize DMAOR, and clean up any error flags that may have
* been set.
......
/*
* Generic heartbeat driver for regular LED banks
*
* Copyright (C) 2007 Paul Mundt
*
* Most SH reference boards include a number of individual LEDs that can
* be independently controlled (either via a pre-defined hardware
* function or via the LED class, if desired -- the hardware tends to
* encapsulate some of the same "triggers" that the LED class supports,
* so there's not too much value in it).
*
* Additionally, most of these boards also have a LED bank that we've
* traditionally used for strobing the load average. This use case is
* handled by this driver, rather than giving each LED bit position its
* own struct device.
*
* 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.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/io.h>
#define DRV_NAME "heartbeat"
#define DRV_VERSION "0.1.0"
struct heartbeat_data {
void __iomem *base;
unsigned char bit_pos[8];
struct timer_list timer;
};
static void heartbeat_timer(unsigned long data)
{
struct heartbeat_data *hd = (struct heartbeat_data *)data;
static unsigned bit = 0, up = 1;
ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base);
if (up)
if (bit == (ARRAY_SIZE(hd->bit_pos) - 1)) {
bit--;
up = 0;
} else
bit++;
else if (bit == 0)
up = 1;
else
bit--;
mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) /
((avenrun[0] / 5) + (3 << FSHIFT)))));
}
static int heartbeat_drv_probe(struct platform_device *pdev)
{
struct resource *res;
struct heartbeat_data *hd;
if (unlikely(pdev->num_resources != 1)) {
dev_err(&pdev->dev, "invalid number of resources\n");
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(res == NULL)) {
dev_err(&pdev->dev, "invalid resource\n");
return -EINVAL;
}
hd = kmalloc(sizeof(struct heartbeat_data), GFP_KERNEL);
if (unlikely(!hd))
return -ENOMEM;
if (pdev->dev.platform_data) {
memcpy(hd->bit_pos, pdev->dev.platform_data,
ARRAY_SIZE(hd->bit_pos));
} else {
int i;
for (i = 0; i < ARRAY_SIZE(hd->bit_pos); i++)
hd->bit_pos[i] = i;
}
hd->base = (void __iomem *)res->start;
setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd);
platform_set_drvdata(pdev, hd);
return mod_timer(&hd->timer, jiffies + 1);
}
static int heartbeat_drv_remove(struct platform_device *pdev)
{
struct heartbeat_data *hd = platform_get_drvdata(pdev);
del_timer_sync(&hd->timer);
platform_set_drvdata(pdev, NULL);
kfree(hd);
return 0;
}
static struct platform_driver heartbeat_driver = {
.probe = heartbeat_drv_probe,
.remove = heartbeat_drv_remove,
.driver = {
.name = DRV_NAME,
},
};
static int __init heartbeat_init(void)
{
printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION);
return platform_driver_register(&heartbeat_driver);
}
static void __exit heartbeat_exit(void)
{
platform_driver_unregister(&heartbeat_driver);
}
module_init(heartbeat_init);
module_exit(heartbeat_exit);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("Paul Mundt");
MODULE_LICENSE("GPLv2");
......@@ -12,7 +12,6 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
dma-dreamcast.o
obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o
......
/*
* linux/arch/sh/drivers/pci/ops-bigsur.c
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
*
* Ported to new API by Paul Mundt <lethal@linux-sh.org>.
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* PCI initialization for the Hitachi Big Sur Evaluation Board
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
#include "pci-sh4.h"
#include <asm/bigsur/bigsur.h>
#define BIGSUR_PCI_IO 0x4000
#define BIGSUR_PCI_MEM 0xfd000000
static struct resource sh7751_io_resource = {
.name = "SH7751 IO",
.start = BIGSUR_PCI_IO,
.end = BIGSUR_PCI_IO + (64*1024) - 1,
.flags = IORESOURCE_IO,
};
static struct resource sh7751_mem_resource = {
.name = "SH7751 mem",
.start = BIGSUR_PCI_MEM,
.end = BIGSUR_PCI_MEM + (64*1024*1024) - 1,
.flags = IORESOURCE_MEM,
};
extern struct pci_ops sh7751_pci_ops;
struct pci_channel board_pci_channels[] = {
{ &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
{ 0, }
};
static struct sh4_pci_address_map sh7751_pci_map = {
.window0 = {
.base = SH7751_CS3_BASE_ADDR,
.size = BIGSUR_LSR0_SIZE,
},
.window1 = {
.base = SH7751_CS3_BASE_ADDR,
.size = BIGSUR_LSR1_SIZE,
},
};
/*
* Initialize the Big Sur PCI interface
* Setup hardware to be Central Funtion
* Copy the BSR regs to the PCI interface
* Setup PCI windows into local RAM
*/
int __init pcibios_init_platform(void)
{
return sh7751_pcic_init(&sh7751_pci_map);
}
int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
/*
* The Big Sur can be used in a CPCI chassis, but the SH7751 PCI
* interface is on the wrong end of the board so that it can also
* support a V320 CPI interface chip... Therefor the IRQ mapping is
* somewhat use dependent... I'l assume a linear map for now, i.e.
* INTA=slot0,pin0... INTD=slot3,pin0...
*/
int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE;
PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n",
slot, pin-1+'A', irq);
return irq;
}
......@@ -157,15 +157,6 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
PCIBIOS_MIN_IO, (64 << 10),
SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO);
/*
* XXX: For now, leave this board-specific. In the event we have other
* boards that need to do similar work, this can be wrapped.
*/
#ifdef CONFIG_SH_BIGSUR
bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10),
SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO, 0);
#endif
/* Make sure the MSB's of IO window are set to access PCI space
* correctly */
word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK;
......
......@@ -6,7 +6,8 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o signal.o traps.o irq.o \
ptrace.o setup.o time.o sys_sh.o semaphore.o \
io.o io_generic.o sh_ksyms.o syscalls.o
io.o io_generic.o sh_ksyms.o syscalls.o \
debugtraps.o
obj-y += cpu/ timers/
obj-$(CONFIG_VSYSCALL) += vsyscall/
......
......@@ -3,7 +3,7 @@
*
* CPU init code
*
* Copyright (C) 2002, 2003 Paul Mundt
* Copyright (C) 2002 - 2006 Paul Mundt
* Copyright (C) 2003 Richard Curnow
*
* This file is subject to the terms and conditions of the GNU General Public
......@@ -12,6 +12,8 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/mmu_context.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/page.h>
......@@ -46,7 +48,7 @@ static void __init cache_init(void)
{
unsigned long ccr, flags;
if (cpu_data->type == CPU_SH_NONE)
if (current_cpu_data.type == CPU_SH_NONE)
panic("Unknown CPU");
jump_to_P2();
......@@ -66,7 +68,7 @@ static void __init cache_init(void)
if (ccr & CCR_CACHE_ENABLE) {
unsigned long ways, waysize, addrstart;
waysize = cpu_data->dcache.sets;
waysize = current_cpu_data.dcache.sets;
#ifdef CCR_CACHE_ORA
/*
......@@ -77,7 +79,7 @@ static void __init cache_init(void)
waysize >>= 1;
#endif
waysize <<= cpu_data->dcache.entry_shift;
waysize <<= current_cpu_data.dcache.entry_shift;
#ifdef CCR_CACHE_EMODE
/* If EMODE is not set, we only have 1 way to flush. */
......@@ -85,7 +87,7 @@ static void __init cache_init(void)
ways = 1;
else
#endif
ways = cpu_data->dcache.ways;
ways = current_cpu_data.dcache.ways;
addrstart = CACHE_OC_ADDRESS_ARRAY;
do {
......@@ -93,10 +95,10 @@ static void __init cache_init(void)
for (addr = addrstart;
addr < addrstart + waysize;
addr += cpu_data->dcache.linesz)
addr += current_cpu_data.dcache.linesz)
ctrl_outl(0, addr);
addrstart += cpu_data->dcache.way_incr;
addrstart += current_cpu_data.dcache.way_incr;
} while (--ways);
}
......@@ -108,7 +110,7 @@ static void __init cache_init(void)
#ifdef CCR_CACHE_EMODE
/* Force EMODE if possible */
if (cpu_data->dcache.ways > 1)
if (current_cpu_data.dcache.ways > 1)
flags |= CCR_CACHE_EMODE;
else
flags &= ~CCR_CACHE_EMODE;
......@@ -125,10 +127,10 @@ static void __init cache_init(void)
#ifdef CONFIG_SH_OCRAM
/* Turn on OCRAM -- halve the OC */
flags |= CCR_CACHE_ORA;
cpu_data->dcache.sets >>= 1;
current_cpu_data.dcache.sets >>= 1;
cpu_data->dcache.way_size = cpu_data->dcache.sets *
cpu_data->dcache.linesz;
current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
current_cpu_data.dcache.linesz;
#endif
ctrl_outl(flags, CCR);
......@@ -170,7 +172,7 @@ static void __init dsp_init(void)
/* If the DSP bit is still set, this CPU has a DSP */
if (sr & SR_DSP)
cpu_data->flags |= CPU_HAS_DSP;
current_cpu_data.flags |= CPU_HAS_DSP;
/* Now that we've determined the DSP status, clear the DSP bit. */
release_dsp();
......@@ -202,22 +204,28 @@ asmlinkage void __init sh_cpu_init(void)
cache_init();
shm_align_mask = max_t(unsigned long,
cpu_data->dcache.way_size - 1,
current_cpu_data.dcache.way_size - 1,
PAGE_SIZE - 1);
/* Disable the FPU */
if (fpu_disabled) {
printk("FPU Disabled\n");
cpu_data->flags &= ~CPU_HAS_FPU;
current_cpu_data.flags &= ~CPU_HAS_FPU;
disable_fpu();
}
/* FPU initialization */
if ((cpu_data->flags & CPU_HAS_FPU)) {
if ((current_cpu_data.flags & CPU_HAS_FPU)) {
clear_thread_flag(TIF_USEDFPU);
clear_used_math();
}
/*
* Initialize the per-CPU ASID cache very early, since the
* TLB flushing routines depend on this being setup.
*/
current_cpu_data.asid_cache = NO_CONTEXT;
#ifdef CONFIG_SH_DSP
/* Probe for DSP */
dsp_init();
......@@ -225,7 +233,7 @@ asmlinkage void __init sh_cpu_init(void)
/* Disable the DSP */
if (dsp_disabled) {
printk("DSP Disabled\n");
cpu_data->flags &= ~CPU_HAS_DSP;
current_cpu_data.flags &= ~CPU_HAS_DSP;
release_dsp();
}
#endif
......@@ -240,4 +248,3 @@ asmlinkage void __init sh_cpu_init(void)
ubc_wakeup();
#endif
}
......@@ -43,16 +43,29 @@ static struct irq_chip ipr_irq_chip = {
.mask_ack = disable_ipr_irq,
};
unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak));
unsigned int map_ipridx_to_addr(int idx)
{
return 0;
}
void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
{
int i;
for (i = 0; i < nr_irqs; i++) {
unsigned int irq = table[i].irq;
table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
if (!irq)
irq = table[i].irq = i;
/* could the IPR index be mapped, if not we ignore this */
if (table[i].addr == 0)
continue;
if (!table[i].addr) {
table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
if (!table[i].addr)
continue;
}
disable_irq_nosync(irq);
set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
handle_level_irq, "level");
......
......@@ -178,12 +178,10 @@ interrupt_entry:
8: .long do_exception_error
trap_entry:
/* verbose BUG trapa entry check */
mov #0x3e,r8
cmp/ge r8,r9
bf/s 1f
add #-0x10,r9
add #0x10,r9
mov #0x30,r8
cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall
bt 1f
add #-0x10,r9 ! convert SH2 to SH3/4 ABI
1:
shll2 r9 ! TRA
mov #OFF_TRA,r8
......@@ -206,7 +204,7 @@ trap_entry:
#if defined(CONFIG_SH_STANDARD_BIOS)
/* Unwind the stack and jmp to the debug entry */
debug_kernel_fw:
ENTRY(sh_bios_handler)
mov r15,r0
add #(22-4)*4-4,r0
ldc.l @r0+,gbr
......
......@@ -18,27 +18,27 @@
int __init detect_cpu_and_cache_system(void)
{
#if defined(CONFIG_CPU_SUBTYPE_SH7604)
cpu_data->type = CPU_SH7604;
cpu_data->dcache.ways = 4;
cpu_data->dcache.way_incr = (1<<10);
cpu_data->dcache.sets = 64;
cpu_data->dcache.entry_shift = 4;
cpu_data->dcache.linesz = L1_CACHE_BYTES;
cpu_data->dcache.flags = 0;
current_cpu_data.type = CPU_SH7604;
current_cpu_data.dcache.ways = 4;
current_cpu_data.dcache.way_incr = (1<<10);
current_cpu_data.dcache.sets = 64;
current_cpu_data.dcache.entry_shift = 4;
current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
current_cpu_data.dcache.flags = 0;
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
cpu_data->type = CPU_SH7619;
cpu_data->dcache.ways = 4;
cpu_data->dcache.way_incr = (1<<12);
cpu_data->dcache.sets = 256;
cpu_data->dcache.entry_shift = 4;
cpu_data->dcache.linesz = L1_CACHE_BYTES;
cpu_data->dcache.flags = 0;
current_cpu_data.type = CPU_SH7619;
current_cpu_data.dcache.ways = 4;
current_cpu_data.dcache.way_incr = (1<<12);
current_cpu_data.dcache.sets = 256;
current_cpu_data.dcache.entry_shift = 4;
current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
current_cpu_data.dcache.flags = 0;
#endif
/*
* SH-2 doesn't have separate caches
*/
cpu_data->dcache.flags |= SH_CACHE_COMBINED;
cpu_data->icache = cpu_data->dcache;
current_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
current_cpu_data.icache = current_cpu_data.dcache;
return 0;
}
......
......@@ -52,42 +52,38 @@ static int __init sh7619_devices_setup(void)
}
__initcall(sh7619_devices_setup);
#define INTC_IPRC 0xf8080000UL
#define INTC_IPRD 0xf8080002UL
#define CMI0_IRQ 86
#define SCIF0_ERI_IRQ 88
#define SCIF0_RXI_IRQ 89
#define SCIF0_BRI_IRQ 90
#define SCIF0_TXI_IRQ 91
#define SCIF1_ERI_IRQ 92
#define SCIF1_RXI_IRQ 93
#define SCIF1_BRI_IRQ 94
#define SCIF1_TXI_IRQ 95
#define SCIF2_BRI_IRQ 96
#define SCIF2_ERI_IRQ 97
#define SCIF2_RXI_IRQ 98
#define SCIF2_TXI_IRQ 99
static struct ipr_data sh7619_ipr_map[] = {
{ CMI0_IRQ, INTC_IPRC, 1, 2 },
{ SCIF0_ERI_IRQ, INTC_IPRD, 3, 3 },
{ SCIF0_RXI_IRQ, INTC_IPRD, 3, 3 },
{ SCIF0_BRI_IRQ, INTC_IPRD, 3, 3 },
{ SCIF0_TXI_IRQ, INTC_IPRD, 3, 3 },
{ SCIF1_ERI_IRQ, INTC_IPRD, 2, 3 },
{ SCIF1_RXI_IRQ, INTC_IPRD, 2, 3 },
{ SCIF1_BRI_IRQ, INTC_IPRD, 2, 3 },
{ SCIF1_TXI_IRQ, INTC_IPRD, 2, 3 },
{ SCIF2_ERI_IRQ, INTC_IPRD, 1, 3 },
{ SCIF2_RXI_IRQ, INTC_IPRD, 1, 3 },
{ SCIF2_BRI_IRQ, INTC_IPRD, 1, 3 },
{ SCIF2_TXI_IRQ, INTC_IPRD, 1, 3 },
{ 86, 0, 4, 2 }, /* CMI0 */
{ 88, 1, 12, 3 }, /* SCIF0_ERI */
{ 89, 1, 12, 3 }, /* SCIF0_RXI */
{ 90, 1, 12, 3 }, /* SCIF0_BRI */
{ 91, 1, 12, 3 }, /* SCIF0_TXI */
{ 92, 1, 8, 3 }, /* SCIF1_ERI */
{ 93, 1, 8, 3 }, /* SCIF1_RXI */
{ 94, 1, 8, 3 }, /* SCIF1_BRI */
{ 95, 1, 8, 3 }, /* SCIF1_TXI */
{ 96, 1, 4, 3 }, /* SCIF2_ERI */
{ 97, 1, 4, 3 }, /* SCIF2_RXI */
{ 98, 1, 4, 3 }, /* SCIF2_BRI */
{ 99, 1, 4, 3 }, /* SCIF2_TXI */
};
static unsigned int ipr_offsets[] = {
0xf8080000, /* IPRC */
0xf8080002, /* IPRD */
0xf8080004, /* IPRE */
0xf8080006, /* IPRF */
0xf8080008, /* IPRG */
};
/* given the IPR index return the address of the IPR register */
unsigned int map_ipridx_to_addr(int idx)
{
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
return 0;
return ipr_offsets[idx];
}
void __init init_IRQ_ipr(void)
{
make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map));
......
......@@ -17,14 +17,14 @@
int __init detect_cpu_and_cache_system(void)
{
/* Just SH7206 for now .. */
cpu_data->type = CPU_SH7206;
current_cpu_data.type = CPU_SH7206;
cpu_data->dcache.ways = 4;
cpu_data->dcache.way_incr = (1 << 11);
cpu_data->dcache.sets = 128;
cpu_data->dcache.entry_shift = 4;
cpu_data->dcache.linesz = L1_CACHE_BYTES;
cpu_data->dcache.flags = 0;
current_cpu_data.dcache.ways = 4;
current_cpu_data.dcache.way_incr = (1 << 11);
current_cpu_data.dcache.sets = 128;
current_cpu_data.dcache.entry_shift = 4;
current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
current_cpu_data.dcache.flags = 0;
/*
* The icache is the same as the dcache as far as this setup is
......@@ -32,7 +32,7 @@ int __init detect_cpu_and_cache_system(void)
* lacks the U bit that the dcache has, none of this has any bearing
* on the cache info.
*/
cpu_data->icache = cpu_data->dcache;
current_cpu_data.icache = current_cpu_data.dcache;
return 0;
}
......
......@@ -57,55 +57,52 @@ static int __init sh7206_devices_setup(void)
}
__initcall(sh7206_devices_setup);
#define INTC_IPR08 0xfffe0c04UL
#define INTC_IPR09 0xfffe0c06UL
#define INTC_IPR14 0xfffe0c10UL
#define CMI0_IRQ 140
#define MTU1_TGI1A 164
#define SCIF0_BRI_IRQ 240
#define SCIF0_ERI_IRQ 241
#define SCIF0_RXI_IRQ 242
#define SCIF0_TXI_IRQ 243
#define SCIF1_BRI_IRQ 244
#define SCIF1_ERI_IRQ 245
#define SCIF1_RXI_IRQ 246
#define SCIF1_TXI_IRQ 247
#define SCIF2_BRI_IRQ 248
#define SCIF2_ERI_IRQ 249
#define SCIF2_RXI_IRQ 250
#define SCIF2_TXI_IRQ 251
#define SCIF3_BRI_IRQ 252
#define SCIF3_ERI_IRQ 253
#define SCIF3_RXI_IRQ 254
#define SCIF3_TXI_IRQ 255
static struct ipr_data sh7206_ipr_map[] = {
{ CMI0_IRQ, INTC_IPR08, 3, 2 },
{ MTU2_TGI1A, INTC_IPR09, 1, 2 },
{ SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 },
{ SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 },
{ SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 },
{ SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 },
{ SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 },
{ SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 },
{ SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 },
{ SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 },
{ SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 },
{ SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 },
{ SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 },
{ SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 },
{ SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 },
{ SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 },
{ SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 },
{ SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 },
{ 140, 7, 12, 2 }, /* CMI0 */
{ 164, 8, 4, 2 }, /* MTU2_TGI1A */
{ 240, 13, 12, 3 }, /* SCIF0_BRI */
{ 241, 13, 12, 3 }, /* SCIF0_ERI */
{ 242, 13, 12, 3 }, /* SCIF0_RXI */
{ 243, 13, 12, 3 }, /* SCIF0_TXI */
{ 244, 13, 8, 3 }, /* SCIF1_BRI */
{ 245, 13, 8, 3 }, /* SCIF1_ERI */
{ 246, 13, 8, 3 }, /* SCIF1_RXI */
{ 247, 13, 8, 3 }, /* SCIF1_TXI */
{ 248, 13, 4, 3 }, /* SCIF2_BRI */
{ 249, 13, 4, 3 }, /* SCIF2_ERI */
{ 250, 13, 4, 3 }, /* SCIF2_RXI */
{ 251, 13, 4, 3 }, /* SCIF2_TXI */
{ 252, 13, 0, 3 }, /* SCIF3_BRI */
{ 253, 13, 0, 3 }, /* SCIF3_ERI */
{ 254, 13, 0, 3 }, /* SCIF3_RXI */
{ 255, 13, 0, 3 }, /* SCIF3_TXI */
};
static unsigned int ipr_offsets[] = {
0xfffe0818, /* IPR01 */
0xfffe081a, /* IPR02 */
0, /* unused */
0, /* unused */
0xfffe0820, /* IPR05 */
0xfffe0c00, /* IPR06 */
0xfffe0c02, /* IPR07 */
0xfffe0c04, /* IPR08 */
0xfffe0c06, /* IPR09 */
0xfffe0c08, /* IPR10 */
0xfffe0c0a, /* IPR11 */
0xfffe0c0c, /* IPR12 */
0xfffe0c0e, /* IPR13 */
0xfffe0c10, /* IPR14 */
};
/* given the IPR index return the address of the IPR register */
unsigned int map_ipridx_to_addr(int idx)
{
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
return 0;
return ipr_offsets[idx];
}
void __init init_IRQ_ipr(void)
{
make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map));
......
......@@ -13,10 +13,8 @@
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
#include <asm/cpu/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/unistd.h>
! NOTE:
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
......@@ -138,14 +136,29 @@ ENTRY(tlb_protection_violation_store)
call_dpf:
mov.l 1f, r0
mov.l @r0, r6 ! address
mov r5, r8
mov.l @r0, r6
mov r6, r9
mov.l 2f, r0
sts pr, r10
jsr @r0
mov r15, r4
!
tst r0, r0
bf/s 0f
lds r10, pr
rts
nop
0: sti
mov.l 3f, r0
mov r9, r6
mov r8, r5
jmp @r0
mov r15, r4 ! regs
mov r15, r4
.align 2
1: .long MMU_TEA
2: .long __do_page_fault
3: .long do_page_fault
.align 2
......@@ -173,7 +186,7 @@ call_dae:
#if defined(CONFIG_SH_STANDARD_BIOS)
/* Unwind the stack and jmp to the debug entry */
debug_kernel_fw:
ENTRY(sh_bios_handler)
mov.l @r15+, r0
mov.l @r15+, r1
mov.l @r15+, r2
......@@ -332,175 +345,9 @@ general_exception:
!
!
/* This code makes some assumptions to improve performance.
* Make sure they are stil true. */
#if PTRS_PER_PGD != PTRS_PER_PTE
#error PGD and PTE sizes don't match
#endif
/* gas doesn't flag impossible values for mov #immediate as an error */
#if (_PAGE_PRESENT >> 2) > 0x7f
#error cannot load PAGE_PRESENT as an immediate
#endif
#if _PAGE_DIRTY > 0x7f
#error cannot load PAGE_DIRTY as an immediate
#endif
#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED
#error cannot derive PAGE_ACCESSED from PAGE_PRESENT
#endif
#if defined(CONFIG_CPU_SH4)
#define ldmmupteh(r) mov.l 8f, r
#else
#define ldmmupteh(r) mov #MMU_PTEH, r
#endif
.balign 1024,0,1024
tlb_miss:
#ifdef COUNT_EXCEPTIONS
! Increment the counts
mov.l 9f, k1
mov.l @k1, k2
add #1, k2
mov.l k2, @k1
#endif
! k0 scratch
! k1 pgd and pte pointers
! k2 faulting address
! k3 pgd and pte index masks
! k4 shift
! Load up the pgd entry (k1)
ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH
mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2
mov #-(PGDIR_SHIFT-2), k4 ! 6 EX
mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2)
mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2)
mov k2, k0 ! 5 MT (latency=0)
shld k4, k0 ! 99 EX
and k3, k0 ! 78 EX
mov.l @(k0, k1), k1 ! 21 LS (latency=2)
mov #-(PAGE_SHIFT-2), k4 ! 6 EX
! Load up the pte entry (k2)
mov k2, k0 ! 5 MT (latency=0)
shld k4, k0 ! 99 EX
tst k1, k1 ! 86 MT
bt 20f ! 110 BR
and k3, k0 ! 78 EX
mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT
mov.l @(k0, k1), k2 ! 21 LS (latency=2)
add k0, k1 ! 49 EX
#ifdef CONFIG_CPU_HAS_PTEA
! Test the entry for present and _PAGE_ACCESSED
mov #-28, k3 ! 6 EX
mov k2, k0 ! 5 MT (latency=0)
tst k4, k2 ! 68 MT
shld k3, k0 ! 99 EX
bt 20f ! 110 BR
! Set PTEA register
! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1)
!
! k0=pte>>28, k1=pte*, k2=pte, k3=<unused>, k4=_PAGE_PRESENT
and #0xe, k0 ! 79 EX
mov k0, k3 ! 5 MT (latency=0)
mov k2, k0 ! 5 MT (latency=0)
and #1, k0 ! 79 EX
or k0, k3 ! 82 EX
ldmmupteh(k0) ! 9 LS (latency=2)
shll2 k4 ! 101 EX _PAGE_ACCESSED
tst k4, k2 ! 68 MT
mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS
mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
#else
! Test the entry for present and _PAGE_ACCESSED
mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
tst k4, k2 ! 68 MT
shll2 k4 ! 101 EX _PAGE_ACCESSED
ldmmupteh(k0) ! 9 LS (latency=2)
bt 20f ! 110 BR
tst k4, k2 ! 68 MT
! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
#endif
! Set up the entry
and k2, k3 ! 78 EX
bt/s 10f ! 108 BR
mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS
ldtlb ! 128 CO
! At least one instruction between ldtlb and rte
nop ! 119 NOP
rte ! 126 CO
nop ! 119 NOP
10: or k4, k2 ! 82 EX
ldtlb ! 128 CO
! At least one instruction between ldtlb and rte
mov.l k2, @k1 ! 27 LS
rte ! 126 CO
! Note we cannot execute mov here, because it is executed after
! restoring SSR, so would be executed in user space.
nop ! 119 NOP
.align 5
! Once cache line if possible...
1: .long swapper_pg_dir
4: .short (PTRS_PER_PGD-1) << 2
5: .short _PAGE_PRESENT
7: .long _PAGE_FLAGS_HARDWARE_MASK
8: .long MMU_PTEH
#ifdef COUNT_EXCEPTIONS
9: .long exception_count_miss
#endif
! Either pgd or pte not present
20: mov.l 1f, k2
mov.l 1f, k2
mov.l 4f, k3
bra handle_exception
mov.l @k2, k2
......@@ -651,15 +498,6 @@ skip_save:
bf interrupt_exception
shlr2 r8
shlr r8
#ifdef COUNT_EXCEPTIONS
mov.l 5f, r9
add r8, r9
mov.l @r9, r10
add #1, r10
mov.l r10, @r9
#endif
mov.l 4f, r9
add r8, r9
mov.l @r9, r9
......@@ -673,9 +511,6 @@ skip_save:
2: .long 0x000080f0 ! FD=1, IMASK=15
3: .long 0xcfffffff ! RB=0, BL=0
4: .long exception_handling_table
#ifdef COUNT_EXCEPTIONS
5: .long exception_count_table
#endif
interrupt_exception:
mov.l 1f, r9
......
......@@ -50,41 +50,41 @@ int __init detect_cpu_and_cache_system(void)
back_to_P1();
cpu_data->dcache.ways = 4;
cpu_data->dcache.entry_shift = 4;
cpu_data->dcache.linesz = L1_CACHE_BYTES;
cpu_data->dcache.flags = 0;
current_cpu_data.dcache.ways = 4;
current_cpu_data.dcache.entry_shift = 4;
current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
current_cpu_data.dcache.flags = 0;
/*
* 7709A/7729 has 16K cache (256-entry), while 7702 has only
* 2K(direct) 7702 is not supported (yet)
*/
if (data0 == data1 && data2 == data3) { /* Shadow */
cpu_data->dcache.way_incr = (1 << 11);
cpu_data->dcache.entry_mask = 0x7f0;
cpu_data->dcache.sets = 128;
cpu_data->type = CPU_SH7708;
current_cpu_data.dcache.way_incr = (1 << 11);
current_cpu_data.dcache.entry_mask = 0x7f0;
current_cpu_data.dcache.sets = 128;
current_cpu_data.type = CPU_SH7708;
cpu_data->flags |= CPU_HAS_MMU_PAGE_ASSOC;
current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC;
} else { /* 7709A or 7729 */
cpu_data->dcache.way_incr = (1 << 12);
cpu_data->dcache.entry_mask = 0xff0;
cpu_data->dcache.sets = 256;
cpu_data->type = CPU_SH7729;
current_cpu_data.dcache.way_incr = (1 << 12);
current_cpu_data.dcache.entry_mask = 0xff0;
current_cpu_data.dcache.sets = 256;
current_cpu_data.type = CPU_SH7729;
#if defined(CONFIG_CPU_SUBTYPE_SH7706)
cpu_data->type = CPU_SH7706;
current_cpu_data.type = CPU_SH7706;
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
cpu_data->type = CPU_SH7710;
current_cpu_data.type = CPU_SH7710;
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
cpu_data->type = CPU_SH7705;
current_cpu_data.type = CPU_SH7705;
#if defined(CONFIG_SH7705_CACHE_32KB)
cpu_data->dcache.way_incr = (1 << 13);
cpu_data->dcache.entry_mask = 0x1ff0;
cpu_data->dcache.sets = 512;
current_cpu_data.dcache.way_incr = (1 << 13);
current_cpu_data.dcache.entry_mask = 0x1ff0;
current_cpu_data.dcache.sets = 512;
ctrl_outl(CCR_CACHE_32KB, CCR3);
#else
ctrl_outl(CCR_CACHE_16KB, CCR3);
......@@ -95,8 +95,8 @@ int __init detect_cpu_and_cache_system(void)
/*
* SH-3 doesn't have separate caches
*/
cpu_data->dcache.flags |= SH_CACHE_COMBINED;
cpu_data->icache = cpu_data->dcache;
current_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
current_cpu_data.icache = current_cpu_data.dcache;
return 0;
}
......
......@@ -51,3 +51,24 @@ static int __init sh7709_devices_setup(void)
ARRAY_SIZE(sh7709_devices));
}
__initcall(sh7709_devices_setup);
#define IPRx(A,N) .addr=A, .shift=0*N*-1
#define IPRA(N) IPRx(0xfffffee2UL,N)
#define IPRB(N) IPRx(0xfffffee4UL,N)
#define IPRE(N) IPRx(0xa400001aUL,N)
static struct ipr_data sh7709_ipr_map[] = {
[16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */
[17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */
[22] = { IPRA(3-0), 2 }, /* RTC CUI */
[23 ... 26] = { IPRB(7-4), 3 }, /* SCI */
[27] = { IPRB(15-12), 2 }, /* WDT ITI */
[48 ... 51] = { IPRE(15-12), 7 }, /* DMA */
[52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */
[56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */
};
void __init init_IRQ_ipr()
{
make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map));
}
......@@ -10,11 +10,10 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
#include <linux/io.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/io.h>
int __init detect_cpu_and_cache_system(void)
{
......@@ -36,20 +35,20 @@ int __init detect_cpu_and_cache_system(void)
/*
* Setup some sane SH-4 defaults for the icache
*/
cpu_data->icache.way_incr = (1 << 13);
cpu_data->icache.entry_shift = 5;
cpu_data->icache.sets = 256;
cpu_data->icache.ways = 1;
cpu_data->icache.linesz = L1_CACHE_BYTES;
current_cpu_data.icache.way_incr = (1 << 13);
current_cpu_data.icache.entry_shift = 5;
current_cpu_data.icache.sets = 256;
current_cpu_data.icache.ways = 1;
current_cpu_data.icache.linesz = L1_CACHE_BYTES;
/*
* And again for the dcache ..
*/
cpu_data->dcache.way_incr = (1 << 14);
cpu_data->dcache.entry_shift = 5;
cpu_data->dcache.sets = 512;
cpu_data->dcache.ways = 1;
cpu_data->dcache.linesz = L1_CACHE_BYTES;
current_cpu_data.dcache.way_incr = (1 << 14);
current_cpu_data.dcache.entry_shift = 5;
current_cpu_data.dcache.sets = 512;
current_cpu_data.dcache.ways = 1;
current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
/*
* Setup some generic flags we can probe
......@@ -57,16 +56,16 @@ int __init detect_cpu_and_cache_system(void)
*/
if (((pvr >> 16) & 0xff) == 0x10) {
if ((cvr & 0x02000000) == 0)
cpu_data->flags |= CPU_HAS_L2_CACHE;
current_cpu_data.flags |= CPU_HAS_L2_CACHE;
if ((cvr & 0x10000000) == 0)
cpu_data->flags |= CPU_HAS_DSP;
current_cpu_data.flags |= CPU_HAS_DSP;
cpu_data->flags |= CPU_HAS_LLSC;
current_cpu_data.flags |= CPU_HAS_LLSC;
}
/* FPU detection works for everyone */
if ((cvr & 0x20000000) == 1)
cpu_data->flags |= CPU_HAS_FPU;
current_cpu_data.flags |= CPU_HAS_FPU;
/* Mask off the upper chip ID */
pvr &= 0xffff;
......@@ -77,151 +76,151 @@ int __init detect_cpu_and_cache_system(void)
*/
switch (pvr) {
case 0x205:
cpu_data->type = CPU_SH7750;
cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
current_cpu_data.type = CPU_SH7750;
current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
CPU_HAS_PERF_COUNTER;
break;
case 0x206:
cpu_data->type = CPU_SH7750S;
cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
current_cpu_data.type = CPU_SH7750S;
current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
CPU_HAS_PERF_COUNTER;
break;
case 0x1100:
cpu_data->type = CPU_SH7751;
cpu_data->flags |= CPU_HAS_FPU;
current_cpu_data.type = CPU_SH7751;
current_cpu_data.flags |= CPU_HAS_FPU;
break;
case 0x2000:
cpu_data->type = CPU_SH73180;
cpu_data->icache.ways = 4;
cpu_data->dcache.ways = 4;
cpu_data->flags |= CPU_HAS_LLSC;
current_cpu_data.type = CPU_SH73180;
current_cpu_data.icache.ways = 4;
current_cpu_data.dcache.ways = 4;
current_cpu_data.flags |= CPU_HAS_LLSC;
break;
case 0x2001:
case 0x2004:
cpu_data->type = CPU_SH7770;
cpu_data->icache.ways = 4;
cpu_data->dcache.ways = 4;
current_cpu_data.type = CPU_SH7770;
current_cpu_data.icache.ways = 4;
current_cpu_data.dcache.ways = 4;
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
break;
case 0x2006:
case 0x200A:
if (prr == 0x61)
cpu_data->type = CPU_SH7781;
current_cpu_data.type = CPU_SH7781;
else
cpu_data->type = CPU_SH7780;
current_cpu_data.type = CPU_SH7780;
cpu_data->icache.ways = 4;
cpu_data->dcache.ways = 4;
current_cpu_data.icache.ways = 4;
current_cpu_data.dcache.ways = 4;
cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
CPU_HAS_LLSC;
break;
case 0x3000:
case 0x3003:
case 0x3009:
cpu_data->type = CPU_SH7343;
cpu_data->icache.ways = 4;
cpu_data->dcache.ways = 4;
cpu_data->flags |= CPU_HAS_LLSC;
current_cpu_data.type = CPU_SH7343;
current_cpu_data.icache.ways = 4;
current_cpu_data.dcache.ways = 4;
current_cpu_data.flags |= CPU_HAS_LLSC;
break;
case 0x3008:
if (prr == 0xa0) {
cpu_data->type = CPU_SH7722;
cpu_data->icache.ways = 4;
cpu_data->dcache.ways = 4;
cpu_data->flags |= CPU_HAS_LLSC;
current_cpu_data.type = CPU_SH7722;
current_cpu_data.icache.ways = 4;
current_cpu_data.dcache.ways = 4;
current_cpu_data.flags |= CPU_HAS_LLSC;
}
break;
case 0x8000:
cpu_data->type = CPU_ST40RA;
cpu_data->flags |= CPU_HAS_FPU;
current_cpu_data.type = CPU_ST40RA;
current_cpu_data.flags |= CPU_HAS_FPU;
break;
case 0x8100:
cpu_data->type = CPU_ST40GX1;
cpu_data->flags |= CPU_HAS_FPU;
current_cpu_data.type = CPU_ST40GX1;
current_cpu_data.flags |= CPU_HAS_FPU;
break;
case 0x700:
cpu_data->type = CPU_SH4_501;
cpu_data->icache.ways = 2;
cpu_data->dcache.ways = 2;
current_cpu_data.type = CPU_SH4_501;
current_cpu_data.icache.ways = 2;
current_cpu_data.dcache.ways = 2;
break;
case 0x600:
cpu_data->type = CPU_SH4_202;
cpu_data->icache.ways = 2;
cpu_data->dcache.ways = 2;
cpu_data->flags |= CPU_HAS_FPU;
current_cpu_data.type = CPU_SH4_202;
current_cpu_data.icache.ways = 2;
current_cpu_data.dcache.ways = 2;
current_cpu_data.flags |= CPU_HAS_FPU;
break;
case 0x500 ... 0x501:
switch (prr) {
case 0x10:
cpu_data->type = CPU_SH7750R;
current_cpu_data.type = CPU_SH7750R;
break;
case 0x11:
cpu_data->type = CPU_SH7751R;
current_cpu_data.type = CPU_SH7751R;
break;
case 0x50 ... 0x5f:
cpu_data->type = CPU_SH7760;
current_cpu_data.type = CPU_SH7760;
break;
}
cpu_data->icache.ways = 2;
cpu_data->dcache.ways = 2;
current_cpu_data.icache.ways = 2;
current_cpu_data.dcache.ways = 2;
cpu_data->flags |= CPU_HAS_FPU;
current_cpu_data.flags |= CPU_HAS_FPU;
break;
default:
cpu_data->type = CPU_SH_NONE;
current_cpu_data.type = CPU_SH_NONE;
break;
}
#ifdef CONFIG_SH_DIRECT_MAPPED
cpu_data->icache.ways = 1;
cpu_data->dcache.ways = 1;
current_cpu_data.icache.ways = 1;
current_cpu_data.dcache.ways = 1;
#endif
#ifdef CONFIG_CPU_HAS_PTEA
cpu_data->flags |= CPU_HAS_PTEA;
current_cpu_data.flags |= CPU_HAS_PTEA;
#endif
/*
* On anything that's not a direct-mapped cache, look to the CVR
* for I/D-cache specifics.
*/
if (cpu_data->icache.ways > 1) {
if (current_cpu_data.icache.ways > 1) {
size = sizes[(cvr >> 20) & 0xf];
cpu_data->icache.way_incr = (size >> 1);
cpu_data->icache.sets = (size >> 6);
current_cpu_data.icache.way_incr = (size >> 1);
current_cpu_data.icache.sets = (size >> 6);
}
/* Setup the rest of the I-cache info */
cpu_data->icache.entry_mask = cpu_data->icache.way_incr -
cpu_data->icache.linesz;
current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
current_cpu_data.icache.linesz;
cpu_data->icache.way_size = cpu_data->icache.sets *
cpu_data->icache.linesz;
current_cpu_data.icache.way_size = current_cpu_data.icache.sets *
current_cpu_data.icache.linesz;
/* And the rest of the D-cache */
if (cpu_data->dcache.ways > 1) {
if (current_cpu_data.dcache.ways > 1) {
size = sizes[(cvr >> 16) & 0xf];
cpu_data->dcache.way_incr = (size >> 1);
cpu_data->dcache.sets = (size >> 6);
current_cpu_data.dcache.way_incr = (size >> 1);
current_cpu_data.dcache.sets = (size >> 6);
}
cpu_data->dcache.entry_mask = cpu_data->dcache.way_incr -
cpu_data->dcache.linesz;
current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr -
current_cpu_data.dcache.linesz;
cpu_data->dcache.way_size = cpu_data->dcache.sets *
cpu_data->dcache.linesz;
current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
current_cpu_data.dcache.linesz;
/*
* Setup the L2 cache desc
*
* SH-4A's have an optional PIPT L2.
*/
if (cpu_data->flags & CPU_HAS_L2_CACHE) {
if (current_cpu_data.flags & CPU_HAS_L2_CACHE) {
/*
* Size calculation is much more sensible
* than it is for the L1.
......@@ -232,16 +231,22 @@ int __init detect_cpu_and_cache_system(void)
BUG_ON(!size);
cpu_data->scache.way_incr = (1 << 16);
cpu_data->scache.entry_shift = 5;
cpu_data->scache.ways = 4;
cpu_data->scache.linesz = L1_CACHE_BYTES;
cpu_data->scache.entry_mask =
(cpu_data->scache.way_incr - cpu_data->scache.linesz);
cpu_data->scache.sets = size /
(cpu_data->scache.linesz * cpu_data->scache.ways);
cpu_data->scache.way_size =
(cpu_data->scache.sets * cpu_data->scache.linesz);
current_cpu_data.scache.way_incr = (1 << 16);
current_cpu_data.scache.entry_shift = 5;
current_cpu_data.scache.ways = 4;
current_cpu_data.scache.linesz = L1_CACHE_BYTES;
current_cpu_data.scache.entry_mask =
(current_cpu_data.scache.way_incr -
current_cpu_data.scache.linesz);
current_cpu_data.scache.sets = size /
(current_cpu_data.scache.linesz *
current_cpu_data.scache.ways);
current_cpu_data.scache.way_size =
(current_cpu_data.scache.sets *
current_cpu_data.scache.linesz);
}
return 0;
......
......@@ -46,11 +46,13 @@ static struct platform_device rtc_device = {
static struct plat_sci_port sci_platform_data[] = {
{
#ifndef CONFIG_SH_RTS7751R2D
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCI,
.irqs = { 23, 24, 25, 0 },
}, {
#endif
.mapbase = 0xffe80000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
......@@ -101,7 +103,7 @@ static struct ipr_data sh7750_ipr_map[] = {
{ 35, 2, 8, 7 }, /* DMAC DMTE1 */
{ 36, 2, 8, 7 }, /* DMAC DMTE2 */
{ 37, 2, 8, 7 }, /* DMAC DMTE3 */
{ 28, 2, 8, 7 }, /* DMAC DMAE */
{ 38, 2, 8, 7 }, /* DMAC DMAE */
};
static struct ipr_data sh7751_ipr_map[] = {
......
......@@ -52,17 +52,11 @@ static int __init sh7760_devices_setup(void)
}
__initcall(sh7760_devices_setup);
/*
* SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
*/
static struct intc2_data intc2_irq_table[] = {
/* INTPRIO0 | INTMSK0 */
{48, 0, 28, 0, 31, 3}, /* IRQ 4 */
{49, 0, 24, 0, 30, 3}, /* IRQ 3 */
{50, 0, 20, 0, 29, 3}, /* IRQ 2 */
{51, 0, 16, 0, 28, 3}, /* IRQ 1 */
/* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
/* INTPRIO4 | INTMSK0 */
{56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */
{57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */
{58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */
......@@ -71,18 +65,15 @@ static struct intc2_data intc2_irq_table[] = {
{61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */
{62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */
{63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */
/* INTPRIO8 | INTMSK0 */
{52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */
{53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */
{54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */
{55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */
{64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */
{65, 8, 24, 0, 16, 3}, /* LCDC */
/* 66, 67 unused */
{68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */
{69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */
{70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */
/* 71 unused */
{72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */
{73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */
{74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */
......@@ -91,26 +82,71 @@ static struct intc2_data intc2_irq_table[] = {
{77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */
{78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */
{79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */
/* | INTMSK4 */
{80, 8, 4, 4, 23, 3}, /* SIM_ERI */
{81, 8, 4, 4, 22, 3}, /* SIM_RXI */
{82, 8, 4, 4, 21, 3}, /* SIM_TXI */
{83, 8, 4, 4, 20, 3}, /* SIM_TEI */
{84, 8, 0, 4, 19, 3}, /* HSPII */
/* INTPRIOC | INTMSK4 */
/* 85-87 unused/reserved */
{88, 12, 20, 4, 18, 3}, /* MMCI0 */
{89, 12, 20, 4, 17, 3}, /* MMCI1 */
{90, 12, 20, 4, 16, 3}, /* MMCI2 */
{91, 12, 20, 4, 15, 3}, /* MMCI3 */
{92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/
/* 93-107 reserved/undocumented */
{92, 12, 12, 4, 6, 3}, /* MFI */
{108,12, 4, 4, 1, 3}, /* ADC */
{109,12, 0, 4, 0, 3}, /* CMTI */
/* 110-111 reserved/unused */
};
static struct ipr_data sh7760_ipr_map[] = {
/* IRQ, IPR-idx, shift, priority */
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
{ 18, 0, 4, 2 }, /* TMU2 TUNI */
{ 19, 0, 4, 2 }, /* TMU2 TIPCI */
{ 27, 1, 12, 2 }, /* WDT ITI */
{ 28, 1, 8, 2 }, /* REF RCMI */
{ 29, 1, 8, 2 }, /* REF ROVI */
{ 32, 2, 0, 7 }, /* HUDI */
{ 33, 2, 12, 7 }, /* GPIOI */
{ 34, 2, 8, 7 }, /* DMAC DMTE0 */
{ 35, 2, 8, 7 }, /* DMAC DMTE1 */
{ 36, 2, 8, 7 }, /* DMAC DMTE2 */
{ 37, 2, 8, 7 }, /* DMAC DMTE3 */
{ 38, 2, 8, 7 }, /* DMAC DMAE */
{ 44, 2, 8, 7 }, /* DMAC DMTE4 */
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */
{ 46, 2, 8, 7 }, /* DMAC DMTE6 */
{ 47, 2, 8, 7 }, /* DMAC DMTE7 */
/* these here are only valid if INTC_ICR bit 7 is set to 1!
* XXX: maybe CONFIG_SH_IRLMODE symbol? SH7751 could use it too */
#if 0
{ 2, 3, 12, 3 }, /* IRL0 */
{ 5, 3, 8, 3 }, /* IRL1 */
{ 8, 3, 4, 3 }, /* IRL2 */
{ 11, 3, 0, 3 }, /* IRL3 */
#endif
};
static unsigned long ipr_offsets[] = {
0xffd00004UL, /* 0: IPRA */
0xffd00008UL, /* 1: IPRB */
0xffd0000cUL, /* 2: IPRC */
0xffd00010UL, /* 3: IPRD */
};
/* given the IPR index return the address of the IPR register */
unsigned int map_ipridx_to_addr(int idx)
{
if (idx >= ARRAY_SIZE(ipr_offsets))
return 0;
return ipr_offsets[idx];
}
void __init init_IRQ_intc2(void)
{
make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
}
void __init init_IRQ_ipr(void)
{
make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map));
}
/*
* arch/sh/kernel/debugtraps.S
*
* Debug trap jump tables for SuperH
*
* Copyright (C) 2006 Paul Mundt
*
* 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.
*/
#include <linux/sys.h>
#include <linux/linkage.h>
#if !defined(CONFIG_SH_KGDB)
#define kgdb_handle_exception debug_trap_handler
#endif
#if !defined(CONFIG_SH_STANDARD_BIOS)
#define sh_bios_handler debug_trap_handler
#endif
.data
ENTRY(debug_trap_table)
.long debug_trap_handler /* 0x30 */
.long debug_trap_handler /* 0x31 */
.long debug_trap_handler /* 0x32 */
.long debug_trap_handler /* 0x33 */
.long debug_trap_handler /* 0x34 */
.long debug_trap_handler /* 0x35 */
.long debug_trap_handler /* 0x36 */
.long debug_trap_handler /* 0x37 */
.long debug_trap_handler /* 0x38 */
.long debug_trap_handler /* 0x39 */
.long debug_trap_handler /* 0x3a */
.long debug_trap_handler /* 0x3b */
.long kgdb_handle_exception /* 0x3c */
.long debug_trap_handler /* 0x3d */
.long bug_trap_handler /* 0x3e */
.long sh_bios_handler /* 0x3f */
......@@ -106,12 +106,32 @@ static struct console scif_console = {
};
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
#define DEFAULT_BAUD 115200
/*
* Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
* devices that aren't using sh-ipl+g.
*/
static void scif_sercon_init(int baud)
static void scif_sercon_init(char *s)
{
unsigned baud = DEFAULT_BAUD;
char *e;
if (*s == ',')
++s;
if (*s) {
/* ignore ioport/device name */
s += strcspn(s, ",");
if (*s == ',')
s++;
}
if (*s) {
baud = simple_strtoul(s, &e, 0);
if (baud == 0 || s == e)
baud = DEFAULT_BAUD;
}
ctrl_outw(0, scif_port.mapbase + 8);
ctrl_outw(0, scif_port.mapbase);
......@@ -167,7 +187,7 @@ int __init setup_early_printk(char *buf)
early_console = &scif_console;
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
scif_sercon_init(115200);
scif_sercon_init(buf + 6);
#endif
}
#endif
......
......@@ -54,79 +54,24 @@
# define resume_kernel __restore_all
#endif
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
! If both are configured, handle the debug traps (breakpoints) in SW,
! but still allow BIOS traps to FW.
.align 2
debug_kernel:
#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
/* Force BIOS call to FW (debug_trap put TRA in r8) */
mov r8,r0
shlr2 r0
cmp/eq #0x3f,r0
bt debug_kernel_fw
#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
debug_enter:
#if defined(CONFIG_SH_KGDB)
/* Jump to kgdb, pass stacked regs as arg */
debug_kernel_sw:
mov.l 3f, r0
jmp @r0
mov r15, r4
.align 2
3: .long kgdb_handle_exception
#endif /* CONFIG_SH_KGDB */
#ifdef CONFIG_SH_STANDARD_BIOS
bra debug_kernel_fw
nop
#endif
#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
.align 2
debug_trap:
#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
mov r8, r0
shlr2 r0
cmp/eq #0x3f, r0 ! sh_bios() trap
bf 1f
#ifdef CONFIG_SH_KGDB
cmp/eq #0xff, r0 ! XXX: KGDB trap, fix for SH-2.
bf 1f
#endif
mov #OFF_SR, r0
mov.l @(r0,r15), r0 ! get status register
shll r0
shll r0 ! kernel space?
bt/s debug_kernel
1:
#endif
mov.l @r15, r0 ! Restore R0 value
mov.l 1f, r8
jmp @r8
nop
.align 2
ENTRY(exception_error)
!
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 3f, r0
mov.l 2f, r0
jsr @r0
nop
#endif
sti
mov.l 2f, r0
mov.l 1f, r0
jmp @r0
nop
!
.align 2
1: .long break_point_trap_software
2: .long do_exception_error
1: .long do_exception_error
#ifdef CONFIG_TRACE_IRQFLAGS
3: .long trace_hardirqs_on
2: .long trace_hardirqs_on
#endif
.align 2
......@@ -330,17 +275,32 @@ __restore_all:
.align 2
1: .long restore_all
.align 2
not_syscall_tra:
bra debug_trap
nop
.align 2
syscall_badsys: ! Bad syscall number
mov #-ENOSYS, r0
bra resume_userspace
mov.l r0, @(OFF_R0,r15) ! Return value
/*
* The main debug trap handler.
*
* r8=TRA (not the trap number!)
*
* Note: This assumes that the trapa value is left in its original
* form (without the shlr2 shift) so the calculation for the jump
* call table offset remains a simple in place mask.
*/
debug_trap:
mov r8, r0
and #(0xf << 2), r0
mov.l 1f, r8
add r0, r8
mov.l @r8, r8
jmp @r8
nop
.align 2
1: .long debug_trap_table
/*
* Syscall interface:
......@@ -348,17 +308,19 @@ syscall_badsys: ! Bad syscall number
* Syscall #: R3
* Arguments #0 to #3: R4--R7
* Arguments #4 to #6: R0, R1, R2
* TRA: (number of arguments + 0x10) x 4
* TRA: (number of arguments + ABI revision) x 4
*
* This code also handles delegating other traps to the BIOS/gdb stub
* according to:
*
* Trap number
* (TRA>>2) Purpose
* -------- -------
* 0x0-0xf old syscall ABI
* 0x10-0x1f new syscall ABI
* 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
* (TRA>>2) Purpose
* -------- -------
* 0x00-0x0f original SH-3/4 syscall ABI (not in general use).
* 0x10-0x1f general SH-3/4 syscall ABI.
* 0x20-0x2f syscall ABI for SH-2 parts.
* 0x30-0x3f debug traps used by the kernel.
* 0x40-0xff Not supported by all parts, so left unhandled.
*
* Note: When we're first called, the TRA value must be shifted
* right 2 bits in order to get the value that was used as the "trapa"
......@@ -375,17 +337,22 @@ ret_from_fork:
nop
.align 2
1: .long schedule_tail
!
/*
* The poorly named main trapa decode and dispatch routine, for
* system calls and debug traps through their respective jump tables.
*/
ENTRY(system_call)
#if !defined(CONFIG_CPU_SH2)
mov.l 1f, r9
mov.l @r9, r8 ! Read from TRA (Trap Address) Register
#endif
!
! Is the trap argument >= 0x20? (TRA will be >= 0x80)
mov #0x7f, r9
/*
* Check the trap type
*/
mov #((0x20 << 2) - 1), r9
cmp/hi r9, r8
bt/s not_syscall_tra
bt/s debug_trap ! it's a debug trap..
mov #OFF_TRA, r9
add r15, r9
mov.l r8, @r9 ! set TRA value to tra
......
/* $Id: io_generic.c,v 1.2 2003/05/04 19:29:53 lethal Exp $
*
* linux/arch/sh/kernel/io_generic.c
/*
* arch/sh/kernel/io_generic.c
*
* Copyright (C) 2000 Niibe Yutaka
* Copyright (C) 2005 Paul Mundt
* Copyright (C) 2005 - 2007 Paul Mundt
*
* Generic I/O routine. These can be used where a machine specific version
* is not required.
......@@ -13,8 +12,9 @@
* for more details.
*/
#include <linux/module.h>
#include <asm/io.h>
#include <linux/io.h>
#include <asm/machvec.h>
#include <asm/cacheflush.h>
#ifdef CONFIG_CPU_SH3
/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
......@@ -96,6 +96,7 @@ void generic_insw(unsigned long port, void *dst, unsigned long count)
while (count--)
*buf++ = *port_addr;
flush_dcache_all();
dummy_read();
}
......@@ -170,6 +171,7 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count)
while (count--)
*port_addr = *buf++;
flush_dcache_all();
dummy_read();
}
......
......@@ -1323,8 +1323,11 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
}
/* There has been an exception, most likely a breakpoint. */
void kgdb_handle_exception(struct pt_regs *regs)
asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int excep_code, vbr_val;
int count;
int trapa_value = ctrl_inl(TRA);
......@@ -1368,8 +1371,6 @@ void kgdb_handle_exception(struct pt_regs *regs)
vbr_val = trap_registers.vbr;
asm("ldc %0, vbr": :"r"(vbr_val));
return;
}
/* Trigger a breakpoint by function */
......
/* $Id: process.c,v 1.28 2004/05/05 16:54:23 lethal Exp $
/*
* arch/sh/kernel/process.c
*
* linux/arch/sh/kernel/process.c
* This file handles the architecture-dependent parts of process handling..
*
* Copyright (C) 1995 Linus Torvalds
*
* SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
* Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
* Copyright (C) 2002 - 2006 Paul Mundt
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#include <linux/module.h>
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/elfcore.h>
#include <linux/a.out.h>
#include <linux/slab.h>
#include <linux/pm.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <linux/kexec.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/elf.h>
#include <asm/ubc.h>
static int hlt_counter=0;
static int hlt_counter;
int ubc_usercnt = 0;
#define HARD_IDLE_TIMEOUT (HZ / 3)
void (*pm_idle)(void);
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
......@@ -44,14 +32,12 @@ void disable_hlt(void)
{
hlt_counter++;
}
EXPORT_SYMBOL(disable_hlt);
void enable_hlt(void)
{
hlt_counter--;
}
EXPORT_SYMBOL(enable_hlt);
void default_idle(void)
......@@ -152,19 +138,21 @@ __asm__(".align 5\n"
".align 2\n\t"
"1:.long do_exit");
/* Don't use this in BL=1(cli). Or else, CPU resets! */
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{ /* Don't use this in BL=1(cli). Or else, CPU resets! */
{
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));
regs.regs[4] = (unsigned long) arg;
regs.regs[5] = (unsigned long) fn;
regs.regs[4] = (unsigned long)arg;
regs.regs[5] = (unsigned long)fn;
regs.pc = (unsigned long) kernel_thread_helper;
regs.pc = (unsigned long)kernel_thread_helper;
regs.sr = (1 << 30);
/* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
&regs, 0, NULL, NULL);
}
/*
......@@ -211,21 +199,20 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
return fpvalid;
}
/*
/*
* Capture the user space registers if the task is not running (in user space)
*/
int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
{
struct pt_regs ptregs;
ptregs = *task_pt_regs(tsk);
elf_core_copy_regs(regs, &ptregs);
return 1;
}
int
dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *fpu)
int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpu)
{
int fpvalid = 0;
......@@ -263,12 +250,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs->regs[15] = usp;
ti->addr_limit = USER_DS;
} else {
childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE;
childregs->regs[15] = (unsigned long)task_stack_page(p) +
THREAD_SIZE;
ti->addr_limit = KERNEL_DS;
}
if (clone_flags & CLONE_SETTLS) {
if (clone_flags & CLONE_SETTLS)
childregs->gbr = childregs->regs[0];
}
childregs->regs[0] = 0; /* Set return value for child */
p->thread.sp = (unsigned long) childregs;
......@@ -280,8 +269,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
}
/* Tracing by user break controller. */
static void
ubc_set_tracing(int asid, unsigned long pc)
static void ubc_set_tracing(int asid, unsigned long pc)
{
#if defined(CONFIG_CPU_SH4A)
unsigned long val;
......@@ -297,7 +285,7 @@ ubc_set_tracing(int asid, unsigned long pc)
val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
ctrl_outl(val, UBC_CRR0);
/* Read UBC register that we writed last. For chekking UBC Register changed */
/* Read UBC register that we wrote last, for checking update */
val = ctrl_inl(UBC_CRR0);
#else /* CONFIG_CPU_SH4A */
......@@ -305,13 +293,14 @@ ubc_set_tracing(int asid, unsigned long pc)
#ifdef CONFIG_MMU
/* We don't have any ASID settings for the SH-2! */
if (cpu_data->type != CPU_SH7604)
if (current_cpu_data.type != CPU_SH7604)
ctrl_outb(asid, UBC_BASRA);
#endif
ctrl_outl(0, UBC_BAMRA);
if (cpu_data->type == CPU_SH7729 || cpu_data->type == CPU_SH7710) {
if (current_cpu_data.type == CPU_SH7729 ||
current_cpu_data.type == CPU_SH7710) {
ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
} else {
......@@ -325,7 +314,8 @@ ubc_set_tracing(int asid, unsigned long pc)
* switch_to(x,y) should switch tasks from x to y.
*
*/
struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next)
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next)
{
#if defined(CONFIG_SH_FPU)
unlazy_fpu(prev, task_pt_regs(prev));
......@@ -354,7 +344,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
#ifdef CONFIG_MMU
/*
* Restore the kernel mode register
* k7 (r7_bank1)
* k7 (r7_bank1)
*/
asm volatile("ldc %0, r7_bank"
: /* no output */
......@@ -367,7 +357,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
else if (next->thread.ubc_pc && next->mm) {
int asid = 0;
#ifdef CONFIG_MMU
asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK;
asid |= cpu_asid(smp_processor_id(), next->mm);
#endif
ubc_set_tracing(asid, next->thread.ubc_pc);
} else {
......@@ -405,7 +395,8 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
if (!newsp)
newsp = regs->regs[15];
return do_fork(clone_flags, newsp, regs, 0,
(int __user *)parent_tidptr, (int __user *)child_tidptr);
(int __user *)parent_tidptr,
(int __user *)child_tidptr);
}
/*
......@@ -493,9 +484,27 @@ asmlinkage void break_point_trap(void)
force_sig(SIGTRAP, current);
}
asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
/*
* Generic trap handler.
*/
asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
/* Rewind */
regs->pc -= 2;
force_sig(SIGTRAP, current);
}
/*
* Special handler for BUG() traps.
*/
asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
......
/*
* linux/arch/sh/kernel/setup.c
* arch/sh/kernel/setup.c
*
* Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2002, 2003 Paul Mundt
*/
/*
* This file handles the architecture-dependent parts of initialization
*
* Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2002 - 2006 Paul Mundt
*/
#include <linux/screen_info.h>
#include <linux/ioport.h>
#include <linux/init.h>
......@@ -395,9 +392,9 @@ static const char *cpu_name[] = {
[CPU_SH_NONE] = "Unknown"
};
const char *get_cpu_subtype(void)
const char *get_cpu_subtype(struct sh_cpuinfo *c)
{
return cpu_name[boot_cpu_data.type];
return cpu_name[c->type];
}
#ifdef CONFIG_PROC_FS
......@@ -407,19 +404,19 @@ static const char *cpu_flags[] = {
"ptea", "llsc", "l2", NULL
};
static void show_cpuflags(struct seq_file *m)
static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
{
unsigned long i;
seq_printf(m, "cpu flags\t:");
if (!cpu_data->flags) {
if (!c->flags) {
seq_printf(m, " %s\n", cpu_flags[0]);
return;
}
for (i = 0; cpu_flags[i]; i++)
if ((cpu_data->flags & (1 << i)))
if ((c->flags & (1 << i)))
seq_printf(m, " %s", cpu_flags[i+1]);
seq_printf(m, "\n");
......@@ -441,16 +438,20 @@ static void show_cacheinfo(struct seq_file *m, const char *type,
*/
static int show_cpuinfo(struct seq_file *m, void *v)
{
unsigned int cpu = smp_processor_id();
struct sh_cpuinfo *c = v;
unsigned int cpu = c - cpu_data;
if (!cpu_online(cpu))
return 0;
if (!cpu && cpu_online(cpu))
if (cpu == 0)
seq_printf(m, "machine\t\t: %s\n", get_system_type());
seq_printf(m, "processor\t: %d\n", cpu);
seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c));
show_cpuflags(m);
show_cpuflags(m, c);
seq_printf(m, "cache type\t: ");
......@@ -459,22 +460,22 @@ static int show_cpuinfo(struct seq_file *m, void *v)
* unified cache on the SH-2 and SH-3, as well as the harvard
* style cache on the SH-4.
*/
if (boot_cpu_data.icache.flags & SH_CACHE_COMBINED) {
if (c->icache.flags & SH_CACHE_COMBINED) {
seq_printf(m, "unified\n");
show_cacheinfo(m, "cache", boot_cpu_data.icache);
show_cacheinfo(m, "cache", c->icache);
} else {
seq_printf(m, "split (harvard)\n");
show_cacheinfo(m, "icache", boot_cpu_data.icache);
show_cacheinfo(m, "dcache", boot_cpu_data.dcache);
show_cacheinfo(m, "icache", c->icache);
show_cacheinfo(m, "dcache", c->dcache);
}
/* Optional secondary cache */
if (boot_cpu_data.flags & CPU_HAS_L2_CACHE)
show_cacheinfo(m, "scache", boot_cpu_data.scache);
if (c->flags & CPU_HAS_L2_CACHE)
show_cacheinfo(m, "scache", c->scache);
seq_printf(m, "bogomips\t: %lu.%02lu\n",
boot_cpu_data.loops_per_jiffy/(500000/HZ),
(boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100);
c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100);
return show_clocks(m);
}
......
......@@ -105,7 +105,6 @@ EXPORT_SYMBOL(__flush_purge_region);
EXPORT_SYMBOL(clear_user_page);
#endif
EXPORT_SYMBOL(flush_tlb_page);
EXPORT_SYMBOL(__down_trylock);
#ifdef CONFIG_SMP
......
......@@ -127,7 +127,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
{
struct task_struct *tsk = current;
if (!(cpu_data->flags & CPU_HAS_FPU))
if (!(current_cpu_data.flags & CPU_HAS_FPU))
return 0;
set_used_math();
......@@ -140,7 +140,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
{
struct task_struct *tsk = current;
if (!(cpu_data->flags & CPU_HAS_FPU))
if (!(current_cpu_data.flags & CPU_HAS_FPU))
return 0;
if (!used_math()) {
......@@ -181,7 +181,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
#undef COPY
#ifdef CONFIG_SH_FPU
if (cpu_data->flags & CPU_HAS_FPU) {
if (current_cpu_data.flags & CPU_HAS_FPU) {
int owned_fp;
struct task_struct *tsk = current;
......
......@@ -319,15 +319,15 @@ ENTRY(sys_call_table)
.long sys_mq_getsetattr
.long sys_kexec_load
.long sys_waitid
.long sys_ni_syscall /* 285 */
.long sys_add_key
.long sys_add_key /* 285 */
.long sys_request_key
.long sys_keyctl
.long sys_ioprio_set
.long sys_ioprio_get /* 290 */
.long sys_inotify_init
.long sys_ioprio_get
.long sys_inotify_init /* 290 */
.long sys_inotify_add_watch
.long sys_inotify_rm_watch
.long sys_ni_syscall
.long sys_migrate_pages
.long sys_openat /* 295 */
.long sys_mkdirat
......
......@@ -156,13 +156,13 @@ static inline void do_bug_verbose(struct pt_regs *regs)
{
}
#endif /* CONFIG_DEBUG_BUGVERBOSE */
#endif /* CONFIG_BUG */
void handle_BUG(struct pt_regs *regs)
{
do_bug_verbose(regs);
die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
}
#endif /* CONFIG_BUG */
/*
* handle an instruction that does an unaligned memory access by emulating the
......@@ -641,7 +641,7 @@ int is_dsp_inst(struct pt_regs *regs)
* Safe guard if DSP mode is already enabled or we're lacking
* the DSP altogether.
*/
if (!(cpu_data->flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
if (!(current_cpu_data.flags & CPU_HAS_DSP) || (regs->sr & SR_DSP))
return 0;
get_user(inst, ((unsigned short *) regs->pc));
......
......@@ -20,7 +20,7 @@ config CPU_SH4
bool
select CPU_HAS_INTEVT
select CPU_HAS_SR_RB
select CPU_HAS_PTEA if !CPU_SUBTYPE_ST40
select CPU_HAS_PTEA if (!CPU_SUBTYPE_ST40 && !CPU_SH4A) || CPU_SHX2
config CPU_SH4A
bool
......@@ -72,6 +72,7 @@ config CPU_SUBTYPE_SH7705
config CPU_SUBTYPE_SH7706
bool "Support SH7706 processor"
select CPU_SH3
select CPU_HAS_IPR_IRQ
help
Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU.
......@@ -92,6 +93,7 @@ config CPU_SUBTYPE_SH7708
config CPU_SUBTYPE_SH7709
bool "Support SH7709 processor"
select CPU_SH3
select CPU_HAS_IPR_IRQ
select CPU_HAS_PINT_IRQ
help
Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU.
......@@ -149,6 +151,7 @@ config CPU_SUBTYPE_SH7760
bool "Support SH7760 processor"
select CPU_SH4
select CPU_HAS_INTC2_IRQ
select CPU_HAS_IPR_IRQ
config CPU_SUBTYPE_SH4_202
bool "Support SH4-202 processor"
......
......@@ -46,10 +46,10 @@ static int cache_seq_show(struct seq_file *file, void *iter)
if (cache_type == CACHE_TYPE_DCACHE) {
base = CACHE_OC_ADDRESS_ARRAY;
cache = &cpu_data->dcache;
cache = &current_cpu_data.dcache;
} else {
base = CACHE_IC_ADDRESS_ARRAY;
cache = &cpu_data->icache;
cache = &current_cpu_data.icache;
}
/*
......
......@@ -44,11 +44,11 @@ void __flush_wback_region(void *start, int size)
for (v = begin; v < end; v+=L1_CACHE_BYTES) {
unsigned long addrstart = CACHE_OC_ADDRESS_ARRAY;
for (j = 0; j < cpu_data->dcache.ways; j++) {
for (j = 0; j < current_cpu_data.dcache.ways; j++) {
unsigned long data, addr, p;
p = __pa(v);
addr = addrstart | (v & cpu_data->dcache.entry_mask);
addr = addrstart | (v & current_cpu_data.dcache.entry_mask);
local_irq_save(flags);
data = ctrl_inl(addr);
......@@ -60,7 +60,7 @@ void __flush_wback_region(void *start, int size)
break;
}
local_irq_restore(flags);
addrstart += cpu_data->dcache.way_incr;
addrstart += current_cpu_data.dcache.way_incr;
}
}
}
......@@ -85,7 +85,7 @@ void __flush_purge_region(void *start, int size)
data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */
addr = CACHE_OC_ADDRESS_ARRAY |
(v & cpu_data->dcache.entry_mask) | SH_CACHE_ASSOC;
(v & current_cpu_data.dcache.entry_mask) | SH_CACHE_ASSOC;
ctrl_outl(data, addr);
}
}
......
......@@ -54,21 +54,21 @@ static void __init emit_cache_params(void)
ctrl_inl(CCN_CVR),
ctrl_inl(CCN_PRR));
printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
cpu_data->icache.ways,
cpu_data->icache.sets,
cpu_data->icache.way_incr);
current_cpu_data.icache.ways,
current_cpu_data.icache.sets,
current_cpu_data.icache.way_incr);
printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
cpu_data->icache.entry_mask,
cpu_data->icache.alias_mask,
cpu_data->icache.n_aliases);
current_cpu_data.icache.entry_mask,
current_cpu_data.icache.alias_mask,
current_cpu_data.icache.n_aliases);
printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
cpu_data->dcache.ways,
cpu_data->dcache.sets,
cpu_data->dcache.way_incr);
current_cpu_data.dcache.ways,
current_cpu_data.dcache.sets,
current_cpu_data.dcache.way_incr);
printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
cpu_data->dcache.entry_mask,
cpu_data->dcache.alias_mask,
cpu_data->dcache.n_aliases);
current_cpu_data.dcache.entry_mask,
current_cpu_data.dcache.alias_mask,
current_cpu_data.dcache.n_aliases);
if (!__flush_dcache_segment_fn)
panic("unknown number of cache ways\n");
......@@ -87,10 +87,10 @@ void __init p3_cache_init(void)
{
int i;
compute_alias(&cpu_data->icache);
compute_alias(&cpu_data->dcache);
compute_alias(&current_cpu_data.icache);
compute_alias(&current_cpu_data.dcache);
switch (cpu_data->dcache.ways) {
switch (current_cpu_data.dcache.ways) {
case 1:
__flush_dcache_segment_fn = __flush_dcache_segment_1way;
break;
......@@ -110,7 +110,7 @@ void __init p3_cache_init(void)
if (ioremap_page_range(P3SEG, P3SEG + (PAGE_SIZE * 4), 0, PAGE_KERNEL))
panic("%s failed.", __FUNCTION__);
for (i = 0; i < cpu_data->dcache.n_aliases; i++)
for (i = 0; i < current_cpu_data.dcache.n_aliases; i++)
mutex_init(&p3map_mutex[i]);
}
......@@ -200,13 +200,14 @@ void flush_cache_sigtramp(unsigned long addr)
: /* no output */
: "m" (__m(v)));
index = CACHE_IC_ADDRESS_ARRAY | (v & cpu_data->icache.entry_mask);
index = CACHE_IC_ADDRESS_ARRAY |
(v & current_cpu_data.icache.entry_mask);
local_irq_save(flags);
jump_to_P2();
for (i = 0; i < cpu_data->icache.ways;
i++, index += cpu_data->icache.way_incr)
for (i = 0; i < current_cpu_data.icache.ways;
i++, index += current_cpu_data.icache.way_incr)
ctrl_outl(0, index); /* Clear out Valid-bit */
back_to_P1();
......@@ -223,7 +224,7 @@ static inline void flush_cache_4096(unsigned long start,
* All types of SH-4 require PC to be in P2 to operate on the I-cache.
* Some types of SH-4 require PC to be in P2 to operate on the D-cache.
*/
if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) ||
if ((current_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
(start < CACHE_OC_ADDRESS_ARRAY))
exec_offset = 0x20000000;
......@@ -236,16 +237,26 @@ static inline void flush_cache_4096(unsigned long start,
/*
* Write back & invalidate the D-cache of the page.
* (To avoid "alias" issues)
*
* This uses a lazy write-back on UP, which is explicitly
* disabled on SMP.
*/
void flush_dcache_page(struct page *page)
{
if (test_bit(PG_mapped, &page->flags)) {
#ifndef CONFIG_SMP
struct address_space *mapping = page_mapping(page);
if (mapping && !mapping_mapped(mapping))
set_bit(PG_dcache_dirty, &page->flags);
else
#endif
{
unsigned long phys = PHYSADDR(page_address(page));
unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
int i, n;
/* Loop all the D-cache */
n = cpu_data->dcache.n_aliases;
n = current_cpu_data.dcache.n_aliases;
for (i = 0; i < n; i++, addr += 4096)
flush_cache_4096(addr, phys);
}
......@@ -277,7 +288,7 @@ static inline void flush_icache_all(void)
void flush_dcache_all(void)
{
(*__flush_dcache_segment_fn)(0UL, cpu_data->dcache.way_size);
(*__flush_dcache_segment_fn)(0UL, current_cpu_data.dcache.way_size);
wmb();
}
......@@ -291,8 +302,8 @@ static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
unsigned long d = 0, p = start & PAGE_MASK;
unsigned long alias_mask = cpu_data->dcache.alias_mask;
unsigned long n_aliases = cpu_data->dcache.n_aliases;
unsigned long alias_mask = current_cpu_data.dcache.alias_mask;
unsigned long n_aliases = current_cpu_data.dcache.n_aliases;
unsigned long select_bit;
unsigned long all_aliases_mask;
unsigned long addr_offset;
......@@ -379,7 +390,7 @@ void flush_cache_mm(struct mm_struct *mm)
* If cache is only 4k-per-way, there are never any 'aliases'. Since
* the cache is physically tagged, the data can just be left in there.
*/
if (cpu_data->dcache.n_aliases == 0)
if (current_cpu_data.dcache.n_aliases == 0)
return;
/*
......@@ -416,7 +427,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
unsigned long phys = pfn << PAGE_SHIFT;
unsigned int alias_mask;
alias_mask = cpu_data->dcache.alias_mask;
alias_mask = current_cpu_data.dcache.alias_mask;
/* We only need to flush D-cache when we have alias */
if ((address^phys) & alias_mask) {
......@@ -430,7 +441,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
phys);
}
alias_mask = cpu_data->icache.alias_mask;
alias_mask = current_cpu_data.icache.alias_mask;
if (vma->vm_flags & VM_EXEC) {
/*
* Evict entries from the portion of the cache from which code
......@@ -462,7 +473,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
* If cache is only 4k-per-way, there are never any 'aliases'. Since
* the cache is physically tagged, the data can just be left in there.
*/
if (cpu_data->dcache.n_aliases == 0)
if (current_cpu_data.dcache.n_aliases == 0)
return;
/*
......@@ -523,7 +534,7 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys,
unsigned long a, ea, p;
unsigned long temp_pc;
dcache = &cpu_data->dcache;
dcache = &current_cpu_data.dcache;
/* Write this way for better assembly. */
way_count = dcache->ways;
way_incr = dcache->way_incr;
......@@ -598,7 +609,7 @@ static void __flush_dcache_segment_1way(unsigned long start,
base_addr = ((base_addr >> 16) << 16);
base_addr |= start;
dcache = &cpu_data->dcache;
dcache = &current_cpu_data.dcache;
linesz = dcache->linesz;
way_incr = dcache->way_incr;
way_size = dcache->way_size;
......@@ -640,7 +651,7 @@ static void __flush_dcache_segment_2way(unsigned long start,
base_addr = ((base_addr >> 16) << 16);
base_addr |= start;
dcache = &cpu_data->dcache;
dcache = &current_cpu_data.dcache;
linesz = dcache->linesz;
way_incr = dcache->way_incr;
way_size = dcache->way_size;
......@@ -699,7 +710,7 @@ static void __flush_dcache_segment_4way(unsigned long start,
base_addr = ((base_addr >> 16) << 16);
base_addr |= start;
dcache = &cpu_data->dcache;
dcache = &current_cpu_data.dcache;
linesz = dcache->linesz;
way_incr = dcache->way_incr;
way_size = dcache->way_size;
......
......@@ -3,11 +3,11 @@
*
* Copyright (C) 1999, 2000 Niibe Yutaka
* Copyright (C) 2004 Alex Song
* Copyright (C) 2006 Paul Mundt
*
* 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.
*
*/
#include <linux/init.h>
#include <linux/mman.h>
......@@ -32,9 +32,9 @@ static inline void cache_wback_all(void)
{
unsigned long ways, waysize, addrstart;
ways = cpu_data->dcache.ways;
waysize = cpu_data->dcache.sets;
waysize <<= cpu_data->dcache.entry_shift;
ways = current_cpu_data.dcache.ways;
waysize = current_cpu_data.dcache.sets;
waysize <<= current_cpu_data.dcache.entry_shift;
addrstart = CACHE_OC_ADDRESS_ARRAY;
......@@ -43,7 +43,7 @@ static inline void cache_wback_all(void)
for (addr = addrstart;
addr < addrstart + waysize;
addr += cpu_data->dcache.linesz) {
addr += current_cpu_data.dcache.linesz) {
unsigned long data;
int v = SH_CACHE_UPDATED | SH_CACHE_VALID;
......@@ -51,10 +51,9 @@ static inline void cache_wback_all(void)
if ((data & v) == v)
ctrl_outl(data & ~v, addr);
}
addrstart += cpu_data->dcache.way_incr;
addrstart += current_cpu_data.dcache.way_incr;
} while (--ways);
}
......@@ -94,9 +93,9 @@ static void __flush_dcache_page(unsigned long phys)
local_irq_save(flags);
jump_to_P2();
ways = cpu_data->dcache.ways;
waysize = cpu_data->dcache.sets;
waysize <<= cpu_data->dcache.entry_shift;
ways = current_cpu_data.dcache.ways;
waysize = current_cpu_data.dcache.sets;
waysize <<= current_cpu_data.dcache.entry_shift;
addrstart = CACHE_OC_ADDRESS_ARRAY;
......@@ -105,7 +104,7 @@ static void __flush_dcache_page(unsigned long phys)
for (addr = addrstart;
addr < addrstart + waysize;
addr += cpu_data->dcache.linesz) {
addr += current_cpu_data.dcache.linesz) {
unsigned long data;
data = ctrl_inl(addr) & (0x1ffffC00 | SH_CACHE_VALID);
......@@ -115,7 +114,7 @@ static void __flush_dcache_page(unsigned long phys)
}
}
addrstart += cpu_data->dcache.way_incr;
addrstart += current_cpu_data.dcache.way_incr;
} while (--ways);
back_to_P1();
......@@ -128,7 +127,11 @@ static void __flush_dcache_page(unsigned long phys)
*/
void flush_dcache_page(struct page *page)
{
if (test_bit(PG_mapped, &page->flags))
struct address_space *mapping = page_mapping(page);
if (mapping && !mapping_mapped(mapping))
set_bit(PG_dcache_dirty, &page->flags);
else
__flush_dcache_page(PHYSADDR(page_address(page)));
}
......
......@@ -17,6 +17,7 @@
#include <linux/kprobes.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
#include <asm/kgdb.h>
extern void die(const char *,struct pt_regs *,long);
......@@ -224,3 +225,89 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
if (!user_mode(regs))
goto no_context;
}
#ifdef CONFIG_SH_STORE_QUEUES
/*
* This is a special case for the SH-4 store queues, as pages for this
* space still need to be faulted in before it's possible to flush the
* store queue cache for writeout to the remapped region.
*/
#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
#else
#define P3_ADDR_MAX P4SEG
#endif
/*
* Called with interrupts disabled.
*/
asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
unsigned long writeaccess,
unsigned long address)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
pte_t entry;
struct mm_struct *mm = current->mm;
spinlock_t *ptl;
int ret = 1;
#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
kgdb_bus_err_hook();
#endif
/*
* We don't take page faults for P1, P2, and parts of P4, these
* are always mapped, whether it be due to legacy behaviour in
* 29-bit mode, or due to PMB configuration in 32-bit mode.
*/
if (address >= P3SEG && address < P3_ADDR_MAX) {
pgd = pgd_offset_k(address);
mm = NULL;
} else {
if (unlikely(address >= TASK_SIZE || !mm))
return 1;
pgd = pgd_offset(mm, address);
}
pud = pud_offset(pgd, address);
if (pud_none_or_clear_bad(pud))
return 1;
pmd = pmd_offset(pud, address);
if (pmd_none_or_clear_bad(pmd))
return 1;
if (mm)
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
else
pte = pte_offset_kernel(pmd, address);
entry = *pte;
if (unlikely(pte_none(entry) || pte_not_present(entry)))
goto unlock;
if (unlikely(writeaccess && !pte_write(entry)))
goto unlock;
if (writeaccess)
entry = pte_mkdirty(entry);
entry = pte_mkyoung(entry);
#ifdef CONFIG_CPU_SH4
/*
* ITLB is not affected by "ldtlb" instruction.
* So, we need to flush the entry by ourselves.
*/
local_flush_tlb_one(get_asid(), address & PAGE_MASK);
#endif
set_pte(pte, entry);
update_mmu_cache(NULL, address, entry);
ret = 0;
unlock:
if (mm)
pte_unmap_unlock(pte, ptl);
return ret;
}
......@@ -39,11 +39,6 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD];
/*
* Cache of MMU context last used.
*/
unsigned long mmu_context_cache = NO_CONTEXT;
#ifdef CONFIG_MMU
/* It'd be good if these lines were in the standard header file. */
#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
......@@ -111,7 +106,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
__flush_tlb_page(get_asid(), addr);
flush_tlb_one(get_asid(), addr);
}
/*
......
......@@ -44,12 +44,6 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
if (!size || last_addr < phys_addr)
return NULL;
/*
* Don't remap the low PCI/ISA area, it's always mapped..
*/
if (phys_addr >= 0xA0000 && last_addr < 0x100000)
return (void __iomem *)phys_to_virt(phys_addr);
/*
* If we're on an SH7751 or SH7780 PCI controller, PCI memory is
* mapped at the end of the address space (typically 0xfd000000)
......
......@@ -13,7 +13,7 @@
extern struct mutex p3map_mutex[];
#define CACHE_ALIAS (cpu_data->dcache.alias_mask)
#define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
/*
* clear_user_page
......@@ -23,7 +23,6 @@ extern struct mutex p3map_mutex[];
*/
void clear_user_page(void *to, unsigned long address, struct page *page)
{
__set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
clear_page(to);
else {
......@@ -40,7 +39,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
set_pte(pte, entry);
local_irq_save(flags);
__flush_tlb_page(get_asid(), p3_addr);
flush_tlb_one(get_asid(), p3_addr);
local_irq_restore(flags);
update_mmu_cache(NULL, p3_addr, entry);
__clear_user_page((void *)p3_addr, to);
......@@ -59,7 +58,6 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
void copy_user_page(void *to, void *from, unsigned long address,
struct page *page)
{
__set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
copy_page(to, from);
else {
......@@ -76,7 +74,7 @@ void copy_user_page(void *to, void *from, unsigned long address,
mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
set_pte(pte, entry);
local_irq_save(flags);
__flush_tlb_page(get_asid(), p3_addr);
flush_tlb_one(get_asid(), p3_addr);
local_irq_restore(flags);
update_mmu_cache(NULL, p3_addr, entry);
__copy_user_page((void *)p3_addr, from, to);
......@@ -84,23 +82,3 @@ void copy_user_page(void *to, void *from, unsigned long address,
mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
}
}
/*
* For SH-4, we have our own implementation for ptep_get_and_clear
*/
inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t pte = *ptep;
pte_clear(mm, addr, ptep);
if (!pte_not_present(pte)) {
unsigned long pfn = pte_pfn(pte);
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
struct address_space *mapping = page_mapping(page);
if (!mapping || !mapping_writably_mapped(mapping))
__clear_bit(PG_mapped, &page->flags);
}
}
return pte;
}
......@@ -7,9 +7,7 @@
* 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.
*
*/
#include <linux/init.h>
#include <linux/mman.h>
#include <linux/mm.h>
......@@ -45,13 +43,13 @@ static inline void __flush_purge_virtual_region(void *p1, void *virt, int size)
p = __pa(p1_begin);
ways = cpu_data->dcache.ways;
ways = current_cpu_data.dcache.ways;
addr = CACHE_OC_ADDRESS_ARRAY;
do {
unsigned long data;
addr |= (v & cpu_data->dcache.entry_mask);
addr |= (v & current_cpu_data.dcache.entry_mask);
data = ctrl_inl(addr);
if ((data & CACHE_PHYSADDR_MASK) ==
......@@ -60,7 +58,7 @@ static inline void __flush_purge_virtual_region(void *p1, void *virt, int size)
ctrl_outl(data, addr);
}
addr += cpu_data->dcache.way_incr;
addr += current_cpu_data.dcache.way_incr;
} while (--ways);
p1_begin += L1_CACHE_BYTES;
......@@ -76,7 +74,6 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
{
struct page *page = virt_to_page(to);
__set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
clear_page(to);
__flush_wback_region(to, PAGE_SIZE);
......@@ -95,12 +92,11 @@ void clear_user_page(void *to, unsigned long address, struct page *pg)
* @from: P1 address
* @address: U0 address to be mapped
*/
void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
void copy_user_page(void *to, void *from, unsigned long address,
struct page *pg)
{
struct page *page = virt_to_page(to);
__set_bit(PG_mapped, &page->flags);
if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
copy_page(to, from);
__flush_wback_region(to, PAGE_SIZE);
......@@ -112,26 +108,3 @@ void copy_user_page(void *to, void *from, unsigned long address, struct page *pg
__flush_wback_region(to, PAGE_SIZE);
}
}
/*
* For SH7705, we have our own implementation for ptep_get_and_clear
* Copied from pg-sh4.c
*/
inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t pte = *ptep;
pte_clear(mm, addr, ptep);
if (!pte_not_present(pte)) {
unsigned long pfn = pte_pfn(pte);
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
struct address_space *mapping = page_mapping(page);
if (!mapping || !mapping_writably_mapped(mapping))
__clear_bit(PG_mapped, &page->flags);
}
}
return pte;
}
......@@ -2,24 +2,28 @@
* TLB flushing operations for SH with an MMU.
*
* Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2003 Paul Mundt
* Copyright (C) 2003 - 2006 Paul Mundt
*
* 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.
*/
#include <linux/mm.h>
#include <linux/io.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
if (vma->vm_mm && vma->vm_mm->context.id != NO_CONTEXT) {
unsigned int cpu = smp_processor_id();
if (vma->vm_mm && cpu_context(cpu, vma->vm_mm) != NO_CONTEXT) {
unsigned long flags;
unsigned long asid;
unsigned long saved_asid = MMU_NO_ASID;
asid = vma->vm_mm->context.id & MMU_CONTEXT_ASID_MASK;
asid = cpu_asid(cpu, vma->vm_mm);
page &= PAGE_MASK;
local_irq_save(flags);
......@@ -27,33 +31,34 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
saved_asid = get_asid();
set_asid(asid);
}
__flush_tlb_page(asid, page);
local_flush_tlb_one(asid, page);
if (saved_asid != MMU_NO_ASID)
set_asid(saved_asid);
local_irq_restore(flags);
}
}
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
struct mm_struct *mm = vma->vm_mm;
unsigned int cpu = smp_processor_id();
if (mm->context.id != NO_CONTEXT) {
if (cpu_context(cpu, mm) != NO_CONTEXT) {
unsigned long flags;
int size;
local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
mm->context.id = NO_CONTEXT;
cpu_context(cpu, mm) = NO_CONTEXT;
if (mm == current->mm)
activate_context(mm);
activate_context(mm, cpu);
} else {
unsigned long asid;
unsigned long saved_asid = MMU_NO_ASID;
asid = mm->context.id & MMU_CONTEXT_ASID_MASK;
asid = cpu_asid(cpu, mm);
start &= PAGE_MASK;
end += (PAGE_SIZE - 1);
end &= PAGE_MASK;
......@@ -62,7 +67,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
set_asid(asid);
}
while (start < end) {
__flush_tlb_page(asid, start);
local_flush_tlb_one(asid, start);
start += PAGE_SIZE;
}
if (saved_asid != MMU_NO_ASID)
......@@ -72,26 +77,27 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
}
}
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
unsigned int cpu = smp_processor_id();
unsigned long flags;
int size;
local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
flush_tlb_all();
local_flush_tlb_all();
} else {
unsigned long asid;
unsigned long saved_asid = get_asid();
asid = init_mm.context.id & MMU_CONTEXT_ASID_MASK;
asid = cpu_asid(cpu, &init_mm);
start &= PAGE_MASK;
end += (PAGE_SIZE - 1);
end &= PAGE_MASK;
set_asid(asid);
while (start < end) {
__flush_tlb_page(asid, start);
local_flush_tlb_one(asid, start);
start += PAGE_SIZE;
}
set_asid(saved_asid);
......@@ -99,22 +105,24 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
local_irq_restore(flags);
}
void flush_tlb_mm(struct mm_struct *mm)
void local_flush_tlb_mm(struct mm_struct *mm)
{
unsigned int cpu = smp_processor_id();
/* Invalidate all TLB of this process. */
/* Instead of invalidating each TLB, we get new MMU context. */
if (mm->context.id != NO_CONTEXT) {
if (cpu_context(cpu, mm) != NO_CONTEXT) {
unsigned long flags;
local_irq_save(flags);
mm->context.id = NO_CONTEXT;
cpu_context(cpu, mm) = NO_CONTEXT;
if (mm == current->mm)
activate_context(mm);
activate_context(mm, cpu);
local_irq_restore(flags);
}
}
void flush_tlb_all(void)
void local_flush_tlb_all(void)
{
unsigned long flags, status;
......@@ -132,3 +140,54 @@ void flush_tlb_all(void)
ctrl_barrier();
local_irq_restore(flags);
}
void update_mmu_cache(struct vm_area_struct *vma,
unsigned long address, pte_t pte)
{
unsigned long flags;
unsigned long pteval;
unsigned long vpn;
struct page *page;
unsigned long pfn = pte_pfn(pte);
struct address_space *mapping;
if (!pfn_valid(pfn))
return;
page = pfn_to_page(pfn);
mapping = page_mapping(page);
if (mapping) {
unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
if (dirty)
__flush_wback_region((void *)P1SEGADDR(phys),
PAGE_SIZE);
}
local_irq_save(flags);
/* Set PTEH register */
vpn = (address & MMU_VPN_MASK) | get_asid();
ctrl_outl(vpn, MMU_PTEH);
pteval = pte_val(pte);
#ifdef CONFIG_CPU_HAS_PTEA
/* Set PTEA register */
/* TODO: make this look less hacky */
ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
#endif
/* Set PTEL register */
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
#if defined(CONFIG_SH_WRITETHROUGH) && defined(CONFIG_CPU_SH4)
pteval |= _PAGE_WT;
#endif
/* conveniently, we want all the software flags to be 0 anyway */
ctrl_outl(pteval, MMU_PTEL);
/* Load the TLB */
asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
local_irq_restore(flags);
}
......@@ -13,39 +13,33 @@
/*
* Nothing too terribly exciting here ..
*/
void flush_tlb(void)
{
BUG();
}
void flush_tlb_all(void)
void local_flush_tlb_all(void)
{
BUG();
}
void flush_tlb_mm(struct mm_struct *mm)
void local_flush_tlb_mm(struct mm_struct *mm)
{
BUG();
}
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
BUG();
}
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
BUG();
}
void __flush_tlb_page(unsigned long asid, unsigned long page)
void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
BUG();
}
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
BUG();
}
......@@ -55,4 +49,3 @@ void update_mmu_cache(struct vm_area_struct * vma,
{
BUG();
}
......@@ -8,71 +8,11 @@
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t pte)
{
unsigned long flags;
unsigned long pteval;
unsigned long vpn;
/* Ptrace may call this routine. */
if (vma && current->active_mm != vma->vm_mm)
return;
#if defined(CONFIG_SH7705_CACHE_32KB)
{
struct page *page = pte_page(pte);
unsigned long pfn = pte_pfn(pte);
if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
__flush_wback_region((void *)P1SEGADDR(phys),
PAGE_SIZE);
__set_bit(PG_mapped, &page->flags);
}
}
#endif
local_irq_save(flags);
/* Set PTEH register */
vpn = (address & MMU_VPN_MASK) | get_asid();
ctrl_outl(vpn, MMU_PTEH);
pteval = pte_val(pte);
/* Set PTEL register */
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
/* conveniently, we want all the software flags to be 0 anyway */
ctrl_outl(pteval, MMU_PTEL);
/* Load the TLB */
asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
local_irq_restore(flags);
}
void __flush_tlb_page(unsigned long asid, unsigned long page)
void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
unsigned long addr, data;
int i, ways = MMU_NTLB_WAYS;
......@@ -86,7 +26,7 @@ void __flush_tlb_page(unsigned long asid, unsigned long page)
addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000);
data = (page & 0xfffe0000) | asid; /* VALID bit is off */
if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) {
if ((current_cpu_data.flags & CPU_HAS_MMU_PAGE_ASSOC)) {
addr |= MMU_PAGE_ASSOC_BIT;
ways = 1; /* we already know the way .. */
}
......@@ -94,4 +34,3 @@ void __flush_tlb_page(unsigned long asid, unsigned long page)
for (i = 0; i < ways; i++)
ctrl_outl(data, addr + (i << 8));
}
......@@ -8,76 +8,11 @@
*
* Released under the terms of the GNU GPL v2.0.
*/
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t pte)
{
unsigned long flags;
unsigned long pteval;
unsigned long vpn;
struct page *page;
unsigned long pfn;
/* Ptrace may call this routine. */
if (vma && current->active_mm != vma->vm_mm)
return;
pfn = pte_pfn(pte);
if (pfn_valid(pfn)) {
page = pfn_to_page(pfn);
if (!test_bit(PG_mapped, &page->flags)) {
unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
__flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
__set_bit(PG_mapped, &page->flags);
}
}
local_irq_save(flags);
/* Set PTEH register */
vpn = (address & MMU_VPN_MASK) | get_asid();
ctrl_outl(vpn, MMU_PTEH);
pteval = pte_val(pte);
/* Set PTEA register */
if (cpu_data->flags & CPU_HAS_PTEA)
/* TODO: make this look less hacky */
ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
/* Set PTEL register */
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
#ifdef CONFIG_SH_WRITETHROUGH
pteval |= _PAGE_WT;
#endif
/* conveniently, we want all the software flags to be 0 anyway */
ctrl_outl(pteval, MMU_PTEL);
/* Load the TLB */
asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
local_irq_restore(flags);
}
void __flush_tlb_page(unsigned long asid, unsigned long page)
void local_flush_tlb_one(unsigned long asid, unsigned long page)
{
unsigned long addr, data;
......@@ -93,4 +28,3 @@ void __flush_tlb_page(unsigned long asid, unsigned long page)
ctrl_outl(data, addr);
back_to_P1();
}
......@@ -259,7 +259,7 @@ static struct oprofile_operations sh7750_perf_counter_ops = {
int __init oprofile_arch_init(struct oprofile_operations **ops)
{
if (!(cpu_data->flags & CPU_HAS_PERF_COUNTER))
if (!(current_cpu_data.flags & CPU_HAS_PERF_COUNTER))
return -ENODEV;
sh7750_perf_counter_ops.cpu_type = (char *)get_cpu_subtype();
......
......@@ -16,7 +16,6 @@ HD64461 HD64461
HD64465 HD64465
SATURN SH_SATURN
DREAMCAST SH_DREAMCAST
BIGSUR SH_BIGSUR
MPC1211 SH_MPC1211
SNAPGEAR SH_SECUREEDGE5410
HS7751RVOIP SH_HS7751RVOIP
......
include include/asm-generic/Kbuild.asm
header-y += cpu-features.h
/*
*
* Hitachi Big Sur Eval Board support
*
* Dustin McIntire (dustin@sensoria.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Derived from Hitachi SH7751 reference manual
*
*/
#ifndef _ASM_BIGSUR_H_
#define _ASM_BIGSUR_H_
#include <asm/irq.h>
#include <asm/hd64465/hd64465.h>
/* 7751 Internal IRQ's used by external CPLD controller */
#define BIGSUR_IRQ_LOW 0
#define BIGSUR_IRQ_NUM 14 /* External CPLD level 1 IRQs */
#define BIGSUR_IRQ_HIGH (BIGSUR_IRQ_LOW + BIGSUR_IRQ_NUM)
#define BIGSUR_2NDLVL_IRQ_LOW (HD64465_IRQ_BASE+HD64465_IRQ_NUM)
#define BIGSUR_2NDLVL_IRQ_NUM 32 /* Level 2 IRQs = 4 regs * 8 bits */
#define BIGSUR_2NDLVL_IRQ_HIGH (BIGSUR_2NDLVL_IRQ_LOW + \
BIGSUR_2NDLVL_IRQ_NUM)
/* PCI interrupt base number (A_INTA-A_INTD) */
#define BIGSUR_SH7751_PCI_IRQ_BASE (BIGSUR_2NDLVL_IRQ_LOW+10)
/* CPLD registers and external chip addresses */
#define BIGSUR_HD64464_ADDR 0xB2000000
#define BIGSUR_DGDR 0xB1FFFE00
#define BIGSUR_BIDR 0xB1FFFD00
#define BIGSUR_CSLR 0xB1FFFC00
#define BIGSUR_SW1R 0xB1FFFB00
#define BIGSUR_DBGR 0xB1FFFA00
#define BIGSUR_BDTR 0xB1FFF900
#define BIGSUR_BDRR 0xB1FFF800
#define BIGSUR_PPR1 0xB1FFF700
#define BIGSUR_PPR2 0xB1FFF600
#define BIGSUR_IDE2 0xB1FFF500
#define BIGSUR_IDE3 0xB1FFF400
#define BIGSUR_SPCR 0xB1FFF300
#define BIGSUR_ETHR 0xB1FE0000
#define BIGSUR_PPDR 0xB1FDFF00
#define BIGSUR_ICTL 0xB1FDFE00
#define BIGSUR_ICMD 0xB1FDFD00
#define BIGSUR_DMA0 0xB1FDFC00
#define BIGSUR_DMA1 0xB1FDFB00
#define BIGSUR_IRQ0 0xB1FDFA00
#define BIGSUR_IRQ1 0xB1FDF900
#define BIGSUR_IRQ2 0xB1FDF800
#define BIGSUR_IRQ3 0xB1FDF700
#define BIGSUR_IMR0 0xB1FDF600
#define BIGSUR_IMR1 0xB1FDF500
#define BIGSUR_IMR2 0xB1FDF400
#define BIGSUR_IMR3 0xB1FDF300
#define BIGSUR_IRLMR0 0xB1FDF200
#define BIGSUR_IRLMR1 0xB1FDF100
#define BIGSUR_V320USC_ADDR 0xB1000000
#define BIGSUR_HD64465_ADDR 0xB0000000
#define BIGSUR_INTERNAL_BASE 0xB0000000
/* SMC ethernet card parameters */
#define BIGSUR_ETHER_IOPORT 0x220
/* IDE register paramters */
#define BIGSUR_IDECMD_IOPORT 0x1f0
#define BIGSUR_IDECTL_IOPORT 0x1f8
/* LED bit position in BIGSUR_CSLR */
#define BIGSUR_LED (1<<4)
/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
#define BIGSUR_LSR0_SIZE (64*(1<<20)) //64MB
#define BIGSUR_LSR1_SIZE (64*(1<<20)) //64MB
#endif /* _ASM_BIGSUR_H_ */
/*
* include/asm-sh/bigsur/io.h
*
* By Dustin McIntire (dustin@sensoria.com) (c)2001
* Derived from io_hd64465.h, which bore the message:
* By Greg Banks <gbanks@pocketpenguins.com>
* (c) 2000 PocketPenguins Inc.
* and from io_hd64461.h, which bore the message:
* Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* IO functions for a Hitachi Big Sur Evaluation Board.
*/
#ifndef _ASM_SH_IO_BIGSUR_H
#define _ASM_SH_IO_BIGSUR_H
#include <linux/types.h>
extern unsigned long bigsur_isa_port2addr(unsigned long offset);
extern int bigsur_irq_demux(int irq);
/* Provision for generic secondary demux step -- used by PCMCIA code */
extern void bigsur_register_irq_demux(int irq,
int (*demux)(int irq, void *dev), void *dev);
extern void bigsur_unregister_irq_demux(int irq);
/* Set this variable to 1 to see port traffic */
extern int bigsur_io_debug;
/* Map a range of ports to a range of kernel virtual memory. */
extern void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift);
extern void bigsur_port_unmap(u32 baseport, u32 nports);
#endif /* _ASM_SH_IO_BIGSUR_H */
/*
* include/asm-sh/bigsur/serial.h
*
* Configuration details for Big Sur 16550 based serial ports
* i.e. HD64465, PCMCIA, etc.
*/
#ifndef _ASM_SERIAL_BIGSUR_H
#define _ASM_SERIAL_BIGSUR_H
#include <asm/hd64465.h>
#define BASE_BAUD (3379200 / 16)
#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
#define SERIAL_PORT_DFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */
/* XXX: This should be moved ino irq.h */
#define irq_cannonicalize(x) (x)
#endif /* _ASM_SERIAL_BIGSUR_H */
......@@ -19,9 +19,9 @@ static void __init check_bugs(void)
extern unsigned long loops_per_jiffy;
char *p = &init_utsname()->machine[2]; /* "sh" */
cpu_data->loops_per_jiffy = loops_per_jiffy;
current_cpu_data.loops_per_jiffy = loops_per_jiffy;
switch (cpu_data->type) {
switch (current_cpu_data.type) {
case CPU_SH7604 ... CPU_SH7619:
*p++ = '2';
break;
......@@ -54,7 +54,7 @@ static void __init check_bugs(void)
break;
}
printk("CPU: %s\n", get_cpu_subtype());
printk("CPU: %s\n", get_cpu_subtype(&current_cpu_data));
#ifndef __LITTLE_ENDIAN__
/* 'eb' means 'Endian Big' */
......
......@@ -30,5 +30,8 @@ extern void __flush_invalidate_region(void *start, int size);
#define HAVE_ARCH_UNMAPPED_AREA
/* Page flag for lazy dcache write-back for the aliasing UP caches */
#define PG_dcache_dirty PG_arch_1
#endif /* __KERNEL__ */
#endif /* __ASM_SH_CACHEFLUSH_H */
......@@ -36,8 +36,6 @@
/* 32KB cache, 4kb PAGE sizes need to check bit 12 */
#define CACHE_ALIAS 0x00001000
#define PG_mapped PG_arch_1
void flush_cache_all(void);
void flush_cache_mm(struct mm_struct *mm);
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
......
......@@ -17,6 +17,7 @@
* so we need them.
*/
void flush_cache_all(void);
void flush_dcache_all(void);
void flush_cache_mm(struct mm_struct *mm);
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
......@@ -38,16 +39,4 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
/* Initialization of P3 area for copy_user_page */
void p3_cache_init(void);
#define PG_mapped PG_arch_1
#ifdef CONFIG_MMU
extern int remap_area_pages(unsigned long addr, unsigned long phys_addr,
unsigned long size, unsigned long flags);
#else /* CONFIG_MMU */
static inline int remap_area_pages(unsigned long addr, unsigned long phys_addr,
unsigned long size, unsigned long flags)
{
return 0;
}
#endif /* CONFIG_MMU */
#endif /* __ASM_CPU_SH4_CACHEFLUSH_H */
......@@ -3,6 +3,17 @@
#define DMAOR_INIT ( 0x8000 | DMAOR_DME )
/* SH7751/7760/7780 DMA IRQ sources */
#define DMTE0_IRQ 34
#define DMTE1_IRQ 35
#define DMTE2_IRQ 36
#define DMTE3_IRQ 37
#define DMTE4_IRQ 44
#define DMTE5_IRQ 45
#define DMTE6_IRQ 46
#define DMTE7_IRQ 47
#define DMAE_IRQ 38
#ifdef CONFIG_CPU_SH4A
#define SH_DMAC_BASE 0xfc808020
......
......@@ -53,6 +53,10 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
consistent_free(vaddr, size);
}
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
#define dma_is_consistent(d, h) (1)
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir)
{
......
#ifndef __ASM_EC3104_H
#define __ASM_EC3104_H
/*
* Most of the register set is at 0xb0ec0000 - 0xb0ecffff.
*
* as far as I've figured it out the register map is:
* 0xb0ec0000 - id string
* 0xb0ec0XXX - power management
* 0xb0ec1XXX - interrupt control
* 0xb0ec3XXX - ps2 port (touch pad on aero 8000)
* 0xb0ec6XXX - i2c
* 0xb0ec7000 - first serial port (proprietary connector on aero 8000)
* 0xb0ec8000 - second serial port
* 0xb0ec9000 - third serial port
* 0xb0eca000 - fourth serial port (keyboard controller on aero 8000)
* 0xb0eccXXX - GPIO
* 0xb0ecdXXX - GPIO
*/
#define EC3104_BASE 0xb0ec0000
#define EC3104_SER4_DATA (EC3104_BASE+0xa000)
#define EC3104_SER4_IIR (EC3104_BASE+0xa008)
#define EC3104_SER4_MCR (EC3104_BASE+0xa010)
#define EC3104_SER4_LSR (EC3104_BASE+0xa014)
#define EC3104_SER4_MSR (EC3104_BASE+0xa018)
/*
* our ISA bus. this seems to be real ISA.
*/
#define EC3104_ISA_BASE 0xa5000000
#define EC3104_IRQ 11
#define EC3104_IRQBASE 64
#define EC3104_IRQ_SER1 EC3104_IRQBASE + 7
#define EC3104_IRQ_SER2 EC3104_IRQBASE + 8
#define EC3104_IRQ_SER3 EC3104_IRQBASE + 9
#define EC3104_IRQ_SER4 EC3104_IRQBASE + 10
#endif /* __ASM_EC3104_H */
#ifndef _ASM_SH_IO_EC3104_H
#define _ASM_SH_IO_EC3104_H
#include <linux/types.h>
extern unsigned char ec3104_inb(unsigned long port);
extern unsigned short ec3104_inw(unsigned long port);
extern unsigned long ec3104_inl(unsigned long port);
extern void ec3104_outb(unsigned char value, unsigned long port);
extern void ec3104_outw(unsigned short value, unsigned long port);
extern void ec3104_outl(unsigned long value, unsigned long port);
extern int ec3104_irq_demux(int irq);
#endif /* _ASM_SH_IO_EC3104_H */
extern unsigned char ec3104_kbd_sysrq_xlate[];
extern int ec3104_kbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int ec3104_kbd_getkeycode(unsigned int scancode);
extern int ec3104_kbd_translate(unsigned char, unsigned char *, char);
extern char ec3104_kbd_unexpected_up(unsigned char);
extern void ec3104_kbd_leds(unsigned char);
extern void ec3104_kbd_init_hw(void);
#define kbd_sysrq_xlate ec3104_kbd_sysrq_xlate
#define kbd_setkeycode ec3104_kbd_setkeycode
#define kbd_getkeycode ec3104_kbd_getkeycode
#define kbd_translate ec3104_kbd_translate
#define kbd_unexpected_up ec3104_kbd_unexpected_up
#define kbd_leds ec3104_kbd_leds
#define kbd_init_hw ec3104_kbd_init_hw
#include <asm/ec3104.h>
/* Naturally we don't know the exact value but 115200 baud has a divisor
* of 9 and 19200 baud has a divisor of 52, so this seems like a good
* guess. */
#define BASE_BAUD (16800000 / 16)
#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
/* there is a fourth serial port with the expected values as well, but
* it's got the keyboard controller behind it so we can't really use it
* (without moving the keyboard driver to userspace, which doesn't sound
* like a very good idea) */
#define SERIAL_PORT_DFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0x11C00, EC3104_IRQBASE+7, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x12000, EC3104_IRQBASE+8, STD_COM_FLAGS }, /* ttyS1 */ \
{ 0, BASE_BAUD, 0x12400, EC3104_IRQBASE+9, STD_COM_FLAGS }, /* ttyS2 */
/* XXX: This should be moved ino irq.h */
#define irq_cannonicalize(x) (x)
......@@ -66,12 +66,8 @@
/* 3. OFFCHIP_NR_IRQS */
#if defined(CONFIG_HD64461)
# define OFFCHIP_NR_IRQS 18
#elif defined (CONFIG_SH_BIGSUR) /* must be before CONFIG_HD64465 */
# define OFFCHIP_NR_IRQS 48
#elif defined(CONFIG_HD64465)
# define OFFCHIP_NR_IRQS 16
#elif defined (CONFIG_SH_EC3104)
# define OFFCHIP_NR_IRQS 16
#elif defined (CONFIG_SH_DREAMCAST)
# define OFFCHIP_NR_IRQS 96
#elif defined (CONFIG_SH_TITAN)
......
......@@ -85,10 +85,10 @@ extern int setjmp(jmp_buf __jmpb);
#define KGDB_PRINTK(...) printk("KGDB: " __VA_ARGS__)
/* Forced breakpoint */
#define BREAKPOINT() do { \
if (kgdb_enabled) { \
asm volatile("trapa #0xff"); \
} \
#define BREAKPOINT() \
do { \
if (kgdb_enabled) \
__asm__ __volatile__("trapa #0x3c"); \
} while (0)
/* KGDB should be able to flush all kernel text space */
......
#ifndef __MMU_H
#define __MMU_H
#if !defined(CONFIG_MMU)
/* Default "unsigned long" context */
typedef unsigned long mm_context_id_t[NR_CPUS];
typedef struct {
#ifdef CONFIG_MMU
mm_context_id_t id;
void *vdso;
#else
struct vm_list_struct *vmlist;
unsigned long end_brk;
#endif
} mm_context_t;
#else
/* Default "unsigned long" context */
typedef unsigned long mm_context_id_t;
typedef struct {
mm_context_id_t id;
void *vdso;
} mm_context_t;
#endif /* CONFIG_MMU */
/*
* Privileged Space Mapping Buffer (PMB) definitions
*/
......
/*
* Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2003 Paul Mundt
* Copyright (C) 2003 - 2006 Paul Mundt
*
* ASID handling idea taken from MIPS implementation.
*/
......@@ -19,11 +19,6 @@
* (b) ASID (Address Space IDentifier)
*/
/*
* Cache of MMU context last used.
*/
extern unsigned long mmu_context_cache;
#define MMU_CONTEXT_ASID_MASK 0x000000ff
#define MMU_CONTEXT_VERSION_MASK 0xffffff00
#define MMU_CONTEXT_FIRST_VERSION 0x00000100
......@@ -32,6 +27,11 @@ extern unsigned long mmu_context_cache;
/* ASID is 8-bit value, so it can't be 0x100 */
#define MMU_NO_ASID 0x100
#define cpu_context(cpu, mm) ((mm)->context.id[cpu])
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & \
MMU_CONTEXT_ASID_MASK)
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
/*
* Virtual Page Number mask
*/
......@@ -41,18 +41,17 @@ extern unsigned long mmu_context_cache;
/*
* Get MMU context if needed.
*/
static inline void get_mmu_context(struct mm_struct *mm)
static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu)
{
unsigned long mc = mmu_context_cache;
unsigned long asid = asid_cache(cpu);
/* Check if we have old version of context. */
if (((mm->context.id ^ mc) & MMU_CONTEXT_VERSION_MASK) == 0)
if (((cpu_context(cpu, mm) ^ asid) & MMU_CONTEXT_VERSION_MASK) == 0)
/* It's up to date, do nothing */
return;
/* It's old, we need to get new context with new version. */
mc = ++mmu_context_cache;
if (!(mc & MMU_CONTEXT_ASID_MASK)) {
if (!(++asid & MMU_CONTEXT_ASID_MASK)) {
/*
* We exhaust ASID of this version.
* Flush all TLB and start new cycle.
......@@ -63,10 +62,11 @@ static inline void get_mmu_context(struct mm_struct *mm)
* Fix version; Note that we avoid version #0
* to distingush NO_CONTEXT.
*/
if (!mc)
mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
if (!asid)
asid = MMU_CONTEXT_FIRST_VERSION;
}
mm->context.id = mc;
cpu_context(cpu, mm) = asid_cache(cpu) = asid;
}
/*
......@@ -74,9 +74,13 @@ static inline void get_mmu_context(struct mm_struct *mm)
* instance.
*/
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
struct mm_struct *mm)
{
mm->context.id = NO_CONTEXT;
int i;
for (i = 0; i < num_online_cpus(); i++)
cpu_context(i, mm) = NO_CONTEXT;
return 0;
}
......@@ -117,10 +121,10 @@ static inline unsigned long get_asid(void)
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
*/
static inline void activate_context(struct mm_struct *mm)
static inline void activate_context(struct mm_struct *mm, unsigned int cpu)
{
get_mmu_context(mm);
set_asid(mm->context.id & MMU_CONTEXT_ASID_MASK);
get_mmu_context(mm, cpu);
set_asid(cpu_asid(cpu, mm));
}
/* MMU_TTB is used for optimizing the fault handling. */
......@@ -138,10 +142,15 @@ static inline void switch_mm(struct mm_struct *prev,
struct mm_struct *next,
struct task_struct *tsk)
{
unsigned int cpu = smp_processor_id();
if (likely(prev != next)) {
cpu_set(cpu, next->cpu_vm_mask);
set_TTB(next->pgd);
activate_context(next);
}
activate_context(next, cpu);
} else
if (!cpu_test_and_set(cpu, next->cpu_vm_mask))
activate_context(next, cpu);
}
#define deactivate_mm(tsk,mm) do { } while (0)
......@@ -159,7 +168,7 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
#define destroy_context(mm) do { } while (0)
#define set_asid(asid) do { } while (0)
#define get_asid() (0)
#define activate_context(mm) do { } while (0)
#define activate_context(mm,cpu) do { } while (0)
#define switch_mm(prev,next,tsk) do { } while (0)
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) do { } while (0)
......@@ -174,14 +183,16 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
*/
static inline void enable_mmu(void)
{
unsigned int cpu = smp_processor_id();
/* Enable MMU */
ctrl_outl(MMU_CONTROL_INIT, MMUCR);
ctrl_barrier();
if (mmu_context_cache == NO_CONTEXT)
mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
if (asid_cache(cpu) == NO_CONTEXT)
asid_cache(cpu) = MMU_CONTEXT_FIRST_VERSION;
set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK);
set_asid(asid_cache(cpu) & MMU_CONTEXT_ASID_MASK);
}
static inline void disable_mmu(void)
......
......@@ -13,6 +13,8 @@
[ P4 control ] 0xE0000000
*/
#ifdef __KERNEL__
/* PAGE_SHIFT determines the page size */
#if defined(CONFIG_PAGE_SIZE_4KB)
# define PAGE_SHIFT 12
......@@ -51,7 +53,6 @@
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT)
#endif
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
extern void (*clear_page)(void *to);
......
......@@ -43,17 +43,17 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
/* PGD bits */
#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS)
#define PGDIR_BITS (32 - PGDIR_SHIFT)
#define PGDIR_SIZE (1 << PGDIR_SHIFT)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* Entries per level */
#define PTRS_PER_PTE (PAGE_SIZE / 4)
#define PTRS_PER_PTE (PAGE_SIZE / (1 << PTE_MAGNITUDE))
#define PTRS_PER_PGD (PAGE_SIZE / 4)
#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
#define PTE_PHYS_MASK 0x1ffff000
#define PTE_PHYS_MASK (0x20000000 - PAGE_SIZE)
/*
* First 1MB map is used by fixed purpose.
......@@ -583,11 +583,6 @@ struct mm_struct;
extern unsigned int kobjsize(const void *objp);
#endif /* !CONFIG_MMU */
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
#endif
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init(void);
......
......@@ -27,8 +27,6 @@
#define CCN_CVR 0xff000040
#define CCN_PRR 0xff000044
const char *get_cpu_subtype(void);
/*
* CPU type and hardware bug flags. Kept separately for each CPU.
*
......@@ -66,6 +64,7 @@ enum cpu_type {
struct sh_cpuinfo {
unsigned int type;
unsigned long loops_per_jiffy;
unsigned long asid_cache;
struct cache_info icache; /* Primary I-cache */
struct cache_info dcache; /* Primary D-cache */
......@@ -288,5 +287,8 @@ extern int vsyscall_init(void);
#define vsyscall_init() do { } while (0)
#endif
/* arch/sh/kernel/setup.c */
const char *get_cpu_subtype(struct sh_cpuinfo *c);
#endif /* __KERNEL__ */
#endif /* __ASM_SH_PROCESSOR_H */
......@@ -68,6 +68,10 @@
#define IRQ_PCISLOT2 10 /* PCI Slot #2 IRQ */
#define IRQ_EXTENTION 11 /* EXTn IRQ */
/* arch/sh/boards/renesas/rts7751r2d/irq.c */
void init_rts7751r2d_IRQ(void);
int rts7751r2d_irq_demux(int);
#define __IO_PREFIX rts7751r2d
#include <asm/io_generic.h>
......
......@@ -9,11 +9,6 @@
#include <linux/kernel.h>
#ifdef CONFIG_SH_EC3104
#include <asm/serial-ec3104.h>
#elif defined (CONFIG_SH_BIGSUR)
#include <asm/serial-bigsur.h>
#else
/*
* This assumes you have a 1.8432 MHz clock for your UART.
*
......@@ -34,12 +29,8 @@
#else
#define SERIAL_PORT_DFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS } /* ttyS1 */
#define SERIAL_PORT_DFNS
#endif
#endif
#endif /* _ASM_SERIAL_H */
......@@ -32,12 +32,20 @@ struct thread_info {
#define PREEMPT_ACTIVE 0x10000000
#ifdef CONFIG_4KSTACKS
#define THREAD_SIZE (PAGE_SIZE)
#if defined(CONFIG_4KSTACKS)
#define THREAD_SIZE_ORDER (0)
#elif defined(CONFIG_PAGE_SIZE_4KB)
#define THREAD_SIZE_ORDER (1)
#elif defined(CONFIG_PAGE_SIZE_8KB)
#define THREAD_SIZE_ORDER (1)
#elif defined(CONFIG_PAGE_SIZE_64KB)
#define THREAD_SIZE_ORDER (0)
#else
#define THREAD_SIZE (PAGE_SIZE * 2)
#error "Unknown thread size"
#endif
#define STACK_WARN (THREAD_SIZE / 8)
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define STACK_WARN (THREAD_SIZE >> 3)
/*
* macros/functions for gaining access to the thread information structure
......
......@@ -4,7 +4,6 @@
/*
* TLB flushing:
*
* - flush_tlb() flushes the current mm struct TLBs
* - flush_tlb_all() flushes all processes TLBs
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
......@@ -12,20 +11,45 @@
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
extern void local_flush_tlb_all(void);
extern void local_flush_tlb_mm(struct mm_struct *mm);
extern void local_flush_tlb_range(struct vm_area_struct *vma,
unsigned long start,
unsigned long end);
extern void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long page);
extern void local_flush_tlb_kernel_range(unsigned long start,
unsigned long end);
extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
#ifdef CONFIG_SMP
extern void flush_tlb(void);
extern void flush_tlb_all(void);
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void __flush_tlb_page(unsigned long asid, unsigned long page);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void flush_tlb_one(unsigned long asid, unsigned long page);
#else
#define flush_tlb_all() local_flush_tlb_all()
#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
#define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page)
#define flush_tlb_one(asid, page) local_flush_tlb_one(asid, page)
#define flush_tlb_range(vma, start, end) \
local_flush_tlb_range(vma, start, end)
#define flush_tlb_kernel_range(start, end) \
local_flush_tlb_kernel_range(start, end)
#endif /* CONFIG_SMP */
static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{ /* Nothing to do */
{
/* Nothing to do */
}
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#endif /* __ASM_SH_TLBFLUSH_H */
......@@ -17,7 +17,7 @@
/* User Break Controller */
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
defined(CONFIG_CPU_SUBTYPE_SH7300)
#define UBC_TYPE_SH7729 (cpu_data->type == CPU_SH7729)
#define UBC_TYPE_SH7729 (current_cpu_data.type == CPU_SH7729)
#else
#define UBC_TYPE_SH7729 0
#endif
......
......@@ -292,22 +292,22 @@
#define __NR_mq_getsetattr (__NR_mq_open+5)
#define __NR_kexec_load 283
#define __NR_waitid 284
/* #define __NR_sys_setaltroot 285 */
#define __NR_add_key 286
#define __NR_request_key 287
#define __NR_keyctl 288
#define __NR_ioprio_set 289
#define __NR_ioprio_get 290
#define __NR_inotify_init 291
#define __NR_inotify_add_watch 292
#define __NR_inotify_rm_watch 293
#define __NR_add_key 285
#define __NR_request_key 286
#define __NR_keyctl 287
#define __NR_ioprio_set 288
#define __NR_ioprio_get 289
#define __NR_inotify_init 290
#define __NR_inotify_add_watch 291
#define __NR_inotify_rm_watch 292
/* 293 is unused */
#define __NR_migrate_pages 294
#define __NR_openat 295
#define __NR_mkdirat 296
#define __NR_mknodat 297
#define __NR_fchownat 298
#define __NR_futimesat 299
#define __NR_newfstatat 300
#define __NR_fstatat64 300
#define __NR_unlinkat 301
#define __NR_renameat 302
#define __NR_linkat 303
......
......@@ -308,6 +308,9 @@
#define AC97C_READ (1 << 19)
#define AC97C_WD_BIT (1 << 2)
#define AC97C_INDEX_MASK 0x7f
/* -------------------------------------------------------------------- */
/* arch/sh/cchips/voyagergx/consistent.c */
void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
#endif /* _VOYAGER_GX_REG_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