From patchwork Thu Jan 15 11:10:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 5638521 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 650BE9F2ED for ; Thu, 15 Jan 2015 11:10:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3BDF220142 for ; Thu, 15 Jan 2015 11:10:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7BBF920166 for ; Thu, 15 Jan 2015 11:10:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752184AbbAOLKa (ORCPT ); Thu, 15 Jan 2015 06:10:30 -0500 Received: from cantor2.suse.de ([195.135.220.15]:47947 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751834AbbAOLK3 (ORCPT ); Thu, 15 Jan 2015 06:10:29 -0500 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 340CBAB0E; Thu, 15 Jan 2015 11:10:27 +0000 (UTC) Message-ID: <54B7A021.90101@suse.de> Date: Thu, 15 Jan 2015 12:10:25 +0100 From: Alexander Graf User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: Ming Lei , Bjorn Helgaas , Will Deacon , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org CC: Rob Herring , alvise rigo Subject: Re: [PATCH] pci: generic host: make it more generic References: <1415702040-2790-1-git-send-email-ming.lei@canonical.com> In-Reply-To: <1415702040-2790-1-git-send-email-ming.lei@canonical.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On 11.11.14 11:33, Ming Lei wrote: > This patch converts the generic host controller driver > into a more generic one, and basically don't need > platform's pcibios support, and use DT based generic > APIs to parse resource and remap IO port. > > This patch has been tested on both ARMv7 and ARMv8 > VM, and in theroy it should support other ARCHs too. > > With this patch, virtio PCI block, network and scsi devices > can work well on ARMv7 and ARMv8 VM. > > QEMU needs below patches for runing the test: > > - Rob Herring's "Add generic PCI host device" patches > http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg03482.html > http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg03483.html > - Alvise Rigo's "Add Generic PCI host device update" > http://marc.info/?l=qemu-devel&m=140506329920172&w=2 > > For ARMv8, cpu model of "host" and "cortex-a57" is missed > in Alvise Rigo's patchset, otherwise ARM64 VM can't boot. > > All these QEMU patches can be found in below tree: > > http://kernel.ubuntu.com/git?p=ming/qemu.git;a=shortlog;h=refs/heads/arm64-pci-test > > Signed-off-by: Ming Lei > --- > drivers/pci/host/Kconfig | 2 +- > drivers/pci/host/pci-host-generic.c | 196 +++++++++++------------------------ > 2 files changed, 63 insertions(+), 135 deletions(-) > > diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig > index 3dc25fa..885034d 100644 > --- a/drivers/pci/host/Kconfig > +++ b/drivers/pci/host/Kconfig > @@ -50,7 +50,7 @@ config PCI_RCAR_GEN2_PCIE > > config PCI_HOST_GENERIC > bool "Generic PCI host controller" > - depends on ARM && OF > + depends on OF > help > Say Y here if you want to support a simple generic PCI host > controller, such as the one emulated by kvmtool. > diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c > index 3d2076f..00d0ca3 100644 > --- a/drivers/pci/host/pci-host-generic.c > +++ b/drivers/pci/host/pci-host-generic.c > @@ -44,12 +44,14 @@ struct gen_pci { > struct list_head resources; > }; > > +/* fake sysdata for cheating ARCH's pcibios code */ > +static char gen_sysdata[256]; > + > static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus, > unsigned int devfn, > int where) > { > - struct pci_sys_data *sys = bus->sysdata; > - struct gen_pci *pci = sys->private_data; > + struct gen_pci *pci = dev_get_drvdata(bus->dev.parent->parent); Just as a heads up, this breaks when you have PCI bridges in between. In that case you need something like the ugly patch below on top. Alex return pci->cfg.win[idx] + ((devfn << 12) | where); @@ -81,7 +96,11 @@ static int gen_pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { void __iomem *addr; - struct gen_pci *pci = dev_get_drvdata(bus->dev.parent->parent); + struct gen_pci *pci = gen_pci_get_drvdata(bus); + + WARN_ON(!pci); + if (!pci) + return PCIBIOS_DEVICE_NOT_FOUND; addr = pci->cfg.ops->map_bus(bus, devfn, where); @@ -103,7 +122,11 @@ static int gen_pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { void __iomem *addr; - struct gen_pci *pci = dev_get_drvdata(bus->dev.parent->parent); + struct gen_pci *pci = gen_pci_get_drvdata(bus); + + WARN_ON(!pci); + if (!pci) + return PCIBIOS_DEVICE_NOT_FOUND; addr = pci->cfg.ops->map_bus(bus, devfn, where); --- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index e580296..730a07b 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c @@ -47,11 +47,26 @@ struct gen_pci { /* fake sysdata for cheating ARCH's pcibios code */ static char gen_sysdata[256]; +static struct gen_pci *gen_pci_get_drvdata(struct pci_bus *bus) +{ + struct device *dev = bus->dev.parent->parent; + struct gen_pci *pci; + + while (dev) { + pci = dev_get_drvdata(dev); + if (pci) + return pci; + dev = dev->parent; + } + + return NULL; +} + static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus, unsigned int devfn, int where) { - struct gen_pci *pci = dev_get_drvdata(bus->dev.parent->parent); + struct gen_pci *pci = gen_pci_get_drvdata(bus); resource_size_t idx = bus->number - pci->cfg.bus_range.start; return pci->cfg.win[idx] + ((devfn << 8) | where); @@ -66,7 +81,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus, unsigned int devfn, int where) { - struct gen_pci *pci = dev_get_drvdata(bus->dev.parent->parent); + struct gen_pci *pci = gen_pci_get_drvdata(bus); resource_size_t idx = bus->number - pci->cfg.bus_range.start;