summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/dma-mapping-fast.h57
-rw-r--r--include/linux/io-pgtable-fast.h57
-rw-r--r--include/linux/iommu.h47
-rw-r--r--include/linux/sched.h1
-rwxr-xr-xinclude/linux/soundwire/soundwire.h2
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 */