// SPDX-License-Identifier: GPL-2.0
/*
 * core.c - ChipIdea USB IP core family device controller
 *
 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
 * Copyright (C) 2020 NXP
 *
 * Author: David Lopo
 *	   Peter Chen <peter.chen@nxp.com>
 *
 * Main Features:
 * - Four transfers are supported, usbtest is passed
 * - USB Certification for gadget: CH9 and Mass Storage are passed
 * - Low power mode
 * - USB wakeup
 */
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/extcon.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
#include <linux/pinctrl/consumer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/usb/chipidea.h>
#include <linux/usb/of.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/usb/ehci_def.h>

#include "ci.h"
#include "udc.h"
#include "bits.h"
#include "host.h"
#include "otg.h"
#include "otg_fsm.h"

/* Controller register map */
static const u8 ci_regs_nolpm[] = {
	[CAP_CAPLENGTH]		= 0x00U,
	[CAP_HCCPARAMS]		= 0x08U,
	[CAP_DCCPARAMS]		= 0x24U,
	[CAP_TESTMODE]		= 0x38U,
	[OP_USBCMD]		= 0x00U,
	[OP_USBSTS]		= 0x04U,
	[OP_USBINTR]		= 0x08U,
	[OP_FRINDEX]		= 0x0CU,
	[OP_DEVICEADDR]		= 0x14U,
	[OP_ENDPTLISTADDR]	= 0x18U,
	[OP_TTCTRL]		= 0x1CU,
	[OP_BURSTSIZE]		= 0x20U,
	[OP_ULPI_VIEWPORT]	= 0x30U,
	[OP_PORTSC]		= 0x44U,
	[OP_DEVLC]		= 0x84U,
	[OP_OTGSC]		= 0x64U,
	[OP_USBMODE]		= 0x68U,
	[OP_ENDPTSETUPSTAT]	= 0x6CU,
	[OP_ENDPTPRIME]		= 0x70U,
	[OP_ENDPTFLUSH]		= 0x74U,
	[OP_ENDPTSTAT]		= 0x78U,
	[OP_ENDPTCOMPLETE]	= 0x7CU,
	[OP_ENDPTCTRL]		= 0x80U,
};

static const u8 ci_regs_lpm[] = {
	[CAP_CAPLENGTH]		= 0x00U,
	[CAP_HCCPARAMS]		= 0x08U,
	[CAP_DCCPARAMS]		= 0x24U,
	[CAP_TESTMODE]		= 0xFCU,
	[OP_USBCMD]		= 0x00U,
	[OP_USBSTS]		= 0x04U,
	[OP_USBINTR]		= 0x08U,
	[OP_FRINDEX]		= 0x0CU,
	[OP_DEVICEADDR]		= 0x14U,
	[OP_ENDPTLISTADDR]	= 0x18U,
	[OP_TTCTRL]		= 0x1CU,
	[OP_BURSTSIZE]		= 0x20U,
	[OP_ULPI_VIEWPORT]	= 0x30U,
	[OP_PORTSC]		= 0x44U,
	[OP_DEVLC]		= 0x84U,
	[OP_OTGSC]		= 0xC4U,
	[OP_USBMODE]		= 0xC8U,
	[OP_ENDPTSETUPSTAT]	= 0xD8U,
	[OP_ENDPTPRIME]		= 0xDCU,
	[OP_ENDPTFLUSH]		= 0xE0U,
	[OP_ENDPTSTAT]		= 0xE4U,
	[OP_ENDPTCOMPLETE]	= 0xE8U,
	[OP_ENDPTCTRL]		= 0xECU,
};

static void hw_alloc_regmap(struct ci_hdrc *ci, bool is_lpm)
{
	int i;

	for (i = 0; i < OP_ENDPTCTRL; i++)
		ci->hw_bank.regmap[i] =
			(i <= CAP_LAST ? ci->hw_bank.cap : ci->hw_bank.op) +
			(is_lpm ? ci_regs_lpm[i] : ci_regs_nolpm[i]);

	for (; i <= OP_LAST; i++)
		ci->hw_bank.regmap[i] = ci->hw_bank.op +
			4 * (i - OP_ENDPTCTRL) +
			(is_lpm
			 ? ci_regs_lpm[OP_ENDPTCTRL]
			 : ci_regs_nolpm[OP_ENDPTCTRL]);

}

static enum ci_revision ci_get_revision(struct ci_hdrc *ci)
{
	int ver = hw_read_id_reg(ci, ID_ID, VERSION) >> __ffs(VERSION);
	enum ci_revision rev = CI_REVISION_UNKNOWN;

	if (ver == 0x2) {
		rev = hw_read_id_reg(ci, ID_ID, REVISION)
			>> __ffs(REVISION);
		rev += CI_REVISION_20;
	} else if (ver == 0x0) {
		rev = CI_REVISION_1X;
	}

	return rev;
}

/**
 * hw_read_intr_enable: returns interrupt enable register
 *
 * @ci: the controller
 *
 * This function returns register data
 */
u32 hw_read_intr_enable(struct ci_hdrc *ci)
{
	return hw_read(ci, OP_USBINTR, ~0);
}

/**
 * hw_read_intr_status: returns interrupt status register
 *
 * @ci: the controller
 *
 * This function returns register data
 */
u32 hw_read_intr_status(struct ci_hdrc *ci)
{
	return hw_read(ci, OP_USBSTS, ~0);
}

/**
 * hw_port_test_set: writes port test mode (execute without interruption)
 * @ci: the controller
 * @mode: new value
 *
 * This function returns an error code
 */
int hw_port_test_set(struct ci_hdrc *ci, u8 mode)
{
	const u8 TEST_MODE_MAX = 7;

	if (mode > TEST_MODE_MAX)
		return -EINVAL;

	hw_write(ci, OP_PORTSC, PORTSC_PTC, mode << __ffs(PORTSC_PTC));
	return 0;
}

/**
 * hw_port_test_get: reads port test mode value
 *
 * @ci: the controller
 *
 * This function returns port test mode value
 */
u8 hw_port_test_get(struct ci_hdrc *ci)
{
	return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
}

static void hw_wait_phy_stable(void)
{
	/*
	 * The phy needs some delay to output the stable status from low
	 * power mode. And for OTGSC, the status inputs are debounced
	 * using a 1 ms time constant, so, delay 2ms for controller to get
	 * the stable status, like vbus and id when the phy leaves low power.
	 */
	usleep_range(2000, 2500);
}

/* The PHY enters/leaves low power mode */
static void ci_hdrc_enter_lpm_common(struct ci_hdrc *ci, bool enable)
{
	enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC;
	bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm)));

	if (enable && !lpm)
		hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
				PORTSC_PHCD(ci->hw_bank.lpm));
	else if (!enable && lpm)
		hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
				0);
}

static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
{
	return ci->platdata->enter_lpm(ci, enable);
}

static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
{
	u32 reg;

	/* bank is a module variable */
	ci->hw_bank.abs = base;

	ci->hw_bank.cap = ci->hw_bank.abs;
	ci->hw_bank.cap += ci->platdata->capoffset;
	ci->hw_bank.op = ci->hw_bank.cap + (ioread32(ci->hw_bank.cap) & 0xff);

	hw_alloc_regmap(ci, false);
	reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) >>
		__ffs(HCCPARAMS_LEN);
	ci->hw_bank.lpm  = reg;
	if (reg)
		hw_alloc_regmap(ci, !!reg);
	ci->hw_bank.size = ci->hw_bank.op - ci->hw_bank.abs;
	ci->hw_bank.size += OP_LAST;
	ci->hw_bank.size /= sizeof(u32);

	reg = hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DEN) >>
		__ffs(DCCPARAMS_DEN);
	ci->hw_ep_max = reg * 2;   /* cache hw ENDPT_MAX */

	if (ci->hw_ep_max > ENDPT_MAX)
		return -ENODEV;

	ci_hdrc_enter_lpm(ci, false);

	/* Disable all interrupts bits */
	hw_write(ci, OP_USBINTR, 0xffffffff, 0);

	/* Clear all interrupts status bits*/
	hw_write(ci, OP_USBSTS, 0xffffffff, 0xffffffff);

	ci->rev = ci_get_revision(ci);

	dev_dbg(ci->dev,
		"revision: %d, lpm: %d; cap: %px op: %px\n",
		ci->rev, ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);

	/* setup lock mode ? */

	/* ENDPTSETUPSTAT is '0' by default */

	/* HCSPARAMS.bf.ppc SHOULD BE zero for device */

	return 0;
}

void hw_phymode_configure(struct ci_hdrc *ci)
{
	u32 portsc, lpm, sts = 0;

	switch (ci->platdata->phy_mode) {
	case USBPHY_INTERFACE_MODE_UTMI:
		portsc = PORTSC_PTS(PTS_UTMI);
		lpm = DEVLC_PTS(PTS_UTMI);
		break;
	case USBPHY_INTERFACE_MODE_UTMIW:
		portsc = PORTSC_PTS(PTS_UTMI) | PORTSC_PTW;
		lpm = DEVLC_PTS(PTS_UTMI) | DEVLC_PTW;
		break;
	case USBPHY_INTERFACE_MODE_ULPI:
		portsc = PORTSC_PTS(PTS_ULPI);
		lpm = DEVLC_PTS(PTS_ULPI);
		break;
	case USBPHY_INTERFACE_MODE_SERIAL:
		portsc = PORTSC_PTS(PTS_SERIAL);
		lpm = DEVLC_PTS(PTS_SERIAL);
		sts = 1;
		break;
	case USBPHY_INTERFACE_MODE_HSIC:
		portsc = PORTSC_PTS(PTS_HSIC);
		lpm = DEVLC_PTS(PTS_HSIC);
		break;
	default:
		return;
	}

	if (ci->hw_bank.lpm) {
		hw_write(ci, OP_DEVLC, DEVLC_PTS(7) | DEVLC_PTW, lpm);
		if (sts)
			hw_write(ci, OP_DEVLC, DEVLC_STS, DEVLC_STS);
	} else {
		hw_write(ci, OP_PORTSC, PORTSC_PTS(7) | PORTSC_PTW, portsc);
		if (sts)
			hw_write(ci, OP_PORTSC, PORTSC_STS, PORTSC_STS);
	}
}
EXPORT_SYMBOL_GPL(hw_phymode_configure);

/**
 * _ci_usb_phy_init: initialize phy taking in account both phy and usb_phy
 * interfaces
 * @ci: the controller
 *
 * This function returns an error code if the phy failed to init
 */
static int _ci_usb_phy_init(struct ci_hdrc *ci)
{
	int ret;

	if (ci->phy) {
		ret = phy_init(ci->phy);
		if (ret)
			return ret;

		ret = phy_power_on(ci->phy);
		if (ret) {
			phy_exit(ci->phy);
			return ret;
		}
	} else {
		ret = usb_phy_init(ci->usb_phy);
	}

	return ret;
}

/**
 * ci_usb_phy_exit: deinitialize phy taking in account both phy and usb_phy
 * interfaces
 * @ci: the controller
 */
static void ci_usb_phy_exit(struct ci_hdrc *ci)
{
	if (ci->platdata->flags & CI_HDRC_OVERRIDE_PHY_CONTROL)
		return;

	if (ci->phy) {
		phy_power_off(ci->phy);
		phy_exit(ci->phy);
	} else {
		usb_phy_shutdown(ci->usb_phy);
	}
}

/**
 * ci_usb_phy_init: initialize phy according to different phy type
 * @ci: the controller
 *
 * This function returns an error code if usb_phy_init has failed
 */
static int ci_usb_phy_init(struct ci_hdrc *ci)
{
	int ret;

	if (ci->platdata->flags & CI_HDRC_OVERRIDE_PHY_CONTROL)
		return 0;

	switch (ci->platdata->phy_mode) {
	case USBPHY_INTERFACE_MODE_UTMI:
	case USBPHY_INTERFACE_MODE_UTMIW:
	case USBPHY_INTERFACE_MODE_HSIC:
		ret = _ci_usb_phy_init(ci);
		if (!ret)
			hw_wait_phy_stable();
		else
			return ret;
		hw_phymode_configure(ci);
		break;
	case USBPHY_INTERFACE_MODE_ULPI:
	case USBPHY_INTERFACE_MODE_SERIAL:
		hw_phymode_configure(ci);
		ret = _ci_usb_phy_init(ci);
		if (ret)
			return ret;
		break;
	default:
		ret = _ci_usb_phy_init(ci);
		if (!ret)
			hw_wait_phy_stable();
	}

	return ret;
}


/**
 * ci_platform_configure: do controller configure
 * @ci: the controller
 *
 */
void ci_platform_configure(struct ci_hdrc *ci)
{
	bool is_device_mode, is_host_mode;

	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;

	if (is_device_mode) {
		phy_set_mode(ci->phy, PHY_MODE_USB_DEVICE);

		if (ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING)
			hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS,
				 USBMODE_CI_SDIS);
	}

	if (is_host_mode) {
		phy_set_mode(ci->phy, PHY_MODE_USB_HOST);

		if (ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING)
			hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS,
				 USBMODE_CI_SDIS);
	}

	if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
		if (ci->hw_bank.lpm)
			hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC);
		else
			hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC);
	}

	if (ci->platdata->flags & CI_HDRC_SET_NON_ZERO_TTHA)
		hw_write(ci, OP_TTCTRL, TTCTRL_TTHA_MASK, TTCTRL_TTHA);

	hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);

	if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
		hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
			ci->platdata->ahb_burst_config);

	/* override burst size, take effect only when ahb_burst_config is 0 */
	if (!hw_read_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK)) {
		if (ci->platdata->flags & CI_HDRC_OVERRIDE_TX_BURST)
			hw_write(ci, OP_BURSTSIZE, TX_BURST_MASK,
			ci->platdata->tx_burst_size << __ffs(TX_BURST_MASK));

		if (ci->platdata->flags & CI_HDRC_OVERRIDE_RX_BURST)
			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
				ci->platdata->rx_burst_size);
	}
}

/**
 * hw_controller_reset: do controller reset
 * @ci: the controller
  *
 * This function returns an error code
 */
static int hw_controller_reset(struct ci_hdrc *ci)
{
	int count = 0;

	hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST);
	while (hw_read(ci, OP_USBCMD, USBCMD_RST)) {
		udelay(10);
		if (count++ > 1000)
			return -ETIMEDOUT;
	}

	return 0;
}

/**
 * hw_device_reset: resets chip (execute without interruption)
 * @ci: the controller
 *
 * This function returns an error code
 */
int hw_device_reset(struct ci_hdrc *ci)
{
	int ret;

	/* should flush & stop before reset */
	hw_write(ci, OP_ENDPTFLUSH, ~0, ~0);
	hw_write(ci, OP_USBCMD, USBCMD_RS, 0);

	ret = hw_controller_reset(ci);
	if (ret) {
		dev_err(ci->dev, "error resetting controller, ret=%d\n", ret);
		return ret;
	}

	if (ci->platdata->notify_event) {
		ret = ci->platdata->notify_event(ci,
			CI_HDRC_CONTROLLER_RESET_EVENT);
		if (ret)
			return ret;
	}

	/* USBMODE should be configured step by step */
	hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
	hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_DC);
	/* HW >= 2.3 */
	hw_write(ci, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);

	if (hw_read(ci, OP_USBMODE, USBMODE_CM) != USBMODE_CM_DC) {
		dev_err(ci->dev, "cannot enter in %s device mode\n",
			ci_role(ci)->name);
		dev_err(ci->dev, "lpm = %i\n", ci->hw_bank.lpm);
		return -ENODEV;
	}

	ci_platform_configure(ci);

	return 0;
}

