Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 
0003 /*
0004  * Quirks for AMD IOMMU
0005  *
0006  * Copyright (C) 2019 Kai-Heng Feng <kai.heng.feng@canonical.com>
0007  */
0008 
0009 #ifdef CONFIG_DMI
0010 #include <linux/dmi.h>
0011 
0012 #include "amd_iommu.h"
0013 
0014 #define IVHD_SPECIAL_IOAPIC     1
0015 
0016 struct ivrs_quirk_entry {
0017     u8 id;
0018     u32 devid;
0019 };
0020 
0021 enum {
0022     DELL_INSPIRON_7375 = 0,
0023     DELL_LATITUDE_5495,
0024     LENOVO_IDEAPAD_330S_15ARR,
0025 };
0026 
0027 static const struct ivrs_quirk_entry ivrs_ioapic_quirks[][3] __initconst = {
0028     /* ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 */
0029     [DELL_INSPIRON_7375] = {
0030         { .id = 4, .devid = 0xa0 },
0031         { .id = 5, .devid = 0x2 },
0032         {}
0033     },
0034     /* ivrs_ioapic[4]=00:14.0 */
0035     [DELL_LATITUDE_5495] = {
0036         { .id = 4, .devid = 0xa0 },
0037         {}
0038     },
0039     /* ivrs_ioapic[32]=00:14.0 */
0040     [LENOVO_IDEAPAD_330S_15ARR] = {
0041         { .id = 32, .devid = 0xa0 },
0042         {}
0043     },
0044     {}
0045 };
0046 
0047 static int __init ivrs_ioapic_quirk_cb(const struct dmi_system_id *d)
0048 {
0049     const struct ivrs_quirk_entry *i;
0050 
0051     for (i = d->driver_data; i->id != 0 && i->devid != 0; i++)
0052         add_special_device(IVHD_SPECIAL_IOAPIC, i->id, (u32 *)&i->devid, 0);
0053 
0054     return 0;
0055 }
0056 
0057 static const struct dmi_system_id ivrs_quirks[] __initconst = {
0058     {
0059         .callback = ivrs_ioapic_quirk_cb,
0060         .ident = "Dell Inspiron 7375",
0061         .matches = {
0062             DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0063             DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7375"),
0064         },
0065         .driver_data = (void *)&ivrs_ioapic_quirks[DELL_INSPIRON_7375],
0066     },
0067     {
0068         .callback = ivrs_ioapic_quirk_cb,
0069         .ident = "Dell Latitude 5495",
0070         .matches = {
0071             DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
0072             DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 5495"),
0073         },
0074         .driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495],
0075     },
0076     {
0077         /*
0078          * Acer Aspire A315-41 requires the very same workaround as
0079          * Dell Latitude 5495
0080          */
0081         .callback = ivrs_ioapic_quirk_cb,
0082         .ident = "Acer Aspire A315-41",
0083         .matches = {
0084             DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
0085             DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-41"),
0086         },
0087         .driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495],
0088     },
0089     {
0090         .callback = ivrs_ioapic_quirk_cb,
0091         .ident = "Lenovo ideapad 330S-15ARR",
0092         .matches = {
0093             DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
0094             DMI_MATCH(DMI_PRODUCT_NAME, "81FB"),
0095         },
0096         .driver_data = (void *)&ivrs_ioapic_quirks[LENOVO_IDEAPAD_330S_15ARR],
0097     },
0098     {}
0099 };
0100 
0101 void __init amd_iommu_apply_ivrs_quirks(void)
0102 {
0103     dmi_check_system(ivrs_quirks);
0104 }
0105 #endif