diff options
-rw-r--r-- | drivers/net/fsl_pq_mdio.c | 59 | ||||
-rw-r--r-- | drivers/net/fsl_pq_mdio.h | 11 |
2 files changed, 57 insertions, 13 deletions
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 <afleming@freescale.com> + * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> * - * 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); diff --git a/drivers/net/fsl_pq_mdio.h b/drivers/net/fsl_pq_mdio.h index 36dad527410..1f7d865cedb 100644 --- a/drivers/net/fsl_pq_mdio.h +++ b/drivers/net/fsl_pq_mdio.h @@ -3,8 +3,9 @@ * Driver for the MDIO bus controller on Freescale PowerQUICC processors * * Author: Andy Fleming + * Modifier: Sandeep Gopalpet * - * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc. + * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -23,6 +24,12 @@ #define MII_READ_COMMAND 0x00000001 struct fsl_pq_mdio { + u8 res1[16]; + u32 ieventm; /* MDIO Interrupt event register (for etsec2)*/ + u32 imaskm; /* MDIO Interrupt mask register (for etsec2)*/ + u8 res2[4]; + u32 emapm; /* MDIO Event mapping register (for etsec2)*/ + u8 res3[1280]; u32 miimcfg; /* MII management configuration reg */ u32 miimcom; /* MII management command reg */ u32 miimadd; /* MII management address reg */ @@ -31,9 +38,9 @@ struct fsl_pq_mdio { u32 miimind; /* MII management indication reg */ u8 reserved[28]; /* Space holder */ u32 utbipar; /* TBI phy address reg (only on UCC) */ + u8 res4[2728]; } __attribute__ ((packed)); - int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum); int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, |