Skip to content

Commit b1fdcdb

Browse files
author
Herton R. Krzesinski
committed
Merge: Update thermal/drivers/qcom for Qdrive3
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1871 Bugzilla: https://bugzilla.redhat.com/2159524 Bring upstream support and fixes for the thermal subsystem that are relevant for Qdrive3 (sa8540p-ride). Signed-off-by: Eric Chanudet <echanude@redhat.com> Approved-by: Andrew Halaney <ahalaney@redhat.com> Approved-by: Adrien Thierry <athierry@redhat.com> Approved-by: Brian Masney <bmasney@redhat.com> Approved-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents 63fab61 + b9fd186 commit b1fdcdb

File tree

8 files changed

+96
-54
lines changed

8 files changed

+96
-54
lines changed

drivers/iio/adc/qcom-vadc-common.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,17 @@ u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio,
677677
}
678678
EXPORT_SYMBOL(qcom_adc_tm5_temp_volt_scale);
679679

680+
u16 qcom_adc_tm5_gen2_temp_res_scale(int temp)
681+
{
682+
int64_t resistance;
683+
684+
resistance = qcom_vadc_map_temp_voltage(adcmap7_100k,
685+
ARRAY_SIZE(adcmap7_100k), temp);
686+
687+
return div64_s64(resistance * RATIO_MAX_ADC7, resistance + R_PU_100K);
688+
}
689+
EXPORT_SYMBOL(qcom_adc_tm5_gen2_temp_res_scale);
690+
680691
int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
681692
unsigned int prescale_ratio,
682693
const struct adc5_data *data,

