diff options
Diffstat (limited to 'drivers/fpga/dfl-afu-main.c')
| -rw-r--r-- | drivers/fpga/dfl-afu-main.c | 35 | 
1 files changed, 24 insertions, 11 deletions
| diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index 753cda4b2568..7f621e96d3b8 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -21,6 +21,9 @@  #include "dfl-afu.h" +#define RST_POLL_INVL 10 /* us */ +#define RST_POLL_TIMEOUT 1000 /* us */ +  /**   * __afu_port_enable - enable a port by clear reset   * @pdev: port platform device. @@ -32,7 +35,7 @@   *   * The caller needs to hold lock for protection.   */ -void __afu_port_enable(struct platform_device *pdev) +int __afu_port_enable(struct platform_device *pdev)  {  	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);  	void __iomem *base; @@ -41,7 +44,7 @@ void __afu_port_enable(struct platform_device *pdev)  	WARN_ON(!pdata->disable_count);  	if (--pdata->disable_count != 0) -		return; +		return 0;  	base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER); @@ -49,10 +52,20 @@ void __afu_port_enable(struct platform_device *pdev)  	v = readq(base + PORT_HDR_CTRL);  	v &= ~PORT_CTRL_SFTRST;  	writeq(v, base + PORT_HDR_CTRL); -} -#define RST_POLL_INVL 10 /* us */ -#define RST_POLL_TIMEOUT 1000 /* us */ +	/* +	 * HW clears the ack bit to indicate that the port is fully out +	 * of reset. +	 */ +	if (readq_poll_timeout(base + PORT_HDR_CTRL, v, +			       !(v & PORT_CTRL_SFTRST_ACK), +			       RST_POLL_INVL, RST_POLL_TIMEOUT)) { +		dev_err(&pdev->dev, "timeout, failure to enable device\n"); +		return -ETIMEDOUT; +	} + +	return 0; +}  /**   * __afu_port_disable - disable a port by hold reset @@ -86,7 +99,7 @@ int __afu_port_disable(struct platform_device *pdev)  	if (readq_poll_timeout(base + PORT_HDR_CTRL, v,  			       v & PORT_CTRL_SFTRST_ACK,  			       RST_POLL_INVL, RST_POLL_TIMEOUT)) { -		dev_err(&pdev->dev, "timeout, fail to reset device\n"); +		dev_err(&pdev->dev, "timeout, failure to disable device\n");  		return -ETIMEDOUT;  	} @@ -110,10 +123,10 @@ static int __port_reset(struct platform_device *pdev)  	int ret;  	ret = __afu_port_disable(pdev); -	if (!ret) -		__afu_port_enable(pdev); +	if (ret) +		return ret; -	return ret; +	return __afu_port_enable(pdev);  }  static int port_reset(struct platform_device *pdev) @@ -872,11 +885,11 @@ static int afu_dev_destroy(struct platform_device *pdev)  static int port_enable_set(struct platform_device *pdev, bool enable)  {  	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); -	int ret = 0; +	int ret;  	mutex_lock(&pdata->lock);  	if (enable) -		__afu_port_enable(pdev); +		ret = __afu_port_enable(pdev);  	else  		ret = __afu_port_disable(pdev);  	mutex_unlock(&pdata->lock); | 
