diff mbox

[v2,2/3] libahci: Implement the capability to override the generic ahci interrupt handler.

Message ID 1453888197-11368-3-git-send-email-stripathi@apm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Suman Tripathi Jan. 27, 2016, 9:49 a.m. UTC
This patch implements the capability to override the generic
ahci interrupt handler so that LDD drivers can implement there
own interrupt handler routines.

Signed-off-by: Suman Tripathi <stripathi@apm.com>
---
 drivers/ata/ahci.h    |    2 ++
 drivers/ata/libahci.c |   13 ++++++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

--
1.7.1

Comments

Tejun Heo Jan. 31, 2016, 11:35 a.m. UTC | #1
On Wed, Jan 27, 2016 at 03:19:56PM +0530, Suman Tripathi wrote:
> @@ -2466,13 +2467,19 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
>  {
>  	struct ahci_host_priv *hpriv = host->private_data;
>  	int irq = hpriv->irq;
> +	irqreturn_t (*ahci_irq_handler)(int irq, void *dev_instance);
>  	int rc;
> 
>  	if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX))
>  		rc = ahci_host_activate_multi_irqs(host, sht);

You need to add { } to the if body too.  Please read CodingStyle.

> -	else
> -		rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
> +	else {
> +		ahci_irq_handler = hpriv->ahci_irq_intr ? hpriv->ahci_irq_intr :
> +				   ahci_single_level_irq_intr;
> +
> +		rc = ata_host_activate(host, irq, ahci_irq_handler,
>  				       IRQF_SHARED, sht);
> +	}

Can you please make this handled the same way as ->start_engine?
Also, maybe print out a warning message if a driver specifies both
AHCI_HFLAG_MULTI_MSI[X] and the irq handler override?

Thanks.
Suman Tripathi Feb. 1, 2016, 7:43 p.m. UTC | #2
On Sun, Jan 31, 2016 at 3:35 AM, Tejun Heo <htejun@gmail.com> wrote:
> On Wed, Jan 27, 2016 at 03:19:56PM +0530, Suman Tripathi wrote:
>> @@ -2466,13 +2467,19 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
>>  {
>>       struct ahci_host_priv *hpriv = host->private_data;
>>       int irq = hpriv->irq;
>> +     irqreturn_t (*ahci_irq_handler)(int irq, void *dev_instance);
>>       int rc;
>>
>>       if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX))
>>               rc = ahci_host_activate_multi_irqs(host, sht);
>
> You need to add { } to the if body too.  Please read CodingStyle.
>
>> -     else
>> -             rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
>> +     else {
>> +             ahci_irq_handler = hpriv->ahci_irq_intr ? hpriv->ahci_irq_intr :
>> +                                ahci_single_level_irq_intr;
>> +
>> +             rc = ata_host_activate(host, irq, ahci_irq_handler,
>>                                      IRQF_SHARED, sht);
>> +     }
>
> Can you please make this handled the same way as ->start_engine?
> Also, maybe print out a warning message if a driver specifies both
> AHCI_HFLAG_MULTI_MSI[X] and the irq handler override?

Ok Sure
>
> Thanks.
>
> --
> tejun
diff mbox

Patch

diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index e9b57e8..284ce3a 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -359,6 +359,7 @@  struct ahci_host_priv {
 	 * be overridden anytime before the host is activated.
 	 */
 	void			(*start_engine)(struct ata_port *ap);
+	irqreturn_t 		(*ahci_irq_intr)(int irq, void *dev_instance);
 };

 #ifdef CONFIG_PCI_MSI
@@ -422,6 +423,7 @@  int ahci_reset_em(struct ata_host *host);
 void ahci_print_info(struct ata_host *host, const char *scc_s);
 int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht);
 void ahci_error_handler(struct ata_port *ap);
+u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked);

 static inline void __iomem *__ahci_port_base(struct ata_host *host,
 					     unsigned int port_no)
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 08be136..fa098c6 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1816,7 +1816,7 @@  static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance)
 	return IRQ_HANDLED;
 }

-static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
+u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
 {
 	unsigned int i, handled = 0;

@@ -1842,6 +1842,7 @@  static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)

 	return handled;
 }
+EXPORT_SYMBOL_GPL(ahci_handle_port_intr);

 static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
 {
@@ -2466,13 +2467,19 @@  int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
 {
 	struct ahci_host_priv *hpriv = host->private_data;
 	int irq = hpriv->irq;
+	irqreturn_t (*ahci_irq_handler)(int irq, void *dev_instance);
 	int rc;

 	if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX))
 		rc = ahci_host_activate_multi_irqs(host, sht);
-	else
-		rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
+	else {
+		ahci_irq_handler = hpriv->ahci_irq_intr ? hpriv->ahci_irq_intr :
+				   ahci_single_level_irq_intr;
+
+		rc = ata_host_activate(host, irq, ahci_irq_handler,
 				       IRQF_SHARED, sht);
+	}
+
 	return rc;
 }
 EXPORT_SYMBOL_GPL(ahci_host_activate);