From patchwork Tue Jul 25 18:12:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 125771 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9010:0:b0:3e4:2afc:c1 with SMTP id l16csp2662834vqg; Tue, 25 Jul 2023 11:38:55 -0700 (PDT) X-Google-Smtp-Source: APBJJlHKiISXS69eRdlWMouS0x8zkbr5HKZ0pUOY30/6SUWZ4Insvtb7OIA9T/6ugFo58Rvnvsyr X-Received: by 2002:a05:6a00:3a03:b0:678:5629:fd43 with SMTP id fj3-20020a056a003a0300b006785629fd43mr22987pfb.9.1690310335578; Tue, 25 Jul 2023 11:38:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690310335; cv=none; d=google.com; s=arc-20160816; b=T8yeXov16txbjNxjZvjxkz9EIDdw/9phjXUXqirujI0561dQavOrG9rsCTRYh/zA6V wXhzymBDWlovpPdpDQjLJgAHzF8vwOwd8ytWXG9fkKmsIgr35wKJGqKivMs5I5KZXAag HAzwbpH6IPBVCgE0sanQSdFFHhKGCAARqkGiqHMVqbCcJ4Si8YQG+c1SOYjrJc4v4K3h rKufNWh/f95LtApyfBCDyE568dC3Plbrp/31LoPzCYtdtjx0mz+pyakg2rKVSyJdKAWH NbxcJA9BkuiHEnfYpwJUw62rj6V9+5o3hloHrgk8tkYOd2P8mZNhId8vdUbeKlPnj7Un x0/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=xy0u3F8wpi7llzoR0QniCwcp76QMhJuFT8c+c0HEEbo=; fh=WAm0nkxw3rD71A4QzwJS1JiPPKRsyn91IiWMPsOrzoY=; b=zyZRcM2b08FENkop3KZllBnXgljUxdPWj4eCxoAYP16n+EgGyY538O9voJxV+BaACm AKsWX65b1d+Xd5IIBsv80Hoox5fX+l88YlSsHGd4HKZ7M4zrVsJ6P6+eiNoIYK5SGzVr PBT1NjJolwYVINoPG3hcI7UNknruqIIHK42WDrEjvq/JITRghVQyH/3GrRcdfGhpEx+F uLsR+ZO4FF2BBGt7c6PVD4Y34BcpH/Kqhr+xpoglhsL7mzZvLUfDk8UsH4wY6361/tGa 7lrrbI2c+Di3Ub98NWZP5fqKz8ZYPx+3NranxYNgHPQPwvRB/CzcS42EuB7/NU/BaN3Q WQ8A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ei35-20020a056a0080e300b0067e5edde6eesi11019521pfb.302.2023.07.25.11.38.41; Tue, 25 Jul 2023 11:38:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232437AbjGYSMK (ORCPT + 99 others); Tue, 25 Jul 2023 14:12:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229746AbjGYSMI (ORCPT ); Tue, 25 Jul 2023 14:12:08 -0400 Received: from cloudserver094114.home.pl (cloudserver094114.home.pl [79.96.170.134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E60C1FDD; Tue, 25 Jul 2023 11:12:06 -0700 (PDT) Received: from localhost (127.0.0.1) (HELO v370.home.net.pl) by /usr/run/smtp (/usr/run/postfix/private/idea_relay_lmtp) via UNIX with SMTP (IdeaSmtpServer 5.2.0) id 65bcc88fa94f1179; Tue, 25 Jul 2023 20:12:05 +0200 Received: from kreacher.localnet (unknown [195.136.19.94]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by v370.home.net.pl (Postfix) with ESMTPSA id 861AB661BBA; Tue, 25 Jul 2023 20:12:04 +0200 (CEST) From: "Rafael J. Wysocki" To: Linux ACPI Cc: LKML , Linux PM , Michal Wilczynski , Zhang Rui , Srinivas Pandruvada , Daniel Lezcano Subject: [PATCH v3.1 6/8] ACPI: thermal: Use trip point table to register thermal zones Date: Tue, 25 Jul 2023 20:12:04 +0200 Message-ID: <4504417.LvFx2qVVIh@kreacher> In-Reply-To: <3177785.5fSG56mABF@kreacher> References: <13318886.uLZWGnKmhe@kreacher> <12254967.O9o76ZdvQC@kreacher> <3177785.5fSG56mABF@kreacher> MIME-Version: 1.0 X-CLIENT-IP: 195.136.19.94 X-CLIENT-HOSTNAME: 195.136.19.94 X-VADE-SPAMSTATE: clean X-VADE-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedviedriedtgdduudelucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecujffqoffgrffnpdggtffipffknecuuegrihhlohhuthemucduhedtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkfgjfhgggfgtsehtufertddttdejnecuhfhrohhmpedftfgrfhgrvghlucflrdcuhgihshhotghkihdfuceorhhjfiesrhhjfiihshhotghkihdrnhgvtheqnecuggftrfgrthhtvghrnhepvdffueeitdfgvddtudegueejtdffteetgeefkeffvdeftddttdeuhfegfedvjefhnecukfhppeduleehrddufeeirdduledrleegnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepudelhedrudefiedrudelrdelgedphhgvlhhopehkrhgvrggthhgvrhdrlhhotggrlhhnvghtpdhmrghilhhfrhhomhepfdftrghfrggvlhculfdrucghhihsohgtkhhifdcuoehrjhifsehrjhifhihsohgtkhhirdhnvghtqedpnhgspghrtghpthhtohepjedprhgtphhtthhopehlihhnuhigqdgrtghpihesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehmihgthhgrlhdrfihilhgtiiihnhhskhhisehinhhtvghlrdgtohhmpdhr tghpthhtoheprhhuihdriihhrghnghesihhnthgvlhdrtghomhdprhgtphhtthhopehsrhhinhhivhgrshdrphgrnhgurhhuvhgruggrsehlihhnuhigrdhinhhtvghlrdgtohhm X-DCC--Metrics: v370.home.net.pl 1024; Body=7 Fuz1=7 Fuz2=7 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771784738121547230 X-GMAIL-MSGID: 1772418850404197276 From: Rafael J. Wysocki Make the ACPI thermal driver use thermal_zone_device_register_with_trips() to register its thermal zones. For this purpose, make it create a trip point table and pass it to thermal_zone_device_register_with_trips() as an argument and use the struct thermal_trip_ref introduced previously to connect the generic thermal trip structures to the internal data structures representing trip points in the driver. Signed-off-by: Rafael J. Wysocki --- This is a bug-fix update that doesn't affect any other patches in the series, so sending it separately as v3.1. v3 -> v3.1: * Do not pass THERMAL_TEMP_INVALID to acpi_thermal_trip_update_temp() in acpi_thermal_check_fn(). v2 -> v3: * Fix error code path memory leak in acpi_thermal_register_thermal_zone(). * Notice that the critical and hot trips never change after initialization, so don't add struct thermal_trip_ref to any of them. v1 -> v2: * Use thermal_zone_device_lock()/thermal_zone_device_unlock() in acpi_thermal_check_fn() explicitly and call __thermal_zone_device_update() from there without unlocking the thermal zone. * Export __thermal_zone_device_update() to modules (so it can be called by the ACPI thermal code). --- drivers/acpi/thermal.c | 107 ++++++++++++++++++++++++++++++++++++++--- drivers/thermal/thermal_core.c | 1 include/linux/thermal.h | 2 3 files changed, 103 insertions(+), 7 deletions(-) Index: linux-pm/drivers/acpi/thermal.c =================================================================== --- linux-pm.orig/drivers/acpi/thermal.c +++ linux-pm/drivers/acpi/thermal.c @@ -107,6 +107,7 @@ struct acpi_thermal_hot { }; struct acpi_thermal_passive { + struct thermal_trip_ref trip_ref; struct acpi_handle_list devices; unsigned long temperature; unsigned long tc1; @@ -116,6 +117,7 @@ struct acpi_thermal_passive { }; struct acpi_thermal_active { + struct thermal_trip_ref trip_ref; struct acpi_handle_list devices; unsigned long temperature; bool valid; @@ -137,6 +139,7 @@ struct acpi_thermal { unsigned long polling_frequency; volatile u8 zombie; struct acpi_thermal_trips trips; + struct thermal_trip *trip_table; struct acpi_handle_list devices; struct thermal_zone_device *thermal_zone; int kelvin_offset; /* in millidegrees */ @@ -190,6 +193,14 @@ static int acpi_thermal_get_polling_freq return 0; } +static void acpi_thermal_trip_update_temp(struct acpi_thermal *tz, + struct thermal_trip *trip, + long temperature) +{ + trip->temperature = deci_kelvin_to_millicelsius_with_offset(temperature, + tz->kelvin_offset); +} + static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) { acpi_status status; @@ -756,6 +767,7 @@ static void acpi_thermal_zone_sysfs_remo static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) { + struct thermal_trip *trip; int passive_delay = 0; int trip_count = 0; int result; @@ -776,12 +788,54 @@ static int acpi_thermal_register_thermal for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid; i++) trip_count++; - tz->thermal_zone = thermal_zone_device_register("acpitz", trip_count, 0, - tz, &acpi_thermal_zone_ops, - NULL, passive_delay, - tz->polling_frequency * 100); - if (IS_ERR(tz->thermal_zone)) - return -ENODEV; + trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); + if (!trip) + return -ENOMEM; + + tz->trip_table = trip; + + if (tz->trips.critical.valid) { + trip->type = THERMAL_TRIP_CRITICAL; + acpi_thermal_trip_update_temp(tz, trip, + tz->trips.critical.temperature); + trip++; + } + + if (tz->trips.hot.valid) { + trip->type = THERMAL_TRIP_HOT; + acpi_thermal_trip_update_temp(tz, trip, + tz->trips.hot.temperature); + trip++; + } + + if (tz->trips.passive.valid) { + trip->type = THERMAL_TRIP_PASSIVE; + acpi_thermal_trip_update_temp(tz, trip, + tz->trips.passive.temperature); + trip->driver_ref = &tz->trips.passive.trip_ref; + trip++; + } + + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].valid; i++) { + trip->type = THERMAL_TRIP_ACTIVE; + acpi_thermal_trip_update_temp(tz, trip, + tz->trips.active[i].temperature); + trip->driver_ref = &tz->trips.active[i].trip_ref; + trip++; + } + + tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz", + tz->trip_table, + trip_count, + 0, tz, + &acpi_thermal_zone_ops, + NULL, + passive_delay, + tz->polling_frequency * 100); + if (IS_ERR(tz->thermal_zone)) { + result = PTR_ERR(tz->thermal_zone); + goto free_trip_table; + } result = acpi_thermal_zone_sysfs_add(tz); if (result) @@ -809,6 +863,8 @@ remove_links: acpi_thermal_zone_sysfs_remove(tz); unregister_tzd: thermal_zone_device_unregister(tz->thermal_zone); +free_trip_table: + kfree(tz->trip_table); return result; } @@ -817,6 +873,7 @@ static void acpi_thermal_unregister_ther { acpi_thermal_zone_sysfs_remove(tz); thermal_zone_device_unregister(tz->thermal_zone); + kfree(tz->trip_table); tz->thermal_zone = NULL; acpi_bus_detach_private_data(tz->device->handle); } @@ -950,6 +1007,8 @@ static void acpi_thermal_check_fn(struct { struct acpi_thermal *tz = container_of(work, struct acpi_thermal, thermal_check_work); + struct thermal_trip *trip; + int i; /* * In general, it is not sufficient to check the pending bit, because @@ -964,7 +1023,41 @@ static void acpi_thermal_check_fn(struct mutex_lock(&tz->thermal_check_lock); - thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); + thermal_zone_device_lock(tz->thermal_zone); + + trip = tz->trips.passive.trip_ref.trip; + if (trip) { + /* + * This means that the passive trip was valid initially, so + * update its temperature in case it has changed or the trip + * has become invalid. + */ + if (tz->trips.passive.valid) + acpi_thermal_trip_update_temp(tz, trip, + tz->trips.passive.temperature); + else + trip->temperature = THERMAL_TEMP_INVALID; + } + + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { + trip = tz->trips.active[i].trip_ref.trip; + if (trip) { + /* + * This means that the active trip #i was valid + * initially, so update its temperature in case it has + * changed or the trip has become invalid. + */ + if (tz->trips.active[i].valid) + acpi_thermal_trip_update_temp(tz, trip, + tz->trips.active[i].temperature); + else + trip->temperature = THERMAL_TEMP_INVALID; + } + } + + __thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); + + thermal_zone_device_unlock(tz->thermal_zone); refcount_inc(&tz->thermal_check_count); Index: linux-pm/drivers/thermal/thermal_core.c =================================================================== --- linux-pm.orig/drivers/thermal/thermal_core.c +++ linux-pm/drivers/thermal/thermal_core.c @@ -429,6 +429,7 @@ void __thermal_zone_device_update(struct monitor_thermal_zone(tz); } +EXPORT_SYMBOL_GPL(__thermal_zone_device_update); static int thermal_zone_device_set_mode(struct thermal_zone_device *tz, enum thermal_device_mode mode) Index: linux-pm/include/linux/thermal.h =================================================================== --- linux-pm.orig/include/linux/thermal.h +++ linux-pm/include/linux/thermal.h @@ -334,6 +334,8 @@ int thermal_zone_bind_cooling_device(str unsigned int); int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *); +void __thermal_zone_device_update(struct thermal_zone_device *, + enum thermal_notify_event); void thermal_zone_device_update(struct thermal_zone_device *, enum thermal_notify_event); void thermal_zone_device_lock(struct thermal_zone_device *tz);