From 1d2397d742b7a2b39b2f09dd9da3b9d1463f55e9 Mon Sep 17 00:00:00 2001 From: Sandeep Gopalpet Date: Mon, 2 Nov 2009 07:03:22 +0000 Subject: fsl_pq_mdio: Add Suport for etsec2.0 devices. This patch adds mdio support for etsec2.0 devices. Modified the fsl_pq_mdio structure to include the new mdio members. Signed-off-by: Sandeep Gopalpet Signed-off-by: David S. Miller --- drivers/net/fsl_pq_mdio.c | 59 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 11 deletions(-) (limited to 'drivers/net/fsl_pq_mdio.c') diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 6ac46486697..4065b7c01ec 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -3,8 +3,9 @@ * Provides Bus interface for MIIM regs * * Author: Andy Fleming + * Modifier: Sandeep Gopalpet * - * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc. + * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc. * * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips) * @@ -189,19 +190,29 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) -static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) +static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) { struct gfar __iomem *enet_regs; + u32 __iomem *ioremap_tbipa; + u64 addr, size; /* * This is mildly evil, but so is our hardware for doing this. * Also, we have to cast back to struct gfar because of * definition weirdness done in gianfar.h. */ - enet_regs = (struct gfar __iomem *) - ((char __iomem *)regs - offsetof(struct gfar, gfar_mii_regs)); - - return &enet_regs->tbipa; + if(of_device_is_compatible(np, "fsl,gianfar-mdio") || + of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "gianfar")) { + enet_regs = (struct gfar __iomem *)regs; + return &enet_regs->tbipa; + } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || + of_device_is_compatible(np, "fsl,etsec2-tbi")) { + addr = of_translate_address(np, of_get_address(np, 1, &size, NULL)); + ioremap_tbipa = ioremap(addr, size); + return ioremap_tbipa; + } else + return NULL; } #endif @@ -250,11 +261,11 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, { struct device_node *np = ofdev->node; struct device_node *tbi; - struct fsl_pq_mdio __iomem *regs; + struct fsl_pq_mdio __iomem *regs = NULL; u32 __iomem *tbipa; struct mii_bus *new_bus; int tbiaddr = -1; - u64 addr, size; + u64 addr = 0, size = 0, ioremap_miimcfg = 0; int err = 0; new_bus = mdiobus_alloc(); @@ -268,8 +279,22 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, fsl_pq_mdio_bus_name(new_bus->id, np); /* Set the PHY base address */ - addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); - regs = ioremap(addr, size); + if (of_device_is_compatible(np,"fsl,gianfar-mdio") || + of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "fsl,ucc-mdio") || + of_device_is_compatible(np,"ucc_geth_phy" )) { + addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); + ioremap_miimcfg = container_of(addr, struct fsl_pq_mdio, miimcfg); + regs = ioremap(ioremap_miimcfg, size + + offsetof(struct fsl_pq_mdio, miimcfg)); + } else if (of_device_is_compatible(np,"fsl,etsec2-mdio") || + of_device_is_compatible(np, "fsl,etsec2-tbi")) { + addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); + regs = ioremap(addr, size); + } else { + err = -EINVAL; + goto err_free_bus; + } if (NULL == regs) { err = -ENOMEM; @@ -290,9 +315,15 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, if (of_device_is_compatible(np, "fsl,gianfar-mdio") || of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "fsl,etsec2-mdio") || + of_device_is_compatible(np, "fsl,etsec2-tbi") || of_device_is_compatible(np, "gianfar")) { #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) - tbipa = get_gfar_tbipa(regs); + tbipa = get_gfar_tbipa(regs, np); + if (!tbipa) { + err = -EINVAL; + goto err_free_irqs; + } #else err = -ENODEV; goto err_free_irqs; @@ -405,6 +436,12 @@ static struct of_device_id fsl_pq_mdio_match[] = { { .compatible = "fsl,gianfar-mdio", }, + { + .compatible = "fsl,etsec2-tbi", + }, + { + .compatible = "fsl,etsec2-mdio", + }, {}, }; MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); -- cgit v1.2.3-70-g09d2 From 2951d64e70652bb11636a5a1f1f2ea295a043f94 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 4 Nov 2009 12:52:56 +0000 Subject: fsl_pq_mdio: Fix compiler/sparse warnings (part 1) commit 1d2397d742b7a2b39b2f09dd9da3b9d1463f55e9 ("fsl_pq_mdio: Add Suport for etsec2.0 devices") introduced the following warnings: CHECK fsl_pq_mdio.c fsl_pq_mdio.c:287:22: warning: incorrect type in initializer (different base types) fsl_pq_mdio.c:287:22: expected unknown type 11 const *__mptr fsl_pq_mdio.c:287:22: got unsigned long long [unsigned] [assigned] [usertype] addr fsl_pq_mdio.c:287:19: warning: incorrect type in assignment (different base types) fsl_pq_mdio.c:287:19: expected unsigned long long [unsigned] [usertype] ioremap_miimcfg fsl_pq_mdio.c:287:19: got struct fsl_pq_mdio * CC fsl_pq_mdio.o fsl_pq_mdio.c: In function 'fsl_pq_mdio_probe': fsl_pq_mdio.c:287: warning: initialization makes pointer from integer without a cast fsl_pq_mdio.c:287: warning: assignment makes integer from pointer without a cast These warnings are not easy to fix without ugly __force casts. So, instead of introducing the casts, rework the code to substitute an offset from an already mapped area. This makes the code a lot simpler and less duplicated. Plus, from now on we don't actually map reserved registers on non-etsec2.0 devices, so we have more chances to catch programming errors. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/fsl_pq_mdio.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers/net/fsl_pq_mdio.c') diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 4065b7c01ec..fb8c8d9dcf2 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -262,10 +262,11 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, struct device_node *np = ofdev->node; struct device_node *tbi; struct fsl_pq_mdio __iomem *regs = NULL; + void __iomem *map; u32 __iomem *tbipa; struct mii_bus *new_bus; int tbiaddr = -1; - u64 addr = 0, size = 0, ioremap_miimcfg = 0; + u64 addr = 0, size = 0; int err = 0; new_bus = mdiobus_alloc(); @@ -279,28 +280,20 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, fsl_pq_mdio_bus_name(new_bus->id, np); /* Set the PHY base address */ - if (of_device_is_compatible(np,"fsl,gianfar-mdio") || - of_device_is_compatible(np, "fsl,gianfar-tbi") || - of_device_is_compatible(np, "fsl,ucc-mdio") || - of_device_is_compatible(np,"ucc_geth_phy" )) { - addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); - ioremap_miimcfg = container_of(addr, struct fsl_pq_mdio, miimcfg); - regs = ioremap(ioremap_miimcfg, size + - offsetof(struct fsl_pq_mdio, miimcfg)); - } else if (of_device_is_compatible(np,"fsl,etsec2-mdio") || - of_device_is_compatible(np, "fsl,etsec2-tbi")) { - addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); - regs = ioremap(addr, size); - } else { - err = -EINVAL; - goto err_free_bus; - } - - if (NULL == regs) { + addr = of_translate_address(np, of_get_address(np, 0, &size, NULL)); + map = ioremap(addr, size); + if (!map) { err = -ENOMEM; goto err_free_bus; } + if (of_device_is_compatible(np, "fsl,gianfar-mdio") || + of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "fsl,ucc-mdio") || + of_device_is_compatible(np, "ucc_geth_phy")) + map -= offsetof(struct fsl_pq_mdio, miimcfg); + regs = map; + new_bus->priv = (void __force *)regs; new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 6748f60b948230684fe3f295220e76679c5efc52 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 4 Nov 2009 12:52:57 +0000 Subject: fsl_pq_mdio: Fix compiler/sparse warnings (part 2) This patch fixes following warnings: fsl_pq_mdio.c:112:38: warning: cast adds address space to expression () fsl_pq_mdio.c:124:38: warning: cast adds address space to expression () fsl_pq_mdio.c:133:38: warning: cast adds address space to expression () fsl_pq_mdio.c:414:11: warning: cast adds address space to expression () Instead of adding __force all over the place, introduce convenient fsl_pq_mdio_get_regs() call that does the ugly casting just once. Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/fsl_pq_mdio.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/net/fsl_pq_mdio.c') diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index fb8c8d9dcf2..b2ca596760f 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -103,13 +103,18 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, return value; } +static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) +{ + return (void __iomem __force *)bus->priv; +} + /* * Write value to the PHY at mii_id at register regnum, * on the bus, waiting until the write is done before returning. */ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) { - struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Write to the local MII regs */ return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value)); @@ -121,7 +126,7 @@ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) */ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { - struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Read the local MII regs */ return(fsl_pq_local_mdio_read(regs, mii_id, regnum)); @@ -130,7 +135,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) /* Reset the MIIM registers, and wait for the bus to free */ static int fsl_pq_mdio_reset(struct mii_bus *bus) { - struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); int timeout = PHY_INIT_TIMEOUT; mutex_lock(&bus->mdio_lock); @@ -404,7 +409,7 @@ static int fsl_pq_mdio_remove(struct of_device *ofdev) dev_set_drvdata(device, NULL); - iounmap((void __iomem *)bus->priv); + iounmap(fsl_pq_mdio_get_regs(bus)); bus->priv = NULL; mdiobus_free(bus); -- cgit v1.2.3-70-g09d2