From patchwork Wed Nov 23 15:08:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Robert_Deli=C3=ABn?= X-Patchwork-Id: 127320 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 53A031007D4 for ; Thu, 24 Nov 2011 02:09:12 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D9F242821B; Wed, 23 Nov 2011 16:09:08 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GYU6hjrqvDCK; Wed, 23 Nov 2011 16:09:08 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 19A942820D; Wed, 23 Nov 2011 16:09:07 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6C0A82820D for ; Wed, 23 Nov 2011 16:09:04 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id W6HMJq6Ykwtx for ; Wed, 23 Nov 2011 16:09:03 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from smarthost.danego.net (smarthost.danego.net [195.246.116.68]) by theia.denx.de (Postfix) with ESMTP id 522A02820A for ; Wed, 23 Nov 2011 16:09:01 +0100 (CET) Received: from smtp.danego.net (smtp.danego.net [195.246.116.61]) by smarthost.danego.net (Postfix) with ESMTP id 847D01C2820A; Wed, 23 Nov 2011 16:31:31 +0100 (CET) From: =?iso-8859-1?Q?Robert_Deli=EBn?= To: "u-boot@lists.denx.de" Thread-Topic: [PATCH] M28: GPIO pin validity check added Thread-Index: AQHMqfHTUbCQWVk1LECNMGD/FFjy4Q== Date: Wed, 23 Nov 2011 15:08:58 +0000 Message-ID: <2A9FB46C-1E1C-4127-9636-8E83FBE93ED7@Delien.nl> Accept-Language: en-GB, nl-NL, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [57.66.175.6] Content-ID: MIME-Version: 1.0 X-Spam: Subject: [U-Boot] [PATCH] M28: GPIO pin validity check added X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This patch adds a validity check for GPIO pins to prevent clobbering reserved bit or even registers, per suggestion of Marek Vasut. Please note: 1. gpio_request no longer checks validity. Pin validity must be checked explicitly use gpio_invalid prior to request and hence use. Previous validity check in gpio_request was incomplete anyway. 2. MX233 is not supported yet. Until it is, macros defining the number of pins for each bank reside in arch/arm/include/asm/arch-mx28/iomux.h Signed-off-by: Robert Deliƫn diff --git a/arch/arm/include/asm/arch-mx28/gpio.h b/arch/arm/include/asm/arch-mx28/gpio.h index be1c944..36f3be8 100644 --- a/arch/arm/include/asm/arch-mx28/gpio.h +++ b/arch/arm/include/asm/arch-mx28/gpio.h @@ -25,6 +25,10 @@ #ifdef CONFIG_MXS_GPIO void mxs_gpio_init(void); + +extern int gpio_invalid(int gp); +#define gpio_invalid(gpio) gpio_invalid(gpio) + #else inline void mxs_gpio_init(void) {} #endif diff --git a/arch/arm/include/asm/arch-mx28/iomux.h b/arch/arm/include/asm/arch-mx28/iomux.h index 7abdf58..2326fdb 100644 --- a/arch/arm/include/asm/arch-mx28/iomux.h +++ b/arch/arm/include/asm/arch-mx28/iomux.h @@ -56,6 +56,16 @@ typedef u32 iomux_cfg_t; #define MXS_PAD_PULL_VALID_SHIFT 16 #define MXS_PAD_PULL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_VALID_SHIFT) +#define MX28_BANK0_PINS 29 +#define MX28_BANK1_PINS 32 +#define MX28_BANK2_PINS 28 +#define MX28_BANK3_PINS 31 +#define MX28_BANK4_PINS 21 + +#define MX23_BANK0_PINS 32 +#define MX23_BANK1_PINS 31 +#define MX23_BANK2_PINS 32 + #define PAD_MUXSEL_0 0 #define PAD_MUXSEL_1 1 #define PAD_MUXSEL_2 2 diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 9cc790a..f81c7d8 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -15,6 +15,10 @@ #define name_to_gpio(name) simple_strtoul(name, NULL, 10) #endif +#ifndef gpio_invalid +#define gpio_invalid(gpio) (0) +#endif + enum gpio_cmd { GPIO_INPUT, GPIO_SET, @@ -56,6 +60,12 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (gpio < 0) goto show_usage; + /* check bank and pin number for validity */ + if (gpio_invalid(gpio)) { + printf("gpio: invalid pin %u\n", gpio); + return (-1); + } + /* grab the pin before we tweak it */ if (gpio_request(gpio, "cmd_gpio")) { printf("gpio: requesting pin %u failed\n", gpio); diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c index b7e9591..d2e9bac 100644 --- a/drivers/gpio/mxs_gpio.c +++ b/drivers/gpio/mxs_gpio.c @@ -31,7 +31,6 @@ #include #if defined(CONFIG_MX23) -#define PINCTRL_BANKS 3 #define PINCTRL_DOUT(n) (0x0500 + ((n) * 0x10)) #define PINCTRL_DIN(n) (0x0600 + ((n) * 0x10)) #define PINCTRL_DOE(n) (0x0700 + ((n) * 0x10)) @@ -39,7 +38,6 @@ #define PINCTRL_IRQEN(n) (0x0900 + ((n) * 0x10)) #define PINCTRL_IRQSTAT(n) (0x0c00 + ((n) * 0x10)) #elif defined(CONFIG_MX28) -#define PINCTRL_BANKS 5 #define PINCTRL_DOUT(n) (0x0700 + ((n) * 0x10)) #define PINCTRL_DIN(n) (0x0900 + ((n) * 0x10)) #define PINCTRL_DOE(n) (0x0b00 + ((n) * 0x10)) @@ -57,11 +55,25 @@ #define GPIO_INT_LEV_MASK (1 << 0) #define GPIO_INT_POL_MASK (1 << 1) +static const int mxs_bank_pins[] = { +#if defined(CONFIG_MX23) + MX23_BANK0_PINS, + MX23_BANK1_PINS, + MX23_BANK2_PINS +#elif defined(CONFIG_MX28) + MX28_BANK0_PINS, + MX28_BANK1_PINS, + MX28_BANK2_PINS, + MX28_BANK3_PINS, + MX28_BANK4_PINS +#endif +}; + void mxs_gpio_init(void) { int i; - for (i = 0; i < PINCTRL_BANKS; i++) { + for (i = 0; i < ARRAY_SIZE(mxs_bank_pins); i++) { writel(0, MXS_PINCTRL_BASE + PINCTRL_PIN2IRQ(i)); writel(0, MXS_PINCTRL_BASE + PINCTRL_IRQEN(i)); /* Use SCT address here to clear the IRQSTAT bits */ @@ -69,6 +81,16 @@ void mxs_gpio_init(void) } } +int gpio_invalid(int gp) +{ + if ( (gp & ~(MXS_PAD_BANK_MASK | MXS_PAD_PIN_MASK)) || + (PAD_BANK(gp) >= ARRAY_SIZE(mxs_bank_pins)) || + (PAD_PIN(gp) >= mxs_bank_pins[PAD_BANK(gp)]) ) + return (-EINVAL); + + return (0); +} + int gpio_get_value(int gp) { uint32_t bank = PAD_BANK(gp); @@ -120,9 +142,6 @@ int gpio_direction_output(int gp, int value) int gpio_request(int gp, const char *label) { - if (PAD_BANK(gp) > PINCTRL_BANKS) - return -EINVAL; - return 0; }