Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2018, Intel Corporation
0004  * Copied from reset-sunxi.c
0005  */
0006 
0007 #include <linux/err.h>
0008 #include <linux/io.h>
0009 #include <linux/init.h>
0010 #include <linux/of.h>
0011 #include <linux/of_address.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/reset-controller.h>
0014 #include <linux/reset/reset-simple.h>
0015 #include <linux/reset/socfpga.h>
0016 #include <linux/slab.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/types.h>
0019 
0020 #define SOCFPGA_NR_BANKS    8
0021 
0022 static int a10_reset_init(struct device_node *np)
0023 {
0024     struct reset_simple_data *data;
0025     struct resource res;
0026     resource_size_t size;
0027     int ret;
0028     u32 reg_offset = 0x10;
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 release_region;
0048     }
0049 
0050     if (of_property_read_u32(np, "altr,modrst-offset", &reg_offset))
0051         pr_warn("missing altr,modrst-offset property, assuming 0x10\n");
0052     data->membase += reg_offset;
0053 
0054     spin_lock_init(&data->lock);
0055 
0056     data->rcdev.owner = THIS_MODULE;
0057     data->rcdev.nr_resets = SOCFPGA_NR_BANKS * 32;
0058     data->rcdev.ops = &reset_simple_ops;
0059     data->rcdev.of_node = np;
0060     data->status_active_low = true;
0061 
0062     ret = reset_controller_register(&data->rcdev);
0063     if (ret)
0064         pr_err("unable to register device\n");
0065 
0066     return ret;
0067 
0068 release_region:
0069     release_mem_region(res.start, size);
0070 
0071 err_alloc:
0072     kfree(data);
0073     return ret;
0074 };
0075 
0076 /*
0077  * These are the reset controller we need to initialize early on in
0078  * our system, before we can even think of using a regular device
0079  * driver for it.
0080  * The controllers that we can register through the regular device
0081  * model are handled by the simple reset driver directly.
0082  */
0083 static const struct of_device_id socfpga_early_reset_dt_ids[] __initconst = {
0084     { .compatible = "altr,rst-mgr", },
0085     { /* sentinel */ },
0086 };
0087 
0088 void __init socfpga_reset_init(void)
0089 {
0090     struct device_node *np;
0091 
0092     for_each_matching_node(np, socfpga_early_reset_dt_ids)
0093         a10_reset_init(np);
0094 }
0095 
0096 /*
0097  * The early driver is problematic, because it doesn't register
0098  * itself as a driver. This causes certain device links to prevent
0099  * consumer devices from probing. The hacky solution is to register
0100  * an empty driver, whose only job is to attach itself to the reset
0101  * manager and call probe.
0102  */
0103 static const struct of_device_id socfpga_reset_dt_ids[] = {
0104     { .compatible = "altr,rst-mgr", },
0105     { /* sentinel */ },
0106 };
0107 
0108 static int reset_simple_probe(struct platform_device *pdev)
0109 {
0110     return 0;
0111 }
0112 
0113 static struct platform_driver reset_socfpga_driver = {
0114     .probe  = reset_simple_probe,
0115     .driver = {
0116         .name       = "socfpga-reset",
0117         .of_match_table = socfpga_reset_dt_ids,
0118     },
0119 };
0120 builtin_platform_driver(reset_socfpga_driver);