diff mbox

[V7,1/5] AHCI Add the AHCI SATA feature on the MX53 platforms

Message ID 1314762635-3923-2-git-send-email-richard.zhu@linaro.org
State Not Applicable
Delegated to: David Miller
Headers show

Commit Message

Richard Zhu Aug. 31, 2011, 3:50 a.m. UTC
Signed-off-by: Richard Zhu <richard.zhu@linaro.org>
Tested-By: Hector Oron Martinez <hector.oron@gmail.com>
---
 arch/arm/mach-mx5/clock-mx51-mx53.c             |   19 ++++
 arch/arm/mach-mx5/devices-imx53.h               |    4 +
 arch/arm/plat-mxc/Makefile                      |    1 +
 arch/arm/plat-mxc/ahci_sata.c                   |  104 +++++++++++++++++++++++
 arch/arm/plat-mxc/devices/Kconfig               |    4 +
 arch/arm/plat-mxc/devices/Makefile              |    1 +
 arch/arm/plat-mxc/devices/platform-ahci-imx.c   |   66 ++++++++++++++
 arch/arm/plat-mxc/include/mach/ahci_sata.h      |   33 +++++++
 arch/arm/plat-mxc/include/mach/devices-common.h |   10 ++
 9 files changed, 242 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-mxc/ahci_sata.c
 create mode 100644 arch/arm/plat-mxc/devices/platform-ahci-imx.c
 create mode 100644 arch/arm/plat-mxc/include/mach/ahci_sata.h

Comments

Arnaud Patard (Rtp) Aug. 31, 2011, 10:03 a.m. UTC | #1
Richard Zhu <richard.zhu@linaro.org> writes:
Hi,


> @@ -1503,6 +1519,9 @@ static struct clk_lookup mx53_lookups[] = {
>  	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
>  	_REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
>  	_REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
> +	_REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk)
> +	_REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk)
> +	_REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk)
>  };
>  
>  static void clk_tree_init(void)

Which tree has been used for this patch ? For instance, on current
imx-features branch of Sascha's tree, there's a pata_imx clock defined
here (see [1]). Should I try to apply it on top of some other branch ?

Arnaud

[1] http://git.pengutronix.de/?p=imx/linux-2.6.git;a=commit;h=03b20b07be130e44faf29f787c66ce5cce5afb2a
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Eric Miao Aug. 31, 2011, 11:04 a.m. UTC | #2
Hi Arnaud,

You can just use Linus tree v3.1-rc4 as the base for this.

Sent from my iPhone

On Aug 31, 2011, at 6:03 PM, Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org> wrote:

> Richard Zhu <richard.zhu@linaro.org> writes:
> Hi,
> 
> 
>> @@ -1503,6 +1519,9 @@ static struct clk_lookup mx53_lookups[] = {
>>    _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
>>    _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
>>    _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
>> +    _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk)
>> +    _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk)
>> +    _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk)
>> };
>> 
>> static void clk_tree_init(void)
> 
> Which tree has been used for this patch ? For instance, on current
> imx-features branch of Sascha's tree, there's a pata_imx clock defined
> here (see [1]). Should I try to apply it on top of some other branch ?
> 
> Arnaud
> 
> [1] http://git.pengutronix.de/?p=imx/linux-2.6.git;a=commit;h=03b20b07be130e44faf29f787c66ce5cce5afb2a
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sascha Hauer Sept. 20, 2011, 8:30 p.m. UTC | #3
On Wed, Aug 31, 2011 at 11:50:31AM +0800, Richard Zhu wrote:
> Signed-off-by: Richard Zhu <richard.zhu@linaro.org>
> Tested-By: Hector Oron Martinez <hector.oron@gmail.com>
> ---
>  arch/arm/mach-mx5/clock-mx51-mx53.c             |   19 ++++
>  arch/arm/mach-mx5/devices-imx53.h               |    4 +
>  arch/arm/plat-mxc/Makefile                      |    1 +
>  arch/arm/plat-mxc/ahci_sata.c                   |  104 +++++++++++++++++++++++
>  arch/arm/plat-mxc/devices/Kconfig               |    4 +
>  arch/arm/plat-mxc/devices/Makefile              |    1 +
>  arch/arm/plat-mxc/devices/platform-ahci-imx.c   |   66 ++++++++++++++
>  arch/arm/plat-mxc/include/mach/ahci_sata.h      |   33 +++++++
>  arch/arm/plat-mxc/include/mach/devices-common.h |   10 ++
>  9 files changed, 242 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/plat-mxc/ahci_sata.c
>  create mode 100644 arch/arm/plat-mxc/devices/platform-ahci-imx.c
>  create mode 100644 arch/arm/plat-mxc/include/mach/ahci_sata.h
> 
> diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
> index 7f20308..e1fadaf 100644
> --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
> +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
> @@ -1397,6 +1397,22 @@ static struct clk esdhc4_mx53_clk = {
>  	.secondary = &esdhc4_ipg_clk,
>  };
>  
> diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
> new file mode 100644
> index 0000000..4f54816
> --- /dev/null
> +++ b/arch/arm/plat-mxc/ahci_sata.c
> @@ -0,0 +1,104 @@
> +/*
> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> + */
> +
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> +
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> +
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/device.h>
> +#include <mach/ahci_sata.h>
> +
> +static struct clk *sata_clk, *sata_ref_clk;

These variables make the driver single instance only.

> +
> +/* AHCI module Initialization, if return 0, initialization is successful. */
> +int sata_init(struct device *dev, void __iomem *addr)

A global function with such a generic name is not a good idea.
Also I wonder how we want to convert this to devicetree when we
implement this as a platform specific hook. It should be done in the
driver.

