lvts_ctrl
static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl, bool enable)
if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE)
lvts_for_each_valid_sensor(i, lvts_ctrl)
writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, const u32 *cmds, int nr_cmds)
writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));
static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
writel(0, LVTS_MONINT(lvts_ctrl->base));
static int lvts_ctrl_set_enable(struct lvts_ctrl *lvts_ctrl, int enable)
writel(enable, LVTS_CLKEN(lvts_ctrl->base));
static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
lvts_write_config(lvts_ctrl, lvts_data->conn_cmd, lvts_data->num_conn_cmd);
id = readl(LVTS_ID(lvts_ctrl->base));
static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
lvts_write_config(lvts_ctrl, lvts_data->init_cmd, lvts_data->num_init_cmd);
static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
LVTS_EDATA00(lvts_ctrl->base),
LVTS_EDATA01(lvts_ctrl->base),
LVTS_EDATA02(lvts_ctrl->base),
LVTS_EDATA03(lvts_ctrl->base)
writel(lvts_ctrl->calibration[i], lvts_edata[i]);
if (lvts_ctrl->lvts_data->msr_offset)
writel(lvts_ctrl->lvts_data->msr_offset,
LVTS_MSROFT(lvts_ctrl->base));
static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
writel(value, LVTS_TSSEL(lvts_ctrl->base));
writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
writel(value, LVTS_MONCTL1(lvts_ctrl->base));
writel(value, LVTS_MONCTL2(lvts_ctrl->base));
return lvts_irq_init(lvts_ctrl);
static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?
lvts_for_each_valid_sensor(i, lvts_ctrl) {
if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base));
writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
struct lvts_ctrl *lvts_ctrl;
#define lvts_for_each_valid_sensor(i, lvts_ctrl) \
lvts_ctrl = &lvts_td->lvts_ctrl[i];
if (!((lvts_ctrl)->valid_sensor_mask & BIT(i))) \
ret = lvts_ctrl_set_enable(lvts_ctrl, true);
ret = lvts_ctrl_connect(dev, lvts_ctrl);
ret = lvts_ctrl_initialize(dev, lvts_ctrl);
ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
ret = lvts_ctrl_configure(dev, lvts_ctrl);
ret = lvts_ctrl_start(dev, lvts_ctrl);
const struct lvts_ctrl_data *lvts_ctrl;
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], false);
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], true);
struct lvts_ctrl *lvts_ctrl;
.lvts_ctrl = mt7987_lvts_ap_data_ctrl,
.lvts_ctrl = mt7988_lvts_ap_data_ctrl,
.lvts_ctrl = mt8186_lvts_data_ctrl,
.lvts_ctrl = mt8188_lvts_mcu_data_ctrl,
.lvts_ctrl = mt8188_lvts_ap_data_ctrl,
.lvts_ctrl = mt8192_lvts_mcu_data_ctrl,
.lvts_ctrl = mt8192_lvts_ap_data_ctrl,
.lvts_ctrl = mt8195_lvts_mcu_data_ctrl,
.lvts_ctrl = mt8195_lvts_ap_data_ctrl,
.lvts_ctrl = mt8196_lvts_mcu_data_ctrl,
.lvts_ctrl = mt8196_lvts_ap_data_ctrl,
struct lvts_ctrl *lvts_ctrl;
lvts_ctrl = &lvts_td->lvts_ctrl[i];
regset->base = lvts_ctrl->base;
struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
value = readl(LVTS_MONINT(lvts_ctrl->base));
lvts_for_each_valid_sensor(i, lvts_ctrl) {
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
&& lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh) {
if (lvts_ctrl->low_thresh == -INT_MAX) {
writel(value, LVTS_MONINT(lvts_ctrl->base));
static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)
if (high > lvts_ctrl->high_thresh)
lvts_for_each_valid_sensor(i, lvts_ctrl)
if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
&& lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high);
lvts_ctrl->high_thresh = high;
lvts_ctrl->low_thresh = low;
lvts_update_irq_mask(lvts_ctrl);
static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]);
static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
LVTS_MSR0(lvts_ctrl->base),
LVTS_MSR1(lvts_ctrl->base),
LVTS_MSR2(lvts_ctrl->base),
LVTS_MSR3(lvts_ctrl->base)
LVTS_IMMD0(lvts_ctrl->base),
LVTS_IMMD1(lvts_ctrl->base),
LVTS_IMMD2(lvts_ctrl->base),
LVTS_IMMD3(lvts_ctrl->base)
LVTS_ATP0(lvts_ctrl->base),
LVTS_ATP1(lvts_ctrl->base),
LVTS_ATP2(lvts_ctrl->base),
LVTS_ATP3(lvts_ctrl->base)
lvts_sensor[i].base = lvts_ctrl->base;
lvts_ctrl->valid_sensor_mask = lvts_ctrl_data->valid_sensor_mask;
static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
lvts_ctrl->calibration[i] = calib;
if (lvts_ctrl->lvts_data->msr_offset)
lvts_ctrl->calibration[i] += lvts_ctrl->lvts_data->msr_offset;
} else if (lvts_ctrl->lvts_data->def_calibration) {
lvts_ctrl->calibration[i] = lvts_ctrl->lvts_data->def_calibration;
size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
struct lvts_ctrl *lvts_ctrl;
lvts_ctrl = devm_kzalloc(dev, size, GFP_KERNEL);
if (!lvts_ctrl)
lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
lvts_ctrl[i].lvts_data = lvts_data;
ret = lvts_sensor_init(dev, &lvts_ctrl[i],
&lvts_data->lvts_ctrl[i]);
ret = lvts_calibration_init(dev, &lvts_ctrl[i],
&lvts_data->lvts_ctrl[i],
lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
lvts_ctrl[i].low_thresh = INT_MIN;
lvts_ctrl[i].high_thresh = INT_MIN;
lvts_td->lvts_ctrl = lvts_ctrl;