2014-10-13 14:43:21

by Jim Davis

[permalink] [raw]
Subject: randconfig build error with next-20141013, in drivers/thermal/int340x_thermal/int3406_thermal.c

Building with the attached random configuration file,

drivers/built-in.o: In function `int3406_thermal_probe':
int3406_thermal.c:(.text+0x1d10b8): undefined reference to
`acpi_video_get_levels'
make: *** [vmlinux] Error 1


Attachments:
randconfig-1413183282.txt (84.62 kB)

2014-10-16 08:59:08

by Aaron Lu

[permalink] [raw]
Subject: [PATCH] Thermal: int3406_thermal: solve the dependency build error

On 10/13/2014 10:43 PM, Jim Davis wrote:
> Building with the attached random configuration file,
>
> drivers/built-in.o: In function `int3406_thermal_probe':
> int3406_thermal.c:(.text+0x1d10b8): undefined reference to
> `acpi_video_get_levels'
> make: *** [vmlinux] Error 1

Thanks for the report Jim, below patch should fix this problem:

From: Aaron Lu <[email protected]>
Date: Thu, 16 Oct 2014 16:35:02 +0800
Subject: [PATCH] Thermal: int3406_thermal: solve the dependency build error

Jim found that the current kernel may trigger a build error with some
config: drivers/built-in.o: In function `int3406_thermal_probe':
int3406_thermal.c:(.text+0x1d10b8): undefined reference to
`acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
CONFIG_ACPI_VIDEO=m. Since the ACPI video driver can still work well
without CONFIG_THERMAL(regarding its main functionality: backlight
control), solve the problem by removing the select THERMAL line for
ACPI_VIDEO and adding the select ACPI_VIDEO for INT340X_THERMAL. The
result is that for kernels that do not have CONFIG_THERMAL selected now,
the ACPI video driver will not create the cooling device as it did
before(but works well otherwise).

Reported-by: Jim Davis <[email protected]>
Signed-off-by: Aaron Lu <[email protected]>
---
drivers/acpi/Kconfig | 1 -
drivers/thermal/Kconfig | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index b23fe37f67c0..8a09f98dbb0c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -131,7 +131,6 @@ config ACPI_VIDEO
tristate "Video"
depends on X86 && BACKLIGHT_CLASS_DEVICE
depends on INPUT
- select THERMAL
help
This driver implements the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9b012ff65220..4e1053a8d774 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -235,6 +235,7 @@ config INT340X_THERMAL
select THERMAL_GOV_USER_SPACE
select ACPI_THERMAL_REL
select ACPI_FAN
+ select ACPI_VIDEO
help
Newer laptops and tablets that use ACPI may have thermal sensors and
other devices with thermal control capabilities outside the core
--
1.9.3

2014-10-17 07:06:25

by Aaron Lu

[permalink] [raw]
Subject: [PATCH v2] Thermal: int3406_thermal: solve the dependency build error

Jim found that the current kernel may trigger a build error with some
config: drivers/built-in.o: In function `int3406_thermal_probe':
int3406_thermal.c:(.text+0x1d10b8): undefined reference to
`acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
int3406 thermal driver and add dependency on ACPI video for it.

Reported-by: Jim Davis <[email protected]>
Signed-off-by: Aaron Lu <[email protected]>
---
v2: v1 still has a problem so please ignore the last patch.

drivers/thermal/Kconfig | 22 +++------------------
drivers/thermal/int340x_thermal/Kconfig | 34 ++++++++++++++++++++++++++++++++
drivers/thermal/int340x_thermal/Makefile | 2 +-
3 files changed, 38 insertions(+), 20 deletions(-)
create mode 100644 drivers/thermal/int340x_thermal/Kconfig

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9b012ff65220..3bca14d86482 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -229,25 +229,9 @@ config INTEL_SOC_DTS_THERMAL
notification methods.The other trip is a critical trip point, which
was set by the driver based on the TJ MAX temperature.

-config INT340X_THERMAL
- tristate "ACPI INT340X thermal drivers"
- depends on X86 && ACPI
- select THERMAL_GOV_USER_SPACE
- select ACPI_THERMAL_REL
- select ACPI_FAN
- help
- Newer laptops and tablets that use ACPI may have thermal sensors and
- other devices with thermal control capabilities outside the core
- CPU/SOC, for thermal safety reasons.
- They are exposed for the OS to use via the INT3400 ACPI device object
- as the master, and INT3401~INT340B ACPI device objects as the slaves.
- Enable this to expose the temperature information and cooling ability
- from these objects to userspace via the normal thermal framework.
- This means that a wide range of applications and GUI widgets can show
- the information to the user or use this information for making
- decisions. For example, the Intel Thermal Daemon can use this
- information to allow the user to select his laptop to run without
- turning on the fans.
+menu "ACPI INT340X thermal drivers"
+source drivers/thermal/int340x_thermal/Kconfig
+endmenu

config ACPI_THERMAL_REL
tristate
diff --git a/drivers/thermal/int340x_thermal/Kconfig b/drivers/thermal/int340x_thermal/Kconfig
new file mode 100644
index 000000000000..9a58520d24a4
--- /dev/null
+++ b/drivers/thermal/int340x_thermal/Kconfig
@@ -0,0 +1,34 @@
+#
+# ACPI INT340x thermal drivers configuration
+#
+
+config INT340X_THERMAL
+ tristate "ACPI INT340X thermal drivers"
+ depends on X86 && ACPI
+ select THERMAL_GOV_USER_SPACE
+ select ACPI_THERMAL_REL
+ select ACPI_FAN
+ help
+ Newer laptops and tablets that use ACPI may have thermal sensors and
+ other devices with thermal control capabilities outside the core
+ CPU/SOC, for thermal safety reasons.
+ They are exposed for the OS to use via the INT3400 ACPI device object
+ as the master, and INT3401~INT340B ACPI device objects as the slaves.
+ Enable this to expose the temperature information and cooling ability
+ from these objects to userspace via the normal thermal framework.
+ This means that a wide range of applications and GUI widgets can show
+ the information to the user or use this information for making
+ decisions. For example, the Intel Thermal Daemon can use this
+ information to allow the user to select his laptop to run without
+ turning on the fans.
+
+config INT3406_THERMAL
+ tristate "ACPI INT3406 display thermal driver"
+ depends on INT340X_THERMAL
+ depends on ACPI_VIDEO
+ help
+ The display thermal device represents the LED/LCD display panel
+ that may or may not include touch support. The main function of
+ the display thermal device is to allow control of the display
+ brightness in order to address a thermal condition or to reduce
+ power consumed by display device.
diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
index e3e2eb20da94..a9d0429be412 100644
--- a/drivers/thermal/int340x_thermal/Makefile
+++ b/drivers/thermal/int340x_thermal/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
-obj-$(CONFIG_INT340X_THERMAL) += int3406_thermal.o
+obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
--
1.9.3

2014-10-17 07:22:44

by Aaron Lu

[permalink] [raw]
Subject: [PATCH v3] Thermal: int3406_thermal: solve the dependency build error

Jim found that the current kernel may trigger a build error with some
config: drivers/built-in.o: In function `int3406_thermal_probe':
int3406_thermal.c:(.text+0x1d10b8): undefined reference to
`acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
int3406 thermal driver and add dependency on ACPI video for it.

Reported-by: Jim Davis <[email protected]>
Signed-off-by: Aaron Lu <[email protected]>
---
v3: move ACPI_THERMAL_REL into the INT340X_THERMAL menu as it is only
used by INT340X drivers and use if INT340X_THERMAL to avoid multiple
depend lines as suggested by Rui.

drivers/thermal/Kconfig | 26 +++-----------------
drivers/thermal/int340x_thermal/Kconfig | 41 ++++++++++++++++++++++++++++++++
drivers/thermal/int340x_thermal/Makefile | 2 +-
3 files changed, 45 insertions(+), 24 deletions(-)
create mode 100644 drivers/thermal/int340x_thermal/Kconfig

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9b012ff65220..4565e55dbef9 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -229,29 +229,9 @@ config INTEL_SOC_DTS_THERMAL
notification methods.The other trip is a critical trip point, which
was set by the driver based on the TJ MAX temperature.

