diff options
author | Scott Wood <scottwood@freescale.com> | 2007-10-02 11:55:58 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:54:03 -0400 |
commit | 976de6a8c304dcc43e38efcb8a0bace7866b6242 (patch) | |
tree | bae132693bbcfa65c03cf44c7db924fdebf13158 /drivers/net/fs_enet/mac-fcc.c | |
parent | 0d0d9c150c046cbd3e507adcfa2d78db82f1f452 (diff) |
fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.
The existing OF glue code was crufty and broken. Rather than fix it, it
will be removed, and the ethernet driver now talks to the device tree
directly.
The old, non-CONFIG_PPC_CPM_NEW_BINDING code can go away once CPM
platforms are dropped from arch/ppc (which will hopefully be soon), and
existing arch/powerpc boards that I wasn't able to test on for this
patchset get converted (which should be even sooner).
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/fs_enet/mac-fcc.c')
-rw-r--r-- | drivers/net/fs_enet/mac-fcc.c | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index e990f728d51b..6094cbf542a2 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c | |||
@@ -42,6 +42,10 @@ | |||
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | 44 | ||
45 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
46 | #include <asm/of_device.h> | ||
47 | #endif | ||
48 | |||
45 | #include "fs_enet.h" | 49 | #include "fs_enet.h" |
46 | 50 | ||
47 | /*************************************************/ | 51 | /*************************************************/ |
@@ -74,33 +78,64 @@ | |||
74 | 78 | ||
75 | #define MAX_CR_CMD_LOOPS 10000 | 79 | #define MAX_CR_CMD_LOOPS 10000 |
76 | 80 | ||
77 | static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) | 81 | static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) |
78 | { | 82 | { |
79 | const struct fs_platform_info *fpi = fep->fpi; | 83 | const struct fs_platform_info *fpi = fep->fpi; |
80 | cpm2_map_t *immap = fs_enet_immap; | 84 | cpm2_map_t *immap = fs_enet_immap; |
81 | cpm_cpm2_t *cpmp = &immap->im_cpm; | 85 | cpm_cpm2_t *cpmp = &immap->im_cpm; |
82 | u32 v; | ||
83 | int i; | 86 | int i; |
84 | 87 | ||
85 | /* Currently I don't know what feature call will look like. But | 88 | W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG); |
86 | I guess there'd be something like do_cpm_cmd() which will require page & sblock */ | ||
87 | v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op); | ||
88 | W32(cpmp, cp_cpcr, v | CPM_CR_FLG); | ||
89 | for (i = 0; i < MAX_CR_CMD_LOOPS; i++) | 89 | for (i = 0; i < MAX_CR_CMD_LOOPS; i++) |
90 | if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) | 90 | if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) |
91 | break; | 91 | return 0; |
92 | |||
93 | if (i >= MAX_CR_CMD_LOOPS) { | ||
94 | printk(KERN_ERR "%s(): Not able to issue CPM command\n", | ||
95 | __FUNCTION__); | ||
96 | return 1; | ||
97 | } | ||
98 | 92 | ||
99 | return 0; | 93 | printk(KERN_ERR "%s(): Not able to issue CPM command\n", |
94 | __FUNCTION__); | ||
95 | return 1; | ||
100 | } | 96 | } |
101 | 97 | ||
102 | static int do_pd_setup(struct fs_enet_private *fep) | 98 | static int do_pd_setup(struct fs_enet_private *fep) |
103 | { | 99 | { |
100 | #ifdef CONFIG_PPC_CPM_NEW_BINDING | ||
101 | struct of_device *ofdev = to_of_device(fep->dev); | ||
102 | struct fs_platform_info *fpi = fep->fpi; | ||
103 | int ret = -EINVAL; | ||
104 | |||
105 | fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); | ||
106 | if (fep->interrupt == NO_IRQ) | ||
107 | goto out; | ||
108 | |||
109 | fep->fcc.fccp = of_iomap(ofdev->node, 0); | ||
110 | if (!fep->fcc.fccp) | ||
111 | goto out; | ||
112 | |||
113 | fep->fcc.ep = of_iomap(ofdev->node, 1); | ||
114 | if (!fep->fcc.ep) | ||
115 | goto out_fccp; | ||
116 | |||
117 | fep->fcc.fcccp = of_iomap(ofdev->node, 2); | ||
118 | if (!fep->fcc.fcccp) | ||
119 | goto out_ep; | ||
120 | |||
121 | fep->fcc.mem = (void *)cpm_dpalloc(128, 8); | ||
122 | fpi->dpram_offset = (u32)cpm2_immr; | ||
123 | if (IS_ERR_VALUE(fpi->dpram_offset)) { | ||
124 | ret = fpi->dpram_offset; | ||
125 | goto out_fcccp; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | |||
130 | out_fcccp: | ||
131 | iounmap(fep->fcc.fcccp); | ||
132 | out_ep: | ||
133 | iounmap(fep->fcc.ep); | ||
134 | out_fccp: | ||
135 | iounmap(fep->fcc.fccp); | ||
136 | out: | ||
137 | return ret; | ||
138 | #else | ||
104 | struct platform_device *pdev = to_platform_device(fep->dev); | 139 | struct platform_device *pdev = to_platform_device(fep->dev); |
105 | struct resource *r; | 140 | struct resource *r; |
106 | 141 | ||
@@ -138,6 +173,7 @@ static int do_pd_setup(struct fs_enet_private *fep) | |||
138 | return -EINVAL; | 173 | return -EINVAL; |
139 | 174 | ||
140 | return 0; | 175 | return 0; |
176 | #endif | ||
141 | } | 177 | } |
142 | 178 | ||
143 | #define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) | 179 | #define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) |
@@ -148,11 +184,17 @@ static int do_pd_setup(struct fs_enet_private *fep) | |||
148 | static int setup_data(struct net_device *dev) | 184 | static int setup_data(struct net_device *dev) |
149 | { | 185 | { |
150 | struct fs_enet_private *fep = netdev_priv(dev); | 186 | struct fs_enet_private *fep = netdev_priv(dev); |
151 | const struct fs_platform_info *fpi = fep->fpi; | 187 | #ifndef CONFIG_PPC_CPM_NEW_BINDING |
188 | struct fs_platform_info *fpi = fep->fpi; | ||
189 | |||
190 | fpi->cp_command = (fpi->cp_page << 26) | | ||
191 | (fpi->cp_block << 21) | | ||
192 | (12 << 6); | ||
152 | 193 | ||
153 | fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); | 194 | fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); |
154 | if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ | 195 | if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ |
155 | return -EINVAL; | 196 | return -EINVAL; |
197 | #endif | ||
156 | 198 | ||
157 | if (do_pd_setup(fep) != 0) | 199 | if (do_pd_setup(fep) != 0) |
158 | return -EINVAL; | 200 | return -EINVAL; |
@@ -226,7 +268,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac) | |||
226 | W16(ep, fen_taddrh, taddrh); | 268 | W16(ep, fen_taddrh, taddrh); |
227 | W16(ep, fen_taddrm, taddrm); | 269 | W16(ep, fen_taddrm, taddrm); |
228 | W16(ep, fen_taddrl, taddrl); | 270 | W16(ep, fen_taddrl, taddrl); |
229 | fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); | 271 | fcc_cr_cmd(fep, CPM_CR_SET_GADDR); |
230 | } | 272 | } |
231 | 273 | ||
232 | static void set_multicast_finish(struct net_device *dev) | 274 | static void set_multicast_finish(struct net_device *dev) |
@@ -281,7 +323,7 @@ static void restart(struct net_device *dev) | |||
281 | 323 | ||
282 | /* clear everything (slow & steady does it) */ | 324 | /* clear everything (slow & steady does it) */ |
283 | for (i = 0; i < sizeof(*ep); i++) | 325 | for (i = 0; i < sizeof(*ep); i++) |
284 | out_8((char *)ep + i, 0); | 326 | out_8((u8 __iomem *)ep + i, 0); |
285 | 327 | ||
286 | /* get physical address */ | 328 | /* get physical address */ |
287 | rx_bd_base_phys = fep->ring_mem_addr; | 329 | rx_bd_base_phys = fep->ring_mem_addr; |
@@ -397,7 +439,7 @@ static void restart(struct net_device *dev) | |||
397 | S8(fcccp, fcc_gfemr, 0x20); | 439 | S8(fcccp, fcc_gfemr, 0x20); |
398 | } | 440 | } |
399 | 441 | ||
400 | fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); | 442 | fcc_cr_cmd(fep, CPM_CR_INIT_TRX); |
401 | 443 | ||
402 | /* clear events */ | 444 | /* clear events */ |
403 | W16(fccp, fcc_fcce, 0xffff); | 445 | W16(fccp, fcc_fcce, 0xffff); |
@@ -515,23 +557,22 @@ int get_regs(struct net_device *dev, void *p, int *sizep) | |||
515 | { | 557 | { |
516 | struct fs_enet_private *fep = netdev_priv(dev); | 558 | struct fs_enet_private *fep = netdev_priv(dev); |
517 | 559 | ||
518 | if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) | 560 | if (*sizep < sizeof(fcc_t) + sizeof(fcc_enet_t) + 1) |
519 | return -EINVAL; | 561 | return -EINVAL; |
520 | 562 | ||
521 | memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); | 563 | memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); |
522 | p = (char *)p + sizeof(fcc_t); | 564 | p = (char *)p + sizeof(fcc_t); |
523 | 565 | ||
524 | memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t)); | ||
525 | p = (char *)p + sizeof(fcc_c_t); | ||
526 | |||
527 | memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); | 566 | memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); |
567 | p = (char *)p + sizeof(fcc_enet_t); | ||
528 | 568 | ||
569 | memcpy_fromio(p, fep->fcc.fcccp, 1); | ||
529 | return 0; | 570 | return 0; |
530 | } | 571 | } |
531 | 572 | ||
532 | int get_regs_len(struct net_device *dev) | 573 | int get_regs_len(struct net_device *dev) |
533 | { | 574 | { |
534 | return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); | 575 | return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1; |
535 | } | 576 | } |
536 | 577 | ||
537 | /* Some transmit errors cause the transmitter to shut | 578 | /* Some transmit errors cause the transmitter to shut |
@@ -551,7 +592,7 @@ void tx_restart(struct net_device *dev) | |||
551 | udelay(10); | 592 | udelay(10); |
552 | S32(fccp, fcc_gfmr, FCC_GFMR_ENT); | 593 | S32(fccp, fcc_gfmr, FCC_GFMR_ENT); |
553 | 594 | ||
554 | fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); | 595 | fcc_cr_cmd(fep, CPM_CR_RESTART_TX); |
555 | } | 596 | } |
556 | 597 | ||
557 | /*************************************************************************/ | 598 | /*************************************************************************/ |