sysfs: add struct file* to bin_attr callbacks
[safe/jmp/linux-2.6] / drivers / pcmcia / at91_cf.c
index 3bcb7dc..fb33fa4 100644 (file)
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 
 #include <pcmcia/ss.h>
 
-#include <asm/hardware.h>
+#include <mach/hardware.h>
 #include <asm/io.h>
 #include <asm/sizes.h>
+#include <asm/gpio.h>
 
-#include <asm/arch/at91rm9200.h>
-#include <asm/arch/board.h>
-#include <asm/arch/gpio.h>
+#include <mach/board.h>
+#include <mach/at91rm9200_mc.h>
 
 
 /*
  * A0..A10 work in each range; A23 indicates I/O space;  A25 is CFRNW;
  * some other bit in {A24,A22..A11} is nREG to flag memory access
  * (vs attributes).  So more than 2KB/region would just be waste.
+ * Note: These are offsets from the physical base address.
  */
-#define        CF_ATTR_PHYS    (AT91_CF_BASE)
-#define        CF_IO_PHYS      (AT91_CF_BASE  + (1 << 23))
-#define        CF_MEM_PHYS     (AT91_CF_BASE  + 0x017ff800)
+#define        CF_ATTR_PHYS    (0)
+#define        CF_IO_PHYS      (1 << 23)
+#define        CF_MEM_PHYS     (0x017ff800)
 
 /*--------------------------------------------------------------------------*/
 
@@ -48,13 +49,13 @@ struct at91_cf_socket {
 
        struct platform_device  *pdev;
        struct at91_cf_data     *board;
-};
 
-#define        SZ_2K                   (2 * SZ_1K)
+       unsigned long           phys_baseaddr;
+};
 
 static inline int at91_cf_present(struct at91_cf_socket *cf)
 {
-       return !at91_get_gpio_value(cf->board->det_pin);
+       return !gpio_get_value(cf->board->det_pin);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -98,9 +99,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
                int vcc = cf->board->vcc_pin;
 
                *sp = SS_DETECT | SS_3VCARD;
-               if (!rdy || at91_get_gpio_value(rdy))
+               if (!rdy || gpio_get_value(rdy))
                        *sp |= SS_READY;
-               if (!vcc || at91_get_gpio_value(vcc))
+               if (!vcc || gpio_get_value(vcc))
                        *sp |= SS_POWERON;
        } else
                *sp = 0;
@@ -119,10 +120,10 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
        if (cf->board->vcc_pin) {
                switch (s->Vcc) {
                        case 0:
-                               at91_set_gpio_value(cf->board->vcc_pin, 0);
+                               gpio_set_value(cf->board->vcc_pin, 0);
                                break;
                        case 33:
-                               at91_set_gpio_value(cf->board->vcc_pin, 1);
+                               gpio_set_value(cf->board->vcc_pin, 1);
                                break;
                        default:
                                return -EINVAL;
@@ -130,7 +131,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
        }
 
        /* toggle reset if needed */
-       at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET);
+       gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET);
 
        pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
                driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
@@ -154,9 +155,8 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
 
        /*
         * Use 16 bit accesses unless/until we need 8-bit i/o space.
-        * Always set CSR4 ... PCMCIA won't always unmap things.
         */
-       csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW;
+       csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW;
 
        /*
         * NOTE: this CF controller ignores IOIS16, so we can't really do
@@ -168,14 +168,14 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
         * some cards only like that way to get at the odd byte, despite
         * CF 3.0 spec table 35 also giving the D8-D15 option.
         */
-       if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) {
+       if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) {
                csr |= AT91_SMC_DBW_8;
                pr_debug("%s: 8bit i/o bus\n", driver_name);
        } else {
                csr |= AT91_SMC_DBW_16;
                pr_debug("%s: 16bit i/o bus\n", driver_name);
        }
-       at91_sys_write(AT91_SMC_CSR(4), csr);
+       at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr);
 
        io->start = cf->socket.io_offset;
        io->stop = io->start + SZ_2K - 1;
@@ -194,11 +194,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
 
        cf = container_of(s, struct at91_cf_socket, socket);
 
-       map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
+       map->flags &= (MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT);
        if (map->flags & MAP_ATTRIB)
-               map->static_start = CF_ATTR_PHYS;
+               map->static_start = cf->phys_baseaddr + CF_ATTR_PHYS;
        else
-               map->static_start = CF_MEM_PHYS;
+               map->static_start = cf->phys_baseaddr + CF_MEM_PHYS;
 
        return 0;
 }
@@ -219,7 +219,6 @@ static int __init at91_cf_probe(struct platform_device *pdev)
        struct at91_cf_socket   *cf;
        struct at91_cf_data     *board = pdev->dev.platform_data;
        struct resource         *io;
-       unsigned int            csa;
        int                     status;
 
        if (!board || !board->det_pin || !board->rst_pin)
@@ -229,43 +228,34 @@ static int __init at91_cf_probe(struct platform_device *pdev)
        if (!io)
                return -ENODEV;
 
-       cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
+       cf = kzalloc(sizeof *cf, GFP_KERNEL);
        if (!cf)
                return -ENOMEM;
 
        cf->board = board;
        cf->pdev = pdev;
+       cf->phys_baseaddr = io->start;
        platform_set_drvdata(pdev, cf);
 
-       /* CF takes over CS4, CS5, CS6 */
-       csa = at91_sys_read(AT91_EBI_CSA);
-       at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
-
-       /* nWAIT is _not_ a default setting */
-       (void) at91_set_A_periph(AT91_PIN_PC6, 1);      /*  nWAIT */
-
-       /*
-        * Static memory controller timing adjustments.
-        * REVISIT:  these timings are in terms of MCK cycles, so
-        * when MCK changes (cpufreq etc) so must these values...
-        */
-       at91_sys_write(AT91_SMC_CSR(4),
-                                 AT91_SMC_ACSS_STD
-                               | AT91_SMC_DBW_16
-                               | AT91_SMC_BAT
-                               | AT91_SMC_WSEN
-                               | AT91_SMC_NWS_(32)     /* wait states */
-                               | AT91_SMC_RWSETUP_(6)  /* setup time */
-                               | AT91_SMC_RWHOLD_(4)   /* hold time */
-       );
-
        /* must be a GPIO; ergo must trigger on both edges */
-       status = request_irq(board->det_pin, at91_cf_irq,
-                       IRQF_SAMPLE_RANDOM, driver_name, cf);
+       status = gpio_request(board->det_pin, "cf_det");
        if (status < 0)
                goto fail0;
+       status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
+       if (status < 0)
+               goto fail00;
        device_init_wakeup(&pdev->dev, 1);
 
+       status = gpio_request(board->rst_pin, "cf_rst");
+       if (status < 0)
+               goto fail0a;
+
+       if (board->vcc_pin) {
+               status = gpio_request(board->vcc_pin, "cf_vcc");
+               if (status < 0)
+                       goto fail0b;
+       }
+
        /*
         * The card driver will request this irq later as needed.
         * but it causes lots of "irqNN: nobody cared" messages
@@ -273,29 +263,37 @@ static int __init at91_cf_probe(struct platform_device *pdev)
         * (Note:  DK board doesn't wire the IRQ pin...)
         */
        if (board->irq_pin) {
+               status = gpio_request(board->irq_pin, "cf_irq");
+               if (status < 0)
+                       goto fail0c;
                status = request_irq(board->irq_pin, at91_cf_irq,
                                IRQF_SHARED, driver_name, cf);
                if (status < 0)
-                       goto fail0a;
+                       goto fail0d;
                cf->socket.pci_irq = board->irq_pin;
        } else
-               cf->socket.pci_irq = NR_IRQS + 1;
+               cf->socket.pci_irq = nr_irqs + 1;
 
        /* pcmcia layer only remaps "real" memory not iospace */
-       cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K);
-       if (!cf->socket.io_offset)
+       cf->socket.io_offset = (unsigned long)
+                       ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
+       if (!cf->socket.io_offset) {
+               status = -ENXIO;
                goto fail1;
+       }
 
-       /* reserve CS4, CS5, and CS6 regions; but use just CS4 */
+       /* reserve chip-select regions */
        if (!request_mem_region(io->start, io->end + 1 - io->start,
-                               driver_name))
+                               driver_name)) {
+               status = -ENXIO;
                goto fail1;
+       }
 
        pr_info("%s: irqs det #%d, io #%d\n", driver_name,
                board->det_pin, board->irq_pin);
 
        cf->socket.owner = THIS_MODULE;
