mxs_gpio: correctly use the GPIO API
authorLothar Waßmann <LW@KARO-electronics.de>
Thu, 30 Jun 2016 13:40:18 +0000 (15:40 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Thu, 30 Jun 2016 13:40:18 +0000 (15:40 +0200)
The GPIO API expects a linear GPIO number as parameter to the gpio_*()
functions. The current implementation of the mxs_gpio driver operates on
iomux_cfg_t cookies instead. Therefore the 'gpio' command cannot be
used with this driver.
Change the driver to implement the correct API and introduce some
checks to catch users that still use the old semantics.
1. assert the most sigificant bit in the iomux_cfg_t pad definitions,
   so that using such a cookie in place of a GPIO number will
   decisively generate an invalid GPIO number and flag an error at runtime.
2. introduce a compile switch CONFIG_MXS_IOMUX_COMPILE_CHECK to make
   the iomux_cfg_t cookie a 64 bit variable, so that passing an
   iomux_cfg_t value to a gpio_*() function will generate a compile
   time error.

arch/arm/include/asm/arch-mxs/gpio.h
arch/arm/include/asm/arch-mxs/iomux.h
board/denx/m28evk/m28evk.c
board/freescale/mx23evk/mx23evk.c
board/freescale/mx28evk/mx28evk.c
board/karo/tx28/tx28.c
board/olimex/mx23_olinuxino/mx23_olinuxino.c
drivers/gpio/mxs_gpio.c
include/configs/mx23_olinuxino.h

index 3bdf879..ac028f3 100644 (file)
@@ -16,4 +16,8 @@ void mxs_gpio_init(void);
 inline void mxs_gpio_init(void) {}
 #endif
 
+#define MXS_GPIO_NR(p, o)      (((p) * 32) | ((o) & 0x1f))
+#define MXS_GPIO_TO_BANK(gpio) ((gpio) / 32)
+#define MXS_GPIO_TO_PIN(gpio)  ((gpio) % 32)
+
 #endif /* __MX28_GPIO_H__ */
index 4a0ad73..a1d9016 100644 (file)
  * PAD_VOL_VALID:      14      (1)
  * PAD_PULL:           15      (1)
  * PAD_PULL_VALID:     16      (1)
- * RESERVED:           17..31  (15)
+ * RESERVED:           17..30  (14)
+ * sentinel to produce an invalid GPIO number when using an
+ * iomux_cfg_t value where a plain GPIO number is expected
+ * GPIO_SENTINEL:      31      (1)
  */
+#ifdef CONFIG_MXS_IOMUX_COMPILE_CHECK
+typedef u64 iomux_cfg_t;
+#define IOMUX_CFG_SHIFT                32
+#else
 typedef u32 iomux_cfg_t;
+#define IOMUX_CFG_SHIFT                0
+#endif
 
-#define MXS_PAD_BANK_SHIFT     0
+#define MXS_PAD_BANK_SHIFT     (IOMUX_CFG_SHIFT + 0)
 #define MXS_PAD_BANK_MASK      ((iomux_cfg_t)0x7 << MXS_PAD_BANK_SHIFT)
-#define MXS_PAD_PIN_SHIFT      3
+#define MXS_PAD_PIN_SHIFT      (IOMUX_CFG_SHIFT + 3)
 #define MXS_PAD_PIN_MASK       ((iomux_cfg_t)0x1f << MXS_PAD_PIN_SHIFT)
-#define MXS_PAD_MUXSEL_SHIFT   8
+#define MXS_PAD_MUXSEL_SHIFT   (IOMUX_CFG_SHIFT + 8)
 #define MXS_PAD_MUXSEL_MASK    ((iomux_cfg_t)0x3 << MXS_PAD_MUXSEL_SHIFT)
-#define MXS_PAD_MA_SHIFT       10
+#define MXS_PAD_MA_SHIFT       (IOMUX_CFG_SHIFT + 10)
 #define MXS_PAD_MA_MASK                ((iomux_cfg_t)0x3 << MXS_PAD_MA_SHIFT)
-#define MXS_PAD_MA_VALID_SHIFT 12
+#define MXS_PAD_MA_VALID_SHIFT (IOMUX_CFG_SHIFT + 12)
 #define MXS_PAD_MA_VALID_MASK  ((iomux_cfg_t)0x1 << MXS_PAD_MA_VALID_SHIFT)
-#define MXS_PAD_VOL_SHIFT      13
+#define MXS_PAD_VOL_SHIFT      (IOMUX_CFG_SHIFT + 13)
 #define MXS_PAD_VOL_MASK       ((iomux_cfg_t)0x1 << MXS_PAD_VOL_SHIFT)
-#define MXS_PAD_VOL_VALID_SHIFT        14
+#define MXS_PAD_VOL_VALID_SHIFT        (IOMUX_CFG_SHIFT + 14)
 #define MXS_PAD_VOL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_VALID_SHIFT)
-#define MXS_PAD_PULL_SHIFT     15
+#define MXS_PAD_PULL_SHIFT     (IOMUX_CFG_SHIFT + 15)
 #define MXS_PAD_PULL_MASK      ((iomux_cfg_t)0x1 << MXS_PAD_PULL_SHIFT)
-#define MXS_PAD_PULL_VALID_SHIFT 16
+#define MXS_PAD_PULL_VALID_SHIFT (IOMUX_CFG_SHIFT + 16)
 #define MXS_PAD_PULL_VALID_MASK        ((iomux_cfg_t)0x1 << MXS_PAD_PULL_VALID_SHIFT)
 
-#define PAD_MUXSEL_0           0
-#define PAD_MUXSEL_1           1
-#define PAD_MUXSEL_2           2
-#define PAD_MUXSEL_GPIO                3
+#define MXS_GPIO_SENTINEL_SHIFT        (IOMUX_CFG_SHIFT + 31)
+#define MXS_GPIO_SENTINEL_MASK ((iomux_cfg_t)0x1 << MXS_GPIO_SENTINEL_SHIFT)
 
-#define PAD_4MA                        0
-#define PAD_8MA                        1
-#define PAD_12MA               2
-#define PAD_16MA               3
+#define PAD_MUXSEL_0           (iomux_cfg_t)0
+#define PAD_MUXSEL_1           (iomux_cfg_t)1
+#define PAD_MUXSEL_2           (iomux_cfg_t)2
+#define PAD_MUXSEL_GPIO                (iomux_cfg_t)3
 
-#define PAD_1V8                        0
+#define PAD_4MA                        (iomux_cfg_t)0
+#define PAD_8MA                        (iomux_cfg_t)1
+#define PAD_12MA               (iomux_cfg_t)2
+#define PAD_16MA               (iomux_cfg_t)3
+
+#define PAD_1V8                        (iomux_cfg_t)0
 #if defined(CONFIG_SOC_MX28)
-#define PAD_3V3                        1
+#define PAD_3V3                        (iomux_cfg_t)1
 #else
-#define PAD_3V3                        0
+#define PAD_3V3                        (iomux_cfg_t)0
 #endif
 
-#define PAD_NOPULL             0
-#define PAD_PULLUP             1
+#define PAD_NOPULL             (iomux_cfg_t)0
+#define PAD_PULLUP             (iomux_cfg_t)1
 
 #define MXS_PAD_4MA    ((PAD_4MA << MXS_PAD_MA_SHIFT) | \
                                        MXS_PAD_MA_VALID_MASK)
