Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
net
can
sja1000
sja1000_of_platform.c
Go to the documentation of this file.
1
/*
2
* Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
3
*
4
* Copyright (C) 2008-2009 Wolfgang Grandegger <
[email protected]
>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the version 2 of the GNU General Public License
8
* as published by the Free Software Foundation
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software Foundation,
17
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
*/
19
20
/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
21
* bus found on embedded PowerPC systems. You need a SJA1000 CAN node
22
* definition in your flattened device tree source (DTS) file similar to:
23
*
24
* can@3,100 {
25
* compatible = "nxp,sja1000";
26
* reg = <3 0x100 0x80>;
27
* interrupts = <2 0>;
28
* interrupt-parent = <&mpic>;
29
* nxp,external-clock-frequency = <16000000>;
30
* };
31
*
32
* See "Documentation/devicetree/bindings/net/can/sja1000.txt" for further
33
* information.
34
*/
35
36
#include <linux/kernel.h>
37
#include <linux/module.h>
38
#include <
linux/interrupt.h
>
39
#include <linux/netdevice.h>
40
#include <
linux/delay.h
>
41
#include <
linux/io.h
>
42
#include <
linux/can/dev.h
>
43
44
#include <
linux/of_platform.h
>
45
#include <asm/prom.h>
46
47
#include "
sja1000.h
"
48
49
#define DRV_NAME "sja1000_of_platform"
50
51
MODULE_AUTHOR
(
"Wolfgang Grandegger <
[email protected]
>"
);
52
MODULE_DESCRIPTION
(
"Socket-CAN driver for SJA1000 on the OF platform bus"
);
53
MODULE_LICENSE
(
"GPL v2"
);
54
55
#define SJA1000_OFP_CAN_CLOCK (16000000 / 2)
56
57
#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN
58
#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF)
59
60
static
u8
sja1000_ofp_read_reg(
const
struct
sja1000_priv
*
priv
,
int
reg
)
61
{
62
return
in_8
(priv->
reg_base
+ reg);
63
}
64
65
static
void
sja1000_ofp_write_reg(
const
struct
sja1000_priv
*
priv
,
66
int
reg
,
u8
val
)
67
{
68
out_8
(priv->
reg_base
+ reg, val);
69
}
70
71
static
int
__devexit
sja1000_ofp_remove(
struct
platform_device
*ofdev)
72
{
73
struct
net_device
*
dev
=
dev_get_drvdata
(&ofdev->
dev
);
74
struct
sja1000_priv
*
priv
= netdev_priv(dev);
75
struct
device_node
*np = ofdev->
dev
.of_node;
76
struct
resource
res
;
77
78
dev_set_drvdata
(&ofdev->
dev
,
NULL
);
79
80
unregister_sja1000dev
(dev);
81
free_sja1000dev
(dev);
82
iounmap
(priv->
reg_base
);
83
irq_dispose_mapping
(dev->
irq
);
84
85
of_address_to_resource
(np, 0, &
res
);
86
release_mem_region
(
res
.start, resource_size(&
res
));
87
88
return
0;
89
}
90
91
static
int
__devinit
sja1000_ofp_probe(
struct
platform_device
*ofdev)
92
{
93
struct
device_node
*np = ofdev->
dev
.of_node;
94
struct
net_device
*
dev
;
95
struct
sja1000_priv
*
priv
;
96
struct
resource
res
;
97
const
u32
*prop;
98
int
err
,
irq
,
res_size
, prop_size;
99
void
__iomem
*
base
;
100
101
err =
of_address_to_resource
(np, 0, &
res
);
102
if
(err) {
103
dev_err
(&ofdev->
dev
,
"invalid address\n"
);
104
return
err
;
105
}
106
107
res_size = resource_size(&
res
);
108
109
if
(!
request_mem_region
(
res
.start, res_size,
DRV_NAME
)) {
110
dev_err
(&ofdev->
dev
,
"couldn't request %pR\n"
, &
res
);
111
return
-
EBUSY
;
112
}
113
114
base =
ioremap_nocache
(
res
.start, res_size);
115
if
(!base) {
116
dev_err
(&ofdev->
dev
,
"couldn't ioremap %pR\n"
, &
res
);
117
err = -
ENOMEM
;
118
goto
exit_release_mem;
119
}
120
121
irq =
irq_of_parse_and_map
(np, 0);
122
if
(irq ==
NO_IRQ
) {
123
dev_err
(&ofdev->
dev
,
"no irq found\n"
);
124
err = -
ENODEV
;
125
goto
exit_unmap_mem;
126
}
127
128
dev =
alloc_sja1000dev
(0);
129
if
(!dev) {
130
err = -
ENOMEM
;
131
goto
exit_dispose_irq;
132
}
133
134
priv = netdev_priv(dev);
135
136
priv->
read_reg
= sja1000_ofp_read_reg;
137
priv->
write_reg
= sja1000_ofp_write_reg;
138
139
prop =
of_get_property
(np,
"nxp,external-clock-frequency"
, &prop_size);
140
if
(prop && (prop_size ==
sizeof
(
u32
)))
141
priv->
can
.clock.freq = *prop / 2;
142
else
143
priv->
can
.clock.freq =
SJA1000_OFP_CAN_CLOCK
;
/* default */
144
145
prop =
of_get_property
(np,
"nxp,tx-output-mode"
, &prop_size);
146
if
(prop && (prop_size ==
sizeof
(
u32
)))
147
priv->
ocr
|= *prop &
OCR_MODE_MASK
;
148
else
149
priv->
ocr
|=
OCR_MODE_NORMAL
;
/* default */
150
151
prop =
of_get_property
(np,
"nxp,tx-output-config"
, &prop_size);
152
if
(prop && (prop_size ==
sizeof
(
u32
)))
153
priv->
ocr
|= (*prop <<
OCR_TX_SHIFT
) &
OCR_TX_MASK
;
154
else
155
priv->
ocr
|=
OCR_TX0_PULLDOWN
;
/* default */
156
157
prop =
of_get_property
(np,
"nxp,clock-out-frequency"
, &prop_size);
158
if
(prop && (prop_size ==
sizeof
(
u32
)) && *prop) {
159
u32
divider = priv->
can
.clock.freq * 2 / *prop;
160
161
if
(divider > 1)
162
priv->
cdr
|= divider / 2 - 1;
163
else
164
priv->
cdr
|=
CDR_CLKOUT_MASK
;
165
}
else
{
166
priv->
cdr
|=
CDR_CLK_OFF
;
/* default */
167
}
168
169
prop =
of_get_property
(np,
"nxp,no-comparator-bypass"
,
NULL
);
170
if
(!prop)
171
priv->
cdr
|=
CDR_CBP
;
/* default */
172
173
priv->
irq_flags
=
IRQF_SHARED
;
174
priv->
reg_base
= base;
175
176
dev->
irq
= irq;
177
178
dev_info
(&ofdev->
dev
,
179
"reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n"
,
180
priv->
reg_base
, dev->
irq
, priv->
can
.clock.freq,
181
priv->
ocr
, priv->
cdr
);
182
183
dev_set_drvdata
(&ofdev->
dev
, dev);
184
SET_NETDEV_DEV
(dev, &ofdev->
dev
);
185
186
err =
register_sja1000dev
(dev);
187
if
(err) {
188
dev_err
(&ofdev->
dev
,
"registering %s failed (err=%d)\n"
,
189
DRV_NAME
, err);
190
goto
exit_free_sja1000;
191
}
192
193
return
0;
194
195
exit_free_sja1000:
196
free_sja1000dev
(dev);
197
exit_dispose_irq:
198
irq_dispose_mapping
(irq);
199
exit_unmap_mem:
200
iounmap
(base);
201
exit_release_mem:
202
release_mem_region
(
res
.start, res_size);
203
204
return
err
;
205
}
206
207
static
struct
of_device_id
__devinitdata
sja1000_ofp_table[] = {
208
{.compatible =
"nxp,sja1000"
},
209
{},
210
};
211
MODULE_DEVICE_TABLE
(of, sja1000_ofp_table);
212
213
static
struct
platform_driver
sja1000_ofp_driver = {
214
.driver = {
215
.owner =
THIS_MODULE
,
216
.name =
DRV_NAME
,
217
.of_match_table = sja1000_ofp_table,
218
},
219
.probe = sja1000_ofp_probe,
220
.remove =
__devexit_p
(sja1000_ofp_remove),
221
};
222
223
module_platform_driver
(sja1000_ofp_driver);
Generated on Thu Jan 10 2013 13:57:47 for Linux Kernel by
1.8.2