1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/gpio/consumer.h>
4 #include <linux/mod_devicetable.h>
5 #include <linux/module.h>
7 #include <linux/platform_device.h>
8 #include <linux/reset-controller.h>
10 struct reset_gpio_priv
{
11 struct reset_controller_dev rc
;
12 struct gpio_desc
*reset
;
15 static inline struct reset_gpio_priv
16 *rc_to_reset_gpio(struct reset_controller_dev
*rc
)
18 return container_of(rc
, struct reset_gpio_priv
, rc
);
21 static int reset_gpio_assert(struct reset_controller_dev
*rc
, unsigned long id
)
23 struct reset_gpio_priv
*priv
= rc_to_reset_gpio(rc
);
25 gpiod_set_value_cansleep(priv
->reset
, 1);
30 static int reset_gpio_deassert(struct reset_controller_dev
*rc
,
33 struct reset_gpio_priv
*priv
= rc_to_reset_gpio(rc
);
35 gpiod_set_value_cansleep(priv
->reset
, 0);
40 static int reset_gpio_status(struct reset_controller_dev
*rc
, unsigned long id
)
42 struct reset_gpio_priv
*priv
= rc_to_reset_gpio(rc
);
44 return gpiod_get_value_cansleep(priv
->reset
);
47 static const struct reset_control_ops reset_gpio_ops
= {
48 .assert = reset_gpio_assert
,
49 .deassert
= reset_gpio_deassert
,
50 .status
= reset_gpio_status
,
53 static int reset_gpio_of_xlate(struct reset_controller_dev
*rcdev
,
54 const struct of_phandle_args
*reset_spec
)
56 return reset_spec
->args
[0];
59 static void reset_gpio_of_node_put(void *data
)
64 static int reset_gpio_probe(struct platform_device
*pdev
)
66 struct device
*dev
= &pdev
->dev
;
67 struct of_phandle_args
*platdata
= dev_get_platdata(dev
);
68 struct reset_gpio_priv
*priv
;
74 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
78 platform_set_drvdata(pdev
, &priv
->rc
);
80 priv
->reset
= devm_gpiod_get(dev
, "reset", GPIOD_OUT_HIGH
);
81 if (IS_ERR(priv
->reset
))
82 return dev_err_probe(dev
, PTR_ERR(priv
->reset
),
83 "Could not get reset gpios\n");
85 priv
->rc
.ops
= &reset_gpio_ops
;
86 priv
->rc
.owner
= THIS_MODULE
;
88 priv
->rc
.of_args
= platdata
;
89 ret
= devm_add_action_or_reset(dev
, reset_gpio_of_node_put
,
94 /* Cells to match GPIO specifier, but it's not really used */
95 priv
->rc
.of_reset_n_cells
= 2;
96 priv
->rc
.of_xlate
= reset_gpio_of_xlate
;
97 priv
->rc
.nr_resets
= 1;
99 return devm_reset_controller_register(dev
, &priv
->rc
);
102 static const struct platform_device_id reset_gpio_ids
[] = {
103 { .name
= "reset-gpio", },
106 MODULE_DEVICE_TABLE(platform
, reset_gpio_ids
);
108 static struct platform_driver reset_gpio_driver
= {
109 .probe
= reset_gpio_probe
,
110 .id_table
= reset_gpio_ids
,
112 .name
= "reset-gpio",
115 module_platform_driver(reset_gpio_driver
);
117 MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
118 MODULE_DESCRIPTION("Generic GPIO reset driver");
119 MODULE_LICENSE("GPL");