From patchwork Wed Sep 18 13:24:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 2907201 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id ED2E99F1BF for ; Wed, 18 Sep 2013 14:32:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C0E942022D for ; Wed, 18 Sep 2013 14:32:40 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7CDF7201BC for ; Wed, 18 Sep 2013 14:32:39 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VMHok-0006an-23; Wed, 18 Sep 2013 13:29:20 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VMHnv-0002br-N3; Wed, 18 Sep 2013 13:28:27 +0000 Received: from mail-bk0-f42.google.com ([209.85.214.42]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VMHmg-0002Pr-7D for linux-arm-kernel@lists.infradead.org; Wed, 18 Sep 2013 13:27:12 +0000 Received: by mail-bk0-f42.google.com with SMTP id my10so2800158bkb.15 for ; Wed, 18 Sep 2013 06:26:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qGUzxlzBGVxioF5be096o8borPTa7AXLzPFt0Po++aQ=; b=O8U+80oLus+TdBmRjWY4AdzJdflcSE4XbY9h8/pOJveWaj+l07NP2vUrLnhpCEsIi8 tIlAZuuKpeauOHaNHkLHHnqzLZnlBK1cxwpdjMpUwVTarctzoNL+KUzQCstkoA3fYqz8 3yIFT70GYBlZlSB2zSuZ4ASmw1Qi348cMY8NJJtvWe1Zlsh/02xRyyQ8mF9wPA0wEU2I Xq5pwuN36kPWTA1vcC/oGqDOF0tv7wkzL2iCYL3YCA1q15PGKq3QxYMJWhC21k+R++sC tLCk2CDh30elOfdaiohtGW0ODSSS5P+OBIRLJGYchXjvu08oSqAHMnH/pHYUltmBnWDR FPdw== X-Received: by 10.205.10.132 with SMTP id pa4mr33988060bkb.15.1379510792748; Wed, 18 Sep 2013 06:26:32 -0700 (PDT) Received: from localhost (port-55509.pppoe.wtnet.de. [46.59.217.135]) by mx.google.com with ESMTPSA id no2sm899090bkb.15.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 18 Sep 2013 06:26:32 -0700 (PDT) From: Thierry Reding To: Rob Herring , Grant Likely , Greg Kroah-Hartman , Thomas Gleixner Subject: [PATCH v2 09/10] of/i2c: Resolve interrupt references at probe time Date: Wed, 18 Sep 2013 15:24:51 +0200 Message-Id: <1379510692-32435-10-git-send-email-treding@nvidia.com> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1379510692-32435-1-git-send-email-treding@nvidia.com> References: <1379510692-32435-1-git-send-email-treding@nvidia.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130918_092710_429675_19EC60D3 X-CRM114-Status: GOOD ( 15.48 ) X-Spam-Score: 0.9 (/) Cc: linux-mips@linux-mips.org, Russell King , devicetree@vger.kernel.org, Benjamin Herrenschmidt , linux-kernel@vger.kernel.org, Ralf Baechle , sparclinux@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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=-1.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, KHOP_BIG_TO_CC, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=no 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 Instead of resolving interrupt references at device creation time, delay resolution until probe time. At device creation time, there is nothing that can be done if an interrupt parent isn't ready yet, and the device will end up with an invalid interrupt number (0). If the interrupt reference is resolved at probe time, the device's probe can be deferred, so that it's interrupt resolution can be retried after more devices (possibly including its interrupt parent) have been probed. However, individual drivers shouldn't be required to do that themselves, over and over again, so this commit implements this functionality within the I2C core. Signed-off-by: Thierry Reding --- Changes in v2: - use __irq_of_parse_and_map() instead of of_irq_get() drivers/i2c/i2c-core.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 29d3f04..5b4f289 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -236,6 +236,22 @@ int i2c_recover_bus(struct i2c_adapter *adap) return adap->bus_recovery_info->recover_bus(adap); } +static int of_i2c_probe(struct i2c_client *client) +{ + struct device_node *np = client->dev.of_node; + int ret; + + /* skip if the device node specifies no interrupts */ + if (of_get_property(np, "interrupts", NULL)) { + ret = __irq_of_parse_and_map(client->dev.of_node, 0, + &client->irq); + if (ret) + return ret; + } + + return 0; +} + static int i2c_device_probe(struct device *dev) { struct i2c_client *client = i2c_verify_client(dev); @@ -254,6 +270,12 @@ static int i2c_device_probe(struct device *dev) client->flags & I2C_CLIENT_WAKE); dev_dbg(dev, "probe\n"); + if (IS_ENABLED(CONFIG_OF) && dev->of_node) { + status = of_i2c_probe(client); + if (status) + return status; + } + status = driver->probe(client, i2c_match_id(driver->id_table, client)); if (status) { client->driver = NULL; @@ -1002,7 +1024,6 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) continue; } - info.irq = irq_of_parse_and_map(node, 0); info.of_node = of_node_get(node); info.archdata = &dev_ad; @@ -1016,7 +1037,6 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) dev_err(&adap->dev, "of_i2c: Failure registering %s\n", node->full_name); of_node_put(node); - irq_dispose_mapping(info.irq); continue; } }