From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hiroshi DOYU Subject: [PATCH 1/1] iommu/tegra: smmu: Add DMA window parser Date: Fri, 18 May 2012 09:43:09 +0300 Message-ID: <1337323393-1035-1-git-send-email-hdoyu@nvidia.com> References: <20120518085051.4a0fca863c5ab37cf8d42cb1@nvidia.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <20120518085051.4a0fca863c5ab37cf8d42cb1-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org Errors-To: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org To: hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org, joerg.roedel-5C7GfCeVMHo@public.gmane.org, swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org, Thierry Reding , linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring , Grant Likely , iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org List-Id: linux-tegra@vger.kernel.org This code was based on: "arch/microblaze/kernel/prom_parse.c" "arch/powerpc/kernel/prom_parse.c" Can be promoted as a global function for general use. Signed-off-by: Hiroshi DOYU --- Based on the discussion: http://marc.info/?l=linux-tegra&m=133732046606458&w=2 --- drivers/iommu/tegra-smmu.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 192fc4a..7fc444b 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -874,6 +874,56 @@ static struct iommu_ops smmu_iommu_ops = { .pgsize_bitmap = SMMU_IOMMU_PGSIZES, }; +static int of_get_dma_window(struct device_node *dn, + const char *propname, int index, + unsigned long *busno, + dma_addr_t *addr, size_t *size) +{ + const __be32 *dma_window, *end; + int bytes, cur_index = 0; + + if (!dn || !addr || !size) + return -EINVAL; + + if (!propname) + propname = "dma-window"; + + dma_window = of_get_property(dn, propname, &bytes); + if (!dma_window) + return -ENODEV; + end = dma_window + bytes / sizeof(*dma_window); + + while (dma_window < end) { + u32 cells; + const void *prop; + + /* busno is always one cell */ + if (busno) + *busno = be32_to_cpup(dma_window++); + + prop = of_get_property(dn, "#dma-address-cells", NULL); + if (!prop) + prop = of_get_property(dn, "#address-cells", NULL); + + cells = prop ? be32_to_cpup(prop) : of_n_addr_cells(dn); + if (!cells) + return -EINVAL; + *addr = of_read_number(dma_window, cells); + dma_window += cells; + + prop = of_get_property(dn, "#dma-size-cells", NULL); + cells = prop ? be32_to_cpup(prop) : of_n_size_cells(dn); + if (!cells) + return -EINVAL; + *size = of_read_number(dma_window, cells); + dma_window += cells; + + if (cur_index++ == index) + break; + } + return 0; +} + static int tegra_smmu_suspend(struct device *dev) { struct smmu_device *smmu = dev_get_drvdata(dev); -- 1.7.5.4