From 25c393f3713647dadbebd0f5fb48e76aca2f72b8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 5 Jul 2013 17:15:54 -0600 Subject: [PATCH] prohibit re-entrance into sam_configgpio() --- ChangeLog | 2 ++ arch/arm/src/sam34/sam3u_gpio.c | 12 ++++++---- arch/arm/src/sam34/sam_gpioirq.c | 40 ++++++++++++++++---------------- include/nuttx/spi/spi_bitbang.c | 28 ++++++++++------------ 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17c2309681..d822b36a5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5111,4 +5111,6 @@ * /drivers/usbdev/composite.c: Fix a type in the composite device driver unitialization logic. DEV1 should be DEV2 in one case (2013-7-4). + * arch/arm/src/sam34/sam3u_gpio.c: sam_configgpio() must protect + against re-entrancy (2013-7-5). diff --git a/arch/arm/src/sam34/sam3u_gpio.c b/arch/arm/src/sam34/sam3u_gpio.c index d94f2a3f86..abaec84daa 100644 --- a/arch/arm/src/sam34/sam3u_gpio.c +++ b/arch/arm/src/sam34/sam3u_gpio.c @@ -375,11 +375,14 @@ int sam_configgpio(gpio_pinset_t cfgset) { uintptr_t base = sam_gpiobase(cfgset); uint32_t pin = sam_gpiopin(cfgset); + irqstate_t flags; int ret; - /* Enable writing to GPIO registers - * TODO: This probably requires some protection against re-entry. - */ + /* Disable interrupts to prohibit re-entrance. */ + + flags = irqsave(); + + /* Enable writing to GPIO registers */ putreg32(PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); @@ -409,9 +412,10 @@ int sam_configgpio(gpio_pinset_t cfgset) break; } - /* Enable writing to GPIO registers */ + /* Disable writing to GPIO registers */ putreg32(PIO_WPMR_WPEN | PIO_WPMR_WPKEY, base + SAM_PIO_WPMR_OFFSET); + irqrestore(flags); return ret; } diff --git a/arch/arm/src/sam34/sam_gpioirq.c b/arch/arm/src/sam34/sam_gpioirq.c index 3b7c8a2a29..399a3eb191 100644 --- a/arch/arm/src/sam34/sam_gpioirq.c +++ b/arch/arm/src/sam34/sam_gpioirq.c @@ -169,14 +169,14 @@ static int sam_irqbase(int irq, uint32_t *base, int *pin) } /**************************************************************************** - * Name: up_gpioa/b/cinterrupt + * Name: sam_gpioa/b/cinterrupt * * Description: * Receive GPIOA/B/C interrupts * ****************************************************************************/ -static int up_gpiointerrupt(uint32_t base, int irq0, void *context) +static int sam_gpiointerrupt(uint32_t base, int irq0, void *context) { uint32_t pending; uint32_t bit; @@ -200,44 +200,44 @@ static int up_gpiointerrupt(uint32_t base, int irq0, void *context) } #ifdef CONFIG_GPIOA_IRQ -static int up_gpioainterrupt(int irq, void *context) +static int sam_gpioainterrupt(int irq, void *context) { - return up_gpiointerrupt(SAM_PIOA_BASE, SAM_IRQ_PA0, context); + return sam_gpiointerrupt(SAM_PIOA_BASE, SAM_IRQ_PA0, context); } #endif #ifdef CONFIG_GPIOB_IRQ -static int up_gpiobinterrupt(int irq, void *context) +static int sam_gpiobinterrupt(int irq, void *context) { - return up_gpiointerrupt(SAM_PIOB_BASE, SAM_IRQ_PB0, context); + return sam_gpiointerrupt(SAM_PIOB_BASE, SAM_IRQ_PB0, context); } #endif #ifdef CONFIG_GPIOC_IRQ -static int up_gpiocinterrupt(int irq, void *context) +static int sam_gpiocinterrupt(int irq, void *context) { - return up_gpiointerrupt(SAM_PIOC_BASE, SAM_IRQ_PC0, context); + return sam_gpiointerrupt(SAM_PIOC_BASE, SAM_IRQ_PC0, context); } #endif #ifdef CONFIG_GPIOD_IRQ -static int up_gpiodinterrupt(int irq, void *context) +static int sam_gpiodinterrupt(int irq, void *context) { - return up_gpiointerrupt(SAM_PIOD_BASE, SAM_IRQ_PD0, context); + return sam_gpiointerrupt(SAM_PIOD_BASE, SAM_IRQ_PD0, context); } #endif #ifdef CONFIG_GPIOE_IRQ -static int up_gpioeinterrupt(int irq, void *context) +static int sam_gpioeinterrupt(int irq, void *context) { - return up_gpiointerrupt(SAM_PIOE_BASE, SAM_IRQ_PE0, context); + return sam_gpiointerrupt(SAM_PIOE_BASE, SAM_IRQ_PE0, context); } #endif #ifdef CONFIG_GPIOF_IRQ -static int up_gpiofinterrupt(int irq, void *context) +static int sam_gpiofinterrupt(int irq, void *context) { - return up_gpiointerrupt(SAM_PIOF_BASE, SAM_IRQ_PF0, context); + return sam_gpiointerrupt(SAM_PIOF_BASE, SAM_IRQ_PF0, context); } #endif @@ -270,7 +270,7 @@ void sam_gpioirqinitialize(void) /* Attach and enable the GPIOA IRQ */ - (void)irq_attach(SAM_IRQ_PIOA, up_gpioainterrupt); + (void)irq_attach(SAM_IRQ_PIOA, sam_gpioainterrupt); up_enable_irq(SAM_IRQ_PIOA); #endif @@ -288,7 +288,7 @@ void sam_gpioirqinitialize(void) /* Attach and enable the GPIOB IRQ */ - (void)irq_attach(SAM_IRQ_PIOB, up_gpiobinterrupt); + (void)irq_attach(SAM_IRQ_PIOB, sam_gpiobinterrupt); up_enable_irq(SAM_IRQ_PIOB); #endif @@ -306,7 +306,7 @@ void sam_gpioirqinitialize(void) /* Attach and enable the GPIOC IRQ */ - (void)irq_attach(SAM_IRQ_PIOC, up_gpiocinterrupt); + (void)irq_attach(SAM_IRQ_PIOC, sam_gpiocinterrupt); up_enable_irq(SAM_IRQ_PIOC); #endif @@ -324,7 +324,7 @@ void sam_gpioirqinitialize(void) /* Attach and enable the GPIOC IRQ */ - (void)irq_attach(SAM_IRQ_PIOD, up_gpiodinterrupt); + (void)irq_attach(SAM_IRQ_PIOD, sam_gpiodinterrupt); up_enable_irq(SAM_IRQ_PIOD); #endif @@ -342,7 +342,7 @@ void sam_gpioirqinitialize(void) /* Attach and enable the GPIOE IRQ */ - (void)irq_attach(SAM_IRQ_PIOE, up_gpioeinterrupt); + (void)irq_attach(SAM_IRQ_PIOE, sam_gpioeinterrupt); up_enable_irq(SAM_IRQ_PIOE); #endif @@ -360,7 +360,7 @@ void sam_gpioirqinitialize(void) /* Attach and enable the GPIOF IRQ */ - (void)irq_attach(SAM_IRQ_PIOF, up_gpiofinterrupt); + (void)irq_attach(SAM_IRQ_PIOF, sam_gpiofinterrupt); up_enable_irq(SAM_IRQ_PIOF); #endif } diff --git a/include/nuttx/spi/spi_bitbang.c b/include/nuttx/spi/spi_bitbang.c index 80401bbecf..9149e6c7d8 100755 --- a/include/nuttx/spi/spi_bitbang.c +++ b/include/nuttx/spi/spi_bitbang.c @@ -337,12 +337,11 @@ static void spi_setmode(FAR struct spi_bitbang_s *priv, * +------------+ +------------+ * | | | | * SCLK ---------------+ +------------+ +------------ - * ` Set MOSI | `- Set MOSI | `- Set MOSI - * | | + * `- Set MOSI | `- Set MOSI | `- Set MOSI * `- Sample MISO `- Sample MISO * - * MISO <------------X------------><-----------X------------> - * MOSO + * MISO /-------------X-----------\/------------X-------------\/----------- + * MOSO \-------------X-----------/\------------X-------------/\----------- * * Input Parameters: * dev - Device-specific state data @@ -406,12 +405,11 @@ static uint16_t spi_bitexchange0(uint16_t dataout, uint32_t holdtime) * +------------+ +------------+ * | | | | * SCLK -+ +------------+ +------------ - * ` Set MOSI | `- Set MOSI | - * | | + * `- Set MOSI | `- Set MOSI | * `- Sample MISO `- Sample MISO * - * MISO <-----------X-------------><----------X-------------> - * MOSO + * MISO /-----------X------------\/-----------X-------------\/------------ + * MOSO \-----------X------------/\-----------X-------------/\------------ * * Input Parameters: * dev - Device-specific state data @@ -474,12 +472,11 @@ static uint16_t spi_bitexchange1(uint16_t dataout, uint32_t holdtime) * ---------------+ +------------+ +------------ * | | | | * SCLK +------------+ +------------+ - * ` Set MOSI | `- Set MOSI | `- Set MOSI - * | | - * `- Sample MISO `- Sample MISO + * `- Set MOSI | `- Set MOSI | `- Set MOSI + * `- Sample MISO `- Sample MISO * - * MISO <------------X------------><-----------X------------> - * MOSO + * MISO /-------------X------------\/-----------X-------------\/----------- + * MOSO \-------------X------------/\-----------X-------------/\----------- * * Input Parameters: * dev - Device-specific state data @@ -544,11 +541,10 @@ static uint16_t spi_bitexchange2(uint16_t dataout, uint32_t holdtime) * | | | | * SCLK +------------+ +------------+ * ` Set MOSI | `- Set MOSI | - * | | * `- Sample MISO `- Sample MISO * - * MISO <-----------X-------------><----------X-------------> - * MOSO + * MISO /-----------X------------\/-----------X-------------\/------------ + * MOSO \-----------X------------/\-----------X-------------/\------------ * * Input Parameters: * dev - Device-specific state data