platform-drivers-x86 for v5.13-2

Assorted pdx86 bug-fixes and model-specific quirks for 5.13.
 
 The following is an automated git shortlog grouped by driver:
 
 dell-smbios-wmi:
  -  Fix oops on rmmod dell_smbios
 
 gigabyte-wmi:
  -  add support for B550 Aorus Elite
  -  add support for X570 UD
  -  streamline dmi matching
 
 hp-wireless:
  -  add AMD's hardware id to the supported list
 
 hp_accel:
  -  Avoid invoking _INI to speed up resume
 
 ideapad-laptop:
  -  fix method name typo
  -  fix a NULL pointer dereference
 
 intel_int0002_vgpio:
  -  Only call enable_irq_wake() when using s2idle
 
 intel_punit_ipc:
  -  Append MODULE_DEVICE_TABLE for ACPI
 
 platform/mellanox:
  -  mlxbf-tmfifo: Fix a memory barrier issue
 
 platform/surface:
  -  dtx: Fix poll function
  -  aggregator: Add platform-drivers-x86 list to MAINTAINERS entry
  -  aggregator: avoid clang -Wconstant-conversion warning
  -  aggregator: Do not mark interrupt as shared
 
 touchscreen_dmi:
  -  Add info for the Chuwi Hi10 Pro (CWI529) tablet
  -  Add info for the Mediacom Winpad 7.0 W700 tablet
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEEuvA7XScYQRpenhd+kuxHeUQDJ9wFAmCmV18UHGhkZWdvZWRl
 QHJlZGhhdC5jb20ACgkQkuxHeUQDJ9zSIQf7BKTfLK4dw15XpDk4Tie5FruysEYB
 HpS0tk5OoCiTIAT4J4DO+nbqx4+sGkyt/50uCptT4TI6CoZMgn1VqOCLF1cx0Q4T
 ilKWt+63IqtxG7/EYYp0lbleb15ea/A8XEFyayWgO/z1Xgng6+j2NyiMpwdxV2WD
 yGoO4E6VLmtxja7GaVK21s3M5z9iznul4G7pIo1yEkegxxSADUXjlqGkTEbM+eO7
 EloIGjGSCVXyl0yzStJTzKY5kkI6MXlHwicQBlGiyZN+Dzcax+kTiViGUCd9bw2X
 Sp9uSJ3DvVsKPWzjwwEXEz1wBAs1t3p0Y6WqwROjANKPgyishNCIzakkew==
 =DK1K
 -----END PGP SIGNATURE-----

Merge tag 'platform-drivers-x86-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Hans de Goede:
 "Assorted pdx86 bug-fixes and model-specific quirks for 5.13"

* tag 'platform-drivers-x86-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86:
  platform/x86: touchscreen_dmi: Add info for the Chuwi Hi10 Pro (CWI529) tablet
  platform/x86: touchscreen_dmi: Add info for the Mediacom Winpad 7.0 W700 tablet
  platform/x86: intel_punit_ipc: Append MODULE_DEVICE_TABLE for ACPI
  platform/x86: dell-smbios-wmi: Fix oops on rmmod dell_smbios
  platform/x86: hp-wireless: add AMD's hardware id to the supported list
  platform/x86: intel_int0002_vgpio: Only call enable_irq_wake() when using s2idle
  platform/x86: gigabyte-wmi: add support for B550 Aorus Elite
  platform/x86: gigabyte-wmi: add support for X570 UD
  platform/x86: gigabyte-wmi: streamline dmi matching
  platform/mellanox: mlxbf-tmfifo: Fix a memory barrier issue
  platform/surface: dtx: Fix poll function
  platform/surface: aggregator: Add platform-drivers-x86 list to MAINTAINERS entry
  platform/surface: aggregator: avoid clang -Wconstant-conversion warning
  platform/surface: aggregator: Do not mark interrupt as shared
  platform/x86: hp_accel: Avoid invoking _INI to speed up resume
  platform/x86: ideapad-laptop: fix method name typo
  platform/x86: ideapad-laptop: fix a NULL pointer dereference
