[Skiboot] [PATCH v8 2/2] Add SBE driver support
Benjamin Herrenschmidt
benh at kernel.crashing.org
Fri Apr 20 16:21:45 AEST 2018
On Thu, 2018-04-19 at 13:58 +0530, Vasant Hegde wrote:
> +}
> +
> +static void __p9_sbe_interrupt(struct p9_sbe *sbe)
> +{
> + bool has_response = false;
> + int rc;
> + u64 data = 0, val;
> + struct p9_sbe_msg *msg = NULL;
>
> /* Read doorbell register */
> - rc = xscom_read(chip_id, PSU_HOST_DOORBELL_REG_RW, &data);
> + rc = xscom_read(sbe->chip_id, PSU_HOST_DOORBELL_REG_RW, &data);
> if (rc) {
> prlog(PR_ERR, "Failed to read SBE to Host doorbell register "
> - "[chip id = %x]\n", chip_id);
> - goto clr_interrupt;
> + "[chip id = %x]\n", sbe->chip_id);
> + p9_sbe_reg_dump(sbe->chip_id);
> + return;
> }
>
> - /* SBE passtrhough command, call prd handler */
> - if (data & SBE_HOST_PASSTHROUGH) {
> - prd_sbe_passthrough(chip_id);
> + /* Called from poller path, nothing to process */
> + if (!data)
> + return;
> +
> + /* Read SBE response before clearing doorbell register */
> + if (data & SBE_HOST_RESPONSE_WAITING) {
> + if (!list_empty(&sbe->msg_list)) {
> + msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
> + p9_sbe_handle_response(sbe->chip_id, msg);
> + has_response = true;
> + }
> }
I still think you should process the ACKs before you look at responses.
Didn't we also say we should have a separate variable for responses in
this function ?
Generally I still prefer if we handle one bit at a time amd loop & re-
read & retry, as discussed.
> -clr_interrupt:
> - /* Clears all the bits */
> - rc = xscom_write(chip_id, PSU_HOST_DOORBELL_REG_AND,
> - SBE_HOST_RESPONSE_CLEAR);
> + /* Clear doorbell register */
> + val = SBE_HOST_RESPONSE_MASK & ~data;
> + rc = xscom_write(sbe->chip_id, PSU_HOST_DOORBELL_REG_AND, val);
> if (rc) {
> prlog(PR_ERR, "Failed to clear SBE to Host doorbell "
> - "register [chip id = %x]\n", chip_id);
> + "interrupt [chip id = %x]\n", sbe->chip_id);
> + return;
> + }
> +
> + /* SBE came back from reset */
> + if (data & SBE_HOST_RESET) {
> + prlog(PR_NOTICE, "Back from reset [chip id = %x]\n", sbe->chip_id);
> + /* Reset SBE MBOX state */
> + sbe->state = sbe_mbox_idle;
> +
> + /* Reset message state */
> + if (!list_empty(&sbe->msg_list)) {
> + msg = list_top(&sbe->msg_list, struct p9_sbe_msg, link);
> + msg->state = sbe_msg_queued;
> + }
> + goto next_msg;
> + }
> +
> + /* SBE passthrough command, call prd handler */
> + if (data & SBE_HOST_PASSTHROUGH) {
> + prd_sbe_passthrough(sbe->chip_id);
> + }
> +
> + /* Process ACK message before response */
> + if (data & SBE_HOST_MSG_READ) {
> + p9_sbe_send_complete(sbe);
> }
> +
> + /* Got response */
> + if (has_response) {
> + /* Reset SBE MBOX state */
> + sbe->state = sbe_mbox_idle;
> + p9_sbe_msg_complete(sbe, msg, sbe_msg_done);
> + }
> +
> +next_msg:
> + p9_sbe_process_queue(sbe);
> +}
> +
More information about the Skiboot
mailing list