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: (124 commits) sh: allow building for both r2d boards in same binary. sh: fix r2d board detection sh: Discard .exit.text/.exit.data at runtime. sh: Fix up some section alignments in linker script. sh: Fix SH-4 DMAC CHCR masking. sh: Rip out left-over nommu cond syscall cruft. sh: Make kgdb i-cache flushing less inept. sh: kgdb section mismatches and tidying. sh: cleanup struct irqaction initializers. sh: early_printk tidying. video: pvr2fb: Add TV (RGB) support to Dreamcast PVR driver. sh: Conditionalize gUSA support. sh: Follow gUSA preempt changes in __switch_to(). sh: Tidy up gUSA preempt handling. sh: __copy_user() optimizations for small copies. sh: clkfwk: Support multi-level clock propagation. sh: Fix URAM start address on SH7785. sh: Use boot_cpu_data for CPU probe. sh: Support extended mode TLB on SH-X3. sh: Bump MAX_ACTIVE_REGIONS for SH7785. ...
This commit is contained in:
@@ -83,6 +83,8 @@ static void propagate_rate(struct clk *clk)
|
||||
continue;
|
||||
if (likely(clkp->ops && clkp->ops->recalc))
|
||||
clkp->ops->recalc(clkp);
|
||||
if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
|
||||
propagate_rate(clkp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ubc.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
/*
|
||||
* Generic wrapper for command line arguments to disable on-chip
|
||||
@@ -143,12 +144,15 @@ static void __init cache_init(void)
|
||||
flags &= ~CCR_CACHE_EMODE;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SH_WRITETHROUGH
|
||||
/* Turn on Write-through caching */
|
||||
#if defined(CONFIG_CACHE_WRITETHROUGH)
|
||||
/* Write-through */
|
||||
flags |= CCR_CACHE_WT;
|
||||
#else
|
||||
/* .. or default to Write-back */
|
||||
#elif defined(CONFIG_CACHE_WRITEBACK)
|
||||
/* Write-back */
|
||||
flags |= CCR_CACHE_CB;
|
||||
#else
|
||||
/* Off */
|
||||
flags &= ~CCR_CACHE_ENABLE;
|
||||
#endif
|
||||
|
||||
ctrl_outl(flags, CCR);
|
||||
@@ -213,8 +217,11 @@ static void __init dsp_init(void)
|
||||
* Each processor family is still responsible for doing its own probing
|
||||
* and cache configuration in detect_cpu_and_cache_system().
|
||||
*/
|
||||
asmlinkage void __init sh_cpu_init(void)
|
||||
|
||||
asmlinkage void __cpuinit sh_cpu_init(void)
|
||||
{
|
||||
current_thread_info()->cpu = hard_smp_processor_id();
|
||||
|
||||
/* First, probe the CPU */
|
||||
detect_cpu_and_cache_system();
|
||||
|
||||
@@ -224,9 +231,10 @@ asmlinkage void __init sh_cpu_init(void)
|
||||
/* Init the cache */
|
||||
cache_init();
|
||||
|
||||
shm_align_mask = max_t(unsigned long,
|
||||
current_cpu_data.dcache.way_size - 1,
|
||||
PAGE_SIZE - 1);
|
||||
if (raw_smp_processor_id() == 0)
|
||||
shm_align_mask = max_t(unsigned long,
|
||||
current_cpu_data.dcache.way_size - 1,
|
||||
PAGE_SIZE - 1);
|
||||
|
||||
/* Disable the FPU */
|
||||
if (fpu_disabled) {
|
||||
@@ -265,6 +273,7 @@ asmlinkage void __init sh_cpu_init(void)
|
||||
* like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So ..
|
||||
* we wake it up and hope that all is well.
|
||||
*/
|
||||
ubc_wakeup();
|
||||
if (raw_smp_processor_id() == 0)
|
||||
ubc_wakeup();
|
||||
speculative_execution_init();
|
||||
}
|
||||
|
@@ -1,9 +1,7 @@
|
||||
#
|
||||
# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
|
||||
#
|
||||
obj-y += imask.o
|
||||
obj-y += imask.o intc.o
|
||||
|
||||
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
|
||||
obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
|
||||
obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o
|
||||
obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
|
||||
|
@@ -20,145 +20,258 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bootmem.h>
|
||||
|
||||
#define _INTC_MK(fn, idx, bit, value) \
|
||||
((fn) << 24 | ((value) << 16) | ((idx) << 8) | (bit))
|
||||
#define _INTC_FN(h) (h >> 24)
|
||||
#define _INTC_VALUE(h) ((h >> 16) & 0xff)
|
||||
#define _INTC_IDX(h) ((h >> 8) & 0xff)
|
||||
#define _INTC_BIT(h) (h & 0xff)
|
||||
#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
|
||||
((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
|
||||
((addr_e) << 16) | ((addr_d << 24)))
|
||||
|
||||
#define _INTC_PTR(desc, member, data) \
|
||||
(desc->member + _INTC_IDX(data))
|
||||
#define _INTC_SHIFT(h) (h & 0x1f)
|
||||
#define _INTC_WIDTH(h) ((h >> 5) & 0xf)
|
||||
#define _INTC_FN(h) ((h >> 9) & 0xf)
|
||||
#define _INTC_MODE(h) ((h >> 13) & 0x7)
|
||||
#define _INTC_ADDR_E(h) ((h >> 16) & 0xff)
|
||||
#define _INTC_ADDR_D(h) ((h >> 24) & 0xff)
|
||||
|
||||
static inline struct intc_desc *get_intc_desc(unsigned int irq)
|
||||
struct intc_handle_int {
|
||||
unsigned int irq;
|
||||
unsigned long handle;
|
||||
};
|
||||
|
||||
struct intc_desc_int {
|
||||
unsigned long *reg;
|
||||
#ifdef CONFIG_SMP
|
||||
unsigned long *smp;
|
||||
#endif
|
||||
unsigned int nr_reg;
|
||||
struct intc_handle_int *prio;
|
||||
unsigned int nr_prio;
|
||||
struct intc_handle_int *sense;
|
||||
unsigned int nr_sense;
|
||||
struct irq_chip chip;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define IS_SMP(x) x.smp
|
||||
#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
|
||||
#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1)
|
||||
#else
|
||||
#define IS_SMP(x) 0
|
||||
#define INTC_REG(d, x, c) (d->reg[(x)])
|
||||
#define SMP_NR(d, x) 1
|
||||
#endif
|
||||
|
||||
static unsigned int intc_prio_level[NR_IRQS]; /* for now */
|
||||
|
||||
static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
|
||||
{
|
||||
struct irq_chip *chip = get_irq_chip(irq);
|
||||
return (void *)((char *)chip - offsetof(struct intc_desc, chip));
|
||||
return (void *)((char *)chip - offsetof(struct intc_desc_int, chip));
|
||||
}
|
||||
|
||||
static inline unsigned int set_field(unsigned int value,
|
||||
unsigned int field_value,
|
||||
unsigned int width,
|
||||
unsigned int shift)
|
||||
unsigned int handle)
|
||||
{
|
||||
unsigned int width = _INTC_WIDTH(handle);
|
||||
unsigned int shift = _INTC_SHIFT(handle);
|
||||
|
||||
value &= ~(((1 << width) - 1) << shift);
|
||||
value |= field_value << shift;
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline unsigned int set_prio_field(struct intc_desc *desc,
|
||||
unsigned int value,
|
||||
unsigned int priority,
|
||||
unsigned int data)
|
||||
static void write_8(unsigned long addr, unsigned long h, unsigned long data)
|
||||
{
|
||||
unsigned int width = _INTC_PTR(desc, prio_regs, data)->field_width;
|
||||
|
||||
return set_field(value, priority, width, _INTC_BIT(data));
|
||||
ctrl_outb(set_field(0, data, h), addr);
|
||||
}
|
||||
|
||||
static void disable_prio_16(struct intc_desc *desc, unsigned int data)
|
||||
static void write_16(unsigned long addr, unsigned long h, unsigned long data)
|
||||
{
|
||||
unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg;
|
||||
|
||||
ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr);
|
||||
ctrl_outw(set_field(0, data, h), addr);
|
||||
}
|
||||
|
||||
static void enable_prio_16(struct intc_desc *desc, unsigned int data)
|
||||
static void write_32(unsigned long addr, unsigned long h, unsigned long data)
|
||||
{
|
||||
unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg;
|
||||
unsigned int prio = _INTC_VALUE(data);
|
||||
|
||||
ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr);
|
||||
ctrl_outl(set_field(0, data, h), addr);
|
||||
}
|
||||
|
||||
static void disable_prio_32(struct intc_desc *desc, unsigned int data)
|
||||
static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
|
||||
{
|
||||
unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg;
|
||||
|
||||
ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr);
|
||||
ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
|
||||
}
|
||||
|
||||
static void enable_prio_32(struct intc_desc *desc, unsigned int data)
|
||||
static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
|
||||
{
|
||||
unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg;
|
||||
unsigned int prio = _INTC_VALUE(data);
|
||||
|
||||
ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr);
|
||||
ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
|
||||
}
|
||||
|
||||
static void disable_mask_8(struct intc_desc *desc, unsigned int data)
|
||||
static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
|
||||
{
|
||||
ctrl_outb(1 << _INTC_BIT(data),
|
||||
_INTC_PTR(desc, mask_regs, data)->set_reg);
|
||||
ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
|
||||
}
|
||||
|
||||
static void enable_mask_8(struct intc_desc *desc, unsigned int data)
|
||||
{
|
||||
ctrl_outb(1 << _INTC_BIT(data),
|
||||
_INTC_PTR(desc, mask_regs, data)->clr_reg);
|
||||
}
|
||||
enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 };
|
||||
|
||||
static void disable_mask_32(struct intc_desc *desc, unsigned int data)
|
||||
{
|
||||
ctrl_outl(1 << _INTC_BIT(data),
|
||||
_INTC_PTR(desc, mask_regs, data)->set_reg);
|
||||
}
|
||||
|
||||
static void enable_mask_32(struct intc_desc *desc, unsigned int data)
|
||||
{
|
||||
ctrl_outl(1 << _INTC_BIT(data),
|
||||
_INTC_PTR(desc, mask_regs, data)->clr_reg);
|
||||
}
|
||||
|
||||
enum { REG_FN_ERROR=0,
|
||||
REG_FN_MASK_8, REG_FN_MASK_32,
|
||||
REG_FN_PRIO_16, REG_FN_PRIO_32 };
|
||||
|
||||
static struct {
|
||||
void (*enable)(struct intc_desc *, unsigned int);
|
||||
void (*disable)(struct intc_desc *, unsigned int);
|
||||
} intc_reg_fns[] = {
|
||||
[REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 },
|
||||
[REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 },
|
||||
[REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 },
|
||||
[REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 },
|
||||
static void (*intc_reg_fns[])(unsigned long addr,
|
||||
unsigned long h,
|
||||
unsigned long data) = {
|
||||
[REG_FN_WRITE_BASE + 0] = write_8,
|
||||
[REG_FN_WRITE_BASE + 1] = write_16,
|
||||
[REG_FN_WRITE_BASE + 3] = write_32,
|
||||
[REG_FN_MODIFY_BASE + 0] = modify_8,
|
||||
[REG_FN_MODIFY_BASE + 1] = modify_16,
|
||||
[REG_FN_MODIFY_BASE + 3] = modify_32,
|
||||
};
|
||||
|
||||
enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */
|
||||
MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */
|
||||
MODE_DUAL_REG, /* Two registers, set bit to enable / disable */
|
||||
MODE_PRIO_REG, /* Priority value written to enable interrupt */
|
||||
MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */
|
||||
};
|
||||
|
||||
static void intc_mode_field(unsigned long addr,
|
||||
unsigned long handle,
|
||||
void (*fn)(unsigned long,
|
||||
unsigned long,
|
||||
unsigned long),
|
||||
unsigned int irq)
|
||||
{
|
||||
fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1));
|
||||
}
|
||||
|
||||
static void intc_mode_zero(unsigned long addr,
|
||||
unsigned long handle,
|
||||
void (*fn)(unsigned long,
|
||||
unsigned long,
|
||||
unsigned long),
|
||||
unsigned int irq)
|
||||
{
|
||||
fn(addr, handle, 0);
|
||||
}
|
||||
|
||||
static void intc_mode_prio(unsigned long addr,
|
||||
unsigned long handle,
|
||||
void (*fn)(unsigned long,
|
||||
unsigned long,
|
||||
unsigned long),
|
||||
unsigned int irq)
|
||||
{
|
||||
fn(addr, handle, intc_prio_level[irq]);
|
||||
}
|
||||
|
||||
static void (*intc_enable_fns[])(unsigned long addr,
|
||||
unsigned long handle,
|
||||
void (*fn)(unsigned long,
|
||||
unsigned long,
|
||||
unsigned long),
|
||||
unsigned int irq) = {
|
||||
[MODE_ENABLE_REG] = intc_mode_field,
|
||||
[MODE_MASK_REG] = intc_mode_zero,
|
||||
[MODE_DUAL_REG] = intc_mode_field,
|
||||
[MODE_PRIO_REG] = intc_mode_prio,
|
||||
[MODE_PCLR_REG] = intc_mode_prio,
|
||||
};
|
||||
|
||||
static void (*intc_disable_fns[])(unsigned long addr,
|
||||
unsigned long handle,
|
||||
void (*fn)(unsigned long,
|
||||
unsigned long,
|
||||
unsigned long),
|
||||
unsigned int irq) = {
|
||||
[MODE_ENABLE_REG] = intc_mode_zero,
|
||||
[MODE_MASK_REG] = intc_mode_field,
|
||||
[MODE_DUAL_REG] = intc_mode_field,
|
||||
[MODE_PRIO_REG] = intc_mode_zero,
|
||||
[MODE_PCLR_REG] = intc_mode_field,
|
||||
};
|
||||
|
||||
static inline void _intc_enable(unsigned int irq, unsigned long handle)
|
||||
{
|
||||
struct intc_desc_int *d = get_intc_desc(irq);
|
||||
unsigned long addr;
|
||||
unsigned int cpu;
|
||||
|
||||
for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
|
||||
addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
|
||||
intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
|
||||
[_INTC_FN(handle)], irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void intc_enable(unsigned int irq)
|
||||
{
|
||||
struct intc_desc *desc = get_intc_desc(irq);
|
||||
unsigned int data = (unsigned int) get_irq_chip_data(irq);
|
||||
|
||||
intc_reg_fns[_INTC_FN(data)].enable(desc, data);
|
||||
_intc_enable(irq, (unsigned long)get_irq_chip_data(irq));
|
||||
}
|
||||
|
||||
static void intc_disable(unsigned int irq)
|
||||
{
|
||||
struct intc_desc *desc = get_intc_desc(irq);
|
||||
unsigned int data = (unsigned int) get_irq_chip_data(irq);
|
||||
struct intc_desc_int *d = get_intc_desc(irq);
|
||||
unsigned long handle = (unsigned long) get_irq_chip_data(irq);
|
||||
unsigned long addr;
|
||||
unsigned int cpu;
|
||||
|
||||
intc_reg_fns[_INTC_FN(data)].disable(desc, data);
|
||||
for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
|
||||
addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
|
||||
intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
|
||||
[_INTC_FN(handle)], irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_sense_16(struct intc_desc *desc, unsigned int data)
|
||||
static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
|
||||
unsigned int nr_hp,
|
||||
unsigned int irq)
|
||||
{
|
||||
unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg;
|
||||
unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width;
|
||||
unsigned int bit = _INTC_BIT(data);
|
||||
unsigned int value = _INTC_VALUE(data);
|
||||
int i;
|
||||
|
||||
ctrl_outw(set_field(ctrl_inw(addr), value, width, bit), addr);
|
||||
/* this doesn't scale well, but...
|
||||
*
|
||||
* this function should only be used for cerain uncommon
|
||||
* operations such as intc_set_priority() and intc_set_sense()
|
||||
* and in those rare cases performance doesn't matter that much.
|
||||
* keeping the memory footprint low is more important.
|
||||
*
|
||||
* one rather simple way to speed this up and still keep the
|
||||
* memory footprint down is to make sure the array is sorted
|
||||
* and then perform a bisect to lookup the irq.
|
||||
*/
|
||||
|
||||
for (i = 0; i < nr_hp; i++) {
|
||||
if ((hp + i)->irq != irq)
|
||||
continue;
|
||||
|
||||
return hp + i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void set_sense_32(struct intc_desc *desc, unsigned int data)
|
||||
int intc_set_priority(unsigned int irq, unsigned int prio)
|
||||
{
|
||||
unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg;
|
||||
unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width;
|
||||
unsigned int bit = _INTC_BIT(data);
|
||||
unsigned int value = _INTC_VALUE(data);
|
||||
struct intc_desc_int *d = get_intc_desc(irq);
|
||||
struct intc_handle_int *ihp;
|
||||
|
||||
ctrl_outl(set_field(ctrl_inl(addr), value, width, bit), addr);
|
||||
if (!intc_prio_level[irq] || prio <= 1)
|
||||
return -EINVAL;
|
||||
|
||||
ihp = intc_find_irq(d->prio, d->nr_prio, irq);
|
||||
if (ihp) {
|
||||
if (prio >= (1 << _INTC_WIDTH(ihp->handle)))
|
||||
return -EINVAL;
|
||||
|
||||
intc_prio_level[irq] = prio;
|
||||
|
||||
/*
|
||||
* only set secondary masking method directly
|
||||
* primary masking method is using intc_prio_level[irq]
|
||||
* priority level will be set during next enable()
|
||||
*/
|
||||
|
||||
if (_INTC_FN(ihp->handle) != REG_FN_ERR)
|
||||
_intc_enable(irq, ihp->handle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define VALID(x) (x | 0x80)
|
||||
@@ -172,79 +285,38 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
|
||||
|
||||
static int intc_set_sense(unsigned int irq, unsigned int type)
|
||||
{
|
||||
struct intc_desc *desc = get_intc_desc(irq);
|
||||
struct intc_desc_int *d = get_intc_desc(irq);
|
||||
unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK];
|
||||
unsigned int i, j, data, bit;
|
||||
intc_enum enum_id = 0;
|
||||
struct intc_handle_int *ihp;
|
||||
unsigned long addr;
|
||||
|
||||
for (i = 0; i < desc->nr_vectors; i++) {
|
||||
struct intc_vect *vect = desc->vectors + i;
|
||||
|
||||
if (evt2irq(vect->vect) != irq)
|
||||
continue;
|
||||
|
||||
enum_id = vect->enum_id;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!enum_id || !value)
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
value ^= VALID(0);
|
||||
|
||||
for (i = 0; i < desc->nr_sense_regs; i++) {
|
||||
struct intc_sense_reg *sr = desc->sense_regs + i;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
|
||||
if (sr->enum_ids[j] != enum_id)
|
||||
continue;
|
||||
|
||||
bit = sr->reg_width - ((j + 1) * sr->field_width);
|
||||
data = _INTC_MK(0, i, bit, value);
|
||||
|
||||
switch(sr->reg_width) {
|
||||
case 16:
|
||||
set_sense_16(desc, data);
|
||||
break;
|
||||
case 32:
|
||||
set_sense_32(desc, data);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
ihp = intc_find_irq(d->sense, d->nr_sense, irq);
|
||||
if (ihp) {
|
||||
addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
|
||||
intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int __init intc_find_mask_handler(unsigned int width)
|
||||
static unsigned int __init intc_get_reg(struct intc_desc_int *d,
|
||||
unsigned long address)
|
||||
{
|
||||
switch (width) {
|
||||
case 8:
|
||||
return REG_FN_MASK_8;
|
||||
case 32:
|
||||
return REG_FN_MASK_32;
|
||||
unsigned int k;
|
||||
|
||||
for (k = 0; k < d->nr_reg; k++) {
|
||||
if (d->reg[k] == address)
|
||||
return k;
|
||||
}
|
||||
|
||||
BUG();
|
||||
return REG_FN_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int __init intc_find_prio_handler(unsigned int width)
|
||||
{
|
||||
switch (width) {
|
||||
case 16:
|
||||
return REG_FN_PRIO_16;
|
||||
case 32:
|
||||
return REG_FN_PRIO_32;
|
||||
}
|
||||
|
||||
BUG();
|
||||
return REG_FN_ERROR;
|
||||
}
|
||||
|
||||
static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id)
|
||||
static intc_enum __init intc_grp_id(struct intc_desc *desc,
|
||||
intc_enum enum_id)
|
||||
{
|
||||
struct intc_group *g = desc->groups;
|
||||
unsigned int i, j;
|
||||
@@ -289,10 +361,12 @@ static unsigned int __init intc_prio_value(struct intc_desc *desc,
|
||||
}
|
||||
|
||||
static unsigned int __init intc_mask_data(struct intc_desc *desc,
|
||||
struct intc_desc_int *d,
|
||||
intc_enum enum_id, int do_grps)
|
||||
{
|
||||
struct intc_mask_reg *mr = desc->mask_regs;
|
||||
unsigned int i, j, fn;
|
||||
unsigned int i, j, fn, mode;
|
||||
unsigned long reg_e, reg_d;
|
||||
|
||||
for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) {
|
||||
mr = desc->mask_regs + i;
|
||||
@@ -301,25 +375,46 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc,
|
||||
if (mr->enum_ids[j] != enum_id)
|
||||
continue;
|
||||
|
||||
fn = intc_find_mask_handler(mr->reg_width);
|
||||
if (fn == REG_FN_ERROR)
|
||||
return 0;
|
||||
if (mr->set_reg && mr->clr_reg) {
|
||||
fn = REG_FN_WRITE_BASE;
|
||||
mode = MODE_DUAL_REG;
|
||||
reg_e = mr->clr_reg;
|
||||
reg_d = mr->set_reg;
|
||||
} else {
|
||||
fn = REG_FN_MODIFY_BASE;
|
||||
if (mr->set_reg) {
|
||||
mode = MODE_ENABLE_REG;
|
||||
reg_e = mr->set_reg;
|
||||
reg_d = mr->set_reg;
|
||||
} else {
|
||||
mode = MODE_MASK_REG;
|
||||
reg_e = mr->clr_reg;
|
||||
reg_d = mr->clr_reg;
|
||||
}
|
||||
}
|
||||
|
||||
return _INTC_MK(fn, i, (mr->reg_width - 1) - j, 0);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_grps)
|
||||
return intc_mask_data(desc, intc_grp_id(desc, enum_id), 0);
|
||||
return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int __init intc_prio_data(struct intc_desc *desc,
|
||||
struct intc_desc_int *d,
|
||||
intc_enum enum_id, int do_grps)
|
||||
{
|
||||
struct intc_prio_reg *pr = desc->prio_regs;
|
||||
unsigned int i, j, fn, bit, prio;
|
||||
unsigned int i, j, fn, mode, bit;
|
||||
unsigned long reg_e, reg_d;
|
||||
|
||||
for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) {
|
||||
pr = desc->prio_regs + i;
|
||||
@@ -328,28 +423,72 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
|
||||
if (pr->enum_ids[j] != enum_id)
|
||||
continue;
|
||||
|
||||
fn = intc_find_prio_handler(pr->reg_width);
|
||||
if (fn == REG_FN_ERROR)
|
||||
return 0;
|
||||
if (pr->set_reg && pr->clr_reg) {
|
||||
fn = REG_FN_WRITE_BASE;
|
||||
mode = MODE_PCLR_REG;
|
||||
reg_e = pr->set_reg;
|
||||
reg_d = pr->clr_reg;
|
||||
} else {
|
||||
fn = REG_FN_MODIFY_BASE;
|
||||
mode = MODE_PRIO_REG;
|
||||
if (!pr->set_reg)
|
||||
BUG();
|
||||
reg_e = pr->set_reg;
|
||||
reg_d = pr->set_reg;
|
||||
}
|
||||
|
||||
prio = intc_prio_value(desc, enum_id, 1);
|
||||
fn += (pr->reg_width >> 3) - 1;
|
||||
bit = pr->reg_width - ((j + 1) * pr->field_width);
|
||||
|
||||
BUG_ON(bit < 0);
|
||||
|
||||
return _INTC_MK(fn, i, bit, prio);
|
||||
return _INTC_MK(fn, mode,
|
||||
intc_get_reg(d, reg_e),
|
||||
intc_get_reg(d, reg_d),
|
||||
pr->field_width, bit);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_grps)
|
||||
return intc_prio_data(desc, intc_grp_id(desc, enum_id), 0);
|
||||
return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id,
|
||||
static unsigned int __init intc_sense_data(struct intc_desc *desc,
|
||||
struct intc_desc_int *d,
|
||||
intc_enum enum_id)
|
||||
{
|
||||
struct intc_sense_reg *sr = desc->sense_regs;
|
||||
unsigned int i, j, fn, bit;
|
||||
|
||||
for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) {
|
||||
sr = desc->sense_regs + i;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) {
|
||||
if (sr->enum_ids[j] != enum_id)
|
||||
continue;
|
||||
|
||||
fn = REG_FN_MODIFY_BASE;
|
||||
fn += (sr->reg_width >> 3) - 1;
|
||||
bit = sr->reg_width - ((j + 1) * sr->field_width);
|
||||
|
||||
BUG_ON(bit < 0);
|
||||
|
||||
return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg),
|
||||
0, sr->field_width, bit);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init intc_register_irq(struct intc_desc *desc,
|
||||
struct intc_desc_int *d,
|
||||
intc_enum enum_id,
|
||||
unsigned int irq)
|
||||
{
|
||||
struct intc_handle_int *hp;
|
||||
unsigned int data[2], primary;
|
||||
|
||||
/* Prefer single interrupt source bitmap over other combinations:
|
||||
@@ -359,15 +498,15 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id,
|
||||
* 4. priority, multiple interrupt sources (groups)
|
||||
*/
|
||||
|
||||
data[0] = intc_mask_data(desc, enum_id, 0);
|
||||
data[1] = intc_prio_data(desc, enum_id, 0);
|
||||
data[0] = intc_mask_data(desc, d, enum_id, 0);
|
||||
data[1] = intc_prio_data(desc, d, enum_id, 0);
|
||||
|
||||
primary = 0;
|
||||
if (!data[0] && data[1])
|
||||
primary = 1;
|
||||
|
||||
data[0] = data[0] ? data[0] : intc_mask_data(desc, enum_id, 1);
|
||||
data[1] = data[1] ? data[1] : intc_prio_data(desc, enum_id, 1);
|
||||
data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1);
|
||||
data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1);
|
||||
|
||||
if (!data[primary])
|
||||
primary ^= 1;
|
||||
@@ -375,31 +514,118 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id,
|
||||
BUG_ON(!data[primary]); /* must have primary masking method */
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
set_irq_chip_and_handler_name(irq, &desc->chip,
|
||||
set_irq_chip_and_handler_name(irq, &d->chip,
|
||||
handle_level_irq, "level");
|
||||
set_irq_chip_data(irq, (void *)data[primary]);
|
||||
|
||||
/* record the desired priority level */
|
||||
intc_prio_level[irq] = intc_prio_value(desc, enum_id, 1);
|
||||
|
||||
/* enable secondary masking method if present */
|
||||
if (data[!primary])
|
||||
intc_reg_fns[_INTC_FN(data[!primary])].enable(desc,
|
||||
data[!primary]);
|
||||
_intc_enable(irq, data[!primary]);
|
||||
|
||||
/* add irq to d->prio list if priority is available */
|
||||
if (data[1]) {
|
||||
hp = d->prio + d->nr_prio;
|
||||
hp->irq = irq;
|
||||
hp->handle = data[1];
|
||||
|
||||
if (primary) {
|
||||
/*
|
||||
* only secondary priority should access registers, so
|
||||
* set _INTC_FN(h) = REG_FN_ERR for intc_set_priority()
|
||||
*/
|
||||
|
||||
hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0);
|
||||
hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0);
|
||||
}
|
||||
d->nr_prio++;
|
||||
}
|
||||
|
||||
/* add irq to d->sense list if sense is available */
|
||||
data[0] = intc_sense_data(desc, d, enum_id);
|
||||
if (data[0]) {
|
||||
(d->sense + d->nr_sense)->irq = irq;
|
||||
(d->sense + d->nr_sense)->handle = data[0];
|
||||
d->nr_sense++;
|
||||
}
|
||||
|
||||
/* irq should be disabled by default */
|
||||
desc->chip.mask(irq);
|
||||
d->chip.mask(irq);
|
||||
}
|
||||
|
||||
static unsigned int __init save_reg(struct intc_desc_int *d,
|
||||
unsigned int cnt,
|
||||
unsigned long value,
|
||||
unsigned int smp)
|
||||
{
|
||||
if (value) {
|
||||
d->reg[cnt] = value;
|
||||
#ifdef CONFIG_SMP
|
||||
d->smp[cnt] = smp;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void __init register_intc_controller(struct intc_desc *desc)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, k, smp;
|
||||
struct intc_desc_int *d;
|
||||
|
||||
desc->chip.mask = intc_disable;
|
||||
desc->chip.unmask = intc_enable;
|
||||
desc->chip.mask_ack = intc_disable;
|
||||
desc->chip.set_type = intc_set_sense;
|
||||
d = alloc_bootmem(sizeof(*d));
|
||||
|
||||
d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
|
||||
d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
|
||||
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
|
||||
|
||||
d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
|
||||
#ifdef CONFIG_SMP
|
||||
d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
|
||||
#endif
|
||||
k = 0;
|
||||
|
||||
if (desc->mask_regs) {
|
||||
for (i = 0; i < desc->nr_mask_regs; i++) {
|
||||
smp = IS_SMP(desc->mask_regs[i]);
|
||||
k += save_reg(d, k, desc->mask_regs[i].set_reg, smp);
|
||||
k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp);
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->prio_regs) {
|
||||
d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio));
|
||||
|
||||
for (i = 0; i < desc->nr_prio_regs; i++) {
|
||||
smp = IS_SMP(desc->prio_regs[i]);
|
||||
k += save_reg(d, k, desc->prio_regs[i].set_reg, smp);
|
||||
k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp);
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->sense_regs) {
|
||||
d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense));
|
||||
|
||||
for (i = 0; i < desc->nr_sense_regs; i++) {
|
||||
k += save_reg(d, k, desc->sense_regs[i].reg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
for (i = 0; i < desc->nr_vectors; i++) {
|
||||
struct intc_vect *vect = desc->vectors + i;
|
||||
|
||||
intc_register_irq(desc, vect->enum_id, evt2irq(vect->vect));
|
||||
intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
|
||||
}
|
||||
}
|
||||
|
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Interrupt handling for INTC2-based IRQ.
|
||||
*
|
||||
* Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
|
||||
* Copyright (C) 2005, 2006 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.
|
||||
*
|
||||
* These are the "new Hitachi style" interrupts, as present on the
|
||||
* Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
static inline struct intc2_desc *get_intc2_desc(unsigned int irq)
|
||||
{
|
||||
struct irq_chip *chip = get_irq_chip(irq);
|
||||
return (void *)((char *)chip - offsetof(struct intc2_desc, chip));
|
||||
}
|
||||
|
||||
static void disable_intc2_irq(unsigned int irq)
|
||||
{
|
||||
struct intc2_data *p = get_irq_chip_data(irq);
|
||||
struct intc2_desc *d = get_intc2_desc(irq);
|
||||
|
||||
ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset +
|
||||
(hard_smp_processor_id() * 4));
|
||||
}
|
||||
|
||||
static void enable_intc2_irq(unsigned int irq)
|
||||
{
|
||||
struct intc2_data *p = get_irq_chip_data(irq);
|
||||
struct intc2_desc *d = get_intc2_desc(irq);
|
||||
|
||||
ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset +
|
||||
(hard_smp_processor_id() * 4));
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup an INTC2 style interrupt.
|
||||
* NOTE: Unlike IPR interrupts, parameters are not shifted by this code,
|
||||
* allowing the use of the numbers straight out of the datasheet.
|
||||
* For example:
|
||||
* PIO1 which is INTPRI00[19,16] and INTMSK00[13]
|
||||
* would be: ^ ^ ^ ^
|
||||
* | | | |
|
||||
* { 84, 0, 16, 0, 13 },
|
||||
*
|
||||
* in the intc2_data table.
|
||||
*/
|
||||
void register_intc2_controller(struct intc2_desc *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
desc->chip.mask = disable_intc2_irq;
|
||||
desc->chip.unmask = enable_intc2_irq;
|
||||
desc->chip.mask_ack = disable_intc2_irq;
|
||||
|
||||
for (i = 0; i < desc->nr_irqs; i++) {
|
||||
unsigned long ipr, flags;
|
||||
struct intc2_data *p = desc->intc2_data + i;
|
||||
|
||||
disable_irq_nosync(p->irq);
|
||||
|
||||
if (desc->prio_base) {
|
||||
/* Set the priority level */
|
||||
local_irq_save(flags);
|
||||
|
||||
ipr = ctrl_inl(desc->prio_base + p->ipr_offset);
|
||||
ipr &= ~(0xf << p->ipr_shift);
|
||||
ipr |= p->priority << p->ipr_shift;
|
||||
ctrl_outl(ipr, desc->prio_base + p->ipr_offset);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
set_irq_chip_and_handler_name(p->irq, &desc->chip,
|
||||
handle_level_irq, "level");
|
||||
set_irq_chip_data(p->irq, p);
|
||||
|
||||
disable_intc2_irq(p->irq);
|
||||
}
|
||||
}
|
@@ -10,26 +10,25 @@
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
int __init detect_cpu_and_cache_system(void)
|
||||
{
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
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;
|
||||
boot_cpu_data.type = CPU_SH7619;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.dcache.way_incr = (1<<12);
|
||||
boot_cpu_data.dcache.sets = 256;
|
||||
boot_cpu_data.dcache.entry_shift = 4;
|
||||
boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
|
||||
boot_cpu_data.dcache.flags = 0;
|
||||
#endif
|
||||
/*
|
||||
* SH-2 doesn't have separate caches
|
||||
*/
|
||||
current_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
|
||||
current_cpu_data.icache = current_cpu_data.dcache;
|
||||
boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
|
||||
boot_cpu_data.icache = boot_cpu_data.dcache;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -12,6 +12,61 @@
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
|
||||
WDT, EDMAC, CMT0, CMT1,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
|
||||
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
|
||||
HIF_HIFI, HIF_HIFBI,
|
||||
DMAC0, DMAC1, DMAC2, DMAC3,
|
||||
SIOF,
|
||||
|
||||
/* interrupt groups */
|
||||
SCIF0, SCIF1, SCIF2,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
|
||||
INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
|
||||
INTC_IRQ(IRQ4, 80), INTC_IRQ(IRQ5, 81),
|
||||
INTC_IRQ(IRQ6, 82), INTC_IRQ(IRQ7, 83),
|
||||
INTC_IRQ(WDT, 84), INTC_IRQ(EDMAC, 85),
|
||||
INTC_IRQ(CMT0, 86), INTC_IRQ(CMT1, 87),
|
||||
INTC_IRQ(SCIF0_ERI, 88), INTC_IRQ(SCIF0_RXI, 89),
|
||||
INTC_IRQ(SCIF0_BRI, 90), INTC_IRQ(SCIF0_TXI, 91),
|
||||
INTC_IRQ(SCIF1_ERI, 92), INTC_IRQ(SCIF1_RXI, 93),
|
||||
INTC_IRQ(SCIF1_BRI, 94), INTC_IRQ(SCIF1_TXI, 95),
|
||||
INTC_IRQ(SCIF2_ERI, 96), INTC_IRQ(SCIF2_RXI, 97),
|
||||
INTC_IRQ(SCIF2_BRI, 98), INTC_IRQ(SCIF2_TXI, 99),
|
||||
INTC_IRQ(HIF_HIFI, 100), INTC_IRQ(HIF_HIFBI, 101),
|
||||
INTC_IRQ(DMAC0, 104), INTC_IRQ(DMAC1, 105),
|
||||
INTC_IRQ(DMAC2, 106), INTC_IRQ(DMAC3, 107),
|
||||
INTC_IRQ(SIOF, 108),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
|
||||
INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xf8140006, 0, 16, 4, /* IPRA */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
|
||||
{ 0xf8140008, 0, 16, 4, /* IPRB */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
{ 0xf8080000, 0, 16, 4, /* IPRC */ { WDT, EDMAC, CMT0, CMT1 } },
|
||||
{ 0xf8080002, 0, 16, 4, /* IPRD */ { SCIF0, SCIF1, SCIF2 } },
|
||||
{ 0xf8080004, 0, 16, 4, /* IPRE */ { HIF_HIFI, HIF_HIFBI } },
|
||||
{ 0xf8080006, 0, 16, 4, /* IPRF */ { DMAC0, DMAC1, DMAC2, DMAC3 } },
|
||||
{ 0xf8080008, 0, 16, 4, /* IPRG */ { SIOF } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups,
|
||||
NULL, NULL, prio_registers, NULL);
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xf8400000,
|
||||
@@ -52,43 +107,7 @@ static int __init sh7619_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7619_devices_setup);
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
{ 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 long ipr_offsets[] = {
|
||||
0xf8080000, /* IPRC */
|
||||
0xf8080002, /* IPRD */
|
||||
0xf8080004, /* IPRE */
|
||||
0xf8080006, /* IPRF */
|
||||
0xf8080008, /* IPRG */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7619",
|
||||
},
|
||||
};
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
@@ -17,15 +17,15 @@
|
||||
int __init detect_cpu_and_cache_system(void)
|
||||
{
|
||||
/* Just SH7206 for now .. */
|
||||
current_cpu_data.type = CPU_SH7206;
|
||||
current_cpu_data.flags |= CPU_HAS_OP32;
|
||||
boot_cpu_data.type = CPU_SH7206;
|
||||
boot_cpu_data.flags |= CPU_HAS_OP32;
|
||||
|
||||
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;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.dcache.way_incr = (1 << 11);
|
||||
boot_cpu_data.dcache.sets = 128;
|
||||
boot_cpu_data.dcache.entry_shift = 4;
|
||||
boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
|
||||
boot_cpu_data.dcache.flags = 0;
|
||||
|
||||
/*
|
||||
* The icache is the same as the dcache as far as this setup is
|
||||
@@ -33,7 +33,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.
|
||||
*/
|
||||
current_cpu_data.icache = current_cpu_data.dcache;
|
||||
boot_cpu_data.icache = boot_cpu_data.dcache;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -12,27 +12,184 @@
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
|
||||
PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
|
||||
ADC_ADI0, ADC_ADI1,
|
||||
DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
|
||||
DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
|
||||
DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
|
||||
DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
|
||||
CMT0, CMT1, BSC, WDT,
|
||||
MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
|
||||
MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
|
||||
MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
|
||||
MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
|
||||
MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
|
||||
MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
|
||||
MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
|
||||
POE2_OEI1, POE2_OEI2,
|
||||
MTU2S_TGI3A, MTU2S_TGI3B, MTU2S_TGI3C, MTU2S_TGI3D, MTU2S_TCI3V,
|
||||
MTU2S_TGI4A, MTU2S_TGI4B, MTU2S_TGI4C, MTU2S_TGI4D, MTU2S_TCI4V,
|
||||
MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W,
|
||||
POE2_OEI3,
|
||||
IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI,
|
||||
SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
|
||||
SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
|
||||
SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
|
||||
SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
|
||||
|
||||
/* interrupt groups */
|
||||
PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
|
||||
MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
|
||||
MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S,
|
||||
IIC3, SCIF0, SCIF1, SCIF2, SCIF3,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65),
|
||||
INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
|
||||
INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
|
||||
INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
|
||||
INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
|
||||
INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
|
||||
INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
|
||||
INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
|
||||
INTC_IRQ(ADC_ADI0, 92), INTC_IRQ(ADC_ADI1, 96),
|
||||
INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
|
||||
INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
|
||||
INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
|
||||
INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
|
||||
INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
|
||||
INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
|
||||
INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
|
||||
INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
|
||||
INTC_IRQ(CMT0, 140), INTC_IRQ(CMT1, 144),
|
||||
INTC_IRQ(BSC, 148), INTC_IRQ(WDT, 152),
|
||||
INTC_IRQ(MTU2_TGI0A, 156), INTC_IRQ(MTU2_TGI0B, 157),
|
||||
INTC_IRQ(MTU2_TGI0C, 158), INTC_IRQ(MTU2_TGI0D, 159),
|
||||
INTC_IRQ(MTU2_TCI0V, 160),
|
||||
INTC_IRQ(MTU2_TGI0E, 161), INTC_IRQ(MTU2_TGI0F, 162),
|
||||
INTC_IRQ(MTU2_TGI1A, 164), INTC_IRQ(MTU2_TGI1B, 165),
|
||||
INTC_IRQ(MTU2_TCI1V, 168), INTC_IRQ(MTU2_TCI1U, 169),
|
||||
INTC_IRQ(MTU2_TGI2A, 172), INTC_IRQ(MTU2_TGI2B, 173),
|
||||
INTC_IRQ(MTU2_TCI2V, 176), INTC_IRQ(MTU2_TCI2U, 177),
|
||||
INTC_IRQ(MTU2_TGI3A, 180), INTC_IRQ(MTU2_TGI3B, 181),
|
||||
INTC_IRQ(MTU2_TGI3C, 182), INTC_IRQ(MTU2_TGI3D, 183),
|
||||
INTC_IRQ(MTU2_TCI3V, 184),
|
||||
INTC_IRQ(MTU2_TGI4A, 188), INTC_IRQ(MTU2_TGI4B, 189),
|
||||
INTC_IRQ(MTU2_TGI4C, 190), INTC_IRQ(MTU2_TGI4D, 191),
|
||||
INTC_IRQ(MTU2_TCI4V, 192),
|
||||
INTC_IRQ(MTU2_TGI5U, 196), INTC_IRQ(MTU2_TGI5V, 197),
|
||||
INTC_IRQ(MTU2_TGI5W, 198),
|
||||
INTC_IRQ(POE2_OEI1, 200), INTC_IRQ(POE2_OEI2, 201),
|
||||
INTC_IRQ(MTU2S_TGI3A, 204), INTC_IRQ(MTU2S_TGI3B, 205),
|
||||
INTC_IRQ(MTU2S_TGI3C, 206), INTC_IRQ(MTU2S_TGI3D, 207),
|
||||
INTC_IRQ(MTU2S_TCI3V, 208),
|
||||
INTC_IRQ(MTU2S_TGI4A, 212), INTC_IRQ(MTU2S_TGI4B, 213),
|
||||
INTC_IRQ(MTU2S_TGI4C, 214), INTC_IRQ(MTU2S_TGI4D, 215),
|
||||
INTC_IRQ(MTU2S_TCI4V, 216),
|
||||
INTC_IRQ(MTU2S_TGI5U, 220), INTC_IRQ(MTU2S_TGI5V, 221),
|
||||
INTC_IRQ(MTU2S_TGI5W, 222),
|
||||
INTC_IRQ(POE2_OEI3, 224),
|
||||
INTC_IRQ(IIC3_STPI, 228), INTC_IRQ(IIC3_NAKI, 229),
|
||||
INTC_IRQ(IIC3_RXI, 230), INTC_IRQ(IIC3_TXI, 231),
|
||||
INTC_IRQ(IIC3_TEI, 232),
|
||||
INTC_IRQ(SCIF0_BRI, 240), INTC_IRQ(SCIF0_ERI, 241),
|
||||
INTC_IRQ(SCIF0_RXI, 242), INTC_IRQ(SCIF0_TXI, 243),
|
||||
INTC_IRQ(SCIF1_BRI, 244), INTC_IRQ(SCIF1_ERI, 245),
|
||||
INTC_IRQ(SCIF1_RXI, 246), INTC_IRQ(SCIF1_TXI, 247),
|
||||
INTC_IRQ(SCIF2_BRI, 248), INTC_IRQ(SCIF2_ERI, 249),
|
||||
INTC_IRQ(SCIF2_RXI, 250), INTC_IRQ(SCIF2_TXI, 251),
|
||||
INTC_IRQ(SCIF3_BRI, 252), INTC_IRQ(SCIF3_ERI, 253),
|
||||
INTC_IRQ(SCIF3_RXI, 254), INTC_IRQ(SCIF3_TXI, 255),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
|
||||
PINT4, PINT5, PINT6, PINT7),
|
||||
INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
|
||||
INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
|
||||
INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
|
||||
INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
|
||||
INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
|
||||
INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
|
||||
INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
|
||||
INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
|
||||
INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
|
||||
INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
|
||||
INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
|
||||
INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
|
||||
INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
|
||||
INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
|
||||
INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
|
||||
INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
|
||||
INTC_GROUP(MTU5, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
|
||||
INTC_GROUP(POE2_12, POE2_OEI1, POE2_OEI2),
|
||||
INTC_GROUP(MTU3S_ABCD, MTU2S_TGI3A, MTU2S_TGI3B,
|
||||
MTU2S_TGI3C, MTU2S_TGI3D),
|
||||
INTC_GROUP(MTU4S_ABCD, MTU2S_TGI4A, MTU2S_TGI4B,
|
||||
MTU2S_TGI4C, MTU2S_TGI4D),
|
||||
INTC_GROUP(MTU5S, MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W),
|
||||
INTC_GROUP(IIC3, IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI),
|
||||
INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
|
||||
INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
|
||||
INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xfffe0818, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
|
||||
{ 0xfffe081a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
{ 0xfffe0820, 0, 16, 4, /* IPR05 */ { PINT, 0, ADC_ADI0, ADC_ADI1 } },
|
||||
{ 0xfffe0c00, 0, 16, 4, /* IPR06 */ { DMAC0, DMAC1, DMAC2, DMAC3 } },
|
||||
{ 0xfffe0c02, 0, 16, 4, /* IPR07 */ { DMAC4, DMAC5, DMAC6, DMAC7 } },
|
||||
{ 0xfffe0c04, 0, 16, 4, /* IPR08 */ { CMT0, CMT1, BSC, WDT } },
|
||||
{ 0xfffe0c06, 0, 16, 4, /* IPR09 */ { MTU0_ABCD, MTU0_VEF,
|
||||
MTU1_AB, MTU1_VU } },
|
||||
{ 0xfffe0c08, 0, 16, 4, /* IPR10 */ { MTU2_AB, MTU2_VU,
|
||||
MTU3_ABCD, MTU2_TCI3V } },
|
||||
{ 0xfffe0c0a, 0, 16, 4, /* IPR11 */ { MTU4_ABCD, MTU2_TCI4V,
|
||||
MTU5, POE2_12 } },
|
||||
{ 0xfffe0c0c, 0, 16, 4, /* IPR12 */ { MTU3S_ABCD, MTU2S_TCI3V,
|
||||
MTU4S_ABCD, MTU2S_TCI4V } },
|
||||
{ 0xfffe0c0e, 0, 16, 4, /* IPR13 */ { MTU5S, POE2_OEI3, IIC3, 0 } },
|
||||
{ 0xfffe0c10, 0, 16, 4, /* IPR14 */ { SCIF0, SCIF1, SCIF2, SCIF3 } },
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xfffe0808, 0, 16, /* PINTER */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7206", vectors, groups,
|
||||
NULL, mask_registers, prio_registers, NULL);
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xfffe8000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 241, 242, 243, 240},
|
||||
.irqs = { 241, 242, 243, 240 },
|
||||
}, {
|
||||
.mapbase = 0xfffe8800,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 247, 244, 245, 246},
|
||||
.irqs = { 245, 246, 247, 244 },
|
||||
}, {
|
||||
.mapbase = 0xfffe9000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 249, 250, 251, 248},
|
||||
.irqs = { 249, 250, 251, 248 },
|
||||
}, {
|
||||
.mapbase = 0xfffe9800,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 253, 254, 255, 252},
|
||||
.irqs = { 253, 254, 255, 252 },
|
||||
}, {
|
||||
.flags = 0,
|
||||
}
|
||||
@@ -57,57 +214,7 @@ static int __init sh7206_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7206_devices_setup);
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
{ 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 long 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 */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7206",
|
||||
},
|
||||
};
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
@@ -6,12 +6,13 @@ obj-y := ex.o probe.o entry.o
|
||||
|
||||
# CPU subtype setup
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh7709.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh7709.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh770x.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o
|
||||
|
||||
# Primary on-chip clocks (common)
|
||||
clock-$(CONFIG_CPU_SH3) := clock-sh3.o
|
||||
@@ -19,5 +20,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o
|
||||
|
||||
obj-y += $(clock-y)
|
||||
|
@@ -50,44 +50,47 @@ int __init detect_cpu_and_cache_system(void)
|
||||
|
||||
back_to_P1();
|
||||
|
||||
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;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.dcache.entry_shift = 4;
|
||||
boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
|
||||
boot_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 */
|
||||
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;
|
||||
boot_cpu_data.dcache.way_incr = (1 << 11);
|
||||
boot_cpu_data.dcache.entry_mask = 0x7f0;
|
||||
boot_cpu_data.dcache.sets = 128;
|
||||
boot_cpu_data.type = CPU_SH7708;
|
||||
|
||||
current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC;
|
||||
boot_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC;
|
||||
} else { /* 7709A or 7729 */
|
||||
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;
|
||||
boot_cpu_data.dcache.way_incr = (1 << 12);
|
||||
boot_cpu_data.dcache.entry_mask = 0xff0;
|
||||
boot_cpu_data.dcache.sets = 256;
|
||||
boot_cpu_data.type = CPU_SH7729;
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7706)
|
||||
current_cpu_data.type = CPU_SH7706;
|
||||
boot_cpu_data.type = CPU_SH7706;
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
|
||||
current_cpu_data.type = CPU_SH7710;
|
||||
boot_cpu_data.type = CPU_SH7710;
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7712)
|
||||
current_cpu_data.type = CPU_SH7712;
|
||||
boot_cpu_data.type = CPU_SH7712;
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7720)
|
||||
boot_cpu_data.type = CPU_SH7720;
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
|
||||
current_cpu_data.type = CPU_SH7705;
|
||||
boot_cpu_data.type = CPU_SH7705;
|
||||
|
||||
#if defined(CONFIG_SH7705_CACHE_32KB)
|
||||
current_cpu_data.dcache.way_incr = (1 << 13);
|
||||
current_cpu_data.dcache.entry_mask = 0x1ff0;
|
||||
current_cpu_data.dcache.sets = 512;
|
||||
boot_cpu_data.dcache.way_incr = (1 << 13);
|
||||
boot_cpu_data.dcache.entry_mask = 0x1ff0;
|
||||
boot_cpu_data.dcache.sets = 512;
|
||||
ctrl_outl(CCR_CACHE_32KB, CCR3);
|
||||
#else
|
||||
ctrl_outl(CCR_CACHE_16KB, CCR3);
|
||||
@@ -98,9 +101,8 @@ int __init detect_cpu_and_cache_system(void)
|
||||
/*
|
||||
* SH-3 doesn't have separate caches
|
||||
*/
|
||||
current_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
|
||||
current_cpu_data.icache = current_cpu_data.dcache;
|
||||
boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
|
||||
boot_cpu_data.icache = boot_cpu_data.dcache;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SH7705 Setup
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006, 2007 Paul Mundt
|
||||
* Copyright (C) 2007 Nobuhiro Iwamatsu
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
@@ -10,8 +10,90 @@
|
||||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
#include <asm/rtc.h>
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
|
||||
PINT07, PINT815,
|
||||
DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
|
||||
SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
|
||||
ADC_ADI,
|
||||
USB_USI0, USB_USI1,
|
||||
TPU0, TPU1, TPU2, TPU3,
|
||||
TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
|
||||
RTC_ATI, RTC_PRI, RTC_CUI,
|
||||
WDT,
|
||||
REF_RCMI,
|
||||
|
||||
/* interrupt groups */
|
||||
RTC, TMU2, DMAC, USB, SCIF2, SCIF0,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
|
||||
INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
|
||||
INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
|
||||
INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
|
||||
INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
|
||||
INTC_VECT(SCIF0_TXI, 0x8e0),
|
||||
INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
|
||||
INTC_VECT(SCIF2_TXI, 0x960),
|
||||
INTC_VECT(ADC_ADI, 0x980),
|
||||
INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
|
||||
INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
|
||||
INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0),
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
|
||||
INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
|
||||
INTC_VECT(RTC_CUI, 0x4c0),
|
||||
INTC_VECT(WDT, 0x560),
|
||||
INTC_VECT(REF_RCMI, 0x580),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
|
||||
INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
|
||||
INTC_GROUP(USB, USB_USI0, USB_USI1),
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(DMAC, 7),
|
||||
INTC_PRIO(SCIF2, 3),
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
|
||||
{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } },
|
||||
{ 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
|
||||
{ 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, IRQ5, IRQ4 } },
|
||||
{ 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, SCIF0, SCIF2, ADC_ADI } },
|
||||
{ 0xa4080000, 0, 16, 4, /* IPRF */ { 0, 0, USB } },
|
||||
{ 0xa4080002, 0, 16, 4, /* IPRG */ { TPU0, TPU1 } },
|
||||
{ 0xa4080004, 0, 16, 4, /* IPRH */ { TPU2, TPU3 } },
|
||||
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
|
||||
static struct intc_vect vectors_irq[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
|
||||
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
@@ -37,8 +119,43 @@ static struct platform_device sci_device = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0xfffffec0,
|
||||
.end = 0xfffffec0 + 0x1e,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = 20,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = 21,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = 22,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_rtc_platform_info rtc_info = {
|
||||
.capabilities = RTC_CAP_4_DIGIT_YEAR,
|
||||
};
|
||||
|
||||
static struct platform_device rtc_device = {
|
||||
.name = "sh-rtc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
.resource = rtc_resources,
|
||||
.dev = {
|
||||
.platform_data = &rtc_info,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh7705_devices[] __initdata = {
|
||||
&sci_device,
|
||||
&rtc_device,
|
||||
};
|
||||
|
||||
static int __init sh7705_devices_setup(void)
|
||||
@@ -48,51 +165,16 @@ static int __init sh7705_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7705_devices_setup);
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
|
||||
{ 18, 0, 4, 2 }, /* TMU2 TUNI */
|
||||
{ 27, 1, 12, 2 }, /* WDT ITI */
|
||||
{ 20, 0, 0, 2 }, /* RTC ATI (alarm) */
|
||||
{ 21, 0, 0, 2 }, /* RTC PRI (period) */
|
||||
{ 22, 0, 0, 2 }, /* RTC CUI (carry) */
|
||||
{ 48, 4, 12, 7 }, /* DMAC DMTE0 */
|
||||
{ 49, 4, 12, 7 }, /* DMAC DMTE1 */
|
||||
{ 50, 4, 12, 7 }, /* DMAC DMTE2 */
|
||||
{ 51, 4, 12, 7 }, /* DMAC DMTE3 */
|
||||
{ 52, 4, 8, 3 }, /* SCIF0 ERI */
|
||||
{ 53, 4, 8, 3 }, /* SCIF0 RXI */
|
||||
{ 55, 4, 8, 3 }, /* SCIF0 TXI */
|
||||
{ 56, 4, 4, 3 }, /* SCIF1 ERI */
|
||||
{ 57, 4, 4, 3 }, /* SCIF1 RXI */
|
||||
{ 59, 4, 4, 3 }, /* SCIF1 TXI */
|
||||
};
|
||||
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xFFFFFEE2, /* 0: IPRA */
|
||||
0xFFFFFEE4, /* 1: IPRB */
|
||||
0xA4000016, /* 2: IPRC */
|
||||
0xA4000018, /* 3: IPRD */
|
||||
0xA400001A, /* 4: IPRE */
|
||||
0xA4080000, /* 5: IPRF */
|
||||
0xA4080002, /* 6: IPRG */
|
||||
0xA4080004, /* 7: IPRH */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7705",
|
||||
},
|
||||
};
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
if (mode == IRQ_MODE_IRQ) {
|
||||
register_intc_controller(&intc_desc_irq);
|
||||
return;
|
||||
}
|
||||
BUG();
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* SH7708 Setup
|
||||
*
|
||||
* 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/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xfffffe80,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCI,
|
||||
.irqs = { 23, 24, 25, 0 },
|
||||
}, {
|
||||
.flags = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sci_device = {
|
||||
.name = "sh-sci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = sci_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh7708_devices[] __initdata = {
|
||||
&sci_device,
|
||||
};
|
||||
|
||||
static int __init sh7708_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(sh7708_devices,
|
||||
ARRAY_SIZE(sh7708_devices));
|
||||
}
|
||||
__initcall(sh7708_devices_setup);
|
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* SH7707/SH7709 Setup
|
||||
*
|
||||
* 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/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0xfffffec0,
|
||||
.end = 0xfffffec0 + 0x1e,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = 20,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = 21,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = 22,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xfffffe80,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCI,
|
||||
.irqs = { 23, 24, 25, 0 },
|
||||
}, {
|
||||
.mapbase = 0xa4000150,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 56, 57, 59, 58 },
|
||||
}, {
|
||||
.mapbase = 0xa4000140,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_IRDA,
|
||||
.irqs = { 52, 53, 55, 54 },
|
||||
}, {
|
||||
.flags = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sci_device = {
|
||||
.name = "sh-sci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = sci_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device rtc_device = {
|
||||
.name = "sh-rtc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
.resource = rtc_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *sh7709_devices[] __initdata = {
|
||||
&sci_device,
|
||||
&rtc_device,
|
||||
};
|
||||
|
||||
static int __init sh7709_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(sh7709_devices,
|
||||
ARRAY_SIZE(sh7709_devices));
|
||||
}
|
||||
__initcall(sh7709_devices_setup);
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
{ 16, 0, 12, 2 }, /* TMU TUNI0 */
|
||||
{ 17, 0, 8, 4 }, /* TMU TUNI1 */
|
||||
{ 18, 0, 4, 1 }, /* TMU TUNI1 */
|
||||
{ 19, 0, 4, 1 }, /* TMU TUNI1 */
|
||||
{ 20, 0, 0, 2 }, /* RTC CUI */
|
||||
{ 21, 0, 0, 2 }, /* RTC CUI */
|
||||
{ 22, 0, 0, 2 }, /* RTC CUI */
|
||||
|
||||
{ 23, 1, 4, 3 }, /* SCI */
|
||||
{ 24, 1, 4, 3 }, /* SCI */
|
||||
{ 25, 1, 4, 3 }, /* SCI */
|
||||
{ 26, 1, 4, 3 }, /* SCI */
|
||||
{ 27, 1, 12, 3 }, /* WDT ITI */
|
||||
|
||||
{ 32, 2, 0, 1 }, /* IRQ 0 */
|
||||
{ 33, 2, 4, 1 }, /* IRQ 1 */
|
||||
{ 34, 2, 8, 1 }, /* IRQ 2 APM */
|
||||
{ 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */
|
||||
|
||||
{ 36, 3, 0, 1 }, /* IRQ 4 */
|
||||
{ 37, 3, 4, 1 }, /* IRQ 5 */
|
||||
|
||||
{ 48, 4, 12, 7 }, /* DMA */
|
||||
{ 49, 4, 12, 7 }, /* DMA */
|
||||
{ 50, 4, 12, 7 }, /* DMA */
|
||||
{ 51, 4, 12, 7 }, /* DMA */
|
||||
|
||||
{ 52, 4, 8, 3 }, /* IRDA */
|
||||
{ 53, 4, 8, 3 }, /* IRDA */
|
||||
{ 54, 4, 8, 3 }, /* IRDA */
|
||||
{ 55, 4, 8, 3 }, /* IRDA */
|
||||
|
||||
{ 56, 4, 4, 3 }, /* SCIF */
|
||||
{ 57, 4, 4, 3 }, /* SCIF */
|
||||
{ 58, 4, 4, 3 }, /* SCIF */
|
||||
{ 59, 4, 4, 3 }, /* SCIF */
|
||||
};
|
||||
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xfffffee2, /* 0: IPRA */
|
||||
0xfffffee4, /* 1: IPRB */
|
||||
0xa4000016, /* 2: IPRC */
|
||||
0xa4000018, /* 3: IPRD */
|
||||
0xa400001a, /* 4: IPRE */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7709",
|
||||
},
|
||||
};
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
224
arch/sh/kernel/cpu/sh3/setup-sh770x.c
Normal file
224
arch/sh/kernel/cpu/sh3/setup-sh770x.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* SH3 Setup code for SH7706, SH7707, SH7708, SH7709
|
||||
*
|
||||
* Copyright (C) 2007 Magnus Damm
|
||||
*
|
||||
* Based on setup-sh7709.c
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
|
||||
PINT07, PINT815,
|
||||
DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
|
||||
SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI,
|
||||
ADC_ADI,
|
||||
LCDC, PCC0, PCC1,
|
||||
TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
|
||||
RTC_ATI, RTC_PRI, RTC_CUI,
|
||||
WDT,
|
||||
REF_RCMI, REF_ROVI,
|
||||
|
||||
/* interrupt groups */
|
||||
RTC, REF, TMU2, DMAC, SCI, SCIF2, SCIF0,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
|
||||
INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
|
||||
INTC_VECT(RTC_CUI, 0x4c0),
|
||||
INTC_VECT(SCI_ERI, 0x4e0), INTC_VECT(SCI_RXI, 0x500),
|
||||
INTC_VECT(SCI_TXI, 0x520), INTC_VECT(SCI_TEI, 0x540),
|
||||
INTC_VECT(WDT, 0x560),
|
||||
INTC_VECT(REF_RCMI, 0x580),
|
||||
INTC_VECT(REF_ROVI, 0x5a0),
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
|
||||
INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
|
||||
INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
|
||||
INTC_VECT(ADC_ADI, 0x980),
|
||||
INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
|
||||
INTC_VECT(SCIF2_BRI, 0x940), INTC_VECT(SCIF2_TXI, 0x960),
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
|
||||
INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
|
||||
INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7707)
|
||||
INTC_VECT(LCDC, 0x9a0),
|
||||
INTC_VECT(PCC0, 0x9c0), INTC_VECT(PCC1, 0x9e0),
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
|
||||
INTC_GROUP(REF, REF_RCMI, REF_ROVI),
|
||||
INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
|
||||
INTC_GROUP(SCI, SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI),
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(DMAC, 7),
|
||||
INTC_PRIO(SCI, 3),
|
||||
INTC_PRIO(SCIF2, 3),
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
|
||||
{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } },
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
{ 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
|
||||
{ 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
|
||||
{ 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, 0, SCIF2, ADC_ADI } },
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
{ 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, } },
|
||||
{ 0xa400001a, 0, 16, 4, /* IPRE */ { 0, SCIF0 } },
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7707)
|
||||
{ 0xa400001c, 0, 16, 4, /* IPRF */ { 0, LCDC, PCC0, PCC1, } },
|
||||
#endif
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
static struct intc_vect vectors_irq[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
|
||||
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
#endif
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0xfffffec0,
|
||||
.end = 0xfffffec0 + 0x1e,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = 20,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = 21,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = 22,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device rtc_device = {
|
||||
.name = "sh-rtc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
.resource = rtc_resources,
|
||||
};
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xfffffe80,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCI,
|
||||
.irqs = { 23, 24, 25, 0 },
|
||||
},
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
{
|
||||
.mapbase = 0xa4000150,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 56, 57, 59, 58 },
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
{
|
||||
.mapbase = 0xa4000140,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_IRDA,
|
||||
.irqs = { 52, 53, 55, 54 },
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.flags = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sci_device = {
|
||||
.name = "sh-sci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = sci_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh770x_devices[] __initdata = {
|
||||
&sci_device,
|
||||
&rtc_device,
|
||||
};
|
||||
|
||||
static int __init sh770x_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(sh770x_devices,
|
||||
ARRAY_SIZE(sh770x_devices));
|
||||
}
|
||||
__initcall(sh770x_devices_setup);
|
||||
|
||||
#define INTC_ICR1 0xa4000010UL
|
||||
#define INTC_ICR1_IRQLVL (1<<14)
|
||||
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
if (mode == IRQ_MODE_IRQ) {
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7709)
|
||||
ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1);
|
||||
register_intc_controller(&intc_desc_irq);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
BUG();
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SH7710 Setup
|
||||
* SH3 Setup code for SH7710, SH7712
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006, 2007 Paul Mundt
|
||||
* Copyright (C) 2007 Nobuhiro Iwamatsu
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
@@ -10,8 +10,140 @@
|
||||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
#include <asm/rtc.h>
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
|
||||
DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
|
||||
DMAC_DEI4, DMAC_DEI5,
|
||||
IPSEC,
|
||||
EDMAC0, EDMAC1, EDMAC2,
|
||||
SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI,
|
||||
SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI,
|
||||
TMU0, TMU1, TMU2,
|
||||
RTC_ATI, RTC_PRI, RTC_CUI,
|
||||
WDT,
|
||||
REF,
|
||||
|
||||
/* interrupt groups */
|
||||
RTC, DMAC1, SCIF0, SCIF1, DMAC2, SIOF0, SIOF1,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
|
||||
INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
|
||||
INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
|
||||
INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
|
||||
INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
|
||||
INTC_VECT(SCIF1_ERI, 0x900), INTC_VECT(SCIF1_RXI, 0x920),
|
||||
INTC_VECT(SCIF1_BRI, 0x940), INTC_VECT(SCIF1_TXI, 0x960),
|
||||
INTC_VECT(DMAC_DEI4, 0xb80), INTC_VECT(DMAC_DEI5, 0xba0),
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7710
|
||||
INTC_VECT(IPSEC, 0xbe0),
|
||||
#endif
|
||||
INTC_VECT(EDMAC0, 0xc00), INTC_VECT(EDMAC1, 0xc20),
|
||||
INTC_VECT(EDMAC2, 0xc40),
|
||||
INTC_VECT(SIOF0_ERI, 0xe00), INTC_VECT(SIOF0_TXI, 0xe20),
|
||||
INTC_VECT(SIOF0_RXI, 0xe40), INTC_VECT(SIOF0_CCI, 0xe60),
|
||||
INTC_VECT(SIOF1_ERI, 0xe80), INTC_VECT(SIOF1_TXI, 0xea0),
|
||||
INTC_VECT(SIOF1_RXI, 0xec0), INTC_VECT(SIOF1_CCI, 0xee0),
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2, 0x440),
|
||||
INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
|
||||
INTC_VECT(RTC_CUI, 0x4c0),
|
||||
INTC_VECT(WDT, 0x560),
|
||||
INTC_VECT(REF, 0x580),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(DMAC1, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
|
||||
INTC_GROUP(DMAC2, DMAC_DEI4, DMAC_DEI5),
|
||||
INTC_GROUP(SIOF0, SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI),
|
||||
INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(DMAC1, 7),
|
||||
INTC_PRIO(DMAC2, 7),
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
INTC_PRIO(SCIF1, 3),
|
||||
INTC_PRIO(SIOF0, 3),
|
||||
INTC_PRIO(SIOF1, 3),
|
||||
INTC_PRIO(EDMAC0, 5),
|
||||
INTC_PRIO(EDMAC1, 5),
|
||||
INTC_PRIO(EDMAC2, 5),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
|
||||
{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
|
||||
{ 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
|
||||
{ 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } },
|
||||
{ 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } },
|
||||
{ 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } },
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7710
|
||||
{ 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } },
|
||||
#endif
|
||||
{ 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } },
|
||||
{ 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } },
|
||||
{ 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
|
||||
static struct intc_vect vectors_irq[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
|
||||
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0xa413fec0,
|
||||
.end = 0xa413fec0 + 0x1e,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
.start = 20,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = 21,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = 22,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_rtc_platform_info rtc_info = {
|
||||
.capabilities = RTC_CAP_4_DIGIT_YEAR,
|
||||
};
|
||||
|
||||
static struct platform_device rtc_device = {
|
||||
.name = "sh-rtc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
.resource = rtc_resources,
|
||||
.dev = {
|
||||
.platform_data = &rtc_info,
|
||||
},
|
||||
};
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
@@ -20,7 +152,7 @@ static struct plat_sci_port sci_platform_data[] = {
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 52, 53, 55, 54 },
|
||||
}, {
|
||||
.mapbase = 0xa4420000,
|
||||
.mapbase = 0xa4410000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 56, 57, 59, 58 },
|
||||
@@ -40,6 +172,7 @@ static struct platform_device sci_device = {
|
||||
|
||||
static struct platform_device *sh7710_devices[] __initdata = {
|
||||
&sci_device,
|
||||
&rtc_device,
|
||||
};
|
||||
|
||||
static int __init sh7710_devices_setup(void)
|
||||
@@ -49,59 +182,16 @@ static int __init sh7710_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7710_devices_setup);
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
|
||||
{ 18, 0, 4, 2 }, /* TMU2 TUNI */
|
||||
{ 27, 1, 12, 2 }, /* WDT ITI */
|
||||
{ 20, 0, 0, 2 }, /* RTC ATI (alarm) */
|
||||
{ 21, 0, 0, 2 }, /* RTC PRI (period) */
|
||||
{ 22, 0, 0, 2 }, /* RTC CUI (carry) */
|
||||
{ 48, 4, 12, 7 }, /* DMAC DMTE0 */
|
||||
{ 49, 4, 12, 7 }, /* DMAC DMTE1 */
|
||||
{ 50, 4, 12, 7 }, /* DMAC DMTE2 */
|
||||
{ 51, 4, 12, 7 }, /* DMAC DMTE3 */
|
||||
{ 52, 4, 8, 3 }, /* SCIF0 ERI */
|
||||
{ 53, 4, 8, 3 }, /* SCIF0 RXI */
|
||||
{ 54, 4, 8, 3 }, /* SCIF0 BRI */
|
||||
{ 55, 4, 8, 3 }, /* SCIF0 TXI */
|
||||
{ 56, 4, 4, 3 }, /* SCIF1 ERI */
|
||||
{ 57, 4, 4, 3 }, /* SCIF1 RXI */
|
||||
{ 58, 4, 4, 3 }, /* SCIF1 BRI */
|
||||
{ 59, 4, 4, 3 }, /* SCIF1 TXI */
|
||||
{ 76, 5, 8, 7 }, /* DMAC DMTE4 */
|
||||
{ 77, 5, 8, 7 }, /* DMAC DMTE5 */
|
||||
{ 80, 6, 12, 5 }, /* EDMAC EINT0 */
|
||||
{ 81, 6, 8, 5 }, /* EDMAC EINT1 */
|
||||
{ 82, 6, 4, 5 }, /* EDMAC EINT2 */
|
||||
};
|
||||
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xA414FEE2, /* 0: IPRA */
|
||||
0xA414FEE4, /* 1: IPRB */
|
||||
0xA4140016, /* 2: IPRC */
|
||||
0xA4140018, /* 3: IPRD */
|
||||
0xA414001A, /* 4: IPRE */
|
||||
0xA4080000, /* 5: IPRF */
|
||||
0xA4080002, /* 6: IPRG */
|
||||
0xA4080004, /* 7: IPRH */
|
||||
0xA4080006, /* 8: IPRI */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7710",
|
||||
},
|
||||
};
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
if (mode == IRQ_MODE_IRQ) {
|
||||
register_intc_controller(&intc_desc_irq);
|
||||
return;
|
||||
}
|
||||
BUG();
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
210
arch/sh/kernel/cpu/sh3/setup-sh7720.c
Normal file
210
arch/sh/kernel/cpu/sh3/setup-sh7720.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* SH7720 Setup
|
||||
*
|
||||
* Copyright (C) 2007 Markus Brunner, Mark Jonas
|
||||
*
|
||||
* Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c:
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006 Jamie Lenehan
|
||||
*
|
||||
* 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/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/sci.h>
|
||||
#include <asm/rtc.h>
|
||||
|
||||
#define INTC_ICR1 0xA4140010UL
|
||||
#define INTC_ICR_IRLM 0x4000
|
||||
#define INTC_ICR_IRQ (~INTC_ICR_IRLM)
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0xa413fec0,
|
||||
.end = 0xa413fec0 + 0x28 - 1,
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
[1] = {
|
||||
/* Period IRQ */
|
||||
.start = 21,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
/* Carry IRQ */
|
||||
.start = 22,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
/* Alarm IRQ */
|
||||
.start = 20,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct sh_rtc_platform_info rtc_info = {
|
||||
.capabilities = RTC_CAP_4_DIGIT_YEAR,
|
||||
};
|
||||
|
||||
static struct platform_device rtc_device = {
|
||||
.name = "sh-rtc",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
.resource = rtc_resources,
|
||||
.dev = {
|
||||
.platform_data = &rtc_info,
|
||||
},
|
||||
};
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xa4430000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 80, 80, 80, 80 },
|
||||
}, {
|
||||
.mapbase = 0xa4438000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 81, 81, 81, 81 },
|
||||
}, {
|
||||
|
||||
.flags = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_device sci_device = {
|
||||
.name = "sh-sci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = sci_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *sh7720_devices[] __initdata = {
|
||||
&rtc_device,
|
||||
&sci_device,
|
||||
};
|
||||
|
||||
static int __init sh7720_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(sh7720_devices,
|
||||
ARRAY_SIZE(sh7720_devices));
|
||||
}
|
||||
__initcall(sh7720_devices_setup);
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
TMU0, TMU1, TMU2, RTC_ATI, RTC_PRI, RTC_CUI,
|
||||
WDT, REF_RCMI, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
|
||||
IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
USBF_SPD, TMU_SUNI, IRQ5, IRQ4,
|
||||
DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3, LCDC, SSL,
|
||||
ADC, DMAC2_DEI4, DMAC2_DEI5, USBFI0, USBFI1, CMT,
|
||||
SCIF0, SCIF1,
|
||||
PINT07, PINT815, TPU0, TPU1, TPU2, TPU3, IIC,
|
||||
SIOF0, SIOF1, MMCI0, MMCI1, MMCI2, MMCI3, PCC,
|
||||
USBHI, AFEIF,
|
||||
H_UDI,
|
||||
/* interrupt groups */
|
||||
TMU, RTC, SIM, DMAC1, USBFI, DMAC2, USB, TPU, MMC,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480),
|
||||
INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0),
|
||||
INTC_VECT(SIM_ERI, 0x4e0), INTC_VECT(SIM_RXI, 0x500),
|
||||
INTC_VECT(SIM_TXI, 0x520), INTC_VECT(SIM_TEND, 0x540),
|
||||
INTC_VECT(WDT, 0x560), INTC_VECT(REF_RCMI, 0x580),
|
||||
/* H_UDI cannot be masked */ INTC_VECT(TMU_SUNI, 0x6c0),
|
||||
INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800),
|
||||
INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840),
|
||||
INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900),
|
||||
INTC_VECT(SSL, 0x980), INTC_VECT(USBFI0, 0xa20),
|
||||
INTC_VECT(USBFI1, 0xa40), INTC_VECT(USBHI, 0xa60),
|
||||
INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0),
|
||||
INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00),
|
||||
INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80),
|
||||
INTC_VECT(PINT815, 0xca0), INTC_VECT(SIOF0, 0xd00),
|
||||
INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU0, 0xd80),
|
||||
INTC_VECT(TPU1, 0xda0), INTC_VECT(TPU2, 0xdc0),
|
||||
INTC_VECT(TPU3, 0xde0), INTC_VECT(IIC, 0xe00),
|
||||
INTC_VECT(MMCI0, 0xe80), INTC_VECT(MMCI1, 0xea0),
|
||||
INTC_VECT(MMCI2, 0xec0), INTC_VECT(MMCI3, 0xee0),
|
||||
INTC_VECT(CMT, 0xf00), INTC_VECT(PCC, 0xf60),
|
||||
INTC_VECT(AFEIF, 0xfe0),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(TMU, TMU0, TMU1, TMU2),
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
|
||||
INTC_GROUP(DMAC1, DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3),
|
||||
INTC_GROUP(USBFI, USBFI0, USBFI1),
|
||||
INTC_GROUP(DMAC2, DMAC2_DEI4, DMAC2_DEI5),
|
||||
INTC_GROUP(TPU, TPU0, TPU1, TPU2, TPU3),
|
||||
INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF0, 2),
|
||||
INTC_PRIO(SCIF1, 2),
|
||||
INTC_PRIO(DMAC1, 1),
|
||||
INTC_PRIO(DMAC2, 1),
|
||||
INTC_PRIO(RTC, 2),
|
||||
INTC_PRIO(TMU, 2),
|
||||
INTC_PRIO(TPU, 2),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
|
||||
{ 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
|
||||
{ 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } },
|
||||
{ 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } },
|
||||
{ 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } },
|
||||
{ 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } },
|
||||
{ 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } },
|
||||
{ 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } },
|
||||
{ 0xA4080006UL, 0, 16, 4, /* IPRI */ { SIOF0, SIOF1, MMC, PCC } },
|
||||
{ 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
|
||||
priorities, NULL, prio_registers, NULL);
|
||||
|
||||
static struct intc_sense_reg sense_registers[] __initdata = {
|
||||
{ INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } },
|
||||
};
|
||||
|
||||
static struct intc_vect vectors_irq[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
|
||||
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
|
||||
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq,
|
||||
NULL, priorities, NULL, prio_registers, sense_registers);
|
||||
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case IRQ_MODE_IRQ:
|
||||
ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1);
|
||||
register_intc_controller(&intc_irq_desc);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* CPU Subtype Probing for SH-4.
|
||||
*
|
||||
* Copyright (C) 2001 - 2006 Paul Mundt
|
||||
* Copyright (C) 2001 - 2007 Paul Mundt
|
||||
* Copyright (C) 2003 Richard Curnow
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
@@ -12,7 +12,6 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
@@ -36,37 +35,34 @@ int __init detect_cpu_and_cache_system(void)
|
||||
/*
|
||||
* Setup some sane SH-4 defaults for the icache
|
||||
*/
|
||||
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;
|
||||
boot_cpu_data.icache.way_incr = (1 << 13);
|
||||
boot_cpu_data.icache.entry_shift = 5;
|
||||
boot_cpu_data.icache.sets = 256;
|
||||
boot_cpu_data.icache.ways = 1;
|
||||
boot_cpu_data.icache.linesz = L1_CACHE_BYTES;
|
||||
|
||||
/*
|
||||
* And again for the dcache ..
|
||||
*/
|
||||
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;
|
||||
boot_cpu_data.dcache.way_incr = (1 << 14);
|
||||
boot_cpu_data.dcache.entry_shift = 5;
|
||||
boot_cpu_data.dcache.sets = 512;
|
||||
boot_cpu_data.dcache.ways = 1;
|
||||
boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
|
||||
|
||||
/*
|
||||
* Setup some generic flags we can probe
|
||||
* (L2 and DSP detection only work on SH-4A)
|
||||
* Setup some generic flags we can probe on SH-4A parts
|
||||
*/
|
||||
if (((pvr >> 16) & 0xff) == 0x10) {
|
||||
if ((cvr & 0x02000000) == 0)
|
||||
current_cpu_data.flags |= CPU_HAS_L2_CACHE;
|
||||
if ((cvr & 0x10000000) == 0)
|
||||
current_cpu_data.flags |= CPU_HAS_DSP;
|
||||
boot_cpu_data.flags |= CPU_HAS_DSP;
|
||||
|
||||
current_cpu_data.flags |= CPU_HAS_LLSC;
|
||||
boot_cpu_data.flags |= CPU_HAS_LLSC;
|
||||
}
|
||||
|
||||
/* FPU detection works for everyone */
|
||||
if ((cvr & 0x20000000) == 1)
|
||||
current_cpu_data.flags |= CPU_HAS_FPU;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU;
|
||||
|
||||
/* Mask off the upper chip ID */
|
||||
pvr &= 0xffff;
|
||||
@@ -77,140 +73,140 @@ int __init detect_cpu_and_cache_system(void)
|
||||
*/
|
||||
switch (pvr) {
|
||||
case 0x205:
|
||||
current_cpu_data.type = CPU_SH7750;
|
||||
current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
|
||||
boot_cpu_data.type = CPU_SH7750;
|
||||
boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
|
||||
CPU_HAS_PERF_COUNTER;
|
||||
break;
|
||||
case 0x206:
|
||||
current_cpu_data.type = CPU_SH7750S;
|
||||
current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
|
||||
boot_cpu_data.type = CPU_SH7750S;
|
||||
boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
|
||||
CPU_HAS_PERF_COUNTER;
|
||||
break;
|
||||
case 0x1100:
|
||||
current_cpu_data.type = CPU_SH7751;
|
||||
current_cpu_data.flags |= CPU_HAS_FPU;
|
||||
boot_cpu_data.type = CPU_SH7751;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x2001:
|
||||
case 0x2004:
|
||||
current_cpu_data.type = CPU_SH7770;
|
||||
current_cpu_data.icache.ways = 4;
|
||||
current_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.type = CPU_SH7770;
|
||||
boot_cpu_data.icache.ways = 4;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
|
||||
current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
|
||||
break;
|
||||
case 0x2006:
|
||||
case 0x200A:
|
||||
if (prr == 0x61)
|
||||
current_cpu_data.type = CPU_SH7781;
|
||||
boot_cpu_data.type = CPU_SH7781;
|
||||
else
|
||||
current_cpu_data.type = CPU_SH7780;
|
||||
boot_cpu_data.type = CPU_SH7780;
|
||||
|
||||
current_cpu_data.icache.ways = 4;
|
||||
current_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.icache.ways = 4;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
|
||||
current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
|
||||
CPU_HAS_LLSC;
|
||||
break;
|
||||
case 0x3000:
|
||||
case 0x3003:
|
||||
case 0x3009:
|
||||
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;
|
||||
boot_cpu_data.type = CPU_SH7343;
|
||||
boot_cpu_data.icache.ways = 4;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.flags |= CPU_HAS_LLSC;
|
||||
break;
|
||||
case 0x3004:
|
||||
case 0x3007:
|
||||
current_cpu_data.type = CPU_SH7785;
|
||||
current_cpu_data.icache.ways = 4;
|
||||
current_cpu_data.dcache.ways = 4;
|
||||
current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
|
||||
boot_cpu_data.type = CPU_SH7785;
|
||||
boot_cpu_data.icache.ways = 4;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
|
||||
CPU_HAS_LLSC;
|
||||
break;
|
||||
case 0x3008:
|
||||
if (prr == 0xa0) {
|
||||
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;
|
||||
boot_cpu_data.type = CPU_SH7722;
|
||||
boot_cpu_data.icache.ways = 4;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.flags |= CPU_HAS_LLSC;
|
||||
}
|
||||
break;
|
||||
case 0x4000: /* 1st cut */
|
||||
case 0x4001: /* 2nd cut */
|
||||
current_cpu_data.type = CPU_SHX3;
|
||||
current_cpu_data.icache.ways = 4;
|
||||
current_cpu_data.dcache.ways = 4;
|
||||
current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
|
||||
boot_cpu_data.type = CPU_SHX3;
|
||||
boot_cpu_data.icache.ways = 4;
|
||||
boot_cpu_data.dcache.ways = 4;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
|
||||
CPU_HAS_LLSC;
|
||||
break;
|
||||
case 0x8000:
|
||||
current_cpu_data.type = CPU_ST40RA;
|
||||
current_cpu_data.flags |= CPU_HAS_FPU;
|
||||
boot_cpu_data.type = CPU_ST40RA;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x8100:
|
||||
current_cpu_data.type = CPU_ST40GX1;
|
||||
current_cpu_data.flags |= CPU_HAS_FPU;
|
||||
boot_cpu_data.type = CPU_ST40GX1;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x700:
|
||||
current_cpu_data.type = CPU_SH4_501;
|
||||
current_cpu_data.icache.ways = 2;
|
||||
current_cpu_data.dcache.ways = 2;
|
||||
boot_cpu_data.type = CPU_SH4_501;
|
||||
boot_cpu_data.icache.ways = 2;
|
||||
boot_cpu_data.dcache.ways = 2;
|
||||
break;
|
||||
case 0x600:
|
||||
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;
|
||||
boot_cpu_data.type = CPU_SH4_202;
|
||||
boot_cpu_data.icache.ways = 2;
|
||||
boot_cpu_data.dcache.ways = 2;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU;
|
||||
break;
|
||||
case 0x500 ... 0x501:
|
||||
switch (prr) {
|
||||
case 0x10:
|
||||
current_cpu_data.type = CPU_SH7750R;
|
||||
boot_cpu_data.type = CPU_SH7750R;
|
||||
break;
|
||||
case 0x11:
|
||||
current_cpu_data.type = CPU_SH7751R;
|
||||
boot_cpu_data.type = CPU_SH7751R;
|
||||
break;
|
||||
case 0x50 ... 0x5f:
|
||||
current_cpu_data.type = CPU_SH7760;
|
||||
boot_cpu_data.type = CPU_SH7760;
|
||||
break;
|
||||
}
|
||||
|
||||
current_cpu_data.icache.ways = 2;
|
||||
current_cpu_data.dcache.ways = 2;
|
||||
boot_cpu_data.icache.ways = 2;
|
||||
boot_cpu_data.dcache.ways = 2;
|
||||
|
||||
current_cpu_data.flags |= CPU_HAS_FPU;
|
||||
boot_cpu_data.flags |= CPU_HAS_FPU;
|
||||
|
||||
break;
|
||||
default:
|
||||
current_cpu_data.type = CPU_SH_NONE;
|
||||
boot_cpu_data.type = CPU_SH_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SH_DIRECT_MAPPED
|
||||
current_cpu_data.icache.ways = 1;
|
||||
current_cpu_data.dcache.ways = 1;
|
||||
boot_cpu_data.icache.ways = 1;
|
||||
boot_cpu_data.dcache.ways = 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_PTEA
|
||||
current_cpu_data.flags |= CPU_HAS_PTEA;
|
||||
boot_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 (current_cpu_data.icache.ways > 1) {
|
||||
if (boot_cpu_data.icache.ways > 1) {
|
||||
size = sizes[(cvr >> 20) & 0xf];
|
||||
current_cpu_data.icache.way_incr = (size >> 1);
|
||||
current_cpu_data.icache.sets = (size >> 6);
|
||||
boot_cpu_data.icache.way_incr = (size >> 1);
|
||||
boot_cpu_data.icache.sets = (size >> 6);
|
||||
|
||||
}
|
||||
|
||||
/* And the rest of the D-cache */
|
||||
if (current_cpu_data.dcache.ways > 1) {
|
||||
if (boot_cpu_data.dcache.ways > 1) {
|
||||
size = sizes[(cvr >> 16) & 0xf];
|
||||
current_cpu_data.dcache.way_incr = (size >> 1);
|
||||
current_cpu_data.dcache.sets = (size >> 6);
|
||||
boot_cpu_data.dcache.way_incr = (size >> 1);
|
||||
boot_cpu_data.dcache.sets = (size >> 6);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -218,7 +214,7 @@ int __init detect_cpu_and_cache_system(void)
|
||||
*
|
||||
* SH-4A's have an optional PIPT L2.
|
||||
*/
|
||||
if (current_cpu_data.flags & CPU_HAS_L2_CACHE) {
|
||||
if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
|
||||
/*
|
||||
* Size calculation is much more sensible
|
||||
* than it is for the L1.
|
||||
@@ -229,22 +225,22 @@ int __init detect_cpu_and_cache_system(void)
|
||||
|
||||
BUG_ON(!size);
|
||||
|
||||
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;
|
||||
boot_cpu_data.scache.way_incr = (1 << 16);
|
||||
boot_cpu_data.scache.entry_shift = 5;
|
||||
boot_cpu_data.scache.ways = 4;
|
||||
boot_cpu_data.scache.linesz = L1_CACHE_BYTES;
|
||||
|
||||
current_cpu_data.scache.entry_mask =
|
||||
(current_cpu_data.scache.way_incr -
|
||||
current_cpu_data.scache.linesz);
|
||||
boot_cpu_data.scache.entry_mask =
|
||||
(boot_cpu_data.scache.way_incr -
|
||||
boot_cpu_data.scache.linesz);
|
||||
|
||||
current_cpu_data.scache.sets = size /
|
||||
(current_cpu_data.scache.linesz *
|
||||
current_cpu_data.scache.ways);
|
||||
boot_cpu_data.scache.sets = size /
|
||||
(boot_cpu_data.scache.linesz *
|
||||
boot_cpu_data.scache.ways);
|
||||
|
||||
current_cpu_data.scache.way_size =
|
||||
(current_cpu_data.scache.sets *
|
||||
current_cpu_data.scache.linesz);
|
||||
boot_cpu_data.scache.way_size =
|
||||
(boot_cpu_data.scache.sets *
|
||||
boot_cpu_data.scache.linesz);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -104,7 +104,7 @@ enum {
|
||||
DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] = {
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
|
||||
@@ -118,7 +118,7 @@ static struct intc_vect vectors[] = {
|
||||
INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] = {
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
|
||||
@@ -126,20 +126,20 @@ static struct intc_group groups[] = {
|
||||
INTC_GROUP(REF, REF_RCMI, REF_ROVI),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] = {
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF, 3),
|
||||
INTC_PRIO(SCI1, 3),
|
||||
INTC_PRIO(DMAC, 7),
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] = {
|
||||
{ 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
|
||||
{ 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
|
||||
{ 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
|
||||
{ 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
|
||||
{ 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
|
||||
TMU4, TMU3,
|
||||
PCIC1, PCIC0_PCISERR } },
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
|
||||
{ 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
|
||||
{ 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
|
||||
{ 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
|
||||
{ 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
|
||||
TMU4, TMU3,
|
||||
PCIC1, PCIC0_PCISERR } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
|
||||
@@ -150,13 +150,13 @@ static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7091)
|
||||
static struct intc_vect vectors_dma4[] = {
|
||||
static struct intc_vect vectors_dma4[] __initdata = {
|
||||
INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
|
||||
INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
|
||||
INTC_VECT(DMAC_DMAE, 0x6c0),
|
||||
};
|
||||
|
||||
static struct intc_group groups_dma4[] = {
|
||||
static struct intc_group groups_dma4[] __initdata = {
|
||||
INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
|
||||
DMAC_DMTE3, DMAC_DMAE),
|
||||
};
|
||||
@@ -168,7 +168,7 @@ static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
|
||||
|
||||
/* SH7750R and SH7751R both have 8-channel DMA controllers */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
|
||||
static struct intc_vect vectors_dma8[] = {
|
||||
static struct intc_vect vectors_dma8[] __initdata = {
|
||||
INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
|
||||
INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
|
||||
INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
|
||||
@@ -176,7 +176,7 @@ static struct intc_vect vectors_dma8[] = {
|
||||
INTC_VECT(DMAC_DMAE, 0x6c0),
|
||||
};
|
||||
|
||||
static struct intc_group groups_dma8[] = {
|
||||
static struct intc_group groups_dma8[] __initdata = {
|
||||
INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
|
||||
DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
|
||||
DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
|
||||
@@ -191,11 +191,11 @@ static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7751R)
|
||||
static struct intc_vect vectors_tmu34[] = {
|
||||
static struct intc_vect vectors_tmu34[] __initdata = {
|
||||
INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] = {
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, TMU4, TMU3,
|
||||
@@ -210,7 +210,7 @@ static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34",
|
||||
#endif
|
||||
|
||||
/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
|
||||
static struct intc_vect vectors_irlm[] = {
|
||||
static struct intc_vect vectors_irlm[] __initdata = {
|
||||
INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
|
||||
INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
|
||||
};
|
||||
@@ -220,14 +220,14 @@ static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL,
|
||||
|
||||
/* SH7751 and SH7751R both have PCI */
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
|
||||
static struct intc_vect vectors_pci[] = {
|
||||
static struct intc_vect vectors_pci[] __initdata = {
|
||||
INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
|
||||
INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
|
||||
INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
|
||||
INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
|
||||
};
|
||||
|
||||
static struct intc_group groups_pci[] = {
|
||||
static struct intc_group groups_pci[] __initdata = {
|
||||
INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
|
||||
PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
|
||||
};
|
||||
@@ -282,13 +282,19 @@ void __init plat_irq_setup(void)
|
||||
#define INTC_ICR 0xffd00000UL
|
||||
#define INTC_ICR_IRLM (1<<7)
|
||||
|
||||
/* enable individual interrupt mode for external interupts */
|
||||
void __init ipr_irq_enable_irlm(void)
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091)
|
||||
BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */
|
||||
return;
|
||||
#endif
|
||||
register_intc_controller(&intc_desc_irlm);
|
||||
|
||||
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
|
||||
switch (mode) {
|
||||
case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */
|
||||
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
|
||||
register_intc_controller(&intc_desc_irlm);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,136 @@
|
||||
#include <linux/serial.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRL0, IRL1, IRL2, IRL3,
|
||||
HUDI, GPIOI,
|
||||
DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
|
||||
DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
|
||||
DMAC_DMAE,
|
||||
IRQ4, IRQ5, IRQ6, IRQ7,
|
||||
HCAN20, HCAN21,
|
||||
SSI0, SSI1,
|
||||
HAC0, HAC1,
|
||||
I2C0, I2C1,
|
||||
USB, LCDC,
|
||||
DMABRG0, DMABRG1, DMABRG2,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
|
||||
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
|
||||
SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
|
||||
HSPI,
|
||||
MMCIF0, MMCIF1, MMCIF2, MMCIF3,
|
||||
MFI, ADC, CMT,
|
||||
TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
|
||||
WDT,
|
||||
REF_RCMI, REF_ROVI,
|
||||
|
||||
/* interrupt groups */
|
||||
DMAC, DMABRG, SCIF0, SCIF1, SCIF2, SIM, MMCIF, TMU2, REF,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
|
||||
INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
|
||||
INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
|
||||
INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
|
||||
INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
|
||||
INTC_VECT(DMAC_DMAE, 0x6c0),
|
||||
INTC_VECT(IRQ4, 0x800), INTC_VECT(IRQ5, 0x820),
|
||||
INTC_VECT(IRQ6, 0x840), INTC_VECT(IRQ6, 0x860),
|
||||
INTC_VECT(HCAN20, 0x900), INTC_VECT(HCAN21, 0x920),
|
||||
INTC_VECT(SSI0, 0x940), INTC_VECT(SSI1, 0x960),
|
||||
INTC_VECT(HAC0, 0x980), INTC_VECT(HAC1, 0x9a0),
|
||||
INTC_VECT(I2C0, 0x9c0), INTC_VECT(I2C1, 0x9e0),
|
||||
INTC_VECT(USB, 0xa00), INTC_VECT(LCDC, 0xa20),
|
||||
INTC_VECT(DMABRG0, 0xa80), INTC_VECT(DMABRG1, 0xaa0),
|
||||
INTC_VECT(DMABRG2, 0xac0),
|
||||
INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
|
||||
INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
|
||||
INTC_VECT(SCIF1_ERI, 0xb00), INTC_VECT(SCIF1_RXI, 0xb20),
|
||||
INTC_VECT(SCIF1_BRI, 0xb40), INTC_VECT(SCIF1_TXI, 0xb60),
|
||||
INTC_VECT(SCIF2_ERI, 0xb80), INTC_VECT(SCIF2_RXI, 0xba0),
|
||||
INTC_VECT(SCIF2_BRI, 0xbc0), INTC_VECT(SCIF2_TXI, 0xbe0),
|
||||
INTC_VECT(SIM_ERI, 0xc00), INTC_VECT(SIM_RXI, 0xc20),
|
||||
INTC_VECT(SIM_TXI, 0xc40), INTC_VECT(SIM_TEI, 0xc60),
|
||||
INTC_VECT(HSPI, 0xc80),
|
||||
INTC_VECT(MMCIF0, 0xd00), INTC_VECT(MMCIF1, 0xd20),
|
||||
INTC_VECT(MMCIF2, 0xd40), INTC_VECT(MMCIF3, 0xd60),
|
||||
INTC_VECT(MFI, 0xe80), /* 0xf80 according to data sheet */
|
||||
INTC_VECT(ADC, 0xf80), INTC_VECT(CMT, 0xfa0),
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
|
||||
INTC_VECT(WDT, 0x560),
|
||||
INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
|
||||
DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
|
||||
DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
|
||||
INTC_GROUP(DMABRG, DMABRG0, DMABRG1, DMABRG2),
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
|
||||
INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
|
||||
INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI),
|
||||
INTC_GROUP(MMCIF, MMCIF0, MMCIF1, MMCIF2, MMCIF3),
|
||||
INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
|
||||
INTC_GROUP(REF, REF_RCMI, REF_ROVI),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
INTC_PRIO(SCIF1, 3),
|
||||
INTC_PRIO(SCIF2, 3),
|
||||
INTC_PRIO(SIM, 3),
|
||||
INTC_PRIO(DMAC, 7),
|
||||
INTC_PRIO(DMABRG, 13),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
|
||||
{ IRQ4, IRQ5, IRQ6, IRQ7, 0, 0, HCAN20, HCAN21,
|
||||
SSI0, SSI1, HAC0, HAC1, I2C0, I2C1, USB, LCDC,
|
||||
0, DMABRG0, DMABRG1, DMABRG2,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
|
||||
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI, } },
|
||||
{ 0xfe080044, 0xfe080064, 32, /* INTMSK04 / INTMSKCLR04 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI,
|
||||
HSPI, MMCIF0, MMCIF1, MMCIF2,
|
||||
MMCIF3, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, MFI, 0, 0, 0, 0, ADC, CMT, } },
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } },
|
||||
{ 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
|
||||
{ 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, 0, HUDI } },
|
||||
{ 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
|
||||
{ 0xfe080000, 0, 32, 4, /* INTPRI00 */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
{ 0xfe080004, 0, 32, 4, /* INTPRI04 */ { HCAN20, HCAN21, SSI0, SSI1,
|
||||
HAC0, HAC1, I2C0, I2C1 } },
|
||||
{ 0xfe080008, 0, 32, 4, /* INTPRI08 */ { USB, LCDC, DMABRG, SCIF0,
|
||||
SCIF1, SCIF2, SIM, HSPI } },
|
||||
{ 0xfe08000c, 0, 32, 4, /* INTPRI0C */ { 0, 0, MMCIF, 0,
|
||||
MFI, 0, ADC, CMT } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups,
|
||||
priorities, mask_registers, prio_registers, NULL);
|
||||
|
||||
static struct intc_vect vectors_irq[] __initdata = {
|
||||
INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
|
||||
INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq, "sh7760-irq", vectors_irq, groups,
|
||||
priorities, mask_registers, prio_registers, NULL);
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xfe600000,
|
||||
@@ -28,6 +158,11 @@ static struct plat_sci_port sci_platform_data[] = {
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 76, 77, 79, 78 },
|
||||
}, {
|
||||
.mapbase = 0xfe480000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCI,
|
||||
.irqs = { 80, 81, 82, 0 },
|
||||
}, {
|
||||
.flags = 0,
|
||||
}
|
||||
@@ -52,114 +187,18 @@ static int __init sh7760_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7760_devices_setup);
|
||||
|
||||
static struct intc2_data intc2_irq_table[] = {
|
||||
{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 */
|
||||
{56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */
|
||||
{57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */
|
||||
{58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */
|
||||
{59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */
|
||||
{60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */
|
||||
{61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */
|
||||
{62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */
|
||||
{63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */
|
||||
{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 */
|
||||
{68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */
|
||||
{69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */
|
||||
{70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */
|
||||
{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 */
|
||||
{75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */
|
||||
{76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */
|
||||
{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 */
|
||||
{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 */
|
||||
{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 */
|
||||
{108,12, 4, 4, 1, 3}, /* ADC */
|
||||
{109,12, 0, 4, 0, 3}, /* CMTI */
|
||||
};
|
||||
|
||||
static struct intc2_desc intc2_irq_desc __read_mostly = {
|
||||
.prio_base = 0xfe080000,
|
||||
.msk_base = 0xfe080040,
|
||||
.mskclr_base = 0xfe080060,
|
||||
|
||||
.intc2_data = intc2_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(intc2_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "INTC2-sh7760",
|
||||
},
|
||||
};
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* 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 */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7760",
|
||||
},
|
||||
};
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case IRQ_MODE_IRQ:
|
||||
register_intc_controller(&intc_desc_irq);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
@@ -58,11 +58,11 @@ do { \
|
||||
*/
|
||||
void sq_flush_range(unsigned long start, unsigned int len)
|
||||
{
|
||||
volatile unsigned long *sq = (unsigned long *)start;
|
||||
unsigned long *sq = (unsigned long *)start;
|
||||
|
||||
/* Flush the queues */
|
||||
for (len >>= 5; len--; sq += 8)
|
||||
prefetchw((void *)sq);
|
||||
prefetchw(sq);
|
||||
|
||||
/* Wait for completion */
|
||||
store_queue_barrier();
|
||||
|
@@ -10,6 +10,9 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
|
||||
|
||||
# SMP setup
|
||||
smp-$(CONFIG_CPU_SUBTYPE_SHX3) := smp-shx3.o
|
||||
|
||||
# Primary on-chip clocks (common)
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
|
||||
@@ -18,4 +21,5 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
|
||||
|
||||
obj-y += $(clock-y)
|
||||
obj-y += $(clock-y)
|
||||
obj-$(CONFIG_SMP) += $(smp-y)
|
||||
|
@@ -41,3 +41,7 @@ static int __init sh7343_devices_setup(void)
|
||||
ARRAY_SIZE(sh7343_devices));
|
||||
}
|
||||
__initcall(sh7343_devices_setup);
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
}
|
||||
|
@@ -84,7 +84,7 @@ enum {
|
||||
SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] = {
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620),
|
||||
INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660),
|
||||
INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0),
|
||||
@@ -117,7 +117,7 @@ static struct intc_vect vectors[] = {
|
||||
INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] = {
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI),
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3),
|
||||
@@ -130,7 +130,7 @@ static struct intc_group groups[] = {
|
||||
INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] = {
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
INTC_PRIO(SCIF1, 3),
|
||||
INTC_PRIO(SCIF2, 3),
|
||||
@@ -138,7 +138,7 @@ static struct intc_prio priorities[] = {
|
||||
INTC_PRIO(TMU1, 2),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] = {
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
|
||||
{ } },
|
||||
{ 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
|
||||
@@ -168,24 +168,24 @@ static struct intc_mask_reg mask_registers[] = {
|
||||
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] = {
|
||||
{ 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } },
|
||||
{ 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } },
|
||||
{ 0xa4080008, 16, 4, /* IPRC */ { } },
|
||||
{ 0xa408000c, 16, 4, /* IPRD */ { } },
|
||||
{ 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } },
|
||||
{ 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } },
|
||||
{ 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } },
|
||||
{ 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } },
|
||||
{ 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } },
|
||||
{ 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } },
|
||||
{ 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } },
|
||||
{ 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } },
|
||||
{ 0xa4140010, 32, 4, /* INTPRI00 */
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } },
|
||||
{ 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } },
|
||||
{ 0xa4080008, 0, 16, 4, /* IPRC */ { } },
|
||||
{ 0xa408000c, 0, 16, 4, /* IPRD */ { } },
|
||||
{ 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } },
|
||||
{ 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } },
|
||||
{ 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } },
|
||||
{ 0xa408001c, 0, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } },
|
||||
{ 0xa4080020, 0, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } },
|
||||
{ 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } },
|
||||
{ 0xa4080028, 0, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } },
|
||||
{ 0xa408002c, 0, 16, 4, /* IPRL */ { TWODG, 0, TPU } },
|
||||
{ 0xa4140010, 0, 32, 4, /* INTPRI00 */
|
||||
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
|
||||
static struct intc_sense_reg sense_registers[] = {
|
||||
static struct intc_sense_reg sense_registers[] __initdata = {
|
||||
{ 0xa414001c, 16, 2, /* ICR1 */
|
||||
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
|
@@ -51,3 +51,7 @@ static int __init sh7770_devices_setup(void)
|
||||
ARRAY_SIZE(sh7770_devices));
|
||||
}
|
||||
__initcall(sh7770_devices_setup);
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct resource rtc_resources[] = {
|
||||
@@ -114,7 +115,7 @@ enum {
|
||||
PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO,
|
||||
};
|
||||
|
||||
static struct intc_vect vectors[] = {
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
|
||||
INTC_VECT(RTC_CUI, 0x4c0),
|
||||
INTC_VECT(WDT, 0x560),
|
||||
@@ -150,7 +151,7 @@ static struct intc_vect vectors[] = {
|
||||
INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] = {
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
|
||||
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
|
||||
INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
|
||||
@@ -167,12 +168,12 @@ static struct intc_group groups[] = {
|
||||
INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] = {
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
INTC_PRIO(SCIF1, 3),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] = {
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
|
||||
{ 0, 0, 0, 0, 0, 0, GPIO, FLCTL,
|
||||
SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
|
||||
@@ -180,16 +181,18 @@ static struct intc_mask_reg mask_registers[] = {
|
||||
HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] = {
|
||||
{ 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } },
|
||||
{ 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
|
||||
{ 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
|
||||
{ 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },
|
||||
{ 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } },
|
||||
{ 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
|
||||
PCIINTD, PCIC5 } },
|
||||
{ 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },
|
||||
{ 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
|
||||
TMU2, TMU2_TICPI } },
|
||||
{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },
|
||||
{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },
|
||||
{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },
|
||||
{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,
|
||||
PCISERR, PCIINTA, } },
|
||||
{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,
|
||||
PCIINTD, PCIC5 } },
|
||||
{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },
|
||||
{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities,
|
||||
@@ -197,24 +200,24 @@ static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities,
|
||||
|
||||
/* Support for external interrupt pins in IRQ mode */
|
||||
|
||||
static struct intc_vect irq_vectors[] = {
|
||||
static struct intc_vect irq_vectors[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
|
||||
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
|
||||
INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
|
||||
INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg irq_mask_registers[] = {
|
||||
static struct intc_mask_reg irq_mask_registers[] __initdata = {
|
||||
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
|
||||
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
|
||||
static struct intc_prio_reg irq_prio_registers[] = {
|
||||
{ 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
static struct intc_prio_reg irq_prio_registers[] __initdata = {
|
||||
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
|
||||
static struct intc_sense_reg irq_sense_registers[] = {
|
||||
static struct intc_sense_reg irq_sense_registers[] __initdata = {
|
||||
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
@@ -225,7 +228,7 @@ static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors,
|
||||
|
||||
/* External interrupt pins in IRL mode */
|
||||
|
||||
static struct intc_vect irl_vectors[] = {
|
||||
static struct intc_vect irl_vectors[] __initdata = {
|
||||
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
|
||||
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
|
||||
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
|
||||
@@ -236,16 +239,16 @@ static struct intc_vect irl_vectors[] = {
|
||||
INTC_VECT(IRL_HHHL, 0x3c0),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg irl3210_mask_registers[] = {
|
||||
{ 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */
|
||||
static struct intc_mask_reg irl3210_mask_registers[] __initdata = {
|
||||
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
|
||||
{ IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
|
||||
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
|
||||
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
|
||||
IRL_HHLL, IRL_HHLH, IRL_HHHL, } },
|
||||
};
|
||||
|
||||
static struct intc_mask_reg irl7654_mask_registers[] = {
|
||||
{ 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */
|
||||
static struct intc_mask_reg irl7654_mask_registers[] __initdata = {
|
||||
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
|
||||
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
|
||||
@@ -259,8 +262,28 @@ static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,
|
||||
static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,
|
||||
NULL, NULL, irl3210_mask_registers, NULL, NULL);
|
||||
|
||||
#define INTC_ICR0 0xffd00000
|
||||
#define INTC_INTMSK0 0xffd00044
|
||||
#define INTC_INTMSK1 0xffd00048
|
||||
#define INTC_INTMSK2 0xffd40080
|
||||
#define INTC_INTMSKCLR1 0xffd00068
|
||||
#define INTC_INTMSKCLR2 0xffd40084
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
/* disable IRQ7-0 */
|
||||
ctrl_outl(0xff000000, INTC_INTMSK0);
|
||||
|
||||
/* disable IRL3-0 + IRL7-4 */
|
||||
ctrl_outl(0xc0000000, INTC_INTMSK1);
|
||||
ctrl_outl(0xfffefffe, INTC_INTMSK2);
|
||||
|
||||
/* select IRL mode for IRL3-0 + IRL7-4 */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
|
||||
|
||||
/* disable holding function, ie enable "SH-4 Mode" */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
|
||||
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
||||
@@ -268,12 +291,28 @@ void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case IRQ_MODE_IRQ:
|
||||
/* select IRQ mode for IRL3-0 + IRL7-4 */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0);
|
||||
register_intc_controller(&intc_irq_desc);
|
||||
break;
|
||||
case IRQ_MODE_IRL7654:
|
||||
register_intc_controller(&intc_irl7654_desc);
|
||||
/* enable IRL7-4 but don't provide any masking */
|
||||
ctrl_outl(0x40000000, INTC_INTMSKCLR1);
|
||||
ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
|
||||
break;
|
||||
case IRQ_MODE_IRL3210:
|
||||
/* enable IRL0-3 but don't provide any masking */
|
||||
ctrl_outl(0x80000000, INTC_INTMSKCLR1);
|
||||
ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
|
||||
break;
|
||||
case IRQ_MODE_IRL7654_MASK:
|
||||
/* enable IRL7-4 and mask using cpu intc controller */
|
||||
ctrl_outl(0x40000000, INTC_INTMSKCLR1);
|
||||
register_intc_controller(&intc_irl7654_desc);
|
||||
break;
|
||||
case IRQ_MODE_IRL3210_MASK:
|
||||
/* enable IRL0-3 and mask using cpu intc controller */
|
||||
ctrl_outl(0x80000000, INTC_INTMSKCLR1);
|
||||
register_intc_controller(&intc_irl3210_desc);
|
||||
break;
|
||||
default:
|
||||
|
@@ -10,6 +10,9 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/mmzone.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
@@ -72,46 +75,281 @@ static int __init sh7785_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7785_devices_setup);
|
||||
|
||||
static struct intc2_data intc2_irq_table[] = {
|
||||
{ 28, 0, 24, 0, 0, 2 }, /* TMU0 */
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
{ 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */
|
||||
{ 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */
|
||||
{ 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */
|
||||
{ 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */
|
||||
/* interrupt sources */
|
||||
|
||||
{ 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */
|
||||
{ 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */
|
||||
{ 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */
|
||||
{ 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */
|
||||
IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
|
||||
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
|
||||
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
|
||||
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
|
||||
|
||||
{ 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */
|
||||
{ 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */
|
||||
{ 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */
|
||||
{ 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */
|
||||
{ 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */
|
||||
IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
|
||||
IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
|
||||
IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
|
||||
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
|
||||
|
||||
{ 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */
|
||||
{ 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */
|
||||
{ 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */
|
||||
{ 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */
|
||||
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
|
||||
WDT,
|
||||
TMU0, TMU1, TMU2, TMU2_TICPI,
|
||||
HUDI,
|
||||
DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
|
||||
DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
|
||||
DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
|
||||
DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
|
||||
HSPI,
|
||||
SCIF2, SCIF3, SCIF4, SCIF5,
|
||||
PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
|
||||
PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
|
||||
SIOF,
|
||||
MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
|
||||
DU,
|
||||
GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI,
|
||||
TMU3, TMU4, TMU5,
|
||||
SSI0, SSI1,
|
||||
HAC0, HAC1,
|
||||
FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
|
||||
GPIOI0, GPIOI1, GPIOI2, GPIOI3,
|
||||
|
||||
/* interrupt groups */
|
||||
|
||||
TMU012, DMAC0, SCIF0, SCIF1, DMAC1,
|
||||
PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO
|
||||
};
|
||||
|
||||
static struct intc2_desc intc2_irq_desc __read_mostly = {
|
||||
.prio_base = 0xffd40000,
|
||||
.msk_base = 0xffd40038,
|
||||
.mskclr_base = 0xffd4003c,
|
||||
|
||||
.intc2_data = intc2_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(intc2_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "INTC2-sh7785",
|
||||
},
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(WDT, 0x560),
|
||||
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
|
||||
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
|
||||
INTC_VECT(HUDI, 0x600),
|
||||
INTC_VECT(DMAC0_DMINT0, 0x620), INTC_VECT(DMAC0_DMINT1, 0x640),
|
||||
INTC_VECT(DMAC0_DMINT2, 0x660), INTC_VECT(DMAC0_DMINT3, 0x680),
|
||||
INTC_VECT(DMAC0_DMINT4, 0x6a0), INTC_VECT(DMAC0_DMINT5, 0x6c0),
|
||||
INTC_VECT(DMAC0_DMAE, 0x6e0),
|
||||
INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
|
||||
INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
|
||||
INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
|
||||
INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
|
||||
INTC_VECT(DMAC1_DMINT6, 0x880), INTC_VECT(DMAC1_DMINT7, 0x8a0),
|
||||
INTC_VECT(DMAC1_DMINT8, 0x8c0), INTC_VECT(DMAC1_DMINT9, 0x8e0),
|
||||
INTC_VECT(DMAC1_DMINT10, 0x900), INTC_VECT(DMAC1_DMINT11, 0x920),
|
||||
INTC_VECT(DMAC1_DMAE, 0x940),
|
||||
INTC_VECT(HSPI, 0x960),
|
||||
INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0),
|
||||
INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0),
|
||||
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
|
||||
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
|
||||
INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
|
||||
INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
|
||||
INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
|
||||
INTC_VECT(SIOF, 0xc00),
|
||||
INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
|
||||
INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
|
||||
INTC_VECT(DU, 0xd80),
|
||||
INTC_VECT(GDTA_GACLI, 0xda0), INTC_VECT(GDTA_GAMCI, 0xdc0),
|
||||
INTC_VECT(GDTA_GAERI, 0xde0),
|
||||
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
|
||||
INTC_VECT(TMU5, 0xe40),
|
||||
INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
|
||||
INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0),
|
||||
INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
|
||||
INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
|
||||
INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
|
||||
INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
|
||||
INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
|
||||
DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
|
||||
INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
|
||||
DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE),
|
||||
INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
|
||||
INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
|
||||
INTC_GROUP(GDTA, GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI),
|
||||
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
|
||||
INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
|
||||
FLCTL_FLTRQ0, FLCTL_FLTRQ1),
|
||||
INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
INTC_PRIO(SCIF1, 3),
|
||||
INTC_PRIO(SCIF2, 3),
|
||||
INTC_PRIO(SCIF3, 3),
|
||||
INTC_PRIO(SCIF4, 3),
|
||||
INTC_PRIO(SCIF5, 3),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
|
||||
{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
|
||||
{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
|
||||
{ IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
|
||||
IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
|
||||
IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
|
||||
IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
|
||||
IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
|
||||
IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
|
||||
IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
|
||||
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
|
||||
|
||||
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
|
||||
{ 0, 0, 0, GDTA, DU, SSI0, SSI1, GPIO,
|
||||
FLCTL, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,
|
||||
PCIINTA, PCISERR, HAC1, HAC0, DMAC1, DMAC0, HUDI, WDT,
|
||||
SCIF5, SCIF4, SCIF3, SCIF2, SCIF1, SCIF0, TMU345, TMU012 } },
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,
|
||||
TMU2, TMU2_TICPI } },
|
||||
{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } },
|
||||
{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1,
|
||||
SCIF2, SCIF3 } },
|
||||
{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } },
|
||||
{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } },
|
||||
{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { HAC0, HAC1,
|
||||
PCISERR, PCIINTA } },
|
||||
{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC,
|
||||
PCIINTD, PCIC5 } },
|
||||
{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } },
|
||||
{ 0xffd40020, 0, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } },
|
||||
{ 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities,
|
||||
mask_registers, prio_registers, NULL);
|
||||
|
||||
/* Support for external interrupt pins in IRQ mode */
|
||||
|
||||
static struct intc_vect vectors_irq0123[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
|
||||
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
|
||||
};
|
||||
|
||||
static struct intc_vect vectors_irq4567[] __initdata = {
|
||||
INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
|
||||
INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
|
||||
};
|
||||
|
||||
static struct intc_sense_reg sense_registers[] __initdata = {
|
||||
{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
IRQ4, IRQ5, IRQ6, IRQ7 } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123,
|
||||
NULL, NULL, mask_registers, prio_registers,
|
||||
sense_registers);
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567,
|
||||
NULL, NULL, mask_registers, prio_registers,
|
||||
sense_registers);
|
||||
|
||||
/* External interrupt pins in IRL mode */
|
||||
|
||||
static struct intc_vect vectors_irl0123[] __initdata = {
|
||||
INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
|
||||
INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
|
||||
INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
|
||||
INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
|
||||
INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
|
||||
INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
|
||||
INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
|
||||
INTC_VECT(IRL0_HHHL, 0x3c0),
|
||||
};
|
||||
|
||||
static struct intc_vect vectors_irl4567[] __initdata = {
|
||||
INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20),
|
||||
INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60),
|
||||
INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0),
|
||||
INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0),
|
||||
INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20),
|
||||
INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60),
|
||||
INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0),
|
||||
INTC_VECT(IRL4_HHHL, 0xcc0),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123,
|
||||
NULL, NULL, mask_registers, NULL, NULL);
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567,
|
||||
NULL, NULL, mask_registers, NULL, NULL);
|
||||
|
||||
#define INTC_ICR0 0xffd00000
|
||||
#define INTC_INTMSK0 0xffd00044
|
||||
#define INTC_INTMSK1 0xffd00048
|
||||
#define INTC_INTMSK2 0xffd40080
|
||||
#define INTC_INTMSKCLR1 0xffd00068
|
||||
#define INTC_INTMSKCLR2 0xffd40084
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
/* disable IRQ3-0 + IRQ7-4 */
|
||||
ctrl_outl(0xff000000, INTC_INTMSK0);
|
||||
|
||||
/* disable IRL3-0 + IRL7-4 */
|
||||
ctrl_outl(0xc0000000, INTC_INTMSK1);
|
||||
ctrl_outl(0xfffefffe, INTC_INTMSK2);
|
||||
|
||||
/* select IRL mode for IRL3-0 + IRL7-4 */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
|
||||
|
||||
/* disable holding function, ie enable "SH-4 Mode" */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
|
||||
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case IRQ_MODE_IRQ7654:
|
||||
/* select IRQ mode for IRL7-4 */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
|
||||
register_intc_controller(&intc_desc_irq4567);
|
||||
break;
|
||||
case IRQ_MODE_IRQ3210:
|
||||
/* select IRQ mode for IRL3-0 */
|
||||
ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
|
||||
register_intc_controller(&intc_desc_irq0123);
|
||||
break;
|
||||
case IRQ_MODE_IRL7654:
|
||||
/* enable IRL7-4 but don't provide any masking */
|
||||
ctrl_outl(0x40000000, INTC_INTMSKCLR1);
|
||||
ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
|
||||
break;
|
||||
case IRQ_MODE_IRL3210:
|
||||
/* enable IRL0-3 but don't provide any masking */
|
||||
ctrl_outl(0x80000000, INTC_INTMSKCLR1);
|
||||
ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
|
||||
break;
|
||||
case IRQ_MODE_IRL7654_MASK:
|
||||
/* enable IRL7-4 and mask using cpu intc controller */
|
||||
ctrl_outl(0x40000000, INTC_INTMSKCLR1);
|
||||
register_intc_controller(&intc_desc_irl4567);
|
||||
break;
|
||||
case IRQ_MODE_IRL3210_MASK:
|
||||
/* enable IRL0-3 and mask using cpu intc controller */
|
||||
ctrl_outl(0x80000000, INTC_INTMSKCLR1);
|
||||
register_intc_controller(&intc_desc_irl0123);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
/* Register the URAM space as Node 1 */
|
||||
setup_bootmem_node(1, 0xe55f0000, 0xe5610000);
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/mmzone.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
@@ -58,28 +59,229 @@ static int __init shx3_devices_setup(void)
|
||||
}
|
||||
__initcall(shx3_devices_setup);
|
||||
|
||||
static struct intc2_data intc2_irq_table[] = {
|
||||
{ 16, 0, 0, 0, 1, 2 }, /* TMU0 */
|
||||
{ 40, 4, 0, 0x20, 0, 3 }, /* SCIF0 ERI */
|
||||
{ 41, 4, 0, 0x20, 1, 3 }, /* SCIF0 RXI */
|
||||
{ 42, 4, 0, 0x20, 2, 3 }, /* SCIF0 BRI */
|
||||
{ 43, 4, 0, 0x20, 3, 3 }, /* SCIF0 TXI */
|
||||
enum {
|
||||
UNUSED = 0,
|
||||
|
||||
/* interrupt sources */
|
||||
IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
|
||||
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
|
||||
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
|
||||
IRL_HHLL, IRL_HHLH, IRL_HHHL,
|
||||
IRQ0, IRQ1, IRQ2, IRQ3,
|
||||
HUDII,
|
||||
TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
|
||||
PCII0, PCII1, PCII2, PCII3, PCII4,
|
||||
PCII5, PCII6, PCII7, PCII8, PCII9,
|
||||
SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
|
||||
SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
|
||||
SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
|
||||
SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI,
|
||||
DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
|
||||
DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
|
||||
DU,
|
||||
DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
|
||||
DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
|
||||
IIC, VIN0, VIN1, VCORE0, ATAPI,
|
||||
DTU0_TEND, DTU0_AE, DTU0_TMISS,
|
||||
DTU1_TEND, DTU1_AE, DTU1_TMISS,
|
||||
DTU2_TEND, DTU2_AE, DTU2_TMISS,
|
||||
DTU3_TEND, DTU3_AE, DTU3_TMISS,
|
||||
FE0, FE1,
|
||||
GPIO0, GPIO1, GPIO2, GPIO3,
|
||||
PAM, IRM,
|
||||
INTICI0, INTICI1, INTICI2, INTICI3,
|
||||
INTICI4, INTICI5, INTICI6, INTICI7,
|
||||
|
||||
/* interrupt groups */
|
||||
IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
|
||||
DMAC0, DMAC1, DTU0, DTU1, DTU2, DTU3,
|
||||
};
|
||||
|
||||
static struct intc2_desc intc2_irq_desc __read_mostly = {
|
||||
.prio_base = 0xfe410000,
|
||||
.msk_base = 0xfe410820,
|
||||
.mskclr_base = 0xfe410850,
|
||||
|
||||
.intc2_data = intc2_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(intc2_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "INTC2-SHX3",
|
||||
},
|
||||
static struct intc_vect vectors[] __initdata = {
|
||||
INTC_VECT(HUDII, 0x3e0),
|
||||
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
|
||||
INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460),
|
||||
INTC_VECT(TMU4, 0x480), INTC_VECT(TMU5, 0x4a0),
|
||||
INTC_VECT(PCII0, 0x500), INTC_VECT(PCII1, 0x520),
|
||||
INTC_VECT(PCII2, 0x540), INTC_VECT(PCII3, 0x560),
|
||||
INTC_VECT(PCII4, 0x580), INTC_VECT(PCII5, 0x5a0),
|
||||
INTC_VECT(PCII6, 0x5c0), INTC_VECT(PCII7, 0x5e0),
|
||||
INTC_VECT(PCII8, 0x600), INTC_VECT(PCII9, 0x620),
|
||||
INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
|
||||
INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
|
||||
INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
|
||||
INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
|
||||
INTC_VECT(SCIF2_ERI, 0x800), INTC_VECT(SCIF2_RXI, 0x820),
|
||||
INTC_VECT(SCIF2_BRI, 0x840), INTC_VECT(SCIF2_TXI, 0x860),
|
||||
INTC_VECT(SCIF3_ERI, 0x880), INTC_VECT(SCIF3_RXI, 0x8a0),
|
||||
INTC_VECT(SCIF3_BRI, 0x8c0), INTC_VECT(SCIF3_TXI, 0x8e0),
|
||||
INTC_VECT(DMAC0_DMINT0, 0x900), INTC_VECT(DMAC0_DMINT1, 0x920),
|
||||
INTC_VECT(DMAC0_DMINT2, 0x940), INTC_VECT(DMAC0_DMINT3, 0x960),
|
||||
INTC_VECT(DMAC0_DMINT4, 0x980), INTC_VECT(DMAC0_DMINT5, 0x9a0),
|
||||
INTC_VECT(DMAC0_DMAE, 0x9c0),
|
||||
INTC_VECT(DU, 0x9e0),
|
||||
INTC_VECT(DMAC1_DMINT6, 0xa00), INTC_VECT(DMAC1_DMINT7, 0xa20),
|
||||
INTC_VECT(DMAC1_DMINT8, 0xa40), INTC_VECT(DMAC1_DMINT9, 0xa60),
|
||||
INTC_VECT(DMAC1_DMINT10, 0xa80), INTC_VECT(DMAC1_DMINT11, 0xaa0),
|
||||
INTC_VECT(DMAC1_DMAE, 0xac0),
|
||||
INTC_VECT(IIC, 0xae0),
|
||||
INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
|
||||
INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
|
||||
INTC_VECT(DTU0_TEND, 0xc00), INTC_VECT(DTU0_AE, 0xc20),
|
||||
INTC_VECT(DTU0_TMISS, 0xc40),
|
||||
INTC_VECT(DTU1_TEND, 0xc60), INTC_VECT(DTU1_AE, 0xc80),
|
||||
INTC_VECT(DTU1_TMISS, 0xca0),
|
||||
INTC_VECT(DTU2_TEND, 0xcc0), INTC_VECT(DTU2_AE, 0xce0),
|
||||
INTC_VECT(DTU2_TMISS, 0xd00),
|
||||
INTC_VECT(DTU3_TEND, 0xd20), INTC_VECT(DTU3_AE, 0xd40),
|
||||
INTC_VECT(DTU3_TMISS, 0xd60),
|
||||
INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
|
||||
INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
|
||||
INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
|
||||
INTC_VECT(PAM, 0xec0), INTC_VECT(IRM, 0xee0),
|
||||
INTC_VECT(INTICI0, 0xf00), INTC_VECT(INTICI1, 0xf20),
|
||||
INTC_VECT(INTICI2, 0xf40), INTC_VECT(INTICI3, 0xf60),
|
||||
INTC_VECT(INTICI4, 0xf80), INTC_VECT(INTICI5, 0xfa0),
|
||||
INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0),
|
||||
};
|
||||
|
||||
static struct intc_group groups[] __initdata = {
|
||||
INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
|
||||
IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
|
||||
IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
|
||||
IRL_HHLL, IRL_HHLH, IRL_HHHL),
|
||||
INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
|
||||
INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
|
||||
INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
|
||||
INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
|
||||
INTC_GROUP(SCIF3, SCIF3_ERI, SCIF3_RXI, SCIF3_BRI, SCIF3_TXI),
|
||||
INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
|
||||
DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
|
||||
INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
|
||||
DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
|
||||
INTC_GROUP(DTU0, DTU0_TEND, DTU0_AE, DTU0_TMISS),
|
||||
INTC_GROUP(DTU1, DTU1_TEND, DTU1_AE, DTU1_TMISS),
|
||||
INTC_GROUP(DTU2, DTU2_TEND, DTU2_AE, DTU2_TMISS),
|
||||
INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS),
|
||||
};
|
||||
|
||||
static struct intc_prio priorities[] __initdata = {
|
||||
INTC_PRIO(SCIF0, 3),
|
||||
INTC_PRIO(SCIF1, 3),
|
||||
INTC_PRIO(SCIF2, 3),
|
||||
INTC_PRIO(SCIF3, 3),
|
||||
};
|
||||
|
||||
static struct intc_mask_reg mask_registers[] __initdata = {
|
||||
{ 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */
|
||||
{ IRQ0, IRQ1, IRQ2, IRQ3 } },
|
||||
{ 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */
|
||||
{ IRL } },
|
||||
{ 0xfe410820, 0xfe410850, 32, /* CnINT2MSK0 / CnINT2MSKCLR0 */
|
||||
{ FE1, FE0, 0, ATAPI, VCORE0, VIN1, VIN0, IIC,
|
||||
DU, GPIO3, GPIO2, GPIO1, GPIO0, PAM, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* HUDI bits ignored */
|
||||
0, TMU5, TMU4, TMU3, TMU2, TMU1, TMU0, 0, } },
|
||||
{ 0xfe410830, 0xfe410860, 32, /* CnINT2MSK1 / CnINT2MSKCLR1 */
|
||||
{ 0, 0, 0, 0, DTU3, DTU2, DTU1, DTU0, /* IRM bits ignored */
|
||||
PCII9, PCII8, PCII7, PCII6, PCII5, PCII4, PCII3, PCII2,
|
||||
PCII1, PCII0, DMAC1_DMAE, DMAC1_DMINT11,
|
||||
DMAC1_DMINT10, DMAC1_DMINT9, DMAC1_DMINT8, DMAC1_DMINT7,
|
||||
DMAC1_DMINT6, DMAC0_DMAE, DMAC0_DMINT5, DMAC0_DMINT4,
|
||||
DMAC0_DMINT3, DMAC0_DMINT2, DMAC0_DMINT1, DMAC0_DMINT0 } },
|
||||
{ 0xfe410840, 0xfe410870, 32, /* CnINT2MSK2 / CnINT2MSKCLR2 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
SCIF3_TXI, SCIF3_BRI, SCIF3_RXI, SCIF3_ERI,
|
||||
SCIF2_TXI, SCIF2_BRI, SCIF2_RXI, SCIF2_ERI,
|
||||
SCIF1_TXI, SCIF1_BRI, SCIF1_RXI, SCIF1_ERI,
|
||||
SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } },
|
||||
};
|
||||
|
||||
static struct intc_prio_reg prio_registers[] __initdata = {
|
||||
{ 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
|
||||
|
||||
{ 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4,
|
||||
TMU3, TMU2, TMU1, TMU0 } },
|
||||
{ 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0,
|
||||
SCIF3, SCIF2,
|
||||
SCIF1, SCIF0 } },
|
||||
{ 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0,
|
||||
PCII56789, PCII4,
|
||||
PCII3, PCII2,
|
||||
PCII1, PCII0 } },
|
||||
{ 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0,
|
||||
VIN1, VIN0, IIC, DU} },
|
||||
{ 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3,
|
||||
GPIO2, GPIO1, GPIO0, IRM } },
|
||||
{ 0xfe410090, 0xfe4100a0, 32, 4, /* CnICIPRI / CnICIPRICLR */
|
||||
{ INTICI7, INTICI6, INTICI5, INTICI4,
|
||||
INTICI3, INTICI2, INTICI1, INTICI0 }, INTC_SMP(4, 4) },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, priorities,
|
||||
mask_registers, prio_registers, NULL);
|
||||
|
||||
/* Support for external interrupt pins in IRQ mode */
|
||||
static struct intc_vect vectors_irq[] __initdata = {
|
||||
INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
|
||||
INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
|
||||
};
|
||||
|
||||
static struct intc_sense_reg sense_registers[] __initdata = {
|
||||
{ 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
|
||||
priorities, mask_registers, prio_registers,
|
||||
sense_registers);
|
||||
|
||||
/* External interrupt pins in IRL mode */
|
||||
static struct intc_vect vectors_irl[] __initdata = {
|
||||
INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
|
||||
INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
|
||||
INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
|
||||
INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
|
||||
INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
|
||||
INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
|
||||
INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
|
||||
INTC_VECT(IRL_HHHL, 0x3c0),
|
||||
};
|
||||
|
||||
static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
|
||||
priorities, mask_registers, prio_registers, NULL);
|
||||
|
||||
void __init plat_irq_setup_pins(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case IRQ_MODE_IRQ:
|
||||
register_intc_controller(&intc_desc_irq);
|
||||
break;
|
||||
case IRQ_MODE_IRL3210:
|
||||
register_intc_controller(&intc_desc_irl);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
void __init plat_irq_setup(void)
|
||||
{
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
register_intc_controller(&intc_desc);
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
unsigned int nid = 1;
|
||||
|
||||
/* Register CPU#0 URAM space as Node 1 */
|
||||
setup_bootmem_node(nid++, 0x145f0000, 0x14610000); /* CPU0 */
|
||||
|
||||
#if 0
|
||||
/* XXX: Not yet.. */
|
||||
setup_bootmem_node(nid++, 0x14df0000, 0x14e10000); /* CPU1 */
|
||||
setup_bootmem_node(nid++, 0x155f0000, 0x15610000); /* CPU2 */
|
||||
setup_bootmem_node(nid++, 0x15df0000, 0x15e10000); /* CPU3 */
|
||||
#endif
|
||||
|
||||
setup_bootmem_node(nid++, 0x16000000, 0x16020000); /* CSM */
|
||||
}
|
||||
|
120
arch/sh/kernel/cpu/sh4a/smp-shx3.c
Normal file
120
arch/sh/kernel/cpu/sh4a/smp-shx3.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* SH-X3 SMP
|
||||
*
|
||||
* Copyright (C) 2007 Paul Mundt
|
||||
* Copyright (C) 2007 Magnus Damm
|
||||
*
|
||||
* 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/cpumask.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
void __init plat_smp_setup(void)
|
||||
{
|
||||
unsigned int cpu = 0;
|
||||
int i, num;
|
||||
|
||||
cpus_clear(cpu_possible_map);
|
||||
cpu_set(cpu, cpu_possible_map);
|
||||
|
||||
__cpu_number_map[0] = 0;
|
||||
__cpu_logical_map[0] = 0;
|
||||
|
||||
/*
|
||||
* Do this stupidly for now.. we don't have an easy way to probe
|
||||
* for the total number of cores.
|
||||
*/
|
||||
for (i = 1, num = 0; i < NR_CPUS; i++) {
|
||||
cpu_set(i, cpu_possible_map);
|
||||
__cpu_number_map[i] = ++num;
|
||||
__cpu_logical_map[num] = i;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
|
||||
}
|
||||
|
||||
void __init plat_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
}
|
||||
|
||||
#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
|
||||
#define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
|
||||
|
||||
#define STBCR_MSTP 0x00000001
|
||||
#define STBCR_RESET 0x00000002
|
||||
#define STBCR_LTSLP 0x80000000
|
||||
|
||||
#define STBCR_AP_VAL (STBCR_RESET | STBCR_LTSLP)
|
||||
|
||||
void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
|
||||
{
|
||||
ctrl_outl(entry_point, RESET_REG(cpu));
|
||||
|
||||
if (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
|
||||
ctrl_outl(STBCR_MSTP, STBCR_REG(cpu));
|
||||
|
||||
while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
|
||||
;
|
||||
|
||||
/* Start up secondary processor by sending a reset */
|
||||
ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu));
|
||||
}
|
||||
|
||||
int plat_smp_processor_id(void)
|
||||
{
|
||||
return ctrl_inl(0xff000048); /* CPIDR */
|
||||
}
|
||||
|
||||
void plat_send_ipi(unsigned int cpu, unsigned int message)
|
||||
{
|
||||
unsigned long addr = 0xfe410070 + (cpu * 4);
|
||||
|
||||
BUG_ON(cpu >= 4);
|
||||
BUG_ON(message >= SMP_MSG_NR);
|
||||
|
||||
ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
|
||||
}
|
||||
|
||||
struct ipi_data {
|
||||
void (*handler)(void *);
|
||||
void *arg;
|
||||
unsigned int message;
|
||||
};
|
||||
|
||||
static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
|
||||
{
|
||||
struct ipi_data *id = arg;
|
||||
unsigned int cpu = hard_smp_processor_id();
|
||||
unsigned int offs = 4 * cpu;
|
||||
unsigned int x;
|
||||
|
||||
x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
|
||||
x &= (1 << (id->message << 2));
|
||||
ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
|
||||
|
||||
id->handler(id->arg);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct ipi_data ipi_handlers[SMP_MSG_NR];
|
||||
|
||||
int plat_register_ipi_handler(unsigned int message,
|
||||
void (*handler)(void *), void *arg)
|
||||
{
|
||||
struct ipi_data *id = &ipi_handlers[message];
|
||||
|
||||
BUG_ON(SMP_MSG_NR >= 8);
|
||||
BUG_ON(message >= SMP_MSG_NR);
|
||||
|
||||
id->handler = handler;
|
||||
id->arg = arg;
|
||||
id->message = message;
|
||||
|
||||
return request_irq(104 + message, ipi_interrupt_handler, 0, "IPI", id);
|
||||
}
|
@@ -77,8 +77,6 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
|
||||
|
||||
static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n");
|
||||
|
||||
if (!cpu_online(policy->cpu))
|
||||
return -ENODEV;
|
||||
|
||||
@@ -143,6 +141,7 @@ static struct cpufreq_driver sh_cpufreq_driver = {
|
||||
|
||||
static int __init sh_cpufreq_module_init(void)
|
||||
{
|
||||
printk(KERN_INFO "cpufreq: SuperH CPU frequency driver.\n");
|
||||
return cpufreq_register_driver(&sh_cpufreq_driver);
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 1999, 2000 Niibe Yutaka
|
||||
* Copyright (C) 2002 M. R. Brown
|
||||
* Copyright (C) 2004 - 2006 Paul Mundt
|
||||
* 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
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#ifdef CONFIG_SH_STANDARD_BIOS
|
||||
#include <asm/sh_bios.h>
|
||||
@@ -62,6 +63,16 @@ static struct console bios_console = {
|
||||
#include <linux/serial_core.h>
|
||||
#include "../../../drivers/serial/sh-sci.h"
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7720)
|
||||
#define EPK_SCSMR_VALUE 0x000
|
||||
#define EPK_SCBRR_VALUE 0x00C
|
||||
#define EPK_FIFO_SIZE 64
|
||||
#define EPK_FIFO_BITS (0x7f00 >> 8)
|
||||
#else
|
||||
#define EPK_FIFO_SIZE 16
|
||||
#define EPK_FIFO_BITS (0x1f00 >> 8)
|
||||
#endif
|
||||
|
||||
static struct uart_port scif_port = {
|
||||
.mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT,
|
||||
.membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
|
||||
@@ -69,7 +80,7 @@ static struct uart_port scif_port = {
|
||||
|
||||
static void scif_sercon_putc(int c)
|
||||
{
|
||||
while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16))
|
||||
while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE))
|
||||
;
|
||||
|
||||
sci_out(&scif_port, SCxTDR, c);
|
||||
@@ -105,7 +116,22 @@ static struct console scif_console = {
|
||||
.index = -1,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
|
||||
#if !defined(CONFIG_SH_STANDARD_BIOS)
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7720)
|
||||
static void scif_sercon_init(char *s)
|
||||
{
|
||||
sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */
|
||||
sci_out(&scif_port, SCFCR, 0x4006); /* reset */
|
||||
sci_out(&scif_port, SCSCR, 0x0000); /* select internal clock */
|
||||
sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE);
|
||||
sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE);
|
||||
|
||||
mdelay(1); /* wait 1-bit time */
|
||||
|
||||
sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */
|
||||
sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */
|
||||
}
|
||||
#elif defined(CONFIG_CPU_SH4)
|
||||
#define DEFAULT_BAUD 115200
|
||||
/*
|
||||
* Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
|
||||
@@ -146,7 +172,8 @@ static void scif_sercon_init(char *s)
|
||||
ctrl_outw(0, scif_port.mapbase + 36);
|
||||
ctrl_outw(0x30, scif_port.mapbase + 8);
|
||||
}
|
||||
#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */
|
||||
#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */
|
||||
#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */
|
||||
#endif /* CONFIG_EARLY_SCIF_CONSOLE */
|
||||
|
||||
/*
|
||||
@@ -163,18 +190,13 @@ static struct console *early_console =
|
||||
#endif
|
||||
;
|
||||
|
||||
static int __initdata keep_early;
|
||||
static int early_console_initialized;
|
||||
|
||||
int __init setup_early_printk(char *buf)
|
||||
static int __init setup_early_printk(char *buf)
|
||||
{
|
||||
int keep_early = 0;
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
if (early_console_initialized)
|
||||
return 0;
|
||||
early_console_initialized = 1;
|
||||
|
||||
if (strstr(buf, "keep"))
|
||||
keep_early = 1;
|
||||
|
||||
@@ -186,7 +208,8 @@ int __init setup_early_printk(char *buf)
|
||||
if (!strncmp(buf, "serial", 6)) {
|
||||
early_console = &scif_console;
|
||||
|
||||
#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
|
||||
#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720)) && \
|
||||
!defined(CONFIG_SH_STANDARD_BIOS)
|
||||
scif_sercon_init(buf + 6);
|
||||
#endif
|
||||
}
|
||||
|
@@ -176,7 +176,7 @@ work_notifysig:
|
||||
jmp @r1
|
||||
lds r0, pr
|
||||
work_resched:
|
||||
#ifndef CONFIG_PREEMPT
|
||||
#if defined(CONFIG_GUSA) && !defined(CONFIG_PREEMPT)
|
||||
! gUSA handling
|
||||
mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
|
||||
mov r0, r1
|
||||
|
@@ -54,8 +54,8 @@ ENTRY(_stext)
|
||||
mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF
|
||||
ldc r0, sr
|
||||
! Initialize global interrupt mask
|
||||
mov #0, r0
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
mov #0, r0
|
||||
ldc r0, r6_bank
|
||||
#endif
|
||||
|
||||
@@ -72,15 +72,18 @@ ENTRY(_stext)
|
||||
!
|
||||
mov.l 2f, r0
|
||||
mov r0, r15 ! Set initial r15 (stack pointer)
|
||||
mov #(THREAD_SIZE >> 10), r1
|
||||
shll8 r1 ! r1 = THREAD_SIZE
|
||||
shll2 r1
|
||||
sub r1, r0 !
|
||||
#ifdef CONFIG_CPU_HAS_SR_RB
|
||||
mov.l 7f, r0
|
||||
ldc r0, r7_bank ! ... and initial thread_info
|
||||
#endif
|
||||
|
||||
! Clear BSS area
|
||||
#ifdef CONFIG_SMP
|
||||
mov.l 3f, r0
|
||||
cmp/eq #0, r0 ! skip clear if set to zero
|
||||
bt 10f
|
||||
#endif
|
||||
|
||||
mov.l 3f, r1
|
||||
add #4, r1
|
||||
mov.l 4f, r2
|
||||
@@ -89,13 +92,14 @@ ENTRY(_stext)
|
||||
bf/s 9b ! while (r1 < r2)
|
||||
mov.l r0,@-r2
|
||||
|
||||
10:
|
||||
! Additional CPU initialization
|
||||
mov.l 6f, r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
SYNCO() ! Wait for pending instructions..
|
||||
|
||||
|
||||
! Start kernel
|
||||
mov.l 5f, r0
|
||||
jmp @r0
|
||||
@@ -107,8 +111,10 @@ ENTRY(_stext)
|
||||
#else
|
||||
1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
|
||||
#endif
|
||||
ENTRY(stack_start)
|
||||
2: .long init_thread_union+THREAD_SIZE
|
||||
3: .long __bss_start
|
||||
4: .long _end
|
||||
5: .long start_kernel
|
||||
6: .long sh_cpu_init
|
||||
7: .long init_thread_union
|
||||
|
@@ -150,13 +150,6 @@ struct kgdb_regs trap_registers;
|
||||
char kgdb_in_gdb_mode;
|
||||
char in_nmi; /* Set during NMI to prevent reentry */
|
||||
int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
|
||||
int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
|
||||
|
||||
/* Exposed for user access */
|
||||
struct task_struct *kgdb_current;
|
||||
unsigned int kgdb_g_imask;
|
||||
int kgdb_trapa_val;
|
||||
int kgdb_excode;
|
||||
|
||||
/* Default values for SCI (can override via kernel args in setup.c) */
|
||||
#ifndef CONFIG_KGDB_DEFPORT
|
||||
@@ -616,7 +609,7 @@ static short *get_step_address(void)
|
||||
else
|
||||
addr = trap_registers.pc + 2;
|
||||
|
||||
kgdb_flush_icache_range(addr, addr + 2);
|
||||
flush_icache_range(addr, addr + 2);
|
||||
return (short *) addr;
|
||||
}
|
||||
|
||||
@@ -639,8 +632,7 @@ static void do_single_step(void)
|
||||
*addr = STEP_OPCODE;
|
||||
|
||||
/* Flush and return */
|
||||
kgdb_flush_icache_range((long) addr, (long) addr + 2);
|
||||
return;
|
||||
flush_icache_range((long) addr, (long) addr + 2);
|
||||
}
|
||||
|
||||
/* Undo a single step */
|
||||
@@ -650,7 +642,7 @@ static void undo_single_step(void)
|
||||
/* Use stepped_address in case we stopped elsewhere */
|
||||
if (stepped_opcode != 0) {
|
||||
*(short*)stepped_address = stepped_opcode;
|
||||
kgdb_flush_icache_range(stepped_address, stepped_address + 2);
|
||||
flush_icache_range(stepped_address, stepped_address + 2);
|
||||
}
|
||||
stepped_opcode = 0;
|
||||
}
|
||||
@@ -736,7 +728,7 @@ static void write_mem_msg(int binary)
|
||||
ebin_to_mem(ptr, (char*)addr, length);
|
||||
else
|
||||
hex_to_mem(ptr, (char*)addr, length);
|
||||
kgdb_flush_icache_range(addr, addr + length);
|
||||
flush_icache_range(addr, addr + length);
|
||||
ptr = 0;
|
||||
send_ok_msg();
|
||||
}
|
||||
@@ -815,14 +807,10 @@ static void set_regs_msg(void)
|
||||
/*
|
||||
* Bring up the ports..
|
||||
*/
|
||||
static int kgdb_serial_setup(void)
|
||||
static int __init kgdb_serial_setup(void)
|
||||
{
|
||||
extern int kgdb_console_setup(struct console *co, char *options);
|
||||
struct console dummy;
|
||||
|
||||
kgdb_console_setup(&dummy, 0);
|
||||
|
||||
return 0;
|
||||
return kgdb_console_setup(&dummy, 0);
|
||||
}
|
||||
#else
|
||||
#define kgdb_serial_setup() 0
|
||||
@@ -833,22 +821,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
|
||||
{
|
||||
int sigval;
|
||||
|
||||
if (excep_code == NMI_VEC) {
|
||||
#ifndef CONFIG_KGDB_NMI
|
||||
printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
|
||||
return;
|
||||
#else /* CONFIG_KGDB_NMI */
|
||||
if (!kgdb_enabled) {
|
||||
kgdb_enabled = 1;
|
||||
kgdb_init();
|
||||
}
|
||||
#endif /* CONFIG_KGDB_NMI */
|
||||
}
|
||||
|
||||
/* Ignore if we're disabled */
|
||||
if (!kgdb_enabled)
|
||||
return;
|
||||
|
||||
/* Enter GDB mode (e.g. after detach) */
|
||||
if (!kgdb_in_gdb_mode) {
|
||||
/* Do serial setup, notify user, issue preemptive ack */
|
||||
@@ -959,18 +931,10 @@ static void handle_exception(struct pt_regs *regs)
|
||||
|
||||
/* Get excode for command loop call, user access */
|
||||
asm("stc r2_bank, %0":"=r"(excep_code));
|
||||
kgdb_excode = excep_code;
|
||||
|
||||
/* Other interesting environment items for reference */
|
||||
asm("stc r6_bank, %0":"=r"(kgdb_g_imask));
|
||||
kgdb_current = current;
|
||||
kgdb_trapa_val = trapa_value;
|
||||
|
||||
/* Act on the exception */
|
||||
kgdb_command_loop(excep_code, trapa_value);
|
||||
|
||||
kgdb_current = NULL;
|
||||
|
||||
/* Copy back the (maybe modified) registers */
|
||||
for (count = 0; count < 16; count++)
|
||||
regs->regs[count] = trap_registers.regs[count];
|
||||
@@ -994,11 +958,8 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
|
||||
}
|
||||
|
||||
/* Initialise the KGDB data structures and serial configuration */
|
||||
int kgdb_init(void)
|
||||
int __init kgdb_init(void)
|
||||
{
|
||||
if (!kgdb_enabled)
|
||||
return 1;
|
||||
|
||||
in_nmi = 0;
|
||||
kgdb_nofault = 0;
|
||||
stepped_opcode = 0;
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <linux/tick.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgalloc.h>
|
||||
@@ -349,12 +350,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||
unlazy_fpu(prev, task_pt_regs(prev));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
#if defined(CONFIG_GUSA) && defined(CONFIG_PREEMPT)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pt_regs *regs;
|
||||
|
||||
local_irq_save(flags);
|
||||
preempt_disable();
|
||||
regs = task_pt_regs(prev);
|
||||
if (user_mode(regs) && regs->regs[15] >= 0xc0000000) {
|
||||
int offset = (int)regs->regs[15];
|
||||
@@ -365,7 +365,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||
/* Go to rewind point */
|
||||
regs->pc = regs->regs[0] + offset;
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
preempt_enable_no_resched();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/page.h>
|
||||
@@ -42,7 +43,13 @@ extern void * __rd_start, * __rd_end;
|
||||
* This value will be used at the very early stage of serial setup.
|
||||
* The bigger value means no problem.
|
||||
*/
|
||||
struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
|
||||
struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = {
|
||||
[0] = {
|
||||
.type = CPU_SH_NONE,
|
||||
.loops_per_jiffy = 10000000,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(cpu_data);
|
||||
|
||||
/*
|
||||
* The machine vector. First entry in .machvec.init, or clobbered by
|
||||
@@ -272,6 +279,10 @@ void __init setup_arch(char **cmdline_p)
|
||||
sh_mv.mv_setup(cmdline_p);
|
||||
|
||||
paging_init();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
plat_smp_setup();
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *cpu_name[] = {
|
||||
@@ -279,7 +290,7 @@ static const char *cpu_name[] = {
|
||||
[CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
|
||||
[CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
|
||||
[CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
|
||||
[CPU_SH7712] = "SH7712",
|
||||
[CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720",
|
||||
[CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750",
|
||||
[CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
|
||||
[CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/sections.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
@@ -43,7 +43,6 @@ EXPORT_SYMBOL(memcpy);
|
||||
EXPORT_SYMBOL(memset);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
EXPORT_SYMBOL(__copy_user);
|
||||
EXPORT_SYMBOL(boot_cpu_data);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
EXPORT_SYMBOL(get_vm_area);
|
||||
@@ -53,6 +52,7 @@ EXPORT_SYMBOL(get_vm_area);
|
||||
EXPORT_SYMBOL(__up);
|
||||
EXPORT_SYMBOL(__down);
|
||||
EXPORT_SYMBOL(__down_interruptible);
|
||||
EXPORT_SYMBOL(__down_trylock);
|
||||
|
||||
EXPORT_SYMBOL(__udelay);
|
||||
EXPORT_SYMBOL(__ndelay);
|
||||
@@ -128,7 +128,8 @@ DECLARE_EXPORT(__movstrSI12_i4);
|
||||
#endif /* __GNUC__ == 4 */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
|
||||
#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
|
||||
defined(CONFIG_SH7705_CACHE_32KB))
|
||||
/* needed by some modules */
|
||||
EXPORT_SYMBOL(flush_cache_all);
|
||||
EXPORT_SYMBOL(flush_cache_range);
|
||||
@@ -136,17 +137,11 @@ EXPORT_SYMBOL(flush_dcache_page);
|
||||
EXPORT_SYMBOL(__flush_purge_region);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \
|
||||
defined(CONFIG_SH7705_CACHE_32KB))
|
||||
#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
|
||||
(defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
|
||||
EXPORT_SYMBOL(clear_user_page);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(__down_trylock);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
EXPORT_SYMBOL(synchronize_irq);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
EXPORT_SYMBOL(csum_partial_copy_generic);
|
||||
#ifdef CONFIG_IPV6
|
||||
@@ -154,3 +149,4 @@ EXPORT_SYMBOL(csum_ipv6_magic);
|
||||
#endif
|
||||
EXPORT_SYMBOL(clear_page);
|
||||
EXPORT_SYMBOL(__clear_user);
|
||||
EXPORT_SYMBOL(_ebss);
|
||||
|
@@ -507,13 +507,11 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
ctrl_inw(regs->pc - 4));
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_GUSA
|
||||
} else {
|
||||
/* gUSA handling */
|
||||
#ifdef CONFIG_PREEMPT
|
||||
unsigned long flags;
|
||||
preempt_disable();
|
||||
|
||||
local_irq_save(flags);
|
||||
#endif
|
||||
if (regs->regs[15] >= 0xc0000000) {
|
||||
int offset = (int)regs->regs[15];
|
||||
|
||||
@@ -524,8 +522,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
regs->pc = regs->regs[0] + offset -
|
||||
instruction_size(ctrl_inw(regs->pc-4));
|
||||
}
|
||||
#ifdef CONFIG_PREEMPT
|
||||
local_irq_restore(flags);
|
||||
|
||||
preempt_enable_no_resched();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -3,69 +3,41 @@
|
||||
*
|
||||
* SMP support for the SuperH processors.
|
||||
*
|
||||
* Copyright (C) 2002, 2003 Paul Mundt
|
||||
* Copyright (C) 2002 - 2007 Paul Mundt
|
||||
* Copyright (C) 2006 - 2007 Akio Idehara
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
* This 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/err.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* This was written with the Sega Saturn (SMP SH-2 7604) in mind,
|
||||
* but is designed to be usable regardless if there's an MMU
|
||||
* present or not.
|
||||
*/
|
||||
struct sh_cpuinfo cpu_data[NR_CPUS];
|
||||
|
||||
extern void per_cpu_trap_init(void);
|
||||
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
|
||||
int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
|
||||
|
||||
cpumask_t cpu_possible_map;
|
||||
EXPORT_SYMBOL(cpu_possible_map);
|
||||
|
||||
cpumask_t cpu_online_map;
|
||||
EXPORT_SYMBOL(cpu_online_map);
|
||||
|
||||
static atomic_t cpus_booted = ATOMIC_INIT(0);
|
||||
|
||||
/* These are defined by the board-specific code. */
|
||||
|
||||
/*
|
||||
* Cause the function described by call_data to be executed on the passed
|
||||
* cpu. When the function has finished, increment the finished field of
|
||||
* call_data.
|
||||
*/
|
||||
void __smp_send_ipi(unsigned int cpu, unsigned int action);
|
||||
|
||||
/*
|
||||
* Find the number of available processors
|
||||
*/
|
||||
unsigned int __smp_probe_cpus(void);
|
||||
|
||||
/*
|
||||
* Start a particular processor
|
||||
*/
|
||||
void __smp_slave_init(unsigned int cpu);
|
||||
|
||||
/*
|
||||
* Run specified function on a particular processor.
|
||||
*/
|
||||
@@ -73,74 +45,123 @@ void __smp_call_function(unsigned int cpu);
|
||||
|
||||
static inline void __init smp_store_cpu_info(unsigned int cpu)
|
||||
{
|
||||
cpu_data[cpu].loops_per_jiffy = loops_per_jiffy;
|
||||
struct sh_cpuinfo *c = cpu_data + cpu;
|
||||
|
||||
c->loops_per_jiffy = loops_per_jiffy;
|
||||
}
|
||||
|
||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
int i;
|
||||
|
||||
atomic_set(&cpus_booted, 1);
|
||||
smp_store_cpu_info(cpu);
|
||||
|
||||
for (i = 0; i < __smp_probe_cpus(); i++)
|
||||
cpu_set(i, cpu_possible_map);
|
||||
init_new_context(current, &init_mm);
|
||||
current_thread_info()->cpu = cpu;
|
||||
plat_prepare_cpus(max_cpus);
|
||||
|
||||
#ifndef CONFIG_HOTPLUG_CPU
|
||||
cpu_present_map = cpu_possible_map;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __devinit smp_prepare_boot_cpu(void)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
__cpu_number_map[0] = cpu;
|
||||
__cpu_logical_map[0] = cpu;
|
||||
|
||||
cpu_set(cpu, cpu_online_map);
|
||||
cpu_set(cpu, cpu_possible_map);
|
||||
}
|
||||
|
||||
int __cpu_up(unsigned int cpu)
|
||||
asmlinkage void __cpuinit start_secondary(void)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
unsigned int cpu;
|
||||
struct mm_struct *mm = &init_mm;
|
||||
|
||||
tsk = fork_idle(cpu);
|
||||
atomic_inc(&mm->mm_count);
|
||||
atomic_inc(&mm->mm_users);
|
||||
current->active_mm = mm;
|
||||
BUG_ON(current->mm);
|
||||
enter_lazy_tlb(mm, current);
|
||||
|
||||
if (IS_ERR(tsk))
|
||||
panic("Failed forking idle task for cpu %d\n", cpu);
|
||||
|
||||
task_thread_info(tsk)->cpu = cpu;
|
||||
per_cpu_trap_init();
|
||||
|
||||
preempt_disable();
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
calibrate_delay();
|
||||
|
||||
cpu = smp_processor_id();
|
||||
smp_store_cpu_info(cpu);
|
||||
|
||||
cpu_set(cpu, cpu_online_map);
|
||||
|
||||
return 0;
|
||||
cpu_idle();
|
||||
}
|
||||
|
||||
int start_secondary(void *unused)
|
||||
extern struct {
|
||||
unsigned long sp;
|
||||
unsigned long bss_start;
|
||||
unsigned long bss_end;
|
||||
void *start_kernel_fn;
|
||||
void *cpu_init_fn;
|
||||
void *thread_info;
|
||||
} stack_start;
|
||||
|
||||
int __cpuinit __cpu_up(unsigned int cpu)
|
||||
{
|
||||
unsigned int cpu;
|
||||
struct task_struct *tsk;
|
||||
unsigned long timeout;
|
||||
|
||||
cpu = smp_processor_id();
|
||||
tsk = fork_idle(cpu);
|
||||
if (IS_ERR(tsk)) {
|
||||
printk(KERN_ERR "Failed forking idle task for cpu %d\n", cpu);
|
||||
return PTR_ERR(tsk);
|
||||
}
|
||||
|
||||
atomic_inc(&init_mm.mm_count);
|
||||
current->active_mm = &init_mm;
|
||||
/* Fill in data in head.S for secondary cpus */
|
||||
stack_start.sp = tsk->thread.sp;
|
||||
stack_start.thread_info = tsk->stack;
|
||||
stack_start.bss_start = 0; /* don't clear bss for secondary cpus */
|
||||
stack_start.start_kernel_fn = start_secondary;
|
||||
|
||||
smp_store_cpu_info(cpu);
|
||||
flush_cache_all();
|
||||
|
||||
__smp_slave_init(cpu);
|
||||
preempt_disable();
|
||||
per_cpu_trap_init();
|
||||
|
||||
atomic_inc(&cpus_booted);
|
||||
plat_start_cpu(cpu, (unsigned long)_stext);
|
||||
|
||||
cpu_idle();
|
||||
return 0;
|
||||
timeout = jiffies + HZ;
|
||||
while (time_before(jiffies, timeout)) {
|
||||
if (cpu_online(cpu))
|
||||
break;
|
||||
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (cpu_online(cpu))
|
||||
return 0;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
void __init smp_cpus_done(unsigned int max_cpus)
|
||||
{
|
||||
smp_mb();
|
||||
unsigned long bogosum = 0;
|
||||
int cpu;
|
||||
|
||||
for_each_online_cpu(cpu)
|
||||
bogosum += cpu_data[cpu].loops_per_jiffy;
|
||||
|
||||
printk(KERN_INFO "SMP: Total of %d processors activated "
|
||||
"(%lu.%02lu BogoMIPS).\n", num_online_cpus(),
|
||||
bogosum / (500000/HZ),
|
||||
(bogosum / (5000/HZ)) % 100);
|
||||
}
|
||||
|
||||
void smp_send_reschedule(int cpu)
|
||||
{
|
||||
__smp_send_ipi(cpu, SMP_MSG_RESCHEDULE);
|
||||
plat_send_ipi(cpu, SMP_MSG_RESCHEDULE);
|
||||
}
|
||||
|
||||
static void stop_this_cpu(void *unused)
|
||||
@@ -157,7 +178,6 @@ void smp_send_stop(void)
|
||||
smp_call_function(stop_this_cpu, 0, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
struct smp_fn_call_struct smp_fn_call = {
|
||||
.lock = SPIN_LOCK_UNLOCKED,
|
||||
.finished = ATOMIC_INIT(0),
|
||||
@@ -175,9 +195,6 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
|
||||
unsigned int nr_cpus = atomic_read(&cpus_booted);
|
||||
int i;
|
||||
|
||||
if (nr_cpus < 2)
|
||||
return 0;
|
||||
|
||||
/* Can deadlock when called with interrupts disabled */
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
@@ -189,7 +206,7 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
|
||||
|
||||
for (i = 0; i < nr_cpus; i++)
|
||||
if (i != smp_processor_id())
|
||||
__smp_call_function(i);
|
||||
plat_send_ipi(i, SMP_MSG_FUNCTION);
|
||||
|
||||
if (wait)
|
||||
while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1));
|
||||
@@ -205,3 +222,143 @@ int setup_profiling_timer(unsigned int multiplier)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void flush_tlb_all_ipi(void *info)
|
||||
{
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
|
||||
void flush_tlb_all(void)
|
||||
{
|
||||
on_each_cpu(flush_tlb_all_ipi, 0, 1, 1);
|
||||
}
|
||||
|
||||
static void flush_tlb_mm_ipi(void *mm)
|
||||
{
|
||||
local_flush_tlb_mm((struct mm_struct *)mm);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following tlb flush calls are invoked when old translations are
|
||||
* being torn down, or pte attributes are changing. For single threaded
|
||||
* address spaces, a new context is obtained on the current cpu, and tlb
|
||||
* context on other cpus are invalidated to force a new context allocation
|
||||
* at switch_mm time, should the mm ever be used on other cpus. For
|
||||
* multithreaded address spaces, intercpu interrupts have to be sent.
|
||||
* Another case where intercpu interrupts are required is when the target
|
||||
* mm might be active on another cpu (eg debuggers doing the flushes on
|
||||
* behalf of debugees, kswapd stealing pages from another process etc).
|
||||
* Kanoj 07/00.
|
||||
*/
|
||||
|
||||
void flush_tlb_mm(struct mm_struct *mm)
|
||||
{
|
||||
preempt_disable();
|
||||
|
||||
if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
|
||||
smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < num_online_cpus(); i++)
|
||||
if (smp_processor_id() != i)
|
||||
cpu_context(i, mm) = 0;
|
||||
}
|
||||
local_flush_tlb_mm(mm);
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
struct flush_tlb_data {
|
||||
struct vm_area_struct *vma;
|
||||
unsigned long addr1;
|
||||
unsigned long addr2;
|
||||
};
|
||||
|
||||
static void flush_tlb_range_ipi(void *info)
|
||||
{
|
||||
struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
|
||||
|
||||
local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2);
|
||||
}
|
||||
|
||||
void flush_tlb_range(struct vm_area_struct *vma,
|
||||
unsigned long start, unsigned long end)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
|
||||
preempt_disable();
|
||||
if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
|
||||
struct flush_tlb_data fd;
|
||||
|
||||
fd.vma = vma;
|
||||
fd.addr1 = start;
|
||||
fd.addr2 = end;
|
||||
smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < num_online_cpus(); i++)
|
||||
if (smp_processor_id() != i)
|
||||
cpu_context(i, mm) = 0;
|
||||
}
|
||||
local_flush_tlb_range(vma, start, end);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void flush_tlb_kernel_range_ipi(void *info)
|
||||
{
|
||||
struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
|
||||
|
||||
local_flush_tlb_kernel_range(fd->addr1, fd->addr2);
|
||||
}
|
||||
|
||||
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
struct flush_tlb_data fd;
|
||||
|
||||
fd.addr1 = start;
|
||||
fd.addr2 = end;
|
||||
on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1);
|
||||
}
|
||||
|
||||
static void flush_tlb_page_ipi(void *info)
|
||||
{
|
||||
struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
|
||||
|
||||
local_flush_tlb_page(fd->vma, fd->addr1);
|
||||
}
|
||||
|
||||
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
|
||||
{
|
||||
preempt_disable();
|
||||
if ((atomic_read(&vma->vm_mm->mm_users) != 1) ||
|
||||
(current->mm != vma->vm_mm)) {
|
||||
struct flush_tlb_data fd;
|
||||
|
||||
fd.vma = vma;
|
||||
fd.addr1 = page;
|
||||
smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < num_online_cpus(); i++)
|
||||
if (smp_processor_id() != i)
|
||||
cpu_context(i, vma->vm_mm) = 0;
|
||||
}
|
||||
local_flush_tlb_page(vma, page);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void flush_tlb_one_ipi(void *info)
|
||||
{
|
||||
struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
|
||||
local_flush_tlb_one(fd->addr1, fd->addr2);
|
||||
}
|
||||
|
||||
void flush_tlb_one(unsigned long asid, unsigned long vaddr)
|
||||
{
|
||||
struct flush_tlb_data fd;
|
||||
|
||||
fd.addr1 = asid;
|
||||
fd.addr2 = vaddr;
|
||||
|
||||
smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1, 1);
|
||||
local_flush_tlb_one(asid, vaddr);
|
||||
}
|
||||
|
@@ -14,24 +14,6 @@
|
||||
#include <linux/sys.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
|
||||
#define sys_nfsservctl sys_ni_syscall
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_MMU)
|
||||
#define sys_madvise sys_ni_syscall
|
||||
#define sys_readahead sys_ni_syscall
|
||||
#define sys_mprotect sys_ni_syscall
|
||||
#define sys_msync sys_ni_syscall
|
||||
#define sys_mlock sys_ni_syscall
|
||||
#define sys_munlock sys_ni_syscall
|
||||
#define sys_mlockall sys_ni_syscall
|
||||
#define sys_munlockall sys_ni_syscall
|
||||
#define sys_mremap sys_ni_syscall
|
||||
#define sys_mincore sys_ni_syscall
|
||||
#define sys_remap_file_pages sys_ni_syscall
|
||||
#endif
|
||||
|
||||
.data
|
||||
ENTRY(sys_call_table)
|
||||
.long sys_restart_syscall /* 0 - old "setup()" system call*/
|
||||
|
@@ -173,7 +173,8 @@ static int tmu_timer_init(void)
|
||||
|
||||
tmu_timer_stop();
|
||||
|
||||
#if !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
|
||||
#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
|
||||
!defined(CONFIG_CPU_SUBTYPE_SH7760) && \
|
||||
!defined(CONFIG_CPU_SUBTYPE_SH7785) && \
|
||||
!defined(CONFIG_CPU_SUBTYPE_SHX3)
|
||||
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
|
||||
|
@@ -807,12 +807,13 @@ static inline void __init gdb_vbr_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init per_cpu_trap_init(void)
|
||||
void __cpuinit per_cpu_trap_init(void)
|
||||
{
|
||||
extern void *vbr_base;
|
||||
|
||||
#ifdef CONFIG_SH_STANDARD_BIOS
|
||||
gdb_vbr_init();
|
||||
if (raw_smp_processor_id() == 0)
|
||||
gdb_vbr_init();
|
||||
#endif
|
||||
|
||||
/* NOTE: The VBR value should be at P1
|
||||
|
@@ -62,6 +62,8 @@ SECTIONS
|
||||
__nosave_end = .;
|
||||
|
||||
PERCPU(PAGE_SIZE)
|
||||
|
||||
. = ALIGN(L1_CACHE_BYTES);
|
||||
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
|
||||
|
||||
_edata = .; /* End of data section */
|
||||
@@ -89,7 +91,14 @@ SECTIONS
|
||||
__con_initcall_end = .;
|
||||
SECURITY_INIT
|
||||
|
||||
/* .exit.text is discarded at runtime, not link time, to deal with
|
||||
references from .rodata */
|
||||
.exit.text : { *(.exit.text) }
|
||||
.exit.data : { *(.exit.data) }
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
|
||||
__initramfs_start = .;
|
||||
.init.ramfs : { *(.init.ramfs) }
|
||||
__initramfs_end = .;
|
||||
@@ -107,6 +116,7 @@ SECTIONS
|
||||
*(.bss.page_aligned)
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* uClinux MTD sucks */
|
||||
_end = . ;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user