linux-omap2 git: enable smart reflex driver for beagleboard
authorKoen Kooi <koen@openembedded.org>
Mon, 2 Jun 2008 12:31:31 +0000 (12:31 +0000)
committerKoen Kooi <koen@openembedded.org>
Mon, 2 Jun 2008 12:31:31 +0000 (12:31 +0000)
packages/linux/linux-omap2-git/beagleboard/00001-mcbsp-transform.patch
packages/linux/linux-omap2-git/beagleboard/00002-mcbsp-omap1.patch
packages/linux/linux-omap2-git/beagleboard/00003-mcbsp-omap3-clock.patch
packages/linux/linux-omap2-git/beagleboard/00004-omap2-mcbsp.patch
packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch [new file with mode: 0644]
packages/linux/linux-omap2-git/beagleboard/0002-ARM-OMAP-SmartReflex-driver.patch [new file with mode: 0644]
packages/linux/linux-omap2-git/beagleboard/0003-ARM-OMAP-SmartReflex-driver.patch [new file with mode: 0644]
packages/linux/linux-omap2-git/beagleboard/defconfig
packages/linux/linux-omap2_git.bb

index 452370b..e8b3e7a 100644 (file)
-From: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
-\r
-This patch transform mcbsp code into a very initial\r
-implementation of a platform driver.\r
-\r
-It also gets ride of ifdefs on mcbsp.c code.\r
-To do it, a platform data structure was defined.\r
-\r
-Platform devices are located in arch/arm/plat-omap/devices.c\r
-\r
-Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
----\r
- arch/arm/plat-omap/devices.c      |   45 +++\r
- arch/arm/plat-omap/mcbsp.c        |  660 ++++++++++++++-----------------------\r
- include/asm-arm/arch-omap/mcbsp.h |   73 ++++-\r
- 3 files changed, 367 insertions(+), 411 deletions(-)\r
-\r
-diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c\r
-index 099182b..b3e0147 100644\r
---- a/arch/arm/plat-omap/devices.c\r
-+++ b/arch/arm/plat-omap/devices.c\r
-@@ -27,6 +27,7 @@\r
- #include <asm/arch/gpio.h>\r
- #include <asm/arch/menelaus.h>\r
- #include <asm/arch/dsp_common.h>\r
-+#include <asm/arch/mcbsp.h>\r
\r
- #if   defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)\r
\r
-@@ -150,6 +151,49 @@ static inline void omap_init_kp(void) {}\r
- #endif\r
\r
- /*-------------------------------------------------------------------------*/\r
-+#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)\r
-+\r
-+static struct platform_device omap_mcbsp_devices[OMAP_MAX_MCBSP_COUNT];\r
-+static int mcbsps_configured;\r
-+\r
-+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,\r
-+                                      int size)\r
-+{\r
-+      int i;\r
-+\r
-+      if (size > OMAP_MAX_MCBSP_COUNT) {\r
-+              printk(KERN_WARNING "Registered too many McBSPs platform_data."\r
-+                      " Using maximum (%d) available.\n",\r
-+                      OMAP_MAX_MCBSP_COUNT);\r
-+              size = OMAP_MAX_MCBSP_COUNT;\r
-+      }\r
-+\r
-+      for (i = 0; i < size; i++) {\r
-+              struct platform_device *new_mcbsp = &omap_mcbsp_devices[i];\r
-+              new_mcbsp->name = "omap-mcbsp";\r
-+              new_mcbsp->id = i + 1;\r
-+              new_mcbsp->dev.platform_data = &config[i];\r
-+      }\r
-+      mcbsps_configured = size;\r
-+}\r
-+\r
-+static void __init omap_init_mcbsp(void)\r
-+{\r
-+      int i;\r
-+\r
-+      for (i = 0; i < mcbsps_configured; i++)\r
-+              platform_device_register(&omap_mcbsp_devices[i]);\r
-+}\r
-+#else\r
-+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,\r
-+                                      int size)\r
-+{  }\r
-+\r
-+static inline void __init omap_init_mcbsp(void)\r
-+{  }\r
-+#endif\r
-+\r
-+/*-------------------------------------------------------------------------*/\r
\r
- #if   defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) \\r
-       || defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)\r
-@@ -511,6 +555,7 @@ static int __init omap_init_devices(void)\r
-        */\r
-       omap_init_dsp();\r
-       omap_init_kp();\r
-+      omap_init_mcbsp();\r
-       omap_init_mmc();\r
-       omap_init_uwire();\r
-       omap_init_wdt();\r
-diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c\r
-index 053de31..5536223 100644\r
---- a/arch/arm/plat-omap/mcbsp.c\r
-+++ b/arch/arm/plat-omap/mcbsp.c\r
-@@ -15,6 +15,7 @@\r
- #include <linux/module.h>\r
- #include <linux/init.h>\r
- #include <linux/device.h>\r
-+#include <linux/platform_device.h>\r
- #include <linux/wait.h>\r
- #include <linux/completion.h>\r
- #include <linux/interrupt.h>\r
-@@ -25,83 +26,53 @@\r
- #include <linux/irq.h>\r
\r
- #include <asm/arch/dma.h>\r
--#include <asm/arch/mux.h>\r
--#include <asm/arch/irqs.h>\r
--#include <asm/arch/dsp_common.h>\r
- #include <asm/arch/mcbsp.h>\r
\r
--#ifdef CONFIG_MCBSP_DEBUG\r
--#define DBG(x...)     printk(x)\r
--#else\r
--#define DBG(x...)                     do { } while (0)\r
--#endif\r
--\r
--struct omap_mcbsp {\r
--      u32                          io_base;\r
--      u8                           id;\r
--      u8                           free;\r
--      omap_mcbsp_word_length       rx_word_length;\r
--      omap_mcbsp_word_length       tx_word_length;\r
--\r
--      omap_mcbsp_io_type_t         io_type; /* IRQ or poll */\r
--      /* IRQ based TX/RX */\r
--      int                          rx_irq;\r
--      int                          tx_irq;\r
--\r
--      /* DMA stuff */\r
--      u8                           dma_rx_sync;\r
--      short                        dma_rx_lch;\r
--      u8                           dma_tx_sync;\r
--      short                        dma_tx_lch;\r
--\r
--      /* Completion queues */\r
--      struct completion            tx_irq_completion;\r
--      struct completion            rx_irq_completion;\r
--      struct completion            tx_dma_completion;\r
--      struct completion            rx_dma_completion;\r
--\r
--      /* Protect the field .free, while checking if the mcbsp is in use */\r
--      spinlock_t                   lock;\r
--};\r
--\r
- static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];\r
--#ifdef CONFIG_ARCH_OMAP1\r
--static struct clk *mcbsp_dsp_ck;\r
--static struct clk *mcbsp_api_ck;\r
--static struct clk *mcbsp_dspxor_ck;\r
--#endif\r
--#ifdef CONFIG_ARCH_OMAP2\r
--static struct clk *mcbsp1_ick;\r
--static struct clk *mcbsp1_fck;\r
--static struct clk *mcbsp2_ick;\r
--static struct clk *mcbsp2_fck;\r
--#endif\r
-+\r
-+#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \\r
-+                                      mcbsp[id].pdata->ops && \\r
-+                                      mcbsp[id].pdata->ops->check && \\r
-+                                      (mcbsp[id].pdata->ops->check(id) == 0))\r
\r
- static void omap_mcbsp_dump_reg(u8 id)\r
- {\r
--      DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);\r
--      DBG("DRR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));\r
--      DBG("DRR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));\r
--      DBG("DXR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));\r
--      DBG("DXR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));\r
--      DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));\r
--      DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));\r
--      DBG("RCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));\r
--      DBG("RCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));\r
--      DBG("XCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));\r
--      DBG("XCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));\r
--      DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));\r
--      DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));\r
--      DBG("PCR0:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));\r
--      DBG("***********************\n");\r
-+      dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);\r
-+      dev_dbg(mcbsp[id].dev, "DRR2:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));\r
-+      dev_dbg(mcbsp[id].dev, "DRR1:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));\r
-+      dev_dbg(mcbsp[id].dev, "DXR2:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));\r
-+      dev_dbg(mcbsp[id].dev, "DXR1:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));\r
-+      dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));\r
-+      dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));\r
-+      dev_dbg(mcbsp[id].dev, "RCR2:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));\r
-+      dev_dbg(mcbsp[id].dev, "RCR1:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));\r
-+      dev_dbg(mcbsp[id].dev, "XCR2:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));\r
-+      dev_dbg(mcbsp[id].dev, "XCR1:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));\r
-+      dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));\r
-+      dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));\r
-+      dev_dbg(mcbsp[id].dev, "PCR0:  0x%04x\n",\r
-+                      OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));\r
-+      dev_dbg(mcbsp[id].dev, "***********************\n");\r
- }\r
\r
- static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)\r
- {\r
-       struct omap_mcbsp *mcbsp_tx = dev_id;\r
\r
--      DBG("TX IRQ callback : 0x%x\n",\r
--          OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));\r
-+      dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",\r
-+              OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));\r
\r
-       complete(&mcbsp_tx->tx_irq_completion);\r
\r
-@@ -112,8 +83,8 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)\r
- {\r
-       struct omap_mcbsp *mcbsp_rx = dev_id;\r
\r
--      DBG("RX IRQ callback : 0x%x\n",\r
--          OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));\r
-+      dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",\r
-+              OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));\r
\r
-       complete(&mcbsp_rx->rx_irq_completion);\r
\r
-@@ -124,8 +95,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)\r
- {\r
-       struct omap_mcbsp *mcbsp_dma_tx = data;\r
\r
--      DBG("TX DMA callback : 0x%x\n",\r
--          OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));\r
-+      dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",\r
-+              OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));\r
\r
-       /* We can free the channels */\r
-       omap_free_dma(mcbsp_dma_tx->dma_tx_lch);\r
-@@ -138,8 +109,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)\r
- {\r
-       struct omap_mcbsp *mcbsp_dma_rx = data;\r
\r
--      DBG("RX DMA callback : 0x%x\n",\r
--          OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));\r
-+      dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",\r
-+              OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));\r
\r
-       /* We can free the channels */\r
-       omap_free_dma(mcbsp_dma_rx->dma_rx_lch);\r
-@@ -156,9 +127,16 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)\r
-  */\r
- void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)\r
- {\r
--      u32 io_base = mcbsp[id].io_base;\r
-+      u32 io_base;\r
-+\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return;\r
-+      }\r
\r
--      DBG("OMAP-McBSP: McBSP%d  io_base: 0x%8x\n", id + 1, io_base);\r
-+      io_base = mcbsp[id].io_base;\r
-+      dev_dbg(mcbsp[id].dev, "Configuring McBSP%d  io_base: 0x%8x\n",\r
-+                      mcbsp[id].id, io_base);\r
\r
-       /* We write the given config */\r
-       OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);\r
-@@ -175,97 +153,22 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)\r
- }\r
- EXPORT_SYMBOL(omap_mcbsp_config);\r
\r
--static int omap_mcbsp_check(unsigned int id)\r
--{\r
--      if (cpu_is_omap730()) {\r
--              if (id > OMAP_MAX_MCBSP_COUNT - 1) {\r
--                     printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",\r
--                              id + 1);\r
--                     return -1;\r
--              }\r
--              return 0;\r
--      }\r
--\r
--      if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {\r
--              if (id > OMAP_MAX_MCBSP_COUNT) {\r
--                      printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",\r
--                              id + 1);\r
--                      return -1;\r
--              }\r
--              return 0;\r
--      }\r
--\r
--      return -1;\r
--}\r
--\r
--#ifdef CONFIG_ARCH_OMAP1\r
--static void omap_mcbsp_dsp_request(void)\r
--{\r
--      if (cpu_is_omap15xx() || cpu_is_omap16xx()) {\r
--              int ret;\r
--\r
--              ret = omap_dsp_request_mem();\r
--              if (ret < 0) {\r
--                      printk(KERN_ERR "Could not get dsp memory: %i\n", ret);\r
--                      return;\r
--              }\r
--\r
--              clk_enable(mcbsp_dsp_ck);\r
--              clk_enable(mcbsp_api_ck);\r
--\r
--              /* enable 12MHz clock to mcbsp 1 & 3 */\r
--              clk_enable(mcbsp_dspxor_ck);\r
--\r
--              /*\r
--               * DSP external peripheral reset\r
--               * FIXME: This should be moved to dsp code\r
--               */\r
--              __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,\r
--                           DSP_RSTCT2);\r
--      }\r
--}\r
--\r
--static void omap_mcbsp_dsp_free(void)\r
--{\r
--      if (cpu_is_omap15xx() || cpu_is_omap16xx()) {\r
--              omap_dsp_release_mem();\r
--              clk_disable(mcbsp_dspxor_ck);\r
--              clk_disable(mcbsp_dsp_ck);\r
--              clk_disable(mcbsp_api_ck);\r
--      }\r
--}\r
--#endif\r
--\r
--#ifdef CONFIG_ARCH_OMAP2\r
--static void omap2_mcbsp2_mux_setup(void)\r
--{\r
--      if (cpu_is_omap2420()) {\r
--              omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);\r
--              omap_cfg_reg(R14_24XX_MCBSP2_FSX);\r
--              omap_cfg_reg(W15_24XX_MCBSP2_DR);\r
--              omap_cfg_reg(V15_24XX_MCBSP2_DX);\r
--              omap_cfg_reg(V14_24XX_GPIO117);\r
--      }\r
--      /*\r
--       * Need to add MUX settings for OMAP 2430 SDP\r
--       */\r
--}\r
--#endif\r
--\r
- /*\r
-  * We can choose between IRQ based or polled IO.\r
-  * This needs to be called before omap_mcbsp_request().\r
-  */\r
- int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)\r
- {\r
--      if (omap_mcbsp_check(id) < 0)\r
--              return -EINVAL;\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
\r
-       spin_lock(&mcbsp[id].lock);\r
\r
-       if (!mcbsp[id].free) {\r
--              printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n",\r
--                      id + 1);\r
-+              dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",\r
-+                      mcbsp[id].id);\r
-               spin_unlock(&mcbsp[id].lock);\r
-               return -EINVAL;\r
-       }\r
-@@ -282,34 +185,20 @@ int omap_mcbsp_request(unsigned int id)\r
- {\r
-       int err;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
--              return -EINVAL;\r
--\r
--#ifdef CONFIG_ARCH_OMAP1\r
--      /*\r
--       * On 1510, 1610 and 1710, McBSP1 and McBSP3\r
--       * are DSP public peripherals.\r
--       */\r
--      if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)\r
--              omap_mcbsp_dsp_request();\r
--#endif\r
--\r
--#ifdef CONFIG_ARCH_OMAP2\r
--      if (cpu_is_omap24xx()) {\r
--              if (id == OMAP_MCBSP1) {\r
--                      clk_enable(mcbsp1_ick);\r
--                      clk_enable(mcbsp1_fck);\r
--              } else {\r
--                      clk_enable(mcbsp2_ick);\r
--                      clk_enable(mcbsp2_fck);\r
--              }\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-       }\r
--#endif\r
-+\r
-+      if (mcbsp[id].pdata->ops->request)\r
-+              mcbsp[id].pdata->ops->request(id);\r
-+\r
-+      mcbsp_clk_enable(&mcbsp[id]);\r
\r
-       spin_lock(&mcbsp[id].lock);\r
-       if (!mcbsp[id].free) {\r
--              printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n",\r
--                      id + 1);\r
-+              dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",\r
-+                      mcbsp[id].id);\r
-               spin_unlock(&mcbsp[id].lock);\r
-               return -1;\r
-       }\r
-@@ -322,9 +211,9 @@ int omap_mcbsp_request(unsigned int id)\r
-               err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,\r
-                                       0, "McBSP", (void *) (&mcbsp[id]));\r
-               if (err != 0) {\r
--                      printk(KERN_ERR "OMAP-McBSP: Unable to "\r
--                                      "request TX IRQ %d for McBSP%d\n",\r
--                                      mcbsp[id].tx_irq, mcbsp[id].id);\r
-+                      dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "\r
-+                                      "for McBSP%d\n", mcbsp[id].tx_irq,\r
-+                                      mcbsp[id].id);\r
-                       return err;\r
-               }\r
\r
-@@ -333,9 +222,9 @@ int omap_mcbsp_request(unsigned int id)\r
-               err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,\r
-                                       0, "McBSP", (void *) (&mcbsp[id]));\r
-               if (err != 0) {\r
--                      printk(KERN_ERR "OMAP-McBSP: Unable to "\r
--                                      "request RX IRQ %d for McBSP%d\n",\r
--                                      mcbsp[id].rx_irq, mcbsp[id].id);\r
-+                      dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "\r
-+                                      "for McBSP%d\n", mcbsp[id].rx_irq,\r
-+                                      mcbsp[id].id);\r
-                       free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));\r
-                       return err;\r
-               }\r
-@@ -349,32 +238,20 @@ EXPORT_SYMBOL(omap_mcbsp_request);\r
\r
- void omap_mcbsp_free(unsigned int id)\r
- {\r
--      if (omap_mcbsp_check(id) < 0)\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-               return;\r
--\r
--#ifdef CONFIG_ARCH_OMAP1\r
--      if (cpu_class_is_omap1()) {\r
--              if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)\r
--                      omap_mcbsp_dsp_free();\r
-       }\r
--#endif\r
--\r
--#ifdef CONFIG_ARCH_OMAP2\r
--      if (cpu_is_omap24xx()) {\r
--              if (id == OMAP_MCBSP1) {\r
--                      clk_disable(mcbsp1_ick);\r
--                      clk_disable(mcbsp1_fck);\r
--              } else {\r
--                      clk_disable(mcbsp2_ick);\r
--                      clk_disable(mcbsp2_fck);\r
--              }\r
--      }\r
--#endif\r
-+\r
-+      if (mcbsp[id].pdata->ops->free)\r
-+              mcbsp[id].pdata->ops->free(id);\r
-+\r
-+      mcbsp_clk_disable(&mcbsp[id]);\r
\r
-       spin_lock(&mcbsp[id].lock);\r
-       if (mcbsp[id].free) {\r
--              printk(KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n",\r
--                      id + 1);\r
-+              dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",\r
-+                      mcbsp[id].id);\r
-               spin_unlock(&mcbsp[id].lock);\r
-               return;\r
-       }\r
-@@ -400,8 +277,10 @@ void omap_mcbsp_start(unsigned int id)\r
-       u32 io_base;\r
-       u16 w;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-               return;\r
-+      }\r
\r
-       io_base = mcbsp[id].io_base;\r
\r
-@@ -435,8 +314,10 @@ void omap_mcbsp_stop(unsigned int id)\r
-       u32 io_base;\r
-       u16 w;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-               return;\r
-+      }\r
\r
-       io_base = mcbsp[id].io_base;\r
\r
-@@ -457,7 +338,14 @@ EXPORT_SYMBOL(omap_mcbsp_stop);\r
- /* polled mcbsp i/o operations */\r
- int omap_mcbsp_pollwrite(unsigned int id, u16 buf)\r
- {\r
--      u32 base = mcbsp[id].io_base;\r
-+      u32 base;\r
-+\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
-+\r
-+      base = mcbsp[id].io_base;\r
-       writew(buf, base + OMAP_MCBSP_REG_DXR1);\r
-       /* if frame sync error - clear the error */\r
-       if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {\r
-@@ -479,8 +367,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)\r
-                                      (XRST),\r
-                                      base + OMAP_MCBSP_REG_SPCR2);\r
-                               udelay(10);\r
--                              printk(KERN_ERR\r
--                                     " Could not write to McBSP Register\n");\r
-+                              dev_err(mcbsp[id].dev, "Could not write to"\r
-+                                      " McBSP%d Register\n", mcbsp[id].id);\r
-                               return -2;\r
-                       }\r
-               }\r
-@@ -492,7 +380,14 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);\r
\r
- int omap_mcbsp_pollread(unsigned int id, u16 *buf)\r
- {\r
--      u32 base = mcbsp[id].io_base;\r
-+      u32 base;\r
-+\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
-+\r
-+      base = mcbsp[id].io_base;\r
-       /* if frame sync error - clear the error */\r
-       if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {\r
-               /* clear error */\r
-@@ -513,8 +408,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)\r
-                                      (RRST),\r
-                                      base + OMAP_MCBSP_REG_SPCR1);\r
-                               udelay(10);\r
--                              printk(KERN_ERR\r
--                                     " Could not read from McBSP Register\n");\r
-+                              dev_err(mcbsp[id].dev, "Could not read from"\r
-+                                      " McBSP%d Register\n", mcbsp[id].id);\r
-                               return -2;\r
-                       }\r
-               }\r
-@@ -531,12 +426,15 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);\r
- void omap_mcbsp_xmit_word(unsigned int id, u32 word)\r
- {\r
-       u32 io_base;\r
--      omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;\r
-+      omap_mcbsp_word_length word_length;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-               return;\r
-+      }\r
\r
-       io_base = mcbsp[id].io_base;\r
-+      word_length = mcbsp[id].tx_word_length;\r
\r
-       wait_for_completion(&(mcbsp[id].tx_irq_completion));\r
\r
-@@ -550,11 +448,14 @@ u32 omap_mcbsp_recv_word(unsigned int id)\r
- {\r
-       u32 io_base;\r
-       u16 word_lsb, word_msb = 0;\r
--      omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;\r
-+      omap_mcbsp_word_length word_length;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
--              return -EINVAL;\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
\r
-+      word_length = mcbsp[id].rx_word_length;\r
-       io_base = mcbsp[id].io_base;\r
\r
-       wait_for_completion(&(mcbsp[id].rx_irq_completion));\r
-@@ -569,11 +470,20 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);\r
\r
- int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)\r
- {\r
--      u32 io_base = mcbsp[id].io_base;\r
--      omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;\r
--      omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;\r
-+      u32 io_base;\r
-+      omap_mcbsp_word_length tx_word_length;\r
-+      omap_mcbsp_word_length rx_word_length;\r
-       u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;\r
\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
-+\r
-+      io_base = mcbsp[id].io_base;\r
-+      tx_word_length = mcbsp[id].tx_word_length;\r
-+      rx_word_length = mcbsp[id].rx_word_length;\r
-+\r
-       if (tx_word_length != rx_word_length)\r
-               return -EINVAL;\r
\r
-@@ -587,7 +497,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)\r
-                       udelay(10);\r
-                       OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);\r
-                       udelay(10);\r
--                      printk(KERN_ERR "McBSP transmitter not ready\n");\r
-+                      dev_err(mcbsp[id].dev, "McBSP%d transmitter not "\r
-+                              "ready\n", mcbsp[id].id);\r
-                       return -EAGAIN;\r
-               }\r
-       }\r
-@@ -607,7 +518,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)\r
-                       udelay(10);\r
-                       OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);\r
-                       udelay(10);\r
--                      printk(KERN_ERR "McBSP receiver not ready\n");\r
-+                      dev_err(mcbsp[id].dev, "McBSP%d receiver not "\r
-+                              "ready\n", mcbsp[id].id);\r
-                       return -EAGAIN;\r
-               }\r
-       }\r
-@@ -623,11 +535,20 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);\r
\r
- int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)\r
- {\r
--      u32 io_base = mcbsp[id].io_base, clock_word = 0;\r
--      omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;\r
--      omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;\r
-+      u32 io_base, clock_word = 0;\r
-+      omap_mcbsp_word_length tx_word_length;\r
-+      omap_mcbsp_word_length rx_word_length;\r
-       u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;\r
\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
-+\r
-+      io_base = mcbsp[id].io_base;\r
-+      tx_word_length = mcbsp[id].tx_word_length;\r
-+      rx_word_length = mcbsp[id].rx_word_length;\r
-+\r
-       if (tx_word_length != rx_word_length)\r
-               return -EINVAL;\r
\r
-@@ -641,7 +562,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)\r
-                       udelay(10);\r
-                       OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);\r
-                       udelay(10);\r
--                      printk(KERN_ERR "McBSP transmitter not ready\n");\r
-+                      dev_err(mcbsp[id].dev, "McBSP%d transmitter not "\r
-+                              "ready\n", mcbsp[id].id);\r
-                       return -EAGAIN;\r
-               }\r
-       }\r
-@@ -661,7 +583,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)\r
-                       udelay(10);\r
-                       OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);\r
-                       udelay(10);\r
--                      printk(KERN_ERR "McBSP receiver not ready\n");\r
-+                      dev_err(mcbsp[id].dev, "McBSP%d receiver not "\r
-+                              "ready\n", mcbsp[id].id);\r
-                       return -EAGAIN;\r
-               }\r
-       }\r
-@@ -692,20 +615,24 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,\r
-       int dest_port = 0;\r
-       int sync_dev = 0;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
--              return -EINVAL;\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
\r
-       if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",\r
-                               omap_mcbsp_tx_dma_callback,\r
-                               &mcbsp[id],\r
-                               &dma_tx_ch)) {\r
--              printk(KERN_ERR "OMAP-McBSP: Unable to request DMA channel for"\r
--                              " McBSP%d TX. Trying IRQ based TX\n", id + 1);\r
-+              dev_err(mcbsp[id].dev, " Unable to request DMA channel for "\r
-+                              "McBSP%d TX. Trying IRQ based TX\n",\r
-+                              mcbsp[id].id);\r
-               return -EAGAIN;\r
-       }\r
-       mcbsp[id].dma_tx_lch = dma_tx_ch;\r
\r
--      DBG("TX DMA on channel %d\n", dma_tx_ch);\r
-+      dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,\r
-+              dma_tx_ch);\r
\r
-       init_completion(&(mcbsp[id].tx_dma_completion));\r
\r
-@@ -713,7 +640,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,\r
-               src_port = OMAP_DMA_PORT_TIPB;\r
-               dest_port = OMAP_DMA_PORT_EMIFF;\r
-       }\r
--      if (cpu_is_omap24xx())\r
-+      if (cpu_class_is_omap2())\r
-               sync_dev = mcbsp[id].dma_tx_sync;\r
\r
-       omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,\r
-@@ -749,20 +676,24 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,\r
-       int dest_port = 0;\r
-       int sync_dev = 0;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
--              return -EINVAL;\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-+              return -ENODEV;\r
-+      }\r
\r
-       if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",\r
-                               omap_mcbsp_rx_dma_callback,\r
-                               &mcbsp[id],\r
-                               &dma_rx_ch)) {\r
--              printk(KERN_ERR "Unable to request DMA channel for McBSP%d RX."\r
--                              " Trying IRQ based RX\n", id + 1);\r
-+              dev_err(mcbsp[id].dev, "Unable to request DMA channel for "\r
-+                              "McBSP%d RX. Trying IRQ based RX\n",\r
-+                              mcbsp[id].id);\r
-               return -EAGAIN;\r
-       }\r
-       mcbsp[id].dma_rx_lch = dma_rx_ch;\r
\r
--      DBG("RX DMA on channel %d\n", dma_rx_ch);\r
-+      dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,\r
-+              dma_rx_ch);\r
\r
-       init_completion(&(mcbsp[id].rx_dma_completion));\r
\r
-@@ -770,7 +701,7 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,\r
-               src_port = OMAP_DMA_PORT_TIPB;\r
-               dest_port = OMAP_DMA_PORT_EMIFF;\r
-       }\r
--      if (cpu_is_omap24xx())\r
-+      if (cpu_class_is_omap2())\r
-               sync_dev = mcbsp[id].dma_rx_sync;\r
\r
-       omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,\r
-@@ -809,8 +740,10 @@ void omap_mcbsp_set_spi_mode(unsigned int id,\r
- {\r
-       struct omap_mcbsp_reg_cfg mcbsp_cfg;\r
\r
--      if (omap_mcbsp_check(id) < 0)\r
-+      if (!omap_mcbsp_check_valid_id(id)) {\r
-+              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);\r
-               return;\r
-+      }\r
\r
-       memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));\r
\r
-@@ -871,182 +804,91 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);\r
-  * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.\r
-  * 730 has only 2 McBSP, and both of them are MPU peripherals.\r
-  */\r
--struct omap_mcbsp_info {\r
--      u32 virt_base;\r
--      u8 dma_rx_sync, dma_tx_sync;\r
--      u16 rx_irq, tx_irq;\r
--};\r
-+static int __init omap_mcbsp_probe(struct platform_device *pdev)\r
-+{\r
-+      struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;\r
-+      int id = pdev->id - 1;\r
-+      int ret = 0;\r
-+      int i;\r
\r
--#ifdef CONFIG_ARCH_OMAP730\r
--static const struct omap_mcbsp_info mcbsp_730[] = {\r
--      [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),\r
--              .dma_rx_sync = OMAP_DMA_MCBSP1_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP1_TX,\r
--              .rx_irq = INT_730_McBSP1RX,\r
--              .tx_irq = INT_730_McBSP1TX },\r
--      [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),\r
--              .dma_rx_sync = OMAP_DMA_MCBSP3_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP3_TX,\r
--              .rx_irq = INT_730_McBSP2RX,\r
--              .tx_irq = INT_730_McBSP2TX },\r
--};\r
--#endif\r
--\r
--#ifdef CONFIG_ARCH_OMAP15XX\r
--static const struct omap_mcbsp_info mcbsp_1510[] = {\r
--      [0] = { .virt_base = OMAP1510_MCBSP1_BASE,\r
--              .dma_rx_sync = OMAP_DMA_MCBSP1_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP1_TX,\r
--              .rx_irq = INT_McBSP1RX,\r
--              .tx_irq = INT_McBSP1TX },\r
--      [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),\r
--              .dma_rx_sync = OMAP_DMA_MCBSP2_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP2_TX,\r
--              .rx_irq = INT_1510_SPI_RX,\r
--              .tx_irq = INT_1510_SPI_TX },\r
--      [2] = { .virt_base = OMAP1510_MCBSP3_BASE,\r
--              .dma_rx_sync = OMAP_DMA_MCBSP3_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP3_TX,\r
--              .rx_irq = INT_McBSP3RX,\r
--              .tx_irq = INT_McBSP3TX },\r
--};\r
--#endif\r
--\r
--#if defined(CONFIG_ARCH_OMAP16XX)\r
--static const struct omap_mcbsp_info mcbsp_1610[] = {\r
--      [0] = { .virt_base = OMAP1610_MCBSP1_BASE,\r
--              .dma_rx_sync = OMAP_DMA_MCBSP1_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP1_TX,\r
--              .rx_irq = INT_McBSP1RX,\r
--              .tx_irq = INT_McBSP1TX },\r
--      [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),\r
--              .dma_rx_sync = OMAP_DMA_MCBSP2_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP2_TX,\r
--              .rx_irq = INT_1610_McBSP2_RX,\r
--              .tx_irq = INT_1610_McBSP2_TX },\r
--      [2] = { .virt_base = OMAP1610_MCBSP3_BASE,\r
--              .dma_rx_sync = OMAP_DMA_MCBSP3_RX,\r
--              .dma_tx_sync = OMAP_DMA_MCBSP3_TX,\r
--              .rx_irq = INT_McBSP3RX,\r
--              .tx_irq = INT_McBSP3TX },\r
--};\r
--#endif\r
--\r
--#if defined(CONFIG_ARCH_OMAP24XX)\r
--static const struct omap_mcbsp_info mcbsp_24xx[] = {\r
--      [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),\r
--              .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,\r
--              .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,\r
--              .rx_irq = INT_24XX_MCBSP1_IRQ_RX,\r
--              .tx_irq = INT_24XX_MCBSP1_IRQ_TX,\r
--              },\r
--      [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),\r
--              .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,\r
--              .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,\r
--              .rx_irq = INT_24XX_MCBSP2_IRQ_RX,\r
--              .tx_irq = INT_24XX_MCBSP2_IRQ_TX,\r
--              },\r
--};\r
--#endif\r
-+      if (!pdata) {\r
-+              dev_err(&pdev->dev, "McBSP device initialized without"\r
-+                              "platform data\n");\r
-+              ret = -EINVAL;\r
-+              goto exit;\r
-+      }\r
\r
--static int __init omap_mcbsp_init(void)\r
-+      dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);\r
-+\r
-+      if (id >= OMAP_MAX_MCBSP_COUNT) {\r
-+              dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);\r
-+              ret = -EINVAL;\r
-+              goto exit;\r
-+      }\r
-+\r
-+      spin_lock_init(&mcbsp[id].lock);\r
-+      mcbsp[id].id = id + 1;\r
-+      mcbsp[id].free = 1;\r
-+      mcbsp[id].dma_tx_lch = -1;\r
-+      mcbsp[id].dma_rx_lch = -1;\r
-+\r
-+      mcbsp[id].io_base = pdata->virt_base;\r
-+      /* Default I/O is IRQ based */\r
-+      mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;\r
-+      mcbsp[id].tx_irq = pdata->tx_irq;\r
-+      mcbsp[id].rx_irq = pdata->rx_irq;\r
-+      mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;\r
-+      mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;\r
-+\r
-+      mcbsp[id].nr_clocks = ARRAY_SIZE(pdata->clocks);\r
-+      for (i = 0; i < ARRAY_SIZE(pdata->clocks); i++)\r
-+              mcbsp[id].clocks[i] = clk_get(&pdev->dev, pdata->clocks[i]);\r
-+\r
-+      mcbsp[id].pdata = pdata;\r
-+      mcbsp[id].dev = &pdev->dev;\r
-+      platform_set_drvdata(pdev, &mcbsp[id]);\r
-+\r
-+exit:\r
-+      return ret;\r
-+}\r
-+\r
-+static int omap_mcbsp_remove(struct platform_device *pdev)\r
- {\r
--      int mcbsp_count = 0, i;\r
--      static const struct omap_mcbsp_info *mcbsp_info;\r
-+      struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);\r
\r
--      printk(KERN_INFO "Initializing OMAP McBSP system\n");\r
-+      platform_set_drvdata(pdev, NULL);\r
-+      if (mcbsp) {\r
-+              int i;\r
\r
--#ifdef CONFIG_ARCH_OMAP1\r
--      mcbsp_dsp_ck = clk_get(0, "dsp_ck");\r
--      if (IS_ERR(mcbsp_dsp_ck)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");\r
--              return PTR_ERR(mcbsp_dsp_ck);\r
--      }\r
--      mcbsp_api_ck = clk_get(0, "api_ck");\r
--      if (IS_ERR(mcbsp_api_ck)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");\r
--              return PTR_ERR(mcbsp_api_ck);\r
--      }\r
--      mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");\r
--      if (IS_ERR(mcbsp_dspxor_ck)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");\r
--              return PTR_ERR(mcbsp_dspxor_ck);\r
--      }\r
--#endif\r
--#ifdef CONFIG_ARCH_OMAP2\r
--      mcbsp1_ick = clk_get(0, "mcbsp1_ick");\r
--      if (IS_ERR(mcbsp1_ick)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire "\r
--                              "mcbsp1_ick handle.\n");\r
--              return PTR_ERR(mcbsp1_ick);\r
--      }\r
--      mcbsp1_fck = clk_get(0, "mcbsp1_fck");\r
--      if (IS_ERR(mcbsp1_fck)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire "\r
--                              "mcbsp1_fck handle.\n");\r
--              return PTR_ERR(mcbsp1_fck);\r
--      }\r
--      mcbsp2_ick = clk_get(0, "mcbsp2_ick");\r
--      if (IS_ERR(mcbsp2_ick)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire "\r
--                              "mcbsp2_ick handle.\n");\r
--              return PTR_ERR(mcbsp2_ick);\r
--      }\r
--      mcbsp2_fck = clk_get(0, "mcbsp2_fck");\r
--      if (IS_ERR(mcbsp2_fck)) {\r
--              printk(KERN_ERR "mcbsp: could not acquire "\r
--                              "mcbsp2_fck handle.\n");\r
--              return PTR_ERR(mcbsp2_fck);\r
--      }\r
--#endif\r
-+              if (mcbsp->pdata && mcbsp->pdata->ops &&\r
-+                              mcbsp->pdata->ops->free)\r
-+                      mcbsp->pdata->ops->free(mcbsp->id);\r
\r
--#ifdef CONFIG_ARCH_OMAP730\r
--      if (cpu_is_omap730()) {\r
--              mcbsp_info = mcbsp_730;\r
--              mcbsp_count = ARRAY_SIZE(mcbsp_730);\r
--      }\r
--#endif\r
--#ifdef CONFIG_ARCH_OMAP15XX\r
--      if (cpu_is_omap15xx()) {\r
--              mcbsp_info = mcbsp_1510;\r
--              mcbsp_count = ARRAY_SIZE(mcbsp_1510);\r
--      }\r
--#endif\r
--#if defined(CONFIG_ARCH_OMAP16XX)\r
--      if (cpu_is_omap16xx()) {\r
--              mcbsp_info = mcbsp_1610;\r
--              mcbsp_count = ARRAY_SIZE(mcbsp_1610);\r
--      }\r
--#endif\r
--#if defined(CONFIG_ARCH_OMAP24XX)\r
--      if (cpu_is_omap24xx()) {\r
--              mcbsp_info = mcbsp_24xx;\r
--              mcbsp_count = ARRAY_SIZE(mcbsp_24xx);\r
--              omap2_mcbsp2_mux_setup();\r
--      }\r
--#endif\r
--      for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {\r
--              if (i >= mcbsp_count) {\r
--                      mcbsp[i].io_base = 0;\r
--                      mcbsp[i].free = 0;\r
--                      continue;\r
--              }\r
--              mcbsp[i].id = i + 1;\r
--              mcbsp[i].free = 1;\r
--              mcbsp[i].dma_tx_lch = -1;\r
--              mcbsp[i].dma_rx_lch = -1;\r
--\r
--              mcbsp[i].io_base = mcbsp_info[i].virt_base;\r
--              /* Default I/O is IRQ based */\r
--              mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO;\r
--              mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;\r
--              mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;\r
--              mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;\r
--              mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;\r
--              spin_lock_init(&mcbsp[i].lock);\r
-+              mcbsp_clk_disable(mcbsp);\r
-+              mcbsp_clk_put(mcbsp);\r
-+\r
-+              for (i = 0; i < mcbsp->nr_clocks; i++)\r
-+                      mcbsp->clocks[i] = NULL;\r
-+\r
-+              mcbsp->free = 0;\r
-+              mcbsp->dev = NULL;\r
-       }\r
\r
-       return 0;\r
- }\r
\r
--arch_initcall(omap_mcbsp_init);\r
-+static struct platform_driver omap_mcbsp_driver = {\r
-+      .probe          = omap_mcbsp_probe,\r
-+      .remove         = omap_mcbsp_remove,\r
-+      .driver         = {\r
-+              .name   = "omap-mcbsp",\r
-+      },\r
-+};\r
-+\r
-+int __init omap_mcbsp_init(void)\r
-+{\r
-+      /* Register the McBSP driver */\r
-+      return platform_driver_register(&omap_mcbsp_driver);\r
-+}\r
-+\r
-+\r
-diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h\r
-index b53c3b2..aa47421 100644\r
---- a/include/asm-arm/arch-omap/mcbsp.h\r
-+++ b/include/asm-arm/arch-omap/mcbsp.h\r
-@@ -24,7 +24,11 @@\r
- #ifndef __ASM_ARCH_OMAP_MCBSP_H\r
- #define __ASM_ARCH_OMAP_MCBSP_H\r
\r
-+#include <linux/completion.h>\r
-+#include <linux/spinlock.h>\r
-+\r
- #include <asm/hardware.h>\r
-+#include <asm/arch/clock.h>\r
\r
- #define OMAP730_MCBSP1_BASE   0xfffb1000\r
- #define OMAP730_MCBSP2_BASE   0xfffb1800\r
-@@ -40,6 +44,9 @@\r
- #define OMAP24XX_MCBSP1_BASE  0x48074000\r
- #define OMAP24XX_MCBSP2_BASE  0x48076000\r
\r
-+#define OMAP34XX_MCBSP1_BASE  0x48074000\r
-+#define OMAP34XX_MCBSP2_BASE  0x49022000\r
-+\r
- #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)\r
\r
- #define OMAP_MCBSP_REG_DRR2   0x00\r
-@@ -74,7 +81,8 @@\r
- #define OMAP_MCBSP_REG_XCERG  0x3A\r
- #define OMAP_MCBSP_REG_XCERH  0x3C\r
\r
--#define OMAP_MAX_MCBSP_COUNT 3\r
-+#define OMAP_MAX_MCBSP_COUNT  3\r
-+#define MAX_MCBSP_CLOCKS      3\r
\r
- #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)\r
- #define AUDIO_MCBSP_DATAREAD  (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)\r
-@@ -117,7 +125,8 @@\r
- #define OMAP_MCBSP_REG_XCERG  0x74\r
- #define OMAP_MCBSP_REG_XCERH  0x78\r
\r
--#define OMAP_MAX_MCBSP_COUNT 2\r
-+#define OMAP_MAX_MCBSP_COUNT  2\r
-+#define MAX_MCBSP_CLOCKS      2\r
\r
- #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)\r
- #define AUDIO_MCBSP_DATAREAD  (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)\r
-@@ -298,6 +307,66 @@ struct omap_mcbsp_spi_cfg {\r
-       omap_mcbsp_word_length          word_length;\r
- };\r
\r
-+/* Platform specific configuration */\r
-+struct omap_mcbsp_ops {\r
-+      void (*request)(unsigned int);\r
-+      void (*free)(unsigned int);\r
-+      int (*check)(unsigned int);\r
-+};\r
-+\r
-+struct omap_mcbsp_platform_data {\r
-+      u32 virt_base;\r
-+      u8 dma_rx_sync, dma_tx_sync;\r
-+      u16 rx_irq, tx_irq;\r
-+      struct omap_mcbsp_ops *ops;\r
-+      char const *clocks[MAX_MCBSP_CLOCKS];\r
-+};\r
-+\r
-+struct omap_mcbsp {\r
-+      struct device *dev;\r
-+      u32 io_base;\r
-+      u8 id;\r
-+      u8 free;\r
-+      omap_mcbsp_word_length rx_word_length;\r
-+      omap_mcbsp_word_length tx_word_length;\r
-+\r
-+      omap_mcbsp_io_type_t io_type; /* IRQ or poll */\r
-+      /* IRQ based TX/RX */\r
-+      int rx_irq;\r
-+      int tx_irq;\r
-+\r
-+      /* DMA stuff */\r
-+      u8 dma_rx_sync;\r
-+      short dma_rx_lch;\r
-+      u8 dma_tx_sync;\r
-+      short dma_tx_lch;\r
-+\r
-+      /* Completion queues */\r
-+      struct completion tx_irq_completion;\r
-+      struct completion rx_irq_completion;\r
-+      struct completion tx_dma_completion;\r
-+      struct completion rx_dma_completion;\r
-+\r
-+      /* Protect the field .free, while checking if the mcbsp is in use */\r
-+      spinlock_t lock;\r
-+      struct omap_mcbsp_platform_data *pdata;\r
-+      int nr_clocks;\r
-+      struct clk *clocks[MAX_MCBSP_CLOCKS];\r
-+};\r
-+\r
-+#define __mcbsp_clk_op(mcbsp, op)                             \\r
-+      do {                                                    \\r
-+              int i;                                          \\r
-+              for (i = 0; i < mcbsp->nr_clocks; i++)          \\r
-+                      clk_##op(mcbsp->clocks[i]);             \\r
-+      } while (0)\r
-+#define mcbsp_clk_enable(mcbsp)               __mcbsp_clk_op((mcbsp), enable)\r
-+#define mcbsp_clk_disable(mcbsp)      __mcbsp_clk_op((mcbsp), disable)\r
-+#define mcbsp_clk_put(mcbsp)          __mcbsp_clk_op((mcbsp), put)\r
-+\r
-+int omap_mcbsp_init(void);\r
-+void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,\r
-+                                      int size);\r
- void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);\r
- int omap_mcbsp_request(unsigned int id);\r
- void omap_mcbsp_free(unsigned int id);\r
--- \r
-1.5.5.1.67.gbdb8.dirty\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at  http://vger.kernel.org/majordomo-info.html\r
-\r
+From: Eduardo Valentin <eduardo.valentin@indt.org.br>
+
+This patch transform mcbsp code into a very initial
+implementation of a platform driver.
+
+It also gets ride of ifdefs on mcbsp.c code.
+To do it, a platform data structure was defined.
+
+Platform devices are located in arch/arm/plat-omap/devices.c
+
+Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>
+---
+ arch/arm/plat-omap/devices.c      |   45 +++
+ arch/arm/plat-omap/mcbsp.c        |  660 ++++++++++++++-----------------------
+ include/asm-arm/arch-omap/mcbsp.h |   73 ++++-
+ 3 files changed, 367 insertions(+), 411 deletions(-)
+
+diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
+index 099182b..b3e0147 100644
+--- a/arch/arm/plat-omap/devices.c
++++ b/arch/arm/plat-omap/devices.c
+@@ -27,6 +27,7 @@
+ #include <asm/arch/gpio.h>
+ #include <asm/arch/menelaus.h>
+ #include <asm/arch/dsp_common.h>
++#include <asm/arch/mcbsp.h>
+ #if   defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
+@@ -150,6 +151,49 @@ static inline void omap_init_kp(void) {}
+ #endif
+ /*-------------------------------------------------------------------------*/
++#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
++
++static struct platform_device omap_mcbsp_devices[OMAP_MAX_MCBSP_COUNT];
++static int mcbsps_configured;
++
++void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
++                                      int size)
++{
++      int i;
++
++      if (size > OMAP_MAX_MCBSP_COUNT) {
++              printk(KERN_WARNING "Registered too many McBSPs platform_data."
++                      " Using maximum (%d) available.\n",
++                      OMAP_MAX_MCBSP_COUNT);
++              size = OMAP_MAX_MCBSP_COUNT;
++      }
++
++      for (i = 0; i < size; i++) {
++              struct platform_device *new_mcbsp = &omap_mcbsp_devices[i];
++              new_mcbsp->name = "omap-mcbsp";
++              new_mcbsp->id = i + 1;
++              new_mcbsp->dev.platform_data = &config[i];
++      }
++      mcbsps_configured = size;
++}
++
++static void __init omap_init_mcbsp(void)
++{
++      int i;
++
++      for (i = 0; i < mcbsps_configured; i++)
++              platform_device_register(&omap_mcbsp_devices[i]);
++}
++#else
++void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
++                                      int size)
++{  }
++
++static inline void __init omap_init_mcbsp(void)
++{  }
++#endif
++
++/*-------------------------------------------------------------------------*/
+ #if   defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) \
+       || defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+@@ -511,6 +555,7 @@ static int __init omap_init_devices(void)
+        */
+       omap_init_dsp();
+       omap_init_kp();
++      omap_init_mcbsp();
+       omap_init_mmc();
+       omap_init_uwire();
+       omap_init_wdt();
+diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
+index 053de31..5536223 100644
+--- a/arch/arm/plat-omap/mcbsp.c
++++ b/arch/arm/plat-omap/mcbsp.c
+@@ -15,6 +15,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/device.h>
++#include <linux/platform_device.h>
+ #include <linux/wait.h>
+ #include <linux/completion.h>
+ #include <linux/interrupt.h>
+@@ -25,83 +26,53 @@
+ #include <linux/irq.h>
+ #include <asm/arch/dma.h>
+-#include <asm/arch/mux.h>
+-#include <asm/arch/irqs.h>
+-#include <asm/arch/dsp_common.h>
+ #include <asm/arch/mcbsp.h>
+-#ifdef CONFIG_MCBSP_DEBUG
+-#define DBG(x...)     printk(x)
+-#else
+-#define DBG(x...)                     do { } while (0)
+-#endif
+-
+-struct omap_mcbsp {
+-      u32                          io_base;
+-      u8                           id;
+-      u8                           free;
+-      omap_mcbsp_word_length       rx_word_length;
+-      omap_mcbsp_word_length       tx_word_length;
+-
+-      omap_mcbsp_io_type_t         io_type; /* IRQ or poll */
+-      /* IRQ based TX/RX */
+-      int                          rx_irq;
+-      int                          tx_irq;
+-
+-      /* DMA stuff */
+-      u8                           dma_rx_sync;
+-      short                        dma_rx_lch;
+-      u8                           dma_tx_sync;
+-      short                        dma_tx_lch;
+-
+-      /* Completion queues */
+-      struct completion            tx_irq_completion;
+-      struct completion            rx_irq_completion;
+-      struct completion            tx_dma_completion;
+-      struct completion            rx_dma_completion;
+-
+-      /* Protect the field .free, while checking if the mcbsp is in use */
+-      spinlock_t                   lock;
+-};
+-
+ static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
+-#ifdef CONFIG_ARCH_OMAP1
+-static struct clk *mcbsp_dsp_ck;
+-static struct clk *mcbsp_api_ck;
+-static struct clk *mcbsp_dspxor_ck;
+-#endif
+-#ifdef CONFIG_ARCH_OMAP2
+-static struct clk *mcbsp1_ick;
+-static struct clk *mcbsp1_fck;
+-static struct clk *mcbsp2_ick;
+-static struct clk *mcbsp2_fck;
+-#endif
++
++#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \
++                                      mcbsp[id].pdata->ops && \
++                                      mcbsp[id].pdata->ops->check && \
++                                      (mcbsp[id].pdata->ops->check(id) == 0))
+ static void omap_mcbsp_dump_reg(u8 id)
+ {
+-      DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
+-      DBG("DRR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
+-      DBG("DRR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
+-      DBG("DXR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
+-      DBG("DXR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
+-      DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
+-      DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
+-      DBG("RCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
+-      DBG("RCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
+-      DBG("XCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
+-      DBG("XCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
+-      DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
+-      DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
+-      DBG("PCR0:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
+-      DBG("***********************\n");
++      dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);
++      dev_dbg(mcbsp[id].dev, "DRR2:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
++      dev_dbg(mcbsp[id].dev, "DRR1:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
++      dev_dbg(mcbsp[id].dev, "DXR2:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
++      dev_dbg(mcbsp[id].dev, "DXR1:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
++      dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
++      dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
++      dev_dbg(mcbsp[id].dev, "RCR2:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
++      dev_dbg(mcbsp[id].dev, "RCR1:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
++      dev_dbg(mcbsp[id].dev, "XCR2:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
++      dev_dbg(mcbsp[id].dev, "XCR1:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
++      dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
++      dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
++      dev_dbg(mcbsp[id].dev, "PCR0:  0x%04x\n",
++                      OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
++      dev_dbg(mcbsp[id].dev, "***********************\n");
+ }
+ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
+ {
+       struct omap_mcbsp *mcbsp_tx = dev_id;
+-      DBG("TX IRQ callback : 0x%x\n",
+-          OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
++      dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n",
++              OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
+       complete(&mcbsp_tx->tx_irq_completion);
+@@ -112,8 +83,8 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
+ {
+       struct omap_mcbsp *mcbsp_rx = dev_id;
+-      DBG("RX IRQ callback : 0x%x\n",
+-          OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
++      dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n",
++              OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
+       complete(&mcbsp_rx->rx_irq_completion);
+@@ -124,8 +95,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
+ {
+       struct omap_mcbsp *mcbsp_dma_tx = data;
+-      DBG("TX DMA callback : 0x%x\n",
+-          OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
++      dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
++              OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
+       /* We can free the channels */
+       omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
+@@ -138,8 +109,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
+ {
+       struct omap_mcbsp *mcbsp_dma_rx = data;
+-      DBG("RX DMA callback : 0x%x\n",
+-          OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
++      dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
++              OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
+       /* We can free the channels */
+       omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
+@@ -156,9 +127,16 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
+  */
+ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
+ {
+-      u32 io_base = mcbsp[id].io_base;
++      u32 io_base;
++
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return;
++      }
+-      DBG("OMAP-McBSP: McBSP%d  io_base: 0x%8x\n", id + 1, io_base);
++      io_base = mcbsp[id].io_base;
++      dev_dbg(mcbsp[id].dev, "Configuring McBSP%d  io_base: 0x%8x\n",
++                      mcbsp[id].id, io_base);
+       /* We write the given config */
+       OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
+@@ -175,97 +153,22 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
+ }
+ EXPORT_SYMBOL(omap_mcbsp_config);
+-static int omap_mcbsp_check(unsigned int id)
+-{
+-      if (cpu_is_omap730()) {
+-              if (id > OMAP_MAX_MCBSP_COUNT - 1) {
+-                     printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
+-                              id + 1);
+-                     return -1;
+-              }
+-              return 0;
+-      }
+-
+-      if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
+-              if (id > OMAP_MAX_MCBSP_COUNT) {
+-                      printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
+-                              id + 1);
+-                      return -1;
+-              }
+-              return 0;
+-      }
+-
+-      return -1;
+-}
+-
+-#ifdef CONFIG_ARCH_OMAP1
+-static void omap_mcbsp_dsp_request(void)
+-{
+-      if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+-              int ret;
+-
+-              ret = omap_dsp_request_mem();
+-              if (ret < 0) {
+-                      printk(KERN_ERR "Could not get dsp memory: %i\n", ret);
+-                      return;
+-              }
+-
+-              clk_enable(mcbsp_dsp_ck);
+-              clk_enable(mcbsp_api_ck);
+-
+-              /* enable 12MHz clock to mcbsp 1 & 3 */
+-              clk_enable(mcbsp_dspxor_ck);
+-
+-              /*
+-               * DSP external peripheral reset
+-               * FIXME: This should be moved to dsp code
+-               */
+-              __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
+-                           DSP_RSTCT2);
+-      }
+-}
+-
+-static void omap_mcbsp_dsp_free(void)
+-{
+-      if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+-              omap_dsp_release_mem();
+-              clk_disable(mcbsp_dspxor_ck);
+-              clk_disable(mcbsp_dsp_ck);
+-              clk_disable(mcbsp_api_ck);
+-      }
+-}
+-#endif
+-
+-#ifdef CONFIG_ARCH_OMAP2
+-static void omap2_mcbsp2_mux_setup(void)
+-{
+-      if (cpu_is_omap2420()) {
+-              omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
+-              omap_cfg_reg(R14_24XX_MCBSP2_FSX);
+-              omap_cfg_reg(W15_24XX_MCBSP2_DR);
+-              omap_cfg_reg(V15_24XX_MCBSP2_DX);
+-              omap_cfg_reg(V14_24XX_GPIO117);
+-      }
+-      /*
+-       * Need to add MUX settings for OMAP 2430 SDP
+-       */
+-}
+-#endif
+-
+ /*
+  * We can choose between IRQ based or polled IO.
+  * This needs to be called before omap_mcbsp_request().
+  */
+ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
+ {
+-      if (omap_mcbsp_check(id) < 0)
+-              return -EINVAL;
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
+       spin_lock(&mcbsp[id].lock);
+       if (!mcbsp[id].free) {
+-              printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n",
+-                      id + 1);
++              dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
++                      mcbsp[id].id);
+               spin_unlock(&mcbsp[id].lock);
+               return -EINVAL;
+       }
+@@ -282,34 +185,20 @@ int omap_mcbsp_request(unsigned int id)
+ {
+       int err;
+-      if (omap_mcbsp_check(id) < 0)
+-              return -EINVAL;
+-
+-#ifdef CONFIG_ARCH_OMAP1
+-      /*
+-       * On 1510, 1610 and 1710, McBSP1 and McBSP3
+-       * are DSP public peripherals.
+-       */
+-      if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+-              omap_mcbsp_dsp_request();
+-#endif
+-
+-#ifdef CONFIG_ARCH_OMAP2
+-      if (cpu_is_omap24xx()) {
+-              if (id == OMAP_MCBSP1) {
+-                      clk_enable(mcbsp1_ick);
+-                      clk_enable(mcbsp1_fck);
+-              } else {
+-                      clk_enable(mcbsp2_ick);
+-                      clk_enable(mcbsp2_fck);
+-              }
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
+       }
+-#endif
++
++      if (mcbsp[id].pdata->ops->request)
++              mcbsp[id].pdata->ops->request(id);
++
++      mcbsp_clk_enable(&mcbsp[id]);
+       spin_lock(&mcbsp[id].lock);
+       if (!mcbsp[id].free) {
+-              printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n",
+-                      id + 1);
++              dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
++                      mcbsp[id].id);
+               spin_unlock(&mcbsp[id].lock);
+               return -1;
+       }
+@@ -322,9 +211,9 @@ int omap_mcbsp_request(unsigned int id)
+               err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,
+                                       0, "McBSP", (void *) (&mcbsp[id]));
+               if (err != 0) {
+-                      printk(KERN_ERR "OMAP-McBSP: Unable to "
+-                                      "request TX IRQ %d for McBSP%d\n",
+-                                      mcbsp[id].tx_irq, mcbsp[id].id);
++                      dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "
++                                      "for McBSP%d\n", mcbsp[id].tx_irq,
++                                      mcbsp[id].id);
+                       return err;
+               }
+@@ -333,9 +222,9 @@ int omap_mcbsp_request(unsigned int id)
+               err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,
+                                       0, "McBSP", (void *) (&mcbsp[id]));
+               if (err != 0) {
+-                      printk(KERN_ERR "OMAP-McBSP: Unable to "
+-                                      "request RX IRQ %d for McBSP%d\n",
+-                                      mcbsp[id].rx_irq, mcbsp[id].id);
++                      dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "
++                                      "for McBSP%d\n", mcbsp[id].rx_irq,
++                                      mcbsp[id].id);
+                       free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+                       return err;
+               }
+@@ -349,32 +238,20 @@ EXPORT_SYMBOL(omap_mcbsp_request);
+ void omap_mcbsp_free(unsigned int id)
+ {
+-      if (omap_mcbsp_check(id) < 0)
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return;
+-
+-#ifdef CONFIG_ARCH_OMAP1
+-      if (cpu_class_is_omap1()) {
+-              if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+-                      omap_mcbsp_dsp_free();
+       }
+-#endif
+-
+-#ifdef CONFIG_ARCH_OMAP2
+-      if (cpu_is_omap24xx()) {
+-              if (id == OMAP_MCBSP1) {
+-                      clk_disable(mcbsp1_ick);
+-                      clk_disable(mcbsp1_fck);
+-              } else {
+-                      clk_disable(mcbsp2_ick);
+-                      clk_disable(mcbsp2_fck);
+-              }
+-      }
+-#endif
++
++      if (mcbsp[id].pdata->ops->free)
++              mcbsp[id].pdata->ops->free(id);
++
++      mcbsp_clk_disable(&mcbsp[id]);
+       spin_lock(&mcbsp[id].lock);
+       if (mcbsp[id].free) {
+-              printk(KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n",
+-                      id + 1);
++              dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",
++                      mcbsp[id].id);
+               spin_unlock(&mcbsp[id].lock);
+               return;
+       }
+@@ -400,8 +277,10 @@ void omap_mcbsp_start(unsigned int id)
+       u32 io_base;
+       u16 w;
+-      if (omap_mcbsp_check(id) < 0)
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return;
++      }
+       io_base = mcbsp[id].io_base;
+@@ -435,8 +314,10 @@ void omap_mcbsp_stop(unsigned int id)
+       u32 io_base;
+       u16 w;
+-      if (omap_mcbsp_check(id) < 0)
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return;
++      }
+       io_base = mcbsp[id].io_base;
+@@ -457,7 +338,14 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
+ /* polled mcbsp i/o operations */
+ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
+ {
+-      u32 base = mcbsp[id].io_base;
++      u32 base;
++
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
++
++      base = mcbsp[id].io_base;
+       writew(buf, base + OMAP_MCBSP_REG_DXR1);
+       /* if frame sync error - clear the error */
+       if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
+@@ -479,8 +367,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
+                                      (XRST),
+                                      base + OMAP_MCBSP_REG_SPCR2);
+                               udelay(10);
+-                              printk(KERN_ERR
+-                                     " Could not write to McBSP Register\n");
++                              dev_err(mcbsp[id].dev, "Could not write to"
++                                      " McBSP%d Register\n", mcbsp[id].id);
+                               return -2;
+                       }
+               }
+@@ -492,7 +380,14 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
+ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
+ {
+-      u32 base = mcbsp[id].io_base;
++      u32 base;
++
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
++
++      base = mcbsp[id].io_base;
+       /* if frame sync error - clear the error */
+       if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
+               /* clear error */
+@@ -513,8 +408,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
+                                      (RRST),
+                                      base + OMAP_MCBSP_REG_SPCR1);
+                               udelay(10);
+-                              printk(KERN_ERR
+-                                     " Could not read from McBSP Register\n");
++                              dev_err(mcbsp[id].dev, "Could not read from"
++                                      " McBSP%d Register\n", mcbsp[id].id);
+                               return -2;
+                       }
+               }
+@@ -531,12 +426,15 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
+ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
+ {
+       u32 io_base;
+-      omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
++      omap_mcbsp_word_length word_length;
+-      if (omap_mcbsp_check(id) < 0)
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return;
++      }
+       io_base = mcbsp[id].io_base;
++      word_length = mcbsp[id].tx_word_length;
+       wait_for_completion(&(mcbsp[id].tx_irq_completion));
+@@ -550,11 +448,14 @@ u32 omap_mcbsp_recv_word(unsigned int id)
+ {
+       u32 io_base;
+       u16 word_lsb, word_msb = 0;
+-      omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
++      omap_mcbsp_word_length word_length;
+-      if (omap_mcbsp_check(id) < 0)
+-              return -EINVAL;
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
++      word_length = mcbsp[id].rx_word_length;
+       io_base = mcbsp[id].io_base;
+       wait_for_completion(&(mcbsp[id].rx_irq_completion));
+@@ -569,11 +470,20 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
+ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
+ {
+-      u32 io_base = mcbsp[id].io_base;
+-      omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
+-      omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
++      u32 io_base;
++      omap_mcbsp_word_length tx_word_length;
++      omap_mcbsp_word_length rx_word_length;
+       u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
++
++      io_base = mcbsp[id].io_base;
++      tx_word_length = mcbsp[id].tx_word_length;
++      rx_word_length = mcbsp[id].rx_word_length;
++
+       if (tx_word_length != rx_word_length)
+               return -EINVAL;
+@@ -587,7 +497,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
+                       udelay(10);
+                       OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
+                       udelay(10);
+-                      printk(KERN_ERR "McBSP transmitter not ready\n");
++                      dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
++                              "ready\n", mcbsp[id].id);
+                       return -EAGAIN;
+               }
+       }
+@@ -607,7 +518,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
+                       udelay(10);
+                       OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
+                       udelay(10);
+-                      printk(KERN_ERR "McBSP receiver not ready\n");
++                      dev_err(mcbsp[id].dev, "McBSP%d receiver not "
++                              "ready\n", mcbsp[id].id);
+                       return -EAGAIN;
+               }
+       }
+@@ -623,11 +535,20 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
+ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
+ {
+-      u32 io_base = mcbsp[id].io_base, clock_word = 0;
+-      omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
+-      omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
++      u32 io_base, clock_word = 0;
++      omap_mcbsp_word_length tx_word_length;
++      omap_mcbsp_word_length rx_word_length;
+       u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
++
++      io_base = mcbsp[id].io_base;
++      tx_word_length = mcbsp[id].tx_word_length;
++      rx_word_length = mcbsp[id].rx_word_length;
++
+       if (tx_word_length != rx_word_length)
+               return -EINVAL;
+@@ -641,7 +562,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
+                       udelay(10);
+                       OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
+                       udelay(10);
+-                      printk(KERN_ERR "McBSP transmitter not ready\n");
++                      dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
++                              "ready\n", mcbsp[id].id);
+                       return -EAGAIN;
+               }
+       }
+@@ -661,7 +583,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
+                       udelay(10);
+                       OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
+                       udelay(10);
+-                      printk(KERN_ERR "McBSP receiver not ready\n");
++                      dev_err(mcbsp[id].dev, "McBSP%d receiver not "
++                              "ready\n", mcbsp[id].id);
+                       return -EAGAIN;
+               }
+       }
+@@ -692,20 +615,24 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
+       int dest_port = 0;
+       int sync_dev = 0;
+-      if (omap_mcbsp_check(id) < 0)
+-              return -EINVAL;
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
+       if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",
+                               omap_mcbsp_tx_dma_callback,
+                               &mcbsp[id],
+                               &dma_tx_ch)) {
+-              printk(KERN_ERR "OMAP-McBSP: Unable to request DMA channel for"
+-                              " McBSP%d TX. Trying IRQ based TX\n", id + 1);
++              dev_err(mcbsp[id].dev, " Unable to request DMA channel for "
++                              "McBSP%d TX. Trying IRQ based TX\n",
++                              mcbsp[id].id);
+               return -EAGAIN;
+       }
+       mcbsp[id].dma_tx_lch = dma_tx_ch;
+-      DBG("TX DMA on channel %d\n", dma_tx_ch);
++      dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,
++              dma_tx_ch);
+       init_completion(&(mcbsp[id].tx_dma_completion));
+@@ -713,7 +640,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
+               src_port = OMAP_DMA_PORT_TIPB;
+               dest_port = OMAP_DMA_PORT_EMIFF;
+       }
+-      if (cpu_is_omap24xx())
++      if (cpu_class_is_omap2())
+               sync_dev = mcbsp[id].dma_tx_sync;
+       omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
+@@ -749,20 +676,24 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
+       int dest_port = 0;
+       int sync_dev = 0;
+-      if (omap_mcbsp_check(id) < 0)
+-              return -EINVAL;
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
++              return -ENODEV;
++      }
+       if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",
+                               omap_mcbsp_rx_dma_callback,
+                               &mcbsp[id],
+                               &dma_rx_ch)) {
+-              printk(KERN_ERR "Unable to request DMA channel for McBSP%d RX."
+-                              " Trying IRQ based RX\n", id + 1);
++              dev_err(mcbsp[id].dev, "Unable to request DMA channel for "
++                              "McBSP%d RX. Trying IRQ based RX\n",
++                              mcbsp[id].id);
+               return -EAGAIN;
+       }
+       mcbsp[id].dma_rx_lch = dma_rx_ch;
+-      DBG("RX DMA on channel %d\n", dma_rx_ch);
++      dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,
++              dma_rx_ch);
+       init_completion(&(mcbsp[id].rx_dma_completion));
+@@ -770,7 +701,7 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
+               src_port = OMAP_DMA_PORT_TIPB;
+               dest_port = OMAP_DMA_PORT_EMIFF;
+       }
+-      if (cpu_is_omap24xx())
++      if (cpu_class_is_omap2())
+               sync_dev = mcbsp[id].dma_rx_sync;
+       omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
+@@ -809,8 +740,10 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
+ {
+       struct omap_mcbsp_reg_cfg mcbsp_cfg;
+-      if (omap_mcbsp_check(id) < 0)
++      if (!omap_mcbsp_check_valid_id(id)) {
++              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+               return;
++      }
+       memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
+@@ -871,182 +804,91 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
+  * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
+  * 730 has only 2 McBSP, and both of them are MPU peripherals.
+  */
+-struct omap_mcbsp_info {
+-      u32 virt_base;
+-      u8 dma_rx_sync, dma_tx_sync;
+-      u16 rx_irq, tx_irq;
+-};
++static int __init omap_mcbsp_probe(struct platform_device *pdev)
++{
++      struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
++      int id = pdev->id - 1;
++      int ret = 0;
++      int i;
+-#ifdef CONFIG_ARCH_OMAP730
+-static const struct omap_mcbsp_info mcbsp_730[] = {
+-      [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
+-              .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+-              .rx_irq = INT_730_McBSP1RX,
+-              .tx_irq = INT_730_McBSP1TX },
+-      [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
+-              .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+-              .rx_irq = INT_730_McBSP2RX,
+-              .tx_irq = INT_730_McBSP2TX },
+-};
+-#endif
+-
+-#ifdef CONFIG_ARCH_OMAP15XX
+-static const struct omap_mcbsp_info mcbsp_1510[] = {
+-      [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
+-              .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+-              .rx_irq = INT_McBSP1RX,
+-              .tx_irq = INT_McBSP1TX },
+-      [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
+-              .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+-              .rx_irq = INT_1510_SPI_RX,
+-              .tx_irq = INT_1510_SPI_TX },
+-      [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
+-              .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+-              .rx_irq = INT_McBSP3RX,
+-              .tx_irq = INT_McBSP3TX },
+-};
+-#endif
+-
+-#if defined(CONFIG_ARCH_OMAP16XX)
+-static const struct omap_mcbsp_info mcbsp_1610[] = {
+-      [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
+-              .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+-              .rx_irq = INT_McBSP1RX,
+-              .tx_irq = INT_McBSP1TX },
+-      [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
+-              .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+-              .rx_irq = INT_1610_McBSP2_RX,
+-              .tx_irq = INT_1610_McBSP2_TX },
+-      [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
+-              .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+-              .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+-              .rx_irq = INT_McBSP3RX,
+-              .tx_irq = INT_McBSP3TX },
+-};
+-#endif
+-
+-#if defined(CONFIG_ARCH_OMAP24XX)
+-static const struct omap_mcbsp_info mcbsp_24xx[] = {
+-      [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
+-              .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
+-              .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
+-              .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
+-              .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
+-              },
+-      [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
+-              .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
+-              .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
+-              .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
+-              .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
+-              },
+-};
+-#endif
++      if (!pdata) {
++              dev_err(&pdev->dev, "McBSP device initialized without"
++                              "platform data\n");
++              ret = -EINVAL;
++              goto exit;
++      }
+-static int __init omap_mcbsp_init(void)
++      dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
++
++      if (id >= OMAP_MAX_MCBSP_COUNT) {
++              dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
++              ret = -EINVAL;
++              goto exit;
++      }
++
++      spin_lock_init(&mcbsp[id].lock);
++      mcbsp[id].id = id + 1;
++      mcbsp[id].free = 1;
++      mcbsp[id].dma_tx_lch = -1;
++      mcbsp[id].dma_rx_lch = -1;
++
++      mcbsp[id].io_base = pdata->virt_base;
++      /* Default I/O is IRQ based */
++      mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;
++      mcbsp[id].tx_irq = pdata->tx_irq;
++      mcbsp[id].rx_irq = pdata->rx_irq;
++      mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;
++      mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;
++
++      mcbsp[id].nr_clocks = ARRAY_SIZE(pdata->clocks);
++      for (i = 0; i < ARRAY_SIZE(pdata->clocks); i++)
++              mcbsp[id].clocks[i] = clk_get(&pdev->dev, pdata->clocks[i]);
++
++      mcbsp[id].pdata = pdata;
++      mcbsp[id].dev = &pdev->dev;
++      platform_set_drvdata(pdev, &mcbsp[id]);
++
++exit:
++      return ret;
++}
++
++static int omap_mcbsp_remove(struct platform_device *pdev)
+ {
+-      int mcbsp_count = 0, i;
+-      static const struct omap_mcbsp_info *mcbsp_info;
++      struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
+-      printk(KERN_INFO "Initializing OMAP McBSP system\n");
++      platform_set_drvdata(pdev, NULL);
++      if (mcbsp) {
++              int i;
+-#ifdef CONFIG_ARCH_OMAP1
+-      mcbsp_dsp_ck = clk_get(0, "dsp_ck");
+-      if (IS_ERR(mcbsp_dsp_ck)) {
+-              printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
+-              return PTR_ERR(mcbsp_dsp_ck);
+-      }
+-      mcbsp_api_ck = clk_get(0, "api_ck");
+-      if (IS_ERR(mcbsp_api_ck)) {
+-              printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
+-              return PTR_ERR(mcbsp_api_ck);
+-      }
+-      mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
+-      if (IS_ERR(mcbsp_dspxor_ck)) {
+-              printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
+-              return PTR_ERR(mcbsp_dspxor_ck);
+-      }
+-#endif
+-#ifdef CONFIG_ARCH_OMAP2
+-      mcbsp1_ick = clk_get(0, "mcbsp1_ick");
+-      if (IS_ERR(mcbsp1_ick)) {
+-              printk(KERN_ERR "mcbsp: could not acquire "
+-                              "mcbsp1_ick handle.\n");
+-              return PTR_ERR(mcbsp1_ick);
+-      }
+-      mcbsp1_fck = clk_get(0, "mcbsp1_fck");
+-      if (IS_ERR(mcbsp1_fck)) {
+-              printk(KERN_ERR "mcbsp: could not acquire "
+-                              "mcbsp1_fck handle.\n");
+-              return PTR_ERR(mcbsp1_fck);
+-      }
+-      mcbsp2_ick = clk_get(0, "mcbsp2_ick");
+-      if (IS_ERR(mcbsp2_ick)) {
+-              printk(KERN_ERR "mcbsp: could not acquire "
+-                              "mcbsp2_ick handle.\n");
+-              return PTR_ERR(mcbsp2_ick);
+-      }
+-      mcbsp2_fck = clk_get(0, "mcbsp2_fck");
+-      if (IS_ERR(mcbsp2_fck)) {
+-              printk(KERN_ERR "mcbsp: could not acquire "
+-                              "mcbsp2_fck handle.\n");
+-              return PTR_ERR(mcbsp2_fck);
+-      }
+-#endif
++              if (mcbsp->pdata && mcbsp->pdata->ops &&
++                              mcbsp->pdata->ops->free)
++                      mcbsp->pdata->ops->free(mcbsp->id);
+-#ifdef CONFIG_ARCH_OMAP730
+-      if (cpu_is_omap730()) {
+-              mcbsp_info = mcbsp_730;
+-              mcbsp_count = ARRAY_SIZE(mcbsp_730);
+-      }
+-#endif
+-#ifdef CONFIG_ARCH_OMAP15XX
+-      if (cpu_is_omap15xx()) {
+-              mcbsp_info = mcbsp_1510;
+-              mcbsp_count = ARRAY_SIZE(mcbsp_1510);
+-      }
+-#endif
+-#if defined(CONFIG_ARCH_OMAP16XX)
+-      if (cpu_is_omap16xx()) {
+-              mcbsp_info = mcbsp_1610;
+-              mcbsp_count = ARRAY_SIZE(mcbsp_1610);
+-      }
+-#endif
+-#if defined(CONFIG_ARCH_OMAP24XX)
+-      if (cpu_is_omap24xx()) {
+-              mcbsp_info = mcbsp_24xx;
+-              mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
+-              omap2_mcbsp2_mux_setup();
+-      }
+-#endif
+-      for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
+-              if (i >= mcbsp_count) {
+-                      mcbsp[i].io_base = 0;
+-                      mcbsp[i].free = 0;
+-                      continue;
+-              }
+-              mcbsp[i].id = i + 1;
+-              mcbsp[i].free = 1;
+-              mcbsp[i].dma_tx_lch = -1;
+-              mcbsp[i].dma_rx_lch = -1;
+-
+-              mcbsp[i].io_base = mcbsp_info[i].virt_base;
+-              /* Default I/O is IRQ based */
+-              mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO;
+-              mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
+-              mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
+-              mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
+-              mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
+-              spin_lock_init(&mcbsp[i].lock);
++              mcbsp_clk_disable(mcbsp);
++              mcbsp_clk_put(mcbsp);
++
++              for (i = 0; i < mcbsp->nr_clocks; i++)
++                      mcbsp->clocks[i] = NULL;
++
++              mcbsp->free = 0;
++              mcbsp->dev = NULL;
+       }
+       return 0;
+ }
+-arch_initcall(omap_mcbsp_init);
++static struct platform_driver omap_mcbsp_driver = {
++      .probe          = omap_mcbsp_probe,
++      .remove         = omap_mcbsp_remove,
++      .driver         = {
++              .name   = "omap-mcbsp",
++      },
++};
++
++int __init omap_mcbsp_init(void)
++{
++      /* Register the McBSP driver */
++      return platform_driver_register(&omap_mcbsp_driver);
++}
++
++
+diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h
+index b53c3b2..aa47421 100644
+--- a/include/asm-arm/arch-omap/mcbsp.h
++++ b/include/asm-arm/arch-omap/mcbsp.h
+@@ -24,7 +24,11 @@
+ #ifndef __ASM_ARCH_OMAP_MCBSP_H
+ #define __ASM_ARCH_OMAP_MCBSP_H
++#include <linux/completion.h>
++#include <linux/spinlock.h>
++
+ #include <asm/hardware.h>
++#include <asm/arch/clock.h>
+ #define OMAP730_MCBSP1_BASE   0xfffb1000
+ #define OMAP730_MCBSP2_BASE   0xfffb1800
+@@ -40,6 +44,9 @@
+ #define OMAP24XX_MCBSP1_BASE  0x48074000
+ #define OMAP24XX_MCBSP2_BASE  0x48076000
++#define OMAP34XX_MCBSP1_BASE  0x48074000
++#define OMAP34XX_MCBSP2_BASE  0x49022000
++
+ #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
+ #define OMAP_MCBSP_REG_DRR2   0x00
+@@ -74,7 +81,8 @@
+ #define OMAP_MCBSP_REG_XCERG  0x3A
+ #define OMAP_MCBSP_REG_XCERH  0x3C
+-#define OMAP_MAX_MCBSP_COUNT 3
++#define OMAP_MAX_MCBSP_COUNT  3
++#define MAX_MCBSP_CLOCKS      3
+ #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
+ #define AUDIO_MCBSP_DATAREAD  (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
+@@ -117,7 +125,8 @@
+ #define OMAP_MCBSP_REG_XCERG  0x74
+ #define OMAP_MCBSP_REG_XCERH  0x78
+-#define OMAP_MAX_MCBSP_COUNT 2
++#define OMAP_MAX_MCBSP_COUNT  2
++#define MAX_MCBSP_CLOCKS      2
+ #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
+ #define AUDIO_MCBSP_DATAREAD  (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
+@@ -298,6 +307,66 @@ struct omap_mcbsp_spi_cfg {
+       omap_mcbsp_word_length          word_length;
+ };
++/* Platform specific configuration */
++struct omap_mcbsp_ops {
++      void (*request)(unsigned int);
++      void (*free)(unsigned int);
++      int (*check)(unsigned int);
++};
++
++struct omap_mcbsp_platform_data {
++      u32 virt_base;
++      u8 dma_rx_sync, dma_tx_sync;
++      u16 rx_irq, tx_irq;
++      struct omap_mcbsp_ops *ops;
++      char const *clocks[MAX_MCBSP_CLOCKS];
++};
++
++struct omap_mcbsp {
++      struct device *dev;
++      u32 io_base;
++      u8 id;
++      u8 free;
++      omap_mcbsp_word_length rx_word_length;
++      omap_mcbsp_word_length tx_word_length;
++
++      omap_mcbsp_io_type_t io_type; /* IRQ or poll */
++      /* IRQ based TX/RX */
++      int rx_irq;
++      int tx_irq;
++
++      /* DMA stuff */
++      u8 dma_rx_sync;
++      short dma_rx_lch;
++      u8 dma_tx_sync;
++      short dma_tx_lch;
++
++      /* Completion queues */
++      struct completion tx_irq_completion;
++      struct completion rx_irq_completion;
++      struct completion tx_dma_completion;
++      struct completion rx_dma_completion;
++
++      /* Protect the field .free, while checking if the mcbsp is in use */
++      spinlock_t lock;
++      struct omap_mcbsp_platform_data *pdata;
++      int nr_clocks;
++      struct clk *clocks[MAX_MCBSP_CLOCKS];
++};
++
++#define __mcbsp_clk_op(mcbsp, op)                             \
++      do {                                                    \
++              int i;                                          \
++              for (i = 0; i < mcbsp->nr_clocks; i++)          \
++                      clk_##op(mcbsp->clocks[i]);             \
++      } while (0)
++#define mcbsp_clk_enable(mcbsp)               __mcbsp_clk_op((mcbsp), enable)
++#define mcbsp_clk_disable(mcbsp)      __mcbsp_clk_op((mcbsp), disable)
++#define mcbsp_clk_put(mcbsp)          __mcbsp_clk_op((mcbsp), put)
++
++int omap_mcbsp_init(void);
++void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
++                                      int size);
+ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
+ int omap_mcbsp_request(unsigned int id);
+ void omap_mcbsp_free(unsigned int id);
+-- 
+1.5.5.1.67.gbdb8.dirty
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+
index 76246a9..cf7c0df 100644 (file)
-From: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
-\r
-This patch adds support for mach-omap1 based on current\r
-mcbsp platform driver.\r
-\r
-Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
----\r
- arch/arm/mach-omap1/Makefile |    2 +\r
- arch/arm/mach-omap1/mcbsp.c  |  165 ++++++++++++++++++++++++++++++++++++++++++\r
- 2 files changed, 167 insertions(+), 0 deletions(-)\r
- create mode 100644 arch/arm/mach-omap1/mcbsp.c\r
-\r
-diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile\r
-index 6ebf23b..09246a7 100644\r
---- a/arch/arm/mach-omap1/Makefile\r
-+++ b/arch/arm/mach-omap1/Makefile\r
-@@ -5,6 +5,8 @@\r
- # Common support\r
- obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o\r
\r
-+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o\r
-+\r
- obj-$(CONFIG_OMAP_MPU_TIMER)  += time.o\r
- obj-$(CONFIG_OMAP_32K_TIMER)  += timer32k.o\r
\r
-diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c\r
-new file mode 100644\r
-index 0000000..f30624a\r
---- /dev/null\r
-+++ b/arch/arm/mach-omap1/mcbsp.c\r
-@@ -0,0 +1,165 @@\r
-+/*\r
-+ * linux/arch/arm/mach-omap1/mcbsp.c\r
-+ *\r
-+ * Copyright (C) 2008 Instituto Nokia de Tecnologia\r
-+ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
-+ *\r
-+ * This program is free software; you can redistribute it and/or modify\r
-+ * it under the terms of the GNU General Public License version 2 as\r
-+ * published by the Free Software Foundation.\r
-+ *\r
-+ * Multichannel mode not supported.\r
-+ */\r
-+#include <linux/module.h>\r
-+#include <linux/init.h>\r
-+#include <linux/clk.h>\r
-+#include <linux/err.h>\r
-+#include <linux/io.h>\r
-+\r
-+#include <asm/arch/dma.h>\r
-+#include <asm/arch/mux.h>\r
-+#include <asm/arch/cpu.h>\r
-+#include <asm/arch/mcbsp.h>\r
-+#include <asm/arch/dsp_common.h>\r
-+\r
-+#define DPS_RSTCT2_PER_EN     (1 << 0)\r
-+#define DSP_RSTCT2_WD_PER_EN  (1 << 1)\r
-+\r
-+static int omap1_mcbsp_check(unsigned int id)\r
-+{\r
-+      /* REVISIT: Check correctly for number of registered McBSPs */\r
-+      if (cpu_is_omap730()) {\r
-+              if (id > OMAP_MAX_MCBSP_COUNT - 2) {\r
-+                     printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",\r
-+                              id + 1);\r
-+                     return -ENODEV;\r
-+              }\r
-+              return 0;\r
-+      }\r
-+\r
-+      if (cpu_is_omap15xx() || cpu_is_omap16xx()) {\r
-+              if (id > OMAP_MAX_MCBSP_COUNT - 1) {\r
-+                      printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",\r
-+                              id + 1);\r
-+                      return -ENODEV;\r
-+              }\r
-+              return 0;\r
-+      }\r
-+\r
-+      return -ENODEV;\r
-+}\r
-+\r
-+static void omap1_mcbsp_request(unsigned int id)\r
-+{\r
-+      /*\r
-+       * On 1510, 1610 and 1710, McBSP1 and McBSP3\r
-+       * are DSP public peripherals.\r
-+       */\r
-+      if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {\r
-+              omap_dsp_request_mem();\r
-+              /*\r
-+               * DSP external peripheral reset\r
-+               * FIXME: This should be moved to dsp code\r
-+               */\r
-+              __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |\r
-+                              DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);\r
-+      }\r
-+}\r
-+\r
-+static void omap1_mcbsp_free(unsigned int id)\r
-+{\r
-+      if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)\r
-+              omap_dsp_release_mem();\r
-+}\r
-+\r
-+static struct omap_mcbsp_ops omap1_mcbsp_ops = {\r
-+      .check          = omap1_mcbsp_check,\r
-+      .request        = omap1_mcbsp_request,\r
-+      .free           = omap1_mcbsp_free,\r
-+};\r
-+\r
-+static struct omap_mcbsp_platform_data omap1_mcbsp_pdata[] = {\r
-+#ifdef CONFIG_ARCH_OMAP730\r
-+      {\r
-+              .virt_base      = io_p2v(OMAP730_MCBSP1_BASE),\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,\r
-+              .rx_irq         = INT_730_McBSP1RX,\r
-+              .tx_irq         = INT_730_McBSP1TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+      },\r
-+      {\r
-+              .virt_base      = io_p2v(OMAP730_MCBSP2_BASE),\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,\r
-+              .rx_irq         = INT_730_McBSP2RX,\r
-+              .tx_irq         = INT_730_McBSP2TX\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+      },\r
-+#endif\r
-+#ifdef CONFIG_ARCH_OMAP15XX\r
-+      {\r
-+              .virt_base      = OMAP1510_MCBSP1_BASE,\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,\r
-+              .rx_irq         = INT_McBSP1RX,\r
-+              .tx_irq         = INT_McBSP1TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },\r
-+              },\r
-+      {\r
-+              .virt_base      = io_p2v(OMAP1510_MCBSP2_BASE),\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,\r
-+              .rx_irq         = INT_1510_SPI_RX,\r
-+              .tx_irq         = INT_1510_SPI_TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+      },\r
-+      {\r
-+              .virt_base      = OMAP1510_MCBSP3_BASE,\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,\r
-+              .rx_irq         = INT_McBSP3RX,\r
-+              .tx_irq         = INT_McBSP3TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },\r
-+      },\r
-+#endif\r
-+#ifdef CONFIG_ARCH_OMAP16XX\r
-+      {\r
-+              .virt_base      = OMAP1610_MCBSP1_BASE,\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,\r
-+              .rx_irq         = INT_McBSP1RX,\r
-+              .tx_irq         = INT_McBSP1TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },\r
-+      },\r
-+      {\r
-+              .virt_base      = io_p2v(OMAP1610_MCBSP2_BASE),\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,\r
-+              .rx_irq         = INT_1610_McBSP2_RX,\r
-+              .tx_irq         = INT_1610_McBSP2_TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+      },\r
-+      {\r
-+              .virt_base      = OMAP1610_MCBSP3_BASE,\r
-+              .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,\r
-+              .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,\r
-+              .rx_irq         = INT_McBSP3RX,\r
-+              .tx_irq         = INT_McBSP3TX,\r
-+              .ops            = &omap1_mcbsp_ops,\r
-+              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },\r
-+      },\r
-+#endif\r
-+};\r
-+#define mcbsp_count           ARRAY_SIZE(omap1_mcbsp_pdata)\r
-+\r
-+int __init omap1_mcbsp_init(void)\r
-+{\r
-+      omap_mcbsp_register_board_cfg(omap1_mcbsp_pdata, mcbsp_count);\r
-+\r
-+      return omap_mcbsp_init();\r
-+}\r
-+arch_initcall(omap1_mcbsp_init);\r
--- \r
-1.5.5.1.67.gbdb8.dirty\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at  http://vger.kernel.org/majordomo-info.html\r
-\r
+From: Eduardo Valentin <eduardo.valentin@indt.org.br>
+
+This patch adds support for mach-omap1 based on current
+mcbsp platform driver.
+
+Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>
+---
+ arch/arm/mach-omap1/Makefile |    2 +
+ arch/arm/mach-omap1/mcbsp.c  |  165 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 167 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-omap1/mcbsp.c
+
+diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
+index 6ebf23b..09246a7 100644
+--- a/arch/arm/mach-omap1/Makefile
++++ b/arch/arm/mach-omap1/Makefile
+@@ -5,6 +5,8 @@
+ # Common support
+ obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
++obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
++
+ obj-$(CONFIG_OMAP_MPU_TIMER)  += time.o
+ obj-$(CONFIG_OMAP_32K_TIMER)  += timer32k.o
+diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
+new file mode 100644
+index 0000000..f30624a
+--- /dev/null
++++ b/arch/arm/mach-omap1/mcbsp.c
+@@ -0,0 +1,165 @@
++/*
++ * linux/arch/arm/mach-omap1/mcbsp.c
++ *
++ * Copyright (C) 2008 Instituto Nokia de Tecnologia
++ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Multichannel mode not supported.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/io.h>
++
++#include <asm/arch/dma.h>
++#include <asm/arch/mux.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/mcbsp.h>
++#include <asm/arch/dsp_common.h>
++
++#define DPS_RSTCT2_PER_EN     (1 << 0)
++#define DSP_RSTCT2_WD_PER_EN  (1 << 1)
++
++static int omap1_mcbsp_check(unsigned int id)
++{
++      /* REVISIT: Check correctly for number of registered McBSPs */
++      if (cpu_is_omap730()) {
++              if (id > OMAP_MAX_MCBSP_COUNT - 2) {
++                     printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
++                              id + 1);
++                     return -ENODEV;
++              }
++              return 0;
++      }
++
++      if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
++              if (id > OMAP_MAX_MCBSP_COUNT - 1) {
++                      printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
++                              id + 1);
++                      return -ENODEV;
++              }
++              return 0;
++      }
++
++      return -ENODEV;
++}
++
++static void omap1_mcbsp_request(unsigned int id)
++{
++      /*
++       * On 1510, 1610 and 1710, McBSP1 and McBSP3
++       * are DSP public peripherals.
++       */
++      if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
++              omap_dsp_request_mem();
++              /*
++               * DSP external peripheral reset
++               * FIXME: This should be moved to dsp code
++               */
++              __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
++                              DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
++      }
++}
++
++static void omap1_mcbsp_free(unsigned int id)
++{
++      if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
++              omap_dsp_release_mem();
++}
++
++static struct omap_mcbsp_ops omap1_mcbsp_ops = {
++      .check          = omap1_mcbsp_check,
++      .request        = omap1_mcbsp_request,
++      .free           = omap1_mcbsp_free,
++};
++
++static struct omap_mcbsp_platform_data omap1_mcbsp_pdata[] = {
++#ifdef CONFIG_ARCH_OMAP730
++      {
++              .virt_base      = io_p2v(OMAP730_MCBSP1_BASE),
++              .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
++              .rx_irq         = INT_730_McBSP1RX,
++              .tx_irq         = INT_730_McBSP1TX,
++              .ops            = &omap1_mcbsp_ops,
++      },
++      {
++              .virt_base      = io_p2v(OMAP730_MCBSP2_BASE),
++              .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
++              .rx_irq         = INT_730_McBSP2RX,
++              .tx_irq         = INT_730_McBSP2TX
++              .ops            = &omap1_mcbsp_ops,
++      },
++#endif
++#ifdef CONFIG_ARCH_OMAP15XX
++      {
++              .virt_base      = OMAP1510_MCBSP1_BASE,
++              .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
++              .rx_irq         = INT_McBSP1RX,
++              .tx_irq         = INT_McBSP1TX,
++              .ops            = &omap1_mcbsp_ops,
++              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },
++              },
++      {
++              .virt_base      = io_p2v(OMAP1510_MCBSP2_BASE),
++              .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,
++              .rx_irq         = INT_1510_SPI_RX,
++              .tx_irq         = INT_1510_SPI_TX,
++              .ops            = &omap1_mcbsp_ops,
++      },
++      {
++              .virt_base      = OMAP1510_MCBSP3_BASE,
++              .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
++              .rx_irq         = INT_McBSP3RX,
++              .tx_irq         = INT_McBSP3TX,
++              .ops            = &omap1_mcbsp_ops,
++              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },
++      },
++#endif
++#ifdef CONFIG_ARCH_OMAP16XX
++      {
++              .virt_base      = OMAP1610_MCBSP1_BASE,
++              .dma_rx_sync    = OMAP_DMA_MCBSP1_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP1_TX,
++              .rx_irq         = INT_McBSP1RX,
++              .tx_irq         = INT_McBSP1TX,
++              .ops            = &omap1_mcbsp_ops,
++              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },
++      },
++      {
++              .virt_base      = io_p2v(OMAP1610_MCBSP2_BASE),
++              .dma_rx_sync    = OMAP_DMA_MCBSP2_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP2_TX,
++              .rx_irq         = INT_1610_McBSP2_RX,
++              .tx_irq         = INT_1610_McBSP2_TX,
++              .ops            = &omap1_mcbsp_ops,
++      },
++      {
++              .virt_base      = OMAP1610_MCBSP3_BASE,
++              .dma_rx_sync    = OMAP_DMA_MCBSP3_RX,
++              .dma_tx_sync    = OMAP_DMA_MCBSP3_TX,
++              .rx_irq         = INT_McBSP3RX,
++              .tx_irq         = INT_McBSP3TX,
++              .ops            = &omap1_mcbsp_ops,
++              .clocks         = { "dsp_ck", "api_ck", "dspxor_ck" },
++      },
++#endif
++};
++#define mcbsp_count           ARRAY_SIZE(omap1_mcbsp_pdata)
++
++int __init omap1_mcbsp_init(void)
++{
++      omap_mcbsp_register_board_cfg(omap1_mcbsp_pdata, mcbsp_count);
++
++      return omap_mcbsp_init();
++}
++arch_initcall(omap1_mcbsp_init);
+-- 
+1.5.5.1.67.gbdb8.dirty
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+
index 6d1e7d3..643a626 100644 (file)
-From: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
-\r
-This patch fix the clock definition for mcbsps on clock34xx.h.\r
-Device identification must be done using .id field, not\r
-only name field.\r
-\r
-Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
----\r
- arch/arm/mach-omap2/clock34xx.h |   30 ++++++++++++++++++++----------\r
- 1 files changed, 20 insertions(+), 10 deletions(-)\r
-\r
-diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h\r
-index 85afe1e..3fea82e 100644\r
---- a/arch/arm/mach-omap2/clock34xx.h\r
-+++ b/arch/arm/mach-omap2/clock34xx.h\r
-@@ -1480,7 +1480,8 @@ static const struct clksel mcbsp_15_clksel[] = {\r
- };\r
\r
- static struct clk mcbsp5_fck = {\r
--      .name           = "mcbsp5_fck",\r
-+      .name           = "mcbsp_fck",\r
-+      .id             = 5,\r
-       .init           = &omap2_init_clksel_parent,\r
-       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),\r
-       .enable_bit     = OMAP3430_EN_MCBSP5_SHIFT,\r
-@@ -1493,7 +1494,8 @@ static struct clk mcbsp5_fck = {\r
- };\r
\r
- static struct clk mcbsp1_fck = {\r
--      .name           = "mcbsp1_fck",\r
-+      .name           = "mcbsp_fck",\r
-+      .id             = 1,\r
-       .init           = &omap2_init_clksel_parent,\r
-       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),\r
-       .enable_bit     = OMAP3430_EN_MCBSP1_SHIFT,\r
-@@ -1941,7 +1943,8 @@ static struct clk gpt10_ick = {\r
- };\r
\r
- static struct clk mcbsp5_ick = {\r
--      .name           = "mcbsp5_ick",\r
-+      .name           = "mcbsp_ick",\r
-+      .id             = 5,\r
-       .parent         = &core_l4_ick,\r
-       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),\r
-       .enable_bit     = OMAP3430_EN_MCBSP5_SHIFT,\r
-@@ -1951,7 +1954,8 @@ static struct clk mcbsp5_ick = {\r
- };\r
\r
- static struct clk mcbsp1_ick = {\r
--      .name           = "mcbsp1_ick",\r
-+      .name           = "mcbsp_ick",\r
-+      .id             = 1,\r
-       .parent         = &core_l4_ick,\r
-       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),\r
-       .enable_bit     = OMAP3430_EN_MCBSP1_SHIFT,\r
-@@ -2754,7 +2758,8 @@ static struct clk gpt2_ick = {\r
- };\r
\r
- static struct clk mcbsp2_ick = {\r
--      .name           = "mcbsp2_ick",\r
-+      .name           = "mcbsp_ick",\r
-+      .id             = 2,\r
-       .parent         = &per_l4_ick,\r
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),\r
-       .enable_bit     = OMAP3430_EN_MCBSP2_SHIFT,\r
-@@ -2764,7 +2769,8 @@ static struct clk mcbsp2_ick = {\r
- };\r
\r
- static struct clk mcbsp3_ick = {\r
--      .name           = "mcbsp3_ick",\r
-+      .name           = "mcbsp_ick",\r
-+      .id             = 3,\r
-       .parent         = &per_l4_ick,\r
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),\r
-       .enable_bit     = OMAP3430_EN_MCBSP3_SHIFT,\r
-@@ -2774,7 +2780,8 @@ static struct clk mcbsp3_ick = {\r
- };\r
\r
- static struct clk mcbsp4_ick = {\r
--      .name           = "mcbsp4_ick",\r
-+      .name           = "mcbsp_ick",\r
-+      .id             = 4,\r
-       .parent         = &per_l4_ick,\r
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),\r
-       .enable_bit     = OMAP3430_EN_MCBSP4_SHIFT,\r
-@@ -2790,7 +2797,8 @@ static const struct clksel mcbsp_234_clksel[] = {\r
- };\r
\r
- static struct clk mcbsp2_fck = {\r
--      .name           = "mcbsp2_fck",\r
-+      .name           = "mcbsp_fck",\r
-+      .id             = 2,\r
-       .init           = &omap2_init_clksel_parent,\r
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),\r
-       .enable_bit     = OMAP3430_EN_MCBSP2_SHIFT,\r
-@@ -2803,7 +2811,8 @@ static struct clk mcbsp2_fck = {\r
- };\r
\r
- static struct clk mcbsp3_fck = {\r
--      .name           = "mcbsp3_fck",\r
-+      .name           = "mcbsp_fck",\r
-+      .id             = 3,\r
-       .init           = &omap2_init_clksel_parent,\r
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),\r
-       .enable_bit     = OMAP3430_EN_MCBSP3_SHIFT,\r
-@@ -2816,7 +2825,8 @@ static struct clk mcbsp3_fck = {\r
- };\r
\r
- static struct clk mcbsp4_fck = {\r
--      .name           = "mcbsp4_fck",\r
-+      .name           = "mcbsp_fck",\r
-+      .id             = 4,\r
-       .init           = &omap2_init_clksel_parent,\r
-       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),\r
-       .enable_bit     = OMAP3430_EN_MCBSP4_SHIFT,\r
--- \r
-1.5.5.1.67.gbdb8.dirty\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at  http://vger.kernel.org/majordomo-info.html\r
-\r
+From: Eduardo Valentin <eduardo.valentin@indt.org.br>
+
+This patch fix the clock definition for mcbsps on clock34xx.h.
+Device identification must be done using .id field, not
+only name field.
+
+Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>
+---
+ arch/arm/mach-omap2/clock34xx.h |   30 ++++++++++++++++++++----------
+ 1 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
+index 85afe1e..3fea82e 100644
+--- a/arch/arm/mach-omap2/clock34xx.h
++++ b/arch/arm/mach-omap2/clock34xx.h
+@@ -1480,7 +1480,8 @@ static const struct clksel mcbsp_15_clksel[] = {
+ };
+ static struct clk mcbsp5_fck = {
+-      .name           = "mcbsp5_fck",
++      .name           = "mcbsp_fck",
++      .id             = 5,
+       .init           = &omap2_init_clksel_parent,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+       .enable_bit     = OMAP3430_EN_MCBSP5_SHIFT,
+@@ -1493,7 +1494,8 @@ static struct clk mcbsp5_fck = {
+ };
+ static struct clk mcbsp1_fck = {
+-      .name           = "mcbsp1_fck",
++      .name           = "mcbsp_fck",
++      .id             = 1,
+       .init           = &omap2_init_clksel_parent,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+       .enable_bit     = OMAP3430_EN_MCBSP1_SHIFT,
+@@ -1941,7 +1943,8 @@ static struct clk gpt10_ick = {
+ };
+ static struct clk mcbsp5_ick = {
+-      .name           = "mcbsp5_ick",
++      .name           = "mcbsp_ick",
++      .id             = 5,
+       .parent         = &core_l4_ick,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+       .enable_bit     = OMAP3430_EN_MCBSP5_SHIFT,
+@@ -1951,7 +1954,8 @@ static struct clk mcbsp5_ick = {
+ };
+ static struct clk mcbsp1_ick = {
+-      .name           = "mcbsp1_ick",
++      .name           = "mcbsp_ick",
++      .id             = 1,
+       .parent         = &core_l4_ick,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+       .enable_bit     = OMAP3430_EN_MCBSP1_SHIFT,
+@@ -2754,7 +2758,8 @@ static struct clk gpt2_ick = {
+ };
+ static struct clk mcbsp2_ick = {
+-      .name           = "mcbsp2_ick",
++      .name           = "mcbsp_ick",
++      .id             = 2,
+       .parent         = &per_l4_ick,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+       .enable_bit     = OMAP3430_EN_MCBSP2_SHIFT,
+@@ -2764,7 +2769,8 @@ static struct clk mcbsp2_ick = {
+ };
+ static struct clk mcbsp3_ick = {
+-      .name           = "mcbsp3_ick",
++      .name           = "mcbsp_ick",
++      .id             = 3,
+       .parent         = &per_l4_ick,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+       .enable_bit     = OMAP3430_EN_MCBSP3_SHIFT,
+@@ -2774,7 +2780,8 @@ static struct clk mcbsp3_ick = {
+ };
+ static struct clk mcbsp4_ick = {
+-      .name           = "mcbsp4_ick",
++      .name           = "mcbsp_ick",
++      .id             = 4,
+       .parent         = &per_l4_ick,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+       .enable_bit     = OMAP3430_EN_MCBSP4_SHIFT,
+@@ -2790,7 +2797,8 @@ static const struct clksel mcbsp_234_clksel[] = {
+ };
+ static struct clk mcbsp2_fck = {
+-      .name           = "mcbsp2_fck",
++      .name           = "mcbsp_fck",
++      .id             = 2,
+       .init           = &omap2_init_clksel_parent,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+       .enable_bit     = OMAP3430_EN_MCBSP2_SHIFT,
+@@ -2803,7 +2811,8 @@ static struct clk mcbsp2_fck = {
+ };
+ static struct clk mcbsp3_fck = {
+-      .name           = "mcbsp3_fck",
++      .name           = "mcbsp_fck",
++      .id             = 3,
+       .init           = &omap2_init_clksel_parent,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+       .enable_bit     = OMAP3430_EN_MCBSP3_SHIFT,
+@@ -2816,7 +2825,8 @@ static struct clk mcbsp3_fck = {
+ };
+ static struct clk mcbsp4_fck = {
+-      .name           = "mcbsp4_fck",
++      .name           = "mcbsp_fck",
++      .id             = 4,
+       .init           = &omap2_init_clksel_parent,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+       .enable_bit     = OMAP3430_EN_MCBSP4_SHIFT,
+-- 
+1.5.5.1.67.gbdb8.dirty
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+
index f31604d..4e42a11 100644 (file)
-From: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
-\r
-This patch adds support for mach-omap2 based on current\r
-mcbsp platform driver.\r
-\r
-Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
----\r
- arch/arm/mach-omap2/Makefile |    2 +\r
- arch/arm/mach-omap2/mcbsp.c  |  105 ++++++++++++++++++++++++++++++++++++++++++\r
- 2 files changed, 107 insertions(+), 0 deletions(-)\r
- create mode 100644 arch/arm/mach-omap2/mcbsp.c\r
-\r
-diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile\r
-index 552664c..84fa698 100644\r
---- a/arch/arm/mach-omap2/Makefile\r
-+++ b/arch/arm/mach-omap2/Makefile\r
-@@ -7,6 +7,8 @@ obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \\r
-               devices.o serial.o gpmc.o timer-gp.o powerdomain.o \\r
-               clockdomain.o\r
\r
-+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o\r
-+\r
- # Functions loaded to SRAM\r
- obj-$(CONFIG_ARCH_OMAP2)              += sram24xx.o\r
\r
-diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c\r
-new file mode 100644\r
-index 0000000..e2ee8f7\r
---- /dev/null\r
-+++ b/arch/arm/mach-omap2/mcbsp.c\r
-@@ -0,0 +1,105 @@\r
-+/*\r
-+ * linux/arch/arm/mach-omap2/mcbsp.c\r
-+ *\r
-+ * Copyright (C) 2008 Instituto Nokia de Tecnologia\r
-+ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>\r
-+ *\r
-+ * This program is free software; you can redistribute it and/or modify\r
-+ * it under the terms of the GNU General Public License version 2 as\r
-+ * published by the Free Software Foundation.\r
-+ *\r
-+ * Multichannel mode not supported.\r
-+ */\r
-+#include <linux/module.h>\r
-+#include <linux/init.h>\r
-+#include <linux/clk.h>\r
-+#include <linux/err.h>\r
-+\r
-+#include <asm/arch/dma.h>\r
-+#include <asm/arch/mux.h>\r
-+#include <asm/arch/cpu.h>\r
-+#include <asm/arch/mcbsp.h>\r
-+\r
-+static void omap2_mcbsp2_mux_setup(void)\r
-+{\r
-+      omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);\r
-+      omap_cfg_reg(R14_24XX_MCBSP2_FSX);\r
-+      omap_cfg_reg(W15_24XX_MCBSP2_DR);\r
-+      omap_cfg_reg(V15_24XX_MCBSP2_DX);\r
-+      omap_cfg_reg(V14_24XX_GPIO117);\r
-+      /*\r
-+       * TODO: Need to add MUX settings for OMAP 2430 SDP\r
-+       */\r
-+}\r
-+\r
-+static void omap2_mcbsp_request(unsigned int id)\r
-+{\r
-+      if (cpu_is_omap2420() && (id == OMAP_MCBSP2))\r
-+              omap2_mcbsp2_mux_setup();\r
-+}\r
-+\r
-+static int omap2_mcbsp_check(unsigned int id)\r
-+{\r
-+      if (id > OMAP_MAX_MCBSP_COUNT - 1) {\r
-+              printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);\r
-+              return -ENODEV;\r
-+      }\r
-+      return 0;\r
-+}\r
-+\r
-+static struct omap_mcbsp_ops omap2_mcbsp_ops = {\r
-+      .request        = omap2_mcbsp_request,\r
-+      .check          = omap2_mcbsp_check,\r
-+};\r
-+\r
-+static struct omap_mcbsp_platform_data omap2_mcbsp_pdata[] = {\r
-+#ifdef CONFIG_ARCH_OMAP24XX\r
-+      {\r
-+              .virt_base      = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),\r
-+              .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,\r
-+              .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,\r
-+              .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,\r
-+              .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,\r
-+              .ops            = &omap2_mcbsp_ops,\r
-+              .clocks         = { "mcbsp_ick", "mcbsp_fck" },\r
-+      },\r
-+      {\r
-+              .virt_base      = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),\r
-+              .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,\r
-+              .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,\r
-+              .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,\r
-+              .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,\r
-+              .ops            = &omap2_mcbsp_ops,\r
-+              .clocks         = { "mcbsp_ick", "mcbsp_fck" },\r
-+      },\r
-+#endif\r
-+#ifdef CONFIG_ARCH_OMAP34XX\r
-+      {\r
-+              .virt_base      = IO_ADDRESS(OMAP34XX_MCBSP1_BASE),\r
-+              .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,\r
-+              .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,\r
-+              .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,\r
-+              .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,\r
-+              .ops            = &omap2_mcbsp_ops,\r
-+              .clocks         = { "mcbsp_ick", "mcbsp_fck" },\r
-+      },\r
-+      {\r
-+              .virt_base      = IO_ADDRESS(OMAP34XX_MCBSP2_BASE),\r
-+              .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,\r
-+              .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,\r
-+              .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,\r
-+              .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,\r
-+              .ops            = &omap2_mcbsp_ops,\r
-+              .clocks         = { "mcbsp_ick", "mcbsp_fck" },\r
-+      },\r
-+#endif\r
-+};\r
-+#define mcbsp_count           ARRAY_SIZE(omap2_mcbsp_pdata)\r
-+\r
-+int __init omap2_mcbsp_init(void)\r
-+{\r
-+      omap_mcbsp_register_board_cfg(omap2_mcbsp_pdata, mcbsp_count);\r
-+\r
-+      return omap_mcbsp_init();\r
-+}\r
-+arch_initcall(omap2_mcbsp_init);\r
--- \r
-1.5.5.1.67.gbdb8.dirty\r
-\r
---\r
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in\r
-the body of a message to majordomo@vger.kernel.org\r
-More majordomo info at  http://vger.kernel.org/majordomo-info.html\r
-\r
+From: Eduardo Valentin <eduardo.valentin@indt.org.br>
+
+This patch adds support for mach-omap2 based on current
+mcbsp platform driver.
+
+Signed-off-by: Eduardo Valentin <eduardo.valentin@indt.org.br>
+---
+ arch/arm/mach-omap2/Makefile |    2 +
+ arch/arm/mach-omap2/mcbsp.c  |  105 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 107 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-omap2/mcbsp.c
+
+diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
+index 552664c..84fa698 100644
+--- a/arch/arm/mach-omap2/Makefile
++++ b/arch/arm/mach-omap2/Makefile
+@@ -7,6 +7,8 @@ obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
+               devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
+               clockdomain.o
++obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
++
+ # Functions loaded to SRAM
+ obj-$(CONFIG_ARCH_OMAP2)              += sram24xx.o
+diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
+new file mode 100644
+index 0000000..e2ee8f7
+--- /dev/null
++++ b/arch/arm/mach-omap2/mcbsp.c
+@@ -0,0 +1,105 @@
++/*
++ * linux/arch/arm/mach-omap2/mcbsp.c
++ *
++ * Copyright (C) 2008 Instituto Nokia de Tecnologia
++ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Multichannel mode not supported.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++
++#include <asm/arch/dma.h>
++#include <asm/arch/mux.h>
++#include <asm/arch/cpu.h>
++#include <asm/arch/mcbsp.h>
++
++static void omap2_mcbsp2_mux_setup(void)
++{
++      omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
++      omap_cfg_reg(R14_24XX_MCBSP2_FSX);
++      omap_cfg_reg(W15_24XX_MCBSP2_DR);
++      omap_cfg_reg(V15_24XX_MCBSP2_DX);
++      omap_cfg_reg(V14_24XX_GPIO117);
++      /*
++       * TODO: Need to add MUX settings for OMAP 2430 SDP
++       */
++}
++
++static void omap2_mcbsp_request(unsigned int id)
++{
++      if (cpu_is_omap2420() && (id == OMAP_MCBSP2))
++              omap2_mcbsp2_mux_setup();
++}
++
++static int omap2_mcbsp_check(unsigned int id)
++{
++      if (id > OMAP_MAX_MCBSP_COUNT - 1) {
++              printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
++              return -ENODEV;
++      }
++      return 0;
++}
++
++static struct omap_mcbsp_ops omap2_mcbsp_ops = {
++      .request        = omap2_mcbsp_request,
++      .check          = omap2_mcbsp_check,
++};
++
++static struct omap_mcbsp_platform_data omap2_mcbsp_pdata[] = {
++#ifdef CONFIG_ARCH_OMAP24XX
++      {
++              .virt_base      = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
++              .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
++              .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
++              .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
++              .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
++              .ops            = &omap2_mcbsp_ops,
++              .clocks         = { "mcbsp_ick", "mcbsp_fck" },
++      },
++      {
++              .virt_base      = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
++              .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
++              .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
++              .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
++              .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
++              .ops            = &omap2_mcbsp_ops,
++              .clocks         = { "mcbsp_ick", "mcbsp_fck" },
++      },
++#endif
++#ifdef CONFIG_ARCH_OMAP34XX
++      {
++              .virt_base      = IO_ADDRESS(OMAP34XX_MCBSP1_BASE),
++              .dma_rx_sync    = OMAP24XX_DMA_MCBSP1_RX,
++              .dma_tx_sync    = OMAP24XX_DMA_MCBSP1_TX,
++              .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
++              .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
++              .ops            = &omap2_mcbsp_ops,
++              .clocks         = { "mcbsp_ick", "mcbsp_fck" },
++      },
++      {
++              .virt_base      = IO_ADDRESS(OMAP34XX_MCBSP2_BASE),
++              .dma_rx_sync    = OMAP24XX_DMA_MCBSP2_RX,
++              .dma_tx_sync    = OMAP24XX_DMA_MCBSP2_TX,
++              .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
++              .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
++              .ops            = &omap2_mcbsp_ops,
++              .clocks         = { "mcbsp_ick", "mcbsp_fck" },
++      },
++#endif
++};
++#define mcbsp_count           ARRAY_SIZE(omap2_mcbsp_pdata)
++
++int __init omap2_mcbsp_init(void)
++{
++      omap_mcbsp_register_board_cfg(omap2_mcbsp_pdata, mcbsp_count);
++
++      return omap_mcbsp_init();
++}
++arch_initcall(omap2_mcbsp_init);
+-- 
+1.5.5.1.67.gbdb8.dirty
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+
diff --git a/packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch b/packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch
new file mode 100644 (file)
index 0000000..550a4f5
--- /dev/null
@@ -0,0 +1,1002 @@
+From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+To: linux-omap@vger.kernel.org
+Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+Subject: [PATCH 1/3] ARM: OMAP: SmartReflex driver, reference source and header files
+Date:  Mon,  2 Jun 2008 14:30:12 +0300
+
+The following patch set integrates TI's SmartReflex driver. SmartReflex is a
+module that adjusts OMAP3 VDD1 and VDD2 operating voltages around the nominal
+values of current operating point depending on silicon characteristics and
+operating conditions.
+
+The driver creates two sysfs entries into /sys/power/ named "sr_vdd1_autocomp"
+and "sr_vdd2_autocomp" which can be used to activate SmartReflex modules 1 and
+2.
+
+Use the following commands to enable SmartReflex:
+
+echo -n 1 > /sys/power/sr_vdd1_autocomp
+echo -n 1 > /sys/power/sr_vdd2_autocomp
+
+To disable:
+
+echo -n 0 > /sys/power/sr_vdd1_autocomp
+echo -n 0 > /sys/power/sr_vdd2_autocomp
+
+This particular patch adds the TI reference source and header files for
+SmartReflex. Only modifications include minor styling to pass checkpatch.pl
+test.
+
+Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+---
+ arch/arm/mach-omap2/smartreflex.c |  815 +++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-omap2/smartreflex.h |  136 ++++++
+ 2 files changed, 951 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-omap2/smartreflex.c
+ create mode 100644 arch/arm/mach-omap2/smartreflex.h
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+new file mode 100644
+index 0000000..dae7460
+--- /dev/null
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -0,0 +1,815 @@
++/*
++ * linux/arch/arm/mach-omap3/smartreflex.c
++ *
++ * OMAP34XX SmartReflex Voltage Control
++ *
++ * Copyright (C) 2007 Texas Instruments, Inc.
++ * Lesly A M <x0080970@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/sysfs.h>
++
++#include <asm/arch/prcm.h>
++#include <asm/arch/power_companion.h>
++#include <linux/io.h>
++
++#include "prcm-regs.h"
++#include "smartreflex.h"
++
++
++/* #define DEBUG_SR 1 */
++#ifdef DEBUG_SR
++#  define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__ ,\
++                                                                      ## args)
++#else
++#  define DPRINTK(fmt, args...)
++#endif
++
++struct omap_sr{
++      int srid;
++      int is_sr_reset;
++      int is_autocomp_active;
++      struct clk *fck;
++      u32 req_opp_no;
++      u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue, opp5_nvalue;
++      u32 senp_mod, senn_mod;
++      u32 srbase_addr;
++      u32 vpbase_addr;
++};
++
++static struct omap_sr sr1 = {
++      .srid = SR1,
++      .is_sr_reset = 1,
++      .is_autocomp_active = 0,
++      .srbase_addr = OMAP34XX_SR1_BASE,
++};
++
++static struct omap_sr sr2 = {
++      .srid = SR2,
++      .is_sr_reset = 1,
++      .is_autocomp_active = 0,
++      .srbase_addr = OMAP34XX_SR2_BASE,
++};
++
++static inline void sr_write_reg(struct omap_sr *sr, int offset, u32 value)
++{
++      omap_writel(value, sr->srbase_addr + offset);
++}
++
++static inline void sr_modify_reg(struct omap_sr *sr, int offset, u32 mask,
++                                                              u32 value)
++{
++      u32 reg_val;
++
++      reg_val = omap_readl(sr->srbase_addr + offset);
++      reg_val &= ~mask;
++      reg_val |= value;
++
++      omap_writel(reg_val, sr->srbase_addr + offset);
++}
++
++static inline u32 sr_read_reg(struct omap_sr *sr, int offset)
++{
++      return omap_readl(sr->srbase_addr + offset);
++}
++
++
++#ifndef USE_EFUSE_VALUES
++static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
++{
++      u32 gn, rn, mul;
++
++      for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
++              mul = 1 << (gn + 8);
++              rn = mul / sensor;
++              if (rn < R_MAXLIMIT) {
++                      *sengain = gn;
++                      *rnsen = rn;
++              }
++      }
++}
++#endif
++
++static int sr_clk_enable(struct omap_sr *sr)
++{
++      if (clk_enable(sr->fck) != 0) {
++              printk(KERN_ERR "Could not enable sr%d_fck\n", sr->srid);
++              goto clk_enable_err;
++      }
++
++      /* set fclk- active , iclk- idle */
++      sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
++                                              SR_CLKACTIVITY_IOFF_FON);
++
++      return 0;
++
++clk_enable_err:
++      return -1;
++}
++
++static int sr_clk_disable(struct omap_sr *sr)
++{
++      /* set fclk, iclk- idle */
++      sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
++                                              SR_CLKACTIVITY_IOFF_FOFF);
++
++      clk_disable(sr->fck);
++      sr->is_sr_reset = 1;
++
++      return 0;
++}
++
++static void sr_set_nvalues(struct omap_sr *sr)
++{
++#ifdef USE_EFUSE_VALUES
++      u32 n1, n2;
++#else
++      u32 senpval, sennval;
++      u32 senpgain, senngain;
++      u32 rnsenp, rnsenn;
++#endif
++
++      if (sr->srid == SR1) {
++#ifdef USE_EFUSE_VALUES
++              /* Read values for VDD1 from EFUSE */
++#else
++              /* since E-Fuse Values are not available, calculating the
++               * reciprocal of the SenN and SenP values for SR1
++               */
++              sr->senp_mod = 0x03;        /* SenN-M5 enabled */
++              sr->senn_mod = 0x03;
++
++              /* for OPP5 */
++              senpval = 0x848 + 0x330;
++              sennval = 0xacd + 0x330;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp5_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              /* for OPP4 */
++              senpval = 0x727 + 0x2a0;
++              sennval = 0x964 + 0x2a0;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp4_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              /* for OPP3 */
++              senpval = 0x655 + 0x200;
++              sennval = 0x85b + 0x200;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp3_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              /* for OPP2 */
++              senpval = 0x3be + 0x1a0;
++              sennval = 0x506 + 0x1a0;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp2_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              /* for OPP1 */
++              senpval = 0x28c + 0x100;
++              sennval = 0x373 + 0x100;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp1_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              sr_clk_enable(sr);
++              sr_write_reg(sr, NVALUERECIPROCAL, sr->opp3_nvalue);
++              sr_clk_disable(sr);
++
++#endif
++      } else if (sr->srid == SR2) {
++#ifdef USE_EFUSE_VALUES
++              /* Read values for VDD2 from EFUSE */
++#else
++              /* since E-Fuse Values are not available, calculating the
++               * reciprocal of the SenN and SenP values for SR2
++               */
++              sr->senp_mod = 0x03;
++              sr->senn_mod = 0x03;
++
++              /* for OPP3 */
++              senpval = 0x579 + 0x200;
++              sennval = 0x76f + 0x200;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp3_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              /* for OPP2 */
++              senpval = 0x390 + 0x1c0;
++              sennval = 0x4f5 + 0x1c0;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp2_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++              /* for OPP1 */
++              senpval = 0x25d;
++              sennval = 0x359;
++
++              cal_reciprocal(senpval, &senpgain, &rnsenp);
++              cal_reciprocal(sennval, &senngain, &rnsenn);
++
++              sr->opp1_nvalue =
++                              ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
++                              (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
++                              (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
++                              (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++
++#endif
++      }
++
++}
++
++static void sr_configure_vp(int srid)
++{
++      u32 vpconfig;
++
++      if (srid == SR1) {
++              vpconfig = PRM_VP1_CONFIG_ERROROFFSET | PRM_VP1_CONFIG_ERRORGAIN
++                      | PRM_VP1_CONFIG_INITVOLTAGE | PRM_VP1_CONFIG_TIMEOUTEN;
++
++              PRM_VP1_CONFIG = vpconfig;
++              PRM_VP1_VSTEPMIN = PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
++                                              PRM_VP1_VSTEPMIN_VSTEPMIN;
++
++              PRM_VP1_VSTEPMAX = PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
++                                              PRM_VP1_VSTEPMAX_VSTEPMAX;
++
++              PRM_VP1_VLIMITTO = PRM_VP1_VLIMITTO_VDDMAX |
++                      PRM_VP1_VLIMITTO_VDDMIN | PRM_VP1_VLIMITTO_TIMEOUT;
++
++              PRM_VP1_CONFIG |= PRM_VP1_CONFIG_INITVDD;
++              PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_INITVDD;
++
++      } else if (srid == SR2) {
++              vpconfig = PRM_VP2_CONFIG_ERROROFFSET | PRM_VP2_CONFIG_ERRORGAIN
++                      | PRM_VP2_CONFIG_INITVOLTAGE | PRM_VP2_CONFIG_TIMEOUTEN;
++
++              PRM_VP2_CONFIG = vpconfig;
++              PRM_VP2_VSTEPMIN = PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
++                                              PRM_VP2_VSTEPMIN_VSTEPMIN;
++
++              PRM_VP2_VSTEPMAX = PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
++                                              PRM_VP2_VSTEPMAX_VSTEPMAX;
++
++              PRM_VP2_VLIMITTO = PRM_VP2_VLIMITTO_VDDMAX |
++                      PRM_VP2_VLIMITTO_VDDMIN | PRM_VP2_VLIMITTO_TIMEOUT;
++
++              PRM_VP2_CONFIG |= PRM_VP2_CONFIG_INITVDD;
++              PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_INITVDD;
++
++      }
++}
++
++static void sr_configure_vc(void)
++{
++      PRM_VC_SMPS_SA =
++              (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA1_SHIFT) |
++              (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA0_SHIFT);
++
++      PRM_VC_SMPS_VOL_RA = (R_VDD2_SR_CONTROL << PRM_VC_SMPS_VOLRA1_SHIFT) |
++                              (R_VDD1_SR_CONTROL << PRM_VC_SMPS_VOLRA0_SHIFT);
++
++      PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL0_ON << PRM_VC_CMD_ON_SHIFT) |
++                      (PRM_VC_CMD_VAL0_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
++                      (PRM_VC_CMD_VAL0_RET << PRM_VC_CMD_RET_SHIFT) |
++                      (PRM_VC_CMD_VAL0_OFF << PRM_VC_CMD_OFF_SHIFT);
++
++      PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL1_ON << PRM_VC_CMD_ON_SHIFT) |
++                      (PRM_VC_CMD_VAL1_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
++                      (PRM_VC_CMD_VAL1_RET << PRM_VC_CMD_RET_SHIFT) |
++                      (PRM_VC_CMD_VAL1_OFF << PRM_VC_CMD_OFF_SHIFT);
++
++      PRM_VC_CH_CONF = PRM_VC_CH_CONF_CMD1 | PRM_VC_CH_CONF_RAV1;
++
++      PRM_VC_I2C_CFG = PRM_VC_I2C_CFG_MCODE | PRM_VC_I2C_CFG_HSEN
++                                                      | PRM_VC_I2C_CFG_SREN;
++
++      /* Setup voltctrl and other setup times */
++#ifdef CONFIG_SYSOFFMODE
++      PRM_VOLTCTRL = PRM_VOLTCTRL_AUTO_OFF | PRM_VOLTCTRL_AUTO_RET;
++      PRM_CLKSETUP = PRM_CLKSETUP_DURATION;
++      PRM_VOLTSETUP1 = (PRM_VOLTSETUP_TIME2 << PRM_VOLTSETUP_TIME2_OFFSET) |
++                      (PRM_VOLTSETUP_TIME1 << PRM_VOLTSETUP_TIME1_OFFSET);
++      PRM_VOLTOFFSET = PRM_VOLTOFFSET_DURATION;
++      PRM_VOLTSETUP2 = PRM_VOLTSETUP2_DURATION;
++#else
++      PRM_VOLTCTRL |= PRM_VOLTCTRL_AUTO_RET;
++#endif
++
++}
++
++
++static void sr_configure(struct omap_sr *sr)
++{
++      u32 sys_clk, sr_clk_length = 0;
++      u32 sr_config;
++      u32 senp_en , senn_en;
++
++      senp_en = sr->senp_mod;
++      senn_en = sr->senn_mod;
++
++      sys_clk = prcm_get_system_clock_speed();
++
++      switch (sys_clk) {
++      case 12000:
++              sr_clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
++              break;
++      case 13000:
++              sr_clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
++              break;
++      case 19200:
++              sr_clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
++              break;
++      case 26000:
++              sr_clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
++              break;
++      case 38400:
++              sr_clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
++              break;
++      default :
++              printk(KERN_ERR "Invalid sysclk value\n");
++              break;
++      }
++
++      DPRINTK(KERN_DEBUG "SR : sys clk %lu\n", sys_clk);
++      if (sr->srid == SR1) {
++              sr_config = SR1_SRCONFIG_ACCUMDATA |
++                      (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
++                      SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
++                      SRCONFIG_MINMAXAVG_EN |
++                      (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
++                      (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
++                      SRCONFIG_DELAYCTRL;
++
++              sr_write_reg(sr, SRCONFIG, sr_config);
++
++              sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
++                                      SR1_AVGWEIGHT_SENNAVGWEIGHT);
++
++              sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
++                      SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
++                      (SR1_ERRWEIGHT | SR1_ERRMAXLIMIT | SR1_ERRMINLIMIT));
++
++      } else if (sr->srid == SR2) {
++              sr_config = SR2_SRCONFIG_ACCUMDATA |
++                      (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
++                      SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
++                      SRCONFIG_MINMAXAVG_EN |
++                      (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
++                      (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
++                      SRCONFIG_DELAYCTRL;
++
++              sr_write_reg(sr, SRCONFIG, sr_config);
++
++              sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
++                                      SR2_AVGWEIGHT_SENNAVGWEIGHT);
++
++              sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
++                      SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
++                      (SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
++
++      }
++      sr->is_sr_reset = 0;
++}
++
++static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
++{
++      u32 nvalue_reciprocal, current_nvalue;
++
++      sr->req_opp_no = target_opp_no;
++
++      if (sr->srid == SR1) {
++              switch (target_opp_no) {
++              case 5:
++                      nvalue_reciprocal = sr->opp5_nvalue;
++                      break;
++              case 4:
++                      nvalue_reciprocal = sr->opp4_nvalue;
++                      break;
++              case 3:
++                      nvalue_reciprocal = sr->opp3_nvalue;
++                      break;
++              case 2:
++                      nvalue_reciprocal = sr->opp2_nvalue;
++                      break;
++              case 1:
++                      nvalue_reciprocal = sr->opp1_nvalue;
++                      break;
++              default:
++                      nvalue_reciprocal = sr->opp3_nvalue;
++                      break;
++              }
++      } else {
++              switch (target_opp_no) {
++              case 3:
++                      nvalue_reciprocal = sr->opp3_nvalue;
++                      break;
++              case 2:
++                      nvalue_reciprocal = sr->opp2_nvalue;
++                      break;
++              case 1:
++                      nvalue_reciprocal = sr->opp1_nvalue;
++                      break;
++              default:
++                      nvalue_reciprocal = sr->opp3_nvalue;
++                      break;
++              }
++      }
++
++      current_nvalue = sr_read_reg(sr, NVALUERECIPROCAL);
++
++      if (current_nvalue == nvalue_reciprocal) {
++              DPRINTK("System is already at the desired voltage level\n");
++              return;
++      }
++
++      sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
++
++      /* Enable the interrupt */
++      sr_modify_reg(sr, ERRCONFIG,
++                      (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
++                      (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
++
++      if (sr->srid == SR1) {
++              /* Enable VP1 */
++              PRM_VP1_CONFIG |= PRM_VP1_CONFIG_VPENABLE;
++      } else if (sr->srid == SR2) {
++              /* Enable VP2 */
++              PRM_VP2_CONFIG |= PRM_VP2_CONFIG_VPENABLE;
++      }
++
++      /* SRCONFIG - enable SR */
++      sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
++
++}
++
++static void sr_disable(struct omap_sr *sr)
++{
++      sr->is_sr_reset = 1;
++
++      /* SRCONFIG - disable SR */
++      sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
++
++      if (sr->srid == SR1) {
++              /* Enable VP1 */
++              PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
++      } else if (sr->srid == SR2) {
++              /* Enable VP2 */
++              PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
++      }
++}
++
++
++void sr_start_vddautocomap(int srid, u32 target_opp_no)
++{
++      struct omap_sr *sr = NULL;
++
++      if (srid == SR1)
++              sr = &sr1;
++      else if (srid == SR2)
++              sr = &sr2;
++
++      if (sr->is_sr_reset == 1) {
++              sr_clk_enable(sr);
++              sr_configure(sr);
++      }
++
++      if (sr->is_autocomp_active == 1)
++              DPRINTK(KERN_WARNING "SR%d: VDD autocomp is already active\n",
++                                                                      srid);
++
++      sr->is_autocomp_active = 1;
++      sr_enable(sr, target_opp_no);
++}
++EXPORT_SYMBOL(sr_start_vddautocomap);
++
++int sr_stop_vddautocomap(int srid)
++{
++      struct omap_sr *sr = NULL;
++
++      if (srid == SR1)
++              sr = &sr1;
++      else if (srid == SR2)
++              sr = &sr2;
++
++      if (sr->is_autocomp_active == 1) {
++              sr_disable(sr);
++              sr_clk_disable(sr);
++              sr->is_autocomp_active = 0;
++              return SR_TRUE;
++      } else {
++              DPRINTK(KERN_WARNING "SR%d: VDD autocomp is not active\n",
++                                                              srid);
++              return SR_FALSE;
++      }
++
++}
++EXPORT_SYMBOL(sr_stop_vddautocomap);
++
++void enable_smartreflex(int srid)
++{
++      u32 target_opp_no = 0;
++      struct omap_sr *sr = NULL;
++
++      if (srid == SR1)
++              sr = &sr1;
++      else if (srid == SR2)
++              sr = &sr2;
++
++      if (sr->is_autocomp_active == 1) {
++              if (sr->is_sr_reset == 1) {
++                      if (srid == SR1) {
++                              /* Enable SR clks */
++                              CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
++                              target_opp_no = get_opp_no(current_vdd1_opp);
++
++                      } else if (srid == SR2) {
++                              /* Enable SR clks */
++                              CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
++                              target_opp_no = get_opp_no(current_vdd2_opp);
++                      }
++
++                      sr_configure(sr);
++
++                      sr_enable(sr, target_opp_no);
++              }
++      }
++}
++
++void disable_smartreflex(int srid)
++{
++      struct omap_sr *sr = NULL;
++
++      if (srid == SR1)
++              sr = &sr1;
++      else if (srid == SR2)
++              sr = &sr2;
++
++      if (sr->is_autocomp_active == 1) {
++              if (srid == SR1) {
++                      /* Enable SR clk */
++                      CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
++
++              } else if (srid == SR2) {
++                      /* Enable SR clk */
++                      CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
++              }
++
++              if (sr->is_sr_reset == 0) {
++
++                      sr->is_sr_reset = 1;
++                      /* SRCONFIG - disable SR */
++                      sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
++                                                      ~SRCONFIG_SRENABLE);
++
++                      if (sr->srid == SR1) {
++                              /* Disable SR clk */
++                              CM_FCLKEN_WKUP &= ~SR1_CLK_ENABLE;
++                              /* Enable VP1 */
++                              PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
++
++                      } else if (sr->srid == SR2) {
++                              /* Disable SR clk */
++                              CM_FCLKEN_WKUP &= ~SR2_CLK_ENABLE;
++                              /* Enable VP2 */
++                              PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
++                      }
++              }
++      }
++}
++
++
++/* Voltage Scaling using SR VCBYPASS */
++int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
++{
++      int ret;
++      int sr_status = 0;
++      u32 vdd, target_opp_no;
++      u32 vc_bypass_value;
++      u32 reg_addr = 0;
++      u32 loop_cnt = 0, retries_cnt = 0;
++
++      vdd = get_vdd(target_opp);
++      target_opp_no = get_opp_no(target_opp);
++
++      if (vdd == PRCM_VDD1) {
++              sr_status = sr_stop_vddautocomap(SR1);
++
++              PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL_0 & ~PRM_VC_CMD_ON_MASK) |
++                                              (vsel << PRM_VC_CMD_ON_SHIFT);
++              reg_addr = R_VDD1_SR_CONTROL;
++
++      } else if (vdd == PRCM_VDD2) {
++              sr_status = sr_stop_vddautocomap(SR2);
++
++              PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL_1 & ~PRM_VC_CMD_ON_MASK) |
++                                              (vsel << PRM_VC_CMD_ON_SHIFT);
++              reg_addr = R_VDD2_SR_CONTROL;
++      }
++
++      vc_bypass_value = (vsel << PRM_VC_BYPASS_DATA_SHIFT) |
++                      (reg_addr << PRM_VC_BYPASS_REGADDR_SHIFT) |
++                      (R_SRI2C_SLAVE_ADDR << PRM_VC_BYPASS_SLAVEADDR_SHIFT);
++
++      PRM_VC_BYPASS_VAL = vc_bypass_value;
++
++      PRM_VC_BYPASS_VAL |= PRM_VC_BYPASS_VALID;
++
++      DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, PRM_VC_BYPASS_VAL);
++      DPRINTK("PRM_IRQST_MPU %X\n", PRM_IRQSTATUS_MPU);
++
++      while ((PRM_VC_BYPASS_VAL & PRM_VC_BYPASS_VALID) != 0x0) {
++              ret = loop_wait(&loop_cnt, &retries_cnt, 10);
++              if (ret != PRCM_PASS) {
++                      printk(KERN_INFO "Loop count exceeded in check SR I2C"
++                                                              "write\n");
++                      return ret;
++              }
++      }
++
++      omap_udelay(T2_SMPS_UPDATE_DELAY);
++
++      if (sr_status) {
++              if (vdd == PRCM_VDD1)
++                      sr_start_vddautocomap(SR1, target_opp_no);
++              else if (vdd == PRCM_VDD2)
++                      sr_start_vddautocomap(SR2, target_opp_no);
++      }
++
++      return SR_PASS;
++}
++
++/* Sysfs interface to select SR VDD1 auto compensation */
++static ssize_t omap_sr_vdd1_autocomp_show(struct kset *subsys, char *buf)
++{
++      return sprintf(buf, "%d\n", sr1.is_autocomp_active);
++}
++
++static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
++                              const char *buf, size_t n)
++{
++      u32 current_vdd1opp_no;
++      unsigned short value;
++
++      if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
++              printk(KERN_ERR "sr_vdd1_autocomp: Invalid value\n");
++              return -EINVAL;
++      }
++
++      current_vdd1opp_no = get_opp_no(current_vdd1_opp);
++
++      if (value == 0)
++              sr_stop_vddautocomap(SR1);
++      else
++              sr_start_vddautocomap(SR1, current_vdd1opp_no);
++
++      return n;
++}
++
++static struct subsys_attribute sr_vdd1_autocomp = {
++      .attr = {
++      .name = __stringify(sr_vdd1_autocomp),
++      .mode = 0644,
++      },
++      .show = omap_sr_vdd1_autocomp_show,
++      .store = omap_sr_vdd1_autocomp_store,
++};
++
++/* Sysfs interface to select SR VDD2 auto compensation */
++static ssize_t omap_sr_vdd2_autocomp_show(struct kset *subsys, char *buf)
++{
++      return sprintf(buf, "%d\n", sr2.is_autocomp_active);
++}
++
++static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
++                              const char *buf, size_t n)
++{
++      u32 current_vdd2opp_no;
++      unsigned short value;
++
++      if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
++              printk(KERN_ERR "sr_vdd2_autocomp: Invalid value\n");
++              return -EINVAL;
++      }
++
++      current_vdd2opp_no = get_opp_no(current_vdd2_opp);
++
++      if (value == 0)
++              sr_stop_vddautocomap(SR2);
++      else
++              sr_start_vddautocomap(SR2, current_vdd2opp_no);
++
++      return n;
++}
++
++static struct subsys_attribute sr_vdd2_autocomp = {
++      .attr = {
++      .name = __stringify(sr_vdd2_autocomp),
++      .mode = 0644,
++      },
++      .show = omap_sr_vdd2_autocomp_show,
++      .store = omap_sr_vdd2_autocomp_store,
++};
++
++
++
++static int __init omap3_sr_init(void)
++{
++      int ret = 0;
++      u8 RdReg;
++
++#ifdef CONFIG_ARCH_OMAP34XX
++      sr1.fck = clk_get(NULL, "sr1_fck");
++      if (IS_ERR(sr1.fck))
++              printk(KERN_ERR "Could not get sr1_fck\n");
++
++      sr2.fck = clk_get(NULL, "sr2_fck");
++      if (IS_ERR(sr2.fck))
++              printk(KERN_ERR "Could not get sr2_fck\n");
++#endif /* #ifdef CONFIG_ARCH_OMAP34XX */
++
++      /* Call the VPConfig, VCConfig, set N Values. */
++      sr_set_nvalues(&sr1);
++      sr_configure_vp(SR1);
++
++      sr_set_nvalues(&sr2);
++      sr_configure_vp(SR2);
++
++      sr_configure_vc();
++
++      /* Enable SR on T2 */
++      ret = t2_in(PM_RECEIVER, &RdReg, R_DCDC_GLOBAL_CFG);
++      RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
++      ret |= t2_out(PM_RECEIVER, RdReg, R_DCDC_GLOBAL_CFG);
++
++
++      printk(KERN_INFO "SmartReflex driver initialized\n");
++
++      ret = subsys_create_file(&power_subsys, &sr_vdd1_autocomp);
++      if (ret)
++              printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
++
++      ret = subsys_create_file(&power_subsys, &sr_vdd2_autocomp);
++      if (ret)
++              printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
++
++      return 0;
++}
++
++arch_initcall(omap3_sr_init);
+diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
+new file mode 100644
+index 0000000..62907ef
+--- /dev/null
++++ b/arch/arm/mach-omap2/smartreflex.h
+@@ -0,0 +1,136 @@
++/*
++ * linux/arch/arm/mach-omap3/smartreflex.h
++ *
++ * Copyright (C) 2007 Texas Instruments, Inc.
++ * Lesly A M <x0080970@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++
++/* SR Modules */
++#define SR1           1
++#define SR2           2
++
++#define SR_FAIL               1
++#define SR_PASS               0
++
++#define SR_TRUE               1
++#define SR_FALSE      0
++
++#define GAIN_MAXLIMIT 16
++#define R_MAXLIMIT    256
++
++#define SR1_CLK_ENABLE        (0x1 << 6)
++#define SR2_CLK_ENABLE        (0x1 << 7)
++
++/* PRM_VP1_CONFIG */
++#define PRM_VP1_CONFIG_ERROROFFSET    (0x00 << 24)
++#define PRM_VP1_CONFIG_ERRORGAIN      (0x20 << 16)
++
++#define PRM_VP1_CONFIG_INITVOLTAGE    (0x30 << 8) /* 1.2 volt */
++#define PRM_VP1_CONFIG_TIMEOUTEN      (0x1 << 3)
++#define PRM_VP1_CONFIG_INITVDD                (0x1 << 2)
++#define PRM_VP1_CONFIG_FORCEUPDATE    (0x1 << 1)
++#define PRM_VP1_CONFIG_VPENABLE               (0x1 << 0)
++
++/* PRM_VP1_VSTEPMIN */
++#define PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN      (0x01F4 << 8)
++#define PRM_VP1_VSTEPMIN_VSTEPMIN             (0x01 << 0)
++
++/* PRM_VP1_VSTEPMAX */
++#define PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX      (0x01F4 << 8)
++#define PRM_VP1_VSTEPMAX_VSTEPMAX             (0x04 << 0)
++
++/* PRM_VP1_VLIMITTO */
++#define PRM_VP1_VLIMITTO_VDDMAX               (0x3C << 24)
++#define PRM_VP1_VLIMITTO_VDDMIN               (0x0 << 16)
++#define PRM_VP1_VLIMITTO_TIMEOUT      (0xFFFF << 0)
++
++/* PRM_VP2_CONFIG */
++#define PRM_VP2_CONFIG_ERROROFFSET    (0x00 << 24)
++#define PRM_VP2_CONFIG_ERRORGAIN      (0x20 << 16)
++
++#define PRM_VP2_CONFIG_INITVOLTAGE    (0x30 << 8) /* 1.2 volt */
++#define PRM_VP2_CONFIG_TIMEOUTEN      (0x1 << 3)
++#define PRM_VP2_CONFIG_INITVDD                (0x1 << 2)
++#define PRM_VP2_CONFIG_FORCEUPDATE    (0x1 << 1)
++#define PRM_VP2_CONFIG_VPENABLE               (0x1 << 0)
++
++/* PRM_VP2_VSTEPMIN */
++#define PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN      (0x01F4 << 8)
++#define PRM_VP2_VSTEPMIN_VSTEPMIN             (0x01 << 0)
++
++/* PRM_VP2_VSTEPMAX */
++#define PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX      (0x01F4 << 8)
++#define PRM_VP2_VSTEPMAX_VSTEPMAX             (0x04 << 0)
++
++/* PRM_VP2_VLIMITTO */
++#define PRM_VP2_VLIMITTO_VDDMAX               (0x2C << 24)
++#define PRM_VP2_VLIMITTO_VDDMIN               (0x0 << 16)
++#define PRM_VP2_VLIMITTO_TIMEOUT      (0xFFFF << 0)
++
++/* SRCONFIG */
++#define SR1_SRCONFIG_ACCUMDATA                (0x1F4 << 22)
++#define SR2_SRCONFIG_ACCUMDATA                (0x1F4 << 22)
++
++#define SRCLKLENGTH_12MHZ_SYSCLK      0x3C
++#define SRCLKLENGTH_13MHZ_SYSCLK      0x41
++#define SRCLKLENGTH_19MHZ_SYSCLK      0x60
++#define SRCLKLENGTH_26MHZ_SYSCLK      0x82
++#define SRCLKLENGTH_38MHZ_SYSCLK      0xC0
++
++#define SRCONFIG_SRCLKLENGTH_SHIFT    12
++#define SRCONFIG_SENNENABLE_SHIFT     5
++#define SRCONFIG_SENPENABLE_SHIFT     3
++
++#define SRCONFIG_SRENABLE             (0x01 << 11)
++#define SRCONFIG_SENENABLE            (0x01 << 10)
++#define SRCONFIG_ERRGEN_EN            (0x01 << 9)
++#define SRCONFIG_MINMAXAVG_EN         (0x01 << 8)
++
++#define SRCONFIG_DELAYCTRL            (0x01 << 2)
++#define SRCONFIG_CLKCTRL              (0x00 << 0)
++
++/* AVGWEIGHT */
++#define SR1_AVGWEIGHT_SENPAVGWEIGHT   (0x03 << 2)
++#define SR1_AVGWEIGHT_SENNAVGWEIGHT   (0x03 << 0)
++
++#define SR2_AVGWEIGHT_SENPAVGWEIGHT   (0x01 << 2)
++#define SR2_AVGWEIGHT_SENNAVGWEIGHT   (0x01 << 0)
++
++/* NVALUERECIPROCAL */
++#define NVALUERECIPROCAL_SENPGAIN_SHIFT       20
++#define NVALUERECIPROCAL_SENNGAIN_SHIFT       16
++#define NVALUERECIPROCAL_RNSENP_SHIFT 8
++#define NVALUERECIPROCAL_RNSENN_SHIFT 0
++
++/* ERRCONFIG */
++#define SR_CLKACTIVITY_MASK           (0x03 << 20)
++#define SR_ERRWEIGHT_MASK             (0x07 << 16)
++#define SR_ERRMAXLIMIT_MASK           (0xFF << 8)
++#define SR_ERRMINLIMIT_MASK           (0xFF << 0)
++
++#define SR_CLKACTIVITY_IOFF_FOFF      (0x00 << 20)
++#define SR_CLKACTIVITY_IOFF_FON               (0x02 << 20)
++
++#define ERRCONFIG_VPBOUNDINTEN                (0x1 << 31)
++#define ERRCONFIG_VPBOUNDINTST                (0x1 << 30)
++
++#define SR1_ERRWEIGHT                 (0x07 << 16)
++#define SR1_ERRMAXLIMIT                       (0x02 << 8)
++#define SR1_ERRMINLIMIT                       (0xFA << 0)
++
++#define SR2_ERRWEIGHT                 (0x07 << 16)
++#define SR2_ERRMAXLIMIT                       (0x02 << 8)
++#define SR2_ERRMINLIMIT                       (0xF9 << 0)
++
++extern u32 current_vdd1_opp;
++extern u32 current_vdd2_opp;
++extern struct kset power_subsys;
++
++extern inline int loop_wait(u32 *lcnt, u32 *rcnt, u32 delay);
++extern void omap_udelay(u32 udelay);
++
+-- 
+1.5.4.3
diff --git a/packages/linux/linux-omap2-git/beagleboard/0002-ARM-OMAP-SmartReflex-driver.patch b/packages/linux/linux-omap2-git/beagleboard/0002-ARM-OMAP-SmartReflex-driver.patch
new file mode 100644 (file)
index 0000000..a5e2e63
--- /dev/null
@@ -0,0 +1,242 @@
+From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+To: linux-omap@vger.kernel.org
+Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+Subject: [PATCH 2/3] ARM: OMAP: SmartReflex driver: added required register and bit definitions.
+Date:  Fri, 30 May 2008 17:12:26 +0300
+
+Added new register and bit definitions to enable Smartreflex driver integration.
+Also PRM_VC_SMPS_SA bit definitions' naming was changed to match the naming of
+other similar bit definitions.
+
+
+Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+---
+ arch/arm/mach-omap2/prm-regbits-34xx.h |   27 ++++++--
+ arch/arm/mach-omap2/smartreflex.h      |  124 ++++++++++++++++++++++++++++++-
+ include/asm-arm/arch-omap/omap34xx.h   |    2 +
+ 3 files changed, 144 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
+index c6a7940..f82b5a7 100644
+--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
++++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
+@@ -435,10 +435,10 @@
+ /* PM_PWSTST_EMU specific bits */
+ /* PRM_VC_SMPS_SA */
+-#define OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT             16
+-#define OMAP3430_PRM_VC_SMPS_SA_SA1_MASK              (0x7f << 16)
+-#define OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT             0
+-#define OMAP3430_PRM_VC_SMPS_SA_SA0_MASK              (0x7f << 0)
++#define OMAP3430_SMPS_SA1_SHIFT                               16
++#define OMAP3430_SMPS_SA1_MASK                                (0x7f << 16)
++#define OMAP3430_SMPS_SA0_SHIFT                               0
++#define OMAP3430_SMPS_SA0_MASK                                (0x7f << 0)
+ /* PRM_VC_SMPS_VOL_RA */
+ #define OMAP3430_VOLRA1_SHIFT                         16
+@@ -452,7 +452,7 @@
+ #define OMAP3430_CMDRA0_SHIFT                         0
+ #define OMAP3430_CMDRA0_MASK                          (0xff << 0)
+-/* PRM_VC_CMD_VAL_0 specific bits */
++/* PRM_VC_CMD_VAL */
+ #define OMAP3430_VC_CMD_ON_SHIFT                      24
+ #define OMAP3430_VC_CMD_ON_MASK                               (0xFF << 24)
+ #define OMAP3430_VC_CMD_ONLP_SHIFT                    16
+@@ -462,7 +462,17 @@
+ #define OMAP3430_VC_CMD_OFF_SHIFT                     0
+ #define OMAP3430_VC_CMD_OFF_MASK                      (0xFF << 0)
++/* PRM_VC_CMD_VAL_0 specific bits */
++#define OMAP3430_VC_CMD_VAL0_ON                               (0x3 << 4)
++#define OMAP3430_VC_CMD_VAL0_ONLP                     (0x3 << 3)
++#define OMAP3430_VC_CMD_VAL0_RET                      (0x3 << 3)
++#define OMAP3430_VC_CMD_VAL0_OFF                      (0x3 << 3)
++
+ /* PRM_VC_CMD_VAL_1 specific bits */
++#define OMAP3430_VC_CMD_VAL1_ON                               (0xB << 2)
++#define OMAP3430_VC_CMD_VAL1_ONLP                     (0x3 << 3)
++#define OMAP3430_VC_CMD_VAL1_RET                      (0x3 << 3)
++#define OMAP3430_VC_CMD_VAL1_OFF                      (0x3 << 3)
+ /* PRM_VC_CH_CONF */
+ #define OMAP3430_CMD1                                 (1 << 20)
+@@ -521,6 +531,13 @@
+ #define OMAP3430_AUTO_RET                             (1 << 1)
+ #define OMAP3430_AUTO_SLEEP                           (1 << 0)
++/* Constants to define setup durations */
++#define OMAP3430_CLKSETUP_DURATION                    0xff
++#define OMAP3430_VOLTSETUP_TIME2                      0xfff
++#define OMAP3430_VOLTSETUP_TIME1                      0xfff
++#define OMAP3430_VOLTOFFSET_DURATION                  0xff
++#define OMAP3430_VOLTSETUP2_DURATION                  0xff
++
+ /* PRM_SRAM_PCHARGE */
+ #define OMAP3430_PCHARGE_TIME_SHIFT                   0
+ #define OMAP3430_PCHARGE_TIME_MASK                    (0xff << 0)
+diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
+index 62907ef..2091a15 100644
+--- a/arch/arm/mach-omap2/smartreflex.h
++++ b/arch/arm/mach-omap2/smartreflex.h
+@@ -1,5 +1,10 @@
++#ifndef __ARCH_ARM_MACH_OMAP3_SMARTREFLEX_H
++#define __ARCH_ARM_MACH_OMAP3_SMARTREFLEX_H
+ /*
+- * linux/arch/arm/mach-omap3/smartreflex.h
++ * linux/arch/arm/mach-omap2/smartreflex.h
++ *
++ * Copyright (C) 2008 Nokia Corporation
++ * Kalle Jokiniemi
+  *
+  * Copyright (C) 2007 Texas Instruments, Inc.
+  * Lesly A M <x0080970@ti.com>
+@@ -9,6 +14,21 @@
+  * published by the Free Software Foundation.
+  */
++#define PHY_TO_OFF_PM_MASTER(p)               (p - 0x36)
++#define PHY_TO_OFF_PM_RECIEVER(p)     (p - 0x5b)
++#define PHY_TO_OFF_PM_INT(p)          (p - 0x2e)
++
++/* SMART REFLEX REG ADDRESS OFFSET */
++#define SRCONFIG      0x00
++#define SRSTATUS      0x04
++#define SENVAL                0x08
++#define SENMIN                0x0C
++#define SENMAX                0x10
++#define SENAVG                0x14
++#define AVGWEIGHT     0x18
++#define NVALUERECIPROCAL      0x1C
++#define SENERROR      0x20
++#define ERRCONFIG     0x24
+ /* SR Modules */
+ #define SR1           1
+@@ -127,10 +147,106 @@
+ #define SR2_ERRMAXLIMIT                       (0x02 << 8)
+ #define SR2_ERRMINLIMIT                       (0xF9 << 0)
++/* T2 SMART REFLEX */
++#define R_SRI2C_SLAVE_ADDR            0x12
++#define R_VDD1_SR_CONTROL             0x00
++#define R_VDD2_SR_CONTROL             0x01
++#define T2_SMPS_UPDATE_DELAY          360     /* In uSec */
++
++/* Vmode control */
++#define R_DCDC_GLOBAL_CFG     PHY_TO_OFF_PM_RECIEVER(0x61)
++
++#define R_VDD1_VSEL           PHY_TO_OFF_PM_RECIEVER(0xb9)
++#define R_VDD1_VMODE_CFG      PHY_TO_OFF_PM_RECIEVER(0xba)
++#define R_VDD1_VFLOOR         PHY_TO_OFF_PM_RECIEVER(0xbb)
++#define R_VDD1_VROOF          PHY_TO_OFF_PM_RECIEVER(0xbc)
++#define R_VDD1_STEP           PHY_TO_OFF_PM_RECIEVER(0xbd)
++
++#define R_VDD2_VSEL           PHY_TO_OFF_PM_RECIEVER(0xc7)
++#define R_VDD2_VMODE_CFG      PHY_TO_OFF_PM_RECIEVER(0xc8)
++#define R_VDD2_VFLOOR         PHY_TO_OFF_PM_RECIEVER(0xc9)
++#define R_VDD2_VROOF          PHY_TO_OFF_PM_RECIEVER(0xca)
++#define R_VDD2_STEP           PHY_TO_OFF_PM_RECIEVER(0xcb)
++
++/* R_DCDC_GLOBAL_CFG register, SMARTREFLEX_ENABLE valuws */
++#define DCDC_GLOBAL_CFG_ENABLE_SRFLX  0x08
++
++/* VDDs*/
++#define PRCM_VDD1     1
++#define PRCM_VDD2     2
++#define PRCM_MAX_SYSC_REGS 30
++
++/* XXX: These should be removed/moved from here once we have a working DVFS
++   implementation in place */
++#define AT_3430               1       /*3430 ES 1.0 */
++#define AT_3430_ES2   2       /*3430 ES 2.0 */
++
++#define ID_OPP                        0xE2    /*OPP*/
++
++/* DEVICE ID/DPLL ID/CLOCK ID: bits 28-31 for OMAP type */
++#define OMAP_TYPE_SHIFT               28
++#define OMAP_TYPE_MASK                0xF
++/* OPP ID: bits: 0-4 for OPP number */
++#define OPP_NO_POS            0
++#define OPP_NO_MASK           0x1F
++/* OPP ID: bits: 5-6 for VDD */
++#define VDD_NO_POS            5
++#define VDD_NO_MASK           0x3
++/* Other IDs: bits 20-27 for ID type */
++/* These IDs have bits 25,26,27 as 1 */
++#define OTHER_ID_TYPE_SHIFT           20
++#define OTHER_ID_TYPE_MASK            0xFF
++
++#define OTHER_ID_TYPE(X) ((X & OTHER_ID_TYPE_MASK) << OTHER_ID_TYPE_SHIFT)
++#define ID_OPP_NO(X)   ((X & OPP_NO_MASK) << OPP_NO_POS)
++#define ID_VDD(X)      ((X & VDD_NO_MASK) << VDD_NO_POS)
++#define OMAP(X)                ((X >> OMAP_TYPE_SHIFT) & OMAP_TYPE_MASK)
++#define get_opp_no(X)  ((X >> OPP_NO_POS) & OPP_NO_MASK)
++#define get_vdd(X)     ((X >> VDD_NO_POS) & VDD_NO_MASK)
++
++/* VDD1 OPPs */
++#define PRCM_VDD1_OPP1                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x1))
++#define PRCM_VDD1_OPP2                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x2))
++#define PRCM_VDD1_OPP3                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x3))
++#define PRCM_VDD1_OPP4                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x4))
++#define PRCM_VDD1_OPP5                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x5))
++#define PRCM_NO_VDD1_OPPS     5
++
++
++/* VDD2 OPPs */
++#define PRCM_VDD2_OPP1                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x1))
++#define PRCM_VDD2_OPP2                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x2))
++#define PRCM_VDD2_OPP3                (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
++                                      ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x3))
++#define PRCM_NO_VDD2_OPPS     3
++/* XXX: end remove/move */
++
++
++/* XXX: find more appropriate place for these once DVFS is in place */
+ extern u32 current_vdd1_opp;
+ extern u32 current_vdd2_opp;
+-extern struct kset power_subsys;
+-extern inline int loop_wait(u32 *lcnt, u32 *rcnt, u32 delay);
+-extern void omap_udelay(u32 udelay);
++/*
++ * Smartreflex module enable/disable interface.
++ * NOTE: if smartreflex is not enabled from sysfs, these functions will not
++ * do anything.
++ */
++#if defined(CONFIG_ARCH_OMAP34XX) && defined(CONFIG_TWL4030_CORE)
++void enable_smartreflex(int srid);
++void disable_smartreflex(int srid);
++#else
++static inline void enable_smartreflex(int srid) {}
++static inline void disable_smartreflex(int srid) {}
++#endif
++
++
++#endif
++
+diff --git a/include/asm-arm/arch-omap/omap34xx.h b/include/asm-arm/arch-omap/omap34xx.h
+index 6a0459a..3667fd6 100644
+--- a/include/asm-arm/arch-omap/omap34xx.h
++++ b/include/asm-arm/arch-omap/omap34xx.h
+@@ -54,6 +54,8 @@
+ #define OMAP34XX_HSUSB_HOST_BASE      (L4_34XX_BASE + 0x64000)
+ #define OMAP34XX_USBTLL_BASE  (L4_34XX_BASE + 0x62000)
+ #define IRQ_SIR_IRQ           0x0040
++#define OMAP34XX_SR1_BASE     0x480C9000
++#define OMAP34XX_SR2_BASE     0x480CB000
+ #if defined(CONFIG_ARCH_OMAP3430)
+-- 
+1.5.4.3
+
diff --git a/packages/linux/linux-omap2-git/beagleboard/0003-ARM-OMAP-SmartReflex-driver.patch b/packages/linux/linux-omap2-git/beagleboard/0003-ARM-OMAP-SmartReflex-driver.patch
new file mode 100644 (file)
index 0000000..3c01abd
--- /dev/null
@@ -0,0 +1,870 @@
+From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+To: linux-omap@vger.kernel.org
+Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+Subject: [PATCH 3/3] ARM: OMAP: SmartReflex driver: integration to linux-omap
+Date:  Mon,  2 Jun 2008 14:30:14 +0300
+
+- Changed register accesses to use prm_{read,write}_mod_reg and
+  prm_{set,clear,rmw}_mod_reg_bits() functions instread of
+  "REG_X = REG_Y" type accesses.
+
+- Changed direct register clock enables/disables to clockframework calls.
+
+- replaced cpu-related #ifdefs with if (cpu_is_xxxx()) calls.
+
+- removed EFUSE related ifdefs
+
+- added smartreflex_disable/enable calls to pm34xx.c suspend function.
+
+- Added "SmartReflex support" entry into Kconfig under "System type->TI OMAP
+  Implementations". It depends on ARCH_OMAP34XX and TWL4030_CORE.
+
+Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
+---
+ arch/arm/mach-omap2/Makefile      |    3 +
+ arch/arm/mach-omap2/pm34xx.c      |    9 +
+ arch/arm/mach-omap2/smartreflex.c |  457 ++++++++++++++++++++++---------------
+ arch/arm/mach-omap2/smartreflex.h |    2 +-
+ arch/arm/plat-omap/Kconfig        |   17 ++
+ 5 files changed, 302 insertions(+), 186 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
+index 50c6657..f645b6e 100644
+--- a/arch/arm/mach-omap2/Makefile
++++ b/arch/arm/mach-omap2/Makefile
+@@ -25,6 +25,9 @@ obj-$(CONFIG_ARCH_OMAP3)             += pm34xx.o sleep34xx.o
+ obj-$(CONFIG_PM_DEBUG)                        += pm-debug.o
+ endif
++# SmartReflex driver
++obj-$(CONFIG_OMAP_SMARTREFLEX)                += smartreflex.o
++
+ # Clock framework
+ obj-$(CONFIG_ARCH_OMAP2)              += clock24xx.o
+ obj-$(CONFIG_ARCH_OMAP3)              += clock34xx.o
+diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
+index 7e775cc..3da4f47 100644
+--- a/arch/arm/mach-omap2/pm34xx.c
++++ b/arch/arm/mach-omap2/pm34xx.c
+@@ -36,6 +36,7 @@
+ #include "prm.h"
+ #include "pm.h"
++#include "smartreflex.h"
+ struct power_state {
+       struct powerdomain *pwrdm;
+@@ -256,6 +257,10 @@ static int omap3_pm_suspend(void)
+       struct power_state *pwrst;
+       int state, ret = 0;
++      /* XXX Disable smartreflex before entering suspend */
++      disable_smartreflex(SR1);
++      disable_smartreflex(SR2);
++
+       /* Read current next_pwrsts */
+       list_for_each_entry(pwrst, &pwrst_list, node)
+               pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+@@ -287,6 +292,10 @@ restore:
+               printk(KERN_INFO "Successfully put all powerdomains "
+                      "to target state\n");
++      /* XXX Enable smartreflex after suspend */
++      enable_smartreflex(SR1);
++      enable_smartreflex(SR2);
++
+       return ret;
+ }
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index dae7460..253369b 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -3,6 +3,9 @@
+  *
+  * OMAP34XX SmartReflex Voltage Control
+  *
++ * Copyright (C) 2008 Nokia Corporation
++ * Kalle Jokiniemi
++ *
+  * Copyright (C) 2007 Texas Instruments, Inc.
+  * Lesly A M <x0080970@ti.com>
+  *
+@@ -20,13 +23,15 @@
+ #include <linux/err.h>
+ #include <linux/clk.h>
+ #include <linux/sysfs.h>
+-
+-#include <asm/arch/prcm.h>
+-#include <asm/arch/power_companion.h>
++#include <linux/kobject.h>
++#include <linux/i2c/twl4030.h>
+ #include <linux/io.h>
+-#include "prcm-regs.h"
++#include <asm/arch/omap34xx.h>
++
++#include "prm.h"
+ #include "smartreflex.h"
++#include "prm-regbits-34xx.h"
+ /* #define DEBUG_SR 1 */
+@@ -37,11 +42,16 @@
+ #  define DPRINTK(fmt, args...)
+ #endif
++/* XXX: These should be relocated where-ever the OPP implementation will be */
++u32 current_vdd1_opp;
++u32 current_vdd2_opp;
++
+ struct omap_sr{
+       int srid;
+       int is_sr_reset;
+       int is_autocomp_active;
+       struct clk *fck;
++      u32 clk_length;
+       u32 req_opp_no;
+       u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue, opp5_nvalue;
+       u32 senp_mod, senn_mod;
+@@ -53,6 +63,7 @@ static struct omap_sr sr1 = {
+       .srid = SR1,
+       .is_sr_reset = 1,
+       .is_autocomp_active = 0,
++      .clk_length = 0,
+       .srbase_addr = OMAP34XX_SR1_BASE,
+ };
+@@ -60,6 +71,7 @@ static struct omap_sr sr2 = {
+       .srid = SR2,
+       .is_sr_reset = 1,
+       .is_autocomp_active = 0,
++      .clk_length = 0,
+       .srbase_addr = OMAP34XX_SR2_BASE,
+ };
+@@ -85,8 +97,6 @@ static inline u32 sr_read_reg(struct omap_sr *sr, int offset)
+       return omap_readl(sr->srbase_addr + offset);
+ }
+-
+-#ifndef USE_EFUSE_VALUES
+ static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
+ {
+       u32 gn, rn, mul;
+@@ -100,7 +110,21 @@ static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
+               }
+       }
+ }
+-#endif
++
++static void sr_clk_get(struct omap_sr *sr)
++{
++      if (sr->srid == SR1) {
++              sr->fck = clk_get(NULL, "sr1_fck");
++              if (IS_ERR(sr->fck))
++                      printk(KERN_ERR "Could not get sr1_fck\n");
++
++      } else if (sr->srid == SR2) {
++              sr->fck = clk_get(NULL, "sr2_fck");
++              if (IS_ERR(sr->fck))
++                      printk(KERN_ERR "Could not get sr2_fck\n");
++
++      }
++}
+ static int sr_clk_enable(struct omap_sr *sr)
+ {
+@@ -131,20 +155,48 @@ static int sr_clk_disable(struct omap_sr *sr)
+       return 0;
+ }
++static void sr_set_clk_length(struct omap_sr *sr)
++{
++      struct clk *osc_sys_ck;
++      u32 sys_clk = 0;
++
++      osc_sys_ck = clk_get(NULL, "osc_sys_ck");
++      sys_clk = clk_get_rate(osc_sys_ck);
++      clk_put(osc_sys_ck);
++
++      switch (sys_clk) {
++      case 12000000:
++              sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
++              break;
++      case 13000000:
++              sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
++              break;
++      case 19200000:
++              sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
++              break;
++      case 26000000:
++              sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
++              break;
++      case 38400000:
++              sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
++              break;
++      default :
++              printk(KERN_ERR "Invalid sysclk value: %d\n", sys_clk);
++              break;
++      }
++}
++
++/*
++ * TODO: once EFUSE is available, it should be used instead of these
++ * pre-calculated values.
++ */
+ static void sr_set_nvalues(struct omap_sr *sr)
+ {
+-#ifdef USE_EFUSE_VALUES
+-      u32 n1, n2;
+-#else
+       u32 senpval, sennval;
+       u32 senpgain, senngain;
+       u32 rnsenp, rnsenn;
+-#endif
+       if (sr->srid == SR1) {
+-#ifdef USE_EFUSE_VALUES
+-              /* Read values for VDD1 from EFUSE */
+-#else
+               /* since E-Fuse Values are not available, calculating the
+                * reciprocal of the SenN and SenP values for SR1
+                */
+@@ -216,15 +268,16 @@ static void sr_set_nvalues(struct omap_sr *sr)
+                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
+                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
++              /* XXX The clocks are enabled in the startup and NVALUE is
++               * set also there. Disabling this for now, but this could
++               * be related to dynamic sleep during boot */
++#if 0
+               sr_clk_enable(sr);
+               sr_write_reg(sr, NVALUERECIPROCAL, sr->opp3_nvalue);
+               sr_clk_disable(sr);
+-
+ #endif
++
+       } else if (sr->srid == SR2) {
+-#ifdef USE_EFUSE_VALUES
+-              /* Read values for VDD2 from EFUSE */
+-#else
+               /* since E-Fuse Values are not available, calculating the
+                * reciprocal of the SenN and SenP values for SR2
+                */
+@@ -269,8 +322,6 @@ static void sr_set_nvalues(struct omap_sr *sr)
+                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
+                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
+                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
+-
+-#endif
+       }
+ }
+@@ -281,122 +332,145 @@ static void sr_configure_vp(int srid)
+       if (srid == SR1) {
+               vpconfig = PRM_VP1_CONFIG_ERROROFFSET | PRM_VP1_CONFIG_ERRORGAIN
+-                      | PRM_VP1_CONFIG_INITVOLTAGE | PRM_VP1_CONFIG_TIMEOUTEN;
+-
+-              PRM_VP1_CONFIG = vpconfig;
+-              PRM_VP1_VSTEPMIN = PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
+-                                              PRM_VP1_VSTEPMIN_VSTEPMIN;
+-
+-              PRM_VP1_VSTEPMAX = PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
+-                                              PRM_VP1_VSTEPMAX_VSTEPMAX;
+-
+-              PRM_VP1_VLIMITTO = PRM_VP1_VLIMITTO_VDDMAX |
+-                      PRM_VP1_VLIMITTO_VDDMIN | PRM_VP1_VLIMITTO_TIMEOUT;
+-
+-              PRM_VP1_CONFIG |= PRM_VP1_CONFIG_INITVDD;
+-              PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_INITVDD;
++                                      | PRM_VP1_CONFIG_INITVOLTAGE
++                                      | PRM_VP1_CONFIG_TIMEOUTEN;
++
++              prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_CONFIG_OFFSET);
++              prm_write_mod_reg(PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
++                                      PRM_VP1_VSTEPMIN_VSTEPMIN,
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_VSTEPMIN_OFFSET);
++
++              prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
++                                      PRM_VP1_VSTEPMAX_VSTEPMAX,
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_VSTEPMAX_OFFSET);
++
++              prm_write_mod_reg(PRM_VP1_VLIMITTO_VDDMAX |
++                                      PRM_VP1_VLIMITTO_VDDMIN |
++                                      PRM_VP1_VLIMITTO_TIMEOUT,
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_VLIMITTO_OFFSET);
++
++              /* Trigger initVDD value copy to voltage processor */
++              prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_CONFIG_OFFSET);
++              /* Clear initVDD copy trigger bit */
++              prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_CONFIG_OFFSET);
+       } else if (srid == SR2) {
+               vpconfig = PRM_VP2_CONFIG_ERROROFFSET | PRM_VP2_CONFIG_ERRORGAIN
+-                      | PRM_VP2_CONFIG_INITVOLTAGE | PRM_VP2_CONFIG_TIMEOUTEN;
+-
+-              PRM_VP2_CONFIG = vpconfig;
+-              PRM_VP2_VSTEPMIN = PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
+-                                              PRM_VP2_VSTEPMIN_VSTEPMIN;
+-
+-              PRM_VP2_VSTEPMAX = PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
+-                                              PRM_VP2_VSTEPMAX_VSTEPMAX;
+-
+-              PRM_VP2_VLIMITTO = PRM_VP2_VLIMITTO_VDDMAX |
+-                      PRM_VP2_VLIMITTO_VDDMIN | PRM_VP2_VLIMITTO_TIMEOUT;
+-
+-              PRM_VP2_CONFIG |= PRM_VP2_CONFIG_INITVDD;
+-              PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_INITVDD;
++                                      | PRM_VP2_CONFIG_INITVOLTAGE
++                                      | PRM_VP2_CONFIG_TIMEOUTEN;
++
++              prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_CONFIG_OFFSET);
++              prm_write_mod_reg(PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
++                                      PRM_VP2_VSTEPMIN_VSTEPMIN,
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_VSTEPMIN_OFFSET);
++
++              prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
++                                      PRM_VP2_VSTEPMAX_VSTEPMAX,
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_VSTEPMAX_OFFSET);
++
++              prm_write_mod_reg(PRM_VP2_VLIMITTO_VDDMAX |
++                                      PRM_VP2_VLIMITTO_VDDMIN |
++                                      PRM_VP2_VLIMITTO_TIMEOUT,
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_VLIMITTO_OFFSET);
++
++              /* Trigger initVDD value copy to voltage processor */
++              prm_set_mod_reg_bits(PRM_VP2_CONFIG_INITVDD, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_CONFIG_OFFSET);
++              /* Reset initVDD copy trigger bit */
++              prm_clear_mod_reg_bits(PRM_VP2_CONFIG_INITVDD, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_CONFIG_OFFSET);
+       }
+ }
+ static void sr_configure_vc(void)
+ {
+-      PRM_VC_SMPS_SA =
+-              (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA1_SHIFT) |
+-              (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA0_SHIFT);
+-
+-      PRM_VC_SMPS_VOL_RA = (R_VDD2_SR_CONTROL << PRM_VC_SMPS_VOLRA1_SHIFT) |
+-                              (R_VDD1_SR_CONTROL << PRM_VC_SMPS_VOLRA0_SHIFT);
+-
+-      PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL0_ON << PRM_VC_CMD_ON_SHIFT) |
+-                      (PRM_VC_CMD_VAL0_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
+-                      (PRM_VC_CMD_VAL0_RET << PRM_VC_CMD_RET_SHIFT) |
+-                      (PRM_VC_CMD_VAL0_OFF << PRM_VC_CMD_OFF_SHIFT);
+-
+-      PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL1_ON << PRM_VC_CMD_ON_SHIFT) |
+-                      (PRM_VC_CMD_VAL1_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
+-                      (PRM_VC_CMD_VAL1_RET << PRM_VC_CMD_RET_SHIFT) |
+-                      (PRM_VC_CMD_VAL1_OFF << PRM_VC_CMD_OFF_SHIFT);
+-
+-      PRM_VC_CH_CONF = PRM_VC_CH_CONF_CMD1 | PRM_VC_CH_CONF_RAV1;
+-
+-      PRM_VC_I2C_CFG = PRM_VC_I2C_CFG_MCODE | PRM_VC_I2C_CFG_HSEN
+-                                                      | PRM_VC_I2C_CFG_SREN;
++      prm_write_mod_reg((R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA1_SHIFT) |
++                      (R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA0_SHIFT),
++                      OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_SA_OFFSET);
++
++      prm_write_mod_reg((R_VDD2_SR_CONTROL << OMAP3430_VOLRA1_SHIFT) |
++                      (R_VDD1_SR_CONTROL << OMAP3430_VOLRA0_SHIFT),
++                      OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET);
++
++      prm_write_mod_reg((OMAP3430_VC_CMD_VAL0_ON <<
++              OMAP3430_VC_CMD_ON_SHIFT) |
++              (OMAP3430_VC_CMD_VAL0_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
++              (OMAP3430_VC_CMD_VAL0_RET << OMAP3430_VC_CMD_RET_SHIFT) |
++              (OMAP3430_VC_CMD_VAL0_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
++              OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
++
++      prm_write_mod_reg((OMAP3430_VC_CMD_VAL1_ON <<
++              OMAP3430_VC_CMD_ON_SHIFT) |
++              (OMAP3430_VC_CMD_VAL1_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
++              (OMAP3430_VC_CMD_VAL1_RET << OMAP3430_VC_CMD_RET_SHIFT) |
++              (OMAP3430_VC_CMD_VAL1_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
++              OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
++
++      prm_write_mod_reg(OMAP3430_CMD1 | OMAP3430_RAV1,
++                              OMAP3430_GR_MOD,
++                              OMAP3_PRM_VC_CH_CONF_OFFSET);
++
++      prm_write_mod_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN | OMAP3430_SREN,
++                              OMAP3430_GR_MOD,
++                              OMAP3_PRM_VC_I2C_CFG_OFFSET);
+       /* Setup voltctrl and other setup times */
++      /* XXX CONFIG_SYSOFFMODE has not been implemented yet */
+ #ifdef CONFIG_SYSOFFMODE
+-      PRM_VOLTCTRL = PRM_VOLTCTRL_AUTO_OFF | PRM_VOLTCTRL_AUTO_RET;
+-      PRM_CLKSETUP = PRM_CLKSETUP_DURATION;
+-      PRM_VOLTSETUP1 = (PRM_VOLTSETUP_TIME2 << PRM_VOLTSETUP_TIME2_OFFSET) |
+-                      (PRM_VOLTSETUP_TIME1 << PRM_VOLTSETUP_TIME1_OFFSET);
+-      PRM_VOLTOFFSET = PRM_VOLTOFFSET_DURATION;
+-      PRM_VOLTSETUP2 = PRM_VOLTSETUP2_DURATION;
++      prm_write_mod_reg(OMAP3430_AUTO_OFF | OMAP3430_AUTO_RET,
++                      OMAP3430_GR_MOD,
++                      OMAP3_PRM_VOLTCTRL_OFFSET);
++
++      prm_write_mod_reg(OMAP3430_CLKSETUP_DURATION, OMAP3430_GR_MOD,
++                      OMAP3_PRM_CLKSETUP_OFFSET);
++      prm_write_mod_reg((OMAP3430_VOLTSETUP_TIME2 <<
++                      OMAP3430_VOLTSETUP_TIME2_OFFSET) |
++                      (OMAP3430_VOLTSETUP_TIME1 <<
++                      OMAP3430_VOLTSETUP_TIME1_OFFSET),
++                      OMAP3430_GR_MOD, OMAP3_PRM_VOLTSETUP1_OFFSET);
++
++      prm_write_mod_reg(OMAP3430_VOLTOFFSET_DURATION, OMAP3430_GR_MOD,
++                      OMAP3_PRM_VOLTOFFSET_OFFSET);
++      prm_write_mod_reg(OMAP3430_VOLTSETUP2_DURATION, OMAP3430_GR_MOD,
++                      OMAP3_PRM_VOLTSETUP2_OFFSET);
+ #else
+-      PRM_VOLTCTRL |= PRM_VOLTCTRL_AUTO_RET;
++      prm_set_mod_reg_bits(OMAP3430_AUTO_RET, OMAP3430_GR_MOD,
++                      OMAP3_PRM_VOLTCTRL_OFFSET);
+ #endif
+ }
+-
+ static void sr_configure(struct omap_sr *sr)
+ {
+-      u32 sys_clk, sr_clk_length = 0;
+       u32 sr_config;
+       u32 senp_en , senn_en;
++      if (sr->clk_length == 0)
++              sr_set_clk_length(sr);
++
+       senp_en = sr->senp_mod;
+       senn_en = sr->senn_mod;
+-
+-      sys_clk = prcm_get_system_clock_speed();
+-
+-      switch (sys_clk) {
+-      case 12000:
+-              sr_clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
+-              break;
+-      case 13000:
+-              sr_clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
+-              break;
+-      case 19200:
+-              sr_clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
+-              break;
+-      case 26000:
+-              sr_clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
+-              break;
+-      case 38400:
+-              sr_clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
+-              break;
+-      default :
+-              printk(KERN_ERR "Invalid sysclk value\n");
+-              break;
+-      }
+-
+-      DPRINTK(KERN_DEBUG "SR : sys clk %lu\n", sys_clk);
+       if (sr->srid == SR1) {
+               sr_config = SR1_SRCONFIG_ACCUMDATA |
+-                      (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
++                      (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+                       SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
+                       SRCONFIG_MINMAXAVG_EN |
+                       (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
+                       (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
+                       SRCONFIG_DELAYCTRL;
+-
++              DPRINTK(KERN_DEBUG "setting SRCONFIG1 to 0x%08lx\n",
++                                              (unsigned long int) sr_config);
+               sr_write_reg(sr, SRCONFIG, sr_config);
+               sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
+@@ -408,18 +482,18 @@ static void sr_configure(struct omap_sr *sr)
+       } else if (sr->srid == SR2) {
+               sr_config = SR2_SRCONFIG_ACCUMDATA |
+-                      (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
++                      (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+                       SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
+                       SRCONFIG_MINMAXAVG_EN |
+                       (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
+                       (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
+                       SRCONFIG_DELAYCTRL;
++              DPRINTK(KERN_DEBUG "setting SRCONFIG2 to 0x%08lx\n",
++                                              (unsigned long int) sr_config);
+               sr_write_reg(sr, SRCONFIG, sr_config);
+-
+               sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
+                                       SR2_AVGWEIGHT_SENNAVGWEIGHT);
+-
+               sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
+                       SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
+                       (SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
+@@ -476,7 +550,6 @@ static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
+       if (current_nvalue == nvalue_reciprocal) {
+               DPRINTK("System is already at the desired voltage level\n");
+-              return;
+       }
+       sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
+@@ -485,18 +558,18 @@ static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
+       sr_modify_reg(sr, ERRCONFIG,
+                       (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
+                       (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
+-
+       if (sr->srid == SR1) {
+               /* Enable VP1 */
+-              PRM_VP1_CONFIG |= PRM_VP1_CONFIG_VPENABLE;
++              prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
++                              OMAP3_PRM_VP1_CONFIG_OFFSET);
+       } else if (sr->srid == SR2) {
+               /* Enable VP2 */
+-              PRM_VP2_CONFIG |= PRM_VP2_CONFIG_VPENABLE;
++              prm_set_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
++                              OMAP3_PRM_VP2_CONFIG_OFFSET);
+       }
+       /* SRCONFIG - enable SR */
+       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
+-
+ }
+ static void sr_disable(struct omap_sr *sr)
+@@ -507,11 +580,13 @@ static void sr_disable(struct omap_sr *sr)
+       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
+       if (sr->srid == SR1) {
+-              /* Enable VP1 */
+-              PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
++              /* Disable VP1 */
++              prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP1_CONFIG_OFFSET);
+       } else if (sr->srid == SR2) {
+-              /* Enable VP2 */
+-              PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
++              /* Disable VP2 */
++              prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VP2_CONFIG_OFFSET);
+       }
+ }
+@@ -574,16 +649,13 @@ void enable_smartreflex(int srid)
+       if (sr->is_autocomp_active == 1) {
+               if (sr->is_sr_reset == 1) {
+-                      if (srid == SR1) {
+-                              /* Enable SR clks */
+-                              CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
+-                              target_opp_no = get_opp_no(current_vdd1_opp);
++                      /* Enable SR clks */
++                      sr_clk_enable(sr);
+-                      } else if (srid == SR2) {
+-                              /* Enable SR clks */
+-                              CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
++                      if (srid == SR1)
++                              target_opp_no = get_opp_no(current_vdd1_opp);
++                      else if (srid == SR2)
+                               target_opp_no = get_opp_no(current_vdd2_opp);
+-                      }
+                       sr_configure(sr);
+@@ -602,15 +674,6 @@ void disable_smartreflex(int srid)
+               sr = &sr2;
+       if (sr->is_autocomp_active == 1) {
+-              if (srid == SR1) {
+-                      /* Enable SR clk */
+-                      CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
+-
+-              } else if (srid == SR2) {
+-                      /* Enable SR clk */
+-                      CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
+-              }
+-
+               if (sr->is_sr_reset == 0) {
+                       sr->is_sr_reset = 1;
+@@ -618,17 +681,18 @@ void disable_smartreflex(int srid)
+                       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
+                                                       ~SRCONFIG_SRENABLE);
++                      /* Disable SR clk */
++                      sr_clk_disable(sr);
+                       if (sr->srid == SR1) {
+-                              /* Disable SR clk */
+-                              CM_FCLKEN_WKUP &= ~SR1_CLK_ENABLE;
+-                              /* Enable VP1 */
+-                              PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
+-
++                              /* Disable VP1 */
++                              prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE,
++                                              OMAP3430_GR_MOD,
++                                              OMAP3_PRM_VP1_CONFIG_OFFSET);
+                       } else if (sr->srid == SR2) {
+-                              /* Disable SR clk */
+-                              CM_FCLKEN_WKUP &= ~SR2_CLK_ENABLE;
+-                              /* Enable VP2 */
+-                              PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
++                              /* Disable VP2 */
++                              prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE,
++                                              OMAP3430_GR_MOD,
++                                              OMAP3_PRM_VP2_CONFIG_OFFSET);
+                       }
+               }
+       }
+@@ -638,7 +702,6 @@ void disable_smartreflex(int srid)
+ /* Voltage Scaling using SR VCBYPASS */
+ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
+ {
+-      int ret;
+       int sr_status = 0;
+       u32 vdd, target_opp_no;
+       u32 vc_bypass_value;
+@@ -651,39 +714,53 @@ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
+       if (vdd == PRCM_VDD1) {
+               sr_status = sr_stop_vddautocomap(SR1);
+-              PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL_0 & ~PRM_VC_CMD_ON_MASK) |
+-                                              (vsel << PRM_VC_CMD_ON_SHIFT);
++              prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
++                                      (vsel << OMAP3430_VC_CMD_ON_SHIFT),
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
+               reg_addr = R_VDD1_SR_CONTROL;
+       } else if (vdd == PRCM_VDD2) {
+               sr_status = sr_stop_vddautocomap(SR2);
+-              PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL_1 & ~PRM_VC_CMD_ON_MASK) |
+-                                              (vsel << PRM_VC_CMD_ON_SHIFT);
++              prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
++                                      (vsel << OMAP3430_VC_CMD_ON_SHIFT),
++                                      OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
+               reg_addr = R_VDD2_SR_CONTROL;
+       }
+-      vc_bypass_value = (vsel << PRM_VC_BYPASS_DATA_SHIFT) |
+-                      (reg_addr << PRM_VC_BYPASS_REGADDR_SHIFT) |
+-                      (R_SRI2C_SLAVE_ADDR << PRM_VC_BYPASS_SLAVEADDR_SHIFT);
++      vc_bypass_value = (vsel << OMAP3430_DATA_SHIFT) |
++                      (reg_addr << OMAP3430_REGADDR_SHIFT) |
++                      (R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
+-      PRM_VC_BYPASS_VAL = vc_bypass_value;
++      prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
++                      OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
+-      PRM_VC_BYPASS_VAL |= PRM_VC_BYPASS_VALID;
++      vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
+-      DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, PRM_VC_BYPASS_VAL);
+-      DPRINTK("PRM_IRQST_MPU %X\n", PRM_IRQSTATUS_MPU);
++      DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, vc_bypass_value);
++      DPRINTK("PRM_IRQST_MPU %X\n", prm_read_mod_reg(OCP_MOD,
++                                      OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
+-      while ((PRM_VC_BYPASS_VAL & PRM_VC_BYPASS_VALID) != 0x0) {
+-              ret = loop_wait(&loop_cnt, &retries_cnt, 10);
+-              if (ret != PRCM_PASS) {
++      while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
++              loop_cnt++;
++              if (retries_cnt > 10) {
+                       printk(KERN_INFO "Loop count exceeded in check SR I2C"
+                                                               "write\n");
+-                      return ret;
++                      return SR_FAIL;
+               }
++              if (loop_cnt > 50) {
++                      retries_cnt++;
++                      loop_cnt = 0;
++                      udelay(10);
++              }
++              vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
++                                      OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
+       }
+-      omap_udelay(T2_SMPS_UPDATE_DELAY);
++      udelay(T2_SMPS_UPDATE_DELAY);
+       if (sr_status) {
+               if (vdd == PRCM_VDD1)
+@@ -696,13 +773,15 @@ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
+ }
+ /* Sysfs interface to select SR VDD1 auto compensation */
+-static ssize_t omap_sr_vdd1_autocomp_show(struct kset *subsys, char *buf)
++static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
++                                      struct kobj_attribute *attr, char *buf)
+ {
+       return sprintf(buf, "%d\n", sr1.is_autocomp_active);
+ }
+-static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
+-                              const char *buf, size_t n)
++static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
++                                      struct kobj_attribute *attr,
++                                      const char *buf, size_t n)
+ {
+       u32 current_vdd1opp_no;
+       unsigned short value;
+@@ -722,7 +801,7 @@ static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
+       return n;
+ }
+-static struct subsys_attribute sr_vdd1_autocomp = {
++static struct kobj_attribute sr_vdd1_autocomp = {
+       .attr = {
+       .name = __stringify(sr_vdd1_autocomp),
+       .mode = 0644,
+@@ -732,13 +811,15 @@ static struct subsys_attribute sr_vdd1_autocomp = {
+ };
+ /* Sysfs interface to select SR VDD2 auto compensation */
+-static ssize_t omap_sr_vdd2_autocomp_show(struct kset *subsys, char *buf)
++static ssize_t omap_sr_vdd2_autocomp_show(struct kobject *kobj,
++                                      struct kobj_attribute *attr, char *buf)
+ {
+       return sprintf(buf, "%d\n", sr2.is_autocomp_active);
+ }
+-static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
+-                              const char *buf, size_t n)
++static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
++                                      struct kobj_attribute *attr,
++                                      const char *buf, size_t n)
+ {
+       u32 current_vdd2opp_no;
+       unsigned short value;
+@@ -758,7 +839,7 @@ static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
+       return n;
+ }
+-static struct subsys_attribute sr_vdd2_autocomp = {
++static struct kobj_attribute sr_vdd2_autocomp = {
+       .attr = {
+       .name = __stringify(sr_vdd2_autocomp),
+       .mode = 0644,
+@@ -774,15 +855,19 @@ static int __init omap3_sr_init(void)
+       int ret = 0;
+       u8 RdReg;
+-#ifdef CONFIG_ARCH_OMAP34XX
+-      sr1.fck = clk_get(NULL, "sr1_fck");
+-      if (IS_ERR(sr1.fck))
+-              printk(KERN_ERR "Could not get sr1_fck\n");
+-
+-      sr2.fck = clk_get(NULL, "sr2_fck");
+-      if (IS_ERR(sr2.fck))
+-              printk(KERN_ERR "Could not get sr2_fck\n");
+-#endif /* #ifdef CONFIG_ARCH_OMAP34XX */
++      if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
++              current_vdd1_opp = PRCM_VDD1_OPP3;
++              current_vdd2_opp = PRCM_VDD2_OPP3;
++      } else {
++              current_vdd1_opp = PRCM_VDD1_OPP1;
++              current_vdd2_opp = PRCM_VDD1_OPP1;
++      }
++      if (cpu_is_omap34xx()) {
++              sr_clk_get(&sr1);
++              sr_clk_get(&sr2);
++      }
++      sr_set_clk_length(&sr1);
++      sr_set_clk_length(&sr2);
+       /* Call the VPConfig, VCConfig, set N Values. */
+       sr_set_nvalues(&sr1);
+@@ -794,22 +879,24 @@ static int __init omap3_sr_init(void)
+       sr_configure_vc();
+       /* Enable SR on T2 */
+-      ret = t2_in(PM_RECEIVER, &RdReg, R_DCDC_GLOBAL_CFG);
+-      RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
+-      ret |= t2_out(PM_RECEIVER, RdReg, R_DCDC_GLOBAL_CFG);
++      ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
++                                      R_DCDC_GLOBAL_CFG);
++      RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
++      ret |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
++                                      R_DCDC_GLOBAL_CFG);
+       printk(KERN_INFO "SmartReflex driver initialized\n");
+-      ret = subsys_create_file(&power_subsys, &sr_vdd1_autocomp);
++      ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
+       if (ret)
+-              printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
++              printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
+-      ret = subsys_create_file(&power_subsys, &sr_vdd2_autocomp);
++      ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
+       if (ret)
+-              printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
++              printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
+       return 0;
+ }
+-arch_initcall(omap3_sr_init);
++late_initcall(omap3_sr_init);
+diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
+index 2091a15..d7ccd46 100644
+--- a/arch/arm/mach-omap2/smartreflex.h
++++ b/arch/arm/mach-omap2/smartreflex.h
+@@ -238,7 +238,7 @@ extern u32 current_vdd2_opp;
+  * NOTE: if smartreflex is not enabled from sysfs, these functions will not
+  * do anything.
+  */
+-#if defined(CONFIG_ARCH_OMAP34XX) && defined(CONFIG_TWL4030_CORE)
++#ifdef CONFIG_OMAP_SMARTREFLEX
+ void enable_smartreflex(int srid);
+ void disable_smartreflex(int srid);
+ #else
+diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
+index b085b07..53745ce 100644
+--- a/arch/arm/plat-omap/Kconfig
++++ b/arch/arm/plat-omap/Kconfig
+@@ -56,6 +56,23 @@ config OMAP_DEBUG_CLOCKDOMAIN
+         for every clockdomain register write.  However, the
+         extra detail costs some memory.
++config OMAP_SMARTREFLEX
++      bool "SmartReflex support"
++      depends on ARCH_OMAP34XX && TWL4030_CORE
++      help
++        Say Y if you want to enable SmartReflex.
++
++        SmartReflex can perform continuous dynamic voltage
++        scaling around the nominal operating point voltage
++        according to silicon characteristics and operating
++        conditions. Enabling SmartReflex reduces power
++        consumption.
++
++        Please note, that by default SmartReflex is only
++        initialized. To enable the automatic voltage
++        compensation for VDD1 and VDD2, user must write 1 to
++        /sys/power/sr_vddX_autocomp, where X is 1 or 2.
++
+ config OMAP_RESET_CLOCKS
+       bool "Reset unused clocks during boot"
+       depends on ARCH_OMAP
+-- 
+1.5.4.3
index c4eec9b..fd310de 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.26-rc4-omap1
-# Sun Jun  1 11:35:14 2008
+# Mon Jun  2 14:01:16 2008
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -175,7 +175,8 @@ CONFIG_ARCH_OMAP3=y
 #
 # CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
 # CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
-# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_SMARTREFLEX=y
+CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_BOOT_TAG=y
 CONFIG_OMAP_BOOT_REASON=y
 # CONFIG_OMAP_COMPONENT_VERSION is not set
index 5fba8e3..109d1b7 100644 (file)
@@ -5,7 +5,7 @@ FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/linux-omap2-git/${MA
 SRCREV = "24d1d54db70a8ebf59382dc51d8ca40ca5c29b08"
 
 PV = "2.6.25+2.6.26-rc4+git${SRCREV}"
-PR = "r19"
+PR = "r20"
 
 
 SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \
@@ -16,6 +16,9 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
            file://mux.patch;patch=1 \
           file://0001-omap3beagle-add-a-platform-device-to-hook-up-the-GP.patch;patch=1 \
           file://flash.patch;patch=1 \
+          file://0001-ARM-OMAP-SmartReflex-driver.patch;patch=1 \
+          file://0002-ARM-OMAP-SmartReflex-driver.patch;patch=1 \
+          file://0003-ARM-OMAP-SmartReflex-driver.patch;patch=1 \
 "
 
 COMPATIBLE_MACHINE = "omap2430sdp|omap2420h4|beagleboard"