diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/net/can/mscan | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/net/can/mscan')
-rw-r--r-- | drivers/net/can/mscan/mpc5xxx_can.c | 57 | ||||
-rw-r--r-- | drivers/net/can/mscan/mscan.c | 77 | ||||
-rw-r--r-- | drivers/net/can/mscan/mscan.h | 1 |
3 files changed, 70 insertions, 65 deletions
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 668850e441d..5fedc337556 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c | |||
@@ -43,13 +43,14 @@ struct mpc5xxx_can_data { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | #ifdef CONFIG_PPC_MPC52xx | 45 | #ifdef CONFIG_PPC_MPC52xx |
46 | static struct of_device_id mpc52xx_cdm_ids[] = { | 46 | static struct of_device_id __devinitdata mpc52xx_cdm_ids[] = { |
47 | { .compatible = "fsl,mpc5200-cdm", }, | 47 | { .compatible = "fsl,mpc5200-cdm", }, |
48 | {} | 48 | {} |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, | 51 | static u32 __devinit mpc52xx_can_get_clock(struct platform_device *ofdev, |
52 | const char *clock_name, int *mscan_clksrc) | 52 | const char *clock_name, |
53 | int *mscan_clksrc) | ||
53 | { | 54 | { |
54 | unsigned int pvr; | 55 | unsigned int pvr; |
55 | struct mpc52xx_cdm __iomem *cdm; | 56 | struct mpc52xx_cdm __iomem *cdm; |
@@ -100,8 +101,9 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, | |||
100 | return freq; | 101 | return freq; |
101 | } | 102 | } |
102 | #else /* !CONFIG_PPC_MPC52xx */ | 103 | #else /* !CONFIG_PPC_MPC52xx */ |
103 | static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, | 104 | static u32 __devinit mpc52xx_can_get_clock(struct platform_device *ofdev, |
104 | const char *clock_name, int *mscan_clksrc) | 105 | const char *clock_name, |
106 | int *mscan_clksrc) | ||
105 | { | 107 | { |
106 | return 0; | 108 | return 0; |
107 | } | 109 | } |
@@ -122,13 +124,14 @@ struct mpc512x_clockctl { | |||
122 | u32 mccr[4]; /* MSCAN Clk Ctrl Reg 1-3 */ | 124 | u32 mccr[4]; /* MSCAN Clk Ctrl Reg 1-3 */ |
123 | }; | 125 | }; |
124 | 126 | ||
125 | static struct of_device_id mpc512x_clock_ids[] = { | 127 | static struct of_device_id __devinitdata mpc512x_clock_ids[] = { |
126 | { .compatible = "fsl,mpc5121-clock", }, | 128 | { .compatible = "fsl,mpc5121-clock", }, |
127 | {} | 129 | {} |
128 | }; | 130 | }; |
129 | 131 | ||
130 | static u32 mpc512x_can_get_clock(struct platform_device *ofdev, | 132 | static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, |
131 | const char *clock_name, int *mscan_clksrc) | 133 | const char *clock_name, |
134 | int *mscan_clksrc) | ||
132 | { | 135 | { |
133 | struct mpc512x_clockctl __iomem *clockctl; | 136 | struct mpc512x_clockctl __iomem *clockctl; |
134 | struct device_node *np_clock; | 137 | struct device_node *np_clock; |
@@ -178,7 +181,7 @@ static u32 mpc512x_can_get_clock(struct platform_device *ofdev, | |||
178 | 181 | ||
179 | if (!clock_name || !strcmp(clock_name, "sys")) { | 182 | if (!clock_name || !strcmp(clock_name, "sys")) { |
180 | sys_clk = clk_get(&ofdev->dev, "sys_clk"); | 183 | sys_clk = clk_get(&ofdev->dev, "sys_clk"); |
181 | if (IS_ERR(sys_clk)) { | 184 | if (!sys_clk) { |
182 | dev_err(&ofdev->dev, "couldn't get sys_clk\n"); | 185 | dev_err(&ofdev->dev, "couldn't get sys_clk\n"); |
183 | goto exit_unmap; | 186 | goto exit_unmap; |
184 | } | 187 | } |
@@ -201,7 +204,7 @@ static u32 mpc512x_can_get_clock(struct platform_device *ofdev, | |||
201 | 204 | ||
202 | if (clocksrc < 0) { | 205 | if (clocksrc < 0) { |
203 | ref_clk = clk_get(&ofdev->dev, "ref_clk"); | 206 | ref_clk = clk_get(&ofdev->dev, "ref_clk"); |
204 | if (IS_ERR(ref_clk)) { | 207 | if (!ref_clk) { |
205 | dev_err(&ofdev->dev, "couldn't get ref_clk\n"); | 208 | dev_err(&ofdev->dev, "couldn't get ref_clk\n"); |
206 | goto exit_unmap; | 209 | goto exit_unmap; |
207 | } | 210 | } |
@@ -236,18 +239,19 @@ exit_put: | |||
236 | return freq; | 239 | return freq; |
237 | } | 240 | } |
238 | #else /* !CONFIG_PPC_MPC512x */ | 241 | #else /* !CONFIG_PPC_MPC512x */ |
239 | static u32 mpc512x_can_get_clock(struct platform_device *ofdev, | 242 | static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, |
240 | const char *clock_name, int *mscan_clksrc) | 243 | const char *clock_name, |
244 | int *mscan_clksrc) | ||
241 | { | 245 | { |
242 | return 0; | 246 | return 0; |
243 | } | 247 | } |
244 | #endif /* CONFIG_PPC_MPC512x */ | 248 | #endif /* CONFIG_PPC_MPC512x */ |
245 | 249 | ||
246 | static const struct of_device_id mpc5xxx_can_table[]; | 250 | static struct of_device_id mpc5xxx_can_table[]; |
247 | static int mpc5xxx_can_probe(struct platform_device *ofdev) | 251 | static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) |
248 | { | 252 | { |
249 | const struct of_device_id *match; | 253 | const struct of_device_id *match; |
250 | const struct mpc5xxx_can_data *data; | 254 | struct mpc5xxx_can_data *data; |
251 | struct device_node *np = ofdev->dev.of_node; | 255 | struct device_node *np = ofdev->dev.of_node; |
252 | struct net_device *dev; | 256 | struct net_device *dev; |
253 | struct mscan_priv *priv; | 257 | struct mscan_priv *priv; |
@@ -319,7 +323,7 @@ exit_unmap_mem: | |||
319 | return err; | 323 | return err; |
320 | } | 324 | } |
321 | 325 | ||
322 | static int mpc5xxx_can_remove(struct platform_device *ofdev) | 326 | static int __devexit mpc5xxx_can_remove(struct platform_device *ofdev) |
323 | { | 327 | { |
324 | struct net_device *dev = dev_get_drvdata(&ofdev->dev); | 328 | struct net_device *dev = dev_get_drvdata(&ofdev->dev); |
325 | struct mscan_priv *priv = netdev_priv(dev); | 329 | struct mscan_priv *priv = netdev_priv(dev); |
@@ -376,23 +380,22 @@ static int mpc5xxx_can_resume(struct platform_device *ofdev) | |||
376 | } | 380 | } |
377 | #endif | 381 | #endif |
378 | 382 | ||
379 | static const struct mpc5xxx_can_data mpc5200_can_data = { | 383 | static struct mpc5xxx_can_data __devinitdata mpc5200_can_data = { |
380 | .type = MSCAN_TYPE_MPC5200, | 384 | .type = MSCAN_TYPE_MPC5200, |
381 | .get_clock = mpc52xx_can_get_clock, | 385 | .get_clock = mpc52xx_can_get_clock, |
382 | }; | 386 | }; |
383 | 387 | ||
384 | static const struct mpc5xxx_can_data mpc5121_can_data = { | 388 | static struct mpc5xxx_can_data __devinitdata mpc5121_can_data = { |
385 | .type = MSCAN_TYPE_MPC5121, | 389 | .type = MSCAN_TYPE_MPC5121, |
386 | .get_clock = mpc512x_can_get_clock, | 390 | .get_clock = mpc512x_can_get_clock, |
387 | }; | 391 | }; |
388 | 392 | ||
389 | static const struct of_device_id mpc5xxx_can_table[] = { | 393 | static struct of_device_id __devinitdata mpc5xxx_can_table[] = { |
390 | { .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, }, | 394 | { .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, }, |
391 | /* Note that only MPC5121 Rev. 2 (and later) is supported */ | 395 | /* Note that only MPC5121 Rev. 2 (and later) is supported */ |
392 | { .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, }, | 396 | { .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, }, |
393 | {}, | 397 | {}, |
394 | }; | 398 | }; |
395 | MODULE_DEVICE_TABLE(of, mpc5xxx_can_table); | ||
396 | 399 | ||
397 | static struct platform_driver mpc5xxx_can_driver = { | 400 | static struct platform_driver mpc5xxx_can_driver = { |
398 | .driver = { | 401 | .driver = { |
@@ -401,14 +404,24 @@ static struct platform_driver mpc5xxx_can_driver = { | |||
401 | .of_match_table = mpc5xxx_can_table, | 404 | .of_match_table = mpc5xxx_can_table, |
402 | }, | 405 | }, |
403 | .probe = mpc5xxx_can_probe, | 406 | .probe = mpc5xxx_can_probe, |
404 | .remove = mpc5xxx_can_remove, | 407 | .remove = __devexit_p(mpc5xxx_can_remove), |
405 | #ifdef CONFIG_PM | 408 | #ifdef CONFIG_PM |
406 | .suspend = mpc5xxx_can_suspend, | 409 | .suspend = mpc5xxx_can_suspend, |
407 | .resume = mpc5xxx_can_resume, | 410 | .resume = mpc5xxx_can_resume, |
408 | #endif | 411 | #endif |
409 | }; | 412 | }; |
410 | 413 | ||
411 | module_platform_driver(mpc5xxx_can_driver); | 414 | static int __init mpc5xxx_can_init(void) |
415 | { | ||
416 | return platform_driver_register(&mpc5xxx_can_driver); | ||
417 | } | ||
418 | module_init(mpc5xxx_can_init); | ||
419 | |||
420 | static void __exit mpc5xxx_can_exit(void) | ||
421 | { | ||
422 | platform_driver_unregister(&mpc5xxx_can_driver); | ||
423 | }; | ||
424 | module_exit(mpc5xxx_can_exit); | ||
412 | 425 | ||
413 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | 426 | MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); |
414 | MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver"); | 427 | MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver"); |
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index e6b40954e20..4cc6f44c2ba 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | #include "mscan.h" | 35 | #include "mscan.h" |
36 | 36 | ||
37 | static const struct can_bittiming_const mscan_bittiming_const = { | 37 | static struct can_bittiming_const mscan_bittiming_const = { |
38 | .name = "mscan", | 38 | .name = "mscan", |
39 | .tseg1_min = 4, | 39 | .tseg1_min = 4, |
40 | .tseg1_max = 16, | 40 | .tseg1_max = 16, |
@@ -62,7 +62,7 @@ static enum can_state state_map[] = { | |||
62 | static int mscan_set_mode(struct net_device *dev, u8 mode) | 62 | static int mscan_set_mode(struct net_device *dev, u8 mode) |
63 | { | 63 | { |
64 | struct mscan_priv *priv = netdev_priv(dev); | 64 | struct mscan_priv *priv = netdev_priv(dev); |
65 | struct mscan_regs __iomem *regs = priv->reg_base; | 65 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
66 | int ret = 0; | 66 | int ret = 0; |
67 | int i; | 67 | int i; |
68 | u8 canctl1; | 68 | u8 canctl1; |
@@ -95,9 +95,9 @@ static int mscan_set_mode(struct net_device *dev, u8 mode) | |||
95 | * any, at once. | 95 | * any, at once. |
96 | */ | 96 | */ |
97 | if (i >= MSCAN_SET_MODE_RETRIES) | 97 | if (i >= MSCAN_SET_MODE_RETRIES) |
98 | netdev_dbg(dev, | 98 | dev_dbg(dev->dev.parent, |
99 | "device failed to enter sleep mode. " | 99 | "device failed to enter sleep mode. " |
100 | "We proceed anyhow.\n"); | 100 | "We proceed anyhow.\n"); |
101 | else | 101 | else |
102 | priv->can.state = CAN_STATE_SLEEPING; | 102 | priv->can.state = CAN_STATE_SLEEPING; |
103 | } | 103 | } |
@@ -138,7 +138,7 @@ static int mscan_set_mode(struct net_device *dev, u8 mode) | |||
138 | static int mscan_start(struct net_device *dev) | 138 | static int mscan_start(struct net_device *dev) |
139 | { | 139 | { |
140 | struct mscan_priv *priv = netdev_priv(dev); | 140 | struct mscan_priv *priv = netdev_priv(dev); |
141 | struct mscan_regs __iomem *regs = priv->reg_base; | 141 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
142 | u8 canrflg; | 142 | u8 canrflg; |
143 | int err; | 143 | int err; |
144 | 144 | ||
@@ -178,7 +178,7 @@ static int mscan_restart(struct net_device *dev) | |||
178 | struct mscan_priv *priv = netdev_priv(dev); | 178 | struct mscan_priv *priv = netdev_priv(dev); |
179 | 179 | ||
180 | if (priv->type == MSCAN_TYPE_MPC5121) { | 180 | if (priv->type == MSCAN_TYPE_MPC5121) { |
181 | struct mscan_regs __iomem *regs = priv->reg_base; | 181 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
182 | 182 | ||
183 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 183 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
184 | WARN(!(in_8(®s->canmisc) & MSCAN_BOHOLD), | 184 | WARN(!(in_8(®s->canmisc) & MSCAN_BOHOLD), |
@@ -199,7 +199,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
199 | { | 199 | { |
200 | struct can_frame *frame = (struct can_frame *)skb->data; | 200 | struct can_frame *frame = (struct can_frame *)skb->data; |
201 | struct mscan_priv *priv = netdev_priv(dev); | 201 | struct mscan_priv *priv = netdev_priv(dev); |
202 | struct mscan_regs __iomem *regs = priv->reg_base; | 202 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
203 | int i, rtr, buf_id; | 203 | int i, rtr, buf_id; |
204 | u32 can_id; | 204 | u32 can_id; |
205 | 205 | ||
@@ -213,7 +213,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
213 | switch (hweight8(i)) { | 213 | switch (hweight8(i)) { |
214 | case 0: | 214 | case 0: |
215 | netif_stop_queue(dev); | 215 | netif_stop_queue(dev); |
216 | netdev_err(dev, "Tx Ring full when queue awake!\n"); | 216 | dev_err(dev->dev.parent, "Tx Ring full when queue awake!\n"); |
217 | return NETDEV_TX_BUSY; | 217 | return NETDEV_TX_BUSY; |
218 | case 1: | 218 | case 1: |
219 | /* | 219 | /* |
@@ -307,7 +307,7 @@ static enum can_state check_set_state(struct net_device *dev, u8 canrflg) | |||
307 | static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) | 307 | static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) |
308 | { | 308 | { |
309 | struct mscan_priv *priv = netdev_priv(dev); | 309 | struct mscan_priv *priv = netdev_priv(dev); |
310 | struct mscan_regs __iomem *regs = priv->reg_base; | 310 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
311 | u32 can_id; | 311 | u32 can_id; |
312 | int i; | 312 | int i; |
313 | 313 | ||
@@ -348,11 +348,11 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame, | |||
348 | u8 canrflg) | 348 | u8 canrflg) |
349 | { | 349 | { |
350 | struct mscan_priv *priv = netdev_priv(dev); | 350 | struct mscan_priv *priv = netdev_priv(dev); |
351 | struct mscan_regs __iomem *regs = priv->reg_base; | 351 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
352 | struct net_device_stats *stats = &dev->stats; | 352 | struct net_device_stats *stats = &dev->stats; |
353 | enum can_state old_state; | 353 | enum can_state old_state; |
354 | 354 | ||
355 | netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg); | 355 | dev_dbg(dev->dev.parent, "error interrupt (canrflg=%#x)\n", canrflg); |
356 | frame->can_id = CAN_ERR_FLAG; | 356 | frame->can_id = CAN_ERR_FLAG; |
357 | 357 | ||
358 | if (canrflg & MSCAN_OVRIF) { | 358 | if (canrflg & MSCAN_OVRIF) { |
@@ -411,7 +411,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) | |||
411 | { | 411 | { |
412 | struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi); | 412 | struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi); |
413 | struct net_device *dev = napi->dev; | 413 | struct net_device *dev = napi->dev; |
414 | struct mscan_regs __iomem *regs = priv->reg_base; | 414 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
415 | struct net_device_stats *stats = &dev->stats; | 415 | struct net_device_stats *stats = &dev->stats; |
416 | int npackets = 0; | 416 | int npackets = 0; |
417 | int ret = 1; | 417 | int ret = 1; |
@@ -427,7 +427,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) | |||
427 | skb = alloc_can_skb(dev, &frame); | 427 | skb = alloc_can_skb(dev, &frame); |
428 | if (!skb) { | 428 | if (!skb) { |
429 | if (printk_ratelimit()) | 429 | if (printk_ratelimit()) |
430 | netdev_notice(dev, "packet dropped\n"); | 430 | dev_notice(dev->dev.parent, "packet dropped\n"); |
431 | stats->rx_dropped++; | 431 | stats->rx_dropped++; |
432 | out_8(®s->canrflg, canrflg); | 432 | out_8(®s->canrflg, canrflg); |
433 | continue; | 433 | continue; |
@@ -458,7 +458,7 @@ static irqreturn_t mscan_isr(int irq, void *dev_id) | |||
458 | { | 458 | { |
459 | struct net_device *dev = (struct net_device *)dev_id; | 459 | struct net_device *dev = (struct net_device *)dev_id; |
460 | struct mscan_priv *priv = netdev_priv(dev); | 460 | struct mscan_priv *priv = netdev_priv(dev); |
461 | struct mscan_regs __iomem *regs = priv->reg_base; | 461 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
462 | struct net_device_stats *stats = &dev->stats; | 462 | struct net_device_stats *stats = &dev->stats; |
463 | u8 cantier, cantflg, canrflg; | 463 | u8 cantier, cantflg, canrflg; |
464 | irqreturn_t ret = IRQ_NONE; | 464 | irqreturn_t ret = IRQ_NONE; |
@@ -517,8 +517,12 @@ static irqreturn_t mscan_isr(int irq, void *dev_id) | |||
517 | 517 | ||
518 | static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode) | 518 | static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode) |
519 | { | 519 | { |
520 | struct mscan_priv *priv = netdev_priv(dev); | ||
520 | int ret = 0; | 521 | int ret = 0; |
521 | 522 | ||
523 | if (!priv->open_time) | ||
524 | return -EINVAL; | ||
525 | |||
522 | switch (mode) { | 526 | switch (mode) { |
523 | case CAN_MODE_START: | 527 | case CAN_MODE_START: |
524 | ret = mscan_restart(dev); | 528 | ret = mscan_restart(dev); |
@@ -538,7 +542,7 @@ static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode) | |||
538 | static int mscan_do_set_bittiming(struct net_device *dev) | 542 | static int mscan_do_set_bittiming(struct net_device *dev) |
539 | { | 543 | { |
540 | struct mscan_priv *priv = netdev_priv(dev); | 544 | struct mscan_priv *priv = netdev_priv(dev); |
541 | struct mscan_regs __iomem *regs = priv->reg_base; | 545 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
542 | struct can_bittiming *bt = &priv->can.bittiming; | 546 | struct can_bittiming *bt = &priv->can.bittiming; |
543 | u8 btr0, btr1; | 547 | u8 btr0, btr1; |
544 | 548 | ||
@@ -547,7 +551,8 @@ static int mscan_do_set_bittiming(struct net_device *dev) | |||
547 | BTR1_SET_TSEG2(bt->phase_seg2) | | 551 | BTR1_SET_TSEG2(bt->phase_seg2) | |
548 | BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)); | 552 | BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)); |
549 | 553 | ||
550 | netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); | 554 | dev_info(dev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", |
555 | btr0, btr1); | ||
551 | 556 | ||
552 | out_8(®s->canbtr0, btr0); | 557 | out_8(®s->canbtr0, btr0); |
553 | out_8(®s->canbtr1, btr1); | 558 | out_8(®s->canbtr1, btr1); |
@@ -555,23 +560,11 @@ static int mscan_do_set_bittiming(struct net_device *dev) | |||
555 | return 0; | 560 | return 0; |
556 | } | 561 | } |
557 | 562 | ||
558 | static int mscan_get_berr_counter(const struct net_device *dev, | ||
559 | struct can_berr_counter *bec) | ||
560 | { | ||
561 | struct mscan_priv *priv = netdev_priv(dev); | ||
562 | struct mscan_regs __iomem *regs = priv->reg_base; | ||
563 | |||
564 | bec->txerr = in_8(®s->cantxerr); | ||
565 | bec->rxerr = in_8(®s->canrxerr); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static int mscan_open(struct net_device *dev) | 563 | static int mscan_open(struct net_device *dev) |
571 | { | 564 | { |
572 | int ret; | 565 | int ret; |
573 | struct mscan_priv *priv = netdev_priv(dev); | 566 | struct mscan_priv *priv = netdev_priv(dev); |
574 | struct mscan_regs __iomem *regs = priv->reg_base; | 567 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
575 | 568 | ||
576 | /* common open */ | 569 | /* common open */ |
577 | ret = open_candev(dev); | 570 | ret = open_candev(dev); |
@@ -582,14 +575,13 @@ static int mscan_open(struct net_device *dev) | |||
582 | 575 | ||
583 | ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev); | 576 | ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev); |
584 | if (ret < 0) { | 577 | if (ret < 0) { |
585 | netdev_err(dev, "failed to attach interrupt\n"); | 578 | dev_err(dev->dev.parent, "failed to attach interrupt\n"); |
586 | goto exit_napi_disable; | 579 | goto exit_napi_disable; |
587 | } | 580 | } |
588 | 581 | ||
589 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) | 582 | priv->open_time = jiffies; |
590 | setbits8(®s->canctl1, MSCAN_LISTEN); | 583 | |
591 | else | 584 | clrbits8(®s->canctl1, MSCAN_LISTEN); |
592 | clrbits8(®s->canctl1, MSCAN_LISTEN); | ||
593 | 585 | ||
594 | ret = mscan_start(dev); | 586 | ret = mscan_start(dev); |
595 | if (ret) | 587 | if (ret) |
@@ -600,6 +592,7 @@ static int mscan_open(struct net_device *dev) | |||
600 | return 0; | 592 | return 0; |
601 | 593 | ||
602 | exit_free_irq: | 594 | exit_free_irq: |
595 | priv->open_time = 0; | ||
603 | free_irq(dev->irq, dev); | 596 | free_irq(dev->irq, dev); |
604 | exit_napi_disable: | 597 | exit_napi_disable: |
605 | napi_disable(&priv->napi); | 598 | napi_disable(&priv->napi); |
@@ -610,7 +603,7 @@ exit_napi_disable: | |||
610 | static int mscan_close(struct net_device *dev) | 603 | static int mscan_close(struct net_device *dev) |
611 | { | 604 | { |
612 | struct mscan_priv *priv = netdev_priv(dev); | 605 | struct mscan_priv *priv = netdev_priv(dev); |
613 | struct mscan_regs __iomem *regs = priv->reg_base; | 606 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
614 | 607 | ||
615 | netif_stop_queue(dev); | 608 | netif_stop_queue(dev); |
616 | napi_disable(&priv->napi); | 609 | napi_disable(&priv->napi); |
@@ -620,6 +613,7 @@ static int mscan_close(struct net_device *dev) | |||
620 | mscan_set_mode(dev, MSCAN_INIT_MODE); | 613 | mscan_set_mode(dev, MSCAN_INIT_MODE); |
621 | close_candev(dev); | 614 | close_candev(dev); |
622 | free_irq(dev->irq, dev); | 615 | free_irq(dev->irq, dev); |
616 | priv->open_time = 0; | ||
623 | 617 | ||
624 | return 0; | 618 | return 0; |
625 | } | 619 | } |
@@ -633,7 +627,7 @@ static const struct net_device_ops mscan_netdev_ops = { | |||
633 | int register_mscandev(struct net_device *dev, int mscan_clksrc) | 627 | int register_mscandev(struct net_device *dev, int mscan_clksrc) |
634 | { | 628 | { |
635 | struct mscan_priv *priv = netdev_priv(dev); | 629 | struct mscan_priv *priv = netdev_priv(dev); |
636 | struct mscan_regs __iomem *regs = priv->reg_base; | 630 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
637 | u8 ctl1; | 631 | u8 ctl1; |
638 | 632 | ||
639 | ctl1 = in_8(®s->canctl1); | 633 | ctl1 = in_8(®s->canctl1); |
@@ -642,10 +636,8 @@ int register_mscandev(struct net_device *dev, int mscan_clksrc) | |||
642 | else | 636 | else |
643 | ctl1 &= ~MSCAN_CLKSRC; | 637 | ctl1 &= ~MSCAN_CLKSRC; |
644 | 638 | ||
645 | if (priv->type == MSCAN_TYPE_MPC5121) { | 639 | if (priv->type == MSCAN_TYPE_MPC5121) |
646 | priv->can.do_get_berr_counter = mscan_get_berr_counter; | ||
647 | ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */ | 640 | ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */ |
648 | } | ||
649 | 641 | ||
650 | ctl1 |= MSCAN_CANE; | 642 | ctl1 |= MSCAN_CANE; |
651 | out_8(®s->canctl1, ctl1); | 643 | out_8(®s->canctl1, ctl1); |
@@ -672,7 +664,7 @@ int register_mscandev(struct net_device *dev, int mscan_clksrc) | |||
672 | void unregister_mscandev(struct net_device *dev) | 664 | void unregister_mscandev(struct net_device *dev) |
673 | { | 665 | { |
674 | struct mscan_priv *priv = netdev_priv(dev); | 666 | struct mscan_priv *priv = netdev_priv(dev); |
675 | struct mscan_regs __iomem *regs = priv->reg_base; | 667 | struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; |
676 | mscan_set_mode(dev, MSCAN_INIT_MODE); | 668 | mscan_set_mode(dev, MSCAN_INIT_MODE); |
677 | clrbits8(®s->canctl1, MSCAN_CANE); | 669 | clrbits8(®s->canctl1, MSCAN_CANE); |
678 | unregister_candev(dev); | 670 | unregister_candev(dev); |
@@ -698,8 +690,7 @@ struct net_device *alloc_mscandev(void) | |||
698 | priv->can.bittiming_const = &mscan_bittiming_const; | 690 | priv->can.bittiming_const = &mscan_bittiming_const; |
699 | priv->can.do_set_bittiming = mscan_do_set_bittiming; | 691 | priv->can.do_set_bittiming = mscan_do_set_bittiming; |
700 | priv->can.do_set_mode = mscan_do_set_mode; | 692 | priv->can.do_set_mode = mscan_do_set_mode; |
701 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | | 693 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; |
702 | CAN_CTRLMODE_LISTENONLY; | ||
703 | 694 | ||
704 | for (i = 0; i < TX_QUEUE_SIZE; i++) { | 695 | for (i = 0; i < TX_QUEUE_SIZE; i++) { |
705 | priv->tx_queue[i].id = i; | 696 | priv->tx_queue[i].id = i; |
diff --git a/drivers/net/can/mscan/mscan.h b/drivers/net/can/mscan/mscan.h index af2ed8baf0a..b43e9f5d326 100644 --- a/drivers/net/can/mscan/mscan.h +++ b/drivers/net/can/mscan/mscan.h | |||
@@ -281,6 +281,7 @@ struct tx_queue_entry { | |||
281 | struct mscan_priv { | 281 | struct mscan_priv { |
282 | struct can_priv can; /* must be the first member */ | 282 | struct can_priv can; /* must be the first member */ |
283 | unsigned int type; /* MSCAN type variants */ | 283 | unsigned int type; /* MSCAN type variants */ |
284 | long open_time; | ||
284 | unsigned long flags; | 285 | unsigned long flags; |
285 | void __iomem *reg_base; /* ioremap'ed address to registers */ | 286 | void __iomem *reg_base; /* ioremap'ed address to registers */ |
286 | u8 shadow_statflg; | 287 | u8 shadow_statflg; |