Loading Documentation/devicetree/bindings/thermal/rockchip-thermal.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2,8 +2,10 @@ Required properties: - compatible : should be "rockchip,<name>-tsadc" "rockchip,rk3228-tsadc": found on RK3228 SoCs "rockchip,rk3288-tsadc": found on RK3288 SoCs "rockchip,rk3368-tsadc": found on RK3368 SoCs "rockchip,rk3399-tsadc": found on RK3399 SoCs - reg : physical base address of the controller and length of memory mapped region. - interrupts : The interrupt number to the cpu. The interrupt specifier format Loading drivers/thermal/rcar_thermal.c +33 −20 Original line number Diff line number Diff line Loading @@ -75,11 +75,11 @@ struct rcar_thermal_priv { #define rcar_has_irq_support(priv) ((priv)->common->base) #define rcar_id_to_shift(priv) ((priv)->id * 8) #ifdef DEBUG # define rcar_force_update_temp(priv) 1 #else # define rcar_force_update_temp(priv) 0 #endif static const struct of_device_id rcar_thermal_dt_ids[] = { { .compatible = "renesas,rcar-thermal", }, {}, }; MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); /* * basic functions Loading Loading @@ -203,14 +203,26 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) { struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); int tmp; int ret; if (!rcar_has_irq_support(priv) || rcar_force_update_temp(priv)) rcar_thermal_update_temp(priv); ret = rcar_thermal_update_temp(priv); if (ret < 0) return ret; mutex_lock(&priv->lock); *temp = MCELSIUS((priv->ctemp * 5) - 65); tmp = MCELSIUS((priv->ctemp * 5) - 65); mutex_unlock(&priv->lock); if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) { struct device *dev = rcar_priv_to_dev(priv); dev_err(dev, "it couldn't measure temperature correctly\n"); return -EIO; } *temp = tmp; return 0; } Loading Loading @@ -288,6 +300,9 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable) unsigned long flags; u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */ if (!rcar_has_irq_support(priv)) return; spin_lock_irqsave(&common->lock, flags); rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask); Loading @@ -299,11 +314,15 @@ static void rcar_thermal_work(struct work_struct *work) { struct rcar_thermal_priv *priv; int cctemp, nctemp; int ret; priv = container_of(work, struct rcar_thermal_priv, work.work); rcar_thermal_get_temp(priv->zone, &cctemp); rcar_thermal_update_temp(priv); ret = rcar_thermal_update_temp(priv); if (ret < 0) return; rcar_thermal_irq_enable(priv); rcar_thermal_get_temp(priv->zone, &nctemp); Loading Loading @@ -368,7 +387,6 @@ static int rcar_thermal_remove(struct platform_device *pdev) struct rcar_thermal_priv *priv; rcar_thermal_for_each_priv(priv, common) { if (rcar_has_irq_support(priv)) rcar_thermal_irq_disable(priv); thermal_zone_device_unregister(priv->zone); } Loading Loading @@ -441,7 +459,9 @@ static int rcar_thermal_probe(struct platform_device *pdev) mutex_init(&priv->lock); INIT_LIST_HEAD(&priv->list); INIT_DELAYED_WORK(&priv->work, rcar_thermal_work); rcar_thermal_update_temp(priv); ret = rcar_thermal_update_temp(priv); if (ret < 0) goto error_unregister; priv->zone = thermal_zone_device_register("rcar_thermal", 1, 0, priv, Loading @@ -453,7 +473,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_unregister; } if (rcar_has_irq_support(priv)) rcar_thermal_irq_enable(priv); list_move_tail(&priv->list, &common->head); Loading Loading @@ -484,12 +503,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) return ret; } static const struct of_device_id rcar_thermal_dt_ids[] = { { .compatible = "renesas,rcar-thermal", }, {}, }; MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); static struct platform_driver rcar_thermal_driver = { .driver = { .name = "rcar_thermal", Loading drivers/thermal/rockchip_thermal.c +160 −12 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ enum tshut_mode { }; /** * the system Temperature Sensors tshut(tshut) polarity * The system Temperature Sensors tshut(tshut) polarity * the bit 8 is tshut polarity. * 0: low active, 1: high active */ Loading @@ -58,8 +58,8 @@ enum sensor_id { /** * The conversion table has the adc value and temperature. * ADC_DECREMENT is the adc value decremnet.(e.g. v2_code_table) * ADC_INCREMNET is the adc value incremnet.(e.g. v3_code_table) * ADC_DECREMENT: the adc value is of diminishing.(e.g. v2_code_table) * ADC_INCREMENT: the adc value is incremental.(e.g. v3_code_table) */ enum adc_sort_mode { ADC_DECREMENT = 0, Loading @@ -72,16 +72,17 @@ enum adc_sort_mode { */ #define SOC_MAX_SENSORS 2 /** * struct chip_tsadc_table: hold information about chip-specific differences * @id: conversion table * @length: size of conversion table * @data_mask: mask to apply on data inputs * @mode: sort mode of this adc variant (incrementing or decrementing) */ struct chip_tsadc_table { const struct tsadc_table *id; /* the array table size*/ unsigned int length; /* that analogic mask data */ u32 data_mask; /* the sort mode is adc value that increment or decrement in table */ enum adc_sort_mode mode; }; Loading Loading @@ -153,6 +154,7 @@ struct rockchip_thermal_data { #define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) #define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) #define TSADCV1_INT_PD_CLEAR_MASK ~BIT(16) #define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8) #define TSADCV2_DATA_MASK 0xfff Loading @@ -168,6 +170,51 @@ struct tsadc_table { int temp; }; /** * Note: * Code to Temperature mapping of the Temperature sensor is a piece wise linear * curve.Any temperature, code faling between to 2 give temperatures can be * linearly interpolated. * Code to Temperature mapping should be updated based on sillcon results. */ static const struct tsadc_table v1_code_table[] = { {TSADCV3_DATA_MASK, -40000}, {436, -40000}, {431, -35000}, {426, -30000}, {421, -25000}, {416, -20000}, {411, -15000}, {406, -10000}, {401, -5000}, {395, 0}, {390, 5000}, {385, 10000}, {380, 15000}, {375, 20000}, {370, 25000}, {364, 30000}, {359, 35000}, {354, 40000}, {349, 45000}, {343, 50000}, {338, 55000}, {333, 60000}, {328, 65000}, {322, 70000}, {317, 75000}, {312, 80000}, {307, 85000}, {301, 90000}, {296, 95000}, {291, 100000}, {286, 105000}, {280, 110000}, {275, 115000}, {270, 120000}, {264, 125000}, }; static const struct tsadc_table v2_code_table[] = { {TSADCV2_DATA_MASK, -40000}, {3800, -40000}, Loading Loading @@ -245,6 +292,44 @@ static const struct tsadc_table v3_code_table[] = { {TSADCV3_DATA_MASK, 125000}, }; static const struct tsadc_table v4_code_table[] = { {TSADCV3_DATA_MASK, -40000}, {431, -40000}, {426, -35000}, {421, -30000}, {415, -25000}, {410, -20000}, {405, -15000}, {399, -10000}, {394, -5000}, {389, 0}, {383, 5000}, {378, 10000}, {373, 15000}, {367, 20000}, {362, 25000}, {357, 30000}, {351, 35000}, {346, 40000}, {340, 45000}, {335, 50000}, {330, 55000}, {324, 60000}, {319, 65000}, {313, 70000}, {308, 75000}, {302, 80000}, {297, 85000}, {291, 90000}, {286, 95000}, {281, 100000}, {275, 105000}, {270, 110000}, {264, 115000}, {259, 120000}, {253, 125000}, }; static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, int temp) { Loading Loading @@ -368,6 +453,14 @@ static void rk_tsadcv2_initialize(void __iomem *regs, regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); } static void rk_tsadcv1_irq_ack(void __iomem *regs) { u32 val; val = readl_relaxed(regs + TSADCV2_INT_PD); writel_relaxed(val & TSADCV1_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); } static void rk_tsadcv2_irq_ack(void __iomem *regs) { u32 val; Loading Loading @@ -429,6 +522,29 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, writel_relaxed(val, regs + TSADCV2_INT_EN); } static const struct rockchip_tsadc_chip rk3228_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_num = 1, /* one channel for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ .tshut_temp = 95000, .initialize = rk_tsadcv2_initialize, .irq_ack = rk_tsadcv1_irq_ack, .control = rk_tsadcv2_control, .get_temp = rk_tsadcv2_get_temp, .set_tshut_temp = rk_tsadcv2_tshut_temp, .set_tshut_mode = rk_tsadcv2_tshut_mode, .table = { .id = v1_code_table, .length = ARRAY_SIZE(v1_code_table), .data_mask = TSADCV3_DATA_MASK, .mode = ADC_DECREMENT, }, }; static const struct rockchip_tsadc_chip rk3288_tsadc_data = { .chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */ .chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */ Loading Loading @@ -477,7 +593,35 @@ static const struct rockchip_tsadc_chip rk3368_tsadc_data = { }, }; static const struct rockchip_tsadc_chip rk3399_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ .tshut_temp = 95000, .initialize = rk_tsadcv2_initialize, .irq_ack = rk_tsadcv1_irq_ack, .control = rk_tsadcv2_control, .get_temp = rk_tsadcv2_get_temp, .set_tshut_temp = rk_tsadcv2_tshut_temp, .set_tshut_mode = rk_tsadcv2_tshut_mode, .table = { .id = v4_code_table, .length = ARRAY_SIZE(v4_code_table), .data_mask = TSADCV3_DATA_MASK, .mode = ADC_DECREMENT, }, }; static const struct of_device_id of_rockchip_thermal_match[] = { { .compatible = "rockchip,rk3228-tsadc", .data = (void *)&rk3228_tsadc_data, }, { .compatible = "rockchip,rk3288-tsadc", .data = (void *)&rk3288_tsadc_data, Loading @@ -486,6 +630,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .compatible = "rockchip,rk3368-tsadc", .data = (void *)&rk3368_tsadc_data, }, { .compatible = "rockchip,rk3399-tsadc", .data = (void *)&rk3399_tsadc_data, }, { /* end */ }, }; MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match); Loading Loading @@ -617,7 +765,7 @@ rockchip_thermal_register_sensor(struct platform_device *pdev, return 0; } /* /** * Reset TSADC Controller, reset all tsadc registers. */ static void rockchip_thermal_reset_controller(struct reset_control *reset) Loading drivers/thermal/step_wise.c +15 −2 Original line number Diff line number Diff line Loading @@ -63,6 +63,19 @@ static unsigned long get_target_state(struct thermal_instance *instance, next_target = instance->target; dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state); if (!instance->initialized) { if (throttle) { next_target = (cur_state + 1) >= instance->upper ? instance->upper : ((cur_state + 1) < instance->lower ? instance->lower : (cur_state + 1)); } else { next_target = THERMAL_NO_TARGET; } return next_target; } switch (trend) { case THERMAL_TREND_RAISING: if (throttle) { Loading Loading @@ -149,7 +162,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n", old_target, (int)instance->target); if (old_target == instance->target) if (instance->initialized && old_target == instance->target) continue; /* Activate a passive thermal instance */ Loading @@ -161,7 +174,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) instance->target == THERMAL_NO_TARGET) update_passive_instance(tz, trip_type, -1); instance->initialized = true; instance->cdev->updated = false; /* cdev needs update */ } Loading drivers/thermal/thermal_core.c +77 −4 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #include <linux/of.h> #include <net/netlink.h> #include <net/genetlink.h> #include <linux/suspend.h> #define CREATE_TRACE_POINTS #include <trace/events/thermal.h> Loading @@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list); static DEFINE_MUTEX(thermal_list_lock); static DEFINE_MUTEX(thermal_governor_lock); static atomic_t in_suspend; static struct thermal_governor *def_governor; static struct thermal_governor *__find_governor(const char *name) Loading Loading @@ -532,14 +535,31 @@ static void update_temperature(struct thermal_zone_device *tz) mutex_unlock(&tz->lock); trace_thermal_temperature(tz); if (tz->last_temperature == THERMAL_TEMP_INVALID) dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n", tz->temperature); else dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", tz->last_temperature, tz->temperature); } static void thermal_zone_device_reset(struct thermal_zone_device *tz) { struct thermal_instance *pos; tz->temperature = THERMAL_TEMP_INVALID; tz->passive = 0; list_for_each_entry(pos, &tz->thermal_instances, tz_node) pos->initialized = false; } void thermal_zone_device_update(struct thermal_zone_device *tz) { int count; if (atomic_read(&in_suspend)) return; if (!tz->ops->get_temp) return; Loading Loading @@ -676,8 +696,12 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, return -EINVAL; ret = tz->ops->set_trip_temp(tz, trip, temperature); if (ret) return ret; return ret ? ret : count; thermal_zone_device_update(tz); return count; } static ssize_t Loading Loading @@ -1321,6 +1345,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, if (!result) { list_add_tail(&dev->tz_node, &tz->thermal_instances); list_add_tail(&dev->cdev_node, &cdev->thermal_instances); atomic_set(&tz->need_update, 1); } mutex_unlock(&cdev->lock); mutex_unlock(&tz->lock); Loading Loading @@ -1430,6 +1455,7 @@ __thermal_cooling_device_register(struct device_node *np, const struct thermal_cooling_device_ops *ops) { struct thermal_cooling_device *cdev; struct thermal_zone_device *pos = NULL; int result; if (type && strlen(type) >= THERMAL_NAME_LENGTH) Loading Loading @@ -1474,6 +1500,12 @@ __thermal_cooling_device_register(struct device_node *np, /* Update binding information for 'this' new cdev */ bind_cdev(cdev); mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) if (atomic_cmpxchg(&pos->need_update, 1, 0)) thermal_zone_device_update(pos); mutex_unlock(&thermal_list_lock); return cdev; } Loading Loading @@ -1806,6 +1838,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, tz->trips = trips; tz->passive_delay = passive_delay; tz->polling_delay = polling_delay; /* A new thermal zone needs to be updated anyway. */ atomic_set(&tz->need_update, 1); dev_set_name(&tz->device, "thermal_zone%d", tz->id); result = device_register(&tz->device); Loading Loading @@ -1900,6 +1934,9 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); thermal_zone_device_reset(tz); /* Update the new thermal zone and mark it as already updated. */ if (atomic_cmpxchg(&tz->need_update, 1, 0)) thermal_zone_device_update(tz); return tz; Loading Loading @@ -2140,6 +2177,36 @@ static void thermal_unregister_governors(void) thermal_gov_power_allocator_unregister(); } static int thermal_pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) { struct thermal_zone_device *tz; switch (mode) { case PM_HIBERNATION_PREPARE: case PM_RESTORE_PREPARE: case PM_SUSPEND_PREPARE: atomic_set(&in_suspend, 1); break; case PM_POST_HIBERNATION: case PM_POST_RESTORE: case PM_POST_SUSPEND: atomic_set(&in_suspend, 0); list_for_each_entry(tz, &thermal_tz_list, node) { thermal_zone_device_reset(tz); thermal_zone_device_update(tz); } break; default: break; } return 0; } static struct notifier_block thermal_pm_nb = { .notifier_call = thermal_pm_notify, }; static int __init thermal_init(void) { int result; Loading @@ -2160,6 +2227,11 @@ static int __init thermal_init(void) if (result) goto exit_netlink; result = register_pm_notifier(&thermal_pm_nb); if (result) pr_warn("Thermal: Can not register suspend notifier, return %d\n", result); return 0; exit_netlink: Loading @@ -2179,6 +2251,7 @@ static int __init thermal_init(void) static void __exit thermal_exit(void) { unregister_pm_notifier(&thermal_pm_nb); of_thermal_destroy_zones(); genetlink_exit(); class_unregister(&thermal_class); Loading Loading
Documentation/devicetree/bindings/thermal/rockchip-thermal.txt +2 −0 Original line number Diff line number Diff line Loading @@ -2,8 +2,10 @@ Required properties: - compatible : should be "rockchip,<name>-tsadc" "rockchip,rk3228-tsadc": found on RK3228 SoCs "rockchip,rk3288-tsadc": found on RK3288 SoCs "rockchip,rk3368-tsadc": found on RK3368 SoCs "rockchip,rk3399-tsadc": found on RK3399 SoCs - reg : physical base address of the controller and length of memory mapped region. - interrupts : The interrupt number to the cpu. The interrupt specifier format Loading
drivers/thermal/rcar_thermal.c +33 −20 Original line number Diff line number Diff line Loading @@ -75,11 +75,11 @@ struct rcar_thermal_priv { #define rcar_has_irq_support(priv) ((priv)->common->base) #define rcar_id_to_shift(priv) ((priv)->id * 8) #ifdef DEBUG # define rcar_force_update_temp(priv) 1 #else # define rcar_force_update_temp(priv) 0 #endif static const struct of_device_id rcar_thermal_dt_ids[] = { { .compatible = "renesas,rcar-thermal", }, {}, }; MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); /* * basic functions Loading Loading @@ -203,14 +203,26 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) { struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); int tmp; int ret; if (!rcar_has_irq_support(priv) || rcar_force_update_temp(priv)) rcar_thermal_update_temp(priv); ret = rcar_thermal_update_temp(priv); if (ret < 0) return ret; mutex_lock(&priv->lock); *temp = MCELSIUS((priv->ctemp * 5) - 65); tmp = MCELSIUS((priv->ctemp * 5) - 65); mutex_unlock(&priv->lock); if ((tmp < MCELSIUS(-45)) || (tmp > MCELSIUS(125))) { struct device *dev = rcar_priv_to_dev(priv); dev_err(dev, "it couldn't measure temperature correctly\n"); return -EIO; } *temp = tmp; return 0; } Loading Loading @@ -288,6 +300,9 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable) unsigned long flags; u32 mask = 0x3 << rcar_id_to_shift(priv); /* enable Rising/Falling */ if (!rcar_has_irq_support(priv)) return; spin_lock_irqsave(&common->lock, flags); rcar_thermal_common_bset(common, INTMSK, mask, enable ? 0 : mask); Loading @@ -299,11 +314,15 @@ static void rcar_thermal_work(struct work_struct *work) { struct rcar_thermal_priv *priv; int cctemp, nctemp; int ret; priv = container_of(work, struct rcar_thermal_priv, work.work); rcar_thermal_get_temp(priv->zone, &cctemp); rcar_thermal_update_temp(priv); ret = rcar_thermal_update_temp(priv); if (ret < 0) return; rcar_thermal_irq_enable(priv); rcar_thermal_get_temp(priv->zone, &nctemp); Loading Loading @@ -368,7 +387,6 @@ static int rcar_thermal_remove(struct platform_device *pdev) struct rcar_thermal_priv *priv; rcar_thermal_for_each_priv(priv, common) { if (rcar_has_irq_support(priv)) rcar_thermal_irq_disable(priv); thermal_zone_device_unregister(priv->zone); } Loading Loading @@ -441,7 +459,9 @@ static int rcar_thermal_probe(struct platform_device *pdev) mutex_init(&priv->lock); INIT_LIST_HEAD(&priv->list); INIT_DELAYED_WORK(&priv->work, rcar_thermal_work); rcar_thermal_update_temp(priv); ret = rcar_thermal_update_temp(priv); if (ret < 0) goto error_unregister; priv->zone = thermal_zone_device_register("rcar_thermal", 1, 0, priv, Loading @@ -453,7 +473,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_unregister; } if (rcar_has_irq_support(priv)) rcar_thermal_irq_enable(priv); list_move_tail(&priv->list, &common->head); Loading Loading @@ -484,12 +503,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) return ret; } static const struct of_device_id rcar_thermal_dt_ids[] = { { .compatible = "renesas,rcar-thermal", }, {}, }; MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids); static struct platform_driver rcar_thermal_driver = { .driver = { .name = "rcar_thermal", Loading
drivers/thermal/rockchip_thermal.c +160 −12 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ enum tshut_mode { }; /** * the system Temperature Sensors tshut(tshut) polarity * The system Temperature Sensors tshut(tshut) polarity * the bit 8 is tshut polarity. * 0: low active, 1: high active */ Loading @@ -58,8 +58,8 @@ enum sensor_id { /** * The conversion table has the adc value and temperature. * ADC_DECREMENT is the adc value decremnet.(e.g. v2_code_table) * ADC_INCREMNET is the adc value incremnet.(e.g. v3_code_table) * ADC_DECREMENT: the adc value is of diminishing.(e.g. v2_code_table) * ADC_INCREMENT: the adc value is incremental.(e.g. v3_code_table) */ enum adc_sort_mode { ADC_DECREMENT = 0, Loading @@ -72,16 +72,17 @@ enum adc_sort_mode { */ #define SOC_MAX_SENSORS 2 /** * struct chip_tsadc_table: hold information about chip-specific differences * @id: conversion table * @length: size of conversion table * @data_mask: mask to apply on data inputs * @mode: sort mode of this adc variant (incrementing or decrementing) */ struct chip_tsadc_table { const struct tsadc_table *id; /* the array table size*/ unsigned int length; /* that analogic mask data */ u32 data_mask; /* the sort mode is adc value that increment or decrement in table */ enum adc_sort_mode mode; }; Loading Loading @@ -153,6 +154,7 @@ struct rockchip_thermal_data { #define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) #define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) #define TSADCV1_INT_PD_CLEAR_MASK ~BIT(16) #define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8) #define TSADCV2_DATA_MASK 0xfff Loading @@ -168,6 +170,51 @@ struct tsadc_table { int temp; }; /** * Note: * Code to Temperature mapping of the Temperature sensor is a piece wise linear * curve.Any temperature, code faling between to 2 give temperatures can be * linearly interpolated. * Code to Temperature mapping should be updated based on sillcon results. */ static const struct tsadc_table v1_code_table[] = { {TSADCV3_DATA_MASK, -40000}, {436, -40000}, {431, -35000}, {426, -30000}, {421, -25000}, {416, -20000}, {411, -15000}, {406, -10000}, {401, -5000}, {395, 0}, {390, 5000}, {385, 10000}, {380, 15000}, {375, 20000}, {370, 25000}, {364, 30000}, {359, 35000}, {354, 40000}, {349, 45000}, {343, 50000}, {338, 55000}, {333, 60000}, {328, 65000}, {322, 70000}, {317, 75000}, {312, 80000}, {307, 85000}, {301, 90000}, {296, 95000}, {291, 100000}, {286, 105000}, {280, 110000}, {275, 115000}, {270, 120000}, {264, 125000}, }; static const struct tsadc_table v2_code_table[] = { {TSADCV2_DATA_MASK, -40000}, {3800, -40000}, Loading Loading @@ -245,6 +292,44 @@ static const struct tsadc_table v3_code_table[] = { {TSADCV3_DATA_MASK, 125000}, }; static const struct tsadc_table v4_code_table[] = { {TSADCV3_DATA_MASK, -40000}, {431, -40000}, {426, -35000}, {421, -30000}, {415, -25000}, {410, -20000}, {405, -15000}, {399, -10000}, {394, -5000}, {389, 0}, {383, 5000}, {378, 10000}, {373, 15000}, {367, 20000}, {362, 25000}, {357, 30000}, {351, 35000}, {346, 40000}, {340, 45000}, {335, 50000}, {330, 55000}, {324, 60000}, {319, 65000}, {313, 70000}, {308, 75000}, {302, 80000}, {297, 85000}, {291, 90000}, {286, 95000}, {281, 100000}, {275, 105000}, {270, 110000}, {264, 115000}, {259, 120000}, {253, 125000}, }; static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, int temp) { Loading Loading @@ -368,6 +453,14 @@ static void rk_tsadcv2_initialize(void __iomem *regs, regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); } static void rk_tsadcv1_irq_ack(void __iomem *regs) { u32 val; val = readl_relaxed(regs + TSADCV2_INT_PD); writel_relaxed(val & TSADCV1_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); } static void rk_tsadcv2_irq_ack(void __iomem *regs) { u32 val; Loading Loading @@ -429,6 +522,29 @@ static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, writel_relaxed(val, regs + TSADCV2_INT_EN); } static const struct rockchip_tsadc_chip rk3228_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_num = 1, /* one channel for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ .tshut_temp = 95000, .initialize = rk_tsadcv2_initialize, .irq_ack = rk_tsadcv1_irq_ack, .control = rk_tsadcv2_control, .get_temp = rk_tsadcv2_get_temp, .set_tshut_temp = rk_tsadcv2_tshut_temp, .set_tshut_mode = rk_tsadcv2_tshut_mode, .table = { .id = v1_code_table, .length = ARRAY_SIZE(v1_code_table), .data_mask = TSADCV3_DATA_MASK, .mode = ADC_DECREMENT, }, }; static const struct rockchip_tsadc_chip rk3288_tsadc_data = { .chn_id[SENSOR_CPU] = 1, /* cpu sensor is channel 1 */ .chn_id[SENSOR_GPU] = 2, /* gpu sensor is channel 2 */ Loading Loading @@ -477,7 +593,35 @@ static const struct rockchip_tsadc_chip rk3368_tsadc_data = { }, }; static const struct rockchip_tsadc_chip rk3399_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ .chn_num = 2, /* two channels for tsadc */ .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ .tshut_temp = 95000, .initialize = rk_tsadcv2_initialize, .irq_ack = rk_tsadcv1_irq_ack, .control = rk_tsadcv2_control, .get_temp = rk_tsadcv2_get_temp, .set_tshut_temp = rk_tsadcv2_tshut_temp, .set_tshut_mode = rk_tsadcv2_tshut_mode, .table = { .id = v4_code_table, .length = ARRAY_SIZE(v4_code_table), .data_mask = TSADCV3_DATA_MASK, .mode = ADC_DECREMENT, }, }; static const struct of_device_id of_rockchip_thermal_match[] = { { .compatible = "rockchip,rk3228-tsadc", .data = (void *)&rk3228_tsadc_data, }, { .compatible = "rockchip,rk3288-tsadc", .data = (void *)&rk3288_tsadc_data, Loading @@ -486,6 +630,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .compatible = "rockchip,rk3368-tsadc", .data = (void *)&rk3368_tsadc_data, }, { .compatible = "rockchip,rk3399-tsadc", .data = (void *)&rk3399_tsadc_data, }, { /* end */ }, }; MODULE_DEVICE_TABLE(of, of_rockchip_thermal_match); Loading Loading @@ -617,7 +765,7 @@ rockchip_thermal_register_sensor(struct platform_device *pdev, return 0; } /* /** * Reset TSADC Controller, reset all tsadc registers. */ static void rockchip_thermal_reset_controller(struct reset_control *reset) Loading
drivers/thermal/step_wise.c +15 −2 Original line number Diff line number Diff line Loading @@ -63,6 +63,19 @@ static unsigned long get_target_state(struct thermal_instance *instance, next_target = instance->target; dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state); if (!instance->initialized) { if (throttle) { next_target = (cur_state + 1) >= instance->upper ? instance->upper : ((cur_state + 1) < instance->lower ? instance->lower : (cur_state + 1)); } else { next_target = THERMAL_NO_TARGET; } return next_target; } switch (trend) { case THERMAL_TREND_RAISING: if (throttle) { Loading Loading @@ -149,7 +162,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n", old_target, (int)instance->target); if (old_target == instance->target) if (instance->initialized && old_target == instance->target) continue; /* Activate a passive thermal instance */ Loading @@ -161,7 +174,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) instance->target == THERMAL_NO_TARGET) update_passive_instance(tz, trip_type, -1); instance->initialized = true; instance->cdev->updated = false; /* cdev needs update */ } Loading
drivers/thermal/thermal_core.c +77 −4 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #include <linux/of.h> #include <net/netlink.h> #include <net/genetlink.h> #include <linux/suspend.h> #define CREATE_TRACE_POINTS #include <trace/events/thermal.h> Loading @@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list); static DEFINE_MUTEX(thermal_list_lock); static DEFINE_MUTEX(thermal_governor_lock); static atomic_t in_suspend; static struct thermal_governor *def_governor; static struct thermal_governor *__find_governor(const char *name) Loading Loading @@ -532,14 +535,31 @@ static void update_temperature(struct thermal_zone_device *tz) mutex_unlock(&tz->lock); trace_thermal_temperature(tz); if (tz->last_temperature == THERMAL_TEMP_INVALID) dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n", tz->temperature); else dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", tz->last_temperature, tz->temperature); } static void thermal_zone_device_reset(struct thermal_zone_device *tz) { struct thermal_instance *pos; tz->temperature = THERMAL_TEMP_INVALID; tz->passive = 0; list_for_each_entry(pos, &tz->thermal_instances, tz_node) pos->initialized = false; } void thermal_zone_device_update(struct thermal_zone_device *tz) { int count; if (atomic_read(&in_suspend)) return; if (!tz->ops->get_temp) return; Loading Loading @@ -676,8 +696,12 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, return -EINVAL; ret = tz->ops->set_trip_temp(tz, trip, temperature); if (ret) return ret; return ret ? ret : count; thermal_zone_device_update(tz); return count; } static ssize_t Loading Loading @@ -1321,6 +1345,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, if (!result) { list_add_tail(&dev->tz_node, &tz->thermal_instances); list_add_tail(&dev->cdev_node, &cdev->thermal_instances); atomic_set(&tz->need_update, 1); } mutex_unlock(&cdev->lock); mutex_unlock(&tz->lock); Loading Loading @@ -1430,6 +1455,7 @@ __thermal_cooling_device_register(struct device_node *np, const struct thermal_cooling_device_ops *ops) { struct thermal_cooling_device *cdev; struct thermal_zone_device *pos = NULL; int result; if (type && strlen(type) >= THERMAL_NAME_LENGTH) Loading Loading @@ -1474,6 +1500,12 @@ __thermal_cooling_device_register(struct device_node *np, /* Update binding information for 'this' new cdev */ bind_cdev(cdev); mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) if (atomic_cmpxchg(&pos->need_update, 1, 0)) thermal_zone_device_update(pos); mutex_unlock(&thermal_list_lock); return cdev; } Loading Loading @@ -1806,6 +1838,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, tz->trips = trips; tz->passive_delay = passive_delay; tz->polling_delay = polling_delay; /* A new thermal zone needs to be updated anyway. */ atomic_set(&tz->need_update, 1); dev_set_name(&tz->device, "thermal_zone%d", tz->id); result = device_register(&tz->device); Loading Loading @@ -1900,6 +1934,9 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); thermal_zone_device_reset(tz); /* Update the new thermal zone and mark it as already updated. */ if (atomic_cmpxchg(&tz->need_update, 1, 0)) thermal_zone_device_update(tz); return tz; Loading Loading @@ -2140,6 +2177,36 @@ static void thermal_unregister_governors(void) thermal_gov_power_allocator_unregister(); } static int thermal_pm_notify(struct notifier_block *nb, unsigned long mode, void *_unused) { struct thermal_zone_device *tz; switch (mode) { case PM_HIBERNATION_PREPARE: case PM_RESTORE_PREPARE: case PM_SUSPEND_PREPARE: atomic_set(&in_suspend, 1); break; case PM_POST_HIBERNATION: case PM_POST_RESTORE: case PM_POST_SUSPEND: atomic_set(&in_suspend, 0); list_for_each_entry(tz, &thermal_tz_list, node) { thermal_zone_device_reset(tz); thermal_zone_device_update(tz); } break; default: break; } return 0; } static struct notifier_block thermal_pm_nb = { .notifier_call = thermal_pm_notify, }; static int __init thermal_init(void) { int result; Loading @@ -2160,6 +2227,11 @@ static int __init thermal_init(void) if (result) goto exit_netlink; result = register_pm_notifier(&thermal_pm_nb); if (result) pr_warn("Thermal: Can not register suspend notifier, return %d\n", result); return 0; exit_netlink: Loading @@ -2179,6 +2251,7 @@ static int __init thermal_init(void) static void __exit thermal_exit(void) { unregister_pm_notifier(&thermal_pm_nb); of_thermal_destroy_zones(); genetlink_exit(); class_unregister(&thermal_class); Loading