From patchwork Fri Feb 6 12:12:52 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Hunter X-Patchwork-Id: 5790531 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 12AF9BF440 for ; Fri, 6 Feb 2015 12:15:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1E8D620122 for ; Fri, 6 Feb 2015 12:15:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 08B7620172 for ; Fri, 6 Feb 2015 12:15:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756714AbbBFMPN (ORCPT ); Fri, 6 Feb 2015 07:15:13 -0500 Received: from mga01.intel.com ([192.55.52.88]:13434 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756719AbbBFMPH (ORCPT ); Fri, 6 Feb 2015 07:15:07 -0500 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP; 06 Feb 2015 04:14:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="450770797" Received: from ahunter-desktop.fi.intel.com ([10.237.72.97]) by FMSMGA003.fm.intel.com with ESMTP; 06 Feb 2015 04:00:36 -0800 From: Adrian Hunter To: Ulf Hansson , Chris Ball Cc: linux-mmc , Philip Rakity , Adrian Hunter Subject: [PATCH V2 02/11] mmc: core: Allow card drive strength to be different to host Date: Fri, 6 Feb 2015 14:12:52 +0200 Message-Id: <1423224781-27076-3-git-send-email-adrian.hunter@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1423224781-27076-1-git-send-email-adrian.hunter@intel.com> References: <1423224781-27076-1-git-send-email-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki 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 Initialization of UHS-I modes for SD and SDIO cards employs a callback to allow the host driver to choose a drive strength value. Currently that assumes the card drive strength and host driver type must be the same value. Change to let the callback make that decision and return both the card drive strength and host driver type. Signed-off-by: Adrian Hunter --- drivers/mmc/core/sd.c | 33 +++++++++++++-------------------- drivers/mmc/core/sdio.c | 43 ++++++++++++++++++------------------------- include/linux/mmc/host.h | 3 ++- 3 files changed, 33 insertions(+), 46 deletions(-) diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index ad4d43e..cbee29a 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -388,18 +388,9 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status) { int host_drv_type = SD_DRIVER_TYPE_B; int card_drv_type = SD_DRIVER_TYPE_B; - int drive_strength; + int drive_strength, drv_type; int err; - /* - * If the host doesn't support any of the Driver Types A,C or D, - * or there is no board specific handler then default Driver - * Type B is used. - */ - if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C - | MMC_CAP_DRIVER_TYPE_D))) - return 0; - if (!card->host->ops->select_drive_strength) return 0; @@ -430,20 +421,22 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status) mmc_host_clk_hold(card->host); drive_strength = card->host->ops->select_drive_strength( card->sw_caps.uhs_max_dtr, - host_drv_type, card_drv_type); + host_drv_type, card_drv_type, &drv_type); mmc_host_clk_release(card->host); - err = mmc_sd_switch(card, 1, 2, drive_strength, status); - if (err) - return err; - - if ((status[15] & 0xF) != drive_strength) { - pr_warn("%s: Problem setting drive strength!\n", - mmc_hostname(card->host)); - return 0; + if (drive_strength) { + err = mmc_sd_switch(card, 1, 2, drive_strength, status); + if (err) + return err; + if ((status[15] & 0xF) != drive_strength) { + pr_warn("%s: Problem setting drive strength!\n", + mmc_hostname(card->host)); + return 0; + } } - mmc_set_driver_type(card->host, drive_strength); + if (drv_type) + mmc_set_driver_type(card->host, drv_type); return 0; } diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index ce6cc47..d7309ab 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -401,21 +401,10 @@ static void sdio_select_driver_type(struct mmc_card *card) { int host_drv_type = SD_DRIVER_TYPE_B; int card_drv_type = SD_DRIVER_TYPE_B; - int drive_strength; + int drive_strength, drv_type; unsigned char card_strength; int err; - /* - * If the host doesn't support any of the Driver Types A,C or D, - * or there is no board specific handler then default Driver - * Type B is used. - */ - if (!(card->host->caps & - (MMC_CAP_DRIVER_TYPE_A | - MMC_CAP_DRIVER_TYPE_C | - MMC_CAP_DRIVER_TYPE_D))) - return; - if (!card->host->ops->select_drive_strength) return; @@ -445,23 +434,27 @@ static void sdio_select_driver_type(struct mmc_card *card) */ drive_strength = card->host->ops->select_drive_strength( card->sw_caps.uhs_max_dtr, - host_drv_type, card_drv_type); + host_drv_type, card_drv_type, &drv_type); - /* if error just use default for drive strength B */ - err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0, - &card_strength); - if (err) - return; + if (drive_strength) { + /* if error just use default for drive strength B */ + err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0, + &card_strength); + if (err) + return; - card_strength &= ~(SDIO_DRIVE_DTSx_MASK<host, drive_strength); + if (drv_type) + mmc_set_driver_type(card->host, drv_type); } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index e9a7470..d984c55 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -138,7 +138,8 @@ struct mmc_host_ops { /* Prepare HS400 target operating frequency depending host driver */ int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); - int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv); + int (*select_drive_strength)(unsigned int max_dtr, int host_drv, + int card_drv, int *drv_type); void (*hw_reset)(struct mmc_host *host); void (*card_event)(struct mmc_host *host);