static irqreturn_t ci_irq_handler(int irq, void *data)
{
	struct ci_hdrc *ci = data;
	irqreturn_t ret = IRQ_NONE;
	u32 otgsc = 0;

	if (ci->in_lpm) {
		/*
		 * If we already have a wakeup irq pending there,
		 * let's just return to wait resume finished firstly.
		 */
		if (ci->wakeup_int)
			return IRQ_HANDLED;

		disable_irq_nosync(irq);
		ci->wakeup_int = true;
		pm_runtime_get(ci->dev);
		return IRQ_HANDLED;
	}

	if (ci->is_otg) {
		otgsc = hw_read_otgsc(ci, ~0);
		if (ci_otg_is_fsm_mode(ci)) {
			ret = ci_otg_fsm_irq(ci);
			if (ret == IRQ_HANDLED)
				return ret;
		}

		/*
		 * Handle id change interrupt, it indicates device/host function
		 * switch.
		 */
		if ((otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) {
			ci->id_event = true;
			/* Clear ID change irq status */
			hw_write_otgsc(ci, OTGSC_IDIS, OTGSC_IDIS);
		}

		/*
		 * Handle vbus change interrupt, it indicates device connection
		 * and disconnection events.
		 */
		if ((otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) {
			ci->b_sess_valid_event = true;
			/* Clear BSV irq */
			hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
		}

		if (ci->id_event || ci->b_sess_valid_event) {
			ci_otg_queue_work(ci);
			return IRQ_HANDLED;
		}
	}

	/* Handle device/host interrupt */
	if (ci->role != CI_ROLE_END)
		ret = ci_role(ci)->irq(ci);

	return ret;
}

static void ci_irq(struct ci_hdrc *ci)
{
	unsigned long flags;

	local_irq_save(flags);
	ci_irq_handler(ci->irq, ci);
	local_irq_restore(flags);
}

static int ci_cable_notifier(struct notifier_block *nb, unsigned long event,
			     void *ptr)
{
	struct ci_hdrc_cable *cbl = container_of(nb, struct ci_hdrc_cable, nb);
	struct ci_hdrc *ci = cbl->ci;

	cbl->connected = event;
	cbl->changed = true;

	ci_irq(ci);
	return NOTIFY_DONE;
}

static enum usb_role ci_usb_role_switch_get(struct usb_role_switch *sw)
{
	struct ci_hdrc *ci = usb_role_switch_get_drvdata(sw);
	enum usb_role role;
	unsigned long flags;

	spin_lock_irqsave(&ci->lock, flags);
	role = ci_role_to_usb_role(ci);
	spin_unlock_irqrestore(&ci->lock, flags);

	return role;
}

static int ci_usb_role_switch_set(struct usb_role_switch *sw,
				  enum usb_role role)
{
	struct ci_hdrc *ci = usb_role_switch_get_drvdata(sw);
	struct ci_hdrc_cable *cable;

	cable = &ci->platdata->id_extcon;
	cable->changed = true;
	cable->connected = (role == USB_ROLE_HOST);

	cable = &ci->platdata->vbus_extcon;
	cable->changed = true;
	cable->connected = (role == USB_ROLE_DEVICE);

	ci_irq(ci);
	return 0;
}

static enum ci_role ci_get_role(struct ci_hdrc *ci)
{
	enum ci_role role;

	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
		if (ci->is_otg) {
			role = ci_otg_role(ci);
			hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);
		} else {
			/*
			 * If the controller is not OTG capable, but support
			 * role switch, the defalt role is gadget, and the
			 * user can switch it through debugfs.
			 */
			role = CI_ROLE_GADGET;
		}
	} else {
		role = ci->roles[CI_ROLE_HOST] ? CI_ROLE_HOST
					: CI_ROLE_GADGET;
	}

	return role;
}

static int ci_get_platdata(struct device *dev,
		struct ci_hdrc_platform_data *platdata)
{
	struct extcon_dev *ext_vbus, *ext_id;
	struct ci_hdrc_cable *cable;
	int ret;

	if (!platdata->phy_mode)
		platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);

	if (!platdata->dr_mode)
		platdata->dr_mode = usb_get_dr_mode(dev);

	if (platdata->dr_mode == USB_DR_MODE_UNKNOWN)
		platdata->dr_mode = USB_DR_MODE_OTG;

	if (platdata->dr_mode != USB_DR_MODE_PERIPHERAL) {
		/* Get the vbus regulator */
		platdata->reg_vbus = devm_regulator_get_optional(dev, "vbus");
		if (PTR_ERR(platdata->reg_vbus) == -EPROBE_DEFER) {
			return -EPROBE_DEFER;
		} else if (PTR_ERR(platdata->reg_vbus) == -ENODEV) {
			/* no vbus regulator is needed */
			platdata->reg_vbus = NULL;
		} else if (IS_ERR(platdata->reg_vbus)) {
			dev_err(dev, "Getting regulator error: %ld\n",
				PTR_ERR(platdata->reg_vbus));
			return PTR_ERR(platdata->reg_vbus);
		}
		/* Get TPL support */
		if (!platdata->tpl_support)
			platdata->tpl_support =
				of_usb_host_tpl_support(dev->of_node);
	}

	if (platdata->dr_mode == USB_DR_MODE_OTG) {
		/* We can support HNP and SRP of OTG 2.0 */
		platdata->ci_otg_caps.otg_rev = 0x0200;
		platdata->ci_otg_caps.hnp_support = true;
		platdata->ci_otg_caps.srp_support = true;

		/* Update otg capabilities by DT properties */
		ret = of_usb_update_otg_caps(dev->of_node,
					&platdata->ci_otg_caps);
		if (ret)
			return ret;
	}

	if (usb_get_maximum_speed(dev) == USB_SPEED_FULL)
		platdata->flags |= CI_HDRC_FORCE_FULLSPEED;

	of_property_read_u32(dev->of_node, "phy-clkgate-delay-us",
				     &platdata->phy_clkgate_delay_us);

	platdata->itc_setting = 1;

	of_property_read_u32(dev->of_node, "itc-setting",
					&platdata->itc_setting);

	ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
				&platdata->ahb_burst_config);
	if (!ret) {
		platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
	} else if (ret != -EINVAL) {
		dev_err(dev, "failed to get ahb-burst-config\n");
		return ret;
	}

	ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword",
				&platdata->tx_burst_size);
	if (!ret) {
		platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST;
	} else if (ret != -EINVAL) {
		dev_err(dev, "failed to get tx-burst-size-dword\n");
		return ret;
	}

	ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword",
				&platdata->rx_burst_size);
	if (!ret) {
		platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
	} else if (ret != -EINVAL) {
		dev_err(dev, "failed to get rx-burst-size-dword\n");
		return ret;
	}

	if (of_property_read_bool(dev->of_node, "non-zero-ttctrl-ttha"))
		platdata->flags |= CI_HDRC_SET_NON_ZERO_TTHA;

	ext_id = ERR_PTR(-ENODEV);
	ext_vbus = ERR_PTR(-ENODEV);
	if (of_property_present(dev->of_node, "extcon")) {
		/* Each one of them is not mandatory */
		ext_vbus = extcon_get_edev_by_phandle(dev, 0);
		if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV)
			return PTR_ERR(ext_vbus);

		ext_id = extcon_get_edev_by_phandle(dev, 1);
		if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV)
			return PTR_ERR(ext_id);
	}

	cable = &platdata->vbus_extcon;
	cable->nb.notifier_call = ci_cable_notifier;
	cable->edev = ext_vbus;

	if (!IS_ERR(ext_vbus)) {
		ret = extcon_get_state(cable->edev, EXTCON_USB);
		if (ret)
			cable->connected = true;
		else
			cable->connected = false;
	}

	cable = &platdata->id_extcon;
	cable->nb.notifier_call = ci_cable_notifier;
	cable->edev = ext_id;

	if (!IS_ERR(ext_id)) {
		ret = extcon_get_state(cable->edev, EXTCON_USB_HOST);
		if (ret)
			cable->connected = true;
		else
			cable->connected = false;
	}

	platdata->pctl = devm_pinctrl_get(dev);
	if (!IS_ERR(platdata->pctl)) {
		struct pinctrl_state *p;

		p = pinctrl_lookup_state(platdata->pctl, "default");
		if (!IS_ERR(p))
			platdata->pins_default = p;

		p = pinctrl_lookup_state(platdata->pctl, "host");
		if (!IS_ERR(p))
			platdata->pins_host = p;

		p = pinctrl_lookup_state(platdata->pctl, "device");
		if (!IS_ERR(p))
			platdata->pins_device = p;
	}

	if (!platdata->enter_lpm)
		platdata->enter_lpm = ci_hdrc_enter_lpm_common;

	return 0;
}

