diff mbox series

[v2,3/3] leds: rgb: leds-ktd202x: Skip regulator settings for Xiaomi pad2

Message ID 20240216160526.235594-4-hpa@redhat.com (mailing list archive)
State Changes Requested, archived
Headers show
Series KTD2026 indicator LED for X86 Xiaomi Pad2 | expand

Commit Message

Kate Hsuan Feb. 16, 2024, 4:05 p.m. UTC
The controller is already powered by BP25890RTWR on Xiaomi Pad2 so the
regulator settings can be ignored.

Signed-off-by: Kate Hsuan <hpa@redhat.com>
---
 drivers/leds/rgb/leds-ktd202x.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Comments

Ilpo Järvinen Feb. 19, 2024, 1:28 p.m. UTC | #1
On Sat, 17 Feb 2024, Kate Hsuan wrote:

> The controller is already powered by BP25890RTWR on Xiaomi Pad2 so the
> regulator settings can be ignored.
> 
> Signed-off-by: Kate Hsuan <hpa@redhat.com>
> ---
>  drivers/leds/rgb/leds-ktd202x.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/leds/rgb/leds-ktd202x.c b/drivers/leds/rgb/leds-ktd202x.c
> index 8eb79c342fb6..6fd0794988e9 100644
> --- a/drivers/leds/rgb/leds-ktd202x.c
> +++ b/drivers/leds/rgb/leds-ktd202x.c
> @@ -14,7 +14,9 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/regmap.h>
> +#ifndef CONFIG_ACPI
>  #include <linux/regulator/consumer.h>
> +#endif

Why you need #ifndef here?
  
>  #define KTD2026_NUM_LEDS 3
>  #define KTD2027_NUM_LEDS 4
> @@ -105,18 +107,22 @@ struct ktd202x {
>  
>  static int ktd202x_chip_disable(struct ktd202x *chip)
>  {
> +#ifndef CONFIG_ACPI
>  	int ret;
> +#endif
>  
>  	if (!chip->enabled)
>  		return 0;
>  
>  	regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP);
>  
> +#ifndef CONFIG_ACPI
>  	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
>  	if (ret) {
>  		dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
>  		return ret;
>  	}
> +#endif
>  
>  	chip->enabled = false;
>  	return 0;
> @@ -129,11 +135,13 @@ static int ktd202x_chip_enable(struct ktd202x *chip)
>  	if (chip->enabled)
>  		return 0;
>  
> +#ifndef CONFIG_ACPI
>  	ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators);
>  	if (ret) {
>  		dev_err(chip->dev, "Failed to enable regulators: %d\n", ret);
>  		return ret;
>  	}
> +#endif
>  	chip->enabled = true;
>  
>  	ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE);
> @@ -560,6 +568,7 @@ static int ktd202x_probe(struct i2c_client *client)
>  		return ret;
>  	}
>  
> +#ifndef CONFIG_ACPI
>  	chip->regulators[0].supply = "vin";
>  	chip->regulators[1].supply = "vio";
>  	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
> @@ -573,10 +582,12 @@ static int ktd202x_probe(struct i2c_client *client)
>  		dev_err_probe(dev, ret, "Failed to enable regulators.\n");
>  		return ret;
>  	}
> +#endif
>  
>  	chip->num_leds = (int) (unsigned long)i2c_get_match_data(client);
>  
>  	ret = ktd202x_probe_dt(chip);
> +#ifndef CONFIG_ACPI
>  	if (ret < 0) {
>  		regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
>  		return ret;
> @@ -587,6 +598,10 @@ static int ktd202x_probe(struct i2c_client *client)
>  		dev_err_probe(dev, ret, "Failed to disable regulators.\n");
>  		return ret;
>  	}
> +#else
> +	if (ret < 0)
> +		return ret;
> +#endif
>  
>  	mutex_init(&chip->mutex);

To me this entire approach looks quite ugly. It would be much cleaner to 
have something along these lines:

#ifndef CONFIG_ACPI
static int ktd202x_regulators_disable(struct ktd202x *chip)
{
	int ret;

	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
	if (ret)
		dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);

	return ret;
}
...
#else
static inline int ktd202x_regulators_disable(struct ktd202x *chip) { return 0; }
...
#endif

And call that function without any #ifdefs from the other code.
Hans de Goede Feb. 19, 2024, 2:04 p.m. UTC | #2
Hi Kate, Ilpo,

On 2/19/24 14:28, Ilpo Järvinen wrote:
> On Sat, 17 Feb 2024, Kate Hsuan wrote:
> 
>> The controller is already powered by BP25890RTWR on Xiaomi Pad2 so the
>> regulator settings can be ignored.
>>
>> Signed-off-by: Kate Hsuan <hpa@redhat.com>
>> ---
>>  drivers/leds/rgb/leds-ktd202x.c | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/drivers/leds/rgb/leds-ktd202x.c b/drivers/leds/rgb/leds-ktd202x.c
>> index 8eb79c342fb6..6fd0794988e9 100644
>> --- a/drivers/leds/rgb/leds-ktd202x.c
>> +++ b/drivers/leds/rgb/leds-ktd202x.c
>> @@ -14,7 +14,9 @@
>>  #include <linux/of.h>
>>  #include <linux/of_device.h>
>>  #include <linux/regmap.h>
>> +#ifndef CONFIG_ACPI
>>  #include <linux/regulator/consumer.h>
>> +#endif
> 
> Why you need #ifndef here?
>   
>>  #define KTD2026_NUM_LEDS 3
>>  #define KTD2027_NUM_LEDS 4
>> @@ -105,18 +107,22 @@ struct ktd202x {
>>  
>>  static int ktd202x_chip_disable(struct ktd202x *chip)
>>  {
>> +#ifndef CONFIG_ACPI
>>  	int ret;
>> +#endif
>>  
>>  	if (!chip->enabled)
>>  		return 0;
>>  
>>  	regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP);
>>  
>> +#ifndef CONFIG_ACPI
>>  	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
>>  	if (ret) {
>>  		dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
>>  		return ret;
>>  	}
>> +#endif
>>  
>>  	chip->enabled = false;
>>  	return 0;
>> @@ -129,11 +135,13 @@ static int ktd202x_chip_enable(struct ktd202x *chip)
>>  	if (chip->enabled)
>>  		return 0;
>>  
>> +#ifndef CONFIG_ACPI
>>  	ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators);
>>  	if (ret) {
>>  		dev_err(chip->dev, "Failed to enable regulators: %d\n", ret);
>>  		return ret;
>>  	}
>> +#endif
>>  	chip->enabled = true;
>>  
>>  	ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE);
>> @@ -560,6 +568,7 @@ static int ktd202x_probe(struct i2c_client *client)
>>  		return ret;
>>  	}
>>  
>> +#ifndef CONFIG_ACPI
>>  	chip->regulators[0].supply = "vin";
>>  	chip->regulators[1].supply = "vio";
>>  	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
>> @@ -573,10 +582,12 @@ static int ktd202x_probe(struct i2c_client *client)
>>  		dev_err_probe(dev, ret, "Failed to enable regulators.\n");
>>  		return ret;
>>  	}
>> +#endif
>>  
>>  	chip->num_leds = (int) (unsigned long)i2c_get_match_data(client);
>>  
>>  	ret = ktd202x_probe_dt(chip);
>> +#ifndef CONFIG_ACPI
>>  	if (ret < 0) {
>>  		regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
>>  		return ret;
>> @@ -587,6 +598,10 @@ static int ktd202x_probe(struct i2c_client *client)
>>  		dev_err_probe(dev, ret, "Failed to disable regulators.\n");
>>  		return ret;
>>  	}
>> +#else
>> +	if (ret < 0)
>> +		return ret;
>> +#endif
>>  
>>  	mutex_init(&chip->mutex);
> 
> To me this entire approach looks quite ugly. It would be much cleaner to 
> have something along these lines:
> 
> #ifndef CONFIG_ACPI
> static int ktd202x_regulators_disable(struct ktd202x *chip)
> {
> 	int ret;
> 
> 	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
> 	if (ret)
> 		dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
> 
> 	return ret;
> }
> ...
> #else
> static inline int ktd202x_regulators_disable(struct ktd202x *chip) { return 0; }
> ...
> #endif
> 
> And call that function without any #ifdefs from the other code.

