svn commit: r325991 - head/sys/arm/allwinner

Kyle Evans kevans at FreeBSD.org
Sun Nov 19 03:14:11 UTC 2017


Author: kevans
Date: Sun Nov 19 03:14:10 2017
New Revision: 325991
URL: https://svnweb.freebsd.org/changeset/base/325991

Log:
  aw_nmi: add support for a31/a83t's r_intc
  
  We currently support the a83t's r_intc in a somewhat hack-ish way; our .dts
  describes it as nmi_intc, and uses a subset of the actual register space to
  make it line up with a20/a31 nmi offsets.
  
  This breaks with the recent 4.14 update describing r_intc using the full
  register space, so update aw_nmi to use the correct register offsets with
  the right compat data in a way that doesn't break our current dts with
  nmi_intc or upstream with r_intc described.
  
  Reviewed by:	manu
  Approved by:	emaste (mentor)
  Differential Revision:	https://reviews.freebsd.org/D13122

Modified:
  head/sys/arm/allwinner/aw_nmi.c

Modified: head/sys/arm/allwinner/aw_nmi.c
==============================================================================
--- head/sys/arm/allwinner/aw_nmi.c	Sun Nov 19 02:16:11 2017	(r325990)
+++ head/sys/arm/allwinner/aw_nmi.c	Sun Nov 19 03:14:10 2017	(r325991)
@@ -57,6 +57,10 @@ __FBSDID("$FreeBSD$");
 #define	A31_NMI_IRQ_ENABLE_REG	0x34
 #define	 NMI_IRQ_ENABLE		(1U << 0)
 
+#define	R_NMI_IRQ_CTRL_REG	0x0c
+#define	R_NMI_IRQ_PENDING_REG	0x10
+#define	R_NMI_IRQ_ENABLE_REG	0x40
+
 #define	SC_NMI_READ(_sc, _reg)		bus_read_4(_sc->res[0], _reg)
 #define	SC_NMI_WRITE(_sc, _reg, _val)	bus_write_4(_sc->res[0], _reg, _val)
 
@@ -73,21 +77,43 @@ struct aw_nmi_intr {
 	enum intr_trigger	tri;
 };
 
+struct aw_nmi_reg_cfg {
+	uint8_t			ctrl_reg;
+	uint8_t			pending_reg;
+	uint8_t			enable_reg;
+};
+
 struct aw_nmi_softc {
 	device_t		dev;
 	struct resource *	res[2];
 	void *			intrcookie;
 	struct aw_nmi_intr	intr;
-	uint8_t			enable_reg;
+	struct aw_nmi_reg_cfg *	cfg;
 };
 
-#define	A20_NMI	1
-#define	A31_NMI	2
+static struct aw_nmi_reg_cfg a20_nmi_cfg = {
+	.ctrl_reg =	NMI_IRQ_CTRL_REG,
+	.pending_reg =	NMI_IRQ_PENDING_REG,
+	.enable_reg =	A20_NMI_IRQ_ENABLE_REG,
+};
 
-static struct ofw_compat_data compat_data[] = {
-	{"allwinner,sun7i-a20-sc-nmi", A20_NMI},
-	{"allwinner,sun6i-a31-sc-nmi", A31_NMI},
+static struct aw_nmi_reg_cfg a31_nmi_cfg = {
+	.ctrl_reg =	NMI_IRQ_CTRL_REG,
+	.pending_reg =	NMI_IRQ_PENDING_REG,
+	.enable_reg =	A31_NMI_IRQ_ENABLE_REG,
+};
 
+static struct aw_nmi_reg_cfg a83t_r_nmi_cfg = {
+	.ctrl_reg =	R_NMI_IRQ_CTRL_REG,
+	.pending_reg =	R_NMI_IRQ_PENDING_REG,
+	.enable_reg =	R_NMI_IRQ_ENABLE_REG,
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"allwinner,sun7i-a20-sc-nmi", (uintptr_t)&a20_nmi_cfg},
+	{"allwinner,sun6i-a31-sc-nmi", (uintptr_t)&a31_nmi_cfg},
+	{"allwinner,sun6i-a31-r-intc", (uintptr_t)&a83t_r_nmi_cfg},
+	{"allwinner,sun8i-a83t-r-intc", (uintptr_t)&a83t_r_nmi_cfg},
 	{NULL, 0},
 };
 
@@ -98,13 +124,13 @@ aw_nmi_intr(void *arg)
 
 	sc = arg;
 
