All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergei Shtylyov <sshtylyov@mvista.com>
To: Kukjin Kim <kgene.kim@samsung.com>
Cc: linux-ide@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, ben-linux@fluff.org,
	jgarzik@pobox.com, Abhilash Kesavan <a.kesavan@samsung.com>
Subject: Re: [PATCH v3] libata: pata_samsung_cf: Add Samsung PATA controller driver
Date: Thu, 10 Jun 2010 14:43:34 +0400	[thread overview]
Message-ID: <4C10C1D6.8080708@ru.mvista.com> (raw)
In-Reply-To: <1276156241-28804-1-git-send-email-kgene.kim@samsung.com>

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..fef5515
> --- /dev/null
> +++ b/drivers/ata/pata_samsung_cf.c
> @@ -0,0 +1,608 @@
> +/* linux/drivers/ata/pata_samsung_cf.c

    File names in the heading comment are discouraged.

[...]

> +static unsigned long
> +pata_s3c_setup_timing(struct s3c_ide_info *info, struct ata_device *adev)
> +{
> +	const struct ata_timing *timing;
> +	int cycle_time;
> +	int t1;
> +	int t2;
> +	int t2i;
> +	ulong piotime;
> +
> +	cycle_time = (int)(1000000000UL / clk_get_rate(info->clk));
> +
> +	timing = ata_timing_find_mode(adev->pio_mode);
> +	t1	= (timing->setup / cycle_time) & 0xf;
> +	t2	= (timing->act8b / cycle_time) & 0xff;
> +	t2i	= (timing->rec8b / cycle_time) & 0xff;

    Why are you still not using ata_timing_compute()?

> +
> +	piotime = (t2i << 12) | (t2 << 4) | t1;
> +
> +	return piotime;
> +}
> +
> +static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev)
> +{
> +	int mode = adev->pio_mode - XFER_PIO_0;
> +	struct s3c_ide_info *info = ap->host->private_data;
> +	ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG);
> +	ulong piotime;
> +
> +	/* Calculates timing parameters for PIO mode */
> +	piotime = pata_s3c_setup_timing(info, adev);

    In fact, for 8-bit (command) timing you should program the slowest mode of 
the two drives. However, with CF, you probably only have only one drive per 
channel...

> +
> +	/* Enables IORDY if mode requires it */
> +	if (ata_pio_need_iordy(adev))
> +		ata_cfg |= S3C_ATA_CFG_IORDYEN;
> +	else
> +		ata_cfg &= ~S3C_ATA_CFG_IORDYEN;
> +
> +	/* Host controller supports upto PIO4 only */
> +	if (mode >= 0 && mode <= 4) {

    No need to check -- you won't be passed a mode not specified by your pio_mask.

> +		writel(ata_cfg, info->ide_addr + S3C_ATA_CFG);
> +		writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME);
> +	}
> +}

[...]

