linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Murray <andrew.murray@arm.com>
To: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>,
	Grant Likely <grant.likely@secretlab.ca>,
	Russell King <linux@arm.linux.org.uk>,
	"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	"devicetree-discuss@lists.ozlabs.org"
	<devicetree-discuss@lists.ozlabs.org>,
	Lior Amsalem <alior@marvell.com>, Andrew Lunn <andrew@lunn.ch>,
	Jason Cooper <jason@lakedaemon.net>,
	Arnd Bergmann <arnd@arndb.de>, Maen Suleiman <maen@marvell.com>,
	Thierry Reding <thierry.reding@avionic-design.de>,
	Gregory Clement <gregory.clement@free-electrons.com>,
	Ezequiel Garcia <ezequiel.garcia@free-electrons.com>,
	Olof Johansson <olof@lixom.net>,
	Tawfik Bayouk <tawfik@marvell.com>,
	Jason Gunthorpe <jgunthorpe@obsidianresearch.com>,
	Mitch Bradley <wmb@firmworks.com>
Subject: Re: [RFCv1 09/11] pci: mvebu: add MSI support
Date: Wed, 27 Mar 2013 10:07:30 +0000	[thread overview]
Message-ID: <20130327100730.GA1575@arm.com> (raw)
In-Reply-To: <1364316746-8702-10-git-send-email-thomas.petazzoni@free-electrons.com>

