diff options
author | sam <sam@FreeBSD.org> | 2009-06-22 20:36:22 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2009-06-22 20:36:22 +0000 |
commit | e8030f4a28ba52b796c613adfaa81f2f0983d6fd (patch) | |
tree | 0e82387e99c79cf2cffa3bb5a26c3e24d94bee80 /sys/arm | |
parent | bb5f483a5c91f72926d57599bb816fe45be133fc (diff) | |
download | FreeBSD-src-e8030f4a28ba52b796c613adfaa81f2f0983d6fd.zip FreeBSD-src-e8030f4a28ba52b796c613adfaa81f2f0983d6fd.tar.gz |
rewrite arm_get_next_irq to always make forward progress (should be optimized)
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/xscale/ixp425/ixp425.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/sys/arm/xscale/ixp425/ixp425.c b/sys/arm/xscale/ixp425/ixp425.c index f19f973..ffe48ae 100644 --- a/sys/arm/xscale/ixp425/ixp425.c +++ b/sys/arm/xscale/ixp425/ixp425.c @@ -214,15 +214,27 @@ ixp435_irq_read(void) } int -arm_get_next_irq(int last __unused) +arm_get_next_irq(int last) { - uint32_t irq; - - if ((irq = ixp425_irq_read())) - return (ffs(irq) - 1); - if (cpu_is_ixp43x() && (irq = ixp435_irq_read())) - return (32 + ffs(irq) - 1); - return (-1); + uint32_t mask; + + last += 1; /* always advance fwd, NB: handles -1 */ + if (last < 32) { + mask = ixp425_irq_read() >> last; + for (; mask != 0; mask >>= 1, last += 1) { + if (mask & 1) + return last; + } + last = 32; + } + if (cpu_is_ixp43x()) { + mask = ixp435_irq_read() >> (32-last); + for (; mask != 0; mask >>= 1, last++) { + if (mask & 1) + return last; + } + } + return -1; } void |