mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
cb8f55b920
commit
a894f14d7e
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue