Merge branch 'mxc-pu-imxfb' of git://pasiphae.extern.pengutronix.de/git/imx/linux...
[safe/jmp/linux-2.6] / drivers / pcmcia / soc_common.c
index 888b70e..f49ac66 100644 (file)
 ======================================================================*/
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
+#include <linux/mutex.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/spinlock.h>
 #include <linux/cpufreq.h>
 
-#include <asm/hardware.h>
+#include <mach/hardware.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/system.h>
 
 #include "soc_common.h"
 
 /* FIXME: platform dependent resource declaration has to move out of this file */
 #ifdef CONFIG_ARCH_PXA
-#include <asm/arch/pxa-regs.h>
+#include <mach/pxa-regs.h>
 #endif
 
-#ifdef DEBUG
+#ifdef CONFIG_PCMCIA_DEBUG
 
 static int pc_debug;
 module_param(pc_debug, int, 0644);
@@ -66,7 +66,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
        if (pc_debug > lvl) {
                printk(KERN_DEBUG "skt%u: %s: ", skt->nr, func);
                va_start(args, fmt);
-               printk(fmt, args);
+               vprintk(fmt, args);
                va_end(args);
        }
 }
@@ -149,10 +149,10 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat
                 */
                if (skt->irq_state != 1 && state->io_irq) {
                        skt->irq_state = 1;
-                       set_irq_type(skt->irq, IRQT_FALLING);
+                       set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING);
                } else if (skt->irq_state == 1 && state->io_irq == 0) {
                        skt->irq_state = 0;
-                       set_irq_type(skt->irq, IRQT_NOEDGE);
+                       set_irq_type(skt->irq, IRQ_TYPE_NONE);
                }
 
                skt->cs_state = *state;
@@ -257,7 +257,7 @@ static void soc_common_pcmcia_poll_event(unsigned long dummy)
  * handling code performs scheduling operations which cannot be
  * executed from within an interrupt context.
  */
-static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev)
 {
        struct soc_pcmcia_socket *skt = dev;
 
@@ -297,32 +297,11 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
 
 
 /*
- * Implements the get_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_GetSocket in Card Services). Not a very
- * exciting routine.
- *
- * Returns: 0
- */
-static int
-soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-       struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
-
-       debug(skt, 2, "\n");
-
-       *state = skt->cs_state;
-
-       return 0;
-}
-
-/*
  * Implements the set_socket() operation for the in-kernel PCMCIA
  * service (formerly SS_SetSocket in Card Services). We more or
  * less punt all of this work and let the kernel handle the details
  * of power configuration, reset, &c. We also record the value of
  * `state' in order to regurgitate it to the PCMCIA core later.
- *
- * Returns: 0
  */
 static int
 soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
@@ -375,7 +354,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
                (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
 
        if (map->map >= MAX_IO_WIN) {
-               printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
+               printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
                       map->map);
                return -1;
        }
@@ -407,7 +386,7 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
  * the map speed as requested, but override the address ranges
  * supplied by Card Services.
  *
- * Returns: 0 on success, -1 on error
+ * Returns: 0 on success, -ERRNO on error
  */
 static int
 soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
@@ -500,10 +479,10 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
  *
  * Returns: the number of characters added to the buffer
  */
-static ssize_t show_status(struct class_device *class_dev, char *buf)
+static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct soc_pcmcia_socket *skt =
-               container_of(class_dev, struct soc_pcmcia_socket, socket.dev);
+               container_of(dev, struct soc_pcmcia_socket, socket.dev);
        char *p = buf;
 
        p+=sprintf(p, "slot     : %d\n", skt->nr);
@@ -523,14 +502,13 @@ static ssize_t show_status(struct class_device *class_dev, char *buf)
 
        return p-buf;
 }
-static CLASS_DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 
 
 static struct pccard_operations soc_common_pcmcia_operations = {
        .init                   = soc_common_pcmcia_sock_init,
        .suspend                = soc_common_pcmcia_suspend,
        .get_status             = soc_common_pcmcia_get_status,
-       .get_socket             = soc_common_pcmcia_get_socket,
        .set_socket             = soc_common_pcmcia_set_socket,
        .set_io_map             = soc_common_pcmcia_set_io_map,
        .set_mem_map            = soc_common_pcmcia_set_mem_map,
@@ -546,10 +524,10 @@ int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
                if (irqs[i].sock != skt->nr)
                        continue;
                res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
-                                 SA_INTERRUPT, irqs[i].str, skt);
+                                 IRQF_DISABLED, irqs[i].str, skt);
                if (res)
                        break;
