SAMA5 Serial: Reading IMR and disabling interrupt must be atomic
This commit is contained in:
parent
35312b31f9
commit
a93913c0f4
@ -650,7 +650,7 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t valu
|
|||||||
|
|
||||||
static inline void up_restoreusartint(struct up_dev_s *priv, uint32_t imr)
|
static inline void up_restoreusartint(struct up_dev_s *priv, uint32_t imr)
|
||||||
{
|
{
|
||||||
/* Restore the previous interrupt state */
|
/* Restore the previous interrupt state (assuming all interrupts disabled) */
|
||||||
|
|
||||||
up_serialout(priv, SAM_UART_IER_OFFSET, imr);
|
up_serialout(priv, SAM_UART_IER_OFFSET, imr);
|
||||||
}
|
}
|
||||||
|
@ -727,11 +727,22 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t valu
|
|||||||
putreg32(value, priv->usartbase + offset);
|
putreg32(value, priv->usartbase + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_restoreusartint
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void up_restoreusartint(struct up_dev_s *priv, uint32_t imr)
|
||||||
|
{
|
||||||
|
/* Restore the previous interrupt state (assuming all interrupts disabled) */
|
||||||
|
|
||||||
|
up_serialout(priv, SAM_UART_IER_OFFSET, imr);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_disableallints
|
* Name: up_disableallints
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void up_disableallints(struct up_dev_s *priv)
|
static void up_disableallints(struct up_dev_s *priv, uint32_t *imr)
|
||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
@ -739,6 +750,13 @@ static void up_disableallints(struct up_dev_s *priv)
|
|||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
|
|
||||||
|
/* Return the current interrupt state */
|
||||||
|
|
||||||
|
if (imr)
|
||||||
|
{
|
||||||
|
*imr = up_serialin(priv, SAM_UART_IMR_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable all interrupts */
|
/* Disable all interrupts */
|
||||||
|
|
||||||
up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_ALLINTS);
|
up_serialout(priv, SAM_UART_IDR_OFFSET, UART_INT_ALLINTS);
|
||||||
@ -887,7 +905,7 @@ static void up_shutdown(struct uart_dev_s *dev)
|
|||||||
|
|
||||||
/* Disable all interrupts */
|
/* Disable all interrupts */
|
||||||
|
|
||||||
up_disableallints(priv);
|
up_disableallints(priv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1243,13 +1261,12 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
* implement TCSADRAIN / TCSAFLUSH
|
* implement TCSADRAIN / TCSAFLUSH
|
||||||
*/
|
*/
|
||||||
|
|
||||||
imr = up_serialin(priv, SAM_UART_IMR_OFFSET);
|
up_disableallints(priv, &imr);
|
||||||
up_disableallints(priv);
|
|
||||||
ret = up_setup(dev);
|
ret = up_setup(dev);
|
||||||
|
|
||||||
/* Restore the interrupt state */
|
/* Restore the interrupt state */
|
||||||
|
|
||||||
up_serialout(priv, SAM_UART_IER_OFFSET, imr);
|
up_restoreusartint(priv, imr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1437,25 +1454,25 @@ void sam_earlyserialinit(void)
|
|||||||
/* Disable all USARTS */
|
/* Disable all USARTS */
|
||||||
|
|
||||||
#ifdef TTYS0_DEV
|
#ifdef TTYS0_DEV
|
||||||
up_disableallints(TTYS0_DEV.priv);
|
up_disableallints(TTYS0_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS1_DEV
|
#ifdef TTYS1_DEV
|
||||||
up_disableallints(TTYS1_DEV.priv);
|
up_disableallints(TTYS1_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS2_DEV
|
#ifdef TTYS2_DEV
|
||||||
up_disableallints(TTYS2_DEV.priv);
|
up_disableallints(TTYS2_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS3_DEV
|
#ifdef TTYS3_DEV
|
||||||
up_disableallints(TTYS3_DEV.priv);
|
up_disableallints(TTYS3_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS4_DEV
|
#ifdef TTYS4_DEV
|
||||||
up_disableallints(TTYS4_DEV.priv);
|
up_disableallints(TTYS4_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS5_DEV
|
#ifdef TTYS5_DEV
|
||||||
up_disableallints(TTYS5_DEV.priv);
|
up_disableallints(TTYS5_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef TTYS6_DEV
|
#ifdef TTYS6_DEV
|
||||||
up_disableallints(TTYS6_DEV.priv);
|
up_disableallints(TTYS6_DEV.priv, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration whichever one is the console */
|
/* Configuration whichever one is the console */
|
||||||
|
@ -710,7 +710,7 @@ static inline void sam_serialout(struct sam_dev_s *priv, int offset, uint32_t va
|
|||||||
|
|
||||||
static inline void sam_restoreusartint(struct sam_dev_s *priv, uint32_t imr)
|
static inline void sam_restoreusartint(struct sam_dev_s *priv, uint32_t imr)
|
||||||
{
|
{
|
||||||
/* Restore the previous interrupt state */
|
/* Restore the previous interrupt state (assuming all interrupts disabled) */
|
||||||
|
|
||||||
sam_serialout(priv, SAM_UART_IER_OFFSET, imr);
|
sam_serialout(priv, SAM_UART_IER_OFFSET, imr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user