1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4*4882a593Smuzhiyun * Rockchip CAN driver
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/uaccess.h>
9*4882a593Smuzhiyun #include <linux/can.h>
10*4882a593Smuzhiyun #include <linux/can/dev.h>
11*4882a593Smuzhiyun #include <linux/can/error.h>
12*4882a593Smuzhiyun #include <linux/can/led.h>
13*4882a593Smuzhiyun #include <linux/clk.h>
14*4882a593Smuzhiyun #include <linux/netdevice.h>
15*4882a593Smuzhiyun #include <linux/interrupt.h>
16*4882a593Smuzhiyun #include <linux/io.h>
17*4882a593Smuzhiyun #include <linux/of_device.h>
18*4882a593Smuzhiyun #include <linux/reset.h>
19*4882a593Smuzhiyun #include <linux/pm_runtime.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define DRV_NAME "rockchip_can"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define CAN_MODE 0x00
24*4882a593Smuzhiyun #define RESET_MODE 0
25*4882a593Smuzhiyun #define WORK_MODE BIT(0)
26*4882a593Smuzhiyun #define SELF_TEST_EN BIT(2)
27*4882a593Smuzhiyun #define MODE_AUTO_RETX BIT(10)
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define CAN_CMD 0x04
30*4882a593Smuzhiyun #define TX_REQ BIT(0)
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #define CAN_STATE 0x08
33*4882a593Smuzhiyun #define RX_BUF_FULL BIT(0)
34*4882a593Smuzhiyun #define TX_BUF_FULL BIT(1)
35*4882a593Smuzhiyun #define RX_PERIOD BIT(2)
36*4882a593Smuzhiyun #define TX_PERIOD BIT(3)
37*4882a593Smuzhiyun #define ERR_WARN BIT(4)
38*4882a593Smuzhiyun #define BUS_OFF BIT(5)
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define CAN_INT 0x0C
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define CAN_INT_MASK 0x10
43*4882a593Smuzhiyun #define RX_FINISH BIT(0)
44*4882a593Smuzhiyun #define TX_FINISH BIT(1)
45*4882a593Smuzhiyun #define ERR_WARN_INT BIT(2)
46*4882a593Smuzhiyun #define RX_BUF_OV BIT(3)
47*4882a593Smuzhiyun #define PASSIVE_ERR BIT(4)
48*4882a593Smuzhiyun #define TX_LOSTARB BIT(5)
49*4882a593Smuzhiyun #define BUS_ERR_INT BIT(6)
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /* Bit Timing Register */
52*4882a593Smuzhiyun #define CAN_BTT 0x18
53*4882a593Smuzhiyun #define MODE_3_SAMPLES BIT(16)
54*4882a593Smuzhiyun #define BT_SJW_SHIFT 14
55*4882a593Smuzhiyun #define BT_SJW_MASK GENMASK(15, 14)
56*4882a593Smuzhiyun #define BT_BRP_SHIFT 8
57*4882a593Smuzhiyun #define BT_BRP_MASK GENMASK(13, 8)
58*4882a593Smuzhiyun #define BT_TSEG2_SHIFT 4
59*4882a593Smuzhiyun #define BT_TSEG2_MASK GENMASK(6, 4)
60*4882a593Smuzhiyun #define BT_TSEG1_SHIFT 0
61*4882a593Smuzhiyun #define BT_TSEG1_MASK GENMASK(3, 0)
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define CAN_LOSTARB_CODE 0x28
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun #define CAN_ERR_CODE 0x2c
66*4882a593Smuzhiyun #define ERR_TYPE_MASK GENMASK(24, 22)
67*4882a593Smuzhiyun #define ERR_TYPE_SHIFT 22
68*4882a593Smuzhiyun #define BIT_ERR 0
69*4882a593Smuzhiyun #define STUFF_ERR 1
70*4882a593Smuzhiyun #define FORM_ERR 2
71*4882a593Smuzhiyun #define ACK_ERR 3
72*4882a593Smuzhiyun #define CRC_ERR 4
73*4882a593Smuzhiyun #define ERR_DIR_RX BIT(21)
74*4882a593Smuzhiyun #define ERR_LOC_MASK GENMASK(13, 0)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun #define CAN_RX_ERR_CNT 0x34
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun #define CAN_TX_ERR_CNT 0x38
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun #define CAN_ID 0x3c
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun #define CAN_ID_MASK 0x40
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun #define CAN_TX_FRM_INFO 0x50
85*4882a593Smuzhiyun #define CAN_EFF BIT(7)
86*4882a593Smuzhiyun #define CAN_RTR BIT(6)
87*4882a593Smuzhiyun #define CAN_DLC_MASK GENMASK(3, 0)
88*4882a593Smuzhiyun #define CAN_DLC(x) ((x) & GENMASK(3, 0))
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun #define CAN_TX_ID 0x54
91*4882a593Smuzhiyun #define CAN_TX_ID_MASK 0x1fffffff
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun #define CAN_TX_DATA1 0x58
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #define CAN_TX_DATA2 0x5c
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun #define CAN_RX_FRM_INFO 0x60
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun #define CAN_RX_ID 0x64
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun #define CAN_RX_DATA1 0x68
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun #define CAN_RX_DATA2 0x6c
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun #define CAN_RX_FILTER_MASK 0x1fffffff
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun #define CAN_VERSION 0x70
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun struct rockchip_can {
110*4882a593Smuzhiyun struct can_priv can;
111*4882a593Smuzhiyun void __iomem *base;
112*4882a593Smuzhiyun struct device *dev;
113*4882a593Smuzhiyun struct clk_bulk_data *clks;
114*4882a593Smuzhiyun int num_clks;
115*4882a593Smuzhiyun struct reset_control *reset;
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun static const struct can_bittiming_const rockchip_can_bittiming_const = {
119*4882a593Smuzhiyun .name = DRV_NAME,
120*4882a593Smuzhiyun .tseg1_min = 1,
121*4882a593Smuzhiyun .tseg1_max = 16,
122*4882a593Smuzhiyun .tseg2_min = 1,
123*4882a593Smuzhiyun .tseg2_max = 8,
124*4882a593Smuzhiyun .sjw_max = 4,
125*4882a593Smuzhiyun .brp_min = 1,
126*4882a593Smuzhiyun .brp_max = 128,
127*4882a593Smuzhiyun .brp_inc = 2,
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
rockchip_can_write_cmdreg(struct rockchip_can * rcan,u8 val)130*4882a593Smuzhiyun static void rockchip_can_write_cmdreg(struct rockchip_can *rcan, u8 val)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun writel(val, rcan->base + CAN_CMD);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
set_reset_mode(struct net_device * ndev)135*4882a593Smuzhiyun static int set_reset_mode(struct net_device *ndev)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun reset_control_assert(rcan->reset);
140*4882a593Smuzhiyun udelay(2);
141*4882a593Smuzhiyun reset_control_deassert(rcan->reset);
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun writel(0, rcan->base + CAN_MODE);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun return 0;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
set_normal_mode(struct net_device * ndev)148*4882a593Smuzhiyun static int set_normal_mode(struct net_device *ndev)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
151*4882a593Smuzhiyun u32 val;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun val = readl(rcan->base + CAN_MODE);
154*4882a593Smuzhiyun val |= WORK_MODE | MODE_AUTO_RETX;
155*4882a593Smuzhiyun writel(val, rcan->base + CAN_MODE);
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun return 0;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /* bittiming is called in reset_mode only */
rockchip_can_set_bittiming(struct net_device * ndev)161*4882a593Smuzhiyun static int rockchip_can_set_bittiming(struct net_device *ndev)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
164*4882a593Smuzhiyun struct can_bittiming *bt = &rcan->can.bittiming;
165*4882a593Smuzhiyun u32 cfg;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun cfg = ((bt->sjw - 1) << BT_SJW_SHIFT) |
168*4882a593Smuzhiyun (((bt->brp >> 1) - 1) << BT_BRP_SHIFT) |
169*4882a593Smuzhiyun ((bt->phase_seg2 - 1) << BT_TSEG2_SHIFT) |
170*4882a593Smuzhiyun ((bt->prop_seg + bt->phase_seg1 - 1));
171*4882a593Smuzhiyun if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
172*4882a593Smuzhiyun cfg |= MODE_3_SAMPLES;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun writel(cfg, rcan->base + CAN_BTT);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun netdev_dbg(ndev, "setting BITTIMING=0x%08x brp: %d bitrate:%d\n",
177*4882a593Smuzhiyun cfg, bt->brp, bt->bitrate);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun return 0;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
rockchip_can_get_berr_counter(const struct net_device * ndev,struct can_berr_counter * bec)182*4882a593Smuzhiyun static int rockchip_can_get_berr_counter(const struct net_device *ndev,
183*4882a593Smuzhiyun struct can_berr_counter *bec)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
186*4882a593Smuzhiyun int err;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun err = pm_runtime_get_sync(rcan->dev);
189*4882a593Smuzhiyun if (err < 0) {
190*4882a593Smuzhiyun netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
191*4882a593Smuzhiyun __func__, err);
192*4882a593Smuzhiyun return err;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun bec->rxerr = readl(rcan->base + CAN_RX_ERR_CNT);
196*4882a593Smuzhiyun bec->txerr = readl(rcan->base + CAN_TX_ERR_CNT);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun pm_runtime_put(rcan->dev);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
201*4882a593Smuzhiyun return 0;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
rockchip_can_start(struct net_device * ndev)204*4882a593Smuzhiyun static int rockchip_can_start(struct net_device *ndev)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* we need to enter the reset mode */
209*4882a593Smuzhiyun set_reset_mode(ndev);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun writel(0, rcan->base + CAN_INT_MASK);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun /* RECEIVING FILTER, accept all */
214*4882a593Smuzhiyun writel(0, rcan->base + CAN_ID);
215*4882a593Smuzhiyun writel(CAN_RX_FILTER_MASK, rcan->base + CAN_ID_MASK);
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun rockchip_can_set_bittiming(ndev);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun set_normal_mode(ndev);
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun rcan->can.state = CAN_STATE_ERROR_ACTIVE;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
224*4882a593Smuzhiyun return 0;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
rockchip_can_stop(struct net_device * ndev)227*4882a593Smuzhiyun static int rockchip_can_stop(struct net_device *ndev)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
230*4882a593Smuzhiyun u32 val;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun rcan->can.state = CAN_STATE_STOPPED;
233*4882a593Smuzhiyun /* we need to enter reset mode */
234*4882a593Smuzhiyun set_reset_mode(ndev);
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /* disable all interrupts */
237*4882a593Smuzhiyun val = RX_FINISH | TX_FINISH | ERR_WARN_INT |
238*4882a593Smuzhiyun RX_BUF_OV | PASSIVE_ERR | TX_LOSTARB |
239*4882a593Smuzhiyun BUS_ERR_INT;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun writel(val, rcan->base + CAN_INT_MASK);
242*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
243*4882a593Smuzhiyun return 0;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
rockchip_can_set_mode(struct net_device * ndev,enum can_mode mode)246*4882a593Smuzhiyun static int rockchip_can_set_mode(struct net_device *ndev, enum can_mode mode)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun int err;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun netdev_dbg(ndev, "can set mode: 0x%x\n", mode);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun switch (mode) {
253*4882a593Smuzhiyun case CAN_MODE_START:
254*4882a593Smuzhiyun err = rockchip_can_start(ndev);
255*4882a593Smuzhiyun if (err) {
256*4882a593Smuzhiyun netdev_err(ndev, "starting CAN controller failed!\n");
257*4882a593Smuzhiyun return err;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun if (netif_queue_stopped(ndev))
260*4882a593Smuzhiyun netif_wake_queue(ndev);
261*4882a593Smuzhiyun break;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun default:
264*4882a593Smuzhiyun return -EOPNOTSUPP;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun return 0;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /* transmit a CAN message
271*4882a593Smuzhiyun * message layout in the sk_buff should be like this:
272*4882a593Smuzhiyun * xx xx xx xx ff ll 00 11 22 33 44 55 66 77
273*4882a593Smuzhiyun * [ can_id ] [flags] [len] [can data (up to 8 bytes]
274*4882a593Smuzhiyun */
rockchip_can_start_xmit(struct sk_buff * skb,struct net_device * ndev)275*4882a593Smuzhiyun static int rockchip_can_start_xmit(struct sk_buff *skb, struct net_device *ndev)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
278*4882a593Smuzhiyun struct can_frame *cf = (struct can_frame *)skb->data;
279*4882a593Smuzhiyun canid_t id;
280*4882a593Smuzhiyun u8 dlc;
281*4882a593Smuzhiyun u32 fi;
282*4882a593Smuzhiyun u32 data1 = 0, data2 = 0;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun if (can_dropped_invalid_skb(ndev, skb))
285*4882a593Smuzhiyun return NETDEV_TX_OK;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun netif_stop_queue(ndev);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun id = cf->can_id;
290*4882a593Smuzhiyun dlc = cf->can_dlc;
291*4882a593Smuzhiyun fi = dlc;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun if (id & CAN_RTR_FLAG) {
294*4882a593Smuzhiyun fi |= CAN_RTR;
295*4882a593Smuzhiyun fi &= ~CAN_DLC_MASK;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun if (id & CAN_EFF_FLAG)
299*4882a593Smuzhiyun fi |= CAN_EFF;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun rockchip_can_write_cmdreg(rcan, 0);
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun writel(id & CAN_TX_ID_MASK, rcan->base + CAN_TX_ID);
304*4882a593Smuzhiyun if (!(id & CAN_RTR_FLAG)) {
305*4882a593Smuzhiyun data1 = le32_to_cpup((__le32 *)&cf->data[0]);
306*4882a593Smuzhiyun data2 = le32_to_cpup((__le32 *)&cf->data[4]);
307*4882a593Smuzhiyun writel(data1, rcan->base + CAN_TX_DATA1);
308*4882a593Smuzhiyun writel(data2, rcan->base + CAN_TX_DATA2);
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun writel(fi, rcan->base + CAN_TX_FRM_INFO);
312*4882a593Smuzhiyun can_put_echo_skb(skb, ndev, 0);
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun rockchip_can_write_cmdreg(rcan, TX_REQ);
315*4882a593Smuzhiyun netdev_dbg(ndev, "TX: can_id:0x%08x dlc: %d mode: 0x%08x data: 0x%08x 0x%08x\n",
316*4882a593Smuzhiyun cf->can_id, cf->can_dlc, rcan->can.ctrlmode, data1, data2);
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun return NETDEV_TX_OK;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
rockchip_can_rx(struct net_device * ndev)321*4882a593Smuzhiyun static void rockchip_can_rx(struct net_device *ndev)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
324*4882a593Smuzhiyun struct net_device_stats *stats = &ndev->stats;
325*4882a593Smuzhiyun struct can_frame *cf;
326*4882a593Smuzhiyun struct sk_buff *skb;
327*4882a593Smuzhiyun canid_t id;
328*4882a593Smuzhiyun u8 fi;
329*4882a593Smuzhiyun u32 data1 = 0, data2 = 0;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /* create zero'ed CAN frame buffer */
332*4882a593Smuzhiyun skb = alloc_can_skb(ndev, &cf);
333*4882a593Smuzhiyun if (!skb)
334*4882a593Smuzhiyun return;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun fi = readl(rcan->base + CAN_RX_FRM_INFO);
337*4882a593Smuzhiyun cf->can_dlc = get_can_dlc(fi & CAN_DLC_MASK);
338*4882a593Smuzhiyun id = readl(rcan->base + CAN_RX_ID);
339*4882a593Smuzhiyun if (fi & CAN_EFF)
340*4882a593Smuzhiyun id |= CAN_EFF_FLAG;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /* remote frame ? */
343*4882a593Smuzhiyun if (fi & CAN_RTR) {
344*4882a593Smuzhiyun id |= CAN_RTR_FLAG;
345*4882a593Smuzhiyun } else {
346*4882a593Smuzhiyun data1 = readl(rcan->base + CAN_RX_DATA1);
347*4882a593Smuzhiyun data2 = readl(rcan->base + CAN_RX_DATA2);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun cf->can_id = id;
351*4882a593Smuzhiyun *(__le32 *)(cf->data + 0) = cpu_to_le32(data1);
352*4882a593Smuzhiyun *(__le32 *)(cf->data + 4) = cpu_to_le32(data2);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun stats->rx_packets++;
355*4882a593Smuzhiyun stats->rx_bytes += cf->can_dlc;
356*4882a593Smuzhiyun netif_rx(skb);
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_RX);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun netdev_dbg(ndev, "%s can_id:0x%08x fi: 0x%08x dlc: %d data: 0x%08x 0x%08x\n",
361*4882a593Smuzhiyun __func__, cf->can_id, fi, cf->can_dlc,
362*4882a593Smuzhiyun data1, data2);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
rockchip_can_clean_rx_info(struct rockchip_can * rcan)365*4882a593Smuzhiyun static void rockchip_can_clean_rx_info(struct rockchip_can *rcan)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun readl(rcan->base + CAN_RX_FRM_INFO);
368*4882a593Smuzhiyun readl(rcan->base + CAN_RX_ID);
369*4882a593Smuzhiyun readl(rcan->base + CAN_RX_DATA1);
370*4882a593Smuzhiyun readl(rcan->base + CAN_RX_DATA2);
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
rockchip_can_err(struct net_device * ndev,u8 isr)373*4882a593Smuzhiyun static int rockchip_can_err(struct net_device *ndev, u8 isr)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
376*4882a593Smuzhiyun struct net_device_stats *stats = &ndev->stats;
377*4882a593Smuzhiyun enum can_state state = rcan->can.state;
378*4882a593Smuzhiyun enum can_state rx_state, tx_state;
379*4882a593Smuzhiyun struct can_frame *cf;
380*4882a593Smuzhiyun struct sk_buff *skb;
381*4882a593Smuzhiyun unsigned int rxerr, txerr;
382*4882a593Smuzhiyun u32 ecc, alc;
383*4882a593Smuzhiyun u32 sta_reg;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun skb = alloc_can_err_skb(ndev, &cf);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun rxerr = readl(rcan->base + CAN_RX_ERR_CNT);
388*4882a593Smuzhiyun txerr = readl(rcan->base + CAN_TX_ERR_CNT);
389*4882a593Smuzhiyun sta_reg = readl(rcan->base + CAN_STATE);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun if (skb) {
392*4882a593Smuzhiyun cf->data[6] = txerr;
393*4882a593Smuzhiyun cf->data[7] = rxerr;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun if (isr & RX_BUF_OV) {
397*4882a593Smuzhiyun /* data overrun interrupt */
398*4882a593Smuzhiyun netdev_dbg(ndev, "data overrun interrupt\n");
399*4882a593Smuzhiyun if (likely(skb)) {
400*4882a593Smuzhiyun cf->can_id |= CAN_ERR_CRTL;
401*4882a593Smuzhiyun cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun stats->rx_over_errors++;
404*4882a593Smuzhiyun stats->rx_errors++;
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /* reset the CAN IP by entering reset mode
407*4882a593Smuzhiyun * ignoring timeout error
408*4882a593Smuzhiyun */
409*4882a593Smuzhiyun set_reset_mode(ndev);
410*4882a593Smuzhiyun set_normal_mode(ndev);
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun if (isr & ERR_WARN_INT) {
414*4882a593Smuzhiyun /* error warning interrupt */
415*4882a593Smuzhiyun netdev_dbg(ndev, "error warning interrupt\n");
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun if (sta_reg & BUS_OFF)
418*4882a593Smuzhiyun state = CAN_STATE_BUS_OFF;
419*4882a593Smuzhiyun else if (sta_reg & ERR_WARN)
420*4882a593Smuzhiyun state = CAN_STATE_ERROR_WARNING;
421*4882a593Smuzhiyun else
422*4882a593Smuzhiyun state = CAN_STATE_ERROR_ACTIVE;
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun if (isr & BUS_ERR_INT) {
426*4882a593Smuzhiyun /* bus error interrupt */
427*4882a593Smuzhiyun netdev_dbg(ndev, "bus error interrupt\n");
428*4882a593Smuzhiyun rcan->can.can_stats.bus_error++;
429*4882a593Smuzhiyun stats->rx_errors++;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if (likely(skb)) {
432*4882a593Smuzhiyun ecc = readl(rcan->base + CAN_ERR_CODE);
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun switch ((ecc & ERR_TYPE_MASK) >> ERR_TYPE_SHIFT) {
437*4882a593Smuzhiyun case BIT_ERR:
438*4882a593Smuzhiyun cf->data[2] |= CAN_ERR_PROT_BIT;
439*4882a593Smuzhiyun break;
440*4882a593Smuzhiyun case FORM_ERR:
441*4882a593Smuzhiyun cf->data[2] |= CAN_ERR_PROT_FORM;
442*4882a593Smuzhiyun break;
443*4882a593Smuzhiyun case STUFF_ERR:
444*4882a593Smuzhiyun cf->data[2] |= CAN_ERR_PROT_STUFF;
445*4882a593Smuzhiyun break;
446*4882a593Smuzhiyun default:
447*4882a593Smuzhiyun cf->data[3] = ecc & ERR_LOC_MASK;
448*4882a593Smuzhiyun break;
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun /* error occurred during transmission? */
451*4882a593Smuzhiyun if ((ecc & ERR_DIR_RX) == 0)
452*4882a593Smuzhiyun cf->data[2] |= CAN_ERR_PROT_TX;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun if (isr & PASSIVE_ERR) {
457*4882a593Smuzhiyun /* error passive interrupt */
458*4882a593Smuzhiyun netdev_dbg(ndev, "error passive interrupt\n");
459*4882a593Smuzhiyun if (state == CAN_STATE_ERROR_PASSIVE)
460*4882a593Smuzhiyun state = CAN_STATE_ERROR_WARNING;
461*4882a593Smuzhiyun else
462*4882a593Smuzhiyun state = CAN_STATE_ERROR_PASSIVE;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun if (isr & TX_LOSTARB) {
465*4882a593Smuzhiyun /* arbitration lost interrupt */
466*4882a593Smuzhiyun netdev_dbg(ndev, "arbitration lost interrupt\n");
467*4882a593Smuzhiyun alc = readl(rcan->base + CAN_LOSTARB_CODE);
468*4882a593Smuzhiyun rcan->can.can_stats.arbitration_lost++;
469*4882a593Smuzhiyun stats->tx_errors++;
470*4882a593Smuzhiyun if (likely(skb)) {
471*4882a593Smuzhiyun cf->can_id |= CAN_ERR_LOSTARB;
472*4882a593Smuzhiyun cf->data[0] = alc;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun if (state != rcan->can.state) {
477*4882a593Smuzhiyun tx_state = txerr >= rxerr ? state : 0;
478*4882a593Smuzhiyun rx_state = txerr <= rxerr ? state : 0;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun if (likely(skb))
481*4882a593Smuzhiyun can_change_state(ndev, cf, tx_state, rx_state);
482*4882a593Smuzhiyun else
483*4882a593Smuzhiyun rcan->can.state = state;
484*4882a593Smuzhiyun if (state == CAN_STATE_BUS_OFF)
485*4882a593Smuzhiyun can_bus_off(ndev);
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun if (likely(skb)) {
489*4882a593Smuzhiyun stats->rx_packets++;
490*4882a593Smuzhiyun stats->rx_bytes += cf->can_dlc;
491*4882a593Smuzhiyun netif_rx(skb);
492*4882a593Smuzhiyun } else {
493*4882a593Smuzhiyun return -ENOMEM;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun return 0;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
rockchip_can_interrupt(int irq,void * dev_id)499*4882a593Smuzhiyun static irqreturn_t rockchip_can_interrupt(int irq, void *dev_id)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun struct net_device *ndev = (struct net_device *)dev_id;
502*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
503*4882a593Smuzhiyun struct net_device_stats *stats = &ndev->stats;
504*4882a593Smuzhiyun u8 err_int = ERR_WARN_INT | RX_BUF_OV | PASSIVE_ERR |
505*4882a593Smuzhiyun TX_LOSTARB | BUS_ERR_INT;
506*4882a593Smuzhiyun u8 isr;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun isr = readl(rcan->base + CAN_INT);
509*4882a593Smuzhiyun if (isr & TX_FINISH) {
510*4882a593Smuzhiyun /* transmission complete interrupt */
511*4882a593Smuzhiyun stats->tx_bytes += readl(rcan->base + CAN_TX_FRM_INFO) &
512*4882a593Smuzhiyun CAN_DLC_MASK;
513*4882a593Smuzhiyun stats->tx_packets++;
514*4882a593Smuzhiyun rockchip_can_write_cmdreg(rcan, 0);
515*4882a593Smuzhiyun can_get_echo_skb(ndev, 0);
516*4882a593Smuzhiyun netif_wake_queue(ndev);
517*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_TX);
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun if (isr & RX_FINISH)
521*4882a593Smuzhiyun rockchip_can_rx(ndev);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if (isr & err_int) {
524*4882a593Smuzhiyun rockchip_can_clean_rx_info(rcan);
525*4882a593Smuzhiyun if (rockchip_can_err(ndev, isr))
526*4882a593Smuzhiyun netdev_err(ndev, "can't allocate buffer - clearing pending interrupts\n");
527*4882a593Smuzhiyun }
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun writel(isr, rcan->base + CAN_INT);
530*4882a593Smuzhiyun rockchip_can_clean_rx_info(rcan);
531*4882a593Smuzhiyun netdev_dbg(ndev, "isr: 0x%x\n", isr);
532*4882a593Smuzhiyun return IRQ_HANDLED;
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun
rockchip_can_open(struct net_device * ndev)535*4882a593Smuzhiyun static int rockchip_can_open(struct net_device *ndev)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
538*4882a593Smuzhiyun int err;
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* common open */
541*4882a593Smuzhiyun err = open_candev(ndev);
542*4882a593Smuzhiyun if (err)
543*4882a593Smuzhiyun return err;
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun err = pm_runtime_get_sync(rcan->dev);
546*4882a593Smuzhiyun if (err < 0) {
547*4882a593Smuzhiyun netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
548*4882a593Smuzhiyun __func__, err);
549*4882a593Smuzhiyun goto exit;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun err = rockchip_can_start(ndev);
553*4882a593Smuzhiyun if (err) {
554*4882a593Smuzhiyun netdev_err(ndev, "could not start CAN peripheral\n");
555*4882a593Smuzhiyun goto exit_can_start;
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_OPEN);
559*4882a593Smuzhiyun netif_start_queue(ndev);
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
562*4882a593Smuzhiyun return 0;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun exit_can_start:
565*4882a593Smuzhiyun pm_runtime_put(rcan->dev);
566*4882a593Smuzhiyun exit:
567*4882a593Smuzhiyun close_candev(ndev);
568*4882a593Smuzhiyun return err;
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun
rockchip_can_close(struct net_device * ndev)571*4882a593Smuzhiyun static int rockchip_can_close(struct net_device *ndev)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun netif_stop_queue(ndev);
576*4882a593Smuzhiyun rockchip_can_stop(ndev);
577*4882a593Smuzhiyun close_candev(ndev);
578*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_STOP);
579*4882a593Smuzhiyun pm_runtime_put(rcan->dev);
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
582*4882a593Smuzhiyun return 0;
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun static const struct net_device_ops rockchip_can_netdev_ops = {
586*4882a593Smuzhiyun .ndo_open = rockchip_can_open,
587*4882a593Smuzhiyun .ndo_stop = rockchip_can_close,
588*4882a593Smuzhiyun .ndo_start_xmit = rockchip_can_start_xmit,
589*4882a593Smuzhiyun };
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun /**
592*4882a593Smuzhiyun * rockchip_can_suspend - Suspend method for the driver
593*4882a593Smuzhiyun * @dev: Address of the device structure
594*4882a593Smuzhiyun *
595*4882a593Smuzhiyun * Put the driver into low power mode.
596*4882a593Smuzhiyun * Return: 0 on success and failure value on error
597*4882a593Smuzhiyun */
rockchip_can_suspend(struct device * dev)598*4882a593Smuzhiyun static int __maybe_unused rockchip_can_suspend(struct device *dev)
599*4882a593Smuzhiyun {
600*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun if (netif_running(ndev)) {
603*4882a593Smuzhiyun netif_stop_queue(ndev);
604*4882a593Smuzhiyun netif_device_detach(ndev);
605*4882a593Smuzhiyun rockchip_can_stop(ndev);
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun return pm_runtime_force_suspend(dev);
609*4882a593Smuzhiyun }
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun /**
612*4882a593Smuzhiyun * rockchip_can_resume - Resume from suspend
613*4882a593Smuzhiyun * @dev: Address of the device structure
614*4882a593Smuzhiyun *
615*4882a593Smuzhiyun * Resume operation after suspend.
616*4882a593Smuzhiyun * Return: 0 on success and failure value on error
617*4882a593Smuzhiyun */
rockchip_can_resume(struct device * dev)618*4882a593Smuzhiyun static int __maybe_unused rockchip_can_resume(struct device *dev)
619*4882a593Smuzhiyun {
620*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
621*4882a593Smuzhiyun int ret;
622*4882a593Smuzhiyun
623*4882a593Smuzhiyun ret = pm_runtime_force_resume(dev);
624*4882a593Smuzhiyun if (ret) {
625*4882a593Smuzhiyun dev_err(dev, "pm_runtime_force_resume failed on resume\n");
626*4882a593Smuzhiyun return ret;
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun if (netif_running(ndev)) {
630*4882a593Smuzhiyun ret = rockchip_can_start(ndev);
631*4882a593Smuzhiyun if (ret) {
632*4882a593Smuzhiyun dev_err(dev, "rockchip_can_chip_start failed on resume\n");
633*4882a593Smuzhiyun return ret;
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun netif_device_attach(ndev);
637*4882a593Smuzhiyun netif_start_queue(ndev);
638*4882a593Smuzhiyun }
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun return 0;
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun /**
644*4882a593Smuzhiyun * rockchip_can_runtime_suspend - Runtime suspend method for the driver
645*4882a593Smuzhiyun * @dev: Address of the device structure
646*4882a593Smuzhiyun *
647*4882a593Smuzhiyun * Put the driver into low power mode.
648*4882a593Smuzhiyun * Return: 0 always
649*4882a593Smuzhiyun */
rockchip_can_runtime_suspend(struct device * dev)650*4882a593Smuzhiyun static int __maybe_unused rockchip_can_runtime_suspend(struct device *dev)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
653*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun clk_bulk_disable_unprepare(rcan->num_clks, rcan->clks);
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun return 0;
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun /**
661*4882a593Smuzhiyun * rockchip_can_runtime_resume - Runtime resume from suspend
662*4882a593Smuzhiyun * @dev: Address of the device structure
663*4882a593Smuzhiyun *
664*4882a593Smuzhiyun * Resume operation after suspend.
665*4882a593Smuzhiyun * Return: 0 on success and failure value on error
666*4882a593Smuzhiyun */
rockchip_can_runtime_resume(struct device * dev)667*4882a593Smuzhiyun static int __maybe_unused rockchip_can_runtime_resume(struct device *dev)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
670*4882a593Smuzhiyun struct rockchip_can *rcan = netdev_priv(ndev);
671*4882a593Smuzhiyun int ret;
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun ret = clk_bulk_prepare_enable(rcan->num_clks, rcan->clks);
674*4882a593Smuzhiyun if (ret) {
675*4882a593Smuzhiyun dev_err(dev, "Cannot enable clock.\n");
676*4882a593Smuzhiyun return ret;
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun return 0;
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun static const struct dev_pm_ops rockchip_can_dev_pm_ops = {
683*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(rockchip_can_suspend, rockchip_can_resume)
684*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(rockchip_can_runtime_suspend,
685*4882a593Smuzhiyun rockchip_can_runtime_resume, NULL)
686*4882a593Smuzhiyun };
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun static const struct of_device_id rockchip_can_of_match[] = {
689*4882a593Smuzhiyun {.compatible = "rockchip,can-1.0"},
690*4882a593Smuzhiyun {},
691*4882a593Smuzhiyun };
692*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rockchip_can_of_match);
693*4882a593Smuzhiyun
rockchip_can_probe(struct platform_device * pdev)694*4882a593Smuzhiyun static int rockchip_can_probe(struct platform_device *pdev)
695*4882a593Smuzhiyun {
696*4882a593Smuzhiyun struct net_device *ndev;
697*4882a593Smuzhiyun struct rockchip_can *rcan;
698*4882a593Smuzhiyun struct resource *res;
699*4882a593Smuzhiyun void __iomem *addr;
700*4882a593Smuzhiyun int err, irq;
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
703*4882a593Smuzhiyun if (irq < 0) {
704*4882a593Smuzhiyun dev_err(&pdev->dev, "could not get a valid irq\n");
705*4882a593Smuzhiyun return -ENODEV;
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
709*4882a593Smuzhiyun addr = devm_ioremap_resource(&pdev->dev, res);
710*4882a593Smuzhiyun if (IS_ERR(addr))
711*4882a593Smuzhiyun return -EBUSY;
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun ndev = alloc_candev(sizeof(struct rockchip_can), 1);
714*4882a593Smuzhiyun if (!ndev) {
715*4882a593Smuzhiyun dev_err(&pdev->dev, "could not allocate memory for CAN device\n");
716*4882a593Smuzhiyun return -ENOMEM;
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun ndev->netdev_ops = &rockchip_can_netdev_ops;
720*4882a593Smuzhiyun ndev->irq = irq;
721*4882a593Smuzhiyun ndev->flags |= IFF_ECHO;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun rcan = netdev_priv(ndev);
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun /* register interrupt handler */
726*4882a593Smuzhiyun err = devm_request_irq(&pdev->dev, ndev->irq, rockchip_can_interrupt,
727*4882a593Smuzhiyun 0, ndev->name, ndev);
728*4882a593Smuzhiyun if (err) {
729*4882a593Smuzhiyun dev_err(&pdev->dev, "request_irq err: %d\n", err);
730*4882a593Smuzhiyun return err;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun rcan->reset = devm_reset_control_array_get(&pdev->dev, false, false);
734*4882a593Smuzhiyun if (IS_ERR(rcan->reset)) {
735*4882a593Smuzhiyun if (PTR_ERR(rcan->reset) != -EPROBE_DEFER)
736*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get rcan reset lines\n");
737*4882a593Smuzhiyun return PTR_ERR(rcan->reset);
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun rcan->num_clks = devm_clk_bulk_get_all(&pdev->dev, &rcan->clks);
741*4882a593Smuzhiyun if (rcan->num_clks < 1) {
742*4882a593Smuzhiyun dev_err(&pdev->dev, "bus clock not found\n");
743*4882a593Smuzhiyun return -ENODEV;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun rcan->dev = &pdev->dev;
747*4882a593Smuzhiyun rcan->can.clock.freq = clk_get_rate(rcan->clks[0].clk);
748*4882a593Smuzhiyun rcan->can.bittiming_const = &rockchip_can_bittiming_const;
749*4882a593Smuzhiyun rcan->can.do_set_mode = rockchip_can_set_mode;
750*4882a593Smuzhiyun rcan->can.do_get_berr_counter = rockchip_can_get_berr_counter;
751*4882a593Smuzhiyun rcan->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
752*4882a593Smuzhiyun CAN_CTRLMODE_LISTENONLY |
753*4882a593Smuzhiyun CAN_CTRLMODE_LOOPBACK |
754*4882a593Smuzhiyun CAN_CTRLMODE_3_SAMPLES;
755*4882a593Smuzhiyun rcan->base = addr;
756*4882a593Smuzhiyun platform_set_drvdata(pdev, ndev);
757*4882a593Smuzhiyun SET_NETDEV_DEV(ndev, &pdev->dev);
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
760*4882a593Smuzhiyun err = pm_runtime_get_sync(&pdev->dev);
761*4882a593Smuzhiyun if (err < 0) {
762*4882a593Smuzhiyun dev_err(&pdev->dev, "%s: pm_runtime_get failed(%d)\n",
763*4882a593Smuzhiyun __func__, err);
764*4882a593Smuzhiyun goto err_pmdisable;
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun err = register_candev(ndev);
768*4882a593Smuzhiyun if (err) {
769*4882a593Smuzhiyun dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
770*4882a593Smuzhiyun DRV_NAME, err);
771*4882a593Smuzhiyun goto err_disableclks;
772*4882a593Smuzhiyun }
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun devm_can_led_init(ndev);
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun pm_runtime_put(&pdev->dev);
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun return 0;
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun err_disableclks:
781*4882a593Smuzhiyun pm_runtime_put(&pdev->dev);
782*4882a593Smuzhiyun err_pmdisable:
783*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
784*4882a593Smuzhiyun free_candev(ndev);
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun return err;
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun
rockchip_can_remove(struct platform_device * pdev)789*4882a593Smuzhiyun static int rockchip_can_remove(struct platform_device *pdev)
790*4882a593Smuzhiyun {
791*4882a593Smuzhiyun struct net_device *ndev = platform_get_drvdata(pdev);
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun unregister_netdev(ndev);
794*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
795*4882a593Smuzhiyun free_candev(ndev);
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun return 0;
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun static struct platform_driver rockchip_can_driver = {
801*4882a593Smuzhiyun .driver = {
802*4882a593Smuzhiyun .name = DRV_NAME,
803*4882a593Smuzhiyun .pm = &rockchip_can_dev_pm_ops,
804*4882a593Smuzhiyun .of_match_table = rockchip_can_of_match,
805*4882a593Smuzhiyun },
806*4882a593Smuzhiyun .probe = rockchip_can_probe,
807*4882a593Smuzhiyun .remove = rockchip_can_remove,
808*4882a593Smuzhiyun };
809*4882a593Smuzhiyun module_platform_driver(rockchip_can_driver);
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
812*4882a593Smuzhiyun MODULE_LICENSE("GPL");
813*4882a593Smuzhiyun MODULE_DESCRIPTION("Rockchip CAN Drivers");
814