1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2017 Chelsio Communications. All rights reserved. |
4 | * |
5 | * Written by: Ganesh Goudar (ganeshgr@chelsio.com) |
6 | */ |
7 | |
8 | #include "cxgb4.h" |
9 | |
10 | #define CXGB4_NUM_TRIPS 1 |
11 | |
12 | static int cxgb4_thermal_get_temp(struct thermal_zone_device *tzdev, |
13 | int *temp) |
14 | { |
15 | struct adapter *adap = thermal_zone_device_priv(tzd: tzdev); |
16 | u32 param, val; |
17 | int ret; |
18 | |
19 | param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | |
20 | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) | |
21 | FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_TMP)); |
22 | |
23 | ret = t4_query_params(adap, mbox: adap->mbox, pf: adap->pf, vf: 0, nparams: 1, |
24 | params: ¶m, val: &val); |
25 | if (ret < 0 || val == 0) |
26 | return -1; |
27 | |
28 | *temp = val * 1000; |
29 | return 0; |
30 | } |
31 | |
32 | static struct thermal_zone_device_ops cxgb4_thermal_ops = { |
33 | .get_temp = cxgb4_thermal_get_temp, |
34 | }; |
35 | |
36 | static struct thermal_trip trip = { .type = THERMAL_TRIP_CRITICAL } ; |
37 | |
38 | int cxgb4_thermal_init(struct adapter *adap) |
39 | { |
40 | struct ch_thermal *ch_thermal = &adap->ch_thermal; |
41 | char ch_tz_name[THERMAL_NAME_LENGTH]; |
42 | int num_trip = CXGB4_NUM_TRIPS; |
43 | u32 param, val; |
44 | int ret; |
45 | |
46 | /* on older firmwares we may not get the trip temperature, |
47 | * set the num of trips to 0. |
48 | */ |
49 | param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | |
50 | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) | |
51 | FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_MAXTMPTHRESH)); |
52 | |
53 | ret = t4_query_params(adap, mbox: adap->mbox, pf: adap->pf, vf: 0, nparams: 1, |
54 | params: ¶m, val: &val); |
55 | if (ret < 0) { |
56 | num_trip = 0; /* could not get trip temperature */ |
57 | } else { |
58 | trip.temperature = val * 1000; |
59 | } |
60 | |
61 | snprintf(buf: ch_tz_name, size: sizeof(ch_tz_name), fmt: "cxgb4_%s" , adap->name); |
62 | ch_thermal->tzdev = thermal_zone_device_register_with_trips(type: ch_tz_name, trips: &trip, num_trips: num_trip, |
63 | mask: 0, devdata: adap, |
64 | ops: &cxgb4_thermal_ops, |
65 | NULL, passive_delay: 0, polling_delay: 0); |
66 | if (IS_ERR(ptr: ch_thermal->tzdev)) { |
67 | ret = PTR_ERR(ptr: ch_thermal->tzdev); |
68 | dev_err(adap->pdev_dev, "Failed to register thermal zone\n" ); |
69 | ch_thermal->tzdev = NULL; |
70 | return ret; |
71 | } |
72 | |
73 | ret = thermal_zone_device_enable(tz: ch_thermal->tzdev); |
74 | if (ret) { |
75 | dev_err(adap->pdev_dev, "Failed to enable thermal zone\n" ); |
76 | thermal_zone_device_unregister(tz: adap->ch_thermal.tzdev); |
77 | return ret; |
78 | } |
79 | |
80 | return 0; |
81 | } |
82 | |
83 | int cxgb4_thermal_remove(struct adapter *adap) |
84 | { |
85 | if (adap->ch_thermal.tzdev) { |
86 | thermal_zone_device_unregister(tz: adap->ch_thermal.tzdev); |
87 | adap->ch_thermal.tzdev = NULL; |
88 | } |
89 | return 0; |
90 | } |
91 | |