ata: arasan: remove the need for platform_data

This adds a complete DT binding for the arasan device driver. There is
currently only one user, which is the spear13xx platform, so we don't
actually have to parse all the properties until another user comes in,
but this does use the generic DMA binding to find the DMA channel.

The patch is untested so far and is part of a series to convert
the spear platform over to use the generic DMA binding, so it
should stay with the rest of the series.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Viresh Kumar <viresh.linux@linaro.org>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: devicetree-discuss@lists.ozlabs.org
This commit is contained in:
Arnd Bergmann 2013-01-28 17:42:24 +00:00
Родитель 6e8887f60f
Коммит e34d3865ee
3 изменённых файлов: 41 добавлений и 20 удалений

Просмотреть файл

@ -6,6 +6,26 @@ Required properties:
- interrupt-parent: Should be the phandle for the interrupt controller - interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device that services interrupts for this device
- interrupt: Should contain the CF interrupt number - interrupt: Should contain the CF interrupt number
- clock-frequency: Interface clock rate, in Hz, one of
25000000
33000000
40000000
50000000
66000000
75000000
100000000
125000000
150000000
166000000
200000000
Optional properties:
- arasan,broken-udma: if present, UDMA mode is unusable
- arasan,broken-mwdma: if present, MWDMA mode is unusable
- arasan,broken-pio: if present, PIO mode is unusable
- dmas: one DMA channel, as described in bindings/dma/dma.txt
required unless both UDMA and MWDMA mode are broken
- dma-names: the corresponding channel name, must be "data"
Example: Example:
@ -14,4 +34,6 @@ Example:
reg = <0xfc000000 0x1000>; reg = <0xfc000000 0x1000>;
interrupt-parent = <&vic1>; interrupt-parent = <&vic1>;
interrupts = <12>; interrupts = <12>;
dmas = <&dma-controller 23>;
dma-names = "data";
}; };

Просмотреть файл

