mirror of https://gitee.com/openkylin/linux.git
OMAP clock/hwmod: fix off-by-one errors
Fix loop bailout off-by-one bugs reported by Juha Leppänen <juha_motorsportcom@luukku.com>. This second version incorporates comments from Russell King <linux@arm.linux.org.uk>. A new macro, 'omap_test_timeout', has been created, with cleaner code, and existing code has been converted to use it. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Juha Leppänen <juha_motorsportcom@luukku.com> Cc: Russell King <linux@arm.linux.org.uk>
This commit is contained in:
parent
3863c74b51
commit
6f8b7ff5b0
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
|
|
||||||
|
#include <plat/common.h>
|
||||||
|
|
||||||
#include "cm.h"
|
#include "cm.h"
|
||||||
#include "cm-regbits-24xx.h"
|
#include "cm-regbits-24xx.h"
|
||||||
#include "cm-regbits-34xx.h"
|
#include "cm-regbits-34xx.h"
|
||||||
|
@ -61,9 +63,8 @@ int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
|
||||||
mask = 1 << idlest_shift;
|
mask = 1 << idlest_shift;
|
||||||
|
|
||||||
/* XXX should be OMAP2 CM */
|
/* XXX should be OMAP2 CM */
|
||||||
while (((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) != ena) &&
|
omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
|
||||||
(i++ < MAX_MODULE_READY_TIME))
|
MAX_MODULE_READY_TIME, i);
|
||||||
udelay(1);
|
|
||||||
|
|
||||||
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
|
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
|
||||||
|
#include <plat/common.h>
|
||||||
#include <plat/cpu.h>
|
#include <plat/cpu.h>
|
||||||
#include <plat/clockdomain.h>
|
#include <plat/clockdomain.h>
|
||||||
#include <plat/powerdomain.h>
|
#include <plat/powerdomain.h>
|
||||||
|
@ -736,7 +737,7 @@ static int _wait_target_ready(struct omap_hwmod *oh)
|
||||||
static int _reset(struct omap_hwmod *oh)
|
static int _reset(struct omap_hwmod *oh)
|
||||||
{
|
{
|
||||||
u32 r, v;
|
u32 r, v;
|
||||||
int c;
|
int c = 0;
|
||||||
|
|
||||||
if (!oh->sysconfig ||
|
if (!oh->sysconfig ||
|
||||||
!(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
|
!(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
|
||||||
|
@ -758,13 +759,9 @@ static int _reset(struct omap_hwmod *oh)
|
||||||
return r;
|
return r;
|
||||||
_write_sysconfig(v, oh);
|
_write_sysconfig(v, oh);
|
||||||
|
|
||||||
c = 0;
|
omap_test_timeout((omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
|
||||||
while (c < MAX_MODULE_RESET_WAIT &&
|
SYSS_RESETDONE_MASK),
|
||||||
!(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
|
MAX_MODULE_RESET_WAIT, c);
|
||||||
SYSS_RESETDONE_MASK)) {
|
|
||||||
udelay(1);
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == MAX_MODULE_RESET_WAIT)
|
if (c == MAX_MODULE_RESET_WAIT)
|
||||||
WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
|
WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
|
||||||
|
|
|
@ -241,9 +241,8 @@ int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name)
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* Wait for lock */
|
/* Wait for lock */
|
||||||
while (((__raw_readl(reg) & mask) != ena) &&
|
omap_test_timeout(((__raw_readl(reg) & mask) == ena),
|
||||||
(i++ < MAX_MODULE_ENABLE_WAIT))
|
MAX_MODULE_ENABLE_WAIT, i);
|
||||||
udelay(1);
|
|
||||||
|
|
||||||
if (i < MAX_MODULE_ENABLE_WAIT)
|
if (i < MAX_MODULE_ENABLE_WAIT)
|
||||||
pr_debug("cm: Module associated with clock %s ready after %d "
|
pr_debug("cm: Module associated with clock %s ready after %d "
|
||||||
|
|
|
@ -71,4 +71,24 @@ void omap2_set_globals_sdrc(struct omap_globals *);
|
||||||
void omap2_set_globals_control(struct omap_globals *);
|
void omap2_set_globals_control(struct omap_globals *);
|
||||||
void omap2_set_globals_prcm(struct omap_globals *);
|
void omap2_set_globals_prcm(struct omap_globals *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* omap_test_timeout - busy-loop, testing a condition
|
||||||
|
* @cond: condition to test until it evaluates to true
|
||||||
|
* @timeout: maximum number of microseconds in the timeout
|
||||||
|
* @index: loop index (integer)
|
||||||
|
*
|
||||||
|
* Loop waiting for @cond to become true or until at least @timeout
|
||||||
|
* microseconds have passed. To use, define some integer @index in the
|
||||||
|
* calling code. After running, if @index == @timeout, then the loop has
|
||||||
|
* timed out.
|
||||||
|
*/
|
||||||
|
#define omap_test_timeout(cond, timeout, index) \
|
||||||
|
({ \
|
||||||
|
for (index = 0; index < timeout; index++) { \
|
||||||
|
if (cond) \
|
||||||
|
break; \
|
||||||
|
udelay(1); \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
|
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
|
||||||
|
|
Loading…
Reference in New Issue