aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorWolfgang Grandegger <wg@denx.de>2010-01-07 04:43:07 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-08 04:02:18 -0500
commitbf3af54732bea5894ccc2cbde3ab566f0af7da56 (patch)
treee8e6681168c9f695006962cacfb937d3dc1bbb06 /drivers/net/can
parent2d4b6faf7d1818e9a52ae9f068ab4ffd9c3be923 (diff)
can: mscan-mpc5xxx: add support for the MPC512x processor
The main differences compared to the MSCAN on the MPC5200 are: - More flexibility in choosing the CAN source clock and frequency: Three different clock sources can be selected: "ip", "ref" or "sys". For the latter two, a clock divider can be defined as well. If the clock source is not specified by the device tree, we first try to find an optimal CAN source clock based on the system clock. If that is not possible, the reference clock will be used. - The behavior of bus-off recovery is configurable: To comply with the usual handling of Socket-CAN bus-off recovery, "recovery on request" is selected (instead of automatic recovery). Note that only MPC5121 Rev. 2 and later is supported. Signed-off-by: Wolfgang Grandegger <wg@denx.de> Reviewed-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/mscan/Kconfig7
-rw-r--r--drivers/net/can/mscan/mpc5xxx_can.c246
-rw-r--r--drivers/net/can/mscan/mscan.c51
-rw-r--r--drivers/net/can/mscan/mscan.h86
4 files changed, 295 insertions, 95 deletions
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig
index cd0f2d6f375d..27d1d398e25e 100644
--- a/drivers/net/can/mscan/Kconfig
+++ b/drivers/net/can/mscan/Kconfig
@@ -11,12 +11,13 @@ if CAN_MSCAN
11 11
12config CAN_MPC5XXX 12config CAN_MPC5XXX
13 tristate "Freescale MPC5xxx onboard CAN controller" 13 tristate "Freescale MPC5xxx onboard CAN controller"
14 depends on PPC_MPC52xx 14 depends on (PPC_MPC52xx || PPC_MPC512x)
15 ---help--- 15 ---help---
16 If you say yes here you get support for Freescale's MPC5xxx 16 If you say yes here you get support for Freescale's MPC5xxx
17 onboard CAN controller. 17 onboard CAN controller. Currently, the MPC5200, MPC5200B and
18 MPC5121 (Rev. 2 and later) are supported.
18 19
19 This driver can also be built as a module. If so, the module 20 This driver can also be built as a module. If so, the module
20 will be called mscan-mpc5xxx.ko. 21 will be called mscan-mpc5xxx.ko.
21 22
22endif 23endif
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index 1de6f6349b16..f73487f723b8 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -29,6 +29,7 @@
29#include <linux/can/dev.h> 29#include <linux/can/dev.h>
30#include <linux/of_platform.h> 30#include <linux/of_platform.h>
31#include <sysdev/fsl_soc.h> 31#include <sysdev/fsl_soc.h>
32#include <linux/clk.h>
32#include <linux/io.h> 33#include <linux/io.h>
33#include <asm/mpc52xx.h> 34#include <asm/mpc52xx.h>
34 35
@@ -36,22 +37,21 @@
36 37
37#define DRV_NAME "mpc5xxx_can" 38#define DRV_NAME "mpc5xxx_can"
38 39
39static struct of_device_id mpc52xx_cdm_ids[] __devinitdata = { 40struct mpc5xxx_can_data {
41 unsigned int type;
42 u32 (*get_clock)(struct of_device *ofdev, const char *clock_name,
43 int *mscan_clksrc);
44};
45
46#ifdef CONFIG_PPC_MPC5200
47static struct of_device_id __devinitdata mpc52xx_cdm_ids[] = {
40 { .compatible = "fsl,mpc5200-cdm", }, 48 { .compatible = "fsl,mpc5200-cdm", },
41 {} 49 {}
42}; 50};
43 51
44/* 52static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,
45 * Get frequency of the MSCAN clock source 53 const char *clock_name,
46 * 54 int *mscan_clksrc)
47 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock (IP_CLK)
48 * can be selected. According to the MPC5200 user's manual, the oscillator
49 * clock is the better choice as it has less jitter but due to a hardware
50 * bug, it can not be selected for the old MPC5200 Rev. A chips.
51 */
52
53static unsigned int __devinit mpc52xx_can_clock_freq(struct of_device *of,
54 int clock_src)
55{ 55{
56 unsigned int pvr; 56 unsigned int pvr;
57 struct mpc52xx_cdm __iomem *cdm; 57 struct mpc52xx_cdm __iomem *cdm;
@@ -61,11 +61,24 @@ static unsigned int __devinit mpc52xx_can_clock_freq(struct of_device *of,
61 61
62 pvr = mfspr(SPRN_PVR); 62 pvr = mfspr(SPRN_PVR);
63 63
64 freq = mpc5xxx_get_bus_frequency(of->node); 64 /*
65 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
66 * (IP_CLK) can be selected as MSCAN clock source. According to
67 * the MPC5200 user's manual, the oscillator clock is the better
68 * choice as it has less jitter. For this reason, it is selected
69 * by default. Unfortunately, it can not be selected for the old
70 * MPC5200 Rev. A chips due to a hardware bug (check errata).
71 */
72 if (clock_name && strcmp(clock_name, "ip") == 0)
73 *mscan_clksrc = MSCAN_CLKSRC_BUS;
74 else
75 *mscan_clksrc = MSCAN_CLKSRC_XTAL;
76
77 freq = mpc5xxx_get_bus_frequency(ofdev->node);
65 if (!freq) 78 if (!freq)
66 return 0; 79 return 0;
67 80
68 if (clock_src == MSCAN_CLKSRC_BUS || pvr == 0x80822011) 81 if (*mscan_clksrc == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
69 return freq; 82 return freq;
70 83
71 /* Determine SYS_XTAL_IN frequency from the clock domain settings */ 84 /* Determine SYS_XTAL_IN frequency from the clock domain settings */
@@ -75,7 +88,6 @@ static unsigned int __devinit mpc52xx_can_clock_freq(struct of_device *of,
75 return 0; 88 return 0;
76 } 89 }
77 cdm = of_iomap(np_cdm, 0); 90 cdm = of_iomap(np_cdm, 0);
78 of_node_put(np_cdm);
79 91
80 if (in_8(&cdm->ipb_clk_sel) & 0x1) 92 if (in_8(&cdm->ipb_clk_sel) & 0x1)
81 freq *= 2; 93 freq *= 2;
@@ -84,26 +96,174 @@ static unsigned int __devinit mpc52xx_can_clock_freq(struct of_device *of,
84 freq *= (val & (1 << 5)) ? 8 : 4; 96 freq *= (val & (1 << 5)) ? 8 : 4;
85 freq /= (val & (1 << 6)) ? 12 : 16; 97 freq /= (val & (1 << 6)) ? 12 : 16;
86 98
99 of_node_put(np_cdm);
87 iounmap(cdm); 100 iounmap(cdm);
88 101
89 return freq; 102 return freq;
90} 103}
104#else /* !CONFIG_PPC_MPC5200 */
105static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev,
106 const char *clock_name,
107 int *mscan_clksrc)
108{
109 return 0;
110}
111#endif /* CONFIG_PPC_MPC5200 */
112
113#ifdef CONFIG_PPC_MPC512x
114struct mpc512x_clockctl {
115 u32 spmr; /* System PLL Mode Reg */
116 u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
117 u32 scfr1; /* System Clk Freq Reg 1 */
118 u32 scfr2; /* System Clk Freq Reg 2 */
119 u32 reserved;
120 u32 bcr; /* Bread Crumb Reg */
121 u32 pccr[12]; /* PSC Clk Ctrl Reg 0-11 */
122 u32 spccr; /* SPDIF Clk Ctrl Reg */
123 u32 cccr; /* CFM Clk Ctrl Reg */
124 u32 dccr; /* DIU Clk Cnfg Reg */
125 u32 mccr[4]; /* MSCAN Clk Ctrl Reg 1-3 */
126};
127
128static struct of_device_id __devinitdata mpc512x_clock_ids[] = {
129 { .compatible = "fsl,mpc5121-clock", },
130 {}
131};
132
133static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
134 const char *clock_name,
135 int *mscan_clksrc)
136{
137 struct mpc512x_clockctl __iomem *clockctl;
138 struct device_node *np_clock;
139 struct clk *sys_clk, *ref_clk;
140 int plen, clockidx, clocksrc = -1;
141 u32 sys_freq, val, clockdiv = 1, freq = 0;
142 const u32 *pval;
143
144 np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
145 if (!np_clock) {
146 dev_err(&ofdev->dev, "couldn't find clock node\n");
147 return -ENODEV;
148 }
149 clockctl = of_iomap(np_clock, 0);
150 if (!clockctl) {
151 dev_err(&ofdev->dev, "couldn't map clock registers\n");
152 return 0;
153 }
154
155 /* Determine the MSCAN device index from the physical address */
156 pval = of_get_property(ofdev->node, "reg", &plen);
157 BUG_ON(!pval || plen < sizeof(*pval));
158 clockidx = (*pval & 0x80) ? 1 : 0;
159 if (*pval & 0x2000)
160 clockidx += 2;
161
162 /*
163 * Clock source and divider selection: 3 different clock sources
164 * can be selected: "ip", "ref" or "sys". For the latter two, a
165 * clock divider can be defined as well. If the clock source is
166 * not specified by the device tree, we first try to find an
167 * optimal CAN source clock based on the system clock. If that
168 * is not posslible, the reference clock will be used.
169 */
170 if (clock_name && !strcmp(clock_name, "ip")) {
171 *mscan_clksrc = MSCAN_CLKSRC_IPS;
172 freq = mpc5xxx_get_bus_frequency(ofdev->node);
173 } else {
174 *mscan_clksrc = MSCAN_CLKSRC_BUS;
175
176 pval = of_get_property(ofdev->node,
177 "fsl,mscan-clock-divider", &plen);
178 if (pval && plen == sizeof(*pval))
179 clockdiv = *pval;
180 if (!clockdiv)
181 clockdiv = 1;
182
183 if (!clock_name || !strcmp(clock_name, "sys")) {
184 sys_clk = clk_get(&ofdev->dev, "sys_clk");
185 if (!sys_clk) {
186 dev_err(&ofdev->dev, "couldn't get sys_clk\n");
187 goto exit_unmap;
188 }
189 /* Get and round up/down sys clock rate */
190 sys_freq = 1000000 *
191 ((clk_get_rate(sys_clk) + 499999) / 1000000);
192
193 if (!clock_name) {
194 /* A multiple of 16 MHz would be optimal */
195 if ((sys_freq % 16000000) == 0) {
196 clocksrc = 0;
197 clockdiv = sys_freq / 16000000;
198 freq = sys_freq / clockdiv;
199 }
200 } else {
201 clocksrc = 0;
202 freq = sys_freq / clockdiv;
203 }
204 }
205
206 if (clocksrc < 0) {
207 ref_clk = clk_get(&ofdev->dev, "ref_clk");
208 if (!ref_clk) {
209 dev_err(&ofdev->dev, "couldn't get ref_clk\n");
210 goto exit_unmap;
211 }
212 clocksrc = 1;
213 freq = clk_get_rate(ref_clk) / clockdiv;
214 }
215 }
216
217 /* Disable clock */
218 out_be32(&clockctl->mccr[clockidx], 0x0);
219 if (clocksrc >= 0) {
220 /* Set source and divider */
221 val = (clocksrc << 14) | ((clockdiv - 1) << 17);
222 out_be32(&clockctl->mccr[clockidx], val);
223 /* Enable clock */
224 out_be32(&clockctl->mccr[clockidx], val | 0x10000);
225 }
226
227 /* Enable MSCAN clock domain */
228 val = in_be32(&clockctl->sccr[1]);
229 if (!(val & (1 << 25)))
230 out_be32(&clockctl->sccr[1], val | (1 << 25));
231
232 dev_dbg(&ofdev->dev, "using '%s' with frequency divider %d\n",
233 *mscan_clksrc == MSCAN_CLKSRC_IPS ? "ips_clk" :
234 clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
235
236exit_unmap:
237 of_node_put(np_clock);
238 iounmap(clockctl);
239
240 return freq;
241}
242#else /* !CONFIG_PPC_MPC512x */
243static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev,
244 const char *clock_name,
245 int *mscan_clksrc)
246{
247 return 0;
248}
249#endif /* CONFIG_PPC_MPC512x */
91 250
92static int __devinit mpc5xxx_can_probe(struct of_device *ofdev, 251static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
93 const struct of_device_id *id) 252 const struct of_device_id *id)
94{ 253{
254 struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data;
95 struct device_node *np = ofdev->node; 255 struct device_node *np = ofdev->node;
96 struct net_device *dev; 256 struct net_device *dev;
97 struct mscan_priv *priv; 257 struct mscan_priv *priv;
98 void __iomem *base; 258 void __iomem *base;
99 const char *clk_src; 259 const char *clock_name = NULL;
100 int err, irq, clock_src; 260 int irq, mscan_clksrc = 0;
261 int err = -ENOMEM;
101 262
102 base = of_iomap(ofdev->node, 0); 263 base = of_iomap(np, 0);
103 if (!base) { 264 if (!base) {
104 dev_err(&ofdev->dev, "couldn't ioremap\n"); 265 dev_err(&ofdev->dev, "couldn't ioremap\n");
105 err = -ENOMEM; 266 return err;
106 goto exit_release_mem;
107 } 267 }
108 268
109 irq = irq_of_parse_and_map(np, 0); 269 irq = irq_of_parse_and_map(np, 0);
@@ -114,37 +274,27 @@ static int __devinit mpc5xxx_can_probe(struct of_device *ofdev,
114 } 274 }
115 275
116 dev = alloc_mscandev(); 276 dev = alloc_mscandev();
117 if (!dev) { 277 if (!dev)
118 err = -ENOMEM;
119 goto exit_dispose_irq; 278 goto exit_dispose_irq;
120 }
121 279
122 priv = netdev_priv(dev); 280 priv = netdev_priv(dev);
123 priv->reg_base = base; 281 priv->reg_base = base;
124 dev->irq = irq; 282 dev->irq = irq;
125 283
126 /* 284 clock_name = of_get_property(np, "fsl,mscan-clock-source", NULL);
127 * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock 285
128 * (IP_CLK) can be selected as MSCAN clock source. According to 286 BUG_ON(!data);
129 * the MPC5200 user's manual, the oscillator clock is the better 287 priv->type = data->type;
130 * choice as it has less jitter. For this reason, it is selected 288 priv->can.clock.freq = data->get_clock(ofdev, clock_name,
131 * by default. 289 &mscan_clksrc);
132 */
133 clk_src = of_get_property(np, "fsl,mscan-clock-source", NULL);
134 if (clk_src && strcmp(clk_src, "ip") == 0)
135 clock_src = MSCAN_CLKSRC_BUS;
136 else
137 clock_src = MSCAN_CLKSRC_XTAL;
138 priv->can.clock.freq = mpc52xx_can_clock_freq(ofdev, clock_src);
139 if (!priv->can.clock.freq) { 290 if (!priv->can.clock.freq) {
140 dev_err(&ofdev->dev, "couldn't get MSCAN clock frequency\n"); 291 dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
141 err = -ENODEV;
142 goto exit_free_mscan; 292 goto exit_free_mscan;
143 } 293 }
144 294
145 SET_NETDEV_DEV(dev, &ofdev->dev); 295 SET_NETDEV_DEV(dev, &ofdev->dev);
146 296
147 err = register_mscandev(dev, clock_src); 297 err = register_mscandev(dev, mscan_clksrc);
148 if (err) { 298 if (err) {
149 dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", 299 dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
150 DRV_NAME, err); 300 DRV_NAME, err);
@@ -164,7 +314,7 @@ exit_dispose_irq:
164 irq_dispose_mapping(irq); 314 irq_dispose_mapping(irq);
165exit_unmap_mem: 315exit_unmap_mem:
166 iounmap(base); 316 iounmap(base);
167exit_release_mem: 317
168 return err; 318 return err;
169} 319}
170 320
@@ -225,8 +375,20 @@ static int mpc5xxx_can_resume(struct of_device *ofdev)
225} 375}
226#endif 376#endif
227 377
378static struct mpc5xxx_can_data __devinitdata mpc5200_can_data = {
379 .type = MSCAN_TYPE_MPC5200,
380 .get_clock = mpc52xx_can_get_clock,
381};
382
383static struct mpc5xxx_can_data __devinitdata mpc5121_can_data = {
384 .type = MSCAN_TYPE_MPC5121,
385 .get_clock = mpc512x_can_get_clock,
386};
387
228static struct of_device_id __devinitdata mpc5xxx_can_table[] = { 388static struct of_device_id __devinitdata mpc5xxx_can_table[] = {
229 {.compatible = "fsl,mpc5200-mscan"}, 389 { .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, },
390 /* Note that only MPC5121 Rev. 2 (and later) is supported */
391 { .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, },
230 {}, 392 {},
231}; 393};
232 394
@@ -255,5 +417,5 @@ static void __exit mpc5xxx_can_exit(void)
255module_exit(mpc5xxx_can_exit); 417module_exit(mpc5xxx_can_exit);
256 418
257MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); 419MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
258MODULE_DESCRIPTION("Freescale MPC5200 CAN driver"); 420MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver");
259MODULE_LICENSE("GPL v2"); 421MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 0dcbe8cfab64..500d18918bd5 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -152,6 +152,12 @@ static int mscan_start(struct net_device *dev)
152 priv->shadow_canrier = 0; 152 priv->shadow_canrier = 0;
153 priv->flags = 0; 153 priv->flags = 0;
154 154
155 if (priv->type == MSCAN_TYPE_MPC5121) {
156 /* Clear pending bus-off condition */
157 if (in_8(&regs->canmisc) & MSCAN_BOHOLD)
158 out_8(&regs->canmisc, MSCAN_BOHOLD);
159 }
160
155 err = mscan_set_mode(dev, MSCAN_NORMAL_MODE); 161 err = mscan_set_mode(dev, MSCAN_NORMAL_MODE);
156 if (err) 162 if (err)
157 return err; 163 return err;
@@ -163,8 +169,29 @@ static int mscan_start(struct net_device *dev)
163 out_8(&regs->cantier, 0); 169 out_8(&regs->cantier, 0);
164 170
165 /* Enable receive interrupts. */ 171 /* Enable receive interrupts. */
166 out_8(&regs->canrier, MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE | 172 out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
167 MSCAN_RSTATE1 | MSCAN_RSTATE0 | MSCAN_TSTATE1 | MSCAN_TSTATE0); 173
174 return 0;
175}
176
177static int mscan_restart(struct net_device *dev)
178{
179 struct mscan_priv *priv = netdev_priv(dev);
180
181 if (priv->type == MSCAN_TYPE_MPC5121) {
182 struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
183
184 priv->can.state = CAN_STATE_ERROR_ACTIVE;
185 WARN(!(in_8(&regs->canmisc) & MSCAN_BOHOLD),
186 "bus-off state expected");
187 out_8(&regs->canmisc, MSCAN_BOHOLD);
188 /* Re-enable receive interrupts. */
189 out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
190 } else {
191 if (priv->can.state <= CAN_STATE_BUS_OFF)
192 mscan_set_mode(dev, MSCAN_INIT_MODE);
193 return mscan_start(dev);
194 }
168 195
169 return 0; 196 return 0;
170} 197}
@@ -362,9 +389,12 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
362 * automatically. To avoid that we stop the chip doing 389 * automatically. To avoid that we stop the chip doing
363 * a light-weight stop (we are in irq-context). 390 * a light-weight stop (we are in irq-context).
364 */ 391 */
365 out_8(&regs->cantier, 0); 392 if (priv->type != MSCAN_TYPE_MPC5121) {
366 out_8(&regs->canrier, 0); 393 out_8(&regs->cantier, 0);
367 setbits8(&regs->canctl0, MSCAN_SLPRQ | MSCAN_INITRQ); 394 out_8(&regs->canrier, 0);
395 setbits8(&regs->canctl0,
396 MSCAN_SLPRQ | MSCAN_INITRQ);
397 }
368 can_bus_off(dev); 398 can_bus_off(dev);
369 break; 399 break;
370 default: 400 default:
@@ -494,9 +524,7 @@ static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
494 524
495 switch (mode) { 525 switch (mode) {
496 case CAN_MODE_START: 526 case CAN_MODE_START:
497 if (priv->can.state <= CAN_STATE_BUS_OFF) 527 ret = mscan_restart(dev);
498 mscan_set_mode(dev, MSCAN_INIT_MODE);
499 ret = mscan_start(dev);
500 if (ret) 528 if (ret)
501 break; 529 break;
502 if (netif_queue_stopped(dev)) 530 if (netif_queue_stopped(dev))
@@ -595,18 +623,21 @@ static const struct net_device_ops mscan_netdev_ops = {
595 .ndo_start_xmit = mscan_start_xmit, 623 .ndo_start_xmit = mscan_start_xmit,
596}; 624};
597 625
598int register_mscandev(struct net_device *dev, int clock_src) 626int register_mscandev(struct net_device *dev, int mscan_clksrc)
599{ 627{
600 struct mscan_priv *priv = netdev_priv(dev); 628 struct mscan_priv *priv = netdev_priv(dev);
601 struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base; 629 struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
602 u8 ctl1; 630 u8 ctl1;
603 631
604 ctl1 = in_8(&regs->canctl1); 632 ctl1 = in_8(&regs->canctl1);
605 if (clock_src) 633 if (mscan_clksrc)
606 ctl1 |= MSCAN_CLKSRC; 634 ctl1 |= MSCAN_CLKSRC;
607 else 635 else
608 ctl1 &= ~MSCAN_CLKSRC; 636 ctl1 &= ~MSCAN_CLKSRC;
609 637
638 if (priv->type == MSCAN_TYPE_MPC5121)
639 ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */
640
610 ctl1 |= MSCAN_CANE; 641 ctl1 |= MSCAN_CANE;
611 out_8(&regs->canctl1, ctl1); 642 out_8(&regs->canctl1, ctl1);
612 udelay(100); 643 udelay(100);
diff --git a/drivers/net/can/mscan/mscan.h b/drivers/net/can/mscan/mscan.h
index 00fc4aaf1ed8..4ff966473bc9 100644
--- a/drivers/net/can/mscan/mscan.h
+++ b/drivers/net/can/mscan/mscan.h
@@ -38,18 +38,20 @@
38#define MSCAN_CLKSRC 0x40 38#define MSCAN_CLKSRC 0x40
39#define MSCAN_LOOPB 0x20 39#define MSCAN_LOOPB 0x20
40#define MSCAN_LISTEN 0x10 40#define MSCAN_LISTEN 0x10
41#define MSCAN_BORM 0x08
41#define MSCAN_WUPM 0x04 42#define MSCAN_WUPM 0x04
42#define MSCAN_SLPAK 0x02 43#define MSCAN_SLPAK 0x02
43#define MSCAN_INITAK 0x01 44#define MSCAN_INITAK 0x01
44 45
45/* Use the MPC5200 MSCAN variant? */ 46/* Use the MPC5XXX MSCAN variant? */
46#ifdef CONFIG_PPC 47#ifdef CONFIG_PPC
47#define MSCAN_FOR_MPC5200 48#define MSCAN_FOR_MPC5XXX
48#endif 49#endif
49 50
50#ifdef MSCAN_FOR_MPC5200 51#ifdef MSCAN_FOR_MPC5XXX
51#define MSCAN_CLKSRC_BUS 0 52#define MSCAN_CLKSRC_BUS 0
52#define MSCAN_CLKSRC_XTAL MSCAN_CLKSRC 53#define MSCAN_CLKSRC_XTAL MSCAN_CLKSRC
54#define MSCAN_CLKSRC_IPS MSCAN_CLKSRC
53#else 55#else
54#define MSCAN_CLKSRC_BUS MSCAN_CLKSRC 56#define MSCAN_CLKSRC_BUS MSCAN_CLKSRC
55#define MSCAN_CLKSRC_XTAL 0 57#define MSCAN_CLKSRC_XTAL 0
@@ -136,7 +138,7 @@
136#define MSCAN_EFF_RTR_SHIFT 0 138#define MSCAN_EFF_RTR_SHIFT 0
137#define MSCAN_EFF_FLAGS 0x18 /* IDE + SRR */ 139#define MSCAN_EFF_FLAGS 0x18 /* IDE + SRR */
138 140
139#ifdef MSCAN_FOR_MPC5200 141#ifdef MSCAN_FOR_MPC5XXX
140#define _MSCAN_RESERVED_(n, num) u8 _res##n[num] 142#define _MSCAN_RESERVED_(n, num) u8 _res##n[num]
141#define _MSCAN_RESERVED_DSR_SIZE 2 143#define _MSCAN_RESERVED_DSR_SIZE 2
142#else 144#else
@@ -165,67 +167,66 @@ struct mscan_regs {
165 u8 cantbsel; /* + 0x14 0x0a */ 167 u8 cantbsel; /* + 0x14 0x0a */
166 u8 canidac; /* + 0x15 0x0b */ 168 u8 canidac; /* + 0x15 0x0b */
167 u8 reserved; /* + 0x16 0x0c */ 169 u8 reserved; /* + 0x16 0x0c */
168 _MSCAN_RESERVED_(6, 5); /* + 0x17 */ 170 _MSCAN_RESERVED_(6, 2); /* + 0x17 */
169#ifndef MSCAN_FOR_MPC5200 171 u8 canmisc; /* + 0x19 0x0d */
170 u8 canmisc; /* 0x0d */ 172 _MSCAN_RESERVED_(7, 2); /* + 0x1a */
171#endif
172 u8 canrxerr; /* + 0x1c 0x0e */ 173 u8 canrxerr; /* + 0x1c 0x0e */
173 u8 cantxerr; /* + 0x1d 0x0f */ 174 u8 cantxerr; /* + 0x1d 0x0f */
174 _MSCAN_RESERVED_(7, 2); /* + 0x1e */ 175 _MSCAN_RESERVED_(8, 2); /* + 0x1e */
175 u16 canidar1_0; /* + 0x20 0x10 */ 176 u16 canidar1_0; /* + 0x20 0x10 */
176 _MSCAN_RESERVED_(8, 2); /* + 0x22 */ 177 _MSCAN_RESERVED_(9, 2); /* + 0x22 */
177 u16 canidar3_2; /* + 0x24 0x12 */ 178 u16 canidar3_2; /* + 0x24 0x12 */
178 _MSCAN_RESERVED_(9, 2); /* + 0x26 */ 179 _MSCAN_RESERVED_(10, 2); /* + 0x26 */
179 u16 canidmr1_0; /* + 0x28 0x14 */ 180 u16 canidmr1_0; /* + 0x28 0x14 */
180 _MSCAN_RESERVED_(10, 2); /* + 0x2a */ 181 _MSCAN_RESERVED_(11, 2); /* + 0x2a */
181 u16 canidmr3_2; /* + 0x2c 0x16 */ 182 u16 canidmr3_2; /* + 0x2c 0x16 */
182 _MSCAN_RESERVED_(11, 2); /* + 0x2e */ 183 _MSCAN_RESERVED_(12, 2); /* + 0x2e */
183 u16 canidar5_4; /* + 0x30 0x18 */ 184 u16 canidar5_4; /* + 0x30 0x18 */
184 _MSCAN_RESERVED_(12, 2); /* + 0x32 */ 185 _MSCAN_RESERVED_(13, 2); /* + 0x32 */
185 u16 canidar7_6; /* + 0x34 0x1a */ 186 u16 canidar7_6; /* + 0x34 0x1a */
186 _MSCAN_RESERVED_(13, 2); /* + 0x36 */ 187 _MSCAN_RESERVED_(14, 2); /* + 0x36 */
187 u16 canidmr5_4; /* + 0x38 0x1c */ 188 u16 canidmr5_4; /* + 0x38 0x1c */
188 _MSCAN_RESERVED_(14, 2); /* + 0x3a */ 189 _MSCAN_RESERVED_(15, 2); /* + 0x3a */
189 u16 canidmr7_6; /* + 0x3c 0x1e */ 190 u16 canidmr7_6; /* + 0x3c 0x1e */
190 _MSCAN_RESERVED_(15, 2); /* + 0x3e */ 191 _MSCAN_RESERVED_(16, 2); /* + 0x3e */
191 struct { 192 struct {
192 u16 idr1_0; /* + 0x40 0x20 */ 193 u16 idr1_0; /* + 0x40 0x20 */
193 _MSCAN_RESERVED_(16, 2); /* + 0x42 */ 194 _MSCAN_RESERVED_(17, 2); /* + 0x42 */
194 u16 idr3_2; /* + 0x44 0x22 */ 195 u16 idr3_2; /* + 0x44 0x22 */
195 _MSCAN_RESERVED_(17, 2); /* + 0x46 */ 196 _MSCAN_RESERVED_(18, 2); /* + 0x46 */
196 u16 dsr1_0; /* + 0x48 0x24 */ 197 u16 dsr1_0; /* + 0x48 0x24 */
197 _MSCAN_RESERVED_(18, 2); /* + 0x4a */ 198 _MSCAN_RESERVED_(19, 2); /* + 0x4a */
198 u16 dsr3_2; /* + 0x4c 0x26 */ 199 u16 dsr3_2; /* + 0x4c 0x26 */
199 _MSCAN_RESERVED_(19, 2); /* + 0x4e */ 200 _MSCAN_RESERVED_(20, 2); /* + 0x4e */
200 u16 dsr5_4; /* + 0x50 0x28 */ 201 u16 dsr5_4; /* + 0x50 0x28 */
201 _MSCAN_RESERVED_(20, 2); /* + 0x52 */ 202 _MSCAN_RESERVED_(21, 2); /* + 0x52 */
202 u16 dsr7_6; /* + 0x54 0x2a */ 203 u16 dsr7_6; /* + 0x54 0x2a */
203 _MSCAN_RESERVED_(21, 2); /* + 0x56 */ 204 _MSCAN_RESERVED_(22, 2); /* + 0x56 */
204 u8 dlr; /* + 0x58 0x2c */ 205 u8 dlr; /* + 0x58 0x2c */
205 u8:8; /* + 0x59 0x2d */ 206 u8 reserved; /* + 0x59 0x2d */
206 _MSCAN_RESERVED_(22, 2); /* + 0x5a */ 207 _MSCAN_RESERVED_(23, 2); /* + 0x5a */
207 u16 time; /* + 0x5c 0x2e */ 208 u16 time; /* + 0x5c 0x2e */
208 } rx; 209 } rx;
209 _MSCAN_RESERVED_(23, 2); /* + 0x5e */ 210 _MSCAN_RESERVED_(24, 2); /* + 0x5e */
210 struct { 211 struct {
211 u16 idr1_0; /* + 0x60 0x30 */ 212 u16 idr1_0; /* + 0x60 0x30 */
212 _MSCAN_RESERVED_(24, 2); /* + 0x62 */ 213 _MSCAN_RESERVED_(25, 2); /* + 0x62 */
213 u16 idr3_2; /* + 0x64 0x32 */ 214 u16 idr3_2; /* + 0x64 0x32 */
214 _MSCAN_RESERVED_(25, 2); /* + 0x66 */ 215 _MSCAN_RESERVED_(26, 2); /* + 0x66 */
215 u16 dsr1_0; /* + 0x68 0x34 */ 216 u16 dsr1_0; /* + 0x68 0x34 */
216 _MSCAN_RESERVED_(26, 2); /* + 0x6a */ 217 _MSCAN_RESERVED_(27, 2); /* + 0x6a */
217 u16 dsr3_2; /* + 0x6c 0x36 */ 218 u16 dsr3_2; /* + 0x6c 0x36 */
218 _MSCAN_RESERVED_(27, 2); /* + 0x6e */ 219 _MSCAN_RESERVED_(28, 2); /* + 0x6e */
219 u16 dsr5_4; /* + 0x70 0x38 */ 220 u16 dsr5_4; /* + 0x70 0x38 */
220 _MSCAN_RESERVED_(28, 2); /* + 0x72 */ 221 _MSCAN_RESERVED_(29, 2); /* + 0x72 */
221 u16 dsr7_6; /* + 0x74 0x3a */ 222 u16 dsr7_6; /* + 0x74 0x3a */
222 _MSCAN_RESERVED_(29, 2); /* + 0x76 */ 223 _MSCAN_RESERVED_(30, 2); /* + 0x76 */
223 u8 dlr; /* + 0x78 0x3c */ 224 u8 dlr; /* + 0x78 0x3c */
224 u8 tbpr; /* + 0x79 0x3d */ 225 u8 tbpr; /* + 0x79 0x3d */
225 _MSCAN_RESERVED_(30, 2); /* + 0x7a */ 226 _MSCAN_RESERVED_(31, 2); /* + 0x7a */
226 u16 time; /* + 0x7c 0x3e */ 227 u16 time; /* + 0x7c 0x3e */
227 } tx; 228 } tx;
228 _MSCAN_RESERVED_(31, 2); /* + 0x7e */ 229 _MSCAN_RESERVED_(32, 2); /* + 0x7e */
229} __attribute__ ((packed)); 230} __attribute__ ((packed));
230 231
231#undef _MSCAN_RESERVED_ 232#undef _MSCAN_RESERVED_
@@ -237,6 +238,15 @@ struct mscan_regs {
237#define MSCAN_POWEROFF_MODE (MSCAN_CSWAI | MSCAN_SLPRQ) 238#define MSCAN_POWEROFF_MODE (MSCAN_CSWAI | MSCAN_SLPRQ)
238#define MSCAN_SET_MODE_RETRIES 255 239#define MSCAN_SET_MODE_RETRIES 255
239#define MSCAN_ECHO_SKB_MAX 3 240#define MSCAN_ECHO_SKB_MAX 3
241#define MSCAN_RX_INTS_ENABLE (MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE | \
242 MSCAN_RSTATE1 | MSCAN_RSTATE0 | \
243 MSCAN_TSTATE1 | MSCAN_TSTATE0)
244
245/* MSCAN type variants */
246enum {
247 MSCAN_TYPE_MPC5200,
248 MSCAN_TYPE_MPC5121
249};
240 250
241#define BTR0_BRP_MASK 0x3f 251#define BTR0_BRP_MASK 0x3f
242#define BTR0_SJW_SHIFT 6 252#define BTR0_SJW_SHIFT 6
@@ -270,6 +280,7 @@ struct tx_queue_entry {
270 280
271struct mscan_priv { 281struct mscan_priv {
272 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 */
273 long open_time; 284 long open_time;
274 unsigned long flags; 285 unsigned long flags;
275 void __iomem *reg_base; /* ioremap'ed address to registers */ 286 void __iomem *reg_base; /* ioremap'ed address to registers */
@@ -285,12 +296,7 @@ struct mscan_priv {
285}; 296};
286 297
287extern struct net_device *alloc_mscandev(void); 298extern struct net_device *alloc_mscandev(void);
288/* 299extern int register_mscandev(struct net_device *dev, int mscan_clksrc);
289 * clock_src:
290 * 1 = The MSCAN clock source is the onchip Bus Clock.
291 * 0 = The MSCAN clock source is the chip Oscillator Clock.
292 */
293extern int register_mscandev(struct net_device *dev, int clock_src);
294extern void unregister_mscandev(struct net_device *dev); 300extern void unregister_mscandev(struct net_device *dev);
295 301
296#endif /* __MSCAN_H__ */ 302#endif /* __MSCAN_H__ */