提交 02b2318e 编写于 作者: L Linus Torvalds

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: (26 commits)
  [SPARC64]: Fix UP build.
  [SPARC64]: dr-cpu unconfigure support.
  [SERIAL]: Fix console write locking in sparc drivers.
  [SPARC64]: Give more accurate errors in dr_cpu_configure().
  [SPARC64]: Clear cpu_{core,sibling}_map[] in smp_fill_in_sib_core_maps()
  [SPARC64]: Fix leak when DR added cpu does not bootup.
  [SPARC64]: Add ->set_affinity IRQ handlers.
  [SPARC64]: Process dr-cpu events in a kthread instead of workqueue.
  [SPARC64]: More sensible udelay implementation.
  [SPARC64]: SMP build fixes.
  [SPARC64]: mdesc.c needs linux/mm.h
  [SPARC64]: Fix build regressions added by dr-cpu changes.
  [SPARC64]: Unconditionally register vio_bus_type.
  [SPARC64]: Initial LDOM cpu hotplug support.
  [SPARC64]: Fix setting of variables in LDOM guest.
  [SPARC64]: Fix MD property lifetime bugs.
  [SPARC64]: Abstract out mdesc accesses for better MD update handling.
  [SPARC64]: Use more mearningful names for IRQ registry.
  [SPARC64]: Initial domain-services driver.
  [SPARC64]: Export powerd facilities for external entities.
  ...