This commit is contained in:
Linus Torvalds 2021-05-20 06:40:20 -10:00
commit 9ebd811816
15 changed files with 164 additions and 70 deletions

View File

@ -12180,6 +12180,7 @@ F: drivers/platform/surface/surfacepro3_button.c
MICROSOFT SURFACE SYSTEM AGGREGATOR SUBSYSTEM
M: Maximilian Luz <luzmaximilian@gmail.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
W: https://github.com/linux-surface/surface-aggregator-module
C: irc://chat.freenode.net/##linux-surface

View File

@ -271,6 +271,7 @@ struct lis3lv02d {
int regs_size;
u8 *reg_cache;
bool regs_stored;
bool init_required;
u8 odr_mask; /* ODR bit mask */
u8 whoami; /* indicates measurement precision */
s16 (*read_data) (struct lis3lv02d *lis3, int reg);

View File

@ -294,6 +294,9 @@ mlxbf_tmfifo_get_next_desc(struct mlxbf_tmfifo_vring *vring)
if (vring->next_avail == virtio16_to_cpu(vdev, vr->avail->idx))
return NULL;
/* Make sure 'avail->idx' is visible already. */
virtio_rmb(false);
idx = vring->next_avail % vr->num;
head = virtio16_to_cpu(vdev, vr->avail->ring[idx]);
if (WARN_ON(head >= vr->num))
@ -322,7 +325,7 @@ static void mlxbf_tmfifo_release_desc(struct mlxbf_tmfifo_vring *vring,
* done or not. Add a memory barrier here to make sure the update above
* completes before updating the idx.
*/
mb();
virtio_mb(false);
vr->used->idx = cpu_to_virtio16(vdev, vr_idx + 1);
}
@ -733,6 +736,12 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
desc = NULL;
fifo->vring[is_rx] = NULL;
/*
* Make sure the load/store are in order before
* returning back to virtio.
*/
virtio_mb(false);
/* Notify upper layer that packet is done. */
spin_lock_irqsave(&fifo->spin_lock[is_rx], flags);
vring_interrupt(0, vring->vq);

View File

@ -2483,8 +2483,7 @@ int ssam_irq_setup(struct ssam_controller *ctrl)
* interrupt, and let the SAM resume callback during the controller
* resume process clear it.
*/
const int irqf = IRQF_SHARED | IRQF_ONESHOT |
IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN;
const int irqf = IRQF_ONESHOT | IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN;
gpiod = gpiod_get(dev, "ssam_wakeup-int", GPIOD_ASIS);
if (IS_ERR(gpiod))

View File

@ -527,20 +527,14 @@ static __poll_t surface_dtx_poll(struct file *file, struct poll_table_struct *pt
struct sdtx_client *client = file->private_data;
__poll_t events = 0;
if (down_read_killable(&client->ddev->lock))
return -ERESTARTSYS;
if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags)) {
up_read(&client->ddev->lock);
if (test_bit(SDTX_DEVICE_SHUTDOWN_BIT, &client->ddev->flags))
return EPOLLHUP | EPOLLERR;
}
poll_wait(file, &client->ddev->waitq, pt);
if (!kfifo_is_empty(&client->buffer))
events |= EPOLLIN | EPOLLRDNORM;
up_read(&client->ddev->lock);
return events;
}

View File

@ -711,7 +711,7 @@ config INTEL_HID_EVENT
config INTEL_INT0002_VGPIO
tristate "Intel ACPI INT0002 Virtual GPIO driver"
depends on GPIOLIB && ACPI
depends on GPIOLIB && ACPI && PM_SLEEP
select GPIOLIB_IRQCHIP
help
Some peripherals on Bay Trail and Cherry Trail platforms signal a

View File

@ -270,7 +270,8 @@ int init_dell_smbios_wmi(void)
void exit_dell_smbios_wmi(void)
{
wmi_driver_unregister(&dell_smbios_wmi_driver);
if (wmi_supported)
wmi_driver_unregister(&dell_smbios_wmi_driver);
}
MODULE_DEVICE_TABLE(wmi, dell_smbios_wmi_id_table);

View File

