svn commit: r300529 - head/sys/arm/freescale/imx

Svatopluk Kraus skra at FreeBSD.org
Mon May 23 18:16:22 UTC 2016


Author: skra
Date: Mon May 23 18:16:21 2016
New Revision: 300529
URL: https://svnweb.freebsd.org/changeset/base/300529

Log:
  INTRNG - support new interrupt mapping type INTR_MAP_DATA_GPIO
  introduced in r298738.
  
  Reviewed by:	ian

Modified:
  head/sys/arm/freescale/imx/imx_gpio.c

Modified: head/sys/arm/freescale/imx/imx_gpio.c
==============================================================================
--- head/sys/arm/freescale/imx/imx_gpio.c	Mon May 23 18:12:52 2016	(r300528)
+++ head/sys/arm/freescale/imx/imx_gpio.c	Mon May 23 18:16:21 2016	(r300529)
@@ -88,7 +88,14 @@ __FBSDID("$FreeBSD$");
 #define	IMX_GPIO_ISR_REG	0x018 /* Interrupt Status Register */
 #define	IMX_GPIO_EDGE_REG	0x01C /* Edge Detect Register */
 
+#ifdef INTRNG
+#define	DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
+    GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
+    GPIO_INTR_EDGE_FALLING )
+#else
 #define	DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)
+#endif
+
 #define	NGPIO		32
 
 #ifdef INTRNG
@@ -156,15 +163,12 @@ static int imx51_gpio_pin_toggle(device_
 
 #ifdef INTRNG
 static int
-gpio_pic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
-    uint32_t *modep)
+gpio_pic_map_fdt(struct imx51_gpio_softc *sc, struct intr_map_data_fdt *daf,
+    u_int *irqp, uint32_t *modep)
 {
-	struct imx51_gpio_softc *sc;
-	u_int irq, tripol;
+	u_int irq;
 	uint32_t mode;
 
-	sc = device_get_softc(dev);
-
 	/*
 	 * From devicetree/bindings/gpio/fsl-imx-gpio.txt:
 	 *  #interrupt-cells:  2. The first cell is the GPIO number. The second
@@ -176,18 +180,17 @@ gpio_pic_map_fdt(device_t dev, u_int nce
          * We can do any single one of these modes, but nothing in combo.
 	 */
 
-	if (ncells != 2) {
+	if (daf->ncells != 2) {
 		device_printf(sc->dev, "Invalid #interrupt-cells\n");
 		return (EINVAL);
 	}
 
-	irq = cells[0];
-	tripol = cells[1];
+	irq = daf->cells[0];
 	if (irq >= sc->gpio_npins) {
 		device_printf(sc->dev, "Invalid interrupt number %u\n", irq);
 		return (EINVAL);
 	}
-	switch (tripol) {
+	switch (daf->cells[1]) {
 	case 1:
 		mode = GPIO_INTR_EDGE_RISING;
 		break;
@@ -202,7 +205,7 @@ gpio_pic_map_fdt(device_t dev, u_int nce
 		break;
 	default:
 		device_printf(sc->dev, "Unsupported interrupt mode 0x%2x\n",
-		    tripol);
+		    daf->cells[1]);
 		return (ENOTSUP);
 	}
 	*irqp = irq;
@@ -212,23 +215,61 @@ gpio_pic_map_fdt(device_t dev, u_int nce
 }
 
 static int
+gpio_pic_map_gpio(struct imx51_gpio_softc *sc, struct intr_map_data_gpio *dag,
+    u_int *irqp, uint32_t *modep)
+{
+	u_int irq;
+	uint32_t mode;
+
+	irq = dag->gpio_pin_num;
+	if (irq >= sc->gpio_npins) {
+		device_printf(sc->dev, "Invalid interrupt number %u\n", irq);
+		return (EINVAL);
+	}
+
+	mode = dag->gpio_intr_mode;
+	if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH &&
+	    mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING) {
+		device_printf(sc->dev, "Unsupported interrupt mode 0x%8x\n",
+		    mode);
+		return (EINVAL);
+	}
+
+	*irqp = irq;
+	if (modep != NULL)
+		*modep = mode;
+	return (0);
+}
+
+static int
+gpio_pic_map(struct imx51_gpio_softc *sc, struct intr_map_data *data,
+    u_int *irqp, uint32_t *modep)
+{
+
+	switch (data->type) {
+	case INTR_MAP_DATA_FDT:
+		return (gpio_pic_map_fdt(sc, (struct intr_map_data_fdt *)data,
+		    irqp, modep));
+	case INTR_MAP_DATA_GPIO:
+		return (gpio_pic_map_gpio(sc, (struct intr_map_data_gpio *)data,
+		    irqp, modep));
+	default:
+		return (ENOTSUP);
+	}
+}
+
+static int
 gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
     struct intr_irqsrc **isrcp)
 {
 	int error;
 	u_int irq;
-	struct intr_map_data_fdt *daf;
 	struct imx51_gpio_softc *sc;
 
-	if (data->type != INTR_MAP_DATA_FDT)
-		return (ENOTSUP);
-
-	daf = (struct intr_map_data_fdt *)data;
-	error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, NULL);
-	if (error == 0) {
-		sc = device_get_softc(dev);
+	sc = device_get_softc(dev);
+	error = gpio_pic_map(sc, data, &irq, NULL);
+	if (error == 0)
 		*isrcp = &sc->gpio_pic_irqsrc[irq].gi_isrc;
-	}
 	return (error);
 }
 
@@ -257,21 +298,20 @@ static int
 gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
     struct resource *res, struct intr_map_data *data)
 {
-	struct intr_map_data_fdt *daf;
 	struct imx51_gpio_softc *sc;
 	struct gpio_irqsrc *gi;
 	int error, icfg;
 	u_int irq, reg, shift, wrk;
 	uint32_t mode;
 
+	if (data == NULL)
+		return (ENOTSUP);
+
 	sc = device_get_softc(dev);
 	gi = (struct gpio_irqsrc *)isrc;
 
 	/* Get config for interrupt. */
-	if (data == NULL || data->type != INTR_MAP_DATA_FDT)
-		return (ENOTSUP);
-	daf = (struct intr_map_data_fdt *)data;
-	error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, &mode);
+	error = gpio_pic_map(sc, data, &irq, &mode);
 	if (error != 0)
 		return (error);
 	if (gi->gi_irq != irq)


More information about the svn-src-head mailing list