Path: blob/master/arch/powerpc/kernel/dma-swiotlb.c
10818 views
/*1* Contains routines needed to support swiotlb for ppc.2*3* Copyright (C) 2009-2010 Freescale Semiconductor, Inc.4* Author: Becky Bruce5*6* This program is free software; you can redistribute it and/or modify it7* under the terms of the GNU General Public License as published by the8* Free Software Foundation; either version 2 of the License, or (at your9* option) any later version.10*11*/1213#include <linux/dma-mapping.h>14#include <linux/pfn.h>15#include <linux/of_platform.h>16#include <linux/platform_device.h>17#include <linux/pci.h>1819#include <asm/machdep.h>20#include <asm/swiotlb.h>21#include <asm/dma.h>22#include <asm/abs_addr.h>2324unsigned int ppc_swiotlb_enable;2526/*27* At the moment, all platforms that use this code only require28* swiotlb to be used if we're operating on HIGHMEM. Since29* we don't ever call anything other than map_sg, unmap_sg,30* map_page, and unmap_page on highmem, use normal dma_ops31* for everything else.32*/33struct dma_map_ops swiotlb_dma_ops = {34.alloc_coherent = dma_direct_alloc_coherent,35.free_coherent = dma_direct_free_coherent,36.map_sg = swiotlb_map_sg_attrs,37.unmap_sg = swiotlb_unmap_sg_attrs,38.dma_supported = swiotlb_dma_supported,39.map_page = swiotlb_map_page,40.unmap_page = swiotlb_unmap_page,41.sync_single_for_cpu = swiotlb_sync_single_for_cpu,42.sync_single_for_device = swiotlb_sync_single_for_device,43.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,44.sync_sg_for_device = swiotlb_sync_sg_for_device,45.mapping_error = swiotlb_dma_mapping_error,46};4748void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)49{50struct pci_controller *hose;51struct dev_archdata *sd;5253hose = pci_bus_to_host(pdev->bus);54sd = &pdev->dev.archdata;55sd->max_direct_dma_addr =56hose->dma_window_base_cur + hose->dma_window_size;57}5859static int ppc_swiotlb_bus_notify(struct notifier_block *nb,60unsigned long action, void *data)61{62struct device *dev = data;63struct dev_archdata *sd;6465/* We are only intereted in device addition */66if (action != BUS_NOTIFY_ADD_DEVICE)67return 0;6869sd = &dev->archdata;70sd->max_direct_dma_addr = 0;7172/* May need to bounce if the device can't address all of DRAM */73if ((dma_get_mask(dev) + 1) < memblock_end_of_DRAM())74set_dma_ops(dev, &swiotlb_dma_ops);7576return NOTIFY_DONE;77}7879static struct notifier_block ppc_swiotlb_plat_bus_notifier = {80.notifier_call = ppc_swiotlb_bus_notify,81.priority = 0,82};8384int __init swiotlb_setup_bus_notifier(void)85{86bus_register_notifier(&platform_bus_type,87&ppc_swiotlb_plat_bus_notifier);88return 0;89}909192