Module Name:    src
Committed By:   hkenken
Date:           Wed Jul 24 12:33:19 UTC 2019

Modified Files:
        src/sys/arch/arm/imx: files.imx51 files.imx6 files.imx7 imx51_gpio.c
            imx51var.h imx6_gpio.c imx6_pcie.c imx6_usdhc.c imx7_gpio.c
            imx7_usdhc.c imxgpio.c imxgpiovar.h
        src/sys/arch/evbarm/conf: ARMADILLO-IOT-G3 CUBOX-I HUMMINGBOARD
            IMX6UL-STARTER KOBO NETWALKER NITROGEN6X mk.nitrogen6 std.nitrogen6
        src/sys/arch/evbarm/imx7: imx7_ioconfig.c
        src/sys/arch/evbarm/kobo: kobo_machdep.c
        src/sys/arch/evbarm/netwalker: netwalker_lcd.c netwalker_machdep.c
            netwalker_spi.c netwalker_usb.c
        src/sys/arch/evbarm/nitrogen6: nitrogen6_iomux.c
Added Files:
        src/sys/arch/arm/imx: imxpcie.c imxpciereg.h imxpcievar.h

Log Message:
Modified i.MX GPIO control module and PCIe module.

+ Add imxpcie.c
  imx PCIe common driver


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/imx/files.imx51
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/imx/files.imx6
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/imx/files.imx7 \
    src/sys/arch/arm/imx/imx51var.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/imx51_gpio.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/imx6_gpio.c \
    src/sys/arch/arm/imx/imx7_usdhc.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/imx/imx6_pcie.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/imx/imx6_usdhc.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/imx7_gpio.c \
    src/sys/arch/arm/imx/imxgpiovar.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/imx/imxgpio.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imxpcie.c \
    src/sys/arch/arm/imx/imxpciereg.h src/sys/arch/arm/imx/imxpcievar.h
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/evbarm/conf/CUBOX-I
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/conf/HUMMINGBOARD
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/evbarm/conf/IMX6UL-STARTER
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbarm/conf/KOBO
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/evbarm/conf/NETWALKER
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/evbarm/conf/NITROGEN6X
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/conf/mk.nitrogen6
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/evbarm/conf/std.nitrogen6
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/evbarm/imx7/imx7_ioconfig.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/kobo/kobo_machdep.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/evbarm/netwalker/netwalker_lcd.c \
    src/sys/arch/evbarm/netwalker/netwalker_usb.c
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/evbarm/netwalker/netwalker_machdep.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/netwalker/netwalker_spi.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/imx/files.imx51
diff -u src/sys/arch/arm/imx/files.imx51:1.18 src/sys/arch/arm/imx/files.imx51:1.19
--- src/sys/arch/arm/imx/files.imx51:1.18	Sat Mar 17 18:34:09 2018
+++ src/sys/arch/arm/imx/files.imx51	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx51,v 1.18 2018/03/17 18:34:09 ryo Exp $
+#	$NetBSD: files.imx51,v 1.19 2019/07/24 12:33:18 hkenken Exp $
 #
 # Configuration info for the Freescale i.MX5x
 #
@@ -62,9 +62,8 @@ file   arch/arm/imx/imxwdog.c		imxwdog
 # iMX GPIO
 device	imxgpio: gpiobus
 attach	imxgpio at axi
-file	arch/arm/imx/imxgpio.c		imxgpio		needs-flag
+file	arch/arm/imx/imxgpio.c		imxgpio
 file	arch/arm/imx/imx51_gpio.c	imxgpio
-defflag opt_imxgpio.h			IMX_GPIO_INTR_SPLIT
 
 # iMX IOMUX
 device	imxiomux : bus_space_generic

Index: src/sys/arch/arm/imx/files.imx6
diff -u src/sys/arch/arm/imx/files.imx6:1.16 src/sys/arch/arm/imx/files.imx6:1.17
--- src/sys/arch/arm/imx/files.imx6:1.16	Wed Jul 24 11:58:00 2019
+++ src/sys/arch/arm/imx/files.imx6	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx6,v 1.16 2019/07/24 11:58:00 hkenken Exp $
+#	$NetBSD: files.imx6,v 1.17 2019/07/24 12:33:18 hkenken Exp $
 #
 # Configuration info for the Freescale i.MX6
 #
@@ -28,8 +28,9 @@ file	arch/arm/imx/imx6_axi.c			axi
 
 # iMX6 PCIe
 device	imxpcie: pcibus
-attach	imxpcie at axi
-file	arch/arm/imx/imx6_pcie.c		imxpcie
+attach	imxpcie at axi with imx6_pcie
+file	arch/arm/imx/imxpcie.c			imxpcie
+file	arch/arm/imx/imx6_pcie.c		imx6_pcie
 
 # iMX6 Clock Control Module
 device	imxccm : clk
@@ -62,9 +63,8 @@ file	arch/arm/imx/imxwdog.c			imxwdog
 # iMX GPIO
 device	imxgpio: gpiobus
 attach	imxgpio at axi
-file	arch/arm/imx/imxgpio.c			imxgpio	needs-flag
+file	arch/arm/imx/imxgpio.c			imxgpio
 file	arch/arm/imx/imx6_gpio.c		imxgpio
-defflag opt_imxgpio.h				IMX_GPIO_INTR_SPLIT
 
 # iMX6 IOMUX
 device	imxiomux

Index: src/sys/arch/arm/imx/files.imx7
diff -u src/sys/arch/arm/imx/files.imx7:1.6 src/sys/arch/arm/imx/files.imx7:1.7
--- src/sys/arch/arm/imx/files.imx7:1.6	Sat Mar 17 18:34:09 2018
+++ src/sys/arch/arm/imx/files.imx7	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx7,v 1.6 2018/03/17 18:34:09 ryo Exp $
+#	$NetBSD: files.imx7,v 1.7 2019/07/24 12:33:18 hkenken Exp $
 #
 # Configuration info for the Freescale i.MX7
 #
@@ -52,9 +52,8 @@ file	arch/arm/imx/imxwdog.c			imxwdog
 # iMX GPIO
 device	imxgpio: gpiobus
 attach	imxgpio at axi
-file	arch/arm/imx/imxgpio.c			imxgpio	needs-flag
+file	arch/arm/imx/imxgpio.c			imxgpio
 file	arch/arm/imx/imx7_gpio.c		imxgpio
-defflag opt_imxgpio.h				IMX_GPIO_INTR_SPLIT
 
 # iMX7 IOMUX
 device	imxiomux
Index: src/sys/arch/arm/imx/imx51var.h
diff -u src/sys/arch/arm/imx/imx51var.h:1.6 src/sys/arch/arm/imx/imx51var.h:1.7
--- src/sys/arch/arm/imx/imx51var.h:1.6	Sat Mar 17 18:34:09 2018
+++ src/sys/arch/arm/imx/imx51var.h	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51var.h,v 1.6 2018/03/17 18:34:09 ryo Exp $ */
+/*	$NetBSD: imx51var.h,v 1.7 2019/07/24 12:33:18 hkenken Exp $ */
 
 /*
  * Copyright (c) 2015 Genetec Corporation.  All rights reserved.
@@ -49,10 +49,6 @@ extern struct bus_space armv7_generic_a4
 extern struct arm32_bus_dma_tag arm_generic_dma_tag;
 extern struct arm32_bus_dma_tag imx_bus_dma_tag;
 
-void gpio_set_direction(uint32_t, uint32_t);
-void gpio_data_write(uint32_t, uint32_t);
-bool gpio_data_read(uint32_t);
-
 struct axi_attach_args {
 	const char	*aa_name;
 	bus_space_tag_t	aa_iot;
@@ -63,7 +59,6 @@ struct axi_attach_args {
 	int		aa_irqbase;
 };
 
-
 /* iomux utility functions */
 struct iomux_conf {
 	u_int pin;

Index: src/sys/arch/arm/imx/imx51_gpio.c
diff -u src/sys/arch/arm/imx/imx51_gpio.c:1.3 src/sys/arch/arm/imx/imx51_gpio.c:1.4
--- src/sys/arch/arm/imx/imx51_gpio.c:1.3	Fri Jul 25 07:49:56 2014
+++ src/sys/arch/arm/imx/imx51_gpio.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51_gpio.c,v 1.3 2014/07/25 07:49:56 hkenken Exp $ */
+/*	$NetBSD: imx51_gpio.c,v 1.4 2019/07/24 12:33:18 hkenken Exp $ */
 
 /* derived from imx31_gpio.c */
 /*-
@@ -30,13 +30,15 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx51_gpio.c,v 1.3 2014/07/25 07:49:56 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx51_gpio.c,v 1.4 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_imx.h"
 
 #include "locators.h"
 #include "gpio.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/param.h>
 #include <sys/evcnt.h>
 #include <sys/atomic.h>
@@ -86,6 +88,7 @@ imxgpio_match(device_t parent, cfdata_t 
 void
 imxgpio_attach(device_t parent, device_t self, void *aux)
 {
+	struct imxgpio_softc * const gpio = device_private(self);
 	struct axi_attach_args * const aa = aux;
 	bus_space_handle_t ioh;
 	int error;
@@ -100,21 +103,30 @@ imxgpio_attach(device_t parent, device_t
 		aprint_error_dev(self, "missing irqbase in config\n");
 		return;
 	}
-		
+
 	if (aa->aa_size == AXICF_SIZE_DEFAULT)
 		aa->aa_size = GPIO_SIZE;
 
 	error = bus_space_map(aa->aa_iot, aa->aa_addr, aa->aa_size,
 	    0, &ioh);
-
 	if (error) {
 		aprint_error(": failed to map register %#lx@%#lx: %d\n",
 		    aa->aa_size, aa->aa_addr, error);
 		return;
 	}
 
-	imxgpio_attach_common(self, aa->aa_iot, ioh,
-	    (aa->aa_addr - GPIO1_BASE) / 0x4000,
-	    aa->aa_irq, aa->aa_irqbase);
+	gpio->gpio_is = intr_establish(aa->aa_irq,
+	    IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+	KASSERT(gpio->gpio_is != NULL );
+	gpio->gpio_is_high = intr_establish(aa->aa_irq + 1,
+	    IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+	KASSERT(gpio->gpio_is_high != NULL);
+
+	gpio->gpio_memt = aa->aa_iot;
+	gpio->gpio_memh = ioh;
+	gpio->gpio_unit = (aa->aa_addr - GPIO1_BASE) / 0x4000;
+	gpio->gpio_irqbase = aa->aa_irqbase;
+
+	imxgpio_attach_common(self);
 }
 

Index: src/sys/arch/arm/imx/imx6_gpio.c
diff -u src/sys/arch/arm/imx/imx6_gpio.c:1.2 src/sys/arch/arm/imx/imx6_gpio.c:1.3
--- src/sys/arch/arm/imx/imx6_gpio.c:1.2	Fri Jun  9 18:14:59 2017
+++ src/sys/arch/arm/imx/imx6_gpio.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx6_gpio.c,v 1.2 2017/06/09 18:14:59 ryo Exp $ */
+/*	$NetBSD: imx6_gpio.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -29,7 +29,9 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c,v 1.2 2017/06/09 18:14:59 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $");
+
+#define	_INTR_PRIVATE
 
 #include "opt_imx.h"
 
@@ -45,12 +47,12 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_gpio.c,
 #include <arm/cpu.h>
 #include <arm/armreg.h>
 #include <arm/cpufunc.h>
+#include <arm/pic/picvar.h>
 
 #include <sys/bus.h>
 
 #include <arm/imx/imx6_reg.h>
 #include <arm/imx/imx6var.h>
-#include <arm/pic/picvar.h>
 
 #include <arm/imx/imxgpioreg.h>
 #include <arm/imx/imxgpiovar.h>
@@ -88,9 +90,10 @@ imxgpio_match(device_t parent, cfdata_t 
 void
 imxgpio_attach(device_t parent, device_t self, void *aux)
 {
+	struct imxgpio_softc * const gpio = device_private(self);
 	struct axi_attach_args * const aa = aux;
 	bus_space_handle_t ioh;
-	int error, group;
+	int error;
 
 	if (aa->aa_irq == AXICF_IRQ_DEFAULT &&
 	    aa->aa_irqbase != AXICF_IRQBASE_DEFAULT) {
@@ -114,8 +117,21 @@ imxgpio_attach(device_t parent, device_t
 		return;
 	}
 
-	group = (aa->aa_addr - IMX6_AIPS1_BASE - AIPS1_GPIO1_BASE) / 0x4000;
-	imxgpio_attach_common(self, aa->aa_iot, ioh, group,
-	    aa->aa_irq, aa->aa_irqbase);
+	aprint_naive("\n");
+	aprint_normal(": GPIO\n");
+
+	gpio->gpio_memt = aa->aa_iot;
+	gpio->gpio_memh = ioh;
+	gpio->gpio_unit = (aa->aa_addr - IMX6_AIPS1_BASE - AIPS1_GPIO1_BASE) / 0x4000;
+	gpio->gpio_irqbase = aa->aa_irqbase;
+
+	gpio->gpio_is = intr_establish(aa->aa_irq,
+	    IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+	KASSERT(gpio->gpio_is != NULL );
+	gpio->gpio_is_high = intr_establish(aa->aa_irq + 1,
+	    IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+	KASSERT(gpio->gpio_is_high != NULL);
+
+	imxgpio_attach_common(self);
 }
 
Index: src/sys/arch/arm/imx/imx7_usdhc.c
diff -u src/sys/arch/arm/imx/imx7_usdhc.c:1.2 src/sys/arch/arm/imx/imx7_usdhc.c:1.3
--- src/sys/arch/arm/imx/imx7_usdhc.c:1.2	Thu Oct 26 05:08:30 2017
+++ src/sys/arch/arm/imx/imx7_usdhc.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx7_usdhc.c,v 1.2 2017/10/26 05:08:30 ryo Exp $	*/
+/*	$NetBSD: imx7_usdhc.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2012  Genetec Corporation.  All rights reserved.
@@ -29,10 +29,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx7_usdhc.c,v 1.2 2017/10/26 05:08:30 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx7_usdhc.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "imxgpio.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/systm.h>
@@ -141,7 +143,7 @@ sdhc_set_gpio_cd(struct sdhc_axi_softc *
 
 	sc->sc_gpio_cd = GPIO_NO(grp, pin);
 #if NIMXGPIO > 0
-	gpio_set_direction(sc->sc_gpio_cd, GPIO_DIR_IN);
+	gpio_set_direction(sc->sc_gpio_cd, GPIO_PIN_INPUT);
 #endif
 }
 

Index: src/sys/arch/arm/imx/imx6_pcie.c
diff -u src/sys/arch/arm/imx/imx6_pcie.c:1.9 src/sys/arch/arm/imx/imx6_pcie.c:1.10
--- src/sys/arch/arm/imx/imx6_pcie.c:1.9	Thu Jun 20 08:16:19 2019
+++ src/sys/arch/arm/imx/imx6_pcie.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx6_pcie.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $	*/
+/*	$NetBSD: imx6_pcie.c,v 1.10 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2016  Genetec Corporation.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.9 2019/06/20 08:16:19 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,v 1.10 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_pci.h"
 
@@ -39,6 +39,8 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,
 #include "imxgpio.h"
 #include "locators.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/intr.h>
@@ -58,467 +60,42 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_pcie.c,
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pciconf.h>
 
+#include <arm/imx/imxpcievar.h>
 #include <arm/imx/imxgpioreg.h>
 #include <arm/imx/imxgpiovar.h>
 #include <arm/imx/imx6var.h>
 #include <arm/imx/imx6_reg.h>
-#include <arm/imx/imx6_pciereg.h>
 #include <arm/imx/imx6_iomuxreg.h>
 #include <arm/imx/imx6_ccmreg.h>
 #include <arm/imx/imx6_ccmvar.h>
 
-static int imx6pcie_match(device_t, cfdata_t, void *);
-static void imx6pcie_attach(device_t, device_t, void *);
-
-#define IMX6_PCIE_MEM_BASE	0x01000000
-#define IMX6_PCIE_MEM_SIZE	0x00f00000 /* 15MB */
-#define IMX6_PCIE_ROOT_BASE	0x01f00000
-#define IMX6_PCIE_ROOT_SIZE	0x00080000 /* 512KB */
-#define IMX6_PCIE_IO_BASE	0x01f80000
-#define IMX6_PCIE_IO_SIZE	0x00010000 /* 64KB */
-
-struct imx6pcie_ih {
-	int (*ih_handler)(void *);
-	void *ih_arg;
-	int ih_ipl;
-	TAILQ_ENTRY(imx6pcie_ih) ih_entry;
-};
-
-struct imx6pcie_softc {
-	device_t sc_dev;
-
-	bus_space_tag_t sc_iot;
-	bus_space_handle_t sc_ioh;
-	bus_space_handle_t sc_root_ioh;
-	bus_dma_tag_t sc_dmat;
-
-	struct arm32_pci_chipset sc_pc;
-
-	TAILQ_HEAD(, imx6pcie_ih) sc_intrs;
-
-	void *sc_ih;
-	kmutex_t sc_lock;
-	u_int sc_intrgen;
+struct imx6_pcie_softc {
+	struct imxpcie_softc sc_imxpcie;
 
 	int32_t sc_gpio_reset;
 	int32_t sc_gpio_reset_active;
-	int32_t sc_gpio_pwren;
-	int32_t sc_gpio_pwren_active;
-
-	struct clk *sc_clk_pcie_axi;
-	struct clk *sc_clk_lvds1_gate;
-	struct clk *sc_clk_pcie_ref;
 };
 
-#define PCIE_CONF_LOCK(s)	(s) = disable_interrupts(I32_bit)
-#define PCIE_CONF_UNLOCK(s)	restore_interrupts((s))
-
-#define PCIE_READ(sc, reg)					\
-	bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, reg)
-#define PCIE_WRITE(sc, reg, val)				\
-	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, reg, val)
-
-static int imx6pcie_intr(void *);
-static void imx6pcie_init(pci_chipset_tag_t, void *);
-static void imx6pcie_setup(struct imx6pcie_softc * const);
-
-static void imx6pcie_attach_hook(device_t, device_t,
-				       struct pcibus_attach_args *);
-static int imx6pcie_bus_maxdevs(void *, int);
-static pcitag_t imx6pcie_make_tag(void *, int, int, int);
-static void imx6pcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
-static pcireg_t imx6pcie_conf_read(void *, pcitag_t, int);
-static void imx6pcie_conf_write(void *, pcitag_t, int, pcireg_t);
-#ifdef __HAVE_PCI_CONF_HOOK
-static int imx6pcie_conf_hook(void *, int, int, int, pcireg_t);
-#endif
-static void imx6pcie_conf_interrupt(void *, int, int, int, int, int *);
-
-static int imx6pcie_intr_map(const struct pci_attach_args *,
-				    pci_intr_handle_t *);
-static const char *imx6pcie_intr_string(void *, pci_intr_handle_t,
-					  char *, size_t);
-const struct evcnt *imx6pcie_intr_evcnt(void *, pci_intr_handle_t);
-static void * imx6pcie_intr_establish(void *, pci_intr_handle_t,
-					 int, int (*)(void *), void *,
-				         const char *);
-static void imx6pcie_intr_disestablish(void *, void *);
-
-CFATTACH_DECL_NEW(imxpcie, sizeof(struct imx6pcie_softc),
-    imx6pcie_match, imx6pcie_attach, NULL, NULL);
-
-static int
-imx6pcie_linkup_status(struct imx6pcie_softc *sc)
-{
-	return PCIE_READ(sc, PCIE_PL_DEBUG1) & PCIE_PL_DEBUG1_XMLH_LINK_UP;
-}
-
-static int
-imx6pcie_valid_device(struct imx6pcie_softc *sc, int bus, int dev)
-{
-	if (bus != 0 && !imx6pcie_linkup_status(sc))
-		return 0;
-	if (bus <= 1 && dev > 0)
-		return 0;
-
-	return 1;
-}
-
-static int
-imx6pcie_init_clocks(struct imx6pcie_softc *sc)
-{
-	int error;
-
-	error = clk_enable(sc->sc_clk_pcie_axi);
-	if (error) {
-		aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error);
-		return error;
-	}
-	error = clk_enable(sc->sc_clk_lvds1_gate);
-	if (error) {
-		aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n", error);
-		return error;
-	}
-	error = clk_enable(sc->sc_clk_pcie_ref);
-	if (error) {
-		aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error);
-		return error;
-	}
-
-	return 0;
-}
-
-static int
-imx6pcie_init_phy(struct imx6pcie_softc *sc)
-{
-	uint32_t v;
-
-	/* initialize IOMUX */
-	v = iomux_read(IOMUX_GPR12);
-	v &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
-	iomux_write(IOMUX_GPR12, v);
-
-	v &= ~IOMUX_GPR12_DEVICE_TYPE;
-	v |= IOMUX_GPR12_DEVICE_TYPE_PCIE_RC;
-	iomux_write(IOMUX_GPR12, v);
-
-	v &= ~IOMUX_GPR12_LOS_LEVEL;
-	v |= __SHIFTIN(9, IOMUX_GPR12_LOS_LEVEL);
-	iomux_write(IOMUX_GPR12, v);
-
-	v = 0;
-	v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_LOW);
-	v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_FULL);
-	v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_6DB);
-	v |= __SHIFTIN(0, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB);
-	v |= __SHIFTIN(0, IOMUX_GPR8_PCS_TX_DEEMPH_GEN1);
-	iomux_write(IOMUX_GPR8, v);
-
-	return 0;
-}
-
-static int
-imx6pcie_phy_wait_ack(struct imx6pcie_softc *sc, int ack)
-{
-	uint32_t v;
-	int timeout;
-
-	for (timeout = 10; timeout > 0; --timeout) {
-		v = PCIE_READ(sc, PCIE_PL_PHY_STATUS);
-		if (!!(v & PCIE_PL_PHY_STATUS_ACK) == !!ack)
-			return 0;
-		delay(1);
-	}
-
-	return -1;
-}
-
-static int
-imx6pcie_phy_addr(struct imx6pcie_softc *sc, uint32_t addr)
-{
-	uint32_t v;
-
-	v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA);
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v);
-
-	v |= PCIE_PL_PHY_CTRL_CAP_ADR;
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v);
-
-	if (imx6pcie_phy_wait_ack(sc, 1))
-		return -1;
-
-	v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA);
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v);
-
-	if (imx6pcie_phy_wait_ack(sc, 0))
-		return -1;
-
-	return 0;
-}
-
-static int
-imx6pcie_phy_write(struct imx6pcie_softc *sc, uint32_t addr, uint16_t data)
-{
-	/* write address */
-	if (imx6pcie_phy_addr(sc, addr) != 0)
-		return -1;
-
-	/* store data */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA));
-
-	/* assert CAP_DAT and wait ack */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA) | PCIE_PL_PHY_CTRL_CAP_DAT);
-	if (imx6pcie_phy_wait_ack(sc, 1))
-		return -1;
-
-	/* deassert CAP_DAT and wait ack */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA));
-	if (imx6pcie_phy_wait_ack(sc, 0))
-		return -1;
-
-	/* assert WR and wait ack */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_WR);
-	if (imx6pcie_phy_wait_ack(sc, 1))
-		return -1;
-
-	/* deassert WR and wait ack */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA));
-	if (imx6pcie_phy_wait_ack(sc, 0))
-		return -1;
-
-	/* done */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0);
-
-	return 0;
-}
-
-static int
-imx6pcie_phy_read(struct imx6pcie_softc *sc, uint32_t addr)
-{
-	uint32_t v;
-
-	/* write address */
-	if (imx6pcie_phy_addr(sc, addr) != 0)
-		return -1;
-
-	/* assert RD */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_RD);
-	if (imx6pcie_phy_wait_ack(sc, 1))
-		return -1;
-
-	/* read data */
-	v = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_PHY_STATUS),
-	    PCIE_PL_PHY_STATUS_DATA);
-
-	/* deassert RD */
-	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0);
-	if (imx6pcie_phy_wait_ack(sc, 0))
-		return -1;
-
-	return v;
-}
-
-static int
-imx6pcie_assert_core_reset(struct imx6pcie_softc *sc)
-{
-	uint32_t gpr1;
-	uint32_t gpr12;
-
-	gpr1 = iomux_read(IOMUX_GPR1);
-	gpr12 = iomux_read(IOMUX_GPR12);
-
-	/* already enabled by bootloader */
-	if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) &&
-	    (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) {
-		uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR);
-		v &= ~PCIE_PL_PFLR_LINK_STATE;
-		v |= PCIE_PL_PFLR_FORCE_LINK;
-		PCIE_WRITE(sc, PCIE_PL_PFLR, v);
-
-		gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
-		iomux_write(IOMUX_GPR12, gpr12);
-	}
-
-#if defined(IMX6DQP)
-	gpr1 |= IOMUX_GPR1_PCIE_SW_RST;
-	iomux_write(IOMUX_GPR1, gpr1);
-#endif
-
-	gpr1 |= IOMUX_GPR1_TEST_POWERDOWN;
-	iomux_write(IOMUX_GPR1, gpr1);
-	gpr1 &= ~IOMUX_GPR1_REF_SSP_EN;
-	iomux_write(IOMUX_GPR1, gpr1);
-
-	return 0;
-}
-
-static int
-imx6pcie_deassert_core_reset(struct imx6pcie_softc *sc)
-{
-	uint32_t v;
-
-	/* Power ON */
-#if NIMXGPIO > 0
-	if (sc->sc_gpio_pwren >= 0) {
-		gpio_data_write(sc->sc_gpio_pwren, sc->sc_gpio_pwren_active);
-		delay(100 * 1000);
-		gpio_data_write(sc->sc_gpio_pwren, !sc->sc_gpio_pwren_active);
-	}
-#endif
-
-	v = iomux_read(IOMUX_GPR1);
-
-#if defined(IMX6DQP)
-	v &= ~IOMUX_GPR1_PCIE_SW_RST;
-	iomux_write(IOMUX_GPR1, v);
-#endif
-
-	delay(50 * 1000);
-
-	v &= ~IOMUX_GPR1_TEST_POWERDOWN;
-	iomux_write(IOMUX_GPR1, v);
-	delay(10);
-	v |= IOMUX_GPR1_REF_SSP_EN;
-	iomux_write(IOMUX_GPR1, v);
-
-	delay(50 * 1000);
-
-	/* Reset */
-#if NIMXGPIO > 0
-	if (sc->sc_gpio_reset >= 0) {
-		gpio_data_write(sc->sc_gpio_reset, sc->sc_gpio_reset_active);
-		delay(100 * 1000);
-		gpio_data_write(sc->sc_gpio_reset, !sc->sc_gpio_reset_active);
-	}
-#endif
-
-	return 0;
-}
-
-static int
-imx6pcie_wait_for_link(struct imx6pcie_softc *sc)
-{
-	uint32_t ltssm, valid, v;
-	int retry;
-
-#define LINKUP_RETRY	200
-	for (retry = LINKUP_RETRY; retry > 0; --retry) {
-		if (!imx6pcie_linkup_status(sc)) {
-			delay(100);
-			continue;
-		}
-
-		valid = imx6pcie_phy_read(sc, PCIE_PHY_RX_ASIC_OUT) &
-		    PCIE_PHY_RX_ASIC_OUT_VALID;
-		ltssm = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_DEBUG0),
-		    PCIE_PL_DEBUG0_XMLH_LTSSM_STATE);
-
-		if ((ltssm == 0x0d) && !valid) {
-			aprint_normal_dev(sc->sc_dev, "resetting PCIe phy\n");
-
-			v = imx6pcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO);
-			v |= PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD;
-			v |= PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD;
-			imx6pcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v);
-
-			delay(3000);
-
-			v = imx6pcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO);
-			v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD;
-			v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD;
-			imx6pcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v);
-		}
-
-		return 0;
-	}
-
-	aprint_error_dev(sc->sc_dev, "Link Up failed.\n");
+static int imx6_pcie_match(device_t, cfdata_t, void *);
+static void imx6_pcie_attach(device_t, device_t, void *);
 
-	return -1;
-}
-
-static int
-imx6pcie_wait_for_changespeed(struct imx6pcie_softc *sc)
-{
-	uint32_t v;
-	int retry;
-
-#define CHANGESPEED_RETRY	200
-	for (retry = CHANGESPEED_RETRY; retry > 0; --retry) {
-		v = PCIE_READ(sc, PCIE_PL_G2CR);
-		if (!(v & PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE))
-			return 0;
-		delay(100);
-	}
-
-	aprint_error_dev(sc->sc_dev, "Speed change timeout.\n");
-
-	return -1;
-}
-
-static void
-imx6pcie_linkup(struct imx6pcie_softc *sc)
-{
-	uint32_t v;
-	int ret;
+static void imx6_pcie_configure(void *);
+static uint32_t imx6_pcie_gpr_read(void *, uint32_t);
+static void imx6_pcie_gpr_write(void *, uint32_t, uint32_t);
+static void imx6_pcie_reset(void *);
 
-	imx6pcie_assert_core_reset(sc);
-	imx6pcie_init_phy(sc);
-	imx6pcie_deassert_core_reset(sc);
-
-	imx6pcie_setup(sc);
-
-	/* GEN1 Operation */
-	v = PCIE_READ(sc, PCIE_RC_LCR);
-	v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS;
-	v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
-	PCIE_WRITE(sc, PCIE_RC_LCR, v);
-
-	/* Link Up */
-	v = iomux_read(IOMUX_GPR12);
-	v |= IOMUX_GPR12_APP_LTSSM_ENABLE;
-	iomux_write(IOMUX_GPR12, v);
-
-	ret = imx6pcie_wait_for_link(sc);
-	if (ret)
-		goto error;
-
-	/* Change speed */
-	v = PCIE_READ(sc, PCIE_PL_G2CR);
-	v |= PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE;
-	PCIE_WRITE(sc, PCIE_PL_G2CR, v);
-
-	ret = imx6pcie_wait_for_changespeed(sc);
-	if (ret)
-		goto error;
-
-	/* Allow Gen2 mode */
-	v = PCIE_READ(sc, PCIE_RC_LCR);
-	v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS;
-	v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
-	PCIE_WRITE(sc, PCIE_RC_LCR, v);
-
-	ret = imx6pcie_wait_for_link(sc);
-	if (ret)
-		goto error;
-
-	v = PCIE_READ(sc, PCIE_RC_LCSR);
-	aprint_normal_dev(sc->sc_dev, "LinkUp, Gen %d\n",
-	    (int)__SHIFTOUT(v, PCIE_RC_LCSR_LINK_SPEED));
-
-	return;
-
-error:
-	aprint_error_dev(sc->sc_dev,
-	    "PCIE_PL_DEBUG0,1 = %08x, %08x\n",
-	    PCIE_READ(sc, PCIE_PL_DEBUG0),
-	    PCIE_READ(sc, PCIE_PL_DEBUG1));
+#define IMX6_PCIE_MEM_BASE	0x01000000
+#define IMX6_PCIE_MEM_SIZE	0x00f00000 /* 15MB */
+#define IMX6_PCIE_ROOT_BASE	0x01f00000
+#define IMX6_PCIE_ROOT_SIZE	0x00080000 /* 512KB */
+#define IMX6_PCIE_IO_BASE	0x01f80000
+#define IMX6_PCIE_IO_SIZE	0x00010000 /* 64KB */
 
-	return;
-}
+CFATTACH_DECL_NEW(imx6_pcie, sizeof(struct imx6_pcie_softc),
+    imx6_pcie_match, imx6_pcie_attach, NULL, NULL);
 
 static int
-imx6pcie_match(device_t parent, cfdata_t cf, void *aux)
+imx6_pcie_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct axi_attach_args * const aa = aux;
 
@@ -542,37 +119,37 @@ imx6pcie_match(device_t parent, cfdata_t
 }
 
 static void
-imx6pcie_attach(device_t parent, device_t self, void *aux)
+imx6_pcie_attach(device_t parent, device_t self, void *aux)
 {
-	struct imx6pcie_softc * const sc = device_private(self);
+	struct imx6_pcie_softc * const ipsc = device_private(self);
+	struct imxpcie_softc * const sc = &ipsc->sc_imxpcie;
 	struct axi_attach_args * const aa = aux;
-	struct pcibus_attach_args pba;
+
+	aprint_naive("\n");
+	aprint_normal(": PCI Express Controller\n");
 
 	sc->sc_dev = self;
 	sc->sc_iot = aa->aa_iot;
 	sc->sc_dmat = aa->aa_dmat;
+	sc->sc_root_addr = IMX6_PCIE_ROOT_BASE;
+	sc->sc_root_size = IMX6_PCIE_ROOT_SIZE;
+	sc->sc_cookie = ipsc;
+	sc->sc_pci_netbsd_configure = imx6_pcie_configure;
+	sc->sc_gpr_read = imx6_pcie_gpr_read;
+	sc->sc_gpr_write = imx6_pcie_gpr_write;
+	sc->sc_reset = imx6_pcie_reset;
 
 	if (aa->aa_size == AXICF_SIZE_DEFAULT)
 		aa->aa_size = IMX6_PCIE_SIZE;
 
-	aprint_naive("\n");
-	aprint_normal(": PCI Express Controller\n");
-
 	if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0,
 	    &sc->sc_ioh)) {
 		aprint_error_dev(self, "Cannot map registers\n");
 		return;
 	}
-	if (bus_space_map(sc->sc_iot, IMX6_PCIE_ROOT_BASE,
-	    IMX6_PCIE_ROOT_SIZE, 0, &sc->sc_root_ioh)) {
-		aprint_error_dev(self, "Cannot map registers\n");
-		return;
-	}
 
-	imx6_set_gpio(self, "imx6pcie-reset-gpio", &sc->sc_gpio_reset,
-	    &sc->sc_gpio_reset_active, GPIO_DIR_OUT);
-	imx6_set_gpio(self, "imx6pcie-pwren-gpio", &sc->sc_gpio_pwren,
-	    &sc->sc_gpio_pwren_active, GPIO_DIR_OUT);
+	imx6_set_gpio(self, "imxpcie-reset-gpio", &ipsc->sc_gpio_reset,
+	    &ipsc->sc_gpio_reset_active, GPIO_PIN_OUTPUT);
 
 	sc->sc_clk_pcie_axi = imx6_get_clock("pcie_axi");
 	if (sc->sc_clk_pcie_axi == NULL) {
@@ -590,15 +167,11 @@ imx6pcie_attach(device_t parent, device_
 		return;
 	}
 
-	imx6pcie_init_clocks(sc);
-
-	imx6pcie_linkup(sc);
-
 	TAILQ_INIT(&sc->sc_intrs);
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
 
 	sc->sc_ih = intr_establish(aa->aa_irq, IPL_VM, IST_LEVEL,
-	    imx6pcie_intr, sc);
+	    imxpcie_intr, sc);
 	if (sc->sc_ih == NULL) {
 		aprint_error_dev(self, "failed to establish interrupt on %d\n",
 		    aa->aa_irq);
@@ -606,7 +179,14 @@ imx6pcie_attach(device_t parent, device_
 	}
 	aprint_normal_dev(self, "interrupting on %d\n", aa->aa_irq);
 
-	imx6pcie_init(&sc->sc_pc, sc);
+	imxpcie_attach_common(sc);
+}
+
+static void
+imx6_pcie_configure(void *cookie)
+{
+	struct imx6_pcie_softc *ipsc = cookie;
+	struct imxpcie_softc *sc = &ipsc->sc_imxpcie;
 
 #ifdef PCI_NETBSD_CONFIGURE
 	struct extent *ioext, *memext;
@@ -626,341 +206,34 @@ imx6pcie_attach(device_t parent, device_
 	extent_destroy(memext);
 
 	if (error) {
-		aprint_error_dev(self, "configuration failed (%d)\n",
+		aprint_error_dev(sc->sc_dev, "configuration failed (%d)\n",
 		    error);
-		return;
 	}
 #endif
-
-	memset(&pba, 0, sizeof(pba));
-	pba.pba_flags = PCI_FLAGS_MEM_OKAY |
-			PCI_FLAGS_IO_OKAY;
-	pba.pba_iot = sc->sc_iot;
-	pba.pba_memt = sc->sc_iot;
-	pba.pba_dmat = sc->sc_dmat;
-	pba.pba_pc = &sc->sc_pc;
-	pba.pba_bus = 0;
-
-	config_found_ia(self, "pcibus", &pba, pcibusprint);
-}
-
-static int
-imx6pcie_intr(void *priv)
-{
-	struct imx6pcie_softc *sc = priv;
-	struct imx6pcie_ih *pcie_ih;
-	int rv = 0;
-	uint32_t v;
-
-	for (int i = 0; i < 8; i++) {
-		v = PCIE_READ(sc, PCIE_PL_MSICIN_STATUS + i * 0xC);
-		int bit;
-		while ((bit = ffs(v) - 1) >= 0) {
-			PCIE_WRITE(sc, PCIE_PL_MSICIN_STATUS + i * 0xC,
-			    __BIT(bit));
-			v &= ~__BIT(bit);
-		}
-	}
-
-	mutex_enter(&sc->sc_lock);
-	const u_int lastgen = sc->sc_intrgen;
-	TAILQ_FOREACH(pcie_ih, &sc->sc_intrs, ih_entry) {
-		int (*callback)(void *) = pcie_ih->ih_handler;
-		void *arg = pcie_ih->ih_arg;
-		mutex_exit(&sc->sc_lock);
-		rv += callback(arg);
-		mutex_enter(&sc->sc_lock);
-		if (lastgen != sc->sc_intrgen)
-			break;
-	}
-	mutex_exit(&sc->sc_lock);
-
-	return rv;
-}
-
-static void
-imx6pcie_setup(struct imx6pcie_softc * const sc)
-{
-	uint32_t v;
-
-	/* Setup RC */
-
-	/* BARs */
-	PCIE_WRITE(sc, PCI_BAR0, 0x00000004);
-	PCIE_WRITE(sc, PCI_BAR1, 0x00000000);
-
-	/* Interurupt pins */
-	v = PCIE_READ(sc, PCI_INTERRUPT_REG);
-	v &= ~(PCI_INTERRUPT_PIN_MASK << PCI_INTERRUPT_PIN_SHIFT);
-	v |= PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT;
-	PCIE_WRITE(sc, PCI_INTERRUPT_REG, v);
-
-	/* Bus number */
-	v = PCIE_READ(sc, PCI_BRIDGE_BUS_REG);
-	v &= ~(PCI_BRIDGE_BUS_SUBORDINATE | PCI_BRIDGE_BUS_SECONDARY |
-	    PCI_BRIDGE_BUS_PRIMARY);
-	v |= PCI_BRIDGE_BUS_NUM_SUBORDINATE(1);
-	v |= PCI_BRIDGE_BUS_NUM_SECONDARY(1);
-	v |= PCI_BRIDGE_BUS_NUM_PRIMARY(0);
-	PCIE_WRITE(sc, PCI_BRIDGE_BUS_REG, v);
-
-	/* Command register */
-	v = PCIE_READ(sc, PCI_COMMAND_STATUS_REG);
-	v |= PCI_COMMAND_IO_ENABLE |
-	    PCI_COMMAND_MEM_ENABLE |
-	    PCI_COMMAND_MASTER_ENABLE |
-	    PCI_COMMAND_SERR_ENABLE;
-	PCIE_WRITE(sc, PCI_COMMAND_STATUS_REG, v);
-
-	PCIE_WRITE(sc, PCI_CLASS_REG,
-	    PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
-		PCI_SUBCLASS_BRIDGE_PCI, PCI_INTERFACE_BRIDGE_PCI_PCI));
-
-	PCIE_WRITE(sc, PCIE_PL_IATUVR, 0);
-
-	PCIE_WRITE(sc, PCIE_PL_IATURLBA, IMX6_PCIE_ROOT_BASE);
-	PCIE_WRITE(sc, PCIE_PL_IATURUBA, 0);
-	PCIE_WRITE(sc, PCIE_PL_IATURLA, IMX6_PCIE_ROOT_BASE + IMX6_PCIE_ROOT_SIZE);
-
-	PCIE_WRITE(sc, PCIE_PL_IATURLTA, 0);
-	PCIE_WRITE(sc, PCIE_PL_IATURUTA, 0);
-	PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0);
-	PCIE_WRITE(sc, PCIE_PL_IATURC2, PCIE_PL_IATURC2_REGION_ENABLE);
-}
-
-void
-imx6pcie_init(pci_chipset_tag_t pc, void *priv)
-{
-	pc->pc_conf_v = priv;
-	pc->pc_attach_hook = imx6pcie_attach_hook;
-	pc->pc_bus_maxdevs = imx6pcie_bus_maxdevs;
-	pc->pc_make_tag = imx6pcie_make_tag;
-	pc->pc_decompose_tag = imx6pcie_decompose_tag;
-	pc->pc_conf_read = imx6pcie_conf_read;
-	pc->pc_conf_write = imx6pcie_conf_write;
-#ifdef __HAVE_PCI_CONF_HOOK
-	pc->pc_conf_hook = imx6pcie_conf_hook;
-#endif
-	pc->pc_conf_interrupt = imx6pcie_conf_interrupt;
-
-	pc->pc_intr_v = priv;
-	pc->pc_intr_map = imx6pcie_intr_map;
-	pc->pc_intr_string = imx6pcie_intr_string;
-	pc->pc_intr_evcnt = imx6pcie_intr_evcnt;
-	pc->pc_intr_establish = imx6pcie_intr_establish;
-	pc->pc_intr_disestablish = imx6pcie_intr_disestablish;
-}
-
-static void
-imx6pcie_attach_hook(device_t parent, device_t self,
-    struct pcibus_attach_args *pba)
-{
-	/* nothing to do */
-}
-
-static int
-imx6pcie_bus_maxdevs(void *v, int busno)
-{
-	return 32;
-}
-
-static pcitag_t
-imx6pcie_make_tag(void *v, int b, int d, int f)
-{
-	return (b << 16) | (d << 11) | (f << 8);
 }
 
-static void
-imx6pcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
+static uint32_t
+imx6_pcie_gpr_read(void *cookie, uint32_t reg)
 {
-	if (bp)
-		*bp = (tag >> 16) & 0xff;
-	if (dp)
-		*dp = (tag >> 11) & 0x1f;
-	if (fp)
-		*fp = (tag >> 8) & 0x7;
+	return iomux_read(reg);
 }
 
-/*
- * work around.
- * If there is no PCIe devices, DABT will be generated by read/write access to
- * config area, so replace original DABT handler with simple jump-back one.
- */
-extern u_int data_abort_handler_address;
-static bool data_abort_flag;
 static void
-imx6pcie_data_abort_handler(trapframe_t *tf)
-{
-	data_abort_flag = true;
-	tf->tf_pc += 0x4;
-	return;
-}
-
-static pcireg_t
-imx6pcie_conf_read(void *v, pcitag_t tag, int offset)
+imx6_pcie_gpr_write(void *cookie, uint32_t reg, uint32_t val)
 {
-	struct imx6pcie_softc *sc = v;
-	bus_space_handle_t bsh;
-	int b, d, f;
-	pcireg_t ret = -1;
-	int s;
-
-	imx6pcie_decompose_tag(v, tag, &b, &d, &f);
-
-	if ((unsigned int)offset >= PCI_EXTCONF_SIZE)
-		return ret;
-	if (!imx6pcie_valid_device(sc, b, d))
-		return ret;
-
-	PCIE_WRITE(sc, PCIE_PL_IATUVR, 0);
-	if (b < 2)
-		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0);
-	else
-		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1);
-
-	if (b == 0) {
-		bsh = sc->sc_ioh;
-	} else {
-		PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8);
-		bsh = sc->sc_root_ioh;
-	}
-	PCIE_READ(sc, PCIE_PL_IATURC2);
-
-	PCIE_CONF_LOCK(s);
-
-	u_int saved = data_abort_handler_address;
-	data_abort_handler_address = (u_int)imx6pcie_data_abort_handler;
-	data_abort_flag = false;
-
-	ret = bus_space_read_4(sc->sc_iot, bsh, offset & ~0x3);
-
-	data_abort_handler_address = saved;
-
-	PCIE_CONF_UNLOCK(s);
-
-	if (data_abort_flag)
-		ret = -1;
-
-	return ret;
+	iomux_write(reg, val);
 }
 
 static void
-imx6pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
+imx6_pcie_reset(void *cookie)
 {
-	struct imx6pcie_softc *sc = v;
-	bus_space_handle_t bsh;
-	int b, d, f;
-	int s;
-
-	imx6pcie_decompose_tag(v, tag, &b, &d, &f);
-
-	if ((unsigned int)offset >= PCI_EXTCONF_SIZE)
-		return;
-	if (!imx6pcie_valid_device(sc, b, d))
-		return;
+	struct imx6_pcie_softc *ipsc = cookie;
 
-	PCIE_WRITE(sc, PCIE_PL_IATUVR, 0);
-	if (b < 2)
-		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0);
-	else
-		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1);
-
-	if (b == 0) {
-		bsh = sc->sc_ioh;
-	} else {
-		PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8);
-		bsh = sc->sc_root_ioh;
+#if NIMXGPIO > 0
+	if (ipsc->sc_gpio_reset >= 0) {
+		gpio_data_write(ipsc->sc_gpio_reset, ipsc->sc_gpio_reset_active);
+		delay(100 * 1000);
+		gpio_data_write(ipsc->sc_gpio_reset, !ipsc->sc_gpio_reset_active);
 	}
-	PCIE_READ(sc, PCIE_PL_IATURC2);
-
-	PCIE_CONF_LOCK(s);
-
-	u_int saved = data_abort_handler_address;
-	data_abort_handler_address = (u_int)imx6pcie_data_abort_handler;
-
-	bus_space_write_4(sc->sc_iot, bsh, offset & ~0x3, val);
-
-	data_abort_handler_address = saved;
-
-	PCIE_CONF_UNLOCK(s);
-
-	return;
-}
-
-#ifdef __HAVE_PCI_CONF_HOOK
-static int
-imx6pcie_conf_hook(void *v, int b, int d, int f, pcireg_t id)
-{
-	return PCI_CONF_DEFAULT;
-}
 #endif
-
-static void
-imx6pcie_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz,
-    int *ilinep)
-{
-	/* nothing to do */
-}
-
-static int
-imx6pcie_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih)
-{
-	if (pa->pa_intrpin == 0)
-		return EINVAL;
-	*ih = pa->pa_intrpin;
-	return 0;
-}
-
-static const char *
-imx6pcie_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
-{
-	if (ih == PCI_INTERRUPT_PIN_NONE)
-		return NULL;
-
-	strlcpy(buf, "pci", len);
-
-	return buf;
-}
-
-const struct evcnt *
-imx6pcie_intr_evcnt(void *v, pci_intr_handle_t ih)
-{
-	return NULL;
-}
-
-static void *
-imx6pcie_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
-    int (*callback)(void *), void *arg, const char *xname)
-{
-	struct imx6pcie_softc *sc = v;
-	struct imx6pcie_ih *pcie_ih;
-
-	if (ih == 0)
-		return NULL;
-
-	pcie_ih = kmem_alloc(sizeof(*pcie_ih), KM_SLEEP);
-	pcie_ih->ih_handler = callback;
-	pcie_ih->ih_arg = arg;
-	pcie_ih->ih_ipl = ipl;
-
-	mutex_enter(&sc->sc_lock);
-	TAILQ_INSERT_TAIL(&sc->sc_intrs, pcie_ih, ih_entry);
-	sc->sc_intrgen++;
-	mutex_exit(&sc->sc_lock);
-
-	return pcie_ih;
-}
-
-static void
-imx6pcie_intr_disestablish(void *v, void *vih)
-{
-	struct imx6pcie_softc *sc = v;
-	struct imx6pcie_ih *pcie_ih = vih;
-
-	mutex_enter(&sc->sc_lock);
-	TAILQ_REMOVE(&sc->sc_intrs, pcie_ih, ih_entry);
-	sc->sc_intrgen++;
-	mutex_exit(&sc->sc_lock);
-
-	kmem_free(pcie_ih, sizeof(*pcie_ih));
 }

Index: src/sys/arch/arm/imx/imx6_usdhc.c
diff -u src/sys/arch/arm/imx/imx6_usdhc.c:1.7 src/sys/arch/arm/imx/imx6_usdhc.c:1.8
--- src/sys/arch/arm/imx/imx6_usdhc.c:1.7	Thu Jun 20 08:16:19 2019
+++ src/sys/arch/arm/imx/imx6_usdhc.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx6_usdhc.c,v 1.7 2019/06/20 08:16:19 hkenken Exp $ */
+/*	$NetBSD: imx6_usdhc.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $ */
 /*-
  * Copyright (c) 2012  Genetec Corporation.  All rights reserved.
  * Written by Hiroyuki Bessho for Genetec Corporation.
@@ -28,10 +28,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c,v 1.7 2019/06/20 08:16:19 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_usdhc.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "imxgpio.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/systm.h>
@@ -115,22 +117,22 @@ sdhc_attach(device_t parent, device_t se
 	case IMX6_AIPS2_BASE + AIPS2_USDHC1_BASE:
 		sc->sc_clk = imx6_get_clock("usdhc1");
 		imx6_set_gpio(self, "usdhc1-cd-gpio", &sc->sc_gpio_cd,
-		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
+		    &sc->sc_gpio_cd_active, GPIO_PIN_INPUT);
 		break;
 	case IMX6_AIPS2_BASE + AIPS2_USDHC2_BASE:
 		sc->sc_clk = imx6_get_clock("usdhc2");
 		imx6_set_gpio(self, "usdhc2-cd-gpio", &sc->sc_gpio_cd,
-		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
+		    &sc->sc_gpio_cd_active, GPIO_PIN_INPUT);
 		break;
 	case IMX6_AIPS2_BASE + AIPS2_USDHC3_BASE:
 		sc->sc_clk = imx6_get_clock("usdhc3");
 		imx6_set_gpio(self, "usdhc3-cd-gpio", &sc->sc_gpio_cd,
-		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
+		    &sc->sc_gpio_cd_active, GPIO_PIN_INPUT);
 		break;
 	case IMX6_AIPS2_BASE + AIPS2_USDHC4_BASE:
 		sc->sc_clk = imx6_get_clock("usdhc4");
 		imx6_set_gpio(self, "usdhc4-cd-gpio", &sc->sc_gpio_cd,
-		    &sc->sc_gpio_cd_active, GPIO_DIR_IN);
+		    &sc->sc_gpio_cd_active, GPIO_PIN_INPUT);
 		break;
 	}
 

Index: src/sys/arch/arm/imx/imx7_gpio.c
diff -u src/sys/arch/arm/imx/imx7_gpio.c:1.1 src/sys/arch/arm/imx/imx7_gpio.c:1.2
--- src/sys/arch/arm/imx/imx7_gpio.c:1.1	Tue May 17 06:44:45 2016
+++ src/sys/arch/arm/imx/imx7_gpio.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx7_gpio.c,v 1.1 2016/05/17 06:44:45 ryo Exp $	*/
+/*	$NetBSD: imx7_gpio.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,11 +30,13 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx7_gpio.c,v 1.1 2016/05/17 06:44:45 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx7_gpio.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "locators.h"
 #include "gpio.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/param.h>
 #include <sys/evcnt.h>
 #include <sys/atomic.h>
@@ -81,9 +83,10 @@ imxgpio_match(device_t parent __unused, 
 void
 imxgpio_attach(device_t parent __unused, device_t self, void *aux)
 {
+	struct imxgpio_softc * const gpio = device_private(self);
 	struct axi_attach_args * const aa = aux;
 	bus_space_handle_t ioh;
-	int error, group;
+	int error;
 
 	if (aa->aa_irq == AXICF_IRQ_DEFAULT &&
 	    aa->aa_irqbase != AXICF_IRQBASE_DEFAULT) {
@@ -100,14 +103,23 @@ imxgpio_attach(device_t parent __unused,
 
 	error = bus_space_map(aa->aa_iot, aa->aa_addr, aa->aa_size,
 	    0, &ioh);
-
 	if (error) {
 		aprint_error(": failed to map register %#lx@%#lx: %d\n",
 		    aa->aa_size, aa->aa_addr, error);
 		return;
 	}
 
-	group = (aa->aa_addr - IMX7_AIPS_BASE - AIPS1_GPIO1_BASE) / 0x10000;
-	imxgpio_attach_common(self, aa->aa_iot, ioh, group,
-	    aa->aa_irq, aa->aa_irqbase);
+	gpio->gpio_is = intr_establish(aa->aa_irq,
+	    IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+	KASSERT(gpio->gpio_is != NULL );
+	gpio->gpio_is_high = intr_establish(aa->aa_irq + 1,
+	    IPL_HIGH, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+	KASSERT(gpio->gpio_is_high != NULL);
+
+	gpio->gpio_memt = aa->aa_iot;
+	gpio->gpio_memh = ioh;
+	gpio->gpio_unit = (aa->aa_addr - IMX7_AIPS_BASE - AIPS1_GPIO1_BASE) / 0x10000;
+	gpio->gpio_irqbase = aa->aa_irqbase;
+
+	imxgpio_attach_common(self);
 }
Index: src/sys/arch/arm/imx/imxgpiovar.h
diff -u src/sys/arch/arm/imx/imxgpiovar.h:1.1 src/sys/arch/arm/imx/imxgpiovar.h:1.2
--- src/sys/arch/arm/imx/imxgpiovar.h:1.1	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imxgpiovar.h	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imxgpiovar.h,v 1.1 2010/11/30 13:05:27 bsh Exp $ */
+/*	$NetBSD: imxgpiovar.h,v 1.2 2019/07/24 12:33:18 hkenken Exp $ */
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -27,27 +27,59 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-#ifndef _ARM_IMX_IMXGRPIOVAR_H
-#define _ARM_IMX_IMXGRPIOVAR_H
+#ifndef _ARM_IMX_IMXGPIOVAR_H
+#define _ARM_IMX_IMXGPIOVAR_H
+
+#include <sys/gpio.h>
+#include <dev/gpio/gpiovar.h>
 
-#include <sys/bus.h>
-#include <sys/device.h>
 #include <arm/imx/imxgpioreg.h>	/* for GPIO_NPINS */
 
-void imxgpio_attach_common(device_t, bus_space_tag_t, bus_space_handle_t,
-    int, int, int);
+struct imxgpio_softc {
+	struct pic_softc gpio_pic;
+
+	device_t gpio_dev;
+	bus_space_tag_t gpio_memt;
+	bus_space_handle_t gpio_memh;
+
+	void *gpio_is;
+	void *gpio_is_high;
+
+	uint gpio_unit;
+	uint gpio_irqbase;
+	uint32_t gpio_enable_mask;
+	uint32_t gpio_edge_mask;
+	uint32_t gpio_level_mask;
+#if NGPIO > 0
+	struct gpio_chipset_tag gpio_chipset;
+	gpio_pin_t gpio_pins[32];
+#endif
+
+	kmutex_t gpio_lock;
+};
+
+struct imxgpio_pin {
+	int pin_no;
+	u_int pin_flags;
+	bool pin_actlo;
+};
+
+void imxgpio_attach_common(device_t);
 /* defined imx[35]1_gpio.c */
 extern const int imxgpio_ngroups;
 int imxgpio_match(device_t, cfdata_t, void *);
 void imxgpio_attach(device_t, device_t, void *);
 
-
-#define	GPIO_NO(group, pin)	(((group) - 1) * GPIO_NPINS + (pin))
-#define	GPIO_MODULE(pin)	((pin) / GPIO_NPINS)
+int imxgpio_pin_read(void *, int);
+void imxgpio_pin_write(void *, int, int);
+void imxgpio_pin_ctl(void *, int, int);
 
 /* in-kernel GPIO access utility functions */
-enum GPIO_DIRECTION {GPIO_DIR_IN, GPIO_DIR_OUT};
-void gpio_set_direction(u_int, enum GPIO_DIRECTION);
+void gpio_set_direction(u_int, int);
 void gpio_data_write(u_int, u_int);
 bool gpio_data_read(u_int);
-#endif	/* _ARM_IMX_IMXGRPIOVAR_H */
+
+#define	GPIO_NO(group, pin)	(((group) - 1) * GPIO_NPINS + (pin))
+#define	GPIO_MODULE(pin)	((pin) / GPIO_NPINS)
+
+#endif	/* _ARM_IMX_IMXGPIOVAR_H */

Index: src/sys/arch/arm/imx/imxgpio.c
diff -u src/sys/arch/arm/imx/imxgpio.c:1.5 src/sys/arch/arm/imx/imxgpio.c:1.6
--- src/sys/arch/arm/imx/imxgpio.c:1.5	Thu Sep 25 05:05:28 2014
+++ src/sys/arch/arm/imx/imxgpio.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imxgpio.c,v 1.5 2014/09/25 05:05:28 ryo Exp $ */
+/*	$NetBSD: imxgpio.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -29,19 +29,17 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 1.5 2014/09/25 05:05:28 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $");
 
 #define	_INTR_PRIVATE
 
 #include "locators.h"
 #include "gpio.h"
-#include "opt_imxgpio.h"
 
 #include <sys/param.h>
 #include <sys/evcnt.h>
 #include <sys/atomic.h>
-
-#include <uvm/uvm_extern.h>
+#include <sys/bus.h>
 
 #include <machine/intr.h>
 
@@ -49,13 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 
 #include <arm/armreg.h>
 #include <arm/cpufunc.h>
 
-#include <sys/bus.h>
-
-#include <arm/imx/imx31reg.h>
-#include <arm/imx/imx31var.h>
-#include <arm/imx/imxgpioreg.h>
-#include <arm/pic/picvar.h>
-
 #include <arm/imx/imxgpioreg.h>
 #include <arm/imx/imxgpiovar.h>
 
@@ -67,68 +58,37 @@ __KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 
 
 #define	MAX_NGROUP	8
 
-static void gpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
-static void gpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
-static int gpio_pic_find_pending_irqs(struct pic_softc *);
-static void gpio_pic_establish_irq(struct pic_softc *, struct intrsource *);
-
-const struct pic_ops gpio_pic_ops = {
-	.pic_unblock_irqs = gpio_pic_unblock_irqs,
-	.pic_block_irqs = gpio_pic_block_irqs,
-	.pic_find_pending_irqs = gpio_pic_find_pending_irqs,
-	.pic_establish_irq = gpio_pic_establish_irq,
+static void imxgpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
+static void imxgpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
+static int imxgpio_pic_find_pending_irqs(struct pic_softc *);
+static void imxgpio_pic_establish_irq(struct pic_softc *, struct intrsource *);
+
+const struct pic_ops imxgpio_pic_ops = {
+	.pic_unblock_irqs = imxgpio_pic_unblock_irqs,
+	.pic_block_irqs = imxgpio_pic_block_irqs,
+	.pic_find_pending_irqs = imxgpio_pic_find_pending_irqs,
+	.pic_establish_irq = imxgpio_pic_establish_irq,
 	.pic_source_name = NULL
 };
 
-struct gpio_softc {
-	device_t gpio_dev;
-	struct pic_softc gpio_pic;
-#if defined(IMX_GPIO_INTR_SPLIT)
-	struct intrsource *gpio_is_0_15;
-	struct intrsource *gpio_is_16_31;
-#else
-	struct intrsource *gpio_is;
-#endif
-	bus_space_tag_t gpio_memt;
-	bus_space_handle_t gpio_memh;
-	uint32_t gpio_enable_mask;
-	uint32_t gpio_edge_mask;
-	uint32_t gpio_level_mask;
-#if NGPIO > 0
-	struct gpio_chipset_tag gpio_chipset;
-	gpio_pin_t gpio_pins[32];
-#endif
-};
+static struct imxgpio_softc *imxgpio_handles[MAX_NGROUP];
 
-static struct {
-	bus_space_tag_t	iot;
-	struct {
-		bus_space_handle_t ioh;
-		struct gpio_softc *softc;
-	} unit[MAX_NGROUP];
-} gpio_handles;
-
-extern struct cfdriver imxgpio_cd;
-
-CFATTACH_DECL_NEW(imxgpio,
-	sizeof(struct gpio_softc),
-	imxgpio_match, imxgpio_attach,
-	NULL, NULL);
-
-
-#define	PIC_TO_SOFTC(pic) \
-	((struct gpio_softc *)((char *)(pic) - \
-		offsetof(struct gpio_softc, gpio_pic)))
+CFATTACH_DECL_NEW(imxgpio, sizeof(struct imxgpio_softc),
+    imxgpio_match, imxgpio_attach, NULL, NULL);
 
-#define	GPIO_READ(gpio, reg) \
+#define	PIC_TO_SOFTC(pic)						      \
+	((struct imxgpio_softc *)((char *)(pic) -			      \
+	    offsetof(struct imxgpio_softc, gpio_pic)))
+
+#define	GPIO_READ(gpio, reg)						      \
 	bus_space_read_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg))
-#define	GPIO_WRITE(gpio, reg, val) \
+#define	GPIO_WRITE(gpio, reg, val)					      \
 	bus_space_write_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg), (val))
 
 void
-gpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask)
+imxgpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask)
 {
-	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic);
 	KASSERT(irq_base == 0);
 
 	gpio->gpio_enable_mask |= irq_mask;
@@ -138,9 +98,9 @@ gpio_pic_unblock_irqs(struct pic_softc *
 }
 
 void
-gpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask)
+imxgpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask)
 {
-	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic);
 	KASSERT(irq_base == 0);
 
 	gpio->gpio_enable_mask &= ~irq_mask;
@@ -148,9 +108,9 @@ gpio_pic_block_irqs(struct pic_softc *pi
 }
 
 int
-gpio_pic_find_pending_irqs(struct pic_softc *pic)
+imxgpio_pic_find_pending_irqs(struct pic_softc *pic)
 {
-	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic);
 	uint32_t v;
 	uint32_t pending;
 
@@ -213,9 +173,9 @@ gpio_pic_find_pending_irqs(struct pic_so
 	 (GPIO_ICR_EDGE_RISING << (2*IST_EDGE_BOTH)))
 
 void
-gpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
+imxgpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
 {
-	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	struct imxgpio_softc * const gpio = PIC_TO_SOFTC(pic);
 	KASSERT(is->is_irq < 32);
 	uint32_t irq_mask = __BIT(is->is_irq);
 	uint32_t v;
@@ -265,20 +225,26 @@ gpio_pic_establish_irq(struct pic_softc 
 
 #if NGPIO > 0
 
-static int
+int
 imxgpio_pin_read(void *arg, int pin)
 {
-	struct gpio_softc * const gpio = arg;
+	struct imxgpio_softc * const gpio = arg;
+	int val;
+
+	val = __SHIFTOUT(GPIO_READ(gpio, GPIO_DR), __BIT(pin));
 
-	return (GPIO_READ(gpio, GPIO_DR) >> pin) & 1;
+	return val;
 }
 
-static void
+void
 imxgpio_pin_write(void *arg, int pin, int value)
 {
-	struct gpio_softc * const gpio = arg;
-	uint32_t mask = 1 << pin;
-	uint32_t old, new;
+	struct imxgpio_softc * const gpio = arg;
+	uint32_t mask = __BIT(pin);
+	uint32_t old;
+	uint32_t new;
+
+	mutex_enter(&gpio->gpio_lock);
 
 	old = GPIO_READ(gpio, GPIO_DR);
 	if (value)
@@ -288,30 +254,43 @@ imxgpio_pin_write(void *arg, int pin, in
 
 	if (old != new)
 		GPIO_WRITE(gpio, GPIO_DR, new);
+
+	mutex_exit(&gpio->gpio_lock);
 }
 
-static void
+void
 imxgpio_pin_ctl(void *arg, int pin, int flags)
 {
-	struct gpio_softc * const gpio = arg;
-	uint32_t mask = 1 << pin;
-	uint32_t old, new;
+	struct imxgpio_softc * const gpio = arg;
+	uint32_t mask = __BIT(pin);
+	uint32_t old;
+	uint32_t new;
+
+	mutex_enter(&gpio->gpio_lock);
 
 	old = GPIO_READ(gpio, GPIO_DIR);
 	new = old;
-	switch (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
-	case GPIO_PIN_INPUT:	new &= ~mask; break;
-	case GPIO_PIN_OUTPUT:	new |= mask; break;
-	default:		return;
+	switch (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
+	case GPIO_PIN_INPUT:
+		new &= ~mask;
+		break;
+	case GPIO_PIN_OUTPUT:
+		new |= mask;
+		break;
+	default:
+		break;
 	}
+
 	if (old != new)
 		GPIO_WRITE(gpio, GPIO_DIR, new);
+
+	mutex_exit(&gpio->gpio_lock);
 }
 
 static void
 gpio_defer(device_t self)
 {
-	struct gpio_softc * const gpio = device_private(self);
+	struct imxgpio_softc * const gpio = device_private(self);
 	struct gpio_chipset_tag * const gp = &gpio->gpio_chipset;
 	struct gpiobus_attach_args gba;
 	gpio_pin_t *pins;
@@ -332,7 +311,7 @@ gpio_defer(device_t self)
 	for (pin = 0, mask = 1, pins = gpio->gpio_pins;
 	     pin < 32; pin++, mask <<= 1, pins++) {
 		pins->pin_num = pin;
-		if ((gpio->gpio_edge_mask|gpio->gpio_level_mask) & mask)
+		if ((gpio->gpio_edge_mask | gpio->gpio_level_mask) & mask)
 			pins->pin_caps = GPIO_PIN_INPUT;
 		else
 			pins->pin_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
@@ -347,112 +326,69 @@ gpio_defer(device_t self)
 #endif /* NGPIO > 0 */
 
 void
-imxgpio_attach_common(device_t self, bus_space_tag_t iot,
-    bus_space_handle_t ioh, int index, int intr, int irqbase)
+imxgpio_attach_common(device_t self)
 {
-	struct gpio_softc * const gpio = device_private(self);
+	struct imxgpio_softc * const gpio = device_private(self);
 
-	KASSERT(index < MAX_NGROUP);
+	KASSERT(gpio->gpio_unit < MAX_NGROUP);
 
 	gpio->gpio_dev = self;
-	gpio->gpio_memt = iot;
-	gpio->gpio_memh = ioh;
 
-	if (irqbase > 0) {
-		gpio->gpio_pic.pic_ops = &gpio_pic_ops;
+	if (gpio->gpio_irqbase > 0) {
+		aprint_normal_dev(gpio->gpio_dev, "interrupts %d..%d\n",
+		    gpio->gpio_irqbase, gpio->gpio_irqbase + GPIO_NPINS - 1);
+
+		gpio->gpio_pic.pic_ops = &imxgpio_pic_ops;
 		strlcpy(gpio->gpio_pic.pic_name, device_xname(self),
 		    sizeof(gpio->gpio_pic.pic_name));
 		gpio->gpio_pic.pic_maxsources = 32;
 
-		pic_add(&gpio->gpio_pic, irqbase);
-
-		aprint_normal(": interrupts %d..%d",
-		    irqbase, irqbase + GPIO_NPINS - 1);
-
-#if defined(IMX_GPIO_INTR_SPLIT)
-		gpio->gpio_is_0_15 = intr_establish(intr,
-		    IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
-		KASSERT( gpio->gpio_is_0_15 != NULL );
-		gpio->gpio_is_16_31 = intr_establish(intr + 1,
-		    IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
-		KASSERT( gpio->gpio_is_16_31 != NULL );
-#else
-		gpio->gpio_is = intr_establish(intr,
-		    IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
-		KASSERT( gpio->gpio_is != NULL );
-#endif
+		pic_add(&gpio->gpio_pic, gpio->gpio_irqbase);
 	}
-	aprint_normal("\n");
 
-	gpio_handles.iot = iot;
-	gpio_handles.unit[index].softc = gpio;
-	gpio_handles.unit[index].ioh = ioh;
+	mutex_init(&gpio->gpio_lock, MUTEX_DEFAULT, IPL_VM);
+
+	imxgpio_handles[gpio->gpio_unit] = gpio;
 
 #if NGPIO > 0
 	config_interrupts(self, gpio_defer);
 #endif
 }
 
-#define	GPIO_GROUP_READ(index,offset)	\
-	bus_space_read_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \
-	    (offset))
-#define	GPIO_GROUP_WRITE(index,offset,value)				\
-	bus_space_write_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \
-	    (offset), (value))
-
+/* in-kernel GPIO access utility functions */
 void
-gpio_set_direction(u_int gpio, u_int dir)
+gpio_set_direction(u_int gpio, int dir)
 {
 	int index = gpio / GPIO_NPINS;
-	int bit = gpio % GPIO_NPINS;
-	uint32_t reg;
+	int pin = gpio % GPIO_NPINS;
 
 	KDASSERT(index < imxgpio_ngroups);
+	KASSERT(imxgpio_handles[index] != NULL);
 
-	/* XXX lock */
-
-
-	reg = GPIO_GROUP_READ(index, GPIO_DIR);
-	if (dir == GPIO_DIR_OUT)
-		reg |= __BIT(bit);
-	else
-		reg &= ~__BIT(bit);
-	GPIO_GROUP_WRITE(index, GPIO_DIR, reg);
-		      
-	/* XXX unlock */
+	imxgpio_pin_ctl(imxgpio_handles[index], pin, dir);
 }
 
-
 void
 gpio_data_write(u_int gpio, u_int value)
 {
 	int index = gpio / GPIO_NPINS;
-	int bit = gpio % GPIO_NPINS;
-	uint32_t reg;
+	int pin = gpio % GPIO_NPINS;
 
 	KDASSERT(index < imxgpio_ngroups);
+	KASSERT(imxgpio_handles[index] != NULL);
 
-	/* XXX lock */
-	reg = GPIO_GROUP_READ(index, GPIO_DR);
-	if (value)
-		reg |= __BIT(bit);
-	else
-		reg &= ~__BIT(bit);
-	GPIO_GROUP_WRITE(index, GPIO_DR, reg);
-
-	/* XXX unlock */
+	imxgpio_pin_write(imxgpio_handles[index], pin, value);
 }
 
 bool
 gpio_data_read(u_int gpio)
 {
 	int index = gpio / GPIO_NPINS;
-	int bit = gpio % GPIO_NPINS;
-	uint32_t reg;
+	int pin = gpio % GPIO_NPINS;
 
 	KDASSERT(index < imxgpio_ngroups);
+	KASSERT(imxgpio_handles[index] != NULL);
 
-	reg = GPIO_GROUP_READ(index, GPIO_DR);
-
-	return reg & __BIT(bit) ? true : false;
+	return imxgpio_pin_read(imxgpio_handles[index], pin) ? true : false;
 }
+

Index: src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3
diff -u src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3:1.18 src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3:1.19
--- src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3:1.18	Sat May 18 08:49:23 2019
+++ src/sys/arch/evbarm/conf/ARMADILLO-IOT-G3	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-# $NetBSD: ARMADILLO-IOT-G3,v 1.18 2019/05/18 08:49:23 skrll Exp $
+# $NetBSD: ARMADILLO-IOT-G3,v 1.19 2019/07/24 12:33:18 hkenken Exp $
 #
 # ARMADILLO-IOT-G3 -- Atmark Techno, Armadillo-IoT G3
 #
@@ -201,7 +201,6 @@ imxgpio4	at axi? addr 0x30220000 irqbase
 imxgpio5	at axi? addr 0x30210000 irqbase 416 irq 106
 imxgpio6	at axi? addr 0x30200000 irqbase 448 irq 108
 gpio*		at imxgpio?
-options 	IMX_GPIO_INTR_SPLIT
 
 # Clock Control
 imxccm0 	at axi? addr 0x30380000

Index: src/sys/arch/evbarm/conf/CUBOX-I
diff -u src/sys/arch/evbarm/conf/CUBOX-I:1.20 src/sys/arch/evbarm/conf/CUBOX-I:1.21
--- src/sys/arch/evbarm/conf/CUBOX-I:1.20	Fri Apr 26 22:46:03 2019
+++ src/sys/arch/evbarm/conf/CUBOX-I	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-# $NetBSD: CUBOX-I,v 1.20 2019/04/26 22:46:03 sevan Exp $
+# $NetBSD: CUBOX-I,v 1.21 2019/07/24 12:33:18 hkenken Exp $
 #
 # CuBox-i
 # - http://www.solid-run.com/products/cubox-i-mini-computer/
@@ -208,7 +208,6 @@ imxgpio4	at axi? addr 0x020ac000 irqbase
 imxgpio5	at axi? addr 0x020b0000 irqbase 416 irq 108
 imxgpio6	at axi? addr 0x020b4000 irqbase 448 irq 110
 gpio*		at imxgpio?
-options 	IMX_GPIO_INTR_SPLIT
 
 # Clock Control
 imxccm0		at axi? addr 0x020c4000

Index: src/sys/arch/evbarm/conf/HUMMINGBOARD
diff -u src/sys/arch/evbarm/conf/HUMMINGBOARD:1.7 src/sys/arch/evbarm/conf/HUMMINGBOARD:1.8
--- src/sys/arch/evbarm/conf/HUMMINGBOARD:1.7	Wed Feb  6 11:58:30 2019
+++ src/sys/arch/evbarm/conf/HUMMINGBOARD	Wed Jul 24 12:33:18 2019
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: HUMMINGBOARD,v 1.7 2019/02/06 11:58:30 rin Exp $
+#	$NetBSD: HUMMINGBOARD,v 1.8 2019/07/24 12:33:18 hkenken Exp $
 #
 #	Hummingboard -- Freescale i.MX6 Eval Board Kernel
 #
@@ -71,7 +71,6 @@ imxgpio4	at axi? addr 0x020ac000 irqbase
 imxgpio5	at axi? addr 0x020b0000 irqbase 416 irq 108
 imxgpio6	at axi? addr 0x020b4000 irqbase 448 irq 110
 gpio*		at imxgpio?
-options		IMX_GPIO_INTR_SPLIT
 
 # Clock Control
 imxccm0		at axi? addr 0x020c4000

Index: src/sys/arch/evbarm/conf/IMX6UL-STARTER
diff -u src/sys/arch/evbarm/conf/IMX6UL-STARTER:1.12 src/sys/arch/evbarm/conf/IMX6UL-STARTER:1.13
--- src/sys/arch/evbarm/conf/IMX6UL-STARTER:1.12	Fri Apr 26 22:46:03 2019
+++ src/sys/arch/evbarm/conf/IMX6UL-STARTER	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: IMX6UL-STARTER,v 1.12 2019/04/26 22:46:03 sevan Exp $
+#	$NetBSD: IMX6UL-STARTER,v 1.13 2019/07/24 12:33:18 hkenken Exp $
 #
 #	IMX6UL-STARTER - Freescale i.MX6UL Evaluation Board
 #
@@ -210,7 +210,6 @@ imxgpio2	at axi? addr 0x020a4000 irqbase
 imxgpio3	at axi? addr 0x020a8000 irqbase 352 irq 104
 imxgpio4	at axi? addr 0x020ac000 irqbase 384 irq 106
 gpio*		at imxgpio?
-options 	IMX_GPIO_INTR_SPLIT
 
 # Clock Control
 imxccm0		at axi? addr 0x020c4000

Index: src/sys/arch/evbarm/conf/KOBO
diff -u src/sys/arch/evbarm/conf/KOBO:1.9 src/sys/arch/evbarm/conf/KOBO:1.10
--- src/sys/arch/evbarm/conf/KOBO:1.9	Wed Feb  6 11:58:30 2019
+++ src/sys/arch/evbarm/conf/KOBO	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: KOBO,v 1.9 2019/02/06 11:58:30 rin Exp $
+#	$NetBSD: KOBO,v 1.10 2019/07/24 12:33:18 hkenken Exp $
 #
 #	KOBO -- http://kobo.com
 #
@@ -84,6 +84,7 @@ imxgpio2	at axi? addr 0x53f8c000 irqbase
 imxgpio3	at axi? addr 0x53f90000 irqbase 224 irq 56
 imxgpio4	at axi? addr 0x53fdc000 irqbase 256 irq 103
 imxgpio5	at axi? addr 0x53fe0000 irqbase 288 irq 105
+gpio*		at imxgpio?
 
 # EPDC E-Ink Controller
 #epdc0		at axi? addr 0x41010000 size 0x2000 irq 27

Index: src/sys/arch/evbarm/conf/NETWALKER
diff -u src/sys/arch/evbarm/conf/NETWALKER:1.37 src/sys/arch/evbarm/conf/NETWALKER:1.38
--- src/sys/arch/evbarm/conf/NETWALKER:1.37	Wed Feb  6 11:58:30 2019
+++ src/sys/arch/evbarm/conf/NETWALKER	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: NETWALKER,v 1.37 2019/02/06 11:58:30 rin Exp $
+#	$NetBSD: NETWALKER,v 1.38 2019/07/24 12:33:18 hkenken Exp $
 #
 #	NETWALKER -- http://www.sharp.co.jp/netwalker/
 #
@@ -17,7 +17,7 @@ options 	CONSDEVNAME="\"imxuart\"",CONAD
 options 	CONSPEED=115200	# Console speed
 
 # Development and Debugging options
-#options        DEBUG
+#options 	DEBUG
 #options 	KGDB
 makeoptions	DEBUG="-g"	# compile full symbol table
 makeoptions	COPY_SYMTAB=1
@@ -35,7 +35,7 @@ options 	BOOT_ARGS="\"verbose console=fb
 #options 	BOOT_ARGS="\"verbose\""
 
 # Kernel root file system and dump configuration.
-config		netbsd		root on ? type ?
+#config		netbsd		root on ? type ?
 config		netbsd-ld0	root on ld0 type ffs
 
 # The main bus device
@@ -79,7 +79,6 @@ imxgpio1	at axi? addr 0x73f88000 irqbase
 imxgpio2	at axi? addr 0x73f8c000 irqbase 192 irq 54
 imxgpio3	at axi? addr 0x73f90000 irqbase 224 irq 56
 gpio*		at imxgpio?
-options		IMX_GPIO_INTR_SPLIT
 
 # I2C
 imxi2c0		at axi? addr 0x83fc8000 irq 62

Index: src/sys/arch/evbarm/conf/NITROGEN6X
diff -u src/sys/arch/evbarm/conf/NITROGEN6X:1.22 src/sys/arch/evbarm/conf/NITROGEN6X:1.23
--- src/sys/arch/evbarm/conf/NITROGEN6X:1.22	Fri Apr 26 22:46:03 2019
+++ src/sys/arch/evbarm/conf/NITROGEN6X	Wed Jul 24 12:33:18 2019
@@ -1,16 +1,11 @@
-# $NetBSD: NITROGEN6X,v 1.22 2019/04/26 22:46:03 sevan Exp $
+# $NetBSD: NITROGEN6X,v 1.23 2019/07/24 12:33:18 hkenken Exp $
 #
 # Nitrogen6X
 # - http://boundarydevices.com/products/nitrogen6x-board-imx6-arm-cortex-a9-sbc/
 #
 
 include	"arch/evbarm/conf/std.nitrogen6"
-
-#options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
-
-# estimated number of users
-
-maxusers	32
+include	"arch/evbarm/conf/GENERIC.common"
 
 # Board Type
 options 	EVBARM_BOARDTYPE=nitrogen6x
@@ -20,150 +15,20 @@ options 	CPU_CORTEX
 options 	CPU_CORTEXA9
 options 	IMX6
 options 	MULTIPROCESSOR
-options 	PMAPCOUNTERS
 
 # Standard system options
 
-options 	INSECURE	# disable kernel security levels - X needs this
-
-options 	RTC_OFFSET=0	# hardware clock is this many mins. west of GMT
-#options 	NTP		# NTP phase/frequency locked loop
-options 	KTRACE		# system call tracing via ktrace(1)
-
-# Note: SysV IPC parameters can be changed dynamically; see sysctl(8).
-options 	SYSVMSG		# System V-like message queues
-options 	SYSVSEM		# System V-like semaphores
-options 	SYSVSHM		# System V-like memory sharing
-
-#options 	USERCONF	# userconf(4) support
-#options 	PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
-options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel
-
-# Alternate buffer queue strategies for better responsiveness under high
-# disk I/O load.
-#options 	BUFQ_READPRIO
-options 	BUFQ_PRIOCSCAN
-
-# Diagnostic/debugging support options
-options 	VERBOSE_INIT_ARM # verbose bootstraping messages
-options 	DIAGNOSTIC	# internally consistency checks
-
+#options 	DIAGNOSTIC	# internal consistency checks
 #options 	DEBUG
-#options 	PMAP_DEBUG	# Enable pmap_debug_level code
-options 	LOCKDEBUG	# expensive locking checks/support
-options 	IRQSTATS	# manage IRQ statistics
-#options 	NO_POWERSAVE	# uncomment this to run under ICE
-
-#makeoptions	COPTS="-O2"
-options 	DDB			# in-kernel debugger
-#options 	DDB_KEYCODE=0x1d	# ^]
-#options 	DDB_COMMANDONENTER="bt"	# execute command when ddb is entered
-options 	DDB_ONPANIC=1		# see also sysctl(7): `ddb.onpanic'
-options 	DDB_HISTORY_SIZE=100	# Enable history editing in DDB
-options 	DDB_VERBOSE_HELP
-#options	KGDB
-#options 	KGDB_DEVNAME="\"imxuart\""
-#options 	KGDB_DEVADDR=0x021e8000
-#options 	KGDB_DEVRATE=115200
+#options 	KGDB
 makeoptions	DEBUG="-g"		# compile full symbol table
 makeoptions	COPY_SYMTAB=1
-#options 	SYSCALL_STATS			# per syscall counts
-#options 	SYSCALL_TIMES			# per syscall times
-#options 	SYSCALL_TIMES_HASCOUNTER	# use 'broken' rdtsc (soekris)
-
-
-# Compatibility options
-
-include 	"conf/compat_netbsd60.config"
-options 	COMPAT_NETBSD32	# allow running arm (e.g. non-earm) binaries
-
-options 	COMPAT_OSSAUDIO	# OSS (Voxware) audio driver compatibility
-
-# Wedge support
-options 	DKWEDGE_AUTODISCOVER	# Automatically add dk(4) instances
-options 	DKWEDGE_METHOD_GPT	# Supports GPT partitions as wedges
-
-# File systems
-file-system	FFS		# UFS
-file-system	MFS		# memory file system
-file-system	NFS		# Network File System client
-file-system	TMPFS		# Efficient memory file-system
-file-system	EXT2FS		# second extended file system (linux)
-file-system	LFS		# log-structured file system
-file-system	NTFS		# Windows/NT file system (experimental)
-file-system	CD9660		# ISO 9660 + Rock Ridge file system
-file-system	MSDOSFS		# MS-DOS file system
-file-system	FDESC		# /dev/fd
-file-system	KERNFS		# /kern
-file-system	NULLFS		# loopback file system
-file-system	OVERLAY		# overlay file system
-file-system	PROCFS		# /proc
-file-system	PUFFS		# Userspace file systems (e.g. ntfs-3g & sshfs)
-file-system	SMBFS		# experimental - CIFS; also needs nsmb (below)
-file-system	UMAPFS		# NULLFS + uid and gid remapping
-file-system	UNION		# union file system
-file-system	CODA		# Coda File System; also needs vcoda (below)
-file-system	PTYFS		# /dev/ptm support
-#file-system	UDF		# experimental - OSTA UDF CD/DVD file-system
-#file-system	HFS		# experimental - Apple HFS+ (read-only)
-#file-system	NILFS		# experimental - NTT's NiLFS(2)
-
-# File system options
-options 	QUOTA		# legacy UFS quotas
-options 	QUOTA2		# new, in-filesystem UFS quotas
-#options 	DISKLABEL_EI	# disklabel Endian Independent support
-options 	FFS_EI		# FFS Endian Independent support
-options 	WAPBL		# File system journaling support
-# Note that UFS_DIRHASH is suspected of causing kernel memory corruption.
-# It is not recommended for general use.
-#options 	UFS_DIRHASH	# UFS Large Directory Hashing - Experimental
-options 	NFSSERVER	# Network File System server
-#options 	EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
-				# immutable) behave as system flags.
-#options 	FFS_NO_SNAPSHOT	# No FFS snapshot support
-
-# Networking options
-#options 	GATEWAY		# packet forwarding
-options 	INET		# IP + ICMP + TCP + UDP
-options 	INET6		# IPv6
-options 	IPSEC		# IP security
-#options 	IPSEC_DEBUG	# debug for IP security
-#options 	MPLS		# MultiProtocol Label Switching (needs mpls)
-#options 	MROUTING	# IP multicast routing
-#options 	PIM		# Protocol Independent Multicast
-options 	NETATALK	# AppleTalk networking protocols
-options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
-options 	PPP_DEFLATE	# Deflate compression support for PPP
-options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
-#options 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
-
-#options 	ALTQ		# Manipulate network interfaces' output queues
-#options 	ALTQ_BLUE	# Stochastic Fair Blue
-#options 	ALTQ_CBQ	# Class-Based Queueing
-#options 	ALTQ_CDNR	# Diffserv Traffic Conditioner
-#options 	ALTQ_FIFOQ	# First-In First-Out Queue
-#options 	ALTQ_FLOWVALVE	# RED/flow-valve (red-penalty-box)
-#options 	ALTQ_HFSC	# Hierarchical Fair Service Curve
-#options 	ALTQ_LOCALQ	# Local queueing discipline
-#options 	ALTQ_PRIQ	# Priority Queueing
-#options 	ALTQ_RED	# Random Early Detection
-#options 	ALTQ_RIO	# RED with IN/OUT
-#options 	ALTQ_WFQ	# Weighted Fair Queueing
 
 # Device options
 
 # Console options.    also need IMXUARTCONSOLE
 options 	CONSDEVNAME="\"imxuart\"",CONADDR=0x021e8000,CONSPEED=115200
 
-# These options enable verbose messages for several subsystems.
-# Warning, these may compile large string tables into the kernel!
-options 	MIIVERBOSE	# verbose PHY autoconfig messages
-#options 	PCIVERBOSE	# verbose PCI device autoconfig messages
-#options 	PCI_CONFIG_DUMP	# verbosely dump PCI config space
-#options 	PCMCIAVERBOSE	# verbose PCMCIA configuration messages
-#options 	SCSIVERBOSE	# Verbose SCSI errors
-options 	USBVERBOSE	# verbose USB device autoconfig messages
-
 # Kernel root file system and dump configuration.
 config		netbsd	root on ? type ?
 
@@ -197,7 +62,6 @@ imxgpio4	at axi? addr 0x020ac000 irqbase
 imxgpio5	at axi? addr 0x020b0000 irqbase 416 irq 108
 imxgpio6	at axi? addr 0x020b4000 irqbase 448 irq 110
 gpio*		at imxgpio?
-options 	IMX_GPIO_INTR_SPLIT
 
 # Clock Control
 imxccm0		at axi? addr 0x020c4000
@@ -302,89 +166,3 @@ sdmmc*		at sdhc?
 #options 	SDMMC_DEBUG
 
 ld*		at sdmmc?			# MMC/SD card
-
-
-# Pseudo-Devices
-
-pseudo-device	crypto			# /dev/crypto device
-pseudo-device	swcrypto		# software crypto implementation
-
-# disk/mass storage pseudo-devices
-pseudo-device	bio			# RAID control device driver
-pseudo-device	ccd			# concatenated/striped disk devices
-pseudo-device	cgd			# cryptographic disk devices
-pseudo-device	raid			# RAIDframe disk driver
-#options 	RAID_AUTOCONFIG		# auto-configuration of RAID components
-#Options to enable various other RAIDframe RAID types.
-#options	RF_INCLUDE_EVENODD=1
-#options	RF_INCLUDE_RAID5_RS=1
-#options	RF_INCLUDE_PARITYLOGGING=1
-#options	RF_INCLUDE_CHAINDECLUSTER=1
-#options	RF_INCLUDE_INTERDECLUSTER=1
-#options	RF_INCLUDE_PARITY_DECLUSTERING=1
-#options	RF_INCLUDE_PARITY_DECLUSTERING_DS=1
-pseudo-device	fss			# file system snapshot device
-pseudo-device	putter			# for puffs and pud
-
-pseudo-device	vnd			# disk-like interface to files
-options 	VND_COMPRESSION		# compressed vnd(4)
-
-
-# network pseudo-devices
-pseudo-device	bpfilter		# Berkeley packet filter
-#pseudo-device	carp			# Common Address Redundancy Protocol
-pseudo-device	loop			# network loopback
-#pseudo-device	mpls			# MPLS pseudo-interface
-pseudo-device	ppp			# Point-to-Point Protocol
-pseudo-device	pppoe			# PPP over Ethernet (RFC 2516)
-pseudo-device	sl			# Serial Line IP
-pseudo-device	strip			# Starmode Radio IP (Metricom)
-pseudo-device	irframetty		# IrDA frame line discipline
-pseudo-device	tun			# network tunneling over tty
-pseudo-device	tap			# virtual Ethernet
-pseudo-device	gre			# generic L3 over IP tunnel
-pseudo-device	gif			# IPv[46] over IPv[46] tunnel (RFC1933)
-#pseudo-device	faith			# IPv[46] tcp relay translation i/f
-pseudo-device	stf			# 6to4 IPv6 over IPv4 encapsulation
-pseudo-device	vlan			# IEEE 802.1q encapsulation
-pseudo-device	bridge			# simple inter-network bridging
-#options 	BRIDGE_IPF		# bridge uses IP/IPv6 pfil hooks too
-pseudo-device	agr			# IEEE 802.3ad link aggregation
-#pseudo-device	npf			# NPF packet filter
-
-#
-# accept filters
-pseudo-device	accf_data		# "dataready" accept filter
-pseudo-device	accf_http		# "httpready" accept filter
-
-# miscellaneous pseudo-devices
-pseudo-device	pty			# pseudo-terminals
-pseudo-device	sequencer		# MIDI sequencer
-#options 	RND_COM			# use "com" randomness as well (BROKEN)
-pseudo-device	clockctl		# user control of clock subsystem
-pseudo-device	ksyms			# /dev/ksyms
-pseudo-device	lockstat		# lock profiling
-pseudo-device	bcsp			# BlueCore Serial Protocol
-pseudo-device	btuart			# Bluetooth HCI UART (H4)
-
-# a pseudo device needed for Coda	# also needs CODA (above)
-pseudo-device	vcoda			# coda minicache <-> venus comm.
-
-# a pseudo device needed for SMBFS
-pseudo-device	nsmb			# experimental - SMB requester
-
-# wscons pseudo-devices
-pseudo-device	wsmux			# mouse & keyboard multiplexor
-pseudo-device	wsfont
-
-# pseudo audio device driver
-#pseudo-device	pad
-
-# userland interface to drivers, including autoconf and properties retrieval
-pseudo-device	drvctl
-
-# Veriexec
-include "dev/veriexec.config"
-
-options 	PAX_MPROTECT=0		# PaX mprotect(2) restrictions
-options 	PAX_ASLR=0		# PaX Address Space Layout Randomization

Index: src/sys/arch/evbarm/conf/mk.nitrogen6
diff -u src/sys/arch/evbarm/conf/mk.nitrogen6:1.4 src/sys/arch/evbarm/conf/mk.nitrogen6:1.5
--- src/sys/arch/evbarm/conf/mk.nitrogen6:1.4	Sat May 18 08:49:23 2019
+++ src/sys/arch/evbarm/conf/mk.nitrogen6	Wed Jul 24 12:33:18 2019
@@ -1,25 +1,30 @@
-#	$NetBSD: mk.nitrogen6,v 1.4 2019/05/18 08:49:23 skrll Exp $
+#	$NetBSD: mk.nitrogen6,v 1.5 2019/07/24 12:33:18 hkenken Exp $
+
+ENTRYPOINT=		generic_start
 
 SYSTEM_FIRST_OBJ=	armv6_start.o
 SYSTEM_FIRST_SFILE=	${ARM}/arm/armv6_start.S
 
 _OSRELEASE!=		${HOST_SH} $S/conf/osrelease.sh
 
-#KERNEL_BASE_PHYS?=$(LOADADDRESS)
-#KERNEL_BASE_VIRT?=$(LOADADDRESS)
-
-MKUBOOTIMAGEARGS=	-A arm -T kernel_noload -O linux -C none
+MKUBOOTIMAGEARGS=	-A arm -T kernel -O linux
 MKUBOOTIMAGEARGS+=	-e 0
-MKUBOOTIMAGEARGS+=	-n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}"
+MKUBOOTIMAGEARGS+=	-n "NetBSD/${BOARDTYPE:U${MACHINE_ARCH}} ${_OSRELEASE}"
+MKUBOOTIMAGEARGS+=	-a $(KERNEL_BASE_PHYS) -e $(KERNEL_BASE_PHYS)
+MKUBOOTIMAGEARGS_NONE=	${MKUBOOTIMAGEARGS} -C none
+MKUBOOTIMAGEARGS_GZ=	${MKUBOOTIMAGEARGS} -C gz
 
 SYSTEM_LD_TAIL_EXTRA+=; \
 	echo ${OBJCOPY} -S -O binary $@ $@.bin; \
 	${OBJCOPY} -S -O binary $@ $@.bin; \
-	echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub; \
-	${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS} $@.bin $@.ub; \
-	echo
+	echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
+	${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
+	echo ${TOOL_GZIP} -c $@.bin > $@.bin.gz; \
+	${TOOL_GZIP} -c $@.bin > $@.bin.gz; \
+	echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub; \
+	${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub
 
 EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@}
 EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.ub@}
 EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin.gz@}
-
+EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.gz.ub@}

Index: src/sys/arch/evbarm/conf/std.nitrogen6
diff -u src/sys/arch/evbarm/conf/std.nitrogen6:1.10 src/sys/arch/evbarm/conf/std.nitrogen6:1.11
--- src/sys/arch/evbarm/conf/std.nitrogen6:1.10	Sat May 18 08:49:23 2019
+++ src/sys/arch/evbarm/conf/std.nitrogen6	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: std.nitrogen6,v 1.10 2019/05/18 08:49:23 skrll Exp $
+#	$NetBSD: std.nitrogen6,v 1.11 2019/07/24 12:33:18 hkenken Exp $
 #
 # standard NetBSD/evbarm options for Nitrogen6X
 
@@ -25,10 +25,6 @@ options 	__HAVE_FAST_SOFTINTS		# should 
 options 	__HAVE_GENERIC_START
 
 makeoptions 	BOARDMKFRAG="${THISARM}/conf/mk.nitrogen6"
-makeoptions 	CPPFLAGS+="-I$S/../../../include"
-makeoptions 	CPUFLAGS="-mcpu=cortex-a9"
 
-# The physical address is chosen by u-boot and determined by armv6_start.S.
-# The 64 byte offset is due to u-boot header.
-makeoptions	KERNEL_BASE_PHYS="0x00000040"
-makeoptions	KERNEL_BASE_VIRT="0x80000040"
+makeoptions 	KERNEL_BASE_PHYS="0x18000040"
+makeoptions 	KERNEL_BASE_VIRT="0x80000040"

Index: src/sys/arch/evbarm/imx7/imx7_ioconfig.c
diff -u src/sys/arch/evbarm/imx7/imx7_ioconfig.c:1.2 src/sys/arch/evbarm/imx7/imx7_ioconfig.c:1.3
--- src/sys/arch/evbarm/imx7/imx7_ioconfig.c:1.2	Thu Mar 28 12:07:30 2019
+++ src/sys/arch/evbarm/imx7/imx7_ioconfig.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx7_ioconfig.c,v 1.2 2019/03/28 12:07:30 christos Exp $	*/
+/*	$NetBSD: imx7_ioconfig.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org>
@@ -26,9 +26,12 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx7_ioconfig.c,v 1.2 2019/03/28 12:07:30 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx7_ioconfig.c,v 1.3 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_evbarm_boardtype.h"
+
+#define	_INTR_PRIVATE
+
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/param.h>
@@ -190,7 +193,7 @@ static const struct iomux_conf iomux_dat
 #define GPIO_SETDIR(unit, pin, dir)					\
 	AIPS_WRITE(GPIO_ADDR(unit) + GPIO_DIR,				\
 	    (AIPS_READ(GPIO_ADDR(unit) + GPIO_DIR) & ~(1 << (pin))) |	\
-	    ((dir) << (pin)))
+	    ((dir == GPIO_PIN_OUTPUT) ? __BIT(pin) : 0))
 #define GPIO_WRITE(unit, pin, data)					\
 	AIPS_WRITE(GPIO_ADDR(unit) + GPIO_DR,				\
 	    (AIPS_READ(GPIO_ADDR(unit) + GPIO_DR) & ~(1 << (pin))) |	\
@@ -198,7 +201,7 @@ static const struct iomux_conf iomux_dat
 /* GPIO set dir & write data */
 #define GPIO_DIROUT_WRITE(unit, pin, data)				\
 	do {								\
-		GPIO_SETDIR(unit, pin, GPIO_DIR_OUT);			\
+		GPIO_SETDIR(unit, pin, GPIO_PIN_OUTPUT);		\
 		GPIO_WRITE(unit, pin, data);				\
 	} while (0 /* CONSTCOND */)
 

Index: src/sys/arch/evbarm/kobo/kobo_machdep.c
diff -u src/sys/arch/evbarm/kobo/kobo_machdep.c:1.7 src/sys/arch/evbarm/kobo/kobo_machdep.c:1.8
--- src/sys/arch/evbarm/kobo/kobo_machdep.c:1.7	Tue Jul 16 14:41:47 2019
+++ src/sys/arch/evbarm/kobo/kobo_machdep.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kobo_machdep.c,v 1.7 2019/07/16 14:41:47 skrll Exp $	*/
+/*	$NetBSD: kobo_machdep.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005, 2010  Genetec Corporation.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobo_machdep.c,v 1.7 2019/07/16 14:41:47 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobo_machdep.c,v 1.8 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -137,7 +137,6 @@ __KERNEL_RCSID(0, "$NetBSD: kobo_machdep
 #include <arm/imx/imxuartreg.h>
 #include <arm/imx/imxuartvar.h>
 #include <arm/imx/imx50_iomuxreg.h>
-#include <arm/imx/imxgpiovar.h>
 
 #include <evbarm/kobo/kobo.h>
 #include <evbarm/kobo/kobo_reg.h>

Index: src/sys/arch/evbarm/netwalker/netwalker_lcd.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.5 src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.6
--- src/sys/arch/evbarm/netwalker/netwalker_lcd.c:1.5	Mon Dec 21 04:26:29 2015
+++ src/sys/arch/evbarm/netwalker/netwalker_lcd.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_lcd.c,v 1.5 2015/12/21 04:26:29 hkenken Exp $	*/
+/*	$NetBSD: netwalker_lcd.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2011, 2012 Genetec corp. All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_lcd.c,v 1.5 2015/12/21 04:26:29 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_lcd.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_imx51_ipuv3.h"
 #include "opt_netwalker_lcd.h"
@@ -36,8 +36,11 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_lc
 #include "ioconf.h"
 #include "netwalker_backlight.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/param.h>
 #include <sys/device.h>
+#include <sys/gpio.h>
 
 #include <sys/bus.h>
 #include <arm/imx/imx51var.h>
@@ -140,17 +143,17 @@ void lcd_attach( device_t parent, device
 	}
 
 	/* LCD power on */
-	gpio_set_direction(GPIO_NO(4, 9), GPIO_DIR_OUT);
-	gpio_set_direction(GPIO_NO(4, 10), GPIO_DIR_OUT);
-	gpio_set_direction(GPIO_NO(3, 3), GPIO_DIR_OUT);
+	gpio_set_direction(GPIO_NO(4, 9), GPIO_PIN_OUTPUT);
+	gpio_set_direction(GPIO_NO(4, 10), GPIO_PIN_OUTPUT);
+	gpio_set_direction(GPIO_NO(3, 3), GPIO_PIN_OUTPUT);
 
-	gpio_data_write(GPIO_NO(3, 3), 1);
-	gpio_data_write(GPIO_NO(4, 9), 1);
+	gpio_data_write(GPIO_NO(3, 3), GPIO_PIN_HIGH);
+	gpio_data_write(GPIO_NO(4, 9), GPIO_PIN_HIGH);
 	delay(180 * 1000);
-	gpio_data_write(GPIO_NO(4, 10), 1);
+	gpio_data_write(GPIO_NO(4, 10), GPIO_PIN_HIGH);
 
-	gpio_set_direction(GPIO_NO(2, 13), GPIO_DIR_OUT);
-	gpio_data_write(GPIO_NO(2, 13), 1);
+	gpio_set_direction(GPIO_NO(2, 13), GPIO_PIN_OUTPUT);
+	gpio_data_write(GPIO_NO(2, 13), GPIO_PIN_HIGH);
 
 	imx51_ipuv3_attach_sub(sc, aux, &sharp_panel);
 
Index: src/sys/arch/evbarm/netwalker/netwalker_usb.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_usb.c:1.5 src/sys/arch/evbarm/netwalker/netwalker_usb.c:1.6
--- src/sys/arch/evbarm/netwalker/netwalker_usb.c:1.5	Wed Jul 24 11:20:55 2019
+++ src/sys/arch/evbarm/netwalker/netwalker_usb.c	Wed Jul 24 12:33:18 2019
@@ -25,7 +25,11 @@
  *
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_usb.c,v 1.5 2019/07/24 11:20:55 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_usb.c,v 1.6 2019/07/24 12:33:18 hkenken Exp $");
+
+#include "locators.h"
+
+#define	_INTR_PRIVATE
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -34,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_us
 #include <sys/device.h>
 #include <sys/intr.h>
 #include <sys/bus.h>
+#include <sys/gpio.h>
 
 #include <dev/usb/usb.h>
 #include <dev/usb/usbdi.h>
@@ -49,7 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_us
 #include <arm/imx/imxusbvar.h>
 #include <arm/imx/imx51_iomuxreg.h>
 #include <arm/imx/imxgpiovar.h>
