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_samsung_cf.c (17372B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
      4 *		http://www.samsung.com
      5 *
      6 * PATA driver for Samsung SoCs.
      7 * Supports CF Interface in True IDE mode. Currently only PIO mode has been
      8 * implemented; UDMA support has to be added.
      9 *
     10 * Based on:
     11 *	PATA driver for AT91SAM9260 Static Memory Controller
     12 *	PATA driver for Toshiba SCC controller
     13*/
     14
     15#include <linux/kernel.h>
     16#include <linux/module.h>
     17#include <linux/mod_devicetable.h>
     18#include <linux/init.h>
     19#include <linux/clk.h>
     20#include <linux/libata.h>
     21#include <linux/platform_device.h>
     22#include <linux/slab.h>
     23
     24#include <linux/platform_data/ata-samsung_cf.h>
     25
     26#define DRV_NAME "pata_samsung_cf"
     27#define DRV_VERSION "0.1"
     28
     29#define S3C_CFATA_REG(x)	(x)
     30#define S3C_CFATA_MUX		S3C_CFATA_REG(0x0)
     31#define S3C_ATA_CTRL		S3C_CFATA_REG(0x0)
     32#define S3C_ATA_CMD		S3C_CFATA_REG(0x8)
     33#define S3C_ATA_IRQ		S3C_CFATA_REG(0x10)
     34#define S3C_ATA_IRQ_MSK		S3C_CFATA_REG(0x14)
     35#define S3C_ATA_CFG		S3C_CFATA_REG(0x18)
     36
     37#define S3C_ATA_PIO_TIME	S3C_CFATA_REG(0x2c)
     38#define S3C_ATA_PIO_DTR		S3C_CFATA_REG(0x54)
     39#define S3C_ATA_PIO_FED		S3C_CFATA_REG(0x58)
     40#define S3C_ATA_PIO_SCR		S3C_CFATA_REG(0x5c)
     41#define S3C_ATA_PIO_LLR		S3C_CFATA_REG(0x60)
     42#define S3C_ATA_PIO_LMR		S3C_CFATA_REG(0x64)
     43#define S3C_ATA_PIO_LHR		S3C_CFATA_REG(0x68)
     44#define S3C_ATA_PIO_DVR		S3C_CFATA_REG(0x6c)
     45#define S3C_ATA_PIO_CSD		S3C_CFATA_REG(0x70)
     46#define S3C_ATA_PIO_DAD		S3C_CFATA_REG(0x74)
     47#define S3C_ATA_PIO_RDATA	S3C_CFATA_REG(0x7c)
     48
     49#define S3C_CFATA_MUX_TRUEIDE	0x01
     50#define S3C_ATA_CFG_SWAP	0x40
     51#define S3C_ATA_CFG_IORDYEN	0x02
     52
     53enum s3c_cpu_type {
     54	TYPE_S3C64XX,
     55	TYPE_S5PV210,
     56};
     57
     58/*
     59 * struct s3c_ide_info - S3C PATA instance.
     60 * @clk: The clock resource for this controller.
     61 * @ide_addr: The area mapped for the hardware registers.
     62 * @sfr_addr: The area mapped for the special function registers.
     63 * @irq: The IRQ number we are using.
     64 * @cpu_type: The exact type of this controller.
     65 * @fifo_status_reg: The ATA_FIFO_STATUS register offset.
     66 */
     67struct s3c_ide_info {
     68	struct clk *clk;
     69	void __iomem *ide_addr;
     70	void __iomem *sfr_addr;
     71	int irq;
     72	enum s3c_cpu_type cpu_type;
     73	unsigned int fifo_status_reg;
     74};
     75
     76static void pata_s3c_set_endian(void __iomem *s3c_ide_regbase, u8 mode)
     77{
     78	u32 reg = readl(s3c_ide_regbase + S3C_ATA_CFG);
     79	reg = mode ? (reg & ~S3C_ATA_CFG_SWAP) : (reg | S3C_ATA_CFG_SWAP);
     80	writel(reg, s3c_ide_regbase + S3C_ATA_CFG);
     81}
     82
     83static void pata_s3c_cfg_mode(void __iomem *s3c_ide_sfrbase)
     84{
     85	/* Select true-ide as the internal operating mode */
     86	writel(readl(s3c_ide_sfrbase + S3C_CFATA_MUX) | S3C_CFATA_MUX_TRUEIDE,
     87		s3c_ide_sfrbase + S3C_CFATA_MUX);
     88}
     89
     90static unsigned long
     91pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata)
     92{
     93	int t1 = ata->setup;
     94	int t2 = ata->act8b;
     95	int t2i = ata->rec8b;
     96	ulong piotime;
     97
     98	piotime = ((t2i & 0xff) << 12) | ((t2 & 0xff) << 4) | (t1 & 0xf);
     99
    100	return piotime;
    101}
    102
    103static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev)
    104{
    105	struct s3c_ide_info *info = ap->host->private_data;
    106	struct ata_timing timing;
    107	int cycle_time;
    108	ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG);
    109	ulong piotime;
    110
    111	/* Enables IORDY if mode requires it */
    112	if (ata_pio_need_iordy(adev))
    113		ata_cfg |= S3C_ATA_CFG_IORDYEN;
    114	else
    115		ata_cfg &= ~S3C_ATA_CFG_IORDYEN;
    116
    117	cycle_time = (int)(1000000000UL / clk_get_rate(info->clk));
    118
    119	ata_timing_compute(adev, adev->pio_mode, &timing,
    120					cycle_time * 1000, 0);
    121
    122	piotime = pata_s3c_setup_timing(info, &timing);
    123
    124	writel(ata_cfg, info->ide_addr + S3C_ATA_CFG);
    125	writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME);
    126}
    127
    128/*
    129 * Waits until the IDE controller is able to perform next read/write
    130 * operation to the disk. Needed for 64XX series boards only.
    131 */
    132static int wait_for_host_ready(struct s3c_ide_info *info)
    133{
    134	ulong timeout;
    135	void __iomem *fifo_reg = info->ide_addr + info->fifo_status_reg;
    136
    137	/* wait for maximum of 20 msec */
    138	timeout = jiffies + msecs_to_jiffies(20);
    139	while (time_before(jiffies, timeout)) {
    140		if ((readl(fifo_reg) >> 28) == 0)
    141			return 0;
    142	}
    143	return -EBUSY;
    144}
    145
    146/*
    147 * Writes to one of the task file registers.
    148 */
    149static void ata_outb(struct ata_host *host, u8 addr, void __iomem *reg)
    150{
    151	struct s3c_ide_info *info = host->private_data;
    152
    153	wait_for_host_ready(info);
    154	writeb(addr, reg);
    155}
    156
    157/*
    158 * Reads from one of the task file registers.
    159 */
    160static u8 ata_inb(struct ata_host *host, void __iomem *reg)
    161{
    162	struct s3c_ide_info *info = host->private_data;
    163	u8 temp;
    164
    165	wait_for_host_ready(info);
    166	(void) readb(reg);
    167	wait_for_host_ready(info);
    168	temp = readb(info->ide_addr + S3C_ATA_PIO_RDATA);
    169	return temp;
    170}
    171
    172/*
    173 * pata_s3c_tf_load - send taskfile registers to host controller
    174 */
    175static void pata_s3c_tf_load(struct ata_port *ap,
    176				const struct ata_taskfile *tf)
    177{
    178	struct ata_ioports *ioaddr = &ap->ioaddr;
    179	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
    180
    181	if (tf->ctl != ap->last_ctl) {
    182		ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr);
    183		ap->last_ctl = tf->ctl;
    184		ata_wait_idle(ap);
    185	}
    186
    187	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
    188		ata_outb(ap->host, tf->hob_feature, ioaddr->feature_addr);
    189		ata_outb(ap->host, tf->hob_nsect, ioaddr->nsect_addr);
    190		ata_outb(ap->host, tf->hob_lbal, ioaddr->lbal_addr);
    191		ata_outb(ap->host, tf->hob_lbam, ioaddr->lbam_addr);
    192		ata_outb(ap->host, tf->hob_lbah, ioaddr->lbah_addr);
    193	}
    194
    195	if (is_addr) {
    196		ata_outb(ap->host, tf->feature, ioaddr->feature_addr);
    197		ata_outb(ap->host, tf->nsect, ioaddr->nsect_addr);
    198		ata_outb(ap->host, tf->lbal, ioaddr->lbal_addr);
    199		ata_outb(ap->host, tf->lbam, ioaddr->lbam_addr);
    200		ata_outb(ap->host, tf->lbah, ioaddr->lbah_addr);
    201	}
    202
    203	if (tf->flags & ATA_TFLAG_DEVICE)
    204		ata_outb(ap->host, tf->device, ioaddr->device_addr);
    205
    206	ata_wait_idle(ap);
    207}
    208
    209/*
    210 * pata_s3c_tf_read - input device's ATA taskfile shadow registers
    211 */
    212static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
    213{
    214	struct ata_ioports *ioaddr = &ap->ioaddr;
    215
    216	tf->error = ata_inb(ap->host, ioaddr->error_addr);
    217	tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr);
    218	tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr);
    219	tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr);
    220	tf->lbah = ata_inb(ap->host, ioaddr->lbah_addr);
    221	tf->device = ata_inb(ap->host, ioaddr->device_addr);
    222
    223	if (tf->flags & ATA_TFLAG_LBA48) {
    224		ata_outb(ap->host, tf->ctl | ATA_HOB, ioaddr->ctl_addr);
    225		tf->hob_feature = ata_inb(ap->host, ioaddr->error_addr);
    226		tf->hob_nsect = ata_inb(ap->host, ioaddr->nsect_addr);
    227		tf->hob_lbal = ata_inb(ap->host, ioaddr->lbal_addr);
    228		tf->hob_lbam = ata_inb(ap->host, ioaddr->lbam_addr);
    229		tf->hob_lbah = ata_inb(ap->host, ioaddr->lbah_addr);
    230		ata_outb(ap->host, tf->ctl, ioaddr->ctl_addr);
    231		ap->last_ctl = tf->ctl;
    232	}
    233}
    234
    235/*
    236 * pata_s3c_exec_command - issue ATA command to host controller
    237 */
    238static void pata_s3c_exec_command(struct ata_port *ap,
    239				const struct ata_taskfile *tf)
    240{
    241	ata_outb(ap->host, tf->command, ap->ioaddr.command_addr);
    242	ata_sff_pause(ap);
    243}
    244
    245/*
    246 * pata_s3c_check_status - Read device status register
    247 */
    248static u8 pata_s3c_check_status(struct ata_port *ap)
    249{
    250	return ata_inb(ap->host, ap->ioaddr.status_addr);
    251}
    252
    253/*
    254 * pata_s3c_check_altstatus - Read alternate device status register
    255 */
    256static u8 pata_s3c_check_altstatus(struct ata_port *ap)
    257{
    258	return ata_inb(ap->host, ap->ioaddr.altstatus_addr);
    259}
    260
    261/*
    262 * pata_s3c_data_xfer - Transfer data by PIO
    263 */
    264static unsigned int pata_s3c_data_xfer(struct ata_queued_cmd *qc,
    265				unsigned char *buf, unsigned int buflen, int rw)
    266{
    267	struct ata_port *ap = qc->dev->link->ap;
    268	struct s3c_ide_info *info = ap->host->private_data;
    269	void __iomem *data_addr = ap->ioaddr.data_addr;
    270	unsigned int words = buflen >> 1, i;
    271	u16 *data_ptr = (u16 *)buf;
    272
    273	/* Requires wait same as in ata_inb/ata_outb */
    274	if (rw == READ)
    275		for (i = 0; i < words; i++, data_ptr++) {
    276			wait_for_host_ready(info);
    277			(void) readw(data_addr);
    278			wait_for_host_ready(info);
    279			*data_ptr = readw(info->ide_addr
    280					+ S3C_ATA_PIO_RDATA);
    281		}
    282	else
    283		for (i = 0; i < words; i++, data_ptr++) {
    284			wait_for_host_ready(info);
    285			writew(*data_ptr, data_addr);
    286		}
    287
    288	if (buflen & 0x01)
    289		dev_err(ap->dev, "unexpected trailing data\n");
    290
    291	return words << 1;
    292}
    293
    294/*
    295 * pata_s3c_dev_select - Select device on ATA bus
    296 */
    297static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device)
    298{
    299	u8 tmp = ATA_DEVICE_OBS;
    300
    301	if (device != 0)
    302		tmp |= ATA_DEV1;
    303
    304	ata_outb(ap->host, tmp, ap->ioaddr.device_addr);
    305	ata_sff_pause(ap);
    306}
    307
    308/*
    309 * pata_s3c_devchk - PATA device presence detection
    310 */
    311static bool pata_s3c_devchk(struct ata_port *ap, unsigned int device)
    312{
    313	struct ata_ioports *ioaddr = &ap->ioaddr;
    314	u8 nsect, lbal;
    315
    316	pata_s3c_dev_select(ap, device);
    317
    318	ata_outb(ap->host, 0x55, ioaddr->nsect_addr);
    319	ata_outb(ap->host, 0xaa, ioaddr->lbal_addr);
    320
    321	ata_outb(ap->host, 0xaa, ioaddr->nsect_addr);
    322	ata_outb(ap->host, 0x55, ioaddr->lbal_addr);
    323
    324	ata_outb(ap->host, 0x55, ioaddr->nsect_addr);
    325	ata_outb(ap->host, 0xaa, ioaddr->lbal_addr);
    326
    327	nsect = ata_inb(ap->host, ioaddr->nsect_addr);
    328	lbal = ata_inb(ap->host, ioaddr->lbal_addr);
    329
    330	if ((nsect == 0x55) && (lbal == 0xaa))
    331		return true;	/* we found a device */
    332
    333	return false;		/* nothing found */
    334}
    335
    336/*
    337 * pata_s3c_wait_after_reset - wait for devices to become ready after reset
    338 */
    339static int pata_s3c_wait_after_reset(struct ata_link *link,
    340		unsigned long deadline)
    341{
    342	int rc;
    343
    344	ata_msleep(link->ap, ATA_WAIT_AFTER_RESET);
    345
    346	/* always check readiness of the master device */
    347	rc = ata_sff_wait_ready(link, deadline);
    348	/* -ENODEV means the odd clown forgot the D7 pulldown resistor
    349	 * and TF status is 0xff, bail out on it too.
    350	 */
    351	if (rc)
    352		return rc;
    353
    354	return 0;
    355}
    356
    357/*
    358 * pata_s3c_bus_softreset - PATA device software reset
    359 */
    360static int pata_s3c_bus_softreset(struct ata_port *ap,
    361		unsigned long deadline)
    362{
    363	struct ata_ioports *ioaddr = &ap->ioaddr;
    364
    365	/* software reset.  causes dev0 to be selected */
    366	ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr);
    367	udelay(20);
    368	ata_outb(ap->host, ap->ctl | ATA_SRST, ioaddr->ctl_addr);
    369	udelay(20);
    370	ata_outb(ap->host, ap->ctl, ioaddr->ctl_addr);
    371	ap->last_ctl = ap->ctl;
    372
    373	return pata_s3c_wait_after_reset(&ap->link, deadline);
    374}
    375
    376/*
    377 * pata_s3c_softreset - reset host port via ATA SRST
    378 */
    379static int pata_s3c_softreset(struct ata_link *link, unsigned int *classes,
    380			 unsigned long deadline)
    381{
    382	struct ata_port *ap = link->ap;
    383	unsigned int devmask = 0;
    384	int rc;
    385	u8 err;
    386
    387	/* determine if device 0 is present */
    388	if (pata_s3c_devchk(ap, 0))
    389		devmask |= (1 << 0);
    390
    391	/* select device 0 again */
    392	pata_s3c_dev_select(ap, 0);
    393
    394	/* issue bus reset */
    395	rc = pata_s3c_bus_softreset(ap, deadline);
    396	/* if link is occupied, -ENODEV too is an error */
    397	if (rc && rc != -ENODEV) {
    398		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
    399		return rc;
    400	}
    401
    402	/* determine by signature whether we have ATA or ATAPI devices */
    403	classes[0] = ata_sff_dev_classify(&ap->link.device[0],
    404					  devmask & (1 << 0), &err);
    405
    406	return 0;
    407}
    408
    409/*
    410 * pata_s3c_set_devctl - Write device control register
    411 */
    412static void pata_s3c_set_devctl(struct ata_port *ap, u8 ctl)
    413{
    414	ata_outb(ap->host, ctl, ap->ioaddr.ctl_addr);
    415}
    416
    417static struct scsi_host_template pata_s3c_sht = {
    418	ATA_PIO_SHT(DRV_NAME),
    419};
    420
    421static struct ata_port_operations pata_s3c_port_ops = {
    422	.inherits		= &ata_sff_port_ops,
    423	.sff_check_status	= pata_s3c_check_status,
    424	.sff_check_altstatus    = pata_s3c_check_altstatus,
    425	.sff_tf_load		= pata_s3c_tf_load,
    426	.sff_tf_read		= pata_s3c_tf_read,
    427	.sff_data_xfer		= pata_s3c_data_xfer,
    428	.sff_exec_command	= pata_s3c_exec_command,
    429	.sff_dev_select         = pata_s3c_dev_select,
    430	.sff_set_devctl         = pata_s3c_set_devctl,
    431	.softreset		= pata_s3c_softreset,
    432	.set_piomode		= pata_s3c_set_piomode,
    433};
    434
    435static struct ata_port_operations pata_s5p_port_ops = {
    436	.inherits		= &ata_sff_port_ops,
    437	.set_piomode		= pata_s3c_set_piomode,
    438};
    439
    440static void pata_s3c_enable(void __iomem *s3c_ide_regbase, bool state)
    441{
    442	u32 temp = readl(s3c_ide_regbase + S3C_ATA_CTRL);
    443	temp = state ? (temp | 1) : (temp & ~1);
    444	writel(temp, s3c_ide_regbase + S3C_ATA_CTRL);
    445}
    446
    447static irqreturn_t pata_s3c_irq(int irq, void *dev_instance)
    448{
    449	struct ata_host *host = dev_instance;
    450	struct s3c_ide_info *info = host->private_data;
    451	u32 reg;
    452
    453	reg = readl(info->ide_addr + S3C_ATA_IRQ);
    454	writel(reg, info->ide_addr + S3C_ATA_IRQ);
    455
    456	return ata_sff_interrupt(irq, dev_instance);
    457}
    458
    459static void pata_s3c_hwinit(struct s3c_ide_info *info,
    460				struct s3c_ide_platdata *pdata)
    461{
    462	switch (info->cpu_type) {
    463	case TYPE_S3C64XX:
    464		/* Configure as big endian */
    465		pata_s3c_cfg_mode(info->sfr_addr);
    466		pata_s3c_set_endian(info->ide_addr, 1);
    467		pata_s3c_enable(info->ide_addr, true);
    468		msleep(100);
    469
    470		/* Remove IRQ Status */
    471		writel(0x1f, info->ide_addr + S3C_ATA_IRQ);
    472		writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK);
    473		break;
    474
    475	case TYPE_S5PV210:
    476		/* Configure as little endian */
    477		pata_s3c_set_endian(info->ide_addr, 0);
    478		pata_s3c_enable(info->ide_addr, true);
    479		msleep(100);
    480
    481		/* Remove IRQ Status */
    482		writel(0x3f, info->ide_addr + S3C_ATA_IRQ);
    483		writel(0x3f, info->ide_addr + S3C_ATA_IRQ_MSK);
    484		break;
    485
    486	default:
    487		BUG();
    488	}
    489}
    490
    491static int __init pata_s3c_probe(struct platform_device *pdev)
    492{
    493	struct s3c_ide_platdata *pdata = dev_get_platdata(&pdev->dev);
    494	struct device *dev = &pdev->dev;
    495	struct s3c_ide_info *info;
    496	struct resource *res;
    497	struct ata_port *ap;
    498	struct ata_host *host;
    499	enum s3c_cpu_type cpu_type;
    500	int ret;
    501
    502	cpu_type = platform_get_device_id(pdev)->driver_data;
    503
    504	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
    505	if (!info)
    506		return -ENOMEM;
    507
    508	info->irq = platform_get_irq(pdev, 0);
    509
    510	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    511
    512	info->ide_addr = devm_ioremap_resource(dev, res);
    513	if (IS_ERR(info->ide_addr))
    514		return PTR_ERR(info->ide_addr);
    515
    516	info->clk = devm_clk_get(&pdev->dev, "cfcon");
    517	if (IS_ERR(info->clk)) {
    518		dev_err(dev, "failed to get access to cf controller clock\n");
    519		ret = PTR_ERR(info->clk);
    520		info->clk = NULL;
    521		return ret;
    522	}
    523
    524	clk_enable(info->clk);
    525
    526	/* init ata host */
    527	host = ata_host_alloc(dev, 1);
    528	if (!host) {
    529		dev_err(dev, "failed to allocate ide host\n");
    530		ret = -ENOMEM;
    531		goto stop_clk;
    532	}
    533
    534	ap = host->ports[0];
    535	ap->pio_mask = ATA_PIO4;
    536
    537	if (cpu_type == TYPE_S3C64XX) {
    538		ap->ops = &pata_s3c_port_ops;
    539		info->sfr_addr = info->ide_addr + 0x1800;
    540		info->ide_addr += 0x1900;
    541		info->fifo_status_reg = 0x94;
    542	} else {
    543		ap->ops = &pata_s5p_port_ops;
    544		info->fifo_status_reg = 0x84;
    545	}
    546
    547	info->cpu_type = cpu_type;
    548
    549	if (info->irq <= 0) {
    550		ap->flags |= ATA_FLAG_PIO_POLLING;
    551		info->irq = 0;
    552		ata_port_desc(ap, "no IRQ, using PIO polling\n");
    553	}
    554
    555	ap->ioaddr.cmd_addr =  info->ide_addr + S3C_ATA_CMD;
    556	ap->ioaddr.data_addr = info->ide_addr + S3C_ATA_PIO_DTR;
    557	ap->ioaddr.error_addr = info->ide_addr + S3C_ATA_PIO_FED;
    558	ap->ioaddr.feature_addr = info->ide_addr + S3C_ATA_PIO_FED;
    559	ap->ioaddr.nsect_addr = info->ide_addr + S3C_ATA_PIO_SCR;
    560	ap->ioaddr.lbal_addr = info->ide_addr + S3C_ATA_PIO_LLR;
    561	ap->ioaddr.lbam_addr = info->ide_addr + S3C_ATA_PIO_LMR;
    562	ap->ioaddr.lbah_addr = info->ide_addr + S3C_ATA_PIO_LHR;
    563	ap->ioaddr.device_addr = info->ide_addr + S3C_ATA_PIO_DVR;
    564	ap->ioaddr.status_addr = info->ide_addr + S3C_ATA_PIO_CSD;
    565	ap->ioaddr.command_addr = info->ide_addr + S3C_ATA_PIO_CSD;
    566	ap->ioaddr.altstatus_addr = info->ide_addr + S3C_ATA_PIO_DAD;
    567	ap->ioaddr.ctl_addr = info->ide_addr + S3C_ATA_PIO_DAD;
    568
    569	ata_port_desc(ap, "mmio cmd 0x%llx ",
    570			(unsigned long long)res->start);
    571
    572	host->private_data = info;
    573
    574	if (pdata && pdata->setup_gpio)
    575		pdata->setup_gpio();
    576
    577	/* Set endianness and enable the interface */
    578	pata_s3c_hwinit(info, pdata);
    579
    580	ret = ata_host_activate(host, info->irq,
    581				info->irq ? pata_s3c_irq : NULL,
    582				0, &pata_s3c_sht);
    583	if (ret)
    584		goto stop_clk;
    585
    586	return 0;
    587
    588stop_clk:
    589	clk_disable(info->clk);
    590	return ret;
    591}
    592
    593static int __exit pata_s3c_remove(struct platform_device *pdev)
    594{
    595	struct ata_host *host = platform_get_drvdata(pdev);
    596	struct s3c_ide_info *info = host->private_data;
    597
    598	ata_host_detach(host);
    599
    600	clk_disable(info->clk);
    601
    602	return 0;
    603}
    604
    605#ifdef CONFIG_PM_SLEEP
    606static int pata_s3c_suspend(struct device *dev)
    607{
    608	struct ata_host *host = dev_get_drvdata(dev);
    609
    610	ata_host_suspend(host, PMSG_SUSPEND);
    611	return 0;
    612}
    613
    614static int pata_s3c_resume(struct device *dev)
    615{
    616	struct ata_host *host = dev_get_drvdata(dev);
    617	struct s3c_ide_platdata *pdata = dev_get_platdata(dev);
    618	struct s3c_ide_info *info = host->private_data;
    619
    620	pata_s3c_hwinit(info, pdata);
    621	ata_host_resume(host);
    622
    623	return 0;
    624}
    625
    626static const struct dev_pm_ops pata_s3c_pm_ops = {
    627	.suspend	= pata_s3c_suspend,
    628	.resume		= pata_s3c_resume,
    629};
    630#endif
    631
    632/* driver device registration */
    633static const struct platform_device_id pata_s3c_driver_ids[] = {
    634	{
    635		.name		= "s3c64xx-pata",
    636		.driver_data	= TYPE_S3C64XX,
    637	}, {
    638		.name		= "s5pv210-pata",
    639		.driver_data	= TYPE_S5PV210,
    640	},
    641	{ }
    642};
    643
    644MODULE_DEVICE_TABLE(platform, pata_s3c_driver_ids);
    645
    646static struct platform_driver pata_s3c_driver = {
    647	.remove		= __exit_p(pata_s3c_remove),
    648	.id_table	= pata_s3c_driver_ids,
    649	.driver		= {
    650		.name	= DRV_NAME,
    651#ifdef CONFIG_PM_SLEEP
    652		.pm	= &pata_s3c_pm_ops,
    653#endif
    654	},
    655};
    656
    657module_platform_driver_probe(pata_s3c_driver, pata_s3c_probe);
    658
    659MODULE_AUTHOR("Abhilash Kesavan, <a.kesavan@samsung.com>");
    660MODULE_DESCRIPTION("low-level driver for Samsung PATA controller");
    661MODULE_LICENSE("GPL");
    662MODULE_VERSION(DRV_VERSION);