diff options
| author | Matthew Garrett <mjg@redhat.com> | 2010-03-02 09:51:48 -0500 |
|---|---|---|
| committer | Matthew Garrett <mjg@redhat.com> | 2010-03-02 09:51:48 -0500 |
| commit | a58db59a263d4232710af816f3857254b5823633 (patch) | |
| tree | 977120471e3d34412d2c810c48d0fe2b9547ffc7 | |
| parent | 881a6c25a8453388e3190de94a5e105439a9f806 (diff) | |
| parent | 88cc83772a3c7756b9f2b4ba835545ad90a08409 (diff) | |
Merge branch 'for-upstream/platform-x86_tpacpi' of git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6 into x86-platform
| -rw-r--r-- | Documentation/laptops/thinkpad-acpi.txt | 4 | ||||
| -rw-r--r-- | drivers/platform/x86/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 116 |
3 files changed, 91 insertions, 39 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 75afa1229fd7..39c0a09d0105 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
| @@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The following commands are available: | |||
| 650 | echo expand_toggle > /proc/acpi/ibm/video | 650 | echo expand_toggle > /proc/acpi/ibm/video |
| 651 | echo video_switch > /proc/acpi/ibm/video | 651 | echo video_switch > /proc/acpi/ibm/video |
| 652 | 652 | ||
| 653 | NOTE: Access to this feature is restricted to processes owning the | ||
| 654 | CAP_SYS_ADMIN capability for safety reasons, as it can interact badly | ||
| 655 | enough with some versions of X.org to crash it. | ||
| 656 | |||
| 653 | Each video output device can be enabled or disabled individually. | 657 | Each video output device can be enabled or disabled individually. |
| 654 | Reading /proc/acpi/ibm/video shows the status of each device. | 658 | Reading /proc/acpi/ibm/video shows the status of each device. |
| 655 | 659 | ||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index aef4f17cdfd4..92161c7ff4b7 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
| @@ -322,9 +322,15 @@ config THINKPAD_ACPI_VIDEO | |||
| 322 | server running, phase of the moon, and the current mood of | 322 | server running, phase of the moon, and the current mood of |
| 323 | Schroedinger's cat. If you can use X.org's RandR to control | 323 | Schroedinger's cat. If you can use X.org's RandR to control |
| 324 | your ThinkPad's video output ports instead of this feature, | 324 | your ThinkPad's video output ports instead of this feature, |
| 325 | don't think twice: do it and say N here to save some memory. | 325 | don't think twice: do it and say N here to save memory and avoid |
| 326 | bad interactions with X.org. | ||
| 326 | 327 | ||
| 327 | If you are not sure, say Y here. | 328 | NOTE: access to this feature is limited to processes with the |
| 329 | CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms | ||
| 330 | where it interacts badly with X.org. | ||
| 331 | |||
| 332 | If you are not sure, say Y here but do try to check if you could | ||
| 333 | be using X.org RandR instead. | ||
| 328 | 334 | ||
| 329 | config THINKPAD_ACPI_HOTKEY_POLL | 335 | config THINKPAD_ACPI_HOTKEY_POLL |
| 330 | bool "Support NVRAM polling for hot keys" | 336 | bool "Support NVRAM polling for hot keys" |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index eb603f1d55ca..e7b0c3bcef89 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -286,6 +286,7 @@ struct ibm_init_struct { | |||
| 286 | char param[32]; | 286 | char param[32]; |
| 287 | 287 | ||
| 288 | int (*init) (struct ibm_init_struct *); | 288 | int (*init) (struct ibm_init_struct *); |
| 289 | mode_t base_procfs_mode; | ||
| 289 | struct ibm_struct *data; | 290 | struct ibm_struct *data; |
| 290 | }; | 291 | }; |
| 291 | 292 | ||
| @@ -2082,6 +2083,7 @@ static struct attribute_set *hotkey_dev_attributes; | |||
| 2082 | 2083 | ||
| 2083 | static void tpacpi_driver_event(const unsigned int hkey_event); | 2084 | static void tpacpi_driver_event(const unsigned int hkey_event); |
| 2084 | static void hotkey_driver_event(const unsigned int scancode); | 2085 | static void hotkey_driver_event(const unsigned int scancode); |
| 2086 | static void hotkey_poll_setup(const bool may_warn); | ||
| 2085 | 2087 | ||
| 2086 | /* HKEY.MHKG() return bits */ | 2088 | /* HKEY.MHKG() return bits */ |
| 2087 | #define TP_HOTKEY_TABLET_MASK (1 << 3) | 2089 | #define TP_HOTKEY_TABLET_MASK (1 << 3) |
| @@ -2264,6 +2266,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask) | |||
| 2264 | 2266 | ||
| 2265 | rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & | 2267 | rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & |
| 2266 | ~hotkey_source_mask); | 2268 | ~hotkey_source_mask); |
| 2269 | hotkey_poll_setup(true); | ||
| 2270 | |||
| 2267 | mutex_unlock(&hotkey_mutex); | 2271 | mutex_unlock(&hotkey_mutex); |
| 2268 | 2272 | ||
| 2269 | return rc; | 2273 | return rc; |
| @@ -2548,7 +2552,7 @@ static void hotkey_poll_stop_sync(void) | |||
| 2548 | } | 2552 | } |
| 2549 | 2553 | ||
| 2550 | /* call with hotkey_mutex held */ | 2554 | /* call with hotkey_mutex held */ |
| 2551 | static void hotkey_poll_setup(bool may_warn) | 2555 | static void hotkey_poll_setup(const bool may_warn) |
| 2552 | { | 2556 | { |
| 2553 | const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; | 2557 | const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; |
| 2554 | const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; | 2558 | const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; |
| @@ -2579,7 +2583,7 @@ static void hotkey_poll_setup(bool may_warn) | |||
| 2579 | } | 2583 | } |
| 2580 | } | 2584 | } |
| 2581 | 2585 | ||
| 2582 | static void hotkey_poll_setup_safe(bool may_warn) | 2586 | static void hotkey_poll_setup_safe(const bool may_warn) |
| 2583 | { | 2587 | { |
| 2584 | mutex_lock(&hotkey_mutex); | 2588 | mutex_lock(&hotkey_mutex); |
| 2585 | hotkey_poll_setup(may_warn); | 2589 | hotkey_poll_setup(may_warn); |
| @@ -2597,7 +2601,11 @@ static void hotkey_poll_set_freq(unsigned int freq) | |||
| 2597 | 2601 | ||
| 2598 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ | 2602 | #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ |
| 2599 | 2603 | ||
| 2600 | static void hotkey_poll_setup_safe(bool __unused) | 2604 | static void hotkey_poll_setup(const bool __unused) |
| 2605 | { | ||
| 2606 | } | ||
| 2607 | |||
| 2608 | static void hotkey_poll_setup_safe(const bool __unused) | ||
| 2601 | { | 2609 | { |
| 2602 | } | 2610 | } |
| 2603 | 2611 | ||
| @@ -2607,16 +2615,11 @@ static int hotkey_inputdev_open(struct input_dev *dev) | |||
| 2607 | { | 2615 | { |
| 2608 | switch (tpacpi_lifecycle) { | 2616 | switch (tpacpi_lifecycle) { |
| 2609 | case TPACPI_LIFE_INIT: | 2617 | case TPACPI_LIFE_INIT: |
| 2610 | /* | ||
| 2611 | * hotkey_init will call hotkey_poll_setup_safe | ||
| 2612 | * at the appropriate moment | ||
| 2613 | */ | ||
| 2614 | return 0; | ||
| 2615 | case TPACPI_LIFE_EXITING: | ||
| 2616 | return -EBUSY; | ||
| 2617 | case TPACPI_LIFE_RUNNING: | 2618 | case TPACPI_LIFE_RUNNING: |
| 2618 | hotkey_poll_setup_safe(false); | 2619 | hotkey_poll_setup_safe(false); |
| 2619 | return 0; | 2620 | return 0; |
| 2621 | case TPACPI_LIFE_EXITING: | ||
| 2622 | return -EBUSY; | ||
| 2620 | } | 2623 | } |
| 2621 | 2624 | ||
| 2622 | /* Should only happen if tpacpi_lifecycle is corrupt */ | 2625 | /* Should only happen if tpacpi_lifecycle is corrupt */ |
| @@ -2627,7 +2630,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) | |||
| 2627 | static void hotkey_inputdev_close(struct input_dev *dev) | 2630 | static void hotkey_inputdev_close(struct input_dev *dev) |
| 2628 | { | 2631 | { |
| 2629 | /* disable hotkey polling when possible */ | 2632 | /* disable hotkey polling when possible */ |
| 2630 | if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING && | 2633 | if (tpacpi_lifecycle != TPACPI_LIFE_EXITING && |
| 2631 | !(hotkey_source_mask & hotkey_driver_mask)) | 2634 | !(hotkey_source_mask & hotkey_driver_mask)) |
| 2632 | hotkey_poll_setup_safe(false); | 2635 | hotkey_poll_setup_safe(false); |
| 2633 | } | 2636 | } |
| @@ -3655,13 +3658,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
| 3655 | break; | 3658 | break; |
| 3656 | case 3: | 3659 | case 3: |
| 3657 | /* 0x3000-0x3FFF: bay-related wakeups */ | 3660 | /* 0x3000-0x3FFF: bay-related wakeups */ |
| 3658 | if (hkey == TP_HKEY_EV_BAYEJ_ACK) { | 3661 | switch (hkey) { |
| 3662 | case TP_HKEY_EV_BAYEJ_ACK: | ||
| 3659 | hotkey_autosleep_ack = 1; | 3663 | hotkey_autosleep_ack = 1; |
| 3660 | printk(TPACPI_INFO | 3664 | printk(TPACPI_INFO |
| 3661 | "bay ejected\n"); | 3665 | "bay ejected\n"); |
| 3662 | hotkey_wakeup_hotunplug_complete_notify_change(); | 3666 | hotkey_wakeup_hotunplug_complete_notify_change(); |
| 3663 | known_ev = true; | 3667 | known_ev = true; |
| 3664 | } else { | 3668 | break; |
| 3669 | case TP_HKEY_EV_OPTDRV_EJ: | ||
| 3670 | /* FIXME: kick libata if SATA link offline */ | ||
| 3671 | known_ev = true; | ||
| 3672 | break; | ||
| 3673 | default: | ||
| 3665 | known_ev = false; | 3674 | known_ev = false; |
| 3666 | } | 3675 | } |
| 3667 | break; | 3676 | break; |
| @@ -3870,7 +3879,7 @@ enum { | |||
| 3870 | TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ | 3879 | TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ |
| 3871 | TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ | 3880 | TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ |
| 3872 | TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: | 3881 | TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: |
| 3873 | off / last state */ | 3882 | 0 = disable, 1 = enable */ |
| 3874 | }; | 3883 | }; |
| 3875 | 3884 | ||
| 3876 | enum { | 3885 | enum { |
| @@ -3916,10 +3925,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) | |||
| 3916 | } | 3925 | } |
| 3917 | #endif | 3926 | #endif |
| 3918 | 3927 | ||
| 3919 | /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ | ||
| 3920 | status = TP_ACPI_BLUETOOTH_RESUMECTRL; | ||
| 3921 | if (state == TPACPI_RFK_RADIO_ON) | 3928 | if (state == TPACPI_RFK_RADIO_ON) |
| 3922 | status |= TP_ACPI_BLUETOOTH_RADIOSSW; | 3929 | status = TP_ACPI_BLUETOOTH_RADIOSSW |
| 3930 | | TP_ACPI_BLUETOOTH_RESUMECTRL; | ||
| 3931 | else | ||
| 3932 | status = 0; | ||
| 3923 | 3933 | ||
| 3924 | if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) | 3934 | if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) |
| 3925 | return -EIO; | 3935 | return -EIO; |
| @@ -4070,7 +4080,7 @@ enum { | |||
| 4070 | TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ | 4080 | TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ |
| 4071 | TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ | 4081 | TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ |
| 4072 | TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: | 4082 | TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: |
| 4073 | off / last state */ | 4083 | 0 = disable, 1 = enable */ |
| 4074 | }; | 4084 | }; |
| 4075 | 4085 | ||
| 4076 | #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" | 4086 | #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" |
| @@ -4107,10 +4117,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state) | |||
| 4107 | } | 4117 | } |
| 4108 | #endif | 4118 | #endif |
| 4109 | 4119 | ||
| 4110 | /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */ | ||
| 4111 | status = TP_ACPI_WANCARD_RESUMECTRL; | ||
| 4112 | if (state == TPACPI_RFK_RADIO_ON) | 4120 | if (state == TPACPI_RFK_RADIO_ON) |
| 4113 | status |= TP_ACPI_WANCARD_RADIOSSW; | 4121 | status = TP_ACPI_WANCARD_RADIOSSW |
| 4122 | | TP_ACPI_WANCARD_RESUMECTRL; | ||
| 4123 | else | ||
| 4124 | status = 0; | ||
| 4114 | 4125 | ||
| 4115 | if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) | 4126 | if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) |
| 4116 | return -EIO; | 4127 | return -EIO; |
| @@ -4619,6 +4630,10 @@ static int video_read(struct seq_file *m) | |||
| 4619 | return 0; | 4630 | return 0; |
| 4620 | } | 4631 | } |
| 4621 | 4632 | ||
| 4633 | /* Even reads can crash X.org, so... */ | ||
| 4634 | if (!capable(CAP_SYS_ADMIN)) | ||
| 4635 | return -EPERM; | ||
| 4636 | |||
| 4622 | status = video_outputsw_get(); | 4637 | status = video_outputsw_get(); |
| 4623 | if (status < 0) | 4638 | if (status < 0) |
| 4624 | return status; | 4639 | return status; |
| @@ -4652,6 +4667,10 @@ static int video_write(char *buf) | |||
| 4652 | if (video_supported == TPACPI_VIDEO_NONE) | 4667 | if (video_supported == TPACPI_VIDEO_NONE) |
| 4653 | return -ENODEV; | 4668 | return -ENODEV; |
| 4654 | 4669 | ||
| 4670 | /* Even reads can crash X.org, let alone writes... */ | ||
| 4671 | if (!capable(CAP_SYS_ADMIN)) | ||
| 4672 | return -EPERM; | ||
| 4673 | |||
| 4655 | enable = 0; | 4674 | enable = 0; |
| 4656 | disable = 0; | 4675 | disable = 0; |
| 4657 | 4676 | ||
| @@ -6133,13 +6152,13 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { | |||
| 6133 | TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ | 6152 | TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ |
| 6134 | 6153 | ||
| 6135 | /* Models with ATI GPUs that can use ECNVRAM */ | 6154 | /* Models with ATI GPUs that can use ECNVRAM */ |
| 6136 | TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), | 6155 | TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), /* R50,51 T40-42 */ |
| 6137 | TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 6156 | TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
| 6138 | TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 6157 | TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC), /* R52 */ |
| 6139 | TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 6158 | TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
| 6140 | 6159 | ||
| 6141 | /* Models with Intel Extreme Graphics 2 */ | 6160 | /* Models with Intel Extreme Graphics 2 */ |
| 6142 | TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), | 6161 | TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), /* X40 */ |
| 6143 | TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 6162 | TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
| 6144 | TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), | 6163 | TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), |
| 6145 | 6164 | ||
| @@ -6522,7 +6541,8 @@ static int volume_set_status(const u8 status) | |||
| 6522 | return volume_set_status_ec(status); | 6541 | return volume_set_status_ec(status); |
| 6523 | } | 6542 | } |
| 6524 | 6543 | ||
| 6525 | static int volume_set_mute_ec(const bool mute) | 6544 | /* returns < 0 on error, 0 on no change, 1 on change */ |
| 6545 | static int __volume_set_mute_ec(const bool mute) | ||
| 6526 | { | 6546 | { |
| 6527 | int rc; | 6547 | int rc; |
| 6528 | u8 s, n; | 6548 | u8 s, n; |
| @@ -6537,22 +6557,37 @@ static int volume_set_mute_ec(const bool mute) | |||
| 6537 | n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK : | 6557 | n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK : |
| 6538 | s & ~TP_EC_AUDIO_MUTESW_MSK; | 6558 | s & ~TP_EC_AUDIO_MUTESW_MSK; |
| 6539 | 6559 | ||
| 6540 | if (n != s) | 6560 | if (n != s) { |
| 6541 | rc = volume_set_status_ec(n); | 6561 | rc = volume_set_status_ec(n); |
| 6562 | if (!rc) | ||
| 6563 | rc = 1; | ||
| 6564 | } | ||
| 6542 | 6565 | ||
| 6543 | unlock: | 6566 | unlock: |
| 6544 | mutex_unlock(&volume_mutex); | 6567 | mutex_unlock(&volume_mutex); |
| 6545 | return rc; | 6568 | return rc; |
| 6546 | } | 6569 | } |
| 6547 | 6570 | ||
| 6571 | static int volume_alsa_set_mute(const bool mute) | ||
| 6572 | { | ||
| 6573 | dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n", | ||
| 6574 | (mute) ? "" : "un"); | ||
| 6575 | return __volume_set_mute_ec(mute); | ||
| 6576 | } | ||
| 6577 | |||
| 6548 | static int volume_set_mute(const bool mute) | 6578 | static int volume_set_mute(const bool mute) |
| 6549 | { | 6579 | { |
| 6580 | int rc; | ||
| 6581 | |||
| 6550 | dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n", | 6582 | dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n", |
| 6551 | (mute) ? "" : "un"); | 6583 | (mute) ? "" : "un"); |
| 6552 | return volume_set_mute_ec(mute); | 6584 | |
| 6585 | rc = __volume_set_mute_ec(mute); | ||
| 6586 | return (rc < 0) ? rc : 0; | ||
| 6553 | } | 6587 | } |
| 6554 | 6588 | ||
| 6555 | static int volume_set_volume_ec(const u8 vol) | 6589 | /* returns < 0 on error, 0 on no change, 1 on change */ |
| 6590 | static int __volume_set_volume_ec(const u8 vol) | ||
| 6556 | { | 6591 | { |
| 6557 | int rc; | 6592 | int rc; |
| 6558 | u8 s, n; | 6593 | u8 s, n; |
| @@ -6569,19 +6604,22 @@ static int volume_set_volume_ec(const u8 vol) | |||
| 6569 | 6604 | ||
| 6570 | n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol; | 6605 | n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol; |
| 6571 | 6606 | ||
| 6572 | if (n != s) | 6607 | if (n != s) { |
| 6573 | rc = volume_set_status_ec(n); | 6608 | rc = volume_set_status_ec(n); |
| 6609 | if (!rc) | ||
| 6610 | rc = 1; | ||
| 6611 | } | ||
| 6574 | 6612 | ||
| 6575 | unlock: | 6613 | unlock: |
| 6576 | mutex_unlock(&volume_mutex); | 6614 | mutex_unlock(&volume_mutex); |
| 6577 | return rc; | 6615 | return rc; |
| 6578 | } | 6616 | } |
| 6579 | 6617 | ||
| 6580 | static int volume_set_volume(const u8 vol) | 6618 | static int volume_alsa_set_volume(const u8 vol) |
| 6581 | { | 6619 | { |
| 6582 | dbg_printk(TPACPI_DBG_MIXER, | 6620 | dbg_printk(TPACPI_DBG_MIXER, |
| 6583 | "trying to set volume level to %hu\n", vol); | 6621 | "ALSA: trying to set volume level to %hu\n", vol); |
| 6584 | return volume_set_volume_ec(vol); | 6622 | return __volume_set_volume_ec(vol); |
| 6585 | } | 6623 | } |
| 6586 | 6624 | ||
| 6587 | static void volume_alsa_notify_change(void) | 6625 | static void volume_alsa_notify_change(void) |
| @@ -6628,7 +6666,7 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol, | |||
| 6628 | static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol, | 6666 | static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol, |
| 6629 | struct snd_ctl_elem_value *ucontrol) | 6667 | struct snd_ctl_elem_value *ucontrol) |
| 6630 | { | 6668 | { |
| 6631 | return volume_set_volume(ucontrol->value.integer.value[0]); | 6669 | return volume_alsa_set_volume(ucontrol->value.integer.value[0]); |
| 6632 | } | 6670 | } |
| 6633 | 6671 | ||
| 6634 | #define volume_alsa_mute_info snd_ctl_boolean_mono_info | 6672 | #define volume_alsa_mute_info snd_ctl_boolean_mono_info |
| @@ -6651,7 +6689,7 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol, | |||
| 6651 | static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, | 6689 | static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, |
| 6652 | struct snd_ctl_elem_value *ucontrol) | 6690 | struct snd_ctl_elem_value *ucontrol) |
| 6653 | { | 6691 | { |
| 6654 | return volume_set_mute(!ucontrol->value.integer.value[0]); | 6692 | return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); |
| 6655 | } | 6693 | } |
| 6656 | 6694 | ||
| 6657 | static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = { | 6695 | static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = { |
| @@ -8477,9 +8515,10 @@ static int __init ibm_init(struct ibm_init_struct *iibm) | |||
| 8477 | "%s installed\n", ibm->name); | 8515 | "%s installed\n", ibm->name); |
| 8478 | 8516 | ||
| 8479 | if (ibm->read) { | 8517 | if (ibm->read) { |
| 8480 | mode_t mode; | 8518 | mode_t mode = iibm->base_procfs_mode; |
| 8481 | 8519 | ||
| 8482 | mode = S_IRUGO; | 8520 | if (!mode) |
| 8521 | mode = S_IRUGO; | ||
| 8483 | if (ibm->write) | 8522 | if (ibm->write) |
| 8484 | mode |= S_IWUSR; | 8523 | mode |= S_IWUSR; |
| 8485 | entry = proc_create_data(ibm->name, mode, proc_dir, | 8524 | entry = proc_create_data(ibm->name, mode, proc_dir, |
| @@ -8670,6 +8709,7 @@ static struct ibm_init_struct ibms_init[] __initdata = { | |||
| 8670 | #ifdef CONFIG_THINKPAD_ACPI_VIDEO | 8709 | #ifdef CONFIG_THINKPAD_ACPI_VIDEO |
| 8671 | { | 8710 | { |
| 8672 | .init = video_init, | 8711 | .init = video_init, |
| 8712 | .base_procfs_mode = S_IRUSR, | ||
| 8673 | .data = &video_driver_data, | 8713 | .data = &video_driver_data, |
| 8674 | }, | 8714 | }, |
| 8675 | #endif | 8715 | #endif |
| @@ -9032,6 +9072,9 @@ static int __init thinkpad_acpi_module_init(void) | |||
| 9032 | return ret; | 9072 | return ret; |
| 9033 | } | 9073 | } |
| 9034 | } | 9074 | } |
| 9075 | |||
| 9076 | tpacpi_lifecycle = TPACPI_LIFE_RUNNING; | ||
| 9077 | |||
| 9035 | ret = input_register_device(tpacpi_inputdev); | 9078 | ret = input_register_device(tpacpi_inputdev); |
| 9036 | if (ret < 0) { | 9079 | if (ret < 0) { |
| 9037 | printk(TPACPI_ERR "unable to register input device\n"); | 9080 | printk(TPACPI_ERR "unable to register input device\n"); |
| @@ -9041,7 +9084,6 @@ static int __init thinkpad_acpi_module_init(void) | |||
| 9041 | tp_features.input_device_registered = 1; | 9084 | tp_features.input_device_registered = 1; |
| 9042 | } | 9085 | } |
| 9043 | 9086 | ||
| 9044 | tpacpi_lifecycle = TPACPI_LIFE_RUNNING; | ||
| 9045 | return 0; | 9087 | return 0; |
| 9046 | } | 9088 | } |
| 9047 | 9089 | ||
