From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Chen-Yu Tsai <wenst@chromium.org>
Cc: Rob Herring <robh@kernel.org>,
Saravana Kannan <saravanak@google.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Wolfram Sang <wsa@kernel.org>, Benson Leung <bleung@chromium.org>,
Tzung-Bi Shih <tzungbi@kernel.org>,
Mark Brown <broonie@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
chrome-platform@lists.linux.dev, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org,
Douglas Anderson <dianders@chromium.org>,
Johan Hovold <johan@kernel.org>, Jiri Kosina <jikos@kernel.org>,
linux-i2c@vger.kernel.org
Subject: Re: [PATCH v6 10/12] i2c: of-prober: Add GPIO support
Date: Wed, 4 Sep 2024 17:04:01 +0300 [thread overview]
Message-ID: <Ztho0WuqgFZxpD1Q@smile.fi.intel.com> (raw)
In-Reply-To: <20240904090016.2841572-11-wenst@chromium.org>
On Wed, Sep 04, 2024 at 05:00:12PM +0800, Chen-Yu Tsai wrote:
> This adds GPIO management to the I2C OF component prober.
> Components that the prober intends to probe likely require their
> regulator supplies be enabled, and GPIOs be toggled to enable them or
> bring them out of reset before they will respond to probe attempts.
> regulator support was added in the previous patch.
>
> Without specific knowledge of each component's resource names or
> power sequencing requirements, the prober can only enable the
> regulator supplies all at once, and toggle the GPIOs all at once.
> Luckily, reset pins tend to be active low, while enable pins tend to
> be active high, so setting the raw status of all GPIO pins to high
> should work. The wait time before and after resources are enabled
> are collected from existing drivers and device trees.
>
> The prober collects resources from all possible components and enables
> them together, instead of enabling resources and probing each component
> one by one. The latter approach does not provide any boot time benefits
> over simply enabling each component and letting each driver probe
> sequentially.
>
> The prober will also deduplicate the resources, since on a component
> swap out or co-layout design, the resources are always the same.
> While duplicate regulator supplies won't cause much issue, shared
> GPIOs don't work reliably, especially with other drivers. For the
> same reason, the prober will release the GPIOs before the successfully
> probed component is actually enabled.
...
> +static int i2c_of_probe_get_gpiod(struct device_node *node, struct property *prop,
> + struct i2c_of_probe_data *data)
> +{
> + struct fwnode_handle *fwnode = of_fwnode_handle(node);
> + struct gpio_descs *gpiods;
> + struct gpio_desc *gpiod;
> + char propname[32]; /* 32 is max size of property name */
> + char *con_id = NULL;
> + size_t new_size;
> + int len, ret;
> +
> + len = gpio_get_property_name_length(prop->name);
> + if (len < 0)
> + return 0;
> +
> + ret = strscpy(propname, prop->name);
> + if (ret < 0) {
> + pr_err("%pOF: length of GPIO name \"%s\" exceeds current limit\n",
> + node, prop->name);
> + return -EINVAL;
Any good reason to shadow the error code from strscpy() here?
> + }
> +
> + if (len > 0) {
> + /* "len < ARRAY_SIZE(propname)" guaranteed by strscpy() above */
is guaranteed
> + propname[len] = '\0';
Please, check if it's guaranteed by strscpy() (IIRC it is, hence redundant line).
> + con_id = propname;
> + }
> +
> + /*
> + * GPIO descriptors are not reference counted. GPIOD_FLAGS_BIT_NONEXCLUSIVE
> + * can't differentiate between GPIOs shared between devices to be probed and
> + * other devices (which is incorrect). If the initial request fails with
> + * -EBUSY, retry with GPIOD_FLAGS_BIT_NONEXCLUSIVE and see if it matches
> + * any existing ones.
> + */
> + gpiod = fwnode_gpiod_get_index(fwnode, con_id, 0, GPIOD_ASIS, "i2c-of-prober");
> + if (IS_ERR(gpiod)) {
> + if (PTR_ERR(gpiod) != -EBUSY || !data->gpiods)
> + return PTR_ERR(gpiod);
> +
> + gpiod = fwnode_gpiod_get_index(fwnode, con_id, 0,
> + GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
> + "i2c-of-prober");
> + for (unsigned int i = 0; i < data->gpiods->ndescs; i++)
> + if (gpiod == data->gpiods->desc[i])
> + return 1;
> +
> + return -EBUSY;
> + }
> +
> + new_size = struct_size(gpiods, desc, data->gpiods ? data->gpiods->ndescs + 1 : 1);
> + gpiods = krealloc(data->gpiods, new_size, GFP_KERNEL);
> + if (!gpiods) {
> + gpiod_put(gpiod);
> + return -ENOMEM;
> + }
> +
> + data->gpiods = gpiods;
> + data->gpiods->desc[data->gpiods->ndescs++] = gpiod;
> +
> + return 1;
> +}
...
> +static int i2c_of_probe_set_gpios(struct device *dev, struct i2c_of_probe_data *data)
> +{
> + int ret;
> + int gpio_i;
Why signed? And can it be simply named 'i'?
> +
> + if (!data->gpiods)
> + return 0;
> +
> + for (gpio_i = 0; gpio_i < data->gpiods->ndescs; gpio_i++) {
> + /*
> + * "reset" GPIOs normally have opposite polarity compared to
> + * "enable" GPIOs. Instead of parsing the flags again, simply
> + * set the raw value to high.
> + */
> + dev_dbg(dev, "Setting GPIO %d\n", gpio_i);
> + ret = gpiod_direction_output_raw(data->gpiods->desc[gpio_i], 1);
> + if (ret)
> + goto disable_gpios;
> + }
> +
> + msleep(data->opts->post_reset_deassert_delay_ms);
> +
> + return 0;
> +
> +disable_gpios:
> + for (gpio_i--; gpio_i >= 0; gpio_i--)
while (i--)
> + gpiod_set_raw_value_cansleep(data->gpiods->desc[gpio_i], 0);
> +
> + return ret;
> +}
--
With Best Regards,
Andy Shevchenko
next prev parent reply other threads:[~2024-09-04 14:04 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-04 9:00 [PATCH v6 00/12] platform/chrome: Introduce DT hardware prober Chen-Yu Tsai
2024-09-04 9:00 ` [PATCH v6 01/12] of: dynamic: Add of_changeset_update_prop_string Chen-Yu Tsai
2024-09-04 9:00 ` [PATCH v6 02/12] of: base: Add for_each_child_of_node_with_prefix_scoped() Chen-Yu Tsai
2024-09-04 13:03 ` Andy Shevchenko
2024-09-04 13:43 ` Rob Herring
2024-09-04 9:00 ` [PATCH v6 03/12] regulator: Move OF-specific regulator lookup code to of_regulator.c Chen-Yu Tsai
2024-09-04 13:09 ` Andy Shevchenko
2024-09-04 13:14 ` Andy Shevchenko
2024-09-05 8:11 ` Chen-Yu Tsai
2024-09-05 8:29 ` Andy Shevchenko
2024-09-04 9:00 ` [PATCH v6 04/12] regulator: Split up _regulator_get() Chen-Yu Tsai
2024-09-04 9:00 ` [PATCH v6 05/12] regulator: Do pure DT regulator lookup in of_regulator_bulk_get_all() Chen-Yu Tsai
2024-09-04 13:13 ` Andy Shevchenko
2024-09-09 2:39 ` Chen-Yu Tsai
2024-09-04 9:00 ` [PATCH v6 06/12] gpiolib: Add gpio_get_property_name_length() Chen-Yu Tsai
2024-09-04 13:40 ` Andy Shevchenko
2024-09-09 2:45 ` Chen-Yu Tsai
2024-09-11 7:37 ` Chen-Yu Tsai
2024-09-11 14:39 ` Andy Shevchenko
2024-09-04 9:00 ` [PATCH v6 07/12] i2c: core: Remove extra space in Makefile Chen-Yu Tsai
2024-09-04 13:41 ` Andy Shevchenko
2024-09-04 9:00 ` [PATCH v6 08/12] i2c: Introduce OF component probe function Chen-Yu Tsai
2024-09-04 13:47 ` Andy Shevchenko
2024-09-09 3:02 ` Chen-Yu Tsai
2024-09-04 15:37 ` Rob Herring
2024-09-04 9:00 ` [PATCH v6 09/12] i2c: of-prober: Add regulator support Chen-Yu Tsai
2024-09-04 13:53 ` Andy Shevchenko
2024-09-04 22:57 ` Doug Anderson
2024-09-05 15:10 ` Chen-Yu Tsai
2024-09-05 18:14 ` Doug Anderson
2024-09-05 18:42 ` Mark Brown
2024-09-05 19:13 ` Andy Shevchenko
2024-09-06 3:45 ` Chen-Yu Tsai
2024-09-11 0:30 ` Doug Anderson
2024-09-11 6:12 ` Chen-Yu Tsai
2024-09-11 14:38 ` Andy Shevchenko
2024-09-11 14:49 ` Mark Brown
2024-09-04 9:00 ` [PATCH v6 10/12] i2c: of-prober: Add GPIO support Chen-Yu Tsai
2024-09-04 14:04 ` Andy Shevchenko [this message]
2024-09-04 9:00 ` [PATCH v6 11/12] platform/chrome: Introduce device tree hardware prober Chen-Yu Tsai
2024-09-04 10:08 ` Tzung-Bi Shih
2024-09-05 3:52 ` Chen-Yu Tsai
2024-09-05 4:34 ` Tzung-Bi Shih
2024-09-04 9:00 ` [PATCH v6 12/12] arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail Chen-Yu Tsai
2024-09-04 17:19 ` (subset) [PATCH v6 00/12] platform/chrome: Introduce DT hardware prober Mark Brown
2024-09-07 16:58 ` Wolfram Sang
2024-09-09 3:24 ` Chen-Yu Tsai
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=Ztho0WuqgFZxpD1Q@smile.fi.intel.com \
--to=andriy.shevchenko@linux.intel.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=bleung@chromium.org \
--cc=broonie@kernel.org \
--cc=chrome-platform@lists.linux.dev \
--cc=devicetree@vger.kernel.org \
--cc=dianders@chromium.org \
--cc=jikos@kernel.org \
--cc=johan@kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=matthias.bgg@gmail.com \
--cc=robh@kernel.org \
--cc=saravanak@google.com \
--cc=tzungbi@kernel.org \
--cc=wenst@chromium.org \
--cc=wsa@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