From patchwork Sun Mar 27 12:14:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugene Shalygin X-Patchwork-Id: 12792806 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C008EC433FE for ; Sun, 27 Mar 2022 12:15:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230495AbiC0MQu (ORCPT ); Sun, 27 Mar 2022 08:16:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234518AbiC0MQs (ORCPT ); Sun, 27 Mar 2022 08:16:48 -0400 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E83537A04; Sun, 27 Mar 2022 05:15:09 -0700 (PDT) Received: by mail-ej1-x62d.google.com with SMTP id yy13so23499195ejb.2; Sun, 27 Mar 2022 05:15:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mFeAdfh+uFFygwIofZUcwHH3/SuesRvoL3kWQMURoiw=; b=Kdba1i8MTHZT9fE4eluzcT2H5BDdN8a1zubJUiUsq8USrbeb7+Jl54FIvDezyKWDkX WQCkKxiNK9RurYqCv3CZf7crnzHSvrDeoI3+lM/WP84zyKnpjUrBML3UY0/MvNgWF5oG 9s1vyFwCvFeDDYE3clN1Gj1tC6dtZkcZ0NLWvJkE+Jpg03NUy6x/BrsNNqO1lXz50Lpq dA9hLRoANDBlIOOzU0rHy7dMSzK56hJpRypIbX9/me1hMuAtNCmkSawhYwoUOMHN7M7j AN1PZNsW+lxg5VNnwqnJCY+X04r+gqascnLnfEK1HL5C5GO+tuzLVU/976tRSI79R2RP slLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mFeAdfh+uFFygwIofZUcwHH3/SuesRvoL3kWQMURoiw=; b=WOFEsAhBABu0JHQvOhIThhadKGTap0YeNnnYKOlMJY22gONgfFLDdauq+69SQUT4Rp OYOyfzZAknHojsF5Lp2xVAqh6HmYbVPQ3+YEmYuaKjaNSi9IqNScbS7110NIvpBYy2O5 UWFXD5lwbwJSBA/V0fmWfTzteTKywrJ2zH1TGeFz9EDtTLsdLwUq9SuWgRB2cWYXmgy+ I+6LUiWJCJgG3Af8GD3rSXF0ErDpudyjapKuSQ/FI7SxtxqZTL9tDpKIE5wYhX35eA8F 0jDtocdQsCvv2wQtA1LAVsFrSYG2PW5S5mG5chEZCqYnYhLLmzfWs0GIX4PhX6f0ovkI wtAg== X-Gm-Message-State: AOAM532S8c60sZuOua1CiadxO8fisY1rBl14dXQxbs6gHL0kmbnpHBq9 YWAC6fo2vJSLZCiwyBDvCBY= X-Google-Smtp-Source: ABdhPJyV/878GH+ND439D5twggrd/P8IDFTivqpu2GlNIilCFr9W9EBMu1VnIk4tyeR5hTXt76Z5kw== X-Received: by 2002:a17:906:168f:b0:6df:b4ed:7c49 with SMTP id s15-20020a170906168f00b006dfb4ed7c49mr22006747ejd.36.1648383307600; Sun, 27 Mar 2022 05:15:07 -0700 (PDT) Received: from tiger.museclub.art (p200300cf9f06c2008407e4c213cb9d01.dip0.t-ipconnect.de. [2003:cf:9f06:c200:8407:e4c2:13cb:9d01]) by smtp.googlemail.com with ESMTPSA id hg11-20020a1709072ccb00b006cee4fb36c7sm4530127ejc.64.2022.03.27.05.15.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Mar 2022 05:15:06 -0700 (PDT) From: Eugene Shalygin To: eugene.shalygin@gmail.com Cc: darcagn@protonmail.com, Jean Delvare , Guenter Roeck , linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] hwmon: (asus-ec-sensors) introduce ec_board_info struct for board data Date: Sun, 27 Mar 2022 14:14:01 +0200 Message-Id: <20220327121404.1702631-2-eugene.shalygin@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220327121404.1702631-1-eugene.shalygin@gmail.com> References: <20220327121404.1702631-1-eugene.shalygin@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org We need to keep some more information about the current board than just the sensors set, and with more boards to add the dmi id array grows quickly. Our probe code is always the same so let's switch to a custom test code and a custom board info array. That allows us to omit board vendor string (ASUS uses two strings that differ in case) in the board info and use case-insensitive comparison, and also do not duplicate sensor definitions for such board variants as " (WI-FI)" when sensors are identical to the base variant. Also saves a quarter of the module size by replacing big dmi_system_id structs with smaller ones. Signed-off-by: Eugene Shalygin --- drivers/hwmon/asus-ec-sensors.c | 209 ++++++++++++++++++-------------- 1 file changed, 119 insertions(+), 90 deletions(-) diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index b5cf0136360c..7e28fc62f717 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -54,8 +54,7 @@ static char *mutex_path_override; /* ACPI mutex for locking access to the EC for the firmware */ #define ASUS_HW_ACCESS_MUTEX_ASMX "\\AMW0.ASMX" -/* There are two variants of the vendor spelling */ -#define VENDOR_ASUS_UPPER_CASE "ASUSTeK COMPUTER INC." +#define MAX_IDENTICAL_BOARD_VARIATIONS 2 typedef union { u32 value; @@ -164,68 +163,88 @@ static const struct ec_sensor_info known_ec_sensors[] = { (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB) #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT) -#define DMI_EXACT_MATCH_BOARD(vendor, name, sensors) { \ - .matches = { \ - DMI_EXACT_MATCH(DMI_BOARD_VENDOR, vendor), \ - DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ - }, \ - .driver_data = (void *)(sensors), \ -} +struct ec_board_info { + const char *board_names[MAX_IDENTICAL_BOARD_VARIATIONS]; + unsigned long sensors; +}; -static const struct dmi_system_id asus_ec_dmi_table[] __initconst = { - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "PRIME X570-PRO", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "Pro WS X570-ACE", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | - SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, - "ROG CROSSHAIR VIII DARK HERO", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, - "ROG CROSSHAIR VIII FORMULA", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG CROSSHAIR VIII HERO", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | - SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, - "ROG CROSSHAIR VIII HERO (WI-FI)", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | - SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, - "ROG CROSSHAIR VIII IMPACT", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX B550-E GAMING", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX B550-I GAMING", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_FAN_VRM_HS | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX X570-E GAMING", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX X570-F GAMING", - SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET), - DMI_EXACT_MATCH_BOARD(VENDOR_ASUS_UPPER_CASE, "ROG STRIX X570-I GAMING", - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_VRM_HS | - SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE), +static const struct ec_board_info board_info[] __initconst = { + { + .board_names = {"PRIME X570-PRO"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, + }, + { + .board_names = {"Pro WS X570-ACE"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | + SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + }, + { + .board_names = {"ROG CROSSHAIR VIII DARK HERO"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | + SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + }, + { + .board_names = {"ROG CROSSHAIR VIII FORMULA"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + }, + { + .board_names = { + "ROG CROSSHAIR VIII HERO", + "ROG CROSSHAIR VIII HERO (WI-FI)", + }, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | + SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | + SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + }, + { + .board_names = {"ROG CROSSHAIR VIII IMPACT"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + }, + { + .board_names = {"ROG STRIX B550-E GAMING"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CPU_OPT, + }, + { + .board_names = {"ROG STRIX B550-I GAMING"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + }, + { + .board_names = {"ROG STRIX X570-E GAMING"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + }, + { + .board_names = {"ROG STRIX X570-F GAMING"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, + }, + { + .board_names = {"ROG STRIX X570-I GAMING"}, + .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_FAN_VRM_HS | + SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + }, {} }; @@ -235,7 +254,7 @@ struct ec_sensor { }; struct ec_sensors_data { - unsigned long board_sensors; + struct ec_board_info board_info; struct ec_sensor *sensors; /* EC registers to read from */ u16 *registers; @@ -245,8 +264,6 @@ struct ec_sensors_data { /* in jiffies */ unsigned long last_updated; acpi_handle aml_mutex; - /* number of board EC sensors */ - u8 nr_sensors; /* * number of EC registers to read * (sensor might span more than 1 register) @@ -281,12 +298,17 @@ get_sensor_info(const struct ec_sensors_data *state, int index) return &known_ec_sensors[state->sensors[index].info_index]; } +static int sensor_count(const struct ec_board_info *board) +{ + return hweight_long(board->sensors); +} + static int find_ec_sensor_index(const struct ec_sensors_data *ec, enum hwmon_sensor_types type, int channel) { unsigned int i; - for (i = 0; i < ec->nr_sensors; i++) { + for (i = 0; i < sensor_count(&ec->board_info); i++) { if (get_sensor_info(ec, i)->type == type) { if (channel == 0) return i; @@ -301,11 +323,6 @@ static int __init bank_compare(const void *a, const void *b) return *((const s8 *)a) - *((const s8 *)b); } -static int __init board_sensors_count(unsigned long sensors) -{ - return hweight_long(sensors); -} - static void __init setup_sensor_data(struct ec_sensors_data *ec) { struct ec_sensor *s = ec->sensors; @@ -316,8 +333,8 @@ static void __init setup_sensor_data(struct ec_sensors_data *ec) ec->nr_banks = 0; ec->nr_registers = 0; - for_each_set_bit(i, &ec->board_sensors, - BITS_PER_TYPE(ec->board_sensors)) { + for_each_set_bit(i, &ec->board_info.sensors, + BITS_PER_TYPE(ec->board_info.sensors)) { s->info_index = i; s->cached_value = 0; ec->nr_registers += @@ -343,7 +360,7 @@ static void __init fill_ec_registers(struct ec_sensors_data *ec) const struct ec_sensor_info *si; unsigned int i, j, register_idx = 0; - for (i = 0; i < ec->nr_sensors; ++i) { + for (i = 0; i < sensor_count(&ec->board_info); ++i) { si = get_sensor_info(ec, i); for (j = 0; j < si->addr.components.size; ++j, ++register_idx) { ec->registers[register_idx] = @@ -457,9 +474,10 @@ static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data) static void update_sensor_values(struct ec_sensors_data *ec, u8 *data) { const struct ec_sensor_info *si; - struct ec_sensor *s; + struct ec_sensor *s, *sensor_end; - for (s = ec->sensors; s != ec->sensors + ec->nr_sensors; s++) { + sensor_end = ec->sensors + sensor_count(&ec->board_info); + for (s = ec->sensors; s != sensor_end; s++) { si = &known_ec_sensors[s->info_index]; s->cached_value = get_sensor_value(si, data); data += si->addr.components.size; @@ -597,12 +615,24 @@ static struct hwmon_chip_info asus_ec_chip_info = { .ops = &asus_ec_hwmon_ops, }; -static unsigned long __init get_board_sensors(void) +static const struct ec_board_info * __init get_board_info(void) { - const struct dmi_system_id *dmi_entry = - dmi_first_match(asus_ec_dmi_table); + const char *dmi_board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); + const char *dmi_board_name = dmi_get_system_info(DMI_BOARD_NAME); + const struct ec_board_info *board; + + if (!dmi_board_vendor || !dmi_board_name || + strcasecmp(dmi_board_vendor, "ASUSTeK COMPUTER INC.")) + return NULL; + + for (board = board_info; board->sensors; board++) { + if (match_string(board->board_names, + MAX_IDENTICAL_BOARD_VARIATIONS, + dmi_board_name) >= 0) + return board; + } - return dmi_entry ? (unsigned long)dmi_entry->driver_data : 0; + return NULL; } static int __init asus_ec_probe(struct platform_device *pdev) @@ -610,17 +640,17 @@ static int __init asus_ec_probe(struct platform_device *pdev) const struct hwmon_channel_info **ptr_asus_ec_ci; int nr_count[hwmon_max] = { 0 }, nr_types = 0; struct hwmon_channel_info *asus_ec_hwmon_chan; + const struct ec_board_info *pboard_info; const struct hwmon_chip_info *chip_info; struct device *dev = &pdev->dev; struct ec_sensors_data *ec_data; const struct ec_sensor_info *si; enum hwmon_sensor_types type; - unsigned long board_sensors; struct device *hwdev; unsigned int i; - board_sensors = get_board_sensors(); - if (!board_sensors) + pboard_info = get_board_info(); + if (!pboard_info) return -ENODEV; ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data), @@ -629,9 +659,8 @@ static int __init asus_ec_probe(struct platform_device *pdev) return -ENOMEM; dev_set_drvdata(dev, ec_data); - ec_data->board_sensors = board_sensors; - ec_data->nr_sensors = board_sensors_count(ec_data->board_sensors); - ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, + ec_data->board_info = *pboard_info; + ec_data->sensors = devm_kcalloc(dev, sensor_count(&ec_data->board_info), sizeof(struct ec_sensor), GFP_KERNEL); setup_sensor_data(ec_data); @@ -647,7 +676,7 @@ static int __init asus_ec_probe(struct platform_device *pdev) ec_data->aml_mutex = asus_hw_access_mutex(dev); - for (i = 0; i < ec_data->nr_sensors; ++i) { + for (i = 0; i < sensor_count(&ec_data->board_info); ++i) { si = get_sensor_info(ec_data, i); if (!nr_count[si->type]) ++nr_types; @@ -681,7 +710,7 @@ static int __init asus_ec_probe(struct platform_device *pdev) } dev_info(dev, "board has %d EC sensors that span %d registers", - ec_data->nr_sensors, ec_data->nr_registers); + sensor_count(&ec_data->board_info), ec_data->nr_registers); hwdev = devm_hwmon_device_register_with_info(dev, "asusec", ec_data, chip_info, NULL); @@ -703,8 +732,8 @@ static struct platform_driver asus_ec_sensors_platform_driver = { }, }; -MODULE_DEVICE_TABLE(dmi, asus_ec_dmi_table); module_platform_driver_probe(asus_ec_sensors_platform_driver, asus_ec_probe); +MODULE_DEVICE_TABLE(acpi, acpi_ec_ids); module_param_named(mutex_path, mutex_path_override, charp, 0); MODULE_PARM_DESC(mutex_path, From patchwork Sun Mar 27 12:14:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugene Shalygin X-Patchwork-Id: 12792809 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1648C433EF for ; Sun, 27 Mar 2022 12:15:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235275AbiC0MQy (ORCPT ); Sun, 27 Mar 2022 08:16:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234663AbiC0MQu (ORCPT ); Sun, 27 Mar 2022 08:16:50 -0400 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [IPv6:2a00:1450:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 782BD37A06; Sun, 27 Mar 2022 05:15:10 -0700 (PDT) Received: by mail-ej1-x636.google.com with SMTP id p15so23469654ejc.7; Sun, 27 Mar 2022 05:15:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7WldFtAHd8wTe30jg8gERDP/O6DG4ckMHTfgNZOG6XQ=; b=hPUt2lsbPYshz9HpUnwntZkZyULLp9hLfdILfFYHqCAX72e972isNiR6cCJ5SHDTcR nvSRK2CqOh5kllw88dBOx/fuvKeYLvIqfVTUBaGnkOhkGLIgbOdrhOiBv3JBogCAxH82 3jVWIhnq2dqP+c3PiwrHbbc/T6TedNk0Gf+CVuYpZGykE+vWcj9thViMxW0UFieCYHB3 QqBsEb/qVOAqKUNzneFtJNSGba259oilZFssmdRA0fl0kIhErdGy1r5xAC2l0tuqqlX8 81z2NPvXuvkpdUNtHdaRUJNySTgIN51IxJhQJSJ7xBOE6vc4FsMtbSBr9qtjCINnmCDE 7fXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7WldFtAHd8wTe30jg8gERDP/O6DG4ckMHTfgNZOG6XQ=; b=Gs+2wmW+CWXzASM4x/qEPpRvTKRg0jaMnKts7u+yBlveLNd22ZXJ5YdyexOiOVC1n2 +wflV5B6q9jMB17ofdfyO2urV+tWbqj0lDaLJ1XWRAYGNb0WmM+eSkYZTO1Pkn9oJ4OG wfHXmeNMYfBWSvlGxa7RlAtZlrIFsNMlOtWR5YTMwH+aQ3E24uxKMAvdf20ksi4W7nrz 2VTa5rWwMazWedAcMxKWTvnvJXrqF8HoviY/IcYLMROZte90rZpP4neQCV8yA4AJ2rer ZuSoyAU8kXp+gBfsi99xLBVNtGl0b00bBZ6EgScq84XaiUECDZXqllA9gi/JYbYNOoTc jCLg== X-Gm-Message-State: AOAM5332Ao/lTA41om96MTMpwGfJjgsH/euCNIaMfhI6Gn62BBT16B2b tqQHcPori78f0CB3h+vxFCaU2d3Ky1PrVg== X-Google-Smtp-Source: ABdhPJxoOZeNLemdMIJnH39zCDm/Ul5LFDyfMUWkJsdNPPLrnuh66Y1R/A+77lL94FS5olXL+OleHA== X-Received: by 2002:a17:907:6e2a:b0:6db:c440:532b with SMTP id sd42-20020a1709076e2a00b006dbc440532bmr22002697ejc.95.1648383309005; Sun, 27 Mar 2022 05:15:09 -0700 (PDT) Received: from tiger.museclub.art (p200300cf9f06c2008407e4c213cb9d01.dip0.t-ipconnect.de. [2003:cf:9f06:c200:8407:e4c2:13cb:9d01]) by smtp.googlemail.com with ESMTPSA id hg11-20020a1709072ccb00b006cee4fb36c7sm4530127ejc.64.2022.03.27.05.15.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Mar 2022 05:15:08 -0700 (PDT) From: Eugene Shalygin To: eugene.shalygin@gmail.com Cc: darcagn@protonmail.com, Jean Delvare , Guenter Roeck , linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] hwmon: (asus-ec-sensors) implement locking via the ACPI global lock Date: Sun, 27 Mar 2022 14:14:02 +0200 Message-Id: <20220327121404.1702631-3-eugene.shalygin@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220327121404.1702631-1-eugene.shalygin@gmail.com> References: <20220327121404.1702631-1-eugene.shalygin@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org For some board models ASUS uses the global ACPI lock to guard access to the hardware, so do we. Signed-off-by: Eugene Shalygin --- drivers/hwmon/asus-ec-sensors.c | 143 +++++++++++++++++++++++++------- 1 file changed, 115 insertions(+), 28 deletions(-) diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index 7e28fc62f717..34841eeb800f 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -56,6 +56,9 @@ static char *mutex_path_override; #define MAX_IDENTICAL_BOARD_VARIATIONS 2 +/* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */ +#define ACPI_GLOBAL_LOCK_PSEUDO_PATH ":GLOBAL_LOCK" + typedef union { u32 value; struct { @@ -166,6 +169,14 @@ static const struct ec_sensor_info known_ec_sensors[] = { struct ec_board_info { const char *board_names[MAX_IDENTICAL_BOARD_VARIATIONS]; unsigned long sensors; + /* + * Defines which mutex to use for guarding access to the state and the + * hardware. Can be either a full path to an AML mutex or the + * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock, + * or left empty to use a regular mutex object, in which case access to + * the hardware is not guarded. + */ + const char *mutex_path; }; static const struct ec_board_info board_info[] __initconst = { @@ -173,12 +184,14 @@ static const struct ec_board_info board_info[] __initconst = { .board_names = {"PRIME X570-PRO"}, .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"Pro WS X570-ACE"}, .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG CROSSHAIR VIII DARK HERO"}, @@ -187,6 +200,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG CROSSHAIR VIII FORMULA"}, @@ -194,6 +208,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = { @@ -206,6 +221,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG CROSSHAIR VIII IMPACT"}, @@ -213,12 +229,14 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG STRIX B550-E GAMING"}, .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG STRIX B550-I GAMING"}, @@ -226,6 +244,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG STRIX X570-E GAMING"}, @@ -233,17 +252,20 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG STRIX X570-F GAMING"}, .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, { .board_names = {"ROG STRIX X570-I GAMING"}, .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, }, {} }; @@ -253,6 +275,57 @@ struct ec_sensor { s32 cached_value; }; +struct lock_data { + union { + acpi_handle aml; + u32 global_lock_handle; + struct mutex regular; + } mutex; + int (*lock)(struct lock_data *data); + int (*unlock)(struct lock_data *data); +}; + +/* + * The next function pairs implement options for locking access to the + * state and the EC + */ +static int lock_via_acpi_mutex(struct lock_data *data) +{ + /* + * ASUS DSDT does not specify that access to the EC has to be guarded, + * but firmware does access it via ACPI + */ + return acpi_acquire_mutex(data->mutex.aml, NULL, + ACPI_LOCK_DELAY_MS); +} + +static int unlock_acpi_mutex(struct lock_data *data) +{ + return acpi_release_mutex(data->mutex.aml, NULL); +} + +static int lock_via_global_acpi_lock(struct lock_data *data) +{ + return acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, + &data->mutex.global_lock_handle); +} + +static int unlock_global_acpi_lock(struct lock_data *data) +{ + return acpi_release_global_lock(data->mutex.global_lock_handle); +} + +static int lock_via_mutex(struct lock_data *data) +{ + return mutex_trylock(&data->mutex.regular) ? 0 : -EBUSY; +} + +static int unlock_mutex(struct lock_data *data) +{ + mutex_unlock(&data->mutex.regular); + return 0; +} + struct ec_sensors_data { struct ec_board_info board_info; struct ec_sensor *sensors; @@ -263,7 +336,9 @@ struct ec_sensors_data { u8 banks[ASUS_EC_MAX_BANK + 1]; /* in jiffies */ unsigned long last_updated; - acpi_handle aml_mutex; + struct lock_data lock_data; + /* number of board EC sensors */ + u8 nr_sensors; /* * number of EC registers to read * (sensor might span more than 1 register) @@ -370,23 +445,36 @@ static void __init fill_ec_registers(struct ec_sensors_data *ec) } } -static acpi_handle __init asus_hw_access_mutex(struct device *dev) +static int __init setup_lock_data(struct device *dev) { const char *mutex_path; - acpi_handle res; int status; + struct ec_sensors_data *state = dev_get_drvdata(dev); mutex_path = mutex_path_override ? - mutex_path_override : ASUS_HW_ACCESS_MUTEX_ASMX; - - status = acpi_get_handle(NULL, (acpi_string)mutex_path, &res); - if (ACPI_FAILURE(status)) { - dev_err(dev, - "Could not get hardware access guard mutex '%s': error %d", - mutex_path, status); - return NULL; + mutex_path_override : state->board_info.mutex_path; + + if (!mutex_path || !strlen(mutex_path)) { + mutex_init(&state->lock_data.mutex.regular); + state->lock_data.lock = lock_via_mutex; + state->lock_data.unlock = unlock_mutex; + } else if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) { + state->lock_data.lock = lock_via_global_acpi_lock; + state->lock_data.unlock = unlock_global_acpi_lock; + } else { + status = acpi_get_handle(NULL, (acpi_string)mutex_path, + &state->lock_data.mutex.aml); + if (ACPI_FAILURE(status)) { + dev_err(dev, + "Failed to get hardware access guard AML mutex" + "'%s': error %d", + mutex_path, status); + return -ENOENT; + } + state->lock_data.lock = lock_via_acpi_mutex; + state->lock_data.unlock = unlock_acpi_mutex; } - return res; + return 0; } static int asus_ec_bank_switch(u8 bank, u8 *old) @@ -417,7 +505,8 @@ static int asus_ec_block_read(const struct device *dev, if (prev_bank) { /* oops... somebody else is working with the EC too */ dev_warn(dev, - "Concurrent access to the ACPI EC detected.\nRace condition possible."); + "Concurrent access to the ACPI EC detected.\n" + "Race condition possible."); } /* read registers minimizing bank switches. */ @@ -489,15 +578,9 @@ static int update_ec_sensors(const struct device *dev, { int status; - /* - * ASUS DSDT does not specify that access to the EC has to be guarded, - * but firmware does access it via ACPI - */ - if (ACPI_FAILURE(acpi_acquire_mutex(ec->aml_mutex, NULL, - ACPI_LOCK_DELAY_MS))) { - dev_err(dev, "Failed to acquire AML mutex"); - status = -EBUSY; - goto cleanup; + if (ec->lock_data.lock(&ec->lock_data)) { + dev_warn(dev, "Failed to acquire mutex"); + return -EBUSY; } status = asus_ec_block_read(dev, ec); @@ -505,10 +588,10 @@ static int update_ec_sensors(const struct device *dev, if (!status) { update_sensor_values(ec, ec->read_buffer); } - if (ACPI_FAILURE(acpi_release_mutex(ec->aml_mutex, NULL))) { - dev_err(dev, "Failed to release AML mutex"); - } -cleanup: + + if (ec->lock_data.unlock(&ec->lock_data)) + dev_err(dev, "Failed to release mutex"); + return status; } @@ -648,6 +731,7 @@ static int __init asus_ec_probe(struct platform_device *pdev) enum hwmon_sensor_types type; struct device *hwdev; unsigned int i; + int status; pboard_info = get_board_info(); if (!pboard_info) @@ -663,6 +747,11 @@ static int __init asus_ec_probe(struct platform_device *pdev) ec_data->sensors = devm_kcalloc(dev, sensor_count(&ec_data->board_info), sizeof(struct ec_sensor), GFP_KERNEL); + status = setup_lock_data(dev); + if (status) { + dev_err(dev, "Failed to setup state/EC locking: %d", status); + return status; + } setup_sensor_data(ec_data); ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers, sizeof(u16), GFP_KERNEL); @@ -674,8 +763,6 @@ static int __init asus_ec_probe(struct platform_device *pdev) fill_ec_registers(ec_data); - ec_data->aml_mutex = asus_hw_access_mutex(dev); - for (i = 0; i < sensor_count(&ec_data->board_info); ++i) { si = get_sensor_info(ec_data, i); if (!nr_count[si->type]) From patchwork Sun Mar 27 12:14:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugene Shalygin X-Patchwork-Id: 12792807 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0159C433F5 for ; Sun, 27 Mar 2022 12:15:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234518AbiC0MQy (ORCPT ); Sun, 27 Mar 2022 08:16:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234704AbiC0MQu (ORCPT ); Sun, 27 Mar 2022 08:16:50 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 115F337A08; Sun, 27 Mar 2022 05:15:12 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id a8so23426389ejc.8; Sun, 27 Mar 2022 05:15:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gPlOM/HUhBRjMnx4RsFxweD+FWKTwqz3KJ8tz6O9dak=; b=C9JTXaNzh84Uq+rF1EHIj2oFyPf5rSxYIhoobdZSpB35tF+yCnQfqgbMrnDuQX2NmW RoTMB6iJCZq5Gw0qdBlG3jTGKRqeLjutbmfEj4CyMDigYXjsaGxPv+EpO/mGQ1YSkQNg Tl368sxndhikpjGcm2QDVa53LMm/M+mxdhTBo2IZfDwZu3iDp2W/aRan49dfw72gDrAm RVCiuhj4Ryjgc6lQqCNxzqav7KHT+GaH2XiRsLROK8PngTc6MAbHwk1hldxR2ZpcXcfH zm7QM8SOsVcvgzVyD4T+23jRrVol0H0KC+Tf2teER+uvL/rUMdSHTKOAdS8UBPvGd/dq drtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gPlOM/HUhBRjMnx4RsFxweD+FWKTwqz3KJ8tz6O9dak=; b=t4Cm7OykpqK97EnFAGCZ6OnhE9Smf2ICg4dfGZH96nJt1UJpTe7ph4X+RxxzgOsT6c BiNw8qyrrcInTydi+dvuYDRtUykmVbhn5XI8PVo/q/YbaLAk2kOXyW9H/DOD5H22s7VI XIUzKy/zashUX74b4GNxj9BrfV0Xtv0FGOZvIsA69DC0bdQP4GFAz1BrpJutL6Qr0ycT 2Eh6aOe7lyH8tAyHdF1KnaRMBz1RmU40V5PC+mdWr2pLQhEDOIDfARMBMwSOwTUSLbTg BcxRK6M6c4d4f7DBvHcqjgng8AvLbtQlFk3WA4cxBxV6QuGFo/U9j8814VhtYWQe+xBS 3B/A== X-Gm-Message-State: AOAM53355yXJlpVr+ucHFOp0lGD4UFIrPvBHurag9K0dTRvai57yGPMZ 09ITrXAuDllLDZZOeMcP6+k= X-Google-Smtp-Source: ABdhPJzSIATIQy5CjoeehGrwpXk4z8gAEU4ZK2e1fgt7MKORtUWqTcik6a5s57R6umTuXA0yijrRLA== X-Received: by 2002:a17:907:9485:b0:6db:331:591e with SMTP id dm5-20020a170907948500b006db0331591emr21738259ejc.478.1648383310623; Sun, 27 Mar 2022 05:15:10 -0700 (PDT) Received: from tiger.museclub.art (p200300cf9f06c2008407e4c213cb9d01.dip0.t-ipconnect.de. [2003:cf:9f06:c200:8407:e4c2:13cb:9d01]) by smtp.googlemail.com with ESMTPSA id hg11-20020a1709072ccb00b006cee4fb36c7sm4530127ejc.64.2022.03.27.05.15.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Mar 2022 05:15:09 -0700 (PDT) From: Eugene Shalygin To: eugene.shalygin@gmail.com Cc: darcagn@protonmail.com, Jean Delvare , Guenter Roeck , linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] hwmon: (asus-ec-sensors) add support for board families Date: Sun, 27 Mar 2022 14:14:03 +0200 Message-Id: <20220327121404.1702631-4-eugene.shalygin@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220327121404.1702631-1-eugene.shalygin@gmail.com> References: <20220327121404.1702631-1-eugene.shalygin@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org DSDT code for AMD 400-series chipset shows that sensor addresses differ for this generation from those for the AMD 500-series boards. Signed-off-by: Eugene Shalygin --- drivers/hwmon/asus-ec-sensors.c | 43 +++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index 34841eeb800f..b4060ed1f0fa 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -135,8 +135,12 @@ enum ec_sensors { #define SENSOR_TEMP_WATER_IN BIT(ec_sensor_temp_water_in) #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out) +enum board_family { + family_amd_500_series, +}; + /* All the known sensors for ASUS EC controllers */ -static const struct ec_sensor_info known_ec_sensors[] = { +static const struct ec_sensor_info sensors_family_amd_500[] = { [ec_sensor_temp_chipset] = EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), @@ -177,6 +181,7 @@ struct ec_board_info { * the hardware is not guarded. */ const char *mutex_path; + enum board_family family; }; static const struct ec_board_info board_info[] __initconst = { @@ -185,6 +190,7 @@ static const struct ec_board_info board_info[] __initconst = { .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"Pro WS X570-ACE"}, @@ -192,6 +198,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG CROSSHAIR VIII DARK HERO"}, @@ -201,6 +208,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG CROSSHAIR VIII FORMULA"}, @@ -209,6 +217,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = { @@ -222,6 +231,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG CROSSHAIR VIII IMPACT"}, @@ -230,6 +240,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG STRIX B550-E GAMING"}, @@ -237,6 +248,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | SENSOR_FAN_CPU_OPT, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG STRIX B550-I GAMING"}, @@ -245,6 +257,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG STRIX X570-E GAMING"}, @@ -253,12 +266,14 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG STRIX X570-F GAMING"}, .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, { .board_names = {"ROG STRIX X570-I GAMING"}, @@ -266,6 +281,7 @@ static const struct ec_board_info board_info[] __initconst = { SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, }, {} }; @@ -328,6 +344,7 @@ static int unlock_mutex(struct lock_data *data) struct ec_sensors_data { struct ec_board_info board_info; + const struct ec_sensor_info *sensors_info; struct ec_sensor *sensors; /* EC registers to read from */ u16 *registers; @@ -370,7 +387,7 @@ static bool is_sensor_data_signed(const struct ec_sensor_info *si) static const struct ec_sensor_info * get_sensor_info(const struct ec_sensors_data *state, int index) { - return &known_ec_sensors[state->sensors[index].info_index]; + return state->sensors_info + state->sensors[index].info_index; } static int sensor_count(const struct ec_board_info *board) @@ -413,9 +430,9 @@ static void __init setup_sensor_data(struct ec_sensors_data *ec) s->info_index = i; s->cached_value = 0; ec->nr_registers += - known_ec_sensors[s->info_index].addr.components.size; + ec->sensors_info[s->info_index].addr.components.size; bank_found = false; - bank = known_ec_sensors[s->info_index].addr.components.bank; + bank = ec->sensors_info[s->info_index].addr.components.bank; for (j = 0; j < ec->nr_banks; j++) { if (ec->banks[j] == bank) { bank_found = true; @@ -566,8 +583,9 @@ static void update_sensor_values(struct ec_sensors_data *ec, u8 *data) struct ec_sensor *s, *sensor_end; sensor_end = ec->sensors + sensor_count(&ec->board_info); + for (s = ec->sensors; s != sensor_end; s++) { - si = &known_ec_sensors[s->info_index]; + si = ec->sensors_info + s->info_index; s->cached_value = get_sensor_value(si, data); data += si->addr.components.size; } @@ -744,14 +762,25 @@ static int __init asus_ec_probe(struct platform_device *pdev) dev_set_drvdata(dev, ec_data); ec_data->board_info = *pboard_info; - ec_data->sensors = devm_kcalloc(dev, sensor_count(&ec_data->board_info), - sizeof(struct ec_sensor), GFP_KERNEL); + switch (ec_data->board_info.family) { + case family_amd_500_series: + ec_data->sensors_info = sensors_family_amd_500; + break; + default: + dev_err(dev, "Unknown board family: %d", + ec_data->board_info.family); + return -EINVAL; + } status = setup_lock_data(dev); if (status) { dev_err(dev, "Failed to setup state/EC locking: %d", status); return status; } + + ec_data->sensors = devm_kcalloc(dev, sensor_count(&ec_data->board_info), + sizeof(struct ec_sensor), GFP_KERNEL); + setup_sensor_data(ec_data); ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers, sizeof(u16), GFP_KERNEL); From patchwork Sun Mar 27 12:14:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugene Shalygin X-Patchwork-Id: 12792808 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6920C4332F for ; Sun, 27 Mar 2022 12:15:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235510AbiC0MQ4 (ORCPT ); Sun, 27 Mar 2022 08:16:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235128AbiC0MQw (ORCPT ); Sun, 27 Mar 2022 08:16:52 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ADFEF37A0E; Sun, 27 Mar 2022 05:15:13 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id o10so23515215ejd.1; Sun, 27 Mar 2022 05:15:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=c4ZqenwWmPW0skuS2J9N+QRi5X/+snz4/hXf3e+SE94=; b=CRoLD6UegOKBpo1G6ixwRpuQpIoBjTkP3ogFKlZsDqRVQMTxlE34E7RQ0kvMWgU13z pQvtcdZXQ0IEjXgL5OKTmkfE7hxjE6jN5F02FD31hBt4fkHTYTieKHKXSGJfU52/J0MK 47AKpkhQX2ttRwkjNkJm231OQTLkXRJtIzE/UtJpE9RXch7c/kxSplaTJcurGaCO6W3W pzgW8kB/jpSN7fuX0b+pTf5NfDm1DKB8ccj+u4Yq/QWM1XCXPoSsJ45qaDSjmUnCeVqW 35AhAu/lS+ggF3vFyjzx7YaEk0aejiJ8FWgM5ZWeZrvanY4dXVbIH0F7bduH3rbMXlLC eJDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=c4ZqenwWmPW0skuS2J9N+QRi5X/+snz4/hXf3e+SE94=; b=kGCvjLPPRvh4tNp3S+EQRc26C2LF9qvc0er5vBpnndKcV3I6wfRF/0Xr3x8CGGlqQ4 S96rdTlsF0xqyKisXuPWPOV9DKu0lPOzAlFY7La34LFOKUK54mgD9rxoOXxKISF3dtxx 84LV+PLy+xDVBTxb+6iElO43FDLRc0T5X6xv6XFq2/XWZQn7etULhE/wsD4KyeNtqVuz f8D+pMI6L7iU8/LaE7BqQMiZaOF38SIP3iAVmvY0snXQsW7zOwwL5NoaOW1YHQx+bbLM gTWuulYs60qJIWFQ2atYd3Ahpjszh1Hr4RC+NQrFMBbXd2Ll2t/8ZixkkR7iqHcTih2F RgfQ== X-Gm-Message-State: AOAM530W/gEn0UxApd4Mc7N2CjMuJENdTYQA0iFDPB51t2Ll8i6KNAU0 V6ZiPFis0RvRuSL78wEWKe0= X-Google-Smtp-Source: ABdhPJy6f16s5PmNJUsXBrTRkotz24owRvjZ0kbXNY/+Ut1f2weCS4jcJzq+8YicgcPNV2M6uwJKOg== X-Received: by 2002:a17:907:3f9c:b0:6d8:116d:476b with SMTP id hr28-20020a1709073f9c00b006d8116d476bmr21152184ejc.432.1648383312207; Sun, 27 Mar 2022 05:15:12 -0700 (PDT) Received: from tiger.museclub.art (p200300cf9f06c2008407e4c213cb9d01.dip0.t-ipconnect.de. [2003:cf:9f06:c200:8407:e4c2:13cb:9d01]) by smtp.googlemail.com with ESMTPSA id hg11-20020a1709072ccb00b006cee4fb36c7sm4530127ejc.64.2022.03.27.05.15.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 27 Mar 2022 05:15:11 -0700 (PDT) From: Eugene Shalygin To: eugene.shalygin@gmail.com Cc: darcagn@protonmail.com, Jean Delvare , Guenter Roeck , linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] hwmon: (asus-ec-sensors) add PRIME X470-PRO board Date: Sun, 27 Mar 2022 14:14:04 +0200 Message-Id: <20220327121404.1702631-5-eugene.shalygin@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220327121404.1702631-1-eugene.shalygin@gmail.com> References: <20220327121404.1702631-1-eugene.shalygin@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org This board is supposed to be handled by the asus-wmi-sensors driver, but due to a buggy WMI implementation the driver and the official ASUS software make the BIOS hang together with fan controls. This driver complements values provided by the SIO chip and does not freeze the BIOS, as tested by a user [2]. [1] https://github.com/electrified/asus-wmi-sensors/blob/master/README.md [2] https://github.com/zeule/asus-ec-sensors/issues/12 Signed-off-by: Eugene Shalygin --- drivers/hwmon/asus-ec-sensors.c | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index b4060ed1f0fa..ce0e1d97b60b 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -136,10 +136,41 @@ enum ec_sensors { #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out) enum board_family { + family_amd_400_series, family_amd_500_series, }; /* All the known sensors for ASUS EC controllers */ +static const struct ec_sensor_info sensors_family_amd_400[] = { + [ec_sensor_temp_chipset] = + EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), + [ec_sensor_temp_cpu] = + EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b), + [ec_sensor_temp_mb] = + EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c), + [ec_sensor_temp_t_sensor] = + EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d), + [ec_sensor_temp_vrm] = + EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e), + [ec_sensor_in_cpu_core] = + EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2), + [ec_sensor_fan_cpu_opt] = + EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc), + [ec_sensor_fan_vrm_hs] = + EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2), + [ec_sensor_fan_chipset] = + /* no chipset fans in this generation */ + EC_SENSOR("Chipset", hwmon_fan, 0, 0x00, 0x00), + [ec_sensor_fan_water_flow] = + EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xb4), + [ec_sensor_curr_cpu] = + EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4), + [ec_sensor_temp_water_in] = + EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x0d), + [ec_sensor_temp_water_out] = + EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x0b), +}; + static const struct ec_sensor_info sensors_family_amd_500[] = { [ec_sensor_temp_chipset] = EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a), @@ -185,6 +216,15 @@ struct ec_board_info { }; static const struct ec_board_info board_info[] __initconst = { + { + .board_names = {"PRIME X470-PRO"}, + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CPU_OPT | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, + .family = family_amd_400_series, + }, { .board_names = {"PRIME X570-PRO"}, .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | @@ -762,7 +802,11 @@ static int __init asus_ec_probe(struct platform_device *pdev) dev_set_drvdata(dev, ec_data); ec_data->board_info = *pboard_info; + switch (ec_data->board_info.family) { + case family_amd_400_series: + ec_data->sensors_info = sensors_family_amd_400; + break; case family_amd_500_series: ec_data->sensors_info = sensors_family_amd_500; break;