-#include "locators.h"
 
 struct netwalker_usbc_softc {
 	struct imxusbc_softc sc_imxusbc; /* Must be first */
@@ -145,8 +149,8 @@ init_h1(struct imxehci_softc *sc)
 	uint32_t reg;
 
 	/* output HIGH to USBH1_STP */
-	gpio_data_write(GPIO_NO(1, 27), 1);
-	gpio_set_direction(GPIO_NO(1, 27), GPIO_DIR_OUT);
+	gpio_data_write(GPIO_NO(1, 27), GPIO_PIN_HIGH);
+	gpio_set_direction(GPIO_NO(1, 27), GPIO_PIN_OUTPUT);
 
 	iomux_mux_config(iomux_usb1_config);
 
@@ -178,21 +182,21 @@ init_h1(struct imxehci_softc *sc)
 
 
 	/* HUB RESET release */
-	gpio_data_write(GPIO_NO(1, 7), 1);
-	gpio_set_direction(GPIO_NO(1, 7), GPIO_DIR_OUT);
+	gpio_data_write(GPIO_NO(1, 7), GPIO_PIN_HIGH);
+	gpio_set_direction(GPIO_NO(1, 7), GPIO_PIN_OUTPUT);
 
 	/* Drive 26M_OSC_EN line high 3_1 */
-	gpio_data_write(GPIO_NO(3, 1), 1);
-	gpio_set_direction(GPIO_NO(3, 1), GPIO_DIR_OUT);
+	gpio_data_write(GPIO_NO(3, 1), GPIO_PIN_HIGH);
+	gpio_set_direction(GPIO_NO(3, 1), GPIO_PIN_OUTPUT);
 
 	/* Drive USB_CLK_EN_B line low  2_1 */
-	gpio_data_write(GPIO_NO(2, 1), 0);
-	gpio_set_direction(GPIO_NO(2, 1), GPIO_DIR_IN);
+	gpio_data_write(GPIO_NO(2, 1), GPIO_PIN_LOW);
+	gpio_set_direction(GPIO_NO(2, 1), GPIO_PIN_INPUT);
 
 	/* MX51_PIN_EIM_D21 - De-assert USB PHY RESETB */
 	delay(10 * 1000);
-	gpio_data_write(GPIO_NO(2, 5), 1);
-	gpio_set_direction(GPIO_NO(2, 5), GPIO_DIR_OUT);
+	gpio_data_write(GPIO_NO(2, 5), GPIO_PIN_HIGH);
+	gpio_set_direction(GPIO_NO(2, 5), GPIO_PIN_OUTPUT);
 	iomux_set_function(MUX_PIN(EIM_D21), IOMUX_CONFIG_ALT1);
 	delay(5 * 1000);
 }

Index: src/sys/arch/evbarm/netwalker/netwalker_machdep.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.25 src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.26
--- src/sys/arch/evbarm/netwalker/netwalker_machdep.c:1.25	Tue Jul 16 14:41:47 2019
+++ src/sys/arch/evbarm/netwalker/netwalker_machdep.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_machdep.c,v 1.25 2019/07/16 14:41:47 skrll Exp $	*/
+/*	$NetBSD: netwalker_machdep.c,v 1.26 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005, 2010  Genetec Corporation.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.25 2019/07/16 14:41:47 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_machdep.c,v 1.26 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -145,7 +145,6 @@ __KERNEL_RCSID(0, "$NetBSD: netwalker_ma
 #include <arm/imx/imxuartreg.h>
 #include <arm/imx/imxuartvar.h>
 #include <arm/imx/imx51_iomuxreg.h>
-#include <arm/imx/imxgpiovar.h>
 
 #include <evbarm/netwalker/netwalker_reg.h>
 #include <evbarm/netwalker/netwalker.h>

Index: src/sys/arch/evbarm/netwalker/netwalker_spi.c
diff -u src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.1 src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.2
--- src/sys/arch/evbarm/netwalker/netwalker_spi.c:1.1	Sat Mar 29 12:00:27 2014
+++ src/sys/arch/evbarm/netwalker/netwalker_spi.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netwalker_spi.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $	*/
+/*	$NetBSD: netwalker_spi.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*-
  * Copyright (c) 2009  Genetec Corporation.  All rights reserved.
@@ -27,13 +27,16 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netwalker_spi.c,v 1.1 2014/03/29 12:00:27 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netwalker_spi.c,v 1.2 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_imxspi.h"
 
+#define	_INTR_PRIVATE
+
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/device.h>
+#include <sys/gpio.h>
 
 #include <arm/imx/imx51reg.h>
 #include <arm/imx/imx51var.h>
@@ -56,16 +59,16 @@ imxspi_cs_enable(void *arg, int slave)
 {
 	switch (slave) {
 	case 0:
-		gpio_data_write(GPIO_NO(4, 24), 0);
-		gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_OUT);
+		gpio_data_write(GPIO_NO(4, 24), GPIO_PIN_LOW);
+		gpio_set_direction(GPIO_NO(4, 24), GPIO_PIN_OUTPUT);
 		break;
 	case 1:
-		gpio_data_write(GPIO_NO(4, 25), 0);
-		gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_OUT);
+		gpio_data_write(GPIO_NO(4, 25), GPIO_PIN_LOW);
+		gpio_set_direction(GPIO_NO(4, 25), GPIO_PIN_OUTPUT);
 		break;
 	case 2:
-		gpio_data_write(GPIO_NO(3, 0), 0);
-		gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_OUT);
+		gpio_data_write(GPIO_NO(3, 0), GPIO_PIN_LOW);
+		gpio_set_direction(GPIO_NO(3, 0), GPIO_PIN_OUTPUT);
 		break;
 	}
 
@@ -77,16 +80,16 @@ imxspi_cs_disable(void *arg, int slave)
 {
 	switch (slave) {
 	case 0:
-		gpio_data_write(GPIO_NO(4, 24), 1);
-		gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_IN);
+		gpio_data_write(GPIO_NO(4, 24), GPIO_PIN_HIGH);
+		gpio_set_direction(GPIO_NO(4, 24), GPIO_PIN_INPUT);
 		break;
 	case 1:
-		gpio_data_write(GPIO_NO(4, 25), 1);
-		gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_IN);
+		gpio_data_write(GPIO_NO(4, 25), GPIO_PIN_HIGH);
+		gpio_set_direction(GPIO_NO(4, 25), GPIO_PIN_INPUT);
 		break;
 	case 2:
-		gpio_data_write(GPIO_NO(3, 0), 1);
-		gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_IN);
+		gpio_data_write(GPIO_NO(3, 0), GPIO_PIN_HIGH);
+		gpio_set_direction(GPIO_NO(3, 0), GPIO_PIN_INPUT);
 		break;
 	}
 
@@ -116,21 +119,21 @@ imxspi_attach(device_t parent, device_t 
 
 	if (device_cfdata(self)->cf_unit == 0) {
 		/* CS 0 GPIO setting */
-		gpio_data_write(GPIO_NO(4, 24), 1);
-		gpio_set_direction(GPIO_NO(4, 24), GPIO_DIR_IN);
+		gpio_data_write(GPIO_NO(4, 24), GPIO_PIN_HIGH);
+		gpio_set_direction(GPIO_NO(4, 24), GPIO_PIN_INPUT);
 
 		/* CS 1 GPIO setting */
-		gpio_data_write(GPIO_NO(4, 25), 1);
-		gpio_set_direction(GPIO_NO(4, 25), GPIO_DIR_IN);
+		gpio_data_write(GPIO_NO(4, 25), GPIO_PIN_HIGH);
+		gpio_set_direction(GPIO_NO(4, 25), GPIO_PIN_INPUT);
 
 		/* CS 2 */
 		/* OJ6SH-T25 Shutdown */
-		gpio_data_write(GPIO_NO(3, 14), 0);
-		gpio_set_direction(GPIO_NO(3, 14), GPIO_DIR_OUT);
+		gpio_data_write(GPIO_NO(3, 14), GPIO_PIN_LOW);
+		gpio_set_direction(GPIO_NO(3, 14), GPIO_PIN_OUTPUT);
 
 		/* CS 2 GPIO setting */
-		gpio_data_write(GPIO_NO(3, 0), 1);
-		gpio_set_direction(GPIO_NO(3, 0), GPIO_DIR_IN);
+		gpio_data_write(GPIO_NO(3, 0), GPIO_PIN_HIGH);
+		gpio_set_direction(GPIO_NO(3, 0), GPIO_PIN_INPUT);
 
 		sc->sc_tag.spi_cs_enable = imxspi_cs_enable;
 		sc->sc_tag.spi_cs_disable = imxspi_cs_disable;

Index: src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c
diff -u src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c:1.4 src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c:1.5
--- src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c:1.4	Fri Jun  9 18:14:59 2017
+++ src/sys/arch/evbarm/nitrogen6/nitrogen6_iomux.c	Wed Jul 24 12:33:18 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: nitrogen6_iomux.c,v 1.4 2017/06/09 18:14:59 ryo Exp $	*/
+/*	$NetBSD: nitrogen6_iomux.c,v 1.5 2019/07/24 12:33:18 hkenken Exp $	*/
 
 /*
  * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org>
@@ -26,17 +26,23 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nitrogen6_iomux.c,v 1.4 2017/06/09 18:14:59 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nitrogen6_iomux.c,v 1.5 2019/07/24 12:33:18 hkenken Exp $");
 
 #include "opt_evbarm_boardtype.h"
+
+#define	_INTR_PRIVATE
+
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/param.h>
+#include <sys/gpio.h>
+
 #include <arm/imx/imx6_reg.h>
 #include <arm/imx/imx6var.h>
 #include <arm/imx/imx6_iomuxreg.h>
 #include <arm/imx/imxgpioreg.h>
 #include <arm/imx/imxgpiovar.h>
+
 #include <evbarm/nitrogen6/platform.h>
 
 struct gpio_conf {
@@ -537,41 +543,41 @@ static const struct iomux_conf iomux_dat
 static const struct gpio_conf gpio_data[] = {
 	/*	GPIOn, PIN,	dir,		value	*/
 #if (EVBARM_BOARDTYPE == nitrogen6x)
-	{	3,	22,	GPIO_DIR_OUT,	1	}, /* USB OTG */
-	{	7,	0,	GPIO_DIR_IN,	0	}, /* SD3 CD */
-	{	2,	6,	GPIO_DIR_IN,	0	}, /* SD4 CD */
+	{	3,	22,	GPIO_PIN_OUTPUT,	1	}, /* USB OTG */
+	{	7,	0,	GPIO_PIN_INPUT,		0	}, /* SD3 CD */
+	{	2,	6,	GPIO_PIN_INPUT,		0	}, /* SD4 CD */
 #endif
 #if (EVBARM_BOARDTYPE == nitrogen6max)
-	{	3,	22,	GPIO_DIR_OUT,	1	}, /* USB OTG */
-	{	7,	12,	GPIO_DIR_OUT,	1	}, /* USB HUB RESET */
-	{	6,	14,	GPIO_DIR_OUT,	1	}, /* SD3 VSELECT */
-	{	7,	0,	GPIO_DIR_IN,	0	}, /* SD3 CD */
-	{	2,	6,	GPIO_DIR_IN,	0	}, /* SD4 CD */
+	{	3,	22,	GPIO_PIN_OUTPUT,	1	}, /* USB OTG */
+	{	7,	12,	GPIO_PIN_OUTPUT,	1	}, /* USB HUB RESET */
+	{	6,	14,	GPIO_PIN_OUTPUT,	1	}, /* SD3 VSELECT */
+	{	7,	0,	GPIO_PIN_INPUT,		0	}, /* SD3 CD */
+	{	2,	6,	GPIO_PIN_INPUT,		0	}, /* SD4 CD */
 #endif
 #if (EVBARM_BOARDTYPE == cubox_i)
-	{	4,	29,	GPIO_DIR_OUT,	1	}, /* FRONT LED? */
-	{	3,	22,	GPIO_DIR_OUT,	1	}, /* USB OTG */
-	{	1,	0,	GPIO_DIR_OUT,	1	}, /* USB H1 */
-	{	1,	4,	GPIO_DIR_IN,	0	}, /* USDHC2 */
+	{	4,	29,	GPIO_PIN_OUTPUT,	1	}, /* FRONT LED? */
+	{	3,	22,	GPIO_PIN_OUTPUT,	1	}, /* USB OTG */
+	{	1,	0,	GPIO_PIN_OUTPUT,	1	}, /* USB H1 */
+	{	1,	4,	GPIO_PIN_INPUT,		0	}, /* USDHC2 */
 #endif
 #if (EVBARM_BOARDTYPE == hummingboard)
-	{	3,	22,	GPIO_DIR_OUT,	1	}, /* USB OTG */
-	{	1,	0,	GPIO_DIR_OUT,	1	}, /* USB H1 */
-	{	1,	4,	GPIO_DIR_IN,	0	}, /* USDHC2 */
-	{	3,	4,	GPIO_DIR_OUT,	0	}, /* PCIe */
+	{	3,	22,	GPIO_PIN_OUTPUT,	1	}, /* USB OTG */
+	{	1,	0,	GPIO_PIN_OUTPUT,	1	}, /* USB H1 */
+	{	1,	4,	GPIO_PIN_INPUT,		0	}, /* USDHC2 */
+	{	3,	4,	GPIO_PIN_OUTPUT,	0	}, /* PCIe */
 #endif
 #if (EVBARM_BOARDTYPE == hummingboard_edge)
-	{	3,	22,	GPIO_DIR_OUT,	1	}, /* USB OTG */
-	{	1,	0,	GPIO_DIR_OUT,	1	}, /* USB H1 */
-	{	1,	4,	GPIO_DIR_IN,	0	}, /* USDHC2 */
-	{	2,	11,	GPIO_DIR_OUT,	0	}, /* PCIe */
+	{	3,	22,	GPIO_PIN_OUTPUT,	1	}, /* USB OTG */
+	{	1,	0,	GPIO_PIN_OUTPUT,	1	}, /* USB H1 */
+	{	1,	4,	GPIO_PIN_INPUT,		0	}, /* USDHC2 */
+	{	2,	11,	GPIO_PIN_OUTPUT,	0	}, /* PCIe */
 #endif
 #if (EVBARM_BOARDTYPE == ccimx6ulstarter)
-	{	3,	2,	GPIO_DIR_OUT,	1	}, /* ENET1 phy */
+	{	3,	2,	GPIO_PIN_OUTPUT,	1	}, /* ENET1 phy */
 #endif
 
 	/* end of table */
-	{	0,	0,	0,		0	},
+	{	0,	0,	0,			0	},
 };
 
 
