mdio: Add support for mdio drivers.

Not all devices on an MDIO bus are PHYs. Meaning not all MDIO drivers
are PHY drivers. Add support for generic MDIO drivers.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 0690359..75f7fad 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -15,6 +15,7 @@
 
 struct mdio_device {
 	struct device dev;
+
 	const struct dev_pm_ops *pm_ops;
 	struct mii_bus *bus;
 	int (*bus_match)(struct device *dev, struct device_driver *drv);
@@ -24,7 +25,37 @@
 };
 #define to_mdio_device(d) container_of(d, struct mdio_device, dev)
 
+/* struct mdio_driver_common: Common to all MDIO drivers */
+struct mdio_driver_common {
+	struct device_driver driver;
+	int flags;
+};
 #define MDIO_DEVICE_FLAG_PHY		1
+#define to_mdio_common_driver(d) \
+	container_of(d, struct mdio_driver_common, driver)
+
+/* struct mdio_driver: Generic MDIO driver */
+struct mdio_driver {
+	struct mdio_driver_common mdiodrv;
+
+	/*
+	 * Called during discovery.  Used to set
+	 * up device-specific structures, if any
+	 */
+	int (*probe)(struct mdio_device *mdiodev);
+
+	/* Clears up any memory if needed */
+	void (*remove)(struct mdio_device *mdiodev);
+};
+#define to_mdio_driver(d)						\
+	container_of(to_mdio_common_driver(d), struct mdio_driver, mdiodrv)
+
+void mdio_device_free(struct mdio_device *mdiodev);
+struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr);
+int mdio_device_register(struct mdio_device *mdiodev);
+void mdio_device_remove(struct mdio_device *mdiodev);
+int mdio_driver_register(struct mdio_driver *drv);
+void mdio_driver_unregister(struct mdio_driver *drv);
 
 static inline bool mdio_phy_id_is_c45(int phy_id)
 {
@@ -197,4 +228,23 @@
 bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
 struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr);
 
+/**
+ * module_mdio_driver() - Helper macro for registering mdio drivers
+ *
+ * Helper macro for MDIO drivers which do not do anything special in module
+ * init/exit. Each module may only use this macro once, and calling it
+ * replaces module_init() and module_exit().
+ */
+#define mdio_module_driver(_mdio_driver)				\
+static int __init mdio_module_init(void)				\
+{									\
+	return mdio_driver_register(&_mdio_driver);			\
+}									\
+module_init(mdio_module_init);						\
+static void __exit mdio_module_exit(void)				\
+{									\
+	mdio_driver_unregister(&_mdio_driver);				\
+}									\
+module_exit(mdio_module_exit)
+
 #endif /* __LINUX_MDIO_H__ */