File Index
Files and directories
Sign in
FILE

reset-gpio.c

File preview with syntax highlighting.

linux-6.19.14/drivers/reset/reset-gpio.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <linux/auxiliary_bus.h>
  4#include <linux/gpio/consumer.h>
  5#include <linux/mod_devicetable.h>
  6#include <linux/module.h>
  7#include <linux/of.h>
  8#include <linux/reset-controller.h>
  9
 10struct reset_gpio_priv {
 11	struct reset_controller_dev rc;
 12	struct gpio_desc *reset;
 13};
 14
 15static inline struct reset_gpio_priv
 16*rc_to_reset_gpio(struct reset_controller_dev *rc)
 17{
 18	return container_of(rc, struct reset_gpio_priv, rc);
 19}
 20
 21static int reset_gpio_assert(struct reset_controller_dev *rc, unsigned long id)
 22{
 23	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
 24
 25	gpiod_set_value_cansleep(priv->reset, 1);
 26
 27	return 0;
 28}
 29
 30static int reset_gpio_deassert(struct reset_controller_dev *rc,
 31			       unsigned long id)
 32{
 33	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
 34
 35	gpiod_set_value_cansleep(priv->reset, 0);
 36
 37	return 0;
 38}
 39
 40static int reset_gpio_status(struct reset_controller_dev *rc, unsigned long id)
 41{
 42	struct reset_gpio_priv *priv = rc_to_reset_gpio(rc);
 43
 44	return gpiod_get_value_cansleep(priv->reset);
 45}
 46
 47static const struct reset_control_ops reset_gpio_ops = {
 48	.assert = reset_gpio_assert,
 49	.deassert = reset_gpio_deassert,
 50	.status = reset_gpio_status,
 51};
 52
 53static int reset_gpio_of_xlate(struct reset_controller_dev *rcdev,
 54			       const struct of_phandle_args *reset_spec)
 55{
 56	return reset_spec->args[0];
 57}
 58
 59static void reset_gpio_of_node_put(void *data)
 60{
 61	of_node_put(data);
 62}
 63
 64static int reset_gpio_probe(struct auxiliary_device *adev,
 65			    const struct auxiliary_device_id *id)
 66{
 67	struct device *dev = &adev->dev;
 68	struct of_phandle_args *platdata = dev_get_platdata(dev);
 69	struct reset_gpio_priv *priv;
 70	int ret;
 71
 72	if (!platdata)
 73		return -EINVAL;
 74
 75	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 76	if (!priv)
 77		return -ENOMEM;
 78
 79	auxiliary_set_drvdata(adev, &priv->rc);
 80
 81	priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 82	if (IS_ERR(priv->reset))
 83		return dev_err_probe(dev, PTR_ERR(priv->reset),
 84				     "Could not get reset gpios\n");
 85
 86	priv->rc.ops = &reset_gpio_ops;
 87	priv->rc.owner = THIS_MODULE;
 88	priv->rc.dev = dev;
 89	priv->rc.of_args = platdata;
 90	ret = devm_add_action_or_reset(dev, reset_gpio_of_node_put,
 91				       priv->rc.of_node);
 92	if (ret)
 93		return ret;
 94
 95	/* Cells to match GPIO specifier, but it's not really used */
 96	priv->rc.of_reset_n_cells = 2;
 97	priv->rc.of_xlate = reset_gpio_of_xlate;
 98	priv->rc.nr_resets = 1;
 99
100	return devm_reset_controller_register(dev, &priv->rc);
101}
102
103static const struct auxiliary_device_id reset_gpio_ids[] = {
104	{ .name = "reset.gpio" },
105	{}
106};
107MODULE_DEVICE_TABLE(auxiliary, reset_gpio_ids);
108
109static struct auxiliary_driver reset_gpio_driver = {
110	.probe		= reset_gpio_probe,
111	.id_table	= reset_gpio_ids,
112	.driver	= {
113		.name = "reset-gpio",
114		.suppress_bind_attrs = true,
115	},
116};
117module_auxiliary_driver(reset_gpio_driver);
118
119MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
120MODULE_DESCRIPTION("Generic GPIO reset driver");
121MODULE_LICENSE("GPL");
~/ Read-only file preview.