2014-02-12 20:59:14

by Jan-Simon Möller

[permalink] [raw]
Subject: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

From: Behan Webster <[email protected]>

The only real change is passing in event_mask to the formerly nested functions.
Otherwise it's just moving around function and macro code.

This is the only place in the Linux kernel where nested functions are still in
use. Nested functions aren't part of the C standards, and complicate the
generated code. Although the Linux Kernel has never set out to be entirely C
standard compliant, it is increasingly compliant to the standard which is
supported by other compilers such as Clang. The LLVMLinux project is working on
being able to compile the Linux kernel with Clang. The use of nested functions
blocks this effort.

Signed-off-by: Behan Webster <[email protected]>
Signed-off-by: Jan-Simon Möller <[email protected]>

CC: David Woodhouse <[email protected]>
CC: Matthew Garrett <[email protected]>
CC: [email protected]
CC: [email protected]
CC: [email protected]
---
drivers/platform/x86/thinkpad_acpi.c | 86 +++++++++++++++++++-----------------
1 file changed, 45 insertions(+), 41 deletions(-)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index defb6af..e6e068e 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -2321,53 +2321,55 @@ static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)
}
}

-static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
- struct tp_nvram_state *newn,
- const u32 event_mask)
-{
-
#define TPACPI_COMPARE_KEY(__scancode, __member) \
- do { \
- if ((event_mask & (1 << __scancode)) && \
- oldn->__member != newn->__member) \
- tpacpi_hotkey_send_key(__scancode); \
- } while (0)
+do { \
+ if ((event_mask & (1 << __scancode)) && \
+ oldn->__member != newn->__member) \
+ tpacpi_hotkey_send_key(__scancode); \
+} while (0)

#define TPACPI_MAY_SEND_KEY(__scancode) \
- do { \
- if (event_mask & (1 << __scancode)) \
- tpacpi_hotkey_send_key(__scancode); \
- } while (0)
+do { \
+ if (event_mask & (1 << __scancode)) \
+ tpacpi_hotkey_send_key(__scancode); \
+} while (0)

- void issue_volchange(const unsigned int oldvol,
- const unsigned int newvol)
- {
- unsigned int i = oldvol;
+static void issue_volchange(const unsigned int oldvol,
+ const unsigned int newvol,
+ const u32 event_mask)
+{
+ unsigned int i = oldvol;

- while (i > newvol) {
- TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
- i--;
- }
- while (i < newvol) {
- TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
- i++;
- }
+ while (i > newvol) {
+ TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN);
+ i--;
+ }
+ while (i < newvol) {
+ TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
+ i++;
}
+}

- void issue_brightnesschange(const unsigned int oldbrt,
- const unsigned int newbrt)
- {
- unsigned int i = oldbrt;
+static void issue_brightnesschange(const unsigned int oldbrt,
+ const unsigned int newbrt,
+ const u32 event_mask)
+{
+ unsigned int i = oldbrt;

- while (i > newbrt) {
- TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
- i--;
- }
- while (i < newbrt) {
- TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
- i++;
- }
+ while (i > newbrt) {
+ TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND);
+ i--;
}
+ while (i < newbrt) {
+ TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME);
+ i++;
+ }
+}
+
+static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
+ struct tp_nvram_state *newn,
+ const u32 event_mask)
+{

TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
@@ -2402,7 +2404,8 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
oldn->volume_level != newn->volume_level) {
/* recently muted, or repeated mute keypress, or
* multiple presses ending in mute */
- issue_volchange(oldn->volume_level, newn->volume_level);
+ issue_volchange(oldn->volume_level, newn->volume_level,
+ event_mask);
TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);
}
} else {
@@ -2412,7 +2415,8 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);
}
if (oldn->volume_level != newn->volume_level) {
- issue_volchange(oldn->volume_level, newn->volume_level);
+ issue_volchange(oldn->volume_level, newn->volume_level,
+ event_mask);
} else if (oldn->volume_toggle != newn->volume_toggle) {
/* repeated vol up/down keypress at end of scale ? */
if (newn->volume_level == 0)
@@ -2425,7 +2429,7 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
/* handle brightness */
if (oldn->brightness_level != newn->brightness_level) {
issue_brightnesschange(oldn->brightness_level,
- newn->brightness_level);
+ newn->brightness_level, event_mask);
} else if (oldn->brightness_toggle != newn->brightness_toggle) {
/* repeated key presses that didn't change state */
if (newn->brightness_level == 0)
--
1.8.4.5


2014-02-12 21:12:38

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

On Wed, Feb 12, 2014 at 09:58:46PM +0100, [email protected] wrote:
> being able to compile the Linux kernel with Clang. The use of nested functions
> blocks this effort.

Is there any good way to make gcc warn about the use of nested functions?

2014-02-12 21:20:42

by Behan Webster

[permalink] [raw]
Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

On 02/12/14 13:11, Christoph Hellwig wrote:
> On Wed, Feb 12, 2014 at 09:58:46PM +0100, [email protected] wrote:
>> being able to compile the Linux kernel with Clang. The use of nested functions
>> blocks this effort.
> Is there any good way to make gcc warn about the use of nested functions?
Interesting idea.

'-Wtrampolines'
Warn about trampolines generated for pointers to nested functions.

A trampoline is a small piece of data or code that is created at
run time on the stack when the address of a nested function is
taken, and is used to call the nested function indirectly. For
some targets, it is made up of data only and thus requires no
special treatment. But, for most targets, it is made up of code
and thus requires the stack to be made executable in order for the
program to work properly.


That might work.

Behan

--
Behan Webster
[email protected]

2014-02-12 21:32:27

by Richard Weinberger

[permalink] [raw]
Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

On Wed, Feb 12, 2014 at 10:20 PM, Behan Webster
<[email protected]> wrote:
> On 02/12/14 13:11, Christoph Hellwig wrote:
>>
>> On Wed, Feb 12, 2014 at 09:58:46PM +0100, [email protected] wrote:
>>>
>>> being able to compile the Linux kernel with Clang. The use of nested
>>> functions
>>> blocks this effort.
>>
>> Is there any good way to make gcc warn about the use of nested functions?
>
> Interesting idea.
>
> '-Wtrampolines'
> Warn about trampolines generated for pointers to nested functions.
>
> A trampoline is a small piece of data or code that is created at
> run time on the stack when the address of a nested function is
> taken, and is used to call the nested function indirectly. For
> some targets, it is made up of data only and thus requires no
> special treatment. But, for most targets, it is made up of code
> and thus requires the stack to be made executable in order for the
> program to work properly.
>
>
> That might work.

I gave it a quick try, but gcc (4.7) did not bark.

--
Thanks,
//richard

2014-02-12 21:34:57

by Måns Rullgård

[permalink] [raw]
Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

Behan Webster <[email protected]> writes:

> On 02/12/14 13:11, Christoph Hellwig wrote:
>> On Wed, Feb 12, 2014 at 09:58:46PM +0100, [email protected] wrote:
>>> being able to compile the Linux kernel with Clang. The use of nested functions
>>> blocks this effort.
>> Is there any good way to make gcc warn about the use of nested functions?
> Interesting idea.
>
> '-Wtrampolines'
> Warn about trampolines generated for pointers to nested functions.
>
> A trampoline is a small piece of data or code that is created at
> run time on the stack when the address of a nested function is
> taken, and is used to call the nested function indirectly. For
> some targets, it is made up of data only and thus requires no
> special treatment. But, for most targets, it is made up of code
> and thus requires the stack to be made executable in order for the
> program to work properly.
>
> That might work.

That sounds like it will only warn if a trampoline is needed. A nested
function whose address isn't taken, as is the case here, wouldn't
trigger this warning.

--
M?ns Rullg?rd
[email protected]

2014-02-12 21:54:54

by David Rientjes

[permalink] [raw]
Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

On Wed, 12 Feb 2014, [email protected] wrote:

> From: Behan Webster <[email protected]>
>
> The only real change is passing in event_mask to the formerly nested functions.
> Otherwise it's just moving around function and macro code.
>
> This is the only place in the Linux kernel where nested functions are still in
> use. Nested functions aren't part of the C standards, and complicate the
> generated code. Although the Linux Kernel has never set out to be entirely C
> standard compliant, it is increasingly compliant to the standard which is
> supported by other compilers such as Clang. The LLVMLinux project is working on
> being able to compile the Linux kernel with Clang. The use of nested functions
> blocks this effort.
>

So this patch is only as a courtesy to clang and you're not complaining
about things like __builtin() functions, typeof, or a ? : b conditional
operators because clang happens to support them?

2014-02-12 22:01:32

by Al Viro

[permalink] [raw]
Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

On Wed, Feb 12, 2014 at 01:54:43PM -0800, David Rientjes wrote:

> So this patch is only as a courtesy to clang and you're not complaining
> about things like __builtin() functions, typeof, or a ? : b conditional
> operators because clang happens to support them?

That patch removes a disgusting construct; who cares how they'd discovered
it? Consider it courtesy to reviewers, clang or no clang...

Folks, it's C; no need to bring Pascal misfeatures in, even if gcc happens
to accept them.

Subject: Re: [PATCH] x86, acpi: LLVMLinux: Remove nested functions from Thinkpad ACPI

On Wed, 12 Feb 2014, [email protected] wrote:
> From: Behan Webster <[email protected]>
> The only real change is passing in event_mask to the formerly nested functions.
> Otherwise it's just moving around function and macro code.
>
> This is the only place in the Linux kernel where nested functions are still in
> use. Nested functions aren't part of the C standards, and complicate the
> generated code. Although the Linux Kernel has never set out to be entirely C
> standard compliant, it is increasingly compliant to the standard which is
> supported by other compilers such as Clang. The LLVMLinux project is working on
> being able to compile the Linux kernel with Clang. The use of nested functions
> blocks this effort.
>
> Signed-off-by: Behan Webster <[email protected]>
> Signed-off-by: Jan-Simon M?ller <[email protected]>
>
> CC: David Woodhouse <[email protected]>
> CC: Matthew Garrett <[email protected]>
> CC: [email protected]
> CC: [email protected]
> CC: [email protected]

Acked-by: Henrique de Moraes Holschuh <[email protected]>

--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh