diff options
| author | David S. Miller <davem@davemloft.net> | 2010-04-06 23:53:30 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-04-06 23:53:30 -0700 | 
| commit | 4a35ecf8bf1c4b039503fa554100fe85c761de76 (patch) | |
| tree | 9b75f5d5636004d9a9aa496924377379be09aa1f /arch/blackfin/mach-common/ints-priority.c | |
| parent | b4d562e3c3553ac58c7120555c4e4aefbb090a2a (diff) | |
| parent | fb9e2d887243499b8d28efcf80821c4f6a092395 (diff) | |
| download | olio-linux-3.10-4a35ecf8bf1c4b039503fa554100fe85c761de76.tar.xz olio-linux-3.10-4a35ecf8bf1c4b039503fa554100fe85c761de76.zip  | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
	drivers/net/bonding/bond_main.c
	drivers/net/via-velocity.c
	drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'arch/blackfin/mach-common/ints-priority.c')
| -rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 208 | 
1 files changed, 184 insertions, 24 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 1873b2c1fed..7ad8878bfa1 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -28,6 +28,7 @@  #include <asm/dpmc.h>  #include <asm/bfin5xx_spi.h>  #include <asm/bfin_sport.h> +#include <asm/bfin_can.h>  #define SIC_SYSIRQ(irq)	(irq - (IRQ_CORETMR + 1)) @@ -172,7 +173,12 @@ static void bfin_internal_mask_irq(unsigned int irq)  	local_irq_restore_hw(flags);  } +#ifdef CONFIG_SMP +static void bfin_internal_unmask_irq_affinity(unsigned int irq, +		const struct cpumask *affinity) +#else  static void bfin_internal_unmask_irq(unsigned int irq) +#endif  {  	unsigned long flags; @@ -185,16 +191,38 @@ static void bfin_internal_unmask_irq(unsigned int irq)  	local_irq_save_hw(flags);  	mask_bank = SIC_SYSIRQ(irq) / 32;  	mask_bit = SIC_SYSIRQ(irq) % 32; -	bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | -			     (1 << mask_bit));  #ifdef CONFIG_SMP -	bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) | -			     (1 << mask_bit)); +	if (cpumask_test_cpu(0, affinity)) +#endif +		bfin_write_SIC_IMASK(mask_bank, +			bfin_read_SIC_IMASK(mask_bank) | +			(1 << mask_bit)); +#ifdef CONFIG_SMP +	if (cpumask_test_cpu(1, affinity)) +		bfin_write_SICB_IMASK(mask_bank, +			bfin_read_SICB_IMASK(mask_bank) | +			(1 << mask_bit));  #endif  #endif  	local_irq_restore_hw(flags);  } +#ifdef CONFIG_SMP +static void bfin_internal_unmask_irq(unsigned int irq) +{ +	struct irq_desc *desc = irq_to_desc(irq); +	bfin_internal_unmask_irq_affinity(irq, desc->affinity); +} + +static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask) +{ +	bfin_internal_mask_irq(irq); +	bfin_internal_unmask_irq_affinity(irq, mask); + +	return 0; +} +#endif +  #ifdef CONFIG_PM  int bfin_internal_set_wake(unsigned int irq, unsigned int state)  { @@ -224,11 +252,6 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)  	wakeup |= USBWE;  	break;  #endif -#ifdef IRQ_KEY -	case IRQ_KEY: -	wakeup |= KPADWE; -	break; -#endif  #ifdef CONFIG_BF54x  	case IRQ_CNT:  	wakeup |= ROTWE; @@ -270,6 +293,9 @@ static struct irq_chip bfin_internal_irqchip = {  	.mask_ack = bfin_internal_mask_irq,  	.disable = bfin_internal_mask_irq,  	.enable = bfin_internal_unmask_irq, +#ifdef CONFIG_SMP +	.set_affinity = bfin_internal_set_affinity, +#endif  #ifdef CONFIG_PM  	.set_wake = bfin_internal_set_wake,  #endif @@ -294,7 +320,6 @@ static int error_int_mask;  static void bfin_generic_error_mask_irq(unsigned int irq)  {  	error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); -  	if (!error_int_mask)  		bfin_internal_mask_irq(IRQ_GENERIC_ERROR);  } @@ -385,6 +410,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,  }  #endif				/* BF537_GENERIC_ERROR_INT_DEMUX */ +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static int mac_stat_int_mask; + +static void bfin_mac_status_ack_irq(unsigned int irq) +{ +	switch (irq) { +	case IRQ_MAC_MMCINT: +		bfin_write_EMAC_MMC_TIRQS( +			bfin_read_EMAC_MMC_TIRQE() & +			bfin_read_EMAC_MMC_TIRQS()); +		bfin_write_EMAC_MMC_RIRQS( +			bfin_read_EMAC_MMC_RIRQE() & +			bfin_read_EMAC_MMC_RIRQS()); +		break; +	case IRQ_MAC_RXFSINT: +		bfin_write_EMAC_RX_STKY( +			bfin_read_EMAC_RX_IRQE() & +			bfin_read_EMAC_RX_STKY()); +		break; +	case IRQ_MAC_TXFSINT: +		bfin_write_EMAC_TX_STKY( +			bfin_read_EMAC_TX_IRQE() & +			bfin_read_EMAC_TX_STKY()); +		break; +	case IRQ_MAC_WAKEDET: +		 bfin_write_EMAC_WKUP_CTL( +			bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS); +		break; +	default: +		/* These bits are W1C */ +		bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT)); +		break; +	} +} + +static void bfin_mac_status_mask_irq(unsigned int irq) +{ +	mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT)); +#ifdef BF537_GENERIC_ERROR_INT_DEMUX +	switch (irq) { +	case IRQ_MAC_PHYINT: +		bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE); +		break; +	default: +		break; +	} +#else +	if (!mac_stat_int_mask) +		bfin_internal_mask_irq(IRQ_MAC_ERROR); +#endif +	bfin_mac_status_ack_irq(irq); +} + +static void bfin_mac_status_unmask_irq(unsigned int irq) +{ +#ifdef BF537_GENERIC_ERROR_INT_DEMUX +	switch (irq) { +	case IRQ_MAC_PHYINT: +		bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE); +		break; +	default: +		break; +	} +#else +	if (!mac_stat_int_mask) +		bfin_internal_unmask_irq(IRQ_MAC_ERROR); +#endif +	mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT); +} + +#ifdef CONFIG_PM +int bfin_mac_status_set_wake(unsigned int irq, unsigned int state) +{ +#ifdef BF537_GENERIC_ERROR_INT_DEMUX +	return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state); +#else +	return bfin_internal_set_wake(IRQ_MAC_ERROR, state); +#endif +} +#endif + +static struct irq_chip bfin_mac_status_irqchip = { +	.name = "MACST", +	.ack = bfin_ack_noop, +	.mask_ack = bfin_mac_status_mask_irq, +	.mask = bfin_mac_status_mask_irq, +	.unmask = bfin_mac_status_unmask_irq, +#ifdef CONFIG_PM +	.set_wake = bfin_mac_status_set_wake, +#endif +}; + +static void bfin_demux_mac_status_irq(unsigned int int_err_irq, +				 struct irq_desc *inta_desc) +{ +	int i, irq = 0; +	u32 status = bfin_read_EMAC_SYSTAT(); + +	for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++) +		if (status & (1L << i)) { +			irq = IRQ_MAC_PHYINT + i; +			break; +		} + +	if (irq) { +		if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) { +			bfin_handle_irq(irq); +		} else { +			bfin_mac_status_ack_irq(irq); +			pr_debug("IRQ %d:" +				 " MASKED MAC ERROR INTERRUPT ASSERTED\n", +				 irq); +		} +	} else +		printk(KERN_ERR +		       "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" +		       " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", +		       __func__, __FILE__, __LINE__); +} +#endif +  static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)  {  #ifdef CONFIG_IPIPE @@ -1031,7 +1177,6 @@ int __init init_arch_irq(void)  #elif defined(CONFIG_BF538) || defined(CONFIG_BF539)  		case IRQ_PORTF_INTA:  #endif -  			set_irq_chained_handler(irq,  						bfin_demux_gpio_irq);  			break; @@ -1040,29 +1185,36 @@ int __init init_arch_irq(void)  			set_irq_chained_handler(irq, bfin_demux_error_irq);  			break;  #endif - -#ifdef CONFIG_SMP -#ifdef CONFIG_TICKSOURCE_GPTMR0 -		case IRQ_TIMER0: -#endif -#ifdef CONFIG_TICKSOURCE_CORETMR -		case IRQ_CORETMR: +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +		case IRQ_MAC_ERROR: +			set_irq_chained_handler(irq, bfin_demux_mac_status_irq); +			break;  #endif +#ifdef CONFIG_SMP  		case IRQ_SUPPLE_0:  		case IRQ_SUPPLE_1:  			set_irq_handler(irq, handle_percpu_irq);  			break;  #endif -#ifdef CONFIG_IPIPE -#ifndef CONFIG_TICKSOURCE_CORETMR -		case IRQ_TIMER0: +#ifdef CONFIG_TICKSOURCE_CORETMR +		case IRQ_CORETMR: +# ifdef CONFIG_SMP +			set_irq_handler(irq, handle_percpu_irq); +			break; +# else  			set_irq_handler(irq, handle_simple_irq);  			break; +# endif  #endif -		case IRQ_CORETMR: + +#ifdef CONFIG_TICKSOURCE_GPTMR0 +		case IRQ_TIMER0:  			set_irq_handler(irq, handle_simple_irq);  			break; +#endif + +#ifdef CONFIG_IPIPE  		default:  			set_irq_handler(irq, handle_level_irq);  			break; @@ -1078,14 +1230,22 @@ int __init init_arch_irq(void)  	for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)  		set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,  					 handle_level_irq); +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +	set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); +#endif  #endif +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +	for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) +		set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip, +					 handle_level_irq); +#endif  	/* if configured as edge, then will be changed to do_edge_IRQ */ -	for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) +	for (irq = GPIO_IRQ_BASE; +		irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)  		set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,  					 handle_level_irq); -  	bfin_write_IMASK(0);  	CSYNC();  	ilat = bfin_read_ILAT();  |