aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/iosapic.c45
-rw-r--r--arch/ia64/kernel/paravirt.c25
-rw-r--r--include/asm-ia64/iosapic.h18
-rw-r--r--include/asm-ia64/paravirt.h40
4 files changed, 110 insertions, 18 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 082c31dcfd99..587196dd84fd 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -587,6 +587,15 @@ static inline int irq_is_shared (int irq)
587 return (iosapic_intr_info[irq].count > 1); 587 return (iosapic_intr_info[irq].count > 1);
588} 588}
589 589
590struct irq_chip*
591ia64_native_iosapic_get_irq_chip(unsigned long trigger)
592{
593 if (trigger == IOSAPIC_EDGE)
594 return &irq_type_iosapic_edge;
595 else
596 return &irq_type_iosapic_level;
597}
598
590static int 599static int
591register_intr (unsigned int gsi, int irq, unsigned char delivery, 600register_intr (unsigned int gsi, int irq, unsigned char delivery,
592 unsigned long polarity, unsigned long trigger) 601 unsigned long polarity, unsigned long trigger)
@@ -637,13 +646,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
637 iosapic_intr_info[irq].dmode = delivery; 646 iosapic_intr_info[irq].dmode = delivery;
638 iosapic_intr_info[irq].trigger = trigger; 647 iosapic_intr_info[irq].trigger = trigger;
639 648
640 if (trigger == IOSAPIC_EDGE) 649 irq_type = iosapic_get_irq_chip(trigger);
641 irq_type = &irq_type_iosapic_edge;
642 else
643 irq_type = &irq_type_iosapic_level;
644 650
645 idesc = irq_desc + irq; 651 idesc = irq_desc + irq;
646 if (idesc->chip != irq_type) { 652 if (irq_type != NULL && idesc->chip != irq_type) {
647 if (idesc->chip != &no_irq_type) 653 if (idesc->chip != &no_irq_type)
648 printk(KERN_WARNING 654 printk(KERN_WARNING
649 "%s: changing vector %d from %s to %s\n", 655 "%s: changing vector %d from %s to %s\n",
@@ -976,6 +982,22 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
976} 982}
977 983
978void __init 984void __init
985ia64_native_iosapic_pcat_compat_init(void)
986{
987 if (pcat_compat) {
988 /*
989 * Disable the compatibility mode interrupts (8259 style),
990 * needs IN/OUT support enabled.
991 */
992 printk(KERN_INFO
993 "%s: Disabling PC-AT compatible 8259 interrupts\n",
994 __func__);
995 outb(0xff, 0xA1);
996 outb(0xff, 0x21);
997 }
998}
999
1000void __init
979iosapic_system_init (int system_pcat_compat) 1001iosapic_system_init (int system_pcat_compat)
980{ 1002{
981 int irq; 1003 int irq;
@@ -989,17 +1011,8 @@ iosapic_system_init (int system_pcat_compat)
989 } 1011 }
990 1012
991 pcat_compat = system_pcat_compat; 1013 pcat_compat = system_pcat_compat;
992 if (pcat_compat) { 1014 if (pcat_compat)
993 /* 1015 iosapic_pcat_compat_init();
994 * Disable the compatibility mode interrupts (8259 style),
995 * needs IN/OUT support enabled.
996 */
997 printk(KERN_INFO
998 "%s: Disabling PC-AT compatible 8259 interrupts\n",
999 __func__);
1000 outb(0xff, 0xA1);
1001 outb(0xff, 0x21);
1002 }
1003} 1016}
1004 1017
1005static inline int 1018static inline int
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 5daf659ff291..65c211b2f985 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -312,3 +312,28 @@ paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
312 cpu_asm_switch->work_processed_syscall; 312 cpu_asm_switch->work_processed_syscall;
313 paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel; 313 paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
314} 314}
315
316/***************************************************************************
317 * pv_iosapic_ops
318 * iosapic read/write hooks.
319 */
320
321static unsigned int
322ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
323{
324 return __ia64_native_iosapic_read(iosapic, reg);
325}
326
327static void
328ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
329{
330 __ia64_native_iosapic_write(iosapic, reg, val);
331}
332
333struct pv_iosapic_ops pv_iosapic_ops = {
334 .pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
335 .get_irq_chip = ia64_native_iosapic_get_irq_chip,
336
337 .__read = ia64_native_iosapic_read,
338 .__write = ia64_native_iosapic_write,
339};
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
index a3a4288daae8..b9c102e15f22 100644
--- a/include/asm-ia64/iosapic.h
+++ b/include/asm-ia64/iosapic.h
@@ -55,13 +55,27 @@
55 55
56#define NR_IOSAPICS 256 56#define NR_IOSAPICS 256
57 57
58static inline unsigned int __iosapic_read(char __iomem *iosapic, unsigned int reg) 58#ifdef CONFIG_PARAVIRT_GUEST
59#include <asm/paravirt.h>
60#else
61#define iosapic_pcat_compat_init ia64_native_iosapic_pcat_compat_init
62#define __iosapic_read __ia64_native_iosapic_read
63#define __iosapic_write __ia64_native_iosapic_write
64#define iosapic_get_irq_chip ia64_native_iosapic_get_irq_chip
65#endif
66
67extern void __init ia64_native_iosapic_pcat_compat_init(void);
68extern struct irq_chip *ia64_native_iosapic_get_irq_chip(unsigned long trigger);
69
70static inline unsigned int
71__ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
59{ 72{
60 writel(reg, iosapic + IOSAPIC_REG_SELECT); 73 writel(reg, iosapic + IOSAPIC_REG_SELECT);
61 return readl(iosapic + IOSAPIC_WINDOW); 74 return readl(iosapic + IOSAPIC_WINDOW);
62} 75}
63 76
64static inline void __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) 77static inline void
78__ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
65{ 79{
66 writel(reg, iosapic + IOSAPIC_REG_SELECT); 80 writel(reg, iosapic + IOSAPIC_REG_SELECT);
67 writel(val, iosapic + IOSAPIC_WINDOW); 81 writel(val, iosapic + IOSAPIC_WINDOW);
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
index 84d74c32eb98..3a40f624e86e 100644
--- a/include/asm-ia64/paravirt.h
+++ b/include/asm-ia64/paravirt.h
@@ -112,6 +112,46 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void)
112 pv_init_ops.post_smp_prepare_boot_cpu(); 112 pv_init_ops.post_smp_prepare_boot_cpu();
113} 113}
114 114
115/******************************************************************************
116 * replacement of iosapic operations.
117 */
118
119struct pv_iosapic_ops {
120 void (*pcat_compat_init)(void);
121
122 struct irq_chip *(*get_irq_chip)(unsigned long trigger);
123
124 unsigned int (*__read)(char __iomem *iosapic, unsigned int reg);
125 void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val);
126};
127
128extern struct pv_iosapic_ops pv_iosapic_ops;
129
130static inline void
131iosapic_pcat_compat_init(void)
132{
133 if (pv_iosapic_ops.pcat_compat_init)
134 pv_iosapic_ops.pcat_compat_init();
135}
136
137static inline struct irq_chip*
138iosapic_get_irq_chip(unsigned long trigger)
139{
140 return pv_iosapic_ops.get_irq_chip(trigger);
141}
142
143static inline unsigned int
144__iosapic_read(char __iomem *iosapic, unsigned int reg)
145{
146 return pv_iosapic_ops.__read(iosapic, reg);
147}
148
149static inline void
150__iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
151{
152 return pv_iosapic_ops.__write(iosapic, reg, val);
153}
154
115#endif /* !__ASSEMBLY__ */ 155#endif /* !__ASSEMBLY__ */
116 156
117#else 157#else