[RFC v1 PATCH 1/2] of/pci: add of_pci_dma_configure() update dma configuration
From: arnd@arndb.de (Arnd Bergmann)
Date: 2014-12-18 22:30:11
Also in:
linux-devicetree, linux-pci, lkml
On Thursday 18 December 2014 17:07:04 Murali Karicheri wrote:
Add of_pci_dma_configure() to allow updating the dma configuration of the pci device using the configuration from the parent of the root bridge device. Signed-off-by: Murali Karicheri <redacted>
Much better! There is one detail that we should get right from the start here, which is currently wrong in the platform device code, but I have so far not dared change it:
+ /* + * Set default dma-mask to 32 bit. Drivers are expected to setup + * the correct supported dma_mask. + */ + dev->coherent_dma_mask = DMA_BIT_MASK(32);
The 32-bit mask is indeed correct as the default for almost all cases, and we must not set it larger than DMA_BIT_MASK(32). There is one corner case though, which happens on some shmobile machines that have a 31-bit mask on the PCI host, and I think we should use that as the default.
+ /*
+ * Set it to coherent_dma_mask by default if the architecture
+ * code has not set it.
+ */
+ if (!dev->dma_mask)
+ dev->dma_mask = &dev->coherent_dma_mask;
+
+ ret = of_dma_get_range(parent_np, &dma_addr, &paddr, &size);
+ if (ret < 0) {
+ dma_addr = offset = 0;
+ size = dev->coherent_dma_mask;Can you check one thing here? I believe the size argument as returned from of_dma_get_range is inclusive (e.g. 0x100000000), while the coherent mask by definition is exlusive (e.g. 0xffffffff), so the size needs to be adapted here. I haven't checked all the code here though, so I may be wrong.
+ } else {
+ offset = PFN_DOWN(paddr - dma_addr);
+ dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset);
+ }
+ dev->dma_pfn_offset = offset;
+
+ coherent = of_dma_is_coherent(parent_np);
+ dev_dbg(dev, "device is%sdma coherent\n",
+ coherent ? " " : " not ");
+
+ arch_setup_dma_ops(dev, dma_addr, size, NULL, coherent);Basically, I would use limit the size argument we pass into arch_setup_dma_ops to the minimum of 'size' and 'dma_mask' here, after converting into the same format. We should make sure we do the same thing for platform_device as well, so it might be better to do it inside of arch_setup_dma_ops instead. Arnd