]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/sysdev/mpic.c
Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / arch / powerpc / sysdev / mpic.c
index 0a13ecb270c7d0c30ac3ea2613bf7a4f76552f69..1be54faf60dd8be75f9f149101733c4c1c92f299 100644 (file)
 #define DBG(fmt...)
 #endif
 
+struct bus_type mpic_subsys = {
+       .name = "mpic",
+       .dev_name = "mpic",
+};
+EXPORT_SYMBOL_GPL(mpic_subsys);
+
 static struct mpic *mpics;
 static struct mpic *mpic_primary;
 static DEFINE_RAW_SPINLOCK(mpic_lock);
 
 #ifdef CONFIG_PPC32    /* XXX for now */
 #ifdef CONFIG_IRQ_ALL_CPUS
-#define distribute_irqs        (!(mpic->flags & MPIC_SINGLE_DEST_CPU))
+#define distribute_irqs        (1)
 #else
 #define distribute_irqs        (0)
 #endif
@@ -920,6 +926,22 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
        return IRQ_SET_MASK_OK_NOCOPY;
 }
 
+static int mpic_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+       struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
+       struct mpic *mpic = mpic_from_irq_data(d);
+
+       if (!(mpic->flags & MPIC_FSL))
+               return -ENXIO;
+
+       if (on)
+               desc->action->flags |= IRQF_NO_SUSPEND;
+       else
+               desc->action->flags &= ~IRQF_NO_SUSPEND;
+
+       return 0;
+}
+
 void mpic_set_vector(unsigned int virq, unsigned int vector)
 {
        struct mpic *mpic = mpic_from_irq(virq);
@@ -957,6 +979,7 @@ static struct irq_chip mpic_irq_chip = {
        .irq_unmask     = mpic_unmask_irq,
        .irq_eoi        = mpic_end_irq,
        .irq_set_type   = mpic_set_irq_type,
+       .irq_set_wake   = mpic_irq_set_wake,
 };
 
 #ifdef CONFIG_SMP
@@ -971,6 +994,7 @@ static struct irq_chip mpic_tm_chip = {
        .irq_mask       = mpic_mask_tm,
        .irq_unmask     = mpic_unmask_tm,
        .irq_eoi        = mpic_end_irq,
+       .irq_set_wake   = mpic_irq_set_wake,
 };
 
 #ifdef CONFIG_MPIC_U3_HT_IRQS
@@ -1173,10 +1197,33 @@ static struct irq_domain_ops mpic_host_ops = {
        .xlate = mpic_host_xlate,
 };
 
+static u32 fsl_mpic_get_version(struct mpic *mpic)
+{
+       u32 brr1;
+
+       if (!(mpic->flags & MPIC_FSL))
+               return 0;
+
+       brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+                       MPIC_FSL_BRR1);
+
+       return brr1 & MPIC_FSL_BRR1_VER;
+}
+
 /*
  * Exported functions
  */
 
+u32 fsl_mpic_primary_get_version(void)
+{
+       struct mpic *mpic = mpic_primary;
+
+       if (mpic)
+               return fsl_mpic_get_version(mpic);
+
+       return 0;
+}
+
 struct mpic * __init mpic_alloc(struct device_node *node,
                                phys_addr_t phys_addr,
                                unsigned int flags,
@@ -1323,7 +1370,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
        mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
 
        if (mpic->flags & MPIC_FSL) {
-               u32 brr1;
                int ret;
 
                /*
@@ -1334,9 +1380,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
                mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
                         MPIC_CPU_THISBASE, 0x1000);
 
-               brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-                               MPIC_FSL_BRR1);
-               fsl_version = brr1 & MPIC_FSL_BRR1_VER;
+               fsl_version = fsl_mpic_get_version(mpic);
 
                /* Error interrupt mask register (EIMR) is required for
                 * handling individual device error interrupts. EIMR
@@ -1526,9 +1570,7 @@ void __init mpic_init(struct mpic *mpic)
        mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
        if (mpic->flags & MPIC_FSL) {
-               u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-                                     MPIC_FSL_BRR1);
-               u32 version = brr1 & MPIC_FSL_BRR1_VER;
+               u32 version = fsl_mpic_get_version(mpic);
 
                /*
                 * Timer group B is present at the latest in MPIC 3.1 (e.g.
@@ -1703,7 +1745,7 @@ void mpic_setup_this_cpu(void)
         * it differently, then we should make sure we also change the default
         * values of irq_desc[].affinity in irq.c.
         */
-       if (distribute_irqs) {
+       if (distribute_irqs && !(mpic->flags & MPIC_SINGLE_DEST_CPU)) {
                for (i = 0; i < mpic->num_sources ; i++)
                        mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
                                mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
@@ -1999,6 +2041,8 @@ static struct syscore_ops mpic_syscore_ops = {
 static int mpic_init_sys(void)
 {
        register_syscore_ops(&mpic_syscore_ops);
+       subsys_system_register(&mpic_subsys, NULL);
+
        return 0;
 }