Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[pandora-kernel.git] / arch / arm / mach-at91 / at91sam9260_devices.c
index ee4ea0e..1fdeb90 100644 (file)
@@ -278,6 +278,102 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  MMC / SD Slot for Atmel MCI Driver
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct mci_platform_data mmc_data;
+
+static struct resource mmc_resources[] = {
+       [0] = {
+               .start  = AT91SAM9260_BASE_MCI,
+               .end    = AT91SAM9260_BASE_MCI + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9260_ID_MCI,
+               .end    = AT91SAM9260_ID_MCI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9260_mmc_device = {
+       .name           = "atmel_mci",
+       .id             = -1,
+       .dev            = {
+                               .dma_mask               = &mmc_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &mmc_data,
+       },
+       .resource       = mmc_resources,
+       .num_resources  = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
+{
+       unsigned int i;
+       unsigned int slot_count = 0;
+
+       if (!data)
+               return;
+
+       for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+               if (data->slot[i].bus_width) {
+                       /* input/irq */
+                       if (data->slot[i].detect_pin) {
+                               at91_set_gpio_input(data->slot[i].detect_pin, 1);
+                               at91_set_deglitch(data->slot[i].detect_pin, 1);
+                       }
+                       if (data->slot[i].wp_pin)
+                               at91_set_gpio_input(data->slot[i].wp_pin, 1);
+
+                       switch (i) {
+                       case 0:
+                               /* CMD */
+                               at91_set_A_periph(AT91_PIN_PA7, 1);
+                               /* DAT0, maybe DAT1..DAT3 */
+                               at91_set_A_periph(AT91_PIN_PA6, 1);
+                               if (data->slot[i].bus_width == 4) {
+                                       at91_set_A_periph(AT91_PIN_PA9, 1);
+                                       at91_set_A_periph(AT91_PIN_PA10, 1);
+                                       at91_set_A_periph(AT91_PIN_PA11, 1);
+                               }
+                               slot_count++;
+                               break;
+                       case 1:
+                               /* CMD */
+                               at91_set_B_periph(AT91_PIN_PA1, 1);
+                               /* DAT0, maybe DAT1..DAT3 */
+                               at91_set_B_periph(AT91_PIN_PA0, 1);
+                               if (data->slot[i].bus_width == 4) {
+                                       at91_set_B_periph(AT91_PIN_PA5, 1);
+                                       at91_set_B_periph(AT91_PIN_PA4, 1);
+                                       at91_set_B_periph(AT91_PIN_PA3, 1);
+                               }
+                               slot_count++;
+                               break;
+                       default:
+                               printk(KERN_ERR
+                                       "AT91: SD/MMC slot %d not available\n", i);
+                               break;
+                       }
+               }
+       }
+
+       if (slot_count) {
+               /* CLK */
+               at91_set_A_periph(AT91_PIN_PA8, 0);
+
+               mmc_data = *data;
+               platform_device_register(&at91sam9260_mmc_device);
+       }
+}
+#else
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
+#endif
+
 
 /* --------------------------------------------------------------------
  *  NAND / SmartMedia
@@ -513,7 +609,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
                at91_set_A_periph(AT91_PIN_PA1, 0);     /* SPI0_MOSI */
                at91_set_A_periph(AT91_PIN_PA2, 0);     /* SPI1_SPCK */
 
-               at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk");
                platform_device_register(&at91sam9260_spi0_device);
        }
        if (enable_spi1) {
@@ -521,7 +616,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
                at91_set_A_periph(AT91_PIN_PB1, 0);     /* SPI1_MOSI */
                at91_set_A_periph(AT91_PIN_PB2, 0);     /* SPI1_SPCK */
 
-               at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk");
                platform_device_register(&at91sam9260_spi1_device);
        }
 }
@@ -598,15 +692,7 @@ static struct platform_device at91sam9260_tcb1_device = {
 
 static void __init at91_add_device_tc(void)
 {
-       /* this chip has a separate clock and irq for each TC channel */
-       at91_clock_associate("tc0_clk", &at91sam9260_tcb0_device.dev, "t0_clk");
-       at91_clock_associate("tc1_clk", &at91sam9260_tcb0_device.dev, "t1_clk");
-       at91_clock_associate("tc2_clk", &at91sam9260_tcb0_device.dev, "t2_clk");
        platform_device_register(&at91sam9260_tcb0_device);
-
-       at91_clock_associate("tc3_clk", &at91sam9260_tcb1_device.dev, "t0_clk");
-       at91_clock_associate("tc4_clk", &at91sam9260_tcb1_device.dev, "t1_clk");
-       at91_clock_associate("tc5_clk", &at91sam9260_tcb1_device.dev, "t2_clk");
        platform_device_register(&at91sam9260_tcb1_device);
 }
 #else
@@ -724,7 +810,6 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins)
        case AT91SAM9260_ID_SSC:
                pdev = &at91sam9260_ssc_device;
                configure_ssc_pins(pins);
-               at91_clock_associate("ssc_clk", &pdev->dev, "pclk");
                break;
        default:
                return;
@@ -1043,47 +1128,42 @@ struct platform_device *atmel_default_console_device;   /* the serial console devi
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
        struct platform_device *pdev;
+       struct atmel_uart_data *pdata;
 
        switch (id) {
                case 0:         /* DBGU */
                        pdev = &at91sam9260_dbgu_device;
                        configure_dbgu_pins();
-                       at91_clock_associate("mck", &pdev->dev, "usart");
                        break;
                case AT91SAM9260_ID_US0:
                        pdev = &at91sam9260_uart0_device;
                        configure_usart0_pins(pins);
-                       at91_clock_associate("usart0_clk", &pdev->dev, "usart");
                        break;
                case AT91SAM9260_ID_US1:
                        pdev = &at91sam9260_uart1_device;
                        configure_usart1_pins(pins);
-                       at91_clock_associate("usart1_clk", &pdev->dev, "usart");
                        break;
                case AT91SAM9260_ID_US2:
                        pdev = &at91sam9260_uart2_device;
                        configure_usart2_pins(pins);
-                       at91_clock_associate("usart2_clk", &pdev->dev, "usart");
                        break;
                case AT91SAM9260_ID_US3:
                        pdev = &at91sam9260_uart3_device;
                        configure_usart3_pins(pins);
-                       at91_clock_associate("usart3_clk", &pdev->dev, "usart");
                        break;
                case AT91SAM9260_ID_US4:
                        pdev = &at91sam9260_uart4_device;
                        configure_usart4_pins();
-                       at91_clock_associate("usart4_clk", &pdev->dev, "usart");
                        break;
                case AT91SAM9260_ID_US5:
                        pdev = &at91sam9260_uart5_device;
                        configure_usart5_pins();
-                       at91_clock_associate("usart5_clk", &pdev->dev, "usart");
                        break;
                default:
                        return;
        }
-       pdev->id = portnr;              /* update to mapped ID */
+       pdata = pdev->dev.platform_data;
+       pdata->num = portnr;            /* update to mapped ID */
 
        if (portnr < ATMEL_MAX_UART)
                at91_uarts[portnr] = pdev;
@@ -1091,8 +1171,10 @@ void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-       if (portnr < ATMEL_MAX_UART)
+       if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
+               at91sam9260_set_console_clock(portnr);
+       }
 }
 
 void __init at91_add_device_serial(void)