0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/delay.h>
0012 #include <linux/io.h>
0013 #include <linux/iopoll.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/reset-controller.h>
0018 #include <linux/slab.h>
0019 #include <linux/types.h>
0020
0021 #define to_hsdk_rst(p) container_of((p), struct hsdk_rst, rcdev)
0022
0023 struct hsdk_rst {
0024 void __iomem *regs_ctl;
0025 void __iomem *regs_rst;
0026 spinlock_t lock;
0027 struct reset_controller_dev rcdev;
0028 };
0029
0030 static const u32 rst_map[] = {
0031 BIT(16),
0032 BIT(17),
0033 BIT(18),
0034 BIT(19),
0035 BIT(20),
0036 BIT(21),
0037 BIT(22),
0038 BIT(25),
0039 BIT(31),
0040 };
0041
0042 #define HSDK_MAX_RESETS ARRAY_SIZE(rst_map)
0043
0044 #define CGU_SYS_RST_CTRL 0x0
0045 #define CGU_IP_SW_RESET 0x0
0046 #define CGU_IP_SW_RESET_DELAY_SHIFT 16
0047 #define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT)
0048 #define CGU_IP_SW_RESET_DELAY 0
0049 #define CGU_IP_SW_RESET_RESET BIT(0)
0050 #define SW_RESET_TIMEOUT 10000
0051
0052 static void hsdk_reset_config(struct hsdk_rst *rst, unsigned long id)
0053 {
0054 writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL);
0055 }
0056
0057 static int hsdk_reset_do(struct hsdk_rst *rst)
0058 {
0059 u32 reg;
0060
0061 reg = readl(rst->regs_rst + CGU_IP_SW_RESET);
0062 reg &= ~CGU_IP_SW_RESET_DELAY_MASK;
0063 reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT;
0064 reg |= CGU_IP_SW_RESET_RESET;
0065 writel(reg, rst->regs_rst + CGU_IP_SW_RESET);
0066
0067
0068 return readl_poll_timeout_atomic(rst->regs_rst + CGU_IP_SW_RESET, reg,
0069 !(reg & CGU_IP_SW_RESET_RESET), 5, SW_RESET_TIMEOUT);
0070 }
0071
0072 static int hsdk_reset_reset(struct reset_controller_dev *rcdev,
0073 unsigned long id)
0074 {
0075 struct hsdk_rst *rst = to_hsdk_rst(rcdev);
0076 unsigned long flags;
0077 int ret;
0078
0079 spin_lock_irqsave(&rst->lock, flags);
0080 hsdk_reset_config(rst, id);
0081 ret = hsdk_reset_do(rst);
0082 spin_unlock_irqrestore(&rst->lock, flags);
0083
0084 return ret;
0085 }
0086
0087 static const struct reset_control_ops hsdk_reset_ops = {
0088 .reset = hsdk_reset_reset,
0089 .deassert = hsdk_reset_reset,
0090 };
0091
0092 static int hsdk_reset_probe(struct platform_device *pdev)
0093 {
0094 struct hsdk_rst *rst;
0095 struct resource *mem;
0096
0097 rst = devm_kzalloc(&pdev->dev, sizeof(*rst), GFP_KERNEL);
0098 if (!rst)
0099 return -ENOMEM;
0100
0101 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0102 rst->regs_ctl = devm_ioremap_resource(&pdev->dev, mem);
0103 if (IS_ERR(rst->regs_ctl))
0104 return PTR_ERR(rst->regs_ctl);
0105
0106 mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
0107 rst->regs_rst = devm_ioremap_resource(&pdev->dev, mem);
0108 if (IS_ERR(rst->regs_rst))
0109 return PTR_ERR(rst->regs_rst);
0110
0111 spin_lock_init(&rst->lock);
0112
0113 rst->rcdev.owner = THIS_MODULE;
0114 rst->rcdev.ops = &hsdk_reset_ops;
0115 rst->rcdev.of_node = pdev->dev.of_node;
0116 rst->rcdev.nr_resets = HSDK_MAX_RESETS;
0117 rst->rcdev.of_reset_n_cells = 1;
0118
0119 return reset_controller_register(&rst->rcdev);
0120 }
0121
0122 static const struct of_device_id hsdk_reset_dt_match[] = {
0123 { .compatible = "snps,hsdk-reset" },
0124 { },
0125 };
0126
0127 static struct platform_driver hsdk_reset_driver = {
0128 .probe = hsdk_reset_probe,
0129 .driver = {
0130 .name = "hsdk-reset",
0131 .of_match_table = hsdk_reset_dt_match,
0132 },
0133 };
0134 builtin_platform_driver(hsdk_reset_driver);
0135
0136 MODULE_AUTHOR("Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>");
0137 MODULE_DESCRIPTION("Synopsys HSDK SDP reset driver");
0138 MODULE_LICENSE("GPL v2");