mirror of
https://github.com/suyu-emu/horinux.git
synced 2026-09-21 14:15:21 -07:00
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:
+4
-13
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user