[PATCH] 6/7 AU1100 MMC support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Support for AU1100 (PIO mode) added.

Signed-off-by: Rodolfo Giometti <giometti@xxxxxxxx>

-- 

GNU/Linux Solutions                  e-mail:    giometti@xxxxxxxxxxxx
Linux Device Driver                             giometti@xxxxxxxxx
Embedded Systems                     		giometti@xxxxxxxx
UNIX programming                     phone:     +39 349 2432127
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index a77be4f..79cb2cf 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -305,7 +305,9 @@ static struct platform_device au1200_ide
 	.num_resources = ARRAY_SIZE(au1200_ide0_resources),
 	.resource	= au1200_ide0_resources,
 };
+#endif /* #ifdef CONFIG_SOC_AU1200 */
 
+#if defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1200) 
 static u64 au1xxx_mmc_dmamask =  ~(u32)0;
 
 static struct resource au1xxx_mmc0_resources[] = {
@@ -317,16 +319,23 @@ static struct resource au1xxx_mmc0_resou
 	},
 	[1] = {
 		.name		= "mmc-irq",
+#if defined(CONFIG_SOC_AU1100)
+		.start          = AU1100_SD_INT,
+		.end            = AU1100_SD_INT,
+#else /* AU1200 */
 		.start          = AU1200_SD_INT,
 		.end            = AU1200_SD_INT,
+#endif
 		.flags          = IORESOURCE_IRQ,
 	},
+#if defined(CONFIG_SOC_AU1200)
 	[2] = {
 		.name		= "mmc-dma",
 		.start          = DSCR_CMD0_SDMS_TX0,
 		.end            = DSCR_CMD0_SDMS_RX0,
 		.flags          = IORESOURCE_DMA,
 	},
+#endif
 };
 
 static struct platform_device au1xxx_mmc0_device = {
@@ -349,16 +358,23 @@ static struct resource au1xxx_mmc1_resou
 	},
 	[1] = {
 		.name		= "mmc-irq",
+#if defined(CONFIG_SOC_AU1100)
+		.start          = AU1100_SD_INT,
+		.end            = AU1100_SD_INT,
+#else /* AU1200 */
 		.start          = AU1200_SD_INT,
 		.end            = AU1200_SD_INT,
+#endif
 		.flags          = IORESOURCE_IRQ,
 	},
+#if defined(CONFIG_SOC_AU1200)
 	[2] = {
 		.name		= "mmc-dma",
 		.start          = DSCR_CMD0_SDMS_TX1,
 		.end            = DSCR_CMD0_SDMS_RX1,
 		.flags          = IORESOURCE_DMA,
 	},
+#endif
 };
 
 static struct platform_device au1xxx_mmc1_device = {
@@ -371,7 +387,7 @@ static struct platform_device au1xxx_mmc
 	.num_resources  = ARRAY_SIZE(au1xxx_mmc1_resources),
 	.resource       = au1xxx_mmc1_resources,
 };
-#endif /* #ifdef CONFIG_SOC_AU1200 */
+#endif /* defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1200) */
 
 static struct platform_device au1x00_pcmcia_device = {
 	.name 		= "au1x00-pcmcia",
@@ -450,6 +466,8 @@ #ifdef CONFIG_SOC_AU1200
 	&au1xxx_usb_otg_device,
 	&au1200_lcd_device,
 	&au1200_ide0_device,
+#endif
+#if defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1200)
 	&au1xxx_mmc0_device,
 	&au1xxx_mmc1_device,
 #endif
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 45bcf09..d7c455c 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -84,7 +84,7 @@ config MMC_WBSD
 
 config MMC_AU1X
 	tristate "Alchemy AU1XX0 MMC Card Interface support"
-	depends on MMC && SOC_AU1200
+	depends on MMC && (SOC_AU1100 || SOC_AU1200)
 	help
 	  This selects the AMD Alchemy(R) Multimedia card interface.
 	  If you have a Alchemy platform with a MMC slot, say Y or M here.
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index f2d44cd..801024b 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -14,7 +14,10 @@
  *     All Rights Reserved.
  *     (drivers/mmc/pxa.c) Copyright (C) 2003 Russell King,
  *     All Rights Reserved.
- *
+
+ *  Support for AU1100 in PIO mode by:
+ *     Rodolfo Giometti <giometti@xxxxxxxx>
+ *     Eurotech S.p.A. <info@xxxxxxxxxxx>
 
  * 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
@@ -75,7 +78,11 @@ #ifndef CONFIG_MIPS_DB1200
 #endif
 };
 
+#if defined(CONFIG_SOC_AU1100)
+static int dma = 0;		/* no DMA support for AU1100 :'( */
+#else /* AU1200 */
 static int dma = 1;
+#endif
 
 #ifdef MODULE
 module_param(dma, bool, 0);
