Hi Elaine,This "otp_out" IO may be connected to the RESET circuit on the hardware. If the IO is in the wrong state, it will trigger RESET (similar to the effect of pressing the RESET button), which will cause the system to restart all the time.
On 11/04/2019 09:46, elaine.zhang wrote:
hi,why?
å 2019/4/4 äå11:03, Daniel Lezcano åé:
On 01/04/2019 08:43, Elaine Zhang wrote:Example:
Based on the TSADC Tshut mode to select pinctrl,I'm not sure to fully read the description. Can you rephrase/elaborate
instead of setting pinctrl based on architecture
(Not depends on pinctrl setting by "init" or "default").
And it requires setting the tshut polarity before select pinctrl.
the changelog?
ÂÂÂÂÂÂÂ tsadc: tsadc@ff250000 {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ compatible = "rockchip,rk3328-tsadc";
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ .....
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ pinctrl-names = "init", "default", "sleep";
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ pinctrl-0 = <&otp_gpio>;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ pinctrl-1 = <&otp_out>;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ pinctrl-2 = <&otp_gpio>;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ status = "disabled";
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ .....
ÂÂÂÂÂÂÂÂÂÂÂ };
ÂÂÂÂÂÂÂ &tsadc {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ status = "okay";
ÂÂÂÂÂÂÂ };
ÂÂÂ Application on the product, hope tsadc overtemperature reset cru to
restart.
ÂÂÂ But when pinctrl is initialized, it will setting pinctrl by "init"
and "default".
ÂÂÂ So the pinctrl will set iomux to "otp_out", which may be make system
crash.
This explanation is correct.
ÂÂÂ tsadc gpio iomux:Let me rephrase it and tell me if I understood correctly:
ÂÂÂ "otp_gpio" : just normal gpio, keep default level.
ÂÂÂ "otp_out" : tsadc shut down io, when overtemperature,this io may be
trigger high
ÂÂÂ level or low level(depend on the tsadc polarity).
ÂÂÂ After correction:
ÂÂÂ if rockchip,hw-tshut-mode = <0>; (tsadc overtemperature reset cru to
restart)
ÂÂÂ select pinctrl to otp_gpio
ÂÂÂ if rockchip,hw-tshut-mode = <1>;(tsadc overtemperature IO triggers
output at high or low levels)
ÂÂÂ select pinctrl to otp_out.
ÂÂÂ Actively select iomux based on rockchip,hw-tshut-mode,
ÂÂÂ rather than relying on the pinctrl framework to select iomux.
"When the temperature sensor mode is set to 0, it will automatically
reset the board via the Clock-Reset-Unit (CRU) if the over temperature
threshold is reached. However, when the pinctrl initializes, it does a
transition to "otp_out" which may lead the SoC to crash (why?)
Explicitly use the pinctrl to set/unset the right mode instead of
relying on the pinctrl init mode"
OK, I'll fix that in the v2.
So this patch is a fix and it must contain the Fixes: ... tag.
OK, keep the enum name. I'll fix it in the V2.
I understand, but at the end the changes for this patch are counterI just want to make it a little bit more intuitive to understand theSigned-off-by: Elaine Zhang <zhangqing@xxxxxxxxxxxxxx>Why do you change the enum name? The impact on the patch is much higher,
---
 drivers/thermal/rockchip_thermal.c | 61
+++++++++++++++++++++++++++++++-------
 1 file changed, 50 insertions(+), 11 deletions(-)
diff --git a/drivers/thermal/rockchip_thermal.c
b/drivers/thermal/rockchip_thermal.c
index 9c7643d62ed7..faa6c7792155 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -34,7 +34,7 @@
ÂÂ */
 enum tshut_mode {
ÂÂÂÂÂ TSHUT_MODE_CRU = 0,
-ÂÂÂ TSHUT_MODE_GPIO,
+ÂÂÂ TSHUT_MODE_OTP,
no ?
definition of mode.
TSHUT_MODE_CRU: pinctrl select iomux to otp_gpio,the io is normal io.
TSHUT_MODE_OTP: pinctrl select iomux to otp_out, the io is tsadc shut io.
intuitive, so it is preferable to keep it as is so we can review the
important part.
[ ... ]
OK, I'll fix it in the V2.
No, that does not reduce a lot of duplicated code, it hides the factBecause there are several places where the call is made,create a couple +static void thermal_pinctrl_select_otp(structYou should not have to create a couple of specific functions just to
rockchip_thermal_data *thermal)
+{
+ÂÂÂ if (!IS_ERR(thermal->pinctrl) &&
!IS_ERR_OR_NULL(thermal->otp_state))
+ÂÂÂÂÂÂÂ pinctrl_select_state(thermal->pinctrl,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ thermal->otp_state);
+}
+
+static void thermal_pinctrl_select_gpio(struct rockchip_thermal_data
*thermal)
+{
+ÂÂÂ if (!IS_ERR(thermal->pinctrl) &&
!IS_ERR_OR_NULL(thermal->gpio_state))
+ÂÂÂÂÂÂÂ pinctrl_select_state(thermal->pinctrl,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ thermal->gpio_state);
+}
check the pinctrl pointers are set. The caller should do that.
of specific functions reduce a lot of duplicated code.
there is no control from the caller. See the comments below.
[ ... ]
OK, It's good advice. I'll fix it in the V2.
panic if devm_pinctrl_get fails. static int rockchip_configure_from_dt(struct device *dev,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ struct device_node *np,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ struct rockchip_thermal_data *thermal)
@@ -1103,7 +1120,7 @@ static int rockchip_configure_from_dt(struct
device *dev,
ÂÂÂÂÂ if (of_property_read_u32(np, "rockchip,hw-tshut-mode",
&tshut_mode)) {
ÂÂÂÂÂÂÂÂÂ dev_warn(dev,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "Missing tshut mode property, using default (%s)\n",
-ÂÂÂÂÂÂÂÂÂÂÂÂ thermal->chip->tshut_mode == TSHUT_MODE_GPIO ?
+ÂÂÂÂÂÂÂÂÂÂÂÂ thermal->chip->tshut_mode == TSHUT_MODE_OTP ?
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "gpio" : "cru");
ÂÂÂÂÂÂÂÂÂ thermal->tshut_mode = thermal->chip->tshut_mode;
ÂÂÂÂÂ } else {
@@ -1242,6 +1259,8 @@ static int rockchip_thermal_probe(struct
platform_device *pdev)
ÂÂÂÂÂÂÂÂÂ return error;
ÂÂÂÂÂ }
 + thermal->chip->control(thermal->regs, false);
+
ÂÂÂÂÂ error = clk_prepare_enable(thermal->clk);
ÂÂÂÂÂ if (error) {
ÂÂÂÂÂÂÂÂÂ dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
@@ -1267,6 +1286,24 @@ static int rockchip_thermal_probe(struct
platform_device *pdev)
ÂÂÂÂÂ thermal->chip->initialize(thermal->grf, thermal->regs,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ thermal->tshut_polarity);
 + if (thermal->tshut_mode == TSHUT_MODE_OTP) {
+ÂÂÂÂÂÂÂ thermal->pinctrl = devm_pinctrl_get(&pdev->dev);
+ÂÂÂÂÂÂÂ if (IS_ERR(thermal->pinctrl))
+ÂÂÂÂÂÂÂÂÂÂÂ dev_err(&pdev->dev, "failed to find thermal pinctrl\n");
+
+ÂÂÂÂÂÂÂ thermal->gpio_state = pinctrl_lookup_state(thermal->pinctrl,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "gpio");
If the DST node is not modified synchronously, which may cause the rockchip_thermal driver probe failed.
It is pointless to have a otp_state and a gpio_state field. Just use oneIf the lookup fails for any of thoseï The pinctrl is no longer set and+ÂÂÂÂÂÂÂ if (IS_ERR_OR_NULL(thermal->gpio_state))What is the meaning for the rest of the code if the lookup fails for any
+ÂÂÂÂÂÂÂÂÂÂÂ dev_err(&pdev->dev, "failed to find thermal gpio state\n");
+
+ÂÂÂÂÂÂÂ thermal->otp_state = pinctrl_lookup_state(thermal->pinctrl,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "otpout");
+ÂÂÂÂÂÂÂ if (IS_ERR_OR_NULL(thermal->otp_state))
+ÂÂÂÂÂÂÂÂÂÂÂ dev_err(&pdev->dev, "failed to find thermal otpout
state\n");
of those ?
remains in its default state(otp_gpio normal io).
+ÂÂÂÂÂÂÂ thermal_pinctrl_select_otp(thermal);
+ÂÂÂ }
+
as the configuration tells you which lookup to do.
In case of error, just bail out. It is pointless to continue with a
broken configuration.
OK. I'll fix it in the V2.
thermal->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(thermal->pinctrl)) {
dev_err(&pdev->dev, "....");
return PTR_ERR(thermal->pinctrl);
}
thermal->pinctrl_state =
pinctrl_lookup_state(thermal->pinctrl,
thermal->tshut_mode == TSHUT_MODE_OTP ?
"otp" : "gpio");
if (IS_ERR_OR_NULL(thermal->pinctrl_state)) {
dev_err(&pdev->dev, "....");
return -EINVAL;
}
No need to use the thermal_pinctrl_select_otp/gpio wrappers, just
replace them with:
pinctrl_select_state(thermal->pinctrl, thermal->pinctrl_state);
and use it unconditionally.
ÂÂÂÂÂ for (i = 0; i < thermal->chip->chn_num; i++) {
ÂÂÂÂÂÂÂÂÂ error = rockchip_thermal_register_sensor(pdev, thermal,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ &thermal->sensors[i],
@@ -1338,7 +1375,8 @@ static int __maybe_unused
rockchip_thermal_suspend(struct device *dev)
ÂÂÂÂÂ clk_disable(thermal->pclk);
ÂÂÂÂÂ clk_disable(thermal->clk);
 - pinctrl_pm_select_sleep_state(dev);
+ÂÂÂ if (thermal->tshut_mode == TSHUT_MODE_OTP)
+ÂÂÂÂÂÂÂ thermal_pinctrl_select_gpio(thermal);
 Â return 0;
 }
@@ -1383,7 +1421,8 @@ static int __maybe_unused
rockchip_thermal_resume(struct device *dev)
ÂÂÂÂÂ for (i = 0; i < thermal->chip->chn_num; i++)
ÂÂÂÂÂÂÂÂÂ rockchip_thermal_toggle_sensor(&thermal->sensors[i], true);
 - pinctrl_pm_select_default_state(dev);
+ÂÂÂ if (thermal->tshut_mode == TSHUT_MODE_OTP)
+ÂÂÂÂÂÂÂ thermal_pinctrl_select_otp(thermal);
 Â return 0;
 }