From 8f85a579410c301c22bb6525071d82790a342d7f Mon Sep 17 00:00:00 2001 From: Ouss4 Date: Sun, 5 Apr 2020 00:16:39 +0100 Subject: [PATCH] Check the return of nxsem_wait_unterruptible() This commit is for all tc drivers under arch/. --- arch/arm/src/sam34/sam4cm_tc.c | 67 +++++++++++++++++---------- arch/arm/src/sama5/sam_tc.c | 68 ++++++++++++++++++---------- arch/arm/src/samv7/sam_tc.c | 82 +++++++++++++++++++++++----------- 3 files changed, 146 insertions(+), 71 deletions(-) diff --git a/arch/arm/src/sam34/sam4cm_tc.c b/arch/arm/src/sam34/sam4cm_tc.c index 91050f7e86..8df6e7b2c2 100644 --- a/arch/arm/src/sam34/sam4cm_tc.c +++ b/arch/arm/src/sam34/sam4cm_tc.c @@ -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)) { diff --git a/arch/arm/src/sama5/sam_tc.c b/arch/arm/src/sama5/sam_tc.c index 8733107a38..525544a8d0 100644 --- a/arch/arm/src/sama5/sam_tc.c +++ b/arch/arm/src/sama5/sam_tc.c @@ -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)) { diff --git a/arch/arm/src/samv7/sam_tc.c b/arch/arm/src/samv7/sam_tc.c index 6256515cca..d638fa1fc8 100644 --- a/arch/arm/src/samv7/sam_tc.c +++ b/arch/arm/src/samv7/sam_tc.c @@ -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; }