aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasanth Ananthan <vasanthananthan@gmail.com>2012-10-30 12:29:33 +0100
committerAndrey Konovalov <andrey.konovalov@linaro.org>2014-02-12 03:21:11 +0400
commit847d1a38c8ce662df03c2abf3d39c6750f4a2e0f (patch)
tree23452e2bb2ab692d246e28753b93448656eeec39
parent400675ab162af472dcd74d04fee787e26365397e (diff)
ata: Add SATA PHY utility framework
This patch adds SATA PHY utility framework APIs. The framework acts as an interface between the SATA device and the PHY device. The SATA PHY device registers itself with the framework through the APIs provided and the SATA device finds and requests for an appropriate PHY device. Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
-rw-r--r--drivers/ata/Kconfig10
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/sata_phy.c104
-rw-r--r--drivers/ata/sata_phy.h44
4 files changed, 159 insertions, 0 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4e737728aee2..e9136ade4488 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -97,6 +97,16 @@ config SATA_AHCI_PLATFORM
If unsure, say N.
+config SATA_PHY
+ bool "SATA PHY Framework"
+ default n
+ help
+ This option enables the SATA PHY utility framework APIs.
+ The framework acts as an interface between the SATA device
+ and the PHY device. The SATA PHY device registers itself
+ with the framework through the APIs provided and the SATA
+ device finds and requests for an appropriate PHY device.
+
config AHCI_IMX
tristate "Freescale i.MX AHCI SATA support"
depends on SATA_AHCI_PLATFORM && MFD_SYSCON
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 46518c622460..a49857393b5a 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
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_SATA_PHY) += sata_phy.o
obj-$(CONFIG_AHCI_IMX) += ahci_imx.o
# SFF w/ custom DMA
diff --git a/drivers/ata/sata_phy.c b/drivers/ata/sata_phy.c
new file mode 100644
index 000000000000..e5631a97951f
--- /dev/null
+++ b/drivers/ata/sata_phy.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - SATA utility framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include "sata_phy.h"
+
+static LIST_HEAD(phy_list);
+static DEFINE_SPINLOCK(phy_lock);
+
+struct sata_phy *sata_get_phy(enum sata_phy_type type)
+{
+ struct sata_phy *x = NULL;
+ unsigned long flag;
+
+ if (list_empty(&phy_list))
+ return x;
+
+ spin_lock_irqsave(&phy_lock, flag);
+
+ list_for_each_entry(x, &phy_list, head) {
+ if (x->type == type) {
+ get_device(x->dev);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&phy_lock, flag);
+ return x;
+}
+EXPORT_SYMBOL(sata_get_phy);
+
+int sata_add_phy(struct sata_phy *phy, enum sata_phy_type type)
+{
+ unsigned long flag;
+ unsigned int ret = -EINVAL;
+ struct sata_phy *x;
+
+ spin_lock_irqsave(&phy_lock, flag);
+
+ if (!phy)
+ return ret;
+
+ list_for_each_entry(x, &phy_list, head) {
+ if (x->type == type) {
+ dev_err(phy->dev, "transceiver type already exists\n");
+ goto out;
+ }
+ }
+ phy->type = type;
+ list_add_tail(&phy->head, &phy_list);
+ ret = 0;
+
+ out:
+ spin_unlock_irqrestore(&phy_lock, flag);
+ return ret;
+}
+EXPORT_SYMBOL(sata_add_phy);
+
+void sata_remove_phy(struct sata_phy *phy)
+{
+ unsigned long flag;
+ struct sata_phy *x;
+
+ spin_lock_irqsave(&phy_lock, flag);
+
+ if (!phy)
+ return;
+
+ list_for_each_entry(x, &phy_list, head) {
+ if (x->type == phy->type)
+ list_del(&phy->head);
+ }
+
+ spin_unlock_irqrestore(&phy_lock, flag);
+}
+EXPORT_SYMBOL(sata_remove_phy);
+
+void sata_put_phy(struct sata_phy *phy)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&phy_lock, flag);
+
+ if (!phy)
+ return;
+
+ put_device(phy->dev);
+ spin_unlock_irqrestore(&phy_lock, flag);
+
+}
+EXPORT_SYMBOL(sata_put_phy);
diff --git a/drivers/ata/sata_phy.h b/drivers/ata/sata_phy.h
new file mode 100644
index 000000000000..dc38683052e3
--- /dev/null
+++ b/drivers/ata/sata_phy.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - SATA utility framework definitions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+enum sata_phy_type {
+ SATA_PHY_GENERATION1,
+ SATA_PHY_GENERATION2,
+ SATA_PHY_GENERATION3,
+};
+
+struct sata_phy {
+ int (*init) (struct sata_phy *);
+ int (*shutdown) (struct sata_phy *);
+ struct device *dev;
+ void *priv_data;
+ enum sata_phy_type type;
+ struct list_head head;
+};
+
+static inline int sata_init_phy(struct sata_phy *x)
+{
+ if (x && x->init)
+ return x->init(x);
+
+ return -EINVAL;
+}
+
+static inline void sata_shutdown_phy(struct sata_phy *x)
+{
+ if (x && x->shutdown)
+ x->shutdown(x);
+}
+
+struct sata_phy *sata_get_phy(enum sata_phy_type);
+int sata_add_phy(struct sata_phy *, enum sata_phy_type);
+void sata_remove_phy(struct sata_phy *);
+void sata_put_phy(struct sata_phy *);