// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018 MediaTek Inc.
 * Author: Weijie Gao <weijie.gao@mediatek.com>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/reset.h>
#include <linux/hrtimer.h>
#include <linux/mii.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_net.h>
#include <linux/of_irq.h>
#include <linux/phy.h>

#include "mt753x.h"
#include "mt753x_swconfig.h"
#include "mt753x_regs.h"
#include "mt753x_nl.h"
#include "mt7530.h"
#include "mt7531.h"

static u32 mt753x_id;
struct list_head mt753x_devs;
static DEFINE_MUTEX(mt753x_devs_lock);

static struct mt753x_sw_id *mt753x_sw_ids[] = {
	&mt7530_id,
	&mt7531_id,
};

u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg)
{
	u32 high, low;

	mutex_lock(&gsw->host_bus->mdio_lock);

	gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
		(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);

	low = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr,
		(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S);

	high = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, 0x10);

	mutex_unlock(&gsw->host_bus->mdio_lock);

	return (high << 16) | (low & 0xffff);
}

void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val)
{
	mutex_lock(&gsw->host_bus->mdio_lock);

	gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
		(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);

	gsw->host_bus->write(gsw->host_bus, gsw->smi_addr,
		(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S, val & 0xffff);

	gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x10, val >> 16);

	mutex_unlock(&gsw->host_bus->mdio_lock);
}