-config INT340X_THERMAL
- tristate "ACPI INT340X thermal drivers"
- depends on X86 && ACPI
- select THERMAL_GOV_USER_SPACE
- select ACPI_THERMAL_REL
- select ACPI_FAN
- help
- Newer laptops and tablets that use ACPI may have thermal sensors and
- other devices with thermal control capabilities outside the core
- CPU/SOC, for thermal safety reasons.
- They are exposed for the OS to use via the INT3400 ACPI device object
- as the master, and INT3401~INT340B ACPI device objects as the slaves.
- Enable this to expose the temperature information and cooling ability
- from these objects to userspace via the normal thermal framework.
- This means that a wide range of applications and GUI widgets can show
- the information to the user or use this information for making
- decisions. For example, the Intel Thermal Daemon can use this
- information to allow the user to select his laptop to run without
- turning on the fans.
-
-config ACPI_THERMAL_REL
- tristate
- depends on ACPI
+menu "ACPI INT340X thermal drivers"
+source drivers/thermal/int340x_thermal/Kconfig
+endmenu

menu "Texas Instruments thermal drivers"
source "drivers/thermal/ti-soc-thermal/Kconfig"
diff --git a/drivers/thermal/int340x_thermal/Kconfig b/drivers/thermal/int340x_thermal/Kconfig
new file mode 100644
index 000000000000..b92892a6afe0
--- /dev/null
+++ b/drivers/thermal/int340x_thermal/Kconfig
@@ -0,0 +1,41 @@
+#
+# ACPI INT340x thermal drivers configuration
+#
+
+config INT340X_THERMAL
+ tristate "ACPI INT340X thermal drivers"
+ depends on X86 && ACPI
+ select THERMAL_GOV_USER_SPACE
+ select ACPI_THERMAL_REL
+ select ACPI_FAN
+ help
+ Newer laptops and tablets that use ACPI may have thermal sensors and
+ other devices with thermal control capabilities outside the core
+ CPU/SOC, for thermal safety reasons.
+ They are exposed for the OS to use via the INT3400 ACPI device object
+ as the master, and INT3401~INT340B ACPI device objects as the slaves.
+ Enable this to expose the temperature information and cooling ability
+ from these objects to userspace via the normal thermal framework.
+ This means that a wide range of applications and GUI widgets can show
+ the information to the user or use this information for making
+ decisions. For example, the Intel Thermal Daemon can use this
+ information to allow the user to select his laptop to run without
+ turning on the fans.
+
+if INT340X_THERMAL
+
+config ACPI_THERMAL_REL
+ tristate
+ depends on ACPI
+
+config INT3406_THERMAL
+ tristate "ACPI INT3406 display thermal driver"
+ depends on ACPI_VIDEO
+ help
+ The display thermal device represents the LED/LCD display panel
+ that may or may not include touch support. The main function of
+ the display thermal device is to allow control of the display
+ brightness in order to address a thermal condition or to reduce
+ power consumed by display device.
+
+endif
diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
index e3e2eb20da94..a9d0429be412 100644
--- a/drivers/thermal/int340x_thermal/Makefile
+++ b/drivers/thermal/int340x_thermal/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
-obj-$(CONFIG_INT340X_THERMAL) += int3406_thermal.o
+obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
--
1.9.3

2014-10-28 06:12:10

by Aaron Lu

[permalink] [raw]
Subject: [PATCH v4] Thermal: int3406_thermal: solve the dependency build error

Jim found that the current kernel may trigger a build error with some
config: drivers/built-in.o: In function `int3406_thermal_probe':
int3406_thermal.c:(.text+0x1d10b8): undefined reference to
`acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
int3406 thermal driver and add dependency on ACPI video for it.

Reported-by: Jim Davis <[email protected]>
Signed-off-by: Aaron Lu <[email protected]>
---
v4: rebased on v3.18-rc2.

drivers/thermal/Kconfig | 26 +++-----------------
drivers/thermal/int340x_thermal/Kconfig | 41 ++++++++++++++++++++++++++++++++
drivers/thermal/int340x_thermal/Makefile | 1 +
3 files changed, 45 insertions(+), 23 deletions(-)
create mode 100644 drivers/thermal/int340x_thermal/Kconfig

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index f554d25b4399..ac391d8d76b4 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -229,29 +229,9 @@ config INTEL_SOC_DTS_THERMAL
notification methods.The other trip is a critical trip point, which
was set by the driver based on the TJ MAX temperature.

-config INT340X_THERMAL
- tristate "ACPI INT340X thermal drivers"
- depends on X86 && ACPI
- select THERMAL_GOV_USER_SPACE
- select ACPI_THERMAL_REL
- select ACPI_FAN
- help
- Newer laptops and tablets that use ACPI may have thermal sensors and
- other devices with thermal control capabilities outside the core
- CPU/SOC, for thermal safety reasons.
- They are exposed for the OS to use via the INT3400 ACPI device object
- as the master, and INT3401~INT340B ACPI device objects as the slaves.
- Enable this to expose the temperature information and cooling ability
- from these objects to userspace via the normal thermal framework.
- This means that a wide range of applications and GUI widgets can show
- the information to the user or use this information for making
- decisions. For example, the Intel Thermal Daemon can use this
- information to allow the user to select his laptop to run without
- turning on the fans.
-
-config ACPI_THERMAL_REL
- tristate
- depends on ACPI
+menu "ACPI INT340X thermal drivers"
+source drivers/thermal/int340x_thermal/Kconfig
+endmenu

menu "Texas Instruments thermal drivers"
source "drivers/thermal/ti-soc-thermal/Kconfig"
diff --git a/drivers/thermal/int340x_thermal/Kconfig b/drivers/thermal/int340x_thermal/Kconfig
new file mode 100644
index 000000000000..b92892a6afe0
--- /dev/null
+++ b/drivers/thermal/int340x_thermal/Kconfig
@@ -0,0 +1,41 @@
+#
+# ACPI INT340x thermal drivers configuration
+#
+
+config INT340X_THERMAL
+ tristate "ACPI INT340X thermal drivers"
+ depends on X86 && ACPI
+ select THERMAL_GOV_USER_SPACE
+ select ACPI_THERMAL_REL
+ select ACPI_FAN
+ help
+ Newer laptops and tablets that use ACPI may have thermal sensors and
+ other devices with thermal control capabilities outside the core
+ CPU/SOC, for thermal safety reasons.
+ They are exposed for the OS to use via the INT3400 ACPI device object
+ as the master, and INT3401~INT340B ACPI device objects as the slaves.
+ Enable this to expose the temperature information and cooling ability
+ from these objects to userspace via the normal thermal framework.
+ This means that a wide range of applications and GUI widgets can show
+ the information to the user or use this information for making
+ decisions. For example, the Intel Thermal Daemon can use this
+ information to allow the user to select his laptop to run without
+ turning on the fans.
+
+if INT340X_THERMAL
+
+config ACPI_THERMAL_REL
+ tristate
+ depends on ACPI
+
+config INT3406_THERMAL
+ tristate "ACPI INT3406 display thermal driver"
+ depends on ACPI_VIDEO
+ help
+ The display thermal device represents the LED/LCD display panel
+ that may or may not include touch support. The main function of
+ the display thermal device is to allow control of the display
+ brightness in order to address a thermal condition or to reduce
+ power consumed by display device.
+
+endif
diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
index ffe40bffaf1a..a9d0429be412 100644
--- a/drivers/thermal/int340x_thermal/Makefile
+++ b/drivers/thermal/int340x_thermal/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
+obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
--
1.9.3

2014-11-07 19:11:42

by Eduardo Valentin

[permalink] [raw]
Subject: Re: [PATCH v4] Thermal: int3406_thermal: solve the dependency build error

Hi,

On Tue, Oct 28, 2014 at 02:11:59PM +0800, Aaron Lu wrote:
> Jim found that the current kernel may trigger a build error with some
> config: drivers/built-in.o: In function `int3406_thermal_probe':
> int3406_thermal.c:(.text+0x1d10b8): undefined reference to
> `acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
> CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
> int3406 thermal driver and add dependency on ACPI video for it.
>
> Reported-by: Jim Davis <[email protected]>
> Signed-off-by: Aaron Lu <[email protected]>

Rui,

Any further comments on this change?

BR,

Eduardo Valentin

