From patchwork Mon Sep 13 13:33:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avri Altman X-Patchwork-Id: 510136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C500C433F5 for ; Mon, 13 Sep 2021 13:35:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E154061880 for ; Mon, 13 Sep 2021 13:35:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242659AbhIMNgf (ORCPT ); Mon, 13 Sep 2021 09:36:35 -0400 Received: from esa1.hgst.iphmx.com ([68.232.141.245]:47585 "EHLO esa1.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243051AbhIMNev (ORCPT ); Mon, 13 Sep 2021 09:34:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1631540015; x=1663076015; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=r441HNcWJeUCvSIYAD/FGn2Dckp0lZ7Q8zp6NuT89jc=; b=XH8MoFH/YaTTsnsk/feYbwI0/FRJb+KJjOrEFYnbO0+1bIabkcaGjSqk fNa/HOU5s4Bu2Yu0t4ZiNZnLP6TFiT/+vAV81DjCRb+vLY7Gqf4whnCUG j0fI+uEJT8lHBnuZJRLN8yafgiHFRx6z/NTrMVqTaB0kEir6fJnkdgIW7 M1eD6H1/z8lzy+dZHBzj7e92+M7uC81cevGTn7Wsio9gc4g0aCqiTyJ0C KqXf1p1zWHAv7CWh6zZopghw3MaLssUFZ1g8undCoulxfDq38aLPd3qOp HSbcI0EnQSztyt00mjOagd47RcUpTTJ/QZOdDcv2/TAM/6vGaU8SF7j7S w==; X-IronPort-AV: E=Sophos;i="5.85,290,1624291200"; d="scan'208";a="291474613" Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 13 Sep 2021 21:33:33 +0800 IronPort-SDR: +fSDP8Zj71mmw4qxoWzFcMg5bh2aujBgYwzbJgeVUAeS5CkD9pVbs33/p4CwlKAHhNIsHuHEJp gQdMu/Lbtv97e8ENGZcRxevdOMeLZ/1xqbKxPrT1EZwe51dVHcQZZLJC3hcfFtDth+RyaqxzIB OA8XcGByrcdd8f78vGzLOr1nabJKNe2VH9Wlex/8JgU5/F0Vk4SYJVOV0LUZ9NuQFdIcPZcpee +RJfHWdmiIyP4muvyk/sUr2hyY3U61JRbNmeP8vxVwZzfZgQuOZWEhLN/RDP3V5hId4VmP4J87 uUk5qnlk+EIO4BpRREwj+8RD Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 06:08:24 -0700 IronPort-SDR: 1X5C2sWljJlnCNysfvXy1LqC2WGTezFkQzOzPcKceHBiIawlZ0fbIF9AZxK9ARysMH3RO3fnuX 3Te/Z7mPjS0YGlgM4lzd15eaZVvPvyvHm4CWs/ndS9RwBhxIw9dyzYvjwN/xNdbtHcUpPx9sbb +YLvYjvULyqSXhayw/1S4qb3X3z7/b8paTXfytochsiIDDzrUqXxnpHQnwxfVhKApWZrC4IL1m JtQHqIH4227u8aWqUEtX/ZzRACBrq8INhhlUWLBBSHBR5+pNCGlOEjQ6rvikXi6Gc6RIjpVuS0 dc0= WDCIronportException: Internal Received: from bxygm33.sdcorp.global.sandisk.com (HELO BXYGM33.ad.shared) ([10.0.231.247]) by uls-op-cesaip01.wdc.com with ESMTP; 13 Sep 2021 06:33:31 -0700 From: Avri Altman To: "James E . J . Bottomley" , "Martin K . Petersen" Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Bart Van Assche , Adrian Hunter , Bean Huo , Guenter Roeck , Avri Altman Subject: [PATCH v4 1/2] scsi: ufs: Probe for temperature notification support Date: Mon, 13 Sep 2021 16:33:02 +0300 Message-Id: <20210913133303.10154-2-avri.altman@wdc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210913133303.10154-1-avri.altman@wdc.com> References: <20210913133303.10154-1-avri.altman@wdc.com> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Probe the dExtendedUFSFeaturesSupport register for the device's temperature notification support, and if supported, add a hw monitor device. Signed-off-by: Avri Altman --- drivers/scsi/ufs/Kconfig | 9 ++ drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-hwmon.c | 194 +++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs.h | 7 ++ drivers/scsi/ufs/ufshcd.c | 26 +++++ drivers/scsi/ufs/ufshcd.h | 18 ++++ 6 files changed, 255 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-hwmon.c diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 432df76e6318..565e8aa6319d 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -199,3 +199,12 @@ config SCSI_UFS_FAULT_INJECTION help Enable fault injection support in the UFS driver. This makes it easier to test the UFS error handler and abort handler. + +config SCSI_UFS_HWMON + bool "UFS Temperature Notification" + depends on SCSI_UFSHCD && HWMON + help + This provides support for UFS hardware monitoring. If enabled, + a hardware monitoring device will be created for the UFS device. + + If unsure, say N. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index c407da9b5171..966048875b50 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -10,6 +10,7 @@ ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o +ufshcd-core-$(CONFIG_SCSI_UFS_HWMON) += ufs-hwmon.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o diff --git a/drivers/scsi/ufs/ufs-hwmon.c b/drivers/scsi/ufs/ufs-hwmon.c new file mode 100644 index 000000000000..390748a9d547 --- /dev/null +++ b/drivers/scsi/ufs/ufs-hwmon.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UFS hardware monitoring support + * Copyright (c) 2021, Western Digital Corporation + */ + +#include +#include + +#include "ufshcd.h" + +struct ufs_hwmon_data { + struct ufs_hba *hba; + u8 mask; +}; + +static bool ufs_read_temp_enable(struct ufs_hba *hba, u8 mask) +{ + u32 ee_mask; + + if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0, + &ee_mask)) + return false; + + return (mask & ee_mask & MASK_EE_TOO_HIGH_TEMP) || (mask & ee_mask & MASK_EE_TOO_LOW_TEMP); +} + +static int ufs_get_temp(struct ufs_hba *hba, enum attr_idn idn, long *val) +{ + u32 value; + + if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, idn, 0, 0, &value)) + return -EINVAL; + + if (value == 0) + return -EINVAL; + + *val = ((long)value - 80) * MILLIDEGREE_PER_DEGREE; + return 0; +} + +static int ufs_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long *val) +{ + struct ufs_hwmon_data *data = dev_get_drvdata(dev); + struct ufs_hba *hba = data->hba; + int err = 0; + + if (type != hwmon_temp) + return 0; + + down(&hba->host_sem); + + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + + ufshcd_rpm_get_sync(hba); + + switch (attr) { + case hwmon_temp_enable: + *val = ufs_read_temp_enable(hba, data->mask); + + break; + case hwmon_temp_crit: + err = ufs_get_temp(hba, QUERY_ATTR_IDN_HIGH_TEMP_BOUND, val); + + break; + case hwmon_temp_lcrit: + err = ufs_get_temp(hba, QUERY_ATTR_IDN_LOW_TEMP_BOUND, val); + + break; + case hwmon_temp_input: + err = ufs_get_temp(hba, QUERY_ATTR_IDN_CASE_ROUGH_TEMP, val); + + break; + default: + err = -EOPNOTSUPP; + + break; + } + + ufshcd_rpm_put_sync(hba); + + up(&hba->host_sem); + + return err; +} + +static int ufs_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, + long val) +{ + struct ufs_hwmon_data *data = dev_get_drvdata(dev); + struct ufs_hba *hba = data->hba; + int err = 0; + + if (attr != hwmon_temp_enable) + return -EINVAL; + + if (val != 0 && val != 1) + return -EINVAL; + + down(&hba->host_sem); + + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + + ufshcd_rpm_get_sync(hba); + + if (val == 1) + err = ufshcd_update_ee_usr_mask(hba, MASK_EE_URGENT_TEMP, 0); + else + err = ufshcd_update_ee_usr_mask(hba, 0, MASK_EE_URGENT_TEMP); + + ufshcd_rpm_put_sync(hba); + + up(&hba->host_sem); + + return err; +} + +static umode_t ufs_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type, u32 attr, + int channel) +{ + if (type != hwmon_temp) + return 0; + + switch (attr) { + case hwmon_temp_enable: + return 0644; + case hwmon_temp_crit: + case hwmon_temp_lcrit: + case hwmon_temp_input: + return 0444; + default: + break; + } + return 0; +} + +static const struct hwmon_channel_info *ufs_hwmon_info[] = { + HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_LCRIT), + NULL +}; + +static const struct hwmon_ops ufs_hwmon_ops = { + .is_visible = ufs_hwmon_is_visible, + .read = ufs_hwmon_read, + .write = ufs_hwmon_write, +}; + +static const struct hwmon_chip_info ufs_hwmon_hba_info = { + .ops = &ufs_hwmon_ops, + .info = ufs_hwmon_info, +}; + +void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) +{ + struct device *dev = hba->dev; + struct ufs_hwmon_data *data; + struct device *hwmon; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return; + + data->hba = hba; + data->mask = mask; + + hwmon = hwmon_device_register_with_info(dev, "ufs", data, &ufs_hwmon_hba_info, NULL); + if (IS_ERR(hwmon)) { + dev_warn(dev, "Failed to instantiate hwmon device\n"); + kfree(data); + return; + } + + hba->hwmon_device = hwmon; +} + +void ufs_hwmon_remove(struct ufs_hba *hba) +{ + struct ufs_hwmon_data *data; + + if (!hba->hwmon_device) + return; + + data = dev_get_drvdata(hba->hwmon_device); + hwmon_device_unregister(hba->hwmon_device); + hba->hwmon_device = NULL; + kfree(data); +} diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 8c6b38b1b142..0bfdca3e648e 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -152,6 +152,9 @@ enum attr_idn { QUERY_ATTR_IDN_PSA_STATE = 0x15, QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16, QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME = 0x17, + QUERY_ATTR_IDN_CASE_ROUGH_TEMP = 0x18, + QUERY_ATTR_IDN_HIGH_TEMP_BOUND = 0x19, + QUERY_ATTR_IDN_LOW_TEMP_BOUND = 0x1A, QUERY_ATTR_IDN_WB_FLUSH_STATUS = 0x1C, QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE = 0x1D, QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E, @@ -338,6 +341,9 @@ enum { /* Possible values for dExtendedUFSFeaturesSupport */ enum { + UFS_DEV_LOW_TEMP_NOTIF = BIT(4), + UFS_DEV_HIGH_TEMP_NOTIF = BIT(5), + UFS_DEV_EXT_TEMP_NOTIF = BIT(6), UFS_DEV_HPB_SUPPORT = BIT(7), UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), }; @@ -370,6 +376,7 @@ enum { MASK_EE_WRITEBOOSTER_EVENT = BIT(5), MASK_EE_PERFORMANCE_THROTTLING = BIT(6), }; +#define MASK_EE_URGENT_TEMP (MASK_EE_TOO_HIGH_TEMP | MASK_EE_TOO_LOW_TEMP) /* Background operation status */ enum bkops_status { diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 67889d74761c..cb20720c5deb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7469,6 +7469,29 @@ static void ufshcd_wb_probe(struct ufs_hba *hba, u8 *desc_buf) hba->caps &= ~UFSHCD_CAP_WB_EN; } +static void ufshcd_temp_notif_probe(struct ufs_hba *hba, u8 *desc_buf) +{ + struct ufs_dev_info *dev_info = &hba->dev_info; + u32 ext_ufs_feature; + u8 mask = 0; + + if (!(hba->caps & UFSHCD_CAP_TEMP_NOTIF) || dev_info->wspecversion < 0x300) + return; + + ext_ufs_feature = get_unaligned_be32(desc_buf + DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP); + + if (ext_ufs_feature & UFS_DEV_LOW_TEMP_NOTIF) + mask |= MASK_EE_TOO_LOW_TEMP; + + if (ext_ufs_feature & UFS_DEV_HIGH_TEMP_NOTIF) + mask |= MASK_EE_TOO_HIGH_TEMP; + + if (mask) { + ufshcd_enable_ee(hba, mask); + ufs_hwmon_probe(hba, mask); + } +} + void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, struct ufs_dev_fix *fixups) { struct ufs_dev_fix *f; @@ -7564,6 +7587,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba) ufshcd_wb_probe(hba, desc_buf); + ufshcd_temp_notif_probe(hba, desc_buf); + /* * ufshcd_read_string_desc returns size of the string * reset the error value @@ -9408,6 +9433,7 @@ void ufshcd_remove(struct ufs_hba *hba) { if (hba->sdev_ufs_device) ufshcd_rpm_get_sync(hba); + ufs_hwmon_remove(hba); ufs_bsg_remove(hba); ufshpb_remove(hba); ufs_sysfs_remove_nodes(hba->dev); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 4723f27a55d1..798a408d71e5 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -653,6 +653,12 @@ enum ufshcd_caps { * in order to exit DeepSleep state. */ UFSHCD_CAP_DEEPSLEEP = 1 << 10, + + /* + * This capability allows the host controller driver to use temperature + * notification if it is supported by the UFS device. + */ + UFSHCD_CAP_TEMP_NOTIF = 1 << 11, }; struct ufs_hba_variant_params { @@ -789,6 +795,10 @@ struct ufs_hba { struct scsi_device *sdev_ufs_device; struct scsi_device *sdev_rpmb; +#ifdef CONFIG_SCSI_UFS_HWMON + struct device *hwmon_device; +#endif + enum ufs_dev_pwr_mode curr_dev_pwr_mode; enum uic_link_state uic_link_state; /* Desired UFS power management level during runtime PM */ @@ -1050,6 +1060,14 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) return 0; } +#ifdef CONFIG_SCSI_UFS_HWMON +void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask); +void ufs_hwmon_remove(struct ufs_hba *hba); +#else +static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {} +static inline void ufs_hwmon_remove(struct ufs_hba *hba) {} +#endif + #ifdef CONFIG_PM extern int ufshcd_runtime_suspend(struct device *dev); extern int ufshcd_runtime_resume(struct device *dev); From patchwork Mon Sep 13 13:33:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Avri Altman X-Patchwork-Id: 510135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2420C433EF for ; Mon, 13 Sep 2021 13:35:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A7C4761A02 for ; Mon, 13 Sep 2021 13:35:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242416AbhIMNhA (ORCPT ); Mon, 13 Sep 2021 09:37:00 -0400 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:31738 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243118AbhIMNe6 (ORCPT ); Mon, 13 Sep 2021 09:34:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1631540021; x=1663076021; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=I+mbTA+03+CBI4ATMHCqjrQ510CBb/AiF9vYJKHKDoQ=; b=ZIzO5mPiLkuG8PaOvjIwOh9edaWSwoRyWvNWMaOTHJl3JoA5EZeyxrkZ RPWG3E/9lO2fl7qZCwN9LOY8Mawxuc+UodO4INKLXJYmYIUj31r9Z0ht4 UnJT/k2i0ZhurNvR2PakD63yP/g7BPrHMvmkxjdm73J82FAXkDTnOuq8n UW5ceCb5QNN3l6y/yQxKBt5WNiglbtLnm83qyNjnucSmwGMt+vRRCQRS+ bGIhz/5nJRhoQf33VI55TVMC/mZldaMO1urCqdgpFidTZw7qX4IifmBpa UjAR9VJ3F0XpNnR0vEyCIGPkKPZ1OepPJfWCU/eaVP+kup6/4kiP9f1gD Q==; X-IronPort-AV: E=Sophos;i="5.85,288,1624291200"; d="scan'208";a="179856628" Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 13 Sep 2021 21:33:41 +0800 IronPort-SDR: ygBL6sAAvZmOwfxINZIZ4p4q4tzSjki6WlObJgyfOdnYqXyhwYozlnFg5Px5qSCEpEm5RUnWE0 NX02XFNHrfI5m2k2oReD57frQaebGAslEvOA35dpC2ZMk9vS6ukRKmBu+0Wp5TcqkbHcSob9Al BSBm94Q9wqFZFJ9JDRP8zUU6GWfAjSmtkd3PqQaxNVWUjRwwMSELhOMjk2IqRRglBYQA79BLfP /w8M8Fii3FSnDhMGNKphC6f18/qFjk0RqBUg1gB7nM8V616tdFUzmXcsPwkq6hUCA7Tg2SrvkV 8yraaRtrIKSoW9/UyskW7Ias Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2021 06:10:07 -0700 IronPort-SDR: 8NsLXAoR9SUGC+xAWtOIOs+cflEltCQAn3ygfA3P9Z9UznjU47sGgqRHWznC7NOM9ncL3WTzKL HVD9BpnF2L6M0SEfEhvKjnIGyzsU0zK/l3Tvi5Q1tk5eoCSV/2Er7Ed43GCJUiwg4UtQkaFTCX qVgKRRXJCSxeYFeVKS7EM7f92VcEk6xAjRFVofev8xCsdM5pyfaX7R0UknuA6GaN/SONbL+uTA rDkAuTHHQ3cOJ0ryigMngF6C5+4O1nwcfw+hY1krJ+4p6qY3/kn04jK5U62VB9VlvAstNM2PUT VWc= WDCIronportException: Internal Received: from bxygm33.sdcorp.global.sandisk.com (HELO BXYGM33.ad.shared) ([10.0.231.247]) by uls-op-cesaip01.wdc.com with ESMTP; 13 Sep 2021 06:33:39 -0700 From: Avri Altman To: "James E . J . Bottomley" , "Martin K . Petersen" Cc: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Bart Van Assche , Adrian Hunter , Bean Huo , Guenter Roeck , Avri Altman Subject: [PATCH v4 2/2] scsi: ufs: Add temperature notification exception handling Date: Mon, 13 Sep 2021 16:33:03 +0300 Message-Id: <20210913133303.10154-3-avri.altman@wdc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210913133303.10154-1-avri.altman@wdc.com> References: <20210913133303.10154-1-avri.altman@wdc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org The device may notify the host of an extreme temperature by using the exception event mechanism. The exception can be raised when the device’s Tcase temperature is either too high or too low. It is essentially up to the platform to decide what further actions need to be taken. leave a placeholder for a designated vop for that. Signed-off-by: Avri Altman --- drivers/scsi/ufs/ufs-hwmon.c | 12 ++++++++++++ drivers/scsi/ufs/ufshcd.c | 21 +++++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 2 ++ 3 files changed, 35 insertions(+) diff --git a/drivers/scsi/ufs/ufs-hwmon.c b/drivers/scsi/ufs/ufs-hwmon.c index 390748a9d547..2fd100e92f81 100644 --- a/drivers/scsi/ufs/ufs-hwmon.c +++ b/drivers/scsi/ufs/ufs-hwmon.c @@ -192,3 +192,15 @@ void ufs_hwmon_remove(struct ufs_hba *hba) hba->hwmon_device = NULL; kfree(data); } + +void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) +{ + if (!hba->hwmon_device) + return; + + if (ee_mask & MASK_EE_TOO_HIGH_TEMP) + hwmon_notify_event(hba->hwmon_device, hwmon_temp, hwmon_temp_max_alarm, 0); + + if (ee_mask & MASK_EE_TOO_LOW_TEMP) + hwmon_notify_event(hba->hwmon_device, hwmon_temp, hwmon_temp_min_alarm, 0); +} diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index cb20720c5deb..3f9b56800e5b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5642,6 +5642,24 @@ static void ufshcd_bkops_exception_event_handler(struct ufs_hba *hba) __func__, err); } +static void ufshcd_temp_exception_event_handler(struct ufs_hba *hba, u16 status) +{ + u32 value; + + if (ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, + QUERY_ATTR_IDN_CASE_ROUGH_TEMP, 0, 0, &value)) + return; + + dev_info(hba->dev, "exception Tcase %d\n", value - 80); + + ufs_hwmon_notify_event(hba, status & MASK_EE_URGENT_TEMP); + + /* + * A placeholder for the platform vendors to add whatever additional + * steps required + */ +} + static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn) { u8 index; @@ -5821,6 +5839,9 @@ static void ufshcd_exception_event_handler(struct work_struct *work) if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS) ufshcd_bkops_exception_event_handler(hba); + if (status & hba->ee_drv_mask & MASK_EE_URGENT_TEMP) + ufshcd_temp_exception_event_handler(hba, status); + ufs_debugfs_exception_event(hba, status); out: ufshcd_scsi_unblock_requests(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 798a408d71e5..d811fe079e04 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1063,9 +1063,11 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) #ifdef CONFIG_SCSI_UFS_HWMON void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask); void ufs_hwmon_remove(struct ufs_hba *hba); +void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask); #else static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {} static inline void ufs_hwmon_remove(struct ufs_hba *hba) {} +static inline void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) {} #endif #ifdef CONFIG_PM