0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/property.h>
0018 #include <linux/reset-controller.h>
0019
0020 struct tps380x_reset {
0021 struct reset_controller_dev rcdev;
0022 struct gpio_desc *reset_gpio;
0023 unsigned int reset_ms;
0024 };
0025
0026 struct tps380x_reset_devdata {
0027 unsigned int min_reset_ms;
0028 unsigned int typ_reset_ms;
0029 unsigned int max_reset_ms;
0030 };
0031
0032 static inline
0033 struct tps380x_reset *to_tps380x_reset(struct reset_controller_dev *rcdev)
0034 {
0035 return container_of(rcdev, struct tps380x_reset, rcdev);
0036 }
0037
0038 static int
0039 tps380x_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
0040 {
0041 struct tps380x_reset *tps380x = to_tps380x_reset(rcdev);
0042
0043 gpiod_set_value_cansleep(tps380x->reset_gpio, 1);
0044
0045 return 0;
0046 }
0047
0048 static int
0049 tps380x_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
0050 {
0051 struct tps380x_reset *tps380x = to_tps380x_reset(rcdev);
0052
0053 gpiod_set_value_cansleep(tps380x->reset_gpio, 0);
0054 msleep(tps380x->reset_ms);
0055
0056 return 0;
0057 }
0058
0059 static const struct reset_control_ops reset_tps380x_ops = {
0060 .assert = tps380x_reset_assert,
0061 .deassert = tps380x_reset_deassert,
0062 };
0063
0064 static int tps380x_reset_of_xlate(struct reset_controller_dev *rcdev,
0065 const struct of_phandle_args *reset_spec)
0066 {
0067
0068 return 0;
0069 }
0070
0071 static int tps380x_reset_probe(struct platform_device *pdev)
0072 {
0073 struct device *dev = &pdev->dev;
0074 const struct tps380x_reset_devdata *devdata;
0075 struct tps380x_reset *tps380x;
0076
0077 devdata = device_get_match_data(dev);
0078 if (!devdata)
0079 return -EINVAL;
0080
0081 tps380x = devm_kzalloc(dev, sizeof(*tps380x), GFP_KERNEL);
0082 if (!tps380x)
0083 return -ENOMEM;
0084
0085 tps380x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
0086 if (IS_ERR(tps380x->reset_gpio))
0087 return dev_err_probe(dev, PTR_ERR(tps380x->reset_gpio),
0088 "Failed to get GPIO\n");
0089
0090 tps380x->reset_ms = devdata->max_reset_ms;
0091
0092 tps380x->rcdev.ops = &reset_tps380x_ops;
0093 tps380x->rcdev.owner = THIS_MODULE;
0094 tps380x->rcdev.dev = dev;
0095 tps380x->rcdev.of_node = dev->of_node;
0096 tps380x->rcdev.of_reset_n_cells = 0;
0097 tps380x->rcdev.of_xlate = tps380x_reset_of_xlate;
0098 tps380x->rcdev.nr_resets = 1;
0099
0100 return devm_reset_controller_register(dev, &tps380x->rcdev);
0101 }
0102
0103 static const struct tps380x_reset_devdata tps3801_reset_data = {
0104 .min_reset_ms = 120,
0105 .typ_reset_ms = 200,
0106 .max_reset_ms = 280,
0107 };
0108
0109 static const struct of_device_id tps380x_reset_dt_ids[] = {
0110 { .compatible = "ti,tps3801", .data = &tps3801_reset_data },
0111 { },
0112 };
0113 MODULE_DEVICE_TABLE(of, tps380x_reset_dt_ids);
0114
0115 static struct platform_driver tps380x_reset_driver = {
0116 .probe = tps380x_reset_probe,
0117 .driver = {
0118 .name = "tps380x-reset",
0119 .of_match_table = tps380x_reset_dt_ids,
0120 },
0121 };
0122 module_platform_driver(tps380x_reset_driver);
0123
0124 MODULE_AUTHOR("Marco Felsch <kernel@pengutronix.de>");
0125 MODULE_DESCRIPTION("TI TPS380x Supply Voltage Supervisor and Reset Driver");
0126 MODULE_LICENSE("GPL v2");