diff options
Diffstat (limited to 'packages/linux/linux-2.6.26/boc01/008-081127-spi.patch')
-rw-r--r-- | packages/linux/linux-2.6.26/boc01/008-081127-spi.patch | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/packages/linux/linux-2.6.26/boc01/008-081127-spi.patch b/packages/linux/linux-2.6.26/boc01/008-081127-spi.patch new file mode 100644 index 0000000000..41777a5753 --- /dev/null +++ b/packages/linux/linux-2.6.26/boc01/008-081127-spi.patch @@ -0,0 +1,327 @@ +--- linux-2.6.26.orig/drivers/spi/spi_mpc83xx.c 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26/drivers/spi/spi_mpc83xx.c 2008-11-26 11:32:07.000000000 +0100 +@@ -27,6 +27,8 @@ + #include <asm/irq.h> + #include <asm/io.h> + ++//#define DBG_SPI 1 ++ + /* SPI Controller registers */ + struct mpc83xx_spi_reg { + u8 res1[0x20]; +@@ -114,6 +116,7 @@ + + static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val) + { ++ + out_be32(reg, val); + } + +@@ -157,11 +160,17 @@ + + mpc83xx_spi = spi_master_get_devdata(spi->master); + ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (163)\n"); ++#endif DBG_SPI ++ + if (value == BITBANG_CS_INACTIVE) { + if (mpc83xx_spi->deactivate_cs) + mpc83xx_spi->deactivate_cs(spi->chip_select, pol); + } +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (171)\n"); ++#endif DBG_SPI + if (value == BITBANG_CS_ACTIVE) { + u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + +@@ -171,6 +180,9 @@ + mpc83xx_spi->get_tx = cs->get_tx; + + if (cs->hw_mode != regval) { ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (184)\n"); ++#endif DBG_SPI + unsigned long flags; + void *tmp_ptr = &mpc83xx_spi->base->mode; + +@@ -184,6 +196,9 @@ + mpc83xx_spi_write_reg(tmp_ptr, regval); + local_irq_restore(flags); + } ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_chipselect (196)\n"); ++#endif DBG_SPI + if (mpc83xx_spi->activate_cs) + mpc83xx_spi->activate_cs(spi->chip_select, pol); + } +@@ -266,26 +281,38 @@ + + cs->hw_mode |= SPMODE_LEN(bits_per_word); + +- if ((mpc83xx_spi->spibrg / hz) >= 64) { ++ /*if ((mpc83xx_spi->spibrg / hz) >= 64) { + pm = mpc83xx_spi->spibrg / (hz * 64) - 1; +- if (pm > 0x0f) { ++ if (pm > 0x0f) {*/ ++ if ((mpc83xx_spi->spibrg / hz) > 64) { ++ cs->hw_mode |= SPMODE_DIV16; ++ pm = mpc83xx_spi->spibrg / (hz * 64); ++ if (pm > 16) { + dev_err(&spi->dev, "Requested speed is too " + "low: %d Hz. Will use %d Hz instead.\n", + hz, mpc83xx_spi->spibrg / 1024); +- pm = 0x0f; ++ pm = 16; + } +- cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16; +- } else { ++ //cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16; ++ } else + pm = mpc83xx_spi->spibrg / (hz * 4); +- if (pm) +- pm--; +- cs->hw_mode |= SPMODE_PM(pm); +- } ++ if (pm) ++ pm--; ++ cs->hw_mode = 0x0F700000; ++ mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode); + regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup_transfer regval=%4X\n",regval); ++#endif ++ ++ ++ + if (cs->hw_mode != regval) { + unsigned long flags; + void *tmp_ptr = &mpc83xx_spi->base->mode; +- ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup_transfer cs->hw_mode=%4X\n",cs->hw_mode); ++#endif + regval = cs->hw_mode; + /* Turn off IRQs locally to minimize time + * that SPI is disabled +@@ -322,15 +349,24 @@ + /* enable rx ints */ + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE); + ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_bufs (338)\n"); ++#endif ++ + /* transmit word */ + word = mpc83xx_spi->get_tx(mpc83xx_spi); +- mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); + ++ mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word); ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_bufs (345)\n"); ++#endif + wait_for_completion(&mpc83xx_spi->done); + + /* disable rx ints */ + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0); +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_bufs (352)\n"); ++#endif + return mpc83xx_spi->count; + } + +@@ -360,15 +396,22 @@ + if (t->bits_per_word || t->speed_hz) { + /* Don't allow changes if CS is active */ + status = -EINVAL; +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_work (366)\n"); ++#endif + if (cs_change) + status = mpc83xx_spi_setup_transfer(spi, t); + if (status < 0) + break; + } +- ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_work (374)\n"); ++#endif + if (cs_change) + mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE); ++#ifdef DBG_SPI ++printk(KERN_INFO "mpc83xx_spi_work (379)\n"); ++#endif + cs_change = t->cs_change; + if (t->len) + status = mpc83xx_spi_bufs(spi, t); +@@ -439,26 +482,39 @@ + cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); + /* mask out bits we are going to set */ + cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH +- | SPMODE_REV | SPMODE_LOOP); +- +- if (spi->mode & SPI_CPHA) ++ | SPMODE_REV); ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup (475) cs->hw_mode=0x%4X\n",cs->hw_mode); ++#endif ++ /*if (spi->mode & SPI_CPHA) + cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; + if (spi->mode & SPI_CPOL) + cs->hw_mode |= SPMODE_CI_INACTIVEHIGH; + if (!(spi->mode & SPI_LSB_FIRST)) +- cs->hw_mode |= SPMODE_REV; +- if (spi->mode & SPI_LOOP) +- cs->hw_mode |= SPMODE_LOOP; ++ cs->hw_mode |= SPMODE_REV;*/ ++ //if (spi->mode & SPI_LOOP) ++ // cs->hw_mode |= SPMODE_LOOP; ++cs->hw_mode = 0x0F700000; ++mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode); ++cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); ++ + ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup (486) cs->hw_mode=0x%4X\n",cs->hw_mode); ++#endif + retval = mpc83xx_spi_setup_transfer(spi, NULL); + if (retval < 0) { ++#ifdef DBG_SPI ++printk("mpc83xx_spi_setup (491) "); ++#endif + cs->hw_mode = hw_mode; /* Restore settings */ + return retval; + } +- +- dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n", ++#ifdef DBG_SPI ++ printk(KERN_INFO "%s, mode %d, %u bits/w, %u Hz\n", + __func__, spi->mode & (SPI_CPOL | SPI_CPHA), + spi->bits_per_word, spi->max_speed_hz); ++#endif + #if 0 /* Don't think this is needed */ + /* NOTE we _need_ to call chipselect() early, ideally with adapter + * setup, unless the hardware defaults cooperate to avoid confusion +@@ -518,7 +574,9 @@ + { + struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master); + unsigned long flags; +- ++#ifdef DBG_SPI ++printk(KERN_INFO "Debut_transfert\n"); ++#endif + m->actual_length = 0; + m->status = -EINPROGRESS; + +@@ -600,10 +658,12 @@ + goto unmap_io; + } + ++printk(KERN_INFO "irq_spi : 0x%2X\n", mpc83xx_spi->irq); ++ + /* Register for SPI Interrupt */ + ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq, + 0, "mpc83xx_spi", mpc83xx_spi); +- ++printk(KERN_INFO "irq_spi : 0x%2X\n", mpc83xx_spi->irq); + if (ret != 0) + goto unmap_io; + +@@ -628,7 +688,7 @@ + INIT_LIST_HEAD(&mpc83xx_spi->queue); + + mpc83xx_spi->workqueue = create_singlethread_workqueue( +- master->dev.parent->bus_id); ++ dev->dev.bus_id); + if (mpc83xx_spi->workqueue == NULL) { + ret = -EBUSY; + goto free_irq; +--- linux-2.6.26/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-07-13 23:51:29.000000000 +0200 ++++ linux-2.6.26.mod/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-11-27 11:55:52.000000000 +0100 +@@ -15,16 +15,82 @@ + + #include <linux/pci.h> + #include <linux/of_platform.h> +- ++#include <linux/interrupt.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/mmc_spi.h> ++#include <linux/mmc/host.h> ++#include <linux/of_platform.h> ++#include <sysdev/fsl_soc.h> ++#include <asm/qe.h> ++#include <asm/qe_ic.h> ++#include <asm/time.h> ++#include <asm/ipic.h> ++#include <asm/udbg.h> + #include <asm/time.h> + #include <asm/ipic.h> + #include <asm/udbg.h> ++#include <sysdev/fsl_soc.h> ++ + + #include "mpc83xx.h" + + /* + * Setup the architecture + */ ++ ++struct gpio { ++ __be32 gpdir; ++ __be32 gpodr; ++ __be32 gpdat; ++ __be32 gpier; ++ __be32 gpimr; ++ __be32 gpicr; ++} __attribute__ ((packed)); ++static struct gpio *gpio_regs; ++ ++static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity) ++{ ++ if (polarity) ++ setbits32(&gpio_regs->gpdat, 1 << (31 - 14)); ++ else ++ clrbits32(&gpio_regs->gpdat, 1 << (31 - 14)); ++} ++ ++static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity) ++{ ++ if (polarity) ++ clrbits32(&gpio_regs->gpdat, 1 << (31 - 14) ); ++ else ++ setbits32(&gpio_regs->gpdat, 1 << (31 - 14) ); ++ ++} ++ ++static struct spi_board_info mpc8313_spi_boardinfo = { ++ .bus_num = 0x7000, ++ .chip_select = 0, ++ .max_speed_hz = 50000000, ++ .modalias = "spidev", ++}; ++ ++static int __init mpc8313_spi_init(void) ++{ ++ /* System I/O Configuration Register Low */ ++ gpio_regs = ioremap(get_immrbase() + 0xc00, 0x20); ++ if ( !gpio_regs) ++ return -ENOMEM; ++ ++ /* set GPIO14 as output */ ++ setbits32(&gpio_regs->gpdir, 1 << (31 - 14)); ++ clrbits32(&gpio_regs->gpodr, 1 << (31 - 14)); ++ setbits32(&gpio_regs->gpdat, 1 << (31 - 14)); ++ ++ return fsl_spi_init(&mpc8313_spi_boardinfo, 1, ++ mpc83xx_spi_activate_cs, ++ mpc83xx_spi_deactivate_cs); ++} ++ ++device_initcall(mpc8313_spi_init); ++ + static void __init mpc831x_rdb_setup_arch(void) + { + #ifdef CONFIG_PCI |