0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/err.h>
0010 #include <linux/init.h>
0011 #include <linux/of.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/reset-controller.h>
0014 #include <linux/slab.h>
0015 #include <linux/delay.h>
0016 #include <linux/types.h>
0017 #include <linux/regmap.h>
0018 #include <linux/mfd/syscon.h>
0019
0020
0021 #define RST_SET_REGOFFSET 0x34
0022 #define RST_CLR_REGOFFSET 0x38
0023
0024 struct oxnas_reset {
0025 struct regmap *regmap;
0026 struct reset_controller_dev rcdev;
0027 };
0028
0029 static int oxnas_reset_reset(struct reset_controller_dev *rcdev,
0030 unsigned long id)
0031 {
0032 struct oxnas_reset *data =
0033 container_of(rcdev, struct oxnas_reset, rcdev);
0034
0035 regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id));
0036 msleep(50);
0037 regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id));
0038
0039 return 0;
0040 }
0041
0042 static int oxnas_reset_assert(struct reset_controller_dev *rcdev,
0043 unsigned long id)
0044 {
0045 struct oxnas_reset *data =
0046 container_of(rcdev, struct oxnas_reset, rcdev);
0047
0048 regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id));
0049
0050 return 0;
0051 }
0052
0053 static int oxnas_reset_deassert(struct reset_controller_dev *rcdev,
0054 unsigned long id)
0055 {
0056 struct oxnas_reset *data =
0057 container_of(rcdev, struct oxnas_reset, rcdev);
0058
0059 regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id));
0060
0061 return 0;
0062 }
0063
0064 static const struct reset_control_ops oxnas_reset_ops = {
0065 .reset = oxnas_reset_reset,
0066 .assert = oxnas_reset_assert,
0067 .deassert = oxnas_reset_deassert,
0068 };
0069
0070 static const struct of_device_id oxnas_reset_dt_ids[] = {
0071 { .compatible = "oxsemi,ox810se-reset", },
0072 { .compatible = "oxsemi,ox820-reset", },
0073 { },
0074 };
0075
0076 static int oxnas_reset_probe(struct platform_device *pdev)
0077 {
0078 struct oxnas_reset *data;
0079 struct device *parent;
0080
0081 parent = pdev->dev.parent;
0082 if (!parent) {
0083 dev_err(&pdev->dev, "no parent\n");
0084 return -ENODEV;
0085 }
0086
0087 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
0088 if (!data)
0089 return -ENOMEM;
0090
0091 data->regmap = syscon_node_to_regmap(parent->of_node);
0092 if (IS_ERR(data->regmap)) {
0093 dev_err(&pdev->dev, "failed to get parent regmap\n");
0094 return PTR_ERR(data->regmap);
0095 }
0096
0097 platform_set_drvdata(pdev, data);
0098
0099 data->rcdev.owner = THIS_MODULE;
0100 data->rcdev.nr_resets = 32;
0101 data->rcdev.ops = &oxnas_reset_ops;
0102 data->rcdev.of_node = pdev->dev.of_node;
0103
0104 return devm_reset_controller_register(&pdev->dev, &data->rcdev);
0105 }
0106
0107 static struct platform_driver oxnas_reset_driver = {
0108 .probe = oxnas_reset_probe,
0109 .driver = {
0110 .name = "oxnas-reset",
0111 .of_match_table = oxnas_reset_dt_ids,
0112 },
0113 };
0114 builtin_platform_driver(oxnas_reset_driver);