diff options
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r-- | arch/x86/kernel/hpet.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index f7cb5e9e261e..3f10d16a8348 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -6,6 +6,8 @@ | |||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/sysdev.h> | 7 | #include <linux/sysdev.h> |
8 | #include <linux/pm.h> | 8 | #include <linux/pm.h> |
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/cpu.h> | ||
9 | 11 | ||
10 | #include <asm/fixmap.h> | 12 | #include <asm/fixmap.h> |
11 | #include <asm/hpet.h> | 13 | #include <asm/hpet.h> |
@@ -25,6 +27,15 @@ | |||
25 | unsigned long hpet_address; | 27 | unsigned long hpet_address; |
26 | static void __iomem *hpet_virt_address; | 28 | static void __iomem *hpet_virt_address; |
27 | 29 | ||
30 | struct hpet_dev { | ||
31 | struct clock_event_device evt; | ||
32 | unsigned int num; | ||
33 | int cpu; | ||
34 | unsigned int irq; | ||
35 | unsigned int flags; | ||
36 | char name[10]; | ||
37 | }; | ||
38 | |||
28 | unsigned long hpet_readl(unsigned long a) | 39 | unsigned long hpet_readl(unsigned long a) |
29 | { | 40 | { |
30 | return readl(hpet_virt_address + a); | 41 | return readl(hpet_virt_address + a); |
@@ -305,6 +316,49 @@ static int hpet_legacy_next_event(unsigned long delta, | |||
305 | } | 316 | } |
306 | 317 | ||
307 | /* | 318 | /* |
319 | * HPET MSI Support | ||
320 | */ | ||
321 | |||
322 | void hpet_msi_unmask(unsigned int irq) | ||
323 | { | ||
324 | struct hpet_dev *hdev = get_irq_data(irq); | ||
325 | unsigned long cfg; | ||
326 | |||
327 | /* unmask it */ | ||
328 | cfg = hpet_readl(HPET_Tn_CFG(hdev->num)); | ||
329 | cfg |= HPET_TN_FSB; | ||
330 | hpet_writel(cfg, HPET_Tn_CFG(hdev->num)); | ||
331 | } | ||
332 | |||
333 | void hpet_msi_mask(unsigned int irq) | ||
334 | { | ||
335 | unsigned long cfg; | ||
336 | struct hpet_dev *hdev = get_irq_data(irq); | ||
337 | |||
338 | /* mask it */ | ||
339 | cfg = hpet_readl(HPET_Tn_CFG(hdev->num)); | ||
340 | cfg &= ~HPET_TN_FSB; | ||
341 | hpet_writel(cfg, HPET_Tn_CFG(hdev->num)); | ||
342 | } | ||
343 | |||
344 | void hpet_msi_write(unsigned int irq, struct msi_msg *msg) | ||
345 | { | ||
346 | struct hpet_dev *hdev = get_irq_data(irq); | ||
347 | |||
348 | hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num)); | ||
349 | hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4); | ||
350 | } | ||
351 | |||
352 | void hpet_msi_read(unsigned int irq, struct msi_msg *msg) | ||
353 | { | ||
354 | struct hpet_dev *hdev = get_irq_data(irq); | ||
355 | |||
356 | msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num)); | ||
357 | msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4); | ||
358 | msg->address_hi = 0; | ||
359 | } | ||
360 | |||
361 | /* | ||
308 | * Clock source related code | 362 | * Clock source related code |
309 | */ | 363 | */ |
310 | static cycle_t read_hpet(void) | 364 | static cycle_t read_hpet(void) |