> +/*
> + * 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;
> +
> +	if (rw == READ)
> +		for (i = 0; i < words; i++, data_ptr++) {
> +			wait_for_host_ready(info);
> +			*data_ptr = readw(data_addr);

    Why not just ignore the result?

> +			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);
> +			writel(*data_ptr, data_addr);
> +		}
> +
> +	return words << 1;
> +}

[...]

> +static struct ata_port_operations pata_s3c_port_ops = {
> +	.inherits		= &ata_sff_port_ops,
> +	.sff_check_status	= pata_s3c_check_status,
> +	.sff_check_altstatus    = pata_s3c_check_altstatus,
> +	.sff_tf_load		= pata_s3c_tf_load,
> +	.sff_tf_read		= pata_s3c_tf_read,
> +	.sff_data_xfer		= pata_s3c_data_xfer,
> +	.sff_exec_command	= pata_s3c_exec_command,
> +	.sff_dev_select         = pata_s3c_dev_select,
> +	.sff_set_devctl         = pata_s3c_set_devctl,

    I forgot: you also need to override the softreset() method as it accesses 
several taskfile registers and ioread8()/iowrite8() won't suffice -- Jeff was 
too quick to ack the patch. See ata_bus_softreset(), ata_devchk(), and 
ata_sff_wait_after_reset() for the accesses I'm talking about...

[...]

> +static int __devinit pata_s3c_probe(struct platform_device *pdev)
> +{
> +	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");
> +		ret = -EINVAL;
> +		goto release_device_mem;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res == NULL) {
> +		dev_err(dev, "failed to get mem resource\n");
> +		ret = -EINVAL;
> +		goto release_device_mem;
> +	}
> +
> +	if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {

    Probably should call devm_request_mem_region() if you're using 
devm_ioremap()...

> +		dev_err(dev, "error requesting register region\n");
> +		return -EBUSY;
> +	}
> +
> +	info->ide_addr = devm_ioremap(dev, res->start, resource_size(res));
> +	if (!info->ide_addr) {
> +		dev_err(dev, "failed to map IO base address\n");
> +		ret = -ENOMEM;
> +		goto release_mem;
> +	}
> +
> +	info->clk = clk_get(&pdev->dev, "cfcon");
> +	if (IS_ERR(info->clk)) {
> +		dev_err(dev, "failed to get access to cf controller clock\n");
> +		ret = PTR_ERR(info->clk);
> +		info->clk = NULL;

    No 'goto' here?

[...]

> +stop_clk:
> +	clk_disable(info->clk);

    Where is clk_put() call?

> +release_mem:
> +	release_mem_region(res->start, resource_size(res));
> +release_device_mem:
> +	kfree(info);

    Doesn't using devm_kzalloc() guarantee that the memory will be freed up 
automatically?

> +return ret;

    Wrong indentation.

> +static struct platform_driver pata_s3c_driver = {
> +	.probe		= pata_s3c_probe,
> 
> 

    2 empty lines -- broken patch?

> +	.remove		= __devexit_p(pata_s3c_remove),
> +	.id_table	= pata_s3c_driver_ids,
> +	.driver		= {
> +		.name	= DRV_NAME,
> +		.owner	= THIS_MODULE,
> +#ifdef CONFIG_PM
> +		.pm	= &pata_s3c_pm_ops,
> +#endif
> +	},
> +};

[...]

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 v3] libata: pata_samsung_cf: Add Samsung PATA controller driver
Date: Thu, 10 Jun 2010 14:43:34 +0400	[thread overview]
Message-ID: <4C10C1D6.8080708@ru.mvista.com> (raw)
In-Reply-To: <1276156241-28804-1-git-send-email-kgene.kim@samsung.com>

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..fef5515
> --- /dev/null
> +++ b/drivers/ata/pata_samsung_cf.c
> @@ -0,0 +1,608 @@
> +/* linux/drivers/ata/pata_samsung_cf.c

    File names in the heading comment are discouraged.

[...]

> +static unsigned long
> +pata_s3c_setup_timing(struct s3c_ide_info *info, struct ata_device *adev)
> +{
> +	const struct ata_timing *timing;
> +	int cycle_time;
> +	int t1;
> +	int t2;
> +	int t2i;
> +	ulong piotime;
> +
> +	cycle_time = (int)(1000000000UL / clk_get_rate(info->clk));
> +
> +	timing = ata_timing_find_mode(adev->pio_mode);
> +	t1	= (timing->setup / cycle_time) & 0xf;
> +	t2	= (timing->act8b / cycle_time) & 0xff;
> +	t2i	= (timing->rec8b / cycle_time) & 0xff;

    Why are you still not using ata_timing_compute()?

> +
> +	piotime = (t2i << 12) | (t2 << 4) | t1;
> +
> +	return piotime;
> +}
> +
> +static void pata_s3c_set_piomode(struct ata_port *ap, struct ata_device *adev)
> +{
> +	int mode = adev->pio_mode - XFER_PIO_0;
> +	struct s3c_ide_info *info = ap->host->private_data;
> +	ulong ata_cfg = readl(info->ide_addr + S3C_ATA_CFG);
> +	ulong piotime;
> +
> +	/* Calculates timing parameters for PIO mode */
> +	piotime = pata_s3c_setup_timing(info, adev);

    In fact, for 8-bit (command) timing you should program the slowest mode of 
the two drives. However, with CF, you probably only have only one drive per 
channel...

> +
> +	/* Enables IORDY if mode requires it */
> +	if (ata_pio_need_iordy(adev))
> +		ata_cfg |= S3C_ATA_CFG_IORDYEN;
> +	else
> +		ata_cfg &= ~S3C_ATA_CFG_IORDYEN;
> +
> +	/* Host controller supports upto PIO4 only */
> +	if (mode >= 0 && mode <= 4) {

    No need to check -- you won't be passed a mode not specified by your pio_mask.

> +		writel(ata_cfg, info->ide_addr + S3C_ATA_CFG);
> +		writel(piotime, info->ide_addr + S3C_ATA_PIO_TIME);
> +	}
> +}

[...]