...@@ -108,6 +108,15 @@ config SECCOMP ...@@ -108,6 +108,15 @@ config SECCOMP
source kernel/Kconfig.hz source kernel/Kconfig.hz
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
depends on SMP
select HOTPLUG
---help---
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
source "init/Kconfig" source "init/Kconfig"
config SYSVIPC_COMPAT config SYSVIPC_COMPAT
...@@ -305,6 +314,12 @@ config SUN_IO ...@@ -305,6 +314,12 @@ config SUN_IO
bool bool
default y default y
config SUN_LDOMS
bool "Sun Logical Domains support"
help
Say Y here is you want to support virtual devices via
Logical Domains.
config PCI config PCI
bool "PCI support" bool "PCI support"
select ARCH_SUPPORTS_MSI select ARCH_SUPPORTS_MSI
......
...@@ -18,7 +18,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o ...@@ -18,7 +18,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
pci_psycho.o pci_sabre.o pci_schizo.o \ pci_psycho.o pci_sabre.o pci_schizo.o \
pci_sun4v.o pci_sun4v_asm.o pci_fire.o pci_sun4v.o pci_sun4v_asm.o pci_fire.o
obj-$(CONFIG_SMP) += smp.o trampoline.o obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o
obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
...@@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES) += module.o ...@@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT) += audit.o
obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o
obj-y += $(obj-yy) obj-y += $(obj-yy)
......
此差异已折叠。
/* hvtramp.S: Hypervisor start-cpu trampoline code.
*
* Copyright (C) 2007 David S. Miller <davem@davemloft.net>
*/
#include <asm/thread_info.h>
#include <asm/hypervisor.h>
#include <asm/scratchpad.h>
#include <asm/spitfire.h>
#include <asm/hvtramp.h>
#include <asm/pstate.h>
#include <asm/ptrace.h>
#include <asm/asi.h>
.text
.align 8
.globl hv_cpu_startup, hv_cpu_startup_end
/* This code executes directly out of the hypervisor
* with physical addressing (va==pa). %o0 contains
* our client argument which for Linux points to
* a descriptor data structure which defines the
* MMU entries we need to load up.
*
* After we set things up we enable the MMU and call
* into the kernel.
*
* First setup basic privileged cpu state.
*/
hv_cpu_startup:
wrpr %g0, 0, %gl
wrpr %g0, 15, %pil
wrpr %g0, 0, %canrestore
wrpr %g0, 0, %otherwin
wrpr %g0, 6, %cansave
wrpr %g0, 6, %cleanwin
wrpr %g0, 0, %cwp
wrpr %g0, 0, %wstate
wrpr %g0, 0, %tl
sethi %hi(sparc64_ttable_tl0), %g1
wrpr %g1, %tba
mov %o0, %l0
lduw [%l0 + HVTRAMP_DESCR_CPU], %g1
mov SCRATCHPAD_CPUID, %g2
stxa %g1, [%g2] ASI_SCRATCHPAD
ldx [%l0 + HVTRAMP_DESCR_FAULT_INFO_VA], %g2
stxa %g2, [%g0] ASI_SCRATCHPAD
mov 0, %l1
lduw [%l0 + HVTRAMP_DESCR_NUM_MAPPINGS], %l2
add %l0, HVTRAMP_DESCR_MAPS, %l3
1: ldx [%l3 + HVTRAMP_MAPPING_VADDR], %o0
clr %o1
ldx [%l3 + HVTRAMP_MAPPING_TTE], %o2
mov HV_MMU_IMMU | HV_MMU_DMMU, %o3
mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
ta HV_FAST_TRAP
brnz,pn %o0, 80f
nop
add %l1, 1, %l1
cmp %l1, %l2
blt,a,pt %xcc, 1b
add %l3, HVTRAMP_MAPPING_SIZE, %l3
ldx [%l0 + HVTRAMP_DESCR_FAULT_INFO_PA], %o0
mov HV_FAST_MMU_FAULT_AREA_CONF, %o5
ta HV_FAST_TRAP
brnz,pn %o0, 80f
nop
wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
ldx [%l0 + HVTRAMP_DESCR_THREAD_REG], %l6
mov 1, %o0
set 1f, %o1
mov HV_FAST_MMU_ENABLE, %o5
ta HV_FAST_TRAP
ba,pt %xcc, 80f
nop
1:
wr %g0, 0, %fprs
wr %g0, ASI_P, %asi
mov PRIMARY_CONTEXT, %g7
stxa %g0, [%g7] ASI_MMU
membar #Sync
mov SECONDARY_CONTEXT, %g7
stxa %g0, [%g7] ASI_MMU
membar #Sync
mov %l6, %g6
ldx [%g6 + TI_TASK], %g4
mov 1, %g5
sllx %g5, THREAD_SHIFT, %g5
sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
add %g6, %g5, %sp
mov 0, %fp
call init_irqwork_curcpu
nop
call hard_smp_processor_id
nop
mov %o0, %o1
mov 0, %o0
mov 0, %o2
call sun4v_init_mondo_queues
mov 1, %o3
call init_cur_cpu_trap
mov %g6, %o0
wrpr %g0, (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE), %pstate
call smp_callin
nop
call cpu_idle
mov 0, %o0
call cpu_panic
nop
80: ba,pt %xcc, 80b
nop
.align 8
hv_cpu_startup_end:
...@@ -293,6 +293,11 @@ static void sun4u_irq_enable(unsigned int virt_irq) ...@@ -293,6 +293,11 @@ static void sun4u_irq_enable(unsigned int virt_irq)
} }
} }
static void sun4u_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
sun4u_irq_enable(virt_irq);
}
static void sun4u_irq_disable(unsigned int virt_irq) static void sun4u_irq_disable(unsigned int virt_irq)
{ {
struct irq_handler_data *data = get_irq_chip_data(virt_irq); struct irq_handler_data *data = get_irq_chip_data(virt_irq);
...@@ -309,6 +314,10 @@ static void sun4u_irq_disable(unsigned int virt_irq) ...@@ -309,6 +314,10 @@ static void sun4u_irq_disable(unsigned int virt_irq)
static void sun4u_irq_end(unsigned int virt_irq) static void sun4u_irq_end(unsigned int virt_irq)
{ {
struct irq_handler_data *data = get_irq_chip_data(virt_irq); struct irq_handler_data *data = get_irq_chip_data(virt_irq);
struct irq_desc *desc = irq_desc + virt_irq;
if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
return;
if (likely(data)) if (likely(data))
upa_writeq(ICLR_IDLE, data->iclr); upa_writeq(ICLR_IDLE, data->iclr);
...@@ -340,6 +349,24 @@ static void sun4v_irq_enable(unsigned int virt_irq) ...@@ -340,6 +349,24 @@ static void sun4v_irq_enable(unsigned int virt_irq)
} }
} }
static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
unsigned int ino = bucket - &ivector_table[0];
if (likely(bucket)) {
unsigned long cpuid;
int err;
cpuid = irq_choose_cpu(virt_irq);
err = sun4v_intr_settarget(ino, cpuid);
if (err != HV_EOK)
printk("sun4v_intr_settarget(%x,%lu): err(%d)\n",
ino, cpuid, err);
}
}
static void sun4v_irq_disable(unsigned int virt_irq) static void sun4v_irq_disable(unsigned int virt_irq)
{ {
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
...@@ -373,6 +400,10 @@ static void sun4v_irq_end(unsigned int virt_irq) ...@@ -373,6 +400,10 @@ static void sun4v_irq_end(unsigned int virt_irq)
{ {
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
unsigned int ino = bucket - &ivector_table[0]; unsigned int ino = bucket - &ivector_table[0];
struct irq_desc *desc = irq_desc + virt_irq;
if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
return;
if (likely(bucket)) { if (likely(bucket)) {
int err; int err;
...@@ -418,6 +449,28 @@ static void sun4v_virq_enable(unsigned int virt_irq) ...@@ -418,6 +449,28 @@ static void sun4v_virq_enable(unsigned int virt_irq)
} }
} }
static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
unsigned int ino = bucket - &ivector_table[0];
if (likely(bucket)) {
unsigned long cpuid, dev_handle, dev_ino;
int err;
cpuid = irq_choose_cpu(virt_irq);
dev_handle = ino & IMAP_IGN;
dev_ino = ino & IMAP_INO;
err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
if (err != HV_EOK)
printk("sun4v_vintr_set_target(%lx,%lx,%lu): "
"err(%d)\n",
dev_handle, dev_ino, cpuid, err);
}
}
static void sun4v_virq_disable(unsigned int virt_irq) static void sun4v_virq_disable(unsigned int virt_irq)
{ {
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
...@@ -443,6 +496,10 @@ static void sun4v_virq_end(unsigned int virt_irq) ...@@ -443,6 +496,10 @@ static void sun4v_virq_end(unsigned int virt_irq)
{ {
struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
unsigned int ino = bucket - &ivector_table[0]; unsigned int ino = bucket - &ivector_table[0];
struct irq_desc *desc = irq_desc + virt_irq;
if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
return;
if (likely(bucket)) { if (likely(bucket)) {
unsigned long dev_handle, dev_ino; unsigned long dev_handle, dev_ino;
...@@ -477,6 +534,7 @@ static struct irq_chip sun4u_irq = { ...@@ -477,6 +534,7 @@ static struct irq_chip sun4u_irq = {
.enable = sun4u_irq_enable, .enable = sun4u_irq_enable,
.disable = sun4u_irq_disable, .disable = sun4u_irq_disable,
.end = sun4u_irq_end, .end = sun4u_irq_end,
.set_affinity = sun4u_set_affinity,
}; };
static struct irq_chip sun4u_irq_ack = { static struct irq_chip sun4u_irq_ack = {
...@@ -485,6 +543,7 @@ static struct irq_chip sun4u_irq_ack = { ...@@ -485,6 +543,7 @@ static struct irq_chip sun4u_irq_ack = {
.disable = sun4u_irq_disable, .disable = sun4u_irq_disable,
.ack = run_pre_handler, .ack = run_pre_handler,
.end = sun4u_irq_end, .end = sun4u_irq_end,
.set_affinity = sun4u_set_affinity,
}; };
static struct irq_chip sun4v_irq = { static struct irq_chip sun4v_irq = {
...@@ -492,6 +551,7 @@ static struct irq_chip sun4v_irq = { ...@@ -492,6 +551,7 @@ static struct irq_chip sun4v_irq = {
.enable = sun4v_irq_enable, .enable = sun4v_irq_enable,
.disable = sun4v_irq_disable, .disable = sun4v_irq_disable,
.end = sun4v_irq_end, .end = sun4v_irq_end,
.set_affinity = sun4v_set_affinity,
}; };
static struct irq_chip sun4v_irq_ack = { static struct irq_chip sun4v_irq_ack = {
...@@ -500,6 +560,7 @@ static struct irq_chip sun4v_irq_ack = { ...@@ -500,6 +560,7 @@ static struct irq_chip sun4v_irq_ack = {
.disable = sun4v_irq_disable, .disable = sun4v_irq_disable,
.ack = run_pre_handler, .ack = run_pre_handler,
.end = sun4v_irq_end, .end = sun4v_irq_end,
.set_affinity = sun4v_set_affinity,
}; };
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
...@@ -511,6 +572,7 @@ static struct irq_chip sun4v_msi = { ...@@ -511,6 +572,7 @@ static struct irq_chip sun4v_msi = {
.disable = sun4v_msi_disable, .disable = sun4v_msi_disable,
.ack = run_pre_handler, .ack = run_pre_handler,
.end = sun4v_irq_end, .end = sun4v_irq_end,
.set_affinity = sun4v_set_affinity,
}; };
#endif #endif
...@@ -519,6 +581,7 @@ static struct irq_chip sun4v_virq = { ...@@ -519,6 +581,7 @@ static struct irq_chip sun4v_virq = {
.enable = sun4v_virq_enable, .enable = sun4v_virq_enable,
.disable = sun4v_virq_disable, .disable = sun4v_virq_disable,
.end = sun4v_virq_end, .end = sun4v_virq_end,
.set_affinity = sun4v_virt_set_affinity,
}; };
static struct irq_chip sun4v_virq_ack = { static struct irq_chip sun4v_virq_ack = {
...@@ -527,6 +590,7 @@ static struct irq_chip sun4v_virq_ack = { ...@@ -527,6 +590,7 @@ static struct irq_chip sun4v_virq_ack = {
.disable = sun4v_virq_disable, .disable = sun4v_virq_disable,
.ack = run_pre_handler, .ack = run_pre_handler,
.end = sun4v_virq_end, .end = sun4v_virq_end,
.set_affinity = sun4v_virt_set_affinity,
}; };
void irq_install_pre_handler(int virt_irq, void irq_install_pre_handler(int virt_irq,
...@@ -739,6 +803,26 @@ void handler_irq(int irq, struct pt_regs *regs) ...@@ -739,6 +803,26 @@ void handler_irq(int irq, struct pt_regs *regs)
set_irq_regs(old_regs); set_irq_regs(old_regs);
} }
#ifdef CONFIG_HOTPLUG_CPU
void fixup_irqs(void)
{
unsigned int irq;
for (irq = 0; irq < NR_IRQS; irq++) {
unsigned long flags;
spin_lock_irqsave(&irq_desc[irq].lock, flags);
if (irq_desc[irq].action &&
!(irq_desc[irq].status & IRQ_PER_CPU)) {
if (irq_desc[irq].chip->set_affinity)
irq_desc[irq].chip->set_affinity(irq,
irq_desc[irq].affinity);
}
spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
}
}
#endif
struct sun5_timer { struct sun5_timer {
u64 count0; u64 count0;
u64 limit0; u64 limit0;
......
此差异已折叠。
此差异已折叠。
/* $Id: power.c,v 1.10 2001/12/11 01:57:16 davem Exp $ /* power.c: Power management driver.
* power.c: Power management driver.
* *
* Copyright (C) 1999 David S. Miller (davem@redhat.com) * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -19,6 +18,7 @@ ...@@ -19,6 +18,7 @@
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/of_device.h> #include <asm/of_device.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/power.h>
#include <asm/sstate.h> #include <asm/sstate.h>
#include <linux/unistd.h> #include <linux/unistd.h>
...@@ -29,24 +29,26 @@ ...@@ -29,24 +29,26 @@
*/ */
int scons_pwroff = 1; int scons_pwroff = 1;
#ifdef CONFIG_PCI
#include <linux/pci.h>
static void __iomem *power_reg; static void __iomem *power_reg;
static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
static int button_pressed; static int button_pressed;
static irqreturn_t power_handler(int irq, void *dev_id) void wake_up_powerd(void)
{ {
if (button_pressed == 0) { if (button_pressed == 0) {
button_pressed = 1; button_pressed = 1;
wake_up(&powerd_wait); wake_up(&powerd_wait);
} }
}
static irqreturn_t power_handler(int irq, void *dev_id)
{
wake_up_powerd();
/* FIXME: Check registers for status... */ /* FIXME: Check registers for status... */
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#endif /* CONFIG_PCI */
extern void machine_halt(void); extern void machine_halt(void);
extern void machine_alt_power_off(void); extern void machine_alt_power_off(void);
...@@ -56,19 +58,18 @@ void machine_power_off(void) ...@@ -56,19 +58,18 @@ void machine_power_off(void)
{ {
sstate_poweroff(); sstate_poweroff();
if (!serial_console || scons_pwroff) { if (!serial_console || scons_pwroff) {
#ifdef CONFIG_PCI
if (power_reg) { if (power_reg) {
/* Both register bits seem to have the /* Both register bits seem to have the
* same effect, so until I figure out * same effect, so until I figure out
* what the difference is... * what the difference is...
*/ */
writel(AUXIO_PCIO_CPWR_OFF | AUXIO_PCIO_SPWR_OFF, power_reg); writel(AUXIO_PCIO_CPWR_OFF | AUXIO_PCIO_SPWR_OFF, power_reg);
} else } else {
#endif /* CONFIG_PCI */
if (poweroff_method != NULL) { if (poweroff_method != NULL) {
poweroff_method(); poweroff_method();
/* not reached */ /* not reached */
} }
}
} }
machine_halt(); machine_halt();
} }
...@@ -76,7 +77,6 @@ void machine_power_off(void) ...@@ -76,7 +77,6 @@ void machine_power_off(void)
void (*pm_power_off)(void) = machine_power_off; void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(pm_power_off);
#ifdef CONFIG_PCI
static int powerd(void *__unused) static int powerd(void *__unused)
{ {
static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
...@@ -86,7 +86,7 @@ static int powerd(void *__unused) ...@@ -86,7 +86,7 @@ static int powerd(void *__unused)
daemonize("powerd"); daemonize("powerd");
add_wait_queue(&powerd_wait, &wait); add_wait_queue(&powerd_wait, &wait);
again:
for (;;) { for (;;) {
set_task_state(current, TASK_INTERRUPTIBLE); set_task_state(current, TASK_INTERRUPTIBLE);
if (button_pressed) if (button_pressed)
...@@ -100,16 +100,28 @@ static int powerd(void *__unused) ...@@ -100,16 +100,28 @@ static int powerd(void *__unused)
/* Ok, down we go... */ /* Ok, down we go... */
button_pressed = 0; button_pressed = 0;
if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
printk("powerd: shutdown execution failed\n"); printk(KERN_ERR "powerd: shutdown execution failed\n");
add_wait_queue(&powerd_wait, &wait); machine_power_off();
goto again;
} }
return 0; return 0;
} }
int start_powerd(void)
{
int err;
err = kernel_thread(powerd, NULL, CLONE_FS);
if (err < 0)
printk(KERN_ERR "power: Failed to start power daemon.\n");
else
printk(KERN_INFO "power: powerd running.\n");
return err;
}
static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
{ {
if (irq == PCI_IRQ_NONE) if (irq == 0xffffffff)
return 0; return 0;
if (!of_find_property(dp, "button", NULL)) if (!of_find_property(dp, "button", NULL))
return 0; return 0;
...@@ -130,17 +142,14 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id ...@@ -130,17 +142,14 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id
poweroff_method = machine_halt; /* able to use the standard halt */ poweroff_method = machine_halt; /* able to use the standard halt */
if (has_button_interrupt(irq, op->node)) { if (has_button_interrupt(irq, op->node)) {
if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { if (start_powerd() < 0)
printk("Failed to start power daemon.\n");
return 0; return 0;
}
printk("powerd running.\n");
if (request_irq(irq, if (request_irq(irq,
power_handler, 0, "power", NULL) < 0) power_handler, 0, "power", NULL) < 0)
printk("power: Error, cannot register IRQ handler.\n"); printk(KERN_ERR "power: Cannot setup IRQ handler.\n");
} else { } else {
printk("not using powerd.\n"); printk(KERN_INFO "power: Not using powerd.\n");
} }
return 0; return 0;
...@@ -164,4 +173,3 @@ void __init power_init(void) ...@@ -164,4 +173,3 @@ void __init power_init(void)
of_register_driver(&power_driver, &of_bus_type); of_register_driver(&power_driver, &of_bus_type);
return; return;
} }
#endif /* CONFIG_PCI */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册