spi: omap2_mcspi rxdma bugfix
[safe/jmp/linux-2.6] / drivers / spi / omap_uwire.c
index 366af49..8980a56 100644 (file)
 
 #include <asm/system.h>
 #include <asm/irq.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
 #include <asm/io.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/mux.h>
-#include <asm/arch/omap730.h>  /* OMAP730_IO_CONF registers */
+#include <mach/mux.h>
+#include <mach/omap730.h>      /* OMAP730_IO_CONF registers */
 
 
 /* FIXME address is now a platform device resource,
  * and irqs should show there too...
  */
 #define UWIRE_BASE_PHYS                0xFFFB3000
-#define UWIRE_BASE             ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS))
 
 /* uWire Registers: */
 #define UWIRE_IO_SIZE 0x20
@@ -103,16 +102,21 @@ struct uwire_state {
 };
 
 /* REVISIT compile time constant for idx_shift? */
+/*
+ * Or, put it in a structure which is used throughout the driver;
+ * that avoids having to issue two loads for each bit of static data.
+ */
 static unsigned int uwire_idx_shift;
+static void __iomem *uwire_base;
 
 static inline void uwire_write_reg(int idx, u16 val)
 {
-       __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift));
+       __raw_writew(val, uwire_base + (idx << uwire_idx_shift));
 }
 
 static inline u16 uwire_read_reg(int idx)
 {
-       return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift));
+       return __raw_readw(uwire_base + (idx << uwire_idx_shift));
 }
 
 static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)
@@ -151,7 +155,7 @@ static int wait_uwire_csr_flag(u16 mask, u16 val, int might_not_catch)
                if (time_after(jiffies, max_jiffies)) {
                        printk(KERN_ERR "%s: timeout. reg=%#06x "
                                        "mask=%#06x val=%#06x\n",
-                              __FUNCTION__, w, mask, val);
+                              __func__, w, mask, val);
                        return -1;
                }
                c++;
@@ -241,7 +245,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
 
 #ifdef VERBOSE
                        pr_debug("%s: write-%d =%04x\n",
-                                       spi->dev.bus_id, bits, val);
+                                       dev_name(&spi->dev), bits, val);
 #endif
                        if (wait_uwire_csr_flag(CSRB, 0, 0))
                                goto eio;
@@ -301,7 +305,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
                        status += bytes;
 #ifdef VERBOSE
                        pr_debug("%s: read-%d =%04x\n",
-                                       spi->dev.bus_id, bits, val);
+                                       dev_name(&spi->dev), bits, val);
 #endif
 
                }
@@ -327,7 +331,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        uwire = spi_master_get_devdata(spi->master);
 
        if (spi->chip_select > 3) {
-               pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select);
+               pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select);
                status = -ENODEV;
                goto done;
        }
@@ -335,11 +339,9 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        bits = spi->bits_per_word;
        if (t != NULL && t->bits_per_word)
                bits = t->bits_per_word;
-       if (!bits)
-               bits = 8;
 
        if (bits > 16) {
-               pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits);
+               pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits);
                status = -ENODEV;
                goto done;
        }
@@ -358,11 +360,11 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
        case SPI_MODE_0:
        case SPI_MODE_3:
-               flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
+               flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
                break;
        case SPI_MODE_1:
        case SPI_MODE_2:
-               flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
+               flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
                break;
        }
 
@@ -374,7 +376,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
                hz = t->speed_hz;
 
        if (!hz) {
-               pr_debug("%s: zero speed?\n", spi->dev.bus_id);
+               pr_debug("%s: zero speed?\n", dev_name(&spi->dev));
                status = -EINVAL;
                goto done;
        }
@@ -402,7 +404,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        }
        if (div1_idx == 4) {
                pr_debug("%s: lowest clock %ld, need %d\n",
-                       spi->dev.bus_id, rate / 10 / 8, hz);
+                       dev_name(&spi->dev), rate / 10 / 8, hz);
                status = -EDOM;
                goto done;
        }