@@ -96,7 +108,13 @@ typedef u32 iomux_cfg_t;
                ((iomux_cfg_t)(_muxsel) << MXS_PAD_MUXSEL_SHIFT) |      \
                ((iomux_cfg_t)(_ma) << MXS_PAD_MA_SHIFT) |              \
                ((iomux_cfg_t)(_vol) << MXS_PAD_VOL_SHIFT) |            \
-               ((iomux_cfg_t)(_pull) << MXS_PAD_PULL_SHIFT))
+               ((iomux_cfg_t)(_pull) << MXS_PAD_PULL_SHIFT) |          \
+               ((iomux_cfg_t)1 << 31))
+
+#define MXS_PAD_TO_GPIO(p)     ((unsigned)(((((p) & MXS_PAD_BANK_MASK) >> \
+                                       MXS_PAD_BANK_SHIFT) << 5) |     \
+                                       ((p) & MXS_PAD_PIN_MASK) >>     \
+                                       MXS_PAD_PIN_SHIFT))
 
 /*
  * A pad becomes naked, when none of mA, vol or pull
index 33d38cf..b0bb934 100644 (file)
@@ -40,11 +40,11 @@ int board_early_init_f(void)
        mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
        mxs_iomux_setup_pad(MX28_PAD_AUART3_TX__GPIO_3_13 |
                        MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
-       gpio_direction_output(MX28_PAD_AUART3_TX__GPIO_3_13, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART3_TX__GPIO_3_13), 0);
 
        mxs_iomux_setup_pad(MX28_PAD_AUART3_RX__GPIO_3_12 |
                        MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
-       gpio_direction_output(MX28_PAD_AUART3_RX__GPIO_3_12, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART3_RX__GPIO_3_12), 0);
 #endif
 
        return 0;
@@ -71,15 +71,15 @@ static int m28_mmc_wp(int id)
                return 1;
        }
 
-       return gpio_get_value(MX28_PAD_AUART2_CTS__GPIO_3_10);
+       return gpio_get_value(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_CTS__GPIO_3_10));
 }
 
 int board_mmc_init(bd_t *bis)
 {
        /* Configure WP as input. */
