From patchwork Tue Dec 13 00:53:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: subhashj@codeaurora.org X-Patchwork-Id: 9471657 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 833AB60760 for ; Tue, 13 Dec 2016 00:54:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7455B28543 for ; Tue, 13 Dec 2016 00:54:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 681DA28549; Tue, 13 Dec 2016 00:54:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E313C28543 for ; Tue, 13 Dec 2016 00:54:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932275AbcLMAxi (ORCPT ); Mon, 12 Dec 2016 19:53:38 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:58014 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753031AbcLMAxf (ORCPT ); Mon, 12 Dec 2016 19:53:35 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 3906561307; Tue, 13 Dec 2016 00:53:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1481590409; bh=ZsFRcPVFtC3PT0rk/6xjwB7TVglOMyFAxH5ELfS1ddI=; h=From:To:Cc:Subject:Date:From; b=Ne3NmUFeXZqT2GfYCSn6ggBTkmonCVZwhe8uGzce+5wPrOkLkCxq+FpfkbdsOsNBG csqvE5KY7u4mpMLzhx4odAkeuotj2uX8Vs0OuLvdnQ3CcVjKmjDZUOZ3RhpEyiR6LM 3BZT6084hLOuMt3bd9PPxzIlYlsQm/117nrYN+HM= Received: from pacamara-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: subhashj@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 79E56606EF; Tue, 13 Dec 2016 00:53:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1481590408; bh=ZsFRcPVFtC3PT0rk/6xjwB7TVglOMyFAxH5ELfS1ddI=; h=From:To:Cc:Subject:Date:From; b=HIuScQYjqVg2jNhXbNfmib6MKFSaRahpvlJcYSouKxJpyx7Rr1XdW9xwVrxqiTmy9 ZZDE8gzT+7YnWmyke/D7c5Nb7R+UmgUlpCtxVE4QDGqKxAqtl7I4RzqxwtYw+5E1xE 3CaRGmmiBsGVUFmDxvAcIIr5/6ROPy4D3VQ71T5c= DMARC-Filter: OpenDMARC Filter v1.3.1 smtp.codeaurora.org 79E56606EF Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=pass smtp.mailfrom=subhashj@codeaurora.org From: Subhash Jadavani To: vinholikatti@gmail.com, jejb@linux.vnet.ibm.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, Sahitya Tummala , Subhash Jadavani , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 04/12] scsi: ufs: Add sysfs node to dynamically control clock gating Date: Mon, 12 Dec 2016 16:53:20 -0800 Message-Id: <1481590400-32311-1-git-send-email-subhashj@codeaurora.org> X-Mailer: git-send-email 1.9.1 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Sahitya Tummala Provide an option to enable/disable clock gating during runtime. Write 1 or 0 to "clkgate_enable" sysfs node to enable/disable clock gating. Signed-off-by: Sahitya Tummala Signed-off-by: Subhash Jadavani --- drivers/scsi/ufs/ufshcd.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufshcd.h | 4 ++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 7fdcab0..aabe706 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1011,6 +1011,41 @@ static ssize_t ufshcd_clkgate_delay_store(struct device *dev, return count; } +static ssize_t ufshcd_clkgate_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hba->clk_gating.is_enabled); +} + +static ssize_t ufshcd_clkgate_enable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + unsigned long flags; + u32 value; + + if (kstrtou32(buf, 0, &value)) + return -EINVAL; + + value = !!value; + if (value == hba->clk_gating.is_enabled) + goto out; + + if (value) { + ufshcd_release(hba); + } else { + spin_lock_irqsave(hba->host->host_lock, flags); + hba->clk_gating.active_reqs++; + spin_unlock_irqrestore(hba->host->host_lock, flags); + } + + hba->clk_gating.is_enabled = value; +out: + return count; +} + static void ufshcd_init_clk_gating(struct ufs_hba *hba) { if (!ufshcd_is_clkgating_allowed(hba)) @@ -1020,13 +1055,23 @@ static void ufshcd_init_clk_gating(struct ufs_hba *hba) INIT_DELAYED_WORK(&hba->clk_gating.gate_work, ufshcd_gate_work); INIT_WORK(&hba->clk_gating.ungate_work, ufshcd_ungate_work); + hba->clk_gating.is_enabled = true; + hba->clk_gating.delay_attr.show = ufshcd_clkgate_delay_show; hba->clk_gating.delay_attr.store = ufshcd_clkgate_delay_store; sysfs_attr_init(&hba->clk_gating.delay_attr.attr); hba->clk_gating.delay_attr.attr.name = "clkgate_delay_ms"; - hba->clk_gating.delay_attr.attr.mode = S_IRUGO | S_IWUSR; + hba->clk_gating.delay_attr.attr.mode = 0644; if (device_create_file(hba->dev, &hba->clk_gating.delay_attr)) dev_err(hba->dev, "Failed to create sysfs for clkgate_delay\n"); + + hba->clk_gating.enable_attr.show = ufshcd_clkgate_enable_show; + hba->clk_gating.enable_attr.store = ufshcd_clkgate_enable_store; + sysfs_attr_init(&hba->clk_gating.enable_attr.attr); + hba->clk_gating.enable_attr.attr.name = "clkgate_enable"; + hba->clk_gating.enable_attr.attr.mode = 0644; + if (device_create_file(hba->dev, &hba->clk_gating.enable_attr)) + dev_err(hba->dev, "Failed to create sysfs for clkgate_enable\n"); } static void ufshcd_exit_clk_gating(struct ufs_hba *hba) @@ -1034,6 +1079,7 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba) if (!ufshcd_is_clkgating_allowed(hba)) return; device_remove_file(hba->dev, &hba->clk_gating.delay_attr); + device_remove_file(hba->dev, &hba->clk_gating.enable_attr); cancel_work_sync(&hba->clk_gating.ungate_work); cancel_delayed_work_sync(&hba->clk_gating.gate_work); } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 08cd26e..0882ba6 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -320,6 +320,8 @@ enum clk_gating_state { * @is_suspended: clk gating is suspended when set to 1 which can be used * during suspend/resume * @delay_attr: sysfs attribute to control delay_attr + * @enable_attr: sysfs attribute to enable/disable clock gating + * @is_enabled: Indicates the current status of clock gating * @active_reqs: number of requests that are pending and should be waited for * completion before gating clocks. */ @@ -330,6 +332,8 @@ struct ufs_clk_gating { unsigned long delay_ms; bool is_suspended; struct device_attribute delay_attr; + struct device_attribute enable_attr; + bool is_enabled; int active_reqs; };