forked from Minki/linux
ACPI updates for 6.1-rc1
- Reimplement acpi_get_pci_dev() using the list of physical devices associated with the given ACPI device object (Rafael Wysocki). - Rename ACPI device object reference counting functions (Rafael Wysocki). - Rearrange ACPI device object initialization code (Rafael Wysocki). - Drop parent field from struct acpi_device (Rafael Wysocki). - Extend the the int3472-tps68470 driver to support multiple consumers of a single TPS68470 along with the requisite framework-level support (Daniel Scally). - Filter out non-memory resources in is_memory(), add a helper function to find all memory type resources of an ACPI device object and use that function in 3 places (Heikki Krogerus). - Add IRQ override quirks for Asus Vivobook K3402ZA/K3502ZA and ASUS model S5402ZA (Tamim Khan, Kellen Renshaw). - Fix acpi_dev_state_d0() kerneldoc (Sakari Ailus). - Fix up suspend-to-idle support on ASUS Rembrandt laptops (Mario Limonciello). - Clean up ACPI platform devices support code (Andy Shevchenko, John Garry). - Clean up ACPI bus management code (Andy Shevchenko, ye xingchen). - Add support for multiple DMA windows with different offsets to the ACPI device enumeration code and use it on LoongArch (Jianmin Lv). - Clean up the ACPI LPSS (Intel SoC) driver (Andy Shevchenko). - Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable (Mario Limonciello). - Drop unused dev_fmt() and redundant 'HMAT' prefix from the HMAT parsing code (Liu Shixin). - Make ACPI FPDT parsing code avoid calling acpi_os_map_memory() on invalid physical addresses (Hans de Goede). - Silence missing-declarations warning related to Apple device properties management (Lukas Wunner). - Disable frequency invariance in the CPPC library if registers used by cppc_get_perf_ctrs() are accessed via PCC (Jeremy Linton). - Add ACPI disabled check to acpi_cpc_valid() (Perry Yuan). - Fix Tx acknowledge in the PCC address space handler (Huisong Li). - Use wait_for_completion_timeout() for PCC mailbox operations (Huisong Li). - Release resources on PCC address space setup failure path (Rafael Mendonca). - Remove unneeded result variables from APEI code (ye xingchen). - Print total number of records found during BERT log parsing (Dmitry Monakhov). - Drop support for 3 _OSI strings that should not be necessary any more and update documentation on custom _OSI strings so that adding new ones is not encouraged any more (Mario Limonciello). - Drop unneeded result variable from ec_write() (ye xingchen). - Remove the leftover struct acpi_ac_bl from the ACPI AC driver (Hanjun Guo). - Reorder symbols to get rid of a few forward declarations in the ACPI fan driver (Uwe Kleine-König). - Add Toshiba Satellite/Portege Z830 ACPI backlight quirk (Arvid Norlander). - Add ARM DMA-330 controller to the supported list in the ACPI AMBA driver (Vijayenthiran Subramaniam). - Drop references to non-functional 01.org/linux-acpi web site from MAINTAINERS and Kconfig help texts (Rafael Wysocki). - Replace strlcpy() with unused retval with strscpy() in the ACPI support code (Wolfram Sang). - Do not initialize ret in main() in the pfrut utility (Shi junming). - Drop useless ACPI DSDT override documentation (Rafael Wysocki). - Fix a few typos and wording mistakes in the ACPI device enumeration documentation (Jean Delvare). - Introduce acpi_dev_uid_to_integer() to convert a _UID string into an integer value (Andy Shevchenko). - Use acpi_dev_uid_to_integer() in several places to unify _UID handling (Andy Shevchenko). - Drop unused pnpid32_to_pnpid() declaration from PNP code (Gaosheng Cui). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmM7OhkSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRx/TkQALQ4TN451dPSj9jcYSNY6qZ/9b4P9Iym TmRf3wO3+IVZQ8JajeKKRuVKNsW3sC0RcFkJJVmgZkydJBr1Uui2L0ZLzi8axGNy RlbZm5NyBeFnlP0fA8Gb2iRMXVAUcRIx+RvZCulxxFmgQ8UhoU4wlVZWlEcko4TQ hGp++lJYcRHR1NbVLSXZhFvzopKLdhGL6vB1Awsjb/I7TVqn23+k4jVRV1DYkIQ7 qgFM+Z7osRVZiVQbaPoOgdykeSa43qXu7Vgs7F/QeJuIiUYx59xDh0/WCJBxnuDM cHGiaNnvuJghKmCg43X8+joaHEH/jCFyvBVGfiSzRvjz03WOPRs1XztwdEiCi+py RcZGzrPaXmkCjNeytPRooiifyqm95HT7aMBN/aTvKBXDaGRrfPheXF+i2idl24HM NrHqMaa0+5qoDGHLUEaf5znlCHfS+3lwq6+lGVrq/UGf6B3cP+9HwOyevEW493JX 4nuv69Y517moR9W3mBU8sAn5mUjshcka7pghRj7QnuoqRqWLbU3lIz8oUDHr84cI ixpIPvt2KlZ5UjnN9aqu/6k70JkJvy4SrKjnx4iqu03ePmMrRc0Hcpy7+VMlgumD tgN9aW+YDgy0/Z5QmO1MOvFodVmA5sX6+gnX1neAjuDdIo3LkJptlkO1fCx2jfQu cgPQk1CtPOos =xyUK -----END PGP SIGNATURE----- Merge tag 'acpi-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI updates from Rafael Wysocki: "ACPI and PNP updates for 6.1-rc1. These rearrange the ACPI device object initialization code (to get rid of a redundant parent pointer from struct acpi_device among other things), unify the _UID handling, drop support for some _OSI strings that should not be necessary any more, add new IDs to support more hardware and some more quirks, fix a few issues and clean up code all over. Specifics: - Reimplement acpi_get_pci_dev() using the list of physical devices associated with the given ACPI device object (Rafael Wysocki) - Rename ACPI device object reference counting functions (Rafael Wysocki) - Rearrange ACPI device object initialization code (Rafael Wysocki) - Drop parent field from struct acpi_device (Rafael Wysocki) - Extend the the int3472-tps68470 driver to support multiple consumers of a single TPS68470 along with the requisite framework-level support (Daniel Scally) - Filter out non-memory resources in is_memory(), add a helper function to find all memory type resources of an ACPI device object and use that function in 3 places (Heikki Krogerus) - Add IRQ override quirks for Asus Vivobook K3402ZA/K3502ZA and ASUS model S5402ZA (Tamim Khan, Kellen Renshaw) - Fix acpi_dev_state_d0() kerneldoc (Sakari Ailus) - Fix up suspend-to-idle support on ASUS Rembrandt laptops (Mario Limonciello) - Clean up ACPI platform devices support code (Andy Shevchenko, John Garry) - Clean up ACPI bus management code (Andy Shevchenko, ye xingchen) - Add support for multiple DMA windows with different offsets to the ACPI device enumeration code and use it on LoongArch (Jianmin Lv) - Clean up the ACPI LPSS (Intel SoC) driver (Andy Shevchenko) - Add a quirk for Dell Inspiron 14 2-in-1 for StorageD3Enable (Mario Limonciello) - Drop unused dev_fmt() and redundant 'HMAT' prefix from the HMAT parsing code (Liu Shixin) - Make ACPI FPDT parsing code avoid calling acpi_os_map_memory() on invalid physical addresses (Hans de Goede) - Silence missing-declarations warning related to Apple device properties management (Lukas Wunner) - Disable frequency invariance in the CPPC library if registers used by cppc_get_perf_ctrs() are accessed via PCC (Jeremy Linton) - Add ACPI disabled check to acpi_cpc_valid() (Perry Yuan) - Fix Tx acknowledge in the PCC address space handler (Huisong Li) - Use wait_for_completion_timeout() for PCC mailbox operations (Huisong Li) - Release resources on PCC address space setup failure path (Rafael Mendonca) - Remove unneeded result variables from APEI code (ye xingchen) - Print total number of records found during BERT log parsing (Dmitry Monakhov) - Drop support for 3 _OSI strings that should not be necessary any more and update documentation on custom _OSI strings so that adding new ones is not encouraged any more (Mario Limonciello) - Drop unneeded result variable from ec_write() (ye xingchen) - Remove the leftover struct acpi_ac_bl from the ACPI AC driver (Hanjun Guo) - Reorder symbols to get rid of a few forward declarations in the ACPI fan driver (Uwe Kleine-König) - Add Toshiba Satellite/Portege Z830 ACPI backlight quirk (Arvid Norlander) - Add ARM DMA-330 controller to the supported list in the ACPI AMBA driver (Vijayenthiran Subramaniam) - Drop references to non-functional 01.org/linux-acpi web site from MAINTAINERS and Kconfig help texts (Rafael Wysocki) - Replace strlcpy() with unused retval with strscpy() in the ACPI support code (Wolfram Sang) - Do not initialize ret in main() in the pfrut utility (Shi junming) - Drop useless ACPI DSDT override documentation (Rafael Wysocki) - Fix a few typos and wording mistakes in the ACPI device enumeration documentation (Jean Delvare) - Introduce acpi_dev_uid_to_integer() to convert a _UID string into an integer value (Andy Shevchenko) - Use acpi_dev_uid_to_integer() in several places to unify _UID handling (Andy Shevchenko) - Drop unused pnpid32_to_pnpid() declaration from PNP code (Gaosheng Cui)" * tag 'acpi-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (79 commits) ACPI: LPSS: Deduplicate skipping device in acpi_lpss_create_device() ACPI: LPSS: Replace loop with first entry retrieval ACPI: x86: s2idle: Add another ID to s2idle_dmi_table ACPI: x86: s2idle: Fix a NULL pointer dereference MAINTAINERS: Drop records pointing to 01.org/linux-acpi ACPI: Kconfig: Drop link to https://01.org/linux-acpi ACPI: docs: Drop useless DSDT override documentation ACPI: DPTF: Drop stale link from Kconfig help ACPI: x86: s2idle: Add a quirk for ASUSTeK COMPUTER INC. ROG Flow X13 ACPI: x86: s2idle: Add a quirk for Lenovo Slim 7 Pro 14ARH7 ACPI: x86: s2idle: Add a quirk for ASUS ROG Zephyrus G14 ACPI: x86: s2idle: Add a quirk for ASUS TUF Gaming A17 FA707RE ACPI: x86: s2idle: Add module parameter to prefer Microsoft GUID ACPI: x86: s2idle: If a new AMD _HID is missing assume Rembrandt ACPI: x86: s2idle: Move _HID handling for AMD systems into structures platform/x86: int3472: Add board data for Surface Go2 IR camera platform/x86: int3472: Support multiple gpio lookups in board data platform/x86: int3472: Support multiple clock consumers ACPI: bus: Add iterator for dependent devices ACPI: scan: Add acpi_dev_get_next_consumer_dev() ...
This commit is contained in:
commit
9388076b4c
@ -1,13 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===============
|
||||
Overriding DSDT
|
||||
===============
|
||||
|
||||
Linux supports a method of overriding the BIOS DSDT:
|
||||
|
||||
CONFIG_ACPI_CUSTOM_DSDT - builds the image into the kernel.
|
||||
|
||||
When to use this method is described in detail on the
|
||||
Linux/ACPI home page:
|
||||
https://01.org/linux-acpi/documentation/overriding-dsdt
|
@ -21,7 +21,7 @@ possible we decided to do following:
|
||||
- Devices behind real busses where there is a connector resource
|
||||
are represented as struct spi_device or struct i2c_device. Note
|
||||
that standard UARTs are not busses so there is no struct uart_device,
|
||||
although some of them may be represented by sturct serdev_device.
|
||||
although some of them may be represented by struct serdev_device.
|
||||
|
||||
As both ACPI and Device Tree represent a tree of devices (and their
|
||||
resources) this implementation follows the Device Tree way as much as
|
||||
@ -205,7 +205,7 @@ Here is what the ACPI namespace for a SPI slave might look like::
|
||||
}
|
||||
...
|
||||
|
||||
The SPI device drivers only need to add ACPI IDs in a similar way than with
|
||||
The SPI device drivers only need to add ACPI IDs in a similar way to
|
||||
the platform device drivers. Below is an example where we add ACPI support
|
||||
to at25 SPI eeprom driver (this is meant for the above ACPI snippet)::
|
||||
|
||||
@ -362,7 +362,7 @@ These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
|
||||
specifies the path to the controller. In order to use these GPIOs in Linux
|
||||
we need to translate them to the corresponding Linux GPIO descriptors.
|
||||
|
||||
There is a standard GPIO API for that and is documented in
|
||||
There is a standard GPIO API for that and it is documented in
|
||||
Documentation/admin-guide/gpio/.
|
||||
|
||||
In the above example we can get the corresponding two GPIO descriptors with
|
||||
@ -538,8 +538,8 @@ information.
|
||||
PCI hierarchy representation
|
||||
============================
|
||||
|
||||
Sometimes could be useful to enumerate a PCI device, knowing its position on the
|
||||
PCI bus.
|
||||
Sometimes it could be useful to enumerate a PCI device, knowing its position on
|
||||
the PCI bus.
|
||||
|
||||
For example, some systems use PCI devices soldered directly on the mother board,
|
||||
in a fixed position (ethernet, Wi-Fi, serial ports, etc.). In this conditions it
|
||||
@ -550,7 +550,7 @@ To identify a PCI device, a complete hierarchical description is required, from
|
||||
the chipset root port to the final device, through all the intermediate
|
||||
bridges/switches of the board.
|
||||
|
||||
For example, let us assume to have a system with a PCIe serial port, an
|
||||
For example, let's assume we have a system with a PCIe serial port, an
|
||||
Exar XR17V3521, soldered on the main board. This UART chip also includes
|
||||
16 GPIOs and we want to add the property ``gpio-line-names`` [1] to these pins.
|
||||
In this case, the ``lspci`` output for this component is::
|
||||
@ -593,8 +593,8 @@ of the chipset bridge (also called "root port") with address::
|
||||
|
||||
Bus: 0 - Device: 14 - Function: 1
|
||||
|
||||
To find this information is necessary disassemble the BIOS ACPI tables, in
|
||||
particular the DSDT (see also [2])::
|
||||
To find this information, it is necessary to disassemble the BIOS ACPI tables,
|
||||
in particular the DSDT (see also [2])::
|
||||
|
||||
mkdir ~/tables/
|
||||
cd ~/tables/
|
||||
|
@ -41,26 +41,23 @@ But it is likely that they will all eventually be added.
|
||||
What should an OEM do if they want to support Linux and Windows
|
||||
using the same BIOS image? Often they need to do something different
|
||||
for Linux to deal with how Linux is different from Windows.
|
||||
Here the BIOS should ask exactly what it wants to know:
|
||||
|
||||
In this case, the OEM should create custom ASL to be executed by the
|
||||
Linux kernel and changes to Linux kernel drivers to execute this custom
|
||||
ASL. The easiest way to accomplish this is to introduce a device specific
|
||||
method (_DSM) that is called from the Linux kernel.
|
||||
|
||||
In the past the kernel used to support something like:
|
||||
_OSI("Linux-OEM-my_interface_name")
|
||||
where 'OEM' is needed if this is an OEM-specific hook,
|
||||
and 'my_interface_name' describes the hook, which could be a
|
||||
quirk, a bug, or a bug-fix.
|
||||
|
||||
In addition, the OEM should send a patch to upstream Linux
|
||||
via the linux-acpi@vger.kernel.org mailing list. When that patch
|
||||
is checked into Linux, the OS will answer "YES" when the BIOS
|
||||
on the OEM's system uses _OSI to ask if the interface is supported
|
||||
by the OS. Linux distributors can back-port that patch for Linux
|
||||
pre-installs, and it will be included by all distributions that
|
||||
re-base to upstream. If the distribution can not update the kernel binary,
|
||||
they can also add an acpi_osi=Linux-OEM-my_interface_name
|
||||
cmdline parameter to the boot loader, as needed.
|
||||
|
||||
If the string refers to a feature where the upstream kernel
|
||||
eventually grows support, a patch should be sent to remove
|
||||
the string when that support is added to the kernel.
|
||||
However this was discovered to be abused by other BIOS vendors to change
|
||||
completely unrelated code on completely unrelated systems. This prompted
|
||||
an evaluation of all of it's uses. This uncovered that they aren't needed
|
||||
for any of the original reasons. As such, the kernel will not respond to
|
||||
any custom Linux-* strings by default.
|
||||
|
||||
That was easy. Read on, to find out how to do it wrong.
|
||||
|
||||
|
@ -348,7 +348,6 @@ M: "Rafael J. Wysocki" <rafael@kernel.org>
|
||||
R: Len Brown <lenb@kernel.org>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://01.org/linux-acpi
|
||||
Q: https://patchwork.kernel.org/project/linux-acpi/list/
|
||||
B: https://bugzilla.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
|
||||
@ -427,7 +426,6 @@ M: Rafael J. Wysocki <rafael@kernel.org>
|
||||
R: Zhang Rui <rui.zhang@intel.com>
|
||||
L: linux-acpi@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://01.org/linux-acpi
|
||||
B: https://bugzilla.kernel.org
|
||||
F: drivers/acpi/*thermal*
|
||||
|
||||
@ -10378,7 +10376,6 @@ INTEL MENLOW THERMAL DRIVER
|
||||
M: Sujith Thomas <sujith.thomas@intel.com>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://01.org/linux-acpi
|
||||
F: drivers/thermal/intel/intel_menlow.c
|
||||
|
||||
INTEL P-Unit IPC DRIVER
|
||||
|
@ -10,7 +10,6 @@ config LOONGARCH
|
||||
select ARCH_ENABLE_MEMORY_HOTPLUG
|
||||
select ARCH_ENABLE_MEMORY_HOTREMOVE
|
||||
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
|
||||
select ARCH_HAS_PHYS_TO_DMA
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_INLINE_READ_LOCK if !PREEMPTION
|
||||
|
@ -2,39 +2,29 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dma-direct.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/swiotlb.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/loongson.h>
|
||||
|
||||
/*
|
||||
* We extract 4bit node id (bit 44~47) from Loongson-3's
|
||||
* 48bit physical address space and embed it into 40bit.
|
||||
*/
|
||||
|
||||
static int node_id_offset;
|
||||
|
||||
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
|
||||
void acpi_arch_dma_setup(struct device *dev)
|
||||
{
|
||||
long nid = (paddr >> 44) & 0xf;
|
||||
int ret;
|
||||
u64 mask, end = 0;
|
||||
const struct bus_dma_region *map = NULL;
|
||||
|
||||
ret = acpi_dma_get_range(dev, &map);
|
||||
if (!ret && map) {
|
||||
const struct bus_dma_region *r = map;
|
||||
|
||||
for (end = 0; r->size; r++) {
|
||||
if (r->dma_start + r->size - 1 > end)
|
||||
end = r->dma_start + r->size - 1;
|
||||
}
|
||||
|
||||
mask = DMA_BIT_MASK(ilog2(end) + 1);
|
||||
dev->bus_dma_limit = end;
|
||||
dev->dma_range_map = map;
|
||||
dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
|
||||
*dev->dma_mask = min(*dev->dma_mask, mask);
|
||||
}
|
||||
|
||||
return ((nid << 44) ^ paddr) | (nid << node_id_offset);
|
||||
}
|
||||
|
||||
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
|
||||
{
|
||||
long nid = (daddr >> node_id_offset) & 0xf;
|
||||
|
||||
return ((nid << node_id_offset) ^ daddr) | (nid << 44);
|
||||
}
|
||||
|
||||
void __init plat_swiotlb_setup(void)
|
||||
{
|
||||
swiotlb_init(true, SWIOTLB_VERBOSE);
|
||||
node_id_offset = ((readl(LS7A_DMA_CFG) & LS7A_DMA_NODE_MASK) >> LS7A_DMA_NODE_SHF) + 36;
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ static void __init arch_mem_init(char **cmdline_p)
|
||||
sparse_init();
|
||||
memblock_set_bottom_up(true);
|
||||
|
||||
plat_swiotlb_setup();
|
||||
swiotlb_init(true, SWIOTLB_VERBOSE);
|
||||
|
||||
dma_contiguous_reserve(PFN_PHYS(max_low_pfn));
|
||||
|
||||
|
@ -27,9 +27,6 @@ menuconfig ACPI
|
||||
Management (APM) specification. If both ACPI and APM support
|
||||
are configured, ACPI is used.
|
||||
|
||||
The project home page for the Linux ACPI subsystem is here:
|
||||
<https://01.org/linux-acpi>
|
||||
|
||||
Linux support for ACPI is based on Intel Corporation's ACPI
|
||||
Component Architecture (ACPI CA). For more information on the
|
||||
ACPI CA, see:
|
||||
@ -347,7 +344,6 @@ config ACPI_CUSTOM_DSDT_FILE
|
||||
depends on !STANDALONE
|
||||
help
|
||||
This option supports a custom DSDT by linking it into the kernel.
|
||||
See Documentation/admin-guide/acpi/dsdt-override.rst
|
||||
|
||||
Enter the full path name to the file which includes the AmlCode
|
||||
or dsdt_aml_code declaration.
|
||||
|
@ -36,11 +36,6 @@ static int acpi_ac_add(struct acpi_device *device);
|
||||
static int acpi_ac_remove(struct acpi_device *device);
|
||||
static void acpi_ac_notify(struct acpi_device *device, u32 event);
|
||||
|
||||
struct acpi_ac_bl {
|
||||
const char *hid;
|
||||
int hrv;
|
||||
};
|
||||
|
||||
static const struct acpi_device_id ac_device_ids[] = {
|
||||
{"ACPI0003", 0},
|
||||
{"", 0},
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
static const struct acpi_device_id amba_id_list[] = {
|
||||
{"ARMH0061", 0}, /* PL061 GPIO Device */
|
||||
{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
|
||||
{"ARMHC500", 0}, /* ARM CoreSight ETM4x */
|
||||
{"ARMHC501", 0}, /* ARM CoreSight ETR */
|
||||
{"ARMHC502", 0}, /* ARM CoreSight STM */
|
||||
@ -48,6 +49,7 @@ static void amba_register_dummy_clk(void)
|
||||
static int amba_handler_attach(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
{
|
||||
struct acpi_device *parent = acpi_dev_parent(adev);
|
||||
struct amba_device *dev;
|
||||
struct resource_entry *rentry;
|
||||
struct list_head resource_list;
|
||||
@ -97,8 +99,8 @@ static int amba_handler_attach(struct acpi_device *adev,
|
||||
* attached to it, that physical device should be the parent of
|
||||
* the amba device we are about to create.
|
||||
*/
|
||||
if (adev->parent)
|
||||
dev->dev.parent = acpi_get_first_physical_node(adev->parent);
|
||||
if (parent)
|
||||
dev->dev.parent = acpi_get_first_physical_node(parent);
|
||||
|
||||
ACPI_COMPANION_SET(&dev->dev, adev);
|
||||
|
||||
|
@ -60,12 +60,6 @@ static int acpi_apd_setup(struct apd_private_data *pdata)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
|
||||
static int misc_check_res(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct resource res;
|
||||
|
||||
return !acpi_dev_resource_memory(ares, &res);
|
||||
}
|
||||
|
||||
static int fch_misc_setup(struct apd_private_data *pdata)
|
||||
{
|
||||
@ -82,8 +76,7 @@ static int fch_misc_setup(struct apd_private_data *pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res,
|
||||
NULL);
|
||||
ret = acpi_dev_get_memory_resources(adev, &resource_list);
|
||||
if (ret < 0)
|
||||
return -ENOENT;
|
||||
|
||||
|
@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = {
|
||||
|
||||
static struct kobject *fpdt_kobj;
|
||||
|
||||
#if defined CONFIG_X86 && defined CONFIG_PHYS_ADDR_T_64BIT
|
||||
#include <linux/processor.h>
|
||||
static bool fpdt_address_valid(u64 address)
|
||||
{
|
||||
/*
|
||||
* On some systems the table contains invalid addresses
|
||||
* with unsuppored high address bits set, check for this.
|
||||
*/
|
||||
return !(address >> boot_cpu_data.x86_phys_bits);
|
||||
}
|
||||
#else
|
||||
static bool fpdt_address_valid(u64 address)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int fpdt_process_subtable(u64 address, u32 subtable_type)
|
||||
{
|
||||
struct fpdt_subtable_header *subtable_header;
|
||||
@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
|
||||
u32 length, offset;
|
||||
int result;
|
||||
|
||||
if (!fpdt_address_valid(address)) {
|
||||
pr_info(FW_BUG "invalid physical address: 0x%llx!\n", address);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
subtable_header = acpi_os_map_memory(address, sizeof(*subtable_header));
|
||||
if (!subtable_header)
|
||||
return -ENOMEM;
|
||||
|
@ -167,10 +167,10 @@ static struct pwm_lookup byt_pwm_lookup[] = {
|
||||
|
||||
static void byt_pwm_setup(struct lpss_private_data *pdata)
|
||||
{
|
||||
struct acpi_device *adev = pdata->adev;
|
||||
u64 uid;
|
||||
|
||||
/* Only call pwm_add_table for the first PWM controller */
|
||||
if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
|
||||
if (acpi_dev_uid_to_integer(pdata->adev, &uid) || uid != 1)
|
||||
return;
|
||||
|
||||
pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup));
|
||||
@ -180,14 +180,13 @@ static void byt_pwm_setup(struct lpss_private_data *pdata)
|
||||
|
||||
static void byt_i2c_setup(struct lpss_private_data *pdata)
|
||||
{
|
||||
const char *uid_str = acpi_device_uid(pdata->adev);
|
||||
acpi_handle handle = pdata->adev->handle;
|
||||
unsigned long long shared_host = 0;
|
||||
acpi_status status;
|
||||
long uid = 0;
|
||||
u64 uid;
|
||||
|
||||
/* Expected to always be true, but better safe then sorry */
|
||||
if (uid_str && !kstrtol(uid_str, 10, &uid) && uid) {
|
||||
/* Expected to always be successfull, but better safe then sorry */
|
||||
if (!acpi_dev_uid_to_integer(pdata->adev, &uid) && uid) {
|
||||
/* Detect I2C bus shared with PUNIT and ignore its d3 status */
|
||||
status = acpi_evaluate_integer(handle, "_SEM", NULL, &shared_host);
|
||||
if (ACPI_SUCCESS(status) && shared_host)
|
||||
@ -211,10 +210,10 @@ static struct pwm_lookup bsw_pwm_lookup[] = {
|
||||
|
||||
static void bsw_pwm_setup(struct lpss_private_data *pdata)
|
||||
{
|
||||
struct acpi_device *adev = pdata->adev;
|
||||
u64 uid;
|
||||
|
||||
/* Only call pwm_add_table for the first PWM controller */
|
||||
if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
|
||||
if (acpi_dev_uid_to_integer(pdata->adev, &uid) || uid != 1)
|
||||
return;
|
||||
|
||||
pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup));
|
||||
@ -392,13 +391,6 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
||||
|
||||
#ifdef CONFIG_X86_INTEL_LPSS
|
||||
|
||||
static int is_memory(struct acpi_resource *res, void *not_used)
|
||||
{
|
||||
struct resource r;
|
||||
|
||||
return !acpi_dev_resource_memory(res, &r);
|
||||
}
|
||||
|
||||
/* LPSS main clock device. */
|
||||
static struct platform_device *lpss_clk_dev;
|
||||
|
||||
@ -659,29 +651,25 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL);
|
||||
ret = acpi_dev_get_memory_resources(adev, &resource_list);
|
||||
if (ret < 0)
|
||||
goto err_out;
|
||||
|
||||
list_for_each_entry(rentry, &resource_list, node)
|
||||
if (resource_type(rentry->res) == IORESOURCE_MEM) {
|
||||
if (dev_desc->prv_size_override)
|
||||
pdata->mmio_size = dev_desc->prv_size_override;
|
||||
else
|
||||
pdata->mmio_size = resource_size(rentry->res);
|
||||
pdata->mmio_base = ioremap(rentry->res->start,
|
||||
pdata->mmio_size);
|
||||
break;
|
||||
}
|
||||
rentry = list_first_entry_or_null(&resource_list, struct resource_entry, node);
|
||||
if (rentry) {
|
||||
if (dev_desc->prv_size_override)
|
||||
pdata->mmio_size = dev_desc->prv_size_override;
|
||||
else
|
||||
pdata->mmio_size = resource_size(rentry->res);
|
||||
pdata->mmio_base = ioremap(rentry->res->start, pdata->mmio_size);
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
if (!pdata->mmio_base) {
|
||||
/* Avoid acpi_bus_attach() instantiating a pdev for this dev. */
|
||||
adev->pnp.type.platform_id = 0;
|
||||
/* Skip the device, but continue the namespace scan. */
|
||||
ret = 0;
|
||||
goto err_out;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
pdata->adev = adev;
|
||||
@ -692,11 +680,8 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
|
||||
if (dev_desc->flags & LPSS_CLK) {
|
||||
ret = register_device_clock(adev, pdata);
|
||||
if (ret) {
|
||||
/* Skip the device, but continue the namespace scan. */
|
||||
ret = 0;
|
||||
goto err_out;
|
||||
}
|
||||
if (ret)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -708,15 +693,19 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
|
||||
adev->driver_data = pdata;
|
||||
pdev = acpi_create_platform_device(adev, dev_desc->properties);
|
||||
if (!IS_ERR_OR_NULL(pdev)) {
|
||||
acpi_lpss_create_device_links(adev, pdev);
|
||||
return 1;
|
||||
if (IS_ERR_OR_NULL(pdev)) {
|
||||
adev->driver_data = NULL;
|
||||
ret = PTR_ERR(pdev);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ret = PTR_ERR(pdev);
|
||||
adev->driver_data = NULL;
|
||||
acpi_lpss_create_device_links(adev, pdev);
|
||||
return 1;
|
||||
|
||||
err_out:
|
||||
out_free:
|
||||
/* Skip the device, but continue the namespace scan */
|
||||
ret = 0;
|
||||
err_out:
|
||||
kfree(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
@ -23,6 +23,12 @@
|
||||
|
||||
#include <acpi/pcc.h>
|
||||
|
||||
/*
|
||||
* Arbitrary retries in case the remote processor is slow to respond
|
||||
* to PCC commands
|
||||
*/
|
||||
#define PCC_CMD_WAIT_RETRIES_NUM 500
|
||||
|
||||
struct pcc_data {
|
||||
struct pcc_mbox_chan *pcc_chan;
|
||||
void __iomem *pcc_comm_addr;
|
||||
@ -63,6 +69,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
||||
if (IS_ERR(data->pcc_chan)) {
|
||||
pr_err("Failed to find PCC channel for subspace %d\n",
|
||||
ctx->subspace_id);
|
||||
kfree(data);
|
||||
return AE_NOT_FOUND;
|
||||
}
|
||||
|
||||
@ -72,6 +79,8 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
|
||||
if (!data->pcc_comm_addr) {
|
||||
pr_err("Failed to ioremap PCC comm region mem for %d\n",
|
||||
ctx->subspace_id);
|
||||
pcc_mbox_free_channel(data->pcc_chan);
|
||||
kfree(data);
|
||||
return AE_NO_MEMORY;
|
||||
}
|
||||
|
||||
@ -86,6 +95,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
|
||||
{
|
||||
int ret;
|
||||
struct pcc_data *data = region_context;
|
||||
u64 usecs_lat;
|
||||
|
||||
reinit_completion(&data->done);
|
||||
|
||||
@ -96,10 +106,22 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
|
||||
if (ret < 0)
|
||||
return AE_ERROR;
|
||||
|
||||
if (data->pcc_chan->mchan->mbox->txdone_irq)
|
||||
wait_for_completion(&data->done);
|
||||
if (data->pcc_chan->mchan->mbox->txdone_irq) {
|
||||
/*
|
||||
* pcc_chan->latency is just a Nominal value. In reality the remote
|
||||
* processor could be much slower to reply. So add an arbitrary
|
||||
* amount of wait on top of Nominal.
|
||||
*/
|
||||
usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
|
||||
ret = wait_for_completion_timeout(&data->done,
|
||||
usecs_to_jiffies(usecs_lat));
|
||||
if (ret == 0) {
|
||||
pr_err("PCC command executed timeout!\n");
|
||||
return AE_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
mbox_client_txdone(data->pcc_chan->mchan, ret);
|
||||
mbox_chan_txdone(data->pcc_chan->mchan, ret);
|
||||
|
||||
memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length);
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
||||
#include "internal.h"
|
||||
|
||||
static const struct acpi_device_id forbidden_id_list[] = {
|
||||
{"ACPI0009", 0}, /* IOxAPIC */
|
||||
{"ACPI000A", 0}, /* IOAPIC */
|
||||
{"PNP0000", 0}, /* PIC */
|
||||
{"PNP0100", 0}, /* Timer */
|
||||
{"PNP0200", 0}, /* AT DMA Controller */
|
||||
{"ACPI0009", 0}, /* IOxAPIC */
|
||||
{"ACPI000A", 0}, /* IOAPIC */
|
||||
{"SMB0001", 0}, /* ACPI SMBUS virtual device */
|
||||
{"", 0},
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_device *acpi_platform_device_find_by_companion(struct acpi_device *adev)
|
||||
@ -78,7 +78,7 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
|
||||
* If the device has parent we need to take its resources into
|
||||
* account as well because this device might consume part of those.
|
||||
*/
|
||||
parent = acpi_get_first_physical_node(adev->parent);
|
||||
parent = acpi_get_first_physical_node(acpi_dev_parent(adev));
|
||||
if (parent && dev_is_pci(parent))
|
||||
dest->parent = pci_find_resource(to_pci_dev(parent), dest);
|
||||
}
|
||||
@ -97,6 +97,7 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
|
||||
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
||||
const struct property_entry *properties)
|
||||
{
|
||||
struct acpi_device *parent = acpi_dev_parent(adev);
|
||||
struct platform_device *pdev = NULL;
|
||||
struct platform_device_info pdevinfo;
|
||||
struct resource_entry *rentry;
|
||||
@ -113,13 +114,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
||||
if (count < 0) {
|
||||
if (count < 0)
|
||||
return NULL;
|
||||
} else if (count > 0) {
|
||||
resources = kcalloc(count, sizeof(struct resource),
|
||||
GFP_KERNEL);
|
||||
if (count > 0) {
|
||||
resources = kcalloc(count, sizeof(*resources), GFP_KERNEL);
|
||||
if (!resources) {
|
||||
dev_err(&adev->dev, "No memory for resources\n");
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
@ -137,10 +136,9 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
||||
* attached to it, that physical device should be the parent of the
|
||||
* platform device we are about to create.
|
||||
*/
|
||||
pdevinfo.parent = adev->parent ?
|
||||
acpi_get_first_physical_node(adev->parent) : NULL;
|
||||
pdevinfo.parent = parent ? acpi_get_first_physical_node(parent) : NULL;
|
||||
pdevinfo.name = dev_name(&adev->dev);
|
||||
pdevinfo.id = -1;
|
||||
pdevinfo.id = PLATFORM_DEVID_NONE;
|
||||
pdevinfo.res = resources;
|
||||
pdevinfo.num_res = count;
|
||||
pdevinfo.fwnode = acpi_fwnode_handle(adev);
|
||||
|
@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_disable_backlight_sysfs_if,
|
||||
.ident = "Toshiba Satellite Z830",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_disable_backlight_sysfs_if,
|
||||
.ident = "Toshiba Portege Z830",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
|
||||
* but the IDs actually follow the Device ID Scheme.
|
||||
@ -2030,7 +2046,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
|
||||
device->parent->handle, 1,
|
||||
acpi_dev_parent(device)->handle, 1,
|
||||
acpi_video_bus_match, NULL,
|
||||
device, NULL);
|
||||
if (status == AE_ALREADY_EXISTS) {
|
||||
|
@ -125,12 +125,9 @@ EXPORT_SYMBOL_GPL(apei_exec_write_register);
|
||||
int apei_exec_write_register_value(struct apei_exec_context *ctx,
|
||||
struct acpi_whea_header *entry)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ctx->value = entry->value;
|
||||
rc = apei_exec_write_register(ctx, entry);
|
||||
|
||||
return rc;
|
||||
return apei_exec_write_register(ctx, entry);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apei_exec_write_register_value);
|
||||
|
||||
|
@ -90,6 +90,9 @@ static void __init bert_print_all(struct acpi_bert_region *region,
|
||||
|
||||
if (skipped)
|
||||
pr_info(HW_ERR "Skipped %d error records\n", skipped);
|
||||
|
||||
if (printed + skipped)
|
||||
pr_info("Total records found: %d\n", printed + skipped);
|
||||
}
|
||||
|
||||
static int __init setup_bert_disable(char *str)
|
||||
|
@ -1020,14 +1020,10 @@ static int reader_pos;
|
||||
|
||||
static int erst_open_pstore(struct pstore_info *psi)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (erst_disable)
|
||||
return -ENODEV;
|
||||
|
||||
rc = erst_get_record_id_begin(&reader_pos);
|
||||
|
||||
return rc;
|
||||
return erst_get_record_id_begin(&reader_pos);
|
||||
}
|
||||
|
||||
static int erst_close_pstore(struct pstore_info *psi)
|
||||
|
@ -4,11 +4,12 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-direct.h>
|
||||
|
||||
void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
||||
void acpi_arch_dma_setup(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
u64 end, mask;
|
||||
u64 dmaaddr = 0, size = 0, offset = 0;
|
||||
u64 size = 0;
|
||||
const struct bus_dma_region *map = NULL;
|
||||
|
||||
/*
|
||||
* If @dev is expected to be DMA-capable then the bus code that created
|
||||
@ -26,7 +27,19 @@ void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
||||
else
|
||||
size = 1ULL << 32;
|
||||
|
||||
ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
|
||||
ret = acpi_dma_get_range(dev, &map);
|
||||
if (!ret && map) {
|
||||
const struct bus_dma_region *r = map;
|
||||
|
||||
for (end = 0; r->size; r++) {
|
||||
if (r->dma_start + r->size - 1 > end)
|
||||
end = r->dma_start + r->size - 1;
|
||||
}
|
||||
|
||||
size = end + 1;
|
||||
dev->dma_range_map = map;
|
||||
}
|
||||
|
||||
if (ret == -ENODEV)
|
||||
ret = iort_dma_get_ranges(dev, &size);
|
||||
if (!ret) {
|
||||
@ -34,17 +47,10 @@ void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
||||
* Limit coherent and dma mask based on size retrieved from
|
||||
* firmware.
|
||||
*/
|
||||
end = dmaaddr + size - 1;
|
||||
end = size - 1;
|
||||
mask = DMA_BIT_MASK(ilog2(end) + 1);
|
||||
dev->bus_dma_limit = end;
|
||||
dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
|
||||
*dev->dma_mask = min(*dev->dma_mask, mask);
|
||||
}
|
||||
|
||||
*dma_addr = dmaaddr;
|
||||
*dma_size = size;
|
||||
|
||||
ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
|
||||
|
||||
dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ out_free:
|
||||
Notification Handling
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
/*
|
||||
* acpi_bus_notify
|
||||
* ---------------
|
||||
* Callback for all 'system-level' device notifications (values 0x00-0x7F).
|
||||
@ -511,7 +511,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
|
||||
break;
|
||||
}
|
||||
|
||||
adev = acpi_bus_get_acpi_device(handle);
|
||||
adev = acpi_get_acpi_dev(handle);
|
||||
if (!adev)
|
||||
goto err;
|
||||
|
||||
@ -524,14 +524,14 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
|
||||
}
|
||||
|
||||
if (!hotplug_event) {
|
||||
acpi_bus_put_acpi_device(adev);
|
||||
acpi_put_acpi_dev(adev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ACPI_SUCCESS(acpi_hotplug_schedule(adev, type)))
|
||||
return;
|
||||
|
||||
acpi_bus_put_acpi_device(adev);
|
||||
acpi_put_acpi_dev(adev);
|
||||
|
||||
err:
|
||||
acpi_evaluate_ost(handle, type, ost_code, NULL);
|
||||
@ -802,7 +802,7 @@ static bool acpi_of_modalias(struct acpi_device *adev,
|
||||
|
||||
str = obj->string.pointer;
|
||||
chr = strchr(str, ',');
|
||||
strlcpy(modalias, chr ? chr + 1 : str, len);
|
||||
strscpy(modalias, chr ? chr + 1 : str, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -822,7 +822,7 @@ void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
|
||||
char *modalias, size_t len)
|
||||
{
|
||||
if (!acpi_of_modalias(adev, modalias, len))
|
||||
strlcpy(modalias, default_id, len);
|
||||
strscpy(modalias, default_id, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_set_modalias);
|
||||
|
||||
@ -925,12 +925,13 @@ static const void *acpi_of_device_get_match_data(const struct device *dev)
|
||||
|
||||
const void *acpi_device_get_match_data(const struct device *dev)
|
||||
{
|
||||
const struct acpi_device_id *acpi_ids = dev->driver->acpi_match_table;
|
||||
const struct acpi_device_id *match;
|
||||
|
||||
if (!dev->driver->acpi_match_table)
|
||||
if (!acpi_ids)
|
||||
return acpi_of_device_get_match_data(dev);
|
||||
|
||||
match = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||||
match = acpi_match_device(acpi_ids, dev);
|
||||
if (!match)
|
||||
return NULL;
|
||||
|
||||
@ -948,14 +949,13 @@ EXPORT_SYMBOL(acpi_match_device_ids);
|
||||
bool acpi_driver_match_device(struct device *dev,
|
||||
const struct device_driver *drv)
|
||||
{
|
||||
if (!drv->acpi_match_table)
|
||||
return acpi_of_match_device(ACPI_COMPANION(dev),
|
||||
drv->of_match_table,
|
||||
NULL);
|
||||
const struct acpi_device_id *acpi_ids = drv->acpi_match_table;
|
||||
const struct of_device_id *of_ids = drv->of_match_table;
|
||||
|
||||
return __acpi_match_device(acpi_companion_match(dev),
|
||||
drv->acpi_match_table, drv->of_match_table,
|
||||
NULL, NULL);
|
||||
if (!acpi_ids)
|
||||
return acpi_of_match_device(ACPI_COMPANION(dev), of_ids, NULL);
|
||||
|
||||
return __acpi_match_device(acpi_companion_match(dev), acpi_ids, of_ids, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_driver_match_device);
|
||||
|
||||
@ -973,16 +973,13 @@ EXPORT_SYMBOL_GPL(acpi_driver_match_device);
|
||||
*/
|
||||
int acpi_bus_register_driver(struct acpi_driver *driver)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
driver->drv.name = driver->name;
|
||||
driver->drv.bus = &acpi_bus_type;
|
||||
driver->drv.owner = driver->owner;
|
||||
|
||||
ret = driver_register(&driver->drv);
|
||||
return ret;
|
||||
return driver_register(&driver->drv);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_bus_register_driver);
|
||||
|
@ -424,6 +424,9 @@ bool acpi_cpc_valid(void)
|
||||
struct cpc_desc *cpc_ptr;
|
||||
int cpu;
|
||||
|
||||
if (acpi_disabled)
|
||||
return false;
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
|
||||
if (!cpc_ptr)
|
||||
@ -1240,6 +1243,48 @@ out_err:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cppc_get_perf_caps);
|
||||
|
||||
/**
|
||||
* cppc_perf_ctrs_in_pcc - Check if any perf counters are in a PCC region.
|
||||
*
|
||||
* CPPC has flexibility about how CPU performance counters are accessed.
|
||||
* One of the choices is PCC regions, which can have a high access latency. This
|
||||
* routine allows callers of cppc_get_perf_ctrs() to know this ahead of time.
|
||||
*
|
||||
* Return: true if any of the counters are in PCC regions, false otherwise
|
||||
*/
|
||||
bool cppc_perf_ctrs_in_pcc(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
for_each_present_cpu(cpu) {
|
||||
struct cpc_register_resource *ref_perf_reg;
|
||||
struct cpc_desc *cpc_desc;
|
||||
|
||||
cpc_desc = per_cpu(cpc_desc_ptr, cpu);
|
||||
|
||||
if (CPC_IN_PCC(&cpc_desc->cpc_regs[DELIVERED_CTR]) ||
|
||||
CPC_IN_PCC(&cpc_desc->cpc_regs[REFERENCE_CTR]) ||
|
||||
CPC_IN_PCC(&cpc_desc->cpc_regs[CTR_WRAP_TIME]))
|
||||
return true;
|
||||
|
||||
|
||||
ref_perf_reg = &cpc_desc->cpc_regs[REFERENCE_PERF];
|
||||
|
||||
/*
|
||||
* If reference perf register is not supported then we should
|
||||
* use the nominal perf value
|
||||
*/
|
||||
if (!CPC_SUPPORTED(ref_perf_reg))
|
||||
ref_perf_reg = &cpc_desc->cpc_regs[NOMINAL_PERF];
|
||||
|
||||
if (CPC_IN_PCC(ref_perf_reg))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cppc_perf_ctrs_in_pcc);
|
||||
|
||||
/**
|
||||
* cppc_get_perf_ctrs - Read a CPU's performance feedback counters.
|
||||
* @cpunum: CPU from which to read counters.
|
||||
|
@ -75,15 +75,17 @@ static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state)
|
||||
int acpi_device_get_power(struct acpi_device *device, int *state)
|
||||
{
|
||||
int result = ACPI_STATE_UNKNOWN;
|
||||
struct acpi_device *parent;
|
||||
int error;
|
||||
|
||||
if (!device || !state)
|
||||
return -EINVAL;
|
||||
|
||||
parent = acpi_dev_parent(device);
|
||||
|
||||
if (!device->flags.power_manageable) {
|
||||
/* TBD: Non-recursive algorithm for walking up hierarchy. */
|
||||
*state = device->parent ?
|
||||
device->parent->power.state : ACPI_STATE_D0;
|
||||
*state = parent ? parent->power.state : ACPI_STATE_D0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -122,10 +124,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
|
||||
* point, the fact that the device is in D0 implies that the parent has
|
||||
* to be in D0 too, except if ignore_parent is set.
|
||||
*/
|
||||
if (!device->power.flags.ignore_parent && device->parent
|
||||
&& device->parent->power.state == ACPI_STATE_UNKNOWN
|
||||
&& result == ACPI_STATE_D0)
|
||||
device->parent->power.state = ACPI_STATE_D0;
|
||||
if (!device->power.flags.ignore_parent && parent &&
|
||||
parent->power.state == ACPI_STATE_UNKNOWN &&
|
||||
result == ACPI_STATE_D0)
|
||||
parent->power.state = ACPI_STATE_D0;
|
||||
|
||||
*state = result;
|
||||
|
||||
@ -191,13 +193,17 @@ int acpi_device_set_power(struct acpi_device *device, int state)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!device->power.flags.ignore_parent && device->parent &&
|
||||
state < device->parent->power.state) {
|
||||
acpi_handle_debug(device->handle,
|
||||
"Cannot transition to %s for parent in %s\n",
|
||||
acpi_power_state_string(state),
|
||||
acpi_power_state_string(device->parent->power.state));
|
||||
return -ENODEV;
|
||||
if (!device->power.flags.ignore_parent) {
|
||||
struct acpi_device *parent;
|
||||
|
||||
parent = acpi_dev_parent(device);
|
||||
if (parent && state < parent->power.state) {
|
||||
acpi_handle_debug(device->handle,
|
||||
"Cannot transition to %s for parent in %s\n",
|
||||
acpi_power_state_string(state),
|
||||
acpi_power_state_string(parent->power.state));
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -497,7 +503,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
|
||||
|
||||
acpi_handle_debug(handle, "Wake notify\n");
|
||||
|
||||
adev = acpi_bus_get_acpi_device(handle);
|
||||
adev = acpi_get_acpi_dev(handle);
|
||||
if (!adev)
|
||||
return;
|
||||
|
||||
@ -515,7 +521,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
|
||||
|
||||
mutex_unlock(&acpi_pm_notifier_lock);
|
||||
|
||||
acpi_bus_put_acpi_device(adev);
|
||||
acpi_put_acpi_dev(adev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1460,7 +1466,7 @@ EXPORT_SYMBOL_GPL(acpi_storage_d3);
|
||||
* not valid to ask for the ACPI power state of the device in that time frame.
|
||||
*
|
||||
* This function is intended to be used in a driver's probe or remove
|
||||
* function. See Documentation/firmware-guide/acpi/low-power-probe.rst for
|
||||
* function. See Documentation/firmware-guide/acpi/non-d0-probe.rst for
|
||||
* more information.
|
||||
*/
|
||||
bool acpi_dev_state_d0(struct device *dev)
|
||||
|
@ -11,9 +11,6 @@ menuconfig ACPI_DPTF
|
||||
a coordinated approach for different policies to effect the hardware
|
||||
state of a system.
|
||||
|
||||
For more information see:
|
||||
<https://01.org/intel%C2%AE-dynamic-platform-and-thermal-framework-dptf-chromium-os/overview>
|
||||
|
||||
if ACPI_DPTF
|
||||
|
||||
config DPTF_POWER
|
||||
|
@ -917,14 +917,10 @@ EXPORT_SYMBOL(ec_read);
|
||||
|
||||
int ec_write(u8 addr, u8 val)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!first_ec)
|
||||
return -ENODEV;
|
||||
|
||||
err = acpi_ec_write(first_ec, addr, val);
|
||||
|
||||
return err;
|
||||
return acpi_ec_write(first_ec, addr, val);
|
||||
}
|
||||
EXPORT_SYMBOL(ec_write);
|
||||
|
||||
|
@ -19,43 +19,12 @@
|
||||
|
||||
#include "fan.h"
|
||||
|
||||
MODULE_AUTHOR("Paul Diefenbaugh");
|
||||
MODULE_DESCRIPTION("ACPI Fan Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int acpi_fan_probe(struct platform_device *pdev);
|
||||
static int acpi_fan_remove(struct platform_device *pdev);
|
||||
|
||||
static const struct acpi_device_id fan_device_ids[] = {
|
||||
ACPI_FAN_DEVICE_IDS,
|
||||
{"", 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, fan_device_ids);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int acpi_fan_suspend(struct device *dev);
|
||||
static int acpi_fan_resume(struct device *dev);
|
||||
static const struct dev_pm_ops acpi_fan_pm = {
|
||||
.resume = acpi_fan_resume,
|
||||
.freeze = acpi_fan_suspend,
|
||||
.thaw = acpi_fan_resume,
|
||||
.restore = acpi_fan_resume,
|
||||
};
|
||||
#define FAN_PM_OPS_PTR (&acpi_fan_pm)
|
||||
#else
|
||||
#define FAN_PM_OPS_PTR NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver acpi_fan_driver = {
|
||||
.probe = acpi_fan_probe,
|
||||
.remove = acpi_fan_remove,
|
||||
.driver = {
|
||||
.name = "acpi-fan",
|
||||
.acpi_match_table = fan_device_ids,
|
||||
.pm = FAN_PM_OPS_PTR,
|
||||
},
|
||||
};
|
||||
|
||||
/* thermal cooling device callbacks */
|
||||
static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
|
||||
*state)
|
||||
@ -459,6 +428,33 @@ static int acpi_fan_resume(struct device *dev)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops acpi_fan_pm = {
|
||||
.resume = acpi_fan_resume,
|
||||
.freeze = acpi_fan_suspend,
|
||||
.thaw = acpi_fan_resume,
|
||||
.restore = acpi_fan_resume,
|
||||
};
|
||||
#define FAN_PM_OPS_PTR (&acpi_fan_pm)
|
||||
|
||||
#else
|
||||
|
||||
#define FAN_PM_OPS_PTR NULL
|
||||
|
||||
#endif
|
||||
|
||||
static struct platform_driver acpi_fan_driver = {
|
||||
.probe = acpi_fan_probe,
|
||||
.remove = acpi_fan_remove,
|
||||
.driver = {
|
||||
.name = "acpi-fan",
|
||||
.acpi_match_table = fan_device_ids,
|
||||
.pm = FAN_PM_OPS_PTR,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(acpi_fan_driver);
|
||||
|
||||
MODULE_AUTHOR("Paul Diefenbaugh");
|
||||
MODULE_DESCRIPTION("ACPI Fan Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -102,10 +102,10 @@ struct acpi_device_bus_id {
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
int acpi_device_add(struct acpi_device *device,
|
||||
void (*release)(struct device *));
|
||||
void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
|
||||
int type);
|
||||
int type, void (*release)(struct device *));
|
||||
int acpi_tie_acpi_dev(struct acpi_device *adev);
|
||||
int acpi_device_add(struct acpi_device *device);
|
||||
int acpi_device_setup_files(struct acpi_device *dev);
|
||||
void acpi_device_remove_files(struct acpi_device *dev);
|
||||
void acpi_device_add_finalize(struct acpi_device *device);
|
||||
|
@ -118,12 +118,12 @@ acpi_get_irq_source_fwhandle(const struct acpi_resource_source *source,
|
||||
if (WARN_ON(ACPI_FAILURE(status)))
|
||||
return NULL;
|
||||
|
||||
device = acpi_bus_get_acpi_device(handle);
|
||||
device = acpi_get_acpi_dev(handle);
|
||||
if (WARN_ON(!device))
|
||||
return NULL;
|
||||
|
||||
result = &device->fwnode;
|
||||
acpi_bus_put_acpi_device(device);
|
||||
acpi_put_acpi_dev(device);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "acpi/hmat: " fmt
|
||||
#define dev_fmt(fmt) "acpi/hmat: " fmt
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitops.h>
|
||||
@ -302,7 +301,7 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header,
|
||||
u8 type, mem_hier;
|
||||
|
||||
if (hmat_loc->header.length < sizeof(*hmat_loc)) {
|
||||
pr_notice("HMAT: Unexpected locality header length: %u\n",
|
||||
pr_notice("Unexpected locality header length: %u\n",
|
||||
hmat_loc->header.length);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -314,12 +313,12 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header,
|
||||
total_size = sizeof(*hmat_loc) + sizeof(*entries) * ipds * tpds +
|
||||
sizeof(*inits) * ipds + sizeof(*targs) * tpds;
|
||||
if (hmat_loc->header.length < total_size) {
|
||||
pr_notice("HMAT: Unexpected locality header length:%u, minimum required:%u\n",
|
||||
pr_notice("Unexpected locality header length:%u, minimum required:%u\n",
|
||||
hmat_loc->header.length, total_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_info("HMAT: Locality: Flags:%02x Type:%s Initiator Domains:%u Target Domains:%u Base:%lld\n",
|
||||
pr_info("Locality: Flags:%02x Type:%s Initiator Domains:%u Target Domains:%u Base:%lld\n",
|
||||
hmat_loc->flags, hmat_data_type(type), ipds, tpds,
|
||||
hmat_loc->entry_base_unit);
|
||||
|
||||
@ -363,13 +362,13 @@ static __init int hmat_parse_cache(union acpi_subtable_headers *header,
|
||||
u32 attrs;
|
||||
|
||||
if (cache->header.length < sizeof(*cache)) {
|
||||
pr_notice("HMAT: Unexpected cache header length: %u\n",
|
||||
pr_notice("Unexpected cache header length: %u\n",
|
||||
cache->header.length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
attrs = cache->cache_attributes;
|
||||
pr_info("HMAT: Cache: Domain:%u Size:%llu Attrs:%08x SMBIOS Handles:%d\n",
|
||||
pr_info("Cache: Domain:%u Size:%llu Attrs:%08x SMBIOS Handles:%d\n",
|
||||
cache->memory_PD, cache->cache_size, attrs,
|
||||
cache->number_of_SMBIOShandles);
|
||||
|
||||
@ -424,24 +423,24 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade
|
||||
struct memory_target *target = NULL;
|
||||
|
||||
if (p->header.length != sizeof(*p)) {
|
||||
pr_notice("HMAT: Unexpected address range header length: %u\n",
|
||||
pr_notice("Unexpected address range header length: %u\n",
|
||||
p->header.length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hmat_revision == 1)
|
||||
pr_info("HMAT: Memory (%#llx length %#llx) Flags:%04x Processor Domain:%u Memory Domain:%u\n",
|
||||
pr_info("Memory (%#llx length %#llx) Flags:%04x Processor Domain:%u Memory Domain:%u\n",
|
||||
p->reserved3, p->reserved4, p->flags, p->processor_PD,
|
||||
p->memory_PD);
|
||||
else
|
||||
pr_info("HMAT: Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n",
|
||||
pr_info("Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n",
|
||||
p->flags, p->processor_PD, p->memory_PD);
|
||||
|
||||
if ((hmat_revision == 1 && p->flags & ACPI_HMAT_MEMORY_PD_VALID) ||
|
||||
hmat_revision > 1) {
|
||||
target = find_mem_target(p->memory_PD);
|
||||
if (!target) {
|
||||
pr_debug("HMAT: Memory Domain missing from SRAT\n");
|
||||
pr_debug("Memory Domain missing from SRAT\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -449,7 +448,7 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade
|
||||
int p_node = pxm_to_node(p->processor_PD);
|
||||
|
||||
if (p_node == NUMA_NO_NODE) {
|
||||
pr_debug("HMAT: Invalid Processor Domain\n");
|
||||
pr_debug("Invalid Processor Domain\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
target->processor_pxm = p->processor_PD;
|
||||
@ -840,7 +839,7 @@ static __init int hmat_init(void)
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
pr_notice("Ignoring HMAT: Unknown revision:%d\n", hmat_revision);
|
||||
pr_notice("Ignoring: Unknown revision:%d\n", hmat_revision);
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
@ -848,7 +847,7 @@ static __init int hmat_init(void)
|
||||
if (acpi_table_parse_entries(ACPI_SIG_HMAT,
|
||||
sizeof(struct acpi_table_hmat), i,
|
||||
hmat_parse_subtable, 0) < 0) {
|
||||
pr_notice("Ignoring HMAT: Invalid table");
|
||||
pr_notice("Ignoring: Invalid table");
|
||||
goto out_put;
|
||||
}
|
||||
}
|
||||
|
@ -44,30 +44,6 @@ osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = {
|
||||
{"Processor Device", true},
|
||||
{"3.0 _SCP Extensions", true},
|
||||
{"Processor Aggregator Device", true},
|
||||
/*
|
||||
* Linux-Dell-Video is used by BIOS to disable RTD3 for NVidia graphics
|
||||
* cards as RTD3 is not supported by drivers now. Systems with NVidia
|
||||
* cards will hang without RTD3 disabled.
|
||||
*
|
||||
* Once NVidia drivers officially support RTD3, this _OSI strings can
|
||||
* be removed if both new and old graphics cards are supported.
|
||||
*/
|
||||
{"Linux-Dell-Video", true},
|
||||
/*
|
||||
* Linux-Lenovo-NV-HDMI-Audio is used by BIOS to power on NVidia's HDMI
|
||||
* audio device which is turned off for power-saving in Windows OS.
|
||||
* This power management feature observed on some Lenovo Thinkpad
|
||||
* systems which will not be able to output audio via HDMI without
|
||||
* a BIOS workaround.
|
||||
*/
|
||||
{"Linux-Lenovo-NV-HDMI-Audio", true},
|
||||
/*
|
||||
* Linux-HPI-Hybrid-Graphics is used by BIOS to enable dGPU to
|
||||
* output video directly to external monitors on HP Inc. mobile
|
||||
* workstations as Nvidia and AMD VGA drivers provide limited
|
||||
* hybrid graphics supports.
|
||||
*/
|
||||
{"Linux-HPI-Hybrid-Graphics", true},
|
||||
};
|
||||
|
||||
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
|
||||
|
@ -312,76 +312,25 @@ struct acpi_handle_node {
|
||||
*/
|
||||
struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
|
||||
{
|
||||
int dev, fn;
|
||||
unsigned long long adr;
|
||||
acpi_status status;
|
||||
acpi_handle phandle;
|
||||
struct pci_bus *pbus;
|
||||
struct pci_dev *pdev = NULL;
|
||||
struct acpi_handle_node *node, *tmp;
|
||||
struct acpi_pci_root *root;
|
||||
LIST_HEAD(device_list);
|
||||
struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
|
||||
struct acpi_device_physical_node *pn;
|
||||
struct pci_dev *pci_dev = NULL;
|
||||
|
||||
/*
|
||||
* Walk up the ACPI CA namespace until we reach a PCI root bridge.
|
||||
*/
|
||||
phandle = handle;
|
||||
while (!acpi_is_root_bridge(phandle)) {
|
||||
node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL);
|
||||
if (!node)
|
||||
goto out;
|
||||
if (!adev)
|
||||
return NULL;
|
||||
|
||||
INIT_LIST_HEAD(&node->node);
|
||||
node->handle = phandle;
|
||||
list_add(&node->node, &device_list);
|
||||
mutex_lock(&adev->physical_node_lock);
|
||||
|
||||
status = acpi_get_parent(phandle, &phandle);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto out;
|
||||
}
|
||||
|
||||
root = acpi_pci_find_root(phandle);
|
||||
if (!root)
|
||||
goto out;
|
||||
|
||||
pbus = root->bus;
|
||||
|
||||
/*
|
||||
* Now, walk back down the PCI device tree until we return to our
|
||||
* original handle. Assumes that everything between the PCI root
|
||||
* bridge and the device we're looking for must be a P2P bridge.
|
||||
*/
|
||||
list_for_each_entry(node, &device_list, node) {
|
||||
acpi_handle hnd = node->handle;
|
||||
status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto out;
|
||||
dev = (adr >> 16) & 0xffff;
|
||||
fn = adr & 0xffff;
|
||||
|
||||
pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn));
|
||||
if (!pdev || hnd == handle)
|
||||
break;
|
||||
|
||||
pbus = pdev->subordinate;
|
||||
pci_dev_put(pdev);
|
||||
|
||||
/*
|
||||
* This function may be called for a non-PCI device that has a
|
||||
* PCI parent (eg. a disk under a PCI SATA controller). In that
|
||||
* case pdev->subordinate will be NULL for the parent.
|
||||
*/
|
||||
if (!pbus) {
|
||||
dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n");
|
||||
pdev = NULL;
|
||||
list_for_each_entry(pn, &adev->physical_node_list, node) {
|
||||
if (dev_is_pci(pn->dev)) {
|
||||
pci_dev = to_pci_dev(pn->dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
list_for_each_entry_safe(node, tmp, &device_list, node)
|
||||
kfree(node);
|
||||
|
||||
return pdev;
|
||||
mutex_unlock(&adev->physical_node_lock);
|
||||
|
||||
return pci_dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
|
||||
|
||||
|
@ -944,13 +944,15 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
|
||||
return NULL;
|
||||
|
||||
device = &resource->device;
|
||||
acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER);
|
||||
acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER,
|
||||
acpi_release_power_resource);
|
||||
mutex_init(&resource->resource_lock);
|
||||
INIT_LIST_HEAD(&resource->list_node);
|
||||
INIT_LIST_HEAD(&resource->dependents);
|
||||
strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
|
||||
device->power.state = ACPI_STATE_UNKNOWN;
|
||||
device->flags.match_driver = true;
|
||||
|
||||
/* Evaluate the object to get the system level and resource order. */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
|
||||
@ -967,8 +969,11 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
|
||||
|
||||
pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device));
|
||||
|
||||
device->flags.match_driver = true;
|
||||
result = acpi_device_add(device, acpi_release_power_resource);
|
||||
result = acpi_tie_acpi_dev(device);
|
||||
if (result)
|
||||
goto err;
|
||||
|
||||
result = acpi_device_add(device);
|
||||
if (result)
|
||||
goto err;
|
||||
|
||||
|
@ -804,7 +804,7 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
|
||||
|
||||
state = &drv->states[count];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
|
||||
strlcpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
|
||||
strscpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = cx->latency;
|
||||
state->target_residency = cx->latency * latency_factor;
|
||||
state->enter = acpi_idle_enter;
|
||||
@ -973,7 +973,7 @@ static int acpi_processor_evaluate_lpi(acpi_handle handle,
|
||||
|
||||
obj = pkg_elem + 9;
|
||||
if (obj->type == ACPI_TYPE_STRING)
|
||||
strlcpy(lpi_state->desc, obj->string.pointer,
|
||||
strscpy(lpi_state->desc, obj->string.pointer,
|
||||
ACPI_CX_DESC_LEN);
|
||||
|
||||
lpi_state->index = state_idx;
|
||||
@ -1039,7 +1039,7 @@ static bool combine_lpi_states(struct acpi_lpi_state *local,
|
||||
result->arch_flags = parent->arch_flags;
|
||||
result->index = parent->index;
|
||||
|
||||
strlcpy(result->desc, local->desc, ACPI_CX_DESC_LEN);
|
||||
strscpy(result->desc, local->desc, ACPI_CX_DESC_LEN);
|
||||
strlcat(result->desc, "+", ACPI_CX_DESC_LEN);
|
||||
strlcat(result->desc, parent->desc, ACPI_CX_DESC_LEN);
|
||||
return true;
|
||||
@ -1213,7 +1213,7 @@ static int acpi_processor_setup_lpi_states(struct acpi_processor *pr)
|
||||
|
||||
state = &drv->states[i];
|
||||
snprintf(state->name, CPUIDLE_NAME_LEN, "LPI-%d", i);
|
||||
strlcpy(state->desc, lpi->desc, CPUIDLE_DESC_LEN);
|
||||
strscpy(state->desc, lpi->desc, CPUIDLE_DESC_LEN);
|
||||
state->exit_latency = lpi->wake_latency;
|
||||
state->target_residency = lpi->min_residency;
|
||||
if (lpi->arch_flags)
|
||||
|
@ -304,8 +304,10 @@ static void acpi_init_of_compatible(struct acpi_device *adev)
|
||||
ret = acpi_dev_get_property(adev, "compatible",
|
||||
ACPI_TYPE_STRING, &of_compatible);
|
||||
if (ret) {
|
||||
if (adev->parent
|
||||
&& adev->parent->flags.of_compatible_ok)
|
||||
struct acpi_device *parent;
|
||||
|
||||
parent = acpi_dev_parent(adev);
|
||||
if (parent && parent->flags.of_compatible_ok)
|
||||
goto out;
|
||||
|
||||
return;
|
||||
@ -1267,10 +1269,11 @@ acpi_node_get_parent(const struct fwnode_handle *fwnode)
|
||||
return to_acpi_data_node(fwnode)->parent;
|
||||
}
|
||||
if (is_acpi_device_node(fwnode)) {
|
||||
struct device *dev = to_acpi_device_node(fwnode)->dev.parent;
|
||||
struct acpi_device *parent;
|
||||
|
||||
if (dev)
|
||||
return acpi_fwnode_handle(to_acpi_device(dev));
|
||||
parent = acpi_dev_parent(to_acpi_device_node(fwnode));
|
||||
if (parent)
|
||||
return acpi_fwnode_handle(parent);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -399,6 +399,31 @@ static const struct dmi_system_id medion_laptop[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
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"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
struct irq_override_cmp {
|
||||
const struct dmi_system_id *system;
|
||||
unsigned char irq;
|
||||
@ -409,6 +434,7 @@ struct irq_override_cmp {
|
||||
|
||||
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,
|
||||
@ -690,6 +716,9 @@ static int is_memory(struct acpi_resource *ares, void *not_used)
|
||||
|
||||
memset(&win, 0, sizeof(win));
|
||||
|
||||
if (acpi_dev_filter_resource_type(ares, IORESOURCE_MEM))
|
||||
return 1;
|
||||
|
||||
return !(acpi_dev_resource_memory(ares, res)
|
||||
|| acpi_dev_resource_address_space(ares, &win)
|
||||
|| acpi_dev_resource_ext_address_space(ares, &win));
|
||||
@ -718,6 +747,23 @@ int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_get_dma_resources);
|
||||
|
||||
/**
|
||||
* acpi_dev_get_memory_resources - Get current memory resources of a device.
|
||||
* @adev: ACPI device node to get the resources for.
|
||||
* @list: Head of the resultant list of resources (must be empty).
|
||||
*
|
||||
* This is a helper function that locates all memory type resources of @adev
|
||||
* with acpi_dev_get_resources().
|
||||
*
|
||||
* The number of resources in the output list is returned on success, an error
|
||||
* code reflecting the error condition is returned otherwise.
|
||||
*/
|
||||
int acpi_dev_get_memory_resources(struct acpi_device *adev, struct list_head *list)
|
||||
{
|
||||
return acpi_dev_get_resources(adev, list, is_memory, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_get_memory_resources);
|
||||
|
||||
/**
|
||||
* acpi_dev_filter_resource_type - Filter ACPI resource according to resource
|
||||
* types
|
||||
|
@ -632,7 +632,7 @@ static int acpi_sbs_add(struct acpi_device *device)
|
||||
|
||||
mutex_init(&sbs->lock);
|
||||
|
||||
sbs->hc = acpi_driver_data(device->parent);
|
||||
sbs->hc = acpi_driver_data(acpi_dev_parent(device));
|
||||
sbs->device = device;
|
||||
strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
|
||||
|
@ -266,7 +266,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device)
|
||||
mutex_init(&hc->lock);
|
||||
init_waitqueue_head(&hc->wait);
|
||||
|
||||
hc->ec = acpi_driver_data(device->parent);
|
||||
hc->ec = acpi_driver_data(acpi_dev_parent(device));
|
||||
hc->offset = (val >> 8) & 0xff;
|
||||
hc->query_bit = val & 0xff;
|
||||
device->driver_data = hc;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/platform_data/x86/apple.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/dma-direct.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@ -29,8 +30,6 @@ extern struct acpi_device *acpi_root;
|
||||
#define ACPI_BUS_HID "LNXSYBUS"
|
||||
#define ACPI_BUS_DEVICE_NAME "System Bus"
|
||||
|
||||
#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
|
||||
|
||||
#define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page)
|
||||
|
||||
static const char *dummy_hid = "device";
|
||||
@ -429,7 +428,7 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src)
|
||||
acpi_evaluate_ost(adev->handle, src, ost_code, NULL);
|
||||
|
||||
out:
|
||||
acpi_bus_put_acpi_device(adev);
|
||||
acpi_put_acpi_dev(adev);
|
||||
mutex_unlock(&acpi_scan_lock);
|
||||
unlock_device_hotplug();
|
||||
}
|
||||
@ -599,11 +598,22 @@ static void get_acpi_device(void *dev)
|
||||
acpi_dev_get(dev);
|
||||
}
|
||||
|
||||
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle)
|
||||
/**
|
||||
* acpi_get_acpi_dev - Retrieve ACPI device object and reference count it.
|
||||
* @handle: ACPI handle associated with the requested ACPI device object.
|
||||
*
|
||||
* Return a pointer to the ACPI device object associated with @handle and bump
|
||||
* up that object's reference counter (under the ACPI Namespace lock), if
|
||||
* present, or return NULL otherwise.
|
||||
*
|
||||
* The ACPI device object reference acquired by this function needs to be
|
||||
* dropped via acpi_dev_put().
|
||||
*/
|
||||
struct acpi_device *acpi_get_acpi_dev(acpi_handle handle)
|
||||
{
|
||||
return handle_to_device(handle, get_acpi_device);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_bus_get_acpi_device);
|
||||
EXPORT_SYMBOL_GPL(acpi_get_acpi_dev);
|
||||
|
||||
static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
|
||||
{
|
||||
@ -632,7 +642,7 @@ static int acpi_device_set_name(struct acpi_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_tie_acpi_dev(struct acpi_device *adev)
|
||||
int acpi_tie_acpi_dev(struct acpi_device *adev)
|
||||
{
|
||||
acpi_handle handle = adev->handle;
|
||||
acpi_status status;
|
||||
@ -662,8 +672,7 @@ static void acpi_store_pld_crc(struct acpi_device *adev)
|
||||
ACPI_FREE(pld);
|
||||
}
|
||||
|
||||
static int __acpi_device_add(struct acpi_device *device,
|
||||
void (*release)(struct device *))
|
||||
int acpi_device_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_device_bus_id *acpi_device_bus_id;
|
||||
int result;
|
||||
@ -719,11 +728,6 @@ static int __acpi_device_add(struct acpi_device *device,
|
||||
|
||||
mutex_unlock(&acpi_device_lock);
|
||||
|
||||
if (device->parent)
|
||||
device->dev.parent = &device->parent->dev;
|
||||
|
||||
device->dev.bus = &acpi_bus_type;
|
||||
device->dev.release = release;
|
||||
result = device_add(&device->dev);
|
||||
if (result) {
|
||||
dev_err(&device->dev, "Error registering device\n");
|
||||
@ -750,17 +754,6 @@ err_unlock:
|
||||
return result;
|
||||
}
|
||||
|
||||
int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *))
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = acpi_tie_acpi_dev(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return __acpi_device_add(adev, release);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Device Enumeration
|
||||
-------------------------------------------------------------------------- */
|
||||
@ -805,10 +798,9 @@ static const char * const acpi_honor_dep_ids[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
|
||||
static struct acpi_device *acpi_find_parent_acpi_dev(acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *device;
|
||||
acpi_status status;
|
||||
struct acpi_device *adev;
|
||||
|
||||
/*
|
||||
* Fixed hardware devices do not appear in the namespace and do not
|
||||
@ -819,13 +811,18 @@ static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
|
||||
return acpi_root;
|
||||
|
||||
do {
|
||||
status = acpi_get_parent(handle, &handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return status == AE_NULL_ENTRY ? NULL : acpi_root;
|
||||
acpi_status status;
|
||||
|
||||
device = acpi_fetch_acpi_dev(handle);
|
||||
} while (!device);
|
||||
return device;
|
||||
status = acpi_get_parent(handle, &handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status != AE_NULL_ENTRY)
|
||||
return acpi_root;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
adev = acpi_fetch_acpi_dev(handle);
|
||||
} while (!adev);
|
||||
return adev;
|
||||
}
|
||||
|
||||
acpi_status
|
||||
@ -1112,7 +1109,7 @@ static void acpi_device_get_busid(struct acpi_device *device)
|
||||
* The device's Bus ID is simply the object name.
|
||||
* TBD: Shouldn't this value be unique (within the ACPI namespace)?
|
||||
*/
|
||||
if (ACPI_IS_ROOT_DEVICE(device)) {
|
||||
if (!acpi_dev_parent(device)) {
|
||||
strcpy(device->pnp.bus_id, "ACPI");
|
||||
return;
|
||||
}
|
||||
@ -1467,25 +1464,21 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
|
||||
* acpi_dma_get_range() - Get device DMA parameters.
|
||||
*
|
||||
* @dev: device to configure
|
||||
* @dma_addr: pointer device DMA address result
|
||||
* @offset: pointer to the DMA offset result
|
||||
* @size: pointer to DMA range size result
|
||||
* @map: pointer to DMA ranges result
|
||||
*
|
||||
* Evaluate DMA regions and return respectively DMA region start, offset
|
||||
* and size in dma_addr, offset and size on parsing success; it does not
|
||||
* update the passed in values on failure.
|
||||
* Evaluate DMA regions and return pointer to DMA regions on
|
||||
* parsing success; it does not update the passed in values on failure.
|
||||
*
|
||||
* Return 0 on success, < 0 on failure.
|
||||
*/
|
||||
int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
|
||||
u64 *size)
|
||||
int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
LIST_HEAD(list);
|
||||
struct resource_entry *rentry;
|
||||
int ret;
|
||||
struct device *dma_dev = dev;
|
||||
u64 len, dma_start = U64_MAX, dma_end = 0, dma_offset = 0;
|
||||
struct bus_dma_region *r;
|
||||
|
||||
/*
|
||||
* Walk the device tree chasing an ACPI companion with a _DMA
|
||||
@ -1510,31 +1503,28 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
|
||||
|
||||
ret = acpi_dev_get_dma_resources(adev, &list);
|
||||
if (ret > 0) {
|
||||
list_for_each_entry(rentry, &list, node) {
|
||||
if (dma_offset && rentry->offset != dma_offset) {
|
||||
ret = -EINVAL;
|
||||
dev_warn(dma_dev, "Can't handle multiple windows with different offsets\n");
|
||||
goto out;
|
||||
}
|
||||
dma_offset = rentry->offset;
|
||||
|
||||
/* Take lower and upper limits */
|
||||
if (rentry->res->start < dma_start)
|
||||
dma_start = rentry->res->start;
|
||||
if (rentry->res->end > dma_end)
|
||||
dma_end = rentry->res->end;
|
||||
}
|
||||
|
||||
if (dma_start >= dma_end) {
|
||||
ret = -EINVAL;
|
||||
dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
|
||||
r = kcalloc(ret + 1, sizeof(*r), GFP_KERNEL);
|
||||
if (!r) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*dma_addr = dma_start - dma_offset;
|
||||
len = dma_end - dma_start;
|
||||
*size = max(len, len + 1);
|
||||
*offset = dma_offset;
|
||||
list_for_each_entry(rentry, &list, node) {
|
||||
if (rentry->res->start >= rentry->res->end) {
|
||||
kfree(r);
|
||||
ret = -EINVAL;
|
||||
dev_dbg(dma_dev, "Invalid DMA regions configuration\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r->cpu_start = rentry->res->start;
|
||||
r->dma_start = rentry->res->start - rentry->offset;
|
||||
r->size = resource_size(rentry->res);
|
||||
r->offset = rentry->offset;
|
||||
r++;
|
||||
}
|
||||
|
||||
*map = r;
|
||||
}
|
||||
out:
|
||||
acpi_dev_free_resource_list(&list);
|
||||
@ -1624,20 +1614,19 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
|
||||
const u32 *input_id)
|
||||
{
|
||||
const struct iommu_ops *iommu;
|
||||
u64 dma_addr = 0, size = 0;
|
||||
|
||||
if (attr == DEV_DMA_NOT_SUPPORTED) {
|
||||
set_dma_ops(dev, &dma_dummy_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
acpi_arch_dma_setup(dev, &dma_addr, &size);
|
||||
acpi_arch_dma_setup(dev);
|
||||
|
||||
iommu = acpi_iommu_configure_id(dev, input_id);
|
||||
if (PTR_ERR(iommu) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
arch_setup_dma_ops(dev, dma_addr, size,
|
||||
arch_setup_dma_ops(dev, 0, U64_MAX,
|
||||
iommu, attr == DEV_DMA_COHERENT);
|
||||
|
||||
return 0;
|
||||
@ -1648,7 +1637,7 @@ static void acpi_init_coherency(struct acpi_device *adev)
|
||||
{
|
||||
unsigned long long cca = 0;
|
||||
acpi_status status;
|
||||
struct acpi_device *parent = adev->parent;
|
||||
struct acpi_device *parent = acpi_dev_parent(adev);
|
||||
|
||||
if (parent && parent->flags.cca_seen) {
|
||||
/*
|
||||
@ -1692,7 +1681,7 @@ static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data)
|
||||
|
||||
static bool acpi_is_indirect_io_slave(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_device *parent = device->parent;
|
||||
struct acpi_device *parent = acpi_dev_parent(device);
|
||||
static const struct acpi_device_id indirect_io_hosts[] = {
|
||||
{"HISI0191", 0},
|
||||
{}
|
||||
@ -1762,12 +1751,16 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
|
||||
}
|
||||
|
||||
void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
|
||||
int type)
|
||||
int type, void (*release)(struct device *))
|
||||
{
|
||||
struct acpi_device *parent = acpi_find_parent_acpi_dev(handle);
|
||||
|
||||
INIT_LIST_HEAD(&device->pnp.ids);
|
||||
device->device_type = type;
|
||||
device->handle = handle;
|
||||
device->parent = acpi_bus_get_parent(handle);
|
||||
device->dev.parent = parent ? &parent->dev : NULL;
|
||||
device->dev.release = release;
|
||||
device->dev.bus = &acpi_bus_type;
|
||||
fwnode_init(&device->fwnode, &acpi_device_fwnode_ops);
|
||||
acpi_set_device_status(device, ACPI_STA_DEFAULT);
|
||||
acpi_device_get_busid(device);
|
||||
@ -1821,7 +1814,7 @@ static int acpi_add_single_object(struct acpi_device **child,
|
||||
if (!device)
|
||||
return -ENOMEM;
|
||||
|
||||
acpi_init_device_object(device, handle, type);
|
||||
acpi_init_device_object(device, handle, type, acpi_device_release);
|
||||
/*
|
||||
* Getting the status is delayed till here so that we can call
|
||||
* acpi_bus_get_status() and use its quirk handling. Note that
|
||||
@ -1851,7 +1844,7 @@ static int acpi_add_single_object(struct acpi_device **child,
|
||||
mutex_unlock(&acpi_dep_list_lock);
|
||||
|
||||
if (!result)
|
||||
result = __acpi_device_add(device, acpi_device_release);
|
||||
result = acpi_device_add(device);
|
||||
|
||||
if (result) {
|
||||
acpi_device_release(&device->dev);
|
||||
@ -1862,8 +1855,8 @@ static int acpi_add_single_object(struct acpi_device **child,
|
||||
acpi_device_add_finalize(device);
|
||||
|
||||
acpi_handle_debug(handle, "Added as %s, parent %s\n",
|
||||
dev_name(&device->dev), device->parent ?
|
||||
dev_name(&device->parent->dev) : "(null)");
|
||||
dev_name(&device->dev), device->dev.parent ?
|
||||
dev_name(device->dev.parent) : "(null)");
|
||||
|
||||
*child = device;
|
||||
return 0;
|
||||
@ -2235,11 +2228,24 @@ ok:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
|
||||
static int acpi_dev_get_next_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
struct acpi_device **adev_p = data;
|
||||
struct acpi_device *adev = *adev_p;
|
||||
|
||||
adev = acpi_bus_get_acpi_device(dep->consumer);
|
||||
/*
|
||||
* If we're passed a 'previous' consumer device then we need to skip
|
||||
* any consumers until we meet the previous one, and then NULL @data
|
||||
* so the next one can be returned.
|
||||
*/
|
||||
if (adev) {
|
||||
if (dep->consumer == adev->handle)
|
||||
*adev_p = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
adev = acpi_get_acpi_dev(dep->consumer);
|
||||
if (adev) {
|
||||
*(struct acpi_device **)data = adev;
|
||||
return 1;
|
||||
@ -2292,7 +2298,7 @@ static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
|
||||
|
||||
static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
|
||||
{
|
||||
struct acpi_device *adev = acpi_bus_get_acpi_device(dep->consumer);
|
||||
struct acpi_device *adev = acpi_get_acpi_dev(dep->consumer);
|
||||
|
||||
if (adev) {
|
||||
adev->dep_unmet--;
|
||||
@ -2368,25 +2374,32 @@ bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
|
||||
|
||||
/**
|
||||
* acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
|
||||
* acpi_dev_get_next_consumer_dev - Return the next adev dependent on @supplier
|
||||
* @supplier: Pointer to the dependee device
|
||||
* @start: Pointer to the current dependent device
|
||||
*
|
||||
* Returns the first &struct acpi_device which declares itself dependent on
|
||||
* Returns the next &struct acpi_device which declares itself dependent on
|
||||
* @supplier via the _DEP buffer, parsed from the acpi_dep_list.
|
||||
*
|
||||
* The caller is responsible for putting the reference to adev when it is no
|
||||
* longer needed.
|
||||
* If the returned adev is not passed as @start to this function, the caller is
|
||||
* responsible for putting the reference to adev when it is no longer needed.
|
||||
*/
|
||||
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
|
||||
struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
|
||||
struct acpi_device *start)
|
||||
{
|
||||
struct acpi_device *adev = NULL;
|
||||
struct acpi_device *adev = start;
|
||||
|
||||
acpi_walk_dep_device_list(supplier->handle,
|
||||
acpi_dev_get_first_consumer_dev_cb, &adev);
|
||||
acpi_dev_get_next_consumer_dev_cb, &adev);
|
||||
|
||||
acpi_dev_put(start);
|
||||
|
||||
if (adev == start)
|
||||
return NULL;
|
||||
|
||||
return adev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_get_next_consumer_dev);
|
||||
|
||||
/**
|
||||
* acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
|
||||
|
@ -793,6 +793,30 @@ bool acpi_dev_hid_uid_match(struct acpi_device *adev,
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_dev_hid_uid_match);
|
||||
|
||||
/**
|
||||
* acpi_dev_uid_to_integer - treat ACPI device _UID as integer
|
||||
* @adev: ACPI device to get _UID from
|
||||
* @integer: output buffer for integer
|
||||
*
|
||||
* Considers _UID as integer and converts it to @integer.
|
||||
*
|
||||
* Returns 0 on success, or negative error code otherwise.
|
||||
*/
|
||||
int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer)
|
||||
{
|
||||
const char *uid;
|
||||
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
uid = acpi_device_uid(adev);
|
||||
if (!uid)
|
||||
return -ENODATA;
|
||||
|
||||
return kstrtou64(uid, 0, integer);
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_dev_uid_to_integer);
|
||||
|
||||
/**
|
||||
* acpi_dev_found - Detect presence of a given ACPI device in the namespace.
|
||||
* @hid: Hardware ID of the device.
|
||||
@ -878,7 +902,7 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
|
||||
struct acpi_dev_match_info match = {};
|
||||
struct device *dev;
|
||||
|
||||
strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
|
||||
strscpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
|
||||
match.uid = uid;
|
||||
match.hrv = hrv;
|
||||
|
||||
@ -911,7 +935,7 @@ acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const cha
|
||||
struct acpi_dev_match_info match = {};
|
||||
struct device *dev;
|
||||
|
||||
strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
|
||||
strscpy(match.hid[0].id, hid, sizeof(match.hid[0].id));
|
||||
match.uid = uid;
|
||||
match.hrv = hrv;
|
||||
|
||||
@ -961,7 +985,7 @@ EXPORT_SYMBOL(acpi_video_backlight_string);
|
||||
|
||||
static int __init acpi_backlight(char *str)
|
||||
{
|
||||
strlcpy(acpi_video_backlight_string, str,
|
||||
strscpy(acpi_video_backlight_string, str,
|
||||
sizeof(acpi_video_backlight_string));
|
||||
return 1;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/platform_data/x86/apple.h>
|
||||
#include <linux/uuid.h>
|
||||
#include "../internal.h"
|
||||
|
||||
/* Apple _DSM device properties GUID */
|
||||
static const guid_t apple_prp_guid =
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "../sleep.h"
|
||||
@ -27,6 +28,10 @@ static bool sleep_no_lps0 __read_mostly;
|
||||
module_param(sleep_no_lps0, bool, 0644);
|
||||
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
|
||||
|
||||
static bool prefer_microsoft_dsm_guid __read_mostly;
|
||||
module_param(prefer_microsoft_dsm_guid, bool, 0644);
|
||||
MODULE_PARM_DESC(prefer_microsoft_dsm_guid, "Prefer using Microsoft GUID in LPS0 device _DSM evaluation");
|
||||
|
||||
static const struct acpi_device_id lps0_device_ids[] = {
|
||||
{"PNP0D80", },
|
||||
{"", },
|
||||
@ -363,40 +368,132 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct amd_lps0_hid_device_data {
|
||||
const unsigned int rev_id;
|
||||
const bool check_off_by_one;
|
||||
const bool prefer_amd_guid;
|
||||
};
|
||||
|
||||
static const struct amd_lps0_hid_device_data amd_picasso = {
|
||||
.rev_id = 0,
|
||||
.check_off_by_one = true,
|
||||
.prefer_amd_guid = false,
|
||||
};
|
||||
|
||||
static const struct amd_lps0_hid_device_data amd_cezanne = {
|
||||
.rev_id = 0,
|
||||
.check_off_by_one = false,
|
||||
.prefer_amd_guid = false,
|
||||
};
|
||||
|
||||
static const struct amd_lps0_hid_device_data amd_rembrandt = {
|
||||
.rev_id = 2,
|
||||
.check_off_by_one = false,
|
||||
.prefer_amd_guid = true,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id amd_hid_ids[] = {
|
||||
{"AMD0004", (kernel_ulong_t)&amd_picasso, },
|
||||
{"AMD0005", (kernel_ulong_t)&amd_picasso, },
|
||||
{"AMDI0005", (kernel_ulong_t)&amd_picasso, },
|
||||
{"AMDI0006", (kernel_ulong_t)&amd_cezanne, },
|
||||
{"AMDI0007", (kernel_ulong_t)&amd_rembrandt, },
|
||||
{}
|
||||
};
|
||||
|
||||
static int lps0_prefer_microsoft(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_debug("Preferring Microsoft GUID.\n");
|
||||
prefer_microsoft_dsm_guid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id s2idle_dmi_table[] __initconst = {
|
||||
{
|
||||
/*
|
||||
* ASUS TUF Gaming A17 FA707RE
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216101
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Gaming A17"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ASUS ROG Zephyrus G14 (2022) */
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus G14 GA402"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Lenovo Yoga Slim 7 Pro X 14ARH7
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216473 : 82V2
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216438 : 82TL
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* ASUSTeK COMPUTER INC. ROG Flow X13 GV301RE_GV301RE
|
||||
* https://gitlab.freedesktop.org/drm/amd/-/issues/2148
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X13 GV301"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* ASUSTeK COMPUTER INC. ROG Flow X16 GV601RW_GV601RW
|
||||
* https://gitlab.freedesktop.org/drm/amd/-/issues/2148
|
||||
*/
|
||||
.callback = lps0_prefer_microsoft,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X16 GV601"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static int lps0_device_attach(struct acpi_device *adev,
|
||||
const struct acpi_device_id *not_used)
|
||||
{
|
||||
if (lps0_device_handle)
|
||||
return 0;
|
||||
|
||||
lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
|
||||
&lps0_dsm_guid_microsoft);
|
||||
if (acpi_s2idle_vendor_amd()) {
|
||||
/* AMD0004, AMD0005, AMDI0005:
|
||||
* - Should use rev_id 0x0
|
||||
* - function mask > 0x3: Should use AMD method, but has off by one bug
|
||||
* - function mask = 0x3: Should use Microsoft method
|
||||
* AMDI0006:
|
||||
* - should use rev_id 0x0
|
||||
* - function mask = 0x3: Should use Microsoft method
|
||||
* AMDI0007:
|
||||
* - Should use rev_id 0x2
|
||||
* - Should only use AMD method
|
||||
*/
|
||||
const char *hid = acpi_device_hid(adev);
|
||||
rev_id = strcmp(hid, "AMDI0007") ? 0 : 2;
|
||||
static const struct acpi_device_id *dev_id;
|
||||
const struct amd_lps0_hid_device_data *data;
|
||||
|
||||
for (dev_id = &amd_hid_ids[0]; dev_id->id[0]; dev_id++)
|
||||
if (acpi_dev_hid_uid_match(adev, dev_id->id, NULL))
|
||||
break;
|
||||
if (dev_id->id[0])
|
||||
data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data;
|
||||
else
|
||||
data = &amd_rembrandt;
|
||||
rev_id = data->rev_id;
|
||||
lps0_dsm_func_mask = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid);
|
||||
lps0_dsm_func_mask_microsoft = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
|
||||
&lps0_dsm_guid_microsoft);
|
||||
if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") ||
|
||||
!strcmp(hid, "AMD0005") ||
|
||||
!strcmp(hid, "AMDI0005"))) {
|
||||
if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) {
|
||||
lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
|
||||
acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
|
||||
ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask);
|
||||
} else if (lps0_dsm_func_mask_microsoft > 0 &&
|
||||
(!strcmp(hid, "AMDI0007") ||
|
||||
!strcmp(hid, "AMDI0008"))) {
|
||||
} else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid &&
|
||||
!prefer_microsoft_dsm_guid) {
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
acpi_handle_debug(adev->handle, "_DSM Using AMD method\n");
|
||||
}
|
||||
@ -404,7 +501,8 @@ static int lps0_device_attach(struct acpi_device *adev,
|
||||
rev_id = 1;
|
||||
lps0_dsm_func_mask = validate_dsm(adev->handle,
|
||||
ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid);
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
if (!prefer_microsoft_dsm_guid)
|
||||
lps0_dsm_func_mask_microsoft = -EINVAL;
|
||||
}
|
||||
|
||||
if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0)
|
||||
@ -533,8 +631,9 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
|
||||
.end = acpi_s2idle_end,
|
||||
};
|
||||
|
||||
void acpi_s2idle_setup(void)
|
||||
void __init acpi_s2idle_setup(void)
|
||||
{
|
||||
dmi_check_system(s2idle_dmi_table);
|
||||
acpi_scan_add_handler(&lps0_handler);
|
||||
s2idle_set_ops(&acpi_s2idle_ops_lps0);
|
||||
}
|
||||
|
@ -207,9 +207,26 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct dmi_system_id force_storage_d3_dmi[] = {
|
||||
{
|
||||
/*
|
||||
* _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME
|
||||
* but .NVME is needed to get StorageD3Enable node
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=216440
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"),
|
||||
}
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
bool force_storage_d3(void)
|
||||
{
|
||||
return x86_match_cpu(storage_d3_cpu_ids);
|
||||
const struct dmi_system_id *dmi_id = dmi_first_match(force_storage_d3_dmi);
|
||||
|
||||
return dmi_id || x86_match_cpu(storage_d3_cpu_ids);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -351,11 +368,17 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s
|
||||
struct acpi_device *adev = ACPI_COMPANION(controller_parent);
|
||||
const struct dmi_system_id *dmi_id;
|
||||
long quirks = 0;
|
||||
u64 uid;
|
||||
int ret;
|
||||
|
||||
*skip = false;
|
||||
|
||||
/* !dev_is_platform() to not match on PNP enumerated debug UARTs */
|
||||
if (!adev || !adev->pnp.unique_id || !dev_is_platform(controller_parent))
|
||||
ret = acpi_dev_uid_to_integer(adev, &uid);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
/* to not match on PNP enumerated debug UARTs */
|
||||
if (!dev_is_platform(controller_parent))
|
||||
return 0;
|
||||
|
||||
dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
|
||||
@ -363,10 +386,10 @@ int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *s
|
||||
quirks = (unsigned long)dmi_id->driver_data;
|
||||
|
||||
if (quirks & ACPI_QUIRK_UART1_TTY_UART2_SKIP) {
|
||||
if (!strcmp(adev->pnp.unique_id, "1"))
|
||||
if (uid == 1)
|
||||
return -ENODEV; /* Create tty cdev instead of serdev */
|
||||
|
||||
if (!strcmp(adev->pnp.unique_id, "2"))
|
||||
if (uid == 2)
|
||||
*skip = true;
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ void topology_init_cpu_capacity_cppc(void)
|
||||
struct cppc_perf_caps perf_caps;
|
||||
int cpu;
|
||||
|
||||
if (likely(acpi_disabled || !acpi_cpc_valid()))
|
||||
if (likely(!acpi_cpc_valid()))
|
||||
return;
|
||||
|
||||
raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
|
||||
|
@ -200,7 +200,9 @@ static int tps68470_clk_probe(struct platform_device *pdev)
|
||||
.flags = CLK_SET_RATE_GATE,
|
||||
};
|
||||
struct tps68470_clkdata *tps68470_clkdata;
|
||||
struct tps68470_clk_consumer *consumer;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
|
||||
GFP_KERNEL);
|
||||
@ -223,10 +225,13 @@ static int tps68470_clk_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
if (pdata) {
|
||||
ret = devm_clk_hw_register_clkdev(&pdev->dev,
|
||||
&tps68470_clkdata->clkout_hw,
|
||||
pdata->consumer_con_id,
|
||||
pdata->consumer_dev_name);
|
||||
for (i = 0; i < pdata->n_consumers; i++) {
|
||||
consumer = &pdata->consumers[i];
|
||||
ret = devm_clk_hw_register_clkdev(&pdev->dev,
|
||||
&tps68470_clkdata->clkout_hw,
|
||||
consumer->consumer_con_id,
|
||||
consumer->consumer_dev_name);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -673,7 +673,7 @@ static int __init amd_pstate_init(void)
|
||||
return -ENODEV;
|
||||
|
||||
if (!acpi_cpc_valid()) {
|
||||
pr_debug("the _CPC object is not present in SBIOS\n");
|
||||
pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,15 @@ static struct cppc_workaround_oem_info wa_info[] = {
|
||||
|
||||
static struct cpufreq_driver cppc_cpufreq_driver;
|
||||
|
||||
static enum {
|
||||
FIE_UNSET = -1,
|
||||
FIE_ENABLED,
|
||||
FIE_DISABLED
|
||||
} fie_disabled = FIE_UNSET;
|
||||
|
||||
#ifdef CONFIG_ACPI_CPPC_CPUFREQ_FIE
|
||||
module_param(fie_disabled, int, 0444);
|
||||
MODULE_PARM_DESC(fie_disabled, "Disable Frequency Invariance Engine (FIE)");
|
||||
|
||||
/* Frequency invariance support */
|
||||
struct cppc_freq_invariance {
|
||||
@ -158,7 +166,7 @@ static void cppc_cpufreq_cpu_fie_init(struct cpufreq_policy *policy)
|
||||
struct cppc_freq_invariance *cppc_fi;
|
||||
int cpu, ret;
|
||||
|
||||
if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate)
|
||||
if (fie_disabled)
|
||||
return;
|
||||
|
||||
for_each_cpu(cpu, policy->cpus) {
|
||||
@ -199,7 +207,7 @@ static void cppc_cpufreq_cpu_fie_exit(struct cpufreq_policy *policy)
|
||||
struct cppc_freq_invariance *cppc_fi;
|
||||
int cpu;
|
||||
|
||||
if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate)
|
||||
if (fie_disabled)
|
||||
return;
|
||||
|
||||
/* policy->cpus will be empty here, use related_cpus instead */
|
||||
@ -229,7 +237,15 @@ static void __init cppc_freq_invariance_init(void)
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate)
|
||||
if (fie_disabled != FIE_ENABLED && fie_disabled != FIE_DISABLED) {
|
||||
fie_disabled = FIE_ENABLED;
|
||||
if (cppc_perf_ctrs_in_pcc()) {
|
||||
pr_info("FIE not enabled on systems with registers in PCC\n");
|
||||
fie_disabled = FIE_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (fie_disabled)
|
||||
return;
|
||||
|
||||
kworker_fie = kthread_create_worker(0, "cppc_fie");
|
||||
@ -247,7 +263,7 @@ static void __init cppc_freq_invariance_init(void)
|
||||
|
||||
static void cppc_freq_invariance_exit(void)
|
||||
{
|
||||
if (cppc_cpufreq_driver.get == hisi_cppc_cpufreq_get_rate)
|
||||
if (fie_disabled)
|
||||
return;
|
||||
|
||||
kthread_destroy_worker(kworker_fie);
|
||||
@ -936,6 +952,7 @@ static void cppc_check_hisi_workaround(void)
|
||||
wa_info[i].oem_revision == tbl->oem_revision) {
|
||||
/* Overwrite the get() callback */
|
||||
cppc_cpufreq_driver.get = hisi_cppc_cpufreq_get_rate;
|
||||
fie_disabled = FIE_DISABLED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -947,7 +964,7 @@ static int __init cppc_cpufreq_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((acpi_disabled) || !acpi_cpc_valid())
|
||||
if (!acpi_cpc_valid())
|
||||
return -ENODEV;
|
||||
|
||||
cppc_check_hisi_workaround();
|
||||
|
@ -15,9 +15,11 @@
|
||||
static long __init parse_acpi_path(const struct efi_dev_path *node,
|
||||
struct device *parent, struct device **child)
|
||||
{
|
||||
char hid[ACPI_ID_LEN], uid[11]; /* UINT_MAX + null byte */
|
||||
struct acpi_device *adev;
|
||||
struct device *phys_dev;
|
||||
char hid[ACPI_ID_LEN];
|
||||
u64 uid;
|
||||
int ret;
|
||||
|
||||
if (node->header.length != 12)
|
||||
return -EINVAL;
|
||||
@ -27,12 +29,12 @@ static long __init parse_acpi_path(const struct efi_dev_path *node,
|
||||
'A' + ((node->acpi.hid >> 5) & 0x1f) - 1,
|
||||
'A' + ((node->acpi.hid >> 0) & 0x1f) - 1,
|
||||
node->acpi.hid >> 16);
|
||||
sprintf(uid, "%u", node->acpi.uid);
|
||||
|
||||
for_each_acpi_dev_match(adev, hid, NULL, -1) {
|
||||
if (adev->pnp.unique_id && !strcmp(adev->pnp.unique_id, uid))
|
||||
ret = acpi_dev_uid_to_integer(adev, &uid);
|
||||
if (ret == 0 && node->acpi.uid == uid)
|
||||
break;
|
||||
if (!adev->pnp.unique_id && node->acpi.uid == 0)
|
||||
if (ret == -ENODATA && node->acpi.uid == 0)
|
||||
break;
|
||||
}
|
||||
if (!adev)
|
||||
|
@ -2453,7 +2453,8 @@ static int vmbus_acpi_add(struct acpi_device *device)
|
||||
* Some ancestor of the vmbus acpi device (Gen1 or Gen2
|
||||
* firmware) is the VMOD that has the mmio ranges. Get that.
|
||||
*/
|
||||
for (ancestor = device->parent; ancestor; ancestor = ancestor->parent) {
|
||||
for (ancestor = acpi_dev_parent(device); ancestor;
|
||||
ancestor = acpi_dev_parent(ancestor)) {
|
||||
result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS,
|
||||
vmbus_walk_resources, NULL);
|
||||
|
||||
|
@ -598,7 +598,7 @@ static int read_domain_devices(struct acpi_power_meter_resource *resource)
|
||||
continue;
|
||||
|
||||
/* Create a symlink to domain objects */
|
||||
obj = acpi_bus_get_acpi_device(element->reference.handle);
|
||||
obj = acpi_get_acpi_dev(element->reference.handle);
|
||||
resource->domain_devices[i] = obj;
|
||||
if (!obj)
|
||||
continue;
|
||||
|
@ -244,14 +244,18 @@ static const struct i2c_adapter_quirks amd_i2c_dev_quirks = {
|
||||
|
||||
static int i2c_amd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
struct amd_i2c_dev *i2c_dev;
|
||||
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
|
||||
struct amd_mp2_dev *mp2_dev;
|
||||
const char *uid;
|
||||
u64 uid;
|
||||
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "missing UID/bus id!\n");
|
||||
if (uid >= 2)
|
||||
return dev_err_probe(dev, -EINVAL, "incorrect UID/bus id \"%llu\"!\n", uid);
|
||||
dev_dbg(dev, "bus id is %llu\n", uid);
|
||||
|
||||
/* The ACPI namespace doesn't contain information about which MP2 PCI
|
||||
* device an AMDI0011 ACPI device is related to, so assume that there's
|
||||
@ -266,6 +270,7 @@ static int i2c_amd_probe(struct platform_device *pdev)
|
||||
if (!i2c_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_dev->common.bus_id = uid;
|
||||
i2c_dev->common.mp2_dev = mp2_dev;
|
||||
i2c_dev->pdev = pdev;
|
||||
platform_set_drvdata(pdev, i2c_dev);
|
||||
@ -276,20 +281,6 @@ static int i2c_amd_probe(struct platform_device *pdev)
|
||||
i2c_dev->common.resume = &i2c_amd_resume;
|
||||
#endif
|
||||
|
||||
uid = adev->pnp.unique_id;
|
||||
if (!uid) {
|
||||
dev_err(&pdev->dev, "missing UID/bus id!\n");
|
||||
return -EINVAL;
|
||||
} else if (strcmp(uid, "0") == 0) {
|
||||
i2c_dev->common.bus_id = 0;
|
||||
} else if (strcmp(uid, "1") == 0) {
|
||||
i2c_dev->common.bus_id = 1;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "incorrect UID/bus id \"%s\"!\n", uid);
|
||||
return -EINVAL;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "bus id is %u\n", i2c_dev->common.bus_id);
|
||||
|
||||
/* Register the adapter */
|
||||
amd_mp2_pm_runtime_get(mp2_dev);
|
||||
|
||||
|
@ -2215,35 +2215,27 @@ MODULE_DEVICE_TABLE(acpi, mlxbf_i2c_acpi_ids);
|
||||
static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv)
|
||||
{
|
||||
const struct acpi_device_id *aid;
|
||||
struct acpi_device *adev;
|
||||
unsigned long bus_id = 0;
|
||||
const char *uid;
|
||||
u64 bus_id;
|
||||
int ret;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENOENT;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev)
|
||||
return -ENXIO;
|
||||
|
||||
aid = acpi_match_device(mlxbf_i2c_acpi_ids, dev);
|
||||
if (!aid)
|
||||
return -ENODEV;
|
||||
|
||||
priv->chip = (struct mlxbf_i2c_chip_info *)aid->driver_data;
|
||||
|
||||
uid = acpi_device_uid(adev);
|
||||
if (!uid || !(*uid)) {
|
||||
ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &bus_id);
|
||||
if (ret) {
|
||||
dev_err(dev, "Cannot retrieve UID\n");
|
||||
return -ENODEV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = kstrtoul(uid, 0, &bus_id);
|
||||
if (!ret)
|
||||
priv->bus = bus_id;
|
||||
priv->bus = bus_id;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv)
|
||||
|
@ -639,6 +639,7 @@ static int dsu_pmu_dt_get_cpus(struct device *dev, cpumask_t *mask)
|
||||
static int dsu_pmu_acpi_get_cpus(struct device *dev, cpumask_t *mask)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
struct acpi_device *parent_adev = acpi_dev_parent(ACPI_COMPANION(dev));
|
||||
int cpu;
|
||||
|
||||
/*
|
||||
@ -653,8 +654,7 @@ static int dsu_pmu_acpi_get_cpus(struct device *dev, cpumask_t *mask)
|
||||
continue;
|
||||
|
||||
acpi_dev = ACPI_COMPANION(cpu_dev);
|
||||
if (acpi_dev &&
|
||||
acpi_dev->parent == ACPI_COMPANION(dev)->parent)
|
||||
if (acpi_dev && acpi_dev_parent(acpi_dev) == parent_adev)
|
||||
cpumask_set_cpu(cpu, mask);
|
||||
}
|
||||
#endif
|
||||
|
@ -840,16 +840,16 @@ static int l2_cache_pmu_probe_cluster(struct device *dev, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev->parent);
|
||||
struct platform_device *sdev = to_platform_device(dev);
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
struct l2cache_pmu *l2cache_pmu = data;
|
||||
struct cluster_pmu *cluster;
|
||||
unsigned long fw_cluster_id;
|
||||
u64 fw_cluster_id;
|
||||
int err;
|
||||
int irq;
|
||||
|
||||
if (!adev || kstrtoul(adev->pnp.unique_id, 10, &fw_cluster_id) < 0) {
|
||||
err = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &fw_cluster_id);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "unable to read ACPI uid\n");
|
||||
return -ENODEV;
|
||||
return err;
|
||||
}
|
||||
|
||||
cluster = devm_kzalloc(&pdev->dev, sizeof(*cluster), GFP_KERNEL);
|
||||
@ -879,7 +879,7 @@ static int l2_cache_pmu_probe_cluster(struct device *dev, void *data)
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev,
|
||||
"Registered L2 cache PMU cluster %ld\n", fw_cluster_id);
|
||||
"Registered L2 cache PMU cluster %lld\n", fw_cluster_id);
|
||||
|
||||
spin_lock_init(&cluster->pmu_lock);
|
||||
|
||||
|
@ -742,7 +742,8 @@ static int qcom_l3_cache_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
l3pmu = devm_kzalloc(&pdev->dev, sizeof(*l3pmu), GFP_KERNEL);
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "l3cache_%s_%s",
|
||||
acpi_dev->parent->pnp.unique_id, acpi_dev->pnp.unique_id);
|
||||
acpi_dev_parent(acpi_dev)->pnp.unique_id,
|
||||
acpi_dev->pnp.unique_id);
|
||||
if (!l3pmu || !name)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -62,7 +62,7 @@ int skl_int3472_get_sensor_adev_and_name(struct device *dev,
|
||||
struct acpi_device *sensor;
|
||||
int ret = 0;
|
||||
|
||||
sensor = acpi_dev_get_first_consumer_dev(adev);
|
||||
sensor = acpi_dev_get_next_consumer_dev(adev, NULL);
|
||||
if (!sensor) {
|
||||
dev_err(dev, "INT3472 seems to have no dependents.\n");
|
||||
return -ENODEV;
|
||||
|
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Author: Dan Scally <djrscally@gmail.com> */
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
@ -95,20 +96,65 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
|
||||
return DESIGNED_FOR_WINDOWS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the size of the flexible array member, because we'll need that later
|
||||
* on to pass .pdata_size to cells.
|
||||
*/
|
||||
static int
|
||||
skl_int3472_fill_clk_pdata(struct device *dev, struct tps68470_clk_platform_data **clk_pdata)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
struct acpi_device *consumer;
|
||||
unsigned int n_consumers = 0;
|
||||
const char *sensor_name;
|
||||
unsigned int i = 0;
|
||||
|
||||
for_each_acpi_consumer_dev(adev, consumer)
|
||||
n_consumers++;
|
||||
|
||||
if (!n_consumers) {
|
||||
dev_err(dev, "INT3472 seems to have no dependents\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*clk_pdata = devm_kzalloc(dev, struct_size(*clk_pdata, consumers, n_consumers),
|
||||
GFP_KERNEL);
|
||||
if (!*clk_pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
(*clk_pdata)->n_consumers = n_consumers;
|
||||
i = 0;
|
||||
|
||||
for_each_acpi_consumer_dev(adev, consumer) {
|
||||
sensor_name = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
|
||||
acpi_dev_name(consumer));
|
||||
if (!sensor_name)
|
||||
return -ENOMEM;
|
||||
|
||||
(*clk_pdata)->consumers[i].consumer_dev_name = sensor_name;
|
||||
i++;
|
||||
}
|
||||
|
||||
acpi_dev_put(consumer);
|
||||
|
||||
return n_consumers;
|
||||
}
|
||||
|
||||
static int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
|
||||
const struct int3472_tps68470_board_data *board_data;
|
||||
struct tps68470_clk_platform_data clk_pdata = {};
|
||||
struct tps68470_clk_platform_data *clk_pdata;
|
||||
struct mfd_cell *cells;
|
||||
struct regmap *regmap;
|
||||
int n_consumers;
|
||||
int device_type;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
|
||||
&clk_pdata.consumer_dev_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata);
|
||||
if (n_consumers < 0)
|
||||
return n_consumers;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
@ -142,22 +188,25 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
* the clk + regulators must be ready when this happens.
|
||||
*/
|
||||
cells[0].name = "tps68470-clk";
|
||||
cells[0].platform_data = &clk_pdata;
|
||||
cells[0].pdata_size = sizeof(clk_pdata);
|
||||
cells[0].platform_data = clk_pdata;
|
||||
cells[0].pdata_size = struct_size(clk_pdata, consumers, n_consumers);
|
||||
cells[1].name = "tps68470-regulator";
|
||||
cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
|
||||
cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
|
||||
cells[2].name = "tps68470-gpio";
|
||||
|
||||
gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_table);
|
||||
for (i = 0; i < board_data->n_gpiod_lookups; i++)
|
||||
gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
|
||||
|
||||
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
|
||||
cells, TPS68470_WIN_MFD_CELL_COUNT,
|
||||
NULL, 0, NULL);
|
||||
kfree(cells);
|
||||
|
||||
if (ret)
|
||||
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
|
||||
if (ret) {
|
||||
for (i = 0; i < board_data->n_gpiod_lookups; i++)
|
||||
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
case DESIGNED_FOR_CHROMEOS:
|
||||
@ -181,10 +230,13 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
static int skl_int3472_tps68470_remove(struct i2c_client *client)
|
||||
{
|
||||
const struct int3472_tps68470_board_data *board_data;
|
||||
int i;
|
||||
|
||||
board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
|
||||
if (board_data)
|
||||
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
|
||||
if (board_data) {
|
||||
for (i = 0; i < board_data->n_gpiod_lookups; i++)
|
||||
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_tables[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,8 +16,9 @@ struct tps68470_regulator_platform_data;
|
||||
|
||||
struct int3472_tps68470_board_data {
|
||||
const char *dev_name;
|
||||
struct gpiod_lookup_table *tps68470_gpio_lookup_table;
|
||||
const struct tps68470_regulator_platform_data *tps68470_regulator_pdata;
|
||||
unsigned int n_gpiod_lookups;
|
||||
struct gpiod_lookup_table *tps68470_gpio_lookup_tables[];
|
||||
};
|
||||
|
||||
const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name);
|
||||
|
@ -30,6 +30,15 @@ static struct regulator_consumer_supply int347a_vcm_consumer_supplies[] = {
|
||||
static struct regulator_consumer_supply int347a_vsio_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("dovdd", "i2c-INT347A:00"),
|
||||
REGULATOR_SUPPLY("vsio", "i2c-INT347A:00-VCM"),
|
||||
REGULATOR_SUPPLY("vddd", "i2c-INT347E:00"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply int347a_aux1_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdda", "i2c-INT347E:00"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply int347a_aux2_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdddo", "i2c-INT347E:00"),
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_core_reg_init_data = {
|
||||
@ -86,6 +95,28 @@ static const struct regulator_init_data surface_go_tps68470_vsio_reg_init_data =
|
||||
.consumer_supplies = int347a_vsio_consumer_supplies,
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_aux1_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 2815200,
|
||||
.max_uV = 2815200,
|
||||
.apply_uV = 1,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(int347a_aux1_consumer_supplies),
|
||||
.consumer_supplies = int347a_aux1_consumer_supplies,
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_aux2_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 1800600,
|
||||
.max_uV = 1800600,
|
||||
.apply_uV = 1,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(int347a_aux2_consumer_supplies),
|
||||
.consumer_supplies = int347a_aux2_consumer_supplies,
|
||||
};
|
||||
|
||||
static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata = {
|
||||
.reg_init_data = {
|
||||
[TPS68470_CORE] = &surface_go_tps68470_core_reg_init_data,
|
||||
@ -93,10 +124,12 @@ static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata =
|
||||
[TPS68470_VCM] = &surface_go_tps68470_vcm_reg_init_data,
|
||||
[TPS68470_VIO] = &surface_go_tps68470_vio_reg_init_data,
|
||||
[TPS68470_VSIO] = &surface_go_tps68470_vsio_reg_init_data,
|
||||
[TPS68470_AUX1] = &surface_go_tps68470_aux1_reg_init_data,
|
||||
[TPS68470_AUX2] = &surface_go_tps68470_aux2_reg_init_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table surface_go_tps68470_gpios = {
|
||||
static struct gpiod_lookup_table surface_go_int347a_gpios = {
|
||||
.dev_id = "i2c-INT347A:00",
|
||||
.table = {
|
||||
GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
|
||||
@ -105,16 +138,31 @@ static struct gpiod_lookup_table surface_go_tps68470_gpios = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table surface_go_int347e_gpios = {
|
||||
.dev_id = "i2c-INT347E:00",
|
||||
.table = {
|
||||
GPIO_LOOKUP("tps68470-gpio", 5, "enable", GPIO_ACTIVE_HIGH),
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
|
||||
.dev_name = "i2c-INT3472:05",
|
||||
.tps68470_gpio_lookup_table = &surface_go_tps68470_gpios,
|
||||
.tps68470_regulator_pdata = &surface_go_tps68470_pdata,
|
||||
.n_gpiod_lookups = 2,
|
||||
.tps68470_gpio_lookup_tables = {
|
||||
&surface_go_int347a_gpios,
|
||||
&surface_go_int347e_gpios,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct int3472_tps68470_board_data surface_go3_tps68470_board_data = {
|
||||
.dev_name = "i2c-INT3472:01",
|
||||
.tps68470_gpio_lookup_table = &surface_go_tps68470_gpios,
|
||||
.tps68470_regulator_pdata = &surface_go_tps68470_pdata,
|
||||
.n_gpiod_lookups = 1,
|
||||
.tps68470_gpio_lookup_tables = {
|
||||
&surface_go_int347a_gpios
|
||||
},
|
||||
};
|
||||
|
||||
static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
|
||||
|
@ -153,7 +153,6 @@ extern int pnpbios_dont_use_current_config;
|
||||
extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node);
|
||||
extern int pnpbios_read_resources_from_node(struct pnp_dev *dev, struct pnp_bios_node *node);
|
||||
extern int pnpbios_write_resources_to_node(struct pnp_dev *dev, struct pnp_bios_node *node);
|
||||
extern void pnpid32_to_pnpid(u32 id, char *str);
|
||||
|
||||
extern void pnpbios_print_status(const char * module, u16 status);
|
||||
extern void pnpbios_calls_init(union pnp_bios_install_struct * header);
|
||||
|
@ -1441,31 +1441,6 @@ static const struct of_device_id pxa2xx_spi_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pxa2xx_spi_of_match);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
static int pxa2xx_spi_get_port_id(struct device *dev)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
unsigned int devid;
|
||||
int port_id = -1;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (adev && adev->pnp.unique_id &&
|
||||
!kstrtouint(adev->pnp.unique_id, 0, &devid))
|
||||
port_id = devid;
|
||||
return port_id;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_ACPI */
|
||||
|
||||
static int pxa2xx_spi_get_port_id(struct device *dev)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)
|
||||
@ -1479,13 +1454,16 @@ static struct pxa2xx_spi_controller *
|
||||
pxa2xx_spi_init_pdata(struct platform_device *pdev)
|
||||
{
|
||||
struct pxa2xx_spi_controller *pdata;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device *parent = dev->parent;
|
||||
struct ssp_device *ssp;
|
||||
struct resource *res;
|
||||
struct device *parent = pdev->dev.parent;
|
||||
struct pci_dev *pcidev = dev_is_pci(parent) ? to_pci_dev(parent) : NULL;
|
||||
const struct pci_device_id *pcidev_id = NULL;
|
||||
enum pxa_ssp_type type;
|
||||
const void *match;
|
||||
int status;
|
||||
u64 uid;
|
||||
|
||||
if (pcidev)
|
||||
pcidev_id = pci_match_id(pxa2xx_spi_pci_compound_match, pcidev);
|
||||
@ -1529,7 +1507,12 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
|
||||
|
||||
ssp->type = type;
|
||||
ssp->dev = &pdev->dev;
|
||||
ssp->port_id = pxa2xx_spi_get_port_id(&pdev->dev);
|
||||
|
||||
status = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid);
|
||||
if (status)
|
||||
ssp->port_id = -1;
|
||||
else
|
||||
ssp->port_id = uid;
|
||||
|
||||
pdata->is_slave = device_property_read_bool(&pdev->dev, "spi-slave");
|
||||
pdata->num_chipselect = 1;
|
||||
|
@ -4374,7 +4374,7 @@ static int acpi_spi_notify(struct notifier_block *nb, unsigned long value,
|
||||
|
||||
switch (value) {
|
||||
case ACPI_RECONFIG_DEVICE_ADD:
|
||||
ctlr = acpi_spi_find_controller_by_adev(adev->parent);
|
||||
ctlr = acpi_spi_find_controller_by_adev(acpi_dev_parent(adev));
|
||||
if (!ctlr)
|
||||
break;
|
||||
|
||||
|
@ -42,7 +42,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
|
||||
*/
|
||||
dev = acpi_get_first_physical_node(adev);
|
||||
while (!dev) {
|
||||
adev = adev->parent;
|
||||
adev = acpi_dev_parent(adev);
|
||||
if (!adev)
|
||||
break;
|
||||
dev = acpi_get_first_physical_node(adev);
|
||||
|
@ -569,15 +569,6 @@ err_unregister_switch:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int is_memory(struct acpi_resource *res, void *data)
|
||||
{
|
||||
struct resource_win win = {};
|
||||
struct resource *r = &win.res;
|
||||
|
||||
return !(acpi_dev_resource_memory(res, r) ||
|
||||
acpi_dev_resource_address_space(res, &win));
|
||||
}
|
||||
|
||||
/* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */
|
||||
static const struct acpi_device_id iom_acpi_ids[] = {
|
||||
/* TigerLake */
|
||||
@ -611,7 +602,7 @@ static int pmc_usb_probe_iom(struct pmc_usb *pmc)
|
||||
return -ENODEV;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, is_memory, NULL);
|
||||
ret = acpi_dev_get_memory_resources(adev, &resource_list);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -365,7 +365,6 @@ struct acpi_device {
|
||||
int device_type;
|
||||
acpi_handle handle; /* no handle for fixed hardware */
|
||||
struct fwnode_handle fwnode;
|
||||
struct acpi_device *parent;
|
||||
struct list_head wakeup_list;
|
||||
struct list_head del_list;
|
||||
struct acpi_device_status status;
|
||||
@ -458,6 +457,14 @@ static inline void *acpi_driver_data(struct acpi_device *d)
|
||||
#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
|
||||
#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
|
||||
|
||||
static inline struct acpi_device *acpi_dev_parent(struct acpi_device *adev)
|
||||
{
|
||||
if (adev->dev.parent)
|
||||
return to_acpi_device(adev->dev.parent);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
|
||||
{
|
||||
*((u32 *)&adev->status) = sta;
|
||||
@ -512,7 +519,6 @@ extern int unregister_acpi_notifier(struct notifier_block *);
|
||||
* External Functions
|
||||
*/
|
||||
|
||||
struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle);
|
||||
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
|
||||
unsigned long long *sta);
|
||||
int acpi_bus_get_status(struct acpi_device *device);
|
||||
@ -613,8 +619,7 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
|
||||
int acpi_iommu_fwspec_init(struct device *dev, u32 id,
|
||||
struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops);
|
||||
int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
|
||||
u64 *size);
|
||||
int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map);
|
||||
int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
|
||||
const u32 *input_id);
|
||||
static inline int acpi_dma_configure(struct device *dev,
|
||||
@ -733,10 +738,24 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
||||
}
|
||||
|
||||
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
|
||||
int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer);
|
||||
|
||||
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
|
||||
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
|
||||
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
|
||||
struct acpi_device *acpi_dev_get_next_consumer_dev(struct acpi_device *supplier,
|
||||
struct acpi_device *start);
|
||||
|
||||
/**
|
||||
* for_each_acpi_consumer_dev - iterate over the consumer ACPI devices for a
|
||||
* given supplier
|
||||
* @supplier: Pointer to the supplier's ACPI device
|
||||
* @consumer: Pointer to &struct acpi_device to hold the consumer, initially NULL
|
||||
*/
|
||||
#define for_each_acpi_consumer_dev(supplier, consumer) \
|
||||
for (consumer = acpi_dev_get_next_consumer_dev(supplier, NULL); \
|
||||
consumer; \
|
||||
consumer = acpi_dev_get_next_consumer_dev(supplier, consumer))
|
||||
|
||||
struct acpi_device *
|
||||
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
|
||||
struct acpi_device *
|
||||
@ -767,9 +786,10 @@ static inline void acpi_dev_put(struct acpi_device *adev)
|
||||
put_device(&adev->dev);
|
||||
}
|
||||
|
||||
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
|
||||
struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle);
|
||||
struct acpi_device *acpi_get_acpi_dev(acpi_handle handle);
|
||||
|
||||
static inline void acpi_bus_put_acpi_device(struct acpi_device *adev)
|
||||
static inline void acpi_put_acpi_dev(struct acpi_device *adev)
|
||||
{
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
|
@ -140,6 +140,7 @@ extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
|
||||
extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
|
||||
extern int cppc_set_enable(int cpu, bool enable);
|
||||
extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
|
||||
extern bool cppc_perf_ctrs_in_pcc(void);
|
||||
extern bool acpi_cpc_valid(void);
|
||||
extern bool cppc_allow_fast_switch(void);
|
||||
extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
|
||||
@ -173,6 +174,10 @@ static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline bool cppc_perf_ctrs_in_pcc(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool acpi_cpc_valid(void)
|
||||
{
|
||||
return false;
|
||||
|
@ -279,14 +279,17 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { }
|
||||
|
||||
void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
|
||||
|
||||
#if defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
|
||||
void acpi_arch_dma_setup(struct device *dev);
|
||||
#else
|
||||
static inline void acpi_arch_dma_setup(struct device *dev) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa);
|
||||
void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size);
|
||||
#else
|
||||
static inline void
|
||||
acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
|
||||
static inline void
|
||||
acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) { }
|
||||
#endif
|
||||
|
||||
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
|
||||
@ -506,6 +509,7 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
|
||||
void *preproc_data);
|
||||
int acpi_dev_get_dma_resources(struct acpi_device *adev,
|
||||
struct list_head *list);
|
||||
int acpi_dev_get_memory_resources(struct acpi_device *adev, struct list_head *list);
|
||||
int acpi_dev_filter_resource_type(struct acpi_resource *ares,
|
||||
unsigned long types);
|
||||
|
||||
@ -798,6 +802,11 @@ acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *u
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int acpi_dev_uid_to_integer(struct acpi_device *adev, u64 *integer)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline struct acpi_device *
|
||||
acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
|
||||
{
|
||||
@ -977,8 +986,7 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
|
||||
return DEV_DMA_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static inline int acpi_dma_get_range(struct device *dev, u64 *dma_addr,
|
||||
u64 *offset, u64 *size)
|
||||
static inline int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -27,9 +27,14 @@ struct tps68470_regulator_platform_data {
|
||||
const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
|
||||
};
|
||||
|
||||
struct tps68470_clk_platform_data {
|
||||
struct tps68470_clk_consumer {
|
||||
const char *consumer_dev_name;
|
||||
const char *consumer_con_id;
|
||||
};
|
||||
|
||||
struct tps68470_clk_platform_data {
|
||||
unsigned int n_consumers;
|
||||
struct tps68470_clk_consumer consumers[];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -190,7 +190,7 @@ int main(int argc, char *argv[])
|
||||
void *addr_map_capsule;
|
||||
struct stat st;
|
||||
char *log_buf;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (getuid() != 0) {
|
||||
printf("Please run the tool as root - Exiting.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user