> +/*
> + * 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;
> +
> +	if (rw == READ)
> +		for (i = 0; i < words; i++, data_ptr++) {
> +			wait_for_host_ready(info);
> +			*data_ptr = readw(data_addr);

    Why not just ignore the result?

> +			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);
> +			writel(*data_ptr, data_addr);
> +		}
> +
> +	return words << 1;
> +}

[...]

> +static struct ata_port_operations pata_s3c_port_ops = {
> +	.inherits		= &ata_sff_port_ops,
> +	.sff_check_status	= pata_s3c_check_status,
> +	.sff_check_altstatus    = pata_s3c_check_altstatus,
> +	.sff_tf_load		= pata_s3c_tf_load,
> +	.sff_tf_read		= pata_s3c_tf_read,
> +	.sff_data_xfer		= pata_s3c_data_xfer,
> +	.sff_exec_command	= pata_s3c_exec_command,
> +	.sff_dev_select         = pata_s3c_dev_select,
> +	.sff_set_devctl         = pata_s3c_set_devctl,

    I forgot: you also need to override the softreset() method as it accesses 
several taskfile registers and ioread8()/iowrite8() won't suffice -- Jeff was 
too quick to ack the patch. See ata_bus_softreset(), ata_devchk(), and 
ata_sff_wait_after_reset() for the accesses I'm talking about...

[...]

> +static int __devinit pata_s3c_probe(struct platform_device *pdev)
> +{
> +	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");
> +		ret = -EINVAL;
> +		goto release_device_mem;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res == NULL) {
> +		dev_err(dev, "failed to get mem resource\n");
> +		ret = -EINVAL;
> +		goto release_device_mem;
> +	}
> +
> +	if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {

    Probably should call devm_request_mem_region() if you're using 
devm_ioremap()...

> +		dev_err(dev, "error requesting register region\n");
> +		return -EBUSY;
> +	}
> +
> +	info->ide_addr = devm_ioremap(dev, res->start, resource_size(res));
> +	if (!info->ide_addr) {
> +		dev_err(dev, "failed to map IO base address\n");
> +		ret = -ENOMEM;
> +		goto release_mem;
> +	}
> +
> +	info->clk = clk_get(&pdev->dev, "cfcon");
> +	if (IS_ERR(info->clk)) {
> +		dev_err(dev, "failed to get access to cf controller clock\n");
> +		ret = PTR_ERR(info->clk);
> +		info->clk = NULL;

    No 'goto' here?

[...]

> +stop_clk:
> +	clk_disable(info->clk);

    Where is clk_put() call?

> +release_mem:
> +	release_mem_region(res->start, resource_size(res));
> +release_device_mem:
> +	kfree(info);

    Doesn't using devm_kzalloc() guarantee that the memory will be freed up 
automatically?

> +return ret;

    Wrong indentation.

> +static struct platform_driver pata_s3c_driver = {
> +	.probe		= pata_s3c_probe,
> 
> 

    2 empty lines -- broken patch?

> +	.remove		= __devexit_p(pata_s3c_remove),
> +	.id_table	= pata_s3c_driver_ids,
> +	.driver		= {
> +		.name	= DRV_NAME,
> +		.owner	= THIS_MODULE,
> +#ifdef CONFIG_PM
> +		.pm	= &pata_s3c_pm_ops,
> +#endif
> +	},
> +};

[...]

MBR, Sergei

  parent reply	other threads:[~2010-06-10 10:43 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-10  7:50 [PATCH v3] libata: pata_samsung_cf: Add Samsung PATA controller driver Kukjin Kim
2010-06-10  7:50 ` Kukjin Kim
2010-06-10  8:52 ` Jeff Garzik
2010-06-10  8:52   ` Jeff Garzik
2010-06-10  8:56   ` Ben Dooks
2010-06-10  8:56     ` Ben Dooks
2010-06-10  9:37     ` Jeff Garzik
2010-06-10  9:37       ` Jeff Garzik
2010-06-10 10:43 ` Sergei Shtylyov [this message]
2010-06-10 10:43   ` Sergei Shtylyov
2010-06-11  1:57   ` Ben Dooks
2010-06-11  1:57     ` Ben Dooks
2010-06-11  7:29   ` Kukjin Kim
2010-06-11  7:29     ` Kukjin Kim
2010-06-11  9:48     ` Sergei Shtylyov
2010-06-11  9:48       ` Sergei Shtylyov
2010-06-14  6:57       ` Kukjin Kim
2010-06-14  6:57         ` Kukjin Kim
2010-06-11  2:24 ` Ben Dooks
2010-06-11  2:24   ` Ben Dooks
2010-06-11  7:41   ` Kukjin Kim
2010-06-11  7:41     ` 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=4C10C1D6.8080708@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.