/* Indirect MDIO clause 22/45 access */
static int mt753x_mii_rw(struct gsw_mt753x *gsw, int phy, int reg, u16 data,
			 u32 cmd, u32 st)
{
	ktime_t timeout;
	u32 val, timeout_us;
	int ret = 0;

	timeout_us = 100000;
	timeout = ktime_add_us(ktime_get(), timeout_us);
	while (1) {
		val = mt753x_reg_read(gsw, PHY_IAC);

		if ((val & PHY_ACS_ST) == 0)
			break;

		if (ktime_compare(ktime_get(), timeout) > 0)
			return -ETIMEDOUT;
	}

	val = (st << MDIO_ST_S) |
	      ((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
	      ((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
	      ((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);

	if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
		val |= data & MDIO_RW_DATA_M;

	mt753x_reg_write(gsw, PHY_IAC, val | PHY_ACS_ST);

	timeout_us = 100000;
	timeout = ktime_add_us(ktime_get(), timeout_us);
	while (1) {
		val = mt753x_reg_read(gsw, PHY_IAC);

		if ((val & PHY_ACS_ST) == 0)
			break;

		if (ktime_compare(ktime_get(), timeout) > 0)
			return -ETIMEDOUT;
	}

	if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
		val = mt753x_reg_read(gsw, PHY_IAC);
		ret = val & MDIO_RW_DATA_M;
	}

	return ret;
}

int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg)
{
	int val;

	if (phy < MT753X_NUM_PHYS)
		phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;

	mutex_lock(&gsw->mii_lock);
	val = mt753x_mii_rw(gsw, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
	mutex_unlock(&gsw->mii_lock);

	return val;
}

void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val)
{
	if (phy < MT753X_NUM_PHYS)
		phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;

	mutex_lock(&gsw->mii_lock);
	mt753x_mii_rw(gsw, phy, reg, val, MDIO_CMD_WRITE, MDIO_ST_C22);
	mutex_unlock(&gsw->mii_lock);
}

int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
	int val;

	if (addr < MT753X_NUM_PHYS)
		addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;

	mutex_lock(&gsw->mii_lock);
	mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
	val = mt753x_mii_rw(gsw, addr, devad, 0, MDIO_CMD_READ_C45,
			    MDIO_ST_C45);
	mutex_unlock(&gsw->mii_lock);

	return val;
}

void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
		      u16 val)
{
	if (addr < MT753X_NUM_PHYS)
		addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;

	mutex_lock(&gsw->mii_lock);
	mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
	mt753x_mii_rw(gsw, addr, devad, val, MDIO_CMD_WRITE, MDIO_ST_C45);
	mutex_unlock(&gsw->mii_lock);
}

int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
	u16 val;

	if (addr < MT753X_NUM_PHYS)
		addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;

	mutex_lock(&gsw->mii_lock);

	mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
		      (MMD_ADDR << MMD_CMD_S) |
		      ((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
		      (MMD_DATA << MMD_CMD_S) |
		      ((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	val = mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, 0,
			    MDIO_CMD_READ, MDIO_ST_C22);

	mutex_unlock(&gsw->mii_lock);

	return val;
}

void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
			  u16 val)
{
	if (addr < MT753X_NUM_PHYS)
		addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;

	mutex_lock(&gsw->mii_lock);

	mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
		      (MMD_ADDR << MMD_CMD_S) |
		      ((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
		      (MMD_DATA << MMD_CMD_S) |
		      ((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, val,
		      MDIO_CMD_WRITE, MDIO_ST_C22);

	mutex_unlock(&gsw->mii_lock);
}

static inline int mt753x_get_duplex(const struct device_node *np)
{
	return of_property_read_bool(np, "full-duplex");
}

static void mt753x_load_port_cfg(struct gsw_mt753x *gsw)
{
	struct device_node *port_np;
	struct device_node *fixed_link_node;
	struct mt753x_port_cfg *port_cfg;
	u32 port;

	for_each_child_of_node(gsw->dev->of_node, port_np) {
		if (!of_device_is_compatible(port_np, "mediatek,mt753x-port"))
			continue;

		if (!of_device_is_available(port_np))
			continue;

		if (of_property_read_u32(port_np, "reg", &port))
			continue;

		switch (port) {
		case 5:
			port_cfg = &gsw->port5_cfg;
			break;
		case 6:
			port_cfg = &gsw->port6_cfg;
			break;
		default:
			continue;
		}

		if (port_cfg->enabled) {
			dev_info(gsw->dev, "duplicated node for port%d\n",
				 port_cfg->phy_mode);
			continue;
		}

		port_cfg->np = port_np;

		port_cfg->phy_mode = of_get_phy_mode(port_np);
		if (port_cfg->phy_mode < 0) {
			dev_info(gsw->dev, "incorrect phy-mode %d\n", port);
			continue;
		}

		fixed_link_node = of_get_child_by_name(port_np, "fixed-link");
		if (fixed_link_node) {
			u32 speed;

			port_cfg->force_link = 1;
			port_cfg->duplex = mt753x_get_duplex(fixed_link_node);

			if (of_property_read_u32(fixed_link_node, "speed",
						 &speed)) {
				speed = 0;
				continue;
			}

			of_node_put(fixed_link_node);

			switch (speed) {
			case 10:
				port_cfg->speed = MAC_SPD_10;
				break;
			case 100:
				port_cfg->speed = MAC_SPD_100;
				break;
			case 1000:
				port_cfg->speed = MAC_SPD_1000;
				break;
			case 2500:
				port_cfg->speed = MAC_SPD_2500;
				break;
			default:
				dev_info(gsw->dev, "incorrect speed %d\n",
					 speed);
				continue;
			}
		}

		port_cfg->ssc_on = of_property_read_bool(port_cfg->np,
							 "mediatek,ssc-on");
		port_cfg->stag_on = of_property_read_bool(port_cfg->np,
							  "mediatek,stag-on");
		port_cfg->enabled = 1;
	}
}

void mt753x_tr_write(struct gsw_mt753x *gsw, int addr, u8 ch, u8 node, u8 daddr,
		     u32 data)
{
	ktime_t timeout;
	u32 timeout_us;
	u32 val;

	if (addr < MT753X_NUM_PHYS)
		addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;

	gsw->mii_write(gsw, addr, PHY_CL22_PAGE_CTRL, PHY_TR_PAGE);

	val = gsw->mii_read(gsw, addr, PHY_TR_CTRL);

	timeout_us = 100000;
	timeout = ktime_add_us(ktime_get(), timeout_us);
	while (1) {
		val = gsw->mii_read(gsw, addr, PHY_TR_CTRL);

		if (!!(val & PHY_TR_PKT_XMT_STA))
			break;

		if (ktime_compare(ktime_get(), timeout) > 0)
			goto out;
	}

	gsw->mii_write(gsw, addr, PHY_TR_LOW_DATA, PHY_TR_LOW_VAL(data));
	gsw->mii_write(gsw, addr, PHY_TR_HIGH_DATA, PHY_TR_HIGH_VAL(data));
	val = PHY_TR_PKT_XMT_STA | (PHY_TR_WRITE << PHY_TR_WR_S) |
	      (ch << PHY_TR_CH_ADDR_S) | (node << PHY_TR_NODE_ADDR_S) |
	      (daddr << PHY_TR_DATA_ADDR_S);
	gsw->mii_write(gsw, addr, PHY_TR_CTRL, val);

	timeout_us = 100000;
	timeout = ktime_add_us(ktime_get(), timeout_us);
	while (1) {
		val = gsw->mii_read(gsw, addr, PHY_TR_CTRL);

		if (!!(val & PHY_TR_PKT_XMT_STA))
			break;

		if (ktime_compare(ktime_get(), timeout) > 0)
			goto out;
	}
out:
	gsw->mii_write(gsw, addr, PHY_CL22_PAGE_CTRL, 0);
}

int mt753x_tr_read(struct gsw_mt753x *gsw, int addr, u8 ch, u8 node, u8 daddr)
{
	ktime_t timeout;
	u32 timeout_us;
	u32 val;
	u8 val_h;

	if (addr < MT753X_NUM_PHYS)
		addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;

	gsw->mii_write(gsw, addr, PHY_CL22_PAGE_CTRL, PHY_TR_PAGE);

	val = gsw->mii_read(gsw, addr, PHY_TR_CTRL);

	timeout_us = 100000;
	timeout = ktime_add_us(ktime_get(), timeout_us);
	while (1) {
		val = gsw->mii_read(gsw, addr, PHY_TR_CTRL);

		if (!!(val & PHY_TR_PKT_XMT_STA))
			break;

		if (ktime_compare(ktime_get(), timeout) > 0) {
			gsw->mii_write(gsw, addr, PHY_CL22_PAGE_CTRL, 0);
			return -ETIMEDOUT;
		}
	}

	val = PHY_TR_PKT_XMT_STA | (PHY_TR_READ << PHY_TR_WR_S) |
	      (ch << PHY_TR_CH_ADDR_S) | (node << PHY_TR_NODE_ADDR_S) |
	      (daddr << PHY_TR_DATA_ADDR_S);
	gsw->mii_write(gsw, addr, PHY_TR_CTRL, val);

	timeout_us = 100000;
	timeout = ktime_add_us(ktime_get(), timeout_us);
	while (1) {
		val = gsw->mii_read(gsw, addr, PHY_TR_CTRL);

		if (!!(val & PHY_TR_PKT_XMT_STA))
			break;

		if (ktime_compare(ktime_get(), timeout) > 0) {
			gsw->mii_write(gsw, addr, PHY_CL22_PAGE_CTRL, 0);
			return -ETIMEDOUT;
		}
	}

	val = gsw->mii_read(gsw, addr, PHY_TR_LOW_DATA);
	val_h = gsw->mii_read(gsw, addr, PHY_TR_HIGH_DATA);
	val |= (val_h << 16);

	gsw->mii_write(gsw, addr, PHY_CL22_PAGE_CTRL, 0);

	return val;
}

static void mt753x_add_gsw(struct gsw_mt753x *gsw)
{
	mutex_lock(&mt753x_devs_lock);
	gsw->id = mt753x_id++;
	INIT_LIST_HEAD(&gsw->list);
	list_add_tail(&gsw->list, &mt753x_devs);
	mutex_unlock(&mt753x_devs_lock);
}

static void mt753x_remove_gsw(struct gsw_mt753x *gsw)
{
	mutex_lock(&mt753x_devs_lock);
	list_del(&gsw->list);
	mutex_unlock(&mt753x_devs_lock);
}


struct gsw_mt753x *mt753x_get_gsw(u32 id)
{
	struct gsw_mt753x *dev;

	mutex_lock(&mt753x_devs_lock);

	list_for_each_entry(dev, &mt753x_devs, list) {
		if (dev->id == id)
			return dev;
	}

	mutex_unlock(&mt753x_devs_lock);

	return NULL;
}

struct gsw_mt753x *mt753x_get_first_gsw(void)
{
	struct gsw_mt753x *dev;

	mutex_lock(&mt753x_devs_lock);

	list_for_each_entry(dev, &mt753x_devs, list)
		return dev;

	mutex_unlock(&mt753x_devs_lock);

	return NULL;
}

void mt753x_put_gsw(void)
{
	mutex_unlock(&mt753x_devs_lock);
}

void mt753x_lock_gsw(void)
{
	mutex_lock(&mt753x_devs_lock);
}

static int mt753x_hw_reset(struct gsw_mt753x *gsw)
{
	struct device_node *np = gsw->dev->of_node;
	struct reset_control *rstc;
	int mcm;
	int ret = -EINVAL;

	mcm = of_property_read_bool(np, "mediatek,mcm");
	if (mcm) {
		rstc = devm_reset_control_get(gsw->dev, "mcm");
		ret = IS_ERR(rstc);
		if (IS_ERR(rstc)) {
			dev_err(gsw->dev, "Missing reset ctrl of switch\n");
			return ret;
		}

		reset_control_assert(rstc);
		msleep(30);
		reset_control_deassert(rstc);

		gsw->reset_pin = -1;
		return 0;
	}

	gsw->reset_pin = of_get_named_gpio(np, "reset-gpios", 0);
	if (gsw->reset_pin < 0) {
		dev_err(gsw->dev, "Missing reset pin of switch\n");
		return ret;
	}

	ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mt753x-reset");
	if (ret) {
		dev_info(gsw->dev, "Failed to request gpio %d\n",
			 gsw->reset_pin);
		return ret;
	}

	gpio_direction_output(gsw->reset_pin, 0);
	msleep(30);
	gpio_set_value(gsw->reset_pin, 1);
	msleep(500);

	return 0;
}
#if 1 //XDXDXDXD
static int mt753x_mdio_read(struct mii_bus *bus, int addr, int reg)
{
	struct gsw_mt753x *gsw = bus->priv;

	return gsw->mii_read(gsw, addr, reg);
}

static int mt753x_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
{
	struct gsw_mt753x *gsw = bus->priv;

	gsw->mii_write(gsw, addr, reg, val);

	return 0;
}

static const struct net_device_ops mt753x_dummy_netdev_ops = {
};

static void mt753x_phy_link_handler(struct net_device *dev)
{
	struct mt753x_phy *phy = container_of(dev, struct mt753x_phy, netdev);
	struct phy_device *phydev = phy->phydev;
	struct gsw_mt753x *gsw = phy->gsw;
	u32 port = phy - gsw->phys;

	if (phydev->link) {
		dev_info(gsw->dev,
			 "Port %d Link is Up - %s/%s - flow control %s\n",
			 port, phy_speed_to_str(phydev->speed),
			 (phydev->duplex == DUPLEX_FULL) ? "Full" : "Half",
			 phydev->pause ? "rx/tx" : "off");
	} else {
		dev_info(gsw->dev, "Port %d Link is Down\n", port);
	}
}

static void mt753x_connect_internal_phys(struct gsw_mt753x *gsw,
					 struct device_node *mii_np)
{
	struct device_node *phy_np;
	struct mt753x_phy *phy;
	int phy_mode;
	u32 phyad;

	if (!mii_np)
		return;

	for_each_child_of_node(mii_np, phy_np) {
		if (of_property_read_u32(phy_np, "reg", &phyad))
			continue;

		if (phyad >= MT753X_NUM_PHYS)
			continue;

		phy_mode = of_get_phy_mode(phy_np);
		if (phy_mode < 0) {
			dev_info(gsw->dev, "incorrect phy-mode %d for PHY %d\n",
				 phy_mode, phyad);
			continue;
		}

		phy = &gsw->phys[phyad];
		phy->gsw = gsw;

		init_dummy_netdev(&phy->netdev);
		phy->netdev.netdev_ops = &mt753x_dummy_netdev_ops;

		phy->phydev = of_phy_connect(&phy->netdev, phy_np,
					mt753x_phy_link_handler, 0, phy_mode);
		if (!phy->phydev) {
			dev_info(gsw->dev, "could not connect to PHY %d\n",
				 phyad);
			continue;
		}

		phy_start(phy->phydev);
	}
}

static void mt753x_disconnect_internal_phys(struct gsw_mt753x *gsw)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(gsw->phys); i++) {
		if (gsw->phys[i].phydev) {
			phy_stop(gsw->phys[i].phydev);
			phy_disconnect(gsw->phys[i].phydev);
			gsw->phys[i].phydev = NULL;
		}
	}
}

static int mt753x_mdio_register(struct gsw_mt753x *gsw)
{
	struct device_node *mii_np;
	int i, ret;

	mii_np = of_get_child_by_name(gsw->dev->of_node, "mdio-bus");
	if (mii_np && !of_device_is_available(mii_np)) {
		ret = -ENODEV;
		goto err_put_node;
	}

	gsw->gphy_bus = devm_mdiobus_alloc(gsw->dev);
	if (!gsw->gphy_bus) {
		ret = -ENOMEM;
		goto err_put_node;
	}

	gsw->gphy_bus->name = "mt753x_mdio";
	gsw->gphy_bus->read = mt753x_mdio_read;
	gsw->gphy_bus->write = mt753x_mdio_write;
	gsw->gphy_bus->priv = gsw;
	gsw->gphy_bus->parent = gsw->dev;
	gsw->gphy_bus->phy_mask = BIT(MT753X_NUM_PHYS) - 1;
//	gsw->gphy_bus->irq = gsw->phy_irqs;

	for (i = 0; i < PHY_MAX_ADDR; i++)
		gsw->gphy_bus->irq[i] = PHY_POLL;

	if (mii_np)
		snprintf(gsw->gphy_bus->id, MII_BUS_ID_SIZE, "%s@%s",
			 mii_np->name, gsw->dev->of_node->name);
	else
		snprintf(gsw->gphy_bus->id, MII_BUS_ID_SIZE, "mdio@%s",
			 gsw->dev->of_node->name);

	ret = of_mdiobus_register(gsw->gphy_bus, mii_np);

	if (ret) {
		devm_mdiobus_free(gsw->dev, gsw->gphy_bus);
		gsw->gphy_bus = NULL;
	} else {
		if (gsw->phy_status_poll)
			mt753x_connect_internal_phys(gsw, mii_np);
	}

err_put_node:
	if (mii_np)
		of_node_put(mii_np);

	return ret;
}
#endif

static irqreturn_t mt753x_irq_handler(int irq, void *dev)
{
	struct gsw_mt753x *gsw = dev;

	disable_irq_nosync(gsw->irq);

	schedule_work(&gsw->irq_worker);

	return IRQ_HANDLED;
}

static int mt753x_probe(struct platform_device *pdev)
{
	struct gsw_mt753x *gsw;
	struct mt753x_sw_id *sw;
	struct device_node *np = pdev->dev.of_node;
	struct device_node *mdio;
	struct mii_bus *mdio_bus;
	int ret = -EINVAL;
	struct chip_rev rev;
	struct mt753x_mapping *map;
	int i;

	mdio = of_parse_phandle(np, "mediatek,mdio", 0);
	if (!mdio)
		return -EINVAL;

	mdio_bus = of_mdio_find_bus(mdio);
	if (!mdio_bus)
		return -EPROBE_DEFER;

	gsw = devm_kzalloc(&pdev->dev, sizeof(struct gsw_mt753x), GFP_KERNEL);
	if (!gsw)
		return -ENOMEM;

	gsw->host_bus = mdio_bus;
	gsw->dev = &pdev->dev;
	mutex_init(&gsw->mii_lock);

	/* Switch hard reset */
	if (mt753x_hw_reset(gsw))
		goto fail;

	/* Fetch the SMI address dirst */
	if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr))
		gsw->smi_addr = MT753X_DFL_SMI_ADDR;

	/* Get LAN/WAN port mapping */
	map = mt753x_find_mapping(np);
	if (map) {
		mt753x_apply_mapping(gsw, map);
		gsw->global_vlan_enable = 1;
		dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name);
	}

	/* Load MAC port configurations */
	mt753x_load_port_cfg(gsw);

	/* Check for valid switch and then initialize */
	for (i = 0; i < ARRAY_SIZE(mt753x_sw_ids); i++) {
		if (!mt753x_sw_ids[i]->detect(gsw, &rev)) {
			sw = mt753x_sw_ids[i];

			gsw->name = rev.name;
			gsw->model = sw->model;

			dev_info(gsw->dev, "Switch is MediaTek %s rev %d",
				 gsw->name, rev.rev);

			/* Initialize the switch */
			ret = sw->init(gsw);
			if (ret)
				goto fail;

			break;
		}
	}

	if (i >= ARRAY_SIZE(mt753x_sw_ids)) {
		dev_err(gsw->dev, "No mt753x switch found\n");
		goto fail;
	}

	gsw->irq = platform_get_irq(pdev, 0);
	if (gsw->irq >= 0) {
		ret = devm_request_irq(gsw->dev, gsw->irq, mt753x_irq_handler,
				       0, dev_name(gsw->dev), gsw);
		if (ret) {
			dev_err(gsw->dev, "Failed to request irq %d\n",
				gsw->irq);
			goto fail;
		}

		INIT_WORK(&gsw->irq_worker, mt753x_irq_worker);
	}

	platform_set_drvdata(pdev, gsw);

	gsw->phy_status_poll = of_property_read_bool(gsw->dev->of_node,
						     "mediatek,phy-poll");

	mt753x_add_gsw(gsw);
#if 1 //XDXD
	mt753x_mdio_register(gsw);
#endif

	mt753x_nl_init();

	mt753x_swconfig_init(gsw);

	if (sw->post_init)
		sw->post_init(gsw);

	if (gsw->irq >= 0)
		mt753x_irq_enable(gsw);

	return 0;

fail:
	devm_kfree(&pdev->dev, gsw);

	return ret;
}