-       gpio_direction_input(MX28_PAD_AUART2_CTS__GPIO_3_10);
+       gpio_direction_input(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_CTS__GPIO_3_10));
        /* Turn on the power to the card. */
-       gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM3__GPIO_3_28), 0);
 
        return mxsmmc_initialize(bis, 0, m28_mmc_wp, NULL);
 }
@@ -125,9 +125,9 @@ int board_eth_init(bd_t *bis)
 
 #if !defined(CONFIG_DENX_M28_V11) && !defined(CONFIG_DENX_M28_V10)
        /* Reset the new PHY */
-       gpio_direction_output(MX28_PAD_AUART2_RTS__GPIO_3_11, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RTS__GPIO_3_11), 0);
        udelay(10000);
-       gpio_set_value(MX28_PAD_AUART2_RTS__GPIO_3_11, 1);
+       gpio_set_value(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RTS__GPIO_3_11), 1);
        udelay(10000);
 #endif
 
index 9428182..a3fe4c1 100644 (file)
@@ -33,10 +33,10 @@ int board_early_init_f(void)
        mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
 
        /* Power on LCD */
-       gpio_direction_output(MX23_PAD_LCD_RESET__GPIO_1_18, 1);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_LCD_RESET__GPIO_1_18), 1);
 
        /* Set contrast to maximum */
-       gpio_direction_output(MX23_PAD_PWM2__GPIO_1_28, 1);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_PWM2__GPIO_1_28), 1);
 
        return 0;
 }
@@ -62,16 +62,16 @@ static int mx23evk_mmc_wp(int id)
                return 1;
        }
 
-       return gpio_get_value(MX23_PAD_PWM4__GPIO_1_30);
+       return gpio_get_value(MXS_PAD_TO_GPIO(MX23_PAD_PWM4__GPIO_1_30));
 }
 
 int board_mmc_init(bd_t *bis)
 {
        /* Configure WP as input */
-       gpio_direction_input(MX23_PAD_PWM4__GPIO_1_30);
+       gpio_direction_input(MXS_PAD_TO_GPIO(MX23_PAD_PWM4__GPIO_1_30));
 
        /* Configure MMC0 Power Enable */
-       gpio_direction_output(MX23_PAD_PWM3__GPIO_1_29, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_PWM3__GPIO_1_29), 0);
 
        return mxsmmc_initialize(bis, 0, mx23evk_mmc_wp, NULL);
 }
index 5005fe2..0f23c30 100644 (file)
@@ -45,14 +45,14 @@ int board_early_init_f(void)
        mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
        mxs_iomux_setup_pad(MX28_PAD_AUART2_RX__GPIO_3_8 |
                        MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL);
-       gpio_direction_output(MX28_PAD_AUART2_RX__GPIO_3_8, 1);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RX__GPIO_3_8), 1);
 #endif
 
        /* Power on LCD */
-       gpio_direction_output(MX28_PAD_LCD_RESET__GPIO_3_30, 1);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_LCD_RESET__GPIO_3_30), 1);
 
        /* Set contrast to maximum */
-       gpio_direction_output(MX28_PAD_PWM2__GPIO_3_18, 1);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM2__GPIO_3_18), 1);
 
        return 0;
 }
@@ -78,16 +78,16 @@ static int mx28evk_mmc_wp(int id)
                return 1;
        }
 
-       return gpio_get_value(MX28_PAD_SSP1_SCK__GPIO_2_12);
+       return gpio_get_value(MXS_PAD_TO_GPIO(MX28_PAD_SSP1_SCK__GPIO_2_12));
 }
 
 int board_mmc_init(bd_t *bis)
 {
        /* Configure WP as input */
-       gpio_direction_input(MX28_PAD_SSP1_SCK__GPIO_2_12);
+       gpio_direction_input(MXS_PAD_TO_GPIO(MX28_PAD_SSP1_SCK__GPIO_2_12));
 
        /* Configure MMC0 Power Enable */
-       gpio_direction_output(MX28_PAD_PWM3__GPIO_3_28, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM3__GPIO_3_28), 0);
 
        return mxsmmc_initialize(bis, 0, mx28evk_mmc_wp, NULL);
 }
@@ -111,12 +111,12 @@ int board_eth_init(bd_t *bis)
               &clkctrl_regs->hw_clkctrl_enet);
 
        /* Power-on FECs */
-       gpio_direction_output(MX28_PAD_SSP1_DATA3__GPIO_2_15, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_SSP1_DATA3__GPIO_2_15), 0);
 
        /* Reset FEC PHYs */
-       gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_CLK__GPIO_4_13), 0);
        udelay(200);
