mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
The max77851 driver is failing to build for Linux kernels v5.16 to v6.0
and the following error is seen ...
drivers/thermal/max77851_thermal.c:173:30: error: implicit declaration
of function 'devm_thermal_of_zone_register'; did you mean
'devm_thermal_zone_of_sensor_register'?
[-Werror=implicit-function-declaration]
thermal->tz_device = devm_thermal_of_zone_register(&pdev->dev, 0,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The function devm_thermal_of_zone_register() was introduced in Linux
kernel v6.1 and not v5.16.
Instead of relying on kernel version to determine if this function is
present using the conftest.sh script which checks the kernel that is
being compiled to see if this function is present or not. This is also
beneficial for working with 3rd party Linux kernels that may have
back-ported upstream changes into their kernel and so the kernel version
checks do not work either.
Bug 200749982
Change-Id: I8d5e70d2d39497d7f513c82cd3a45312b2bc016a
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2980925
233 lines
6.6 KiB
C
233 lines
6.6 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
/*
|
|
* Junction temperature thermal driver for Maxim Max77851.
|
|
*/
|
|
|
|
#include <nvidia/conftest.h>
|
|
|
|
#include <linux/irq.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/mfd/max77851.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/thermal.h>
|
|
|
|
#include <linux/of_device.h>
|
|
|
|
#define MAX77851_TJALARM1_TH BIT(0) // 85 Degree
|
|
#define MAX77851_TJALARM2_TH BIT(0) // 115 Degree
|
|
#define MAX77851_TJSHUTDOWN_TH BIT(0) // 140 Degree
|
|
|
|
#define MAX77851_NORMAL_OPERATING_TEMP 100000
|
|
#define MAX77851_TJALARM1_TEMP 105000
|
|
#define MAX77851_TJALARM2_TEMP 135000
|
|
#define MAX77851_TJSHUTDOWN_TEMP 150000
|
|
|
|
struct max77851_therm_info {
|
|
struct device *dev;
|
|
struct regmap *rmap;
|
|
struct thermal_zone_device *tz_device;
|
|
|
|
bool tjalarm_en;
|
|
bool tjshutdown_en;
|
|
|
|
int tjshutdown_th;
|
|
int tjalarm1_th;
|
|
int tjalarm2_th;
|
|
|
|
int irq_tjshutdown;
|
|
int irq_tjalarm1;
|
|
int irq_tjalarm2;
|
|
};
|
|
|
|
#if defined(NV_DEVM_THERMAL_OF_ZONE_REGISTER_PRESENT)
|
|
static int max77851_thermal_read_temp(struct thermal_zone_device *data, int *temp)
|
|
#else
|
|
static int max77851_thermal_read_temp(void *data, int *temp)
|
|
#endif
|
|
{
|
|
#if defined(NV_DEVM_THERMAL_OF_ZONE_REGISTER_PRESENT)
|
|
struct max77851_therm_info *thermal = data->devdata;
|
|
#else
|
|
struct max77851_therm_info *thermal = data;
|
|
#endif
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
ret = regmap_read(thermal->rmap, TOP_STAT1_REG, &val);
|
|
if (ret < 0) {
|
|
dev_err(thermal->dev, "Failed to read STATLBT: %d\n", ret);
|
|
return ret;
|
|
}
|
|
if (val & TOP_STAT1_TJ_SHDN)
|
|
*temp = MAX77851_TJSHUTDOWN_TEMP;
|
|
else if (val & TOP_STAT1_TJ_ALM2)
|
|
*temp = MAX77851_TJALARM2_TEMP;
|
|
else if (val & TOP_STAT1_TJ_ALM1)
|
|
*temp = MAX77851_TJALARM1_TEMP;
|
|
else
|
|
*temp = MAX77851_NORMAL_OPERATING_TEMP;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(NV_DEVM_THERMAL_OF_ZONE_REGISTER_PRESENT)
|
|
static const struct thermal_zone_device_ops max77851_thermal_ops = {
|
|
#else
|
|
static const struct thermal_zone_of_device_ops max77851_thermal_ops = {
|
|
#endif
|
|
.get_temp = max77851_thermal_read_temp,
|
|
};
|
|
|
|
static irqreturn_t max77851_thermal_irq(int irq, void *data)
|
|
{
|
|
struct max77851_therm_info *thermal = data;
|
|
|
|
if (irq == thermal->irq_tjalarm1)
|
|
dev_warn(thermal->dev, "Junction Temp Alarm1(105C) occurred\n");
|
|
else if (irq == thermal->irq_tjalarm2)
|
|
dev_crit(thermal->dev, "Junction Temp Alarm2(135C) occurred\n");
|
|
else if (irq == thermal->irq_tjshutdown)
|
|
dev_crit(thermal->dev, "Junction Temp Shutdown(150C) occurred\n");
|
|
|
|
thermal_zone_device_update(thermal->tz_device,
|
|
THERMAL_EVENT_UNSPECIFIED);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
static int max77851_thermal_init(struct max77851_therm_info *thermal)
|
|
{
|
|
int ret;
|
|
|
|
u8 config;
|
|
|
|
thermal->tjalarm_en = true;
|
|
thermal->tjshutdown_en = false;
|
|
|
|
thermal->tjalarm1_th = MAX77851_TJALARM1_TEMP;
|
|
thermal->tjalarm2_th = MAX77851_TJALARM2_TEMP;
|
|
thermal->tjshutdown_th = MAX77851_TJSHUTDOWN_TEMP;
|
|
|
|
config = thermal->tjalarm_en ? TOP_CFG0_TJ_ALM_EN : 0;
|
|
config |= thermal->tjshutdown_en ? TOP_CFG0_TJ_EN : 0;
|
|
|
|
ret = regmap_update_bits(thermal->rmap, TOP_CFG0_REG,
|
|
TOP_CFG0_TJ_ALM_EN | TOP_CFG0_TJ_EN, config);
|
|
if (ret < 0)
|
|
dev_err(thermal->dev, "Failed to update TOP_CFG0_REG: %d\n", ret);
|
|
|
|
config = MAX77851_TJALARM1_TH | MAX77851_TJALARM2_TH | MAX77851_TJSHUTDOWN_TH;
|
|
|
|
ret = regmap_update_bits(thermal->rmap, TJ_SHDN_CFG_REG,
|
|
TJ_SHDN_CFG_TJ_ALM1_R | TJ_SHDN_CFG_TJ_ALM2_R | TJ_SHDN_CFG_TJ_SHDN_R, config);
|
|
if (ret < 0)
|
|
dev_err(thermal->dev, "Failed to update TJ_SHDN_CFG_REG: %d\n", ret);
|
|
|
|
ret = regmap_update_bits(thermal->rmap, TOP_MSK1_REG,
|
|
TOP_MSK1_TJ_SHDN_M | TOP_MSK1_TJ_ALM1_M, 0);
|
|
if (ret < 0)
|
|
dev_err(thermal->dev, "Failed to update TOP_MSK1_REG: %d\n", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int max77851_thermal_probe(struct platform_device *pdev)
|
|
{
|
|
struct max77851_chip *chip = dev_get_drvdata(pdev->dev.parent);
|
|
struct max77851_therm_info *thermal;
|
|
int ret;
|
|
|
|
thermal = devm_kzalloc(&pdev->dev, sizeof(*thermal), GFP_KERNEL);
|
|
if (!thermal)
|
|
return -ENOMEM;
|
|
|
|
thermal->irq_tjshutdown = regmap_irq_get_virq(chip->top_irq_data, MAX77851_IRQ_TOP_TJ_SHDN);
|
|
thermal->irq_tjalarm1 = regmap_irq_get_virq(chip->top_irq_data, MAX77851_IRQ_TOP_TJ_ALM1);
|
|
thermal->irq_tjalarm2 = regmap_irq_get_virq(chip->top_irq_data, MAX77851_IRQ_TOP_TJ_ALM2);
|
|
if ((thermal->irq_tjalarm1 < 0) || (thermal->irq_tjalarm2 < 0) || (thermal->irq_tjshutdown < 0)) {
|
|
dev_err(&pdev->dev, "Alarm irq number not available\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
thermal->dev = &pdev->dev;
|
|
thermal->rmap = dev_get_regmap(pdev->dev.parent, NULL);
|
|
if (!thermal->rmap) {
|
|
dev_err(&pdev->dev, "Failed to get parent regmap\n");
|
|
return -ENODEV;
|
|
}
|
|
|
|
of_node_put(pdev->dev.of_node);
|
|
pdev->dev.of_node = of_node_get(pdev->dev.parent->of_node);
|
|
|
|
max77851_thermal_init(thermal);
|
|
|
|
#if defined(NV_DEVM_THERMAL_OF_ZONE_REGISTER_PRESENT)
|
|
thermal->tz_device = devm_thermal_of_zone_register(&pdev->dev, 0,
|
|
thermal, &max77851_thermal_ops);
|
|
#else
|
|
thermal->tz_device = devm_thermal_zone_of_sensor_register(&pdev->dev, 0,
|
|
thermal, &max77851_thermal_ops);
|
|
#endif
|
|
if (IS_ERR(thermal->tz_device)) {
|
|
ret = PTR_ERR(thermal->tz_device);
|
|
dev_err(&pdev->dev, "Failed to register thermal zone: %d\n",
|
|
ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = request_threaded_irq(thermal->irq_tjshutdown, NULL, max77851_thermal_irq, 0,
|
|
"thermal-shutdown", thermal);
|
|
if (ret < 0) {
|
|
dev_err(&pdev->dev, "Failed to request thermal-shutdown IRQ: %d: %d\n",
|
|
thermal->irq_tjshutdown, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = request_threaded_irq(thermal->irq_tjalarm1, NULL, max77851_thermal_irq, 0,
|
|
"thermal-alarm1", thermal);
|
|
if (ret < 0) {
|
|
dev_err(&pdev->dev, "Failed to request thermal-alarm1 IRQ: %d: %d\n",
|
|
thermal->irq_tjalarm1, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = request_threaded_irq(thermal->irq_tjalarm2, NULL, max77851_thermal_irq, 0,
|
|
"thermal-alarm2", thermal);
|
|
if (ret < 0) {
|
|
dev_err(&pdev->dev, "Failed to request thermal-alarm2 IRQ: %d: %d\n",
|
|
thermal->irq_tjalarm2, ret);
|
|
return ret;
|
|
}
|
|
|
|
platform_set_drvdata(pdev, thermal);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct platform_device_id max77851_thermal_devtype[] = {
|
|
{ .name = "max77851-thermal", },
|
|
{},
|
|
};
|
|
|
|
static struct platform_driver max77851_thermal_driver = {
|
|
.driver = {
|
|
.name = "max77851-thermal",
|
|
},
|
|
.probe = max77851_thermal_probe,
|
|
.id_table = max77851_thermal_devtype,
|
|
};
|
|
|
|
module_platform_driver(max77851_thermal_driver);
|
|
|
|
MODULE_DESCRIPTION("MAX77851 thermal driver");
|
|
MODULE_AUTHOR("Shubhi Garg<shgarg@nvidia.com>");
|
|
MODULE_AUTHOR("Joan Na<Joan.na@maximintegrated.com>");
|
|
MODULE_ALIAS("platform:max77851-thermal");
|
|
MODULE_LICENSE("GPL v2");
|