diff options
| author | Mark Brown <broonie@kernel.org> | 2023-09-04 15:53:37 +0100 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2023-09-04 15:53:37 +0100 | 
| commit | 578464679f33cde8331507c78f7b302299df7783 (patch) | |
| tree | 2c2f8f6e1561190ef9b499db1e195512a9591ee8 /drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c | |
| parent | 60ea3db33fbddf559e18567ca8897f6bb9f25290 (diff) | |
| parent | 1f11f4202caf5710204d334fe63392052783876d (diff) | |
spi: sun6i: fix RX data corruption in DMA mode
Merge series from Tobias Schramm <t.schramm@manjaro.org>:
This set of patches fixes two bugs in the sun6i SPI driver that result in
corruption of received data in DMA RX mode.
The first bug seems to be related to an incompatibility of the SPI RX FIFO
with wider than single byte read accesses during SPI transfers. I'm not
sure if this bug affects all types of SPI controllers found in Allwinner
SoCs supported by this driver. However reducing the access width should
always be safe. I've tested this change on a V3s SoC. Further testing to
narrow down the set of affected SoCs in the future would be welcome.
The second bug is a race between SPI RX DMA and FIFO drain logic for
interrupt-based SPI operation. This bug affects all SPI controllers
supported by this driver. Once again this change has been tested on the
Allwinner V3s SoC.
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c | 13 | 
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c index 9c9cca129498..565a1fa436d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c @@ -239,8 +239,13 @@ static int amdgpu_xcp_dev_alloc(struct amdgpu_device *adev)  	for (i = 1; i < MAX_XCP; i++) {  		ret = amdgpu_xcp_drm_dev_alloc(&p_ddev); -		if (ret) +		if (ret == -ENOSPC) { +			dev_warn(adev->dev, +			"Skip xcp node #%d when out of drm node resource.", i); +			return 0; +		} else if (ret) {  			return ret; +		}  		/* Redirect all IOCTLs to the primary device */  		adev->xcp_mgr->xcp[i].rdev = p_ddev->render->dev; @@ -328,6 +333,9 @@ int amdgpu_xcp_dev_register(struct amdgpu_device *adev,  		return 0;  	for (i = 1; i < MAX_XCP; i++) { +		if (!adev->xcp_mgr->xcp[i].ddev) +			break; +  		ret = drm_dev_register(adev->xcp_mgr->xcp[i].ddev, ent->driver_data);  		if (ret)  			return ret; @@ -345,6 +353,9 @@ void amdgpu_xcp_dev_unplug(struct amdgpu_device *adev)  		return;  	for (i = 1; i < MAX_XCP; i++) { +		if (!adev->xcp_mgr->xcp[i].ddev) +			break; +  		p_ddev = adev->xcp_mgr->xcp[i].ddev;  		drm_dev_unplug(p_ddev);  		p_ddev->render->dev = adev->xcp_mgr->xcp[i].rdev;  | 
