Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Scott Wood and committed by
David S. Miller
976de6a8 0d0d9c15

+720 -184
+1
drivers/net/fs_enet/Kconfig
··· 11 11 config FS_ENET_HAS_FCC 12 12 bool "Chip has an FCC usable for ethernet" 13 13 depends on FS_ENET && CPM2 14 + select MDIO_BITBANG 14 15 default y 15 16 16 17 config FS_ENET_HAS_FEC
+241 -17
drivers/net/fs_enet/fs_enet-main.c
··· 42 42 #include <asm/irq.h> 43 43 #include <asm/uaccess.h> 44 44 45 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 46 + #include <asm/of_platform.h> 47 + #endif 48 + 45 49 #include "fs_enet.h" 46 50 47 51 /*************************************************/ 48 52 53 + #ifndef CONFIG_PPC_CPM_NEW_BINDING 49 54 static char version[] __devinitdata = 50 55 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n"; 56 + #endif 51 57 52 58 MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>"); 53 59 MODULE_DESCRIPTION("Freescale Ethernet Driver"); ··· 954 948 extern int fs_mii_connect(struct net_device *dev); 955 949 extern void fs_mii_disconnect(struct net_device *dev); 956 950 951 + #ifndef CONFIG_PPC_CPM_NEW_BINDING 957 952 static struct net_device *fs_init_instance(struct device *dev, 958 953 struct fs_platform_info *fpi) 959 954 { ··· 1136 1129 1137 1130 return 0; 1138 1131 } 1132 + #endif 1139 1133 1140 1134 /**************************************************************************************/ 1141 1135 ··· 1145 1137 1146 1138 static int setup_immap(void) 1147 1139 { 1148 - phys_addr_t paddr = 0; 1149 - unsigned long size = 0; 1150 - 1151 1140 #ifdef CONFIG_CPM1 1152 - paddr = IMAP_ADDR; 1153 - size = 0x10000; /* map 64K */ 1141 + fs_enet_immap = ioremap(IMAP_ADDR, 0x4000); 1142 + WARN_ON(!fs_enet_immap); 1143 + #elif defined(CONFIG_CPM2) 1144 + fs_enet_immap = cpm2_immr; 1154 1145 #endif 1155 - 1156 - #ifdef CONFIG_CPM2 1157 - paddr = CPM_MAP_ADDR; 1158 - size = 0x40000; /* map 256 K */ 1159 - #endif 1160 - fs_enet_immap = ioremap(paddr, size); 1161 - if (fs_enet_immap == NULL) 1162 - return -EBADF; /* XXX ahem; maybe just BUG_ON? */ 1163 1146 1164 1147 return 0; 1165 1148 } 1166 1149 1167 1150 static void cleanup_immap(void) 1168 1151 { 1169 - if (fs_enet_immap != NULL) { 1170 - iounmap(fs_enet_immap); 1171 - fs_enet_immap = NULL; 1172 - } 1152 + #if defined(CONFIG_CPM1) 1153 + iounmap(fs_enet_immap); 1154 + #endif 1173 1155 } 1174 1156 1175 1157 /**************************************************************************************/ 1176 1158 1159 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 1160 + static int __devinit find_phy(struct device_node *np, 1161 + struct fs_platform_info *fpi) 1162 + { 1163 + struct device_node *phynode, *mdionode; 1164 + struct resource res; 1165 + int ret = 0, len; 1166 + 1167 + const u32 *data = of_get_property(np, "phy-handle", &len); 1168 + if (!data || len != 4) 1169 + return -EINVAL; 1170 + 1171 + phynode = of_find_node_by_phandle(*data); 1172 + if (!phynode) 1173 + return -EINVAL; 1174 + 1175 + mdionode = of_get_parent(phynode); 1176 + if (!mdionode) 1177 + goto out_put_phy; 1178 + 1179 + ret = of_address_to_resource(mdionode, 0, &res); 1180 + if (ret) 1181 + goto out_put_mdio; 1182 + 1183 + data = of_get_property(phynode, "reg", &len); 1184 + if (!data || len != 4) 1185 + goto out_put_mdio; 1186 + 1187 + snprintf(fpi->bus_id, 16, PHY_ID_FMT, res.start, *data); 1188 + 1189 + out_put_mdio: 1190 + of_node_put(mdionode); 1191 + out_put_phy: 1192 + of_node_put(phynode); 1193 + return ret; 1194 + } 1195 + 1196 + #ifdef CONFIG_FS_ENET_HAS_FEC 1197 + #define IS_FEC(match) ((match)->data == &fs_fec_ops) 1198 + #else 1199 + #define IS_FEC(match) 0 1200 + #endif 1201 + 1202 + static int __devinit fs_enet_probe(struct of_device *ofdev, 1203 + const struct of_device_id *match) 1204 + { 1205 + struct net_device *ndev; 1206 + struct fs_enet_private *fep; 1207 + struct fs_platform_info *fpi; 1208 + const u32 *data; 1209 + const u8 *mac_addr; 1210 + int privsize, len, ret = -ENODEV; 1211 + 1212 + fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); 1213 + if (!fpi) 1214 + return -ENOMEM; 1215 + 1216 + if (!IS_FEC(match)) { 1217 + data = of_get_property(ofdev->node, "fsl,cpm-command", &len); 1218 + if (!data || len != 4) 1219 + goto out_free_fpi; 1220 + 1221 + fpi->cp_command = *data; 1222 + } 1223 + 1224 + fpi->rx_ring = 32; 1225 + fpi->tx_ring = 32; 1226 + fpi->rx_copybreak = 240; 1227 + fpi->use_napi = 0; 1228 + fpi->napi_weight = 17; 1229 + 1230 + ret = find_phy(ofdev->node, fpi); 1231 + if (ret) 1232 + goto out_free_fpi; 1233 + 1234 + privsize = sizeof(*fep) + 1235 + sizeof(struct sk_buff **) * 1236 + (fpi->rx_ring + fpi->tx_ring); 1237 + 1238 + ndev = alloc_etherdev(privsize); 1239 + if (!ndev) { 1240 + ret = -ENOMEM; 1241 + goto out_free_fpi; 1242 + } 1243 + 1244 + SET_MODULE_OWNER(ndev); 1245 + dev_set_drvdata(&ofdev->dev, ndev); 1246 + 1247 + fep = netdev_priv(ndev); 1248 + fep->dev = &ofdev->dev; 1249 + fep->fpi = fpi; 1250 + fep->ops = match->data; 1251 + 1252 + ret = fep->ops->setup_data(ndev); 1253 + if (ret) 1254 + goto out_free_dev; 1255 + 1256 + fep->rx_skbuff = (struct sk_buff **)&fep[1]; 1257 + fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; 1258 + 1259 + spin_lock_init(&fep->lock); 1260 + spin_lock_init(&fep->tx_lock); 1261 + 1262 + mac_addr = of_get_mac_address(ofdev->node); 1263 + if (mac_addr) 1264 + memcpy(ndev->dev_addr, mac_addr, 6); 1265 + 1266 + ret = fep->ops->allocate_bd(ndev); 1267 + if (ret) 1268 + goto out_cleanup_data; 1269 + 1270 + fep->rx_bd_base = fep->ring_base; 1271 + fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; 1272 + 1273 + fep->tx_ring = fpi->tx_ring; 1274 + fep->rx_ring = fpi->rx_ring; 1275 + 1276 + ndev->open = fs_enet_open; 1277 + ndev->hard_start_xmit = fs_enet_start_xmit; 1278 + ndev->tx_timeout = fs_timeout; 1279 + ndev->watchdog_timeo = 2 * HZ; 1280 + ndev->stop = fs_enet_close; 1281 + ndev->get_stats = fs_enet_get_stats; 1282 + ndev->set_multicast_list = fs_set_multicast_list; 1283 + if (fpi->use_napi) { 1284 + ndev->poll = fs_enet_rx_napi; 1285 + ndev->weight = fpi->napi_weight; 1286 + } 1287 + ndev->ethtool_ops = &fs_ethtool_ops; 1288 + ndev->do_ioctl = fs_ioctl; 1289 + 1290 + init_timer(&fep->phy_timer_list); 1291 + 1292 + netif_carrier_off(ndev); 1293 + 1294 + ret = register_netdev(ndev); 1295 + if (ret) 1296 + goto out_free_bd; 1297 + 1298 + printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n", 1299 + ndev->name, 1300 + ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], 1301 + ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); 1302 + 1303 + return 0; 1304 + 1305 + out_free_bd: 1306 + fep->ops->free_bd(ndev); 1307 + out_cleanup_data: 1308 + fep->ops->cleanup_data(ndev); 1309 + out_free_dev: 1310 + free_netdev(ndev); 1311 + dev_set_drvdata(&ofdev->dev, NULL); 1312 + out_free_fpi: 1313 + kfree(fpi); 1314 + return ret; 1315 + } 1316 + 1317 + static int fs_enet_remove(struct of_device *ofdev) 1318 + { 1319 + struct net_device *ndev = dev_get_drvdata(&ofdev->dev); 1320 + struct fs_enet_private *fep = netdev_priv(ndev); 1321 + 1322 + unregister_netdev(ndev); 1323 + 1324 + fep->ops->free_bd(ndev); 1325 + fep->ops->cleanup_data(ndev); 1326 + dev_set_drvdata(fep->dev, NULL); 1327 + 1328 + free_netdev(ndev); 1329 + return 0; 1330 + } 1331 + 1332 + static struct of_device_id fs_enet_match[] = { 1333 + #ifdef CONFIG_FS_ENET_HAS_SCC 1334 + { 1335 + .compatible = "fsl,cpm1-scc-enet", 1336 + .data = (void *)&fs_scc_ops, 1337 + }, 1338 + #endif 1339 + #ifdef CONFIG_FS_ENET_HAS_FCC 1340 + { 1341 + .compatible = "fsl,cpm2-fcc-enet", 1342 + .data = (void *)&fs_fcc_ops, 1343 + }, 1344 + #endif 1345 + #ifdef CONFIG_FS_ENET_HAS_FEC 1346 + { 1347 + .compatible = "fsl,pq1-fec-enet", 1348 + .data = (void *)&fs_fec_ops, 1349 + }, 1350 + #endif 1351 + {} 1352 + }; 1353 + 1354 + static struct of_platform_driver fs_enet_driver = { 1355 + .name = "fs_enet", 1356 + .match_table = fs_enet_match, 1357 + .probe = fs_enet_probe, 1358 + .remove = fs_enet_remove, 1359 + }; 1360 + 1361 + static int __init fs_init(void) 1362 + { 1363 + int r = setup_immap(); 1364 + if (r != 0) 1365 + return r; 1366 + 1367 + r = of_register_platform_driver(&fs_enet_driver); 1368 + if (r != 0) 1369 + goto out; 1370 + 1371 + return 0; 1372 + 1373 + out: 1374 + cleanup_immap(); 1375 + return r; 1376 + } 1377 + 1378 + static void __exit fs_cleanup(void) 1379 + { 1380 + of_unregister_platform_driver(&fs_enet_driver); 1381 + cleanup_immap(); 1382 + } 1383 + #else 1177 1384 static int __devinit fs_enet_probe(struct device *dev) 1178 1385 { 1179 1386 struct net_device *ndev; ··· 1502 1279 driver_unregister(&fs_enet_scc_driver); 1503 1280 cleanup_immap(); 1504 1281 } 1282 + #endif 1505 1283 1506 1284 #ifdef CONFIG_NET_POLL_CONTROLLER 1507 1285 static void fs_enet_netpoll(struct net_device *dev)
+3 -52
drivers/net/fs_enet/fs_enet.h
··· 24 24 #include <asm/cpm2.h> 25 25 #endif 26 26 27 - /* This is used to operate with pins. 28 - Note that the actual port size may 29 - be different; cpm(s) handle it OK */ 30 - struct bb_info { 31 - u8 mdio_dat_msk; 32 - u8 mdio_dir_msk; 33 - u8 *mdio_dir; 34 - u8 *mdio_dat; 35 - u8 mdc_msk; 36 - u8 *mdc_dat; 37 - int delay; 38 - }; 39 - 40 27 /* hw driver ops */ 41 28 struct fs_ops { 42 29 int (*setup_data)(struct net_device *dev); ··· 72 85 #define ENET_RX_ALIGN 16 73 86 #define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE + ENET_RX_ALIGN - 1) 74 87 75 - struct fs_enet_mii_bus { 76 - struct list_head list; 77 - spinlock_t mii_lock; 78 - const struct fs_mii_bus_info *bus_info; 79 - int refs; 80 - u32 usage_map; 81 - 82 - int (*mii_read)(struct fs_enet_mii_bus *bus, 83 - int phy_id, int location); 84 - 85 - void (*mii_write)(struct fs_enet_mii_bus *bus, 86 - int phy_id, int location, int value); 87 - 88 - union { 89 - struct { 90 - unsigned int mii_speed; 91 - void *fecp; 92 - } fec; 93 - 94 - struct { 95 - /* note that the actual port size may */ 96 - /* be different; cpm(s) handle it OK */ 97 - u8 mdio_msk; 98 - u8 *mdio_dir; 99 - u8 *mdio_dat; 100 - u8 mdc_msk; 101 - u8 *mdc_dir; 102 - u8 *mdc_dat; 103 - } bitbang; 104 - 105 - struct { 106 - u16 lpa; 107 - } fixed; 108 - }; 109 - }; 110 - 111 88 struct fs_enet_private { 112 89 struct napi_struct napi; 113 90 struct device *dev; /* pointer back to the device (must be initialized first) */ 114 91 spinlock_t lock; /* during all ops except TX pckt processing */ 115 92 spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ 116 - const struct fs_platform_info *fpi; 93 + struct fs_platform_info *fpi; 117 94 const struct fs_ops *ops; 118 95 int rx_ring, tx_ring; 119 96 dma_addr_t ring_mem_addr; ··· 96 145 u32 msg_enable; 97 146 struct mii_if_info mii_if; 98 147 unsigned int last_mii_status; 99 - struct fs_enet_mii_bus *mii_bus; 100 148 int interrupt; 101 149 102 150 struct phy_device *phydev; ··· 137 187 }; 138 188 139 189 /***************************************************************************/ 190 + #ifndef CONFIG_PPC_CPM_NEW_BINDING 140 191 int fs_enet_mdio_bb_init(void); 141 - int fs_mii_fixed_init(struct fs_enet_mii_bus *bus); 142 192 int fs_enet_mdio_fec_init(void); 193 + #endif 143 194 144 195 void fs_init_bds(struct net_device *dev); 145 196 void fs_cleanup_bds(struct net_device *dev);
+65 -24
drivers/net/fs_enet/mac-fcc.c
··· 42 42 #include <asm/irq.h> 43 43 #include <asm/uaccess.h> 44 44 45 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 46 + #include <asm/of_device.h> 47 + #endif 48 + 45 49 #include "fs_enet.h" 46 50 47 51 /*************************************************/ ··· 78 74 79 75 #define MAX_CR_CMD_LOOPS 10000 80 76 81 - static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op) 77 + static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) 82 78 { 83 79 const struct fs_platform_info *fpi = fep->fpi; 84 80 cpm2_map_t *immap = fs_enet_immap; 85 81 cpm_cpm2_t *cpmp = &immap->im_cpm; 86 - u32 v; 87 82 int i; 88 83 89 - /* Currently I don't know what feature call will look like. But 90 - I guess there'd be something like do_cpm_cmd() which will require page & sblock */ 91 - v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op); 92 - W32(cpmp, cp_cpcr, v | CPM_CR_FLG); 84 + W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG); 93 85 for (i = 0; i < MAX_CR_CMD_LOOPS; i++) 94 86 if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) 95 - break; 87 + return 0; 96 88 97 - if (i >= MAX_CR_CMD_LOOPS) { 98 - printk(KERN_ERR "%s(): Not able to issue CPM command\n", 99 - __FUNCTION__); 100 - return 1; 101 - } 102 - 103 - return 0; 89 + printk(KERN_ERR "%s(): Not able to issue CPM command\n", 90 + __FUNCTION__); 91 + return 1; 104 92 } 105 93 106 94 static int do_pd_setup(struct fs_enet_private *fep) 107 95 { 96 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 97 + struct of_device *ofdev = to_of_device(fep->dev); 98 + struct fs_platform_info *fpi = fep->fpi; 99 + int ret = -EINVAL; 100 + 101 + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); 102 + if (fep->interrupt == NO_IRQ) 103 + goto out; 104 + 105 + fep->fcc.fccp = of_iomap(ofdev->node, 0); 106 + if (!fep->fcc.fccp) 107 + goto out; 108 + 109 + fep->fcc.ep = of_iomap(ofdev->node, 1); 110 + if (!fep->fcc.ep) 111 + goto out_fccp; 112 + 113 + fep->fcc.fcccp = of_iomap(ofdev->node, 2); 114 + if (!fep->fcc.fcccp) 115 + goto out_ep; 116 + 117 + fep->fcc.mem = (void *)cpm_dpalloc(128, 8); 118 + fpi->dpram_offset = (u32)cpm2_immr; 119 + if (IS_ERR_VALUE(fpi->dpram_offset)) { 120 + ret = fpi->dpram_offset; 121 + goto out_fcccp; 122 + } 123 + 124 + return 0; 125 + 126 + out_fcccp: 127 + iounmap(fep->fcc.fcccp); 128 + out_ep: 129 + iounmap(fep->fcc.ep); 130 + out_fccp: 131 + iounmap(fep->fcc.fccp); 132 + out: 133 + return ret; 134 + #else 108 135 struct platform_device *pdev = to_platform_device(fep->dev); 109 136 struct resource *r; 110 137 ··· 173 138 return -EINVAL; 174 139 175 140 return 0; 141 + #endif 176 142 } 177 143 178 144 #define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) ··· 184 148 static int setup_data(struct net_device *dev) 185 149 { 186 150 struct fs_enet_private *fep = netdev_priv(dev); 187 - const struct fs_platform_info *fpi = fep->fpi; 151 + #ifndef CONFIG_PPC_CPM_NEW_BINDING 152 + struct fs_platform_info *fpi = fep->fpi; 153 + 154 + fpi->cp_command = (fpi->cp_page << 26) | 155 + (fpi->cp_block << 21) | 156 + (12 << 6); 188 157 189 158 fep->fcc.idx = fs_get_fcc_index(fpi->fs_no); 190 159 if ((unsigned int)fep->fcc.idx >= 3) /* max 3 FCCs */ 191 160 return -EINVAL; 161 + #endif 192 162 193 163 if (do_pd_setup(fep) != 0) 194 164 return -EINVAL; ··· 268 226 W16(ep, fen_taddrh, taddrh); 269 227 W16(ep, fen_taddrm, taddrm); 270 228 W16(ep, fen_taddrl, taddrl); 271 - fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR); 229 + fcc_cr_cmd(fep, CPM_CR_SET_GADDR); 272 230 } 273 231 274 232 static void set_multicast_finish(struct net_device *dev) ··· 323 281 324 282 /* clear everything (slow & steady does it) */ 325 283 for (i = 0; i < sizeof(*ep); i++) 326 - out_8((char *)ep + i, 0); 284 + out_8((u8 __iomem *)ep + i, 0); 327 285 328 286 /* get physical address */ 329 287 rx_bd_base_phys = fep->ring_mem_addr; ··· 439 397 S8(fcccp, fcc_gfemr, 0x20); 440 398 } 441 399 442 - fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX); 400 + fcc_cr_cmd(fep, CPM_CR_INIT_TRX); 443 401 444 402 /* clear events */ 445 403 W16(fccp, fcc_fcce, 0xffff); ··· 557 515 { 558 516 struct fs_enet_private *fep = netdev_priv(dev); 559 517 560 - if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t)) 518 + if (*sizep < sizeof(fcc_t) + sizeof(fcc_enet_t) + 1) 561 519 return -EINVAL; 562 520 563 521 memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t)); 564 522 p = (char *)p + sizeof(fcc_t); 565 523 566 - memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t)); 567 - p = (char *)p + sizeof(fcc_c_t); 568 - 569 524 memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t)); 525 + p = (char *)p + sizeof(fcc_enet_t); 570 526 527 + memcpy_fromio(p, fep->fcc.fcccp, 1); 571 528 return 0; 572 529 } 573 530 574 531 int get_regs_len(struct net_device *dev) 575 532 { 576 - return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t); 533 + return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1; 577 534 } 578 535 579 536 /* Some transmit errors cause the transmitter to shut ··· 592 551 udelay(10); 593 552 S32(fccp, fcc_gfmr, FCC_GFMR_ENT); 594 553 595 - fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX); 554 + fcc_cr_cmd(fep, CPM_CR_RESTART_TX); 596 555 } 597 556 598 557 /*************************************************************************/
+18 -1
drivers/net/fs_enet/mac-fec.c
··· 43 43 #include <asm/commproc.h> 44 44 #endif 45 45 46 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 47 + #include <asm/of_device.h> 48 + #endif 49 + 46 50 #include "fs_enet.h" 47 51 #include "fec.h" 48 52 ··· 99 95 100 96 static int do_pd_setup(struct fs_enet_private *fep) 101 97 { 98 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 99 + struct of_device *ofdev = to_of_device(fep->dev); 100 + 101 + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); 102 + if (fep->interrupt == NO_IRQ) 103 + return -EINVAL; 104 + 105 + fep->fec.fecp = of_iomap(ofdev->node, 0); 106 + if (!fep->fcc.fccp) 107 + return -EINVAL; 108 + 109 + return 0; 110 + #else 102 111 struct platform_device *pdev = to_platform_device(fep->dev); 103 112 struct resource *r; 104 113 ··· 127 110 return -EINVAL; 128 111 129 112 return 0; 130 - 113 + #endif 131 114 } 132 115 133 116 #define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
+37 -16
drivers/net/fs_enet/mac-scc.c
··· 43 43 #include <asm/commproc.h> 44 44 #endif 45 45 46 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 47 + #include <asm/of_platform.h> 48 + #endif 49 + 46 50 #include "fs_enet.h" 47 51 48 52 /*************************************************/ ··· 93 89 94 90 static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) 95 91 { 96 - cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm; 97 - u32 v, ch; 98 - int i = 0; 92 + const struct fs_platform_info *fpi = fep->fpi; 93 + int i; 99 94 100 - ch = fep->scc.idx << 2; 101 - v = mk_cr_cmd(ch, op); 102 - W16(cpmp, cp_cpcr, v | CPM_CR_FLG); 95 + W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8)); 103 96 for (i = 0; i < MAX_CR_CMD_LOOPS; i++) 104 97 if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) 105 - break; 98 + return 0; 106 99 107 - if (i >= MAX_CR_CMD_LOOPS) { 108 - printk(KERN_ERR "%s(): Not able to issue CPM command\n", 109 - __FUNCTION__); 110 - return 1; 111 - } 112 - return 0; 100 + printk(KERN_ERR "%s(): Not able to issue CPM command\n", 101 + __FUNCTION__); 102 + return 1; 113 103 } 114 104 115 105 static int do_pd_setup(struct fs_enet_private *fep) 116 106 { 107 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 108 + struct of_device *ofdev = to_of_device(fep->dev); 109 + 110 + fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); 111 + if (fep->interrupt == NO_IRQ) 112 + return -EINVAL; 113 + 114 + fep->scc.sccp = of_iomap(ofdev->node, 0); 115 + if (!fep->scc.sccp) 116 + return -EINVAL; 117 + 118 + fep->scc.ep = of_iomap(ofdev->node, 1); 119 + if (!fep->scc.ep) { 120 + iounmap(fep->scc.sccp); 121 + return -EINVAL; 122 + } 123 + #else 117 124 struct platform_device *pdev = to_platform_device(fep->dev); 118 125 struct resource *r; 119 126 ··· 144 129 145 130 if (fep->scc.ep == NULL) 146 131 return -EINVAL; 132 + #endif 147 133 148 134 return 0; 149 135 } ··· 157 141 static int setup_data(struct net_device *dev) 158 142 { 159 143 struct fs_enet_private *fep = netdev_priv(dev); 160 - const struct fs_platform_info *fpi = fep->fpi; 144 + 145 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 146 + struct fs_platform_info *fpi = fep->fpi; 161 147 162 148 fep->scc.idx = fs_get_scc_index(fpi->fs_no); 163 - if ((unsigned int)fep->fcc.idx > 4) /* max 4 SCCs */ 149 + if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */ 164 150 return -EINVAL; 151 + 152 + fpi->cp_command = fep->fcc.idx << 6; 153 + #endif 165 154 166 155 do_pd_setup(fep); 167 156 ··· 175 154 176 155 fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK; 177 156 fep->ev_rx = SCC_RX_EVENT; 178 - fep->ev_tx = SCC_TX_EVENT; 157 + fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE; 179 158 fep->ev_err = SCC_ERR_EVENT_MSK; 180 159 181 160 return 0;
+208 -73
drivers/net/fs_enet/mii-bitbang.c
··· 13 13 */ 14 14 15 15 #include <linux/module.h> 16 - #include <linux/types.h> 17 - #include <linux/kernel.h> 18 - #include <linux/string.h> 19 - #include <linux/ptrace.h> 20 - #include <linux/errno.h> 21 16 #include <linux/ioport.h> 22 17 #include <linux/slab.h> 23 18 #include <linux/interrupt.h> ··· 20 25 #include <linux/delay.h> 21 26 #include <linux/netdevice.h> 22 27 #include <linux/etherdevice.h> 23 - #include <linux/skbuff.h> 24 - #include <linux/spinlock.h> 25 28 #include <linux/mii.h> 26 29 #include <linux/ethtool.h> 27 30 #include <linux/bitops.h> 28 31 #include <linux/platform_device.h> 29 32 30 - #include <asm/pgtable.h> 31 - #include <asm/irq.h> 32 - #include <asm/uaccess.h> 33 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 34 + #include <linux/of_platform.h> 35 + #endif 33 36 34 37 #include "fs_enet.h" 35 38 36 - static int bitbang_prep_bit(u8 **datp, u8 *mskp, 37 - struct fs_mii_bit *mii_bit) 39 + struct bb_info { 40 + __be32 __iomem *dir; 41 + __be32 __iomem *dat; 42 + u32 mdio_msk; 43 + u32 mdc_msk; 44 + int delay; 45 + }; 46 + 47 + /* FIXME: If any other users of GPIO crop up, then these will have to 48 + * have some sort of global synchronization to avoid races with other 49 + * pins on the same port. The ideal solution would probably be to 50 + * bind the ports to a GPIO driver, and have this be a client of it. 51 + */ 52 + static inline void bb_set(u32 __iomem *p, u32 m) 38 53 { 39 - void *dat; 40 - int adv; 41 - u8 msk; 42 - 43 - dat = (void*) mii_bit->offset; 44 - 45 - adv = mii_bit->bit >> 3; 46 - dat = (char *)dat + adv; 47 - 48 - msk = 1 << (7 - (mii_bit->bit & 7)); 49 - 50 - *datp = dat; 51 - *mskp = msk; 52 - 53 - return 0; 54 + out_be32(p, in_be32(p) | m); 54 55 } 55 56 56 - static inline void bb_set(u8 *p, u8 m) 57 + static inline void bb_clr(u32 __iomem *p, u32 m) 57 58 { 58 - out_8(p, in_8(p) | m); 59 + out_be32(p, in_be32(p) & ~m); 59 60 } 60 61 61 - static inline void bb_clr(u8 *p, u8 m) 62 + static inline int bb_read(u32 __iomem *p, u32 m) 62 63 { 63 - out_8(p, in_8(p) & ~m); 64 - } 65 - 66 - static inline int bb_read(u8 *p, u8 m) 67 - { 68 - return (in_8(p) & m) != 0; 64 + return (in_be32(p) & m) != 0; 69 65 } 70 66 71 67 static inline void mdio_active(struct bb_info *bitbang) 72 68 { 73 - bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk); 69 + bb_set(bitbang->dir, bitbang->mdio_msk); 74 70 } 75 71 76 - static inline void mdio_tristate(struct bb_info *bitbang ) 72 + static inline void mdio_tristate(struct bb_info *bitbang) 77 73 { 78 - bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk); 74 + bb_clr(bitbang->dir, bitbang->mdio_msk); 79 75 } 80 76 81 - static inline int mdio_read(struct bb_info *bitbang ) 77 + static inline int mdio_read(struct bb_info *bitbang) 82 78 { 83 - return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk); 79 + return bb_read(bitbang->dat, bitbang->mdio_msk); 84 80 } 85 81 86 - static inline void mdio(struct bb_info *bitbang , int what) 87 - { 88 - if (what) 89 - bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk); 90 - else 91 - bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk); 92 - } 93 - 94 - static inline void mdc(struct bb_info *bitbang , int what) 82 + static inline void mdio(struct bb_info *bitbang, int what) 95 83 { 96 84 if (what) 97 - bb_set(bitbang->mdc_dat, bitbang->mdc_msk); 85 + bb_set(bitbang->dat, bitbang->mdio_msk); 98 86 else 99 - bb_clr(bitbang->mdc_dat, bitbang->mdc_msk); 87 + bb_clr(bitbang->dat, bitbang->mdio_msk); 100 88 } 101 89 102 - static inline void mii_delay(struct bb_info *bitbang ) 90 + static inline void mdc(struct bb_info *bitbang, int what) 91 + { 92 + if (what) 93 + bb_set(bitbang->dat, bitbang->mdc_msk); 94 + else 95 + bb_clr(bitbang->dat, bitbang->mdc_msk); 96 + } 97 + 98 + static inline void mii_delay(struct bb_info *bitbang) 103 99 { 104 100 udelay(bitbang->delay); 105 101 } ··· 266 280 return 0; 267 281 } 268 282 269 - static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi) 283 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 284 + static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, 285 + struct device_node *np) 270 286 { 271 - int r; 287 + struct resource res; 288 + const u32 *data; 289 + int mdio_pin, mdc_pin, len; 290 + struct bb_info *bitbang = bus->priv; 272 291 292 + int ret = of_address_to_resource(np, 0, &res); 293 + if (ret) 294 + return ret; 295 + 296 + if (res.end - res.start < 13) 297 + return -ENODEV; 298 + 299 + /* This should really encode the pin number as well, but all 300 + * we get is an int, and the odds of multiple bitbang mdio buses 301 + * is low enough that it's not worth going too crazy. 302 + */ 303 + bus->id = res.start; 304 + 305 + data = of_get_property(np, "fsl,mdio-pin", &len); 306 + if (!data || len != 4) 307 + return -ENODEV; 308 + mdio_pin = *data; 309 + 310 + data = of_get_property(np, "fsl,mdc-pin", &len); 311 + if (!data || len != 4) 312 + return -ENODEV; 313 + mdc_pin = *data; 314 + 315 + bitbang->dir = ioremap(res.start, res.end - res.start + 1); 316 + if (!bitbang->dir) 317 + return -ENOMEM; 318 + 319 + bitbang->dat = bitbang->dir + 4; 320 + bitbang->mdio_msk = 1 << (31 - mdio_pin); 321 + bitbang->mdc_msk = 1 << (31 - mdc_pin); 322 + bitbang->delay = 1; /* 1 us between operations */ 323 + 324 + return 0; 325 + } 326 + 327 + static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) 328 + { 329 + const u32 *data; 330 + int len, id, irq; 331 + 332 + data = of_get_property(np, "reg", &len); 333 + if (!data || len != 4) 334 + return; 335 + 336 + id = *data; 337 + bus->phy_mask &= ~(1 << id); 338 + 339 + irq = of_irq_to_resource(np, 0, NULL); 340 + if (irq != NO_IRQ) 341 + bus->irq[id] = irq; 342 + } 343 + 344 + static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, 345 + const struct of_device_id *match) 346 + { 347 + struct device_node *np = NULL; 348 + struct mii_bus *new_bus; 349 + struct bb_info *bitbang; 350 + int ret = -ENOMEM; 351 + int i; 352 + 353 + new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); 354 + if (!new_bus) 355 + goto out; 356 + 357 + bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); 358 + if (!bitbang) 359 + goto out_free_bus; 360 + 361 + new_bus->priv = bitbang; 362 + new_bus->name = "CPM2 Bitbanged MII", 363 + new_bus->read = &fs_enet_mii_bb_read, 364 + new_bus->write = &fs_enet_mii_bb_write, 365 + new_bus->reset = &fs_enet_mii_bb_reset, 366 + 367 + ret = fs_mii_bitbang_init(new_bus, ofdev->node); 368 + if (ret) 369 + goto out_free_bitbang; 370 + 371 + new_bus->phy_mask = ~0; 372 + new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); 373 + if (!new_bus->irq) 374 + goto out_unmap_regs; 375 + 376 + for (i = 0; i < PHY_MAX_ADDR; i++) 377 + new_bus->irq[i] = -1; 378 + 379 + while ((np = of_get_next_child(ofdev->node, np))) 380 + if (!strcmp(np->type, "ethernet-phy")) 381 + add_phy(new_bus, np); 382 + 383 + new_bus->dev = &ofdev->dev; 384 + dev_set_drvdata(&ofdev->dev, new_bus); 385 + 386 + ret = mdiobus_register(new_bus); 387 + if (ret) 388 + goto out_free_irqs; 389 + 390 + return 0; 391 + 392 + out_free_irqs: 393 + dev_set_drvdata(&ofdev->dev, NULL); 394 + kfree(new_bus->irq); 395 + out_unmap_regs: 396 + iounmap(bitbang->dir); 397 + out_free_bitbang: 398 + kfree(bitbang); 399 + out_free_bus: 400 + kfree(new_bus); 401 + out: 402 + return ret; 403 + } 404 + 405 + static int fs_enet_mdio_remove(struct of_device *ofdev) 406 + { 407 + struct mii_bus *bus = dev_get_drvdata(&ofdev->dev); 408 + struct bb_info *bitbang = bus->priv; 409 + 410 + mdiobus_unregister(bus); 411 + dev_set_drvdata(&ofdev->dev, NULL); 412 + kfree(bus->irq); 413 + iounmap(bitbang->dir); 414 + kfree(bitbang); 415 + kfree(bus); 416 + 417 + return 0; 418 + } 419 + 420 + static struct of_device_id fs_enet_mdio_bb_match[] = { 421 + { 422 + .compatible = "fsl,cpm2-mdio-bitbang", 423 + }, 424 + {}, 425 + }; 426 + 427 + static struct of_platform_driver fs_enet_bb_mdio_driver = { 428 + .name = "fsl-bb-mdio", 429 + .match_table = fs_enet_mdio_bb_match, 430 + .probe = fs_enet_mdio_probe, 431 + .remove = fs_enet_mdio_remove, 432 + }; 433 + 434 + int fs_enet_mdio_bb_init(void) 435 + { 436 + return of_register_platform_driver(&fs_enet_bb_mdio_driver); 437 + } 438 + 439 + void fs_enet_mdio_bb_exit(void) 440 + { 441 + of_unregister_platform_driver(&fs_enet_bb_mdio_driver); 442 + } 443 + 444 + module_init(fs_enet_mdio_bb_init); 445 + module_exit(fs_enet_mdio_bb_exit); 446 + #else 447 + static int __devinit fs_mii_bitbang_init(struct bb_info *bitbang, 448 + struct fs_mii_bb_platform_info *fmpi) 449 + { 450 + bitbang->dir = (u32 __iomem *)fmpi->mdio_dir.offset; 451 + bitbang->dat = (u32 __iomem *)fmpi->mdio_dat.offset; 452 + bitbang->mdio_msk = 1U << (31 - fmpi->mdio_dat.bit); 453 + bitbang->mdc_msk = 1U << (31 - fmpi->mdc_dat.bit); 273 454 bitbang->delay = fmpi->delay; 274 - 275 - r = bitbang_prep_bit(&bitbang->mdio_dir, 276 - &bitbang->mdio_dir_msk, 277 - &fmpi->mdio_dir); 278 - if (r != 0) 279 - return r; 280 - 281 - r = bitbang_prep_bit(&bitbang->mdio_dat, 282 - &bitbang->mdio_dat_msk, 283 - &fmpi->mdio_dat); 284 - if (r != 0) 285 - return r; 286 - 287 - r = bitbang_prep_bit(&bitbang->mdc_dat, 288 - &bitbang->mdc_msk, 289 - &fmpi->mdc_dat); 290 - if (r != 0) 291 - return r; 292 455 293 456 return 0; 294 457 }
+142 -1
drivers/net/fs_enet/mii-fec.c
··· 36 36 #include <asm/irq.h> 37 37 #include <asm/uaccess.h> 38 38 39 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 40 + #include <asm/of_platform.h> 41 + #endif 42 + 39 43 #include "fs_enet.h" 40 44 #include "fec.h" 41 45 ··· 51 47 52 48 #define FEC_MII_LOOPS 10000 53 49 50 + #ifndef CONFIG_PPC_CPM_NEW_BINDING 54 51 static int match_has_phy (struct device *dev, void* data) 55 52 { 56 53 struct platform_device* pdev = container_of(dev, struct platform_device, dev); ··· 95 90 96 91 return 0; 97 92 } 93 + #endif 98 94 99 95 static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location) 100 96 { ··· 151 145 return 0; 152 146 } 153 147 148 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 149 + static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) 150 + { 151 + const u32 *data; 152 + int len, id, irq; 153 + 154 + data = of_get_property(np, "reg", &len); 155 + if (!data || len != 4) 156 + return; 157 + 158 + id = *data; 159 + bus->phy_mask &= ~(1 << id); 160 + 161 + irq = of_irq_to_resource(np, 0, NULL); 162 + if (irq != NO_IRQ) 163 + bus->irq[id] = irq; 164 + } 165 + 166 + static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, 167 + const struct of_device_id *match) 168 + { 169 + struct device_node *np = NULL; 170 + struct resource res; 171 + struct mii_bus *new_bus; 172 + struct fec_info *fec; 173 + int ret = -ENOMEM, i; 174 + 175 + new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); 176 + if (!new_bus) 177 + goto out; 178 + 179 + fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL); 180 + if (!fec) 181 + goto out_mii; 182 + 183 + new_bus->priv = fec; 184 + new_bus->name = "FEC MII Bus"; 185 + new_bus->read = &fs_enet_fec_mii_read; 186 + new_bus->write = &fs_enet_fec_mii_write; 187 + new_bus->reset = &fs_enet_fec_mii_reset; 188 + 189 + ret = of_address_to_resource(ofdev->node, 0, &res); 190 + if (ret) 191 + return ret; 192 + 193 + new_bus->id = res.start; 194 + 195 + fec->fecp = ioremap(res.start, res.end - res.start + 1); 196 + if (!fec->fecp) 197 + goto out_fec; 198 + 199 + fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1; 200 + 201 + setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); 202 + setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | 203 + FEC_ECNTRL_ETHER_EN); 204 + out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII); 205 + out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed); 206 + 207 + new_bus->phy_mask = ~0; 208 + new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); 209 + if (!new_bus->irq) 210 + goto out_unmap_regs; 211 + 212 + for (i = 0; i < PHY_MAX_ADDR; i++) 213 + new_bus->irq[i] = -1; 214 + 215 + while ((np = of_get_next_child(ofdev->node, np))) 216 + if (!strcmp(np->type, "ethernet-phy")) 217 + add_phy(new_bus, np); 218 + 219 + new_bus->dev = &ofdev->dev; 220 + dev_set_drvdata(&ofdev->dev, new_bus); 221 + 222 + ret = mdiobus_register(new_bus); 223 + if (ret) 224 + goto out_free_irqs; 225 + 226 + return 0; 227 + 228 + out_free_irqs: 229 + dev_set_drvdata(&ofdev->dev, NULL); 230 + kfree(new_bus->irq); 231 + out_unmap_regs: 232 + iounmap(fec->fecp); 233 + out_fec: 234 + kfree(fec); 235 + out_mii: 236 + kfree(new_bus); 237 + out: 238 + return ret; 239 + } 240 + 241 + static int fs_enet_mdio_remove(struct of_device *ofdev) 242 + { 243 + struct mii_bus *bus = dev_get_drvdata(&ofdev->dev); 244 + struct fec_info *fec = bus->priv; 245 + 246 + mdiobus_unregister(bus); 247 + dev_set_drvdata(&ofdev->dev, NULL); 248 + kfree(bus->irq); 249 + iounmap(fec->fecp); 250 + kfree(fec); 251 + kfree(bus); 252 + 253 + return 0; 254 + } 255 + 256 + static struct of_device_id fs_enet_mdio_fec_match[] = { 257 + { 258 + .compatible = "fsl,pq1-fec-mdio", 259 + }, 260 + {}, 261 + }; 262 + 263 + static struct of_platform_driver fs_enet_fec_mdio_driver = { 264 + .name = "fsl-fec-mdio", 265 + .match_table = fs_enet_mdio_fec_match, 266 + .probe = fs_enet_mdio_probe, 267 + .remove = fs_enet_mdio_remove, 268 + }; 269 + 270 + static int fs_enet_mdio_fec_init(void) 271 + { 272 + return of_register_platform_driver(&fs_enet_fec_mdio_driver); 273 + } 274 + 275 + static void fs_enet_mdio_fec_exit(void) 276 + { 277 + of_unregister_platform_driver(&fs_enet_fec_mdio_driver); 278 + } 279 + 280 + module_init(fs_enet_mdio_fec_init); 281 + module_exit(fs_enet_mdio_fec_exit); 282 + #else 154 283 static int __devinit fs_enet_fec_mdio_probe(struct device *dev) 155 284 { 156 285 struct platform_device *pdev = to_platform_device(dev); ··· 376 235 { 377 236 driver_unregister(&fs_enet_fec_mdio_driver); 378 237 } 379 - 238 + #endif
+5
include/linux/fs_enet_pd.h
··· 120 120 121 121 u32 cp_page; /* CPM page */ 122 122 u32 cp_block; /* CPM sblock */ 123 + u32 cp_command; /* CPM page/sblock/mcn */ 123 124 124 125 u32 clk_trx; /* some stuff for pins & mux configuration*/ 125 126 u32 clk_rx; ··· 135 134 u32 device_flags; 136 135 137 136 int phy_addr; /* the phy address (-1 no phy) */ 137 + #ifdef CONFIG_PPC_CPM_NEW_BINDING 138 + char bus_id[16]; 139 + #else 138 140 const char* bus_id; 141 + #endif 139 142 int phy_irq; /* the phy irq (if it exists) */ 140 143 141 144 const struct fs_mii_bus_info *bus_info;