@@ -615,10 +621,10 @@ nitrogen6_gpio_config(const struct gpio_
 	const struct gpio_conf *c;
 
 	for (c = conflist; c->group != 0; c++) {
-		if (c->dir == GPIO_DIR_IN) {
+		if (c->dir == GPIO_PIN_INPUT) {
 			*AIPS1_ADDR(GPIO_ADDR(c->group, GPIO_DIR)) &=
 			    ~(1 << c->pin);
-		} else if (c->dir == GPIO_DIR_OUT) {
+		} else if (c->dir == GPIO_PIN_OUTPUT) {
 			*AIPS1_ADDR(GPIO_ADDR(c->group, GPIO_DIR)) |=
 			    (1 << c->pin);
 

Added files:

Index: src/sys/arch/arm/imx/imxpcie.c
diff -u /dev/null src/sys/arch/arm/imx/imxpcie.c:1.1
--- /dev/null	Wed Jul 24 12:33:19 2019
+++ src/sys/arch/arm/imx/imxpcie.c	Wed Jul 24 12:33:18 2019
@@ -0,0 +1,798 @@
+/*	$NetBSD: imxpcie.c,v 1.1 2019/07/24 12:33:18 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2019  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * i.MX6 On-Chip PCI Express Controller
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imxpcie.c,v 1.1 2019/07/24 12:33:18 hkenken Exp $");
+
+#include "opt_pci.h"
+#include "opt_fdt.h"
+
+#include "pci.h"
+#include "locators.h"
+
+#define	_INTR_PRIVATE
+
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/extent.h>
+#include <sys/queue.h>
+#include <sys/mutex.h>
+#include <sys/kmem.h>
+
+#include <machine/frame.h>
+#include <arm/cpufunc.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pciconf.h>
+#include <dev/clk/clk_backend.h>
+
+#include <arm/imx/imxpciereg.h>
+#include <arm/imx/imxpcievar.h>
+#include <arm/imx/imx6var.h>
+#include <arm/imx/imx6_iomuxreg.h>
+
+#define PCIE_CONF_LOCK(s)	(s) = disable_interrupts(I32_bit)
+#define PCIE_CONF_UNLOCK(s)	restore_interrupts((s))
+
+#define PCIE_READ(sc, reg)					\
+	bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, reg)
+#define PCIE_WRITE(sc, reg, val)				\
+	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, reg, val)
+
+static void imxpcie_init(pci_chipset_tag_t, void *);
+static void imxpcie_setup(struct imxpcie_softc * const);
+
+static void imxpcie_attach_hook(device_t, device_t, struct pcibus_attach_args *);
+static int imxpcie_bus_maxdevs(void *, int);
+static pcitag_t imxpcie_make_tag(void *, int, int, int);
+static void imxpcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
+static pcireg_t imxpcie_conf_read(void *, pcitag_t, int);
+static void imxpcie_conf_write(void *, pcitag_t, int, pcireg_t);
+#ifdef __HAVE_PCI_CONF_HOOK
+static int imxpcie_conf_hook(void *, int, int, int, pcireg_t);
+#endif
+static void imxpcie_conf_interrupt(void *, int, int, int, int, int *);
+
+static int imxpcie_intr_map(const struct pci_attach_args *, pci_intr_handle_t *);
+static const char *imxpcie_intr_string(void *, pci_intr_handle_t, char *, size_t);
+const struct evcnt *imxpcie_intr_evcnt(void *, pci_intr_handle_t);
+static void * imxpcie_intr_establish(void *, pci_intr_handle_t, int,
+    int (*)(void *), void *, const char *);
+static void imxpcie_intr_disestablish(void *, void *);
+
+static int
+imxpcie_linkup_status(struct imxpcie_softc *sc)
+{
+	return PCIE_READ(sc, PCIE_PL_DEBUG1) & PCIE_PL_DEBUG1_XMLH_LINK_UP;
+}
+
+static int
+imxpcie_valid_device(struct imxpcie_softc *sc, int bus, int dev)
+{
+	if (bus != 0 && !imxpcie_linkup_status(sc))
+		return 0;
+	if (bus <= 1 && dev > 0)
+		return 0;
+
+	return 1;
+}
+
+static int
+imxpcie_init_phy(struct imxpcie_softc *sc)
+{
+	uint32_t v;
+
+	/* initialize IOMUX */
+	v = sc->sc_gpr_read(sc, IOMUX_GPR12);
+	v &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
+	sc->sc_gpr_write(sc, IOMUX_GPR12, v);
+
+	v &= ~IOMUX_GPR12_LOS_LEVEL;
+	v |= __SHIFTIN(9, IOMUX_GPR12_LOS_LEVEL);
+	sc->sc_gpr_write(sc, IOMUX_GPR12, v);
+
+	v = 0;
+	v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_LOW);
+	v |= __SHIFTIN(0x7f, IOMUX_GPR8_PCS_TX_SWING_FULL);
+	v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_6DB);
+	v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB);
+	v |= __SHIFTIN(20, IOMUX_GPR8_PCS_TX_DEEMPH_GEN1);
+	sc->sc_gpr_write(sc, IOMUX_GPR8, v);
+
+	v &= ~IOMUX_GPR12_DEVICE_TYPE;
+	v |= IOMUX_GPR12_DEVICE_TYPE_PCIE_RC;
+	sc->sc_gpr_write(sc, IOMUX_GPR12, v);
+
+	return 0;
+}
+
+static int
+imxpcie_phy_wait_ack(struct imxpcie_softc *sc, int ack)
+{
+	uint32_t v;
+	int timeout;
+
+	for (timeout = 10; timeout > 0; --timeout) {
+		v = PCIE_READ(sc, PCIE_PL_PHY_STATUS);
+		if (!!(v & PCIE_PL_PHY_STATUS_ACK) == !!ack)
+			return 0;
+		delay(1);
+	}
+
+	return -1;
+}
+
+static int
+imxpcie_phy_addr(struct imxpcie_softc *sc, uint32_t addr)
+{
+	uint32_t v;
+
+	v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA);
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v);
+
+	v |= PCIE_PL_PHY_CTRL_CAP_ADR;
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v);
+
+	if (imxpcie_phy_wait_ack(sc, 1))
+		return -1;
+
+	v = __SHIFTIN(addr, PCIE_PL_PHY_CTRL_DATA);
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, v);
+
+	if (imxpcie_phy_wait_ack(sc, 0))
+		return -1;
+
+	return 0;
+}
+
+static int
+imxpcie_phy_write(struct imxpcie_softc *sc, uint32_t addr, uint16_t data)
+{
+	/* write address */
+	if (imxpcie_phy_addr(sc, addr) != 0)
+		return -1;
+
+	/* store data */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA));
+
+	/* assert CAP_DAT and wait ack */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA) | PCIE_PL_PHY_CTRL_CAP_DAT);
+	if (imxpcie_phy_wait_ack(sc, 1))
+		return -1;
+
+	/* deassert CAP_DAT and wait ack */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA));
+	if (imxpcie_phy_wait_ack(sc, 0))
+		return -1;
+
+	/* assert WR and wait ack */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_WR);
+	if (imxpcie_phy_wait_ack(sc, 1))
+		return -1;
+
+	/* deassert WR and wait ack */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, __SHIFTIN(data, PCIE_PL_PHY_CTRL_DATA));
+	if (imxpcie_phy_wait_ack(sc, 0))
+		return -1;
+
+	/* done */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0);
+
+	return 0;
+}
+
+static int
+imxpcie_phy_read(struct imxpcie_softc *sc, uint32_t addr)
+{
+	uint32_t v;
+
+	/* write address */
+	if (imxpcie_phy_addr(sc, addr) != 0)
+		return -1;
+
+	/* assert RD */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, PCIE_PL_PHY_CTRL_RD);
+	if (imxpcie_phy_wait_ack(sc, 1))
+		return -1;
+
+	/* read data */
+	v = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_PHY_STATUS),
+	    PCIE_PL_PHY_STATUS_DATA);
+
+	/* deassert RD */
+	PCIE_WRITE(sc, PCIE_PL_PHY_CTRL, 0);
+	if (imxpcie_phy_wait_ack(sc, 0))
+		return -1;
+
+	return v;
+}
+
+static int
+imxpcie_assert_core_reset(struct imxpcie_softc *sc)
+{
+	uint32_t gpr1;
+	uint32_t gpr12;
+
+	gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
+	gpr12 = sc->sc_gpr_read(sc, IOMUX_GPR12);
+
+	/* already enabled by bootloader */
+	if ((gpr1 & IOMUX_GPR1_REF_SSP_EN) &&
+	    (gpr12 & IOMUX_GPR12_APP_LTSSM_ENABLE)) {
+		uint32_t v = PCIE_READ(sc, PCIE_PL_PFLR);
+		v &= ~PCIE_PL_PFLR_LINK_STATE;
+		v |= PCIE_PL_PFLR_FORCE_LINK;
+		PCIE_WRITE(sc, PCIE_PL_PFLR, v);
+
+		gpr12 &= ~IOMUX_GPR12_APP_LTSSM_ENABLE;
+		sc->sc_gpr_write(sc, IOMUX_GPR12, gpr12);
+	}
+
+#if defined(IMX6DQP)
+	gpr1 |= IOMUX_GPR1_PCIE_SW_RST;
+	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+#endif
+
+	gpr1 |= IOMUX_GPR1_TEST_POWERDOWN;
+	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+	gpr1 &= ~IOMUX_GPR1_REF_SSP_EN;
+	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+
+	return 0;
+}
+
+static int
+imxpcie_deassert_core_reset(struct imxpcie_softc *sc)
+{
+	int error;
+
+	error = clk_enable(sc->sc_clk_pcie_axi);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "couldn't enable pcie_axi: %d\n", error);
+		return error;
+	}
+	error = clk_enable(sc->sc_clk_lvds1_gate);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "couldn't enable lvds1_gate: %d\n", error);
+		return error;
+	}
+	error = clk_enable(sc->sc_clk_pcie_ref);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "couldn't enable pcie_ref: %d\n", error);
+		return error;
+	}
+
+	uint32_t gpr1 = sc->sc_gpr_read(sc, IOMUX_GPR1);
+
+#if defined(IMX6DQP)
+	gpr1 &= ~IOMUX_GPR1_PCIE_SW_RST;
+	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+#endif
+
+	delay(50 * 1000);
+
+	gpr1 &= ~IOMUX_GPR1_TEST_POWERDOWN;
+	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+	delay(10);
+	gpr1 |= IOMUX_GPR1_REF_SSP_EN;
+	sc->sc_gpr_write(sc, IOMUX_GPR1, gpr1);
+
+	delay(50 * 1000);
+
+	/* Reset */
+	if (sc->sc_reset != NULL)
+		sc->sc_reset(sc);
+
+	return 0;
+}
+
+static int
+imxpcie_wait_for_link(struct imxpcie_softc *sc)
+{
+#define LINKUP_RETRY	20000
+	for (int retry = LINKUP_RETRY; retry > 0; --retry) {
+		if (!imxpcie_linkup_status(sc)) {
+			delay(10);
+			continue;
+		}
+
+		uint32_t valid = imxpcie_phy_read(sc, PCIE_PHY_RX_ASIC_OUT) &
+		    PCIE_PHY_RX_ASIC_OUT_VALID;
+		uint32_t ltssm = __SHIFTOUT(PCIE_READ(sc, PCIE_PL_DEBUG0),
+		    PCIE_PL_DEBUG0_XMLH_LTSSM_STATE);
+
+		if ((ltssm == 0x0d) && !valid) {
+			aprint_normal_dev(sc->sc_dev, "resetting PCIe phy\n");
+
+			uint32_t v = imxpcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO);
+			v |= PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD;
+			v |= PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD;
+			imxpcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v);
+
+			delay(3000);
+
+			v = imxpcie_phy_read(sc, PCIE_PHY_RX_OVRD_IN_LO);
+			v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD;
+			v &= ~PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD;
+			imxpcie_phy_write(sc, PCIE_PHY_RX_OVRD_IN_LO, v);
+		}
+
+		return 0;
+	}
+
+	aprint_error_dev(sc->sc_dev, "Link Up failed.\n");
+
+	return -1;
+}
+
+static int
+imxpcie_wait_for_changespeed(struct imxpcie_softc *sc)
+{
+#define CHANGESPEED_RETRY	200
+	for (int retry = CHANGESPEED_RETRY; retry > 0; --retry) {
+		uint32_t v = PCIE_READ(sc, PCIE_PL_G2CR);
+		if (!(v & PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE))
+			return 0;
+		delay(100);
+	}
+
+	aprint_error_dev(sc->sc_dev, "Speed change timeout.\n");
+
+	return -1;
+}
+
+static void
+imxpcie_linkup(struct imxpcie_softc *sc)
+{
+	uint32_t v;
+	int ret;
+
+	imxpcie_assert_core_reset(sc);
+	imxpcie_init_phy(sc);
+	imxpcie_deassert_core_reset(sc);
+
+	imxpcie_setup(sc);
+
+	/* GEN1 Operation */
+	v = PCIE_READ(sc, PCIE_RC_LCR);
+	v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS;
+	v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1;
+	PCIE_WRITE(sc, PCIE_RC_LCR, v);
+
+	/* Link Up */
+	v = sc->sc_gpr_read(sc, IOMUX_GPR12);
+	v |= IOMUX_GPR12_APP_LTSSM_ENABLE;
+	sc->sc_gpr_write(sc, IOMUX_GPR12, v);
+
+	ret = imxpcie_wait_for_link(sc);
+	if (ret)
+		goto error;
+
+	/* Allow Gen2 mode */
+	v = PCIE_READ(sc, PCIE_RC_LCR);
+	v &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS;
+	v |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2;
+	PCIE_WRITE(sc, PCIE_RC_LCR, v);
+
+	/* Change speed */
+	v = PCIE_READ(sc, PCIE_PL_G2CR);
+	v |= PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE;
+	PCIE_WRITE(sc, PCIE_PL_G2CR, v);
+
+	ret = imxpcie_wait_for_changespeed(sc);
+	if (ret)
+		goto error;
+
+	ret = imxpcie_wait_for_link(sc);
+	if (ret)
+		goto error;
+
+	v = PCIE_READ(sc, PCIE_RC_LCSR);
+	aprint_normal_dev(sc->sc_dev, "LinkUp, Gen %d\n",
+	    (int)__SHIFTOUT(v, PCIE_RC_LCSR_LINK_SPEED));
+
+	return;
+
+error:
+	aprint_error_dev(sc->sc_dev, "PCIE_PL_DEBUG0,1 = %08x, %08x\n",
+	    PCIE_READ(sc, PCIE_PL_DEBUG0), PCIE_READ(sc, PCIE_PL_DEBUG1));
+
+	return;
+}
+
+void
+imxpcie_attach_common(struct imxpcie_softc * const sc)
+{
+	struct pcibus_attach_args pba;
+
+	if (bus_space_map(sc->sc_iot, sc->sc_root_addr, sc->sc_root_size, 0,
+		&sc->sc_root_ioh)) {
+		aprint_error_dev(sc->sc_dev, "Cannot map root config\n");
+		return;
+	}
+
+	imxpcie_linkup(sc);
+
+	TAILQ_INIT(&sc->sc_intrs);
+	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
+
+	imxpcie_init(&sc->sc_pc, sc);
+
+	if (sc->sc_pci_netbsd_configure != NULL)
+		sc->sc_pci_netbsd_configure(sc);
+
+	memset(&pba, 0, sizeof(pba));
+	pba.pba_flags = PCI_FLAGS_MEM_OKAY |
+	    PCI_FLAGS_IO_OKAY;
+	pba.pba_iot = sc->sc_iot;
+	pba.pba_memt = sc->sc_iot;
+	pba.pba_dmat = sc->sc_dmat;
+	pba.pba_pc = &sc->sc_pc;
+	pba.pba_bus = 0;
+
+	config_found_ia(sc->sc_dev, "pcibus", &pba, pcibusprint);
+}
+
+int
+imxpcie_intr(void *priv)
+{
+	struct imxpcie_softc *sc = priv;
+	struct imxpcie_ih *pcie_ih;
+
+	for (int i = 0; i < 8; i++) {
+		uint32_t v = PCIE_READ(sc, PCIE_PL_MSICIN_STATUS + i * 0xC);
+		int bit;
+		while ((bit = ffs(v) - 1) >= 0) {
+			PCIE_WRITE(sc, PCIE_PL_MSICIN_STATUS + i * 0xC,
+			    __BIT(bit));
+			v &= ~__BIT(bit);
+		}
+	}
+
+	mutex_enter(&sc->sc_lock);
+	int rv = 0;
+	const u_int lastgen = sc->sc_intrgen;
+	TAILQ_FOREACH(pcie_ih, &sc->sc_intrs, ih_entry) {
+		int (*callback)(void *) = pcie_ih->ih_handler;
+		void *arg = pcie_ih->ih_arg;
+		mutex_exit(&sc->sc_lock);
+		rv += callback(arg);
+		mutex_enter(&sc->sc_lock);
+		if (lastgen != sc->sc_intrgen)
+			break;
+	}
+	mutex_exit(&sc->sc_lock);
+
+	return rv;
+}
+
+static void
+imxpcie_setup(struct imxpcie_softc * const sc)
+{
+	uint32_t v;
+
+	/* Setup RC */
+	v = PCIE_READ(sc, PCIE_PL_PLCR);
+	v &= ~PCIE_PL_PLCR_LINK_MODE_ENABLE;
+	v |= __SHIFTIN(1, PCIE_PL_PLCR_LINK_MODE_ENABLE);
+	PCIE_WRITE(sc, PCIE_PL_PLCR, v);
+
+	v = PCIE_READ(sc, PCIE_PL_G2CR);
+	v &= ~PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES;
+	v |= __SHIFTIN(1, PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES);
+	PCIE_WRITE(sc, PCIE_PL_G2CR, v);
+
+	/* BARs */
+	PCIE_WRITE(sc, PCI_BAR0, 0x00000004);
+	PCIE_WRITE(sc, PCI_BAR1, 0x00000000);
+
+	/* Interurupt pins */
+	v = PCIE_READ(sc, PCI_INTERRUPT_REG);
+	v &= ~(PCI_INTERRUPT_PIN_MASK << PCI_INTERRUPT_PIN_SHIFT);
+	v |= PCI_INTERRUPT_PIN_A << PCI_INTERRUPT_PIN_SHIFT;
+	PCIE_WRITE(sc, PCI_INTERRUPT_REG, v);
+
+	/* Bus number */
+	v = PCIE_READ(sc, PCI_BRIDGE_BUS_REG);
+	v &= ~(PCI_BRIDGE_BUS_SUBORDINATE | PCI_BRIDGE_BUS_SECONDARY |
+	    PCI_BRIDGE_BUS_PRIMARY);
+	v |= PCI_BRIDGE_BUS_NUM_SUBORDINATE(1);
+	v |= PCI_BRIDGE_BUS_NUM_SECONDARY(1);
+	v |= PCI_BRIDGE_BUS_NUM_PRIMARY(0);
+	PCIE_WRITE(sc, PCI_BRIDGE_BUS_REG, v);
+
+	/* Command register */
+	v = PCIE_READ(sc, PCI_COMMAND_STATUS_REG);
+	v |= PCI_COMMAND_IO_ENABLE |
+	    PCI_COMMAND_MEM_ENABLE |
+	    PCI_COMMAND_MASTER_ENABLE |
+	    PCI_COMMAND_SERR_ENABLE;
+	PCIE_WRITE(sc, PCI_COMMAND_STATUS_REG, v);
+
+	PCIE_WRITE(sc, PCI_CLASS_REG,
+	    PCI_CLASS_CODE(PCI_CLASS_BRIDGE,
+		PCI_SUBCLASS_BRIDGE_PCI,
+		PCI_INTERFACE_BRIDGE_PCI_PCI));
+
+	PCIE_WRITE(sc, PCIE_PL_IATUVR, 0);
+
+	PCIE_WRITE(sc, PCIE_PL_IATURLBA, sc->sc_root_addr);
+	PCIE_WRITE(sc, PCIE_PL_IATURUBA, 0);
+	PCIE_WRITE(sc, PCIE_PL_IATURLA, sc->sc_root_addr + sc->sc_root_size);
+
+	PCIE_WRITE(sc, PCIE_PL_IATURLTA, 0);
+	PCIE_WRITE(sc, PCIE_PL_IATURUTA, 0);
+	PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0);
+	PCIE_WRITE(sc, PCIE_PL_IATURC2, PCIE_PL_IATURC2_REGION_ENABLE);
+}
+
+void
+imxpcie_init(pci_chipset_tag_t pc, void *priv)
+{
+	pc->pc_conf_v = priv;
+	pc->pc_attach_hook = imxpcie_attach_hook;
+	pc->pc_bus_maxdevs = imxpcie_bus_maxdevs;
+	pc->pc_make_tag = imxpcie_make_tag;
+	pc->pc_decompose_tag = imxpcie_decompose_tag;
+	pc->pc_conf_read = imxpcie_conf_read;
+	pc->pc_conf_write = imxpcie_conf_write;
+#ifdef __HAVE_PCI_CONF_HOOK
+	pc->pc_conf_hook = imxpcie_conf_hook;
+#endif
+	pc->pc_conf_interrupt = imxpcie_conf_interrupt;
+
+	pc->pc_intr_v = priv;
+	pc->pc_intr_map = imxpcie_intr_map;
+	pc->pc_intr_string = imxpcie_intr_string;
+	pc->pc_intr_evcnt = imxpcie_intr_evcnt;
+	pc->pc_intr_establish = imxpcie_intr_establish;
+	pc->pc_intr_disestablish = imxpcie_intr_disestablish;
+}
+
+static void
+imxpcie_attach_hook(device_t parent, device_t self,
+    struct pcibus_attach_args *pba)
+{
+	/* nothing to do */
+}
+
+static int
+imxpcie_bus_maxdevs(void *v, int busno)
+{
+	return 32;
+}
+
+static pcitag_t
+imxpcie_make_tag(void *v, int b, int d, int f)
+{
+	return (b << 16) | (d << 11) | (f << 8);
+}
+
+static void
+imxpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
+{
+	if (bp)
+		*bp = (tag >> 16) & 0xff;
+	if (dp)
+		*dp = (tag >> 11) & 0x1f;
+	if (fp)
+		*fp = (tag >> 8) & 0x7;
+}
+
+/*
+ * work around.
+ * If there is no PCIe devices, DABT will be generated by read/write access to
+ * config area, so replace original DABT handler with simple jump-back one.
+ */
+extern u_int data_abort_handler_address;
+static bool data_abort_flag;
+static void
+imxpcie_data_abort_handler(trapframe_t *tf)
+{
+	data_abort_flag = true;
+	tf->tf_pc += 0x4;
+	return;
+}
+
+static pcireg_t
+imxpcie_conf_read(void *v, pcitag_t tag, int offset)
+{
+	struct imxpcie_softc *sc = v;
+	bus_space_handle_t bsh;
+	int b, d, f;
+	pcireg_t ret = -1;
+	int s;
+
+	imxpcie_decompose_tag(v, tag, &b, &d, &f);
+
+	if ((unsigned int)offset >= PCI_EXTCONF_SIZE)
+		return ret;
+	if (!imxpcie_valid_device(sc, b, d))
+		return ret;
+
+	PCIE_WRITE(sc, PCIE_PL_IATUVR, 0);
+	if (b < 2)
+		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0);
+	else
+		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1);
+
+	if (b == 0) {
+		bsh = sc->sc_ioh;
+	} else {
+		PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8);
+		bsh = sc->sc_root_ioh;
+	}
+	PCIE_READ(sc, PCIE_PL_IATURC2);
+
+	PCIE_CONF_LOCK(s);
+
+	u_int saved = data_abort_handler_address;
+	data_abort_handler_address = (u_int)imxpcie_data_abort_handler;
+	data_abort_flag = false;
+
+	ret = bus_space_read_4(sc->sc_iot, bsh, offset & ~0x3);
+
+	data_abort_handler_address = saved;
+
+	PCIE_CONF_UNLOCK(s);
+
+	if (data_abort_flag)
+		ret = -1;
+
+	return ret;
+}
+
+static void
+imxpcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
+{
+	struct imxpcie_softc *sc = v;
+	bus_space_handle_t bsh;
+	int b, d, f;
+	int s;
+
+	imxpcie_decompose_tag(v, tag, &b, &d, &f);
+
+	if ((unsigned int)offset >= PCI_EXTCONF_SIZE)
+		return;
+	if (!imxpcie_valid_device(sc, b, d))
+		return;
+
+	PCIE_WRITE(sc, PCIE_PL_IATUVR, 0);
+	if (b < 2)
+		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG0);
+	else
+		PCIE_WRITE(sc, PCIE_PL_IATURC1, PCIE_PL_IATURC1_TYPE_CFG1);
+
+	if (b == 0) {
+		bsh = sc->sc_ioh;
+	} else {
+		PCIE_WRITE(sc, PCIE_PL_IATURLTA, tag << 8);
+		bsh = sc->sc_root_ioh;
+	}
+	PCIE_READ(sc, PCIE_PL_IATURC2);
+
+	PCIE_CONF_LOCK(s);
+
+	u_int saved = data_abort_handler_address;
+	data_abort_handler_address = (u_int)imxpcie_data_abort_handler;
+
+	bus_space_write_4(sc->sc_iot, bsh, offset & ~0x3, val);
+
+	data_abort_handler_address = saved;
+
+	PCIE_CONF_UNLOCK(s);
+
+	return;
+}
+
+#ifdef __HAVE_PCI_CONF_HOOK
+static int
+imxpcie_conf_hook(void *v, int b, int d, int f, pcireg_t id)
+{
+	return PCI_CONF_DEFAULT;
+}
+#endif
+
+static void
+imxpcie_conf_interrupt(void *v, int bus, int dev, int ipin, int swiz,
+    int *ilinep)
+{
+	/* nothing to do */
+}
+
+static int
+imxpcie_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih)
+{
+	if (pa->pa_intrpin == 0)
+		return EINVAL;
+	*ih = pa->pa_intrpin;
+	return 0;
+}
+
+static const char *
+imxpcie_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
+{
+	if (ih == PCI_INTERRUPT_PIN_NONE)
+		return NULL;
+
+	snprintf(buf, len, "pci");
+
+	return buf;
+}
+
+const struct evcnt *
+imxpcie_intr_evcnt(void *v, pci_intr_handle_t ih)
+{
+	return NULL;
+}
+
+static void *
+imxpcie_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
+    int (*callback)(void *), void *arg, const char *xname)
+{
+	struct imxpcie_softc *sc = v;
+	struct imxpcie_ih *pcie_ih;
+
+	if (ih == 0)
+		return NULL;
+
+	pcie_ih = kmem_alloc(sizeof(*pcie_ih), KM_SLEEP);
+	pcie_ih->ih_handler = callback;
+	pcie_ih->ih_arg = arg;
+	pcie_ih->ih_ipl = ipl;
+
+	mutex_enter(&sc->sc_lock);
+	TAILQ_INSERT_TAIL(&sc->sc_intrs, pcie_ih, ih_entry);
+	sc->sc_intrgen++;
+	mutex_exit(&sc->sc_lock);
+
+	return pcie_ih;
+}
+
+static void
+imxpcie_intr_disestablish(void *v, void *vih)
+{
+	struct imxpcie_softc *sc = v;
+	struct imxpcie_ih *pcie_ih = vih;
+
+	mutex_enter(&sc->sc_lock);
+	TAILQ_REMOVE(&sc->sc_intrs, pcie_ih, ih_entry);
+	sc->sc_intrgen++;
+	mutex_exit(&sc->sc_lock);
+
+	kmem_free(pcie_ih, sizeof(*pcie_ih));
+}
Index: src/sys/arch/arm/imx/imxpciereg.h
diff -u /dev/null src/sys/arch/arm/imx/imxpciereg.h:1.1
--- /dev/null	Wed Jul 24 12:33:19 2019
+++ src/sys/arch/arm/imx/imxpciereg.h	Wed Jul 24 12:33:18 2019
@@ -0,0 +1,297 @@
+/*	$NetBSD: imxpciereg.h,v 1.1 2019/07/24 12:33:18 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2015 Ryo Shimizu <r...@nerv.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_IMX_IMX6_PCIEREG_H_
+#define _ARM_IMX_IMX6_PCIEREG_H_
+
+/* PCIe EP Mode Registers */
+#define PCIE_EP_DEVICEID			0x00000000
+#define PCIE_EP_COMMAND				0x00000004
+#define PCIE_EP_BIST				0x0000000c
+#define PCIE_EP_BAR0				0x00000010
+#define PCIE_EP_MASK0				0x00000010
+#define PCIE_EP_MASK1				0x00000014
+#define PCIE_EP_MASK2				0x00000018
+#define PCIE_EP_MASK3				0x0000001c
+#define PCIE_EP_CISP				0x00000028
+#define PCIE_EP_SSID				0x0000002c
+#define PCIE_EP_EROMBAR				0x00000030
+#define PCIE_EP_EROMMASK			0x00000030
+#define PCIE_EP_CAPPR				0x00000034
+#define PCIE_EP_ILR				0x0000003c
+#define PCIE_EP_AER				0x00000100
+#define PCIE_EP_UESR				0x00000104
+#define PCIE_EP_UEMR				0x00000108
+#define PCIE_EP_UESEVR				0x0000010c
+#define PCIE_EP_CESR				0x00000110
+#define PCIE_EP_CEMR				0x00000114
+#define PCIE_EP_ACCR				0x00000118
+#define PCIE_EP_HLR				0x0000011c
+#define PCIE_EP_VCECHR				0x00000140
+#define PCIE_EP_PVCCR1				0x00000144
+#define PCIE_EP_PVCCR2				0x00000148
+#define PCIE_EP_PVCCSR				0x0000014c
+#define PCIE_EP_VCRCR				0x00000150
+#define PCIE_EP_VCRCONR				0x00000154
+#define PCIE_EP_VCRSR				0x00000158
+
+/* PCIe RC Mode Registers */
+#define PCIE_RC_DEVICEID			0x00000000
+#define PCIE_RC_COMMAND				0x00000004
+#define PCIE_RC_REVID				0x00000008
+#define PCIE_RC_BIST				0x0000000c
+#define PCIE_RC_BAR0				0x00000010
+#define PCIE_RC_BAR1				0x00000014
+#define PCIE_RC_BNR				0x00000018
+#define PCIE_RC_IOBLSSR				0x0000001c
+#define PCIE_RC_MEM_BLR				0x00000020
+#define PCIE_RC_PREF_MEM_BLR			0x00000024
+#define PCIE_RC_PREF_BASE_U32			0x00000028
+#define PCIE_RC_PREF_LIM_U32			0x0000002c
+#define PCIE_RC_IO_BASE_LIM_U16			0x00000030
+#define PCIE_RC_CAPPR				0x00000034
+#define PCIE_RC_EROMBAR				0x00000038
+#define PCIE_RC_EROMMASK			0x00000038
+#define PCIE_RC_PMCR				0x00000040
+#define PCIE_RC_PMCSR				0x00000044
+#define PCIE_RC_CIDR				0x00000070
+#define PCIE_RC_DCR				0x00000074
+#define PCIE_RC_DCONR				0x00000078
+#define PCIE_RC_LCR				0x0000007c
+#define  PCIE_RC_LCR_MAX_LINK_SPEEDS		__BITS(3, 0)
+#define  PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1	__SHIFTIN(0x1, PCIE_RC_LCR_MAX_LINK_SPEEDS)
+#define  PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2	__SHIFTIN(0x2, PCIE_RC_LCR_MAX_LINK_SPEEDS)
+#define PCIE_RC_LCSR				0x00000080
+#define  PCIE_RC_LCSR_LINK_SPEED		__BITS(19, 16)
+#define PCIE_RC_SCR				0x00000084
+#define PCIE_RC_SCSR				0x00000088
+#define PCIE_RC_RCCR				0x0000008c
+#define PCIE_RC_RSR				0x00000090
+#define PCIE_RC_DCR2				0x00000094
+#define PCIE_RC_DCSR2				0x00000098
+#define PCIE_RC_LCR2				0x0000009c
+#define PCIE_RC_LCSR2				0x000000a0
+#define PCIE_RC_AER				0x00000100
+#define PCIE_RC_UESR				0x00000104
+#define PCIE_RC_UEMR				0x00000108
+#define PCIE_RC_UESEVR				0x0000010c
+#define PCIE_RC_CESR				0x00000110
+#define PCIE_RC_CEMR				0x00000114
+#define PCIE_RC_ACCR				0x00000118
+#define PCIE_RC_HLR				0x0000011c
+#define PCIE_RC_RECR				0x0000012c
+#define PCIE_RC_RESR				0x00000130
+#define PCIE_RC_ESIR				0x00000134
+#define PCIE_RC_VCECHR				0x00000140
+#define PCIE_RC_PVCCR1				0x00000144
+#define PCIE_RC_PVCCR2				0x00000148
+#define PCIE_RC_PVCCSR				0x0000014c
+#define PCIE_RC_VCRCR				0x00000150
+#define PCIE_RC_VCRCONR				0x00000154
+#define PCIE_RC_VCRSR				0x00000158
+
+/* PCIe Port Logic Registers */
+#define PCIE_PL_ALTRTR				0x00000700
+#define PCIE_PL_VSDR				0x00000704
+#define PCIE_PL_PFLR				0x00000708
+#define  PCIE_PL_PFLR_LOW_POWER_ENTRANCE_COUNT	__BITS(31, 24)
+#define  PCIE_PL_PFLR_LINK_STATE		__BITS(21, 16)
+#define  PCIE_PL_PFLR_FORCE_LINK		__BIT(15)
+#define  PCIE_PL_PFLR_LINK_NUMBER		__BITS(7, 0)
+#define PCIE_PL_AFLACR				0x0000070c
+#define PCIE_PL_PLCR				0x00000710
+#define  PCIE_PL_PLCR_LINK_MODE_ENABLE		__BITS(21, 16)
+#define PCIE_PL_LSR				0x00000714
+#define PCIE_PL_SNR				0x00000718
+#define PCIE_PL_STRFM1				0x0000071c
+#define PCIE_PL_STRFM2				0x00000720
+#define PCIE_PL_AMODNPSR			0x00000724
+#define PCIE_PL_DEBUG0				0x00000728
+#define  PCIE_PL_DEBUG0_XMLH_LTSSM_STATE	__BITS(0, 5)
+#define PCIE_PL_DEBUG1				0x0000072c
+#define  PCIE_PL_DEBUG1_XMLH_LINK_UP		__BIT(4)
+#define  PCIE_PL_DEBUG1_XMLH_LINK_IN_TRAINING	__BIT(29)
+#define PCIE_PL_TPFCSR				0x00000730
+#define PCIE_PL_TNFCSR				0x00000734
+#define PCIE_PL_TCFCSR				0x00000738
+#define PCIE_PL_QSR				0x0000073c
+#define PCIE_PL_VCTAR1				0x00000740
+#define PCIE_PL_VCTAR2				0x00000744
+#define PCIE_PL_VC0PRQC				0x00000748
+#define PCIE_PL_VC0NRQC				0x0000074c
+#define PCIE_PL_VC0CRQC				0x00000750
+#define PCIE_PL_VCNPRQC				0x00000754
+#define PCIE_PL_VCNNRQC				0x00000758
+#define PCIE_PL_VCNCRQC				0x0000075c
+#define PCIE_PL_VC0PBD				0x000007a8
+#define PCIE_PL_VC0NPBD				0x000007ac
+#define PCIE_PL_VC0CBD				0x000007b0
+#define PCIE_PL_VC1PBD				0x000007b4
+#define PCIE_PL_VC1NPBD				0x000007b8
+#define PCIE_PL_VC1CBD				0x000007bc
+#define PCIE_PL_G2CR				0x0000080c
+#define  PCIE_PL_G2CR_DIRECTED_SPEED_CHANGE	__BIT(17)
+#define  PCIE_PL_G2CR_PREDETERMINED_NUMBER_OF_LANES	__BITS(16, 8)
+#define PCIE_PL_PHY_STATUS			0x00000810
+#define  PCIE_PL_PHY_STATUS_ACK			__BIT(16)
+#define  PCIE_PL_PHY_STATUS_DATA		__BITS(0, 15)
+#define PCIE_PL_PHY_CTRL			0x00000814
+#define  PCIE_PL_PHY_CTRL_RD			__BIT(19)
+#define  PCIE_PL_PHY_CTRL_WR			__BIT(18)
+#define  PCIE_PL_PHY_CTRL_CAP_DAT		__BIT(17)
+#define  PCIE_PL_PHY_CTRL_CAP_ADR		__BIT(16)
+#define  PCIE_PL_PHY_CTRL_DATA			__BITS(0, 15)
+#define PCIE_PL_MRCCR0				0x00000818
+#define PCIE_PL_MRCCR1				0x0000081c
+#define PCIE_PL_MSICA				0x00000820
+#define PCIE_PL_MSICUA				0x00000824
+#define PCIE_PL_MSICIN_ENB			0x00000828
+#define PCIE_PL_MSICIN_MASK			0x0000082c
+#define PCIE_PL_MSICIN_STATUS			0x00000830
+#define PCIE_PL_MSICGPIO			0x00000888
+
+// ATU_R_BaseAddress 0x900
+#define PCIE_PL_IATUVR				0x00000900
+// ATU_VIEWPORT_R (ATU_R_BaseAddress + 0x0)
+
+#define PCIE_PL_IATURC1				0x00000904
+// ATU_REGION_CTRL1_R (ATU_R_BaseAddress + 0x4)
+#define  PCIE_PL_IATURC1_FUNC			__BITS(22, 20)
+#define  PCIE_PL_IATURC1_AT			__BITS(17, 16)
+#define  PCIE_PL_IATURC1_ATTR			__BITS(10, 9)
+#define  PCIE_PL_IATURC1_TD			__BIT(8)
+#define  PCIE_PL_IATURC1_TC			__BITS(7, 5)
+#define  PCIE_PL_IATURC1_TYPE			__BITS(4, 0)
+#define   PCIE_PL_IATURC1_TYPE_IO		__SHIFTIN(0, PCIE_PL_IATURC1_TYPE)
+#define   PCIE_PL_IATURC1_TYPE_MEM		__SHIFTIN(2, PCIE_PL_IATURC1_TYPE)
+#define   PCIE_PL_IATURC1_TYPE_CFG0		__SHIFTIN(4, PCIE_PL_IATURC1_TYPE)
+#define   PCIE_PL_IATURC1_TYPE_CFG1		__SHIFTIN(5, PCIE_PL_IATURC1_TYPE)
+
+#define PCIE_PL_IATURC2				0x00000908
+// ATU_REGION_CTRL2_R (ATU_R_BaseAddress + 0x8)
+#define  PCIE_PL_IATURC2_REGION_ENABLE		__BIT(31)
+
+#define PCIE_PL_IATURLBA			0x0000090c
+// ATU_REGION_LOWBASE_R (ATU_R_BaseAddress + 0xC)
+
+#define PCIE_PL_IATURUBA			0x00000910
+// ATU_REGION_UPBASE_R (ATU_R_BaseAddress + 0x10)
+
+#define PCIE_PL_IATURLA				0x00000914
+// ATU_REGION_LIMIT_ADDR_R (ATU_R_BaseAddress + 0x14)
+
+#define PCIE_PL_IATURLTA			0x00000918
+// ATU_REGION_LOW_TRGT_ADDR_R (ATU_R_BaseAddress + 0x18)
+
+#define PCIE_PL_IATURUTA			0x0000091c
+// ATU_REGION_UP_TRGT_ADDR_R (ATU_R_BaseAddress + 0x1C)
+
+/* PCIe PHY registers */
+#define PCIE_PHY_IDCODE_LO			0x0000
+#define PCIE_PHY_IDCODE_HI			0x0001
+#define PCIE_PHY_DEBUG				0x0002
+#define PCIE_PHY_RTUNE_DEBUG			0x0003
+#define PCIE_PHY_RTUNE_STAT			0x0004
+#define PCIE_PHY_SS_PHASE			0x0005
+#define PCIE_PHY_SS_FREQ			0x0006
+#define PCIE_PHY_ATEOVRD			0x0010
+#define PCIE_PHY_MPLL_OVRD_IN_LO		0x0011
+#define PCIE_PHY_MPLL_OVRD_IN_HI		0x0011
+#define PCIE_PHY_SSC_OVRD_IN			0x0013
+#define PCIE_PHY_BS_OVRD_IN			0x0014
+#define PCIE_PHY_LEVEL_OVRD_IN			0x0015
+#define PCIE_PHY_SUP_OVRD_OUT			0x0016
+#define PCIE_PHY_MPLL_ASIC_IN			0x0017
+#define PCIE_PHY_BS_ASIC_IN			0x0018
+#define PCIE_PHY_LEVEL_ASIC_IN			0x0019
+#define PCIE_PHY_SSC_ASIC_IN			0x001a
+#define PCIE_PHY_SUP_ASIC_OUT			0x001b
+#define PCIE_PHY_ATEOVRD_STATUS			0x001c
+#define PCIE_PHY_SCOPE_ENABLES			0x0020
+#define PCIE_PHY_SCOPE_SAMPLES			0x0021
+#define PCIE_PHY_SCOPE_COUNT			0x0022
+#define PCIE_PHY_SCOPE_CTL			0x0023
+#define PCIE_PHY_SCOPE_MASK_000			0x0024
+#define PCIE_PHY_SCOPE_MASK_001			0x0025
+#define PCIE_PHY_SCOPE_MASK_010			0x0026
+#define PCIE_PHY_SCOPE_MASK_011			0x0027
+#define PCIE_PHY_SCOPE_MASK_100			0x0028
+#define PCIE_PHY_SCOPE_MASK_101			0x0029
+#define PCIE_PHY_SCOPE_MASK_110			0x002a
+#define PCIE_PHY_SCOPE_MASK_111			0x002b
+#define PCIE_PHY_MPLL_LOOP_CTL			0x0030
+#define PCIE_PHY_MPLL_ATB_MEAS2			0x0032
+#define PCIE_PHY_MPLL_OVR			0x0033
+#define PCIE_PHY_RTUNE_RTUNE_CTRL		0x0034
+#define PCIE_PHY_TX_OVRD_IN_LO			0x1000
+#define PCIE_PHY_TX_OVRD_IN_HI			0x1001
+#define PCIE_PHY_TX_OVRD_DRV_LO			0x1003
+#define PCIE_PHY_TX_OVRD_OUT			0x1004
+#define PCIE_PHY_RX_OVRD_IN_LO			0x1005
+#define  PCIE_PHY_RX_OVRD_IN_LO_RX_PLL_EN_OVRD	__BIT(3)
+#define  PCIE_PHY_RX_OVRD_IN_LO_RX_DATA_EN_OVRD	__BIT(5)
+#define PCIE_PHY_RX_OVRD_IN_HI			0x1006
+#define PCIE_PHY_RX_OVRD_OUT			0x1007
+#define PCIE_PHY_TX_ASIC_IN			0x1008
+#define PCIE_PHY_TX_ASIC_DRV_LO			0x1009
+#define PCIE_PHY_TX_ASIC_DRV_HI			0x100a
+#define PCIE_PHY_TX_ASIC_OUT			0x100b
+#define PCIE_PHY_RX_ASIC_IN			0x100c
+#define PCIE_PHY_RX_ASIC_OUT			0x100d
+#define  PCIE_PHY_RX_ASIC_OUT_LOS		__BIT(2)
+#define  PCIE_PHY_RX_ASIC_OUT_PLL_STATE		__BIT(1)
+#define  PCIE_PHY_RX_ASIC_OUT_VALID		__BIT(0)
+#define PCIE_PHY_TX_VMD_FSM_TX_VCM_0		0x1011
+#define PCIE_PHY_TX_VMD_FSM_TX_VCM_1		0x1012
+#define PCIE_PHY_TX_VMD_FSM_TX_VCM_DEBUG_IN	0x1013
+#define PCIE_PHY_TX_VMD_FSM_TX_VCM_DEBUG_OUT	0x1014
+#define PCIE_PHY_TX_LBERT_CTL			0x1015
+#define PCIE_PHY_RX_LBERT_CTL			0x1016
+#define PCIE_PHY_RX_LBERT_ERR			0x1017
+#define PCIE_PHY_RX_SCOPE_CTL			0x1018
+#define PCIE_PHY_RX_SCOPE_PHASE			0x1019
+#define PCIE_PHY_RX_DPLL_FREQ			0x101a
+#define PCIE_PHY_RX_CDR_CTL			0x101b
+#define PCIE_PHY_RX_CDR_CDR_FSM_DEBUG		0x101c
+#define PCIE_PHY_RX_CDR_LOCK_VEC_OVRD		0x101d
+#define PCIE_PHY_RX_CDR_LOCK_VEC		0x101e
+#define PCIE_PHY_RX_CDR_ADAP_FSM		0x101f
+#define PCIE_PHY_RX_ATB0			0x1020
+#define PCIE_PHY_RX_ATB1			0x1021
+#define PCIE_PHY_RX_ENPWR0			0x1022
+#define PCIE_PHY_RX_PMIX_PHASE			0x1023
+#define PCIE_PHY_RX_ENPWR1			0x1024
+#define PCIE_PHY_RX_ENPWR2			0x1025
+#define PCIE_PHY_RX_SCOPE			0x1026
+#define PCIE_PHY_TX_TXDRV_CNTRL			0x102b
+#define PCIE_PHY_TX_POWER_CTL			0x102c
+#define PCIE_PHY_TX_ALT_BLOCK			0x102d
+#define PCIE_PHY_TX_ALT_AND_LOOPBACK		0x102e
+#define PCIE_PHY_TX_TX_ATB_REG			0x102f
+
+#endif /* _ARM_IMX_IMX6_PCIEREG_H_ */
Index: src/sys/arch/arm/imx/imxpcievar.h
diff -u /dev/null src/sys/arch/arm/imx/imxpcievar.h:1.1
--- /dev/null	Wed Jul 24 12:33:19 2019
+++ src/sys/arch/arm/imx/imxpcievar.h	Wed Jul 24 12:33:18 2019
@@ -0,0 +1,75 @@
+/*	$NetBSD: imxpcievar.h,v 1.1 2019/07/24 12:33:18 hkenken Exp $	*/
+
+/*
+ * Copyright (c) 2019  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	_ARM_IMX_IMXPCIEVAR_H_
+#define	_ARM_IMX_IMXPCIEVAR_H_
+
+struct imxpcie_ih;
+
+struct imxpcie_softc {
+	device_t sc_dev;
+
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+	bus_space_handle_t sc_root_ioh;
+	bus_space_handle_t sc_gpr_ioh;
+	bus_dma_tag_t sc_dmat;
+
+	paddr_t sc_root_addr;
+	size_t sc_root_size;
+
+	struct arm32_pci_chipset sc_pc;
+
+	TAILQ_HEAD(, imxpcie_ih) sc_intrs;
+
+	void *sc_ih;
+	kmutex_t sc_lock;
+	u_int sc_intrgen;
+
+	struct clk *sc_clk_pcie_axi;
+	struct clk *sc_clk_lvds1_gate;
+	struct clk *sc_clk_pcie_ref;
+
+	void *sc_cookie;
+	void (* sc_pci_netbsd_configure)(void *);
+	uint32_t (* sc_gpr_read)(void *, uint32_t);
+	void (* sc_gpr_write)(void *, uint32_t, uint32_t);
+	void (* sc_reset)(void *);
+};
+
+struct imxpcie_ih {
+	int (*ih_handler)(void *);
+	void *ih_arg;
+	int ih_ipl;
+	TAILQ_ENTRY(imxpcie_ih) ih_entry;
+};
+
+int imxpcie_intr(void *);
+void imxpcie_attach_common(struct imxpcie_softc *);
+
+#endif	/* _ARM_IMX_IMXPCIEVAR_H_ */

Reply via email to