[RFC/PATCH 10/16] Add a pci_irq_fixup for MSI via RTAS
Michael Ellerman
michael at ellerman.id.au
Thu Jan 25 19:34:13 EST 2007
When RTAS is managing MSIs for us, it will/may enable MSI on devices that
support it by default. This is contrary to the Linux model where a device
is in LSI mode until the driver requests MSIs.
To remedy this we add a pci_irq_fixup call, which disables MSI if they've
been assigned by firmware and the device also supports LSI.
At the moment there is no pci_irq_fixup on pSeries, so we can just set it
unconditionally. If other platforms use the RTAS MSI backend they'll need
to check that still holds.
Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---
drivers/pci/msi/rtas.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
Index: msi/drivers/pci/msi/rtas.c
===================================================================
--- msi.orig/drivers/pci/msi/rtas.c
+++ msi/drivers/pci/msi/rtas.c
@@ -238,6 +238,24 @@ static int msi_rtas_alloc(struct pci_dev
return -1;
}
+static void msi_rtas_pci_irq_fixup(struct pci_dev *pdev)
+{
+ /* No LSI -> leave MSIs (if any) configured */
+ if (pdev->irq == NO_IRQ) {
+ msi_debug("no LSI on %s, nothing to do.\n", pci_name(pdev));
+ return;
+ }
+
+ /* No MSI -> MSIs can't have been assigned by fw, leave LSI */
+ if (check_req_msi(pdev)) {
+ msi_debug("no req#msi on %s, nothing to do.\n", pci_name(pdev));
+ return;
+ }
+
+ msi_debug("disabling existing MSI on %s\n", pci_name(pdev));
+ rtas_disable_msi(pdev);
+}
+
static struct msi_ops rtas_msi_ops = {
.check = msi_rtas_check,
.alloc = msi_rtas_alloc,
@@ -264,5 +282,8 @@ int msi_rtas_init(void)
ppc_md.get_msi_ops = rtas_get_msi_ops;
+ WARN_ON(ppc_md.pci_irq_fixup);
+ ppc_md.pci_irq_fixup = msi_rtas_pci_irq_fixup;
+
return 0;
}
More information about the Linuxppc-dev
mailing list