#ifdef __KERNEL__
#include <linux/irq.h>
+#include <linux/sysdev.h>
+#include <asm/dcr.h>
/*
* Global registers
#define MPIC_MAX_CPUS 32
#define MPIC_MAX_ISU 32
-/*
- * Special vector numbers (internal use only)
- */
-#define MPIC_VEC_SPURRIOUS 255
-#define MPIC_VEC_IPI_3 254
-#define MPIC_VEC_IPI_2 253
-#define MPIC_VEC_IPI_1 252
-#define MPIC_VEC_IPI_0 251
-
-/* unused */
-#define MPIC_VEC_TIMER_3 250
-#define MPIC_VEC_TIMER_2 249
-#define MPIC_VEC_TIMER_1 248
-#define MPIC_VEC_TIMER_0 247
-
/*
* Tsi108 implementation of MPIC has many differences from the original one
*/
};
-#ifdef CONFIG_MPIC_BROKEN_U3
+#ifdef CONFIG_MPIC_U3_HT_IRQS
/* Fixup table entry */
struct mpic_irq_fixup
{
u32 data;
unsigned int index;
};
-#endif /* CONFIG_MPIC_BROKEN_U3 */
+#endif /* CONFIG_MPIC_U3_HT_IRQS */
+
+
+enum mpic_reg_type {
+ mpic_access_mmio_le,
+ mpic_access_mmio_be,
+#ifdef CONFIG_PPC_DCR
+ mpic_access_dcr
+#endif
+};
+
+struct mpic_reg_bank {
+ u32 __iomem *base;
+#ifdef CONFIG_PPC_DCR
+ dcr_host_t dhost;
+#endif /* CONFIG_PPC_DCR */
+};
+struct mpic_irq_save {
+ u32 vecprio,
+ dest;
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+ u32 fixup_data;
+#endif
+};
/* The instance data of a given MPIC */
struct mpic
{
- /* The device node of the interrupt controller */
- struct device_node *of_node;
-
/* The remapper for this MPIC */
struct irq_host *irqhost;
/* The "linux" controller struct */
struct irq_chip hc_irq;
-#ifdef CONFIG_MPIC_BROKEN_U3
+#ifdef CONFIG_MPIC_U3_HT_IRQS
struct irq_chip hc_ht_irq;
#endif
#ifdef CONFIG_SMP
unsigned char *senses;
unsigned int senses_count;
-#ifdef CONFIG_MPIC_BROKEN_U3
+ /* vector numbers used for internal sources (ipi/timers) */
+ unsigned int ipi_vecs[4];
+ unsigned int timer_vecs[4];
+
+ /* Spurious vector to program into unused sources */
+ unsigned int spurious_vec;
+
+#ifdef CONFIG_MPIC_U3_HT_IRQS
/* The fixup table */
struct mpic_irq_fixup *fixups;
spinlock_t fixup_lock;
#endif
+ /* Register access method */
+ enum mpic_reg_type reg_type;
+
/* The various ioremap'ed bases */
- volatile u32 __iomem *gregs;
- volatile u32 __iomem *tmregs;
- volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS];
- volatile u32 __iomem *isus[MPIC_MAX_ISU];
+ struct mpic_reg_bank gregs;
+ struct mpic_reg_bank tmregs;
+ struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS];
+ struct mpic_reg_bank isus[MPIC_MAX_ISU];
+
+ /* Protected sources */
+ unsigned long *protected;
#ifdef CONFIG_MPIC_WEIRD
/* Pointer to HW info array */
u32 *hw_set;
#endif
+#ifdef CONFIG_PCI_MSI
+ spinlock_t bitmap_lock;
+ unsigned long *hwirq_bitmap;
+#endif
+
+#ifdef CONFIG_MPIC_BROKEN_REGREAD
+ u32 isu_reg0_shadow[MPIC_MAX_IRQ_SOURCES];
+#endif
+
/* link */
struct mpic *next;
+
+ struct sys_device sysdev;
+
+#ifdef CONFIG_PM
+ struct mpic_irq_save *save_data;
+#endif
};
/*
/* Set this for a big-endian MPIC */
#define MPIC_BIG_ENDIAN 0x00000002
/* Broken U3 MPIC */
-#define MPIC_BROKEN_U3 0x00000004
+#define MPIC_U3_HT_IRQS 0x00000004
/* Broken IPI registers (autodetected) */
#define MPIC_BROKEN_IPI 0x00000008
/* MPIC wants a reset */
#define MPIC_SPV_EOI 0x00000020
/* No passthrough disable */
#define MPIC_NO_PTHROU_DIS 0x00000040
+/* DCR based MPIC */
+#define MPIC_USES_DCR 0x00000080
+/* MPIC has 11-bit vector fields (or larger) */
+#define MPIC_LARGE_VECTORS 0x00000100
/* MPIC HW modification ID */
#define MPIC_REGSET_MASK 0xf0000000
* @senses_num: number of entries in the array
*
* Note about the sense array. If none is passed, all interrupts are
- * setup to be level negative unless MPIC_BROKEN_U3 is set in which
+ * setup to be level negative unless MPIC_U3_HT_IRQS is set in which
* case they are edge positive (and the array is ignored anyway).
* The values in the array start at the first source of the MPIC,
* that is senses[0] correspond to linux irq "irq_offset".
*/
extern struct mpic *mpic_alloc(struct device_node *node,
- unsigned long phys_addr,
+ phys_addr_t phys_addr,
unsigned int flags,
unsigned int isu_size,
unsigned int irq_count,
* @phys_addr: physical address of the ISU
*/
extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
- unsigned long phys_addr);
+ phys_addr_t phys_addr);
/* Set default sense codes
*