@@ -437,7 +439,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        }
        omap_uwire_configure_mode(spi->chip_select, flags);
        pr_debug("%s: uwire flags %02x, armxor %lu KHz, SCK %lu KHz\n",
-                       __FUNCTION__, flags,
+                       __func__, flags,
                        clk_get_rate(uwire->ck) / 1000,
                        rate / 1000);
        status = 0;
@@ -459,7 +461,7 @@ static int uwire_setup(struct spi_device *spi)
        return uwire_setup_transfer(spi, NULL);
 }
 
-static void uwire_cleanup(const struct spi_device *spi)
+static void uwire_cleanup(struct spi_device *spi)
 {
        kfree(spi->controller_state);
 }
@@ -472,7 +474,7 @@ static void uwire_off(struct uwire_spi *uwire)
        spi_master_put(uwire->bitbang.master);
 }
 
-static int uwire_probe(struct platform_device *pdev)
+static int __init uwire_probe(struct platform_device *pdev)
 {
        struct spi_master       *master;
        struct uwire_spi        *uwire;
@@ -483,13 +485,22 @@ static int uwire_probe(struct platform_device *pdev)
                return -ENODEV;
 
        uwire = spi_master_get_devdata(master);
+
+       uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE);
+       if (!uwire_base) {
+               dev_dbg(&pdev->dev, "can't ioremap UWIRE\n");
+               spi_master_put(master);
+               return -ENOMEM;
+       }
+
        dev_set_drvdata(&pdev->dev, uwire);
 
-       uwire->ck = clk_get(&pdev->dev, "armxor_ck");
-       if (!uwire->ck || IS_ERR(uwire->ck)) {
-               dev_dbg(&pdev->dev, "no mpu_xor_clk ?\n");
+       uwire->ck = clk_get(&pdev->dev, "fck");
+       if (IS_ERR(uwire->ck)) {
+               status = PTR_ERR(uwire->ck);
+               dev_dbg(&pdev->dev, "no functional clock?\n");
                spi_master_put(master);
-               return -ENODEV;
+               return status;
        }
        clk_enable(uwire->ck);
 
@@ -500,6 +511,11 @@ static int uwire_probe(struct platform_device *pdev)
 
        uwire_write_reg(UWIRE_SR3, 1);
 
+       /* the spi->mode bits understood by this driver: */
+       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+
+       master->flags = SPI_MASTER_HALF_DUPLEX;
+
        master->bus_num = 2;    /* "official" */
        master->num_chipselect = 4;
        master->setup = uwire_setup;
@@ -511,12 +527,14 @@ static int uwire_probe(struct platform_device *pdev)
        uwire->bitbang.txrx_bufs = uwire_txrx;
 
        status = spi_bitbang_start(&uwire->bitbang);
-       if (status < 0)
+       if (status < 0) {
                uwire_off(uwire);
+               iounmap(uwire_base);
+       }
        return status;
 }
 
-static int uwire_remove(struct platform_device *pdev)
+static int __exit uwire_remove(struct platform_device *pdev)
 {
        struct uwire_spi        *uwire = dev_get_drvdata(&pdev->dev);
        int                     status;
@@ -525,17 +543,19 @@ static int uwire_remove(struct platform_device *pdev)
 
        status = spi_bitbang_stop(&uwire->bitbang);
        uwire_off(uwire);
+       iounmap(uwire_base);
        return status;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:omap_uwire");
+
 static struct platform_driver uwire_driver = {
        .driver = {
                .name           = "omap_uwire",
-               .bus            = &platform_bus_type,
                .owner          = THIS_MODULE,
        },
-       .probe          = uwire_probe,
-       .remove         = uwire_remove,
+       .remove         = __exit_p(uwire_remove),
        // suspend ... unuse ck
        // resume ... use ck
 };
@@ -557,7 +577,7 @@ static int __init omap_uwire_init(void)
                omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
        }
 
-       return platform_driver_register(&uwire_driver);
+       return platform_driver_probe(&uwire_driver, uwire_probe);
 }
 
 static void __exit omap_uwire_exit(void)