* [PATCH 0/7] phylib: fix + drivers
@ 2012-11-18 12:46 Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
2012-11-20 8:39 ` [PATCH 0/7] phylib: fix + drivers Sascha Hauer
0 siblings, 2 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:46 UTC (permalink / raw)
To: barebox
HI,
Today we have a bug on the match the logic is inverted.
We are lucky as the generic Phy driver is not suppoed to match with
any device it work so fix it. Ensure the generic phy driver is
probe last if needed.
for mx53-loco we are lucky too the first phy found is the right one
The following changes since commit 272a5d738ab152347d67be062e8a4e771825493a:
at91rm9200ek: add spi support (2012-11-16 15:33:50 +0100)
are available in the git repository at:
git://git.jcrosoft.org/barebox.git delivery/phylib_fix
for you to fetch changes up to 5ea00036e330ea58293774a36d3ee5f9c1fbe895:
phylib: add micrel support (2012-11-16 23:11:16 +0800)
----------------------------------------------------------------
Jean-Christophe PLAGNIOL-VILLARD (7):
driver: introduce device_probe to manully probe a device
phylib: fix generic phy driver probe
mdio_bus: fix match
phylib: export phy_id via param
phylib: introduction of forced 100Mbps
phylib: add fixup support
phylib: add micrel support
drivers/base/driver.c | 23 +++++++++----
drivers/net/phy/Kconfig | 11 +++---
drivers/net/phy/Makefile | 2 +-
drivers/net/phy/generic.c | 36 --------------------
drivers/net/phy/mdio_bus.c | 28 ++++++++++-----
drivers/net/phy/micrel.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/phy/phy.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
include/driver.h | 5 +++
include/linux/micrel_phy.h | 30 ++++++++++++++++
include/linux/phy.h | 21 +++++++++++-
10 files changed, 400 insertions(+), 60 deletions(-)
delete mode 100644 drivers/net/phy/generic.c
create mode 100644 drivers/net/phy/micrel.c
create mode 100644 include/linux/micrel_phy.h
Best Regards,
J.
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/7] driver: introduce device_probe to manully probe a device
2012-11-18 12:46 [PATCH 0/7] phylib: fix + drivers Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 2/7] phylib: fix generic phy driver probe Jean-Christophe PLAGNIOL-VILLARD
` (5 more replies)
2012-11-20 8:39 ` [PATCH 0/7] phylib: fix + drivers Sascha Hauer
1 sibling, 6 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
This will expect a driver to be specified
This is needed by the phylib the probe the generic phy if not driver found
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/base/driver.c | 23 +++++++++++++++++------
include/driver.h | 5 +++++
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index dc2df91..1f4031a 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -75,6 +75,21 @@ int get_free_deviceid(const char *name_template)
};
}
+int device_probe(struct device_d *dev)
+{
+ int ret;
+
+ ret = dev->bus->probe(dev);
+ if (ret) {
+ dev_err(dev, "probe failed: %s\n", strerror(-ret));
+ return ret;
+ }
+
+ list_add(&dev->active, &active);
+
+ return 0;
+}
+
static int match(struct driver_d *drv, struct device_d *dev)
{
int ret;
@@ -86,13 +101,9 @@ static int match(struct driver_d *drv, struct device_d *dev)
if (dev->bus->match(dev, drv))
goto err_out;
- ret = dev->bus->probe(dev);
- if (ret) {
- dev_err(dev, "probe failed: %s\n", strerror(-ret));
+ ret = device_probe(dev);
+ if (ret)
goto err_out;
- }
-
- list_add(&dev->active, &active);
return 0;
err_out:
diff --git a/include/driver.h b/include/driver.h
index f8d815c..a085981 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -148,6 +148,11 @@ struct driver_d {
int register_driver(struct driver_d *);
int register_device(struct device_d *);
+/* manualy probe a device
+ * the driver need to be specified
+ */
+int device_probe(struct device_d *dev);
+
/* Unregister a device. This function can fail, e.g. when the device
* has children.
*/
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/7] phylib: fix generic phy driver probe
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 3/7] mdio_bus: fix match Jean-Christophe PLAGNIOL-VILLARD
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
the generic phy driver is used if no driver are found
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/phy/Kconfig | 8 ++------
drivers/net/phy/Makefile | 1 -
drivers/net/phy/generic.c | 36 ------------------------------------
drivers/net/phy/phy.c | 34 ++++++++++++++++++++++++++++++++--
4 files changed, 34 insertions(+), 45 deletions(-)
delete mode 100644 drivers/net/phy/generic.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 616b539..3f7c150 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -8,15 +8,11 @@ if PHYLIB
comment "MII PHY device drivers"
-config GENERIC_PHY
- bool "Drivers for the Generic PHYs"
- default y
-
-endif
-
config SMSC_PHY
bool "Drivers for SMSC PHYs"
---help---
Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
+endif
+
endmenu
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 0caeb70..dfc709a 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,3 +1,2 @@
obj-y += phy.o mdio_bus.o
-obj-$(CONFIG_GENERIC_PHY) += generic.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
diff --git a/drivers/net/phy/generic.c b/drivers/net/phy/generic.c
deleted file mode 100644
index 3f5f127..0000000
--- a/drivers/net/phy/generic.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * 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 Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- */
-
-#include <common.h>
-#include <linux/phy.h>
-#include <init.h>
-
-static struct phy_driver generic_phy = {
- .drv.name = "Generic PHY",
- .phy_id = PHY_ANY_UID,
- .phy_id_mask = PHY_ANY_UID,
- .features = 0,
-};
-
-static int generic_phy_register(void)
-{
- return phy_driver_register(&generic_phy);
-}
-device_initcall(generic_phy_register);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 4478d9f..2fd0440 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -19,6 +19,7 @@
#include <common.h>
#include <driver.h>
+#include <init.h>
#include <net.h>
#include <malloc.h>
#include <linux/phy.h>
@@ -27,6 +28,7 @@
#define PHY_AN_TIMEOUT 10
+static struct phy_driver genphy_driver;
static int genphy_config_init(struct phy_device *phydev);
int phy_update_status(struct phy_device *dev)
@@ -142,6 +144,21 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr)
return dev;
}
+static int phy_register_device(struct phy_device* dev)
+{
+ int ret;
+
+ ret = register_device(&dev->dev);
+ if (ret)
+ return ret;
+
+ if (dev->dev.driver)
+ return 0;
+
+ dev->dev.driver = &genphy_driver.drv;
+ return device_probe(&dev->dev);
+}
+
/* Automatically gets and returns the PHY device */
int phy_device_connect(struct eth_device *edev, struct mii_bus *bus, int addr,
void (*adjust_link) (struct eth_device *edev),
@@ -164,7 +181,7 @@ int phy_device_connect(struct eth_device *edev, struct mii_bus *bus, int addr,
dev->interface = interface;
dev->dev_flags = flags;
- ret = register_device(&dev->dev);
+ ret = phy_register_device(dev);
if (ret)
goto fail;
} else {
@@ -181,7 +198,7 @@ int phy_device_connect(struct eth_device *edev, struct mii_bus *bus, int addr,
dev->interface = interface;
dev->dev_flags = flags;
- ret = register_device(&dev->dev);
+ ret = phy_register_device(dev);
if (ret)
goto fail;
@@ -597,3 +614,16 @@ int phy_drivers_register(struct phy_driver *new_driver, int n)
}
return ret;
}
+
+static struct phy_driver genphy_driver = {
+ .drv.name = "Generic PHY",
+ .phy_id = PHY_ANY_UID,
+ .phy_id_mask = PHY_ANY_UID,
+ .features = 0,
+};
+
+static int generic_phy_register(void)
+{
+ return phy_driver_register(&genphy_driver);
+}
+device_initcall(generic_phy_register);
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/7] mdio_bus: fix match
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 2/7] phylib: fix generic phy driver probe Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 4/7] phylib: export phy_id via param Jean-Christophe PLAGNIOL-VILLARD
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
on barebox we have the weird way the return 0 true on bus match
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/phy/mdio_bus.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 35319b4..762adfe 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -106,7 +106,7 @@ static int mdio_bus_match(struct device_d *dev, struct driver_d *drv)
struct phy_device *phydev = to_phy_device(dev);
struct phy_driver *phydrv = to_phy_driver(drv);
- return ((phydrv->phy_id & phydrv->phy_id_mask) ==
+ return ((phydrv->phy_id & phydrv->phy_id_mask) !=
(phydev->phy_id & phydrv->phy_id_mask));
}
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/7] phylib: export phy_id via param
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 2/7] phylib: fix generic phy driver probe Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 3/7] mdio_bus: fix match Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 5/7] phylib: introduction of forced 100Mbps Jean-Christophe PLAGNIOL-VILLARD
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/phy/mdio_bus.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 762adfe..41c8a96 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -193,6 +193,9 @@ static int mdio_bus_probe(struct device_d *_dev)
sprintf(str, "%d", dev->addr);
dev_add_param_fixed(&dev->dev, "phy_addr", str);
+ sprintf(str, "0x%08x", dev->phy_id);
+ dev_add_param_fixed(&dev->dev, "phy_id", str);
+
dev->cdev.name = asprintf("phy%d", _dev->id);
dev->cdev.size = 64;
dev->cdev.ops = &phydev_ops;
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/7] phylib: introduction of forced 100Mbps
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
` (2 preceding siblings ...)
2012-11-18 12:49 ` [PATCH 4/7] phylib: export phy_id via param Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 6/7] phylib: add fixup support Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 7/7] phylib: add micrel support Jean-Christophe PLAGNIOL-VILLARD
5 siblings, 0 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/phy/mdio_bus.c | 4 ++++
include/linux/phy.h | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 41c8a96..3e79345 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -175,6 +175,10 @@ static int mdio_bus_probe(struct device_d *_dev)
dev->speed = SPEED_10;
dev->duplex = DUPLEX_FULL;
dev->autoneg = !AUTONEG_ENABLE;
+ } else if (dev->dev_flags & PHYLIB_FORCE_100) {
+ dev->speed = SPEED_100;
+ dev->duplex = DUPLEX_FULL;
+ dev->autoneg = !AUTONEG_ENABLE;
}
}
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 4f14dae..791d657 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -60,7 +60,8 @@ typedef enum {
#define MII_BUS_ID_SIZE (20 - 3)
#define PHYLIB_FORCE_10 (1 << 0)
-#define PHYLIB_FORCE_LINK (1 << 1)
+#define PHYLIB_FORCE_100 (1 << 1)
+#define PHYLIB_FORCE_LINK (1 << 2)
#define PHYLIB_CAPABLE_1000M (1 << 0)
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/7] phylib: add fixup support
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
` (3 preceding siblings ...)
2012-11-18 12:49 ` [PATCH 5/7] phylib: introduction of forced 100Mbps Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 7/7] phylib: add micrel support Jean-Christophe PLAGNIOL-VILLARD
5 siblings, 0 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
if board need specific phy fixup they can register it and then the code will
executed only if needed
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/phy/mdio_bus.c | 19 +++++----
drivers/net/phy/phy.c | 96 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 18 +++++++++
3 files changed, 125 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 3e79345..1d20bb0 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -153,6 +153,7 @@ static int mdio_bus_probe(struct device_d *_dev)
struct phy_device *dev = to_phy_device(_dev);
struct phy_driver *drv = to_phy_driver(_dev->driver);
+ int ret;
char str[16];
dev->attached_dev->phydev = dev;
@@ -160,14 +161,9 @@ static int mdio_bus_probe(struct device_d *_dev)
dev_add_child(dev->dev.parent, _dev);
if (drv->probe) {
- int ret;
-
ret = drv->probe(dev);
- if (ret) {
- dev->attached_dev->phydev = NULL;
- dev->attached_dev = NULL;
- return ret;
- }
+ if (ret)
+ goto err;
}
if (dev->dev_flags) {
@@ -188,7 +184,9 @@ static int mdio_bus_probe(struct device_d *_dev)
dev->supported = drv->features;
dev->advertising = drv->features;
- drv->config_init(dev);
+ ret = phy_init_hw(dev);
+ if (ret)
+ goto err;
/* Sanitize settings based on PHY capabilities */
if ((dev->supported & SUPPORTED_Autoneg) == 0)
@@ -208,6 +206,11 @@ static int mdio_bus_probe(struct device_d *_dev)
devfs_create(&dev->cdev);
return 0;
+
+err:
+ dev->attached_dev->phydev = NULL;
+ dev->attached_dev = NULL;
+ return ret;
}
static void mdio_bus_remove(struct device_d *_dev)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 2fd0440..59df742 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -55,6 +55,87 @@ int phy_update_status(struct phy_device *dev)
return 0;
}
+static LIST_HEAD(phy_fixup_list);
+
+/*
+ * Creates a new phy_fixup and adds it to the list
+ * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID)
+ * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY)
+ * It can also be PHY_ANY_UID
+ * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before
+ * comparison
+ * @run: The actual code to be run when a matching PHY is found
+ */
+int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
+ int (*run)(struct phy_device *))
+{
+ struct phy_fixup *fixup;
+
+ fixup = kzalloc(sizeof(struct phy_fixup), GFP_KERNEL);
+ if (!fixup)
+ return -ENOMEM;
+
+ strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id));
+ fixup->phy_uid = phy_uid;
+ fixup->phy_uid_mask = phy_uid_mask;
+ fixup->run = run;
+
+ list_add_tail(&fixup->list, &phy_fixup_list);
+
+ return 0;
+}
+
+/* Registers a fixup to be run on any PHY with the UID in phy_uid */
+int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
+ int (*run)(struct phy_device *))
+{
+ return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run);
+}
+
+/* Registers a fixup to be run on the PHY with id string bus_id */
+int phy_register_fixup_for_id(const char *bus_id,
+ int (*run)(struct phy_device *))
+{
+ return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run);
+}
+
+/*
+ * Returns 1 if fixup matches phydev in bus_id and phy_uid.
+ * Fixups can be set to match any in one or more fields.
+ */
+static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
+{
+ if (strcmp(fixup->bus_id, dev_name(&phydev->dev)) != 0)
+ if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
+ return 0;
+
+ if ((fixup->phy_uid & fixup->phy_uid_mask) !=
+ (phydev->phy_id & fixup->phy_uid_mask))
+ if (fixup->phy_uid != PHY_ANY_UID)
+ return 0;
+
+ return 1;
+}
+/* Runs any matching fixups for this phydev */
+int phy_scan_fixups(struct phy_device *phydev)
+{
+ struct phy_fixup *fixup;
+
+ list_for_each_entry(fixup, &phy_fixup_list, list) {
+ if (phy_needs_fixup(phydev, fixup)) {
+ int err;
+
+ err = fixup->run(phydev);
+
+ if (err < 0) {
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id)
{
struct phy_device *dev;
@@ -615,6 +696,21 @@ int phy_drivers_register(struct phy_driver *new_driver, int n)
return ret;
}
+int phy_init_hw(struct phy_device *phydev)
+{
+ struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver);
+ int ret;
+
+ if (!phydrv || !phydrv->config_init)
+ return 0;
+
+ ret = phy_scan_fixups(phydev);
+ if (ret < 0)
+ return ret;
+
+ return phydrv->config_init(phydev);
+}
+
static struct phy_driver genphy_driver = {
.drv.name = "Generic PHY",
.phy_id = PHY_ANY_UID,
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 791d657..b39eca5 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -226,10 +226,20 @@ struct phy_driver {
#define PHY_ANY_ID "MATCH ANY PHY"
#define PHY_ANY_UID 0xffffffff
+/* A Structure for boards to register fixups with the PHY Lib */
+struct phy_fixup {
+ struct list_head list;
+ char bus_id[20];
+ u32 phy_uid;
+ u32 phy_uid_mask;
+ int (*run)(struct phy_device *phydev);
+};
+
int phy_driver_register(struct phy_driver *drv);
int phy_drivers_register(struct phy_driver *new_driver, int n);
struct phy_device *get_phy_device(struct mii_bus *bus, int addr);
int phy_init(void);
+int phy_init_hw(struct phy_device *phydev);
/**
* phy_read - Convenience function for reading a given PHY register
@@ -267,5 +277,13 @@ int genphy_config_advert(struct phy_device *phydev);
int genphy_setup_forced(struct phy_device *phydev);
int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
+int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
+ int (*run)(struct phy_device *));
+int phy_register_fixup_for_id(const char *bus_id,
+ int (*run)(struct phy_device *));
+int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
+ int (*run)(struct phy_device *));
+int phy_scan_fixups(struct phy_device *phydev);
+
extern struct bus_type mdio_bus_type;
#endif /* __PHYDEV_H__ */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 7/7] phylib: add micrel support
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
` (4 preceding siblings ...)
2012-11-18 12:49 ` [PATCH 6/7] phylib: add fixup support Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-18 12:49 ` Jean-Christophe PLAGNIOL-VILLARD
5 siblings, 0 replies; 9+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2012-11-18 12:49 UTC (permalink / raw)
To: barebox
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/phy/Kconfig | 5 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/micrel.c | 174 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/micrel_phy.h | 30 ++++++++
4 files changed, 210 insertions(+)
create mode 100644 drivers/net/phy/micrel.c
create mode 100644 include/linux/micrel_phy.h
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 3f7c150..c75d73d 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -8,6 +8,11 @@ if PHYLIB
comment "MII PHY device drivers"
+config MICREL_PHY
+ bool "Driver for Micrel PHYs"
+ ---help---
+ Supports the KSZ9021, VSC8201, KS8001 PHYs.
+
config SMSC_PHY
bool "Drivers for SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index dfc709a..5f8191d 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,2 +1,3 @@
obj-y += phy.o mdio_bus.o
+obj-$(CONFIG_MICREL_PHY) += micrel.o
obj-$(CONFIG_SMSC_PHY) += smsc.o
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
new file mode 100644
index 0000000..0c6d43e
--- /dev/null
+++ b/drivers/net/phy/micrel.c
@@ -0,0 +1,174 @@
+/*
+ * drivers/net/phy/micrel.c
+ *
+ * Driver for Micrel PHYs
+ *
+ * Author: David J. Choi
+ *
+ * Copyright (c) 2010 Micrel, 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Support : ksz9021 1000/100/10 phy from Micrel
+ * ks8001, ks8737, ks8721, ks8041, ks8051 100/10 phy
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include <linux/micrel_phy.h>
+
+/* Operation Mode Strap Override */
+#define MII_KSZPHY_OMSO 0x16
+#define KSZPHY_OMSO_B_CAST_OFF (1 << 9)
+#define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1)
+#define KSZPHY_OMSO_MII_OVERRIDE (1 << 0)
+
+/* general PHY control reg in vendor specific block. */
+#define MII_KSZPHY_CTRL 0x1F
+/* bitmap of PHY register to set interrupt mode */
+#define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9)
+#define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14)
+#define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14)
+#define KSZ8051_RMII_50MHZ_CLK (1 << 7)
+
+static int kszphy_config_init(struct phy_device *phydev)
+{
+ return 0;
+}
+
+static int ksz8021_config_init(struct phy_device *phydev)
+{
+ const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE;
+ phy_write(phydev, MII_KSZPHY_OMSO, val);
+ return 0;
+}
+
+static int ks8051_config_init(struct phy_device *phydev)
+{
+ int regval;
+
+ if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) {
+ regval = phy_read(phydev, MII_KSZPHY_CTRL);
+ regval |= KSZ8051_RMII_50MHZ_CLK;
+ phy_write(phydev, MII_KSZPHY_CTRL, regval);
+ }
+
+ return 0;
+}
+
+#define KSZ8873MLL_GLOBAL_CONTROL_4 0x06
+#define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6)
+#define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4)
+int ksz8873mll_read_status(struct phy_device *phydev)
+{
+ int regval;
+
+ /* dummy read */
+ regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
+
+ regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
+
+ if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX)
+ phydev->duplex = DUPLEX_HALF;
+ else
+ phydev->duplex = DUPLEX_FULL;
+
+ if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_SPEED)
+ phydev->speed = SPEED_10;
+ else
+ phydev->speed = SPEED_100;
+
+ phydev->link = 1;
+ phydev->pause = phydev->asym_pause = 0;
+
+ return 0;
+}
+
+static int ksz8873mll_config_aneg(struct phy_device *phydev)
+{
+ return 0;
+}
+
+static int ksz8873mll_config_init(struct phy_device *phydev)
+{
+ phydev->autoneg = AUTONEG_DISABLE;
+ phydev->link = 1;
+
+ return 0;
+}
+
+static struct phy_driver ksphy_driver[] = {
+{
+ .phy_id = PHY_ID_KS8737,
+ .phy_id_mask = 0x00fffff0,
+ .drv.name = "Micrel KS8737",
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+ .config_init = kszphy_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+}, {
+ .phy_id = PHY_ID_KSZ8021,
+ .phy_id_mask = 0x00ffffff,
+ .drv.name = "Micrel KSZ8021",
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
+ .config_init = ksz8021_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+}, {
+ .phy_id = PHY_ID_KSZ8041,
+ .phy_id_mask = 0x00fffff0,
+ .drv.name = "Micrel KSZ8041",
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+ .config_init = kszphy_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+}, {
+ .phy_id = PHY_ID_KSZ8051,
+ .phy_id_mask = 0x00fffff0,
+ .drv.name = "Micrel KSZ8051",
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+ .config_init = ks8051_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+}, {
+ .phy_id = PHY_ID_KSZ8001,
+ .drv.name = "Micrel KSZ8001 or KS8721",
+ .phy_id_mask = 0x00ffffff,
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+ .config_init = kszphy_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+}, {
+ .phy_id = PHY_ID_KSZ9021,
+ .phy_id_mask = 0x000ffffe,
+ .drv.name = "Micrel KSZ9021 Gigabit PHY",
+ .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+ .config_init = kszphy_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+}, {
+ .phy_id = PHY_ID_KSZ8873MLL,
+ .phy_id_mask = 0x00fffff0,
+ .drv.name = "Micrel KSZ8873MLL Swithch",
+ .features = (SUPPORTED_Pause | SUPPORTED_Asym_Pause),
+ .config_init = ksz8873mll_config_init,
+ .config_aneg = ksz8873mll_config_aneg,
+ .read_status = ksz8873mll_read_status,
+} };
+
+static int ksphy_init(void)
+{
+ return phy_drivers_register(ksphy_driver,
+ ARRAY_SIZE(ksphy_driver));
+}
+fs_initcall(ksphy_init);
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
new file mode 100644
index 0000000..adfe8c0
--- /dev/null
+++ b/include/linux/micrel_phy.h
@@ -0,0 +1,30 @@
+/*
+ * include/linux/micrel_phy.h
+ *
+ * Micrel PHY IDs
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _MICREL_PHY_H
+#define _MICREL_PHY_H
+
+#define MICREL_PHY_ID_MASK 0x00fffff0
+
+#define PHY_ID_KSZ8873MLL 0x000e7237
+#define PHY_ID_KSZ9021 0x00221610
+#define PHY_ID_KS8737 0x00221720
+#define PHY_ID_KSZ8021 0x00221555
+#define PHY_ID_KSZ8041 0x00221510
+#define PHY_ID_KSZ8051 0x00221550
+/* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */
+#define PHY_ID_KSZ8001 0x0022161A
+
+/* struct phy_device dev_flags definitions */
+#define MICREL_PHY_50MHZ_CLK 0x00000001
+
+#endif /* _MICREL_PHY_H */
--
1.7.10.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/7] phylib: fix + drivers
2012-11-18 12:46 [PATCH 0/7] phylib: fix + drivers Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
@ 2012-11-20 8:39 ` Sascha Hauer
1 sibling, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2012-11-20 8:39 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox
On Sun, Nov 18, 2012 at 01:46:27PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> HI,
>
> Today we have a bug on the match the logic is inverted.
> We are lucky as the generic Phy driver is not suppoed to match with
> any device it work so fix it. Ensure the generic phy driver is
> probe last if needed.
>
> for mx53-loco we are lucky too the first phy found is the right one
>
> The following changes since commit 272a5d738ab152347d67be062e8a4e771825493a:
>
> at91rm9200ek: add spi support (2012-11-16 15:33:50 +0100)
>
> are available in the git repository at:
>
> git://git.jcrosoft.org/barebox.git delivery/phylib_fix
>
> for you to fetch changes up to 5ea00036e330ea58293774a36d3ee5f9c1fbe895:
>
> phylib: add micrel support (2012-11-16 23:11:16 +0800)
Applied, thanks
Sascha
>
> ----------------------------------------------------------------
> Jean-Christophe PLAGNIOL-VILLARD (7):
> driver: introduce device_probe to manully probe a device
> phylib: fix generic phy driver probe
> mdio_bus: fix match
> phylib: export phy_id via param
> phylib: introduction of forced 100Mbps
> phylib: add fixup support
> phylib: add micrel support
>
> drivers/base/driver.c | 23 +++++++++----
> drivers/net/phy/Kconfig | 11 +++---
> drivers/net/phy/Makefile | 2 +-
> drivers/net/phy/generic.c | 36 --------------------
> drivers/net/phy/mdio_bus.c | 28 ++++++++++-----
> drivers/net/phy/micrel.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> drivers/net/phy/phy.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> include/driver.h | 5 +++
> include/linux/micrel_phy.h | 30 ++++++++++++++++
> include/linux/phy.h | 21 +++++++++++-
> 10 files changed, 400 insertions(+), 60 deletions(-)
> delete mode 100644 drivers/net/phy/generic.c
> create mode 100644 drivers/net/phy/micrel.c
> create mode 100644 include/linux/micrel_phy.h
>
> Best Regards,
> J.
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-11-20 8:39 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-18 12:46 [PATCH 0/7] phylib: fix + drivers Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 1/7] driver: introduce device_probe to manully probe a device Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 2/7] phylib: fix generic phy driver probe Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 3/7] mdio_bus: fix match Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 4/7] phylib: export phy_id via param Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 5/7] phylib: introduction of forced 100Mbps Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 6/7] phylib: add fixup support Jean-Christophe PLAGNIOL-VILLARD
2012-11-18 12:49 ` [PATCH 7/7] phylib: add micrel support Jean-Christophe PLAGNIOL-VILLARD
2012-11-20 8:39 ` [PATCH 0/7] phylib: fix + drivers Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox