Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6: (68 commits) sh: sh-rtc support for SH7709. sh: Revert __xdiv64_32 size change. sh: Update r7785rp defconfig. sh: Export div symbols for GCC 4.2 and ST GCC. sh: fix race in parallel out-of-tree build sh: Kill off dead mach.c for hp6xx. sh: hd64461.h cleanup and added comments. sh: Update the alignment when 4K stacks are used. sh: Add a .bss.page_aligned section for 4K stacks. sh: Don't let SH-4A clobber SH-4 CFLAGS. sh: Add parport stub for SuperIO ports. sh: Drop -Wa,-dsp for DSP tuning. sh: Update dreamcast defconfig. fb: pvr2fb: A few more __devinit annotations for PCI. fb: pvr2fb: Fix up section mismatch warnings. sh: Select IPR-IRQ for SH7091. sh: Correct __xdiv64_32/div64_32 return value size. sh: Fix timer-tmu build for SH-3. sh: Add cpu and mach links to CLEAN_FILES. sh: Preliminary support for the SH-X3 CPU. ...
This commit is contained in:
@@ -4,10 +4,9 @@
|
||||
|
||||
extra-y := head.o init_task.o vmlinux.lds
|
||||
|
||||
obj-y := process.o signal.o traps.o irq.o \
|
||||
ptrace.o setup.o time.o sys_sh.o semaphore.o \
|
||||
io.o io_generic.o sh_ksyms.o syscalls.o \
|
||||
debugtraps.o
|
||||
obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \
|
||||
semaphore.o setup.o signal.o sys_sh.o syscalls.o \
|
||||
time.o topology.o traps.o
|
||||
|
||||
obj-y += cpu/ timers/
|
||||
obj-$(CONFIG_VSYSCALL) += vsyscall/
|
||||
@@ -17,7 +16,7 @@ obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
|
||||
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
|
||||
obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o
|
||||
obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_MODULES) += sh_ksyms.o module.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
|
@@ -75,11 +75,7 @@ static int __init cf_init_default(void)
|
||||
#if defined(CONFIG_CPU_SH4)
|
||||
allocate_cf_area();
|
||||
#endif
|
||||
#if defined(CONFIG_SH_UNKNOWN)
|
||||
/* This should be done in each board's init_xxx_irq. */
|
||||
make_imask_irq(14);
|
||||
disable_irq(14);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -21,8 +21,7 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
extern void detect_cpu_and_cache_system(void);
|
||||
#include <asm/ubc.h>
|
||||
|
||||
/*
|
||||
* Generic wrapper for command line arguments to disable on-chip
|
||||
@@ -152,15 +151,6 @@ static void __init cache_init(void)
|
||||
flags |= CCR_CACHE_CB;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SH_OCRAM
|
||||
/* Turn on OCRAM -- halve the OC */
|
||||
flags |= CCR_CACHE_ORA;
|
||||
current_cpu_data.dcache.sets >>= 1;
|
||||
|
||||
current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
|
||||
current_cpu_data.dcache.linesz;
|
||||
#endif
|
||||
|
||||
ctrl_outl(flags, CCR);
|
||||
back_to_P1();
|
||||
}
|
||||
@@ -269,7 +259,6 @@ asmlinkage void __init sh_cpu_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_UBC_WAKEUP
|
||||
/*
|
||||
* Some brain-damaged loaders decided it would be a good idea to put
|
||||
* the UBC to sleep. This causes some issues when it comes to things
|
||||
@@ -277,7 +266,5 @@ asmlinkage void __init sh_cpu_init(void)
|
||||
* we wake it up and hope that all is well.
|
||||
*/
|
||||
ubc_wakeup();
|
||||
#endif
|
||||
|
||||
speculative_execution_init();
|
||||
}
|
||||
|
@@ -13,36 +13,31 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#if defined(CONFIG_CPU_SUBTYPE_SH7760)
|
||||
#define INTC2_BASE 0xfe080000
|
||||
#define INTC2_INTMSK (INTC2_BASE + 0x40)
|
||||
#define INTC2_INTMSKCLR (INTC2_BASE + 0x60)
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \
|
||||
defined(CONFIG_CPU_SUBTYPE_SH7785)
|
||||
#define INTC2_BASE 0xffd40000
|
||||
#define INTC2_INTMSK (INTC2_BASE + 0x38)
|
||||
#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
|
||||
#endif
|
||||
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);
|
||||
ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset);
|
||||
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);
|
||||
ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset);
|
||||
}
|
||||
struct intc2_desc *d = get_intc2_desc(irq);
|
||||
|
||||
static struct irq_chip intc2_irq_chip = {
|
||||
.name = "INTC2",
|
||||
.mask = disable_intc2_irq,
|
||||
.unmask = enable_intc2_irq,
|
||||
.mask_ack = disable_intc2_irq,
|
||||
};
|
||||
ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset +
|
||||
(hard_smp_processor_id() * 4));
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup an INTC2 style interrupt.
|
||||
@@ -56,30 +51,36 @@ static struct irq_chip intc2_irq_chip = {
|
||||
*
|
||||
* in the intc2_data table.
|
||||
*/
|
||||
void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs)
|
||||
void register_intc2_controller(struct intc2_desc *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_irqs; 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 = table + i;
|
||||
struct intc2_data *p = desc->intc2_data + i;
|
||||
|
||||
disable_irq_nosync(p->irq);
|
||||
|
||||
/* Set the priority level */
|
||||
local_irq_save(flags);
|
||||
if (desc->prio_base) {
|
||||
/* Set the priority level */
|
||||
local_irq_save(flags);
|
||||
|
||||
ipr = ctrl_inl(INTC2_BASE + p->ipr_offset);
|
||||
ipr &= ~(0xf << p->ipr_shift);
|
||||
ipr |= p->priority << p->ipr_shift;
|
||||
ctrl_outl(ipr, INTC2_BASE + p->ipr_offset);
|
||||
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);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip,
|
||||
set_irq_chip_and_handler_name(p->irq, &desc->chip,
|
||||
handle_level_irq, "level");
|
||||
set_irq_chip_data(p->irq, p);
|
||||
|
||||
enable_intc2_irq(p->irq);
|
||||
disable_intc2_irq(p->irq);
|
||||
}
|
||||
}
|
||||
|
@@ -22,58 +22,57 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
static inline struct ipr_desc *get_ipr_desc(unsigned int irq)
|
||||
{
|
||||
struct irq_chip *chip = get_irq_chip(irq);
|
||||
return (void *)((char *)chip - offsetof(struct ipr_desc, chip));
|
||||
}
|
||||
|
||||
static void disable_ipr_irq(unsigned int irq)
|
||||
{
|
||||
struct ipr_data *p = get_irq_chip_data(irq);
|
||||
unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
|
||||
/* Set the priority in IPR to 0 */
|
||||
ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
|
||||
ctrl_outw(ctrl_inw(addr) & (0xffff ^ (0xf << p->shift)), addr);
|
||||
}
|
||||
|
||||
static void enable_ipr_irq(unsigned int irq)
|
||||
{
|
||||
struct ipr_data *p = get_irq_chip_data(irq);
|
||||
unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
|
||||
/* Set priority in IPR back to original value */
|
||||
ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
|
||||
ctrl_outw(ctrl_inw(addr) | (p->priority << p->shift), addr);
|
||||
}
|
||||
|
||||
static struct irq_chip ipr_irq_chip = {
|
||||
.name = "IPR",
|
||||
.mask = disable_ipr_irq,
|
||||
.unmask = enable_ipr_irq,
|
||||
.mask_ack = disable_ipr_irq,
|
||||
};
|
||||
/*
|
||||
* The shift value is now the number of bits to shift, not the number of
|
||||
* bits/4. This is to make it easier to read the value directly from the
|
||||
* datasheets. The IPR address is calculated using the ipr_offset table.
|
||||
*/
|
||||
|
||||
unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak));
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
|
||||
void register_ipr_controller(struct ipr_desc *desc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
unsigned int irq = table[i].irq;
|
||||
desc->chip.mask = disable_ipr_irq;
|
||||
desc->chip.unmask = enable_ipr_irq;
|
||||
desc->chip.mask_ack = disable_ipr_irq;
|
||||
|
||||
if (!irq)
|
||||
irq = table[i].irq = i;
|
||||
for (i = 0; i < desc->nr_irqs; i++) {
|
||||
struct ipr_data *p = desc->ipr_data + i;
|
||||
|
||||
/* could the IPR index be mapped, if not we ignore this */
|
||||
if (!table[i].addr) {
|
||||
table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
|
||||
if (!table[i].addr)
|
||||
continue;
|
||||
}
|
||||
BUG_ON(p->ipr_idx >= desc->nr_offsets);
|
||||
BUG_ON(!desc->ipr_offsets[p->ipr_idx]);
|
||||
|
||||
disable_irq_nosync(irq);
|
||||
set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
|
||||
disable_irq_nosync(p->irq);
|
||||
set_irq_chip_and_handler_name(p->irq, &desc->chip,
|
||||
handle_level_irq, "level");
|
||||
set_irq_chip_data(irq, &table[i]);
|
||||
enable_ipr_irq(irq);
|
||||
set_irq_chip_data(p->irq, p);
|
||||
disable_ipr_irq(p->irq);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(make_ipr_irq);
|
||||
|
||||
EXPORT_SYMBOL(register_ipr_controller);
|
||||
|
||||
#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
|
||||
int ipr_irq_demux(int irq)
|
||||
|
@@ -311,6 +311,7 @@ restore_all:
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
1: .long trace_hardirqs_off
|
||||
#endif
|
||||
|
@@ -9,23 +9,14 @@
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* 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_SH7604)
|
||||
current_cpu_data.type = CPU_SH7604;
|
||||
current_cpu_data.dcache.ways = 4;
|
||||
current_cpu_data.dcache.way_incr = (1<<10);
|
||||
current_cpu_data.dcache.sets = 64;
|
||||
current_cpu_data.dcache.entry_shift = 4;
|
||||
current_cpu_data.dcache.linesz = L1_CACHE_BYTES;
|
||||
current_cpu_data.dcache.flags = 0;
|
||||
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
|
||||
#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);
|
||||
|
@@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7619_devices_setup);
|
||||
|
||||
static struct ipr_data sh7619_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
{ 86, 0, 4, 2 }, /* CMI0 */
|
||||
{ 88, 1, 12, 3 }, /* SCIF0_ERI */
|
||||
{ 89, 1, 12, 3 }, /* SCIF0_RXI */
|
||||
@@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = {
|
||||
{ 99, 1, 4, 3 }, /* SCIF2_TXI */
|
||||
};
|
||||
|
||||
static unsigned int ipr_offsets[] = {
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xf8080000, /* IPRC */
|
||||
0xf8080002, /* IPRD */
|
||||
0xf8080004, /* IPRE */
|
||||
@@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = {
|
||||
0xf8080008, /* IPRG */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
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 init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7206_devices_setup);
|
||||
|
||||
static struct ipr_data sh7206_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
{ 140, 7, 12, 2 }, /* CMI0 */
|
||||
{ 164, 8, 4, 2 }, /* MTU2_TGI1A */
|
||||
{ 240, 13, 12, 3 }, /* SCIF0_BRI */
|
||||
@@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = {
|
||||
{ 255, 13, 0, 3 }, /* SCIF3_TXI */
|
||||
};
|
||||
|
||||
static unsigned int ipr_offsets[] = {
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xfffe0818, /* IPR01 */
|
||||
0xfffe081a, /* IPR02 */
|
||||
0, /* unused */
|
||||
@@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = {
|
||||
0xfffe0c10, /* IPR14 */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
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 init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
@@ -340,8 +340,27 @@ ENTRY(vbr_base)
|
||||
general_exception:
|
||||
mov.l 1f, k2
|
||||
mov.l 2f, k3
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SHX3
|
||||
mov.l @k2, k2
|
||||
|
||||
! Is EXPEVT larger than 0x800?
|
||||
mov #0x8, k0
|
||||
shll8 k0
|
||||
cmp/hs k0, k2
|
||||
bf 0f
|
||||
|
||||
! then add 0x580 (k2 is 0xd80 or 0xda0)
|
||||
mov #0x58, k0
|
||||
shll2 k0
|
||||
shll2 k0
|
||||
add k0, k2
|
||||
0:
|
||||
bra handle_exception
|
||||
nop
|
||||
#else
|
||||
bra handle_exception
|
||||
mov.l @k2, k2
|
||||
#endif
|
||||
.align 2
|
||||
1: .long EXPEVT
|
||||
2: .long ret_from_exception
|
||||
|
@@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7705_devices_setup);
|
||||
|
||||
static struct ipr_data sh7705_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
|
||||
@@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = {
|
||||
};
|
||||
|
||||
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 */
|
||||
0xFFFFFEE2, /* 0: IPRA */
|
||||
0xFFFFFEE4, /* 1: IPRB */
|
||||
0xA4000016, /* 2: IPRC */
|
||||
0xA4000018, /* 3: IPRD */
|
||||
0xA400001A, /* 4: IPRE */
|
||||
0xA4080000, /* 5: IPRF */
|
||||
0xA4080002, /* 6: IPRG */
|
||||
0xA4080004, /* 7: IPRH */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(ipr_offsets))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
void __init init_IRQ_ipr()
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7705",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
@@ -12,6 +12,26 @@
|
||||
#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,
|
||||
@@ -41,8 +61,16 @@ static struct platform_device sci_device = {
|
||||
},
|
||||
};
|
||||
|
||||
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)
|
||||
@@ -52,32 +80,66 @@ static int __init sh7709_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7709_devices_setup);
|
||||
|
||||
#define IPRx(A,N) .addr=A, .shift=N
|
||||
#define IPRA(N) IPRx(0xfffffee2UL,N)
|
||||
#define IPRB(N) IPRx(0xfffffee4UL,N)
|
||||
#define IPRC(N) IPRx(0xa4000016UL,N)
|
||||
#define IPRD(N) IPRx(0xa4000018UL,N)
|
||||
#define IPRE(N) IPRx(0xa400001aUL,N)
|
||||
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 */
|
||||
|
||||
static struct ipr_data sh7709_ipr_map[] = {
|
||||
[16] = { IPRA(12), 2 }, /* TMU TUNI0 */
|
||||
[17] = { IPRA(8), 4 }, /* TMU TUNI1 */
|
||||
[18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */
|
||||
[20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */
|
||||
[23 ... 26] = { IPRB(4), 3 }, /* SCI */
|
||||
[27] = { IPRB(12), 2 }, /* WDT ITI */
|
||||
[32] = { IPRC(0), 1 }, /* IRQ 0 */
|
||||
[33] = { IPRC(4), 1 }, /* IRQ 1 */
|
||||
[34] = { IPRC(8), 1 }, /* IRQ 2 APM */
|
||||
[35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */
|
||||
[36] = { IPRD(0), 1 }, /* IRQ 4 */
|
||||
[37] = { IPRD(4), 1 }, /* IRQ 5 */
|
||||
[48 ... 51] = { IPRE(12), 7 }, /* DMA */
|
||||
[52 ... 55] = { IPRE(8), 3 }, /* IRDA */
|
||||
[56 ... 59] = { IPRE(4), 3 }, /* SCIF */
|
||||
{ 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 */
|
||||
};
|
||||
|
||||
void __init init_IRQ_ipr()
|
||||
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 init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7710_devices_setup);
|
||||
|
||||
static struct ipr_data sh7710_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
|
||||
@@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = {
|
||||
};
|
||||
|
||||
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 */
|
||||
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 */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(ipr_offsets))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
void __init init_IRQ_ipr()
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7710",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
@@ -10,7 +10,11 @@ obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
|
||||
|
||||
# CPU subtype setup
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7750R) += setup-sh7750.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7750S) += setup-sh7750.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7091) += setup-sh7750.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += setup-sh7750.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o
|
||||
|
||||
|
@@ -141,6 +141,14 @@ int __init detect_cpu_and_cache_system(void)
|
||||
current_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 |
|
||||
CPU_HAS_LLSC;
|
||||
break;
|
||||
case 0x8000:
|
||||
current_cpu_data.type = CPU_ST40RA;
|
||||
current_cpu_data.flags |= CPU_HAS_FPU;
|
||||
|
@@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7750_devices_setup);
|
||||
|
||||
static struct ipr_data sh7750_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 12, 2 }, /* TMU1 TUNI */
|
||||
@@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = {
|
||||
{ 38, 2, 8, 7 }, /* DMAC DMAE */
|
||||
};
|
||||
|
||||
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-sh7750",
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7751
|
||||
static struct ipr_data sh7751_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table_sh7751[] = {
|
||||
{ 44, 2, 8, 7 }, /* DMAC DMTE4 */
|
||||
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */
|
||||
{ 46, 2, 8, 7 }, /* DMAC DMTE6 */
|
||||
@@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = {
|
||||
/*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
|
||||
/*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
|
||||
};
|
||||
|
||||
static struct ipr_desc ipr_irq_desc_sh7751 = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
.ipr_data = ipr_irq_table_sh7751,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751),
|
||||
|
||||
.chip = {
|
||||
.name = "IPR-sh7751",
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static unsigned long ipr_offsets[] = {
|
||||
0xffd00004UL, /* 0: IPRA */
|
||||
0xffd00008UL, /* 1: IPRB */
|
||||
0xffd0000cUL, /* 2: IPRC */
|
||||
0xffd00010UL, /* 3: IPRD */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
void __init init_IRQ_ipr(void)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(ipr_offsets))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7751
|
||||
register_ipr_controller(&ipr_irq_desc_sh7751);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define INTC_ICR 0xffd00000UL
|
||||
@@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void)
|
||||
{
|
||||
ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
|
||||
}
|
||||
|
||||
void __init init_IRQ_ipr()
|
||||
{
|
||||
make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map));
|
||||
#ifdef CONFIG_CPU_SUBTYPE_SH7751
|
||||
make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map));
|
||||
#endif
|
||||
}
|
||||
|
@@ -96,7 +96,25 @@ static struct intc2_data intc2_irq_table[] = {
|
||||
{109,12, 0, 4, 0, 3}, /* CMTI */
|
||||
};
|
||||
|
||||
static struct ipr_data sh7760_ipr_map[] = {
|
||||
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",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_intc2(void)
|
||||
{
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
}
|
||||
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, priority */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 TUNI*/
|
||||
{ 17, 0, 8, 2 }, /* TMU1 TUNI */
|
||||
@@ -133,20 +151,19 @@ static unsigned long ipr_offsets[] = {
|
||||
0xffd00010UL, /* 3: IPRD */
|
||||
};
|
||||
|
||||
/* given the IPR index return the address of the IPR register */
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (idx >= ARRAY_SIZE(ipr_offsets))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
static struct ipr_desc ipr_irq_desc = {
|
||||
.ipr_offsets = ipr_offsets,
|
||||
.nr_offsets = ARRAY_SIZE(ipr_offsets),
|
||||
|
||||
void __init init_IRQ_intc2(void)
|
||||
{
|
||||
make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
|
||||
}
|
||||
.ipr_data = ipr_irq_table,
|
||||
.nr_irqs = ARRAY_SIZE(ipr_irq_table),
|
||||
|
||||
void __init init_IRQ_ipr(void)
|
||||
.chip = {
|
||||
.name = "IPR-sh7760",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
|
||||
obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o
|
||||
|
||||
# Primary on-chip clocks (common)
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o
|
||||
@@ -17,5 +18,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
|
||||
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
|
||||
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)
|
||||
|
135
arch/sh/kernel/cpu/sh4a/clock-shx3.c
Normal file
135
arch/sh/kernel/cpu/sh4a/clock-shx3.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* arch/sh/kernel/cpu/sh4/clock-shx3.c
|
||||
*
|
||||
* SH-X3 support for the clock framework
|
||||
*
|
||||
* Copyright (C) 2006-2007 Renesas Technology Corp.
|
||||
* Copyright (C) 2006-2007 Renesas Solutions Corp.
|
||||
* Copyright (C) 2006-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
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/clock.h>
|
||||
#include <asm/freq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static int ifc_divisors[] = { 1, 2, 4 ,6 };
|
||||
static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 };
|
||||
static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 };
|
||||
static int cfc_divisors[] = { 1, 1, 4, 6 };
|
||||
|
||||
#define IFC_POS 28
|
||||
#define IFC_MSK 0x0003
|
||||
#define BFC_MSK 0x000f
|
||||
#define PFC_MSK 0x000f
|
||||
#define CFC_MSK 0x0003
|
||||
#define BFC_POS 16
|
||||
#define PFC_POS 0
|
||||
#define CFC_POS 20
|
||||
|
||||
static void master_clk_init(struct clk *clk)
|
||||
{
|
||||
clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK];
|
||||
}
|
||||
|
||||
static struct clk_ops shx3_master_clk_ops = {
|
||||
.init = master_clk_init,
|
||||
};
|
||||
|
||||
static void module_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK);
|
||||
clk->rate = clk->parent->rate / pfc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops shx3_module_clk_ops = {
|
||||
.recalc = module_clk_recalc,
|
||||
};
|
||||
|
||||
static void bus_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK);
|
||||
clk->rate = clk->parent->rate / bfc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops shx3_bus_clk_ops = {
|
||||
.recalc = bus_clk_recalc,
|
||||
};
|
||||
|
||||
static void cpu_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK);
|
||||
clk->rate = clk->parent->rate / ifc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops shx3_cpu_clk_ops = {
|
||||
.recalc = cpu_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk_ops *shx3_clk_ops[] = {
|
||||
&shx3_master_clk_ops,
|
||||
&shx3_module_clk_ops,
|
||||
&shx3_bus_clk_ops,
|
||||
&shx3_cpu_clk_ops,
|
||||
};
|
||||
|
||||
void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
|
||||
{
|
||||
if (idx < ARRAY_SIZE(shx3_clk_ops))
|
||||
*ops = shx3_clk_ops[idx];
|
||||
}
|
||||
|
||||
static void shyway_clk_recalc(struct clk *clk)
|
||||
{
|
||||
int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK);
|
||||
clk->rate = clk->parent->rate / cfc_divisors[idx];
|
||||
}
|
||||
|
||||
static struct clk_ops shx3_shyway_clk_ops = {
|
||||
.recalc = shyway_clk_recalc,
|
||||
};
|
||||
|
||||
static struct clk shx3_shyway_clk = {
|
||||
.name = "shyway_clk",
|
||||
.flags = CLK_ALWAYS_ENABLED,
|
||||
.ops = &shx3_shyway_clk_ops,
|
||||
};
|
||||
|
||||
/*
|
||||
* Additional SHx3-specific on-chip clocks that aren't already part of the
|
||||
* clock framework
|
||||
*/
|
||||
static struct clk *shx3_onchip_clocks[] = {
|
||||
&shx3_shyway_clk,
|
||||
};
|
||||
|
||||
static int __init shx3_clk_init(void)
|
||||
{
|
||||
struct clk *clk = clk_get(NULL, "master_clk");
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
|
||||
struct clk *clkp = shx3_onchip_clocks[i];
|
||||
|
||||
clkp->parent = clk;
|
||||
clk_register(clkp);
|
||||
clk_enable(clkp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we have the rest of the clocks registered, we need to
|
||||
* force the parent clock to propagate so that these clocks will
|
||||
* automatically figure out their rate. We cheat by handing the
|
||||
* parent clock its current rate and forcing child propagation.
|
||||
*/
|
||||
clk_set_rate(clk, clk_get_rate(clk));
|
||||
|
||||
clk_put(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(shx3_clk_init);
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SH7722 Setup
|
||||
*
|
||||
* Copyright (C) 2006 Paul Mundt
|
||||
* Copyright (C) 2006 - 2007 Paul Mundt
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/mmzone.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
@@ -42,7 +44,7 @@ static int __init sh7722_devices_setup(void)
|
||||
}
|
||||
__initcall(sh7722_devices_setup);
|
||||
|
||||
static struct ipr_data sh7722_ipr_map[] = {
|
||||
static struct ipr_data ipr_irq_table[] = {
|
||||
/* IRQ, IPR-idx, shift, prio */
|
||||
{ 16, 0, 12, 2 }, /* TMU0 */
|
||||
{ 17, 0, 8, 2 }, /* TMU1 */
|
||||
@@ -67,14 +69,25 @@ static unsigned long ipr_offsets[] = {
|
||||
0xa408002c, /* 11: IPRL */
|
||||
};
|
||||
|
||||
unsigned int map_ipridx_to_addr(int idx)
|
||||
{
|
||||
if (unlikely(idx >= ARRAY_SIZE(ipr_offsets)))
|
||||
return 0;
|
||||
return ipr_offsets[idx];
|
||||
}
|
||||
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-sh7722",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_ipr(void)
|
||||
{
|
||||
make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map));
|
||||
register_ipr_controller(&ipr_irq_desc);
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
/* Register the URAM space as Node 1 */
|
||||
setup_bootmem_node(1, 0x055f0000, 0x05610000);
|
||||
}
|
||||
|
@@ -102,7 +102,20 @@ static struct intc2_data intc2_irq_table[] = {
|
||||
{ 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */
|
||||
};
|
||||
|
||||
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-sh7780",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_intc2(void)
|
||||
{
|
||||
make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
}
|
||||
|
@@ -97,7 +97,21 @@ static struct intc2_data intc2_irq_table[] = {
|
||||
{ 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */
|
||||
};
|
||||
|
||||
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",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_intc2(void)
|
||||
{
|
||||
make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
}
|
||||
|
||||
|
85
arch/sh/kernel/cpu/sh4a/setup-shx3.c
Normal file
85
arch/sh/kernel/cpu/sh4a/setup-shx3.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SH-X3 Setup
|
||||
*
|
||||
* Copyright (C) 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
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/sci.h>
|
||||
|
||||
static struct plat_sci_port sci_platform_data[] = {
|
||||
{
|
||||
.mapbase = 0xffc30000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 40, 41, 43, 42 },
|
||||
}, {
|
||||
.mapbase = 0xffc40000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 44, 45, 47, 46 },
|
||||
}, {
|
||||
.mapbase = 0xffc50000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { 48, 49, 51, 50 },
|
||||
}, {
|
||||
.mapbase = 0xffc60000,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.type = PORT_SCIF,
|
||||
.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 *shx3_devices[] __initdata = {
|
||||
&sci_device,
|
||||
};
|
||||
|
||||
static int __init shx3_devices_setup(void)
|
||||
{
|
||||
return platform_add_devices(shx3_devices,
|
||||
ARRAY_SIZE(shx3_devices));
|
||||
}
|
||||
__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 */
|
||||
};
|
||||
|
||||
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",
|
||||
},
|
||||
};
|
||||
|
||||
void __init init_IRQ_intc2(void)
|
||||
{
|
||||
register_intc2_controller(&intc2_irq_desc);
|
||||
}
|
@@ -158,15 +158,11 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
/*
|
||||
* These should really be __section__(".bss.page_aligned") as well, but
|
||||
* gcc's 3.0 and earlier don't handle that correctly.
|
||||
*/
|
||||
static char softirq_stack[NR_CPUS * THREAD_SIZE]
|
||||
__attribute__((__aligned__(THREAD_SIZE)));
|
||||
__attribute__((__section__(".bss.page_aligned")));
|
||||
|
||||
static char hardirq_stack[NR_CPUS * THREAD_SIZE]
|
||||
__attribute__((__aligned__(THREAD_SIZE)));
|
||||
__attribute__((__section__(".bss.page_aligned")));
|
||||
|
||||
/*
|
||||
* allocate per-cpu stacks for hardirq and for softirq processing
|
||||
|
130
arch/sh/kernel/machvec.c
Normal file
130
arch/sh/kernel/machvec.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* arch/sh/kernel/machvec.c
|
||||
*
|
||||
* The SuperH machine vector setup handlers, yanked from setup.c
|
||||
*
|
||||
* Copyright (C) 1999 Niibe Yutaka
|
||||
* Copyright (C) 2002 - 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
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#define MV_NAME_SIZE 32
|
||||
|
||||
#define for_each_mv(mv) \
|
||||
for ((mv) = (struct sh_machine_vector *)&__machvec_start; \
|
||||
(mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \
|
||||
(mv)++)
|
||||
|
||||
static struct sh_machine_vector * __init get_mv_byname(const char *name)
|
||||
{
|
||||
struct sh_machine_vector *mv;
|
||||
|
||||
for_each_mv(mv)
|
||||
if (strcasecmp(name, mv->mv_name) == 0)
|
||||
return mv;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned int __initdata machvec_selected;
|
||||
|
||||
static int __init early_parse_mv(char *from)
|
||||
{
|
||||
char mv_name[MV_NAME_SIZE] = "";
|
||||
char *mv_end;
|
||||
char *mv_comma;
|
||||
int mv_len;
|
||||
struct sh_machine_vector *mvp;
|
||||
|
||||
mv_end = strchr(from, ' ');
|
||||
if (mv_end == NULL)
|
||||
mv_end = from + strlen(from);
|
||||
|
||||
mv_comma = strchr(from, ',');
|
||||
mv_len = mv_end - from;
|
||||
if (mv_len > (MV_NAME_SIZE-1))
|
||||
mv_len = MV_NAME_SIZE-1;
|
||||
memcpy(mv_name, from, mv_len);
|
||||
mv_name[mv_len] = '\0';
|
||||
from = mv_end;
|
||||
|
||||
machvec_selected = 1;
|
||||
|
||||
/* Boot with the generic vector */
|
||||
if (strcmp(mv_name, "generic") == 0)
|
||||
return 0;
|
||||
|
||||
mvp = get_mv_byname(mv_name);
|
||||
if (unlikely(!mvp)) {
|
||||
printk("Available vectors:\n\n\t'%s', ", sh_mv.mv_name);
|
||||
for_each_mv(mvp)
|
||||
printk("'%s', ", mvp->mv_name);
|
||||
printk("\n\n");
|
||||
panic("Failed to select machvec '%s' -- halting.\n",
|
||||
mv_name);
|
||||
} else
|
||||
sh_mv = *mvp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("sh_mv", early_parse_mv);
|
||||
|
||||
void __init sh_mv_setup(void)
|
||||
{
|
||||
/*
|
||||
* Only overload the machvec if one hasn't been selected on
|
||||
* the command line with sh_mv=
|
||||
*/
|
||||
if (!machvec_selected) {
|
||||
unsigned long machvec_size;
|
||||
|
||||
machvec_size = ((unsigned long)&__machvec_end -
|
||||
(unsigned long)&__machvec_start);
|
||||
|
||||
/*
|
||||
* If the machvec hasn't been preselected, use the first
|
||||
* vector (usually the only one) from .machvec.init.
|
||||
*/
|
||||
if (machvec_size >= sizeof(struct sh_machine_vector))
|
||||
sh_mv = *(struct sh_machine_vector *)&__machvec_start;
|
||||
}
|
||||
|
||||
printk(KERN_NOTICE "Booting machvec: %s\n", get_system_type());
|
||||
|
||||
/*
|
||||
* Manually walk the vec, fill in anything that the board hasn't yet
|
||||
* by hand, wrapping to the generic implementation.
|
||||
*/
|
||||
#define mv_set(elem) do { \
|
||||
if (!sh_mv.mv_##elem) \
|
||||
sh_mv.mv_##elem = generic_##elem; \
|
||||
} while (0)
|
||||
|
||||
mv_set(inb); mv_set(inw); mv_set(inl);
|
||||
mv_set(outb); mv_set(outw); mv_set(outl);
|
||||
|
||||
mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
|
||||
mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
|
||||
|
||||
mv_set(insb); mv_set(insw); mv_set(insl);
|
||||
mv_set(outsb); mv_set(outsw); mv_set(outsl);
|
||||
|
||||
mv_set(readb); mv_set(readw); mv_set(readl);
|
||||
mv_set(writeb); mv_set(writew); mv_set(writel);
|
||||
|
||||
mv_set(ioport_map);
|
||||
mv_set(ioport_unmap);
|
||||
mv_set(irq_demux);
|
||||
|
||||
if (!sh_mv.mv_nr_irqs)
|
||||
sh_mv.mv_nr_irqs = NR_IRQS;
|
||||
}
|
@@ -17,6 +17,7 @@
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgalloc.h>
|
||||
@@ -319,9 +320,7 @@ static void ubc_set_tracing(int asid, unsigned long pc)
|
||||
ctrl_outl(pc, UBC_BARA);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
/* We don't have any ASID settings for the SH-2! */
|
||||
if (current_cpu_data.type != CPU_SH7604)
|
||||
ctrl_outb(asid, UBC_BASRA);
|
||||
ctrl_outb(asid, UBC_BASRA);
|
||||
#endif
|
||||
|
||||
ctrl_outl(0, UBC_BAMRA);
|
||||
@@ -405,8 +404,8 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
#ifdef CONFIG_MMU
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL);
|
||||
#else
|
||||
/* fork almost works, enough to trick you into looking elsewhere :-( */
|
||||
@@ -449,23 +448,20 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
|
||||
/*
|
||||
* sys_execve() executes a new program.
|
||||
*/
|
||||
asmlinkage int sys_execve(char *ufilename, char **uargv,
|
||||
char **uenvp, unsigned long r7,
|
||||
asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
|
||||
char __user * __user *uenvp, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
int error;
|
||||
char *filename;
|
||||
|
||||
filename = getname((char __user *)ufilename);
|
||||
filename = getname(ufilename);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename,
|
||||
(char __user * __user *)uargv,
|
||||
(char __user * __user *)uenvp,
|
||||
regs);
|
||||
error = do_execve(filename, uargv, uenvp, regs);
|
||||
if (error == 0) {
|
||||
task_lock(current);
|
||||
current->ptrace &= ~PT_DTRACE;
|
||||
|
@@ -99,7 +99,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
ret = -EIO;
|
||||
if (copied != sizeof(tmp))
|
||||
break;
|
||||
ret = put_user(tmp,(unsigned long *) data);
|
||||
ret = put_user(tmp,(unsigned long __user *) data);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
tmp = !!tsk_used_math(child);
|
||||
else
|
||||
tmp = 0;
|
||||
ret = put_user(tmp, (unsigned long *)data);
|
||||
ret = put_user(tmp, (unsigned long __user *)data);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
|
||||
case PTRACE_SINGLESTEP: { /* set the trap flag. */
|
||||
long pc;
|
||||
struct pt_regs *dummy = NULL;
|
||||
struct pt_regs *regs = NULL;
|
||||
|
||||
ret = -EIO;
|
||||
if (!valid_signal(data))
|
||||
@@ -207,7 +207,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
child->ptrace |= PT_DTRACE;
|
||||
}
|
||||
|
||||
pc = get_stack_long(child, (long)&dummy->pc);
|
||||
pc = get_stack_long(child, (long)®s->pc);
|
||||
|
||||
/* Next scheduling will set up UBC */
|
||||
if (child->thread.ubc_pc == 0)
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <linux/kexec.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/setup.h>
|
||||
@@ -41,20 +42,19 @@ extern void * __rd_start, * __rd_end;
|
||||
* The bigger value means no problem.
|
||||
*/
|
||||
struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
|
||||
|
||||
/*
|
||||
* The machine vector. First entry in .machvec.init, or clobbered by
|
||||
* sh_mv= on the command line, prior to .machvec.init teardown.
|
||||
*/
|
||||
struct sh_machine_vector sh_mv = { .mv_name = "generic", };
|
||||
|
||||
#ifdef CONFIG_VT
|
||||
struct screen_info screen_info;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SH_UNKNOWN)
|
||||
struct sh_machine_vector sh_mv;
|
||||
#endif
|
||||
|
||||
extern int root_mountflags;
|
||||
|
||||
#define MV_NAME_SIZE 32
|
||||
|
||||
static struct sh_machine_vector* __init get_mv_byname(const char* name);
|
||||
|
||||
/*
|
||||
* This is set up by the setup-routine at boot-time
|
||||
*/
|
||||
@@ -80,131 +80,17 @@ static struct resource data_resource = { .name = "Kernel data", };
|
||||
|
||||
unsigned long memory_start, memory_end;
|
||||
|
||||
static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
|
||||
struct sh_machine_vector** mvp,
|
||||
unsigned long *mv_io_base)
|
||||
static int __init early_parse_mem(char *p)
|
||||
{
|
||||
char c = ' ', *to = command_line, *from = COMMAND_LINE;
|
||||
int len = 0;
|
||||
|
||||
/* Save unparsed command line copy for /proc/cmdline */
|
||||
memcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
|
||||
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
|
||||
unsigned long size;
|
||||
|
||||
memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
|
||||
memory_end = memory_start + __MEMORY_SIZE;
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
* "mem=XXX[kKmM]" defines a size of memory.
|
||||
*/
|
||||
if (c == ' ' && !memcmp(from, "mem=", 4)) {
|
||||
if (to != command_line)
|
||||
to--;
|
||||
{
|
||||
unsigned long mem_size;
|
||||
|
||||
mem_size = memparse(from+4, &from);
|
||||
memory_end = memory_start + mem_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
|
||||
char* mv_end;
|
||||
char* mv_comma;
|
||||
int mv_len;
|
||||
if (to != command_line)
|
||||
to--;
|
||||
from += 6;
|
||||
mv_end = strchr(from, ' ');
|
||||
if (mv_end == NULL)
|
||||
mv_end = from + strlen(from);
|
||||
|
||||
mv_comma = strchr(from, ',');
|
||||
if ((mv_comma != NULL) && (mv_comma < mv_end)) {
|
||||
int ints[3];
|
||||
get_options(mv_comma+1, ARRAY_SIZE(ints), ints);
|
||||
*mv_io_base = ints[1];
|
||||
mv_len = mv_comma - from;
|
||||
} else {
|
||||
mv_len = mv_end - from;
|
||||
}
|
||||
if (mv_len > (MV_NAME_SIZE-1))
|
||||
mv_len = MV_NAME_SIZE-1;
|
||||
memcpy(mv_name, from, mv_len);
|
||||
mv_name[mv_len] = '\0';
|
||||
from = mv_end;
|
||||
|
||||
*mvp = get_mv_byname(mv_name);
|
||||
}
|
||||
|
||||
c = *(from++);
|
||||
if (!c)
|
||||
break;
|
||||
if (COMMAND_LINE_SIZE <= ++len)
|
||||
break;
|
||||
*(to++) = c;
|
||||
}
|
||||
*to = '\0';
|
||||
*cmdline_p = command_line;
|
||||
}
|
||||
|
||||
static int __init sh_mv_setup(char **cmdline_p)
|
||||
{
|
||||
#ifdef CONFIG_SH_UNKNOWN
|
||||
extern struct sh_machine_vector mv_unknown;
|
||||
#endif
|
||||
struct sh_machine_vector *mv = NULL;
|
||||
char mv_name[MV_NAME_SIZE] = "";
|
||||
unsigned long mv_io_base = 0;
|
||||
|
||||
parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base);
|
||||
|
||||
#ifdef CONFIG_SH_UNKNOWN
|
||||
if (mv == NULL) {
|
||||
mv = &mv_unknown;
|
||||
if (*mv_name != '\0') {
|
||||
printk("Warning: Unsupported machine %s, using unknown\n",
|
||||
mv_name);
|
||||
}
|
||||
}
|
||||
sh_mv = *mv;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Manually walk the vec, fill in anything that the board hasn't yet
|
||||
* by hand, wrapping to the generic implementation.
|
||||
*/
|
||||
#define mv_set(elem) do { \
|
||||
if (!sh_mv.mv_##elem) \
|
||||
sh_mv.mv_##elem = generic_##elem; \
|
||||
} while (0)
|
||||
|
||||
mv_set(inb); mv_set(inw); mv_set(inl);
|
||||
mv_set(outb); mv_set(outw); mv_set(outl);
|
||||
|
||||
mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
|
||||
mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
|
||||
|
||||
mv_set(insb); mv_set(insw); mv_set(insl);
|
||||
mv_set(outsb); mv_set(outsw); mv_set(outsl);
|
||||
|
||||
mv_set(readb); mv_set(readw); mv_set(readl);
|
||||
mv_set(writeb); mv_set(writew); mv_set(writel);
|
||||
|
||||
mv_set(ioport_map);
|
||||
mv_set(ioport_unmap);
|
||||
mv_set(irq_demux);
|
||||
|
||||
#ifdef CONFIG_SH_UNKNOWN
|
||||
__set_io_port_base(mv_io_base);
|
||||
#endif
|
||||
|
||||
if (!sh_mv.mv_nr_irqs)
|
||||
sh_mv.mv_nr_irqs = NR_IRQS;
|
||||
size = memparse(p, &p);
|
||||
memory_end = memory_start + size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("mem", early_parse_mem);
|
||||
|
||||
/*
|
||||
* Register fully available low RAM pages with the bootmem allocator.
|
||||
@@ -230,7 +116,7 @@ static void __init register_bootmem_low_pages(void)
|
||||
free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
|
||||
}
|
||||
|
||||
void __init setup_bootmem_allocator(unsigned long start_pfn)
|
||||
void __init setup_bootmem_allocator(unsigned long free_pfn)
|
||||
{
|
||||
unsigned long bootmap_size;
|
||||
|
||||
@@ -239,9 +125,10 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
|
||||
* bootstrap step all allocations (until the page allocator
|
||||
* is intact) must be done via bootmem_alloc().
|
||||
*/
|
||||
bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
|
||||
bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
|
||||
min_low_pfn, max_low_pfn);
|
||||
|
||||
add_active_range(0, min_low_pfn, max_low_pfn);
|
||||
register_bootmem_low_pages();
|
||||
|
||||
node_set_online(0);
|
||||
@@ -254,7 +141,7 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
|
||||
* an invalid RAM area.
|
||||
*/
|
||||
reserve_bootmem(__MEMORY_START+PAGE_SIZE,
|
||||
(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
|
||||
(PFN_PHYS(free_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
|
||||
|
||||
/*
|
||||
* reserve physical page 0 - it's a special BIOS page on many boxes,
|
||||
@@ -262,6 +149,8 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
|
||||
*/
|
||||
reserve_bootmem(__MEMORY_START, PAGE_SIZE);
|
||||
|
||||
sparse_memory_present_with_active_regions(0);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
|
||||
if (&__rd_start != &__rd_end) {
|
||||
@@ -315,10 +204,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
{
|
||||
enable_mmu();
|
||||
|
||||
#ifdef CONFIG_CMDLINE_BOOL
|
||||
strcpy(COMMAND_LINE, CONFIG_CMDLINE);
|
||||
#endif
|
||||
|
||||
ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_RAM
|
||||
@@ -339,9 +224,22 @@ void __init setup_arch(char **cmdline_p)
|
||||
data_resource.start = virt_to_phys(_etext);
|
||||
data_resource.end = virt_to_phys(_edata)-1;
|
||||
|
||||
memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
|
||||
memory_end = memory_start + __MEMORY_SIZE;
|
||||
|
||||
#ifdef CONFIG_CMDLINE_BOOL
|
||||
strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
|
||||
#else
|
||||
strlcpy(command_line, COMMAND_LINE, sizeof(command_line));
|
||||
#endif
|
||||
|
||||
/* Save unparsed command line copy for /proc/cmdline */
|
||||
memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
|
||||
*cmdline_p = command_line;
|
||||
|
||||
parse_early_param();
|
||||
|
||||
sh_mv_setup(cmdline_p);
|
||||
sh_mv_setup();
|
||||
|
||||
/*
|
||||
* Find the highest page frame number we have available
|
||||
@@ -355,8 +253,9 @@ void __init setup_arch(char **cmdline_p)
|
||||
min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
|
||||
|
||||
nodes_clear(node_online_map);
|
||||
|
||||
/* Setup bootmem with available RAM */
|
||||
setup_memory();
|
||||
paging_init();
|
||||
sparse_init();
|
||||
|
||||
#ifdef CONFIG_DUMMY_CONSOLE
|
||||
@@ -366,46 +265,13 @@ void __init setup_arch(char **cmdline_p)
|
||||
/* Perform the machine specific initialisation */
|
||||
if (likely(sh_mv.mv_setup))
|
||||
sh_mv.mv_setup(cmdline_p);
|
||||
|
||||
paging_init();
|
||||
}
|
||||
|
||||
struct sh_machine_vector* __init get_mv_byname(const char* name)
|
||||
{
|
||||
extern long __machvec_start, __machvec_end;
|
||||
struct sh_machine_vector *all_vecs =
|
||||
(struct sh_machine_vector *)&__machvec_start;
|
||||
|
||||
int i, n = ((unsigned long)&__machvec_end
|
||||
- (unsigned long)&__machvec_start)/
|
||||
sizeof(struct sh_machine_vector);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
struct sh_machine_vector *mv = &all_vecs[i];
|
||||
if (mv == NULL)
|
||||
continue;
|
||||
if (strcasecmp(name, get_system_type()) == 0) {
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct cpu cpu[NR_CPUS];
|
||||
|
||||
static int __init topology_init(void)
|
||||
{
|
||||
int cpu_id;
|
||||
|
||||
for_each_possible_cpu(cpu_id)
|
||||
register_cpu(&cpu[cpu_id], cpu_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(topology_init);
|
||||
|
||||
static const char *cpu_name[] = {
|
||||
[CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
|
||||
[CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300",
|
||||
[CPU_SH7300] = "SH7300",
|
||||
[CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
|
||||
[CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
|
||||
[CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
|
||||
@@ -419,7 +285,7 @@ static const char *cpu_name[] = {
|
||||
[CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780",
|
||||
[CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343",
|
||||
[CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722",
|
||||
[CPU_SH_NONE] = "Unknown"
|
||||
[CPU_SHX3] = "SH-X3", [CPU_SH_NONE] = "Unknown"
|
||||
};
|
||||
|
||||
const char *get_cpu_subtype(struct sh_cpuinfo *c)
|
||||
|
@@ -78,6 +78,16 @@ DECLARE_EXPORT(__movstr);
|
||||
DECLARE_EXPORT(__movmem_i4_even);
|
||||
DECLARE_EXPORT(__movmem_i4_odd);
|
||||
DECLARE_EXPORT(__movmemSI12_i4);
|
||||
|
||||
#if (__GNUC_MINOR__ == 2 || defined(__GNUC_STM_RELEASE__))
|
||||
/*
|
||||
* GCC 4.2 emits these for division, as do GCC 4.1.x versions of the ST
|
||||
* compiler which include backported patches.
|
||||
*/
|
||||
DECLARE_EXPORT(__sdivsi3_i4i);
|
||||
DECLARE_EXPORT(__udiv_qrnnd_16);
|
||||
DECLARE_EXPORT(__udivsi3_i4i);
|
||||
#endif
|
||||
#else /* GCC 3.x */
|
||||
DECLARE_EXPORT(__movstr_i4_even);
|
||||
DECLARE_EXPORT(__movstr_i4_odd);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <linux/personality.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/uaccess.h>
|
||||
@@ -261,7 +262,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
|
||||
goto badframe;
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
do_sigaltstack(&st, NULL, regs->regs[15]);
|
||||
do_sigaltstack((const stack_t __user *)&st, NULL, (unsigned long)frame);
|
||||
|
||||
return r0;
|
||||
|
||||
|
@@ -308,9 +308,9 @@ ENTRY(sys_call_table)
|
||||
.long sys_utimes
|
||||
.long sys_fadvise64_64_wrapper
|
||||
.long sys_ni_syscall /* Reserved for vserver */
|
||||
.long sys_ni_syscall /* Reserved for mbind */
|
||||
.long sys_ni_syscall /* 275 - get_mempolicy */
|
||||
.long sys_ni_syscall /* set_mempolicy */
|
||||
.long sys_mbind
|
||||
.long sys_get_mempolicy /* 275 */
|
||||
.long sys_set_mempolicy
|
||||
.long sys_mq_open
|
||||
.long sys_mq_unlink
|
||||
.long sys_mq_timedsend
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
static int tmu_timer_start(void)
|
||||
{
|
||||
ctrl_outb(ctrl_inb(TMU_TSTR) | 0x3, TMU_TSTR);
|
||||
ctrl_outb(ctrl_inb(TMU_012_TSTR) | 0x3, TMU_012_TSTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ static void tmu0_timer_set_interval(unsigned long interval, unsigned int reload)
|
||||
|
||||
static int tmu_timer_stop(void)
|
||||
{
|
||||
ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x3, TMU_TSTR);
|
||||
ctrl_outb(ctrl_inb(TMU_012_TSTR) & ~0x3, TMU_012_TSTR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,8 @@ static int tmu_timer_init(void)
|
||||
|
||||
#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \
|
||||
!defined(CONFIG_CPU_SUBTYPE_SH7760) && \
|
||||
!defined(CONFIG_CPU_SUBTYPE_SH7785)
|
||||
!defined(CONFIG_CPU_SUBTYPE_SH7785) && \
|
||||
!defined(CONFIG_CPU_SUBTYPE_SHX3)
|
||||
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
|
||||
#endif
|
||||
|
||||
|
49
arch/sh/kernel/topology.c
Normal file
49
arch/sh/kernel/topology.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* arch/sh/kernel/topology.c
|
||||
*
|
||||
* Copyright (C) 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
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/node.h>
|
||||
#include <linux/nodemask.h>
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
static int __init topology_init(void)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
#ifdef CONFIG_NEED_MULTIPLE_NODES
|
||||
for_each_online_node(i)
|
||||
register_one_node(i);
|
||||
#endif
|
||||
|
||||
for_each_present_cpu(i) {
|
||||
ret = register_cpu(&per_cpu(cpu_devices, i), i);
|
||||
if (unlikely(ret))
|
||||
printk(KERN_WARNING "%s: register_cpu %d failed (%d)\n",
|
||||
__FUNCTION__, i, ret);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NUMA) && !defined(CONFIG_SMP)
|
||||
/*
|
||||
* In the UP case, make sure the CPU association is still
|
||||
* registered under each node. Without this, sysfs fails
|
||||
* to make the connection between nodes other than node0
|
||||
* and cpu0.
|
||||
*/
|
||||
for_each_online_node(i)
|
||||
if (i != numa_node_id())
|
||||
register_cpu_under_node(raw_smp_processor_id(), i);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(topology_init);
|
@@ -584,7 +584,7 @@ uspace_segv:
|
||||
info.si_signo = SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = si_code;
|
||||
info.si_addr = (void *) address;
|
||||
info.si_addr = (void __user *)address;
|
||||
force_sig_info(SIGBUS, &info, current);
|
||||
} else {
|
||||
if (regs->pc & 1)
|
||||
@@ -617,7 +617,7 @@ uspace_segv:
|
||||
*/
|
||||
int is_dsp_inst(struct pt_regs *regs)
|
||||
{
|
||||
unsigned short inst;
|
||||
unsigned short inst = 0;
|
||||
|
||||
/*
|
||||
* Safe guard if DSP mode is already enabled or we're lacking
|
||||
@@ -645,7 +645,6 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
|
||||
unsigned long r6, unsigned long r7,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
siginfo_t info;
|
||||
|
||||
switch (r4) {
|
||||
|
@@ -97,18 +97,20 @@ SECTIONS
|
||||
__initramfs_end = .;
|
||||
#endif
|
||||
|
||||
. = ALIGN(4);
|
||||
__machvec_start = .;
|
||||
.init.machvec : { *(.init.machvec) }
|
||||
.machvec.init : { *(.machvec.init) }
|
||||
__machvec_end = .;
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .; /* BSS */
|
||||
.bss : { *(.bss) }
|
||||
|
||||
. = ALIGN(4);
|
||||
_end = . ;
|
||||
.bss : {
|
||||
__init_end = .;
|
||||
__bss_start = .; /* BSS */
|
||||
*(.bss.page_aligned)
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_end = . ;
|
||||
}
|
||||
|
||||
/* When something in the kernel is NOT compiled as a module, the
|
||||
* module cleanup code and data are put into these segments. Both
|
||||
|
Reference in New Issue
Block a user