Commit e1342f1d authored by Russell King's avatar Russell King Committed by Russell King

Merge branch 'smp-fix'

parents 776abac8 ee348d5a
...@@ -253,9 +253,9 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) ...@@ -253,9 +253,9 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
void gic_raise_softirq(cpumask_t cpumask, unsigned int irq) void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{ {
unsigned long map = *cpus_addr(cpumask); unsigned long map = *cpus_addr(*mask);
/* this always happens on GIC0 */ /* this always happens on GIC0 */
writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
void gic_cpu_init(unsigned int gic_nr, void __iomem *base); void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(cpumask_t cpumask, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
#endif #endif
#endif #endif
...@@ -53,17 +53,12 @@ extern void smp_store_cpu_info(unsigned int cpuid); ...@@ -53,17 +53,12 @@ extern void smp_store_cpu_info(unsigned int cpuid);
/* /*
* Raise an IPI cross call on CPUs in callmap. * Raise an IPI cross call on CPUs in callmap.
*/ */
extern void smp_cross_call(cpumask_t callmap); extern void smp_cross_call(const struct cpumask *mask);
/*
* Broadcast a timer interrupt to the other CPUs.
*/
extern void smp_send_timer(void);
/* /*
* Broadcast a clock event to other CPUs. * Broadcast a clock event to other CPUs.
*/ */
extern void smp_timer_broadcast(cpumask_t mask); extern void smp_timer_broadcast(const struct cpumask *mask);
/* /*
* Boot a secondary CPU, and assign it the specified idle task. * Boot a secondary CPU, and assign it the specified idle task.
...@@ -102,7 +97,8 @@ extern int platform_cpu_kill(unsigned int cpu); ...@@ -102,7 +97,8 @@ extern int platform_cpu_kill(unsigned int cpu);
extern void platform_cpu_enable(unsigned int cpu); extern void platform_cpu_enable(unsigned int cpu);
extern void arch_send_call_function_single_ipi(int cpu); extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi(cpumask_t mask); extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
/* /*
* Local timer interrupt handling function (can be IPI'ed). * Local timer interrupt handling function (can be IPI'ed).
......
...@@ -326,14 +326,14 @@ void __init smp_prepare_boot_cpu(void) ...@@ -326,14 +326,14 @@ void __init smp_prepare_boot_cpu(void)
per_cpu(cpu_data, cpu).idle = current; per_cpu(cpu_data, cpu).idle = current;
} }
static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg)
{ {
unsigned long flags; unsigned long flags;
unsigned int cpu; unsigned int cpu;
local_irq_save(flags); local_irq_save(flags);
for_each_cpu_mask(cpu, callmap) { for_each_cpu(cpu, mask) {
struct ipi_data *ipi = &per_cpu(ipi_data, cpu); struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
spin_lock(&ipi->lock); spin_lock(&ipi->lock);
...@@ -344,19 +344,19 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) ...@@ -344,19 +344,19 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
/* /*
* Call the platform specific cross-CPU call function. * Call the platform specific cross-CPU call function.
*/ */
smp_cross_call(callmap); smp_cross_call(mask);
local_irq_restore(flags); local_irq_restore(flags);
} }
void arch_send_call_function_ipi(cpumask_t mask) void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{ {
send_ipi_message(mask, IPI_CALL_FUNC); send_ipi_message(mask, IPI_CALL_FUNC);
} }
void arch_send_call_function_single_ipi(int cpu) void arch_send_call_function_single_ipi(int cpu)
{ {
send_ipi_message(cpumask_of_cpu(cpu), IPI_CALL_FUNC_SINGLE); send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
} }
void show_ipi_list(struct seq_file *p) void show_ipi_list(struct seq_file *p)
...@@ -498,17 +498,10 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs) ...@@ -498,17 +498,10 @@ asmlinkage void __exception do_IPI(struct pt_regs *regs)
void smp_send_reschedule(int cpu) void smp_send_reschedule(int cpu)
{ {
send_ipi_message(cpumask_of_cpu(cpu), IPI_RESCHEDULE); send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
} }
void smp_send_timer(void) void smp_timer_broadcast(const struct cpumask *mask)
{
cpumask_t mask = cpu_online_map;
cpu_clear(smp_processor_id(), mask);
send_ipi_message(mask, IPI_TIMER);
}
void smp_timer_broadcast(cpumask_t mask)
{ {
send_ipi_message(mask, IPI_TIMER); send_ipi_message(mask, IPI_TIMER);
} }
...@@ -517,7 +510,7 @@ void smp_send_stop(void) ...@@ -517,7 +510,7 @@ void smp_send_stop(void)
{ {
cpumask_t mask = cpu_online_map; cpumask_t mask = cpu_online_map;
cpu_clear(smp_processor_id(), mask); cpu_clear(smp_processor_id(), mask);
send_ipi_message(mask, IPI_CPU_STOP); send_ipi_message(&mask, IPI_CPU_STOP);
} }
/* /*
...@@ -528,20 +521,17 @@ int setup_profiling_timer(unsigned int multiplier) ...@@ -528,20 +521,17 @@ int setup_profiling_timer(unsigned int multiplier)
return -EINVAL; return -EINVAL;
} }
static int static void
on_each_cpu_mask(void (*func)(void *), void *info, int wait, cpumask_t mask) on_each_cpu_mask(void (*func)(void *), void *info, int wait,
const struct cpumask *mask)
{ {
int ret = 0;
preempt_disable(); preempt_disable();
ret = smp_call_function_mask(mask, func, info, wait); smp_call_function_many(mask, func, info, wait);
if (cpu_isset(smp_processor_id(), mask)) if (cpumask_test_cpu(smp_processor_id(), mask))
func(info); func(info);
preempt_enable(); preempt_enable();
return ret;
} }
/**********************************************************************/ /**********************************************************************/
...@@ -602,20 +592,17 @@ void flush_tlb_all(void) ...@@ -602,20 +592,17 @@ void flush_tlb_all(void)
void flush_tlb_mm(struct mm_struct *mm) void flush_tlb_mm(struct mm_struct *mm)
{ {
cpumask_t mask = mm->cpu_vm_mask; on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, &mm->cpu_vm_mask);
on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mask);
} }
void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
{ {
cpumask_t mask = vma->vm_mm->cpu_vm_mask;
struct tlb_args ta; struct tlb_args ta;
ta.ta_vma = vma; ta.ta_vma = vma;
ta.ta_start = uaddr; ta.ta_start = uaddr;
on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mask); on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, &vma->vm_mm->cpu_vm_mask);
} }
void flush_tlb_kernel_page(unsigned long kaddr) void flush_tlb_kernel_page(unsigned long kaddr)
...@@ -630,14 +617,13 @@ void flush_tlb_kernel_page(unsigned long kaddr) ...@@ -630,14 +617,13 @@ void flush_tlb_kernel_page(unsigned long kaddr)
void flush_tlb_range(struct vm_area_struct *vma, void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end) unsigned long start, unsigned long end)
{ {
cpumask_t mask = vma->vm_mm->cpu_vm_mask;
struct tlb_args ta; struct tlb_args ta;
ta.ta_vma = vma; ta.ta_vma = vma;
ta.ta_start = start; ta.ta_start = start;
ta.ta_end = end; ta.ta_end = end;
on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mask); on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, &vma->vm_mm->cpu_vm_mask);
} }
void flush_tlb_kernel_range(unsigned long start, unsigned long end) void flush_tlb_kernel_range(unsigned long start, unsigned long end)
......
...@@ -750,14 +750,6 @@ void __init realview_timer_init(unsigned int timer_irq) ...@@ -750,14 +750,6 @@ void __init realview_timer_init(unsigned int timer_irq)
{ {
u32 val; u32 val;
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
/*
* The dummy clock device has to be registered before the main device
* so that the latter will broadcast the clock events
*/
local_timer_setup();
#endif
/* /*
* set clock frequency: * set clock frequency:
* REALVIEW_REFCLK is 32KHz * REALVIEW_REFCLK is 32KHz
......
...@@ -15,16 +15,9 @@ ...@@ -15,16 +15,9 @@
/* /*
* We use IRQ1 as the IPI * We use IRQ1 as the IPI
*/ */
static inline void smp_cross_call(cpumask_t callmap) static inline void smp_cross_call(const struct cpumask *mask)
{
gic_raise_softirq(callmap, 1);
}
/*
* Do nothing on MPcore.
*/
static inline void smp_cross_call_done(cpumask_t callmap)
{ {
gic_raise_softirq(mask, 1);
} }
#endif #endif
...@@ -189,8 +189,10 @@ void __cpuinit local_timer_setup(void) ...@@ -189,8 +189,10 @@ void __cpuinit local_timer_setup(void)
struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
clk->name = "dummy_timer"; clk->name = "dummy_timer";
clk->features = CLOCK_EVT_FEAT_DUMMY; clk->features = CLOCK_EVT_FEAT_ONESHOT |
clk->rating = 200; CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_DUMMY;
clk->rating = 400;
clk->mult = 1; clk->mult = 1;
clk->set_mode = dummy_timer_set_mode; clk->set_mode = dummy_timer_set_mode;
clk->broadcast = smp_timer_broadcast; clk->broadcast = smp_timer_broadcast;
......
...@@ -77,13 +77,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu) ...@@ -77,13 +77,6 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
{ {
trace_hardirqs_off(); trace_hardirqs_off();
/*
* the primary core may have used a "cross call" soft interrupt
* to get this processor out of WFI in the BootMonitor - make
* sure that we are no longer being sent this soft interrupt
*/
smp_cross_call_done(cpumask_of_cpu(cpu));
/* /*
* if any interrupts are already enabled for the primary * if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled * core (e.g. timer irq), then they will not have been enabled
...@@ -136,7 +129,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -136,7 +129,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Use smp_cross_call() for this, since there's little * Use smp_cross_call() for this, since there's little
* point duplicating the code here * point duplicating the code here
*/ */
smp_cross_call(cpumask_of_cpu(cpu)); smp_cross_call(cpumask_of(cpu));
timeout = jiffies + (1 * HZ); timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
...@@ -224,11 +217,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -224,11 +217,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (max_cpus > ncores) if (max_cpus > ncores)
max_cpus = ncores; max_cpus = ncores;
#ifdef CONFIG_LOCAL_TIMERS #if defined(CONFIG_LOCAL_TIMERS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
/* /*
* Enable the local timer for primary CPU. If the device is * Enable the local timer or broadcast device for the boot CPU.
* dummy (!CONFIG_LOCAL_TIMERS), it was already registers in
* realview_timer_init
*/ */
local_timer_setup(); local_timer_setup();
#endif #endif
......
...@@ -5,40 +5,43 @@ ...@@ -5,40 +5,43 @@
ccflags-y := -Os ccflags-y := -Os
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ # use acpi.o to put all files here into acpi.o modparam namespace
obj-y += acpi.o
acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \
dsinit.o dsinit.o
obj-y += evevent.o evregion.o evsci.o evxfevnt.o \ acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
evmisc.o evrgnini.o evxface.o evxfregn.o \ evmisc.o evrgnini.o evxface.o evxfregn.o \
evgpe.o evgpeblk.o evgpe.o evgpeblk.o
obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
obj-$(ACPI_FUTURE_USAGE) += hwtimer.o acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \
nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \
nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \
nsparse.o nspredef.o nsparse.o nspredef.o
obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ acpi-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \
psopcode.o psscope.o psutils.o psxface.o psopcode.o psscope.o psutils.o psxface.o
obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
rscalc.o rsirq.o rsmemory.o rsutils.o rscalc.o rsirq.o rsmemory.o rsutils.o
obj-$(ACPI_FUTURE_USAGE) += rsdump.o acpi-$(ACPI_FUTURE_USAGE) += rsdump.o
obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
utstate.o utmutex.o utobject.o utresrc.o utlock.o utstate.o utmutex.o utobject.o utresrc.o utlock.o
...@@ -787,7 +787,12 @@ struct acpi_bit_register_info { ...@@ -787,7 +787,12 @@ struct acpi_bit_register_info {
/* For control registers, both ignored and reserved bits must be preserved */ /* For control registers, both ignored and reserved bits must be preserved */
#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */ /*
* The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0)
* but we need to be able to write ACPI_BITREG_SCI_ENABLE directly
* as a BIOS workaround on some machines.
*/
#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */
#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */
#define ACPI_PM1_CONTROL_PRESERVED_BITS \ #define ACPI_PM1_CONTROL_PRESERVED_BITS \
(ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
......
...@@ -312,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) ...@@ -312,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
end: end:
if (result) if (result)
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
"Transitioning device [%s] to D%d\n", "Device [%s] failed to transition to D%d\n",
device->pnp.bus_id, state); device->pnp.bus_id, state);
else { else {
device->power.state = state; device->power.state = state;
......
...@@ -202,21 +202,44 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, ...@@ -202,21 +202,44 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
* Suspend / resume control * Suspend / resume control
*/ */
static int acpi_idle_suspend; static int acpi_idle_suspend;
static u32 saved_bm_rld;
static void acpi_idle_bm_rld_save(void)
{
acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
}
static void acpi_idle_bm_rld_restore(void)
{
u32 resumed_bm_rld;
acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
if (resumed_bm_rld != saved_bm_rld)
acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
}
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
{ {
if (acpi_idle_suspend == 1)
return 0;
acpi_idle_bm_rld_save();
acpi_idle_suspend = 1; acpi_idle_suspend = 1;
return 0; return 0;
} }
int acpi_processor_resume(struct acpi_device * device) int acpi_processor_resume(struct acpi_device * device)
{ {
if (acpi_idle_suspend == 0)
return 0;
acpi_idle_bm_rld_restore();
acpi_idle_suspend = 0; acpi_idle_suspend = 0;
return 0; return 0;
} }
#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
static int tsc_halts_in_c(int state) static void tsc_check_state(int state)
{ {
switch (boot_cpu_data.x86_vendor) { switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD: case X86_VENDOR_AMD:
...@@ -226,13 +249,17 @@ static int tsc_halts_in_c(int state) ...@@ -226,13 +249,17 @@ static int tsc_halts_in_c(int state)
* C/P/S0/S1 states when this bit is set. * C/P/S0/S1 states when this bit is set.
*/ */
if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
return 0; return;
/*FALL THROUGH*/ /*FALL THROUGH*/
default: default:
return state > ACPI_STATE_C1; /* TSC could halt in idle, so notify users */
if (state > ACPI_STATE_C1)
mark_tsc_unstable("TSC halts in idle");
} }
} }
#else
static void tsc_check_state(int state) { return; }
#endif #endif
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
...@@ -578,14 +605,9 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) ...@@ -578,14 +605,9 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
pr->power.timer_broadcast_on_state = INT_MAX; pr->power.timer_broadcast_on_state = INT_MAX;
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
struct acpi_processor_cx *cx = &pr->power.states[i]; struct acpi_processor_cx *cx = &pr->power.states[i];
#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(cx->type))
mark_tsc_unstable("TSC halts in idle");;
#endif
switch (cx->type) { switch (cx->type) {
case ACPI_STATE_C1: case ACPI_STATE_C1:
cx->valid = 1; cx->valid = 1;
...@@ -603,6 +625,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) ...@@ -603,6 +625,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
acpi_timer_check_state(i, pr, cx); acpi_timer_check_state(i, pr, cx);
break; break;
} }
if (cx->valid)
tsc_check_state(cx->type);
if (cx->valid) if (cx->valid)
working++; working++;
......
...@@ -45,6 +45,14 @@ ...@@ -45,6 +45,14 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT #define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_throttling"); ACPI_MODULE_NAME("processor_throttling");
/* ignore_tpc:
* 0 -> acpi processor driver doesn't ignore _TPC values
* 1 -> acpi processor driver ignores _TPC values
*/
static int ignore_tpc;
module_param(ignore_tpc, int, 0644);
MODULE_PARM_DESC(ignore_tpc, "Disable broken BIOS _TPC throttling support");
struct throttling_tstate { struct throttling_tstate {
unsigned int cpu; /* cpu nr */ unsigned int cpu; /* cpu nr */
int target_state; /* target T-state */ int target_state; /* target T-state */
...@@ -283,6 +291,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) ...@@ -283,6 +291,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
if (!pr) if (!pr)
return -EINVAL; return -EINVAL;
if (ignore_tpc)
goto end;
status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) { if (status != AE_NOT_FOUND) {
...@@ -290,6 +302,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) ...@@ -290,6 +302,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
} }
return -ENODEV; return -ENODEV;
} }
end:
pr->throttling_platform_limit = (int)tpc; pr->throttling_platform_limit = (int)tpc;
return 0; return 0;
} }
...@@ -302,6 +316,9 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) ...@@ -302,6 +316,9 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
struct acpi_processor_limit *limit; struct acpi_processor_limit *limit;
int target_state; int target_state;
if (ignore_tpc)
return 0;
result = acpi_processor_get_platform_limit(pr); result = acpi_processor_get_platform_limit(pr);
if (result) { if (result) {
/* Throttling Limit is unsupported */ /* Throttling Limit is unsupported */
...@@ -821,6 +838,14 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) ...@@ -821,6 +838,14 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
ret = acpi_read_throttling_status(pr, &value); ret = acpi_read_throttling_status(pr, &value);
if (ret >= 0) { if (ret >= 0) {
state = acpi_get_throttling_state(pr, value); state = acpi_get_throttling_state(pr, value);
if (state == -1) {
ACPI_WARNING((AE_INFO,
"Invalid throttling state, reset\n"));
state = 0;
ret = acpi_processor_set_throttling(pr, state);
if (ret)
return ret;
}
pr->throttling.state = state; pr->throttling.state = state;
} }
......
...@@ -538,6 +538,41 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) ...@@ -538,6 +538,41 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
return -EINVAL; return -EINVAL;
} }
/*
* For some buggy _BQC methods, we need to add a constant value to
* the _BQC return value to get the actual current brightness level
*/
static int bqc_offset_aml_bug_workaround;
static int __init video_set_bqc_offset(const struct dmi_system_id *d)
{
bqc_offset_aml_bug_workaround = 9;
return 0;
}
static struct dmi_system_id video_dmi_table[] __initdata = {
/*
* Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
*/
{
.callback = video_set_bqc_offset,
.ident = "Acer Aspire 5720",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
},
},
{
.callback = video_set_bqc_offset,
.ident = "Acer Aspire 5710Z",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
},
},
{}
};
static int static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level) unsigned long long *level)
...@@ -557,6 +592,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, ...@@ -557,6 +592,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
*level = device->brightness->levels[*level + 2]; *level = device->brightness->levels[*level + 2];
} }
*level += bqc_offset_aml_bug_workaround;
device->brightness->curr = *level; device->brightness->curr = *level;
return 0; return 0;
} else { } else {
...@@ -2290,6 +2326,8 @@ EXPORT_SYMBOL(acpi_video_register); ...@@ -2290,6 +2326,8 @@ EXPORT_SYMBOL(acpi_video_register);
static int __init acpi_video_init(void) static int __init acpi_video_init(void)
{ {
dmi_check_system(video_dmi_table);
if (intel_opregion_present()) if (intel_opregion_present())
return 0; return 0;
......
...@@ -84,6 +84,12 @@ config DRM_I915 ...@@ -84,6 +84,12 @@ config DRM_I915
config DRM_I915_KMS config DRM_I915_KMS
bool "Enable modesetting on intel by default" bool "Enable modesetting on intel by default"
depends on DRM_I915 depends on DRM_I915
# i915 KMS depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
select VIDEO_OUTPUT_CONTROL if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select INPUT if ACPI
select ACPI_VIDEO if ACPI
help help
Choose this option if you want kernel modesetting enabled by default, Choose this option if you want kernel modesetting enabled by default,
and you have a new enough userspace to support this. Running old and you have a new enough userspace to support this. Running old
......
...@@ -466,7 +466,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) ...@@ -466,7 +466,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
struct ide_host *host; struct ide_host *host;
unsigned int sel = 0; unsigned int sel = 0;
int ret; int ret;
hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL }; hw_regs_t hw[2], *hws[] = { &hw[0], &hw[1], NULL, NULL };
struct ide_port_info d = icside_v6_port_info; struct ide_port_info d = icside_v6_port_info;
ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
......
...@@ -614,12 +614,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, ...@@ -614,12 +614,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
if (drive->pc->c[0] == REQUEST_SENSE &&
pc->c[0] == REQUEST_SENSE) {
printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
"Two request sense in serial were issued\n");
}
if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
drive->failed_pc = pc; drive->failed_pc = pc;
......
...@@ -263,6 +263,7 @@ static const struct ich_laptop ich_laptop[] = { ...@@ -263,6 +263,7 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */
{ 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
{ 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
{ 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
/* end marker */ /* end marker */
{ 0, } { 0, }
}; };
......
...@@ -269,16 +269,16 @@ static struct key_entry asus_keymap[] = { ...@@ -269,16 +269,16 @@ static struct key_entry asus_keymap[] = {
{KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
{KE_KEY, 0x40, KEY_PREVIOUSSONG}, {KE_KEY, 0x40, KEY_PREVIOUSSONG},
{KE_KEY, 0x41, KEY_NEXTSONG}, {KE_KEY, 0x41, KEY_NEXTSONG},
{KE_KEY, 0x43, KEY_STOP}, {KE_KEY, 0x43, KEY_STOPCD},
{KE_KEY, 0x45, KEY_PLAYPAUSE}, {KE_KEY, 0x45, KEY_PLAYPAUSE},
{KE_KEY, 0x50, KEY_EMAIL}, {KE_KEY, 0x50, KEY_EMAIL},
{KE_KEY, 0x51, KEY_WWW}, {KE_KEY, 0x51, KEY_WWW},
{KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */
{KE_KEY, 0x5D, KEY_WLAN}, {KE_KEY, 0x5D, KEY_WLAN},
{KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
{KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
{KE_KEY, 0x82, KEY_CAMERA}, {KE_KEY, 0x82, KEY_CAMERA},
{KE_KEY, 0x8A, KEY_TV}, {KE_KEY, 0x8A, KEY_PROG1},
{KE_KEY, 0x95, KEY_MEDIA}, {KE_KEY, 0x95, KEY_MEDIA},
{KE_KEY, 0x99, KEY_PHONE}, {KE_KEY, 0x99, KEY_PHONE},
{KE_END, 0}, {KE_END, 0},
......
...@@ -158,6 +158,7 @@ enum { KE_KEY, KE_END }; ...@@ -158,6 +158,7 @@ enum { KE_KEY, KE_END };
static struct key_entry eeepc_keymap[] = { static struct key_entry eeepc_keymap[] = {
/* Sleep already handled via generic ACPI code */ /* Sleep already handled via generic ACPI code */
{KE_KEY, 0x10, KEY_WLAN }, {KE_KEY, 0x10, KEY_WLAN },
{KE_KEY, 0x11, KEY_WLAN },
{KE_KEY, 0x12, KEY_PROG1 }, {KE_KEY, 0x12, KEY_PROG1 },
{KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x13, KEY_MUTE },
{KE_KEY, 0x14, KEY_VOLUMEDOWN }, {KE_KEY, 0x14, KEY_VOLUMEDOWN },
...@@ -166,6 +167,8 @@ static struct key_entry eeepc_keymap[] = { ...@@ -166,6 +167,8 @@ static struct key_entry eeepc_keymap[] = {
{KE_KEY, 0x1b, KEY_ZOOM }, {KE_KEY, 0x1b, KEY_ZOOM },
{KE_KEY, 0x1c, KEY_PROG2 }, {KE_KEY, 0x1c, KEY_PROG2 },
{KE_KEY, 0x1d, KEY_PROG3 }, {KE_KEY, 0x1d, KEY_PROG3 },
{KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
{KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP },
{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
...@@ -381,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) ...@@ -381,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, char *buf)
EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV);
static struct attribute *platform_attributes[] = { static struct attribute *platform_attributes[] = {
&dev_attr_camera.attr, &dev_attr_camera.attr,
&dev_attr_cardr.attr, &dev_attr_cardr.attr,
&dev_attr_disp.attr, &dev_attr_disp.attr,
&dev_attr_cpufv.attr,
NULL NULL
}; };
...@@ -512,15 +517,21 @@ static int eeepc_hotk_check(void) ...@@ -512,15 +517,21 @@ static int eeepc_hotk_check(void)
return 0; return 0;
} }
static void notify_brn(void) static int notify_brn(void)
{ {
/* returns the *previous* brightness, or -1 */
struct backlight_device *bd = eeepc_backlight_device; struct backlight_device *bd = eeepc_backlight_device;
if (bd) if (bd) {
int old = bd->props.brightness;
bd->props.brightness = read_brightness(bd); bd->props.brightness = read_brightness(bd);
return old;
}
return -1;
} }
static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
{ {
enum rfkill_state state;
struct pci_dev *dev; struct pci_dev *dev;
struct pci_bus *bus = pci_find_bus(0, 1); struct pci_bus *bus = pci_find_bus(0, 1);
...@@ -532,7 +543,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) ...@@ -532,7 +543,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
return; return;
} }
if (get_acpi(CM_ASL_WLAN) == 1) { eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state);
if (state == RFKILL_STATE_UNBLOCKED) {
dev = pci_get_slot(bus, 0); dev = pci_get_slot(bus, 0);
if (dev) { if (dev) {
/* Device already present */ /* Device already present */
...@@ -552,23 +565,41 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) ...@@ -552,23 +565,41 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
pci_dev_put(dev); pci_dev_put(dev);
} }
} }
rfkill_force_state(ehotk->eeepc_wlan_rfkill, state);
} }
static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
{ {
static struct key_entry *key; static struct key_entry *key;
u16 count; u16 count;
int brn = -ENODEV;
if (!ehotk) if (!ehotk)
return; return;
if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
notify_brn(); brn = notify_brn();
count = ehotk->event_count[event % 128]++; count = ehotk->event_count[event % 128]++;
acpi_bus_generate_proc_event(ehotk->device, event, count); acpi_bus_generate_proc_event(ehotk->device, event, count);
acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
dev_name(&ehotk->device->dev), event, dev_name(&ehotk->device->dev), event,
count); count);
if (ehotk->inputdev) { if (ehotk->inputdev) {
if (brn != -ENODEV) {
/* brightness-change events need special
* handling for conversion to key events
*/
if (brn < 0)
brn = event;
else
brn += NOTIFY_BRN_MIN;
if (event < brn)
event = NOTIFY_BRN_MIN; /* brightness down */
else if (event > brn)
event = NOTIFY_BRN_MIN + 2; /* ... up */
else
event = NOTIFY_BRN_MIN + 1; /* ... unchanged */
}
key = eepc_get_entry_by_scancode(event); key = eepc_get_entry_by_scancode(event);
if (key) { if (key) {
switch (key->type) { switch (key->type) {
...@@ -649,6 +680,9 @@ static int eeepc_hotk_add(struct acpi_device *device) ...@@ -649,6 +680,9 @@ static int eeepc_hotk_add(struct acpi_device *device)
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
printk(EEEPC_ERR "Error installing notify handler\n"); printk(EEEPC_ERR "Error installing notify handler\n");
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
if (get_acpi(CM_ASL_WLAN) != -1) { if (get_acpi(CM_ASL_WLAN) != -1) {
ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
RFKILL_TYPE_WLAN); RFKILL_TYPE_WLAN);
...@@ -704,9 +738,6 @@ static int eeepc_hotk_add(struct acpi_device *device) ...@@ -704,9 +738,6 @@ static int eeepc_hotk_add(struct acpi_device *device)
goto bluetooth_fail; goto bluetooth_fail;
} }
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
return 0; return 0;
bluetooth_fail: bluetooth_fail:
...@@ -717,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_device *device) ...@@ -717,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_device *device)
wlan_fail: wlan_fail:
if (ehotk->eeepc_wlan_rfkill) if (ehotk->eeepc_wlan_rfkill)
rfkill_free(ehotk->eeepc_wlan_rfkill); rfkill_free(ehotk->eeepc_wlan_rfkill);
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
ehotk_fail: ehotk_fail:
kfree(ehotk); kfree(ehotk);
ehotk = NULL; ehotk = NULL;
......
...@@ -110,11 +110,9 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) ...@@ -110,11 +110,9 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */ /* acpi_unregister_gsi(pnp_irq(dev, 0)); */
ret = 0; ret = 0;
if (acpi_bus_power_manageable(handle)) { if (acpi_bus_power_manageable(handle))
ret = acpi_bus_set_power(handle, ACPI_STATE_D3); acpi_bus_set_power(handle, ACPI_STATE_D3);
if (ret) /* continue even if acpi_bus_set_power() fails */
return ret;
}
if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
ret = -ENODEV; ret = -ENODEV;
return ret; return ret;
......
...@@ -961,7 +961,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) ...@@ -961,7 +961,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
switch (trip_type) { switch (trip_type) {
case THERMAL_TRIP_CRITICAL: case THERMAL_TRIP_CRITICAL:
if (temp > trip_temp) { if (temp >= trip_temp) {
if (tz->ops->notify) if (tz->ops->notify)
ret = tz->ops->notify(tz, count, ret = tz->ops->notify(tz, count,
trip_type); trip_type);
...@@ -974,7 +974,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) ...@@ -974,7 +974,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
} }
break; break;
case THERMAL_TRIP_HOT: case THERMAL_TRIP_HOT:
if (temp > trip_temp) if (temp >= trip_temp)
if (tz->ops->notify) if (tz->ops->notify)
tz->ops->notify(tz, count, trip_type); tz->ops->notify(tz, count, trip_type);
break; break;
...@@ -986,14 +986,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) ...@@ -986,14 +986,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
cdev = instance->cdev; cdev = instance->cdev;
if (temp > trip_temp) if (temp >= trip_temp)
cdev->ops->set_cur_state(cdev, 1); cdev->ops->set_cur_state(cdev, 1);
else else
cdev->ops->set_cur_state(cdev, 0); cdev->ops->set_cur_state(cdev, 0);
} }
break; break;
case THERMAL_TRIP_PASSIVE: case THERMAL_TRIP_PASSIVE:
if (temp > trip_temp || tz->passive) if (temp >= trip_temp || tz->passive)
thermal_zone_device_passive(tz, temp, thermal_zone_device_passive(tz, temp,
trip_temp, count); trip_temp, count);
break; break;
......
...@@ -340,39 +340,44 @@ void oops_exit(void) ...@@ -340,39 +340,44 @@ void oops_exit(void)
} }
#ifdef WANT_WARN_ON_SLOWPATH #ifdef WANT_WARN_ON_SLOWPATH
void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) struct slowpath_args {
{ const char *fmt;
va_list args; va_list args;
char function[KSYM_SYMBOL_LEN]; };
unsigned long caller = (unsigned long)__builtin_return_address(0);
const char *board;
sprint_symbol(function, caller); static void warn_slowpath_common(const char *file, int line, void *caller, struct slowpath_args *args)
{
const char *board;
printk(KERN_WARNING "------------[ cut here ]------------\n"); printk(KERN_WARNING "------------[ cut here ]------------\n");
printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, printk(KERN_WARNING "WARNING: at %s:%d %pS()\n", file, line, caller);
line, function);
board = dmi_get_system_info(DMI_PRODUCT_NAME); board = dmi_get_system_info(DMI_PRODUCT_NAME);
if (board) if (board)
printk(KERN_WARNING "Hardware name: %s\n", board); printk(KERN_WARNING "Hardware name: %s\n", board);
if (*fmt) { if (args)
va_start(args, fmt); vprintk(args->fmt, args->args);
vprintk(fmt, args);
va_end(args);
}
print_modules(); print_modules();
dump_stack(); dump_stack();
print_oops_end_marker(); print_oops_end_marker();
add_taint(TAINT_WARN); add_taint(TAINT_WARN);
} }
void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
{
struct slowpath_args args;
args.fmt = fmt;
va_start(args.args, fmt);
warn_slowpath_common(file, line, __builtin_return_address(0), &args);
va_end(args.args);
}
EXPORT_SYMBOL(warn_slowpath_fmt); EXPORT_SYMBOL(warn_slowpath_fmt);
void warn_slowpath_null(const char *file, int line) void warn_slowpath_null(const char *file, int line)
{ {
static const char *empty = ""; warn_slowpath_common(file, line, __builtin_return_address(0), NULL);
warn_slowpath_fmt(file, line, empty);
} }
EXPORT_SYMBOL(warn_slowpath_null); EXPORT_SYMBOL(warn_slowpath_null);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment