| 1 | // SPDX-License-Identifier: GPL-2.0 | 
|---|
| 2 | /* | 
|---|
| 3 | *  Copyright (C) 2008 Intel Corp | 
|---|
| 4 | *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com> | 
|---|
| 5 | *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com> | 
|---|
| 6 | *  Copyright 2022 Linaro Limited | 
|---|
| 7 | * | 
|---|
| 8 | * Thermal trips handling | 
|---|
| 9 | */ | 
|---|
| 10 | #include "thermal_core.h" | 
|---|
| 11 |  | 
|---|
| 12 | static const char *trip_type_names[] = { | 
|---|
| 13 | [THERMAL_TRIP_ACTIVE] = "active", | 
|---|
| 14 | [THERMAL_TRIP_PASSIVE] = "passive", | 
|---|
| 15 | [THERMAL_TRIP_HOT] = "hot", | 
|---|
| 16 | [THERMAL_TRIP_CRITICAL] = "critical", | 
|---|
| 17 | }; | 
|---|
| 18 |  | 
|---|
| 19 | const char *thermal_trip_type_name(enum thermal_trip_type trip_type) | 
|---|
| 20 | { | 
|---|
| 21 | if (trip_type < THERMAL_TRIP_ACTIVE || trip_type > THERMAL_TRIP_CRITICAL) | 
|---|
| 22 | return "unknown"; | 
|---|
| 23 |  | 
|---|
| 24 | return trip_type_names[trip_type]; | 
|---|
| 25 | } | 
|---|
| 26 |  | 
|---|
| 27 | int for_each_thermal_trip(struct thermal_zone_device *tz, | 
|---|
| 28 | int (*cb)(struct thermal_trip *, void *), | 
|---|
| 29 | void *data) | 
|---|
| 30 | { | 
|---|
| 31 | struct thermal_trip_desc *td; | 
|---|
| 32 | int ret; | 
|---|
| 33 |  | 
|---|
| 34 | for_each_trip_desc(tz, td) { | 
|---|
| 35 | ret = cb(&td->trip, data); | 
|---|
| 36 | if (ret) | 
|---|
| 37 | return ret; | 
|---|
| 38 | } | 
|---|
| 39 |  | 
|---|
| 40 | return 0; | 
|---|
| 41 | } | 
|---|
| 42 | EXPORT_SYMBOL_GPL(for_each_thermal_trip); | 
|---|
| 43 |  | 
|---|
| 44 | int thermal_zone_for_each_trip(struct thermal_zone_device *tz, | 
|---|
| 45 | int (*cb)(struct thermal_trip *, void *), | 
|---|
| 46 | void *data) | 
|---|
| 47 | { | 
|---|
| 48 | guard(thermal_zone)(T: tz); | 
|---|
| 49 |  | 
|---|
| 50 | return for_each_thermal_trip(tz, cb, data); | 
|---|
| 51 | } | 
|---|
| 52 | EXPORT_SYMBOL_GPL(thermal_zone_for_each_trip); | 
|---|
| 53 |  | 
|---|
| 54 | void thermal_zone_set_trips(struct thermal_zone_device *tz, int low, int high) | 
|---|
| 55 | { | 
|---|
| 56 | int ret; | 
|---|
| 57 |  | 
|---|
| 58 | lockdep_assert_held(&tz->lock); | 
|---|
| 59 |  | 
|---|
| 60 | if (!tz->ops.set_trips) | 
|---|
| 61 | return; | 
|---|
| 62 |  | 
|---|
| 63 | /* No need to change trip points */ | 
|---|
| 64 | if (tz->prev_low_trip == low && tz->prev_high_trip == high) | 
|---|
| 65 | return; | 
|---|
| 66 |  | 
|---|
| 67 | tz->prev_low_trip = low; | 
|---|
| 68 | tz->prev_high_trip = high; | 
|---|
| 69 |  | 
|---|
| 70 | dev_dbg(&tz->device, | 
|---|
| 71 | "new temperature boundaries: %d < x < %d\n", low, high); | 
|---|
| 72 |  | 
|---|
| 73 | /* | 
|---|
| 74 | * Set a temperature window. When this window is left the driver | 
|---|
| 75 | * must inform the thermal core via thermal_zone_device_update. | 
|---|
| 76 | */ | 
|---|
| 77 | ret = tz->ops.set_trips(tz, low, high); | 
|---|
| 78 | if (ret) | 
|---|
| 79 | dev_err(&tz->device, "Failed to set trips: %d\n", ret); | 
|---|
| 80 | } | 
|---|
| 81 |  | 
|---|
| 82 | int thermal_zone_trip_id(const struct thermal_zone_device *tz, | 
|---|
| 83 | const struct thermal_trip *trip) | 
|---|
| 84 | { | 
|---|
| 85 | /* | 
|---|
| 86 | * Assume the trip to be located within the bounds of the thermal | 
|---|
| 87 | * zone's trips[] table. | 
|---|
| 88 | */ | 
|---|
| 89 | return trip_to_trip_desc(trip) - tz->trips; | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|