-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iommu: Add DMA window parser, of_get_dma_window()
This code was based on: "arch/microblaze/kernel/prom_parse.c" "arch/powerpc/kernel/prom_parse.c" Can replace "of_parse_dma_window()" in the above. This supports different formats flexibly. "prefix" can be configured if any. "busno" and "index" are optionally specified. Set NULL and 0 if not used. Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com> Acked-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
- Loading branch information
Hiroshi Doyu
authored and
Joerg Roedel
committed
Jun 25, 2012
1 parent
485802a
commit 4e0ee78
Showing
4 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* OF helpers for IOMMU | ||
* | ||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program; if not, write to the Free Software Foundation, Inc., | ||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
*/ | ||
|
||
#include <linux/export.h> | ||
#include <linux/limits.h> | ||
#include <linux/of.h> | ||
|
||
/** | ||
* of_get_dma_window - Parse *dma-window property and returns 0 if found. | ||
* | ||
* @dn: device node | ||
* @prefix: prefix for property name if any | ||
* @index: index to start to parse | ||
* @busno: Returns busno if supported. Otherwise pass NULL | ||
* @addr: Returns address that DMA starts | ||
* @size: Returns the range that DMA can handle | ||
* | ||
* This supports different formats flexibly. "prefix" can be | ||
* configured if any. "busno" and "index" are optionally | ||
* specified. Set 0(or NULL) if not used. | ||
*/ | ||
int of_get_dma_window(struct device_node *dn, const char *prefix, int index, | ||
unsigned long *busno, dma_addr_t *addr, size_t *size) | ||
{ | ||
const __be32 *dma_window, *end; | ||
int bytes, cur_index = 0; | ||
char propname[NAME_MAX], addrname[NAME_MAX], sizename[NAME_MAX]; | ||
|
||
if (!dn || !addr || !size) | ||
return -EINVAL; | ||
|
||
if (!prefix) | ||
prefix = ""; | ||
|
||
snprintf(propname, sizeof(propname), "%sdma-window", prefix); | ||
snprintf(addrname, sizeof(addrname), "%s#dma-address-cells", prefix); | ||
snprintf(sizename, sizeof(sizename), "%s#dma-size-cells", prefix); | ||
|
||
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 one cell if supported */ | ||
if (busno) | ||
*busno = be32_to_cpup(dma_window++); | ||
|
||
prop = of_get_property(dn, addrname, 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, sizename, 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; | ||
} | ||
EXPORT_SYMBOL_GPL(of_get_dma_window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#ifndef __OF_IOMMU_H | ||
#define __OF_IOMMU_H | ||
|
||
#ifdef CONFIG_OF_IOMMU | ||
|
||
extern int of_get_dma_window(struct device_node *dn, const char *prefix, | ||
int index, unsigned long *busno, dma_addr_t *addr, | ||
size_t *size); | ||
|
||
#else | ||
|
||
static inline int of_get_dma_window(struct device_node *dn, const char *prefix, | ||
int index, unsigned long *busno, dma_addr_t *addr, | ||
size_t *size) | ||
{ | ||
return -EINVAL; | ||
} | ||
|
||
#endif /* CONFIG_OF_IOMMU */ | ||
|
||
#endif /* __OF_IOMMU_H */ |