diff options
Diffstat (limited to 'drivers/usb/chipidea/otg_fsm.c')
| -rw-r--r-- | drivers/usb/chipidea/otg_fsm.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 949183ede16f..929536dc96ec 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * otg_fsm.c - ChipIdea USB IP core OTG FSM driver * * Copyright (C) 2014 Freescale Semiconductor, Inc. * * Author: Jun Li - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ /* @@ -32,7 +29,7 @@ /* Add for otg: interact with user space app */ static ssize_t -get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +a_bus_req_show(struct device *dev, struct device_attribute *attr, char *buf) { char *next; unsigned size, t; @@ -48,7 +45,7 @@ get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) } static ssize_t -set_a_bus_req(struct device *dev, struct device_attribute *attr, +a_bus_req_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ci_hdrc *ci = dev_get_drvdata(dev); @@ -78,10 +75,10 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req); +static DEVICE_ATTR_RW(a_bus_req); static ssize_t -get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) +a_bus_drop_show(struct device *dev, struct device_attribute *attr, char *buf) { char *next; unsigned size, t; @@ -97,7 +94,7 @@ get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) } static ssize_t -set_a_bus_drop(struct device *dev, struct device_attribute *attr, +a_bus_drop_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ci_hdrc *ci = dev_get_drvdata(dev); @@ -118,11 +115,10 @@ set_a_bus_drop(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, - set_a_bus_drop); +static DEVICE_ATTR_RW(a_bus_drop); static ssize_t -get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +b_bus_req_show(struct device *dev, struct device_attribute *attr, char *buf) { char *next; unsigned size, t; @@ -138,7 +134,7 @@ get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) } static ssize_t -set_b_bus_req(struct device *dev, struct device_attribute *attr, +b_bus_req_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ci_hdrc *ci = dev_get_drvdata(dev); @@ -163,10 +159,10 @@ set_b_bus_req(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req); +static DEVICE_ATTR_RW(b_bus_req); static ssize_t -set_a_clr_err(struct device *dev, struct device_attribute *attr, +a_clr_err_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ci_hdrc *ci = dev_get_drvdata(dev); @@ -183,7 +179,7 @@ set_a_clr_err(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); +static DEVICE_ATTR_WO(a_clr_err); static struct attribute *inputs_attrs[] = { &dev_attr_a_bus_req.attr, @@ -193,7 +189,7 @@ static struct attribute *inputs_attrs[] = { NULL, }; -static struct attribute_group inputs_attr_group = { +static const struct attribute_group inputs_attr_group = { .name = "inputs", .attrs = inputs_attrs, }; @@ -260,8 +256,10 @@ static void ci_otg_del_timer(struct ci_hdrc *ci, enum otg_fsm_timer t) ci->enabled_otg_timer_bits &= ~(1 << t); if (ci->next_otg_timer == t) { if (ci->enabled_otg_timer_bits == 0) { + spin_unlock_irqrestore(&ci->lock, flags); /* No enabled timers after delete it */ hrtimer_cancel(&ci->otg_fsm_hrtimer); + spin_lock_irqsave(&ci->lock, flags); ci->next_otg_timer = NUM_OTG_FSM_TIMERS; } else { /* Find the next timer */ @@ -426,8 +424,7 @@ static enum hrtimer_restart ci_otg_hrtimer_func(struct hrtimer *t) /* Initialize timers */ static int ci_otg_init_timers(struct ci_hdrc *ci) { - hrtimer_init(&ci->otg_fsm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - ci->otg_fsm_hrtimer.function = ci_otg_hrtimer_func; + hrtimer_setup(&ci->otg_fsm_hrtimer, ci_otg_hrtimer_func, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); return 0; } @@ -463,7 +460,7 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on) struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); if (on) { - /* Enable power power */ + /* Enable power */ hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP, PORTSC_PP); if (ci->platdata->reg_vbus) { @@ -475,6 +472,10 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on) return; } } + + if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) + usb_phy_vbus_on(ci->usb_phy); + /* Disable data pulse irq */ hw_write_otgsc(ci, OTGSC_DPIE, 0); @@ -484,6 +485,9 @@ static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on) if (ci->platdata->reg_vbus) regulator_disable(ci->platdata->reg_vbus); + if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) + usb_phy_vbus_off(ci->usb_phy); + fsm->a_bus_drop = 1; fsm->a_bus_req = 0; } @@ -625,7 +629,6 @@ int ci_otg_fsm_work(struct ci_hdrc *ci) ci_otg_queue_work(ci); } } else if (ci->fsm.otg->state == OTG_STATE_A_HOST) { - pm_runtime_mark_last_busy(ci->dev); pm_runtime_put_autosuspend(ci->dev); return 0; } |