-       gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
+       gpio_set_value(MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_CLK__GPIO_4_13), 1);
 
        ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
        if (ret) {
index 273463e..b7ece92 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/fb.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
+#include <asm/arch/iomux.h>
 #include <asm/arch/iomux-mx28.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define MXS_GPIO_NR(p, o)      (((p) << 5) | (o))
+#define TX28_LCD_PWR_GPIO      MXS_PAD_TO_GPIO(MX28_PAD_LCD_ENABLE__GPIO_1_31)
+#define TX28_LCD_RST_GPIO      MXS_PAD_TO_GPIO(MX28_PAD_LCD_RESET__GPIO_3_30)
+#define TX28_LCD_BACKLIGHT_GPIO        MXS_PAD_TO_GPIO(MX28_PAD_PWM0__GPIO_3_16)
 
-#define TX28_LCD_PWR_GPIO      MX28_PAD_LCD_ENABLE__GPIO_1_31
-#define TX28_LCD_RST_GPIO      MX28_PAD_LCD_RESET__GPIO_3_30
-#define TX28_LCD_BACKLIGHT_GPIO        MX28_PAD_PWM0__GPIO_3_16
+#define TX28_USBH_VBUSEN_GPIO  MXS_PAD_TO_GPIO(MX28_PAD_SPDIF__GPIO_3_27)
+#define TX28_USBH_OC_GPIO      MXS_PAD_TO_GPIO(MX28_PAD_JTAG_RTCK__GPIO_4_20)
+#define TX28_USBOTG_VBUSEN_GPIO        MXS_PAD_TO_GPIO(MX28_PAD_GPMI_CE2N__GPIO_0_18)
+#define TX28_USBOTG_OC_GPIO    MXS_PAD_TO_GPIO(MX28_PAD_GPMI_CE3N__GPIO_0_19)
+#define TX28_USBOTG_ID_GPIO    MXS_PAD_TO_GPIO(MX28_PAD_PWM2__GPIO_3_18)
 
-#define TX28_USBH_VBUSEN_GPIO  MX28_PAD_SPDIF__GPIO_3_27
-#define TX28_USBH_OC_GPIO      MX28_PAD_JTAG_RTCK__GPIO_4_20
-#define TX28_USBOTG_VBUSEN_GPIO        MX28_PAD_GPMI_CE2N__GPIO_0_18
-#define TX28_USBOTG_OC_GPIO    MX28_PAD_GPMI_CE3N__GPIO_0_19
-#define TX28_USBOTG_ID_GPIO    MX28_PAD_PWM2__GPIO_3_18
+#define TX28_LED_GPIO          MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RXD3__GPIO_4_10)
 
-#define TX28_LED_GPIO          MX28_PAD_ENET0_RXD3__GPIO_4_10
-
-#define STK5_CAN_XCVR_GPIO     MX28_PAD_LCD_D00__GPIO_1_0
+#define STK5_CAN_XCVR_PAD      MX28_PAD_LCD_D00__GPIO_1_0
+#define STK5_CAN_XCVR_GPIO     MXS_PAD_TO_GPIO(STK5_CAN_XCVR_PAD)
 
 #define ENET_PAD_CTRL          (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
 #define GPIO_PAD_CTRL          (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
@@ -297,24 +297,38 @@ static const iomux_cfg_t tx28_fec_pads[] = {
        MX28_PAD_ENET0_RXD1__ENET0_RXD1 | ENET_PAD_CTRL,
 };
 
+static struct gpio tx28_fec_strap_gpios[] = {
+       /* first entry must be RESET pin */
+       { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_CLK__GPIO_4_13),
+         GPIOFLAG_OUTPUT_INIT_LOW, "PHY Reset", },
+
+       { MXS_PAD_TO_GPIO(MX28_PAD_PWM4__GPIO_3_29),
+         GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Power", },
+
+       /* Pull strap pins to high */
+       { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RX_EN__GPIO_4_2),
+         GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Mode0", },
+       { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RXD0__GPIO_4_3),
+         GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Mode1", },
+       { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_RXD1__GPIO_4_4),
+         GPIOFLAG_OUTPUT_INIT_HIGH, "PHY Mode2", },
+
+       { MXS_PAD_TO_GPIO(MX28_PAD_ENET0_TX_CLK__GPIO_4_5),
+         GPIOFLAG_INPUT, "PHY INT", },
+};
+
 int board_eth_init(bd_t *bis)
 {
        int ret;
 
        /* Reset the external phy */
-       gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
-
-       /* Power on the external phy */
-       gpio_direction_output(MX28_PAD_PWM4__GPIO_3_29, 1);
-
-       /* Pull strap pins to high */
-       gpio_direction_output(MX28_PAD_ENET0_RX_EN__GPIO_4_2, 1);
-       gpio_direction_output(MX28_PAD_ENET0_RXD0__GPIO_4_3, 1);
-       gpio_direction_output(MX28_PAD_ENET0_RXD1__GPIO_4_4, 1);
-       gpio_direction_input(MX28_PAD_ENET0_TX_CLK__GPIO_4_5);
+       ret = gpio_request_array(tx28_fec_strap_gpios,
+                               ARRAY_SIZE(tx28_fec_strap_gpios));
+       if (ret)
+               printf("Failed to request FEC GPIOs: %d\n", ret);
 
        udelay(25000);
-       gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
+       gpio_set_value(tx28_fec_strap_gpios[0].gpio, 1);
        udelay(100);
 
        mxs_iomux_setup_multiple_pads(tx28_fec_pads, ARRAY_SIZE(tx28_fec_pads));
@@ -840,7 +854,7 @@ static void stk5v5_board_init(void)
        /* init flexcan transceiver enable GPIO */
        gpio_request_one(STK5_CAN_XCVR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH,
                        "Flexcan Transceiver");
-       mxs_iomux_setup_pad(STK5_CAN_XCVR_GPIO);
+       mxs_iomux_setup_pad(STK5_CAN_XCVR_PAD);
 }
 
 int board_late_init(void)
index 65cbbf1..34fd869 100644 (file)
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
+#include <asm/arch/iomux.h>
 #include <asm/arch/iomux-mx23.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
@@ -37,7 +38,7 @@ int board_early_init_f(void)
 int board_ehci_hcd_init(int port)
 {
        /* Enable LAN9512 (Maxi) or GL850G (Mini) USB HUB power. */
-       gpio_direction_output(MX23_PAD_GPMI_ALE__GPIO_0_17, 1);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_GPMI_ALE__GPIO_0_17), 1);
        udelay(100);
        return 0;
 }
@@ -45,7 +46,7 @@ int board_ehci_hcd_init(int port)
 int board_ehci_hcd_exit(int port)
 {
        /* Enable LAN9512 (Maxi) or GL850G (Mini) USB HUB power. */
-       gpio_direction_output(MX23_PAD_GPMI_ALE__GPIO_0_17, 0);
+       gpio_direction_output(MXS_PAD_TO_GPIO(MX23_PAD_GPMI_ALE__GPIO_0_17), 0);
        return 0;
 }
 #endif
index f761104..e0e627d 100644 (file)
@@ -49,55 +49,73 @@ void mxs_gpio_init(void)
 
 int gpio_get_value(unsigned gpio)
 {
-       uint32_t bank = PAD_BANK(gpio);
+       uint32_t bank = MXS_GPIO_TO_BANK(gpio);
        uint32_t offset = PINCTRL_DIN(bank);
        struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
 
-       return (readl(&reg->reg) >> PAD_PIN(gpio)) & 1;
+       if (bank >= PINCTRL_BANKS)
+               return -EINVAL;
+
+       return (readl(&reg->reg) >> MXS_GPIO_TO_PIN(gpio)) & 1;
 }
 
 int gpio_set_value(unsigned gpio, int value)
 {
-       uint32_t bank = PAD_BANK(gpio);
+       uint32_t bank = MXS_GPIO_TO_BANK(gpio);
        uint32_t offset = PINCTRL_DOUT(bank);
        struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
 
+       if (bank >= PINCTRL_BANKS)
+               return -EINVAL;
+
        if (value)
-               writel(1 << PAD_PIN(gpio), &reg->reg_set);
+               writel(1 << MXS_GPIO_TO_PIN(gpio), &reg->reg_set);
        else
-               writel(1 << PAD_PIN(gpio), &reg->reg_clr);
+               writel(1 << MXS_GPIO_TO_PIN(gpio), &reg->reg_clr);
 
        return 0;
 }
 
 int gpio_direction_input(unsigned gpio)
 {
-       uint32_t bank = PAD_BANK(gpio);
+       uint32_t bank = MXS_GPIO_TO_BANK(gpio);
        uint32_t offset = PINCTRL_DOE(bank);
        struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
 
-       writel(1 << PAD_PIN(gpio), &reg->reg_clr);
+       if (bank >= PINCTRL_BANKS)
+               return -EINVAL;
+
+       writel(1 << MXS_GPIO_TO_PIN(gpio), &reg->reg_clr);
 
        return 0;
 }
 
 int gpio_direction_output(unsigned gpio, int value)
 {
-       uint32_t bank = PAD_BANK(gpio);
+       uint32_t bank = MXS_GPIO_TO_BANK(gpio);
        uint32_t offset = PINCTRL_DOE(bank);
        struct mxs_register_32 *reg = (void *)(MXS_PINCTRL_BASE + offset);
 
+       if (bank >= PINCTRL_BANKS)
+               return -EINVAL;
+
        gpio_set_value(gpio, value);
 
-       writel(1 << PAD_PIN(gpio), &reg->reg_set);
+       writel(1 << MXS_GPIO_TO_PIN(gpio), &reg->reg_set);
 
        return 0;
 }
 
 int gpio_request(unsigned gpio, const char *label)
 {
-       if (PAD_BANK(gpio) >= PINCTRL_BANKS)
-               return -1;
+       if (MXS_GPIO_TO_BANK(gpio) >= PINCTRL_BANKS) {
+               printf("%s(): Invalid GPIO%d (GPIO_%u_%u) requested; possibly intended: GPIO_%u_%u\n",
+                       __func__, gpio, gpio / 32, gpio % 32,
+                       PAD_BANK(gpio), PAD_PIN(gpio));
+               printf("Linear GPIO number required rather than iomux_cfg_t cookie!\n");
+               printf("Possibly missing MXS_PAD_TO_GPIO() in the GPIO specification.\n");
+               return -EINVAL;
+       }
 
        return 0;
 }
index b630973..eeb2290 100644 (file)
@@ -45,7 +45,7 @@
 #define CONFIG_GPIO_LED
 #define CONFIG_BOARD_SPECIFIC_LED
 #define STATUS_LED_BOOT                0
-#define STATUS_LED_BIT         MX23_PAD_SSP1_DETECT__GPIO_2_1
+#define STATUS_LED_BIT         MXS_PAD_TO_GPIO(MX23_PAD_SSP1_DETECT__GPIO_2_1)
 #define STATUS_LED_STATE       STATUS_LED_ON
 #define STATUS_LED_PERIOD      (CONFIG_SYS_HZ / 2)