65 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From dbdda4277cf0422a9ccb7ea98d0263c3cdbecdf6 Mon Sep 17 00:00:00 2001
 | |
| From: Mark Salter <msalter@redhat.com>
 | |
| Date: Tue, 8 May 2018 21:54:39 -0400
 | |
| Subject: [PATCH] ACPI / irq: Workaround firmware issue on X-Gene based
 | |
|  m400
 | |
| 
 | |
| The ACPI firmware on the xgene-based m400 platorms erroneously
 | |
| describes its UART interrupt as ACPI_PRODUCER rather than
 | |
| ACPI_CONSUMER. This leads to the UART driver being unable to
 | |
| find its interrupt and the kernel unable find a console.
 | |
| Work around this by avoiding the producer/consumer check
 | |
| for X-Gene UARTs.
 | |
| 
 | |
| Signed-off-by: Mark Salter <msalter@redhat.com>
 | |
| ---
 | |
|  drivers/acpi/irq.c | 17 +++++++++++++++--
 | |
|  1 file changed, 15 insertions(+), 2 deletions(-)
 | |
| 
 | |
| diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
 | |
| index 7c352cba0528..028c1a564cff 100644
 | |
| --- a/drivers/acpi/irq.c
 | |
| +++ b/drivers/acpi/irq.c
 | |
| @@ -129,6 +129,7 @@ struct acpi_irq_parse_one_ctx {
 | |
|  	unsigned int index;
 | |
|  	unsigned long *res_flags;
 | |
|  	struct irq_fwspec *fwspec;
 | |
| +	bool skip_producer_check;
 | |
|  };
 | |
|  
 | |
|  /**
 | |
| @@ -200,7 +201,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
 | |
|  		return AE_CTRL_TERMINATE;
 | |
|  	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 | |
|  		eirq = &ares->data.extended_irq;
 | |
| -		if (eirq->producer_consumer == ACPI_PRODUCER)
 | |
| +		if (!ctx->skip_producer_check &&
 | |
| +		    eirq->producer_consumer == ACPI_PRODUCER)
 | |
|  			return AE_OK;
 | |
|  		if (ctx->index >= eirq->interrupt_count) {
 | |
|  			ctx->index -= eirq->interrupt_count;
 | |
| @@ -235,8 +237,19 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
 | |
|  static int acpi_irq_parse_one(acpi_handle handle, unsigned int index,
 | |
|  			      struct irq_fwspec *fwspec, unsigned long *flags)
 | |
|  {
 | |
| -	struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec };
 | |
| +	struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false };
 | |
|  
 | |
| +	/*
 | |
| +	 * Firmware on arm64-based HPE m400 platform incorrectly marks
 | |
| +	 * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER.
 | |
| +	 * Don't do the producer/consumer check for that device.
 | |
| +	 */
 | |
| +	if (IS_ENABLED(CONFIG_ARM64)) {
 | |
| +		struct acpi_device *adev = acpi_bus_get_acpi_device(handle);
 | |
| +
 | |
| +		if (adev && !strcmp(acpi_device_hid(adev), "APMC0D08"))
 | |
| +			ctx.skip_producer_check = true;
 | |
| +	}
 | |
|  	acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx);
 | |
|  	return ctx.rc;
 | |
|  }
 | |
| -- 
 | |
| 2.17.0
 | |
| 
 |