mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
More ACPI updates for 5.16-rc1
- Add support for new ACPI device configuration object called _DSC to allow certain devices to be probed without changing their power states, document it and make two drivers use it (Sakari Ailus, Rajmohan Mani). - Fix device wakeup power reference counting broken recently by mistake (Rafael Wysocki). - Drop unused symbol and macros depending on it from acgcc.h (Rafael Wysocki). - Add HP ZHAN 66 Pro to the "no EC wakeup" quirk list (Binbin Zhou). - Add Xiaomi Mi Pad 2 to the backlight quirk list and drop an unused piece of data from all of the list entries (Hans de Goede). - Fix register read accesses handling in the Intel PMIC operation region driver (Hans de Goede). - Clean up static variables initialization in the EC driver (wangzhitong). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAmGL01cSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxF0YQAKXlCWrebWXwkDDqnSXZOqk7/aL+QZ9x Di1snFSqrpzgnSgZTuEjpUWLCFZ6hdpEyIH9X12PYo3o9SI3TkfGWpoA4XWEU6v7 CRpFWIXGHznFWFx3IHoyuUgfDMT2bLxdSrYQrC1lw0icvZHOyk72zNH7oVp0tsXq QwfxQDozJKypgSnNxbL+KsabG/DhK8Vyf4HjE6K1pTZ9fpsf0q9CnRGWWgdiaqdE B5iFxVIA46J1+izE2C9aN+bEJ43HThgVrvv9V+WOMLJKLJoHwEikZaDRBzvR1ofZ dm2f7J5/TDhJQSrlRYftMtNkYrw4Fcey+1xeGE1lTrmw0GM+/pvOs8THfj+TaUp9 0dmJCsHTndEby6PpQqCqTdfTRYsCIbhp8xRK3Q9qZcrYVNXcOrrifzmqY9bUDh2G IXHzPao6sfv4E9yWypuZ7VO4UR5alzxTQfnB5K+cCju2vMqz6Zkk1tr32xJLlsw/ vd6w3q3Bataa1xGZEBbgSYvgSkKEJwFOeU9R+Rvcn1QWgXQuoPufOssz28KSH3oQ 0mj/nHMJdRdlSDqADzyRUgoaxv7KUmRYRxbTUMiM+aWnDCu/OD7jWNq24sTNi9xC c7WMWHYC+0t5YxsyHo1MRfz8Q12zE1qWJFjBqMO23IZuBO3M1p3YSjl+z6NkUMj6 95M4WeJK2cBb =k8+T -----END PGP SIGNATURE----- Merge tag 'acpi-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more ACPI updates from Rafael Wysocki: "These add support for a new ACPI device configuration object called _DSC, fix some issues including one recent regression, add two new items to quirk lists and clean up assorted pieces of code. Specifics: - Add support for new ACPI device configuration object called _DSC ("Deepest State for Configuration") to allow certain devices to be probed without changing their power states, document it and make two drivers use it (Sakari Ailus, Rajmohan Mani). - Fix device wakeup power reference counting broken recently by mistake (Rafael Wysocki). - Drop unused symbol and macros depending on it from acgcc.h (Rafael Wysocki). - Add HP ZHAN 66 Pro to the "no EC wakeup" quirk list (Binbin Zhou). - Add Xiaomi Mi Pad 2 to the backlight quirk list and drop an unused piece of data from all of the list entries (Hans de Goede). - Fix register read accesses handling in the Intel PMIC operation region driver (Hans de Goede). - Clean up static variables initialization in the EC driver (wangzhitong)" * tag 'acpi-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Documentation: ACPI: Fix non-D0 probe _DSC object example ACPI: Drop ACPI_USE_BUILTIN_STDARG ifdef from acgcc.h ACPI: PM: Fix device wakeup power reference counting error ACPI: video: use platform backlight driver on Xiaomi Mi Pad 2 ACPI: video: Drop dmi_system_id.ident settings from video_detect_dmi_table[] ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses ACPI: EC: Remove initialization of static variables to false ACPI: EC: Use ec_no_wakeup on HP ZHAN 66 Pro at24: Support probing while in non-zero ACPI D state media: i2c: imx319: Support device probe in non-zero ACPI D state ACPI: Add a convenience function to tell a device is in D0 state Documentation: ACPI: Document _DSC object usage for enum power state i2c: Allow an ACPI driver to manage the device's power state during probe ACPI: scan: Obtain device's desired enumeration power state
This commit is contained in:
commit
285fc3db0a
@ -26,5 +26,6 @@ ACPI Support
|
||||
acpi-lid
|
||||
lpit
|
||||
video_extension
|
||||
non-d0-probe
|
||||
extcon-intel-int3496
|
||||
intel-pmc-mux
|
||||
|
78
Documentation/firmware-guide/acpi/non-d0-probe.rst
Normal file
78
Documentation/firmware-guide/acpi/non-d0-probe.rst
Normal file
@ -0,0 +1,78 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
========================================
|
||||
Probing devices in other D states than 0
|
||||
========================================
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
In some cases it may be preferred to leave certain devices powered off for the
|
||||
entire system bootup if powering on these devices has adverse side effects,
|
||||
beyond just powering on the said device.
|
||||
|
||||
How it works
|
||||
============
|
||||
|
||||
The _DSC (Device State for Configuration) object that evaluates to an integer
|
||||
may be used to tell Linux the highest allowed D state for a device during
|
||||
probe. The support for _DSC requires support from the kernel bus type if the
|
||||
bus driver normally sets the device in D0 state for probe.
|
||||
|
||||
The downside of using _DSC is that as the device is not powered on, even if
|
||||
there's a problem with the device, the driver likely probes just fine but the
|
||||
first user will find out the device doesn't work, instead of a failure at probe
|
||||
time. This feature should thus be used sparingly.
|
||||
|
||||
I²C
|
||||
---
|
||||
|
||||
If an I²C driver indicates its support for this by setting the
|
||||
I2C_DRV_ACPI_WAIVE_D0_PROBE flag in struct i2c_driver.flags field and the
|
||||
_DSC object evaluates to integer higher than the D state of the device,
|
||||
the device will not be powered on (put in D0 state) for probe.
|
||||
|
||||
D states
|
||||
--------
|
||||
|
||||
The D states and thus also the allowed values for _DSC are listed below. Refer
|
||||
to [1] for more information on device power states.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Number State Description
|
||||
0 D0 Device fully powered on
|
||||
1 D1
|
||||
2 D2
|
||||
3 D3hot
|
||||
4 D3cold Off
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] https://uefi.org/specifications/ACPI/6.4/02_Definition_of_Terms/Definition_of_Terms.html#device-power-state-definitions
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
An ASL example describing an ACPI device using _DSC object to tell Operating
|
||||
System the device should remain powered off during probe looks like this. Some
|
||||
objects not relevant from the example point of view have been omitted.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Device (CAM0)
|
||||
{
|
||||
Name (_HID, "SONY319A")
|
||||
Name (_UID, Zero)
|
||||
Name (_CRS, ResourceTemplate ()
|
||||
{
|
||||
I2cSerialBus(0x0020, ControllerInitiated, 0x00061A80,
|
||||
AddressingMode7Bit, "\\_SB.PCI0.I2C0",
|
||||
0x00, ResourceConsumer)
|
||||
})
|
||||
Method (_DSC, 0, NotSerialized)
|
||||
{
|
||||
Return (0x4)
|
||||
}
|
||||
}
|
@ -1400,4 +1400,30 @@ bool acpi_storage_d3(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_storage_d3);
|
||||
|
||||
/**
|
||||
* acpi_dev_state_d0 - Tell if the device is in D0 power state
|
||||
* @dev: Physical device the ACPI power state of which to check
|
||||
*
|
||||
* On a system without ACPI, return true. On a system with ACPI, return true if
|
||||
* the current ACPI power state of the device is D0, or false otherwise.
|
||||
*
|
||||
* Note that the power state of a device is not well-defined after it has been
|
||||
* passed to acpi_device_set_power() and before that function returns, so it is
|
||||
* 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
|
||||
* more information.
|
||||
*/
|
||||
bool acpi_dev_state_d0(struct device *dev)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
|
||||
if (!adev)
|
||||
return true;
|
||||
|
||||
return adev->power.state == ACPI_STATE_D0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_state_d0);
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
@ -133,7 +133,7 @@ static unsigned int ec_storm_threshold __read_mostly = 8;
|
||||
module_param(ec_storm_threshold, uint, 0644);
|
||||
MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm");
|
||||
|
||||
static bool ec_freeze_events __read_mostly = false;
|
||||
static bool ec_freeze_events __read_mostly;
|
||||
module_param(ec_freeze_events, bool, 0644);
|
||||
MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume");
|
||||
|
||||
@ -177,7 +177,7 @@ struct acpi_ec *first_ec;
|
||||
EXPORT_SYMBOL(first_ec);
|
||||
|
||||
static struct acpi_ec *boot_ec;
|
||||
static bool boot_ec_is_ecdt = false;
|
||||
static bool boot_ec_is_ecdt;
|
||||
static struct workqueue_struct *ec_wq;
|
||||
static struct workqueue_struct *ec_query_wq;
|
||||
|
||||
@ -2152,6 +2152,13 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "HP ZHAN 66 Pro",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
|
||||
},
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -211,31 +211,36 @@ static acpi_status intel_pmic_regs_handler(u32 function,
|
||||
void *handler_context, void *region_context)
|
||||
{
|
||||
struct intel_pmic_opregion *opregion = region_context;
|
||||
int result = 0;
|
||||
int result = -EINVAL;
|
||||
|
||||
switch (address) {
|
||||
case 0:
|
||||
return AE_OK;
|
||||
case 1:
|
||||
opregion->ctx.addr |= (*value64 & 0xff) << 8;
|
||||
return AE_OK;
|
||||
case 2:
|
||||
opregion->ctx.addr |= *value64 & 0xff;
|
||||
return AE_OK;
|
||||
case 3:
|
||||
opregion->ctx.val = *value64 & 0xff;
|
||||
return AE_OK;
|
||||
case 4:
|
||||
if (*value64) {
|
||||
result = regmap_write(opregion->regmap, opregion->ctx.addr,
|
||||
opregion->ctx.val);
|
||||
} else {
|
||||
result = regmap_read(opregion->regmap, opregion->ctx.addr,
|
||||
&opregion->ctx.val);
|
||||
if (result == 0)
|
||||
*value64 = opregion->ctx.val;
|
||||
if (function == ACPI_WRITE) {
|
||||
switch (address) {
|
||||
case 0:
|
||||
return AE_OK;
|
||||
case 1:
|
||||
opregion->ctx.addr |= (*value64 & 0xff) << 8;
|
||||
return AE_OK;
|
||||
case 2:
|
||||
opregion->ctx.addr |= *value64 & 0xff;
|
||||
return AE_OK;
|
||||
case 3:
|
||||
opregion->ctx.val = *value64 & 0xff;
|
||||
return AE_OK;
|
||||
case 4:
|
||||
if (*value64) {
|
||||
result = regmap_write(opregion->regmap, opregion->ctx.addr,
|
||||
opregion->ctx.val);
|
||||
} else {
|
||||
result = regmap_read(opregion->regmap, opregion->ctx.addr,
|
||||
&opregion->ctx.val);
|
||||
}
|
||||
opregion->ctx.addr = 0;
|
||||
}
|
||||
memset(&opregion->ctx, 0x00, sizeof(opregion->ctx));
|
||||
}
|
||||
|
||||
if (function == ACPI_READ && address == 3) {
|
||||
*value64 = opregion->ctx.val;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
|
@ -757,13 +757,11 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
|
||||
|
||||
mutex_lock(&acpi_device_lock);
|
||||
|
||||
if (dev->wakeup.prepare_count > 1) {
|
||||
dev->wakeup.prepare_count--;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Do nothing if wakeup power has not been enabled for this device. */
|
||||
if (!dev->wakeup.prepare_count)
|
||||
if (dev->wakeup.prepare_count <= 0)
|
||||
goto out;
|
||||
|
||||
if (--dev->wakeup.prepare_count > 0)
|
||||
goto out;
|
||||
|
||||
err = acpi_device_sleep_wake(dev, 0, 0, 0);
|
||||
|
@ -1017,6 +1017,7 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
|
||||
|
||||
static void acpi_bus_get_power_flags(struct acpi_device *device)
|
||||
{
|
||||
unsigned long long dsc = ACPI_STATE_D0;
|
||||
u32 i;
|
||||
|
||||
/* Presence of _PS0|_PR0 indicates 'power manageable' */
|
||||
@ -1038,6 +1039,9 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
|
||||
if (acpi_has_method(device->handle, "_DSW"))
|
||||
device->power.flags.dsw_present = 1;
|
||||
|
||||
acpi_evaluate_integer(device->handle, "_DSC", NULL, &dsc);
|
||||
device->power.state_for_enumeration = dsc;
|
||||
|
||||
/*
|
||||
* Enumerate supported power management states
|
||||
*/
|
||||
|
@ -115,7 +115,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "X360",
|
||||
/* X360 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
|
||||
@ -124,7 +124,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "Asus UL30VT",
|
||||
/* Asus UL30VT */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
|
||||
@ -132,7 +132,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "Asus UL30A",
|
||||
/* Asus UL30A */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
|
||||
@ -140,7 +140,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "GIGABYTE GB-BXBT-2807",
|
||||
/* GIGABYTE GB-BXBT-2807 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
|
||||
@ -148,12 +148,20 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "Sony VPCEH3U1E",
|
||||
/* Sony VPCEH3U1E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
/* Xiaomi Mi Pad 2 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* These models have a working acpi_video backlight control, and using
|
||||
@ -164,7 +172,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "ThinkPad T420",
|
||||
/* ThinkPad T420 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"),
|
||||
@ -172,7 +180,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "ThinkPad T520",
|
||||
/* ThinkPad T520 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"),
|
||||
@ -180,7 +188,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "ThinkPad X201s",
|
||||
/* ThinkPad X201s */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"),
|
||||
@ -188,7 +196,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "ThinkPad X201T",
|
||||
/* ThinkPad X201T */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"),
|
||||
@ -199,7 +207,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "HP ENVY 15 Notebook",
|
||||
/* HP ENVY 15 Notebook */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"),
|
||||
@ -207,7 +215,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 870Z5E/880Z5E/680Z5E",
|
||||
/* SAMSUNG 870Z5E/880Z5E/680Z5E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"),
|
||||
@ -215,7 +223,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V",
|
||||
/* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,
|
||||
@ -225,7 +233,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 3570R/370R/470R/450R/510R/4450RV",
|
||||
/* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,
|
||||
@ -235,7 +243,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 670Z5E",
|
||||
/* SAMSUNG 670Z5E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"),
|
||||
@ -244,7 +252,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 730U3E/740U3E",
|
||||
/* SAMSUNG 730U3E/740U3E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"),
|
||||
@ -253,7 +261,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D",
|
||||
/* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME,
|
||||
@ -263,7 +271,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "Dell XPS14 L421X",
|
||||
/* Dell XPS14 L421X */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
|
||||
@ -272,7 +280,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "Dell XPS15 L521X",
|
||||
/* Dell XPS15 L521X */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
|
||||
@ -281,7 +289,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "SAMSUNG 530U4E/540U4E",
|
||||
/* SAMSUNG 530U4E/540U4E */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
|
||||
@ -290,7 +298,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
/* https://bugs.launchpad.net/bugs/1894667 */
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "HP 635 Notebook",
|
||||
/* HP 635 Notebook */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"),
|
||||
@ -301,7 +309,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Lenovo Ideapad S405",
|
||||
/* Lenovo Ideapad S405 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
|
||||
@ -310,7 +318,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Lenovo Ideapad Z570",
|
||||
/* Lenovo Ideapad Z570 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
|
||||
@ -318,7 +326,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Lenovo E41-25",
|
||||
/* Lenovo E41-25 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "81FS"),
|
||||
@ -326,7 +334,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Lenovo E41-45",
|
||||
/* Lenovo E41-45 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "82BK"),
|
||||
@ -335,7 +343,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Apple MacBook Pro 12,1",
|
||||
/* Apple MacBook Pro 12,1 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
|
||||
@ -343,7 +351,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Dell Vostro V131",
|
||||
/* Dell Vostro V131 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
|
||||
@ -352,7 +360,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Dell XPS 17 L702X",
|
||||
/* Dell XPS 17 L702X */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
|
||||
@ -360,7 +368,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Dell Precision 7510",
|
||||
/* Dell Precision 7510 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
|
||||
@ -368,7 +376,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Acer Aspire 5738z",
|
||||
/* Acer Aspire 5738z */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"),
|
||||
@ -378,7 +386,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
{
|
||||
/* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Acer TravelMate 5735Z",
|
||||
/* Acer TravelMate 5735Z */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"),
|
||||
@ -387,7 +395,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "ASUSTeK COMPUTER INC. GA401",
|
||||
/* ASUSTeK COMPUTER INC. GA401 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GA401"),
|
||||
@ -395,7 +403,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "ASUSTeK COMPUTER INC. GA502",
|
||||
/* ASUSTeK COMPUTER INC. GA502 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GA502"),
|
||||
@ -403,7 +411,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "ASUSTeK COMPUTER INC. GA503",
|
||||
/* ASUSTeK COMPUTER INC. GA503 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
|
||||
@ -416,7 +424,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
.ident = "Dell OptiPlex 9020M",
|
||||
/* Dell OptiPlex 9020M */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
|
||||
@ -424,7 +432,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
.ident = "MSI MS-7721",
|
||||
/* MSI MS-7721 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
|
||||
|
@ -522,6 +522,16 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
|
||||
|
||||
bool i2c_acpi_waive_d0_probe(struct device *dev)
|
||||
{
|
||||
struct i2c_driver *driver = to_i2c_driver(dev->driver);
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
|
||||
return driver->flags & I2C_DRV_ACPI_WAIVE_D0_PROBE &&
|
||||
adev && adev->power.state_for_enumeration >= adev->power.state;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_acpi_waive_d0_probe);
|
||||
|
||||
#ifdef CONFIG_ACPI_I2C_OPREGION
|
||||
static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
|
||||
u8 cmd, u8 *data, u8 data_len)
|
||||
|
@ -551,7 +551,8 @@ static int i2c_device_probe(struct device *dev)
|
||||
if (status < 0)
|
||||
goto err_clear_wakeup_irq;
|
||||
|
||||
status = dev_pm_domain_attach(&client->dev, true);
|
||||
status = dev_pm_domain_attach(&client->dev,
|
||||
!i2c_acpi_waive_d0_probe(dev));
|
||||
if (status)
|
||||
goto err_clear_wakeup_irq;
|
||||
|
||||
@ -590,7 +591,7 @@ static int i2c_device_probe(struct device *dev)
|
||||
err_release_driver_resources:
|
||||
devres_release_group(&client->dev, client->devres_group_id);
|
||||
err_detach_pm_domain:
|
||||
dev_pm_domain_detach(&client->dev, true);
|
||||
dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
|
||||
err_clear_wakeup_irq:
|
||||
dev_pm_clear_wake_irq(&client->dev);
|
||||
device_init_wakeup(&client->dev, false);
|
||||
@ -621,7 +622,7 @@ static void i2c_device_remove(struct device *dev)
|
||||
|
||||
devres_release_group(&client->dev, client->devres_group_id);
|
||||
|
||||
dev_pm_domain_detach(&client->dev, true);
|
||||
dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev));
|
||||
if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator)
|
||||
regulator_disable(adap->bus_regulator);
|
||||
|
||||
|
@ -140,6 +140,8 @@ struct imx319 {
|
||||
|
||||
/* Streaming on/off */
|
||||
bool streaming;
|
||||
/* True if the device has been identified */
|
||||
bool identified;
|
||||
};
|
||||
|
||||
static const struct imx319_reg imx319_global_regs[] = {
|
||||
@ -2084,6 +2086,31 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Verify chip ID */
|
||||
static int imx319_identify_module(struct imx319 *imx319)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
if (imx319->identified)
|
||||
return 0;
|
||||
|
||||
ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val != IMX319_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x",
|
||||
IMX319_CHIP_ID, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
imx319->identified = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start streaming */
|
||||
static int imx319_start_streaming(struct imx319 *imx319)
|
||||
{
|
||||
@ -2091,6 +2118,10 @@ static int imx319_start_streaming(struct imx319 *imx319)
|
||||
const struct imx319_reg_list *reg_list;
|
||||
int ret;
|
||||
|
||||
ret = imx319_identify_module(imx319);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Global Setting */
|
||||
reg_list = &imx319_global_setting;
|
||||
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
|
||||
@ -2206,26 +2237,6 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify chip ID */
|
||||
static int imx319_identify_module(struct imx319 *imx319)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val != IMX319_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x",
|
||||
IMX319_CHIP_ID, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = {
|
||||
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
|
||||
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||||
@ -2420,6 +2431,7 @@ out_err:
|
||||
static int imx319_probe(struct i2c_client *client)
|
||||
{
|
||||
struct imx319 *imx319;
|
||||
bool full_power;
|
||||
int ret;
|
||||
u32 i;
|
||||
|
||||
@ -2432,11 +2444,14 @@ static int imx319_probe(struct i2c_client *client)
|
||||
/* Initialize subdev */
|
||||
v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
|
||||
|
||||
/* Check module identity */
|
||||
ret = imx319_identify_module(imx319);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
goto error_probe;
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
if (full_power) {
|
||||
/* Check module identity */
|
||||
ret = imx319_identify_module(imx319);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
}
|
||||
|
||||
imx319->hwcfg = imx319_get_hwcfg(&client->dev);
|
||||
@ -2488,11 +2503,9 @@ static int imx319_probe(struct i2c_client *client)
|
||||
if (ret < 0)
|
||||
goto error_media_entity;
|
||||
|
||||
/*
|
||||
* Device is already turned on by i2c-core with ACPI domain PM.
|
||||
* Enable runtime PM and turn off the device.
|
||||
*/
|
||||
pm_runtime_set_active(&client->dev);
|
||||
/* Set the device's state to active if it's in D0 state. */
|
||||
if (full_power)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
|
||||
@ -2545,6 +2558,7 @@ static struct i2c_driver imx319_i2c_driver = {
|
||||
},
|
||||
.probe_new = imx319_probe,
|
||||
.remove = imx319_remove,
|
||||
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
|
||||
};
|
||||
module_i2c_driver(imx319_i2c_driver);
|
||||
|
||||
|
@ -595,6 +595,7 @@ static int at24_probe(struct i2c_client *client)
|
||||
bool i2c_fn_i2c, i2c_fn_block;
|
||||
unsigned int i, num_addresses;
|
||||
struct at24_data *at24;
|
||||
bool full_power;
|
||||
struct regmap *regmap;
|
||||
bool writable;
|
||||
u8 test_byte;
|
||||
@ -747,14 +748,16 @@ static int at24_probe(struct i2c_client *client)
|
||||
|
||||
i2c_set_clientdata(client, at24);
|
||||
|
||||
err = regulator_enable(at24->vcc_reg);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to enable vcc regulator\n");
|
||||
return err;
|
||||
}
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
if (full_power) {
|
||||
err = regulator_enable(at24->vcc_reg);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to enable vcc regulator\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* enable runtime pm */
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
}
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
|
||||
@ -766,15 +769,18 @@ static int at24_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a one-byte test read to verify that the
|
||||
* chip is functional.
|
||||
* Perform a one-byte test read to verify that the chip is functional,
|
||||
* unless powering on the device is to be avoided during probe (i.e.
|
||||
* it's powered off right now).
|
||||
*/
|
||||
err = at24_read(at24, 0, &test_byte, 1);
|
||||
if (err) {
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return -ENODEV;
|
||||
if (full_power) {
|
||||
err = at24_read(at24, 0, &test_byte, 1);
|
||||
if (err) {
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_idle(dev);
|
||||
@ -794,9 +800,11 @@ static int at24_remove(struct i2c_client *client)
|
||||
struct at24_data *at24 = i2c_get_clientdata(client);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
if (acpi_dev_state_d0(&client->dev)) {
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -833,6 +841,7 @@ static struct i2c_driver at24_driver = {
|
||||
.probe_new = at24_probe,
|
||||
.remove = at24_remove,
|
||||
.id_table = at24_ids,
|
||||
.flags = I2C_DRV_ACPI_WAIVE_D0_PROBE,
|
||||
};
|
||||
|
||||
static int __init at24_init(void)
|
||||
|
@ -278,6 +278,7 @@ struct acpi_device_power {
|
||||
int state; /* Current state */
|
||||
struct acpi_device_power_flags flags;
|
||||
struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
|
||||
u8 state_for_enumeration; /* Deepest power state for enumeration */
|
||||
};
|
||||
|
||||
struct acpi_dep_data {
|
||||
|
@ -10,25 +10,12 @@
|
||||
#ifndef __ACGCC_H__
|
||||
#define __ACGCC_H__
|
||||
|
||||
/*
|
||||
* Use compiler specific <stdarg.h> is a good practice for even when
|
||||
* -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined.
|
||||
*/
|
||||
#ifndef va_arg
|
||||
#ifdef ACPI_USE_BUILTIN_STDARG
|
||||
typedef __builtin_va_list va_list;
|
||||
#define va_start(v, l) __builtin_va_start(v, l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v, l) __builtin_va_arg(v, l)
|
||||
#define va_copy(d, s) __builtin_va_copy(d, s)
|
||||
#else
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/stdarg.h>
|
||||
#else
|
||||
/* Used to build acpi tools */
|
||||
#include <stdarg.h>
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* ACPI_USE_BUILTIN_STDARG */
|
||||
#endif /* ! va_arg */
|
||||
|
||||
#define ACPI_INLINE __inline__
|
||||
|
@ -1014,6 +1014,7 @@ int acpi_subsys_runtime_suspend(struct device *dev);
|
||||
int acpi_subsys_runtime_resume(struct device *dev);
|
||||
int acpi_dev_pm_attach(struct device *dev, bool power_on);
|
||||
bool acpi_storage_d3(struct device *dev);
|
||||
bool acpi_dev_state_d0(struct device *dev);
|
||||
#else
|
||||
static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
|
||||
static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
|
||||
@ -1025,6 +1026,10 @@ static inline bool acpi_storage_d3(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool acpi_dev_state_d0(struct device *dev)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define _LINUX_I2C_H
|
||||
|
||||
#include <linux/acpi.h> /* for acpi_handle */
|
||||
#include <linux/bits.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/device.h> /* for struct device */
|
||||
#include <linux/sched.h> /* for completion */
|
||||
@ -222,6 +223,15 @@ enum i2c_alert_protocol {
|
||||
I2C_PROTOCOL_SMBUS_HOST_NOTIFY,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum i2c_driver_flags - Flags for an I2C device driver
|
||||
*
|
||||
* @I2C_DRV_ACPI_WAIVE_D0_PROBE: Don't put the device in D0 state for probe
|
||||
*/
|
||||
enum i2c_driver_flags {
|
||||
I2C_DRV_ACPI_WAIVE_D0_PROBE = BIT(0),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct i2c_driver - represent an I2C device driver
|
||||
* @class: What kind of i2c device we instantiate (for detect)
|
||||
@ -236,6 +246,7 @@ enum i2c_alert_protocol {
|
||||
* @detect: Callback for device detection
|
||||
* @address_list: The I2C addresses to probe (for detect)
|
||||
* @clients: List of detected clients we created (for i2c-core use only)
|
||||
* @flags: A bitmask of flags defined in &enum i2c_driver_flags
|
||||
*
|
||||
* The driver.owner field should be set to the module owner of this driver.
|
||||
* The driver.name field should be set to the name of this driver.
|
||||
@ -294,6 +305,8 @@ struct i2c_driver {
|
||||
int (*detect)(struct i2c_client *client, struct i2c_board_info *info);
|
||||
const unsigned short *address_list;
|
||||
struct list_head clients;
|
||||
|
||||
u32 flags;
|
||||
};
|
||||
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
|
||||
|
||||
@ -1015,6 +1028,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev);
|
||||
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
struct i2c_board_info *info);
|
||||
struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
|
||||
bool i2c_acpi_waive_d0_probe(struct device *dev);
|
||||
#else
|
||||
static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c)
|
||||
@ -1038,6 +1052,10 @@ static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle ha
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline bool i2c_acpi_waive_d0_probe(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
#endif /* _LINUX_I2C_H */
|
||||
|
Loading…
Reference in New Issue
Block a user