1967dd82fSFlorian Fainelli /*
2967dd82fSFlorian Fainelli * B53 register access through memory mapped registers
3967dd82fSFlorian Fainelli *
4967dd82fSFlorian Fainelli * Copyright (C) 2012-2013 Jonas Gorski <jogo@openwrt.org>
5967dd82fSFlorian Fainelli *
6967dd82fSFlorian Fainelli * Permission to use, copy, modify, and/or distribute this software for any
7967dd82fSFlorian Fainelli * purpose with or without fee is hereby granted, provided that the above
8967dd82fSFlorian Fainelli * copyright notice and this permission notice appear in all copies.
9967dd82fSFlorian Fainelli *
10967dd82fSFlorian Fainelli * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11967dd82fSFlorian Fainelli * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12967dd82fSFlorian Fainelli * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13967dd82fSFlorian Fainelli * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14967dd82fSFlorian Fainelli * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15967dd82fSFlorian Fainelli * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16967dd82fSFlorian Fainelli * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17967dd82fSFlorian Fainelli */
18967dd82fSFlorian Fainelli
19a5538a77SÁlvaro Fernández Rojas #include <linux/bits.h>
20967dd82fSFlorian Fainelli #include <linux/kernel.h>
21967dd82fSFlorian Fainelli #include <linux/module.h>
22*f44a9010SRob Herring #include <linux/of.h>
23967dd82fSFlorian Fainelli #include <linux/io.h>
24967dd82fSFlorian Fainelli #include <linux/platform_device.h>
25967dd82fSFlorian Fainelli #include <linux/platform_data/b53.h>
26967dd82fSFlorian Fainelli
27967dd82fSFlorian Fainelli #include "b53_priv.h"
28967dd82fSFlorian Fainelli
29967dd82fSFlorian Fainelli struct b53_mmap_priv {
30967dd82fSFlorian Fainelli void __iomem *regs;
31967dd82fSFlorian Fainelli };
32967dd82fSFlorian Fainelli
b53_mmap_read8(struct b53_device * dev,u8 page,u8 reg,u8 * val)33967dd82fSFlorian Fainelli static int b53_mmap_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
34967dd82fSFlorian Fainelli {
35861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
36861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
37967dd82fSFlorian Fainelli
38967dd82fSFlorian Fainelli *val = readb(regs + (page << 8) + reg);
39967dd82fSFlorian Fainelli
40967dd82fSFlorian Fainelli return 0;
41967dd82fSFlorian Fainelli }
42967dd82fSFlorian Fainelli
b53_mmap_read16(struct b53_device * dev,u8 page,u8 reg,u16 * val)43967dd82fSFlorian Fainelli static int b53_mmap_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val)
44967dd82fSFlorian Fainelli {
45861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
46861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
47967dd82fSFlorian Fainelli
48967dd82fSFlorian Fainelli if (WARN_ON(reg % 2))
49967dd82fSFlorian Fainelli return -EINVAL;
50967dd82fSFlorian Fainelli
5155e7f6abSArnd Bergmann if (dev->pdata && dev->pdata->big_endian)
5255e7f6abSArnd Bergmann *val = ioread16be(regs + (page << 8) + reg);
53967dd82fSFlorian Fainelli else
54967dd82fSFlorian Fainelli *val = readw(regs + (page << 8) + reg);
55967dd82fSFlorian Fainelli
56967dd82fSFlorian Fainelli return 0;
57967dd82fSFlorian Fainelli }
58967dd82fSFlorian Fainelli
b53_mmap_read32(struct b53_device * dev,u8 page,u8 reg,u32 * val)59967dd82fSFlorian Fainelli static int b53_mmap_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val)
60967dd82fSFlorian Fainelli {
61861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
62861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
63967dd82fSFlorian Fainelli
64967dd82fSFlorian Fainelli if (WARN_ON(reg % 4))
65967dd82fSFlorian Fainelli return -EINVAL;
66967dd82fSFlorian Fainelli
6755e7f6abSArnd Bergmann if (dev->pdata && dev->pdata->big_endian)
6855e7f6abSArnd Bergmann *val = ioread32be(regs + (page << 8) + reg);
69967dd82fSFlorian Fainelli else
70967dd82fSFlorian Fainelli *val = readl(regs + (page << 8) + reg);
71967dd82fSFlorian Fainelli
72967dd82fSFlorian Fainelli return 0;
73967dd82fSFlorian Fainelli }
74967dd82fSFlorian Fainelli
b53_mmap_read48(struct b53_device * dev,u8 page,u8 reg,u64 * val)75967dd82fSFlorian Fainelli static int b53_mmap_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val)
76967dd82fSFlorian Fainelli {
77861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
78861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
795eca2914SArnd Bergmann
80967dd82fSFlorian Fainelli if (WARN_ON(reg % 2))
81967dd82fSFlorian Fainelli return -EINVAL;
82967dd82fSFlorian Fainelli
83967dd82fSFlorian Fainelli if (reg % 4) {
84967dd82fSFlorian Fainelli u16 lo;
85967dd82fSFlorian Fainelli u32 hi;
86967dd82fSFlorian Fainelli
875eca2914SArnd Bergmann if (dev->pdata && dev->pdata->big_endian) {
885eca2914SArnd Bergmann lo = ioread16be(regs + (page << 8) + reg);
895eca2914SArnd Bergmann hi = ioread32be(regs + (page << 8) + reg + 2);
905eca2914SArnd Bergmann } else {
915eca2914SArnd Bergmann lo = readw(regs + (page << 8) + reg);
925eca2914SArnd Bergmann hi = readl(regs + (page << 8) + reg + 2);
935eca2914SArnd Bergmann }
94967dd82fSFlorian Fainelli
95967dd82fSFlorian Fainelli *val = ((u64)hi << 16) | lo;
96967dd82fSFlorian Fainelli } else {
97967dd82fSFlorian Fainelli u32 lo;
98967dd82fSFlorian Fainelli u16 hi;
99967dd82fSFlorian Fainelli
1005eca2914SArnd Bergmann if (dev->pdata && dev->pdata->big_endian) {
1015eca2914SArnd Bergmann lo = ioread32be(regs + (page << 8) + reg);
1025eca2914SArnd Bergmann hi = ioread16be(regs + (page << 8) + reg + 4);
1035eca2914SArnd Bergmann } else {
1045eca2914SArnd Bergmann lo = readl(regs + (page << 8) + reg);
1055eca2914SArnd Bergmann hi = readw(regs + (page << 8) + reg + 4);
1065eca2914SArnd Bergmann }
107967dd82fSFlorian Fainelli
108967dd82fSFlorian Fainelli *val = ((u64)hi << 32) | lo;
109967dd82fSFlorian Fainelli }
110967dd82fSFlorian Fainelli
111967dd82fSFlorian Fainelli return 0;
112967dd82fSFlorian Fainelli }
113967dd82fSFlorian Fainelli
b53_mmap_read64(struct b53_device * dev,u8 page,u8 reg,u64 * val)114967dd82fSFlorian Fainelli static int b53_mmap_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val)
115967dd82fSFlorian Fainelli {
116861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
117861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
118967dd82fSFlorian Fainelli u32 hi, lo;
119967dd82fSFlorian Fainelli
120967dd82fSFlorian Fainelli if (WARN_ON(reg % 4))
121967dd82fSFlorian Fainelli return -EINVAL;
122967dd82fSFlorian Fainelli
1235eca2914SArnd Bergmann if (dev->pdata && dev->pdata->big_endian) {
1245eca2914SArnd Bergmann lo = ioread32be(regs + (page << 8) + reg);
1255eca2914SArnd Bergmann hi = ioread32be(regs + (page << 8) + reg + 4);
1265eca2914SArnd Bergmann } else {
1275eca2914SArnd Bergmann lo = readl(regs + (page << 8) + reg);
1285eca2914SArnd Bergmann hi = readl(regs + (page << 8) + reg + 4);
1295eca2914SArnd Bergmann }
130967dd82fSFlorian Fainelli
131967dd82fSFlorian Fainelli *val = ((u64)hi << 32) | lo;
132967dd82fSFlorian Fainelli
133967dd82fSFlorian Fainelli return 0;
134967dd82fSFlorian Fainelli }
135967dd82fSFlorian Fainelli
b53_mmap_write8(struct b53_device * dev,u8 page,u8 reg,u8 value)136967dd82fSFlorian Fainelli static int b53_mmap_write8(struct b53_device *dev, u8 page, u8 reg, u8 value)
137967dd82fSFlorian Fainelli {
138861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
139861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
140967dd82fSFlorian Fainelli
141967dd82fSFlorian Fainelli writeb(value, regs + (page << 8) + reg);
142967dd82fSFlorian Fainelli
143967dd82fSFlorian Fainelli return 0;
144967dd82fSFlorian Fainelli }
145967dd82fSFlorian Fainelli
b53_mmap_write16(struct b53_device * dev,u8 page,u8 reg,u16 value)146967dd82fSFlorian Fainelli static int b53_mmap_write16(struct b53_device *dev, u8 page, u8 reg,
147967dd82fSFlorian Fainelli u16 value)
148967dd82fSFlorian Fainelli {
149861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
150861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
151967dd82fSFlorian Fainelli
152967dd82fSFlorian Fainelli if (WARN_ON(reg % 2))
153967dd82fSFlorian Fainelli return -EINVAL;
154967dd82fSFlorian Fainelli
15555e7f6abSArnd Bergmann if (dev->pdata && dev->pdata->big_endian)
15655e7f6abSArnd Bergmann iowrite16be(value, regs + (page << 8) + reg);
157967dd82fSFlorian Fainelli else
158967dd82fSFlorian Fainelli writew(value, regs + (page << 8) + reg);
159967dd82fSFlorian Fainelli
160967dd82fSFlorian Fainelli return 0;
161967dd82fSFlorian Fainelli }
162967dd82fSFlorian Fainelli
b53_mmap_write32(struct b53_device * dev,u8 page,u8 reg,u32 value)163967dd82fSFlorian Fainelli static int b53_mmap_write32(struct b53_device *dev, u8 page, u8 reg,
164967dd82fSFlorian Fainelli u32 value)
165967dd82fSFlorian Fainelli {
166861690d0SFlorian Fainelli struct b53_mmap_priv *priv = dev->priv;
167861690d0SFlorian Fainelli void __iomem *regs = priv->regs;
168967dd82fSFlorian Fainelli
169967dd82fSFlorian Fainelli if (WARN_ON(reg % 4))
170967dd82fSFlorian Fainelli return -EINVAL;
171967dd82fSFlorian Fainelli
17255e7f6abSArnd Bergmann if (dev->pdata && dev->pdata->big_endian)
17355e7f6abSArnd Bergmann iowrite32be(value, regs + (page << 8) + reg);
174967dd82fSFlorian Fainelli else
175967dd82fSFlorian Fainelli writel(value, regs + (page << 8) + reg);
176967dd82fSFlorian Fainelli
177967dd82fSFlorian Fainelli return 0;
178967dd82fSFlorian Fainelli }
179967dd82fSFlorian Fainelli
b53_mmap_write48(struct b53_device * dev,u8 page,u8 reg,u64 value)180967dd82fSFlorian Fainelli static int b53_mmap_write48(struct b53_device *dev, u8 page, u8 reg,
181967dd82fSFlorian Fainelli u64 value)
182967dd82fSFlorian Fainelli {
183967dd82fSFlorian Fainelli if (WARN_ON(reg % 2))
184967dd82fSFlorian Fainelli return -EINVAL;
185967dd82fSFlorian Fainelli
186967dd82fSFlorian Fainelli if (reg % 4) {
187967dd82fSFlorian Fainelli u32 hi = (u32)(value >> 16);
188967dd82fSFlorian Fainelli u16 lo = (u16)value;
189967dd82fSFlorian Fainelli
190967dd82fSFlorian Fainelli b53_mmap_write16(dev, page, reg, lo);
191967dd82fSFlorian Fainelli b53_mmap_write32(dev, page, reg + 2, hi);
192967dd82fSFlorian Fainelli } else {
193967dd82fSFlorian Fainelli u16 hi = (u16)(value >> 32);
194967dd82fSFlorian Fainelli u32 lo = (u32)value;
195967dd82fSFlorian Fainelli
196967dd82fSFlorian Fainelli b53_mmap_write32(dev, page, reg, lo);
197967dd82fSFlorian Fainelli b53_mmap_write16(dev, page, reg + 4, hi);
198967dd82fSFlorian Fainelli }
199967dd82fSFlorian Fainelli
200967dd82fSFlorian Fainelli return 0;
201967dd82fSFlorian Fainelli }
202967dd82fSFlorian Fainelli
b53_mmap_write64(struct b53_device * dev,u8 page,u8 reg,u64 value)203967dd82fSFlorian Fainelli static int b53_mmap_write64(struct b53_device *dev, u8 page, u8 reg,
204967dd82fSFlorian Fainelli u64 value)
205967dd82fSFlorian Fainelli {
206967dd82fSFlorian Fainelli u32 hi, lo;
207967dd82fSFlorian Fainelli
208967dd82fSFlorian Fainelli hi = upper_32_bits(value);
209967dd82fSFlorian Fainelli lo = lower_32_bits(value);
210967dd82fSFlorian Fainelli
211967dd82fSFlorian Fainelli if (WARN_ON(reg % 4))
212967dd82fSFlorian Fainelli return -EINVAL;
213967dd82fSFlorian Fainelli
214967dd82fSFlorian Fainelli b53_mmap_write32(dev, page, reg, lo);
215967dd82fSFlorian Fainelli b53_mmap_write32(dev, page, reg + 4, hi);
216967dd82fSFlorian Fainelli
217967dd82fSFlorian Fainelli return 0;
218967dd82fSFlorian Fainelli }
219967dd82fSFlorian Fainelli
b53_mmap_phy_read16(struct b53_device * dev,int addr,int reg,u16 * value)22045977e58SÁlvaro Fernández Rojas static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg,
22145977e58SÁlvaro Fernández Rojas u16 *value)
22245977e58SÁlvaro Fernández Rojas {
22345977e58SÁlvaro Fernández Rojas return -EIO;
22445977e58SÁlvaro Fernández Rojas }
22545977e58SÁlvaro Fernández Rojas
b53_mmap_phy_write16(struct b53_device * dev,int addr,int reg,u16 value)22645977e58SÁlvaro Fernández Rojas static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg,
22745977e58SÁlvaro Fernández Rojas u16 value)
22845977e58SÁlvaro Fernández Rojas {
22945977e58SÁlvaro Fernández Rojas return -EIO;
23045977e58SÁlvaro Fernández Rojas }
23145977e58SÁlvaro Fernández Rojas
2320dff88d3SJulia Lawall static const struct b53_io_ops b53_mmap_ops = {
233967dd82fSFlorian Fainelli .read8 = b53_mmap_read8,
234967dd82fSFlorian Fainelli .read16 = b53_mmap_read16,
235967dd82fSFlorian Fainelli .read32 = b53_mmap_read32,
236967dd82fSFlorian Fainelli .read48 = b53_mmap_read48,
237967dd82fSFlorian Fainelli .read64 = b53_mmap_read64,
238967dd82fSFlorian Fainelli .write8 = b53_mmap_write8,
239967dd82fSFlorian Fainelli .write16 = b53_mmap_write16,
240967dd82fSFlorian Fainelli .write32 = b53_mmap_write32,
241967dd82fSFlorian Fainelli .write48 = b53_mmap_write48,
242967dd82fSFlorian Fainelli .write64 = b53_mmap_write64,
24345977e58SÁlvaro Fernández Rojas .phy_read16 = b53_mmap_phy_read16,
24445977e58SÁlvaro Fernández Rojas .phy_write16 = b53_mmap_phy_write16,
245967dd82fSFlorian Fainelli };
246967dd82fSFlorian Fainelli
b53_mmap_probe_of(struct platform_device * pdev,struct b53_platform_data ** ppdata)247a5538a77SÁlvaro Fernández Rojas static int b53_mmap_probe_of(struct platform_device *pdev,
248a5538a77SÁlvaro Fernández Rojas struct b53_platform_data **ppdata)
249a5538a77SÁlvaro Fernández Rojas {
250a5538a77SÁlvaro Fernández Rojas struct device_node *np = pdev->dev.of_node;
251a5538a77SÁlvaro Fernández Rojas struct device_node *of_ports, *of_port;
252a5538a77SÁlvaro Fernández Rojas struct device *dev = &pdev->dev;
253a5538a77SÁlvaro Fernández Rojas struct b53_platform_data *pdata;
254a5538a77SÁlvaro Fernández Rojas void __iomem *mem;
255a5538a77SÁlvaro Fernández Rojas
256a5538a77SÁlvaro Fernández Rojas mem = devm_platform_ioremap_resource(pdev, 0);
257a5538a77SÁlvaro Fernández Rojas if (IS_ERR(mem))
258a5538a77SÁlvaro Fernández Rojas return PTR_ERR(mem);
259a5538a77SÁlvaro Fernández Rojas
260a5538a77SÁlvaro Fernández Rojas pdata = devm_kzalloc(dev, sizeof(struct b53_platform_data),
261a5538a77SÁlvaro Fernández Rojas GFP_KERNEL);
262a5538a77SÁlvaro Fernández Rojas if (!pdata)
263a5538a77SÁlvaro Fernández Rojas return -ENOMEM;
264a5538a77SÁlvaro Fernández Rojas
265a5538a77SÁlvaro Fernández Rojas pdata->regs = mem;
266260887c7SÁlvaro Fernández Rojas pdata->chip_id = (u32)(unsigned long)device_get_match_data(dev);
267a5538a77SÁlvaro Fernández Rojas pdata->big_endian = of_property_read_bool(np, "big-endian");
268a5538a77SÁlvaro Fernández Rojas
269a5538a77SÁlvaro Fernández Rojas of_ports = of_get_child_by_name(np, "ports");
270a5538a77SÁlvaro Fernández Rojas if (!of_ports) {
271a5538a77SÁlvaro Fernández Rojas dev_err(dev, "no ports child node found\n");
272a5538a77SÁlvaro Fernández Rojas return -EINVAL;
273a5538a77SÁlvaro Fernández Rojas }
274a5538a77SÁlvaro Fernández Rojas
275a5538a77SÁlvaro Fernández Rojas for_each_available_child_of_node(of_ports, of_port) {
276a5538a77SÁlvaro Fernández Rojas u32 reg;
277a5538a77SÁlvaro Fernández Rojas
278a5538a77SÁlvaro Fernández Rojas if (of_property_read_u32(of_port, "reg", ®))
279a5538a77SÁlvaro Fernández Rojas continue;
280a5538a77SÁlvaro Fernández Rojas
28130796d0dSÁlvaro Fernández Rojas if (reg < B53_N_PORTS)
282a5538a77SÁlvaro Fernández Rojas pdata->enabled_ports |= BIT(reg);
283a5538a77SÁlvaro Fernández Rojas }
284a5538a77SÁlvaro Fernández Rojas
285a5538a77SÁlvaro Fernández Rojas of_node_put(of_ports);
286a5538a77SÁlvaro Fernández Rojas *ppdata = pdata;
287a5538a77SÁlvaro Fernández Rojas
288a5538a77SÁlvaro Fernández Rojas return 0;
289a5538a77SÁlvaro Fernández Rojas }
290a5538a77SÁlvaro Fernández Rojas
b53_mmap_probe(struct platform_device * pdev)291967dd82fSFlorian Fainelli static int b53_mmap_probe(struct platform_device *pdev)
292967dd82fSFlorian Fainelli {
293a5538a77SÁlvaro Fernández Rojas struct device_node *np = pdev->dev.of_node;
294967dd82fSFlorian Fainelli struct b53_platform_data *pdata = pdev->dev.platform_data;
295861690d0SFlorian Fainelli struct b53_mmap_priv *priv;
296967dd82fSFlorian Fainelli struct b53_device *dev;
297a5538a77SÁlvaro Fernández Rojas int ret;
298a5538a77SÁlvaro Fernández Rojas
299a5538a77SÁlvaro Fernández Rojas if (!pdata && np) {
300a5538a77SÁlvaro Fernández Rojas ret = b53_mmap_probe_of(pdev, &pdata);
301a5538a77SÁlvaro Fernández Rojas if (ret) {
302a5538a77SÁlvaro Fernández Rojas dev_err(&pdev->dev, "OF probe error\n");
303a5538a77SÁlvaro Fernández Rojas return ret;
304a5538a77SÁlvaro Fernández Rojas }
305a5538a77SÁlvaro Fernández Rojas }
306967dd82fSFlorian Fainelli
307967dd82fSFlorian Fainelli if (!pdata)
308967dd82fSFlorian Fainelli return -EINVAL;
309967dd82fSFlorian Fainelli
310861690d0SFlorian Fainelli priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
311861690d0SFlorian Fainelli if (!priv)
312861690d0SFlorian Fainelli return -ENOMEM;
313861690d0SFlorian Fainelli
314861690d0SFlorian Fainelli priv->regs = pdata->regs;
315861690d0SFlorian Fainelli
316861690d0SFlorian Fainelli dev = b53_switch_alloc(&pdev->dev, &b53_mmap_ops, priv);
317967dd82fSFlorian Fainelli if (!dev)
318967dd82fSFlorian Fainelli return -ENOMEM;
319967dd82fSFlorian Fainelli
320967dd82fSFlorian Fainelli dev->pdata = pdata;
321967dd82fSFlorian Fainelli
322967dd82fSFlorian Fainelli platform_set_drvdata(pdev, dev);
323967dd82fSFlorian Fainelli
324967dd82fSFlorian Fainelli return b53_switch_register(dev);
325967dd82fSFlorian Fainelli }
326967dd82fSFlorian Fainelli
b53_mmap_remove(struct platform_device * pdev)327967dd82fSFlorian Fainelli static int b53_mmap_remove(struct platform_device *pdev)
328967dd82fSFlorian Fainelli {
329967dd82fSFlorian Fainelli struct b53_device *dev = platform_get_drvdata(pdev);
330967dd82fSFlorian Fainelli
331967dd82fSFlorian Fainelli if (dev)
332967dd82fSFlorian Fainelli b53_switch_remove(dev);
333967dd82fSFlorian Fainelli
334967dd82fSFlorian Fainelli return 0;
335967dd82fSFlorian Fainelli }
336967dd82fSFlorian Fainelli
b53_mmap_shutdown(struct platform_device * pdev)3370650bf52SVladimir Oltean static void b53_mmap_shutdown(struct platform_device *pdev)
3380650bf52SVladimir Oltean {
3390650bf52SVladimir Oltean struct b53_device *dev = platform_get_drvdata(pdev);
3400650bf52SVladimir Oltean
3410650bf52SVladimir Oltean if (dev)
3420650bf52SVladimir Oltean b53_switch_shutdown(dev);
3430650bf52SVladimir Oltean
3440650bf52SVladimir Oltean platform_set_drvdata(pdev, NULL);
3450650bf52SVladimir Oltean }
3460650bf52SVladimir Oltean
347967dd82fSFlorian Fainelli static const struct of_device_id b53_mmap_of_table[] = {
348260887c7SÁlvaro Fernández Rojas {
349260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm3384-switch",
350260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63XX_DEVICE_ID,
351260887c7SÁlvaro Fernández Rojas }, {
352260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm6318-switch",
353260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63268_DEVICE_ID,
354260887c7SÁlvaro Fernández Rojas }, {
355260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm6328-switch",
356260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63XX_DEVICE_ID,
357260887c7SÁlvaro Fernández Rojas }, {
358260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm6362-switch",
359260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63XX_DEVICE_ID,
360260887c7SÁlvaro Fernández Rojas }, {
361260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm6368-switch",
362260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63XX_DEVICE_ID,
363260887c7SÁlvaro Fernández Rojas }, {
364260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm63268-switch",
365260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63268_DEVICE_ID,
366260887c7SÁlvaro Fernández Rojas }, {
367260887c7SÁlvaro Fernández Rojas .compatible = "brcm,bcm63xx-switch",
368260887c7SÁlvaro Fernández Rojas .data = (void *)BCM63XX_DEVICE_ID,
369260887c7SÁlvaro Fernández Rojas }, { /* sentinel */ }
370967dd82fSFlorian Fainelli };
37103eaae52SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, b53_mmap_of_table);
372967dd82fSFlorian Fainelli
373967dd82fSFlorian Fainelli static struct platform_driver b53_mmap_driver = {
374967dd82fSFlorian Fainelli .probe = b53_mmap_probe,
375967dd82fSFlorian Fainelli .remove = b53_mmap_remove,
3760650bf52SVladimir Oltean .shutdown = b53_mmap_shutdown,
377967dd82fSFlorian Fainelli .driver = {
378967dd82fSFlorian Fainelli .name = "b53-switch",
379967dd82fSFlorian Fainelli .of_match_table = b53_mmap_of_table,
380967dd82fSFlorian Fainelli },
381967dd82fSFlorian Fainelli };
382967dd82fSFlorian Fainelli
383967dd82fSFlorian Fainelli module_platform_driver(b53_mmap_driver);
384967dd82fSFlorian Fainelli MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
385967dd82fSFlorian Fainelli MODULE_DESCRIPTION("B53 MMAP access driver");
386967dd82fSFlorian Fainelli MODULE_LICENSE("Dual BSD/GPL");
387