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

* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (37 commits)
  SH: catch negative denormal_subf1() retval in denormal_add()
  sh: Fix DMAC base address for SH7709S
  sh: update smc91x platform data for se7206.
  sh: Stub in cpu_to_node() and friends for NUMA build.
  sh: intc register modify fix
  sh: no high level trigger on some sh3 cpus
  sh: clean up sh7710 and sh7720 intc tables
  sh: add interrupt ack code to sh3
  sh: unify external irq pin code for sh3
  sh-sci: avoid writing to nonexistent registers
  sh-sci: sh7722 lacks scsptr registers
  sh-sci: improve sh7722 support
  sh: reset hardware from early printk
  sh: drain and wait for early printk
  sh: use sci_out() for early printk
  sh: add memory resources to /proc/iomem
  sh: add kernel bss resource
  sh: fix sh7705 interrupt vector typo
  sh: update smc91x platform data for se7722
  sh: update smc91x platform data for MigoR
  ...
This commit is contained in:
Linus Torvalds
2008-05-09 08:07:58 -07:00
63 changed files with 498 additions and 1793 deletions
+4 -13
View File
@@ -448,14 +448,6 @@ config SH_DREAMCAST
Select Dreamcast if configuring for a SEGA Dreamcast.
More information at <http://www.linux-sh.org>
config SH_MPC1211
bool "Interface MPC1211"
depends on CPU_SUBTYPE_SH7751 && BROKEN
help
CTP/PCI-SH02 is a CPU module computer that is produced
by Interface Corporation.
More information at <http://www.interface.co.jp>
config SH_SH03
bool "Interface CTP/PCI-SH03"
depends on CPU_SUBTYPE_SH7751
@@ -657,8 +649,7 @@ source "arch/sh/drivers/Kconfig"
endmenu
config ISA_DMA_API
def_bool y
depends on SH_MPC1211
bool
menu "Kernel features"
@@ -666,7 +657,7 @@ source kernel/Kconfig.hz
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
depends on EXPERIMENTAL
depends on SUPERH32 && EXPERIMENTAL
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
@@ -683,7 +674,7 @@ config KEXEC
config CRASH_DUMP
bool "kernel crash dumps (EXPERIMENTAL)"
depends on EXPERIMENTAL
depends on SUPERH32 && EXPERIMENTAL
help
Generate crash dump after being started by kexec.
This should be normally only set in special crash dump kernels
@@ -763,7 +754,7 @@ menu "Boot options"
config ZERO_PAGE_OFFSET
hex "Zero page offset"
default "0x00004000" if SH_MPC1211 || SH_SH03
default "0x00004000" if SH_SH03
default "0x00010000" if PAGE_SIZE_64KB
default "0x00002000" if PAGE_SIZE_8KB
default "0x00001000"
+1
View File
@@ -7,6 +7,7 @@ source "lib/Kconfig.debug"
config SH_STANDARD_BIOS
bool "Use LinuxSH standard BIOS"
depends on SUPERH32
help
Say Y here if your target has the gdb-sh-stub
package from www.m17n.org (or any conforming standard LinuxSH BIOS)
-1
View File
@@ -110,7 +110,6 @@ machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) += se/7343
machdir-$(CONFIG_SH_7721_SOLUTION_ENGINE) += se/7721
machdir-$(CONFIG_SH_HP6XX) += hp6xx
machdir-$(CONFIG_SH_DREAMCAST) += dreamcast
machdir-$(CONFIG_SH_MPC1211) += mpc1211
machdir-$(CONFIG_SH_SH03) += sh03
machdir-$(CONFIG_SH_SECUREEDGE5410) += snapgear
machdir-$(CONFIG_SH_RTS7751R2D) += renesas/rts7751r2d
-8
View File
@@ -1,8 +0,0 @@
#
# Makefile for the Interface (CTP/PCI/MPC-SH02) specific parts of the kernel
#
obj-y := setup.o rtc.o
obj-$(CONFIG_PCI) += pci.o
-295
View File
@@ -1,295 +0,0 @@
/*
* Low-Level PCI Support for the MPC-1211(CTP/PCI/MPC-SH02)
*
* (c) 2002-2003 Saito.K & Jeanne
*
* Dustin McIntire (dustin@sensoria.com)
* Derived from arch/i386/kernel/pci-*.c which bore the message:
* (c) 1999--2000 Martin Mares <mj@ucw.cz>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/mpc1211/pci.h>
static struct resource mpcpci_io_resource = {
"MPCPCI IO",
0x00000000,
0xffffffff,
IORESOURCE_IO
};
static struct resource mpcpci_mem_resource = {
"MPCPCI mem",
0x00000000,
0xffffffff,
IORESOURCE_MEM
};
static struct pci_ops pci_direct_conf1;
struct pci_channel board_pci_channels[] = {
{&pci_direct_conf1, &mpcpci_io_resource, &mpcpci_mem_resource, 0, 256},
{NULL, NULL, NULL, 0, 0},
};
/*
* Direct access to PCI hardware...
*/
#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
/*
* Functions for accessing PCI configuration space with type 1 accesses
*/
static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{
u32 word;
unsigned long flags;
/*
* PCIPDR may only be accessed as 32 bit words,
* so we must do byte alignment by hand
*/
local_irq_save(flags);
writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
word = readl(PCIPDR);
local_irq_restore(flags);
switch (size) {
case 1:
switch (where & 0x3) {
case 3:
*value = (u8)(word >> 24);
break;
case 2:
*value = (u8)(word >> 16);
break;
case 1:
*value = (u8)(word >> 8);
break;
default:
*value = (u8)word;
break;
}
break;
case 2:
switch (where & 0x3) {
case 3:
*value = (u16)(word >> 24);
local_irq_save(flags);
writel(CONFIG_CMD(bus,devfn,(where+1)), PCIPAR);
word = readl(PCIPDR);
local_irq_restore(flags);
*value |= ((word & 0xff) << 8);
break;
case 2:
*value = (u16)(word >> 16);
break;
case 1:
*value = (u16)(word >> 8);
break;
default:
*value = (u16)word;
break;
}
break;
case 4:
*value = word;
break;
}
PCIDBG(4,"pci_conf1_read@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),*value);
return PCIBIOS_SUCCESSFUL;
}
/*
* Since MPC-1211 only does 32bit access we'll have to do a read,mask,write operation.
* We'll allow an odd byte offset, though it should be illegal.
*/
static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{
u32 word,mask = 0;
unsigned long flags;
u32 shift = (where & 3) * 8;
if(size == 1) {
mask = ((1 << 8) - 1) << shift; // create the byte mask
} else if(size == 2){
if(shift == 24)
return PCIBIOS_BAD_REGISTER_NUMBER;
mask = ((1 << 16) - 1) << shift; // create the word mask
}
local_irq_save(flags);
writel(CONFIG_CMD(bus,devfn,where), PCIPAR);
if(size == 4){
writel(value, PCIPDR);
local_irq_restore(flags);
PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),value);
return PCIBIOS_SUCCESSFUL;
}
word = readl(PCIPDR);
word &= ~mask;
word |= ((value << shift) & mask);
writel(word, PCIPDR);
local_irq_restore(flags);
PCIDBG(4,"pci_conf1_write@0x%08x=0x%x\n", CONFIG_CMD(bus,devfn,where),word);
return PCIBIOS_SUCCESSFUL;
}
#undef CONFIG_CMD
static struct pci_ops pci_direct_conf1 = {
.read = pci_conf1_read,
.write = pci_conf1_write,
};
static void __devinit quirk_ali_ide_ports(struct pci_dev *dev)
{
dev->resource[0].start = 0x1f0;
dev->resource[0].end = 0x1f7;
dev->resource[0].flags = IORESOURCE_IO;
dev->resource[1].start = 0x3f6;
dev->resource[1].end = 0x3f6;
dev->resource[1].flags = IORESOURCE_IO;
dev->resource[2].start = 0x170;
dev->resource[2].end = 0x177;
dev->resource[2].flags = IORESOURCE_IO;
dev->resource[3].start = 0x376;
dev->resource[3].end = 0x376;
dev->resource[3].flags = IORESOURCE_IO;
dev->resource[4].start = 0xf000;
dev->resource[4].end = 0xf00f;
dev->resource[4].flags = IORESOURCE_IO;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_ports);
char * __devinit pcibios_setup(char *str)
{
return str;
}
/*
* Called after each bus is probed, but before its children
* are examined.
*/
void __devinit pcibios_fixup_bus(struct pci_bus *b)
{
pci_read_bridge_bases(b);
}
/*
* IRQ functions
*/
static inline u8 bridge_swizzle(u8 pin, u8 slot)
{
return (((pin-1) + slot) % 4) + 1;
}
static inline u8 bridge_swizzle_pci_1(u8 pin, u8 slot)
{
return (((pin-1) - slot) & 3) + 1;
}
static u8 __init mpc1211_swizzle(struct pci_dev *dev, u8 *pinp)
{
unsigned long flags;
u8 pin = *pinp;
u32 word;
for ( ; dev->bus->self; dev = dev->bus->self) {
if (!pin)
continue;
if (dev->bus->number == 1) {
local_irq_save(flags);
writel(0x80000000 | 0x2c, PCIPAR);
word = readl(PCIPDR);
local_irq_restore(flags);
word >>= 16;
if (word == 0x0001)
pin = bridge_swizzle_pci_1(pin, PCI_SLOT(dev->devfn));
else
pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
} else
pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
}
*pinp = pin;
return PCI_SLOT(dev->devfn);
}
static int __init map_mpc1211_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
int irq = -1;
/* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
if (dev->bus->number == 0) {
switch (slot) {
case 13: irq = 9; break; /* USB */
case 22: irq = 10; break; /* LAN */
default: irq = 0; break;
}
} else {
switch (pin) {
case 0: irq = 0; break;
case 1: irq = 7; break;
case 2: irq = 9; break;
case 3: irq = 10; break;
case 4: irq = 11; break;
}
}
if( irq < 0 ) {
PCIDBG(3, "PCI: Error mapping IRQ on device %s\n", pci_name(dev));
return irq;
}
PCIDBG(2, "Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
return irq;
}
void __init pcibios_fixup_irqs(void)
{
pci_fixup_irqs(mpc1211_swizzle, map_mpc1211_irq);
}
void pcibios_align_resource(void *data, struct resource *res,
resource_size_t size, resource_size_t align)
{
resource_size_t start = res->start;
if (res->flags & IORESOURCE_IO) {
if (start >= 0x10000UL) {
if ((start & 0xffffUL) < 0x4000UL) {
start = (start & 0xffff0000UL) + 0x4000UL;
} else if ((start & 0xffffUL) >= 0xf000UL) {
start = (start & 0xffff0000UL) + 0x10000UL;
}
res->start = start;
} else {
if (start & 0x300) {
start = (start + 0x3ff) & ~0x3ff;
res->start = start;
}
}
}
}
-136
View File
@@ -1,136 +0,0 @@
/*
* linux/arch/sh/kernel/rtc-mpc1211.c -- MPC-1211 on-chip RTC support
*
* Copyright (C) 2002 Saito.K & Jeanne
*
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/bcd.h>
#include <linux/mc146818rtc.h>
unsigned long get_cmos_time(void)
{
unsigned int year, mon, day, hour, min, sec;
spin_lock(&rtc_lock);
do {
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
hour = CMOS_READ(RTC_HOURS);
day = CMOS_READ(RTC_DAY_OF_MONTH);
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
} while (sec != CMOS_READ(RTC_SECONDS));
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hour);
BCD_TO_BIN(day);
BCD_TO_BIN(mon);
BCD_TO_BIN(year);
}
spin_unlock(&rtc_lock);
year += 1900;
if (year < 1970)
year += 100;
return mktime(year, mon, day, hour, min, sec);
}
void mpc1211_rtc_gettimeofday(struct timeval *tv)
{
tv->tv_sec = get_cmos_time();
tv->tv_usec = 0;
}
/* arc/i386/kernel/time.c */
/*
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
* called 500 ms after the second nowtime has started, because when
* nowtime is written into the registers of the CMOS clock, it will
* jump to the next second precisely 500 ms later. Check the Motorola
* MC146818A or Dallas DS12887 data sheet for details.
*
* BUG: This routine does not handle hour overflow properly; it just
* sets the minutes. Usually you'll only notice that after reboot!
*/
static int set_rtc_mmss(unsigned long nowtime)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
/* gets recalled with irq locally disabled */
spin_lock(&rtc_lock);
save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
cmos_minutes = CMOS_READ(RTC_MINUTES);
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
BCD_TO_BIN(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
* don't interfere with hour overflow. This avoids
* messing with unknown time zones but requires your
* RTC not to be off by more than 15 minutes
*/
real_seconds = nowtime % 60;
real_minutes = nowtime / 60;
if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
real_minutes += 30; /* correct for half hour time zone */
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
BIN_TO_BCD(real_seconds);
BIN_TO_BCD(real_minutes);
}
CMOS_WRITE(real_seconds,RTC_SECONDS);
CMOS_WRITE(real_minutes,RTC_MINUTES);
} else {
printk(KERN_WARNING
"set_rtc_mmss: can't update from %d to %d\n",
cmos_minutes, real_minutes);
retval = -1;
}
/* The following flags have to be released exactly in this order,
* otherwise the DS12887 (popular MC146818A clone with integrated
* battery and quartz) will not reset the oscillator and will not
* update precisely 500 ms later. You won't find this mentioned in
* the Dallas Semiconductor data sheets, but who believes data
* sheets anyway ... -- Markus Kuhn
*/
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
spin_unlock(&rtc_lock);
return retval;
}
int mpc1211_rtc_settimeofday(const struct timeval *tv)
{
unsigned long nowtime = tv->tv_sec;
return set_rtc_mmss(nowtime);
}
void mpc1211_time_init(void)
{
rtc_sh_get_time = mpc1211_rtc_gettimeofday;
rtc_sh_set_time = mpc1211_rtc_settimeofday;
}
-347
View File
@@ -1,347 +0,0 @@
/*
* linux/arch/sh/boards/mpc1211/setup.c
*
* Copyright (C) 2002 Saito.K & Jeanne, Fujii.Y
*
*/
#include <linux/init.h>
#include <linux/irq.h>
#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>
#include <asm/mpc1211/pci.h>
#include <asm/mpc1211/m1543c.h>
/* ALI15X3 SMBus address offsets */
#define SMBHSTSTS (0 + 0x3100)
#define SMBHSTCNT (1 + 0x3100)
#define SMBHSTSTART (2 + 0x3100)
#define SMBHSTCMD (7 + 0x3100)
#define SMBHSTADD (3 + 0x3100)
#define SMBHSTDAT0 (4 + 0x3100)
#define SMBHSTDAT1 (5 + 0x3100)
#define SMBBLKDAT (6 + 0x3100)
/* Other settings */
#define MAX_TIMEOUT 500 /* times 1/100 sec */
/* ALI15X3 command constants */
#define ALI15X3_ABORT 0x04
#define ALI15X3_T_OUT 0x08
#define ALI15X3_QUICK 0x00
#define ALI15X3_BYTE 0x10
#define ALI15X3_BYTE_DATA 0x20
#define ALI15X3_WORD_DATA 0x30
#define ALI15X3_BLOCK_DATA 0x40
#define ALI15X3_BLOCK_CLR 0x80
/* ALI15X3 status register bits */
#define ALI15X3_STS_IDLE 0x04
#define ALI15X3_STS_BUSY 0x08
#define ALI15X3_STS_DONE 0x10
#define ALI15X3_STS_DEV 0x20 /* device error */
#define ALI15X3_STS_COLL 0x40 /* collision or no response */
#define ALI15X3_STS_TERM 0x80 /* terminated by abort */
#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */
static void __init pci_write_config(unsigned long busNo,
unsigned long devNo,
unsigned long fncNo,
unsigned long cnfAdd,
unsigned long cnfData)
{
ctrl_outl((0x80000000
+ ((busNo & 0xff) << 16)
+ ((devNo & 0x1f) << 11)
+ ((fncNo & 0x07) << 8)
+ (cnfAdd & 0xfc)), PCIPAR);
ctrl_outl(cnfData, PCIPDR);
}
/*
Initialize IRQ setting
*/
static unsigned char m_irq_mask = 0xfb;
static unsigned char s_irq_mask = 0xff;
static void disable_mpc1211_irq(unsigned int irq)
{
if( irq < 8) {
m_irq_mask |= (1 << irq);
outb(m_irq_mask,I8259_M_MR);
} else {
s_irq_mask |= (1 << (irq - 8));
outb(s_irq_mask,I8259_S_MR);
}
}
static void enable_mpc1211_irq(unsigned int irq)
{
if( irq < 8) {
m_irq_mask &= ~(1 << irq);
outb(m_irq_mask,I8259_M_MR);
} else {
s_irq_mask &= ~(1 << (irq - 8));
outb(s_irq_mask,I8259_S_MR);
}
}
static inline int mpc1211_irq_real(unsigned int irq)
{
int value;
int irqmask;
if ( irq < 8) {
irqmask = 1<<irq;
outb(0x0b,I8259_M_CR); /* ISR register */
value = inb(I8259_M_CR) & irqmask;
outb(0x0a,I8259_M_CR); /* back ro the IPR reg */
return value;
}
irqmask = 1<<(irq - 8);
outb(0x0b,I8259_S_CR); /* ISR register */
value = inb(I8259_S_CR) & irqmask;
outb(0x0a,I8259_S_CR); /* back ro the IPR reg */
return value;
}
static void mask_and_ack_mpc1211(unsigned int irq)
{
if(irq < 8) {
if(m_irq_mask & (1<<irq)){
if(!mpc1211_irq_real(irq)){
atomic_inc(&irq_err_count)
printk("spurious 8259A interrupt: IRQ %x\n",irq);
}
} else {
m_irq_mask |= (1<<irq);
}
inb(I8259_M_MR); /* DUMMY */
outb(m_irq_mask,I8259_M_MR); /* disable */
outb(0x60+irq,I8259_M_CR); /* EOI */
} else {
if(s_irq_mask & (1<<(irq - 8))){
if(!mpc1211_irq_real(irq)){
atomic_inc(&irq_err_count);
printk("spurious 8259A interrupt: IRQ %x\n",irq);
}
} else {
s_irq_mask |= (1<<(irq - 8));
}
inb(I8259_S_MR); /* DUMMY */
outb(s_irq_mask,I8259_S_MR); /* disable */
outb(0x60+(irq-8),I8259_S_CR); /* EOI */
outb(0x60+2,I8259_M_CR);
}
}
static void end_mpc1211_irq(unsigned int irq)
{
enable_mpc1211_irq(irq);
}
static unsigned int startup_mpc1211_irq(unsigned int irq)
{
enable_mpc1211_irq(irq);
return 0;
}
static void shutdown_mpc1211_irq(unsigned int irq)
{
disable_mpc1211_irq(irq);
}
static struct hw_interrupt_type mpc1211_irq_type = {
.typename = "MPC1211-IRQ",
.startup = startup_mpc1211_irq,
.shutdown = shutdown_mpc1211_irq,
.enable = enable_mpc1211_irq,
.disable = disable_mpc1211_irq,
.ack = mask_and_ack_mpc1211,
.end = end_mpc1211_irq
};
static void make_mpc1211_irq(unsigned int irq)
{
irq_desc[irq].chip = &mpc1211_irq_type;
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = 0;
irq_desc[irq].depth = 1;
disable_mpc1211_irq(irq);
}
int mpc1211_irq_demux(int irq)
{
unsigned int poll;
if( irq == 2 ) {
outb(0x0c,I8259_M_CR);
poll = inb(I8259_M_CR);
if(poll & 0x80) {
irq = (poll & 0x07);
}
if( irq == 2) {
outb(0x0c,I8259_S_CR);
poll = inb(I8259_S_CR);
irq = (poll & 0x07) + 8;
}
}
return irq;
}
static void __init init_mpc1211_IRQ(void)
{
int i;
/*
* Super I/O (Just mimic PC):
* 1: keyboard
* 3: serial 1
* 4: serial 0
* 5: printer
* 6: floppy
* 8: rtc
* 10: lan
* 12: mouse
* 14: ide0
* 15: ide1
*/
pci_write_config(0,0,0,0x54, 0xb0b0002d);
outb(0x11, I8259_M_CR); /* mater icw1 edge trigger */
outb(0x11, I8259_S_CR); /* slave icw1 edge trigger */
outb(0x20, I8259_M_MR); /* m icw2 base vec 0x08 */
outb(0x28, I8259_S_MR); /* s icw2 base vec 0x70 */
outb(0x04, I8259_M_MR); /* m icw3 slave irq2 */
outb(0x02, I8259_S_MR); /* s icw3 slave id */
outb(0x01, I8259_M_MR); /* m icw4 non buf normal eoi*/
outb(0x01, I8259_S_MR); /* s icw4 non buf normal eo1*/
outb(0xfb, I8259_M_MR); /* disable irq0--irq7 */
outb(0xff, I8259_S_MR); /* disable irq8--irq15 */
for ( i=0; i < 16; i++) {
if(i != 2) {
make_mpc1211_irq(i);
}
}
}
static void delay1000(void)
{
int i;
for (i=0; i<1000; i++)
ctrl_delay();
}
static int put_smb_blk(unsigned char *p, int address, int command, int no)
{
int temp;
int timeout;
int i;
outb(0xff, SMBHSTSTS);
temp = inb(SMBHSTSTS);
for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE); timeout++) {
delay1000();
temp = inb(SMBHSTSTS);
}
if (timeout >= MAX_TIMEOUT){
return -1;
}
outb(((address & 0x7f) << 1), SMBHSTADD);
outb(0xc0, SMBHSTCNT);
outb(command & 0xff, SMBHSTCMD);
outb(no & 0x1f, SMBHSTDAT0);
for(i = 1; i <= no; i++) {
outb(*p++, SMBBLKDAT);
}
outb(0xff, SMBHSTSTART);
temp = inb(SMBHSTSTS);
for (timeout = 0; (timeout < MAX_TIMEOUT) && !(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)); timeout++) {
delay1000();
temp = inb(SMBHSTSTS);
}
if (timeout >= MAX_TIMEOUT) {
return -2;
}
if ( temp & ALI15X3_STS_ERR ){
return -3;
}
return 0;
}
static struct resource heartbeat_resources[] = {
[0] = {
.start = 0xa2000000,
.end = 0xa2000000,
.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);
static void __init mpc1211_setup(char **cmdline_p)
{
unsigned char spd_buf[128];
__set_io_port_base(PA_PCI_IO);
pci_write_config(0,0,0,0x54, 0xb0b00000);
do {
outb(ALI15X3_ABORT, SMBHSTCNT);
spd_buf[0] = 0x0c;
spd_buf[1] = 0x43;
spd_buf[2] = 0x7f;
spd_buf[3] = 0x03;
spd_buf[4] = 0x00;
spd_buf[5] = 0x03;
spd_buf[6] = 0x00;
} while (put_smb_blk(spd_buf, 0x69, 0, 7) < 0);
board_time_init = mpc1211_time_init;
return 0;
}
/*
* The Machine Vector
*/
static struct sh_machine_vector mv_mpc1211 __initmv = {
.mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)",
.mv_setup = mpc1211_setup,
.mv_nr_irqs = 48,
.mv_irq_demux = mpc1211_irq_demux,
.mv_init_irq = init_mpc1211_IRQ,
};
+10 -1
View File
@@ -14,6 +14,7 @@
#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
#include <linux/i2c.h>
#include <linux/smc91x.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/sh_keysc.h>
@@ -27,6 +28,11 @@
* 0x18000000 8GB 8 NAND Flash (K9K8G08U0A)
*/
static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT,
.irq_flags = IRQF_TRIGGER_HIGH,
};
static struct resource smc91x_eth_resources[] = {
[0] = {
.name = "SMC91C111" ,
@@ -36,7 +42,7 @@ static struct resource smc91x_eth_resources[] = {
},
[1] = {
.start = 32, /* IRQ0 */
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
.flags = IORESOURCE_IRQ,
},
};
@@ -44,6 +50,9 @@ static struct platform_device smc91x_eth_device = {
.name = "smc91x",
.num_resources = ARRAY_SIZE(smc91x_eth_resources),
.resource = smc91x_eth_resources,
.dev = {
.platform_data = &smc91x_info,
},
};
static struct sh_keysc_info sh_keysc_info = {
+1 -1
View File
@@ -62,7 +62,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors,
NULL, mask_registers, NULL, NULL);
unsigned char * __init highlander_init_irq_r7780mp(void)
unsigned char * __init highlander_plat_irq_setup(void)
{
if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) {
printk(KERN_INFO "Using r7780mp interrupt controller.\n");
+1 -1
View File
@@ -55,7 +55,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors,
NULL, mask_registers, NULL, NULL);
unsigned char * __init highlander_init_irq_r7780rp(void)
unsigned char * __init highlander_plat_irq_setup(void)
{
if (ctrl_inw(0xa5000600)) {
printk(KERN_INFO "Using r7780rp interrupt controller.\n");
+1 -1
View File
@@ -64,7 +64,7 @@ static unsigned char irl2irq[HL_NR_IRL] __initdata = {
static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors,
NULL, mask_registers, NULL, NULL);
unsigned char * __init highlander_init_irq_r7785rp(void)
unsigned char * __init highlander_plat_irq_setup(void)
{
if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000)
return NULL;
+3 -21
View File
@@ -316,7 +316,7 @@ static void __init highlander_setup(char **cmdline_p)
static unsigned char irl2irq[HL_NR_IRL];
int highlander_irq_demux(int irq)
static int highlander_irq_demux(int irq)
{
if (irq >= HL_NR_IRL || !irl2irq[irq])
return irq;
@@ -324,27 +324,9 @@ int highlander_irq_demux(int irq)
return irl2irq[irq];
}
void __init highlander_init_irq(void)
static void __init highlander_init_irq(void)
{
unsigned char *ucp = NULL;
do {
#ifdef CONFIG_SH_R7780MP
ucp = highlander_init_irq_r7780mp();
if (ucp)
break;
#endif
#ifdef CONFIG_SH_R7785RP
ucp = highlander_init_irq_r7785rp();
if (ucp)
break;
#endif
#ifdef CONFIG_SH_R7780RP
ucp = highlander_init_irq_r7780rp();
if (ucp)
break;
#endif
} while (0);
unsigned char *ucp = highlander_plat_irq_setup();
if (ucp) {
plat_irq_setup_pins(IRQ_MODE_IRL3210);
+2 -5
View File
@@ -109,7 +109,6 @@ static struct platform_device heartbeat_device = {
.resource = heartbeat_resources,
};
#ifdef CONFIG_MFD_SM501
static struct plat_serial8250_port uart_platform_data[] = {
{
.membase = (void __iomem *)0xb3e30000,
@@ -208,13 +207,9 @@ static struct platform_device sm501_device = {
.resource = sm501_resources,
};
#endif /* CONFIG_MFD_SM501 */
static struct platform_device *rts7751r2d_devices[] __initdata = {
#ifdef CONFIG_MFD_SM501
&uart_device,
&sm501_device,
#endif
&heartbeat_device,
&spi_sh_sci_device,
};
@@ -234,7 +229,9 @@ static int __init rts7751r2d_devices_setup(void)
{
if (register_trapped_io(&cf_trapped_io) == 0)
platform_device_register(&cf_ide_device);
spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
return platform_add_devices(rts7751r2d_devices,
ARRAY_SIZE(rts7751r2d_devices));
}
+14 -3
View File
@@ -3,12 +3,13 @@
* linux/arch/sh/boards/se/7206/setup.c
*
* Copyright (C) 2006 Yoshinori Sato
* Copyright (C) 2007 Paul Mundt
* Copyright (C) 2007 - 2008 Paul Mundt
*
* Hitachi 7206 SolutionEngine Support.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/smc91x.h>
#include <asm/se7206.h>
#include <asm/io.h>
#include <asm/machvec.h>
@@ -16,8 +17,9 @@
static struct resource smc91x_resources[] = {
[0] = {
.start = 0x300,
.end = 0x300 + 0x020 - 1,
.name = "smc91x-regs",
.start = PA_SMSC + 0x300,
.end = PA_SMSC + 0x300 + 0x020 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -27,9 +29,18 @@ static struct resource smc91x_resources[] = {
},
};
static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
.dev = {
.dma_mask = NULL,
.coherent_dma_mask = 0xffffffff,
.platform_data = &smc91x_info,
},
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
};
+6
View File
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/input.h>
#include <linux/smc91x.h>
#include <asm/machvec.h>
#include <asm/se7722.h>
#include <asm/io.h>
@@ -44,6 +45,10 @@ static struct platform_device heartbeat_device = {
};
/* SMC91x */
static struct smc91x_platdata smc91x_info = {
.flags = SMC91X_USE_16BIT,
};
static struct resource smc91x_eth_resources[] = {
[0] = {
.name = "smc91x-regs" ,
@@ -64,6 +69,7 @@ static struct platform_device smc91x_eth_device = {
.dev = {
.dma_mask = NULL, /* don't use dma */
.coherent_dma_mask = 0xffffffff,
.platform_data = &smc91x_info,
},
.num_resources = ARRAY_SIZE(smc91x_eth_resources),
.resource = smc91x_eth_resources,
-1
View File
@@ -6,7 +6,6 @@
targets := vmlinux vmlinux.bin vmlinux.bin.gz \
head_32.o misc_32.o piggy.o
EXTRA_AFLAGS := -traditional
OBJECTS = $(obj)/head_32.o $(obj)/misc_32.o
-1
View File
@@ -13,7 +13,6 @@
targets := vmlinux vmlinux.bin vmlinux.bin.gz \
head_64.o misc_64.o cache.o piggy.o
EXTRA_AFLAGS := -traditional
OBJECTS := $(obj)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o \
$(obj)/cache.o
+37 -34
View File
@@ -184,9 +184,8 @@ int intc_irq_describe(char* p, int irq)
void __init plat_irq_setup(void)
{
unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
unsigned long reg;
unsigned long data;
int i;
intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
@@ -196,11 +195,8 @@ void __init plat_irq_setup(void)
/* Set default: per-line enable/disable, priority driven ack/eoi */
for (i = 0; i < NR_INTC_IRQS; i++) {
if (platform_int_priority[i] != NO_PRIORITY) {
irq_desc[i].chip = &intc_irq_type;
}
}
for (i = 0; i < NR_INTC_IRQS; i++)
irq_desc[i].chip = &intc_irq_type;
/* Disable all interrupts and set all priorities to 0 to avoid trouble */
@@ -211,35 +207,42 @@ void __init plat_irq_setup(void)
ctrl_outl( NO_PRIORITY, reg);
/* Set IRLM */
/* If all the priorities are set to 'no priority', then
* assume we are using encoded mode.
*/
irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];
#ifdef CONFIG_SH_CAYMAN
{
unsigned long data;
if (irlm == NO_PRIORITY) {
/* IRLM = 0 */
reg = INTC_ICR_CLEAR;
i = IRQ_INTA;
printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
} else {
/* IRLM = 1 */
reg = INTC_ICR_SET;
i = IRQ_IRL0;
}
ctrl_outl(INTC_ICR_IRLM, reg);
/* Set interrupt priorities according to platform description */
for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
/* Upon the 7th, set Priority Register */
ctrl_outl(data, reg);
data = 0;
reg += 8;
/* Set IRLM */
/* If all the priorities are set to 'no priority', then
* assume we are using encoded mode.
*/
irlm = platform_int_priority[IRQ_IRL0] +
platform_int_priority[IRQ_IRL1] +
platform_int_priority[IRQ_IRL2] +
platform_int_priority[IRQ_IRL3];
if (irlm == NO_PRIORITY) {
/* IRLM = 0 */
reg = INTC_ICR_CLEAR;
i = IRQ_INTA;
printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
} else {
/* IRLM = 1 */
reg = INTC_ICR_SET;
i = IRQ_IRL0;
}
}
ctrl_outl(INTC_ICR_IRLM, reg);
/* Set interrupt priorities according to platform description */
for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
data |= platform_int_priority[i] <<
((i % INTC_INTPRI_PPREG) * 4);
if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
/* Upon the 7th, set Priority Register */
ctrl_outl(data, reg);
data = 0;
reg += 8;
}
}
#endif
/*
* And now let interrupts come in.
+90 -3
View File
@@ -1,7 +1,7 @@
/*
* Shared interrupt handling code for IPR and INTC2 types of IRQs.
*
* Copyright (C) 2007 Magnus Damm
* Copyright (C) 2007, 2008 Magnus Damm
*
* Based on intc2.c and ipr.c
*
@@ -62,6 +62,9 @@ struct intc_desc_int {
#endif
static unsigned int intc_prio_level[NR_IRQS]; /* for now */
#ifdef CONFIG_CPU_SH3
static unsigned long ack_handle[NR_IRQS];
#endif
static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
{
@@ -98,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data)
static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
{
unsigned long flags;
local_irq_save(flags);
ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
local_irq_restore(flags);
}
static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
{
unsigned long flags;
local_irq_save(flags);
ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
local_irq_restore(flags);
}
static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
{
unsigned long flags;
local_irq_save(flags);
ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
local_irq_restore(flags);
}
enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
@@ -219,6 +231,25 @@ static void intc_disable(unsigned int irq)
}
}
#ifdef CONFIG_CPU_SH3
static void intc_mask_ack(unsigned int irq)
{
struct intc_desc_int *d = get_intc_desc(irq);
unsigned long handle = ack_handle[irq];
unsigned long addr;
intc_disable(irq);
/* read register and write zero only to the assocaited bit */
if (handle) {
addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
ctrl_inb(addr);
ctrl_outb(0x3f ^ set_field(0, 1, handle), addr);
}
}
#endif
static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
unsigned int nr_hp,
unsigned int irq)
@@ -280,7 +311,12 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
[IRQ_TYPE_EDGE_FALLING] = VALID(0),
[IRQ_TYPE_EDGE_RISING] = VALID(1),
[IRQ_TYPE_LEVEL_LOW] = VALID(2),
/* SH7706, SH7707 and SH7709 do not support high level triggered */
#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \
!defined(CONFIG_CPU_SUBTYPE_SH7707) && \
!defined(CONFIG_CPU_SUBTYPE_SH7709)
[IRQ_TYPE_LEVEL_HIGH] = VALID(3),
#endif
};
static int intc_set_sense(unsigned int irq, unsigned int type)
@@ -430,6 +466,40 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
return 0;
}
#ifdef CONFIG_CPU_SH3
static unsigned int __init intc_ack_data(struct intc_desc *desc,
struct intc_desc_int *d,
intc_enum enum_id)
{
struct intc_mask_reg *mr = desc->ack_regs;
unsigned int i, j, fn, mode;
unsigned long reg_e, reg_d;
for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) {
mr = desc->ack_regs + i;
for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
if (mr->enum_ids[j] != enum_id)
continue;
fn = REG_FN_MODIFY_BASE;
mode = MODE_ENABLE_REG;
reg_e = mr->set_reg;
reg_d = mr->set_reg;
fn += (mr->reg_width >> 3) - 1;
return _INTC_MK(fn, mode,
intc_get_reg(d, reg_e),
intc_get_reg(d, reg_d),
1,
(mr->reg_width - 1) - j);
}
}
return 0;
}
#endif
static unsigned int __init intc_sense_data(struct intc_desc *desc,
struct intc_desc_int *d,
intc_enum enum_id)
@@ -530,6 +600,11 @@ static void __init intc_register_irq(struct intc_desc *desc,
/* irq should be disabled by default */
d->chip.mask(irq);
#ifdef CONFIG_CPU_SH3
if (desc->ack_regs)
ack_handle[irq] = intc_ack_data(desc, d, enum_id);
#endif
}
static unsigned int __init save_reg(struct intc_desc_int *d,
@@ -560,6 +635,9 @@ void __init register_intc_controller(struct intc_desc *desc)
d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
#ifdef CONFIG_CPU_SH3
d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0;
#endif
d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
#ifdef CONFIG_SMP
d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
@@ -592,14 +670,23 @@ void __init register_intc_controller(struct intc_desc *desc)
}
}
BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
d->chip.name = desc->name;
d->chip.mask = intc_disable;
d->chip.unmask = intc_enable;
d->chip.mask_ack = intc_disable;
d->chip.set_type = intc_set_sense;
#ifdef CONFIG_CPU_SH3
if (desc->ack_regs) {
for (i = 0; i < desc->nr_ack_regs; i++)
k += save_reg(d, k, desc->ack_regs[i].set_reg, 0);
d->chip.mask_ack = intc_mask_ack;
}
#endif
BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
for (i = 0; i < desc->nr_vectors; i++) {
struct intc_vect *vect = desc->vectors + i;
+2 -2
View File
@@ -300,7 +300,7 @@ static int denormal_addf(int hx, int hy)
iy = hy & 0x7fffffff;
if (iy < 0x00800000) {
ix = denormal_subf1(ix, iy);
if (ix < 0) {
if ((int) ix < 0) {
ix = -ix;
sign ^= 0x80000000;
}
@@ -385,7 +385,7 @@ static long long denormal_addd(long long hx, long long hy)
iy = hy & 0x7fffffffffffffffLL;
if (iy < 0x0010000000000000LL) {
ix = denormal_subd1(ix, iy);
if (ix < 0) {
if ((int) ix < 0) {
ix = -ix;
sign ^= 0x8000000000000000LL;
}

Some files were not shown because too many files have changed in this diff Show More