From: Sergei Shtylyov <sshtylyov@mvista.com>
To: Kukjin Kim <kgene.kim@samsung.com>
Cc: linux-samsung-soc@vger.kernel.org, linux-ide@vger.kernel.org,
ben-linux@fluff.org, Abhilash Kesavan <a.kesavan@samsung.com>,
jgarzik@pobox.com, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v4] libata: pata_samsung_cf: Add Samsung PATA controller driver
Date: Mon, 28 Jun 2010 14:12:06 +0400 [thread overview]
Message-ID: <4C287576.6050506@ru.mvista.com> (raw)
In-Reply-To: <1276499263-12217-1-git-send-email-kgene.kim@samsung.com>
Hello.
Kukjin Kim wrote:
> From: Abhilash Kesavan <a.kesavan@samsung.com>
> Adds support for the Samsung PATA controller. This driver is based on the
> Libata subsystem and references the earlier patches sent for IDE subsystem.
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
[...]
> diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
> new file mode 100644
> index 0000000..aeb2825
> --- /dev/null
> +++ b/drivers/ata/pata_samsung_cf.c
> @@ -0,0 +1,735 @@
[...]
> +static unsigned long
> +pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata)
> +{
> + int t1;
> + int t2;
> + int t2i;
> + ulong piotime;
> +
> + t1 = ata->setup;
> + t2 = ata->act8b;
> + t2i = ata->rec8b;
Could be initializers...
[...]
> +/*
> + * pata_s3c_data_xfer - Transfer data by PIO
> + */
> +unsigned int pata_s3c_data_xfer(struct ata_device *dev, unsigned char *buf,
> + unsigned int buflen, int rw)
> +{
> + struct ata_port *ap = dev->link->ap;
> + struct s3c_ide_info *info = ap->host->private_data;
> + void __iomem *data_addr = ap->ioaddr.data_addr;
> + unsigned int words = buflen >> 1, i;
> + u16 *data_ptr = (u16 *)buf;
> +
> + /* Requires wait same as in ata_inb/ata_outb */
> + if (rw == READ)
> + for (i = 0; i < words; i++, data_ptr++) {
> + wait_for_host_ready(info);
> + (void) readw(data_addr);
> + wait_for_host_ready(info);
> + *data_ptr = readw(info->ide_addr
> + + S3C_ATA_PIO_RDATA);
> + }
> + else
> + for (i = 0; i < words; i++, data_ptr++) {
> + wait_for_host_ready(info);
> + writew(*data_ptr, data_addr);
> + }
> +
> + if (buflen & 0x01) {
> + dev_err(ap->dev, "unexpected trailing data\n");
> + return -EINVAL;
This method should return number of bytes consumed, never error...
> + }
> +
> + return words << 1;
> +}
[...]
> +/*
> + * pata_s3c_devchk - PATA device presence detection
> + */
> +static unsigned int pata_s3c_devchk(struct ata_port *ap,
> + unsigned int device)
> +{
> + struct ata_ioports *ioaddr = &ap->ioaddr;
> + u8 nsect, lbal;
> +
> + ap->ops->sff_dev_select(ap, device);
Can call pata_s3c_dev_select() directly...
> +/*
> + * pata_s3c_wait_after_reset - wait for devices to become ready after reset
> + */
> +static int pata_s3c_wait_after_reset(struct ata_link *link,
> + unsigned int devmask, unsigned long deadline)
> +{
> + struct ata_port *ap = link->ap;
> + struct ata_ioports *ioaddr = &ap->ioaddr;
> + unsigned int dev0 = devmask & (1 << 0);
> + unsigned int dev1 = devmask & (1 << 1);
> + int rc, ret = 0;
> +
> + msleep(ATA_WAIT_AFTER_RESET);
> +
> + /* always check readiness of the master device */
> + rc = ata_sff_wait_ready(link, deadline);
> + if (rc)
> + return rc;
> +
> + /* if device 1 was found in ata_devchk, wait for register
> + * access briefly, then wait for BSY to clear.
> + */
> + if (dev1) {
> + int i;
> +
> + ap->ops->sff_dev_select(ap, 1);
Ditto.
> +
> + for (i = 0; i < 2; i++) {
> + u8 nsect, lbal;
> +
> + nsect = ata_inb(ap->host, ioaddr->nsect_addr);
> + lbal = ata_inb(ap->host, ioaddr->lbal_addr);
> + if ((nsect == 1) && (lbal == 1))
> + break;
> + msleep(50); /* give drive a breather */
> + }
> +
> + rc = ata_sff_wait_ready(link, deadline);
> + if (rc) {
> + if (rc != -ENODEV)
> + return rc;
> + ret = rc;
> + }
> + }
> +
Should have copied the original commant here, cause I dount that this
drive selection trickery is indeed necessary...
> + ap->ops->sff_dev_select(ap, 0);
> + if (dev1)
> + ap->ops->sff_dev_select(ap, 1);
> + if (dev0)
> + ap->ops->sff_dev_select(ap, 0);
Ditto.
> +/*
> + * pata_s3c_softreset - reset host port via ATA SRST
> + */
> +static int pata_s3c_softreset(struct ata_link *link, unsigned int *classes,
> + unsigned long deadline)
> +{
> + struct ata_port *ap = link->ap;
> + unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
I don't see where you set this flag, hence the check seems useless.
> + unsigned int devmask = 0;
> + int rc;
> + u8 err;
> +
> + /* determine if device 0/1 are present */
> + if (pata_s3c_devchk(ap, 0))
> + devmask |= (1 << 0);
> + if (slave_possible && pata_s3c_devchk(ap, 1))
> + devmask |= (1 << 1);
> +
> + /* select device 0 again */
> + ap->ops->sff_dev_select(ap, 0);
Can call pata_s3c_dev_select() directly...
> +
> + /* issue bus reset */
> + rc = pata_s3c_bus_softreset(ap, devmask, deadline);
> + /* if link is occupied, -ENODEV too is an error */
> + if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
sata_scr_valid() doesn't apply to your PATA driver, no need to call it.
> +static void pata_s3c_hwinit(struct s3c_ide_info *info,
> + struct s3c_ide_platdata *pdata)
> +{
> + switch (info->cpu_type) {
> + case TYPE_S3C64XX:
> + /* Configure as big endian */
> + pata_s3c_cfg_mode(info->sfr_addr);
> + pata_s3c_set_endian(info->ide_addr, 1);
> + pata_s3c_enable(info->ide_addr, true);
> + msleep(100);
> +
> + /* Remove IRQ Status */
> + writel(0x1f, info->ide_addr + S3C_ATA_IRQ);
> + writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK);
> + break;
Mis-indented: one more tab needed.
> +
> + case TYPE_S5PC100:
> + pata_s3c_cfg_mode(info->sfr_addr);
There should be a comment like /* FALLTHRU */ if *break* is omitted.
> + case TYPE_S5PV210:
> + /* Configure as little endian */
> + pata_s3c_set_endian(info->ide_addr, 0);
> + pata_s3c_enable(info->ide_addr, true);
> + msleep(100);
> +
> + /* Remove IRQ Status */
> + writel(0x3f, info->ide_addr + S3C_ATA_IRQ);
> + writel(0x3f, info->ide_addr + S3C_ATA_IRQ_MSK);
> + break;
Mis-indented.
> +static int __devinit pata_s3c_probe(struct platform_device *pdev)
Is this device really hot-pluggable? Shouldn't this be '__init' instead?
> +{
> + struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
> + struct device *dev = &pdev->dev;
> + struct s3c_ide_info *info;
> + struct resource *res;
> + struct ata_port *ap;
> + struct ata_host *host;
> + enum s3c_cpu_type cpu_type;
> + int ret;
> +
> + cpu_type = platform_get_device_id(pdev)->driver_data;
> +
> + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
> + if (!info) {
> + dev_err(dev, "failed to allocate memory for device data\n");
> + return -ENOMEM;
> + }
> +
> + info->irq = platform_get_irq(pdev, 0);
> + if (info->irq < 0) {
> + dev_err(dev, "could not obtain irq number\n");
You driver permits working without IRQ -- why require an IRQ resource even
if there's no IRQ?
[...]
> + if (!info->irq) {
Should be (info->irq <= 0) instead, I think, with the above check removed.
> + ap->flags |= ATA_FLAG_PIO_POLLING;
> + ata_port_desc(ap, "no IRQ, using PIO polling\n");
> + }
> +
[...]
> +static struct platform_driver pata_s3c_driver = {
> + .probe = pata_s3c_probe,
If this function will be '__init', this needs to be removed.
[...]
> +static int __init pata_s3c_init(void)
> +{
> + return platform_driver_register(&pata_s3c_driver);
I'd coinsider platform_driver_probe() -- this device doesn't seem to be
hot-pluggable...
MBR, Sergei
WARNING: multiple messages have this Message-ID (diff)
From: sshtylyov@mvista.com (Sergei Shtylyov)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4] libata: pata_samsung_cf: Add Samsung PATA controller driver
Date: Mon, 28 Jun 2010 14:12:06 +0400 [thread overview]
Message-ID: <4C287576.6050506@ru.mvista.com> (raw)
In-Reply-To: <1276499263-12217-1-git-send-email-kgene.kim@samsung.com>
Hello.
Kukjin Kim wrote:
> From: Abhilash Kesavan <a.kesavan@samsung.com>
> Adds support for the Samsung PATA controller. This driver is based on the
> Libata subsystem and references the earlier patches sent for IDE subsystem.
> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
[...]
> diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
> new file mode 100644
> index 0000000..aeb2825
> --- /dev/null
> +++ b/drivers/ata/pata_samsung_cf.c
> @@ -0,0 +1,735 @@
[...]
> +static unsigned long
> +pata_s3c_setup_timing(struct s3c_ide_info *info, const struct ata_timing *ata)
> +{
> + int t1;
> + int t2;
> + int t2i;
> + ulong piotime;
> +
> + t1 = ata->setup;
> + t2 = ata->act8b;
> + t2i = ata->rec8b;
Could be initializers...
[...]
> +/*
> + * pata_s3c_data_xfer - Transfer data by PIO
> + */
> +unsigned int pata_s3c_data_xfer(struct ata_device *dev, unsigned char *buf,
> + unsigned int buflen, int rw)
> +{
> + struct ata_port *ap = dev->link->ap;
> + struct s3c_ide_info *info = ap->host->private_data;
> + void __iomem *data_addr = ap->ioaddr.data_addr;
> + unsigned int words = buflen >> 1, i;
> + u16 *data_ptr = (u16 *)buf;
> +
> + /* Requires wait same as in ata_inb/ata_outb */
> + if (rw == READ)
> + for (i = 0; i < words; i++, data_ptr++) {
> + wait_for_host_ready(info);
> + (void) readw(data_addr);
> + wait_for_host_ready(info);
> + *data_ptr = readw(info->ide_addr
> + + S3C_ATA_PIO_RDATA);
> + }
> + else
> + for (i = 0; i < words; i++, data_ptr++) {
> + wait_for_host_ready(info);
> + writew(*data_ptr, data_addr);
> + }
> +
> + if (buflen & 0x01) {
> + dev_err(ap->dev, "unexpected trailing data\n");
> + return -EINVAL;
This method should return number of bytes consumed, never error...
> + }
> +
> + return words << 1;
> +}
[...]
> +/*
> + * pata_s3c_devchk - PATA device presence detection
> + */
> +static unsigned int pata_s3c_devchk(struct ata_port *ap,
> + unsigned int device)
> +{
> + struct ata_ioports *ioaddr = &ap->ioaddr;
> + u8 nsect, lbal;
> +
> + ap->ops->sff_dev_select(ap, device);
Can call pata_s3c_dev_select() directly...
> +/*
> + * pata_s3c_wait_after_reset - wait for devices to become ready after reset
> + */
> +static int pata_s3c_wait_after_reset(struct ata_link *link,
> + unsigned int devmask, unsigned long deadline)
> +{
> + struct ata_port *ap = link->ap;
> + struct ata_ioports *ioaddr = &ap->ioaddr;
> + unsigned int dev0 = devmask & (1 << 0);
> + unsigned int dev1 = devmask & (1 << 1);
> + int rc, ret = 0;
> +
> + msleep(ATA_WAIT_AFTER_RESET);
> +
> + /* always check readiness of the master device */
> + rc = ata_sff_wait_ready(link, deadline);
> + if (rc)
> + return rc;
> +
> + /* if device 1 was found in ata_devchk, wait for register
> + * access briefly, then wait for BSY to clear.
> + */
> + if (dev1) {
> + int i;
> +
> + ap->ops->sff_dev_select(ap, 1);
Ditto.
> +
> + for (i = 0; i < 2; i++) {
> + u8 nsect, lbal;
> +
> + nsect = ata_inb(ap->host, ioaddr->nsect_addr);
> + lbal = ata_inb(ap->host, ioaddr->lbal_addr);
> + if ((nsect == 1) && (lbal == 1))
> + break;
> + msleep(50); /* give drive a breather */
> + }
> +
> + rc = ata_sff_wait_ready(link, deadline);
> + if (rc) {
> + if (rc != -ENODEV)
> + return rc;
> + ret = rc;
> + }
> + }
> +
Should have copied the original commant here, cause I dount that this
drive selection trickery is indeed necessary...
> + ap->ops->sff_dev_select(ap, 0);
> + if (dev1)
> + ap->ops->sff_dev_select(ap, 1);
> + if (dev0)
> + ap->ops->sff_dev_select(ap, 0);
Ditto.
> +/*
> + * pata_s3c_softreset - reset host port via ATA SRST
> + */
> +static int pata_s3c_softreset(struct ata_link *link, unsigned int *classes,
> + unsigned long deadline)
> +{
> + struct ata_port *ap = link->ap;
> + unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
I don't see where you set this flag, hence the check seems useless.
> + unsigned int devmask = 0;
> + int rc;
> + u8 err;
> +
> + /* determine if device 0/1 are present */
> + if (pata_s3c_devchk(ap, 0))
> + devmask |= (1 << 0);
> + if (slave_possible && pata_s3c_devchk(ap, 1))
> + devmask |= (1 << 1);
> +
> + /* select device 0 again */
> + ap->ops->sff_dev_select(ap, 0);
Can call pata_s3c_dev_select() directly...
> +
> + /* issue bus reset */
> + rc = pata_s3c_bus_softreset(ap, devmask, deadline);
> + /* if link is occupied, -ENODEV too is an error */
> + if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
sata_scr_valid() doesn't apply to your PATA driver, no need to call it.
> +static void pata_s3c_hwinit(struct s3c_ide_info *info,
> + struct s3c_ide_platdata *pdata)
> +{
> + switch (info->cpu_type) {
> + case TYPE_S3C64XX:
> + /* Configure as big endian */
> + pata_s3c_cfg_mode(info->sfr_addr);
> + pata_s3c_set_endian(info->ide_addr, 1);
> + pata_s3c_enable(info->ide_addr, true);
> + msleep(100);
> +
> + /* Remove IRQ Status */
> + writel(0x1f, info->ide_addr + S3C_ATA_IRQ);
> + writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK);
> + break;
Mis-indented: one more tab needed.
> +
> + case TYPE_S5PC100:
> + pata_s3c_cfg_mode(info->sfr_addr);
There should be a comment like /* FALLTHRU */ if *break* is omitted.
> + case TYPE_S5PV210:
> + /* Configure as little endian */
> + pata_s3c_set_endian(info->ide_addr, 0);
> + pata_s3c_enable(info->ide_addr, true);
> + msleep(100);
> +
> + /* Remove IRQ Status */
> + writel(0x3f, info->ide_addr + S3C_ATA_IRQ);
> + writel(0x3f, info->ide_addr + S3C_ATA_IRQ_MSK);
> + break;
Mis-indented.
> +static int __devinit pata_s3c_probe(struct platform_device *pdev)
Is this device really hot-pluggable? Shouldn't this be '__init' instead?
> +{
> + struct s3c_ide_platdata *pdata = pdev->dev.platform_data;
> + struct device *dev = &pdev->dev;
> + struct s3c_ide_info *info;
> + struct resource *res;
> + struct ata_port *ap;
> + struct ata_host *host;
> + enum s3c_cpu_type cpu_type;
> + int ret;
> +
> + cpu_type = platform_get_device_id(pdev)->driver_data;
> +
> + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
> + if (!info) {
> + dev_err(dev, "failed to allocate memory for device data\n");
> + return -ENOMEM;
> + }
> +
> + info->irq = platform_get_irq(pdev, 0);
> + if (info->irq < 0) {
> + dev_err(dev, "could not obtain irq number\n");
You driver permits working without IRQ -- why require an IRQ resource even
if there's no IRQ?
[...]
> + if (!info->irq) {
Should be (info->irq <= 0) instead, I think, with the above check removed.
> + ap->flags |= ATA_FLAG_PIO_POLLING;
> + ata_port_desc(ap, "no IRQ, using PIO polling\n");
> + }
> +
[...]
> +static struct platform_driver pata_s3c_driver = {
> + .probe = pata_s3c_probe,
If this function will be '__init', this needs to be removed.
[...]
> +static int __init pata_s3c_init(void)
> +{
> + return platform_driver_register(&pata_s3c_driver);
I'd coinsider platform_driver_probe() -- this device doesn't seem to be
hot-pluggable...
MBR, Sergei
next prev parent reply other threads:[~2010-06-28 10:12 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-14 7:07 [PATCH v4] libata: pata_samsung_cf: Add Samsung PATA controller driver Kukjin Kim
2010-06-14 7:07 ` Kukjin Kim
2010-06-22 1:45 ` Kukjin Kim
2010-06-22 1:45 ` Kukjin Kim
2010-06-23 20:36 ` Jeff Garzik
2010-06-23 20:36 ` Jeff Garzik
2010-06-25 3:38 ` Kukjin Kim
2010-06-25 3:38 ` Kukjin Kim
2010-06-25 4:18 ` Marek Vasut
2010-06-25 4:18 ` Marek Vasut
2010-06-29 11:32 ` Kukjin Kim
2010-06-29 11:32 ` Kukjin Kim
2010-06-26 19:33 ` Russell King - ARM Linux
2010-06-26 19:33 ` Russell King - ARM Linux
2010-06-28 10:09 ` Sergei Shtylyov
2010-06-28 10:09 ` Sergei Shtylyov
2010-06-29 8:28 ` Kukjin Kim
2010-06-29 8:28 ` Kukjin Kim
2010-06-29 8:39 ` Kukjin Kim
2010-06-29 8:39 ` Kukjin Kim
2010-06-28 10:12 ` Sergei Shtylyov [this message]
2010-06-28 10:12 ` Sergei Shtylyov
2010-06-29 8:25 ` Kukjin Kim
2010-06-29 8:25 ` Kukjin Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C287576.6050506@ru.mvista.com \
--to=sshtylyov@mvista.com \
--cc=a.kesavan@samsung.com \
--cc=ben-linux@fluff.org \
--cc=jgarzik@pobox.com \
--cc=kgene.kim@samsung.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.