mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Matthias Fend <matthias.fend@emfend.at>
To: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Pavel Machek <pavel@ucw.cz>, Lee Jones <lee@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	bsp-development.geo@leica-geosystems.com
Subject: Re: [PATCH v2 2/2] leds: tps6131x: add support for Texas Instruments TPS6131X flash LED driver
Date: Sun, 23 Mar 2025 13:04:21 +0100	[thread overview]
Message-ID: <0ecfd0be-8ab4-48b3-8798-ba1ce0d3e939@emfend.at> (raw)
In-Reply-To: <92d8d240-5156-414f-b58b-a957e27eb30c@kernel.org>

Hi Krzysztof,

Am 19.03.2025 um 20:28 schrieb Krzysztof Kozlowski:
> On 19/03/2025 17:25, Matthias Fend wrote:
>>>> +
>>>> +	if (reg3 & TPS6131X_REG_3_HPFL)
>>>> +		*fault |= LED_FAULT_SHORT_CIRCUIT;
>>>> +
>>>> +	if (reg3 & TPS6131X_REG_3_SELSTIM_TO)
>>>> +		*fault |= LED_FAULT_TIMEOUT;
>>>> +
>>>> +	if (reg4 & TPS6131X_REG_4_HOTDIE_HI)
>>>> +		*fault |= LED_FAULT_OVER_TEMPERATURE;
>>>> +
>>>> +	if (reg6 & (TPS6131X_REG_6_LEDHOT | TPS6131X_REG_6_LEDWARN))
>>>> +		*fault |= LED_FAULT_LED_OVER_TEMPERATURE;
>>>> +
>>>> +	if (!(reg6 & TPS6131X_REG_6_LEDHDR))
>>>> +		*fault |= LED_FAULT_UNDER_VOLTAGE;
>>>> +
>>>> +	if (reg6 & TPS6131X_REG_6_LEDHOT) {
>>>> +		ret = regmap_update_bits_base(tps6131x->regmap, TPS6131X_REG_6,
>>>> +					      TPS6131X_REG_6_LEDHOT, 0, NULL, false, true);
>>>
>>> And this is not locked?
>>
>> The read modify write operation is protected by regmap. Since this
>> operation does not interact with any other functions, no lock is needed
>> here.
> 
> 
> Following that logic no lock is needed in the first place. Define what
> is the purpose of this lock, not just "hardware access". I assumed you
> want to keep consistent hardware state between multiple updates. If
> that's correct, how did you prevent returning value from reads happening
> in the middle of concurrent update? Or how this update_bits_base is
> prevented from happening while you are in the middle of earlier calls
> which are protected by your lock?
> 
> That's confusing lock, considering also too short comment explaining its
> purpose.

Registers 0, 1, 2, and 3 control parts of the controller that are not 
completely independent of each other.
For some operations, it is therefore necessary to write to the registers 
in a specific order to avoid unwanted side effects.
Therefore, I protected write access to these registers with a lock. The 
RMW sequence in regmap_update_bits_base uses the cached value of the 
register and does not read from the hardware.

Explicit reads to the status registers can be performed at any time. If 
a flag is set, this can be reported.
Since regmap_read_bypassed actually reads from the hardware but doesn't 
update the cache, this isn't a problem either.
Therefore, I don't see any need for a lock here.

My suggestion would be to expand the comment as follows:
/* Hardware access lock for register 0, 1, 2 and 3 */

and add this additional note before it:
/*
  * Registers 0, 1, 2, and 3 control parts of the controller that are 
not completely
  * independent of each other. Since some operations require the 
registers to be written in
  * a specific order to avoid unwanted side effects, they are 
synchronized with a lock.
  */

Do you think that's acceptable?

> 
>>
>>>
>>>> +		if (ret < 0)
>>>> +			return ret;
>>>> +	}
>>>> +
>>>
>>> ...
>>>
>>>> +
>>>> +static int tps6131x_flash_external_strobe_set(struct v4l2_flash *v4l2_flash, bool enable)
>>>> +{
>>>> +	struct led_classdev_flash *fled_cdev = v4l2_flash->fled_cdev;
>>>> +	struct tps6131x *tps6131x = fled_cdev_to_tps6131x(fled_cdev);
>>>> +
>>>> +	guard(mutex)(&tps6131x->lock);
>>>> +
>>>> +	return tps6131x_set_mode(tps6131x, enable ? TPS6131X_MODE_FLASH : TPS6131X_MODE_SHUTDOWN,
>>>> +				 false);
>>>> +}
>>>> +
>>>> +static const struct v4l2_flash_ops tps6131x_v4l2_flash_ops = {
>>>> +	.external_strobe_set = tps6131x_flash_external_strobe_set,
>>>> +};
>>>> +
>>>> +static int tps6131x_v4l2_setup(struct tps6131x *tps6131x)
>>>> +{
>>>> +	struct v4l2_flash_config v4l2_cfg = { 0 };
>>>> +	struct led_flash_setting *intensity = &v4l2_cfg.intensity;
>>>> +
>>>> +	if (!IS_BUILTIN(CONFIG_V4L2_FLASH_LED_CLASS))
>>>
>>> Why builtin? That's a tristate, so I don't get why driver and v4l flash
>>> cannot be modules. You wanted REACHABLE probably... but then it is
>>> anyway discouraged practice leading to runtime debugging. So actually
>>> you want CONFIG_V4L2_FLASH_LED_CLASS || !CONFIG_V4L2_FLASH_LED_CLASS
>>> dependency.
>>
>> Okay, I'll add 'depends on V4L2_FLASH_LED_CLASS ||
>> !V4L2_FLASH_LED_CLASS' to the Kconfig entry and do the check in the
>> driver like this:
> 
> Only this
> 
>>     if (!IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS))
>>       return 0;
>>
>> Is this solution okay for you?
> 
> This should should not be needed, because there are v4l2 stubs.

True, it works that way too, you're right, of course.
I was initially tempted by the many 
'IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)' in the other drivers, and then 
by the requested switch to an early return.
I will now remove the remaining early return as well.

Thanks!
  ~Matthias

> 
> Best regards,
> Krzysztof


  reply	other threads:[~2025-03-23 12:04 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-18  7:28 [PATCH v2 0/2] Support " Matthias Fend
2025-03-18  7:28 ` [PATCH v2 1/2] dt-bindings: leds: add Texas Instruments TPS6131x " Matthias Fend
2025-03-19  8:52   ` Krzysztof Kozlowski
2025-03-18  7:28 ` [PATCH v2 2/2] leds: tps6131x: add support for Texas Instruments TPS6131X " Matthias Fend
2025-03-18 10:41   ` kernel test robot
2025-03-19  9:03   ` Krzysztof Kozlowski
2025-03-19 16:25     ` Matthias Fend
2025-03-19 19:28       ` Krzysztof Kozlowski
2025-03-23 12:04         ` Matthias Fend [this message]
2025-03-22  7:30   ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0ecfd0be-8ab4-48b3-8798-ba1ce0d3e939@emfend.at \
    --to=matthias.fend@emfend.at \
    --cc=bsp-development.geo@leica-geosystems.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=krzk@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=robh@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®