Loading drivers/soc/qcom/rpmh-rsc.c +54 −23 Original line number Diff line number Diff line Loading @@ -200,6 +200,42 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv, return NULL; } static void __tcs_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 inline 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 */ Loading Loading @@ -236,6 +272,21 @@ 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_trigger(drv, i, false); /* * Disable interrupt for this TCS to avoid being * spammed with interrupts coming when the solver * sends its wake votes. */ enable_tcs_irq(drv, i, false); } skip: /* Reclaim the TCS */ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0); Loading Loading @@ -283,28 +334,6 @@ 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) { Loading Loading @@ -375,10 +404,12 @@ 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) enable_tcs_irq(drv, tcs_id, true); spin_unlock(&drv->lock); __tcs_buffer_write(drv, tcs_id, 0, msg); __tcs_trigger(drv, tcs_id); __tcs_trigger(drv, tcs_id, true); done_write: spin_unlock_irqrestore(&tcs->lock, flags); Loading Loading
drivers/soc/qcom/rpmh-rsc.c +54 −23 Original line number Diff line number Diff line Loading @@ -200,6 +200,42 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv, return NULL; } static void __tcs_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 inline 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 */ Loading Loading @@ -236,6 +272,21 @@ 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_trigger(drv, i, false); /* * Disable interrupt for this TCS to avoid being * spammed with interrupts coming when the solver * sends its wake votes. */ enable_tcs_irq(drv, i, false); } skip: /* Reclaim the TCS */ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0); Loading Loading @@ -283,28 +334,6 @@ 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) { Loading Loading @@ -375,10 +404,12 @@ 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) enable_tcs_irq(drv, tcs_id, true); spin_unlock(&drv->lock); __tcs_buffer_write(drv, tcs_id, 0, msg); __tcs_trigger(drv, tcs_id); __tcs_trigger(drv, tcs_id, true); done_write: spin_unlock_irqrestore(&tcs->lock, flags); Loading