diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/dma-mapping-fast.h | 57 | ||||
| -rw-r--r-- | include/linux/io-pgtable-fast.h | 57 | ||||
| -rw-r--r-- | include/linux/iommu.h | 47 | ||||
| -rw-r--r-- | include/linux/sched.h | 1 | ||||
| -rwxr-xr-x | include/linux/soundwire/soundwire.h | 2 |
5 files changed, 163 insertions, 1 deletions
diff --git a/include/linux/dma-mapping-fast.h b/include/linux/dma-mapping-fast.h new file mode 100644 index 000000000000..aa9fcfe73162 --- /dev/null +++ b/include/linux/dma-mapping-fast.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that 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. + */ + +#ifndef __LINUX_DMA_MAPPING_FAST_H +#define __LINUX_DMA_MAPPING_FAST_H + +#include <linux/iommu.h> +#include <linux/io-pgtable-fast.h> + +struct dma_fast_smmu_mapping { + struct device *dev; + struct iommu_domain *domain; + dma_addr_t base; + size_t size; + size_t num_4k_pages; + + unsigned int bitmap_size; + unsigned long *bitmap; + unsigned long next_start; + unsigned long upcoming_stale_bit; + bool have_stale_tlbs; + + dma_addr_t pgtbl_dma_handle; + av8l_fast_iopte *pgtbl_pmds; + + spinlock_t lock; + struct notifier_block notifier; +}; + +#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST +int fast_smmu_attach_device(struct device *dev, + struct dma_iommu_mapping *mapping); +void fast_smmu_detach_device(struct device *dev, + struct dma_iommu_mapping *mapping); +#else +static inline int fast_smmu_attach_device(struct device *dev, + struct dma_iommu_mapping *mapping) +{ + return -ENODEV; +} + +static inline void fast_smmu_detach_device(struct device *dev, + struct dma_iommu_mapping *mapping) +{ +} +#endif + +#endif /* __LINUX_DMA_MAPPING_FAST_H */ diff --git a/include/linux/io-pgtable-fast.h b/include/linux/io-pgtable-fast.h new file mode 100644 index 000000000000..ab5a1dc6753e --- /dev/null +++ b/include/linux/io-pgtable-fast.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that 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. + */ + +#ifndef __LINUX_IO_PGTABLE_FAST_H +#define __LINUX_IO_PGTABLE_FAST_H + +#include <linux/notifier.h> + +typedef u64 av8l_fast_iopte; + +#define iopte_pmd_offset(pmds, iova) (pmds + (iova >> 12)) + +int av8l_fast_map_public(av8l_fast_iopte *ptep, phys_addr_t paddr, size_t size, + int prot); +void av8l_fast_unmap_public(av8l_fast_iopte *ptep, size_t size); + +/* events for notifiers passed to av8l_register_notify */ +#define MAPPED_OVER_STALE_TLB 1 + + +#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB +/* + * Doesn't matter what we use as long as bit 0 is unset. The reason why we + * need a different value at all is that there are certain hardware + * platforms with erratum that require that a PTE actually be zero'd out + * and not just have its valid bit unset. + */ +#define AV8L_FAST_PTE_UNMAPPED_NEED_TLBI 0xa + +void av8l_fast_clear_stale_ptes(av8l_fast_iopte *puds, bool skip_sync); +void av8l_register_notify(struct notifier_block *nb); + +#else /* !CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB */ + +#define AV8L_FAST_PTE_UNMAPPED_NEED_TLBI 0 + +static inline void av8l_fast_clear_stale_ptes(av8l_fast_iopte *puds, + bool skip_sync) +{ +} + +static inline void av8l_register_notify(struct notifier_block *nb) +{ +} + +#endif /* CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB */ + +#endif /* __LINUX_IO_PGTABLE_FAST_H */ diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 82c397b30628..56855724271c 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -56,6 +56,10 @@ struct iommu_domain_geometry { bool force_aperture; /* DMA only allowed in mappable range? */ }; +struct iommu_pgtbl_info { + void *pmds; +}; + /* Domain feature flags */ #define __IOMMU_DOMAIN_PAGING (1U << 0) /* Support for iommu_map/unmap */ #define __IOMMU_DOMAIN_DMA_API (1U << 1) /* Domain for use in DMA-API @@ -128,6 +132,8 @@ enum iommu_attr { DOMAIN_ATTR_DYNAMIC, DOMAIN_ATTR_NON_FATAL_FAULTS, DOMAIN_ATTR_S1_BYPASS, + DOMAIN_ATTR_FAST, + DOMAIN_ATTR_PGTBL_INFO, DOMAIN_ATTR_MAX, }; @@ -167,9 +173,14 @@ struct iommu_dm_region { * @domain_set_attr: Change domain attributes * @of_xlate: add OF master IDs to iommu grouping * @pgsize_bitmap: bitmap of supported page sizes + * @get_pgsize_bitmap: gets a bitmap of supported page sizes for a domain + * This takes precedence over @pgsize_bitmap. * @trigger_fault: trigger a fault on the device attached to an iommu domain * @reg_read: read an IOMMU register * @reg_write: write an IOMMU register + * @tlbi_domain: Invalidate all TLBs covering an iommu domain + * @enable_config_clocks: Enable all config clocks for this domain's IOMMU + * @disable_config_clocks: Disable all config clocks for this domain's IOMMU * @priv: per-instance data private to the iommu driver */ struct iommu_ops { @@ -217,11 +228,15 @@ struct iommu_ops { unsigned long offset); void (*reg_write)(struct iommu_domain *domain, unsigned long val, unsigned long offset); + void (*tlbi_domain)(struct iommu_domain *domain); + int (*enable_config_clocks)(struct iommu_domain *domain); + void (*disable_config_clocks)(struct iommu_domain *domain); #ifdef CONFIG_OF_IOMMU int (*of_xlate)(struct device *dev, struct of_phandle_args *args); #endif + unsigned long (*get_pgsize_bitmap)(struct iommu_domain *domain); unsigned long pgsize_bitmap; void *priv; }; @@ -378,6 +393,25 @@ extern struct iommu_group *pci_device_group(struct device *dev); /* Generic device grouping function */ extern struct iommu_group *generic_device_group(struct device *dev); +static inline void iommu_tlbiall(struct iommu_domain *domain) +{ + if (domain->ops->tlbi_domain) + domain->ops->tlbi_domain(domain); +} + +static inline int iommu_enable_config_clocks(struct iommu_domain *domain) +{ + if (domain->ops->enable_config_clocks) + return domain->ops->enable_config_clocks(domain); + return 0; +} + +static inline void iommu_disable_config_clocks(struct iommu_domain *domain) +{ + if (domain->ops->disable_config_clocks) + domain->ops->disable_config_clocks(domain); +} + #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; @@ -622,6 +656,19 @@ static int iommu_dma_supported(struct iommu_domain *domain, struct device *dev, return -EINVAL; } +static inline void iommu_tlbiall(struct iommu_domain *domain) +{ +} + +static inline int iommu_enable_config_clocks(struct iommu_domain *domain) +{ + return 0; +} + +static inline void iommu_disable_config_clocks(struct iommu_domain *domain) +{ +} + #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index bc7ad2e61018..7e107c3d7a5c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -3370,7 +3370,6 @@ static inline unsigned long rlimit_max(unsigned int limit) struct cpu_cycle_counter_cb { u64 (*get_cpu_cycle_counter)(int cpu); - u32 (*get_cpu_cycles_max_per_us)(int cpu); }; int register_cpu_cycle_counter_cb(struct cpu_cycle_counter_cb *cb); diff --git a/include/linux/soundwire/soundwire.h b/include/linux/soundwire/soundwire.h index 4b957245209e..2083e7b5da25 100755 --- a/include/linux/soundwire/soundwire.h +++ b/include/linux/soundwire/soundwire.h @@ -152,6 +152,7 @@ struct swr_master { int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id, u8 *dev_num); void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable); + bool (*remove_from_group)(struct swr_master *mstr); }; static inline struct swr_master *to_swr_master(struct device *dev) @@ -307,4 +308,5 @@ extern int swr_reset_device(struct swr_device *swr_dev); extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num, bool enable); +extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num); #endif /* _LINUX_SOUNDWIRE_H */ |
