Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=eaf5f925a31973e2fdc50c785665b90ff444eceb
Commit:     eaf5f925a31973e2fdc50c785665b90ff444eceb
Parent:     2042c1c4e7a5e3b69ff3c3c5db6bf6416abd8b24
Author:     Haavard Skinnemoen <[EMAIL PROTECTED]>
AuthorDate: Mon Oct 22 18:32:14 2007 +0200
Committer:  Haavard Skinnemoen <[EMAIL PROTECTED]>
CommitDate: Tue Oct 23 11:20:05 2007 +0200

    [AVR32] Implement at32_add_device_cf()
    
    Implement at32_add_device_cf() which will add a platform_device for
    the at32_cf driver (not merged yet). Separate out most of the
    at32_add_device_ide() code and use it to implement
    at32_add_device_cf() as well.
    
    This changes the API in the following ways:
      * The board code must initialize data->cs to the chipselect ID to
        use before calling any of these functions.
      * The board code must use GPIO_PIN_NONE to indicate unused CF pins.
    
    Signed-off-by: Haavard Skinnemoen <[EMAIL PROTECTED]>
---
 arch/avr32/mach-at32ap/at32ap7000.c   |  133 +++++++++++++++++++++++++--------
 include/asm-avr32/arch-at32ap/board.h |   11 +++
 2 files changed, 113 insertions(+), 31 deletions(-)

diff --git a/arch/avr32/mach-at32ap/at32ap7000.c 
b/arch/avr32/mach-at32ap/at32ap7000.c
index d152504..a9d9ec0 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -1330,10 +1330,9 @@ out_free_pdev:
 }
 
 /* --------------------------------------------------------------------
- * IDE
+ * IDE / CompactFlash
  * -------------------------------------------------------------------- */
