use small lock in following file
arch/arm/src/efm32/efm32_leserial.c arch/arm/src/efm32/efm32_serial.c arch/arm/src/gd32f4/gd32f4xx_serial.c arch/arm/src/imx9/imx9_edma.c arch/arm/src/imxrt/imxrt_edma.c arch/arm/src/imxrt/imxrt_hprtc.c arch/arm/src/kinetis/kinetis_lpserial.c arch/arm/src/lc823450/lc823450_gpio.c arch/arm/src/s32k1xx/s32k1xx_edma.c arch/arm/src/s32k3xx/s32k3xx_edma.c arch/arm64/src/imx9/imx9_edma.c Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
parent
b66c1b94ce
commit
9aa5eda649
11 changed files with 254 additions and 111 deletions
|
@ -134,6 +134,7 @@ struct efm32_leuart_s
|
|||
{
|
||||
const struct efm32_config_s *config;
|
||||
uint16_t ien; /* Interrupts enabled */
|
||||
spinlock_t lock; /* Spinlock */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -212,6 +213,7 @@ static const struct efm32_config_s g_leuart0config =
|
|||
static struct efm32_leuart_s g_leuart0priv =
|
||||
{
|
||||
.config = &g_leuart0config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_leuart0port =
|
||||
|
@ -247,6 +249,7 @@ static struct efm32_config_s g_leuart1config =
|
|||
static struct efm32_leuart_s g_leuart1priv =
|
||||
{
|
||||
.config = &g_leuart1config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_leuart1port =
|
||||
|
@ -303,6 +306,17 @@ static inline void efm32_setuartint(struct efm32_leuart_s *priv)
|
|||
* Name: efm32_restoreuartint
|
||||
****************************************************************************/
|
||||
|
||||
static void efm32_restoreuartint_nolock(struct efm32_leuart_s *priv,
|
||||
uint32_t ien)
|
||||
{
|
||||
/* Re-enable/re-disable interrupts corresponding to the state of
|
||||
* bits in ien.
|
||||
*/
|
||||
|
||||
priv->ien = ien;
|
||||
efm32_setuartint(priv);
|
||||
}
|
||||
|
||||
static void efm32_restoreuartint(struct efm32_leuart_s *priv, uint32_t ien)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -311,10 +325,9 @@ static void efm32_restoreuartint(struct efm32_leuart_s *priv, uint32_t ien)
|
|||
* bits in ien.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
priv->ien = ien;
|
||||
efm32_setuartint(priv);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
efm32_restoreuartint_nolock(priv, len);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -325,14 +338,14 @@ static void efm32_disableuartint(struct efm32_leuart_s *priv, uint32_t *ien)
|
|||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (ien)
|
||||
{
|
||||
*ien = priv->ien;
|
||||
}
|
||||
|
||||
efm32_restoreuartint(priv, 0);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
efm32_restoreuartint_nolock(priv, 0);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -607,7 +620,7 @@ static void efm32_rxint(struct uart_dev_s *dev, bool enable)
|
|||
struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (enable)
|
||||
{
|
||||
/* Receive an interrupt when there is anything in the Rx data register
|
||||
|
@ -625,7 +638,7 @@ static void efm32_rxint(struct uart_dev_s *dev, bool enable)
|
|||
efm32_setuartint(priv);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -673,7 +686,7 @@ static void efm32_txint(struct uart_dev_s *dev, bool enable)
|
|||
struct efm32_leuart_s *priv = (struct efm32_leuart_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (enable)
|
||||
{
|
||||
/* Enable the TX interrupt */
|
||||
|
@ -697,7 +710,7 @@ static void efm32_txint(struct uart_dev_s *dev, bool enable)
|
|||
efm32_setuartint(priv);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -223,6 +223,7 @@ struct efm32_usart_s
|
|||
const struct efm32_config_s *config;
|
||||
#endif
|
||||
uint16_t ien; /* Interrupts enabled */
|
||||
spinlock_t lock; /* Spinlock */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -303,7 +304,7 @@ static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
|
|||
/* This describes the state of the EFM32 USART0 port. */
|
||||
|
||||
#ifdef CONFIG_EFM32_USART0_ISUART
|
||||
static const struct efm32_usart_s g_usart0config =
|
||||
static const struct efm32_config_s g_usart0config =
|
||||
{
|
||||
.uartbase = EFM32_USART0_BASE,
|
||||
.baud = CONFIG_USART0_BAUD,
|
||||
|
@ -317,6 +318,7 @@ static const struct efm32_usart_s g_usart0config =
|
|||
static struct efm32_usart_s g_usart0priv =
|
||||
{
|
||||
.config = &g_usart0config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_usart0port =
|
||||
|
@ -353,6 +355,7 @@ static struct efm32_config_s g_usart1config =
|
|||
static struct efm32_usart_s g_usart1priv =
|
||||
{
|
||||
.config = &g_usart1config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_usart1port =
|
||||
|
@ -389,6 +392,7 @@ static struct efm32_config_s g_usart2config =
|
|||
static struct efm32_usart_s g_usart2priv =
|
||||
{
|
||||
.config = &g_usart2config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_usart2port =
|
||||
|
@ -425,6 +429,7 @@ static struct efm32_config_s g_uart0config =
|
|||
static struct efm32_usart_s g_uart0priv =
|
||||
{
|
||||
.config = &g_uart0config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_uart0port =
|
||||
|
@ -447,7 +452,7 @@ static struct uart_dev_s g_uart0port =
|
|||
/* This describes the state of the EFM32 UART1 port. */
|
||||
|
||||
#ifdef CONFIG_EFM32_UART1
|
||||
static struct efm32_usart_s g_uart1config =
|
||||
static struct efm32_config_s g_uart1config =
|
||||
{
|
||||
.uartbase = EFM32_UART1_BASE,
|
||||
.baud = CONFIG_UART1_BAUD,
|
||||
|
@ -461,6 +466,7 @@ static struct efm32_usart_s g_uart1config =
|
|||
static struct efm32_usart_s g_uart1priv =
|
||||
{
|
||||
.config = &g_uart1config,
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
static struct uart_dev_s g_uart1port =
|
||||
|
@ -516,6 +522,13 @@ static inline void efm32_setuartint(struct efm32_usart_s *priv)
|
|||
* Name: efm32_restoreuartint
|
||||
****************************************************************************/
|
||||
|
||||
static void efm32_restoreuartint_nolock(struct efm32_usart_s *priv,
|
||||
uint32_t ien)
|
||||
{
|
||||
priv->ien = ien;
|
||||
efm32_setuartint(priv);
|
||||
}
|
||||
|
||||
static void efm32_restoreuartint(struct efm32_usart_s *priv, uint32_t ien)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -524,10 +537,9 @@ static void efm32_restoreuartint(struct efm32_usart_s *priv, uint32_t ien)
|
|||
* ien
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
priv->ien = ien;
|
||||
efm32_setuartint(priv);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
efm32_restoreuartint_nolock(priv, len);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -539,14 +551,14 @@ static void efm32_disableuartint(struct efm32_usart_s *priv, uint32_t *ien)
|
|||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (ien)
|
||||
{
|
||||
*ien = priv->ien;
|
||||
}
|
||||
|
||||
efm32_restoreuartint(priv, 0);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
efm32_restoreuartint_nolock(priv, 0);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -966,7 +978,7 @@ static void efm32_rxint(struct uart_dev_s *dev, bool enable)
|
|||
struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (enable)
|
||||
{
|
||||
/* Receive an interrupt when their is anything in the Rx data register
|
||||
|
@ -984,7 +996,7 @@ static void efm32_rxint(struct uart_dev_s *dev, bool enable)
|
|||
efm32_setuartint(priv);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1032,7 +1044,7 @@ static void efm32_txint(struct uart_dev_s *dev, bool enable)
|
|||
struct efm32_usart_s *priv = (struct efm32_usart_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (enable)
|
||||
{
|
||||
/* Enable the TX interrupt */
|
||||
|
@ -1056,7 +1068,7 @@ static void efm32_txint(struct uart_dev_s *dev, bool enable)
|
|||
efm32_setuartint(priv);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -131,6 +131,7 @@ struct up_dev_s
|
|||
uint8_t stop_2bits; /* True: Configure with 2 stop bits instead of 1 */
|
||||
uint32_t tx_gpio; /* USART TX GPIO pin configuration */
|
||||
uint32_t rx_gpio; /* USART RX GPIO pin configuration */
|
||||
spinlock_t lock; /* Spinlock */
|
||||
|
||||
# ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
uint32_t rts_gpio; /* UART RTS GPIO pin configuration */
|
||||
|
@ -437,6 +438,7 @@ static struct up_dev_s g_usart0priv =
|
|||
|
||||
.tx_gpio = GPIO_USART0_TX,
|
||||
.rx_gpio = GPIO_USART0_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART0_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_USART0_RTS,
|
||||
|
@ -509,6 +511,7 @@ static struct up_dev_s g_usart1priv =
|
|||
|
||||
.tx_gpio = GPIO_USART1_TX,
|
||||
.rx_gpio = GPIO_USART1_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_USART1_RTS,
|
||||
|
@ -581,6 +584,7 @@ static struct up_dev_s g_usart2priv =
|
|||
|
||||
.tx_gpio = GPIO_USART2_TX,
|
||||
.rx_gpio = GPIO_USART2_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_USART2_RTS,
|
||||
|
@ -653,6 +657,7 @@ static struct up_dev_s g_usart5priv =
|
|||
|
||||
.tx_gpio = GPIO_USART5_TX,
|
||||
.rx_gpio = GPIO_USART5_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART5_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_USART5_RTS,
|
||||
|
@ -725,6 +730,7 @@ static struct up_dev_s g_uart3priv =
|
|||
|
||||
.tx_gpio = GPIO_UART3_TX,
|
||||
.rx_gpio = GPIO_UART3_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART3_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_UART3_RTS,
|
||||
|
@ -797,6 +803,7 @@ static struct up_dev_s g_uart4priv =
|
|||
|
||||
.tx_gpio = GPIO_UART4_TX,
|
||||
.rx_gpio = GPIO_UART4_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART4_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_UART4_RTS,
|
||||
|
@ -869,6 +876,7 @@ static struct up_dev_s g_uart6priv =
|
|||
|
||||
.tx_gpio = GPIO_UART6_TX,
|
||||
.rx_gpio = GPIO_UART6_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART6_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_UART6_RTS,
|
||||
|
@ -941,6 +949,7 @@ static struct up_dev_s g_uart7priv =
|
|||
|
||||
.tx_gpio = GPIO_UART7_TX,
|
||||
.rx_gpio = GPIO_UART7_RX,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART7_IFLOWCONTROL)
|
||||
.iflow = true,
|
||||
.rts_gpio = GPIO_UART7_RTS,
|
||||
|
@ -1127,7 +1136,7 @@ static void up_disableusartint(struct up_dev_s *priv, uint32_t *ie)
|
|||
irqstate_t flags;
|
||||
uint32_t ctl_ie;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
if (ie)
|
||||
{
|
||||
|
@ -1161,7 +1170,7 @@ static void up_disableusartint(struct up_dev_s *priv, uint32_t *ie)
|
|||
ctl_ie = (USART_CFG_CTL_MASK << USART_CFG_SHIFT);
|
||||
up_setusartint(priv, ctl_ie);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1172,11 +1181,11 @@ static void up_restoreusartint(struct up_dev_s *priv, uint32_t ie)
|
|||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
up_setusartint(priv, ie);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -145,6 +145,7 @@ struct imx9_edma_s
|
|||
/* This array describes each DMA channel */
|
||||
|
||||
struct imx9_dmach_s dmach[IMX9_EDMA_NCHANNELS];
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -159,6 +160,7 @@ static struct imx9_edma_s g_edma =
|
|||
#if CONFIG_IMX9_EDMA_NTCD > 0
|
||||
.dsem = SEM_INITIALIZER(CONFIG_IMX9_EDMA_NTCD),
|
||||
#endif
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
#if CONFIG_IMX9_EDMA_NTCD > 0
|
||||
|
@ -198,15 +200,15 @@ static struct imx9_edmatcd_s *imx9_tcd_alloc(void)
|
|||
* waiting.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
nxsem_wait_uninterruptible(&g_edma.dsem);
|
||||
|
||||
/* Now there should be a TCD in the free list reserved just for us */
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
tcd = (struct imx9_edmatcd_s *)sq_remfirst(&g_tcd_free);
|
||||
DEBUGASSERT(tcd != NULL);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return tcd;
|
||||
}
|
||||
#endif
|
||||
|
@ -220,6 +222,17 @@ static struct imx9_edmatcd_s *imx9_tcd_alloc(void)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_IMX9_EDMA_NTCD > 0
|
||||
static void imx9_tcd_free_nolock(struct imx9_edmatcd_s *tcd)
|
||||
{
|
||||
/* Add the the TCD to the end of the free list and post the 'dsem',
|
||||
* possibly waking up another thread that might be waiting for
|
||||
* a TCD.
|
||||
*/
|
||||
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
}
|
||||
|
||||
static void imx9_tcd_free(struct imx9_edmatcd_s *tcd)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -229,10 +242,11 @@ static void imx9_tcd_free(struct imx9_edmatcd_s *tcd)
|
|||
* a TCD.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
imx9_tcd_free_nolock(tcd);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -458,6 +472,11 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result)
|
|||
edma_callback_t callback;
|
||||
void *arg;
|
||||
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
|
||||
/* Disable channel IRQ requests */
|
||||
|
||||
putreg32(EDMA_CH_INT, base + IMX9_EDMA_CH_INT_OFFSET);
|
||||
|
@ -487,7 +506,7 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result)
|
|||
next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
|
||||
NULL : (struct imx9_edmatcd_s *)((uintptr_t)tcd->dlastsga);
|
||||
|
||||
imx9_tcd_free(tcd);
|
||||
imx9_tcd_free_nolock(tcd);
|
||||
}
|
||||
|
||||
dmach->head = NULL;
|
||||
|
@ -507,6 +526,9 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result)
|
|||
{
|
||||
callback((DMACH_HANDLE)dmach, arg, true, result);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1344,7 +1366,7 @@ int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
|
||||
/* Save the callback info. This will be invoked when the DMA completes */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
dmach->callback = callback;
|
||||
dmach->arg = arg;
|
||||
|
||||
|
@ -1363,7 +1385,7 @@ int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
putreg32(regval, base + IMX9_EDMA_CH_CSR_OFFSET);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1386,14 +1408,11 @@ int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
void imx9_dmach_stop(DMACH_HANDLE handle)
|
||||
{
|
||||
struct imx9_dmach_s *dmach = (struct imx9_dmach_s *)handle;
|
||||
irqstate_t flags;
|
||||
|
||||
dmainfo("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
imx9_dmaterminate(dmach, -EINTR);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1508,7 +1527,7 @@ void imx9_dmasample(DMACH_HANDLE handle, struct imx9_dmaregs_s *regs)
|
|||
|
||||
/* eDMA Global Registers */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
|
||||
/* REVISIT: eDMA4 does not show INT_HIGH / HRS_HIGH values correctly */
|
||||
|
||||
|
@ -1542,7 +1561,7 @@ void imx9_dmasample(DMACH_HANDLE handle, struct imx9_dmaregs_s *regs)
|
|||
regs->dmamux = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ static struct imxrt_edma_s g_edma =
|
|||
#if CONFIG_IMXRT_EDMA_NTCD > 0
|
||||
.dsem = SEM_INITIALIZER(CONFIG_IMXRT_EDMA_NTCD),
|
||||
#endif
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
#if CONFIG_IMXRT_EDMA_NTCD > 0
|
||||
|
@ -197,15 +198,15 @@ static struct imxrt_edmatcd_s *imxrt_tcd_alloc(void)
|
|||
* waiting.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
nxsem_wait_uninterruptible(&g_edma.dsem);
|
||||
|
||||
/* Now there should be a TCD in the free list reserved just for us */
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
tcd = (struct imxrt_edmatcd_s *)sq_remfirst(&g_tcd_free);
|
||||
DEBUGASSERT(tcd != NULL);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return tcd;
|
||||
}
|
||||
#endif
|
||||
|
@ -219,6 +220,17 @@ static struct imxrt_edmatcd_s *imxrt_tcd_alloc(void)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_IMXRT_EDMA_NTCD > 0
|
||||
static void imxrt_tcd_free_nolock(struct imxrt_edmatcd_s *tcd)
|
||||
{
|
||||
/* Add the the TCD to the end of the free list and post the 'dsem',
|
||||
* possibly waking up another thread that might be waiting for
|
||||
* a TCD.
|
||||
*/
|
||||
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
}
|
||||
|
||||
static void imxrt_tcd_free(struct imxrt_edmatcd_s *tcd)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -228,10 +240,9 @@ static void imxrt_tcd_free(struct imxrt_edmatcd_s *tcd)
|
|||
* a TCD.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
imxrt_tcd_free_nolock(tcd);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -436,8 +447,11 @@ static void imxrt_dmaterminate(struct imxrt_dmach_s *dmach, int result)
|
|||
uint8_t regval8;
|
||||
uint8_t chan;
|
||||
edma_callback_t callback;
|
||||
irqstate_t flags;
|
||||
void *arg;
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
|
||||
/* Disable channel ERROR interrupts */
|
||||
|
||||
chan = dmach->chan;
|
||||
|
@ -469,7 +483,7 @@ static void imxrt_dmaterminate(struct imxrt_dmach_s *dmach, int result)
|
|||
next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
|
||||
NULL : (struct imxrt_edmatcd_s *)tcd->dlastsga;
|
||||
|
||||
imxrt_tcd_free(tcd);
|
||||
imxrt_tcd_free_nolock(tcd);
|
||||
}
|
||||
|
||||
dmach->head = NULL;
|
||||
|
@ -489,6 +503,8 @@ static void imxrt_dmaterminate(struct imxrt_dmach_s *dmach, int result)
|
|||
{
|
||||
callback((DMACH_HANDLE)dmach, arg, true, result);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1143,7 +1159,7 @@ int imxrt_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
|
||||
/* Save the callback info. This will be invoked when the DMA completes */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
dmach->callback = callback;
|
||||
dmach->arg = arg;
|
||||
|
||||
|
@ -1168,7 +1184,7 @@ int imxrt_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
putreg8(regval8, IMXRT_EDMA_SERQ);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1196,9 +1212,7 @@ void imxrt_dmach_stop(DMACH_HANDLE handle)
|
|||
dmainfo("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
imxrt_dmaterminate(dmach, -EINTR);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1313,7 +1327,7 @@ void imxrt_dmasample(DMACH_HANDLE handle, struct imxrt_dmaregs_s *regs)
|
|||
|
||||
/* eDMA Global Registers */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
|
||||
regs->cr = getreg32(IMXRT_EDMA_CR); /* Control */
|
||||
regs->es = getreg32(IMXRT_EDMA_ES); /* Error Status */
|
||||
|
@ -1348,7 +1362,7 @@ void imxrt_dmasample(DMACH_HANDLE handle, struct imxrt_dmaregs_s *regs)
|
|||
regaddr = IMXRT_DMAMUX_CHCFG(chan);
|
||||
regs->dmamux = getreg32(regaddr); /* Channel configuration */
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
/* Callback to use when the alarm expires */
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
static spinlock_t g_imxrt_hprtc_lock = SP_UNLOCKED;
|
||||
static hprtc_alarm_callback_t g_hprtc_alarmcb;
|
||||
#endif
|
||||
|
||||
|
@ -526,7 +527,7 @@ int imxrt_hprtc_setalarm(struct timespec *ts, hprtc_alarm_callback_t cb)
|
|||
* interrupted or preempted.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_imxrt_hprtc_lock);
|
||||
|
||||
now = imxrt_hprtc_time();
|
||||
|
||||
|
@ -539,7 +540,7 @@ int imxrt_hprtc_setalarm(struct timespec *ts, hprtc_alarm_callback_t cb)
|
|||
if ((uint32_t)ts->tv_sec <= now)
|
||||
{
|
||||
rtcwarn("WARNING: time is in the past\n");
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_imxrt_hprtc_lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -569,7 +570,7 @@ int imxrt_hprtc_setalarm(struct timespec *ts, hprtc_alarm_callback_t cb)
|
|||
/* Unconditionally enable the RTC alarm interrupt */
|
||||
|
||||
imxrt_hprtc_alarmenable();
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_imxrt_hprtc_lock, flags);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -273,6 +273,7 @@ struct kinetis_dev_s
|
|||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||
uint8_t bits; /* Number of bits (8 or 9) */
|
||||
uint8_t stop2; /* Use 2 stop bits */
|
||||
spinlock_t lock; /* Spinlock */
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
bool iflow; /* input flow control (RTS) enabled */
|
||||
#endif
|
||||
|
@ -428,6 +429,7 @@ static struct kinetis_dev_s g_lpuart0priv =
|
|||
.parity = CONFIG_LPUART0_PARITY,
|
||||
.bits = CONFIG_LPUART0_BITS,
|
||||
.stop2 = CONFIG_LPUART0_2STOP,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART0_OFLOWCONTROL)
|
||||
.oflow = true,
|
||||
.cts_gpio = PIN_LPUART0_CTS,
|
||||
|
@ -475,6 +477,7 @@ static struct kinetis_dev_s g_lpuart1priv =
|
|||
.parity = CONFIG_LPUART1_PARITY,
|
||||
.bits = CONFIG_LPUART1_BITS,
|
||||
.stop2 = CONFIG_LPUART1_2STOP,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL)
|
||||
.oflow = true,
|
||||
.cts_gpio = PIN_LPUART1_CTS,
|
||||
|
@ -522,6 +525,7 @@ static struct kinetis_dev_s g_lpuart2priv =
|
|||
.parity = CONFIG_LPUART2_PARITY,
|
||||
.bits = CONFIG_LPUART2_BITS,
|
||||
.stop2 = CONFIG_LPUART2_2STOP,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART2_OFLOWCONTROL)
|
||||
.oflow = true,
|
||||
.cts_gpio = PIN_LPUART2_CTS,
|
||||
|
@ -569,6 +573,7 @@ static struct kinetis_dev_s g_lpuart3priv =
|
|||
.parity = CONFIG_LPUART3_PARITY,
|
||||
.bits = CONFIG_LPUART3_BITS,
|
||||
.stop2 = CONFIG_LPUART3_2STOP,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART3_OFLOWCONTROL)
|
||||
.oflow = true,
|
||||
.cts_gpio = PIN_LPUART3_CTS,
|
||||
|
@ -616,6 +621,7 @@ static struct kinetis_dev_s g_lpuart4priv =
|
|||
.parity = CONFIG_LPUART4_PARITY,
|
||||
.bits = CONFIG_LPUART4_BITS,
|
||||
.stop2 = CONFIG_LPUART4_2STOP,
|
||||
.lock = SP_UNLOCKED,
|
||||
#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART4_OFLOWCONTROL)
|
||||
.oflow = true,
|
||||
.cts_gpio = PIN_LPUART4_CTS,
|
||||
|
@ -700,6 +706,17 @@ static void kinetis_setuartint(struct kinetis_dev_s *priv)
|
|||
* Name: kinetis_restoreuartint
|
||||
****************************************************************************/
|
||||
|
||||
static void kinetis_restoreuartint_nolock(struct kinetis_dev_s *priv,
|
||||
uint32_t ie)
|
||||
{
|
||||
/* Re-enable/re-disable interrupts corresponding to the state of bits in
|
||||
* ie
|
||||
*/
|
||||
|
||||
priv->ie = ie & LPUART_CTRL_ALL_INTS;
|
||||
kinetis_setuartint(priv);
|
||||
}
|
||||
|
||||
static void kinetis_restoreuartint(struct kinetis_dev_s *priv, uint32_t ie)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -708,10 +725,9 @@ static void kinetis_restoreuartint(struct kinetis_dev_s *priv, uint32_t ie)
|
|||
* ie
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
priv->ie = ie & LPUART_CTRL_ALL_INTS;
|
||||
kinetis_setuartint(priv);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
kinetis_restoreuartint_nolock(priv, ie);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -723,14 +739,14 @@ static void kinetis_disableuartint(struct kinetis_dev_s *priv, uint32_t *ie)
|
|||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
if (ie)
|
||||
{
|
||||
*ie = priv->ie;
|
||||
}
|
||||
|
||||
kinetis_restoreuartint(priv, 0);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
kinetis_restoreuartint_nolock(priv, 0);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_gpio_lock = SP_UNLOCKED;
|
||||
|
||||
#ifdef CONFIG_IOEX
|
||||
static struct ioex_dev_s *g_ioex_dev;
|
||||
#endif
|
||||
|
@ -229,12 +231,12 @@ int lc823450_gpio_mux(uint16_t gpiocfg)
|
|||
|
||||
if (port <= (GPIO_PORT5 >> GPIO_PORT_SHIFT))
|
||||
{
|
||||
irqstate_t flags = spin_lock_irqsave(NULL);
|
||||
irqstate_t flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
val = getreg32(PMDCNT0 + (port * 4));
|
||||
val &= ~(3 << (2 * pin));
|
||||
val |= (mux << (2 *pin));
|
||||
putreg32(val, PMDCNT0 + (port * 4));
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -277,7 +279,7 @@ int lc823450_gpio_config(uint16_t gpiocfg)
|
|||
|
||||
/* Handle the GPIO configuration by the basic mode of the pin */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
|
||||
/* pull up/down specified */
|
||||
|
||||
|
@ -302,7 +304,7 @@ int lc823450_gpio_config(uint16_t gpiocfg)
|
|||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
}
|
||||
#ifdef CONFIG_IOEX
|
||||
else if (port <= (GPIO_PORTEX >> GPIO_PORT_SHIFT))
|
||||
|
@ -390,7 +392,7 @@ void lc823450_gpio_write(uint16_t gpiocfg, bool value)
|
|||
|
||||
regaddr = lc823450_get_gpio_data(port);
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
|
||||
/* Write the value (0 or 1). To the data register */
|
||||
|
||||
|
@ -407,7 +409,7 @@ void lc823450_gpio_write(uint16_t gpiocfg, bool value)
|
|||
|
||||
putreg32(regval, regaddr);
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
}
|
||||
#ifdef CONFIG_IOEX
|
||||
else if (port <= (GPIO_PORTEX >> GPIO_PORT_SHIFT))
|
||||
|
|
|
@ -142,6 +142,7 @@ struct s32k1xx_edma_s
|
|||
/* This array describes each DMA channel */
|
||||
|
||||
struct s32k1xx_dmach_s dmach[S32K1XX_EDMA_NCHANNELS];
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -156,6 +157,7 @@ static struct s32k1xx_edma_s g_edma =
|
|||
#if CONFIG_S32K1XX_EDMA_NTCD > 0
|
||||
.dsem = SEM_INITIALIZER(CONFIG_S32K1XX_EDMA_NTCD),
|
||||
#endif
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
#if CONFIG_S32K1XX_EDMA_NTCD > 0
|
||||
|
@ -195,15 +197,15 @@ static struct s32k1xx_edmatcd_s *s32k1xx_tcd_alloc(void)
|
|||
* waiting.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
nxsem_wait_uninterruptible(&g_edma.dsem);
|
||||
|
||||
/* Now there should be a TCD in the free list reserved just for us */
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
tcd = (struct s32k1xx_edmatcd_s *)sq_remfirst(&g_tcd_free);
|
||||
DEBUGASSERT(tcd != NULL);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return tcd;
|
||||
}
|
||||
#endif
|
||||
|
@ -217,6 +219,17 @@ static struct s32k1xx_edmatcd_s *s32k1xx_tcd_alloc(void)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_S32K1XX_EDMA_NTCD > 0
|
||||
static void s32k1xx_tcd_free_nolock(struct s32k1xx_edmatcd_s *tcd)
|
||||
{
|
||||
/* Add the the TCD to the end of the free list and post the 'dsem',
|
||||
* possibly waking up another thread that might be waiting for
|
||||
* a TCD.
|
||||
*/
|
||||
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
}
|
||||
|
||||
static void s32k1xx_tcd_free(struct s32k1xx_edmatcd_s *tcd)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -226,10 +239,9 @@ static void s32k1xx_tcd_free(struct s32k1xx_edmatcd_s *tcd)
|
|||
* a TCD.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
s32k1xx_tcd_free_nolock(tcd);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -432,9 +444,13 @@ static void s32k1xx_dmaterminate(struct s32k1xx_dmach_s *dmach, int result)
|
|||
struct s32k1xx_edmatcd_s *next;
|
||||
#endif
|
||||
uintptr_t regaddr;
|
||||
irqstate_t flags;
|
||||
uint8_t regval8;
|
||||
uint8_t chan;
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
|
||||
/* Disable channel ERROR interrupts */
|
||||
|
||||
chan = dmach->chan;
|
||||
|
@ -465,7 +481,7 @@ static void s32k1xx_dmaterminate(struct s32k1xx_dmach_s *dmach, int result)
|
|||
|
||||
next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
|
||||
NULL : (struct s32k1xx_edmatcd_s *)tcd->dlastsga;
|
||||
s32k1xx_tcd_free(tcd);
|
||||
s32k1xx_tcd_free_nolock(tcd);
|
||||
}
|
||||
|
||||
dmach->head = NULL;
|
||||
|
@ -482,6 +498,8 @@ static void s32k1xx_dmaterminate(struct s32k1xx_dmach_s *dmach, int result)
|
|||
dmach->callback = NULL;
|
||||
dmach->arg = NULL;
|
||||
dmach->state = S32K1XX_DMA_IDLE;
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1098,7 +1116,7 @@ int s32k1xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
|
||||
/* Save the callback info. This will be invoked when the DMA completes */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
dmach->callback = callback;
|
||||
dmach->arg = arg;
|
||||
|
||||
|
@ -1123,7 +1141,7 @@ int s32k1xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
putreg8(regval8, S32K1XX_EDMA_SERQ);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1151,9 +1169,9 @@ void s32k1xx_dmach_stop(DMACH_HANDLE handle)
|
|||
dmainfo("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
s32k1xx_dmaterminate(dmach, -EINTR);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1251,7 +1269,7 @@ void s32k1xx_dmasample(DMACH_HANDLE handle, struct s32k1xx_dmaregs_s *regs)
|
|||
|
||||
/* eDMA Global Registers */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
|
||||
regs->cr = getreg32(S32K1XX_EDMA_CR); /* Control */
|
||||
regs->es = getreg32(S32K1XX_EDMA_ES); /* Error Status */
|
||||
|
@ -1286,7 +1304,7 @@ void s32k1xx_dmasample(DMACH_HANDLE handle, struct s32k1xx_dmaregs_s *regs)
|
|||
regaddr = S32K1XX_DMAMUX_CHCFG(chan);
|
||||
regs->dmamux = getreg32(regaddr); /* Channel configuration */
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ static struct s32k3xx_edma_s g_edma =
|
|||
#if CONFIG_S32K3XX_EDMA_NTCD > 0
|
||||
.dsem = SEM_INITIALIZER(CONFIG_S32K3XX_EDMA_NTCD),
|
||||
#endif
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
#if CONFIG_S32K3XX_EDMA_NTCD > 0
|
||||
|
@ -450,15 +451,15 @@ static struct s32k3xx_edmatcd_s *s32k3xx_tcd_alloc(void)
|
|||
* waiting.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
nxsem_wait_uninterruptible(&g_edma.dsem);
|
||||
|
||||
/* Now there should be a TCD in the free list reserved just for us */
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
tcd = (struct s32k3xx_edmatcd_s *)sq_remfirst(&g_tcd_free);
|
||||
DEBUGASSERT(tcd != NULL);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return tcd;
|
||||
}
|
||||
#endif
|
||||
|
@ -472,6 +473,17 @@ static struct s32k3xx_edmatcd_s *s32k3xx_tcd_alloc(void)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_S32K3XX_EDMA_NTCD > 0
|
||||
static void s32k3xx_tcd_free_nolock(struct s32k3xx_edmatcd_s *tcd)
|
||||
{
|
||||
/* Add the the TCD to the end of the free list and post the 'dsem',
|
||||
* possibly waking up another thread that might be waiting for
|
||||
* a TCD.
|
||||
*/
|
||||
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
}
|
||||
|
||||
static void s32k3xx_tcd_free(struct s32k3xx_edmatcd_s *tcd)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -481,10 +493,11 @@ static void s32k3xx_tcd_free(struct s32k3xx_edmatcd_s *tcd)
|
|||
* a TCD.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
s32k3xx_tcd_free_nolock(tcd);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -709,8 +722,12 @@ static void s32k3xx_dmaterminate(struct s32k3xx_dmach_s *dmach, int result)
|
|||
#endif
|
||||
uint8_t chan;
|
||||
edma_callback_t callback;
|
||||
irqstate_t flags;
|
||||
void *arg;
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
|
||||
chan = dmach->chan;
|
||||
|
||||
/* Disable channel IRQ requests */
|
||||
|
@ -742,7 +759,7 @@ static void s32k3xx_dmaterminate(struct s32k3xx_dmach_s *dmach, int result)
|
|||
next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
|
||||
NULL : (struct s32k3xx_edmatcd_s *)tcd->dlastsga;
|
||||
|
||||
s32k3xx_tcd_free(tcd);
|
||||
s32k3xx_tcd_free_nolock(tcd);
|
||||
}
|
||||
|
||||
dmach->head = NULL;
|
||||
|
@ -762,6 +779,9 @@ static void s32k3xx_dmaterminate(struct s32k3xx_dmach_s *dmach, int result)
|
|||
{
|
||||
callback((DMACH_HANDLE)dmach, arg, true, result);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1377,7 +1397,7 @@ int s32k3xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
|
||||
/* Save the callback info. This will be invoked when the DMA completes */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
dmach->callback = callback;
|
||||
dmach->arg = arg;
|
||||
|
||||
|
@ -1397,7 +1417,7 @@ int s32k3xx_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
putreg32(regval, S32K3XX_EDMA_TCD[chan] + S32K3XX_EDMA_CH_CSR_OFFSET);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1425,9 +1445,9 @@ void s32k3xx_dmach_stop(DMACH_HANDLE handle)
|
|||
dmainfo("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
s32k3xx_dmaterminate(dmach, -EINTR);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1544,7 +1564,7 @@ void s32k3xx_dmasample(DMACH_HANDLE handle, struct s32k3xx_dmaregs_s *regs)
|
|||
|
||||
/* eDMA Global Registers */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
|
||||
regs->cr = getreg32(S32K3XX_EDMA_CSR); /* Control */
|
||||
regs->es = getreg32(S32K3XX_EDMA_ES); /* Error Status */
|
||||
|
@ -1576,7 +1596,7 @@ void s32k3xx_dmasample(DMACH_HANDLE handle, struct s32k3xx_dmaregs_s *regs)
|
|||
regs->dmamux = getreg32(S32K3XX_DMAMUX1_CHCFG(chan - 16)); /* Channel configuration */
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ struct imx9_edma_s
|
|||
/* This array describes each DMA channel */
|
||||
|
||||
struct imx9_dmach_s dmach[IMX9_EDMA_NCHANNELS];
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -155,6 +156,7 @@ static struct imx9_edma_s g_edma =
|
|||
#if CONFIG_IMX9_EDMA_NTCD > 0
|
||||
.dsem = SEM_INITIALIZER(CONFIG_IMX9_EDMA_NTCD),
|
||||
#endif
|
||||
.lock = SP_UNLOCKED
|
||||
};
|
||||
|
||||
#if CONFIG_IMX9_EDMA_NTCD > 0
|
||||
|
@ -194,15 +196,15 @@ static struct imx9_edmatcd_s *imx9_tcd_alloc(void)
|
|||
* waiting.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
nxsem_wait_uninterruptible(&g_edma.dsem);
|
||||
|
||||
/* Now there should be a TCD in the free list reserved just for us */
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
tcd = (struct imx9_edmatcd_s *)sq_remfirst(&g_tcd_free);
|
||||
DEBUGASSERT(tcd != NULL);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_lock_irqsave(&g_edma.lock, flags);
|
||||
return tcd;
|
||||
}
|
||||
#endif
|
||||
|
@ -216,6 +218,17 @@ static struct imx9_edmatcd_s *imx9_tcd_alloc(void)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_IMX9_EDMA_NTCD > 0
|
||||
static void imx9_tcd_free_nolock(struct imx9_edmatcd_s *tcd)
|
||||
{
|
||||
/* Add the the TCD to the end of the free list and post the 'dsem',
|
||||
* possibly waking up another thread that might be waiting for
|
||||
* a TCD.
|
||||
*/
|
||||
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
}
|
||||
|
||||
static void imx9_tcd_free(struct imx9_edmatcd_s *tcd)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
@ -225,10 +238,11 @@ static void imx9_tcd_free(struct imx9_edmatcd_s *tcd)
|
|||
* a TCD.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
sq_addlast((sq_entry_t *)tcd, &g_tcd_free);
|
||||
nxsem_post(&g_edma.dsem);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
imx9_tcd_free_nolock(tcd);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -438,6 +452,11 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result)
|
|||
edma_callback_t callback;
|
||||
void *arg;
|
||||
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
sched_lock();
|
||||
|
||||
/* Disable channel IRQ requests */
|
||||
|
||||
putreg32(EDMA_CH_INT, base + IMX9_EDMA_CH_INT_OFFSET);
|
||||
|
@ -467,7 +486,7 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result)
|
|||
next = dmach->flags & EDMA_CONFIG_LOOPDEST ?
|
||||
NULL : (struct imx9_edmatcd_s *)((uintptr_t)tcd->dlastsga);
|
||||
|
||||
imx9_tcd_free(tcd);
|
||||
imx9_tcd_free_nolock(tcd);
|
||||
}
|
||||
|
||||
dmach->head = NULL;
|
||||
|
@ -487,6 +506,9 @@ static void imx9_dmaterminate(struct imx9_dmach_s *dmach, int result)
|
|||
{
|
||||
callback((DMACH_HANDLE)dmach, arg, true, result);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1252,7 +1274,7 @@ int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
|
||||
/* Save the callback info. This will be invoked when the DMA completes */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
dmach->callback = callback;
|
||||
dmach->arg = arg;
|
||||
|
||||
|
@ -1271,7 +1293,7 @@ int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
putreg32(regval, base + IMX9_EDMA_CH_CSR_OFFSET);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -1294,14 +1316,11 @@ int imx9_dmach_start(DMACH_HANDLE handle, edma_callback_t callback,
|
|||
void imx9_dmach_stop(DMACH_HANDLE handle)
|
||||
{
|
||||
struct imx9_dmach_s *dmach = (struct imx9_dmach_s *)handle;
|
||||
irqstate_t flags;
|
||||
|
||||
dmainfo("dmach: %p\n", dmach);
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
imx9_dmaterminate(dmach, -EINTR);
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1416,7 +1435,7 @@ void imx9_dmasample(DMACH_HANDLE handle, struct imx9_dmaregs_s *regs)
|
|||
|
||||
/* eDMA Global Registers */
|
||||
|
||||
flags = spin_lock_irqsave(NULL);
|
||||
flags = spin_lock_irqsave(&g_edma.lock);
|
||||
|
||||
/* REVISIT: eDMA4 does not show INT_HIGH / HRS_HIGH values correctly */
|
||||
|
||||
|
@ -1450,7 +1469,7 @@ void imx9_dmasample(DMACH_HANDLE handle, struct imx9_dmaregs_s *regs)
|
|||
regs->dmamux = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(NULL, flags);
|
||||
spin_unlock_irqrestore(&g_edma.lock, flags);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_DMA */
|
||||
|
||||
|
|
Loading…
Reference in a new issue