drivers/thermal/qcom/tsens-8960.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,12 @@ static const struct tsens_ops ops_8960 = {
269269
static struct tsens_features tsens_8960_feat = {
270270
.ver_major = VER_0,
271271
.crit_int = 0,
272+
.combo_int = 0,
272273
.adc = 1,
273274
.srot_split = 0,
274275
.max_sensors = 11,
276+
.trip_min_temp = -40000,
277+
.trip_max_temp = 120000,
275278
};
276279

277280
struct tsens_plat_data data_8960 = {

drivers/thermal/qcom/tsens-v0_1.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,12 @@ static int calibrate_9607(struct tsens_priv *priv)
539539
static struct tsens_features tsens_v0_1_feat = {
540540
.ver_major = VER_0_1,
541541
.crit_int = 0,
542+
.combo_int = 0,
542543
.adc = 1,
543544
.srot_split = 1,
544545
.max_sensors = 11,
546+
.trip_min_temp = -40000,
547+
.trip_max_temp = 120000,
545548
};
546549

547550
static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
@@ -604,7 +607,7 @@ static const struct tsens_ops ops_8939 = {
604607
struct tsens_plat_data data_8939 = {
605608
.num_sensors = 10,
606609
.ops = &ops_8939,
607-
.hw_ids = (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 },
610+
.hw_ids = (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 },
608611

609612
.feat = &tsens_v0_1_feat,
610613
.fields = tsens_v0_1_regfields,

drivers/thermal/qcom/tsens-v1.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,12 @@ static int calibrate_8976(struct tsens_priv *priv)
302302
static struct tsens_features tsens_v1_feat = {
303303
.ver_major = VER_1_X,
304304
.crit_int = 0,
305+
.combo_int = 0,
305306
.adc = 1,
306307
.srot_split = 1,
307308
.max_sensors = 11,
309+
.trip_min_temp = -40000,
310+
.trip_max_temp = 120000,
308311
};
309312

310313
static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {

drivers/thermal/qcom/tsens-v2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131
static struct tsens_features tsens_v2_feat = {
3232
.ver_major = VER_2_X,
3333
.crit_int = 1,
34+
.combo_int = 0,
3435
.adc = 0,
3536
.srot_split = 1,
3637
.max_sensors = 16,
38+
.trip_min_temp = -40000,
39+
.trip_max_temp = 120000,
3740
};
3841

3942
static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {

drivers/thermal/qcom/tsens.c

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/regmap.h>
1919
#include <linux/slab.h>
2020
#include <linux/thermal.h>
21+
#include "../thermal_hwmon.h"
2122
#include "tsens.h"
2223

2324
/**
@@ -417,7 +418,7 @@ static irqreturn_t tsens_critical_irq_thread(int irq, void *data)
417418
const struct tsens_sensor *s = &priv->sensor[i];
418419
u32 hw_id = s->hw_id;
419420

420-
if (IS_ERR(s->tzd))
421+
if (!s->tzd)
421422
continue;
422423
if (!tsens_threshold_violated(priv, hw_id, &d))
423424
continue;
@@ -467,7 +468,7 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
467468
const struct tsens_sensor *s = &priv->sensor[i];
468469
u32 hw_id = s->hw_id;
469470

470-
if (IS_ERR(s->tzd))
471+
if (!s->tzd)
471472
continue;
472473
if (!tsens_threshold_violated(priv, hw_id, &d))
473474
continue;
@@ -531,6 +532,27 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
531532
return IRQ_HANDLED;
532533
}
533534

535+
/**
536+
* tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts
537+
* @irq: irq number
538+
* @data: tsens controller private data
539+
*
540+
* Handle the combined interrupt as if it were 2 separate interrupts, so call the
541+
* critical handler first and then the up/low one.
542+
*
543+
* Return: IRQ_HANDLED
544+
*/
545+
static irqreturn_t tsens_combined_irq_thread(int irq, void *data)
546+
{
547+
irqreturn_t ret;
548+
549+
ret = tsens_critical_irq_thread(irq, data);
550+
if (ret != IRQ_HANDLED)
551+
return ret;
552+
553+
return tsens_irq_thread(irq, data);
554+
}
555+
534556
static int tsens_set_trips(void *_sensor, int low, int high)
535557
{
536558
struct tsens_sensor *s = _sensor;
@@ -551,8 +573,8 @@ static int tsens_set_trips(void *_sensor, int low, int high)
551573
dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
552574
hw_id, __func__, low, high);
553575

554-
cl_high = clamp_val(high, -40000, 120000);
555-
cl_low = clamp_val(low, -40000, 120000);
576+
cl_high = clamp_val(high, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
577+
cl_low = clamp_val(low, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
556578

557579
high_val = tsens_mC_to_hw(s, cl_high);
558580
low_val = tsens_mC_to_hw(s, cl_low);
@@ -603,22 +625,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp)
603625
int ret;
604626

605627
/* VER_0 doesn't have VALID bit */
606-
if (tsens_version(priv) >= VER_0_1) {
607-
ret = regmap_field_read(priv->rf[valid_idx], &valid);
608-
if (ret)
609-
return ret;
610-
while (!valid) {
611-
/* Valid bit is 0 for 6 AHB clock cycles.
612-
* At 19.2MHz, 1 AHB clock is ~60ns.
613-
* We should enter this loop very, very rarely.
614-
*/
615-
ndelay(400);
616-
ret = regmap_field_read(priv->rf[valid_idx], &valid);
617-
if (ret)
618-
return ret;
619-
}
620-
}
628+
if (tsens_version(priv) == VER_0)
629+
goto get_temp;
621630

631+
/* Valid bit is 0 for 6 AHB clock cycles.
632+
* At 19.2MHz, 1 AHB clock is ~60ns.
633+
* We should enter this loop very, very rarely.
634+
* Wait 1 us since it's the min of poll_timeout macro.
635+
* Old value was 400 ns.
636+
*/
637+
ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid,
638+
valid, 1, 20 * USEC_PER_MSEC);
639+
if (ret)
640+
return ret;
641+
642+
get_temp:
622643
/* Valid bit is set, OK to read the temperature */
623644
*temp = tsens_hw_to_mC(s, temp_idx);
624645

@@ -692,7 +713,7 @@ static int dbg_version_show(struct seq_file *s, void *data)
692713
return ret;
693714
seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver);
694715
} else {
695-
seq_puts(s, "0.1.0\n");
716+
seq_printf(s, "0.%d.0\n", priv->feat->ver_major);
696717
}
697718

698719
return 0;
@@ -704,21 +725,14 @@ DEFINE_SHOW_ATTRIBUTE(dbg_sensors);
704725
static void tsens_debug_init(struct platform_device *pdev)
705726
{
706727
struct tsens_priv *priv = platform_get_drvdata(pdev);
707-
struct dentry *root, *file;
708728

709-
root = debugfs_lookup("tsens", NULL);
710-
if (!root)
729+
priv->debug_root = debugfs_lookup("tsens", NULL);
730+
if (!priv->debug_root)
711731
priv->debug_root = debugfs_create_dir("tsens", NULL);
712-
else
713-
priv->debug_root = root;
714-
715-
file = debugfs_lookup("version", priv->debug_root);
716-
if (!file)
717-
debugfs_create_file("version", 0444, priv->debug_root,
718-
pdev, &dbg_version_fops);
719732

720733
/* A directory for each instance of the TSENS IP */
721734
priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root);
735+
debugfs_create_file("version", 0444, priv->debug, pdev, &dbg_version_fops);
722736
debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops);
723737
}
724738
#else
@@ -918,8 +932,6 @@ int __init init_common(struct tsens_priv *priv)
918932
if (tsens_version(priv) >= VER_0_1)
919933
tsens_enable_irq(priv);
920934

921-
tsens_debug_init(op);
922-
923935
err_put_device:
924936
put_device(&op->dev);
925937
return ret;
@@ -933,17 +945,6 @@ static int tsens_get_temp(void *data, int *temp)
933945
return priv->ops->get_temp(s, temp);
934946
}
935947

936-
static int tsens_get_trend(void *data, int trip, enum thermal_trend *trend)
937-
{
938-
struct tsens_sensor *s = data;
939-
struct tsens_priv *priv = s->priv;
940-
941-
if (priv->ops->get_trend)
942-
return priv->ops->get_trend(s, trend);
943-
944-
return -ENOTSUPP;
945-
}
946-
947948
static int __maybe_unused tsens_suspend(struct device *dev)
948949
{
949950
struct tsens_priv *priv = dev_get_drvdata(dev);
@@ -1001,7 +1002,6 @@ MODULE_DEVICE_TABLE(of, tsens_table);
10011002

10021003
static const struct thermal_zone_of_device_ops tsens_of_ops = {
10031004
.get_temp = tsens_get_temp,
1004-
.get_trend = tsens_get_trend,
10051005
.set_trips = tsens_set_trips,
10061006
};
10071007

@@ -1061,6 +1061,10 @@ static int tsens_register(struct tsens_priv *priv)
10611061
priv->sensor[i].tzd = tzd;
10621062
if (priv->ops->enable)
10631063
priv->ops->enable(priv, i);
1064+
1065+
if (devm_thermal_add_hwmon_sysfs(tzd))
1066+
dev_warn(priv->dev,
1067+
"Failed to add hwmon sysfs attributes\n");
10641068
}
10651069

10661070
/* VER_0 require to set MIN and MAX THRESH
@@ -1076,13 +1080,18 @@ static int tsens_register(struct tsens_priv *priv)
10761080
tsens_mC_to_hw(priv->sensor, 0));
10771081
}
10781082

1079-
ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
1080-
if (ret < 0)
1081-
return ret;
1083+
if (priv->feat->combo_int) {
1084+
ret = tsens_register_irq(priv, "combined",
1085+
tsens_combined_irq_thread);
1086+
} else {
1087+
ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
1088+
if (ret < 0)
1089+
return ret;
10821090

1083-
if (priv->feat->crit_int)
1084-
ret = tsens_register_irq(priv, "critical",
1085-
tsens_critical_irq_thread);
1091+
if (priv->feat->crit_int)
1092+
ret = tsens_register_irq(priv, "critical",
1093+
tsens_critical_irq_thread);
1094+
}
10861095

10871096
return ret;
10881097
}
@@ -1158,7 +1167,11 @@ static int tsens_probe(struct platform_device *pdev)
11581167
}
11591168
}
11601169

1161-
return tsens_register(priv);
1170+
ret = tsens_register(priv);
1171+
if (!ret)
1172+
tsens_debug_init(pdev);
1173+
1174+
return ret;
11621175
}
11631176

11641177
static int tsens_remove(struct platform_device *pdev)

drivers/thermal/qcom/tsens.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ struct tsens_sensor {
6565
* @disable: Function to disable the tsens device
6666
* @suspend: Function to suspend the tsens device
6767
* @resume: Function to resume the tsens device
68-
* @get_trend: Function to get the thermal/temp trend
6968
*/
7069
struct tsens_ops {
7170
/* mandatory callbacks */
@@ -77,7 +76,6 @@ struct tsens_ops {
7776
void (*disable)(struct tsens_priv *priv);
7877
int (*suspend)(struct tsens_priv *priv);
7978
int (*resume)(struct tsens_priv *priv);
80-
int (*get_trend)(struct tsens_sensor *s, enum thermal_trend *trend);
8179
};
8280

8381
#define REG_FIELD_FOR_EACH_SENSOR11(_name, _offset, _startbit, _stopbit) \
@@ -495,19 +493,25 @@ enum regfield_ids {
495493
* struct tsens_features - Features supported by the IP
496494
* @ver_major: Major number of IP version
497495
* @crit_int: does the IP support critical interrupts?
496+
* @combo_int: does the IP use one IRQ for up, low and critical thresholds?
498497
* @adc: do the sensors only output adc code (instead of temperature)?
499498
* @srot_split: does the IP neatly splits the register space into SROT and TM,
500499
* with SROT only being available to secure boot firmware?
501500
* @has_watchdog: does this IP support watchdog functionality?
502501
* @max_sensors: maximum sensors supported by this version of the IP
502+
* @trip_min_temp: minimum trip temperature supported by this version of the IP
503+
* @trip_max_temp: maximum trip temperature supported by this version of the IP
503504
*/
504505
struct tsens_features {
505506
unsigned int ver_major;
506507
unsigned int crit_int:1;
508+
unsigned int combo_int:1;
507509
unsigned int adc:1;
508510
unsigned int srot_split:1;
509511
unsigned int has_watchdog:1;
510512
unsigned int max_sensors;
513+
int trip_min_temp;
514+
int trip_max_temp;
511515
};
512516

513517
/**

include/linux/iio/adc/qcom-vadc-common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
152152
u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio,
153153
u32 full_scale_code_volt, int temp);
154154

155+
u16 qcom_adc_tm5_gen2_temp_res_scale(int temp);
156+
155157
int qcom_adc5_prescaling_from_dt(u32 num, u32 den);
156158

157159
int qcom_adc5_hw_settle_time_from_dt(u32 value, const unsigned int *hw_settle);

0 commit comments

Comments
 (0)