13
13
* warranty of any kind, whether express or implied.
14
14
*/
15
15
16
+ #include <linux/bits.h>
16
17
#include <linux/kernel.h>
17
18
#include <linux/module.h>
18
19
#include <linux/init.h>
136
137
137
138
#define ARMADA_370_XP_MAX_PER_CPU_IRQS (28)
138
139
140
+ /* IPI and MSI interrupt definitions for IPI platforms */
139
141
#define IPI_DOORBELL_START (0)
140
142
#define IPI_DOORBELL_END (8)
141
143
#define IPI_DOORBELL_MASK 0xFF
144
146
#define PCI_MSI_DOORBELL_END (32)
145
147
#define PCI_MSI_DOORBELL_MASK 0xFFFF0000
146
148
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
+
147
157
static void __iomem * per_cpu_int_base ;
148
158
static void __iomem * main_int_base ;
149
159
static struct irq_domain * armada_370_xp_mpic_domain ;
@@ -152,7 +162,7 @@ static int parent_irq;
152
162
#ifdef CONFIG_PCI_MSI
153
163
static struct irq_domain * armada_370_xp_msi_domain ;
154
164
static 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 ) ;
156
166
static DEFINE_MUTEX (msi_used_lock );
157
167
static phys_addr_t msi_doorbell_addr ;
158
168
#endif
@@ -168,6 +178,30 @@ static inline bool is_ipi_available(void)
168
178
return parent_irq <= 0 ;
169
179
}
170
180
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
+
171
205
static inline bool is_percpu_irq (irq_hw_number_t irq )
172
206
{
173
207
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
225
259
226
260
msg -> address_lo = lower_32_bits (msi_doorbell_addr );
227
261
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 () );
229
263
}
230
264
231
265
static 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,
258
292
int hwirq , i ;
259
293
260
294
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 () ,
262
296
order_base_2 (nr_irqs ));
263
297
mutex_unlock (& msi_used_lock );
264
298
@@ -295,9 +329,10 @@ static void armada_370_xp_msi_reenable_percpu(void)
295
329
u32 reg ;
296
330
297
331
/* 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 () ;
300
334
writel (reg , per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS );
335
+
301
336
/* Unmask local doorbell interrupt */
302
337
writel (1 , per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS );
303
338
}
@@ -309,7 +344,7 @@ static int armada_370_xp_msi_init(struct device_node *node,
309
344
ARMADA_370_XP_SW_TRIG_INT_OFFS ;
310
345
311
346
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 () ,
313
348
& armada_370_xp_msi_domain_ops , NULL );
314
349
if (!armada_370_xp_msi_inner_domain )
315
350
return - ENOMEM ;
@@ -325,6 +360,10 @@ static int armada_370_xp_msi_init(struct device_node *node,
325
360
326
361
armada_370_xp_msi_reenable_percpu ();
327
362
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
+
328
367
return 0 ;
329
368
}
330
369
#else
@@ -613,20 +652,20 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
613
652
u32 msimask , msinr ;
614
653
615
654
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 () ;
618
657
619
658
writel (~msimask , per_cpu_int_base +
620
659
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS );
621
660
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 ++ ) {
624
663
unsigned int irq ;
625
664
626
665
if (!(msimask & BIT (msinr )))
627
666
continue ;
628
667
629
- irq = msinr - PCI_MSI_DOORBELL_START ;
668
+ irq = msinr - msi_doorbell_start () ;
630
669
631
670
generic_handle_domain_irq (armada_370_xp_msi_inner_domain , irq );
632
671
}
@@ -655,7 +694,7 @@ static void armada_370_xp_mpic_handle_cascade_irq(struct irq_desc *desc)
655
694
if (!(irqsrc & ARMADA_370_XP_INT_IRQ_FIQ_MASK (cpuid )))
656
695
continue ;
657
696
658
- if (irqn == 1 ) {
697
+ if (irqn == 0 || irqn == 1 ) {
659
698
armada_370_xp_handle_msi_irq (NULL , true);
660
699
continue ;
661
700
}
@@ -716,6 +755,7 @@ static int armada_370_xp_mpic_suspend(void)
716
755
717
756
static void armada_370_xp_mpic_resume (void )
718
757
{
758
+ bool src0 , src1 ;
719
759
int nirqs ;
720
760
irq_hw_number_t irq ;
721
761
@@ -755,9 +795,18 @@ static void armada_370_xp_mpic_resume(void)
755
795
/* Reconfigure doorbells for IPIs and MSIs */
756
796
writel (doorbell_mask_reg ,
757
797
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 )
759
808
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 )
761
810
writel (1 , per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS );
762
811
763
812
if (is_ipi_available ())
0 commit comments