From patchwork Tue Sep 16 11:20:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 4916611 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5FA18BEEA5 for ; Tue, 16 Sep 2014 11:17:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EF836201DC for ; Tue, 16 Sep 2014 11:17:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9B09C20149 for ; Tue, 16 Sep 2014 11:17:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752951AbaIPLRx (ORCPT ); Tue, 16 Sep 2014 07:17:53 -0400 Received: from mail-pd0-f178.google.com ([209.85.192.178]:42134 "EHLO mail-pd0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752833AbaIPLRw (ORCPT ); Tue, 16 Sep 2014 07:17:52 -0400 Received: by mail-pd0-f178.google.com with SMTP id p10so8282008pdj.23 for ; Tue, 16 Sep 2014 04:17:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:date:message-id:in-reply-to:references:subject; bh=QTzvS3xgqHtFY6dq1PZYhtP5xVsWULJOt3LPS4hk8pA=; b=RK4s+OY1LpGFPg7kffJOLSK+Bxntb9Ler2Kg71rBSm+heXQ1vKchiV3IoZ71upHPIW p6UTN63Mp20uRKTZ4T5DjMZjz/9erFmOvO3C9jQwF7InIvNb6Rx1kwM0bvNX85hmdHpC dtQw+Mkp6KU9uM+SUDZveBibqzh2ZfgHNNrQapkaZ3FsyFgbXXix+UqNheTa95TDgxFc yC/Oaheo4vzt1S0empQEz3M5/uXnNUk0tevjf626RRvq7v7eF2Z20pdmjCVNcqN8THO1 4TEwPe1dqX/zet6ByGdAXJ5usSPCL3zDB+Mv02G4eYYRM8bTlba1QqBtUrSlbuMnoo71 JChw== X-Received: by 10.66.220.230 with SMTP id pz6mr14786548pac.145.1410866271457; Tue, 16 Sep 2014 04:17:51 -0700 (PDT) Received: from [127.0.0.1] (s214090.ppp.asahi-net.or.jp. [220.157.214.90]) by mx.google.com with ESMTPSA id ic5sm13943781pbb.3.2014.09.16.04.17.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Sep 2014 04:17:48 -0700 (PDT) From: Magnus Damm To: Magnus Damm , linux-sh@vger.kernel.org Cc: Magnus Damm , laurent.pinchart@ideasonboard.com Date: Tue, 16 Sep 2014 20:20:11 +0900 Message-Id: <20140916112011.14889.71199.sendpatchset@w520> In-Reply-To: <20140916112001.14889.62059.sendpatchset@w520> References: <20140916112001.14889.62059.sendpatchset@w520> Subject: [PATCH 01/03] PCI: rcar: Use notifier to hook up IOMMU groups Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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 From: Magnus Damm Extend the R-Car Gen2 PCI controller to use a notifier to add OHCI and EHCI devices to the same IOMMU group as the PCI host device. With this patch the PCI host controller driver will simply assign the same IOMMU group to all children hanging off the PCI bus that it happens to driver. Multiple PCI host controllers and IOMMU groups are known to work. It is the responsibility of the IOMMU driver to assign one IOMMU group per PCI host controller and make sure that when PCI devices are added to IOMMU groups then such devices need to be handled by the IOMMU as well. Tested on r8a7790 Lager with a single USB device connected to USB1 on CN5. Other USB host controllers and their PCI host controllers on USB0 and USB2 are known to get unique IOMMU groups but apart from that no special testing has been done due to lack of DT-capable USB PHY driver upstream. Known to compile and work independently of if IOMMU is enabled in the Kconfig or IPMMU driver available. Signed-off-by: Magnus Damm --- drivers/pci/host/pci-rcar-gen2.c | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- 0001/drivers/pci/host/pci-rcar-gen2.c +++ work/drivers/pci/host/pci-rcar-gen2.c 2014-09-16 16:45:03.000000000 +0900 @@ -13,8 +13,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -102,6 +104,7 @@ struct rcar_pci_priv { unsigned busnr; int irq; unsigned long window_size; + struct notifier_block bus_notifier; }; /* PCI configuration space operations */ @@ -329,6 +332,52 @@ static struct pci_ops rcar_pci_ops = { .write = rcar_pci_write_config, }; +static int rcar_pci_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct rcar_pci_priv *priv; + struct device *dev = data; + struct pci_dev *pci_dev = to_pci_dev(dev); + struct pci_sys_data *sys = pci_dev->sysdata; + struct iommu_group *iommu_group; + + priv = container_of(nb, struct rcar_pci_priv, bus_notifier); + if (priv != sys->private_data) + return 0; + + iommu_group = iommu_group_get(priv->dev); + if (iommu_group) { + switch (action) { + case BUS_NOTIFY_BIND_DRIVER: + iommu_group_add_device(iommu_group, dev); + break; + + case BUS_NOTIFY_UNBOUND_DRIVER: + iommu_group_remove_device(dev); + break; + } + iommu_group_put(iommu_group); + } + + return 0; +} + +static void rcar_pci_add_bus(struct pci_bus *bus) +{ + struct pci_sys_data *sys = bus->sysdata; + struct rcar_pci_priv *priv = sys->private_data; + + bus_register_notifier(&pci_bus_type, &priv->bus_notifier); +} + +static void rcar_pci_remove_bus(struct pci_bus *bus) +{ + struct pci_sys_data *sys = bus->sysdata; + struct rcar_pci_priv *priv = sys->private_data; + + bus_unregister_notifier(&pci_bus_type, &priv->bus_notifier); +} + static int rcar_pci_probe(struct platform_device *pdev) { struct resource *cfg_res, *mem_res; @@ -372,6 +421,7 @@ static int rcar_pci_probe(struct platfor } priv->window_size = SZ_1G; + priv->bus_notifier.notifier_call = rcar_pci_bus_notify; if (pdev->dev.of_node) { struct resource busnr; @@ -397,6 +447,8 @@ static int rcar_pci_probe(struct platfor hw.map_irq = rcar_pci_map_irq; hw.ops = &rcar_pci_ops; hw.setup = rcar_pci_setup; + hw.add_bus = rcar_pci_add_bus; + hw.remove_bus = rcar_pci_remove_bus; pci_common_init_dev(&pdev->dev, &hw); return 0; }