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 /drivers/platform/x86 | |
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
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r-- | drivers/platform/x86/Kconfig | 10 | ||||
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 116 |
2 files changed, 87 insertions, 39 deletions
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 | ||