Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1267975 > unrolled thread

[PATCH] mmc: dw_mmc: use resource_size_t to store physical address

Started byArnd Bergmann <arnd@arndb.de>
First post2015-11-12 15:30 +0100
Last post2015-11-13 10:40 +0100
Articles 3 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] mmc: dw_mmc: use resource_size_t to store physical address Arnd Bergmann <arnd@arndb.de> - 2015-11-12 15:30 +0100
    Re: [PATCH] mmc: dw_mmc: use resource_size_t to store physical address Andy Shevchenko <andy.shevchenko@gmail.com> - 2015-11-13 02:20 +0100
      Re: [PATCH] mmc: dw_mmc: use resource_size_t to store physical address Arnd Bergmann <arnd@arndb.de> - 2015-11-13 10:40 +0100

#1267975 — [PATCH] mmc: dw_mmc: use resource_size_t to store physical address

FromArnd Bergmann <arnd@arndb.de>
Date2015-11-12 15:30 +0100
Subject[PATCH] mmc: dw_mmc: use resource_size_t to store physical address
Message-ID<qu12W-1Bf-23@gated-at.bofh.it>
The dw_mmc driver stores the physical address of the MMIO registers
in a pointer, which requires the use of type casts, and is actually
broken if anyone ever has this device on a 32-bit SoC in registers
above 4GB. Gcc warns about this possibility when the driver is built
with ARM LPAE enabled:

mmc/host/dw_mmc.c: In function 'dw_mci_edmac_start_dma':
mmc/host/dw_mmc.c:702:17: warning: cast from pointer to integer of different size
  cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
                 ^
mmc/host/dw_mmc-pltfm.c: In function 'dw_mci_pltfm_register':
mmc/host/dw_mmc-pltfm.c:63:19: warning: cast to pointer from integer of different size
  host->phy_regs = (void *)(regs->start);

This changes the code to use resource_size_t, which gets rid of the
warning, the bug and the useless casts.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
From the arm64 allmodconfig build reports

diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 7e1d13b68b06..81bdeeb05a4d 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -60,7 +60,7 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	/* Get registers' physical base address */
-	host->phy_regs = (void *)(regs->start);
+	host->phy_regs = regs->start;
 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
 	if (IS_ERR(host->regs))
 		return PTR_ERR(host->regs);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 7a6cedbe48a8..fb204ee6ff89 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -699,7 +699,7 @@ static int dw_mci_edmac_start_dma(struct dw_mci *host,
 	int ret = 0;
 
 	/* Set external dma config: burst size, burst width */
-	cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
+	cfg.dst_addr = host->phy_regs + fifo_offset;
 	cfg.src_addr = cfg.dst_addr;
 	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index f67b2ec18e6d..7776afb0ffa5 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -172,7 +172,7 @@ struct dw_mci {
 	/* For edmac */
 	struct dw_mci_dma_slave *dms;
 	/* Registers's physical base address */
-	void                    *phy_regs;
+	resource_size_t		phy_regs;
 
 	u32			cmd_status;
 	u32			data_status;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1268531

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2015-11-13 02:20 +0100
Message-ID<qubbY-8bp-11@gated-at.bofh.it>
In reply to#1267975
On Thu, Nov 12, 2015 at 4:14 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> The dw_mmc driver stores the physical address of the MMIO registers
> in a pointer, which requires the use of type casts, and is actually
> broken if anyone ever has this device on a 32-bit SoC in registers
> above 4GB. Gcc warns about this possibility when the driver is built
> with ARM LPAE enabled:

> -       host->phy_regs = (void *)(regs->start);
> +       host->phy_regs = regs->start;

>         /* Set external dma config: burst size, burst width */
> -       cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
> +       cfg.dst_addr = host->phy_regs + fifo_offset;

dst_addr is dma_addr_t?

>         /* Registers's physical base address */
> -       void                    *phy_regs;
> +       resource_size_t         phy_regs;

If dst_addr is dma_addr_t wouldn't be a problem when
resource_size_t is defined as 64-bit address, and dma_addr_t as 32-bit?

Btw, for me casting to dma_addr_t looks sane.

-- 
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1268729

FromArnd Bergmann <arnd@arndb.de>
Date2015-11-13 10:40 +0100
Message-ID<quiZP-4Ce-11@gated-at.bofh.it>
In reply to#1268531
On Friday 13 November 2015 03:10:13 Andy Shevchenko wrote:
> On Thu, Nov 12, 2015 at 4:14 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > The dw_mmc driver stores the physical address of the MMIO registers
> > in a pointer, which requires the use of type casts, and is actually
> > broken if anyone ever has this device on a 32-bit SoC in registers
> > above 4GB. Gcc warns about this possibility when the driver is built
> > with ARM LPAE enabled:
> 
> > -       host->phy_regs = (void *)(regs->start);
> > +       host->phy_regs = regs->start;
> 
> >         /* Set external dma config: burst size, burst width */
> > -       cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
> > +       cfg.dst_addr = host->phy_regs + fifo_offset;
> 
> dst_addr is dma_addr_t?

Sort of. It doesn't really fit into any of the categories, and we actually
had a patch to change the type in the past, see
https://lkml.org/lkml/2015/7/10/167. Not sure what is going on there.

> >         /* Registers's physical base address */
> > -       void                    *phy_regs;
> > +       resource_size_t         phy_regs;
> 
> If dst_addr is dma_addr_t wouldn't be a problem when
> resource_size_t is defined as 64-bit address, and dma_addr_t as 32-bit?
> 
> Btw, for me casting to dma_addr_t looks sane.

The background here is that the address comes from a resource_size_t
that describes the MMIO register area as seen from the CPU, and that
is normally a phys_addr_t (resource_size_t is defined as being long
enough to store a phys_addr_t or various other things depending on
resource->flags).

dma_addr_t strictly speaking refers to a RAM location as seen by a
DMA master, and that only comes out of dma_map_*() or
dma_alloc_coherent().

The DMA engine wants something else here, which is an MMIO register
address as seen by a DMA master, and we don't have a separate typedef
for that. Almost universally all of resource_size_t, phys_addr_t and
dma_addr_t are the same type, and if we ever get a platform that
wants something other than a phys_addr_t to put into cfg.dst_addr,
we are in deep trouble.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web