diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-07-23 13:43:45 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-08-05 08:26:10 -0400 |
commit | a894f14d7ebe9e278b496b1e653ae57f2eff514e (patch) | |
tree | adf5e2caef5ec79c7256d50d6a7f3fdff94e8d15 /arch | |
parent | cb8f55b9207df96ccc332748eb3d154cd2e8014f (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.c | 93 | ||||
-rw-r--r-- | arch/mips/pci/msi-octeon.c | 90 |
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 | ||
16 | static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); | 14 | static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); |
17 | static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock); | 15 | static 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 | |||
533 | static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock); | ||
534 | |||
535 | static 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 | |||
551 | static void octeon_irq_msi_eoi(unsigned int irq) | ||
552 | { | ||
553 | /* Nothing needed */ | ||
554 | } | ||
555 | |||
556 | static 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 | |||
584 | static 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 | |||
606 | static 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 | |||
615 | void __init arch_init_irq(void) | 529 | void __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 | ||
252 | static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock); | ||
253 | |||
254 | static 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 | |||
270 | static void octeon_irq_msi_eoi(unsigned int irq) | ||
271 | { | ||
272 | /* Nothing needed */ | ||
273 | } | ||
274 | |||
275 | static 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 | |||
303 | static 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 | |||
325 | static 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 | */ |
256 | int octeon_msi_initialize(void) | 336 | static 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 | |||
288 | subsys_initcall(octeon_msi_initialize); | 374 | subsys_initcall(octeon_msi_initialize); |