drm/radeon/kms/igp: sideport is AMD only
[sfrench/cifs-2.6.git] / arch / mips / bcm63xx / dev-enet.c
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 <mbizon@freebox.fr>
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 (!shared_device_registered) {
108                 shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
109                 shared_res[0].end = shared_res[0].start;
110                 if (BCMCPU_IS_6338())
111                         shared_res[0].end += (RSET_ENETDMA_SIZE / 2)  - 1;
112                 else
113                         shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
114
115                 ret = platform_device_register(&bcm63xx_enet_shared_device);
116                 if (ret)
117                         return ret;
118                 shared_device_registered = 1;
119         }
120
121         if (unit == 0) {
122                 enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
123                 enet0_res[0].end = enet0_res[0].start;
124                 enet0_res[0].end += RSET_ENET_SIZE - 1;
125                 enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
126                 enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
127                 enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
128                 pdev = &bcm63xx_enet0_device;
129         } else {
130                 enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
131                 enet1_res[0].end = enet1_res[0].start;
132                 enet1_res[0].end += RSET_ENET_SIZE - 1;
133                 enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
134                 enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
135                 enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
136                 pdev = &bcm63xx_enet1_device;
137         }
138
139         /* copy given platform data */
140         dpd = pdev->dev.platform_data;
141         memcpy(dpd, pd, sizeof(*pd));
142
143         /* adjust them in case internal phy is used */
144         if (dpd->use_internal_phy) {
145
146                 /* internal phy only exists for enet0 */
147                 if (unit == 1)
148                         return -ENODEV;
149
150                 dpd->phy_id = 1;
151                 dpd->has_phy_interrupt = 1;
152                 dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
153         }
154
155         ret = platform_device_register(pdev);
156         if (ret)
157                 return ret;
158         return 0;
159 }