Skip to content

Commit

Permalink
powerpc/xics: Rename the map handler in a check handler
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Cédric Le Goater authored and Michael Ellerman committed Aug 10, 2021
1 parent 298f6f9 commit 248af24
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 50 deletions.
3 changes: 2 additions & 1 deletion arch/powerpc/include/asm/xics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
};

Expand Down
13 changes: 5 additions & 8 deletions arch/powerpc/sysdev/xics/ics-native.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down
27 changes: 10 additions & 17 deletions arch/powerpc/sysdev/xics/ics-opal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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))
Expand Down
28 changes: 10 additions & 18 deletions arch/powerpc/sysdev/xics/ics-rtas.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}

Expand Down Expand Up @@ -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");
Expand Down
15 changes: 9 additions & 6 deletions arch/powerpc/sysdev/xics/xics-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down

0 comments on commit 248af24

Please sign in to comment.