Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933335AbdCWI62 (ORCPT ); Thu, 23 Mar 2017 04:58:28 -0400 Received: from mail-cys01nam02on0045.outbound.protection.outlook.com ([104.47.37.45]:30944 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750767AbdCWI6Z (ORCPT ); Thu, 23 Mar 2017 04:58:25 -0400 Authentication-Results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=caviumnetworks.com; Date: Thu, 23 Mar 2017 09:58:12 +0100 From: Jan Glauber To: Ulf Hansson Cc: "linux-mmc@vger.kernel.org" , "linux-kernel@vger.kernel.org" , David Daney , "Steven J . Hill" Subject: Re: [PATCH v12 6/9] mmc: cavium: Add MMC PCI driver for ThunderX SOCs Message-ID: <20170323085812.GA2250@hardcore> References: <20170310132507.32025-1-jglauber@cavium.com> <20170310132507.32025-7-jglauber@cavium.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Originating-IP: [109.193.47.185] X-ClientProxiedBy: VI1PR09CA0080.eurprd09.prod.outlook.com (10.174.49.152) To BN3PR07MB2577.namprd07.prod.outlook.com (10.167.4.154) X-MS-Office365-Filtering-Correlation-Id: 1fe782ae-a16d-4dfc-ab71-08d471cac278 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:BN3PR07MB2577; X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2577;3:HcF2pJsGibHdXk7zM+4YDfdIBIpa98AbDWlimqdqREXF3qoevzfWNjXWFIDekDZE60Xg9cTBOQUUgmWOmWWm8LzAoMGO0ykGy8C622QcvBKwmS63X4OmGKITBQTMSqY0wyKC037gihA/DV0SNwfw7xS1jngMvJ9Q7kliJ+Sr9eSOOaHm3QmPVc9Jsk551ERbbPgqEkWCTFrvOF/iYBdHokq1FmQ1pmDyCHED/gQeNz+xZ1JJyH1Ti6V5uXONi0wcoudgrte/4rEK4amFPdy7ug==;25:RNJT/mvkdJzwsR6QLklcyPKw7hnTdt+0tpUdRF3qOvzxbJYi49qV04H7y+KKSh/OtlO8zuEghlz/tiv1FLoRvMamdnHaEGOUCmalLGVCPU6EJqR/mJk2EkyF6r4gXFONJNKe5iRdNqjn5EeFJrhfNjxG0YfrQk4Kkc/ivLSY0YcppQXepCON8muRbRujnmnNCk/SVnMnWegDBMd1TEv5RedOz9mBH1xQypUDcD0eW7aqtx6KcV8Mciq/4/Ah4j/14A+EHv14tssuAJsQ0ZZv91FGZyPnLO0NldisqJ1MwH4QNsa2cfAN/L46vl4fxNxrBg7bttyVlAX0Hbhl5Od8en2I+HujZ/Z/dJl5lQQQks1Iuo5teYw70ym2y7c110RBjskTXfrvJbklEKGbTQPesmRLlrlKTRjTbuZ4BIpTO+NxMcQjaS8GPvPOC0XWhq0KOL4/EaqFjLHJNQ6FB6r90A== X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2577;31:XHiANCXtHAzVi36iCH4Uoznz7IJh5UHBeclKIvtXFS1DjXk/70rJ55mHjK8tloxUT+O+ll97wnfiQlYuODtUvRVLG3UXESAdujoRrHr5Wmd5dGWWL9DBZ57nrb3Ngu5EhRzbQUz+Lu4fY/ryok9T+jtGRDHIVGl2Yz2G5gqMJynlhLst4lCiXrkvtEjFKL6Pv+uJ8I/XWC47cVJ62SsXbaggIkoddoPHGTABDIa75Zs=;20:PRCVYV4o4nKDGvqGuB4Nw4qMz4XjwciUoPr+Kd2jCqZ2Qo4MHGVLBsZJO8PtPHOcDMtdAJf7nu6SKN7tCIwEsk9enMioBHM23FWVn9DZ+K/TdSmC9aqJQ3XsAE9lktfILHvsM6gOfPYdDZLxy7sGrKIzzAcOSyVHUl8xxdvmjUPjyGBVvJuY7phd8a7ltdl75JWkazris03+6Ieac2GhHaHbaDtr0/G7rgeaeSlDqxr/XswrZvb6oguzF0dO335kxD8GUD5fXop5KwdpIa+B0aR3nAWaDd7A8iWRcFD6Fx0DmytxwXF4clpQE6ttCRRHFzcwQB3y13WTqw5CdD9jq7TL53xp367PEIYkrJAUThOZ+OeH/39/qdqPZ0KgsFaBgQ2yIs6OOfkU+lHqnUvANub0o5G2ILtt2LWUOTfqcNnTC/FiqeZ0qiG0EEU6BwnKXImrwmt7NFcvV2k7NmlfONDVTzodB0LpBBOTgMRWNkP8j78VK/EgOXfYDnVCtwf04g5q7RvQDkaPo3fyRdFvzbOHsmourhddQJp27bLuDorLxiCr/nbOxYhPsCsVBjUHQOzJh9r1Cx8AB4A6yff5c5C1InG++K9Duh8Yzn+0lkk= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6041248)(20161123560025)(20161123558025)(20161123555025)(20161123564025)(20161123562025)(6072148);SRVR:BN3PR07MB2577;BCL:0;PCL:0;RULEID:;SRVR:BN3PR07MB2577; X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2577;4:GyYKy+zl+ocfZ3LxQZ7dWnIl30NHErvYvXi9beSJTYjAwx/60RkxOz4mJ86HIk3uNjIdCVwlPsOjfghh0HSj+KSGG4RzNXWW7/l4ZbVF1CkzDzKsFAGv/lqiAHND9bvP+yPShciL+G/OH/GKTKQH3/PS7TIEHVDE7ohRuVvhNmw9KuXvWEuXubKSq2zEUVT4+M3r1jeU7NpSOm19hnH634E6+DfzD88aLncEvNDSHUsxFSqcHsS8dDd1K9U9/STvN7LLLXlK9n3jucnLgOxrFq1MDNMqoYnS2AllwwwyvmM3fuGTckn00Cf/tbVHyY88qtF0EAEnX5wSN60xkKpw6erGJeEESD635dXOBWcmoEd6L+XyRLw0YSX6219X+8/Rj+mN27rVuNUWcMPIxRPKE2g0dEMUdtZB6AGxfPnHUvkjDvQXYYOw53IugLmXi5DGD5D8xLR4d2NGCgWp1CvXNScX+5CBfFeMk7Kft3X9JrfsOgKPxEA8gAiH2BmcnhbjCAlmDzlSQd1T0azvDacaKcZ9rZihTskrhzeVuqkiCqT19CZcF/GCjkMmukzEENdNbcP0Phsuk6qMAXxc0QIVOvUXdpbMapJcwcMJTMRODcc= X-Forefront-PRVS: 0255DF69B9 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(39410400002)(39830400002)(39450400003)(24454002)(3846002)(55016002)(9686003)(107886003)(53936002)(110136004)(6246003)(6496005)(23726003)(42186005)(42882006)(54906002)(38730400002)(229853002)(50986999)(1076002)(25786009)(47776003)(76176999)(6666003)(305945005)(66066001)(2950100002)(50466002)(5660300001)(54356999)(6916009)(7736002)(8676002)(4326008)(575784001)(6116002)(2906002)(83506001)(53546009)(33656002)(33716001)(4001350100001)(81166006)(189998001)(18370500001)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:BN3PR07MB2577;H:hardcore;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BN3PR07MB2577;23:+eoYZl2liwiZIyXGUGNJXDSanvMdOd2M6RbCpNwa/?= =?us-ascii?Q?RNJUDSsCVqo/dauA2voGCfJspS5G4tjo8ysnmGOKGygP3Rl36fn+vQGY2uVm?= =?us-ascii?Q?E481uyDEL66e20wwW2uWrmLRAu24lZAe6QN/96w7OqOZJnTXYKknFkb4RJwW?= =?us-ascii?Q?OxooY4p66RDwsbwIyGW9raon3BxWVmX9IJKuiPxzPrYs9faj1UVbFDh4gemi?= =?us-ascii?Q?0pXf1/Uwgz4/6s0z3aonh7o7QCjtHwjyY+q+nv0Ow4Q2V0Ut7bg+0g9ETg0G?= =?us-ascii?Q?k/VyIV934dNPir1rC6tQ56806U/w6vW1DsdiugFRftR0TiEBRy4W8swyanT5?= =?us-ascii?Q?Zm2I7jUMQuu6KAbpuMpem5o7IsOdyXYhnMJ6jH1/u32QlQ5MsWKonAwiP/Wm?= =?us-ascii?Q?r86sY77BV+3dflDTc+eMTYvAnHKv8hFYZAbJirvK2fFr09oDoWWoOKxAeJmT?= =?us-ascii?Q?hoD3BHka/v79UhjlEPX6HV2bz/W203uytDaw9ZWDjfixOMT6ikoJYRwUa/n8?= =?us-ascii?Q?PswcVAgCpd2ntT0tD2bhWnzGBtfMiFs7mTczDtxAaoMqD5IbPE2ljPTYFFNo?= =?us-ascii?Q?DgWKgfcLBGNEaxoBxxZbB2B5brFCLVW/OcNwVmvgNPgglB0KB1qJAGM8rqHw?= =?us-ascii?Q?0x7btbPGqdAefW0yUZqCp2Ic6htTWjlt1tbTOPLBC1nNsRwSI7Zf7ktOZzaQ?= =?us-ascii?Q?R+LmyQPznMAZ0vW3oJHErq6wfEig1r/nha/aXHGrLpIsaPzdgkOxa0BBiC6q?= =?us-ascii?Q?GyFkE7wzGhk0tps7c4fbYgKFSGOv7SWpXA0XayBTR2/SKVTky2ziibzpd8BI?= =?us-ascii?Q?BhMbc5yF0Fm4lIyO2f4+sY1YLf55YPUrZXjXF2nbKtLDpvpUj23OWp63tr9W?= =?us-ascii?Q?Cw4sU2OFVGPPtHf1Ggb9RywfK4rcv20Vxvc99xloUfCzrvNoJXZLkBuiwkhq?= =?us-ascii?Q?tw15lSZP7UIit72baHbeVyCeKKoGROvsDfVU5nddn0wIMteim+QDFq4iubmJ?= =?us-ascii?Q?KIQ+kS36BPHY4G7X/AQQarU2fnimhGw4HPGFPyyul5u4CsbPl8dYPqo/O9wo?= =?us-ascii?Q?Cz8ac9pL3JPL5vXXMXWkhcKYTwUfbEeRHIJtcGku89EdKZOssWw27msNG0S2?= =?us-ascii?Q?UdMJ1L9+s7YZpoDjMzBS+tVZc8QAiX6SiBjEc+fBRZ6ZNA4+KS2o/vkGHntK?= =?us-ascii?Q?/bFmFRMNXsKNFw=3D?= X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2577;6:nKHyMQid70QoPMUKKUOfBbIUyhjd5LrsZakXZ3H8gA+B+w52302c2iDxAJXndAHkAchCRJQDIYaXrspKQzDmgRLMPEVOJFLEnTyM9o7e2SLwb0j69sXXPdTyjtfN5IEWcGN14E4J9Psjp2N8C8oi8+dMEoLkzTaNtUJXDEwJ4NETmwxo1SfP+xg2rrTXwFhG1MKyJb033fYO5O9H0f9hRYuASLLvOB8kaLnh61/9CGz3oYRYP5cddgYJaed0gkOk51EwWo01ft8nXf8eenFY1/RY2BbPc2LC8avyH4rO2GQPvhNwXg9/zA1as3zj8uZSR/biLaJFzgGpTgr8XxSQMImmobr3aHtbi7yDkw58D0ISGDworl6QiSleiKqA4AyaZq8FrLh9fqy2vtmgwtubTA==;5:ZGEA9pyXj9JmWtFOwhBkckz5HAEP2edXK13pcjPBcImmQcIURXFs10RuZf2623XHHTdqkhtnfmmahzuThJ2fdLOQcovcyc7UpE5A10XP/ZiOGoGfTBx2Yvh29luYqtDy2t5rvCSrdhwWzxBw1JVCpA==;24:Xnco/9BbmD/rRnHsaLAI9i5y9j0HZ7WiqiD5LZeOs5mYCql82DM+cugcdKm6SfwcGgK3dZBU71z1sMF8JjSWiUZqdwAzmhtd7dnhPaoXbjs= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BN3PR07MB2577;7:qtWaWey5r4qubE9UuP8j9skZ/9vDUjLcerPGs7EJcQeG3PBEOitMSQ0TpoAtDe3GPqJ8793hUBMYKap/hK+e6sywYeVtPYxL1FIvS0W+N5jho7XOHGBTUVyw0lFHkIXvq4owd2nLOSMCOcdDpA+PTipdZAL5otEs96pPx87ZuvIPDWg0971BZWFSX6iJ750EUVmK58tL+iRgJWOg4XEdd6HFcC5yANcd9SHo9y7JKLf+nTOkKLc0r9eMEae4QJAFKmoVyHdW2uO2rcPHbCOemgPn9+vJ/i3LdXPAgl+Iy3z+Oy/vCmQjvT73UQSjchrEbxne8bGzIhUQqAuXiqx/Zg== X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Mar 2017 08:58:21.6044 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR07MB2577 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 11701 Lines: 318 On Fri, Mar 17, 2017 at 03:58:26PM +0100, Ulf Hansson wrote: > On 10 March 2017 at 14:25, Jan Glauber wrote: > > Add a platform driver for ThunderX ARM SOCs. > > > > Signed-off-by: Jan Glauber > > --- > > drivers/mmc/host/Kconfig | 10 ++ > > drivers/mmc/host/Makefile | 2 + > > drivers/mmc/host/cavium-mmc.h | 10 +- > > drivers/mmc/host/cavium-pci-thunderx.c | 198 +++++++++++++++++++++++++++++++++ > > 4 files changed, 218 insertions(+), 2 deletions(-) > > create mode 100644 drivers/mmc/host/cavium-pci-thunderx.c > > > > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig > > index 68cc811..3983dee 100644 > > --- a/drivers/mmc/host/Kconfig > > +++ b/drivers/mmc/host/Kconfig > > @@ -632,6 +632,16 @@ config MMC_CAVIUM_OCTEON > > > > If unsure, say N. > > > > +config MMC_CAVIUM_THUNDERX > > + tristate "Cavium ThunderX SD/MMC Card Interface support" > > + depends on PCI && 64BIT && (ARM64 || COMPILE_TEST) > > + select GPIO_THUNDERX > > Do you really need to select GPIO_THUNDERX? What is the relationship? I don't know much about gpio, but in the end despite all these layers there must be a gpio set function called doing the writeq on our SOC to enable/disable the power gpio, right? GPIO_THUNDERX implements this gpio set function for Cavium's SOC. > Maybe "depends on GPIOLIB" instead? > > > + help > > + This selects Cavium ThunderX SD/MMC Card Interface. > > + If you have an Cavium ARM64 board with a Multimedia Card slot > > + or builtin eMMC chip say Y or M here. If built as a module > > + the module will be called thunderx_mmc.ko. > > + > > config MMC_DW > > tristate "Synopsys DesignWare Memory Card Interface" > > depends on HAS_DMA > > diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile > > index c7f0ccf..0068610 100644 > > --- a/drivers/mmc/host/Makefile > > +++ b/drivers/mmc/host/Makefile > > @@ -44,6 +44,8 @@ obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o > > obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o > > octeon-mmc-objs := cavium-mmc.o cavium-pltfm-octeon.o > > obj-$(CONFIG_MMC_CAVIUM_OCTEON) += octeon-mmc.o > > +thunderx-mmc-objs := cavium-mmc.o cavium-pci-thunderx.o > > +obj-$(CONFIG_MMC_CAVIUM_THUNDERX) += thunderx-mmc.o > > obj-$(CONFIG_MMC_DW) += dw_mmc.o > > obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o > > obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o > > diff --git a/drivers/mmc/host/cavium-mmc.h b/drivers/mmc/host/cavium-mmc.h > > index 4b22432..fb82aee 100644 > > --- a/drivers/mmc/host/cavium-mmc.h > > +++ b/drivers/mmc/host/cavium-mmc.h > > @@ -22,8 +22,12 @@ > > #define CAVIUM_MAX_MMC 4 > > > > /* DMA register addresses */ > > -#define MIO_EMM_DMA_CFG(x) (0x00 + x->reg_off_dma) > > -#define MIO_EMM_DMA_ADR(x) (0x08 + x->reg_off_dma) > > +#define MIO_EMM_DMA_CFG(x) (0x20 + x->reg_off_dma) > > +#define MIO_EMM_DMA_ADR(x) (0x28 + x->reg_off_dma) > > +#define MIO_EMM_DMA_INT(x) (0x30 + x->reg_off_dma) > > +#define MIO_EMM_DMA_INT_W1S(x) (0x38 + x->reg_off_dma) > > +#define MIO_EMM_DMA_INT_ENA_W1S(x) (0x40 + x->reg_off_dma) > > +#define MIO_EMM_DMA_INT_ENA_W1C(x) (0x48 + x->reg_off_dma) > > > > /* register addresses */ > > #define MIO_EMM_CFG(x) (0x00 + x->reg_off) > > @@ -39,6 +43,8 @@ > > #define MIO_EMM_SAMPLE(x) (0x90 + x->reg_off) > > #define MIO_EMM_STS_MASK(x) (0x98 + x->reg_off) > > #define MIO_EMM_RCA(x) (0xa0 + x->reg_off) > > +#define MIO_EMM_INT_EN_SET(x) (0xb0 + x->reg_off) > > +#define MIO_EMM_INT_EN_CLR(x) (0xb8 + x->reg_off) > > #define MIO_EMM_BUF_IDX(x) (0xe0 + x->reg_off) > > #define MIO_EMM_BUF_DAT(x) (0xe8 + x->reg_off) > > > > diff --git a/drivers/mmc/host/cavium-pci-thunderx.c b/drivers/mmc/host/cavium-pci-thunderx.c > > new file mode 100644 > > index 0000000..6ad36b4 > > --- /dev/null > > +++ b/drivers/mmc/host/cavium-pci-thunderx.c > > @@ -0,0 +1,198 @@ > > +/* > > + * Driver for MMC and SSD cards for Cavium ThunderX SOCs. > > + * > > + * This file is subject to the terms and conditions of the GNU General Public > > + * License. See the file "COPYING" in the main directory of this archive > > + * for more details. > > + * > > + * Copyright (C) 2016 Cavium Inc. > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include "cavium-mmc.h" > > + > > +struct platform_device *slot_pdev[2]; > > Let's not be lazy. We don't want global arrays of platform devices, > whatever the reason. OK, I'll move this into the host struct. > > + > > +static void thunder_mmc_acquire_bus(struct cvm_mmc_host *host) > > +{ > > + down(&host->mmc_serializer); > > +} > > + > > +static void thunder_mmc_release_bus(struct cvm_mmc_host *host) > > +{ > > + up(&host->mmc_serializer); > > +} > > + > > +static void thunder_mmc_int_enable(struct cvm_mmc_host *host, u64 val) > > +{ > > + writeq(val, host->base + MIO_EMM_INT(host)); > > + writeq(val, host->base + MIO_EMM_INT_EN_SET(host)); > > +} > > + > > +static int thunder_mmc_register_interrupts(struct cvm_mmc_host *host, > > + struct pci_dev *pdev) > > +{ > > + int nvec, ret, i; > > + > > + nvec = pci_alloc_irq_vectors(pdev, 1, 9, PCI_IRQ_MSIX); > > + if (nvec < 0) > > + return nvec; > > + > > + /* register interrupts */ > > + for (i = 0; i < nvec; i++) { > > + ret = devm_request_irq(&pdev->dev, pci_irq_vector(pdev, i), > > + cvm_mmc_interrupt, > > + 0, cvm_mmc_irq_names[i], host); > > + if (ret) > > + return ret; > > + } > > + return 0; > > +} > > + > > +static int thunder_mmc_probe(struct pci_dev *pdev, > > + const struct pci_device_id *id) > > +{ > > + struct device_node *node = pdev->dev.of_node; > > + struct device *dev = &pdev->dev; > > + struct device_node *child_node; > > + struct cvm_mmc_host *host; > > + int ret, i = 0; > > + > > + host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); > > + if (!host) > > + return -ENOMEM; > > + > > + pci_set_drvdata(pdev, host); > > + ret = pcim_enable_device(pdev); > > + if (ret) > > + return ret; > > + > > + ret = pci_request_regions(pdev, KBUILD_MODNAME); > > + if (ret) > > + return ret; > > + > > + host->base = pcim_iomap(pdev, 0, pci_resource_len(pdev, 0)); > > + if (!host->base) > > + return -EINVAL; > > + > > + /* On ThunderX these are identical */ > > + host->dma_base = host->base; > > + > > + host->reg_off = 0x2000; > > + host->reg_off_dma = 0x160; > > + > > + host->clk = devm_clk_get(dev, NULL); > > + if (IS_ERR(host->clk)) > > + return PTR_ERR(host->clk); > > + > > + ret = clk_prepare_enable(host->clk); > > + if (ret) > > + return ret; > > + host->sys_freq = clk_get_rate(host->clk); > > + > > + spin_lock_init(&host->irq_handler_lock); > > + sema_init(&host->mmc_serializer, 1); > > + > > + host->dev = dev; > > + host->acquire_bus = thunder_mmc_acquire_bus; > > + host->release_bus = thunder_mmc_release_bus; > > + host->int_enable = thunder_mmc_int_enable; > > + > > + host->big_dma_addr = true; > > + host->need_irq_handler_lock = true; > > + host->last_slot = -1; > > + > > + ret = dma_set_mask(dev, DMA_BIT_MASK(48)); > > + if (ret) > > + goto error; > > + > > + /* > > + * Clear out any pending interrupts that may be left over from > > + * bootloader. Writing 1 to the bits clears them. > > + */ > > + writeq(127, host->base + MIO_EMM_INT_EN(host)); > > + writeq(3, host->base + MIO_EMM_DMA_INT_ENA_W1C(host)); > > + > > + ret = thunder_mmc_register_interrupts(host, pdev); > > + if (ret) > > + goto error; > > + > > + for_each_child_of_node(node, child_node) { > > + /* > > + * TODO: mmc_of_parse and devm* require one device per slot. > > I guess the TODO is about fixing this behavior in the mmc core, such > we can use mmc_of_parse() in more flexible manner. You may want to > remove the "TODO", but please keep the comment. OK. > > + * Create a dummy device per slot and set the node pointer to > > + * the slot. The easiest way to get this is using > > + * of_platform_device_create. > > + */ > > + if (!slot_pdev[i]) > > + slot_pdev[i] = of_platform_device_create(child_node, NULL, > > + &pdev->dev); > > Seems like we should verify that this is a slot node, by checking the > compatible, before creating a platform device for it. No? Not sure I understand you correctly. Before creating the platform device I don't have a device for the slot. Looking at functions I could use to check the compatible all of these need a device, which I'm just going to create. Can you point me to a function I can use here? > > + if (!slot_pdev[i]) > > + continue; > > + ret = cvm_mmc_of_slot_probe(&slot_pdev[i]->dev, host); > > + if (ret) > > + goto error; > > + i++; > > + } > > + dev_info(dev, "probed\n"); > > + return 0; > > + > > +error: > > + clk_disable_unprepare(host->clk); > > + return ret; > > +} > > + > > +static void thunder_mmc_remove(struct pci_dev *pdev) > > +{ > > + struct cvm_mmc_host *host = pci_get_drvdata(pdev); > > + u64 dma_cfg; > > + int i; > > + > > + for (i = 0; i < CAVIUM_MAX_MMC; i++) > > + if (host->slot[i]) { > > + cvm_mmc_of_slot_remove(host->slot[i]); > > + platform_device_del(slot_pdev[i]); > > + } > > + > > + dma_cfg = readq(host->dma_base + MIO_EMM_DMA_CFG(host)); > > + dma_cfg &= ~MIO_EMM_DMA_CFG_EN; > > + writeq(dma_cfg, host->dma_base + MIO_EMM_DMA_CFG(host)); > > + > > + clk_disable_unprepare(host->clk); > > +} > > + > > +static const struct pci_device_id thunder_mmc_id_table[] = { > > + { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa010) }, > > + { 0, } /* end of table */ > > +}; > > + > > +static struct pci_driver thunder_mmc_driver = { > > + .name = KBUILD_MODNAME, > > + .id_table = thunder_mmc_id_table, > > + .probe = thunder_mmc_probe, > > + .remove = thunder_mmc_remove, > > +}; > > + > > +static int __init thunder_mmc_init_module(void) > > +{ > > + return pci_register_driver(&thunder_mmc_driver); > > +} > > + > > +static void __exit thunder_mmc_exit_module(void) > > +{ > > + pci_unregister_driver(&thunder_mmc_driver); > > +} > > + > > +module_init(thunder_mmc_init_module); > > +module_exit(thunder_mmc_exit_module); > > + > > +MODULE_AUTHOR("Cavium Inc."); > > +MODULE_DESCRIPTION("Cavium ThunderX eMMC Driver"); > > +MODULE_LICENSE("GPL"); > > +MODULE_DEVICE_TABLE(pci, thunder_mmc_id_table); > > -- > > 2.9.0.rc0.21.g7777322 > > > > Kind regards > Uffe