> +{
> +	u32 tmpdata;
> +	int ret = 0;
> +	struct clk *clk;
> +
> +	sata_clk = clk_get(dev, "ahci");
> +	if (IS_ERR(sata_clk)) {
> +		dev_err(dev, "no sata clock.\n");
> +		return PTR_ERR(sata_clk);
> +	}
> +	ret = clk_enable(sata_clk);
> +	if (ret) {
> +		dev_err(dev, "can't enable sata clock.\n");
> +		goto put_sata_clk;
> +	}
> +
> +	/* FSL IMX AHCI SATA uses the internal usb phy1 clk on loco */

So this function is loco specific or is the comment wrong?

> +	sata_ref_clk = clk_get(dev, "ahci_phy");
> +	if (IS_ERR(sata_ref_clk)) {
> +		dev_err(dev, "no sata ref clock.\n");
> +		ret = PTR_ERR(sata_ref_clk);
> +		goto release_sata_clk;
> +	}
> +	ret = clk_enable(sata_ref_clk);
> +	if (ret) {
> +		dev_err(dev, "can't enable sata ref clock.\n");
> +		goto put_sata_ref_clk;
> +	}
> +
> +	/* Get the AHB clock rate, and configure the TIMER1MS reg later */
> +	clk = clk_get(dev, "ahci_dma");
> +	if (IS_ERR(clk)) {
> +		dev_err(dev, "no dma clock.\n");
> +		ret = PTR_ERR(clk);
> +		goto release_sata_ref_clk;
> +	}
> +	tmpdata = clk_get_rate(clk) / 1000;
> +	clk_put(clk);
> +
> +	writel(tmpdata, addr + HOST_TIMER1MS);
> +
> +	tmpdata = readl(addr + HOST_CAP);
> +	if (!(tmpdata & HOST_CAP_SSS)) {
> +		tmpdata |= HOST_CAP_SSS;
> +		writel(tmpdata, addr + HOST_CAP);
> +	}
> +
> +	if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
> +		writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
> +			addr + HOST_PORTS_IMPL);
> +
> +	return 0;
> +
> +release_sata_ref_clk:
> +	clk_disable(sata_ref_clk);
> +put_sata_ref_clk:
> +	clk_put(sata_ref_clk);
> +release_sata_clk:
> +	clk_disable(sata_clk);
> +put_sata_clk:
> +	clk_put(sata_clk);
> +
> +	return ret;
> +}
> +
> +void sata_exit(struct device *dev)
> +{
> +	clk_disable(sata_ref_clk);
> +	clk_put(sata_ref_clk);
> +
> +	clk_disable(sata_clk);
> +	clk_put(sata_clk);
> +
> +}
> diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
> index bd294ad..f63887b 100644
> --- a/arch/arm/plat-mxc/devices/Kconfig
> +++ b/arch/arm/plat-mxc/devices/Kconfig
> @@ -76,3 +76,7 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
>  
>  config IMX_HAVE_PLATFORM_SPI_IMX
>  	bool
> +
> +config IMX_HAVE_PLATFORM_AHCI
> +	bool
> +	default y if ARCH_MX53
> diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
> index b41bf97..e858ad9 100644
> --- a/arch/arm/plat-mxc/devices/Makefile
> +++ b/arch/arm/plat-mxc/devices/Makefile
> @@ -25,3 +25,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
>  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
>  obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
>  obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
> +obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) +=  platform-ahci-imx.o
> diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
> new file mode 100644
> index 0000000..9e1b460
> --- /dev/null
> +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
> @@ -0,0 +1,66 @@
> +/*
> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> + */
> +
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> +
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> +
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <asm/sizes.h>
> +#include <mach/hardware.h>
> +#include <mach/devices-common.h>
> +#include <mach/ahci_sata.h>
> +
> +#define imx_ahci_imx_data_entry_single(soc, _devid)		\
> +	{								\
> +		.devid = _devid,					\
> +		.iobase = soc ## _SATA_BASE_ADDR,			\
> +		.irq = soc ## _INT_SATA,				\
> +	}
> +
> +#ifdef CONFIG_SOC_IMX53
> +const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
> +	imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
> +#endif
> +
> +static struct ahci_platform_data default_sata_pdata = {
> +	.init = sata_init,
> +	.exit = sata_exit,
> +};
> +
> +struct platform_device *__init imx_add_ahci_imx(
> +		const struct imx_ahci_imx_data *data,
> +		const struct ahci_platform_data *pdata)
> +{
> +	struct resource res[] = {
> +		{
> +			.start = data->iobase,
> +			.end = data->iobase + SZ_4K - 1,
> +			.flags = IORESOURCE_MEM,
> +		}, {
> +			.start = data->irq,
> +			.end = data->irq,
> +			.flags = IORESOURCE_IRQ,
> +		},
> +	};
> +
> +	if (pdata == NULL)
> +		pdata = &default_sata_pdata;
> +
> +	return imx_add_platform_device_dmamask(data->devid, 0,
> +			res, ARRAY_SIZE(res),
> +			pdata, sizeof(*pdata),  DMA_BIT_MASK(32));
> +}
> diff --git a/arch/arm/plat-mxc/include/mach/ahci_sata.h b/arch/arm/plat-mxc/include/mach/ahci_sata.h
> new file mode 100644
> index 0000000..ba297e1
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/ahci_sata.h
> @@ -0,0 +1,33 @@
> +/*
> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> + */
> +
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> +
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> +
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __PLAT_MXC_AHCI_SATA_H__
> +#define __PLAT_MXC_AHCI_SATA_H__
> +
> +enum {
> +	HOST_CAP = 0x00,
> +	HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
> +	HOST_PORTS_IMPL	= 0x0c,
> +	HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
> +};
> +
> +extern int sata_init(struct device *dev, void __iomem *addr);
> +extern void sata_exit(struct device *dev);
> +#endif /* __PLAT_MXC_AHCI_SATA_H__ */
> diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
> index 524538a..f04e063 100644
> --- a/arch/arm/plat-mxc/include/mach/devices-common.h
> +++ b/arch/arm/plat-mxc/include/mach/devices-common.h
> @@ -301,3 +301,13 @@ struct platform_device *__init imx_add_spi_imx(
>  struct platform_device *imx_add_imx_dma(void);
>  struct platform_device *imx_add_imx_sdma(char *name,
>  	resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
> +
> +#include <linux/ahci_platform.h>
> +struct imx_ahci_imx_data {
> +	const char *devid;
> +	resource_size_t iobase;
> +	resource_size_t irq;
> +};
> +struct platform_device *__init imx_add_ahci_imx(
> +		const struct imx_ahci_imx_data *data,
> +		const struct ahci_platform_data *pdata);
> -- 
> 1.7.1
> 
> 
>
Richard Zhu Sept. 21, 2011, 5:04 a.m. UTC | #4
Hi Sascha:
Thanks for your comments.

Best Regard
Richard Zhu

On 21 September 2011 04:30, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Wed, Aug 31, 2011 at 11:50:31AM +0800, Richard Zhu wrote:
>> Signed-off-by: Richard Zhu <richard.zhu@linaro.org>
>> Tested-By: Hector Oron Martinez <hector.oron@gmail.com>
>> ---
>>  arch/arm/mach-mx5/clock-mx51-mx53.c             |   19 ++++
>>  arch/arm/mach-mx5/devices-imx53.h               |    4 +
>>  arch/arm/plat-mxc/Makefile                      |    1 +
>>  arch/arm/plat-mxc/ahci_sata.c                   |  104 +++++++++++++++++++++++
>>  arch/arm/plat-mxc/devices/Kconfig               |    4 +
>>  arch/arm/plat-mxc/devices/Makefile              |    1 +
>>  arch/arm/plat-mxc/devices/platform-ahci-imx.c   |   66 ++++++++++++++
>>  arch/arm/plat-mxc/include/mach/ahci_sata.h      |   33 +++++++
>>  arch/arm/plat-mxc/include/mach/devices-common.h |   10 ++
>>  9 files changed, 242 insertions(+), 0 deletions(-)
>>  create mode 100644 arch/arm/plat-mxc/ahci_sata.c
>>  create mode 100644 arch/arm/plat-mxc/devices/platform-ahci-imx.c
>>  create mode 100644 arch/arm/plat-mxc/include/mach/ahci_sata.h
>>
>> diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
>> index 7f20308..e1fadaf 100644
>> --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
>> +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
>> @@ -1397,6 +1397,22 @@ static struct clk esdhc4_mx53_clk = {
>>       .secondary = &esdhc4_ipg_clk,
>>  };
>>
>> diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
>> new file mode 100644
>> index 0000000..4f54816
>> --- /dev/null
>> +++ b/arch/arm/plat-mxc/ahci_sata.c
>> @@ -0,0 +1,104 @@
>> +/*
>> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
>> + */
>> +
>> +/*
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> +
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> +
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/clk.h>
>> +#include <linux/err.h>
>> +#include <linux/device.h>
>> +#include <mach/ahci_sata.h>
>> +
>> +static struct clk *sata_clk, *sata_ref_clk;
>
> These variables make the driver single instance only.
[Richard Zhu] In order to handle the clock enable/disable stuff, these
two variables are mandatory required.
Otherwise, new two struct clk members had to be added into
ahci_platform_data struct. Then the clks can
be transferred by the platform data.
The current is preferred, refer to the second choice.
>
>> +
>> +/* AHCI module Initialization, if return 0, initialization is successful. */
>> +int sata_init(struct device *dev, void __iomem *addr)
>
> A global function with such a generic name is not a good idea.
> Also I wonder how we want to convert this to devicetree when we
> implement this as a platform specific hook. It should be done in the
> driver.
>
[Richard Zhu] The name of these two func can be changed.
But I don't have a good idea to move out these two platform specific
hooks (->init, ->exit).

Refer to you comments, do you means that the ->init and ->exit should
be done in ahci_platform.c driver?
Different platform may have the different ->init and ->exit funcs to
handle it's own initialization and exit.
It would be a problem that handle all kinds of init in one driver
without the hooks.

>> +{
>> +     u32 tmpdata;
>> +     int ret = 0;
>> +     struct clk *clk;
>> +
>> +     sata_clk = clk_get(dev, "ahci");
>> +     if (IS_ERR(sata_clk)) {
>> +             dev_err(dev, "no sata clock.\n");
>> +             return PTR_ERR(sata_clk);
>> +     }
>> +     ret = clk_enable(sata_clk);
>> +     if (ret) {
>> +             dev_err(dev, "can't enable sata clock.\n");
>> +             goto put_sata_clk;
>> +     }
>> +
>> +     /* FSL IMX AHCI SATA uses the internal usb phy1 clk on loco */
>
> So this function is loco specific or is the comment wrong?
[Richard Zhu] Comments wrong, they're common codes and should't be
specified by the exact
 board, would be changed later.
>
>> +     sata_ref_clk = clk_get(dev, "ahci_phy");
>> +     if (IS_ERR(sata_ref_clk)) {
>> +             dev_err(dev, "no sata ref clock.\n");
>> +             ret = PTR_ERR(sata_ref_clk);
>> +             goto release_sata_clk;
>> +     }
>> +     ret = clk_enable(sata_ref_clk);
>> +     if (ret) {
>> +             dev_err(dev, "can't enable sata ref clock.\n");
>> +             goto put_sata_ref_clk;
>> +     }
>> +
>> +     /* Get the AHB clock rate, and configure the TIMER1MS reg later */
>> +     clk = clk_get(dev, "ahci_dma");
>> +     if (IS_ERR(clk)) {
>> +             dev_err(dev, "no dma clock.\n");
>> +             ret = PTR_ERR(clk);
>> +             goto release_sata_ref_clk;
>> +     }
>> +     tmpdata = clk_get_rate(clk) / 1000;
>> +     clk_put(clk);
>> +
>> +     writel(tmpdata, addr + HOST_TIMER1MS);
>> +
>> +     tmpdata = readl(addr + HOST_CAP);
>> +     if (!(tmpdata & HOST_CAP_SSS)) {
>> +             tmpdata |= HOST_CAP_SSS;
>> +             writel(tmpdata, addr + HOST_CAP);
>> +     }
>> +
>> +     if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
>> +             writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
>> +                     addr + HOST_PORTS_IMPL);
>> +
>> +     return 0;
>> +
>> +release_sata_ref_clk:
>> +     clk_disable(sata_ref_clk);
>> +put_sata_ref_clk:
>> +     clk_put(sata_ref_clk);
>> +release_sata_clk:
>> +     clk_disable(sata_clk);
>> +put_sata_clk:
>> +     clk_put(sata_clk);
>> +
>> +     return ret;
>> +}
>> +
>> +void sata_exit(struct device *dev)
>> +{
>> +     clk_disable(sata_ref_clk);
>> +     clk_put(sata_ref_clk);
>> +
>> +     clk_disable(sata_clk);
>> +     clk_put(sata_clk);
>> +
>> +}
>> diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
>> index bd294ad..f63887b 100644
>> --- a/arch/arm/plat-mxc/devices/Kconfig
>> +++ b/arch/arm/plat-mxc/devices/Kconfig
>> @@ -76,3 +76,7 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
>>
>>  config IMX_HAVE_PLATFORM_SPI_IMX
>>       bool
>> +
>> +config IMX_HAVE_PLATFORM_AHCI
>> +     bool
>> +     default y if ARCH_MX53
>> diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
>> index b41bf97..e858ad9 100644
>> --- a/arch/arm/plat-mxc/devices/Makefile
>> +++ b/arch/arm/plat-mxc/devices/Makefile
>> @@ -25,3 +25,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
>>  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
>>  obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
>>  obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
>> +obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) +=  platform-ahci-imx.o
>> diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
>> new file mode 100644
>> index 0000000..9e1b460
>> --- /dev/null
>> +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
>> @@ -0,0 +1,66 @@
>> +/*
>> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
>> + */
>> +
>> +/*
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> +
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> +
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#include <linux/dma-mapping.h>
>> +#include <asm/sizes.h>
>> +#include <mach/hardware.h>
>> +#include <mach/devices-common.h>
>> +#include <mach/ahci_sata.h>
>> +
>> +#define imx_ahci_imx_data_entry_single(soc, _devid)          \
>> +     {                                                               \
>> +             .devid = _devid,                                        \
>> +             .iobase = soc ## _SATA_BASE_ADDR,                       \
>> +             .irq = soc ## _INT_SATA,                                \
>> +     }
>> +
>> +#ifdef CONFIG_SOC_IMX53
>> +const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
>> +     imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
>> +#endif
>> +
>> +static struct ahci_platform_data default_sata_pdata = {
>> +     .init = sata_init,
>> +     .exit = sata_exit,
>> +};
>> +
>> +struct platform_device *__init imx_add_ahci_imx(
>> +             const struct imx_ahci_imx_data *data,
>> +             const struct ahci_platform_data *pdata)
>> +{
>> +     struct resource res[] = {
>> +             {
>> +                     .start = data->iobase,
>> +                     .end = data->iobase + SZ_4K - 1,
>> +                     .flags = IORESOURCE_MEM,
>> +             }, {
>> +                     .start = data->irq,
>> +                     .end = data->irq,
>> +                     .flags = IORESOURCE_IRQ,
>> +             },
>> +     };
>> +
>> +     if (pdata == NULL)
>> +             pdata = &default_sata_pdata;
>> +
>> +     return imx_add_platform_device_dmamask(data->devid, 0,
>> +                     res, ARRAY_SIZE(res),
>> +                     pdata, sizeof(*pdata),  DMA_BIT_MASK(32));
>> +}
>> diff --git a/arch/arm/plat-mxc/include/mach/ahci_sata.h b/arch/arm/plat-mxc/include/mach/ahci_sata.h
>> new file mode 100644
>> index 0000000..ba297e1
>> --- /dev/null
>> +++ b/arch/arm/plat-mxc/include/mach/ahci_sata.h
>> @@ -0,0 +1,33 @@
>> +/*
>> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
>> + */
>> +
>> +/*
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> +
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> +
>> + * You should have received a copy of the GNU General Public License along
>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef __PLAT_MXC_AHCI_SATA_H__
>> +#define __PLAT_MXC_AHCI_SATA_H__
>> +
>> +enum {
>> +     HOST_CAP = 0x00,
>> +     HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
>> +     HOST_PORTS_IMPL = 0x0c,
>> +     HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
>> +};
>> +
>> +extern int sata_init(struct device *dev, void __iomem *addr);
>> +extern void sata_exit(struct device *dev);
>> +#endif /* __PLAT_MXC_AHCI_SATA_H__ */
>> diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
>> index 524538a..f04e063 100644
>> --- a/arch/arm/plat-mxc/include/mach/devices-common.h
>> +++ b/arch/arm/plat-mxc/include/mach/devices-common.h
>> @@ -301,3 +301,13 @@ struct platform_device *__init imx_add_spi_imx(
>>  struct platform_device *imx_add_imx_dma(void);
>>  struct platform_device *imx_add_imx_sdma(char *name,
>>       resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
>> +
>> +#include <linux/ahci_platform.h>
>> +struct imx_ahci_imx_data {
>> +     const char *devid;
>> +     resource_size_t iobase;
>> +     resource_size_t irq;
>> +};
>> +struct platform_device *__init imx_add_ahci_imx(
>> +             const struct imx_ahci_imx_data *data,
>> +             const struct ahci_platform_data *pdata);
>> --
>> 1.7.1
>>
>>
>>
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
>
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sascha Hauer Sept. 21, 2011, 7:02 a.m. UTC | #5
On Wed, Sep 21, 2011 at 01:04:09PM +0800, Richard Zhu wrote:
> Hi Sascha:
> Thanks for your comments.
> 
> Best Regard
> Richard Zhu
> 
> On 21 September 2011 04:30, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > On Wed, Aug 31, 2011 at 11:50:31AM +0800, Richard Zhu wrote:
> >> Signed-off-by: Richard Zhu <richard.zhu@linaro.org>
> >> Tested-By: Hector Oron Martinez <hector.oron@gmail.com>
> >> ---
> >>  arch/arm/mach-mx5/clock-mx51-mx53.c             |   19 ++++
> >>  arch/arm/mach-mx5/devices-imx53.h               |    4 +
> >>  arch/arm/plat-mxc/Makefile                      |    1 +
> >>  arch/arm/plat-mxc/ahci_sata.c                   |  104 +++++++++++++++++++++++
> >>  arch/arm/plat-mxc/devices/Kconfig               |    4 +
> >>  arch/arm/plat-mxc/devices/Makefile              |    1 +
> >>  arch/arm/plat-mxc/devices/platform-ahci-imx.c   |   66 ++++++++++++++
> >>  arch/arm/plat-mxc/include/mach/ahci_sata.h      |   33 +++++++
> >>  arch/arm/plat-mxc/include/mach/devices-common.h |   10 ++
> >>  9 files changed, 242 insertions(+), 0 deletions(-)
> >>  create mode 100644 arch/arm/plat-mxc/ahci_sata.c
> >>  create mode 100644 arch/arm/plat-mxc/devices/platform-ahci-imx.c
> >>  create mode 100644 arch/arm/plat-mxc/include/mach/ahci_sata.h
> >>
> >> diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
> >> index 7f20308..e1fadaf 100644
> >> --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
> >> +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
> >> @@ -1397,6 +1397,22 @@ static struct clk esdhc4_mx53_clk = {
> >>       .secondary = &esdhc4_ipg_clk,
> >>  };
> >>
> >> diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
> >> new file mode 100644
> >> index 0000000..4f54816
> >> --- /dev/null
> >> +++ b/arch/arm/plat-mxc/ahci_sata.c
> >> @@ -0,0 +1,104 @@
> >> +/*
> >> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> >> + */
> >> +
> >> +/*
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License as published by
> >> + * the Free Software Foundation; either version 2 of the License, or
> >> + * (at your option) any later version.
> >> +
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> +
> >> + * You should have received a copy of the GNU General Public License along
> >> + * with this program; if not, write to the Free Software Foundation, Inc.,
> >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> >> + */
> >> +
> >> +#include <linux/io.h>
> >> +#include <linux/clk.h>
> >> +#include <linux/err.h>
> >> +#include <linux/device.h>
> >> +#include <mach/ahci_sata.h>
> >> +
> >> +static struct clk *sata_clk, *sata_ref_clk;
> >
> > These variables make the driver single instance only.
> [Richard Zhu] In order to handle the clock enable/disable stuff, these
> two variables are mandatory required.
> Otherwise, new two struct clk members had to be added into
> ahci_platform_data struct. Then the clks can
> be transferred by the platform data.
> The current is preferred, refer to the second choice.
> >
> >> +
> >> +/* AHCI module Initialization, if return 0, initialization is successful. */
> >> +int sata_init(struct device *dev, void __iomem *addr)
> >
> > A global function with such a generic name is not a good idea.
> > Also I wonder how we want to convert this to devicetree when we
> > implement this as a platform specific hook. It should be done in the
> > driver.
> >
> [Richard Zhu] The name of these two func can be changed.
> But I don't have a good idea to move out these two platform specific
> hooks (->init, ->exit).
> 
> Refer to you comments, do you means that the ->init and ->exit should
> be done in ahci_platform.c driver?
> Different platform may have the different ->init and ->exit funcs to
> handle it's own initialization and exit.
> It would be a problem that handle all kinds of init in one driver
> without the hooks.

Maybe Shawn can comment on the device tree topic. I just think that if
we merge this without devicetree support it should at least be
devicetree friendly. For example each platform could provide it's own
platform driver glue code like it's done for the sdhci driver.

> >> diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
> >> new file mode 100644
> >> index 0000000..9e1b460
> >> --- /dev/null
> >> +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
> >> @@ -0,0 +1,66 @@
> >> +/*
> >> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> >> + */
> >> +
> >> +/*
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License as published by
> >> + * the Free Software Foundation; either version 2 of the License, or
> >> + * (at your option) any later version.
> >> +
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >> + * GNU General Public License for more details.
> >> +
> >> + * You should have received a copy of the GNU General Public License along
> >> + * with this program; if not, write to the Free Software Foundation, Inc.,
> >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> >> + */
> >> +
> >> +#include <linux/dma-mapping.h>
> >> +#include <asm/sizes.h>
> >> +#include <mach/hardware.h>
> >> +#include <mach/devices-common.h>
> >> +#include <mach/ahci_sata.h>
> >> +
> >> +#define imx_ahci_imx_data_entry_single(soc, _devid)          \
> >> +     {                                                               \
> >> +             .devid = _devid,                                        \
> >> +             .iobase = soc ## _SATA_BASE_ADDR,                       \
> >> +             .irq = soc ## _INT_SATA,                                \
> >> +     }
> >> +
> >> +#ifdef CONFIG_SOC_IMX53
> >> +const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
> >> +     imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
> >> +#endif
> >> +
> >> +static struct ahci_platform_data default_sata_pdata = {
> >> +     .init = sata_init,
> >> +     .exit = sata_exit,
> >> +};

If we continue going the way you started, please add the
sata_init/sata_exit functions as static functions to this file, ...

> >> +
> >> +struct platform_device *__init imx_add_ahci_imx(
> >> +             const struct imx_ahci_imx_data *data,
> >> +             const struct ahci_platform_data *pdata)
> >> +{
> >> +     struct resource res[] = {
> >> +             {
> >> +                     .start = data->iobase,
> >> +                     .end = data->iobase + SZ_4K - 1,
> >> +                     .flags = IORESOURCE_MEM,
> >> +             }, {
> >> +                     .start = data->irq,
> >> +                     .end = data->irq,
> >> +                     .flags = IORESOURCE_IRQ,
> >> +             },
> >> +     };
> >> +
> >> +     if (pdata == NULL)
> >> +             pdata = &default_sata_pdata;

...remove these two lines, and instead introduce a function like this:

struct platform_device *__init imx53_add_ahci_imx(void)
{
	struct ahci_platform_data pdata = {
		.init = imx53_sata_init,
		.exit = imx53_sata_exit,
	};

	return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata);
}
Richard Zhu Sept. 21, 2011, 7:05 a.m. UTC | #6
Hi Sascha:
One proposal about how to convert the ahci driver to devicetree in future.
ahci driver system can make a reference to the evolution of the sdhc driver.

* separate the ahci to ahci common codes, ahci-pci driver and
ahci-platform driver.
* create kinds of ahci vendor's own ahci platform driver refer to the
sdhci-xxx driver solutions.
* then we can convert the ahci driver to devicetree smoothly.

It's a long term evolution.

Hi Jeff:
Do you have any suggestions or advices about it?

Best Regard
Richard Zhu

On 21 September 2011 13:04, Richard Zhu <richard.zhu@linaro.org> wrote:
> Hi Sascha:
> Thanks for your comments.
>
> Best Regard
> Richard Zhu
>
> On 21 September 2011 04:30, Sascha Hauer <s.hauer@pengutronix.de> wrote:
>> On Wed, Aug 31, 2011 at 11:50:31AM +0800, Richard Zhu wrote:
>>> Signed-off-by: Richard Zhu <richard.zhu@linaro.org>
>>> Tested-By: Hector Oron Martinez <hector.oron@gmail.com>
>>> ---
>>>  arch/arm/mach-mx5/clock-mx51-mx53.c             |   19 ++++
>>>  arch/arm/mach-mx5/devices-imx53.h               |    4 +
>>>  arch/arm/plat-mxc/Makefile                      |    1 +
>>>  arch/arm/plat-mxc/ahci_sata.c                   |  104 +++++++++++++++++++++++
>>>  arch/arm/plat-mxc/devices/Kconfig               |    4 +
>>>  arch/arm/plat-mxc/devices/Makefile              |    1 +
>>>  arch/arm/plat-mxc/devices/platform-ahci-imx.c   |   66 ++++++++++++++
>>>  arch/arm/plat-mxc/include/mach/ahci_sata.h      |   33 +++++++
>>>  arch/arm/plat-mxc/include/mach/devices-common.h |   10 ++
>>>  9 files changed, 242 insertions(+), 0 deletions(-)
>>>  create mode 100644 arch/arm/plat-mxc/ahci_sata.c
>>>  create mode 100644 arch/arm/plat-mxc/devices/platform-ahci-imx.c
>>>  create mode 100644 arch/arm/plat-mxc/include/mach/ahci_sata.h
>>>
>>> diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
>>> index 7f20308..e1fadaf 100644
>>> --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
>>> +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
>>> @@ -1397,6 +1397,22 @@ static struct clk esdhc4_mx53_clk = {
>>>       .secondary = &esdhc4_ipg_clk,
>>>  };
>>>
>>> diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
>>> new file mode 100644
>>> index 0000000..4f54816
>>> --- /dev/null
>>> +++ b/arch/arm/plat-mxc/ahci_sata.c
>>> @@ -0,0 +1,104 @@
>>> +/*
>>> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
>>> + */
>>> +
>>> +/*
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> +
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> +
>>> + * You should have received a copy of the GNU General Public License along
>>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>>> + */
>>> +
>>> +#include <linux/io.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/err.h>
>>> +#include <linux/device.h>
>>> +#include <mach/ahci_sata.h>
>>> +
>>> +static struct clk *sata_clk, *sata_ref_clk;
>>
>> These variables make the driver single instance only.
> [Richard Zhu] In order to handle the clock enable/disable stuff, these
> two variables are mandatory required.
> Otherwise, new two struct clk members had to be added into
> ahci_platform_data struct. Then the clks can
> be transferred by the platform data.
> The current is preferred, refer to the second choice.
>>
>>> +
>>> +/* AHCI module Initialization, if return 0, initialization is successful. */
>>> +int sata_init(struct device *dev, void __iomem *addr)
>>
>> A global function with such a generic name is not a good idea.
>> Also I wonder how we want to convert this to devicetree when we
>> implement this as a platform specific hook. It should be done in the
>> driver.
>>
> [Richard Zhu] The name of these two func can be changed.
> But I don't have a good idea to move out these two platform specific
> hooks (->init, ->exit).
>
> Refer to you comments, do you means that the ->init and ->exit should
> be done in ahci_platform.c driver?
> Different platform may have the different ->init and ->exit funcs to
> handle it's own initialization and exit.
> It would be a problem that handle all kinds of init in one driver
> without the hooks.
>
>>> +{
>>> +     u32 tmpdata;
>>> +     int ret = 0;
>>> +     struct clk *clk;
>>> +
>>> +     sata_clk = clk_get(dev, "ahci");
>>> +     if (IS_ERR(sata_clk)) {
>>> +             dev_err(dev, "no sata clock.\n");
>>> +             return PTR_ERR(sata_clk);
>>> +     }
>>> +     ret = clk_enable(sata_clk);
>>> +     if (ret) {
>>> +             dev_err(dev, "can't enable sata clock.\n");
>>> +             goto put_sata_clk;
>>> +     }
>>> +
>>> +     /* FSL IMX AHCI SATA uses the internal usb phy1 clk on loco */
>>
>> So this function is loco specific or is the comment wrong?
> [Richard Zhu] Comments wrong, they're common codes and should't be
> specified by the exact
>  board, would be changed later.
>>
>>> +     sata_ref_clk = clk_get(dev, "ahci_phy");
>>> +     if (IS_ERR(sata_ref_clk)) {
>>> +             dev_err(dev, "no sata ref clock.\n");
>>> +             ret = PTR_ERR(sata_ref_clk);
>>> +             goto release_sata_clk;
>>> +     }
>>> +     ret = clk_enable(sata_ref_clk);
>>> +     if (ret) {
>>> +             dev_err(dev, "can't enable sata ref clock.\n");
>>> +             goto put_sata_ref_clk;
>>> +     }
>>> +
>>> +     /* Get the AHB clock rate, and configure the TIMER1MS reg later */
>>> +     clk = clk_get(dev, "ahci_dma");
>>> +     if (IS_ERR(clk)) {
>>> +             dev_err(dev, "no dma clock.\n");
>>> +             ret = PTR_ERR(clk);
>>> +             goto release_sata_ref_clk;
>>> +     }
>>> +     tmpdata = clk_get_rate(clk) / 1000;
>>> +     clk_put(clk);
>>> +
>>> +     writel(tmpdata, addr + HOST_TIMER1MS);
>>> +
>>> +     tmpdata = readl(addr + HOST_CAP);
>>> +     if (!(tmpdata & HOST_CAP_SSS)) {
>>> +             tmpdata |= HOST_CAP_SSS;
>>> +             writel(tmpdata, addr + HOST_CAP);
>>> +     }
>>> +
>>> +     if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
>>> +             writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
>>> +                     addr + HOST_PORTS_IMPL);
>>> +
>>> +     return 0;
>>> +
>>> +release_sata_ref_clk:
>>> +     clk_disable(sata_ref_clk);
>>> +put_sata_ref_clk:
>>> +     clk_put(sata_ref_clk);
>>> +release_sata_clk:
>>> +     clk_disable(sata_clk);
>>> +put_sata_clk:
>>> +     clk_put(sata_clk);
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +void sata_exit(struct device *dev)
>>> +{
>>> +     clk_disable(sata_ref_clk);
>>> +     clk_put(sata_ref_clk);
>>> +
>>> +     clk_disable(sata_clk);
>>> +     clk_put(sata_clk);
>>> +
>>> +}
>>> diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
>>> index bd294ad..f63887b 100644
>>> --- a/arch/arm/plat-mxc/devices/Kconfig
>>> +++ b/arch/arm/plat-mxc/devices/Kconfig
>>> @@ -76,3 +76,7 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
>>>
>>>  config IMX_HAVE_PLATFORM_SPI_IMX
>>>       bool
>>> +
>>> +config IMX_HAVE_PLATFORM_AHCI
>>> +     bool
>>> +     default y if ARCH_MX53
>>> diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
>>> index b41bf97..e858ad9 100644
>>> --- a/arch/arm/plat-mxc/devices/Makefile
>>> +++ b/arch/arm/plat-mxc/devices/Makefile
>>> @@ -25,3 +25,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
>>>  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
>>>  obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
>>>  obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
>>> +obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) +=  platform-ahci-imx.o
>>> diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
>>> new file mode 100644
>>> index 0000000..9e1b460
>>> --- /dev/null
>>> +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
>>> @@ -0,0 +1,66 @@
>>> +/*
>>> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
>>> + */
>>> +
>>> +/*
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> +
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> +
>>> + * You should have received a copy of the GNU General Public License along
>>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>>> + */
>>> +
>>> +#include <linux/dma-mapping.h>
>>> +#include <asm/sizes.h>
>>> +#include <mach/hardware.h>
>>> +#include <mach/devices-common.h>
>>> +#include <mach/ahci_sata.h>
>>> +
>>> +#define imx_ahci_imx_data_entry_single(soc, _devid)          \
>>> +     {                                                               \
>>> +             .devid = _devid,                                        \
>>> +             .iobase = soc ## _SATA_BASE_ADDR,                       \
>>> +             .irq = soc ## _INT_SATA,                                \
>>> +     }
>>> +
>>> +#ifdef CONFIG_SOC_IMX53
>>> +const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
>>> +     imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
>>> +#endif
>>> +
>>> +static struct ahci_platform_data default_sata_pdata = {
>>> +     .init = sata_init,
>>> +     .exit = sata_exit,
>>> +};
>>> +
>>> +struct platform_device *__init imx_add_ahci_imx(
>>> +             const struct imx_ahci_imx_data *data,
>>> +             const struct ahci_platform_data *pdata)
>>> +{
>>> +     struct resource res[] = {
>>> +             {
>>> +                     .start = data->iobase,
>>> +                     .end = data->iobase + SZ_4K - 1,
>>> +                     .flags = IORESOURCE_MEM,
>>> +             }, {
>>> +                     .start = data->irq,
>>> +                     .end = data->irq,
>>> +                     .flags = IORESOURCE_IRQ,
>>> +             },
>>> +     };
>>> +
>>> +     if (pdata == NULL)
>>> +             pdata = &default_sata_pdata;
>>> +
>>> +     return imx_add_platform_device_dmamask(data->devid, 0,
>>> +                     res, ARRAY_SIZE(res),
>>> +                     pdata, sizeof(*pdata),  DMA_BIT_MASK(32));
>>> +}
>>> diff --git a/arch/arm/plat-mxc/include/mach/ahci_sata.h b/arch/arm/plat-mxc/include/mach/ahci_sata.h
>>> new file mode 100644
>>> index 0000000..ba297e1
>>> --- /dev/null
>>> +++ b/arch/arm/plat-mxc/include/mach/ahci_sata.h
>>> @@ -0,0 +1,33 @@
>>> +/*
>>> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
>>> + */
>>> +
>>> +/*
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> +
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> +
>>> + * You should have received a copy of the GNU General Public License along
>>> + * with this program; if not, write to the Free Software Foundation, Inc.,
>>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>>> + */
>>> +
>>> +#ifndef __PLAT_MXC_AHCI_SATA_H__
>>> +#define __PLAT_MXC_AHCI_SATA_H__
>>> +
>>> +enum {
>>> +     HOST_CAP = 0x00,
>>> +     HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
>>> +     HOST_PORTS_IMPL = 0x0c,
>>> +     HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
>>> +};
>>> +
>>> +extern int sata_init(struct device *dev, void __iomem *addr);
>>> +extern void sata_exit(struct device *dev);
>>> +#endif /* __PLAT_MXC_AHCI_SATA_H__ */
>>> diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
>>> index 524538a..f04e063 100644
>>> --- a/arch/arm/plat-mxc/include/mach/devices-common.h
>>> +++ b/arch/arm/plat-mxc/include/mach/devices-common.h
>>> @@ -301,3 +301,13 @@ struct platform_device *__init imx_add_spi_imx(
>>>  struct platform_device *imx_add_imx_dma(void);
>>>  struct platform_device *imx_add_imx_sdma(char *name,
>>>       resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
>>> +
>>> +#include <linux/ahci_platform.h>
>>> +struct imx_ahci_imx_data {
>>> +     const char *devid;
>>> +     resource_size_t iobase;
>>> +     resource_size_t irq;
>>> +};
>>> +struct platform_device *__init imx_add_ahci_imx(
>>> +             const struct imx_ahci_imx_data *data,
>>> +             const struct ahci_platform_data *pdata);
>>> --
>>> 1.7.1
>>>
>>>
>>>
>>
>> --
>> Pengutronix e.K.                           |                             |
>> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
>> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Shawn Guo Sept. 21, 2011, 7:32 a.m. UTC | #7
On Wed, Sep 21, 2011 at 09:02:01AM +0200, Sascha Hauer wrote:
> On Wed, Sep 21, 2011 at 01:04:09PM +0800, Richard Zhu wrote:
> > Hi Sascha:
> > Thanks for your comments.
> > 
> > Best Regard
> > Richard Zhu
> > 
> > On 21 September 2011 04:30, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > > On Wed, Aug 31, 2011 at 11:50:31AM +0800, Richard Zhu wrote:
> > >> Signed-off-by: Richard Zhu <richard.zhu@linaro.org>
> > >> Tested-By: Hector Oron Martinez <hector.oron@gmail.com>
> > >> ---
> > >>  arch/arm/mach-mx5/clock-mx51-mx53.c             |   19 ++++
> > >>  arch/arm/mach-mx5/devices-imx53.h               |    4 +
> > >>  arch/arm/plat-mxc/Makefile                      |    1 +
> > >>  arch/arm/plat-mxc/ahci_sata.c                   |  104 +++++++++++++++++++++++
> > >>  arch/arm/plat-mxc/devices/Kconfig               |    4 +
> > >>  arch/arm/plat-mxc/devices/Makefile              |    1 +
> > >>  arch/arm/plat-mxc/devices/platform-ahci-imx.c   |   66 ++++++++++++++
> > >>  arch/arm/plat-mxc/include/mach/ahci_sata.h      |   33 +++++++
> > >>  arch/arm/plat-mxc/include/mach/devices-common.h |   10 ++
> > >>  9 files changed, 242 insertions(+), 0 deletions(-)
> > >>  create mode 100644 arch/arm/plat-mxc/ahci_sata.c
> > >>  create mode 100644 arch/arm/plat-mxc/devices/platform-ahci-imx.c
> > >>  create mode 100644 arch/arm/plat-mxc/include/mach/ahci_sata.h
> > >>
> > >> diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
> > >> index 7f20308..e1fadaf 100644
> > >> --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
> > >> +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
> > >> @@ -1397,6 +1397,22 @@ static struct clk esdhc4_mx53_clk = {
> > >>       .secondary = &esdhc4_ipg_clk,
> > >>  };
> > >>
> > >> diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
> > >> new file mode 100644
> > >> index 0000000..4f54816
> > >> --- /dev/null
> > >> +++ b/arch/arm/plat-mxc/ahci_sata.c
> > >> @@ -0,0 +1,104 @@
> > >> +/*
> > >> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > >> + */
> > >> +
> > >> +/*
> > >> + * This program is free software; you can redistribute it and/or modify
> > >> + * it under the terms of the GNU General Public License as published by
> > >> + * the Free Software Foundation; either version 2 of the License, or
> > >> + * (at your option) any later version.
> > >> +
> > >> + * This program is distributed in the hope that it will be useful,
> > >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > >> + * GNU General Public License for more details.
> > >> +
> > >> + * You should have received a copy of the GNU General Public License along
> > >> + * with this program; if not, write to the Free Software Foundation, Inc.,
> > >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> > >> + */
> > >> +
> > >> +#include <linux/io.h>
> > >> +#include <linux/clk.h>
> > >> +#include <linux/err.h>
> > >> +#include <linux/device.h>
> > >> +#include <mach/ahci_sata.h>
> > >> +
> > >> +static struct clk *sata_clk, *sata_ref_clk;
> > >
> > > These variables make the driver single instance only.
> > [Richard Zhu] In order to handle the clock enable/disable stuff, these
> > two variables are mandatory required.
> > Otherwise, new two struct clk members had to be added into
> > ahci_platform_data struct. Then the clks can
> > be transferred by the platform data.
> > The current is preferred, refer to the second choice.
> > >
> > >> +
> > >> +/* AHCI module Initialization, if return 0, initialization is successful. */
> > >> +int sata_init(struct device *dev, void __iomem *addr)
> > >
> > > A global function with such a generic name is not a good idea.
> > > Also I wonder how we want to convert this to devicetree when we
> > > implement this as a platform specific hook. It should be done in the
> > > driver.
> > >
> > [Richard Zhu] The name of these two func can be changed.
> > But I don't have a good idea to move out these two platform specific
> > hooks (->init, ->exit).
> > 
> > Refer to you comments, do you means that the ->init and ->exit should
> > be done in ahci_platform.c driver?
> > Different platform may have the different ->init and ->exit funcs to
> > handle it's own initialization and exit.
> > It would be a problem that handle all kinds of init in one driver
> > without the hooks.
> 
> Maybe Shawn can comment on the device tree topic. I just think that if
> we merge this without devicetree support it should at least be
> devicetree friendly. For example each platform could provide it's own
> platform driver glue code like it's done for the sdhci driver.
> 
+1

Though we have a way out for platform hooks if there is really no other
way around, using aux_data to pass a platform_data holding the hooks,
I really hate to see that.  And obviously, Sascha's suggestion seems
the right thing to do.
 
Regards,
Shawn

> > >> diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
> > >> new file mode 100644
> > >> index 0000000..9e1b460
> > >> --- /dev/null
> > >> +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
> > >> @@ -0,0 +1,66 @@
> > >> +/*
> > >> + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
> > >> + */
> > >> +
> > >> +/*
> > >> + * This program is free software; you can redistribute it and/or modify
> > >> + * it under the terms of the GNU General Public License as published by
> > >> + * the Free Software Foundation; either version 2 of the License, or
> > >> + * (at your option) any later version.
> > >> +
> > >> + * This program is distributed in the hope that it will be useful,
> > >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > >> + * GNU General Public License for more details.
> > >> +
> > >> + * You should have received a copy of the GNU General Public License along
> > >> + * with this program; if not, write to the Free Software Foundation, Inc.,
> > >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> > >> + */
> > >> +
> > >> +#include <linux/dma-mapping.h>
> > >> +#include <asm/sizes.h>
> > >> +#include <mach/hardware.h>
> > >> +#include <mach/devices-common.h>
> > >> +#include <mach/ahci_sata.h>
> > >> +
> > >> +#define imx_ahci_imx_data_entry_single(soc, _devid)          \
> > >> +     {                                                               \
> > >> +             .devid = _devid,                                        \
> > >> +             .iobase = soc ## _SATA_BASE_ADDR,                       \
> > >> +             .irq = soc ## _INT_SATA,                                \
> > >> +     }
> > >> +
> > >> +#ifdef CONFIG_SOC_IMX53
> > >> +const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
> > >> +     imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
> > >> +#endif
> > >> +
> > >> +static struct ahci_platform_data default_sata_pdata = {
> > >> +     .init = sata_init,
> > >> +     .exit = sata_exit,
> > >> +};
> 
> If we continue going the way you started, please add the
> sata_init/sata_exit functions as static functions to this file, ...
> 
> > >> +
> > >> +struct platform_device *__init imx_add_ahci_imx(
> > >> +             const struct imx_ahci_imx_data *data,
> > >> +             const struct ahci_platform_data *pdata)
> > >> +{
> > >> +     struct resource res[] = {
> > >> +             {
> > >> +                     .start = data->iobase,
> > >> +                     .end = data->iobase + SZ_4K - 1,
> > >> +                     .flags = IORESOURCE_MEM,
> > >> +             }, {
> > >> +                     .start = data->irq,
> > >> +                     .end = data->irq,
> > >> +                     .flags = IORESOURCE_IRQ,
> > >> +             },
> > >> +     };
> > >> +
> > >> +     if (pdata == NULL)
> > >> +             pdata = &default_sata_pdata;
> 
> ...remove these two lines, and instead introduce a function like this:
> 
> struct platform_device *__init imx53_add_ahci_imx(void)
> {
> 	struct ahci_platform_data pdata = {
> 		.init = imx53_sata_init,
> 		.exit = imx53_sata_exit,
> 	};
> 
> 	return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata);
> }
> 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Garzik Sept. 22, 2011, 6:12 p.m. UTC | #8
On 09/21/2011 03:05 AM, Richard Zhu wrote:
> Hi Sascha:
> One proposal about how to convert the ahci driver to devicetree in future.
> ahci driver system can make a reference to the evolution of the sdhc driver.
>
> * separate the ahci to ahci common codes, ahci-pci driver and
> ahci-platform driver.

We already have this, with libahci.

"libahci" == ahci common code
"ahci" == AHCI PCI driver
"ahci-platform" == AHCI platform driver

	Jeff




--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Anton Vorontsov Sept. 22, 2011, 6:31 p.m. UTC | #9
Hi Richard,

On Wed, Sep 21, 2011 at 03:05:44PM +0800, Richard Zhu wrote:
> Hi Sascha:
> One proposal about how to convert the ahci driver to devicetree in future.
> ahci driver system can make a reference to the evolution of the sdhc driver.

You don't need to "convert" ahci driver to devicetree. IIRC,
the current ahci_platform driver should work almost* out of
the box with OF-enabled architectures, as OF subsystem
automatically populates memory and interrupt resources for
platform devices.

Someday you might need to implement OF-specific bindings
(e.g. get some property from the device tree and translate
it into port flags). When/if you'll need it, you can just
add it into the driver.

* Almost: you have to add of_match_table into 'struct
  platform_driver ahci_driver'.

> * separate the ahci to ahci common codes, ahci-pci driver and
> ahci-platform driver.

Done. Long time ago, actually.

> * create kinds of ahci vendor's own ahci platform driver refer to the
> sdhci-xxx driver solutions.

I think that this is viable, but personally I would like to
see platforms to just pass port flags and all needed hooks
via platform_data. That is, I'd leave the hooks in the arch/
code. Usually these hooks are very arch-specific (i.e. enable
these and these clocks, etc), so arch/ seems like a perfect
place for such things.

Not a strong opinion though, and if you like to go your route,
I'm also fine with this. It has its own pros (and cons).

Thanks,
diff mbox

Patch

diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 7f20308..e1fadaf 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -1397,6 +1397,22 @@  static struct clk esdhc4_mx53_clk = {
 	.secondary = &esdhc4_ipg_clk,
 };
 
+static struct clk sata_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_max_enable,
+	.enable_reg = MXC_CCM_CCGR4,
+	.enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+	.disable = _clk_max_disable,
+};
+
+static struct clk ahci_phy_clk = {
+	.parent = &usb_phy1_clk,
+};
+
+static struct clk ahci_dma_clk = {
+	.parent = &ahb_clk,
+};
+
 DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
 DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
 DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
@@ -1503,6 +1519,9 @@  static struct clk_lookup mx53_lookups[] = {
 	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
 	_REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
 	_REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
+	_REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk)
+	_REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk)
+	_REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk)
 };
 
 static void clk_tree_init(void)
diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h
index c27fe8b..bcb3af1 100644
--- a/arch/arm/mach-mx5/devices-imx53.h
+++ b/arch/arm/mach-mx5/devices-imx53.h
@@ -40,3 +40,7 @@  extern const struct imx_imx_ssi_data imx53_imx_ssi_data[];
 extern const struct imx_imx_keypad_data imx53_imx_keypad_data;
 #define imx53_add_imx_keypad(pdata)	\
 	imx_add_imx_keypad(&imx53_imx_keypad_data, pdata)
+
+extern const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst;
+#define imx53_add_ahci_imx(id, pdata)   \
+	imx_add_ahci_imx(&imx53_ahci_imx_data, pdata)
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index d53c35f..cc8e65a 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -19,6 +19,7 @@  obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
 obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
 obj-$(CONFIG_CPU_FREQ_IMX)    += cpufreq.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI)	+= ahci_sata.o
 ifdef CONFIG_SND_IMX_SOC
 obj-y += ssi-fiq.o
 obj-y += ssi-fiq-ksym.o
diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
new file mode 100644
index 0000000..4f54816
--- /dev/null
+++ b/arch/arm/plat-mxc/ahci_sata.c
@@ -0,0 +1,104 @@ 
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <mach/ahci_sata.h>
+
+static struct clk *sata_clk, *sata_ref_clk;
+
+/* AHCI module Initialization, if return 0, initialization is successful. */
+int sata_init(struct device *dev, void __iomem *addr)
+{
+	u32 tmpdata;
+	int ret = 0;
+	struct clk *clk;
+
+	sata_clk = clk_get(dev, "ahci");
+	if (IS_ERR(sata_clk)) {
+		dev_err(dev, "no sata clock.\n");
+		return PTR_ERR(sata_clk);
+	}
+	ret = clk_enable(sata_clk);
+	if (ret) {
+		dev_err(dev, "can't enable sata clock.\n");
+		goto put_sata_clk;
+	}
+
+	/* FSL IMX AHCI SATA uses the internal usb phy1 clk on loco */
+	sata_ref_clk = clk_get(dev, "ahci_phy");
+	if (IS_ERR(sata_ref_clk)) {
+		dev_err(dev, "no sata ref clock.\n");
+		ret = PTR_ERR(sata_ref_clk);
+		goto release_sata_clk;
+	}
+	ret = clk_enable(sata_ref_clk);
+	if (ret) {
+		dev_err(dev, "can't enable sata ref clock.\n");
+		goto put_sata_ref_clk;
+	}
+
+	/* Get the AHB clock rate, and configure the TIMER1MS reg later */
+	clk = clk_get(dev, "ahci_dma");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "no dma clock.\n");
+		ret = PTR_ERR(clk);
+		goto release_sata_ref_clk;
+	}
+	tmpdata = clk_get_rate(clk) / 1000;
+	clk_put(clk);
+
+	writel(tmpdata, addr + HOST_TIMER1MS);
+
+	tmpdata = readl(addr + HOST_CAP);
+	if (!(tmpdata & HOST_CAP_SSS)) {
+		tmpdata |= HOST_CAP_SSS;
+		writel(tmpdata, addr + HOST_CAP);
+	}
+
+	if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
+		writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
+			addr + HOST_PORTS_IMPL);
+
+	return 0;
+
+release_sata_ref_clk:
+	clk_disable(sata_ref_clk);
+put_sata_ref_clk:
+	clk_put(sata_ref_clk);
+release_sata_clk:
+	clk_disable(sata_clk);
+put_sata_clk:
+	clk_put(sata_clk);
+
+	return ret;
+}
+
+void sata_exit(struct device *dev)
+{
+	clk_disable(sata_ref_clk);
+	clk_put(sata_ref_clk);
+
+	clk_disable(sata_clk);
+	clk_put(sata_clk);
+
+}
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index bd294ad..f63887b 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -76,3 +76,7 @@  config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 
 config IMX_HAVE_PLATFORM_SPI_IMX
 	bool
+
+config IMX_HAVE_PLATFORM_AHCI
+	bool
+	default y if ARCH_MX53
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index b41bf97..e858ad9 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -25,3 +25,4 @@  obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) +=  platform-ahci-imx.o
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
new file mode 100644
index 0000000..9e1b460
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
@@ -0,0 +1,66 @@ 
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/dma-mapping.h>
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <mach/ahci_sata.h>
+
+#define imx_ahci_imx_data_entry_single(soc, _devid)		\
+	{								\
+		.devid = _devid,					\
+		.iobase = soc ## _SATA_BASE_ADDR,			\
+		.irq = soc ## _INT_SATA,				\
+	}
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst =
+	imx_ahci_imx_data_entry_single(MX53, "imx53-ahci");
+#endif
+
+static struct ahci_platform_data default_sata_pdata = {
+	.init = sata_init,
+	.exit = sata_exit,
+};
+
+struct platform_device *__init imx_add_ahci_imx(
+		const struct imx_ahci_imx_data *data,
+		const struct ahci_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	if (pdata == NULL)
+		pdata = &default_sata_pdata;
+
+	return imx_add_platform_device_dmamask(data->devid, 0,
+			res, ARRAY_SIZE(res),
+			pdata, sizeof(*pdata),  DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/include/mach/ahci_sata.h b/arch/arm/plat-mxc/include/mach/ahci_sata.h
new file mode 100644
index 0000000..ba297e1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ahci_sata.h
@@ -0,0 +1,33 @@ 
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __PLAT_MXC_AHCI_SATA_H__
+#define __PLAT_MXC_AHCI_SATA_H__
+
+enum {
+	HOST_CAP = 0x00,
+	HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
+	HOST_PORTS_IMPL	= 0x0c,
+	HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
+};
+
+extern int sata_init(struct device *dev, void __iomem *addr);
+extern void sata_exit(struct device *dev);
+#endif /* __PLAT_MXC_AHCI_SATA_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 524538a..f04e063 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -301,3 +301,13 @@  struct platform_device *__init imx_add_spi_imx(
 struct platform_device *imx_add_imx_dma(void);
 struct platform_device *imx_add_imx_sdma(char *name,
 	resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
+
+#include <linux/ahci_platform.h>
+struct imx_ahci_imx_data {
+	const char *devid;
+	resource_size_t iobase;
+	resource_size_t irq;
+};
+struct platform_device *__init imx_add_ahci_imx(
+		const struct imx_ahci_imx_data *data,
+		const struct ahci_platform_data *pdata);