mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
Merge "cnss2: Add cnss_smmu_unmap API"
This commit is contained in:
commit
8e7791b3c0
3 changed files with 52 additions and 4 deletions
|
|
@ -3469,12 +3469,17 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
|||
"smmu_iova_ipa");
|
||||
if (res) {
|
||||
pci_priv->smmu_iova_ipa_start = res->start;
|
||||
pci_priv->smmu_iova_ipa_current = res->start;
|
||||
pci_priv->smmu_iova_ipa_len = resource_size(res);
|
||||
cnss_pr_dbg("smmu_iova_ipa_start: %pa, smmu_iova_ipa_len: 0x%zx\n",
|
||||
&pci_priv->smmu_iova_ipa_start,
|
||||
pci_priv->smmu_iova_ipa_len);
|
||||
}
|
||||
|
||||
pci_priv->iommu_geometry = of_property_read_bool(of_node,
|
||||
"qcom,iommu-geometry");
|
||||
cnss_pr_dbg("iommu_geometry: %d\n", pci_priv->iommu_geometry);
|
||||
|
||||
of_node_put(of_node);
|
||||
|
||||
return 0;
|
||||
|
|
@ -3549,10 +3554,11 @@ int cnss_smmu_map(struct device *dev,
|
|||
plat_priv = pci_priv->plat_priv;
|
||||
|
||||
len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE);
|
||||
iova = roundup(pci_priv->smmu_iova_ipa_start, PAGE_SIZE);
|
||||
iova = roundup(pci_priv->smmu_iova_ipa_current, PAGE_SIZE);
|
||||
|
||||
if (iova >=
|
||||
(pci_priv->smmu_iova_ipa_start + pci_priv->smmu_iova_ipa_len)) {
|
||||
if (pci_priv->iommu_geometry &&
|
||||
iova >= pci_priv->smmu_iova_ipa_start +
|
||||
pci_priv->smmu_iova_ipa_len) {
|
||||
cnss_pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
|
||||
iova,
|
||||
&pci_priv->smmu_iova_ipa_start,
|
||||
|
|
@ -3579,6 +3585,8 @@ int cnss_smmu_map(struct device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
cnss_pr_dbg("IOMMU map: iova %lx, len %zu\n", iova, len);
|
||||
|
||||
ret = iommu_map(pci_priv->iommu_domain, iova,
|
||||
rounddown(paddr, PAGE_SIZE), len, flag);
|
||||
if (ret) {
|
||||
|
|
@ -3586,13 +3594,50 @@ int cnss_smmu_map(struct device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
pci_priv->smmu_iova_ipa_start = iova + len;
|
||||
pci_priv->smmu_iova_ipa_current = iova + len;
|
||||
*iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE));
|
||||
cnss_pr_dbg("IOMMU map: iova_addr %lx\n", *iova_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_smmu_map);
|
||||
|
||||
int cnss_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
|
||||
unsigned long iova;
|
||||
size_t unmapped;
|
||||
size_t len;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
iova = rounddown(iova_addr, PAGE_SIZE);
|
||||
len = roundup(size + iova_addr - iova, PAGE_SIZE);
|
||||
|
||||
if (iova >= pci_priv->smmu_iova_ipa_start +
|
||||
pci_priv->smmu_iova_ipa_len) {
|
||||
cnss_pr_err("Out of IOVA space to unmap, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
|
||||
iova,
|
||||
&pci_priv->smmu_iova_ipa_start,
|
||||
pci_priv->smmu_iova_ipa_len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("IOMMU unmap: iova %lx, len %zu\n", iova, len);
|
||||
|
||||
unmapped = iommu_unmap(pci_priv->iommu_domain, iova, len);
|
||||
if (unmapped != len) {
|
||||
cnss_pr_err("IOMMU unmap failed, unmapped = %zu, requested = %zu\n",
|
||||
unmapped, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pci_priv->smmu_iova_ipa_current = iova;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_smmu_unmap);
|
||||
|
||||
int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(to_pci_dev(dev));
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ struct cnss_pci_data {
|
|||
dma_addr_t smmu_iova_start;
|
||||
size_t smmu_iova_len;
|
||||
dma_addr_t smmu_iova_ipa_start;
|
||||
dma_addr_t smmu_iova_ipa_current;
|
||||
size_t smmu_iova_ipa_len;
|
||||
void __iomem *bar;
|
||||
struct cnss_msi_config *msi_config;
|
||||
|
|
@ -101,6 +102,7 @@ struct cnss_pci_data {
|
|||
u32 pcie_reg_size;
|
||||
struct cnss_misc_reg *wlaon_reg;
|
||||
u32 wlaon_reg_size;
|
||||
u8 iommu_geometry;
|
||||
};
|
||||
|
||||
static inline void cnss_set_pci_priv(struct pci_dev *pci_dev, void *data)
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ extern int cnss_get_platform_cap(struct device *dev,
|
|||
extern struct iommu_domain *cnss_smmu_get_domain(struct device *dev);
|
||||
extern int cnss_smmu_map(struct device *dev,
|
||||
phys_addr_t paddr, uint32_t *iova_addr, size_t size);
|
||||
extern int cnss_smmu_unmap(struct device *dev, uint32_t iova_addr, size_t size);
|
||||
extern int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info);
|
||||
extern int cnss_request_bus_bandwidth(struct device *dev, int bandwidth);
|
||||
extern int cnss_power_up(struct device *dev);
|
||||
|
|
|
|||
Loading…
Reference in a new issue