diff --git a/[refs] b/[refs]
index dacbebffb9ff..6a521089e6dc 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 0efdf2626676db4b30d343ff88f8461ad09130da
+refs/heads/master: 383956a9c59157db4c404d1c8bb9074b8dfe3ee0
diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile
index 36526a1e76d7..db9499adbed4 100644
--- a/trunk/Documentation/DocBook/Makefile
+++ b/trunk/Documentation/DocBook/Makefile
@@ -190,13 +190,9 @@ quiet_cmd_fig2png = FIG2PNG $@
###
# Help targets as used by the top-level makefile
dochelp:
- @echo ' Linux kernel internal documentation in different formats:'
- @echo ' htmldocs - HTML'
- @echo ' installmandocs - install man pages generated by mandocs'
- @echo ' mandocs - man pages'
- @echo ' pdfdocs - PDF'
- @echo ' psdocs - Postscript'
- @echo ' xmldocs - XML DocBook'
+ @echo ' Linux kernel internal documentation in different formats:'
+ @echo ' xmldocs (XML DocBook), psdocs (Postscript), pdfdocs (PDF)'
+ @echo ' htmldocs (HTML), mandocs (man pages, use installmandocs to install)'
###
# Temporary files left by various tools
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index 2e1898e4e8fd..15e4fed127f6 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -1416,11 +1416,6 @@ and is between 256 and 4096 characters. It is defined in the file
scsi_logging= [SCSI]
- scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are
- discovered. async scans them in kernel threads,
- allowing boot to proceed. none ignores them, expecting
- user space to do the scan.
-
selinux [SELINUX] Disable or enable SELinux at boot time.
Format: { "0" | "1" }
See security/selinux/Kconfig help text.
diff --git a/trunk/Documentation/scsi/scsi_mid_low_api.txt b/trunk/Documentation/scsi/scsi_mid_low_api.txt
index 6f70f2b9327e..75a535a975c3 100644
--- a/trunk/Documentation/scsi/scsi_mid_low_api.txt
+++ b/trunk/Documentation/scsi/scsi_mid_low_api.txt
@@ -375,6 +375,7 @@ Summary:
scsi_add_device - creates new scsi device (lu) instance
scsi_add_host - perform sysfs registration and set up transport class
scsi_adjust_queue_depth - change the queue depth on a SCSI device
+ scsi_assign_lock - replace default host_lock with given lock
scsi_bios_ptable - return copy of block device's partition table
scsi_block_requests - prevent further commands being queued to given host
scsi_deactivate_tcq - turn off tag command queueing
@@ -487,6 +488,20 @@ void scsi_adjust_queue_depth(struct scsi_device * sdev, int tagged,
int tags)
+/**
+ * scsi_assign_lock - replace default host_lock with given lock
+ * @shost: a pointer to a scsi host instance
+ * @lock: pointer to lock to replace host_lock for this host
+ *
+ * Returns nothing
+ *
+ * Might block: no
+ *
+ * Defined in: include/scsi/scsi_host.h .
+ **/
+void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
+
+
/**
* scsi_bios_ptable - return copy of block device's partition table
* @dev: pointer to block device
@@ -1351,11 +1366,17 @@ Locks
Each struct Scsi_Host instance has a spin_lock called struct
Scsi_Host::default_lock which is initialized in scsi_host_alloc() [found in
hosts.c]. Within the same function the struct Scsi_Host::host_lock pointer
-is initialized to point at default_lock. Thereafter lock and unlock
-operations performed by the mid level use the struct Scsi_Host::host_lock
-pointer. Previously drivers could override the host_lock pointer but
-this is not allowed anymore.
-
+is initialized to point at default_lock with the scsi_assign_lock() function.
+Thereafter lock and unlock operations performed by the mid level use the
+struct Scsi_Host::host_lock pointer.
+
+LLDs can override the use of struct Scsi_Host::default_lock by
+using scsi_assign_lock(). The earliest opportunity to do this would
+be in the detect() function after it has invoked scsi_register(). It
+could be replaced by a coarser grain lock (e.g. per driver) or a
+lock of equal granularity (i.e. per host). Using finer grain locks
+(e.g. per SCSI device) may be possible by juggling locks in
+queuecommand().
Autosense
=========
diff --git a/trunk/README b/trunk/README
index c05561523029..3e264723b863 100644
--- a/trunk/README
+++ b/trunk/README
@@ -1,4 +1,4 @@
- Linux kernel release 2.6.xx
+ Linux kernel release 2.6.xx
These are the release notes for Linux version 2.6. Read them carefully,
as they tell you what this is all about, explain how to install the
@@ -22,17 +22,15 @@ ON WHAT HARDWARE DOES IT RUN?
Although originally developed first for 32-bit x86-based PCs (386 or higher),
today Linux also runs on (at least) the Compaq Alpha AXP, Sun SPARC and
- UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell,
+ UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH,
IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64, AXIS CRIS,
- Cris, Xtensa, AVR32 and Renesas M32R architectures.
+ and Renesas M32R architectures.
Linux is easily portable to most general-purpose 32- or 64-bit architectures
as long as they have a paged memory management unit (PMMU) and a port of the
GNU C compiler (gcc) (part of The GNU Compiler Collection, GCC). Linux has
also been ported to a number of architectures without a PMMU, although
functionality is then obviously somewhat limited.
- Linux has also been ported to itself. You can now run the kernel as a
- userspace application - this is called UserMode Linux (UML).
DOCUMENTATION:
@@ -115,7 +113,6 @@ INSTALLING the kernel:
version 2.6.12.2 and want to jump to 2.6.12.3, you must first
reverse the 2.6.12.2 patch (that is, patch -R) _before_ applying
the 2.6.12.3 patch.
- You can read more on this in Documentation/applying-patches.txt
- Make sure you have no stale .o files and dependencies lying around:
@@ -164,7 +161,6 @@ CONFIGURING the kernel:
only ask you for the answers to new questions.
- Alternate configuration commands are:
- "make config" Plain text interface.
"make menuconfig" Text based color menus, radiolists & dialogs.
"make xconfig" X windows (Qt) based configuration tool.
"make gconfig" X windows (Gtk) based configuration tool.
@@ -307,9 +303,8 @@ IF SOMETHING GOES WRONG:
- If you compiled the kernel with CONFIG_KALLSYMS you can send the dump
as is, otherwise you will have to use the "ksymoops" program to make
- sense of the dump (but compiling with CONFIG_KALLSYMS is usually preferred).
- This utility can be downloaded from
- ftp://ftp..kernel.org/pub/linux/utils/kernel/ksymoops/ .
+ sense of the dump. This utility can be downloaded from
+ ftp://ftp..kernel.org/pub/linux/utils/kernel/ksymoops.
Alternately you can do the dump lookup by hand:
- In debugging dumps like the above, it helps enormously if you can
@@ -341,7 +336,7 @@ IF SOMETHING GOES WRONG:
If you for some reason cannot do the above (you have a pre-compiled
kernel image or similar), telling me as much about your setup as
- possible will help. Please read the REPORTING-BUGS document for details.
+ possible will help.
- Alternately, you can use gdb on a running kernel. (read-only; i.e. you
cannot change values or set break points.) To do this, first compile the
diff --git a/trunk/arch/arm/common/sharpsl_pm.c b/trunk/arch/arm/common/sharpsl_pm.c
index b3599743093b..605dedf96790 100644
--- a/trunk/arch/arm/common/sharpsl_pm.c
+++ b/trunk/arch/arm/common/sharpsl_pm.c
@@ -60,16 +60,16 @@ static int sharpsl_ac_check(void);
static int sharpsl_fatal_check(void);
static int sharpsl_average_value(int ad);
static void sharpsl_average_clear(void);
-static void sharpsl_charge_toggle(struct work_struct *private_);
-static void sharpsl_battery_thread(struct work_struct *private_);
+static void sharpsl_charge_toggle(void *private_);
+static void sharpsl_battery_thread(void *private_);
/*
* Variables
*/
struct sharpsl_pm_status sharpsl_pm;
-DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle);
-DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread);
+DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
+DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
@@ -116,7 +116,7 @@ void sharpsl_battery_kick(void)
EXPORT_SYMBOL(sharpsl_battery_kick);
-static void sharpsl_battery_thread(struct work_struct *private_)
+static void sharpsl_battery_thread(void *private_)
{
int voltage, percent, apm_status, i = 0;
@@ -128,7 +128,7 @@ static void sharpsl_battery_thread(struct work_struct *private_)
/* Corgi cannot confirm when battery fully charged so periodically kick! */
if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON)
&& time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
- schedule_delayed_work(&toggle_charger, 0);
+ schedule_work(&toggle_charger);
while(1) {
voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
@@ -212,7 +212,7 @@ static void sharpsl_charge_off(void)
sharpsl_pm_led(SHARPSL_LED_OFF);
sharpsl_pm.charge_mode = CHRG_OFF;
- schedule_delayed_work(&sharpsl_bat, 0);
+ schedule_work(&sharpsl_bat);
}
static void sharpsl_charge_error(void)
@@ -222,7 +222,7 @@ static void sharpsl_charge_error(void)
sharpsl_pm.charge_mode = CHRG_ERROR;
}
-static void sharpsl_charge_toggle(struct work_struct *private_)
+static void sharpsl_charge_toggle(void *private_)
{
dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
@@ -254,7 +254,7 @@ static void sharpsl_ac_timer(unsigned long data)
else if (sharpsl_pm.charge_mode == CHRG_ON)
sharpsl_charge_off();
- schedule_delayed_work(&sharpsl_bat, 0);
+ schedule_work(&sharpsl_bat);
}
@@ -279,10 +279,10 @@ static void sharpsl_chrg_full_timer(unsigned long data)
sharpsl_charge_off();
} else if (sharpsl_pm.full_count < 2) {
dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
- schedule_delayed_work(&toggle_charger, 0);
+ schedule_work(&toggle_charger);
} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
- schedule_delayed_work(&toggle_charger, 0);
+ schedule_work(&toggle_charger);
} else {
sharpsl_charge_off();
sharpsl_pm.charge_mode = CHRG_DONE;
diff --git a/trunk/arch/arm/mach-omap1/board-h3.c b/trunk/arch/arm/mach-omap1/board-h3.c
index 9d2346fb68f4..f225a083dee1 100644
--- a/trunk/arch/arm/mach-omap1/board-h3.c
+++ b/trunk/arch/arm/mach-omap1/board-h3.c
@@ -323,8 +323,7 @@ static int h3_transceiver_mode(struct device *dev, int mode)
cancel_delayed_work(&irda_config->gpio_expa);
PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
-#error this is not permitted - mode is an argument variable
- schedule_delayed_work(&irda_config->gpio_expa, 0);
+ schedule_work(&irda_config->gpio_expa);
return 0;
}
diff --git a/trunk/arch/arm/mach-omap1/board-nokia770.c b/trunk/arch/arm/mach-omap1/board-nokia770.c
index cbe909bad79b..dbc555d209ff 100644
--- a/trunk/arch/arm/mach-omap1/board-nokia770.c
+++ b/trunk/arch/arm/mach-omap1/board-nokia770.c
@@ -74,7 +74,7 @@ static struct omap_kp_platform_data nokia770_kp_data = {
.rows = 8,
.cols = 8,
.keymap = nokia770_keymap,
- .keymapsize = ARRAY_SIZE(nokia770_keymap),
+ .keymapsize = ARRAY_SIZE(nokia770_keymap)
.delay = 4,
};
@@ -191,7 +191,7 @@ static void nokia770_audio_pwr_up(void)
printk("HP connected\n");
}
-static void codec_delayed_power_down(struct work_struct *work)
+static void codec_delayed_power_down(void *arg)
{
down(&audio_pwr_sem);
if (audio_pwr_state == -1)
@@ -200,7 +200,7 @@ static void codec_delayed_power_down(struct work_struct *work)
up(&audio_pwr_sem);
}
-static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down);
+static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL);
static void nokia770_audio_pwr_down(void)
{
diff --git a/trunk/arch/arm/mach-omap1/leds-osk.c b/trunk/arch/arm/mach-omap1/leds-osk.c
index 0cbf1b0071f8..3b29e59b0e6f 100644
--- a/trunk/arch/arm/mach-omap1/leds-osk.c
+++ b/trunk/arch/arm/mach-omap1/leds-osk.c
@@ -35,7 +35,7 @@ static u8 hw_led_state;
static u8 tps_leds_change;
-static void tps_work(struct work_struct *unused)
+static void tps_work(void *unused)
{
for (;;) {
u8 leds;
@@ -61,7 +61,7 @@ static void tps_work(struct work_struct *unused)
}
}
-static DECLARE_WORK(work, tps_work);
+static DECLARE_WORK(work, tps_work, NULL);
#ifdef CONFIG_OMAP_OSK_MISTRAL
diff --git a/trunk/arch/arm/mach-omap2/board-h4.c b/trunk/arch/arm/mach-omap2/board-h4.c
index 3b1ad1d981a3..26a95a642ad7 100644
--- a/trunk/arch/arm/mach-omap2/board-h4.c
+++ b/trunk/arch/arm/mach-omap2/board-h4.c
@@ -206,8 +206,7 @@ static int h4_transceiver_mode(struct device *dev, int mode)
cancel_delayed_work(&irda_config->gpio_expa);
PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
-#error this is not permitted - mode is an argument variable
- schedule_delayed_work(&irda_config->gpio_expa, 0);
+ schedule_work(&irda_config->gpio_expa);
return 0;
}
diff --git a/trunk/arch/arm/mach-pxa/akita-ioexp.c b/trunk/arch/arm/mach-pxa/akita-ioexp.c
index 12d2fe0ceff6..1b398742ab56 100644
--- a/trunk/arch/arm/mach-pxa/akita-ioexp.c
+++ b/trunk/arch/arm/mach-pxa/akita-ioexp.c
@@ -36,11 +36,11 @@ I2C_CLIENT_INSMOD;
static int max7310_write(struct i2c_client *client, int address, int data);
static struct i2c_client max7310_template;
-static void akita_ioexp_work(struct work_struct *private_);
+static void akita_ioexp_work(void *private_);
static struct device *akita_ioexp_device;
static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
-DECLARE_WORK(akita_ioexp, akita_ioexp_work);
+DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL);
/*
@@ -158,7 +158,7 @@ void akita_reset_ioexp(struct device *dev, unsigned char bit)
EXPORT_SYMBOL(akita_set_ioexp);
EXPORT_SYMBOL(akita_reset_ioexp);
-static void akita_ioexp_work(struct work_struct *private_)
+static void akita_ioexp_work(void *private_)
{
if (akita_ioexp_device)
max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
diff --git a/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c b/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c
index 6b5d3518a1c0..1f9153ae5b03 100644
--- a/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c
+++ b/trunk/arch/i386/kernel/cpu/mcheck/non-fatal.c
@@ -51,10 +51,10 @@ static void mce_checkregs (void *info)
}
}
-static void mce_work_fn(struct work_struct *work);
-static DECLARE_DELAYED_WORK(mce_work, mce_work_fn);
+static void mce_work_fn(void *data);
+static DECLARE_WORK(mce_work, mce_work_fn, NULL);
-static void mce_work_fn(struct work_struct *work)
+static void mce_work_fn(void *data)
{
on_each_cpu(mce_checkregs, NULL, 1, 1);
schedule_delayed_work(&mce_work, MCE_RATE);
diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c
index 02a9b66b6ac3..4bb8b77cd65b 100644
--- a/trunk/arch/i386/kernel/smpboot.c
+++ b/trunk/arch/i386/kernel/smpboot.c
@@ -1049,15 +1049,13 @@ void cpu_exit_clear(void)
struct warm_boot_cpu_info {
struct completion *complete;
- struct work_struct task;
int apicid;
int cpu;
};
-static void __cpuinit do_warm_boot_cpu(struct work_struct *work)
+static void __cpuinit do_warm_boot_cpu(void *p)
{
- struct warm_boot_cpu_info *info =
- container_of(work, struct warm_boot_cpu_info, task);
+ struct warm_boot_cpu_info *info = p;
do_boot_cpu(info->apicid, info->cpu);
complete(info->complete);
}
@@ -1066,6 +1064,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
{
DECLARE_COMPLETION_ONSTACK(done);
struct warm_boot_cpu_info info;
+ struct work_struct task;
int apicid, ret;
struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
@@ -1090,7 +1089,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
info.complete = &done;
info.apicid = apicid;
info.cpu = cpu;
- INIT_WORK(&info.task, do_warm_boot_cpu);
+ INIT_WORK(&task, do_warm_boot_cpu, &info);
tsc_sync_disabled = 1;
@@ -1098,7 +1097,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
KERNEL_PGD_PTRS);
flush_tlb_all();
- schedule_work(&info.task);
+ schedule_work(&task);
wait_for_completion(&done);
tsc_sync_disabled = 0;
diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c
index 9810c8c90750..fbc95828cd74 100644
--- a/trunk/arch/i386/kernel/tsc.c
+++ b/trunk/arch/i386/kernel/tsc.c
@@ -217,7 +217,7 @@ static unsigned int cpufreq_delayed_issched = 0;
static unsigned int cpufreq_init = 0;
static struct work_struct cpufreq_delayed_get_work;
-static void handle_cpufreq_delayed_get(struct work_struct *work)
+static void handle_cpufreq_delayed_get(void *v)
{
unsigned int cpu;
@@ -306,7 +306,7 @@ static int __init cpufreq_tsc(void)
{
int ret;
- INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get);
+ INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL);
ret = cpufreq_register_notifier(&time_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (!ret)
diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c
index b62f0c4d2c7c..caab986af70c 100644
--- a/trunk/arch/ia64/hp/sim/simserial.c
+++ b/trunk/arch/ia64/hp/sim/simserial.c
@@ -209,7 +209,7 @@ static void do_serial_bh(void)
}
#endif
-static void do_softint(struct work_struct *private_)
+static void do_softint(void *private_)
{
printk(KERN_ERR "simserial: do_softint called\n");
}
@@ -698,7 +698,7 @@ static int get_async_struct(int line, struct async_struct **ret_info)
info->flags = sstate->flags;
info->xmit_fifo_size = sstate->xmit_fifo_size;
info->line = line;
- INIT_WORK(&info->work, do_softint);
+ INIT_WORK(&info->work, do_softint, info);
info->state = sstate;
if (sstate->info) {
kfree(info);
diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c
index 6bedd97570ca..7cfa63a98cb3 100644
--- a/trunk/arch/ia64/kernel/mca.c
+++ b/trunk/arch/ia64/kernel/mca.c
@@ -678,7 +678,7 @@ ia64_mca_cmc_vector_enable (void *dummy)
* disable the cmc interrupt vector.
*/
static void
-ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused)
+ia64_mca_cmc_vector_disable_keventd(void *unused)
{
on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0);
}
@@ -690,7 +690,7 @@ ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused)
* enable the cmc interrupt vector.
*/
static void
-ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused)
+ia64_mca_cmc_vector_enable_keventd(void *unused)
{
on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0);
}
@@ -1247,8 +1247,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
monarch_cpu = -1;
}
-static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd);
-static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd);
+static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL);
+static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL);
/*
* ia64_mca_cmc_int_handler
diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c
index b21ddecea943..f7d7f5668144 100644
--- a/trunk/arch/ia64/kernel/smpboot.c
+++ b/trunk/arch/ia64/kernel/smpboot.c
@@ -463,17 +463,15 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
}
struct create_idle {
- struct work_struct work;
struct task_struct *idle;
struct completion done;
int cpu;
};
void
-do_fork_idle(struct work_struct *work)
+do_fork_idle(void *_c_idle)
{
- struct create_idle *c_idle =
- container_of(work, struct create_idle, work);
+ struct create_idle *c_idle = _c_idle;
c_idle->idle = fork_idle(c_idle->cpu);
complete(&c_idle->done);
@@ -484,10 +482,10 @@ do_boot_cpu (int sapicid, int cpu)
{
int timeout;
struct create_idle c_idle = {
- .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
.cpu = cpu,
.done = COMPLETION_INITIALIZER(c_idle.done),
};
+ DECLARE_WORK(work, do_fork_idle, &c_idle);
c_idle.idle = get_idle_for_cpu(cpu);
if (c_idle.idle) {
@@ -499,9 +497,9 @@ do_boot_cpu (int sapicid, int cpu)
* We can't use kernel_thread since we must avoid to reschedule the child.
*/
if (!keventd_up() || current_is_keventd())
- c_idle.work.func(&c_idle.work);
+ work.func(work.data);
else {
- schedule_work(&c_idle.work);
+ schedule_work(&work);
wait_for_completion(&c_idle.done);
}
diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c
index eb92cef9cd0d..f4edfbf27134 100644
--- a/trunk/arch/ia64/pci/pci.c
+++ b/trunk/arch/ia64/pci/pci.c
@@ -564,8 +564,8 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
void
pcibios_disable_device (struct pci_dev *dev)
{
- BUG_ON(atomic_read(&dev->enable_cnt));
- acpi_pci_irq_disable(dev);
+ if (dev->is_enabled)
+ acpi_pci_irq_disable(dev);
}
void
diff --git a/trunk/arch/m68knommu/platform/5307/timers.c b/trunk/arch/m68knommu/platform/5307/timers.c
index e5668af19789..24781f009337 100644
--- a/trunk/arch/m68knommu/platform/5307/timers.c
+++ b/trunk/arch/m68knommu/platform/5307/timers.c
@@ -3,7 +3,7 @@
/*
* timers.c -- generic ColdFire hardware timer support.
*
- * Copyright (C) 1999-2006, Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
*/
/***************************************************************************/
@@ -44,14 +44,6 @@ unsigned int mcf_timerlevel = 5;
extern void mcf_settimericr(int timer, int level);
extern int mcf_timerirqpending(int timer);
-#if defined(CONFIG_M532x)
-#define __raw_readtrr __raw_readl
-#define __raw_writetrr __raw_writel
-#else
-#define __raw_readtrr __raw_readw
-#define __raw_writetrr __raw_writew
-#endif
-
/***************************************************************************/
void coldfire_tick(void)
@@ -65,7 +57,7 @@ void coldfire_tick(void)
void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
{
__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
- __raw_writetrr(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR));
+ __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR));
__raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
@@ -84,7 +76,7 @@ unsigned long coldfire_timer_offset(void)
unsigned long trr, tcn, offset;
tcn = __raw_readw(TA(MCFTIMER_TCN));
- trr = __raw_readtrr(TA(MCFTIMER_TRR));
+ trr = __raw_readw(TA(MCFTIMER_TRR));
offset = (tcn * (1000000 / HZ)) / trr;
/* Check if we just wrapped the counters and maybe missed a tick */
@@ -128,7 +120,7 @@ void coldfire_profile_init(void)
/* Set up TIMER 2 as high speed profile clock */
__raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
- __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
+ __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
__raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
diff --git a/trunk/arch/m68knommu/platform/68360/config.c b/trunk/arch/m68knommu/platform/68360/config.c
index 1b36f6261764..c5482e3622eb 100644
--- a/trunk/arch/m68knommu/platform/68360/config.c
+++ b/trunk/arch/m68knommu/platform/68360/config.c
@@ -114,7 +114,7 @@ void BSP_gettod (int *yearp, int *monp, int *dayp,
{
}
-int BSP_hwclk(int op, struct rtc_time *t)
+int BSP_hwclk(int op, struct hwclk_time *t)
{
if (!op) {
/* read */
diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig
index d8af858fe3f5..4d64960be035 100644
--- a/trunk/arch/mips/Kconfig
+++ b/trunk/arch/mips/Kconfig
@@ -242,7 +242,6 @@ config LASAT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config MIPS_ATLAS
bool "MIPS Atlas board"
@@ -266,7 +265,6 @@ config MIPS_ATLAS
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL
- select GENERIC_HARDIRQS_NO__DO_IRQ
help
This enables support for the MIPS Technologies Atlas evaluation
board.
@@ -421,7 +419,6 @@ config MOMENCO_OCELOT_C
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
help
The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer .
@@ -572,7 +569,6 @@ config SGI_IP27
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_SMP
- select GENERIC_HARDIRQS_NO__DO_IRQ
help
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
workstations. To compile a Linux kernel that runs on these, say Y
@@ -839,10 +835,6 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER
bool
default y
-config GENERIC_HARDIRQS_NO__DO_IRQ
- bool
- default n
-
#
# Select some configuration options automatically based on user selections.
#
@@ -1004,7 +996,6 @@ config SOC_PNX8550
select HW_HAS_PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
- select GENERIC_HARDIRQS_NO__DO_IRQ
config SWAP_IO_SPACE
bool
diff --git a/trunk/arch/mips/dec/ecc-berr.c b/trunk/arch/mips/dec/ecc-berr.c
index 6d55e8aab668..c8430c07355e 100644
--- a/trunk/arch/mips/dec/ecc-berr.c
+++ b/trunk/arch/mips/dec/ecc-berr.c
@@ -25,7 +25,6 @@
#include
#include
#include
-#include
#include
#include
diff --git a/trunk/arch/mips/dec/ioasic-irq.c b/trunk/arch/mips/dec/ioasic-irq.c
index 4c7cb4048d35..269b22b34313 100644
--- a/trunk/arch/mips/dec/ioasic-irq.c
+++ b/trunk/arch/mips/dec/ioasic-irq.c
@@ -67,6 +67,7 @@ static struct irq_chip ioasic_irq_type = {
.mask = mask_ioasic_irq,
.mask_ack = ack_ioasic_irq,
.unmask = unmask_ioasic_irq,
+ .end = end_ioasic_irq,
};
@@ -105,7 +106,8 @@ void __init init_ioasic_irqs(int base)
set_irq_chip_and_handler(i, &ioasic_irq_type,
handle_level_irq);
for (; i < base + IO_IRQ_LINES; i++)
- set_irq_chip(i, &ioasic_dma_irq_type);
+ set_irq_chip_and_handler(i, &ioasic_dma_irq_type,
+ handle_level_irq);
ioasic_irq_base = base;
}
diff --git a/trunk/arch/mips/dec/kn01-berr.c b/trunk/arch/mips/dec/kn01-berr.c
index d3b8002bf1e7..f19b4617a0a6 100644
--- a/trunk/arch/mips/dec/kn01-berr.c
+++ b/trunk/arch/mips/dec/kn01-berr.c
@@ -20,10 +20,8 @@
#include
#include
-#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/mips/dec/kn02-irq.c b/trunk/arch/mips/dec/kn02-irq.c
index 916e46b8ccd8..5a9be4c93584 100644
--- a/trunk/arch/mips/dec/kn02-irq.c
+++ b/trunk/arch/mips/dec/kn02-irq.c
@@ -57,12 +57,19 @@ static void ack_kn02_irq(unsigned int irq)
iob();
}
+static void end_kn02_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ unmask_kn02_irq(irq);
+}
+
static struct irq_chip kn02_irq_type = {
.typename = "KN02-CSR",
.ack = ack_kn02_irq,
.mask = mask_kn02_irq,
.mask_ack = ack_kn02_irq,
.unmask = unmask_kn02_irq,
+ .end = end_kn02_irq,
};
diff --git a/trunk/arch/mips/emma2rh/common/irq_emma2rh.c b/trunk/arch/mips/emma2rh/common/irq_emma2rh.c
index 8d880f0b06ec..59b98299c896 100644
--- a/trunk/arch/mips/emma2rh/common/irq_emma2rh.c
+++ b/trunk/arch/mips/emma2rh/common/irq_emma2rh.c
@@ -56,12 +56,19 @@ static void emma2rh_irq_disable(unsigned int irq)
ll_emma2rh_irq_disable(irq - emma2rh_irq_base);
}
+static void emma2rh_irq_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ ll_emma2rh_irq_enable(irq - emma2rh_irq_base);
+}
+
struct irq_chip emma2rh_irq_controller = {
.typename = "emma2rh_irq",
.ack = emma2rh_irq_disable,
.mask = emma2rh_irq_disable,
.mask_ack = emma2rh_irq_disable,
.unmask = emma2rh_irq_enable,
+ .end = emma2rh_irq_end,
};
void emma2rh_irq_init(u32 irq_base)
diff --git a/trunk/arch/mips/emma2rh/markeins/irq_markeins.c b/trunk/arch/mips/emma2rh/markeins/irq_markeins.c
index 2116d9be5fa9..3ac4e405ecdc 100644
--- a/trunk/arch/mips/emma2rh/markeins/irq_markeins.c
+++ b/trunk/arch/mips/emma2rh/markeins/irq_markeins.c
@@ -48,12 +48,19 @@ static void emma2rh_sw_irq_disable(unsigned int irq)
ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base);
}
+static void emma2rh_sw_irq_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base);
+}
+
struct irq_chip emma2rh_sw_irq_controller = {
.typename = "emma2rh_sw_irq",
.ack = emma2rh_sw_irq_disable,
.mask = emma2rh_sw_irq_disable,
.mask_ack = emma2rh_sw_irq_disable,
.unmask = emma2rh_sw_irq_enable,
+ .end = emma2rh_sw_irq_end,
};
void emma2rh_sw_irq_init(u32 irq_base)
diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c
index f8d417b5c2bb..5c4f50cdf157 100644
--- a/trunk/arch/mips/jazz/irq.c
+++ b/trunk/arch/mips/jazz/irq.c
@@ -39,12 +39,19 @@ void disable_r4030_irq(unsigned int irq)
spin_unlock_irqrestore(&r4030_lock, flags);
}
+static void end_r4030_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_r4030_irq(irq);
+}
+
static struct irq_chip r4030_irq_type = {
.typename = "R4030",
.ack = disable_r4030_irq,
.mask = disable_r4030_irq,
.mask_ack = disable_r4030_irq,
.unmask = enable_r4030_irq,
+ .end = end_r4030_irq,
};
void __init init_r4030_ints(void)
diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c
index b59a676c6d0e..2526c0ca4d81 100644
--- a/trunk/arch/mips/kernel/i8259.c
+++ b/trunk/arch/mips/kernel/i8259.c
@@ -19,6 +19,9 @@
#include
#include
+void enable_8259A_irq(unsigned int irq);
+void disable_8259A_irq(unsigned int irq);
+
/*
* This is the 'legacy' 8259A Programmable Interrupt Controller,
* present in the majority of PC/AT boxes.
@@ -28,16 +31,23 @@
* moves to arch independent land
*/
-static int i8259A_auto_eoi;
DEFINE_SPINLOCK(i8259A_lock);
-/* some platforms call this... */
+
+static void end_8259A_irq (unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
+ irq_desc[irq].action)
+ enable_8259A_irq(irq);
+}
+
void mask_and_ack_8259A(unsigned int);
-static struct irq_chip i8259A_chip = {
- .name = "XT-PIC",
- .mask = disable_8259A_irq,
- .unmask = enable_8259A_irq,
- .mask_ack = mask_and_ack_8259A,
+static struct irq_chip i8259A_irq_type = {
+ .typename = "XT-PIC",
+ .enable = enable_8259A_irq,
+ .disable = disable_8259A_irq,
+ .ack = mask_and_ack_8259A,
+ .end = end_8259A_irq,
};
/*
@@ -49,8 +59,8 @@ static struct irq_chip i8259A_chip = {
*/
static unsigned int cached_irq_mask = 0xffff;
-#define cached_master_mask (cached_irq_mask)
-#define cached_slave_mask (cached_irq_mask >> 8)
+#define cached_21 (cached_irq_mask)
+#define cached_A1 (cached_irq_mask >> 8)
void disable_8259A_irq(unsigned int irq)
{
@@ -60,9 +70,9 @@ void disable_8259A_irq(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask |= mask;
if (irq & 8)
- outb(cached_slave_mask, PIC_SLAVE_IMR);
+ outb(cached_A1,0xA1);
else
- outb(cached_master_mask, PIC_MASTER_IMR);
+ outb(cached_21,0x21);
spin_unlock_irqrestore(&i8259A_lock, flags);
}
@@ -74,9 +84,9 @@ void enable_8259A_irq(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags);
cached_irq_mask &= mask;
if (irq & 8)
- outb(cached_slave_mask, PIC_SLAVE_IMR);
+ outb(cached_A1,0xA1);
else
- outb(cached_master_mask, PIC_MASTER_IMR);
+ outb(cached_21,0x21);
spin_unlock_irqrestore(&i8259A_lock, flags);
}
@@ -88,9 +98,9 @@ int i8259A_irq_pending(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags);
if (irq < 8)
- ret = inb(PIC_MASTER_CMD) & mask;
+ ret = inb(0x20) & mask;
else
- ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
+ ret = inb(0xA0) & (mask >> 8);
spin_unlock_irqrestore(&i8259A_lock, flags);
return ret;
@@ -99,7 +109,7 @@ int i8259A_irq_pending(unsigned int irq)
void make_8259A_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+ set_irq_chip(irq, &i8259A_irq_type);
enable_irq(irq);
}
@@ -115,14 +125,14 @@ static inline int i8259A_irq_real(unsigned int irq)
int irqmask = 1 << irq;
if (irq < 8) {
- outb(0x0B,PIC_MASTER_CMD); /* ISR register */
- value = inb(PIC_MASTER_CMD) & irqmask;
- outb(0x0A,PIC_MASTER_CMD); /* back to the IRR register */
+ outb(0x0B,0x20); /* ISR register */
+ value = inb(0x20) & irqmask;
+ outb(0x0A,0x20); /* back to the IRR register */
return value;
}
- outb(0x0B,PIC_SLAVE_CMD); /* ISR register */
- value = inb(PIC_SLAVE_CMD) & (irqmask >> 8);
- outb(0x0A,PIC_SLAVE_CMD); /* back to the IRR register */
+ outb(0x0B,0xA0); /* ISR register */
+ value = inb(0xA0) & (irqmask >> 8);
+ outb(0x0A,0xA0); /* back to the IRR register */
return value;
}
@@ -139,19 +149,17 @@ void mask_and_ack_8259A(unsigned int irq)
spin_lock_irqsave(&i8259A_lock, flags);
/*
- * Lightweight spurious IRQ detection. We do not want
- * to overdo spurious IRQ handling - it's usually a sign
- * of hardware problems, so we only do the checks we can
- * do without slowing down good hardware unnecessarily.
+ * Lightweight spurious IRQ detection. We do not want to overdo
+ * spurious IRQ handling - it's usually a sign of hardware problems, so
+ * we only do the checks we can do without slowing down good hardware
+ * nnecesserily.
*
- * Note that IRQ7 and IRQ15 (the two spurious IRQs
- * usually resulting from the 8259A-1|2 PICs) occur
- * even if the IRQ is masked in the 8259A. Thus we
- * can check spurious 8259A IRQs without doing the
- * quite slow i8259A_irq_real() call for every IRQ.
- * This does not cover 100% of spurious interrupts,
- * but should be enough to warn the user that there
- * is something bad going on ...
+ * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting
+ * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A.
+ * Thus we can check spurious 8259A IRQs without doing the quite slow
+ * i8259A_irq_real() call for every IRQ. This does not cover 100% of
+ * spurious interrupts, but should be enough to warn the user that
+ * there is something bad going on ...
*/
if (cached_irq_mask & irqmask)
goto spurious_8259A_irq;
@@ -159,14 +167,14 @@ void mask_and_ack_8259A(unsigned int irq)
handle_real_irq:
if (irq & 8) {
- inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */
- outb(cached_slave_mask, PIC_SLAVE_IMR);
- outb(0x60+(irq&7),PIC_SLAVE_CMD);/* 'Specific EOI' to slave */
- outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */
+ inb(0xA1); /* DUMMY - (do we need this?) */
+ outb(cached_A1,0xA1);
+ outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */
+ outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */
} else {
- inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */
- outb(cached_master_mask, PIC_MASTER_IMR);
- outb(0x60+irq,PIC_MASTER_CMD); /* 'Specific EOI to master */
+ inb(0x21); /* DUMMY - (do we need this?) */
+ outb(cached_21,0x21);
+ outb(0x60+irq,0x20); /* 'Specific EOI' to master */
}
#ifdef CONFIG_MIPS_MT_SMTC
if (irq_hwmask[irq] & ST0_IM)
@@ -187,7 +195,7 @@ void mask_and_ack_8259A(unsigned int irq)
goto handle_real_irq;
{
- static int spurious_irq_mask;
+ static int spurious_irq_mask = 0;
/*
* At this point we can be sure the IRQ is spurious,
* lets ACK and report it. [once per IRQ]
@@ -208,25 +216,13 @@ void mask_and_ack_8259A(unsigned int irq)
static int i8259A_resume(struct sys_device *dev)
{
- init_8259A(i8259A_auto_eoi);
- return 0;
-}
-
-static int i8259A_shutdown(struct sys_device *dev)
-{
- /* Put the i8259A into a quiescent state that
- * the kernel initialization code can get it
- * out of.
- */
- outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
- outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
+ init_8259A(0);
return 0;
}
static struct sysdev_class i8259_sysdev_class = {
set_kset_name("i8259"),
.resume = i8259A_resume,
- .shutdown = i8259A_shutdown,
};
static struct sys_device device_i8259A = {
@@ -248,41 +244,41 @@ void __init init_8259A(int auto_eoi)
{
unsigned long flags;
- i8259A_auto_eoi = auto_eoi;
-
spin_lock_irqsave(&i8259A_lock, flags);
- outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
- outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
+ outb(0xff, 0x21); /* mask all of 8259A-1 */
+ outb(0xff, 0xA1); /* mask all of 8259A-2 */
/*
* outb_p - this has to work on a wide range of PC hardware.
*/
- outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
- outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */
- outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */
- if (auto_eoi) /* master does Auto EOI */
- outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
- else /* master expects normal EOI */
- outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
-
- outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */
- outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */
- outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */
- outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
+ outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
+ outb_p(0x00, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */
+ outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
+ if (auto_eoi)
+ outb_p(0x03, 0x21); /* master does Auto EOI */
+ else
+ outb_p(0x01, 0x21); /* master expects normal EOI */
+
+ outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
+ outb_p(0x08, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */
+ outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */
+ outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode
+ is to be investigated) */
+
if (auto_eoi)
/*
- * In AEOI mode we just have to mask the interrupt
+ * in AEOI mode we just have to mask the interrupt
* when acking.
*/
- i8259A_chip.mask_ack = disable_8259A_irq;
+ i8259A_irq_type.ack = disable_8259A_irq;
else
- i8259A_chip.mask_ack = mask_and_ack_8259A;
+ i8259A_irq_type.ack = mask_and_ack_8259A;
udelay(100); /* wait for 8259A to initialize */
- outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
- outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */
+ outb(cached_21, 0x21); /* restore master IRQ mask */
+ outb(cached_A1, 0xA1); /* restore slave IRQ mask */
spin_unlock_irqrestore(&i8259A_lock, flags);
}
@@ -295,17 +291,11 @@ static struct irqaction irq2 = {
};
static struct resource pic1_io_resource = {
- .name = "pic1",
- .start = PIC_MASTER_CMD,
- .end = PIC_MASTER_IMR,
- .flags = IORESOURCE_BUSY
+ .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY
};
static struct resource pic2_io_resource = {
- .name = "pic2",
- .start = PIC_SLAVE_CMD,
- .end = PIC_SLAVE_IMR,
- .flags = IORESOURCE_BUSY
+ .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY
};
/*
@@ -323,7 +313,7 @@ void __init init_i8259_irqs (void)
init_8259A(0);
for (i = 0; i < 16; i++)
- set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq);
+ set_irq_chip(i, &i8259A_irq_type);
- setup_irq(PIC_CASCADE_IR, &irq2);
+ setup_irq(2, &irq2);
}
diff --git a/trunk/arch/mips/kernel/irq-mv6434x.c b/trunk/arch/mips/kernel/irq-mv6434x.c
index efbd219845b5..6cfb31cafde2 100644
--- a/trunk/arch/mips/kernel/irq-mv6434x.c
+++ b/trunk/arch/mips/kernel/irq-mv6434x.c
@@ -66,6 +66,15 @@ static inline void unmask_mv64340_irq(unsigned int irq)
}
}
+/*
+ * End IRQ processing
+ */
+static void end_mv64340_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ unmask_mv64340_irq(irq);
+}
+
/*
* Interrupt handler for interrupts coming from the Marvell chip.
* It could be built in ethernet ports etc...
@@ -97,6 +106,7 @@ struct irq_chip mv64340_irq_type = {
.mask = mask_mv64340_irq,
.mask_ack = mask_mv64340_irq,
.unmask = unmask_mv64340_irq,
+ .end = end_mv64340_irq,
};
void __init mv64340_irq_init(unsigned int base)
diff --git a/trunk/arch/mips/kernel/irq-rm7000.c b/trunk/arch/mips/kernel/irq-rm7000.c
index 123324ba8c14..ddcc2a5f8a06 100644
--- a/trunk/arch/mips/kernel/irq-rm7000.c
+++ b/trunk/arch/mips/kernel/irq-rm7000.c
@@ -29,12 +29,19 @@ static inline void mask_rm7k_irq(unsigned int irq)
clear_c0_intcontrol(0x100 << (irq - irq_base));
}
+static void rm7k_cpu_irq_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ unmask_rm7k_irq(irq);
+}
+
static struct irq_chip rm7k_irq_controller = {
.typename = "RM7000",
.ack = mask_rm7k_irq,
.mask = mask_rm7k_irq,
.mask_ack = mask_rm7k_irq,
.unmask = unmask_rm7k_irq,
+ .end = rm7k_cpu_irq_end,
};
void __init rm7k_cpu_irq_init(int base)
diff --git a/trunk/arch/mips/kernel/irq-rm9000.c b/trunk/arch/mips/kernel/irq-rm9000.c
index 0e6f4c5349d2..ba6440c88abd 100644
--- a/trunk/arch/mips/kernel/irq-rm9000.c
+++ b/trunk/arch/mips/kernel/irq-rm9000.c
@@ -80,12 +80,19 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1);
}
+static void rm9k_cpu_irq_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ unmask_rm9k_irq(irq);
+}
+
static struct irq_chip rm9k_irq_controller = {
.typename = "RM9000",
.ack = mask_rm9k_irq,
.mask = mask_rm9k_irq,
.mask_ack = mask_rm9k_irq,
.unmask = unmask_rm9k_irq,
+ .end = rm9k_cpu_irq_end,
};
static struct irq_chip rm9k_perfcounter_irq = {
@@ -96,6 +103,7 @@ static struct irq_chip rm9k_perfcounter_irq = {
.mask = mask_rm9k_irq,
.mask_ack = mask_rm9k_irq,
.unmask = unmask_rm9k_irq,
+ .end = rm9k_cpu_irq_end,
};
unsigned int rm9000_perfcount_irq;
diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c
index 2fe4c868a801..b339798b3172 100644
--- a/trunk/arch/mips/kernel/irq.c
+++ b/trunk/arch/mips/kernel/irq.c
@@ -117,7 +117,7 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
- seq_printf(p, " %14s", irq_desc[i].chip->name);
+ seq_printf(p, " %14s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c
index fcc86b96ccf6..be5ac23d3812 100644
--- a/trunk/arch/mips/kernel/irq_cpu.c
+++ b/trunk/arch/mips/kernel/irq_cpu.c
@@ -50,6 +50,12 @@ static inline void mask_mips_irq(unsigned int irq)
irq_disable_hazard();
}
+static void mips_cpu_irq_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ unmask_mips_irq(irq);
+}
+
static struct irq_chip mips_cpu_irq_controller = {
.typename = "MIPS",
.ack = mask_mips_irq,
@@ -57,6 +63,7 @@ static struct irq_chip mips_cpu_irq_controller = {
.mask_ack = mask_mips_irq,
.unmask = unmask_mips_irq,
.eoi = unmask_mips_irq,
+ .end = mips_cpu_irq_end,
};
/*
@@ -89,6 +96,8 @@ static void mips_mt_cpu_irq_ack(unsigned int irq)
mask_mips_mt_irq(irq);
}
+#define mips_mt_cpu_irq_end mips_cpu_irq_end
+
static struct irq_chip mips_mt_cpu_irq_controller = {
.typename = "MIPS",
.startup = mips_mt_cpu_irq_startup,
@@ -97,6 +106,7 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
.mask_ack = mips_mt_cpu_irq_ack,
.unmask = unmask_mips_mt_irq,
.eoi = unmask_mips_mt_irq,
+ .end = mips_mt_cpu_irq_end,
};
void __init mips_cpu_irq_init(int irq_base)
diff --git a/trunk/arch/mips/kernel/kspd.c b/trunk/arch/mips/kernel/kspd.c
index 2c82412b9efe..f06a144c7881 100644
--- a/trunk/arch/mips/kernel/kspd.c
+++ b/trunk/arch/mips/kernel/kspd.c
@@ -319,7 +319,7 @@ static void sp_cleanup(void)
static int channel_open = 0;
/* the work handler */
-static void sp_work(struct work_struct *unused)
+static void sp_work(void *data)
{
if (!channel_open) {
if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) {
@@ -354,7 +354,7 @@ static void startwork(int vpe)
return;
}
- INIT_WORK(&work, sp_work);
+ INIT_WORK(&work, sp_work, NULL);
queue_work(workqueue, &work);
} else
queue_work(workqueue, &work);
diff --git a/trunk/arch/mips/lasat/interrupt.c b/trunk/arch/mips/lasat/interrupt.c
index 2affa5ff171c..4a84a7beac53 100644
--- a/trunk/arch/mips/lasat/interrupt.c
+++ b/trunk/arch/mips/lasat/interrupt.c
@@ -44,12 +44,19 @@ void enable_lasat_irq(unsigned int irq_nr)
*lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
}
+static void end_lasat_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_lasat_irq(irq);
+}
+
static struct irq_chip lasat_irq_type = {
.typename = "Lasat",
.ack = disable_lasat_irq,
.mask = disable_lasat_irq,
.mask_ack = disable_lasat_irq,
.unmask = enable_lasat_irq,
+ .end = end_lasat_irq,
};
static inline int ls1bit32(unsigned int x)
diff --git a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c
index bb11fef08472..e5a4a0a8a7f0 100644
--- a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c
+++ b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c
@@ -65,6 +65,15 @@ static inline void unmask_cpci_irq(unsigned int irq)
value = OCELOT_FPGA_READ(INTMASK);
}
+/*
+ * End IRQ processing
+ */
+static void end_cpci_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ unmask_cpci_irq(irq);
+}
+
/*
* Interrupt handler for interrupts coming from the FPGA chip.
* It could be built in ethernet ports etc...
@@ -89,6 +98,7 @@ struct irq_chip cpci_irq_type = {
.mask = mask_cpci_irq,
.mask_ack = mask_cpci_irq,
.unmask = unmask_cpci_irq,
+ .end = end_cpci_irq,
};
void cpci_irq_init(void)
diff --git a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c
index a7a80c0da569..0029f0008dea 100644
--- a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c
+++ b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c
@@ -59,6 +59,15 @@ static inline void unmask_uart_irq(unsigned int irq)
value = OCELOT_FPGA_READ(UART_INTMASK);
}
+/*
+ * End IRQ processing
+ */
+static void end_uart_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ unmask_uart_irq(irq);
+}
+
/*
* Interrupt handler for interrupts coming from the FPGA chip.
*/
@@ -82,6 +91,7 @@ struct irq_chip uart_irq_type = {
.mask = mask_uart_irq,
.mask_ack = mask_uart_irq,
.unmask = unmask_uart_irq,
+ .end = end_uart_irq,
};
void uart_irq_init(void)
diff --git a/trunk/arch/mips/philips/pnx8550/common/int.c b/trunk/arch/mips/philips/pnx8550/common/int.c
index 2c36c108c4d6..0dc23930edbd 100644
--- a/trunk/arch/mips/philips/pnx8550/common/int.c
+++ b/trunk/arch/mips/philips/pnx8550/common/int.c
@@ -158,12 +158,20 @@ int pnx8550_set_gic_priority(int irq, int priority)
return prev_priority;
}
+static void end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ unmask_irq(irq);
+ }
+}
+
static struct irq_chip level_irq_type = {
.typename = "PNX Level IRQ",
.ack = mask_irq,
.mask = mask_irq,
.mask_ack = mask_irq,
.unmask = unmask_irq,
+ .end = end_irq,
};
static struct irqaction gic_action = {
diff --git a/trunk/arch/mips/sgi-ip22/ip22-int.c b/trunk/arch/mips/sgi-ip22/ip22-int.c
index c44f8be0644f..c7b138053159 100644
--- a/trunk/arch/mips/sgi-ip22/ip22-int.c
+++ b/trunk/arch/mips/sgi-ip22/ip22-int.c
@@ -51,12 +51,19 @@ static void disable_local0_irq(unsigned int irq)
sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
}
+static void end_local0_irq (unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_local0_irq(irq);
+}
+
static struct irq_chip ip22_local0_irq_type = {
.typename = "IP22 local 0",
.ack = disable_local0_irq,
.mask = disable_local0_irq,
.mask_ack = disable_local0_irq,
.unmask = enable_local0_irq,
+ .end = end_local0_irq,
};
static void enable_local1_irq(unsigned int irq)
@@ -72,12 +79,19 @@ void disable_local1_irq(unsigned int irq)
sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
}
+static void end_local1_irq (unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_local1_irq(irq);
+}
+
static struct irq_chip ip22_local1_irq_type = {
.typename = "IP22 local 1",
.ack = disable_local1_irq,
.mask = disable_local1_irq,
.mask_ack = disable_local1_irq,
.unmask = enable_local1_irq,
+ .end = end_local1_irq,
};
static void enable_local2_irq(unsigned int irq)
@@ -93,12 +107,19 @@ void disable_local2_irq(unsigned int irq)
sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
}
+static void end_local2_irq (unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_local2_irq(irq);
+}
+
static struct irq_chip ip22_local2_irq_type = {
.typename = "IP22 local 2",
.ack = disable_local2_irq,
.mask = disable_local2_irq,
.mask_ack = disable_local2_irq,
.unmask = enable_local2_irq,
+ .end = end_local2_irq,
};
static void enable_local3_irq(unsigned int irq)
@@ -114,12 +135,19 @@ void disable_local3_irq(unsigned int irq)
sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
}
+static void end_local3_irq (unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_local3_irq(irq);
+}
+
static struct irq_chip ip22_local3_irq_type = {
.typename = "IP22 local 3",
.ack = disable_local3_irq,
.mask = disable_local3_irq,
.mask_ack = disable_local3_irq,
.unmask = enable_local3_irq,
+ .end = end_local3_irq,
};
static void indy_local0_irqdispatch(void)
diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c
index 319f8803ef6f..5f8835b4e84a 100644
--- a/trunk/arch/mips/sgi-ip27/ip27-irq.c
+++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c
@@ -332,6 +332,13 @@ static inline void disable_bridge_irq(unsigned int irq)
intr_disconnect_level(cpu, swlevel);
}
+static void end_bridge_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
+ irq_desc[irq].action)
+ enable_bridge_irq(irq);
+}
+
static struct irq_chip bridge_irq_type = {
.typename = "bridge",
.startup = startup_bridge_irq,
@@ -340,6 +347,7 @@ static struct irq_chip bridge_irq_type = {
.mask = disable_bridge_irq,
.mask_ack = disable_bridge_irq,
.unmask = enable_bridge_irq,
+ .end = end_bridge_irq,
};
void __devinit register_bridge_irq(unsigned int irq)
diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c
index c20e9899b34b..7d361726bbfb 100644
--- a/trunk/arch/mips/sgi-ip27/ip27-timer.c
+++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c
@@ -180,6 +180,10 @@ static void disable_rt_irq(unsigned int irq)
{
}
+static void end_rt_irq(unsigned int irq)
+{
+}
+
static struct irq_chip rt_irq_type = {
.typename = "SN HUB RT timer",
.ack = disable_rt_irq,
@@ -187,6 +191,7 @@ static struct irq_chip rt_irq_type = {
.mask_ack = disable_rt_irq,
.unmask = enable_rt_irq,
.eoi = enable_rt_irq,
+ .end = end_rt_irq,
};
static struct irqaction rt_irqaction = {
diff --git a/trunk/arch/mips/tx4927/common/tx4927_irq.c b/trunk/arch/mips/tx4927/common/tx4927_irq.c
index ed4a19adf361..21873de49aa8 100644
--- a/trunk/arch/mips/tx4927/common/tx4927_irq.c
+++ b/trunk/arch/mips/tx4927/common/tx4927_irq.c
@@ -66,10 +66,12 @@
#define TX4927_IRQ_CP0_INIT ( 1 << 10 )
#define TX4927_IRQ_CP0_ENABLE ( 1 << 13 )
#define TX4927_IRQ_CP0_DISABLE ( 1 << 14 )
+#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 )
#define TX4927_IRQ_PIC_INIT ( 1 << 20 )
#define TX4927_IRQ_PIC_ENABLE ( 1 << 23 )
#define TX4927_IRQ_PIC_DISABLE ( 1 << 24 )
+#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 )
#define TX4927_IRQ_ALL 0xffffffff
#endif
@@ -80,10 +82,12 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE
| TX4927_IRQ_WARN | TX4927_IRQ_EROR
// | TX4927_IRQ_CP0_INIT
// | TX4927_IRQ_CP0_ENABLE
+// | TX4927_IRQ_CP0_DISABLE
// | TX4927_IRQ_CP0_ENDIRQ
// | TX4927_IRQ_PIC_INIT
// | TX4927_IRQ_PIC_ENABLE
// | TX4927_IRQ_PIC_DISABLE
+// | TX4927_IRQ_PIC_ENDIRQ
// | TX4927_IRQ_INIT
// | TX4927_IRQ_NEST1
// | TX4927_IRQ_NEST2
@@ -110,9 +114,11 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE
static void tx4927_irq_cp0_enable(unsigned int irq);
static void tx4927_irq_cp0_disable(unsigned int irq);
+static void tx4927_irq_cp0_end(unsigned int irq);
static void tx4927_irq_pic_enable(unsigned int irq);
static void tx4927_irq_pic_disable(unsigned int irq);
+static void tx4927_irq_pic_end(unsigned int irq);
/*
* Kernel structs for all pic's
@@ -125,6 +131,7 @@ static struct irq_chip tx4927_irq_cp0_type = {
.mask = tx4927_irq_cp0_disable,
.mask_ack = tx4927_irq_cp0_disable,
.unmask = tx4927_irq_cp0_enable,
+ .end = tx4927_irq_cp0_end,
};
#define TX4927_PIC_NAME "TX4927-PIC"
@@ -134,6 +141,7 @@ static struct irq_chip tx4927_irq_pic_type = {
.mask = tx4927_irq_pic_disable,
.mask_ack = tx4927_irq_pic_disable,
.unmask = tx4927_irq_pic_enable,
+ .end = tx4927_irq_pic_end,
};
#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL }
@@ -206,6 +214,15 @@ static void tx4927_irq_cp0_disable(unsigned int irq)
tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0);
}
+static void tx4927_irq_cp0_end(unsigned int irq)
+{
+ TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq);
+
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4927_irq_cp0_enable(irq);
+ }
+}
+
/*
* Functions for pic
*/
@@ -359,6 +376,15 @@ static void tx4927_irq_pic_disable(unsigned int irq)
tx4927_irq_pic_mask(irq), 0);
}
+static void tx4927_irq_pic_end(unsigned int irq)
+{
+ TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq);
+
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4927_irq_pic_enable(irq);
+ }
+}
+
/*
* Main init functions
*/
diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
index 5a5ea6c0b9f6..34cdb2a240e9 100644
--- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
+++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
@@ -153,6 +153,7 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB
#define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 )
#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 )
#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 )
+#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 )
#define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 )
#define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 )
@@ -171,6 +172,7 @@ static const u32 toshiba_rbtx4927_irq_debug_flag =
// | TOSHIBA_RBTX4927_IRQ_IOC_INIT
// | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE
// | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE
+// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ
// | TOSHIBA_RBTX4927_IRQ_ISA_INIT
// | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE
// | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE
@@ -221,6 +223,7 @@ extern void mask_and_ack_8259A(unsigned int irq);
static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq);
#ifdef CONFIG_TOSHIBA_FPCIB0
static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq);
@@ -236,6 +239,7 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
.mask = toshiba_rbtx4927_irq_ioc_disable,
.mask_ack = toshiba_rbtx4927_irq_ioc_disable,
.unmask = toshiba_rbtx4927_irq_ioc_enable,
+ .end = toshiba_rbtx4927_irq_ioc_end,
};
#define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000
#define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006
@@ -384,6 +388,23 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v);
}
+static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq)
+{
+ TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ,
+ "irq=%d\n", irq);
+
+ if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG
+ || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) {
+ TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR,
+ "bad irq=%d\n", irq);
+ panic("\n");
+ }
+
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ toshiba_rbtx4927_irq_ioc_enable(irq);
+ }
+}
+
/**********************************************************************************/
/* Functions for isa */
diff --git a/trunk/arch/mips/tx4938/common/irq.c b/trunk/arch/mips/tx4938/common/irq.c
index a347b424d91c..42e127683ae9 100644
--- a/trunk/arch/mips/tx4938/common/irq.c
+++ b/trunk/arch/mips/tx4938/common/irq.c
@@ -39,9 +39,11 @@
static void tx4938_irq_cp0_enable(unsigned int irq);
static void tx4938_irq_cp0_disable(unsigned int irq);
+static void tx4938_irq_cp0_end(unsigned int irq);
static void tx4938_irq_pic_enable(unsigned int irq);
static void tx4938_irq_pic_disable(unsigned int irq);
+static void tx4938_irq_pic_end(unsigned int irq);
/**********************************************************************************/
/* Kernel structs for all pic's */
@@ -54,6 +56,7 @@ static struct irq_chip tx4938_irq_cp0_type = {
.mask = tx4938_irq_cp0_disable,
.mask_ack = tx4938_irq_cp0_disable,
.unmask = tx4938_irq_cp0_enable,
+ .end = tx4938_irq_cp0_end,
};
#define TX4938_PIC_NAME "TX4938-PIC"
@@ -63,6 +66,7 @@ static struct irq_chip tx4938_irq_pic_type = {
.mask = tx4938_irq_pic_disable,
.mask_ack = tx4938_irq_pic_disable,
.unmask = tx4938_irq_pic_enable,
+ .end = tx4938_irq_pic_end,
};
static struct irqaction tx4938_irq_pic_action = {
@@ -100,6 +104,14 @@ tx4938_irq_cp0_disable(unsigned int irq)
clear_c0_status(tx4938_irq_cp0_mask(irq));
}
+static void
+tx4938_irq_cp0_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4938_irq_cp0_enable(irq);
+ }
+}
+
/**********************************************************************************/
/* Functions for pic */
/**********************************************************************************/
@@ -257,6 +269,14 @@ tx4938_irq_pic_disable(unsigned int irq)
tx4938_irq_pic_mask(irq), 0);
}
+static void
+tx4938_irq_pic_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ tx4938_irq_pic_enable(irq);
+ }
+}
+
/**********************************************************************************/
/* Main init functions */
/**********************************************************************************/
diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c
index b6f363d08011..8c87a35f3068 100644
--- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c
@@ -89,6 +89,7 @@ IRQ Device
static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq);
#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
@@ -97,6 +98,7 @@ static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
.mask = toshiba_rbtx4938_irq_ioc_disable,
.mask_ack = toshiba_rbtx4938_irq_ioc_disable,
.unmask = toshiba_rbtx4938_irq_ioc_enable,
+ .end = toshiba_rbtx4938_irq_ioc_end,
};
#define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
@@ -165,6 +167,14 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
}
+static void
+toshiba_rbtx4938_irq_ioc_end(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ toshiba_rbtx4938_irq_ioc_enable(irq);
+ }
+}
+
extern void __init txx9_spi_irqinit(int irc_irq);
void __init arch_init_irq(void)
diff --git a/trunk/arch/mips/vr41xx/Kconfig b/trunk/arch/mips/vr41xx/Kconfig
index c8dfd8092cab..92f41f6f934a 100644
--- a/trunk/arch/mips/vr41xx/Kconfig
+++ b/trunk/arch/mips/vr41xx/Kconfig
@@ -6,7 +6,6 @@ config CASIO_E55
select ISA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config IBM_WORKPAD
bool "Support for IBM WorkPad z50"
@@ -16,7 +15,6 @@ config IBM_WORKPAD
select ISA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config NEC_CMBVR4133
bool "Support for NEC CMB-VR4133"
@@ -41,7 +39,6 @@ config TANBAC_TB022X
select IRQ_CPU
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
help
The TANBAC VR4131 multichip module(TB0225) and
the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
@@ -74,7 +71,6 @@ config VICTOR_MPC30X
select IRQ_CPU
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config ZAO_CAPCELLA
bool "Support for ZAO Networks Capcella"
@@ -84,7 +80,6 @@ config ZAO_CAPCELLA
select IRQ_CPU
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config PCI_VR41XX
bool "Add PCI control unit support of NEC VR4100 series"
diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c
index c075261976c5..54b92a74c7ac 100644
--- a/trunk/arch/mips/vr41xx/common/icu.c
+++ b/trunk/arch/mips/vr41xx/common/icu.c
@@ -427,12 +427,19 @@ static void enable_sysint1_irq(unsigned int irq)
icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
}
+static void end_sysint1_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq));
+}
+
static struct irq_chip sysint1_irq_type = {
.typename = "SYSINT1",
.ack = disable_sysint1_irq,
.mask = disable_sysint1_irq,
.mask_ack = disable_sysint1_irq,
.unmask = enable_sysint1_irq,
+ .end = end_sysint1_irq,
};
static void disable_sysint2_irq(unsigned int irq)
@@ -445,12 +452,19 @@ static void enable_sysint2_irq(unsigned int irq)
icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
}
+static void end_sysint2_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq));
+}
+
static struct irq_chip sysint2_irq_type = {
.typename = "SYSINT2",
.ack = disable_sysint2_irq,
.mask = disable_sysint2_irq,
.mask_ack = disable_sysint2_irq,
.unmask = enable_sysint2_irq,
+ .end = end_sysint2_irq,
};
static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
diff --git a/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c b/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c
index 0e837762cc5b..31bcdae84823 100644
--- a/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c
+++ b/trunk/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -14,7 +14,7 @@ static unsigned long avr_clock;
static struct work_struct wd_work;
-static void wd_stop(struct work_struct *unused)
+static void wd_stop(void *unused)
{
const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
int i = 0, rescue = 8;
@@ -122,7 +122,7 @@ static int __init ls_uarts_init(void)
ls_uart_init();
- INIT_WORK(&wd_work, wd_stop);
+ INIT_WORK(&wd_work, wd_stop, NULL);
schedule_work(&wd_work);
return 0;
diff --git a/trunk/arch/powerpc/platforms/powermac/backlight.c b/trunk/arch/powerpc/platforms/powermac/backlight.c
index c3a89414ddc0..afa593a8544a 100644
--- a/trunk/arch/powerpc/platforms/powermac/backlight.c
+++ b/trunk/arch/powerpc/platforms/powermac/backlight.c
@@ -18,11 +18,11 @@
#define OLD_BACKLIGHT_MAX 15
-static void pmac_backlight_key_worker(struct work_struct *work);
-static void pmac_backlight_set_legacy_worker(struct work_struct *work);
+static void pmac_backlight_key_worker(void *data);
+static void pmac_backlight_set_legacy_worker(void *data);
-static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker);
-static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker);
+static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL);
+static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL);
/* Although these variables are used in interrupt context, it makes no sense to
* protect them. No user is able to produce enough key events per second and
@@ -94,7 +94,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value)
return level;
}
-static void pmac_backlight_key_worker(struct work_struct *work)
+static void pmac_backlight_key_worker(void *data)
{
if (atomic_read(&kernel_backlight_disabled))
return;
@@ -166,7 +166,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness)
return error;
}
-static void pmac_backlight_set_legacy_worker(struct work_struct *work)
+static void pmac_backlight_set_legacy_worker(void *data)
{
if (atomic_read(&kernel_backlight_disabled))
return;
diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_event.c b/trunk/arch/powerpc/platforms/pseries/eeh_event.c
index 49037edf7d39..137077451316 100644
--- a/trunk/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/trunk/arch/powerpc/platforms/pseries/eeh_event.c
@@ -37,8 +37,8 @@
/* EEH event workqueue setup. */
static DEFINE_SPINLOCK(eeh_eventlist_lock);
LIST_HEAD(eeh_eventlist);
-static void eeh_thread_launcher(struct work_struct *);
-DECLARE_WORK(eeh_event_wq, eeh_thread_launcher);
+static void eeh_thread_launcher(void *);
+DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
/* Serialize reset sequences for a given pci device */
DEFINE_MUTEX(eeh_event_mutex);
@@ -103,7 +103,7 @@ static int eeh_event_handler(void * dummy)
* eeh_thread_launcher
* @dummy - unused
*/
-static void eeh_thread_launcher(struct work_struct *dummy)
+static void eeh_thread_launcher(void *dummy)
{
if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0)
printk(KERN_ERR "Failed to start EEH daemon\n");
diff --git a/trunk/arch/ppc/8260_io/fcc_enet.c b/trunk/arch/ppc/8260_io/fcc_enet.c
index 709952c25f29..2e1943e27819 100644
--- a/trunk/arch/ppc/8260_io/fcc_enet.c
+++ b/trunk/arch/ppc/8260_io/fcc_enet.c
@@ -385,7 +385,6 @@ struct fcc_enet_private {
phy_info_t *phy;
struct work_struct phy_relink;
struct work_struct phy_display_config;
- struct net_device *dev;
uint sequence_done;
@@ -1392,11 +1391,10 @@ static phy_info_t *phy_info[] = {
NULL
};
-static void mii_display_status(struct work_struct *work)
+static void mii_display_status(void *data)
{
- volatile struct fcc_enet_private *fep =
- container_of(work, struct fcc_enet_private, phy_relink);
- struct net_device *dev = fep->dev;
+ struct net_device *dev = data;
+ volatile struct fcc_enet_private *fep = dev->priv;
uint s = fep->phy_status;
if (!fep->link && !fep->old_link) {
@@ -1430,12 +1428,10 @@ static void mii_display_status(struct work_struct *work)
printk(".\n");
}
-static void mii_display_config(struct work_struct *work)
+static void mii_display_config(void *data)
{
- volatile struct fcc_enet_private *fep =
- container_of(work, struct fcc_enet_private,
- phy_display_config);
- struct net_device *dev = fep->dev;
+ struct net_device *dev = data;
+ volatile struct fcc_enet_private *fep = dev->priv;
uint s = fep->phy_status;
printk("%s: config: auto-negotiation ", dev->name);
@@ -1762,9 +1758,8 @@ static int __init fec_enet_init(void)
cep->phy_id_done = 0;
cep->phy_addr = fip->fc_phyaddr;
mii_queue(dev, mk_mii_read(MII_PHYSID1), mii_discover_phy);
- INIT_WORK(&cep->phy_relink, mii_display_status);
- INIT_WORK(&cep->phy_display_config, mii_display_config);
- cep->dev = dev;
+ INIT_WORK(&cep->phy_relink, mii_display_status, dev);
+ INIT_WORK(&cep->phy_display_config, mii_display_config, dev);
#endif /* CONFIG_USE_MDIO */
fip++;
diff --git a/trunk/arch/ppc/8xx_io/fec.c b/trunk/arch/ppc/8xx_io/fec.c
index e6c28fb423b2..2f9fa9e3d331 100644
--- a/trunk/arch/ppc/8xx_io/fec.c
+++ b/trunk/arch/ppc/8xx_io/fec.c
@@ -173,7 +173,6 @@ struct fec_enet_private {
uint phy_speed;
phy_info_t *phy;
struct work_struct phy_task;
- struct net_device *dev;
uint sequence_done;
@@ -1264,11 +1263,10 @@ static void mii_display_status(struct net_device *dev)
printk(".\n");
}
-static void mii_display_config(struct work_struct *work)
+static void mii_display_config(void *priv)
{
- struct fec_enet_private *fep =
- container_of(work, struct fec_enet_private, phy_task);
- struct net_device *dev = fep->dev;
+ struct net_device *dev = (struct net_device *)priv;
+ struct fec_enet_private *fep = dev->priv;
volatile uint *s = &(fep->phy_status);
printk("%s: config: auto-negotiation ", dev->name);
@@ -1297,11 +1295,10 @@ static void mii_display_config(struct work_struct *work)
fep->sequence_done = 1;
}
-static void mii_relink(struct work_struct *work)
+static void mii_relink(void *priv)
{
- struct fec_enet_private *fep =
- container_of(work, struct fec_enet_private, phy_task);
- struct net_device *dev = fep->dev;
+ struct net_device *dev = (struct net_device *)priv;
+ struct fec_enet_private *fep = dev->priv;
int duplex;
fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0;
@@ -1328,8 +1325,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = dev->priv;
- fep->dev = dev;
- INIT_WORK(&fep->phy_task, mii_relink);
+ INIT_WORK(&fep->phy_task, mii_relink, (void *)dev);
schedule_work(&fep->phy_task);
}
@@ -1337,8 +1333,7 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev)
{
struct fec_enet_private *fep = dev->priv;
- fep->dev = dev;
- INIT_WORK(&fep->phy_task, mii_display_config);
+ INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev);
schedule_work(&fep->phy_task);
}
diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c
index 67d5cf9cba83..af1e8fc7d985 100644
--- a/trunk/arch/s390/appldata/appldata_base.c
+++ b/trunk/arch/s390/appldata/appldata_base.c
@@ -92,8 +92,8 @@ static int appldata_timer_active;
* Work queue
*/
static struct workqueue_struct *appldata_wq;
-static void appldata_work_fn(struct work_struct *work);
-static DECLARE_WORK(appldata_work, appldata_work_fn);
+static void appldata_work_fn(void *data);
+static DECLARE_WORK(appldata_work, appldata_work_fn, NULL);
/*
@@ -125,7 +125,7 @@ static void appldata_timer_function(unsigned long data)
*
* call data gathering function for each (active) module
*/
-static void appldata_work_fn(struct work_struct *work)
+static void appldata_work_fn(void *data)
{
struct list_head *lh;
struct appldata_ops *ops;
diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig
index d83d64af31f2..bffc7e176970 100644
--- a/trunk/arch/sh/Kconfig
+++ b/trunk/arch/sh/Kconfig
@@ -51,14 +51,6 @@ config GENERIC_TIME
config ARCH_MAY_HAVE_PC_FDC
bool
-config STACKTRACE_SUPPORT
- bool
- default y
-
-config LOCKDEP_SUPPORT
- bool
- default y
-
source "init/Kconfig"
menu "System type"
@@ -227,20 +219,6 @@ config SH_SHMIN
help
Select SHMIN if configuring for the SHMIN board.
-config SH_7206_SOLUTION_ENGINE
- bool "SolutionEngine7206"
- select CPU_SUBTYPE_SH7206
- help
- Select 7206 SolutionEngine if configuring for a Hitachi SH7206
- evaluation board.
-
-config SH_7619_SOLUTION_ENGINE
- bool "SolutionEngine7619"
- select CPU_SUBTYPE_SH7619
- help
- Select 7619 SolutionEngine if configuring for a Hitachi SH7619
- evaluation board.
-
config SH_UNKNOWN
bool "BareCPU"
help
@@ -302,20 +280,12 @@ config CF_BASE_ADDR
menu "Processor features"
-choice
- prompt "Endianess selection"
- default CPU_LITTLE_ENDIAN
- help
- Some SuperH machines can be configured for either little or big
- endian byte order. These modes require different kernels.
-
config CPU_LITTLE_ENDIAN
bool "Little Endian"
-
-config CPU_BIG_ENDIAN
- bool "Big Endian"
-
-endchoice
+ help
+ Some SuperH machines can be configured for either little or big
+ endian byte order. These modes require different kernels. Say Y if
+ your machine is little endian, N if it's a big endian machine.
config SH_FPU
bool "FPU support"
@@ -375,9 +345,6 @@ config CPU_HAS_MASKREG_IRQ
config CPU_HAS_INTC2_IRQ
bool
-config CPU_HAS_IPR_IRQ
- bool
-
config CPU_HAS_SR_RB
bool "CPU has SR.RB"
depends on CPU_SH3 || CPU_SH4
@@ -390,9 +357,6 @@ config CPU_HAS_SR_RB
See for further
information on SR.RB and register banking in the kernel in general.
-config CPU_HAS_PTEA
- bool
-
endmenu
menu "Timer support"
@@ -400,25 +364,10 @@ depends on !GENERIC_TIME
config SH_TMU
bool "TMU timer support"
- depends on CPU_SH3 || CPU_SH4
default y
help
This enables the use of the TMU as the system timer.
-config SH_CMT
- bool "CMT timer support"
- depends on CPU_SH2
- default y
- help
- This enables the use of the CMT as the system timer.
-
-config SH_MTU2
- bool "MTU2 timer support"
- depends on CPU_SH2A
- default n
- help
- This enables the use of the MTU2 as the system timer.
-
endmenu
source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
@@ -427,52 +376,19 @@ source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
source "arch/sh/boards/renesas/r7780rp/Kconfig"
-config SH_TIMER_IRQ
- int
- default "28" if CPU_SUBTYPE_SH7780
- default "86" if CPU_SUBTYPE_SH7619
- default "140" if CPU_SUBTYPE_SH7206
- default "16"
-
-config NO_IDLE_HZ
- bool "Dynamic tick timer"
- help
- Select this option if you want to disable continuous timer ticks
- and have them programmed to occur as required. This option saves
- power as the system can remain in idle state for longer.
-
- By default dynamic tick is disabled during the boot, and can be
- manually enabled with:
-
- echo 1 > /sys/devices/system/timer/timer0/dyn_tick
-
- Alternatively, if you want dynamic tick automatically enabled
- during boot, pass "dyntick=enable" via the kernel command string.
-
- Please note that dynamic tick may affect the accuracy of
- timekeeping on some platforms depending on the implementation.
-
config SH_PCLK_FREQ
int "Peripheral clock frequency (in Hz)"
- default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
- default "31250000" if CPU_SUBTYPE_SH7619
- default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
- CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
- CPU_SUBTYPE_SH7206
default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
default "60000000" if CPU_SUBTYPE_SH7751
+ default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
+ CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705
+ default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
default "66000000" if CPU_SUBTYPE_SH4_202
help
This option is used to specify the peripheral clock frequency.
This is necessary for determining the reference clock value on
platforms lacking an RTC.
-config SH_CLK_MD
- int "CPU Mode Pin Setting"
- depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206
- help
- MD2 - MD0 Setting.
-
menu "CPU Frequency scaling"
source "drivers/cpufreq/Kconfig"
@@ -505,8 +421,6 @@ config HEARTBEAT
behavior is platform-dependent, but normally the flash frequency is
a hyperbolic function of the 5-minute load average.
-source "arch/sh/drivers/Kconfig"
-
endmenu
config ISA_DMA_API
diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug
index 66a25ef4ef1b..48479e014dac 100644
--- a/trunk/arch/sh/Kconfig.debug
+++ b/trunk/arch/sh/Kconfig.debug
@@ -1,9 +1,5 @@
menu "Kernel hacking"
-config TRACE_IRQFLAGS_SUPPORT
- bool
- default y
-
source "lib/Kconfig.debug"
config SH_STANDARD_BIOS
@@ -21,18 +17,7 @@ config SH_STANDARD_BIOS
config EARLY_SCIF_CONSOLE
bool "Use early SCIF console"
- help
- This enables an early console using a fixed SCIF port. This can
- be used by platforms that are either not running the SH
- standard BIOS, or do not wish to use the BIOS callbacks for the
- serial I/O.
-
-config EARLY_SCIF_CONSOLE_PORT
- hex "SCIF port for early console"
- depends on EARLY_SCIF_CONSOLE
- default "0xffe00000" if CPU_SUBTYPE_SH7780
- default "0xfffe9800" if CPU_SUBTYPE_SH72060
- default "0xffe80000" if CPU_SH4
+ depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS
config EARLY_PRINTK
bool "Early printk support"
@@ -45,11 +30,6 @@ config EARLY_PRINTK
when the kernel may crash or hang before the serial console is
initialised. If unsure, say N.
- On devices that are running SH-IPL and want to keep the port
- initialization consistent while not using the BIOS callbacks,
- select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
- the kernel command line option to toggle back and forth.
-
config DEBUG_STACKOVERFLOW
bool "Check for stack overflows"
depends on DEBUG_KERNEL
diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile
index d10bba5e1074..26d62ff51a64 100644
--- a/trunk/arch/sh/Makefile
+++ b/trunk/arch/sh/Makefile
@@ -13,6 +13,10 @@
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
+
+cflags-y := -mb
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml
+
isa-y := any
isa-$(CONFIG_SH_DSP) := sh
isa-$(CONFIG_CPU_SH2) := sh2
@@ -34,16 +38,13 @@ isa-y := $(isa-y)-nofpu
endif
endif
-cflags-$(CONFIG_CPU_SH2) := -m2
-cflags-$(CONFIG_CPU_SH3) := -m3
-cflags-$(CONFIG_CPU_SH4) := -m4 \
- $(call cc-option,-mno-implicit-fp,-m4-nofpu)
-cflags-$(CONFIG_CPU_SH4A) := -m4a $(call cc-option,-m4a-nofpu,)
-
-cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb
-cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
+cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
-cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
+cflags-$(CONFIG_CPU_SH2) += -m2
+cflags-$(CONFIG_CPU_SH3) += -m3
+cflags-$(CONFIG_CPU_SH4) += -m4 \
+ $(call cc-option,-mno-implicit-fp,-m4-nofpu)
+cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a-nofpu,)
cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
cflags-$(CONFIG_SH_KGDB) += -g
@@ -58,9 +59,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S
# never be used by anyone. Use a board-specific defconfig that has a
# reasonable chance of being current instead.
#
-KBUILD_DEFCONFIG := r7780rp_defconfig
-
-KBUILD_IMAGE := arch/sh/boot/zImage
+KBUILD_DEFCONFIG := rts7751r2d_defconfig
#
# Choosing incompatible machines durings configuration will result in
@@ -110,8 +109,6 @@ machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
machdir-$(CONFIG_SH_LANDISK) := landisk
machdir-$(CONFIG_SH_TITAN) := titan
machdir-$(CONFIG_SH_SHMIN) := shmin
-machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206
-machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619
machdir-$(CONFIG_SH_UNKNOWN) := unknown
incdir-y := $(notdir $(machdir-y))
@@ -127,7 +124,6 @@ core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/
core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/
cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2
-cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a
cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3
cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4
diff --git a/trunk/arch/sh/boards/renesas/r7780rp/Makefile b/trunk/arch/sh/boards/renesas/r7780rp/Makefile
index 574b0316ed56..f1776d027978 100644
--- a/trunk/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/trunk/arch/sh/boards/renesas/r7780rp/Makefile
@@ -3,6 +3,4 @@
#
obj-y := setup.o io.o irq.o
-
-obj-$(CONFIG_HEARTBEAT) += led.o
-obj-$(CONFIG_PUSH_SWITCH) += psw.o
+obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq.c b/trunk/arch/sh/boards/renesas/r7780rp/irq.c
index cc381e197783..aa15ec5bc69e 100644
--- a/trunk/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/trunk/arch/sh/boards/renesas/r7780rp/irq.c
@@ -10,7 +10,6 @@
*/
#include
#include
-#include
#include
#include
diff --git a/trunk/arch/sh/boards/renesas/r7780rp/psw.c b/trunk/arch/sh/boards/renesas/r7780rp/psw.c
deleted file mode 100644
index c844dfa5d58d..000000000000
--- a/trunk/arch/sh/boards/renesas/r7780rp/psw.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * arch/sh/boards/renesas/r7780rp/psw.c
- *
- * push switch support for RDBRP-1/RDBREVRP-1 debug boards.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-
-static irqreturn_t psw_irq_handler(int irq, void *arg)
-{
- struct platform_device *pdev = arg;
- struct push_switch *psw = platform_get_drvdata(pdev);
- struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
- unsigned int l, mask;
- int ret = 0;
-
- l = ctrl_inw(PA_DBSW);
-
- /* Nothing to do if there's no state change */
- if (psw->state) {
- ret = 1;
- goto out;
- }
-
- mask = l & 0x70;
- /* Figure out who raised it */
- if (mask & (1 << psw_info->bit)) {
- psw->state = !!(mask & (1 << psw_info->bit));
- if (psw->state) /* debounce */
- mod_timer(&psw->debounce, jiffies + 50);
-
- ret = 1;
- }
-
-out:
- /* Clear the switch IRQs */
- l |= (0x7 << 12);
- ctrl_outw(l, PA_DBSW);
-
- return IRQ_RETVAL(ret);
-}
-
-static struct resource psw_resources[] = {
- [0] = {
- .start = IRQ_PSW,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct push_switch_platform_info s2_platform_data = {
- .name = "s2",
- .bit = 6,
- .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
- IRQF_SHARED,
- .irq_handler = psw_irq_handler,
-};
-
-static struct platform_device s2_switch_device = {
- .name = "push-switch",
- .id = 0,
- .num_resources = ARRAY_SIZE(psw_resources),
- .resource = psw_resources,
- .dev = {
- .platform_data = &s2_platform_data,
- },
-};
-
-static struct push_switch_platform_info s3_platform_data = {
- .name = "s3",
- .bit = 5,
- .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
- IRQF_SHARED,
- .irq_handler = psw_irq_handler,
-};
-
-static struct platform_device s3_switch_device = {
- .name = "push-switch",
- .id = 1,
- .num_resources = ARRAY_SIZE(psw_resources),
- .resource = psw_resources,
- .dev = {
- .platform_data = &s3_platform_data,
- },
-};
-
-static struct push_switch_platform_info s4_platform_data = {
- .name = "s4",
- .bit = 4,
- .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
- IRQF_SHARED,
- .irq_handler = psw_irq_handler,
-};
-
-static struct platform_device s4_switch_device = {
- .name = "push-switch",
- .id = 2,
- .num_resources = ARRAY_SIZE(psw_resources),
- .resource = psw_resources,
- .dev = {
- .platform_data = &s4_platform_data,
- },
-};
-
-static struct platform_device *psw_devices[] = {
- &s2_switch_device, &s3_switch_device, &s4_switch_device,
-};
-
-static int __init psw_init(void)
-{
- return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
-}
-module_init(psw_init);
diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c
index 9f89c8de9db9..c331caeb694b 100644
--- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c
@@ -44,37 +44,8 @@ static struct platform_device m66596_usb_host_device = {
.resource = m66596_usb_host_resources,
};
-static struct resource cf_ide_resources[] = {
- [0] = {
- .start = 0x1f0,
- .end = 0x1f0 + 8,
- .flags = IORESOURCE_IO,
- },
- [1] = {
- .start = 0x1f0 + 0x206,
- .end = 0x1f0 + 8 + 0x206 + 8,
- .flags = IORESOURCE_IO,
- },
- [2] = {
-#ifdef CONFIG_SH_R7780MP
- .start = 1,
-#else
- .start = 4,
-#endif
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device cf_ide_device = {
- .name = "pata_platform",
- .id = -1,
- .num_resources = ARRAY_SIZE(cf_ide_resources),
- .resource = cf_ide_resources,
-};
-
static struct platform_device *r7780rp_devices[] __initdata = {
&m66596_usb_host_device,
- &cf_ide_device,
};
static int __init r7780rp_devices_setup(void)
diff --git a/trunk/arch/sh/boards/se/7206/Makefile b/trunk/arch/sh/boards/se/7206/Makefile
deleted file mode 100644
index 63950f4f2453..000000000000
--- a/trunk/arch/sh/boards/se/7206/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the 7206 SolutionEngine specific parts of the kernel
-#
-
-obj-y := setup.o io.o irq.o
-obj-$(CONFIG_HEARTBEAT) += led.o
-
diff --git a/trunk/arch/sh/boards/se/7206/io.c b/trunk/arch/sh/boards/se/7206/io.c
deleted file mode 100644
index b557273e0cbe..000000000000
--- a/trunk/arch/sh/boards/se/7206/io.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
- *
- * linux/arch/sh/boards/se/7206/io.c
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * I/O routine for Hitachi 7206 SolutionEngine.
- *
- */
-
-#include
-#include
-#include
-#include
-
-
-static inline void delay(void)
-{
- ctrl_inw(0x20000000); /* P2 ROM Area */
-}
-
-/* MS7750 requires special versions of in*, out* routines, since
- PC-like io ports are located at upper half byte of 16-bit word which
- can be accessed only with 16-bit wide. */
-
-static inline volatile __u16 *
-port2adr(unsigned int port)
-{
- if (port >= 0x2000)
- return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
- else if (port >= 0x300 || port < 0x310)
- return (volatile __u16 *) (PA_SMSC + (port - 0x300));
-}
-
-unsigned char se7206_inb(unsigned long port)
-{
- return (*port2adr(port))&0xff;
-}
-
-unsigned char se7206_inb_p(unsigned long port)
-{
- unsigned long v;
-
- v = (*port2adr(port))&0xff;
- delay();
- return v;
-}
-
-unsigned short se7206_inw(unsigned long port)
-{
- return *port2adr(port);;
-}
-
-unsigned int se7206_inl(unsigned long port)
-{
- maybebadio(port);
- return 0;
-}
-
-void se7206_outb(unsigned char value, unsigned long port)
-{
- *(port2adr(port)) = value;
-}
-
-void se7206_outb_p(unsigned char value, unsigned long port)
-{
- *(port2adr(port)) = value;
- delay();
-}
-
-void se7206_outw(unsigned short value, unsigned long port)
-{
- *port2adr(port) = value;
-}
-
-void se7206_outl(unsigned int value, unsigned long port)
-{
- maybebadio(port);
-}
-
-void se7206_insb(unsigned long port, void *addr, unsigned long count)
-{
- volatile __u16 *p = port2adr(port);
- __u8 *ap = addr;
-
- while (count--)
- *ap++ = *p;
-}
-
-void se7206_insw(unsigned long port, void *addr, unsigned long count)
-{
- volatile __u16 *p = port2adr(port);
- __u16 *ap = addr;
- while (count--)
- *ap++ = *p;
-}
-
-void se7206_insl(unsigned long port, void *addr, unsigned long count)
-{
- maybebadio(port);
-}
-
-void se7206_outsb(unsigned long port, const void *addr, unsigned long count)
-{
- volatile __u16 *p = port2adr(port);
- const __u8 *ap = addr;
-
- while (count--)
- *p = *ap++;
-}
-
-void se7206_outsw(unsigned long port, const void *addr, unsigned long count)
-{
- volatile __u16 *p = port2adr(port);
- const __u16 *ap = addr;
- while (count--)
- *p = *ap++;
-}
-
-void se7206_outsl(unsigned long port, const void *addr, unsigned long count)
-{
- maybebadio(port);
-}
diff --git a/trunk/arch/sh/boards/se/7206/irq.c b/trunk/arch/sh/boards/se/7206/irq.c
deleted file mode 100644
index 3fb0c5f5b23a..000000000000
--- a/trunk/arch/sh/boards/se/7206/irq.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * linux/arch/sh/boards/se/7206/irq.c
- *
- * Copyright (C) 2005,2006 Yoshinori Sato
- *
- * Hitachi SolutionEngine Support.
- *
- */
-#include
-#include
-#include
-#include
-#include
-
-#define INTSTS0 0x31800000
-#define INTSTS1 0x31800002
-#define INTMSK0 0x31800004
-#define INTMSK1 0x31800006
-#define INTSEL 0x31800008
-
-static void disable_se7206_irq(unsigned int irq)
-{
- unsigned short val;
- unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq)));
- unsigned short msk0,msk1;
-
- /* Set the priority in IPR to 0 */
- val = ctrl_inw(INTC_IPR01);
- val &= mask;
- ctrl_outw(val, INTC_IPR01);
- /* FPGA mask set */
- msk0 = ctrl_inw(INTMSK0);
- msk1 = ctrl_inw(INTMSK1);
-
- switch (irq) {
- case IRQ0_IRQ:
- msk0 |= 0x0010;
- break;
- case IRQ1_IRQ:
- msk0 |= 0x000f;
- break;
- case IRQ2_IRQ:
- msk0 |= 0x0f00;
- msk1 |= 0x00ff;
- break;
- }
- ctrl_outw(msk0, INTMSK0);
- ctrl_outw(msk1, INTMSK1);
-}
-
-static void enable_se7206_irq(unsigned int irq)
-{
- unsigned short val;
- unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq)));
- unsigned short msk0,msk1;
-
- /* Set priority in IPR back to original value */
- val = ctrl_inw(INTC_IPR01);
- val |= value;
- ctrl_outw(val, INTC_IPR01);
-
- /* FPGA mask reset */
- msk0 = ctrl_inw(INTMSK0);
- msk1 = ctrl_inw(INTMSK1);
-
- switch (irq) {
- case IRQ0_IRQ:
- msk0 &= ~0x0010;
- break;
- case IRQ1_IRQ:
- msk0 &= ~0x000f;
- break;
- case IRQ2_IRQ:
- msk0 &= ~0x0f00;
- msk1 &= ~0x00ff;
- break;
- }
- ctrl_outw(msk0, INTMSK0);
- ctrl_outw(msk1, INTMSK1);
-}
-
-static void eoi_se7206_irq(unsigned int irq)
-{
- unsigned short sts0,sts1;
-
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_se7206_irq(irq);
- /* FPGA isr clear */
- sts0 = ctrl_inw(INTSTS0);
- sts1 = ctrl_inw(INTSTS1);
-
- switch (irq) {
- case IRQ0_IRQ:
- sts0 &= ~0x0010;
- break;
- case IRQ1_IRQ:
- sts0 &= ~0x000f;
- break;
- case IRQ2_IRQ:
- sts0 &= ~0x0f00;
- sts1 &= ~0x00ff;
- break;
- }
- ctrl_outw(sts0, INTSTS0);
- ctrl_outw(sts1, INTSTS1);
-}
-
-static struct irq_chip se7206_irq_chip __read_mostly = {
- .name = "SE7206-FPGA-IRQ",
- .mask = disable_se7206_irq,
- .unmask = enable_se7206_irq,
- .mask_ack = disable_se7206_irq,
- .eoi = eoi_se7206_irq,
-};
-
-static void make_se7206_irq(unsigned int irq)
-{
- disable_irq_nosync(irq);
- set_irq_chip_and_handler_name(irq, &se7206_irq_chip,
- handle_level_irq, "level");
- disable_se7206_irq(irq);
-}
-
-/*
- * Initialize IRQ setting
- */
-void __init init_se7206_IRQ(void)
-{
- make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */
- make_se7206_irq(IRQ1_IRQ); /* ATA */
- make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
- ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */
-
- /* FPGA System register setup*/
- ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */
- ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */
- /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */
- ctrl_outw(0x0001,INTSEL);
-}
diff --git a/trunk/arch/sh/boards/se/7206/led.c b/trunk/arch/sh/boards/se/7206/led.c
deleted file mode 100644
index ef794601ab86..000000000000
--- a/trunk/arch/sh/boards/se/7206/led.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * linux/arch/sh/kernel/led_se.c
- *
- * Copyright (C) 2000 Stuart Menefy
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * This file contains Solution Engine specific LED code.
- */
-
-#include
-#include
-
-#ifdef CONFIG_HEARTBEAT
-
-#include
-
-/* Cycle the LED's in the clasic Knightrider/Sun pattern */
-void heartbeat_se(void)
-{
- static unsigned int cnt = 0, period = 0;
- volatile unsigned short* p = (volatile unsigned short*)PA_LED;
- static unsigned bit = 0, up = 1;
-
- cnt += 1;
- if (cnt < period) {
- return;
- }
-
- cnt = 0;
-
- /* Go through the points (roughly!):
- * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
- */
- period = 110 - ( (300<
-#include
-#include
-#include
-#include
-
-static struct resource smc91x_resources[] = {
- [0] = {
- .start = 0x300,
- .end = 0x300 + 0x020 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = 64,
- .end = 64,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device smc91x_device = {
- .name = "smc91x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smc91x_resources),
- .resource = smc91x_resources,
-};
-
-static int __init se7206_devices_setup(void)
-{
- return platform_device_register(&smc91x_device);
-}
-
-__initcall(se7206_devices_setup);
-
-void heartbeat_se(void);
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_se __initmv = {
- .mv_name = "SolutionEngine",
- .mv_nr_irqs = 256,
- .mv_inb = se7206_inb,
- .mv_inw = se7206_inw,
- .mv_inl = se7206_inl,
- .mv_outb = se7206_outb,
- .mv_outw = se7206_outw,
- .mv_outl = se7206_outl,
-
- .mv_inb_p = se7206_inb_p,
- .mv_inw_p = se7206_inw,
- .mv_inl_p = se7206_inl,
- .mv_outb_p = se7206_outb_p,
- .mv_outw_p = se7206_outw,
- .mv_outl_p = se7206_outl,
-
- .mv_insb = se7206_insb,
- .mv_insw = se7206_insw,
- .mv_insl = se7206_insl,
- .mv_outsb = se7206_outsb,
- .mv_outsw = se7206_outsw,
- .mv_outsl = se7206_outsl,
-
- .mv_init_irq = init_se7206_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_se,
-#endif
-};
-ALIAS_MV(se)
diff --git a/trunk/arch/sh/boards/se/7619/Makefile b/trunk/arch/sh/boards/se/7619/Makefile
deleted file mode 100644
index 3666eca8a658..000000000000
--- a/trunk/arch/sh/boards/se/7619/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the 7619 SolutionEngine specific parts of the kernel
-#
-
-obj-y := setup.o io.o
diff --git a/trunk/arch/sh/boards/se/7619/io.c b/trunk/arch/sh/boards/se/7619/io.c
deleted file mode 100644
index 176f1f39cd9d..000000000000
--- a/trunk/arch/sh/boards/se/7619/io.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- *
- * linux/arch/sh/boards/se/7619/io.c
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * I/O routine for Hitachi 7619 SolutionEngine.
- *
- */
-
-#include
-#include
-#include
-#include
-#include
-
-/* FIXME: M3A-ZAB7 Compact Flash Slot support */
-
-static inline void delay(void)
-{
- ctrl_inw(0xa0000000); /* Uncached ROM area (P2) */
-}
-
-#define badio(name,port) \
- printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \
- #name, (port), (__u32) __builtin_return_address(0))
-
-unsigned char se7619___inb(unsigned long port)
-{
- badio(inb, port);
- return 0;
-}
-
-unsigned char se7619___inb_p(unsigned long port)
-{
- badio(inb_p, port);
- delay();
- return 0;
-}
-
-unsigned short se7619___inw(unsigned long port)
-{
- badio(inw, port);
- return 0;
-}
-
-unsigned int se7619___inl(unsigned long port)
-{
- badio(inl, port);
- return 0;
-}
-
-void se7619___outb(unsigned char value, unsigned long port)
-{
- badio(outb, port);
-}
-
-void se7619___outb_p(unsigned char value, unsigned long port)
-{
- badio(outb_p, port);
- delay();
-}
-
-void se7619___outw(unsigned short value, unsigned long port)
-{
- badio(outw, port);
-}
-
-void se7619___outl(unsigned int value, unsigned long port)
-{
- badio(outl, port);
-}
-
-void se7619___insb(unsigned long port, void *addr, unsigned long count)
-{
- badio(inw, port);
-}
-
-void se7619___insw(unsigned long port, void *addr, unsigned long count)
-{
- badio(inw, port);
-}
-
-void se7619___insl(unsigned long port, void *addr, unsigned long count)
-{
- badio(insl, port);
-}
-
-void se7619___outsb(unsigned long port, const void *addr, unsigned long count)
-{
- badio(insl, port);
-}
-
-void se7619___outsw(unsigned long port, const void *addr, unsigned long count)
-{
- badio(insl, port);
-}
-
-void se7619___outsl(unsigned long port, const void *addr, unsigned long count)
-{
- badio(outsw, port);
-}
diff --git a/trunk/arch/sh/boards/se/7619/setup.c b/trunk/arch/sh/boards/se/7619/setup.c
deleted file mode 100644
index e627b26de0d0..000000000000
--- a/trunk/arch/sh/boards/se/7619/setup.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * arch/sh/boards/se/7619/setup.c
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * Hitachi SH7619 SolutionEngine Support.
- */
-
-#include
-#include
-#include
-#include
-#include
-
-/*
- * The Machine Vector
- */
-
-struct sh_machine_vector mv_se __initmv = {
- .mv_name = "SolutionEngine",
- .mv_nr_irqs = 108,
- .mv_inb = se7619___inb,
- .mv_inw = se7619___inw,
- .mv_inl = se7619___inl,
- .mv_outb = se7619___outb,
- .mv_outw = se7619___outw,
- .mv_outl = se7619___outl,
-
- .mv_inb_p = se7619___inb_p,
- .mv_inw_p = se7619___inw,
- .mv_inl_p = se7619___inl,
- .mv_outb_p = se7619___outb_p,
- .mv_outw_p = se7619___outw,
- .mv_outl_p = se7619___outl,
-
- .mv_insb = se7619___insb,
- .mv_insw = se7619___insw,
- .mv_insl = se7619___insl,
- .mv_outsb = se7619___outsb,
- .mv_outsw = se7619___outsw,
- .mv_outsl = se7619___outsl,
-};
-ALIAS_MV(se)
diff --git a/trunk/arch/sh/boards/titan/setup.c b/trunk/arch/sh/boards/titan/setup.c
index 6bcd939bfaed..a6046d93758b 100644
--- a/trunk/arch/sh/boards/titan/setup.c
+++ b/trunk/arch/sh/boards/titan/setup.c
@@ -1,30 +1,26 @@
/*
- * arch/sh/boards/titan/setup.c - Setup for Titan
- *
- * 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.
+ * Setup for Titan
*/
+
#include
-#include
+#include
#include
#include
+extern void __init pcibios_init_platform(void);
+
static struct ipr_data titan_ipr_map[] = {
- /* IRQ, IPR idx, shift, prio */
- { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */
- { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */
- { TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */
- { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */
+ { TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY },
+ { TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY },
+ { TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY },
+ { TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY },
};
static void __init init_titan_irq(void)
{
/* enable individual interrupt mode for externals */
- ipr_irq_enable_irlm();
- /* register ipr irqs */
+ ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+
make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map));
}
@@ -51,5 +47,6 @@ struct sh_machine_vector mv_titan __initmv = {
.mv_ioport_map = titan_ioport_map,
.mv_init_irq = init_titan_irq,
+ .mv_init_pci = pcibios_init_platform,
};
ALIAS_MV(titan)
diff --git a/trunk/arch/sh/boot/compressed/misc.c b/trunk/arch/sh/boot/compressed/misc.c
index 35452d85b7f7..f2fed5ce5cc3 100644
--- a/trunk/arch/sh/boot/compressed/misc.c
+++ b/trunk/arch/sh/boot/compressed/misc.c
@@ -12,7 +12,6 @@
*/
#include
-#include
#ifdef CONFIG_SH_STANDARD_BIOS
#include
#endif
@@ -229,7 +228,7 @@ long* stack_start = &user_stack[STACK_SIZE];
void decompress_kernel(void)
{
output_data = 0;
- output_ptr = P2SEGADDR((unsigned long)&_text+0x1000);
+ output_ptr = (unsigned long)&_text+0x20001000;
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
diff --git a/trunk/arch/sh/configs/r7780rp_defconfig b/trunk/arch/sh/configs/r7780rp_defconfig
index 2b75b4896ba5..34e2046c3213 100644
--- a/trunk/arch/sh/configs/r7780rp_defconfig
+++ b/trunk/arch/sh/configs/r7780rp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Wed Dec 6 11:59:38 2006
+# Linux kernel version: 2.6.19-rc3
+# Tue Oct 31 12:32:06 2006
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -11,8 +11,6 @@ CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME is not set
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -39,7 +37,6 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -121,8 +118,6 @@ CONFIG_SH_R7780RP=y
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
# CONFIG_SH_SHMIN is not set
-# CONFIG_SH_7206_SOLUTION_ENGINE is not set
-# CONFIG_SH_7619_SOLUTION_ENGINE is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -135,12 +130,6 @@ CONFIG_CPU_SH4A=y
# SH-2 Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7619 is not set
-
-#
-# SH-2A Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7206 is not set
#
# SH-3 Processor Support
@@ -176,7 +165,6 @@ CONFIG_CPU_SH4A=y
#
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
-# CONFIG_CPU_SUBTYPE_SH7785 is not set
#
# SH4AL-DSP Processor Support
@@ -193,14 +181,8 @@ CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
# CONFIG_32BIT is not set
CONFIG_VSYSCALL=y
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_HUGETLB_PAGE_SIZE_64K=y
-# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
-# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
-# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -222,14 +204,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_SH_FPU=y
# CONFIG_SH_DSP is not set
CONFIG_SH_STORE_QUEUES=y
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_INTC2_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
-CONFIG_CPU_HAS_PTEA=y
#
# Timer support
@@ -240,8 +220,6 @@ CONFIG_SH_TMU=y
# R7780RP options
#
CONFIG_SH_R7780MP=y
-CONFIG_SH_TIMER_IRQ=28
-CONFIG_NO_IDLE_HZ=y
CONFIG_SH_PCLK_FREQ=32000000
#
@@ -259,11 +237,6 @@ CONFIG_SH_PCLK_FREQ=32000000
#
# CONFIG_HD6446X_SERIES is not set
-#
-# Additional SuperH Device Drivers
-#
-CONFIG_PUSH_SWITCH=y
-
#
# Kernel features
#
@@ -271,7 +244,7 @@ CONFIG_PUSH_SWITCH=y
CONFIG_HZ_250=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
-CONFIG_KEXEC=y
+# CONFIG_KEXEC is not set
# CONFIG_SMP is not set
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
@@ -305,7 +278,10 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
#
# PCI Hotplug Support
#
-# CONFIG_HOTPLUG_PCI is not set
+CONFIG_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_FAKE is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
#
# Executable file formats
@@ -365,7 +341,6 @@ CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
@@ -581,7 +556,6 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
@@ -598,7 +572,6 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
-CONFIG_PATA_PLATFORM=y
#
# Multi-device support (RAID and LVM)
@@ -715,7 +688,6 @@ CONFIG_R8169=y
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -858,6 +830,10 @@ CONFIG_HW_RANDOM=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
@@ -1044,7 +1020,7 @@ CONFIG_INOTIFY_USER=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -1076,7 +1052,7 @@ CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -1177,33 +1153,28 @@ CONFIG_NLS_ISO8859_1=y
#
# Profiling support
#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
+# CONFIG_PROFILING is not set
#
# Kernel hacking
#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
+# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_SPINLOCK=y
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_RWSEMS is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
@@ -1213,7 +1184,7 @@ CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_SH_STANDARD_BIOS is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
-CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_4KSTACKS is not set
# CONFIG_KGDB is not set
diff --git a/trunk/arch/sh/configs/se7206_defconfig b/trunk/arch/sh/configs/se7206_defconfig
deleted file mode 100644
index 36cec0b6e7c1..000000000000
--- a/trunk/arch/sh/configs/se7206_defconfig
+++ /dev/null
@@ -1,826 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-rc4
-# Sun Nov 5 16:20:10 2006
-#
-CONFIG_SUPERH=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-# CONFIG_GENERIC_TIME is not set
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SYSVIPC is not set
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_UID16=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_TINY_SHMEM=y
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-
-#
-# System type
-#
-# CONFIG_SH_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SOLUTION_ENGINE is not set
-# CONFIG_SH_7300_SOLUTION_ENGINE is not set
-# CONFIG_SH_7343_SOLUTION_ENGINE is not set
-# CONFIG_SH_73180_SOLUTION_ENGINE is not set
-# CONFIG_SH_7751_SYSTEMH is not set
-# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
-# CONFIG_SH_SATURN is not set
-# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
-# CONFIG_SH_MPC1211 is not set
-# CONFIG_SH_SH03 is not set
-# CONFIG_SH_SECUREEDGE5410 is not set
-# CONFIG_SH_HS7751RVOIP is not set
-# CONFIG_SH_7710VOIPGW is not set
-# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
-# CONFIG_SH_EDOSK7705 is not set
-# CONFIG_SH_SH4202_MICRODEV is not set
-# CONFIG_SH_LANDISK is not set
-# CONFIG_SH_TITAN is not set
-# CONFIG_SH_SHMIN is not set
-CONFIG_SH_7206_SOLUTION_ENGINE=y
-# CONFIG_SH_7619_SOLUTION_ENGINE is not set
-# CONFIG_SH_UNKNOWN is not set
-
-#
-# Processor selection
-#
-CONFIG_CPU_SH2=y
-CONFIG_CPU_SH2A=y
-
-#
-# SH-2 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7604 is not set
-# CONFIG_CPU_SUBTYPE_SH7619 is not set
-
-#
-# SH-2A Processor Support
-#
-CONFIG_CPU_SUBTYPE_SH7206=y
-
-#
-# SH-3 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7300 is not set
-# CONFIG_CPU_SUBTYPE_SH7705 is not set
-# CONFIG_CPU_SUBTYPE_SH7706 is not set
-# CONFIG_CPU_SUBTYPE_SH7707 is not set
-# CONFIG_CPU_SUBTYPE_SH7708 is not set
-# CONFIG_CPU_SUBTYPE_SH7709 is not set
-# CONFIG_CPU_SUBTYPE_SH7710 is not set
-
-#
-# SH-4 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7750 is not set
-# CONFIG_CPU_SUBTYPE_SH7091 is not set
-# CONFIG_CPU_SUBTYPE_SH7750R is not set
-# CONFIG_CPU_SUBTYPE_SH7750S is not set
-# CONFIG_CPU_SUBTYPE_SH7751 is not set
-# CONFIG_CPU_SUBTYPE_SH7751R is not set
-# CONFIG_CPU_SUBTYPE_SH7760 is not set
-# CONFIG_CPU_SUBTYPE_SH4_202 is not set
-
-#
-# ST40 Processor Support
-#
-# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
-# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
-
-#
-# SH-4A Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH7770 is not set
-# CONFIG_CPU_SUBTYPE_SH7780 is not set
-
-#
-# SH4AL-DSP Processor Support
-#
-# CONFIG_CPU_SUBTYPE_SH73180 is not set
-# CONFIG_CPU_SUBTYPE_SH7343 is not set
-
-#
-# Memory management options
-#
-CONFIG_PAGE_OFFSET=0x00000000
-CONFIG_MEMORY_START=0x0c000000
-CONFIG_MEMORY_SIZE=0x02000000
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-
-#
-# Cache configuration
-#
-# CONFIG_SH_DIRECT_MAPPED is not set
-# CONFIG_SH_WRITETHROUGH is not set
-# CONFIG_SH_OCRAM is not set
-
-#
-# Processor features
-#
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_SH_FPU is not set
-# CONFIG_SH_FPU_EMU is not set
-# CONFIG_SH_DSP is not set
-
-#
-# Timer support
-#
-CONFIG_SH_CMT=y
-# CONFIG_SH_MTU2 is not set
-CONFIG_SH_PCLK_FREQ=33333333
-CONFIG_SH_CLK_MD=6
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# DMA support
-#
-# CONFIG_SH_DMA is not set
-
-#
-# Companion Chips
-#
-# CONFIG_HD6446X_SERIES is not set
-
-#
-# Kernel features
-#
-CONFIG_HZ_100=y
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=100
-# CONFIG_KEXEC is not set
-# CONFIG_SMP is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-
-#
-# Boot options
-#
-CONFIG_ZERO_PAGE_OFFSET=0x00001000
-CONFIG_BOOT_LINK_OFFSET=0x00800000
-# CONFIG_UBC_WAKEUP is not set
-# CONFIG_CMDLINE_BOOL is not set
-
-#
-# Bus options
-#
-# CONFIG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_FLAT=y
-CONFIG_BINFMT_ZFLAT=y
-# CONFIG_BINFMT_SHARED_FLAT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options (EXPERIMENTAL)
-#
-# CONFIG_PM is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
-# CONFIG_UNIX is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_DIAG is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0x1000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_UCLINUX is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
-# CONFIG_MTD_ONENAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
-# CONFIG_NETDEVICES is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-# CONFIG_INPUT is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=4
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_UNIX98_PTYS is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
-# CONFIG_INOTIFY is not set
-# CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-# CONFIG_SYSFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_UNWIND_INFO is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_EARLY_SCIF_CONSOLE is not set
-# CONFIG_KGDB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
diff --git a/trunk/arch/sh/drivers/Kconfig b/trunk/arch/sh/drivers/Kconfig
deleted file mode 100644
index c54c758e6243..000000000000
--- a/trunk/arch/sh/drivers/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-menu "Additional SuperH Device Drivers"
-
-config PUSH_SWITCH
- tristate "Push switch support"
- help
- This enables support for the push switch framework, a simple
- framework that allows for sysfs driven switch status reporting.
-
-endmenu
diff --git a/trunk/arch/sh/drivers/Makefile b/trunk/arch/sh/drivers/Makefile
index bf18dbfb6787..338c3729d270 100644
--- a/trunk/arch/sh/drivers/Makefile
+++ b/trunk/arch/sh/drivers/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_SH_DMA) += dma/
obj-$(CONFIG_SUPERHYWAY) += superhyway/
-obj-$(CONFIG_PUSH_SWITCH) += push-switch.o
+
diff --git a/trunk/arch/sh/drivers/dma/Makefile b/trunk/arch/sh/drivers/dma/Makefile
index db1295d32268..065d4c90970e 100644
--- a/trunk/arch/sh/drivers/dma/Makefile
+++ b/trunk/arch/sh/drivers/dma/Makefile
@@ -2,8 +2,8 @@
# Makefile for the SuperH DMA specific kernel interface routines under Linux.
#
-obj-y += dma-api.o
-obj-$(CONFIG_ISA_DMA_API) += dma-isa.o
+obj-y += dma-api.o dma-isa.o
obj-$(CONFIG_SYSFS) += dma-sysfs.o
obj-$(CONFIG_SH_DMA) += dma-sh.o
obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o
+
diff --git a/trunk/arch/sh/drivers/dma/dma-api.c b/trunk/arch/sh/drivers/dma/dma-api.c
index e062067edd24..47c3e837599b 100644
--- a/trunk/arch/sh/drivers/dma/dma-api.c
+++ b/trunk/arch/sh/drivers/dma/dma-api.c
@@ -11,27 +11,61 @@
*/
#include
#include
+#include
#include
#include
#include
#include
-#include
#include
DEFINE_SPINLOCK(dma_spin_lock);
static LIST_HEAD(registered_dmac_list);
+/*
+ * A brief note about the reasons for this API as it stands.
+ *
+ * For starters, the old ISA DMA API didn't work for us for a number of
+ * reasons, for one, the vast majority of channels on the SH DMAC are
+ * dual-address mode only, and both the new and the old DMA APIs are after the
+ * concept of managing a DMA buffer, which doesn't overly fit this model very
+ * well. In addition to which, the new API is largely geared at IOMMUs and
+ * GARTs, and doesn't even support the channel notion very well.
+ *
+ * The other thing that's a marginal issue, is the sheer number of random DMA
+ * engines that are present (ie, in boards like the Dreamcast), some of which
+ * cascade off of the SH DMAC, and others do not. As such, there was a real
+ * need for a scalable subsystem that could deal with both single and
+ * dual-address mode usage, in addition to interoperating with cascaded DMACs.
+ *
+ * There really isn't any reason why this needs to be SH specific, though I'm
+ * not aware of too many other processors (with the exception of some MIPS)
+ * that have the same concept of a dual address mode, or any real desire to
+ * actually make use of the DMAC even if such a subsystem were exposed
+ * elsewhere.
+ *
+ * The idea for this was derived from the ARM port, which acted as an excellent
+ * reference when trying to address these issues.
+ *
+ * It should also be noted that the decision to add Yet Another DMA API(tm) to
+ * the kernel wasn't made easily, and was only decided upon after conferring
+ * with jejb with regards to the state of the old and new APIs as they applied
+ * to these circumstances. Philip Blundell was also a great help in figuring
+ * out some single-address mode DMA semantics that were otherwise rather
+ * confusing.
+ */
+
struct dma_info *get_dma_info(unsigned int chan)
{
struct dma_info *info;
+ unsigned int total = 0;
/*
* Look for each DMAC's range to determine who the owner of
* the channel is.
*/
list_for_each_entry(info, ®istered_dmac_list, list) {
- if ((chan < info->first_channel_nr) ||
- (chan >= info->first_channel_nr + info->nr_channels))
+ total += info->nr_channels;
+ if (chan > total)
continue;
return info;
@@ -39,22 +73,6 @@ struct dma_info *get_dma_info(unsigned int chan)
return NULL;
}
-EXPORT_SYMBOL(get_dma_info);
-
-struct dma_info *get_dma_info_by_name(const char *dmac_name)
-{
- struct dma_info *info;
-
- list_for_each_entry(info, ®istered_dmac_list, list) {
- if (dmac_name && (strcmp(dmac_name, info->name) != 0))
- continue;
- else
- return info;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(get_dma_info_by_name);
static unsigned int get_nr_channels(void)
{
@@ -73,161 +91,63 @@ static unsigned int get_nr_channels(void)
struct dma_channel *get_dma_channel(unsigned int chan)
{
struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel;
- int i;
- if (unlikely(!info))
+ if (!info)
return ERR_PTR(-EINVAL);
- for (i = 0; i < info->nr_channels; i++) {
- channel = &info->channels[i];
- if (channel->chan == chan)
- return channel;
- }
-
- return NULL;
+ return info->channels + chan;
}
-EXPORT_SYMBOL(get_dma_channel);
int get_dma_residue(unsigned int chan)
{
struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
+ struct dma_channel *channel = &info->channels[chan];
if (info->ops->get_residue)
return info->ops->get_residue(channel);
return 0;
}
-EXPORT_SYMBOL(get_dma_residue);
-
-static int search_cap(const char **haystack, const char *needle)
-{
- const char **p;
-
- for (p = haystack; *p; p++)
- if (strcmp(*p, needle) == 0)
- return 1;
-
- return 0;
-}
-
-/**
- * request_dma_bycap - Allocate a DMA channel based on its capabilities
- * @dmac: List of DMA controllers to search
- * @caps: List of capabilites
- *
- * Search all channels of all DMA controllers to find a channel which
- * matches the requested capabilities. The result is the channel
- * number if a match is found, or %-ENODEV if no match is found.
- *
- * Note that not all DMA controllers export capabilities, in which
- * case they can never be allocated using this API, and so
- * request_dma() must be used specifying the channel number.
- */
-int request_dma_bycap(const char **dmac, const char **caps, const char *dev_id)
-{
- unsigned int found = 0;
- struct dma_info *info;
- const char **p;
- int i;
-
- BUG_ON(!dmac || !caps);
-
- list_for_each_entry(info, ®istered_dmac_list, list)
- if (strcmp(*dmac, info->name) == 0) {
- found = 1;
- break;
- }
- if (!found)
- return -ENODEV;
-
- for (i = 0; i < info->nr_channels; i++) {
- struct dma_channel *channel = &info->channels[i];
-
- if (unlikely(!channel->caps))
- continue;
-
- for (p = caps; *p; p++) {
- if (!search_cap(channel->caps, *p))
- break;
- if (request_dma(channel->chan, dev_id) == 0)
- return channel->chan;
- }
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL(request_dma_bycap);
-
-int dmac_search_free_channel(const char *dev_id)
+int request_dma(unsigned int chan, const char *dev_id)
{
- struct dma_channel *channel = { 0 };
- struct dma_info *info = get_dma_info(0);
- int i;
-
- for (i = 0; i < info->nr_channels; i++) {
- channel = &info->channels[i];
- if (unlikely(!channel))
- return -ENODEV;
-
- if (atomic_read(&channel->busy) == 0)
- break;
- }
+ struct dma_info *info = get_dma_info(chan);
+ struct dma_channel *channel = &info->channels[chan];
- if (info->ops->request) {
- int result = info->ops->request(channel);
- if (result)
- return result;
+ down(&channel->sem);
- atomic_set(&channel->busy, 1);
- return channel->chan;
+ if (!info->ops || chan >= MAX_DMA_CHANNELS) {
+ up(&channel->sem);
+ return -EINVAL;
}
- return -ENOSYS;
-}
-
-int request_dma(unsigned int chan, const char *dev_id)
-{
- struct dma_channel *channel = { 0 };
- struct dma_info *info = get_dma_info(chan);
- int result;
-
- channel = get_dma_channel(chan);
- if (atomic_xchg(&channel->busy, 1))
- return -EBUSY;
+ atomic_set(&channel->busy, 1);
strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
- if (info->ops->request) {
- result = info->ops->request(channel);
- if (result)
- atomic_set(&channel->busy, 0);
+ up(&channel->sem);
- return result;
- }
+ if (info->ops->request)
+ return info->ops->request(channel);
return 0;
}
-EXPORT_SYMBOL(request_dma);
void free_dma(unsigned int chan)
{
struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
+ struct dma_channel *channel = &info->channels[chan];
if (info->ops->free)
info->ops->free(channel);
atomic_set(&channel->busy, 0);
}
-EXPORT_SYMBOL(free_dma);
void dma_wait_for_completion(unsigned int chan)
{
struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
+ struct dma_channel *channel = &info->channels[chan];
if (channel->flags & DMA_TEI_CAPABLE) {
wait_event(channel->wait_queue,
@@ -238,52 +158,21 @@ void dma_wait_for_completion(unsigned int chan)
while (info->ops->get_residue(channel))
cpu_relax();
}
-EXPORT_SYMBOL(dma_wait_for_completion);
-
-int register_chan_caps(const char *dmac, struct dma_chan_caps *caps)
-{
- struct dma_info *info;
- unsigned int found = 0;
- int i;
-
- list_for_each_entry(info, ®istered_dmac_list, list)
- if (strcmp(dmac, info->name) == 0) {
- found = 1;
- break;
- }
-
- if (unlikely(!found))
- return -ENODEV;
-
- for (i = 0; i < info->nr_channels; i++, caps++) {
- struct dma_channel *channel;
-
- if ((info->first_channel_nr + i) != caps->ch_num)
- return -EINVAL;
-
- channel = &info->channels[i];
- channel->caps = caps->caplist;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(register_chan_caps);
void dma_configure_channel(unsigned int chan, unsigned long flags)
{
struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
+ struct dma_channel *channel = &info->channels[chan];
if (info->ops->configure)
info->ops->configure(channel, flags);
}
-EXPORT_SYMBOL(dma_configure_channel);
int dma_xfer(unsigned int chan, unsigned long from,
unsigned long to, size_t size, unsigned int mode)
{
struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
+ struct dma_channel *channel = &info->channels[chan];
channel->sar = from;
channel->dar = to;
@@ -292,20 +181,8 @@ int dma_xfer(unsigned int chan, unsigned long from,
return info->ops->xfer(channel);
}
-EXPORT_SYMBOL(dma_xfer);
-
-int dma_extend(unsigned int chan, unsigned long op, void *param)
-{
- struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
-
- if (info->ops->extend)
- return info->ops->extend(channel, op, param);
-
- return -ENOSYS;
-}
-EXPORT_SYMBOL(dma_extend);
+#ifdef CONFIG_PROC_FS
static int dma_read_proc(char *buf, char **start, off_t off,
int len, int *eof, void *data)
{
@@ -337,6 +214,8 @@ static int dma_read_proc(char *buf, char **start, off_t off,
return p - buf;
}
+#endif
+
int register_dmac(struct dma_info *info)
{
@@ -345,7 +224,8 @@ int register_dmac(struct dma_info *info)
INIT_LIST_HEAD(&info->list);
printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n",
- info->name, info->nr_channels, info->nr_channels > 1 ? "s" : "");
+ info->name, info->nr_channels,
+ info->nr_channels > 1 ? "s" : "");
BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels);
@@ -362,26 +242,28 @@ int register_dmac(struct dma_info *info)
size = sizeof(struct dma_channel) * info->nr_channels;
- info->channels = kzalloc(size, GFP_KERNEL);
+ info->channels = kmalloc(size, GFP_KERNEL);
if (!info->channels)
return -ENOMEM;
+
+ memset(info->channels, 0, size);
}
total_channels = get_nr_channels();
for (i = 0; i < info->nr_channels; i++) {
- struct dma_channel *chan = &info->channels[i];
-
- atomic_set(&chan->busy, 0);
+ struct dma_channel *chan = info->channels + i;
- chan->chan = info->first_channel_nr + i;
- chan->vchan = info->first_channel_nr + i + total_channels;
+ chan->chan = i;
+ chan->vchan = i + total_channels;
memcpy(chan->dev_id, "Unused", 7);
if (info->flags & DMAC_CHANNELS_TEI_CAPABLE)
chan->flags |= DMA_TEI_CAPABLE;
+ init_MUTEX(&chan->sem);
init_waitqueue_head(&chan->wait_queue);
+
dma_create_sysfs_files(chan, info);
}
@@ -389,7 +271,6 @@ int register_dmac(struct dma_info *info)
return 0;
}
-EXPORT_SYMBOL(register_dmac);
void unregister_dmac(struct dma_info *info)
{
@@ -404,16 +285,31 @@ void unregister_dmac(struct dma_info *info)
list_del(&info->list);
platform_device_unregister(info->pdev);
}
-EXPORT_SYMBOL(unregister_dmac);
static int __init dma_api_init(void)
{
- printk(KERN_NOTICE "DMA: Registering DMA API.\n");
+ printk("DMA: Registering DMA API.\n");
+
+#ifdef CONFIG_PROC_FS
create_proc_read_entry("dma", 0, 0, dma_read_proc, 0);
+#endif
+
return 0;
}
+
subsys_initcall(dma_api_init);
MODULE_AUTHOR("Paul Mundt ");
MODULE_DESCRIPTION("DMA API for SuperH");
MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
+EXPORT_SYMBOL(register_dmac);
+EXPORT_SYMBOL(get_dma_residue);
+EXPORT_SYMBOL(get_dma_info);
+EXPORT_SYMBOL(get_dma_channel);
+EXPORT_SYMBOL(dma_xfer);
+EXPORT_SYMBOL(dma_wait_for_completion);
+EXPORT_SYMBOL(dma_configure_channel);
+
diff --git a/trunk/arch/sh/drivers/dma/dma-sh.c b/trunk/arch/sh/drivers/dma/dma-sh.c
index f63721ed86c2..660786013350 100644
--- a/trunk/arch/sh/drivers/dma/dma-sh.c
+++ b/trunk/arch/sh/drivers/dma/dma-sh.c
@@ -94,13 +94,20 @@ static int sh_dmac_request_dma(struct dma_channel *chan)
if (unlikely(!chan->flags & DMA_TEI_CAPABLE))
return 0;
+ chan->name = kzalloc(32, GFP_KERNEL);
+ if (unlikely(chan->name == NULL))
+ return -ENOMEM;
+ snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)",
+ chan->chan);
+
return request_irq(get_dmte_irq(chan->chan), dma_tei,
- IRQF_DISABLED, chan->dev_id, chan);
+ IRQF_DISABLED, chan->name, chan);
}
static void sh_dmac_free_dma(struct dma_channel *chan)
{
free_irq(get_dmte_irq(chan->chan), chan);
+ kfree(chan->name);
}
static void
diff --git a/trunk/arch/sh/drivers/dma/dma-sysfs.c b/trunk/arch/sh/drivers/dma/dma-sysfs.c
index eebcd4768bbf..29b8ef9873d1 100644
--- a/trunk/arch/sh/drivers/dma/dma-sysfs.c
+++ b/trunk/arch/sh/drivers/dma/dma-sysfs.c
@@ -3,7 +3,7 @@
*
* sysfs interface for SH DMA API
*
- * Copyright (C) 2004 - 2006 Paul Mundt
+ * Copyright (C) 2004, 2005 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
@@ -21,6 +21,7 @@
static struct sysdev_class dma_sysclass = {
set_kset_name("dma"),
};
+
EXPORT_SYMBOL(dma_sysclass);
static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
@@ -30,10 +31,7 @@ static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
for (i = 0; i < MAX_DMA_CHANNELS; i++) {
struct dma_info *info = get_dma_info(i);
- struct dma_channel *channel = get_dma_channel(i);
-
- if (unlikely(!info) || !channel)
- continue;
+ struct dma_channel *channel = &info->channels[i];
len += sprintf(buf + len, "%2d: %14s %s\n",
channel->chan, info->name,
@@ -127,16 +125,11 @@ int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info)
if (ret)
return ret;
- ret |= sysdev_create_file(dev, &attr_dev_id);
- ret |= sysdev_create_file(dev, &attr_count);
- ret |= sysdev_create_file(dev, &attr_mode);
- ret |= sysdev_create_file(dev, &attr_flags);
- ret |= sysdev_create_file(dev, &attr_config);
-
- if (unlikely(ret)) {
- dev_err(&info->pdev->dev, "Failed creating attrs\n");
- return ret;
- }
+ sysdev_create_file(dev, &attr_dev_id);
+ sysdev_create_file(dev, &attr_count);
+ sysdev_create_file(dev, &attr_mode);
+ sysdev_create_file(dev, &attr_flags);
+ sysdev_create_file(dev, &attr_config);
snprintf(name, sizeof(name), "dma%d", chan->chan);
return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name);
diff --git a/trunk/arch/sh/drivers/pci/ops-titan.c b/trunk/arch/sh/drivers/pci/ops-titan.c
index ac8ee2312cd8..cd56d53375e7 100644
--- a/trunk/arch/sh/drivers/pci/ops-titan.c
+++ b/trunk/arch/sh/drivers/pci/ops-titan.c
@@ -15,21 +15,25 @@
#include
#include
#include
-#include
+#include
#include
#include "pci-sh4.h"
-static char titan_irq_tab[] __initdata = {
- TITAN_IRQ_WAN,
- TITAN_IRQ_LAN,
- TITAN_IRQ_MPCIA,
- TITAN_IRQ_MPCIB,
- TITAN_IRQ_USB,
-};
-
int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
- int irq = titan_irq_tab[slot];
+ int irq = -1;
+
+ switch (slot) {
+ case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */
+ case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */
+ case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */
+ case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */
+ case 4: irq = TITAN_IRQ_USB; break; /* USB */
+ default:
+ printk(KERN_INFO "PCI: Bad IRQ mapping "
+ "request for slot %d\n", slot);
+ return -1;
+ }
printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n",
slot, pin - 1 + 'A', irq);
diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.c b/trunk/arch/sh/drivers/pci/pci-sh7780.c
index 602b644c35ad..d6e635296534 100644
--- a/trunk/arch/sh/drivers/pci/pci-sh7780.c
+++ b/trunk/arch/sh/drivers/pci/pci-sh7780.c
@@ -22,20 +22,6 @@
#include
#include "pci-sh4.h"
-#define INTC_BASE 0xffd00000
-#define INTC_ICR0 (INTC_BASE+0x0)
-#define INTC_ICR1 (INTC_BASE+0x1c)
-#define INTC_INTPRI (INTC_BASE+0x10)
-#define INTC_INTREQ (INTC_BASE+0x24)
-#define INTC_INTMSK0 (INTC_BASE+0x44)
-#define INTC_INTMSK1 (INTC_BASE+0x48)
-#define INTC_INTMSK2 (INTC_BASE+0x40080)
-#define INTC_INTMSKCLR0 (INTC_BASE+0x64)
-#define INTC_INTMSKCLR1 (INTC_BASE+0x68)
-#define INTC_INTMSKCLR2 (INTC_BASE+0x40084)
-#define INTC_INT2MSKR (INTC_BASE+0x40038)
-#define INTC_INT2MSKCR (INTC_BASE+0x4003c)
-
/*
* Initialization. Try all known PCI access methods. Note that we support
* using both PCI BIOS and direct access: in such cases, we use I/O ports
diff --git a/trunk/arch/sh/drivers/push-switch.c b/trunk/arch/sh/drivers/push-switch.c
deleted file mode 100644
index f2b9157c314f..000000000000
--- a/trunk/arch/sh/drivers/push-switch.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Generic push-switch framework
- *
- * 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
-#include
-#include
-#include
-#include
-
-#define DRV_NAME "push-switch"
-#define DRV_VERSION "0.1.0"
-
-static ssize_t switch_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct push_switch_platform_info *psw_info = dev->platform_data;
- return sprintf(buf, "%s\n", psw_info->name);
-}
-static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL);
-
-static void switch_timer(unsigned long data)
-{
- struct push_switch *psw = (struct push_switch *)data;
-
- schedule_work(&psw->work);
-}
-
-static void switch_work_handler(void *data)
-{
- struct platform_device *pdev = data;
- struct push_switch *psw = platform_get_drvdata(pdev);
-
- psw->state = 0;
-
- kobject_uevent(&pdev->dev.kobj, KOBJ_CHANGE);
-}
-
-static int switch_drv_probe(struct platform_device *pdev)
-{
- struct push_switch_platform_info *psw_info;
- struct push_switch *psw;
- int ret, irq;
-
- psw = kzalloc(sizeof(struct push_switch), GFP_KERNEL);
- if (unlikely(!psw))
- return -ENOMEM;
-
- irq = platform_get_irq(pdev, 0);
- if (unlikely(irq < 0)) {
- ret = -ENODEV;
- goto err;
- }
-
- psw_info = pdev->dev.platform_data;
- BUG_ON(!psw_info);
-
- ret = request_irq(irq, psw_info->irq_handler,
- IRQF_DISABLED | psw_info->irq_flags,
- psw_info->name ? psw_info->name : DRV_NAME, pdev);
- if (unlikely(ret < 0))
- goto err;
-
- if (psw_info->name) {
- ret = device_create_file(&pdev->dev, &dev_attr_switch);
- if (unlikely(ret)) {
- dev_err(&pdev->dev, "Failed creating device attrs\n");
- ret = -EINVAL;
- goto err_irq;
- }
- }
-
- INIT_WORK(&psw->work, switch_work_handler, pdev);
- init_timer(&psw->debounce);
-
- psw->debounce.function = switch_timer;
- psw->debounce.data = (unsigned long)psw;
-
- platform_set_drvdata(pdev, psw);
-
- return 0;
-
-err_irq:
- free_irq(irq, pdev);
-err:
- kfree(psw);
- return ret;
-}
-
-static int switch_drv_remove(struct platform_device *pdev)
-{
- struct push_switch *psw = platform_get_drvdata(pdev);
- struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
- int irq = platform_get_irq(pdev, 0);
-
- if (psw_info->name)
- device_remove_file(&pdev->dev, &dev_attr_switch);
-
- platform_set_drvdata(pdev, NULL);
- flush_scheduled_work();
- del_timer_sync(&psw->debounce);
- free_irq(irq, pdev);
-
- kfree(psw);
-
- return 0;
-}
-
-static struct platform_driver switch_driver = {
- .probe = switch_drv_probe,
- .remove = switch_drv_remove,
- .driver = {
- .name = DRV_NAME,
- },
-};
-
-static int __init switch_init(void)
-{
- printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION);
- return platform_driver_register(&switch_driver);
-}
-
-static void __exit switch_exit(void)
-{
- platform_driver_unregister(&switch_driver);
-}
-module_init(switch_init);
-module_exit(switch_exit);
-
-MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR("Paul Mundt");
-MODULE_LICENSE("GPLv2");
diff --git a/trunk/arch/sh/kernel/Makefile b/trunk/arch/sh/kernel/Makefile
index 99c7e5249f7a..5da88a43d350 100644
--- a/trunk/arch/sh/kernel/Makefile
+++ b/trunk/arch/sh/kernel/Makefile
@@ -4,7 +4,7 @@
extra-y := head.o init_task.o vmlinux.lds
-obj-y := process.o signal.o traps.o irq.o \
+obj-y := process.o signal.o entry.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
@@ -21,4 +21,3 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/trunk/arch/sh/kernel/cpu/Makefile b/trunk/arch/sh/kernel/cpu/Makefile
index 0582e6712b79..fb5dac069382 100644
--- a/trunk/arch/sh/kernel/cpu/Makefile
+++ b/trunk/arch/sh/kernel/cpu/Makefile
@@ -2,12 +2,11 @@
# Makefile for the Linux/SuperH CPU-specifc backends.
#
-obj-$(CONFIG_CPU_SH2) = sh2/
-obj-$(CONFIG_CPU_SH2A) = sh2a/
-obj-$(CONFIG_CPU_SH3) = sh3/
-obj-$(CONFIG_CPU_SH4) = sh4/
+obj-y += irq/ init.o clock.o
+
+obj-$(CONFIG_CPU_SH2) += sh2/
+obj-$(CONFIG_CPU_SH3) += sh3/
+obj-$(CONFIG_CPU_SH4) += sh4/
obj-$(CONFIG_UBC_WAKEUP) += ubc.o
obj-$(CONFIG_SH_ADC) += adc.o
-
-obj-y += irq/ init.o clock.o
diff --git a/trunk/arch/sh/kernel/cpu/clock.c b/trunk/arch/sh/kernel/cpu/clock.c
index abb586b12565..51ec64cdf348 100644
--- a/trunk/arch/sh/kernel/cpu/clock.c
+++ b/trunk/arch/sh/kernel/cpu/clock.c
@@ -5,11 +5,9 @@
*
* This clock framework is derived from the OMAP version by:
*
- * Copyright (C) 2004 - 2005 Nokia Corporation
+ * Copyright (C) 2004 Nokia Corporation
* Written by Tuukka Tikkanen
*
- * Modified for omap shared clock framework by Tony Lindgren
- *
* 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.
@@ -22,7 +20,6 @@
#include
#include
#include
-#include
#include
#include
@@ -198,37 +195,17 @@ void clk_recalc_rate(struct clk *clk)
propagate_rate(clk);
}
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk *clk_get(struct device *dev, const char *id)
+struct clk *clk_get(const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- int idno;
-
- if (dev == NULL || dev->bus != &platform_bus_type)
- idno = -1;
- else
- idno = to_platform_device(dev)->id;
mutex_lock(&clock_list_sem);
- list_for_each_entry(p, &clock_list, node) {
- if (p->id == idno &&
- strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
- clk = p;
- goto found;
- }
- }
-
list_for_each_entry(p, &clock_list, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
-
-found:
mutex_unlock(&clock_list_sem);
return clk;
diff --git a/trunk/arch/sh/kernel/cpu/init.c b/trunk/arch/sh/kernel/cpu/init.c
index 48121766e8d2..bfb90eb0b7a6 100644
--- a/trunk/arch/sh/kernel/cpu/init.c
+++ b/trunk/arch/sh/kernel/cpu/init.c
@@ -68,14 +68,12 @@ static void __init cache_init(void)
waysize = cpu_data->dcache.sets;
-#ifdef CCR_CACHE_ORA
/*
* If the OC is already in RAM mode, we only have
* half of the entries to flush..
*/
if (ccr & CCR_CACHE_ORA)
waysize >>= 1;
-#endif
waysize <<= cpu_data->dcache.entry_shift;
diff --git a/trunk/arch/sh/kernel/cpu/irq/Makefile b/trunk/arch/sh/kernel/cpu/irq/Makefile
index 0049d217561a..1c034c283f59 100644
--- a/trunk/arch/sh/kernel/cpu/irq/Makefile
+++ b/trunk/arch/sh/kernel/cpu/irq/Makefile
@@ -1,9 +1,8 @@
#
# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
#
-obj-y += imask.o
+obj-y += ipr.o imask.o
-obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
diff --git a/trunk/arch/sh/kernel/cpu/irq/imask.c b/trunk/arch/sh/kernel/cpu/irq/imask.c
index 301b505c4278..a33ae3e0a5a5 100644
--- a/trunk/arch/sh/kernel/cpu/irq/imask.c
+++ b/trunk/arch/sh/kernel/cpu/irq/imask.c
@@ -53,10 +53,7 @@ void static inline set_interrupt_registers(int ip)
{
unsigned long __dummy;
- asm volatile(
-#ifdef CONFIG_CPU_HAS_SR_RB
- "ldc %2, r6_bank\n\t"
-#endif
+ asm volatile("ldc %2, r6_bank\n\t"
"stc sr, %0\n\t"
"and #0xf0, %0\n\t"
"shlr2 %0\n\t"
diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c
index 74defe76a058..74ca576a7ce5 100644
--- a/trunk/arch/sh/kernel/cpu/irq/intc2.c
+++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c
@@ -11,29 +11,22 @@
* Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
*/
#include
-#include
+#include
#include
-
-#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)
-#define INTC2_BASE 0xffd40000
-#define INTC2_INTMSK (INTC2_BASE + 0x38)
-#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
-#endif
+#include
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);
+ ctrl_outl(1 << p->msk_shift,
+ INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset);
}
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);
+ ctrl_outl(1 << p->msk_shift,
+ INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset);
}
static struct irq_chip intc2_irq_chip = {
@@ -68,10 +61,12 @@ void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs)
/* Set the priority level */
local_irq_save(flags);
- ipr = ctrl_inl(INTC2_BASE + p->ipr_offset);
+ ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET +
+ p->ipr_offset);
ipr &= ~(0xf << p->ipr_shift);
ipr |= p->priority << p->ipr_shift;
- ctrl_outl(ipr, INTC2_BASE + p->ipr_offset);
+ ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET +
+ p->ipr_offset);
local_irq_restore(flags);
diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c
index 35eb5751a3aa..a0089563cbfc 100644
--- a/trunk/arch/sh/kernel/cpu/irq/ipr.c
+++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c
@@ -19,21 +19,25 @@
#include
#include
#include
-#include
-#include
+#include
+#include
+#include
+
static void disable_ipr_irq(unsigned int irq)
{
struct ipr_data *p = get_irq_chip_data(irq);
+ int shift = p->shift*4;
/* Set the priority in IPR to 0 */
- ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
+ ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr);
}
static void enable_ipr_irq(unsigned int irq)
{
struct ipr_data *p = get_irq_chip_data(irq);
+ int shift = p->shift*4;
/* Set priority in IPR back to original value */
- ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
+ ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr);
}
static struct irq_chip ipr_irq_chip = {
@@ -49,10 +53,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
for (i = 0; i < nr_irqs; i++) {
unsigned int irq = table[i].irq;
- table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
- /* could the IPR index be mapped, if not we ignore this */
- if (table[i].addr == 0)
- continue;
disable_irq_nosync(irq);
set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
handle_level_irq, "level");
@@ -62,6 +62,83 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
}
EXPORT_SYMBOL(make_ipr_irq);
+static struct ipr_data sys_ipr_map[] = {
+#ifndef CONFIG_CPU_SUBTYPE_SH7780
+ { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY },
+ { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY },
+#ifdef RTC_IRQ
+ { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY },
+#endif
+#ifdef SCI_ERI_IRQ
+ { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+ { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+ { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+#endif
+#ifdef SCIF1_ERI_IRQ
+ { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+ { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+ { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+ { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+ { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+ { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+ { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+ { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+#endif
+#ifdef SCIF_ERI_IRQ
+ { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+ { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+ { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+ { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+#endif
+#ifdef IRDA_ERI_IRQ
+ { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+ { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+ { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+ { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7706) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
+ /*
+ * Initialize the Interrupt Controller (INTC)
+ * registers to their power on values
+ */
+
+ /*
+ * Enable external irq (INTC IRQ mode).
+ * You should set corresponding bits of PFC to "00"
+ * to enable these interrupts.
+ */
+ { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY },
+ { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
+ { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
+ { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY },
+ { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY },
+ { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY },
+#endif
+#endif
+};
+
+void __init init_IRQ(void)
+{
+ make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map));
+
+#ifdef CONFIG_CPU_HAS_PINT_IRQ
+ init_IRQ_pint();
+#endif
+
+#ifdef CONFIG_CPU_HAS_INTC2_IRQ
+ init_IRQ_intc2();
+#endif
+ /* Perform the machine specific initialisation */
+ if (sh_mv.mv_init_irq != NULL)
+ sh_mv.mv_init_irq();
+
+ irq_ctx_init(smp_processor_id());
+}
+
#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
int ipr_irq_demux(int irq)
{
diff --git a/trunk/arch/sh/kernel/cpu/sh2/Makefile b/trunk/arch/sh/kernel/cpu/sh2/Makefile
index f0f059acfcfb..389353fba608 100644
--- a/trunk/arch/sh/kernel/cpu/sh2/Makefile
+++ b/trunk/arch/sh/kernel/cpu/sh2/Makefile
@@ -2,6 +2,5 @@
# Makefile for the Linux/SuperH SH-2 backends.
#
-obj-y := ex.o probe.o entry.o
+obj-y := probe.o
-obj-$(CONFIG_CPU_SUBTYPE_SH7619) += setup-sh7619.o clock-sh7619.o
diff --git a/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c
deleted file mode 100644
index d0440b269702..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2/clock-sh7619.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh2/clock-sh7619.c
- *
- * SH7619 support for the clock framework
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * Based on clock-sh4.c
- * Copyright (C) 2005 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
-#include
-#include
-#include
-#include
-
-const static int pll1rate[]={1,2};
-const static int pfc_divisors[]={1,2,0,4};
-
-#if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
-#define PLL2 (4)
-#elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6)
-#define PLL2 (2)
-#else
-#error "Illigal Clock Mode!"
-#endif
-
-static void master_clk_init(struct clk *clk)
-{
- clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
-}
-
-static struct clk_ops sh7619_master_clk_ops = {
- .init = master_clk_init,
-};
-
-static void module_clk_recalc(struct clk *clk)
-{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
- clk->rate = clk->parent->rate / pfc_divisors[idx];
-}
-
-static struct clk_ops sh7619_module_clk_ops = {
- .recalc = module_clk_recalc,
-};
-
-static void bus_clk_recalc(struct clk *clk)
-{
- clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
-}
-
-static struct clk_ops sh7619_bus_clk_ops = {
- .recalc = bus_clk_recalc,
-};
-
-static void cpu_clk_recalc(struct clk *clk)
-{
- clk->rate = clk->parent->rate;
-}
-
-static struct clk_ops sh7619_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
-};
-
-static struct clk_ops *sh7619_clk_ops[] = {
- &sh7619_master_clk_ops,
- &sh7619_module_clk_ops,
- &sh7619_bus_clk_ops,
- &sh7619_cpu_clk_ops,
-};
-
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(sh7619_clk_ops))
- *ops = sh7619_clk_ops[idx];
-}
-
diff --git a/trunk/arch/sh/kernel/cpu/sh2/entry.S b/trunk/arch/sh/kernel/cpu/sh2/entry.S
deleted file mode 100644
index 34d51b3745ea..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2/entry.S
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh2/entry.S
- *
- * The SH-2 exception entry
- *
- * Copyright (C) 2005,2006 Yoshinori Sato
- * Copyright (C) 2005 AXE,Inc.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Offsets to the stack */
-OFF_R0 = 0 /* Return value. New ABI also arg4 */
-OFF_R1 = 4 /* New ABI: arg5 */
-OFF_R2 = 8 /* New ABI: arg6 */
-OFF_R3 = 12 /* New ABI: syscall_nr */
-OFF_R4 = 16 /* New ABI: arg0 */
-OFF_R5 = 20 /* New ABI: arg1 */
-OFF_R6 = 24 /* New ABI: arg2 */
-OFF_R7 = 28 /* New ABI: arg3 */
-OFF_SP = (15*4)
-OFF_PC = (16*4)
-OFF_SR = (16*4+2*4)
-OFF_TRA = (16*4+6*4)
-
-#include
-
-ENTRY(exception_handler)
- ! already saved r0/r1
- mov.l r2,@-sp
- mov.l r3,@-sp
- mov r0,r1
- cli
- mov.l $cpu_mode,r2
- mov.l @r2,r0
- mov.l @(5*4,r15),r3 ! previous SR
- shll2 r3 ! set "S" flag
- rotl r0 ! T <- "S" flag
- rotl r0 ! "S" flag is LSB
- rotcr r3 ! T -> r3:b30
- shlr r3
- shlr r0
- bt/s 1f
- mov.l r3,@(5*4,r15) ! copy cpu mode to SR
- ! switch to kernel mode
- mov #1,r0
- rotr r0
- rotr r0
- mov.l r0,@r2 ! enter kernel mode
- mov.l $current_thread_info,r2
- mov.l @r2,r2
- mov #0x20,r0
- shll8 r0
- add r2,r0
- mov r15,r2 ! r2 = user stack top
- mov r0,r15 ! switch kernel stack
- add #-4,r15 ! dummy
- mov.l r1,@-r15 ! TRA
- sts.l macl, @-r15
- sts.l mach, @-r15
- stc.l gbr, @-r15
- mov.l @(4*4,r2),r0
- mov.l @(5*4,r2),r1
- mov.l r1,@-r15 ! original SR
- sts.l pr,@-r15
- mov.l r0,@-r15 ! original PC
- mov r2,r3
- add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame
- mov.l r3,@-r15 ! original SP
- mov.l r14,@-r15
- mov.l r13,@-r15
- mov.l r12,@-r15
- mov.l r11,@-r15
- mov.l r10,@-r15
- mov.l r9,@-r15
- mov.l r8,@-r15
- mov.l r7,@-r15
- mov.l r6,@-r15
- mov.l r5,@-r15
- mov.l r4,@-r15
- mov r2,r8 ! copy user -> kernel stack
- mov.l @r8+,r3
- mov.l r3,@-r15
- mov.l @r8+,r2
- mov.l r2,@-r15
- mov.l @r8+,r1
- mov.l r1,@-r15
- mov.l @r8+,r0
- bra 2f
- mov.l r0,@-r15
-1:
- ! in kernel exception
- mov #(22-4-4-1)*4+4,r0
- mov r15,r2
- sub r0,r15
- mov.l @r2+,r0 ! old R3
- mov.l r0,@-r15
- mov.l @r2+,r0 ! old R2
- mov.l r0,@-r15
- mov.l @r2+,r0 ! old R1
- mov.l r0,@-r15
- mov.l @r2+,r0 ! old R0
- mov.l r0,@-r15
- mov.l @r2+,r3 ! old PC
- mov.l @r2+,r0 ! old SR
- add #-4,r2 ! exception frame stub (sr)
- mov.l r1,@-r2 ! TRA
- sts.l macl, @-r2
- sts.l mach, @-r2
- stc.l gbr, @-r2
- mov.l r0,@-r2 ! save old SR
- sts.l pr,@-r2
- mov.l r3,@-r2 ! save old PC
- mov r2,r0
- add #8*4,r0
- mov.l r0,@-r2 ! save old SP
- mov.l r14,@-r2
- mov.l r13,@-r2
- mov.l r12,@-r2
- mov.l r11,@-r2
- mov.l r10,@-r2
- mov.l r9,@-r2
- mov.l r8,@-r2
- mov.l r7,@-r2
- mov.l r6,@-r2
- mov.l r5,@-r2
- mov.l r4,@-r2
- mov.l @(OFF_R0,r15),r0
- mov.l @(OFF_R1,r15),r1
- mov.l @(OFF_R2,r15),r2
- mov.l @(OFF_R3,r15),r3
-2:
- mov #OFF_TRA,r8
- add r15,r8
- mov.l @r8,r9
- mov #64,r8
- cmp/hs r8,r9
- bt interrupt_entry ! vec >= 64 is interrupt
- mov #32,r8
- cmp/hs r8,r9
- bt trap_entry ! 64 > vec >= 32 is trap
- mov.l 4f,r8
- mov r9,r4
- shll2 r9
- add r9,r8
- mov.l @r8,r8
- mov #0,r9
- cmp/eq r9,r8
- bf 3f
- mov.l 8f,r8 ! unhandled exception
-3:
- mov.l 5f,r10
- jmp @r8
- lds r10,pr
-
-interrupt_entry:
- mov r9,r4
- mov.l 6f,r9
- mov.l 7f,r8
- jmp @r8
- lds r9,pr
-
- .align 2
-4: .long exception_handling_table
-5: .long ret_from_exception
-6: .long ret_from_irq
-7: .long do_IRQ
-8: .long do_exception_error
-
-trap_entry:
- add #-0x10,r9
- shll2 r9 ! TRA
- mov #OFF_TRA,r8
- add r15,r8
- mov.l r9,@r8
- mov r9,r8
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 5f, r9
- jsr @r9
- nop
-#endif
- sti
- bra system_call
- nop
-
- .align 2
-1: .long syscall_exit
-2: .long break_point_trap_software
-3: .long NR_syscalls
-4: .long sys_call_table
-#ifdef CONFIG_TRACE_IRQFLAGS
-5: .long trace_hardirqs_on
-#endif
-
-#if defined(CONFIG_SH_STANDARD_BIOS)
- /* Unwind the stack and jmp to the debug entry */
-debug_kernel_fw:
- mov r15,r0
- add #(22-4)*4-4,r0
- ldc.l @r0+,gbr
- lds.l @r0+,mach
- lds.l @r0+,macl
- mov r15,r0
- mov.l @(OFF_SP,r0),r1
- mov #OFF_SR,r2
- mov.l @(r0,r2),r3
- mov.l r3,@-r1
- mov #OFF_SP,r2
- mov.l @(r0,r2),r3
- mov.l r3,@-r1
- mov r15,r0
- add #(22-4)*4-8,r0
- mov.l 1f,r2
- mov.l @r2,r2
- stc sr,r3
- mov.l r2,@r0
- mov.l r3,@r0
- mov.l r1,@(8,r0)
- mov.l @r15+, r0
- mov.l @r15+, r1
- mov.l @r15+, r2
- mov.l @r15+, r3
- mov.l @r15+, r4
- mov.l @r15+, r5
- mov.l @r15+, r6
- mov.l @r15+, r7
- mov.l @r15+, r8
- mov.l @r15+, r9
- mov.l @r15+, r10
- mov.l @r15+, r11
- mov.l @r15+, r12
- mov.l @r15+, r13
- mov.l @r15+, r14
- add #8,r15
- lds.l @r15+, pr
- rte
- mov.l @r15+,r15
- .align 2
-1: .long gdb_vbr_vector
-#endif /* CONFIG_SH_STANDARD_BIOS */
-
-ENTRY(address_error_handler)
- mov r15,r4 ! regs
- add #4,r4
- mov #OFF_PC,r0
- mov.l @(r0,r15),r6 ! pc
- mov.l 1f,r0
- jmp @r0
- mov #0,r5 ! writeaccess is unknown
- .align 2
-
-1: .long do_address_error
-
-restore_all:
- cli
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 3f, r0
- jsr @r0
- nop
-#endif
- mov r15,r0
- mov.l $cpu_mode,r2
- mov #OFF_SR,r3
- mov.l @(r0,r3),r1
- mov.l r1,@r2
- shll2 r1 ! clear MD bit
- shlr2 r1
- mov.l @(OFF_SP,r0),r2
- add #-8,r2
- mov.l r2,@(OFF_SP,r0) ! point exception frame top
- mov.l r1,@(4,r2) ! set sr
- mov #OFF_PC,r3
- mov.l @(r0,r3),r1
- mov.l r1,@r2 ! set pc
- add #4*16+4,r0
- lds.l @r0+,pr
- add #4,r0 ! skip sr
- ldc.l @r0+,gbr
- lds.l @r0+,mach
- lds.l @r0+,macl
- get_current_thread_info r0, r1
- mov.l $current_thread_info,r1
- mov.l r0,@r1
- mov.l @r15+,r0
- mov.l @r15+,r1
- mov.l @r15+,r2
- mov.l @r15+,r3
- mov.l @r15+,r4
- mov.l @r15+,r5
- mov.l @r15+,r6
- mov.l @r15+,r7
- mov.l @r15+,r8
- mov.l @r15+,r9
- mov.l @r15+,r10
- mov.l @r15+,r11
- mov.l @r15+,r12
- mov.l @r15+,r13
- mov.l @r15+,r14
- mov.l @r15,r15
- rte
- nop
-2:
- mov.l 1f,r8
- mov.l 2f,r9
- jmp @r9
- lds r8,pr
-
- .align 2
-$current_thread_info:
- .long __current_thread_info
-$cpu_mode:
- .long __cpu_mode
-#ifdef CONFIG_TRACE_IRQFLAGS
-3: .long trace_hardirqs_off
-#endif
-
-! common exception handler
-#include "../../entry-common.S"
-
- .data
-! cpu operation mode
-! bit30 = MD (compatible SH3/4)
-__cpu_mode:
- .long 0x40000000
-
- .section .bss
-__current_thread_info:
- .long 0
-
-ENTRY(exception_handling_table)
- .space 4*32
diff --git a/trunk/arch/sh/kernel/cpu/sh2/ex.S b/trunk/arch/sh/kernel/cpu/sh2/ex.S
deleted file mode 100644
index 6d285af7846c..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2/ex.S
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh2/ex.S
- *
- * The SH-2 exception vector table
- *
- * Copyright (C) 2005 Yoshinori Sato
- *
- * 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
-
-!
-! convert Exception Vector to Exception Number
-!
-exception_entry:
-no = 0
- .rept 256
- mov.l r0,@-sp
- mov #no,r0
- bra exception_trampoline
- and #0xff,r0
-no = no + 1
- .endr
-exception_trampoline:
- mov.l r1,@-sp
- mov.l $exception_handler,r1
- jmp @r1
-
- .align 2
-$exception_entry:
- .long exception_entry
-$exception_handler:
- .long exception_handler
-!
-! Exception Vector Base
-!
- .align 2
-ENTRY(vbr_base)
-vector = 0
- .rept 256
- .long exception_entry + vector * 8
-vector = vector + 1
- .endr
diff --git a/trunk/arch/sh/kernel/cpu/sh2/probe.c b/trunk/arch/sh/kernel/cpu/sh2/probe.c
index ba527d9b5024..f17a2a0d588e 100644
--- a/trunk/arch/sh/kernel/cpu/sh2/probe.c
+++ b/trunk/arch/sh/kernel/cpu/sh2/probe.c
@@ -17,23 +17,17 @@
int __init detect_cpu_and_cache_system(void)
{
-#if defined(CONFIG_CPU_SUBTYPE_SH7604)
+ /*
+ * For now, assume SH7604 .. fix this later.
+ */
cpu_data->type = CPU_SH7604;
cpu_data->dcache.ways = 4;
- cpu_data->dcache.way_incr = (1<<10);
+ cpu_data->dcache.way_shift = 6;
cpu_data->dcache.sets = 64;
cpu_data->dcache.entry_shift = 4;
cpu_data->dcache.linesz = L1_CACHE_BYTES;
cpu_data->dcache.flags = 0;
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
- cpu_data->type = CPU_SH7619;
- cpu_data->dcache.ways = 4;
- cpu_data->dcache.way_incr = (1<<12);
- cpu_data->dcache.sets = 256;
- cpu_data->dcache.entry_shift = 4;
- cpu_data->dcache.linesz = L1_CACHE_BYTES;
- cpu_data->dcache.flags = 0;
-#endif
+
/*
* SH-2 doesn't have separate caches
*/
diff --git a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c
deleted file mode 100644
index 82c2d905152f..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SH7619 Setup
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * 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
-#include
-#include
-#include
-
-static struct plat_sci_port sci_platform_data[] = {
- {
- .mapbase = 0xf8400000,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 88, 89, 91, 90},
- }, {
- .mapbase = 0xf8410000,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 92, 93, 95, 94},
- }, {
- .mapbase = 0xf8420000,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 96, 97, 99, 98},
- }, {
- .flags = 0,
- }
-};
-
-static struct platform_device sci_device = {
- .name = "sh-sci",
- .id = -1,
- .dev = {
- .platform_data = sci_platform_data,
- },
-};
-
-static struct platform_device *sh7619_devices[] __initdata = {
- &sci_device,
-};
-
-static int __init sh7619_devices_setup(void)
-{
- return platform_add_devices(sh7619_devices,
- ARRAY_SIZE(sh7619_devices));
-}
-__initcall(sh7619_devices_setup);
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/Makefile b/trunk/arch/sh/kernel/cpu/sh2a/Makefile
deleted file mode 100644
index 350972ae9410..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2a/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the Linux/SuperH SH-2A backends.
-#
-
-obj-y := common.o probe.o
-
-common-y += $(addprefix ../sh2/, ex.o)
-common-y += $(addprefix ../sh2/, entry.o)
-
-obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
deleted file mode 100644
index a9ad309c6a33..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7206.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh2a/clock-sh7206.c
- *
- * SH7206 support for the clock framework
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * Based on clock-sh4.c
- * Copyright (C) 2005 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
-#include
-#include
-#include
-#include
-
-const static int pll1rate[]={1,2,3,4,6,8};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
-#define ifc_divisors pfc_divisors
-
-#if (CONFIG_SH_CLK_MD == 2)
-#define PLL2 (4)
-#elif (CONFIG_SH_CLK_MD == 6)
-#define PLL2 (2)
-#elif (CONFIG_SH_CLK_MD == 7)
-#define PLL2 (1)
-#else
-#error "Illigal Clock Mode!"
-#endif
-
-static void master_clk_init(struct clk *clk)
-{
- clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
-}
-
-static struct clk_ops sh7206_master_clk_ops = {
- .init = master_clk_init,
-};
-
-static void module_clk_recalc(struct clk *clk)
-{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
- clk->rate = clk->parent->rate / pfc_divisors[idx];
-}
-
-static struct clk_ops sh7206_module_clk_ops = {
- .recalc = module_clk_recalc,
-};
-
-static void bus_clk_recalc(struct clk *clk)
-{
- clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007];
-}
-
-static struct clk_ops sh7206_bus_clk_ops = {
- .recalc = bus_clk_recalc,
-};
-
-static void cpu_clk_recalc(struct clk *clk)
-{
- int idx = (ctrl_inw(FREQCR) & 0x0007);
- clk->rate = clk->parent->rate / ifc_divisors[idx];
-}
-
-static struct clk_ops sh7206_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
-};
-
-static struct clk_ops *sh7206_clk_ops[] = {
- &sh7206_master_clk_ops,
- &sh7206_module_clk_ops,
- &sh7206_bus_clk_ops,
- &sh7206_cpu_clk_ops,
-};
-
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(sh7206_clk_ops))
- *ops = sh7206_clk_ops[idx];
-}
-
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/probe.c b/trunk/arch/sh/kernel/cpu/sh2a/probe.c
deleted file mode 100644
index 87c6c0542089..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2a/probe.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/sh/kernel/cpu/sh2a/probe.c
- *
- * CPU Subtype Probing for SH-2A.
- *
- * Copyright (C) 2004, 2005 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
-#include
-#include
-
-int __init detect_cpu_and_cache_system(void)
-{
- /* Just SH7206 for now .. */
- cpu_data->type = CPU_SH7206;
-
- cpu_data->dcache.ways = 4;
- cpu_data->dcache.way_incr = (1 << 11);
- cpu_data->dcache.sets = 128;
- cpu_data->dcache.entry_shift = 4;
- cpu_data->dcache.linesz = L1_CACHE_BYTES;
- cpu_data->dcache.flags = 0;
-
- /*
- * The icache is the same as the dcache as far as this setup is
- * concerned. The only real difference in hardware is that the icache
- * lacks the U bit that the dcache has, none of this has any bearing
- * on the cache info.
- */
- cpu_data->icache = cpu_data->dcache;
-
- return 0;
-}
-
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
deleted file mode 100644
index cdfeef49e62e..000000000000
--- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SH7206 Setup
- *
- * Copyright (C) 2006 Yoshinori Sato
- *
- * 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
-#include
-#include
-#include
-
-static struct plat_sci_port sci_platform_data[] = {
- {
- .mapbase = 0xfffe8000,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 240, 241, 242, 243},
- }, {
- .mapbase = 0xfffe8800,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 244, 245, 246, 247},
- }, {
- .mapbase = 0xfffe9000,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 248, 249, 250, 251},
- }, {
- .mapbase = 0xfffe9800,
- .flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 252, 253, 254, 255},
- }, {
- .flags = 0,
- }
-};
-
-static struct platform_device sci_device = {
- .name = "sh-sci",
- .id = -1,
- .dev = {
- .platform_data = sci_platform_data,
- },
-};
-
-static struct platform_device *sh7206_devices[] __initdata = {
- &sci_device,
-};
-
-static int __init sh7206_devices_setup(void)
-{
- return platform_add_devices(sh7206_devices,
- ARRAY_SIZE(sh7206_devices));
-}
-__initcall(sh7206_devices_setup);
diff --git a/trunk/arch/sh/kernel/cpu/sh3/Makefile b/trunk/arch/sh/kernel/cpu/sh3/Makefile
index 83905e4e4387..58d3815695ff 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/Makefile
+++ b/trunk/arch/sh/kernel/cpu/sh3/Makefile
@@ -2,7 +2,7 @@
# Makefile for the Linux/SuperH SH-3 backends.
#
-obj-y := ex.o probe.o entry.o
+obj-y := ex.o probe.o
# CPU subtype setup
obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
diff --git a/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c
index b791a29fdb62..10461a745e5f 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c
+++ b/trunk/arch/sh/kernel/cpu/sh3/clock-sh7709.c
@@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
static void set_bus_parent(struct clk *clk)
{
- struct clk *bus_clk = clk_get(NULL, "bus_clk");
+ struct clk *bus_clk = clk_get("bus_clk");
clk->parent = bus_clk;
clk_put(bus_clk);
}
diff --git a/trunk/arch/sh/kernel/cpu/sh4/Makefile b/trunk/arch/sh/kernel/cpu/sh4/Makefile
index 6e415baf04b4..8dbf3895ece7 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/Makefile
+++ b/trunk/arch/sh/kernel/cpu/sh4/Makefile
@@ -2,8 +2,7 @@
# Makefile for the Linux/SuperH SH-4 backends.
#
-obj-y := ex.o probe.o common.o
-common-y += $(addprefix ../sh3/, entry.o)
+obj-y := ex.o probe.o
obj-$(CONFIG_SH_FPU) += fpu.o
obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
diff --git a/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index fa2019aabd74..bfdf5fe8d948 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -97,7 +97,7 @@ static void shoc_clk_recalc(struct clk *clk)
static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
{
- struct clk *bclk = clk_get(NULL, "bus_clk");
+ struct clk *bclk = clk_get("bus_clk");
unsigned long bclk_rate = clk_get_rate(bclk);
clk_put(bclk);
@@ -151,7 +151,7 @@ static struct clk *sh4202_onchip_clocks[] = {
static int __init sh4202_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk = clk_get("master_clk");
int i;
for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
diff --git a/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c
index 9e6a216750c8..93ad367342c9 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/clock-sh7780.c
@@ -98,7 +98,7 @@ static struct clk *sh7780_onchip_clocks[] = {
static int __init sh7780_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk = clk_get("master_clk");
int i;
for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
diff --git a/trunk/arch/sh/kernel/cpu/sh4/fpu.c b/trunk/arch/sh/kernel/cpu/sh4/fpu.c
index 7624677f6628..f486c07e10e2 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/fpu.c
@@ -282,8 +282,11 @@ ieee_fpe_handler (struct pt_regs *regs)
grab_fpu(regs);
restore_fpu(tsk);
set_tsk_thread_flag(tsk, TIF_USEDFPU);
- } else
+ } else {
+ tsk->thread.trap_no = 11;
+ tsk->thread.error_code = 0;
force_sig(SIGFPE, tsk);
+ }
regs->pc = nextpc;
return 1;
@@ -293,29 +296,29 @@ ieee_fpe_handler (struct pt_regs *regs)
}
asmlinkage void
-do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6,
- unsigned long r7, struct pt_regs __regs)
+do_fpu_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);
struct task_struct *tsk = current;
- if (ieee_fpe_handler(regs))
+ if (ieee_fpe_handler (®s))
return;
- regs->pc += 2;
- save_fpu(tsk, regs);
+ regs.pc += 2;
+ save_fpu(tsk, ®s);
+ tsk->thread.trap_no = 11;
+ tsk->thread.error_code = 0;
force_sig(SIGFPE, tsk);
}
asmlinkage void
do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
- unsigned long r7, struct pt_regs __regs)
+ unsigned long r7, struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
struct task_struct *tsk = current;
- grab_fpu(regs);
- if (!user_mode(regs)) {
+ grab_fpu(®s);
+ if (!user_mode(®s)) {
printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
return;
}
diff --git a/trunk/arch/sh/kernel/cpu/sh4/probe.c b/trunk/arch/sh/kernel/cpu/sh4/probe.c
index afe0f1b1c030..c294de1e14a3 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/probe.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/probe.c
@@ -79,16 +79,16 @@ int __init detect_cpu_and_cache_system(void)
case 0x205:
cpu_data->type = CPU_SH7750;
cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
- CPU_HAS_PERF_COUNTER;
+ CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
break;
case 0x206:
cpu_data->type = CPU_SH7750S;
cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
- CPU_HAS_PERF_COUNTER;
+ CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
break;
case 0x1100:
cpu_data->type = CPU_SH7751;
- cpu_data->flags |= CPU_HAS_FPU;
+ cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
break;
case 0x2000:
cpu_data->type = CPU_SH73180;
@@ -126,22 +126,23 @@ int __init detect_cpu_and_cache_system(void)
break;
case 0x8000:
cpu_data->type = CPU_ST40RA;
- cpu_data->flags |= CPU_HAS_FPU;
+ cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
break;
case 0x8100:
cpu_data->type = CPU_ST40GX1;
- cpu_data->flags |= CPU_HAS_FPU;
+ cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
break;
case 0x700:
cpu_data->type = CPU_SH4_501;
cpu_data->icache.ways = 2;
cpu_data->dcache.ways = 2;
+ cpu_data->flags |= CPU_HAS_PTEA;
break;
case 0x600:
cpu_data->type = CPU_SH4_202;
cpu_data->icache.ways = 2;
cpu_data->dcache.ways = 2;
- cpu_data->flags |= CPU_HAS_FPU;
+ cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
break;
case 0x500 ... 0x501:
switch (prr) {
@@ -159,7 +160,7 @@ int __init detect_cpu_and_cache_system(void)
cpu_data->icache.ways = 2;
cpu_data->dcache.ways = 2;
- cpu_data->flags |= CPU_HAS_FPU;
+ cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
break;
default:
@@ -172,10 +173,6 @@ int __init detect_cpu_and_cache_system(void)
cpu_data->dcache.ways = 1;
#endif
-#ifdef CONFIG_CPU_HAS_PTEA
- 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.
diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index bbcb06f18b04..50812d57c1c1 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -2,7 +2,6 @@
* SH7750/SH7751 Setup
*
* 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
@@ -11,7 +10,6 @@
#include
#include
#include
-#include
#include
static struct plat_sci_port sci_platform_data[] = {
@@ -48,71 +46,3 @@ static int __init sh7750_devices_setup(void)
ARRAY_SIZE(sh7750_devices));
}
__initcall(sh7750_devices_setup);
-
-static struct ipr_data sh7750_ipr_map[] = {
- /* IRQ, IPR-idx, shift, priority */
- { 16, 0, 12, 2 }, /* TMU0 TUNI*/
- { 17, 0, 12, 2 }, /* TMU1 TUNI */
- { 18, 0, 4, 2 }, /* TMU2 TUNI */
- { 19, 0, 4, 2 }, /* TMU2 TIPCI */
- { 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) */
- { 23, 1, 4, 3 }, /* SCI ERI */
- { 24, 1, 4, 3 }, /* SCI RXI */
- { 25, 1, 4, 3 }, /* SCI TXI */
- { 40, 2, 4, 3 }, /* SCIF ERI */
- { 41, 2, 4, 3 }, /* SCIF RXI */
- { 42, 2, 4, 3 }, /* SCIF BRI */
- { 43, 2, 4, 3 }, /* SCIF TXI */
- { 34, 2, 8, 7 }, /* DMAC DMTE0 */
- { 35, 2, 8, 7 }, /* DMAC DMTE1 */
- { 36, 2, 8, 7 }, /* DMAC DMTE2 */
- { 37, 2, 8, 7 }, /* DMAC DMTE3 */
- { 28, 2, 8, 7 }, /* DMAC DMAE */
-};
-
-static struct ipr_data sh7751_ipr_map[] = {
- { 44, 2, 8, 7 }, /* DMAC DMTE4 */
- { 45, 2, 8, 7 }, /* DMAC DMTE5 */
- { 46, 2, 8, 7 }, /* DMAC DMTE6 */
- { 47, 2, 8, 7 }, /* DMAC DMTE7 */
- /* The following use INTC_INPRI00 for masking, which is a 32-bit
- register, not a 16-bit register like the IPRx registers, so it
- would need special support */
- /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
- /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
-};
-
-static unsigned long ipr_offsets[] = {
- 0xffd00004UL, /* 0: IPRA */
- 0xffd00008UL, /* 1: IPRB */
- 0xffd0000cUL, /* 2: IPRC */
- 0xffd00010UL, /* 3: IPRD */
-};
-
-/* given the IPR index return the address of the IPR register */
-unsigned int map_ipridx_to_addr(int idx)
-{
- if (idx >= ARRAY_SIZE(ipr_offsets))
- return 0;
- return ipr_offsets[idx];
-}
-
-#define INTC_ICR 0xffd00000UL
-#define INTC_ICR_IRLM (1<<7)
-
-/* enable individual interrupt mode for external interupts */
-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
-}
diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c
index 9aeaa2ddaa28..814ddb226531 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c
@@ -79,27 +79,25 @@ static int __init sh7780_devices_setup(void)
__initcall(sh7780_devices_setup);
static struct intc2_data intc2_irq_table[] = {
- { 28, 0, 24, 0, 0, 2 }, /* TMU0 */
+ { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 },
+ { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+ { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+ { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+ { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+ { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
- { 21, 1, 0, 0, 2, 2 },
- { 22, 1, 1, 0, 2, 2 },
- { 23, 1, 2, 0, 2, 2 },
+ { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+ { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
- { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */
- { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */
- { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */
- { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */
-
- { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */
- { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */
- { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */
- { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */
-
- { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */
- { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */
- { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */
- { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */
- { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */
+ { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
+ { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
+ { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
+ { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
+ { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
};
void __init init_IRQ_intc2(void)
diff --git a/trunk/arch/sh/kernel/cpu/sh4/sq.c b/trunk/arch/sh/kernel/cpu/sh4/sq.c
index 55f43506995a..7bcc73f9b8df 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/sq.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/sq.c
@@ -19,7 +19,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -67,7 +67,6 @@ void sq_flush_range(unsigned long start, unsigned int len)
/* Wait for completion */
store_queue_barrier();
}
-EXPORT_SYMBOL(sq_flush_range);
static inline void sq_mapping_list_add(struct sq_mapping *map)
{
@@ -167,7 +166,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
map->size = size;
map->name = name;
- page = bitmap_find_free_region(sq_bitmap, 0x04000000 >> PAGE_SHIFT,
+ page = bitmap_find_free_region(sq_bitmap, 0x04000000,
get_order(map->size));
if (unlikely(page < 0)) {
ret = -ENOSPC;
@@ -194,7 +193,6 @@ unsigned long sq_remap(unsigned long phys, unsigned int size,
kmem_cache_free(sq_cache, map);
return ret;
}
-EXPORT_SYMBOL(sq_remap);
/**
* sq_unmap - Unmap a Store Queue allocation
@@ -236,7 +234,6 @@ void sq_unmap(unsigned long vaddr)
kmem_cache_free(sq_cache, map);
}
-EXPORT_SYMBOL(sq_unmap);
/*
* Needlessly complex sysfs interface. Unfortunately it doesn't seem like
@@ -405,3 +402,7 @@ module_exit(sq_api_exit);
MODULE_AUTHOR("Paul Mundt , M. R. Brown ");
MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues");
MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(sq_remap);
+EXPORT_SYMBOL(sq_unmap);
+EXPORT_SYMBOL(sq_flush_range);
diff --git a/trunk/arch/sh/kernel/early_printk.c b/trunk/arch/sh/kernel/early_printk.c
index 60340823798a..a00022722e9e 100644
--- a/trunk/arch/sh/kernel/early_printk.c
+++ b/trunk/arch/sh/kernel/early_printk.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
#ifdef CONFIG_SH_STANDARD_BIOS
#include
@@ -62,9 +62,17 @@ static struct console bios_console = {
#include
#include "../../../drivers/serial/sh-sci.h"
+#ifdef CONFIG_CPU_SH4
+#define SCIF_REG 0xffe80000
+#elif defined(CONFIG_CPU_SUBTYPE_SH72060)
+#define SCIF_REG 0xfffe9800
+#else
+#error "Undefined SCIF for this subtype"
+#endif
+
static struct uart_port scif_port = {
- .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT,
- .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT,
+ .mapbase = SCIF_REG,
+ .membase = (char __iomem *)SCIF_REG,
};
static void scif_sercon_putc(int c)
@@ -105,29 +113,23 @@ static struct console scif_console = {
.index = -1,
};
-#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
-/*
- * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
- * devices that aren't using sh-ipl+g.
- */
static void scif_sercon_init(int baud)
{
- ctrl_outw(0, scif_port.mapbase + 8);
- ctrl_outw(0, scif_port.mapbase);
+ ctrl_outw(0, SCIF_REG + 8);
+ ctrl_outw(0, SCIF_REG);
/* Set baud rate */
ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) /
- (32 * baud) - 1, scif_port.mapbase + 4);
-
- ctrl_outw(12, scif_port.mapbase + 24);
- ctrl_outw(8, scif_port.mapbase + 24);
- ctrl_outw(0, scif_port.mapbase + 32);
- ctrl_outw(0x60, scif_port.mapbase + 16);
- ctrl_outw(0, scif_port.mapbase + 36);
- ctrl_outw(0x30, scif_port.mapbase + 8);
+ (32 * baud) - 1, SCIF_REG + 4);
+
+ ctrl_outw(12, SCIF_REG + 24);
+ ctrl_outw(8, SCIF_REG + 24);
+ ctrl_outw(0, SCIF_REG + 32);
+ ctrl_outw(0x60, SCIF_REG + 16);
+ ctrl_outw(0, SCIF_REG + 36);
+ ctrl_outw(0x30, SCIF_REG + 8);
}
-#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */
-#endif /* CONFIG_EARLY_SCIF_CONSOLE */
+#endif
/*
* Setup a default console, if more than one is compiled in, rely on the
@@ -166,7 +168,7 @@ int __init setup_early_printk(char *opt)
if (!strncmp(buf, "serial", 6)) {
early_console = &scif_console;
-#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS)
+#ifdef CONFIG_CPU_SH4
scif_sercon_init(115200);
#endif
}
diff --git a/trunk/arch/sh/kernel/entry-common.S b/trunk/arch/sh/kernel/entry-common.S
deleted file mode 100644
index 29136a35d7c7..000000000000
--- a/trunk/arch/sh/kernel/entry-common.S
+++ /dev/null
@@ -1,433 +0,0 @@
-/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
- *
- * linux/arch/sh/entry.S
- *
- * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
- * Copyright (C) 2003 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.
- *
- */
-
-! NOTE:
-! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
-! to be jumped is too far, but it causes illegal slot exception.
-
-/*
- * entry.S contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call.
- *
- * NOTE: This code uses a convention that instructions in the delay slot
- * of a transfer-control instruction are indented by an extra space, thus:
- *
- * jmp @k0 ! control-transfer instruction
- * ldc k1, ssr ! delay slot
- *
- * Stack layout in 'ret_from_syscall':
- * ptrace needs to have all regs on the stack.
- * if the order here is changed, it needs to be
- * updated in ptrace.c and ptrace.h
- *
- * r0
- * ...
- * r15 = stack pointer
- * spc
- * pr
- * ssr
- * gbr
- * mach
- * macl
- * syscall #
- *
- */
-
-#if defined(CONFIG_PREEMPT)
-# define preempt_stop() cli
-#else
-# define preempt_stop()
-# define resume_kernel __restore_all
-#endif
-
-#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
-! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
-! If both are configured, handle the debug traps (breakpoints) in SW,
-! but still allow BIOS traps to FW.
-
- .align 2
-debug_kernel:
-#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
- /* Force BIOS call to FW (debug_trap put TRA in r8) */
- mov r8,r0
- shlr2 r0
- cmp/eq #0x3f,r0
- bt debug_kernel_fw
-#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
-
-debug_enter:
-#if defined(CONFIG_SH_KGDB)
- /* Jump to kgdb, pass stacked regs as arg */
-debug_kernel_sw:
- mov.l 3f, r0
- jmp @r0
- mov r15, r4
- .align 2
-3: .long kgdb_handle_exception
-#endif /* CONFIG_SH_KGDB */
-
-#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
-
-
- .align 2
-debug_trap:
-#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
- mov #OFF_SR, r0
- mov.l @(r0,r15), r0 ! get status register
- shll r0
- shll r0 ! kernel space?
- bt/s debug_kernel
-#endif
- mov.l @r15, r0 ! Restore R0 value
- mov.l 1f, r8
- jmp @r8
- nop
-
- .align 2
-ENTRY(exception_error)
- !
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 3f, r0
- jsr @r0
- nop
-#endif
- sti
- mov.l 2f, r0
- jmp @r0
- nop
-
-!
- .align 2
-1: .long break_point_trap_software
-2: .long do_exception_error
-#ifdef CONFIG_TRACE_IRQFLAGS
-3: .long trace_hardirqs_on
-#endif
-
- .align 2
-ret_from_exception:
- preempt_stop()
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 4f, r0
- jsr @r0
- nop
-#endif
-ENTRY(ret_from_irq)
- !
- mov #OFF_SR, r0
- mov.l @(r0,r15), r0 ! get status register
- shll r0
- shll r0 ! kernel space?
- get_current_thread_info r8, r0
- bt resume_kernel ! Yes, it's from kernel, go back soon
-
-#ifdef CONFIG_PREEMPT
- bra resume_userspace
- nop
-ENTRY(resume_kernel)
- mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
- tst r0, r0
- bf noresched
-need_resched:
- mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
- tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
- bt noresched
-
- mov #OFF_SR, r0
- mov.l @(r0,r15), r0 ! get status register
- and #0xf0, r0 ! interrupts off (exception path)?
- cmp/eq #0xf0, r0
- bt noresched
-
- mov.l 1f, r0
- mov.l r0, @(TI_PRE_COUNT,r8)
-
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 3f, r0
- jsr @r0
- nop
-#endif
- sti
- mov.l 2f, r0
- jsr @r0
- nop
- mov #0, r0
- mov.l r0, @(TI_PRE_COUNT,r8)
- cli
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 4f, r0
- jsr @r0
- nop
-#endif
-
- bra need_resched
- nop
-
-noresched:
- bra __restore_all
- nop
-
- .align 2
-1: .long PREEMPT_ACTIVE
-2: .long schedule
-#ifdef CONFIG_TRACE_IRQFLAGS
-3: .long trace_hardirqs_on
-4: .long trace_hardirqs_off
-#endif
-#endif
-
-ENTRY(resume_userspace)
- ! r8: current_thread_info
- cli
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 5f, r0
- jsr @r0
- nop
-#endif
- mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
- tst #_TIF_WORK_MASK, r0
- bt/s __restore_all
- tst #_TIF_NEED_RESCHED, r0
-
- .align 2
-work_pending:
- ! r0: current_thread_info->flags
- ! r8: current_thread_info
- ! t: result of "tst #_TIF_NEED_RESCHED, r0"
- bf/s work_resched
- tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
-work_notifysig:
- bt/s __restore_all
- mov r15, r4
- mov r12, r5 ! set arg1(save_r0)
- mov r0, r6
- mov.l 2f, r1
- mov.l 3f, r0
- jmp @r1
- lds r0, pr
-work_resched:
-#ifndef CONFIG_PREEMPT
- ! gUSA handling
- mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
- mov r0, r1
- shll r0
- bf/s 1f
- shll r0
- bf/s 1f
- mov #OFF_PC, r0
- ! SP >= 0xc0000000 : gUSA mark
- mov.l @(r0,r15), r2 ! get user space PC (program counter)
- mov.l @(OFF_R0,r15), r3 ! end point
- cmp/hs r3, r2 ! r2 >= r3?
- bt 1f
- add r3, r1 ! rewind point #2
- mov.l r1, @(r0,r15) ! reset PC to rewind point #2
- !
-1:
-#endif
- mov.l 1f, r1
- jsr @r1 ! schedule
- nop
- cli
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 5f, r0
- jsr @r0
- nop
-#endif
- !
- mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
- tst #_TIF_WORK_MASK, r0
- bt __restore_all
- bra work_pending
- tst #_TIF_NEED_RESCHED, r0
-
- .align 2
-1: .long schedule
-2: .long do_notify_resume
-3: .long restore_all
-#ifdef CONFIG_TRACE_IRQFLAGS
-4: .long trace_hardirqs_on
-5: .long trace_hardirqs_off
-#endif
-
- .align 2
-syscall_exit_work:
- ! r0: current_thread_info->flags
- ! r8: current_thread_info
- tst #_TIF_SYSCALL_TRACE, r0
- bt/s work_pending
- tst #_TIF_NEED_RESCHED, r0
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 5f, r0
- jsr @r0
- nop
-#endif
- sti
- ! XXX setup arguments...
- mov.l 4f, r0 ! do_syscall_trace
- jsr @r0
- nop
- bra resume_userspace
- nop
-
- .align 2
-syscall_trace_entry:
- ! Yes it is traced.
- ! XXX setup arguments...
- mov.l 4f, r11 ! Call do_syscall_trace which notifies
- jsr @r11 ! superior (will chomp R[0-7])
- nop
- ! Reload R0-R4 from kernel stack, where the
- ! parent may have modified them using
- ! ptrace(POKEUSR). (Note that R0-R2 are
- ! used by the system call handler directly
- ! from the kernel stack anyway, so don't need
- ! to be reloaded here.) This allows the parent
- ! to rewrite system calls and args on the fly.
- mov.l @(OFF_R4,r15), r4 ! arg0
- mov.l @(OFF_R5,r15), r5
- mov.l @(OFF_R6,r15), r6
- mov.l @(OFF_R7,r15), r7 ! arg3
- mov.l @(OFF_R3,r15), r3 ! syscall_nr
- !
- mov.l 2f, r10 ! Number of syscalls
- cmp/hs r10, r3
- bf syscall_call
- mov #-ENOSYS, r0
- bra syscall_exit
- mov.l r0, @(OFF_R0,r15) ! Return value
-
-__restore_all:
- mov.l 1f, r0
- jmp @r0
- nop
-
- .align 2
-1: .long restore_all
-
- .align 2
-not_syscall_tra:
- bra debug_trap
- nop
-
- .align 2
-syscall_badsys: ! Bad syscall number
- mov #-ENOSYS, r0
- bra resume_userspace
- mov.l r0, @(OFF_R0,r15) ! Return value
-
-
-/*
- * Syscall interface:
- *
- * Syscall #: R3
- * Arguments #0 to #3: R4--R7
- * Arguments #4 to #6: R0, R1, R2
- * TRA: (number of arguments + 0x10) x 4
- *
- * This code also handles delegating other traps to the BIOS/gdb stub
- * according to:
- *
- * Trap number
- * (TRA>>2) Purpose
- * -------- -------
- * 0x0-0xf old syscall ABI
- * 0x10-0x1f new syscall ABI
- * 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
- *
- * Note: When we're first called, the TRA value must be shifted
- * right 2 bits in order to get the value that was used as the "trapa"
- * argument.
- */
-
- .align 2
- .globl ret_from_fork
-ret_from_fork:
- mov.l 1f, r8
- jsr @r8
- mov r0, r4
- bra syscall_exit
- nop
- .align 2
-1: .long schedule_tail
- !
-ENTRY(system_call)
-#if !defined(CONFIG_CPU_SH2)
- mov.l 1f, r9
- mov.l @r9, r8 ! Read from TRA (Trap Address) Register
-#endif
- !
- ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
- mov #0x7f, r9
- cmp/hi r9, r8
- bt/s not_syscall_tra
- mov #OFF_TRA, r9
- add r15, r9
- mov.l r8, @r9 ! set TRA value to tra
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 5f, r10
- jsr @r10
- nop
-#endif
- sti
-
- !
- get_current_thread_info r8, r10
- mov.l @(TI_FLAGS,r8), r8
- mov #_TIF_SYSCALL_TRACE, r10
- tst r10, r8
- bf syscall_trace_entry
- !
- mov.l 2f, r8 ! Number of syscalls
- cmp/hs r8, r3
- bt syscall_badsys
- !
-syscall_call:
- shll2 r3 ! x4
- mov.l 3f, r8 ! Load the address of sys_call_table
- add r8, r3
- mov.l @r3, r8
- jsr @r8 ! jump to specific syscall handler
- nop
- mov.l @(OFF_R0,r15), r12 ! save r0
- mov.l r0, @(OFF_R0,r15) ! save the return value
- !
-syscall_exit:
- cli
-#ifdef CONFIG_TRACE_IRQFLAGS
- mov.l 6f, r0
- jsr @r0
- nop
-#endif
- !
- get_current_thread_info r8, r0
- mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
- tst #_TIF_ALLWORK_MASK, r0
- bf syscall_exit_work
- bra __restore_all
- nop
- .align 2
-#if !defined(CONFIG_CPU_SH2)
-1: .long TRA
-#endif
-2: .long NR_syscalls
-3: .long sys_call_table
-4: .long do_syscall_trace
-#ifdef CONFIG_TRACE_IRQFLAGS
-5: .long trace_hardirqs_on
-6: .long trace_hardirqs_off
-#endif
diff --git a/trunk/arch/sh/kernel/cpu/sh3/entry.S b/trunk/arch/sh/kernel/entry.S
similarity index 58%
rename from trunk/arch/sh/kernel/cpu/sh3/entry.S
rename to trunk/arch/sh/kernel/entry.S
index 8c0dc2700c69..39aaefb2d83f 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/entry.S
+++ b/trunk/arch/sh/kernel/entry.S
@@ -1,5 +1,5 @@
/*
- * arch/sh/kernel/entry.S
+ * linux/arch/sh/entry.S
*
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka
* Copyright (C) 2003 - 2006 Paul Mundt
@@ -7,16 +7,15 @@
* 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
#include
#include
#include
#include
-#include
#include
-#include
-#include
+#include
! NOTE:
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -82,8 +81,6 @@ OFF_TRA = (16*4+6*4)
#define k_g_imask r6_bank /* r6_bank1 */
#define current r7 /* r7_bank1 */
-#include
-
/*
* Kernel mode register usage:
* k0 scratch
@@ -110,6 +107,26 @@ OFF_TRA = (16*4+6*4)
! this first version depends *much* on C implementation.
!
+#define CLI() \
+ stc sr, r0; \
+ or #0xf0, r0; \
+ ldc r0, sr
+
+#define STI() \
+ mov.l __INV_IMASK, r11; \
+ stc sr, r10; \
+ and r11, r10; \
+ stc k_g_imask, r11; \
+ or r11, r10; \
+ ldc r10, sr
+
+#if defined(CONFIG_PREEMPT)
+# define preempt_stop() CLI()
+#else
+# define preempt_stop()
+# define resume_kernel restore_all
+#endif
+
#if defined(CONFIG_MMU)
.align 2
ENTRY(tlb_miss_load)
@@ -138,14 +155,29 @@ ENTRY(tlb_protection_violation_store)
call_dpf:
mov.l 1f, r0
- mov.l @r0, r6 ! address
+ mov r5, r8
+ mov.l @r0, r6
+ mov r6, r9
+ mov.l 2f, r0
+ sts pr, r10
+ jsr @r0
+ mov r15, r4
+ !
+ tst r0, r0
+ bf/s 0f
+ lds r10, pr
+ rts
+ nop
+0: STI()
mov.l 3f, r0
-
+ mov r9, r6
+ mov r8, r5
jmp @r0
- mov r15, r4 ! regs
+ mov r15, r4
.align 2
1: .long MMU_TEA
+2: .long __do_page_fault
3: .long do_page_fault
.align 2
@@ -171,6 +203,32 @@ call_dae:
2: .long do_address_error
#endif /* CONFIG_MMU */
+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
+! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
+! If both are configured, handle the debug traps (breakpoints) in SW,
+! but still allow BIOS traps to FW.
+
+ .align 2
+debug_kernel:
+#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
+ /* Force BIOS call to FW (debug_trap put TRA in r8) */
+ mov r8,r0
+ shlr2 r0
+ cmp/eq #0x3f,r0
+ bt debug_kernel_fw
+#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
+
+debug_enter:
+#if defined(CONFIG_SH_KGDB)
+ /* Jump to kgdb, pass stacked regs as arg */
+debug_kernel_sw:
+ mov.l 3f, r0
+ jmp @r0
+ mov r15, r4
+ .align 2
+3: .long kgdb_handle_exception
+#endif /* CONFIG_SH_KGDB */
+
#if defined(CONFIG_SH_STANDARD_BIOS)
/* Unwind the stack and jmp to the debug entry */
debug_kernel_fw:
@@ -211,6 +269,276 @@ debug_kernel_fw:
2: .long gdb_vbr_vector
#endif /* CONFIG_SH_STANDARD_BIOS */
+#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
+
+
+ .align 2
+debug_trap:
+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ shll r0
+ shll r0 ! kernel space?
+ bt/s debug_kernel
+#endif
+ mov.l @r15, r0 ! Restore R0 value
+ mov.l 1f, r8
+ jmp @r8
+ nop
+
+ .align 2
+ENTRY(exception_error)
+ !
+ STI()
+ mov.l 2f, r0
+ jmp @r0
+ nop
+
+!
+ .align 2
+1: .long break_point_trap_software
+2: .long do_exception_error
+
+ .align 2
+ret_from_exception:
+ preempt_stop()
+ENTRY(ret_from_irq)
+ !
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ shll r0
+ shll r0 ! kernel space?
+ bt/s resume_kernel ! Yes, it's from kernel, go back soon
+ GET_THREAD_INFO(r8)
+
+#ifdef CONFIG_PREEMPT
+ bra resume_userspace
+ nop
+ENTRY(resume_kernel)
+ mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count
+ tst r0, r0
+ bf noresched
+need_resched:
+ mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
+ tst #_TIF_NEED_RESCHED, r0 ! need_resched set?
+ bt noresched
+
+ mov #OFF_SR, r0
+ mov.l @(r0,r15), r0 ! get status register
+ and #0xf0, r0 ! interrupts off (exception path)?
+ cmp/eq #0xf0, r0
+ bt noresched
+
+ mov.l 1f, r0
+ mov.l r0, @(TI_PRE_COUNT,r8)
+
+ STI()
+ mov.l 2f, r0
+ jsr @r0
+ nop
+ mov #0, r0
+ mov.l r0, @(TI_PRE_COUNT,r8)
+ CLI()
+
+ bra need_resched
+ nop
+noresched:
+ bra restore_all
+ nop
+
+ .align 2
+1: .long PREEMPT_ACTIVE
+2: .long schedule
+#endif
+
+ENTRY(resume_userspace)
+ ! r8: current_thread_info
+ CLI()
+ mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
+ tst #_TIF_WORK_MASK, r0
+ bt/s restore_all
+ tst #_TIF_NEED_RESCHED, r0
+
+ .align 2
+work_pending:
+ ! r0: current_thread_info->flags
+ ! r8: current_thread_info
+ ! t: result of "tst #_TIF_NEED_RESCHED, r0"
+ bf/s work_resched
+ tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
+work_notifysig:
+ bt/s restore_all
+ mov r15, r4
+ mov r12, r5 ! set arg1(save_r0)
+ mov r0, r6
+ mov.l 2f, r1
+ mova restore_all, r0
+ jmp @r1
+ lds r0, pr
+work_resched:
+#ifndef CONFIG_PREEMPT
+ ! gUSA handling
+ mov.l @(OFF_SP,r15), r0 ! get user space stack pointer
+ mov r0, r1
+ shll r0
+ bf/s 1f
+ shll r0
+ bf/s 1f
+ mov #OFF_PC, r0
+ ! SP >= 0xc0000000 : gUSA mark
+ mov.l @(r0,r15), r2 ! get user space PC (program counter)
+ mov.l @(OFF_R0,r15), r3 ! end point
+ cmp/hs r3, r2 ! r2 >= r3?
+ bt 1f
+ add r3, r1 ! rewind point #2
+ mov.l r1, @(r0,r15) ! reset PC to rewind point #2
+ !
+1:
+#endif
+ mov.l 1f, r1
+ jsr @r1 ! schedule
+ nop
+ CLI()
+ !
+ mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
+ tst #_TIF_WORK_MASK, r0
+ bt restore_all
+ bra work_pending
+ tst #_TIF_NEED_RESCHED, r0
+
+ .align 2
+1: .long schedule
+2: .long do_notify_resume
+
+ .align 2
+syscall_exit_work:
+ ! r0: current_thread_info->flags
+ ! r8: current_thread_info
+ tst #_TIF_SYSCALL_TRACE, r0
+ bt/s work_pending
+ tst #_TIF_NEED_RESCHED, r0
+ STI()
+ ! XXX setup arguments...
+ mov.l 4f, r0 ! do_syscall_trace
+ jsr @r0
+ nop
+ bra resume_userspace
+ nop
+
+ .align 2
+syscall_trace_entry:
+ ! Yes it is traced.
+ ! XXX setup arguments...
+ mov.l 4f, r11 ! Call do_syscall_trace which notifies
+ jsr @r11 ! superior (will chomp R[0-7])
+ nop
+ ! Reload R0-R4 from kernel stack, where the
+ ! parent may have modified them using
+ ! ptrace(POKEUSR). (Note that R0-R2 are
+ ! used by the system call handler directly
+ ! from the kernel stack anyway, so don't need
+ ! to be reloaded here.) This allows the parent
+ ! to rewrite system calls and args on the fly.
+ mov.l @(OFF_R4,r15), r4 ! arg0
+ mov.l @(OFF_R5,r15), r5
+ mov.l @(OFF_R6,r15), r6
+ mov.l @(OFF_R7,r15), r7 ! arg3
+ mov.l @(OFF_R3,r15), r3 ! syscall_nr
+ ! Arrange for do_syscall_trace to be called
+ ! again as the system call returns.
+ mov.l 2f, r10 ! Number of syscalls
+ cmp/hs r10, r3
+ bf syscall_call
+ mov #-ENOSYS, r0
+ bra syscall_exit
+ mov.l r0, @(OFF_R0,r15) ! Return value
+
+/*
+ * Syscall interface:
+ *
+ * Syscall #: R3
+ * Arguments #0 to #3: R4--R7
+ * Arguments #4 to #6: R0, R1, R2
+ * TRA: (number of arguments + 0x10) x 4
+ *
+ * This code also handles delegating other traps to the BIOS/gdb stub
+ * according to:
+ *
+ * Trap number
+ * (TRA>>2) Purpose
+ * -------- -------
+ * 0x0-0xf old syscall ABI
+ * 0x10-0x1f new syscall ABI
+ * 0x20-0xff delegated through debug_trap to BIOS/gdb stub.
+ *
+ * Note: When we're first called, the TRA value must be shifted
+ * right 2 bits in order to get the value that was used as the "trapa"
+ * argument.
+ */
+
+ .align 2
+ .globl ret_from_fork
+ret_from_fork:
+ mov.l 1f, r8
+ jsr @r8
+ mov r0, r4
+ bra syscall_exit
+ nop
+ .align 2
+1: .long schedule_tail
+ !
+ENTRY(system_call)
+ mov.l 1f, r9
+ mov.l @r9, r8 ! Read from TRA (Trap Address) Register
+ !
+ ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
+ mov #0x7f, r9
+ cmp/hi r9, r8
+ bt/s 0f
+ mov #OFF_TRA, r9
+ add r15, r9
+ !
+ mov.l r8, @r9 ! set TRA value to tra
+ STI()
+ ! Call the system call handler through the table.
+ ! First check for bad syscall number
+ mov r3, r9
+ mov.l 2f, r8 ! Number of syscalls
+ cmp/hs r8, r9
+ bf/s good_system_call
+ GET_THREAD_INFO(r8)
+syscall_badsys: ! Bad syscall number
+ mov #-ENOSYS, r0
+ bra resume_userspace
+ mov.l r0, @(OFF_R0,r15) ! Return value
+ !
+0:
+ bra debug_trap
+ nop
+ !
+good_system_call: ! Good syscall number
+ mov.l @(TI_FLAGS,r8), r8
+ mov #_TIF_SYSCALL_TRACE, r10
+ tst r10, r8
+ bf syscall_trace_entry
+ !
+syscall_call:
+ shll2 r9 ! x4
+ mov.l 3f, r8 ! Load the address of sys_call_table
+ add r8, r9
+ mov.l @r9, r8
+ jsr @r8 ! jump to specific syscall handler
+ nop
+ mov.l @(OFF_R0,r15), r12 ! save r0
+ mov.l r0, @(OFF_R0,r15) ! save the return value
+ !
+syscall_exit:
+ CLI()
+ !
+ GET_THREAD_INFO(r8)
+ mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
+ tst #_TIF_ALLWORK_MASK, r0
+ bf syscall_exit_work
restore_all:
mov.l @r15+, r0
mov.l @r15+, r1
@@ -278,9 +606,7 @@ skip_restore:
!
! Calculate new SR value
mov k3, k2 ! original SR value
- mov #0xf0, k1
- extu.b k1, k1
- not k1, k1
+ mov.l 9f, k1
and k1, k2 ! Mask orignal SR value
!
mov k3, k0 ! Calculate IMASK-bits
@@ -306,12 +632,16 @@ skip_restore:
nop
.align 2
+1: .long TRA
+2: .long NR_syscalls
+3: .long sys_call_table
+4: .long do_syscall_trace
5: .long 0x00001000 ! DSP
7: .long 0x30000000
+9:
+__INV_IMASK:
+ .long 0xffffff0f ! ~(IMASK)
-! common exception handler
-#include "../../entry-common.S"
-
! Exception Vector Base
!
! Should be aligned page boundary.
@@ -331,176 +661,9 @@ general_exception:
2: .long ret_from_exception
!
!
-
-/* This code makes some assumptions to improve performance.
- * Make sure they are stil true. */
-#if PTRS_PER_PGD != PTRS_PER_PTE
-#error PGD and PTE sizes don't match
-#endif
-
-/* gas doesn't flag impossible values for mov #immediate as an error */
-#if (_PAGE_PRESENT >> 2) > 0x7f
-#error cannot load PAGE_PRESENT as an immediate
-#endif
-#if _PAGE_DIRTY > 0x7f
-#error cannot load PAGE_DIRTY as an immediate
-#endif
-#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED
-#error cannot derive PAGE_ACCESSED from PAGE_PRESENT
-#endif
-
-#if defined(CONFIG_CPU_SH4)
-#define ldmmupteh(r) mov.l 8f, r
-#else
-#define ldmmupteh(r) mov #MMU_PTEH, r
-#endif
-
.balign 1024,0,1024
tlb_miss:
-#ifdef COUNT_EXCEPTIONS
- ! Increment the counts
- mov.l 9f, k1
- mov.l @k1, k2
- add #1, k2
- mov.l k2, @k1
-#endif
-
- ! k0 scratch
- ! k1 pgd and pte pointers
- ! k2 faulting address
- ! k3 pgd and pte index masks
- ! k4 shift
-
- ! Load up the pgd entry (k1)
-
- ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH
-
- mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2
- mov #-(PGDIR_SHIFT-2), k4 ! 6 EX
-
- mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2)
-
- mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2)
-
- mov k2, k0 ! 5 MT (latency=0)
- shld k4, k0 ! 99 EX
-
- and k3, k0 ! 78 EX
-
- mov.l @(k0, k1), k1 ! 21 LS (latency=2)
- mov #-(PAGE_SHIFT-2), k4 ! 6 EX
-
- ! Load up the pte entry (k2)
-
- mov k2, k0 ! 5 MT (latency=0)
- shld k4, k0 ! 99 EX
-
- tst k1, k1 ! 86 MT
-
- bt 20f ! 110 BR
-
- and k3, k0 ! 78 EX
- mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT
-
- mov.l @(k0, k1), k2 ! 21 LS (latency=2)
- add k0, k1 ! 49 EX
-
-#ifdef CONFIG_CPU_HAS_PTEA
- ! Test the entry for present and _PAGE_ACCESSED
-
- mov #-28, k3 ! 6 EX
- mov k2, k0 ! 5 MT (latency=0)
-
- tst k4, k2 ! 68 MT
- shld k3, k0 ! 99 EX
-
- bt 20f ! 110 BR
-
- ! Set PTEA register
- ! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1)
- !
- ! k0=pte>>28, k1=pte*, k2=pte, k3=, k4=_PAGE_PRESENT
-
- and #0xe, k0 ! 79 EX
-
- mov k0, k3 ! 5 MT (latency=0)
- mov k2, k0 ! 5 MT (latency=0)
-
- and #1, k0 ! 79 EX
-
- or k0, k3 ! 82 EX
-
- ldmmupteh(k0) ! 9 LS (latency=2)
- shll2 k4 ! 101 EX _PAGE_ACCESSED
-
- tst k4, k2 ! 68 MT
-
- mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS
-
- mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
-
- ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
-#else
-
- ! Test the entry for present and _PAGE_ACCESSED
-
- mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK
- tst k4, k2 ! 68 MT
-
- shll2 k4 ! 101 EX _PAGE_ACCESSED
- ldmmupteh(k0) ! 9 LS (latency=2)
-
- bt 20f ! 110 BR
- tst k4, k2 ! 68 MT
-
- ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED
-
-#endif
-
- ! Set up the entry
-
- and k2, k3 ! 78 EX
- bt/s 10f ! 108 BR
-
- mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS
-
- ldtlb ! 128 CO
-
- ! At least one instruction between ldtlb and rte
- nop ! 119 NOP
-
- rte ! 126 CO
-
- nop ! 119 NOP
-
-
-10: or k4, k2 ! 82 EX
-
- ldtlb ! 128 CO
-
- ! At least one instruction between ldtlb and rte
- mov.l k2, @k1 ! 27 LS
-
- rte ! 126 CO
-
- ! Note we cannot execute mov here, because it is executed after
- ! restoring SSR, so would be executed in user space.
- nop ! 119 NOP
-
-
- .align 5
- ! Once cache line if possible...
-1: .long swapper_pg_dir
-4: .short (PTRS_PER_PGD-1) << 2
-5: .short _PAGE_PRESENT
-7: .long _PAGE_FLAGS_HARDWARE_MASK
-8: .long MMU_PTEH
-#ifdef COUNT_EXCEPTIONS
-9: .long exception_count_miss
-#endif
-
- ! Either pgd or pte not present
-20: mov.l 1f, k2
+ mov.l 1f, k2
mov.l 4f, k3
bra handle_exception
mov.l @k2, k2
@@ -547,9 +710,8 @@ ENTRY(handle_exception)
bt/s 1f ! It's a kernel to kernel transition.
mov r15, k0 ! save original stack to k0
/* User space to kernel */
- mov #(THREAD_SIZE >> 10), k1
+ mov #(THREAD_SIZE >> 8), k1
shll8 k1 ! k1 := THREAD_SIZE
- shll2 k1
add current, k1
mov k1, r15 ! change to kernel stack
!
@@ -599,7 +761,7 @@ skip_save:
! Save the user registers on the stack.
mov.l k2, @-r15 ! EXPEVT
- mov #-1, k4
+ mov #-1, k4
mov.l k4, @-r15 ! set TRA (default: -1)
!
sts.l macl, @-r15
@@ -651,15 +813,6 @@ skip_save:
bf interrupt_exception
shlr2 r8
shlr r8
-
-#ifdef COUNT_EXCEPTIONS
- mov.l 5f, r9
- add r8, r9
- mov.l @r9, r10
- add #1, r10
- mov.l r10, @r9
-#endif
-
mov.l 4f, r9
add r8, r9
mov.l @r9, r9
@@ -673,9 +826,6 @@ skip_save:
2: .long 0x000080f0 ! FD=1, IMASK=15
3: .long 0xcfffffff ! RB=0, BL=0
4: .long exception_handling_table
-#ifdef COUNT_EXCEPTIONS
-5: .long exception_count_table
-#endif
interrupt_exception:
mov.l 1f, r9
diff --git a/trunk/arch/sh/kernel/head.S b/trunk/arch/sh/kernel/head.S
index 6aca4bc6ec5d..f5f53d14f245 100644
--- a/trunk/arch/sh/kernel/head.S
+++ b/trunk/arch/sh/kernel/head.S
@@ -33,7 +33,7 @@ ENTRY(empty_zero_page)
.long 0x00360000 /* INITRD_START */
.long 0x000a0000 /* INITRD_SIZE */
.long 0
- .balign PAGE_SIZE,0,PAGE_SIZE
+ .balign 4096,0,4096
.text
/*
@@ -53,10 +53,8 @@ ENTRY(_stext)
ldc r0, sr
! Initialize global interrupt mask
mov #0, r0
-#ifdef CONFIG_CPU_HAS_SR_RB
ldc r0, r6_bank
-#endif
-
+
/*
* Prefetch if possible to reduce cache miss penalty.
*
@@ -70,14 +68,11 @@ ENTRY(_stext)
!
mov.l 2f, r0
mov r0, r15 ! Set initial r15 (stack pointer)
- mov #(THREAD_SIZE >> 10), r1
+ mov #(THREAD_SIZE >> 8), r1
shll8 r1 ! r1 = THREAD_SIZE
- shll2 r1
sub r1, r0 !
-#ifdef CONFIG_CPU_HAS_SR_RB
ldc r0, r7_bank ! ... and initial thread_info
-#endif
-
+
! Clear BSS area
mov.l 3f, r1
add #4, r1
@@ -100,11 +95,7 @@ ENTRY(_stext)
nop
.balign 4
-#if defined(CONFIG_CPU_SH2)
-1: .long 0x000000F0 ! IMASK=0xF
-#else
1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
-#endif
2: .long init_thread_union+THREAD_SIZE
3: .long __bss_start
4: .long _end
diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c
index 67be2b6e8cd1..944128ce9706 100644
--- a/trunk/arch/sh/kernel/irq.c
+++ b/trunk/arch/sh/kernel/irq.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -78,16 +78,15 @@ union irq_ctx {
u32 stack[THREAD_SIZE/sizeof(u32)];
};
-static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
-static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
+static union irq_ctx *hardirq_ctx[NR_CPUS];
+static union irq_ctx *softirq_ctx[NR_CPUS];
#endif
asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
- struct pt_regs *old_regs = set_irq_regs(regs);
+ struct pt_regs *old_regs = set_irq_regs(®s);
int irq;
#ifdef CONFIG_4KSTACKS
union irq_ctx *curctx, *irqctx;
@@ -112,7 +111,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
#endif
#ifdef CONFIG_CPU_HAS_INTEVT
- irq = evt2irq(ctrl_inl(INTEVT));
+ irq = (ctrl_inl(INTEVT) >> 5) - 16;
#else
irq = r4;
#endif
@@ -136,24 +135,17 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
irqctx->tinfo.task = curctx->tinfo.task;
irqctx->tinfo.previous_sp = current_stack_pointer;
- /*
- * Copy the softirq bits in preempt_count so that the
- * softirq checks work in the hardirq context.
- */
- irqctx->tinfo.preempt_count =
- (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
- (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
-
__asm__ __volatile__ (
"mov %0, r4 \n"
- "mov r15, r8 \n"
+ "mov r15, r9 \n"
"jsr @%1 \n"
/* swith to the irq stack */
" mov %2, r15 \n"
/* restore the stack (ring zero) */
- "mov r8, r15 \n"
+ "mov r9, r15 \n"
: /* no outputs */
: "r" (irq), "r" (generic_handle_irq), "r" (isp)
+ /* XXX: A somewhat excessive clobber list? -PFM */
: "memory", "r0", "r1", "r2", "r3", "r4",
"r5", "r6", "r7", "r8", "t", "pr"
);
@@ -201,7 +193,7 @@ void irq_ctx_init(int cpu)
irqctx->tinfo.task = NULL;
irqctx->tinfo.exec_domain = NULL;
irqctx->tinfo.cpu = cpu;
- irqctx->tinfo.preempt_count = 0;
+ irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET;
irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
softirq_ctx[cpu] = irqctx;
@@ -247,38 +239,13 @@ asmlinkage void do_softirq(void)
"mov r9, r15 \n"
: /* no outputs */
: "r" (__do_softirq), "r" (isp)
+ /* XXX: A somewhat excessive clobber list? -PFM */
: "memory", "r0", "r1", "r2", "r3", "r4",
"r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
);
-
- /*
- * Shouldnt happen, we returned above if in_interrupt():
- */
- WARN_ON_ONCE(softirq_count());
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(do_softirq);
#endif
-
-void __init init_IRQ(void)
-{
-#ifdef CONFIG_CPU_HAS_PINT_IRQ
- init_IRQ_pint();
-#endif
-
-#ifdef CONFIG_CPU_HAS_INTC2_IRQ
- init_IRQ_intc2();
-#endif
-
-#ifdef CONFIG_CPU_HAS_IPR_IRQ
- init_IRQ_ipr();
-#endif
-
- /* Perform the machine specific initialisation */
- if (sh_mv.mv_init_irq)
- sh_mv.mv_init_irq();
-
- irq_ctx_init(smp_processor_id());
-}
diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c
index f3e2631be144..a52b13ac6b7f 100644
--- a/trunk/arch/sh/kernel/process.c
+++ b/trunk/arch/sh/kernel/process.c
@@ -385,11 +385,10 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
#ifdef CONFIG_MMU
- return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL);
+ return do_fork(SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL);
#else
/* fork almost works, enough to trick you into looking elsewhere :-( */
return -EINVAL;
@@ -399,12 +398,11 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
unsigned long parent_tidptr,
unsigned long child_tidptr,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
if (!newsp)
- newsp = regs->regs[15];
- return do_fork(clone_flags, newsp, regs, 0,
+ newsp = regs.regs[15];
+ return do_fork(clone_flags, newsp, ®s, 0,
(int __user *)parent_tidptr, (int __user *)child_tidptr);
}
@@ -420,10 +418,9 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
*/
asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs,
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s,
0, NULL, NULL);
}
@@ -432,9 +429,8 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
*/
asmlinkage int sys_execve(char *ufilename, char **uargv,
char **uenvp, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int error;
char *filename;
@@ -446,7 +442,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
error = do_execve(filename,
(char __user * __user *)uargv,
(char __user * __user *)uenvp,
- regs);
+ ®s);
if (error == 0) {
task_lock(current);
current->ptrace &= ~PT_DTRACE;
@@ -476,7 +472,9 @@ unsigned long get_wchan(struct task_struct *p)
return pc;
}
-asmlinkage void break_point_trap(void)
+asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs regs)
{
/* Clear tracing. */
#if defined(CONFIG_CPU_SH4A)
@@ -494,10 +492,8 @@ asmlinkage void break_point_trap(void)
asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
-
- regs->pc -= 2;
+ regs.pc -= 2;
force_sig(SIGTRAP, current);
}
diff --git a/trunk/arch/sh/kernel/relocate_kernel.S b/trunk/arch/sh/kernel/relocate_kernel.S
index c66cb3209db5..8221b37c9773 100644
--- a/trunk/arch/sh/kernel/relocate_kernel.S
+++ b/trunk/arch/sh/kernel/relocate_kernel.S
@@ -7,9 +7,11 @@
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
+
#include
-#include
-#include
+
+#define PAGE_SIZE 4096 /* must be same value as in */
+
.globl relocate_new_kernel
relocate_new_kernel:
@@ -18,8 +20,8 @@ relocate_new_kernel:
/* r6 = start_address */
/* r7 = vbr_reg */
- mov.l 10f,r8 /* PAGE_SIZE */
- mov.l 11f,r9 /* P2SEG */
+ mov.l 10f,r8 /* 4096 */
+ mov.l 11f,r9 /* 0xa0000000 */
/* stack setting */
add r8,r5
@@ -30,7 +32,7 @@ relocate_new_kernel:
0:
mov.l @r4+,r0 /* cmd = *ind++ */
-1: /* addr = (cmd | P2SEG) & 0xfffffff0 */
+1: /* addr = (cmd | 0xa0000000) & 0xfffffff0 */
mov r0,r2
or r9,r2
mov #-16,r1
@@ -90,7 +92,7 @@ relocate_new_kernel:
10:
.long PAGE_SIZE
11:
- .long P2SEG
+ .long 0xa0000000
relocate_new_kernel_end:
diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c
index 696ca75752d9..36d86f9ac38a 100644
--- a/trunk/arch/sh/kernel/setup.c
+++ b/trunk/arch/sh/kernel/setup.c
@@ -392,7 +392,6 @@ static int __init topology_init(void)
subsys_initcall(topology_init);
static const char *cpu_name[] = {
- [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
[CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300",
[CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
[CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
@@ -405,7 +404,6 @@ static const char *cpu_name[] = {
[CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
[CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780",
[CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343",
- [CPU_SH7785] = "SH7785",
[CPU_SH_NONE] = "Unknown"
};
diff --git a/trunk/arch/sh/kernel/sh_ksyms.c b/trunk/arch/sh/kernel/sh_ksyms.c
index c706f3bfd897..8a2fd19dc9eb 100644
--- a/trunk/arch/sh/kernel/sh_ksyms.c
+++ b/trunk/arch/sh/kernel/sh_ksyms.c
@@ -73,6 +73,8 @@ DECLARE_EXPORT(__lshrdi3);
DECLARE_EXPORT(__movstr);
DECLARE_EXPORT(__movstrSI16);
+EXPORT_SYMBOL(strcpy);
+
#ifdef CONFIG_CPU_SH4
DECLARE_EXPORT(__movstr_i4_even);
DECLARE_EXPORT(__movstr_i4_odd);
diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c
index 50d7c4993bef..5213f5bc6ce0 100644
--- a/trunk/arch/sh/kernel/signal.c
+++ b/trunk/arch/sh/kernel/signal.c
@@ -37,7 +37,7 @@
asmlinkage int
sys_sigsuspend(old_sigset_t mask,
unsigned long r5, unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
mask &= _BLOCKABLE;
spin_lock_irq(¤t->sighand->siglock);
@@ -52,7 +52,7 @@ sys_sigsuspend(old_sigset_t mask,
return -ERESTARTNOHAND;
}
-asmlinkage int
+asmlinkage int
sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
@@ -87,11 +87,9 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
-
- return do_sigaltstack(uss, uoss, regs->regs[15]);
+ return do_sigaltstack(uss, uoss, regs.regs[15]);
}
@@ -100,11 +98,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
*/
#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
-#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A)
-#define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */
-#else
-#define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */
-#endif
+#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */
#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
struct sigframe
@@ -200,10 +194,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
- struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15];
+ struct sigframe __user *frame = (struct sigframe __user *)regs.regs[15];
sigset_t set;
int r0;
@@ -223,7 +216,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- if (restore_sigcontext(regs, &frame->sc, &r0))
+ if (restore_sigcontext(®s, &frame->sc, &r0))
goto badframe;
return r0;
@@ -234,10 +227,9 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
- struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15];
+ struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs.regs[15];
sigset_t set;
stack_t st;
int r0;
@@ -254,14 +246,14 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &r0))
goto badframe;
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
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(&st, NULL, regs.regs[15]);
return r0;
@@ -358,7 +350,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
} else {
/* Generate return code (system call to sigreturn) */
err |= __put_user(MOVW(7), &frame->retcode[0]);
- err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
+ err |= __put_user(TRAP16, &frame->retcode[1]);
err |= __put_user(OR_R0_R0, &frame->retcode[2]);
err |= __put_user(OR_R0_R0, &frame->retcode[3]);
err |= __put_user(OR_R0_R0, &frame->retcode[4]);
@@ -438,7 +430,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
} else {
/* Generate return code (system call to rt_sigreturn) */
err |= __put_user(MOVW(7), &frame->retcode[0]);
- err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
+ err |= __put_user(TRAP16, &frame->retcode[1]);
err |= __put_user(OR_R0_R0, &frame->retcode[2]);
err |= __put_user(OR_R0_R0, &frame->retcode[3]);
err |= __put_user(OR_R0_R0, &frame->retcode[4]);
diff --git a/trunk/arch/sh/kernel/stacktrace.c b/trunk/arch/sh/kernel/stacktrace.c
deleted file mode 100644
index 0d5268afe80f..000000000000
--- a/trunk/arch/sh/kernel/stacktrace.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * arch/sh/kernel/stacktrace.c
- *
- * Stack trace management functions
- *
- * 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
-#include
-#include
-#include
-
-/*
- * Save stack-backtrace addresses into a stack_trace buffer.
- */
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
-{
- unsigned long *sp;
-
- if (!task)
- task = current;
- if (task == current)
- sp = (unsigned long *)current_stack_pointer;
- else
- sp = (unsigned long *)task->thread.sp;
-
- while (!kstack_end(sp)) {
- unsigned long addr = *sp++;
-
- if (__kernel_text_address(addr)) {
- if (trace->skip > 0)
- trace->skip--;
- else
- trace->entries[trace->nr_entries++] = addr;
- if (trace->nr_entries >= trace->max_entries)
- break;
- }
- }
-}
diff --git a/trunk/arch/sh/kernel/sys_sh.c b/trunk/arch/sh/kernel/sys_sh.c
index 5083b6ed4b39..8fde95001c34 100644
--- a/trunk/arch/sh/kernel/sys_sh.c
+++ b/trunk/arch/sh/kernel/sys_sh.c
@@ -33,15 +33,14 @@
*/
asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int fd[2];
int error;
error = do_pipe(fd);
if (!error) {
- regs->regs[1] = fd[1];
+ regs.regs[1] = fd[1];
return fd[0];
}
return error;
@@ -51,7 +50,6 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
EXPORT_SYMBOL(shm_align_mask);
-#ifdef CONFIG_MMU
/*
* To avoid cache aliases, we map the shared page with same color.
*/
@@ -137,7 +135,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
addr = COLOUR_ALIGN(addr, pgoff);
}
}
-#endif /* CONFIG_MMU */
static inline long
do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
diff --git a/trunk/arch/sh/kernel/time.c b/trunk/arch/sh/kernel/time.c
index c206c9504c4b..57e708d7b52d 100644
--- a/trunk/arch/sh/kernel/time.c
+++ b/trunk/arch/sh/kernel/time.c
@@ -13,8 +13,6 @@
#include
#include
#include
-#include
-#include
#include
#include
#include
@@ -52,20 +50,15 @@ unsigned long long __attribute__ ((weak)) sched_clock(void)
#ifndef CONFIG_GENERIC_TIME
void do_gettimeofday(struct timeval *tv)
{
- unsigned long flags;
unsigned long seq;
unsigned long usec, sec;
do {
- /*
- * Turn off IRQs when grabbing xtime_lock, so that
- * the sys_timer get_offset code doesn't have to handle it.
- */
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ seq = read_seqbegin(&xtime_lock);
usec = get_timer_offset();
sec = xtime.tv_sec;
- usec += xtime.tv_nsec / NSEC_PER_USEC;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+ usec += xtime.tv_nsec / 1000;
+ } while (read_seqretry(&xtime_lock, seq));
while (usec >= 1000000) {
usec -= 1000000;
@@ -92,7 +85,7 @@ int do_settimeofday(struct timespec *tv)
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
- nsec -= get_timer_offset() * NSEC_PER_USEC;
+ nsec -= 1000 * get_timer_offset();
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -176,108 +169,6 @@ static struct sysdev_class timer_sysclass = {
.resume = timer_resume,
};
-#ifdef CONFIG_NO_IDLE_HZ
-static int timer_dyn_tick_enable(void)
-{
- struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick;
- unsigned long flags;
- int ret = -ENODEV;
-
- if (dyn_tick) {
- spin_lock_irqsave(&dyn_tick->lock, flags);
- ret = 0;
- if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
- ret = dyn_tick->enable();
-
- if (ret == 0)
- dyn_tick->state |= DYN_TICK_ENABLED;
- }
- spin_unlock_irqrestore(&dyn_tick->lock, flags);
- }
-
- return ret;
-}
-
-static int timer_dyn_tick_disable(void)
-{
- struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick;
- unsigned long flags;
- int ret = -ENODEV;
-
- if (dyn_tick) {
- spin_lock_irqsave(&dyn_tick->lock, flags);
- ret = 0;
- if (dyn_tick->state & DYN_TICK_ENABLED) {
- ret = dyn_tick->disable();
-
- if (ret == 0)
- dyn_tick->state &= ~DYN_TICK_ENABLED;
- }
- spin_unlock_irqrestore(&dyn_tick->lock, flags);
- }
-
- return ret;
-}
-
-/*
- * Reprogram the system timer for at least the calculated time interval.
- * This function should be called from the idle thread with IRQs disabled,
- * immediately before sleeping.
- */
-void timer_dyn_reprogram(void)
-{
- struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick;
- unsigned long next, seq, flags;
-
- if (!dyn_tick)
- return;
-
- spin_lock_irqsave(&dyn_tick->lock, flags);
- if (dyn_tick->state & DYN_TICK_ENABLED) {
- next = next_timer_interrupt();
- do {
- seq = read_seqbegin(&xtime_lock);
- dyn_tick->reprogram(next - jiffies);
- } while (read_seqretry(&xtime_lock, seq));
- }
- spin_unlock_irqrestore(&dyn_tick->lock, flags);
-}
-
-static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
-{
- return sprintf(buf, "%i\n",
- (sys_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1);
-}
-
-static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf,
- size_t count)
-{
- unsigned int enable = simple_strtoul(buf, NULL, 2);
-
- if (enable)
- timer_dyn_tick_enable();
- else
- timer_dyn_tick_disable();
-
- return count;
-}
-static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick);
-
-/*
- * dyntick=enable|disable
- */
-static char dyntick_str[4] __initdata = "";
-
-static int __init dyntick_setup(char *str)
-{
- if (str)
- strlcpy(dyntick_str, str, sizeof(dyntick_str));
- return 1;
-}
-
-__setup("dyntick=", dyntick_setup);
-#endif
-
static int __init timer_init_sysfs(void)
{
int ret = sysdev_class_register(&timer_sysclass);
@@ -285,22 +176,7 @@ static int __init timer_init_sysfs(void)
return ret;
sys_timer->dev.cls = &timer_sysclass;
- ret = sysdev_register(&sys_timer->dev);
-
-#ifdef CONFIG_NO_IDLE_HZ
- if (ret == 0 && sys_timer->dyn_tick) {
- ret = sysdev_create_file(&sys_timer->dev, &attr_dyn_tick);
-
- /*
- * Turn on dynamic tick after calibrate delay
- * for correct bogomips
- */
- if (ret == 0 && dyntick_str[0] == 'e')
- ret = timer_dyn_tick_enable();
- }
-#endif
-
- return ret;
+ return sysdev_register(&sys_timer->dev);
}
device_initcall(timer_init_sysfs);
@@ -324,11 +200,6 @@ void __init time_init(void)
sys_timer = get_sys_timer();
printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
-#ifdef CONFIG_NO_IDLE_HZ
- if (sys_timer->dyn_tick)
- spin_lock_init(&sys_timer->dyn_tick->lock);
-#endif
-
#if defined(CONFIG_SH_KGDB)
/*
* Set up kgdb as requested. We do it here because the serial
diff --git a/trunk/arch/sh/kernel/timers/Makefile b/trunk/arch/sh/kernel/timers/Makefile
index bcf244ff6a12..151a6a304cec 100644
--- a/trunk/arch/sh/kernel/timers/Makefile
+++ b/trunk/arch/sh/kernel/timers/Makefile
@@ -5,6 +5,4 @@
obj-y := timer.o
obj-$(CONFIG_SH_TMU) += timer-tmu.o
-obj-$(CONFIG_SH_MTU2) += timer-mtu2.o
-obj-$(CONFIG_SH_CMT) += timer-cmt.o
diff --git a/trunk/arch/sh/kernel/timers/timer-cmt.c b/trunk/arch/sh/kernel/timers/timer-cmt.c
deleted file mode 100644
index a574b93a4e7b..000000000000
--- a/trunk/arch/sh/kernel/timers/timer-cmt.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support
- *
- * Copyright (C) 2005 Yoshinori Sato
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7619)
-#define CMT_CMSTR 0xf84a0070
-#define CMT_CMCSR_0 0xf84a0072
-#define CMT_CMCNT_0 0xf84a0074
-#define CMT_CMCOR_0 0xf84a0076
-#define CMT_CMCSR_1 0xf84a0078
-#define CMT_CMCNT_1 0xf84a007a
-#define CMT_CMCOR_1 0xf84a007c
-
-#define STBCR3 0xf80a0000
-#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0)
-#define CMT_CMCSR_INIT 0x0040
-#define CMT_CMCSR_CALIB 0x0000
-#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
-#define CMT_CMSTR 0xfffec000
-#define CMT_CMCSR_0 0xfffec002
-#define CMT_CMCNT_0 0xfffec004
-#define CMT_CMCOR_0 0xfffec006
-
-#define STBCR4 0xfffe040c
-#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0)
-#define CMT_CMCSR_INIT 0x0040
-#define CMT_CMCSR_CALIB 0x0000
-#else
-#error "Unknown CPU SUBTYPE"
-#endif
-
-static unsigned long cmt_timer_get_offset(void)
-{
- int count;
- static unsigned short count_p = 0xffff; /* for the first call after boot */
- static unsigned long jiffies_p = 0;
-
- /*
- * cache volatile jiffies temporarily; we have IRQs turned off.
- */
- unsigned long jiffies_t;
-
- /* timer count may underflow right here */
- count = ctrl_inw(CMT_CMCOR_0);
- count -= ctrl_inw(CMT_CMCNT_0);
-
- jiffies_t = jiffies;
-
- /*
- * avoiding timer inconsistencies (they are rare, but they happen)...
- * there is one kind of problem that must be avoided here:
- * 1. the timer counter underflows
- */
-
- if (jiffies_t == jiffies_p) {
- if (count > count_p) {
- /* the nutcase */
- if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */
- count -= LATCH;
- } else {
- printk("%s (): hardware timer problem?\n",
- __FUNCTION__);
- }
- }
- } else
- jiffies_p = jiffies_t;
-
- count_p = count;
-
- count = ((LATCH-1) - count) * TICK_SIZE;
- count = (count + LATCH/2) / LATCH;
-
- return count;
-}
-
-static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id)
-{
- unsigned long timer_status;
-
- /* Clear CMF bit */
- timer_status = ctrl_inw(CMT_CMCSR_0);
- timer_status &= ~0x80;
- ctrl_outw(timer_status, CMT_CMCSR_0);
-
- /*
- * Here we are in the timer irq handler. We just have irqs locally
- * disabled but we don't know if the timer_bh is running on the other
- * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
- * the irq version of write_lock because as just said we have irq
- * locally disabled. -arca
- */
- write_seqlock(&xtime_lock);
- handle_timer_tick();
- write_sequnlock(&xtime_lock);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction cmt_irq = {
- .name = "timer",
- .handler = cmt_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
-};
-
-static void cmt_clk_init(struct clk *clk)
-{
- u8 divisor = CMT_CMCSR_INIT & 0x3;
- ctrl_inw(CMT_CMCSR_0);
- ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0);
- clk->parent = clk_get(NULL, "module_clk");
- clk->rate = clk->parent->rate / (8 << (divisor << 1));
-}
-
-static void cmt_clk_recalc(struct clk *clk)
-{
- u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3;
- clk->rate = clk->parent->rate / (8 << (divisor << 1));
-}
-
-static struct clk_ops cmt_clk_ops = {
- .init = cmt_clk_init,
- .recalc = cmt_clk_recalc,
-};
-
-static struct clk cmt0_clk = {
- .name = "cmt0_clk",
- .ops = &cmt_clk_ops,
-};
-
-static int cmt_timer_start(void)
-{
- ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR);
- return 0;
-}
-
-static int cmt_timer_stop(void)
-{
- ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR);
- return 0;
-}
-
-static int cmt_timer_init(void)
-{
- unsigned long interval;
-
- cmt_clock_enable();
-
- setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq);
-
- cmt0_clk.parent = clk_get(NULL, "module_clk");
-
- cmt_timer_stop();
-
- interval = cmt0_clk.parent->rate / 8 / HZ;
- printk(KERN_INFO "Interval = %ld\n", interval);
-
- ctrl_outw(interval, CMT_CMCOR_0);
-
- clk_register(&cmt0_clk);
- clk_enable(&cmt0_clk);
-
- cmt_timer_start();
-
- return 0;
-}
-
-struct sys_timer_ops cmt_timer_ops = {
- .init = cmt_timer_init,
- .start = cmt_timer_start,
- .stop = cmt_timer_stop,
-#ifndef CONFIG_GENERIC_TIME
- .get_offset = cmt_timer_get_offset,
-#endif
-};
-
-struct sys_timer cmt_timer = {
- .name = "cmt",
- .ops = &cmt_timer_ops,
-};
diff --git a/trunk/arch/sh/kernel/timers/timer-mtu2.c b/trunk/arch/sh/kernel/timers/timer-mtu2.c
deleted file mode 100644
index fffcd1c09873..000000000000
--- a/trunk/arch/sh/kernel/timers/timer-mtu2.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * arch/sh/kernel/timers/timer-mtu2.c - MTU2 Timer Support
- *
- * Copyright (C) 2005 Paul Mundt
- *
- * Based off of arch/sh/kernel/timers/timer-tmu.c
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/*
- * We use channel 1 for our lowly system timer. Channel 2 would be the other
- * likely candidate, but we leave it alone as it has higher divisors that
- * would be of more use to other more interesting applications.
- *
- * TODO: Presently we only implement a 16-bit single-channel system timer.
- * However, we can implement channel cascade if we go the overflow route and
- * get away with using 2 MTU2 channels as a 32-bit timer.
- */
-#define MTU2_TSTR 0xfffe4280
-#define MTU2_TCR_1 0xfffe4380
-#define MTU2_TMDR_1 0xfffe4381
-#define MTU2_TIOR_1 0xfffe4382
-#define MTU2_TIER_1 0xfffe4384
-#define MTU2_TSR_1 0xfffe4385
-#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */
-#define MTU2_TGRA_1 0xfffe438a
-
-#define STBCR3 0xfffe0408
-
-#define MTU2_TSTR_CST1 (1 << 1) /* Counter Start 1 */
-
-#define MTU2_TSR_TGFA (1 << 0) /* GRA compare match */
-
-#define MTU2_TIER_TGIEA (1 << 0) /* GRA compare match interrupt enable */
-
-#define MTU2_TCR_INIT 0x22
-
-#define MTU2_TCR_CALIB 0x00
-
-static unsigned long mtu2_timer_get_offset(void)
-{
- int count;
- static int count_p = 0x7fff; /* for the first call after boot */
- static unsigned long jiffies_p = 0;
-
- /*
- * cache volatile jiffies temporarily; we have IRQs turned off.
- */
- unsigned long jiffies_t;
-
- /* timer count may underflow right here */
- count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */
-
- jiffies_t = jiffies;
-
- /*
- * avoiding timer inconsistencies (they are rare, but they happen)...
- * there is one kind of problem that must be avoided here:
- * 1. the timer counter underflows
- */
-
- if (jiffies_t == jiffies_p) {
- if (count > count_p) {
- if (ctrl_inb(MTU2_TSR_1) & MTU2_TSR_TGFA) {
- count -= LATCH;
- } else {
- printk("%s (): hardware timer problem?\n",
- __FUNCTION__);
- }
- }
- } else
- jiffies_p = jiffies_t;
-
- count_p = count;
-
- count = ((LATCH-1) - count) * TICK_SIZE;
- count = (count + LATCH/2) / LATCH;
-
- return count;
-}
-
-static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id)
-{
- unsigned long timer_status;
-
- /* Clear TGFA bit */
- timer_status = ctrl_inb(MTU2_TSR_1);
- timer_status &= ~MTU2_TSR_TGFA;
- ctrl_outb(timer_status, MTU2_TSR_1);
-
- /* Do timer tick */
- write_seqlock(&xtime_lock);
- handle_timer_tick();
- write_sequnlock(&xtime_lock);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction mtu2_irq = {
- .name = "timer",
- .handler = mtu2_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
-};
-
-static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 };
-
-static void mtu2_clk_init(struct clk *clk)
-{
- u8 idx = MTU2_TCR_INIT & 0x7;
-
- clk->rate = clk->parent->rate / divisors[idx];
- /* Start TCNT counting */
- ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
-
-}
-
-static void mtu2_clk_recalc(struct clk *clk)
-{
- u8 idx = ctrl_inb(MTU2_TCR_1) & 0x7;
- clk->rate = clk->parent->rate / divisors[idx];
-}
-
-static struct clk_ops mtu2_clk_ops = {
- .init = mtu2_clk_init,
- .recalc = mtu2_clk_recalc,
-};
-
-static struct clk mtu2_clk1 = {
- .name = "mtu2_clk1",
- .ops = &mtu2_clk_ops,
-};
-
-static int mtu2_timer_start(void)
-{
- ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR);
- return 0;
-}
-
-static int mtu2_timer_stop(void)
-{
- ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR);
- return 0;
-}
-
-static int mtu2_timer_init(void)
-{
- u8 tmp;
- unsigned long interval;
-
- setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq);
-
- mtu2_clk1.parent = clk_get(NULL, "module_clk");
-
- ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3);
-
- /* Normal operation */
- ctrl_outb(0, MTU2_TMDR_1);
- ctrl_outb(MTU2_TCR_INIT, MTU2_TCR_1);
- ctrl_outb(0x01, MTU2_TIOR_1);
-
- /* Enable underflow interrupt */
- ctrl_outb(ctrl_inb(MTU2_TIER_1) | MTU2_TIER_TGIEA, MTU2_TIER_1);
-
- interval = CONFIG_SH_PCLK_FREQ / 16 / HZ;
- printk(KERN_INFO "Interval = %ld\n", interval);
-
- ctrl_outw(interval, MTU2_TGRA_1);
- ctrl_outw(0, MTU2_TCNT_1);
-
- clk_register(&mtu2_clk1);
- clk_enable(&mtu2_clk1);
-
- return 0;
-}
-
-struct sys_timer_ops mtu2_timer_ops = {
- .init = mtu2_timer_init,
- .start = mtu2_timer_start,
- .stop = mtu2_timer_stop,
-#ifndef CONFIG_GENERIC_TIME
- .get_offset = mtu2_timer_get_offset,
-#endif
-};
-
-struct sys_timer mtu2_timer = {
- .name = "mtu2",
- .ops = &mtu2_timer_ops,
-};
diff --git a/trunk/arch/sh/kernel/timers/timer-tmu.c b/trunk/arch/sh/kernel/timers/timer-tmu.c
index e060e71d0785..24927015dc31 100644
--- a/trunk/arch/sh/kernel/timers/timer-tmu.c
+++ b/trunk/arch/sh/kernel/timers/timer-tmu.c
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -30,9 +31,13 @@
#define TMU0_TCR_CALIB 0x0000
+static DEFINE_SPINLOCK(tmu0_lock);
+
static unsigned long tmu_timer_get_offset(void)
{
int count;
+ unsigned long flags;
+
static int count_p = 0x7fffffff; /* for the first call after boot */
static unsigned long jiffies_p = 0;
@@ -41,6 +46,7 @@ static unsigned long tmu_timer_get_offset(void)
*/
unsigned long jiffies_t;
+ spin_lock_irqsave(&tmu0_lock, flags);
/* timer count may underflow right here */
count = ctrl_inl(TMU0_TCNT); /* read the latched count */
@@ -66,6 +72,7 @@ static unsigned long tmu_timer_get_offset(void)
jiffies_p = jiffies_t;
count_p = count;
+ spin_unlock_irqrestore(&tmu0_lock, flags);
count = ((LATCH-1) - count) * TICK_SIZE;
count = (count + LATCH/2) / LATCH;
@@ -99,7 +106,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
static struct irqaction tmu_irq = {
.name = "timer",
.handler = tmu_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED,
.mask = CPU_MASK_NONE,
};
@@ -142,9 +149,9 @@ static int tmu_timer_init(void)
{
unsigned long interval;
- setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq);
+ setup_irq(TIMER_IRQ, &tmu_irq);
- tmu0_clk.parent = clk_get(NULL, "module_clk");
+ tmu0_clk.parent = clk_get("module_clk");
/* Start TMU0 */
tmu_timer_stop();
diff --git a/trunk/arch/sh/kernel/timers/timer.c b/trunk/arch/sh/kernel/timers/timer.c
index a6bcc913d25e..dc1f631053a8 100644
--- a/trunk/arch/sh/kernel/timers/timer.c
+++ b/trunk/arch/sh/kernel/timers/timer.c
@@ -16,12 +16,6 @@
static struct sys_timer *sys_timers[] __initdata = {
#ifdef CONFIG_SH_TMU
&tmu_timer,
-#endif
-#ifdef CONFIG_SH_MTU2
- &mtu2_timer,
-#endif
-#ifdef CONFIG_SH_CMT
- &cmt_timer,
#endif
NULL,
};
diff --git a/trunk/arch/sh/kernel/traps.c b/trunk/arch/sh/kernel/traps.c
index 3762d9dc2046..53dfa55f3156 100644
--- a/trunk/arch/sh/kernel/traps.c
+++ b/trunk/arch/sh/kernel/traps.c
@@ -18,14 +18,13 @@
#include
#include
#include
-#include
#include
#include
#ifdef CONFIG_SH_KGDB
#include
-#define CHK_REMOTE_DEBUG(regs) \
-{ \
+#define CHK_REMOTE_DEBUG(regs) \
+{ \
if (kgdb_debug_hook && !user_mode(regs))\
(*kgdb_debug_hook)(regs); \
}
@@ -34,13 +33,8 @@
#endif
#ifdef CONFIG_CPU_SH2
-# define TRAP_RESERVED_INST 4
-# define TRAP_ILLEGAL_SLOT_INST 6
-# define TRAP_ADDRESS_ERROR 9
-# ifdef CONFIG_CPU_SH2A
-# define TRAP_DIVZERO_ERROR 17
-# define TRAP_DIVOVF_ERROR 18
-# endif
+#define TRAP_RESERVED_INST 4
+#define TRAP_ILLEGAL_SLOT_INST 6
#else
#define TRAP_RESERVED_INST 12
#define TRAP_ILLEGAL_SLOT_INST 13
@@ -94,7 +88,7 @@ void die(const char * str, struct pt_regs * regs, long err)
if (!user_mode(regs) || in_interrupt())
dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
- (unsigned long)task_stack_page(current));
+ (unsigned long)task_stack_page(current));
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
@@ -108,6 +102,8 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs,
die(str, regs, err);
}
+static int handle_unaligned_notify_count = 10;
+
/*
* try and fix up kernelspace address errors
* - userspace errors just cause EFAULT to be returned, resulting in SEGV
@@ -202,7 +198,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
if (copy_to_user(dst,src,4))
goto fetch_fault;
ret = 0;
- break;
+ break;
case 2: /* mov.[bwl] to memory, possibly with pre-decrement */
if (instruction & 4)
@@ -226,7 +222,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
if (copy_from_user(dst,src,4))
goto fetch_fault;
ret = 0;
- break;
+ break;
case 6: /* mov.[bwl] from memory, possibly with post-increment */
src = (unsigned char*) *rm;
@@ -234,7 +230,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
*rm += count;
dst = (unsigned char*) rn;
*(unsigned long*)dst = 0;
-
+
#ifdef __LITTLE_ENDIAN__
if (copy_from_user(dst, src, count))
goto fetch_fault;
@@ -245,7 +241,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs)
}
#else
dst += 4-count;
-
+
if (copy_from_user(dst, src, count))
goto fetch_fault;
@@ -324,8 +320,7 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs)
return -EFAULT;
/* kernel */
- die("delay-slot-insn faulting in handle_unaligned_delayslot",
- regs, 0);
+ die("delay-slot-insn faulting in handle_unaligned_delayslot", regs, 0);
}
return handle_unaligned_ins(instruction,regs);
@@ -347,13 +342,6 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs)
#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
-/*
- * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
- * opcodes..
- */
-#ifndef CONFIG_CPU_SH2A
-static int handle_unaligned_notify_count = 10;
-
static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
{
u_int rm;
@@ -366,8 +354,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
if (user_mode(regs) && handle_unaligned_notify_count>0) {
handle_unaligned_notify_count--;
- printk(KERN_NOTICE "Fixing up unaligned userspace access "
- "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+ printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
current->comm,current->pid,(u16*)regs->pc,instruction);
}
@@ -491,58 +478,32 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
regs->pc += 2;
return ret;
}
-#endif /* CONFIG_CPU_SH2A */
-
-#ifdef CONFIG_CPU_HAS_SR_RB
-#define lookup_exception_vector(x) \
- __asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x)))
-#else
-#define lookup_exception_vector(x) \
- __asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x)))
-#endif
/*
- * Handle various address error exceptions:
- * - instruction address error:
- * misaligned PC
- * PC >= 0x80000000 in user mode
- * - data address error (read and write)
- * misaligned data access
- * access to >= 0x80000000 is user mode
- * Unfortuntaly we can't distinguish between instruction address error
- * and data address errors caused by read acceses.
+ * Handle various address error exceptions
*/
-asmlinkage void do_address_error(struct pt_regs *regs,
+asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long writeaccess,
unsigned long address)
{
- unsigned long error_code = 0;
+ unsigned long error_code;
mm_segment_t oldfs;
- siginfo_t info;
-#ifndef CONFIG_CPU_SH2A
u16 instruction;
int tmp;
-#endif
- /* Intentional ifdef */
-#ifdef CONFIG_CPU_HAS_SR_RB
- lookup_exception_vector(error_code);
-#endif
+ asm volatile("stc r2_bank,%0": "=r" (error_code));
oldfs = get_fs();
if (user_mode(regs)) {
- int si_code = BUS_ADRERR;
-
local_irq_enable();
+ current->thread.error_code = error_code;
+ current->thread.trap_no = (writeaccess) ? 8 : 7;
/* bad PC is not something we can fix */
- if (regs->pc & 1) {
- si_code = BUS_ADRALN;
+ if (regs->pc & 1)
goto uspace_segv;
- }
-#ifndef CONFIG_CPU_SH2A
set_fs(USER_DS);
if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
/* Argh. Fault on the instruction itself.
@@ -557,23 +518,14 @@ asmlinkage void do_address_error(struct pt_regs *regs,
if (tmp==0)
return; /* sorted */
-#endif
-
-uspace_segv:
- printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
- "access (PC %lx PR %lx)\n", current->comm, regs->pc,
- regs->pr);
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = si_code;
- info.si_addr = (void *) address;
- force_sig_info(SIGBUS, &info, current);
+ uspace_segv:
+ printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm);
+ force_sig(SIGSEGV, current);
} else {
if (regs->pc & 1)
die("unaligned program counter", regs, error_code);
-#ifndef CONFIG_CPU_SH2A
set_fs(KERNEL_DS);
if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) {
/* Argh. Fault on the instruction itself.
@@ -585,12 +537,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
handle_unaligned_access(instruction, regs);
set_fs(oldfs);
-#else
- printk(KERN_NOTICE "Killing process \"%s\" due to unaligned "
- "access\n", current->comm);
-
- force_sig(SIGSEGV, current);
-#endif
}
}
@@ -602,7 +548,7 @@ int is_dsp_inst(struct pt_regs *regs)
{
unsigned short inst;
- /*
+ /*
* Safe guard if DSP mode is already enabled or we're lacking
* the DSP altogether.
*/
@@ -623,49 +569,27 @@ int is_dsp_inst(struct pt_regs *regs)
#define is_dsp_inst(regs) (0)
#endif /* CONFIG_SH_DSP */
-#ifdef CONFIG_CPU_SH2A
-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) {
- case TRAP_DIVZERO_ERROR:
- info.si_code = FPE_INTDIV;
- break;
- case TRAP_DIVOVF_ERROR:
- info.si_code = FPE_INTOVF;
- break;
- }
-
- force_sig_info(SIGFPE, &info, current);
-}
-#endif
-
/* arch/sh/kernel/cpu/sh4/fpu.c */
extern int do_fpu_inst(unsigned short, struct pt_regs *);
extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7, struct pt_regs __regs);
+ unsigned long r6, unsigned long r7, struct pt_regs regs);
asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
unsigned long error_code;
struct task_struct *tsk = current;
#ifdef CONFIG_SH_FPU_EMU
- unsigned short inst = 0;
+ unsigned short inst;
int err;
- get_user(inst, (unsigned short*)regs->pc);
+ get_user(inst, (unsigned short*)regs.pc);
- err = do_fpu_inst(inst, regs);
+ err = do_fpu_inst(inst, ®s);
if (!err) {
- regs->pc += 2;
+ regs.pc += 2;
return;
}
/* not a FPU inst. */
@@ -673,19 +597,20 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
#ifdef CONFIG_SH_DSP
/* Check if it's a DSP instruction */
- if (is_dsp_inst(regs)) {
+ if (is_dsp_inst(®s)) {
/* Enable DSP mode, and restart instruction. */
- regs->sr |= SR_DSP;
+ regs.sr |= SR_DSP;
return;
}
#endif
- lookup_exception_vector(error_code);
-
+ asm volatile("stc r2_bank, %0": "=r" (error_code));
local_irq_enable();
- CHK_REMOTE_DEBUG(regs);
+ tsk->thread.error_code = error_code;
+ tsk->thread.trap_no = TRAP_RESERVED_INST;
+ CHK_REMOTE_DEBUG(®s);
force_sig(SIGILL, tsk);
- die_if_no_fixup("reserved instruction", regs, error_code);
+ die_if_no_fixup("reserved instruction", ®s, error_code);
}
#ifdef CONFIG_SH_FPU_EMU
@@ -733,41 +658,39 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs)
asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
unsigned long error_code;
struct task_struct *tsk = current;
#ifdef CONFIG_SH_FPU_EMU
- unsigned short inst = 0;
+ unsigned short inst;
- get_user(inst, (unsigned short *)regs->pc + 1);
- if (!do_fpu_inst(inst, regs)) {
- get_user(inst, (unsigned short *)regs->pc);
- if (!emulate_branch(inst, regs))
+ get_user(inst, (unsigned short *)regs.pc + 1);
+ if (!do_fpu_inst(inst, ®s)) {
+ get_user(inst, (unsigned short *)regs.pc);
+ if (!emulate_branch(inst, ®s))
return;
/* fault in branch.*/
}
/* not a FPU inst. */
#endif
- lookup_exception_vector(error_code);
-
+ asm volatile("stc r2_bank, %0": "=r" (error_code));
local_irq_enable();
- CHK_REMOTE_DEBUG(regs);
+ tsk->thread.error_code = error_code;
+ tsk->thread.trap_no = TRAP_RESERVED_INST;
+ CHK_REMOTE_DEBUG(®s);
force_sig(SIGILL, tsk);
- die_if_no_fixup("illegal slot instruction", regs, error_code);
+ die_if_no_fixup("illegal slot instruction", ®s, error_code);
}
asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+ struct pt_regs regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
long ex;
-
- lookup_exception_vector(ex);
- die_if_kernel("exception", regs, ex);
+ asm volatile("stc r2_bank, %0" : "=r" (ex));
+ die_if_kernel("exception", ®s, ex);
}
#if defined(CONFIG_SH_STANDARD_BIOS)
@@ -812,16 +735,12 @@ void *set_exception_table_vec(unsigned int vec, void *handler)
{
extern void *exception_handling_table[];
void *old_handler;
-
+
old_handler = exception_handling_table[vec];
exception_handling_table[vec] = handler;
return old_handler;
}
-extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs __regs);
-
void __init trap_init(void)
{
set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
@@ -840,15 +759,7 @@ void __init trap_init(void)
set_exception_table_evt(0x800, do_fpu_state_restore);
set_exception_table_evt(0x820, do_fpu_state_restore);
#endif
-
-#ifdef CONFIG_CPU_SH2
- set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler);
-#endif
-#ifdef CONFIG_CPU_SH2A
- set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error);
- set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error);
-#endif
-
+
/* Setup VBR for boot cpu */
per_cpu_trap_init();
}
@@ -873,11 +784,6 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
}
printk("\n");
-
- if (!tsk)
- tsk = current;
-
- debug_show_held_locks(tsk);
}
void show_stack(struct task_struct *tsk, unsigned long *sp)
diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig
index 4e0362f50384..9dd606464d23 100644
--- a/trunk/arch/sh/mm/Kconfig
+++ b/trunk/arch/sh/mm/Kconfig
@@ -4,12 +4,8 @@ menu "Processor selection"
# Processor families
#
config CPU_SH2
- select SH_WRITETHROUGH if !CPU_SH2A
bool
-
-config CPU_SH2A
- bool
- select CPU_SH2
+ select SH_WRITETHROUGH
config CPU_SH3
bool
@@ -20,7 +16,6 @@ config CPU_SH4
bool
select CPU_HAS_INTEVT
select CPU_HAS_SR_RB
- select CPU_HAS_PTEA if !CPU_SUBTYPE_ST40
config CPU_SH4A
bool
@@ -45,16 +40,6 @@ config CPU_SUBTYPE_SH7604
bool "Support SH7604 processor"
select CPU_SH2
-config CPU_SUBTYPE_SH7619
- bool "Support SH7619 processor"
- select CPU_SH2
-
-comment "SH-2A Processor Support"
-
-config CPU_SUBTYPE_SH7206
- bool "Support SH7206 processor"
- select CPU_SH2A
-
comment "SH-3 Processor Support"
config CPU_SUBTYPE_SH7300
@@ -104,7 +89,6 @@ comment "SH-4 Processor Support"
config CPU_SUBTYPE_SH7750
bool "Support SH7750 processor"
select CPU_SH4
- select CPU_HAS_IPR_IRQ
help
Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
@@ -120,18 +104,15 @@ config CPU_SUBTYPE_SH7750R
bool "Support SH7750R processor"
select CPU_SH4
select CPU_SUBTYPE_SH7750
- select CPU_HAS_IPR_IRQ
config CPU_SUBTYPE_SH7750S
bool "Support SH7750S processor"
select CPU_SH4
select CPU_SUBTYPE_SH7750
- select CPU_HAS_IPR_IRQ
config CPU_SUBTYPE_SH7751
bool "Support SH7751 processor"
select CPU_SH4
- select CPU_HAS_IPR_IRQ
help
Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
or if you have a HD6417751R CPU.
@@ -140,7 +121,6 @@ config CPU_SUBTYPE_SH7751R
bool "Support SH7751R processor"
select CPU_SH4
select CPU_SUBTYPE_SH7751
- select CPU_HAS_IPR_IRQ
config CPU_SUBTYPE_SH7760
bool "Support SH7760 processor"
@@ -177,11 +157,6 @@ config CPU_SUBTYPE_SH7780
select CPU_SH4A
select CPU_HAS_INTC2_IRQ
-config CPU_SUBTYPE_SH7785
- bool "Support SH7785 processor"
- select CPU_SH4A
- select CPU_HAS_INTC2_IRQ
-
comment "SH4AL-DSP Processor Support"
config CPU_SUBTYPE_SH73180
@@ -241,22 +216,13 @@ config MEMORY_SIZE
config 32BIT
bool "Support 32-bit physical addressing through PMB"
- depends on CPU_SH4A && MMU && (!X2TLB || BROKEN)
+ depends on CPU_SH4A && MMU
default y
help
If you say Y here, physical addressing will be extended to
32-bits through the SH-4A PMB. If this is not set, legacy
29-bit physical addressing will be used.
-config X2TLB
- bool "Enable extended TLB mode"
- depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL
- help
- Selecting this option will enable the extended mode of the SH-X2
- TLB. For legacy SH-X behaviour and interoperability, say N. For
- all of the fun new features and a willingless to submit bug reports,
- say Y.
-
config VSYSCALL
bool "Support vsyscall page"
depends on MMU
@@ -270,53 +236,17 @@ config VSYSCALL
For systems with an MMU that can afford to give up a page,
(the default value) say Y.
-choice
- prompt "Kernel page size"
- default PAGE_SIZE_4KB
-
-config PAGE_SIZE_4KB
- bool "4kB"
- help
- This is the default page size used by all SuperH CPUs.
-
-config PAGE_SIZE_8KB
- bool "8kB"
- depends on EXPERIMENTAL && X2TLB
- help
- This enables 8kB pages as supported by SH-X2 and later MMUs.
-
-config PAGE_SIZE_64KB
- bool "64kB"
- depends on EXPERIMENTAL && CPU_SH4
- help
- This enables support for 64kB pages, possible on all SH-4
- CPUs and later. Highly experimental, not recommended.
-
-endchoice
-
choice
prompt "HugeTLB page size"
depends on HUGETLB_PAGE && CPU_SH4 && MMU
default HUGETLB_PAGE_SIZE_64K
config HUGETLB_PAGE_SIZE_64K
- bool "64kB"
-
-config HUGETLB_PAGE_SIZE_256K
- bool "256kB"
- depends on X2TLB
+ bool "64K"
config HUGETLB_PAGE_SIZE_1MB
bool "1MB"
-config HUGETLB_PAGE_SIZE_4MB
- bool "4MB"
- depends on X2TLB
-
-config HUGETLB_PAGE_SIZE_64MB
- bool "64MB"
- depends on X2TLB
-
endchoice
source "mm/Kconfig"
@@ -344,6 +274,7 @@ config SH_DIRECT_MAPPED
config SH_WRITETHROUGH
bool "Use write-through caching"
+ default y if CPU_SH2
help
Selecting this option will configure the caches in write-through
mode, as opposed to the default write-back configuration.
diff --git a/trunk/arch/sh/mm/cache-sh2.c b/trunk/arch/sh/mm/cache-sh2.c
index 6614033f6be9..2689cb24ea2b 100644
--- a/trunk/arch/sh/mm/cache-sh2.c
+++ b/trunk/arch/sh/mm/cache-sh2.c
@@ -5,7 +5,6 @@
*
* Released under the terms of the GNU GPL v2.0.
*/
-
#include
#include
@@ -15,43 +14,37 @@
#include
#include
-void __flush_wback_region(void *start, int size)
-{
- unsigned long v;
- unsigned long begin, end;
-
- begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
- end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
- & ~(L1_CACHE_BYTES-1);
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- /* FIXME cache purge */
- ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
- }
-}
-
-void __flush_purge_region(void *start, int size)
-{
- unsigned long v;
- unsigned long begin, end;
-
- begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
- end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
- & ~(L1_CACHE_BYTES-1);
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
- }
-}
-
-void __flush_invalidate_region(void *start, int size)
+/*
+ * Calculate the OC address and set the way bit on the SH-2.
+ *
+ * We must have already jump_to_P2()'ed prior to calling this
+ * function, since we rely on CCR manipulation to do the
+ * Right Thing(tm).
+ */
+unsigned long __get_oc_addr(unsigned long set, unsigned long way)
{
- unsigned long v;
- unsigned long begin, end;
-
- begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
- end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
- & ~(L1_CACHE_BYTES-1);
- for (v = begin; v < end; v+=L1_CACHE_BYTES) {
- ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008);
- }
+ unsigned long ccr;
+
+ /*
+ * On SH-2 the way bit isn't tracked in the address field
+ * if we're doing address array access .. instead, we need
+ * to manually switch out the way in the CCR.
+ */
+ ccr = ctrl_inl(CCR);
+ ccr &= ~0x00c0;
+ ccr |= way << cpu_data->dcache.way_shift;
+
+ /*
+ * Despite the number of sets being halved, we end up losing
+ * the first 2 ways to OCRAM instead of the last 2 (if we're
+ * 4-way). As a result, forcibly setting the W1 bit handily
+ * bumps us up 2 ways.
+ */
+ if (ccr & CCR_CACHE_ORA)
+ ccr |= 1 << (cpu_data->dcache.way_shift + 1);
+
+ ctrl_outl(ccr, CCR);
+
+ return CACHE_OC_ADDRESS_ARRAY | (set << cpu_data->dcache.entry_shift);
}
diff --git a/trunk/arch/sh/mm/cache-sh4.c b/trunk/arch/sh/mm/cache-sh4.c
index ae531affccbd..e48cc22724d9 100644
--- a/trunk/arch/sh/mm/cache-sh4.c
+++ b/trunk/arch/sh/mm/cache-sh4.c
@@ -11,8 +11,12 @@
*/
#include
#include
-#include
-#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
@@ -79,9 +83,9 @@ static void __init emit_cache_params(void)
*/
/* Worst case assumed to be 64k cache, direct-mapped i.e. 4 synonym bits. */
-#define MAX_P3_MUTEXES 16
+#define MAX_P3_SEMAPHORES 16
-struct mutex p3map_mutex[MAX_P3_MUTEXES];
+struct semaphore p3map_sem[MAX_P3_SEMAPHORES];
void __init p3_cache_init(void)
{
@@ -111,7 +115,7 @@ void __init p3_cache_init(void)
panic("%s failed.", __FUNCTION__);
for (i = 0; i < cpu_data->dcache.n_aliases; i++)
- mutex_init(&p3map_mutex[i]);
+ sema_init(&p3map_sem[i], 1);
}
/*
@@ -225,7 +229,7 @@ static inline void flush_cache_4096(unsigned long start,
*/
if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) ||
(start < CACHE_OC_ADDRESS_ARRAY))
- exec_offset = 0x20000000;
+ exec_offset = 0x20000000;
local_irq_save(flags);
__flush_cache_4096(start | SH_CACHE_ASSOC,
@@ -246,7 +250,7 @@ void flush_dcache_page(struct page *page)
/* Loop all the D-cache */
n = cpu_data->dcache.n_aliases;
- for (i = 0; i < n; i++, addr += 4096)
+ for (i = 0; i < n; i++, addr += PAGE_SIZE)
flush_cache_4096(addr, phys);
}
diff --git a/trunk/arch/sh/mm/clear_page.S b/trunk/arch/sh/mm/clear_page.S
index 8a706131e521..7b96425ae270 100644
--- a/trunk/arch/sh/mm/clear_page.S
+++ b/trunk/arch/sh/mm/clear_page.S
@@ -1,12 +1,12 @@
-/*
+/* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $
+ *
* __clear_user_page, __clear_user, clear_page implementation of SuperH
*
* Copyright (C) 2001 Kaz Kojima
* Copyright (C) 2001, 2002 Niibe Yutaka
- * Copyright (C) 2006 Paul Mundt
+ *
*/
#include
-#include
/*
* clear_page_slow
@@ -18,11 +18,11 @@
/*
* r0 --- scratch
* r4 --- to
- * r5 --- to + PAGE_SIZE
+ * r5 --- to + 4096
*/
ENTRY(clear_page_slow)
mov r4,r5
- mov.l .Llimit,r0
+ mov.w .Llimit,r0
add r0,r5
mov #0,r0
!
@@ -50,7 +50,7 @@ ENTRY(clear_page_slow)
!
rts
nop
-.Llimit: .long (PAGE_SIZE-28)
+.Llimit: .word (4096-28)
ENTRY(__clear_user)
!
@@ -164,10 +164,10 @@ ENTRY(__clear_user)
* r0 --- scratch
* r4 --- to
* r5 --- orig_to
- * r6 --- to + PAGE_SIZE
+ * r6 --- to + 4096
*/
ENTRY(__clear_user_page)
- mov.l .Lpsz,r0
+ mov.w .L4096,r0
mov r4,r6
add r0,r6
mov #0,r0
@@ -191,7 +191,7 @@ ENTRY(__clear_user_page)
!
rts
nop
-.Lpsz: .long PAGE_SIZE
+.L4096: .word 4096
#endif
diff --git a/trunk/arch/sh/mm/copy_page.S b/trunk/arch/sh/mm/copy_page.S
index 397c94c97315..1addffe117c3 100644
--- a/trunk/arch/sh/mm/copy_page.S
+++ b/trunk/arch/sh/mm/copy_page.S
@@ -1,12 +1,12 @@
-/*
+/* $Id: copy_page.S,v 1.8 2003/08/25 17:03:10 lethal Exp $
+ *
* copy_page, __copy_user_page, __copy_user implementation of SuperH
*
* Copyright (C) 2001 Niibe Yutaka & Kaz Kojima
* Copyright (C) 2002 Toshinobu Sugioka
- * Copyright (C) 2006 Paul Mundt
+ *
*/
#include
-#include
/*
* copy_page_slow
@@ -18,7 +18,7 @@
/*
* r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
- * r8 --- from + PAGE_SIZE
+ * r8 --- from + 4096
* r9 --- not used
* r10 --- to
* r11 --- from
@@ -30,7 +30,7 @@ ENTRY(copy_page_slow)
mov r4,r10
mov r5,r11
mov r5,r8
- mov.l .Lpsz,r0
+ mov.w .L4096,r0
add r0,r8
!
1: mov.l @r11+,r0
@@ -80,7 +80,7 @@ ENTRY(copy_page_slow)
/*
* r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
- * r8 --- from + PAGE_SIZE
+ * r8 --- from + 4096
* r9 --- orig_to
* r10 --- to
* r11 --- from
@@ -94,7 +94,7 @@ ENTRY(__copy_user_page)
mov r5,r11
mov r6,r9
mov r5,r8
- mov.l .Lpsz,r0
+ mov.w .L4096,r0
add r0,r8
!
1: ocbi @r9
@@ -129,7 +129,7 @@ ENTRY(__copy_user_page)
rts
nop
#endif
-.Lpsz: .long PAGE_SIZE
+.L4096: .word 4096
/*
* __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
* Return the number of bytes NOT copied
diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c
index 716ebf568af2..68663b8f99ae 100644
--- a/trunk/arch/sh/mm/fault.c
+++ b/trunk/arch/sh/mm/fault.c
@@ -26,19 +26,13 @@ extern void die(const char *,struct pt_regs *,long);
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
-asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
- unsigned long writeaccess,
- unsigned long address)
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+ unsigned long address)
{
struct task_struct *tsk;
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long page;
- int si_code;
- siginfo_t info;
-
- trace_hardirqs_on();
- local_irq_enable();
#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
@@ -47,46 +41,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
tsk = current;
mm = tsk->mm;
- si_code = SEGV_MAPERR;
-
- if (unlikely(address >= TASK_SIZE)) {
- /*
- * Synchronize this task's top level page-table
- * with the 'reference' page table.
- *
- * Do _not_ use "tsk" here. We might be inside
- * an interrupt in the middle of a task switch..
- */
- int offset = pgd_index(address);
- pgd_t *pgd, *pgd_k;
- pud_t *pud, *pud_k;
- pmd_t *pmd, *pmd_k;
-
- pgd = get_TTB() + offset;
- pgd_k = swapper_pg_dir + offset;
-
- /* This will never happen with the folded page table. */
- if (!pgd_present(*pgd)) {
- if (!pgd_present(*pgd_k))
- goto bad_area_nosemaphore;
- set_pgd(pgd, *pgd_k);
- return;
- }
-
- pud = pud_offset(pgd, address);
- pud_k = pud_offset(pgd_k, address);
- if (pud_present(*pud) || !pud_present(*pud_k))
- goto bad_area_nosemaphore;
- set_pud(pud, *pud_k);
-
- pmd = pmd_offset(pud, address);
- pmd_k = pmd_offset(pud_k, address);
- if (pmd_present(*pmd) || !pmd_present(*pmd_k))
- goto bad_area_nosemaphore;
- set_pmd(pmd, *pmd_k);
-
- return;
- }
/*
* If we're in an interrupt or have no user
@@ -111,7 +65,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
* we can handle it..
*/
good_area:
- si_code = SEGV_ACCERR;
if (writeaccess) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -151,13 +104,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
bad_area:
up_read(&mm->mmap_sem);
-bad_area_nosemaphore:
if (user_mode(regs)) {
- info.si_signo = SIGSEGV;
- info.si_errno = 0;
- info.si_code = si_code;
- info.si_addr = (void *) address;
- force_sig_info(SIGSEGV, &info, tsk);
+ tsk->thread.address = address;
+ tsk->thread.error_code = writeaccess;
+ force_sig(SIGSEGV, tsk);
return;
}
@@ -177,9 +127,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
printk(KERN_ALERT "Unable to handle kernel paging request");
printk(" at virtual address %08lx\n", address);
printk(KERN_ALERT "pc = %08lx\n", regs->pc);
- page = (unsigned long)get_TTB();
+ asm volatile("mov.l %1, %0"
+ : "=r" (page)
+ : "m" (__m(MMU_TTB)));
if (page) {
- page = ((unsigned long *) page)[address >> PGDIR_SHIFT];
+ page = ((unsigned long *) page)[address >> 22];
printk(KERN_ALERT "*pde = %08lx\n", page);
if (page & _PAGE_PRESENT) {
page &= PAGE_MASK;
@@ -214,13 +166,98 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_ADRERR;
- info.si_addr = (void *)address;
- force_sig_info(SIGBUS, &info, tsk);
+ tsk->thread.address = address;
+ tsk->thread.error_code = writeaccess;
+ tsk->thread.trap_no = 14;
+ force_sig(SIGBUS, tsk);
/* Kernel mode? Handle exceptions or die */
if (!user_mode(regs))
goto no_context;
}
+
+#ifdef CONFIG_SH_STORE_QUEUES
+/*
+ * This is a special case for the SH-4 store queues, as pages for this
+ * space still need to be faulted in before it's possible to flush the
+ * store queue cache for writeout to the remapped region.
+ */
+#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
+#else
+#define P3_ADDR_MAX P4SEG
+#endif
+
+/*
+ * Called with interrupts disabled.
+ */
+asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
+ unsigned long writeaccess,
+ unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ pte_t entry;
+ struct mm_struct *mm = current->mm;
+ spinlock_t *ptl;
+ int ret = 1;
+
+#ifdef CONFIG_SH_KGDB
+ if (kgdb_nofault && kgdb_bus_err_hook)
+ kgdb_bus_err_hook();
+#endif
+
+ /*
+ * We don't take page faults for P1, P2, and parts of P4, these
+ * are always mapped, whether it be due to legacy behaviour in
+ * 29-bit mode, or due to PMB configuration in 32-bit mode.
+ */
+ if (address >= P3SEG && address < P3_ADDR_MAX) {
+ pgd = pgd_offset_k(address);
+ mm = NULL;
+ } else {
+ if (unlikely(address >= TASK_SIZE || !mm))
+ return 1;
+
+ pgd = pgd_offset(mm, address);
+ }
+
+ pud = pud_offset(pgd, address);
+ if (pud_none_or_clear_bad(pud))
+ return 1;
+ pmd = pmd_offset(pud, address);
+ if (pmd_none_or_clear_bad(pmd))
+ return 1;
+
+ if (mm)
+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
+ else
+ pte = pte_offset_kernel(pmd, address);
+
+ entry = *pte;
+ if (unlikely(pte_none(entry) || pte_not_present(entry)))
+ goto unlock;
+ if (unlikely(writeaccess && !pte_write(entry)))
+ goto unlock;
+
+ if (writeaccess)
+ entry = pte_mkdirty(entry);
+ entry = pte_mkyoung(entry);
+
+#ifdef CONFIG_CPU_SH4
+ /*
+ * ITLB is not affected by "ldtlb" instruction.
+ * So, we need to flush the entry by ourselves.
+ */
+ __flush_tlb_page(get_asid(), address & PAGE_MASK);
+#endif
+
+ set_pte(pte, entry);
+ update_mmu_cache(NULL, address, entry);
+ ret = 0;
+unlock:
+ if (mm)
+ pte_unmap_unlock(pte, ptl);
+ return ret;
+}
diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c
index 59f4cc18235b..7154d1ce9785 100644
--- a/trunk/arch/sh/mm/init.c
+++ b/trunk/arch/sh/mm/init.c
@@ -84,22 +84,30 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
pmd_t *pmd;
pte_t *pte;
- pgd = pgd_offset_k(addr);
+ pgd = swapper_pg_dir + pgd_index(addr);
if (pgd_none(*pgd)) {
pgd_ERROR(*pgd);
return;
}
- pud = pud_alloc(NULL, pgd, addr);
- if (unlikely(!pud)) {
- pud_ERROR(*pud);
- return;
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud)) {
+ pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC);
+ set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
+ if (pmd != pmd_offset(pud, 0)) {
+ pud_ERROR(*pud);
+ return;
+ }
}
- pmd = pmd_alloc(NULL, pud, addr);
- if (unlikely(!pmd)) {
- pmd_ERROR(*pmd);
- return;
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd)) {
+ pte = (pte_t *)get_zeroed_page(GFP_ATOMIC);
+ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
+ if (pte != pte_offset_kernel(pmd, 0)) {
+ pmd_ERROR(*pmd);
+ return;
+ }
}
pte = pte_offset_kernel(pmd, addr);
@@ -147,6 +155,9 @@ extern char __init_begin, __init_end;
/*
* paging_init() sets up the page tables
+ *
+ * This routines also unmaps the page at virtual kernel address 0, so
+ * that we can trap those pesky NULL-reference errors in the kernel.
*/
void __init paging_init(void)
{
@@ -169,11 +180,14 @@ void __init paging_init(void)
*/
{
unsigned long max_dma, low, start_pfn;
+ pgd_t *pg_dir;
+ int i;
+
+ /* We don't need kernel mapping as hardware support that. */
+ pg_dir = swapper_pg_dir;
- /* We don't need to map the kernel through the TLB, as
- * it is permanatly mapped using P1. So clear the
- * entire pgd. */
- memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
+ for (i = 0; i < PTRS_PER_PGD; i++)
+ pgd_val(pg_dir[i]) = 0;
/* Turn on the MMU */
enable_mmu();
@@ -192,10 +206,6 @@ void __init paging_init(void)
}
}
- /* Set an initial value for the MMU.TTB so we don't have to
- * check for a null value. */
- set_TTB(swapper_pg_dir);
-
#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4)
/*
* If we don't have CONFIG_MMU set and the processor in question
@@ -217,6 +227,7 @@ static struct kcore_list kcore_mem, kcore_vmalloc;
void __init mem_init(void)
{
+ extern unsigned long empty_zero_page[1024];
int codesize, reservedpages, datasize, initsize;
int tmp;
extern unsigned long memory_start;
diff --git a/trunk/arch/sh/mm/ioremap.c b/trunk/arch/sh/mm/ioremap.c
index 11d54c149821..a9fe80cfc233 100644
--- a/trunk/arch/sh/mm/ioremap.c
+++ b/trunk/arch/sh/mm/ioremap.c
@@ -28,7 +28,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address,
{
unsigned long end;
unsigned long pfn;
- pgprot_t pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags);
+ pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW |
+ _PAGE_DIRTY | _PAGE_ACCESSED |
+ _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | flags);
address &= ~PMD_MASK;
end = address + size;
diff --git a/trunk/arch/sh/mm/pg-dma.c b/trunk/arch/sh/mm/pg-dma.c
index bb23679369d6..1406d2e348ca 100644
--- a/trunk/arch/sh/mm/pg-dma.c
+++ b/trunk/arch/sh/mm/pg-dma.c
@@ -39,6 +39,8 @@ static void copy_page_dma(void *to, void *from)
static void clear_page_dma(void *to)
{
+ extern unsigned long empty_zero_page[1024];
+
/*
* We get invoked quite early on, if the DMAC hasn't been initialized
* yet, fall back on the slow manual implementation.
diff --git a/trunk/arch/sh/mm/pg-sh4.c b/trunk/arch/sh/mm/pg-sh4.c
index 3f98d2a4f936..07371ed7a313 100644
--- a/trunk/arch/sh/mm/pg-sh4.c
+++ b/trunk/arch/sh/mm/pg-sh4.c
@@ -6,12 +6,22 @@
*
* Released under the terms of the GNU GPL v2.0.
*/
+#include
+#include
#include
-#include
+#include