The patch makes possible to have mdio and mdc pins on different physical ports also for CONFIG_PPC_CPM_NEW_BINDING. To setup it in the device tree: reg = <10d40 14 10d60 14>; // mdc: 0x10d40, mdio: 0x10d60 or reg = <10d40 14>; // mdc and mdio have the same offset 10d40 The approach was taken from older version.
Signed-off-by: Sergej Stepanov <[EMAIL PROTECTED]> -- diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index b8e4a73..eea5feb 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -29,12 +29,16 @@ #include "fs_enet.h" -struct bb_info { - struct mdiobb_ctrl ctrl; +struct bb_port { __be32 __iomem *dir; __be32 __iomem *dat; - u32 mdio_msk; - u32 mdc_msk; + u32 msk; +}; + +struct bb_info { + struct mdiobb_ctrl ctrl; + struct bb_port mdc; + struct bb_port mdio; }; /* FIXME: If any other users of GPIO crop up, then these will have to @@ -62,18 +66,18 @@ static inline void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (dir) - bb_set(bitbang->dir, bitbang->mdio_msk); + bb_set(bitbang->mdio.dir, bitbang->mdio.msk); else - bb_clr(bitbang->dir, bitbang->mdio_msk); + bb_clr(bitbang->mdio.dir, bitbang->mdio.msk); /* Read back to flush the write. */ - in_be32(bitbang->dir); + in_be32(bitbang->mdio.dir); } static inline int mdio_read(struct mdiobb_ctrl *ctrl) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); - return bb_read(bitbang->dat, bitbang->mdio_msk); + return bb_read(bitbang->mdio.dat, bitbang->mdio.msk); } static inline void mdio(struct mdiobb_ctrl *ctrl, int what) @@ -81,12 +85,12 @@ static inline void mdio(struct mdiobb_ctrl *ctrl, int what) struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (what) - bb_set(bitbang->dat, bitbang->mdio_msk); + bb_set(bitbang->mdio.dat, bitbang->mdio.msk); else - bb_clr(bitbang->dat, bitbang->mdio_msk); + bb_clr(bitbang->mdio.dat, bitbang->mdio.msk); /* Read back to flush the write. */ - in_be32(bitbang->dat); + in_be32(bitbang->mdio.dat); } static inline void mdc(struct mdiobb_ctrl *ctrl, int what) @@ -94,12 +98,12 @@ static inline void mdc(struct mdiobb_ctrl *ctrl, int what) struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); if (what) - bb_set(bitbang->dat, bitbang->mdc_msk); + bb_set(bitbang->mdc.dat, bitbang->mdc.msk); else - bb_clr(bitbang->dat, bitbang->mdc_msk); + bb_clr(bitbang->mdc.dat, bitbang->mdc.msk); /* Read back to flush the write. */ - in_be32(bitbang->dat); + in_be32(bitbang->mdc.dat); } static struct mdiobb_ops bb_ops = { @@ -114,23 +118,23 @@ static struct mdiobb_ops bb_ops = { static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, struct device_node *np) { - struct resource res; + struct resource res[2]; const u32 *data; int mdio_pin, mdc_pin, len; struct bb_info *bitbang = bus->priv; - int ret = of_address_to_resource(np, 0, &res); + int ret = of_address_to_resource(np, 0, &res[0]); if (ret) return ret; - if (res.end - res.start < 13) + if (res[0].end - res[0].start < 13) return -ENODEV; /* This should really encode the pin number as well, but all * we get is an int, and the odds of multiple bitbang mdio buses * is low enough that it's not worth going too crazy. */ - bus->id = res.start; + bus->id = res[0].start; data = of_get_property(np, "fsl,mdio-pin", &len); if (!data || len != 4) @@ -142,15 +146,32 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, return -ENODEV; mdc_pin = *data; - bitbang->dir = ioremap(res.start, res.end - res.start + 1); - if (!bitbang->dir) + bitbang->mdc.dir = ioremap(res[0].start, res[0].end - res[0].start + 1); + if (!bitbang->mdc.dir) return -ENOMEM; - bitbang->dat = bitbang->dir + 4; - bitbang->mdio_msk = 1 << (31 - mdio_pin); - bitbang->mdc_msk = 1 << (31 - mdc_pin); + bitbang->mdc.dat = bitbang->mdc.dir + 4; + if( !of_address_to_resource(np, 1, &res[1])) { + if (res[1].end - res[1].start < 13) + goto bad_resource; + bitbang->mdio.dir = ioremap(res[1].start, res[1].end - res[1].start + 1); + if (!bitbang->mdio.dir) + goto unmap_and_exit; + bitbang->mdio.dat = bitbang->mdio.dir + 4; + } else { + bitbang->mdio.dir = bitbang->mdc.dir; + bitbang->mdio.dat = bitbang->mdc.dat; + } + bitbang->mdio.msk = 1 << (31 - mdio_pin); + bitbang->mdc.msk = 1 << (31 - mdc_pin); return 0; +bad_resource: + iounmap(bitbang->mdc.dir); + return -ENODEV; +unmap_and_exit: + iounmap(bitbang->mdc.dir); + return -ENOMEM; } static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) @@ -220,7 +241,9 @@ out_free_irqs: dev_set_drvdata(&ofdev->dev, NULL); kfree(new_bus->irq); out_unmap_regs: - iounmap(bitbang->dir); + if (bitbang->mdio.dir != bitbang->mdc.dir) + iounmap(bitbang->mdio.dir); + iounmap(bitbang->mdc.dir); out_free_bus: kfree(new_bus); out_free_priv: @@ -238,7 +261,9 @@ static int fs_enet_mdio_remove(struct of_device *ofdev) free_mdio_bitbang(bus); dev_set_drvdata(&ofdev->dev, NULL); kfree(bus->irq); - iounmap(bitbang->dir); + if ( bitbang->mdio.dir != bitbang->mdc.dir) + iounmap(bitbang->mdio.dir); + iounmap(bitbang->mdc.dir); kfree(bitbang); kfree(bus); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html