svn commit: r302598 - projects/powernv/powerpc/powernv

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Jul 11 23:01:59 UTC 2016


Author: nwhitehorn
Date: Mon Jul 11 23:01:58 2016
New Revision: 302598
URL: https://svnweb.freebsd.org/changeset/base/302598

Log:
  Forward interrupts on OPAL-owned devices to OPAL.

Modified:
  projects/powernv/powerpc/powernv/opal_dev.c

Modified: projects/powernv/powerpc/powernv/opal_dev.c
==============================================================================
--- projects/powernv/powerpc/powernv/opal_dev.c	Mon Jul 11 22:53:22 2016	(r302597)
+++ projects/powernv/powerpc/powernv/opal_dev.c	Mon Jul 11 23:01:58 2016	(r302598)
@@ -59,6 +59,7 @@ static const struct ofw_bus_devinfo *opa
     device_t child);
 
 static void	opal_shutdown(void *arg, int howto);
+static void	opal_intr(void *);
 
 static device_method_t  opaldev_methods[] = {
 	/* Device interface */
@@ -93,6 +94,8 @@ DRIVER_MODULE(opaldev, ofwbus, opaldev_d
 static int
 opaldev_probe(device_t dev)
 {
+	pcell_t *irqs;
+	int i, n_irqs;
 
 	if (!ofw_bus_is_compatible(dev, "ibm,opal-v3"))
 		return (ENXIO);
@@ -100,6 +103,20 @@ opaldev_probe(device_t dev)
 		return (ENXIO);
 
 	device_set_desc(dev, "OPAL Abstraction Firmware");
+
+	/* Manually add IRQs before attaching */
+	if (OF_hasprop(ofw_bus_get_node(dev), "opal-interrupts")) {
+		n_irqs = OF_getproplen(ofw_bus_get_node(dev),
+                    "opal-interrupts") / sizeof(*irqs);
+		irqs = malloc(n_irqs * sizeof(*irqs), M_DEVBUF, M_WAITOK);
+		OF_getencprop(ofw_bus_get_node(dev), "opal-interrupts", irqs,
+		    n_irqs * sizeof(*irqs));
+		for (i = 0; i < n_irqs; i++)
+			bus_set_resource(dev, SYS_RES_IRQ, i, irqs[i], 1);
+		free(irqs, M_DEVBUF);
+	}
+
+
 	return (BUS_PROBE_SPECIFIC);
 }
 
@@ -109,8 +126,9 @@ opaldev_attach(device_t dev)
 	phandle_t child;
 	device_t cdev;
 	uint64_t junk;
-	int rv;
+	int i, rv;
 	struct ofw_bus_devinfo *dinfo;
+	struct resource *irq;
 
 	/* Test for RTC support and register clock if it works */
 	rv = opal_call(OPAL_RTC_READ, vtophys(&junk), vtophys(&junk));
@@ -126,6 +144,13 @@ opaldev_attach(device_t dev)
 	EVENTHANDLER_REGISTER(shutdown_final, opal_shutdown, NULL,
 	    SHUTDOWN_PRI_LAST);
 
+	/* Bind to interrupts */
+	for (i = 0; (irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
+	    RF_ACTIVE)) != NULL; i++)
+		bus_setup_intr(dev, irq, INTR_TYPE_TTY | INTR_MPSAFE |
+		    INTR_ENTROPY, NULL, opal_intr, (void *)rman_get_start(irq),
+		    NULL);
+
 	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
 	    child = OF_peer(child)) {
 		dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO);
@@ -217,3 +242,14 @@ opal_shutdown(void *arg, int howto)
 		opal_call(OPAL_CEC_REBOOT);
 }
 
+static void
+opal_intr(void *xintr)
+{
+	uint64_t events = 0;
+
+	opal_call(OPAL_HANDLE_INTERRUPT, (uint32_t)(uint64_t)xintr,
+	    vtophys(&events));
+	/* XXX: do something useful with this information */
+
+}
+


More information about the svn-src-projects mailing list