@ -133,31 +133,21 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
return r;
}
#define DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME(name) \
{ .matches = { \
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), \
DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \
}}
static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
{ .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "B550 GAMING X V2"),
}},
{ .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "B550M AORUS PRO-P"),
}},
{ .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "B550M DS3H"),
}},
{ .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Z390 I AORUS PRO WIFI-CF"),
}},
{ .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "X570 AORUS ELITE"),
}},
{ .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "X570 I AORUS PRO WIFI"),
}},
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 GAMING X V2"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z390 I AORUS PRO WIFI-CF"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 AORUS ELITE"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 I AORUS PRO WIFI"),
DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 UD"),
{ }
};

View File

@ -17,12 +17,14 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex Hung");
MODULE_ALIAS("acpi*:HPQ6001:*");
MODULE_ALIAS("acpi*:WSTADEF:*");
MODULE_ALIAS("acpi*:AMDI0051:*");
static struct input_dev *hpwl_input_dev;
static const struct acpi_device_id hpwl_ids[] = {
{"HPQ6001", 0},
{"WSTADEF", 0},
{"AMDI0051", 0},
{"", 0},
};

View File

@ -88,6 +88,9 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
static int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
{
struct acpi_device *dev = lis3->bus_priv;
if (!lis3->init_required)
return 0;
if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
NULL, NULL) != AE_OK)
return -EINVAL;
@ -356,6 +359,7 @@ static int lis3lv02d_add(struct acpi_device *device)
}
/* call the core layer do its init */
lis3_dev.init_required = true;
ret = lis3lv02d_init_device(&lis3_dev);
if (ret)
return ret;
@ -403,11 +407,27 @@ static int lis3lv02d_suspend(struct device *dev)
static int lis3lv02d_resume(struct device *dev)
{
lis3_dev.init_required = false;
lis3lv02d_poweron(&lis3_dev);
return 0;
}
static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume);
static int lis3lv02d_restore(struct device *dev)
{
lis3_dev.init_required = true;
lis3lv02d_poweron(&lis3_dev);
return 0;
}
static const struct dev_pm_ops hp_accel_pm = {
.suspend = lis3lv02d_suspend,
.resume = lis3lv02d_resume,
.freeze = lis3lv02d_suspend,
.thaw = lis3lv02d_resume,
.poweroff = lis3lv02d_suspend,
.restore = lis3lv02d_restore,
};
#define HP_ACCEL_PM (&hp_accel_pm)
#else
#define HP_ACCEL_PM NULL

View File

@ -57,8 +57,8 @@ enum {
};
enum {
SMBC_CONSERVATION_ON = 3,
SMBC_CONSERVATION_OFF = 5,
SBMC_CONSERVATION_ON = 3,
SBMC_CONSERVATION_OFF = 5,
};
enum {
@ -182,9 +182,9 @@ static int eval_gbmd(acpi_handle handle, unsigned long *res)
return eval_int(handle, "GBMD", res);
}
static int exec_smbc(acpi_handle handle, unsigned long arg)
static int exec_sbmc(acpi_handle handle, unsigned long arg)
{
return exec_simple_method(handle, "SMBC", arg);
return exec_simple_method(handle, "SBMC", arg);
}
static int eval_hals(acpi_handle handle, unsigned long *res)
@ -477,7 +477,7 @@ static ssize_t conservation_mode_store(struct device *dev,
if (err)
return err;
err = exec_smbc(priv->adev->handle, state ? SMBC_CONSERVATION_ON : SMBC_CONSERVATION_OFF);
err = exec_sbmc(priv->adev->handle, state ? SBMC_CONSERVATION_ON : SBMC_CONSERVATION_OFF);
if (err)
return err;
@ -809,6 +809,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
{
struct ideapad_dytc_priv *dytc = container_of(pprof, struct ideapad_dytc_priv, pprof);
struct ideapad_private *priv = dytc->priv;
unsigned long output;
int err;
err = mutex_lock_interruptible(&dytc->mutex);
@ -829,7 +830,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
/* Determine if we are in CQL mode. This alters the commands we do */
err = dytc_cql_command(priv, DYTC_SET_COMMAND(DYTC_FUNCTION_MMC, perfmode, 1),
NULL);
&output);
if (err)
goto unlock;
}

