aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@macmini.osdl.org>2006-11-01 09:11:00 -0800
committerLinus Torvalds <torvalds@macmini.osdl.org>2006-11-01 09:11:00 -0800
commit130fe05dbc0114609cfef9815c0c5580b42decfa (patch)
tree1af977ef76bb369bfb5009c30bde7c495591bc98
parent4b1c46a383aafc137bc91a0f9698bfc11e062d1b (diff)
i386: clean up io-apic accesses
This is preparation for fixing the ordering of the accesses that got broken by the commit cf4c6a2f27f5db810b69dcb1da7f194489e8ff88 when factoring out the "common" io apic routing entry accesses. Move the accessor function (that were only used by io_apic.c) out of a header file, and use proper memory-mapped accesses rather than making up our own "volatile" pointers. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/io_apic.c40
-rw-r--r--include/asm-i386/io_apic.h29
2 files changed, 41 insertions, 28 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 350192d6ab9..eb10bd5da64 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -91,6 +91,46 @@ static struct irq_pin_list {
int apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
+struct io_apic {
+ unsigned int index;
+ unsigned int unused[3];
+ unsigned int data;
+};
+
+static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
+{
+ return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
+ + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);
+}
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+ struct io_apic __iomem *io_apic = io_apic_base(apic);
+ writel(reg, &io_apic->index);
+ return readl(&io_apic->data);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+ struct io_apic __iomem *io_apic = io_apic_base(apic);
+ writel(reg, &io_apic->index);
+ writel(value, &io_apic->data);
+}
+
+/*
+ * Re-write a value: to be used for read-modify-write
+ * cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index register
+ */
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
+{
+ volatile struct io_apic *io_apic = io_apic_base(apic);
+ if (sis_apic_bug)
+ writel(reg, &io_apic->index);
+ writel(value, &io_apic->data);
+}
+
union entry_union {
struct { u32 w1, w2; };
struct IO_APIC_route_entry entry;
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index 276ea7e8144..059a9ff28b4 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -12,10 +12,6 @@
#ifdef CONFIG_X86_IO_APIC
-#define IO_APIC_BASE(idx) \
- ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
- + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
-
/*
* The structure of the IO-APIC:
*/
@@ -119,31 +115,8 @@ extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* non-0 if default (table-less) MP configuration */
extern int mpc_default_type;
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
- *IO_APIC_BASE(apic) = reg;
- return *(IO_APIC_BASE(apic)+4);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
- *IO_APIC_BASE(apic) = reg;
- *(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index regiser
- */
+/* Older SiS APIC requires we rewrite the index register */
extern int sis_apic_bug;
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
- if (sis_apic_bug)
- *IO_APIC_BASE(apic) = reg;
- *(IO_APIC_BASE(apic)+4) = value;
-}
/* 1 if "noapic" boot option passed */
extern int skip_ioapic_setup;