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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 3fca40c7
...@@ -275,9 +275,6 @@ struct mpic ...@@ -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, ...@@ -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) ...@@ -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;
vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
/* We don't support "none" type */
if (flow_type == IRQ_TYPE_NONE) if (flow_type == IRQ_TYPE_NONE)
if (mpic->senses && src < mpic->senses_count) flow_type = IRQ_TYPE_DEFAULT;
flow_type = mpic->senses[src];
if (flow_type == IRQ_TYPE_NONE) /* Default: read HW settings */
flow_type = IRQ_TYPE_LEVEL_LOW; 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, ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment