[Skiboot] [PATCH 04/22] xive: introduce an operation backend for current and new drivers
Cédric Le Goater
clg at kaod.org
Wed Sep 4 03:03:55 AEST 2019
These operations define the high level interface of the XIVE driver
with other OPAL drivers using interrupts : PHBs, PSI, NPU. Each XIVE
driver will need to define its custom set to operate. Driver probing
is done as before using the "compatible" property.
Signed-off-by: Cédric Le Goater <clg at kaod.org>
---
include/xive.h | 24 +++++++++
hw/xive.c | 133 ++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 144 insertions(+), 13 deletions(-)
diff --git a/include/xive.h b/include/xive.h
index 8414e63c918e..8cc98bfdaaf3 100644
--- a/include/xive.h
+++ b/include/xive.h
@@ -55,4 +55,28 @@ void *xive_get_trigger_port(uint32_t girq);
extern void xive_cpu_reset(void);
extern void xive_late_init(void);
+struct xive_ops {
+ const char *name;
+ const char *compat;
+ void (*init)(const char *compat);
+ void (*late_init)(void);
+ int64_t (*reset)(void);
+ void (*cpu_reset)(void);
+ uint32_t (*alloc_hw_irqs)(uint32_t chip_id, uint32_t count,
+ uint32_t align);
+ uint32_t (*alloc_ipi_irqs)(uint32_t chip_id, uint32_t count,
+ uint32_t align);
+ uint64_t (*get_notify_port)(uint32_t chip_id, uint32_t offset);
+ uint32_t (*get_notify_base)(uint32_t girq);
+ void (*register_hw)(uint32_t base, uint32_t count, uint32_t shift,
+ void *mmio, uint32_t flags, void *data,
+ const struct irq_source_ops *ops);
+ void (*register_ipi)(uint32_t base, uint32_t count, void *data,
+ const struct irq_source_ops *ops);
+ void (*cpu_callin)(struct cpu_thread *cpu);
+ void *(*get_trigger_port)(uint32_t girq);
+};
+
+extern struct xive_ops xive_p9_ops;
+
#endif /* __XIVE_H__ */
diff --git a/hw/xive.c b/hw/xive.c
index 9eb80a7b8561..13c985536720 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -2056,7 +2056,8 @@ static bool xive_check_ipi_free(struct xive *x, uint32_t irq, uint32_t count)
return true;
}
-uint32_t xive_alloc_hw_irqs(uint32_t chip_id, uint32_t count, uint32_t align)
+static uint32_t xive_p9_alloc_hw_irqs(uint32_t chip_id, uint32_t count,
+ uint32_t align)
{
struct proc_chip *chip = get_chip(chip_id);
struct xive *x;
@@ -2102,7 +2103,8 @@ uint32_t xive_alloc_hw_irqs(uint32_t chip_id, uint32_t count, uint32_t align)
return base;
}
-uint32_t xive_alloc_ipi_irqs(uint32_t chip_id, uint32_t count, uint32_t align)
+static uint32_t xive_p9_alloc_ipi_irqs(uint32_t chip_id, uint32_t count,
+ uint32_t align)
{
struct proc_chip *chip = get_chip(chip_id);
struct xive *x;
@@ -2149,7 +2151,7 @@ uint32_t xive_alloc_ipi_irqs(uint32_t chip_id, uint32_t count, uint32_t align)
return base;
}
-void *xive_get_trigger_port(uint32_t girq)
+static void *xive_p9_get_trigger_port(uint32_t girq)
{
uint32_t idx = GIRQ_TO_IDX(girq);
struct xive *x;
@@ -2172,7 +2174,7 @@ void *xive_get_trigger_port(uint32_t girq)
}
}
-uint64_t xive_get_notify_port(uint32_t chip_id, uint32_t ent)
+static uint64_t xive_p9_get_notify_port(uint32_t chip_id, uint32_t ent)
{
struct proc_chip *chip = get_chip(chip_id);
struct xive *x;
@@ -2254,7 +2256,7 @@ uint64_t xive_get_notify_port(uint32_t chip_id, uint32_t ent)
}
/* Manufacture the powerbus packet bits 32:63 */
-__attrconst uint32_t xive_get_notify_base(uint32_t girq)
+static __attrconst uint32_t xive_p9_get_notify_base(uint32_t girq)
{
return (GIRQ_TO_BLK(girq) << 28) | GIRQ_TO_IDX(girq);
}
@@ -2762,7 +2764,7 @@ static void __xive_register_source(struct xive *x, struct xive_src *s,
__register_irq_source(&s->is, secondary);
}
-void xive_register_hw_source(uint32_t base, uint32_t count, uint32_t shift,
+static void xive_p9_register_hw_source(uint32_t base, uint32_t count, uint32_t shift,
void *mmio, uint32_t flags, void *data,
const struct irq_source_ops *ops)
{
@@ -2777,7 +2779,7 @@ void xive_register_hw_source(uint32_t base, uint32_t count, uint32_t shift,
false, data, ops);
}
-void xive_register_ipi_source(uint32_t base, uint32_t count, void *data,
+static void xive_p9_register_ipi_source(uint32_t base, uint32_t count, void *data,
const struct irq_source_ops *ops)
{
struct xive_src *s;
@@ -2990,7 +2992,7 @@ static void xive_reset_enable_thread(struct cpu_thread *c)
}
}
-void xive_cpu_callin(struct cpu_thread *cpu)
+static void xive_p9_cpu_callin(struct cpu_thread *cpu)
{
struct xive_cpu_state *xs = cpu->xstate;
uint8_t old_w2 __unused, w2 __unused;
@@ -3221,7 +3223,7 @@ static void xive_configure_ex_special_bar(struct xive *x, struct cpu_thread *c)
}
}
-void xive_late_init(void)
+static void xive_p9_late_init(void)
{
struct cpu_thread *c;
@@ -4811,7 +4813,7 @@ static void xive_reset_mask_source_cb(struct irq_source *is,
}
}
-void xive_cpu_reset(void)
+static void xive_p9_cpu_reset(void)
{
struct cpu_thread *c = this_cpu();
struct xive_cpu_state *xs = c->xstate;
@@ -4861,7 +4863,7 @@ static int64_t __xive_reset(uint64_t version)
}
/* Called by fast reboot */
-int64_t xive_reset(void)
+static int64_t xive_p9_reset(void)
{
if (xive_mode == XIVE_MODE_NONE)
return OPAL_SUCCESS;
@@ -5381,7 +5383,7 @@ static void xive_init_globals(void)
xive_block_to_chip[i] = XIVE_INVALID_CHIP;
}
-void init_xive(void)
+static void xive_p9_init(const char *compat)
{
struct dt_node *np;
struct proc_chip *chip;
@@ -5390,7 +5392,7 @@ void init_xive(void)
bool first = true;
/* Look for xive nodes and do basic inits */
- dt_for_each_compatible(dt_root, np, "ibm,power9-xive-x") {
+ dt_for_each_compatible(dt_root, np, compat) {
struct xive *x;
/* Initialize some global stuff */
@@ -5462,3 +5464,108 @@ void init_xive(void)
opal_register(OPAL_XIVE_GET_VP_STATE, opal_xive_get_vp_state, 2);
}
+static struct xive_ops *xive_ops;
+
+int64_t xive_reset(void)
+{
+ return xive_ops->reset();
+}
+
+uint32_t xive_alloc_hw_irqs(uint32_t chip_id, uint32_t count, uint32_t align)
+{
+ return xive_ops->alloc_hw_irqs(chip_id, count, align);
+}
+
+uint32_t xive_alloc_ipi_irqs(uint32_t chip_id, uint32_t count, uint32_t align)
+{
+ return xive_ops->alloc_ipi_irqs(chip_id, count, align);
+}
+
+uint64_t xive_get_notify_port(uint32_t chip_id, uint32_t ent)
+{
+ return xive_ops->get_notify_port(chip_id, ent);
+}
+
+uint32_t xive_get_notify_base(uint32_t girq)
+{
+ return xive_ops->get_notify_base(girq);
+}
+
+void xive_cpu_callin(struct cpu_thread *cpu)
+{
+ return xive_ops->cpu_callin(cpu);
+}
+
+void *xive_get_trigger_port(uint32_t girq)
+{
+ return xive_ops->get_trigger_port(girq);
+}
+
+void xive_register_hw_source(uint32_t base, uint32_t count, uint32_t shift,
+ void *mmio, uint32_t flags, void *data,
+ const struct irq_source_ops *ops)
+{
+ xive_ops->register_hw(base, count, shift, mmio, flags, data, ops);
+}
+
+void xive_register_ipi_source(uint32_t base, uint32_t count, void *data,
+ const struct irq_source_ops *ops)
+{
+ xive_ops->register_ipi(base, count, data, ops);
+}
+
+void xive_cpu_reset(void)
+{
+ xive_ops->cpu_reset();
+}
+
+void xive_late_init(void)
+{
+ xive_ops->late_init();
+}
+
+struct xive_ops xive_p9_ops = {
+ .name = "POWER9 Interrupt Controller (XIVE)",
+ .compat = "ibm,power9-xive-x",
+
+ .init = xive_p9_init,
+ .late_init = xive_p9_late_init,
+ .reset = xive_p9_reset,
+ .alloc_hw_irqs = xive_p9_alloc_hw_irqs,
+ .alloc_ipi_irqs = xive_p9_alloc_ipi_irqs,
+ .get_trigger_port = xive_p9_get_trigger_port,
+ .get_notify_port = xive_p9_get_notify_port,
+ .get_notify_base = xive_p9_get_notify_base,
+ .register_hw = xive_p9_register_hw_source,
+ .register_ipi = xive_p9_register_ipi_source,
+ .cpu_reset = xive_p9_cpu_reset,
+ .cpu_callin = xive_p9_cpu_callin,
+};
+
+static struct xive_ops *xive_ops_table[] = {
+ &xive_p9_ops,
+};
+
+static struct xive_ops *xive_ops_match(void)
+{
+ struct dt_node *np;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(xive_ops_table); i++) {
+ dt_for_each_compatible(dt_root, np, xive_ops_table[i]->compat)
+ return xive_ops_table[i];
+ }
+
+ return NULL;
+}
+
+void init_xive(void)
+{
+ xive_ops = xive_ops_match();
+ if (!xive_ops) {
+ return;
+ }
+
+ prlog(PR_INFO, "XIVE: found %s\n", xive_ops->name);
+ xive_ops->init(xive_ops->compat);
+}
--
2.21.0
More information about the Skiboot
mailing list