Commit 9963113e authored by Nikita Shubin's avatar Nikita Shubin Committed by Arnd Bergmann

ata: pata_ep93xx: add device tree support

- add OF ID match table
- drop platform DMA and filters
- change DMA setup to OF, so we can defer probe
Signed-off-by: default avatarNikita Shubin <nikita.shubin@maquefel.me>
Tested-by: default avatarAlexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: default avatarSergey Shtylyov <s.shtylyov@omp.ru>
Acked-by: default avatarDamien Le Moal <dlemoal@kernel.org>
Acked-by: default avatarVinod Koul <vkoul@kernel.org>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent f4da2b60
...@@ -44,8 +44,8 @@ ...@@ -44,8 +44,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_data/dma-ep93xx.h>
#include <linux/soc/cirrus/ep93xx.h> #include <linux/soc/cirrus/ep93xx.h>
#define DRV_NAME "ep93xx-ide" #define DRV_NAME "ep93xx-ide"
...@@ -126,7 +126,7 @@ enum { ...@@ -126,7 +126,7 @@ enum {
}; };
struct ep93xx_pata_data { struct ep93xx_pata_data {
const struct platform_device *pdev; struct platform_device *pdev;
void __iomem *ide_base; void __iomem *ide_base;
struct ata_timing t; struct ata_timing t;
bool iordy; bool iordy;
...@@ -135,9 +135,7 @@ struct ep93xx_pata_data { ...@@ -135,9 +135,7 @@ struct ep93xx_pata_data {
unsigned long udma_out_phys; unsigned long udma_out_phys;
struct dma_chan *dma_rx_channel; struct dma_chan *dma_rx_channel;
struct ep93xx_dma_data dma_rx_data;
struct dma_chan *dma_tx_channel; struct dma_chan *dma_tx_channel;
struct ep93xx_dma_data dma_tx_data;
}; };
static void ep93xx_pata_clear_regs(void __iomem *base) static void ep93xx_pata_clear_regs(void __iomem *base)
...@@ -637,20 +635,13 @@ static void ep93xx_pata_release_dma(struct ep93xx_pata_data *drv_data) ...@@ -637,20 +635,13 @@ static void ep93xx_pata_release_dma(struct ep93xx_pata_data *drv_data)
} }
} }
static bool ep93xx_pata_dma_filter(struct dma_chan *chan, void *filter_param) static int ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
{ {
if (ep93xx_dma_chan_is_m2p(chan)) struct platform_device *pdev = drv_data->pdev;
return false; struct device *dev = &pdev->dev;
chan->private = filter_param;
return true;
}
static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
{
const struct platform_device *pdev = drv_data->pdev;
dma_cap_mask_t mask; dma_cap_mask_t mask;
struct dma_slave_config conf; struct dma_slave_config conf;
int ret;
dma_cap_zero(mask); dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SLAVE, mask);
...@@ -660,22 +651,16 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) ...@@ -660,22 +651,16 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
* to request only one channel, and reprogram it's direction at * to request only one channel, and reprogram it's direction at
* start of new transfer. * start of new transfer.
*/ */
drv_data->dma_rx_data.port = EP93XX_DMA_IDE; drv_data->dma_rx_channel = dma_request_chan(dev, "rx");
drv_data->dma_rx_data.direction = DMA_DEV_TO_MEM; if (IS_ERR(drv_data->dma_rx_channel))
drv_data->dma_rx_data.name = "ep93xx-pata-rx"; return dev_err_probe(dev, PTR_ERR(drv_data->dma_rx_channel),
drv_data->dma_rx_channel = dma_request_channel(mask, "rx DMA setup failed\n");
ep93xx_pata_dma_filter, &drv_data->dma_rx_data);
if (!drv_data->dma_rx_channel) drv_data->dma_tx_channel = dma_request_chan(&pdev->dev, "tx");
return; if (IS_ERR(drv_data->dma_tx_channel)) {
ret = dev_err_probe(dev, PTR_ERR(drv_data->dma_tx_channel),
drv_data->dma_tx_data.port = EP93XX_DMA_IDE; "tx DMA setup failed\n");
drv_data->dma_tx_data.direction = DMA_MEM_TO_DEV; goto fail_release_rx;
drv_data->dma_tx_data.name = "ep93xx-pata-tx";
drv_data->dma_tx_channel = dma_request_channel(mask,
ep93xx_pata_dma_filter, &drv_data->dma_tx_data);
if (!drv_data->dma_tx_channel) {
dma_release_channel(drv_data->dma_rx_channel);
return;
} }
/* Configure receive channel direction and source address */ /* Configure receive channel direction and source address */
...@@ -683,10 +668,10 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) ...@@ -683,10 +668,10 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
conf.direction = DMA_DEV_TO_MEM; conf.direction = DMA_DEV_TO_MEM;
conf.src_addr = drv_data->udma_in_phys; conf.src_addr = drv_data->udma_in_phys;
conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
if (dmaengine_slave_config(drv_data->dma_rx_channel, &conf)) { ret = dmaengine_slave_config(drv_data->dma_rx_channel, &conf);
dev_err(&pdev->dev, "failed to configure rx dma channel\n"); if (ret) {
ep93xx_pata_release_dma(drv_data); dev_err_probe(dev, ret, "failed to configure rx dma channel");
return; goto fail_release_dma;
} }
/* Configure transmit channel direction and destination address */ /* Configure transmit channel direction and destination address */
...@@ -694,10 +679,20 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data) ...@@ -694,10 +679,20 @@ static void ep93xx_pata_dma_init(struct ep93xx_pata_data *drv_data)
conf.direction = DMA_MEM_TO_DEV; conf.direction = DMA_MEM_TO_DEV;
conf.dst_addr = drv_data->udma_out_phys; conf.dst_addr = drv_data->udma_out_phys;
conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
if (dmaengine_slave_config(drv_data->dma_tx_channel, &conf)) { ret = dmaengine_slave_config(drv_data->dma_tx_channel, &conf);
dev_err(&pdev->dev, "failed to configure tx dma channel\n"); if (ret) {
ep93xx_pata_release_dma(drv_data); dev_err_probe(dev, ret, "failed to configure tx dma channel");
goto fail_release_dma;
} }
return 0;
fail_release_rx:
dma_release_channel(drv_data->dma_rx_channel);
fail_release_dma:
ep93xx_pata_release_dma(drv_data);
return ret;
} }
static void ep93xx_pata_dma_start(struct ata_queued_cmd *qc) static void ep93xx_pata_dma_start(struct ata_queued_cmd *qc)
...@@ -954,7 +949,9 @@ static int ep93xx_pata_probe(struct platform_device *pdev) ...@@ -954,7 +949,9 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
drv_data->ide_base = ide_base; drv_data->ide_base = ide_base;
drv_data->udma_in_phys = mem_res->start + IDEUDMADATAIN; drv_data->udma_in_phys = mem_res->start + IDEUDMADATAIN;
drv_data->udma_out_phys = mem_res->start + IDEUDMADATAOUT; drv_data->udma_out_phys = mem_res->start + IDEUDMADATAOUT;
ep93xx_pata_dma_init(drv_data); err = ep93xx_pata_dma_init(drv_data);
if (err)
return err;
/* allocate host */ /* allocate host */
host = ata_host_alloc(&pdev->dev, 1); host = ata_host_alloc(&pdev->dev, 1);
...@@ -1021,9 +1018,16 @@ static void ep93xx_pata_remove(struct platform_device *pdev) ...@@ -1021,9 +1018,16 @@ static void ep93xx_pata_remove(struct platform_device *pdev)
ep93xx_ide_release_gpio(pdev); ep93xx_ide_release_gpio(pdev);
} }
static const struct of_device_id ep93xx_pata_of_ids[] = {
{ .compatible = "cirrus,ep9312-pata" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ep93xx_pata_of_ids);
static struct platform_driver ep93xx_pata_platform_driver = { static struct platform_driver ep93xx_pata_platform_driver = {
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = ep93xx_pata_of_ids,
}, },
.probe = ep93xx_pata_probe, .probe = ep93xx_pata_probe,
.remove_new = ep93xx_pata_remove, .remove_new = ep93xx_pata_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment