/** * devm_ioremap_resource() - check, request region, and ioremap resource * @dev: generic device to handle the resource for * @res: resource to be handled * * Checks that a resource is a valid memory region, requests the memory * region and ioremaps it. All operations are managed and will be undone * on driver detach. * * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code * on failure. Usage example: * * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); * base = devm_ioremap_resource(&pdev->dev, res); * if (IS_ERR(base)) * return PTR_ERR(base); */ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) { resource_size_t size; const char *name; void __iomem *dest_ptr; BUG_ON(!dev); if (!res || resource_type(res) != IORESOURCE_MEM) { dev_err(dev, "invalid resource\n"); return IOMEM_ERR_PTR(-EINVAL); } size = resource_size(res); name = res->name ?: dev_name(dev); if (!devm_request_mem_region(dev, res->start, size, name)) { dev_err(dev, "can't request region for resource %pR\n", res); return IOMEM_ERR_PTR(-EBUSY); } dest_ptr = devm_ioremap(dev, res->start, size); if (!dest_ptr) { dev_err(dev, "ioremap failed for resource %pR\n", res); devm_release_mem_region(dev, res->start, size); dest_ptr = IOMEM_ERR_PTR(-ENOMEM); } return dest_ptr; }
/** * mips_cdmm_early_probe() - Minimally probe for a specific device on CDMM. * @dev_type: CDMM type code to look for. * * Minimally configure the in-CPU Common Device Memory Map (CDMM) and look for a * specific device. This can be used to find a device very early in boot for * example to configure an early FDC console device. * * The caller must prevent migration to another CPU, either by disabling * pre-emption or by running from a pinned kernel thread. * * Returns: MMIO pointer to device memory. The caller can read the ACSR * register to find more information about the device (such as the * version number or the number of blocks). * May return IOMEM_ERR_PTR(-errno) in case of error, so check with * IS_ERR(). */ void __iomem *mips_cdmm_early_probe(unsigned int dev_type) { struct mips_cdmm_bus *bus; void __iomem *cdmm; u32 acsr; unsigned int drb, type, size; int err; if (WARN_ON(!dev_type)) return IOMEM_ERR_PTR(-ENODEV); bus = mips_cdmm_get_bus(); err = mips_cdmm_setup(bus); if (err) return IOMEM_ERR_PTR(err); /* Skip the first block if it's reserved for more registers */ drb = bus->drbs_reserved; cdmm = bus->regs; /* Look for a specific device type */ for (; drb < bus->drbs; drb += size + 1) { acsr = readl(cdmm + drb * CDMM_DRB_SIZE); type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT; if (type == dev_type) return cdmm + drb * CDMM_DRB_SIZE; size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT; } return IOMEM_ERR_PTR(-ENODEV); }
/* * of_io_request_and_map - Requests a resource and maps the memory mapped IO * for a given device_node * @device: the device whose io range will be mapped * @index: index of the io range * @name: name of the resource * * Returns a pointer to the requested and mapped memory or an ERR_PTR() encoded * error code on failure. Usage example: * * base = of_io_request_and_map(node, 0, "foo"); * if (IS_ERR(base)) * return PTR_ERR(base); */ void __iomem *of_io_request_and_map(struct device_node *np, int index, const char *name) { struct resource res; void __iomem *mem; if (of_address_to_resource(np, index, &res)) return IOMEM_ERR_PTR(-EINVAL); if (!request_mem_region(res.start, resource_size(&res), name)) return IOMEM_ERR_PTR(-EBUSY); mem = ioremap(res.start, resource_size(&res)); if (!mem) { release_mem_region(res.start, resource_size(&res)); return IOMEM_ERR_PTR(-ENOMEM); } return mem; }
static void __iomem *qtnf_map_bar(struct qtnf_pcie_bus_priv *priv, u8 index) { void __iomem *vaddr; dma_addr_t busaddr; size_t len; int ret; ret = pcim_iomap_regions(priv->pdev, 1 << index, DRV_NAME); if (ret) return IOMEM_ERR_PTR(ret); busaddr = pci_resource_start(priv->pdev, index); len = pci_resource_len(priv->pdev, index); vaddr = pcim_iomap_table(priv->pdev)[index]; if (!vaddr) return IOMEM_ERR_PTR(-ENOMEM); pr_debug("BAR%u vaddr=0x%p busaddr=%pad len=%u\n", index, vaddr, &busaddr, (int)len); return vaddr; }
static void __iomem *bgpio_map(struct platform_device *pdev, const char *name, resource_size_t sane_sz) { struct resource *r; resource_size_t sz; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); if (!r) return NULL; sz = resource_size(r); if (sz != sane_sz) return IOMEM_ERR_PTR(-EINVAL); return devm_ioremap_resource(&pdev->dev, r); }