aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/00-INDEX2
-rw-r--r--Documentation/timers/00-INDEX10
-rw-r--r--Documentation/timers/hpet.txt (renamed from Documentation/hpet.txt)0
-rw-r--r--drivers/char/hpet.c63
-rw-r--r--include/linux/hpet.h3
5 files changed, 75 insertions, 3 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 6de71308a906..cfaa505dfd06 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -161,8 +161,6 @@ hayes-esp.txt
161 - info on using the Hayes ESP serial driver. 161 - info on using the Hayes ESP serial driver.
162highuid.txt 162highuid.txt
163 - notes on the change from 16 bit to 32 bit user/group IDs. 163 - notes on the change from 16 bit to 32 bit user/group IDs.
164hpet.txt
165 - High Precision Event Timer Driver for Linux.
166timers/ 164timers/
167 - info on the timer related topics 165 - info on the timer related topics
168hw_random.txt 166hw_random.txt
diff --git a/Documentation/timers/00-INDEX b/Documentation/timers/00-INDEX
new file mode 100644
index 000000000000..397dc35e1323
--- /dev/null
+++ b/Documentation/timers/00-INDEX
@@ -0,0 +1,10 @@
100-INDEX
2 - this file
3highres.txt
4 - High resolution timers and dynamic ticks design notes
5hpet.txt
6 - High Precision Event Timer Driver for Linux
7hrtimers.txt
8 - subsystem for high-resolution kernel timers
9timer_stats.txt
10 - timer usage statistics
diff --git a/Documentation/hpet.txt b/Documentation/timers/hpet.txt
index 6ad52d9dad6c..6ad52d9dad6c 100644
--- a/Documentation/hpet.txt
+++ b/Documentation/timers/hpet.txt
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index b3f5dbc6d880..f3981ffe20f0 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -185,6 +185,67 @@ static irqreturn_t hpet_interrupt(int irq, void *data)
185 return IRQ_HANDLED; 185 return IRQ_HANDLED;
186} 186}
187 187
188static void hpet_timer_set_irq(struct hpet_dev *devp)
189{
190 unsigned long v;
191 int irq, gsi;
192 struct hpet_timer __iomem *timer;
193
194 spin_lock_irq(&hpet_lock);
195 if (devp->hd_hdwirq) {
196 spin_unlock_irq(&hpet_lock);
197 return;
198 }
199
200 timer = devp->hd_timer;
201
202 /* we prefer level triggered mode */
203 v = readl(&timer->hpet_config);
204 if (!(v & Tn_INT_TYPE_CNF_MASK)) {
205 v |= Tn_INT_TYPE_CNF_MASK;
206 writel(v, &timer->hpet_config);
207 }
208 spin_unlock_irq(&hpet_lock);
209
210 v = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >>
211 Tn_INT_ROUTE_CAP_SHIFT;
212
213 /*
214 * In PIC mode, skip IRQ0-4, IRQ6-9, IRQ12-15 which is always used by
215 * legacy device. In IO APIC mode, we skip all the legacy IRQS.
216 */
217 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC)
218 v &= ~0xf3df;
219 else
220 v &= ~0xffff;
221
222 for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
223 irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
224
225 if (irq >= NR_IRQS) {
226 irq = HPET_MAX_IRQ;
227 break;
228 }
229
230 gsi = acpi_register_gsi(irq, ACPI_LEVEL_SENSITIVE,
231 ACPI_ACTIVE_LOW);
232 if (gsi > 0)
233 break;
234
235 /* FIXME: Setup interrupt source table */
236 }
237
238 if (irq < HPET_MAX_IRQ) {
239 spin_lock_irq(&hpet_lock);
240 v = readl(&timer->hpet_config);
241 v |= irq << Tn_INT_ROUTE_CNF_SHIFT;
242 writel(v, &timer->hpet_config);
243 devp->hd_hdwirq = gsi;
244 spin_unlock_irq(&hpet_lock);
245 }
246 return;
247}
248
188static int hpet_open(struct inode *inode, struct file *file) 249static int hpet_open(struct inode *inode, struct file *file)
189{ 250{
190 struct hpet_dev *devp; 251 struct hpet_dev *devp;
@@ -219,6 +280,8 @@ static int hpet_open(struct inode *inode, struct file *file)
219 spin_unlock_irq(&hpet_lock); 280 spin_unlock_irq(&hpet_lock);
220 unlock_kernel(); 281 unlock_kernel();
221 282
283 hpet_timer_set_irq(devp);
284
222 return 0; 285 return 0;
223} 286}
224 287
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 2dc29ce6c8e4..6d2626b63a9a 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -37,6 +37,7 @@ struct hpet {
37#define hpet_compare _u1._hpet_compare 37#define hpet_compare _u1._hpet_compare
38 38
39#define HPET_MAX_TIMERS (32) 39#define HPET_MAX_TIMERS (32)
40#define HPET_MAX_IRQ (32)
40 41
41/* 42/*
42 * HPET general capabilities register 43 * HPET general capabilities register
@@ -64,7 +65,7 @@ struct hpet {
64 */ 65 */
65 66
66#define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL) 67#define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL)
67#define Tn_INI_ROUTE_CAP_SHIFT (32UL) 68#define Tn_INT_ROUTE_CAP_SHIFT (32UL)
68#define Tn_FSB_INT_DELCAP_MASK (0x8000UL) 69#define Tn_FSB_INT_DELCAP_MASK (0x8000UL)
69#define Tn_FSB_INT_DELCAP_SHIFT (15) 70#define Tn_FSB_INT_DELCAP_SHIFT (15)
70#define Tn_FSB_EN_CNF_MASK (0x4000UL) 71#define Tn_FSB_EN_CNF_MASK (0x4000UL)