cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

otg_fsm.c (19599B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * otg_fsm.c - ChipIdea USB IP core OTG FSM driver
      4 *
      5 * Copyright (C) 2014 Freescale Semiconductor, Inc.
      6 *
      7 * Author: Jun Li
      8 */
      9
     10/*
     11 * This file mainly handles OTG fsm, it includes OTG fsm operations
     12 * for HNP and SRP.
     13 *
     14 * TODO List
     15 * - ADP
     16 * - OTG test device
     17 */
     18
     19#include <linux/usb/otg.h>
     20#include <linux/usb/gadget.h>
     21#include <linux/usb/hcd.h>
     22#include <linux/usb/chipidea.h>
     23#include <linux/regulator/consumer.h>
     24
     25#include "ci.h"
     26#include "bits.h"
     27#include "otg.h"
     28#include "otg_fsm.h"
     29
     30/* Add for otg: interact with user space app */
     31static ssize_t
     32a_bus_req_show(struct device *dev, struct device_attribute *attr, char *buf)
     33{
     34	char		*next;
     35	unsigned	size, t;
     36	struct ci_hdrc	*ci = dev_get_drvdata(dev);
     37
     38	next = buf;
     39	size = PAGE_SIZE;
     40	t = scnprintf(next, size, "%d\n", ci->fsm.a_bus_req);
     41	size -= t;
     42	next += t;
     43
     44	return PAGE_SIZE - size;
     45}
     46
     47static ssize_t
     48a_bus_req_store(struct device *dev, struct device_attribute *attr,
     49					const char *buf, size_t count)
     50{
     51	struct ci_hdrc *ci = dev_get_drvdata(dev);
     52
     53	if (count > 2)
     54		return -1;
     55
     56	mutex_lock(&ci->fsm.lock);
     57	if (buf[0] == '0') {
     58		ci->fsm.a_bus_req = 0;
     59	} else if (buf[0] == '1') {
     60		/* If a_bus_drop is TRUE, a_bus_req can't be set */
     61		if (ci->fsm.a_bus_drop) {
     62			mutex_unlock(&ci->fsm.lock);
     63			return count;
     64		}
     65		ci->fsm.a_bus_req = 1;
     66		if (ci->fsm.otg->state == OTG_STATE_A_PERIPHERAL) {
     67			ci->gadget.host_request_flag = 1;
     68			mutex_unlock(&ci->fsm.lock);
     69			return count;
     70		}
     71	}
     72
     73	ci_otg_queue_work(ci);
     74	mutex_unlock(&ci->fsm.lock);
     75
     76	return count;
     77}
     78static DEVICE_ATTR_RW(a_bus_req);
     79
     80static ssize_t
     81a_bus_drop_show(struct device *dev, struct device_attribute *attr, char *buf)
     82{
     83	char		*next;
     84	unsigned	size, t;
     85	struct ci_hdrc	*ci = dev_get_drvdata(dev);
     86
     87	next = buf;
     88	size = PAGE_SIZE;
     89	t = scnprintf(next, size, "%d\n", ci->fsm.a_bus_drop);
     90	size -= t;
     91	next += t;
     92
     93	return PAGE_SIZE - size;
     94}
     95
     96static ssize_t
     97a_bus_drop_store(struct device *dev, struct device_attribute *attr,
     98					const char *buf, size_t count)
     99{
    100	struct ci_hdrc	*ci = dev_get_drvdata(dev);
    101
    102	if (count > 2)
    103		return -1;
    104
    105	mutex_lock(&ci->fsm.lock);
    106	if (buf[0] == '0') {
    107		ci->fsm.a_bus_drop = 0;
    108	} else if (buf[0] == '1') {
    109		ci->fsm.a_bus_drop = 1;
    110		ci->fsm.a_bus_req = 0;
    111	}
    112
    113	ci_otg_queue_work(ci);
    114	mutex_unlock(&ci->fsm.lock);
    115
    116	return count;
    117}
    118static DEVICE_ATTR_RW(a_bus_drop);
    119
    120static ssize_t
    121b_bus_req_show(struct device *dev, struct device_attribute *attr, char *buf)
    122{
    123	char		*next;
    124	unsigned	size, t;
    125	struct ci_hdrc	*ci = dev_get_drvdata(dev);
    126
    127	next = buf;
    128	size = PAGE_SIZE;
    129	t = scnprintf(next, size, "%d\n", ci->fsm.b_bus_req);
    130	size -= t;
    131	next += t;
    132
    133	return PAGE_SIZE - size;
    134}
    135
    136static ssize_t
    137b_bus_req_store(struct device *dev, struct device_attribute *attr,
    138					const char *buf, size_t count)
    139{
    140	struct ci_hdrc	*ci = dev_get_drvdata(dev);
    141
    142	if (count > 2)
    143		return -1;
    144
    145	mutex_lock(&ci->fsm.lock);
    146	if (buf[0] == '0')
    147		ci->fsm.b_bus_req = 0;
    148	else if (buf[0] == '1') {
    149		ci->fsm.b_bus_req = 1;
    150		if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) {
    151			ci->gadget.host_request_flag = 1;
    152			mutex_unlock(&ci->fsm.lock);
    153			return count;
    154		}
    155	}
    156
    157	ci_otg_queue_work(ci);
    158	mutex_unlock(&ci->fsm.lock);
    159
    160	return count;
    161}
    162static DEVICE_ATTR_RW(b_bus_req);
    163
    164static ssize_t
    165a_clr_err_store(struct device *dev, struct device_attribute *attr,
    166					const char *buf, size_t count)
    167{
    168	struct ci_hdrc	*ci = dev_get_drvdata(dev);
    169
    170	if (count > 2)
    171		return -1;
    172
    173	mutex_lock(&ci->fsm.lock);
    174	if (buf[0] == '1')
    175		ci->fsm.a_clr_err = 1;
    176
    177	ci_otg_queue_work(ci);
    178	mutex_unlock(&ci->fsm.lock);
    179
    180	return count;
    181}
    182static DEVICE_ATTR_WO(a_clr_err);
    183
    184static struct attribute *inputs_attrs[] = {
    185	&dev_attr_a_bus_req.attr,
    186	&dev_attr_a_bus_drop.attr,
    187	&dev_attr_b_bus_req.attr,
    188	&dev_attr_a_clr_err.attr,
    189	NULL,
    190};
    191
    192static const struct attribute_group inputs_attr_group = {
    193	.name = "inputs",
    194	.attrs = inputs_attrs,
    195};
    196
    197/*
    198 * Keep this list in the same order as timers indexed
    199 * by enum otg_fsm_timer in include/linux/usb/otg-fsm.h
    200 */
    201static unsigned otg_timer_ms[] = {
    202	TA_WAIT_VRISE,
    203	TA_WAIT_VFALL,
    204	TA_WAIT_BCON,
    205	TA_AIDL_BDIS,
    206	TB_ASE0_BRST,
    207	TA_BIDL_ADIS,
    208	TB_AIDL_BDIS,
    209	TB_SE0_SRP,
    210	TB_SRP_FAIL,
    211	0,
    212	TB_DATA_PLS,
    213	TB_SSEND_SRP,
    214};
    215
    216/*
    217 * Add timer to active timer list
    218 */
    219static void ci_otg_add_timer(struct ci_hdrc *ci, enum otg_fsm_timer t)
    220{
    221	unsigned long flags, timer_sec, timer_nsec;
    222
    223	if (t >= NUM_OTG_FSM_TIMERS)
    224		return;
    225
    226	spin_lock_irqsave(&ci->lock, flags);
    227	timer_sec = otg_timer_ms[t] / MSEC_PER_SEC;
    228	timer_nsec = (otg_timer_ms[t] % MSEC_PER_SEC) * NSEC_PER_MSEC;
    229	ci->hr_timeouts[t] = ktime_add(ktime_get(),
    230				ktime_set(timer_sec, timer_nsec));
    231	ci->enabled_otg_timer_bits |= (1 << t);
    232	if ((ci->next_otg_timer == NUM_OTG_FSM_TIMERS) ||
    233			ktime_after(ci->hr_timeouts[ci->next_otg_timer],
    234						ci->hr_timeouts[t])) {
    235			ci->next_otg_timer = t;
    236			hrtimer_start_range_ns(&ci->otg_fsm_hrtimer,
    237					ci->hr_timeouts[t], NSEC_PER_MSEC,
    238							HRTIMER_MODE_ABS);
    239	}
    240	spin_unlock_irqrestore(&ci->lock, flags);
    241}
    242
    243/*
    244 * Remove timer from active timer list
    245 */
    246static void ci_otg_del_timer(struct ci_hdrc *ci, enum otg_fsm_timer t)
    247{
    248	unsigned long flags, enabled_timer_bits;
    249	enum otg_fsm_timer cur_timer, next_timer = NUM_OTG_FSM_TIMERS;
    250
    251	if ((t >= NUM_OTG_FSM_TIMERS) ||
    252			!(ci->enabled_otg_timer_bits & (1 << t)))
    253		return;
    254
    255	spin_lock_irqsave(&ci->lock, flags);
    256	ci->enabled_otg_timer_bits &= ~(1 << t);
    257	if (ci->next_otg_timer == t) {
    258		if (ci->enabled_otg_timer_bits == 0) {
    259			/* No enabled timers after delete it */
    260			hrtimer_cancel(&ci->otg_fsm_hrtimer);
    261			ci->next_otg_timer = NUM_OTG_FSM_TIMERS;
    262		} else {
    263			/* Find the next timer */
    264			enabled_timer_bits = ci->enabled_otg_timer_bits;
    265			for_each_set_bit(cur_timer, &enabled_timer_bits,
    266							NUM_OTG_FSM_TIMERS) {
    267				if ((next_timer == NUM_OTG_FSM_TIMERS) ||
    268					ktime_before(ci->hr_timeouts[next_timer],
    269					 ci->hr_timeouts[cur_timer]))
    270					next_timer = cur_timer;
    271			}
    272		}
    273	}
    274	if (next_timer != NUM_OTG_FSM_TIMERS) {
    275		ci->next_otg_timer = next_timer;
    276		hrtimer_start_range_ns(&ci->otg_fsm_hrtimer,
    277			ci->hr_timeouts[next_timer], NSEC_PER_MSEC,
    278							HRTIMER_MODE_ABS);
    279	}
    280	spin_unlock_irqrestore(&ci->lock, flags);
    281}
    282
    283/* OTG FSM timer handlers */
    284static int a_wait_vrise_tmout(struct ci_hdrc *ci)
    285{
    286	ci->fsm.a_wait_vrise_tmout = 1;
    287	return 0;
    288}
    289
    290static int a_wait_vfall_tmout(struct ci_hdrc *ci)
    291{
    292	ci->fsm.a_wait_vfall_tmout = 1;
    293	return 0;
    294}
    295
    296static int a_wait_bcon_tmout(struct ci_hdrc *ci)
    297{
    298	ci->fsm.a_wait_bcon_tmout = 1;
    299	return 0;
    300}
    301
    302static int a_aidl_bdis_tmout(struct ci_hdrc *ci)
    303{
    304	ci->fsm.a_aidl_bdis_tmout = 1;
    305	return 0;
    306}
    307
    308static int b_ase0_brst_tmout(struct ci_hdrc *ci)
    309{
    310	ci->fsm.b_ase0_brst_tmout = 1;
    311	return 0;
    312}
    313
    314static int a_bidl_adis_tmout(struct ci_hdrc *ci)
    315{
    316	ci->fsm.a_bidl_adis_tmout = 1;
    317	return 0;
    318}
    319
    320static int b_aidl_bdis_tmout(struct ci_hdrc *ci)
    321{
    322	ci->fsm.a_bus_suspend = 1;
    323	return 0;
    324}
    325
    326static int b_se0_srp_tmout(struct ci_hdrc *ci)
    327{
    328	ci->fsm.b_se0_srp = 1;
    329	return 0;
    330}
    331
    332static int b_srp_fail_tmout(struct ci_hdrc *ci)
    333{
    334	ci->fsm.b_srp_done = 1;
    335	return 1;
    336}
    337
    338static int b_data_pls_tmout(struct ci_hdrc *ci)
    339{
    340	ci->fsm.b_srp_done = 1;
    341	ci->fsm.b_bus_req = 0;
    342	if (ci->fsm.power_up)
    343		ci->fsm.power_up = 0;
    344	hw_write_otgsc(ci, OTGSC_HABA, 0);
    345	pm_runtime_put(ci->dev);
    346	return 0;
    347}
    348
    349static int b_ssend_srp_tmout(struct ci_hdrc *ci)
    350{
    351	ci->fsm.b_ssend_srp = 1;
    352	/* only vbus fall below B_sess_vld in b_idle state */
    353	if (ci->fsm.otg->state == OTG_STATE_B_IDLE)
    354		return 0;
    355	else
    356		return 1;
    357}
    358
    359/*
    360 * Keep this list in the same order as timers indexed
    361 * by enum otg_fsm_timer in include/linux/usb/otg-fsm.h
    362 */
    363static int (*otg_timer_handlers[])(struct ci_hdrc *) = {
    364	a_wait_vrise_tmout,	/* A_WAIT_VRISE */
    365	a_wait_vfall_tmout,	/* A_WAIT_VFALL */
    366	a_wait_bcon_tmout,	/* A_WAIT_BCON */
    367	a_aidl_bdis_tmout,	/* A_AIDL_BDIS */
    368	b_ase0_brst_tmout,	/* B_ASE0_BRST */
    369	a_bidl_adis_tmout,	/* A_BIDL_ADIS */
    370	b_aidl_bdis_tmout,	/* B_AIDL_BDIS */
    371	b_se0_srp_tmout,	/* B_SE0_SRP */
    372	b_srp_fail_tmout,	/* B_SRP_FAIL */
    373	NULL,			/* A_WAIT_ENUM */
    374	b_data_pls_tmout,	/* B_DATA_PLS */
    375	b_ssend_srp_tmout,	/* B_SSEND_SRP */
    376};
    377
    378/*
    379 * Enable the next nearest enabled timer if have
    380 */
    381static enum hrtimer_restart ci_otg_hrtimer_func(struct hrtimer *t)
    382{
    383	struct ci_hdrc *ci = container_of(t, struct ci_hdrc, otg_fsm_hrtimer);
    384	ktime_t	now, *timeout;
    385	unsigned long   enabled_timer_bits;
    386	unsigned long   flags;
    387	enum otg_fsm_timer cur_timer, next_timer = NUM_OTG_FSM_TIMERS;
    388	int ret = -EINVAL;
    389
    390	spin_lock_irqsave(&ci->lock, flags);
    391	enabled_timer_bits = ci->enabled_otg_timer_bits;
    392	ci->next_otg_timer = NUM_OTG_FSM_TIMERS;
    393
    394	now = ktime_get();
    395	for_each_set_bit(cur_timer, &enabled_timer_bits, NUM_OTG_FSM_TIMERS) {
    396		if (ktime_compare(now, ci->hr_timeouts[cur_timer]) >= 0) {
    397			ci->enabled_otg_timer_bits &= ~(1 << cur_timer);
    398			if (otg_timer_handlers[cur_timer])
    399				ret = otg_timer_handlers[cur_timer](ci);
    400		} else {
    401			if ((next_timer == NUM_OTG_FSM_TIMERS) ||
    402				ktime_before(ci->hr_timeouts[cur_timer],
    403					ci->hr_timeouts[next_timer]))
    404				next_timer = cur_timer;
    405		}
    406	}
    407	/* Enable the next nearest timer */
    408	if (next_timer < NUM_OTG_FSM_TIMERS) {
    409		timeout = &ci->hr_timeouts[next_timer];
    410		hrtimer_start_range_ns(&ci->otg_fsm_hrtimer, *timeout,
    411					NSEC_PER_MSEC, HRTIMER_MODE_ABS);
    412		ci->next_otg_timer = next_timer;
    413	}
    414	spin_unlock_irqrestore(&ci->lock, flags);
    415
    416	if (!ret)
    417		ci_otg_queue_work(ci);
    418
    419	return HRTIMER_NORESTART;
    420}
    421
    422/* Initialize timers */
    423static int ci_otg_init_timers(struct ci_hdrc *ci)
    424{
    425	hrtimer_init(&ci->otg_fsm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
    426	ci->otg_fsm_hrtimer.function = ci_otg_hrtimer_func;
    427
    428	return 0;
    429}
    430
    431/* -------------------------------------------------------------*/
    432/* Operations that will be called from OTG Finite State Machine */
    433/* -------------------------------------------------------------*/
    434static void ci_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
    435{
    436	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    437
    438	if (t < NUM_OTG_FSM_TIMERS)
    439		ci_otg_add_timer(ci, t);
    440	return;
    441}
    442
    443static void ci_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
    444{
    445	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    446
    447	if (t < NUM_OTG_FSM_TIMERS)
    448		ci_otg_del_timer(ci, t);
    449	return;
    450}
    451
    452/*
    453 * A-device drive vbus: turn on vbus regulator and enable port power
    454 * Data pulse irq should be disabled while vbus is on.
    455 */
    456static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
    457{
    458	int ret;
    459	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    460
    461	if (on) {
    462		/* Enable power power */
    463		hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP,
    464							PORTSC_PP);
    465		if (ci->platdata->reg_vbus) {
    466			ret = regulator_enable(ci->platdata->reg_vbus);
    467			if (ret) {
    468				dev_err(ci->dev,
    469				"Failed to enable vbus regulator, ret=%d\n",
    470				ret);
    471				return;
    472			}
    473		}
    474		/* Disable data pulse irq */
    475		hw_write_otgsc(ci, OTGSC_DPIE, 0);
    476
    477		fsm->a_srp_det = 0;
    478		fsm->power_up = 0;
    479	} else {
    480		if (ci->platdata->reg_vbus)
    481			regulator_disable(ci->platdata->reg_vbus);
    482
    483		fsm->a_bus_drop = 1;
    484		fsm->a_bus_req = 0;
    485	}
    486}
    487
    488/*
    489 * Control data line by Run Stop bit.
    490 */
    491static void ci_otg_loc_conn(struct otg_fsm *fsm, int on)
    492{
    493	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    494
    495	if (on)
    496		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
    497	else
    498		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
    499}
    500
    501/*
    502 * Generate SOF by host.
    503 * In host mode, controller will automatically send SOF.
    504 * Suspend will block the data on the port.
    505 *
    506 * This is controlled through usbcore by usb autosuspend,
    507 * so the usb device class driver need support autosuspend,
    508 * otherwise the bus suspend will not happen.
    509 */
    510static void ci_otg_loc_sof(struct otg_fsm *fsm, int on)
    511{
    512	struct usb_device *udev;
    513
    514	if (!fsm->otg->host)
    515		return;
    516
    517	udev = usb_hub_find_child(fsm->otg->host->root_hub, 1);
    518	if (!udev)
    519		return;
    520
    521	if (on) {
    522		usb_disable_autosuspend(udev);
    523	} else {
    524		pm_runtime_set_autosuspend_delay(&udev->dev, 0);
    525		usb_enable_autosuspend(udev);
    526	}
    527}
    528
    529/*
    530 * Start SRP pulsing by data-line pulsing,
    531 * no v-bus pulsing followed
    532 */
    533static void ci_otg_start_pulse(struct otg_fsm *fsm)
    534{
    535	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    536
    537	/* Hardware Assistant Data pulse */
    538	hw_write_otgsc(ci, OTGSC_HADP, OTGSC_HADP);
    539
    540	pm_runtime_get(ci->dev);
    541	ci_otg_add_timer(ci, B_DATA_PLS);
    542}
    543
    544static int ci_otg_start_host(struct otg_fsm *fsm, int on)
    545{
    546	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    547
    548	if (on) {
    549		ci_role_stop(ci);
    550		ci_role_start(ci, CI_ROLE_HOST);
    551	} else {
    552		ci_role_stop(ci);
    553		ci_role_start(ci, CI_ROLE_GADGET);
    554	}
    555	return 0;
    556}
    557
    558static int ci_otg_start_gadget(struct otg_fsm *fsm, int on)
    559{
    560	struct ci_hdrc	*ci = container_of(fsm, struct ci_hdrc, fsm);
    561
    562	if (on)
    563		usb_gadget_vbus_connect(&ci->gadget);
    564	else
    565		usb_gadget_vbus_disconnect(&ci->gadget);
    566
    567	return 0;
    568}
    569
    570static struct otg_fsm_ops ci_otg_ops = {
    571	.drv_vbus = ci_otg_drv_vbus,
    572	.loc_conn = ci_otg_loc_conn,
    573	.loc_sof = ci_otg_loc_sof,
    574	.start_pulse = ci_otg_start_pulse,
    575	.add_timer = ci_otg_fsm_add_timer,
    576	.del_timer = ci_otg_fsm_del_timer,
    577	.start_host = ci_otg_start_host,
    578	.start_gadget = ci_otg_start_gadget,
    579};
    580
    581int ci_otg_fsm_work(struct ci_hdrc *ci)
    582{
    583	/*
    584	 * Don't do fsm transition for B device
    585	 * when there is no gadget class driver
    586	 */
    587	if (ci->fsm.id && !(ci->driver) &&
    588		ci->fsm.otg->state < OTG_STATE_A_IDLE)
    589		return 0;
    590
    591	pm_runtime_get_sync(ci->dev);
    592	if (otg_statemachine(&ci->fsm)) {
    593		if (ci->fsm.otg->state == OTG_STATE_A_IDLE) {
    594			/*
    595			 * Further state change for cases:
    596			 * a_idle to b_idle; or
    597			 * a_idle to a_wait_vrise due to ID change(1->0), so
    598			 * B-dev becomes A-dev can try to start new session
    599			 * consequently; or
    600			 * a_idle to a_wait_vrise when power up
    601			 */
    602			if ((ci->fsm.id) || (ci->id_event) ||
    603						(ci->fsm.power_up)) {
    604				ci_otg_queue_work(ci);
    605			} else {
    606				/* Enable data pulse irq */
    607				hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS |
    608								PORTSC_PP, 0);
    609				hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
    610				hw_write_otgsc(ci, OTGSC_DPIE, OTGSC_DPIE);
    611			}
    612			if (ci->id_event)
    613				ci->id_event = false;
    614		} else if (ci->fsm.otg->state == OTG_STATE_B_IDLE) {
    615			if (ci->fsm.b_sess_vld) {
    616				ci->fsm.power_up = 0;
    617				/*
    618				 * Further transite to b_periphearl state
    619				 * when register gadget driver with vbus on
    620				 */
    621				ci_otg_queue_work(ci);
    622			}
    623		} else if (ci->fsm.otg->state == OTG_STATE_A_HOST) {
    624			pm_runtime_mark_last_busy(ci->dev);
    625			pm_runtime_put_autosuspend(ci->dev);
    626			return 0;
    627		}
    628	}
    629	pm_runtime_put_sync(ci->dev);
    630	return 0;
    631}
    632
    633/*
    634 * Update fsm variables in each state if catching expected interrupts,
    635 * called by otg fsm isr.
    636 */
    637static void ci_otg_fsm_event(struct ci_hdrc *ci)
    638{
    639	u32 intr_sts, otg_bsess_vld, port_conn;
    640	struct otg_fsm *fsm = &ci->fsm;
    641
    642	intr_sts = hw_read_intr_status(ci);
    643	otg_bsess_vld = hw_read_otgsc(ci, OTGSC_BSV);
    644	port_conn = hw_read(ci, OP_PORTSC, PORTSC_CCS);
    645
    646	switch (ci->fsm.otg->state) {
    647	case OTG_STATE_A_WAIT_BCON:
    648		if (port_conn) {
    649			fsm->b_conn = 1;
    650			fsm->a_bus_req = 1;
    651			ci_otg_queue_work(ci);
    652		}
    653		break;
    654	case OTG_STATE_B_IDLE:
    655		if (otg_bsess_vld && (intr_sts & USBi_PCI) && port_conn) {
    656			fsm->b_sess_vld = 1;
    657			ci_otg_queue_work(ci);
    658		}
    659		break;
    660	case OTG_STATE_B_PERIPHERAL:
    661		if ((intr_sts & USBi_SLI) && port_conn && otg_bsess_vld) {
    662			ci_otg_add_timer(ci, B_AIDL_BDIS);
    663		} else if (intr_sts & USBi_PCI) {
    664			ci_otg_del_timer(ci, B_AIDL_BDIS);
    665			if (fsm->a_bus_suspend == 1)
    666				fsm->a_bus_suspend = 0;
    667		}
    668		break;
    669	case OTG_STATE_B_HOST:
    670		if ((intr_sts & USBi_PCI) && !port_conn) {
    671			fsm->a_conn = 0;
    672			fsm->b_bus_req = 0;
    673			ci_otg_queue_work(ci);
    674		}
    675		break;
    676	case OTG_STATE_A_PERIPHERAL:
    677		if (intr_sts & USBi_SLI) {
    678			 fsm->b_bus_suspend = 1;
    679			/*
    680			 * Init a timer to know how long this suspend
    681			 * will continue, if time out, indicates B no longer
    682			 * wants to be host role
    683			 */
    684			 ci_otg_add_timer(ci, A_BIDL_ADIS);
    685		}
    686
    687		if (intr_sts & USBi_URI)
    688			ci_otg_del_timer(ci, A_BIDL_ADIS);
    689
    690		if (intr_sts & USBi_PCI) {
    691			if (fsm->b_bus_suspend == 1) {
    692				ci_otg_del_timer(ci, A_BIDL_ADIS);
    693				fsm->b_bus_suspend = 0;
    694			}
    695		}
    696		break;
    697	case OTG_STATE_A_SUSPEND:
    698		if ((intr_sts & USBi_PCI) && !port_conn) {
    699			fsm->b_conn = 0;
    700
    701			/* if gadget driver is binded */
    702			if (ci->driver) {
    703				/* A device to be peripheral mode */
    704				ci->gadget.is_a_peripheral = 1;
    705			}
    706			ci_otg_queue_work(ci);
    707		}
    708		break;
    709	case OTG_STATE_A_HOST:
    710		if ((intr_sts & USBi_PCI) && !port_conn) {
    711			fsm->b_conn = 0;
    712			ci_otg_queue_work(ci);
    713		}
    714		break;
    715	case OTG_STATE_B_WAIT_ACON:
    716		if ((intr_sts & USBi_PCI) && port_conn) {
    717			fsm->a_conn = 1;
    718			ci_otg_queue_work(ci);
    719		}
    720		break;
    721	default:
    722		break;
    723	}
    724}
    725
    726/*
    727 * ci_otg_irq - otg fsm related irq handling
    728 * and also update otg fsm variable by monitoring usb host and udc
    729 * state change interrupts.
    730 * @ci: ci_hdrc
    731 */
    732irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci)
    733{
    734	irqreturn_t retval =  IRQ_NONE;
    735	u32 otgsc, otg_int_src = 0;
    736	struct otg_fsm *fsm = &ci->fsm;
    737
    738	otgsc = hw_read_otgsc(ci, ~0);
    739	otg_int_src = otgsc & OTGSC_INT_STATUS_BITS & (otgsc >> 8);
    740	fsm->id = (otgsc & OTGSC_ID) ? 1 : 0;
    741
    742	if (otg_int_src) {
    743		if (otg_int_src & OTGSC_DPIS) {
    744			hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
    745			fsm->a_srp_det = 1;
    746			fsm->a_bus_drop = 0;
    747		} else if (otg_int_src & OTGSC_IDIS) {
    748			hw_write_otgsc(ci, OTGSC_IDIS, OTGSC_IDIS);
    749			if (fsm->id == 0) {
    750				fsm->a_bus_drop = 0;
    751				fsm->a_bus_req = 1;
    752				ci->id_event = true;
    753			}
    754		} else if (otg_int_src & OTGSC_BSVIS) {
    755			hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
    756			if (otgsc & OTGSC_BSV) {
    757				fsm->b_sess_vld = 1;
    758				ci_otg_del_timer(ci, B_SSEND_SRP);
    759				ci_otg_del_timer(ci, B_SRP_FAIL);
    760				fsm->b_ssend_srp = 0;
    761			} else {
    762				fsm->b_sess_vld = 0;
    763				if (fsm->id)
    764					ci_otg_add_timer(ci, B_SSEND_SRP);
    765			}
    766		} else if (otg_int_src & OTGSC_AVVIS) {
    767			hw_write_otgsc(ci, OTGSC_AVVIS, OTGSC_AVVIS);
    768			if (otgsc & OTGSC_AVV) {
    769				fsm->a_vbus_vld = 1;
    770			} else {
    771				fsm->a_vbus_vld = 0;
    772				fsm->b_conn = 0;
    773			}
    774		}
    775		ci_otg_queue_work(ci);
    776		return IRQ_HANDLED;
    777	}
    778
    779	ci_otg_fsm_event(ci);
    780
    781	return retval;
    782}
    783
    784void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci)
    785{
    786	ci_otg_queue_work(ci);
    787}
    788
    789int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
    790{
    791	int retval = 0;
    792
    793	if (ci->phy)
    794		ci->otg.phy = ci->phy;
    795	else
    796		ci->otg.usb_phy = ci->usb_phy;
    797
    798	ci->otg.gadget = &ci->gadget;
    799	ci->fsm.otg = &ci->otg;
    800	ci->fsm.power_up = 1;
    801	ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
    802	ci->fsm.otg->state = OTG_STATE_UNDEFINED;
    803	ci->fsm.ops = &ci_otg_ops;
    804	ci->gadget.hnp_polling_support = 1;
    805	ci->fsm.host_req_flag = devm_kzalloc(ci->dev, 1, GFP_KERNEL);
    806	if (!ci->fsm.host_req_flag)
    807		return -ENOMEM;
    808
    809	mutex_init(&ci->fsm.lock);
    810
    811	retval = ci_otg_init_timers(ci);
    812	if (retval) {
    813		dev_err(ci->dev, "Couldn't init OTG timers\n");
    814		return retval;
    815	}
    816	ci->enabled_otg_timer_bits = 0;
    817	ci->next_otg_timer = NUM_OTG_FSM_TIMERS;
    818
    819	retval = sysfs_create_group(&ci->dev->kobj, &inputs_attr_group);
    820	if (retval < 0) {
    821		dev_dbg(ci->dev,
    822			"Can't register sysfs attr group: %d\n", retval);
    823		return retval;
    824	}
    825
    826	/* Enable A vbus valid irq */
    827	hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE);
    828
    829	if (ci->fsm.id) {
    830		ci->fsm.b_ssend_srp =
    831			hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1;
    832		ci->fsm.b_sess_vld =
    833			hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0;
    834		/* Enable BSV irq */
    835		hw_write_otgsc(ci, OTGSC_BSVIE, OTGSC_BSVIE);
    836	}
    837
    838	return 0;
    839}
    840
    841void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci)
    842{
    843	sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group);
    844}