W: http://acpi.sourceforge.net/
S: Supported
+ ACPI VIDEO DRIVER
+ P: Luming Yu
+ M: luming.yu@intel.com
+ L: linux-acpi@vger.kernel.org
+ W: http://acpi.sourceforge.net/
+ S: Supported
+
AD1816 SOUND DRIVER
P: Thorsten Knabe
M: Thorsten Knabe <linux@thorsten-knabe.de>
M: hskinnemoen@atmel.com
S: Supported
+ATMEL SPI DRIVER
+P: Haavard Skinnemoen
+M: hskinnemoen@atmel.com
+S: Supported
+
ATMEL WIRELESS DRIVER
P: Simon Kelley
M: simon@thekelleys.org.uk
T: git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git
S: Maintained
+AUXILIARY DISPLAY DRIVERS
+P: Miguel Ojeda Sandonis
+M: maxextreme@gmail.com
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
AVR32 ARCHITECTURE
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
L: discuss@x86-64.org
S: Maintained
+CFAG12864B LCD DRIVER
+P: Miguel Ojeda Sandonis
+M: maxextreme@gmail.com
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
+CFAG12864BFB LCD FRAMEBUFFER DRIVER
+P: Miguel Ojeda Sandonis
+M: maxextreme@gmail.com
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
COMMON INTERNET FILE SYSTEM (CIFS)
P: Steve French
M: sfrench@samba.org
S: Maintained
CYCLADES ASYNC MUX DRIVER
-M: async@cyclades.com
W: http://www.cyclades.com/
-S: Supported
+S: Orphan
CYCLADES PC300 DRIVER
-M: pc300@cyclades.com
W: http://www.cyclades.com/
-S: Supported
+S: Orphan
DAMA SLAVE for AX.25
P: Joerg Reuter
DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
P: Tobias Ringstrom
M: tori@unhappy.mine.nu
-L: linux-kernel@vger.kernel.org
+L: netdev@vger.kernel.org
S: Maintained
DOCBOOK FOR DOCUMENTATION
L: linux-kernel@vger.kernel.org
S: Maintained
+KS0108 LCD CONTROLLER DRIVER
+P: Miguel Ojeda Sandonis
+M: maxextreme@gmail.com
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
LAPB module
L: linux-x25@vger.kernel.org
S: Orphan
NETWORKING [WIRELESS]
P: John W. Linville
M: linville@tuxdriver.com
-L: netdev@vger.kernel.org
+L: linux-wireless@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained
L: netdev@vger.kernel.org
S: Maintained
+PA SEMI SMBUS DRIVER
+P: Olof Johansson
+M: olof@lixom.net
+L: i2c@lm-sensors.org
+S: Maintained
+
PARALLEL PORT SUPPORT
P: Phil Blundell
M: philb@gnu.org
L: alsa-devel@alsa-project.org
S: Maintained
+SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
+P: Liam Girdwood
+M: liam.girdwood@wolfsonmicro.com
+L: alsa-devel@alsa-project.org
+S: Supported
+
SPI SUBSYSTEM
P: David Brownell
M: dbrownell@users.sourceforge.net
W: http://vtun.sourceforge.net/tun
S: Maintained
+TURBOCHANNEL SUBSYSTEM
+P: Maciej W. Rozycki
+M: macro@linux-mips.org
+S: Maintained
+
U14-34F SCSI DRIVER
P: Dario Ballabio
M: ballabio_dario@emc.com
M: ak@suse.de
L: discuss@x86-64.org
W: http://www.x86-64.org
+T: quilt ftp://ftp.firstfloor.org/pub/ak/x86_64/quilt-current
S: Maintained
YAM DRIVER FOR AX.25
#include <linux/moduleparam.h>
#include <linux/sched.h> /* need_resched() */
#include <linux/latency.h>
+#include <linux/clockchips.h>
+
+/*
+ * Include the apic definitions for x86 to have the APIC timer related defines
+ * available also for UP (on SMP it gets magically included via linux/smp.h).
+ * asm/acpi.h is not an option, as it would require more include magic. Also
+ * creating an empty asm-ia64/apic.h would just trade pest vs. cholera.
+ */
+#ifdef CONFIG_X86
+#include <asm/apic.h>
+#endif
+ /*
+ * Include the apic definitions for x86 to have the APIC timer related defines
+ * available also for UP (on SMP it gets magically included via linux/smp.h).
+ */
+ #ifdef CONFIG_X86
+ #include <asm/apic.h>
+ #endif
+
#include <asm/io.h>
#include <asm/uaccess.h>
}
}
+#ifdef ARCH_APICTIMER_STOPS_ON_C3
+
+/*
+ * Some BIOS implementations switch to C3 in the published C2 state.
+ * This seems to be a common problem on AMD boxen, but other vendors
+ * are affected too. We pick the most conservative approach: we assume
+ * that the local APIC stops in both C2 and C3.
+ */
+static void acpi_timer_check_state(int state, struct acpi_processor *pr,
+ struct acpi_processor_cx *cx)
+{
+ struct acpi_processor_power *pwr = &pr->power;
+
+ /*
+ * Check, if one of the previous states already marked the lapic
+ * unstable
+ */
+ if (pwr->timer_broadcast_on_state < state)
+ return;
+
+ if (cx->type >= ACPI_STATE_C2)
+ pr->power.timer_broadcast_on_state = state;
+}
+
+static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
+{
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+ unsigned long reason;
+
+ reason = pr->power.timer_broadcast_on_state < INT_MAX ?
+ CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
+
+ clockevents_notify(reason, &pr->id);
+#else
+ cpumask_t mask = cpumask_of_cpu(pr->id);
+
+ if (pr->power.timer_broadcast_on_state < INT_MAX)
+ on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
+ else
+ on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
+#endif
+}
+
+/* Power(C) State timer broadcast control */
+static void acpi_state_timer_broadcast(struct acpi_processor *pr,
+ struct acpi_processor_cx *cx,
+ int broadcast)
+{
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+
+ int state = cx - pr->power.states;
+
+ if (state >= pr->power.timer_broadcast_on_state) {
+ unsigned long reason;
+
+ reason = broadcast ? CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
+ CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
+ clockevents_notify(reason, &pr->id);
+ }
+#endif
+}
+
+#else
+
+static void acpi_timer_check_state(int state, struct acpi_processor *pr,
+ struct acpi_processor_cx *cstate) { }
+static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { }
+static void acpi_state_timer_broadcast(struct acpi_processor *pr,
+ struct acpi_processor_cx *cx,
+ int broadcast)
+{
+}
+
+#endif
+
static void acpi_processor_idle(void)
{
struct acpi_processor *pr = NULL;
/* Get start time (ticks) */
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
/* Invoke C2 */
+ acpi_state_timer_broadcast(pr, cx, 1);
acpi_cstate_enter(cx);
/* Get end time (ticks) */
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
/* Compute time (ticks) that we were actually asleep */
sleep_ticks =
ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
+ acpi_state_timer_broadcast(pr, cx, 0);
break;
case ACPI_STATE_C3:
/* Get start time (ticks) */
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
/* Invoke C3 */
+ acpi_state_timer_broadcast(pr, cx, 1);
acpi_cstate_enter(cx);
/* Get end time (ticks) */
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
/* Compute time (ticks) that we were actually asleep */
sleep_ticks =
ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
+ acpi_state_timer_broadcast(pr, cx, 0);
break;
default:
unsigned int i;
unsigned int working = 0;
-#ifdef ARCH_APICTIMER_STOPS_ON_C3
- int timer_broadcast = 0;
- cpumask_t mask = cpumask_of_cpu(pr->id);
- on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
-#endif
+ pr->power.timer_broadcast_on_state = INT_MAX;
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
struct acpi_processor_cx *cx = &pr->power.states[i];
case ACPI_STATE_C2:
acpi_processor_power_verify_c2(cx);
-#ifdef ARCH_APICTIMER_STOPS_ON_C3
- /* Some AMD systems fake C3 as C2, but still
- have timer troubles */
- if (cx->valid &&
- boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
- timer_broadcast++;
-#endif
+ if (cx->valid)
+ acpi_timer_check_state(i, pr, cx);
break;
case ACPI_STATE_C3:
acpi_processor_power_verify_c3(pr, cx);
-#ifdef ARCH_APICTIMER_STOPS_ON_C3
if (cx->valid)
- timer_broadcast++;
-#endif
+ acpi_timer_check_state(i, pr, cx);
break;
}
working++;
}
-#ifdef ARCH_APICTIMER_STOPS_ON_C3
- if (timer_broadcast)
- on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
-#endif
+ acpi_propagate_timer_broadcast(pr);
return (working);
}