0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/err.h>
0011 #include <linux/io.h>
0012 #include <linux/init.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/reset-controller.h>
0017 #include <linux/reset/reset-simple.h>
0018 #include <linux/reset/sunxi.h>
0019 #include <linux/slab.h>
0020 #include <linux/spinlock.h>
0021 #include <linux/types.h>
0022
0023 static int sunxi_reset_init(struct device_node *np)
0024 {
0025 struct reset_simple_data *data;
0026 struct resource res;
0027 resource_size_t size;
0028 int ret;
0029
0030 data = kzalloc(sizeof(*data), GFP_KERNEL);
0031 if (!data)
0032 return -ENOMEM;
0033
0034 ret = of_address_to_resource(np, 0, &res);
0035 if (ret)
0036 goto err_alloc;
0037
0038 size = resource_size(&res);
0039 if (!request_mem_region(res.start, size, np->name)) {
0040 ret = -EBUSY;
0041 goto err_alloc;
0042 }
0043
0044 data->membase = ioremap(res.start, size);
0045 if (!data->membase) {
0046 ret = -ENOMEM;
0047 goto err_alloc;
0048 }
0049
0050 spin_lock_init(&data->lock);
0051
0052 data->rcdev.owner = THIS_MODULE;
0053 data->rcdev.nr_resets = size * 8;
0054 data->rcdev.ops = &reset_simple_ops;
0055 data->rcdev.of_node = np;
0056 data->active_low = true;
0057
0058 return reset_controller_register(&data->rcdev);
0059
0060 err_alloc:
0061 kfree(data);
0062 return ret;
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072 static const struct of_device_id sunxi_early_reset_dt_ids[] __initconst = {
0073 { .compatible = "allwinner,sun6i-a31-ahb1-reset", },
0074 { },
0075 };
0076
0077 void __init sun6i_reset_init(void)
0078 {
0079 struct device_node *np;
0080
0081 for_each_matching_node(np, sunxi_early_reset_dt_ids)
0082 sunxi_reset_init(np);
0083 }