void pnv_ocxl_spa_release(void *platform_data);
 int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int pe_handle);
 
+int pnv_ocxl_map_lpar(struct pci_dev *dev, uint64_t lparid,
+                     uint64_t lpcr, void __iomem **arva);
+void pnv_ocxl_unmap_lpar(void __iomem *arva);
 #endif /* _ASM_PNV_OCXL_H */
 
        return rc;
 }
 EXPORT_SYMBOL_GPL(pnv_ocxl_spa_remove_pe_from_cache);
+
+int pnv_ocxl_map_lpar(struct pci_dev *dev, uint64_t lparid,
+                     uint64_t lpcr, void __iomem **arva)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       struct pnv_phb *phb = hose->private_data;
+       u64 mmio_atsd;
+       int rc;
+
+       /* ATSD physical address.
+        * ATSD LAUNCH register: write access initiates a shoot down to
+        * initiate the TLB Invalidate command.
+        */
+       rc = of_property_read_u64_index(hose->dn, "ibm,mmio-atsd",
+                                       0, &mmio_atsd);
+       if (rc) {
+               dev_info(&dev->dev, "No available ATSD found\n");
+               return rc;
+       }
+
+       /* Assign a register set to a Logical Partition and MMIO ATSD
+        * LPARID register to the required value.
+        */
+       rc = opal_npu_map_lpar(phb->opal_id, pci_dev_id(dev),
+                              lparid, lpcr);
+       if (rc) {
+               dev_err(&dev->dev, "Error mapping device to LPAR: %d\n", rc);
+               return rc;
+       }
+
+       *arva = ioremap(mmio_atsd, 24);
+       if (!(*arva)) {
+               dev_warn(&dev->dev, "ioremap failed - mmio_atsd: %#llx\n", mmio_atsd);
+               rc = -ENOMEM;
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(pnv_ocxl_map_lpar);
+
+void pnv_ocxl_unmap_lpar(void __iomem *arva)
+{
+       iounmap(arva);
+}
+EXPORT_SYMBOL_GPL(pnv_ocxl_unmap_lpar);