* [PATCH v4 0/4] AHCI: Optimize interrupt processing in multi-MSI mode
@ 2014-09-25 13:13 Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 1/4] AHCI: Cleanup checking of multiple MSIs/SLM modes Alexander Gordeev
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-25 13:13 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev
Changes since v3:
- series rebased on libata/for-3.18;
- single IRQ interrupt update removed, along with patches 4,5
"AHCI: Get rid of redundant arg to ahci_handle_port_interrupt()"
"AHCI: Optimize single IRQ interrupt processing" removed;
- multi-MSI updated to skip zero value port status;
Changes since v2:
- single patch split in a series;
- benchmarking statistics reworded;
- HOST_IRQ_STAT reg optimization added (patch 6);
Alexander Gordeev (4):
AHCI: Cleanup checking of multiple MSIs/SLM modes
AHCI: Move host activation code into ahci_host_activate()
AHCI: Make few function names more descriptive
AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode
drivers/ata/acard-ahci.c | 3 +-
drivers/ata/ahci.c | 80 ++---------------------
drivers/ata/ahci.h | 7 +-
drivers/ata/libahci.c | 145 ++++++++++++++++++++++++++---------------
drivers/ata/libahci_platform.c | 3 +-
5 files changed, 102 insertions(+), 136 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 1/4] AHCI: Cleanup checking of multiple MSIs/SLM modes
2014-09-25 13:13 [PATCH v4 0/4] AHCI: Optimize interrupt processing in multi-MSI mode Alexander Gordeev
@ 2014-09-25 13:13 ` Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate() Alexander Gordeev
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-25 13:13 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, linux-ide
Sharing Last Message (SLM) mode is currently checked in two
functions: ahci_host_activate() and ahci_init_interrupts().
This update consolidates SLM mode check with activation of
multiple MSIs mode.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/ahci.c | 18 +++++++-----------
drivers/ata/ahci.h | 2 +-
2 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index c880699..f68a995 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1211,6 +1211,9 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
goto single_msi;
}
+ if (nvec > 1)
+ hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
+
return nvec;
single_msi:
@@ -1227,7 +1230,6 @@ intx:
* ahci_host_activate - start AHCI host, request IRQs and register it
* @host: target ATA host
* @irq: base IRQ number to request
- * @n_msis: number of MSIs allocated for this host
* @irq_handler: irq_handler used when requesting IRQs
* @irq_flags: irq_flags used when requesting IRQs
*
@@ -1241,14 +1243,10 @@ intx:
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis)
+int ahci_host_activate(struct ata_host *host, int irq)
{
int i, rc;
- /* Sharing Last Message among several ports is not supported */
- if (n_msis < host->n_ports)
- return -EINVAL;
-
rc = ata_host_start(host);
if (rc)
return rc;
@@ -1296,7 +1294,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
struct ata_host *host;
- int n_ports, n_msis, i, rc;
+ int n_ports, i, rc;
int ahci_pci_bar = AHCI_PCI_BAR_STANDARD;
VPRINTK("ENTER\n");
@@ -1437,9 +1435,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
- n_msis = ahci_init_interrupts(pdev, n_ports, hpriv);
- if (n_msis > 1)
- hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
+ ahci_init_interrupts(pdev, n_ports, hpriv);
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host)
@@ -1492,7 +1488,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
- return ahci_host_activate(host, pdev->irq, n_msis);
+ return ahci_host_activate(host, pdev->irq);
return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
&ahci_sht);
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 90156ff..a074c73 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -392,7 +392,7 @@ irqreturn_t ahci_interrupt(int irq, void *dev_instance);
irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance);
irqreturn_t ahci_thread_fn(int irq, void *dev_instance);
void ahci_print_info(struct ata_host *host, const char *scc_s);
-int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis);
+int ahci_host_activate(struct ata_host *host, int irq);
void ahci_error_handler(struct ata_port *ap);
static inline void __iomem *__ahci_port_base(struct ata_host *host,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate()
2014-09-25 13:13 [PATCH v4 0/4] AHCI: Optimize interrupt processing in multi-MSI mode Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 1/4] AHCI: Cleanup checking of multiple MSIs/SLM modes Alexander Gordeev
@ 2014-09-25 13:13 ` Alexander Gordeev
2014-09-28 16:04 ` Tejun Heo
2014-09-25 13:13 ` [PATCH v4 3/4] AHCI: Make few function names more descriptive Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 4/4] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode Alexander Gordeev
3 siblings, 1 reply; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-25 13:13 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, linux-ide
Currently host activation done by calling either function
ahci_host_activate() or ata_host_activate(). Consolidate
the code by only calling ahci_host_activate() for all AHCI
devices.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/acard-ahci.c | 3 +-
drivers/ata/ahci.c | 66 +--------------------------------
drivers/ata/ahci.h | 6 +--
drivers/ata/libahci.c | 84 +++++++++++++++++++++++++++++++++++++++---
drivers/ata/libahci_platform.c | 3 +-
5 files changed, 83 insertions(+), 79 deletions(-)
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c
index 25d0ac3..c962886 100644
--- a/drivers/ata/acard-ahci.c
+++ b/drivers/ata/acard-ahci.c
@@ -498,8 +498,7 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id
acard_ahci_pci_print_info(host);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
- &acard_ahci_sht);
+ return ahci_host_activate(host, pdev->irq, &acard_ahci_sht);
}
module_pci_driver(acard_ahci_pci_driver);
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f68a995..d0ac38b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1226,66 +1226,6 @@ intx:
return 0;
}
-/**
- * ahci_host_activate - start AHCI host, request IRQs and register it
- * @host: target ATA host
- * @irq: base IRQ number to request
- * @irq_handler: irq_handler used when requesting IRQs
- * @irq_flags: irq_flags used when requesting IRQs
- *
- * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
- * when multiple MSIs were allocated. That is one MSI per port, starting
- * from @irq.
- *
- * LOCKING:
- * Inherited from calling layer (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ahci_host_activate(struct ata_host *host, int irq)
-{
- int i, rc;
-
- rc = ata_host_start(host);
- if (rc)
- return rc;
-
- for (i = 0; i < host->n_ports; i++) {
- struct ahci_port_priv *pp = host->ports[i]->private_data;
-
- /* Do not receive interrupts sent by dummy ports */
- if (!pp) {
- disable_irq(irq + i);
- continue;
- }
-
- rc = devm_request_threaded_irq(host->dev, irq + i,
- ahci_hw_interrupt,
- ahci_thread_fn, IRQF_SHARED,
- pp->irq_desc, host->ports[i]);
- if (rc)
- goto out_free_irqs;
- }
-
- for (i = 0; i < host->n_ports; i++)
- ata_port_desc(host->ports[i], "irq %d", irq + i);
-
- rc = ata_host_register(host, &ahci_sht);
- if (rc)
- goto out_free_all_irqs;
-
- return 0;
-
-out_free_all_irqs:
- i = host->n_ports;
-out_free_irqs:
- for (i--; i >= 0; i--)
- devm_free_irq(host->dev, irq + i, host->ports[i]);
-
- return rc;
-}
-
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned int board_id = ent->driver_data;
@@ -1487,11 +1427,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
- return ahci_host_activate(host, pdev->irq);
-
- return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
- &ahci_sht);
+ return ahci_host_activate(host, pdev->irq, &ahci_sht);
}
module_pci_driver(ahci_pci_driver);
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index a074c73..6a22055 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -388,11 +388,9 @@ int ahci_port_resume(struct ata_port *ap);
void ahci_set_em_messages(struct ahci_host_priv *hpriv,
struct ata_port_info *pi);
int ahci_reset_em(struct ata_host *host);
-irqreturn_t ahci_interrupt(int irq, void *dev_instance);
-irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance);
-irqreturn_t ahci_thread_fn(int irq, void *dev_instance);
void ahci_print_info(struct ata_host *host, const char *scc_s);
-int ahci_host_activate(struct ata_host *host, int irq);
+int ahci_host_activate(struct ata_host *host, int irq,
+ struct scsi_host_template *sht);
void ahci_error_handler(struct ata_port *ap);
static inline void __iomem *__ahci_port_base(struct ata_host *host,
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index b784e9d..0080551 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1789,7 +1789,7 @@ static void ahci_port_intr(struct ata_port *ap)
ahci_handle_port_interrupt(ap, port_mmio, status);
}
-irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
+static irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
{
struct ata_port *ap = dev_instance;
struct ahci_port_priv *pp = ap->private_data;
@@ -1809,7 +1809,6 @@ irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-EXPORT_SYMBOL_GPL(ahci_thread_fn);
static void ahci_hw_port_interrupt(struct ata_port *ap)
{
@@ -1823,7 +1822,7 @@ static void ahci_hw_port_interrupt(struct ata_port *ap)
pp->intr_status |= status;
}
-irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
+static irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
{
struct ata_port *ap_this = dev_instance;
struct ahci_port_priv *pp = ap_this->private_data;
@@ -1877,9 +1876,8 @@ irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
return IRQ_WAKE_THREAD;
}
-EXPORT_SYMBOL_GPL(ahci_hw_interrupt);
-irqreturn_t ahci_interrupt(int irq, void *dev_instance)
+static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
@@ -1938,7 +1936,6 @@ irqreturn_t ahci_interrupt(int irq, void *dev_instance)
return IRQ_RETVAL(handled);
}
-EXPORT_SYMBOL_GPL(ahci_interrupt);
unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{
@@ -2472,6 +2469,81 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
}
EXPORT_SYMBOL_GPL(ahci_set_em_messages);
+static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq,
+ struct scsi_host_template *sht)
+{
+ int i, rc;
+
+ rc = ata_host_start(host);
+ if (rc)
+ return rc;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ahci_port_priv *pp = host->ports[i]->private_data;
+
+ /* Do not receive interrupts sent by dummy ports */
+ if (!pp) {
+ disable_irq(irq + i);
+ continue;
+ }
+
+ rc = devm_request_threaded_irq(host->dev, irq + i,
+ ahci_hw_interrupt,
+ ahci_thread_fn, IRQF_SHARED,
+ pp->irq_desc, host->ports[i]);
+ if (rc)
+ goto out_free_irqs;
+ }
+
+ for (i = 0; i < host->n_ports; i++)
+ ata_port_desc(host->ports[i], "irq %d", irq + i);
+
+ rc = ata_host_register(host, sht);
+ if (rc)
+ goto out_free_all_irqs;
+
+ return 0;
+
+out_free_all_irqs:
+ i = host->n_ports;
+out_free_irqs:
+ for (i--; i >= 0; i--)
+ devm_free_irq(host->dev, irq + i, host->ports[i]);
+
+ return rc;
+}
+
+/**
+ * ahci_host_activate - start AHCI host, request IRQs and register it
+ * @host: target ATA host
+ * @irq: base IRQ number to request
+ * @sht: scsi_host_template to use when registering the host
+ *
+ * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
+ * when multiple MSIs were allocated. That is one MSI per port, starting
+ * from @irq.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ahci_host_activate(struct ata_host *host, int irq,
+ struct scsi_host_template *sht)
+{
+ struct ahci_host_priv *hpriv = host->private_data;
+ int rc;
+
+ if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
+ rc = ahci_host_activate_multi_irqs(host, irq, sht);
+ else
+ rc = ata_host_activate(host, irq, ahci_interrupt,
+ IRQF_SHARED, sht);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_host_activate);
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Common AHCI SATA low-level routines");
MODULE_LICENSE("GPL");
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index c7f787e..0b03f90 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -493,8 +493,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
ahci_init_controller(host);
ahci_print_info(host, "platform");
- return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
- &ahci_platform_sht);
+ return ahci_host_activate(host, irq, &ahci_platform_sht);
}
EXPORT_SYMBOL_GPL(ahci_platform_init_host);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 3/4] AHCI: Make few function names more descriptive
2014-09-25 13:13 [PATCH v4 0/4] AHCI: Optimize interrupt processing in multi-MSI mode Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 1/4] AHCI: Cleanup checking of multiple MSIs/SLM modes Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate() Alexander Gordeev
@ 2014-09-25 13:13 ` Alexander Gordeev
2014-09-28 16:04 ` Tejun Heo
2014-09-25 13:13 ` [PATCH v4 4/4] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode Alexander Gordeev
3 siblings, 1 reply; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-25 13:13 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, linux-ide
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/libahci.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 0080551..48175e5 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1789,7 +1789,7 @@ static void ahci_port_intr(struct ata_port *ap)
ahci_handle_port_interrupt(ap, port_mmio, status);
}
-static irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
+static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
{
struct ata_port *ap = dev_instance;
struct ahci_port_priv *pp = ap->private_data;
@@ -1810,7 +1810,7 @@ static irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-static void ahci_hw_port_interrupt(struct ata_port *ap)
+static void ahci_update_intr_status(struct ata_port *ap)
{
void __iomem *port_mmio = ahci_port_base(ap);
struct ahci_port_priv *pp = ap->private_data;
@@ -1822,7 +1822,7 @@ static void ahci_hw_port_interrupt(struct ata_port *ap)
pp->intr_status |= status;
}
-static irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
+static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance)
{
struct ata_port *ap_this = dev_instance;
struct ahci_port_priv *pp = ap_this->private_data;
@@ -1858,7 +1858,7 @@ static irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
ap = host->ports[i];
if (ap) {
- ahci_hw_port_interrupt(ap);
+ ahci_update_intr_status(ap);
VPRINTK("port %u\n", i);
} else {
VPRINTK("port %u (no irq)\n", i);
@@ -1877,7 +1877,7 @@ static irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
return IRQ_WAKE_THREAD;
}
-static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
+static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
@@ -2488,8 +2488,8 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq,
}
rc = devm_request_threaded_irq(host->dev, irq + i,
- ahci_hw_interrupt,
- ahci_thread_fn, IRQF_SHARED,
+ ahci_multi_irqs_intr,
+ ahci_port_thread_fn, IRQF_SHARED,
pp->irq_desc, host->ports[i]);
if (rc)
goto out_free_irqs;
@@ -2538,7 +2538,7 @@ int ahci_host_activate(struct ata_host *host, int irq,
if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
rc = ahci_host_activate_multi_irqs(host, irq, sht);
else
- rc = ata_host_activate(host, irq, ahci_interrupt,
+ rc = ata_host_activate(host, irq, ahci_single_irq_intr,
IRQF_SHARED, sht);
return rc;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 4/4] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode
2014-09-25 13:13 [PATCH v4 0/4] AHCI: Optimize interrupt processing in multi-MSI mode Alexander Gordeev
` (2 preceding siblings ...)
2014-09-25 13:13 ` [PATCH v4 3/4] AHCI: Make few function names more descriptive Alexander Gordeev
@ 2014-09-25 13:13 ` Alexander Gordeev
2014-09-28 16:10 ` Tejun Heo
3 siblings, 1 reply; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-25 13:13 UTC (permalink / raw)
To: linux-kernel; +Cc: Alexander Gordeev, linux-ide
As described in AHCI v1.0 specification chapter 10.6.2.2
"Multiple MSI Based Messages" generation of interrupts
is not controlled through the HOST_IRQ_STAT register.
Considering MMIO access is expensive remove unnecessary
reading and writing of HOST_IRQ_STAT register.
Further, serializing access to the host data is no longer
needed and the interrupt service routine can avoid competing
on the host lock.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Suggested-by: "Jiang, Dave" <dave.jiang@intel.com>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/ahci.h | 1 +
drivers/ata/libahci.c | 59 +++++++++++----------------------------------------
2 files changed, 13 insertions(+), 47 deletions(-)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 6a22055..e5c6048 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -305,6 +305,7 @@ struct ahci_port_priv {
unsigned int ncq_saw_dmas:1;
unsigned int ncq_saw_sdb:1;
u32 intr_status; /* interrupts to handle */
+ spinlock_t intr_lock; /* protects intr_status */
spinlock_t lock; /* protects parent ata_port */
u32 intr_mask; /* interrupts to enable */
bool fbs_supported; /* set iff FBS is supported */
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 48175e5..fafa7f0 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1797,11 +1797,14 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
unsigned long flags;
u32 status;
- spin_lock_irqsave(&ap->host->lock, flags);
+ spin_lock_irqsave(&pp->intr_lock, flags);
status = pp->intr_status;
if (status)
pp->intr_status = 0;
- spin_unlock_irqrestore(&ap->host->lock, flags);
+ spin_unlock_irqrestore(&pp->intr_lock, flags);
+
+ if (!status)
+ return IRQ_NONE;
spin_lock_bh(ap->lock);
ahci_handle_port_interrupt(ap, port_mmio, status);
@@ -1824,53 +1827,14 @@ static void ahci_update_intr_status(struct ata_port *ap)
static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance)
{
- struct ata_port *ap_this = dev_instance;
- struct ahci_port_priv *pp = ap_this->private_data;
- struct ata_host *host = ap_this->host;
- struct ahci_host_priv *hpriv = host->private_data;
- void __iomem *mmio = hpriv->mmio;
- unsigned int i;
- u32 irq_stat, irq_masked;
+ struct ata_port *ap = dev_instance;
+ struct ahci_port_priv *pp = ap->private_data;
VPRINTK("ENTER\n");
- spin_lock(&host->lock);
-
- irq_stat = readl(mmio + HOST_IRQ_STAT);
-
- if (!irq_stat) {
- u32 status = pp->intr_status;
-
- spin_unlock(&host->lock);
-
- VPRINTK("EXIT\n");
-
- return status ? IRQ_WAKE_THREAD : IRQ_NONE;
- }
-
- irq_masked = irq_stat & hpriv->port_map;
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
-
- if (!(irq_masked & (1 << i)))
- continue;
-
- ap = host->ports[i];
- if (ap) {
- ahci_update_intr_status(ap);
- VPRINTK("port %u\n", i);
- } else {
- VPRINTK("port %u (no irq)\n", i);
- if (ata_ratelimit())
- dev_warn(host->dev,
- "interrupt on disabled port %u\n", i);
- }
- }
-
- writel(irq_stat, mmio + HOST_IRQ_STAT);
-
- spin_unlock(&host->lock);
+ spin_lock(&pp->intr_lock);
+ ahci_update_intr_status(ap);
+ spin_unlock(&pp->intr_lock);
VPRINTK("EXIT\n");
@@ -2349,7 +2313,8 @@ static int ahci_port_start(struct ata_port *ap)
/*
* Switch to per-port locking in case each port has its own MSI vector.
*/
- if ((hpriv->flags & AHCI_HFLAG_MULTI_MSI)) {
+ if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) {
+ spin_lock_init(&pp->intr_lock);
spin_lock_init(&pp->lock);
ap->lock = &pp->lock;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate()
2014-09-25 13:13 ` [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate() Alexander Gordeev
@ 2014-09-28 16:04 ` Tejun Heo
2014-09-29 10:18 ` Alexander Gordeev
0 siblings, 1 reply; 12+ messages in thread
From: Tejun Heo @ 2014-09-28 16:04 UTC (permalink / raw)
To: Alexander Gordeev; +Cc: linux-kernel, linux-ide
On Thu, Sep 25, 2014 at 03:13:22PM +0200, Alexander Gordeev wrote:
> -/**
> - * ahci_host_activate - start AHCI host, request IRQs and register it
> - * @host: target ATA host
> - * @irq: base IRQ number to request
> - * @irq_handler: irq_handler used when requesting IRQs
> - * @irq_flags: irq_flags used when requesting IRQs
> - *
> - * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
> - * when multiple MSIs were allocated. That is one MSI per port, starting
> - * from @irq.
> - *
> - * LOCKING:
> - * Inherited from calling layer (may sleep).
> - *
> - * RETURNS:
> - * 0 on success, -errno otherwise.
> - */
> -int ahci_host_activate(struct ata_host *host, int irq)
> -{
> - int i, rc;
> -
> - rc = ata_host_start(host);
> - if (rc)
> - return rc;
> -
> - for (i = 0; i < host->n_ports; i++) {
> - struct ahci_port_priv *pp = host->ports[i]->private_data;
> -
> - /* Do not receive interrupts sent by dummy ports */
> - if (!pp) {
> - disable_irq(irq + i);
> - continue;
> - }
> -
> - rc = devm_request_threaded_irq(host->dev, irq + i,
> - ahci_hw_interrupt,
> - ahci_thread_fn, IRQF_SHARED,
> - pp->irq_desc, host->ports[i]);
> - if (rc)
> - goto out_free_irqs;
> - }
> -
> - for (i = 0; i < host->n_ports; i++)
> - ata_port_desc(host->ports[i], "irq %d", irq + i);
> -
> - rc = ata_host_register(host, &ahci_sht);
> - if (rc)
> - goto out_free_all_irqs;
> -
> - return 0;
> -
> -out_free_all_irqs:
> - i = host->n_ports;
> -out_free_irqs:
> - for (i--; i >= 0; i--)
> - devm_free_irq(host->dev, irq + i, host->ports[i]);
> -
> - return rc;
> -}
It's generally a bad idea to mix code movement w/ other changes. I'm
applying this one but please separate code movements to separate
patches from now on.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 3/4] AHCI: Make few function names more descriptive
2014-09-25 13:13 ` [PATCH v4 3/4] AHCI: Make few function names more descriptive Alexander Gordeev
@ 2014-09-28 16:04 ` Tejun Heo
0 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2014-09-28 16:04 UTC (permalink / raw)
To: Alexander Gordeev; +Cc: linux-kernel, linux-ide
On Thu, Sep 25, 2014 at 03:13:23PM +0200, Alexander Gordeev wrote:
> Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
> Cc: linux-ide@vger.kernel.org
Applied 1-3 to libata/for-3.18.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 4/4] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode
2014-09-25 13:13 ` [PATCH v4 4/4] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode Alexander Gordeev
@ 2014-09-28 16:10 ` Tejun Heo
2014-09-29 10:21 ` [PATCH] " Alexander Gordeev
0 siblings, 1 reply; 12+ messages in thread
From: Tejun Heo @ 2014-09-28 16:10 UTC (permalink / raw)
To: Alexander Gordeev; +Cc: linux-kernel, linux-ide
Hello, Alexander.
On Thu, Sep 25, 2014 at 03:13:24PM +0200, Alexander Gordeev wrote:
> @@ -1797,11 +1797,14 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
> unsigned long flags;
> u32 status;
>
> - spin_lock_irqsave(&ap->host->lock, flags);
> + spin_lock_irqsave(&pp->intr_lock, flags);
> status = pp->intr_status;
> if (status)
> pp->intr_status = 0;
> - spin_unlock_irqrestore(&ap->host->lock, flags);
> + spin_unlock_irqrestore(&pp->intr_lock, flags);
atomic_xchg() prolly is a better option here.
> +
> + if (!status)
> + return IRQ_NONE;
>
> spin_lock_bh(ap->lock);
> ahci_handle_port_interrupt(ap, port_mmio, status);
> @@ -1824,53 +1827,14 @@ static void ahci_update_intr_status(struct ata_port *ap)
>
> static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance)
> {
...
> + spin_lock(&pp->intr_lock);
> + ahci_update_intr_status(ap);
> + spin_unlock(&pp->intr_lock);
and atomic_or() in update_intr_status.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate()
2014-09-28 16:04 ` Tejun Heo
@ 2014-09-29 10:18 ` Alexander Gordeev
2014-09-29 10:19 ` [PATCH] " Alexander Gordeev
0 siblings, 1 reply; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-29 10:18 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-kernel, linux-ide
On Sun, Sep 28, 2014 at 12:04:08PM -0400, Tejun Heo wrote:
> It's generally a bad idea to mix code movement w/ other changes. I'm
> applying this one but please separate code movements to separate
> patches from now on.
This patch lacks the hunk below, which causes build error.
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -568,8 +568,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
ahci_init_controller(host);
ahci_print_info(host, "platform");
- rc = ata_host_activate(host, irq, ahci_interrupt, 0,
- &ahci_highbank_platform_sht);
+ rc = ahci_host_activate(host, irq, &ahci_highbank_platform_sht);
if (rc)
goto err0;
> Thanks.
>
> --
> tejun
--
Regards,
Alexander Gordeev
agordeev@redhat.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] AHCI: Move host activation code into ahci_host_activate()
2014-09-29 10:18 ` Alexander Gordeev
@ 2014-09-29 10:19 ` Alexander Gordeev
2014-09-29 14:04 ` Tejun Heo
0 siblings, 1 reply; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-29 10:19 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-kernel, linux-ide
Currently host activation done by calling either function
ahci_host_activate() or ata_host_activate(). Consolidate
the code by only calling ahci_host_activate() for all AHCI
devices.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/acard-ahci.c | 3 +-
drivers/ata/ahci.c | 66 +--------------------------------
drivers/ata/ahci.h | 6 +--
drivers/ata/libahci.c | 84 +++++++++++++++++++++++++++++++++++++++---
drivers/ata/libahci_platform.c | 3 +-
drivers/ata/sata_highbank.c | 3 +-
6 files changed, 84 insertions(+), 81 deletions(-)
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c
index 25d0ac3..c962886 100644
--- a/drivers/ata/acard-ahci.c
+++ b/drivers/ata/acard-ahci.c
@@ -498,8 +498,7 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id
acard_ahci_pci_print_info(host);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
- &acard_ahci_sht);
+ return ahci_host_activate(host, pdev->irq, &acard_ahci_sht);
}
module_pci_driver(acard_ahci_pci_driver);
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index f68a995..d0ac38b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1226,66 +1226,6 @@ intx:
return 0;
}
-/**
- * ahci_host_activate - start AHCI host, request IRQs and register it
- * @host: target ATA host
- * @irq: base IRQ number to request
- * @irq_handler: irq_handler used when requesting IRQs
- * @irq_flags: irq_flags used when requesting IRQs
- *
- * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
- * when multiple MSIs were allocated. That is one MSI per port, starting
- * from @irq.
- *
- * LOCKING:
- * Inherited from calling layer (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ahci_host_activate(struct ata_host *host, int irq)
-{
- int i, rc;
-
- rc = ata_host_start(host);
- if (rc)
- return rc;
-
- for (i = 0; i < host->n_ports; i++) {
- struct ahci_port_priv *pp = host->ports[i]->private_data;
-
- /* Do not receive interrupts sent by dummy ports */
- if (!pp) {
- disable_irq(irq + i);
- continue;
- }
-
- rc = devm_request_threaded_irq(host->dev, irq + i,
- ahci_hw_interrupt,
- ahci_thread_fn, IRQF_SHARED,
- pp->irq_desc, host->ports[i]);
- if (rc)
- goto out_free_irqs;
- }
-
- for (i = 0; i < host->n_ports; i++)
- ata_port_desc(host->ports[i], "irq %d", irq + i);
-
- rc = ata_host_register(host, &ahci_sht);
- if (rc)
- goto out_free_all_irqs;
-
- return 0;
-
-out_free_all_irqs:
- i = host->n_ports;
-out_free_irqs:
- for (i--; i >= 0; i--)
- devm_free_irq(host->dev, irq + i, host->ports[i]);
-
- return rc;
-}
-
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned int board_id = ent->driver_data;
@@ -1487,11 +1427,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
- return ahci_host_activate(host, pdev->irq);
-
- return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
- &ahci_sht);
+ return ahci_host_activate(host, pdev->irq, &ahci_sht);
}
module_pci_driver(ahci_pci_driver);
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index a074c73..6a22055 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -388,11 +388,9 @@ int ahci_port_resume(struct ata_port *ap);
void ahci_set_em_messages(struct ahci_host_priv *hpriv,
struct ata_port_info *pi);
int ahci_reset_em(struct ata_host *host);
-irqreturn_t ahci_interrupt(int irq, void *dev_instance);
-irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance);
-irqreturn_t ahci_thread_fn(int irq, void *dev_instance);
void ahci_print_info(struct ata_host *host, const char *scc_s);
-int ahci_host_activate(struct ata_host *host, int irq);
+int ahci_host_activate(struct ata_host *host, int irq,
+ struct scsi_host_template *sht);
void ahci_error_handler(struct ata_port *ap);
static inline void __iomem *__ahci_port_base(struct ata_host *host,
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index b784e9d..0080551 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1789,7 +1789,7 @@ static void ahci_port_intr(struct ata_port *ap)
ahci_handle_port_interrupt(ap, port_mmio, status);
}
-irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
+static irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
{
struct ata_port *ap = dev_instance;
struct ahci_port_priv *pp = ap->private_data;
@@ -1809,7 +1809,6 @@ irqreturn_t ahci_thread_fn(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-EXPORT_SYMBOL_GPL(ahci_thread_fn);
static void ahci_hw_port_interrupt(struct ata_port *ap)
{
@@ -1823,7 +1822,7 @@ static void ahci_hw_port_interrupt(struct ata_port *ap)
pp->intr_status |= status;
}
-irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
+static irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
{
struct ata_port *ap_this = dev_instance;
struct ahci_port_priv *pp = ap_this->private_data;
@@ -1877,9 +1876,8 @@ irqreturn_t ahci_hw_interrupt(int irq, void *dev_instance)
return IRQ_WAKE_THREAD;
}
-EXPORT_SYMBOL_GPL(ahci_hw_interrupt);
-irqreturn_t ahci_interrupt(int irq, void *dev_instance)
+static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
@@ -1938,7 +1936,6 @@ irqreturn_t ahci_interrupt(int irq, void *dev_instance)
return IRQ_RETVAL(handled);
}
-EXPORT_SYMBOL_GPL(ahci_interrupt);
unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{
@@ -2472,6 +2469,81 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
}
EXPORT_SYMBOL_GPL(ahci_set_em_messages);
+static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq,
+ struct scsi_host_template *sht)
+{
+ int i, rc;
+
+ rc = ata_host_start(host);
+ if (rc)
+ return rc;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ahci_port_priv *pp = host->ports[i]->private_data;
+
+ /* Do not receive interrupts sent by dummy ports */
+ if (!pp) {
+ disable_irq(irq + i);
+ continue;
+ }
+
+ rc = devm_request_threaded_irq(host->dev, irq + i,
+ ahci_hw_interrupt,
+ ahci_thread_fn, IRQF_SHARED,
+ pp->irq_desc, host->ports[i]);
+ if (rc)
+ goto out_free_irqs;
+ }
+
+ for (i = 0; i < host->n_ports; i++)
+ ata_port_desc(host->ports[i], "irq %d", irq + i);
+
+ rc = ata_host_register(host, sht);
+ if (rc)
+ goto out_free_all_irqs;
+
+ return 0;
+
+out_free_all_irqs:
+ i = host->n_ports;
+out_free_irqs:
+ for (i--; i >= 0; i--)
+ devm_free_irq(host->dev, irq + i, host->ports[i]);
+
+ return rc;
+}
+
+/**
+ * ahci_host_activate - start AHCI host, request IRQs and register it
+ * @host: target ATA host
+ * @irq: base IRQ number to request
+ * @sht: scsi_host_template to use when registering the host
+ *
+ * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
+ * when multiple MSIs were allocated. That is one MSI per port, starting
+ * from @irq.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ahci_host_activate(struct ata_host *host, int irq,
+ struct scsi_host_template *sht)
+{
+ struct ahci_host_priv *hpriv = host->private_data;
+ int rc;
+
+ if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
+ rc = ahci_host_activate_multi_irqs(host, irq, sht);
+ else
+ rc = ata_host_activate(host, irq, ahci_interrupt,
+ IRQF_SHARED, sht);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_host_activate);
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Common AHCI SATA low-level routines");
MODULE_LICENSE("GPL");
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index c7f787e..0b03f90 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -493,8 +493,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
ahci_init_controller(host);
ahci_print_info(host, "platform");
- return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
- &ahci_platform_sht);
+ return ahci_host_activate(host, irq, &ahci_platform_sht);
}
EXPORT_SYMBOL_GPL(ahci_platform_init_host);
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index da3bc27..ce2b99a 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -568,8 +568,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
ahci_init_controller(host);
ahci_print_info(host, "platform");
- rc = ata_host_activate(host, irq, ahci_interrupt, 0,
- &ahci_highbank_platform_sht);
+ rc = ahci_host_activate(host, irq, &ahci_highbank_platform_sht);
if (rc)
goto err0;
--
1.8.3.1
--
Regards,
Alexander Gordeev
agordeev@redhat.com
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode
2014-09-28 16:10 ` Tejun Heo
@ 2014-09-29 10:21 ` Alexander Gordeev
0 siblings, 0 replies; 12+ messages in thread
From: Alexander Gordeev @ 2014-09-29 10:21 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-kernel, linux-ide, Jiang, Dave
As described in AHCI v1.0 specification chapter 10.6.2.2
"Multiple MSI Based Messages" generation of interrupts
is not controlled through the HOST_IRQ_STAT register.
Considering MMIO access is expensive remove unnecessary
reading and writing of HOST_IRQ_STAT register.
Further, serializing access to the host data is no longer
needed and the interrupt service routine can avoid competing
on the host lock.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Suggested-by: "Jiang, Dave" <dave.jiang@intel.com>
Cc: "Jiang, Dave" <dave.jiang@intel.com>
Cc: linux-ide@vger.kernel.org
---
drivers/ata/ahci.h | 2 +-
drivers/ata/libahci.c | 67 ++++++---------------------------------------------
2 files changed, 9 insertions(+), 60 deletions(-)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 6a22055..40f0e34 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -304,7 +304,7 @@ struct ahci_port_priv {
unsigned int ncq_saw_d2h:1;
unsigned int ncq_saw_dmas:1;
unsigned int ncq_saw_sdb:1;
- u32 intr_status; /* interrupts to handle */
+ atomic_t intr_status; /* interrupts to handle */
spinlock_t lock; /* protects parent ata_port */
u32 intr_mask; /* interrupts to enable */
bool fbs_supported; /* set iff FBS is supported */
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 48175e5..97683e4 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1794,14 +1794,11 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
struct ata_port *ap = dev_instance;
struct ahci_port_priv *pp = ap->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
- unsigned long flags;
u32 status;
- spin_lock_irqsave(&ap->host->lock, flags);
- status = pp->intr_status;
- if (status)
- pp->intr_status = 0;
- spin_unlock_irqrestore(&ap->host->lock, flags);
+ status = atomic_xchg(&pp->intr_status, 0);
+ if (!status)
+ return IRQ_NONE;
spin_lock_bh(ap->lock);
ahci_handle_port_interrupt(ap, port_mmio, status);
@@ -1810,67 +1807,19 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-static void ahci_update_intr_status(struct ata_port *ap)
+static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance)
{
+ struct ata_port *ap = dev_instance;
void __iomem *port_mmio = ahci_port_base(ap);
struct ahci_port_priv *pp = ap->private_data;
u32 status;
- status = readl(port_mmio + PORT_IRQ_STAT);
- writel(status, port_mmio + PORT_IRQ_STAT);
-
- pp->intr_status |= status;
-}
-
-static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance)
-{
- struct ata_port *ap_this = dev_instance;
- struct ahci_port_priv *pp = ap_this->private_data;
- struct ata_host *host = ap_this->host;
- struct ahci_host_priv *hpriv = host->private_data;
- void __iomem *mmio = hpriv->mmio;
- unsigned int i;
- u32 irq_stat, irq_masked;
-
VPRINTK("ENTER\n");
- spin_lock(&host->lock);
-
- irq_stat = readl(mmio + HOST_IRQ_STAT);
-
- if (!irq_stat) {
- u32 status = pp->intr_status;
-
- spin_unlock(&host->lock);
-
- VPRINTK("EXIT\n");
-
- return status ? IRQ_WAKE_THREAD : IRQ_NONE;
- }
-
- irq_masked = irq_stat & hpriv->port_map;
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
-
- if (!(irq_masked & (1 << i)))
- continue;
-
- ap = host->ports[i];
- if (ap) {
- ahci_update_intr_status(ap);
- VPRINTK("port %u\n", i);
- } else {
- VPRINTK("port %u (no irq)\n", i);
- if (ata_ratelimit())
- dev_warn(host->dev,
- "interrupt on disabled port %u\n", i);
- }
- }
-
- writel(irq_stat, mmio + HOST_IRQ_STAT);
+ status = readl(port_mmio + PORT_IRQ_STAT);
+ writel(status, port_mmio + PORT_IRQ_STAT);
- spin_unlock(&host->lock);
+ atomic_or(status, &pp->intr_status);
VPRINTK("EXIT\n");
--
1.8.3.1
--
Regards,
Alexander Gordeev
agordeev@redhat.com
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] AHCI: Move host activation code into ahci_host_activate()
2014-09-29 10:19 ` [PATCH] " Alexander Gordeev
@ 2014-09-29 14:04 ` Tejun Heo
0 siblings, 0 replies; 12+ messages in thread
From: Tejun Heo @ 2014-09-29 14:04 UTC (permalink / raw)
To: Alexander Gordeev; +Cc: linux-kernel, linux-ide
On Mon, Sep 29, 2014 at 11:19:49AM +0100, Alexander Gordeev wrote:
> Currently host activation done by calling either function
> ahci_host_activate() or ata_host_activate(). Consolidate
> the code by only calling ahci_host_activate() for all AHCI
> devices.
>
> Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
> Cc: linux-ide@vger.kernel.org
I reverted 2-3. Can you please respin the patches so that code
movement is separate from other changes?
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-09-29 14:04 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-25 13:13 [PATCH v4 0/4] AHCI: Optimize interrupt processing in multi-MSI mode Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 1/4] AHCI: Cleanup checking of multiple MSIs/SLM modes Alexander Gordeev
2014-09-25 13:13 ` [PATCH v4 2/4] AHCI: Move host activation code into ahci_host_activate() Alexander Gordeev
2014-09-28 16:04 ` Tejun Heo
2014-09-29 10:18 ` Alexander Gordeev
2014-09-29 10:19 ` [PATCH] " Alexander Gordeev
2014-09-29 14:04 ` Tejun Heo
2014-09-25 13:13 ` [PATCH v4 3/4] AHCI: Make few function names more descriptive Alexander Gordeev
2014-09-28 16:04 ` Tejun Heo
2014-09-25 13:13 ` [PATCH v4 4/4] AHCI: Do not read HOST_IRQ_STAT reg in multi-MSI mode Alexander Gordeev
2014-09-28 16:10 ` Tejun Heo
2014-09-29 10:21 ` [PATCH] " Alexander Gordeev
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.