in coresight/coresight-tmc-etr.c [188:231]
static int tmc_pages_alloc(struct tmc_pages *tmc_pages,
struct device *dev, int node,
enum dma_data_direction dir, void **pages)
{
int i, nr_pages;
dma_addr_t paddr;
struct page *page;
struct device *real_dev = dev->parent;
nr_pages = tmc_pages->nr_pages;
tmc_pages->daddrs = kcalloc(nr_pages, sizeof(*tmc_pages->daddrs),
GFP_KERNEL);
if (!tmc_pages->daddrs)
return -ENOMEM;
tmc_pages->pages = kcalloc(nr_pages, sizeof(*tmc_pages->pages),
GFP_KERNEL);
if (!tmc_pages->pages) {
kfree(tmc_pages->daddrs);
tmc_pages->daddrs = NULL;
return -ENOMEM;
}
for (i = 0; i < nr_pages; i++) {
if (pages && pages[i]) {
page = virt_to_page(pages[i]);
/* Hold a refcount on the page */
get_page(page);
} else {
page = alloc_pages_node(node,
GFP_KERNEL | __GFP_ZERO, 0);
if (!page)
goto err;
}
paddr = dma_map_page(real_dev, page, 0, PAGE_SIZE, dir);
if (dma_mapping_error(real_dev, paddr))
goto err;
tmc_pages->daddrs[i] = paddr;
tmc_pages->pages[i] = page;
}
return 0;
err:
tmc_pages_free(tmc_pages, dev, dir);
return -ENOMEM;
}