cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pata_ftide010.c (16484B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Faraday Technology FTIDE010 driver
      4 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
      5 *
      6 * Includes portions of the SL2312/SL3516/Gemini PATA driver
      7 * Copyright (C) 2003 StorLine, Inc <jason@storlink.com.tw>
      8 * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
      9 * Copyright (C) 2010 Frederic Pecourt <opengemini@free.fr>
     10 * Copyright (C) 2011 Tobias Waldvogel <tobias.waldvogel@gmail.com>
     11 */
     12
     13#include <linux/platform_device.h>
     14#include <linux/module.h>
     15#include <linux/libata.h>
     16#include <linux/bitops.h>
     17#include <linux/of_address.h>
     18#include <linux/of_device.h>
     19#include <linux/clk.h>
     20#include "sata_gemini.h"
     21
     22#define DRV_NAME "pata_ftide010"
     23
     24/**
     25 * struct ftide010 - state container for the Faraday FTIDE010
     26 * @dev: pointer back to the device representing this controller
     27 * @base: remapped I/O space address
     28 * @pclk: peripheral clock for the IDE block
     29 * @host: pointer to the ATA host for this device
     30 * @master_cbl: master cable type
     31 * @slave_cbl: slave cable type
     32 * @sg: Gemini SATA bridge pointer, if running on the Gemini
     33 * @master_to_sata0: Gemini SATA bridge: the ATA master is connected
     34 * to the SATA0 bridge
     35 * @slave_to_sata0: Gemini SATA bridge: the ATA slave is connected
     36 * to the SATA0 bridge
     37 * @master_to_sata1: Gemini SATA bridge: the ATA master is connected
     38 * to the SATA1 bridge
     39 * @slave_to_sata1: Gemini SATA bridge: the ATA slave is connected
     40 * to the SATA1 bridge
     41 */
     42struct ftide010 {
     43	struct device *dev;
     44	void __iomem *base;
     45	struct clk *pclk;
     46	struct ata_host *host;
     47	unsigned int master_cbl;
     48	unsigned int slave_cbl;
     49	/* Gemini-specific properties */
     50	struct sata_gemini *sg;
     51	bool master_to_sata0;
     52	bool slave_to_sata0;
     53	bool master_to_sata1;
     54	bool slave_to_sata1;
     55};
     56
     57#define FTIDE010_DMA_REG	0x00
     58#define FTIDE010_DMA_STATUS	0x02
     59#define FTIDE010_IDE_BMDTPR	0x04
     60#define FTIDE010_IDE_DEVICE_ID	0x08
     61#define FTIDE010_PIO_TIMING	0x10
     62#define FTIDE010_MWDMA_TIMING	0x11
     63#define FTIDE010_UDMA_TIMING0	0x12 /* Master */
     64#define FTIDE010_UDMA_TIMING1	0x13 /* Slave */
     65#define FTIDE010_CLK_MOD	0x14
     66/* These registers are mapped directly to the IDE registers */
     67#define FTIDE010_CMD_DATA	0x20
     68#define FTIDE010_ERROR_FEATURES	0x21
     69#define FTIDE010_NSECT		0x22
     70#define FTIDE010_LBAL		0x23
     71#define FTIDE010_LBAM		0x24
     72#define FTIDE010_LBAH		0x25
     73#define FTIDE010_DEVICE		0x26
     74#define FTIDE010_STATUS_COMMAND	0x27
     75#define FTIDE010_ALTSTAT_CTRL	0x36
     76
     77/* Set this bit for UDMA mode 5 and 6 */
     78#define FTIDE010_UDMA_TIMING_MODE_56	BIT(7)
     79
     80/* 0 = 50 MHz, 1 = 66 MHz */
     81#define FTIDE010_CLK_MOD_DEV0_CLK_SEL	BIT(0)
     82#define FTIDE010_CLK_MOD_DEV1_CLK_SEL	BIT(1)
     83/* Enable UDMA on a device */
     84#define FTIDE010_CLK_MOD_DEV0_UDMA_EN	BIT(4)
     85#define FTIDE010_CLK_MOD_DEV1_UDMA_EN	BIT(5)
     86
     87static struct scsi_host_template pata_ftide010_sht = {
     88	ATA_BMDMA_SHT(DRV_NAME),
     89};
     90
     91/*
     92 * Bus timings
     93 *
     94 * The unit of the below required timings is two clock periods of the ATA
     95 * reference clock which is 30 nanoseconds per unit at 66MHz and 20
     96 * nanoseconds per unit at 50 MHz. The PIO timings assume 33MHz speed for
     97 * PIO.
     98 *
     99 * pio_active_time: array of 5 elements for T2 timing for Mode 0,
    100 * 1, 2, 3 and 4. Range 0..15.
    101 * pio_recovery_time: array of 5 elements for T2l timing for Mode 0,
    102 * 1, 2, 3 and 4. Range 0..15.
    103 * mdma_50_active_time: array of 4 elements for Td timing for multi
    104 * word DMA, Mode 0, 1, and 2 at 50 MHz. Range 0..15.
    105 * mdma_50_recovery_time: array of 4 elements for Tk timing for
    106 * multi word DMA, Mode 0, 1 and 2 at 50 MHz. Range 0..15.
    107 * mdma_66_active_time: array of 4 elements for Td timing for multi
    108 * word DMA, Mode 0, 1 and 2 at 66 MHz. Range 0..15.
    109 * mdma_66_recovery_time: array of 4 elements for Tk timing for
    110 * multi word DMA, Mode 0, 1 and 2 at 66 MHz. Range 0..15.
    111 * udma_50_setup_time: array of 4 elements for Tvds timing for ultra
    112 * DMA, Mode 0, 1, 2, 3, 4 and 5 at 50 MHz. Range 0..7.
    113 * udma_50_hold_time: array of 4 elements for Tdvh timing for
    114 * multi word DMA, Mode 0, 1, 2, 3, 4 and 5 at 50 MHz, Range 0..7.
    115 * udma_66_setup_time: array of 4 elements for Tvds timing for multi
    116 * word DMA, Mode 0, 1, 2, 3, 4, 5 and 6 at 66 MHz. Range 0..7.
    117 * udma_66_hold_time: array of 4 elements for Tdvh timing for
    118 * multi word DMA, Mode 0, 1, 2, 3, 4, 5 and 6 at 66 MHz. Range 0..7.
    119 */
    120static const u8 pio_active_time[5] = {10, 10, 10, 3, 3};
    121static const u8 pio_recovery_time[5] = {10, 3, 1, 3, 1};
    122static const u8 mwdma_50_active_time[3] = {6, 2, 2};
    123static const u8 mwdma_50_recovery_time[3] = {6, 2, 1};
    124static const u8 mwdma_66_active_time[3] = {8, 3, 3};
    125static const u8 mwdma_66_recovery_time[3] = {8, 2, 1};
    126static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 1};
    127static const u8 udma_50_hold_time[6] = {3, 1, 1, 1, 1, 1};
    128static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, };
    129static const u8 udma_66_hold_time[7] = {};
    130
    131/*
    132 * We set 66 MHz for all MWDMA modes
    133 */
    134static const bool set_mdma_66_mhz[] = { true, true, true, true };
    135
    136/*
    137 * We set 66 MHz for UDMA modes 3, 4 and 6 and no others
    138 */
    139static const bool set_udma_66_mhz[] = { false, false, false, true, true, false, true };
    140
    141static void ftide010_set_dmamode(struct ata_port *ap, struct ata_device *adev)
    142{
    143	struct ftide010 *ftide = ap->host->private_data;
    144	u8 speed = adev->dma_mode;
    145	u8 devno = adev->devno & 1;
    146	u8 udma_en_mask;
    147	u8 f66m_en_mask;
    148	u8 clkreg;
    149	u8 timreg;
    150	u8 i;
    151
    152	/* Target device 0 (master) or 1 (slave) */
    153	if (!devno) {
    154		udma_en_mask = FTIDE010_CLK_MOD_DEV0_UDMA_EN;
    155		f66m_en_mask = FTIDE010_CLK_MOD_DEV0_CLK_SEL;
    156	} else {
    157		udma_en_mask = FTIDE010_CLK_MOD_DEV1_UDMA_EN;
    158		f66m_en_mask = FTIDE010_CLK_MOD_DEV1_CLK_SEL;
    159	}
    160
    161	clkreg = readb(ftide->base + FTIDE010_CLK_MOD);
    162	clkreg &= ~udma_en_mask;
    163	clkreg &= ~f66m_en_mask;
    164
    165	if (speed & XFER_UDMA_0) {
    166		i = speed & ~XFER_UDMA_0;
    167		dev_dbg(ftide->dev, "set UDMA mode %02x, index %d\n",
    168			speed, i);
    169
    170		clkreg |= udma_en_mask;
    171		if (set_udma_66_mhz[i]) {
    172			clkreg |= f66m_en_mask;
    173			timreg = udma_66_setup_time[i] << 4 |
    174				udma_66_hold_time[i];
    175		} else {
    176			timreg = udma_50_setup_time[i] << 4 |
    177				udma_50_hold_time[i];
    178		}
    179
    180		/* A special bit needs to be set for modes 5 and 6 */
    181		if (i >= 5)
    182			timreg |= FTIDE010_UDMA_TIMING_MODE_56;
    183
    184		dev_dbg(ftide->dev, "UDMA write clkreg = %02x, timreg = %02x\n",
    185			clkreg, timreg);
    186
    187		writeb(clkreg, ftide->base + FTIDE010_CLK_MOD);
    188		writeb(timreg, ftide->base + FTIDE010_UDMA_TIMING0 + devno);
    189	} else {
    190		i = speed & ~XFER_MW_DMA_0;
    191		dev_dbg(ftide->dev, "set MWDMA mode %02x, index %d\n",
    192			speed, i);
    193
    194		if (set_mdma_66_mhz[i]) {
    195			clkreg |= f66m_en_mask;
    196			timreg = mwdma_66_active_time[i] << 4 |
    197				mwdma_66_recovery_time[i];
    198		} else {
    199			timreg = mwdma_50_active_time[i] << 4 |
    200				mwdma_50_recovery_time[i];
    201		}
    202		dev_dbg(ftide->dev,
    203			"MWDMA write clkreg = %02x, timreg = %02x\n",
    204			clkreg, timreg);
    205		/* This will affect all devices */
    206		writeb(clkreg, ftide->base + FTIDE010_CLK_MOD);
    207		writeb(timreg, ftide->base + FTIDE010_MWDMA_TIMING);
    208	}
    209
    210	/*
    211	 * Store the current device (master or slave) in ap->private_data
    212	 * so that .qc_issue() can detect if this changes and reprogram
    213	 * the DMA settings.
    214	 */
    215	ap->private_data = adev;
    216
    217	return;
    218}
    219
    220static void ftide010_set_piomode(struct ata_port *ap, struct ata_device *adev)
    221{
    222	struct ftide010 *ftide = ap->host->private_data;
    223	u8 pio = adev->pio_mode - XFER_PIO_0;
    224
    225	dev_dbg(ftide->dev, "set PIO mode %02x, index %d\n",
    226		adev->pio_mode, pio);
    227	writeb(pio_active_time[pio] << 4 | pio_recovery_time[pio],
    228	       ftide->base + FTIDE010_PIO_TIMING);
    229}
    230
    231/*
    232 * We implement our own qc_issue() callback since we may need to set up
    233 * the timings differently for master and slave transfers: the CLK_MOD_REG
    234 * and MWDMA_TIMING_REG is shared between master and slave, so reprogramming
    235 * this may be necessary.
    236 */
    237static unsigned int ftide010_qc_issue(struct ata_queued_cmd *qc)
    238{
    239	struct ata_port *ap = qc->ap;
    240	struct ata_device *adev = qc->dev;
    241
    242	/*
    243	 * If the device changed, i.e. slave->master, master->slave,
    244	 * then set up the DMA mode again so we are sure the timings
    245	 * are correct.
    246	 */
    247	if (adev != ap->private_data && ata_dma_enabled(adev))
    248		ftide010_set_dmamode(ap, adev);
    249
    250	return ata_bmdma_qc_issue(qc);
    251}
    252
    253static struct ata_port_operations pata_ftide010_port_ops = {
    254	.inherits	= &ata_bmdma_port_ops,
    255	.set_dmamode	= ftide010_set_dmamode,
    256	.set_piomode	= ftide010_set_piomode,
    257	.qc_issue	= ftide010_qc_issue,
    258};
    259
    260static struct ata_port_info ftide010_port_info = {
    261	.flags		= ATA_FLAG_SLAVE_POSS,
    262	.mwdma_mask	= ATA_MWDMA2,
    263	.udma_mask	= ATA_UDMA6,
    264	.pio_mask	= ATA_PIO4,
    265	.port_ops	= &pata_ftide010_port_ops,
    266};
    267
    268#if IS_ENABLED(CONFIG_SATA_GEMINI)
    269
    270static int pata_ftide010_gemini_port_start(struct ata_port *ap)
    271{
    272	struct ftide010 *ftide = ap->host->private_data;
    273	struct device *dev = ftide->dev;
    274	struct sata_gemini *sg = ftide->sg;
    275	int bridges = 0;
    276	int ret;
    277
    278	ret = ata_bmdma_port_start(ap);
    279	if (ret)
    280		return ret;
    281
    282	if (ftide->master_to_sata0) {
    283		dev_info(dev, "SATA0 (master) start\n");
    284		ret = gemini_sata_start_bridge(sg, 0);
    285		if (!ret)
    286			bridges++;
    287	}
    288	if (ftide->master_to_sata1) {
    289		dev_info(dev, "SATA1 (master) start\n");
    290		ret = gemini_sata_start_bridge(sg, 1);
    291		if (!ret)
    292			bridges++;
    293	}
    294	/* Avoid double-starting */
    295	if (ftide->slave_to_sata0 && !ftide->master_to_sata0) {
    296		dev_info(dev, "SATA0 (slave) start\n");
    297		ret = gemini_sata_start_bridge(sg, 0);
    298		if (!ret)
    299			bridges++;
    300	}
    301	/* Avoid double-starting */
    302	if (ftide->slave_to_sata1 && !ftide->master_to_sata1) {
    303		dev_info(dev, "SATA1 (slave) start\n");
    304		ret = gemini_sata_start_bridge(sg, 1);
    305		if (!ret)
    306			bridges++;
    307	}
    308
    309	dev_info(dev, "brought %d bridges online\n", bridges);
    310	return (bridges > 0) ? 0 : -EINVAL; // -ENODEV;
    311}
    312
    313static void pata_ftide010_gemini_port_stop(struct ata_port *ap)
    314{
    315	struct ftide010 *ftide = ap->host->private_data;
    316	struct device *dev = ftide->dev;
    317	struct sata_gemini *sg = ftide->sg;
    318
    319	if (ftide->master_to_sata0) {
    320		dev_info(dev, "SATA0 (master) stop\n");
    321		gemini_sata_stop_bridge(sg, 0);
    322	}
    323	if (ftide->master_to_sata1) {
    324		dev_info(dev, "SATA1 (master) stop\n");
    325		gemini_sata_stop_bridge(sg, 1);
    326	}
    327	/* Avoid double-stopping */
    328	if (ftide->slave_to_sata0 && !ftide->master_to_sata0) {
    329		dev_info(dev, "SATA0 (slave) stop\n");
    330		gemini_sata_stop_bridge(sg, 0);
    331	}
    332	/* Avoid double-stopping */
    333	if (ftide->slave_to_sata1 && !ftide->master_to_sata1) {
    334		dev_info(dev, "SATA1 (slave) stop\n");
    335		gemini_sata_stop_bridge(sg, 1);
    336	}
    337}
    338
    339static int pata_ftide010_gemini_cable_detect(struct ata_port *ap)
    340{
    341	struct ftide010 *ftide = ap->host->private_data;
    342
    343	/*
    344	 * Return the master cable, I have no clue how to return a different
    345	 * cable for the slave than for the master.
    346	 */
    347	return ftide->master_cbl;
    348}
    349
    350static int pata_ftide010_gemini_init(struct ftide010 *ftide,
    351				     struct ata_port_info *pi,
    352				     bool is_ata1)
    353{
    354	struct device *dev = ftide->dev;
    355	struct sata_gemini *sg;
    356	enum gemini_muxmode muxmode;
    357
    358	/* Look up SATA bridge */
    359	sg = gemini_sata_bridge_get();
    360	if (IS_ERR(sg))
    361		return PTR_ERR(sg);
    362	ftide->sg = sg;
    363
    364	muxmode = gemini_sata_get_muxmode(sg);
    365
    366	/* Special ops */
    367	pata_ftide010_port_ops.port_start =
    368		pata_ftide010_gemini_port_start;
    369	pata_ftide010_port_ops.port_stop =
    370		pata_ftide010_gemini_port_stop;
    371	pata_ftide010_port_ops.cable_detect =
    372		pata_ftide010_gemini_cable_detect;
    373
    374	/* Flag port as SATA-capable */
    375	if (gemini_sata_bridge_enabled(sg, is_ata1))
    376		pi->flags |= ATA_FLAG_SATA;
    377
    378	/* This device has broken DMA, only PIO works */
    379	if (of_machine_is_compatible("itian,sq201")) {
    380		pi->mwdma_mask = 0;
    381		pi->udma_mask = 0;
    382	}
    383
    384	/*
    385	 * We assume that a simple 40-wire cable is used in the PATA mode.
    386	 * if you're adding a system using the PATA interface, make sure
    387	 * the right cable is set up here, it might be necessary to use
    388	 * special hardware detection or encode the cable type in the device
    389	 * tree with special properties.
    390	 */
    391	if (!is_ata1) {
    392		switch (muxmode) {
    393		case GEMINI_MUXMODE_0:
    394			ftide->master_cbl = ATA_CBL_SATA;
    395			ftide->slave_cbl = ATA_CBL_PATA40;
    396			ftide->master_to_sata0 = true;
    397			break;
    398		case GEMINI_MUXMODE_1:
    399			ftide->master_cbl = ATA_CBL_SATA;
    400			ftide->slave_cbl = ATA_CBL_NONE;
    401			ftide->master_to_sata0 = true;
    402			break;
    403		case GEMINI_MUXMODE_2:
    404			ftide->master_cbl = ATA_CBL_PATA40;
    405			ftide->slave_cbl = ATA_CBL_PATA40;
    406			break;
    407		case GEMINI_MUXMODE_3:
    408			ftide->master_cbl = ATA_CBL_SATA;
    409			ftide->slave_cbl = ATA_CBL_SATA;
    410			ftide->master_to_sata0 = true;
    411			ftide->slave_to_sata1 = true;
    412			break;
    413		}
    414	} else {
    415		switch (muxmode) {
    416		case GEMINI_MUXMODE_0:
    417			ftide->master_cbl = ATA_CBL_SATA;
    418			ftide->slave_cbl = ATA_CBL_NONE;
    419			ftide->master_to_sata1 = true;
    420			break;
    421		case GEMINI_MUXMODE_1:
    422			ftide->master_cbl = ATA_CBL_SATA;
    423			ftide->slave_cbl = ATA_CBL_PATA40;
    424			ftide->master_to_sata1 = true;
    425			break;
    426		case GEMINI_MUXMODE_2:
    427			ftide->master_cbl = ATA_CBL_SATA;
    428			ftide->slave_cbl = ATA_CBL_SATA;
    429			ftide->slave_to_sata0 = true;
    430			ftide->master_to_sata1 = true;
    431			break;
    432		case GEMINI_MUXMODE_3:
    433			ftide->master_cbl = ATA_CBL_PATA40;
    434			ftide->slave_cbl = ATA_CBL_PATA40;
    435			break;
    436		}
    437	}
    438	dev_info(dev, "set up Gemini PATA%d\n", is_ata1);
    439
    440	return 0;
    441}
    442#else
    443static int pata_ftide010_gemini_init(struct ftide010 *ftide,
    444				     struct ata_port_info *pi,
    445				     bool is_ata1)
    446{
    447	return -ENOTSUPP;
    448}
    449#endif
    450
    451
    452static int pata_ftide010_probe(struct platform_device *pdev)
    453{
    454	struct device *dev = &pdev->dev;
    455	struct device_node *np = dev->of_node;
    456	struct ata_port_info pi = ftide010_port_info;
    457	const struct ata_port_info *ppi[] = { &pi, NULL };
    458	struct ftide010 *ftide;
    459	struct resource *res;
    460	int irq;
    461	int ret;
    462	int i;
    463
    464	ftide = devm_kzalloc(dev, sizeof(*ftide), GFP_KERNEL);
    465	if (!ftide)
    466		return -ENOMEM;
    467	ftide->dev = dev;
    468
    469	irq = platform_get_irq(pdev, 0);
    470	if (irq < 0)
    471		return irq;
    472
    473	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    474	if (!res)
    475		return -ENODEV;
    476
    477	ftide->base = devm_ioremap_resource(dev, res);
    478	if (IS_ERR(ftide->base))
    479		return PTR_ERR(ftide->base);
    480
    481	ftide->pclk = devm_clk_get(dev, "PCLK");
    482	if (!IS_ERR(ftide->pclk)) {
    483		ret = clk_prepare_enable(ftide->pclk);
    484		if (ret) {
    485			dev_err(dev, "failed to enable PCLK\n");
    486			return ret;
    487		}
    488	}
    489
    490	/* Some special Cortina Gemini init, if needed */
    491	if (of_device_is_compatible(np, "cortina,gemini-pata")) {
    492		/*
    493		 * We need to know which instance is probing (the
    494		 * Gemini has two instances of FTIDE010) and we do
    495		 * this simply by looking at the physical base
    496		 * address, which is 0x63400000 for ATA1, else we
    497		 * are ATA0. This will also set up the cable types.
    498		 */
    499		ret = pata_ftide010_gemini_init(ftide,
    500				&pi,
    501				(res->start == 0x63400000));
    502		if (ret)
    503			goto err_dis_clk;
    504	} else {
    505		/* Else assume we are connected using PATA40 */
    506		ftide->master_cbl = ATA_CBL_PATA40;
    507		ftide->slave_cbl = ATA_CBL_PATA40;
    508	}
    509
    510	ftide->host = ata_host_alloc_pinfo(dev, ppi, 1);
    511	if (!ftide->host) {
    512		ret = -ENOMEM;
    513		goto err_dis_clk;
    514	}
    515	ftide->host->private_data = ftide;
    516
    517	for (i = 0; i < ftide->host->n_ports; i++) {
    518		struct ata_port *ap = ftide->host->ports[i];
    519		struct ata_ioports *ioaddr = &ap->ioaddr;
    520
    521		ioaddr->bmdma_addr = ftide->base + FTIDE010_DMA_REG;
    522		ioaddr->cmd_addr = ftide->base + FTIDE010_CMD_DATA;
    523		ioaddr->ctl_addr = ftide->base + FTIDE010_ALTSTAT_CTRL;
    524		ioaddr->altstatus_addr = ftide->base + FTIDE010_ALTSTAT_CTRL;
    525		ata_sff_std_ports(ioaddr);
    526	}
    527
    528	dev_info(dev, "device ID %08x, irq %d, reg %pR\n",
    529		 readl(ftide->base + FTIDE010_IDE_DEVICE_ID), irq, res);
    530
    531	ret = ata_host_activate(ftide->host, irq, ata_bmdma_interrupt,
    532				0, &pata_ftide010_sht);
    533	if (ret)
    534		goto err_dis_clk;
    535
    536	return 0;
    537
    538err_dis_clk:
    539	clk_disable_unprepare(ftide->pclk);
    540
    541	return ret;
    542}
    543
    544static int pata_ftide010_remove(struct platform_device *pdev)
    545{
    546	struct ata_host *host = platform_get_drvdata(pdev);
    547	struct ftide010 *ftide = host->private_data;
    548
    549	ata_host_detach(ftide->host);
    550	clk_disable_unprepare(ftide->pclk);
    551
    552	return 0;
    553}
    554
    555static const struct of_device_id pata_ftide010_of_match[] = {
    556	{ .compatible = "faraday,ftide010", },
    557	{ /* sentinel */ }
    558};
    559
    560static struct platform_driver pata_ftide010_driver = {
    561	.driver = {
    562		.name = DRV_NAME,
    563		.of_match_table = of_match_ptr(pata_ftide010_of_match),
    564	},
    565	.probe = pata_ftide010_probe,
    566	.remove = pata_ftide010_remove,
    567};
    568module_platform_driver(pata_ftide010_driver);
    569
    570MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
    571MODULE_LICENSE("GPL");
    572MODULE_ALIAS("platform:" DRV_NAME);