* [PATCH RFC v4 01/10] libahci: Allow drivers to override start_engine
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2014-01-20 16:44 ` Hans de Goede
2014-01-20 16:44 ` [PATCH RFC v4 02/10] libahci: Move ahci_host_priv declaration to include/linux/ahci.h Hans de Goede
` (10 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
Allwinner A10 and A20 ARM SoCs have an AHCI sata controller which needs a
special register to be poked before starting the DMA engine.
This register gets reset on an ahci_stop_engine call, so there is no other
place then ahci_start_engine where this poking can be done.
This commit allows drivers to override ahci_start_engine behavior for use by
the Allwinner AHCI driver (and potentially other drivers in the future).
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/ata/ahci.c | 6 ++++--
drivers/ata/ahci.h | 3 ++-
drivers/ata/libahci.c | 27 ++++++++++++++++++---------
drivers/ata/sata_highbank.c | 3 ++-
4 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index c0ed4f27..bb4c903 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -559,6 +559,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
struct ata_port *ap = link->ap;
+ struct ahci_host_priv *hpriv = ap->host->private_data;
bool online;
int rc;
@@ -569,7 +570,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
deadline, &online, NULL);
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
@@ -584,6 +585,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
{
struct ata_port *ap = link->ap;
struct ahci_port_priv *pp = ap->private_data;
+ struct ahci_host_priv *hpriv = ap->host->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
bool online;
@@ -599,7 +601,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
deadline, &online, NULL);
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
/* The pseudo configuration device on SIMG4726 attached to
* ASUS P5W-DH Deluxe doesn't send signature FIS after
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 2289efd..2c04211 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -323,6 +323,8 @@ struct ahci_host_priv {
u32 em_msg_type; /* EM message type */
struct clk *clk; /* Only for platforms supporting clk */
void *plat_data; /* Other platform data */
+ /* Optional ahci_start_engine override */
+ void (*start_engine)(struct ata_port *ap);
};
extern int ahci_ignore_sss;
@@ -357,7 +359,6 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
int (*check_ready)(struct ata_link *link));
int ahci_stop_engine(struct ata_port *ap);
-void ahci_start_engine(struct ata_port *ap);
int ahci_check_ready(struct ata_link *link);
int ahci_kick_engine(struct ata_port *ap);
int ahci_port_resume(struct ata_port *ap);
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index c482f8c..96d128c 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -69,6 +69,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
+static void ahci_start_engine(struct ata_port *ap);
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
static int ahci_port_start(struct ata_port *ap);
@@ -500,6 +501,9 @@ void ahci_save_initial_config(struct device *dev,
hpriv->cap = cap;
hpriv->cap2 = cap2;
hpriv->port_map = port_map;
+
+ if (!hpriv->start_engine)
+ hpriv->start_engine = ahci_start_engine;
}
EXPORT_SYMBOL_GPL(ahci_save_initial_config);
@@ -565,7 +569,7 @@ static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
return -EINVAL;
}
-void ahci_start_engine(struct ata_port *ap)
+static void ahci_start_engine(struct ata_port *ap)
{
void __iomem *port_mmio = ahci_port_base(ap);
u32 tmp;
@@ -576,7 +580,6 @@ void ahci_start_engine(struct ata_port *ap)
writel(tmp, port_mmio + PORT_CMD);
readl(port_mmio + PORT_CMD); /* flush */
}
-EXPORT_SYMBOL_GPL(ahci_start_engine);
int ahci_stop_engine(struct ata_port *ap)
{
@@ -766,7 +769,7 @@ static void ahci_start_port(struct ata_port *ap)
/* enable DMA */
if (!(hpriv->flags & AHCI_HFLAG_DELAY_ENGINE))
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
/* turn on LEDs */
if (ap->flags & ATA_FLAG_EM) {
@@ -1234,7 +1237,7 @@ int ahci_kick_engine(struct ata_port *ap)
/* restart engine */
out_restart:
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
return rc;
}
EXPORT_SYMBOL_GPL(ahci_kick_engine);
@@ -1426,6 +1429,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
struct ata_port *ap = link->ap;
struct ahci_port_priv *pp = ap->private_data;
+ struct ahci_host_priv *hpriv = ap->host->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
bool online;
@@ -1443,7 +1447,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
rc = sata_link_hardreset(link, timing, deadline, &online,
ahci_check_ready);
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
if (online)
*class = ahci_dev_classify(ap);
@@ -2007,10 +2011,12 @@ static void ahci_thaw(struct ata_port *ap)
void ahci_error_handler(struct ata_port *ap)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
/* restart engine */
ahci_stop_engine(ap);
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
}
sata_pmp_error_handler(ap);
@@ -2031,6 +2037,7 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
struct ata_device *dev = ap->link.device;
u32 devslp, dm, dito, mdat, deto;
@@ -2094,7 +2101,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
PORT_DEVSLP_ADSE);
writel(devslp, port_mmio + PORT_DEVSLP);
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
/* enable device sleep feature for the drive */
err_mask = ata_dev_set_feature(dev,
@@ -2106,6 +2113,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
static void ahci_enable_fbs(struct ata_port *ap)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
struct ahci_port_priv *pp = ap->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
u32 fbs;
@@ -2134,11 +2142,12 @@ static void ahci_enable_fbs(struct ata_port *ap)
} else
dev_err(ap->host->dev, "Failed to enable FBS\n");
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
}
static void ahci_disable_fbs(struct ata_port *ap)
{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
struct ahci_port_priv *pp = ap->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
u32 fbs;
@@ -2166,7 +2175,7 @@ static void ahci_disable_fbs(struct ata_port *ap)
pp->fbs_enabled = false;
}
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
}
static void ahci_pmp_attach(struct ata_port *ap)
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index ea3b3dc..30aa9c1 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -404,6 +404,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
static const unsigned long timing[] = { 5, 100, 500};
struct ata_port *ap = link->ap;
struct ahci_port_priv *pp = ap->private_data;
+ struct ahci_host_priv *hpriv = ap->host->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
bool online;
@@ -432,7 +433,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
break;
} while (!online && retry--);
- ahci_start_engine(ap);
+ hpriv->start_engine(ap);
if (online)
*class = ahci_dev_classify(ap);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 02/10] libahci: Move ahci_host_priv declaration to include/linux/ahci.h
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-20 16:44 ` [PATCH RFC v4 01/10] libahci: Allow drivers to override start_engine Hans de Goede
@ 2014-01-20 16:44 ` Hans de Goede
2014-01-20 16:44 ` [PATCH RFC v4 03/10] ahci-platform: Pass ahci_host_priv ptr to ahci_platform_data init method Hans de Goede
` (9 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
With the ahci-platform.c changes later in this patch-set, some
arch/arm/mach-foo/*.c sata drivers need access to ahci_host_priv, so move
its declaration outside of drivers/ata.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/ata/ahci.h | 20 +-------------------
include/linux/ahci.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 19 deletions(-)
create mode 100644 include/linux/ahci.h
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 2c04211..0f80129 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -35,7 +35,7 @@
#ifndef _AHCI_H
#define _AHCI_H
-#include <linux/clk.h>
+#include <linux/ahci.h>
#include <linux/libata.h>
/* Enclosure Management Control */
@@ -309,24 +309,6 @@ struct ahci_port_priv {
char *irq_desc; /* desc in /proc/interrupts */
};
-struct ahci_host_priv {
- void __iomem * mmio; /* bus-independent mem map */
- unsigned int flags; /* AHCI_HFLAG_* */
- u32 cap; /* cap to use */
- u32 cap2; /* cap2 to use */
- u32 port_map; /* port map to use */
- u32 saved_cap; /* saved initial cap */
- u32 saved_cap2; /* saved initial cap2 */
- u32 saved_port_map; /* saved initial port_map */
- u32 em_loc; /* enclosure management location */
- u32 em_buf_sz; /* EM buffer size in byte */
- u32 em_msg_type; /* EM message type */
- struct clk *clk; /* Only for platforms supporting clk */
- void *plat_data; /* Other platform data */
- /* Optional ahci_start_engine override */
- void (*start_engine)(struct ata_port *ap);
-};
-
extern int ahci_ignore_sss;
extern struct device_attribute *ahci_shost_attrs[];
diff --git a/include/linux/ahci.h b/include/linux/ahci.h
new file mode 100644
index 0000000..3499d44
--- /dev/null
+++ b/include/linux/ahci.h
@@ -0,0 +1,46 @@
+/*
+ * ahci.h - Common AHCI SATA definitions and declarations
+ *
+ * Maintained by: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
+ * Please ALWAYS copy linux-ide-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
+ * on emails.
+ *
+ * Copyright 2004-2005 Red Hat, Inc.
+ *
+ * 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, 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.
+ */
+
+#ifndef __LINUX_AHCI_H__
+#define __LINUX_AHCI_H__
+
+#include <linux/clk.h>
+
+struct ata_port;
+
+struct ahci_host_priv {
+ void __iomem *mmio; /* bus-independent mem map */
+ unsigned int flags; /* AHCI_HFLAG_* */
+ u32 cap; /* cap to use */
+ u32 cap2; /* cap2 to use */
+ u32 port_map; /* port map to use */
+ u32 saved_cap; /* saved initial cap */
+ u32 saved_cap2; /* saved initial cap2 */
+ u32 saved_port_map; /* saved initial port_map */
+ u32 em_loc; /* enclosure management location */
+ u32 em_buf_sz; /* EM buffer size in byte */
+ u32 em_msg_type; /* EM message type */
+ struct clk *clk; /* Optional */
+ void *plat_data; /* Other platform data */
+ /* Optional ahci_start_engine override */
+ void (*start_engine)(struct ata_port *ap);
+};
+
+#endif
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 03/10] ahci-platform: Pass ahci_host_priv ptr to ahci_platform_data init method
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-01-20 16:44 ` [PATCH RFC v4 01/10] libahci: Allow drivers to override start_engine Hans de Goede
2014-01-20 16:44 ` [PATCH RFC v4 02/10] libahci: Move ahci_host_priv declaration to include/linux/ahci.h Hans de Goede
@ 2014-01-20 16:44 ` Hans de Goede
2014-01-20 16:44 ` [PATCH RFC v4 04/10] ahci-platform: Add support for devices with more then 1 clock Hans de Goede
` (8 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
Some ahci_platform_data->init methods need access to the ahci_host_priv data.
When calling ahci_platform_data->init the ata_host has not been allocated yet,
so access to ahci_host_priv through the dev argument is not possible.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/mach-davinci/devices-da8xx.c | 5 +++--
arch/arm/mach-spear/spear1340.c | 2 +-
drivers/ata/ahci_imx.c | 12 ++++++------
drivers/ata/ahci_platform.c | 2 +-
include/linux/ahci_platform.h | 3 ++-
5 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 78829c5..28e7c4c 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/dma-contiguous.h>
#include <linux/serial_8250.h>
+#include <linux/ahci.h>
#include <linux/ahci_platform.h>
#include <linux/clk.h>
#include <linux/reboot.h>
@@ -1061,7 +1062,7 @@ static unsigned long da850_sata_xtal[] = {
KHZ_TO_HZ(60000),
};
-static int da850_sata_init(struct device *dev, void __iomem *addr)
+static int da850_sata_init(struct device *dev, struct ahci_host_priv *hpriv)
{
int i, ret;
unsigned int val;
@@ -1096,7 +1097,7 @@ static int da850_sata_init(struct device *dev, void __iomem *addr)
SATA_PHY_TXSWING(3) |
SATA_PHY_ENPLL(1);
- __raw_writel(val, addr + SATA_P0PHYCR_REG);
+ __raw_writel(val, hpriv->mmio + SATA_P0PHYCR_REG);
return 0;
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
index 3fb6834..9e2f3ac 100644
--- a/arch/arm/mach-spear/spear1340.c
+++ b/arch/arm/mach-spear/spear1340.c
@@ -77,7 +77,7 @@
SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
/* SATA device registration */
-static int sata_miphy_init(struct device *dev, void __iomem *addr)
+static int sata_miphy_init(struct device *dev, struct ahci_host_priv *hpriv)
{
writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 3e23e99..49fa0ca 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -91,7 +91,7 @@ static const struct ata_port_info ahci_imx_port_info = {
.port_ops = &ahci_imx_ops,
};
-static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
+static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv)
{
int ret = 0;
unsigned int reg_val;
@@ -145,19 +145,19 @@ static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
* Implement the port0.
* Get the ahb clock rate, and configure the TIMER1MS register.
*/
- reg_val = readl(mmio + HOST_CAP);
+ reg_val = readl(hpriv->mmio + HOST_CAP);
if (!(reg_val & HOST_CAP_SSS)) {
reg_val |= HOST_CAP_SSS;
- writel(reg_val, mmio + HOST_CAP);
+ writel(reg_val, hpriv->mmio + HOST_CAP);
}
- reg_val = readl(mmio + HOST_PORTS_IMPL);
+ reg_val = readl(hpriv->mmio + HOST_PORTS_IMPL);
if (!(reg_val & 0x1)) {
reg_val |= 0x1;
- writel(reg_val, mmio + HOST_PORTS_IMPL);
+ writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
}
reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
- writel(reg_val, mmio + HOST_TIMER1MS);
+ writel(reg_val, hpriv->mmio + HOST_TIMER1MS);
return 0;
}
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 4b231ba..434ab89 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -149,7 +149,7 @@ static int ahci_probe(struct platform_device *pdev)
* returned successfully.
*/
if (pdata && pdata->init) {
- rc = pdata->init(dev, hpriv->mmio);
+ rc = pdata->init(dev, hpriv);
if (rc)
goto disable_unprepare_clk;
}
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 73a2500..737fe38 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -19,9 +19,10 @@
struct device;
struct ata_port_info;
+struct ahci_host_priv;
struct ahci_platform_data {
- int (*init)(struct device *dev, void __iomem *addr);
+ int (*init)(struct device *dev, struct ahci_host_priv *hpriv);
void (*exit)(struct device *dev);
int (*suspend)(struct device *dev);
int (*resume)(struct device *dev);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 04/10] ahci-platform: Add support for devices with more then 1 clock
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (2 preceding siblings ...)
2014-01-20 16:44 ` [PATCH RFC v4 03/10] ahci-platform: Pass ahci_host_priv ptr to ahci_platform_data init method Hans de Goede
@ 2014-01-20 16:44 ` Hans de Goede
2014-01-20 16:44 ` [PATCH RFC v4 05/10] ahci-platform: Add support for an optional regulator for sata-target power Hans de Goede
` (7 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
The allwinner-sun4i AHCI controller needs 2 clocks to be enabled and the
imx AHCI controller needs 3 clocks to be enabled.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/ata/ahci-platform.txt | 1 +
drivers/ata/ahci_platform.c | 97 +++++++++++++++-------
include/linux/ahci.h | 4 +-
include/linux/ahci_platform.h | 3 +
4 files changed, 73 insertions(+), 32 deletions(-)
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 89de156..3ced07d 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -10,6 +10,7 @@ Required properties:
Optional properties:
- dma-coherent : Present if dma operations are coherent
+- clocks : a list of phandle + clock specifier pairs
Example:
sata@ffe08000 {
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 434ab89..aaa0c08 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -87,6 +87,44 @@ static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT("ahci_platform"),
};
+
+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv)
+{
+ int c, rc;
+
+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++) {
+ rc = clk_prepare_enable(hpriv->clks[c]);
+ if (rc)
+ goto disable_unprepare_clk;
+ }
+ return 0;
+
+disable_unprepare_clk:
+ while (--c >= 0)
+ clk_disable_unprepare(hpriv->clks[c]);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_enable_clks);
+
+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
+{
+ int c;
+
+ for (c = AHCI_MAX_CLKS - 1; c >= 0; c--)
+ if (hpriv->clks[c])
+ clk_disable_unprepare(hpriv->clks[c]);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
+
+
+static void ahci_put_clks(struct ahci_host_priv *hpriv)
+{
+ int c;
+
+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
+ clk_put(hpriv->clks[c]);
+}
+
static int ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -97,10 +135,8 @@ static int ahci_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv;
struct ata_host *host;
struct resource *mem;
- int irq;
- int n_ports;
- int i;
- int rc;
+ struct clk *clk;
+ int i, irq, max_clk, n_ports, rc;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
@@ -131,17 +167,26 @@ static int ahci_probe(struct platform_device *pdev)
return -ENOMEM;
}
- hpriv->clk = clk_get(dev, NULL);
- if (IS_ERR(hpriv->clk)) {
- dev_err(dev, "can't get clock\n");
- } else {
- rc = clk_prepare_enable(hpriv->clk);
- if (rc) {
- dev_err(dev, "clock prepare enable failed");
- goto free_clk;
+ max_clk = dev->of_node ? AHCI_MAX_CLKS : 1;
+ for (i = 0; i < max_clk; i++) {
+ if (i == 0)
+ clk = clk_get(dev, NULL); /* For old platform init */
+ else
+ clk = of_clk_get(dev->of_node, i);
+
+ if (IS_ERR(clk)) {
+ rc = PTR_ERR(clk);
+ if (rc == -EPROBE_DEFER)
+ goto free_clk;
+ break;
}
+ hpriv->clks[i] = clk;
}
+ rc = ahci_enable_clks(dev, hpriv);
+ if (rc)
+ goto free_clk;
+
/*
* Some platforms might need to prepare for mmio region access,
* which could be done in the following init call. So, the mmio
@@ -222,11 +267,9 @@ pdata_exit:
if (pdata && pdata->exit)
pdata->exit(dev);
disable_unprepare_clk:
- if (!IS_ERR(hpriv->clk))
- clk_disable_unprepare(hpriv->clk);
+ ahci_disable_clks(hpriv);
free_clk:
- if (!IS_ERR(hpriv->clk))
- clk_put(hpriv->clk);
+ ahci_put_clks(hpriv);
return rc;
}
@@ -239,10 +282,8 @@ static void ahci_host_stop(struct ata_host *host)
if (pdata && pdata->exit)
pdata->exit(dev);
- if (!IS_ERR(hpriv->clk)) {
- clk_disable_unprepare(hpriv->clk);
- clk_put(hpriv->clk);
- }
+ ahci_disable_clks(hpriv);
+ ahci_put_clks(hpriv);
}
#ifdef CONFIG_PM_SLEEP
@@ -277,8 +318,7 @@ static int ahci_suspend(struct device *dev)
if (pdata && pdata->suspend)
return pdata->suspend(dev);
- if (!IS_ERR(hpriv->clk))
- clk_disable_unprepare(hpriv->clk);
+ ahci_disable_clks(hpriv);
return 0;
}
@@ -290,13 +330,9 @@ static int ahci_resume(struct device *dev)
struct ahci_host_priv *hpriv = host->private_data;
int rc;
- if (!IS_ERR(hpriv->clk)) {
- rc = clk_prepare_enable(hpriv->clk);
- if (rc) {
- dev_err(dev, "clock prepare enable failed");
- return rc;
- }
- }
+ rc = ahci_enable_clks(dev, hpriv);
+ if (rc)
+ return rc;
if (pdata && pdata->resume) {
rc = pdata->resume(dev);
@@ -317,8 +353,7 @@ static int ahci_resume(struct device *dev)
return 0;
disable_unprepare_clk:
- if (!IS_ERR(hpriv->clk))
- clk_disable_unprepare(hpriv->clk);
+ ahci_disable_clks(hpriv);
return rc;
}
diff --git a/include/linux/ahci.h b/include/linux/ahci.h
index 3499d44..19970b0 100644
--- a/include/linux/ahci.h
+++ b/include/linux/ahci.h
@@ -23,6 +23,8 @@
#include <linux/clk.h>
+#define AHCI_MAX_CLKS 3
+
struct ata_port;
struct ahci_host_priv {
@@ -37,7 +39,7 @@ struct ahci_host_priv {
u32 em_loc; /* enclosure management location */
u32 em_buf_sz; /* EM buffer size in byte */
u32 em_msg_type; /* EM message type */
- struct clk *clk; /* Optional */
+ struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
void *plat_data; /* Other platform data */
/* Optional ahci_start_engine override */
void (*start_engine)(struct ata_port *ap);
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 737fe38..0071d0b 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -31,4 +31,7 @@ struct ahci_platform_data {
unsigned int mask_port_map;
};
+int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
+void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
+
#endif /* _AHCI_PLATFORM_H */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 05/10] ahci-platform: Add support for an optional regulator for sata-target power
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (3 preceding siblings ...)
2014-01-20 16:44 ` [PATCH RFC v4 04/10] ahci-platform: Add support for devices with more then 1 clock Hans de Goede
@ 2014-01-20 16:44 ` Hans de Goede
2014-01-20 16:44 ` [PATCH RFC v4 06/10] ahci-platform: Add enable_ / disable_resources helper functions Hans de Goede
` (6 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/ata/ahci-platform.txt | 1 +
drivers/ata/ahci_platform.c | 35 ++++++++++++++++++++--
include/linux/ahci.h | 2 ++
3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 3ced07d..1ac807f 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -11,6 +11,7 @@ Required properties:
Optional properties:
- dma-coherent : Present if dma operations are coherent
- clocks : a list of phandle + clock specifier pairs
+- target-supply : regulator for SATA target power
Example:
sata@ffe08000 {
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index aaa0c08..2f319e9 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -167,6 +167,13 @@ static int ahci_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
+ if (IS_ERR(hpriv->target_pwr)) {
+ if (PTR_ERR(hpriv->target_pwr) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ hpriv->target_pwr = NULL;
+ }
+
max_clk = dev->of_node ? AHCI_MAX_CLKS : 1;
for (i = 0; i < max_clk; i++) {
if (i == 0)
@@ -183,9 +190,15 @@ static int ahci_probe(struct platform_device *pdev)
hpriv->clks[i] = clk;
}
+ if (hpriv->target_pwr) {
+ rc = regulator_enable(hpriv->target_pwr);
+ if (rc)
+ goto free_clk;
+ }
+
rc = ahci_enable_clks(dev, hpriv);
if (rc)
- goto free_clk;
+ goto disable_regulator;
/*
* Some platforms might need to prepare for mmio region access,
@@ -268,6 +281,9 @@ pdata_exit:
pdata->exit(dev);
disable_unprepare_clk:
ahci_disable_clks(hpriv);
+disable_regulator:
+ if (hpriv->target_pwr)
+ regulator_disable(hpriv->target_pwr);
free_clk:
ahci_put_clks(hpriv);
return rc;
@@ -284,6 +300,9 @@ static void ahci_host_stop(struct ata_host *host)
ahci_disable_clks(hpriv);
ahci_put_clks(hpriv);
+
+ if (hpriv->target_pwr)
+ regulator_disable(hpriv->target_pwr);
}
#ifdef CONFIG_PM_SLEEP
@@ -320,6 +339,9 @@ static int ahci_suspend(struct device *dev)
ahci_disable_clks(hpriv);
+ if (hpriv->target_pwr)
+ regulator_disable(hpriv->target_pwr);
+
return 0;
}
@@ -330,9 +352,15 @@ static int ahci_resume(struct device *dev)
struct ahci_host_priv *hpriv = host->private_data;
int rc;
+ if (hpriv->target_pwr) {
+ rc = regulator_enable(hpriv->target_pwr);
+ if (rc)
+ return rc;
+ }
+
rc = ahci_enable_clks(dev, hpriv);
if (rc)
- return rc;
+ goto disable_regulator;
if (pdata && pdata->resume) {
rc = pdata->resume(dev);
@@ -354,6 +382,9 @@ static int ahci_resume(struct device *dev)
disable_unprepare_clk:
ahci_disable_clks(hpriv);
+disable_regulator:
+ if (hpriv->target_pwr)
+ regulator_disable(hpriv->target_pwr);
return rc;
}
diff --git a/include/linux/ahci.h b/include/linux/ahci.h
index 19970b0..ac69cdc 100644
--- a/include/linux/ahci.h
+++ b/include/linux/ahci.h
@@ -22,6 +22,7 @@
#define __LINUX_AHCI_H__
#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
#define AHCI_MAX_CLKS 3
@@ -40,6 +41,7 @@ struct ahci_host_priv {
u32 em_buf_sz; /* EM buffer size in byte */
u32 em_msg_type; /* EM message type */
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
+ struct regulator *target_pwr; /* Optional */
void *plat_data; /* Other platform data */
/* Optional ahci_start_engine override */
void (*start_engine)(struct ata_port *ap);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 06/10] ahci-platform: Add enable_ / disable_resources helper functions
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (4 preceding siblings ...)
2014-01-20 16:44 ` [PATCH RFC v4 05/10] ahci-platform: Add support for an optional regulator for sata-target power Hans de Goede
@ 2014-01-20 16:44 ` Hans de Goede
2014-01-20 16:45 ` [PATCH RFC v4 07/10] ahci-platform: "Library-ise" ahci_probe functionality Hans de Goede
` (5 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/ata/ahci_platform.c | 83 ++++++++++++++++++++++++-------------------
include/linux/ahci_platform.h | 2 ++
2 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 2f319e9..1cce7a2 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -117,6 +117,39 @@ void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
+{
+ int rc;
+
+ if (hpriv->target_pwr) {
+ rc = regulator_enable(hpriv->target_pwr);
+ if (rc)
+ return rc;
+ }
+
+ rc = ahci_platform_enable_clks(hpriv);
+ if (rc)
+ goto disable_regulator;
+
+ return 0;
+
+disable_regulator:
+ if (hpriv->target_pwr)
+ regulator_disable(hpriv->target_pwr);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
+
+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
+{
+ ahci_platform_disable_clks(hpriv);
+
+ if (hpriv->target_pwr)
+ regulator_disable(hpriv->target_pwr);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
+
+
static void ahci_put_clks(struct ahci_host_priv *hpriv)
{
int c;
@@ -190,15 +223,9 @@ static int ahci_probe(struct platform_device *pdev)
hpriv->clks[i] = clk;
}
- if (hpriv->target_pwr) {
- rc = regulator_enable(hpriv->target_pwr);
- if (rc)
- goto free_clk;
- }
-
- rc = ahci_enable_clks(dev, hpriv);
+ rc = ahci_platform_enable_resources(hpriv);
if (rc)
- goto disable_regulator;
+ goto free_clk;
/*
* Some platforms might need to prepare for mmio region access,
@@ -209,7 +236,7 @@ static int ahci_probe(struct platform_device *pdev)
if (pdata && pdata->init) {
rc = pdata->init(dev, hpriv);
if (rc)
- goto disable_unprepare_clk;
+ goto disable_resources;
}
ahci_save_initial_config(dev, hpriv,
@@ -279,11 +306,8 @@ static int ahci_probe(struct platform_device *pdev)
pdata_exit:
if (pdata && pdata->exit)
pdata->exit(dev);
-disable_unprepare_clk:
- ahci_disable_clks(hpriv);
-disable_regulator:
- if (hpriv->target_pwr)
- regulator_disable(hpriv->target_pwr);
+disable_resources:
+ ahci_platform_disable_resources(hpriv);
free_clk:
ahci_put_clks(hpriv);
return rc;
@@ -298,11 +322,8 @@ static void ahci_host_stop(struct ata_host *host)
if (pdata && pdata->exit)
pdata->exit(dev);
- ahci_disable_clks(hpriv);
+ ahci_platform_disable_resources(hpriv);
ahci_put_clks(hpriv);
-
- if (hpriv->target_pwr)
- regulator_disable(hpriv->target_pwr);
}
#ifdef CONFIG_PM_SLEEP
@@ -337,10 +358,7 @@ static int ahci_suspend(struct device *dev)
if (pdata && pdata->suspend)
return pdata->suspend(dev);
- ahci_disable_clks(hpriv);
-
- if (hpriv->target_pwr)
- regulator_disable(hpriv->target_pwr);
+ ahci_platform_disable_resources(hpriv);
return 0;
}
@@ -352,26 +370,20 @@ static int ahci_resume(struct device *dev)
struct ahci_host_priv *hpriv = host->private_data;
int rc;
- if (hpriv->target_pwr) {
- rc = regulator_enable(hpriv->target_pwr);
- if (rc)
- return rc;
- }
-
- rc = ahci_enable_clks(dev, hpriv);
+ rc = ahci_platform_enable_resources(hpriv);
if (rc)
- goto disable_regulator;
+ return rc;
if (pdata && pdata->resume) {
rc = pdata->resume(dev);
if (rc)
- goto disable_unprepare_clk;
+ goto disable_resources;
}
if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
rc = ahci_reset_controller(host);
if (rc)
- goto disable_unprepare_clk;
+ goto disable_resources;
ahci_init_controller(host);
}
@@ -380,11 +392,8 @@ static int ahci_resume(struct device *dev)
return 0;
-disable_unprepare_clk:
- ahci_disable_clks(hpriv);
-disable_regulator:
- if (hpriv->target_pwr)
- regulator_disable(hpriv->target_pwr);
+disable_resources:
+ ahci_platform_disable_resources(hpriv);
return rc;
}
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 0071d0b..5e5f85e 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -33,5 +33,7 @@ struct ahci_platform_data {
int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
#endif /* _AHCI_PLATFORM_H */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 07/10] ahci-platform: "Library-ise" ahci_probe functionality
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (5 preceding siblings ...)
2014-01-20 16:44 ` [PATCH RFC v4 06/10] ahci-platform: Add enable_ / disable_resources helper functions Hans de Goede
@ 2014-01-20 16:45 ` Hans de Goede
2014-01-20 16:45 ` [PATCH RFC v4 08/10] ahci-platform: "Library-ise" suspend / resume functionality Hans de Goede
` (4 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
ahci_probe consists of 3 steps:
1) Get resources (get mmio, clks, regulator)
2) Enable resources, handled by ahci_platform_enable_resouces
3) The more or less standard ahci-host controller init sequence
This commit refactors step 1 and 3 into separate functions, so the platform
drivers for AHCI implementations which need a specific order in step 2,
and / or need to do some custom register poking at some time, can re-use
ahci-platform.c code without needing to copy and paste it.
Note that ahci_platform_init_host's prototype takes the 3 non function
members of ahci_platform_data as arguments, the idea is that drivers using
the new exported utility functions will not use ahci_platform_data at all,
and hopefully in the future ahci_platform_data can go away entirely.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/ata/ahci_platform.c | 158 ++++++++++++++++++++++++------------------
include/linux/ahci_platform.h | 14 ++++
2 files changed, 106 insertions(+), 66 deletions(-)
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 1cce7a2..b260ebe 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -150,60 +150,31 @@ void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
-static void ahci_put_clks(struct ahci_host_priv *hpriv)
-{
- int c;
-
- for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
- clk_put(hpriv->clks[c]);
-}
-
-static int ahci_probe(struct platform_device *pdev)
+struct ahci_host_priv *ahci_platform_get_resources(
+ struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev_get_platdata(dev);
- const struct platform_device_id *id = platform_get_device_id(pdev);
- struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
- const struct ata_port_info *ppi[] = { &pi, NULL };
struct ahci_host_priv *hpriv;
- struct ata_host *host;
- struct resource *mem;
struct clk *clk;
- int i, irq, max_clk, n_ports, rc;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(dev, "no mmio space\n");
- return -EINVAL;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
- dev_err(dev, "no irq\n");
- return -EINVAL;
- }
-
- if (pdata && pdata->ata_port_info)
- pi = *pdata->ata_port_info;
+ int i, max_clk, rc;
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv) {
dev_err(dev, "can't alloc ahci_host_priv\n");
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
- hpriv->flags |= (unsigned long)pi.private_data;
-
- hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
+ hpriv->mmio = devm_ioremap_resource(dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
if (!hpriv->mmio) {
- dev_err(dev, "can't map %pR\n", mem);
- return -ENOMEM;
+ dev_err(dev, "no mmio space\n");
+ return ERR_PTR(-EINVAL);
}
hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
if (IS_ERR(hpriv->target_pwr)) {
if (PTR_ERR(hpriv->target_pwr) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ return ERR_PTR(-EPROBE_DEFER);
hpriv->target_pwr = NULL;
}
@@ -223,27 +194,48 @@ static int ahci_probe(struct platform_device *pdev)
hpriv->clks[i] = clk;
}
- rc = ahci_platform_enable_resources(hpriv);
- if (rc)
- goto free_clk;
+ return hpriv;
- /*
- * Some platforms might need to prepare for mmio region access,
- * which could be done in the following init call. So, the mmio
- * region shouldn't be accessed before init (if provided) has
- * returned successfully.
- */
- if (pdata && pdata->init) {
- rc = pdata->init(dev, hpriv);
- if (rc)
- goto disable_resources;
- }
+free_clk:
+ while (--i >= 0)
+ clk_put(hpriv->clks[i]);
+ return ERR_PTR(rc);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
+
+void ahci_platform_put_resources(struct ahci_host_priv *hpriv)
+{
+ int c;
+
+ for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
+ clk_put(hpriv->clks[c]);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_put_resources);
+
+
+int ahci_platform_init_host(struct platform_device *pdev,
+ struct ahci_host_priv *hpriv,
+ const struct ata_port_info *pi_template,
+ unsigned int force_port_map,
+ unsigned int mask_port_map)
+{
+ struct device *dev = &pdev->dev;
+ struct ata_port_info pi = *pi_template;
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+ struct ata_host *host;
+ int i, irq, n_ports, rc;
- ahci_save_initial_config(dev, hpriv,
- pdata ? pdata->force_port_map : 0,
- pdata ? pdata->mask_port_map : 0);
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "no irq\n");
+ return -EINVAL;
+ }
/* prepare host */
+ hpriv->flags |= (unsigned long)pi.private_data;
+
+ ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
+
if (hpriv->cap & HOST_CAP_NCQ)
pi.flags |= ATA_FLAG_NCQ;
@@ -260,10 +252,8 @@ static int ahci_probe(struct platform_device *pdev)
n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
host = ata_host_alloc_pinfo(dev, ppi, n_ports);
- if (!host) {
- rc = -ENOMEM;
- goto pdata_exit;
- }
+ if (!host)
+ return -ENOMEM;
host->private_data = hpriv;
@@ -278,7 +268,8 @@ static int ahci_probe(struct platform_device *pdev)
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- ata_port_desc(ap, "mmio %pR", mem);
+ ata_port_desc(ap, "mmio %pR",
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
/* set enclosure management message type */
@@ -292,13 +283,48 @@ static int ahci_probe(struct platform_device *pdev)
rc = ahci_reset_controller(host);
if (rc)
- goto pdata_exit;
+ return rc;
ahci_init_controller(host);
ahci_print_info(host, "platform");
- rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
- &ahci_platform_sht);
+ return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
+ &ahci_platform_sht);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_init_host);
+
+static int ahci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
+ const struct platform_device_id *id = platform_get_device_id(pdev);
+ struct ahci_host_priv *hpriv;
+ int rc;
+
+ hpriv = ahci_platform_get_resources(pdev);
+ if (IS_ERR(hpriv))
+ return PTR_ERR(hpriv);
+
+ rc = ahci_platform_enable_resources(hpriv);
+ if (rc)
+ goto put_resources;
+
+ /*
+ * Some platforms might need to prepare for mmio region access,
+ * which could be done in the following init call. So, the mmio
+ * region shouldn't be accessed before init (if provided) has
+ * returned successfully.
+ */
+ if (pdata && pdata->init) {
+ rc = pdata->init(dev, hpriv);
+ if (rc)
+ goto disable_resources;
+ }
+
+ rc = ahci_platform_init_host(pdev, hpriv,
+ &ahci_port_info[id ? id->driver_data : 0],
+ pdata ? pdata->force_port_map : 0,
+ pdata ? pdata->mask_port_map : 0);
if (rc)
goto pdata_exit;
@@ -308,8 +334,8 @@ pdata_exit:
pdata->exit(dev);
disable_resources:
ahci_platform_disable_resources(hpriv);
-free_clk:
- ahci_put_clks(hpriv);
+put_resources:
+ ahci_platform_put_resources(hpriv);
return rc;
}
@@ -323,7 +349,7 @@ static void ahci_host_stop(struct ata_host *host)
pdata->exit(dev);
ahci_platform_disable_resources(hpriv);
- ahci_put_clks(hpriv);
+ ahci_platform_put_resources(hpriv);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 5e5f85e..1dc7602 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -20,7 +20,13 @@
struct device;
struct ata_port_info;
struct ahci_host_priv;
+struct platform_device;
+/*
+ * Note ahci_platform_data is deprecated. New drivers which need to override
+ * any of these, should instead declare there own platform_driver struct, and
+ * use ahci_platform* functions in their own probe, suspend and resume methods.
+ */
struct ahci_platform_data {
int (*init)(struct device *dev, struct ahci_host_priv *hpriv);
void (*exit)(struct device *dev);
@@ -35,5 +41,13 @@ int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
+struct ahci_host_priv *ahci_platform_get_resources(
+ struct platform_device *pdev);
+void ahci_platform_put_resources(struct ahci_host_priv *hpriv);
+int ahci_platform_init_host(struct platform_device *pdev,
+ struct ahci_host_priv *hpriv,
+ const struct ata_port_info *pi_template,
+ unsigned int force_port_map,
+ unsigned int mask_port_map);
#endif /* _AHCI_PLATFORM_H */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 08/10] ahci-platform: "Library-ise" suspend / resume functionality
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (6 preceding siblings ...)
2014-01-20 16:45 ` [PATCH RFC v4 07/10] ahci-platform: "Library-ise" ahci_probe functionality Hans de Goede
@ 2014-01-20 16:45 ` Hans de Goede
2014-01-20 16:45 ` [PATCH RFC v4 09/10] ARM: sunxi: Add support for Allwinner SUNXi SoCs sata to ahci_platform Hans de Goede
` (3 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
Split suspend / resume code into host suspend / resume functionality and
resource enable / disabling phases, and export the new suspend_ / resume_host
functions.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
drivers/ata/ahci_platform.c | 55 +++++++++++++++++++++++++++++++------------
include/linux/ahci_platform.h | 7 ++++++
2 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index b260ebe..ba93930 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -353,14 +353,12 @@ static void ahci_host_stop(struct ata_host *host)
}
#ifdef CONFIG_PM_SLEEP
-static int ahci_suspend(struct device *dev)
+int ahci_platform_suspend_host(struct device *dev)
{
- struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->mmio;
u32 ctl;
- int rc;
if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
dev_err(dev, "firmware update required for suspend/resume\n");
@@ -377,7 +375,37 @@ static int ahci_suspend(struct device *dev)
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */
- rc = ata_host_suspend(host, PMSG_SUSPEND);
+ return ata_host_suspend(host, PMSG_SUSPEND);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
+
+int ahci_platform_resume_host(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ int rc;
+
+ if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
+ rc = ahci_reset_controller(host);
+ if (rc)
+ return rc;
+
+ ahci_init_controller(host);
+ }
+
+ ata_host_resume(host);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
+
+int ahci_platform_suspend(struct device *dev)
+{
+ struct ahci_platform_data *pdata = dev_get_platdata(dev);
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ int rc;
+
+ rc = ahci_platform_suspend_host(dev);
if (rc)
return rc;
@@ -388,8 +416,9 @@ static int ahci_suspend(struct device *dev)
return 0;
}
+EXPORT_SYMBOL_GPL(ahci_platform_suspend);
-static int ahci_resume(struct device *dev)
+int ahci_platform_resume(struct device *dev)
{
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ata_host *host = dev_get_drvdata(dev);
@@ -406,15 +435,9 @@ static int ahci_resume(struct device *dev)
goto disable_resources;
}
- if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
- rc = ahci_reset_controller(host);
- if (rc)
- goto disable_resources;
-
- ahci_init_controller(host);
- }
-
- ata_host_resume(host);
+ rc = ahci_platform_resume_host(dev);
+ if (rc)
+ goto disable_resources;
return 0;
@@ -423,9 +446,11 @@ disable_resources:
return rc;
}
+EXPORT_SYMBOL_GPL(ahci_platform_resume);
#endif
-static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
+static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
+ ahci_platform_resume);
static const struct of_device_id ahci_of_match[] = {
{ .compatible = "snps,spear-ahci", },
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 1dc7602..b484ac0 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -50,4 +50,11 @@ int ahci_platform_init_host(struct platform_device *pdev,
unsigned int force_port_map,
unsigned int mask_port_map);
+#ifdef CONFIG_PM_SLEEP
+int ahci_platform_suspend_host(struct device *dev);
+int ahci_platform_resume_host(struct device *dev);
+int ahci_platform_suspend(struct device *dev);
+int ahci_platform_resume(struct device *dev);
+#endif
+
#endif /* _AHCI_PLATFORM_H */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 09/10] ARM: sunxi: Add support for Allwinner SUNXi SoCs sata to ahci_platform
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (7 preceding siblings ...)
2014-01-20 16:45 ` [PATCH RFC v4 08/10] ahci-platform: "Library-ise" suspend / resume functionality Hans de Goede
@ 2014-01-20 16:45 ` Hans de Goede
2014-01-20 16:45 ` [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform Hans de Goede
` (2 subsequent siblings)
11 siblings, 0 replies; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
From: Olliver Schinagl <oliver-dxLnbx3+1qmEVqv0pETR8A@public.gmane.org>
This patch adds support for the ahci sata controler found on Allwinner A10
and A20 SoCs to the ahci_platform driver.
Orignally written by Olliver Schinagl using the approach of having a platform
device which probe method creates a new child platform device which gets
driven by ahci_platform.c, as done by ahci_imx.c .
Refactored by Hans de Goede to add most of the non sunxi specific functionality
to ahci_platform.c and use a platform_data pointer from of_device_id for the
sunxi specific bits.
Signed-off-by: Olliver Schinagl <oliver-dxLnbx3+1qmEVqv0pETR8A@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/ata/ahci-platform.txt | 18 +-
drivers/ata/Kconfig | 9 +
drivers/ata/Makefile | 1 +
drivers/ata/ahci_sunxi.c | 242 +++++++++++++++++++++
4 files changed, 267 insertions(+), 3 deletions(-)
create mode 100644 drivers/ata/ahci_sunxi.c
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 1ac807f..f036e786 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -4,7 +4,9 @@ SATA nodes are defined to describe on-chip Serial ATA controllers.
Each SATA controller should have its own node.
Required properties:
-- compatible : compatible list, contains "snps,spear-ahci"
+- compatible : compatible list, one of "snps,spear-ahci",
+ "snps,exynos5440-ahci", "ibm,476gtr-ahci", or
+ "allwinner,sun4i-a10-ahci"
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
@@ -13,10 +15,20 @@ Optional properties:
- clocks : a list of phandle + clock specifier pairs
- target-supply : regulator for SATA target power
-Example:
+allwinner,sun4i-a10-ahci required properties:
+- clocks : index 0 must point to the sata_ref clk, 1 to the ahb clk
+
+Examples:
sata@ffe08000 {
compatible = "snps,spear-ahci";
reg = <0xffe08000 0x1000>;
interrupts = <115>;
-
};
+
+ sata: ahci@01c18000 {
+ compatible = "allwinner,sun4i-a10-ahci";
+ reg = <0x01c18000 0x1000>;
+ interrupts = <56>;
+ clocks = <&pll6 0>, <&ahb_gates 25>;
+ target-supply = <®_ahci_5v>;
+ };
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4e73772..cc67cc0 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -106,6 +106,15 @@ config AHCI_IMX
If unsure, say N.
+config AHCI_SUNXI
+ tristate "Allwinner sunxi AHCI SATA support"
+ depends on ARCH_SUNXI && SATA_AHCI_PLATFORM
+ help
+ This option enables support for the Allwinner sunxi SoC's
+ onboard AHCI SATA.
+
+ If unsure, say N.
+
config SATA_FSL
tristate "Freescale 3.0Gbps SATA support"
depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 46518c6..246050b 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
+obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o
# SFF w/ custom DMA
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
new file mode 100644
index 0000000..b3f4463
--- /dev/null
+++ b/drivers/ata/ahci_sunxi.c
@@ -0,0 +1,242 @@
+/*
+ * Allwinner sunxi AHCI SATA platform driver
+ * Copyright 2013 Olliver Schinagl <oliver-dxLnbx3+1qmEVqv0pETR8A@public.gmane.org>
+ * Copyright 2014 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
+ * Based on code from Allwinner Technology Co., Ltd. <www.allwinnertech.com>,
+ * Daniel Wang <danielwang-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/ahci_platform.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include "ahci.h"
+
+#define AHCI_BISTAFR 0x00a0
+#define AHCI_BISTCR 0x00a4
+#define AHCI_BISTFCTR 0x00a8
+#define AHCI_BISTSR 0x00ac
+#define AHCI_BISTDECR 0x00b0
+#define AHCI_DIAGNR0 0x00b4
+#define AHCI_DIAGNR1 0x00b8
+#define AHCI_OOBR 0x00bc
+#define AHCI_PHYCS0R 0x00c0
+#define AHCI_PHYCS1R 0x00c4
+#define AHCI_PHYCS2R 0x00c8
+#define AHCI_TIMER1MS 0x00e0
+#define AHCI_GPARAM1R 0x00e8
+#define AHCI_GPARAM2R 0x00ec
+#define AHCI_PPARAMR 0x00f0
+#define AHCI_TESTR 0x00f4
+#define AHCI_VERSIONR 0x00f8
+#define AHCI_IDR 0x00fc
+#define AHCI_RWCR 0x00fc
+#define AHCI_P0DMACR 0x0170
+#define AHCI_P0PHYCR 0x0178
+#define AHCI_P0PHYSR 0x017c
+
+static void sunxi_clrbits(void __iomem *reg, u32 clr_val)
+{
+ u32 reg_val;
+
+ reg_val = readl(reg);
+ reg_val &= ~(clr_val);
+ writel(reg_val, reg);
+}
+
+static void sunxi_setbits(void __iomem *reg, u32 set_val)
+{
+ u32 reg_val;
+
+ reg_val = readl(reg);
+ reg_val |= set_val;
+ writel(reg_val, reg);
+}
+
+static void sunxi_clrsetbits(void __iomem *reg, u32 clr_val, u32 set_val)
+{
+ u32 reg_val;
+
+ reg_val = readl(reg);
+ reg_val &= ~(clr_val);
+ reg_val |= set_val;
+ writel(reg_val, reg);
+}
+
+static u32 sunxi_getbits(void __iomem *reg, u8 mask, u8 shift)
+{
+ return (readl(reg) >> shift) & mask;
+}
+
+static int ahci_sunxi_phy_init(struct device *dev, void __iomem *reg_base)
+{
+ u32 reg_val;
+ int timeout;
+
+ /* This magic is from the original code */
+ writel(0, reg_base + AHCI_RWCR);
+ mdelay(5);
+
+ sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+ (0x7 << 24),
+ (0x5 << 24) | BIT(23) | BIT(18));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS1R,
+ (0x3 << 16) | (0x1f << 8) | (0x3 << 6),
+ (0x2 << 16) | (0x6 << 8) | (0x2 << 6));
+ sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
+ sunxi_clrbits(reg_base + AHCI_PHYCS1R, BIT(19));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+ (0x7 << 20), (0x3 << 20));
+ sunxi_clrsetbits(reg_base + AHCI_PHYCS2R,
+ (0x1f << 5), (0x19 << 5));
+ mdelay(5);
+
+ sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
+
+ timeout = 0x100000;
+ do {
+ reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28);
+ } while (--timeout && (reg_val != 0x2));
+ if (!timeout) {
+ dev_err(dev, "PHY power up failed.\n");
+ return -EIO;
+ }
+
+ sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24));
+
+ timeout = 0x100000;
+ do {
+ reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24);
+ } while (--timeout && reg_val);
+ if (!timeout) {
+ dev_err(dev, "PHY calibration failed.\n");
+ return -EIO;
+ }
+ mdelay(15);
+
+ writel(0x7, reg_base + AHCI_RWCR);
+
+ return 0;
+}
+
+static void ahci_sunxi_start_engine(struct ata_port *ap)
+{
+ void __iomem *port_mmio = ahci_port_base(ap);
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+
+ /* Setup DMA before DMA start */
+ sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400);
+
+ /* Start DMA */
+ sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START);
+}
+
+static const struct ata_port_info ahci_sunxi_port_info = {
+ AHCI_HFLAGS(AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
+ AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ),
+ .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_platform_ops,
+};
+
+static int ahci_sunxi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ int rc;
+
+ hpriv = ahci_platform_get_resources(pdev);
+ if (IS_ERR(hpriv))
+ return PTR_ERR(hpriv);
+
+ hpriv->start_engine = ahci_sunxi_start_engine;
+
+ rc = ahci_platform_enable_resources(hpriv);
+ if (rc)
+ goto put_resources;
+
+ rc = ahci_sunxi_phy_init(dev, hpriv->mmio);
+ if (rc)
+ goto disable_resources;
+
+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info, 0, 0);
+ if (rc)
+ goto disable_resources;
+
+ return 0;
+
+disable_resources:
+ ahci_platform_disable_resources(hpriv);
+put_resources:
+ ahci_platform_put_resources(hpriv);
+ return rc;
+}
+
+#ifdef CONFIG_PM_SLEEP
+int ahci_sunxi_resume(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ int rc;
+
+ rc = ahci_platform_enable_resources(hpriv);
+ if (rc)
+ return rc;
+
+ rc = ahci_sunxi_phy_init(dev, hpriv->mmio);
+ if (rc)
+ goto disable_resources;
+
+ rc = ahci_platform_resume_host(dev);
+ if (rc)
+ goto disable_resources;
+
+ return 0;
+
+disable_resources:
+ ahci_platform_disable_resources(hpriv);
+ return rc;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend,
+ ahci_sunxi_resume);
+
+static const struct of_device_id ahci_sunxi_of_match[] = {
+ { .compatible = "allwinner,sun4i-a10-ahci", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
+
+static struct platform_driver ahci_sunxi_driver = {
+ .probe = ahci_sunxi_probe,
+ .remove = ata_platform_remove_one,
+ .driver = {
+ .name = "ahci-sunxi",
+ .owner = THIS_MODULE,
+ .of_match_table = ahci_sunxi_of_match,
+ .pm = &ahci_sunxi_pm_ops,
+ },
+};
+module_platform_driver(ahci_sunxi_driver);
+
+MODULE_DESCRIPTION("Allwinner sunxi AHCI SATA driver");
+MODULE_AUTHOR("Olliver Schinagl <oliver-dxLnbx3+1qmEVqv0pETR8A@public.gmane.org>");
+MODULE_LICENSE("GPL");
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (8 preceding siblings ...)
2014-01-20 16:45 ` [PATCH RFC v4 09/10] ARM: sunxi: Add support for Allwinner SUNXi SoCs sata to ahci_platform Hans de Goede
@ 2014-01-20 16:45 ` Hans de Goede
2014-01-22 6:51 ` Sascha Hauer
2014-01-20 19:53 ` [PATCH RFC v4 00/10] ahci: library-ise ahci_platform, add sunxi driver and cleanup imx driver Ezaul Zillmer
2014-02-03 16:31 ` Rob Herring
11 siblings, 1 reply; 18+ messages in thread
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
To: Tejun Heo
Cc: Oliver Schinagl, Maxime Ripard, Richard Zhu, Roger Quadros,
linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
This avoids the ugliness of creating a nested platform device from probe.
Note untested, I've ordered a wandboard to be able to test these changes.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/ata/ahci-platform.txt | 8 +-
drivers/ata/ahci_imx.c | 199 ++++++++-------------
2 files changed, 80 insertions(+), 127 deletions(-)
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index f036e786..ee3a127 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -5,8 +5,8 @@ Each SATA controller should have its own node.
Required properties:
- compatible : compatible list, one of "snps,spear-ahci",
- "snps,exynos5440-ahci", "ibm,476gtr-ahci", or
- "allwinner,sun4i-a10-ahci"
+ "snps,exynos5440-ahci", "ibm,476gtr-ahci",
+ "allwinner,sun4i-a10-ahci" or "fsl,imx6q-ahci"
- interrupts : <interrupt mapping for SATA IRQ>
- reg : <registers mapping>
@@ -18,6 +18,10 @@ Optional properties:
allwinner,sun4i-a10-ahci required properties:
- clocks : index 0 must point to the sata_ref clk, 1 to the ahb clk
+fsl,imx6q-ahci required properties:
+- clocks : index 0 must point to the sataf clk, 1 to the sata_ref
+ clk and 2 to the ahb clk
+
Examples:
sata@ffe08000 {
compatible = "snps,spear-ahci";
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 49fa0ca..3454b18 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -34,10 +34,14 @@ enum {
HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
};
+enum {
+ CLK_SATA,
+ CLK_SATA_REF,
+ CLK_AHB
+};
+
struct imx_ahci_priv {
struct platform_device *ahci_pdev;
- struct clk *sata_ref_clk;
- struct clk *ahb_clk;
struct regmap *gpr;
bool no_device;
bool first_time;
@@ -47,6 +51,8 @@ static int ahci_imx_hotplug;
module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
+static void ahci_imx_host_stop(struct ata_host *host);
+
static void ahci_imx_error_handler(struct ata_port *ap)
{
u32 reg_val;
@@ -54,7 +60,7 @@ static void ahci_imx_error_handler(struct ata_port *ap)
struct ata_host *host = dev_get_drvdata(ap->dev);
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->mmio;
- struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
+ struct imx_ahci_priv *imxpriv = hpriv->plat_data;
ahci_error_handler(ap);
@@ -75,12 +81,13 @@ static void ahci_imx_error_handler(struct ata_port *ap)
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
- clk_disable_unprepare(imxpriv->sata_ref_clk);
+ ahci_platform_disable_clks(hpriv);
imxpriv->no_device = true;
}
static struct ata_port_operations ahci_imx_ops = {
- .inherits = &ahci_platform_ops,
+ .inherits = &ahci_ops,
+ .host_stop = ahci_imx_host_stop,
.error_handler = ahci_imx_error_handler,
};
@@ -91,23 +98,38 @@ static const struct ata_port_info ahci_imx_port_info = {
.port_ops = &ahci_imx_ops,
};
-static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv)
+static int imx_ahci_probe(struct platform_device *pdev)
{
- int ret = 0;
+ struct device *dev = &pdev->dev;
+ struct ahci_host_priv *hpriv;
+ struct imx_ahci_priv *imxpriv;
unsigned int reg_val;
- struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+ int rc;
+
+ imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
+ if (!imxpriv)
+ return -ENOMEM;
+
+ hpriv = ahci_platform_get_resources(pdev);
+ if (IS_ERR(hpriv))
+ return PTR_ERR(hpriv);
+ if (!hpriv->clks[CLK_AHB]) {
+ dev_err(dev, "no ahb clk, need sata, sata_ref and ahb clks\n");
+ rc = -ENOENT;
+ goto put_resources;
+ }
+ hpriv->plat_data = imxpriv;
+
+ rc = ahci_platform_enable_resources(hpriv);
+ if (rc)
+ goto put_resources;
imxpriv->gpr =
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
if (IS_ERR(imxpriv->gpr)) {
dev_err(dev, "failed to find fsl,imx6q-iomux-gpr regmap\n");
- return PTR_ERR(imxpriv->gpr);
- }
-
- ret = clk_prepare_enable(imxpriv->sata_ref_clk);
- if (ret < 0) {
- dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret);
- return ret;
+ rc = PTR_ERR(imxpriv->gpr);
+ goto disable_resources;
}
/*
@@ -156,24 +178,45 @@ static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv)
writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
}
- reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
+ reg_val = clk_get_rate(hpriv->clks[CLK_AHB]) / 1000;
writel(reg_val, hpriv->mmio + HOST_TIMER1MS);
+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0);
+ if (rc)
+ goto disable_resources;
+
return 0;
+
+disable_resources:
+ ahci_platform_disable_resources(hpriv);
+put_resources:
+ ahci_platform_put_resources(hpriv);
+ return rc;
}
-static void imx6q_sata_exit(struct device *dev)
+static void ahci_imx_host_stop(struct ata_host *host)
{
- struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+ struct ahci_host_priv *hpriv = host->private_data;
+ struct imx_ahci_priv *imxpriv = hpriv->plat_data;
- regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+ if (!imxpriv->no_device) {
+ regmap_update_bits(imxpriv->gpr, 0x34,
+ IMX6Q_GPR13_SATA_MPLL_CLK_EN,
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
- clk_disable_unprepare(imxpriv->sata_ref_clk);
+ ahci_platform_disable_clks(hpriv);
+ }
}
static int imx_ahci_suspend(struct device *dev)
{
- struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ struct imx_ahci_priv *imxpriv = hpriv->plat_data;
+ int rc;
+
+ rc = ahci_platform_suspend_host(dev);
+ if (rc)
+ return rc;
/*
* If no_device is set, The CLKs had been gated off in the
@@ -183,7 +226,7 @@ static int imx_ahci_suspend(struct device *dev)
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
- clk_disable_unprepare(imxpriv->sata_ref_clk);
+ ahci_platform_disable_clks(hpriv);
}
return 0;
@@ -191,11 +234,13 @@ static int imx_ahci_suspend(struct device *dev)
static int imx_ahci_resume(struct device *dev)
{
- struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct ahci_host_priv *hpriv = host->private_data;
+ struct imx_ahci_priv *imxpriv = hpriv->plat_data;
int ret;
if (!imxpriv->no_device) {
- ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+ ret = ahci_platform_enable_clks(hpriv);
if (ret < 0) {
dev_err(dev, "pre-enable sata_ref clock err:%d\n", ret);
return ret;
@@ -207,123 +252,27 @@ static int imx_ahci_resume(struct device *dev)
usleep_range(1000, 2000);
}
- return 0;
+ return ahci_platform_resume_host(dev);
}
-static struct ahci_platform_data imx6q_sata_pdata = {
- .init = imx6q_sata_init,
- .exit = imx6q_sata_exit,
- .ata_port_info = &ahci_imx_port_info,
- .suspend = imx_ahci_suspend,
- .resume = imx_ahci_resume,
-};
+static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
static const struct of_device_id imx_ahci_of_match[] = {
- { .compatible = "fsl,imx6q-ahci", .data = &imx6q_sata_pdata},
+ { .compatible = "fsl,imx6q-ahci", },
{},
};
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
-static int imx_ahci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct resource *mem, *irq, res[2];
- const struct of_device_id *of_id;
- const struct ahci_platform_data *pdata = NULL;
- struct imx_ahci_priv *imxpriv;
- struct device *ahci_dev;
- struct platform_device *ahci_pdev;
- int ret;
-
- imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
- if (!imxpriv) {
- dev_err(dev, "can't alloc ahci_host_priv\n");
- return -ENOMEM;
- }
-
- ahci_pdev = platform_device_alloc("ahci", -1);
- if (!ahci_pdev)
- return -ENODEV;
-
- ahci_dev = &ahci_pdev->dev;
- ahci_dev->parent = dev;
-
- imxpriv->no_device = false;
- imxpriv->first_time = true;
- imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
- if (IS_ERR(imxpriv->ahb_clk)) {
- dev_err(dev, "can't get ahb clock.\n");
- ret = PTR_ERR(imxpriv->ahb_clk);
- goto err_out;
- }
-
- imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
- if (IS_ERR(imxpriv->sata_ref_clk)) {
- dev_err(dev, "can't get sata_ref clock.\n");
- ret = PTR_ERR(imxpriv->sata_ref_clk);
- goto err_out;
- }
-
- imxpriv->ahci_pdev = ahci_pdev;
- platform_set_drvdata(pdev, imxpriv);
-
- of_id = of_match_device(imx_ahci_of_match, dev);
- if (of_id) {
- pdata = of_id->data;
- } else {
- ret = -EINVAL;
- goto err_out;
- }
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!mem || !irq) {
- dev_err(dev, "no mmio/irq resource\n");
- ret = -ENOMEM;
- goto err_out;
- }
-
- res[0] = *mem;
- res[1] = *irq;
-
- ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
- ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
- ahci_dev->of_node = dev->of_node;
-
- ret = platform_device_add_resources(ahci_pdev, res, 2);
- if (ret)
- goto err_out;
-
- ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
- if (ret)
- goto err_out;
-
- ret = platform_device_add(ahci_pdev);
- if (ret) {
-err_out:
- platform_device_put(ahci_pdev);
- return ret;
- }
-
- return 0;
-}
-
-static int imx_ahci_remove(struct platform_device *pdev)
-{
- struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
- struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
-
- platform_device_unregister(ahci_pdev);
- return 0;
-}
static struct platform_driver imx_ahci_driver = {
.probe = imx_ahci_probe,
- .remove = imx_ahci_remove,
+ .remove = ata_platform_remove_one,
.driver = {
.name = "ahci-imx",
.owner = THIS_MODULE,
.of_match_table = imx_ahci_of_match,
+ .pm = &ahci_imx_pm_ops,
},
};
module_platform_driver(imx_ahci_driver);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform
2014-01-20 16:45 ` [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform Hans de Goede
@ 2014-01-22 6:51 ` Sascha Hauer
[not found] ` <20140122065151.GC16215-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Sascha Hauer @ 2014-01-22 6:51 UTC (permalink / raw)
To: Hans de Goede
Cc: Tejun Heo, Oliver Schinagl, Maxime Ripard, Richard Zhu,
Roger Quadros, linux-ide, linux-arm-kernel, devicetree,
linux-sunxi
Hi Hans,
On Mon, Jan 20, 2014 at 05:45:03PM +0100, Hans de Goede wrote:
> This avoids the ugliness of creating a nested platform device from probe.
>
> Note untested, I've ordered a wandboard to be able to test these changes.
Looks much better now, thanks. I could test this patch aswell, no need
to buy new hardware for this.
Sascha
--
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 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH RFC v4 00/10] ahci: library-ise ahci_platform, add sunxi driver and cleanup imx driver
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (9 preceding siblings ...)
2014-01-20 16:45 ` [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform Hans de Goede
@ 2014-01-20 19:53 ` Ezaul Zillmer
[not found] ` <b8dd9fd4-02ce-4656-8b92-49f2ab82cc69-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org>
2014-02-03 16:31 ` Rob Herring
11 siblings, 1 reply; 18+ messages in thread
From: Ezaul Zillmer @ 2014-01-20 19:53 UTC (permalink / raw)
To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Tejun Heo, Oliver Schinagl, Maxime Ripard, Richard Zhu,
Roger Quadros, linux-ide-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree
[-- Attachment #1: Type: text/plain, Size: 4991 bytes --]
hi Hans
First wanted to thank his work with sunxi ... as they say here in Brazil
you're the guy !
I noticed the following after your upgrade .. 01/20/2014 my ATA does not
look rose more !
# # # # Here before UP ! # # # # #
Image Name : Linux - 3.13.0 - rc7
[ 1.150317 ] 8021Q : 802.1Q VLAN Support v1.8
[ 1.154585 ] Key type dns_resolver registered
[ 1.159130 ] Registering SWP / SWPB emulation handler
[ 1.165146 ] ahci - 5v : 5000 mV
[ 1.168509 ] usb1 - VBUS : 5000 mV
[ 1.172082 ] usb2 - VBUS : 5000 mV
[ 1.200799 ] ahci sunxi - 1c18000.ahci : controller can not do PMP ,
turning off CAP_PMP
[ 1.208303 ] sunxi 1c18000.ahci - ahci : forcing PORTS_IMPL to 0x1
[ 1.214179 ] sunxi 1c18000.ahci - ahci : AHCI 0001.0100 32 slots 1 ports 3
Gbps 0x1 impl sunxi mode
[ 1.222903 ] sunxi 1c18000.ahci - ahci : flags : NCQ SNTF pm led clo pio
slum part ccc only
[ 1.231594 ] scsi0 : sunxi_ahci
[ 1.234955 ] ATA1 : SATA max UDMA/133 irq 88
[ 1.239639 ] ehci - sunxi 1c14000.ehci0 : EHCI Host Controller
[ 1.245171 ] ehci - sunxi 1c14000.ehci0 : new USB bus registered , assigned
bus number 2
[ 1.252978 ] ehci - sunxi 1c14000.ehci0 : irq 71 , io mem 0x01c14000
[ 1.269124 ] ehci - sunxi 1c14000.ehci0 : USB 2.0 started , EHCI 1:00
[ 1.275924 ] hub 2-0:1.0 : USB hub found
[ 1.279773 ] hub 2-0:1.0 : 1 port detected
[ 1.284455 ] ehci - sunxi 1c1c000.ehci1 : EHCI Host Controller
[ 1.290026 ] ehci - sunxi 1c1c000.ehci1 : new USB bus registered , assigned
bus number 3
[ 1.297789 ] ehci - sunxi 1c1c000.ehci1 : irq 72 , io mem 0x01c1c000
[ 1.319118 ] ehci - sunxi 1c1c000.ehci1 : USB 2.0 started , EHCI 1:00
[ 1.325805 ] hub 3-0:1.0 : USB hub found
[ 1.329639 ] hub 3-0:1.0 : 1 port detected
[ 1.333894 ] rtc - sunxi 1c20d00.rtc : setting system clock to 1970-01-01
00:00:08 UTC ( 8 )
[ 1.584180 ] mmc0 : new high speed SDHC card at address E624
[ 1.590049 ] isa bounce pool size: 16 pages
[ 1.594297 ] mmcblk0 : mmc0 : E624 SU08G 7:40 GiB
[ 1.600605 ] mmcblk0 : p1
[ 4.889135 ] ATA1 : SATA link up 3.0 Gbps ( sstatus 123 SControl 300 )
[ 4.904967 ] ata1.00 : ATA - 8 : SAMSUNG HM320II , 2AC101C4 , max UDMA/133
[ 4.911260 ] ata1.00 : 625142448 sectors , multi 0 : LBA48 NCQ (depth 31/32
)
[ 4.927633 ] ata1.00 : configured for UDMA/133
[ 4.932311 ] scsi 0:0:0:0 : Direct -Access ATA SAMSUNG HM320II 2AC1 PQ : 0
ANSI : 5
[ 4.941156 ] sd 0:0:0:0 : [ sda ] 625142448 512 - byte logical blocks : (
320 GB/298 GiB )
[ 4.948875 ] sd 0:0:0:0 : [ sda ] Write Protect is off
[ 4.953822 ] sd 0:0:0:0 : [ sda ] Write cache : enabled , read cache :
enabled , does not support DPO or FUA
[ 4.975349 ] sda : sda1
[ 4.978721 ] sd 0:0:0:0 : [ sda ] Attached SCSI disk
[ 5.000798 ] EXT4 - fs ( mmcblk0p1 ) : mounted filesystem with ordered data
mode . Opts : ( null)
[ 5.008962 ] VFS : Mounted root ( ext4 filesystem ) readonly on device
179:1 .
[ 5.016841 ] devtmpfs : mounted
[ 5.020432 ] Freeing unused kernel memory: 528k ( c0922000 - c09a6000 )
INIT : version 2.88 booting
# # # # NOW AFTER UP # # # # # # # # # # #
Even . Config
git pull
[ 1.183099 ] ip6_tables : ( C ) 2000-2006 Netfilter Core Team
[ 1.188522 ] sit : IPv6 over IPv4 tunneling driver
[ 1.193777 ] NET : Registered protocol family 17
[ 1.198369 ] Bridge firewalling registered
[ 1.202495 ] l2tp_core : L2TP core driver , V2.0
[ 1.206861 ] 8021Q : 802.1Q VLAN Support v1.8
[ 1.210139 ] ATA1 : SATA link down ( sstatus 0 SControl 300 )
[ 1.216491 ] lib80211 : common routines for IEEE802.11 drivers
[ 1.222231 ] Key type dns_resolver registered
[ 1.226770 ] Registering SWP / SWPB emulation handler
[ 1.232696 ] ahci - 5v : 5000 mV
[ 1.236057 ] usb1 - VBUS : 5000 mV
[ 1.239504 ] usb2 - VBUS : 5000 mV
[ 1.243904 ] rtc - sunxi 1c20d00.rtc : setting system clock to 1970-01-01
00:00:08 UTC ( 8 )
[ 1.252615 ] Waiting for device / dev/mmcblk0p1 root ...
[ 1.599045 ] mmc0 : new high speed SDHC card at address E624
[ 1.604917 ] isa bounce pool size: 16 pages
[ 1.609178 ] mmcblk0 : mmc0 : E624 SU08G 7:40 GiB
[ 1.615470 ] mmcblk0 : p1
[ 1.692426 ] EXT4 - fs ( mmcblk0p1 ) : INFO : recovery required on readonly
filesystem
[ 1.699757 ] EXT4 - fs ( mmcblk0p1 ) : write access will be enabled During
recovery
[ 2.423617 ] random: nonblocking pool is initialized
[ 3.274181 ] EXT4 - fs ( mmcblk0p1 ) : recovery complete
[ 3.286043 ] EXT4 - fs ( mmcblk0p1 ) : mounted filesystem with ordered data
mode . Opts : ( null)
[ 3.294229 ] VFS : Mounted root ( ext4 filesystem ) readonly on device
179:1 .
[ 3.302179 ] devtmpfs : mounted
[ 3.305714 ] Freeing unused kernel memory: 524K ( c0959000 - c09dc000 )
INIT : version 2.88 booting
What could it be? says Down !
Copy your old uImage UP
new uImage DOWN
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
[-- Attachment #2: Type: text/html, Size: 6103 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH RFC v4 00/10] ahci: library-ise ahci_platform, add sunxi driver and cleanup imx driver
[not found] ` <1390236303-22538-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (10 preceding siblings ...)
2014-01-20 19:53 ` [PATCH RFC v4 00/10] ahci: library-ise ahci_platform, add sunxi driver and cleanup imx driver Ezaul Zillmer
@ 2014-02-03 16:31 ` Rob Herring
[not found] ` <CAL_JsqKnus+9rgLAQ990eD-1F6-2G-SuqYuPkmc+Tw6QP1CT4g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
11 siblings, 1 reply; 18+ messages in thread
From: Rob Herring @ 2014-02-03 16:31 UTC (permalink / raw)
To: Hans de Goede
Cc: Tejun Heo, devicetree, linux-ide-u79uwXL29TY76Z2rM5mHXA,
Oliver Schinagl, Richard Zhu, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Roger Quadros
On Mon, Jan 20, 2014 at 10:44 AM, Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Hi All,
>
> Here is v4 of my patchset for adding ahci-sunxi support. It has grown quite
> a bit since I've been going for a more generic approach this time and I've
> also cleaned up the ahci-imx driver to use the same generic approach.
I don't know if you missed it or just don't intend to refactor all
AHCI drivers, but the highbank driver could benefit from this as well.
Rob
>
> History:
>
> v1, by Olliver Schinagl:
> This was using the approach of having a platform device which probe method
> creates a new child platform device which gets driven by ahci_platform.c,
> as done by ahci_imx.c .
>
> v2, by Hans de Goede:
> Stand-alone platform driver based on Olliver's work
>
> v3, by Hans de Goede:
> patch-series, with 4 different parts
> a) Make ahci_platform.c more generic, handle more then 1 clk, target pwr
> regulator
> b) New ahci-sunxi code only populating ahci_platform_data, passed to
> ahci_platform.c to of_device_id matching.
> c) Refactor ahci-imx code to work the same as the new ahci-sunxi code, this
> is the reason why v3 is an RFC, I'm waiting for the wandboard I ordered to
> arrive so that I can actually test this.
> d) dts bindings for the sunxi ahci parts
>
> v4, by Hans de Goede:
> patch-series, with 5 different parts:
> a) Make ahci_platform.c more generic, handle more then 1 clk, target pwr
> regulator
> b) Turn parts of ahci_platform.c into a library for use by other drivers
> c) New ahci-sunxi driver using the ahci_platform.c library functionality
> d) Refactor ahci-imx code to work the same as the new ahci-sunxi code
> e) dts bindings for the sunxi ahci parts
>
> Parts a-d are intended for merging through the ata tree, the dts bindings
> will be merged to Maxime Ripard's sunxi-dts tree.
>
> Regards,
>
> Hans
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread