diff options
Diffstat (limited to 'drivers/thermal/qcom')
-rw-r--r-- | drivers/thermal/qcom/lmh.c | 10 | ||||
-rw-r--r-- | drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 18 | ||||
-rw-r--r-- | drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 33 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-v1.c | 21 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens-v2.c | 1 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens.c | 46 | ||||
-rw-r--r-- | drivers/thermal/qcom/tsens.h | 7 |
7 files changed, 82 insertions, 54 deletions
diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c index f6edb12ec004..d2d49264cf83 100644 --- a/drivers/thermal/qcom/lmh.c +++ b/drivers/thermal/qcom/lmh.c @@ -73,7 +73,14 @@ static struct irq_chip lmh_irq_chip = { static int lmh_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { struct lmh_hw_data *lmh_data = d->host_data; + static struct lock_class_key lmh_lock_key; + static struct lock_class_key lmh_request_key; + /* + * This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ + irq_set_lockdep_class(irq, &lmh_lock_key, &lmh_request_key); irq_set_chip_and_handler(irq, &lmh_irq_chip, handle_simple_irq); irq_set_chip_data(irq, lmh_data); @@ -95,6 +102,9 @@ static int lmh_probe(struct platform_device *pdev) unsigned int enable_alg; u32 node_id; + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + lmh_data = devm_kzalloc(dev, sizeof(*lmh_data), GFP_KERNEL); if (!lmh_data) return -ENOMEM; diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c index 756ac6842ff9..d7f2e6ca92c2 100644 --- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c +++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c @@ -18,7 +18,7 @@ #include <linux/regmap.h> #include <linux/thermal.h> -#include <asm/unaligned.h> +#include <linux/unaligned.h> #include "../thermal_hwmon.h" @@ -829,12 +829,9 @@ static int adc_tm5_get_dt_channel_data(struct adc_tm5_chip *adc_tm, channel->iio = devm_fwnode_iio_channel_get_by_name(adc_tm->dev, of_fwnode_handle(node), NULL); - if (IS_ERR(channel->iio)) { - ret = PTR_ERR(channel->iio); - if (ret != -EPROBE_DEFER) - dev_err(dev, "%s: error getting channel: %d\n", name, ret); - return ret; - } + if (IS_ERR(channel->iio)) + return dev_err_probe(dev, PTR_ERR(channel->iio), "%s: error getting channel\n", + name); ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2); if (!ret) { @@ -941,7 +938,6 @@ static const struct adc_tm5_data adc_tm5_gen2_data_pmic = { static int adc_tm5_get_dt_data(struct adc_tm5_chip *adc_tm, struct device_node *node) { struct adc_tm5_channel *channels; - struct device_node *child; u32 value; int ret; struct device *dev = adc_tm->dev; @@ -985,12 +981,10 @@ static int adc_tm5_get_dt_data(struct adc_tm5_chip *adc_tm, struct device_node * adc_tm->avg_samples = VADC_DEF_AVG_SAMPLES; } - for_each_available_child_of_node(node, child) { + for_each_available_child_of_node_scoped(node, child) { ret = adc_tm5_get_dt_channel_data(adc_tm, channels, child); - if (ret) { - of_node_put(child); + if (ret) return ret; - } channels++; } diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c index 78c5cfe6a0c0..c2d59cbfaea9 100644 --- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c +++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c @@ -74,7 +74,6 @@ struct qpnp_tm_chip { long temp; unsigned int thresh; unsigned int stage; - unsigned int prev_stage; unsigned int base; /* protects .thresh, .stage and chip registers */ struct mutex lock; @@ -262,17 +261,13 @@ skip: return qpnp_tm_write(chip, QPNP_TM_REG_SHUTDOWN_CTRL1, reg); } -static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, int trip_id, int temp) +static int qpnp_tm_set_trip_temp(struct thermal_zone_device *tz, + const struct thermal_trip *trip, int temp) { struct qpnp_tm_chip *chip = thermal_zone_device_priv(tz); - struct thermal_trip trip; int ret; - ret = __thermal_zone_get_trip(chip->tz_dev, trip_id, &trip); - if (ret) - return ret; - - if (trip.type != THERMAL_TRIP_CRITICAL) + if (trip->type != THERMAL_TRIP_CRITICAL) return 0; mutex_lock(&chip->lock); @@ -296,24 +291,6 @@ static irqreturn_t qpnp_tm_isr(int irq, void *data) return IRQ_HANDLED; } -static int qpnp_tm_get_critical_trip_temp(struct qpnp_tm_chip *chip) -{ - struct thermal_trip trip; - int i, ret; - - for (i = 0; i < thermal_zone_get_num_trips(chip->tz_dev); i++) { - - ret = thermal_zone_get_trip(chip->tz_dev, i, &trip); - if (ret) - continue; - - if (trip.type == THERMAL_TRIP_CRITICAL) - return trip.temperature; - } - - return THERMAL_TEMP_INVALID; -} - /* * This function initializes the internal temp value based on only the * current thermal stage and threshold. Setup threshold control and @@ -348,7 +325,9 @@ static int qpnp_tm_init(struct qpnp_tm_chip *chip) mutex_unlock(&chip->lock); - crit_temp = qpnp_tm_get_critical_trip_temp(chip); + ret = thermal_zone_get_crit_temp(chip->tz_dev, &crit_temp); + if (ret) + crit_temp = THERMAL_TEMP_INVALID; mutex_lock(&chip->lock); diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c index dc1c4ae2d8b0..1a7874676f68 100644 --- a/drivers/thermal/qcom/tsens-v1.c +++ b/drivers/thermal/qcom/tsens-v1.c @@ -162,28 +162,35 @@ struct tsens_plat_data data_tsens_v1 = { .fields = tsens_v1_regfields, }; -static const struct tsens_ops ops_8956 = { - .init = init_8956, +static const struct tsens_ops ops_common = { + .init = init_common, .calibrate = tsens_calibrate_common, .get_temp = get_temp_tsens_valid, }; -struct tsens_plat_data data_8956 = { +struct tsens_plat_data data_8937 = { .num_sensors = 11, - .ops = &ops_8956, + .ops = &ops_common, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, }; -static const struct tsens_ops ops_8976 = { - .init = init_common, +static const struct tsens_ops ops_8956 = { + .init = init_8956, .calibrate = tsens_calibrate_common, .get_temp = get_temp_tsens_valid, }; +struct tsens_plat_data data_8956 = { + .num_sensors = 11, + .ops = &ops_8956, + .feat = &tsens_v1_feat, + .fields = tsens_v1_regfields, +}; + struct tsens_plat_data data_8976 = { .num_sensors = 11, - .ops = &ops_8976, + .ops = &ops_common, .feat = &tsens_v1_feat, .fields = tsens_v1_regfields, }; diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c index 29a61d2d6ca3..0cb7301eca6e 100644 --- a/drivers/thermal/qcom/tsens-v2.c +++ b/drivers/thermal/qcom/tsens-v2.c @@ -107,6 +107,7 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = { static const struct tsens_ops ops_generic_v2 = { .init = init_common, .get_temp = get_temp_tsens_valid, + .resume = tsens_resume_common, }; struct tsens_plat_data data_tsens_v2 = { diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 6d7c16ccb44d..3aa3736181aa 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -17,6 +17,7 @@ #include <linux/pm.h> #include <linux/regmap.h> #include <linux/slab.h> +#include <linux/suspend.h> #include <linux/thermal.h> #include "../thermal_hwmon.h" #include "tsens.h" @@ -264,7 +265,7 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *p1, for (i = 0; i < priv->num_sensors; i++) { dev_dbg(priv->dev, "%s: sensor%d - data_point1:%#x data_point2:%#x\n", - __func__, i, p1[i], p2[i]); + __func__, i, p1[i], p2 ? p2[i] : 0); if (!priv->sensor[i].slope) priv->sensor[i].slope = SLOPE_DEFAULT; @@ -1119,6 +1120,9 @@ static const struct of_device_id tsens_table[] = { .compatible = "qcom,msm8916-tsens", .data = &data_8916, }, { + .compatible = "qcom,msm8937-tsens", + .data = &data_8937, + }, { .compatible = "qcom,msm8939-tsens", .data = &data_8939, }, { @@ -1193,6 +1197,36 @@ static int tsens_register_irq(struct tsens_priv *priv, char *irqname, return ret; } +#ifdef CONFIG_SUSPEND +static int tsens_reinit(struct tsens_priv *priv) +{ + if (tsens_version(priv) >= VER_2_X) { + /* + * Re-enable the watchdog, unmask the bark. + * Disable cycle completion monitoring + */ + if (priv->feat->has_watchdog) { + regmap_field_write(priv->rf[WDOG_BARK_MASK], 0); + regmap_field_write(priv->rf[CC_MON_MASK], 1); + } + + /* Re-enable interrupts */ + tsens_enable_irq(priv); + } + + return 0; +} + +int tsens_resume_common(struct tsens_priv *priv) +{ + if (pm_suspend_target_state == PM_SUSPEND_MEM) + tsens_reinit(priv); + + return 0; +} + +#endif /* !CONFIG_SUSPEND */ + static int tsens_register(struct tsens_priv *priv) { int i, ret; @@ -1305,11 +1339,9 @@ static int tsens_probe(struct platform_device *pdev) if (priv->ops->calibrate) { ret = priv->ops->calibrate(priv); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "%s: calibration failed\n", __func__); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "%s: calibration failed\n", + __func__); } ret = tsens_register(priv); @@ -1331,7 +1363,7 @@ static void tsens_remove(struct platform_device *pdev) static struct platform_driver tsens_driver = { .probe = tsens_probe, - .remove_new = tsens_remove, + .remove = tsens_remove, .driver = { .name = "qcom-tsens", .pm = &tsens_pm_ops, diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index cb637fa289ca..7b36a0318fa6 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -634,6 +634,11 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo int init_common(struct tsens_priv *priv); int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp); int get_temp_common(const struct tsens_sensor *s, int *temp); +#ifdef CONFIG_SUSPEND +int tsens_resume_common(struct tsens_priv *priv); +#else +#define tsens_resume_common NULL +#endif /* TSENS target */ extern struct tsens_plat_data data_8960; @@ -642,7 +647,7 @@ extern struct tsens_plat_data data_8960; extern struct tsens_plat_data data_8226, data_8909, data_8916, data_8939, data_8974, data_9607; /* TSENS v1 targets */ -extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956; +extern struct tsens_plat_data data_tsens_v1, data_8937, data_8976, data_8956; /* TSENS v2 targets */ extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2; |