[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