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
arch
powerpc
sysdev
tsi108_dev.c
Go to the documentation of this file.
1
/*
2
* tsi108/109 device setup code
3
*
4
* Maintained by Roy Zang <
[email protected]
>
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the
8
* Free Software Foundation; either version 2 of the License, or (at your
9
* option) any later version.
10
*/
11
12
#include <linux/stddef.h>
13
#include <linux/kernel.h>
14
#include <
linux/init.h
>
15
#include <linux/errno.h>
16
#include <
linux/major.h
>
17
#include <
linux/delay.h
>
18
#include <
linux/irq.h
>
19
#include <linux/export.h>
20
#include <linux/device.h>
21
#include <
linux/platform_device.h
>
22
#include <
linux/of_net.h
>
23
#include <
asm/tsi108.h
>
24
25
#include <
linux/atomic.h
>
26
#include <asm/io.h>
27
#include <asm/irq.h>
28
#include <asm/prom.h>
29
#include <
mm/mmu_decl.h
>
30
31
#undef DEBUG
32
33
#ifdef DEBUG
34
#define DBG(fmt...) do { printk(fmt); } while(0)
35
#else
36
#define DBG(fmt...) do { } while(0)
37
#endif
38
39
static
phys_addr_t
tsi108_csr_base = -1;
40
41
phys_addr_t
get_csrbase
(
void
)
42
{
43
struct
device_node
*tsi;
44
45
if
(tsi108_csr_base != -1)
46
return
tsi108_csr_base;
47
48
tsi =
of_find_node_by_type
(
NULL
,
"tsi-bridge"
);
49
if
(tsi) {
50
unsigned
int
size
;
51
const
void
*prop =
of_get_property
(tsi,
"reg"
, &size);
52
tsi108_csr_base =
of_translate_address
(tsi, prop);
53
of_node_put(tsi);
54
};
55
return
tsi108_csr_base;
56
}
57
58
u32
get_vir_csrbase
(
void
)
59
{
60
return
(
u32
) (
ioremap
(
get_csrbase
(), 0x10000));
61
}
62
63
EXPORT_SYMBOL
(
get_csrbase
);
64
EXPORT_SYMBOL
(
get_vir_csrbase
);
65
66
static
int
__init
tsi108_eth_of_init(
void
)
67
{
68
struct
device_node
*np;
69
unsigned
int
i
= 0;
70
struct
platform_device
*tsi_eth_dev;
71
struct
resource
res
;
72
int
ret
;
73
74
for_each_compatible_node(np,
"network"
,
"tsi108-ethernet"
) {
75
struct
resource
r
[2];
76
struct
device_node
*
phy
, *mdio;
77
hw_info
tsi_eth_data;
78
const
unsigned
int
*
phy_id
;
79
const
void
*
mac_addr
;
80
const
phandle
*
ph
;
81
82
memset
(
r
, 0,
sizeof
(
r
));
83
memset
(&tsi_eth_data, 0,
sizeof
(tsi_eth_data));
84
85
ret =
of_address_to_resource
(np, 0, &
r
[0]);
86
DBG
(
"%s: name:start->end = %s:%pR\n"
,
87
__func__,
r
[0].
name
, &
r
[0]);
88
if
(ret)
89
goto
err
;
90
91
r
[1].name =
"tx"
;
92
r
[1].start =
irq_of_parse_and_map
(np, 0);
93
r
[1].end =
irq_of_parse_and_map
(np, 0);
94
r
[1].flags =
IORESOURCE_IRQ
;
95
DBG
(
"%s: name:start->end = %s:%pR\n"
,
96
__func__,
r
[1].
name
, &
r
[1]);
97
98
tsi_eth_dev =
99
platform_device_register_simple(
"tsi-ethernet"
, i++, &
r
[0],
100
1);
101
102
if
(IS_ERR(tsi_eth_dev)) {
103
ret = PTR_ERR(tsi_eth_dev);
104
goto
err
;
105
}
106
107
mac_addr =
of_get_mac_address
(np);
108
if
(mac_addr)
109
memcpy
(tsi_eth_data.
mac_addr
, mac_addr, 6);
110
111
ph =
of_get_property
(np,
"mdio-handle"
,
NULL
);
112
mdio =
of_find_node_by_phandle
(*ph);
113
ret =
of_address_to_resource
(mdio, 0, &
res
);
114
of_node_put(mdio);
115
if
(ret)
116
goto
unreg;
117
118
ph =
of_get_property
(np,
"phy-handle"
,
NULL
);
119
phy =
of_find_node_by_phandle
(*ph);
120
121
if
(phy ==
NULL
) {
122
ret = -
ENODEV
;
123
goto
unreg;
124
}
125
126
phy_id =
of_get_property
(phy,
"reg"
,
NULL
);
127
128
tsi_eth_data.
regs
=
r
[0].start;
129
tsi_eth_data.
phyregs
=
res
.start;
130
tsi_eth_data.
phy
= *
phy_id
;
131
tsi_eth_data.
irq_num
=
irq_of_parse_and_map
(np, 0);
132
133
/* Some boards with the TSI108 bridge (e.g. Holly)
134
* have a miswiring of the ethernet PHYs which
135
* requires a workaround. The special
136
* "txc-rxc-delay-disable" property enables this
137
* workaround. FIXME: Need to port the tsi108_eth
138
* driver itself to phylib and use a non-misleading
139
* name for the workaround flag - it's not actually to
140
* do with the model of PHY in use */
141
if
(
of_get_property
(phy,
"txc-rxc-delay-disable"
,
NULL
))
142
tsi_eth_data.
phy_type
=
TSI108_PHY_BCM54XX
;
143
of_node_put(phy);
144
145
ret =
146
platform_device_add_data
(tsi_eth_dev, &tsi_eth_data,
147
sizeof
(
hw_info
));
148
if
(ret)
149
goto
unreg;
150
}
151
return
0;
152
unreg:
153
platform_device_unregister
(tsi_eth_dev);
154
err
:
155
of_node_put(np);
156
return
ret
;
157
}
158
159
arch_initcall
(tsi108_eth_of_init);
Generated on Thu Jan 10 2013 13:16:23 for Linux Kernel by
1.8.2