#include <linux/spi/spi.h>
-#include <asm/arch/dma.h>
-#include <asm/arch/clock.h>
+#include <mach/dma.h>
+#include <mach/clock.h>
#define OMAP2_MCSPI_MAX_FREQ 48000000
struct clk *fck;
/* Virtual base address of the controller */
void __iomem *base;
+ unsigned long phys;
/* SPI1 has 4 channels, while SPI2 has 2 */
struct omap2_mcspi_dma *dma_channels;
};
struct omap2_mcspi_cs {
void __iomem *base;
+ unsigned long phys;
int word_len;
};
c = count;
word_len = cs->word_len;
- base = (unsigned long) io_v2p(cs->base);
+ base = cs->phys;
tx_reg = base + OMAP2_MCSPI_TX0;
rx_reg = base + OMAP2_MCSPI_RX0;
rx = xfer->rx_buf;
tx = xfer->tx_buf;
do {
+ c -= 1;
if (tx != NULL) {
if (mcspi_wait_for_reg_bit(chstat_reg,
OMAP2_MCSPI_CHSTAT_TXS) < 0) {
word_len, *(rx - 1));
#endif
}
- c -= 1;
} while (c);
} else if (word_len <= 16) {
u16 *rx;
rx = xfer->rx_buf;
tx = xfer->tx_buf;
do {
+ c -= 2;
if (tx != NULL) {
if (mcspi_wait_for_reg_bit(chstat_reg,
OMAP2_MCSPI_CHSTAT_TXS) < 0) {
word_len, *(rx - 1));
#endif
}
- c -= 2;
} while (c);
} else if (word_len <= 32) {
u32 *rx;
rx = xfer->rx_buf;
tx = xfer->tx_buf;
do {
+ c -= 4;
if (tx != NULL) {
if (mcspi_wait_for_reg_bit(chstat_reg,
OMAP2_MCSPI_CHSTAT_TXS) < 0) {
word_len, *(rx - 1));
#endif
}
- c -= 4;
} while (c);
}
if (!cs)
return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14;
+ cs->phys = mcspi->phys + spi->chip_select * 0x14;
spi->controller_state = cs;
}
clk_enable(mcspi->ick);
clk_enable(mcspi->fck);
- ret = omap2_mcspi_setup_transfer(spi, NULL);
+ ret = omap2_mcspi_setup_transfer(spi, NULL);
clk_disable(mcspi->fck);
clk_disable(mcspi->ick);
struct spi_device *spi;
struct spi_transfer *t = NULL;
int cs_active = 0;
- struct omap2_mcspi_device_config *conf;
struct omap2_mcspi_cs *cs;
int par_override = 0;
int status = 0;
spin_unlock_irq(&mcspi->lock);
spi = m->spi;
- conf = spi->controller_data;
cs = spi->controller_state;
omap2_mcspi_set_enable(spi, 1);
if (tx_buf != NULL) {
t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf,
len, DMA_TO_DEVICE);
- if (dma_mapping_error(t->tx_dma)) {
+ if (dma_mapping_error(&spi->dev, t->tx_dma)) {
dev_dbg(&spi->dev, "dma %cX %d bytes error\n",
'T', len);
return -EINVAL;
if (rx_buf != NULL) {
t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len,
DMA_FROM_DEVICE);
- if (dma_mapping_error(t->rx_dma)) {
+ if (dma_mapping_error(&spi->dev, t->rx_dma)) {
dev_dbg(&spi->dev, "dma %cX %d bytes error\n",
'R', len);
if (tx_buf != NULL)
OMAP24XX_DMA_SPI2_TX1,
};
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
+static u8 __initdata spi3_rxdma_id[] = {
+ OMAP24XX_DMA_SPI3_RX0,
+ OMAP24XX_DMA_SPI3_RX1,
+};
+
+static u8 __initdata spi3_txdma_id[] = {
+ OMAP24XX_DMA_SPI3_TX0,
+ OMAP24XX_DMA_SPI3_TX1,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static u8 __initdata spi4_rxdma_id[] = {
+ OMAP34XX_DMA_SPI4_RX0,
+};
+
+static u8 __initdata spi4_txdma_id[] = {
+ OMAP34XX_DMA_SPI4_TX0,
+};
+#endif
+
static int __init omap2_mcspi_probe(struct platform_device *pdev)
{
struct spi_master *master;
txdma_id = spi2_txdma_id;
num_chipselect = 2;
break;
- /* REVISIT omap2430 has a third McSPI ... */
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
+ case 3:
+ rxdma_id = spi3_rxdma_id;
+ txdma_id = spi3_txdma_id;
+ num_chipselect = 2;
+ break;
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ case 4:
+ rxdma_id = spi4_rxdma_id;
+ txdma_id = spi4_txdma_id;
+ num_chipselect = 1;
+ break;
+#endif
default:
return -EINVAL;
}
goto err1;
}
if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto err1;
}
- mcspi->base = (void __iomem *) io_p2v(r->start);
+ mcspi->phys = r->start;
+ mcspi->base = ioremap(r->start, r->end - r->start + 1);
+ if (!mcspi->base) {
+ dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
+ status = -ENOMEM;
+ goto err1aa;
+ }
INIT_WORK(&mcspi->work, omap2_mcspi_work);
spin_lock_init(&mcspi->lock);
INIT_LIST_HEAD(&mcspi->msg_queue);
- mcspi->ick = clk_get(&pdev->dev, "mcspi_ick");
+ mcspi->ick = clk_get(&pdev->dev, "ick");
if (IS_ERR(mcspi->ick)) {
dev_dbg(&pdev->dev, "can't get mcspi_ick\n");
status = PTR_ERR(mcspi->ick);
goto err1a;
}
- mcspi->fck = clk_get(&pdev->dev, "mcspi_fck");
+ mcspi->fck = clk_get(&pdev->dev, "fck");
if (IS_ERR(mcspi->fck)) {
dev_dbg(&pdev->dev, "can't get mcspi_fck\n");
status = PTR_ERR(mcspi->fck);
err2:
clk_put(mcspi->ick);
err1a:
+ iounmap(mcspi->base);
+err1aa:
release_mem_region(r->start, (r->end - r->start) + 1);
err1:
spi_master_put(master);
struct omap2_mcspi *mcspi;
struct omap2_mcspi_dma *dma_channels;
struct resource *r;
+ void __iomem *base;
master = dev_get_drvdata(&pdev->dev);
mcspi = spi_master_get_devdata(master);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(r->start, (r->end - r->start) + 1);
+ base = mcspi->base;
spi_unregister_master(master);
+ iounmap(base);
kfree(dma_channels);
return 0;
}
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:omap2_mcspi");
+
static struct platform_driver omap2_mcspi_driver = {
.driver = {
.name = "omap2_mcspi",