1313 * warranty of any kind, whether express or implied.
1414 */
1515
16+ #include <linux/bits.h>
1617#include <linux/kernel.h>
1718#include <linux/module.h>
1819#include <linux/init.h>
136137
137138#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28)
138139
140+ /* IPI and MSI interrupt definitions for IPI platforms */
139141#define IPI_DOORBELL_START (0)
140142#define IPI_DOORBELL_END (8)
141143#define IPI_DOORBELL_MASK 0xFF
144146#define PCI_MSI_DOORBELL_END (32)
145147#define PCI_MSI_DOORBELL_MASK 0xFFFF0000
146148
149+ /* MSI interrupt definitions for non-IPI platforms */
150+ #define PCI_MSI_FULL_DOORBELL_START 0
151+ #define PCI_MSI_FULL_DOORBELL_NR 32
152+ #define PCI_MSI_FULL_DOORBELL_END 32
153+ #define PCI_MSI_FULL_DOORBELL_MASK GENMASK(31, 0)
154+ #define PCI_MSI_FULL_DOORBELL_SRC0_MASK GENMASK(15, 0)
155+ #define PCI_MSI_FULL_DOORBELL_SRC1_MASK GENMASK(31, 16)
156+
147157static void __iomem * per_cpu_int_base ;
148158static void __iomem * main_int_base ;
149159static struct irq_domain * armada_370_xp_mpic_domain ;
@@ -152,7 +162,7 @@ static int parent_irq;
152162#ifdef CONFIG_PCI_MSI
153163static struct irq_domain * armada_370_xp_msi_domain ;
154164static struct irq_domain * armada_370_xp_msi_inner_domain ;
155- static DECLARE_BITMAP (msi_used , PCI_MSI_DOORBELL_NR ) ;
165+ static DECLARE_BITMAP (msi_used , PCI_MSI_FULL_DOORBELL_NR ) ;
156166static DEFINE_MUTEX (msi_used_lock );
157167static phys_addr_t msi_doorbell_addr ;
158168#endif
@@ -168,6 +178,30 @@ static inline bool is_ipi_available(void)
168178 return parent_irq <= 0 ;
169179}
170180
181+ static inline u32 msi_doorbell_mask (void )
182+ {
183+ return is_ipi_available () ? PCI_MSI_DOORBELL_MASK :
184+ PCI_MSI_FULL_DOORBELL_MASK ;
185+ }
186+
187+ static inline unsigned int msi_doorbell_start (void )
188+ {
189+ return is_ipi_available () ? PCI_MSI_DOORBELL_START :
190+ PCI_MSI_FULL_DOORBELL_START ;
191+ }
192+
193+ static inline unsigned int msi_doorbell_size (void )
194+ {
195+ return is_ipi_available () ? PCI_MSI_DOORBELL_NR :
196+ PCI_MSI_FULL_DOORBELL_NR ;
197+ }
198+
199+ static inline unsigned int msi_doorbell_end (void )
200+ {
201+ return is_ipi_available () ? PCI_MSI_DOORBELL_END :
202+ PCI_MSI_FULL_DOORBELL_END ;
203+ }
204+
171205static inline bool is_percpu_irq (irq_hw_number_t irq )
172206{
173207 if (irq <= ARMADA_370_XP_MAX_PER_CPU_IRQS )
@@ -225,7 +259,7 @@ static void armada_370_xp_compose_msi_msg(struct irq_data *data, struct msi_msg
225259
226260 msg -> address_lo = lower_32_bits (msi_doorbell_addr );
227261 msg -> address_hi = upper_32_bits (msi_doorbell_addr );
228- msg -> data = BIT (cpu + 8 ) | (data -> hwirq + PCI_MSI_DOORBELL_START );
262+ msg -> data = BIT (cpu + 8 ) | (data -> hwirq + msi_doorbell_start () );
229263}
230264
231265static int armada_370_xp_msi_set_affinity (struct irq_data * irq_data ,
@@ -258,7 +292,7 @@ static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
258292 int hwirq , i ;
259293
260294 mutex_lock (& msi_used_lock );
261- hwirq = bitmap_find_free_region (msi_used , PCI_MSI_DOORBELL_NR ,
295+ hwirq = bitmap_find_free_region (msi_used , msi_doorbell_size () ,
262296 order_base_2 (nr_irqs ));
263297 mutex_unlock (& msi_used_lock );
264298
@@ -295,9 +329,10 @@ static void armada_370_xp_msi_reenable_percpu(void)
295329 u32 reg ;
296330
297331 /* Enable MSI doorbell mask and combined cpu local interrupt */
298- reg = readl (per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS )
299- | PCI_MSI_DOORBELL_MASK ;
332+ reg = readl (per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS );
333+ reg |= msi_doorbell_mask () ;
300334 writel (reg , per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS );
335+
301336 /* Unmask local doorbell interrupt */
302337 writel (1 , per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS );
303338}
@@ -309,7 +344,7 @@ static int armada_370_xp_msi_init(struct device_node *node,
309344 ARMADA_370_XP_SW_TRIG_INT_OFFS ;
310345
311346 armada_370_xp_msi_inner_domain =
312- irq_domain_add_linear (NULL , PCI_MSI_DOORBELL_NR ,
347+ irq_domain_add_linear (NULL , msi_doorbell_size () ,
313348 & armada_370_xp_msi_domain_ops , NULL );
314349 if (!armada_370_xp_msi_inner_domain )
315350 return - ENOMEM ;
@@ -325,6 +360,10 @@ static int armada_370_xp_msi_init(struct device_node *node,
325360
326361 armada_370_xp_msi_reenable_percpu ();
327362
363+ /* Unmask low 16 MSI irqs on non-IPI platforms */
364+ if (!is_ipi_available ())
365+ writel (0 , per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS );
366+
328367 return 0 ;
329368}
330369#else
@@ -613,20 +652,20 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
613652 u32 msimask , msinr ;
614653
615654 msimask = readl_relaxed (per_cpu_int_base +
616- ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS )
617- & PCI_MSI_DOORBELL_MASK ;
655+ ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS );
656+ msimask &= msi_doorbell_mask () ;
618657
619658 writel (~msimask , per_cpu_int_base +
620659 ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS );
621660
622- for (msinr = PCI_MSI_DOORBELL_START ;
623- msinr < PCI_MSI_DOORBELL_END ; msinr ++ ) {
661+ for (msinr = msi_doorbell_start () ;
662+ msinr < msi_doorbell_end () ; msinr ++ ) {
624663 unsigned int irq ;
625664
626665 if (!(msimask & BIT (msinr )))
627666 continue ;
628667
629- irq = msinr - PCI_MSI_DOORBELL_START ;
668+ irq = msinr - msi_doorbell_start () ;
630669
631670 generic_handle_domain_irq (armada_370_xp_msi_inner_domain , irq );
632671 }
@@ -655,7 +694,7 @@ static void armada_370_xp_mpic_handle_cascade_irq(struct irq_desc *desc)
655694 if (!(irqsrc & ARMADA_370_XP_INT_IRQ_FIQ_MASK (cpuid )))
656695 continue ;
657696
658- if (irqn == 1 ) {
697+ if (irqn == 0 || irqn == 1 ) {
659698 armada_370_xp_handle_msi_irq (NULL , true);
660699 continue ;
661700 }
@@ -716,6 +755,7 @@ static int armada_370_xp_mpic_suspend(void)
716755
717756static void armada_370_xp_mpic_resume (void )
718757{
758+ bool src0 , src1 ;
719759 int nirqs ;
720760 irq_hw_number_t irq ;
721761
@@ -755,9 +795,18 @@ static void armada_370_xp_mpic_resume(void)
755795 /* Reconfigure doorbells for IPIs and MSIs */
756796 writel (doorbell_mask_reg ,
757797 per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS );
758- if (is_ipi_available () && (doorbell_mask_reg & IPI_DOORBELL_MASK ))
798+
799+ if (is_ipi_available ()) {
800+ src0 = doorbell_mask_reg & IPI_DOORBELL_MASK ;
801+ src1 = doorbell_mask_reg & PCI_MSI_DOORBELL_MASK ;
802+ } else {
803+ src0 = doorbell_mask_reg & PCI_MSI_FULL_DOORBELL_SRC0_MASK ;
804+ src1 = doorbell_mask_reg & PCI_MSI_FULL_DOORBELL_SRC1_MASK ;
805+ }
806+
807+ if (src0 )
759808 writel (0 , per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS );
760- if (doorbell_mask_reg & PCI_MSI_DOORBELL_MASK )
809+ if (src1 )
761810 writel (1 , per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS );
762811
763812 if (is_ipi_available ())
0 commit comments