Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/bcm63xx/dev-enet.c
10817 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (C) 2008 Maxime Bizon <[email protected]>
7
*/
8
9
#include <linux/init.h>
10
#include <linux/kernel.h>
11
#include <linux/platform_device.h>
12
#include <bcm63xx_dev_enet.h>
13
#include <bcm63xx_io.h>
14
#include <bcm63xx_regs.h>
15
16
static struct resource shared_res[] = {
17
{
18
.start = -1, /* filled at runtime */
19
.end = -1, /* filled at runtime */
20
.flags = IORESOURCE_MEM,
21
},
22
};
23
24
static struct platform_device bcm63xx_enet_shared_device = {
25
.name = "bcm63xx_enet_shared",
26
.id = 0,
27
.num_resources = ARRAY_SIZE(shared_res),
28
.resource = shared_res,
29
};
30
31
static int shared_device_registered;
32
33
static struct resource enet0_res[] = {
34
{
35
.start = -1, /* filled at runtime */
36
.end = -1, /* filled at runtime */
37
.flags = IORESOURCE_MEM,
38
},
39
{
40
.start = -1, /* filled at runtime */
41
.flags = IORESOURCE_IRQ,
42
},
43
{
44
.start = -1, /* filled at runtime */
45
.flags = IORESOURCE_IRQ,
46
},
47
{
48
.start = -1, /* filled at runtime */
49
.flags = IORESOURCE_IRQ,
50
},
51
};
52
53
static struct bcm63xx_enet_platform_data enet0_pd;
54
55
static struct platform_device bcm63xx_enet0_device = {
56
.name = "bcm63xx_enet",
57
.id = 0,
58
.num_resources = ARRAY_SIZE(enet0_res),
59
.resource = enet0_res,
60
.dev = {
61
.platform_data = &enet0_pd,
62
},
63
};
64
65
static struct resource enet1_res[] = {
66
{
67
.start = -1, /* filled at runtime */
68
.end = -1, /* filled at runtime */
69
.flags = IORESOURCE_MEM,
70
},
71
{
72
.start = -1, /* filled at runtime */
73
.flags = IORESOURCE_IRQ,
74
},
75
{
76
.start = -1, /* filled at runtime */
77
.flags = IORESOURCE_IRQ,
78
},
79
{
80
.start = -1, /* filled at runtime */
81
.flags = IORESOURCE_IRQ,
82
},
83
};
84
85
static struct bcm63xx_enet_platform_data enet1_pd;
86
87
static struct platform_device bcm63xx_enet1_device = {
88
.name = "bcm63xx_enet",
89
.id = 1,
90
.num_resources = ARRAY_SIZE(enet1_res),
91
.resource = enet1_res,
92
.dev = {
93
.platform_data = &enet1_pd,
94
},
95
};
96
97
int __init bcm63xx_enet_register(int unit,
98
const struct bcm63xx_enet_platform_data *pd)
99
{
100
struct platform_device *pdev;
101
struct bcm63xx_enet_platform_data *dpd;
102
int ret;
103
104
if (unit > 1)
105
return -ENODEV;
106
107
if (unit == 1 && BCMCPU_IS_6338())
108
return -ENODEV;
109
110
if (!shared_device_registered) {
111
shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
112
shared_res[0].end = shared_res[0].start;
113
if (BCMCPU_IS_6338())
114
shared_res[0].end += (RSET_ENETDMA_SIZE / 2) - 1;
115
else
116
shared_res[0].end += (RSET_ENETDMA_SIZE) - 1;
117
118
ret = platform_device_register(&bcm63xx_enet_shared_device);
119
if (ret)
120
return ret;
121
shared_device_registered = 1;
122
}
123
124
if (unit == 0) {
125
enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
126
enet0_res[0].end = enet0_res[0].start;
127
enet0_res[0].end += RSET_ENET_SIZE - 1;
128
enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
129
enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
130
enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
131
pdev = &bcm63xx_enet0_device;
132
} else {
133
enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
134
enet1_res[0].end = enet1_res[0].start;
135
enet1_res[0].end += RSET_ENET_SIZE - 1;
136
enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
137
enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
138
enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
139
pdev = &bcm63xx_enet1_device;
140
}
141
142
/* copy given platform data */
143
dpd = pdev->dev.platform_data;
144
memcpy(dpd, pd, sizeof(*pd));
145
146
/* adjust them in case internal phy is used */
147
if (dpd->use_internal_phy) {
148
149
/* internal phy only exists for enet0 */
150
if (unit == 1)
151
return -ENODEV;
152
153
dpd->phy_id = 1;
154
dpd->has_phy_interrupt = 1;
155
dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
156
}
157
158
ret = platform_device_register(pdev);
159
if (ret)
160
return ret;
161
return 0;
162
}
163
164