15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+
294ae9843SFelipe Balbi /*
394ae9843SFelipe Balbi * Copyright (C) 2011 Marvell International Ltd. All rights reserved.
494ae9843SFelipe Balbi * Author: Chao Xie <chao.xie@marvell.com>
594ae9843SFelipe Balbi * Neil Zhang <zhangwm@marvell.com>
694ae9843SFelipe Balbi */
794ae9843SFelipe Balbi
894ae9843SFelipe Balbi #include <linux/module.h>
994ae9843SFelipe Balbi #include <linux/kernel.h>
1094ae9843SFelipe Balbi #include <linux/io.h>
11f158afecSChunfeng Yun #include <linux/iopoll.h>
1294ae9843SFelipe Balbi #include <linux/uaccess.h>
1394ae9843SFelipe Balbi #include <linux/device.h>
1494ae9843SFelipe Balbi #include <linux/proc_fs.h>
1594ae9843SFelipe Balbi #include <linux/clk.h>
1694ae9843SFelipe Balbi #include <linux/workqueue.h>
1794ae9843SFelipe Balbi #include <linux/platform_device.h>
1894ae9843SFelipe Balbi
1994ae9843SFelipe Balbi #include <linux/usb.h>
2094ae9843SFelipe Balbi #include <linux/usb/ch9.h>
2194ae9843SFelipe Balbi #include <linux/usb/otg.h>
2294ae9843SFelipe Balbi #include <linux/usb/gadget.h>
2394ae9843SFelipe Balbi #include <linux/usb/hcd.h>
2494ae9843SFelipe Balbi #include <linux/platform_data/mv_usb.h>
2594ae9843SFelipe Balbi
2694ae9843SFelipe Balbi #include "phy-mv-usb.h"
2794ae9843SFelipe Balbi
2894ae9843SFelipe Balbi #define DRIVER_DESC "Marvell USB OTG transceiver driver"
2994ae9843SFelipe Balbi
3094ae9843SFelipe Balbi MODULE_DESCRIPTION(DRIVER_DESC);
3194ae9843SFelipe Balbi MODULE_LICENSE("GPL");
3294ae9843SFelipe Balbi
3394ae9843SFelipe Balbi static const char driver_name[] = "mv-otg";
3494ae9843SFelipe Balbi
3594ae9843SFelipe Balbi static char *state_string[] = {
3694ae9843SFelipe Balbi "undefined",
3794ae9843SFelipe Balbi "b_idle",
3894ae9843SFelipe Balbi "b_srp_init",
3994ae9843SFelipe Balbi "b_peripheral",
4094ae9843SFelipe Balbi "b_wait_acon",
4194ae9843SFelipe Balbi "b_host",
4294ae9843SFelipe Balbi "a_idle",
4394ae9843SFelipe Balbi "a_wait_vrise",
4494ae9843SFelipe Balbi "a_wait_bcon",
4594ae9843SFelipe Balbi "a_host",
4694ae9843SFelipe Balbi "a_suspend",
4794ae9843SFelipe Balbi "a_peripheral",
4894ae9843SFelipe Balbi "a_wait_vfall",
4994ae9843SFelipe Balbi "a_vbus_err"
5094ae9843SFelipe Balbi };
5194ae9843SFelipe Balbi
mv_otg_set_vbus(struct usb_otg * otg,bool on)5294ae9843SFelipe Balbi static int mv_otg_set_vbus(struct usb_otg *otg, bool on)
5394ae9843SFelipe Balbi {
5419c1eac2SAntoine Tenart struct mv_otg *mvotg = container_of(otg->usb_phy, struct mv_otg, phy);
5594ae9843SFelipe Balbi if (mvotg->pdata->set_vbus == NULL)
5694ae9843SFelipe Balbi return -ENODEV;
5794ae9843SFelipe Balbi
5894ae9843SFelipe Balbi return mvotg->pdata->set_vbus(on);
5994ae9843SFelipe Balbi }
6094ae9843SFelipe Balbi
mv_otg_set_host(struct usb_otg * otg,struct usb_bus * host)6194ae9843SFelipe Balbi static int mv_otg_set_host(struct usb_otg *otg,
6294ae9843SFelipe Balbi struct usb_bus *host)
6394ae9843SFelipe Balbi {
6494ae9843SFelipe Balbi otg->host = host;
6594ae9843SFelipe Balbi
6694ae9843SFelipe Balbi return 0;
6794ae9843SFelipe Balbi }
6894ae9843SFelipe Balbi
mv_otg_set_peripheral(struct usb_otg * otg,struct usb_gadget * gadget)6994ae9843SFelipe Balbi static int mv_otg_set_peripheral(struct usb_otg *otg,
7094ae9843SFelipe Balbi struct usb_gadget *gadget)
7194ae9843SFelipe Balbi {
7294ae9843SFelipe Balbi otg->gadget = gadget;
7394ae9843SFelipe Balbi
7494ae9843SFelipe Balbi return 0;
7594ae9843SFelipe Balbi }
7694ae9843SFelipe Balbi
mv_otg_run_state_machine(struct mv_otg * mvotg,unsigned long delay)7794ae9843SFelipe Balbi static void mv_otg_run_state_machine(struct mv_otg *mvotg,
7894ae9843SFelipe Balbi unsigned long delay)
7994ae9843SFelipe Balbi {
8094ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "transceiver is updated\n");
8194ae9843SFelipe Balbi if (!mvotg->qwork)
8294ae9843SFelipe Balbi return;
8394ae9843SFelipe Balbi
8494ae9843SFelipe Balbi queue_delayed_work(mvotg->qwork, &mvotg->work, delay);
8594ae9843SFelipe Balbi }
8694ae9843SFelipe Balbi
mv_otg_timer_await_bcon(struct timer_list * t)879718756fSKees Cook static void mv_otg_timer_await_bcon(struct timer_list *t)
8894ae9843SFelipe Balbi {
899718756fSKees Cook struct mv_otg *mvotg = from_timer(mvotg, t,
909718756fSKees Cook otg_ctrl.timer[A_WAIT_BCON_TIMER]);
9194ae9843SFelipe Balbi
9294ae9843SFelipe Balbi mvotg->otg_ctrl.a_wait_bcon_timeout = 1;
9394ae9843SFelipe Balbi
9494ae9843SFelipe Balbi dev_info(&mvotg->pdev->dev, "B Device No Response!\n");
9594ae9843SFelipe Balbi
9694ae9843SFelipe Balbi if (spin_trylock(&mvotg->wq_lock)) {
9794ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
9894ae9843SFelipe Balbi spin_unlock(&mvotg->wq_lock);
9994ae9843SFelipe Balbi }
10094ae9843SFelipe Balbi }
10194ae9843SFelipe Balbi
mv_otg_cancel_timer(struct mv_otg * mvotg,unsigned int id)10294ae9843SFelipe Balbi static int mv_otg_cancel_timer(struct mv_otg *mvotg, unsigned int id)
10394ae9843SFelipe Balbi {
10494ae9843SFelipe Balbi struct timer_list *timer;
10594ae9843SFelipe Balbi
10694ae9843SFelipe Balbi if (id >= OTG_TIMER_NUM)
10794ae9843SFelipe Balbi return -EINVAL;
10894ae9843SFelipe Balbi
10994ae9843SFelipe Balbi timer = &mvotg->otg_ctrl.timer[id];
11094ae9843SFelipe Balbi
11194ae9843SFelipe Balbi if (timer_pending(timer))
11294ae9843SFelipe Balbi del_timer(timer);
11394ae9843SFelipe Balbi
11494ae9843SFelipe Balbi return 0;
11594ae9843SFelipe Balbi }
11694ae9843SFelipe Balbi
mv_otg_set_timer(struct mv_otg * mvotg,unsigned int id,unsigned long interval)11794ae9843SFelipe Balbi static int mv_otg_set_timer(struct mv_otg *mvotg, unsigned int id,
1189718756fSKees Cook unsigned long interval)
11994ae9843SFelipe Balbi {
12094ae9843SFelipe Balbi struct timer_list *timer;
12194ae9843SFelipe Balbi
12294ae9843SFelipe Balbi if (id >= OTG_TIMER_NUM)
12394ae9843SFelipe Balbi return -EINVAL;
12494ae9843SFelipe Balbi
12594ae9843SFelipe Balbi timer = &mvotg->otg_ctrl.timer[id];
12694ae9843SFelipe Balbi if (timer_pending(timer)) {
12794ae9843SFelipe Balbi dev_err(&mvotg->pdev->dev, "Timer%d is already running\n", id);
12894ae9843SFelipe Balbi return -EBUSY;
12994ae9843SFelipe Balbi }
13094ae9843SFelipe Balbi
13194ae9843SFelipe Balbi timer->expires = jiffies + interval;
13294ae9843SFelipe Balbi add_timer(timer);
13394ae9843SFelipe Balbi
13494ae9843SFelipe Balbi return 0;
13594ae9843SFelipe Balbi }
13694ae9843SFelipe Balbi
mv_otg_reset(struct mv_otg * mvotg)13794ae9843SFelipe Balbi static int mv_otg_reset(struct mv_otg *mvotg)
13894ae9843SFelipe Balbi {
13994ae9843SFelipe Balbi u32 tmp;
140f158afecSChunfeng Yun int ret;
14194ae9843SFelipe Balbi
14294ae9843SFelipe Balbi /* Stop the controller */
14394ae9843SFelipe Balbi tmp = readl(&mvotg->op_regs->usbcmd);
14494ae9843SFelipe Balbi tmp &= ~USBCMD_RUN_STOP;
14594ae9843SFelipe Balbi writel(tmp, &mvotg->op_regs->usbcmd);
14694ae9843SFelipe Balbi
14794ae9843SFelipe Balbi /* Reset the controller to get default values */
14894ae9843SFelipe Balbi writel(USBCMD_CTRL_RESET, &mvotg->op_regs->usbcmd);
14994ae9843SFelipe Balbi
150f158afecSChunfeng Yun ret = readl_poll_timeout_atomic(&mvotg->op_regs->usbcmd, tmp,
151f158afecSChunfeng Yun (tmp & USBCMD_CTRL_RESET), 10, 10000);
152f158afecSChunfeng Yun if (ret < 0) {
15394ae9843SFelipe Balbi dev_err(&mvotg->pdev->dev,
15494ae9843SFelipe Balbi "Wait for RESET completed TIMEOUT\n");
155f158afecSChunfeng Yun return ret;
15694ae9843SFelipe Balbi }
15794ae9843SFelipe Balbi
15894ae9843SFelipe Balbi writel(0x0, &mvotg->op_regs->usbintr);
15994ae9843SFelipe Balbi tmp = readl(&mvotg->op_regs->usbsts);
16094ae9843SFelipe Balbi writel(tmp, &mvotg->op_regs->usbsts);
16194ae9843SFelipe Balbi
16294ae9843SFelipe Balbi return 0;
16394ae9843SFelipe Balbi }
16494ae9843SFelipe Balbi
mv_otg_init_irq(struct mv_otg * mvotg)16594ae9843SFelipe Balbi static void mv_otg_init_irq(struct mv_otg *mvotg)
16694ae9843SFelipe Balbi {
16794ae9843SFelipe Balbi u32 otgsc;
16894ae9843SFelipe Balbi
16994ae9843SFelipe Balbi mvotg->irq_en = OTGSC_INTR_A_SESSION_VALID
17094ae9843SFelipe Balbi | OTGSC_INTR_A_VBUS_VALID;
17194ae9843SFelipe Balbi mvotg->irq_status = OTGSC_INTSTS_A_SESSION_VALID
17294ae9843SFelipe Balbi | OTGSC_INTSTS_A_VBUS_VALID;
17394ae9843SFelipe Balbi
17494ae9843SFelipe Balbi if (mvotg->pdata->vbus == NULL) {
17594ae9843SFelipe Balbi mvotg->irq_en |= OTGSC_INTR_B_SESSION_VALID
17694ae9843SFelipe Balbi | OTGSC_INTR_B_SESSION_END;
17794ae9843SFelipe Balbi mvotg->irq_status |= OTGSC_INTSTS_B_SESSION_VALID
17894ae9843SFelipe Balbi | OTGSC_INTSTS_B_SESSION_END;
17994ae9843SFelipe Balbi }
18094ae9843SFelipe Balbi
18194ae9843SFelipe Balbi if (mvotg->pdata->id == NULL) {
18294ae9843SFelipe Balbi mvotg->irq_en |= OTGSC_INTR_USB_ID;
18394ae9843SFelipe Balbi mvotg->irq_status |= OTGSC_INTSTS_USB_ID;
18494ae9843SFelipe Balbi }
18594ae9843SFelipe Balbi
18694ae9843SFelipe Balbi otgsc = readl(&mvotg->op_regs->otgsc);
18794ae9843SFelipe Balbi otgsc |= mvotg->irq_en;
18894ae9843SFelipe Balbi writel(otgsc, &mvotg->op_regs->otgsc);
18994ae9843SFelipe Balbi }
19094ae9843SFelipe Balbi
mv_otg_start_host(struct mv_otg * mvotg,int on)19194ae9843SFelipe Balbi static void mv_otg_start_host(struct mv_otg *mvotg, int on)
19294ae9843SFelipe Balbi {
19394ae9843SFelipe Balbi #ifdef CONFIG_USB
19494ae9843SFelipe Balbi struct usb_otg *otg = mvotg->phy.otg;
19594ae9843SFelipe Balbi struct usb_hcd *hcd;
19694ae9843SFelipe Balbi
19794ae9843SFelipe Balbi if (!otg->host)
19894ae9843SFelipe Balbi return;
19994ae9843SFelipe Balbi
20094ae9843SFelipe Balbi dev_info(&mvotg->pdev->dev, "%s host\n", on ? "start" : "stop");
20194ae9843SFelipe Balbi
20294ae9843SFelipe Balbi hcd = bus_to_hcd(otg->host);
20394ae9843SFelipe Balbi
2043c9740a1SPeter Chen if (on) {
20594ae9843SFelipe Balbi usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
2063c9740a1SPeter Chen device_wakeup_enable(hcd->self.controller);
2073c9740a1SPeter Chen } else {
20894ae9843SFelipe Balbi usb_remove_hcd(hcd);
2093c9740a1SPeter Chen }
21094ae9843SFelipe Balbi #endif /* CONFIG_USB */
21194ae9843SFelipe Balbi }
21294ae9843SFelipe Balbi
mv_otg_start_periphrals(struct mv_otg * mvotg,int on)21394ae9843SFelipe Balbi static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on)
21494ae9843SFelipe Balbi {
21594ae9843SFelipe Balbi struct usb_otg *otg = mvotg->phy.otg;
21694ae9843SFelipe Balbi
21794ae9843SFelipe Balbi if (!otg->gadget)
21894ae9843SFelipe Balbi return;
21994ae9843SFelipe Balbi
22094ae9843SFelipe Balbi dev_info(mvotg->phy.dev, "gadget %s\n", on ? "on" : "off");
22194ae9843SFelipe Balbi
22294ae9843SFelipe Balbi if (on)
22394ae9843SFelipe Balbi usb_gadget_vbus_connect(otg->gadget);
22494ae9843SFelipe Balbi else
22594ae9843SFelipe Balbi usb_gadget_vbus_disconnect(otg->gadget);
22694ae9843SFelipe Balbi }
22794ae9843SFelipe Balbi
otg_clock_enable(struct mv_otg * mvotg)22894ae9843SFelipe Balbi static void otg_clock_enable(struct mv_otg *mvotg)
22994ae9843SFelipe Balbi {
230df18fedaSChao Xie clk_prepare_enable(mvotg->clk);
23194ae9843SFelipe Balbi }
23294ae9843SFelipe Balbi
otg_clock_disable(struct mv_otg * mvotg)23394ae9843SFelipe Balbi static void otg_clock_disable(struct mv_otg *mvotg)
23494ae9843SFelipe Balbi {
235df18fedaSChao Xie clk_disable_unprepare(mvotg->clk);
23694ae9843SFelipe Balbi }
23794ae9843SFelipe Balbi
mv_otg_enable_internal(struct mv_otg * mvotg)23894ae9843SFelipe Balbi static int mv_otg_enable_internal(struct mv_otg *mvotg)
23994ae9843SFelipe Balbi {
24094ae9843SFelipe Balbi int retval = 0;
24194ae9843SFelipe Balbi
24294ae9843SFelipe Balbi if (mvotg->active)
24394ae9843SFelipe Balbi return 0;
24494ae9843SFelipe Balbi
24594ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "otg enabled\n");
24694ae9843SFelipe Balbi
24794ae9843SFelipe Balbi otg_clock_enable(mvotg);
24894ae9843SFelipe Balbi if (mvotg->pdata->phy_init) {
24994ae9843SFelipe Balbi retval = mvotg->pdata->phy_init(mvotg->phy_regs);
25094ae9843SFelipe Balbi if (retval) {
25194ae9843SFelipe Balbi dev_err(&mvotg->pdev->dev,
25294ae9843SFelipe Balbi "init phy error %d\n", retval);
25394ae9843SFelipe Balbi otg_clock_disable(mvotg);
25494ae9843SFelipe Balbi return retval;
25594ae9843SFelipe Balbi }
25694ae9843SFelipe Balbi }
25794ae9843SFelipe Balbi mvotg->active = 1;
25894ae9843SFelipe Balbi
25994ae9843SFelipe Balbi return 0;
26094ae9843SFelipe Balbi
26194ae9843SFelipe Balbi }
26294ae9843SFelipe Balbi
mv_otg_enable(struct mv_otg * mvotg)26394ae9843SFelipe Balbi static int mv_otg_enable(struct mv_otg *mvotg)
26494ae9843SFelipe Balbi {
26594ae9843SFelipe Balbi if (mvotg->clock_gating)
26694ae9843SFelipe Balbi return mv_otg_enable_internal(mvotg);
26794ae9843SFelipe Balbi
26894ae9843SFelipe Balbi return 0;
26994ae9843SFelipe Balbi }
27094ae9843SFelipe Balbi
mv_otg_disable_internal(struct mv_otg * mvotg)27194ae9843SFelipe Balbi static void mv_otg_disable_internal(struct mv_otg *mvotg)
27294ae9843SFelipe Balbi {
27394ae9843SFelipe Balbi if (mvotg->active) {
27494ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "otg disabled\n");
27594ae9843SFelipe Balbi if (mvotg->pdata->phy_deinit)
27694ae9843SFelipe Balbi mvotg->pdata->phy_deinit(mvotg->phy_regs);
27794ae9843SFelipe Balbi otg_clock_disable(mvotg);
27894ae9843SFelipe Balbi mvotg->active = 0;
27994ae9843SFelipe Balbi }
28094ae9843SFelipe Balbi }
28194ae9843SFelipe Balbi
mv_otg_disable(struct mv_otg * mvotg)28294ae9843SFelipe Balbi static void mv_otg_disable(struct mv_otg *mvotg)
28394ae9843SFelipe Balbi {
28494ae9843SFelipe Balbi if (mvotg->clock_gating)
28594ae9843SFelipe Balbi mv_otg_disable_internal(mvotg);
28694ae9843SFelipe Balbi }
28794ae9843SFelipe Balbi
mv_otg_update_inputs(struct mv_otg * mvotg)28894ae9843SFelipe Balbi static void mv_otg_update_inputs(struct mv_otg *mvotg)
28994ae9843SFelipe Balbi {
29094ae9843SFelipe Balbi struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl;
29194ae9843SFelipe Balbi u32 otgsc;
29294ae9843SFelipe Balbi
29394ae9843SFelipe Balbi otgsc = readl(&mvotg->op_regs->otgsc);
29494ae9843SFelipe Balbi
29594ae9843SFelipe Balbi if (mvotg->pdata->vbus) {
29694ae9843SFelipe Balbi if (mvotg->pdata->vbus->poll() == VBUS_HIGH) {
29794ae9843SFelipe Balbi otg_ctrl->b_sess_vld = 1;
29894ae9843SFelipe Balbi otg_ctrl->b_sess_end = 0;
29994ae9843SFelipe Balbi } else {
30094ae9843SFelipe Balbi otg_ctrl->b_sess_vld = 0;
30194ae9843SFelipe Balbi otg_ctrl->b_sess_end = 1;
30294ae9843SFelipe Balbi }
30394ae9843SFelipe Balbi } else {
30494ae9843SFelipe Balbi otg_ctrl->b_sess_vld = !!(otgsc & OTGSC_STS_B_SESSION_VALID);
30594ae9843SFelipe Balbi otg_ctrl->b_sess_end = !!(otgsc & OTGSC_STS_B_SESSION_END);
30694ae9843SFelipe Balbi }
30794ae9843SFelipe Balbi
30894ae9843SFelipe Balbi if (mvotg->pdata->id)
30994ae9843SFelipe Balbi otg_ctrl->id = !!mvotg->pdata->id->poll();
31094ae9843SFelipe Balbi else
31194ae9843SFelipe Balbi otg_ctrl->id = !!(otgsc & OTGSC_STS_USB_ID);
31294ae9843SFelipe Balbi
31394ae9843SFelipe Balbi if (mvotg->pdata->otg_force_a_bus_req && !otg_ctrl->id)
31494ae9843SFelipe Balbi otg_ctrl->a_bus_req = 1;
31594ae9843SFelipe Balbi
31694ae9843SFelipe Balbi otg_ctrl->a_sess_vld = !!(otgsc & OTGSC_STS_A_SESSION_VALID);
31794ae9843SFelipe Balbi otg_ctrl->a_vbus_vld = !!(otgsc & OTGSC_STS_A_VBUS_VALID);
31894ae9843SFelipe Balbi
31994ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "%s: ", __func__);
32094ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "id %d\n", otg_ctrl->id);
32194ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "b_sess_vld %d\n", otg_ctrl->b_sess_vld);
32294ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "b_sess_end %d\n", otg_ctrl->b_sess_end);
32394ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "a_vbus_vld %d\n", otg_ctrl->a_vbus_vld);
32494ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev, "a_sess_vld %d\n", otg_ctrl->a_sess_vld);
32594ae9843SFelipe Balbi }
32694ae9843SFelipe Balbi
mv_otg_update_state(struct mv_otg * mvotg)32794ae9843SFelipe Balbi static void mv_otg_update_state(struct mv_otg *mvotg)
32894ae9843SFelipe Balbi {
32994ae9843SFelipe Balbi struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl;
330e47d9254SAntoine Tenart int old_state = mvotg->phy.otg->state;
33194ae9843SFelipe Balbi
33294ae9843SFelipe Balbi switch (old_state) {
33394ae9843SFelipe Balbi case OTG_STATE_UNDEFINED:
334e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_B_IDLE;
3354e71e079SGustavo A. R. Silva fallthrough;
33694ae9843SFelipe Balbi case OTG_STATE_B_IDLE:
33794ae9843SFelipe Balbi if (otg_ctrl->id == 0)
338e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_IDLE;
33994ae9843SFelipe Balbi else if (otg_ctrl->b_sess_vld)
340e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_B_PERIPHERAL;
34194ae9843SFelipe Balbi break;
34294ae9843SFelipe Balbi case OTG_STATE_B_PERIPHERAL:
34394ae9843SFelipe Balbi if (!otg_ctrl->b_sess_vld || otg_ctrl->id == 0)
344e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_B_IDLE;
34594ae9843SFelipe Balbi break;
34694ae9843SFelipe Balbi case OTG_STATE_A_IDLE:
34794ae9843SFelipe Balbi if (otg_ctrl->id)
348e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_B_IDLE;
34994ae9843SFelipe Balbi else if (!(otg_ctrl->a_bus_drop) &&
35094ae9843SFelipe Balbi (otg_ctrl->a_bus_req || otg_ctrl->a_srp_det))
351e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_WAIT_VRISE;
35294ae9843SFelipe Balbi break;
35394ae9843SFelipe Balbi case OTG_STATE_A_WAIT_VRISE:
35494ae9843SFelipe Balbi if (otg_ctrl->a_vbus_vld)
355e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON;
35694ae9843SFelipe Balbi break;
35794ae9843SFelipe Balbi case OTG_STATE_A_WAIT_BCON:
35894ae9843SFelipe Balbi if (otg_ctrl->id || otg_ctrl->a_bus_drop
35994ae9843SFelipe Balbi || otg_ctrl->a_wait_bcon_timeout) {
36094ae9843SFelipe Balbi mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER);
36194ae9843SFelipe Balbi mvotg->otg_ctrl.a_wait_bcon_timeout = 0;
362e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL;
36394ae9843SFelipe Balbi otg_ctrl->a_bus_req = 0;
36494ae9843SFelipe Balbi } else if (!otg_ctrl->a_vbus_vld) {
36594ae9843SFelipe Balbi mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER);
36694ae9843SFelipe Balbi mvotg->otg_ctrl.a_wait_bcon_timeout = 0;
367e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR;
36894ae9843SFelipe Balbi } else if (otg_ctrl->b_conn) {
36994ae9843SFelipe Balbi mv_otg_cancel_timer(mvotg, A_WAIT_BCON_TIMER);
37094ae9843SFelipe Balbi mvotg->otg_ctrl.a_wait_bcon_timeout = 0;
371e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_HOST;
37294ae9843SFelipe Balbi }
37394ae9843SFelipe Balbi break;
37494ae9843SFelipe Balbi case OTG_STATE_A_HOST:
37594ae9843SFelipe Balbi if (otg_ctrl->id || !otg_ctrl->b_conn
37694ae9843SFelipe Balbi || otg_ctrl->a_bus_drop)
377e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_WAIT_BCON;
37894ae9843SFelipe Balbi else if (!otg_ctrl->a_vbus_vld)
379e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_VBUS_ERR;
38094ae9843SFelipe Balbi break;
38194ae9843SFelipe Balbi case OTG_STATE_A_WAIT_VFALL:
38294ae9843SFelipe Balbi if (otg_ctrl->id
38394ae9843SFelipe Balbi || (!otg_ctrl->b_conn && otg_ctrl->a_sess_vld)
38494ae9843SFelipe Balbi || otg_ctrl->a_bus_req)
385e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_IDLE;
38694ae9843SFelipe Balbi break;
38794ae9843SFelipe Balbi case OTG_STATE_A_VBUS_ERR:
38894ae9843SFelipe Balbi if (otg_ctrl->id || otg_ctrl->a_clr_err
38994ae9843SFelipe Balbi || otg_ctrl->a_bus_drop) {
39094ae9843SFelipe Balbi otg_ctrl->a_clr_err = 0;
391e47d9254SAntoine Tenart mvotg->phy.otg->state = OTG_STATE_A_WAIT_VFALL;
39294ae9843SFelipe Balbi }
39394ae9843SFelipe Balbi break;
39494ae9843SFelipe Balbi default:
39594ae9843SFelipe Balbi break;
39694ae9843SFelipe Balbi }
39794ae9843SFelipe Balbi }
39894ae9843SFelipe Balbi
mv_otg_work(struct work_struct * work)39994ae9843SFelipe Balbi static void mv_otg_work(struct work_struct *work)
40094ae9843SFelipe Balbi {
40194ae9843SFelipe Balbi struct mv_otg *mvotg;
40294ae9843SFelipe Balbi struct usb_otg *otg;
40394ae9843SFelipe Balbi int old_state;
40494ae9843SFelipe Balbi
40594ae9843SFelipe Balbi mvotg = container_of(to_delayed_work(work), struct mv_otg, work);
40694ae9843SFelipe Balbi
40794ae9843SFelipe Balbi run:
40894ae9843SFelipe Balbi /* work queue is single thread, or we need spin_lock to protect */
409e47d9254SAntoine Tenart otg = mvotg->phy.otg;
410e47d9254SAntoine Tenart old_state = otg->state;
41194ae9843SFelipe Balbi
41294ae9843SFelipe Balbi if (!mvotg->active)
41394ae9843SFelipe Balbi return;
41494ae9843SFelipe Balbi
41594ae9843SFelipe Balbi mv_otg_update_inputs(mvotg);
41694ae9843SFelipe Balbi mv_otg_update_state(mvotg);
41794ae9843SFelipe Balbi
418e47d9254SAntoine Tenart if (old_state != mvotg->phy.otg->state) {
41994ae9843SFelipe Balbi dev_info(&mvotg->pdev->dev, "change from state %s to %s\n",
42094ae9843SFelipe Balbi state_string[old_state],
421e47d9254SAntoine Tenart state_string[mvotg->phy.otg->state]);
42294ae9843SFelipe Balbi
423e47d9254SAntoine Tenart switch (mvotg->phy.otg->state) {
42494ae9843SFelipe Balbi case OTG_STATE_B_IDLE:
42594ae9843SFelipe Balbi otg->default_a = 0;
42694ae9843SFelipe Balbi if (old_state == OTG_STATE_B_PERIPHERAL)
42794ae9843SFelipe Balbi mv_otg_start_periphrals(mvotg, 0);
42894ae9843SFelipe Balbi mv_otg_reset(mvotg);
42994ae9843SFelipe Balbi mv_otg_disable(mvotg);
430b20f3f9eSKiran Raparthy usb_phy_set_event(&mvotg->phy, USB_EVENT_NONE);
43194ae9843SFelipe Balbi break;
43294ae9843SFelipe Balbi case OTG_STATE_B_PERIPHERAL:
43394ae9843SFelipe Balbi mv_otg_enable(mvotg);
43494ae9843SFelipe Balbi mv_otg_start_periphrals(mvotg, 1);
435b20f3f9eSKiran Raparthy usb_phy_set_event(&mvotg->phy, USB_EVENT_ENUMERATED);
43694ae9843SFelipe Balbi break;
43794ae9843SFelipe Balbi case OTG_STATE_A_IDLE:
43894ae9843SFelipe Balbi otg->default_a = 1;
43994ae9843SFelipe Balbi mv_otg_enable(mvotg);
44094ae9843SFelipe Balbi if (old_state == OTG_STATE_A_WAIT_VFALL)
44194ae9843SFelipe Balbi mv_otg_start_host(mvotg, 0);
44294ae9843SFelipe Balbi mv_otg_reset(mvotg);
44394ae9843SFelipe Balbi break;
44494ae9843SFelipe Balbi case OTG_STATE_A_WAIT_VRISE:
44594ae9843SFelipe Balbi mv_otg_set_vbus(otg, 1);
44694ae9843SFelipe Balbi break;
44794ae9843SFelipe Balbi case OTG_STATE_A_WAIT_BCON:
44894ae9843SFelipe Balbi if (old_state != OTG_STATE_A_HOST)
44994ae9843SFelipe Balbi mv_otg_start_host(mvotg, 1);
45094ae9843SFelipe Balbi mv_otg_set_timer(mvotg, A_WAIT_BCON_TIMER,
4519718756fSKees Cook T_A_WAIT_BCON);
45294ae9843SFelipe Balbi /*
45394ae9843SFelipe Balbi * Now, we directly enter A_HOST. So set b_conn = 1
45494ae9843SFelipe Balbi * here. In fact, it need host driver to notify us.
45594ae9843SFelipe Balbi */
45694ae9843SFelipe Balbi mvotg->otg_ctrl.b_conn = 1;
45794ae9843SFelipe Balbi break;
45894ae9843SFelipe Balbi case OTG_STATE_A_HOST:
45994ae9843SFelipe Balbi break;
46094ae9843SFelipe Balbi case OTG_STATE_A_WAIT_VFALL:
46194ae9843SFelipe Balbi /*
46294ae9843SFelipe Balbi * Now, we has exited A_HOST. So set b_conn = 0
46394ae9843SFelipe Balbi * here. In fact, it need host driver to notify us.
46494ae9843SFelipe Balbi */
46594ae9843SFelipe Balbi mvotg->otg_ctrl.b_conn = 0;
46694ae9843SFelipe Balbi mv_otg_set_vbus(otg, 0);
46794ae9843SFelipe Balbi break;
46894ae9843SFelipe Balbi case OTG_STATE_A_VBUS_ERR:
46994ae9843SFelipe Balbi break;
47094ae9843SFelipe Balbi default:
47194ae9843SFelipe Balbi break;
47294ae9843SFelipe Balbi }
47394ae9843SFelipe Balbi goto run;
47494ae9843SFelipe Balbi }
47594ae9843SFelipe Balbi }
47694ae9843SFelipe Balbi
mv_otg_irq(int irq,void * dev)47794ae9843SFelipe Balbi static irqreturn_t mv_otg_irq(int irq, void *dev)
47894ae9843SFelipe Balbi {
47994ae9843SFelipe Balbi struct mv_otg *mvotg = dev;
48094ae9843SFelipe Balbi u32 otgsc;
48194ae9843SFelipe Balbi
48294ae9843SFelipe Balbi otgsc = readl(&mvotg->op_regs->otgsc);
48394ae9843SFelipe Balbi writel(otgsc, &mvotg->op_regs->otgsc);
48494ae9843SFelipe Balbi
48594ae9843SFelipe Balbi /*
48694ae9843SFelipe Balbi * if we have vbus, then the vbus detection for B-device
48794ae9843SFelipe Balbi * will be done by mv_otg_inputs_irq().
48894ae9843SFelipe Balbi */
48994ae9843SFelipe Balbi if (mvotg->pdata->vbus)
49094ae9843SFelipe Balbi if ((otgsc & OTGSC_STS_USB_ID) &&
49194ae9843SFelipe Balbi !(otgsc & OTGSC_INTSTS_USB_ID))
49294ae9843SFelipe Balbi return IRQ_NONE;
49394ae9843SFelipe Balbi
49494ae9843SFelipe Balbi if ((otgsc & mvotg->irq_status) == 0)
49594ae9843SFelipe Balbi return IRQ_NONE;
49694ae9843SFelipe Balbi
49794ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
49894ae9843SFelipe Balbi
49994ae9843SFelipe Balbi return IRQ_HANDLED;
50094ae9843SFelipe Balbi }
50194ae9843SFelipe Balbi
mv_otg_inputs_irq(int irq,void * dev)50294ae9843SFelipe Balbi static irqreturn_t mv_otg_inputs_irq(int irq, void *dev)
50394ae9843SFelipe Balbi {
50494ae9843SFelipe Balbi struct mv_otg *mvotg = dev;
50594ae9843SFelipe Balbi
50694ae9843SFelipe Balbi /* The clock may disabled at this time */
50794ae9843SFelipe Balbi if (!mvotg->active) {
50894ae9843SFelipe Balbi mv_otg_enable(mvotg);
50994ae9843SFelipe Balbi mv_otg_init_irq(mvotg);
51094ae9843SFelipe Balbi }
51194ae9843SFelipe Balbi
51294ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
51394ae9843SFelipe Balbi
51494ae9843SFelipe Balbi return IRQ_HANDLED;
51594ae9843SFelipe Balbi }
51694ae9843SFelipe Balbi
51794ae9843SFelipe Balbi static ssize_t
a_bus_req_show(struct device * dev,struct device_attribute * attr,char * buf)518ed5bd7a4SGreg Kroah-Hartman a_bus_req_show(struct device *dev, struct device_attribute *attr, char *buf)
51994ae9843SFelipe Balbi {
52094ae9843SFelipe Balbi struct mv_otg *mvotg = dev_get_drvdata(dev);
52194ae9843SFelipe Balbi return scnprintf(buf, PAGE_SIZE, "%d\n",
52294ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_req);
52394ae9843SFelipe Balbi }
52494ae9843SFelipe Balbi
52594ae9843SFelipe Balbi static ssize_t
a_bus_req_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)526ed5bd7a4SGreg Kroah-Hartman a_bus_req_store(struct device *dev, struct device_attribute *attr,
52794ae9843SFelipe Balbi const char *buf, size_t count)
52894ae9843SFelipe Balbi {
52994ae9843SFelipe Balbi struct mv_otg *mvotg = dev_get_drvdata(dev);
53094ae9843SFelipe Balbi
53194ae9843SFelipe Balbi if (count > 2)
53294ae9843SFelipe Balbi return -1;
53394ae9843SFelipe Balbi
53494ae9843SFelipe Balbi /* We will use this interface to change to A device */
535e47d9254SAntoine Tenart if (mvotg->phy.otg->state != OTG_STATE_B_IDLE
536e47d9254SAntoine Tenart && mvotg->phy.otg->state != OTG_STATE_A_IDLE)
53794ae9843SFelipe Balbi return -1;
53894ae9843SFelipe Balbi
53994ae9843SFelipe Balbi /* The clock may disabled and we need to set irq for ID detected */
54094ae9843SFelipe Balbi mv_otg_enable(mvotg);
54194ae9843SFelipe Balbi mv_otg_init_irq(mvotg);
54294ae9843SFelipe Balbi
54394ae9843SFelipe Balbi if (buf[0] == '1') {
54494ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_req = 1;
54594ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_drop = 0;
54694ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev,
54794ae9843SFelipe Balbi "User request: a_bus_req = 1\n");
54894ae9843SFelipe Balbi
54994ae9843SFelipe Balbi if (spin_trylock(&mvotg->wq_lock)) {
55094ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
55194ae9843SFelipe Balbi spin_unlock(&mvotg->wq_lock);
55294ae9843SFelipe Balbi }
55394ae9843SFelipe Balbi }
55494ae9843SFelipe Balbi
55594ae9843SFelipe Balbi return count;
55694ae9843SFelipe Balbi }
55794ae9843SFelipe Balbi
558ed5bd7a4SGreg Kroah-Hartman static DEVICE_ATTR_RW(a_bus_req);
55994ae9843SFelipe Balbi
56094ae9843SFelipe Balbi static ssize_t
a_clr_err_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)561ca35910aSGreg Kroah-Hartman a_clr_err_store(struct device *dev, struct device_attribute *attr,
56294ae9843SFelipe Balbi const char *buf, size_t count)
56394ae9843SFelipe Balbi {
56494ae9843SFelipe Balbi struct mv_otg *mvotg = dev_get_drvdata(dev);
56594ae9843SFelipe Balbi if (!mvotg->phy.otg->default_a)
56694ae9843SFelipe Balbi return -1;
56794ae9843SFelipe Balbi
56894ae9843SFelipe Balbi if (count > 2)
56994ae9843SFelipe Balbi return -1;
57094ae9843SFelipe Balbi
57194ae9843SFelipe Balbi if (buf[0] == '1') {
57294ae9843SFelipe Balbi mvotg->otg_ctrl.a_clr_err = 1;
57394ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev,
57494ae9843SFelipe Balbi "User request: a_clr_err = 1\n");
57594ae9843SFelipe Balbi }
57694ae9843SFelipe Balbi
57794ae9843SFelipe Balbi if (spin_trylock(&mvotg->wq_lock)) {
57894ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
57994ae9843SFelipe Balbi spin_unlock(&mvotg->wq_lock);
58094ae9843SFelipe Balbi }
58194ae9843SFelipe Balbi
58294ae9843SFelipe Balbi return count;
58394ae9843SFelipe Balbi }
58494ae9843SFelipe Balbi
585ca35910aSGreg Kroah-Hartman static DEVICE_ATTR_WO(a_clr_err);
58694ae9843SFelipe Balbi
58794ae9843SFelipe Balbi static ssize_t
a_bus_drop_show(struct device * dev,struct device_attribute * attr,char * buf)588ed5bd7a4SGreg Kroah-Hartman a_bus_drop_show(struct device *dev, struct device_attribute *attr,
58994ae9843SFelipe Balbi char *buf)
59094ae9843SFelipe Balbi {
59194ae9843SFelipe Balbi struct mv_otg *mvotg = dev_get_drvdata(dev);
59294ae9843SFelipe Balbi return scnprintf(buf, PAGE_SIZE, "%d\n",
59394ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_drop);
59494ae9843SFelipe Balbi }
59594ae9843SFelipe Balbi
59694ae9843SFelipe Balbi static ssize_t
a_bus_drop_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)597ed5bd7a4SGreg Kroah-Hartman a_bus_drop_store(struct device *dev, struct device_attribute *attr,
59894ae9843SFelipe Balbi const char *buf, size_t count)
59994ae9843SFelipe Balbi {
60094ae9843SFelipe Balbi struct mv_otg *mvotg = dev_get_drvdata(dev);
60194ae9843SFelipe Balbi if (!mvotg->phy.otg->default_a)
60294ae9843SFelipe Balbi return -1;
60394ae9843SFelipe Balbi
60494ae9843SFelipe Balbi if (count > 2)
60594ae9843SFelipe Balbi return -1;
60694ae9843SFelipe Balbi
60794ae9843SFelipe Balbi if (buf[0] == '0') {
60894ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_drop = 0;
60994ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev,
61094ae9843SFelipe Balbi "User request: a_bus_drop = 0\n");
61194ae9843SFelipe Balbi } else if (buf[0] == '1') {
61294ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_drop = 1;
61394ae9843SFelipe Balbi mvotg->otg_ctrl.a_bus_req = 0;
61494ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev,
61594ae9843SFelipe Balbi "User request: a_bus_drop = 1\n");
61694ae9843SFelipe Balbi dev_dbg(&mvotg->pdev->dev,
61794ae9843SFelipe Balbi "User request: and a_bus_req = 0\n");
61894ae9843SFelipe Balbi }
61994ae9843SFelipe Balbi
62094ae9843SFelipe Balbi if (spin_trylock(&mvotg->wq_lock)) {
62194ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
62294ae9843SFelipe Balbi spin_unlock(&mvotg->wq_lock);
62394ae9843SFelipe Balbi }
62494ae9843SFelipe Balbi
62594ae9843SFelipe Balbi return count;
62694ae9843SFelipe Balbi }
62794ae9843SFelipe Balbi
628ed5bd7a4SGreg Kroah-Hartman static DEVICE_ATTR_RW(a_bus_drop);
62994ae9843SFelipe Balbi
63094ae9843SFelipe Balbi static struct attribute *inputs_attrs[] = {
63194ae9843SFelipe Balbi &dev_attr_a_bus_req.attr,
63294ae9843SFelipe Balbi &dev_attr_a_clr_err.attr,
63394ae9843SFelipe Balbi &dev_attr_a_bus_drop.attr,
63494ae9843SFelipe Balbi NULL,
63594ae9843SFelipe Balbi };
63694ae9843SFelipe Balbi
6371cefc269SArvind Yadav static const struct attribute_group inputs_attr_group = {
63894ae9843SFelipe Balbi .name = "inputs",
63994ae9843SFelipe Balbi .attrs = inputs_attrs,
64094ae9843SFelipe Balbi };
64194ae9843SFelipe Balbi
6423e2cb866SGreg Kroah-Hartman static const struct attribute_group *mv_otg_groups[] = {
6433e2cb866SGreg Kroah-Hartman &inputs_attr_group,
6443e2cb866SGreg Kroah-Hartman NULL,
6453e2cb866SGreg Kroah-Hartman };
6463e2cb866SGreg Kroah-Hartman
mv_otg_remove(struct platform_device * pdev)647*25b979e4SUwe Kleine-König static void mv_otg_remove(struct platform_device *pdev)
64894ae9843SFelipe Balbi {
64994ae9843SFelipe Balbi struct mv_otg *mvotg = platform_get_drvdata(pdev);
65094ae9843SFelipe Balbi
651f057a1d4SChristophe JAILLET if (mvotg->qwork)
65294ae9843SFelipe Balbi destroy_workqueue(mvotg->qwork);
65394ae9843SFelipe Balbi
65494ae9843SFelipe Balbi mv_otg_disable(mvotg);
65594ae9843SFelipe Balbi
65694ae9843SFelipe Balbi usb_remove_phy(&mvotg->phy);
65794ae9843SFelipe Balbi }
65894ae9843SFelipe Balbi
mv_otg_probe(struct platform_device * pdev)65994ae9843SFelipe Balbi static int mv_otg_probe(struct platform_device *pdev)
66094ae9843SFelipe Balbi {
66119f9e188SJingoo Han struct mv_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
66294ae9843SFelipe Balbi struct mv_otg *mvotg;
66394ae9843SFelipe Balbi struct usb_otg *otg;
66494ae9843SFelipe Balbi struct resource *r;
665df18fedaSChao Xie int retval = 0, i;
66694ae9843SFelipe Balbi
66794ae9843SFelipe Balbi if (pdata == NULL) {
66894ae9843SFelipe Balbi dev_err(&pdev->dev, "failed to get platform data\n");
66994ae9843SFelipe Balbi return -ENODEV;
67094ae9843SFelipe Balbi }
67194ae9843SFelipe Balbi
672df18fedaSChao Xie mvotg = devm_kzalloc(&pdev->dev, sizeof(*mvotg), GFP_KERNEL);
673aa10c7b0SPeter Chen if (!mvotg)
67494ae9843SFelipe Balbi return -ENOMEM;
67594ae9843SFelipe Balbi
67694ae9843SFelipe Balbi otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
67794ae9843SFelipe Balbi if (!otg)
67894ae9843SFelipe Balbi return -ENOMEM;
67994ae9843SFelipe Balbi
68094ae9843SFelipe Balbi platform_set_drvdata(pdev, mvotg);
68194ae9843SFelipe Balbi
68294ae9843SFelipe Balbi mvotg->pdev = pdev;
68394ae9843SFelipe Balbi mvotg->pdata = pdata;
68494ae9843SFelipe Balbi
685df18fedaSChao Xie mvotg->clk = devm_clk_get(&pdev->dev, NULL);
686df18fedaSChao Xie if (IS_ERR(mvotg->clk))
687df18fedaSChao Xie return PTR_ERR(mvotg->clk);
68894ae9843SFelipe Balbi
68994ae9843SFelipe Balbi mvotg->qwork = create_singlethread_workqueue("mv_otg_queue");
69094ae9843SFelipe Balbi if (!mvotg->qwork) {
69194ae9843SFelipe Balbi dev_dbg(&pdev->dev, "cannot create workqueue for OTG\n");
69294ae9843SFelipe Balbi return -ENOMEM;
69394ae9843SFelipe Balbi }
69494ae9843SFelipe Balbi
69594ae9843SFelipe Balbi INIT_DELAYED_WORK(&mvotg->work, mv_otg_work);
69694ae9843SFelipe Balbi
69794ae9843SFelipe Balbi /* OTG common part */
69894ae9843SFelipe Balbi mvotg->pdev = pdev;
69994ae9843SFelipe Balbi mvotg->phy.dev = &pdev->dev;
70094ae9843SFelipe Balbi mvotg->phy.otg = otg;
70194ae9843SFelipe Balbi mvotg->phy.label = driver_name;
70294ae9843SFelipe Balbi
703e47d9254SAntoine Tenart otg->state = OTG_STATE_UNDEFINED;
70419c1eac2SAntoine Tenart otg->usb_phy = &mvotg->phy;
70594ae9843SFelipe Balbi otg->set_host = mv_otg_set_host;
70694ae9843SFelipe Balbi otg->set_peripheral = mv_otg_set_peripheral;
70794ae9843SFelipe Balbi otg->set_vbus = mv_otg_set_vbus;
70894ae9843SFelipe Balbi
70994ae9843SFelipe Balbi for (i = 0; i < OTG_TIMER_NUM; i++)
7109718756fSKees Cook timer_setup(&mvotg->otg_ctrl.timer[i],
7119718756fSKees Cook mv_otg_timer_await_bcon, 0);
71294ae9843SFelipe Balbi
71394ae9843SFelipe Balbi r = platform_get_resource_byname(mvotg->pdev,
71494ae9843SFelipe Balbi IORESOURCE_MEM, "phyregs");
71594ae9843SFelipe Balbi if (r == NULL) {
71694ae9843SFelipe Balbi dev_err(&pdev->dev, "no phy I/O memory resource defined\n");
71794ae9843SFelipe Balbi retval = -ENODEV;
71894ae9843SFelipe Balbi goto err_destroy_workqueue;
71994ae9843SFelipe Balbi }
72094ae9843SFelipe Balbi
72194ae9843SFelipe Balbi mvotg->phy_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
72294ae9843SFelipe Balbi if (mvotg->phy_regs == NULL) {
72394ae9843SFelipe Balbi dev_err(&pdev->dev, "failed to map phy I/O memory\n");
72494ae9843SFelipe Balbi retval = -EFAULT;
72594ae9843SFelipe Balbi goto err_destroy_workqueue;
72694ae9843SFelipe Balbi }
72794ae9843SFelipe Balbi
72894ae9843SFelipe Balbi r = platform_get_resource_byname(mvotg->pdev,
72994ae9843SFelipe Balbi IORESOURCE_MEM, "capregs");
73094ae9843SFelipe Balbi if (r == NULL) {
73194ae9843SFelipe Balbi dev_err(&pdev->dev, "no I/O memory resource defined\n");
73294ae9843SFelipe Balbi retval = -ENODEV;
73394ae9843SFelipe Balbi goto err_destroy_workqueue;
73494ae9843SFelipe Balbi }
73594ae9843SFelipe Balbi
73694ae9843SFelipe Balbi mvotg->cap_regs = devm_ioremap(&pdev->dev, r->start, resource_size(r));
73794ae9843SFelipe Balbi if (mvotg->cap_regs == NULL) {
73894ae9843SFelipe Balbi dev_err(&pdev->dev, "failed to map I/O memory\n");
73994ae9843SFelipe Balbi retval = -EFAULT;
74094ae9843SFelipe Balbi goto err_destroy_workqueue;
74194ae9843SFelipe Balbi }
74294ae9843SFelipe Balbi
74394ae9843SFelipe Balbi /* we will acces controller register, so enable the udc controller */
74494ae9843SFelipe Balbi retval = mv_otg_enable_internal(mvotg);
74594ae9843SFelipe Balbi if (retval) {
74694ae9843SFelipe Balbi dev_err(&pdev->dev, "mv otg enable error %d\n", retval);
74794ae9843SFelipe Balbi goto err_destroy_workqueue;
74894ae9843SFelipe Balbi }
74994ae9843SFelipe Balbi
75094ae9843SFelipe Balbi mvotg->op_regs =
75194ae9843SFelipe Balbi (struct mv_otg_regs __iomem *) ((unsigned long) mvotg->cap_regs
75294ae9843SFelipe Balbi + (readl(mvotg->cap_regs) & CAPLENGTH_MASK));
75394ae9843SFelipe Balbi
75494ae9843SFelipe Balbi if (pdata->id) {
75594ae9843SFelipe Balbi retval = devm_request_threaded_irq(&pdev->dev, pdata->id->irq,
75694ae9843SFelipe Balbi NULL, mv_otg_inputs_irq,
75794ae9843SFelipe Balbi IRQF_ONESHOT, "id", mvotg);
75894ae9843SFelipe Balbi if (retval) {
75994ae9843SFelipe Balbi dev_info(&pdev->dev,
76094ae9843SFelipe Balbi "Failed to request irq for ID\n");
76194ae9843SFelipe Balbi pdata->id = NULL;
76294ae9843SFelipe Balbi }
76394ae9843SFelipe Balbi }
76494ae9843SFelipe Balbi
76594ae9843SFelipe Balbi if (pdata->vbus) {
76694ae9843SFelipe Balbi mvotg->clock_gating = 1;
76794ae9843SFelipe Balbi retval = devm_request_threaded_irq(&pdev->dev, pdata->vbus->irq,
76894ae9843SFelipe Balbi NULL, mv_otg_inputs_irq,
76994ae9843SFelipe Balbi IRQF_ONESHOT, "vbus", mvotg);
77094ae9843SFelipe Balbi if (retval) {
77194ae9843SFelipe Balbi dev_info(&pdev->dev,
77294ae9843SFelipe Balbi "Failed to request irq for VBUS, "
77394ae9843SFelipe Balbi "disable clock gating\n");
77494ae9843SFelipe Balbi mvotg->clock_gating = 0;
77594ae9843SFelipe Balbi pdata->vbus = NULL;
77694ae9843SFelipe Balbi }
77794ae9843SFelipe Balbi }
77894ae9843SFelipe Balbi
77994ae9843SFelipe Balbi if (pdata->disable_otg_clock_gating)
78094ae9843SFelipe Balbi mvotg->clock_gating = 0;
78194ae9843SFelipe Balbi
78294ae9843SFelipe Balbi mv_otg_reset(mvotg);
78394ae9843SFelipe Balbi mv_otg_init_irq(mvotg);
78494ae9843SFelipe Balbi
78594ae9843SFelipe Balbi r = platform_get_resource(mvotg->pdev, IORESOURCE_IRQ, 0);
78694ae9843SFelipe Balbi if (r == NULL) {
78794ae9843SFelipe Balbi dev_err(&pdev->dev, "no IRQ resource defined\n");
78894ae9843SFelipe Balbi retval = -ENODEV;
78994ae9843SFelipe Balbi goto err_disable_clk;
79094ae9843SFelipe Balbi }
79194ae9843SFelipe Balbi
79294ae9843SFelipe Balbi mvotg->irq = r->start;
79394ae9843SFelipe Balbi if (devm_request_irq(&pdev->dev, mvotg->irq, mv_otg_irq, IRQF_SHARED,
79494ae9843SFelipe Balbi driver_name, mvotg)) {
79594ae9843SFelipe Balbi dev_err(&pdev->dev, "Request irq %d for OTG failed\n",
79694ae9843SFelipe Balbi mvotg->irq);
79794ae9843SFelipe Balbi mvotg->irq = 0;
79894ae9843SFelipe Balbi retval = -ENODEV;
79994ae9843SFelipe Balbi goto err_disable_clk;
80094ae9843SFelipe Balbi }
80194ae9843SFelipe Balbi
80294ae9843SFelipe Balbi retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2);
80394ae9843SFelipe Balbi if (retval < 0) {
80494ae9843SFelipe Balbi dev_err(&pdev->dev, "can't register transceiver, %d\n",
80594ae9843SFelipe Balbi retval);
80694ae9843SFelipe Balbi goto err_disable_clk;
80794ae9843SFelipe Balbi }
80894ae9843SFelipe Balbi
80994ae9843SFelipe Balbi spin_lock_init(&mvotg->wq_lock);
81094ae9843SFelipe Balbi if (spin_trylock(&mvotg->wq_lock)) {
81194ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 2 * HZ);
81294ae9843SFelipe Balbi spin_unlock(&mvotg->wq_lock);
81394ae9843SFelipe Balbi }
81494ae9843SFelipe Balbi
81594ae9843SFelipe Balbi dev_info(&pdev->dev,
81694ae9843SFelipe Balbi "successful probe OTG device %s clock gating.\n",
81794ae9843SFelipe Balbi mvotg->clock_gating ? "with" : "without");
81894ae9843SFelipe Balbi
81994ae9843SFelipe Balbi return 0;
82094ae9843SFelipe Balbi
82194ae9843SFelipe Balbi err_disable_clk:
82294ae9843SFelipe Balbi mv_otg_disable_internal(mvotg);
82394ae9843SFelipe Balbi err_destroy_workqueue:
82494ae9843SFelipe Balbi destroy_workqueue(mvotg->qwork);
82594ae9843SFelipe Balbi
82694ae9843SFelipe Balbi return retval;
82794ae9843SFelipe Balbi }
82894ae9843SFelipe Balbi
82994ae9843SFelipe Balbi #ifdef CONFIG_PM
mv_otg_suspend(struct platform_device * pdev,pm_message_t state)83094ae9843SFelipe Balbi static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state)
83194ae9843SFelipe Balbi {
83294ae9843SFelipe Balbi struct mv_otg *mvotg = platform_get_drvdata(pdev);
83394ae9843SFelipe Balbi
83490bdf403SArnd Bergmann if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) {
83594ae9843SFelipe Balbi dev_info(&pdev->dev,
83694ae9843SFelipe Balbi "OTG state is not B_IDLE, it is %d!\n",
83790bdf403SArnd Bergmann mvotg->phy.otg->state);
83894ae9843SFelipe Balbi return -EAGAIN;
83994ae9843SFelipe Balbi }
84094ae9843SFelipe Balbi
84194ae9843SFelipe Balbi if (!mvotg->clock_gating)
84294ae9843SFelipe Balbi mv_otg_disable_internal(mvotg);
84394ae9843SFelipe Balbi
84494ae9843SFelipe Balbi return 0;
84594ae9843SFelipe Balbi }
84694ae9843SFelipe Balbi
mv_otg_resume(struct platform_device * pdev)84794ae9843SFelipe Balbi static int mv_otg_resume(struct platform_device *pdev)
84894ae9843SFelipe Balbi {
84994ae9843SFelipe Balbi struct mv_otg *mvotg = platform_get_drvdata(pdev);
85094ae9843SFelipe Balbi u32 otgsc;
85194ae9843SFelipe Balbi
85294ae9843SFelipe Balbi if (!mvotg->clock_gating) {
85394ae9843SFelipe Balbi mv_otg_enable_internal(mvotg);
85494ae9843SFelipe Balbi
85594ae9843SFelipe Balbi otgsc = readl(&mvotg->op_regs->otgsc);
85694ae9843SFelipe Balbi otgsc |= mvotg->irq_en;
85794ae9843SFelipe Balbi writel(otgsc, &mvotg->op_regs->otgsc);
85894ae9843SFelipe Balbi
85994ae9843SFelipe Balbi if (spin_trylock(&mvotg->wq_lock)) {
86094ae9843SFelipe Balbi mv_otg_run_state_machine(mvotg, 0);
86194ae9843SFelipe Balbi spin_unlock(&mvotg->wq_lock);
86294ae9843SFelipe Balbi }
86394ae9843SFelipe Balbi }
86494ae9843SFelipe Balbi return 0;
86594ae9843SFelipe Balbi }
86694ae9843SFelipe Balbi #endif
86794ae9843SFelipe Balbi
86894ae9843SFelipe Balbi static struct platform_driver mv_otg_driver = {
86994ae9843SFelipe Balbi .probe = mv_otg_probe,
870*25b979e4SUwe Kleine-König .remove_new = mv_otg_remove,
87194ae9843SFelipe Balbi .driver = {
87294ae9843SFelipe Balbi .name = driver_name,
8733e2cb866SGreg Kroah-Hartman .dev_groups = mv_otg_groups,
87494ae9843SFelipe Balbi },
87594ae9843SFelipe Balbi #ifdef CONFIG_PM
87694ae9843SFelipe Balbi .suspend = mv_otg_suspend,
87794ae9843SFelipe Balbi .resume = mv_otg_resume,
87894ae9843SFelipe Balbi #endif
87994ae9843SFelipe Balbi };
88094ae9843SFelipe Balbi module_platform_driver(mv_otg_driver);
881