diff options
author | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2008-06-03 11:41:30 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2008-06-03 11:41:30 +0000 |
commit | 972f72f4e47196817b8a3fc62a9e9dd188490f81 (patch) | |
tree | 77d115be3d0a03cf9b86de1a70d30330e4d236dc /packages/linux/linux-omap2-git/beagleboard | |
parent | b4db5d7f3e1a0470f2111508e2b701acee95055e (diff) | |
parent | 915c1e3654c4be1667a9390c3671d1a3601e2a56 (diff) |
merge of '6c9b3832ef2260eb1b3a74e74b1d73166ab79d89'
and 'f275c97e2c93f0e846205b213e997b28ed0b148e'
Diffstat (limited to 'packages/linux/linux-omap2-git/beagleboard')
12 files changed, 4525 insertions, 1760 deletions
diff --git a/packages/linux/linux-omap2-git/beagleboard/00001-mcbsp-transform.patch b/packages/linux/linux-omap2-git/beagleboard/00001-mcbsp-transform.patch index 452370bf3e..e8b3e7a70e 100644 --- a/packages/linux/linux-omap2-git/beagleboard/00001-mcbsp-transform.patch +++ b/packages/linux/linux-omap2-git/beagleboard/00001-mcbsp-transform.patch @@ -1,1160 +1,1160 @@ -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
-
+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 + diff --git a/packages/linux/linux-omap2-git/beagleboard/00002-mcbsp-omap1.patch b/packages/linux/linux-omap2-git/beagleboard/00002-mcbsp-omap1.patch index 76246a9fae..cf7c0df4e0 100644 --- a/packages/linux/linux-omap2-git/beagleboard/00002-mcbsp-omap1.patch +++ b/packages/linux/linux-omap2-git/beagleboard/00002-mcbsp-omap1.patch @@ -1,204 +1,204 @@ -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
-
+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 + diff --git a/packages/linux/linux-omap2-git/beagleboard/00003-mcbsp-omap3-clock.patch b/packages/linux/linux-omap2-git/beagleboard/00003-mcbsp-omap3-clock.patch index 6d1e7d3f71..643a626f30 100644 --- a/packages/linux/linux-omap2-git/beagleboard/00003-mcbsp-omap3-clock.patch +++ b/packages/linux/linux-omap2-git/beagleboard/00003-mcbsp-omap3-clock.patch @@ -1,123 +1,123 @@ -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
-
+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 + diff --git a/packages/linux/linux-omap2-git/beagleboard/00004-omap2-mcbsp.patch b/packages/linux/linux-omap2-git/beagleboard/00004-omap2-mcbsp.patch index f31604d658..4e42a11a17 100644 --- a/packages/linux/linux-omap2-git/beagleboard/00004-omap2-mcbsp.patch +++ b/packages/linux/linux-omap2-git/beagleboard/00004-omap2-mcbsp.patch @@ -1,144 +1,144 @@ -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
-
+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 index 0000000000..550a4f58be --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch @@ -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/0001-omap3beagle-add-a-platform-device-to-hook-up-the-GP.patch b/packages/linux/linux-omap2-git/beagleboard/0001-omap3beagle-add-a-platform-device-to-hook-up-the-GP.patch new file mode 100644 index 0000000000..17329be29b --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/0001-omap3beagle-add-a-platform-device-to-hook-up-the-GP.patch @@ -0,0 +1,69 @@ +From 7a444ee080c5f1a62ac5042f1e7926622b3e1ce7 Mon Sep 17 00:00:00 2001 +From: Koen Kooi <koen@openembedded.org> +Date: Fri, 30 May 2008 13:43:36 +0200 +Subject: [PATCH] ARM: OMAP: omap3beagle: add a platform device to hook up the GPIO leds to the leds-gpio driver + +omap3beagle: add a platform device to hook up the GPIO leds to the leds-gpio driver + * on revision A5 and earlier board the two leds can't be controlled seperately, should be fixed in rev. B and C boards. + +Signed-off-by: Koen Kooi <koen@openembedded.org> +--- + arch/arm/mach-omap2/board-omap3beagle.c | 28 ++++++++++++++++++++++++++++ + 1 files changed, 28 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index c992cc7..83891fc 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -19,6 +19,7 @@ + #include <linux/err.h> + #include <linux/clk.h> + #include <linux/io.h> ++#include <linux/leds.h> + + #include <asm/hardware.h> + #include <asm/mach-types.h> +@@ -72,6 +73,32 @@ static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { + .ctrl_name = "internal", + }; + ++struct gpio_led gpio_leds[] = { ++ { ++ .name = "beagleboard::led0", ++ .default_trigger = "none", ++ .gpio = 149, ++ }, ++ { ++ .name = "beagleboard::led1", ++ .default_trigger = "none", ++ .gpio = 150, ++ }, ++}; ++ ++static struct gpio_led_platform_data gpio_led_info = { ++ .leds = gpio_leds, ++ .num_leds = ARRAY_SIZE(gpio_leds), ++}; ++ ++static struct platform_device leds_gpio = { ++ .name = "leds-gpio", ++ .id = -1, ++ .dev = { ++ .platform_data = &gpio_led_info, ++ }, ++}; ++ + static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { + { OMAP_TAG_UART, &omap3_beagle_uart_config }, + { OMAP_TAG_MMC, &omap3beagle_mmc_config }, +@@ -83,6 +110,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = { + #ifdef CONFIG_RTC_DRV_TWL4030 + &omap3_beagle_twl4030rtc_device, + #endif ++ &leds_gpio, + }; + + static void __init omap3_beagle_init(void) +-- +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 index 0000000000..a5e2e63db2 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/0002-ARM-OMAP-SmartReflex-driver.patch @@ -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 index 0000000000..3c01abda8b --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/0003-ARM-OMAP-SmartReflex-driver.patch @@ -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 diff --git a/packages/linux/linux-omap2-git/beagleboard/defconfig b/packages/linux/linux-omap2-git/beagleboard/defconfig index 3d3562d9f5..fd310de701 100644 --- a/packages/linux/linux-omap2-git/beagleboard/defconfig +++ b/packages/linux/linux-omap2-git/beagleboard/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc3-omap1 -# Tue May 20 19:38:20 2008 +# Linux kernel version: 2.6.26-rc4-omap1 +# Mon Jun 2 14:01:16 2008 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -31,6 +31,7 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y @@ -79,8 +80,9 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set # CONFIG_MARKERS is not set @@ -171,17 +173,15 @@ CONFIG_ARCH_OMAP3=y # # OMAP Feature Selections # -CONFIG_OMAP_DEBUG_SRAM_PATCH=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 # CONFIG_OMAP_GPIO_SWITCH is not set -CONFIG_OMAP_MUX=n -# CONFIG_OMAP_MUX_DEBUG is not set -CONFIG_OMAP_MUX_WARNINGS=n +# CONFIG_OMAP_MUX is not set CONFIG_OMAP_MCBSP=y # CONFIG_OMAP_MMU_FWK is not set # CONFIG_OMAP_MBOX_FWK is not set @@ -192,7 +192,6 @@ CONFIG_OMAP_DM_TIMER=y # CONFIG_OMAP_LL_DEBUG_UART1 is not set # CONFIG_OMAP_LL_DEBUG_UART2 is not set CONFIG_OMAP_LL_DEBUG_UART3=y -CONFIG_OMAP_SERIAL_WAKE=y CONFIG_ARCH_OMAP34XX=y CONFIG_ARCH_OMAP3430=y @@ -233,7 +232,7 @@ CONFIG_CPU_CP15_MMU=y # Processor Features # CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_THUMBEE=y # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_BPREDICT_DISABLE is not set @@ -254,7 +253,7 @@ CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_PREEMPT is not set +CONFIG_PREEMPT=y CONFIG_HZ=128 CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set @@ -273,7 +272,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y -# CONFIG_LEDS is not set +CONFIG_LEDS=y CONFIG_ALIGNMENT_TRAP=y # @@ -473,7 +472,7 @@ CONFIG_MAC80211_RC_DEFAULT_PID=y CONFIG_MAC80211_RC_DEFAULT="pid" CONFIG_MAC80211_RC_PID=y # CONFIG_MAC80211_MESH is not set -# CONFIG_MAC80211_LEDS is not set +CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set # CONFIG_MAC80211_DEBUG is not set CONFIG_IEEE80211=y @@ -514,7 +513,7 @@ CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y -CONFIG_FTL=y +# CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set @@ -566,6 +565,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_OMAP2=y CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set @@ -853,22 +853,23 @@ CONFIG_I2C_OMAP=y # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_SENSORS_EEPROM is not set +CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8574 is not set # CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_ISP1301_OMAP is not set # CONFIG_TPS65010 is not set -CONFIG_SENSORS_TLV320AIC23=y +# CONFIG_SENSORS_TLV320AIC23 is not set CONFIG_TWL4030_CORE=y CONFIG_TWL4030_GPIO=y -# CONFIG_TWL4030_MADC is not set +CONFIG_TWL4030_MADC=m CONFIG_TWL4030_USB=y CONFIG_TWL4030_USB_HS_ULPI=y CONFIG_TWL4030_PWRBUTTON=y -# CONFIG_TWL4030_POWEROFF is not set +CONFIG_TWL4030_POWEROFF=y # CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_TSL2563 is not set # CONFIG_LP5521 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -912,8 +913,65 @@ CONFIG_HAVE_GPIO_LIB=y # # CONFIG_GPIO_MCP23S08 is not set # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_APM_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_TSC210X is not set +CONFIG_SENSORS_OMAP34XX=y +# CONFIG_HWMON_DEBUG_CHIP is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_NOWAYOUT=y @@ -949,102 +1007,13 @@ CONFIG_SSB_POSSIBLE=y # # Multimedia core support # -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -# CONFIG_VIDEO_ALLOW_V4L1 is not set -# CONFIG_VIDEO_V4L1_COMPAT is not set +# CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -CONFIG_VIDEO_MEDIA=y +# CONFIG_VIDEO_MEDIA is not set # # Multimedia drivers # -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_TUNER=y -# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set -CONFIG_MEDIA_TUNER_SIMPLE=y -CONFIG_MEDIA_TUNER_TDA8290=y -CONFIG_MEDIA_TUNER_TDA9887=y -CONFIG_MEDIA_TUNER_TEA5761=y -CONFIG_MEDIA_TUNER_TEA5767=y -CONFIG_MEDIA_TUNER_MT20XX=y -CONFIG_MEDIA_TUNER_XC2028=y -CONFIG_MEDIA_TUNER_XC5000=y -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEO_TVEEPROM=m -CONFIG_VIDEO_TUNER=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set - -# -# Encoders/decoders and other helper chips -# - -# -# Audio decoders -# -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TDA9875 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -CONFIG_VIDEO_MSP3400=m -# CONFIG_VIDEO_CS5345 is not set -CONFIG_VIDEO_CS53L32A=m -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -CONFIG_VIDEO_WM8775=m -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_VP27SMPX is not set - -# -# Video decoders -# -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_TCM825X is not set -# CONFIG_VIDEO_OV9640 is not set -CONFIG_VIDEO_SAA711X=m -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_TVP5150 is not set - -# -# Video and audio decoders -# -CONFIG_VIDEO_CX25840=m - -# -# MPEG video encoders -# -CONFIG_VIDEO_CX2341X=m - -# -# Video encoders -# -# CONFIG_VIDEO_SAA7127 is not set - -# -# Video improvement chips -# -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_USB_ET61X251 is not set -CONFIG_USB_SN9C102=m -# CONFIG_USB_ZC0301 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_SOC_CAMERA is not set -# CONFIG_RADIO_ADAPTERS is not set # CONFIG_DAB is not set # @@ -1203,7 +1172,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_SUSPEND=y -# CONFIG_USB_OTG is not set +CONFIG_USB_OTG=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -1228,9 +1197,10 @@ CONFIG_USB_MUSB_SOC=y # OMAP 343x high speed USB support # # CONFIG_USB_MUSB_HOST is not set -CONFIG_USB_MUSB_PERIPHERAL=y -# CONFIG_USB_MUSB_OTG is not set +# CONFIG_USB_MUSB_PERIPHERAL is not set +CONFIG_USB_MUSB_OTG=y CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC_HCD=y # CONFIG_MUSB_PIO_ONLY is not set CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TI_CPPI_DMA is not set @@ -1241,6 +1211,7 @@ CONFIG_USB_MUSB_LOGLEVEL=0 # CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m +# CONFIG_USB_WDM is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -1380,6 +1351,7 @@ CONFIG_MMC_UNSAFE_RESUME=y CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_SDIO_UART=y +# CONFIG_MMC_TEST is not set # # MMC/SD Host Controller Drivers @@ -1395,14 +1367,14 @@ CONFIG_LEDS_CLASS=y # CONFIG_LEDS_OMAP_DEBUG is not set # CONFIG_LEDS_OMAP is not set # CONFIG_LEDS_OMAP_PWM is not set -CONFIG_LEDS_GPIO=m +CONFIG_LEDS_GPIO=y # # LED Triggers # CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y @@ -1476,8 +1448,12 @@ CONFIG_EXT3_FS=y CONFIG_JBD=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_DNOTIFY=y @@ -1491,13 +1467,16 @@ CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set +CONFIG_FUSE_FS=m # # CD-ROM/DVD Filesystems # -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems @@ -1530,7 +1509,23 @@ CONFIG_TMPFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_RUBIN=y +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set @@ -1641,7 +1636,9 @@ CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y # CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_DEBUG_PREEMPT=y # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set @@ -1652,7 +1649,7 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set @@ -1665,7 +1662,7 @@ CONFIG_FRAME_POINTER=y # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_USER is not set -CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set @@ -1772,8 +1769,10 @@ CONFIG_CRC_ITU_T=y CONFIG_CRC32=y CONFIG_CRC7=y CONFIG_LIBCRC32C=y -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y diff --git a/packages/linux/linux-omap2-git/beagleboard/flash.patch b/packages/linux/linux-omap2-git/beagleboard/flash.patch new file mode 100644 index 0000000000..4c76cd97bd --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/flash.patch @@ -0,0 +1,558 @@ +diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile +index 13d0043..d582b8f 100644 +--- a/arch/arm/mach-omap2/Makefile ++++ b/arch/arm/mach-omap2/Makefile +@@ -44,7 +44,8 @@ obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \ + board-omap3evm-flash.o + obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ + usb-musb.o usb-ehci.o \ +- hsmmc.o ++ hsmmc.o \ ++ board-omap3beagle-flash.o + obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \ + hsmmc.o \ + usb-musb.o +diff --git a/arch/arm/mach-omap2/board-omap3beagle-flash.c b/arch/arm/mach-omap2/board-omap3beagle-flash.c +new file mode 100644 +index 0000000..5346df0 +--- /dev/null ++++ b/arch/arm/mach-omap2/board-omap3beagle-flash.c +@@ -0,0 +1,119 @@ ++/* ++ * board-omap3beagle-flash.c ++ * ++ * Copyright (c) 2008 Texas Instruments ++ * ++ * Modified from board-omap3evm-flash.c ++ * ++ * 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/platform_device.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++#include <linux/mtd/nand.h> ++#include <linux/types.h> ++#include <linux/io.h> ++ ++#include <asm/mach/flash.h> ++#include <asm/arch/board.h> ++#include <asm/arch/gpmc.h> ++#include <asm/arch/nand.h> ++ ++#define GPMC_CS0_BASE 0x60 ++#define GPMC_CS_SIZE 0x30 ++ ++static struct mtd_partition omap3beagle_nand_partitions[] = { ++ /* All the partition sizes are listed in terms of NAND block size */ ++ { ++ .name = "X-Loader", ++ .offset = 0, ++ .size = 4*(64 * 2048), ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, ++ { ++ .name = "U-Boot", ++ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ ++ .size = 15*(64 * 2048), ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, ++ { ++ .name = "U-Boot Env", ++ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ ++ .size = 1*(64 * 2048), ++ }, ++ { ++ .name = "Kernel", ++ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ ++ .size = 32*(64 * 2048), ++ }, ++ { ++ .name = "File System", ++ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ ++ .size = MTDPART_SIZ_FULL, ++ }, ++}; ++ ++static struct omap_nand_platform_data omap3beagle_nand_data = { ++ .parts = omap3beagle_nand_partitions, ++ .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions), ++ .dma_channel = -1, /* disable DMA in OMAP NAND driver */ ++ .nand_setup = NULL, ++ .dev_ready = NULL, ++}; ++ ++static struct resource omap3beagle_nand_resource = { ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device omap3beagle_nand_device = { ++ .name = "omap2-nand", ++ .id = -1, ++ .dev = { ++ .platform_data = &omap3beagle_nand_data, ++ }, ++ .num_resources = 1, ++ .resource = &omap3beagle_nand_resource, ++}; ++ ++ ++void __init omap3beagle_flash_init(void) ++{ ++ u8 cs = 0; ++ u8 nandcs = GPMC_CS_NUM + 1; ++ ++ u32 gpmc_base_add = OMAP34XX_GPMC_VIRT; ++ ++ /* find out the chip-select on which NAND exists */ ++ while (cs < GPMC_CS_NUM) { ++ u32 ret = 0; ++ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); ++ ++ if ((ret & 0xC00) == 0x800) { ++ printk(KERN_INFO "Found NAND on CS%d\n", cs); ++ if (nandcs > GPMC_CS_NUM) ++ nandcs = cs; ++ } ++ cs++; ++ } ++ ++ if (nandcs > GPMC_CS_NUM) { ++ printk(KERN_INFO "NAND: Unable to find configuration " ++ "in GPMC\n "); ++ return; ++ } ++ ++ if (nandcs < GPMC_CS_NUM) { ++ omap3beagle_nand_data.cs = nandcs; ++ omap3beagle_nand_data.gpmc_cs_baseaddr = (void *)(gpmc_base_add + ++ GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE); ++ omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add); ++ ++ printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); ++ if (platform_device_register(&omap3beagle_nand_device) < 0) ++ printk(KERN_ERR "Unable to register NAND device\n"); ++ } ++} +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index c992cc7..99e042e 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -94,6 +94,7 @@ static void __init omap3_beagle_init(void) + hsmmc_init(); + usb_musb_init(); + usb_ehci_init(); ++ omap3beagle_flash_init(); + } + + arch_initcall(omap3_beagle_i2c_init); +diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig +index 3d5e432..02b9ced 100644 +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -71,7 +71,7 @@ config MTD_NAND_AMS_DELTA + + config MTD_NAND_OMAP2 + tristate "NAND Flash device on OMAP 2420H4/2430SDP boards" +- depends on (ARM && ARCH_OMAP2 && MTD_NAND) ++ depends on ARM && MTD_NAND && (ARCH_OMAP2 || ARCH_OMAP3) + help + Support for NAND flash on Texas Instruments 2430SDP/2420H4 platforms. + +diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c +index 3b7307c..3aac1d2 100644 +--- a/drivers/mtd/nand/omap2.c ++++ b/drivers/mtd/nand/omap2.c +@@ -111,15 +111,6 @@ + static const char *part_probes[] = { "cmdlinepart", NULL }; + #endif + +-static int hw_ecc = 1; +- +-/* new oob placement block for use with hardware ecc generation */ +-static struct nand_ecclayout omap_hw_eccoob = { +- .eccbytes = 12, +- .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, +- .oobfree = {{16, 32}, {33, 63} }, +-}; +- + struct omap_nand_info { + struct nand_hw_control controller; + struct omap_nand_platform_data *pdata; +@@ -133,6 +124,13 @@ struct omap_nand_info { + void __iomem *gpmc_cs_baseaddr; + void __iomem *gpmc_baseaddr; + }; ++ ++/* ++ * omap_nand_wp - This function enable or disable the Write Protect feature on ++ * NAND device ++ * @mtd: MTD device structure ++ * @mode: WP ON/OFF ++ */ + static void omap_nand_wp(struct mtd_info *mtd, int mode) + { + struct omap_nand_info *info = container_of(mtd, +@@ -189,11 +187,11 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) + } + + /* +-* omap_read_buf - read data from NAND controller into buffer +-* @mtd: MTD device structure +-* @buf: buffer to store date +-* @len: number of bytes to read +-*/ ++ * omap_read_buf - read data from NAND controller into buffer ++ * @mtd: MTD device structure ++ * @buf: buffer to store date ++ * @len: number of bytes to read ++ */ + static void omap_read_buf(struct mtd_info *mtd, u_char *buf, int len) + { + struct omap_nand_info *info = container_of(mtd, +@@ -207,11 +205,11 @@ static void omap_read_buf(struct mtd_info *mtd, u_char *buf, int len) + } + + /* +-* omap_write_buf - write buffer to NAND controller +-* @mtd: MTD device structure +-* @buf: data buffer +-* @len: number of bytes to write +-*/ ++ * omap_write_buf - write buffer to NAND controller ++ * @mtd: MTD device structure ++ * @buf: data buffer ++ * @len: number of bytes to write ++ */ + static void omap_write_buf(struct mtd_info *mtd, const u_char * buf, int len) + { + struct omap_nand_info *info = container_of(mtd, +@@ -250,10 +248,16 @@ static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len) + return 0; + } + ++#ifdef CONFIG_MTD_NAND_OMAP_HWECC ++/* ++ * omap_hwecc_init-Initialize the Hardware ECC for NAND flash in GPMC controller ++ * @mtd: MTD device structure ++ */ + static void omap_hwecc_init(struct mtd_info *mtd) + { + struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, + mtd); ++ register struct nand_chip *chip = mtd->priv; + unsigned long val = 0x0; + + /* Read from ECC Control Register */ +@@ -264,16 +268,15 @@ static void omap_hwecc_init(struct mtd_info *mtd) + + /* Read from ECC Size Config Register */ + val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG); +- /* ECCSIZE1=512 | ECCSIZE0=8bytes | Select eccResultsize[0123] */ +- val = ((0x000000FF<<22) | (0x00000003<<12) | (0x0000000F)); ++ /* ECCSIZE1=512 | Select eccResultsize[0-3] */ ++ val = ((((chip->ecc.size >> 1) - 1) << 22) | (0x0000000F)); + __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG); +- +- + } + + /* +- * This function will generate true ECC value, which can be used ++ * gen_true_ecc - This function will generate true ECC value, which can be used + * when correcting data read from NAND flash memory core ++ * @ecc_buf: buffer to store ecc code + */ + static void gen_true_ecc(u8 *ecc_buf) + { +@@ -289,8 +292,12 @@ static void gen_true_ecc(u8 *ecc_buf) + } + + /* +- * This function compares two ECC's and indicates if there is an error. +- * If the error can be corrected it will be corrected to the buffer ++ * omap_compare_ecc - This function compares two ECC's and indicates if there ++ * is an error. If the error can be corrected it will be corrected to the ++ * buffer ++ * @ecc_data1: ecc code from nand spare area ++ * @ecc_data2: ecc code from hardware register obtained from hardware ecc ++ * @page_data: page data + */ + static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ + u8 *ecc_data2, /* read from register */ +@@ -409,6 +416,14 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ + } + } + ++/* ++ * omap_correct_data - Compares the ecc read from nand spare area with ECC ++ * registers values and corrects one bit error if it has occured ++ * @mtd: MTD device structure ++ * @dat: page data ++ * @read_ecc: ecc read from nand flash ++ * @calc_ecc: ecc read from ECC registers ++ */ + static int omap_correct_data(struct mtd_info *mtd, u_char * dat, + u_char * read_ecc, u_char * calc_ecc) + { +@@ -436,65 +451,64 @@ static int omap_correct_data(struct mtd_info *mtd, u_char * dat, + } + + /* +-** Generate non-inverted ECC bytes. +-** +-** Using noninverted ECC can be considered ugly since writing a blank +-** page ie. padding will clear the ECC bytes. This is no problem as long +-** nobody is trying to write data on the seemingly unused page. +-** +-** Reading an erased page will produce an ECC mismatch between +-** generated and read ECC bytes that has to be dealt with separately. +-*/ ++ * omap_calcuate_ecc - Generate non-inverted ECC bytes. ++ * Using noninverted ECC can be considered ugly since writing a blank ++ * page ie. padding will clear the ECC bytes. This is no problem as long ++ * nobody is trying to write data on the seemingly unused page. Reading ++ * an erased page will produce an ECC mismatch between generated and read ++ * ECC bytes that has to be dealt with separately. ++ * @mtd: MTD device structure ++ * @dat: The pointer to data on which ecc is computed ++ * @ecc_code: The ecc_code buffer ++ */ + static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, + u_char *ecc_code) + { + struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, + mtd); + unsigned long val = 0x0; +- unsigned long reg, n; +- +- /* Ex NAND_ECC_HW12_2048 */ +- if ((info->nand.ecc.mode == NAND_ECC_HW) && +- (info->nand.ecc.size == 2048)) +- n = 4; +- else +- n = 1; ++ unsigned long reg; + + /* Start Reading from HW ECC1_Result = 0x200 */ + reg = (unsigned long)(info->gpmc_baseaddr + GPMC_ECC1_RESULT); +- while (n--) { +- val = __raw_readl(reg); +- *ecc_code++ = val; /* P128e, ..., P1e */ +- *ecc_code++ = val >> 16; /* P128o, ..., P1o */ +- /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ +- *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); +- reg += 4; +- } ++ val = __raw_readl(reg); ++ *ecc_code++ = val; /* P128e, ..., P1e */ ++ *ecc_code++ = val >> 16; /* P128o, ..., P1o */ ++ /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ ++ *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); ++ reg += 4; + + return 0; +-} /* omap_calculate_ecc */ ++} + ++/* ++ * omap_enable_hwecc - This function enables the hardware ecc functionality ++ * @mtd: MTD device structure ++ * @mode: Read/Write mode ++ */ + static void omap_enable_hwecc(struct mtd_info *mtd, int mode) + { + struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, + mtd); ++ register struct nand_chip *chip = mtd->priv; ++ unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; + unsigned long val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONFIG); + + switch (mode) { + case NAND_ECC_READ : + __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL); +- /* ECC 16 bit col) | ( CS 0 ) | ECC Enable */ +- val = (1 << 7) | (0x0) | (0x1) ; ++ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ ++ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); + break; + case NAND_ECC_READSYN : +- __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL); +- /* ECC 16 bit col) | ( CS 0 ) | ECC Enable */ +- val = (1 << 7) | (0x0) | (0x1) ; ++ __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL); ++ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ ++ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); + break; + case NAND_ECC_WRITE : + __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL); +- /* ECC 16 bit col) | ( CS 0 ) | ECC Enable */ +- val = (1 << 7) | (0x0) | (0x1) ; ++ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ ++ val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); + break; + default: + DEBUG(MTD_DEBUG_LEVEL0, "Error: Unrecognized Mode[%d]!\n", +@@ -504,7 +518,38 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) + + __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONFIG); + } ++#endif + ++/* ++ * omap_wait - Wait function is called during Program and erase ++ * operations and the way it is called from MTD layer, we should wait ++ * till the NAND chip is ready after the programming/erase operation ++ * has completed. ++ * @mtd: MTD device structure ++ * @chip: NAND Chip structure ++ */ ++static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) ++{ ++ register struct nand_chip *this = mtd->priv; ++ struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, ++ mtd); ++ int status = 0; ++ ++ this->IO_ADDR_W = (void *) info->gpmc_cs_baseaddr + ++ GPMC_CS_NAND_COMMAND; ++ this->IO_ADDR_R = (void *) info->gpmc_cs_baseaddr + GPMC_CS_NAND_DATA; ++ ++ while (!(status & 0x40)) { ++ __raw_writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W); ++ status = __raw_readb(this->IO_ADDR_R); ++ } ++ return status; ++} ++ ++/* ++ * omap_dev_ready - calls the platform specific dev_ready function ++ * @mtd: MTD device structure ++ */ + static int omap_dev_ready(struct mtd_info *mtd) + { + struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, +@@ -534,7 +579,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) + struct omap_nand_info *info; + struct omap_nand_platform_data *pdata; + int err; +- unsigned long val; ++ unsigned long val; + + + pdata = pdev->dev.platform_data; +@@ -568,15 +613,20 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) + } + + /* Enable RD PIN Monitoring Reg */ +- val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1); +- val |= WR_RD_PIN_MONITORING; +- gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val); ++ if (pdata->dev_ready) { ++ val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1); ++ val |= WR_RD_PIN_MONITORING; ++ gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val); ++ } + + val = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7); + val &= ~(0xf << 8); + val |= (0xc & 0xf) << 8; + gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val); + ++ /* NAND write protect off */ ++ omap_nand_wp(&info->mtd, NAND_WP_OFF); ++ + if (!request_mem_region(info->phys_base, NAND_IO_SIZE, + pdev->dev.driver->name)) { + err = -EBUSY; +@@ -597,29 +647,39 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) + info->nand.write_buf = omap_write_buf; + info->nand.verify_buf = omap_verify_buf; + +- info->nand.dev_ready = omap_dev_ready; +- info->nand.chip_delay = 0; +- +- /* Options */ +- info->nand.options = NAND_BUSWIDTH_16; +- info->nand.options |= NAND_SKIP_BBTSCAN; +- +- if (hw_ecc) { +- /* init HW ECC */ +- omap_hwecc_init(&info->mtd); +- +- info->nand.ecc.calculate = omap_calculate_ecc; +- info->nand.ecc.hwctl = omap_enable_hwecc; +- info->nand.ecc.correct = omap_correct_data; +- info->nand.ecc.mode = NAND_ECC_HW; +- info->nand.ecc.bytes = 12; +- info->nand.ecc.size = 2048; +- info->nand.ecc.layout = &omap_hw_eccoob; +- ++ /* ++ * If RDY/BSY line is connected to OMAP then use the omap ready funcrtion ++ * and the generic nand_wait function which reads the status register ++ * after monitoring the RDY/BSY line.Otherwise use a standard chip delay ++ * which is slightly more than tR (AC Timing) of the NAND device and read ++ * status register until you get a failure or success ++ */ ++ if (pdata->dev_ready) { ++ info->nand.dev_ready = omap_dev_ready; ++ info->nand.chip_delay = 0; + } else { +- info->nand.ecc.mode = NAND_ECC_SOFT; ++ info->nand.waitfunc = omap_wait; ++ info->nand.chip_delay = 50; + } + ++ info->nand.options |= NAND_SKIP_BBTSCAN; ++ if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000) ++ == 0x1000) ++ info->nand.options |= NAND_BUSWIDTH_16; ++ ++#ifdef CONFIG_MTD_NAND_OMAP_HWECC ++ info->nand.ecc.bytes = 3; ++ info->nand.ecc.size = 512; ++ info->nand.ecc.calculate = omap_calculate_ecc; ++ info->nand.ecc.hwctl = omap_enable_hwecc; ++ info->nand.ecc.correct = omap_correct_data; ++ info->nand.ecc.mode = NAND_ECC_HW; ++ ++ /* init HW ECC */ ++ omap_hwecc_init(&info->mtd); ++#else ++ info->nand.ecc.mode = NAND_ECC_SOFT; ++#endif + + /* DIP switches on some boards change between 8 and 16 bit + * bus widths for flash. Try the other width if the first try fails. +@@ -636,14 +696,12 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) + err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); + if (err > 0) + add_mtd_partitions(&info->mtd, info->parts, err); +- else if (err < 0 && pdata->parts) ++ else if (err <= 0 && pdata->parts) + add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); + else + #endif + add_mtd_device(&info->mtd); + +- omap_nand_wp(&info->mtd, NAND_WP_OFF); +- + platform_set_drvdata(pdev, &info->mtd); + + return 0; +diff --git a/include/asm-arm/arch-omap/board-omap3beagle.h b/include/asm-arm/arch-omap/board-omap3beagle.h +index 46dff31..26ecfb8 100644 +--- a/include/asm-arm/arch-omap/board-omap3beagle.h ++++ b/include/asm-arm/arch-omap/board-omap3beagle.h +@@ -29,5 +29,7 @@ + #ifndef __ASM_ARCH_OMAP3_BEAGLE_H + #define __ASM_ARCH_OMAP3_BEAGLE_H + ++extern void omap3beagle_flash_init(void); ++ + #endif /* __ASM_ARCH_OMAP3_BEAGLE_H */ + diff --git a/packages/linux/linux-omap2-git/beagleboard/mcbsp-fix-include.patch b/packages/linux/linux-omap2-git/beagleboard/mcbsp-fix-include.patch new file mode 100644 index 0000000000..13e931b61a --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/mcbsp-fix-include.patch @@ -0,0 +1,10 @@ +--- /tmp/mcbsp.c 2008-05-29 00:41:05.793645383 +0200 ++++ git/arch/arm/mach-omap2/mcbsp.c 2008-05-29 00:41:31.584031392 +0200 +@@ -14,6 +14,7 @@ + #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> diff --git a/packages/linux/linux-omap2-git/beagleboard/mux.patch b/packages/linux/linux-omap2-git/beagleboard/mux.patch new file mode 100644 index 0000000000..836b52954d --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/mux.patch @@ -0,0 +1,15 @@ +diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c +index 7d56516..be6eb3e 100644 +--- a/arch/arm/mach-omap2/mux.c ++++ b/arch/arm/mach-omap2/mux.c +@@ -253,8 +253,8 @@ MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2, + OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN) + + /* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/ +-MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0, +- OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) ++/*KK MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0, ++ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)*/ + MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2, + OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) + MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4, |