Message ID | 20240411090628.2436389-2-ckeepax@opensource.cirrus.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add bridged amplifiers to cs42l43 | expand |
On Thu, Apr 11, 2024 at 12:06 PM Charles Keepax <ckeepax@opensource.cirrus.com> wrote: > > SPI devices can specify a cs-gpios property to enumerate their > chip selects. Under device tree, a zero entry in this property can > be used to specify that a particular chip select is using the SPI > controllers native chip select, for example: > > cs-gpios = <&gpio1 0 0>, <0>; > > Here the second chip select is native. However, when using swnodes Here, the > there is currently no way to specify a native chip select. The > proposal here is to register a swnode_gpio_undefined software node, > that can be specified to allow the indication of a native chip > select. For example: > > static const struct software_node_ref_args device_cs_refs[] = { > { > .node = &device_gpiochip_swnode, > .nargs = 2, > .args = { 0, GPIO_ACTIVE_LOW }, > }, > { > .node = &swnode_gpio_undefined, > .nargs = 0, > }, > }; > > Register the swnode as the gpiolib is initialised and check in > swnode_get_gpio_device() if the returned node matches > swnode_gpio_undefined and return -ENOENT, which matches the > behaviour of the device tree system when it encounters a 0 phandle. ... > +config GPIO_SWNODE_UNDEFINED > + bool But why did you remove the help? Please, put it back. ... > + /* > + * Check for special node that identifies undefined GPIOs, this is for a special > + * primarily used as a key for internal chip selects in SPI bindings. > + */ > + if (!strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME)) > + return ERR_PTR(-ENOENT); This is a dead code when the respective config option is not selected. Or actually a potential flaw if somebody else names their swnode like this. ... > + ret = software_node_register(&swnode_gpio_undefined); > + if (ret < 0) > + pr_err("gpiolib: failed to register swnode: %d\n", ret); Instead of this prefix, define pr_fmt() > + return ret; ... > --- a/include/linux/gpio/consumer.h > +++ b/include/linux/gpio/consumer.h Why? I already said that the best place is gpio/property.h as it's exactly for swnode related code.
On Thu, Apr 11, 2024 at 04:25:25PM +0300, Andy Shevchenko wrote: > On Thu, Apr 11, 2024 at 12:06 PM Charles Keepax > <ckeepax@opensource.cirrus.com> wrote: > > Here the second chip select is native. However, when using swnodes > > Here, the > Can do. > > +config GPIO_SWNODE_UNDEFINED > > + bool > > But why did you remove the help? Please, put it back. > Sorry didn't realise you still wanted it will pop it back. > ... > > > + /* > > + * Check for special node that identifies undefined GPIOs, this is > > for a special Can do. > > > + * primarily used as a key for internal chip selects in SPI bindings. > > + */ > > + if (!strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME)) > > + return ERR_PTR(-ENOENT); > > This is a dead code when the respective config option is not selected. > Or actually a potential flaw if somebody else names their swnode like > this. > Can add a check for the config. > ... > > > + ret = software_node_register(&swnode_gpio_undefined); > > + if (ret < 0) > > + pr_err("gpiolib: failed to register swnode: %d\n", ret); > > Instead of this prefix, define pr_fmt() > Little iffy on this, there are other prints in gpiolib that do it this way as well, I guess I could add a patch to convert everything but its starting to get a little out of the thrust of what I am doing here. > > + return ret; > > ... > > > --- a/include/linux/gpio/consumer.h > > +++ b/include/linux/gpio/consumer.h > > Why? I already said that the best place is gpio/property.h as it's > exactly for swnode related code. > Oh I see that's what you meant by those comments, as per my email I wasn't exactly sure. Will move them I don't mind where they go. Thanks, Charles
On Thu, Apr 11, 2024 at 7:44 PM Charles Keepax <ckeepax@opensource.cirrus.com> wrote: > On Thu, Apr 11, 2024 at 04:25:25PM +0300, Andy Shevchenko wrote: > > On Thu, Apr 11, 2024 at 12:06 PM Charles Keepax > > <ckeepax@opensource.cirrus.com> wrote: ... > > > +config GPIO_SWNODE_UNDEFINED > > > + bool > > > > But why did you remove the help? Please, put it back. > > Sorry didn't realise you still wanted it will pop it back. No, I don't want it to be user-selectable. This is defined by a non-empty summary near to the type of the option (bool, tristate). The help text is orthogonal to this. ... > > > + if (!strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME)) > > > + return ERR_PTR(-ENOENT); > > > > This is a dead code when the respective config option is not selected. > > Or actually a potential flaw if somebody else names their swnode like > > this. > > Can add a check for the config. Maybe something like if (IS_ENABLED(...) && !strcmp(...)) ... > > > + ret = software_node_register(&swnode_gpio_undefined); > > > + if (ret < 0) > > > + pr_err("gpiolib: failed to register swnode: %d\n", ret); > > > > Instead of this prefix, define pr_fmt() > > Little iffy on this, there are other prints in gpiolib that do it > this way as well, I guess I could add a patch to convert > everything but its starting to get a little out of the thrust of > what I am doing here. That's why I'm talking only about this (gpiolib-swnode) module where you can have it as "gpiolib: swnode: " fmt or alike
On Thu, Apr 11, 2024 at 07:50:46PM +0300, Andy Shevchenko wrote: > On Thu, Apr 11, 2024 at 7:44 PM Charles Keepax > <ckeepax@opensource.cirrus.com> wrote: > > On Thu, Apr 11, 2024 at 04:25:25PM +0300, Andy Shevchenko wrote: > > > On Thu, Apr 11, 2024 at 12:06 PM Charles Keepax > > > <ckeepax@opensource.cirrus.com> wrote: > > ... > > > > > +config GPIO_SWNODE_UNDEFINED > > > > + bool > > > > > > But why did you remove the help? Please, put it back. > > > > Sorry didn't realise you still wanted it will pop it back. > > No, I don't want it to be user-selectable. > Yeah I get that just didn't realise you also wanted the help, they are technically orthogonal but most non-user selectable things don't define a help. > Maybe something like > > if (IS_ENABLED(...) && > !strcmp(...)) > Aye that is what I just added. > > > > + ret = software_node_register(&swnode_gpio_undefined); > > > > + if (ret < 0) > > > > + pr_err("gpiolib: failed to register swnode: %d\n", ret); > > > > > > Instead of this prefix, define pr_fmt() > > > > Little iffy on this, there are other prints in gpiolib that do it > > this way as well, I guess I could add a patch to convert > > everything but its starting to get a little out of the thrust of > > what I am doing here. > > That's why I'm talking only about this (gpiolib-swnode) module where > you can have it as > > "gpiolib: swnode: " fmt > > or alike > Alright will add this too. Thanks, Charles
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b50d0b470849..c44a6b57aefa 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -103,6 +103,9 @@ config GPIO_REGMAP select REGMAP tristate +config GPIO_SWNODE_UNDEFINED + bool + # put drivers in the right section, in alphabetical order # This symbol is selected by both I2C and SPI expanders diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c index fa52bdb1a29a..add5f8962e8d 100644 --- a/drivers/gpio/gpiolib-swnode.c +++ b/drivers/gpio/gpiolib-swnode.c @@ -6,6 +6,8 @@ */ #include <linux/err.h> #include <linux/errno.h> +#include <linux/export.h> +#include <linux/init.h> #include <linux/kernel.h> #include <linux/printk.h> #include <linux/property.h> @@ -17,6 +19,8 @@ #include "gpiolib.h" #include "gpiolib-swnode.h" +#define GPIOLIB_SWNODE_UNDEFINED_NAME "swnode-gpio-undefined" + static void swnode_format_propname(const char *con_id, char *propname, size_t max_size) { @@ -40,6 +44,13 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) if (!gdev_node || !gdev_node->name) return ERR_PTR(-EINVAL); + /* + * Check for special node that identifies undefined GPIOs, this is + * primarily used as a key for internal chip selects in SPI bindings. + */ + if (!strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME)) + return ERR_PTR(-ENOENT); + gdev = gpio_device_find_by_label(gdev_node->name); return gdev ?: ERR_PTR(-EPROBE_DEFER); } @@ -121,3 +132,32 @@ int swnode_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) return count ?: -ENOENT; } + +#if IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED) +/* + * A special node that identifies undefined GPIOs, this is primarily used as + * a key for internal chip selects in SPI bindings. + */ +const struct software_node swnode_gpio_undefined = { + .name = GPIOLIB_SWNODE_UNDEFINED_NAME, +}; +EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, GPIO_SWNODE); + +static int __init swnode_gpio_init(void) +{ + int ret; + + ret = software_node_register(&swnode_gpio_undefined); + if (ret < 0) + pr_err("gpiolib: failed to register swnode: %d\n", ret); + + return ret; +} +subsys_initcall(swnode_gpio_init); + +static void __exit swnode_gpio_cleanup(void) +{ + software_node_unregister(&swnode_gpio_undefined); +} +__exitcall(swnode_gpio_cleanup); +#endif diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index db2dfbae8edb..e685fac43398 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -12,6 +12,8 @@ struct fwnode_handle; struct gpio_array; struct gpio_desc; +struct software_node; + /** * struct gpio_descs - Struct containing an array of descriptors that can be * obtained using gpiod_get_array() @@ -54,6 +56,8 @@ enum gpiod_flags { GPIOD_OUT_HIGH_OPEN_DRAIN = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_OPEN_DRAIN, }; +extern const struct software_node swnode_gpio_undefined; + #ifdef CONFIG_GPIOLIB /* Return the number of GPIOs associated with a device / function */