static int ci_extcon_register(struct ci_hdrc *ci)
{
	struct ci_hdrc_cable *id, *vbus;
	int ret;

	id = &ci->platdata->id_extcon;
	id->ci = ci;
	if (!IS_ERR_OR_NULL(id->edev)) {
		ret = devm_extcon_register_notifier(ci->dev, id->edev,
						EXTCON_USB_HOST, &id->nb);
		if (ret < 0) {
			dev_err(ci->dev, "register ID failed\n");
			return ret;
		}
	}

	vbus = &ci->platdata->vbus_extcon;
	vbus->ci = ci;
	if (!IS_ERR_OR_NULL(vbus->edev)) {
		ret = devm_extcon_register_notifier(ci->dev, vbus->edev,
						EXTCON_USB, &vbus->nb);
		if (ret < 0) {
			dev_err(ci->dev, "register VBUS failed\n");
			return ret;
		}
	}

	return 0;
}

static void ci_power_lost_work(struct work_struct *work)
{
	struct ci_hdrc *ci = container_of(work, struct ci_hdrc, power_lost_work);
	enum ci_role role;

	disable_irq_nosync(ci->irq);
	pm_runtime_get_sync(ci->dev);
	if (!ci_otg_is_fsm_mode(ci)) {
		role = ci_get_role(ci);

		if (ci->role != role) {
			ci_handle_id_switch(ci);
		} else if (role == CI_ROLE_GADGET) {
			if (ci->is_otg && hw_read_otgsc(ci, OTGSC_BSV))
				usb_gadget_vbus_connect(&ci->gadget);
		}
	}
	pm_runtime_put_sync(ci->dev);
	enable_irq(ci->irq);
}

static DEFINE_IDA(ci_ida);

struct platform_device *ci_hdrc_add_device(struct device *dev,
			struct resource *res, int nres,
			struct ci_hdrc_platform_data *platdata)
{
	struct platform_device *pdev;
	int id, ret;

	ret = ci_get_platdata(dev, platdata);
	if (ret)
		return ERR_PTR(ret);

	id = ida_alloc(&ci_ida, GFP_KERNEL);
	if (id < 0)
		return ERR_PTR(id);

	pdev = platform_device_alloc("ci_hdrc", id);
	if (!pdev) {
		ret = -ENOMEM;
		goto put_id;
	}

	pdev->dev.parent = dev;
	platform_device_set_of_node_from_dev(pdev, dev);

	ret = platform_device_add_resources(pdev, res, nres);
	if (ret)
		goto err;

	ret = platform_device_add_data(pdev, platdata, sizeof(*platdata));
	if (ret)
		goto err;

	ret = platform_device_add(pdev);
	if (ret)
		goto err;

	dev_pm_domain_detach(&pdev->dev, false);

	return pdev;

err:
	platform_device_put(pdev);
put_id:
	ida_free(&ci_ida, id);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(ci_hdrc_add_device);

void ci_hdrc_remove_device(struct platform_device *pdev)
{
	int id = pdev->id;
	platform_device_unregister(pdev);
	ida_free(&ci_ida, id);
}
EXPORT_SYMBOL_GPL(ci_hdrc_remove_device);

/**
 * ci_hdrc_query_available_role: get runtime available operation mode
 *
 * The glue layer can get current operation mode (host/peripheral/otg)
 * This function should be called after ci core device has created.
 *
 * @pdev: the platform device of ci core.
 *
 * Return runtime usb_dr_mode.
 */
enum usb_dr_mode ci_hdrc_query_available_role(struct platform_device *pdev)
{
	struct ci_hdrc *ci = platform_get_drvdata(pdev);

	if (!ci)
		return USB_DR_MODE_UNKNOWN;
	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])
		return USB_DR_MODE_OTG;
	else if (ci->roles[CI_ROLE_HOST])
		return USB_DR_MODE_HOST;
	else if (ci->roles[CI_ROLE_GADGET])
		return USB_DR_MODE_PERIPHERAL;
	else
		return USB_DR_MODE_UNKNOWN;
}
EXPORT_SYMBOL_GPL(ci_hdrc_query_available_role);

static inline void ci_role_destroy(struct ci_hdrc *ci)
{
	ci_hdrc_gadget_destroy(ci);
	ci_hdrc_host_destroy(ci);
	if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
		ci_hdrc_otg_destroy(ci);
}

static void ci_get_otg_capable(struct ci_hdrc *ci)
{
	if (ci->platdata->flags & CI_HDRC_DUAL_ROLE_NOT_OTG)
		ci->is_otg = false;
	else
		ci->is_otg = (hw_read(ci, CAP_DCCPARAMS,
				DCCPARAMS_DC | DCCPARAMS_HC)
					== (DCCPARAMS_DC | DCCPARAMS_HC));
	if (ci->is_otg) {
		dev_dbg(ci->dev, "It is OTG capable controller\n");
		/* Disable and clear all OTG irq */
		hw_write_otgsc(ci, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS,
							OTGSC_INT_STATUS_BITS);
	}
}

static ssize_t role_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);

	if (ci->role != CI_ROLE_END)
		return sprintf(buf, "%s\n", ci_role(ci)->name);

	return 0;
}

static ssize_t role_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t n)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	enum ci_role role;
	int ret;

	if (!(ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET])) {
		dev_warn(dev, "Current configuration is not dual-role, quit\n");
		return -EPERM;
	}

	for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++)
		if (!strncmp(buf, ci->roles[role]->name,
			     strlen(ci->roles[role]->name)))
			break;

	if (role == CI_ROLE_END)
		return -EINVAL;

	mutex_lock(&ci->mutex);

	if (role == ci->role) {
		mutex_unlock(&ci->mutex);
		return n;
	}

	pm_runtime_get_sync(dev);
	disable_irq(ci->irq);
	ci_role_stop(ci);
	ret = ci_role_start(ci, role);
	if (!ret && ci->role == CI_ROLE_GADGET)
		ci_handle_vbus_change(ci);
	enable_irq(ci->irq);
	pm_runtime_put_sync(dev);
	mutex_unlock(&ci->mutex);

	return (ret == 0) ? n : ret;
}
static DEVICE_ATTR_RW(role);

static struct attribute *ci_attrs[] = {
	&dev_attr_role.attr,
	NULL,
};
ATTRIBUTE_GROUPS(ci);

static int ci_hdrc_probe(struct platform_device *pdev)
{
	struct usb_role_switch_desc ci_role_switch = {};
	struct device	*dev = &pdev->dev;
	struct ci_hdrc	*ci;
	struct resource	*res;
	void __iomem	*base;
	int		ret;
	enum usb_dr_mode dr_mode;

	if (!dev_get_platdata(dev)) {
		dev_err(dev, "platform data missing\n");
		return -ENODEV;
	}

	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	ci = devm_kzalloc(dev, sizeof(*ci), GFP_KERNEL);
	if (!ci)
		return -ENOMEM;

	spin_lock_init(&ci->lock);
	mutex_init(&ci->mutex);
	INIT_WORK(&ci->power_lost_work, ci_power_lost_work);

	ci->dev = dev;
	ci->platdata = dev_get_platdata(dev);
	ci->imx28_write_fix = !!(ci->platdata->flags &
		CI_HDRC_IMX28_WRITE_FIX);
	ci->supports_runtime_pm = !!(ci->platdata->flags &
		CI_HDRC_SUPPORTS_RUNTIME_PM);
	ci->has_portsc_pec_bug = !!(ci->platdata->flags &
		CI_HDRC_HAS_PORTSC_PEC_MISSED);
	ci->has_short_pkt_limit = !!(ci->platdata->flags &
		CI_HDRC_HAS_SHORT_PKT_LIMIT);
	platform_set_drvdata(pdev, ci);

	ret = hw_device_init(ci, base);
	if (ret < 0) {
		dev_err(dev, "can't initialize hardware\n");
		return -ENODEV;
	}

	ret = ci_ulpi_init(ci);
	if (ret)
		return ret;

	if (ci->platdata->phy) {
		ci->phy = ci->platdata->phy;
	} else if (ci->platdata->usb_phy) {
		ci->usb_phy = ci->platdata->usb_phy;
	} else {
		/* Look for a generic PHY first */
		ci->phy = devm_phy_get(dev->parent, "usb-phy");

		if (PTR_ERR(ci->phy) == -EPROBE_DEFER) {
			ret = -EPROBE_DEFER;
			goto ulpi_exit;
		} else if (IS_ERR(ci->phy)) {
			ci->phy = NULL;
		}

		/* Look for a legacy USB PHY from device-tree next */
		if (!ci->phy) {
			ci->usb_phy = devm_usb_get_phy_by_phandle(dev->parent,
								  "phys", 0);

			if (PTR_ERR(ci->usb_phy) == -EPROBE_DEFER) {
				ret = -EPROBE_DEFER;
				goto ulpi_exit;
			} else if (IS_ERR(ci->usb_phy)) {
				ci->usb_phy = NULL;
			}
		}

		/* Look for any registered legacy USB PHY as last resort */
		if (!ci->phy && !ci->usb_phy) {
			ci->usb_phy = devm_usb_get_phy(dev->parent,
						       USB_PHY_TYPE_USB2);

			if (PTR_ERR(ci->usb_phy) == -EPROBE_DEFER) {
				ret = -EPROBE_DEFER;
				goto ulpi_exit;
			} else if (IS_ERR(ci->usb_phy)) {
				ci->usb_phy = NULL;
			}
		}

		/* No USB PHY was found in the end */
		if (!ci->phy && !ci->usb_phy) {
			ret = -ENXIO;
			goto ulpi_exit;
		}
	}

	ret = ci_usb_phy_init(ci);
	if (ret) {
		dev_err(dev, "unable to init phy: %d\n", ret);
		goto ulpi_exit;
	}

	ci->hw_bank.phys = res->start;

	ci->irq = platform_get_irq(pdev, 0);
	if (ci->irq < 0) {
		ret = ci->irq;
		goto deinit_phy;
	}

	ci_get_otg_capable(ci);

	dr_mode = ci->platdata->dr_mode;
	/* initialize role(s) before the interrupt is requested */
	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
		ret = ci_hdrc_host_init(ci);
		if (ret) {
			if (ret == -ENXIO)
				dev_info(dev, "doesn't support host\n");
			else
				goto deinit_phy;
		}
	}

	if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
		ret = ci_hdrc_gadget_init(ci);
		if (ret) {
			if (ret == -ENXIO)
				dev_info(dev, "doesn't support gadget\n");
			else
				goto deinit_host;
		}
	}

	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
		dev_err(dev, "no supported roles\n");
		ret = -ENODEV;
		goto deinit_gadget;
	}

	if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
		ret = ci_hdrc_otg_init(ci);
		if (ret) {
			dev_err(dev, "init otg fails, ret = %d\n", ret);
			goto deinit_gadget;
		}
	}

	if (device_property_read_bool(dev, "usb-role-switch")) {
		ci_role_switch.set = ci_usb_role_switch_set;
		ci_role_switch.get = ci_usb_role_switch_get;
		ci_role_switch.allow_userspace_control = true;
		ci_role_switch.fwnode = dev_fwnode(dev);
		ci_role_switch.driver_data = ci;
		ci->role_switch = usb_role_switch_register(dev,
					&ci_role_switch);
		if (IS_ERR(ci->role_switch)) {
			ret = PTR_ERR(ci->role_switch);
			goto deinit_otg;
		}
	}

	ci->role = ci_get_role(ci);
	if (!ci_otg_is_fsm_mode(ci)) {
		ret = ci_role_start(ci, ci->role);
		if (ret) {
			dev_err(dev, "can't start %s role\n",
						ci_role(ci)->name);
			goto stop;
		}

		/* only update vbus status for peripheral */
		if (ci->role == CI_ROLE_GADGET)
			ci_handle_vbus_change(ci);
	}

	ret = devm_request_irq(dev, ci->irq, ci_irq_handler, IRQF_SHARED,
			ci->platdata->name, ci);
	if (ret)
		goto stop;

	ret = ci_extcon_register(ci);
	if (ret)
		goto stop;

	if (ci->supports_runtime_pm) {
		pm_runtime_set_active(&pdev->dev);
		pm_runtime_enable(&pdev->dev);
		pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
		pm_runtime_mark_last_busy(ci->dev);
		pm_runtime_use_autosuspend(&pdev->dev);
	}

	if (ci_otg_is_fsm_mode(ci))
		ci_hdrc_otg_fsm_start(ci);

	device_set_wakeup_capable(&pdev->dev, true);
	dbg_create_files(ci);

	return 0;

