From 910fc996da3fa86781c0bdf494745b07dca16b59 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 16 May 2023 17:14:51 +0900 Subject: [PATCH] Revert "This driver allows GPIO lines to be used as reset signals." This reverts commit be455a52165a60b71029727885213045a7561f07. Change-Id: Iec06e26d4eb0406e8021ef5c9d5944c58d517d83 --- .../ABI/testing/sysfs-driver-gpio-reset | 18 - .../devicetree/bindings/reset/gpio.txt | 44 -- drivers/reset/Kconfig | 13 - drivers/reset/Makefile | 1 - drivers/reset/gpio-reset.c | 463 ------------------ 5 files changed, 539 deletions(-) delete mode 100644 Documentation/ABI/testing/sysfs-driver-gpio-reset delete mode 100644 Documentation/devicetree/bindings/reset/gpio.txt delete mode 100644 drivers/reset/gpio-reset.c diff --git a/Documentation/ABI/testing/sysfs-driver-gpio-reset b/Documentation/ABI/testing/sysfs-driver-gpio-reset deleted file mode 100644 index 6c141441bea7..000000000000 --- a/Documentation/ABI/testing/sysfs-driver-gpio-reset +++ /dev/null @@ -1,18 +0,0 @@ -In the descriptions below is the name of the device tree node -describing the reset line. - -What: /sys/bus/platform/devices/gpio-reset.//duration_ms -Date: February 2014 -Contact: Martin Fuzzey -Description: Allows reset duration to be configured - Read: returns reset duration in ms (decimal) - Write: sets new resst duration in ms (decimal) - -What: /sys/bus/platform/devices/gpio-reset.//control -Date: February 2014 -Contact: Martin Fuzzey -Description: Allows reset line state to be controlled - Write only accepting the following strings: - "reset" : Line will be asserted during the reset duration then deasserted - "assert" : Line will be asserted until next write operation - "deassert" : Line will be deasserted until the next write operation diff --git a/Documentation/devicetree/bindings/reset/gpio.txt b/Documentation/devicetree/bindings/reset/gpio.txt deleted file mode 100644 index 1a36821cce7d..000000000000 --- a/Documentation/devicetree/bindings/reset/gpio.txt +++ /dev/null @@ -1,44 +0,0 @@ -Generic GPIO based Reset Controller -====================================== - -Please also refer to reset.txt in this directory for common reset -controller binding usage. - -The parent node only needs a compatible property "linux,gpio-reset". - -Eaach reset line is described by a child node with the following properties: -Required properties: -- gpios : phandle of the GPIO line to use - -Optional properties: -- asserted-state: 0 => line low to reset, 1 => line high to reset. Defalut 0 -- duration-ms : Number of ms the line should be asserted while resetting (default 1) -- auto : boolean property - if present a reset will be done on boot -- #reset-cells: 0 if drivers can trigger reset via phandle - -example: - -gpio-reset { - compatible = "linux,gpio-reset"; - - wifi { - gpios = <&gpio2 1 0>; - asserted-state = <0>; - duration-ms = <100>; - auto; - }; - - ethernet_phy_reset:ethernet_phy { - #reset-cells = <0>; - gpios = <&gpio7 6 0>; - asserted-state = <0>; - duration-ms = <100>; - }; -}; - -Note that, although this controller may be used as part of the reset -framework, meaning that a device driver may request the reset using the -child node's phandle it (ethernet example above) it can also be used -in a standalone mode where the reset is performed automatically at boot -or from userspace by sysfs. This is particularly for devices that require -reset but are on discoverable busses (eg SDIO, USB). diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 205fe96d0023..06d9fa2f3bc0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -14,19 +14,6 @@ menuconfig RESET_CONTROLLER if RESET_CONTROLLER -config GPIO_RESET_CONTROLLER - tristate "GPIO reset controller" - help - Reset controller using GPIO lines - - There are two main methods of using this controller: - * As a reset controller within the reset framework allowing device - drivers to request a hardware reset of their devices. - * As a standalone driver performing reset at boot or upon userspace - request (via sysfs) - The second method is suitable for devices on discoverable busses - (SDIO, USB) - config RESET_ATH79 bool "AR71xx Reset Driver" if COMPILE_TEST default ATH79 diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index fa376fe3a8ec..bbe7026617fc 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -13,4 +13,3 @@ obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_TI_SYSCON_RESET) += reset-ti-syscon.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o -obj-$(CONFIG_GPIO_RESET_CONTROLLER) += gpio-reset.o diff --git a/drivers/reset/gpio-reset.c b/drivers/reset/gpio-reset.c deleted file mode 100644 index b374e72a1a9e..000000000000 --- a/drivers/reset/gpio-reset.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright 2014 Parkeon - * Martin Fuzzey - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License version 2 as published by the - * Free Software Foundation. - * - * Driver allowing arbitrary hardware to be reset by GPIO signals. - * The reset may be triggered in several ways: - * At boot time (if configured in DT) - * On userspace request via sysfs - * By a driver using the reset controller framework - * - * The first two methods are supplied for devices on discoverable busses - * needing an external reset (eg some SDIO modules, USB hub chips) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -struct gpio_reset_priv; - -struct gpio_reset_line { - struct kobject kobj; - struct gpio_reset_priv *priv; - const char *name; - int gpio; - uint32_t asserted_value; - uint32_t duration_ms; -#ifdef CONFIG_RESET_CONTROLLER - struct reset_controller_dev rcdev; -#endif -}; -#define kobj_to_gpio_reset_line(x) container_of(x, struct gpio_reset_line, kobj) - - -struct gpio_reset_priv { - struct kref refcount; - struct device *dev; - int num_lines; - struct gpio_reset_line lines[]; -}; - -struct gpio_reset_attribute { - struct attribute attr; - ssize_t (*show)(struct gpio_reset_line *line, - struct gpio_reset_attribute *attr, char *buf); - ssize_t (*store)(struct gpio_reset_line *line, - struct gpio_reset_attribute *attr, - const char *buf, size_t count); -}; -#define to_gpio_reset_attr(x) container_of(x, struct gpio_reset_attribute, attr) - - -static void gpio_reset_assert(struct gpio_reset_line *line) -{ - gpio_set_value(line->gpio, line->asserted_value); -} - -static void gpio_reset_deassert(struct gpio_reset_line *line) -{ - gpio_set_value(line->gpio, !line->asserted_value); -} - -static void gpio_reset_reset(struct gpio_reset_line *line) -{ - dev_info(line->priv->dev, "Resetting '%s' (%dms)", - line->name, line->duration_ms); - gpio_reset_assert(line); - msleep(line->duration_ms); - gpio_reset_deassert(line); -} - - -static void gpio_reset_free_priv(struct kref *ref) -{ - struct gpio_reset_priv *priv = container_of(ref, - struct gpio_reset_priv, refcount); - - kfree(priv); -} - -static void gpio_reset_release_kobj(struct kobject *kobj) -{ - struct gpio_reset_line *line; - - line = kobj_to_gpio_reset_line(kobj); - - kref_put(&line->priv->refcount, gpio_reset_free_priv); -} - - -#ifdef CONFIG_SYSFS - -static ssize_t gpio_reset_attr_show(struct kobject *kobj, - struct attribute *attr, - char *buf) -{ - struct gpio_reset_attribute *attribute; - struct gpio_reset_line *line; - - attribute = to_gpio_reset_attr(attr); - line = kobj_to_gpio_reset_line(kobj); - - if (!attribute->show) - return -EIO; - - return attribute->show(line, attribute, buf); -} - -static ssize_t gpio_reset_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, size_t len) -{ - struct gpio_reset_attribute *attribute; - struct gpio_reset_line *line; - - attribute = to_gpio_reset_attr(attr); - line = kobj_to_gpio_reset_line(kobj); - - if (!attribute->store) - return -EIO; - - return attribute->store(line, attribute, buf, len); -} - -static ssize_t control_store(struct gpio_reset_line *line, - struct gpio_reset_attribute *attr, const char *buf, size_t count) -{ - char action[10]; - char *eol; - - strncpy(action, buf, min(count, sizeof(action))); - action[sizeof(action) - 1] = '\0'; - eol = strrchr(action, '\n'); - if (eol) - *eol = '\0'; - - if (!strcmp("reset", action)) - gpio_reset_reset(line); - else if (!strcmp("assert", action)) - gpio_reset_assert(line); - else if (!strcmp("deassert", action)) - gpio_reset_deassert(line); - else - return -EINVAL; - - return count; -} - -static ssize_t duration_ms_show(struct gpio_reset_line *line, - struct gpio_reset_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", line->duration_ms); -} - -static ssize_t duration_ms_store(struct gpio_reset_line *line, - struct gpio_reset_attribute *attr, const char *buf, size_t count) -{ - int ret; - - ret = kstrtouint(buf, 0, &line->duration_ms); - if (ret != 1) - return -EINVAL; - - return count; -} - -static struct gpio_reset_attribute control_attribute = __ATTR_WO(control); -static struct gpio_reset_attribute duration_attribute = __ATTR_RW(duration_ms); - -static struct attribute *gpio_reset_attrs[] = { - &control_attribute.attr, - &duration_attribute.attr, - NULL -}; - - -static const struct sysfs_ops gpio_reset_sysfs_ops = { - .show = gpio_reset_attr_show, - .store = gpio_reset_attr_store, -}; - - -static struct kobj_type gpio_reset_ktype = { - .release = gpio_reset_release_kobj, - .sysfs_ops = &gpio_reset_sysfs_ops, - .default_attrs = gpio_reset_attrs, -}; - -static int gpio_reset_create_sysfs(struct gpio_reset_line *line) -{ - int ret; - - ret = kobject_init_and_add(&line->kobj, &gpio_reset_ktype, - &line->priv->dev->kobj, "reset-%s", line->name); - - kref_get(&line->priv->refcount); /* kobject part of private structure */ - - if (ret) { - kobject_put(&line->kobj); - return ret; - } - - kobject_uevent(&line->kobj, KOBJ_ADD); - - return 0; -} - -static void gpio_reset_destroy_sysfs(struct gpio_reset_line *line) -{ - kobject_put(&line->kobj); -} - - -#else - -static int gpio_reset_create_sysfs(struct gpio_reset_line *line) -{ - return 0; -} - -static void gpio_reset_destroy_sysfs(struct gpio_reset_line *line) -{ -} - -#endif /* CONFIG_SYSFS */ - - -#ifdef CONFIG_RESET_CONTROLLER -#define rcdev_to_gpio_reset_line(x) \ - container_of(x, struct gpio_reset_line, rcdev) - -static int gpio_reset_controller_assert(struct reset_controller_dev *rcdev, - unsigned long sw_reset_idx) -{ - struct gpio_reset_line *line = rcdev_to_gpio_reset_line(rcdev); - - gpio_reset_assert(line); - - return 0; -} - -static int gpio_reset_controller_deassert(struct reset_controller_dev *rcdev, - unsigned long sw_reset_idx) -{ - struct gpio_reset_line *line = rcdev_to_gpio_reset_line(rcdev); - - gpio_reset_deassert(line); - - return 0; -} - -static int gpio_reset_controller_reset(struct reset_controller_dev *rcdev, - unsigned long sw_reset_idx) -{ - struct gpio_reset_line *line = rcdev_to_gpio_reset_line(rcdev); - - gpio_reset_reset(line); - - return 0; -} - -static struct reset_control_ops gpio_reset_ops = { - .assert = gpio_reset_controller_assert, - .deassert = gpio_reset_controller_deassert, - .reset = gpio_reset_controller_reset, -}; - - -int gpio_reset_nooarg_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) -{ - if (WARN_ON(reset_spec->args_count != 0)) - return -EINVAL; - - return 0; -} - -/* We register one controller per line rather than a single - * global controller so that drivers my directly reference the - * phandle of the gpio_reset subnode rather than having to know - * the index. - */ -static int gpio_reset_register_controller( - struct device_node *np, - struct gpio_reset_line *line) -{ - line->rcdev.of_node = np; - line->rcdev.nr_resets = 1; - line->rcdev.ops = &gpio_reset_ops; - line->rcdev.of_xlate = gpio_reset_nooarg_xlate; - - return reset_controller_register(&line->rcdev); -} - -static void gpio_reset_unregister_controller(struct gpio_reset_line *line) -{ - if (line->rcdev.nr_resets) - reset_controller_unregister(&line->rcdev); -} - -#else - -static int gpio_reset_register_controller( - struct device_node *np, - struct gpio_reset_line *line) -{ - return 0; -} - -static void gpio_reset_unregister_controller(struct gpio_reset_line *line) -{ -} -#endif /* CONFIG_RESET_CONTROLLER */ - - -static int gpio_reset_init_line( - struct device_node *np, - struct gpio_reset_line *line) -{ - int ret; - struct device *dev = line->priv->dev; - - line->name = np->name; - - line->gpio = of_get_gpio(np, 0); - if (!gpio_is_valid(line->gpio)) { - dev_warn(dev, "Invalid reset gpio for '%s'", np->name); - return 0; - } - - line->duration_ms = 1; - of_property_read_u32(np, "asserted-state", &line->asserted_value); - of_property_read_u32(np, "duration-ms", &line->duration_ms); - - ret = devm_gpio_request_one(dev, line->gpio, - line->asserted_value ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, - line->name); - if (ret) - return ret; - - ret = gpio_reset_create_sysfs(line); - if (ret) - return ret; - - ret = gpio_reset_register_controller(np, line); - if (ret) - return ret; - - - if (of_property_read_bool(np, "auto")) - gpio_reset_reset(line); - - return 0; -} - -static void gpio_reset_free_line(struct gpio_reset_line *line) -{ - gpio_reset_destroy_sysfs(line); - gpio_reset_unregister_controller(line); -} - -static int gpio_reset_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node, *child; - struct gpio_reset_priv *priv; - struct gpio_reset_line *line; - int num_lines; - int ret; - - num_lines = of_get_available_child_count(np); - if (!num_lines) - return -ENODEV; - - for_each_available_child_of_node(np, child) { - ret = of_get_gpio(child, 0); - if (ret == -EPROBE_DEFER) - return ret; - } - - priv = kzalloc(sizeof(*priv) + sizeof(*line) * num_lines, GFP_KERNEL); - if (!priv) - return -ENOMEM; - - kref_init(&priv->refcount); - priv->dev = &pdev->dev; - priv->num_lines = num_lines; - - line = priv->lines; - for_each_available_child_of_node(np, child) { - line->priv = priv; - ret = gpio_reset_init_line(child, line); - if (ret) - goto rollback; - line++; - } - - platform_set_drvdata(pdev, priv); - - return 0; - -rollback: - while (line >= priv->lines) - gpio_reset_free_line(line--); - - kref_put(&priv->refcount, gpio_reset_free_priv); - - return ret; -} - -static int gpio_reset_remove(struct platform_device *pdev) -{ - struct gpio_reset_priv *priv = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < priv->num_lines; i++) - gpio_reset_free_line(&priv->lines[i]); - - kref_put(&priv->refcount, gpio_reset_free_priv); - - return 0; -} - -static const struct of_device_id gpio_reset_dt_ids[] = { - { .compatible = "linux,gpio-reset" }, - {} -}; - -static struct platform_driver gpio_reset_driver = { - .probe = gpio_reset_probe, - .remove = gpio_reset_remove, - .driver = { - .name = "gpio_reset", - .owner = THIS_MODULE, - .of_match_table = gpio_reset_dt_ids, - }, -}; - -static int __init gpio_reset_init(void) -{ - return platform_driver_register(&gpio_reset_driver); -} -subsys_initcall(gpio_reset_init); - -static void __exit gpio_reset_exit(void) -{ - platform_driver_unregister(&gpio_reset_driver); -} -module_exit(gpio_reset_exit); - -MODULE_AUTHOR("Martin Fuzzey "); -MODULE_DESCRIPTION("GPIO reset controller"); -MODULE_LICENSE("GPL");