|
@@ -16,6 +16,7 @@
|
|
|
#include <linux/ioport.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/irq.h>
|
|
|
+#include <linux/dmi.h>
|
|
|
|
|
|
#ifdef CONFIG_X86
|
|
|
#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
|
|
@@ -380,21 +381,136 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type);
|
|
|
|
|
|
-static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
|
|
|
+static const struct dmi_system_id medion_laptop[] = {
|
|
|
+ {
|
|
|
+ .ident = "MEDION P15651",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "M15T"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+static const struct dmi_system_id asus_laptop[] = {
|
|
|
+ {
|
|
|
+ .ident = "Asus Vivobook K3402ZA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus Vivobook K3502ZA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus Vivobook S5402ZA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus Vivobook S5602ZA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus ExpertBook B1402CBA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus ExpertBook B1502CBA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus ExpertBook B2402CBA",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* Asus ExpertBook B1402CVA */
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* TongFang GM6XGxX/TUXEDO Stellaris 16 Gen5 AMD */
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .ident = "Asus ExpertBook B2502",
|
|
|
+ .matches = {
|
|
|
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
|
|
+ DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
+struct irq_override_cmp {
|
|
|
+ const struct dmi_system_id *system;
|
|
|
+ unsigned char irq;
|
|
|
+ unsigned char triggering;
|
|
|
+ unsigned char polarity;
|
|
|
+ unsigned char shareable;
|
|
|
+};
|
|
|
+
|
|
|
+static const struct irq_override_cmp skip_override_table[] = {
|
|
|
+ { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
|
|
|
+ { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
|
|
|
+};
|
|
|
+
|
|
|
+static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
|
|
|
+ u8 shareable)
|
|
|
{
|
|
|
- res->start = gsi;
|
|
|
- res->end = gsi;
|
|
|
- res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) {
|
|
|
+ const struct irq_override_cmp *entry = &skip_override_table[i];
|
|
|
+
|
|
|
+ if (dmi_check_system(entry->system) &&
|
|
|
+ entry->irq == gsi &&
|
|
|
+ entry->triggering == triggering &&
|
|
|
+ entry->polarity == polarity &&
|
|
|
+ entry->shareable == shareable)
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
|
|
|
u8 triggering, u8 polarity, u8 shareable,
|
|
|
- bool legacy)
|
|
|
+ bool check_override)
|
|
|
{
|
|
|
int irq, p, t;
|
|
|
|
|
|
if (!valid_IRQ(gsi)) {
|
|
|
- acpi_dev_irqresource_disabled(res, gsi);
|
|
|
+ irqresource_disabled(res, gsi);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -408,7 +524,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
|
|
|
* using extended IRQ descriptors we take the IRQ configuration
|
|
|
* from _CRS directly.
|
|
|
*/
|
|
|
- if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
|
|
|
+ if (check_override &&
|
|
|
+ acpi_dev_irq_override(gsi, triggering, polarity, shareable) &&
|
|
|
+ !acpi_get_override_irq(gsi, &t, &p)) {
|
|
|
u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
|
|
|
u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
|
|
|
|
|
@@ -426,7 +544,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
|
|
|
res->start = irq;
|
|
|
res->end = irq;
|
|
|
} else {
|
|
|
- acpi_dev_irqresource_disabled(res, gsi);
|
|
|
+ irqresource_disabled(res, gsi);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -463,7 +581,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
|
|
|
*/
|
|
|
irq = &ares->data.irq;
|
|
|
if (index >= irq->interrupt_count) {
|
|
|
- acpi_dev_irqresource_disabled(res, 0);
|
|
|
+ irqresource_disabled(res, 0);
|
|
|
return false;
|
|
|
}
|
|
|
acpi_dev_get_irqresource(res, irq->interrupts[index],
|
|
@@ -473,7 +591,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
|
|
|
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
|
|
|
ext_irq = &ares->data.extended_irq;
|
|
|
if (index >= ext_irq->interrupt_count) {
|
|
|
- acpi_dev_irqresource_disabled(res, 0);
|
|
|
+ irqresource_disabled(res, 0);
|
|
|
return false;
|
|
|
}
|
|
|
if (is_gsi(ext_irq))
|
|
@@ -481,7 +599,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
|
|
|
ext_irq->triggering, ext_irq->polarity,
|
|
|
ext_irq->shareable, false);
|
|
|
else
|
|
|
- acpi_dev_irqresource_disabled(res, 0);
|
|
|
+ irqresource_disabled(res, 0);
|
|
|
break;
|
|
|
default:
|
|
|
res->flags = 0;
|