stop:
	if (ci->role_switch)
		usb_role_switch_unregister(ci->role_switch);
deinit_otg:
	if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
		ci_hdrc_otg_destroy(ci);
deinit_gadget:
	ci_hdrc_gadget_destroy(ci);
deinit_host:
	ci_hdrc_host_destroy(ci);
deinit_phy:
	ci_usb_phy_exit(ci);
ulpi_exit:
	ci_ulpi_exit(ci);

	return ret;
}

static void ci_hdrc_remove(struct platform_device *pdev)
{
	struct ci_hdrc *ci = platform_get_drvdata(pdev);

	if (ci->role_switch)
		usb_role_switch_unregister(ci->role_switch);

	if (ci->supports_runtime_pm) {
		pm_runtime_dont_use_autosuspend(&pdev->dev);
		pm_runtime_get_sync(&pdev->dev);
		pm_runtime_disable(&pdev->dev);
		pm_runtime_put_noidle(&pdev->dev);
	}

	dbg_remove_files(ci);
	ci_role_destroy(ci);
	ci_hdrc_enter_lpm(ci, true);
	ci_usb_phy_exit(ci);
	ci_ulpi_exit(ci);
}

#ifdef CONFIG_PM
/* Prepare wakeup by SRP before suspend */
static void ci_otg_fsm_suspend_for_srp(struct ci_hdrc *ci)
{
	if ((ci->fsm.otg->state == OTG_STATE_A_IDLE) &&
				!hw_read_otgsc(ci, OTGSC_ID)) {
		hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP,
								PORTSC_PP);
		hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_WKCN,
								PORTSC_WKCN);
	}
}

/* Handle SRP when wakeup by data pulse */
static void ci_otg_fsm_wakeup_by_srp(struct ci_hdrc *ci)
{
	if ((ci->fsm.otg->state == OTG_STATE_A_IDLE) &&
		(ci->fsm.a_bus_drop == 1) && (ci->fsm.a_bus_req == 0)) {
		if (!hw_read_otgsc(ci, OTGSC_ID)) {
			ci->fsm.a_srp_det = 1;
			ci->fsm.a_bus_drop = 0;
		} else {
			ci->fsm.id = 1;
		}
		ci_otg_queue_work(ci);
	}
}

static void ci_controller_suspend(struct ci_hdrc *ci)
{
	disable_irq(ci->irq);
	ci_hdrc_enter_lpm(ci, true);
	if (ci->platdata->phy_clkgate_delay_us)
		usleep_range(ci->platdata->phy_clkgate_delay_us,
			     ci->platdata->phy_clkgate_delay_us + 50);
	usb_phy_set_suspend(ci->usb_phy, 1);
	ci->in_lpm = true;
	enable_irq(ci->irq);
}

/*
 * Handle the wakeup interrupt triggered by extcon connector
 * We need to call ci_irq again for extcon since the first
 * interrupt (wakeup int) only let the controller be out of
 * low power mode, but not handle any interrupts.
 */
static void ci_extcon_wakeup_int(struct ci_hdrc *ci)
{
	struct ci_hdrc_cable *cable_id, *cable_vbus;
	u32 otgsc = hw_read_otgsc(ci, ~0);

	cable_id = &ci->platdata->id_extcon;
	cable_vbus = &ci->platdata->vbus_extcon;

	if ((!IS_ERR(cable_id->edev) || ci->role_switch)
		&& ci->is_otg &&
		(otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS))
		ci_irq(ci);

	if ((!IS_ERR(cable_vbus->edev) || ci->role_switch)
		&& ci->is_otg &&
		(otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS))
		ci_irq(ci);
}

static int ci_controller_resume(struct device *dev)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	int ret;

	dev_dbg(dev, "at %s\n", __func__);

	if (!ci->in_lpm) {
		WARN_ON(1);
		return 0;
	}

	ci_hdrc_enter_lpm(ci, false);

	ret = ci_ulpi_resume(ci);
	if (ret)
		return ret;

	if (ci->usb_phy) {
		usb_phy_set_suspend(ci->usb_phy, 0);
		usb_phy_set_wakeup(ci->usb_phy, false);
		hw_wait_phy_stable();
	}

	ci->in_lpm = false;
	if (ci->wakeup_int) {
		ci->wakeup_int = false;
		pm_runtime_put_autosuspend(ci->dev);
		enable_irq(ci->irq);
		if (ci_otg_is_fsm_mode(ci))
			ci_otg_fsm_wakeup_by_srp(ci);
		ci_extcon_wakeup_int(ci);
	}

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int ci_suspend(struct device *dev)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);

	if (ci->wq)
		flush_workqueue(ci->wq);
	/*
	 * Controller needs to be active during suspend, otherwise the core
	 * may run resume when the parent is at suspend if other driver's
	 * suspend fails, it occurs before parent's suspend has not started,
	 * but the core suspend has finished.
	 */
	if (ci->in_lpm)
		pm_runtime_resume(dev);

	if (ci->in_lpm) {
		WARN_ON(1);
		return 0;
	}

	/* Extra routine per role before system suspend */
	if (ci->role != CI_ROLE_END && ci_role(ci)->suspend)
		ci_role(ci)->suspend(ci);

	if (device_may_wakeup(dev)) {
		if (ci_otg_is_fsm_mode(ci))
			ci_otg_fsm_suspend_for_srp(ci);

		usb_phy_set_wakeup(ci->usb_phy, true);
		enable_irq_wake(ci->irq);
	}

	ci_controller_suspend(ci);

	return 0;
}

static int ci_resume(struct device *dev)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	bool power_lost;
	int ret;

	/* Since ASYNCLISTADDR (host mode) and ENDPTLISTADDR (device
	 * mode) share the same register address. We can check if
	 * controller resume from power lost based on this address
	 * due to this register will be reset after power lost.
	 */
	power_lost = !hw_read(ci, OP_ENDPTLISTADDR, ~0);

	if (device_may_wakeup(dev))
		disable_irq_wake(ci->irq);

	ret = ci_controller_resume(dev);
	if (ret)
		return ret;

	if (power_lost) {
		/* shutdown and re-init for phy */
		ci_usb_phy_exit(ci);
		ci_usb_phy_init(ci);
	}

	/* Extra routine per role after system resume */
	if (ci->role != CI_ROLE_END && ci_role(ci)->resume)
		ci_role(ci)->resume(ci, power_lost);

	if (power_lost)
		queue_work(system_freezable_wq, &ci->power_lost_work);

	if (ci->supports_runtime_pm) {
		pm_runtime_disable(dev);
		pm_runtime_set_active(dev);
		pm_runtime_enable(dev);
	}

	return ret;
}
#endif /* CONFIG_PM_SLEEP */

static int ci_runtime_suspend(struct device *dev)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);

	dev_dbg(dev, "at %s\n", __func__);

	if (ci->in_lpm) {
		WARN_ON(1);
		return 0;
	}

	if (ci_otg_is_fsm_mode(ci))
		ci_otg_fsm_suspend_for_srp(ci);

	usb_phy_set_wakeup(ci->usb_phy, true);
	ci_controller_suspend(ci);

	return 0;
}

static int ci_runtime_resume(struct device *dev)
{
	return ci_controller_resume(dev);
}

#endif /* CONFIG_PM */
static const struct dev_pm_ops ci_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume)
	SET_RUNTIME_PM_OPS(ci_runtime_suspend, ci_runtime_resume, NULL)
};

static struct platform_driver ci_hdrc_driver = {
	.probe	= ci_hdrc_probe,
	.remove = ci_hdrc_remove,
	.driver	= {
		.name	= "ci_hdrc",
		.pm	= &ci_pm_ops,
		.dev_groups = ci_groups,
	},
};

static int __init ci_hdrc_platform_register(void)
{
	ci_hdrc_host_driver_init();
	return platform_driver_register(&ci_hdrc_driver);
}
module_init(ci_hdrc_platform_register);

static void __exit ci_hdrc_platform_unregister(void)
{
	platform_driver_unregister(&ci_hdrc_driver);
}
module_exit(ci_hdrc_platform_unregister);

MODULE_ALIAS("platform:ci_hdrc");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("David Lopo <dlopo@chipidea.mips.com>");
MODULE_DESCRIPTION("ChipIdea HDRC Driver");
