gpiolib-swnode.c (0ea5c948cb64bab5bc7a5516774eb8536f05aa0d) gpiolib-swnode.c (9d50f95bc0d5df56f2591b950a251d90bffad094)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Software Node helpers for the GPIO API
4 *
5 * Copyright 2022 Google LLC
6 */
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Software Node helpers for the GPIO API
4 *
5 * Copyright 2022 Google LLC
6 */
7
8#define pr_fmt(fmt) "gpiolib: swnode: " fmt
9
7#include <linux/err.h>
8#include <linux/errno.h>
10#include <linux/err.h>
11#include <linux/errno.h>
12#include <linux/export.h>
13#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/printk.h>
11#include <linux/property.h>
12#include <linux/string.h>
13
14#include <linux/gpio/consumer.h>
15#include <linux/gpio/driver.h>
16
17#include "gpiolib.h"
18#include "gpiolib-swnode.h"
19
14#include <linux/kernel.h>
15#include <linux/printk.h>
16#include <linux/property.h>
17#include <linux/string.h>
18
19#include <linux/gpio/consumer.h>
20#include <linux/gpio/driver.h>
21
22#include "gpiolib.h"
23#include "gpiolib-swnode.h"
24
25#define GPIOLIB_SWNODE_UNDEFINED_NAME "swnode-gpio-undefined"
26
20static void swnode_format_propname(const char *con_id, char *propname,
21 size_t max_size)
22{
23 /*
24 * Note we do not need to try both -gpios and -gpio suffixes,
25 * as, unlike OF and ACPI, we can fix software nodes to conform
26 * to the proper binding.
27 */

--- 7 unchanged lines hidden (view full) ---

35{
36 const struct software_node *gdev_node;
37 struct gpio_device *gdev;
38
39 gdev_node = to_software_node(fwnode);
40 if (!gdev_node || !gdev_node->name)
41 return ERR_PTR(-EINVAL);
42
27static void swnode_format_propname(const char *con_id, char *propname,
28 size_t max_size)
29{
30 /*
31 * Note we do not need to try both -gpios and -gpio suffixes,
32 * as, unlike OF and ACPI, we can fix software nodes to conform
33 * to the proper binding.
34 */

--- 7 unchanged lines hidden (view full) ---

42{
43 const struct software_node *gdev_node;
44 struct gpio_device *gdev;
45
46 gdev_node = to_software_node(fwnode);
47 if (!gdev_node || !gdev_node->name)
48 return ERR_PTR(-EINVAL);
49
50 /*
51 * Check for a special node that identifies undefined GPIOs, this is
52 * primarily used as a key for internal chip selects in SPI bindings.
53 */
54 if (IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED) &&
55 !strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME))
56 return ERR_PTR(-ENOENT);
57
43 gdev = gpio_device_find_by_label(gdev_node->name);
44 return gdev ?: ERR_PTR(-EPROBE_DEFER);
45}
46
47struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode,
48 const char *con_id, unsigned int idx,
49 unsigned long *flags)
50{

--- 65 unchanged lines hidden (view full) ---

116 while (fwnode_property_get_reference_args(fwnode, propname, NULL, 0,
117 count, &args) == 0) {
118 fwnode_handle_put(args.fwnode);
119 count++;
120 }
121
122 return count ?: -ENOENT;
123}
58 gdev = gpio_device_find_by_label(gdev_node->name);
59 return gdev ?: ERR_PTR(-EPROBE_DEFER);
60}
61
62struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode,
63 const char *con_id, unsigned int idx,
64 unsigned long *flags)
65{

--- 65 unchanged lines hidden (view full) ---

131 while (fwnode_property_get_reference_args(fwnode, propname, NULL, 0,
132 count, &args) == 0) {
133 fwnode_handle_put(args.fwnode);
134 count++;
135 }
136
137 return count ?: -ENOENT;
138}
139
140#if IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED)
141/*
142 * A special node that identifies undefined GPIOs, this is primarily used as
143 * a key for internal chip selects in SPI bindings.
144 */
145const struct software_node swnode_gpio_undefined = {
146 .name = GPIOLIB_SWNODE_UNDEFINED_NAME,
147};
148EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, GPIO_SWNODE);
149
150static int __init swnode_gpio_init(void)
151{
152 int ret;
153
154 ret = software_node_register(&swnode_gpio_undefined);
155 if (ret < 0)
156 pr_err("failed to register swnode: %d\n", ret);
157
158 return ret;
159}
160subsys_initcall(swnode_gpio_init);
161
162static void __exit swnode_gpio_cleanup(void)
163{
164 software_node_unregister(&swnode_gpio_undefined);
165}
166__exitcall(swnode_gpio_cleanup);
167#endif