aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-07-23 13:43:45 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-08-05 08:26:10 -0400
commita894f14d7ebe9e278b496b1e653ae57f2eff514e (patch)
treeadf5e2caef5ec79c7256d50d6a7f3fdff94e8d15 /arch
parentcb8f55b9207df96ccc332748eb3d154cd2e8014f (diff)
MIPS: Octeon: Move MSI code out of octeon-irq.c.
Put all the MSI code in one place (msi-octeon.c). This simplifies octeon-irq.c and gets rid of some ugly #ifdefs Signed-off-by: David Daney <ddaney@caviumnetworks.com> To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/1484/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c93
-rw-r--r--arch/mips/pci/msi-octeon.c90
2 files changed, 88 insertions, 95 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index c424cd158dc6..f4b901aaf509 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -10,8 +10,6 @@
10#include <linux/smp.h> 10#include <linux/smp.h>
11 11
12#include <asm/octeon/octeon.h> 12#include <asm/octeon/octeon.h>
13#include <asm/octeon/cvmx-pexp-defs.h>
14#include <asm/octeon/cvmx-npi-defs.h>
15 13
16static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); 14static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
17static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock); 15static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
@@ -528,90 +526,6 @@ static struct irq_chip octeon_irq_chip_ciu1 = {
528#endif 526#endif
529}; 527};
530 528
531#ifdef CONFIG_PCI_MSI
532
533static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
534
535static void octeon_irq_msi_ack(unsigned int irq)
536{
537 if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
538 /* These chips have PCI */
539 cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
540 1ull << (irq - OCTEON_IRQ_MSI_BIT0));
541 } else {
542 /*
543 * These chips have PCIe. Thankfully the ACK doesn't
544 * need any locking.
545 */
546 cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
547 1ull << (irq - OCTEON_IRQ_MSI_BIT0));
548 }
549}
550
551static void octeon_irq_msi_eoi(unsigned int irq)
552{
553 /* Nothing needed */
554}
555
556static void octeon_irq_msi_enable(unsigned int irq)
557{
558 if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
559 /*
560 * Octeon PCI doesn't have the ability to mask/unmask
561 * MSI interrupts individually. Instead of
562 * masking/unmasking them in groups of 16, we simple
563 * assume MSI devices are well behaved. MSI
564 * interrupts are always enable and the ACK is assumed
565 * to be enough.
566 */
567 } else {
568 /* These chips have PCIe. Note that we only support
569 * the first 64 MSI interrupts. Unfortunately all the
570 * MSI enables are in the same register. We use
571 * MSI0's lock to control access to them all.
572 */
573 uint64_t en;
574 unsigned long flags;
575 raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
576 en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
577 en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
578 cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
579 cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
580 raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
581 }
582}
583
584static void octeon_irq_msi_disable(unsigned int irq)
585{
586 if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
587 /* See comment in enable */
588 } else {
589 /*
590 * These chips have PCIe. Note that we only support
591 * the first 64 MSI interrupts. Unfortunately all the
592 * MSI enables are in the same register. We use
593 * MSI0's lock to control access to them all.
594 */
595 uint64_t en;
596 unsigned long flags;
597 raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
598 en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
599 en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
600 cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
601 cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
602 raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
603 }
604}
605
606static struct irq_chip octeon_irq_chip_msi = {
607 .name = "MSI",
608 .enable = octeon_irq_msi_enable,
609 .disable = octeon_irq_msi_disable,
610 .ack = octeon_irq_msi_ack,
611 .eoi = octeon_irq_msi_eoi,
612};
613#endif
614
615void __init arch_init_irq(void) 529void __init arch_init_irq(void)
616{ 530{
617 int irq; 531 int irq;
@@ -672,13 +586,6 @@ void __init arch_init_irq(void)
672 set_irq_chip_and_handler(irq, chip1, handle_percpu_irq); 586 set_irq_chip_and_handler(irq, chip1, handle_percpu_irq);
673 } 587 }
674 588
675#ifdef CONFIG_PCI_MSI
676 /* 152 - 215 PCI/PCIe MSI interrupts */
677 for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
678 set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
679 handle_percpu_irq);
680 }
681#endif
682 set_c0_status(0x300 << 2); 589 set_c0_status(0x300 << 2);
683} 590}
684 591
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index 03742e647657..1e31526f0e53 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -249,12 +249,99 @@ static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id)
249 return IRQ_NONE; 249 return IRQ_NONE;
250} 250}
251 251
252static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
253
254static void octeon_irq_msi_ack(unsigned int irq)
255{
256 if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
257 /* These chips have PCI */
258 cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
259 1ull << (irq - OCTEON_IRQ_MSI_BIT0));
260 } else {
261 /*
262 * These chips have PCIe. Thankfully the ACK doesn't
263 * need any locking.
264 */
265 cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
266 1ull << (irq - OCTEON_IRQ_MSI_BIT0));
267 }
268}
269
270static void octeon_irq_msi_eoi(unsigned int irq)
271{
272 /* Nothing needed */
273}
274
275static void octeon_irq_msi_enable(unsigned int irq)
276{
277 if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
278 /*
279 * Octeon PCI doesn't have the ability to mask/unmask
280 * MSI interrupts individually. Instead of
281 * masking/unmasking them in groups of 16, we simple
282 * assume MSI devices are well behaved. MSI
283 * interrupts are always enable and the ACK is assumed
284 * to be enough.
285 */
286 } else {
287 /* These chips have PCIe. Note that we only support
288 * the first 64 MSI interrupts. Unfortunately all the
289 * MSI enables are in the same register. We use
290 * MSI0's lock to control access to them all.
291 */
292 uint64_t en;
293 unsigned long flags;
294 raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
295 en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
296 en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
297 cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
298 cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
299 raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
300 }
301}
302
303static void octeon_irq_msi_disable(unsigned int irq)
304{
305 if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
306 /* See comment in enable */
307 } else {
308 /*
309 * These chips have PCIe. Note that we only support
310 * the first 64 MSI interrupts. Unfortunately all the
311 * MSI enables are in the same register. We use
312 * MSI0's lock to control access to them all.
313 */
314 uint64_t en;
315 unsigned long flags;
316 raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
317 en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
318 en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
319 cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
320 cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
321 raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
322 }
323}
324
325static struct irq_chip octeon_irq_chip_msi = {
326 .name = "MSI",
327 .enable = octeon_irq_msi_enable,
328 .disable = octeon_irq_msi_disable,
329 .ack = octeon_irq_msi_ack,
330 .eoi = octeon_irq_msi_eoi,
331};
252 332
253/* 333/*
254 * Initializes the MSI interrupt handling code 334 * Initializes the MSI interrupt handling code
255 */ 335 */
256int octeon_msi_initialize(void) 336static int __init octeon_msi_initialize(void)
257{ 337{
338 int irq;
339
340 for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
341 set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
342 handle_percpu_irq);
343 }
344
258 if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { 345 if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
259 if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, 346 if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
260 IRQF_SHARED, 347 IRQF_SHARED,
@@ -284,5 +371,4 @@ int octeon_msi_initialize(void)
284 } 371 }
285 return 0; 372 return 0;
286} 373}
287
288subsys_initcall(octeon_msi_initialize); 374subsys_initcall(octeon_msi_initialize);