From: Andy Shevchenko <andy@kernel.org>
To: "Marek Behún" <kabel@kernel.org>
Cc: Gregory CLEMENT <gregory.clement@bootlin.com>,
Arnd Bergmann <arnd@arndb.de>,
soc@kernel.org, arm@kernel.org,
Linus Walleij <linus.walleij@linaro.org>,
Bartosz Golaszewski <brgl@bgdev.pl>,
linux-gpio@vger.kernel.org
Subject: Re: [PATCH v3 3/7] platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs
Date: Mon, 23 Oct 2023 23:04:07 +0300 [thread overview]
Message-ID: <ZTbRtwTsmAjp3QG0@smile.fi.intel.com> (raw)
In-Reply-To: <20231023143130.11602-4-kabel@kernel.org>
On Mon, Oct 23, 2023 at 04:31:26PM +0200, Marek Behún wrote:
> Add support for GPIOs connected to the MCU on the Turris Omnia board.
>
> This includes:
> - front button pin
> - enable pins for USB regulators
> - MiniPCIe / mSATA card presence pins in MiniPCIe port 0
> - LED output pins from WAN ethernet PHY, LAN switch and MiniPCIe ports
> - on board revisions 32+ also various peripheral resets and another
> voltage regulator enable pin
...
> +static bool omnia_gpio_available(struct omnia_mcu *mcu,
> + const struct omnia_gpio *gpio)
> +{
> + if (gpio->feat_mask)
> + return (mcu->features & gpio->feat_mask) == gpio->feat;
> + else if (gpio->feat)
Redundant 'else'.
> + return mcu->features & gpio->feat;
> +
> + return true;
> +}
...
> +static int omnia_gpio_init_valid_mask(struct gpio_chip *gc,
> + unsigned long *valid_mask,
> + unsigned int ngpios)
> +{
> + struct omnia_mcu *mcu = gpiochip_get_data(gc);
> +
> + for (unsigned int i = 0; i < ngpios; i++) {
> + const struct omnia_gpio *gpio = &omnia_gpios[i];
> + if (!gpio->cmd && !gpio->int_bit) {
> + __clear_bit(i, valid_mask);
> + continue;
> + }
> +
> + __assign_bit(i, valid_mask, omnia_gpio_available(mcu, gpio));
Hmm... Why not simply
if (...)
__clear_bit();
else
__assign_bit(...);
?
> + }
> +
> + return 0;
> +}
...
> +static void omnia_irq_bus_lock(struct irq_data *d)
> +{
> + struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> + struct omnia_mcu *mcu = gpiochip_get_data(gc);
> +
> + /* nothing to do if MCU firmware does not support new interrupt API */
> + if (!(mcu->features & FEAT_NEW_INT_API))
> + return;
> +
> + mutex_lock(&mcu->lock);
I'm wondering if sparse complains on unbalanced locking. If so,
the function needs an annotation.
> +}
...
> +static void omnia_irq_bus_sync_unlock(struct irq_data *d)
> +{
> + struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
> + struct omnia_mcu *mcu = gpiochip_get_data(gc);
> + struct device *dev = &mcu->client->dev;
> + u8 cmd[1 + CMD_INT_ARG_LEN];
> + u32 rising, falling;
> + int err;
> +
> + /* nothing to do if MCU firmware does not support new interrupt API */
> + if (!(mcu->features & FEAT_NEW_INT_API))
> + return;
> +
> + cmd[0] = CMD_SET_INT_MASK;
> +
> + rising = mcu->rising & mcu->mask;
> + falling = mcu->falling & mcu->mask;
> +
> + /* interleave the rising and falling bytes into the command arguments */
> + omnia_mask_interleave(&cmd[1], rising, falling);
> +
> + dev_dbg(dev, "set int mask %8ph\n", &cmd[1]);
> +
> + err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
> + if (err) {
> + dev_err(dev, "Cannot set mask: %d\n", err);
> + goto unlock;
> + }
> +
> + /*
> + * Remember which GPIOs have both rising and falling interrupts enabled.
> + * For those we will cache their value so that .get() method is faster.
> + * We also need to forget cached values of GPIOs that aren't cached
> + * anymore.
> + */
> + mcu->both = rising & falling;
> + mcu->is_cached &= mcu->both;
> +
> +unlock:
> + mutex_unlock(&mcu->lock);
> +}
Same question as above.
...
> +static void omnia_irq_init_valid_mask(struct gpio_chip *gc,
> + unsigned long *valid_mask,
> + unsigned int ngpios)
> +{
> + struct omnia_mcu *mcu = gpiochip_get_data(gc);
> +
> + for (unsigned int i = 0; i < ngpios; i++) {
> + const struct omnia_gpio *gpio = &omnia_gpios[i];
> +
> + if (!gpio->int_bit) {
> + __clear_bit(i, valid_mask);
> + continue;
> + }
> +
> + __assign_bit(i, valid_mask, omnia_gpio_available(mcu, gpio));
if-else ?
> + }
> +}
...
> +static void omnia_mcu_mutex_destroy(void *data)
> +{
> + struct mutex *lock = data;
> +
> + mutex_destroy(lock);
> +}
Can be shrunk to oneliner:
static void omnia_mcu_mutex_destroy(void *lock)
{
mutex_destroy(lock);
}
...
> + /*
> + * The button_release_emul_work has to be initialized before the
> + * thread is requested, and on driver remove it needs to be
> + * canceled before the thread is freed. Therefore we can't use
> + * devm_delayed_work_autocancel() directly, because the order
> + * devm_delayed_work_autocancel();
> + * devm_request_threaded_irq();
> + * would cause improper release order:
> + * free_irq();
> + * cancel_delayed_work_sync();
> + * Instead we first initialize the work above, and only now
> + * after IRQ is requested we add the work devm action.
> + */
...
> +/* Returns 0 on success */
> +static inline int omnia_cmd_read_bits(const struct i2c_client *client, u8 cmd,
> + u32 bits, u32 *dst)
> +{
> + __le32 reply;
> + int err;
> +
> + if (!bits) {
> + *dst = 0;
> + return 0;
> + }
> + err = omnia_cmd_read(client, cmd, &reply, (__fls(bits) >> 3) + 1);
> + if (!err)
> + *dst = le32_to_cpu(reply) & bits;
> +
> + return err;
Why not be in align with the below, i.e.
if (err)
return err;
...
return 0;
?
> +}
> +
> +static inline int omnia_cmd_read_bit(const struct i2c_client *client, u8 cmd,
> + u32 bit)
> +{
> + u32 reply;
> + int err;
> +
> + err = omnia_cmd_read_bits(client, cmd, bit, &reply);
> + if (err)
> + return err;
> +
> + return !!reply;
> +}
...
> static inline int omnia_cmd_read_u16(const struct i2c_client *client, u8 cmd)
> {
> - u16 reply;
> + __le16 reply;
> int err;
Shouldn't this be a part of another patch?
> }
--
With Best Regards,
Andy Shevchenko
next prev parent reply other threads:[~2023-10-23 20:04 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-23 14:31 [PATCH v3 0/7] Turris Omnia MCU driver Marek Behún
2023-10-23 14:31 ` [PATCH v3 1/7] dt-bindings: arm: add cznic,turris-omnia-mcu binding Marek Behún
2023-10-23 14:31 ` [PATCH v3 2/7] platform: cznic: Add preliminary support for Turris Omnia MCU Marek Behún
2023-10-23 14:31 ` [PATCH v3 3/7] platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs Marek Behún
2023-10-23 20:04 ` Andy Shevchenko [this message]
2023-10-26 16:14 ` Marek Behún
2023-10-23 14:31 ` [PATCH v3 4/7] platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup Marek Behún
2023-10-23 19:40 ` Andy Shevchenko
2023-10-26 16:16 ` Marek Behún
2023-10-23 14:31 ` [PATCH v3 5/7] platform: cznic: turris-omnia-mcu: Add support for MCU watchdog Marek Behún
2023-10-23 14:47 ` Guenter Roeck
2023-10-23 14:59 ` Marek Behún
2023-10-23 15:03 ` Mark Brown
2023-10-23 15:09 ` Marek Behún
2023-10-23 14:31 ` [PATCH v3 6/7] ARM: dts: turris-omnia: Add MCU system-controller node Marek Behún
2023-10-23 14:31 ` [PATCH v3 7/7] ARM: dts: turris-omnia: Add GPIO key node for front button Marek Behún
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=ZTbRtwTsmAjp3QG0@smile.fi.intel.com \
--to=andy@kernel.org \
--cc=arm@kernel.org \
--cc=arnd@arndb.de \
--cc=brgl@bgdev.pl \
--cc=gregory.clement@bootlin.com \
--cc=kabel@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=soc@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