From: Arnd Bergmann <arnd@xxxxxxxx> There are only a handful of users of gpio_export() and related functions. As these are just wrappers around the modern gpiod_export() helper, remove the wrappers and open-code the gpio_to_desc in all callers to shrink the legacy API. Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx> --- Documentation/admin-guide/gpio/sysfs.rst | 2 +- Documentation/driver-api/gpio/legacy.rst | 30 ----------------- Documentation/translations/zh_CN/gpio.txt | 26 -------------- Documentation/translations/zh_TW/gpio.txt | 27 --------------- arch/arm/mach-davinci/board-dm646x-evm.c | 28 +++++++++------- arch/arm/mach-omap2/pdata-quirks.c | 9 ++--- arch/sh/boards/mach-ap325rxa/setup.c | 7 ++-- drivers/gpio/gpiolib-sysfs.c | 4 +-- drivers/media/i2c/noon010pc30.c | 5 +-- drivers/media/i2c/ov9650.c | 4 +-- drivers/media/i2c/s5k4ecgx.c | 3 +- drivers/media/pci/sta2x11/sta2x11_vip.c | 10 ++++-- drivers/mfd/dm355evm_msp.c | 3 +- drivers/net/ieee802154/ca8210.c | 3 +- include/linux/gpio.h | 41 ----------------------- 15 files changed, 45 insertions(+), 157 deletions(-) diff --git a/Documentation/admin-guide/gpio/sysfs.rst b/Documentation/admin-guide/gpio/sysfs.rst index ec09ffd983e7..35171d15f78d 100644 --- a/Documentation/admin-guide/gpio/sysfs.rst +++ b/Documentation/admin-guide/gpio/sysfs.rst @@ -145,7 +145,7 @@ requested using gpio_request():: /* export the GPIO to userspace */ int gpiod_export(struct gpio_desc *desc, bool direction_may_change); - /* reverse gpio_export() */ + /* reverse gpiod_export() */ void gpiod_unexport(struct gpio_desc *desc); /* create a sysfs link to an exported GPIO node */ diff --git a/Documentation/driver-api/gpio/legacy.rst b/Documentation/driver-api/gpio/legacy.rst index eae185f771d7..34fcb14814db 100644 --- a/Documentation/driver-api/gpio/legacy.rst +++ b/Documentation/driver-api/gpio/legacy.rst @@ -717,36 +717,6 @@ gpiochip nodes (possibly in conjunction with schematics) to determine the correct GPIO number to use for a given signal. -Exporting from Kernel code --------------------------- -Kernel code can explicitly manage exports of GPIOs which have already been -requested using gpio_request():: - - /* export the GPIO to userspace */ - int gpio_export(unsigned gpio, bool direction_may_change); - - /* reverse gpio_export() */ - void gpio_unexport(); - - /* create a sysfs link to an exported GPIO node */ - int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) - -After a kernel driver requests a GPIO, it may only be made available in -the sysfs interface by gpio_export(). The driver can control whether the -signal direction may change. This helps drivers prevent userspace code -from accidentally clobbering important system state. - -This explicit exporting can help with debugging (by making some kinds -of experiments easier), or can provide an always-there interface that's -suitable for documenting as part of a board support package. - -After the GPIO has been exported, gpio_export_link() allows creating -symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can -use this to provide the interface under their own device in sysfs with -a descriptive name. - - API Reference ============= diff --git a/Documentation/translations/zh_CN/gpio.txt b/Documentation/translations/zh_CN/gpio.txt index a23ee14fc927..e49fa88a2804 100644 --- a/Documentation/translations/zh_CN/gpio.txt +++ b/Documentation/translations/zh_CN/gpio.txt @@ -622,29 +622,3 @@ GPIO 控制器的路径类似 /sys/class/gpio/gpiochip42/ (对于从#42 GPIO 固定的,例如在扩展卡上的 GPIO会根据所使用的主板或所在堆叠架构中其他的板子而 有所不同。在这种情况下,你可能需要使用 gpiochip 节点(尽可能地结合电路图)来 确定给定信号所用的 GPIO 编号。 - - -从内核代码中导出 -------------- -内核代码可以明确地管理那些已通过 gpio_request()申请的 GPIO 的导出: - - /* 导出 GPIO 到用户空间 */ - int gpio_export(unsigned gpio, bool direction_may_change); - - /* gpio_export()的逆操作 */ - void gpio_unexport(); - - /* 创建一个 sysfs 连接到已导出的 GPIO 节点 */ - int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) - -在一个内核驱动申请一个 GPIO 之后,它可以通过 gpio_export()使其在 sysfs -接口中可见。该驱动可以控制信号方向是否可修改。这有助于防止用户空间代码无意间 -破坏重要的系统状态。 - -这个明确的导出有助于(通过使某些实验更容易来)调试,也可以提供一个始终存在的接口, -与文档配合作为板级支持包的一部分。 - -在 GPIO 被导出之后,gpio_export_link()允许在 sysfs 文件系统的任何地方 -创建一个到这个 GPIO sysfs 节点的符号链接。这样驱动就可以通过一个描述性的 -名字,在 sysfs 中他们所拥有的设备下提供一个(到这个 GPIO sysfs 节点的)接口。 diff --git a/Documentation/translations/zh_TW/gpio.txt b/Documentation/translations/zh_TW/gpio.txt index e3c076dd75a5..c9bf3ddd08b3 100644 --- a/Documentation/translations/zh_TW/gpio.txt +++ b/Documentation/translations/zh_TW/gpio.txt @@ -622,30 +622,3 @@ GPIO 控制器的路徑類似 /sys/class/gpio/gpiochip42/ (對於從#42 GPIO 固定的,例如在擴展卡上的 GPIO會根據所使用的主板或所在堆疊架構中其他的板子而 有所不同。在這種情況下,你可能需要使用 gpiochip 節點(儘可能地結合電路圖)來 確定給定信號所用的 GPIO 編號。 - - -從內核代碼中導出 -------------- -內核代碼可以明確地管理那些已通過 gpio_request()申請的 GPIO 的導出: - - /* 導出 GPIO 到用戶空間 */ - int gpio_export(unsigned gpio, bool direction_may_change); - - /* gpio_export()的逆操作 */ - void gpio_unexport(); - - /* 創建一個 sysfs 連接到已導出的 GPIO 節點 */ - int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) - -在一個內核驅動申請一個 GPIO 之後,它可以通過 gpio_export()使其在 sysfs -接口中可見。該驅動可以控制信號方向是否可修改。這有助於防止用戶空間代碼無意間 -破壞重要的系統狀態。 - -這個明確的導出有助於(通過使某些實驗更容易來)調試,也可以提供一個始終存在的接口, -與文檔配合作爲板級支持包的一部分。 - -在 GPIO 被導出之後,gpio_export_link()允許在 sysfs 文件系統的任何地方 -創建一個到這個 GPIO sysfs 節點的符號連結。這樣驅動就可以通過一個描述性的 -名字,在 sysfs 中他們所擁有的設備下提供一個(到這個 GPIO sysfs 節點的)接口。 - diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index ee91d81ebbfd..4a258e33021d 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -19,7 +19,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/leds.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/property.h> @@ -249,7 +249,7 @@ static int evm_led_teardown(struct i2c_client *client, int gpio, return 0; } -static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL }; +static struct gpio_desc *evm_sw_gpio[4]; static int evm_sw_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c) @@ -259,17 +259,19 @@ static int evm_sw_setup(struct i2c_client *client, int gpio, char label[10]; for (i = 0; i < 4; ++i) { + struct gpio_desc *desc = gpio_to_desc(gpio + i); + snprintf(label, 10, "user_sw%d", i); - status = gpio_request(gpio, label); + status = gpio_request(gpio + i, label); if (status) goto out_free; - evm_sw_gpio[i] = gpio++; + evm_sw_gpio[i] = desc; - status = gpio_direction_input(evm_sw_gpio[i]); + status = gpiod_direction_input(desc); if (status) goto out_free; - status = gpio_export(evm_sw_gpio[i], 0); + status = gpiod_export(desc, 0); if (status) goto out_free; } @@ -277,9 +279,9 @@ static int evm_sw_setup(struct i2c_client *client, int gpio, out_free: for (i = 0; i < 4; ++i) { - if (evm_sw_gpio[i] != -EINVAL) { - gpio_free(evm_sw_gpio[i]); - evm_sw_gpio[i] = -EINVAL; + if (evm_sw_gpio[i]) { + gpio_free(pin + i); + evm_sw_gpio[i] = NULL; } } return status; @@ -291,10 +293,10 @@ static int evm_sw_teardown(struct i2c_client *client, int gpio, int i; for (i = 0; i < 4; ++i) { - if (evm_sw_gpio[i] != -EINVAL) { - gpio_unexport(evm_sw_gpio[i]); - gpio_free(evm_sw_gpio[i]); - evm_sw_gpio[i] = -EINVAL; + if (evm_sw_gpio[i]) { + gpiod_unexport(evm_sw_gpio[i]); + gpio_free(gpio + i); + evm_sw_gpio[i] = NULL; } } return 0; diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index e7fd29a502a0..1fdf7fcf091e 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -6,6 +6,7 @@ */ #include <linux/clk.h> #include <linux/davinci_emac.h> +#include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/kernel.h> @@ -120,7 +121,7 @@ static int omap3_sbc_t3730_twl_callback(struct device *dev, if (res) return res; - gpio_export(gpio, 0); + gpiod_export(gpio_to_desc(gpio), 0); return 0; } @@ -135,7 +136,7 @@ static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name) return; } - gpio_export(gpio, 0); + gpiod_export(gpio_to_desc(gpio), 0); udelay(10); gpio_set_value(gpio, 1); @@ -212,8 +213,8 @@ static void __init omap3_sbc_t3517_wifi_init(void) return; } - gpio_export(cm_t3517_wlan_gpios[0].gpio, 0); - gpio_export(cm_t3517_wlan_gpios[1].gpio, 0); + gpiod_export(gpio_to_desc(cm_t3517_wlan_gpios[0].gpio), 0); + gpiod_export(gpio_to_desc(cm_t3517_wlan_gpios[1].gpio), 0); msleep(100); gpio_set_value(cm_t3517_wlan_gpios[1].gpio, 0); diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index c77b5f00a66a..151792162152 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/device.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/gpio/machine.h> #include <linux/i2c.h> #include <linux/init.h> @@ -411,16 +412,16 @@ static int __init ap325rxa_devices_setup(void) /* LD3 and LD4 LEDs */ gpio_request(GPIO_PTX5, NULL); /* RUN */ gpio_direction_output(GPIO_PTX5, 1); - gpio_export(GPIO_PTX5, 0); + gpiod_export(gpio_to_desc(GPIO_PTX5), 0); gpio_request(GPIO_PTX4, NULL); /* INDICATOR */ gpio_direction_output(GPIO_PTX4, 0); - gpio_export(GPIO_PTX4, 0); + gpiod_export(gpio_to_desc(GPIO_PTX4), 0); /* SW1 input */ gpio_request(GPIO_PTF7, NULL); /* MODE */ gpio_direction_input(GPIO_PTF7); - gpio_export(GPIO_PTF7, 0); + gpiod_export(gpio_to_desc(GPIO_PTF7), 0); /* LCDC */ gpio_request(GPIO_FN_LCDD15, NULL); diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 4098bc7f88b7..a83fba3649c4 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -511,7 +511,7 @@ static ssize_t unexport_store(struct class *class, goto done; desc = gpio_to_desc(gpio); - /* reject bogus commands (gpio_unexport ignores them) */ + /* reject bogus commands (gpiod_unexport ignores them) */ if (!desc) { pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); return -EINVAL; @@ -814,7 +814,7 @@ static int __init gpiolib_sysfs_init(void) * early (e.g. before the class_register above was called). * * We run before arch_initcall() so chip->dev nodes can have - * registered, and so arch_initcall() can always gpio_export(). + * registered, and so arch_initcall() can always gpiod_export(). */ spin_lock_irqsave(&gpio_lock, flags); list_for_each_entry(gdev, &gpio_devices, list) { diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index f3ac379ef34a..6faa44eb5354 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -10,6 +10,7 @@ */ #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/slab.h> @@ -755,7 +756,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err; } info->gpio_nreset = pdata->gpio_nreset; - gpio_export(info->gpio_nreset, 0); + gpiod_export(gpio_to_desc(info->gpio_nreset), 0); } if (gpio_is_valid(pdata->gpio_nstby)) { @@ -767,7 +768,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err; } info->gpio_nstby = pdata->gpio_nstby; - gpio_export(info->gpio_nstby, 0); + gpiod_export(gpio_to_desc(info->gpio_nstby), 0); } for (i = 0; i < NOON010_NUM_SUPPLIES; i++) diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index c313e11a9754..021acd20ede2 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1426,9 +1426,9 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x, return ret; v4l2_dbg(1, debug, &ov965x->sd, "set gpio %d to 1\n", gpio); - gpio_set_value_cansleep(gpio, 1); - gpio_export(gpio, 0); ov965x->gpios[i] = gpio_to_desc(gpio); + gpiod_set_value_cansleep(ov965x->gpios[i], 1); + gpiod_export(ov965x->gpios[i], 0); } return 0; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index af9a305242cd..419d03fcc978 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -15,6 +15,7 @@ #include <linux/ctype.h> #include <linux/delay.h> #include <linux/firmware.h> +#include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/module.h> @@ -852,7 +853,7 @@ static int s5k4ecgx_config_gpio(int nr, int val, const char *name) return 0; ret = gpio_request_one(nr, flags, name); if (!ret) - gpio_export(nr, 0); + gpiod_export(gpio_to_desc(nr), 0); return ret; } diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index 524912f20d9f..f7cef598f21d 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -18,6 +18,7 @@ #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/delay.h> @@ -893,6 +894,7 @@ static int sta2x11_vip_init_controls(struct sta2x11_vip *vip) static int vip_gpio_reserve(struct device *dev, int pin, int dir, const char *name) { + struct gpio_desc *desc = gpio_to_desc(pin); int ret = -ENODEV; if (!gpio_is_valid(pin)) @@ -904,7 +906,7 @@ static int vip_gpio_reserve(struct device *dev, int pin, int dir, return ret; } - ret = gpio_direction_output(pin, dir); + ret = gpiod_direction_output(desc, dir); if (ret) { dev_err(dev, "Failed to set direction for pin %d (%s)\n", pin, name); @@ -912,7 +914,7 @@ static int vip_gpio_reserve(struct device *dev, int pin, int dir, return ret; } - ret = gpio_export(pin, false); + ret = gpiod_export(desc, false); if (ret) { dev_err(dev, "Failed to export pin %d (%s)\n", pin, name); gpio_free(pin); @@ -932,8 +934,10 @@ static int vip_gpio_reserve(struct device *dev, int pin, int dir, static void vip_gpio_release(struct device *dev, int pin, const char *name) { if (gpio_is_valid(pin)) { + struct gpio_desc *desc = gpio_to_desc(pin); + dev_dbg(dev, "releasing pin %d (%s)\n", pin, name); - gpio_unexport(pin); + gpiod_unexport(desc); gpio_free(pin); } } diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c index 54fb6cbd2aa0..2388fb4d0121 100644 --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c @@ -11,6 +11,7 @@ #include <linux/clk.h> #include <linux/module.h> #include <linux/err.h> +#include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/gpio/machine.h> #include <linux/leds.h> @@ -329,7 +330,7 @@ static int add_children(struct i2c_client *client) gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label); /* make it easy for userspace to see these */ - gpio_export(gpio, false); + gpiod_export(gpio_to_desc(gpio), false); } /* MMC/SD inputs -- right after the last config input */ diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index ece6ff6049f6..6252907b2c92 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -51,6 +51,7 @@ #include <linux/clk-provider.h> #include <linux/debugfs.h> #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/gpio.h> #include <linux/ieee802154.h> #include <linux/io.h> @@ -2895,7 +2896,7 @@ static int ca8210_interrupt_init(struct spi_device *spi) ); if (ret) { dev_crit(&spi->dev, "request_irq %d failed\n", pdata->irq_id); - gpio_unexport(pdata->gpio_irq); + gpiod_unexport(gpio_to_desc(pdata->gpio_irq)); gpio_free(pdata->gpio_irq); } diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 64cc8f09eba8..7ceb93678689 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -144,26 +144,6 @@ extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *labe extern int gpio_request_array(const struct gpio *array, size_t num); extern void gpio_free_array(const struct gpio *array, size_t num); -/* - * A sysfs interface can be exported by individual drivers if they want, - * but more typically is configured entirely from userspace. - */ -static inline int gpio_export(unsigned gpio, bool direction_may_change) -{ - return gpiod_export(gpio_to_desc(gpio), direction_may_change); -} - -static inline int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) -{ - return gpiod_export_link(dev, name, gpio_to_desc(gpio)); -} - -static inline void gpio_unexport(unsigned gpio) -{ - gpiod_unexport(gpio_to_desc(gpio)); -} - /* CONFIG_GPIOLIB: bindings for managed devices that want to request gpios */ struct device; @@ -253,27 +233,6 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value) WARN_ON(1); } -static inline int gpio_export(unsigned gpio, bool direction_may_change) -{ - /* GPIO can never have been requested or set as {in,out}put */ - WARN_ON(1); - return -EINVAL; -} - -static inline int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) -{ - /* GPIO can never have been exported */ - WARN_ON(1); - return -EINVAL; -} - -static inline void gpio_unexport(unsigned gpio) -{ - /* GPIO can never have been exported */ - WARN_ON(1); -} - static inline int gpio_to_irq(unsigned gpio) { /* GPIO can never have been requested or set as input */ -- 2.29.2