提交 a894f14d 编写于 作者: D David Daney 提交者: 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: NDavid Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1484/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 cb8f55b9
......@@ -10,8 +10,6 @@
#include <linux/smp.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_ciu1_lock);
......@@ -528,90 +526,6 @@ static struct irq_chip octeon_irq_chip_ciu1 = {
#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)
{
int irq;
......@@ -672,13 +586,6 @@ void __init arch_init_irq(void)
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);
}
......
......@@ -249,12 +249,99 @@ static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id)
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
*/
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 (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
IRQF_SHARED,
......@@ -284,5 +371,4 @@ int octeon_msi_initialize(void)
}
return 0;
}
subsys_initcall(octeon_msi_initialize);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册