powerpc/xics: Rename the map handler in a check handler
This moves the IRQ initialization done under the different ICS backends in the common part of XICS. The 'map' handler becomes a simple 'check' on the HW IRQ at the FW level. As we don't need an ICS anymore in xics_migrate_irqs_away(), the XICS domain does not set a chip data for the IRQ. Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210701132750.1475580-18-clg@kaod.org
This commit is contained in:
Родитель
298f6f9528
Коммит
248af248a8
|
@ -89,10 +89,11 @@ static inline int ics_opal_init(void) { return -ENODEV; }
|
|||
/* ICS instance, hooked up to chip_data of an irq */
|
||||
struct ics {
|
||||
struct list_head link;
|
||||
int (*map)(struct ics *ics, unsigned int virq);
|
||||
int (*check)(struct ics *ics, unsigned int hwirq);
|
||||
void (*mask_unknown)(struct ics *ics, unsigned long vec);
|
||||
long (*get_server)(struct ics *ics, unsigned long vec);
|
||||
int (*host_match)(struct ics *ics, struct device_node *node);
|
||||
struct irq_chip *chip;
|
||||
char data[];
|
||||
};
|
||||
|
||||
|
|
|
@ -131,19 +131,15 @@ static struct irq_chip ics_native_irq_chip = {
|
|||
.irq_retrigger = xics_retrigger,
|
||||
};
|
||||
|
||||
static int ics_native_map(struct ics *ics, unsigned int virq)
|
||||
static int ics_native_check(struct ics *ics, unsigned int hw_irq)
|
||||
{
|
||||
unsigned int vec = (unsigned int)virq_to_hw(virq);
|
||||
struct ics_native *in = to_ics_native(ics);
|
||||
|
||||
pr_devel("%s: vec=0x%x\n", __func__, vec);
|
||||
pr_devel("%s: hw_irq=0x%x\n", __func__, hw_irq);
|
||||
|
||||
if (vec < in->ibase || vec >= (in->ibase + in->icount))
|
||||
if (hw_irq < in->ibase || hw_irq >= (in->ibase + in->icount))
|
||||
return -EINVAL;
|
||||
|
||||
irq_set_chip_and_handler(virq, &ics_native_irq_chip, handle_fasteoi_irq);
|
||||
irq_set_chip_data(virq, ics);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -177,10 +173,11 @@ static int ics_native_host_match(struct ics *ics, struct device_node *node)
|
|||
}
|
||||
|
||||
static struct ics ics_native_template = {
|
||||
.map = ics_native_map,
|
||||
.check = ics_native_check,
|
||||
.mask_unknown = ics_native_mask_unknown,
|
||||
.get_server = ics_native_get_server,
|
||||
.host_match = ics_native_host_match,
|
||||
.chip = &ics_native_irq_chip,
|
||||
};
|
||||
|
||||
static int __init ics_native_add_one(struct device_node *np)
|
||||
|
|
|
@ -157,26 +157,13 @@ static struct irq_chip ics_opal_irq_chip = {
|
|||
.irq_retrigger = xics_retrigger,
|
||||
};
|
||||
|
||||
static int ics_opal_map(struct ics *ics, unsigned int virq);
|
||||
static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec);
|
||||
static long ics_opal_get_server(struct ics *ics, unsigned long vec);
|
||||
|
||||
static int ics_opal_host_match(struct ics *ics, struct device_node *node)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Only one global & state struct ics */
|
||||
static struct ics ics_hal = {
|
||||
.map = ics_opal_map,
|
||||
.mask_unknown = ics_opal_mask_unknown,
|
||||
.get_server = ics_opal_get_server,
|
||||
.host_match = ics_opal_host_match,
|
||||
};
|
||||
|
||||
static int ics_opal_map(struct ics *ics, unsigned int virq)
|
||||
static int ics_opal_check(struct ics *ics, unsigned int hw_irq)
|
||||
{
|
||||
unsigned int hw_irq = (unsigned int)virq_to_hw(virq);
|
||||
int64_t rc;
|
||||
__be16 server;
|
||||
int8_t priority;
|
||||
|
@ -189,9 +176,6 @@ static int ics_opal_map(struct ics *ics, unsigned int virq)
|
|||
if (rc != OPAL_SUCCESS)
|
||||
return -ENXIO;
|
||||
|
||||
irq_set_chip_and_handler(virq, &ics_opal_irq_chip, handle_fasteoi_irq);
|
||||
irq_set_chip_data(virq, &ics_hal);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -222,6 +206,15 @@ static long ics_opal_get_server(struct ics *ics, unsigned long vec)
|
|||
return ics_opal_unmangle_server(be16_to_cpu(server));
|
||||
}
|
||||
|
||||
/* Only one global & state struct ics */
|
||||
static struct ics ics_hal = {
|
||||
.check = ics_opal_check,
|
||||
.mask_unknown = ics_opal_mask_unknown,
|
||||
.get_server = ics_opal_get_server,
|
||||
.host_match = ics_opal_host_match,
|
||||
.chip = &ics_opal_irq_chip,
|
||||
};
|
||||
|
||||
int __init ics_opal_init(void)
|
||||
{
|
||||
if (!firmware_has_feature(FW_FEATURE_OPAL))
|
||||
|
|
|
@ -24,19 +24,6 @@ static int ibm_set_xive;
|
|||
static int ibm_int_on;
|
||||
static int ibm_int_off;
|
||||
|
||||
static int ics_rtas_map(struct ics *ics, unsigned int virq);
|
||||
static void ics_rtas_mask_unknown(struct ics *ics, unsigned long vec);
|
||||
static long ics_rtas_get_server(struct ics *ics, unsigned long vec);
|
||||
static int ics_rtas_host_match(struct ics *ics, struct device_node *node);
|
||||
|
||||
/* Only one global & state struct ics */
|
||||
static struct ics ics_rtas = {
|
||||
.map = ics_rtas_map,
|
||||
.mask_unknown = ics_rtas_mask_unknown,
|
||||
.get_server = ics_rtas_get_server,
|
||||
.host_match = ics_rtas_host_match,
|
||||
};
|
||||
|
||||
static void ics_rtas_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
|
||||
|
@ -169,9 +156,8 @@ static struct irq_chip ics_rtas_irq_chip = {
|
|||
.irq_retrigger = xics_retrigger,
|
||||
};
|
||||
|
||||
static int ics_rtas_map(struct ics *ics, unsigned int virq)
|
||||
static int ics_rtas_check(struct ics *ics, unsigned int hw_irq)
|
||||
{
|
||||
unsigned int hw_irq = (unsigned int)virq_to_hw(virq);
|
||||
int status[2];
|
||||
int rc;
|
||||
|
||||
|
@ -183,9 +169,6 @@ static int ics_rtas_map(struct ics *ics, unsigned int virq)
|
|||
if (rc)
|
||||
return -ENXIO;
|
||||
|
||||
irq_set_chip_and_handler(virq, &ics_rtas_irq_chip, handle_fasteoi_irq);
|
||||
irq_set_chip_data(virq, &ics_rtas);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -213,6 +196,15 @@ static int ics_rtas_host_match(struct ics *ics, struct device_node *node)
|
|||
return !of_device_is_compatible(node, "chrp,iic");
|
||||
}
|
||||
|
||||
/* Only one global & state struct ics */
|
||||
static struct ics ics_rtas = {
|
||||
.check = ics_rtas_check,
|
||||
.mask_unknown = ics_rtas_mask_unknown,
|
||||
.get_server = ics_rtas_get_server,
|
||||
.host_match = ics_rtas_host_match,
|
||||
.chip = &ics_rtas_irq_chip,
|
||||
};
|
||||
|
||||
__init int ics_rtas_init(void)
|
||||
{
|
||||
ibm_get_xive = rtas_token("ibm,get-xive");
|
||||
|
|
|
@ -318,10 +318,10 @@ static struct irq_chip xics_ipi_chip = {
|
|||
.irq_unmask = xics_ipi_unmask,
|
||||
};
|
||||
|
||||
static int xics_host_map(struct irq_domain *h, unsigned int virq,
|
||||
irq_hw_number_t hw)
|
||||
static int xics_host_map(struct irq_domain *domain, unsigned int virq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
|
||||
pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hwirq);
|
||||
|
||||
/*
|
||||
* Mark interrupts as edge sensitive by default so that resend
|
||||
|
@ -331,7 +331,7 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
|
|||
irq_clear_status_flags(virq, IRQ_LEVEL);
|
||||
|
||||
/* Don't call into ICS for IPIs */
|
||||
if (hw == XICS_IPI) {
|
||||
if (hwirq == XICS_IPI) {
|
||||
irq_set_chip_and_handler(virq, &xics_ipi_chip,
|
||||
handle_percpu_irq);
|
||||
return 0;
|
||||
|
@ -340,10 +340,13 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
|
|||
if (WARN_ON(!xics_ics))
|
||||
return -EINVAL;
|
||||
|
||||
/* Let the ICS setup the chip data */
|
||||
if (xics_ics->map(xics_ics, virq))
|
||||
if (xics_ics->check(xics_ics, hwirq))
|
||||
return -EINVAL;
|
||||
|
||||
/* No chip data for the XICS domain */
|
||||
irq_domain_set_info(domain, virq, hwirq, xics_ics->chip,
|
||||
NULL, handle_fasteoi_irq, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче