Revert rpmh and usb changes
8aafbcb
usb: dwc3: gadget: Properly handle failed kick_transferc646369
soc: qcom: rpmh: Dirt can only make you dirtier, not cleanera91f874
soc: qcom: rpmh-rsc: Allow using free WAKE TCS for active requestc15a40c
soc: qcom: rpmh-rsc: Clear active mode configuration for wake TCS8644121
soc: qcom: rpmh: Invalidate SLEEP and WAKE TCSes before flushing new datad504699
soc: qcom: rpmh: Update dirty flag only when data changes Change-Id: I0d919e1b658c8195230444ef118f7f1fe8e63b47 Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
This commit is contained in:
parent
204dd19a9b
commit
73abf3a00c
@ -148,7 +148,7 @@ int rpmh_rsc_invalidate(struct rsc_drv *drv)
|
||||
static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv,
|
||||
const struct tcs_request *msg)
|
||||
{
|
||||
int type;
|
||||
int type, ret;
|
||||
struct tcs_group *tcs;
|
||||
|
||||
switch (msg->state) {
|
||||
@ -169,10 +169,19 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv,
|
||||
* If we are making an active request on a RSC that does not have a
|
||||
* dedicated TCS for active state use, then re-purpose a wake TCS to
|
||||
* send active votes.
|
||||
* NOTE: The driver must be aware that this RSC does not have a
|
||||
* dedicated AMC, and therefore would invalidate the sleep and wake
|
||||
* TCSes before making an active state request.
|
||||
*/
|
||||
tcs = get_tcs_of_type(drv, type);
|
||||
if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs)
|
||||
if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) {
|
||||
tcs = get_tcs_of_type(drv, WAKE_TCS);
|
||||
if (tcs->num_tcs) {
|
||||
ret = rpmh_rsc_invalidate(drv);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
return tcs;
|
||||
}
|
||||
@ -192,42 +201,6 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
|
||||
{
|
||||
u32 enable;
|
||||
|
||||
/*
|
||||
* HW req: Clear the DRV_CONTROL and enable TCS again
|
||||
* While clearing ensure that the AMC mode trigger is cleared
|
||||
* and then the mode enable is cleared.
|
||||
*/
|
||||
enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0);
|
||||
enable &= ~TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable &= ~TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
|
||||
if (trigger) {
|
||||
/* Enable the AMC mode on the TCS and then trigger the TCS */
|
||||
enable = TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable |= TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, 0);
|
||||
if (enable)
|
||||
data |= BIT(tcs_id);
|
||||
else
|
||||
data &= ~BIT(tcs_id);
|
||||
write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* tcs_tx_done: TX Done interrupt handler
|
||||
*/
|
||||
@ -264,14 +237,6 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
|
||||
}
|
||||
|
||||
trace_rpmh_tx_done(drv, i, req, err);
|
||||
|
||||
/*
|
||||
* If wake tcs was re-purposed for sending active
|
||||
* votes, clear AMC trigger & enable modes and
|
||||
* disable interrupt for this TCS
|
||||
*/
|
||||
if (!drv->tcs[ACTIVE_TCS].num_tcs)
|
||||
__tcs_set_trigger(drv, i, false);
|
||||
skip:
|
||||
/* Reclaim the TCS */
|
||||
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0);
|
||||
@ -279,13 +244,6 @@ skip:
|
||||
write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i));
|
||||
spin_lock(&drv->lock);
|
||||
clear_bit(i, drv->tcs_in_use);
|
||||
/*
|
||||
* Disable interrupt for WAKE TCS to avoid being
|
||||
* spammed with interrupts coming when the solver
|
||||
* sends its wake votes.
|
||||
*/
|
||||
if (!drv->tcs[ACTIVE_TCS].num_tcs)
|
||||
enable_tcs_irq(drv, i, false);
|
||||
spin_unlock(&drv->lock);
|
||||
if (req)
|
||||
rpmh_tx_done(req, err);
|
||||
@ -327,6 +285,28 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
|
||||
write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable);
|
||||
}
|
||||
|
||||
static void __tcs_trigger(struct rsc_drv *drv, int tcs_id)
|
||||
{
|
||||
u32 enable;
|
||||
|
||||
/*
|
||||
* HW req: Clear the DRV_CONTROL and enable TCS again
|
||||
* While clearing ensure that the AMC mode trigger is cleared
|
||||
* and then the mode enable is cleared.
|
||||
*/
|
||||
enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0);
|
||||
enable &= ~TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable &= ~TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
|
||||
/* Enable the AMC mode on the TCS and then trigger the TCS */
|
||||
enable = TCS_AMC_MODE_ENABLE;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
enable |= TCS_AMC_MODE_TRIGGER;
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable);
|
||||
}
|
||||
|
||||
static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
|
||||
const struct tcs_request *msg)
|
||||
{
|
||||
@ -397,20 +377,10 @@ static int tcs_write(struct rsc_drv *drv, const struct tcs_request *msg)
|
||||
|
||||
tcs->req[tcs_id - tcs->offset] = msg;
|
||||
set_bit(tcs_id, drv->tcs_in_use);
|
||||
if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) {
|
||||
/*
|
||||
* Clear previously programmed WAKE commands in selected
|
||||
* repurposed TCS to avoid triggering them. tcs->slots will be
|
||||
* cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate()
|
||||
*/
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0);
|
||||
write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0);
|
||||
enable_tcs_irq(drv, tcs_id, true);
|
||||
}
|
||||
spin_unlock(&drv->lock);
|
||||
|
||||
__tcs_buffer_write(drv, tcs_id, 0, msg);
|
||||
__tcs_set_trigger(drv, tcs_id, true);
|
||||
__tcs_trigger(drv, tcs_id);
|
||||
|
||||
done_write:
|
||||
spin_unlock_irqrestore(&tcs->lock, flags);
|
||||
|
@ -119,7 +119,6 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
|
||||
{
|
||||
struct cache_req *req;
|
||||
unsigned long flags;
|
||||
u32 old_sleep_val, old_wake_val;
|
||||
|
||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||
req = __find_req(ctrlr, cmd->addr);
|
||||
@ -134,27 +133,26 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr,
|
||||
|
||||
req->addr = cmd->addr;
|
||||
req->sleep_val = req->wake_val = UINT_MAX;
|
||||
INIT_LIST_HEAD(&req->list);
|
||||
list_add_tail(&req->list, &ctrlr->cache);
|
||||
|
||||
existing:
|
||||
old_sleep_val = req->sleep_val;
|
||||
old_wake_val = req->wake_val;
|
||||
|
||||
switch (state) {
|
||||
case RPMH_ACTIVE_ONLY_STATE:
|
||||
if (req->sleep_val != UINT_MAX)
|
||||
req->wake_val = cmd->data;
|
||||
break;
|
||||
case RPMH_WAKE_ONLY_STATE:
|
||||
req->wake_val = cmd->data;
|
||||
break;
|
||||
case RPMH_SLEEP_STATE:
|
||||
req->sleep_val = cmd->data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ctrlr->dirty |= (req->sleep_val != old_sleep_val ||
|
||||
req->wake_val != old_wake_val) &&
|
||||
req->sleep_val != UINT_MAX &&
|
||||
req->wake_val != UINT_MAX;
|
||||
|
||||
ctrlr->dirty = true;
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||
|
||||
@ -290,7 +288,6 @@ static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req)
|
||||
|
||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||
list_add_tail(&req->list, &ctrlr->batch_cache);
|
||||
ctrlr->dirty = true;
|
||||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||
}
|
||||
|
||||
@ -318,6 +315,18 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void invalidate_batch(struct rpmh_ctrlr *ctrlr)
|
||||
{
|
||||
struct batch_cache_req *req, *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||
list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list)
|
||||
kfree(req);
|
||||
INIT_LIST_HEAD(&ctrlr->batch_cache);
|
||||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmh_write_batch: Write multiple sets of RPMH commands and wait for the
|
||||
* batch to finish.
|
||||
@ -457,13 +466,6 @@ int rpmh_flush(const struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Invalidate the TCSes first to avoid stale data */
|
||||
do {
|
||||
ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr));
|
||||
} while (ret == -EAGAIN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* First flush the cached batch requests */
|
||||
ret = flush_batch(ctrlr);
|
||||
if (ret)
|
||||
@ -495,25 +497,25 @@ int rpmh_flush(const struct device *dev)
|
||||
EXPORT_SYMBOL(rpmh_flush);
|
||||
|
||||
/**
|
||||
* rpmh_invalidate: Invalidate sleep and wake sets in batch_cache
|
||||
* rpmh_invalidate: Invalidate all sleep and active sets
|
||||
* sets.
|
||||
*
|
||||
* @dev: The device making the request
|
||||
*
|
||||
* Invalidate the sleep and wake values in batch_cache.
|
||||
* Invalidate the sleep and active values in the TCS blocks.
|
||||
*/
|
||||
int rpmh_invalidate(const struct device *dev)
|
||||
{
|
||||
struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev);
|
||||
struct batch_cache_req *req, *tmp;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&ctrlr->cache_lock, flags);
|
||||
list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list)
|
||||
kfree(req);
|
||||
INIT_LIST_HEAD(&ctrlr->batch_cache);
|
||||
invalidate_batch(ctrlr);
|
||||
ctrlr->dirty = true;
|
||||
spin_unlock_irqrestore(&ctrlr->cache_lock, flags);
|
||||
|
||||
return 0;
|
||||
do {
|
||||
ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr));
|
||||
} while (ret == -EAGAIN);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rpmh_invalidate);
|
||||
|
@ -1217,8 +1217,6 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
|
||||
}
|
||||
}
|
||||
|
||||
static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep);
|
||||
|
||||
static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
|
||||
{
|
||||
struct dwc3_gadget_ep_cmd_params params;
|
||||
@ -1255,20 +1253,14 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
|
||||
|
||||
ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms);
|
||||
if (ret < 0) {
|
||||
struct dwc3_request *tmp;
|
||||
|
||||
if (ret == -EAGAIN)
|
||||
return ret;
|
||||
|
||||
dwc3_stop_active_transfer(dep, true, true);
|
||||
|
||||
list_for_each_entry_safe(req, tmp, &dep->started_list, list)
|
||||
dwc3_gadget_move_cancelled_request(req);
|
||||
|
||||
/* If ep isn't started, then there's no end transfer pending */
|
||||
if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
|
||||
dwc3_gadget_ep_cleanup_cancelled_requests(dep);
|
||||
|
||||
/*
|
||||
* FIXME we need to iterate over the list of requests
|
||||
* here and stop, unmap, free and del each of the linked
|
||||
* requests instead of what we do now.
|
||||
*/
|
||||
if (req->trb)
|
||||
memset(req->trb, 0, sizeof(struct dwc3_trb));
|
||||
dwc3_gadget_del_and_unmap_request(dep, req, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user