static int mt753x_remove(struct platform_device *pdev)
{
	struct gsw_mt753x *gsw = platform_get_drvdata(pdev);

	if (gsw->irq >= 0)
		cancel_work_sync(&gsw->irq_worker);

	if (gsw->reset_pin >= 0)
		devm_gpio_free(&pdev->dev, gsw->reset_pin);

#ifdef CONFIG_SWCONFIG
	mt753x_swconfig_destroy(gsw);
#endif

#if 1 //XDXD
	mt753x_disconnect_internal_phys(gsw);

	mdiobus_unregister(gsw->gphy_bus);
#endif

	mt753x_nl_exit();

	mt753x_remove_gsw(gsw);

	platform_set_drvdata(pdev, NULL);

	return 0;
}

static const struct of_device_id mt753x_ids[] = {
	{ .compatible = "mediatek,mt753x" },
	{ },
};

MODULE_DEVICE_TABLE(of, mt753x_ids);

static struct platform_driver mt753x_driver = {
	.probe = mt753x_probe,
	.remove = mt753x_remove,
	.driver = {
		.name = "mt753x",
		.of_match_table = mt753x_ids,
	},
};

static int __init mt753x_init(void)
{
	int ret;

	INIT_LIST_HEAD(&mt753x_devs);
	ret = platform_driver_register(&mt753x_driver);

	return ret;
}
module_init(mt753x_init);

static void __exit mt753x_exit(void)
{
	platform_driver_unregister(&mt753x_driver);
}
module_exit(mt753x_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch");