View File

@ -51,6 +51,12 @@
#define GPE0A_STS_PORT 0x420
#define GPE0A_EN_PORT 0x428
struct int0002_data {
struct gpio_chip chip;
int parent_irq;
int wake_enable_count;
};
/*
* As this is not a real GPIO at all, but just a hack to model an event in
* ACPI the get / set functions are dummy functions.
@ -98,14 +104,16 @@ static void int0002_irq_mask(struct irq_data *data)
static int int0002_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct platform_device *pdev = to_platform_device(chip->parent);
int irq = platform_get_irq(pdev, 0);
struct int0002_data *int0002 = container_of(chip, struct int0002_data, chip);
/* Propagate to parent irq */
/*
* Applying of the wakeup flag to our parent IRQ is delayed till system
* suspend, because we only want to do this when using s2idle.
*/
if (on)
enable_irq_wake(irq);
int0002->wake_enable_count++;
else
disable_irq_wake(irq);
int0002->wake_enable_count--;
return 0;
}
@ -135,7 +143,7 @@ static bool int0002_check_wake(void *data)
return (gpe_sts_reg & GPE0A_PME_B0_STS_BIT);
}
static struct irq_chip int0002_byt_irqchip = {
static struct irq_chip int0002_irqchip = {
.name = DRV_NAME,
.irq_ack = int0002_irq_ack,
.irq_mask = int0002_irq_mask,
@ -143,21 +151,9 @@ static struct irq_chip int0002_byt_irqchip = {
.irq_set_wake = int0002_irq_set_wake,
};
static struct irq_chip int0002_cht_irqchip = {
.name = DRV_NAME,
.irq_ack = int0002_irq_ack,
.irq_mask = int0002_irq_mask,
.irq_unmask = int0002_irq_unmask,
/*
* No set_wake, on CHT the IRQ is typically shared with the ACPI SCI
* and we don't want to mess with the ACPI SCI irq settings.
*/
.flags = IRQCHIP_SKIP_SET_WAKE,
};
static const struct x86_cpu_id int0002_cpu_ids[] = {
X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &int0002_byt_irqchip),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &int0002_cht_irqchip),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, NULL),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, NULL),
{}
};
@ -172,8 +168,9 @@ static int int0002_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct x86_cpu_id *cpu_id;
struct gpio_chip *chip;
struct int0002_data *int0002;
struct gpio_irq_chip *girq;
struct gpio_chip *chip;
int irq, ret;
/* Menlow has a different INT0002 device? <sigh> */
@ -185,10 +182,13 @@ static int int0002_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
int0002 = devm_kzalloc(dev, sizeof(*int0002), GFP_KERNEL);
if (!int0002)
return -ENOMEM;
int0002->parent_irq = irq;
chip = &int0002->chip;
chip->label = DRV_NAME;
chip->parent = dev;
chip->owner = THIS_MODULE;
@ -214,7 +214,7 @@ static int int0002_probe(struct platform_device *pdev)
}
girq = &chip->irq;
girq->chip = (struct irq_chip *)cpu_id->driver_data;
girq->chip = &int0002_irqchip;
/* This let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
@ -230,6 +230,7 @@ static int int0002_probe(struct platform_device *pdev)
acpi_register_wakeup_handler(irq, int0002_check_wake, NULL);
device_init_wakeup(dev, true);
dev_set_drvdata(dev, int0002);
return 0;
}
@ -240,6 +241,36 @@ static int int0002_remove(struct platform_device *pdev)
return 0;
}
static int int0002_suspend(struct device *dev)
{
struct int0002_data *int0002 = dev_get_drvdata(dev);
/*
* The INT0002 parent IRQ is often shared with the ACPI GPE IRQ, don't
* muck with it when firmware based suspend is used, otherwise we may
* cause spurious wakeups from firmware managed suspend.
*/
if (!pm_suspend_via_firmware() && int0002->wake_enable_count)
enable_irq_wake(int0002->parent_irq);
return 0;
}
static int int0002_resume(struct device *dev)
{
struct int0002_data *int0002 = dev_get_drvdata(dev);
if (!pm_suspend_via_firmware() && int0002->wake_enable_count)
disable_irq_wake(int0002->parent_irq);
return 0;
}
static const struct dev_pm_ops int0002_pm_ops = {
.suspend = int0002_suspend,
.resume = int0002_resume,
};
static const struct acpi_device_id int0002_acpi_ids[] = {
{ "INT0002", 0 },
{ },
@ -250,6 +281,7 @@ static struct platform_driver int0002_driver = {
.driver = {
.name = DRV_NAME,
.acpi_match_table = int0002_acpi_ids,
.pm = &int0002_pm_ops,
},
.probe = int0002_probe,
.remove = int0002_remove,

View File

@ -312,6 +312,7 @@ static const struct acpi_device_id punit_ipc_acpi_ids[] = {
{ "INT34D4", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids);
static struct platform_driver intel_punit_ipc_driver = {
.probe = intel_punit_ipc_probe,

View File

@ -115,6 +115,32 @@ static const struct ts_dmi_data chuwi_hi10_plus_data = {
.properties = chuwi_hi10_plus_props,
};
static const struct property_entry chuwi_hi10_pro_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 8),
PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1912),
PROPERTY_ENTRY_U32("touchscreen-size-y", 1272),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi10-pro.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
PROPERTY_ENTRY_BOOL("silead,home-button"),
{ }
};
static const struct ts_dmi_data chuwi_hi10_pro_data = {
.embedded_fw = {
.name = "silead/gsl1680-chuwi-hi10-pro.fw",
.prefix = { 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 },
.length = 42504,
.sha256 = { 0xdb, 0x92, 0x68, 0xa8, 0xdb, 0x81, 0x31, 0x00,
0x1f, 0x58, 0x89, 0xdb, 0x19, 0x1b, 0x15, 0x8c,
0x05, 0x14, 0xf4, 0x95, 0xba, 0x15, 0x45, 0x98,
0x42, 0xa3, 0xbb, 0x65, 0xe3, 0x30, 0xa5, 0x93 },
},
.acpi_name = "MSSL1680:00",
.properties = chuwi_hi10_pro_props,
};
static const struct property_entry chuwi_vi8_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
PROPERTY_ENTRY_U32("touchscreen-min-y", 6),
@ -915,6 +941,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
},
},
{
/* Chuwi Hi10 Prus (CWI597) */
.driver_data = (void *)&chuwi_hi10_pro_data,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
DMI_MATCH(DMI_PRODUCT_NAME, "Hi10 pro tablet"),
DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
},
},
{
/* Chuwi Vi8 (CWI506) */
.driver_data = (void *)&chuwi_vi8_data,
@ -1096,6 +1131,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
},
},
{
/* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */
.driver_data = (void *)&trekstor_surftab_wintron70_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
DMI_MATCH(DMI_PRODUCT_NAME, "WinPad 7 W10 - WPW700"),
},
},
{
/* Mediacom Flexbook Edge 11 (same hw as TS Primebook C11) */
.driver_data = (void *)&trekstor_primebook_c11_data,

View File

@ -98,9 +98,9 @@ struct ssam_device_uid {
| (((fun) != SSAM_ANY_FUN) ? SSAM_MATCH_FUNCTION : 0), \
.domain = d, \
.category = cat, \
.target = ((tid) != SSAM_ANY_TID) ? (tid) : 0, \
.instance = ((iid) != SSAM_ANY_IID) ? (iid) : 0, \
.function = ((fun) != SSAM_ANY_FUN) ? (fun) : 0 \
.target = __builtin_choose_expr((tid) != SSAM_ANY_TID, (tid), 0), \
.instance = __builtin_choose_expr((iid) != SSAM_ANY_IID, (iid), 0), \
.function = __builtin_choose_expr((fun) != SSAM_ANY_FUN, (fun), 0)
/**
* SSAM_VDEV() - Initialize a &struct ssam_device_id as virtual device with