> ---
> v4: rebased on v3.18-rc2.
>
> drivers/thermal/Kconfig | 26 +++-----------------
> drivers/thermal/int340x_thermal/Kconfig | 41 ++++++++++++++++++++++++++++++++
> drivers/thermal/int340x_thermal/Makefile | 1 +
> 3 files changed, 45 insertions(+), 23 deletions(-)
> create mode 100644 drivers/thermal/int340x_thermal/Kconfig
>
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index f554d25b4399..ac391d8d76b4 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -229,29 +229,9 @@ config INTEL_SOC_DTS_THERMAL
> notification methods.The other trip is a critical trip point, which
> was set by the driver based on the TJ MAX temperature.
>
> -config INT340X_THERMAL
> - tristate "ACPI INT340X thermal drivers"
> - depends on X86 && ACPI
> - select THERMAL_GOV_USER_SPACE
> - select ACPI_THERMAL_REL
> - select ACPI_FAN
> - help
> - Newer laptops and tablets that use ACPI may have thermal sensors and
> - other devices with thermal control capabilities outside the core
> - CPU/SOC, for thermal safety reasons.
> - They are exposed for the OS to use via the INT3400 ACPI device object
> - as the master, and INT3401~INT340B ACPI device objects as the slaves.
> - Enable this to expose the temperature information and cooling ability
> - from these objects to userspace via the normal thermal framework.
> - This means that a wide range of applications and GUI widgets can show
> - the information to the user or use this information for making
> - decisions. For example, the Intel Thermal Daemon can use this
> - information to allow the user to select his laptop to run without
> - turning on the fans.
> -
> -config ACPI_THERMAL_REL
> - tristate
> - depends on ACPI
> +menu "ACPI INT340X thermal drivers"
> +source drivers/thermal/int340x_thermal/Kconfig
> +endmenu
>
> menu "Texas Instruments thermal drivers"
> source "drivers/thermal/ti-soc-thermal/Kconfig"
> diff --git a/drivers/thermal/int340x_thermal/Kconfig b/drivers/thermal/int340x_thermal/Kconfig
> new file mode 100644
> index 000000000000..b92892a6afe0
> --- /dev/null
> +++ b/drivers/thermal/int340x_thermal/Kconfig
> @@ -0,0 +1,41 @@
> +#
> +# ACPI INT340x thermal drivers configuration
> +#
> +
> +config INT340X_THERMAL
> + tristate "ACPI INT340X thermal drivers"
> + depends on X86 && ACPI
> + select THERMAL_GOV_USER_SPACE
> + select ACPI_THERMAL_REL
> + select ACPI_FAN
> + help
> + Newer laptops and tablets that use ACPI may have thermal sensors and
> + other devices with thermal control capabilities outside the core
> + CPU/SOC, for thermal safety reasons.
> + They are exposed for the OS to use via the INT3400 ACPI device object
> + as the master, and INT3401~INT340B ACPI device objects as the slaves.
> + Enable this to expose the temperature information and cooling ability
> + from these objects to userspace via the normal thermal framework.
> + This means that a wide range of applications and GUI widgets can show
> + the information to the user or use this information for making
> + decisions. For example, the Intel Thermal Daemon can use this
> + information to allow the user to select his laptop to run without
> + turning on the fans.
> +
> +if INT340X_THERMAL
> +
> +config ACPI_THERMAL_REL
> + tristate
> + depends on ACPI
> +
> +config INT3406_THERMAL
> + tristate "ACPI INT3406 display thermal driver"
> + depends on ACPI_VIDEO
> + help
> + The display thermal device represents the LED/LCD display panel
> + that may or may not include touch support. The main function of
> + the display thermal device is to allow control of the display
> + brightness in order to address a thermal condition or to reduce
> + power consumed by display device.
> +
> +endif
> diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
> index ffe40bffaf1a..a9d0429be412 100644
> --- a/drivers/thermal/int340x_thermal/Makefile
> +++ b/drivers/thermal/int340x_thermal/Makefile
> @@ -1,4 +1,5 @@
> obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
> obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
> obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
> +obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
> obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
> --
> 1.9.3
>


Attachments:
(No filename) (4.87 kB)
signature.asc (473.00 B)
Digital signature
Download all attachments

2014-11-30 12:23:07

by Zhang, Rui

[permalink] [raw]
Subject: Re: [PATCH v4] Thermal: int3406_thermal: solve the dependency build error

On Fri, 2014-11-07 at 15:11 -0400, Eduardo Valentin wrote:
> Hi,
>
> On Tue, Oct 28, 2014 at 02:11:59PM +0800, Aaron Lu wrote:
> > Jim found that the current kernel may trigger a build error with some
> > config: drivers/built-in.o: In function `int3406_thermal_probe':
> > int3406_thermal.c:(.text+0x1d10b8): undefined reference to
> > `acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
> > CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
> > int3406 thermal driver and add dependency on ACPI video for it.
> >
> > Reported-by: Jim Davis <[email protected]>
> > Signed-off-by: Aaron Lu <[email protected]>
>
Aaron, this is an incremental patch on top of the INT3406 driver patch.
As, both patches have not been shipped in Linus' tree, please merge
these two patches altogether and resend.

thanks,
rui
> Rui,
>
> Any further comments on this change?
>
> BR,
>
> Eduardo Valentin
>
> > ---
> > v4: rebased on v3.18-rc2.
> >
> > drivers/thermal/Kconfig | 26 +++-----------------
> > drivers/thermal/int340x_thermal/Kconfig | 41 ++++++++++++++++++++++++++++++++
> > drivers/thermal/int340x_thermal/Makefile | 1 +
> > 3 files changed, 45 insertions(+), 23 deletions(-)
> > create mode 100644 drivers/thermal/int340x_thermal/Kconfig
> >
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index f554d25b4399..ac391d8d76b4 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -229,29 +229,9 @@ config INTEL_SOC_DTS_THERMAL
> > notification methods.The other trip is a critical trip point, which
> > was set by the driver based on the TJ MAX temperature.
> >
> > -config INT340X_THERMAL
> > - tristate "ACPI INT340X thermal drivers"
> > - depends on X86 && ACPI
> > - select THERMAL_GOV_USER_SPACE
> > - select ACPI_THERMAL_REL
> > - select ACPI_FAN
> > - help
> > - Newer laptops and tablets that use ACPI may have thermal sensors and
> > - other devices with thermal control capabilities outside the core
> > - CPU/SOC, for thermal safety reasons.
> > - They are exposed for the OS to use via the INT3400 ACPI device object
> > - as the master, and INT3401~INT340B ACPI device objects as the slaves.
> > - Enable this to expose the temperature information and cooling ability
> > - from these objects to userspace via the normal thermal framework.
> > - This means that a wide range of applications and GUI widgets can show
> > - the information to the user or use this information for making
> > - decisions. For example, the Intel Thermal Daemon can use this
> > - information to allow the user to select his laptop to run without
> > - turning on the fans.
> > -
> > -config ACPI_THERMAL_REL
> > - tristate
> > - depends on ACPI
> > +menu "ACPI INT340X thermal drivers"
> > +source drivers/thermal/int340x_thermal/Kconfig
> > +endmenu
> >
> > menu "Texas Instruments thermal drivers"
> > source "drivers/thermal/ti-soc-thermal/Kconfig"
> > diff --git a/drivers/thermal/int340x_thermal/Kconfig b/drivers/thermal/int340x_thermal/Kconfig
> > new file mode 100644
> > index 000000000000..b92892a6afe0
> > --- /dev/null
> > +++ b/drivers/thermal/int340x_thermal/Kconfig
> > @@ -0,0 +1,41 @@
> > +#
> > +# ACPI INT340x thermal drivers configuration
> > +#
> > +
> > +config INT340X_THERMAL
> > + tristate "ACPI INT340X thermal drivers"
> > + depends on X86 && ACPI
> > + select THERMAL_GOV_USER_SPACE
> > + select ACPI_THERMAL_REL
> > + select ACPI_FAN
> > + help
> > + Newer laptops and tablets that use ACPI may have thermal sensors and
> > + other devices with thermal control capabilities outside the core
> > + CPU/SOC, for thermal safety reasons.
> > + They are exposed for the OS to use via the INT3400 ACPI device object
> > + as the master, and INT3401~INT340B ACPI device objects as the slaves.
> > + Enable this to expose the temperature information and cooling ability
> > + from these objects to userspace via the normal thermal framework.
> > + This means that a wide range of applications and GUI widgets can show
> > + the information to the user or use this information for making
> > + decisions. For example, the Intel Thermal Daemon can use this
> > + information to allow the user to select his laptop to run without
> > + turning on the fans.
> > +
> > +if INT340X_THERMAL
> > +
> > +config ACPI_THERMAL_REL
> > + tristate
> > + depends on ACPI
> > +
> > +config INT3406_THERMAL
> > + tristate "ACPI INT3406 display thermal driver"
> > + depends on ACPI_VIDEO
> > + help
> > + The display thermal device represents the LED/LCD display panel
> > + that may or may not include touch support. The main function of
> > + the display thermal device is to allow control of the display
> > + brightness in order to address a thermal condition or to reduce
> > + power consumed by display device.
> > +
> > +endif
> > diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
> > index ffe40bffaf1a..a9d0429be412 100644
> > --- a/drivers/thermal/int340x_thermal/Makefile
> > +++ b/drivers/thermal/int340x_thermal/Makefile
> > @@ -1,4 +1,5 @@
> > obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
> > obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
> > obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
> > +obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
> > obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
> > --
> > 1.9.3
> >

