diff options
| author | Zeng Chi <zengchi@kylinos.cn> | 2026-09-21 18:24:42 +0800 |
|---|---|---|
| committer | Sean Christopherson <seanjc@google.com> | 2026-09-22 08:36:16 -0700 |
| commit | 119e9db233ad0f4cbd4cfb9f9385a7bca378b37d (patch) | |
| tree | 660d50d4139cb750fbde1ae3432452c20726c99d /drivers/mfd/vx855.c | |
| download | linux-stable-119e9db233ad0f4cbd4cfb9f9385a7bca378b37d.tar.gz linux-stable-119e9db233ad0f4cbd4cfb9f9385a7bca378b37d.zip | |
KVM: Don't pre-reserve xarray entries when storing empty/NULL attributesgrafted
Skip the xarray reservation loop when clearing all memory attributes, as
storing NULL only erases the entry and never needs to allocate, so no
reservation (and no cleanup of a failed one) is required in that case.
Suggested-by: Sean Christopherson <seanjc@google.com>
Cc: David Ballesteros <davimaba.v@proton.me>
Signed-off-by: Zeng Chi <zengchi@kylinos.cn>
Link: https://patch.msgid.link/20260921102442.1232375-1-zeng_chi911@163.com
[sean: split to separate patch]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'drivers/mfd/vx855.c')
| -rw-r--r-- | drivers/mfd/vx855.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c new file mode 100644 index 000000000..985f81c17 --- /dev/null +++ b/drivers/mfd/vx855.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Linux multi-function-device driver (MFD) for the integrated peripherals + * of the VIA VX855 chipset + * + * Copyright (C) 2009 VIA Technologies, Inc. + * Copyright (C) 2010 One Laptop per Child + * Author: Harald Welte <HaraldWelte@viatech.com> + * All rights reserved. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/pci.h> +#include <linux/mfd/core.h> + +/* offset into pci config space indicating the 16bit register containing + * the power management IO space base */ +#define VX855_CFG_PMIO_OFFSET 0x88 + +/* ACPI I/O Space registers */ +#define VX855_PMIO_ACPI 0x00 +#define VX855_PMIO_ACPI_LEN 0x0b + +/* Processor Power Management */ +#define VX855_PMIO_PPM 0x10 +#define VX855_PMIO_PPM_LEN 0x08 + +/* General Purpose Power Management */ +#define VX855_PMIO_GPPM 0x20 +#define VX855_PMIO_R_GPI 0x48 +#define VX855_PMIO_R_GPO 0x4c +#define VX855_PMIO_GPPM_LEN 0x33 + +#define VSPIC_MMIO_SIZE 0x1000 + +static struct resource vx855_gpio_resources[] = { + { + .flags = IORESOURCE_IO, + }, + { + .flags = IORESOURCE_IO, + }, +}; + +static const struct mfd_cell vx855_cells[] = { + { + .name = "vx855_gpio", + .num_resources = ARRAY_SIZE(vx855_gpio_resources), + .resources = vx855_gpio_resources, + + /* we must ignore resource conflicts, for reasons outlined in + * the vx855_gpio driver */ + .ignore_resource_conflicts = true, + }, +}; + +static int vx855_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret; + u16 gpio_io_offset; + + ret = pci_enable_device(pdev); + if (ret) + return -ENODEV; + + pci_read_config_word(pdev, VX855_CFG_PMIO_OFFSET, &gpio_io_offset); + if (!gpio_io_offset) { + dev_warn(&pdev->dev, + "BIOS did not assign PMIO base offset?!?\n"); + ret = -ENODEV; + goto out; + } + + /* mask out the lowest seven bits, as they are always zero, but + * hardware returns them as 0x01 */ + gpio_io_offset &= 0xff80; + + /* As the region identified here includes many non-GPIO things, we + * only work with the specific registers that concern us. */ + vx855_gpio_resources[0].start = gpio_io_offset + VX855_PMIO_R_GPI; + vx855_gpio_resources[0].end = vx855_gpio_resources[0].start + 3; + vx855_gpio_resources[1].start = gpio_io_offset + VX855_PMIO_R_GPO; + vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; + + ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), + NULL, 0, NULL); + + /* we always return -ENODEV here in order to enable other + * drivers like old, not-yet-platform_device ported i2c-viapro */ + return -ENODEV; +out: + pci_disable_device(pdev); + return ret; +} + +static void vx855_remove(struct pci_dev *pdev) +{ + mfd_remove_devices(&pdev->dev); + pci_disable_device(pdev); +} + +static const struct pci_device_id vx855_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, vx855_pci_tbl); + +static struct pci_driver vx855_pci_driver = { + .name = "vx855", + .id_table = vx855_pci_tbl, + .probe = vx855_probe, + .remove = vx855_remove, +}; + +module_pci_driver(vx855_pci_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Harald Welte <HaraldWelte@viatech.com>"); +MODULE_DESCRIPTION("Driver for the VIA VX855 chipset"); |
