Blame view
drivers/reset/reset-socfpga.c
4.15 KB
a39a49393 reset: add driver... |
1 |
/* |
02163199b reset: socfpga: m... |
2 3 |
* Socfpga Reset Controller Driver * |
a39a49393 reset: add driver... |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* Copyright 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de> * * based on * Allwinner SoCs Reset Controller driver * * Copyright 2013 Maxime Ripard * * Maxime Ripard <maxime.ripard@free-electrons.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include <linux/err.h> #include <linux/io.h> |
02163199b reset: socfpga: m... |
21 |
#include <linux/init.h> |
a39a49393 reset: add driver... |
22 23 24 25 26 |
#include <linux/of.h> #include <linux/platform_device.h> #include <linux/reset-controller.h> #include <linux/spinlock.h> #include <linux/types.h> |
d518d9cab reset-socfpga: Fi... |
27 28 |
#define BANK_INCREMENT 4 #define NR_BANKS 8 |
a39a49393 reset: add driver... |
29 30 31 32 33 34 35 36 37 38 39 40 41 |
struct socfpga_reset_data { spinlock_t lock; void __iomem *membase; struct reset_controller_dev rcdev; }; static int socfpga_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { struct socfpga_reset_data *data = container_of(rcdev, struct socfpga_reset_data, rcdev); |
f450f28e7 reset: socfpga: f... |
42 43 44 |
int reg_width = sizeof(u32); int bank = id / (reg_width * BITS_PER_BYTE); int offset = id % (reg_width * BITS_PER_BYTE); |
a39a49393 reset: add driver... |
45 46 47 48 |
unsigned long flags; u32 reg; spin_lock_irqsave(&data->lock, flags); |
d518d9cab reset-socfpga: Fi... |
49 50 |
reg = readl(data->membase + (bank * BANK_INCREMENT)); writel(reg | BIT(offset), data->membase + (bank * BANK_INCREMENT)); |
a39a49393 reset: add driver... |
51 52 53 54 55 56 57 58 59 60 61 |
spin_unlock_irqrestore(&data->lock, flags); return 0; } static int socfpga_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) { struct socfpga_reset_data *data = container_of(rcdev, struct socfpga_reset_data, rcdev); |
f450f28e7 reset: socfpga: f... |
62 63 64 |
int reg_width = sizeof(u32); int bank = id / (reg_width * BITS_PER_BYTE); int offset = id % (reg_width * BITS_PER_BYTE); |
a39a49393 reset: add driver... |
65 66 67 68 |
unsigned long flags; u32 reg; spin_lock_irqsave(&data->lock, flags); |
d518d9cab reset-socfpga: Fi... |
69 70 |
reg = readl(data->membase + (bank * BANK_INCREMENT)); writel(reg & ~BIT(offset), data->membase + (bank * BANK_INCREMENT)); |
a39a49393 reset: add driver... |
71 72 73 74 75 |
spin_unlock_irqrestore(&data->lock, flags); return 0; } |
f200890f2 reset: add socfpg... |
76 77 78 79 80 |
static int socfpga_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { struct socfpga_reset_data *data = container_of(rcdev, struct socfpga_reset_data, rcdev); |
f450f28e7 reset: socfpga: f... |
81 82 83 |
int reg_width = sizeof(u32); int bank = id / (reg_width * BITS_PER_BYTE); int offset = id % (reg_width * BITS_PER_BYTE); |
f200890f2 reset: add socfpg... |
84 |
u32 reg; |
d518d9cab reset-socfpga: Fi... |
85 |
reg = readl(data->membase + (bank * BANK_INCREMENT)); |
f200890f2 reset: add socfpg... |
86 87 88 |
return !(reg & BIT(offset)); } |
387eb3f3d reset: socfpga: M... |
89 |
static const struct reset_control_ops socfpga_reset_ops = { |
a39a49393 reset: add driver... |
90 91 |
.assert = socfpga_reset_assert, .deassert = socfpga_reset_deassert, |
f200890f2 reset: add socfpg... |
92 |
.status = socfpga_reset_status, |
a39a49393 reset: add driver... |
93 94 95 96 97 98 |
}; static int socfpga_reset_probe(struct platform_device *pdev) { struct socfpga_reset_data *data; struct resource *res; |
27e44646d reset: socfpga: U... |
99 100 |
struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; |
6b37d3e95 reset: socfpga: n... |
101 |
u32 modrst_offset; |
a39a49393 reset: add driver... |
102 103 104 105 106 107 |
/* * The binding was mainlined without the required property. * Do not continue, when we encounter an old DT. */ if (!of_find_property(pdev->dev.of_node, "#reset-cells", NULL)) { |
7799167b7 regulator: Conver... |
108 109 110 |
dev_err(&pdev->dev, "%pOF missing #reset-cells property ", pdev->dev.of_node); |
a39a49393 reset: add driver... |
111 112 113 114 115 116 117 118 119 120 121 |
return -EINVAL; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(data->membase)) return PTR_ERR(data->membase); |
6b37d3e95 reset: socfpga: n... |
122 |
if (of_property_read_u32(np, "altr,modrst-offset", &modrst_offset)) { |
27e44646d reset: socfpga: U... |
123 124 |
dev_warn(dev, "missing altr,modrst-offset property, assuming 0x10! "); |
6b37d3e95 reset: socfpga: n... |
125 |
modrst_offset = 0x10; |
27e44646d reset: socfpga: U... |
126 |
} |
6b37d3e95 reset: socfpga: n... |
127 |
data->membase += modrst_offset; |
27e44646d reset: socfpga: U... |
128 |
|
a39a49393 reset: add driver... |
129 130 131 |
spin_lock_init(&data->lock); data->rcdev.owner = THIS_MODULE; |
f450f28e7 reset: socfpga: f... |
132 |
data->rcdev.nr_resets = NR_BANKS * (sizeof(u32) * BITS_PER_BYTE); |
a39a49393 reset: add driver... |
133 134 |
data->rcdev.ops = &socfpga_reset_ops; data->rcdev.of_node = pdev->dev.of_node; |
a39a49393 reset: add driver... |
135 |
|
dc22e08ef reset: socfpga: u... |
136 |
return devm_reset_controller_register(dev, &data->rcdev); |
a39a49393 reset: add driver... |
137 138 139 140 141 142 143 144 145 |
} static const struct of_device_id socfpga_reset_dt_ids[] = { { .compatible = "altr,rst-mgr", }, { /* sentinel */ }, }; static struct platform_driver socfpga_reset_driver = { .probe = socfpga_reset_probe, |
a39a49393 reset: add driver... |
146 147 |
.driver = { .name = "socfpga-reset", |
a39a49393 reset: add driver... |
148 149 150 |
.of_match_table = socfpga_reset_dt_ids, }, }; |
02163199b reset: socfpga: m... |
151 |
builtin_platform_driver(socfpga_reset_driver); |