diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/Kconfig | 10 | ||||
-rw-r--r-- | drivers/ata/Makefile | 1 | ||||
-rw-r--r-- | drivers/ata/sata_phy.c | 104 | ||||
-rw-r--r-- | drivers/ata/sata_phy.h | 44 |
4 files changed, 159 insertions, 0 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 868429a47be..a6aff18350b 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 46518c62246..a49857393b5 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 00000000000..e5631a97951 --- /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 00000000000..dc38683052e --- /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 *); |