2 * Platform CAN bus driver for Bosch C_CAN controller
4 * Copyright (C) 2010 ST Microelectronics
5 * Bhupesh Sharma <bhupesh.sharma@st.com>
7 * Borrowed heavily from the C_CAN driver originally written by:
9 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
10 * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
12 * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
13 * Bosch C_CAN user manual can be obtained from:
14 * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
15 * users_manual_c_can.pdf
17 * This file is licensed under the terms of the GNU General Public
18 * License version 2. This program is licensed "as is" without any
19 * warranty of any kind, whether express or implied.
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/interrupt.h>
25 #include <linux/delay.h>
26 #include <linux/netdevice.h>
27 #include <linux/if_arp.h>
28 #include <linux/if_ether.h>
29 #include <linux/list.h>
31 #include <linux/platform_device.h>
32 #include <linux/clk.h>
34 #include <linux/of_device.h>
36 #include <linux/can/dev.h>
40 #define CAN_RAMINIT_START_MASK(i) (0x001 << (i))
41 #define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i))
42 #define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i))
43 static DEFINE_SPINLOCK(raminit_lock
);
45 * 16-bit c_can registers can be arranged differently in the memory
46 * architecture of different implementations. For example: 16-bit
47 * registers can be aligned to a 16-bit boundary or 32-bit boundary etc.
48 * Handle the same by providing a common read/write interface.
50 static u16
c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv
*priv
,
53 return readw(priv
->base
+ priv
->regs
[index
]);
56 static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv
*priv
,
57 enum reg index
, u16 val
)
59 writew(val
, priv
->base
+ priv
->regs
[index
]);
62 static u16
c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv
*priv
,
65 return readw(priv
->base
+ 2 * priv
->regs
[index
]);
68 static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv
*priv
,
69 enum reg index
, u16 val
)
71 writew(val
, priv
->base
+ 2 * priv
->regs
[index
]);
74 static void c_can_hw_raminit_wait(const struct c_can_priv
*priv
, u32 mask
,
77 /* We look only at the bits of our instance. */
79 while ((readl(priv
->raminit_ctrlreg
) & mask
) != val
)
83 static void c_can_hw_raminit(const struct c_can_priv
*priv
, bool enable
)
85 u32 mask
= CAN_RAMINIT_ALL_MASK(priv
->instance
);
88 spin_lock(&raminit_lock
);
90 ctrl
= readl(priv
->raminit_ctrlreg
);
91 /* We clear the done and start bit first. The start bit is
92 * looking at the 0 -> transition, but is not self clearing;
93 * And we clear the init done bit as well.
95 ctrl
&= ~CAN_RAMINIT_START_MASK(priv
->instance
);
96 ctrl
|= CAN_RAMINIT_DONE_MASK(priv
->instance
);
97 writel(ctrl
, priv
->raminit_ctrlreg
);
98 ctrl
&= ~CAN_RAMINIT_DONE_MASK(priv
->instance
);
99 c_can_hw_raminit_wait(priv
, ctrl
, mask
);
102 /* Set start bit and wait for the done bit. */
103 ctrl
|= CAN_RAMINIT_START_MASK(priv
->instance
);
104 writel(ctrl
, priv
->raminit_ctrlreg
);
105 ctrl
|= CAN_RAMINIT_DONE_MASK(priv
->instance
);
106 c_can_hw_raminit_wait(priv
, ctrl
, mask
);
108 spin_unlock(&raminit_lock
);
111 static struct platform_device_id c_can_id_table
[] = {
112 [BOSCH_C_CAN_PLATFORM
] = {
113 .name
= KBUILD_MODNAME
,
114 .driver_data
= BOSCH_C_CAN
,
118 .driver_data
= BOSCH_C_CAN
,
122 .driver_data
= BOSCH_D_CAN
,
126 MODULE_DEVICE_TABLE(platform
, c_can_id_table
);
128 static const struct of_device_id c_can_of_table
[] = {
129 { .compatible
= "bosch,c_can", .data
= &c_can_id_table
[BOSCH_C_CAN
] },
130 { .compatible
= "bosch,d_can", .data
= &c_can_id_table
[BOSCH_D_CAN
] },
133 MODULE_DEVICE_TABLE(of
, c_can_of_table
);
135 static int c_can_plat_probe(struct platform_device
*pdev
)
139 struct net_device
*dev
;
140 struct c_can_priv
*priv
;
141 const struct of_device_id
*match
;
142 const struct platform_device_id
*id
;
143 struct resource
*mem
, *res
;
147 if (pdev
->dev
.of_node
) {
148 match
= of_match_device(c_can_of_table
, &pdev
->dev
);
150 dev_err(&pdev
->dev
, "Failed to find matching dt id\n");
156 id
= platform_get_device_id(pdev
);
159 /* get the appropriate clk */
160 clk
= clk_get(&pdev
->dev
, NULL
);
162 dev_err(&pdev
->dev
, "no clock defined\n");
167 /* get the platform data */
168 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
169 irq
= platform_get_irq(pdev
, 0);
170 if (!mem
|| irq
<= 0) {
175 if (!request_mem_region(mem
->start
, resource_size(mem
),
177 dev_err(&pdev
->dev
, "resource unavailable\n");
182 addr
= ioremap(mem
->start
, resource_size(mem
));
184 dev_err(&pdev
->dev
, "failed to map can port\n");
186 goto exit_release_mem
;
189 /* allocate the c_can device */
190 dev
= alloc_c_can_dev();
196 priv
= netdev_priv(dev
);
197 switch (id
->driver_data
) {
199 priv
->regs
= reg_map_c_can
;
200 switch (mem
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
201 case IORESOURCE_MEM_32BIT
:
202 priv
->read_reg
= c_can_plat_read_reg_aligned_to_32bit
;
203 priv
->write_reg
= c_can_plat_write_reg_aligned_to_32bit
;
205 case IORESOURCE_MEM_16BIT
:
207 priv
->read_reg
= c_can_plat_read_reg_aligned_to_16bit
;
208 priv
->write_reg
= c_can_plat_write_reg_aligned_to_16bit
;
213 priv
->regs
= reg_map_d_can
;
214 priv
->can
.ctrlmode_supported
|= CAN_CTRLMODE_3_SAMPLES
;
215 priv
->read_reg
= c_can_plat_read_reg_aligned_to_16bit
;
216 priv
->write_reg
= c_can_plat_write_reg_aligned_to_16bit
;
218 if (pdev
->dev
.of_node
)
219 priv
->instance
= of_alias_get_id(pdev
->dev
.of_node
, "d_can");
221 priv
->instance
= pdev
->id
;
223 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
224 priv
->raminit_ctrlreg
= devm_ioremap_resource(&pdev
->dev
, res
);
225 if (IS_ERR(priv
->raminit_ctrlreg
) || priv
->instance
< 0)
226 dev_info(&pdev
->dev
, "control memory is not used for raminit\n");
228 priv
->raminit
= c_can_hw_raminit
;
232 goto exit_free_device
;
237 priv
->device
= &pdev
->dev
;
238 priv
->can
.clock
.freq
= clk_get_rate(clk
);
240 priv
->type
= id
->driver_data
;
242 platform_set_drvdata(pdev
, dev
);
243 SET_NETDEV_DEV(dev
, &pdev
->dev
);
245 ret
= register_c_can_dev(dev
);
247 dev_err(&pdev
->dev
, "registering %s failed (err=%d)\n",
248 KBUILD_MODNAME
, ret
);
249 goto exit_free_device
;
252 dev_info(&pdev
->dev
, "%s device registered (regs=%p, irq=%d)\n",
253 KBUILD_MODNAME
, priv
->base
, dev
->irq
);
261 release_mem_region(mem
->start
, resource_size(mem
));
265 dev_err(&pdev
->dev
, "probe failed\n");
270 static int c_can_plat_remove(struct platform_device
*pdev
)
272 struct net_device
*dev
= platform_get_drvdata(pdev
);
273 struct c_can_priv
*priv
= netdev_priv(dev
);
274 struct resource
*mem
;
276 unregister_c_can_dev(dev
);
281 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
282 release_mem_region(mem
->start
, resource_size(mem
));
290 static int c_can_suspend(struct platform_device
*pdev
, pm_message_t state
)
293 struct net_device
*ndev
= platform_get_drvdata(pdev
);
294 struct c_can_priv
*priv
= netdev_priv(ndev
);
296 if (priv
->type
!= BOSCH_D_CAN
) {
297 dev_warn(&pdev
->dev
, "Not supported\n");
301 if (netif_running(ndev
)) {
302 netif_stop_queue(ndev
);
303 netif_device_detach(ndev
);
306 ret
= c_can_power_down(ndev
);
308 netdev_err(ndev
, "failed to enter power down mode\n");
312 priv
->can
.state
= CAN_STATE_SLEEPING
;
317 static int c_can_resume(struct platform_device
*pdev
)
320 struct net_device
*ndev
= platform_get_drvdata(pdev
);
321 struct c_can_priv
*priv
= netdev_priv(ndev
);
323 if (priv
->type
!= BOSCH_D_CAN
) {
324 dev_warn(&pdev
->dev
, "Not supported\n");
328 ret
= c_can_power_up(ndev
);
330 netdev_err(ndev
, "Still in power down mode\n");
334 priv
->can
.state
= CAN_STATE_ERROR_ACTIVE
;
336 if (netif_running(ndev
)) {
337 netif_device_attach(ndev
);
338 netif_start_queue(ndev
);
344 #define c_can_suspend NULL
345 #define c_can_resume NULL
348 static struct platform_driver c_can_plat_driver
= {
350 .name
= KBUILD_MODNAME
,
351 .owner
= THIS_MODULE
,
352 .of_match_table
= c_can_of_table
,
354 .probe
= c_can_plat_probe
,
355 .remove
= c_can_plat_remove
,
356 .suspend
= c_can_suspend
,
357 .resume
= c_can_resume
,
358 .id_table
= c_can_id_table
,
361 module_platform_driver(c_can_plat_driver
);
363 MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>");
364 MODULE_LICENSE("GPL v2");
365 MODULE_DESCRIPTION("Platform CAN bus driver for Bosch C_CAN controller");