summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt7
-rw-r--r--Documentation/magic-number.txt1
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/i386/kernel/apic.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p4.c2
-rw-r--r--arch/i386/kernel/io_apic.c10
-rw-r--r--arch/i386/kernel/irq.c3
-rw-r--r--arch/i386/kernel/process.c53
-rw-r--r--arch/i386/kernel/smp.c2
-rw-r--r--arch/ia64/kernel/msi_ia64.c2
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c2
-rw-r--r--arch/mips/Kconfig18
-rw-r--r--arch/mips/Makefile2
-rw-r--r--arch/mips/cobalt/mtd.c2
-rw-r--r--arch/mips/configs/atlas_defconfig2
-rw-r--r--arch/mips/configs/bigsur_defconfig5
-rw-r--r--arch/mips/configs/capcella_defconfig3
-rw-r--r--arch/mips/configs/cobalt_defconfig7
-rw-r--r--arch/mips/configs/db1000_defconfig4
-rw-r--r--arch/mips/configs/db1100_defconfig4
-rw-r--r--arch/mips/configs/db1200_defconfig4
-rw-r--r--arch/mips/configs/db1500_defconfig7
-rw-r--r--arch/mips/configs/db1550_defconfig5
-rw-r--r--arch/mips/configs/ddb5477_defconfig4
-rw-r--r--arch/mips/configs/decstation_defconfig3
-rw-r--r--arch/mips/configs/e55_defconfig3
-rw-r--r--arch/mips/configs/emma2rh_defconfig5
-rw-r--r--arch/mips/configs/ev64120_defconfig5
-rw-r--r--arch/mips/configs/excite_defconfig7
-rw-r--r--arch/mips/configs/ip22_defconfig3
-rw-r--r--arch/mips/configs/ip27_defconfig5
-rw-r--r--arch/mips/configs/ip32_defconfig4
-rw-r--r--arch/mips/configs/jaguar-atx_defconfig7
-rw-r--r--arch/mips/configs/jazz_defconfig3
-rw-r--r--arch/mips/configs/jmr3927_defconfig4
-rw-r--r--arch/mips/configs/lasat200_defconfig5
-rw-r--r--arch/mips/configs/malta_defconfig2
-rw-r--r--arch/mips/configs/mipssim_defconfig4
-rw-r--r--arch/mips/configs/mpc30x_defconfig5
-rw-r--r--arch/mips/configs/ocelot_3_defconfig6
-rw-r--r--arch/mips/configs/ocelot_c_defconfig4
-rw-r--r--arch/mips/configs/ocelot_defconfig4
-rw-r--r--arch/mips/configs/ocelot_g_defconfig4
-rw-r--r--arch/mips/configs/pb1100_defconfig4
-rw-r--r--arch/mips/configs/pb1500_defconfig6
-rw-r--r--arch/mips/configs/pb1550_defconfig6
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig5
-rw-r--r--arch/mips/configs/pnx8550-stb810_defconfig5
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig6
-rw-r--r--arch/mips/configs/qemu_defconfig3
-rw-r--r--arch/mips/configs/rbhma4500_defconfig6
-rw-r--r--arch/mips/configs/rm200_defconfig4
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig5
-rw-r--r--arch/mips/configs/sead_defconfig2
-rw-r--r--arch/mips/configs/tb0226_defconfig4
-rw-r--r--arch/mips/configs/tb0229_defconfig5
-rw-r--r--arch/mips/configs/tb0287_defconfig5
-rw-r--r--arch/mips/configs/workpad_defconfig3
-rw-r--r--arch/mips/configs/wrppmc_defconfig3
-rw-r--r--arch/mips/configs/yosemite_defconfig4
-rw-r--r--arch/mips/defconfig3
-rw-r--r--arch/mips/kernel/asm-offsets.c4
-rw-r--r--arch/mips/kernel/ptrace.c10
-rw-r--r--arch/mips/kernel/signal.c7
-rw-r--r--arch/mips/kernel/smp.c25
-rw-r--r--arch/mips/kernel/traps.c3
-rw-r--r--arch/mips/mm/ioremap.c96
-rw-r--r--arch/mips/momentum/jaguar_atx/platform.c2
-rw-r--r--arch/mips/momentum/ocelot_3/platform.c2
-rw-r--r--arch/mips/momentum/ocelot_c/platform.c2
-rw-r--r--arch/sparc64/defconfig28
-rw-r--r--arch/sparc64/kernel/irq.c2
-rw-r--r--arch/sparc64/kernel/pci.c2
-rw-r--r--arch/x86_64/kernel/entry.S3
-rw-r--r--arch/x86_64/kernel/i8259.c52
-rw-r--r--arch/x86_64/kernel/io_apic.c439
-rw-r--r--drivers/base/class.c42
-rw-r--r--drivers/base/core.c31
-rw-r--r--drivers/char/agp/Makefile3
-rw-r--r--drivers/char/agp/agp.h8
-rw-r--r--drivers/char/agp/ali-agp.c6
-rw-r--r--drivers/char/agp/amd-k7-agp.c6
-rw-r--r--drivers/char/agp/amd64-agp.c4
-rw-r--r--drivers/char/agp/ati-agp.c4
-rw-r--r--drivers/char/agp/efficeon-agp.c6
-rw-r--r--drivers/char/agp/generic.c2
-rw-r--r--drivers/char/agp/hp-agp.c2
-rw-r--r--drivers/char/agp/i460-agp.c4
-rw-r--r--drivers/char/agp/intel-agp.c38
-rw-r--r--drivers/char/agp/nvidia-agp.c6
-rw-r--r--drivers/char/agp/parisc-agp.c2
-rw-r--r--drivers/char/agp/sgi-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c2
-rw-r--r--drivers/char/agp/sworks-agp.c6
-rw-r--r--drivers/char/agp/uninorth-agp.c8
-rw-r--r--drivers/char/agp/via-agp.c6
-rw-r--r--drivers/leds/Kconfig12
-rw-r--r--drivers/leds/Makefile2
-rw-r--r--drivers/leds/leds-cobalt.c43
-rw-r--r--drivers/leds/leds-h1940.c163
-rw-r--r--drivers/pcmcia/hd64465_ss.c2
-rw-r--r--drivers/pcmcia/m32r_cfc.c2
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c2
-rw-r--r--drivers/pcmcia/omap_cf.c2
-rw-r--r--drivers/pcmcia/rsrc_mgr.c2
-rw-r--r--drivers/pcmcia/vrc4171_card.c2
-rw-r--r--drivers/sbus/char/Kconfig7
-rw-r--r--drivers/sbus/char/Makefile1
-rw-r--r--drivers/sbus/char/aurora.c2364
-rw-r--r--drivers/sbus/char/aurora.h276
-rw-r--r--drivers/sbus/char/bbc_i2c.c17
-rw-r--r--drivers/sbus/char/cd180.h240
-rw-r--r--drivers/sbus/char/uctrl.c8
-rw-r--r--drivers/serial/serial_txx9.c276
-rw-r--r--drivers/usb/core/Makefile2
-rw-r--r--drivers/usb/core/driver.c69
-rw-r--r--drivers/usb/core/hub.c3
-rw-r--r--drivers/usb/core/message.c6
-rw-r--r--drivers/usb/core/quirks.c77
-rw-r--r--drivers/usb/core/sysfs.c111
-rw-r--r--drivers/usb/core/usb.c12
-rw-r--r--drivers/usb/core/usb.h9
-rw-r--r--drivers/usb/gadget/inode.c5
-rw-r--r--drivers/usb/host/uhci-debug.c57
-rw-r--r--drivers/usb/host/uhci-hcd.c58
-rw-r--r--drivers/usb/host/uhci-hcd.h82
-rw-r--r--drivers/usb/host/uhci-q.c219
-rw-r--r--drivers/usb/input/usbkbd.c4
-rw-r--r--drivers/usb/input/usbmouse.c4
-rw-r--r--drivers/usb/input/wacom_wac.c103
-rw-r--r--drivers/usb/input/wacom_wac.h1
-rw-r--r--drivers/usb/misc/Kconfig14
-rw-r--r--drivers/usb/misc/Makefile1
-rw-r--r--drivers/usb/misc/iowarrior.c925
-rw-r--r--drivers/usb/mon/mon_bin.c2
-rw-r--r--drivers/usb/mon/mon_text.c2
-rw-r--r--drivers/usb/mon/usb_mon.h4
-rw-r--r--drivers/usb/net/Kconfig9
-rw-r--r--drivers/usb/net/Makefile1
-rw-r--r--drivers/usb/net/asix.c14
-rw-r--r--drivers/usb/net/dm9601.c606
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.h6
-rw-r--r--drivers/usb/serial/option.c117
-rw-r--r--fs/jfs/jfs_txnmgr.c3
-rw-r--r--fs/sysfs/file.c44
-rw-r--r--fs/sysfs/sysfs.h11
-rw-r--r--include/asm-i386/idle.h14
-rw-r--r--include/asm-i386/processor.h8
-rw-r--r--include/asm-mips/ptrace.h4
-rw-r--r--include/asm-mips/sigcontext.h4
-rw-r--r--include/asm-mips/stackframe.h30
-rw-r--r--include/asm-x86_64/hw_irq.h25
-rw-r--r--include/linux/device.h2
-rw-r--r--include/linux/irq.h11
-rw-r--r--include/linux/kmod.h2
-rw-r--r--include/linux/pm.h37
-rw-r--r--include/linux/sysfs.h30
-rw-r--r--include/linux/usb.h4
-rw-r--r--include/linux/usb/ch9.h22
-rw-r--r--include/linux/usb/iowarrior.h33
-rw-r--r--include/linux/usb/quirks.h11
-rw-r--r--kernel/irq/migration.c9
-rw-r--r--kernel/kmod.c120
-rw-r--r--kernel/module.c32
-rw-r--r--kernel/params.c1
-rw-r--r--kernel/power/main.c5
-rw-r--r--kernel/time/tick-common.c5
-rw-r--r--kernel/time/tick-sched.c2
169 files changed, 3603 insertions, 3998 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c479d30eeaa..03eb5ed503f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1758,6 +1758,13 @@ and is between 256 and 4096 characters. It is defined in the file
Note that genuine overcurrent events won't be
reported either.
+ usbcore.autosuspend=
+ [USB] The autosuspend time delay (in seconds) used
+ for newly-detected USB devices (default 2). This
+ is the time required before an idle device will be
+ autosuspended. Devices for which the delay is set
+ to 0 won't be autosuspended at all.
+
usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at.
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index af67faccf4d..0e740c812d1 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -65,7 +65,6 @@ CMAGIC 0x0111 user include/linux/a.out.h
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
-AURORA_MAGIC 0x0A18 Aurora_port drivers/sbus/char/aurora.h
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
APM_BIOS_MAGIC 0x4101 apm_user arch/i386/kernel/apm.c
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
diff --git a/MAINTAINERS b/MAINTAINERS
index c268b51e451..a9c13196f6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3392,6 +3392,13 @@ L: linux-usb-devel@lists.sourceforge.net
S: Maintained
W: http://www.kroah.com/linux-usb/
+USB DAVICOM DM9601 DRIVER
+P: Peter Korsgaard
+M: jacmet@sunsite.dk
+L: linux-usb-devel@lists.sourceforge.net
+W: http://www.linux-usb.org/usbnet
+S: Maintained
+
USB EHCI DRIVER
P: David Brownell
M: dbrownell@users.sourceforge.net
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 9655c233e6f..7a2c9cbdb51 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -38,7 +38,6 @@
#include <asm/hpet.h>
#include <asm/i8253.h>
#include <asm/nmi.h>
-#include <asm/idle.h>
#include <mach_apic.h>
#include <mach_apicdef.h>
@@ -561,7 +560,6 @@ void fastcall smp_apic_timer_interrupt(struct pt_regs *regs)
* Besides, if we don't timer interrupts ignore the global
* interrupt lock, which is the WrongThing (tm) to do.
*/
- exit_idle();
irq_enter();
local_apic_timer_interrupt();
irq_exit();
@@ -1221,7 +1219,6 @@ void smp_spurious_interrupt(struct pt_regs *regs)
{
unsigned long v;
- exit_idle();
irq_enter();
/*
* Check if this really is a spurious interrupt and ACK it
@@ -1245,7 +1242,6 @@ void smp_error_interrupt(struct pt_regs *regs)
{
unsigned long v, v1;
- exit_idle();
irq_enter();
/* First tickle the hardware, only then report what went on. -- REW */
v = apic_read(APIC_ESR);
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index 8359c19d3a2..504434a4601 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -12,7 +12,6 @@
#include <asm/system.h>
#include <asm/msr.h>
#include <asm/apic.h>
-#include <asm/idle.h>
#include <asm/therm_throt.h>
@@ -60,7 +59,6 @@ static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_therm
fastcall void smp_thermal_interrupt(struct pt_regs *regs)
{
- exit_idle();
irq_enter();
vendor_thermal_interrupt(regs);
irq_exit();
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 4ccebd454e2..6fec4dab70b 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -343,7 +343,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
break;
entry = irq_2_pin + entry->next;
}
- set_native_irq_info(irq, cpumask);
+ irq_desc[irq].affinity = cpumask;
spin_unlock_irqrestore(&ioapic_lock, flags);
}
@@ -1354,7 +1354,7 @@ static void __init setup_IO_APIC_irqs(void)
}
spin_lock_irqsave(&ioapic_lock, flags);
__ioapic_write_entry(apic, pin, entry);
- set_native_irq_info(irq, TARGET_CPUS);
+ irq_desc[irq].affinity = TARGET_CPUS;
spin_unlock_irqrestore(&ioapic_lock, flags);
}
}
@@ -2585,7 +2585,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
write_msi_msg(irq, &msg);
- set_native_irq_info(irq, mask);
+ irq_desc[irq].affinity = mask;
}
#endif /* CONFIG_SMP */
@@ -2669,7 +2669,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
dest = cpu_mask_to_apicid(mask);
target_ht_irq(irq, dest);
- set_native_irq_info(irq, mask);
+ irq_desc[irq].affinity = mask;
}
#endif
@@ -2875,7 +2875,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
spin_lock_irqsave(&ioapic_lock, flags);
__ioapic_write_entry(ioapic, pin, entry);
- set_native_irq_info(irq, TARGET_CPUS);
+ irq_desc[irq].affinity = TARGET_CPUS;
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 0f2ca590bf2..8db8d514c9c 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -18,8 +18,6 @@
#include <linux/cpu.h>
#include <linux/delay.h>
-#include <asm/idle.h>
-
#include <asm/apic.h>
#include <asm/uaccess.h>
@@ -77,7 +75,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
union irq_ctx *curctx, *irqctx;
u32 *isp;
#endif
- exit_idle();
if (unlikely((unsigned)irq >= NR_IRQS)) {
printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index bea304d48cd..393a67d5d94 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -49,7 +49,6 @@
#include <asm/i387.h>
#include <asm/desc.h>
#include <asm/vm86.h>
-#include <asm/idle.h>
#ifdef CONFIG_MATH_EMULATION
#include <asm/math_emu.h>
#endif
@@ -82,42 +81,6 @@ void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
-static ATOMIC_NOTIFIER_HEAD(idle_notifier);
-
-void idle_notifier_register(struct notifier_block *n)
-{
- atomic_notifier_chain_register(&idle_notifier, n);
-}
-
-void idle_notifier_unregister(struct notifier_block *n)
-{
- atomic_notifier_chain_unregister(&idle_notifier, n);
-}
-
-static DEFINE_PER_CPU(volatile unsigned long, idle_state);
-
-void enter_idle(void)
-{
- /* needs to be atomic w.r.t. interrupts, not against other CPUs */
- __set_bit(0, &__get_cpu_var(idle_state));
- atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
-}
-
-static void __exit_idle(void)
-{
- /* needs to be atomic w.r.t. interrupts, not against other CPUs */
- if (__test_and_clear_bit(0, &__get_cpu_var(idle_state)) == 0)
- return;
- atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
-}
-
-void exit_idle(void)
-{
- if (current->pid)
- return;
- __exit_idle();
-}
-
void disable_hlt(void)
{
hlt_counter++;
@@ -168,7 +131,6 @@ EXPORT_SYMBOL(default_idle);
*/
static void poll_idle (void)
{
- local_irq_enable();
cpu_relax();
}
@@ -229,16 +191,7 @@ void cpu_idle(void)
play_dead();
__get_cpu_var(irq_stat).idle_timestamp = jiffies;
-
- /*
- * Idle routines should keep interrupts disabled
- * from here on, until they go to idle.
- * Otherwise, idle callbacks can misfire.
- */
- local_irq_disable();
- enter_idle();
idle();
- __exit_idle();
}
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
@@ -293,11 +246,7 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
__monitor((void *)&current_thread_info()->flags, 0, 0);
smp_mb();
if (!need_resched())
- __sti_mwait(eax, ecx);
- else
- local_irq_enable();
- } else {
- local_irq_enable();
+ __mwait(eax, ecx);
}
}
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 9bd9637ae69..0e8977871b1 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -23,7 +23,6 @@
#include <asm/mtrr.h>
#include <asm/tlbflush.h>
-#include <asm/idle.h>
#include <mach_apic.h>
/*
@@ -624,7 +623,6 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs)
/*
* At this point the info structure may be out of scope unless wait==1
*/
- exit_idle();
irq_enter();
(*func)(info);
irq_exit();
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 0d05450c91c..e7220900ea1 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -60,7 +60,7 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
msg.address_lo = addr;
write_msi_msg(irq, &msg);
- set_native_irq_info(irq, cpu_mask);
+ irq_desc[irq].affinity = cpu_mask;
}
#endif /* CONFIG_SMP */
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index ea3dc38d73f..49873aa4a37 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -204,7 +204,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
write_msi_msg(irq, &msg);
- set_native_irq_info(irq, cpu_mask);
+ irq_desc[irq].affinity = cpu_mask;
}
#endif /* CONFIG_SMP */
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index c6f74f1c639..58e97886d77 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -274,6 +274,7 @@ config MIPS_ATLAS
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL
+ select SYS_SUPPORTS_SMARTMIPS
select GENERIC_HARDIRQS_NO__DO_IRQ
help
This enables support for the MIPS Technologies Atlas evaluation
@@ -305,6 +306,7 @@ config MIPS_MALTA
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_SMARTMIPS
help
This enables support for the MIPS Technologies Malta evaluation
board.
@@ -322,6 +324,7 @@ config MIPS_SEAD
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_SMARTMIPS
help
This enables support for the MIPS Technologies SEAD evaluation
board.
@@ -1641,6 +1644,18 @@ config 64BIT_PHYS_ADDR
config CPU_HAS_LLSC
bool
+config CPU_HAS_SMARTMIPS
+ depends on SYS_SUPPORTS_SMARTMIPS
+ bool "Support for the SmartMIPS ASE"
+ help
+ SmartMIPS is a extension of the MIPS32 architecture aimed at
+ increased security at both hardware and software level for
+ smartcards. Enabling this option will allow proper use of the
+ SmartMIPS instructions by Linux applications. However a kernel with
+ this option will not work on a MIPS core without SmartMIPS core. If
+ you don't know you probably don't have SmartMIPS and should say N
+ here.
+
config CPU_HAS_WB
bool
@@ -1704,6 +1719,9 @@ config CPU_SUPPORTS_HIGHMEM
config SYS_SUPPORTS_HIGHMEM
bool
+config SYS_SUPPORTS_SMARTMIPS
+ bool
+
config ARCH_FLATMEM_ENABLE
def_bool y
depends on !NUMA
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index c68b5d3e5d1..92bca6ad6ab 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -103,6 +103,8 @@ predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__
cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
+cflags-$(CONFIG_CPU_HAS_SMARTMIPS) += $(call cc-option,-msmartmips)
+
cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \
-fno-omit-frame-pointer
diff --git a/arch/mips/cobalt/mtd.c b/arch/mips/cobalt/mtd.c
index 01d8ec77fe9..2b088ef3839 100644
--- a/arch/mips/cobalt/mtd.c
+++ b/arch/mips/cobalt/mtd.c
@@ -24,7 +24,7 @@
static struct mtd_partition cobalt_mtd_partitions[] = {
{
- .name = "Colo",
+ .name = "firmware",
.offset = 0x0,
.size = 0x80000,
},
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 45874d1038d..458894933a4 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -139,10 +139,12 @@ CONFIG_MIPS_MT_DISABLED=y
CONFIG_SYS_SUPPORTS_MULTITHREADING=y
# CONFIG_64BIT_PHYS_ADDR is not set
CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index b4cdd3e7cdf..aa05e294ea6 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:35 2007
+# Tue Feb 20 21:47:22 2007
#
CONFIG_MIPS=y
@@ -417,6 +417,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -589,6 +590,7 @@ CONFIG_NET_SB1250_MAC=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1025,7 +1027,6 @@ CONFIG_FORCED_INLINING=y
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
# CONFIG_SB1XXX_CORELIS is not set
# CONFIG_RUNTIME_DEBUG is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index b05469e0bcd..b2594fa556f 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:36 2007
+# Tue Feb 20 21:47:22 2007
#
CONFIG_MIPS=y
@@ -388,6 +388,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index f88c40fc994..9090a7aba6c 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Mon Feb 19 14:51:58 2007
+# Tue Feb 20 21:47:24 2007
#
CONFIG_MIPS=y
@@ -425,7 +425,7 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_LEN=0x0
CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_PLATRAM is not set
@@ -449,7 +449,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -464,6 +463,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -658,6 +658,7 @@ CONFIG_TULIP=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 1db19f1bfd4..4cb8cf4255a 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:39 2007
+# Tue Feb 20 21:47:24 2007
#
CONFIG_MIPS=y
@@ -548,6 +548,7 @@ CONFIG_MTD_ALCHEMY=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1103,6 +1104,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 529e6ebe2a8..d86dedf27fc 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:39 2007
+# Tue Feb 20 21:47:24 2007
#
CONFIG_MIPS=y
@@ -537,6 +537,7 @@ CONFIG_MTD_ALCHEMY=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1103,6 +1104,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 9e86dcd3c31..c24b6008345 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:40 2007
+# Tue Feb 20 21:47:25 2007
#
CONFIG_MIPS=y
@@ -541,6 +541,7 @@ CONFIG_MTD_NAND_IDS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1185,6 +1186,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="mem=48M"
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 9c944611eda..baad2c5223b 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:41 2007
+# Tue Feb 20 21:47:26 2007
#
CONFIG_MIPS=y
@@ -542,7 +542,6 @@ CONFIG_MTD_ALCHEMY=y
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -557,6 +556,7 @@ CONFIG_MTD_ALCHEMY=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -715,6 +715,7 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1145,6 +1146,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1402,6 +1404,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 5b18d5da985..c29fdab0423 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:42 2007
+# Tue Feb 20 21:47:27 2007
#
CONFIG_MIPS=y
@@ -562,6 +562,7 @@ CONFIG_MTD_NAND_AU1550=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -751,6 +752,7 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1219,6 +1221,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index 12101888618..f4b316d2cd7 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:43 2007
+# Tue Feb 20 21:47:28 2007
#
CONFIG_MIPS=y
@@ -386,6 +386,7 @@ CONFIG_PROC_EVENTS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -925,6 +926,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="ip=any"
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 2d717455a82..9c38e5c7776 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:44 2007
+# Tue Feb 20 21:47:28 2007
#
CONFIG_MIPS=y
@@ -398,6 +398,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 0ee2fbb35f1..922af379aa4 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:44 2007
+# Tue Feb 20 21:47:28 2007
#
CONFIG_MIPS=y
@@ -294,6 +294,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# Plug and Play support
#
# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 218fe6e5f2d..c0db8f14713 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:46 2007
+# Tue Feb 20 21:47:29 2007
#
CONFIG_MIPS=y
@@ -611,7 +611,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -626,6 +625,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1039,6 +1039,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index 5ad4870ad5e..ce088b36291 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:46 2007
+# Tue Feb 20 21:47:30 2007
#
CONFIG_MIPS=y
@@ -391,6 +391,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -520,6 +521,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -914,6 +916,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 5e179fe599b..82f204d080b 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:47 2007
+# Tue Feb 20 21:47:31 2007
#
CONFIG_MIPS=y
@@ -451,6 +451,7 @@ CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_BASLER_EXCITE is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
@@ -467,6 +468,7 @@ CONFIG_MTD_NAND_IDS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -638,6 +640,7 @@ CONFIG_NETDEVICES=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1008,6 +1011,7 @@ CONFIG_USB_HID=m
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1277,6 +1281,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 864de219eb6..cb81f13bd45 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:48 2007
+# Tue Feb 20 21:47:32 2007
#
CONFIG_MIPS=y
@@ -620,6 +620,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 7b2f5f8397a..46f6ac4083b 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:49 2007
+# Tue Feb 20 21:47:32 2007
#
CONFIG_MIPS=y
@@ -456,6 +456,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -672,6 +673,7 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1060,6 +1062,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=15
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 14398e8a176..d9e5000d532 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:50 2007
+# Tue Feb 20 21:47:33 2007
#
CONFIG_MIPS=y
@@ -396,6 +396,7 @@ CONFIG_PROC_EVENTS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -600,6 +601,7 @@ CONFIG_SGI_O2MACE_ETH=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index b38978794a5..57ef0c45a62 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:51 2007
+# Tue Feb 20 21:47:33 2007
#
CONFIG_MIPS=y
@@ -375,6 +375,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -518,9 +519,6 @@ CONFIG_EEPRO100=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
-CONFIG_MV643XX_ETH_0=y
-CONFIG_MV643XX_ETH_1=y
-CONFIG_MV643XX_ETH_2=y
CONFIG_QLA3XXX=m
#
@@ -833,6 +831,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index dacf0a618d5..21d979f8326 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:52 2007
+# Tue Feb 20 21:47:33 2007
#
CONFIG_MIPS=y
@@ -646,6 +646,7 @@ CONFIG_PARPORT_1284=y
# Plug and Play support
#
# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 29ed772455f..9ebb522fbbb 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:53 2007
+# Tue Feb 20 21:47:34 2007
#
CONFIG_MIPS=y
@@ -384,6 +384,7 @@ CONFIG_PROC_EVENTS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -513,6 +514,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index a1437b34e18..b3f767ff1c5 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:54 2007
+# Tue Feb 20 21:47:34 2007
#
CONFIG_MIPS=y
@@ -454,7 +454,6 @@ CONFIG_MTD_LASAT=y
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -469,6 +468,7 @@ CONFIG_MTD_LASAT=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -654,6 +654,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 8d21bb96349..a5f379d626d 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -145,6 +145,7 @@ CONFIG_SYS_SUPPORTS_MULTITHREADING=y
CONFIG_MIPS_MT_FPAFF=y
# CONFIG_64BIT_PHYS_ADDR is not set
CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_MIPSR2_SRS=y
CONFIG_CPU_HAS_SYNC=y
@@ -152,6 +153,7 @@ CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_IRQ_PER_CPU=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 2acb99bf2ec..5ff53e18491 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:56 2007
+# Tue Feb 20 21:47:35 2007
#
CONFIG_MIPS=y
@@ -436,6 +436,7 @@ CONFIG_FIB_RULES=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -878,7 +879,6 @@ CONFIG_FORCED_INLINING=y
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
# CONFIG_RUNTIME_DEBUG is not set
# CONFIG_MIPS_UNCACHED is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index d52a5a4877d..750e6445c61 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:56 2007
+# Tue Feb 20 21:47:35 2007
#
CONFIG_MIPS=y
@@ -405,6 +405,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -531,6 +532,7 @@ CONFIG_MII=m
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -883,6 +885,7 @@ CONFIG_USB_PEGASUS=m
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index 746106b88ba..2febd0a7fba 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:58 2007
+# Tue Feb 20 21:47:35 2007
#
CONFIG_MIPS=y
@@ -496,6 +496,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -713,9 +714,6 @@ CONFIG_E100=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
-CONFIG_MV643XX_ETH_0=y
-CONFIG_MV643XX_ETH_1=y
-CONFIG_MV643XX_ETH_2=y
CONFIG_QLA3XXX=m
# CONFIG_ATL1 is not set
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index 4b32b270df3..b8f457300bb 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:58 2007
+# Tue Feb 20 21:47:36 2007
#
CONFIG_MIPS=y
@@ -393,6 +393,7 @@ CONFIG_PROC_EVENTS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -523,6 +524,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_BNX2 is not set
# CONFIG_MV643XX_ETH is not set
CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 674631b09c9..8ade072271c 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:59 2007
+# Tue Feb 20 21:47:36 2007
#
CONFIG_MIPS=y
@@ -390,6 +390,7 @@ CONFIG_PROC_EVENTS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -854,6 +855,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 26002639234..d20a2216c11 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:00 2007
+# Tue Feb 20 21:47:36 2007
#
CONFIG_MIPS=y
@@ -392,6 +392,7 @@ CONFIG_PROC_EVENTS=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -522,6 +523,7 @@ CONFIG_GALILEO_64240_ETH=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 05a33a2aeb2..33fcc8133bc 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:01 2007
+# Tue Feb 20 21:47:37 2007
#
CONFIG_MIPS=y
@@ -549,6 +549,7 @@ CONFIG_MTD_ALCHEMY=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1096,6 +1097,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 34a6bee589b..e07c55dc8dc 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:02 2007
+# Tue Feb 20 21:47:37 2007
#
CONFIG_MIPS=y
@@ -541,7 +541,6 @@ CONFIG_MTD_ALCHEMY=y
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -556,6 +555,7 @@ CONFIG_MTD_ALCHEMY=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -745,6 +745,7 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1213,6 +1214,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index e3bff462e62..df210dd2247 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:03 2007
+# Tue Feb 20 21:47:37 2007
#
CONFIG_MIPS=y
@@ -542,7 +542,6 @@ CONFIG_MTD_ALCHEMY=y
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -557,6 +556,7 @@ CONFIG_MTD_ALCHEMY=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -746,6 +746,7 @@ CONFIG_MIPS_AU1X00_ENET=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1206,6 +1207,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 009b3f87b44..106a1641c0b 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:04 2007
+# Tue Feb 20 21:47:38 2007
#
CONFIG_MIPS=y
@@ -389,6 +389,7 @@ CONFIG_FW_LOADER=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -962,6 +963,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1229,6 +1231,7 @@ CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
# CONFIG_RUNTIME_DEBUG is not set
# CONFIG_MIPS_UNCACHED is not set
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index 5bd377bdbb2..8caa2cd1aa7 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:04 2007
+# Tue Feb 20 21:47:38 2007
#
CONFIG_MIPS=y
@@ -386,6 +386,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -952,6 +953,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1219,6 +1221,7 @@ CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
# CONFIG_RUNTIME_DEBUG is not set
# CONFIG_MIPS_UNCACHED is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index cc694709ba6..43f1becec2a 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:06 2007
+# Tue Feb 20 21:47:39 2007
#
CONFIG_MIPS=y
@@ -474,6 +474,7 @@ CONFIG_FW_LOADER=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -987,6 +988,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -1209,6 +1211,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1466,6 +1469,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index c18c5e71d8a..f68396d19f9 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:06 2007
+# Tue Feb 20 21:47:39 2007
#
CONFIG_MIPS=y
@@ -348,6 +348,7 @@ CONFIG_PROC_EVENTS=y
# Plug and Play support
#
# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 678f23217c9..a6a824fcc87 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:07 2007
+# Tue Feb 20 21:47:39 2007
#
CONFIG_MIPS=y
@@ -560,7 +560,6 @@ CONFIG_MTD_CFI_UTIL=y
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
#
# OneNAND Flash Device Drivers
@@ -576,6 +575,7 @@ CONFIG_MTD_CFI_UTIL=y
# Plug and Play support
#
# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1191,6 +1191,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1462,6 +1463,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 0417e86ab62..bee3702d501 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:09 2007
+# Tue Feb 20 21:47:40 2007
#
CONFIG_MIPS=y
@@ -661,6 +661,7 @@ CONFIG_PARPORT_NOT_PC=y
# Plug and Play support
#
# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -1397,6 +1398,7 @@ CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
CONFIG_USB_LED=m
# CONFIG_USB_CYPRESS_CY7C63 is not set
CONFIG_USB_CYTHERM=m
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 533df6fd8b4..3c891ed1014 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:09 2007
+# Tue Feb 20 21:47:40 2007
#
CONFIG_MIPS=y
@@ -424,6 +424,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -581,6 +582,7 @@ CONFIG_NET_SB1250_MAC=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -945,6 +947,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=15
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
# CONFIG_SB1XXX_CORELIS is not set
#
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 38816fe264a..e31d964a053 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -129,10 +129,12 @@ CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_VPE_LOADER is not set
# CONFIG_64BIT_PHYS_ADDR is not set
CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index c2f7c8cea1e..5771c1aee76 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:11 2007
+# Tue Feb 20 21:47:41 2007
#
CONFIG_MIPS=y
@@ -396,6 +396,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -920,6 +921,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index 33b788089ab..a8eb4b182d3 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:12 2007
+# Tue Feb 20 21:47:41 2007
#
CONFIG_MIPS=y
@@ -397,6 +397,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -530,6 +531,7 @@ CONFIG_R8169=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -819,6 +821,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index d180586d638..69b87304fdb 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:13 2007
+# Tue Feb 20 21:47:41 2007
#
CONFIG_MIPS=y
@@ -409,6 +409,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -675,6 +676,7 @@ CONFIG_R8169=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -1016,6 +1018,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 570f0c1475b..2abbd682772 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:13 2007
+# Tue Feb 20 21:47:42 2007
#
CONFIG_MIPS=y
@@ -396,6 +396,7 @@ CONFIG_CONNECTOR=m
# Plug and Play support
#
# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 08f3190dda8..44b6b7c1fdb 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:14 2007
+# Tue Feb 20 21:47:42 2007
#
CONFIG_MIPS=y
@@ -400,6 +400,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index aa69fee321d..f24e1c6fc48 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:15 2007
+# Tue Feb 20 21:47:42 2007
#
CONFIG_MIPS=y
@@ -381,6 +381,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -841,6 +842,7 @@ CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
# CONFIG_RUNTIME_DEBUG is not set
#
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 6c2a233e36c..8cb8f591919 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:34 2007
+# Tue Feb 20 21:47:14 2007
#
CONFIG_MIPS=y
@@ -620,6 +620,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index c0b089d4718..222de465db7 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -64,6 +64,9 @@ void output_ptreg_defines(void)
offset("#define PT_R31 ", struct pt_regs, regs[31]);
offset("#define PT_LO ", struct pt_regs, lo);
offset("#define PT_HI ", struct pt_regs, hi);
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ offset("#define PT_ACX ", struct pt_regs, acx);
+#endif
offset("#define PT_EPC ", struct pt_regs, cp0_epc);
offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
offset("#define PT_STATUS ", struct pt_regs, cp0_status);
@@ -246,6 +249,7 @@ void output_sc_defines(void)
text("/* Linux sigcontext offsets. */");
offset("#define SC_REGS ", struct sigcontext, sc_regs);
offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs);
+ offset("#define SC_ACX ", struct sigcontext, sc_acx);
offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
offset("#define SC_PC ", struct sigcontext, sc_pc);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 258d74fd0b6..201ae194d1b 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -236,6 +236,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case MMLO:
tmp = regs->lo;
break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ case ACX:
+ tmp = regs->acx;
+ break;
+#endif
case FPC_CSR:
tmp = child->thread.fpu.fcr31;
break;
@@ -362,6 +367,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case MMLO:
regs->lo = data;
break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ case ACX:
+ regs->acx = data;
+ break;
+#endif
case FPC_CSR:
child->thread.fpu.fcr31 = data;
break;
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index adbfb95e42d..f091786187a 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -89,6 +89,9 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
for (i = 1; i < 32; i++)
err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ err |= __put_user(regs->acx, &sc->sc_acx);
+#endif
err |= __put_user(regs->hi, &sc->sc_mdhi);
err |= __put_user(regs->lo, &sc->sc_mdlo);
if (cpu_has_dsp) {
@@ -132,6 +135,10 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
current_thread_info()->restart_block.fn = do_no_restart_syscall;
err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ err |= __get_user(regs->acx, &sc->sc_acx);
+#endif
err |= __get_user(regs->hi, &sc->sc_mdhi);
err |= __get_user(regs->lo, &sc->sc_mdlo);
if (cpu_has_dsp) {
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 0555fc554f6..c46e479c992 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -51,31 +51,14 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
EXPORT_SYMBOL(phys_cpu_present_map);
EXPORT_SYMBOL(cpu_online_map);
+/* This happens early in bootup, can't really do it better */
static void smp_tune_scheduling (void)
{
struct cache_desc *cd = &current_cpu_data.scache;
- unsigned long cachesize; /* kB */
- unsigned long cpu_khz;
+ unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
- /*
- * Crude estimate until we actually meassure ...
- */
- cpu_khz = loops_per_jiffy * 2 * HZ / 1000;
-
- /*
- * Rough estimation for SMP scheduling, this is the number of
- * cycles it takes for a fully memory-limited process to flush
- * the SMP-local cache.
- *
- * (For a P5 this pretty much means we will choose another idle
- * CPU almost always at wakeup time (this is due to the small
- * L1 cache), on PIIs it's around 50-100 usecs, depending on
- * the cache size)
- */
- if (!cpu_khz)
- return;
-
- cachesize = cd->linesz * cd->sets * cd->ways;
+ if (cachesize > max_cache_size)
+ max_cache_size = cachesize;
}
extern void __init calibrate_delay(void);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2aa208b99da..18f56a9dbcf 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -229,6 +229,9 @@ void show_regs(struct pt_regs *regs)
printk("\n");
}
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ printk("Acx : %0*lx\n", field, regs->acx);
+#endif
printk("Hi : %0*lx\n", field, regs->hi);
printk("Lo : %0*lx\n", field, regs->lo);
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index fc2c96f0a1f..cea7d0ea36e 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -6,13 +6,98 @@
* (C) Copyright 1995 1996 Linus Torvalds
* (C) Copyright 2001, 2002 Ralf Baechle
*/
-#include <linux/mm.h>
#include <linux/module.h>
#include <asm/addrspace.h>
#include <asm/byteorder.h>
#include <linux/vmalloc.h>
-#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+ phys_t size, phys_t phys_addr, unsigned long flags)
+{
+ phys_t end;
+ unsigned long pfn;
+ pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+ | __WRITEABLE | flags);
+
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ if (address >= end)
+ BUG();
+ pfn = phys_addr >> PAGE_SHIFT;
+ do {
+ if (!pte_none(*pte)) {
+ printk("remap_area_pte: page already exists\n");
+ BUG();
+ }
+ set_pte(pte, pfn_pte(pfn, pgprot));
+ address += PAGE_SIZE;
+ pfn++;
+ pte++;
+ } while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+ phys_t size, phys_t phys_addr, unsigned long flags)
+{
+ phys_t end;
+
+ address &= ~PGDIR_MASK;
+ end = address + size;
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+ phys_addr -= address;
+ if (address >= end)
+ BUG();
+ do {
+ pte_t * pte = pte_alloc_kernel(pmd, address);
+ if (!pte)
+ return -ENOMEM;
+ remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address && (address < end));
+ return 0;
+}
+
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+ phys_t size, unsigned long flags)
+{
+ int error;
+ pgd_t * dir;
+ unsigned long end = address + size;
+
+ phys_addr -= address;
+ dir = pgd_offset(&init_mm, address);
+ flush_cache_all();
+ if (address >= end)
+ BUG();
+ do {
+ pud_t *pud;
+ pmd_t *pmd;
+
+ error = -ENOMEM;
+ pud = pud_alloc(&init_mm, dir, address);
+ if (!pud)
+ break;
+ pmd = pmd_alloc(&init_mm, pud, address);
+ if (!pmd)
+ break;
+ if (remap_area_pmd(pmd, address, end - address,
+ phys_addr + address, flags))
+ break;
+ error = 0;
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ } while (address && (address < end));
+ flush_tlb_all();
+ return error;
+}
/*
* Generic mapping function (not visible outside):
@@ -36,7 +121,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
unsigned long offset;
phys_t last_addr;
void * addr;
- pgprot_t pgprot;
phys_addr = fixup_bigphys_addr(phys_addr, size);
@@ -68,9 +152,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
return NULL;
}
- pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
- | __WRITEABLE | flags);
-
/*
* Mappings have to be page-aligned
*/
@@ -85,8 +166,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
if (!area)
return NULL;
addr = area->addr;
- if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
- phys_addr, pgprot)) {
+ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
vunmap(addr);
return NULL;
}
diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c
index c78ba3025af..3df36eda75a 100644
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -200,7 +200,7 @@ static int __init mv643xx_eth_add_pds(void)
int ret;
get_mac(mac);
- eth_mac_add(eth1_mac_addr, mac, 0);
+ eth_mac_add(eth0_mac_addr, mac, 0);
eth_mac_add(eth1_mac_addr, mac, 1);
eth_mac_add(eth2_mac_addr, mac, 2);
ret = platform_add_devices(mv643xx_eth_pd_devs,
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
index 0ab8d231cf7..024aef25f37 100644
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -200,7 +200,7 @@ static int __init mv643xx_eth_add_pds(void)
int ret;
get_mac(mac);
- eth_mac_add(eth1_mac_addr, mac, 0);
+ eth_mac_add(eth0_mac_addr, mac, 0);
eth_mac_add(eth1_mac_addr, mac, 1);
eth_mac_add(eth2_mac_addr, mac, 2);
ret = platform_add_devices(mv643xx_eth_pd_devs,
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
index 8e381d44757..fac8b249938 100644
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -174,7 +174,7 @@ static int __init mv643xx_eth_add_pds(void)
int ret;
get_mac(mac);
- eth_mac_add(eth1_mac_addr, mac, 0);
+ eth_mac_add(eth0_mac_addr, mac, 0);
eth_mac_add(eth1_mac_addr, mac, 1);
ret = platform_add_devices(mv643xx_eth_pd_devs,
ARRAY_SIZE(mv643xx_eth_pd_devs));
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 0f44a6a6675..59eef403c60 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Sun Feb 11 23:47:40 2007
+# Linux kernel version: 2.6.21-rc1
+# Mon Feb 26 10:45:21 2007
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -41,6 +41,7 @@ CONFIG_LOCALVERSION=""
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
@@ -322,6 +323,7 @@ CONFIG_CONNECTOR=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -787,6 +789,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_I2C_SIS5595 is not set
@@ -833,6 +836,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -874,6 +878,11 @@ CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -887,16 +896,22 @@ CONFIG_HWMON=y
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
CONFIG_FB_DDC=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
+
+#
+# Frambuffer hardware drivers
+#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_ASILIANT is not set
@@ -908,9 +923,11 @@ CONFIG_FB_TILEBLITTING=y
# CONFIG_FB_MATROX is not set
CONFIG_FB_RADEON=y
CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_BACKLIGHT is not set
# CONFIG_FB_RADEON_DEBUG is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
@@ -947,7 +964,6 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_SUN_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -1192,6 +1208,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1445,9 +1462,11 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_LOG_BUF_SHIFT=18
CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -1465,6 +1484,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_STACK_DEBUG is not set
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index b5ff3ee5ace..c443db18437 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -109,6 +109,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
return ent;
}
+#ifdef CONFIG_PCI_MSI
static void virt_irq_free(unsigned int virt_irq)
{
unsigned int real_irq;
@@ -121,6 +122,7 @@ static void virt_irq_free(unsigned int virt_irq)
__bucket(real_irq)->virt_irq = 0;
}
+#endif
static unsigned int virt_to_real_irq(unsigned char virt_irq)
{
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 6b740eb6fe7..6fedfb98f8b 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -668,7 +668,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
void arch_teardown_msi_irq(unsigned int virt_irq)
{
- struct msi_desc *entry = get_irq_data(virt_irq);
+ struct msi_desc *entry = get_irq_msi(virt_irq);
struct pci_dev *pdev = entry->dev;
struct pcidev_cookie *pcp = pdev->sysdata;
struct pci_pbm_info *pbm = pcp->pbm;
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 9f5dac64aa8..ed4350ced3d 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -675,6 +675,9 @@ END(invalidate_interrupt\num)
ENTRY(call_function_interrupt)
apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
END(call_function_interrupt)
+ENTRY(irq_move_cleanup_interrupt)
+ apicinterrupt IRQ_MOVE_CLEANUP_VECTOR,smp_irq_move_cleanup_interrupt
+END(irq_move_cleanup_interrupt)
#endif
ENTRY(apic_timer_interrupt)
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 01e2cf0bdeb..21d95b74743 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -299,7 +299,7 @@ void init_8259A(int auto_eoi)
* outb_p - this has to work on a wide range of PC hardware.
*/
outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
- outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+ outb_p(IRQ0_VECTOR, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
if (auto_eoi)
outb_p(0x03, 0x21); /* master does Auto EOI */
@@ -307,7 +307,7 @@ void init_8259A(int auto_eoi)
outb_p(0x01, 0x21); /* master expects normal EOI */
outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
- outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+ outb_p(IRQ8_VECTOR, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
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) */
@@ -398,24 +398,24 @@ device_initcall(i8259A_init_sysfs);
static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
- [0 ... FIRST_EXTERNAL_VECTOR - 1] = -1,
- [FIRST_EXTERNAL_VECTOR + 0] = 0,
- [FIRST_EXTERNAL_VECTOR + 1] = 1,
- [FIRST_EXTERNAL_VECTOR + 2] = 2,
- [FIRST_EXTERNAL_VECTOR + 3] = 3,
- [FIRST_EXTERNAL_VECTOR + 4] = 4,
- [FIRST_EXTERNAL_VECTOR + 5] = 5,
- [FIRST_EXTERNAL_VECTOR + 6] = 6,
- [FIRST_EXTERNAL_VECTOR + 7] = 7,
- [FIRST_EXTERNAL_VECTOR + 8] = 8,
- [FIRST_EXTERNAL_VECTOR + 9] = 9,
- [FIRST_EXTERNAL_VECTOR + 10] = 10,
- [FIRST_EXTERNAL_VECTOR + 11] = 11,
- [FIRST_EXTERNAL_VECTOR + 12] = 12,
- [FIRST_EXTERNAL_VECTOR + 13] = 13,
- [FIRST_EXTERNAL_VECTOR + 14] = 14,
- [FIRST_EXTERNAL_VECTOR + 15] = 15,
- [FIRST_EXTERNAL_VECTOR + 16 ... NR_VECTORS - 1] = -1
+ [0 ... IRQ0_VECTOR - 1] = -1,
+ [IRQ0_VECTOR] = 0,
+ [IRQ1_VECTOR] = 1,
+ [IRQ2_VECTOR] = 2,
+ [IRQ3_VECTOR] = 3,
+ [IRQ4_VECTOR] = 4,
+ [IRQ5_VECTOR] = 5,
+ [IRQ6_VECTOR] = 6,
+ [IRQ7_VECTOR] = 7,
+ [IRQ8_VECTOR] = 8,
+ [IRQ9_VECTOR] = 9,
+ [IRQ10_VECTOR] = 10,
+ [IRQ11_VECTOR] = 11,
+ [IRQ12_VECTOR] = 12,
+ [IRQ13_VECTOR] = 13,
+ [IRQ14_VECTOR] = 14,
+ [IRQ15_VECTOR] = 15,
+ [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
};
void __init init_ISA_irqs (void)
@@ -450,6 +450,7 @@ void spurious_interrupt(void);
void error_interrupt(void);
void reschedule_interrupt(void);
void call_function_interrupt(void);
+void irq_move_cleanup_interrupt(void);
void invalidate_interrupt0(void);
void invalidate_interrupt1(void);
void invalidate_interrupt2(void);
@@ -520,12 +521,6 @@ void __init init_IRQ(void)
#ifdef CONFIG_SMP
/*
- * IRQ0 must be given a fixed assignment and initialized,
- * because it's used before the IO-APIC is set up.
- */
- __get_cpu_var(vector_irq)[FIRST_DEVICE_VECTOR] = 0;
-
- /*
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
*/
@@ -543,7 +538,10 @@ void __init init_IRQ(void)
/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
-#endif
+
+ /* Low priority IPI to cleanup after moving an irq */
+ set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
+#endif
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 950682f3576..48593f6b708 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -36,6 +36,7 @@
#include <acpi/acpi_bus.h>
#endif
+#include <asm/idle.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/desc.h>
@@ -47,7 +48,35 @@
#include <asm/msidef.h>
#include <asm/hypertransport.h>
-static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result);
+struct irq_cfg {
+ cpumask_t domain;
+ cpumask_t old_domain;
+ unsigned move_cleanup_count;
+ u8 vector;
+ u8 move_in_progress : 1;
+};
+
+/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
+struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
+ [0] = { .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, },
+ [1] = { .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR, },
+ [2] = { .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR, },
+ [3] = { .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR, },
+ [4] = { .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR, },
+ [5] = { .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR, },
+ [6] = { .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR, },
+ [7] = { .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR, },
+ [8] = { .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR, },
+ [9] = { .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR, },
+ [10] = { .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
+ [11] = { .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
+ [12] = { .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
+ [13] = { .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
+ [14] = { .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
+ [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
+};
+
+static int assign_irq_vector(int irq, cpumask_t mask);
#define __apicdebuginit __init
@@ -74,7 +103,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
* Rough estimation of how many shared IRQs there are, can
* be changed anytime.
*/
-#define MAX_PLUS_SHARED_IRQS NR_IRQ_VECTORS
+#define MAX_PLUS_SHARED_IRQS NR_IRQS
#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
/*
@@ -149,11 +178,11 @@ static inline void io_apic_sync(unsigned int apic)
reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \
reg ACTION; \
io_apic_modify(entry->apic, reg); \
+ FINAL; \
if (!entry->next) \
break; \
entry = irq_2_pin + entry->next; \
} \
- FINAL; \
}
union entry_union {
@@ -237,21 +266,19 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
{
+ struct irq_cfg *cfg = irq_cfg + irq;
unsigned long flags;
unsigned int dest;
cpumask_t tmp;
- int vector;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
- tmp = TARGET_CPUS;
-
- cpus_and(mask, tmp, CPU_MASK_ALL);
+ return;
- vector = assign_irq_vector(irq, mask, &tmp);
- if (vector < 0)
+ if (assign_irq_vector(irq, mask))
return;
+ cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
/*
@@ -260,8 +287,8 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
dest = SET_APIC_LOGICAL_ID(dest);
spin_lock_irqsave(&ioapic_lock, flags);
- __target_IO_APIC_irq(irq, dest, vector);
- set_native_irq_info(irq, mask);
+ __target_IO_APIC_irq(irq, dest, cfg->vector);
+ irq_desc[irq].affinity = mask;
spin_unlock_irqrestore(&ioapic_lock, flags);
}
#endif
@@ -615,63 +642,7 @@ static int pin_2_irq(int idx, int apic, int pin)
return irq;
}
-static inline int IO_APIC_irq_trigger(int irq)
-{
- int apic, idx, pin;
-
- for (apic = 0; apic < nr_ioapics; apic++) {
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
- idx = find_irq_entry(apic,pin,mp_INT);
- if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin)))
- return irq_trigger(idx);
- }
- }
- /*
- * nonexistent IRQs are edge default
- */
- return 0;
-}
-
-/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = {
- [0] = FIRST_EXTERNAL_VECTOR + 0,
- [1] = FIRST_EXTERNAL_VECTOR + 1,
- [2] = FIRST_EXTERNAL_VECTOR + 2,
- [3] = FIRST_EXTERNAL_VECTOR + 3,
- [4] = FIRST_EXTERNAL_VECTOR + 4,
- [5] = FIRST_EXTERNAL_VECTOR + 5,
- [6] = FIRST_EXTERNAL_VECTOR + 6,
- [7] = FIRST_EXTERNAL_VECTOR + 7,
- [8] = FIRST_EXTERNAL_VECTOR + 8,
- [9] = FIRST_EXTERNAL_VECTOR + 9,
- [10] = FIRST_EXTERNAL_VECTOR + 10,
- [11] = FIRST_EXTERNAL_VECTOR + 11,
- [12] = FIRST_EXTERNAL_VECTOR + 12,
- [13] = FIRST_EXTERNAL_VECTOR + 13,
- [14] = FIRST_EXTERNAL_VECTOR + 14,
- [15] = FIRST_EXTERNAL_VECTOR + 15,
-};
-
-static cpumask_t irq_domain[NR_IRQ_VECTORS] __read_mostly = {
- [0] = CPU_MASK_ALL,
- [1] = CPU_MASK_ALL,
- [2] = CPU_MASK_ALL,
- [3] = CPU_MASK_ALL,
- [4] = CPU_MASK_ALL,
- [5] = CPU_MASK_ALL,
- [6] = CPU_MASK_ALL,
- [7] = CPU_MASK_ALL,
- [8] = CPU_MASK_ALL,
- [9] = CPU_MASK_ALL,
- [10] = CPU_MASK_ALL,
- [11] = CPU_MASK_ALL,
- [12] = CPU_MASK_ALL,
- [13] = CPU_MASK_ALL,
- [14] = CPU_MASK_ALL,
- [15] = CPU_MASK_ALL,
-};
-
-static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
+static int __assign_irq_vector(int irq, cpumask_t mask)
{
/*
* NOTE! The local APIC isn't very good at handling
@@ -685,20 +656,25 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
* 0x80, because int 0x80 is hm, kind of importantish. ;)
*/
static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
- int old_vector = -1;
+ unsigned int old_vector;
int cpu;
+ struct irq_cfg *cfg;
- BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
+ BUG_ON((unsigned)irq >= NR_IRQS);
+ cfg = &irq_cfg[irq];
/* Only try and allocate irqs on cpus that are present */
cpus_and(mask, mask, cpu_online_map);
- if (irq_vector[irq] > 0)
- old_vector = irq_vector[irq];
- if (old_vector > 0) {
- cpus_and(*result, irq_domain[irq], mask);
- if (!cpus_empty(*result))
- return old_vector;
+ if ((cfg->move_in_progress) || cfg->move_cleanup_count)
+ return -EBUSY;
+
+ old_vector = cfg->vector;
+ if (old_vector) {
+ cpumask_t tmp;
+ cpus_and(tmp, cfg->domain, mask);
+ if (!cpus_empty(tmp))
+ return 0;
}
for_each_cpu_mask(cpu, mask) {
@@ -728,48 +704,47 @@ next:
/* Found one! */
current_vector = vector;
current_offset = offset;
- if (old_vector >= 0) {
- cpumask_t old_mask;
- int old_cpu;
- cpus_and(old_mask, irq_domain[irq], cpu_online_map);
- for_each_cpu_mask(old_cpu, old_mask)
- per_cpu(vector_irq, old_cpu)[old_vector] = -1;
+ if (old_vector) {
+ cfg->move_in_progress = 1;
+ cfg->old_domain = cfg->domain;
}
for_each_cpu_mask(new_cpu, new_mask)
per_cpu(vector_irq, new_cpu)[vector] = irq;
- irq_vector[irq] = vector;
- irq_domain[irq] = domain;
- cpus_and(*result, domain, mask);
- return vector;
+ cfg->vector = vector;
+ cfg->domain = domain;
+ return 0;
}
return -ENOSPC;
}
-static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
+static int assign_irq_vector(int irq, cpumask_t mask)
{
- int vector;
+ int err;
unsigned long flags;
spin_lock_irqsave(&vector_lock, flags);
- vector = __assign_irq_vector(irq, mask, result);
+ err = __assign_irq_vector(irq, mask);
spin_unlock_irqrestore(&vector_lock, flags);
- return vector;
+ return err;
}
static void __clear_irq_vector(int irq)
{
+ struct irq_cfg *cfg;
cpumask_t mask;
int cpu, vector;
- BUG_ON(!irq_vector[irq]);
+ BUG_ON((unsigned)irq >= NR_IRQS);
+ cfg = &irq_cfg[irq];
+ BUG_ON(!cfg->vector);
- vector = irq_vector[irq];
- cpus_and(mask, irq_domain[irq], cpu_online_map);
+ vector = cfg->vector;
+ cpus_and(mask, cfg->domain, cpu_online_map);
for_each_cpu_mask(cpu, mask)
per_cpu(vector_irq, cpu)[vector] = -1;
- irq_vector[irq] = 0;
- irq_domain[irq] = CPU_MASK_NONE;
+ cfg->vector = 0;
+ cfg->domain = CPU_MASK_NONE;
}
void __setup_vector_irq(int cpu)
@@ -779,10 +754,10 @@ void __setup_vector_irq(int cpu)
int irq, vector;
/* Mark the inuse vectors */
- for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) {
- if (!cpu_isset(cpu, irq_domain[irq]))
+ for (irq = 0; irq < NR_IRQS; ++irq) {
+ if (!cpu_isset(cpu, irq_cfg[irq].domain))
continue;
- vector = irq_vector[irq];
+ vector = irq_cfg[irq].vector;
per_cpu(vector_irq, cpu)[vector] = irq;
}
/* Mark the free vectors */
@@ -790,36 +765,46 @@ void __setup_vector_irq(int cpu)
irq = per_cpu(vector_irq, cpu)[vector];
if (irq < 0)
continue;
- if (!cpu_isset(cpu, irq_domain[irq]))
+ if (!cpu_isset(cpu, irq_cfg[irq].domain))
per_cpu(vector_irq, cpu)[vector] = -1;
}
}
-extern void (*interrupt[NR_IRQS])(void);
-
static struct irq_chip ioapic_chip;
-#define IOAPIC_AUTO -1
-#define IOAPIC_EDGE 0
-#define IOAPIC_LEVEL 1
-
-static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
+static void ioapic_register_intr(int irq, unsigned long trigger)
{
- if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
- trigger == IOAPIC_LEVEL)
+ if (trigger)
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_fasteoi_irq, "fasteoi");
else
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_edge_irq, "edge");
}
-static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq)
+
+static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
+ int trigger, int polarity)
{
+ struct irq_cfg *cfg = irq_cfg + irq;
struct IO_APIC_route_entry entry;
- int vector;
+ cpumask_t mask;
unsigned long flags;
+ if (!IO_APIC_IRQ(irq))
+ return;
+
+ mask = TARGET_CPUS;
+ if (assign_irq_vector(irq, mask))
+ return;
+
+ cpus_and(mask, cfg->domain, mask);
+
+ apic_printk(APIC_VERBOSE,KERN_DEBUG
+ "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
+ "IRQ %d Mode:%i Active:%i)\n",
+ apic, mp_ioapics[apic].mpc_apicid, pin, cfg->vector,
+ irq, trigger, polarity);
/*
* add it to the IO-APIC irq-routing table:
@@ -828,41 +813,27 @@ static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq)
entry.delivery_mode = INT_DELIVERY_MODE;
entry.dest_mode = INT_DEST_MODE;
+ entry.dest = cpu_mask_to_apicid(mask);
entry.mask = 0; /* enable IRQ */
- entry.dest = cpu_mask_to_apicid(TARGET_CPUS);
-
- entry.trigger = irq_trigger(idx);
- entry.polarity = irq_polarity(idx);
+ entry.trigger = trigger;
+ entry.polarity = polarity;
+ entry.vector = cfg->vector;
- if (irq_trigger(idx)) {
- entry.trigger = 1;
+ /* Mask level triggered irqs.
+ * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
+ */
+ if (trigger)
entry.mask = 1;
- entry.dest = cpu_mask_to_apicid(TARGET_CPUS);
- }
-
- if (!apic && !IO_APIC_IRQ(irq))
- return;
-
- if (IO_APIC_IRQ(irq)) {
- cpumask_t mask;
- vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
- if (vector < 0)
- return;
-
- entry.dest = cpu_mask_to_apicid(mask);
- entry.vector = vector;
- ioapic_register_intr(irq, vector, IOAPIC_AUTO);
- if (!apic && (irq < 16))
- disable_8259A_irq(irq);
- }
+ ioapic_register_intr(irq, trigger);
+ if (irq < 16)
+ disable_8259A_irq(irq);
ioapic_write_entry(apic, pin, entry);
spin_lock_irqsave(&ioapic_lock, flags);
- set_native_irq_info(irq, TARGET_CPUS);
+ irq_desc[irq].affinity = TARGET_CPUS;
spin_unlock_irqrestore(&ioapic_lock, flags);
-
}
static void __init setup_IO_APIC_irqs(void)
@@ -887,8 +858,8 @@ static void __init setup_IO_APIC_irqs(void)
irq = pin_2_irq(idx, apic, pin);
add_pin_to_irq(irq, apic, pin);
- setup_IO_APIC_irq(apic, pin, idx, irq);
-
+ setup_IO_APIC_irq(apic, pin, irq,
+ irq_trigger(idx), irq_polarity(idx));
}
}
@@ -1373,16 +1344,15 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
static int ioapic_retrigger_irq(unsigned int irq)
{
+ struct irq_cfg *cfg = &irq_cfg[irq];
cpumask_t mask;
- unsigned vector;
unsigned long flags;
spin_lock_irqsave(&vector_lock, flags);
- vector = irq_vector[irq];
cpus_clear(mask);
- cpu_set(first_cpu(irq_domain[irq]), mask);
+ cpu_set(first_cpu(cfg->domain), mask);
- send_IPI_mask(mask, vector);
+ send_IPI_mask(mask, cfg->vector);
spin_unlock_irqrestore(&vector_lock, flags);
return 1;
@@ -1397,8 +1367,68 @@ static int ioapic_retrigger_irq(unsigned int irq)
* races.
*/
+#ifdef CONFIG_SMP
+asmlinkage void smp_irq_move_cleanup_interrupt(void)
+{
+ unsigned vector, me;
+ ack_APIC_irq();
+ exit_idle();
+ irq_enter();
+
+ me = smp_processor_id();
+ for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
+ unsigned int irq;
+ struct irq_desc *desc;
+ struct irq_cfg *cfg;
+ irq = __get_cpu_var(vector_irq)[vector];
+ if (irq >= NR_IRQS)
+ continue;
+
+ desc = irq_desc + irq;
+ cfg = irq_cfg + irq;
+ spin_lock(&desc->lock);
+ if (!cfg->move_cleanup_count)
+ goto unlock;
+
+ if ((vector == cfg->vector) && cpu_isset(me, cfg->domain))
+ goto unlock;
+
+ __get_cpu_var(vector_irq)[vector] = -1;
+ cfg->move_cleanup_count--;
+unlock:
+ spin_unlock(&desc->lock);
+ }
+
+ irq_exit();
+}
+
+static void irq_complete_move(unsigned int irq)
+{
+ struct irq_cfg *cfg = irq_cfg + irq;
+ unsigned vector, me;
+
+ if (likely(!cfg->move_in_progress))
+ return;
+
+ vector = ~get_irq_regs()->orig_rax;
+ me = smp_processor_id();
+ if ((vector == cfg->vector) &&
+ cpu_isset(smp_processor_id(), cfg->domain)) {
+ cpumask_t cleanup_mask;
+
+ cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map);
+ cfg->move_cleanup_count = cpus_weight(cleanup_mask);
+ send_IPI_mask(cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR);
+ cfg->move_in_progress = 0;
+ }
+}
+#else
+static inline void irq_complete_move(unsigned int irq) {}
+#endif
+
static void ack_apic_edge(unsigned int irq)
{
+ irq_complete_move(irq);
move_native_irq(irq);
ack_APIC_irq();
}
@@ -1407,6 +1437,7 @@ static void ack_apic_level(unsigned int irq)
{
int do_unmask_irq = 0;
+ irq_complete_move(irq);
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
/* If we are moving the irq we need to mask it */
if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
@@ -1457,7 +1488,7 @@ static inline void init_IO_APIC_traps(void)
*/
for (irq = 0; irq < NR_IRQS ; irq++) {
int tmp = irq;
- if (IO_APIC_IRQ(tmp) && !irq_vector[tmp]) {
+ if (IO_APIC_IRQ(tmp) && !irq_cfg[tmp].vector) {
/*
* Hmm.. We don't have an entry for this,
* so default to an old-fashioned 8259
@@ -1596,15 +1627,14 @@ static inline void unlock_ExtINT_logic(void)
*/
static inline void check_timer(void)
{
+ struct irq_cfg *cfg = irq_cfg + 0;
int apic1, pin1, apic2, pin2;
- int vector;
- cpumask_t mask;
/*
* get/set the timer IRQ vector:
*/
disable_8259A_irq(0);
- vector = assign_irq_vector(0, TARGET_CPUS, &mask);
+ assign_irq_vector(0, TARGET_CPUS);
/*
* Subtle, code in do_timer_interrupt() expects an AEOI
@@ -1624,7 +1654,7 @@ static inline void check_timer(void)
apic2 = ioapic_i8259.apic;
apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
- vector, apic1, pin1, apic2, pin2);
+ cfg->vector, apic1, pin1, apic2, pin2);
if (pin1 != -1) {
/*
@@ -1655,7 +1685,7 @@ static inline void check_timer(void)
/*
* legacy devices should be connected to IO APIC #0
*/
- setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
+ setup_ExtINT_IRQ0_pin(apic2, pin2, cfg->vector);
if (timer_irq_works()) {
apic_printk(APIC_VERBOSE," works.\n");
nmi_watchdog_default();
@@ -1680,14 +1710,14 @@ static inline void check_timer(void)
disable_8259A_irq(0);
irq_desc[0].chip = &lapic_irq_type;
- apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
+ apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
enable_8259A_irq(0);
if (timer_irq_works()) {
apic_printk(APIC_VERBOSE," works.\n");
return;
}
- apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
+ apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
apic_printk(APIC_VERBOSE," failed.\n");
apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ...");
@@ -1834,19 +1864,16 @@ int create_irq(void)
/* Allocate an unused irq */
int irq;
int new;
- int vector = 0;
unsigned long flags;
- cpumask_t mask;
irq = -ENOSPC;
spin_lock_irqsave(&vector_lock, flags);
for (new = (NR_IRQS - 1); new >= 0; new--) {
if (platform_legacy_irq(new))
continue;
- if (irq_vector[new] != 0)
+ if (irq_cfg[new].vector != 0)
continue;
- vector = __assign_irq_vector(new, TARGET_CPUS, &mask);
- if (likely(vector > 0))
+ if (__assign_irq_vector(new, TARGET_CPUS) == 0)
irq = new;
break;
}
@@ -1875,12 +1902,15 @@ void destroy_irq(unsigned int irq)
#ifdef CONFIG_PCI_MSI
static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
{
- int vector;
+ struct irq_cfg *cfg = irq_cfg + irq;
+ int err;
unsigned dest;
cpumask_t tmp;
- vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
- if (vector >= 0) {
+ tmp = TARGET_CPUS;
+ err = assign_irq_vector(irq, tmp);
+ if (!err) {
+ cpus_and(tmp, cfg->domain, tmp);
dest = cpu_mask_to_apicid(tmp);
msg->address_hi = MSI_ADDR_BASE_HI;
@@ -1900,40 +1930,38 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
((INT_DELIVERY_MODE != dest_LowestPrio) ?
MSI_DATA_DELIVERY_FIXED:
MSI_DATA_DELIVERY_LOWPRI) |
- MSI_DATA_VECTOR(vector);
+ MSI_DATA_VECTOR(cfg->vector);
}
- return vector;
+ return err;
}
#ifdef CONFIG_SMP
static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
{
+ struct irq_cfg *cfg = irq_cfg + irq;
struct msi_msg msg;
unsigned int dest;
cpumask_t tmp;
- int vector;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
- tmp = TARGET_CPUS;
-
- cpus_and(mask, tmp, CPU_MASK_ALL);
+ return;
- vector = assign_irq_vector(irq, mask, &tmp);
- if (vector < 0)
+ if (assign_irq_vector(irq, mask))
return;
+ cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
read_msi_msg(irq, &msg);
msg.data &= ~MSI_DATA_VECTOR_MASK;
- msg.data |= MSI_DATA_VECTOR(vector);
+ msg.data |= MSI_DATA_VECTOR(cfg->vector);
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
write_msi_msg(irq, &msg);
- set_native_irq_info(irq, mask);
+ irq_desc[irq].affinity = mask;
}
#endif /* CONFIG_SMP */
@@ -2004,24 +2032,22 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
{
+ struct irq_cfg *cfg = irq_cfg + irq;
unsigned int dest;
cpumask_t tmp;
- int vector;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
- tmp = TARGET_CPUS;
-
- cpus_and(mask, tmp, CPU_MASK_ALL);
+ return;
- vector = assign_irq_vector(irq, mask, &tmp);
- if (vector < 0)
+ if (assign_irq_vector(irq, mask))
return;
+ cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
- target_ht_irq(irq, dest, vector);
- set_native_irq_info(irq, mask);
+ target_ht_irq(irq, dest, cfg->vector);
+ irq_desc[irq].affinity = mask;
}
#endif
@@ -2038,14 +2064,17 @@ static struct irq_chip ht_irq_chip = {
int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
{
- int vector;
+ struct irq_cfg *cfg = irq_cfg + irq;
+ int err;
cpumask_t tmp;
- vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
- if (vector >= 0) {
+ tmp = TARGET_CPUS;
+ err = assign_irq_vector(irq, tmp);
+ if (!err) {
struct ht_irq_msg msg;
unsigned dest;
+ cpus_and(tmp, cfg->domain, tmp);
dest = cpu_mask_to_apicid(tmp);
msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
@@ -2053,7 +2082,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
msg.address_lo =
HT_IRQ_LOW_BASE |
HT_IRQ_LOW_DEST_ID(dest) |
- HT_IRQ_LOW_VECTOR(vector) |
+ HT_IRQ_LOW_VECTOR(cfg->vector) |
((INT_DEST_MODE == 0) ?
HT_IRQ_LOW_DM_PHYSICAL :
HT_IRQ_LOW_DM_LOGICAL) |
@@ -2068,7 +2097,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
set_irq_chip_and_handler_name(irq, &ht_irq_chip,
handle_edge_irq, "edge");
}
- return vector;
+ return err;
}
#endif /* CONFIG_HT_IRQ */
@@ -2095,11 +2124,6 @@ int __init io_apic_get_redir_entries (int ioapic)
int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
{
- struct IO_APIC_route_entry entry;
- unsigned long flags;
- int vector;
- cpumask_t mask;
-
if (!IO_APIC_IRQ(irq)) {
apic_printk(APIC_QUIET,KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
ioapic);
@@ -2112,42 +2136,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
if (irq >= 16)
add_pin_to_irq(irq, ioapic, pin);
-
- vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
- if (vector < 0)
- return vector;
-
- /*
- * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
- * Note that we mask (disable) IRQs now -- these get enabled when the
- * corresponding device driver registers for this IRQ.
- */
-
- memset(&entry,0,sizeof(entry));
-
- entry.delivery_mode = INT_DELIVERY_MODE;
- entry.dest_mode = INT_DEST_MODE;
- entry.dest = cpu_mask_to_apicid(mask);
- entry.trigger = triggering;
- entry.polarity = polarity;
- entry.mask = 1; /* Disabled (masked) */
- entry.vector = vector & 0xff;
-
- apic_printk(APIC_VERBOSE,KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
- "IRQ %d Mode:%i Active:%i)\n", ioapic,
- mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
- triggering, polarity);
-
- ioapic_register_intr(irq, entry.vector, triggering);
-
- if (!ioapic && (irq < 16))
- disable_8259A_irq(irq);
-
- ioapic_write_entry(ioapic, pin, entry);
-
- spin_lock_irqsave(&ioapic_lock, flags);
- set_native_irq_info(irq, TARGET_CPUS);
- spin_unlock_irqrestore(&ioapic_lock, flags);
+ setup_IO_APIC_irq(ioapic, pin, irq, triggering, polarity);
return 0;
}
@@ -2179,8 +2168,10 @@ void __init setup_ioapic_dest(void)
* when you have too many devices, because at that time only boot
* cpu is online.
*/
- if(!irq_vector[irq])
- setup_IO_APIC_irq(ioapic, pin, irq_entry, irq);
+ if (!irq_cfg[irq].vector)
+ setup_IO_APIC_irq(ioapic, pin, irq,
+ irq_trigger(irq_entry),
+ irq_polarity(irq_entry));
else
set_ioapic_affinity_irq(irq, TARGET_CPUS);
}
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 1417e5cd4c6..d5968128be2 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -840,48 +840,6 @@ void class_device_destroy(struct class *cls, dev_t devt)
class_device_unregister(class_dev);
}
-int class_device_rename(struct class_device *class_dev, char *new_name)
-{
- int error = 0;
- char *old_class_name = NULL, *new_class_name = NULL;
-
- class_dev = class_device_get(class_dev);
- if (!class_dev)
- return -EINVAL;
-
- pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
- new_name);
-
-#ifdef CONFIG_SYSFS_DEPRECATED
- if (class_dev->dev)
- old_class_name = make_class_name(class_dev->class->name,
- &class_dev->kobj);
-#endif
-
- strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
-
- error = kobject_rename(&class_dev->kobj, new_name);
-
-#ifdef CONFIG_SYSFS_DEPRECATED
- if (class_dev->dev) {
- new_class_name = make_class_name(class_dev->class->name,
- &class_dev->kobj);
- if (new_class_name)
- sysfs_create_link(&class_dev->dev->kobj,
- &class_dev->kobj, new_class_name);
- if (old_class_name)
- sysfs_remove_link(&class_dev->dev->kobj,
- old_class_name);
- }
-#endif
- class_device_put(class_dev);
-
- kfree(old_class_name);
- kfree(new_class_name);
-
- return error;
-}
-
struct class_device * class_device_get(struct class_device *class_dev)
{
if (class_dev)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d04fd33dcd9..cf2a398aaaa 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -637,12 +637,41 @@ int device_add(struct device *dev)
BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_groups(dev);
GroupError:
- device_remove_attrs(dev);
+ device_remove_attrs(dev);
AttrsError:
if (dev->devt_attr) {
device_remove_file(dev, dev->devt_attr);
kfree(dev->devt_attr);
}
+
+ if (dev->class) {
+ sysfs_remove_link(&dev->kobj, "subsystem");
+ /* If this is not a "fake" compatible device, remove the
+ * symlink from the class to the device. */
+ if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
+ sysfs_remove_link(&dev->class->subsys.kset.kobj,
+ dev->bus_id);
+#ifdef CONFIG_SYSFS_DEPRECATED
+ if (parent) {
+ char *class_name = make_class_name(dev->class->name,
+ &dev->kobj);
+ if (class_name)
+ sysfs_remove_link(&dev->parent->kobj,
+ class_name);
+ kfree(class_name);
+ sysfs_remove_link(&dev->kobj, "device");
+ }
+#endif
+
+ down(&dev->class->sem);
+ /* notify any interfaces that the device is now gone */
+ list_for_each_entry(class_intf, &dev->class->interfaces, node)
+ if (class_intf->remove_dev)
+ class_intf->remove_dev(dev, class_intf);
+ /* remove the device from the class list */
+ list_del_init(&dev->node);
+ up(&dev->class->sem);
+ }
ueventattrError:
device_remove_file(dev, &dev->uevent_attr);
attrError:
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index a0d04a23dac..627f542827c 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -1,7 +1,8 @@
agpgart-y := backend.o frontend.o generic.o isoch.o
+agpgart-$(CONFIG_COMPAT) += compat_ioctl.o
+
obj-$(CONFIG_AGP) += agpgart.o
-obj-$(CONFIG_COMPAT) += compat_ioctl.o
obj-$(CONFIG_AGP_ALI) += ali-agp.o
obj-$(CONFIG_AGP_ATI) += ati-agp.o
obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 9bd68d9f0f5..fdbca25a394 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -93,12 +93,12 @@ struct aper_size_info_fixed {
struct agp_bridge_driver {
struct module *owner;
- void *aperture_sizes;
+ const void *aperture_sizes;
int num_aperture_sizes;
enum aper_size_type size_type;
int cant_use_aperture;
int needs_scratch_page;
- struct gatt_mask *masks;
+ const struct gatt_mask *masks;
int (*fetch_size)(void);
int (*configure)(void);
void (*agp_enable)(struct agp_bridge_data *, u32);
@@ -119,7 +119,7 @@ struct agp_bridge_driver {
struct agp_bridge_data {
const struct agp_version *version;
- struct agp_bridge_driver *driver;
+ const struct agp_bridge_driver *driver;
struct vm_operations_struct *vm_ops;
void *previous_size;
void *current_size;
@@ -290,7 +290,7 @@ void agp3_generic_cleanup(void);
/* aperture sizes have been standardised since v3 */
#define AGP_GENERIC_SIZES_ENTRIES 11
-extern struct aper_size_info_16 agp3_generic_sizes[];
+extern const struct aper_size_info_16 agp3_generic_sizes[];
#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 98177a93076..5b684fddcc0 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -182,7 +182,7 @@ static void m1541_destroy_page(void * addr)
/* Setup function */
-static struct aper_size_info_32 ali_generic_sizes[7] =
+static const struct aper_size_info_32 ali_generic_sizes[7] =
{
{256, 65536, 6, 10},
{128, 32768, 5, 9},
@@ -193,7 +193,7 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
{4, 1024, 0, 3}
};
-static struct agp_bridge_driver ali_generic_bridge = {
+static const struct agp_bridge_driver ali_generic_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
@@ -217,7 +217,7 @@ static struct agp_bridge_driver ali_generic_bridge = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver ali_m1541_bridge = {
+static const struct agp_bridge_driver ali_m1541_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 3d8d448bf39..e6c534e6284 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -344,7 +344,7 @@ static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
return 0;
}
-static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
+static const struct aper_size_info_lvl2 amd_irongate_sizes[7] =
{
{2048, 524288, 0x0000000c},
{1024, 262144, 0x0000000a},
@@ -355,12 +355,12 @@ static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
{32, 8192, 0x00000000}
};
-static struct gatt_mask amd_irongate_masks[] =
+static const struct gatt_mask amd_irongate_masks[] =
{
{.mask = 1, .type = 0}
};
-static struct agp_bridge_driver amd_irongate_driver = {
+static const struct agp_bridge_driver amd_irongate_driver = {
.owner = THIS_MODULE,
.aperture_sizes = amd_irongate_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 636d984ed4a..485720486d6 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -192,7 +192,7 @@ static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table)
}
-static struct aper_size_info_32 amd_8151_sizes[7] =
+static const struct aper_size_info_32 amd_8151_sizes[7] =
{
{2048, 524288, 9, 0x00000000 }, /* 0 0 0 0 0 0 */
{1024, 262144, 8, 0x00000400 }, /* 1 0 0 0 0 0 */
@@ -232,7 +232,7 @@ static void amd64_cleanup(void)
}
-static struct agp_bridge_driver amd_8151_driver = {
+static const struct agp_bridge_driver amd_8151_driver = {
.owner = THIS_MODULE,
.aperture_sizes = amd_8151_sizes,
.size_type = U32_APER_SIZE,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 77c9ad68fba..780e59e588a 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -24,7 +24,7 @@
#define ATI_GART_CACHE_ENTRY_CNTRL 0x10
-static struct aper_size_info_lvl2 ati_generic_sizes[7] =
+static const struct aper_size_info_lvl2 ati_generic_sizes[7] =
{
{2048, 524288, 0x0000000c},
{1024, 262144, 0x0000000a},
@@ -410,7 +410,7 @@ static int ati_free_gatt_table(struct agp_bridge_data *bridge)
return 0;
}
-static struct agp_bridge_driver ati_generic_bridge = {
+static const struct agp_bridge_driver ati_generic_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ati_generic_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 658cb1a72d2..df8da726285 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -59,7 +59,7 @@ static struct _efficeon_private {
unsigned long l1_table[EFFICEON_L1_SIZE];
} efficeon_private;
-static struct gatt_mask efficeon_generic_masks[] =
+static const struct gatt_mask efficeon_generic_masks[] =
{
{.mask = 0x00000001, .type = 0}
};
@@ -70,7 +70,7 @@ static inline unsigned long efficeon_mask_memory(unsigned long addr)
return addr | 0x00000001;
}
-static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
+static const struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
{
{256, 65536, 0},
{128, 32768, 32},
@@ -309,7 +309,7 @@ static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int t
}
-static struct agp_bridge_driver efficeon_driver = {
+static const struct agp_bridge_driver efficeon_driver = {
.owner = THIS_MODULE,
.aperture_sizes = efficeon_generic_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 7923337c3d2..f902d71947b 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1340,7 +1340,7 @@ void agp3_generic_cleanup(void)
}
EXPORT_SYMBOL(agp3_generic_cleanup);
-struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
+const struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
{
{4096, 1048576, 10,0x000},
{2048, 524288, 9, 0x800},
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 847deabf7f9..79f7c01db75 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -419,7 +419,7 @@ hp_zx1_enable (struct agp_bridge_data *bridge, u32 mode)
agp_device_command(command, (mode & AGP8X_MODE) != 0);
}
-struct agp_bridge_driver hp_zx1_driver = {
+struct const agp_bridge_driver hp_zx1_driver = {
.owner = THIS_MODULE,
.size_type = FIXED_APER_SIZE,
.configure = hp_zx1_configure,
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 3e7618653ab..1cde376a45e 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -78,7 +78,7 @@ static struct {
} *lp_desc;
} i460;
-static struct aper_size_info_8 i460_sizes[3] =
+static const struct aper_size_info_8 i460_sizes[3] =
{
/*
* The 32GB aperture is only available with a 4M GART page size. Due to the
@@ -550,7 +550,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
}
-struct agp_bridge_driver intel_i460_driver = {
+struct const agp_bridge_driver intel_i460_driver = {
.owner = THIS_MODULE,
.aperture_sizes = i460_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 06b0bb6d982..e542a628f1c 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -63,7 +63,7 @@ extern int agp_memory_reserved;
#define INTEL_I7505_AGPCTRL 0x70
#define INTEL_I7505_MCHCFG 0x50
-static struct aper_size_info_fixed intel_i810_sizes[] =
+static const struct aper_size_info_fixed intel_i810_sizes[] =
{
{64, 16384, 4},
/* The 32M mode still requires a 64k gatt */
@@ -1365,18 +1365,18 @@ static int intel_7505_configure(void)
}
/* Setup function */
-static struct gatt_mask intel_generic_masks[] =
+static const struct gatt_mask intel_generic_masks[] =
{
{.mask = 0x00000017, .type = 0}
};
-static struct aper_size_info_8 intel_815_sizes[2] =
+static const struct aper_size_info_8 intel_815_sizes[2] =
{
{64, 16384, 4, 0},
{32, 8192, 3, 8},
};
-static struct aper_size_info_8 intel_8xx_sizes[7] =
+static const struct aper_size_info_8 intel_8xx_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
@@ -1387,7 +1387,7 @@ static struct aper_size_info_8 intel_8xx_sizes[7] =
{4, 1024, 0, 63}
};
-static struct aper_size_info_16 intel_generic_sizes[7] =
+static const struct aper_size_info_16 intel_generic_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
@@ -1398,7 +1398,7 @@ static struct aper_size_info_16 intel_generic_sizes[7] =
{4, 1024, 0, 63}
};
-static struct aper_size_info_8 intel_830mp_sizes[4] =
+static const struct aper_size_info_8 intel_830mp_sizes[4] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
@@ -1406,7 +1406,7 @@ static struct aper_size_info_8 intel_830mp_sizes[4] =
{32, 8192, 3, 56}
};
-static struct agp_bridge_driver intel_generic_driver = {
+static const struct agp_bridge_driver intel_generic_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_generic_sizes,
.size_type = U16_APER_SIZE,
@@ -1430,7 +1430,7 @@ static struct agp_bridge_driver intel_generic_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_810_driver = {
+static const struct agp_bridge_driver intel_810_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_i810_sizes,
.size_type = FIXED_APER_SIZE,
@@ -1455,7 +1455,7 @@ static struct agp_bridge_driver intel_810_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_815_driver = {
+static const struct agp_bridge_driver intel_815_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_815_sizes,
.size_type = U8_APER_SIZE,
@@ -1479,7 +1479,7 @@ static struct agp_bridge_driver intel_815_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_830_driver = {
+static const struct agp_bridge_driver intel_830_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_i830_sizes,
.size_type = FIXED_APER_SIZE,
@@ -1504,7 +1504,7 @@ static struct agp_bridge_driver intel_830_driver = {
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
};
-static struct agp_bridge_driver intel_820_driver = {
+static const struct agp_bridge_driver intel_820_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
@@ -1528,7 +1528,7 @@ static struct agp_bridge_driver intel_820_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_830mp_driver = {
+static const struct agp_bridge_driver intel_830mp_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_830mp_sizes,
.size_type = U8_APER_SIZE,
@@ -1552,7 +1552,7 @@ static struct agp_bridge_driver intel_830mp_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_840_driver = {
+static const struct agp_bridge_driver intel_840_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
@@ -1576,7 +1576,7 @@ static struct agp_bridge_driver intel_840_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_845_driver = {
+static const struct agp_bridge_driver intel_845_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
@@ -1600,7 +1600,7 @@ static struct agp_bridge_driver intel_845_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_850_driver = {
+static const struct agp_bridge_driver intel_850_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
@@ -1624,7 +1624,7 @@ static struct agp_bridge_driver intel_850_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_860_driver = {
+static const struct agp_bridge_driver intel_860_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
@@ -1648,7 +1648,7 @@ static struct agp_bridge_driver intel_860_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver intel_915_driver = {
+static const struct agp_bridge_driver intel_915_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_i830_sizes,
.size_type = FIXED_APER_SIZE,
@@ -1673,7 +1673,7 @@ static struct agp_bridge_driver intel_915_driver = {
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
};
-static struct agp_bridge_driver intel_i965_driver = {
+static const struct agp_bridge_driver intel_i965_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_i830_sizes,
.size_type = FIXED_APER_SIZE,
@@ -1698,7 +1698,7 @@ static struct agp_bridge_driver intel_i965_driver = {
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
};
-static struct agp_bridge_driver intel_7505_driver = {
+static const struct agp_bridge_driver intel_7505_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 2563286b2fc..0c9dab557c9 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -272,7 +272,7 @@ static void nvidia_tlbflush(struct agp_memory *mem)
}
-static struct aper_size_info_8 nvidia_generic_sizes[5] =
+static const struct aper_size_info_8 nvidia_generic_sizes[5] =
{
{512, 131072, 7, 0},
{256, 65536, 6, 8},
@@ -283,13 +283,13 @@ static struct aper_size_info_8 nvidia_generic_sizes[5] =
};
-static struct gatt_mask nvidia_generic_masks[] =
+static const struct gatt_mask nvidia_generic_masks[] =
{
{ .mask = 1, .type = 0}
};
-static struct agp_bridge_driver nvidia_driver = {
+static const struct agp_bridge_driver nvidia_driver = {
.owner = THIS_MODULE,
.aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index b7b4590673a..36d07e3635c 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -210,7 +210,7 @@ parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
agp_device_command(command, (mode & AGP8X_MODE) != 0);
}
-struct agp_bridge_driver parisc_agp_driver = {
+struct const agp_bridge_driver parisc_agp_driver = {
.owner = THIS_MODULE,
.size_type = FIXED_APER_SIZE,
.configure = parisc_agp_configure,
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 92d1dc45b9b..e12773acf3d 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -247,7 +247,7 @@ static struct agp_bridge_data *sgi_tioca_find_bridge(struct pci_dev *pdev)
return bridge;
}
-struct agp_bridge_driver sgi_tioca_driver = {
+struct const agp_bridge_driver sgi_tioca_driver = {
.owner = THIS_MODULE,
.size_type = U16_APER_SIZE,
.configure = sgi_tioca_configure,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 60342b70815..125f4282d95 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -108,7 +108,7 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode)
}
}
-static struct aper_size_info_8 sis_generic_sizes[7] =
+static const struct aper_size_info_8 sis_generic_sizes[7] =
{
{256, 65536, 6, 99},
{128, 32768, 5, 83},
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 9f5ae7714f8..55212a3811f 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -385,12 +385,12 @@ static int serverworks_remove_memory(struct agp_memory *mem, off_t pg_start,
return 0;
}
-static struct gatt_mask serverworks_masks[] =
+static const struct gatt_mask serverworks_masks[] =
{
{.mask = 1, .type = 0}
};
-static struct aper_size_info_lvl2 serverworks_sizes[7] =
+static const struct aper_size_info_lvl2 serverworks_sizes[7] =
{
{2048, 524288, 0x80000000},
{1024, 262144, 0xc0000000},
@@ -423,7 +423,7 @@ static void serverworks_agp_enable(struct agp_bridge_data *bridge, u32 mode)
agp_device_command(command, 0);
}
-static struct agp_bridge_driver sworks_driver = {
+static const struct agp_bridge_driver sworks_driver = {
.owner = THIS_MODULE,
.aperture_sizes = serverworks_sizes,
.size_type = LVL2_APER_SIZE,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 6c45702e542..292b4ad1ae3 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -460,7 +460,7 @@ void null_cache_flush(void)
/* Setup function */
-static struct aper_size_info_32 uninorth_sizes[7] =
+static const struct aper_size_info_32 uninorth_sizes[7] =
{
#if 0 /* Not sure uninorth supports that high aperture sizes */
{256, 65536, 6, 64},
@@ -477,7 +477,7 @@ static struct aper_size_info_32 uninorth_sizes[7] =
* Not sure that u3 supports that high aperture sizes but it
* would strange if it did not :)
*/
-static struct aper_size_info_32 u3_sizes[8] =
+static const struct aper_size_info_32 u3_sizes[8] =
{
{512, 131072, 7, 128},
{256, 65536, 6, 64},
@@ -489,7 +489,7 @@ static struct aper_size_info_32 u3_sizes[8] =
{4, 1024, 0, 1}
};
-struct agp_bridge_driver uninorth_agp_driver = {
+struct const agp_bridge_driver uninorth_agp_driver = {
.owner = THIS_MODULE,
.aperture_sizes = (void *)uninorth_sizes,
.size_type = U32_APER_SIZE,
@@ -514,7 +514,7 @@ struct agp_bridge_driver uninorth_agp_driver = {
.cant_use_aperture = 1,
};
-struct agp_bridge_driver u3_agp_driver = {
+struct const agp_bridge_driver u3_agp_driver = {
.owner = THIS_MODULE,
.aperture_sizes = (void *)u3_sizes,
.size_type = U32_APER_SIZE,
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 2e7c04370cd..a2bb4eccaab 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -89,7 +89,7 @@ static void via_tlbflush(struct agp_memory *mem)
}
-static struct aper_size_info_8 via_generic_sizes[9] =
+static const struct aper_size_info_8 via_generic_sizes[9] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 128},
@@ -170,7 +170,7 @@ static void via_tlbflush_agp3(struct agp_memory *mem)
}
-static struct agp_bridge_driver via_agp3_driver = {
+static const struct agp_bridge_driver via_agp3_driver = {
.owner = THIS_MODULE,
.aperture_sizes = agp3_generic_sizes,
.size_type = U8_APER_SIZE,
@@ -194,7 +194,7 @@ static struct agp_bridge_driver via_agp3_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static struct agp_bridge_driver via_driver = {
+static const struct agp_bridge_driver via_driver = {
.owner = THIS_MODULE,
.aperture_sizes = via_generic_sizes,
.size_type = U8_APER_SIZE,
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 7399ba79111..80acd08f0e9 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -82,6 +82,18 @@ config LEDS_WRAP
help
This option enables support for the PCEngines WRAP programmable LEDs.
+config LEDS_H1940
+ tristate "LED Support for iPAQ H1940 device"
+ depends LEDS_CLASS && ARCH_H1940
+ help
+ This option enables support for the LEDs on the h1940.
+
+config LEDS_COBALT
+ tristate "LED Support for Cobalt Server front LED"
+ depends on LEDS_CLASS && MIPS_COBALT
+ help
+ This option enables support for the front LED on Cobalt Server
+
comment "LED Triggers"
config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 500de3dc962..aa2c18efa5b 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
+obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
+obj-$(CONFIG_LEDS_COBALT) += leds-cobalt.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
diff --git a/drivers/leds/leds-cobalt.c b/drivers/leds/leds-cobalt.c
new file mode 100644
index 00000000000..d16439ce5da
--- /dev/null
+++ b/drivers/leds/leds-cobalt.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006 - Florian Fainelli <florian@openwrt.org>
+ *
+ * Control the Cobalt Qube/RaQ front LED
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <asm/mach-cobalt/cobalt.h>
+
+static void cobalt_led_set(struct led_classdev *led_cdev, enum led_brightness brightness)
+{
+ if (brightness)
+ COBALT_LED_PORT = COBALT_LED_BAR_LEFT | COBALT_LED_BAR_RIGHT;
+ else
+ COBALT_LED_PORT = 0;
+}
+
+static struct led_classdev cobalt_led = {
+ .name = "cobalt-front-led",
+ .brightness_set = cobalt_led_set,
+ .default_trigger = "ide-disk",
+};
+
+static int __init cobalt_led_init(void)
+{
+ return led_classdev_register(NULL, &cobalt_led);
+}
+
+static void __exit cobalt_led_exit(void)
+{
+ led_classdev_unregister(&cobalt_led);
+}
+
+module_init(cobalt_led_init);
+module_exit(cobalt_led_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Front LED support for Cobalt Server");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
new file mode 100644
index 00000000000..1d49d2ade55
--- /dev/null
+++ b/drivers/leds/leds-h1940.c
@@ -0,0 +1,163 @@
+/*
+ * drivers/leds/h1940-leds.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * 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.
+ *
+ * H1940 leds driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/hardware.h>
+#include <asm/arch/h1940-latch.h>
+
+/*
+ * Green led.
+ */
+void h1940_greenled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+ switch (value) {
+ case LED_HALF:
+ h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+ s3c2410_gpio_setpin(S3C2410_GPA7,1);
+ break;
+ case LED_FULL:
+ h1940_latch_control(0,H1940_LATCH_LED_GREEN);
+ s3c2410_gpio_setpin(S3C2410_GPA7,1);
+ break;
+ default:
+ case LED_OFF:
+ h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+ h1940_latch_control(H1940_LATCH_LED_GREEN,0);
+ s3c2410_gpio_setpin(S3C2410_GPA7,0);
+ break;
+ }
+}
+
+static struct led_classdev h1940_greenled = {
+ .name = "h1940:green",
+ .brightness_set = h1940_greenled_set,
+ .default_trigger = "h1940-charger",
+};
+
+/*
+ * Red led.
+ */
+void h1940_redled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+ switch (value) {
+ case LED_HALF:
+ h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+ s3c2410_gpio_setpin(S3C2410_GPA1,1);
+ break;
+ case LED_FULL:
+ h1940_latch_control(0,H1940_LATCH_LED_RED);
+ s3c2410_gpio_setpin(S3C2410_GPA1,1);
+ break;
+ default:
+ case LED_OFF:
+ h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+ h1940_latch_control(H1940_LATCH_LED_RED,0);
+ s3c2410_gpio_setpin(S3C2410_GPA1,0);
+ break;
+ }
+}
+
+static struct led_classdev h1940_redled = {
+ .name = "h1940:red",
+ .brightness_set = h1940_redled_set,
+ .default_trigger = "h1940-charger",
+};
+
+/*
+ * Blue led.
+ * (it can only be blue flashing led)
+ */
+void h1940_blueled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+ if (value) {
+ /* flashing Blue */
+ h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+ s3c2410_gpio_setpin(S3C2410_GPA3,1);
+ } else {
+ h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+ s3c2410_gpio_setpin(S3C2410_GPA3,0);
+ }
+
+}
+
+static struct led_classdev h1940_blueled = {
+ .name = "h1940:blue",
+ .brightness_set = h1940_blueled_set,
+ .default_trigger = "h1940-bluetooth",
+};
+
+static int __init h1940leds_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = led_classdev_register(&pdev->dev, &h1940_greenled);
+ if (ret)
+ goto err_green;
+
+ ret = led_classdev_register(&pdev->dev, &h1940_redled);
+ if (ret)
+ goto err_red;
+
+ ret = led_classdev_register(&pdev->dev, &h1940_blueled);
+ if (ret)
+ goto err_blue;
+
+ return 0;
+
+err_blue:
+ led_classdev_unregister(&h1940_redled);
+err_red:
+ led_classdev_unregister(&h1940_greenled);
+err_green:
+ return ret;
+}
+
+static int h1940leds_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&h1940_greenled);
+ led_classdev_unregister(&h1940_redled);
+ led_classdev_unregister(&h1940_blueled);
+ return 0;
+}
+
+
+static struct platform_driver h1940leds_driver = {
+ .driver = {
+ .name = "h1940-leds",
+ },
+ .probe = h1940leds_probe,
+ .remove = h1940leds_remove,
+};
+
+
+static int __init h1940leds_init(void)
+{
+ return platform_driver_register(&h1940leds_driver);
+}
+
+static void __exit h1940leds_exit(void)
+{
+ platform_driver_unregister(&h1940leds_driver);
+}
+
+module_init(h1940leds_init);
+module_exit(h1940leds_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("LED driver for the iPAQ H1940");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index caca0dc9d30..f2e810f53c8 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -907,7 +907,7 @@ static int __init init_hs(void)
for (i=0; i<HS_MAX_SOCKETS; i++) {
unsigned int ret;
- hs_sockets[i].socket.dev.dev = &hd64465_device.dev;
+ hs_sockets[i].socket.dev.parent = &hd64465_device.dev;
hs_sockets[i].number = i;
ret = pcmcia_register_socket(&hs_sockets[i].socket);
if (ret && i)
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index e4a94108aab..91da15b5a81 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -760,7 +760,7 @@ static int __init init_m32r_pcc(void)
/* Set up interrupt handler(s) */
for (i = 0 ; i < pcc_sockets ; i++) {
- socket[i].socket.dev.dev = &pcc_device.dev;
+ socket[i].socket.dev.parent = &pcc_device.dev;
socket[i].socket.ops = &pcc_operations;
socket[i].socket.resource_ops = &pccard_nonstatic_ops;
socket[i].socket.owner = THIS_MODULE;
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index d059c919617..9721ed7bf50 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -1321,7 +1321,7 @@ static int __init m8xx_init(void)
socket[i].socket.ops = &m8xx_services;
socket[i].socket.resource_ops = &pccard_iodyn_ops;
socket[i].socket.cb_dev = NULL;
- socket[i].socket.dev.dev = &m8xx_device.dev;
+ socket[i].socket.dev.parent = &m8xx_device.dev;
}
for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 76f7cbc62a8..d77f75129f8 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -291,7 +291,7 @@ static int __devinit omap_cf_probe(struct device *dev)
omap_cf_present() ? "present" : "(not present)");
cf->socket.owner = THIS_MODULE;
- cf->socket.dev.dev = dev;
+ cf->socket.dev.parent = dev;
cf->socket.ops = &omap_cf_ops;
cf->socket.resource_ops = &pccard_static_ops;
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 81dfc2cac2b..ce2226273aa 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -232,7 +232,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s)
{
struct resource *res = make_resource(0, num, IORESOURCE_IO,
- s->dev.class_id);
+ s->dev.bus_id);
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 206e26c9180..eee2f1cb213 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -596,7 +596,7 @@ static int __devinit vrc4171_add_sockets(void)
}
sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot);
- socket->pcmcia_socket.dev.dev = &vrc4171_card_device.dev;
+ socket->pcmcia_socket.dev.parent = &vrc4171_card_device.dev;
socket->pcmcia_socket.ops = &vrc4171_pccard_operations;
socket->pcmcia_socket.owner = THIS_MODULE;
diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
index 3a8152906bf..35a73168333 100644
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -46,13 +46,6 @@ config SUN_VIDEOPIX
based on the Phillips SAA9051, can handle NTSC and PAL/SECAM and
SVIDEO signals.
-config SUN_AURORA
- tristate "Aurora Multiboard 1600se (EXPERIMENTAL)"
- depends on EXPERIMENTAL && BROKEN
- help
- The Aurora Multiboard is a multi-port high-speed serial controller.
- If you have one of these, say Y.
-
config TADPOLE_TS102_UCTRL
tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)"
depends on EXPERIMENTAL && SPARC32
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 3a5ea1dc789..7ab060e9a5f 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o
obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o
obj-$(CONFIG_SUN_BPP) += bpp.o
obj-$(CONFIG_SUN_VIDEOPIX) += vfc.o
-obj-$(CONFIG_SUN_AURORA) += aurora.o
obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o
obj-$(CONFIG_SUN_JSFLASH) += jsflash.o
obj-$(CONFIG_BBC_I2C) += bbc.o
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
deleted file mode 100644
index a54b4ac6756..00000000000
--- a/drivers/sbus/char/aurora.c
+++ /dev/null
@@ -1,2364 +0,0 @@
-/* $Id: aurora.c,v 1.19 2002/01/08 16:00:16 davem Exp $
- * linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
- *
- * Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
- *
- * This code is based on the RISCom/8 multiport serial driver written
- * by Dmitry Gorodchanin (pgmdsg@ibi.com), based on the Linux serial
- * driver, written by Linus Torvalds, Theodore T'so and others.
- * The Aurora multiport programming info was obtained mainly from the
- * Cirrus Logic CD180 documentation (available on the web), and by
- * doing heavy tests on the board. Many thanks to Eddie C. Dost for the
- * help on the sbus interface.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Revision 1.0
- *
- * This is the first public release.
- *
- * Most of the information you need is in the aurora.h file. Please
- * read that file before reading this one.
- *
- * Several parts of the code do not have comments yet.
- *
- * n.b. The board can support 115.2 bit rates, but only on a few
- * ports. The total badwidth of one chip (ports 0-7 or 8-15) is equal
- * to OSC_FREQ div 16. In case of my board, each chip can take 6
- * channels of 115.2 kbaud. This information is not well-tested.
- *
- * Fixed to use tty_get_baud_rate().
- * Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
- */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#ifdef AURORA_INT_DEBUG
-#include <linux/timer.h>
-#endif
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/kdebug.h>
-#include <asm/sbus.h>
-#include <asm/uaccess.h>
-
-#include "aurora.h"
-#include "cd180.h"
-
-unsigned char irqs[4] = {
- 0, 0, 0, 0
-};
-
-#ifdef AURORA_INT_DEBUG
-int irqhit=0;
-#endif
-
-static struct tty_driver *aurora_driver;
-static struct Aurora_board aurora_board[AURORA_NBOARD] = {
- {0,},
-};
-
-static struct Aurora_port aurora_port[AURORA_TNPORTS] = {
- { 0, },
-};
-
-/* no longer used. static struct Aurora_board * IRQ_to_board[16] = { NULL, } ;*/
-static unsigned char * tmp_buf = NULL;
-
-DECLARE_TASK_QUEUE(tq_aurora);
-
-static inline int aurora_paranoia_check(struct Aurora_port const * port,
- char *name, const char *routine)
-{
-#ifdef AURORA_PARANOIA_CHECK
- static const char *badmagic =
- KERN_DEBUG "aurora: Warning: bad aurora port magic number for device %s in %s\n";
- static const char *badinfo =
- KERN_DEBUG "aurora: Warning: null aurora port for device %s in %s\n";
-
- if (!port) {
- printk(badinfo, name, routine);
- return 1;
- }
- if (port->magic != AURORA_MAGIC) {
- printk(badmagic, name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-/*
- *
- * Service functions for aurora driver.
- *
- */
-
-/* Get board number from pointer */
-static inline int board_No (struct Aurora_board const * bp)
-{
- return bp - aurora_board;
-}
-
-/* Get port number from pointer */
-static inline int port_No (struct Aurora_port const * port)
-{
- return AURORA_PORT(port - aurora_port);
-}
-
-/* Get pointer to board from pointer to port */
-static inline struct Aurora_board * port_Board(struct Aurora_port const * port)
-{
- return &aurora_board[AURORA_BOARD(port - aurora_port)];
-}
-
-/* Wait for Channel Command Register ready */
-static inline void aurora_wait_CCR(struct aurora_reg128 * r)
-{
- unsigned long delay;
-
-#ifdef AURORA_DEBUG
-printk("aurora_wait_CCR\n");
-#endif
- /* FIXME: need something more descriptive than 100000 :) */
- for (delay = 100000; delay; delay--)
- if (!sbus_readb(&r->r[CD180_CCR]))
- return;
- printk(KERN_DEBUG "aurora: Timeout waiting for CCR.\n");
-}
-
-/*
- * aurora probe functions.
- */
-
-/* Must be called with enabled interrupts */
-static inline void aurora_long_delay(unsigned long delay)
-{
- unsigned long i;
-
-#ifdef AURORA_DEBUG
- printk("aurora_long_delay: start\n");
-#endif
- for (i = jiffies + delay; time_before(jiffies, i); ) ;
-#ifdef AURORA_DEBUG
- printk("aurora_long_delay: end\n");
-#endif
-}
-
-/* Reset and setup CD180 chip */
-static int aurora_init_CD180(struct Aurora_board * bp, int chip)
-{
- unsigned long flags;
- int id;
-
-#ifdef AURORA_DEBUG
- printk("aurora_init_CD180: start %d:%d\n",
- board_No(bp), chip);
-#endif
- save_flags(flags); cli();
- sbus_writeb(0, &bp->r[chip]->r[CD180_CAR]);
- sbus_writeb(0, &bp->r[chip]->r[CD180_GSVR]);
-
- /* Wait for CCR ready */
- aurora_wait_CCR(bp->r[chip]);
-
- /* Reset CD180 chip */
- sbus_writeb(CCR_HARDRESET, &bp->r[chip]->r[CD180_CCR]);
- udelay(1);
- sti();
- id=1000;
- while((--id) &&
- (sbus_readb(&bp->r[chip]->r[CD180_GSVR])!=0xff))udelay(100);
- if(!id) {
- printk(KERN_ERR "aurora%d: Chip %d failed init.\n",
- board_No(bp), chip);
- restore_flags(flags);
- return(-1);
- }
- cli();
- sbus_writeb((board_No(bp)<<5)|((chip+1)<<3),
- &bp->r[chip]->r[CD180_GSVR]); /* Set ID for this chip */
- sbus_writeb(0x80|bp->ACK_MINT,
- &bp->r[chip]->r[CD180_MSMR]); /* Prio for modem intr */
- sbus_writeb(0x80|bp->ACK_TINT,
- &bp->r[chip]->r[CD180_TSMR]); /* Prio for transmitter intr */
- sbus_writeb(0x80|bp->ACK_RINT,
- &bp->r[chip]->r[CD180_RSMR]); /* Prio for receiver intr */
- /* Setting up prescaler. We need 4 tick per 1 ms */
- sbus_writeb((bp->oscfreq/(1000000/AURORA_TPS)) >> 8,
- &bp->r[chip]->r[CD180_PPRH]);
- sbus_writeb((bp->oscfreq/(1000000/AURORA_TPS)) & 0xff,
- &bp->r[chip]->r[CD180_PPRL]);
-
- sbus_writeb(SRCR_AUTOPRI|SRCR_GLOBPRI,
- &bp->r[chip]->r[CD180_SRCR]);
-
- id = sbus_readb(&bp->r[chip]->r[CD180_GFRCR]);
- printk(KERN_INFO "aurora%d: Chip %d id %02x: ",
- board_No(bp), chip,id);
- if(sbus_readb(&bp->r[chip]->r[CD180_SRCR]) & 128) {
- switch (id) {
- case 0x82:printk("CL-CD1864 rev A\n");break;
- case 0x83:printk("CL-CD1865 rev A\n");break;
- case 0x84:printk("CL-CD1865 rev B\n");break;
- case 0x85:printk("CL-CD1865 rev C\n");break;
- default:printk("Unknown.\n");
- };
- } else {
- switch (id) {
- case 0x81:printk("CL-CD180 rev B\n");break;
- case 0x82:printk("CL-CD180 rev C\n");break;
- default:printk("Unknown.\n");
- };
- }
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_init_CD180: end\n");
-#endif
- return 0;
-}
-
-static int valid_irq(unsigned char irq)
-{
-int i;
-for(i=0;i<TYPE_1_IRQS;i++)
- if (type_1_irq[i]==irq) return 1;
-return 0;
-}
-
-static irqreturn_t aurora_interrupt(int irq, void * dev_id);
-
-/* Main probing routine, also sets irq. */
-static int aurora_probe(void)
-{
- struct sbus_bus *sbus;
- struct sbus_dev *sdev;
- int grrr;
- char buf[30];
- int bn = 0;
- struct Aurora_board *bp;
-
- for_each_sbus(sbus) {
- for_each_sbusdev(sdev, sbus) {
-/* printk("Try: %x %s\n",sdev,sdev->prom_name);*/
- if (!strcmp(sdev->prom_name, "sio16")) {
-#ifdef AURORA_DEBUG
- printk(KERN_INFO "aurora: sio16 at %p\n",sdev);
-#endif
- if((sdev->reg_addrs[0].reg_size!=1) &&
- (sdev->reg_addrs[1].reg_size!=128) &&
- (sdev->reg_addrs[2].reg_size!=128) &&
- (sdev->reg_addrs[3].reg_size!=4)) {
- printk(KERN_ERR "aurora%d: registers' sizes "
- "do not match.\n", bn);
- break;
- }
- bp = &aurora_board[bn];
- bp->r0 = (struct aurora_reg1 *)
- sbus_ioremap(&sdev->resource[0], 0,
- sdev->reg_addrs[0].reg_size,
- "sio16");
- if (bp->r0 == NULL) {
- printk(KERN_ERR "aurora%d: can't map "
- "reg_addrs[0]\n", bn);
- break;
- }
-#ifdef AURORA_DEBUG
- printk("Map reg 0: %p\n", bp->r0);
-#endif
- bp->r[0] = (struct aurora_reg128 *)
- sbus_ioremap(&sdev->resource[1], 0,
- sdev->reg_addrs[1].reg_size,
- "sio16");
- if (bp->r[0] == NULL) {
- printk(KERN_ERR "aurora%d: can't map "
- "reg_addrs[1]\n", bn);
- break;
- }
-#ifdef AURORA_DEBUG
- printk("Map reg 1: %p\n", bp->r[0]);
-#endif
- bp->r[1] = (struct aurora_reg128 *)
- sbus_ioremap(&sdev->resource[2], 0,
- sdev->reg_addrs[2].reg_size,
- "sio16");
- if (bp->r[1] == NULL) {
- printk(KERN_ERR "aurora%d: can't map "
- "reg_addrs[2]\n", bn);
- break;
- }
-#ifdef AURORA_DEBUG
- printk("Map reg 2: %p\n", bp->r[1]);
-#endif
- bp->r3 = (struct aurora_reg4 *)
- sbus_ioremap(&sdev->resource[3], 0,
- sdev->reg_addrs[3].reg_size,
- "sio16");
- if (bp->r3 == NULL) {
- printk(KERN_ERR "aurora%d: can't map "
- "reg_addrs[3]\n", bn);
- break;
- }
-#ifdef AURORA_DEBUG
- printk("Map reg 3: %p\n", bp->r3);
-#endif
- /* Variables setup */
- bp->flags = 0;
-#ifdef AURORA_DEBUG
- grrr=prom_getint(sdev->prom_node,"intr");
- printk("intr pri %d\n", grrr);
-#endif
- if ((bp->irq=irqs[bn]) && valid_irq(bp->irq) &&
- !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
- free_irq(bp->irq|0x30, bp);
- } else
- if ((bp->irq=prom_getint(sdev->prom_node, "bintr")) && valid_irq(bp->irq) &&
- !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
- free_irq(bp->irq|0x30, bp);
- } else
- if ((bp->irq=prom_getint(sdev->prom_node, "intr")) && valid_irq(bp->irq) &&
- !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
- free_irq(bp->irq|0x30, bp);
- } else
- for(grrr=0;grrr<TYPE_1_IRQS;grrr++) {
- if ((bp->irq=type_1_irq[grrr])&&!request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
- free_irq(bp->irq|0x30, bp);
- break;
- } else {
- printk(KERN_ERR "aurora%d: Could not get an irq for this board !!!\n",bn);
- bp->flags=0xff;
- }
- }
- if(bp->flags==0xff)break;
- printk(KERN_INFO "aurora%d: irq %d\n",bn,bp->irq&0x0f);
- buf[0]=0;
- grrr=prom_getproperty(sdev->prom_node,"dtr_rts",buf,sizeof(buf));
- if(!strcmp(buf,"swapped")){
- printk(KERN_INFO "aurora%d: Swapped DTR and RTS\n",bn);
- bp->DTR=MSVR_RTS;
- bp->RTS=MSVR_DTR;
- bp->MSVDTR=CD180_MSVRTS;
- bp->MSVRTS=CD180_MSVDTR;
- bp->flags|=AURORA_BOARD_DTR_FLOW_OK;
- }else{
- #ifdef AURORA_FORCE_DTR_FLOW
- printk(KERN_INFO "aurora%d: Forcing swapped DTR-RTS\n",bn);
- bp->DTR=MSVR_RTS;
- bp->RTS=MSVR_DTR;
- bp->MSVDTR=CD180_MSVRTS;
- bp->MSVRTS=CD180_MSVDTR;
- bp->flags|=AURORA_BOARD_DTR_FLOW_OK;
- #else
- printk(KERN_INFO "aurora%d: Normal DTR and RTS\n",bn);
- bp->DTR=MSVR_DTR;
- bp->RTS=MSVR_RTS;
- bp->MSVDTR=CD180_MSVDTR;
- bp->MSVRTS=CD180_MSVRTS;
- #endif
- }
- bp->oscfreq=prom_getint(sdev->prom_node,"clk")*100;
- printk(KERN_INFO "aurora%d: Oscillator: %d Hz\n",bn,bp->oscfreq);
- grrr=prom_getproperty(sdev->prom_node,"chip",buf,sizeof(buf));
- printk(KERN_INFO "aurora%d: Chips: %s\n",bn,buf);
- grrr=prom_getproperty(sdev->prom_node,"manu",buf,sizeof(buf));
- printk(KERN_INFO "aurora%d: Manufacturer: %s\n",bn,buf);
- grrr=prom_getproperty(sdev->prom_node,"model",buf,sizeof(buf));
- printk(KERN_INFO "aurora%d: Model: %s\n",bn,buf);
- grrr=prom_getproperty(sdev->prom_node,"rev",buf,sizeof(buf));
- printk(KERN_INFO "aurora%d: Revision: %s\n",bn,buf);
- grrr=prom_getproperty(sdev->prom_node,"mode",buf,sizeof(buf));
- printk(KERN_INFO "aurora%d: Mode: %s\n",bn,buf);
- #ifdef MODULE
- bp->count=0;
- #endif
- bp->flags = AURORA_BOARD_PRESENT;
- /* hardware ack */
- bp->ACK_MINT=1;
- bp->ACK_TINT=2;
- bp->ACK_RINT=3;
- bn++;
- }
- }
- }
- return bn;
-}
-
-static void aurora_release_io_range(struct Aurora_board *bp)
-{
- sbus_iounmap((unsigned long)bp->r0, 1);
- sbus_iounmap((unsigned long)bp->r[0], 128);
- sbus_iounmap((unsigned long)bp->r[1], 128);
- sbus_iounmap((unsigned long)bp->r3, 4);
-}
-
-static inline void aurora_mark_event(struct Aurora_port * port, int event)
-{
-#ifdef AURORA_DEBUG
- printk("aurora_mark_event: start\n");
-#endif
- set_bit(event, &port->event);
- queue_task(&port->tqueue, &tq_aurora);
- mark_bh(AURORA_BH);
-#ifdef AURORA_DEBUG
- printk("aurora_mark_event: end\n");
-#endif
-}
-
-static __inline__ struct Aurora_port * aurora_get_port(struct Aurora_board const * bp,
- int chip,
- unsigned char const *what)
-{
- unsigned char channel;
- struct Aurora_port * port;
-
- channel = ((chip << 3) |
- ((sbus_readb(&bp->r[chip]->r[CD180_GSCR]) & GSCR_CHAN) >> GSCR_CHAN_OFF));
- port = &aurora_port[board_No(bp) * AURORA_NPORT * AURORA_NCD180 + channel];
- if (port->flags & ASYNC_INITIALIZED)
- return port;
-
- printk(KERN_DEBUG "aurora%d: %s interrupt from invalid port %d\n",
- board_No(bp), what, channel);
- return NULL;
-}
-
-static void aurora_receive_exc(struct Aurora_board const * bp, int chip)
-{
- struct Aurora_port *port;
- struct tty_struct *tty;
- unsigned char status;
- unsigned char ch;
-
- if (!(port = aurora_get_port(bp, chip, "Receive_x")))
- return;
-
- tty = port->tty;
- if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-#ifdef AURORA_INTNORM
- printk("aurora%d: port %d: Working around flip buffer overflow.\n",
- board_No(bp), port_No(port));
-#endif
- return;
- }
-
-#ifdef AURORA_REPORT_OVERRUN
- status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]);
- if (status & RCSR_OE) {
- port->overrun++;
-#if 1
- printk("aurora%d: port %d: Overrun. Total %ld overruns.\n",
- board_No(bp), port_No(port), port->overrun);
-#endif
- }
- status &= port->mark_mask;
-#else
- status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]) & port->mark_mask;
-#endif
- ch = sbus_readb(&bp->r[chip]->r[CD180_RDR]);
- if (!status)
- return;
-
- if (status & RCSR_TOUT) {
-/* printk("aurora%d: port %d: Receiver timeout. Hardware problems ?\n",
- board_No(bp), port_No(port));*/
- return;
-
- } else if (status & RCSR_BREAK) {
- printk(KERN_DEBUG "aurora%d: port %d: Handling break...\n",
- board_No(bp), port_No(port));
- *tty->flip.flag_buf_ptr++ = TTY_BREAK;
- if (port->flags & ASYNC_SAK)
- do_SAK(tty);
-
- } else if (status & RCSR_PE)
- *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-
- else if (status & RCSR_FE)
- *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-
- else if (status & RCSR_OE)
- *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-
- else
- *tty->flip.flag_buf_ptr++ = 0;
-
- *tty->flip.char_buf_ptr++ = ch;
- tty->flip.count++;
- queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void aurora_receive(struct Aurora_board const * bp, int chip)
-{
- struct Aurora_port *port;
- struct tty_struct *tty;
- unsigned char count,cnt;
-
- if (!(port = aurora_get_port(bp, chip, "Receive")))
- return;
-
- tty = port->tty;
-
- count = sbus_readb(&bp->r[chip]->r[CD180_RDCR]);
-
-#ifdef AURORA_REPORT_FIFO
- port->hits[count > 8 ? 9 : count]++;
-#endif
-
- while (count--) {
- if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-#ifdef AURORA_INTNORM
- printk("aurora%d: port %d: Working around flip buffer overflow.\n",
- board_No(bp), port_No(port));
-#endif
- break;
- }
- cnt = sbus_readb(&bp->r[chip]->r[CD180_RDR]);
- *tty->flip.char_buf_ptr++ = cnt;
- *tty->flip.flag_buf_ptr++ = 0;
- tty->flip.count++;
- }
- queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void aurora_transmit(struct Aurora_board const * bp, int chip)
-{
- struct Aurora_port *port;
- struct tty_struct *tty;
- unsigned char count;
-
- if (!(port = aurora_get_port(bp, chip, "Transmit")))
- return;
-
- tty = port->tty;
-
- if (port->SRER & SRER_TXEMPTY) {
- /* FIFO drained */
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- port->SRER &= ~SRER_TXEMPTY;
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- return;
- }
-
- if ((port->xmit_cnt <= 0 && !port->break_length)
- || tty->stopped || tty->hw_stopped) {
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- port->SRER &= ~SRER_TXRDY;
- sbus_writeb(port->SRER,
- &bp->r[chip]->r[CD180_SRER]);
- return;
- }
-
- if (port->break_length) {
- if (port->break_length > 0) {
- if (port->COR2 & COR2_ETC) {
- sbus_writeb(CD180_C_ESC,
- &bp->r[chip]->r[CD180_TDR]);
- sbus_writeb(CD180_C_SBRK,
- &bp->r[chip]->r[CD180_TDR]);
- port->COR2 &= ~COR2_ETC;
- }
- count = min(port->break_length, 0xff);
- sbus_writeb(CD180_C_ESC,
- &bp->r[chip]->r[CD180_TDR]);
- sbus_writeb(CD180_C_DELAY,
- &bp->r[chip]->r[CD180_TDR]);
- sbus_writeb(count,
- &bp->r[chip]->r[CD180_TDR]);
- if (!(port->break_length -= count))
- port->break_length--;
- } else {
- sbus_writeb(CD180_C_ESC,
- &bp->r[chip]->r[CD180_TDR]);
- sbus_writeb(CD180_C_EBRK,
- &bp->r[chip]->r[CD180_TDR]);
- sbus_writeb(port->COR2,
- &bp->r[chip]->r[CD180_COR2]);
- aurora_wait_CCR(bp->r[chip]);
- sbus_writeb(CCR_CORCHG2,
- &bp->r[chip]->r[CD180_CCR]);
- port->break_length = 0;
- }
- return;
- }
-
- count = CD180_NFIFO;
- do {
- u8 byte = port->xmit_buf[port->xmit_tail++];
-
- sbus_writeb(byte, &bp->r[chip]->r[CD180_TDR]);
- port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
- if (--port->xmit_cnt <= 0)
- break;
- } while (--count > 0);
-
- if (port->xmit_cnt <= 0) {
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- port->SRER &= ~SRER_TXRDY;
- sbus_writeb(port->SRER,
- &bp->r[chip]->r[CD180_SRER]);
- }
- if (port->xmit_cnt <= port->wakeup_chars)
- aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-}
-
-static void aurora_check_modem(struct Aurora_board const * bp, int chip)
-{
- struct Aurora_port *port;
- struct tty_struct *tty;
- unsigned char mcr;
-
- if (!(port = aurora_get_port(bp, chip, "Modem")))
- return;
-
- tty = port->tty;
-
- mcr = sbus_readb(&bp->r[chip]->r[CD180_MCR]);
- if (mcr & MCR_CDCHG) {
- if (sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD)
- wake_up_interruptible(&port->open_wait);
- else
- schedule_task(&port->tqueue_hangup);
- }
-
-/* We don't have such things yet. My aurora board has DTR and RTS swapped, but that doesn't count in this driver. Let's hope
- * Aurora didn't made any boards with CTS or DSR broken...
- */
-/* #ifdef AURORA_BRAIN_DAMAGED_CTS
- if (mcr & MCR_CTSCHG) {
- if (aurora_in(bp, CD180_MSVR) & MSVR_CTS) {
- tty->hw_stopped = 0;
- port->SRER |= SRER_TXRDY;
- if (port->xmit_cnt <= port->wakeup_chars)
- aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
- } else {
- tty->hw_stopped = 1;
- port->SRER &= ~SRER_TXRDY;
- }
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- }
- if (mcr & MCR_DSRCHG) {
- if (aurora_in(bp, CD180_MSVR) & MSVR_DSR) {
- tty->hw_stopped = 0;
- port->SRER |= SRER_TXRDY;
- if (port->xmit_cnt <= port->wakeup_chars)
- aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
- } else {
- tty->hw_stopped = 1;
- port->SRER &= ~SRER_TXRDY;
- }
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- }
-#endif AURORA_BRAIN_DAMAGED_CTS */
-
- /* Clear change bits */
- sbus_writeb(0, &bp->r[chip]->r[CD180_MCR]);
-}
-
-/* The main interrupt processing routine */
-static irqreturn_t aurora_interrupt(int irq, void * dev_id)
-{
- unsigned char status;
- unsigned char ack,chip/*,chip_id*/;
- struct Aurora_board * bp = (struct Aurora_board *) dev_id;
- unsigned long loop = 0;
-
-#ifdef AURORA_INT_DEBUG
- printk("IRQ%d %d\n",irq,++irqhit);
-#ifdef AURORA_FLOODPRO
- if (irqhit>=AURORA_FLOODPRO)
- sbus_writeb(8, &bp->r0->r);
-#endif
-#endif
-
-/* old bp = IRQ_to_board[irq&0x0f];*/
-
- if (!bp || !(bp->flags & AURORA_BOARD_ACTIVE))
- return IRQ_NONE;
-
-/* The while() below takes care of this.
- status = sbus_readb(&bp->r[0]->r[CD180_SRSR]);
-#ifdef AURORA_INT_DEBUG
- printk("mumu: %02x\n", status);
-#endif
- if (!(status&SRSR_ANYINT))
- return IRQ_NONE; * Nobody has anything to say, so exit *
-*/
- while ((loop++ < 48) &&
- (status = sbus_readb(&bp->r[0]->r[CD180_SRSR]) & SRSR_ANYINT)){
-#ifdef AURORA_INT_DEBUG
- printk("SRSR: %02x\n", status);
-#endif
- if (status & SRSR_REXT) {
- ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);
-#ifdef AURORA_INT_DEBUG
- printk("R-ACK %02x\n", ack);
-#endif
- if ((ack >> 5) == board_No(bp)) {
- if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
- if ((ack&GSVR_ITMASK)==GSVR_IT_RGD) {
- aurora_receive(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- } else if ((ack & GSVR_ITMASK) == GSVR_IT_REXC) {
- aurora_receive_exc(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- }
- }
- }
- } else if (status & SRSR_TEXT) {
- ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);
-#ifdef AURORA_INT_DEBUG
- printk("T-ACK %02x\n", ack);
-#endif
- if ((ack >> 5) == board_No(bp)) {
- if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
- if ((ack&GSVR_ITMASK)==GSVR_IT_TX) {
- aurora_transmit(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- }
- }
- }
- } else if (status & SRSR_MEXT) {
- ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);
-#ifdef AURORA_INT_DEBUG
- printk("M-ACK %02x\n", ack);
-#endif
- if ((ack >> 5) == board_No(bp)) {
- if ((chip = ((ack>>3)&3)-1) < AURORA_NCD180) {
- if ((ack&GSVR_ITMASK)==GSVR_IT_MDM) {
- aurora_check_modem(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- }
- }
- }
- }
- }
-/* I guess this faster code can be used with CD1865, using AUROPRI and GLOBPRI. */
-#if 0
- while ((loop++ < 48)&&(status=bp->r[0]->r[CD180_SRSR]&SRSR_ANYINT)){
-#ifdef AURORA_INT_DEBUG
- printk("SRSR: %02x\n",status);
-#endif
- ack = sbus_readb(&bp->r3->r[0]);
-#ifdef AURORA_INT_DEBUG
- printk("ACK: %02x\n",ack);
-#endif
- if ((ack>>5)==board_No(bp)) {
- if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
- ack&=GSVR_ITMASK;
- if (ack==GSVR_IT_RGD) {
- aurora_receive(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- } else if (ack==GSVR_IT_REXC) {
- aurora_receive_exc(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- } else if (ack==GSVR_IT_TX) {
- aurora_transmit(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- } else if (ack==GSVR_IT_MDM) {
- aurora_check_modem(bp,chip);
- sbus_writeb(0,
- &bp->r[chip]->r[CD180_EOSRR]);
- }
- }
- }
- }
-#endif
-
-/* This is the old handling routine, used in riscom8 for only one CD180. I keep it here for reference. */
-#if 0
- for(chip=0;chip<AURORA_NCD180;chip++){
- chip_id=(board_No(bp)<<5)|((chip+1)<<3);
- loop=0;
- while ((loop++ < 1) &&
- ((status = sbus_readb(&bp->r[chip]->r[CD180_SRSR])) &
- (SRSR_TEXT | SRSR_MEXT | SRSR_REXT))) {
-
- if (status & SRSR_REXT) {
- ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);
- if (ack == (chip_id | GSVR_IT_RGD)) {
-#ifdef AURORA_INTMSG
- printk("RX ACK\n");
-#endif
- aurora_receive(bp,chip);
- } else if (ack == (chip_id | GSVR_IT_REXC)) {
-#ifdef AURORA_INTMSG
- printk("RXC ACK\n");
-#endif
- aurora_receive_exc(bp,chip);
- } else {
-#ifdef AURORA_INTNORM
- printk("aurora%d-%d: Bad receive ack 0x%02x.\n",
- board_No(bp), chip, ack);
-#endif
- }
- } else if (status & SRSR_TEXT) {
- ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);
- if (ack == (chip_id | GSVR_IT_TX)){
-#ifdef AURORA_INTMSG
- printk("TX ACK\n");
-#endif
- aurora_transmit(bp,chip);
- } else {
-#ifdef AURORA_INTNORM
- printk("aurora%d-%d: Bad transmit ack 0x%02x.\n",
- board_No(bp), chip, ack);
-#endif
- }
- } else if (status & SRSR_MEXT) {
- ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);
- if (ack == (chip_id | GSVR_IT_MDM)){
-#ifdef AURORA_INTMSG
- printk("MDM ACK\n");
-#endif
- aurora_check_modem(bp,chip);
- } else {
-#ifdef AURORA_INTNORM
- printk("aurora%d-%d: Bad modem ack 0x%02x.\n",
- board_No(bp), chip, ack);
-#endif
- }
- }
- sbus_writeb(0, &bp->r[chip]->r[CD180_EOSRR]);
- }
- }
-#endif
-
- return IRQ_HANDLED;
-}
-
-#ifdef AURORA_INT_DEBUG
-static void aurora_timer (unsigned long ignored);
-
-static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0);
-
-static void
-aurora_timer (unsigned long ignored)
-{
- unsigned long flags;
- int i;
-
- save_flags(flags); cli();
-
- printk("SRSR: %02x,%02x - ",
- sbus_readb(&aurora_board[0].r[0]->r[CD180_SRSR]),
- sbus_readb(&aurora_board[0].r[1]->r[CD180_SRSR]));
- for (i = 0; i < 4; i++) {
- udelay(1);
- printk("%02x ",
- sbus_readb(&aurora_board[0].r3->r[i]));
- }
- printk("\n");
-
- aurora_poll_timer.expires = jiffies + 300;
- add_timer (&aurora_poll_timer);
-
- restore_flags(flags);
-}
-#endif
-
-/*
- * Routines for open & close processing.
- */
-
-/* Called with disabled interrupts */
-static int aurora_setup_board(struct Aurora_board * bp)
-{
- int error;
-
-#ifdef AURORA_ALLIRQ
- int i;
- for (i = 0; i < AURORA_ALLIRQ; i++) {
- error = request_irq(allirq[i]|0x30, aurora_interrupt, IRQF_SHARED,
- "sio16", bp);
- if (error)
- printk(KERN_ERR "IRQ%d request error %d\n",
- allirq[i], error);
- }
-#else
- error = request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED,
- "sio16", bp);
- if (error) {
- printk(KERN_ERR "IRQ request error %d\n", error);
- return error;
- }
-#endif
- /* Board reset */
- sbus_writeb(0, &bp->r0->r);
- udelay(1);
- if (bp->flags & AURORA_BOARD_TYPE_2) {
- /* unknown yet */
- } else {
- sbus_writeb((AURORA_CFG_ENABLE_IO | AURORA_CFG_ENABLE_IRQ |
- (((bp->irq)&0x0f)>>2)),
- &bp->r0->r);
- }
- udelay(10000);
-
- if (aurora_init_CD180(bp,0))error=1;error=0;
- if (aurora_init_CD180(bp,1))error++;
- if (error == AURORA_NCD180) {
- printk(KERN_ERR "Both chips failed initialisation.\n");
- return -EIO;
- }
-
-#ifdef AURORA_INT_DEBUG
- aurora_poll_timer.expires= jiffies + 1;
- add_timer(&aurora_poll_timer);
-#endif
-#ifdef AURORA_DEBUG
- printk("aurora_setup_board: end\n");
-#endif
- return 0;
-}
-
-/* Called with disabled interrupts */
-static void aurora_shutdown_board(struct Aurora_board *bp)
-{
- int i;
-
-#ifdef AURORA_DEBUG
- printk("aurora_shutdown_board: start\n");
-#endif
-
-#ifdef AURORA_INT_DEBUG
- del_timer(&aurora_poll_timer);
-#endif
-
-#ifdef AURORA_ALLIRQ
- for(i=0;i<AURORA_ALLIRQ;i++){
- free_irq(allirq[i]|0x30, bp);
-/* IRQ_to_board[allirq[i]&0xf] = NULL;*/
- }
-#else
- free_irq(bp->irq|0x30, bp);
-/* IRQ_to_board[bp->irq&0xf] = NULL;*/
-#endif
- /* Drop all DTR's */
- for(i=0;i<16;i++){
- sbus_writeb(i & 7, &bp->r[i>>3]->r[CD180_CAR]);
- udelay(1);
- sbus_writeb(0, &bp->r[i>>3]->r[CD180_MSVR]);
- udelay(1);
- }
- /* Board shutdown */
- sbus_writeb(0, &bp->r0->r);
-
-#ifdef AURORA_DEBUG
- printk("aurora_shutdown_board: end\n");
-#endif
-}
-
-/* Setting up port characteristics.
- * Must be called with disabled interrupts
- */
-static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *port)
-{
- struct tty_struct *tty;
- unsigned long baud;
- long tmp;
- unsigned char cor1 = 0, cor3 = 0;
- unsigned char mcor1 = 0, mcor2 = 0,chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_change_speed: start\n");
-#endif
- if (!(tty = port->tty) || !tty->termios)
- return;
-
- chip = AURORA_CD180(port_No(port));
-
- port->SRER = 0;
- port->COR2 = 0;
- port->MSVR = MSVR_RTS|MSVR_DTR;
-
- baud = tty_get_baud_rate(tty);
-
- /* Select port on the board */
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
-
- if (!baud) {
- /* Drop DTR & exit */
- port->MSVR &= ~(bp->DTR|bp->RTS);
- sbus_writeb(port->MSVR,
- &bp->r[chip]->r[CD180_MSVR]);
- return;
- } else {
- /* Set DTR on */
- port->MSVR |= bp->DTR;
- sbus_writeb(port->MSVR,
- &bp->r[chip]->r[CD180_MSVR]);
- }
-
- /* Now we must calculate some speed dependent things. */
-
- /* Set baud rate for port. */
- tmp = (((bp->oscfreq + baud/2) / baud +
- CD180_TPC/2) / CD180_TPC);
-
-/* tmp = (bp->oscfreq/7)/baud;
- if((tmp%10)>4)tmp=tmp/10+1;else tmp=tmp/10;*/
-/* printk("Prescaler period: %d\n",tmp);*/
-
- sbus_writeb((tmp >> 8) & 0xff,
- &bp->r[chip]->r[CD180_RBPRH]);
- sbus_writeb((tmp >> 8) & 0xff,
- &bp->r[chip]->r[CD180_TBPRH]);
- sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_RBPRL]);
- sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_TBPRL]);
-
- baud = (baud + 5) / 10; /* Estimated CPS */
-
- /* Two timer ticks seems enough to wakeup something like SLIP driver */
- tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;
- port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
- SERIAL_XMIT_SIZE - 1 : tmp);
-
- /* Receiver timeout will be transmission time for 1.5 chars */
- tmp = (AURORA_TPS + AURORA_TPS/2 + baud/2) / baud;
- tmp = (tmp > 0xff) ? 0xff : tmp;
- sbus_writeb(tmp, &bp->r[chip]->r[CD180_RTPR]);
-
- switch (C_CSIZE(tty)) {
- case CS5:
- cor1 |= COR1_5BITS;
- break;
- case CS6:
- cor1 |= COR1_6BITS;
- break;
- case CS7:
- cor1 |= COR1_7BITS;
- break;
- case CS8:
- cor1 |= COR1_8BITS;
- break;
- }
-
- if (C_CSTOPB(tty))
- cor1 |= COR1_2SB;
-
- cor1 |= COR1_IGNORE;
- if (C_PARENB(tty)) {
- cor1 |= COR1_NORMPAR;
- if (C_PARODD(tty))
- cor1 |= COR1_ODDP;
- if (I_INPCK(tty))
- cor1 &= ~COR1_IGNORE;
- }
- /* Set marking of some errors */
- port->mark_mask = RCSR_OE | RCSR_TOUT;
- if (I_INPCK(tty))
- port->mark_mask |= RCSR_FE | RCSR_PE;
- if (I_BRKINT(tty) || I_PARMRK(tty))
- port->mark_mask |= RCSR_BREAK;
- if (I_IGNPAR(tty))
- port->mark_mask &= ~(RCSR_FE | RCSR_PE);
- if (I_IGNBRK(tty)) {
- port->mark_mask &= ~RCSR_BREAK;
- if (I_IGNPAR(tty))
- /* Real raw mode. Ignore all */
- port->mark_mask &= ~RCSR_OE;
- }
- /* Enable Hardware Flow Control */
- if (C_CRTSCTS(tty)) {
-/*#ifdef AURORA_BRAIN_DAMAGED_CTS
- port->SRER |= SRER_DSR | SRER_CTS;
- mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
- mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
- tty->hw_stopped = !(aurora_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
-#else*/
- port->COR2 |= COR2_CTSAE;
-/*#endif*/
- if (bp->flags&AURORA_BOARD_DTR_FLOW_OK) {
- mcor1 |= AURORA_RXTH;
- }
- }
- /* Enable Software Flow Control. FIXME: I'm not sure about this */
- /* Some people reported that it works, but I still doubt */
- if (I_IXON(tty)) {
- port->COR2 |= COR2_TXIBE;
- cor3 |= (COR3_FCT | COR3_SCDE);
- if (I_IXANY(tty))
- port->COR2 |= COR2_IXM;
- sbus_writeb(START_CHAR(tty),
- &bp->r[chip]->r[CD180_SCHR1]);
- sbus_writeb(STOP_CHAR(tty),
- &bp->r[chip]->r[CD180_SCHR2]);
- sbus_writeb(START_CHAR(tty),
- &bp->r[chip]->r[CD180_SCHR3]);
- sbus_writeb(STOP_CHAR(tty),
- &bp->r[chip]->r[CD180_SCHR4]);
- }
- if (!C_CLOCAL(tty)) {
- /* Enable CD check */
- port->SRER |= SRER_CD;
- mcor1 |= MCOR1_CDZD;
- mcor2 |= MCOR2_CDOD;
- }
-
- if (C_CREAD(tty))
- /* Enable receiver */
- port->SRER |= SRER_RXD;
-
- /* Set input FIFO size (1-8 bytes) */
- cor3 |= AURORA_RXFIFO;
- /* Setting up CD180 channel registers */
- sbus_writeb(cor1, &bp->r[chip]->r[CD180_COR1]);
- sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);
- sbus_writeb(cor3, &bp->r[chip]->r[CD180_COR3]);
- /* Make CD180 know about registers change */
- aurora_wait_CCR(bp->r[chip]);
- sbus_writeb(CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3,
- &bp->r[chip]->r[CD180_CCR]);
- /* Setting up modem option registers */
- sbus_writeb(mcor1, &bp->r[chip]->r[CD180_MCOR1]);
- sbus_writeb(mcor2, &bp->r[chip]->r[CD180_MCOR2]);
- /* Enable CD180 transmitter & receiver */
- aurora_wait_CCR(bp->r[chip]);
- sbus_writeb(CCR_TXEN | CCR_RXEN, &bp->r[chip]->r[CD180_CCR]);
- /* Enable interrupts */
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- /* And finally set RTS on */
- sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-#ifdef AURORA_DEBUG
- printk("aurora_change_speed: end\n");
-#endif
-}
-
-/* Must be called with interrupts enabled */
-static int aurora_setup_port(struct Aurora_board *bp, struct Aurora_port *port)
-{
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_setup_port: start %d\n",port_No(port));
-#endif
- if (port->flags & ASYNC_INITIALIZED)
- return 0;
-
- if (!port->xmit_buf) {
- /* We may sleep in get_zeroed_page() */
- unsigned long tmp;
-
- if (!(tmp = get_zeroed_page(GFP_KERNEL)))
- return -ENOMEM;
-
- if (port->xmit_buf) {
- free_page(tmp);
- return -ERESTARTSYS;
- }
- port->xmit_buf = (unsigned char *) tmp;
- }
-
- save_flags(flags); cli();
-
- if (port->tty)
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
-
-#ifdef MODULE
- if ((port->count == 1) && ((++bp->count) == 1))
- bp->flags |= AURORA_BOARD_ACTIVE;
-#endif
-
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- aurora_change_speed(bp, port);
- port->flags |= ASYNC_INITIALIZED;
-
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_setup_port: end\n");
-#endif
- return 0;
-}
-
-/* Must be called with interrupts disabled */
-static void aurora_shutdown_port(struct Aurora_board *bp, struct Aurora_port *port)
-{
- struct tty_struct *tty;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_shutdown_port: start\n");
-#endif
- if (!(port->flags & ASYNC_INITIALIZED))
- return;
-
- chip = AURORA_CD180(port_No(port));
-
-#ifdef AURORA_REPORT_OVERRUN
- printk("aurora%d: port %d: Total %ld overruns were detected.\n",
- board_No(bp), port_No(port), port->overrun);
-#endif
-#ifdef AURORA_REPORT_FIFO
- {
- int i;
-
- printk("aurora%d: port %d: FIFO hits [ ",
- board_No(bp), port_No(port));
- for (i = 0; i < 10; i++) {
- printk("%ld ", port->hits[i]);
- }
- printk("].\n");
- }
-#endif
- if (port->xmit_buf) {
- free_page((unsigned long) port->xmit_buf);
- port->xmit_buf = NULL;
- }
-
- if (!(tty = port->tty) || C_HUPCL(tty)) {
- /* Drop DTR */
- port->MSVR &= ~(bp->DTR|bp->RTS);
- sbus_writeb(port->MSVR,
- &bp->r[chip]->r[CD180_MSVR]);
- }
-
- /* Select port */
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
-
- /* Reset port */
- aurora_wait_CCR(bp->r[chip]);
- sbus_writeb(CCR_SOFTRESET, &bp->r[chip]->r[CD180_CCR]);
-
- /* Disable all interrupts from this port */
- port->SRER = 0;
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-
- if (tty)
- set_bit(TTY_IO_ERROR, &tty->flags);
- port->flags &= ~ASYNC_INITIALIZED;
-
-#ifdef MODULE
- if (--bp->count < 0) {
- printk(KERN_DEBUG "aurora%d: aurora_shutdown_port: "
- "bad board count: %d\n",
- board_No(bp), bp->count);
- bp->count = 0;
- }
-
- if (!bp->count)
- bp->flags &= ~AURORA_BOARD_ACTIVE;
-#endif
-
-#ifdef AURORA_DEBUG
- printk("aurora_shutdown_port: end\n");
-#endif
-}
-
-
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
- struct Aurora_port *port)
-{
- DECLARE_WAITQUEUE(wait, current);
- struct Aurora_board *bp = port_Board(port);
- int retval;
- int do_clocal = 0;
- int CD;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("block_til_ready: start\n");
-#endif
- chip = AURORA_CD180(port_No(port));
-
- /* If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
- }
-
- /* If non-blocking mode is set, or the port is not enabled,
- * then make the check up front and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
- }
-
- if (C_CLOCAL(tty))
- do_clocal = 1;
-
- /* Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
- * rs_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&port->open_wait, &wait);
- cli();
- if (!tty_hung_up_p(filp))
- port->count--;
- sti();
- port->blocked_open++;
- while (1) {
- cli();
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- CD = sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD;
- port->MSVR=bp->RTS;
-
- /* auto drops DTR */
- sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
- sti();
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
- break;
- }
- if (!(port->flags & ASYNC_CLOSING) &&
- (do_clocal || CD))
- break;
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&port->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
- if (retval)
- return retval;
-
- port->flags |= ASYNC_NORMAL_ACTIVE;
-#ifdef AURORA_DEBUG
- printk("block_til_ready: end\n");
-#endif
- return 0;
-}
-
-static int aurora_open(struct tty_struct * tty, struct file * filp)
-{
- int board;
- int error;
- struct Aurora_port * port;
- struct Aurora_board * bp;
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_open: start\n");
-#endif
-
- board = AURORA_BOARD(tty->index);
- if (board > AURORA_NBOARD ||
- !(aurora_board[board].flags & AURORA_BOARD_PRESENT)) {
-#ifdef AURORA_DEBUG
- printk("aurora_open: error board %d present %d\n",
- board, aurora_board[board].flags & AURORA_BOARD_PRESENT);
-#endif
- return -ENODEV;
- }
-
- bp = &aurora_board[board];
- port = aurora_port + board * AURORA_NPORT * AURORA_NCD180 + AURORA_PORT(tty->index);
- if ((aurora_paranoia_check(port, tty->name, "aurora_open")) {
-#ifdef AURORA_DEBUG
- printk("aurora_open: error paranoia check\n");
-#endif
- return -ENODEV;
- }
-
- port->count++;
- tty->driver_data = port;
- port->tty = tty;
-
- if ((error = aurora_setup_port(bp, port))) {
-#ifdef AURORA_DEBUG
- printk("aurora_open: error aurora_setup_port ret %d\n",error);
-#endif
- return error;
- }
-
- if ((error = block_til_ready(tty, filp, port))) {
-#ifdef AURORA_DEBUG
- printk("aurora_open: error block_til_ready ret %d\n",error);
-#endif
- return error;
- }
-
-#ifdef AURORA_DEBUG
- printk("aurora_open: end\n");
-#endif
- return 0;
-}
-
-static void aurora_close(struct tty_struct * tty, struct file * filp)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
- unsigned long flags;
- unsigned long timeout;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_close: start\n");
-#endif
-
- if (!port || (aurora_paranoia_check(port, tty->name, "close"))
- return;
-
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
- if (tty_hung_up_p(filp)) {
- restore_flags(flags);
- return;
- }
-
- bp = port_Board(port);
- if ((tty->count == 1) && (port->count != 1)) {
- printk(KERN_DEBUG "aurora%d: aurora_close: bad port count; "
- "tty->count is 1, port count is %d\n",
- board_No(bp), port->count);
- port->count = 1;
- }
- if (--port->count < 0) {
- printk(KERN_DEBUG "aurora%d: aurora_close: bad port "
- "count for tty%d: %d\n",
- board_No(bp), port_No(port), port->count);
- port->count = 0;
- }
- if (port->count) {
- restore_flags(flags);
- return;
- }
- port->flags |= ASYNC_CLOSING;
-
- /* Now we wait for the transmit buffer to clear; and we notify
- * the line discipline to only process XON/XOFF characters.
- */
- tty->closing = 1;
- if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE){
-#ifdef AURORA_DEBUG
- printk("aurora_close: waiting to flush...\n");
-#endif
- tty_wait_until_sent(tty, port->closing_wait);
- }
-
- /* At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
- port->SRER &= ~SRER_RXD;
- if (port->flags & ASYNC_INITIALIZED) {
- port->SRER &= ~SRER_TXRDY;
- port->SRER |= SRER_TXEMPTY;
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- timeout = jiffies+HZ;
- while(port->SRER & SRER_TXEMPTY) {
- msleep_interruptible(jiffies_to_msecs(port->timeout));
- if (time_after(jiffies, timeout))
- break;
- }
- }
-#ifdef AURORA_DEBUG
- printk("aurora_close: shutdown_port\n");
-#endif
- aurora_shutdown_port(bp, port);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- tty_ldisc_flush(tty);
- tty->closing = 0;
- port->event = 0;
- port->tty = 0;
- if (port->blocked_open) {
- if (port->close_delay) {
- msleep_interruptible(jiffies_to_msecs(port->close_delay));
- }
- wake_up_interruptible(&port->open_wait);
- }
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&port->close_wait);
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_close: end\n");
-#endif
-}
-
-static int aurora_write(struct tty_struct * tty,
- const unsigned char *buf, int count)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
- int c, total = 0;
- unsigned long flags;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_write: start %d\n",count);
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_write"))
- return 0;
-
- chip = AURORA_CD180(port_No(port));
-
- bp = port_Board(port);
-
- if (!tty || !port->xmit_buf || !tmp_buf)
- return 0;
-
- save_flags(flags);
- while (1) {
- cli();
- c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - port->xmit_head));
- if (c <= 0) {
- restore_flags(flags);
- break;
- }
- memcpy(port->xmit_buf + port->xmit_head, buf, c);
- port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
- port->xmit_cnt += c;
- restore_flags(flags);
-
- buf += c;
- count -= c;
- total += c;
- }
-
- cli();
- if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
- !(port->SRER & SRER_TXRDY)) {
- port->SRER |= SRER_TXRDY;
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- }
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_write: end %d\n",total);
-#endif
- return total;
-}
-
-static void aurora_put_char(struct tty_struct * tty, unsigned char ch)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_put_char: start %c\n",ch);
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_put_char"))
- return;
-
- if (!tty || !port->xmit_buf)
- return;
-
- save_flags(flags); cli();
-
- if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
- restore_flags(flags);
- return;
- }
-
- port->xmit_buf[port->xmit_head++] = ch;
- port->xmit_head &= SERIAL_XMIT_SIZE - 1;
- port->xmit_cnt++;
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_put_char: end\n");
-#endif
-}
-
-static void aurora_flush_chars(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- unsigned long flags;
- unsigned char chip;
-
-/*#ifdef AURORA_DEBUG
- printk("aurora_flush_chars: start\n");
-#endif*/
- if ((aurora_paranoia_check(port, tty->name, "aurora_flush_chars"))
- return;
-
- chip = AURORA_CD180(port_No(port));
-
- if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
- !port->xmit_buf)
- return;
-
- save_flags(flags); cli();
- port->SRER |= SRER_TXRDY;
- sbus_writeb(port_No(port) & 7,
- &port_Board(port)->r[chip]->r[CD180_CAR]);
- udelay(1);
- sbus_writeb(port->SRER,
- &port_Board(port)->r[chip]->r[CD180_SRER]);
- restore_flags(flags);
-/*#ifdef AURORA_DEBUG
- printk("aurora_flush_chars: end\n");
-#endif*/
-}
-
-static int aurora_write_room(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- int ret;
-
-#ifdef AURORA_DEBUG
- printk("aurora_write_room: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_write_room"))
- return 0;
-
- ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
- if (ret < 0)
- ret = 0;
-#ifdef AURORA_DEBUG
- printk("aurora_write_room: end\n");
-#endif
- return ret;
-}
-
-static int aurora_chars_in_buffer(struct tty_struct *tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-
- if ((aurora_paranoia_check(port, tty->name, "aurora_chars_in_buffer"))
- return 0;
-
- return port->xmit_cnt;
-}
-
-static void aurora_flush_buffer(struct tty_struct *tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_flush_buffer: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_flush_buffer"))
- return;
-
- save_flags(flags); cli();
- port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
- restore_flags(flags);
-
- tty_wakeup(tty);
-#ifdef AURORA_DEBUG
- printk("aurora_flush_buffer: end\n");
-#endif
-}
-
-static int aurora_tiocmget(struct tty_struct *tty, struct file *file)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board * bp;
- unsigned char status,chip;
- unsigned int result;
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_get_modem_info: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
- return -ENODEV;
-
- chip = AURORA_CD180(port_No(port));
-
- bp = port_Board(port);
-
- save_flags(flags); cli();
-
- sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
-
- status = sbus_readb(&bp->r[chip]->r[CD180_MSVR]);
- result = 0/*bp->r[chip]->r[AURORA_RI] & (1u << port_No(port)) ? 0 : TIOCM_RNG*/;
-
- restore_flags(flags);
-
- result |= ((status & bp->RTS) ? TIOCM_RTS : 0)
- | ((status & bp->DTR) ? TIOCM_DTR : 0)
- | ((status & MSVR_CD) ? TIOCM_CAR : 0)
- | ((status & MSVR_DSR) ? TIOCM_DSR : 0)
- | ((status & MSVR_CTS) ? TIOCM_CTS : 0);
-
-#ifdef AURORA_DEBUG
- printk("aurora_get_modem_info: end\n");
-#endif
- return result;
-}
-
-static int aurora_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- unsigned int arg;
- unsigned long flags;
- struct Aurora_board *bp = port_Board(port);
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_set_modem_info: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
- return -ENODEV;
-
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
- if (set & TIOCM_RTS)
- port->MSVR |= bp->RTS;
- if (set & TIOCM_DTR)
- port->MSVR |= bp->DTR;
- if (clear & TIOCM_RTS)
- port->MSVR &= ~bp->RTS;
- if (clear & TIOCM_DTR)
- port->MSVR &= ~bp->DTR;
-
- sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
-
- sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_set_modem_info: end\n");
-#endif
- return 0;
-}
-
-static void aurora_send_break(struct Aurora_port * port, unsigned long length)
-{
- struct Aurora_board *bp = port_Board(port);
- unsigned long flags;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_send_break: start\n");
-#endif
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
-
- port->break_length = AURORA_TPS / HZ * length;
- port->COR2 |= COR2_ETC;
- port->SRER |= SRER_TXRDY;
- sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
-
- sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);
- sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
- aurora_wait_CCR(bp->r[chip]);
-
- sbus_writeb(CCR_CORCHG2, &bp->r[chip]->r[CD180_CCR]);
- aurora_wait_CCR(bp->r[chip]);
-
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_send_break: end\n");
-#endif
-}
-
-static int aurora_set_serial_info(struct Aurora_port * port,
- struct serial_struct * newinfo)
-{
- struct serial_struct tmp;
- struct Aurora_board *bp = port_Board(port);
- int change_speed;
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_set_serial_info: start\n");
-#endif
- if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
- return -EFAULT;
-#if 0
- if ((tmp.irq != bp->irq) ||
- (tmp.port != bp->base) ||
- (tmp.type != PORT_CIRRUS) ||
- (tmp.baud_base != (bp->oscfreq + CD180_TPC/2) / CD180_TPC) ||
- (tmp.custom_divisor != 0) ||
- (tmp.xmit_fifo_size != CD180_NFIFO) ||
- (tmp.flags & ~AURORA_LEGAL_FLAGS))
- return -EINVAL;
-#endif
-
- change_speed = ((port->flags & ASYNC_SPD_MASK) !=
- (tmp.flags & ASYNC_SPD_MASK));
-
- if (!capable(CAP_SYS_ADMIN)) {
- if ((tmp.close_delay != port->close_delay) ||
- (tmp.closing_wait != port->closing_wait) ||
- ((tmp.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
- return -EPERM;
- port->flags = ((port->flags & ~ASYNC_USR_MASK) |
- (tmp.flags & ASYNC_USR_MASK));
- } else {
- port->flags = ((port->flags & ~ASYNC_FLAGS) |
- (tmp.flags & ASYNC_FLAGS));
- port->close_delay = tmp.close_delay;
- port->closing_wait = tmp.closing_wait;
- }
- if (change_speed) {
- save_flags(flags); cli();
- aurora_change_speed(bp, port);
- restore_flags(flags);
- }
-#ifdef AURORA_DEBUG
- printk("aurora_set_serial_info: end\n");
-#endif
- return 0;
-}
-
-extern int aurora_get_serial_info(struct Aurora_port * port,
- struct serial_struct * retinfo)
-{
- struct serial_struct tmp;
- struct Aurora_board *bp = port_Board(port);
-
-#ifdef AURORA_DEBUG
- printk("aurora_get_serial_info: start\n");
-#endif
- if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
- return -EFAULT;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = PORT_CIRRUS;
- tmp.line = port - aurora_port;
- tmp.port = 0;
- tmp.irq = bp->irq;
- tmp.flags = port->flags;
- tmp.baud_base = (bp->oscfreq + CD180_TPC/2) / CD180_TPC;
- tmp.close_delay = port->close_delay * HZ/100;
- tmp.closing_wait = port->closing_wait * HZ/100;
- tmp.xmit_fifo_size = CD180_NFIFO;
- copy_to_user(retinfo, &tmp, sizeof(tmp));
-#ifdef AURORA_DEBUG
-printk("aurora_get_serial_info: end\n");
-#endif
- return 0;
-}
-
-static int aurora_ioctl(struct tty_struct * tty, struct file * filp,
- unsigned int cmd, unsigned long arg)
-
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- int retval;
-
-#ifdef AURORA_DEBUG
- printk("aurora_ioctl: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_ioctl"))
- return -ENODEV;
-
- switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- if (!arg)
- aurora_send_break(port, HZ/4); /* 1/4 second */
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- aurora_send_break(port, arg ? arg*(HZ/10) : HZ/4);
- return 0;
- case TIOCGSOFTCAR:
- return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
- case TIOCSSOFTCAR:
- if (get_user(arg,(unsigned long *)arg))
- return -EFAULT;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
- case TIOCGSERIAL:
- return aurora_get_serial_info(port, (struct serial_struct *) arg);
- case TIOCSSERIAL:
- return aurora_set_serial_info(port, (struct serial_struct *) arg);
- default:
- return -ENOIOCTLCMD;
- };
-#ifdef AURORA_DEBUG
- printk("aurora_ioctl: end\n");
-#endif
- return 0;
-}
-
-static void aurora_throttle(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
- unsigned long flags;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_throttle: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_throttle"))
- return;
-
- bp = port_Board(port);
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
- port->MSVR &= ~bp->RTS;
- sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- if (I_IXOFF(tty)) {
- aurora_wait_CCR(bp->r[chip]);
- sbus_writeb(CCR_SSCH2, &bp->r[chip]->r[CD180_CCR]);
- aurora_wait_CCR(bp->r[chip]);
- }
- sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_throttle: end\n");
-#endif
-}
-
-static void aurora_unthrottle(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
- unsigned long flags;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_unthrottle: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_unthrottle"))
- return;
-
- bp = port_Board(port);
-
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
- port->MSVR |= bp->RTS;
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- if (I_IXOFF(tty)) {
- aurora_wait_CCR(bp->r[chip]);
- sbus_writeb(CCR_SSCH1,
- &bp->r[chip]->r[CD180_CCR]);
- aurora_wait_CCR(bp->r[chip]);
- }
- sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_unthrottle: end\n");
-#endif
-}
-
-static void aurora_stop(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
- unsigned long flags;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_stop: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_stop"))
- return;
-
- bp = port_Board(port);
-
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
- port->SRER &= ~SRER_TXRDY;
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- sbus_writeb(port->SRER,
- &bp->r[chip]->r[CD180_SRER]);
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_stop: end\n");
-#endif
-}
-
-static void aurora_start(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
- unsigned long flags;
- unsigned char chip;
-
-#ifdef AURORA_DEBUG
- printk("aurora_start: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_start"))
- return;
-
- bp = port_Board(port);
-
- chip = AURORA_CD180(port_No(port));
-
- save_flags(flags); cli();
- if (port->xmit_cnt && port->xmit_buf && !(port->SRER & SRER_TXRDY)) {
- port->SRER |= SRER_TXRDY;
- sbus_writeb(port_No(port) & 7,
- &bp->r[chip]->r[CD180_CAR]);
- udelay(1);
- sbus_writeb(port->SRER,
- &bp->r[chip]->r[CD180_SRER]);
- }
- restore_flags(flags);
-#ifdef AURORA_DEBUG
- printk("aurora_start: end\n");
-#endif
-}
-
-/*
- * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occurred. The path of
- * hangup processing is:
- *
- * serial interrupt routine -> (scheduler tqueue) ->
- * do_aurora_hangup() -> tty->hangup() -> aurora_hangup()
- *
- */
-static void do_aurora_hangup(void *private_)
-{
- struct Aurora_port *port = (struct Aurora_port *) private_;
- struct tty_struct *tty;
-
-#ifdef AURORA_DEBUG
- printk("do_aurora_hangup: start\n");
-#endif
- tty = port->tty;
- if (tty != NULL) {
- tty_hangup(tty); /* FIXME: module removal race - AKPM */
-#ifdef AURORA_DEBUG
- printk("do_aurora_hangup: end\n");
-#endif
- }
-}
-
-static void aurora_hangup(struct tty_struct * tty)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- struct Aurora_board *bp;
-
-#ifdef AURORA_DEBUG
- printk("aurora_hangup: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_hangup"))
- return;
-
- bp = port_Board(port);
-
- aurora_shutdown_port(bp, port);
- port->event = 0;
- port->count = 0;
- port->flags &= ~ASYNC_NORMAL_ACTIVE;
- port->tty = 0;
- wake_up_interruptible(&port->open_wait);
-#ifdef AURORA_DEBUG
- printk("aurora_hangup: end\n");
-#endif
-}
-
-static void aurora_set_termios(struct tty_struct * tty, struct termios * old_termios)
-{
- struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
- unsigned long flags;
-
-#ifdef AURORA_DEBUG
- printk("aurora_set_termios: start\n");
-#endif
- if ((aurora_paranoia_check(port, tty->name, "aurora_set_termios"))
- return;
-
- if (tty->termios->c_cflag == old_termios->c_cflag &&
- tty->termios->c_iflag == old_termios->c_iflag)
- return;
-
- save_flags(flags); cli();
- aurora_change_speed(port_Board(port), port);
- restore_flags(flags);
-
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS)) {
- tty->hw_stopped = 0;
- aurora_start(tty);
- }
-#ifdef AURORA_DEBUG
- printk("aurora_set_termios: end\n");
-#endif
-}
-
-static void do_aurora_bh(void)
-{
- run_task_queue(&tq_aurora);
-}
-
-static void do_softint(void *private_)
-{
- struct Aurora_port *port = (struct Aurora_port *) private_;
- struct tty_struct *tty;
-
-#ifdef AURORA_DEBUG
- printk("do_softint: start\n");
-#endif
- tty = port->tty;
- if (tty == NULL)
- return;
-
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
- tty_wakeup(tty);
- }
-#ifdef AURORA_DEBUG
- printk("do_softint: end\n");
-#endif
-}
-
-static const struct tty_operations aurora_ops = {
- .open = aurora_open,
- .close = aurora_close,
- .write = aurora_write,
- .put_char = aurora_put_char,
- .flush_chars = aurora_flush_chars,
- .write_room = aurora_write_room,
- .chars_in_buffer = aurora_chars_in_buffer,
- .flush_buffer = aurora_flush_buffer,
- .ioctl = aurora_ioctl,
- .throttle = aurora_throttle,
- .unthrottle = aurora_unthrottle,
- .set_termios = aurora_set_termios,
- .stop = aurora_stop,
- .start = aurora_start,
- .hangup = aurora_hangup,
- .tiocmget = aurora_tiocmget,
- .tiocmset = aurora_tiocmset,
-};
-
-static int aurora_init_drivers(void)
-{
- int error;
- int i;
-
-#ifdef AURORA_DEBUG
- printk("aurora_init_drivers: start\n");
-#endif
- tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
- if (tmp_buf == NULL) {
- printk(KERN_ERR "aurora: Couldn't get free page.\n");
- return 1;
- }
- init_bh(AURORA_BH, do_aurora_bh);
- aurora_driver = alloc_tty_driver(AURORA_INPORTS);
- if (!aurora_driver) {
- printk(KERN_ERR "aurora: Couldn't allocate tty driver.\n");
- free_page((unsigned long) tmp_buf);
- return 1;
- }
- aurora_driver->owner = THIS_MODULE;
- aurora_driver->name = "ttyA";
- aurora_driver->major = AURORA_MAJOR;
- aurora_driver->type = TTY_DRIVER_TYPE_SERIAL;
- aurora_driver->subtype = SERIAL_TYPE_NORMAL;
- aurora_driver->init_termios = tty_std_termios;
- aurora_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- aurora_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(aurora_driver, &aurora_ops);
- error = tty_register_driver(aurora_driver);
- if (error) {
- put_tty_driver(aurora_driver);
- free_page((unsigned long) tmp_buf);
- printk(KERN_ERR "aurora: Couldn't register aurora driver, error = %d\n",
- error);
- return 1;
- }
-
- memset(aurora_port, 0, sizeof(aurora_port));
- for (i = 0; i < AURORA_TNPORTS; i++) {
- aurora_port[i].magic = AURORA_MAGIC;
- aurora_port[i].tqueue.routine = do_softint;
- aurora_port[i].tqueue.data = &aurora_port[i];
- aurora_port[i].tqueue_hangup.routine = do_aurora_hangup;
- aurora_port[i].tqueue_hangup.data = &aurora_port[i];
- aurora_port[i].close_delay = 50 * HZ/100;
- aurora_port[i].closing_wait = 3000 * HZ/100;
- init_waitqueue_head(&aurora_port[i].open_wait);
- init_waitqueue_head(&aurora_port[i].close_wait);
- }
-#ifdef AURORA_DEBUG
- printk("aurora_init_drivers: end\n");
-#endif
- return 0;
-}
-
-static void aurora_release_drivers(void)
-{
-#ifdef AURORA_DEBUG
- printk("aurora_release_drivers: start\n");
-#endif
- free_page((unsigned long)tmp_buf);
- tty_unregister_driver(aurora_driver);
- put_tty_driver(aurora_driver);
-#ifdef AURORA_DEBUG
- printk("aurora_release_drivers: end\n");
-#endif
-}
-
-/*
- * Called at boot time.
- *
- * You can specify IO base for up to RC_NBOARD cards,
- * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
- * Note that there will be no probing at default
- * addresses in this case.
- *
- */
-void __init aurora_setup(char *str, int *ints)
-{
- int i;
-
- for(i=0;(i<ints[0])&&(i<4);i++) {
- if (ints[i+1]) irqs[i]=ints[i+1];
- }
-}
-
-static int __init aurora_real_init(void)
-{
- int found;
- int i;
-
- printk(KERN_INFO "aurora: Driver starting.\n");
- if(aurora_init_drivers())
- return -EIO;
- found = aurora_probe();
- if(!found) {
- aurora_release_drivers();
- printk(KERN_INFO "aurora: No Aurora Multiport boards detected.\n");
- return -EIO;
- } else {
- printk(KERN_INFO "aurora: %d boards found.\n", found);
- }
- for (i = 0; i < found; i++) {
- int ret = aurora_setup_board(&aurora_board[i]);
-
- if (ret) {
-#ifdef AURORA_DEBUG
- printk(KERN_ERR "aurora_init: error aurora_setup_board ret %d\n",
- ret);
-#endif
- return ret;
- }
- }
- return 0;
-}
-
-int irq = 0;
-int irq1 = 0;
-int irq2 = 0;
-int irq3 = 0;
-module_param(irq , int, 0);
-module_param(irq1, int, 0);
-module_param(irq2, int, 0);
-module_param(irq3, int, 0);
-
-static int __init aurora_init(void)
-{
- if (irq ) irqs[0]=irq ;
- if (irq1) irqs[1]=irq1;
- if (irq2) irqs[2]=irq2;
- if (irq3) irqs[3]=irq3;
- return aurora_real_init();
-}
-
-static void __exit aurora_cleanup(void)
-{
- int i;
-
-#ifdef AURORA_DEBUG
-printk("cleanup_module: aurora_release_drivers\n");
-#endif
-
- aurora_release_drivers();
- for (i = 0; i < AURORA_NBOARD; i++)
- if (aurora_board[i].flags & AURORA_BOARD_PRESENT) {
- aurora_shutdown_board(&aurora_board[i]);
- aurora_release_io_range(&aurora_board[i]);
- }
-}
-
-module_init(aurora_init);
-module_exit(aurora_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/aurora.h b/drivers/sbus/char/aurora.h
deleted file mode 100644
index b8b5476d986..00000000000
--- a/drivers/sbus/char/aurora.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* $Id: aurora.h,v 1.6 2001/06/05 12:23:38 davem Exp $
- * linux/drivers/sbus/char/aurora.h -- Aurora multiport driver
- *
- * Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro)
- *
- * This code is based on the RISCom/8 multiport serial driver written
- * by Dmitry Gorodchanin (pgmdsg@ibi.com), based on the Linux serial
- * driver, written by Linus Torvalds, Theodore T'so and others.
- * The Aurora multiport programming info was obtained mainly from the
- * Cirrus Logic CD180 documentation (available on the web), and by
- * doing heavy tests on the board. Many thanks to Eddie C. Dost for the
- * help on the sbus interface.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Revision 1.0
- *
- * This is the first public release.
- *
- * This version needs a lot of feedback. This is the version that works
- * with _my_ board. My board is model 1600se, revision '@(#)1600se.fth
- * 1.2 3/28/95 1'. The driver might work with your board, but I do not
- * guarantee it. If you have _any_ type of board, I need to know if the
- * driver works or not, I need to know exactly your board parameters
- * (get them with 'cd /proc/openprom/iommu/sbus/sio16/; ls *; cat *')
- * Also, I need your board revision code, which is written on the board.
- * Send me the output of my driver too (it outputs through klogd).
- *
- * If the driver does not work, you can try enabling the debug options
- * to see what's wrong or what should be done.
- *
- * I'm sorry about the alignment of the code. It was written in a
- * 128x48 environment.
- *
- * I must say that I do not like Aurora Technologies' policy. I asked
- * them to help me do this driver faster, but they ended by something
- * like "don't call us, we'll call you", and I never heard anything
- * from them. They told me "knowing the way the board works, I don't
- * doubt you and others on the net will make the driver."
- * The truth about this board is that it has nothing intelligent on it.
- * If you want to say to somebody what kind of board you have, say that
- * it uses Cirrus Logic processors (CD180). The power of the board is
- * in those two chips. The rest of the board is the interface to the
- * sbus and to the peripherals. Still, they did something smart: they
- * reversed DTR and RTS to make on-board automatic hardware flow
- * control usable.
- * Thanks to Aurora Technologies for wasting my time, nerves and money.
- */
-
-#ifndef __LINUX_AURORA_H
-#define __LINUX_AURORA_H
-
-#include <linux/serial.h>
-#include <linux/serialP.h>
-
-#ifdef __KERNEL__
-
-/* This is the number of boards to support. I've only tested this driver with
- * one board, so it might not work.
- */
-#define AURORA_NBOARD 1
-
-/* Useful ? Yes. But you can safely comment the warnings if they annoy you
- * (let me say that again: the warnings in the code, not this define).
- */
-#define AURORA_PARANOIA_CHECK
-
-/* Well, after many lost nights, I found that the IRQ for this board is
- * selected from four built-in values by writing some bits in the
- * configuration register. This causes a little problem to occur: which
- * IRQ to select ? Which one is the best for the user ? Well, I finally
- * decided for the following algorithm: if the "bintr" value is not acceptable
- * (not within type_1_irq[], then test the "intr" value, if that fails too,
- * try each value from type_1_irq until succeded. Hope it's ok.
- * You can safely reorder the irq's.
- */
-#define TYPE_1_IRQS 4
-unsigned char type_1_irq[TYPE_1_IRQS] = {
- 3, 5, 9, 13
-};
-/* I know something about another method of interrupt setting, but not enough.
- * Also, this is for another type of board, so I first have to learn how to
- * detect it.
-#define TYPE_2_IRQS 3
-unsigned char type_2_irq[TYPE_2_IRQS] = {
- 0, 0, 0 ** could anyone find these for me ? (see AURORA_ALLIRQ below) **
- };
-unsigned char type_2_mask[TYPE_2_IRQS] = {
- 32, 64, 128
- };
-*/
-
-/* The following section should only be modified by those who know what
- * they're doing (or don't, but want to help with some feedback). Modifying
- * anything raises a _big_ probability for your system to hang, but the
- * sacrifice worths. (I sacrificed my ext2fs many, many times...)
- */
-
-/* This one tries to dump to console the name of almost every function called,
- * and many other debugging info.
- */
-#undef AURORA_DEBUG
-
-/* These are the most dangerous and useful defines. They do printk() during
- * the interrupt processing routine(s), so if you manage to get "flooded" by
- * irq's, start thinking about the "Power off/on" button...
- */
-#undef AURORA_INTNORM /* This one enables the "normal" messages, but some
- * of them cause flood, so I preffered putting
- * them under a define */
-#undef AURORA_INT_DEBUG /* This one is really bad. */
-
-/* Here's something helpful: after n irq's, the board will be disabled. This
- * prevents irq flooding during debug (no need to think about power
- * off/on anymore...)
- */
-#define AURORA_FLOODPRO 10
-
-/* This one helps finding which irq the board calls, in case of a strange/
- * unsupported board. AURORA_INT_DEBUG should be enabled, because I don't
- * think /proc/interrupts or any command will be available in case of an irq
- * flood... "allirq" is the list of all free irq's.
- */
-/*
-#define AURORA_ALLIRQ 6
-int allirq[AURORA_ALLIRQ]={
- 2,3,5,7,9,13
- };
-*/
-
-/* These must not be modified. These values are assumed during the code for
- * performance optimisations.
- */
-#define AURORA_NCD180 2 /* two chips per board */
-#define AURORA_NPORT 8 /* 8 ports per chip */
-
-/* several utilities */
-#define AURORA_BOARD(line) (((line) >> 4) & 0x01)
-#define AURORA_CD180(line) (((line) >> 3) & 0x01)
-#define AURORA_PORT(line) ((line) & 15)
-
-#define AURORA_TNPORTS (AURORA_NBOARD*AURORA_NCD180*AURORA_NPORT)
-
-/* Ticks per sec. Used for setting receiver timeout and break length */
-#define AURORA_TPS 4000
-
-#define AURORA_MAGIC 0x0A18
-
-/* Yeah, after heavy testing I decided it must be 6.
- * Sure, You can change it if needed.
- */
-#define AURORA_RXFIFO 6 /* Max. receiver FIFO size (1-8) */
-
-#define AURORA_RXTH 7
-
-struct aurora_reg1 {
- __volatile__ unsigned char r;
-};
-
-struct aurora_reg128 {
- __volatile__ unsigned char r[128];
-};
-
-struct aurora_reg4 {
- __volatile__ unsigned char r[4];
-};
-
-struct Aurora_board {
- unsigned long flags;
- struct aurora_reg1 * r0; /* This is the board configuration
- * register (write-only). */
- struct aurora_reg128 * r[2]; /* These are the registers for the
- * two chips. */
- struct aurora_reg4 * r3; /* These are used for hardware-based
- * acknowledge. Software-based ack is
- * not supported by CD180. */
- unsigned int oscfreq; /* The on-board oscillator
- * frequency, in Hz. */
- unsigned char irq;
-#ifdef MODULE
- signed char count; /* counts the use of the board */
-#endif
- /* Values for the dtr_rts swapped mode. */
- unsigned char DTR;
- unsigned char RTS;
- unsigned char MSVDTR;
- unsigned char MSVRTS;
- /* Values for hardware acknowledge. */
- unsigned char ACK_MINT, ACK_TINT, ACK_RINT;
-};
-
-/* Board configuration register */
-#define AURORA_CFG_ENABLE_IO 8
-#define AURORA_CFG_ENABLE_IRQ 4
-
-/* Board flags */
-#define AURORA_BOARD_PRESENT 0x00000001
-#define AURORA_BOARD_ACTIVE 0x00000002
-#define AURORA_BOARD_TYPE_2 0x00000004 /* don't know how to
- * detect this yet */
-#define AURORA_BOARD_DTR_FLOW_OK 0x00000008
-
-/* The story goes like this: Cirrus programmed the CD-180 chip to do automatic
- * hardware flow control, and do it using CTS and DTR. CTS is ok, but, if you
- * have a modem and the chip drops DTR, then the modem will drop the carrier
- * (ain't that cute...). Luckily, the guys at Aurora decided to swap DTR and
- * RTS, which makes the flow control usable. I hope that all the boards made
- * by Aurora have these two signals swapped. If your's doesn't but you have a
- * breakout box, you can try to reverse them yourself, then set the following
- * flag.
- */
-#undef AURORA_FORCE_DTR_FLOW
-
-/* In fact, a few more words have to be said about hardware flow control.
- * This driver handles "output" flow control through the on-board facility
- * CTS Auto Enable. For the "input" flow control there are two cases when
- * the flow should be controlled. The first case is when the kernel is so
- * busy that it cannot process IRQ's in time; this flow control can only be
- * activated by the on-board chip, and if the board has RTS and DTR swapped,
- * this facility is usable. The second case is when the application is so
- * busy that it cannot receive bytes from the kernel, and this flow must be
- * activated by software. This second case is not yet implemented in this
- * driver. Unfortunately, I estimate that the second case is the one that
- * occurs the most.
- */
-
-
-struct Aurora_port {
- int magic;
- int baud_base;
- int flags;
- struct tty_struct * tty;
- int count;
- int blocked_open;
- long event;
- int timeout;
- int close_delay;
- unsigned char * xmit_buf;
- int custom_divisor;
- int xmit_head;
- int xmit_tail;
- int xmit_cnt;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
- struct tq_struct tqueue;
- struct tq_struct tqueue_hangup;
- short wakeup_chars;
- short break_length;
- unsigned short closing_wait;
- unsigned char mark_mask;
- unsigned char SRER;
- unsigned char MSVR;
- unsigned char COR2;
-#ifdef AURORA_REPORT_OVERRUN
- unsigned long overrun;
-#endif
-#ifdef AURORA_REPORT_FIFO
- unsigned long hits[10];
-#endif
-};
-
-#endif
-#endif /*__LINUX_AURORA_H*/
-
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index 22631f8b9b4..8410587348f 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -187,19 +187,20 @@ static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status)
bp->waiting = 1;
add_wait_queue(&bp->wq, &wait);
while (limit-- > 0) {
- u8 val;
-
- set_current_state(TASK_INTERRUPTIBLE);
- *status = val = readb(bp->i2c_control_regs + 0);
- if ((val & I2C_PCF_PIN) == 0) {
+ unsigned long val;
+
+ val = wait_event_interruptible_timeout(
+ bp->wq,
+ (((*status = readb(bp->i2c_control_regs + 0))
+ & I2C_PCF_PIN) == 0),
+ msecs_to_jiffies(250));
+ if (val > 0) {
ret = 0;
break;
}
- msleep_interruptible(250);
}
remove_wait_queue(&bp->wq, &wait);
bp->waiting = 0;
- current->state = TASK_RUNNING;
return ret;
}
@@ -340,7 +341,7 @@ static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id)
*/
if (bp->waiting &&
!(readb(bp->i2c_control_regs + 0x0) & I2C_PCF_PIN))
- wake_up(&bp->wq);
+ wake_up_interruptible(&bp->wq);
return IRQ_HANDLED;
}
diff --git a/drivers/sbus/char/cd180.h b/drivers/sbus/char/cd180.h
deleted file mode 100644
index 445b86cc65e..00000000000
--- a/drivers/sbus/char/cd180.h
+++ /dev/null
@@ -1,240 +0,0 @@
-
-/* Definitions for Cirrus Logic CL-CD180 8-port async mux chip */
-#define CD180_NCH 8 /* Total number of channels */
-#define CD180_TPC 16 /* Ticks per character */
-#define CD180_NFIFO 8 /* TX FIFO size */
-
-/* Global registers */
-#define CD180_GFRCR 0x6b /* Global Firmware Revision Code Register */
-#define CD180_SRCR 0x66 /* Service Request Configuration Register */
-#define CD180_PPRH 0x70 /* Prescaler Period Register High */
-#define CD180_PPRL 0x71 /* Prescaler Period Register Low */
-#define CD180_MSMR 0x61 /* Modem Service Match Register */
-#define CD180_TSMR 0x62 /* Transmit Service Match Register */
-#define CD180_RSMR 0x63 /* Receive Service Match Register */
-#define CD180_GSVR 0x40 /* Global Service Vector Register */
-#define CD180_SRSR 0x65 /* Service Request Status Register */
-#define CD180_GSCR 0x41 /* Global Service Channel Register */
-#define CD180_CAR 0x64 /* Channel Access Register */
-
-/* Indexed registers */
-#define CD180_RDCR 0x07 /* Receive Data Count Register */
-#define CD180_RDR 0x78 /* Receiver Data Register */
-#define CD180_RCSR 0x7a /* Receiver Character Status Register */
-#define CD180_TDR 0x7b /* Transmit Data Register */
-#define CD180_EOSRR 0x7f /* End of Service Request Register */
-
-/* Channel Registers */
-#define CD180_SRER 0x02 /* Service Request Enable Register */
-#define CD180_CCR 0x01 /* Channel Command Register */
-#define CD180_COR1 0x03 /* Channel Option Register 1 */
-#define CD180_COR2 0x04 /* Channel Option Register 2 */
-#define CD180_COR3 0x05 /* Channel Option Register 3 */
-#define CD180_CCSR 0x06 /* Channel Control Status Register */
-#define CD180_RTPR 0x18 /* Receive Timeout Period Register */
-#define CD180_RBPRH 0x31 /* Receive Bit Rate Period Register High */
-#define CD180_RBPRL 0x32 /* Receive Bit Rate Period Register Low */
-#define CD180_TBPRH 0x39 /* Transmit Bit Rate Period Register High */
-#define CD180_TBPRL 0x3a /* Transmit Bit Rate Period Register Low */
-#define CD180_SCHR1 0x09 /* Special Character Register 1 */
-#define CD180_SCHR2 0x0a /* Special Character Register 2 */
-#define CD180_SCHR3 0x0b /* Special Character Register 3 */
-#define CD180_SCHR4 0x0c /* Special Character Register 4 */
-#define CD180_MCR 0x12 /* Modem Change Register */
-#define CD180_MCOR1 0x10 /* Modem Change Option 1 Register */
-#define CD180_MCOR2 0x11 /* Modem Change Option 2 Register */
-#define CD180_MSVR 0x28 /* Modem Signal Value Register */
-#define CD180_MSVRTS 0x29 /* Modem Signal Value RTS */
-#define CD180_MSVDTR 0x2a /* Modem Signal Value DTR */
-
-/* Global Interrupt Vector Register (R/W) */
-
-#define GSVR_ITMASK 0x07 /* Interrupt type mask */
-#define GSVR_IT_MDM 0x01 /* Modem Signal Change Interrupt */
-#define GSVR_IT_TX 0x02 /* Transmit Data Interrupt */
-#define GSVR_IT_RGD 0x03 /* Receive Good Data Interrupt */
-#define GSVR_IT_REXC 0x07 /* Receive Exception Interrupt */
-
-
-/* Global Interrupt Channel Register (R/W) */
-
-#define GSCR_CHAN 0x1c /* Channel Number Mask */
-#define GSCR_CHAN_OFF 2 /* Channel Number Offset */
-
-
-/* Channel Address Register (R/W) */
-
-#define CAR_CHAN 0x07 /* Channel Number Mask */
-
-
-/* Receive Character Status Register (R/O) */
-
-#define RCSR_TOUT 0x80 /* Rx Timeout */
-#define RCSR_SCDET 0x70 /* Special Character Detected Mask */
-#define RCSR_NO_SC 0x00 /* No Special Characters Detected */
-#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */
-#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */
-#define RCSR_SC_3 0x30 /* Special Char 3 Detected */
-#define RCSR_SC_4 0x40 /* Special Char 4 Detected */
-#define RCSR_BREAK 0x08 /* Break has been detected */
-#define RCSR_PE 0x04 /* Parity Error */
-#define RCSR_FE 0x02 /* Frame Error */
-#define RCSR_OE 0x01 /* Overrun Error */
-
-
-/* Channel Command Register (R/W) (commands in groups can be OR-ed) */
-
-#define CCR_HARDRESET 0x81 /* Reset the chip */
-
-#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */
-
-#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */
-#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */
-#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */
-
-#define CCR_SSCH1 0x21 /* Send Special Character 1 */
-
-#define CCR_SSCH2 0x22 /* Send Special Character 2 */
-
-#define CCR_SSCH3 0x23 /* Send Special Character 3 */
-
-#define CCR_SSCH4 0x24 /* Send Special Character 4 */
-
-#define CCR_TXEN 0x18 /* Enable Transmitter */
-#define CCR_RXEN 0x12 /* Enable Receiver */
-
-#define CCR_TXDIS 0x14 /* Disable Transmitter */
-#define CCR_RXDIS 0x11 /* Disable Receiver */
-
-
-/* Service Request Enable Register (R/W) */
-
-#define SRER_DSR 0x80 /* Enable interrupt on DSR change */
-#define SRER_CD 0x40 /* Enable interrupt on CD change */
-#define SRER_CTS 0x20 /* Enable interrupt on CTS change */
-#define SRER_RXD 0x10 /* Enable interrupt on Receive Data */
-#define SRER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */
-#define SRER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */
-#define SRER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */
-#define SRER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */
-
-
-/* Channel Option Register 1 (R/W) */
-
-#define COR1_ODDP 0x80 /* Odd Parity */
-#define COR1_PARMODE 0x60 /* Parity Mode mask */
-#define COR1_NOPAR 0x00 /* No Parity */
-#define COR1_FORCEPAR 0x20 /* Force Parity */
-#define COR1_NORMPAR 0x40 /* Normal Parity */
-#define COR1_IGNORE 0x10 /* Ignore Parity on RX */
-#define COR1_STOPBITS 0x0c /* Number of Stop Bits */
-#define COR1_1SB 0x00 /* 1 Stop Bit */
-#define COR1_15SB 0x04 /* 1.5 Stop Bits */
-#define COR1_2SB 0x08 /* 2 Stop Bits */
-#define COR1_CHARLEN 0x03 /* Character Length */
-#define COR1_5BITS 0x00 /* 5 bits */
-#define COR1_6BITS 0x01 /* 6 bits */
-#define COR1_7BITS 0x02 /* 7 bits */
-#define COR1_8BITS 0x03 /* 8 bits */
-
-
-/* Channel Option Register 2 (R/W) */
-
-#define COR2_IXM 0x80 /* Implied XON mode */
-#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */
-#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */
-#define COR2_LLM 0x10 /* Local Loopback Mode */
-#define COR2_RLM 0x08 /* Remote Loopback Mode */
-#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */
-#define COR2_CTSAE 0x02 /* CTS Automatic Enable */
-#define COR2_DSRAE 0x01 /* DSR Automatic Enable */
-
-
-/* Channel Option Register 3 (R/W) */
-
-#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */
-#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */
-#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */
-#define COR3_SCDE 0x10 /* Special Character Detection Enable */
-#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */
-
-
-/* Channel Control Status Register (R/O) */
-
-#define CCSR_RXEN 0x80 /* Receiver Enabled */
-#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */
-#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */
-#define CCSR_TXEN 0x08 /* Transmitter Enabled */
-#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */
-#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */
-
-
-/* Modem Change Option Register 1 (R/W) */
-
-#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */
-#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */
-#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */
-#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */
-#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */
-
-
-/* Modem Change Option Register 2 (R/W) */
-
-#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */
-#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */
-#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */
-
-
-/* Modem Change Register (R/W) */
-
-#define MCR_DSRCHG 0x80 /* DSR Changed */
-#define MCR_CDCHG 0x40 /* CD Changed */
-#define MCR_CTSCHG 0x20 /* CTS Changed */
-
-
-/* Modem Signal Value Register (R/W) */
-
-#define MSVR_DSR 0x80 /* Current state of DSR input */
-#define MSVR_CD 0x40 /* Current state of CD input */
-#define MSVR_CTS 0x20 /* Current state of CTS input */
-#define MSVR_DTR 0x02 /* Current state of DTR output */
-#define MSVR_RTS 0x01 /* Current state of RTS output */
-
-
-/* Service Request Status Register */
-
-#define SRSR_CMASK 0xC0 /* Current Service Context Mask */
-#define SRSR_CNONE 0x00 /* Not in a service context */
-#define SRSR_CRX 0x40 /* Rx Context */
-#define SRSR_CTX 0x80 /* Tx Context */
-#define SRSR_CMDM 0xC0 /* Modem Context */
-#define SRSR_ANYINT 0x6F /* Any interrupt flag */
-#define SRSR_RINT 0x10 /* Receive Interrupt */
-#define SRSR_TINT 0x04 /* Transmit Interrupt */
-#define SRSR_MINT 0x01 /* Modem Interrupt */
-#define SRSR_REXT 0x20 /* Receive External Interrupt */
-#define SRSR_TEXT 0x08 /* Transmit External Interrupt */
-#define SRSR_MEXT 0x02 /* Modem External Interrupt */
-
-
-/* Service Request Configuration Register */
-
-#define SRCR_PKGTYPE 0x80
-#define SRCR_REGACKEN 0x40
-#define SRCR_DAISYEN 0x20
-#define SRCR_GLOBPRI 0x10
-#define SRCR_UNFAIR 0x08
-#define SRCR_AUTOPRI 0x02
-#define SRCR_PRISEL 0x01
-
-/* Values for register-based Interrupt ACKs */
-#define CD180_ACK_MINT 0x75 /* goes to MSMR */
-#define CD180_ACK_TINT 0x76 /* goes to TSMR */
-#define CD180_ACK_RINT 0x77 /* goes to RSMR */
-
-/* Escape characters */
-
-#define CD180_C_ESC 0x00 /* Escape character */
-#define CD180_C_SBRK 0x81 /* Start sending BREAK */
-#define CD180_C_DELAY 0x82 /* Delay output */
-#define CD180_C_EBRK 0x83 /* Stop sending BREAK */
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 45cf5bc0bbe..44d2ef906ac 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -364,6 +364,7 @@ static int __init ts102_uctrl_init(void)
struct linux_prom_irqs tmp_irq[2];
unsigned int vaddr[2] = { 0, 0 };
int tmpnode, uctrlnode = prom_getchild(prom_root_node);
+ int err;
tmpnode = prom_searchsiblings(uctrlnode, "obio");
@@ -389,7 +390,12 @@ static int __init ts102_uctrl_init(void)
if(!driver->irq)
driver->irq = tmp_irq[0].pri;
- request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
+ err = request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
+ if (err) {
+ printk("%s: unable to register irq %d\n",
+ __FUNCTION__, driver->irq);
+ return err;
+ }
if (misc_register(&uctrl_dev)) {
printk("%s: unable to get misc minor %d\n",
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index f4440d32931..509ace7e688 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -38,6 +38,8 @@
* Fix some spin_locks.
* Do not call uart_add_one_port for absent ports.
* 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup.
+ * 1.08 Use platform_device.
+ * Fix and cleanup suspend/resume/initialization codes.
*/
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -50,7 +52,7 @@
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -60,7 +62,7 @@
#include <asm/io.h>
-static char *serial_version = "1.07";
+static char *serial_version = "1.08";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -94,12 +96,7 @@ static char *serial_name = "TX39/49 Serial driver";
struct uart_txx9_port {
struct uart_port port;
-
- /*
- * We provide a per-port pm hook.
- */
- void (*pm)(struct uart_port *port,
- unsigned int state, unsigned int old);
+ /* No additional info for now */
};
#define TXX9_REGION_SIZE 0x24
@@ -277,6 +274,31 @@ static void serial_txx9_enable_ms(struct uart_port *port)
/* TXX9-SIO can not control DTR... */
}
+static void serial_txx9_initialize(struct uart_port *port)
+{
+ struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+ unsigned int tmout = 10000;
+
+ sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
+ /* TX4925 BUG WORKAROUND. Accessing SIOC register
+ * immediately after soft reset causes bus error. */
+ mmiowb();
+ udelay(1);
+ while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout)
+ udelay(1);
+ /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
+ sio_set(up, TXX9_SIFCR,
+ TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
+ /* initial settings */
+ sio_out(up, TXX9_SILCR,
+ TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+ ((up->port.flags & UPF_TXX9_USE_SCLK) ?
+ TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+ sio_quot_set(up, uart_get_divisor(port, 9600));
+ sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+ sio_out(up, TXX9_SIDICR, 0);
+}
+
static inline void
receive_chars(struct uart_txx9_port *up, unsigned int *status)
{
@@ -657,9 +679,8 @@ static void
serial_txx9_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
- struct uart_txx9_port *up = (struct uart_txx9_port *)port;
- if (up->pm)
- up->pm(port, state, oldstate);
+ if (state == 0)
+ serial_txx9_initialize(port);
}
static int serial_txx9_request_resource(struct uart_txx9_port *up)
@@ -732,7 +753,6 @@ static int serial_txx9_request_port(struct uart_port *port)
static void serial_txx9_config_port(struct uart_port *port, int uflags)
{
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
- unsigned long flags;
int ret;
/*
@@ -749,30 +769,7 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags)
if (up->port.line == up->port.cons->index)
return;
#endif
- spin_lock_irqsave(&up->port.lock, flags);
- /*
- * Reset the UART.
- */
- sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
-#ifdef CONFIG_CPU_TX49XX
- /* TX4925 BUG WORKAROUND. Accessing SIOC register
- * immediately after soft reset causes bus error. */
- iob();
- udelay(1);
-#endif
- while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
- ;
- /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
- sio_set(up, TXX9_SIFCR,
- TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
- /* initial settings */
- sio_out(up, TXX9_SILCR,
- TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
- ((up->port.flags & UPF_TXX9_USE_SCLK) ?
- TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
- sio_quot_set(up, uart_get_divisor(port, 9600));
- sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
- spin_unlock_irqrestore(&up->port.lock, flags);
+ serial_txx9_initialize(port);
}
static int
@@ -818,7 +815,8 @@ static struct uart_ops serial_txx9_pops = {
static struct uart_txx9_port serial_txx9_ports[UART_NR];
-static void __init serial_txx9_register_ports(struct uart_driver *drv)
+static void __init serial_txx9_register_ports(struct uart_driver *drv,
+ struct device *dev)
{
int i;
@@ -827,6 +825,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv)
up->port.line = i;
up->port.ops = &serial_txx9_pops;
+ up->port.dev = dev;
if (up->port.iobase || up->port.mapbase)
uart_add_one_port(drv, &up->port);
}
@@ -898,7 +897,7 @@ serial_txx9_console_write(struct console *co, const char *s, unsigned int count)
sio_out(up, TXX9_SIDICR, ier);
}
-static int serial_txx9_console_setup(struct console *co, char *options)
+static int __init serial_txx9_console_setup(struct console *co, char *options)
{
struct uart_port *port;
struct uart_txx9_port *up;
@@ -919,17 +918,7 @@ static int serial_txx9_console_setup(struct console *co, char *options)
if (!port->ops)
return -ENODEV;
- /*
- * Disable UART interrupts, set DTR and RTS high
- * and set speed.
- */
- sio_out(up, TXX9_SIDICR, 0);
- /* initial settings */
- sio_out(up, TXX9_SILCR,
- TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
- ((port->flags & UPF_TXX9_USE_SCLK) ?
- TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
- sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+ serial_txx9_initialize(&up->port);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -981,31 +970,6 @@ int __init early_serial_txx9_setup(struct uart_port *port)
return 0;
}
-#ifdef ENABLE_SERIAL_TXX9_PCI
-#ifdef CONFIG_PM
-/**
- * serial_txx9_suspend_port - suspend one serial port
- * @line: serial line number
- *
- * Suspend one serial port.
- */
-static void serial_txx9_suspend_port(int line)
-{
- uart_suspend_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-
-/**
- * serial_txx9_resume_port - resume one serial port
- * @line: serial line number
- *
- * Resume one serial port.
- */
-static void serial_txx9_resume_port(int line)
-{
- uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-#endif
-
static DEFINE_MUTEX(serial_txx9_mutex);
/**
@@ -1028,8 +992,18 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
mutex_lock(&serial_txx9_mutex);
for (i = 0; i < UART_NR; i++) {
uart = &serial_txx9_ports[i];
- if (!(uart->port.iobase || uart->port.mapbase))
+ if (uart_match_port(&uart->port, port)) {
+ uart_remove_one_port(&serial_txx9_reg, &uart->port);
break;
+ }
+ }
+ if (i == UART_NR) {
+ /* Find unused port */
+ for (i = 0; i < UART_NR; i++) {
+ uart = &serial_txx9_ports[i];
+ if (!(uart->port.iobase || uart->port.mapbase))
+ break;
+ }
}
if (i < UART_NR) {
uart->port.iobase = port->iobase;
@@ -1072,6 +1046,95 @@ static void __devexit serial_txx9_unregister_port(int line)
}
/*
+ * Register a set of serial devices attached to a platform device.
+ */
+static int __devinit serial_txx9_probe(struct platform_device *dev)
+{
+ struct uart_port *p = dev->dev.platform_data;
+ struct uart_port port;
+ int ret, i;
+
+ memset(&port, 0, sizeof(struct uart_port));
+ for (i = 0; p && p->uartclk != 0; p++, i++) {
+ port.iobase = p->iobase;
+ port.membase = p->membase;
+ port.irq = p->irq;
+ port.uartclk = p->uartclk;
+ port.iotype = p->iotype;
+ port.flags = p->flags;
+ port.mapbase = p->mapbase;
+ port.dev = &dev->dev;
+ ret = serial_txx9_register_port(&port);
+ if (ret < 0) {
+ dev_err(&dev->dev, "unable to register port at index %d "
+ "(IO%x MEM%lx IRQ%d): %d\n", i,
+ p->iobase, p->mapbase, p->irq, ret);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial_txx9_remove(struct platform_device *dev)
+{
+ int i;
+
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+ if (up->port.dev == &dev->dev)
+ serial_txx9_unregister_port(i);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int serial_txx9_suspend(struct platform_device *dev, pm_message_t state)
+{
+ int i;
+
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+ uart_suspend_port(&serial_txx9_reg, &up->port);
+ }
+
+ return 0;
+}
+
+static int serial_txx9_resume(struct platform_device *dev)
+{
+ int i;
+
+ for (i = 0; i < UART_NR; i++) {
+ struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+ if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+ uart_resume_port(&serial_txx9_reg, &up->port);
+ }
+
+ return 0;
+}
+#endif
+
+static struct platform_driver serial_txx9_plat_driver = {
+ .probe = serial_txx9_probe,
+ .remove = __devexit_p(serial_txx9_remove),
+#ifdef CONFIG_PM
+ .suspend = serial_txx9_suspend,
+ .resume = serial_txx9_resume,
+#endif
+ .driver = {
+ .name = "serial_txx9",
+ .owner = THIS_MODULE,
+ },
+};
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
+/*
* Probe one serial board. Unfortunately, there is no rhyme nor reason
* to the arrangement of serial ports on a PCI card.
*/
@@ -1097,20 +1160,22 @@ pciserial_txx9_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
line = serial_txx9_register_port(&port);
if (line < 0) {
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
+ pci_disable_device(dev);
+ return line;
}
- pci_set_drvdata(dev, (void *)(long)line);
+ pci_set_drvdata(dev, &serial_txx9_ports[line]);
return 0;
}
static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
{
- int line = (int)(long)pci_get_drvdata(dev);
+ struct uart_txx9_port *up = pci_get_drvdata(dev);
pci_set_drvdata(dev, NULL);
- if (line) {
- serial_txx9_unregister_port(line);
+ if (up) {
+ serial_txx9_unregister_port(up->port.line);
pci_disable_device(dev);
}
}
@@ -1118,10 +1183,10 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
#ifdef CONFIG_PM
static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
{
- int line = (int)(long)pci_get_drvdata(dev);
+ struct uart_txx9_port *up = pci_get_drvdata(dev);
- if (line)
- serial_txx9_suspend_port(line);
+ if (up)
+ uart_suspend_port(&serial_txx9_reg, &up->port);
pci_save_state(dev);
pci_set_power_state(dev, pci_choose_state(dev, state));
return 0;
@@ -1129,15 +1194,12 @@ static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
static int pciserial_txx9_resume_one(struct pci_dev *dev)
{
- int line = (int)(long)pci_get_drvdata(dev);
+ struct uart_txx9_port *up = pci_get_drvdata(dev);
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
-
- if (line) {
- pci_enable_device(dev);
- serial_txx9_resume_port(line);
- }
+ if (up)
+ uart_resume_port(&serial_txx9_reg, &up->port);
return 0;
}
#endif
@@ -1161,6 +1223,8 @@ static struct pci_driver serial_txx9_pci_driver = {
MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
#endif /* ENABLE_SERIAL_TXX9_PCI */
+static struct platform_device *serial_txx9_plat_devs;
+
static int __init serial_txx9_init(void)
{
int ret;
@@ -1168,13 +1232,39 @@ static int __init serial_txx9_init(void)
printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
ret = uart_register_driver(&serial_txx9_reg);
- if (ret >= 0) {
- serial_txx9_register_ports(&serial_txx9_reg);
+ if (ret)
+ goto out;
+
+ serial_txx9_plat_devs = platform_device_alloc("serial_txx9", -1);
+ if (!serial_txx9_plat_devs) {
+ ret = -ENOMEM;
+ goto unreg_uart_drv;
+ }
+
+ ret = platform_device_add(serial_txx9_plat_devs);
+ if (ret)
+ goto put_dev;
+
+ serial_txx9_register_ports(&serial_txx9_reg,
+ &serial_txx9_plat_devs->dev);
+
+ ret = platform_driver_register(&serial_txx9_plat_driver);
+ if (ret)
+ goto del_dev;
#ifdef ENABLE_SERIAL_TXX9_PCI
- ret = pci_register_driver(&serial_txx9_pci_driver);
+ ret = pci_register_driver(&serial_txx9_pci_driver);
#endif
- }
+ if (ret == 0)
+ goto out;
+
+ del_dev:
+ platform_device_del(serial_txx9_plat_devs);
+ put_dev:
+ platform_device_put(serial_txx9_plat_devs);
+ unreg_uart_drv:
+ uart_unregister_driver(&serial_txx9_reg);
+ out:
return ret;
}
@@ -1185,6 +1275,8 @@ static void __exit serial_txx9_exit(void)
#ifdef ENABLE_SERIAL_TXX9_PCI
pci_unregister_driver(&serial_txx9_pci_driver);
#endif
+ platform_driver_unregister(&serial_txx9_plat_driver);
+ platform_device_unregister(serial_txx9_plat_devs);
for (i = 0; i < UART_NR; i++) {
struct uart_txx9_port *up = &serial_txx9_ports[i];
if (up->port.iobase || up->port.mapbase)
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 34e9bac319b..b6078706fb9 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -4,7 +4,7 @@
usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \
config.o file.o buffer.o sysfs.o endpoint.o \
- devio.o notify.o generic.o
+ devio.o notify.o generic.o quirks.o
ifeq ($(CONFIG_PCI),y)
usbcore-objs += hcd-pci.o
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 2aded261f42..9e3e943f313 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -366,19 +366,8 @@ void usb_driver_release_interface(struct usb_driver *driver,
EXPORT_SYMBOL(usb_driver_release_interface);
/* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_interface *interface,
- const struct usb_device_id *id)
+int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
{
- struct usb_host_interface *intf;
- struct usb_device *dev;
-
- /* proc_connectinfo in devio.c may call us with id == NULL. */
- if (id == NULL)
- return 0;
-
- intf = interface->cur_altsetting;
- dev = interface_to_usbdev(interface);
-
if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
return 0;
@@ -409,6 +398,26 @@ int usb_match_one_id(struct usb_interface *interface,
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
return 0;
+ return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_host_interface *intf;
+ struct usb_device *dev;
+
+ /* proc_connectinfo in devio.c may call us with id == NULL. */
+ if (id == NULL)
+ return 0;
+
+ intf = interface->cur_altsetting;
+ dev = interface_to_usbdev(interface);
+
+ if (!usb_match_device(dev, id))
+ return 0;
+
/* The interface class, subclass, and protocol should never be
* checked for a match if the device class is Vendor Specific,
* unless the match record specifies the Vendor ID. */
@@ -954,12 +963,16 @@ static int autosuspend_check(struct usb_device *udev)
int i;
struct usb_interface *intf;
- /* For autosuspend, fail fast if anything is in use.
- * Also fail if any interfaces require remote wakeup but it
- * isn't available. */
+ /* For autosuspend, fail fast if anything is in use or autosuspend
+ * is disabled. Also fail if any interfaces require remote wakeup
+ * but it isn't available.
+ */
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
if (udev->pm_usage_cnt > 0)
return -EBUSY;
+ if (!udev->autosuspend_delay)
+ return -EPERM;
+
if (udev->actconfig) {
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
@@ -982,7 +995,7 @@ static int autosuspend_check(struct usb_device *udev)
#define autosuspend_check(udev) 0
-#endif
+#endif /* CONFIG_USB_SUSPEND */
/**
* usb_suspend_both - suspend a USB device and its interfaces
@@ -1177,7 +1190,7 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
udev->pm_usage_cnt -= inc_usage_cnt;
} else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
- USB_AUTOSUSPEND_DELAY);
+ udev->autosuspend_delay);
usb_pm_unlock(udev);
return status;
}
@@ -1212,6 +1225,26 @@ void usb_autosuspend_device(struct usb_device *udev)
}
/**
+ * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces
+ * @udev: the usb_device to autosuspend
+ *
+ * This routine should be called when a core subsystem thinks @udev may
+ * be ready to autosuspend.
+ *
+ * @udev's usage counter left unchanged. If it or any of the usage counters
+ * for an active interface is greater than 0, or autosuspend is not allowed
+ * for any other reason, no autosuspend request will be queued.
+ *
+ * This routine can run only in process context.
+ */
+void usb_try_autosuspend_device(struct usb_device *udev)
+{
+ usb_autopm_do_device(udev, 0);
+ // dev_dbg(&udev->dev, "%s: cnt %d\n",
+ // __FUNCTION__, udev->pm_usage_cnt);
+}
+
+/**
* usb_autoresume_device - immediately autoresume a USB device and its interfaces
* @udev: the usb_device to autoresume
*
@@ -1261,7 +1294,7 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
intf->pm_usage_cnt -= inc_usage_cnt;
} else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
- USB_AUTOSUSPEND_DELAY);
+ udev->autosuspend_delay);
}
usb_pm_unlock(udev);
return status;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 50c0db15304..41400743ce2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1287,6 +1287,9 @@ int usb_new_device(struct usb_device *udev)
if (!try_module_get(THIS_MODULE))
return -EINVAL;
+ /* Determine quirks */
+ usb_detect_quirks(udev);
+
err = usb_get_configuration(udev);
if (err < 0) {
dev_err(&udev->dev, "can't read configurations, error %d\n",
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 74edaea5665..2f17468b5c1 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -11,6 +11,7 @@
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/device.h>
+#include <linux/usb/quirks.h>
#include <asm/byteorder.h>
#include <asm/scatterlist.h>
@@ -685,7 +686,10 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
/* Try to read the string descriptor by asking for the maximum
* possible number of bytes */
- rc = usb_get_string(dev, langid, index, buf, 255);
+ if (dev->quirks & USB_QUIRK_STRING_FETCH_255)
+ rc = -EIO;
+ else
+ rc = usb_get_string(dev, langid, index, buf, 255);
/* If that failed try to read the descriptor length, then
* ask for just that many bytes */
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
new file mode 100644
index 00000000000..0e5c646cb4f
--- /dev/null
+++ b/drivers/usb/core/quirks.c
@@ -0,0 +1,77 @@
+/*
+ * USB device quirk handling logic and table
+ *
+ * Copyright (c) 2007 Oliver Neukum
+ * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/usb/quirks.h>
+#include "usb.h"
+
+/* List of quirky USB devices. Please keep this list ordered by:
+ * 1) Vendor ID
+ * 2) Product ID
+ * 3) Class ID
+ *
+ * as we want specific devices to be overridden first, and only after that, any
+ * class specific quirks.
+ *
+ * Right now the logic aborts if it finds a valid device in the table, we might
+ * want to change that in the future if it turns out that a whole class of
+ * devices is broken...
+ */
+static const struct usb_device_id usb_quirk_list[] = {
+ /* HP 5300/5370C scanner */
+ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+
+ /* Elsa MicroLink 56k (V.250) */
+ { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+ { } /* terminating entry must be last */
+};
+
+static void usb_autosuspend_quirk(struct usb_device *udev)
+{
+#ifdef CONFIG_USB_SUSPEND
+ /* disable autosuspend, but allow the user to re-enable it via sysfs */
+ udev->autosuspend_delay = 0;
+#endif
+}
+
+static const struct usb_device_id *find_id(struct usb_device *udev)
+{
+ const struct usb_device_id *id = usb_quirk_list;
+
+ for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+ id->driver_info; id++) {
+ if (usb_match_device(udev, id))
+ return id;
+ }
+ return NULL;
+}
+
+/*
+ * Detect any quirks the device has, and do any housekeeping for it if needed.
+ */
+void usb_detect_quirks(struct usb_device *udev)
+{
+ const struct usb_device_id *id = usb_quirk_list;
+
+ id = find_id(udev);
+ if (id)
+ udev->quirks = (u32)(id->driver_info);
+ if (udev->quirks)
+ dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
+ udev->quirks);
+
+ /* do any special quirk handling here if needed */
+ if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND)
+ usb_autosuspend_quirk(udev);
+}
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 0edfbafd702..311d5df8038 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -148,6 +148,75 @@ show_maxchild(struct device *dev, struct device_attribute *attr, char *buf)
}
static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
+static ssize_t
+show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct usb_device *udev;
+
+ udev = to_usb_device(dev);
+ return sprintf(buf, "0x%x\n", udev->quirks);
+}
+static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
+
+#ifdef CONFIG_USB_SUSPEND
+
+static ssize_t
+show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct usb_device *udev = to_usb_device(dev);
+
+ return sprintf(buf, "%u\n", udev->autosuspend_delay / HZ);
+}
+
+static ssize_t
+set_autosuspend(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ unsigned value, old;
+
+ if (sscanf(buf, "%u", &value) != 1 || value >= INT_MAX/HZ)
+ return -EINVAL;
+ value *= HZ;
+
+ old = udev->autosuspend_delay;
+ udev->autosuspend_delay = value;
+ if (value > 0 && old == 0)
+ usb_try_autosuspend_device(udev);
+
+ return count;
+}
+
+static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR,
+ show_autosuspend, set_autosuspend);
+
+static char power_group[] = "power";
+
+static int add_power_attributes(struct device *dev)
+{
+ int rc = 0;
+
+ if (is_usb_device(dev))
+ rc = sysfs_add_file_to_group(&dev->kobj,
+ &dev_attr_autosuspend.attr,
+ power_group);
+ return rc;
+}
+
+static void remove_power_attributes(struct device *dev)
+{
+ sysfs_remove_file_from_group(&dev->kobj,
+ &dev_attr_autosuspend.attr,
+ power_group);
+}
+
+#else
+
+#define add_power_attributes(dev) 0
+#define remove_power_attributes(dev) do {} while (0)
+
+#endif /* CONFIG_USB_SUSPEND */
+
/* Descriptor fields */
#define usb_descriptor_attr_le16(field, format_string) \
static ssize_t \
@@ -204,6 +273,7 @@ static struct attribute *dev_attrs[] = {
&dev_attr_devnum.attr,
&dev_attr_version.attr,
&dev_attr_maxchild.attr,
+ &dev_attr_quirks.attr,
NULL,
};
static struct attribute_group dev_attr_grp = {
@@ -219,6 +289,10 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
if (retval)
return retval;
+ retval = add_power_attributes(dev);
+ if (retval)
+ goto error;
+
if (udev->manufacturer) {
retval = device_create_file(dev, &dev_attr_manufacturer);
if (retval)
@@ -239,10 +313,7 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
goto error;
return 0;
error:
- usb_remove_ep_files(&udev->ep0);
- device_remove_file(dev, &dev_attr_manufacturer);
- device_remove_file(dev, &dev_attr_product);
- device_remove_file(dev, &dev_attr_serial);
+ usb_remove_sysfs_dev_files(udev);
return retval;
}
@@ -251,14 +322,11 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
struct device *dev = &udev->dev;
usb_remove_ep_files(&udev->ep0);
+ device_remove_file(dev, &dev_attr_manufacturer);
+ device_remove_file(dev, &dev_attr_product);
+ device_remove_file(dev, &dev_attr_serial);
+ remove_power_attributes(dev);
sysfs_remove_group(&dev->kobj, &dev_attr_grp);
-
- if (udev->manufacturer)
- device_remove_file(dev, &dev_attr_manufacturer);
- if (udev->product)
- device_remove_file(dev, &dev_attr_product);
- if (udev->serial)
- device_remove_file(dev, &dev_attr_serial);
}
/* Interface fields */
@@ -362,33 +430,28 @@ static inline void usb_remove_intf_ep_files(struct usb_interface *intf)
int usb_create_sysfs_intf_files(struct usb_interface *intf)
{
+ struct device *dev = &intf->dev;
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_host_interface *alt = intf->cur_altsetting;
int retval;
- retval = sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
+ retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
if (retval)
- goto error;
+ return retval;
if (alt->string == NULL)
alt->string = usb_cache_string(udev, alt->desc.iInterface);
if (alt->string)
- retval = device_create_file(&intf->dev, &dev_attr_interface);
+ retval = device_create_file(dev, &dev_attr_interface);
usb_create_intf_ep_files(intf, udev);
return 0;
-error:
- if (alt->string)
- device_remove_file(&intf->dev, &dev_attr_interface);
- sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
- usb_remove_intf_ep_files(intf);
- return retval;
}
void usb_remove_sysfs_intf_files(struct usb_interface *intf)
{
- usb_remove_intf_ep_files(intf);
- sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
+ struct device *dev = &intf->dev;
- if (intf->cur_altsetting->string)
- device_remove_file(&intf->dev, &dev_attr_interface);
+ usb_remove_intf_ep_files(intf);
+ device_remove_file(dev, &dev_attr_interface);
+ sysfs_remove_group(&dev->kobj, &intf_attr_grp);
}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 3db721cd557..54b42ce311c 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -22,6 +22,7 @@
*/
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/slab.h>
@@ -50,6 +51,16 @@ static int nousb; /* Disable USB when built into kernel image */
struct workqueue_struct *ksuspend_usb_wq; /* For autosuspend */
+#ifdef CONFIG_USB_SUSPEND
+static int usb_autosuspend_delay = 2; /* Default delay value,
+ * in seconds */
+module_param_named(autosuspend, usb_autosuspend_delay, uint, 0644);
+MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
+
+#else
+#define usb_autosuspend_delay 0
+#endif
+
/**
* usb_ifnum_to_if - get the interface object with a given interface number
@@ -306,6 +317,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1)
#ifdef CONFIG_PM
mutex_init(&dev->pm_mutex);
INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
+ dev->autosuspend_delay = usb_autosuspend_delay * HZ;
#endif
return dev;
}
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 17830a81be1..08b5a04e375 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -13,6 +13,7 @@ extern void usb_disable_interface (struct usb_device *dev,
struct usb_interface *intf);
extern void usb_release_interface_cache(struct kref *ref);
extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
+extern void usb_detect_quirks(struct usb_device *udev);
extern int usb_get_device_descriptor(struct usb_device *dev,
unsigned int size);
@@ -21,6 +22,8 @@ extern int usb_set_configuration(struct usb_device *dev, int configuration);
extern void usb_kick_khubd(struct usb_device *dev);
extern void usb_resume_root_hub(struct usb_device *dev);
+extern int usb_match_device(struct usb_device *dev,
+ const struct usb_device_id *id);
extern int usb_hub_init(void);
extern void usb_hub_cleanup(void);
@@ -62,14 +65,14 @@ static inline void usb_pm_unlock(struct usb_device *udev) {}
#ifdef CONFIG_USB_SUSPEND
-#define USB_AUTOSUSPEND_DELAY (HZ*2)
-
extern void usb_autosuspend_device(struct usb_device *udev);
+extern void usb_try_autosuspend_device(struct usb_device *udev);
extern int usb_autoresume_device(struct usb_device *udev);
#else
-#define usb_autosuspend_device(udev) do {} while (0)
+#define usb_autosuspend_device(udev) do {} while (0)
+#define usb_try_autosuspend_device(udev) do {} while (0)
static inline int usb_autoresume_device(struct usb_device *udev)
{
return 0;
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 34296e79edc..188c74a9521 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -553,6 +553,7 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
{
struct kiocb_priv *priv = iocb->private;
ssize_t len, total;
+ void *to_copy;
int i;
/* we "retry" to get the right mm context for this: */
@@ -560,10 +561,11 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
/* copy stuff into user buffers */
total = priv->actual;
len = 0;
+ to_copy = priv->buf;
for (i=0; i < priv->nr_segs; i++) {
ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total);
- if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) {
+ if (copy_to_user(priv->iv[i].iov_base, to_copy, this)) {
if (len == 0)
len = -EFAULT;
break;
@@ -571,6 +573,7 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb)
total -= this;
len += this;
+ to_copy += this;
if (total == 0)
break;
}
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 5d6c06bc452..8d24d3dc0a6 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -196,7 +196,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
struct uhci_td *td = list_entry(urbp->td_list.next,
struct uhci_td, list);
- if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
+ if (element != LINK_TO_TD(td))
out += sprintf(out, "%*s Element != First TD\n",
space, "");
i = nurbs = 0;
@@ -220,16 +220,6 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
return out - buf;
}
-static const char * const qh_names[] = {
- "skel_unlink_qh", "skel_iso_qh",
- "skel_int128_qh", "skel_int64_qh",
- "skel_int32_qh", "skel_int16_qh",
- "skel_int8_qh", "skel_int4_qh",
- "skel_int2_qh", "skel_int1_qh",
- "skel_ls_control_qh", "skel_fs_control_qh",
- "skel_bulk_qh", "skel_term_qh"
-};
-
static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
{
char *out = buf;
@@ -352,6 +342,12 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
struct uhci_td *td;
struct list_head *tmp, *head;
int nframes, nerrs;
+ __le32 link;
+
+ static const char * const qh_names[] = {
+ "unlink", "iso", "int128", "int64", "int32", "int16",
+ "int8", "int4", "int2", "async", "term"
+ };
out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
out += sprintf(out, "HC status\n");
@@ -374,7 +370,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
nframes = 10;
nerrs = 0;
for (i = 0; i < UHCI_NUMFRAMES; ++i) {
- __le32 link, qh_dma;
+ __le32 qh_dma;
j = 0;
td = uhci->frame_cpu[i];
@@ -393,7 +389,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
do {
td = list_entry(tmp, struct uhci_td, fl_list);
tmp = tmp->next;
- if (cpu_to_le32(td->dma_handle) != link) {
+ if (link != LINK_TO_TD(td)) {
if (nframes > 0)
out += sprintf(out, " link does "
"not match list entry!\n");
@@ -430,23 +426,21 @@ check_link:
for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
int cnt = 0;
+ __le32 fsbr_link = 0;
qh = uhci->skelqh[i];
- out += sprintf(out, "- %s\n", qh_names[i]); \
+ out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
out += uhci_show_qh(qh, out, len - (out - buf), 4);
/* Last QH is the Terminating QH, it's different */
- if (i == UHCI_NUM_SKELQH - 1) {
- if (qh->link != UHCI_PTR_TERM)
- out += sprintf(out, " bandwidth reclamation on!\n");
-
- if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle))
+ if (i == SKEL_TERM) {
+ if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
out += sprintf(out, " skel_term_qh element is not set to term_td!\n");
-
+ if (link == LINK_TO_QH(uhci->skel_term_qh))
+ goto check_qh_link;
continue;
}
- j = (i < 9) ? 9 : i+1; /* Next skeleton */
head = &qh->node;
tmp = head->next;
@@ -456,15 +450,26 @@ check_link:
if (++cnt <= 10)
out += uhci_show_qh(qh, out,
len - (out - buf), 4);
+ if (!fsbr_link && qh->skel >= SKEL_FSBR)
+ fsbr_link = LINK_TO_QH(qh);
}
if ((cnt -= 10) > 0)
out += sprintf(out, " Skipped %d QHs\n", cnt);
- if (i > 1 && i < UHCI_NUM_SKELQH - 1) {
- if (qh->link !=
- (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH))
- out += sprintf(out, " last QH not linked to next skeleton!\n");
- }
+ link = UHCI_PTR_TERM;
+ if (i <= SKEL_ISO)
+ ;
+ else if (i < SKEL_ASYNC)
+ link = LINK_TO_QH(uhci->skel_async_qh);
+ else if (!uhci->fsbr_is_on)
+ ;
+ else if (fsbr_link)
+ link = fsbr_link;
+ else
+ link = LINK_TO_QH(uhci->skel_term_qh);
+check_qh_link:
+ if (qh->link != link)
+ out += sprintf(out, " last QH not linked to next skeleton!\n");
}
return out - buf;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index ded4df30a63..44da4334f1d 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -13,7 +13,7 @@
* (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
* support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
* (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
*
* Intel documents this fairly well, and as far as I know there
* are no royalties or anything like that, but even so there are
@@ -107,16 +107,16 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)
* interrupt QHs, which will help spread out bandwidth utilization.
*
* ffs (Find First bit Set) does exactly what we need:
- * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8],
- * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
+ * 1,3,5,... => ffs = 0 => use period-2 QH = skelqh[8],
+ * 2,6,10,... => ffs = 1 => use period-4 QH = skelqh[7], etc.
* ffs >= 7 => not on any high-period queue, so use
- * skel_int1_qh = skelqh[9].
+ * period-1 QH = skelqh[9].
* Add in UHCI_NUMFRAMES to insure at least one bit is set.
*/
skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
if (skelnum <= 1)
skelnum = 9;
- return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle);
+ return LINK_TO_QH(uhci->skelqh[skelnum]);
}
#include "uhci-debug.c"
@@ -540,16 +540,18 @@ static void uhci_shutdown(struct pci_dev *pdev)
*
* The hardware doesn't really know any difference
* in the queues, but the order does matter for the
- * protocols higher up. The order is:
+ * protocols higher up. The order in which the queues
+ * are encountered by the hardware is:
*
- * - any isochronous events handled before any
+ * - All isochronous events are handled before any
* of the queues. We don't do that here, because
* we'll create the actual TD entries on demand.
- * - The first queue is the interrupt queue.
- * - The second queue is the control queue, split into low- and full-speed
- * - The third queue is bulk queue.
- * - The fourth queue is the bandwidth reclamation queue, which loops back
- * to the full-speed control queue.
+ * - The first queue is the high-period interrupt queue.
+ * - The second queue is the period-1 interrupt and async
+ * (low-speed control, full-speed control, then bulk) queue.
+ * - The third queue is the terminating bandwidth reclamation queue,
+ * which contains no members, loops back to itself, and is present
+ * only when FSBR is on and there are no full-speed control or bulk QHs.
*/
static int uhci_start(struct usb_hcd *hcd)
{
@@ -626,34 +628,18 @@ static int uhci_start(struct usb_hcd *hcd)
}
/*
- * 8 Interrupt queues; link all higher int queues to int1,
- * then link int1 to control and control to bulk
+ * 8 Interrupt queues; link all higher int queues to int1 = async
*/
- uhci->skel_int128_qh->link =
- uhci->skel_int64_qh->link =
- uhci->skel_int32_qh->link =
- uhci->skel_int16_qh->link =
- uhci->skel_int8_qh->link =
- uhci->skel_int4_qh->link =
- uhci->skel_int2_qh->link = UHCI_PTR_QH |
- cpu_to_le32(uhci->skel_int1_qh->dma_handle);
-
- uhci->skel_int1_qh->link = UHCI_PTR_QH |
- cpu_to_le32(uhci->skel_ls_control_qh->dma_handle);
- uhci->skel_ls_control_qh->link = UHCI_PTR_QH |
- cpu_to_le32(uhci->skel_fs_control_qh->dma_handle);
- uhci->skel_fs_control_qh->link = UHCI_PTR_QH |
- cpu_to_le32(uhci->skel_bulk_qh->dma_handle);
- uhci->skel_bulk_qh->link = UHCI_PTR_QH |
- cpu_to_le32(uhci->skel_term_qh->dma_handle);
+ for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
+ uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
+ uhci->skel_async_qh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
/* This dummy TD is to work around a bug in Intel PIIX controllers */
uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
- (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
- uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle);
-
- uhci->skel_term_qh->link = UHCI_PTR_TERM;
- uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle);
+ (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
+ uhci->term_td->link = UHCI_PTR_TERM;
+ uhci->skel_async_qh->element = uhci->skel_term_qh->element =
+ LINK_TO_TD(uhci->term_td);
/*
* Fill the frame list: make all entries point to the proper
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 74469b5bcb6..1b3d23406ac 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -129,11 +129,12 @@ struct uhci_qh {
__le32 element; /* Queue element (TD) pointer */
/* Software fields */
+ dma_addr_t dma_handle;
+
struct list_head node; /* Node in the list of QHs */
struct usb_host_endpoint *hep; /* Endpoint information */
struct usb_device *udev;
struct list_head queue; /* Queue of urbps for this QH */
- struct uhci_qh *skel; /* Skeleton for this QH */
struct uhci_td *dummy_td; /* Dummy TD to end the queue */
struct uhci_td *post_td; /* Last TD completed */
@@ -149,8 +150,7 @@ struct uhci_qh {
int state; /* QH_STATE_xxx; see above */
int type; /* Queue type (control, bulk, etc) */
-
- dma_addr_t dma_handle;
+ int skel; /* Skeleton queue number */
unsigned int initial_toggle:1; /* Endpoint's current toggle value */
unsigned int needs_fixup:1; /* Must fix the TD toggle values */
@@ -171,6 +171,8 @@ static inline __le32 qh_element(struct uhci_qh *qh) {
return element;
}
+#define LINK_TO_QH(qh) (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle))
+
/*
* Transfer Descriptors
@@ -264,6 +266,8 @@ static inline u32 td_status(struct uhci_td *td) {
return le32_to_cpu(status);
}
+#define LINK_TO_TD(td) (cpu_to_le32((td)->dma_handle))
+
/*
* Skeleton Queue Headers
@@ -272,12 +276,13 @@ static inline u32 td_status(struct uhci_td *td) {
/*
* The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for
* automatic queuing. To make it easy to insert entries into the schedule,
- * we have a skeleton of QHs for each predefined Interrupt latency,
- * low-speed control, full-speed control, bulk, and terminating QH
- * (see explanation for the terminating QH below).
+ * we have a skeleton of QHs for each predefined Interrupt latency.
+ * Asynchronous QHs (low-speed control, full-speed control, and bulk)
+ * go onto the period-1 interrupt list, since they all get accessed on
+ * every frame.
*
- * When we want to add a new QH, we add it to the end of the list for the
- * skeleton QH. For instance, the schedule list can look like this:
+ * When we want to add a new QH, we add it to the list starting from the
+ * appropriate skeleton QH. For instance, the schedule can look like this:
*
* skel int128 QH
* dev 1 interrupt QH
@@ -285,50 +290,47 @@ static inline u32 td_status(struct uhci_td *td) {
* skel int64 QH
* skel int32 QH
* ...
- * skel int1 QH
- * skel low-speed control QH
- * dev 5 control QH
- * skel full-speed control QH
- * skel bulk QH
+ * skel int1 + async QH
+ * dev 5 low-speed control QH
* dev 1 bulk QH
* dev 2 bulk QH
- * skel terminating QH
*
- * The terminating QH is used for 2 reasons:
- * - To place a terminating TD which is used to workaround a PIIX bug
- * (see Intel errata for explanation), and
- * - To loop back to the full-speed control queue for full-speed bandwidth
- * reclamation.
+ * There is a special terminating QH used to keep full-speed bandwidth
+ * reclamation active when no full-speed control or bulk QHs are linked
+ * into the schedule. It has an inactive TD (to work around a PIIX bug,
+ * see the Intel errata) and it points back to itself.
*
- * There's a special skeleton QH for Isochronous QHs. It never appears
- * on the schedule, and Isochronous TDs go on the schedule before the
+ * There's a special skeleton QH for Isochronous QHs which never appears
+ * on the schedule. Isochronous TDs go on the schedule before the
* the skeleton QHs. The hardware accesses them directly rather than
* through their QH, which is used only for bookkeeping purposes.
* While the UHCI spec doesn't forbid the use of QHs for Isochronous,
* it doesn't use them either. And the spec says that queues never
* advance on an error completion status, which makes them totally
* unsuitable for Isochronous transfers.
+ *
+ * There's also a special skeleton QH used for QHs which are in the process
+ * of unlinking and so may still be in use by the hardware. It too never
+ * appears on the schedule.
*/
-#define UHCI_NUM_SKELQH 14
-#define skel_unlink_qh skelqh[0]
-#define skel_iso_qh skelqh[1]
-#define skel_int128_qh skelqh[2]
-#define skel_int64_qh skelqh[3]
-#define skel_int32_qh skelqh[4]
-#define skel_int16_qh skelqh[5]
-#define skel_int8_qh skelqh[6]
-#define skel_int4_qh skelqh[7]
-#define skel_int2_qh skelqh[8]
-#define skel_int1_qh skelqh[9]
-#define skel_ls_control_qh skelqh[10]
-#define skel_fs_control_qh skelqh[11]
-#define skel_bulk_qh skelqh[12]
-#define skel_term_qh skelqh[13]
-
-/* Find the skelqh entry corresponding to an interval exponent */
-#define UHCI_SKEL_INDEX(exponent) (9 - exponent)
-
+#define UHCI_NUM_SKELQH 11
+#define SKEL_UNLINK 0
+#define skel_unlink_qh skelqh[SKEL_UNLINK]
+#define SKEL_ISO 1
+#define skel_iso_qh skelqh[SKEL_ISO]
+ /* int128, int64, ..., int1 = 2, 3, ..., 9 */
+#define SKEL_INDEX(exponent) (9 - exponent)
+#define SKEL_ASYNC 9
+#define skel_async_qh skelqh[SKEL_ASYNC]
+#define SKEL_TERM 10
+#define skel_term_qh skelqh[SKEL_TERM]
+
+/* The following entries refer to sublists of skel_async_qh */
+#define SKEL_LS_CONTROL 20
+#define SKEL_FS_CONTROL 21
+#define SKEL_FSBR SKEL_FS_CONTROL
+#define SKEL_BULK 22
/*
* The UHCI controller and root hub
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 68e66b33e72..f4ebdb3e488 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -13,7 +13,7 @@
* (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
* support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
* (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
*/
@@ -45,15 +45,43 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
*/
static void uhci_fsbr_on(struct uhci_hcd *uhci)
{
+ struct uhci_qh *fsbr_qh, *lqh, *tqh;
+
uhci->fsbr_is_on = 1;
- uhci->skel_term_qh->link = cpu_to_le32(
- uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
+ lqh = list_entry(uhci->skel_async_qh->node.prev,
+ struct uhci_qh, node);
+
+ /* Find the first FSBR QH. Linear search through the list is
+ * acceptable because normally FSBR gets turned on as soon as
+ * one QH needs it. */
+ fsbr_qh = NULL;
+ list_for_each_entry_reverse(tqh, &uhci->skel_async_qh->node, node) {
+ if (tqh->skel < SKEL_FSBR)
+ break;
+ fsbr_qh = tqh;
+ }
+
+ /* No FSBR QH means we must insert the terminating skeleton QH */
+ if (!fsbr_qh) {
+ uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
+ wmb();
+ lqh->link = uhci->skel_term_qh->link;
+
+ /* Otherwise loop the last QH to the first FSBR QH */
+ } else
+ lqh->link = LINK_TO_QH(fsbr_qh);
}
static void uhci_fsbr_off(struct uhci_hcd *uhci)
{
+ struct uhci_qh *lqh;
+
uhci->fsbr_is_on = 0;
- uhci->skel_term_qh->link = UHCI_PTR_TERM;
+ lqh = list_entry(uhci->skel_async_qh->node.prev,
+ struct uhci_qh, node);
+
+ /* End the async list normally and unlink the terminating QH */
+ lqh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
}
static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
@@ -158,11 +186,11 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
td->link = ltd->link;
wmb();
- ltd->link = cpu_to_le32(td->dma_handle);
+ ltd->link = LINK_TO_TD(td);
} else {
td->link = uhci->frame[framenum];
wmb();
- uhci->frame[framenum] = cpu_to_le32(td->dma_handle);
+ uhci->frame[framenum] = LINK_TO_TD(td);
uhci->frame_cpu[framenum] = td;
}
}
@@ -184,7 +212,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
struct uhci_td *ntd;
ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
- uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
+ uhci->frame[td->frame] = LINK_TO_TD(ntd);
uhci->frame_cpu[td->frame] = ntd;
}
} else {
@@ -405,12 +433,81 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
}
/*
- * Put a QH on the schedule in both hardware and software
+ * Link an Isochronous QH into its skeleton's list
*/
-static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+static inline void link_iso(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+ list_add_tail(&qh->node, &uhci->skel_iso_qh->node);
+
+ /* Isochronous QHs aren't linked by the hardware */
+}
+
+/*
+ * Link a high-period interrupt QH into the schedule at the end of its
+ * skeleton's list
+ */
+static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
struct uhci_qh *pqh;
+ list_add_tail(&qh->node, &uhci->skelqh[qh->skel]->node);
+
+ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+ qh->link = pqh->link;
+ wmb();
+ pqh->link = LINK_TO_QH(qh);
+}
+
+/*
+ * Link a period-1 interrupt or async QH into the schedule at the
+ * correct spot in the async skeleton's list, and update the FSBR link
+ */
+static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+ struct uhci_qh *pqh, *lqh;
+ __le32 link_to_new_qh;
+ __le32 *extra_link = &link_to_new_qh;
+
+ /* Find the predecessor QH for our new one and insert it in the list.
+ * The list of QHs is expected to be short, so linear search won't
+ * take too long. */
+ list_for_each_entry_reverse(pqh, &uhci->skel_async_qh->node, node) {
+ if (pqh->skel <= qh->skel)
+ break;
+ }
+ list_add(&qh->node, &pqh->node);
+ qh->link = pqh->link;
+
+ link_to_new_qh = LINK_TO_QH(qh);
+
+ /* If this is now the first FSBR QH, take special action */
+ if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
+ qh->skel >= SKEL_FSBR) {
+ lqh = list_entry(uhci->skel_async_qh->node.prev,
+ struct uhci_qh, node);
+
+ /* If the new QH is also the last one, we must unlink
+ * the terminating skeleton QH and make the new QH point
+ * back to itself. */
+ if (qh == lqh) {
+ qh->link = link_to_new_qh;
+ extra_link = &uhci->skel_term_qh->link;
+
+ /* Otherwise the last QH must point to the new QH */
+ } else
+ extra_link = &lqh->link;
+ }
+
+ /* Link it into the schedule */
+ wmb();
+ *extra_link = pqh->link = link_to_new_qh;
+}
+
+/*
+ * Put a QH on the schedule in both hardware and software
+ */
+static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
WARN_ON(list_empty(&qh->queue));
/* Set the element pointer if it isn't set already.
@@ -421,7 +518,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
struct uhci_td *td = list_entry(urbp->td_list.next,
struct uhci_td, list);
- qh->element = cpu_to_le32(td->dma_handle);
+ qh->element = LINK_TO_TD(td);
}
/* Treat the queue as if it has just advanced */
@@ -432,18 +529,64 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
return;
qh->state = QH_STATE_ACTIVE;
- /* Move the QH from its old list to the end of the appropriate
+ /* Move the QH from its old list to the correct spot in the appropriate
* skeleton's list */
if (qh == uhci->next_qh)
uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
node);
- list_move_tail(&qh->node, &qh->skel->node);
+ list_del(&qh->node);
+
+ if (qh->skel == SKEL_ISO)
+ link_iso(uhci, qh);
+ else if (qh->skel < SKEL_ASYNC)
+ link_interrupt(uhci, qh);
+ else
+ link_async(uhci, qh);
+}
+
+/*
+ * Unlink a high-period interrupt QH from the schedule
+ */
+static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+ struct uhci_qh *pqh;
- /* Link it into the schedule */
pqh = list_entry(qh->node.prev, struct uhci_qh, node);
- qh->link = pqh->link;
- wmb();
- pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle);
+ pqh->link = qh->link;
+ mb();
+}
+
+/*
+ * Unlink a period-1 interrupt or async QH from the schedule
+ */
+static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+ struct uhci_qh *pqh, *lqh;
+ __le32 link_to_next_qh = qh->link;
+
+ pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+
+ /* If this is the first FSBQ QH, take special action */
+ if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
+ qh->skel >= SKEL_FSBR) {
+ lqh = list_entry(uhci->skel_async_qh->node.prev,
+ struct uhci_qh, node);
+
+ /* If this QH is also the last one, we must link in
+ * the terminating skeleton QH. */
+ if (qh == lqh) {
+ link_to_next_qh = LINK_TO_QH(uhci->skel_term_qh);
+ uhci->skel_term_qh->link = link_to_next_qh;
+ wmb();
+ qh->link = link_to_next_qh;
+
+ /* Otherwise the last QH must point to the new first FSBR QH */
+ } else
+ lqh->link = link_to_next_qh;
+ }
+
+ pqh->link = link_to_next_qh;
+ mb();
}
/*
@@ -451,17 +594,18 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
*/
static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
- struct uhci_qh *pqh;
-
if (qh->state == QH_STATE_UNLINKING)
return;
WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
qh->state = QH_STATE_UNLINKING;
/* Unlink the QH from the schedule and record when we did it */
- pqh = list_entry(qh->node.prev, struct uhci_qh, node);
- pqh->link = qh->link;
- mb();
+ if (qh->skel == SKEL_ISO)
+ ;
+ else if (qh->skel < SKEL_ASYNC)
+ unlink_interrupt(uhci, qh);
+ else
+ unlink_async(uhci, qh);
uhci_get_current_frame_number(uhci);
qh->unlink_frame = uhci->frame_number;
@@ -697,6 +841,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
dma_addr_t data = urb->transfer_dma;
__le32 *plink;
struct urb_priv *urbp = urb->hcpriv;
+ int skel;
/* The "pipe" thing contains the destination in bits 8--18 */
destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
@@ -737,7 +882,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci);
if (!td)
goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
+ *plink = LINK_TO_TD(td);
/* Alternate Data0/1 (start with Data1) */
destination ^= TD_TOKEN_TOGGLE;
@@ -757,7 +902,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci);
if (!td)
goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
+ *plink = LINK_TO_TD(td);
/*
* It's IN if the pipe is an output pipe or we're not expecting
@@ -784,7 +929,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci);
if (!td)
goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
+ *plink = LINK_TO_TD(td);
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb();
@@ -797,11 +942,13 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
* isn't in the CONFIGURED state. */
if (urb->dev->speed == USB_SPEED_LOW ||
urb->dev->state != USB_STATE_CONFIGURED)
- qh->skel = uhci->skel_ls_control_qh;
+ skel = SKEL_LS_CONTROL;
else {
- qh->skel = uhci->skel_fs_control_qh;
+ skel = SKEL_FS_CONTROL;
uhci_add_fsbr(uhci, urb);
}
+ if (qh->state != QH_STATE_ACTIVE)
+ qh->skel = skel;
urb->actual_length = -8; /* Account for the SETUP packet */
return 0;
@@ -860,7 +1007,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci);
if (!td)
goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
+ *plink = LINK_TO_TD(td);
}
uhci_add_td_to_urbp(td, urbp);
uhci_fill_td(td, status,
@@ -888,7 +1035,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci);
if (!td)
goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
+ *plink = LINK_TO_TD(td);
uhci_add_td_to_urbp(td, urbp);
uhci_fill_td(td, status,
@@ -914,7 +1061,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci);
if (!td)
goto nomem;
- *plink = cpu_to_le32(td->dma_handle);
+ *plink = LINK_TO_TD(td);
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb();
@@ -931,7 +1078,7 @@ nomem:
return -ENOMEM;
}
-static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
+static int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
struct uhci_qh *qh)
{
int ret;
@@ -940,7 +1087,8 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
if (urb->dev->speed == USB_SPEED_LOW)
return -EINVAL;
- qh->skel = uhci->skel_bulk_qh;
+ if (qh->state != QH_STATE_ACTIVE)
+ qh->skel = SKEL_BULK;
ret = uhci_submit_common(uhci, urb, qh);
if (ret == 0)
uhci_add_fsbr(uhci, urb);
@@ -968,7 +1116,7 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
if (exponent < 0)
return -EINVAL;
qh->period = 1 << exponent;
- qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)];
+ qh->skel = SKEL_INDEX(exponent);
/* For now, interrupt phase is fixed by the layout
* of the QH lists. */
@@ -1005,7 +1153,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci,
* the queue at the status stage transaction, which is
* the last TD. */
WARN_ON(list_empty(&urbp->td_list));
- qh->element = cpu_to_le32(td->dma_handle);
+ qh->element = LINK_TO_TD(td);
tmp = td->list.prev;
ret = -EINPROGRESS;
@@ -1216,7 +1364,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
qh->iso_status = 0;
}
- qh->skel = uhci->skel_iso_qh;
+ qh->skel = SKEL_ISO;
if (!qh->bandwidth_reserved)
uhci_reserve_bandwidth(uhci, qh);
return 0;
@@ -1566,8 +1714,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh)
if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
/* Detect the Intel bug and work around it */
- if (qh->post_td && qh_element(qh) ==
- cpu_to_le32(qh->post_td->dma_handle)) {
+ if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) {
qh->element = qh->post_td->link;
qh->advance_jiffies = jiffies;
ret = 1;
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 8505824848f..3749f4a235f 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
+#include <linux/hid.h>
/*
* Version Information
@@ -330,7 +331,8 @@ static void usb_kbd_disconnect(struct usb_interface *intf)
}
static struct usb_device_id usb_kbd_id_table [] = {
- { USB_INTERFACE_INFO(3, 1, 1) },
+ { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
+ USB_INTERFACE_PROTOCOL_KEYBOARD) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 64a33e420cf..692fd608777 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
+#include <linux/hid.h>
/*
* Version Information
@@ -213,7 +214,8 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
}
static struct usb_device_id usb_mouse_id_table [] = {
- { USB_INTERFACE_INFO(3, 1, 2) },
+ { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
+ USB_INTERFACE_PROTOCOL_MOUSE) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c
index 4142e36730f..4f3e9bc7177 100644
--- a/drivers/usb/input/wacom_wac.c
+++ b/drivers/usb/input/wacom_wac.c
@@ -163,7 +163,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
}
id = STYLUS_DEVICE_ID;
- if (data[1] & 0x10) { /* in prox */
+ if (data[1] & 0x80) { /* in prox */
switch ((data[1] >> 5) & 3) {
@@ -196,9 +196,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
break;
}
- }
-
- if (data[1] & 0x90) {
x = wacom_le16_to_cpu(&data[2]);
y = wacom_le16_to_cpu(&data[4]);
wacom_report_abs(wcombo, ABS_X, x);
@@ -210,19 +207,28 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
}
wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
- }
- else
- wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-
- if (data[1] & 0x10) /* only report prox-in when in area */
wacom_report_key(wcombo, wacom->tool[0], 1);
- if (!(data[1] & 0x90)) /* report prox-out when physically out */
+ } else if (!(data[1] & 0x90)) {
+ wacom_report_abs(wcombo, ABS_X, 0);
+ wacom_report_abs(wcombo, ABS_Y, 0);
+ if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+ wacom_report_key(wcombo, BTN_LEFT, 0);
+ wacom_report_key(wcombo, BTN_RIGHT, 0);
+ wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+ } else {
+ wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+ wacom_report_key(wcombo, BTN_TOUCH, 0);
+ wacom_report_key(wcombo, BTN_STYLUS, 0);
+ wacom_report_key(wcombo, BTN_STYLUS2, 0);
+ }
+ wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
wacom_report_key(wcombo, wacom->tool[0], 0);
- wacom_input_sync(wcombo);
+ }
/* send pad data */
if (wacom->features->type == WACOM_G4) {
- if ( (wacom->serial[1] & 0xc0) != (data[7] & 0xf8) ) {
+ if (data[7] & 0xf8) {
+ wacom_input_sync(wcombo); /* sync last event */
wacom->id[1] = 1;
wacom->serial[1] = (data[7] & 0xf8);
wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
@@ -230,10 +236,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
wacom_report_rel(wcombo, REL_WHEEL, rw);
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
+ wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
} else if (wacom->id[1]) {
+ wacom_input_sync(wcombo); /* sync last event */
wacom->id[1] = 0;
+ wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+ wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+ wacom_report_abs(wcombo, ABS_MISC, 0);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
}
}
@@ -304,28 +315,35 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
default: /* Unknown tool */
wacom->tool[idx] = BTN_TOOL_PEN;
}
- /* only large I3 support Lens Cursor */
- if(!((wacom->tool[idx] == BTN_TOOL_LENS)
- && ((wacom->features->type == INTUOS3)
- || (wacom->features->type == INTUOS3S)))) {
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
- wacom_report_key(wcombo, wacom->tool[idx], 1);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- return 2;
- }
return 1;
}
/* Exit report */
if ((data[1] & 0xfe) == 0x80) {
- if(!((wacom->tool[idx] == BTN_TOOL_LENS)
- && ((wacom->features->type == INTUOS3)
- || (wacom->features->type == INTUOS3S)))) {
- wacom_report_key(wcombo, wacom->tool[idx], 0);
- wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- return 2;
+ wacom_report_abs(wcombo, ABS_X, 0);
+ wacom_report_abs(wcombo, ABS_Y, 0);
+ wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+ if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
+ wacom_report_key(wcombo, BTN_LEFT, 0);
+ wacom_report_key(wcombo, BTN_MIDDLE, 0);
+ wacom_report_key(wcombo, BTN_RIGHT, 0);
+ wacom_report_key(wcombo, BTN_SIDE, 0);
+ wacom_report_key(wcombo, BTN_EXTRA, 0);
+ wacom_report_abs(wcombo, ABS_THROTTLE, 0);
+ wacom_report_abs(wcombo, ABS_RZ, 0);
+ } else {
+ wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+ wacom_report_abs(wcombo, ABS_TILT_X, 0);
+ wacom_report_abs(wcombo, ABS_TILT_Y, 0);
+ wacom_report_key(wcombo, BTN_STYLUS, 0);
+ wacom_report_key(wcombo, BTN_STYLUS2, 0);
+ wacom_report_key(wcombo, BTN_TOUCH, 0);
+ wacom_report_abs(wcombo, ABS_WHEEL, 0);
}
+ wacom_report_key(wcombo, wacom->tool[idx], 0);
+ wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+ wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+ return 2;
}
return 0;
}
@@ -394,6 +412,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
wacom_report_key(wcombo, wacom->tool[1], 1);
else
wacom_report_key(wcombo, wacom->tool[1], 0);
+ wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff);
return 1;
}
@@ -403,6 +422,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
if (result)
return result-1;
+ /* Only large I3 and I1 & I2 support Lense Cursor */
+ if((wacom->tool[idx] == BTN_TOOL_LENS)
+ && ((wacom->features->type == INTUOS3)
+ || (wacom->features->type == INTUOS3S)))
+ return 0;
+
/* Cintiq doesn't send data when RDY bit isn't set */
if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
return 0;
@@ -554,11 +579,11 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE },
{ "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE },
{ "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE },
- { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS },
- { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS },
- { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS },
- { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 63, INTUOS },
- { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 63, INTUOS },
+ { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
+ { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
+ { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
+ { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
+ { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
{ "Wacom PL400", 8, 5408, 4056, 255, 0, PL },
{ "Wacom PL500", 8, 6144, 4608, 255, 0, PL },
{ "Wacom PL600", 8, 6126, 4604, 255, 0, PL },
@@ -571,11 +596,11 @@ static struct wacom_features wacom_features[] = {
{ "Wacom DTF521", 8, 6282, 4762, 511, 0, PL },
{ "Wacom DTF720", 8, 6858, 5506, 511, 0, PL },
{ "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU },
- { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 63, INTUOS },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS },
- { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 63, INTUOS },
- { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 63, INTUOS },
- { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 63, INTUOS },
+ { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
+ { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
+ { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
+ { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
+ { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
{ "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S },
{ "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 },
{ "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 },
@@ -584,7 +609,7 @@ static struct wacom_features wacom_features[] = {
{ "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 },
{ "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S },
{ "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS },
+ { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
{ }
};
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/usb/input/wacom_wac.h
index a1d9ce00797..a2302228724 100644
--- a/drivers/usb/input/wacom_wac.h
+++ b/drivers/usb/input/wacom_wac.h
@@ -12,6 +12,7 @@
#define STYLUS_DEVICE_ID 0x02
#define CURSOR_DEVICE_ID 0x06
#define ERASER_DEVICE_ID 0x0A
+#define PAD_DEVICE_ID 0x0F
enum {
PENPARTNER = 0,
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 4907e8b8007..9c7eb6144d0 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -244,6 +244,20 @@ config USB_TRANCEVIBRATOR
To compile this driver as a module, choose M here: the
module will be called trancevibrator.
+config USB_IOWARRIOR
+ tristate "IO Warrior driver support"
+ depends on USB
+ help
+ Say Y here if you want to support the IO Warrior devices from Code
+ Mercenaries. This includes support for the following devices:
+ IO Warrior 40
+ IO Warrior 24
+ IO Warrior 56
+ IO Warrior 24 Power Vampire
+
+ To compile this driver as a module, choose M here: the
+ module will be called iowarrior.
+
config USB_TEST
tristate "USB testing driver (DEVELOPMENT)"
depends on USB && USB_DEVICEFS && EXPERIMENTAL
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index dac2d5b7156..b68e6b774f1 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_EMI26) += emi26.o
obj-$(CONFIG_USB_EMI62) += emi62.o
obj-$(CONFIG_USB_FTDI_ELAN) += ftdi-elan.o
obj-$(CONFIG_USB_IDMOUSE) += idmouse.o
+obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o
obj-$(CONFIG_USB_LCD) += usblcd.o
obj-$(CONFIG_USB_LD) += ldusb.o
obj-$(CONFIG_USB_LED) += usbled.o
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
new file mode 100644
index 00000000000..d69665c8de0
--- /dev/null
+++ b/drivers/usb/misc/iowarrior.c
@@ -0,0 +1,925 @@
+/*
+ * Native support for the I/O-Warrior USB devices
+ *
+ * Copyright (c) 2003-2005 Code Mercenaries GmbH
+ * written by Christian Lucht <lucht@codemercs.com>
+ *
+ * based on
+
+ * usb-skeleton.c by Greg Kroah-Hartman <greg@kroah.com>
+ * brlvger.c by Stephane Dalton <sdalton@videotron.ca>
+ * and St�hane Doyon <s.doyon@videotron.ca>
+ *
+ * Released under the GPLv2.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/version.h>
+#include <linux/usb/iowarrior.h>
+
+/* Version Information */
+#define DRIVER_VERSION "v0.4.0"
+#define DRIVER_AUTHOR "Christian Lucht <lucht@codemercs.com>"
+#define DRIVER_DESC "USB IO-Warrior driver (Linux 2.6.x)"
+
+#define USB_VENDOR_ID_CODEMERCS 1984
+/* low speed iowarrior */
+#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500
+#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501
+#define USB_DEVICE_ID_CODEMERCS_IOWPV1 0x1511
+#define USB_DEVICE_ID_CODEMERCS_IOWPV2 0x1512
+/* full speed iowarrior */
+#define USB_DEVICE_ID_CODEMERCS_IOW56 0x1503
+
+/* Get a minor range for your devices from the usb maintainer */
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define IOWARRIOR_MINOR_BASE 0
+#else
+#define IOWARRIOR_MINOR_BASE 208 // SKELETON_MINOR_BASE 192 + 16, not offical yet
+#endif
+
+/* interrupt input queue size */
+#define MAX_INTERRUPT_BUFFER 16
+/*
+ maximum number of urbs that are submitted for writes at the same time,
+ this applies to the IOWarrior56 only!
+ IOWarrior24 and IOWarrior40 use synchronous usb_control_msg calls.
+*/
+#define MAX_WRITES_IN_FLIGHT 4
+
+/* Use our own dbg macro */
+#undef dbg
+#define dbg( format, arg... ) do { if( debug ) printk( KERN_DEBUG __FILE__ ": " format "\n" , ## arg ); } while ( 0 )
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/* Module parameters */
+static int debug = 0;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
+
+static struct usb_driver iowarrior_driver;
+
+/*--------------*/
+/* data */
+/*--------------*/
+
+/* Structure to hold all of our device specific stuff */
+struct iowarrior {
+ struct mutex mutex; /* locks this structure */
+ struct usb_device *udev; /* save off the usb device pointer */
+ struct usb_interface *interface; /* the interface for this device */
+ unsigned char minor; /* the starting minor number for this device */
+ struct usb_endpoint_descriptor *int_out_endpoint; /* endpoint for reading (needed for IOW56 only) */
+ struct usb_endpoint_descriptor *int_in_endpoint; /* endpoint for reading */
+ struct urb *int_in_urb; /* the urb for reading data */
+ unsigned char *int_in_buffer; /* buffer for data to be read */
+ unsigned char serial_number; /* to detect lost packages */
+ unsigned char *read_queue; /* size is MAX_INTERRUPT_BUFFER * packet size */
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait; /* wait-queue for writing to the device */
+ atomic_t write_busy; /* number of write-urbs submitted */
+ atomic_t read_idx;
+ atomic_t intr_idx;
+ spinlock_t intr_idx_lock; /* protects intr_idx */
+ atomic_t overflow_flag; /* signals an index 'rollover' */
+ int present; /* this is 1 as long as the device is connected */
+ int opened; /* this is 1 if the device is currently open */
+ char chip_serial[9]; /* the serial number string of the chip connected */
+ int report_size; /* number of bytes in a report */
+ u16 product_id;
+};
+
+/*--------------*/
+/* globals */
+/*--------------*/
+/* prevent races between open() and disconnect() */
+static DECLARE_MUTEX(disconnect_sem);
+
+/*
+ * USB spec identifies 5 second timeouts.
+ */
+#define GET_TIMEOUT 5
+#define USB_REQ_GET_REPORT 0x01
+//#if 0
+static int usb_get_report(struct usb_device *dev,
+ struct usb_host_interface *inter, unsigned char type,
+ unsigned char id, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_REPORT,
+ USB_DIR_IN | USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE, (type << 8) + id,
+ inter->desc.bInterfaceNumber, buf, size,
+ GET_TIMEOUT);
+}
+//#endif
+
+#define USB_REQ_SET_REPORT 0x09
+
+static int usb_set_report(struct usb_interface *intf, unsigned char type,
+ unsigned char id, void *buf, int size)
+{
+ return usb_control_msg(interface_to_usbdev(intf),
+ usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+ USB_REQ_SET_REPORT,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ (type << 8) + id,
+ intf->cur_altsetting->desc.bInterfaceNumber, buf,
+ size, 1);
+}
+
+/*---------------------*/
+/* driver registration */
+/*---------------------*/
+/* table of devices that work with this driver */
+static struct usb_device_id iowarrior_ids[] = {
+ {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)},
+ {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)},
+ {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)},
+ {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV2)},
+ {USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56)},
+ {} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, iowarrior_ids);
+
+/*
+ * USB callback handler for reading data
+ */
+static void iowarrior_callback(struct urb *urb)
+{
+ struct iowarrior *dev = (struct iowarrior *)urb->context;
+ int intr_idx;
+ int read_idx;
+ int aux_idx;
+ int offset;
+ int status;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default:
+ goto exit;
+ }
+
+ spin_lock(&dev->intr_idx_lock);
+ intr_idx = atomic_read(&dev->intr_idx);
+ /* aux_idx become previous intr_idx */
+ aux_idx = (intr_idx == 0) ? (MAX_INTERRUPT_BUFFER - 1) : (intr_idx - 1);
+ read_idx = atomic_read(&dev->read_idx);
+
+ /* queue is not empty and it's interface 0 */
+ if ((intr_idx != read_idx)
+ && (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0)) {
+ /* + 1 for serial number */
+ offset = aux_idx * (dev->report_size + 1);
+ if (!memcmp
+ (dev->read_queue + offset, urb->transfer_buffer,
+ dev->report_size)) {
+ /* equal values on interface 0 will be ignored */
+ spin_unlock(&dev->intr_idx_lock);
+ goto exit;
+ }
+ }
+
+ /* aux_idx become next intr_idx */
+ aux_idx = (intr_idx == (MAX_INTERRUPT_BUFFER - 1)) ? 0 : (intr_idx + 1);
+ if (read_idx == aux_idx) {
+ /* queue full, dropping oldest input */
+ read_idx = (++read_idx == MAX_INTERRUPT_BUFFER) ? 0 : read_idx;
+ atomic_set(&dev->read_idx, read_idx);
+ atomic_set(&dev->overflow_flag, 1);
+ }
+
+ /* +1 for serial number */
+ offset = intr_idx * (dev->report_size + 1);
+ memcpy(dev->read_queue + offset, urb->transfer_buffer,
+ dev->report_size);
+ *(dev->read_queue + offset + (dev->report_size)) = dev->serial_number++;
+
+ atomic_set(&dev->intr_idx, aux_idx);
+ spin_unlock(&dev->intr_idx_lock);
+ /* tell the blocking read about the new data */
+ wake_up_interruptible(&dev->read_wait);
+
+exit:
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status)
+ dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
+ __FUNCTION__, status);
+
+}
+
+/*
+ * USB Callback handler for write-ops
+ */
+static void iowarrior_write_callback(struct urb *urb)
+{
+ struct iowarrior *dev;
+ dev = (struct iowarrior *)urb->context;
+ /* sync/async unlink faults aren't errors */
+ if (urb->status &&
+ !(urb->status == -ENOENT ||
+ urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) {
+ dbg("%s - nonzero write bulk status received: %d",
+ __func__, urb->status);
+ }
+ /* free up our allocated buffer */
+ usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+ /* tell a waiting writer the interrupt-out-pipe is available again */
+ atomic_dec(&dev->write_busy);
+ wake_up_interruptible(&dev->write_wait);
+}
+
+/**
+ * iowarrior_delete
+ */
+static inline void iowarrior_delete(struct iowarrior *dev)
+{
+ dbg("%s - minor %d", __func__, dev->minor);
+ kfree(dev->int_in_buffer);
+ usb_free_urb(dev->int_in_urb);
+ kfree(dev->read_queue);
+ kfree(dev);
+}
+
+/*---------------------*/
+/* fops implementation */
+/*---------------------*/
+
+static int read_index(struct iowarrior *dev)
+{
+ int intr_idx, read_idx;
+
+ read_idx = atomic_read(&dev->read_idx);
+ intr_idx = atomic_read(&dev->intr_idx);
+
+ return (read_idx == intr_idx ? -1 : read_idx);
+}
+
+/**
+ * iowarrior_read
+ */
+static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iowarrior *dev;
+ int read_idx;
+ int offset;
+
+ dev = (struct iowarrior *)file->private_data;
+
+ /* verify that the device wasn't unplugged */
+ if (dev == NULL || !dev->present)
+ return -ENODEV;
+
+ dbg("%s - minor %d, count = %zd", __func__, dev->minor, count);
+
+ /* read count must be packet size (+ time stamp) */
+ if ((count != dev->report_size)
+ && (count != (dev->report_size + 1)))
+ return -EINVAL;
+
+ /* repeat until no buffer overrun in callback handler occur */
+ do {
+ atomic_set(&dev->overflow_flag, 0);
+ if ((read_idx = read_index(dev)) == -1) {
+ /* queue emty */
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+ else {
+ //next line will return when there is either new data, or the device is unplugged
+ int r = wait_event_interruptible(dev->read_wait,
+ (!dev->present
+ || (read_idx =
+ read_index
+ (dev)) !=
+ -1));
+ if (r) {
+ //we were interrupted by a signal
+ return -ERESTART;
+ }
+ if (!dev->present) {
+ //The device was unplugged
+ return -ENODEV;
+ }
+ if (read_idx == -1) {
+ // Can this happen ???
+ return 0;
+ }
+ }
+ }
+
+ offset = read_idx * (dev->report_size + 1);
+ if (copy_to_user(buffer, dev->read_queue + offset, count)) {
+ return -EFAULT;
+ }
+ } while (atomic_read(&dev->overflow_flag));
+
+ read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
+ atomic_set(&dev->read_idx, read_idx);
+ return count;
+}
+
+/*
+ * iowarrior_write
+ */
+static ssize_t iowarrior_write(struct file *file,
+ const char __user *user_buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iowarrior *dev;
+ int retval = 0;
+ char *buf = NULL; /* for IOW24 and IOW56 we need a buffer */
+ struct urb *int_out_urb = NULL;
+
+ dev = (struct iowarrior *)file->private_data;
+
+ mutex_lock(&dev->mutex);
+ /* verify that the device wasn't unplugged */
+ if (dev == NULL || !dev->present) {
+ retval = -ENODEV;
+ goto exit;
+ }
+ dbg("%s - minor %d, count = %zd", __func__, dev->minor, count);
+ /* if count is 0 we're already done */
+ if (count == 0) {
+ retval = 0;
+ goto exit;
+ }
+ /* We only accept full reports */
+ if (count != dev->report_size) {
+ retval = -EINVAL;
+ goto exit;
+ }
+ switch (dev->product_id) {
+ case USB_DEVICE_ID_CODEMERCS_IOW24:
+ case USB_DEVICE_ID_CODEMERCS_IOWPV1:
+ case USB_DEVICE_ID_CODEMERCS_IOWPV2:
+ case USB_DEVICE_ID_CODEMERCS_IOW40:
+ /* IOW24 and IOW40 use a synchronous call */
+ buf = kmalloc(8, GFP_KERNEL); /* 8 bytes are enough for both products */
+ if (!buf) {
+ retval = -ENOMEM;
+ goto exit;
+ }
+ if (copy_from_user(buf, user_buffer, count)) {
+ retval = -EFAULT;
+ kfree(buf);
+ goto exit;
+ }
+ retval = usb_set_report(dev->interface, 2, 0, buf, count);
+ kfree(buf);
+ goto exit;
+ break;
+ case USB_DEVICE_ID_CODEMERCS_IOW56:
+ /* The IOW56 uses asynchronous IO and more urbs */
+ if (atomic_read(&dev->write_busy) == MAX_WRITES_IN_FLIGHT) {
+ /* Wait until we are below the limit for submitted urbs */
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto exit;
+ } else {
+ retval = wait_event_interruptible(dev->write_wait,
+ (!dev->present || (atomic_read (&dev-> write_busy) < MAX_WRITES_IN_FLIGHT)));
+ if (retval) {
+ /* we were interrupted by a signal */
+ retval = -ERESTART;
+ goto exit;
+ }
+ if (!dev->present) {
+ /* The device was unplugged */
+ retval = -ENODEV;
+ goto exit;
+ }
+ if (!dev->opened) {
+ /* We were closed while waiting for an URB */
+ retval = -ENODEV;
+ goto exit;
+ }
+ }
+ }
+ atomic_inc(&dev->write_busy);
+ int_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!int_out_urb) {
+ retval = -ENOMEM;
+ dbg("%s Unable to allocate urb ", __func__);
+ goto error;
+ }
+ buf = usb_buffer_alloc(dev->udev, dev->report_size,
+ GFP_KERNEL, &int_out_urb->transfer_dma);
+ if (!buf) {
+ retval = -ENOMEM;
+ dbg("%s Unable to allocate buffer ", __func__);
+ goto error;
+ }
+ usb_fill_int_urb(int_out_urb, dev->udev,
+ usb_sndintpipe(dev->udev,
+ dev->int_out_endpoint->bEndpointAddress),
+ buf, dev->report_size,
+ iowarrior_write_callback, dev,
+ dev->int_out_endpoint->bInterval);
+ int_out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ if (copy_from_user(buf, user_buffer, count)) {
+ retval = -EFAULT;
+ goto error;
+ }
+ retval = usb_submit_urb(int_out_urb, GFP_KERNEL);
+ if (retval) {
+ dbg("%s submit error %d for urb nr.%d", __func__,
+ retval, atomic_read(&dev->write_busy));
+ goto error;
+ }
+ /* submit was ok */
+ retval = count;
+ usb_free_urb(int_out_urb);
+ goto exit;
+ break;
+ default:
+ /* what do we have here ? An unsupported Product-ID ? */
+ dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
+ __FUNCTION__, dev->product_id);
+ retval = -EFAULT;
+ goto exit;
+ break;
+ }
+error:
+ usb_buffer_free(dev->udev, dev->report_size, buf,
+ int_out_urb->transfer_dma);
+ usb_free_urb(int_out_urb);
+ atomic_dec(&dev->write_busy);
+ wake_up_interruptible(&dev->write_wait);
+exit:
+ mutex_unlock(&dev->mutex);
+ return retval;
+}
+
+/**
+ * iowarrior_ioctl
+ */
+static int iowarrior_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct iowarrior *dev = NULL;
+ __u8 *buffer;
+ __u8 __user *user_buffer;
+ int retval;
+ int io_res; /* checks for bytes read/written and copy_to/from_user results */
+
+ dev = (struct iowarrior *)file->private_data;
+ if (dev == NULL) {
+ return -ENODEV;
+ }
+
+ buffer = kzalloc(dev->report_size, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ /* lock this object */
+ mutex_lock(&dev->mutex);
+
+ /* verify that the device wasn't unplugged */
+ if (!dev->present) {
+ mutex_unlock(&dev->mutex);
+ return -ENODEV;
+ }
+
+ dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd,
+ arg);
+
+ retval = 0;
+ io_res = 0;
+ switch (cmd) {
+ case IOW_WRITE:
+ if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24 ||
+ dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV1 ||
+ dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV2 ||
+ dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW40) {
+ user_buffer = (__u8 __user *)arg;
+ io_res = copy_from_user(buffer, user_buffer,
+ dev->report_size);
+ if (io_res) {
+ retval = -EFAULT;
+ } else {
+ io_res = usb_set_report(dev->interface, 2, 0,
+ buffer,
+ dev->report_size);
+ if (io_res < 0)
+ retval = io_res;
+ }
+ } else {
+ retval = -EINVAL;
+ dev_err(&dev->interface->dev,
+ "ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+ dev->product_id);
+ }
+ break;
+ case IOW_READ:
+ user_buffer = (__u8 __user *)arg;
+ io_res = usb_get_report(dev->udev,
+ dev->interface->cur_altsetting, 1, 0,
+ buffer, dev->report_size);
+ if (io_res < 0)
+ retval = io_res;
+ else {
+ io_res = copy_to_user(user_buffer, buffer, dev->report_size);
+ if (io_res < 0)
+ retval = -EFAULT;
+ }
+ break;
+ case IOW_GETINFO:
+ {
+ /* Report available information for the device */
+ struct iowarrior_info info;
+ /* needed for power consumption */
+ struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;
+
+ /* directly from the descriptor */
+ info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ info.product = dev->product_id;
+ info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
+
+ /* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
+ info.speed = le16_to_cpu(dev->udev->speed);
+ info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
+ info.report_size = dev->report_size;
+
+ /* serial number string has been read earlier 8 chars or empty string */
+ memcpy(info.serial, dev->chip_serial,
+ sizeof(dev->chip_serial));
+ if (cfg_descriptor == NULL) {
+ info.power = -1; /* no information available */
+ } else {
+ /* the MaxPower is stored in units of 2mA to make it fit into a byte-value */
+ info.power = cfg_descriptor->bMaxPower * 2;
+ }
+ io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
+ sizeof(struct iowarrior_info));
+ if (io_res < 0)
+ retval = -EFAULT;
+ break;
+ }
+ default:
+ /* return that we did not understand this ioctl call */
+ retval = -ENOTTY;
+ break;
+ }
+
+ /* unlock the device */
+ mutex_unlock(&dev->mutex);
+ return retval;
+}
+
+/**
+ * iowarrior_open
+ */
+static int iowarrior_open(struct inode *inode, struct file *file)
+{
+ struct iowarrior *dev = NULL;
+ struct usb_interface *interface;
+ int subminor;
+ int retval = 0;
+
+ dbg("%s", __func__);
+
+ subminor = iminor(inode);
+
+ /* prevent disconnects */
+ down(&disconnect_sem);
+
+ interface = usb_find_interface(&iowarrior_driver, subminor);
+ if (!interface) {
+ err("%s - error, can't find device for minor %d", __FUNCTION__,
+ subminor);
+ retval = -ENODEV;
+ goto out;
+ }
+
+ dev = usb_get_intfdata(interface);
+ if (!dev) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ /* Only one process can open each device, no sharing. */
+ if (dev->opened) {
+ retval = -EBUSY;
+ goto out;
+ }
+
+ /* setup interrupt handler for receiving values */
+ if ((retval = usb_submit_urb(dev->int_in_urb, GFP_KERNEL)) < 0) {
+ dev_err(&interface->dev, "Error %d while submitting URB\n", retval);
+ retval = -EFAULT;
+ goto out;
+ }
+ /* increment our usage count for the driver */
+ ++dev->opened;
+ /* save our object in the file's private structure */
+ file->private_data = dev;
+ retval = 0;
+
+out:
+ up(&disconnect_sem);
+ return retval;
+}
+
+/**
+ * iowarrior_release
+ */
+static int iowarrior_release(struct inode *inode, struct file *file)
+{
+ struct iowarrior *dev;
+ int retval = 0;
+
+ dev = (struct iowarrior *)file->private_data;
+ if (dev == NULL) {
+ return -ENODEV;
+ }
+
+ dbg("%s - minor %d", __func__, dev->minor);
+
+ /* lock our device */
+ mutex_lock(&dev->mutex);
+
+ if (dev->opened <= 0) {
+ retval = -ENODEV; /* close called more than once */
+ mutex_unlock(&dev->mutex);
+ } else {
+ dev->opened = 0; /* we're closeing now */
+ retval = 0;
+ if (dev->present) {
+ /*
+ The device is still connected so we only shutdown
+ pending read-/write-ops.
+ */
+ usb_kill_urb(dev->int_in_urb);
+ wake_up_interruptible(&dev->read_wait);
+ wake_up_interruptible(&dev->write_wait);
+ mutex_unlock(&dev->mutex);
+ } else {
+ /* The device was unplugged, cleanup resources */
+ mutex_unlock(&dev->mutex);
+ iowarrior_delete(dev);
+ }
+ }
+ return retval;
+}
+
+static unsigned iowarrior_poll(struct file *file, poll_table * wait)
+{
+ struct iowarrior *dev = file->private_data;
+ unsigned int mask = 0;
+
+ if (!dev->present)
+ return POLLERR | POLLHUP;
+
+ poll_wait(file, &dev->read_wait, wait);
+ poll_wait(file, &dev->write_wait, wait);
+
+ if (!dev->present)
+ return POLLERR | POLLHUP;
+
+ if (read_index(dev) != -1)
+ mask |= POLLIN | POLLRDNORM;
+
+ if (atomic_read(&dev->write_busy) < MAX_WRITES_IN_FLIGHT)
+ mask |= POLLOUT | POLLWRNORM;
+ return mask;
+}
+
+/*
+ * File operations needed when we register this driver.
+ * This assumes that this driver NEEDS file operations,
+ * of course, which means that the driver is expected
+ * to have a node in the /dev directory. If the USB
+ * device were for a network interface then the driver
+ * would use "struct net_driver" instead, and a serial
+ * device would use "struct tty_driver".
+ */
+static struct file_operations iowarrior_fops = {
+ .owner = THIS_MODULE,
+ .write = iowarrior_write,
+ .read = iowarrior_read,
+ .ioctl = iowarrior_ioctl,
+ .open = iowarrior_open,
+ .release = iowarrior_release,
+ .poll = iowarrior_poll,
+};
+
+/*
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with devfs and the driver core
+ */
+static struct usb_class_driver iowarrior_class = {
+ .name = "iowarrior%d",
+ .fops = &iowarrior_fops,
+ .minor_base = IOWARRIOR_MINOR_BASE,
+};
+
+/*---------------------------------*/
+/* probe and disconnect functions */
+/*---------------------------------*/
+/**
+ * iowarrior_probe
+ *
+ * Called by the usb core when a new device is connected that it thinks
+ * this driver might be interested in.
+ */
+static int iowarrior_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ struct iowarrior *dev = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int i;
+ int retval = -ENOMEM;
+ int idele = 0;
+
+ /* allocate memory for our device state and intialize it */
+ dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
+ if (dev == NULL) {
+ dev_err(&interface->dev, "Out of memory");
+ return retval;
+ }
+
+ mutex_init(&dev->mutex);
+
+ atomic_set(&dev->intr_idx, 0);
+ atomic_set(&dev->read_idx, 0);
+ spin_lock_init(&dev->intr_idx_lock);
+ atomic_set(&dev->overflow_flag, 0);
+ init_waitqueue_head(&dev->read_wait);
+ atomic_set(&dev->write_busy, 0);
+ init_waitqueue_head(&dev->write_wait);
+
+ dev->udev = udev;
+ dev->interface = interface;
+
+ iface_desc = interface->cur_altsetting;
+ dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
+
+ /* set up the endpoint information */
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (usb_endpoint_is_int_in(endpoint))
+ dev->int_in_endpoint = endpoint;
+ if (usb_endpoint_is_int_out(endpoint))
+ /* this one will match for the IOWarrior56 only */
+ dev->int_out_endpoint = endpoint;
+ }
+ /* we have to check the report_size often, so remember it in the endianess suitable for our machine */
+ dev->report_size = le16_to_cpu(dev->int_in_endpoint->wMaxPacketSize);
+ if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
+ (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56))
+ /* IOWarrior56 has wMaxPacketSize different from report size */
+ dev->report_size = 7;
+
+ /* create the urb and buffer for reading */
+ dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->int_in_urb) {
+ dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n");
+ goto error;
+ }
+ dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL);
+ if (!dev->int_in_buffer) {
+ dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n");
+ goto error;
+ }
+ usb_fill_int_urb(dev->int_in_urb, dev->udev,
+ usb_rcvintpipe(dev->udev,
+ dev->int_in_endpoint->bEndpointAddress),
+ dev->int_in_buffer, dev->report_size,
+ iowarrior_callback, dev,
+ dev->int_in_endpoint->bInterval);
+ /* create an internal buffer for interrupt data from the device */
+ dev->read_queue =
+ kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER),
+ GFP_KERNEL);
+ if (!dev->read_queue) {
+ dev_err(&interface->dev, "Couldn't allocate read_queue\n");
+ goto error;
+ }
+ /* Get the serial-number of the chip */
+ memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
+ usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial,
+ sizeof(dev->chip_serial));
+ if (strlen(dev->chip_serial) != 8)
+ memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
+
+ /* Set the idle timeout to 0, if this is interface 0 */
+ if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
+ idele = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ 0x0A,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
+ 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ dbg("idele = %d", idele);
+ }
+ /* allow device read and ioctl */
+ dev->present = 1;
+
+ /* we can register the device now, as it is ready */
+ usb_set_intfdata(interface, dev);
+
+ retval = usb_register_dev(interface, &iowarrior_class);
+ if (retval) {
+ /* something prevented us from registering this driver */
+ dev_err(&interface->dev, "Not able to get a minor for this device.\n");
+ usb_set_intfdata(interface, NULL);
+ goto error;
+ }
+
+ dev->minor = interface->minor;
+
+ /* let the user know what node this device is now attached to */
+ dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
+ "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
+ iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
+ return retval;
+
+error:
+ iowarrior_delete(dev);
+ return retval;
+}
+
+/**
+ * iowarrior_disconnect
+ *
+ * Called by the usb core when the device is removed from the system.
+ */
+static void iowarrior_disconnect(struct usb_interface *interface)
+{
+ struct iowarrior *dev;
+ int minor;
+
+ /* prevent races with open() */
+ down(&disconnect_sem);
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ mutex_lock(&dev->mutex);
+
+ minor = dev->minor;
+
+ /* give back our minor */
+ usb_deregister_dev(interface, &iowarrior_class);
+
+ /* prevent device read, write and ioctl */
+ dev->present = 0;
+
+ mutex_unlock(&dev->mutex);
+
+ if (dev->opened) {
+ /* There is a process that holds a filedescriptor to the device ,
+ so we only shutdown read-/write-ops going on.
+ Deleting the device is postponed until close() was called.
+ */
+ usb_kill_urb(dev->int_in_urb);
+ wake_up_interruptible(&dev->read_wait);
+ wake_up_interruptible(&dev->write_wait);
+ } else {
+ /* no process is using the device, cleanup now */
+ iowarrior_delete(dev);
+ }
+ up(&disconnect_sem);
+
+ dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
+ minor - IOWARRIOR_MINOR_BASE);
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver iowarrior_driver = {
+ .name = "iowarrior",
+ .probe = iowarrior_probe,
+ .disconnect = iowarrior_disconnect,
+ .id_table = iowarrior_ids,
+};
+
+static int __init iowarrior_init(void)
+{
+ return usb_register(&iowarrior_driver);
+}
+
+static void __exit iowarrior_exit(void)
+{
+ usb_deregister(&iowarrior_driver);
+}
+
+module_init(iowarrior_init);
+module_exit(iowarrior_exit);
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index c01dfe60367..b2bedd974ac 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1165,7 +1165,7 @@ err_dev:
return rc;
}
-void __exit mon_bin_exit(void)
+void mon_bin_exit(void)
{
cdev_del(&mon_bin_cdev);
unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index d38a1279d9d..494ee3b9a22 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -520,7 +520,7 @@ int __init mon_text_init(void)
return 0;
}
-void __exit mon_text_exit(void)
+void mon_text_exit(void)
{
debugfs_remove(mon_dir);
}
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index 4f949ce8a7f..efdfd8993d9 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -57,9 +57,9 @@ void mon_text_del(struct mon_bus *mbus);
// void mon_bin_add(struct mon_bus *);
int __init mon_text_init(void);
-void __exit mon_text_exit(void);
+void mon_text_exit(void);
int __init mon_bin_init(void);
-void __exit mon_bin_exit(void);
+void mon_bin_exit(void);
/*
* DMA interface.
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index 0f3d7dbb537..3de564b2314 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -186,6 +186,15 @@ config USB_NET_CDCETHER
IEEE 802 "local assignment" bit is set in the address, a "usbX"
name is used instead.
+config USB_NET_DM9601
+ tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
+ depends on USB_USBNET
+ select CRC32
+ select USB_USBNET_MII
+ help
+ This option adds support for Davicom DM9601 based USB 1.1
+ 10/100 Ethernet adapters.
+
config USB_NET_GL620A
tristate "GeneSys GL620USB-A based cables"
depends on USB_USBNET
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
index 7b51964de17..595a539f838 100644
--- a/drivers/usb/net/Makefile
+++ b/drivers/usb/net/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_PEGASUS) += pegasus.o
obj-$(CONFIG_USB_RTL8150) += rtl8150.o
obj-$(CONFIG_USB_NET_AX8817X) += asix.o
obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
+obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
obj-$(CONFIG_USB_NET_NET1080) += net1080.o
obj-$(CONFIG_USB_NET_PLUSB) += plusb.o
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 7ef2e4b5e39..5808ea08245 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -1395,9 +1395,9 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x07b8, 0x420a),
.driver_info = (unsigned long) &hawking_uf200_info,
}, {
- // Billionton Systems, USB2AR
- USB_DEVICE (0x08dd, 0x90ff),
- .driver_info = (unsigned long) &ax8817x_info,
+ // Billionton Systems, USB2AR
+ USB_DEVICE (0x08dd, 0x90ff),
+ .driver_info = (unsigned long) &ax8817x_info,
}, {
// ATEN UC210T
USB_DEVICE (0x0557, 0x2009),
@@ -1423,9 +1423,13 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x1631, 0x6200),
.driver_info = (unsigned long) &ax8817x_info,
}, {
+ // JVC MP-PRX1 Port Replicator
+ USB_DEVICE (0x04f1, 0x3008),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
// ASIX AX88772 10/100
- USB_DEVICE (0x0b95, 0x7720),
- .driver_info = (unsigned long) &ax88772_info,
+ USB_DEVICE (0x0b95, 0x7720),
+ .driver_info = (unsigned long) &ax88772_info,
}, {
// ASIX AX88178 10/100/1000
USB_DEVICE (0x0b95, 0x1780),
diff --git a/drivers/usb/net/dm9601.c b/drivers/usb/net/dm9601.c
new file mode 100644
index 00000000000..4a932e1cd93
--- /dev/null
+++ b/drivers/usb/net/dm9601.c
@@ -0,0 +1,606 @@
+/*
+ * Davicom DM9601 USB 1.1 10/100Mbps ethernet devices
+ *
+ * Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+//#define DEBUG
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+
+#include "usbnet.h"
+
+/* datasheet:
+ http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
+*/
+
+/* control requests */
+#define DM_READ_REGS 0x00
+#define DM_WRITE_REGS 0x01
+#define DM_READ_MEMS 0x02
+#define DM_WRITE_REG 0x03
+#define DM_WRITE_MEMS 0x05
+#define DM_WRITE_MEM 0x07
+
+/* registers */
+#define DM_NET_CTRL 0x00
+#define DM_RX_CTRL 0x05
+#define DM_SHARED_CTRL 0x0b
+#define DM_SHARED_ADDR 0x0c
+#define DM_SHARED_DATA 0x0d /* low + high */
+#define DM_PHY_ADDR 0x10 /* 6 bytes */
+#define DM_MCAST_ADDR 0x16 /* 8 bytes */
+#define DM_GPR_CTRL 0x1e
+#define DM_GPR_DATA 0x1f
+
+#define DM_MAX_MCAST 64
+#define DM_MCAST_SIZE 8
+#define DM_EEPROM_LEN 256
+#define DM_TX_OVERHEAD 2 /* 2 byte header */
+#define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */
+#define DM_TIMEOUT 1000
+
+
+static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+ devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
+ return usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ DM_READ_REGS,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+}
+
+static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
+{
+ return dm_read(dev, reg, 1, value);
+}
+
+static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+ devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
+ return usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ DM_WRITE_REGS,
+ USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+ 0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+}
+
+static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
+{
+ devdbg(dev, "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value);
+ return usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ DM_WRITE_REG,
+ USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+ value, reg, 0, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static void dm_write_async_callback(struct urb *urb)
+{
+ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+ if (urb->status < 0)
+ printk(KERN_DEBUG "dm_write_async_callback() failed with %d",
+ urb->status);
+
+ kfree(req);
+ usb_free_urb(urb);
+}
+
+static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+ struct usb_ctrlrequest *req;
+ struct urb *urb;
+ int status;
+
+ devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ deverr(dev, "Error allocating URB in dm_write_async!");
+ return;
+ }
+
+ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+ if (!req) {
+ deverr(dev, "Failed to allocate memory for control request");
+ usb_free_urb(urb);
+ return;
+ }
+
+ req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+ req->bRequest = DM_WRITE_REGS;
+ req->wValue = 0;
+ req->wIndex = cpu_to_le16(reg);
+ req->wLength = cpu_to_le16(length);
+
+ usb_fill_control_urb(urb, dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ (void *)req, data, length,
+ dm_write_async_callback, req);
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status < 0) {
+ deverr(dev, "Error submitting the control message: status=%d",
+ status);
+ kfree(req);
+ usb_free_urb(urb);
+ }
+}
+
+static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+{
+ struct usb_ctrlrequest *req;
+ struct urb *urb;
+ int status;
+
+ devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
+ reg, value);
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ deverr(dev, "Error allocating URB in dm_write_async!");
+ return;
+ }
+
+ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+ if (!req) {
+ deverr(dev, "Failed to allocate memory for control request");
+ usb_free_urb(urb);
+ return;
+ }
+
+ req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+ req->bRequest = DM_WRITE_REG;
+ req->wValue = cpu_to_le16(value);
+ req->wIndex = cpu_to_le16(reg);
+ req->wLength = 0;
+
+ usb_fill_control_urb(urb, dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ (void *)req, 0, 0, dm_write_async_callback, req);
+
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status < 0) {
+ deverr(dev, "Error submitting the control message: status=%d",
+ status);
+ kfree(req);
+ usb_free_urb(urb);
+ }
+}
+
+static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, u16 *value)
+{
+ int ret, i;
+
+ mutex_lock(&dev->phy_mutex);
+
+ dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
+ dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4);
+
+ for (i = 0; i < DM_TIMEOUT; i++) {
+ u8 tmp;
+
+ udelay(1);
+ ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
+ if (ret < 0)
+ goto out;
+
+ /* ready */
+ if ((tmp & 1) == 0)
+ break;
+ }
+
+ if (i == DM_TIMEOUT) {
+ deverr(dev, "%s read timed out!", phy ? "phy" : "eeprom");
+ ret = -EIO;
+ goto out;
+ }
+
+ dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
+ ret = dm_read(dev, DM_SHARED_DATA, 2, value);
+
+ devdbg(dev, "read shared %d 0x%02x returned 0x%04x, %d",
+ phy, reg, *value, ret);
+
+ out:
+ mutex_unlock(&dev->phy_mutex);
+ return ret;
+}
+
+static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, u16 value)
+{
+ int ret, i;
+
+ mutex_lock(&dev->phy_mutex);
+
+ ret = dm_write(dev, DM_SHARED_DATA, 2, &value);
+ if (ret < 0)
+ goto out;
+
+ dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
+ dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14);
+
+ for (i = 0; i < DM_TIMEOUT; i++) {
+ u8 tmp;
+
+ udelay(1);
+ ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
+ if (ret < 0)
+ goto out;
+
+ /* ready */
+ if ((tmp & 1) == 0)
+ break;
+ }
+
+ if (i == DM_TIMEOUT) {
+ deverr(dev, "%s write timed out!", phy ? "phy" : "eeprom");
+ ret = -EIO;
+ goto out;
+ }
+
+ dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
+
+out:
+ mutex_unlock(&dev->phy_mutex);
+ return ret;
+}
+
+static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
+{
+ return dm_read_shared_word(dev, 0, offset, value);
+}
+
+
+
+static int dm9601_get_eeprom_len(struct net_device *dev)
+{
+ return DM_EEPROM_LEN;
+}
+
+static int dm9601_get_eeprom(struct net_device *net,
+ struct ethtool_eeprom *eeprom, u8 * data)
+{
+ struct usbnet *dev = netdev_priv(net);
+ u16 *ebuf = (u16 *) data;
+ int i;
+
+ /* access is 16bit */
+ if ((eeprom->offset % 2) || (eeprom->len % 2))
+ return -EINVAL;
+
+ for (i = 0; i < eeprom->len / 2; i++) {
+ if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i,
+ &ebuf[i]) < 0)
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+
+ u16 res;
+
+ if (phy_id) {
+ devdbg(dev, "Only internal phy supported");
+ return 0;
+ }
+
+ dm_read_shared_word(dev, 1, loc, &res);
+
+ devdbg(dev,
+ "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x",
+ phy_id, loc, le16_to_cpu(res));
+
+ return le16_to_cpu(res);
+}
+
+static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,
+ int val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ u16 res = cpu_to_le16(val);
+
+ if (phy_id) {
+ devdbg(dev, "Only internal phy supported");
+ return;
+ }
+
+ devdbg(dev,"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
+ phy_id, loc, val);
+
+ dm_write_shared_word(dev, 1, loc, res);
+}
+
+static void dm9601_get_drvinfo(struct net_device *net,
+ struct ethtool_drvinfo *info)
+{
+ /* Inherit standard device info */
+ usbnet_get_drvinfo(net, info);
+ info->eedump_len = DM_EEPROM_LEN;
+}
+
+static u32 dm9601_get_link(struct net_device *net)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ return mii_link_ok(&dev->mii);
+}
+
+static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+ struct usbnet *dev = netdev_priv(net);
+
+ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static struct ethtool_ops dm9601_ethtool_ops = {
+ .get_drvinfo = dm9601_get_drvinfo,
+ .get_link = dm9601_get_link,
+ .get_msglevel = usbnet_get_msglevel,
+ .set_msglevel = usbnet_set_msglevel,
+ .get_eeprom_len = dm9601_get_eeprom_len,
+ .get_eeprom = dm9601_get_eeprom,
+ .get_settings = usbnet_get_settings,
+ .set_settings = usbnet_set_settings,
+ .nway_reset = usbnet_nway_reset,
+};
+
+static void dm9601_set_multicast(struct net_device *net)
+{
+ struct usbnet *dev = netdev_priv(net);
+ /* We use the 20 byte dev->data for our 8 byte filter buffer
+ * to avoid allocating memory that is tricky to free later */
+ u8 *hashes = (u8 *) & dev->data;
+ u8 rx_ctl = 0x01;
+
+ memset(hashes, 0x00, DM_MCAST_SIZE);
+ hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */
+
+ if (net->flags & IFF_PROMISC) {
+ rx_ctl |= 0x02;
+ } else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) {
+ rx_ctl |= 0x04;
+ } else if (net->mc_count) {
+ struct dev_mc_list *mc_list = net->mc_list;
+ int i;
+
+ for (i = 0; i < net->mc_count; i++) {
+ u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
+ hashes[crc >> 3] |= 1 << (crc & 0x7);
+ }
+ }
+
+ dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes);
+ dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
+}
+
+static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+
+ ret = usbnet_get_endpoints(dev, intf);
+ if (ret)
+ goto out;
+
+ dev->net->do_ioctl = dm9601_ioctl;
+ dev->net->set_multicast_list = dm9601_set_multicast;
+ dev->net->ethtool_ops = &dm9601_ethtool_ops;
+ dev->net->hard_header_len += DM_TX_OVERHEAD;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+ dev->rx_urb_size = dev->net->mtu + DM_RX_OVERHEAD;
+
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = dm9601_mdio_read;
+ dev->mii.mdio_write = dm9601_mdio_write;
+ dev->mii.phy_id_mask = 0x1f;
+ dev->mii.reg_num_mask = 0x1f;
+
+ /* reset */
+ ret = dm_write_reg(dev, DM_NET_CTRL, 1);
+ udelay(20);
+
+ /* read MAC */
+ ret = dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
+ if (ret < 0) {
+ printk(KERN_ERR "Error reading MAC address\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+
+ /* power up phy */
+ dm_write_reg(dev, DM_GPR_CTRL, 1);
+ dm_write_reg(dev, DM_GPR_DATA, 0);
+
+ /* receive broadcast packets */
+ dm9601_set_multicast(dev->net);
+
+ dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+ dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+ mii_nway_restart(&dev->mii);
+
+out:
+ return ret;
+}
+
+static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ u8 status;
+ int len;
+
+ /* format:
+ b0: rx status
+ b1: packet length (incl crc) low
+ b2: packet length (incl crc) high
+ b3..n-4: packet data
+ bn-3..bn: ethernet crc
+ */
+
+ if (unlikely(skb->len < DM_RX_OVERHEAD)) {
+ dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
+ return 0;
+ }
+
+ status = skb->data[0];
+ len = (skb->data[1] | (skb->data[2] << 8)) - 4;
+
+ if (unlikely(status & 0xbf)) {
+ if (status & 0x01) dev->stats.rx_fifo_errors++;
+ if (status & 0x02) dev->stats.rx_crc_errors++;
+ if (status & 0x04) dev->stats.rx_frame_errors++;
+ if (status & 0x20) dev->stats.rx_missed_errors++;
+ if (status & 0x90) dev->stats.rx_length_errors++;
+ return 0;
+ }
+
+ skb_pull(skb, 3);
+ skb_trim(skb, len);
+
+ return 1;
+}
+
+static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+ gfp_t flags)
+{
+ int len;
+
+ /* format:
+ b0: packet length low
+ b1: packet length high
+ b3..n: packet data
+ */
+
+ if (skb_headroom(skb) < DM_TX_OVERHEAD) {
+ struct sk_buff *skb2;
+
+ skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags);
+ dev_kfree_skb_any(skb);
+ skb = skb2;
+ if (!skb)
+ return NULL;
+ }
+
+ __skb_push(skb, DM_TX_OVERHEAD);
+
+ len = skb->len;
+ /* usbnet adds padding if length is a multiple of packet size
+ if so, adjust length value in header */
+ if ((len % dev->maxpacket) == 0)
+ len++;
+
+ skb->data[0] = len;
+ skb->data[1] = len >> 8;
+
+ return skb;
+}
+
+static void dm9601_status(struct usbnet *dev, struct urb *urb)
+{
+ int link;
+ u8 *buf;
+
+ /* format:
+ b0: net status
+ b1: tx status 1
+ b2: tx status 2
+ b3: rx status
+ b4: rx overflow
+ b5: rx count
+ b6: tx count
+ b7: gpr
+ */
+
+ if (urb->actual_length < 8)
+ return;
+
+ buf = urb->transfer_buffer;
+
+ link = !!(buf[0] & 0x40);
+ if (netif_carrier_ok(dev->net) != link) {
+ if (link) {
+ netif_carrier_on(dev->net);
+ usbnet_defer_kevent (dev, EVENT_LINK_RESET);
+ }
+ else
+ netif_carrier_off(dev->net);
+ devdbg(dev, "Link Status is: %d", link);
+ }
+}
+
+static int dm9601_link_reset(struct usbnet *dev)
+{
+ struct ethtool_cmd ecmd;
+
+ mii_check_media(&dev->mii, 1, 1);
+ mii_ethtool_gset(&dev->mii, &ecmd);
+
+ devdbg(dev, "link_reset() speed: %d duplex: %d",
+ ecmd.speed, ecmd.duplex);
+
+ return 0;
+}
+
+static const struct driver_info dm9601_info = {
+ .description = "Davicom DM9601 USB Ethernet",
+ .flags = FLAG_ETHER,
+ .bind = dm9601_bind,
+ .rx_fixup = dm9601_rx_fixup,
+ .tx_fixup = dm9601_tx_fixup,
+ .status = dm9601_status,
+ .link_reset = dm9601_link_reset,
+ .reset = dm9601_link_reset,
+};
+
+static const struct usb_device_id products[] = {
+ {
+ USB_DEVICE(0x0a46, 0x9601), /* Davicom USB-100 */
+ .driver_info = (unsigned long)&dm9601_info,
+ },
+ {}, // END
+};
+
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver dm9601_driver = {
+ .name = "dm9601",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init dm9601_init(void)
+{
+ return usb_register(&dm9601_driver);
+}
+
+static void __exit dm9601_exit(void)
+{
+ usb_deregister(&dm9601_driver);
+}
+
+module_init(dm9601_init);
+module_exit(dm9601_exit);
+
+MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
+MODULE_DESCRIPTION("Davicom DM9601 USB 1.1 ethernet devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4695952b647..c525b42dadd 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -513,6 +513,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+ { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 7eff1c03ba8..1bdda935f7d 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -491,6 +491,12 @@
#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */
#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */
+/*
+ * Telldus Technologies
+ */
+#define TELLDUS_VID 0x1781 /* Vendor ID */
+#define TELLDUS_TELLSTICK_PID 0x0C30 /* RF control dongle 433 MHz using FT232RL */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 9963a8b7584..db92a7fb1f7 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -67,50 +67,95 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file,
static int option_send_setup(struct usb_serial_port *port);
/* Vendor and product IDs */
-#define OPTION_VENDOR_ID 0x0AF0
-#define HUAWEI_VENDOR_ID 0x12D1
-#define NOVATELWIRELESS_VENDOR_ID 0x1410
-#define ANYDATA_VENDOR_ID 0x16d5
-
-#define OPTION_PRODUCT_OLD 0x5000
-#define OPTION_PRODUCT_FUSION 0x6000
-#define OPTION_PRODUCT_FUSION2 0x6300
-#define OPTION_PRODUCT_COBRA 0x6500
-#define OPTION_PRODUCT_COBRA2 0x6600
-#define OPTION_PRODUCT_GTMAX36 0x6701
-#define HUAWEI_PRODUCT_E600 0x1001
-#define HUAWEI_PRODUCT_E220 0x1003
-#define NOVATELWIRELESS_PRODUCT_U740 0x1400
-#define ANYDATA_PRODUCT_ID 0x6501
+#define OPTION_VENDOR_ID 0x0AF0
+#define OPTION_PRODUCT_COLT 0x5000
+#define OPTION_PRODUCT_RICOLA 0x6000
+#define OPTION_PRODUCT_RICOLA_LIGHT 0x6100
+#define OPTION_PRODUCT_RICOLA_QUAD 0x6200
+#define OPTION_PRODUCT_RICOLA_QUAD_LIGHT 0x6300
+#define OPTION_PRODUCT_RICOLA_NDIS 0x6050
+#define OPTION_PRODUCT_RICOLA_NDIS_LIGHT 0x6150
+#define OPTION_PRODUCT_RICOLA_NDIS_QUAD 0x6250
+#define OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT 0x6350
+#define OPTION_PRODUCT_COBRA 0x6500
+#define OPTION_PRODUCT_COBRA_BUS 0x6501
+#define OPTION_PRODUCT_VIPER 0x6600
+#define OPTION_PRODUCT_VIPER_BUS 0x6601
+#define OPTION_PRODUCT_GT_MAX_READY 0x6701
+#define OPTION_PRODUCT_GT_MAX 0x6711
+#define OPTION_PRODUCT_FUJI_MODEM_LIGHT 0x6721
+#define OPTION_PRODUCT_FUJI_MODEM_GT 0x6741
+#define OPTION_PRODUCT_FUJI_MODEM_EX 0x6761
+#define OPTION_PRODUCT_FUJI_NETWORK_LIGHT 0x6731
+#define OPTION_PRODUCT_FUJI_NETWORK_GT 0x6751
+#define OPTION_PRODUCT_FUJI_NETWORK_EX 0x6771
+#define OPTION_PRODUCT_KOI_MODEM 0x6800
+#define OPTION_PRODUCT_KOI_NETWORK 0x6811
+#define OPTION_PRODUCT_SCORPION_MODEM 0x6901
+#define OPTION_PRODUCT_SCORPION_NETWORK 0x6911
+#define OPTION_PRODUCT_ETNA_MODEM 0x7001
+#define OPTION_PRODUCT_ETNA_NETWORK 0x7011
+#define OPTION_PRODUCT_ETNA_MODEM_LITE 0x7021
+#define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041
+#define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061
+#define OPTION_PRODUCT_ETNA_NETWORK_LITE 0x7031
+#define OPTION_PRODUCT_ETNA_NETWORK_GT 0x7051
+#define OPTION_PRODUCT_ETNA_NETWORK_EX 0x7071
+#define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100
+#define OPTION_PRODUCT_ETNA_KOI_NETWORK 0x7111
+
+#define HUAWEI_VENDOR_ID 0x12D1
+#define HUAWEI_PRODUCT_E600 0x1001
+#define HUAWEI_PRODUCT_E220 0x1003
+
+#define NOVATELWIRELESS_VENDOR_ID 0x1410
+#define NOVATELWIRELESS_PRODUCT_U740 0x1400
+
+#define ANYDATA_VENDOR_ID 0x16d5
+#define ANYDATA_PRODUCT_ID 0x6501
static struct usb_device_id option_ids[] = {
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD_LIGHT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_LIGHT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA_BUS) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_LIGHT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_GT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_EX) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_NETWORK) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_NETWORK) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_LITE) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_GT) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */
};
-
-static struct usb_device_id option_ids1[] = {
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
- { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
- { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
- { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
- { } /* Terminating entry */
-};
-
MODULE_DEVICE_TABLE(usb, option_ids);
static struct usb_driver option_driver = {
@@ -132,7 +177,7 @@ static struct usb_serial_driver option_1port_device = {
},
.description = "GSM modem (1-port)",
.usb_driver = &option_driver,
- .id_table = option_ids1,
+ .id_table = option_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 6988a1082f5..03893acbfda 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -1919,7 +1919,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
* header ?
*/
if (tlck->type & tlckTRUNCATE) {
- pxd_t pxd; /* truncated extent of xad */
+ /* This odd declaration suppresses a bogus gcc warning */
+ pxd_t pxd = pxd; /* truncated extent of xad */
int twm;
/*
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 98b0910ad80..8d4d839a9d8 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -502,6 +502,30 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
/**
+ * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @group: group name.
+ */
+int sysfs_add_file_to_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group)
+{
+ struct dentry *dir;
+ int error;
+
+ dir = lookup_one_len(group, kobj->dentry, strlen(group));
+ if (IS_ERR(dir))
+ error = PTR_ERR(dir);
+ else {
+ error = sysfs_add_file(dir, attr, SYSFS_KOBJ_ATTR);
+ dput(dir);
+ }
+ return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
+
+
+/**
* sysfs_update_file - update the modified timestamp on an object attribute.
* @kobj: object we're acting for.
* @attr: attribute descriptor.
@@ -586,6 +610,26 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
}
+/**
+ * sysfs_remove_file_from_group - remove an attribute file from a group.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @group: group name.
+ */
+void sysfs_remove_file_from_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group)
+{
+ struct dentry *dir;
+
+ dir = lookup_one_len(group, kobj->dentry, strlen(group));
+ if (!IS_ERR(dir)) {
+ sysfs_hash_and_remove(dir, attr->name);
+ dput(dir);
+ }
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
+
+
EXPORT_SYMBOL_GPL(sysfs_create_file);
EXPORT_SYMBOL_GPL(sysfs_remove_file);
EXPORT_SYMBOL_GPL(sysfs_update_file);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index d976b000554..a77c57e5a6d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -1,3 +1,14 @@
+struct sysfs_dirent {
+ atomic_t s_count;
+ struct list_head s_sibling;
+ struct list_head s_children;
+ void * s_element;
+ int s_type;
+ umode_t s_mode;
+ struct dentry * s_dentry;
+ struct iattr * s_iattr;
+ atomic_t s_event;
+};
extern struct vfsmount * sysfs_mount;
extern struct kmem_cache *sysfs_dir_cachep;
diff --git a/include/asm-i386/idle.h b/include/asm-i386/idle.h
deleted file mode 100644
index 87ab9391119..00000000000
--- a/include/asm-i386/idle.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _ASM_I386_IDLE_H
-#define _ASM_I386_IDLE_H 1
-
-#define IDLE_START 1
-#define IDLE_END 2
-
-struct notifier_block;
-void idle_notifier_register(struct notifier_block *n);
-void idle_notifier_unregister(struct notifier_block *n);
-
-void exit_idle(void);
-void enter_idle(void);
-
-#endif
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index edfbe46a5e1..11bf899de8a 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -257,14 +257,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
: :"a" (eax), "c" (ecx));
}
-static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
-{
- /* "mwait %eax,%ecx;" */
- asm volatile(
- "sti; .byte 0x0f,0x01,0xc9;"
- : :"a" (eax), "c" (ecx));
-}
-
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
/* from system description table in BIOS. Mostly for MCA use, but
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 8a1f2b6f04a..1906938285c 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -21,6 +21,7 @@
#define FPC_EIR 70
#define DSP_BASE 71 /* 3 more hi / lo register pairs */
#define DSP_CONTROL 77
+#define ACX 78
/*
* This struct defines the way the registers are stored on the stack during a
@@ -39,6 +40,9 @@ struct pt_regs {
unsigned long cp0_status;
unsigned long hi;
unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ unsigned long acx;
+#endif
unsigned long cp0_badvaddr;
unsigned long cp0_cause;
unsigned long cp0_epc;
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index 972947474eb..9ce0607d7a4 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -23,7 +23,7 @@ struct sigcontext {
unsigned long long sc_pc;
unsigned long long sc_regs[32];
unsigned long long sc_fpregs[32];
- unsigned int sc_ownedfp; /* Unused */
+ unsigned int sc_acx; /* Was sc_ownedfp */
unsigned int sc_fpc_csr;
unsigned int sc_fpc_eir; /* Unused */
unsigned int sc_used_math;
@@ -79,7 +79,7 @@ struct sigcontext32 {
__u64 sc_pc;
__u64 sc_regs[32];
__u64 sc_fpregs[32];
- __u32 sc_ownedfp; /* Unused */
+ __u32 sc_acx; /* Only MIPS32; was sc_ownedfp */
__u32 sc_fpc_csr;
__u32 sc_fpc_eir; /* Unused */
__u32 sc_used_math;
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index 1fae5dc5813..7afa1fdf70c 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -29,16 +29,25 @@
.endm
.macro SAVE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ mflhxu v1
+ LONG_S v1, PT_LO(sp)
+ mflhxu v1
+ LONG_S v1, PT_HI(sp)
+ mflhxu v1
+ LONG_S v1, PT_ACX(sp)
+#else
mfhi v1
+ LONG_S v1, PT_HI(sp)
+ mflo v1
+ LONG_S v1, PT_LO(sp)
+#endif
#ifdef CONFIG_32BIT
LONG_S $8, PT_R8(sp)
LONG_S $9, PT_R9(sp)
#endif
- LONG_S v1, PT_HI(sp)
- mflo v1
LONG_S $10, PT_R10(sp)
LONG_S $11, PT_R11(sp)
- LONG_S v1, PT_LO(sp)
LONG_S $12, PT_R12(sp)
LONG_S $13, PT_R13(sp)
LONG_S $14, PT_R14(sp)
@@ -182,16 +191,25 @@
.endm
.macro RESTORE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ LONG_L $24, PT_ACX(sp)
+ mtlhx $24
+ LONG_L $24, PT_HI(sp)
+ mtlhx $24
LONG_L $24, PT_LO(sp)
+ mtlhx $24
+#else
+ LONG_L $24, PT_LO(sp)
+ mtlo $24
+ LONG_L $24, PT_HI(sp)
+ mthi $24
+#endif
#ifdef CONFIG_32BIT
LONG_L $8, PT_R8(sp)
LONG_L $9, PT_R9(sp)
#endif
- mtlo $24
- LONG_L $24, PT_HI(sp)
LONG_L $10, PT_R10(sp)
LONG_L $11, PT_R11(sp)
- mthi $24
LONG_L $12, PT_R12(sp)
LONG_L $13, PT_R13(sp)
LONG_L $14, PT_R14(sp)
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 552df5f10a6..2e4b7a5ed1c 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -32,9 +32,30 @@
#define IA32_SYSCALL_VECTOR 0x80
+/* Reserve the lowest usable priority level 0x20 - 0x2f for triggering
+ * cleanup after irq migration.
+ */
+#define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR
+
/*
* Vectors 0x20-0x2f are used for ISA interrupts.
*/
+#define IRQ0_VECTOR FIRST_EXTERNAL_VECTOR + 0x10
+#define IRQ1_VECTOR IRQ0_VECTOR + 1
+#define IRQ2_VECTOR IRQ0_VECTOR + 2
+#define IRQ3_VECTOR IRQ0_VECTOR + 3
+#define IRQ4_VECTOR IRQ0_VECTOR + 4
+#define IRQ5_VECTOR IRQ0_VECTOR + 5
+#define IRQ6_VECTOR IRQ0_VECTOR + 6
+#define IRQ7_VECTOR IRQ0_VECTOR + 7
+#define IRQ8_VECTOR IRQ0_VECTOR + 8
+#define IRQ9_VECTOR IRQ0_VECTOR + 9
+#define IRQ10_VECTOR IRQ0_VECTOR + 10
+#define IRQ11_VECTOR IRQ0_VECTOR + 11
+#define IRQ12_VECTOR IRQ0_VECTOR + 12
+#define IRQ13_VECTOR IRQ0_VECTOR + 13
+#define IRQ14_VECTOR IRQ0_VECTOR + 14
+#define IRQ15_VECTOR IRQ0_VECTOR + 15
/*
* Special IRQ vectors used by the SMP architecture, 0xf0-0xff
@@ -66,10 +87,10 @@
/*
* First APIC vector available to drivers: (vectors 0x30-0xee)
- * we start at 0x31 to spread out vectors evenly between priority
+ * we start at 0x41 to spread out vectors evenly between priority
* levels. (0x80 is the syscall vector)
*/
-#define FIRST_DEVICE_VECTOR 0x31
+#define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2)
#define FIRST_SYSTEM_VECTOR 0xef /* duplicated in irq.h */
diff --git a/include/linux/device.h b/include/linux/device.h
index d1a3a27c398..39a3199a826 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -294,8 +294,6 @@ extern void class_device_initialize(struct class_device *);
extern int __must_check class_device_add(struct class_device *);
extern void class_device_del(struct class_device *);
-extern int class_device_rename(struct class_device *, char *);
-
extern struct class_device * class_device_get(struct class_device *);
extern void class_device_put(struct class_device *);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index aa5b3e6178a..b0a44b8e028 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -200,17 +200,6 @@ extern int setup_irq(unsigned int irq, struct irqaction *new);
#endif
#ifdef CONFIG_SMP
-static inline void set_native_irq_info(int irq, cpumask_t mask)
-{
- irq_desc[irq].affinity = mask;
-}
-#else
-static inline void set_native_irq_info(int irq, cpumask_t mask)
-{
-}
-#endif
-
-#ifdef CONFIG_SMP
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index cc8e674ae27..10f505c8431 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -28,10 +28,8 @@
#ifdef CONFIG_KMOD
/* modprobe exit status on success, -ve on error. Return value
* usually useless though. */
-extern void kmod_sysfs_init(void);
extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
#else
-static inline void kmod_sysfs_init(void) {};
static inline int request_module(const char * name, ...) { return -ENOSYS; }
#endif
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 070394e846d..21db05ac7c0 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -120,15 +120,48 @@ typedef int __bitwise suspend_disk_method_t;
#define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6)
#define PM_DISK_MAX ((__force suspend_disk_method_t) 7)
+/**
+ * struct pm_ops - Callbacks for managing platform dependent suspend states.
+ * @valid: Callback to determine whether the given state can be entered.
+ * If %CONFIG_SOFTWARE_SUSPEND is set then %PM_SUSPEND_DISK is
+ * always valid and never passed to this call.
+ * If not assigned, all suspend states are advertised as valid
+ * in /sys/power/state (but can still be rejected by prepare or enter.)
+ *
+ * @prepare: Prepare the platform for the given suspend state. Can return a
+ * negative error code if necessary.
+ *
+ * @enter: Enter the given suspend state, must be assigned. Can return a
+ * negative error code if necessary.
+ *
+ * @finish: Called when the system has left the given state and all devices
+ * are resumed. The return value is ignored.
+ *
+ * @pm_disk_mode: Set to the disk method that the user should be able to
+ * configure for suspend-to-disk. Since %PM_DISK_SHUTDOWN,
+ * %PM_DISK_REBOOT, %PM_DISK_TEST and %PM_DISK_TESTPROC
+ * are always allowed, currently only %PM_DISK_PLATFORM
+ * makes sense. If the user then choses %PM_DISK_PLATFORM,
+ * the @prepare call will be called before suspending to disk
+ * (if present), the @enter call should be present and will
+ * be called after all state has been saved and the machine
+ * is ready to be shut down/suspended/..., and the @finish
+ * callback is called after state has been restored. All
+ * these calls are called with %PM_SUSPEND_DISK as the state.
+ */
struct pm_ops {
- suspend_disk_method_t pm_disk_mode;
int (*valid)(suspend_state_t state);
int (*prepare)(suspend_state_t state);
int (*enter)(suspend_state_t state);
int (*finish)(suspend_state_t state);
+ suspend_disk_method_t pm_disk_mode;
};
-extern void pm_set_ops(struct pm_ops *);
+/**
+ * pm_set_ops - set platform dependent power management ops
+ * @pm_ops: The new power management operations to set.
+ */
+extern void pm_set_ops(struct pm_ops *pm_ops);
extern struct pm_ops *pm_ops;
extern int pm_suspend(suspend_state_t state);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 192de3afa96..21805b500aa 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -17,6 +17,7 @@
struct kobject;
struct module;
struct nameidata;
+struct dentry;
struct attribute {
const char * name;
@@ -68,18 +69,6 @@ struct sysfs_ops {
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
-struct sysfs_dirent {
- atomic_t s_count;
- struct list_head s_sibling;
- struct list_head s_children;
- void * s_element;
- int s_type;
- umode_t s_mode;
- struct dentry * s_dentry;
- struct iattr * s_iattr;
- atomic_t s_event;
-};
-
#define SYSFS_ROOT 0x0001
#define SYSFS_DIR 0x0002
#define SYSFS_KOBJ_ATTR 0x0004
@@ -126,6 +115,11 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
int __must_check sysfs_create_group(struct kobject *,
const struct attribute_group *);
void sysfs_remove_group(struct kobject *, const struct attribute_group *);
+int sysfs_add_file_to_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group);
+void sysfs_remove_file_from_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group);
+
void sysfs_notify(struct kobject * k, char *dir, char *attr);
@@ -210,6 +204,18 @@ static inline void sysfs_remove_group(struct kobject * k, const struct attribute
;
}
+static inline int sysfs_add_file_to_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group)
+{
+ return 0;
+}
+
+static inline void sysfs_remove_file_from_group(struct kobject *kobj,
+ const struct attribute *attr, const char *group);
+{
+ ;
+}
+
static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
{
}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index a8e8d1ecebb..87dc75a6cee 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -388,10 +388,14 @@ struct usb_device {
struct usb_device *children[USB_MAXCHILDREN];
int pm_usage_cnt; /* usage counter for autosuspend */
+ u32 quirks; /* quirks of the whole device */
+
#ifdef CONFIG_PM
struct delayed_work autosuspend; /* for delayed autosuspends */
struct mutex pm_mutex; /* protects PM operations */
+ unsigned autosuspend_delay; /* in jiffies */
+
unsigned auto_pm:1; /* autosuspend/resume in progress */
unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */
#endif
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 245c7253122..1122a6c2c1a 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -1,8 +1,9 @@
/*
- * This file holds USB constants and structures that are needed for USB
- * device APIs. These are used by the USB device model, which is defined
- * in chapter 9 of the USB 2.0 specification. Linux has several APIs in C
- * that need these:
+ * This file holds USB constants and structures that are needed for
+ * USB device APIs. These are used by the USB device model, which is
+ * defined in chapter 9 of the USB 2.0 specification and in the
+ * Wireless USB 1.0 (spread around). Linux has several APIs in C that
+ * need these:
*
* - the master/host side Linux-USB kernel driver API;
* - the "usbfs" user space API; and
@@ -14,6 +15,19 @@
*
* There's also "Wireless USB", using low power short range radios for
* peripheral interconnection but otherwise building on the USB framework.
+ *
+ * Note all descriptors are declared '__attribute__((packed))' so that:
+ *
+ * [a] they never get padded, either internally (USB spec writers
+ * probably handled that) or externally;
+ *
+ * [b] so that accessing bigger-than-a-bytes fields will never
+ * generate bus errors on any platform, even when the location of
+ * its descriptor inside a bundle isn't "naturally aligned", and
+ *
+ * [c] for consistency, removing all doubt even when it appears to
+ * someone that the two other points are non-issues for that
+ * particular descriptor type.
*/
#ifndef __LINUX_USB_CH9_H
diff --git a/include/linux/usb/iowarrior.h b/include/linux/usb/iowarrior.h
new file mode 100644
index 00000000000..cbbe020a4f5
--- /dev/null
+++ b/include/linux/usb/iowarrior.h
@@ -0,0 +1,33 @@
+#ifndef _IOWARRIOR_H_
+#define _IOWARRIOR_H_
+
+#define CODEMERCS_MAGIC_NUMBER 0xC0 /* like COde Mercenaries */
+
+/* Define the ioctl commands for reading and writing data */
+#define IOW_WRITE _IOW(CODEMERCS_MAGIC_NUMBER, 1, __u8 *)
+#define IOW_READ _IOW(CODEMERCS_MAGIC_NUMBER, 2, __u8 *)
+
+/*
+ A struct for available device info which is read
+ with the ioctl IOW_GETINFO.
+ To be compatible with 2.4 userspace which didn't have an easy way to get
+ this information.
+*/
+struct iowarrior_info {
+ __u32 vendor; /* vendor id : supposed to be USB_VENDOR_ID_CODEMERCS in all cases */
+ __u32 product; /* product id : depends on type of chip (USB_DEVICE_ID_CODEMERCS_XXXXX) */
+ __u8 serial[9]; /* the serial number of our chip (if a serial-number is not available this is empty string) */
+ __u32 revision; /* revision number of the chip */
+ __u32 speed; /* USB-speed of the device (0=UNKNOWN, 1=LOW, 2=FULL 3=HIGH) */
+ __u32 power; /* power consumption of the device in mA */
+ __u32 if_num; /* the number of the endpoint */
+ __u32 report_size; /* size of the data-packets on this interface */
+};
+
+/*
+ Get some device-information (product-id , serial-number etc.)
+ in order to identify a chip.
+*/
+#define IOW_GETINFO _IOR(CODEMERCS_MAGIC_NUMBER, 3, struct iowarrior_info)
+
+#endif /* _IOWARRIOR_H_ */
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
new file mode 100644
index 00000000000..6bac8faacbc
--- /dev/null
+++ b/include/linux/usb/quirks.h
@@ -0,0 +1,11 @@
+/*
+ * This file holds the definitions of quirks found in USB devices.
+ * Only quirks that affect the whole device, not an interface,
+ * belong here.
+ */
+
+/* device must not be autosuspended */
+#define USB_QUIRK_NO_AUTOSUSPEND 0x00000001
+
+/* string descriptors must not be fetched using a 255-byte read */
+#define USB_QUIRK_STRING_FETCH_255 0x00000002
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 4baa3bbcd25..77b7acc875c 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -65,12 +65,11 @@ void move_native_irq(int irq)
if (likely(!(desc->status & IRQ_MOVE_PENDING)))
return;
- if (likely(!(desc->status & IRQ_DISABLED)))
- desc->chip->disable(irq);
+ if (unlikely(desc->status & IRQ_DISABLED))
+ return;
+ desc->chip->mask(irq);
move_masked_irq(irq);
-
- if (likely(!(desc->status & IRQ_DISABLED)))
- desc->chip->enable(irq);
+ desc->chip->unmask(irq);
}
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 9f923f8ce6a..796276141e5 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -36,8 +36,6 @@
#include <linux/resource.h>
#include <asm/uaccess.h>
-extern int delete_module(const char *name, unsigned int flags);
-
extern int max_threads;
static struct workqueue_struct *khelper_wq;
@@ -48,7 +46,6 @@ static struct workqueue_struct *khelper_wq;
modprobe_path is set via /proc/sys.
*/
char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
-struct module_kobject kmod_mk;
/**
* request_module - try to load a kernel module
@@ -78,11 +75,6 @@ int request_module(const char *fmt, ...)
static atomic_t kmod_concurrent = ATOMIC_INIT(0);
#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
static int kmod_loop_msg;
- char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
- char *uevent_envp[2] = {
- modalias,
- NULL
- };
va_start(args, fmt);
ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -90,12 +82,6 @@ int request_module(const char *fmt, ...)
if (ret >= MODULE_NAME_LEN)
return -ENAMETOOLONG;
- strcpy(&modalias[strlen("MODALIAS=")], module_name);
- kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
-
- if (modprobe_path[0] == '\0')
- goto out;
-
/* If modprobe needs a service that is in a module, we get a recursive
* loop. Limit the number of running kmod threads to max_threads/2 or
* MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
@@ -122,115 +108,9 @@ int request_module(const char *fmt, ...)
ret = call_usermodehelper(modprobe_path, argv, envp, 1);
atomic_dec(&kmod_concurrent);
-out:
return ret;
}
EXPORT_SYMBOL(request_module);
-
-static ssize_t store_mod_request(struct module_attribute *mattr,
- struct module *mod,
- const char *buffer, size_t count)
-{
- char name[MODULE_NAME_LEN];
- int ret;
-
- if (count < 1 || count+1 > MODULE_NAME_LEN)
- return -EINVAL;
- memcpy(name, buffer, count);
- name[count] = '\0';
- if (name[count-1] == '\n')
- name[count-1] = '\0';
-
- ret = request_module(name);
- if (ret < 0)
- return ret;
- return count;
-}
-
-static struct module_attribute mod_request = {
- .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
- .store = store_mod_request,
-};
-
-#ifdef CONFIG_MODULE_UNLOAD
-static ssize_t store_mod_unload(struct module_attribute *mattr,
- struct module *mod,
- const char *buffer, size_t count)
-{
- char name[MODULE_NAME_LEN];
- int ret;
-
- if (count < 1 || count+1 > MODULE_NAME_LEN)
- return -EINVAL;
- memcpy(name, buffer, count);
- name[count] = '\0';
- if (name[count-1] == '\n')
- name[count-1] = '\0';
-
- ret = delete_module(name, O_NONBLOCK);
- if (ret < 0)
- return ret;
- return count;
-}
-
-static struct module_attribute mod_unload = {
- .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
- .store = store_mod_unload,
-};
-#endif
-
-static ssize_t show_mod_request_helper(struct module_attribute *mattr,
- struct module *mod,
- char *buffer)
-{
- return sprintf(buffer, "%s\n", modprobe_path);
-}
-
-static ssize_t store_mod_request_helper(struct module_attribute *mattr,
- struct module *mod,
- const char *buffer, size_t count)
-{
- if (count < 1 || count+1 > KMOD_PATH_LEN)
- return -EINVAL;
- memcpy(modprobe_path, buffer, count);
- modprobe_path[count] = '\0';
- if (modprobe_path[count-1] == '\n')
- modprobe_path[count-1] = '\0';
- return count;
-}
-
-static struct module_attribute mod_request_helper = {
- .attr = {
- .name = "mod_request_helper",
- .mode = S_IWUSR | S_IRUGO,
- .owner = THIS_MODULE
- },
- .show = show_mod_request_helper,
- .store = store_mod_request_helper,
-};
-
-void __init kmod_sysfs_init(void)
-{
- int ret;
-
- kmod_mk.mod = THIS_MODULE;
- kobj_set_kset_s(&kmod_mk, module_subsys);
- kobject_set_name(&kmod_mk.kobj, "kmod");
- kobject_init(&kmod_mk.kobj);
- ret = kobject_add(&kmod_mk.kobj);
- if (ret < 0)
- goto out;
-
- ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
- ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
-#ifdef CONFIG_MODULE_UNLOAD
- ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
-#endif
-
- kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
-out:
- return;
-}
#endif /* CONFIG_KMOD */
struct subprocess_info {
diff --git a/kernel/module.c b/kernel/module.c
index 8c25b1a04fa..f77e893e462 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -653,11 +653,20 @@ static void wait_for_zero_refcount(struct module *mod)
mutex_lock(&module_mutex);
}
-int delete_module(const char *name, unsigned int flags)
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
{
struct module *mod;
+ char name[MODULE_NAME_LEN];
int ret, forced = 0;
+ if (!capable(CAP_SYS_MODULE))
+ return -EPERM;
+
+ if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+ return -EFAULT;
+ name[MODULE_NAME_LEN-1] = '\0';
+
if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR;
@@ -718,21 +727,6 @@ int delete_module(const char *name, unsigned int flags)
return ret;
}
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
-{
- char name[MODULE_NAME_LEN];
-
- if (!capable(CAP_SYS_MODULE))
- return -EPERM;
-
- if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
- return -EFAULT;
- name[MODULE_NAME_LEN-1] = '\0';
-
- return delete_module(name, flags);
-}
-
static void print_unload_info(struct seq_file *m, struct module *mod)
{
struct module_use *use;
@@ -2425,6 +2419,12 @@ void module_remove_driver(struct device_driver *drv)
kfree(driver_name);
}
}
+ /*
+ * Undo the additional reference we added in module_add_driver()
+ * via kset_find_obj()
+ */
+ if (drv->mod_name)
+ kobject_put(&drv->kobj);
}
EXPORT_SYMBOL(module_remove_driver);
#endif
diff --git a/kernel/params.c b/kernel/params.c
index 7a751570b56..e265b13195b 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -707,7 +707,6 @@ static int __init param_sysfs_init(void)
}
param_sysfs_builtin();
- kmod_sysfs_init();
return 0;
}
diff --git a/kernel/power/main.c b/kernel/power/main.c
index e1c41312046..a064dfd8877 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -167,7 +167,10 @@ static inline int valid_state(suspend_state_t state)
if (state == PM_SUSPEND_DISK)
return 1;
- if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
+ /* all other states need lowlevel support and need to be
+ * valid to the lowlevel implementation, no valid callback
+ * implies that all are valid. */
+ if (!pm_ops || (pm_ops->valid && !pm_ops->valid(state)))
return 0;
return 1;
}
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 4500e347f1b..0986a2bfab4 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -77,6 +77,7 @@ static void tick_periodic(int cpu)
void tick_handle_periodic(struct clock_event_device *dev)
{
int cpu = smp_processor_id();
+ ktime_t next;
tick_periodic(cpu);
@@ -86,12 +87,12 @@ void tick_handle_periodic(struct clock_event_device *dev)
* Setup the next period for devices, which do not have
* periodic mode:
*/
+ next = ktime_add(dev->next_event, tick_period);
for (;;) {
- ktime_t next = ktime_add(dev->next_event, tick_period);
-
if (!clockevents_program_event(dev, next, ktime_get()))
return;
tick_periodic(cpu);
+ next = ktime_add(next, tick_period);
}
}
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 512a4a90646..51556b95f60 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -21,6 +21,8 @@
#include <linux/sched.h>
#include <linux/tick.h>
+#include <asm/irq_regs.h>
+
#include "tick-internal.h"
/*