-       cf->socket.dev.dev = &pdev->dev;
+       cf->socket.dev.parent = &pdev->dev;
        cf->socket.ops = &at91_cf_ops;
        cf->socket.resource_ops = &pccard_static_ops;
        cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
@@ -314,14 +312,22 @@ fail2:
 fail1:
        if (cf->socket.io_offset)
                iounmap((void __iomem *) cf->socket.io_offset);
-       if (board->irq_pin)
+       if (board->irq_pin) {
                free_irq(board->irq_pin, cf);
+fail0d:
+               gpio_free(board->irq_pin);
+       }
+fail0c:
+       if (board->vcc_pin)
+               gpio_free(board->vcc_pin);
+fail0b:
+       gpio_free(board->rst_pin);
 fail0a:
        device_init_wakeup(&pdev->dev, 0);
        free_irq(board->det_pin, cf);
-       device_init_wakeup(&pdev->dev, 0);
+fail00:
+       gpio_free(board->det_pin);
 fail0:
-       at91_sys_write(AT91_EBI_CSA, csa);
        kfree(cf);
        return status;
 }
@@ -331,19 +337,20 @@ static int __exit at91_cf_remove(struct platform_device *pdev)
        struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
        struct at91_cf_data     *board = cf->board;
        struct resource         *io = cf->socket.io[0].res;
-       unsigned int            csa;
 
        pcmcia_unregister_socket(&cf->socket);
-       if (board->irq_pin)
+       release_mem_region(io->start, io->end + 1 - io->start);
+       iounmap((void __iomem *) cf->socket.io_offset);
+       if (board->irq_pin) {
                free_irq(board->irq_pin, cf);
-       free_irq(board->det_pin, cf);
+               gpio_free(board->irq_pin);
+       }
+       if (board->vcc_pin)
+               gpio_free(board->vcc_pin);
+       gpio_free(board->rst_pin);
        device_init_wakeup(&pdev->dev, 0);
-       iounmap((void __iomem *) cf->socket.io_offset);
-       release_mem_region(io->start, io->end + 1 - io->start);
-
-       csa = at91_sys_read(AT91_EBI_CSA);
-       at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A);
-
+       free_irq(board->det_pin, cf);
+       gpio_free(board->det_pin);
        kfree(cf);
        return 0;
 }
@@ -355,22 +362,25 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
        struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
        struct at91_cf_data     *board = cf->board;
 
-       pcmcia_socket_dev_suspend(&pdev->dev, mesg);
        if (device_may_wakeup(&pdev->dev)) {
                enable_irq_wake(board->det_pin);
                if (board->irq_pin)
                        enable_irq_wake(board->irq_pin);
-       } else {
-               disable_irq_wake(board->det_pin);
-               if (board->irq_pin)
-                       disable_irq_wake(board->irq_pin);
        }
        return 0;
 }
 
 static int at91_cf_resume(struct platform_device *pdev)
 {
-       pcmcia_socket_dev_resume(&pdev->dev);
+       struct at91_cf_socket   *cf = platform_get_drvdata(pdev);
+       struct at91_cf_data     *board = cf->board;
+
+       if (device_may_wakeup(&pdev->dev)) {
+               disable_irq_wake(board->det_pin);
+               if (board->irq_pin)
+                       disable_irq_wake(board->irq_pin);
+       }
+
        return 0;
 }
 
@@ -384,7 +394,6 @@ static struct platform_driver at91_cf_driver = {
                .name           = (char *) driver_name,
                .owner          = THIS_MODULE,
        },
-       .probe          = at91_cf_probe,
        .remove         = __exit_p(at91_cf_remove),
        .suspend        = at91_cf_suspend,
        .resume         = at91_cf_resume,
@@ -394,7 +403,7 @@ static struct platform_driver at91_cf_driver = {
 
 static int __init at91_cf_init(void)
 {
-       return platform_driver_register(&at91_cf_driver);
+       return platform_driver_probe(&at91_cf_driver, at91_cf_probe);
 }
 module_init(at91_cf_init);
 
@@ -407,3 +416,4 @@ module_exit(at91_cf_exit);
 MODULE_DESCRIPTION("AT91 Compact Flash Driver");
 MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_cf");