@@ -564,8 +564,12 @@ static int tsens_set_trips(void *_sensor, int low, int high)
/* Write the new thresholds and clear the status */
regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val);
regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val);
- tsens_set_interrupt(priv, hw_id, LOWER, true);
- tsens_set_interrupt(priv, hw_id, UPPER, true);
+ s->trips_configured = true;
+
+ if (s->enable_irqs) {
+ tsens_set_interrupt(priv, hw_id, LOWER, true);
+ tsens_set_interrupt(priv, hw_id, UPPER, true);
+ }
spin_unlock_irqrestore(&priv->ul_lock, flags);
@@ -575,6 +579,40 @@ static int tsens_set_trips(void *_sensor, int low, int high)
return 0;
}
+static int tsens_change_mode(void *_sensor, enum thermal_device_mode mode)
+{
+ struct tsens_sensor *s = _sensor;
+ struct tsens_priv *priv = s->priv;
+ u32 hw_id = s->hw_id;
+ bool enable = (mode == THERMAL_DEVICE_ENABLED);
+ unsigned long flags;
+
+ if (tsens_version(priv) < VER_0_1) {
+ /* Pre v0.1 IP had a single register for each type of interrupt
+ * and threshold, so we can't support individual enable/disable.
+ */
+ hw_id = 0;
+ enable = true;
+ }
+
+ spin_lock_irqsave(&priv->ul_lock, flags);
+
+ /* During sensor registration, thermal core calls change_mode(ENABLED)
+ * before it calls set_trips(low, high). To avoid enabling threshold
+ * interrupts before thresholds are configured, let's let set_trips do
+ * the first enable.
+ */
+ if (s->trips_configured) {
+ tsens_set_interrupt(priv, hw_id, LOWER, enable);
+ tsens_set_interrupt(priv, hw_id, UPPER, enable);
+ }
+ s->enable_irqs = enable;
+
+ spin_unlock_irqrestore(&priv->ul_lock, flags);
+
+ return 0;
+}
+
static int tsens_enable_irq(struct tsens_priv *priv)
{
int ret;
@@ -1002,6 +1040,7 @@ static const struct thermal_zone_of_device_ops tsens_of_ops = {
.get_temp = tsens_get_temp,
.get_trend = tsens_get_trend,
.set_trips = tsens_set_trips,
+ .change_mode = tsens_change_mode,
};
static int tsens_register_irq(struct tsens_priv *priv, char *irqname,
@@ -45,6 +45,8 @@ enum tsens_irq_type {
* @offset: offset of temperature adjustment curve
* @hw_id: HW ID can be used in case of platform-specific IDs
* @slope: slope of temperature adjustment curve
+ * @trips_configured: whether this sensor's upper/lower thresholds are set
+ * @enable_irqs: whether this sensor's threshold IRQs should be enabled
* @status: 8960-specific variable to track 8960 and 8660 status register offset
*/
struct tsens_sensor {
@@ -53,6 +55,8 @@ struct tsens_sensor {
int offset;
unsigned int hw_id;
int slope;
+ bool trips_configured;
+ bool enable_irqs;
u32 status;
};