[d-kernel] [PATCH 33/35] hwmon: baikal-pvt: support work on machines with old firmware
Daniil Gnusarev
gnusarevda на basealt.ru
Пт Фев 27 13:32:34 MSK 2026
The first firmware versions used PVT channel indices, while
the latest versions have switched to direct addressing. Depending
on the presence of the "pvt_id" property in the DTS, the corresponding
addressing scheme is used.
Also, if the "clock-names" property is missing in the DTS, the value
25000000 / 21 is used instead of determining the operating frequency.
SMC32 calls are also used.
Signed-off-by: Daniil Gnusarev <gnusarevda на basealt.ru>
Do-not-upstream: this is a feature of Baikal-M
---
drivers/hwmon/baikal-pvt-core.c | 6 +++---
drivers/hwmon/baikal-pvt.h | 1 +
drivers/hwmon/bm1000-pvt-hwmon.c | 11 ++++++++---
include/linux/firmware/baikal/baikal-smc.h | 2 +-
4 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/baikal-pvt-core.c b/drivers/hwmon/baikal-pvt-core.c
index 7a649b65768f72..2853a841135917 100644
--- a/drivers/hwmon/baikal-pvt-core.c
+++ b/drivers/hwmon/baikal-pvt-core.c
@@ -556,7 +556,7 @@ static int pvt_write_timeout(struct pvt_hwmon *pvt, long val)
rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk);
if (!rate)
- return -ENODEV;
+ rate = 25000000 / 21;
/*
* If alarms are enabled, the requested timeout must be divided
@@ -952,8 +952,8 @@ static int pvt_init_iface(struct pvt_hwmon *pvt)
rate = clk_get_rate(pvt->clks[PVT_CLOCK_REF].clk);
if (!rate) {
- dev_err(pvt->dev, "Invalid reference clock rate\n");
- return -ENODEV;
+ dev_warn(pvt->dev, "Invalid reference clock rate, default value is used\n");
+ rate = 25000000 / 21;
}
/*
diff --git a/drivers/hwmon/baikal-pvt.h b/drivers/hwmon/baikal-pvt.h
index ca1c786f872dfe..b419f847e67834 100644
--- a/drivers/hwmon/baikal-pvt.h
+++ b/drivers/hwmon/baikal-pvt.h
@@ -250,6 +250,7 @@ struct pvt_hwmon {
struct device *hwmon;
void __iomem *regs;
+ int pvt_id;
int irq;
struct clk_bulk_data clks[PVT_CLOCK_NUM];
diff --git a/drivers/hwmon/bm1000-pvt-hwmon.c b/drivers/hwmon/bm1000-pvt-hwmon.c
index 5b955da5996972..f355fce876037a 100644
--- a/drivers/hwmon/bm1000-pvt-hwmon.c
+++ b/drivers/hwmon/bm1000-pvt-hwmon.c
@@ -126,6 +126,9 @@ static int baikal_init_pvt(struct pvt_hwmon *pvt)
return -ENODEV;
pvt->regs = (void __iomem *)res->start;
+ pvt->pvt_id = -1;
+ of_property_read_u32(pvt->dev->of_node, "pvt_id", &(pvt->pvt_id));
+
return 0;
}
@@ -133,9 +136,9 @@ static u32 baikal_read_pvt(struct pvt_hwmon *pvt, u32 reg)
{
struct arm_smccc_res res;
- arm_smccc_smc(BAIKAL_SMC_PVT_CMD, PVT_READ, (unsigned long)pvt->regs,
+ arm_smccc_smc(BAIKAL_SMC_PVT_CMD, PVT_READ,
+ (pvt->pvt_id >= 0) ? (unsigned long)pvt->pvt_id : (unsigned long)pvt->regs,
reg, 0, 0, 0, 0, &res);
-
return res.a0;
}
@@ -143,7 +146,8 @@ static int baikal_write_pvt(struct pvt_hwmon *pvt, u32 reg, u32 data)
{
struct arm_smccc_res res;
- arm_smccc_smc(BAIKAL_SMC_PVT_CMD, PVT_WRITE, (unsigned long)pvt->regs,
+ arm_smccc_smc(BAIKAL_SMC_PVT_CMD, PVT_WRITE,
+ (pvt->pvt_id >= 0) ? (unsigned long)pvt->pvt_id : (unsigned long)pvt->regs,
reg, data, 0, 0, 0, &res);
return res.a0;
}
@@ -183,6 +187,7 @@ static int pvt_probe(struct platform_device *pdev)
static const struct of_device_id pvt_of_match[] = {
{ .compatible = "baikal,bm1000-pvt" },
+ { .compatible = "baikal,pvt" },
{ }
};
MODULE_DEVICE_TABLE(of, pvt_of_match);
diff --git a/include/linux/firmware/baikal/baikal-smc.h b/include/linux/firmware/baikal/baikal-smc.h
index 648b1e9507de48..1ff7b775975238 100644
--- a/include/linux/firmware/baikal/baikal-smc.h
+++ b/include/linux/firmware/baikal/baikal-smc.h
@@ -9,7 +9,7 @@
#include <linux/arm-smccc.h>
#define BAIKALL_SIP_SMC_FAST_CALL_VAL(func_num) \
- ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_SIP, (func_num))
#define BAIKAL_SMC_CMU_CMD BAIKALL_SIP_SMC_FAST_CALL_VAL(0x0000)
--
2.42.2
Подробная информация о списке рассылки devel-kernel