--- linux-2.6.27.orig/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-10-10 00:13:53.000000000 +0200 +++ linux-2.6.27/arch/powerpc/platforms/83xx/mpc831x_rdb.c 2008-12-12 09:45:19.000000000 +0100 @@ -15,17 +15,87 @@ #include #include +#include #include #include #include #include +#include +#include #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) +{ + //printk(KERN_INFO "%s %d %d\n", __func__, cs, 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) +{ +//printk(KERN_INFO "%s %d %d\n", __func__, cs, polarity); + if (polarity) + clrbits32(&gpio_regs->gpdat, 1 << (31 - 14)); + else + setbits32(&gpio_regs->gpdat, 1 << (31 - 14)); + +} + +//static struct mmc_spi_platform_data mpc8313_mmc_pdata = { +// .ocr_mask = MMC_VDD_33_34, +//}; + +static struct spi_board_info mpc8313_spi_boardinfo = { + .bus_num = 0x7000, + .chip_select = 0, + .max_speed_hz = 50000000, + .modalias = "spidev", +// .platform_data = &mpc8313_mmc_pdata, +}; + +static int __init mpc8313_spi_init(void) +{ + __be32 __iomem *psicrl; + + /* System I/O Configuration Register Low */ + psicrl = ioremap(get_immrbase() + MPC83XX_SICRL_OFFS, 0x4); + gpio_regs = ioremap(get_immrbase() + 0xc00, 0x20); + if (!psicrl || !gpio_regs) + return -ENOMEM; + + clrbits32(psicrl, 0x03F00000); + setbits32(psicrl, 0x30000000); + iounmap(psicrl); + + /* set GPIO13 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 @@ -40,6 +110,8 @@ mpc83xx_add_bridge(np); #endif mpc831x_usb_cfg(); + + mpc8313_spi_init(); } void __init mpc831x_rdb_init_IRQ(void) --- linux-2.6.27.orig/drivers/spi/spi_mpc83xx.c 2008-10-10 00:13:53.000000000 +0200 +++ linux-2.6.27.modif/drivers/spi/spi_mpc83xx.c 2008-12-08 14:45:12.000000000 +0100 @@ -280,7 +280,9 @@ if (pm) pm--; - cs->hw_mode |= SPMODE_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); if (cs->hw_mode != regval) { unsigned long flags; @@ -448,7 +450,7 @@ 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); + | SPMODE_REV ); if (spi->mode & SPI_CPHA) cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK; @@ -456,8 +458,10 @@ 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 = 0x0F700000; + mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode,cs->hw_mode); + cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); retval = mpc83xx_spi_setup_transfer(spi, NULL); if (retval < 0) { @@ -637,7 +641,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;