.. | .. |
---|
17 | 17 | #include <linux/module.h> |
---|
18 | 18 | #include <linux/of_address.h> |
---|
19 | 19 | #include <linux/of_device.h> |
---|
| 20 | +#include <linux/of_reserved_mem.h> |
---|
20 | 21 | #include <linux/platform_device.h> |
---|
21 | 22 | #include <linux/pm_domain.h> |
---|
22 | 23 | #include <linux/pm_runtime.h> |
---|
.. | .. |
---|
189 | 190 | void *mba_region; |
---|
190 | 191 | size_t mba_size; |
---|
191 | 192 | size_t dp_size; |
---|
| 193 | + |
---|
| 194 | + phys_addr_t mdata_phys; |
---|
| 195 | + size_t mdata_size; |
---|
192 | 196 | |
---|
193 | 197 | phys_addr_t mpss_phys; |
---|
194 | 198 | phys_addr_t mpss_reloc; |
---|
.. | .. |
---|
816 | 820 | if (IS_ERR(metadata)) |
---|
817 | 821 | return PTR_ERR(metadata); |
---|
818 | 822 | |
---|
819 | | - ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); |
---|
820 | | - if (!ptr) { |
---|
821 | | - kfree(metadata); |
---|
822 | | - dev_err(qproc->dev, "failed to allocate mdt buffer\n"); |
---|
823 | | - return -ENOMEM; |
---|
| 823 | + if (qproc->mdata_phys) { |
---|
| 824 | + if (size > qproc->mdata_size) { |
---|
| 825 | + ret = -EINVAL; |
---|
| 826 | + dev_err(qproc->dev, "metadata size outside memory range\n"); |
---|
| 827 | + goto free_metadata; |
---|
| 828 | + } |
---|
| 829 | + |
---|
| 830 | + phys = qproc->mdata_phys; |
---|
| 831 | + ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC); |
---|
| 832 | + if (!ptr) { |
---|
| 833 | + ret = -EBUSY; |
---|
| 834 | + dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", |
---|
| 835 | + &qproc->mdata_phys, size); |
---|
| 836 | + goto free_metadata; |
---|
| 837 | + } |
---|
| 838 | + } else { |
---|
| 839 | + ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); |
---|
| 840 | + if (!ptr) { |
---|
| 841 | + ret = -ENOMEM; |
---|
| 842 | + dev_err(qproc->dev, "failed to allocate mdt buffer\n"); |
---|
| 843 | + goto free_metadata; |
---|
| 844 | + } |
---|
824 | 845 | } |
---|
825 | 846 | |
---|
826 | 847 | memcpy(ptr, metadata, size); |
---|
| 848 | + |
---|
| 849 | + if (qproc->mdata_phys) |
---|
| 850 | + memunmap(ptr); |
---|
827 | 851 | |
---|
828 | 852 | /* Hypervisor mapping to access metadata by modem */ |
---|
829 | 853 | mdata_perm = BIT(QCOM_SCM_VMID_HLOS); |
---|
.. | .. |
---|
853 | 877 | "mdt buffer not reclaimed system may become unstable\n"); |
---|
854 | 878 | |
---|
855 | 879 | free_dma_attrs: |
---|
856 | | - dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); |
---|
| 880 | + if (!qproc->mdata_phys) |
---|
| 881 | + dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); |
---|
| 882 | +free_metadata: |
---|
857 | 883 | kfree(metadata); |
---|
858 | 884 | |
---|
859 | 885 | return ret < 0 ? ret : 0; |
---|
.. | .. |
---|
1585 | 1611 | static int q6v5_alloc_memory_region(struct q6v5 *qproc) |
---|
1586 | 1612 | { |
---|
1587 | 1613 | struct device_node *child; |
---|
| 1614 | + struct reserved_mem *rmem; |
---|
1588 | 1615 | struct device_node *node; |
---|
1589 | 1616 | struct resource r; |
---|
1590 | 1617 | int ret; |
---|
.. | .. |
---|
1637 | 1664 | qproc->mpss_phys = qproc->mpss_reloc = r.start; |
---|
1638 | 1665 | qproc->mpss_size = resource_size(&r); |
---|
1639 | 1666 | |
---|
| 1667 | + if (!child) { |
---|
| 1668 | + node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2); |
---|
| 1669 | + } else { |
---|
| 1670 | + child = of_get_child_by_name(qproc->dev->of_node, "metadata"); |
---|
| 1671 | + node = of_parse_phandle(child, "memory-region", 0); |
---|
| 1672 | + of_node_put(child); |
---|
| 1673 | + } |
---|
| 1674 | + |
---|
| 1675 | + if (!node) |
---|
| 1676 | + return 0; |
---|
| 1677 | + |
---|
| 1678 | + rmem = of_reserved_mem_lookup(node); |
---|
| 1679 | + if (!rmem) { |
---|
| 1680 | + dev_err(qproc->dev, "unable to resolve metadata region\n"); |
---|
| 1681 | + return -EINVAL; |
---|
| 1682 | + } |
---|
| 1683 | + |
---|
| 1684 | + qproc->mdata_phys = rmem->base; |
---|
| 1685 | + qproc->mdata_size = rmem->size; |
---|
| 1686 | + |
---|
1640 | 1687 | return 0; |
---|
1641 | 1688 | } |
---|
1642 | 1689 | |
---|