Check the return of nxsem_wait_unterruptible()

This commit is for all tc drivers under arch/.
This commit is contained in:
Ouss4 2020-04-05 00:16:39 +01:00 committed by patacongo
parent dc96287d27
commit 8f85a57941
3 changed files with 146 additions and 71 deletions

View File

@ -84,6 +84,7 @@
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure describes the static configuration of a TC channel */
struct sam_chconfig_s
@ -115,10 +116,10 @@ struct sam_chan_s
/* Debug stuff */
#ifdef CONFIG_SAM34_TC_REGDEBUG
bool wr; /* True:Last was a write */
uint32_t regaddr; /* Last address */
uint32_t regval; /* Last value */
int ntimes; /* Number of times */
bool wr; /* True:Last was a write */
uint32_t regaddr; /* Last address */
uint32_t regval; /* Last value */
int ntimes; /* Number of times */
#endif
};
@ -128,7 +129,7 @@ struct sam_chan_s
/* Low-level helpers ********************************************************/
static void sam_takesem(struct sam_chan_s *chan);
static int sam_takesem(struct sam_chan_s *chan);
#define sam_givesem(chan) (nxsem_post(&chan->exclsem))
#ifdef CONFIG_SAM34_TC_REGDEBUG
@ -158,6 +159,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel);
/****************************************************************************
* Private Data
****************************************************************************/
/* Static timer configuration */
static const struct sam_chconfig_s g_configs[] =
@ -340,9 +342,11 @@ static const uint8_t g_regoffset[TC_NREGISTERS] =
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: sam_takesem
*
@ -358,9 +362,9 @@ static const uint8_t g_regoffset[TC_NREGISTERS] =
*
****************************************************************************/
static void sam_takesem(struct sam_chan_s *chan)
static int sam_takesem(struct sam_chan_s *chan)
{
nxsem_wait_uninterruptible(&chan->exclsem);
return nxsem_wait_uninterruptible(&chan->exclsem);
}
/****************************************************************************
@ -386,19 +390,26 @@ static void sam_regdump(struct sam_chan_s *chan, const char *msg)
base = chan->base;
tmrinfo("TC%d [%08x]: %s\n", chan->chan, (int)base, msg);
tmrinfo(" BMR: %08x QIMR: %08x QISR: %08x WPMR: %08x\n",
getreg32(base+SAM_TC_BMR_OFFSET), getreg32(base+SAM_TC_QIMR_OFFSET),
getreg32(base+SAM_TC_QISR_OFFSET), getreg32(base+SAM_TC_WPMR_OFFSET));
getreg32(base + SAM_TC_BMR_OFFSET),
getreg32(base + SAM_TC_QIMR_OFFSET),
getreg32(base + SAM_TC_QISR_OFFSET),
getreg32(base + SAM_TC_WPMR_OFFSET));
base = chan->base;
tmrinfo("TC%d Channel %d [%08x]: %s\n", chan->chan, chan->chan, (int)base, msg);
tmrinfo("TC%d Channel %d [%08x]: %s\n",
chan->chan, chan->chan, (int)base, msg);
tmrinfo(" CMR: %08x SSMR: %08x RAB: %08x CV: %08x\n",
getreg32(base+SAM_TC_CMR_OFFSET), getreg32(base+SAM_TC_SMMR_OFFSET),
getreg32(base+SAM_TC_RAB_OFFSET), getreg32(base+SAM_TC_CV_OFFSET));
getreg32(base + SAM_TC_CMR_OFFSET),
getreg32(base + SAM_TC_SMMR_OFFSET),
getreg32(base + SAM_TC_RAB_OFFSET),
getreg32(base + SAM_TC_CV_OFFSET));
tmrinfo(" RA: %08x RB: %08x RC: %08x SR: %08x\n",
getreg32(base+SAM_TC_RA_OFFSET), getreg32(base+SAM_TC_RB_OFFSET),
getreg32(base+SAM_TC_RC_OFFSET), getreg32(base+SAM_TC_SR_OFFSET));
getreg32(base + SAM_TC_RA_OFFSET),
getreg32(base + SAM_TC_RB_OFFSET),
getreg32(base + SAM_TC_RC_OFFSET),
getreg32(base + SAM_TC_SR_OFFSET));
tmrinfo(" IMR: %08x\n",
getreg32(base+SAM_TC_IMR_OFFSET));
getreg32(base + SAM_TC_IMR_OFFSET));
}
#endif
@ -490,8 +501,8 @@ static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan,
*
****************************************************************************/
static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
uint32_t regval)
static inline void sam_chan_putreg(struct sam_chan_s *chan,
unsigned int offset, uint32_t regval)
{
uint32_t regaddr = chan->base + offset;
@ -508,6 +519,7 @@ static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: sam_tc_interrupt
*
@ -521,7 +533,8 @@ static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -616,8 +629,8 @@ static int sam_tc_mckdivider(uint32_t mck)
* Name: sam_tc_freqdiv_lookup
*
* Description:
* Given the TC input frequency (Ftcin) and a divider index, return the value of
* the Ftcin divider.
* Given the TC input frequency (Ftcin) and a divider index, return the
* value of the Ftcin divider.
*
* Input Parameters:
* ftcin - TC input frequency
@ -693,7 +706,8 @@ static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx)
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -788,7 +802,13 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
/* Get exclusive access to the timer/count data structure */
sam_takesem(chan);
ret = sam_takesem(chan);
if (ret < 0)
{
leave_critical_section(flags);
return ret;
}
leave_critical_section(flags);
/* Is it available? */
@ -815,6 +835,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_tc_allocate
*
@ -1223,7 +1244,7 @@ int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks)
* frequency < tc_input_frequency / divider.
*/
for (; ndx < (TC_NDIVOPTIONS-1); ndx++)
for (; ndx < (TC_NDIVOPTIONS - 1); ndx++)
{
if (frequency > sam_tc_divfreq_lookup(ftcin, ndx + 1))
{

View File

@ -82,6 +82,7 @@
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure describes the static configuration of a TC channel */
struct sam_chconfig_s
@ -136,10 +137,10 @@ struct sam_tc_s
/* Debug stuff */
#ifdef CONFIG_SAMA5_TC_REGDEBUG
bool wr; /* True:Last was a write */
uint32_t regaddr; /* Last address */
uint32_t regval; /* Last value */
int ntimes; /* Number of times */
bool wr; /* True:Last was a write */
uint32_t regaddr; /* Last address */
uint32_t regval; /* Last value */
int ntimes; /* Number of times */
#endif
};
@ -149,7 +150,7 @@ struct sam_tc_s
/* Low-level helpers ********************************************************/
static void sam_takesem(struct sam_tc_s *tc);
static int sam_takesem(struct sam_tc_s *tc);
#define sam_givesem(tc) (nxsem_post(&tc->exclsem))
#ifdef CONFIG_SAMA5_TC_REGDEBUG
@ -196,6 +197,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel);
/****************************************************************************
* Private Data
****************************************************************************/
/* Static timer configuration */
#ifdef CONFIG_SAMA5_TC0
@ -451,9 +453,11 @@ static const uint8_t g_regoffset[TC_NREGISTERS] =
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: sam_takesem
*
@ -469,9 +473,9 @@ static const uint8_t g_regoffset[TC_NREGISTERS] =
*
****************************************************************************/
static void sam_takesem(struct sam_tc_s *tc)
static int sam_takesem(struct sam_tc_s *tc)
{
nxsem_wait_uninterruptible(&tc->exclsem);
return nxsem_wait_uninterruptible(&tc->exclsem);
}
/****************************************************************************
@ -498,19 +502,25 @@ static void sam_regdump(struct sam_chan_s *chan, const char *msg)
base = tc->base;
tminfo("TC%d [%08x]: %s\n", tc->tc, (int)base, msg);
tminfo(" BMR: %08x QIMR: %08x QISR: %08x WPMR: %08x\n",
getreg32(base+SAM_TC_BMR_OFFSET), getreg32(base+SAM_TC_QIMR_OFFSET),
getreg32(base+SAM_TC_QISR_OFFSET), getreg32(base+SAM_TC_WPMR_OFFSET));
getreg32(base + SAM_TC_BMR_OFFSET),
getreg32(base + SAM_TC_QIMR_OFFSET),
getreg32(base + SAM_TC_QISR_OFFSET),
getreg32(base + SAM_TC_WPMR_OFFSET));
base = chan->base;
tminfo("TC%d Channel %d [%08x]: %s\n", tc->tc, chan->chan, (int)base, msg);
tminfo(" CMR: %08x SSMR: %08x RAB: %08x CV: %08x\n",
getreg32(base+SAM_TC_CMR_OFFSET), getreg32(base+SAM_TC_SMMR_OFFSET),
getreg32(base+SAM_TC_RAB_OFFSET), getreg32(base+SAM_TC_CV_OFFSET));
getreg32(base + SAM_TC_CMR_OFFSET),
getreg32(base + SAM_TC_SMMR_OFFSET),
getreg32(base + SAM_TC_RAB_OFFSET),
getreg32(base + SAM_TC_CV_OFFSET));
tminfo(" RA: %08x RB: %08x RC: %08x SR: %08x\n",
getreg32(base+SAM_TC_RA_OFFSET), getreg32(base+SAM_TC_RB_OFFSET),
getreg32(base+SAM_TC_RC_OFFSET), getreg32(base+SAM_TC_SR_OFFSET));
getreg32(base + SAM_TC_RA_OFFSET),
getreg32(base + SAM_TC_RB_OFFSET),
getreg32(base + SAM_TC_RC_OFFSET),
getreg32(base + SAM_TC_SR_OFFSET));
tminfo(" IMR: %08x\n",
getreg32(base+SAM_TC_IMR_OFFSET));
getreg32(base + SAM_TC_IMR_OFFSET));
}
#endif
@ -651,8 +661,8 @@ static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan,
*
****************************************************************************/
static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
uint32_t regval)
static inline void sam_chan_putreg(struct sam_chan_s *chan,
unsigned int offset, uint32_t regval)
{
uint32_t regaddr = chan->base + offset;
@ -669,6 +679,7 @@ static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: sam_tc_interrupt
*
@ -682,7 +693,8 @@ static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -749,7 +761,8 @@ static int sam_tc_interrupt(struct sam_tc_s *tc)
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -777,6 +790,7 @@ static int sam_tc678_interrupt(int irq, void *context, FAR void *arg)
/****************************************************************************
* Initialization
****************************************************************************/
/****************************************************************************
* Name: sam_tc_mckdivider
*
@ -821,8 +835,8 @@ static int sam_tc_mckdivider(uint32_t mck)
* Name: sam_tc_freqdiv_lookup
*
* Description:
* Given the TC input frequency (Ftcin) and a divider index, return the value of
* the Ftcin divider.
* Given the TC input frequency (Ftcin) and a divider index, return the
* value of the Ftcin divider.
*
* Input Parameters:
* ftcin - TC input frequency
@ -898,7 +912,8 @@ static uint32_t sam_tc_divfreq_lookup(uint32_t ftcin, int ndx)
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -1039,7 +1054,13 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
/* Get exclusive access to the timer/count data structure */
sam_takesem(tc);
ret = sam_takesem(tc);
if (ret < 0)
{
leave_critical_section(flags);
return ret;
}
leave_critical_section(flags);
/* Get the requested channel structure */
@ -1070,6 +1091,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_tc_allocate
*
@ -1484,7 +1506,7 @@ int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks)
* frequency < tc_input_frequency / divider.
*/
for (; ndx < (TC_NDIVOPTIONS-1); ndx++)
for (; ndx < (TC_NDIVOPTIONS - 1); ndx++)
{
if (frequency > sam_tc_divfreq_lookup(ftcin, ndx + 1))
{

View File

@ -84,6 +84,7 @@
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure describes the static configuration of a TC channel */
struct sam_chconfig_s
@ -138,10 +139,10 @@ struct sam_tc_s
/* Debug stuff */
#ifdef CONFIG_SAMV7_TC_REGDEBUG
bool wr; /* True:Last was a write */
uint32_t regaddr; /* Last address */
uint32_t regval; /* Last value */
int ntimes; /* Number of times */
bool wr; /* True:Last was a write */
uint32_t regaddr; /* Last address */
uint32_t regval; /* Last value */
int ntimes; /* Number of times */
#endif
};
@ -159,7 +160,7 @@ struct mck_divsrc_s
/* Low-level helpers ********************************************************/
static void sam_takesem(struct sam_tc_s *tc);
static int sam_takesem(struct sam_tc_s *tc);
#define sam_givesem(tc) (nxsem_post(&tc->exclsem))
#ifdef CONFIG_SAMV7_TC_REGDEBUG
@ -220,6 +221,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel);
/****************************************************************************
* Private Data
****************************************************************************/
/* Static timer configuration */
#ifdef CONFIG_SAMV7_TC0
@ -569,11 +571,20 @@ static struct sam_tc_s g_tc901;
static struct mck_divsrc_s g_log2divider[TC_NDIVOPTIONS] =
{
/* TIMER_CLOCK1(0) -> PCK6 */
{3, 1}, /* TIMER_CLOCK2(1) -> MCK/8 */
{5, 2}, /* TIMER_CLOCK3(2) -> MCK/32 */
{7, 3}, /* TIMER_CLOCK4(3) -> MCK/128 */
{0, 4}, /* TIMER_CLOCK5(4) -> SLCK (No MCK divider) */
/* TIMER_CLOCK1(0) -> PCK6 */
{
3, 1 /* TIMER_CLOCK2(1) -> MCK/8 */
},
{
5, 2 /* TIMER_CLOCK3(2) -> MCK/32 */
},
{
7, 3 /* TIMER_CLOCK4(3) -> MCK/128 */
},
{
0, 4 /* TIMER_CLOCK5(4) -> SLCK (No MCK divider) */
},
};
/* TC register lookup used by sam_tc_setregister */
@ -590,9 +601,11 @@ static const uint8_t g_regoffset[TC_NREGISTERS] =
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Low-level Helpers
****************************************************************************/
/****************************************************************************
* Name: sam_takesem
*
@ -608,9 +621,9 @@ static const uint8_t g_regoffset[TC_NREGISTERS] =
*
****************************************************************************/
static void sam_takesem(struct sam_tc_s *tc)
static int sam_takesem(struct sam_tc_s *tc)
{
nxsem_wait_uninterruptible(&tc->exclsem);
return nxsem_wait_uninterruptible(&tc->exclsem);
}
/****************************************************************************
@ -640,17 +653,24 @@ static void sam_regdump(struct sam_chan_s *chan, const char *msg)
base = tc->base;
tmrinfo("TC%d [%08x]: %s\n", tc->tc, (int)base, msg);
tmrinfo(" BMR: %08x QIMR: %08x QISR: %08x WPMR: %08x\n",
getreg32(base+SAM_TC_BMR_OFFSET), getreg32(base+SAM_TC_QIMR_OFFSET),
getreg32(base+SAM_TC_QISR_OFFSET), getreg32(base+SAM_TC_WPMR_OFFSET));
getreg32(base + SAM_TC_BMR_OFFSET),
getreg32(base + SAM_TC_QIMR_OFFSET),
getreg32(base + SAM_TC_QISR_OFFSET),
getreg32(base + SAM_TC_WPMR_OFFSET));
base = chan->base;
tmrinfo("TC%d Channel %d [%08x]: %s\n", tc->tc, chan->chan, (int)base, msg);
tmrinfo("TC%d Channel %d [%08x]: %s\n",
tc->tc, chan->chan, (int)base, msg);
tmrinfo(" CMR: %08x SSMR: %08x RAB: %08x CV: %08x\n",
getreg32(base+SAM_TC_CMR_OFFSET), getreg32(base+SAM_TC_SMMR_OFFSET),
getreg32(base+SAM_TC_RAB_OFFSET), getreg32(base+SAM_TC_CV_OFFSET));
getreg32(base + SAM_TC_CMR_OFFSET),
getreg32(base + SAM_TC_SMMR_OFFSET),
getreg32(base + SAM_TC_RAB_OFFSET),
getreg32(base + SAM_TC_CV_OFFSET));
tmrinfo(" RA: %08x RB: %08x RC: %08x IMR: %08x\n",
getreg32(base+SAM_TC_RA_OFFSET), getreg32(base+SAM_TC_RB_OFFSET),
getreg32(base+SAM_TC_RC_OFFSET), getreg32(base+SAM_TC_IMR_OFFSET));
getreg32(base + SAM_TC_RA_OFFSET),
getreg32(base + SAM_TC_RB_OFFSET),
getreg32(base + SAM_TC_RC_OFFSET),
getreg32(base + SAM_TC_IMR_OFFSET));
}
#endif
@ -791,8 +811,8 @@ static inline uint32_t sam_chan_getreg(struct sam_chan_s *chan,
*
****************************************************************************/
static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
uint32_t regval)
static inline void sam_chan_putreg(struct sam_chan_s *chan,
unsigned int offset, uint32_t regval)
{
uint32_t regaddr = chan->base + offset;
@ -809,6 +829,7 @@ static inline void sam_chan_putreg(struct sam_chan_s *chan, unsigned int offset,
/****************************************************************************
* Interrupt Handling
****************************************************************************/
/****************************************************************************
* Name: sam_tc_interrupt
*
@ -879,7 +900,8 @@ static int sam_tc_interrupt(struct sam_tc_s *tc, struct sam_chan_s *chan)
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -1105,7 +1127,8 @@ static int sam_tc_mcksrc(uint32_t frequency, uint32_t *tcclks,
* A pointer to the initialized timer channel structure associated with tc
* and channel. NULL is returned on any failure.
*
* On successful return, the caller holds the tc exclusive access semaphore.
* On successful return, the caller holds the tc exclusive access
* semaphore.
*
****************************************************************************/
@ -1120,6 +1143,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
int chndx;
int ch;
int chfirst;
int ret;
/* Select the timer/counter and get the index associated with the
* channel.
@ -1208,7 +1232,13 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
/* Get exclusive access to the timer/count data structure */
sam_takesem(tc);
ret = sam_takesem(tc);
if (ret < 0)
{
leave_critical_section(flags);
return NULL;
}
leave_critical_section(flags);
/* Is the requested channel already in-use? */
@ -1286,6 +1316,7 @@ static inline struct sam_chan_s *sam_tc_initialize(int channel)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_tc_allocate
*
@ -1720,7 +1751,8 @@ int sam_tc_clockselect(uint32_t frequency, uint32_t *tcclks,
if (tcclks)
{
tmrinfo("return tcclks=%08lx\n", (unsigned long)TC_CMR_TCCLKS_PCK6);
tmrinfo("return tcclks=%08lx\n",
(unsigned long)TC_CMR_TCCLKS_PCK6);
*tcclks = TC_CMR_TCCLKS_PCK6;
}