// SPDX-License-Identifier: GPL-2.0
/**
 * PCI Endpoint *Controller* Address Space Management
 *
 * Copyright (C) 2017 Texas Instruments
 * Author: Kishon Vijay Abraham I <kishon@ti.com>
 */

#include <linux/io.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <linux/pci-epc.h>

/**
 * pci_epc_mem_get_order() - determine the allocation order of a memory size
 * @mem: address space of the endpoint controller
 * @size: the size for which to get the order
 *
 * Reimplement get_order() for mem->page_size since the generic get_order
 * always gets order with a constant PAGE_SIZE.
 */
static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
{
	int order;
	unsigned int page_shift = ilog2(mem->window.page_size);

	size--;
	size >>= page_shift;
#if BITS_PER_LONG == 32
	order = fls(size);
#else
	order = fls64(size);
#endif
	return order;
}

/**
 * pci_epc_multi_mem_init() - initialize the pci_epc_mem structure
 * @epc: the EPC device that invoked pci_epc_mem_init
 * @windows: pointer to windows supported by the device
 * @num_windows: number of windows device supports
 *
 * Invoke to initialize the pci_epc_mem structure used by the
 * endpoint functions to allocate mapped PCI address.
 */
int pci_epc_multi_mem_init(struct pci_epc *epc,
			   struct pci_epc_mem_window *windows,
			   unsigned int num_windows)
{
	struct pci_epc_mem *mem = NULL;
	unsigned long *bitmap = NULL;
	unsigned int page_shift;
	size_t page_size;
	int bitmap_size;
	int pages;
	int ret;
	int i;

	epc->num_windows = 0;

	if (!windows || !num_windows)
		return -EINVAL;

	epc->windows = kcalloc(num_windows, sizeof(*epc->windows), GFP_KERNEL);
	if (!epc->windows)
		return -ENOMEM;

	for (i = 0; i < num_windows; i++) {
		page_size = windows[i].page_size;
		if (page_size < PAGE_SIZE)
			page_size = PAGE_SIZE;
		page_shift = ilog2(page_size);
		pages = windows[i].size >> page_shift;
		bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);

		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
		if (!mem) {
			ret = -ENOMEM;
			i--;
			goto err_mem;
		}

		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
		if (!bitmap) {
			ret = -ENOMEM;
			kfree(mem);
			i--;
			goto err_mem;
		}

		mem->window.phys_base = windows[i].phys_base;
		mem->window.size = windows[i].size;
		mem->window.page_size = page_size;
		mem->bitmap = bitmap;
		mem->pages = pages;
		mutex_init(&mem->lock);
		epc->windows[i] = mem;
	}

	epc->mem = epc->windows[0];
	epc->num_windows = num_windows;

	return 0;

err_mem:
	for (; i >= 0; i--) {
		mem = epc->windows[i];
		kfree(mem->bitmap);
		kfree(mem);
	}
	kfree(epc->windows);

	return ret;
}
EXPORT_SYMBOL_GPL(pci_epc_multi_mem_init);

int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base,
		     size_t size, size_t page_size)
{
	struct pci_epc_mem_window mem_window;

	mem_window.phys_base = base;
	mem_window.size = size;
	mem_window.page_size = page_size;

	return pci_epc_multi_mem_init(epc, &mem_window, 1);
}
EXPORT_SYMBOL_GPL(pci_epc_mem_init);

/**
 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
 * @epc: the EPC device that invoked pci_epc_mem_exit
 *
 * Invoke to cleanup the pci_epc_mem structure allocated in
 * pci_epc_mem_init().
 */
void pci_epc_mem_exit(struct pci_epc *epc)
{
	struct pci_epc_mem *mem;
	int i;

	if (!epc->num_windows)
		return;

	for (i = 0; i < epc->num_windows; i++) {
		mem = epc->windows[i];
		kfree(mem->bitmap);
		kfree(mem);
	}
	kfree(epc->windows);

	epc->windows = NULL;
	epc->mem = NULL;
	epc->num_windows = 0;
}
EXPORT_SYMBOL_GPL(pci_epc_mem_exit);

/**
 * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space
 * @epc: the EPC device on which memory has to be allocated
 * @phys_addr: populate the allocated physical address here
 * @size: the size of the address space that has to be allocated
 *
 * Invoke to allocate memory address from the EPC address space. This
 * is usually done to map the remote RC address into the local system.
 */
void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
				     phys_addr_t *phys_addr, size_t size)
{
	void __iomem *virt_addr = NULL;
	struct pci_epc_mem *mem;
	unsigned int page_shift;
	size_t align_size;
	int pageno;
	int order;
	int i;

	for (i = 0; i < epc->num_windows; i++) {
		mem = epc->windows[i];
		mutex_lock(&mem->lock);
		align_size = ALIGN(size, mem->window.page_size);
		order = pci_epc_mem_get_order(mem, align_size);

		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
						 order);
		if (pageno >= 0) {
			page_shift = ilog2(mem->window.page_size);
			*phys_addr = mem->window.phys_base +
				((phys_addr_t)pageno << page_shift);
			virt_addr = ioremap(*phys_addr, align_size);
			if (!virt_addr) {
				bitmap_release_region(mem->bitmap,
						      pageno, order);
				mutex_unlock(&mem->lock);
				continue;
			}
			mutex_unlock(&mem->lock);
			return virt_addr;
		}
		mutex_unlock(&mem->lock);
	}

	return virt_addr;
}
EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);

static struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc *epc,
						       phys_addr_t phys_addr)
{
	struct pci_epc_mem *mem;
	int i;

	for (i = 0; i < epc->num_windows; i++) {
		mem = epc->windows[i];

		if (phys_addr >= mem->window.phys_base &&
		    phys_addr < (mem->window.phys_base + mem->window.size))
			return mem;
	}

	return NULL;
}

/**
 * pci_epc_mem_free_addr() - free the allocated memory address
 * @epc: the EPC device on which memory was allocated
 * @phys_addr: the allocated physical address
 * @virt_addr: virtual address of the allocated mem space
 * @size: the size of the allocated address space
 *
 * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
 */
void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
			   void __iomem *virt_addr, size_t size)
{
	struct pci_epc_mem *mem;
	unsigned int page_shift;
	size_t page_size;
	int pageno;
	int order;

	mem = pci_epc_get_matching_window(epc, phys_addr);
	if (!mem) {
		pr_err("failed to get matching window\n");
		return;
	}

	page_size = mem->window.page_size;
	page_shift = ilog2(page_size);
	iounmap(virt_addr);
	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
	size = ALIGN(size, page_size);
	order = pci_epc_mem_get_order(mem, size);
	mutex_lock(&mem->lock);
	bitmap_release_region(mem->bitmap, pageno, order);
	mutex_unlock(&mem->lock);
}
EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);

MODULE_DESCRIPTION("PCI EPC Address Space Management");
MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
MODULE_LICENSE("GPL v2");