-               set_irq_type(irqs[i].irq, IRQT_NOEDGE);
+               set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
        }
 
        if (res) {
@@ -582,7 +560,7 @@ void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
 
        for (i = 0; i < nr; i++)
                if (irqs[i].sock == skt->nr)
-                       set_irq_type(irqs[i].irq, IRQT_NOEDGE);
+                       set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
 }
 EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
 
@@ -593,15 +571,15 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
 
        for (i = 0; i < nr; i++)
                if (irqs[i].sock == skt->nr) {
-                       set_irq_type(irqs[i].irq, IRQT_RISING);
-                       set_irq_type(irqs[i].irq, IRQT_BOTHEDGE);
+                       set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
+                       set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
                }
 }
 EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
 
 
 LIST_HEAD(soc_pcmcia_sockets);
-DECLARE_MUTEX(soc_pcmcia_sockets_lock);
+static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
 static const char *skt_names[] = {
        "PCMCIA socket 0",
@@ -624,11 +602,11 @@ soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
        struct cpufreq_freqs *freqs = data;
        int ret = 0;
 
-       down(&soc_pcmcia_sockets_lock);
+       mutex_lock(&soc_pcmcia_sockets_lock);
        list_for_each_entry(skt, &soc_pcmcia_sockets, node)
                if ( skt->ops->frequency_change )
                        ret += skt->ops->frequency_change(skt, val, freqs);
-       up(&soc_pcmcia_sockets_lock);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
 
        return ret;
 }
@@ -655,8 +633,8 @@ static void soc_pcmcia_cpufreq_unregister(void)
 }
 
 #else
-#define soc_pcmcia_cpufreq_register()
-#define soc_pcmcia_cpufreq_unregister()
+static int soc_pcmcia_cpufreq_register(void) { return 0; }
+static void soc_pcmcia_cpufreq_unregister(void) {}
 #endif
 
 int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
@@ -665,15 +643,14 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
        struct soc_pcmcia_socket *skt;
        int ret, i;
 
-       down(&soc_pcmcia_sockets_lock);
+       mutex_lock(&soc_pcmcia_sockets_lock);
 
-       sinfo = kmalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
+       sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
        if (!sinfo) {
                ret = -ENOMEM;
                goto out;
        }
 
-       memset(sinfo, 0, SKT_DEV_INFO_SIZE(nr));
        sinfo->nskt = nr;
 
        /*
@@ -684,7 +661,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
                skt->socket.ops = &soc_common_pcmcia_operations;
                skt->socket.owner = ops->owner;
-               skt->socket.dev.dev = dev;
+               skt->socket.dev.parent = dev;
 
                init_timer(&skt->poll_timer);
                skt->poll_timer.function = soc_common_pcmcia_poll_event;
@@ -738,7 +715,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
                        goto out_err_5;
                }
 
-               if ( list_empty(&soc_pcmcia_sockets) )
+               if (list_empty(&soc_pcmcia_sockets))
                        soc_pcmcia_cpufreq_register();
 
                list_add(&skt->node, &soc_pcmcia_sockets);
@@ -771,7 +748,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
                add_timer(&skt->poll_timer);
 
-               class_device_create_file(&skt->socket.dev, &class_device_attr_status);
+               ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+               if (ret)
+                       goto out_err_8;
        }
 
        dev_set_drvdata(dev, sinfo);
@@ -781,6 +760,8 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
        do {
                skt = &sinfo->skt[i];
 
+               device_remove_file(&skt->socket.dev, &dev_attr_status);
+ out_err_8:
                del_timer_sync(&skt->poll_timer);
                pcmcia_unregister_socket(&skt->socket);
 
@@ -806,7 +787,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
        kfree(sinfo);
 
  out:
-       up(&soc_pcmcia_sockets_lock);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
        return ret;
 }
 
@@ -817,7 +798,7 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
 
        dev_set_drvdata(dev, NULL);
 
-       down(&soc_pcmcia_sockets_lock);
+       mutex_lock(&soc_pcmcia_sockets_lock);
        for (i = 0; i < sinfo->nskt; i++) {
                struct soc_pcmcia_socket *skt = &sinfo->skt[i];
 
@@ -839,12 +820,13 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
                release_resource(&skt->res_io);
                release_resource(&skt->res_skt);
        }
-       if ( list_empty(&soc_pcmcia_sockets) )
+       if (list_empty(&soc_pcmcia_sockets))
                soc_pcmcia_cpufreq_unregister();
 
-       up(&soc_pcmcia_sockets_lock);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
 
        kfree(sinfo);
 
        return 0;
 }
+EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);