@@ -317,11 +324,15 @@ static void au1xmmc_data_complete(struct
 
 	if (data->error == MMC_ERR_NONE) {
 		if (host->flags & HOST_F_DMA) {
+#if defined(CONFIG_SOC_AU1100)
+			err("no DMA support for AU1100 CPUs!\n", host->id);
+#else /* AU1200 */
 			u32 chan = DMA_CHANNEL(host);
 
 			chan_tab_t *c = *((chan_tab_t **) chan);
 			au1x_dma_chan_t *cp = c->chan_ptr;
 			data->bytes_xfered = cp->ddma_bytecnt;
+#endif
 		}
 		else
 			data->bytes_xfered =
@@ -546,6 +557,9 @@ static void au1xmmc_cmd_complete(struct 
 	host->status = HOST_S_DATA;
 
 	if (host->flags & HOST_F_DMA) {
+#if defined(CONFIG_SOC_AU1100)
+		err("no DMA support for AU1100 CPUs!\n", host->id);
+#else /* AU1200 */
 		u32 channel = DMA_CHANNEL(host);
 
 		/* Start the DMA as soon as the buffer gets something in it */
@@ -558,6 +572,7 @@ static void au1xmmc_cmd_complete(struct 
 		}
 
 		au1xxx_dbdma_start(channel);
+#endif
 	}
 }
 
@@ -614,6 +629,9 @@ au1xmmc_prepare_data(struct au1xmmc_host
 	au_writel(data->blksz - 1, HOST_BLKSIZE(host));
 
 	if (host->flags & HOST_F_DMA) {
+#if defined(CONFIG_SOC_AU1100)
+		err("no DMA support for AU1100 CPUs!\n", host->id);
+#else /* AU1200 */
 		int i;
 		u32 channel = DMA_CHANNEL(host);
 
@@ -647,6 +665,7 @@ au1xmmc_prepare_data(struct au1xmmc_host
 
 			datalen -= len;
 		}
+#endif
 	}
 	else {
 		host->pio.index = 0;
@@ -662,9 +681,11 @@ au1xmmc_prepare_data(struct au1xmmc_host
 
 	return MMC_ERR_NONE;
 
+#if !defined(CONFIG_SOC_AU1100)
  dataerr:
 	dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);
 	return MMC_ERR_TIMEOUT;
+#endif
 }
 
 /* static void au1xmmc_request
@@ -749,6 +770,7 @@ static void au1xmmc_set_ios(struct mmc_h
 	}
 }
 
+#if !defined(CONFIG_SOC_AU1100)
 static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
@@ -763,6 +785,7 @@ static void au1xmmc_dma_callback(int irq
 
 	tasklet_schedule(&host->data_task);
 }
+#endif
 
 #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
 #define STATUS_DATA_IN  (SD_STATUS_NE)
@@ -845,6 +868,7 @@ static void au1xmmc_poll_event(unsigned 
 	mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
 }
 
+#if !defined(CONFIG_SOC_AU1100)
 static dbdev_tab_t au1xmmc_mem_dbdev =
 {
 	DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0
@@ -880,6 +904,7 @@ static void au1xmmc_init_dma(struct au1x
 	host->tx_chan = txchan;
 	host->rx_chan = rxchan;
 }
+#endif
 
 struct mmc_host_ops au1xmmc_ops = {
 	.request	= au1xmmc_request,
@@ -911,11 +936,13 @@ static int __devinit au1xmmc_probe(struc
 		return -ENODEV;
 	irq = res->start;
 
+#if !defined(CONFIG_SOC_AU1100)
 	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "mmc-dma");
 	if (!res)
 		return -ENODEV;
 	tx_devid = res->start;
 	rx_devid = res->end;
+#endif
 
 	mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
 	if (!mmc) {
@@ -961,8 +988,15 @@ static int __devinit au1xmmc_probe(struc
 
 	spin_lock_init(&host->lock);
 
-	if (dma != 0)
+	if (dma != 0) {
+#if defined(CONFIG_SOC_AU1100)
+		err("no DMA support for AU1100 CPUs!\n", host->id);
+		ret = -EINVAL;
+		goto no_dma;
+#else /* AU1200 */
 		au1xmmc_init_dma(host);
+#endif
+	}
 
 	au1xmmc_reset_controller(host);
 
@@ -985,20 +1019,25 @@ static int __devinit au1xmmc_probe(struc
 	return 0;
 
 exit :
-	iounmap(base_addr);
+	del_timer_sync(&host->timer);
+	mmc_remove_host(mmc);
+
+no_dma :
+	au1xmmc_set_power(host, 0);
 
 	tasklet_kill(&host->data_task);
 	tasklet_kill(&host->finish_task);
 
-	del_timer_sync(&host->timer);
-	au1xmmc_set_power(host, 0);
-
-	mmc_remove_host(mmc);
+	au_writel(0x0, HOST_ENABLE(host));
 
+#if !defined(CONFIG_SOC_AU1100)
 	au1xxx_dbdma_chan_free(host->tx_chan);
 	au1xxx_dbdma_chan_free(host->rx_chan);
+#endif
+
+	mmc_free_host(mmc);
+	iounmap(base_addr);
 
-	au_writel(0x0, HOST_ENABLE(host));
 	au_sync();
 
 	return ret;
@@ -1013,22 +1052,27 @@ static int __devexit au1xmmc_remove(stru
 	if (!host)
 		return 0;
 
+	del_timer_sync(&host->timer);
+
 	tasklet_kill(&host->data_task);
 	tasklet_kill(&host->finish_task);
 
-	del_timer_sync(&host->timer);
 	au1xmmc_set_power(host, 0);
 
+	au_writel(0x0, HOST_ENABLE(host));
 	mmc_remove_host(mmc);
 
+#if !defined(CONFIG_SOC_AU1100)
 	au1xxx_dbdma_chan_free(host->tx_chan);
 	au1xxx_dbdma_chan_free(host->rx_chan);
+#endif
 
 	au_writel(0x0, HOST_ENABLE(host));
 	au_sync();
 
 	free_irq(host->irq, host);
 
+	mmc_free_host(mmc);
 	iounmap(base_addr);
 
 	return 0;

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux