From: Michael Ellerman <michael@ellerman.id.au>
To: <linuxppc-dev@ozlabs.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
Greg Kroah-Hartman <greg@kroah.com>,
linux-pci@atrey.karlin.mff.cuni.cz,
"David S. Miller" <davem@davemloft.net>
Subject: [RFC/PATCH 6/7] MPIC MSI backend
Date: Tue, 07 Nov 2006 18:21:24 +1100 [thread overview]
Message-ID: <20061107072126.C586067CD6@ozlabs.org> (raw)
In-Reply-To: <1162884080.585336.70559261997.qpush@cradle>
MPIC MSI backend. Based on code from Segher, heavily hacked by me.
This version discovers the magic address by reading the config space.
Still slightly hacky in that we reuse pdev->irq, pending an irq
allocator for MPIC.
Tested, succesfully getting MSIs from the tg3 via HT/PCI-X on a JS21
running SLOF.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/kernel/msi-mpic.c | 138 +++++++++++++++++++++++++++++++++++++++++
include/asm-powerpc/msi.h | 2
2 files changed, 140 insertions(+)
Index: msi/arch/powerpc/kernel/msi-mpic.c
===================================================================
--- /dev/null
+++ msi/arch/powerpc/kernel/msi-mpic.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2006 Segher Boessenkool, IBM Corp.
+ * Copyright (C) 2006 Michael Ellerman, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/irq.h>
+#include <asm/msi.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+static unsigned int find_ht_msi_capability(struct pci_dev *pdev)
+{
+ u8 subcap;
+ unsigned int pos = pci_find_capability(pdev, PCI_CAP_ID_HT);
+
+ while (pos) {
+ pci_read_config_byte(pdev, pos + HT_SUBCAP_OFFSET, &subcap);
+ if (subcap == HT_CAPTYPE_MSI_MAPPING)
+ return pos;
+ pos = pci_find_next_capability(pdev, pos, PCI_CAP_ID_HT);
+ }
+
+ return 0;
+}
+
+static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
+{
+ u8 flags;
+ u32 tmp;
+ u64 addr;
+
+ pci_read_config_byte(pdev, pos + HT_MSI_FLAGS, &flags);
+
+ if (flags & HT_MSI_FLAGS_FIXED)
+ return HT_MSI_FIXED_ADDR;
+
+ pci_read_config_dword(pdev, pos + HT_MSI_ADDR_LO, &tmp);
+ addr = tmp & HT_MSI_ADDR_LO_MASK;
+ pci_read_config_dword(pdev, pos + HT_MSI_ADDR_HI, &tmp);
+ addr = addr | ((u64)tmp << 32);
+
+ return addr;
+}
+
+static u64 find_ht_magic_addr(struct pci_dev *pdev)
+{
+ struct pci_bus *bus;
+ unsigned int pos;
+
+ for (bus = pdev->bus; bus; bus = bus->parent) {
+ pos = find_ht_msi_capability(bus->self);
+ if (pos)
+ return read_ht_magic_addr(bus->self, pos);
+ }
+
+ return 0;
+}
+
+static int msi_mpic_check(struct pci_dev *pdev, int num,
+ struct msix_entry *entries, int type)
+{
+ /* We need an irq allocator before we can support multi-MSI & MSI-X */
+ if (num != 1 || type == PCI_CAP_ID_MSIX) {
+ msi_debug("precondition failure for %s\n", pci_name(pdev));
+ return 1;
+ }
+
+ /* If we can't find a magic address then MSI ain't gonna work */
+ if (find_ht_magic_addr(pdev) == 0) {
+ msi_debug("no magic address found for %s\n", pci_name(pdev));
+ return 1;
+ }
+
+ return 0;
+}
+
+static void msi_mpic_free(struct pci_dev *pdev, int num,
+ struct msix_entry *entries, int type)
+{
+ /* We borrowed the LSI irq, so don't unmap it! */
+ return;
+}
+
+static int msi_mpic_alloc(struct pci_dev *pdev, int num,
+ struct msix_entry *entries, int type)
+{
+ /* For now we reuse the assigned LSI, this is a hack. */
+ set_irq_type(pdev->irq, IRQ_TYPE_EDGE_RISING);
+ entries[0].vector = pdev->irq;
+
+ return 0;
+}
+
+static int msi_mpic_setup_msi_msg(struct pci_dev *pdev,
+ struct msix_entry *entry, struct msi_msg *msg, int type)
+{
+ u64 addr;
+
+ addr = find_ht_magic_addr(pdev);
+ msg->address_lo = addr & 0xFFFFFFFF;
+ msg->address_hi = addr >> 32;
+ msg->data = irq_map[pdev->irq].hwirq;
+
+ msi_debug("allocated irq %d at 0x%lx for %s\n", pdev->irq,
+ addr, pci_name(pdev));
+
+ return 0;
+}
+
+static struct ppc_msi_ops mpic_msi_ops = {
+ .check = msi_mpic_check,
+ .alloc = msi_mpic_alloc,
+ .free = msi_mpic_free,
+ .enable = msi_raw_enable,
+ .disable = msi_raw_disable,
+ .setup_msi_msg = msi_mpic_setup_msi_msg,
+};
+
+static struct ppc_msi_ops *mpic_get_msi_ops(struct pci_dev *pdev)
+{
+ return &mpic_msi_ops;
+}
+
+int msi_mpic_init(void)
+{
+ pr_debug("mpic_msi_init: Registering MPIC MSI ops.\n");
+ ppc_md.get_msi_ops = mpic_get_msi_ops;
+
+ return 0;
+}
Index: msi/include/asm-powerpc/msi.h
===================================================================
--- msi.orig/include/asm-powerpc/msi.h
+++ msi/include/asm-powerpc/msi.h
@@ -170,8 +170,10 @@ extern void msi_raw_disable(struct pci_d
#ifdef CONFIG_PCI_MSI
extern int msi_rtas_init(void);
+extern int msi_mpic_init(void);
#else
static inline int msi_rtas_init(void) { return -1; };
+static inline int msi_mpic_init(void) { return -1; };
#endif
#endif /* __ASSEMBLY__ */
next prev parent reply other threads:[~2006-11-07 7:21 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-07 7:21 [RFC/PATCH 0/7] Powerpc MSI Implementation Michael Ellerman
2006-11-07 7:21 ` [RFC/PATCH 1/7] Add #defines for Hypertransport MSI fields Michael Ellerman
2006-11-07 8:01 ` Segher Boessenkool
2006-11-07 7:21 ` [RFC/PATCH 2/7] Make some MSI-X #defines generic Michael Ellerman
2006-11-13 18:31 ` patch pci-make-some-msi-x-defines-generic.patch added to gregkh-2.6 tree gregkh
2006-11-07 7:21 ` [RFC/PATCH 3/7] Rip out the existing powerpc msi stubs Michael Ellerman
2006-11-07 7:21 ` [RFC/PATCH 4/7] Powerpc MSI implementation Michael Ellerman
2006-11-07 20:07 ` Matthew Wilcox
2006-11-07 20:14 ` Russell King
2006-11-07 20:40 ` Benjamin Herrenschmidt
2006-11-07 20:44 ` Matthew Wilcox
2006-11-07 20:48 ` Russell King
2006-11-07 21:02 ` Matthew Wilcox
2006-11-07 22:25 ` Russell King
2006-11-07 22:29 ` Benjamin Herrenschmidt
2006-11-07 23:11 ` Eric W. Biederman
2006-11-08 0:15 ` Benjamin Herrenschmidt
2006-11-08 1:33 ` Eric W. Biederman
2006-11-08 2:08 ` Benjamin Herrenschmidt
2006-11-08 2:43 ` Eric W. Biederman
2006-11-08 3:02 ` Benjamin Herrenschmidt
2006-11-07 20:39 ` Benjamin Herrenschmidt
2006-11-07 7:21 ` [RFC/PATCH 5/7] RTAS " Michael Ellerman
2006-11-08 20:16 ` Jake Moilanen
2006-11-08 23:35 ` Michael Ellerman
2006-11-07 7:21 ` Michael Ellerman [this message]
2006-11-07 8:27 ` [RFC/PATCH 6/7] MPIC MSI backend Segher Boessenkool
2006-11-07 8:42 ` Benjamin Herrenschmidt
2006-11-07 9:04 ` Segher Boessenkool
2006-11-07 9:16 ` Benjamin Herrenschmidt
2006-11-07 11:12 ` Segher Boessenkool
2006-11-07 7:21 ` [RFC/PATCH 7/7] Enable MSI on Powerpc Michael Ellerman
2006-11-07 7:41 ` [RFC/PATCH 0/7] Powerpc MSI Implementation Benjamin Herrenschmidt
2006-11-07 8:02 ` Greg KH
2006-11-08 5:18 ` Michael Ellerman
2006-11-08 10:26 ` Eric W. Biederman
2006-11-08 23:33 ` Michael Ellerman
2006-11-09 7:36 ` Segher Boessenkool
2006-11-13 6:05 ` Michael Ellerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061107072126.C586067CD6@ozlabs.org \
--to=michael@ellerman.id.au \
--cc=davem@davemloft.net \
--cc=ebiederm@xmission.com \
--cc=greg@kroah.com \
--cc=linux-pci@atrey.karlin.mff.cuni.cz \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).