On Tue, Mar 26, 2013 at 04:52:24PM +0000, Thomas Petazzoni wrote:
> This commit adds the MSI support for the Marvell EBU PCIe driver. The
> driver now looks at the 'msi-parent' property of the PCIe controller
> DT node, and if it exists, it gets the associated IRQ domain, which
> should be the MSI interrupt controller registered by the IRQ
> controller driver.
> 
> Using this, the PCIe driver registers the ->setup_irq() and
> ->teardown_irq() callbacks using the newly introduced msi_chip
> infrastructure, which allows the kernel PCI core to use the MSI
> functionality.
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
>  .../devicetree/bindings/pci/mvebu-pci.txt          |    5 +
>  drivers/pci/host/pci-mvebu.c                       |  128 ++++++++++++++++++++
>  2 files changed, 133 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
> index 192bdfb..53cc437 100644
> --- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
> +++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
> @@ -14,6 +14,10 @@ Mandatory properties:
>    corresponding registers
>  - ranges: ranges for the PCI memory and I/O regions
>  
> +Optional properties:
> +- msi-parent: a phandle pointing to the interrupt controller that
> +  handles the MSI interrupts.
> +
>  In addition, the Device Tree node must have sub-nodes describing each
>  PCIe interface, having the following mandatory properties:
>  - reg: used only for interrupt mapping, so only the first four bytes
> @@ -43,6 +47,7 @@ pcie-controller {
>  	#address-cells = <3>;
>  	#size-cells = <2>;
>  
> +	msi-parent = <&msi>;
>  	bus-range = <0x00 0xff>;
>  
>  	reg = <0xd0040000 0x2000>, <0xd0042000 0x2000>,
> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> index 9e6b137..b46fab8 100644
> --- a/drivers/pci/host/pci-mvebu.c
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -7,17 +7,23 @@
>   */
>  
>  #include <linux/kernel.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
> +#include <linux/msi.h>
>  #include <linux/clk.h>
>  #include <linux/module.h>
>  #include <linux/mbus.h>
>  #include <linux/slab.h>
>  #include <linux/platform_device.h>
> +#include <linux/interrupt.h>
>  #include <linux/of_address.h>
>  #include <linux/of_pci.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
>  
> +#define INT_PCI_MSI_NR (16)
> +
>  /*
>   * PCIe unit register offsets.
>   */
> @@ -101,10 +107,19 @@ struct mvebu_sw_pci_bridge {
>  
>  struct mvebu_pcie_port;
>

This structure...
 
> +struct mvebu_pcie_msi {
> +	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
> +	struct irq_domain *domain;
> +	struct mutex lock;
> +	struct msi_chip chip;
> +	phys_addr_t doorbell;
> +};

And these functions...

> +#if defined(CONFIG_PCI_MSI)
> +static int mvebu_pcie_msi_alloc(struct mvebu_pcie_msi *chip)
> +{
> +	int msi;
> +
> +	mutex_lock(&chip->lock);
> +
> +	msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR);
> +
> +	if (msi < INT_PCI_MSI_NR)
> +		set_bit(msi, chip->used);
> +	else
> +		msi = -ENOSPC;
> +
> +	mutex_unlock(&chip->lock);
> +
> +	return msi;
> +}
> +
> +static void mvebu_pcie_msi_free(struct mvebu_pcie_msi *chip, unsigned long irq)
> +{
> +	struct device *dev = chip->chip.dev;
> +
> +	mutex_lock(&chip->lock);
> +
> +	if (!test_bit(irq, chip->used))
> +		dev_err(dev, "trying to free unused MSI#%lu\n", irq);
> +	else
> +		clear_bit(irq, chip->used);
> +
> +	mutex_unlock(&chip->lock);
> +}
> +
> +static int mvebu_pcie_setup_msi_irq(struct msi_chip *chip,
> +				    struct pci_dev *pdev,
> +				    struct msi_desc *desc)
> +{
> +	struct mvebu_pcie_msi *msi = to_mvebu_msi(chip);
> +	struct msi_msg msg;
> +	unsigned int irq;
> +	int hwirq;
> +
> +	hwirq = mvebu_pcie_msi_alloc(msi);
> +	if (hwirq < 0)
> +		return hwirq;
> +
> +	irq = irq_create_mapping(msi->domain, hwirq);
> +	if (!irq)
> +		return -EINVAL;
> +
> +	irq_set_msi_desc(irq, desc);
> +
> +	msg.address_lo = msi->doorbell;
> +	msg.address_hi = 0;
> +	msg.data = 0xf00 | (hwirq + 16);
> +
> +	write_msi_msg(irq, &msg);
> +
> +	return 0;
> +}
> +
> +static void mvebu_pcie_teardown_msi_irq(struct msi_chip *chip,
> +					unsigned int irq)
> +{
> +	struct mvebu_pcie_msi *msi = to_mvebu_msi(chip);
> +	struct irq_data *d = irq_get_irq_data(irq);
> +
> +	mvebu_pcie_msi_free(msi, d->hwirq);
> +}

...are not related to your PCIe driver or PCI. I remember you said that the MSI
registers are all inter-mixed with the interrupt controller. Therefore as the
above don't interact with PCIe controller registers can you move this out to an
irqchip driver or include it inside your interrupt controller?

> +
> +static int mvebu_pcie_enable_msi(struct mvebu_pcie *pcie)
> +{
> +	struct device_node *msi_node;
> +	struct mvebu_pcie_msi *msi;
> +
> +	msi = &pcie->msi;
> +
> +	mutex_init(&msi->lock);
> +
> +	msi_node = of_parse_phandle(pcie->pdev->dev.of_node,
> +				    "msi-parent", 0);
> +	if (!msi_node)
> +		return -EINVAL;
> +
> +	msi->domain = irq_find_host(msi_node);
> +	if (!msi->domain)
> +		return -EINVAL;
> +
> +	if (of_property_read_u32(msi_node, "marvell,doorbell", &msi->doorbell))
> +		return -EINVAL;
> +
> +	msi->chip.dev = &pcie->pdev->dev;
> +	msi->chip.setup_irq = mvebu_pcie_setup_msi_irq;
> +	msi->chip.teardown_irq = mvebu_pcie_teardown_msi_irq;
> +
> +	return 0;
> +}

This can change too, as per Thierry's suggestion you can call something like:

msi_chip_add(&msi)

from your interrupt controller. And then in this file you can call something
like:

of_find_msi_chip_by_node(msi_node)

and use the returned chip to assign to pcie->msi (and register with the pci_bus).
Perhaps then you may not need to expose the doorbell register as that would be
knowledge that the interrupt controller may already have (i.e. offset from base
address already provided in DT).

Andrew Murray

> +#endif /* CONFIG_PCI_MSI */
> +
>  static int __init mvebu_pcie_probe(struct platform_device *pdev)
>  {
>  	struct mvebu_pcie *pcie;
> @@ -903,6 +1024,13 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
>  
>  	mvebu_pcie_enable(pcie);
>  
> +#ifdef CONFIG_PCI_MSI
> +	ret = mvebu_pcie_enable_msi(pcie);
> +	if (ret)
> +		dev_warn(&pdev->dev, "could not enable MSI support: %d\n",
> +			 ret);
> +#endif
> +
>  	return 0;
>  }
>  
> -- 
> 1.7.9.5
> 
> 

  reply	other threads:[~2013-03-27 10:08 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-26 16:52 [RFCv1 00/11] MSI support for Marvell EBU PCIe driver Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 01/11] arm: mvebu: move L2 cache initialization in init_early() Thomas Petazzoni
2013-03-26 16:53   ` Arnd Bergmann
2013-03-26 17:02     ` Thomas Petazzoni
2013-03-27  1:53   ` Rob Herring
2013-03-26 16:52 ` [RFCv1 02/11] irqchip: move IRQ driver for Armada 370/XP Thomas Petazzoni
2013-03-26 16:54   ` Arnd Bergmann
2013-03-26 16:52 ` [RFCv1 03/11] irqchip: armada-370-xp: move IRQ handler to avoid forward declaration Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 04/11] irqchip: armada-370-xp: slightly cleanup irq controller driver Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 05/11] arm: mvebu: do not duplicate the mpic alias Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 06/11] irqchip: armada-370-xp: use a separate mpic node Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 07/11] irqchip: armada-370-xp: add MSI support to interrupt controller driver Thomas Petazzoni
2013-03-26 17:07   ` Arnd Bergmann
2013-03-26 17:17     ` Thomas Petazzoni
2013-03-26 18:38       ` Arnd Bergmann
2013-03-26 20:46         ` Thomas Petazzoni
2013-03-26 21:10           ` Arnd Bergmann
2013-03-26 21:37             ` Thomas Petazzoni
2013-03-26 21:53               ` Arnd Bergmann
2013-03-26 21:14           ` Jason Gunthorpe
2013-03-26 21:41             ` Thomas Petazzoni
2013-03-26 18:02   ` Jason Gunthorpe
2013-03-26 21:16     ` Thomas Petazzoni
2013-03-26 21:31       ` Arnd Bergmann
2013-03-26 21:47         ` Thomas Petazzoni
2013-03-26 21:55       ` Jason Gunthorpe
2013-03-26 22:04         ` Arnd Bergmann
2013-03-26 22:06         ` Thomas Petazzoni
2013-03-26 22:26           ` Jason Gunthorpe
2013-03-26 21:15   ` Arnd Bergmann
2013-03-26 21:42     ` Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 08/11] PCI: Introduce new MSI chip infrastructure Thomas Petazzoni
2013-04-08 22:28   ` Bjorn Helgaas
2013-04-09  8:11     ` Andrew Murray
2013-04-09  8:22       ` Thierry Reding
2013-04-09  8:25         ` Andrew Murray
2013-04-09  8:18     ` Thierry Reding
2013-03-26 16:52 ` [RFCv1 09/11] pci: mvebu: add MSI support Thomas Petazzoni
2013-03-27 10:07   ` Andrew Murray [this message]
2013-04-08 22:29   ` Bjorn Helgaas
2013-05-30 12:15     ` Thierry Reding
2013-05-30 18:13       ` Bjorn Helgaas
2013-03-26 16:52 ` [RFCv1 10/11] arm: mvebu: enable MSI support in DT Thomas Petazzoni
2013-03-26 16:52 ` [RFCv1 11/11] arm: mvebu: enable PCI MSI support in defconfig Thomas Petazzoni
2013-03-26 17:05 ` [RFCv1 00/11] MSI support for Marvell EBU PCIe driver Thomas Petazzoni
2013-03-26 17:18   ` Arnd Bergmann
2013-03-26 17:21     ` Thomas Petazzoni
2013-04-04  9:16 ` Ezequiel Garcia
2013-04-04  9:29   ` Thomas Petazzoni

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=20130327100730.GA1575@arm.com \
    --to=andrew.murray@arm.com \
    --cc=alior@marvell.com \
    --cc=andrew@lunn.ch \
    --cc=arnd@arndb.de \
    --cc=bhelgaas@google.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=grant.likely@secretlab.ca \
    --cc=gregory.clement@free-electrons.com \
    --cc=jason@lakedaemon.net \
    --cc=jgunthorpe@obsidianresearch.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=maen@marvell.com \
    --cc=olof@lixom.net \
    --cc=tawfik@marvell.com \
    --cc=thierry.reding@avionic-design.de \
    --cc=thomas.petazzoni@free-electrons.com \
    --cc=wmb@firmworks.com \
    /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).