|
@@ -101,6 +101,50 @@ static struct tcs_group *get_tcs_of_type(struct rsc_drv *drv, int type)
|
|
|
return &drv->tcs[type];
|
|
|
}
|
|
|
|
|
|
+static int tcs_invalidate(struct rsc_drv *drv, int type)
|
|
|
+{
|
|
|
+ int m;
|
|
|
+ struct tcs_group *tcs;
|
|
|
+
|
|
|
+ tcs = get_tcs_of_type(drv, type);
|
|
|
+ if (IS_ERR(tcs))
|
|
|
+ return PTR_ERR(tcs);
|
|
|
+
|
|
|
+ spin_lock(&tcs->lock);
|
|
|
+ if (bitmap_empty(tcs->slots, MAX_TCS_SLOTS)) {
|
|
|
+ spin_unlock(&tcs->lock);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) {
|
|
|
+ if (!tcs_is_free(drv, m)) {
|
|
|
+ spin_unlock(&tcs->lock);
|
|
|
+ return -EAGAIN;
|
|
|
+ }
|
|
|
+ write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, m, 0);
|
|
|
+ }
|
|
|
+ bitmap_zero(tcs->slots, MAX_TCS_SLOTS);
|
|
|
+ spin_unlock(&tcs->lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * rpmh_rsc_invalidate - Invalidate sleep and wake TCSes
|
|
|
+ *
|
|
|
+ * @drv: the RSC controller
|
|
|
+ */
|
|
|
+int rpmh_rsc_invalidate(struct rsc_drv *drv)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = tcs_invalidate(drv, SLEEP_TCS);
|
|
|
+ if (!ret)
|
|
|
+ ret = tcs_invalidate(drv, WAKE_TCS);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv,
|
|
|
const struct tcs_request *msg)
|
|
|
{
|