Commit e856f2ad014e6cb1bd3eca126be23b8f919f3dd1
1 parent
c9a33054
Use a QEMUBH when an OMAP timer must expire immediately.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5265 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
14 additions
and
10 deletions
hw/omap1.c
@@ -664,6 +664,7 @@ struct omap_mpu_timer_s { | @@ -664,6 +664,7 @@ struct omap_mpu_timer_s { | ||
664 | uint32_t val; | 664 | uint32_t val; |
665 | int64_t time; | 665 | int64_t time; |
666 | QEMUTimer *timer; | 666 | QEMUTimer *timer; |
667 | + QEMUBH *tick; | ||
667 | int64_t rate; | 668 | int64_t rate; |
668 | int it_ena; | 669 | int it_ena; |
669 | 670 | ||
@@ -708,21 +709,15 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) | @@ -708,21 +709,15 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) | ||
708 | * ticks. */ | 709 | * ticks. */ |
709 | if (expires > (ticks_per_sec >> 10) || timer->ar) | 710 | if (expires > (ticks_per_sec >> 10) || timer->ar) |
710 | qemu_mod_timer(timer->timer, timer->time + expires); | 711 | qemu_mod_timer(timer->timer, timer->time + expires); |
711 | - else { | ||
712 | - timer->val = 0; | ||
713 | - timer->st = 0; | ||
714 | - if (timer->it_ena) | ||
715 | - /* Edge-triggered irq */ | ||
716 | - qemu_irq_pulse(timer->irq); | ||
717 | - } | 712 | + else |
713 | + qemu_bh_schedule(timer->tick); | ||
718 | } else | 714 | } else |
719 | qemu_del_timer(timer->timer); | 715 | qemu_del_timer(timer->timer); |
720 | } | 716 | } |
721 | 717 | ||
722 | -static void omap_timer_tick(void *opaque) | 718 | +static void omap_timer_fire(void *opaque) |
723 | { | 719 | { |
724 | - struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque; | ||
725 | - omap_timer_sync(timer); | 720 | + struct omap_mpu_timer_s *timer = opaque; |
726 | 721 | ||
727 | if (!timer->ar) { | 722 | if (!timer->ar) { |
728 | timer->val = 0; | 723 | timer->val = 0; |
@@ -732,6 +727,14 @@ static void omap_timer_tick(void *opaque) | @@ -732,6 +727,14 @@ static void omap_timer_tick(void *opaque) | ||
732 | if (timer->it_ena) | 727 | if (timer->it_ena) |
733 | /* Edge-triggered irq */ | 728 | /* Edge-triggered irq */ |
734 | qemu_irq_pulse(timer->irq); | 729 | qemu_irq_pulse(timer->irq); |
730 | +} | ||
731 | + | ||
732 | +static void omap_timer_tick(void *opaque) | ||
733 | +{ | ||
734 | + struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque; | ||
735 | + | ||
736 | + omap_timer_sync(timer); | ||
737 | + omap_timer_fire(timer); | ||
735 | omap_timer_update(timer); | 738 | omap_timer_update(timer); |
736 | } | 739 | } |
737 | 740 | ||
@@ -835,6 +838,7 @@ struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base, | @@ -835,6 +838,7 @@ struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base, | ||
835 | s->clk = clk; | 838 | s->clk = clk; |
836 | s->base = base; | 839 | s->base = base; |
837 | s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s); | 840 | s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s); |
841 | + s->tick = qemu_bh_new(omap_timer_fire, s); | ||
838 | omap_mpu_timer_reset(s); | 842 | omap_mpu_timer_reset(s); |
839 | omap_timer_clk_setup(s); | 843 | omap_timer_clk_setup(s); |
840 | 844 |