@@ -171,7 +171,7 @@ static struct irq_chip iproc_msi_irq_chip = {
171
171
172
172
static struct msi_domain_info iproc_msi_domain_info = {
173
173
.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
174
- MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX ,
174
+ MSI_FLAG_PCI_MSIX ,
175
175
.chip = & iproc_msi_irq_chip ,
176
176
};
177
177
@@ -250,20 +250,23 @@ static int iproc_msi_irq_domain_alloc(struct irq_domain *domain,
250
250
struct iproc_msi * msi = domain -> host_data ;
251
251
int hwirq , i ;
252
252
253
+ if (msi -> nr_cpus > 1 && nr_irqs > 1 )
254
+ return - EINVAL ;
255
+
253
256
mutex_lock (& msi -> bitmap_lock );
254
257
255
- /* Allocate 'nr_cpus' number of MSI vectors each time */
256
- hwirq = bitmap_find_next_zero_area (msi -> bitmap , msi -> nr_msi_vecs , 0 ,
257
- msi -> nr_cpus , 0 );
258
- if (hwirq < msi -> nr_msi_vecs ) {
259
- bitmap_set (msi -> bitmap , hwirq , msi -> nr_cpus );
260
- } else {
261
- mutex_unlock (& msi -> bitmap_lock );
262
- return - ENOSPC ;
263
- }
258
+ /*
259
+ * Allocate 'nr_irqs' multiplied by 'nr_cpus' number of MSI vectors
260
+ * each time
261
+ */
262
+ hwirq = bitmap_find_free_region (msi -> bitmap , msi -> nr_msi_vecs ,
263
+ order_base_2 (msi -> nr_cpus * nr_irqs ));
264
264
265
265
mutex_unlock (& msi -> bitmap_lock );
266
266
267
+ if (hwirq < 0 )
268
+ return - ENOSPC ;
269
+
267
270
for (i = 0 ; i < nr_irqs ; i ++ ) {
268
271
irq_domain_set_info (domain , virq + i , hwirq + i ,
269
272
& iproc_msi_bottom_irq_chip ,
@@ -284,7 +287,8 @@ static void iproc_msi_irq_domain_free(struct irq_domain *domain,
284
287
mutex_lock (& msi -> bitmap_lock );
285
288
286
289
hwirq = hwirq_to_canonical_hwirq (msi , data -> hwirq );
287
- bitmap_clear (msi -> bitmap , hwirq , msi -> nr_cpus );
290
+ bitmap_release_region (msi -> bitmap , hwirq ,
291
+ order_base_2 (msi -> nr_cpus * nr_irqs ));
288
292
289
293
mutex_unlock (& msi -> bitmap_lock );
290
294
@@ -539,6 +543,9 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node)
539
543
mutex_init (& msi -> bitmap_lock );
540
544
msi -> nr_cpus = num_possible_cpus ();
541
545
546
+ if (msi -> nr_cpus == 1 )
547
+ iproc_msi_domain_info .flags |= MSI_FLAG_MULTI_PCI_MSI ;
548
+
542
549
msi -> nr_irqs = of_irq_count (node );
543
550
if (!msi -> nr_irqs ) {
544
551
dev_err (pcie -> dev , "found no MSI GIC interrupt\n" );
0 commit comments