Commit a894f14d authored by David Daney's avatar David Daney Committed by Ralf Baechle

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: default avatarDavid Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1484/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent cb8f55b9
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <asm/octeon/octeon.h> #include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-pexp-defs.h>
#include <asm/octeon/cvmx-npi-defs.h>
static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock); static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
...@@ -528,90 +526,6 @@ static struct irq_chip octeon_irq_chip_ciu1 = { ...@@ -528,90 +526,6 @@ static struct irq_chip octeon_irq_chip_ciu1 = {
#endif #endif
}; };
#ifdef CONFIG_PCI_MSI
static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
static void octeon_irq_msi_ack(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/* These chips have PCI */
cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
1ull << (irq - OCTEON_IRQ_MSI_BIT0));
} else {
/*
* These chips have PCIe. Thankfully the ACK doesn't
* need any locking.
*/
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
1ull << (irq - OCTEON_IRQ_MSI_BIT0));
}
}
static void octeon_irq_msi_eoi(unsigned int irq)
{
/* Nothing needed */
}
static void octeon_irq_msi_enable(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/*
* Octeon PCI doesn't have the ability to mask/unmask
* MSI interrupts individually. Instead of
* masking/unmasking them in groups of 16, we simple
* assume MSI devices are well behaved. MSI
* interrupts are always enable and the ACK is assumed
* to be enough.
*/
} else {
/* These chips have PCIe. Note that we only support
* the first 64 MSI interrupts. Unfortunately all the
* MSI enables are in the same register. We use
* MSI0's lock to control access to them all.
*/
uint64_t en;
unsigned long flags;
raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
}
static void octeon_irq_msi_disable(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/* See comment in enable */
} else {
/*
* These chips have PCIe. Note that we only support
* the first 64 MSI interrupts. Unfortunately all the
* MSI enables are in the same register. We use
* MSI0's lock to control access to them all.
*/
uint64_t en;
unsigned long flags;
raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
}
static struct irq_chip octeon_irq_chip_msi = {
.name = "MSI",
.enable = octeon_irq_msi_enable,
.disable = octeon_irq_msi_disable,
.ack = octeon_irq_msi_ack,
.eoi = octeon_irq_msi_eoi,
};
#endif
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
int irq; int irq;
...@@ -672,13 +586,6 @@ void __init arch_init_irq(void) ...@@ -672,13 +586,6 @@ void __init arch_init_irq(void)
set_irq_chip_and_handler(irq, chip1, handle_percpu_irq); set_irq_chip_and_handler(irq, chip1, handle_percpu_irq);
} }
#ifdef CONFIG_PCI_MSI
/* 152 - 215 PCI/PCIe MSI interrupts */
for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
handle_percpu_irq);
}
#endif
set_c0_status(0x300 << 2); set_c0_status(0x300 << 2);
} }
......
...@@ -249,12 +249,99 @@ static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id) ...@@ -249,12 +249,99 @@ static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
} }
static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
static void octeon_irq_msi_ack(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/* These chips have PCI */
cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
1ull << (irq - OCTEON_IRQ_MSI_BIT0));
} else {
/*
* These chips have PCIe. Thankfully the ACK doesn't
* need any locking.
*/
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
1ull << (irq - OCTEON_IRQ_MSI_BIT0));
}
}
static void octeon_irq_msi_eoi(unsigned int irq)
{
/* Nothing needed */
}
static void octeon_irq_msi_enable(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/*
* Octeon PCI doesn't have the ability to mask/unmask
* MSI interrupts individually. Instead of
* masking/unmasking them in groups of 16, we simple
* assume MSI devices are well behaved. MSI
* interrupts are always enable and the ACK is assumed
* to be enough.
*/
} else {
/* These chips have PCIe. Note that we only support
* the first 64 MSI interrupts. Unfortunately all the
* MSI enables are in the same register. We use
* MSI0's lock to control access to them all.
*/
uint64_t en;
unsigned long flags;
raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
}
static void octeon_irq_msi_disable(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/* See comment in enable */
} else {
/*
* These chips have PCIe. Note that we only support
* the first 64 MSI interrupts. Unfortunately all the
* MSI enables are in the same register. We use
* MSI0's lock to control access to them all.
*/
uint64_t en;
unsigned long flags;
raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
}
static struct irq_chip octeon_irq_chip_msi = {
.name = "MSI",
.enable = octeon_irq_msi_enable,
.disable = octeon_irq_msi_disable,
.ack = octeon_irq_msi_ack,
.eoi = octeon_irq_msi_eoi,
};
/* /*
* Initializes the MSI interrupt handling code * Initializes the MSI interrupt handling code
*/ */
int octeon_msi_initialize(void) static int __init octeon_msi_initialize(void)
{ {
int irq;
for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
handle_percpu_irq);
}
if (octeon_has_feature(OCTEON_FEATURE_PCIE)) { if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt, if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
IRQF_SHARED, IRQF_SHARED,
...@@ -284,5 +371,4 @@ int octeon_msi_initialize(void) ...@@ -284,5 +371,4 @@ int octeon_msi_initialize(void)
} }
return 0; return 0;
} }
subsys_initcall(octeon_msi_initialize); subsys_initcall(octeon_msi_initialize);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment