diff options
| author | David S. Miller <davem@davemloft.net> | 2010-03-22 20:05:26 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-03-22 20:05:26 -0700 | 
| commit | 91c030b4d6445ebe9fbddb86d584441f300df15c (patch) | |
| tree | e8a48e3ad9e0448c690268175e555fa651983546 /drivers/sh/intc.c | |
| parent | 7c3456fdb503071787f7f972de1069b9cacd16f0 (diff) | |
| parent | ae6be51ed01d6c4aaf249a207b4434bc7785853b (diff) | |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'drivers/sh/intc.c')
| -rw-r--r-- | drivers/sh/intc.c | 31 | 
1 files changed, 30 insertions, 1 deletions
| diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index c2750391fd34..a3d8677af6a5 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -2,7 +2,7 @@   * Shared interrupt handling code for IPR and INTC2 types of IRQs.   *   * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009 Paul Mundt + * Copyright (C) 2009, 2010 Paul Mundt   *   * Based on intc2.c and ipr.c   * @@ -26,6 +26,7 @@  #include <linux/list.h>  #include <linux/topology.h>  #include <linux/bitmap.h> +#include <linux/cpumask.h>  #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \  	((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ @@ -234,6 +235,10 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle)  	unsigned int cpu;  	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { +#ifdef CONFIG_SMP +		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) +			continue; +#endif  		addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);  		intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\  						    [_INTC_FN(handle)], irq); @@ -253,6 +258,10 @@ static void intc_disable(unsigned int irq)  	unsigned int cpu;  	for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { +#ifdef CONFIG_SMP +		if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) +			continue; +#endif  		addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);  		intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\  						     [_INTC_FN(handle)], irq); @@ -301,6 +310,23 @@ static int intc_set_wake(unsigned int irq, unsigned int on)  	return 0; /* allow wakeup, but setup hardware in intc_suspend() */  } +#ifdef CONFIG_SMP +/* + * This is held with the irq desc lock held, so we don't require any + * additional locking here at the intc desc level. The affinity mask is + * later tested in the enable/disable paths. + */ +static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask) +{ +	if (!cpumask_intersects(cpumask, cpu_online_mask)) +		return -1; + +	cpumask_copy(irq_to_desc(irq)->affinity, cpumask); + +	return 0; +} +#endif +  static void intc_mask_ack(unsigned int irq)  {  	struct intc_desc_int *d = get_intc_desc(irq); @@ -847,6 +873,9 @@ void __init register_intc_controller(struct intc_desc *desc)  	d->chip.shutdown = intc_disable;  	d->chip.set_type = intc_set_sense;  	d->chip.set_wake = intc_set_wake; +#ifdef CONFIG_SMP +	d->chip.set_affinity = intc_set_affinity; +#endif  	if (hw->ack_regs) {  		for (i = 0; i < hw->nr_ack_regs; i++) | 
