Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751174AbdCQNfI (ORCPT ); Fri, 17 Mar 2017 09:35:08 -0400 Received: from mail-by2nam01on0065.outbound.protection.outlook.com ([104.47.34.65]:36138 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750998AbdCQNfG (ORCPT ); Fri, 17 Mar 2017 09:35:06 -0400 Authentication-Results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=caviumnetworks.com; Date: Fri, 17 Mar 2017 14:34:53 +0100 From: Jan Glauber To: Ulf Hansson Cc: "linux-mmc@vger.kernel.org" , "linux-kernel@vger.kernel.org" , David Daney , "Steven J . Hill" , David Daney Subject: Re: [PATCH v12 2/9] mmc: cavium: Add core MMC driver for Cavium SOCs Message-ID: <20170317133453.GA2739@hardcore> References: <20170310132507.32025-1-jglauber@cavium.com> <20170310132507.32025-3-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: [88.67.130.225] X-ClientProxiedBy: DB6PR0501CA0003.eurprd05.prod.outlook.com (10.172.232.141) To CO2PR07MB2582.namprd07.prod.outlook.com (10.166.201.21) X-MS-Office365-Filtering-Correlation-Id: e56309e8-4d96-4965-c255-08d46d3a6b0c X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:CO2PR07MB2582; X-Microsoft-Exchange-Diagnostics: 1;CO2PR07MB2582;3:/BsAu2Qy5w+hVcFHSVbbOqa4LXlDfbo9Im9LUNQDMkAAwX1FW9Ys+Cr7J21JO+7SniWjdCA6K3SqXd9QUzL6VS7S8nbkZv6QtH/H7VAYdCKU5qnWfzMK7rnaRZZ4D/nz/0Rs/7FrydK92Jjw87A8WXB9n8+HPnlxaTZXAXNElVH2+OssCj7Fa6jcwn1NiQKzGDeCIpoA5PbNpZaKDVa5JYO8aG89477oc0ypP7EpxFMN/EYEPyhzNON4lc0PXBHdA8PNIt6TZ24bnRHCwVIdJA==;25:2qXTIOeGRHAeVDx0QYROUnnDjrrB8VaY/6MNgk51c925UsZxwLozPjYvDe+oZrl9q00Dus5RGkZ9If0Dt3StWWL9xDpZvHiu9BFOky1wueeTEt8zbh64P/AoF0JTalLieVJjG4UCTUHxlD8ikYtkFQ8ulwIiYhG9ayt+4CHbSaXxgKbRPJGWwFwolcIRz6mgwwZKZWORBXz1alxDTwH06NVOOR5nUTo8W3yesNDb9Z/9pX/xPWOUM26HEl/Ia/pWZCpN1g2b1WD5zqyCaiA9x8y57/xopFJUjm9+8AqL9gYi9CnP4znRRP7LVq/lMs53WvV4mpBko81RMdk262PsUMNo6r6w37wKetE53LK8BuL3dbsL61dys7hppWJTjkBoH3PThYSXuXp+fx4cxfpp+DiOc7RKKL2TawnNkRGU7eXbIqTgE2y7f22PInmU/bsPEUNK+HaFUMqSdmIfvg8g4w== X-Microsoft-Exchange-Diagnostics: 1;CO2PR07MB2582;31:PGlwyvNn4GK/JM6sjIVViyG6mcBcFTey5x4qMnZV7KT+y07FNXYxNiRzxatUrJHVNJ3lX1kFyKwb7d6EYwaLAtd6SQztLYuR9xpYTsiNNNoqDPsslxVhjaixmCF+w3FWIaesieVhB5lNXw5STU90ulA0SvGT5t9rd38p8QcSCYC37ds0mRUvBKDdz48NSpPe/KXIHbatYU6drDjl4XyIC7m/SpCTOu81ubHf/tzNXUk=;20:SWkc9+bCmTU7ktiNgTpmf4Bq0kCvJREuWtP6rPrlXozz9PqDYyT9RzLzbgYKdN6tYht0bWs2tCeFMkGIyLJOXnHgm6Q4PhAECTVLIGMMcBgft96GUVNuWgMZgHe2wpatb3PhJ/HVzbd+GNLtxA3TBtHHxhF9I1vQVjUDyO2FUF0ZOqQbdDkXqfqfoop1/CQXifSydxcCaJuF2nHt44bC9AVnpBQuT6ulugC1f9l+3TnNIR20lXDK2GLtCk3CSls2f7Y6qcOYXTsxfMbX8dlyF5wi8bwFhc7CDlFx2tJNBdKbHM/Ae9khFf5XYZcHiMSKfQTb0BafcbaJUe9wktvGqGGbRRBjMLlXYqI7ZNqI6W0ZC8ysduuCFfkqM4GOd5VtXz7bET0lcFgkYljBSzzt2MgquTG8zz3JG9elN5B5JdAmbVyeMOVlYRrtsfs8b+6XP4QrBThkK1RPlp50f6wcvaSPd9jZA81JhrUhr6SgSjrqETowBKQkHi1L9ArGTe+PJLny6fuFD3qWSmN8WBzBLkNvAStKj+ioUlakccWDnpaO9+r0+ldAfCg+BV/+j6oUjauCiD92owyBlj0NEAwSAfC8hE23+c4TwHSbj3xfUGo= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6041248)(20161123564025)(20161123555025)(20161123562025)(20161123560025)(20161123558025)(6072148);SRVR:CO2PR07MB2582;BCL:0;PCL:0;RULEID:;SRVR:CO2PR07MB2582; X-Microsoft-Exchange-Diagnostics: 1;CO2PR07MB2582;4:aF+PYMBNeAle3pQu6tAiQ2mGgTCOJU9H2g4JIqn0gCjaoL+9qKZ9tAKUCkU4AlhOhKrqV5vL5S3WIAS1yjB6RnYiyz4Ef4TP/5MzcNBMjJy5SojzJwPLGV5dOFla5+rL7oVtIT7O5PpcyKL9yrb3nUCBd/u8OYW2SWLBmYRjlaHeRB5uv2Xf3ZS6PSan25iR0rK/jX4ZHI5cxsa87M9WWVgtpu2CucC+iBXmDrHCIL7H6bv7szb9Hw69nb4zlqJoDD+MuD0CO+Rl4AT5jymU6QAJPmrJFPKAzBxkX/X9h2aIgQuiUV2yKxgu7r5gk4Aqfx1LAoBj1qv8HFHzFYuLS6h1tWsY/qLawgbTzWQToeZjyOtvLzXn5U8f+L43GVfs5pirSWtF50i30Mdz9i3/rDKmJd7NjWCgbbtJqRFR4Tmu0NvUXzxa9MgiuLasis/np1ggnDzciryUzwImxHV98/tEqy0+N8zj3zV1MsM/cDjWfoYt21n6LGHSa2Ieu+bHTUYCn3y6sutYk2oaLi7R1oaaxwfhfYL7Ld12gISgKQag7J3RV2ghRXhSs2E+eLOa5esbAaEtqQkaORnW58jSGpSs2nNyf+Q1dd1pBzzp9SA= X-Forefront-PRVS: 0249EFCB0B X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(39830400002)(39410400002)(39450400003)(24454002)(51914003)(54534003)(33716001)(23726003)(66066001)(81166006)(110136004)(3846002)(76176999)(8676002)(53936002)(107886003)(54356999)(47776003)(7736002)(6496005)(53546008)(4326008)(38730400002)(42186005)(305945005)(189998001)(4001350100001)(6246003)(50986999)(9686003)(2950100002)(1076002)(50466002)(25786008)(83506001)(5660300001)(6666003)(6916009)(2906002)(229853002)(42882006)(55016002)(33656002)(6116002)(54906002)(18370500001);DIR:OUT;SFP:1101;SCL:1;SRVR:CO2PR07MB2582;H:hardcore;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CO2PR07MB2582;23:c/mnTEMNvZDzoNIFwKqYBBMulPHFeyR4gFmi+HuZV?= =?us-ascii?Q?9K19Z0w3ybUzkkzKglJj4iuhnDe/gBb/gqDQzb/cuHNpGBZjBs0PdJxCKJ+p?= =?us-ascii?Q?HTy7QhWpv9s1HJjOpJGHCrlBUET6cGXQywk9mIsoXDYxm+gN8elO+587aV/+?= =?us-ascii?Q?GVucfTtg3rdeg0QC9k0VDnTnSgYhSCnPwh86q7tFhCGDchuD66NkCvzuiZXM?= =?us-ascii?Q?sLvVmnikg5vUDqPMhAJU/XyxVPz4oeQ6MGKi6w/HBZBCQ/6Ms2WmEfKoPDkj?= =?us-ascii?Q?iZ+g45zzTdL+0q5ny4mhgPwwXY7KeLoA7t7l2HW4LZ0xHrskEL65ZD+xdOxZ?= =?us-ascii?Q?eC3dafYU+NnXlrEOcYxJ03kNOOUSKdLqkLfUlJZ+GrDpTTzCLOfpfWyZC9ff?= =?us-ascii?Q?vZPbc8GEhkFyRX9D2ZKRNeFzK3Q3sfnuwMSpqXY9x8fvY9jhT7k25VNlOn7t?= =?us-ascii?Q?LPv0vIw1C+wKct7pQpRn/vd0oWU+zedrlH7erV04XUQnWtiD+rIR6zUrgnhM?= =?us-ascii?Q?MtPi64aht2sjZ242X1UGawO6uZ0FU3oCagrIBZHAXJUVhO5kqOqVQLuI18iS?= =?us-ascii?Q?mk1C2sjxRkJ0H6IqlpxMZIXz2oxl61yYoa9qLTlKUuRltXAna7iqH7Hd1QDg?= =?us-ascii?Q?RHJCWiTWYaCLEWWU25tbLrlZVaknpWRJsSpRFWHszE5DnZfwsfOMElVl6td6?= =?us-ascii?Q?cWUnDYzbI+1vgO0QuqNY3izs/rBBf4uYYLipNxg7Jqh7a0TLFu/zQMSAVrUd?= =?us-ascii?Q?IWhPw+97bsUNGyL3sfskuFTbMEmyZIV2JkSlrDbw7kSZ6dcmQAuVGKJuiDeZ?= =?us-ascii?Q?3dGrFBTUagfjP3FXxiWJbBXhcvUqsYH8+i/t1qAzKg2M0IBm+8mK3aVBrY6X?= =?us-ascii?Q?QGMzmJ8F+2ItMd7PVsz2UYWVyHXGNVlgigDD+nzDggrzC1uOdU5bTv4Din16?= =?us-ascii?Q?kcy4pX8zJQ+T81Gtu8Koh2RrFfizpXKY/mhFTd4YOGk+X32uHwqRkN+cPw0i?= =?us-ascii?Q?FmbZoqOqvfwSD84YPauS1ontACqmsK+EQlf/mwVnT6Y9tYz+KcF8KGdMyZf0?= =?us-ascii?Q?NsMYJdypi+7VS8HYJyBdYFZRCRzWmEZBEYp2AB8/SXNwnxbV42lAiDJ1/r82?= =?us-ascii?Q?vH/uzjg+l3fsYRq8erBAtVmTySEcR0nSf7zcVOApXOe4DN7t5cNcNg6eeGUJ?= =?us-ascii?Q?+aCkrTO3dfY1+Q=3D?= X-Microsoft-Exchange-Diagnostics: 1;CO2PR07MB2582;6:E13U+j9Dj/NJP9kBOjr12a3L9fGxNNaif7HnrVQVMsLsWuIx24FZZai6noKk0I8swo5BTqNjyEhj3EFXml5uIf6vWLeRVxdYgXerKIQ/nJwpbDAJB2y+1WLN/n6EM/HbIjJlst/gZ/vGKliaQKiUbPcipFA3kRDUytpMXLF2DJDfNSMbtxlVcd6qInY3/vHnKcITccENAuekR0BZAn+YeCZdZDDlfdU+BzulfXdjhIDPpHn/j42ghmHIiLXQTK/NLFwmsCv9V7RgWr/zfrM3w6l8rur3DWc4TJ7PJUG4Sbsm1iRAZhZCvEFpiq11aFQDZ7MzPrQ4wZ7Az8BG2Wq8sZ74TrJMZvjJfhkcVrqHUB1vFHGyxSzNYzcgc0sgi1evMigMeelzms0aNyLsuuMc+A==;5:GUfCAD8H0KwWMMk5je1UmZ+e4iBuxkV2IbuiGweLKLqmpZvMsOMCkl9RLOp0FDd6itMk1YBgFI96u6cNT6/Mt0l6IQpoKBa7o4pAE1Ckdg6AWwkUJtYBiX5/3645CWn+IggufaYJlPYjCerh1bTbbQ==;24:hxDz9AJPAxPU1/sySXwYzzknzpSwElfayYZYG6CNgNJCNoqqm/wRvTPxsQhQkBhthvwzDz/wzAkzCDg5qc9h/xBgnCCPnmPeeHN0KfauV4U= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CO2PR07MB2582;7:KAbjDWFfH5j5kLVHHzsZfsI+8y37zLAOfIu+e1nB10LQcJ7AL5ijHSwgOPStXfC3WFJbzrBoCbkCbJozzvcupKv5mr4+U3/uA1em9O3CXOo1m5pnGLd9lV9iyen+bAbZaoslcfd4wHJqzH6NIS5trft1/lYf8xk6aUTCiREhlX0X4vmIrhBz5ywnSZIxzdT1pSxjbtXFRjOrozi3N867GQKsIs3r++knwvgS/hVZLCTZYBw/qAI/BSfYS4kR1wsYVyfn5N3aZiMSBVinEEXUF3zTsRgGO+BeQkSEomIz0LH8cCbLH240UABKgBaehalxXsirvvVWfOSGTzWxRdo5uA== X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Mar 2017 13:35:01.9876 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO2PR07MB2582 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 10994 Lines: 325 On Fri, Mar 17, 2017 at 12:24:57PM +0100, Ulf Hansson wrote: > On 10 March 2017 at 14:25, Jan Glauber wrote: > > This core driver will be used by a MIPS platform driver > > or by an ARM64 PCI driver. The core driver implements the > > mmc_host_ops and slot probe & remove functions. > > Callbacks are provided to allow platform specific interrupt > > enable and bus locking. > > > > The host controller supports: > > - up to 4 slots that can contain sd-cards or eMMC chips > > - 1, 4 and 8 bit bus width > > - SDR and DDR > > - transfers up to 52 Mhz (might be less when multiple slots are used) > > - DMA read/write > > - multi-block read/write (but not stream mode) > > > > Voltage is limited to 3.3v and shared for all slots (vmmc and vmmcq). > > > > A global lock for all MMC devices is required because the host > > controller is shared. > > > > Signed-off-by: Jan Glauber > > Signed-off-by: David Daney > > Signed-off-by: Steven J. Hill > > --- > > drivers/mmc/host/cavium-mmc.c | 988 ++++++++++++++++++++++++++++++++++++++++++ > > drivers/mmc/host/cavium-mmc.h | 178 ++++++++ > > 2 files changed, 1166 insertions(+) > > create mode 100644 drivers/mmc/host/cavium-mmc.c > > create mode 100644 drivers/mmc/host/cavium-mmc.h > > > > diff --git a/drivers/mmc/host/cavium-mmc.c b/drivers/mmc/host/cavium-mmc.c > > new file mode 100644 > > index 0000000..11fdcfb > > --- /dev/null > > +++ b/drivers/mmc/host/cavium-mmc.c > > @@ -0,0 +1,988 @@ > > +/* > > + * Shared part of driver for MMC/SDHC controller on Cavium OCTEON and > > + * 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) 2012-2017 Cavium Inc. > > + * Authors: > > + * David Daney > > + * Peter Swain > > + * Steven J. Hill > > + * Jan Glauber > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include "cavium-mmc.h" > > + > > +const char *cvm_mmc_irq_names[] = { > > + "MMC Buffer", > > + "MMC Command", > > + "MMC DMA", > > + "MMC Command Error", > > + "MMC DMA Error", > > + "MMC Switch", > > + "MMC Switch Error", > > + "MMC DMA int Fifo", > > + "MMC DMA int", > > +}; > > Debug-leftover? > > [...] No, this is used by both Octeon and ThunderX drivers. Maybe I should have put it into an extra patch. > > + > > +static void cvm_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > > +{ > > + struct cvm_mmc_slot *slot = mmc_priv(mmc); > > + struct cvm_mmc_host *host = slot->host; > > + int clk_period = 0, power_class = 10, bus_width = 0; > > + u64 clock, emm_switch; > > + > > + host->acquire_bus(host); > > + cvm_mmc_switch_to(slot); > > + > > + /* Set the power state */ > > + switch (ios->power_mode) { > > + case MMC_POWER_ON: > > + break; > > + > > + case MMC_POWER_OFF: > > + cvm_mmc_reset_bus(slot); > > + > > + if (host->global_pwr_gpiod) > > + gpiod_set_value_cansleep(host->global_pwr_gpiod, 0); > > If I have understood the changelog correctly this GPIO is shared for > all slots, right? Yes. > In such case, this doesn't work. You need to centralize the management > of this GPIO pin (to enable reference counting), as otherwise one slot > can decide to power off its card while another still uses their card > and expecting the power to be on. OK. I could create a function in the shared part with ref counting. On the other side, only the existing Octeon HW will use the global_pwr_gpiod, and this HW only has one slot. For all new HW we'll use the GPIO regulator, so I think it is not worth changing it. I'll add a comment. > Another option would be to model it as GPIO regulator (using a device > tree overlay as we discussed earlier), then you get the reference > counting for free - and easily get ocr_avail mask from the mmc core's > regulator API. :-) > No, this is what I already do in case host->global_pwr_gpiod is not set. > Moreover, I didn't find this GPIO being documented as a DT binding, it > should and it should also be marked as deprecated. Good point, I'll add it. > > + else > > + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); > > + break; > > + > > + case MMC_POWER_UP: > > + if (host->global_pwr_gpiod) > > + gpiod_set_value_cansleep(host->global_pwr_gpiod, 1); > > Dittto. > > > + else > > + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); > > + break; > > + } > > + > > [...] > > > + > > +static int cvm_mmc_of_parse(struct device *dev, struct cvm_mmc_slot *slot) > > +{ > > + u32 id, cmd_skew = 0, dat_skew = 0, bus_width = 0, f_max = 0; > > + struct device_node *node = dev->of_node; > > + struct mmc_host *mmc = slot->mmc; > > + u64 clock_period; > > + int ret; > > + > > + ret = of_property_read_u32(node, "reg", &id); > > + if (ret) { > > + dev_err(dev, "Missing or invalid reg property on %s\n", > > + of_node_full_name(node)); > > + return ret; > > + } > > + > > + if (id >= CAVIUM_MAX_MMC || slot->host->slot[id]) { > > + dev_err(dev, "Invalid reg property on %s\n", > > + of_node_full_name(node)); > > + return -EINVAL; > > + } > > + > > + /* Deprecated Cavium bindings for old firmware */ > > + of_property_read_u32(node, "cavium,bus-max-width", &bus_width); > > + of_property_read_u32(node, "spi-max-frequency", &f_max); > > + if (slot->host->global_pwr_gpiod) { > > + /* Get a sane OCR mask for other parts of the MMC subsytem. */ > > + ret = mmc_of_parse_voltage(node, &mmc->ocr_avail); > > I noticed your comment to Arnd for the cover-letter. So I assume you > will remove this and instead assign mmc->ocr_avail a default value in > cases when you don't have a vmmc regulator to find it from. Yes. > > + if (ret < 0) > > + return ret; > > + } > > + > > + /* Cavium-specific DT properties */ > > + of_property_read_u32(node, "cavium,cmd-clk-skew", &cmd_skew); > > + of_property_read_u32(node, "cavium,dat-clk-skew", &dat_skew); > > + > > + if (!slot->host->global_pwr_gpiod) { > > + mmc->supply.vmmc = devm_regulator_get(dev, "vmmc"); > > + if (IS_ERR(mmc->supply.vmmc)) > > + return PTR_ERR(mmc->supply.vmmc); > > + > > + ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc); > > + if (ret > 0) > > + mmc->ocr_avail = ret; > > + } > > + > > + /* Common MMC bindings */ > > + ret = mmc_of_parse(mmc); > > + if (ret) > > + return ret; > > + > > + /* Set bus width */ > > + if (!bus_width) { > > + if (mmc->caps & MMC_CAP_8_BIT_DATA) > > + bus_width = 8; > > + else if (mmc->caps & MMC_CAP_4_BIT_DATA) > > + bus_width = 4; > > + else > > + bus_width = 1; > > + } > > + > > + switch (bus_width) { > > + case 8: > > + slot->bus_width = 2; > > Why do you need to store this in slot struct? The information is > already available in the mmc host. I guess it is in the slot because the HW encoding is different from the mmc bus width. Let me see if removing it simplifies the code. > > + slot->mmc->caps = MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; > > This is wrong, as you will clear all the other mmc caps potentially > assigned by mmc_of_parse() above. Good catch. > Moreover, you can use mmc->caps instead of slot->mmc->caps. Yup. > > + break; > > + case 4: > > + slot->bus_width = 1; > > + slot->mmc->caps = MMC_CAP_4_BIT_DATA; > > + break; > > + case 1: > > + slot->bus_width = 0; > > + break; > > + } > > I would rather make the deprecated bindings to take the lowest > precedence and besides, this bus_width setup looks messy. How about > something like this instead: Previously you said I should parse deprecated bindings first, so I did that ;- > mmc_of_parse(); > > if (!(mmc->caps & (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA))) { > of_property_read_u32(node, "cavium,bus-max-width", &bus_width); > if (bus_width == 8) > mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA; > else if (bus_width == 4) > mmc->caps |= MMC_CAP_4_BIT_DATA; > } OK. > > + > > + /* Set maximum and minimum frequency */ > > + if (f_max) > > + mmc->f_max = f_max; > > Again, let's make sure the deprecated bindings takes lower precedence. > Thus if mmc->f_max has a value let's use that and if not, then parse > the deprecated DT binding and use that value instead. OK. > > + if (!mmc->f_max || mmc->f_max > 52000000) > > + mmc->f_max = 52000000; > > + mmc->f_min = 400000; > > + > > + /* Sampling register settings, period in picoseconds */ > > + clock_period = 1000000000000ull / slot->host->sys_freq; > > + slot->cmd_cnt = (cmd_skew + clock_period / 2) / clock_period; > > + slot->dat_cnt = (dat_skew + clock_period / 2) / clock_period; > > + > > + return id; > > +} > > [...] > > > diff --git a/drivers/mmc/host/cavium-mmc.h b/drivers/mmc/host/cavium-mmc.h > > new file mode 100644 > > index 0000000..c3843448 > > --- /dev/null > > +++ b/drivers/mmc/host/cavium-mmc.h > > [...] > > + > > +/* Protoypes */ > > +irqreturn_t cvm_mmc_interrupt(int irq, void *dev_id); > > +int cvm_mmc_of_slot_probe(struct device *dev, struct cvm_mmc_host *host); > > +int cvm_mmc_of_slot_remove(struct cvm_mmc_slot *slot); > > +extern const char *cvm_mmc_irq_names[]; > > Debug leftover? No, as I said before this is the interface I need for sharing cavium-mmc.c and using it from the Octeon and ThunderX drivers. Should I put the interface into a separate patch (together with the interrupt names)? Thanks for the review! Jan > Kind regards > Uffe