-	if (SC_NMI_READ(sc, NMI_IRQ_PENDING_REG) == 0) {
+	if (SC_NMI_READ(sc, sc->cfg->pending_reg) == 0) {
 		device_printf(sc->dev, "Spurious interrupt\n");
 		return (FILTER_HANDLED);
 	}
 
 	if (intr_isrc_dispatch(&sc->intr.isrc, curthread->td_intr_frame) != 0) {
-		SC_NMI_WRITE(sc, sc->enable_reg, !NMI_IRQ_ENABLE);
+		SC_NMI_WRITE(sc, sc->cfg->enable_reg, !NMI_IRQ_ENABLE);
 		device_printf(sc->dev, "Stray interrupt, NMI disabled\n");
 	}
 
@@ -118,7 +144,7 @@ aw_nmi_enable_intr(device_t dev, struct intr_irqsrc *i
 
 	sc = device_get_softc(dev);
 
-	SC_NMI_WRITE(sc, sc->enable_reg, NMI_IRQ_ENABLE);
+	SC_NMI_WRITE(sc, sc->cfg->enable_reg, NMI_IRQ_ENABLE);
 }
 
 static void
@@ -128,7 +154,7 @@ aw_nmi_disable_intr(device_t dev, struct intr_irqsrc *
 
 	sc = device_get_softc(dev);
 
-	SC_NMI_WRITE(sc, sc->enable_reg, !NMI_IRQ_ENABLE);
+	SC_NMI_WRITE(sc, sc->cfg->enable_reg, !NMI_IRQ_ENABLE);
 }
 
 static int
@@ -254,7 +280,7 @@ aw_nmi_setup_intr(device_t dev, struct intr_irqsrc *is
 			icfg = NMI_IRQ_LOW_EDGE;
 	}
 
-	SC_NMI_WRITE(sc, NMI_IRQ_CTRL_REG, icfg);
+	SC_NMI_WRITE(sc, sc->cfg->ctrl_reg, icfg);
 
 	return (0);
 }
@@ -271,7 +297,7 @@ aw_nmi_teardown_intr(device_t dev, struct intr_irqsrc 
 		sc->intr.pol = INTR_POLARITY_CONFORM;
 		sc->intr.tri = INTR_TRIGGER_CONFORM;
 
-		SC_NMI_WRITE(sc, sc->enable_reg, !NMI_IRQ_ENABLE);
+		SC_NMI_WRITE(sc, sc->cfg->enable_reg, !NMI_IRQ_ENABLE);
 	}
 
 	return (0);
@@ -284,7 +310,7 @@ aw_nmi_pre_ithread(device_t dev, struct intr_irqsrc *i
 
 	sc = device_get_softc(dev);
 	aw_nmi_disable_intr(dev, isrc);
-	SC_NMI_WRITE(sc, NMI_IRQ_PENDING_REG, NMI_IRQ_ACK);
+	SC_NMI_WRITE(sc, sc->cfg->pending_reg, NMI_IRQ_ACK);
 }
 
 static void
@@ -303,7 +329,7 @@ aw_nmi_post_filter(device_t dev, struct intr_irqsrc *i
 	sc = device_get_softc(dev);
 
 	arm_irq_memory_barrier(0);
-	SC_NMI_WRITE(sc, NMI_IRQ_PENDING_REG, NMI_IRQ_ACK);
+	SC_NMI_WRITE(sc, sc->cfg->pending_reg, NMI_IRQ_ACK);
 }
 
 static int
@@ -327,6 +353,8 @@ aw_nmi_attach(device_t dev)
 
 	sc = device_get_softc(dev);
 	sc->dev = dev;
+	sc->cfg = (struct aw_nmi_reg_cfg *)
+	    ofw_bus_search_compatible(dev, compat_data)->ocd_data;
 
 	if (bus_alloc_resources(dev, aw_nmi_res_spec, sc->res) != 0) {
 		device_printf(dev, "can't allocate device resources\n");
@@ -339,18 +367,9 @@ aw_nmi_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
-	case A20_NMI:
-		sc->enable_reg = A20_NMI_IRQ_ENABLE_REG;
-		break;
-	case A31_NMI:
-		sc->enable_reg = A31_NMI_IRQ_ENABLE_REG;
-		break;
-	}
-
 	/* Disable and clear interrupts */
-	SC_NMI_WRITE(sc, sc->enable_reg, !NMI_IRQ_ENABLE);
-	SC_NMI_WRITE(sc, NMI_IRQ_PENDING_REG, NMI_IRQ_ACK);
+	SC_NMI_WRITE(sc, sc->cfg->enable_reg, !NMI_IRQ_ENABLE);
+	SC_NMI_WRITE(sc, sc->cfg->pending_reg, NMI_IRQ_ACK);
 
 	xref = OF_xref_from_node(ofw_bus_get_node(dev));
 	/* Register our isrc */


More information about the svn-src-head mailing list