@ -209,8 +209,6 @@ struct arasan_cf_dev {
struct dma_chan *dma_chan; struct dma_chan *dma_chan;
/* Mask for DMA transfers */ /* Mask for DMA transfers */
dma_cap_mask_t mask; dma_cap_mask_t mask;
/* dma channel private data */
void *dma_priv;
/* DMA transfer work */ /* DMA transfer work */
struct work_struct work; struct work_struct work;
/* DMA delayed finish work */ /* DMA delayed finish work */
@ -308,6 +306,7 @@ static void cf_card_detect(struct arasan_cf_dev *acdev, bool hotplugged)
static int cf_init(struct arasan_cf_dev *acdev) static int cf_init(struct arasan_cf_dev *acdev)
{ {
struct arasan_cf_pdata *pdata = dev_get_platdata(acdev->host->dev); struct arasan_cf_pdata *pdata = dev_get_platdata(acdev->host->dev);
unsigned int if_clk;
unsigned long flags; unsigned long flags;
int ret = 0; int ret = 0;
@ -325,8 +324,12 @@ static int cf_init(struct arasan_cf_dev *acdev)
spin_lock_irqsave(&acdev->host->lock, flags); spin_lock_irqsave(&acdev->host->lock, flags);
/* configure CF interface clock */ /* configure CF interface clock */
writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : /* TODO: read from device tree */
CF_IF_CLK_166M, acdev->vbase + CLK_CFG); if_clk = CF_IF_CLK_166M;
if (pdata && pdata->cf_if_clk <= CF_IF_CLK_200M)
if_clk = pdata->cf_if_clk;
writel(if_clk, acdev->vbase + CLK_CFG);
writel(TRUE_IDE_MODE | CFHOST_ENB, acdev->vbase + OP_MODE); writel(TRUE_IDE_MODE | CFHOST_ENB, acdev->vbase + OP_MODE);
cf_interrupt_enable(acdev, CARD_DETECT_IRQ, 1); cf_interrupt_enable(acdev, CARD_DETECT_IRQ, 1);
@ -357,12 +360,6 @@ static void dma_callback(void *dev)
complete(&acdev->dma_completion); complete(&acdev->dma_completion);
} }
static bool filter(struct dma_chan *chan, void *slave)
{
chan->private = slave;
return true;
}
static inline void dma_complete(struct arasan_cf_dev *acdev) static inline void dma_complete(struct arasan_cf_dev *acdev)
{ {
struct ata_queued_cmd *qc = acdev->qc; struct ata_queued_cmd *qc = acdev->qc;
@ -530,8 +527,7 @@ static void data_xfer(struct work_struct *work)
/* request dma channels */ /* request dma channels */
/* dma_request_channel may sleep, so calling from process context */ /* dma_request_channel may sleep, so calling from process context */
acdev->dma_chan = dma_request_channel(acdev->mask, filter, acdev->dma_chan = dma_request_slave_channel(acdev->host->dev, "data");
acdev->dma_priv);
if (!acdev->dma_chan) { if (!acdev->dma_chan) {
dev_err(acdev->host->dev, "Unable to get dma_chan\n"); dev_err(acdev->host->dev, "Unable to get dma_chan\n");
goto chan_request_fail; goto chan_request_fail;
@ -798,6 +794,7 @@ static int arasan_cf_probe(struct platform_device *pdev)
struct ata_host *host; struct ata_host *host;
struct ata_port *ap; struct ata_port *ap;
struct resource *res; struct resource *res;
u32 quirk;
irq_handler_t irq_handler = NULL; irq_handler_t irq_handler = NULL;
int ret = 0; int ret = 0;
@ -817,12 +814,17 @@ static int arasan_cf_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
if (pdata)
quirk = pdata->quirk;
else
quirk = CF_BROKEN_UDMA; /* as it is on spear1340 */
/* if irq is 0, support only PIO */ /* if irq is 0, support only PIO */
acdev->irq = platform_get_irq(pdev, 0); acdev->irq = platform_get_irq(pdev, 0);
if (acdev->irq) if (acdev->irq)
irq_handler = arasan_cf_interrupt; irq_handler = arasan_cf_interrupt;
else else
pdata->quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA; quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA;
acdev->pbase = res->start; acdev->pbase = res->start;
acdev->vbase = devm_ioremap_nocache(&pdev->dev, res->start, acdev->vbase = devm_ioremap_nocache(&pdev->dev, res->start,
@ -859,17 +861,16 @@ static int arasan_cf_probe(struct platform_device *pdev)
INIT_WORK(&acdev->work, data_xfer); INIT_WORK(&acdev->work, data_xfer);
INIT_DELAYED_WORK(&acdev->dwork, delayed_finish); INIT_DELAYED_WORK(&acdev->dwork, delayed_finish);
dma_cap_set(DMA_MEMCPY, acdev->mask); dma_cap_set(DMA_MEMCPY, acdev->mask);
acdev->dma_priv = pdata->dma_priv;
/* Handle platform specific quirks */ /* Handle platform specific quirks */
if (pdata->quirk) { if (quirk) {
if (pdata->quirk & CF_BROKEN_PIO) { if (quirk & CF_BROKEN_PIO) {
ap->ops->set_piomode = NULL; ap->ops->set_piomode = NULL;
ap->pio_mask = 0; ap->pio_mask = 0;
} }
if (pdata->quirk & CF_BROKEN_MWDMA) if (quirk & CF_BROKEN_MWDMA)
ap->mwdma_mask = 0; ap->mwdma_mask = 0;
if (pdata->quirk & CF_BROKEN_UDMA) if (quirk & CF_BROKEN_UDMA)
ap->udma_mask = 0; ap->udma_mask = 0;
} }
ap->flags |= ATA_FLAG_PIO_POLLING | ATA_FLAG_NO_ATAPI; ap->flags |= ATA_FLAG_PIO_POLLING | ATA_FLAG_NO_ATAPI;

Просмотреть файл

@ -37,8 +37,6 @@ struct arasan_cf_pdata {
#define CF_BROKEN_PIO (1) #define CF_BROKEN_PIO (1)
#define CF_BROKEN_MWDMA (1 << 1) #define CF_BROKEN_MWDMA (1 << 1)
#define CF_BROKEN_UDMA (1 << 2) #define CF_BROKEN_UDMA (1 << 2)
/* This is platform specific data for the DMA controller */
void *dma_priv;
}; };
static inline void static inline void