I believe that skipping the regulator stuff in the ACPI case is not
the right solution here.

There likely is some underlying issue which also happens on non ACPI
hw, but I guess no-one has ever tried to remove the module there.

I have the same tablet as on which Kate is testing this. So I plan
to make some time to reproduce this and see if I can come up with
a proper fix.

Regards,

Hans
Kate Hsuan Feb. 20, 2024, 4:21 a.m. UTC | #3
Hi Hans and llpo,

On Mon, Feb 19, 2024 at 10:04 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi Kate, Ilpo,
>
> On 2/19/24 14:28, Ilpo Järvinen wrote:
> > On Sat, 17 Feb 2024, Kate Hsuan wrote:
> >
> >> The controller is already powered by BP25890RTWR on Xiaomi Pad2 so the
> >> regulator settings can be ignored.
> >>
> >> Signed-off-by: Kate Hsuan <hpa@redhat.com>
> >> ---
> >>  drivers/leds/rgb/leds-ktd202x.c | 15 +++++++++++++++
> >>  1 file changed, 15 insertions(+)
> >>
> >> diff --git a/drivers/leds/rgb/leds-ktd202x.c b/drivers/leds/rgb/leds-ktd202x.c
> >> index 8eb79c342fb6..6fd0794988e9 100644
> >> --- a/drivers/leds/rgb/leds-ktd202x.c
> >> +++ b/drivers/leds/rgb/leds-ktd202x.c
> >> @@ -14,7 +14,9 @@
> >>  #include <linux/of.h>
> >>  #include <linux/of_device.h>
> >>  #include <linux/regmap.h>
> >> +#ifndef CONFIG_ACPI
> >>  #include <linux/regulator/consumer.h>
> >> +#endif
> >
> > Why you need #ifndef here?
> >
> >>  #define KTD2026_NUM_LEDS 3
> >>  #define KTD2027_NUM_LEDS 4
> >> @@ -105,18 +107,22 @@ struct ktd202x {
> >>
> >>  static int ktd202x_chip_disable(struct ktd202x *chip)
> >>  {
> >> +#ifndef CONFIG_ACPI
> >>      int ret;
> >> +#endif
> >>
> >>      if (!chip->enabled)
> >>              return 0;
> >>
> >>      regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP);
> >>
> >> +#ifndef CONFIG_ACPI
> >>      ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
> >>      if (ret) {
> >>              dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
> >>              return ret;
> >>      }
> >> +#endif
> >>
> >>      chip->enabled = false;
> >>      return 0;
> >> @@ -129,11 +135,13 @@ static int ktd202x_chip_enable(struct ktd202x *chip)
> >>      if (chip->enabled)
> >>              return 0;
> >>
> >> +#ifndef CONFIG_ACPI
> >>      ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators);
> >>      if (ret) {
> >>              dev_err(chip->dev, "Failed to enable regulators: %d\n", ret);
> >>              return ret;
> >>      }
> >> +#endif
> >>      chip->enabled = true;
> >>
> >>      ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE);
> >> @@ -560,6 +568,7 @@ static int ktd202x_probe(struct i2c_client *client)
> >>              return ret;
> >>      }
> >>
> >> +#ifndef CONFIG_ACPI
> >>      chip->regulators[0].supply = "vin";
> >>      chip->regulators[1].supply = "vio";
> >>      ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
> >> @@ -573,10 +582,12 @@ static int ktd202x_probe(struct i2c_client *client)
> >>              dev_err_probe(dev, ret, "Failed to enable regulators.\n");
> >>              return ret;
> >>      }
> >> +#endif
> >>
> >>      chip->num_leds = (int) (unsigned long)i2c_get_match_data(client);
> >>
> >>      ret = ktd202x_probe_dt(chip);
> >> +#ifndef CONFIG_ACPI
> >>      if (ret < 0) {
> >>              regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
> >>              return ret;
> >> @@ -587,6 +598,10 @@ static int ktd202x_probe(struct i2c_client *client)
> >>              dev_err_probe(dev, ret, "Failed to disable regulators.\n");
> >>              return ret;
> >>      }
> >> +#else
> >> +    if (ret < 0)
> >> +            return ret;
> >> +#endif
> >>
> >>      mutex_init(&chip->mutex);
> >
> > To me this entire approach looks quite ugly. It would be much cleaner to
> > have something along these lines:
> >
> > #ifndef CONFIG_ACPI
> > static int ktd202x_regulators_disable(struct ktd202x *chip)
> > {
> >       int ret;
> >
> >       ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
> >       if (ret)
> >               dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
> >
> >       return ret;
> > }
> > ...
> > #else
> > static inline int ktd202x_regulators_disable(struct ktd202x *chip) { return 0; }
> > ...
> > #endif
> >
> > And call that function without any #ifdefs from the other code.
>
> I believe that skipping the regulator stuff in the ACPI case is not
> the right solution here.
>
> There likely is some underlying issue which also happens on non ACPI
> hw, but I guess no-one has ever tried to remove the module there.
>
> I have the same tablet as on which Kate is testing this. So I plan
> to make some time to reproduce this and see if I can come up with
> a proper fix.
>
> Regards,
>
> Hans
>

