xref: /linux/drivers/net/dsa/b53/b53_mmap.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
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>
22f44a9010SRob 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", &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)327*c306171dSUwe Kleine-König static void 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 
b53_mmap_shutdown(struct platform_device * pdev)3350650bf52SVladimir Oltean static void b53_mmap_shutdown(struct platform_device *pdev)
3360650bf52SVladimir Oltean {
3370650bf52SVladimir Oltean 	struct b53_device *dev = platform_get_drvdata(pdev);
3380650bf52SVladimir Oltean 
3390650bf52SVladimir Oltean 	if (dev)
3400650bf52SVladimir Oltean 		b53_switch_shutdown(dev);
3410650bf52SVladimir Oltean 
3420650bf52SVladimir Oltean 	platform_set_drvdata(pdev, NULL);
3430650bf52SVladimir Oltean }
3440650bf52SVladimir Oltean 
345967dd82fSFlorian Fainelli static const struct of_device_id b53_mmap_of_table[] = {
346260887c7SÁlvaro Fernández Rojas 	{
347260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm3384-switch",
348260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63XX_DEVICE_ID,
349260887c7SÁlvaro Fernández Rojas 	}, {
350260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm6318-switch",
351260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63268_DEVICE_ID,
352260887c7SÁlvaro Fernández Rojas 	}, {
353260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm6328-switch",
354260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63XX_DEVICE_ID,
355260887c7SÁlvaro Fernández Rojas 	}, {
356260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm6362-switch",
357260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63XX_DEVICE_ID,
358260887c7SÁlvaro Fernández Rojas 	}, {
359260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm6368-switch",
360260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63XX_DEVICE_ID,
361260887c7SÁlvaro Fernández Rojas 	}, {
362260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm63268-switch",
363260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63268_DEVICE_ID,
364260887c7SÁlvaro Fernández Rojas 	}, {
365260887c7SÁlvaro Fernández Rojas 		.compatible = "brcm,bcm63xx-switch",
366260887c7SÁlvaro Fernández Rojas 		.data = (void *)BCM63XX_DEVICE_ID,
367260887c7SÁlvaro Fernández Rojas 	}, { /* sentinel */ }
368967dd82fSFlorian Fainelli };
36903eaae52SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, b53_mmap_of_table);
370967dd82fSFlorian Fainelli 
371967dd82fSFlorian Fainelli static struct platform_driver b53_mmap_driver = {
372967dd82fSFlorian Fainelli 	.probe = b53_mmap_probe,
373*c306171dSUwe Kleine-König 	.remove_new = b53_mmap_remove,
3740650bf52SVladimir Oltean 	.shutdown = b53_mmap_shutdown,
375967dd82fSFlorian Fainelli 	.driver = {
376967dd82fSFlorian Fainelli 		.name = "b53-switch",
377967dd82fSFlorian Fainelli 		.of_match_table = b53_mmap_of_table,
378967dd82fSFlorian Fainelli 	},
379967dd82fSFlorian Fainelli };
380967dd82fSFlorian Fainelli 
381967dd82fSFlorian Fainelli module_platform_driver(b53_mmap_driver);
382967dd82fSFlorian Fainelli MODULE_AUTHOR("Jonas Gorski <jogo@openwrt.org>");
383967dd82fSFlorian Fainelli MODULE_DESCRIPTION("B53 MMAP access driver");
384967dd82fSFlorian Fainelli MODULE_LICENSE("Dual BSD/GPL");
385