aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/kernel/hpet.c
diff options
context:
space:
mode:
authorvenkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com>2008-09-05 18:02:17 -0700
committerIngo Molnar <mingo@elte.hu>2008-10-16 16:53:07 +0200
commit58ac1e76ce77d515bd5cb65dbc465a040da341c6 (patch)
treee1bd9e60aaaa5098ea368c04043adf2a79fca604 /arch/x86/kernel/hpet.c
parentb40d575bf0679c45aaf9e1161fc51a6b041b7210 (diff)
x86: HPET_MSI Basic HPET_MSI setup code
Basic HPET MSI setup code. Routines to perform basic MSI read write in HPET memory map and setting up irq_chip for HPET MSI. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r--arch/x86/kernel/hpet.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index f7cb5e9e261..3f10d16a834 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -6,6 +6,8 @@
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
#include <asm/fixmap.h>
#include <asm/hpet.h>
@@ -25,6 +27,15 @@
unsigned long hpet_address;
static void __iomem *hpet_virt_address;
+struct hpet_dev {
+ struct clock_event_device evt;
+ unsigned int num;
+ int cpu;
+ unsigned int irq;
+ unsigned int flags;
+ char name[10];
+};
+
unsigned long hpet_readl(unsigned long a)
{
return readl(hpet_virt_address + a);
@@ -305,6 +316,49 @@ static int hpet_legacy_next_event(unsigned long delta,
}
/*
+ * HPET MSI Support
+ */
+
+void hpet_msi_unmask(unsigned int irq)
+{
+ struct hpet_dev *hdev = get_irq_data(irq);
+ unsigned long cfg;
+
+ /* unmask it */
+ cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
+ cfg |= HPET_TN_FSB;
+ hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
+}
+
+void hpet_msi_mask(unsigned int irq)
+{
+ unsigned long cfg;
+ struct hpet_dev *hdev = get_irq_data(irq);
+
+ /* mask it */
+ cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
+ cfg &= ~HPET_TN_FSB;
+ hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
+}
+
+void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+{
+ struct hpet_dev *hdev = get_irq_data(irq);
+
+ hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
+ hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
+}
+
+void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+{
+ struct hpet_dev *hdev = get_irq_data(irq);
+
+ msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
+ msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
+ msg->address_hi = 0;
+}
+
+/*
* Clock source related code
*/
static cycle_t read_hpet(void)