Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86: uniwill-laptop: Introduce device descriptor system

Future additions to the driver will depend on device-specific
initialization steps. Extend the DMI-based feature detection system
to include device descriptors. Each descriptor contains a bitmap of
supported features and a set of callback for performing
device-specific initialization.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Co-developed-by: Werner Sembach <wse@tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260115154332.402873-1-wse@tuxedocomputers.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Armin Wolf and committed by
Ilpo Järvinen
d8c560f7 2ee83230

+131 -26
+131 -26
drivers/platform/x86/uniwill/uniwill-acpi.c
··· 322 322 struct device *dev; 323 323 acpi_handle handle; 324 324 struct regmap *regmap; 325 + unsigned int features; 325 326 struct acpi_battery_hook hook; 326 327 unsigned int last_charge_ctrl; 327 328 struct mutex battery_lock; /* Protects the list of currently registered batteries */ ··· 342 341 struct power_supply *battery; 343 342 }; 344 343 344 + struct uniwill_device_descriptor { 345 + unsigned int features; 346 + /* Executed during driver probing */ 347 + int (*probe)(struct uniwill_data *data); 348 + }; 349 + 345 350 static bool force; 346 351 module_param_unsafe(force, bool, 0); 347 352 MODULE_PARM_DESC(force, "Force loading without checking for supported devices\n"); 348 353 349 - /* Feature bitmask since the associated registers are not reliable */ 350 - static unsigned int supported_features; 354 + /* 355 + * Contains device specific data like the feature bitmap since 356 + * the associated registers are not always reliable. 357 + */ 358 + static struct uniwill_device_descriptor device_descriptor __ro_after_init; 351 359 352 360 static const char * const uniwill_temp_labels[] = { 353 361 "CPU", ··· 420 410 421 411 { KE_END } 422 412 }; 413 + 414 + static inline bool uniwill_device_supports(struct uniwill_data *data, 415 + unsigned int features) 416 + { 417 + return (data->features & features) == features; 418 + } 423 419 424 420 static int uniwill_ec_reg_write(void *context, unsigned int reg, unsigned int val) 425 421 { ··· 815 799 816 800 static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) 817 801 { 802 + struct device *dev = kobj_to_dev(kobj); 803 + struct uniwill_data *data = dev_get_drvdata(dev); 804 + 818 805 if (attr == &dev_attr_fn_lock_toggle_enable.attr) { 819 - if (supported_features & UNIWILL_FEATURE_FN_LOCK_TOGGLE) 806 + if (uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK_TOGGLE)) 820 807 return attr->mode; 821 808 } 822 809 823 810 if (attr == &dev_attr_super_key_toggle_enable.attr) { 824 - if (supported_features & UNIWILL_FEATURE_SUPER_KEY_TOGGLE) 811 + if (uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) 825 812 return attr->mode; 826 813 } 827 814 828 815 if (attr == &dev_attr_touchpad_toggle_enable.attr) { 829 - if (supported_features & UNIWILL_FEATURE_TOUCHPAD_TOGGLE) 816 + if (uniwill_device_supports(data, UNIWILL_FEATURE_TOUCHPAD_TOGGLE)) 830 817 return attr->mode; 831 818 } 832 819 833 820 if (attr == &dev_attr_rainbow_animation.attr || 834 821 attr == &dev_attr_breathing_in_suspend.attr) { 835 - if (supported_features & UNIWILL_FEATURE_LIGHTBAR) 822 + if (uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR)) 836 823 return attr->mode; 837 824 } 838 825 ··· 963 944 { 964 945 struct device *hdev; 965 946 966 - if (!(supported_features & UNIWILL_FEATURE_HWMON)) 947 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_HWMON)) 967 948 return 0; 968 949 969 950 hdev = devm_hwmon_device_register_with_info(data->dev, "uniwill", data, ··· 1038 1019 unsigned int value; 1039 1020 int ret; 1040 1021 1041 - if (!(supported_features & UNIWILL_FEATURE_LIGHTBAR)) 1022 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR)) 1042 1023 return 0; 1043 1024 1044 1025 ret = devm_mutex_init(data->dev, &data->led_lock); ··· 1251 1232 { 1252 1233 int ret; 1253 1234 1254 - if (!(supported_features & UNIWILL_FEATURE_BATTERY)) 1235 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1255 1236 return 0; 1256 1237 1257 1238 ret = devm_mutex_init(data->dev, &data->battery_lock); ··· 1380 1361 if (ret < 0) 1381 1362 return ret; 1382 1363 1364 + data->features = device_descriptor.features; 1365 + 1366 + /* 1367 + * Some devices might need to perform some device-specific initialization steps 1368 + * before the supported features are initialized. Because of this we have to call 1369 + * this callback just after the EC itself was initialized. 1370 + */ 1371 + if (device_descriptor.probe) { 1372 + ret = device_descriptor.probe(data); 1373 + if (ret < 0) 1374 + return ret; 1375 + } 1376 + 1383 1377 ret = uniwill_battery_init(data); 1384 1378 if (ret < 0) 1385 1379 return ret; ··· 1417 1385 1418 1386 static int uniwill_suspend_keyboard(struct uniwill_data *data) 1419 1387 { 1420 - if (!(supported_features & UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) 1388 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) 1421 1389 return 0; 1422 1390 1423 1391 /* ··· 1429 1397 1430 1398 static int uniwill_suspend_battery(struct uniwill_data *data) 1431 1399 { 1432 - if (!(supported_features & UNIWILL_FEATURE_BATTERY)) 1400 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1433 1401 return 0; 1434 1402 1435 1403 /* ··· 1464 1432 unsigned int value; 1465 1433 int ret; 1466 1434 1467 - if (!(supported_features & UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) 1435 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) 1468 1436 return 0; 1469 1437 1470 1438 ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value); ··· 1480 1448 1481 1449 static int uniwill_resume_battery(struct uniwill_data *data) 1482 1450 { 1483 - if (!(supported_features & UNIWILL_FEATURE_BATTERY)) 1451 + if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) 1484 1452 return 0; 1485 1453 1486 1454 return regmap_update_bits(data->regmap, EC_ADDR_CHARGE_CTRL, CHARGE_CTRL_MASK, ··· 1528 1496 .shutdown = uniwill_shutdown, 1529 1497 }; 1530 1498 1499 + static struct uniwill_device_descriptor lapac71h_descriptor __initdata = { 1500 + .features = UNIWILL_FEATURE_FN_LOCK_TOGGLE | 1501 + UNIWILL_FEATURE_SUPER_KEY_TOGGLE | 1502 + UNIWILL_FEATURE_TOUCHPAD_TOGGLE | 1503 + UNIWILL_FEATURE_BATTERY | 1504 + UNIWILL_FEATURE_HWMON, 1505 + }; 1506 + 1507 + static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = { 1508 + .features = UNIWILL_FEATURE_FN_LOCK_TOGGLE | 1509 + UNIWILL_FEATURE_SUPER_KEY_TOGGLE | 1510 + UNIWILL_FEATURE_TOUCHPAD_TOGGLE | 1511 + UNIWILL_FEATURE_LIGHTBAR | 1512 + UNIWILL_FEATURE_BATTERY | 1513 + UNIWILL_FEATURE_HWMON, 1514 + }; 1515 + 1516 + static struct uniwill_device_descriptor empty_descriptor __initdata = {}; 1517 + 1531 1518 static const struct dmi_system_id uniwill_dmi_table[] __initconst = { 1532 1519 { 1533 1520 .ident = "XMG FUSION 15", ··· 1554 1503 DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 1555 1504 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71A"), 1556 1505 }, 1506 + .driver_data = &empty_descriptor, 1557 1507 }, 1558 1508 { 1559 1509 .ident = "XMG FUSION 15", ··· 1562 1510 DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 1563 1511 DMI_EXACT_MATCH(DMI_BOARD_NAME, "LAPQC71B"), 1564 1512 }, 1513 + .driver_data = &empty_descriptor, 1565 1514 }, 1566 1515 { 1567 1516 .ident = "Intel NUC x15", ··· 1570 1517 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 1571 1518 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPAC71H"), 1572 1519 }, 1573 - .driver_data = (void *)(UNIWILL_FEATURE_FN_LOCK_TOGGLE | 1574 - UNIWILL_FEATURE_SUPER_KEY_TOGGLE | 1575 - UNIWILL_FEATURE_TOUCHPAD_TOGGLE | 1576 - UNIWILL_FEATURE_BATTERY | 1577 - UNIWILL_FEATURE_HWMON), 1520 + .driver_data = &lapac71h_descriptor, 1578 1521 }, 1579 1522 { 1580 1523 .ident = "Intel NUC x15", ··· 1578 1529 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 1579 1530 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LAPKC71F"), 1580 1531 }, 1581 - .driver_data = (void *)(UNIWILL_FEATURE_FN_LOCK_TOGGLE | 1582 - UNIWILL_FEATURE_SUPER_KEY_TOGGLE | 1583 - UNIWILL_FEATURE_TOUCHPAD_TOGGLE | 1584 - UNIWILL_FEATURE_LIGHTBAR | 1585 - UNIWILL_FEATURE_BATTERY | 1586 - UNIWILL_FEATURE_HWMON), 1532 + .driver_data = &lapkc71f_descriptor, 1587 1533 }, 1588 1534 { 1589 1535 .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel", ··· 1586 1542 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1587 1543 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTxX1"), 1588 1544 }, 1545 + .driver_data = &empty_descriptor, 1589 1546 }, 1590 1547 { 1591 1548 .ident = "TUXEDO InfinityBook Pro 14 Gen6 Intel", ··· 1594 1549 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1595 1550 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxTQx1"), 1596 1551 }, 1552 + .driver_data = &empty_descriptor, 1597 1553 }, 1598 1554 { 1599 1555 .ident = "TUXEDO InfinityBook Pro 14/16 Gen7 Intel", ··· 1602 1556 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1603 1557 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PHxARX1_PHxAQF1"), 1604 1558 }, 1559 + .driver_data = &empty_descriptor, 1605 1560 }, 1606 1561 { 1607 1562 .ident = "TUXEDO InfinityBook Pro 16 Gen7 Intel/Commodore Omnia-Book Pro Gen 7", ··· 1610 1563 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1611 1564 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6AG01_PH6AQ71_PH6AQI1"), 1612 1565 }, 1566 + .driver_data = &empty_descriptor, 1613 1567 }, 1614 1568 { 1615 1569 .ident = "TUXEDO InfinityBook Pro 14/16 Gen8 Intel/Commodore Omnia-Book Pro Gen 8", ··· 1618 1570 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1619 1571 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1"), 1620 1572 }, 1573 + .driver_data = &empty_descriptor, 1621 1574 }, 1622 1575 { 1623 1576 .ident = "TUXEDO InfinityBook Pro 14 Gen8 Intel/Commodore Omnia-Book Pro Gen 8", ··· 1626 1577 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1627 1578 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH4PG31"), 1628 1579 }, 1580 + .driver_data = &empty_descriptor, 1629 1581 }, 1630 1582 { 1631 1583 .ident = "TUXEDO InfinityBook Pro 16 Gen8 Intel", ··· 1634 1584 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1635 1585 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PH6PG01_PH6PG71"), 1636 1586 }, 1587 + .driver_data = &empty_descriptor, 1637 1588 }, 1638 1589 { 1639 1590 .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 AMD", ··· 1642 1591 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1643 1592 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxHRXx"), 1644 1593 }, 1594 + .driver_data = &empty_descriptor, 1645 1595 }, 1646 1596 { 1647 1597 .ident = "TUXEDO InfinityBook Pro 14/15 Gen9 Intel/Commodore Omnia-Book 15 Gen9", ··· 1650 1598 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1651 1599 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GXxMRXx"), 1652 1600 }, 1601 + .driver_data = &empty_descriptor, 1653 1602 }, 1654 1603 { 1655 1604 .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD", ··· 1658 1605 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1659 1606 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxHP4NAx"), 1660 1607 }, 1608 + .driver_data = &empty_descriptor, 1661 1609 }, 1662 1610 { 1663 1611 .ident = "TUXEDO InfinityBook Pro 14/15 Gen10 AMD", ··· 1666 1612 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1667 1613 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"), 1668 1614 }, 1615 + .driver_data = &empty_descriptor, 1669 1616 }, 1670 1617 { 1671 1618 .ident = "TUXEDO InfinityBook Pro 15 Gen10 Intel", ··· 1674 1619 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1675 1620 DMI_EXACT_MATCH(DMI_BOARD_NAME, "XxAR4NAx"), 1676 1621 }, 1622 + .driver_data = &empty_descriptor, 1677 1623 }, 1678 1624 { 1679 1625 .ident = "TUXEDO InfinityBook Max 15 Gen10 AMD", ··· 1682 1626 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1683 1627 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5KK45xS_X5SP45xS"), 1684 1628 }, 1629 + .driver_data = &empty_descriptor, 1685 1630 }, 1686 1631 { 1687 1632 .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD", ··· 1690 1633 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1691 1634 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6HP45xU"), 1692 1635 }, 1636 + .driver_data = &empty_descriptor, 1693 1637 }, 1694 1638 { 1695 1639 .ident = "TUXEDO InfinityBook Max 16 Gen10 AMD", ··· 1698 1640 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1699 1641 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6KK45xU_X6SP45xU"), 1700 1642 }, 1643 + .driver_data = &empty_descriptor, 1701 1644 }, 1702 1645 { 1703 1646 .ident = "TUXEDO InfinityBook Max 15 Gen10 Intel", ··· 1706 1647 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1707 1648 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X5AR45xS"), 1708 1649 }, 1650 + .driver_data = &empty_descriptor, 1709 1651 }, 1710 1652 { 1711 1653 .ident = "TUXEDO InfinityBook Max 16 Gen10 Intel", ··· 1714 1654 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1715 1655 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR55xU"), 1716 1656 }, 1657 + .driver_data = &empty_descriptor, 1717 1658 }, 1718 1659 { 1719 1660 .ident = "TUXEDO Polaris 15 Gen1 AMD", ··· 1722 1661 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1723 1662 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"), 1724 1663 }, 1664 + .driver_data = &empty_descriptor, 1725 1665 }, 1726 1666 { 1727 1667 .ident = "TUXEDO Polaris 15 Gen1 AMD", ··· 1730 1668 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1731 1669 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"), 1732 1670 }, 1671 + .driver_data = &empty_descriptor, 1733 1672 }, 1734 1673 { 1735 1674 .ident = "TUXEDO Polaris 17 Gen1 AMD", ··· 1738 1675 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1739 1676 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"), 1740 1677 }, 1678 + .driver_data = &empty_descriptor, 1741 1679 }, 1742 1680 { 1743 1681 .ident = "TUXEDO Polaris 17 Gen1 AMD", ··· 1746 1682 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1747 1683 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"), 1748 1684 }, 1685 + .driver_data = &empty_descriptor, 1749 1686 }, 1750 1687 { 1751 1688 .ident = "TUXEDO Polaris 15 Gen1 Intel", ··· 1754 1689 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1755 1690 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I1650TI"), 1756 1691 }, 1692 + .driver_data = &empty_descriptor, 1757 1693 }, 1758 1694 { 1759 1695 .ident = "TUXEDO Polaris 15 Gen1 Intel", ··· 1762 1696 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1763 1697 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1501I2060"), 1764 1698 }, 1699 + .driver_data = &empty_descriptor, 1765 1700 }, 1766 1701 { 1767 1702 .ident = "TUXEDO Polaris 17 Gen1 Intel", ··· 1770 1703 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1771 1704 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I1650TI"), 1772 1705 }, 1706 + .driver_data = &empty_descriptor, 1773 1707 }, 1774 1708 { 1775 1709 .ident = "TUXEDO Polaris 17 Gen1 Intel", ··· 1778 1710 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1779 1711 DMI_EXACT_MATCH(DMI_BOARD_NAME, "POLARIS1701I2060"), 1780 1712 }, 1713 + .driver_data = &empty_descriptor, 1781 1714 }, 1782 1715 { 1783 1716 .ident = "TUXEDO Trinity 15 Intel Gen1", ··· 1786 1717 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1787 1718 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1501I"), 1788 1719 }, 1720 + .driver_data = &empty_descriptor, 1789 1721 }, 1790 1722 { 1791 1723 .ident = "TUXEDO Trinity 17 Intel Gen1", ··· 1794 1724 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1795 1725 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TRINITY1701I"), 1796 1726 }, 1727 + .driver_data = &empty_descriptor, 1797 1728 }, 1798 1729 { 1799 1730 .ident = "TUXEDO Polaris 15/17 Gen2 AMD", ··· 1802 1731 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1803 1732 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxMGxx"), 1804 1733 }, 1734 + .driver_data = &empty_descriptor, 1805 1735 }, 1806 1736 { 1807 1737 .ident = "TUXEDO Polaris 15/17 Gen2 Intel", ··· 1810 1738 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1811 1739 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxNGxx"), 1812 1740 }, 1741 + .driver_data = &empty_descriptor, 1813 1742 }, 1814 1743 { 1815 1744 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 AMD", ··· 1818 1745 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1819 1746 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxZGxx"), 1820 1747 }, 1748 + .driver_data = &empty_descriptor, 1821 1749 }, 1822 1750 { 1823 1751 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen3 Intel", ··· 1826 1752 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1827 1753 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxTGxx"), 1828 1754 }, 1755 + .driver_data = &empty_descriptor, 1829 1756 }, 1830 1757 { 1831 1758 .ident = "TUXEDO Stellaris/Polaris 15/17 Gen4 AMD", ··· 1834 1759 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1835 1760 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxRGxx"), 1836 1761 }, 1762 + .driver_data = &empty_descriptor, 1837 1763 }, 1838 1764 { 1839 1765 .ident = "TUXEDO Stellaris 15 Gen4 Intel", ··· 1842 1766 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1843 1767 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxAGxx"), 1844 1768 }, 1769 + .driver_data = &empty_descriptor, 1845 1770 }, 1846 1771 { 1847 1772 .ident = "TUXEDO Polaris 15/17 Gen5 AMD", ··· 1850 1773 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1851 1774 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxXGxx"), 1852 1775 }, 1776 + .driver_data = &empty_descriptor, 1853 1777 }, 1854 1778 { 1855 1779 .ident = "TUXEDO Stellaris 16 Gen5 AMD", ··· 1858 1780 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1859 1781 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6XGxX"), 1860 1782 }, 1783 + .driver_data = &empty_descriptor, 1861 1784 }, 1862 1785 { 1863 1786 .ident = "TUXEDO Stellaris 16/17 Gen5 Intel/Commodore ORION Gen 5", ··· 1866 1787 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1867 1788 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxPXxx"), 1868 1789 }, 1790 + .driver_data = &empty_descriptor, 1869 1791 }, 1870 1792 { 1871 1793 .ident = "TUXEDO Stellaris Slim 15 Gen6 AMD", ··· 1874 1794 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1875 1795 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GMxHGxx"), 1876 1796 }, 1797 + .driver_data = &empty_descriptor, 1877 1798 }, 1878 1799 { 1879 1800 .ident = "TUXEDO Stellaris Slim 15 Gen6 Intel/Commodore ORION Slim 15 Gen6", ··· 1882 1801 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1883 1802 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM5IXxA"), 1884 1803 }, 1804 + .driver_data = &empty_descriptor, 1885 1805 }, 1886 1806 { 1887 1807 .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6", ··· 1890 1808 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1891 1809 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB1"), 1892 1810 }, 1811 + .driver_data = &empty_descriptor, 1893 1812 }, 1894 1813 { 1895 1814 .ident = "TUXEDO Stellaris 16 Gen6 Intel/Commodore ORION 16 Gen6", ··· 1898 1815 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1899 1816 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM6IXxB_MB2"), 1900 1817 }, 1818 + .driver_data = &empty_descriptor, 1901 1819 }, 1902 1820 { 1903 1821 .ident = "TUXEDO Stellaris 17 Gen6 Intel/Commodore ORION 17 Gen6", ··· 1906 1822 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1907 1823 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GM7IXxN"), 1908 1824 }, 1825 + .driver_data = &empty_descriptor, 1909 1826 }, 1910 1827 { 1911 1828 .ident = "TUXEDO Stellaris 16 Gen7 AMD", ··· 1914 1829 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1915 1830 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6FR5xxY"), 1916 1831 }, 1832 + .driver_data = &empty_descriptor, 1917 1833 }, 1918 1834 { 1919 1835 .ident = "TUXEDO Stellaris 16 Gen7 Intel", ··· 1922 1836 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1923 1837 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY"), 1924 1838 }, 1839 + .driver_data = &empty_descriptor, 1925 1840 }, 1926 1841 { 1927 1842 .ident = "TUXEDO Stellaris 16 Gen7 Intel", ··· 1930 1843 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1931 1844 DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY_mLED"), 1932 1845 }, 1846 + .driver_data = &empty_descriptor, 1933 1847 }, 1934 1848 { 1935 1849 .ident = "TUXEDO Book BA15 Gen10 AMD", ··· 1938 1850 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1939 1851 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5PU1G"), 1940 1852 }, 1853 + .driver_data = &empty_descriptor, 1941 1854 }, 1942 1855 { 1943 1856 .ident = "TUXEDO Pulse 14 Gen1 AMD", ··· 1946 1857 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1947 1858 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1401"), 1948 1859 }, 1860 + .driver_data = &empty_descriptor, 1949 1861 }, 1950 1862 { 1951 1863 .ident = "TUXEDO Pulse 15 Gen1 AMD", ··· 1954 1864 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1955 1865 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PULSE1501"), 1956 1866 }, 1867 + .driver_data = &empty_descriptor, 1957 1868 }, 1958 1869 { 1959 1870 .ident = "TUXEDO Pulse 15 Gen2 AMD", ··· 1962 1871 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 1963 1872 DMI_EXACT_MATCH(DMI_BOARD_NAME, "PF5LUXG"), 1964 1873 }, 1874 + .driver_data = &empty_descriptor, 1965 1875 }, 1966 1876 { } 1967 1877 }; ··· 1970 1878 1971 1879 static int __init uniwill_init(void) 1972 1880 { 1881 + const struct uniwill_device_descriptor *descriptor; 1973 1882 const struct dmi_system_id *id; 1974 1883 int ret; 1975 1884 ··· 1980 1887 return -ENODEV; 1981 1888 1982 1889 /* Assume that the device supports all features */ 1983 - supported_features = UINT_MAX; 1890 + device_descriptor.features = UINT_MAX; 1984 1891 pr_warn("Loading on a potentially unsupported device\n"); 1985 1892 } else { 1986 - supported_features = (uintptr_t)id->driver_data; 1893 + /* 1894 + * Some devices might support additional features depending on 1895 + * the BIOS version/date, so we call this callback to let them 1896 + * modify their device descriptor accordingly. 1897 + */ 1898 + if (id->callback) { 1899 + ret = id->callback(id); 1900 + if (ret < 0) 1901 + return ret; 1902 + } 1903 + 1904 + descriptor = id->driver_data; 1905 + device_descriptor = *descriptor; 1987 1906 } 1988 1907 1989 1908 ret = platform_driver_register(&uniwill_driver);