diff options
Diffstat (limited to 'arch/powerpc/sysdev')
| -rw-r--r-- | arch/powerpc/sysdev/cpm2_pic.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mpc8xx_pic.c | 61 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mpic.c | 54 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mpic_msgr.c | 12 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe.c | 22 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/scom.c | 1 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/xics/xics-common.c | 7 | 
7 files changed, 85 insertions, 75 deletions
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index d3be961e2ae..10386b676d8 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -51,8 +51,7 @@  static intctl_cpm2_t __iomem *cpm2_intctl;  static struct irq_domain *cpm2_pic_host; -#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */  static const u_char irq_to_siureg[] = {  	1, 1, 1, 1, 1, 1, 1, 1, diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c index d5f5416be31..b724622c3a0 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/sysdev/mpc8xx_pic.c @@ -18,69 +18,45 @@  extern int cpm_get_irq(struct pt_regs *regs);  static struct irq_domain *mpc8xx_pic_host; -#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long mpc8xx_cached_irq_mask;  static sysconf8xx_t __iomem *siu_reg; -int cpm_get_irq(struct pt_regs *regs); +static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) +{ +	return 0x80000000 >> irqd_to_hwirq(d); +}  static void mpc8xx_unmask_irq(struct irq_data *d)  { -	int	bit, word; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	word = irq_nr >> 5; - -	ppc_cached_irq_mask[word] |= (1 << (31-bit)); -	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); +	mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); +	out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);  }  static void mpc8xx_mask_irq(struct irq_data *d)  { -	int	bit, word; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	word = irq_nr >> 5; - -	ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); -	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); +	mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); +	out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);  }  static void mpc8xx_ack(struct irq_data *d)  { -	int	bit; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); +	out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d));  }  static void mpc8xx_end_irq(struct irq_data *d)  { -	int bit, word; -	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - -	bit = irq_nr & 0x1f; -	word = irq_nr >> 5; - -	ppc_cached_irq_mask[word] |= (1 << (31-bit)); -	out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); +	mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); +	out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);  }  static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)  { -	if (flow_type & IRQ_TYPE_EDGE_FALLING) { -		irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); +	/* only external IRQ senses are programmable */ +	if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) {  		unsigned int siel = in_be32(&siu_reg->sc_siel); - -		/* only external IRQ senses are programmable */ -		if ((hw & 1) == 0) { -			siel |= (0x80000000 >> hw); -			out_be32(&siu_reg->sc_siel, siel); -			__irq_set_handler_locked(d->irq, handle_edge_irq); -		} +		siel |= mpc8xx_irqd_to_bit(d); +		out_be32(&siu_reg->sc_siel, siel); +		__irq_set_handler_locked(d->irq, handle_edge_irq);  	}  	return 0;  } @@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,  		IRQ_TYPE_EDGE_FALLING,  	}; +	if (intspec[0] > 0x1f) +		return 0; +  	*out_hwirq = intspec[0];  	if (intsize > 1 && intspec[1] < 4)  		*out_flags = map_pic_senses[intspec[1]]; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9ac71ebd2c4..395af134774 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -604,18 +604,14 @@ static struct mpic *mpic_find(unsigned int irq)  }  /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src)  { -	unsigned int src = virq_to_hw(irq); -  	return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);  }  /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src)  { -	unsigned int src = virq_to_hw(irq); -  	return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);  } @@ -876,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)  	if (src >= mpic->num_sources)  		return -EINVAL; +	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); + +	/* We don't support "none" type */  	if (flow_type == IRQ_TYPE_NONE) -		if (mpic->senses && src < mpic->senses_count) -			flow_type = mpic->senses[src]; -	if (flow_type == IRQ_TYPE_NONE) -		flow_type = IRQ_TYPE_LEVEL_LOW; +		flow_type = IRQ_TYPE_DEFAULT; + +	/* Default: read HW settings */ +	if (flow_type == IRQ_TYPE_DEFAULT) { +		switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) | +			       MPIC_INFO(VECPRI_SENSE_MASK))) { +			case MPIC_INFO(VECPRI_SENSE_EDGE) | +			     MPIC_INFO(VECPRI_POLARITY_POSITIVE): +				flow_type = IRQ_TYPE_EDGE_RISING; +				break; +			case MPIC_INFO(VECPRI_SENSE_EDGE) | +			     MPIC_INFO(VECPRI_POLARITY_NEGATIVE): +				flow_type = IRQ_TYPE_EDGE_FALLING; +				break; +			case MPIC_INFO(VECPRI_SENSE_LEVEL) | +			     MPIC_INFO(VECPRI_POLARITY_POSITIVE): +				flow_type = IRQ_TYPE_LEVEL_HIGH; +				break; +			case MPIC_INFO(VECPRI_SENSE_LEVEL) | +			     MPIC_INFO(VECPRI_POLARITY_NEGATIVE): +				flow_type = IRQ_TYPE_LEVEL_LOW; +				break; +		} +	} +	/* Apply to irq desc */  	irqd_set_trigger_type(d, flow_type); +	/* Apply to HW */  	if (mpic_is_ht_interrupt(mpic, src))  		vecpri = MPIC_VECPRI_POLARITY_POSITIVE |  			MPIC_VECPRI_SENSE_EDGE;  	else  		vecpri = mpic_type_to_vecpri(mpic, flow_type); -	vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));  	vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |  			MPIC_INFO(VECPRI_SENSE_MASK));  	vnew |= vecpri; @@ -1026,7 +1046,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,  	irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);  	/* Set default irq type */ -	irq_set_irq_type(virq, IRQ_TYPE_NONE); +	irq_set_irq_type(virq, IRQ_TYPE_DEFAULT);  	/* If the MPIC was reset, then all vectors have already been  	 * initialized.  Otherwise, a per source lazy initialization @@ -1417,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,  		mpic->num_sources = isu_first + mpic->isu_size;  } -void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count) -{ -	mpic->senses = senses; -	mpic->senses_count = count; -} -  void __init mpic_init(struct mpic *mpic)  {  	int i, cpu; @@ -1555,12 +1569,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)  		return;  	raw_spin_lock_irqsave(&mpic_lock, flags); -	if (mpic_is_ipi(mpic, irq)) { +	if (mpic_is_ipi(mpic, src)) {  		reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &  			~MPIC_VECPRI_PRIORITY_MASK;  		mpic_ipi_write(src - mpic->ipi_vecs[0],  			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); -	} else if (mpic_is_tm(mpic, irq)) { +	} else if (mpic_is_tm(mpic, src)) {  		reg = mpic_tm_read(src - mpic->timer_vecs[0]) &  			~MPIC_VECPRI_PRIORITY_MASK;  		mpic_tm_write(src - mpic->timer_vecs[0], diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 6e7fa386e76..483d8fa72e8 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -27,6 +27,7 @@  static struct mpic_msgr **mpic_msgrs;  static unsigned int mpic_msgr_count; +static DEFINE_RAW_SPINLOCK(msgrs_lock);  static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value)  { @@ -56,12 +57,11 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num)  	if (reg_num >= mpic_msgr_count)  		return ERR_PTR(-ENODEV); -	raw_spin_lock_irqsave(&msgr->lock, flags); -	if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) { -		msgr = mpic_msgrs[reg_num]; +	raw_spin_lock_irqsave(&msgrs_lock, flags); +	msgr = mpic_msgrs[reg_num]; +	if (msgr->in_use == MSGR_FREE)  		msgr->in_use = MSGR_INUSE; -	} -	raw_spin_unlock_irqrestore(&msgr->lock, flags); +	raw_spin_unlock_irqrestore(&msgrs_lock, flags);  	return msgr;  } @@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev)  		reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i;  		msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE; -		msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET; +		msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET);  		msgr->in_use = MSGR_FREE;  		msgr->num = i;  		raw_spin_lock_init(&msgr->lock); diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index ceb09cbd232..818e763f826 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -1,5 +1,5 @@  /* - * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006-2010 Freescale Semicondutor, Inc. All rights reserved.   *   * Authors: 	Shlomi Gridish <gridish@freescale.com>   * 		Li Yang <leoli@freescale.com> @@ -266,7 +266,19 @@ EXPORT_SYMBOL(qe_clock_source);  static void qe_snums_init(void)  {  	int i; -	static const u8 snum_init[] = { +	static const u8 snum_init_76[] = { +		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, +		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, +		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, +		0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D, +		0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D, +		0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D, +		0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, +		0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD, +		0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, +		0xF4, 0xF5, 0xFC, 0xFD, +	}; +	static const u8 snum_init_46[] = {  		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,  		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,  		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, @@ -274,9 +286,15 @@ static void qe_snums_init(void)  		0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,  		0x68, 0x69, 0x78, 0x79, 0x80, 0x81,  	}; +	static const u8 *snum_init;  	qe_num_of_snum = qe_get_num_of_snums(); +	if (qe_num_of_snum == 76) +		snum_init = snum_init_76; +	else +		snum_init = snum_init_46; +  	for (i = 0; i < qe_num_of_snum; i++) {  		snums[i].num = snum_init[i];  		snums[i].state = QE_SNUM_STATE_FREE; diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c index 49a3ece1c6b..702256a1ca1 100644 --- a/arch/powerpc/sysdev/scom.c +++ b/arch/powerpc/sysdev/scom.c @@ -22,6 +22,7 @@  #include <linux/debugfs.h>  #include <linux/slab.h>  #include <linux/export.h> +#include <asm/debug.h>  #include <asm/prom.h>  #include <asm/scom.h> diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index ea5e204e345..cd1d18db92c 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void)  {  	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();  	unsigned int irq, virq; +	struct irq_desc *desc;  	/* If we used to be the default server, move to the new "boot_cpuid" */  	if (hw_cpu == xics_default_server) @@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void)  	/* Allow IPIs again... */  	icp_ops->set_priority(DEFAULT_PRIORITY); -	for_each_irq(virq) { -		struct irq_desc *desc; +	for_each_irq_desc(virq, desc) {  		struct irq_chip *chip;  		long server;  		unsigned long flags; @@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void)  		/* We can't set affinity on ISA interrupts */  		if (virq < NUM_ISA_INTERRUPTS)  			continue; -		desc = irq_to_desc(virq);  		/* We only need to migrate enabled IRQS */ -		if (!desc || !desc->action) +		if (!desc->action)  			continue;  		if (desc->irq_data.domain != xics_host)  			continue;  |