From patchwork Mon Apr 11 14:58:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georgi Djakov X-Patchwork-Id: 8803211 Return-Path: X-Original-To: patchwork-linux-arm@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 2BE5A9F54F for ; Mon, 11 Apr 2016 15:08:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 35A9E202B8 for ; Mon, 11 Apr 2016 15:08:54 +0000 (UTC) Received: from bombadil.infradead.org (unknown [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C84A9202F8 for ; Mon, 11 Apr 2016 15:08:52 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1apdJ4-0001IG-CV; Mon, 11 Apr 2016 14:59:14 +0000 Received: from mail-wm0-x235.google.com ([2a00:1450:400c:c09::235]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1apdIr-0001Cw-NF for linux-arm-kernel@lists.infradead.org; Mon, 11 Apr 2016 14:59:03 +0000 Received: by mail-wm0-x235.google.com with SMTP id f198so149474483wme.0 for ; Mon, 11 Apr 2016 07:58:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=M38TVSZzh+fu0zYPWlfq7fZd8B6K/ud/FRmzktI+qpQ=; b=eb0v++ZydamPnE5UdhScbbin8gs4vL5I/AyKUicTUNg55SbKMXuapy5nmJ9Fwfx5wj qCQFgRVRXd6Ax5vJlk9tXWZABlOl24r7HWBQpGqmg5t14PacOSxN8WXWytJhbRB5pSzZ mqXW6OXcgDBMg+l1DRgH4NhkularckVU66p4A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=M38TVSZzh+fu0zYPWlfq7fZd8B6K/ud/FRmzktI+qpQ=; b=Wat1CrxzCiAT0lD8RCMFlbKr9XmV1qPVKXTN5Hfs6+SOyFO7h86WJap1CWUyexBMNS yhL0LfrDoDJs2+DLNswimEGH9J5A/A8UT2GGKVptUbsTwao8gvYP4U6eKm15QOF2OXhk JEqEGhjFLPoMsPhziAIp0vH0ioP4ExgewwxjDRf8eALptB6PHrNA5KHq8jIFLRJSWLob EDK7Tv9BNz+PxUKFGmhDW3G+x67wOXC42gCFf6niYKnr+GUAvNnYQti4WQQFMxLsjZtY RmKqPEguqMe/nco8Y1a14TKNi83ycNbm2ETFDS2PmXRlgJg3O+R5X0hbZo+qqyXhGusc 5Z7g== X-Gm-Message-State: AD7BkJJ41st45hLQ0qehNzeZooG6jDzDxS4bwp1rwJUaHgSNq5Nxn1/YvKXKnPv89VAZa22+ X-Received: by 10.28.27.73 with SMTP id b70mr18885295wmb.19.1460386718974; Mon, 11 Apr 2016 07:58:38 -0700 (PDT) Received: from mms.qualcomm.mm-sol.com ([37.157.136.206]) by smtp.googlemail.com with ESMTPSA id qb8sm28332926wjc.24.2016.04.11.07.58.37 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 11 Apr 2016 07:58:37 -0700 (PDT) From: Georgi Djakov To: linux@arm.linux.org.uk Subject: [PATCH v1 1/2] amba: Defer device peripheral ID read Date: Mon, 11 Apr 2016 17:58:35 +0300 Message-Id: <1460386716-23262-1-git-send-email-georgi.djakov@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160411_075901_930041_86699979 X-CRM114-Status: GOOD ( 18.45 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-msm@vger.kernel.org, georgi.djakov@linaro.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, iivanov.xz@gmail.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RDNS_NONE,T_DKIM_INVALID,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 From: "Ivan T. Ivanov" To be able to read peripheral ID during device create time bus code have turn on device interface clock, but this clock could be unavailable at this time. Fix this by defer device ID read until driver match time. Signed-off-by: Ivan T. Ivanov Signed-off-by: Georgi Djakov --- drivers/amba/bus.c | 138 ++++++++++++++++++++++++++-------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index f0099360039e..a32a43dbaccc 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -24,11 +24,79 @@ #define to_amba_driver(d) container_of(d, struct amba_driver, drv) +static int amba_get_enable_pclk(struct amba_device *pcdev) +{ + int ret; + + pcdev->pclk = clk_get(&pcdev->dev, "apb_pclk"); + if (IS_ERR(pcdev->pclk)) + return PTR_ERR(pcdev->pclk); + + ret = clk_prepare_enable(pcdev->pclk); + if (ret) + clk_put(pcdev->pclk); + + return ret; +} + +static void amba_put_disable_pclk(struct amba_device *pcdev) +{ + clk_disable_unprepare(pcdev->pclk); + clk_put(pcdev->pclk); +} + +static int amba_read_periphid(struct amba_device *adev) +{ + resource_size_t size; + void __iomem *tmp; + int r, i; + + if (adev->periphid) + return 0; + + /* + * Dynamically calculate the size of the resource + * and use this for iomap + */ + size = resource_size(&adev->res); + tmp = ioremap(adev->res.start, size); + if (!tmp) + return -ENODEV; + + r = amba_get_enable_pclk(adev); + if (r == 0) { + u32 pid, cid; + + /* + * Read pid and cid based on size of resource + * they are located at end of region + */ + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << + (i * 8); + for (cid = 0, i = 0; i < 4; i++) + cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << + (i * 8); + + amba_put_disable_pclk(adev); + + if (cid == AMBA_CID || cid == CORESIGHT_CID) + adev->periphid = pid; + } + + iounmap(tmp); + + return adev->periphid ? 0 : -ENODEV; +} + static const struct amba_id * amba_lookup(const struct amba_id *table, struct amba_device *dev) { int ret = 0; + if (amba_read_periphid(dev)) + return NULL; + while (table->mask) { ret = (dev->periphid & table->mask) == table->id; if (ret) @@ -204,27 +272,6 @@ static int __init amba_init(void) postcore_initcall(amba_init); -static int amba_get_enable_pclk(struct amba_device *pcdev) -{ - int ret; - - pcdev->pclk = clk_get(&pcdev->dev, "apb_pclk"); - if (IS_ERR(pcdev->pclk)) - return PTR_ERR(pcdev->pclk); - - ret = clk_prepare_enable(pcdev->pclk); - if (ret) - clk_put(pcdev->pclk); - - return ret; -} - -static void amba_put_disable_pclk(struct amba_device *pcdev) -{ - clk_disable_unprepare(pcdev->pclk); - clk_put(pcdev->pclk); -} - /* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. @@ -347,9 +394,7 @@ static void amba_device_release(struct device *dev) */ int amba_device_add(struct amba_device *dev, struct resource *parent) { - u32 size; - void __iomem *tmp; - int i, ret; + int ret; WARN_ON(dev->irq[0] == (unsigned int)-1); WARN_ON(dev->irq[1] == (unsigned int)-1); @@ -358,51 +403,6 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) if (ret) goto err_out; - /* Hard-coded primecell ID instead of plug-n-play */ - if (dev->periphid != 0) - goto skip_probe; - - /* - * Dynamically calculate the size of the resource - * and use this for iomap - */ - size = resource_size(&dev->res); - tmp = ioremap(dev->res.start, size); - if (!tmp) { - ret = -ENOMEM; - goto err_release; - } - - ret = amba_get_enable_pclk(dev); - if (ret == 0) { - u32 pid, cid; - - /* - * Read pid and cid based on size of resource - * they are located at end of region - */ - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << - (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << - (i * 8); - - amba_put_disable_pclk(dev); - - if (cid == AMBA_CID || cid == CORESIGHT_CID) - dev->periphid = pid; - - if (!dev->periphid) - ret = -ENODEV; - } - - iounmap(tmp); - - if (ret) - goto err_release; - - skip_probe: ret = device_add(&dev->dev); if (ret) goto err_release;