#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
+#include <linux/io.h>
#include <asm/dma.h>
#include <asm/ecard.h>
#include <asm/hardware.h>
-#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/mach/irq.h>
}
EXPORT_SYMBOL(ecard_setirq);
+void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
+ unsigned long offset, unsigned long maxsize)
+{
+ unsigned long start = ecard_resource_start(ec, res);
+ unsigned long end = ecard_resource_end(ec, res);
+
+ if (offset > (end - start))
+ return NULL;
+
+ start += offset;
+ if (maxsize && end - start > maxsize)
+ end = start + maxsize;
+
+ return devm_ioremap(&ec->dev, start, end - start);
+}
+EXPORT_SYMBOL(ecardm_iomap);
+
/*
* Probe for an expansion card.
*
struct pata_icside_state *state = ae->private_data;
void __iomem *base;
- base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
- ecard_resource_len(ec, ECARD_RES_MEMC));
+ base = ecardm_iomap(info->ec, ECARD_RES_MEMC, 0, 0);
if (!base)
return -ENOMEM;
struct pata_icside_state *state = ae->private_data;
void __iomem *ioc_base, *easi_base;
unsigned int sel = 0;
- int ret;
- ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
- ecard_resource_len(ec, ECARD_RES_IOCFAST));
- if (!ioc_base) {
- ret = -ENOMEM;
- goto out;
- }
+ ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
+ if (!ioc_base)
+ return -ENOMEM;
easi_base = ioc_base;
if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
- easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI),
- ecard_resource_len(ec, ECARD_RES_EASI));
- if (!easi_base) {
- ret = -ENOMEM;
- goto unmap_slot;
- }
+ easi_base = ecardm_iomap(ec, ECARD_RES_EASI, 0, 0);
+ if (!easi_base)
+ return -ENOMEM;
/*
* Enable access to the EASI region.
return icside_dma_init(ae, ec);
- unmap_slot:
- iounmap(ioc_base);
- out:
- return ret;
}
static int __devinit
state->type = ICS_TYPE_NOTYPE;
state->dma = NO_DMA;
- idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
- ecard_resource_len(ec, ECARD_RES_IOCFAST));
+ idmem = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (idmem) {
unsigned int type;
type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1;
type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2;
type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3;
- iounmap(idmem);
+ ecardm_iounmap(ec, idmem);
state->type = type;
}
*/
if (state->dma != NO_DMA)
free_dma(state->dma);
- if (state->ioc_base)
- iounmap(state->ioc_base);
- if (state->ioc_base != state->irq_port)
- iounmap(state->irq_port);
kfree(state);
ecard_release_resources(ec);
ide_hwif_t *hwif;
void __iomem *base;
- base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
- ecard_resource_len(ec, ECARD_RES_MEMC));
+ base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!base)
return -ENOMEM;
icside_irqdisable_arcin_v5(ec, 0);
hwif = icside_setup(base, &icside_cardinfo_v5, ec);
- if (!hwif) {
- iounmap(base);
+ if (!hwif)
return -ENODEV;
- }
state->hwif[0] = hwif;
unsigned int sel = 0;
int ret;
- ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
- ecard_resource_len(ec, ECARD_RES_IOCFAST));
+ ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!ioc_base) {
ret = -ENOMEM;
goto out;
easi_base = ioc_base;
if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
- easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI),
- ecard_resource_len(ec, ECARD_RES_EASI));
+ easi_base = ecardm_iomap(ec, ECARD_RES_EASI, 0, 0);
if (!easi_base) {
ret = -ENOMEM;
- goto unmap_slot;
+ goto out;
}
/*
if (!hwif || !mate) {
ret = -ENODEV;
- goto unmap_port;
+ goto out;
}
state->hwif[0] = hwif;
return 0;
- unmap_port:
- if (easi_base != ioc_base)
- iounmap(easi_base);
- unmap_slot:
- iounmap(ioc_base);
out:
return ret;
}
state->type = ICS_TYPE_NOTYPE;
state->dev = &ec->dev;
- idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
- ecard_resource_len(ec, ECARD_RES_IOCFAST));
+ idmem = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (idmem) {
unsigned int type;
type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1;
type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2;
type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3;
- iounmap(idmem);
+ ecardm_iounmap(ec, idmem);
state->type = type;
}
ecard_set_drvdata(ec, NULL);
- if (state->ioc_base)
- iounmap(state->ioc_base);
- if (state->ioc_base != state->irq_port)
- iounmap(state->irq_port);
-
kfree(state);
ecard_release_resources(ec);
}
if (ret)
goto out;
- base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
- ecard_resource_len(ec, ECARD_RES_MEMC));
+ base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!base) {
ret = -ENOMEM;
goto release;
goto out;
}
- iounmap(base);
release:
ecard_release_resources(ec);
out:
/* there must be a better way */
ide_unregister(hwif - ide_hwifs);
- iounmap(hwif->hwif_data);
ecard_release_resources(ec);
}
SET_NETDEV_DEV(dev, &ec->dev);
dev->irq = ec->irq;
- priv(dev)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
- ecard_resource_len(ec, ECARD_RES_IOCFAST));
+ priv(dev)->base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!priv(dev)->base) {
ret = -ENOMEM;
goto free;
return 0;
free:
- if (priv(dev)->base)
- iounmap(priv(dev)->base);
free_netdev(dev);
release:
ecard_release_resources(ec);
ecard_set_drvdata(ec, NULL);
unregister_netdev(dev);
- iounmap(priv(dev)->base);
free_netdev(dev);
ecard_release_resources(ec);
}
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &ec->dev);
- priv(dev)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
- ecard_resource_len(ec, ECARD_RES_MEMC));
+ priv(dev)->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!priv(dev)->base) {
ret = -ENOMEM;
goto free;
return 0;
free:
- if (priv(dev)->base)
- iounmap(priv(dev)->base);
free_netdev(dev);
release:
ecard_release_resources(ec);
ecard_set_drvdata(ec, NULL);
unregister_netdev(dev);
- iounmap(priv(dev)->base);
free_netdev(dev);
ecard_release_resources(ec);
}
eh->supported = data->supported;
eh->ctrl = 0;
eh->id = ec->cid.product;
- eh->memc = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), PAGE_SIZE);
+ eh->memc = ecardm_iomap(ec, ECARD_RES_MEMC, 0, PAGE_SIZE);
if (!eh->memc) {
ret = -ENOMEM;
goto free;
eh->ctrl_port = eh->memc;
if (data->ctrl_ioc) {
- eh->ioc_fast = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), PAGE_SIZE);
+ eh->ioc_fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, PAGE_SIZE);
if (!eh->ioc_fast) {
ret = -ENOMEM;
goto free;
return 0;
free:
- if (eh->ioc_fast)
- iounmap(eh->ioc_fast);
- if (eh->memc)
- iounmap(eh->memc);
free_netdev(dev);
release:
ecard_release_resources(ec);
static void __devexit etherh_remove(struct expansion_card *ec)
{
struct net_device *dev = ecard_get_drvdata(ec);
- struct etherh_priv *eh = etherh_priv(dev);
ecard_set_drvdata(ec, NULL);
unregister_netdev(dev);
- if (eh->ioc_fast)
- iounmap(eh->ioc_fast);
- iounmap(eh->memc);
-
free_netdev(dev);
ecard_release_resources(ec);
{
struct Scsi_Host *host;
struct arxescsi_info *info;
- unsigned long resbase, reslen;
void __iomem *base;
int ret;
if (ret)
goto out;
- resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
- reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
- base = ioremap(resbase, reslen);
+ base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!base) {
ret = -ENOMEM;
goto out_region;
host = scsi_host_alloc(&arxescsi_template, sizeof(struct arxescsi_info));
if (!host) {
ret = -ENOMEM;
- goto out_unmap;
+ goto out_region;
}
info = (struct arxescsi_info *)host->hostdata;
fas216_release(host);
out_unregister:
scsi_host_put(host);
- out_unmap:
- iounmap(base);
out_region:
ecard_release_resources(ec);
out:
static void __devexit arxescsi_remove(struct expansion_card *ec)
{
struct Scsi_Host *host = ecard_get_drvdata(ec);
- struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata;
ecard_set_drvdata(ec, NULL);
fas216_remove(host);
- iounmap(info->base);
-
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
{
struct Scsi_Host *host;
struct cumanascsi2_info *info;
- unsigned long resbase, reslen;
void __iomem *base;
int ret;
if (ret)
goto out;
- resbase = ecard_resource_start(ec, ECARD_RES_MEMC);
- reslen = ecard_resource_len(ec, ECARD_RES_MEMC);
- base = ioremap(resbase, reslen);
+ base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!base) {
ret = -ENOMEM;
goto out_region;
sizeof(struct cumanascsi2_info));
if (!host) {
ret = -ENOMEM;
- goto out_unmap;
+ goto out_region;
}
ecard_set_drvdata(ec, host);
out_free:
scsi_host_put(host);
- out_unmap:
- iounmap(base);
-
out_region:
ecard_release_resources(ec);
free_dma(info->info.scsi.dma);
free_irq(ec->irq, info);
- iounmap(info->base);
-
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
{
struct Scsi_Host *host;
struct eesoxscsi_info *info;
- unsigned long resbase, reslen;
void __iomem *base;
int ret;
if (ret)
goto out;
- resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
- reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
- base = ioremap(resbase, reslen);
+ base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!base) {
ret = -ENOMEM;
goto out_region;
sizeof(struct eesoxscsi_info));
if (!host) {
ret = -ENOMEM;
- goto out_unmap;
+ goto out_region;
}
ecard_set_drvdata(ec, host);
device_remove_file(&ec->dev, &dev_attr_bus_term);
scsi_host_put(host);
- out_unmap:
- iounmap(base);
-
out_region:
ecard_release_resources(ec);
device_remove_file(&ec->dev, &dev_attr_bus_term);
- iounmap(info->base);
-
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
{
struct Scsi_Host *host;
struct powertec_info *info;
- unsigned long resbase, reslen;
void __iomem *base;
int ret;
if (ret)
goto out;
- resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
- reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
- base = ioremap(resbase, reslen);
+ base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!base) {
ret = -ENOMEM;
goto out_region;
sizeof (struct powertec_info));
if (!host) {
ret = -ENOMEM;
- goto out_unmap;
+ goto out_region;
}
ecard_set_drvdata(ec, host);
device_remove_file(&ec->dev, &dev_attr_bus_term);
scsi_host_put(host);
- out_unmap:
- iounmap(base);
-
out_region:
ecard_release_resources(ec);
free_dma(info->info.scsi.dma);
free_irq(ec->irq, info);
- iounmap(info->base);
-
fas216_release(host);
scsi_host_put(host);
ecard_release_resources(ec);
info->num_ports = type->num_ports;
bus_addr = ecard_resource_start(ec, type->type);
- info->vaddr = ioremap(bus_addr, ecard_resource_len(ec, type->type));
+ info->vaddr = ecardm_iomap(ec, type->type, 0, 0);
if (!info->vaddr) {
kfree(info);
return -ENOMEM;
if (info->ports[i] > 0)
serial8250_unregister_port(info->ports[i]);
- iounmap(info->vaddr);
kfree(info);
}
extern int ecard_request_resources(struct expansion_card *ec);
extern void ecard_release_resources(struct expansion_card *ec);
+void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
+ unsigned long offset, unsigned long maxsize);
+#define ecardm_iounmap(__ec, __addr) devm_iounmap(&(__ec)->dev, __addr)
+
extern struct bus_type ecard_bus_type;
#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)