powerpc/mpic: Properly set default triggers
This gets rid of the unused default senses array, and replaces the incorrect use of IRQ_TYPE_NONE with the new IRQ_TYPE_DEFAULT for the initial set_trigger() call when mapping an interrupt. This in turn makes us read the HW state and update the irq desc accordingly. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
@@ -275,9 +275,6 @@ struct mpic
|
|||||||
unsigned int isu_mask;
|
unsigned int isu_mask;
|
||||||
/* Number of sources */
|
/* Number of sources */
|
||||||
unsigned int num_sources;
|
unsigned int num_sources;
|
||||||
/* default senses array */
|
|
||||||
unsigned char *senses;
|
|
||||||
unsigned int senses_count;
|
|
||||||
|
|
||||||
/* vector numbers used for internal sources (ipi/timers) */
|
/* vector numbers used for internal sources (ipi/timers) */
|
||||||
unsigned int ipi_vecs[4];
|
unsigned int ipi_vecs[4];
|
||||||
@@ -415,21 +412,6 @@ extern struct mpic *mpic_alloc(struct device_node *node,
|
|||||||
extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
|
extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
|
||||||
phys_addr_t phys_addr);
|
phys_addr_t phys_addr);
|
||||||
|
|
||||||
/* Set default sense codes
|
|
||||||
*
|
|
||||||
* @mpic: controller
|
|
||||||
* @senses: array of sense codes
|
|
||||||
* @count: size of above array
|
|
||||||
*
|
|
||||||
* Optionally provide an array (indexed on hardware interrupt numbers
|
|
||||||
* for this MPIC) of default sense codes for the chip. Those are linux
|
|
||||||
* sense codes IRQ_TYPE_*
|
|
||||||
*
|
|
||||||
* The driver gets ownership of the pointer, don't dispose of it or
|
|
||||||
* anything like that. __init only.
|
|
||||||
*/
|
|
||||||
extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count);
|
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the controller. After this has been called, none of the above
|
/* Initialize the controller. After this has been called, none of the above
|
||||||
* should be called again for this mpic
|
* should be called again for this mpic
|
||||||
|
@@ -872,21 +872,45 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
|
|||||||
if (src >= mpic->num_sources)
|
if (src >= mpic->num_sources)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (flow_type == IRQ_TYPE_NONE)
|
vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
|
||||||
if (mpic->senses && src < mpic->senses_count)
|
|
||||||
flow_type = mpic->senses[src];
|
|
||||||
if (flow_type == IRQ_TYPE_NONE)
|
|
||||||
flow_type = IRQ_TYPE_LEVEL_LOW;
|
|
||||||
|
|
||||||
|
/* We don't support "none" type */
|
||||||
|
if (flow_type == IRQ_TYPE_NONE)
|
||||||
|
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);
|
irqd_set_trigger_type(d, flow_type);
|
||||||
|
|
||||||
|
/* Apply to HW */
|
||||||
if (mpic_is_ht_interrupt(mpic, src))
|
if (mpic_is_ht_interrupt(mpic, src))
|
||||||
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
|
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
|
||||||
MPIC_VECPRI_SENSE_EDGE;
|
MPIC_VECPRI_SENSE_EDGE;
|
||||||
else
|
else
|
||||||
vecpri = mpic_type_to_vecpri(mpic, flow_type);
|
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) |
|
vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
|
||||||
MPIC_INFO(VECPRI_SENSE_MASK));
|
MPIC_INFO(VECPRI_SENSE_MASK));
|
||||||
vnew |= vecpri;
|
vnew |= vecpri;
|
||||||
@@ -1022,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);
|
irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
|
||||||
|
|
||||||
/* Set default irq type */
|
/* 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
|
/* If the MPIC was reset, then all vectors have already been
|
||||||
* initialized. Otherwise, a per source lazy initialization
|
* initialized. Otherwise, a per source lazy initialization
|
||||||
@@ -1413,12 +1437,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
|
|||||||
mpic->num_sources = isu_first + mpic->isu_size;
|
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)
|
void __init mpic_init(struct mpic *mpic)
|
||||||
{
|
{
|
||||||
int i, cpu;
|
int i, cpu;
|
||||||
|
Reference in New Issue
Block a user