2014-12-02 06:19:32

by Aaron Lu

[permalink] [raw]
Subject: [PATCH] Thermal: introduce INT3406 thermal driver

On 11/30/2014 08:22 PM, Zhang Rui wrote:
> On Fri, 2014-11-07 at 15:11 -0400, Eduardo Valentin wrote:
>> Hi,
>>
>> On Tue, Oct 28, 2014 at 02:11:59PM +0800, Aaron Lu wrote:
>>> Jim found that the current kernel may trigger a build error with some
>>> config: drivers/built-in.o: In function `int3406_thermal_probe':
>>> int3406_thermal.c:(.text+0x1d10b8): undefined reference to
>>> `acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
>>> CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
>>> int3406 thermal driver and add dependency on ACPI video for it.
>>>
>>> Reported-by: Jim Davis <[email protected]>
>>> Signed-off-by: Aaron Lu <[email protected]>
>>
> Aaron, this is an incremental patch on top of the INT3406 driver patch.
> As, both patches have not been shipped in Linus' tree, please merge
> these two patches altogether and resend.

OK, here it is:

>From 02d7abdcfe138e6cdee7572b10addce4f56d89eb Mon Sep 17 00:00:00 2001
From: Aaron Lu <[email protected]>
Date: Wed, 3 Sep 2014 15:15:02 +0800
Subject: [PATCH] Thermal: introduce INT3406 thermal driver

INT3406 ACPI device object resembles an ACPI video output device, but its
_BCM is said to be deprecated and should not be used. So we will make
use of the raw interface to do the actual cooling. Due to this, the
backlight core has some modifications. Also, to re-use some of the ACPI
video module's code, one function has been exported.

Signed-off-by: Aaron Lu <[email protected]>
Signed-off-by: Zhang Rui <[email protected]>
---
drivers/acpi/video.c | 78 ++++----
drivers/thermal/Kconfig | 26 +--
drivers/thermal/int340x_thermal/Makefile | 1 +
drivers/thermal/int340x_thermal/int3406_thermal.c | 230 ++++++++++++++++++++++
drivers/video/backlight/backlight.c | 44 +++--
include/acpi/video.h | 20 ++
include/linux/backlight.h | 2 +
7 files changed, 326 insertions(+), 75 deletions(-)
create mode 100644 drivers/thermal/int340x_thermal/int3406_thermal.c

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 826884392e6b..b2604322dd1f 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -186,19 +186,6 @@ struct acpi_video_device_cap {
u8 _DDC:1; /* Return the EDID for this device */
};

-struct acpi_video_brightness_flags {
- u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
- u8 _BCL_reversed:1; /* _BCL package is in a reversed order */
- u8 _BQC_use_index:1; /* _BQC returns an index value */
-};
-
-struct acpi_video_device_brightness {
- int curr;
- int count;
- int *levels;
- struct acpi_video_brightness_flags flags;
-};
-
struct acpi_video_device {
unsigned long device_id;
struct acpi_video_device_flags flags;
@@ -344,7 +331,7 @@ static const struct thermal_cooling_device_ops video_cooling_ops = {
*/

static int
-acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
+acpi_video_device_lcd_query_levels(acpi_handle handle,
union acpi_object **levels)
{
int status;
@@ -354,7 +341,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,

*levels = NULL;

- status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
+ status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer);
if (!ACPI_SUCCESS(status))
return status;
obj = (union acpi_object *)buffer.pointer;
@@ -943,29 +930,18 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
return 0;
}

-
-/*
- * Arg:
- * device : video output device (LCD, CRT, ..)
- *
- * Return Value:
- * Maximum brightness level
- *
- * Allocate and initialize device->brightness.
- */
-
-static int
-acpi_video_init_brightness(struct acpi_video_device *device)
+int acpi_video_get_levels(struct acpi_device *device,
+ struct acpi_video_device_brightness **dev_br)
{
union acpi_object *obj = NULL;
int i, max_level = 0, count = 0, level_ac_battery = 0;
- unsigned long long level, level_old;
union acpi_object *o;
struct acpi_video_device_brightness *br = NULL;
- int result = -EINVAL;
+ int result = 0;
u32 value;

- if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
+ if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device->handle,
+ &obj))) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
"LCD brightness level\n"));
goto out;
@@ -1038,6 +1014,38 @@ acpi_video_init_brightness(struct acpi_video_device *device)
"Found unordered _BCL package"));

br->count = count;
+ *dev_br = br;
+
+out:
+ kfree(obj);
+ return result;
+out_free:
+ kfree(br);
+ goto out;
+}
+EXPORT_SYMBOL(acpi_video_get_levels);
+
+/*
+ * Arg:
+ * device : video output device (LCD, CRT, ..)
+ *
+ * Return Value:
+ * Maximum brightness level
+ *
+ * Allocate and initialize device->brightness.
+ */
+
+static int
+acpi_video_init_brightness(struct acpi_video_device *device)
+{
+ int i, max_level = 0;
+ unsigned long long level, level_old;
+ struct acpi_video_device_brightness *br = NULL;
+ int result = -EINVAL;
+
+ result = acpi_video_get_levels(device->dev, &br);
+ if (result)
+ return result;
device->brightness = br;

/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
@@ -1080,17 +1088,13 @@ set_level:
goto out_free_levels;

ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "found %d brightness levels\n", count - 2));
- kfree(obj);
- return result;
+ "found %d brightness levels\n", br->count - 2));
+ return 0;

out_free_levels:
kfree(br->levels);
-out_free:
kfree(br);
-out:
device->brightness = NULL;
- kfree(obj);
return result;
}

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9b012ff65220..4565e55dbef9 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -229,29 +229,9 @@ config INTEL_SOC_DTS_THERMAL
notification methods.The other trip is a critical trip point, which
was set by the driver based on the TJ MAX temperature.

-config INT340X_THERMAL
- tristate "ACPI INT340X thermal drivers"
- depends on X86 && ACPI
- select THERMAL_GOV_USER_SPACE
- select ACPI_THERMAL_REL
- select ACPI_FAN
- help
- Newer laptops and tablets that use ACPI may have thermal sensors and
- other devices with thermal control capabilities outside the core
- CPU/SOC, for thermal safety reasons.
- They are exposed for the OS to use via the INT3400 ACPI device object
- as the master, and INT3401~INT340B ACPI device objects as the slaves.
- Enable this to expose the temperature information and cooling ability
- from these objects to userspace via the normal thermal framework.
- This means that a wide range of applications and GUI widgets can show
- the information to the user or use this information for making
- decisions. For example, the Intel Thermal Daemon can use this
- information to allow the user to select his laptop to run without
- turning on the fans.
-
-config ACPI_THERMAL_REL
- tristate
- depends on ACPI
+menu "ACPI INT340X thermal drivers"
+source drivers/thermal/int340x_thermal/Kconfig
+endmenu

