generic: rtl8366_smi: use __rtl8366_smi_cleanup instead of gpio_free calls
[openwrt.git] / target / linux / generic / files / drivers / net / phy / rtl8366_smi.c
index c3fde0d..1288db1 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/skbuff.h>
 #include <linux/rtl8366.h>
 
-#ifdef CONFIG_RTL8366S_PHY_DEBUG_FS
+#ifdef CONFIG_RTL8366_SMI_DEBUG_FS
 #include <linux/debugfs.h>
 #endif
 
@@ -157,6 +157,12 @@ static int rtl8366_smi_write_byte(struct rtl8366_smi *smi, u8 data)
        return rtl8366_smi_wait_for_ack(smi);
 }
 
+static int rtl8366_smi_write_byte_noack(struct rtl8366_smi *smi, u8 data)
+{
+       rtl8366_smi_write_bits(smi, data, 8);
+       return 0;
+}
+
 static int rtl8366_smi_read_byte0(struct rtl8366_smi *smi, u8 *data)
 {
        u32 t;
@@ -228,7 +234,8 @@ int rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
 }
 EXPORT_SYMBOL_GPL(rtl8366_smi_read_reg);
 
-int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
+static int __rtl8366_smi_write_reg(struct rtl8366_smi *smi,
+                                  u32 addr, u32 data, bool ack)
 {
        unsigned long flags;
        int ret;
@@ -258,7 +265,10 @@ int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
                goto out;
 
        /* write DATA[15:8] */
-       ret = rtl8366_smi_write_byte(smi, data >> 8);
+       if (ack)
+               ret = rtl8366_smi_write_byte(smi, data >> 8);
+       else
+               ret = rtl8366_smi_write_byte_noack(smi, data >> 8);
        if (ret)
                goto out;
 
@@ -270,8 +280,19 @@ int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
 
        return ret;
 }
+
+int rtl8366_smi_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
+{
+       return __rtl8366_smi_write_reg(smi, addr, data, true);
+}
 EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg);
 
+int rtl8366_smi_write_reg_noack(struct rtl8366_smi *smi, u32 addr, u32 data)
+{
+       return __rtl8366_smi_write_reg(smi, addr, data, false);
+}
+EXPORT_SYMBOL_GPL(rtl8366_smi_write_reg_noack);
+
 int rtl8366_smi_rmwr(struct rtl8366_smi *smi, u32 addr, u32 mask, u32 data)
 {
        u32 t;
@@ -558,7 +579,7 @@ static int rtl8366_init_vlan(struct rtl8366_smi *smi)
        return rtl8366_enable_vlan(smi, 1);
 }
 
-#ifdef CONFIG_RTL8366S_PHY_DEBUG_FS
+#ifdef CONFIG_RTL8366_SMI_DEBUG_FS
 int rtl8366_debugfs_open(struct inode *inode, struct file *file)
 {
        file->private_data = inode->i_private;
@@ -869,7 +890,7 @@ static void rtl8366_debugfs_remove(struct rtl8366_smi *smi)
 #else
 static inline void rtl8366_debugfs_init(struct rtl8366_smi *smi) {}
 static inline void rtl8366_debugfs_remove(struct rtl8366_smi *smi) {}
-#endif /* CONFIG_RTL8366S_PHY_DEBUG_FS */
+#endif /* CONFIG_RTL8366_SMI_DEBUG_FS */
 
 static int rtl8366_smi_mii_init(struct rtl8366_smi *smi)
 {
@@ -912,6 +933,31 @@ static void rtl8366_smi_mii_cleanup(struct rtl8366_smi *smi)
        mdiobus_free(smi->mii_bus);
 }
 
+int rtl8366_sw_reset_switch(struct switch_dev *dev)
+{
+       struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
+       int err;
+
+       err = smi->ops->reset_chip(smi);
+       if (err)
+               return err;
+
+       err = smi->ops->setup(smi);
+       if (err)
+               return err;
+
+       err = rtl8366_reset_vlan(smi);
+       if (err)
+               return err;
+
+       err = rtl8366_enable_vlan(smi, 1);
+       if (err)
+               return err;
+
+       return rtl8366_enable_all_ports(smi, 1);
+}
+EXPORT_SYMBOL_GPL(rtl8366_sw_reset_switch);
+
 int rtl8366_sw_get_port_pvid(struct switch_dev *dev, int port, int *val)
 {
        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
@@ -1204,6 +1250,9 @@ enum rtl8366_type rtl8366_smi_detect(struct rtl8366_platform_data *pdata)
        memset(&smi, 0, sizeof(smi));
        smi.gpio_sda = pdata->gpio_sda;
        smi.gpio_sck = pdata->gpio_sck;
+       smi.clk_delay = 10;
+       smi.cmd_read  = 0xa9;
+       smi.cmd_write = 0xa8;
 
        if (__rtl8366_smi_init(&smi, "rtl8366"))
                goto out;
@@ -1242,8 +1291,6 @@ int rtl8366_smi_init(struct rtl8366_smi *smi)
        if (err)
                goto err_out;
 
-       spin_lock_init(&smi->lock);
-
        dev_info(smi->parent, "using GPIO pins %u (SDA) and %u (SCK)\n",
                 smi->gpio_sda, smi->gpio_sck);
 
@@ -1253,6 +1300,10 @@ int rtl8366_smi_init(struct rtl8366_smi *smi)
                goto err_free_sck;
        }
 
+       err = smi->ops->reset_chip(smi);
+       if (err)
+               goto err_free_sck;
+
        err = smi->ops->setup(smi);
        if (err) {
                dev_err(smi->parent, "chip setup failed, err=%d\n", err);
@@ -1289,8 +1340,7 @@ void rtl8366_smi_cleanup(struct rtl8366_smi *smi)
 {
        rtl8366_debugfs_remove(smi);
        rtl8366_smi_mii_cleanup(smi);
-       gpio_free(smi->gpio_sck);
-       gpio_free(smi->gpio_sda);
+       __rtl8366_smi_cleanup(smi);
 }
 EXPORT_SYMBOL_GPL(rtl8366_smi_cleanup);