FILE
gpiolib-swnode.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpio/gpiolib-swnode.c
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 10#include <linux/err.h> 11#include <linux/errno.h> 12#include <linux/export.h> 13#include <linux/init.h> 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 27static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) 28{ 29 const struct software_node *gdev_node; 30 struct gpio_device *gdev; 31 32 gdev_node = to_software_node(fwnode); 33 if (!gdev_node || !gdev_node->name) 34 goto fwnode_lookup; 35 36 /* 37 * Check for a special node that identifies undefined GPIOs, this is 38 * primarily used as a key for internal chip selects in SPI bindings. 39 */ 40 if (IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED) && 41 !strcmp(gdev_node->name, GPIOLIB_SWNODE_UNDEFINED_NAME)) 42 return ERR_PTR(-ENOENT); 43 44fwnode_lookup: 45 gdev = gpio_device_find_by_fwnode(fwnode); 46 if (!gdev && gdev_node && gdev_node->name) 47 /* 48 * FIXME: We shouldn't need to compare the GPIO controller's 49 * label against the software node that is supposedly attached 50 * to it. However there are currently GPIO users that - knowing 51 * the expected label of the GPIO chip whose pins they want to 52 * control - set up dummy software nodes named after those GPIO 53 * controllers, which aren't actually attached to them. In this 54 * case gpio_device_find_by_fwnode() will fail as no device on 55 * the GPIO bus is actually associated with the fwnode we're 56 * looking for. 57 * 58 * As a fallback: continue checking the label if we have no 59 * match. However, the situation described above is an abuse 60 * of the software node API and should be phased out and the 61 * following line - eventually removed. 62 */ 63 gdev = gpio_device_find_by_label(gdev_node->name); 64 65 return gdev ?: ERR_PTR(-EPROBE_DEFER); 66} 67 68static int swnode_gpio_get_reference(const struct fwnode_handle *fwnode, 69 const char *propname, unsigned int idx, 70 struct fwnode_reference_args *args) 71{ 72 /* 73 * We expect all swnode-described GPIOs have GPIO number and 74 * polarity arguments, hence nargs is set to 2. 75 */ 76 return fwnode_property_get_reference_args(fwnode, propname, NULL, 2, idx, args); 77} 78 79struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, 80 const char *con_id, unsigned int idx, 81 unsigned long *flags) 82{ 83 const struct software_node *swnode; 84 struct fwnode_reference_args args; 85 struct gpio_desc *desc; 86 char propname[32]; /* 32 is max size of property name */ 87 int ret = 0; 88 89 swnode = to_software_node(fwnode); 90 if (!swnode) 91 return ERR_PTR(-EINVAL); 92 93 for_each_gpio_property_name(propname, con_id) { 94 ret = swnode_gpio_get_reference(fwnode, propname, idx, &args); 95 if (ret == 0) 96 break; 97 } 98 if (ret) { 99 pr_debug("%s: can't parse '%s' property of node '%pfwP[%d]'\n", 100 __func__, propname, fwnode, idx); 101 return ERR_PTR(ret); 102 } 103 104 struct gpio_device *gdev __free(gpio_device_put) = 105 swnode_get_gpio_device(args.fwnode); 106 fwnode_handle_put(args.fwnode); 107 if (IS_ERR(gdev)) 108 return ERR_CAST(gdev); 109 110 /* 111 * FIXME: The GPIO device reference is put at return but the descriptor 112 * is passed on. Find a proper solution. 113 */ 114 desc = gpio_device_get_desc(gdev, args.args[0]); 115 *flags = args.args[1]; /* We expect native GPIO flags */ 116 117 pr_debug("%s: parsed '%s' property of node '%pfwP[%d]' - status (%d)\n", 118 __func__, propname, fwnode, idx, PTR_ERR_OR_ZERO(desc)); 119 120 return desc; 121} 122 123/** 124 * swnode_gpio_count - count the GPIOs associated with a device / function 125 * @fwnode: firmware node of the GPIO consumer, can be %NULL for 126 * system-global GPIOs 127 * @con_id: function within the GPIO consumer 128 * 129 * Returns: 130 * The number of GPIOs associated with a device / function or %-ENOENT, 131 * if no GPIO has been assigned to the requested function. 132 */ 133int swnode_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) 134{ 135 struct fwnode_reference_args args; 136 char propname[32]; 137 int count; 138 139 /* 140 * This is not very efficient, but GPIO lists usually have only 141 * 1 or 2 entries. 142 */ 143 for_each_gpio_property_name(propname, con_id) { 144 count = 0; 145 while (swnode_gpio_get_reference(fwnode, propname, count, &args) == 0) { 146 fwnode_handle_put(args.fwnode); 147 count++; 148 } 149 if (count) 150 return count; 151 } 152 153 return -ENOENT; 154} 155 156#if IS_ENABLED(CONFIG_GPIO_SWNODE_UNDEFINED) 157/* 158 * A special node that identifies undefined GPIOs, this is primarily used as 159 * a key for internal chip selects in SPI bindings. 160 */ 161const struct software_node swnode_gpio_undefined = { 162 .name = GPIOLIB_SWNODE_UNDEFINED_NAME, 163}; 164EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, "GPIO_SWNODE"); 165 166static int __init swnode_gpio_init(void) 167{ 168 int ret; 169 170 ret = software_node_register(&swnode_gpio_undefined); 171 if (ret < 0) 172 pr_err("failed to register swnode: %d\n", ret); 173 174 return ret; 175} 176subsys_initcall(swnode_gpio_init); 177 178static void __exit swnode_gpio_cleanup(void) 179{ 180 software_node_unregister(&swnode_gpio_undefined); 181} 182__exitcall(swnode_gpio_cleanup); 183#endif
~/
Read-only file preview.