menu "Texas Instruments thermal drivers"
source "drivers/thermal/ti-soc-thermal/Kconfig"
diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
index ffe40bffaf1a..a9d0429be412 100644
--- a/drivers/thermal/int340x_thermal/Makefile
+++ b/drivers/thermal/int340x_thermal/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
+obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c
new file mode 100644
index 000000000000..162ddee4f937
--- /dev/null
+++ b/drivers/thermal/int340x_thermal/int3406_thermal.c
@@ -0,0 +1,230 @@
+/*
+ * INT3406 thermal driver for display participant device
+ *
+ * Copyright (C) 2014, Intel Corporation
+ * Authors: Aaron Lu <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/backlight.h>
+#include <linux/thermal.h>
+#include <acpi/video.h>
+
+#define INT3406_BRIGHTNESS_LIMITS_CHANGED 0x80
+
+struct int3406_thermal_data {
+ int upper_limit;
+ int upper_limit_index;
+ int lower_limit;
+ int lower_limit_index;
+ acpi_handle handle;
+ struct acpi_video_device_brightness *br;
+ struct backlight_device *raw_bd;
+ struct thermal_cooling_device *cooling_dev;
+};
+
+static int int3406_thermal_to_raw(int level, struct int3406_thermal_data *d)
+{
+ int max_level = d->br->levels[d->br->count - 1];
+ int raw_max = d->raw_bd->props.max_brightness;
+
+ return level * raw_max / max_level;
+}
+
+static int int3406_thermal_to_acpi(int level, struct int3406_thermal_data *d)
+{
+ int raw_max = d->raw_bd->props.max_brightness;
+ int max_level = d->br->levels[d->br->count - 1];
+
+ return level * max_level / raw_max;
+}
+
+static int
+int3406_thermal_get_max_state(struct thermal_cooling_device *cooling_dev,
+ unsigned long *state)
+{
+ struct int3406_thermal_data *d = cooling_dev->devdata;
+ int index = d->lower_limit_index ? d->lower_limit_index : 2;
+
+ *state = d->br->count - 1 - index;
+ return 0;
+}
+
+static int
+int3406_thermal_set_cur_state(struct thermal_cooling_device *cooling_dev,
+ unsigned long state)
+{
+ struct int3406_thermal_data *d = cooling_dev->devdata;
+ int level, raw_level;
+
+ if (state > d->br->count - 3)
+ return -EINVAL;
+
+ state = d->br->count - 1 - state;
+ level = d->br->levels[state];
+
+ if ((d->upper_limit && level > d->upper_limit) ||
+ (d->lower_limit && level < d->lower_limit))
+ return -EINVAL;
+
+ raw_level = int3406_thermal_to_raw(level, d);
+ return backlight_device_set_brightness(d->raw_bd, raw_level);
+}
+
+static int
+int3406_thermal_get_cur_state(struct thermal_cooling_device *cooling_dev,
+ unsigned long *state)
+{
+ struct int3406_thermal_data *d = cooling_dev->devdata;
+ int raw_level, level, i;
+
+ raw_level = d->raw_bd->props.brightness;
+ level = int3406_thermal_to_acpi(raw_level, d);
+
+ /*
+ * There is no 1:1 mapping between the firmware interface level with the
+ * raw interface level, we will have to find one that is close enough.
+ */
+ for (i = 2; i < d->br->count - 1; i++) {
+ if (level >= d->br->levels[i] && level <= d->br->levels[i + 1])
+ break;
+ }
+
+ *state = i;
+ return 0;
+}
+
+static const struct thermal_cooling_device_ops video_cooling_ops = {
+ .get_max_state = int3406_thermal_get_max_state,
+ .get_cur_state = int3406_thermal_get_cur_state,
+ .set_cur_state = int3406_thermal_set_cur_state,
+};
+
+static int int3406_thermal_get_index(int *array, int nr, int value)
+{
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ if (array[i] == value)
+ break;
+ }
+ return i == nr ? -ENOENT : i;
+}
+
+static void int3406_thermal_get_limit(struct int3406_thermal_data *d)
+{
+ acpi_status status;
+ unsigned long long lower_limit, upper_limit;
+ int index;
+
+ status = acpi_evaluate_integer(d->handle, "DDDL", NULL, &lower_limit);
+ if (ACPI_SUCCESS(status)) {
+ index = int3406_thermal_get_index(d->br->levels, d->br->count,
+ lower_limit);
+ if (index > 0) {
+ d->lower_limit = (int)lower_limit;
+ d->lower_limit_index = index;
+ }
+ }
+
+ status = acpi_evaluate_integer(d->handle, "DDPC", NULL, &upper_limit);
+ if (ACPI_SUCCESS(status)) {
+ index = int3406_thermal_get_index(d->br->levels, d->br->count,
+ upper_limit);
+ if (index > 0) {
+ d->upper_limit = (int)upper_limit;
+ d->upper_limit_index = index;
+ }
+ }
+}
+
+static void int3406_notify(acpi_handle handle, u32 event, void *data)
+{
+ if (event == INT3406_BRIGHTNESS_LIMITS_CHANGED)
+ int3406_thermal_get_limit(data);
+}
+
+static int int3406_thermal_probe(struct platform_device *pdev)
+{
+ struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+ struct int3406_thermal_data *d;
+ struct backlight_device *bd;
+ int ret;
+
+ if (!ACPI_HANDLE(&pdev->dev))
+ return -ENODEV;
+
+ d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL);
+ if (!d)
+ return -ENOMEM;
+ d->handle = ACPI_HANDLE(&pdev->dev);
+
+ bd = backlight_device_get_by_type(BACKLIGHT_RAW);
+ if (!bd)
+ return -ENODEV;
+ d->raw_bd = bd;
+
+ ret = acpi_video_get_levels(ACPI_COMPANION(&pdev->dev), &d->br);
+ if (ret)
+ return ret;
+
+ int3406_thermal_get_limit(d);
+
+ d->cooling_dev = thermal_cooling_device_register(acpi_device_bid(adev),
+ d, &video_cooling_ops);
+ if (IS_ERR(d->cooling_dev))
+ goto err;
+
+ ret = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
+ int3406_notify, d);
+ if (ret)
+ goto err_cdev;
+
+ platform_set_drvdata(pdev, d);
+
+ return 0;
+
+err_cdev:
+ thermal_cooling_device_unregister(d->cooling_dev);
+err:
+ kfree(d->br);
+ return -ENODEV;
+}
+
+static int int3406_thermal_remove(struct platform_device *pdev)
+{
+ struct int3406_thermal_data *d = platform_get_drvdata(pdev);
+
+ thermal_cooling_device_unregister(platform_get_drvdata(pdev));
+ kfree(d->br);
+ return 0;
+}
+
+static const struct acpi_device_id int3406_thermal_match[] = {
+ {"INT3406", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(acpi, int3406_thermal_match);
+
+static struct platform_driver int3406_thermal_driver = {
+ .probe = int3406_thermal_probe,
+ .remove = int3406_thermal_remove,
+ .driver = {
+ .name = "int3406 thermal",
+ .owner = THIS_MODULE,
+ .acpi_match_table = int3406_thermal_match,
+ },
+};
+
+module_platform_driver(int3406_thermal_driver);
+
+MODULE_DESCRIPTION("INT3406 Thermal driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index bddc8b17a4d8..bea749329236 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -164,28 +164,19 @@ static ssize_t brightness_show(struct device *dev,
return sprintf(buf, "%d\n", bd->props.brightness);
}

-static ssize_t brightness_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+int backlight_device_set_brightness(struct backlight_device *bd, int brightness)
{
- int rc;
- struct backlight_device *bd = to_backlight_device(dev);
- unsigned long brightness;
-
- rc = kstrtoul(buf, 0, &brightness);
- if (rc)
- return rc;
-
- rc = -ENXIO;
+ int rc = -ENXIO;

mutex_lock(&bd->ops_lock);
if (bd->ops) {
if (brightness > bd->props.max_brightness)
rc = -EINVAL;
else {
- pr_debug("set brightness to %lu\n", brightness);
+ pr_debug("set brightness to %u\n", brightness);
bd->props.brightness = brightness;
backlight_update_status(bd);
- rc = count;
+ rc = 0;
}
}
mutex_unlock(&bd->ops_lock);
@@ -194,6 +185,23 @@ static ssize_t brightness_store(struct device *dev,

return rc;
}
+EXPORT_SYMBOL(backlight_device_set_brightness);
+
+static ssize_t brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int rc;
+ struct backlight_device *bd = to_backlight_device(dev);
+ unsigned long brightness;
+
+ rc = kstrtoul(buf, 0, &brightness);
+ if (rc)
+ return rc;
+
+ rc = backlight_device_set_brightness(bd, brightness);
+
+ return rc ? rc : count;
+}
static DEVICE_ATTR_RW(brightness);

static ssize_t type_show(struct device *dev, struct device_attribute *attr,
@@ -380,7 +388,7 @@ struct backlight_device *backlight_device_register(const char *name,
}
EXPORT_SYMBOL(backlight_device_register);

-bool backlight_device_registered(enum backlight_type type)
+struct backlight_device *backlight_device_get_by_type(enum backlight_type type)
{
bool found = false;
struct backlight_device *bd;
@@ -394,7 +402,13 @@ bool backlight_device_registered(enum backlight_type type)
}
mutex_unlock(&backlight_dev_list_mutex);

- return found;
+ return found ? bd : NULL;
+}
+EXPORT_SYMBOL(backlight_device_get_by_type);
+
+bool backlight_device_registered(enum backlight_type type)
+{
+ return backlight_device_get_by_type(type) ? true : false;
}
EXPORT_SYMBOL(backlight_device_registered);

diff --git a/include/acpi/video.h b/include/acpi/video.h
index 843ef1adfbfa..956300d2f214 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -3,6 +3,19 @@

#include <linux/errno.h> /* for ENODEV */

+struct acpi_video_brightness_flags {
+ u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
+ u8 _BCL_reversed:1; /* _BCL package is in a reversed order */
+ u8 _BQC_use_index:1; /* _BQC returns an index value */
+};
+
+struct acpi_video_device_brightness {
+ int curr;
+ int count;
+ int *levels;
+ struct acpi_video_brightness_flags flags;
+};
+
struct acpi_device;

#define ACPI_VIDEO_CLASS "video"
@@ -22,6 +35,8 @@ extern void acpi_video_unregister(void);
extern void acpi_video_unregister_backlight(void);
extern int acpi_video_get_edid(struct acpi_device *device, int type,
int device_id, void **edid);
+extern int acpi_video_get_levels(struct acpi_device *device,
+ struct acpi_video_device_brightness **dev_br);
extern bool acpi_video_verify_backlight_support(void);
#else
static inline int acpi_video_register(void) { return 0; }
@@ -32,6 +47,11 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
{
return -ENODEV;
}
+static int acpi_video_get_levels(struct acpi_device *device,
+ struct acpi_video_device_brightness **dev_br)
+{
+ return -ENODEV;
+}
static inline bool acpi_video_verify_backlight_support(void) { return false; }
#endif

diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index adb14a8616df..c59a020df3f8 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -140,6 +140,8 @@ extern void backlight_force_update(struct backlight_device *bd,
extern bool backlight_device_registered(enum backlight_type type);
extern int backlight_register_notifier(struct notifier_block *nb);
extern int backlight_unregister_notifier(struct notifier_block *nb);
+extern struct backlight_device *backlight_device_get_by_type(enum backlight_type type);
+extern int backlight_device_set_brightness(struct backlight_device *bd, int brightness);

#define to_backlight_device(obj) container_of(obj, struct backlight_device, dev)

--
1.9.3

2014-12-08 03:35:17

by Zhang, Rui

[permalink] [raw]
Subject: Re: [PATCH] Thermal: introduce INT3406 thermal driver

On Tue, 2014-12-02 at 14:18 +0800, Aaron Lu wrote:
> On 11/30/2014 08:22 PM, Zhang Rui wrote:
> > On Fri, 2014-11-07 at 15:11 -0400, Eduardo Valentin wrote:
> >> Hi,
> >>
> >> On Tue, Oct 28, 2014 at 02:11:59PM +0800, Aaron Lu wrote:
> >>> Jim found that the current kernel may trigger a build error with some
> >>> config: drivers/built-in.o: In function `int3406_thermal_probe':
> >>> int3406_thermal.c:(.text+0x1d10b8): undefined reference to
> >>> `acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
> >>> CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
> >>> int3406 thermal driver and add dependency on ACPI video for it.
> >>>
> >>> Reported-by: Jim Davis <[email protected]>
> >>> Signed-off-by: Aaron Lu <[email protected]>
> >>
> > Aaron, this is an incremental patch on top of the INT3406 driver patch.
> > As, both patches have not been shipped in Linus' tree, please merge
> > these two patches altogether and resend.
>
> OK, here it is:
>
> From 02d7abdcfe138e6cdee7572b10addce4f56d89eb Mon Sep 17 00:00:00 2001
> From: Aaron Lu <[email protected]>
> Date: Wed, 3 Sep 2014 15:15:02 +0800
> Subject: [PATCH] Thermal: introduce INT3406 thermal driver
>
> INT3406 ACPI device object resembles an ACPI video output device, but its
> _BCM is said to be deprecated and should not be used. So we will make
> use of the raw interface to do the actual cooling. Due to this, the
> backlight core has some modifications. Also, to re-use some of the ACPI
> video module's code, one function has been exported.
>
> Signed-off-by: Aaron Lu <[email protected]>
> Signed-off-by: Zhang Rui <[email protected]>

applied.

thanks,
rui
> ---
> drivers/acpi/video.c | 78 ++++----
> drivers/thermal/Kconfig | 26 +--
> drivers/thermal/int340x_thermal/Makefile | 1 +
> drivers/thermal/int340x_thermal/int3406_thermal.c | 230 ++++++++++++++++++++++
> drivers/video/backlight/backlight.c | 44 +++--
> include/acpi/video.h | 20 ++
> include/linux/backlight.h | 2 +
> 7 files changed, 326 insertions(+), 75 deletions(-)
> create mode 100644 drivers/thermal/int340x_thermal/int3406_thermal.c
>
> diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
> index 826884392e6b..b2604322dd1f 100644
> --- a/drivers/acpi/video.c
> +++ b/drivers/acpi/video.c
> @@ -186,19 +186,6 @@ struct acpi_video_device_cap {
> u8 _DDC:1; /* Return the EDID for this device */
> };
>
> -struct acpi_video_brightness_flags {
> - u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
> - u8 _BCL_reversed:1; /* _BCL package is in a reversed order */
> - u8 _BQC_use_index:1; /* _BQC returns an index value */
> -};
> -
> -struct acpi_video_device_brightness {
> - int curr;
> - int count;
> - int *levels;
> - struct acpi_video_brightness_flags flags;
> -};
> -
> struct acpi_video_device {
> unsigned long device_id;
> struct acpi_video_device_flags flags;
> @@ -344,7 +331,7 @@ static const struct thermal_cooling_device_ops video_cooling_ops = {
> */
>
> static int
> -acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
> +acpi_video_device_lcd_query_levels(acpi_handle handle,
> union acpi_object **levels)
> {
> int status;
> @@ -354,7 +341,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
>
> *levels = NULL;
>
> - status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
> + status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer);
> if (!ACPI_SUCCESS(status))
> return status;
> obj = (union acpi_object *)buffer.pointer;
> @@ -943,29 +930,18 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
> return 0;
> }
>
> -
> -/*
> - * Arg:
> - * device : video output device (LCD, CRT, ..)
> - *
> - * Return Value:
> - * Maximum brightness level
> - *
> - * Allocate and initialize device->brightness.
> - */
> -
> -static int
> -acpi_video_init_brightness(struct acpi_video_device *device)
> +int acpi_video_get_levels(struct acpi_device *device,
> + struct acpi_video_device_brightness **dev_br)
> {
> union acpi_object *obj = NULL;
> int i, max_level = 0, count = 0, level_ac_battery = 0;
> - unsigned long long level, level_old;
> union acpi_object *o;
> struct acpi_video_device_brightness *br = NULL;
> - int result = -EINVAL;
> + int result = 0;
> u32 value;
>
> - if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
> + if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device->handle,
> + &obj))) {
> ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
> "LCD brightness level\n"));
> goto out;
> @@ -1038,6 +1014,38 @@ acpi_video_init_brightness(struct acpi_video_device *device)
> "Found unordered _BCL package"));
>
> br->count = count;
> + *dev_br = br;
> +
> +out:
> + kfree(obj);
> + return result;
> +out_free:
> + kfree(br);
> + goto out;
> +}
> +EXPORT_SYMBOL(acpi_video_get_levels);
> +
> +/*
> + * Arg:
> + * device : video output device (LCD, CRT, ..)
> + *
> + * Return Value:
> + * Maximum brightness level
> + *
> + * Allocate and initialize device->brightness.
> + */
> +
> +static int
> +acpi_video_init_brightness(struct acpi_video_device *device)
> +{
> + int i, max_level = 0;
> + unsigned long long level, level_old;
> + struct acpi_video_device_brightness *br = NULL;
> + int result = -EINVAL;
> +
> + result = acpi_video_get_levels(device->dev, &br);
> + if (result)
> + return result;
> device->brightness = br;
>
> /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
> @@ -1080,17 +1088,13 @@ set_level:
> goto out_free_levels;
>
> ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> - "found %d brightness levels\n", count - 2));
> - kfree(obj);
> - return result;
> + "found %d brightness levels\n", br->count - 2));
> + return 0;
>
> out_free_levels:
> kfree(br->levels);
> -out_free:
> kfree(br);
> -out:
> device->brightness = NULL;
> - kfree(obj);
> return result;
> }
>
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 9b012ff65220..4565e55dbef9 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -229,29 +229,9 @@ config INTEL_SOC_DTS_THERMAL
> notification methods.The other trip is a critical trip point, which
> was set by the driver based on the TJ MAX temperature.
>
> -config INT340X_THERMAL
> - tristate "ACPI INT340X thermal drivers"
> - depends on X86 && ACPI
> - select THERMAL_GOV_USER_SPACE
> - select ACPI_THERMAL_REL
> - select ACPI_FAN
> - help
> - Newer laptops and tablets that use ACPI may have thermal sensors and
> - other devices with thermal control capabilities outside the core
> - CPU/SOC, for thermal safety reasons.
> - They are exposed for the OS to use via the INT3400 ACPI device object
> - as the master, and INT3401~INT340B ACPI device objects as the slaves.
> - Enable this to expose the temperature information and cooling ability
> - from these objects to userspace via the normal thermal framework.
> - This means that a wide range of applications and GUI widgets can show
> - the information to the user or use this information for making
> - decisions. For example, the Intel Thermal Daemon can use this
> - information to allow the user to select his laptop to run without
> - turning on the fans.
> -
> -config ACPI_THERMAL_REL
> - tristate
> - depends on ACPI
> +menu "ACPI INT340X thermal drivers"
> +source drivers/thermal/int340x_thermal/Kconfig
> +endmenu
>
> menu "Texas Instruments thermal drivers"
> source "drivers/thermal/ti-soc-thermal/Kconfig"
> diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
> index ffe40bffaf1a..a9d0429be412 100644
> --- a/drivers/thermal/int340x_thermal/Makefile
> +++ b/drivers/thermal/int340x_thermal/Makefile
> @@ -1,4 +1,5 @@
> obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
> obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
> obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
> +obj-$(CONFIG_INT3406_THERMAL) += int3406_thermal.o
> obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o
> diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c
> new file mode 100644
> index 000000000000..162ddee4f937
> --- /dev/null
> +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c
> @@ -0,0 +1,230 @@
> +/*
> + * INT3406 thermal driver for display participant device
> + *
> + * Copyright (C) 2014, Intel Corporation
> + * Authors: Aaron Lu <[email protected]>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/acpi.h>
> +#include <linux/backlight.h>
> +#include <linux/thermal.h>
> +#include <acpi/video.h>
> +
> +#define INT3406_BRIGHTNESS_LIMITS_CHANGED 0x80
> +
> +struct int3406_thermal_data {
> + int upper_limit;
> + int upper_limit_index;
> + int lower_limit;
> + int lower_limit_index;
> + acpi_handle handle;
> + struct acpi_video_device_brightness *br;
> + struct backlight_device *raw_bd;
> + struct thermal_cooling_device *cooling_dev;
> +};
> +
> +static int int3406_thermal_to_raw(int level, struct int3406_thermal_data *d)
> +{
> + int max_level = d->br->levels[d->br->count - 1];
> + int raw_max = d->raw_bd->props.max_brightness;
> +
> + return level * raw_max / max_level;
> +}
> +
> +static int int3406_thermal_to_acpi(int level, struct int3406_thermal_data *d)
> +{
> + int raw_max = d->raw_bd->props.max_brightness;
> + int max_level = d->br->levels[d->br->count - 1];
> +
> + return level * max_level / raw_max;
> +}
> +
> +static int
> +int3406_thermal_get_max_state(struct thermal_cooling_device *cooling_dev,
> + unsigned long *state)
> +{
> + struct int3406_thermal_data *d = cooling_dev->devdata;
> + int index = d->lower_limit_index ? d->lower_limit_index : 2;
> +
> + *state = d->br->count - 1 - index;
> + return 0;
> +}
> +
> +static int
> +int3406_thermal_set_cur_state(struct thermal_cooling_device *cooling_dev,
> + unsigned long state)
> +{
> + struct int3406_thermal_data *d = cooling_dev->devdata;
> + int level, raw_level;
> +
> + if (state > d->br->count - 3)
> + return -EINVAL;
> +
> + state = d->br->count - 1 - state;
> + level = d->br->levels[state];
> +
> + if ((d->upper_limit && level > d->upper_limit) ||
> + (d->lower_limit && level < d->lower_limit))
> + return -EINVAL;
> +
> + raw_level = int3406_thermal_to_raw(level, d);
> + return backlight_device_set_brightness(d->raw_bd, raw_level);
> +}
> +
> +static int
> +int3406_thermal_get_cur_state(struct thermal_cooling_device *cooling_dev,
> + unsigned long *state)
> +{
> + struct int3406_thermal_data *d = cooling_dev->devdata;
> + int raw_level, level, i;
> +
> + raw_level = d->raw_bd->props.brightness;
> + level = int3406_thermal_to_acpi(raw_level, d);
> +
> + /*
> + * There is no 1:1 mapping between the firmware interface level with the
> + * raw interface level, we will have to find one that is close enough.
> + */
> + for (i = 2; i < d->br->count - 1; i++) {
> + if (level >= d->br->levels[i] && level <= d->br->levels[i + 1])
> + break;
> + }
> +
> + *state = i;
> + return 0;
> +}
> +
> +static const struct thermal_cooling_device_ops video_cooling_ops = {
> + .get_max_state = int3406_thermal_get_max_state,
> + .get_cur_state = int3406_thermal_get_cur_state,
> + .set_cur_state = int3406_thermal_set_cur_state,
> +};
> +
> +static int int3406_thermal_get_index(int *array, int nr, int value)
> +{
> + int i;
> +
> + for (i = 0; i < nr; i++) {
> + if (array[i] == value)
> + break;
> + }
> + return i == nr ? -ENOENT : i;
> +}
> +
> +static void int3406_thermal_get_limit(struct int3406_thermal_data *d)
> +{
> + acpi_status status;
> + unsigned long long lower_limit, upper_limit;
> + int index;
> +
> + status = acpi_evaluate_integer(d->handle, "DDDL", NULL, &lower_limit);
> + if (ACPI_SUCCESS(status)) {
> + index = int3406_thermal_get_index(d->br->levels, d->br->count,
> + lower_limit);
> + if (index > 0) {
> + d->lower_limit = (int)lower_limit;
> + d->lower_limit_index = index;
> + }
> + }
> +
> + status = acpi_evaluate_integer(d->handle, "DDPC", NULL, &upper_limit);
> + if (ACPI_SUCCESS(status)) {
> + index = int3406_thermal_get_index(d->br->levels, d->br->count,
> + upper_limit);
> + if (index > 0) {
> + d->upper_limit = (int)upper_limit;
> + d->upper_limit_index = index;
> + }
> + }
> +}
> +
> +static void int3406_notify(acpi_handle handle, u32 event, void *data)
> +{
> + if (event == INT3406_BRIGHTNESS_LIMITS_CHANGED)
> + int3406_thermal_get_limit(data);
> +}
> +
> +static int int3406_thermal_probe(struct platform_device *pdev)
> +{
> + struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
> + struct int3406_thermal_data *d;
> + struct backlight_device *bd;
> + int ret;
> +
> + if (!ACPI_HANDLE(&pdev->dev))
> + return -ENODEV;
> +
> + d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL);
> + if (!d)
> + return -ENOMEM;
> + d->handle = ACPI_HANDLE(&pdev->dev);
> +
> + bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> + if (!bd)
> + return -ENODEV;
> + d->raw_bd = bd;
> +
> + ret = acpi_video_get_levels(ACPI_COMPANION(&pdev->dev), &d->br);
> + if (ret)
> + return ret;
> +
> + int3406_thermal_get_limit(d);
> +
> + d->cooling_dev = thermal_cooling_device_register(acpi_device_bid(adev),
> + d, &video_cooling_ops);
> + if (IS_ERR(d->cooling_dev))
> + goto err;
> +
> + ret = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
> + int3406_notify, d);
> + if (ret)
> + goto err_cdev;
> +
> + platform_set_drvdata(pdev, d);
> +
> + return 0;
> +
> +err_cdev:
> + thermal_cooling_device_unregister(d->cooling_dev);
> +err:
> + kfree(d->br);
> + return -ENODEV;
> +}
> +
> +static int int3406_thermal_remove(struct platform_device *pdev)
> +{
> + struct int3406_thermal_data *d = platform_get_drvdata(pdev);
> +
> + thermal_cooling_device_unregister(platform_get_drvdata(pdev));
> + kfree(d->br);
> + return 0;
> +}
> +
> +static const struct acpi_device_id int3406_thermal_match[] = {
> + {"INT3406", 0},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(acpi, int3406_thermal_match);
> +
> +static struct platform_driver int3406_thermal_driver = {
> + .probe = int3406_thermal_probe,
> + .remove = int3406_thermal_remove,
> + .driver = {
> + .name = "int3406 thermal",
> + .owner = THIS_MODULE,
> + .acpi_match_table = int3406_thermal_match,
> + },
> +};
> +
> +module_platform_driver(int3406_thermal_driver);
> +
> +MODULE_DESCRIPTION("INT3406 Thermal driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
> index bddc8b17a4d8..bea749329236 100644
> --- a/drivers/video/backlight/backlight.c
> +++ b/drivers/video/backlight/backlight.c
> @@ -164,28 +164,19 @@ static ssize_t brightness_show(struct device *dev,
> return sprintf(buf, "%d\n", bd->props.brightness);
> }
>
> -static ssize_t brightness_store(struct device *dev,
> - struct device_attribute *attr, const char *buf, size_t count)
> +int backlight_device_set_brightness(struct backlight_device *bd, int brightness)
> {
> - int rc;
> - struct backlight_device *bd = to_backlight_device(dev);
> - unsigned long brightness;
> -
> - rc = kstrtoul(buf, 0, &brightness);
> - if (rc)
> - return rc;
> -
> - rc = -ENXIO;
> + int rc = -ENXIO;
>
> mutex_lock(&bd->ops_lock);
> if (bd->ops) {
> if (brightness > bd->props.max_brightness)
> rc = -EINVAL;
> else {
> - pr_debug("set brightness to %lu\n", brightness);
> + pr_debug("set brightness to %u\n", brightness);
> bd->props.brightness = brightness;
> backlight_update_status(bd);
> - rc = count;
> + rc = 0;
> }
> }
> mutex_unlock(&bd->ops_lock);
> @@ -194,6 +185,23 @@ static ssize_t brightness_store(struct device *dev,
>
> return rc;
> }
> +EXPORT_SYMBOL(backlight_device_set_brightness);
> +
> +static ssize_t brightness_store(struct device *dev,
> + struct device_attribute *attr, const char *buf, size_t count)
> +{
> + int rc;
> + struct backlight_device *bd = to_backlight_device(dev);
> + unsigned long brightness;
> +
> + rc = kstrtoul(buf, 0, &brightness);
> + if (rc)
> + return rc;
> +
> + rc = backlight_device_set_brightness(bd, brightness);
> +
> + return rc ? rc : count;
> +}
> static DEVICE_ATTR_RW(brightness);
>
> static ssize_t type_show(struct device *dev, struct device_attribute *attr,
> @@ -380,7 +388,7 @@ struct backlight_device *backlight_device_register(const char *name,
> }
> EXPORT_SYMBOL(backlight_device_register);
>
> -bool backlight_device_registered(enum backlight_type type)
> +struct backlight_device *backlight_device_get_by_type(enum backlight_type type)
> {
> bool found = false;
> struct backlight_device *bd;
> @@ -394,7 +402,13 @@ bool backlight_device_registered(enum backlight_type type)
> }
> mutex_unlock(&backlight_dev_list_mutex);
>
> - return found;
> + return found ? bd : NULL;
> +}
> +EXPORT_SYMBOL(backlight_device_get_by_type);
> +
> +bool backlight_device_registered(enum backlight_type type)
> +{
> + return backlight_device_get_by_type(type) ? true : false;
> }
> EXPORT_SYMBOL(backlight_device_registered);
>
> diff --git a/include/acpi/video.h b/include/acpi/video.h
> index 843ef1adfbfa..956300d2f214 100644
> --- a/include/acpi/video.h
> +++ b/include/acpi/video.h
> @@ -3,6 +3,19 @@
>
> #include <linux/errno.h> /* for ENODEV */
>
> +struct acpi_video_brightness_flags {
> + u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
> + u8 _BCL_reversed:1; /* _BCL package is in a reversed order */
> + u8 _BQC_use_index:1; /* _BQC returns an index value */
> +};
> +
> +struct acpi_video_device_brightness {
> + int curr;
> + int count;
> + int *levels;
> + struct acpi_video_brightness_flags flags;
> +};
> +
> struct acpi_device;
>
> #define ACPI_VIDEO_CLASS "video"
> @@ -22,6 +35,8 @@ extern void acpi_video_unregister(void);
> extern void acpi_video_unregister_backlight(void);
> extern int acpi_video_get_edid(struct acpi_device *device, int type,
> int device_id, void **edid);
> +extern int acpi_video_get_levels(struct acpi_device *device,
> + struct acpi_video_device_brightness **dev_br);
> extern bool acpi_video_verify_backlight_support(void);
> #else
> static inline int acpi_video_register(void) { return 0; }
> @@ -32,6 +47,11 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
> {
> return -ENODEV;
> }
> +static int acpi_video_get_levels(struct acpi_device *device,
> + struct acpi_video_device_brightness **dev_br)
> +{
> + return -ENODEV;
> +}
> static inline bool acpi_video_verify_backlight_support(void) { return false; }
> #endif
>
> diff --git a/include/linux/backlight.h b/include/linux/backlight.h
> index adb14a8616df..c59a020df3f8 100644
> --- a/include/linux/backlight.h
> +++ b/include/linux/backlight.h
> @@ -140,6 +140,8 @@ extern void backlight_force_update(struct backlight_device *bd,
> extern bool backlight_device_registered(enum backlight_type type);
> extern int backlight_register_notifier(struct notifier_block *nb);
> extern int backlight_unregister_notifier(struct notifier_block *nb);
> +extern struct backlight_device *backlight_device_get_by_type(enum backlight_type type);
> +extern int backlight_device_set_brightness(struct backlight_device *bd, int brightness);
>
> #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev)
>

2014-12-08 10:55:54

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH] Thermal: introduce INT3406 thermal driver

On Mon, Dec 8, 2014 at 4:35 AM, Zhang Rui <[email protected]> wrote:
> On Tue, 2014-12-02 at 14:18 +0800, Aaron Lu wrote:
>> On 11/30/2014 08:22 PM, Zhang Rui wrote:
>> > On Fri, 2014-11-07 at 15:11 -0400, Eduardo Valentin wrote:
>> >> Hi,
>> >>
>> >> On Tue, Oct 28, 2014 at 02:11:59PM +0800, Aaron Lu wrote:
>> >>> Jim found that the current kernel may trigger a build error with some
>> >>> config: drivers/built-in.o: In function `int3406_thermal_probe':
>> >>> int3406_thermal.c:(.text+0x1d10b8): undefined reference to
>> >>> `acpi_video_get_levels'. The problem happens when CONFIG_THERMAL=y and
>> >>> CONFIG_ACPI_VIDEO=m. Solve the problem by separating a kernel config for
>> >>> int3406 thermal driver and add dependency on ACPI video for it.
>> >>>
>> >>> Reported-by: Jim Davis <[email protected]>
>> >>> Signed-off-by: Aaron Lu <[email protected]>
>> >>
>> > Aaron, this is an incremental patch on top of the INT3406 driver patch.
>> > As, both patches have not been shipped in Linus' tree, please merge
>> > these two patches altogether and resend.
>>
>> OK, here it is:
>>
>> From 02d7abdcfe138e6cdee7572b10addce4f56d89eb Mon Sep 17 00:00:00 2001
>> From: Aaron Lu <[email protected]>
>> Date: Wed, 3 Sep 2014 15:15:02 +0800
>> Subject: [PATCH] Thermal: introduce INT3406 thermal driver
>>
>> INT3406 ACPI device object resembles an ACPI video output device, but its
>> _BCM is said to be deprecated and should not be used. So we will make
>> use of the raw interface to do the actual cooling. Due to this, the
>> backlight core has some modifications. Also, to re-use some of the ACPI
>> video module's code, one function has been exported.
>>
>> Signed-off-by: Aaron Lu <[email protected]>
>> Signed-off-by: Zhang Rui <[email protected]>
>
> applied.

Unfortunately drivers/thermal/int340x_thermal/Kconfig was missing
from the patch, hence "make oldconfig" now fails miserably with

drivers/thermal/Kconfig:265: can't open file
"drivers/thermal/int340x_thermal/Kconfig"

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2014-12-08 11:20:47

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH] Thermal: introduce INT3406 thermal driver

On Mon, Dec 8, 2014 at 11:55 AM, Geert Uytterhoeven
<[email protected]> wrote:
> Unfortunately drivers/thermal/int340x_thermal/Kconfig was missing
> from the patch, hence "make oldconfig" now fails miserably with
>
> drivers/thermal/Kconfig:265: can't open file
> "drivers/thermal/int340x_thermal/Kconfig"

I've lifted the missing file from "[PATCH v3] Thermal: int3406_thermal:
solve the dependency build error" (https://lkml.org/lkml/2014/10/17/38).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2014-12-08 13:25:22

by Aaron Lu

[permalink] [raw]
Subject: Re: [PATCH] Thermal: introduce INT3406 thermal driver

On 12/08/2014 07:20 PM, Geert Uytterhoeven wrote:
> On Mon, Dec 8, 2014 at 11:55 AM, Geert Uytterhoeven
> <[email protected]> wrote:
>> Unfortunately drivers/thermal/int340x_thermal/Kconfig was missing
>> from the patch, hence "make oldconfig" now fails miserably with
>>
>> drivers/thermal/Kconfig:265: can't open file
>> "drivers/thermal/int340x_thermal/Kconfig"
>
> I've lifted the missing file from "[PATCH v3] Thermal: int3406_thermal:
> solve the dependency build error" (https://lkml.org/lkml/2014/10/17/38).

My bad, and thanks a lot for your kind help!

Regards,
Aaron

>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
>