From patchwork Mon Jun 30 09:07:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 4446841 Return-Path: X-Original-To: patchwork-linux-mmc@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 3DBBBBEEAA for ; Mon, 30 Jun 2014 09:08:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5B22A20176 for ; Mon, 30 Jun 2014 09:08:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 52ED3202F8 for ; Mon, 30 Jun 2014 09:08:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754943AbaF3JIS (ORCPT ); Mon, 30 Jun 2014 05:08:18 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23807 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753017AbaF3JIP (ORCPT ); Mon, 30 Jun 2014 05:08:15 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5U97bK3013528 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 30 Jun 2014 05:07:37 -0400 Received: from shalem.localdomain.com (vpn1-4-214.ams2.redhat.com [10.36.4.214]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5U97Qmk008116; Mon, 30 Jun 2014 05:07:34 -0400 From: Hans de Goede To: Chris Ball , Ulf Hansson , Mike Turquette Cc: Arend van Spriel , Maxime Ripard , Sascha Hauer , linux-mmc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree , linux-sunxi@googlegroups.com, Hans de Goede Subject: [PATCH resend v3 2/2] mmc: Add SDIO function devicetree subnode parsing Date: Mon, 30 Jun 2014 11:07:25 +0200 Message-Id: <1404119245-5839-3-git-send-email-hdegoede@redhat.com> In-Reply-To: <1404119245-5839-1-git-send-email-hdegoede@redhat.com> References: <1404119245-5839-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, 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: Sascha Hauer This adds SDIO devicetree subnode parsing to the mmc core. While SDIO devices are runtime probable they sometimes need nonprobable additional information on embedded systems, like an additional gpio interrupt or a clock. This patch makes it possible to supply this information from the devicetree. SDIO drivers will find a pointer to the devicenode in their devices of_node pointer. Signed-off-by: Sascha Hauer [hdegoede@redhat.com: Misc. cleanups] Signed-off-by: Hans de Goede --- drivers/mmc/core/bus.c | 4 ++++ drivers/mmc/core/core.c | 28 ++++++++++++++++++++++++++++ drivers/mmc/core/core.h | 3 +++ drivers/mmc/core/sdio_bus.c | 11 +++++++++++ 4 files changed, 46 insertions(+) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index d2dbf02..3b2fca9 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -360,6 +361,8 @@ int mmc_add_card(struct mmc_card *card) #endif mmc_init_context_info(card->host); + card->dev.of_node = mmc_of_find_child_device(card->host, 0); + ret = device_add(&card->dev); if (ret) return ret; @@ -388,6 +391,7 @@ void mmc_remove_card(struct mmc_card *card) mmc_hostname(card->host), card->rca); } device_del(&card->dev); + of_node_put(card->dev.of_node); } put_device(&card->dev); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 7dc0c85..ca2577d 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1205,6 +1205,34 @@ EXPORT_SYMBOL(mmc_of_parse_voltage); #endif /* CONFIG_OF */ +static int mmc_of_get_func_num(struct device_node *node) +{ + u32 reg; + int ret; + + ret = of_property_read_u32(node, "reg", ®); + if (ret < 0) + return ret; + + return reg; +} + +struct device_node *mmc_of_find_child_device(struct mmc_host *host, + unsigned func_num) +{ + struct device_node *node; + + if (!host->parent || !host->parent->of_node) + return NULL; + + for_each_child_of_node(host->parent->of_node, node) { + if (mmc_of_get_func_num(node) == func_num) + return node; + } + + return NULL; +} + #ifdef CONFIG_REGULATOR /** diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 443a584..f712f6e 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -32,6 +32,9 @@ struct mmc_bus_ops { void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); void mmc_detach_bus(struct mmc_host *host); +struct device_node *mmc_of_find_child_device(struct mmc_host *host, + unsigned func_num); + void mmc_init_erase(struct mmc_card *card); void mmc_set_chip_select(struct mmc_host *host, int mode); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 4fa8fef9..4032d25 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -21,7 +21,9 @@ #include #include #include +#include +#include "core.h" #include "sdio_cis.h" #include "sdio_bus.h" @@ -302,6 +304,13 @@ static void sdio_acpi_set_handle(struct sdio_func *func) static inline void sdio_acpi_set_handle(struct sdio_func *func) {} #endif +static void sdio_set_of_node(struct sdio_func *func) +{ + struct mmc_host *host = func->card->host; + + func->dev.of_node = mmc_of_find_child_device(host, func->num); +} + /* * Register a new SDIO function with the driver model. */ @@ -311,6 +320,7 @@ int sdio_add_func(struct sdio_func *func) dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); + sdio_set_of_node(func); sdio_acpi_set_handle(func); ret = device_add(&func->dev); if (ret == 0) { @@ -334,6 +344,7 @@ void sdio_remove_func(struct sdio_func *func) acpi_dev_pm_detach(&func->dev, false); device_del(&func->dev); + of_node_put(func->dev.of_node); put_device(&func->dev); }