-static struct ide_platform_data at32_ide0_data;
-static struct resource at32_ide0_resource[] = {
+static struct resource at32_smc_cs4_resource[] __initdata = {
        {
                .start  = 0x04000000,
                .end    = 0x07ffffff,
@@ -1341,45 +1340,63 @@ static struct resource at32_ide0_resource[] = {
        },
        IRQ(~0UL), /* Magic IRQ will be overridden */
 };
-DEFINE_DEV_DATA(at32_ide, 0);
+static struct resource at32_smc_cs5_resource[] __initdata = {
+       {
+               .start  = 0x20000000,
+               .end    = 0x23ffffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(~0UL), /* Magic IRQ will be overridden */
+};
 
-struct platform_device *__init
-at32_add_device_ide(unsigned int id, unsigned int extint,
-                   struct ide_platform_data *data)
+static int __init at32_init_ide_or_cf(struct platform_device *pdev,
+               unsigned int cs, unsigned int extint)
 {
-       struct platform_device *pdev;
+       static unsigned int extint_pin_map[4] __initdata = {
+               GPIO_PIN_PB(25),
+               GPIO_PIN_PB(26),
+               GPIO_PIN_PB(27),
+               GPIO_PIN_PB(28),
+       };
+       static bool common_pins_initialized __initdata = false;
        unsigned int extint_pin;
+       int ret;
 
-       switch (extint) {
-       case 0:
-               extint_pin = GPIO_PIN_PB(25);
-               break;
-       case 1:
-               extint_pin = GPIO_PIN_PB(26);
-               break;
-       case 2:
-               extint_pin = GPIO_PIN_PB(27);
+       if (extint >= ARRAY_SIZE(extint_pin_map))
+               return -EINVAL;
+       extint_pin = extint_pin_map[extint];
+
+       switch (cs) {
+       case 4:
+               ret = platform_device_add_resources(pdev,
+                               at32_smc_cs4_resource,
+                               ARRAY_SIZE(at32_smc_cs4_resource));
+               if (ret)
+                       return ret;
+
+               select_peripheral(PE(21), PERIPH_A, 0); /* NCS4   -> OE_N  */
+               set_ebi_sfr_bits(HMATRIX_BIT(CS4A));
                break;
-       case 3:
-               extint_pin = GPIO_PIN_PB(28);
+       case 5:
+               ret = platform_device_add_resources(pdev,
+                               at32_smc_cs5_resource,
+                               ARRAY_SIZE(at32_smc_cs5_resource));
+               if (ret)
+                       return ret;
+
+               select_peripheral(PE(22), PERIPH_A, 0); /* NCS5   -> OE_N  */
+               set_ebi_sfr_bits(HMATRIX_BIT(CS5A));
                break;
        default:
-               return NULL;
+               return -EINVAL;
        }
 
-       switch (id) {
-       case 0:
-               pdev = &at32_ide0_device;
+       if (!common_pins_initialized) {
                select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1  -> CS0_N */
                select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2  -> CS1_N */
-               select_peripheral(PE(21), PERIPH_A, 0); /* NCS4   -> OE_N  */
                select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW  -> DIR   */
                select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT  <- IORDY */
-               set_ebi_sfr_bits(HMATRIX_BIT(CS4A));
-               data->cs = 4;
-               break;
-       default:
-               return NULL;
+               common_pins_initialized = true;
        }
 
        at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
@@ -1387,11 +1404,65 @@ at32_add_device_ide(unsigned int id, unsigned int 
extint,
        pdev->resource[1].start = EIM_IRQ_BASE + extint;
        pdev->resource[1].end = pdev->resource[1].start;
 
-       memcpy(pdev->dev.platform_data, data, sizeof(struct ide_platform_data));
+       return 0;
+}
 
-       platform_device_register(pdev);
+struct platform_device *__init
+at32_add_device_ide(unsigned int id, unsigned int extint,
+                   struct ide_platform_data *data)
+{
+       struct platform_device *pdev;
+
+       pdev = platform_device_alloc("at32_ide", id);
+       if (!pdev)
+               goto fail;
+
+       if (platform_device_add_data(pdev, data,
+                               sizeof(struct ide_platform_data)))
+               goto fail;
+
+       if (at32_init_ide_or_cf(pdev, data->cs, extint))
+               goto fail;
+
+       platform_device_add(pdev);
+       return pdev;
+
+fail:
+       platform_device_put(pdev);
+       return NULL;
+}
+
+struct platform_device *__init
+at32_add_device_cf(unsigned int id, unsigned int extint,
+                   struct cf_platform_data *data)
+{
+       struct platform_device *pdev;
+
+       pdev = platform_device_alloc("at32_cf", id);
+       if (!pdev)
+               goto fail;
 
+       if (platform_device_add_data(pdev, data,
+                               sizeof(struct cf_platform_data)))
+               goto fail;
+
+       if (at32_init_ide_or_cf(pdev, data->cs, extint))
+               goto fail;
+
+       if (data->detect_pin != GPIO_PIN_NONE)
+               at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH);
+       if (data->reset_pin != GPIO_PIN_NONE)
+               at32_select_gpio(data->reset_pin, 0);
+       if (data->vcc_pin != GPIO_PIN_NONE)
+               at32_select_gpio(data->vcc_pin, 0);
+       /* READY is used as extint, so we can't select it as gpio */
+
+       platform_device_add(pdev);
        return pdev;
+
+fail:
+       platform_device_put(pdev);
+       return NULL;
 }
 
 /* --------------------------------------------------------------------
diff --git a/include/asm-avr32/arch-at32ap/board.h 
b/include/asm-avr32/arch-at32ap/board.h
index 946378a..d6993a6 100644
--- a/include/asm-avr32/arch-at32ap/board.h
+++ b/include/asm-avr32/arch-at32ap/board.h
@@ -70,4 +70,15 @@ struct platform_device *at32_add_device_mci(unsigned int id);
 struct platform_device *at32_add_device_ac97c(unsigned int id);
 struct platform_device *at32_add_device_abdac(unsigned int id);
 
+struct cf_platform_data {
+       int     detect_pin;
+       int     reset_pin;
+       int     vcc_pin;
+       int     ready_pin;
+       u8      cs;
+};
+struct platform_device *
+at32_add_device_cf(unsigned int id, unsigned int extint,
+               struct cf_platform_data *data);
+
 #endif /* __ASM_ARCH_BOARD_H */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to