[PATCH linux dev-4.10 3/3] drivers: fsi: sbefifo: Attempt reset request during probe

Andrew Jeffery andrew at aj.id.au
Thu Oct 19 00:58:24 AEDT 2017


On Tue, 2017-10-17 at 16:35 -0500, Eddie James wrote:
> From: "Edward A. James" <eajames at us.ibm.com>
> 
> If data is found in the FIFO, the driver currently immediately fails
> the probe. Instead, try a reset request and poll for it's completion for
> a while (this protocol is defined in the SBE FIFO spec, though the
> timeout lengths are my own invention).
> 
> Signed-off-by: Edward A. James <eajames at us.ibm.com>
> ---
>  drivers/fsi/fsi-sbefifo.c | 53 +++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 42 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
> index 764d8f3..f756822 100644
> --- a/drivers/fsi/fsi-sbefifo.c
> +++ b/drivers/fsi/fsi-sbefifo.c
> @@ -47,8 +47,10 @@
>  
>  #define SBEFIFO_STS		0x04
>  #define   SBEFIFO_EMPTY			BIT(20)
> +#define   SBEFIFO_STS_RESET_REQ		BIT(25)
>  #define SBEFIFO_EOT_RAISE	0x08
>  #define   SBEFIFO_EOT_MAGIC		0xffffffff
> +#define SBEFIFO_REQ_RESET	0x0C

Bit of a nit, but it would be nice to have consistency between RESET_REQ and
REQ_RESET. I don't see any reason for it to be inconsistent from reading the
documentation. However that can probably be left for some other time.

Andrew

>  #define SBEFIFO_EOT_ACK		0x14
>  
>  #define SBEFIFO_RESCHEDULE	msecs_to_jiffies(500)
> @@ -831,6 +833,36 @@ static int sbefifo_unregister_child(struct device *dev, void *data)
>  	return 0;
>  }
>  
> +static int sbefifo_request_reset(struct sbefifo *sbefifo)
> +{
> +	int ret;
> +	u32 status;
> +	unsigned long start;
> +	const unsigned int wait_time = 5;	/* jiffies */
> +	const unsigned long timeout = msecs_to_jiffies(250);
> +
> +	ret = sbefifo_outw(sbefifo, SBEFIFO_UP | SBEFIFO_REQ_RESET, 1);
> +	if (ret)
> +		return ret;
> +
> +	start = jiffies;
> +
> +	do {
> +		ret = sbefifo_inw(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &status);
> +		if (ret)
> +			return ret;
> +
> +		if (!(status & SBEFIFO_STS_RESET_REQ))
> +			return 0;
> +
> +		set_current_state(TASK_INTERRUPTIBLE);
> +		if (schedule_timeout(wait_time) > 0)
> +			return -EINTR;
> +	} while (time_after(start + timeout, jiffies));
> +
> +	return -ETIME;
> +}
> +
>  static int sbefifo_probe(struct device *dev)
>  {
>  	struct fsi_device *fsi_dev = to_fsi_dev(dev);
> @@ -838,7 +870,7 @@ static int sbefifo_probe(struct device *dev)
>  	struct device_node *np;
>  	struct platform_device *child;
>  	char child_name[32];
> -	u32 sts;
> +	u32 up, down;
>  	int ret, child_idx = 0;
>  
>  	dev_dbg(dev, "Found sbefifo device\n");
> @@ -848,22 +880,21 @@ static int sbefifo_probe(struct device *dev)
>  
>  	sbefifo->fsi_dev = fsi_dev;
>  
> -	ret = sbefifo_inw(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &sts);
> +	ret = sbefifo_inw(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &up);
>  	if (ret)
>  		return ret;
>  
> -	if (!(sts & SBEFIFO_EMPTY)) {
> -		dev_err(dev, "Found data in upstream fifo\n");
> -		return -EIO;
> -	}
> -
> -	ret = sbefifo_inw(sbefifo, SBEFIFO_DWN | SBEFIFO_STS, &sts);
> +	ret = sbefifo_inw(sbefifo, SBEFIFO_DWN | SBEFIFO_STS, &down);
>  	if (ret)
>  		return ret;
>  
> -	if (!(sts & SBEFIFO_EMPTY)) {
> -		dev_err(dev, "Found data in downstream fifo\n");
> -		return -EIO;
> +	if (!(up & SBEFIFO_EMPTY) || !(down & SBEFIFO_EMPTY)) {
> +		ret = sbefifo_request_reset(sbefifo);
> +		if (ret) {
> +			dev_err(dev,
> +				"fifos weren't empty and failed the reset\n");
> +			return ret;
> +		}
>  	}
>  
>  	spin_lock_init(&sbefifo->lock);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20171019/cb530a24/attachment.sig>


More information about the openbmc mailing list