You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc/4xx: Adding PCIe MSI support powerpc: Fix irq_free_virt by adjusting bounds before loop powerpc/irq: Protect irq_radix_revmap_lookup against irq_free_virt powerpc/irq: Check desc in handle_one_irq and expand generic_handle_irq powerpc/irq: Always free duplicate IRQ_LEGACY hosts powerpc/irq: Remove stale and misleading comment powerpc/cell: Rename ipi functions to match current abstractions powerpc/cell: Use common smp ipi actions Remove unused MSG_ flags in linux/smp.h powerpc/pseries: Update MAX_HCALL_OPCODE to reflect page coalescing powerpc/oprofile: Handle events that raise an exception without overflowing powerpc/ftrace: Implement raw syscall tracepoints on PowerPC
This commit is contained in:
@@ -141,6 +141,7 @@ config PPC
|
||||
select GENERIC_IRQ_SHOW
|
||||
select GENERIC_IRQ_SHOW_LEVEL
|
||||
select HAVE_RCU_TABLE_FREE if SMP
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
|
||||
config EARLY_PRINTK
|
||||
bool
|
||||
|
||||
@@ -530,5 +530,23 @@
|
||||
0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */
|
||||
0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>;
|
||||
};
|
||||
|
||||
MSI: ppc4xx-msi@C10000000 {
|
||||
compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
|
||||
reg = < 0xC 0x10000000 0x100>;
|
||||
sdr-base = <0x36C>;
|
||||
msi-data = <0x00000000>;
|
||||
msi-mask = <0x44440000>;
|
||||
interrupt-count = <3>;
|
||||
interrupts = <0 1 2 3>;
|
||||
interrupt-parent = <&UIC3>;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
interrupt-map = <0 &UIC3 0x18 1
|
||||
1 &UIC3 0x19 1
|
||||
2 &UIC3 0x1A 1
|
||||
3 &UIC3 0x1B 1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -442,6 +442,24 @@
|
||||
0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
|
||||
};
|
||||
|
||||
MSI: ppc4xx-msi@400300000 {
|
||||
compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
|
||||
reg = < 0x4 0x00300000 0x100>;
|
||||
sdr-base = <0x3B0>;
|
||||
msi-data = <0x00000000>;
|
||||
msi-mask = <0x44440000>;
|
||||
interrupt-count = <3>;
|
||||
interrupts =<0 1 2 3>;
|
||||
interrupt-parent = <&UIC0>;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
interrupt-map = <0 &UIC0 0xC 1
|
||||
1 &UIC0 0x0D 1
|
||||
2 &UIC0 0x0E 1
|
||||
3 &UIC0 0x0F 1>;
|
||||
};
|
||||
|
||||
I2O: i2o@400100000 {
|
||||
compatible = "ibm,i2o-440spe";
|
||||
reg = <0x00000004 0x00100000 0x100>;
|
||||
|
||||
@@ -403,5 +403,33 @@
|
||||
0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */
|
||||
0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>;
|
||||
};
|
||||
|
||||
MSI: ppc4xx-msi@C10000000 {
|
||||
compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
|
||||
reg = < 0x0 0xEF620000 0x100>;
|
||||
sdr-base = <0x4B0>;
|
||||
msi-data = <0x00000000>;
|
||||
msi-mask = <0x44440000>;
|
||||
interrupt-count = <12>;
|
||||
interrupts = <0 1 2 3 4 5 6 7 8 9 0xA 0xB 0xC 0xD>;
|
||||
interrupt-parent = <&UIC2>;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
interrupt-map = <0 &UIC2 0x10 1
|
||||
1 &UIC2 0x11 1
|
||||
2 &UIC2 0x12 1
|
||||
2 &UIC2 0x13 1
|
||||
2 &UIC2 0x14 1
|
||||
2 &UIC2 0x15 1
|
||||
2 &UIC2 0x16 1
|
||||
2 &UIC2 0x17 1
|
||||
2 &UIC2 0x18 1
|
||||
2 &UIC2 0x19 1
|
||||
2 &UIC2 0x1A 1
|
||||
2 &UIC2 0x1B 1
|
||||
2 &UIC2 0x1C 1
|
||||
3 &UIC2 0x1D 1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -358,8 +358,28 @@
|
||||
0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
|
||||
};
|
||||
|
||||
MSI: ppc4xx-msi@400300000 {
|
||||
compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
|
||||
reg = < 0x4 0x00300000 0x100
|
||||
0x4 0x00300000 0x100>;
|
||||
sdr-base = <0x3B0>;
|
||||
msi-data = <0x00000000>;
|
||||
msi-mask = <0x44440000>;
|
||||
interrupt-count = <3>;
|
||||
interrupts =<0 1 2 3>;
|
||||
interrupt-parent = <&UIC0>;
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
interrupt-map = <0 &UIC0 0xC 1
|
||||
1 &UIC0 0x0D 1
|
||||
2 &UIC0 0x0E 1
|
||||
3 &UIC0 0x0F 1>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
chosen {
|
||||
linux,stdout-path = "/plb/opb/serial@ef600200";
|
||||
};
|
||||
|
||||
@@ -60,4 +60,18 @@ struct dyn_arch_ftrace {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__)
|
||||
#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
|
||||
static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
|
||||
{
|
||||
/*
|
||||
* Compare the symbol name with the system call name. Skip the .sys or .SyS
|
||||
* prefix from the symbol name and the sys prefix from the system call name and
|
||||
* just match the rest. This is only needed on ppc64 since symbol names on
|
||||
* 32bit do not start with a period so the generic function will work.
|
||||
*/
|
||||
return !strcmp(sym + 4, name + 3);
|
||||
}
|
||||
#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_POWERPC_FTRACE */
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
#define H_HOME_NODE_ASSOCIATIVITY 0x2EC
|
||||
#define H_BEST_ENERGY 0x2F4
|
||||
#define H_GET_MPP_X 0x314
|
||||
#define MAX_HCALL_OPCODE H_BEST_ENERGY
|
||||
#define MAX_HCALL_OPCODE H_GET_MPP_X
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
||||
@@ -191,8 +191,6 @@ extern unsigned long __secondary_hold_spinloop;
|
||||
extern unsigned long __secondary_hold_acknowledge;
|
||||
extern char __secondary_hold;
|
||||
|
||||
extern irqreturn_t debug_ipi_action(int irq, void *data);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
/* ftrace syscalls requires exporting the sys_call_table */
|
||||
#ifdef CONFIG_FTRACE_SYSCALLS
|
||||
extern const unsigned long *sys_call_table;
|
||||
#endif /* CONFIG_FTRACE_SYSCALLS */
|
||||
|
||||
static inline long syscall_get_nr(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
|
||||
@@ -110,7 +110,8 @@ static inline struct thread_info *current_thread_info(void)
|
||||
#define TIF_NOERROR 12 /* Force successful syscall return */
|
||||
#define TIF_NOTIFY_RESUME 13 /* callback before returning to user */
|
||||
#define TIF_FREEZE 14 /* Freezing for suspend */
|
||||
#define TIF_RUNLATCH 15 /* Is the runlatch enabled? */
|
||||
#define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */
|
||||
#define TIF_RUNLATCH 16 /* Is the runlatch enabled? */
|
||||
|
||||
/* as above, but as bit values */
|
||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||
@@ -127,8 +128,10 @@ static inline struct thread_info *current_thread_info(void)
|
||||
#define _TIF_NOERROR (1<<TIF_NOERROR)
|
||||
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
|
||||
#define _TIF_FREEZE (1<<TIF_FREEZE)
|
||||
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
|
||||
#define _TIF_RUNLATCH (1<<TIF_RUNLATCH)
|
||||
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
|
||||
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
|
||||
_TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
|
||||
|
||||
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
|
||||
_TIF_NOTIFY_RESUME)
|
||||
|
||||
@@ -109,6 +109,7 @@ obj-$(CONFIG_PPC_IO_WORKAROUNDS) += io-workarounds.o
|
||||
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
||||
obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
|
||||
|
||||
obj-$(CONFIG_PPC_PERF_CTRS) += perf_event.o
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/code-patching.h>
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/syscall.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
@@ -600,3 +601,10 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
||||
|
||||
#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64)
|
||||
unsigned long __init arch_syscall_addr(int nr)
|
||||
{
|
||||
return sys_call_table[nr*2];
|
||||
}
|
||||
#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 */
|
||||
|
||||
+26
-20
@@ -295,17 +295,20 @@ static inline void handle_one_irq(unsigned int irq)
|
||||
unsigned long saved_sp_limit;
|
||||
struct irq_desc *desc;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
/* Switch to the irq stack to handle this */
|
||||
curtp = current_thread_info();
|
||||
irqtp = hardirq_ctx[smp_processor_id()];
|
||||
|
||||
if (curtp == irqtp) {
|
||||
/* We're already on the irq stack, just handle it */
|
||||
generic_handle_irq(irq);
|
||||
desc->handle_irq(irq, desc);
|
||||
return;
|
||||
}
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
saved_sp_limit = current->thread.ksp_limit;
|
||||
|
||||
irqtp->task = curtp->task;
|
||||
@@ -557,15 +560,8 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
|
||||
if (revmap_type == IRQ_HOST_MAP_LEGACY) {
|
||||
if (irq_map[0].host != NULL) {
|
||||
raw_spin_unlock_irqrestore(&irq_big_lock, flags);
|
||||
/* If we are early boot, we can't free the structure,
|
||||
* too bad...
|
||||
* this will be fixed once slab is made available early
|
||||
* instead of the current cruft
|
||||
*/
|
||||
if (mem_init_done) {
|
||||
of_node_put(host->of_node);
|
||||
kfree(host);
|
||||
}
|
||||
of_node_put(host->of_node);
|
||||
kfree(host);
|
||||
return NULL;
|
||||
}
|
||||
irq_map[0].host = host;
|
||||
@@ -727,9 +723,7 @@ unsigned int irq_create_mapping(struct irq_host *host,
|
||||
}
|
||||
pr_debug("irq: -> using host @%p\n", host);
|
||||
|
||||
/* Check if mapping already exist, if it does, call
|
||||
* host->ops->map() to update the flags
|
||||
*/
|
||||
/* Check if mapping already exists */
|
||||
virq = irq_find_mapping(host, hwirq);
|
||||
if (virq != NO_IRQ) {
|
||||
pr_debug("irq: -> existing mapping on virq %d\n", virq);
|
||||
@@ -899,10 +893,13 @@ unsigned int irq_radix_revmap_lookup(struct irq_host *host,
|
||||
return irq_find_mapping(host, hwirq);
|
||||
|
||||
/*
|
||||
* No rcu_read_lock(ing) needed, the ptr returned can't go under us
|
||||
* as it's referencing an entry in the static irq_map table.
|
||||
* The ptr returned references the static global irq_map.
|
||||
* but freeing an irq can delete nodes along the path to
|
||||
* do the lookup via call_rcu.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
|
||||
rcu_read_unlock();
|
||||
|
||||
/*
|
||||
* If found in radix tree, then fine.
|
||||
@@ -1010,14 +1007,23 @@ void irq_free_virt(unsigned int virq, unsigned int count)
|
||||
WARN_ON (virq < NUM_ISA_INTERRUPTS);
|
||||
WARN_ON (count == 0 || (virq + count) > irq_virq_count);
|
||||
|
||||
if (virq < NUM_ISA_INTERRUPTS) {
|
||||
if (virq + count < NUM_ISA_INTERRUPTS)
|
||||
return;
|
||||
count =- NUM_ISA_INTERRUPTS - virq;
|
||||
virq = NUM_ISA_INTERRUPTS;
|
||||
}
|
||||
|
||||
if (count > irq_virq_count || virq > irq_virq_count - count) {
|
||||
if (virq > irq_virq_count)
|
||||
return;
|
||||
count = irq_virq_count - virq;
|
||||
}
|
||||
|
||||
raw_spin_lock_irqsave(&irq_big_lock, flags);
|
||||
for (i = virq; i < (virq + count); i++) {
|
||||
struct irq_host *host;
|
||||
|
||||
if (i < NUM_ISA_INTERRUPTS ||
|
||||
(virq + count) > irq_virq_count)
|
||||
continue;
|
||||
|
||||
host = irq_map[i].host;
|
||||
irq_map[i].hwirq = host->inval_irq;
|
||||
smp_wmb();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/audit.h>
|
||||
#include <trace/syscall.h>
|
||||
#ifdef CONFIG_PPC32
|
||||
#include <linux/module.h>
|
||||
#endif
|
||||
@@ -40,6 +41,9 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/syscalls.h>
|
||||
|
||||
/*
|
||||
* The parameter save area on the stack is used to store arguments being passed
|
||||
* to callee function and is located at fixed offset from stack pointer.
|
||||
@@ -1710,6 +1714,9 @@ long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
*/
|
||||
ret = -1L;
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->gpr[0]);
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
#ifdef CONFIG_PPC64
|
||||
if (!is_32bit_task())
|
||||
@@ -1738,6 +1745,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
|
||||
regs->result);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_exit(regs, regs->result);
|
||||
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
|
||||
@@ -129,7 +129,7 @@ static irqreturn_t call_function_single_action(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
irqreturn_t debug_ipi_action(int irq, void *data)
|
||||
static irqreturn_t debug_ipi_action(int irq, void *data)
|
||||
{
|
||||
if (crash_ipi_function_ptr) {
|
||||
crash_ipi_function_ptr(get_irq_regs());
|
||||
|
||||
@@ -261,6 +261,28 @@ static int get_kernel(unsigned long pc, unsigned long mmcra)
|
||||
return is_kernel;
|
||||
}
|
||||
|
||||
static bool pmc_overflow(unsigned long val)
|
||||
{
|
||||
if ((int)val < 0)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Events on POWER7 can roll back if a speculative event doesn't
|
||||
* eventually complete. Unfortunately in some rare cases they will
|
||||
* raise a performance monitor exception. We need to catch this to
|
||||
* ensure we reset the PMC. In all cases the PMC will be 256 or less
|
||||
* cycles from overflow.
|
||||
*
|
||||
* We only do this if the first pass fails to find any overflowing
|
||||
* PMCs because a user might set a period of less than 256 and we
|
||||
* don't want to mistakenly reset them.
|
||||
*/
|
||||
if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void power4_handle_interrupt(struct pt_regs *regs,
|
||||
struct op_counter_config *ctr)
|
||||
{
|
||||
@@ -281,7 +303,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
|
||||
|
||||
for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
|
||||
val = classic_ctr_read(i);
|
||||
if (val < 0) {
|
||||
if (pmc_overflow(val)) {
|
||||
if (oprofile_running && ctr[i].enabled) {
|
||||
oprofile_add_ext_sample(pc, regs, i, is_kernel);
|
||||
classic_ctr_write(i, reset_value[i]);
|
||||
|
||||
@@ -57,6 +57,8 @@ config KILAUEA
|
||||
select 405EX
|
||||
select PPC40x_SIMPLE
|
||||
select PPC4xx_PCI_EXPRESS
|
||||
select PCI_MSI
|
||||
select PPC4xx_MSI
|
||||
help
|
||||
This option enables support for the AMCC PPC405EX evaluation board.
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@ config KATMAI
|
||||
select 440SPe
|
||||
select PCI
|
||||
select PPC4xx_PCI_EXPRESS
|
||||
select PCI_MSI
|
||||
select PCC4xx_MSI
|
||||
help
|
||||
This option enables support for the AMCC PPC440SPe evaluation board.
|
||||
|
||||
@@ -118,6 +120,8 @@ config CANYONLANDS
|
||||
select 460EX
|
||||
select PCI
|
||||
select PPC4xx_PCI_EXPRESS
|
||||
select PCI_MSI
|
||||
select PPC4xx_MSI
|
||||
select IBM_NEW_EMAC_RGMII
|
||||
select IBM_NEW_EMAC_ZMII
|
||||
help
|
||||
@@ -144,6 +148,8 @@ config REDWOOD
|
||||
select 460SX
|
||||
select PCI
|
||||
select PPC4xx_PCI_EXPRESS
|
||||
select PCI_MSI
|
||||
select PPC4xx_MSI
|
||||
help
|
||||
This option enables support for the AMCC PPC460SX Redwood board.
|
||||
|
||||
|
||||
@@ -176,14 +176,14 @@ EXPORT_SYMBOL_GPL(iic_get_target_id);
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/* Use the highest interrupt priorities for IPI */
|
||||
static inline int iic_ipi_to_irq(int ipi)
|
||||
static inline int iic_msg_to_irq(int msg)
|
||||
{
|
||||
return IIC_IRQ_TYPE_IPI + 0xf - ipi;
|
||||
return IIC_IRQ_TYPE_IPI + 0xf - msg;
|
||||
}
|
||||
|
||||
void iic_cause_IPI(int cpu, int mesg)
|
||||
void iic_message_pass(int cpu, int msg)
|
||||
{
|
||||
out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - mesg) << 4);
|
||||
out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
|
||||
}
|
||||
|
||||
struct irq_host *iic_get_irq_host(int node)
|
||||
@@ -192,50 +192,31 @@ struct irq_host *iic_get_irq_host(int node)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iic_get_irq_host);
|
||||
|
||||
static irqreturn_t iic_ipi_action(int irq, void *dev_id)
|
||||
{
|
||||
int ipi = (int)(long)dev_id;
|
||||
|
||||
switch(ipi) {
|
||||
case PPC_MSG_CALL_FUNCTION:
|
||||
generic_smp_call_function_interrupt();
|
||||
break;
|
||||
case PPC_MSG_RESCHEDULE:
|
||||
scheduler_ipi();
|
||||
break;
|
||||
case PPC_MSG_CALL_FUNC_SINGLE:
|
||||
generic_smp_call_function_single_interrupt();
|
||||
break;
|
||||
case PPC_MSG_DEBUGGER_BREAK:
|
||||
debug_ipi_action(0, NULL);
|
||||
break;
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
static void iic_request_ipi(int ipi, const char *name)
|
||||
static void iic_request_ipi(int msg)
|
||||
{
|
||||
int virq;
|
||||
|
||||
virq = irq_create_mapping(iic_host, iic_ipi_to_irq(ipi));
|
||||
virq = irq_create_mapping(iic_host, iic_msg_to_irq(msg));
|
||||
if (virq == NO_IRQ) {
|
||||
printk(KERN_ERR
|
||||
"iic: failed to map IPI %s\n", name);
|
||||
"iic: failed to map IPI %s\n", smp_ipi_name[msg]);
|
||||
return;
|
||||
}
|
||||
if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, name,
|
||||
(void *)(long)ipi))
|
||||
printk(KERN_ERR
|
||||
"iic: failed to request IPI %s\n", name);
|
||||
|
||||
/*
|
||||
* If smp_request_message_ipi encounters an error it will notify
|
||||
* the error. If a message is not needed it will return non-zero.
|
||||
*/
|
||||
if (smp_request_message_ipi(virq, msg))
|
||||
irq_dispose_mapping(virq);
|
||||
}
|
||||
|
||||
void iic_request_IPIs(void)
|
||||
{
|
||||
iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
|
||||
iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
|
||||
iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE, "IPI-call-single");
|
||||
#ifdef CONFIG_DEBUGGER
|
||||
iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
|
||||
#endif /* CONFIG_DEBUGGER */
|
||||
iic_request_ipi(PPC_MSG_CALL_FUNCTION);
|
||||
iic_request_ipi(PPC_MSG_RESCHEDULE);
|
||||
iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE);
|
||||
iic_request_ipi(PPC_MSG_DEBUGGER_BREAK);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
@@ -75,7 +75,7 @@ enum {
|
||||
};
|
||||
|
||||
extern void iic_init_IRQ(void);
|
||||
extern void iic_cause_IPI(int cpu, int mesg);
|
||||
extern void iic_message_pass(int cpu, int msg);
|
||||
extern void iic_request_IPIs(void);
|
||||
extern void iic_setup_cpu(void);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user