* Copyright (c) 2004 Freescale Semiconductor, Inc.
  */
 #include <linux/bitops.h>
+#include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #define RTL821x_PAGE_SELECT                    0x1f
 
 #define RTL8211F_PHYCR1                                0x18
+#define RTL8211F_PHYCR2                                0x19
 #define RTL8211F_INSR                          0x1d
 
 #define RTL8211F_TX_DELAY                      BIT(8)
 #define RTL8211E_TX_DELAY                      BIT(12)
 #define RTL8211E_RX_DELAY                      BIT(11)
 
+#define RTL8211F_CLKOUT_EN                     BIT(0)
+
 #define RTL8201F_ISR                           0x1e
 #define RTL8201F_ISR_ANERR                     BIT(15)
 #define RTL8201F_ISR_DUPLEX                    BIT(13)
 MODULE_AUTHOR("Johnson Leung");
 MODULE_LICENSE("GPL");
 
+struct rtl821x_priv {
+       u16 phycr2;
+};
+
 static int rtl821x_read_page(struct phy_device *phydev)
 {
        return __phy_read(phydev, RTL821x_PAGE_SELECT);
        return __phy_write(phydev, RTL821x_PAGE_SELECT, page);
 }
 
+static int rtl821x_probe(struct phy_device *phydev)
+{
+       struct device *dev = &phydev->mdio.dev;
+       struct rtl821x_priv *priv;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->phycr2 = phy_read_paged(phydev, 0xa43, RTL8211F_PHYCR2);
+       if (priv->phycr2 < 0)
+               return priv->phycr2;
+
+       priv->phycr2 &= RTL8211F_CLKOUT_EN;
+       if (of_property_read_bool(dev->of_node, "realtek,clkout-disable"))
+               priv->phycr2 &= ~RTL8211F_CLKOUT_EN;
+
+       phydev->priv = priv;
+
+       return 0;
+}
+
 static int rtl8201_ack_interrupt(struct phy_device *phydev)
 {
        int err;
 
 static int rtl8211f_config_init(struct phy_device *phydev)
 {
+       struct rtl821x_priv *priv = phydev->priv;
        struct device *dev = &phydev->mdio.dev;
        u16 val_txdly, val_rxdly;
        u16 val;
                        val_rxdly ? "enabled" : "disabled");
        }
 
-       return 0;
+       ret = phy_modify_paged(phydev, 0xa43, RTL8211F_PHYCR2,
+                              RTL8211F_CLKOUT_EN, priv->phycr2);
+       if (ret < 0) {
+               dev_err(dev, "clkout configuration failed: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+
+       return genphy_soft_reset(phydev);
 }
 
 static int rtl8211e_config_init(struct phy_device *phydev)
        }, {
                PHY_ID_MATCH_EXACT(0x001cc916),
                .name           = "RTL8211F Gigabit Ethernet",
+               .probe          = rtl821x_probe,
                .config_init    = &rtl8211f_config_init,
                .read_status    = rtlgen_read_status,
                .config_intr    = &rtl8211f_config_intr,