Thank you for reviewing it.

This patch is used to prevent the WARN_ON() shown in the following URL.
https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L2396

I'll drop this patch in the v3 patch. And I can also try to
investigate the issue of the regulator.


--
BR,
Kate
diff mbox series

Patch

diff --git a/drivers/leds/rgb/leds-ktd202x.c b/drivers/leds/rgb/leds-ktd202x.c
index 8eb79c342fb6..6fd0794988e9 100644
--- a/drivers/leds/rgb/leds-ktd202x.c
+++ b/drivers/leds/rgb/leds-ktd202x.c
@@ -14,7 +14,9 @@ 
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/regmap.h>
+#ifndef CONFIG_ACPI
 #include <linux/regulator/consumer.h>
+#endif
 
 #define KTD2026_NUM_LEDS 3
 #define KTD2027_NUM_LEDS 4
@@ -105,18 +107,22 @@  struct ktd202x {
 
 static int ktd202x_chip_disable(struct ktd202x *chip)
 {
+#ifndef CONFIG_ACPI
 	int ret;
+#endif
 
 	if (!chip->enabled)
 		return 0;
 
 	regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP);
 
+#ifndef CONFIG_ACPI
 	ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
 	if (ret) {
 		dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
 		return ret;
 	}
+#endif
 
 	chip->enabled = false;
 	return 0;
@@ -129,11 +135,13 @@  static int ktd202x_chip_enable(struct ktd202x *chip)
 	if (chip->enabled)
 		return 0;
 
+#ifndef CONFIG_ACPI
 	ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators);
 	if (ret) {
 		dev_err(chip->dev, "Failed to enable regulators: %d\n", ret);
 		return ret;
 	}
+#endif
 	chip->enabled = true;
 
 	ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE);
@@ -560,6 +568,7 @@  static int ktd202x_probe(struct i2c_client *client)
 		return ret;
 	}
 
+#ifndef CONFIG_ACPI
 	chip->regulators[0].supply = "vin";
 	chip->regulators[1].supply = "vio";
 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
@@ -573,10 +582,12 @@  static int ktd202x_probe(struct i2c_client *client)
 		dev_err_probe(dev, ret, "Failed to enable regulators.\n");
 		return ret;
 	}
+#endif
 
 	chip->num_leds = (int) (unsigned long)i2c_get_match_data(client);
 
 	ret = ktd202x_probe_dt(chip);
+#ifndef CONFIG_ACPI
 	if (ret < 0) {
 		regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
 		return ret;
@@ -587,6 +598,10 @@  static int ktd202x_probe(struct i2c_client *client)
 		dev_err_probe(dev, ret, "Failed to disable regulators.\n");
 		return ret;
 	}
+#else
+	if (ret < 0)
+		return ret;
+#endif
 
 	mutex_init(&chip->mutex);