| From cca8befc85bcdc426de92ae61fab6cb705262823 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 3 Jun 2021 19:17:02 +0000 |
| Subject: powerpc/ps3: Add dma_mask to ps3_dma_region |
| |
| From: Geoff Levand <geoff@infradead.org> |
| |
| [ Upstream commit 9733862e50fdba55e7f1554e4286fcc5302ff28e ] |
| |
| Commit f959dcd6ddfd29235030e8026471ac1b022ad2b0 (dma-direct: Fix |
| potential NULL pointer dereference) added a null check on the |
| dma_mask pointer of the kernel's device structure. |
| |
| Add a dma_mask variable to the ps3_dma_region structure and set |
| the device structure's dma_mask pointer to point to this new variable. |
| |
| Fixes runtime errors like these: |
| # WARNING: Fixes tag on line 10 doesn't match correct format |
| # WARNING: Fixes tag on line 10 doesn't match correct format |
| |
| ps3_system_bus_match:349: dev=8.0(sb_01), drv=8.0(ps3flash): match |
| WARNING: CPU: 0 PID: 1 at kernel/dma/mapping.c:151 .dma_map_page_attrs+0x34/0x1e0 |
| ps3flash sb_01: ps3stor_setup:193: map DMA region failed |
| |
| Signed-off-by: Geoff Levand <geoff@infradead.org> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Link: https://lore.kernel.org/r/562d0c9ea0100a30c3b186bcc7adb34b0bbd2cd7.1622746428.git.geoff@infradead.org |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/powerpc/include/asm/ps3.h | 2 ++ |
| arch/powerpc/platforms/ps3/mm.c | 12 ++++++++++++ |
| 2 files changed, 14 insertions(+) |
| |
| diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h |
| index e646c7f218bc..12b6b76e8d0f 100644 |
| --- a/arch/powerpc/include/asm/ps3.h |
| +++ b/arch/powerpc/include/asm/ps3.h |
| @@ -71,6 +71,7 @@ struct ps3_dma_region_ops; |
| * @bus_addr: The 'translated' bus address of the region. |
| * @len: The length in bytes of the region. |
| * @offset: The offset from the start of memory of the region. |
| + * @dma_mask: Device dma_mask. |
| * @ioid: The IOID of the device who owns this region |
| * @chunk_list: Opaque variable used by the ioc page manager. |
| * @region_ops: struct ps3_dma_region_ops - dma region operations |
| @@ -85,6 +86,7 @@ struct ps3_dma_region { |
| enum ps3_dma_region_type region_type; |
| unsigned long len; |
| unsigned long offset; |
| + u64 dma_mask; |
| |
| /* driver variables (set by ps3_dma_region_create) */ |
| unsigned long bus_addr; |
| diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c |
| index d094321964fb..a81eac35d900 100644 |
| --- a/arch/powerpc/platforms/ps3/mm.c |
| +++ b/arch/powerpc/platforms/ps3/mm.c |
| @@ -6,6 +6,7 @@ |
| * Copyright 2006 Sony Corp. |
| */ |
| |
| +#include <linux/dma-mapping.h> |
| #include <linux/kernel.h> |
| #include <linux/export.h> |
| #include <linux/memblock.h> |
| @@ -1118,6 +1119,7 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, |
| enum ps3_dma_region_type region_type, void *addr, unsigned long len) |
| { |
| unsigned long lpar_addr; |
| + int result; |
| |
| lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0; |
| |
| @@ -1129,6 +1131,16 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, |
| r->offset -= map.r1.offset; |
| r->len = len ? len : ALIGN(map.total, 1 << r->page_size); |
| |
| + dev->core.dma_mask = &r->dma_mask; |
| + |
| + result = dma_set_mask_and_coherent(&dev->core, DMA_BIT_MASK(32)); |
| + |
| + if (result < 0) { |
| + dev_err(&dev->core, "%s:%d: dma_set_mask_and_coherent failed: %d\n", |
| + __func__, __LINE__, result); |
| + return result; |
| + } |
| + |
| switch (dev->dev_type) { |
| case PS3_DEVICE_TYPE_SB: |
| r->region_ops = (USE_DYNAMIC_DMA) |
| -- |
| 2.30.2 |
| |