summaryrefslogtreecommitdiff
path: root/drivers/pcmcia/omap_cf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/omap_cf.c')
-rw-r--r--drivers/pcmcia/omap_cf.c96
1 files changed, 37 insertions, 59 deletions
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 25c4b1993b3d..d6f24c7d1562 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* omap_cf.c -- OMAP 16xx CompactFlash controller driver
*
* Copyright (c) 2005 David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
#include <linux/module.h>
@@ -20,13 +16,12 @@
#include <pcmcia/ss.h>
-#include <mach/hardware.h>
#include <asm/io.h>
-#include <asm/sizes.h>
-
-#include <mach/mux.h>
-#include <mach/tc.h>
+#include <linux/sizes.h>
+#include <linux/soc/ti/omap1-io.h>
+#include <linux/soc/ti/omap1-soc.h>
+#include <linux/soc/ti/omap1-mux.h>
/* NOTE: don't expect this to support many I/O cards. The 16xx chips have
* hard-wired timings to support Compact Flash memory cards; they won't work
@@ -80,9 +75,9 @@ static int omap_cf_ss_init(struct pcmcia_socket *s)
}
/* the timer is primarily to kick this socket's pccardd */
-static void omap_cf_timer(unsigned long _cf)
+static void omap_cf_timer(struct timer_list *t)
{
- struct omap_cf_socket *cf = (void *) _cf;
+ struct omap_cf_socket *cf = timer_container_of(cf, t, timer);
unsigned present = omap_cf_present();
if (present != cf->present) {
@@ -102,7 +97,9 @@ static void omap_cf_timer(unsigned long _cf)
*/
static irqreturn_t omap_cf_irq(int irq, void *_cf)
{
- omap_cf_timer((unsigned long)_cf);
+ struct omap_cf_socket *cf = (struct omap_cf_socket *)_cf;
+
+ omap_cf_timer(&cf->timer);
return IRQ_HANDLED;
}
@@ -127,8 +124,6 @@ static int omap_cf_get_status(struct pcmcia_socket *s, u_int *sp)
static int
omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
{
- u16 control;
-
/* REVISIT some non-OSK boards may support power switching */
switch (s->Vcc) {
case 0:
@@ -138,7 +133,7 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
return -EINVAL;
}
- control = omap_readw(CF_CONTROL);
+ omap_readw(CF_CONTROL);
if (s->flags & SS_RESET)
omap_writew(CF_CONTROL_RESET, CF_CONTROL);
else
@@ -207,6 +202,8 @@ static int __init omap_cf_probe(struct platform_device *pdev)
struct omap_cf_socket *cf;
int irq;
int status;
+ struct resource *res;
+ struct resource iospace = DEFINE_RES_IO(SZ_64, SZ_4K);
seg = (int) pdev->dev.platform_data;
if (seg == 0 || seg > 3)
@@ -217,12 +214,14 @@ static int __init omap_cf_probe(struct platform_device *pdev)
if (irq < 0)
return -EINVAL;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+
cf = kzalloc(sizeof *cf, GFP_KERNEL);
if (!cf)
return -ENOMEM;
- init_timer(&cf->timer);
- cf->timer.function = omap_cf_timer;
- cf->timer.data = (unsigned long) cf;
+ timer_setup(&cf->timer, omap_cf_timer, 0);
cf->pdev = pdev;
platform_set_drvdata(pdev, cf);
@@ -234,33 +233,20 @@ static int __init omap_cf_probe(struct platform_device *pdev)
goto fail0;
cf->irq = irq;
cf->socket.pci_irq = irq;
-
- switch (seg) {
- /* NOTE: CS0 could be configured too ... */
- case 1:
- cf->phys_cf = OMAP_CS1_PHYS;
- break;
- case 2:
- cf->phys_cf = OMAP_CS2_PHYS;
- break;
- case 3:
- cf->phys_cf = omap_cs3_phys();
- break;
- default:
- goto fail1;
- }
- cf->iomem.start = cf->phys_cf;
- cf->iomem.end = cf->iomem.end + SZ_8K - 1;
- cf->iomem.flags = IORESOURCE_MEM;
+ cf->phys_cf = res->start;
/* pcmcia layer only remaps "real" memory */
- cf->socket.io_offset = (unsigned long)
- ioremap(cf->phys_cf + SZ_4K, SZ_2K);
- if (!cf->socket.io_offset)
+ cf->socket.io_offset = iospace.start;
+ status = pci_remap_iospace(&iospace, cf->phys_cf + SZ_4K);
+ if (status) {
+ status = -ENOMEM;
goto fail1;
+ }
- if (!request_mem_region(cf->phys_cf, SZ_8K, driver_name))
+ if (!request_mem_region(cf->phys_cf, SZ_8K, driver_name)) {
+ status = -ENXIO;
goto fail1;
+ }
/* NOTE: CF conflicts with MMC1 */
omap_cfg_reg(W11_1610_CF_CD1);
@@ -273,15 +259,6 @@ static int __init omap_cf_probe(struct platform_device *pdev)
pr_info("%s: cs%d on irq %d\n", driver_name, seg, irq);
- /* NOTE: better EMIFS setup might support more cards; but the
- * TRM only shows how to affect regular flash signals, not their
- * CF/PCMCIA variants...
- */
- pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", driver_name,
- seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg)));
- omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */
- omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */
-
/* CF uses armxor_ck, which is "always" available */
pr_debug("%s: sts %04x cfg %04x control %04x %s\n", driver_name,
@@ -309,32 +286,33 @@ static int __init omap_cf_probe(struct platform_device *pdev)
fail2:
release_mem_region(cf->phys_cf, SZ_8K);
fail1:
- if (cf->socket.io_offset)
- iounmap((void __iomem *) cf->socket.io_offset);
free_irq(irq, cf);
fail0:
kfree(cf);
return status;
}
-static int __exit omap_cf_remove(struct platform_device *pdev)
+static void __exit omap_cf_remove(struct platform_device *pdev)
{
struct omap_cf_socket *cf = platform_get_drvdata(pdev);
cf->active = 0;
pcmcia_unregister_socket(&cf->socket);
- del_timer_sync(&cf->timer);
- iounmap((void __iomem *) cf->socket.io_offset);
+ timer_shutdown_sync(&cf->timer);
release_mem_region(cf->phys_cf, SZ_8K);
free_irq(cf->irq, cf);
kfree(cf);
- return 0;
}
-static struct platform_driver omap_cf_driver = {
+/*
+ * omap_cf_remove() lives in .exit.text. For drivers registered via
+ * platform_driver_probe() this is ok because they cannot get unbound at
+ * runtime. So mark the driver struct with __refdata to prevent modpost
+ * triggering a section mismatch warning.
+ */
+static struct platform_driver omap_cf_driver __refdata = {
.driver = {
- .name = (char *) driver_name,
- .owner = THIS_MODULE,
+ .name = driver_name,
},
.remove = __exit_p(omap_cf_remove),
};