diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-04-04 10:26:10 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-04 12:36:49 -0400 |
commit | 5761d64b277c287a7520b868c32d656ef03374b4 (patch) | |
tree | 9fb217efd1a50ed4d5fbf5c313cae586604d6f2f /drivers/char | |
parent | 47001d603375f857a7fab0e9c095d964a1ea0039 (diff) |
x86: revert assign IRQs to hpet timer
The commits:
commit 37a47db8d7f0f38dac5acf5a13abbc8f401707fa
Author: Balaji Rao <balajirrao@gmail.com>
Date: Wed Jan 30 13:30:03 2008 +0100
x86: assign IRQs to HPET timers, fix
and
commit e3f37a54f690d3e64995ea7ecea08c5ab3070faf
Author: Balaji Rao <balajirrao@gmail.com>
Date: Wed Jan 30 13:30:03 2008 +0100
x86: assign IRQs to HPET timers
have been identified to cause a regression on some platforms due to
the assignement of legacy IRQs which makes the legacy devices
connected to those IRQs disfunctional.
Revert them.
This fixes http://bugzilla.kernel.org/show_bug.cgi?id=10382
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/hpet.c | 51 |
1 files changed, 7 insertions, 44 deletions
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 465ad35ed38f..1399971be689 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -731,14 +731,14 @@ static unsigned long hpet_calibrate(struct hpets *hpetp) | |||
731 | 731 | ||
732 | int hpet_alloc(struct hpet_data *hdp) | 732 | int hpet_alloc(struct hpet_data *hdp) |
733 | { | 733 | { |
734 | u64 cap, mcfg, hpet_config; | 734 | u64 cap, mcfg; |
735 | struct hpet_dev *devp; | 735 | struct hpet_dev *devp; |
736 | u32 i, ntimer, irq; | 736 | u32 i, ntimer; |
737 | struct hpets *hpetp; | 737 | struct hpets *hpetp; |
738 | size_t siz; | 738 | size_t siz; |
739 | struct hpet __iomem *hpet; | 739 | struct hpet __iomem *hpet; |
740 | static struct hpets *last = NULL; | 740 | static struct hpets *last = NULL; |
741 | unsigned long period, irq_bitmap; | 741 | unsigned long period; |
742 | unsigned long long temp; | 742 | unsigned long long temp; |
743 | 743 | ||
744 | /* | 744 | /* |
@@ -765,47 +765,11 @@ int hpet_alloc(struct hpet_data *hdp) | |||
765 | hpetp->hp_hpet_phys = hdp->hd_phys_address; | 765 | hpetp->hp_hpet_phys = hdp->hd_phys_address; |
766 | 766 | ||
767 | hpetp->hp_ntimer = hdp->hd_nirqs; | 767 | hpetp->hp_ntimer = hdp->hd_nirqs; |
768 | hpet = hpetp->hp_hpet; | ||
769 | |||
770 | /* Assign IRQs statically for legacy devices */ | ||
771 | hpetp->hp_dev[0].hd_hdwirq = hdp->hd_irq[0]; | ||
772 | hpetp->hp_dev[1].hd_hdwirq = hdp->hd_irq[1]; | ||
773 | |||
774 | /* Assign IRQs dynamically for the others */ | ||
775 | for (i = 2, devp = &hpetp->hp_dev[2]; i < hdp->hd_nirqs; i++, devp++) { | ||
776 | struct hpet_timer __iomem *timer; | ||
777 | 768 | ||
778 | timer = &hpet->hpet_timers[devp - hpetp->hp_dev]; | 769 | for (i = 0; i < hdp->hd_nirqs; i++) |
770 | hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i]; | ||
779 | 771 | ||
780 | /* Check if there's already an IRQ assigned to the timer */ | 772 | hpet = hpetp->hp_hpet; |
781 | if (hdp->hd_irq[i]) { | ||
782 | hpetp->hp_dev[i].hd_hdwirq = hdp->hd_irq[i]; | ||
783 | continue; | ||
784 | } | ||
785 | |||
786 | hpet_config = readq(&timer->hpet_config); | ||
787 | irq_bitmap = (hpet_config & Tn_INT_ROUTE_CAP_MASK) | ||
788 | >> Tn_INT_ROUTE_CAP_SHIFT; | ||
789 | if (!irq_bitmap) | ||
790 | irq = 0; /* No valid IRQ Assignable */ | ||
791 | else { | ||
792 | irq = find_first_bit(&irq_bitmap, 32); | ||
793 | do { | ||
794 | hpet_config |= irq << Tn_INT_ROUTE_CNF_SHIFT; | ||
795 | writeq(hpet_config, &timer->hpet_config); | ||
796 | |||
797 | /* | ||
798 | * Verify whether we have written a valid | ||
799 | * IRQ number by reading it back again | ||
800 | */ | ||
801 | hpet_config = readq(&timer->hpet_config); | ||
802 | if (irq == (hpet_config & Tn_INT_ROUTE_CNF_MASK) | ||
803 | >> Tn_INT_ROUTE_CNF_SHIFT) | ||
804 | break; /* Success */ | ||
805 | } while ((irq = (find_next_bit(&irq_bitmap, 32, irq)))); | ||
806 | } | ||
807 | hpetp->hp_dev[i].hd_hdwirq = irq; | ||
808 | } | ||
809 | 773 | ||
810 | cap = readq(&hpet->hpet_cap); | 774 | cap = readq(&hpet->hpet_cap); |
811 | 775 | ||
@@ -836,8 +800,7 @@ int hpet_alloc(struct hpet_data *hdp) | |||
836 | hpetp->hp_which, hdp->hd_phys_address, | 800 | hpetp->hp_which, hdp->hd_phys_address, |
837 | hpetp->hp_ntimer > 1 ? "s" : ""); | 801 | hpetp->hp_ntimer > 1 ? "s" : ""); |
838 | for (i = 0; i < hpetp->hp_ntimer; i++) | 802 | for (i = 0; i < hpetp->hp_ntimer; i++) |
839 | printk("%s %d", i > 0 ? "," : "", | 803 | printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); |
840 | hpetp->hp_dev[i].hd_hdwirq); | ||
841 | printk("\n"); | 804 | printk("\n"); |
842 | 805 | ||
843 | printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", | 806 | printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n", |