hc
2024-05-10 ee930fffee469d076998274a2ca55e13dc1efb67
kernel/drivers/parisc/dino.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 ** DINO manager
34 **
....@@ -5,12 +6,8 @@
56 ** (c) Copyright 1999 SuSE GmbH
67 ** (c) Copyright 1999,2000 Hewlett-Packard Company
78 ** (c) Copyright 2000 Grant Grundler
8
-** (c) Copyright 2006 Helge Deller
9
+** (c) Copyright 2006-2019 Helge Deller
910 **
10
-** This program is free software; you can redistribute it and/or modify
11
-** it under the terms of the GNU General Public License as published by
12
-** the Free Software Foundation; either version 2 of the License, or
13
-** (at your option) any later version.
1411 **
1512 ** This module provides access to Dino PCI bus (config/IOport spaces)
1613 ** and helps manage Dino IRQ lines.
....@@ -59,6 +56,7 @@
5956 #include <asm/hardware.h>
6057
6158 #include "gsc.h"
59
+#include "iommu.h"
6260
6361 #undef DINO_DEBUG
6462
....@@ -144,21 +142,18 @@
144142 {
145143 struct pci_hba_data hba; /* 'C' inheritance - must be first */
146144 spinlock_t dinosaur_pen;
147
- unsigned long txn_addr; /* EIR addr to generate interrupt */
148
- u32 txn_data; /* EIR data assign to each dino */
149145 u32 imr; /* IRQ's which are enabled */
146
+ struct gsc_irq gsc_irq;
150147 int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */
151148 #ifdef DINO_DEBUG
152149 unsigned int dino_irr0; /* save most recent IRQ line stat */
153150 #endif
154151 };
155152
156
-/* Looks nice and keeps the compiler happy */
157
-#define DINO_DEV(d) ({ \
158
- void *__pdata = d; \
159
- BUG_ON(!__pdata); \
160
- (struct dino_device *)__pdata; })
161
-
153
+static inline struct dino_device *DINO_DEV(struct pci_hba_data *hba)
154
+{
155
+ return container_of(hba, struct dino_device, hba);
156
+}
162157
163158 /*
164159 * Dino Configuration Space Accessor Functions
....@@ -343,14 +338,43 @@
343338 if (tmp & DINO_MASK_IRQ(local_irq)) {
344339 DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n",
345340 __func__, tmp);
346
- gsc_writel(dino_dev->txn_data, dino_dev->txn_addr);
341
+ gsc_writel(dino_dev->gsc_irq.txn_data, dino_dev->gsc_irq.txn_addr);
347342 }
348343 }
344
+
345
+#ifdef CONFIG_SMP
346
+static int dino_set_affinity_irq(struct irq_data *d, const struct cpumask *dest,
347
+ bool force)
348
+{
349
+ struct dino_device *dino_dev = irq_data_get_irq_chip_data(d);
350
+ struct cpumask tmask;
351
+ int cpu_irq;
352
+ u32 eim;
353
+
354
+ if (!cpumask_and(&tmask, dest, cpu_online_mask))
355
+ return -EINVAL;
356
+
357
+ cpu_irq = cpu_check_affinity(d, &tmask);
358
+ if (cpu_irq < 0)
359
+ return cpu_irq;
360
+
361
+ dino_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq);
362
+ eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data;
363
+ __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
364
+
365
+ irq_data_update_effective_affinity(d, &tmask);
366
+
367
+ return IRQ_SET_MASK_OK;
368
+}
369
+#endif
349370
350371 static struct irq_chip dino_interrupt_type = {
351372 .name = "GSC-PCI",
352373 .irq_unmask = dino_unmask_irq,
353374 .irq_mask = dino_mask_irq,
375
+#ifdef CONFIG_SMP
376
+ .irq_set_affinity = dino_set_affinity_irq,
377
+#endif
354378 };
355379
356380
....@@ -382,7 +406,7 @@
382406 DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n",
383407 __func__, irq, intr_dev, mask);
384408 generic_handle_irq(irq);
385
- mask &= ~(1 << local_irq);
409
+ mask &= ~DINO_MASK_IRQ(local_irq);
386410 } while (mask);
387411
388412 /* Support for level triggered IRQ lines.
....@@ -396,9 +420,8 @@
396420 if (mask) {
397421 if (--ilr_loop > 0)
398422 goto ilr_again;
399
- printk(KERN_ERR "Dino 0x%px: stuck interrupt %d\n",
423
+ pr_warn_ratelimited("Dino 0x%px: stuck interrupt %d\n",
400424 dino_dev->hba.base_addr, mask);
401
- return IRQ_NONE;
402425 }
403426 return IRQ_HANDLED;
404427 }
....@@ -811,7 +834,6 @@
811834 {
812835 int status;
813836 u32 eim;
814
- struct gsc_irq gsc_irq;
815837 struct resource *res;
816838
817839 pcibios_register_hba(&dino_dev->hba);
....@@ -826,10 +848,8 @@
826848 ** still only has 11 IRQ input lines - just map some of them
827849 ** to a different processor.
828850 */
829
- dev->irq = gsc_alloc_irq(&gsc_irq);
830
- dino_dev->txn_addr = gsc_irq.txn_addr;
831
- dino_dev->txn_data = gsc_irq.txn_data;
832
- eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
851
+ dev->irq = gsc_alloc_irq(&dino_dev->gsc_irq);
852
+ eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data;
833853
834854 /*
835855 ** Dino needs a PA "IRQ" to get a processor's attention.
....@@ -892,14 +912,14 @@
892912 #define CUJO_RAVEN_BADPAGE 0x01003000UL
893913 #define CUJO_FIREHAWK_BADPAGE 0x01607000UL
894914
895
-static const char *dino_vers[] = {
915
+static const char dino_vers[][4] = {
896916 "2.0",
897917 "2.1",
898918 "3.0",
899919 "3.1"
900920 };
901921
902
-static const char *cujo_vers[] = {
922
+static const char cujo_vers[][4] = {
903923 "1.0",
904924 "2.0"
905925 };
....@@ -979,7 +999,7 @@
979999 }
9801000
9811001 dino_dev->hba.dev = dev;
982
- dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096);
1002
+ dino_dev->hba.base_addr = ioremap(hpa, 4096);
9831003 dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND;
9841004 spin_lock_init(&dino_dev->dinosaur_pen);
9851005 dino_dev->hba.iommu = ccio_get_iommu(dev);