Merge branch 'msm-core' into for-next
authorDavid Brown <davidb@codeaurora.org>
Fri, 28 Jan 2011 20:27:59 +0000 (12:27 -0800)
committerDavid Brown <davidb@codeaurora.org>
Fri, 28 Jan 2011 20:27:59 +0000 (12:27 -0800)
* msm-core:
  msm: serial: Add MSM8960 serial support

12 files changed:
arch/arm/mach-msm/board-qsd8x50.c
arch/arm/mach-msm/devices-msm7x00.c
arch/arm/mach-msm/devices-msm7x30.c
arch/arm/mach-msm/devices-qsd8x50.c
arch/arm/mach-msm/gpiomux-8x50.c
arch/arm/mach-msm/include/mach/mmc.h
arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
drivers/mmc/host/msm_sdcc.c
drivers/mmc/host/msm_sdcc.h
drivers/tty/serial/msm_serial.c
drivers/tty/serial/msm_serial.h
drivers/video/msm/msm_fb.c

index 3edc4de7e542f54dedfdb3449d1790cd92e97d86..b464d48da7c0ded1029d01946965b93ce0df8c5a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/usb/msm_hsusb.h>
+#include <linux/err.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -31,6 +32,8 @@
 #include <mach/irqs.h>
 #include <mach/sirc.h>
 #include <mach/gpio.h>
+#include <mach/vreg.h>
+#include <mach/mmc.h>
 
 #include "devices.h"
 
@@ -95,6 +98,81 @@ static struct platform_device *devices[] __initdata = {
        &msm_device_hsusb_host,
 };
 
+static struct msm_mmc_gpio sdc1_gpio_cfg[] = {
+       {51, "sdc1_dat_3"},
+       {52, "sdc1_dat_2"},
+       {53, "sdc1_dat_1"},
+       {54, "sdc1_dat_0"},
+       {55, "sdc1_cmd"},
+       {56, "sdc1_clk"}
+};
+
+static struct vreg *vreg_mmc;
+static unsigned long vreg_sts;
+
+static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
+{
+       int rc = 0;
+       struct platform_device *pdev;
+
+       pdev = container_of(dv, struct platform_device, dev);
+
+       if (vdd == 0) {
+               if (!vreg_sts)
+                       return 0;
+
+               clear_bit(pdev->id, &vreg_sts);
+
+               if (!vreg_sts) {
+                       rc = vreg_disable(vreg_mmc);
+                       if (rc)
+                               pr_err("vreg_mmc disable failed for slot "
+                                               "%d: %d\n", pdev->id, rc);
+               }
+               return 0;
+       }
+
+       if (!vreg_sts) {
+               rc = vreg_set_level(vreg_mmc, 2900);
+               if (rc)
+                       pr_err("vreg_mmc set level failed for slot %d: %d\n",
+                                       pdev->id, rc);
+               rc = vreg_enable(vreg_mmc);
+               if (rc)
+                       pr_err("vreg_mmc enable failed for slot %d: %d\n",
+                                       pdev->id, rc);
+       }
+       set_bit(pdev->id, &vreg_sts);
+       return 0;
+}
+
+static struct msm_mmc_gpio_data sdc1_gpio = {
+       .gpio = sdc1_gpio_cfg,
+       .size = ARRAY_SIZE(sdc1_gpio_cfg),
+};
+
+static struct msm_mmc_platform_data qsd8x50_sdc1_data = {
+       .ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+       .translate_vdd  = msm_sdcc_setup_power,
+       .gpio_data = &sdc1_gpio,
+};
+
+static void __init qsd8x50_init_mmc(void)
+{
+       if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa())
+               vreg_mmc = vreg_get(NULL, "gp6");
+       else
+               vreg_mmc = vreg_get(NULL, "gp5");
+
+       if (IS_ERR(vreg_mmc)) {
+               pr_err("vreg get for vreg_mmc failed (%ld)\n",
+                               PTR_ERR(vreg_mmc));
+               return;
+       }
+
+       msm_add_sdcc(1, &qsd8x50_sdc1_data, 0, 0);
+}
+
 static void __init qsd8x50_map_io(void)
 {
        msm_map_qsd8x50_io();
@@ -113,6 +191,7 @@ static void __init qsd8x50_init(void)
        msm_device_hsusb.dev.parent = &msm_device_otg.dev;
        msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
        platform_add_devices(devices, ARRAY_SIZE(devices));
+       qsd8x50_init_mmc();
 }
 
 MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
index 0a47678143f6b71aa5d55d8711ba38d36ef92cc4..ed62806559e7a66e5943abf0710a569e90bf6309 100644 (file)
@@ -39,6 +39,7 @@ static struct resource resources_uart1[] = {
                .start  = MSM_UART1_PHYS,
                .end    = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
                .flags  = IORESOURCE_MEM,
+               .name  = "uart_resource"
        },
 };
 
@@ -52,6 +53,7 @@ static struct resource resources_uart2[] = {
                .start  = MSM_UART2_PHYS,
                .end    = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
                .flags  = IORESOURCE_MEM,
+               .name  = "uart_resource"
        },
 };
 
