Module Name:    src
Committed By:   marty
Date:           Fri Dec 11 04:03:44 UTC 2015

Modified Files:
        src/sys/arch/arm/samsung: exynos5_reg.h exynos_gpio.c exynos_i2c.c
            exynos_soc.c exynos_var.h mct.c

Log Message:
EXYNOS Rewrite step 2 of N: New exynos_gpio.c

I can't bring  myself to fully nuke from orbit, so there are really two
things in this checkin:

1) A major rewrite of exynos_gpio.c, based mostly on the Nvidia
   tegra_gpio.c file.  This is missing a major function that will be
   added the first time a customer for it is integrated, which is meant to
   select pins based on aliases, rather than pin bank names.

2) A small number of changes to other files that keep the tree compiling
   and progressing as far as ever; except it is now 5422 specific and
   will not boot on the other exynos socs, which I don't have hardware to
   test.

The choice to remove functionality is always controversial, but since
we are doing a significant rewrite and I don't have either
documentation or hardware *and* none of the code really works now
anyway, I'm taking the stance that only tested functionality should be
added, and that we'll layer the other exynos socs on this once it
fully boots.


To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/arm/samsung/exynos5_reg.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/samsung/exynos_gpio.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/samsung/exynos_i2c.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/arm/samsung/exynos_soc.c
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/samsung/exynos_var.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/samsung/mct.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/samsung/exynos5_reg.h
diff -u src/sys/arch/arm/samsung/exynos5_reg.h:1.20 src/sys/arch/arm/samsung/exynos5_reg.h:1.21
--- src/sys/arch/arm/samsung/exynos5_reg.h:1.20	Mon Dec 29 22:58:59 2014
+++ src/sys/arch/arm/samsung/exynos5_reg.h	Fri Dec 11 04:03:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos5_reg.h,v 1.20 2014/12/29 22:58:59 skrll Exp $	*/
+/*	$NetBSD: exynos5_reg.h,v 1.21 2015/12/11 04:03:44 marty Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -51,6 +51,13 @@
  * 0x40000000	0xFFFFFFFF		DRAM
 */
 
+/* MJF: The GPIO offset names made no sense and the values wer wrong. */
+#define EXYNOS5_GPIO_MUXA_OFFSET		0x03400000
+#define EXYNOS5_GPIO_MUXB_OFFSET		0x03410000
+#define EXYNOS5_GPIO_MUXC_OFFSET		0x04000000
+#define EXYNOS5_GPIO_MUXD_OFFSET		0x04010000
+#define EXYNOS5_GPIO_MUXE_OFFSET		0x03860000
+
 /* CORE */
 #define EXYNOS5_CORE_SIZE			0x0f000000
 #define EXYNOS5_SDRAM_PBASE			0x40000000
@@ -103,7 +110,7 @@
 #define EXYNOS5_AS_A_LEFT_BUS_OFFSET		0x00CE0000
 #define EXYNOS5_AS_A_RIGHT0_BUS_OFFSET		0x00CF0000
 #define EXYNOS5_AS_A_DISP1_BUS_OFFSET		0x00D00000
-#define EXYNOS5_GPIO_C2C_OFFSET			0x00D10000
+/*#define EXYNOS5_GPIO_C2C_OFFSET			0x00D10000*/
 #define EXYNOS5_DREXII_OFFSET			0x00DD0000
 #define EXYNOS5_AS_A_EFCON_OFFSET		0x00DE0000
 #define EXYNOS5_AP_C2C_OFFSET			0x00E00000
@@ -117,7 +124,7 @@
 #define EXYNOS5_MFC_OFFSET			0x01000000
 #define EXYNOS5_SYSMMU_MFC0_R			0x01200000
 #define EXYNOS5_SYSMMU_MFC1_L			0x01210000
-#define EXYNOS5_GPIO_LEFT_OFFSET		0x01400000
+/*#define EXYNOS5_GPIO_LEFT_OFFSET		0x04010000*/
 #define EXYNOS5_AS_A_MFC_OFFSET			0x01680000
 #define EXYNOS5_AS_A_GENX_OFFSET		0x016A0000
 #define EXYNOS5_3D ENGINE_OFFSET		0x01800000
@@ -236,7 +243,7 @@
 #define EXYNOS5_SYSMMU_FIMC_DIS0		0x032D0000
 #define EXYNOS5_SYSMMU_FIMC_DIS1		0x032E0000
 #define EXYNOS5_SYSMMU_FIMC_3DNR_OFFSET		0x032F0000
-#define EXYNOS5_GPIO_RIGHT_OFFSET		0x03400000
+/*#define EXYNOS5_GPIO_RIGHT_OFFSET		0x04000000*/
 #define EXYNOS5_AS_A_MFC0_OFFSET		0x03620000
 #define EXYNOS5_AS_A_ISP0_OFFSET		0x03640000
 #define EXYNOS5_AS_A_ISP1_OFFSET		0x03650000

Index: src/sys/arch/arm/samsung/exynos_gpio.c
diff -u src/sys/arch/arm/samsung/exynos_gpio.c:1.12 src/sys/arch/arm/samsung/exynos_gpio.c:1.13
--- src/sys/arch/arm/samsung/exynos_gpio.c:1.12	Mon Dec 29 22:34:08 2014
+++ src/sys/arch/arm/samsung/exynos_gpio.c	Fri Dec 11 04:03:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos_gpio.c,v 1.12 2014/12/29 22:34:08 skrll Exp $	*/
+/*	$NetBSD: exynos_gpio.c,v 1.13 2015/12/11 04:03:44 marty Exp $ */
 
 /*-
 * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
 #include "gpio.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.12 2014/12/29 22:34:08 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.13 2015/12/11 04:03:44 marty Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -42,21 +42,14 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.
 #include <sys/intr.h>
 #include <sys/systm.h>
 #include <sys/kmem.h>
+#include <sys/gpio.h>
+
+#include <dev/gpio/gpiovar.h>
 
 #include <arm/samsung/exynos_reg.h>
 #include <arm/samsung/exynos_io.h>
 #include <arm/samsung/exynos_intr.h>
 
-#include <sys/gpio.h>
-#include <dev/gpio/gpiovar.h>
-
-static int exynos_gpio_match(device_t, cfdata_t, void *);
-static void exynos_gpio_attach(device_t, device_t, void *);
-
-static int exynos_gpio_pin_read(void *, int);
-static void exynos_gpio_pin_write(void *, int, int);
-static void exynos_gpio_pin_ctl(void *, int, int);
-
 struct exynos_gpio_pin_cfg {
 	uint32_t cfg;
 	uint32_t pud;
@@ -65,277 +58,108 @@ struct exynos_gpio_pin_cfg {
 	uint32_t pudpwd;
 };
 
-struct exynos_gpio_pin_group {
-	const char		grp_name[6];
-	const bus_addr_t	grp_core_offset;
-	const uint8_t		grp_bits;
-
-	uint8_t			grp_pin_mask;
-	uint8_t			grp_pin_inuse_mask;
-	bus_space_handle_t	grp_bsh;
-	struct exynos_gpio_pin_cfg grp_cfg;
-	struct gpio_chipset_tag grp_gc_tag;
-};
-
-
-#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o))
-#define GPIO_GRP(v, s, o, n, b) \
-	{ \
-		.grp_name = #n, \
-		.grp_core_offset = GPIO_REG(v,s,o), \
-		.grp_bits = b,\
-	}
-
-#ifdef EXYNOS4
-/*
- * Exynos 4412 contains 304 multi-functional input/output port pins and 164
- * memory port pins. There are 37 general port groups and two memory port
- * groups. They are:
- *
- *  GPA0, GPA1: 14 in/out ports-3xUART with flow control, UART without flow
- *  control, and/or 2xI2C
- *
- *  GPB: 8 in/out ports-2xSPI and/or 2xI2C and/ or IEM
- *
- *  GPC0, GPC1: 10 in/out ports-2xI2S, and/or 2xPCM, and/or AC97, SPDIF, I2C,
- *  and/or SPI
- *
- *  GPD0, GPD1: 8 in/out ports-PWM, 2xI2C, and/ or LCD I/F, MIPI
- *
- *  GPM0, GPM1, GPM2, GPM3, GPM4: 35 in/out ports-CAM I/F, and/ or TS I/F,
- *  HSI, and/ or Trace I/F
- *
- *  GPF0, GPF1, GPF2, GPF3: 30 in/out ports-LCD I/F
- *
- *  GPJ0, GPJ1: 13 in/out ports-CAM I/F
- *
- *  GPK0, GPK1, GPK2, GPK3: 28 in/out ports-4xMMC (4-bit MMC), and/or 2xMMC
- *  (8-bit MMC)), and/or GPS debugging I/F
- *
- *  GPL0, GPL1: 11 in/out ports-GPS I/F
- *
- *  GPL2: 8 in/out ports-GPS debugging I/F or Key pad I/F
- *
- *  GPX0, GPX1, GPX2, GPX3: 32 in/out ports-External wake-up, and/or Key pad
- *  I/F
- *
- *  GPZ: 7 in/out ports-low Power I2S and/or PCM
- *
- *  GPY0, GPY1, GPY2: 16 in/out ports-Control signals of EBI (SROM, NF, One
- *  NAND)
- *
- *  GPY3, GPY4, GPY5, GPY6: 32 in/out memory ports-EBI (For more information
- *  about EBI configuration, refer to Chapter 5, and 6)
- *
- *  MP1_0-MP1_9: 78 DRAM1 ports. NOTE: GPIO registers does not control these
- *  ports.
- *
- *  MP2_0-MP2_9: 78 DRAM2 ports. NOTE: GPIO registers does not control these
- *  ports.
- *
- *  ETC0, ETC1, ETC6: 18 in/out ETC ports-JTAG, SLIMBUS, RESET, CLOCK
- *
- *  ETC7, ETC8 : 4 clock port for C2C
- *
- */
+struct exynos_gpio_softc;
 
-static struct exynos_gpio_pin_group exynos4_pin_groups[] = {
-	GPIO_GRP(4, LEFT,  0x0000, GPA0, 8),
-	GPIO_GRP(4, LEFT,  0x0020, GPA1, 6),
-	GPIO_GRP(4, LEFT,  0x0040, GPB,  8),
-	GPIO_GRP(4, LEFT,  0x0060, GPC0, 5),
-	GPIO_GRP(4, LEFT,  0x0080, GPC1, 5),
-	GPIO_GRP(4, LEFT,  0x00A0, GPD0, 4),
-	GPIO_GRP(4, LEFT,  0x00C0, GPD1, 4),
-	GPIO_GRP(4, LEFT,  0x0180, GPF0, 8),
-	GPIO_GRP(4, LEFT,  0x01A0, GPF1, 8),
-	GPIO_GRP(4, LEFT,  0x01C0, GPF2, 8),
-	GPIO_GRP(4, LEFT,  0x01E0, GPF3, 8),
-	GPIO_GRP(4, LEFT,  0x0240, GPJ0, 8),
-	GPIO_GRP(4, LEFT,  0x0260, GPJ1, 5),
-	/* EXTINT skipped */
-
-	GPIO_GRP(4, RIGHT, 0x0040, GPK0, 8),
-	GPIO_GRP(4, RIGHT, 0x0060, GPK1, 8),
-	GPIO_GRP(4, RIGHT, 0x0080, GPK2, 7),
-	GPIO_GRP(4, RIGHT, 0x00A0, GPK3, 7),
-	GPIO_GRP(4, RIGHT, 0x00C0, GPL0, 7),
-	GPIO_GRP(4, RIGHT, 0x00E0, GPL1, 2),
-	GPIO_GRP(4, RIGHT, 0x0100, GPL2, 8),
-	GPIO_GRP(4, RIGHT, 0x0120, GPY0, 6),
-	GPIO_GRP(4, RIGHT, 0x0140, GPY1, 4),
-	GPIO_GRP(4, RIGHT, 0x0160, GPY2, 6),
-	GPIO_GRP(4, RIGHT, 0x0180, GPY3, 8),
-	GPIO_GRP(4, RIGHT, 0x01A0, GPY4, 8),
-	GPIO_GRP(4, RIGHT, 0x01C0, GPY5, 8),
-	GPIO_GRP(4, RIGHT, 0x01E0, GPY6, 8),
-	GPIO_GRP(4, RIGHT, 0x0200, ETC0, 6),
-	GPIO_GRP(4, RIGHT, 0x0220, ETC6, 8),
-	GPIO_GRP(4, RIGHT, 0x0260, GPM0, 8),
-	GPIO_GRP(4, RIGHT, 0x0280, GPM1, 7),
-	GPIO_GRP(4, RIGHT, 0x02A0, GPM2, 5),
-	GPIO_GRP(4, RIGHT, 0x02C0, GPM3, 8),
-	GPIO_GRP(4, RIGHT, 0x02E0, GPM4, 8),
-	/* EXTINT skipped */
-	GPIO_GRP(4, RIGHT, 0x0C00, GPX0, 8),
-	GPIO_GRP(4, RIGHT, 0x0C20, GPX1, 8),
-	GPIO_GRP(4, RIGHT, 0x0C40, GPX2, 8),
-	GPIO_GRP(4, RIGHT, 0x0C60, GPX3, 8),
-	/* EXTINT skipped */
-
-	GPIO_GRP(4, I2S0,  0x0000, GPZ,  8),
-	/* EXTINT skipped */
-
-	GPIO_GRP(4, C2C,   0x0000, GPV0, 8),
-	GPIO_GRP(4, C2C,   0x0020, GPV1, 8),
-	GPIO_GRP(4, C2C,   0x0040, ETC7, 2),
-	GPIO_GRP(4, C2C,   0x0060, GPV2, 8),
-	GPIO_GRP(4, C2C,   0x0080, GPV3, 8),
-	GPIO_GRP(4, C2C,   0x00A0, ETC8, 2),
-	GPIO_GRP(4, C2C,   0x00C0, GPV4, 2),
-	/* EXTINT skipped */
+struct exynos_gpio_bank {
+	const char		bank_name[6];
+	struct exynos_gpio_softc *bank_sc;
+	device_t		bank_dev;
+	struct gpio_chipset_tag	bank_gc;
+	gpio_pin_t		bank_pins[8];
+
+	const bus_addr_t	bank_core_offset;
+	const uint8_t		bank_bits;
+
+	uint8_t			bank_pin_mask;
+	uint8_t			bank_pin_inuse_mask;
+	bus_space_handle_t	bank_bsh;
+	struct exynos_gpio_pin_cfg bank_cfg;
 };
-#endif
 
+struct exynos_gpio_softc {
+	device_t		sc_dev;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
 
-#ifdef EXYNOS5
-
-/*
- * Exynos 5250 contains 253 multi-functional input/output port pins and 160
- * memory port pins. There are 39 general port groups and 2 memory port
- * groups. They are:
- *
- * GPA0, GPA1: 14 in/out ports-2xUART with flow control, UART without flow
- * control, and/or 2xI2C , and/or2xHS-I2C
- *
- * GPA2: 8 in/out ports-2xSPI, and/or I2C
- *
- * GPB0, GPB1: 10 in/out ports-2xI2S, and/or 2xPCM, and/or AC97, SPDIF, I2C,
- * and/or SPI
- *
- * GPB2, GPB3: 8 in/out ports-PWM, I2C, and/or I2C ,and/or HS-I2C
- *
- * GPC0, GPC1: 11 in/out ports-1xMMC (8-bit MMC) I/F
- *
- * GPC2: 7 in/out ports-1xMMC (4-bit MMC) I/F
- *
- * GPC3, GPC4: 14 in/out ports-2xMMC (4-bit MMC) and/or 1xMMC (8-bit MMC) I/F
- *
- * GPD0: 4 pin/out ports-1xUART with flow control I/F
- *
- * GPD1: 8 pin/out ports-HSI I/F
- *
- * GPE0, GPE1, GPF0, GPF1, GPG0, GPG1, GPG2, GPH0, GPH1: 48 in/out ports-CAM
- * I/F, and/or Trace I/F
- *
- * GPV0, GPV1, GPV2, GPV3, GPV4: 34 in/out ports-C2C I/F
- *
- * GPX0, 1, 2, 3: 32 in/out port-external wake-up interrupts (up-to 32-bit),
- * and/or AUD I/F, and/or MFC I/F (GPX groups are in alive region)
- *
- * GPY0, GPY1, GPY2: 16 in/out ports-control signals of EBI (SROM)
- *
- * GPY3, GPY4, GPY5, GPY6: 32 in/out memory ports-EBI
- *
- * GPZ: 7 in/out ports-low power I2S and/or PCM
- *
- * MP1_0-MP1_10: 80 DRAM1 ports NOTE: GPIO registers do not control these
- * ports.
- *
- * MP2_0-MP2_10: 80 DRAM2 ports NOTE: GPIO registers do not control these
- * ports.
- *
- * ETC0, ETC5, ETC6, ETC7, ETC8: 22 in/out ETC ports-JTAG, C2C_CLK (Rx),
- * RESET, CLOCK, USBOTG and USB3, C2C_CLK (Tx)
- */
-
-static struct exynos_gpio_pin_group exynos5_pin_groups[] = {
-	GPIO_GRP(5, LEFT,  0x0000, GPA0, 8),
-	GPIO_GRP(5, LEFT,  0x0020, GPA1, 6),
-	GPIO_GRP(5, LEFT,  0x0040, GPA2, 8),
-	GPIO_GRP(5, LEFT,  0x0060, GPB0, 5),
-	GPIO_GRP(5, LEFT,  0x0080, GPB1, 5),
-	GPIO_GRP(5, LEFT,  0x00A0, GPB2, 4),
-	GPIO_GRP(5, LEFT,  0x00C0, GPB3, 4),
-	GPIO_GRP(5, LEFT,  0x00E0, GPC0, 7),
-	GPIO_GRP(5, LEFT,  0x0100, GPC1, 4),
-	GPIO_GRP(5, LEFT,  0x0120, GPC2, 7),
-	GPIO_GRP(5, LEFT,  0x0140, GPC3, 7),
-	GPIO_GRP(5, LEFT,  0x0160, GPD0, 4),
-	GPIO_GRP(5, LEFT,  0x0180, GPD1, 8),
-	GPIO_GRP(5, LEFT,  0x01A0, GPY0, 6),
-	GPIO_GRP(5, LEFT,  0x01C0, GPY1, 4),
-	GPIO_GRP(5, LEFT,  0x01E0, GPY2, 6),
-	GPIO_GRP(5, LEFT,  0x0200, GPY3, 8),
-	GPIO_GRP(5, LEFT,  0x0220, GPY4, 8),
-	GPIO_GRP(5, LEFT,  0x0240, GPY5, 8),
-	GPIO_GRP(5, LEFT,  0x0260, GPY6, 8),
-	GPIO_GRP(5, LEFT,  0x0280, ETC0, 6),
-	GPIO_GRP(5, LEFT,  0x02A0, ETC6, 7),
-	GPIO_GRP(5, LEFT,  0x02C0, ETC7, 5),
-	GPIO_GRP(5, LEFT,  0x02E0, GPC4, 7),
-	/* EXTINT skipped */
-	GPIO_GRP(5, LEFT,  0x0C00, GPX0, 8),
-	GPIO_GRP(5, LEFT,  0x0C20, GPX1, 8),
-	GPIO_GRP(5, LEFT,  0x0C40, GPX2, 8),
-	GPIO_GRP(5, LEFT,  0x0C60, GPX3, 8),
-	/* EXTINT skipped */
-
-	GPIO_GRP(5, RIGHT, 0x0000, GPE0, 8),
-	GPIO_GRP(5, RIGHT, 0x0020, GPE1, 2),
-	GPIO_GRP(5, RIGHT, 0x0040, GPF0, 4),
-	GPIO_GRP(5, RIGHT, 0x0060, GPF1, 4),
-	GPIO_GRP(5, RIGHT, 0x0080, GPG0, 8),
-	GPIO_GRP(5, RIGHT, 0x00A0, GPG1, 8),
-	GPIO_GRP(5, RIGHT, 0x00C0, GPG2, 2),
-	GPIO_GRP(5, RIGHT, 0x00E0, GPH0, 4),
-	GPIO_GRP(5, RIGHT, 0x0100, GPH1, 8),
-	/* EXTINT skipped */
-
-	GPIO_GRP(5, USB,   0x0000, GPJ0, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x0020, GPJ1, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x0040, GPJ2, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x0060, GPJ3, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x0080, GPJ4, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x00A0, GPK0, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x00C0, GPK1, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x00E0, GPK2, 8),	// unknown num bits
-	GPIO_GRP(5, USB,   0x0100, GPK3, 8),	// unknown num bits
-	/* unknown bits skipped */
-
-	GPIO_GRP(5, C2C,   0x0000, GPV0, 8),
-	GPIO_GRP(5, C2C,   0x0020, GPV1, 8),
-	GPIO_GRP(5, C2C,   0x0040, ETC5, 2),
-	GPIO_GRP(5, C2C,   0x0060, GPV2, 8),
-	GPIO_GRP(5, C2C,   0x0080, GPV3, 8),
-	GPIO_GRP(5, C2C,   0x00A0, ETC8, 2),
-	GPIO_GRP(5, C2C,   0x00C0, GPV4, 2),
-	/* EXTINT skipped */
+	struct exynos_gpio_bank *sc_banks;
+};
 
-	GPIO_GRP(5, I2S,   0x0000, GPZ,  7),
-	/* EXTINT skipped */
+struct exynos_gpio_pin {
+	struct exynos_gpio_softc *pin_sc;
+	const struct exynos_gpio_bank  *pin_bank;
+	int			  pin_no;
+	u_int			  pin_flags;
 };
-#endif
 
+#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o))
+#define GPIO_GRP(v, s, o, n, b)	\
+	{ \
+		.bank_name = #n, \
+		.bank_core_offset = GPIO_REG(v,s,o), \
+		.bank_bits = b, \
+	}
+
+static struct exynos_gpio_bank exynos5_banks[] = {
+	GPIO_GRP(5, MUXA, 0x0000, gpy7, 8),
+	GPIO_GRP(5, MUXA, 0x0C00, gpx0, 8),
+	GPIO_GRP(5, MUXA, 0x0C20, gpx1, 8),
+	GPIO_GRP(5, MUXA, 0x0C40, gpx2, 8),
+	GPIO_GRP(5, MUXA, 0x0C60, gpx3, 8),
+
+	GPIO_GRP(5, MUXB, 0x0000, gpc0, 8),
+	GPIO_GRP(5, MUXB, 0x0020, gpc1, 8),
+	GPIO_GRP(5, MUXB, 0x0040, gpc2, 7),
+	GPIO_GRP(5, MUXB, 0x0060, gpc3, 4),
+	GPIO_GRP(5, MUXB, 0x0080, gpc4, 2),
+	GPIO_GRP(5, MUXB, 0x00A0, gpd1, 8),
+	GPIO_GRP(5, MUXB, 0x00C0, gpy0, 6),
+	GPIO_GRP(5, MUXB, 0x00E0, gpy1, 4),
+	GPIO_GRP(5, MUXB, 0x0100, gpy2, 6),
+	GPIO_GRP(5, MUXB, 0x0120, gpy3, 8),
+	GPIO_GRP(5, MUXB, 0x0140, gpy4, 8),
+	GPIO_GRP(5, MUXB, 0x0160, gpy5, 8),
+	GPIO_GRP(5, MUXB, 0x0180, gpy6, 8),
+
+	GPIO_GRP(5, MUXC, 0x0000, gpe0, 8),
+	GPIO_GRP(5, MUXC, 0x0020, gpe1, 2),
+	GPIO_GRP(5, MUXC, 0x0040, gpf0, 6),
+	GPIO_GRP(5, MUXC, 0x0060, gpf1, 8),
+	GPIO_GRP(5, MUXC, 0x0080, gpg0, 8),
+	GPIO_GRP(5, MUXC, 0x00A0, gpg1, 8),
+	GPIO_GRP(5, MUXC, 0x00C0, gpg2, 2),
+	GPIO_GRP(5, MUXC, 0x00E0, gpj4, 4),
+
+	GPIO_GRP(5, MUXD, 0x0000, gpa0, 8),
+	GPIO_GRP(5, MUXD, 0x0020, gpa1, 6),
+	GPIO_GRP(5, MUXD, 0x0040, gpa2, 8),
+	GPIO_GRP(5, MUXD, 0x0060, gpb0, 5),
+	GPIO_GRP(5, MUXD, 0x0080, gpb1, 5),
+	GPIO_GRP(5, MUXD, 0x00A0, gpb2, 4),
+	GPIO_GRP(5, MUXD, 0x00C0, gpb3, 8),
+	GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2),
+	GPIO_GRP(5, MUXD, 0x0100, gph0, 4),
 
-struct exynos_gpio_softc {
-	device_t		sc_dev;
-	bus_space_tag_t		sc_bst;
-	bus_space_handle_t	sc_bsh;
+//	GPIO_GRP(5, MUXE, 0x0000, gpz0,  7),
 };
 
+static int exynos_gpio_match(device_t, cfdata_t, void *);
+static void exynos_gpio_attach(device_t, device_t, void *);
+
+static int exynos_gpio_pin_read(void *, int);
+static void exynos_gpio_pin_write(void *, int, int);
+static void exynos_gpio_pin_ctl(void *, int, int);
+static int exynos_gpio_cfprint(void *, const char *);
+struct exynos_gpio_pin *exynos_gpio_acquire(const char *pinname, u_int flags);
 
 /* force these structures in DATA segment */
-static struct exynos_gpio_pin_group *exynos_pin_groups = NULL;
-static int exynos_n_pin_groups = 0;
+static struct exynos_gpio_bank *exynos_gpio_banks = NULL;
+static int exynos_n_gpio_banks = 0;
 
 static struct exynos_gpio_softc exynos_gpio_sc = {};
 
-
 CFATTACH_DECL_NEW(exynos_gpio, sizeof(struct exynos_gpio_softc),
 	exynos_gpio_match, exynos_gpio_attach, NULL, NULL);
 
-
 static int
 exynos_gpio_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -358,24 +182,21 @@ exynos_gpio_match(device_t parent, cfdat
 
 #if NGPIO > 0
 static void
-exynos_gpio_config_pins(device_t self)
+exynos_gpio_attach_banks(device_t self)
 {
 	struct exynos_gpio_softc * const sc = &exynos_gpio_sc;
-	struct exynos_gpio_pin_group *grp;
+	struct exynos_gpio_bank *bank;
 	struct gpiobus_attach_args gba;
-	gpio_pin_t *pin, *pins;
 	size_t pin_count = 0;
 	int i, bit, mask, pincaps, data;
 
-	if (exynos_n_pin_groups == 0)
+	if (exynos_n_gpio_banks == 0)
 		return;
 
 	/* find out how many pins we can offer */
 	pin_count = 0;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		mask = grp->grp_pin_mask & ~grp->grp_pin_inuse_mask;
-		pin_count += popcount32(mask);
+	for (i = 0; i < exynos_n_gpio_banks; i++) {
+		pin_count += exynos_gpio_banks[i].bank_bits;
 	}
 
 	/* if no pins available, don't proceed */
@@ -383,101 +204,84 @@ exynos_gpio_config_pins(device_t self)
 		return;
 
 	/* allocate pin data */
-	pins = kmem_zalloc(sizeof(gpio_pin_t) * pin_count, KM_SLEEP);
-	KASSERT(pins);
+	sc->sc_banks = exynos_gpio_banks;
+	KASSERT(sc->sc_banks);
 
 	pincaps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
 		GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
 
-	/* add all pins */
-	pin = pins;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		mask = grp->grp_pin_mask & ~grp->grp_pin_inuse_mask;
+	for (i = 0; i < exynos_n_gpio_banks; i++) {
+		bank = &sc->sc_banks[i];
+		bank->bank_sc = sc;
+		bank->bank_gc.gp_cookie = bank;
+		bank->bank_gc.gp_pin_read = exynos_gpio_pin_read;
+		bank->bank_gc.gp_pin_write = exynos_gpio_pin_write;
+		bank->bank_gc.gp_pin_ctl = exynos_gpio_pin_ctl;
+		mask = bank->bank_pin_mask & ~bank->bank_pin_inuse_mask;
 		if (mask == 0)
 			continue;
-		gba.gba_gc = &grp->grp_gc_tag;
-		gba.gba_pins = pin;
-		data = bus_space_read_1(sc->sc_bst, grp->grp_bsh,
+		data = bus_space_read_1(sc->sc_bst, bank->bank_bsh,
 				EXYNOS_GPIO_DAT);
 		for (bit = 0; mask != 0; mask >>= 1, data >>= 1, bit++) {
 			if (mask & 1) {
-				pin->pin_num = bit + (i << 3);
-				pin->pin_caps = pincaps;
-				pin->pin_flags = pincaps;
-				pin->pin_state = (data & 1) != 0;
-				pin++;
+				bank->bank_pins[bit].pin_num = bit + (i << 3);
+				bank->bank_pins[bit].pin_caps = pincaps;
+				bank->bank_pins[bit].pin_flags = pincaps;
+				bank->bank_pins[bit].pin_state = (data & 1) != 0;
 			}
 		}
-		gba.gba_npins = pin - gba.gba_pins;
-		config_found_ia(self, "gpiobus", &gba, gpiobus_print);
+		memset(&gba, 0, sizeof(gba));
+		gba.gba_gc = &bank->bank_gc;
+		gba.gba_pins = bank->bank_pins;
+		gba.gba_npins = bit; /* MJF? */
+		bank->bank_dev = config_found_ia(self, "gpiobus", &gba,
+						 exynos_gpio_cfprint);
 	}
 }
 #endif
 
+static int
+exynos_gpio_cfprint(void *priv, const char *pnp)
+{
+	struct gpiobus_attach_args *gba = priv;
+	struct exynos_gpio_bank *bank = gba->gba_gc->gp_cookie;
+	const char *bankname = bank->bank_name;
+
+	if (pnp)
+		aprint_normal("gpiobus at %s", pnp);
+
+	aprint_normal(" (%s)", bankname);
+
+	return UNCONF;
+}
 
 static void
 exynos_gpio_attach(device_t parent, device_t self, void *aux)
 {
 	struct exynos_gpio_softc * const sc = &exynos_gpio_sc;
 	struct exyo_attach_args * const exyoaa = aux;
-	struct exynos_gpio_pin_group *grp;
-	prop_dictionary_t dict = device_properties(self);
-	uint32_t nc;
-	char scrap[16];
-	int i;
 
-	/* construct softc */
 	sc->sc_dev = self;
-
-	/* we use the core bushandle here */
 	sc->sc_bst = exyoaa->exyo_core_bst;
 	sc->sc_bsh = exyoaa->exyo_core_bsh;
 
 	exynos_gpio_bootstrap();
-	if (exynos_n_pin_groups == 0) {
+	if (exynos_n_gpio_banks == 0) {
 		printf(": disabled, no pins defined\n");
 		return;
 	}
 
-	KASSERT(exynos_pin_groups);
-	KASSERT(exynos_n_pin_groups);
+	KASSERT(exynos_gpio_banks);
+	KASSERT(exynos_n_gpio_banks);
 
 	aprint_naive("\n");
 	aprint_normal("\n");
 
-	/* go trough all pin groups */
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		snprintf(scrap, sizeof(scrap), "nc-%s", grp->grp_name);
-		if (prop_dictionary_get_uint32(dict, scrap, &nc)) {
-			KASSERT((~grp->grp_pin_mask & nc) == 0);
-			/* switch off the pins we have signalled NC */
-			grp->grp_pin_mask &= ~nc;
-#if 0
-			printf("%s: %-4s inuse_mask %02x, pin_mask %02x\n",
-			    __func__, grp->grp_name,
-			    grp->grp_pin_inuse_mask, grp->grp_pin_mask);
-#endif
-		}
-	}
-
 #if NGPIO > 0
-	config_defer(self, exynos_gpio_config_pins);
+	exynos_gpio_attach_banks(self);
 #endif
 }
 
-
-/* pin access functions */
-static u_int
-exynos_gpio_get_pin_func(const struct exynos_gpio_pin_cfg *cfg, int pin)
-{
-	const u_int shift = (pin & 7) << 2;
-
-	return (cfg->cfg >> shift) & 0x0f;
-}
-
-
 static void
 exynos_gpio_set_pin_func(struct exynos_gpio_pin_cfg *cfg,
 	int pin, int func)
@@ -498,68 +302,65 @@ exynos_gpio_set_pin_pull(struct exynos_g
 	cfg->pud |= pull << shift;
 }
 
-
 static int
 exynos_gpio_pin_read(void *cookie, int pin)
 {
-	struct exynos_gpio_pin_group * const grp = cookie;
+	struct exynos_gpio_bank * const bank = cookie;
 
-	KASSERT(pin < grp->grp_bits);
-	return (bus_space_read_1(exynos_gpio_sc.sc_bst, grp->grp_bsh,
+	KASSERT(pin < bank->bank_bits);
+	return (bus_space_read_1(exynos_gpio_sc.sc_bst, bank->bank_bsh,
 		EXYNOS_GPIO_DAT) >> pin) & 1;
 }
 
-
 static void
 exynos_gpio_pin_write(void *cookie, int pin, int value)
 {
-	struct exynos_gpio_pin_group * const grp = cookie;
+	struct exynos_gpio_bank * const bank = cookie;
 	int val;
 
-	KASSERT(pin < grp->grp_bits);
-	val = bus_space_read_1(exynos_gpio_sc.sc_bst, grp->grp_bsh,
+	KASSERT(pin < bank->bank_bits);
+	val = bus_space_read_1(exynos_gpio_sc.sc_bst, bank->bank_bsh,
 		EXYNOS_GPIO_DAT);
 	val &= ~__BIT(pin);
 	if (value)
 		val |= __BIT(pin);
-	bus_space_write_1(exynos_gpio_sc.sc_bst, grp->grp_bsh,
+	bus_space_write_1(exynos_gpio_sc.sc_bst, bank->bank_bsh,
 		EXYNOS_GPIO_DAT, val);
 }
 
-
 static void
-exynos_gpio_update_cfg_regs(struct exynos_gpio_pin_group *grp,
+exynos_gpio_update_cfg_regs(struct exynos_gpio_bank *bank,
 	const struct exynos_gpio_pin_cfg *ncfg)
 {
 	bus_space_tag_t bst = &exynos_bs_tag;
 
-	if (grp->grp_cfg.cfg != ncfg->cfg) {
-		bus_space_write_4(bst, grp->grp_bsh,
+	if (bank->bank_cfg.cfg != ncfg->cfg) {
+		bus_space_write_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_CON, ncfg->cfg);
-		grp->grp_cfg.cfg = ncfg->cfg;
+		bank->bank_cfg.cfg = ncfg->cfg;
 	}
-	if (grp->grp_cfg.pud != ncfg->pud) {
-		bus_space_write_4(bst, grp->grp_bsh,
+	if (bank->bank_cfg.pud != ncfg->pud) {
+		bus_space_write_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_PUD, ncfg->pud);
-		grp->grp_cfg.pud = ncfg->pud;
+		bank->bank_cfg.pud = ncfg->pud;
 	}
 
 	/* the following attributes are not yet setable */
 #if 0
-	if (grp->grp_cfg.drv != ncfg->drv) {
-		bus_space_write_4(bst, grp->grp_bsh,
+	if (bank->bank_cfg.drv != ncfg->drv) {
+		bus_space_write_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_DRV, ncfg->drv);
-		grp->grp_cfg.drv = ncfg->drv;
+		bank->bank_cfg.drv = ncfg->drv;
 	}
-	if (grp->grp_cfg.conpwd != ncfg->conpwd) {
-		bus_space_write_4(bst, grp->grp_bsh,
+	if (bank->bank_cfg.conpwd != ncfg->conpwd) {
+		bus_space_write_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_CONPWD, ncfg->conpwd);
-		grp->grp_cfg.conpwd = ncfg->conpwd;
+		bank->bank_cfg.conpwd = ncfg->conpwd;
 	}
-	if (grp->grp_cfg.pudpwd != ncfg->pudpwd) {
-		bus_space_write_4(bst, grp->grp_bsh,
+	if (bank->bank_cfg.pudpwd != ncfg->pudpwd) {
+		bus_space_write_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_PUDPWD, ncfg->pudpwd);
-		grp->grp_cfg.pudpwd = ncfg->pudpwd;
+		bank->bank_cfg.pudpwd = ncfg->pudpwd;
 	}
 #endif
 }
@@ -568,8 +369,8 @@ exynos_gpio_update_cfg_regs(struct exyno
 static void
 exynos_gpio_pin_ctl(void *cookie, int pin, int flags)
 {
-	struct exynos_gpio_pin_group * const grp = cookie;
-	struct exynos_gpio_pin_cfg ncfg = grp->grp_cfg;
+	struct exynos_gpio_bank * const bank = cookie;
+	struct exynos_gpio_pin_cfg ncfg = bank->bank_cfg;
 	int pull;
 
 	/* honour pullup requests */
@@ -587,374 +388,113 @@ exynos_gpio_pin_ctl(void *cookie, int pi
 		exynos_gpio_set_pin_func(&ncfg, pin, EXYNOS_GPIO_FUNC_OUTPUT);
 
 	/* update any config registers that changed */
-	exynos_gpio_update_cfg_regs(grp, &ncfg);
-}
-
-
-bool
-exynos_gpio_pinset_available(const struct exynos_gpio_pinset *req)
-{
-	struct exynos_gpio_pin_group *grp;
-	int i, n, inuse;
-
-	KASSERT(req);
-	if (exynos_n_pin_groups == 0)
-		return false;
-
-	/* we need a pinset group */
-	if (strlen(req->pinset_group) == 0)
-		return false;
-
-	/* determine which group is requested */
-	grp = NULL;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		if (strcmp(req->pinset_group, grp->grp_name) == 0)
-			break;
-	}
-	/* found? */
-	if (i == exynos_n_pin_groups)
-		return false;
-	KASSERT(grp);
-
-	/* fail unconnected pins */
-	if (req->pinset_mask & ~grp->grp_pin_mask)
-		return false;
-
-	/* if none in use, they are available */
-	if (req->pinset_mask & ~grp->grp_pin_inuse_mask)
-		return true;
-
-	/* OK, so some are in use; now see if the request is compatible */
-	inuse = req->pinset_mask & grp->grp_pin_inuse_mask;
-	for (i = 0; inuse; i++, inuse >>= 1) {
-		/* try to be smart by skipping zero's */
-		n = ffs(inuse) -1;
-		i += n;
-		inuse >>= n;
-		/* this pin is in use, check its usage */
-		if (exynos_gpio_get_pin_func(&grp->grp_cfg, i) != req->pinset_func)
-			return false;
-	}
-
-	/* seems to be OK */
-	return true;
-}
-
-
-void
-exynos_gpio_pinset_acquire(const struct exynos_gpio_pinset *req)
-{
-	struct exynos_gpio_pin_group *grp;
-	struct exynos_gpio_pin_cfg ncfg;
-	int i, n, todo;
-
-	KASSERT(req);
-	KASSERT(exynos_gpio_pinset_available(req));
-
-	/* determine which group is requested */
-	grp = NULL;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		if (strcmp(req->pinset_group, grp->grp_name) == 0)
-			break;
-	}
-	KASSERT(grp);
-
-	/* check if all the pins have the right function */
-	if ((req->pinset_mask & ~grp->grp_pin_inuse_mask) == 0)
-		return;
-
-	/* copy current config for update routine */
-	ncfg = grp->grp_cfg;
-
-	/* update the function of each pin that is not in use */
-	todo = req->pinset_mask & grp->grp_pin_inuse_mask;
-	for (i = 0; todo; i++, todo >>= 1) {
-		/* try to be smart by skipping zero's */
-		n = ffs(todo) -1;
-		i += n;
-		todo >>= n;
-		/* change the function of this pin */
-		exynos_gpio_set_pin_func(&ncfg, i, req->pinset_func);
-	}
-
-	/* update config registers */
-	exynos_gpio_update_cfg_regs(grp, &ncfg);
-
-	/* mark pins in use */
-	grp->grp_pin_inuse_mask |= req->pinset_mask;
-}
-
-
-/* get a pindata structure from a pinset structure */
-void
-exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *req, int pinnr,
-	struct exynos_gpio_pindata *pd)
-{
-	struct exynos_gpio_pin_group *grp;
-	int i;
-
-	KASSERT(req);
-	KASSERT(pd);
-	KASSERT(req->pinset_mask & __BIT(pinnr));
-
-	/* determine which group is requested */
-	grp = NULL;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		if (strcmp(req->pinset_group, grp->grp_name) == 0)
-			break;
-	}
-	KASSERT(grp);
-
-	pd->pd_gc = &grp->grp_gc_tag;
-	pd->pd_pin = pinnr;
-}
-
-
-/* XXXRPZ This release doesn't grock multiple usages! */
-void
-exynos_gpio_pinset_release(const struct exynos_gpio_pinset *req)
-{
-	struct exynos_gpio_pin_group *grp;
-	int i;
-
-	KASSERT(!exynos_gpio_pinset_available(req));
-
-	/* determine which group is requested */
-	grp = NULL;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		if (strcmp(req->pinset_group, grp->grp_name) == 0)
-			break;
-	}
-	KASSERT(grp);
-
-	/* bluntly mark as not being in use */
-	grp->grp_pin_inuse_mask &= ~req->pinset_mask;
-}
-
-
-/*
- * name convention :
- * pin   = <func><groupname><pinnr>[<pud>]
- * func  = '<' | '>'
- * pinnr = '['['0'-'7']']'
- * pud   =  'F' | 'U' | 'D'
- *
- * example "<GPC1[0]", ">GPB[0]"
- */
-
-bool
-exynos_gpio_pin_reserve(const char *name, struct exynos_gpio_pindata *pd)
-{
-	struct exynos_gpio_softc * const sc = &exynos_gpio_sc;
-	struct exynos_gpio_pin_group *grp;
-	struct exynos_gpio_pin_cfg ncfg;
-	prop_dictionary_t dict = device_properties(sc->sc_dev);
-	const char *pin_data;
-	char grp_name[15], *pos;
-	int func, pud, pinnr;
-	int pi, i;
-
-	if (exynos_n_pin_groups == 0)
-		return false;
-
-	/* do we have a named pin description? */
-	if (!prop_dictionary_get_cstring_nocopy(dict, name, &pin_data))
-		return false;
-
-	KASSERT(strlen(pin_data) < 10);
-	if (!(pin_data[0] == '>' || pin_data[0] == '<')) {
-		printf("%s: malformed pin data in '%s', missing direction\n",
-			__func__, pin_data);
-		return false;
-	}
-
-	func = (pin_data[0] == '<') ?
-		EXYNOS_GPIO_FUNC_INPUT : EXYNOS_GPIO_FUNC_OUTPUT;
-
-	/* find groupname */
-	pi = 1; pos = grp_name;
-	while (pin_data[pi] && pin_data[pi] != '[') {
-		*pos++ = pin_data[pi++];
-	}
-	if (pin_data[pi] != '[') {
-		printf("%s: malformed pin data in '%s', missing '['\n",
-			__func__, pin_data);
-		return false;
-	}
-	*pos++ = (char) 0;
-
-	/* skip '[' */
-	pi++;
-	if (!(pin_data[pi] >= '0' && pin_data[pi] <= '7')) {
-		printf("%s: malformed pin data in '%s', bad pin number\n",
-			__func__, pin_data);
-		return false;
-	}
-	pinnr = pin_data[pi] - '0';
-
-	/* skip digit */
-	pi++;
-	if ((pin_data[pi] != ']')) {
-		printf("%s: malformed pin data in '%s', missing end ']'\n",
-			__func__, pin_data);
-		return false;
-	}
-
-	/* skip ']' */
-	pi++;
-	pud = EXYNOS_GPIO_PIN_FLOAT;
-	switch (tolower(pin_data[pi])) {
-		case (char) 0:
-			break;
-		case 'f':
-			pud = EXYNOS_GPIO_PIN_FLOAT;
-			break;
-		case 'u':
-			pud = EXYNOS_GPIO_PIN_PULL_UP;
-			break;
-		case 'd':
-			pud = EXYNOS_GPIO_PIN_PULL_DOWN;
-			break;
-		default:
-			printf("%s: malformed pin data in '%s', expecting "
-				"optional pull up/down or float argument\n",
-				__func__, pin_data);
-		return false;
-	}
-
-	/* determine which group is requested */
-	grp = NULL;
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		if (strcmp(grp_name, grp->grp_name) == 0)
-			break;
-	}
-
-	/* found? */
-	if (i >= exynos_n_pin_groups) {
-		printf("%s: malformed pin data in '%s', "
-			"no such pin group name\n",
-			__func__, grp_name);
-		return false;
-	}
-	KASSERT(grp);
-
-	/* in range? */
-	if (pinnr >= grp->grp_bits)
-		return false;
-
-	/* marked as connected? */
-	if ((grp->grp_pin_mask & __BIT(pinnr)) == 0)
-		return false;
-
-	/* it better not be used!! this is not taken lightly */
-	KASSERT((grp->grp_pin_inuse_mask & __BIT(pinnr)) == 0);
-
-	/* update our pin configuration */
-	ncfg = grp->grp_cfg;
-	exynos_gpio_set_pin_func(&ncfg, pinnr, func);
-	exynos_gpio_set_pin_pull(&ncfg, pinnr, pud);
-	exynos_gpio_update_cfg_regs(grp, &ncfg);
-
-	grp->grp_pin_inuse_mask |= __BIT(pinnr);
-	grp->grp_pin_mask &= ~__BIT(pinnr);
-
-	pd->pd_gc = &grp->grp_gc_tag;
-	pd->pd_pin = pinnr;
-
-	return true;
+	exynos_gpio_update_cfg_regs(bank, &ncfg);
 }
 
-
 /* bootstrapping */
 void
 exynos_gpio_bootstrap(void)
 {
 	bus_space_tag_t bst = &exynos_bs_tag;
-	struct exynos_gpio_pin_group *grp;
+	struct exynos_gpio_bank *bank;
 	struct gpio_chipset_tag *gc_tag;
 	int i;
 
 	/* determine what we're running on */
-#ifdef EXYNOS4
-	if (IS_EXYNOS4_P()) {
-		exynos_pin_groups = exynos4_pin_groups;
-		exynos_n_pin_groups = __arraycount(exynos4_pin_groups);
-	}
-#endif
-#ifdef EXYNOS5
 	if (IS_EXYNOS5_P()) {
-		exynos_pin_groups = exynos5_pin_groups;
-		exynos_n_pin_groups = __arraycount(exynos5_pin_groups);
+		exynos_gpio_banks = exynos5_banks;
+		exynos_n_gpio_banks = __arraycount(exynos5_banks);
 	}
-#endif
 
-	if (exynos_n_pin_groups == 0)
+	if (exynos_n_gpio_banks == 0)
 		return;
 
-	/* init groups */
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		gc_tag = &grp->grp_gc_tag;
+	/* init banks */
+	for (i = 0; i < exynos_n_gpio_banks; i++) {
+		bank = &exynos_gpio_banks[i];
+		gc_tag = &bank->bank_gc;
 
 		bus_space_subregion(&exynos_bs_tag, exynos_core_bsh,
-			grp->grp_core_offset, EXYNOS_GPIO_GRP_SIZE,
-			&grp->grp_bsh);
-		KASSERT(&grp->grp_bsh);
+			bank->bank_core_offset, EXYNOS_GPIO_GRP_SIZE,
+			&bank->bank_bsh);
+		KASSERT(&bank->bank_bsh);
 
-		grp->grp_pin_mask = __BIT(grp->grp_bits) - 1;
-		grp->grp_pin_inuse_mask = 0;
+		bank->bank_pin_mask = __BIT(bank->bank_bits) - 1;
+		bank->bank_pin_inuse_mask = 0;
 
-		gc_tag->gp_cookie = grp;
+		gc_tag->gp_cookie = bank;
 		gc_tag->gp_pin_read  = exynos_gpio_pin_read;
 		gc_tag->gp_pin_write = exynos_gpio_pin_write;
 		gc_tag->gp_pin_ctl   = exynos_gpio_pin_ctl;
 
 		/* read in our initial settings */
-		grp->grp_cfg.cfg = bus_space_read_4(bst, grp->grp_bsh,
+		bank->bank_cfg.cfg = bus_space_read_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_CON);
-		grp->grp_cfg.pud = bus_space_read_4(bst, grp->grp_bsh,
+		bank->bank_cfg.pud = bus_space_read_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_PUD);
-		grp->grp_cfg.drv = bus_space_read_4(bst, grp->grp_bsh,
+		bank->bank_cfg.drv = bus_space_read_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_DRV);
-		grp->grp_cfg.conpwd = bus_space_read_4(bst, grp->grp_bsh,
+		bank->bank_cfg.conpwd = bus_space_read_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_CONPWD);
-		grp->grp_cfg.pudpwd = bus_space_read_4(bst, grp->grp_bsh,
+		bank->bank_cfg.pudpwd = bus_space_read_4(bst, bank->bank_bsh,
 			EXYNOS_GPIO_PUDPWD);
+	}
 
-		/*
-		 * Normally we would count the busy pins.
-		 *
-		 * We can't check inuse here since uboot has used pins for its
-		 * own use and left them configured forbidding us to use pins
-		 * for our own sake.
-		 */
-#if 0
-		for (int j = 0, int mask = 1;
-		     (mask & grp->grp_pin_mask) != 0;
-		     j++, mask <<= 1) {
-			int func = exynos_gpio_get_pin_func(&grp->grp_cfg, j);
-			if (func > EXYNOS_GPIO_FUNC_INPUT) {
-				printf("%s: %s[%d] func %d\n", __func__,
-				    grp->grp_name, j, func);
-			}
+}
+
+/*
+ * pinmame = gpLD-N
+ *     L = 'a' - 'z' -+
+ *     D = '0' - '8' -+ ===== bank name
+ *     N = '0' - '8'    ===== pin number
+ */
+
+static const struct exynos_gpio_bank *
+exynos_gpio_pin_lookup(const char *pinname, int *ppin)
+{
+	char bankname[5];
+	u_int n;
+	int pin;
+
+	KASSERT(strlen(pinname) == 2 || strlen(pinname) == 3);
+
+	memset(bankname, 0, sizeof(bankname));
+	bankname[0] = pinname[0]; /* 'g' */
+	bankname[1] = pinname[1]; /* 'p' */
+	bankname[2] = pinname[2]; /*  L  */
+	bankname[3] = pinname[3]; /*  D  */
+	pin = pinname[5] - '0';	  /* skip the '-' */
+
+	for (n = 0; n < __arraycount(exynos_gpio_banks); n++) {
+		const struct exynos_gpio_bank *pb =
+		    &exynos_gpio_banks[n];
+		if (strcmp(pb->bank_name, bankname) == 0) {
+			*ppin = pin;
+			return pb;
 		}
-#endif
-	}
-#if 0
-	printf("\n");
-	printf("default NC pin list generated: \n");
-	/* enable this for default NC pins list generation */
-	for (i = 0; i < exynos_n_pin_groups; i++) {
-		grp = &exynos_pin_groups[i];
-		printf("prop_dictionary_set_uint32(dict, \"nc-%s\", "
-			"0x%02x - 0b00000000);\n",
-			grp->grp_name, grp->grp_pin_mask);
 	}
-#endif
+
+	return NULL;
 }
 
+struct exynos_gpio_pin *
+exynos_gpio_acquire(const char *pinname, u_int flags)
+{
+	const struct exynos_gpio_bank *bank;
+	struct exynos_gpio_pin *gpin;
+	int pin;
+
+	bank = exynos_gpio_pin_lookup(pinname, &pin);
+	if (bank == NULL)
+		return NULL;
+
+	gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP);
+	gpin->pin_sc = bank->bank_sc;
+	gpin->pin_bank = bank;
+	gpin->pin_no = pin;
+	gpin->pin_flags = flags;
+
+	exynos_gpio_pin_ctl(&gpin->pin_bank, gpin->pin_no, gpin->pin_flags);
+
+	return gpin;
+}

Index: src/sys/arch/arm/samsung/exynos_i2c.c
diff -u src/sys/arch/arm/samsung/exynos_i2c.c:1.3 src/sys/arch/arm/samsung/exynos_i2c.c:1.4
--- src/sys/arch/arm/samsung/exynos_i2c.c:1.3	Mon Dec 29 22:34:08 2014
+++ src/sys/arch/arm/samsung/exynos_i2c.c	Fri Dec 11 04:03:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos_i2c.c,v 1.3 2014/12/29 22:34:08 skrll Exp $ */
+/*	$NetBSD: exynos_i2c.c,v 1.4 2015/12/11 04:03:44 marty Exp $ */
 
 /*
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include "exynos_iic.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.3 2014/12/29 22:34:08 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.4 2015/12/11 04:03:44 marty Exp $");
 
 
 #include <sys/param.h>
@@ -214,7 +214,7 @@ exynos_iic_attach_i2cbus(struct exynos_i
 
 	/* reserve our pins */
 	pinset = &ei2c_sc->isc_pinset;
-	strcpy(pinset->pinset_group, loc->loc_gpio_bus);
+	strcpy(pinset->pinset_bank, loc->loc_gpio_bus);
 	pinset->pinset_mask = __BIT(loc->loc_sda) | __BIT(loc->loc_slc);
 	pinset->pinset_func = loc->loc_func;
 
@@ -227,9 +227,11 @@ exynos_iic_attach_i2cbus(struct exynos_i
 	i2c_cntr->ic_read_byte   = exynos_iic_read_byte;
 	i2c_cntr->ic_write_byte  = exynos_iic_write_byte;
 
-	exynos_gpio_pinset_acquire(pinset);
+	/*MJF: FIX ME IN REWRITE */
+//	exynos_gpio_pinset_acquire(pinset);
 	if (ei2c_sc->isc_isgpio) {
 		/* get sda and slc pins */
+#if 0
 		exynos_gpio_pinset_to_pindata(pinset,
 			loc->loc_sda, &ei2c_sc->isc_sda);
 		exynos_gpio_pinset_to_pindata(pinset,
@@ -237,6 +239,7 @@ exynos_iic_attach_i2cbus(struct exynos_i
 		ei2c_sc->isc_sda_is_output = false;
 		exynos_gpio_pindata_ctl(&ei2c_sc->isc_sda, GPIO_PIN_INPUT);
 		exynos_gpio_pindata_ctl(&ei2c_sc->isc_slc, GPIO_PIN_OUTPUT);
+#endif
 		return 1;
 	} else {
 		/* TBD: attach hardware driver */

Index: src/sys/arch/arm/samsung/exynos_soc.c
diff -u src/sys/arch/arm/samsung/exynos_soc.c:1.28 src/sys/arch/arm/samsung/exynos_soc.c:1.29
--- src/sys/arch/arm/samsung/exynos_soc.c:1.28	Thu Nov 19 05:44:41 2015
+++ src/sys/arch/arm/samsung/exynos_soc.c	Fri Dec 11 04:03:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos_soc.c,v 1.28 2015/11/19 05:44:41 marty Exp $	*/
+/*	$NetBSD: exynos_soc.c,v 1.29 2015/12/11 04:03:44 marty Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
 #define	_ARM32_BUS_DMA_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_soc.c,v 1.28 2015/11/19 05:44:41 marty Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_soc.c,v 1.29 2015/12/11 04:03:44 marty Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -690,94 +690,10 @@ exynos_device_register_post_config(devic
 	exyo_device_register_post_config(self, aux);
 }
 
-
-/*
- * USB power SoC dependent handling
- */
-
-#ifdef EXYNOS4
-static struct exynos_gpio_pinset e4_uhost_pwr_pinset = {
-	.pinset_group = "ETC6",
-	.pinset_func  = 0,
-	.pinset_mask  = __BIT(6) | __BIT(7),
-};
-#endif
-
-
-#ifdef EXYNOS5
-static struct exynos_gpio_pinset e5_uhost_pwr_pinset = {
-	.pinset_group = "ETC6",
-	.pinset_func  = 0,
-	.pinset_mask  = __BIT(5) | __BIT(6),
-};
-static struct exynos_gpio_pinset e5_usb3_bus0_pinset = {
-	.pinset_group = "GPK3",
-	.pinset_func  = 2,
-	.pinset_mask  = __BIT(0) | __BIT(1) | __BIT(3),
-};
-static struct exynos_gpio_pinset e5_usb3_bus1_pinset = {
-	.pinset_group = "GPK2",
-	.pinset_func  = 2,
-	.pinset_mask  = __BIT(4) | __BIT(5) | __BIT(7),
-};
-#endif
-
-
 void
 exynos_usb_soc_powerup(void)
 {
-	struct exynos_gpio_pindata XuhostOVERCUR;
-	struct exynos_gpio_pindata XuhostPWREN;
-
-#ifdef EXYNOS4
-		exynos_gpio_pinset_acquire(&e4_uhost_pwr_pinset);
-		exynos_gpio_pinset_to_pindata(&e4_uhost_pwr_pinset, 6, &XuhostPWREN);
-		exynos_gpio_pinset_to_pindata(&e4_uhost_pwr_pinset, 7, &XuhostOVERCUR);
-
-		/* enable power and set Xuhost OVERCUR to inactive by pulling it up */
-		exynos_gpio_pindata_ctl(&XuhostPWREN, GPIO_PIN_PULLUP);
-		exynos_gpio_pindata_ctl(&XuhostOVERCUR, GPIO_PIN_PULLUP);
-		DELAY(80000);
-#endif
-#ifdef EXYNOS5
-	if (IS_EXYNOS5410_P()) {
-		struct exynos_gpio_pindata Xovercur2, Xovercur3;
-		struct exynos_gpio_pindata Xvbus;
-
-		/* BUS 0 */
-		exynos_gpio_pinset_acquire(&e5_usb3_bus0_pinset);
-		exynos_gpio_pinset_to_pindata(&e5_usb3_bus0_pinset, 0, &Xovercur2);
-		exynos_gpio_pinset_to_pindata(&e5_usb3_bus0_pinset, 1, &Xovercur3);
-		exynos_gpio_pinset_to_pindata(&e5_usb3_bus0_pinset, 3, &Xvbus);
-
-		/* enable power and set overcur inactive by pulling them up */
-		exynos_gpio_pindata_ctl(&Xvbus, GPIO_PIN_PULLUP);
-		exynos_gpio_pindata_ctl(&Xovercur2, GPIO_PIN_PULLUP);
-		exynos_gpio_pindata_ctl(&Xovercur3, GPIO_PIN_PULLUP);
-
-		/* BUS 1 */
-		exynos_gpio_pinset_acquire(&e5_usb3_bus1_pinset);
-		exynos_gpio_pinset_to_pindata(&e5_usb3_bus1_pinset, 4, &Xovercur2);
-		exynos_gpio_pinset_to_pindata(&e5_usb3_bus1_pinset, 5, &Xovercur3);
-		exynos_gpio_pinset_to_pindata(&e5_usb3_bus1_pinset, 7, &Xvbus);
-
-		/* enable power and set overcur inactive by pulling them up */
-		exynos_gpio_pindata_ctl(&Xvbus, GPIO_PIN_PULLUP);
-		exynos_gpio_pindata_ctl(&Xovercur2, GPIO_PIN_PULLUP);
-		exynos_gpio_pindata_ctl(&Xovercur3, GPIO_PIN_PULLUP);
-
-		/* enable power to the hub */
-		exynos_gpio_pinset_acquire(&e5_uhost_pwr_pinset);
-		exynos_gpio_pinset_to_pindata(&e5_uhost_pwr_pinset, 5, &XuhostPWREN);
-		exynos_gpio_pinset_to_pindata(&e5_uhost_pwr_pinset, 6, &XuhostOVERCUR);
-
-		/* enable power and set Xuhost OVERCUR to inactive by pulling it up */
-		exynos_gpio_pindata_ctl(&XuhostPWREN, GPIO_PIN_PULLUP);
-		exynos_gpio_pindata_ctl(&XuhostOVERCUR, GPIO_PIN_PULLUP);
-		DELAY(80000);
-	}
 	/* XXX 5422 XXX */
-#endif
 }
 
 

Index: src/sys/arch/arm/samsung/exynos_var.h
diff -u src/sys/arch/arm/samsung/exynos_var.h:1.18 src/sys/arch/arm/samsung/exynos_var.h:1.19
--- src/sys/arch/arm/samsung/exynos_var.h:1.18	Tue Sep 30 14:23:41 2014
+++ src/sys/arch/arm/samsung/exynos_var.h	Fri Dec 11 04:03:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: exynos_var.h,v 1.18 2014/09/30 14:23:41 reinoud Exp $	*/
+/*	$NetBSD: exynos_var.h,v 1.19 2015/12/11 04:03:44 marty Exp $	*/
 
 /*-
  * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -94,7 +94,7 @@ struct exyo_attach_args {
 };
 
 struct exynos_gpio_pinset {
-	char pinset_group[10];
+	char pinset_bank[10];
 	uint8_t pinset_func;
 	uint8_t pinset_mask;
 };

Index: src/sys/arch/arm/samsung/mct.c
diff -u src/sys/arch/arm/samsung/mct.c:1.5 src/sys/arch/arm/samsung/mct.c:1.6
--- src/sys/arch/arm/samsung/mct.c:1.5	Thu Aug 28 20:29:05 2014
+++ src/sys/arch/arm/samsung/mct.c	Fri Dec 11 04:03:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: mct.c,v 1.5 2014/08/28 20:29:05 snj Exp $	*/
+/*	$NetBSD: mct.c,v 1.6 2015/12/11 04:03:44 marty Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.5 2014/08/28 20:29:05 snj Exp $");
+__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.6 2015/12/11 04:03:44 marty Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -54,12 +54,11 @@ static int  mct_match(device_t, cfdata_t
 static void mct_attach(device_t, device_t, void *);
 
 static int clockhandler(void *);
-static u_int mct_get_timecount(struct timecounter *);
-
 
 CFATTACH_DECL_NEW(exyo_mct, 0, mct_match, mct_attach, NULL, NULL);
 
 
+#if 0
 static struct timecounter mct_timecounter = {
 	.tc_get_timecount = mct_get_timecount,
 	.tc_poll_pps = 0,
@@ -70,6 +69,7 @@ static struct timecounter mct_timecounte
 	.tc_priv = &mct_sc,
 	.tc_next = NULL,
 };
+#endif
 
 
 static inline uint32_t
@@ -188,6 +188,7 @@ mct_attach(device_t parent, device_t sel
 		panic("%s: unable to register timer interrupt", __func__);
 	aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n", sc->sc_irq);
 
+#if 0
 	/* blink led */
 	if (prop_dictionary_get_cstring_nocopy(dict, "heartbeat", &pin_name)) {
 		if (!exynos_gpio_pin_reserve(pin_name, &sc->sc_gpio_led)) {
@@ -200,6 +201,7 @@ mct_attach(device_t parent, device_t sel
 			sc->sc_led_timer = hz;
 		}
 	}
+#endif
 }
 
 
@@ -215,14 +217,6 @@ mct_gettime(struct mct_softc *sc)
 }
 
 
-static u_int
-mct_get_timecount(struct timecounter *tc)
-{
-	struct mct_softc * const sc = tc->tc_priv;
-	return (u_int) (mct_gettime(sc));
-}
-
-
 /* interrupt handler */
 static int
 clockhandler(void *arg)
@@ -299,6 +293,7 @@ mct_init_cpu_clock(struct cpu_info *ci)
 }
 
 
+#if 0
 void
 cpu_initclocks(void)
 {
@@ -331,9 +326,4 @@ cpu_initclocks(void)
 #endif
 }
 
-
-void
-setstatclockrate(int newhz)
-{
-}
-
+#endif

Reply via email to