[PATCH v3 2/2] mailbox: mpfs: read the system controller's status

Palmer Dabbelt palmer at rivosinc.com
Fri Dec 9 11:14:40 PST 2022


On Wed, 23 Nov 2022 09:56:52 PST (-0800), Conor Dooley wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
>
> Some services explicitly return an error code in their response, but
> others rely on the system controller to set a status in its status
> register. The meaning of the bits varies based on what service is
> requested, so pass it back up to the driver that requested the service
> in the first place. The field in the message struct already existed, but
> was unused until now.
>
> If the system controller is busy, in which case we should never actually
> be in the interrupt handler, or if the service fails the mailbox itself
> should not be read. Callers should check the status before operating on
> the response.
>
> There's an existing, but unused, #define for the mailbox mask - but it
> was incorrect. It was doing a GENMASK_ULL(32, 16) which should've just
> been a GENMASK(31, 16), so fix that up and start using it.
>
> Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox")
> Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  drivers/mailbox/mailbox-mpfs.c | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
> index cfacb3f320a6..853901acaeec 100644
> --- a/drivers/mailbox/mailbox-mpfs.c
> +++ b/drivers/mailbox/mailbox-mpfs.c
> @@ -2,7 +2,7 @@
>  /*
>   * Microchip PolarFire SoC (MPFS) system controller/mailbox controller driver
>   *
> - * Copyright (c) 2020 Microchip Corporation. All rights reserved.
> + * Copyright (c) 2020-2022 Microchip Corporation. All rights reserved.
>   *
>   * Author: Conor Dooley <conor.dooley at microchip.com>
>   *
> @@ -56,7 +56,7 @@
>  #define SCB_STATUS_NOTIFY_MASK BIT(SCB_STATUS_NOTIFY)
>
>  #define SCB_STATUS_POS (16)
> -#define SCB_STATUS_MASK GENMASK_ULL(SCB_STATUS_POS + SCB_MASK_WIDTH, SCB_STATUS_POS)
> +#define SCB_STATUS_MASK GENMASK(SCB_STATUS_POS + SCB_MASK_WIDTH - 1, SCB_STATUS_POS)
>
>  struct mpfs_mbox {
>  	struct mbox_controller controller;
> @@ -130,13 +130,38 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
>  	struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
>  	struct mpfs_mss_response *response = mbox->response;
>  	u16 num_words = ALIGN((response->resp_size), (4)) / 4U;
> -	u32 i;
> +	u32 i, status;
>
>  	if (!response->resp_msg) {
>  		dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM);
>  		return;
>  	}
>
> +	/*
> +	 * The status is stored in bits 31:16 of the SERVICES_SR register.
> +	 * It is only valid when BUSY == 0.
> +	 * We should *never* get an interrupt while the controller is
> +	 * still in the busy state. If we do, something has gone badly
> +	 * wrong & the content of the mailbox would not be valid.
> +	 */
> +	if (mpfs_mbox_busy(mbox)) {
> +		dev_err(mbox->dev, "got an interrupt but system controller is busy\n");
> +		response->resp_status = 0xDEAD;
> +		return;
> +	}
> +
> +	status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
> +
> +	/*
> +	 * If the status of the individual servers is non-zero, the service has
> +	 * failed. The contents of the mailbox at this point are not be valid,
> +	 * so don't bother reading them. Set the status so that the driver
> +	 * implementing the service can handle the result.
> +	 */
> +	response->resp_status = (status & SCB_STATUS_MASK) >> SCB_STATUS_POS;
> +	if (response->resp_status)
> +		return;
> +
>  	if (!mpfs_mbox_busy(mbox)) {
>  		for (i = 0; i < num_words; i++) {
>  			response->resp_msg[i] =

Reviewed-by: Palmer Dabbelt <palmer at rivosinc.com>

I'm assuming this is aimed at some other tree.



More information about the linux-riscv mailing list