@@ -65,6 +67,7 @@ static struct resource resources_uart3[] = {
                .start  = MSM_UART3_PHYS,
                .end    = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
                .flags  = IORESOURCE_MEM,
+               .name  = "uart_resource"
        },
 };
 
index 8bd730792ff0240c315b2dc72d750ebef0be4f67..cd4343bcf7304110e81fb49b0fd9589737d0cdab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -42,6 +42,7 @@ static struct resource resources_uart2[] = {
                .start  = MSM_UART2_PHYS,
                .end    = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
                .flags  = IORESOURCE_MEM,
+               .name  = "uart_resource"
        },
 };
 
index 4cbf89dda733106fe3f063b2ce4bb5f8bd3edf2e..bd545f9e8c29bcffafd19139355ee98a70a5b947 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -39,6 +39,7 @@ static struct resource resources_uart3[] = {
                .start  = MSM_UART3_PHYS,
                .end    = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
                .flags  = IORESOURCE_MEM,
+               .name  = "uart_resource"
        },
 };
 
@@ -125,6 +126,194 @@ struct platform_device msm_device_hsusb_host = {
        },
 };
 
+static struct resource resources_sdc1[] = {
+       {
+               .start  = MSM_SDC1_PHYS,
+               .end    = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC1_0,
+               .end    = INT_SDC1_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+       {
+               .start  = INT_SDC1_1,
+               .end    = INT_SDC1_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc2[] = {
+       {
+               .start  = MSM_SDC2_PHYS,
+               .end    = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC2_0,
+               .end    = INT_SDC2_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+               {
+               .start  = INT_SDC2_1,
+               .end    = INT_SDC2_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc3[] = {
+       {
+               .start  = MSM_SDC3_PHYS,
+               .end    = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC3_0,
+               .end    = INT_SDC3_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+               {
+               .start  = INT_SDC3_1,
+               .end    = INT_SDC3_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc4[] = {
+       {
+               .start  = MSM_SDC4_PHYS,
+               .end    = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC4_0,
+               .end    = INT_SDC4_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+               {
+               .start  = INT_SDC4_1,
+               .end    = INT_SDC4_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device msm_device_sdc1 = {
+       .name           = "msm_sdcc",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(resources_sdc1),
+       .resource       = resources_sdc1,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc2 = {
+       .name           = "msm_sdcc",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(resources_sdc2),
+       .resource       = resources_sdc2,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc3 = {
+       .name           = "msm_sdcc",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(resources_sdc3),
+       .resource       = resources_sdc3,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc4 = {
+       .name           = "msm_sdcc",
+       .id             = 4,
+       .num_resources  = ARRAY_SIZE(resources_sdc4),
+       .resource       = resources_sdc4,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+static struct platform_device *msm_sdcc_devices[] __initdata = {
+       &msm_device_sdc1,
+       &msm_device_sdc2,
+       &msm_device_sdc3,
+       &msm_device_sdc4,
+};
+
+int __init msm_add_sdcc(unsigned int controller,
+                       struct msm_mmc_platform_data *plat,
+                       unsigned int stat_irq, unsigned long stat_irq_flags)
+{
+       struct platform_device  *pdev;
+       struct resource *res;
+
+       if (controller < 1 || controller > 4)
+               return -EINVAL;
+
+       pdev = msm_sdcc_devices[controller-1];
+       pdev->dev.platform_data = plat;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
+       if (!res)
+               return -EINVAL;
+       else if (stat_irq) {
+               res->start = res->end = stat_irq;
+               res->flags &= ~IORESOURCE_DISABLED;
+               res->flags |= stat_irq_flags;
+       }
+
+       return platform_device_register(pdev);
+}
+
 struct clk msm_clocks_8x50[] = {
        CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
        CLK_PCOM("ce_clk",      CE_CLK,         NULL, 0),
@@ -147,6 +336,14 @@ struct clk msm_clocks_8x50[] = {
        CLK_PCOM("pbus_clk",    PBUS_CLK,       NULL, CLK_MIN),
        CLK_PCOM("pcm_clk",     PCM_CLK,        NULL, 0),
        CLK_PCOM("sdac_clk",    SDAC_CLK,       NULL, OFF),
+       CLK_PCOM("sdc_clk",     SDC1_CLK,       &msm_device_sdc1.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC1_P_CLK,     &msm_device_sdc1.dev, OFF),
+       CLK_PCOM("sdc_clk",     SDC2_CLK,       &msm_device_sdc2.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC2_P_CLK,     &msm_device_sdc2.dev, OFF),
+       CLK_PCOM("sdc_clk",     SDC3_CLK,       &msm_device_sdc3.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC3_P_CLK,     &msm_device_sdc3.dev, OFF),
+       CLK_PCOM("sdc_clk",     SDC4_CLK,       &msm_device_sdc4.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC4_P_CLK,     &msm_device_sdc4.dev, OFF),
        CLK_PCOM("spi_clk",     SPI_CLK,        NULL, 0),
        CLK_PCOM("tsif_clk",    TSIF_CLK,       NULL, 0),
        CLK_PCOM("tsif_ref_clk",        TSIF_REF_CLK,   NULL, 0),
index 4406e0f4ae9508670d5303c494b5952a808c71be..f7a4ea593c95054591120d34a23c3f6a32e1cffb 100644 (file)
  */
 #include "gpiomux.h"
 
+#if defined(CONFIG_MMC_MSM) || defined(CONFIG_MMC_MSM_MODULE)
+       #define SDCC_DAT_0_3_CMD_ACTV_CFG (GPIOMUX_VALID | GPIOMUX_PULL_UP\
+                                       | GPIOMUX_FUNC_1 | GPIOMUX_DRV_8MA)
+       #define SDCC_CLK_ACTV_CFG (GPIOMUX_VALID | GPIOMUX_PULL_NONE\
+                                       | GPIOMUX_FUNC_1 | GPIOMUX_DRV_8MA)
+#else
+       #define SDCC_DAT_0_3_CMD_ACTV_CFG 0
+       #define SDCC_CLK_ACTV_CFG 0
+#endif
+
+#define SDC1_SUSPEND_CONFIG (GPIOMUX_VALID | GPIOMUX_PULL_DOWN\
+                               | GPIOMUX_FUNC_GPIO | GPIOMUX_DRV_2MA)
+
 struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
        [86] = { /* UART3 RX */
                .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
@@ -25,4 +38,14 @@ struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
                .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
                             GPIOMUX_FUNC_1 | GPIOMUX_VALID,
        },
+       /* SDC1 data[3:0] & CMD */
+       [51 ... 55] = {
+               .active = SDCC_DAT_0_3_CMD_ACTV_CFG,
+               .suspended = SDC1_SUSPEND_CONFIG
+       },
+       /* SDC1 CLK */
+       [56] = {
+               .active = SDCC_CLK_ACTV_CFG,
+               .suspended = SDC1_SUSPEND_CONFIG
+       },
 };
index d54b6b086cff412bba5ad9e489d9c0dbee7c1a2c..5631b51cec465e78f90feec4cc52ae7a74d7b0be 100644 (file)
@@ -15,12 +15,23 @@ struct embedded_sdio_data {
        int num_funcs;
 };
 
+struct msm_mmc_gpio {
+       unsigned no;
+       const char *name;
+};
+
+struct msm_mmc_gpio_data {
+       struct msm_mmc_gpio *gpio;
+       u8 size;
+};
+
 struct msm_mmc_platform_data {
        unsigned int ocr_mask;                  /* available voltages */
        u32 (*translate_vdd)(struct device *, unsigned int);
        unsigned int (*status)(struct device *);
        struct embedded_sdio_data *embedded_sdio;
        int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
+       struct msm_mmc_gpio_data *gpio_data;
 };
 
 #endif
index cf1c2df1d953d8b2477400e3fa2f2b623829073e..d4143201999f2d8675e29a142d4290f2fef75f2e 100644 (file)
 #define MSM_UART2DM_PHYS      0xA0900000
 
 
-#define MSM_SDC1_PHYS          0xA0400000
+#define MSM_SDC1_PHYS          0xA0300000
 #define MSM_SDC1_SIZE          SZ_4K
 
-#define MSM_SDC2_PHYS          0xA0500000
+#define MSM_SDC2_PHYS          0xA0400000
 #define MSM_SDC2_SIZE          SZ_4K
 
-#define MSM_SDC3_PHYS          0xA0600000
+#define MSM_SDC3_PHYS          0xA0500000
 #define MSM_SDC3_SIZE           SZ_4K
 
-#define MSM_SDC4_PHYS          0xA0700000
+#define MSM_SDC4_PHYS          0xA0600000
 #define MSM_SDC4_SIZE          SZ_4K
 
 #endif
index 5decfd0bd61dc1d1369e8c5cd81fca8d681f1322..97c9b3638d57ea81aef3917c042b0067234fa31b 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/io.h>
 #include <linux/memory.h>
 #include <linux/gfp.h>
+#include <linux/gpio.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
@@ -383,14 +384,30 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
        host->curr.user_pages = 0;
 
        box = &nc->cmd[0];
-       for (i = 0; i < host->dma.num_ents; i++) {
-               box->cmd = CMD_MODE_BOX;
 
-       /* Initialize sg dma address */
-       sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg))
-                               + sg->offset;
+       /* location of command block must be 64 bit aligned */
+       BUG_ON(host->dma.cmd_busaddr & 0x07);
+
+       nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
+       host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
+                              DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
+       host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
 
-       if (i == (host->dma.num_ents - 1))
+       n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
+                       host->dma.num_ents, host->dma.dir);
+       if (n == 0) {
+               printk(KERN_ERR "%s: Unable to map in all sg elements\n",
+                       mmc_hostname(host->mmc));
+               host->dma.sg = NULL;
+               host->dma.num_ents = 0;
+               return -ENOMEM;
+       }
+
+       for_each_sg(host->dma.sg, sg, n, i) {
+
+               box->cmd = CMD_MODE_BOX;
+
+               if (i == n - 1)
                        box->cmd |= CMD_LC;
                rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ?
                        (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 :
@@ -418,27 +435,6 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
                        box->cmd |= CMD_DST_CRCI(crci);
                }
                box++;
-               sg++;
-       }
-
-       /* location of command block must be 64 bit aligned */
-       BUG_ON(host->dma.cmd_busaddr & 0x07);
-
-       nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
-       host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
-                              DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
-       host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
-
-       n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
-                       host->dma.num_ents, host->dma.dir);
-/* dsb inside dma_map_sg will write nc out to mem as well */
-
-       if (n != host->dma.num_ents) {
-               printk(KERN_ERR "%s: Unable to map in all sg elements\n",
-                       mmc_hostname(host->mmc));
-               host->dma.sg = NULL;
-               host->dma.num_ents = 0;
-               return -ENOMEM;
        }
 
        return 0;
@@ -946,6 +942,38 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq)
        spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static void msmsdcc_setup_gpio(struct msmsdcc_host *host, bool enable)
+{
+       struct msm_mmc_gpio_data *curr;
+       int i, rc = 0;
+
+       if (!host->plat->gpio_data && host->gpio_config_status == enable)
+               return;
+
+       curr = host->plat->gpio_data;
+       for (i = 0; i < curr->size; i++) {
+               if (enable) {
+                       rc = gpio_request(curr->gpio[i].no,
+                                               curr->gpio[i].name);
+                       if (rc) {
+                               pr_err("%s: gpio_request(%d, %s) failed %d\n",
+                                       mmc_hostname(host->mmc),
+                                       curr->gpio[i].no,
+                                       curr->gpio[i].name, rc);
+                               goto free_gpios;
+                       }
+               } else {
+                       gpio_free(curr->gpio[i].no);
+               }
+       }
+       host->gpio_config_status = enable;
+       return;
+
+free_gpios:
+       for (; i >= 0; i--)
+               gpio_free(curr->gpio[i].no);
+}
+
 static void
 msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
@@ -958,6 +986,8 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        msmsdcc_enable_clocks(host);
 
+       spin_unlock_irqrestore(&host->lock, flags);
+
        if (ios->clock) {
                if (ios->clock != host->clk_rate) {
                        rc = clk_set_rate(host->clk, ios->clock);
@@ -984,9 +1014,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        switch (ios->power_mode) {
        case MMC_POWER_OFF:
+               msmsdcc_setup_gpio(host, false);
                break;
        case MMC_POWER_UP:
                pwr |= MCI_PWR_UP;
+               msmsdcc_setup_gpio(host, true);
                break;
        case MMC_POWER_ON:
                pwr |= MCI_PWR_ON;
@@ -1003,9 +1035,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                msmsdcc_writel(host, pwr, MMCIPOWER);
        }
 #if BUSCLK_PWRSAVE
+       spin_lock_irqsave(&host->lock, flags);
        msmsdcc_disable_clocks(host, 1);
-#endif
        spin_unlock_irqrestore(&host->lock, flags);
+#endif
 }
 
 static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -1331,9 +1364,6 @@ msmsdcc_probe(struct platform_device *pdev)
        if (host->timer.function)
                pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc));
 
-#if BUSCLK_PWRSAVE
-       msmsdcc_disable_clocks(host, 1);
-#endif
        return 0;
  cmd_irq_free:
        free_irq(cmd_irqres->start, host);
index 939557af266d6e535c8b416895665cdaaceef645..42d7bbc977c5846a38e5c06449a22a0998374e41 100644 (file)
@@ -243,6 +243,7 @@ struct msmsdcc_host {
        unsigned int            cmd_datactrl;
        struct mmc_command      *cmd_cmd;
        u32                     cmd_c;
+       bool                    gpio_config_status;
 
        bool prog_scan;
        bool prog_enable;
index 8e43a7b69e646accf723a020ba8ef5f8a05841d0..bfee9b4c66611045132893e1efcb6e8a8a925714 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -31,6 +32,7 @@
 #include <linux/serial.h>
 #include <linux/clk.h>
 #include <linux/platform_device.h>
+#include <linux/delay.h>
 
 #include "msm_serial.h"
 
@@ -38,9 +40,20 @@ struct msm_port {
        struct uart_port        uart;
        char                    name[16];
        struct clk              *clk;
+       struct clk              *pclk;
        unsigned int            imr;
+       unsigned int            *gsbi_base;
+       int                     is_uartdm;
+       unsigned int            old_snap_state;
 };
 
+static inline void wait_for_xmitr(struct uart_port *port, int bits)
+{
+       if (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY))
+               while ((msm_read(port, UART_ISR) & bits) != bits)
+                       cpu_relax();
+}
+
 static void msm_stop_tx(struct uart_port *port)
 {
        struct msm_port *msm_port = UART_TO_MSM(port);
@@ -73,6 +86,61 @@ static void msm_enable_ms(struct uart_port *port)
        msm_write(port, msm_port->imr, UART_IMR);
 }
 
+static void handle_rx_dm(struct uart_port *port, unsigned int misr)
+{
+       struct tty_struct *tty = port->state->port.tty;
+       unsigned int sr;
+       int count = 0;
+       struct msm_port *msm_port = UART_TO_MSM(port);
+
+       if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) {
+               port->icount.overrun++;
+               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
+       }
+
+       if (misr & UART_IMR_RXSTALE) {
+               count = msm_read(port, UARTDM_RX_TOTAL_SNAP) -
+                       msm_port->old_snap_state;
+               msm_port->old_snap_state = 0;
+       } else {
+               count = 4 * (msm_read(port, UART_RFWR));
+               msm_port->old_snap_state += count;
+       }
+
+       /* TODO: Precise error reporting */
+
+       port->icount.rx += count;
+
+       while (count > 0) {
+               unsigned int c;
+
+               sr = msm_read(port, UART_SR);
+               if ((sr & UART_SR_RX_READY) == 0) {
+                       msm_port->old_snap_state -= count;
+                       break;
+               }
+               c = msm_read(port, UARTDM_RF);
+               if (sr & UART_SR_RX_BREAK) {
+                       port->icount.brk++;
+                       if (uart_handle_break(port))
+                               continue;
+               } else if (sr & UART_SR_PAR_FRAME_ERR)
+                       port->icount.frame++;
+
+               /* TODO: handle sysrq */
+               tty_insert_flip_string(tty, (char *) &c,
+                                      (count > 4) ? 4 : count);
+               count -= 4;
+       }
+
+       tty_flip_buffer_push(tty);
+       if (misr & (UART_IMR_RXSTALE))
+               msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
+       msm_write(port, 0xFFFFFF, UARTDM_DMRX);
+       msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
+}
+
 static void handle_rx(struct uart_port *port)
 {
        struct tty_struct *tty = port->state->port.tty;
@@ -121,6 +189,12 @@ static void handle_rx(struct uart_port *port)
        tty_flip_buffer_push(tty);
 }
 
+static void reset_dm_count(struct uart_port *port)
+{
+       wait_for_xmitr(port, UART_ISR_TX_READY);
+       msm_write(port, 1, UARTDM_NCF_TX);
+}
+
 static void handle_tx(struct uart_port *port)
 {
        struct circ_buf *xmit = &port->state->xmit;
@@ -128,11 +202,18 @@ static void handle_tx(struct uart_port *port)
        int sent_tx;
 
        if (port->x_char) {
-               msm_write(port, port->x_char, UART_TF);
+               if (msm_port->is_uartdm)
+                       reset_dm_count(port);
+
+               msm_write(port, port->x_char,
+                         msm_port->is_uartdm ? UARTDM_TF : UART_TF);
                port->icount.tx++;
                port->x_char = 0;
        }
 
+       if (msm_port->is_uartdm)
+               reset_dm_count(port);
+
        while (msm_read(port, UART_SR) & UART_SR_TX_READY) {
                if (uart_circ_empty(xmit)) {
                        /* disable tx interrupts */
@@ -140,8 +221,11 @@ static void handle_tx(struct uart_port *port)
                        msm_write(port, msm_port->imr, UART_IMR);
                        break;
                }
+               msm_write(port, xmit->buf[xmit->tail],
+                         msm_port->is_uartdm ? UARTDM_TF : UART_TF);
 
-               msm_write(port, xmit->buf[xmit->tail], UART_TF);
+               if (msm_port->is_uartdm)
+                       reset_dm_count(port);
 
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
                port->icount.tx++;
@@ -169,8 +253,12 @@ static irqreturn_t msm_irq(int irq, void *dev_id)
        misr = msm_read(port, UART_MISR);
        msm_write(port, 0, UART_IMR); /* disable interrupt */
 
-       if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE))
-               handle_rx(port);
+       if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) {
+               if (msm_port->is_uartdm)
+                       handle_rx_dm(port, misr);
+               else
+                       handle_rx(port);
+       }
        if (misr & UART_IMR_TXLEV)
                handle_tx(port);
        if (misr & UART_IMR_DELTA_CTS)
@@ -192,10 +280,21 @@ static unsigned int msm_get_mctrl(struct uart_port *port)
        return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR | TIOCM_RTS;
 }
 
-static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
+
+static void msm_reset(struct uart_port *port)
 {
-       unsigned int mr;
+       /* reset everything */
+       msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
+       msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
+       msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
+       msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
+       msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
+       msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
+}
 
+void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+       unsigned int mr;
        mr = msm_read(port, UART_MR1);
 
        if (!(mctrl & TIOCM_RTS)) {
@@ -219,6 +318,7 @@ static void msm_break_ctl(struct uart_port *port, int break_ctl)
 static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
 {
        unsigned int baud_code, rxstale, watermark;
+       struct msm_port *msm_port = UART_TO_MSM(port);
 
        switch (baud) {
        case 300:
@@ -273,6 +373,9 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
                break;
        }
 
+       if (msm_port->is_uartdm)
+               msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
+
        msm_write(port, baud_code, UART_CSR);
 
        /* RX stale watermark */
@@ -288,25 +391,23 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
        /* set TX watermark */
        msm_write(port, 10, UART_TFWR);
 
+       if (msm_port->is_uartdm) {
+               msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
+               msm_write(port, 0xFFFFFF, UARTDM_DMRX);
+               msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
+       }
+
        return baud;
 }
 
-static void msm_reset(struct uart_port *port)
-{
-       /* reset everything */
-       msm_write(port, UART_CR_CMD_RESET_RX, UART_CR);
-       msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
-       msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
-       msm_write(port, UART_CR_CMD_RESET_BREAK_INT, UART_CR);
-       msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
-       msm_write(port, UART_CR_CMD_SET_RFR, UART_CR);
-}
 
 static void msm_init_clock(struct uart_port *port)
 {
        struct msm_port *msm_port = UART_TO_MSM(port);
 
        clk_enable(msm_port->clk);
+       if (!IS_ERR(msm_port->pclk))
+               clk_enable(msm_port->pclk);
        msm_serial_set_mnd_regs(port);
 }
 
@@ -347,15 +448,31 @@ static int msm_startup(struct uart_port *port)
                msm_write(port, data, UART_IPR);
        }
 
-       msm_reset(port);
+       data = 0;
+       if (!port->cons || (port->cons && !(port->cons->flags & CON_ENABLED))) {
+               msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
+               msm_reset(port);
+               data = UART_CR_TX_ENABLE;
+       }
+
+       data |= UART_CR_RX_ENABLE;
+       msm_write(port, data, UART_CR); /* enable TX & RX */
 
-       msm_write(port, 0x05, UART_CR); /* enable TX & RX */
+       /* Make sure IPR is not 0 to start with*/
+       if (msm_port->is_uartdm)
+               msm_write(port, UART_IPR_STALE_LSB, UART_IPR);
 
        /* turn on RX and CTS interrupts */
        msm_port->imr = UART_IMR_RXLEV | UART_IMR_RXSTALE |
                        UART_IMR_CURRENT_CTS;
-       msm_write(port, msm_port->imr, UART_IMR);
 
+       if (msm_port->is_uartdm) {
+               msm_write(port, 0xFFFFFF, UARTDM_DMRX);
+               msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
+               msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
+       }
+
+       msm_write(port, msm_port->imr, UART_IMR);
        return 0;
 }
 
@@ -384,7 +501,7 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
        baud = msm_set_baud_rate(port, baud);
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);
-       
+
        /* calculate parity */
        mr = msm_read(port, UART_MR2);
        mr &= ~UART_MR2_PARITY_MODE;
@@ -454,48 +571,105 @@ static const char *msm_type(struct uart_port *port)
 static void msm_release_port(struct uart_port *port)
 {
        struct platform_device *pdev = to_platform_device(port->dev);
-       struct resource *resource;
+       struct msm_port *msm_port = UART_TO_MSM(port);
+       struct resource *uart_resource;
+       struct resource *gsbi_resource;
        resource_size_t size;
 
-       resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (unlikely(!resource))
+       uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (unlikely(!uart_resource))
                return;
-       size = resource->end - resource->start + 1;
+       size = resource_size(uart_resource);
 
        release_mem_region(port->mapbase, size);
        iounmap(port->membase);
        port->membase = NULL;
+
+       if (msm_port->gsbi_base) {
+               iowrite32(GSBI_PROTOCOL_IDLE, msm_port->gsbi_base +
+                         GSBI_CONTROL);
+
+               gsbi_resource = platform_get_resource_byname(pdev,
+                                                            IORESOURCE_MEM,
+                                                            "gsbi_resource");
+
+               if (unlikely(!gsbi_resource))
+                       return;
+
+               size = resource_size(gsbi_resource);
+               release_mem_region(gsbi_resource->start, size);
+               iounmap(msm_port->gsbi_base);
+               msm_port->gsbi_base = NULL;
+       }
 }
 
 static int msm_request_port(struct uart_port *port)
 {
+       struct msm_port *msm_port = UART_TO_MSM(port);
        struct platform_device *pdev = to_platform_device(port->dev);
-       struct resource *resource;
+       struct resource *uart_resource;
+       struct resource *gsbi_resource;
        resource_size_t size;
+       int ret;
 
-       resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (unlikely(!resource))
+       uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                    "uart_resource");
+       if (unlikely(!uart_resource))
                return -ENXIO;
-       size = resource->end - resource->start + 1;
 
-       if (unlikely(!request_mem_region(port->mapbase, size, "msm_serial")))
+       size = resource_size(uart_resource);
+
+       if (!request_mem_region(port->mapbase, size, "msm_serial"))
                return -EBUSY;
 
        port->membase = ioremap(port->mapbase, size);
        if (!port->membase) {
-               release_mem_region(port->mapbase, size);
-               return -EBUSY;
+               ret = -EBUSY;
+               goto fail_release_port;
+       }
+
+       gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                    "gsbi_resource");
+       /* Is this a GSBI-based port? */
+       if (gsbi_resource) {
+               size = resource_size(gsbi_resource);
+
+               if (!request_mem_region(gsbi_resource->start, size,
+                                                "msm_serial")) {
+                       ret = -EBUSY;
+                       goto fail_release_port;
+               }
+
+               msm_port->gsbi_base = ioremap(gsbi_resource->start, size);
+               if (!msm_port->gsbi_base) {
+                       ret = -EBUSY;
+                       goto fail_release_gsbi;
+               }
        }
 
        return 0;
+
+fail_release_gsbi:
+       release_mem_region(gsbi_resource->start, size);
+fail_release_port:
+       release_mem_region(port->mapbase, size);
+       return ret;
 }
 
 static void msm_config_port(struct uart_port *port, int flags)
 {
+       struct msm_port *msm_port = UART_TO_MSM(port);
+       int ret;
        if (flags & UART_CONFIG_TYPE) {
                port->type = PORT_MSM;
-               msm_request_port(port);
+               ret = msm_request_port(port);
+               if (ret)
+                       return;
        }
+
+       if (msm_port->is_uartdm)
+               iowrite32(GSBI_PROTOCOL_UART, msm_port->gsbi_base +
+                         GSBI_CONTROL);
 }
 
 static int msm_verify_port(struct uart_port *port, struct serial_struct *ser)
@@ -515,9 +689,13 @@ static void msm_power(struct uart_port *port, unsigned int state,
        switch (state) {
        case 0:
                clk_enable(msm_port->clk);
+               if (!IS_ERR(msm_port->pclk))
+                       clk_enable(msm_port->pclk);
                break;
        case 3:
                clk_disable(msm_port->clk);
+               if (!IS_ERR(msm_port->pclk))
+                       clk_disable(msm_port->pclk);
                break;
        default:
                printk(KERN_ERR "msm_serial: Unknown PM state %d\n", state);
@@ -550,7 +728,7 @@ static struct msm_port msm_uart_ports[] = {
                        .iotype = UPIO_MEM,
                        .ops = &msm_uart_pops,
                        .flags = UPF_BOOT_AUTOCONF,
-                       .fifosize = 512,
+                       .fifosize = 64,
                        .line = 0,
                },
        },
@@ -559,7 +737,7 @@ static struct msm_port msm_uart_ports[] = {
                        .iotype = UPIO_MEM,
                        .ops = &msm_uart_pops,
                        .flags = UPF_BOOT_AUTOCONF,
-                       .fifosize = 512,
+                       .fifosize = 64,
                        .line = 1,
                },
        },
@@ -585,9 +763,14 @@ static inline struct uart_port *get_port_from_line(unsigned int line)
 
 static void msm_console_putchar(struct uart_port *port, int c)
 {
+       struct msm_port *msm_port = UART_TO_MSM(port);
+
+       if (msm_port->is_uartdm)
+               reset_dm_count(port);
+
        while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
                ;
-       msm_write(port, c, UART_TF);
+       msm_write(port, c, msm_port->is_uartdm ? UARTDM_TF : UART_TF);
 }
 
 static void msm_console_write(struct console *co, const char *s,
@@ -609,12 +792,14 @@ static void msm_console_write(struct console *co, const char *s,
 static int __init msm_console_setup(struct console *co, char *options)
 {
        struct uart_port *port;
+       struct msm_port *msm_port;
        int baud, flow, bits, parity;
 
        if (unlikely(co->index >= UART_NR || co->index < 0))
                return -ENXIO;
 
        port = get_port_from_line(co->index);
+       msm_port = UART_TO_MSM(port);
 
        if (unlikely(!port->membase))
                return -ENXIO;
@@ -638,6 +823,11 @@ static int __init msm_console_setup(struct console *co, char *options)
 
        msm_reset(port);
 
+       if (msm_port->is_uartdm) {
+               msm_write(port, UART_CR_CMD_PROTECTION_EN, UART_CR);
+               msm_write(port, UART_CR_TX_ENABLE, UART_CR);
+       }
+
        printk(KERN_INFO "msm_serial: console setup on port #%d\n", port->line);
 
        return uart_set_options(port, co, baud, parity, bits, flow);
@@ -685,14 +875,32 @@ static int __init msm_serial_probe(struct platform_device *pdev)
        port->dev = &pdev->dev;
        msm_port = UART_TO_MSM(port);
 
-       msm_port->clk = clk_get(&pdev->dev, "uart_clk");
-       if (IS_ERR(msm_port->clk))
-               return PTR_ERR(msm_port->clk);
+       if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"))
+               msm_port->is_uartdm = 1;
+       else
+               msm_port->is_uartdm = 0;
+
+       if (msm_port->is_uartdm) {
+               msm_port->clk = clk_get(&pdev->dev, "gsbi_uart_clk");
+               msm_port->pclk = clk_get(&pdev->dev, "gsbi_pclk");
+       } else {
+               msm_port->clk = clk_get(&pdev->dev, "uart_clk");
+               msm_port->pclk = ERR_PTR(-ENOENT);
+       }
+
+       if (unlikely(IS_ERR(msm_port->clk) || (IS_ERR(msm_port->pclk) &&
+                                              msm_port->is_uartdm)))
+                       return PTR_ERR(msm_port->clk);
+
+       if (msm_port->is_uartdm)
+               clk_set_rate(msm_port->clk, 7372800);
+
        port->uartclk = clk_get_rate(msm_port->clk);
        printk(KERN_INFO "uartclk = %d\n", port->uartclk);
 
 
-       resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                    "uart_resource");
        if (unlikely(!resource))
                return -ENXIO;
        port->mapbase = resource->start;
index f6ca9ca79e98f34be24525596f1b38fe5c5f31a3..9b8dc5d0d85546e70aa978dc4381fea752f07812 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -54,6 +55,7 @@
 #define UART_CSR_300   0x22
 
 #define UART_TF                0x000C
+#define UARTDM_TF      0x0070
 
 #define UART_CR                                0x0010
 #define UART_CR_CMD_NULL               (0 << 4)
 #define UART_CR_CMD_START_BREAK                (5 << 4)
 #define UART_CR_CMD_STOP_BREAK         (6 << 4)
 #define UART_CR_CMD_RESET_CTS          (7 << 4)
+#define UART_CR_CMD_RESET_STALE_INT    (8 << 4)
 #define UART_CR_CMD_PACKET_MODE                (9 << 4)
 #define UART_CR_CMD_MODE_RESET         (12 << 4)
 #define UART_CR_CMD_SET_RFR            (13 << 4)
 #define UART_CR_CMD_RESET_RFR          (14 << 4)
+#define UART_CR_CMD_PROTECTION_EN      (16 << 4)
+#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
 #define UART_CR_TX_DISABLE             (1 << 3)
-#define UART_CR_TX_ENABLE              (1 << 3)
-#define UART_CR_RX_DISABLE             (1 << 3)
-#define UART_CR_RX_ENABLE              (1 << 3)
+#define UART_CR_TX_ENABLE              (1 << 2)
+#define UART_CR_RX_DISABLE             (1 << 1)
+#define UART_CR_RX_ENABLE              (1 << 0)
 
 #define UART_IMR               0x0014
 #define UART_IMR_TXLEV         (1 << 0)
 #define UART_SR_RX_FULL                (1 << 1)
 #define UART_SR_RX_READY       (1 << 0)
 
-#define UART_RF                0x000C
-#define UART_MISR      0x0010
-#define UART_ISR       0x0014
+#define UART_RF                        0x000C
+#define UARTDM_RF              0x0070
+#define UART_MISR              0x0010
+#define UART_ISR               0x0014
+#define UART_ISR_TX_READY      (1 << 7)
+
+#define GSBI_CONTROL           0x0
+#define GSBI_PROTOCOL_CODE     0x30
+#define GSBI_PROTOCOL_UART     0x40
+#define GSBI_PROTOCOL_IDLE     0x0
+
+#define UARTDM_DMRX            0x34
+#define UARTDM_NCF_TX          0x40
+#define UARTDM_RX_TOTAL_SNAP   0x38
 
 #define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port)
 
index debe5933fd2e6c0d3c3e272242e093632f2732cf..5436aeb9445626888be2d453aba070d47d1cf65d 100644 (file)
@@ -81,7 +81,6 @@ struct msmfb_info {
        spinlock_t update_lock;
        struct mutex panel_init_lock;
        wait_queue_head_t frame_wq;
-       struct workqueue_struct *resume_workqueue;
        struct work_struct resume_work;
        struct msmfb_callback dma_callback;
        struct msmfb_callback vsync_callback;
@@ -111,7 +110,7 @@ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
        if (msmfb->sleeping == UPDATING &&
            msmfb->frame_done == msmfb->update_frame) {
                DLOG(SUSPEND_RESUME, "full update completed\n");
-               queue_work(msmfb->resume_workqueue, &msmfb->resume_work);
+               schedule_work(&msmfb->resume_work);
        }
        spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
        wake_up(&msmfb->frame_wq);
@@ -559,12 +558,6 @@ static int msmfb_probe(struct platform_device *pdev)
        spin_lock_init(&msmfb->update_lock);
        mutex_init(&msmfb->panel_init_lock);
        init_waitqueue_head(&msmfb->frame_wq);
-       msmfb->resume_workqueue = create_workqueue("panel_on");
-       if (msmfb->resume_workqueue == NULL) {
-               printk(KERN_ERR "failed to create panel_on workqueue\n");
-               ret = -ENOMEM;
-               goto error_create_workqueue;
-       }
        INIT_WORK(&msmfb->resume_work, power_on_panel);
        msmfb->black = kzalloc(msmfb->fb->var.bits_per_pixel*msmfb->xres,
                               GFP_KERNEL);
@@ -589,8 +582,6 @@ static int msmfb_probe(struct platform_device *pdev)
        return 0;
 
 error_register_framebuffer:
-       destroy_workqueue(msmfb->resume_workqueue);
-error_create_workqueue:
        iounmap(fb->screen_base);
 error_setup_fbmem:
        framebuffer_release(msmfb->fb);