From: Henrique de Moraes Holschuh Date: Thu, 9 Apr 2009 01:38:25 +0000 (-0300) Subject: Add patches accepted for 2.6.30-rc1 X-Git-Url: https://repo.or.cz/w/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git/commitdiff_plain/4e8a23f5fa327f5bff1cf723429314883e368817 Add patches accepted for 2.6.30-rc1 Signed-off-by: Henrique de Moraes Holschuh --- diff --git a/releases/upstream/2.6.30-rc1/0001-trivial-Fix-misspelling-of-firmware.patch b/releases/upstream/2.6.30-rc1/0001-trivial-Fix-misspelling-of-firmware.patch new file mode 100644 index 00000000000..e2b664c7189 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0001-trivial-Fix-misspelling-of-firmware.patch @@ -0,0 +1,303 @@ +From 877d03105d04b2c13e241130277fa69c8d2564f0 Mon Sep 17 00:00:00 2001 +From: Nick Andrew +Date: Mon, 26 Jan 2009 11:06:57 +0100 +Subject: trivial: Fix misspelling of firmware + +Fix misspelling of firmware. + +Signed-off-by: Nick Andrew +Signed-off-by: Jiri Kosina +--- + Documentation/ia64/kvm.txt | 2 +- + .../dts-bindings/fsl/cpm_qe/qe/firmware.txt | 2 +- + arch/mips/sgi-ip27/ip27-smp.c | 2 +- + arch/sparc/kernel/head_64.S | 2 +- + drivers/net/sb1250-mac.c | 2 +- + drivers/net/tg3.c | 2 +- + drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- + drivers/net/wireless/ipw2x00/ipw2200.c | 2 +- + drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- + drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- + drivers/net/wireless/libertas/cmd.c | 2 +- + drivers/pci/pci.c | 2 +- + drivers/platform/x86/thinkpad_acpi.c | 2 +- + drivers/staging/otus/hal/hpmain.c | 2 +- + drivers/usb/atm/ueagle-atm.c | 2 +- + drivers/usb/serial/ChangeLog.history | 2 +- + include/linux/libata.h | 2 +- + kernel/power/disk.c | 4 ++-- + sound/oss/pss.c | 2 +- + sound/sh/aica.c | 2 +- + 20 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt +index 84f7cb3..ffb5c80 100644 +--- a/Documentation/ia64/kvm.txt ++++ b/Documentation/ia64/kvm.txt +@@ -42,7 +42,7 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe + hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg + you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries. + +- (3) Rename the firware you owned to Flash.fd, and copy it to /usr/local/share/qemu ++ (3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu + + 4. Boot up Linux or Windows guests: + 4.1 Create or install a image for guest boot. If you have xen experience, it should be easy. +diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt +index 6c238f5..249db3a 100644 +--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt ++++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt +@@ -1,6 +1,6 @@ + * Uploaded QE firmware + +- If a new firwmare has been uploaded to the QE (usually by the ++ If a new firmware has been uploaded to the QE (usually by the + boot loader), then a 'firmware' child node should be added to the QE + node. This node provides information on the uploaded firmware that + device drivers may need. +diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c +index 5b47d6b..cbcd7eb 100644 +--- a/arch/mips/sgi-ip27/ip27-smp.c ++++ b/arch/mips/sgi-ip27/ip27-smp.c +@@ -221,7 +221,7 @@ static void __init ip27_smp_setup(void) + * Assumption to be fixed: we're always booted on logical / physical + * processor 0. While we're always running on logical processor 0 + * this still means this is physical processor zero; it might for +- * example be disabled in the firwware. ++ * example be disabled in the firmware. + */ + alloc_cpupda(0, 0); + } +diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S +index a46c3a2..3a1b7bf 100644 +--- a/arch/sparc/kernel/head_64.S ++++ b/arch/sparc/kernel/head_64.S +@@ -686,7 +686,7 @@ tlb_fixup_done: + * point. + * + * There used to be enormous complexity wrt. transferring +- * over from the firwmare's trap table to the Linux kernel's. ++ * over from the firmware's trap table to the Linux kernel's. + * For example, there was a chicken & egg problem wrt. building + * the OBP page tables, yet needing to be on the Linux kernel + * trap table (to translate PAGE_OFFSET addresses) in order to +diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c +index 88dd2e0..ce7551e 100644 +--- a/drivers/net/sb1250-mac.c ++++ b/drivers/net/sb1250-mac.c +@@ -2299,7 +2299,7 @@ static int sbmac_init(struct platform_device *pldev, long long base) + eaddr = sc->sbm_hwaddr; + + /* +- * Read the ethernet address. The firwmare left this programmed ++ * Read the ethernet address. The firmware left this programmed + * for us in the ethernet address register for each mac. + */ + +diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c +index f7efcec..ed60b18 100644 +--- a/drivers/net/tg3.c ++++ b/drivers/net/tg3.c +@@ -11225,7 +11225,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) + return tg3_phy_init(tp); + + /* Reading the PHY ID register can conflict with ASF +- * firwmare access to the PHY hardware. ++ * firmware access to the PHY hardware. + */ + err = 0; + if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) || +diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c +index 115b704..f4e963b 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2100.c ++++ b/drivers/net/wireless/ipw2x00/ipw2100.c +@@ -2362,7 +2362,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i) + i * sizeof(struct ipw2100_status)); + + #ifdef IPW2100_DEBUG_C3 +- /* Halt the fimrware so we can get a good image */ ++ /* Halt the firmware so we can get a good image */ + write_register(priv->net_dev, IPW_REG_RESET_REG, + IPW_AUX_HOST_RESET_REG_STOP_MASTER); + j = 5; +diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c +index b344994..f6174fd 100644 +--- a/drivers/net/wireless/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/ipw2x00/ipw2200.c +@@ -8844,7 +8844,7 @@ static int ipw_wx_set_mode(struct net_device *dev, + #endif /* CONFIG_IPW2200_MONITOR */ + + /* Free the existing firmware and reset the fw_loaded +- * flag so ipw_load() will bring in the new firmawre */ ++ * flag so ipw_load() will bring in the new firmware */ + free_firmware(); + + priv->ieee->iw_mode = wrqu->mode; +diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c +index 663dc83..3889158 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-agn.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c +@@ -1337,7 +1337,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) + + /* api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely +- * on the API version read from firware header from here on forward */ ++ * on the API version read from firmware header from here on forward */ + + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, "Driver unable to support your firmware API. " +diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c +index a71b08c..9d5f97d 100644 +--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c ++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c +@@ -2562,7 +2562,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv) + + /* api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely +- * on the API version read from firware header from here on forward */ ++ * on the API version read from firmware header from here on forward */ + + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, "Driver unable to support your firmware API. " +diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c +index 639dd02..8c3605c 100644 +--- a/drivers/net/wireless/libertas/cmd.c ++++ b/drivers/net/wireless/libertas/cmd.c +@@ -1649,7 +1649,7 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv) + + /** + * @brief This function executes next command in command +- * pending queue. It will put fimware back to PS mode ++ * pending queue. It will put firmware back to PS mode + * if applicable. + * + * @param priv A pointer to struct lbs_private structure +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 6d61200..dab33a2 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -550,7 +550,7 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state) + * @dev: PCI device to handle. + * @state: PCI power state (D0, D1, D2, D3hot) to put the device into. + * +- * Transition a device to a new power state, using the platform formware and/or ++ * Transition a device to a new power state, using the platform firmware and/or + * the device's PCI PM registers. + * + * RETURN VALUE: +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index d243320..814cb65 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -5811,7 +5811,7 @@ static struct ibm_struct volume_driver_data = { + * ThinkPads from this same time period (and earlier) probably lack the + * tachometer as well. + * +- * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare ++ * Unfortunately a lot of ThinkPads with new-style ECs but whose firmware + * was never fixed by IBM to report the EC firmware version string + * probably support the tachometer (like the early X models), so + * detecting it is quite hard. We need more data to know for sure. +diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c +index 2e65c46..dab2783 100644 +--- a/drivers/staging/otus/hal/hpmain.c ++++ b/drivers/staging/otus/hal/hpmain.c +@@ -152,7 +152,7 @@ u16_t zfHpInit(zdev_t* dev, u32_t frequency) + else + { + #ifndef ZM_OTUS_LINUX_PHASE_2 +- /* donwload the normal frimware */ ++ /* download the normal firmware */ + if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + { +diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c +index b6483dd..9cf9ff6 100644 +--- a/drivers/usb/atm/ueagle-atm.c ++++ b/drivers/usb/atm/ueagle-atm.c +@@ -626,7 +626,7 @@ static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *conte + goto err_fw_corrupted; + + /* +- * Start to upload formware : send reset ++ * Start to upload firmware : send reset + */ + value = 1; + ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value); +diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history +index c1b2799..f13fd48 100644 +--- a/drivers/usb/serial/ChangeLog.history ++++ b/drivers/usb/serial/ChangeLog.history +@@ -715,7 +715,7 @@ io_edgeport.c Change Log comments: + + 0.2 (01/30/2000) greg kroah-hartman + Milestone 1 release. +- Device is found by USB subsystem, enumerated, fimware is downloaded ++ Device is found by USB subsystem, enumerated, firmware is downloaded + and the descriptors are printed to the debug log, config is set, and + green light starts to blink. Open port works, and data can be sent + and received at the default settings of the UART. Loopback connector +diff --git a/include/linux/libata.h b/include/linux/libata.h +index 76262d8..b450a26 100644 +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -379,7 +379,7 @@ enum { + ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ + ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands + not multiple of 16 bytes */ +- ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firwmare update warning */ ++ ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firmware update warning */ + ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ + + /* DMA mask for user DMA control: User visible values; DO NOT +diff --git a/kernel/power/disk.c b/kernel/power/disk.c +index 4a4a206..9d1c1a0 100644 +--- a/kernel/power/disk.c ++++ b/kernel/power/disk.c +@@ -265,7 +265,7 @@ static int create_image(int platform_mode) + * hibernation_snapshot - quiesce devices and create the hibernation + * snapshot image. + * @platform_mode - if set, use the platform driver, if available, to +- * prepare the platform frimware for the power transition. ++ * prepare the platform firmware for the power transition. + * + * Must be called with pm_mutex held + */ +@@ -378,7 +378,7 @@ static int resume_target_kernel(void) + * hibernation_restore - quiesce devices and restore the hibernation + * snapshot image. If successful, control returns in hibernation_snaphot() + * @platform_mode - if set, use the platform driver, if available, to +- * prepare the platform frimware for the transition. ++ * prepare the platform firmware for the transition. + * + * Must be called with pm_mutex held + */ +diff --git a/sound/oss/pss.c b/sound/oss/pss.c +index 16517a5..83f5ee2 100644 +--- a/sound/oss/pss.c ++++ b/sound/oss/pss.c +@@ -46,7 +46,7 @@ + * load the driver as it did in previous versions. + * 04-07-1999: Anthony Barbachan + * Added module parameter pss_firmware to allow the user to tell +- * the driver where the fireware file is located. The default ++ * the driver where the firmware file is located. The default + * setting is the previous hardcoded setting "/etc/sound/pss_synth". + * 00-03-03: Christoph Hellwig + * Adapted to module_init/module_exit +diff --git a/sound/sh/aica.c b/sound/sh/aica.c +index f551233..583a369 100644 +--- a/sound/sh/aica.c ++++ b/sound/sh/aica.c +@@ -565,7 +565,7 @@ static int load_aica_firmware(void) + err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); + if (unlikely(err)) + return err; +- /* write firware into memory */ ++ /* write firmware into memory */ + spu_disable(); + spu_memload(0, fw_entry->data, fw_entry->size); + spu_enable(); +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0002-proc-2-2-remove-struct-proc_dir_entry-owner.patch b/releases/upstream/2.6.30-rc1/0002-proc-2-2-remove-struct-proc_dir_entry-owner.patch new file mode 100644 index 00000000000..9f56c2e2af8 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0002-proc-2-2-remove-struct-proc_dir_entry-owner.patch @@ -0,0 +1,1274 @@ +From 99b76233803beab302123d243eea9e41149804f3 Mon Sep 17 00:00:00 2001 +From: Alexey Dobriyan +Date: Wed, 25 Mar 2009 22:48:06 +0300 +Subject: proc 2/2: remove struct proc_dir_entry::owner + +Setting ->owner as done currently (pde->owner = THIS_MODULE) is racy +as correctly noted at bug #12454. Someone can lookup entry with NULL +->owner, thus not pinning enything, and release it later resulting +in module refcount underflow. + +We can keep ->owner and supply it at registration time like ->proc_fops +and ->data. + +But this leaves ->owner as easy-manipulative field (just one C assignment) +and somebody will forget to unpin previous/pin current module when +switching ->owner. ->proc_fops is declared as "const" which should give +some thoughts. + +->read_proc/->write_proc were just fixed to not require ->owner for +protection. + +rmmod'ed directories will be empty and return "." and ".." -- no harm. +And directories with tricky enough readdir and lookup shouldn't be modular. +We definitely don't want such modular code. + +Removing ->owner will also make PDE smaller. + +So, let's nuke it. + +Kudos to Jeff Layton for reminding about this, let's say, oversight. + +http://bugzilla.kernel.org/show_bug.cgi?id=12454 + +Signed-off-by: Alexey Dobriyan +--- + Documentation/DocBook/procfs_example.c | 9 -------- + arch/alpha/kernel/srm_env.c | 5 ---- + arch/blackfin/mm/sram-alloc.c | 1 - + arch/ia64/kernel/palinfo.c | 2 - + arch/ia64/sn/kernel/sn2/prominfo_proc.c | 9 +------ + arch/powerpc/kernel/rtas_flash.c | 1 - + arch/sparc/kernel/led.c | 1 - + arch/x86/kernel/cpu/mtrr/if.c | 10 +-------- + drivers/acpi/ac.c | 1 - + drivers/acpi/battery.c | 1 - + drivers/acpi/button.c | 3 -- + drivers/acpi/fan.c | 2 - + drivers/acpi/processor_core.c | 2 - + drivers/acpi/sbs.c | 1 - + drivers/acpi/thermal.c | 2 - + drivers/acpi/video.c | 5 ---- + drivers/block/ps3vram.c | 2 - + drivers/char/ipmi/ipmi_msghandler.c | 12 +++------- + drivers/char/ipmi/ipmi_si_intf.c | 6 ++-- + drivers/input/input.c | 2 - + drivers/isdn/hardware/eicon/divasi.c | 1 - + drivers/media/video/cpia.c | 4 +-- + drivers/message/i2o/i2o_proc.c | 2 - + drivers/net/bonding/bond_main.c | 35 +----------------------------- + drivers/net/irda/vlsi_ir.c | 7 ------ + drivers/net/wireless/airo.c | 1 - + drivers/platform/x86/asus_acpi.c | 3 -- + drivers/platform/x86/thinkpad_acpi.c | 2 - + drivers/platform/x86/toshiba_acpi.c | 3 -- + drivers/rtc/rtc-proc.c | 10 +------- + drivers/s390/block/dasd_proc.c | 2 - + drivers/scsi/scsi_devinfo.c | 2 - + drivers/scsi/scsi_proc.c | 3 -- + drivers/video/via/viafbdev.c | 5 ---- + fs/afs/proc.c | 1 - + fs/cifs/cifs_debug.c | 1 - + fs/jfs/jfs_debug.c | 1 - + fs/nfs/client.c | 2 - + fs/proc/inode.c | 19 ++-------------- + fs/proc/proc_tty.c | 1 - + fs/reiserfs/procfs.c | 5 +--- + include/linux/ipmi_smi.h | 2 +- + include/linux/proc_fs.h | 4 --- + net/appletalk/atalk_proc.c | 1 - + net/atm/mpoa_proc.c | 1 - + net/atm/proc.c | 1 - + net/can/bcm.c | 4 --- + net/can/proc.c | 2 - + net/core/pktgen.c | 1 - + net/irda/irproc.c | 1 - + net/llc/llc_proc.c | 1 - + net/sctp/protocol.c | 8 +----- + net/sunrpc/cache.c | 4 --- + net/sunrpc/stats.c | 10 +------- + sound/core/info.c | 31 +------------------------- + 55 files changed, 26 insertions(+), 232 deletions(-) + +diff --git a/Documentation/DocBook/procfs_example.c b/Documentation/DocBook/procfs_example.c +index 8c6396e..a5b1179 100644 +--- a/Documentation/DocBook/procfs_example.c ++++ b/Documentation/DocBook/procfs_example.c +@@ -117,9 +117,6 @@ static int __init init_procfs_example(void) + rv = -ENOMEM; + goto out; + } +- +- example_dir->owner = THIS_MODULE; +- + /* create jiffies using convenience function */ + jiffies_file = create_proc_read_entry("jiffies", + 0444, example_dir, +@@ -130,8 +127,6 @@ static int __init init_procfs_example(void) + goto no_jiffies; + } + +- jiffies_file->owner = THIS_MODULE; +- + /* create foo and bar files using same callback + * functions + */ +@@ -146,7 +141,6 @@ static int __init init_procfs_example(void) + foo_file->data = &foo_data; + foo_file->read_proc = proc_read_foobar; + foo_file->write_proc = proc_write_foobar; +- foo_file->owner = THIS_MODULE; + + bar_file = create_proc_entry("bar", 0644, example_dir); + if(bar_file == NULL) { +@@ -159,7 +153,6 @@ static int __init init_procfs_example(void) + bar_file->data = &bar_data; + bar_file->read_proc = proc_read_foobar; + bar_file->write_proc = proc_write_foobar; +- bar_file->owner = THIS_MODULE; + + /* create symlink */ + symlink = proc_symlink("jiffies_too", example_dir, +@@ -169,8 +162,6 @@ static int __init init_procfs_example(void) + goto no_symlink; + } + +- symlink->owner = THIS_MODULE; +- + /* everything OK */ + printk(KERN_INFO "%s %s initialised\n", + MODULE_NAME, MODULE_VERS); +diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c +index 78ad7cd..d12af47 100644 +--- a/arch/alpha/kernel/srm_env.c ++++ b/arch/alpha/kernel/srm_env.c +@@ -218,7 +218,6 @@ srm_env_init(void) + BASE_DIR); + goto cleanup; + } +- base_dir->owner = THIS_MODULE; + + /* + * Create per-name subdirectory +@@ -229,7 +228,6 @@ srm_env_init(void) + BASE_DIR, NAMED_DIR); + goto cleanup; + } +- named_dir->owner = THIS_MODULE; + + /* + * Create per-number subdirectory +@@ -241,7 +239,6 @@ srm_env_init(void) + goto cleanup; + + } +- numbered_dir->owner = THIS_MODULE; + + /* + * Create all named nodes +@@ -254,7 +251,6 @@ srm_env_init(void) + goto cleanup; + + entry->proc_entry->data = (void *) entry; +- entry->proc_entry->owner = THIS_MODULE; + entry->proc_entry->read_proc = srm_env_read; + entry->proc_entry->write_proc = srm_env_write; + +@@ -275,7 +271,6 @@ srm_env_init(void) + + entry->id = var_num; + entry->proc_entry->data = (void *) entry; +- entry->proc_entry->owner = THIS_MODULE; + entry->proc_entry->read_proc = srm_env_read; + entry->proc_entry->write_proc = srm_env_write; + } +diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c +index 834cab7..530d139 100644 +--- a/arch/blackfin/mm/sram-alloc.c ++++ b/arch/blackfin/mm/sram-alloc.c +@@ -854,7 +854,6 @@ static int __init sram_proc_init(void) + printk(KERN_WARNING "unable to create /proc/sram\n"); + return -1; + } +- ptr->owner = THIS_MODULE; + ptr->read_proc = sram_proc_read; + return 0; + } +diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c +index e5c57f4..a4f19c7 100644 +--- a/arch/ia64/kernel/palinfo.c ++++ b/arch/ia64/kernel/palinfo.c +@@ -1002,8 +1002,6 @@ create_palinfo_proc_entries(unsigned int cpu) + *pdir = create_proc_read_entry( + palinfo_entries[j].name, 0, cpu_dir, + palinfo_read_entry, (void *)f.value); +- if (*pdir) +- (*pdir)->owner = THIS_MODULE; + pdir++; + } + } +diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c +index 4dcce3d..e633288 100644 +--- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c ++++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c +@@ -225,7 +225,6 @@ static struct proc_dir_entry *sgi_prominfo_entry; + int __init prominfo_init(void) + { + struct proc_dir_entry **entp; +- struct proc_dir_entry *p; + cnodeid_t cnodeid; + unsigned long nasid; + int size; +@@ -246,14 +245,10 @@ int __init prominfo_init(void) + sprintf(name, "node%d", cnodeid); + *entp = proc_mkdir(name, sgi_prominfo_entry); + nasid = cnodeid_to_nasid(cnodeid); +- p = create_proc_read_entry("fit", 0, *entp, read_fit_entry, ++ create_proc_read_entry("fit", 0, *entp, read_fit_entry, + (void *)nasid); +- if (p) +- p->owner = THIS_MODULE; +- p = create_proc_read_entry("version", 0, *entp, ++ create_proc_read_entry("version", 0, *entp, + read_version_entry, (void *)nasid); +- if (p) +- p->owner = THIS_MODULE; + entp++; + } + +diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c +index 149cb11..13011a9 100644 +--- a/arch/powerpc/kernel/rtas_flash.c ++++ b/arch/powerpc/kernel/rtas_flash.c +@@ -669,7 +669,6 @@ static void remove_flash_pde(struct proc_dir_entry *dp) + { + if (dp) { + kfree(dp->data); +- dp->owner = NULL; + remove_proc_entry(dp->name, dp->parent); + } + } +diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c +index adaaed4..00d034e 100644 +--- a/arch/sparc/kernel/led.c ++++ b/arch/sparc/kernel/led.c +@@ -126,7 +126,6 @@ static int __init led_init(void) + led = proc_create("led", 0, NULL, &led_proc_fops); + if (!led) + return -ENOMEM; +- led->owner = THIS_MODULE; + + printk(KERN_INFO + "led: version %s, Lars Kotthoff \n", +diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c +index 4c42146..fb73a52 100644 +--- a/arch/x86/kernel/cpu/mtrr/if.c ++++ b/arch/x86/kernel/cpu/mtrr/if.c +@@ -377,10 +377,6 @@ static const struct file_operations mtrr_fops = { + .release = mtrr_close, + }; + +- +-static struct proc_dir_entry *proc_root_mtrr; +- +- + static int mtrr_seq_show(struct seq_file *seq, void *offset) + { + char factor; +@@ -423,11 +419,7 @@ static int __init mtrr_if_init(void) + (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) + return -ENODEV; + +- proc_root_mtrr = +- proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); +- +- if (proc_root_mtrr) +- proc_root_mtrr->owner = THIS_MODULE; ++ proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); + return 0; + } + +diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c +index 9b917da..88e42ab 100644 +--- a/drivers/acpi/ac.c ++++ b/drivers/acpi/ac.c +@@ -191,7 +191,6 @@ static int acpi_ac_add_fs(struct acpi_device *device) + acpi_ac_dir); + if (!acpi_device_dir(device)) + return -ENODEV; +- acpi_device_dir(device)->owner = THIS_MODULE; + } + + /* 'state' [R] */ +diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c +index 69cbc57..3bcb5bf 100644 +--- a/drivers/acpi/battery.c ++++ b/drivers/acpi/battery.c +@@ -760,7 +760,6 @@ static int acpi_battery_add_fs(struct acpi_device *device) + acpi_battery_dir); + if (!acpi_device_dir(device)) + return -ENODEV; +- acpi_device_dir(device)->owner = THIS_MODULE; + } + + for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { +diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c +index 171fd91..c2f0606 100644 +--- a/drivers/acpi/button.c ++++ b/drivers/acpi/button.c +@@ -200,12 +200,10 @@ static int acpi_button_add_fs(struct acpi_device *device) + + if (!entry) + return -ENODEV; +- entry->owner = THIS_MODULE; + + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); + if (!acpi_device_dir(device)) + return -ENODEV; +- acpi_device_dir(device)->owner = THIS_MODULE; + + /* 'info' [R] */ + entry = proc_create_data(ACPI_BUTTON_FILE_INFO, +@@ -522,7 +520,6 @@ static int __init acpi_button_init(void) + acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); + if (!acpi_button_dir) + return -ENODEV; +- acpi_button_dir->owner = THIS_MODULE; + result = acpi_bus_register_driver(&acpi_button_driver); + if (result < 0) { + remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); +diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c +index eaaee16..8a02944 100644 +--- a/drivers/acpi/fan.c ++++ b/drivers/acpi/fan.c +@@ -193,7 +193,6 @@ static int acpi_fan_add_fs(struct acpi_device *device) + acpi_fan_dir); + if (!acpi_device_dir(device)) + return -ENODEV; +- acpi_device_dir(device)->owner = THIS_MODULE; + } + + /* 'status' [R/W] */ +@@ -347,7 +346,6 @@ static int __init acpi_fan_init(void) + acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); + if (!acpi_fan_dir) + return -ENODEV; +- acpi_fan_dir->owner = THIS_MODULE; + #endif + + result = acpi_bus_register_driver(&acpi_fan_driver); +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 0cc2fd3..fa2f742 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -359,7 +359,6 @@ static int acpi_processor_add_fs(struct acpi_device *device) + if (!acpi_device_dir(device)) + return -ENODEV; + } +- acpi_device_dir(device)->owner = THIS_MODULE; + + /* 'info' [R] */ + entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, +@@ -1137,7 +1136,6 @@ static int __init acpi_processor_init(void) + acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); + if (!acpi_processor_dir) + return -ENOMEM; +- acpi_processor_dir->owner = THIS_MODULE; + + /* + * Check whether the system is DMI table. If yes, OSPM +diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c +index 6050ce4..59afd52 100644 +--- a/drivers/acpi/sbs.c ++++ b/drivers/acpi/sbs.c +@@ -488,7 +488,6 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, + if (!*dir) { + return -ENODEV; + } +- (*dir)->owner = THIS_MODULE; + } + + /* 'info' [R] */ +diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c +index 99e6f1f..c11f9ae 100644 +--- a/drivers/acpi/thermal.c ++++ b/drivers/acpi/thermal.c +@@ -1506,7 +1506,6 @@ static int acpi_thermal_add_fs(struct acpi_device *device) + acpi_thermal_dir); + if (!acpi_device_dir(device)) + return -ENODEV; +- acpi_device_dir(device)->owner = THIS_MODULE; + } + + /* 'state' [R] */ +@@ -1875,7 +1874,6 @@ static int __init acpi_thermal_init(void) + acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); + if (!acpi_thermal_dir) + return -ENODEV; +- acpi_thermal_dir->owner = THIS_MODULE; + + result = acpi_bus_register_driver(&acpi_thermal_driver); + if (result < 0) { +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c +index bb5ed05..67cc36d 100644 +--- a/drivers/acpi/video.c ++++ b/drivers/acpi/video.c +@@ -1125,8 +1125,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device) + if (!device_dir) + return -ENOMEM; + +- device_dir->owner = THIS_MODULE; +- + /* 'info' [R] */ + entry = proc_create_data("info", S_IRUGO, device_dir, + &acpi_video_device_info_fops, acpi_driver_data(device)); +@@ -1403,8 +1401,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) + if (!device_dir) + return -ENOMEM; + +- device_dir->owner = THIS_MODULE; +- + /* 'info' [R] */ + entry = proc_create_data("info", S_IRUGO, device_dir, + &acpi_video_bus_info_fops, +@@ -2131,7 +2127,6 @@ static int __init acpi_video_init(void) + acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); + if (!acpi_video_dir) + return -ENODEV; +- acpi_video_dir->owner = THIS_MODULE; + + result = acpi_bus_register_driver(&acpi_video_bus); + if (result < 0) { +diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c +index 393ed67..8eddef3 100644 +--- a/drivers/block/ps3vram.c ++++ b/drivers/block/ps3vram.c +@@ -551,8 +551,6 @@ static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) + dev_warn(&dev->core, "failed to create /proc entry\n"); + return; + } +- +- pde->owner = THIS_MODULE; + pde->data = priv; + } + +diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c +index 7a88dfd..e93fc8d 100644 +--- a/drivers/char/ipmi/ipmi_msghandler.c ++++ b/drivers/char/ipmi/ipmi_msghandler.c +@@ -1944,7 +1944,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off, + + int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, + read_proc_t *read_proc, +- void *data, struct module *owner) ++ void *data) + { + int rv = 0; + #ifdef CONFIG_PROC_FS +@@ -1970,7 +1970,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, + } else { + file->data = data; + file->read_proc = read_proc; +- file->owner = owner; + + mutex_lock(&smi->proc_entry_lock); + /* Stick it on the list. */ +@@ -1993,23 +1992,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num) + smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); + if (!smi->proc_dir) + rv = -ENOMEM; +- else +- smi->proc_dir->owner = THIS_MODULE; + + if (rv == 0) + rv = ipmi_smi_add_proc_entry(smi, "stats", + stat_file_read_proc, +- smi, THIS_MODULE); ++ smi); + + if (rv == 0) + rv = ipmi_smi_add_proc_entry(smi, "ipmb", + ipmb_file_read_proc, +- smi, THIS_MODULE); ++ smi); + + if (rv == 0) + rv = ipmi_smi_add_proc_entry(smi, "version", + version_file_read_proc, +- smi, THIS_MODULE); ++ smi); + #endif /* CONFIG_PROC_FS */ + + return rv; +@@ -4265,7 +4262,6 @@ static int ipmi_init_msghandler(void) + return -ENOMEM; + } + +- proc_ipmi_root->owner = THIS_MODULE; + #endif /* CONFIG_PROC_FS */ + + setup_timer(&ipmi_timer, ipmi_timeout, 0); +diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c +index 3000135..e58ea4c 100644 +--- a/drivers/char/ipmi/ipmi_si_intf.c ++++ b/drivers/char/ipmi/ipmi_si_intf.c +@@ -2899,7 +2899,7 @@ static int try_smi_init(struct smi_info *new_smi) + + rv = ipmi_smi_add_proc_entry(new_smi->intf, "type", + type_file_read_proc, +- new_smi, THIS_MODULE); ++ new_smi); + if (rv) { + printk(KERN_ERR + "ipmi_si: Unable to create proc entry: %d\n", +@@ -2909,7 +2909,7 @@ static int try_smi_init(struct smi_info *new_smi) + + rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats", + stat_file_read_proc, +- new_smi, THIS_MODULE); ++ new_smi); + if (rv) { + printk(KERN_ERR + "ipmi_si: Unable to create proc entry: %d\n", +@@ -2919,7 +2919,7 @@ static int try_smi_init(struct smi_info *new_smi) + + rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", + param_read_proc, +- new_smi, THIS_MODULE); ++ new_smi); + if (rv) { + printk(KERN_ERR + "ipmi_si: Unable to create proc entry: %d\n", +diff --git a/drivers/input/input.c b/drivers/input/input.c +index 1730d73..ec3db3a 100644 +--- a/drivers/input/input.c ++++ b/drivers/input/input.c +@@ -903,8 +903,6 @@ static int __init input_proc_init(void) + if (!proc_bus_input_dir) + return -ENOMEM; + +- proc_bus_input_dir->owner = THIS_MODULE; +- + entry = proc_create("devices", 0, proc_bus_input_dir, + &input_devices_fileops); + if (!entry) +diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c +index f4969fe..69e71eb 100644 +--- a/drivers/isdn/hardware/eicon/divasi.c ++++ b/drivers/isdn/hardware/eicon/divasi.c +@@ -118,7 +118,6 @@ static int DIVA_INIT_FUNCTION create_um_idi_proc(void) + return (0); + + um_idi_proc_entry->read_proc = um_idi_proc_read; +- um_idi_proc_entry->owner = THIS_MODULE; + + return (1); + } +diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c +index c3b0c8c..43ab0ad 100644 +--- a/drivers/media/video/cpia.c ++++ b/drivers/media/video/cpia.c +@@ -1381,9 +1381,7 @@ static void proc_cpia_create(void) + { + cpia_proc_root = proc_mkdir("cpia", NULL); + +- if (cpia_proc_root) +- cpia_proc_root->owner = THIS_MODULE; +- else ++ if (!cpia_proc_root) + LOG("Unable to initialise /proc/cpia\n"); + } + +diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c +index 9a36b5a..7045c45 100644 +--- a/drivers/message/i2o/i2o_proc.c ++++ b/drivers/message/i2o/i2o_proc.c +@@ -2037,8 +2037,6 @@ static int __init i2o_proc_fs_create(void) + if (!i2o_proc_dir_root) + return -1; + +- i2o_proc_dir_root->owner = THIS_MODULE; +- + list_for_each_entry(c, &i2o_controllers, list) + i2o_proc_iop_add(i2o_proc_dir_root, c); + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 9c326a5..99610f3 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3444,25 +3444,12 @@ static void bond_remove_proc_entry(struct bonding *bond) + */ + static void bond_create_proc_dir(void) + { +- int len = strlen(DRV_NAME); +- +- for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir; +- bond_proc_dir = bond_proc_dir->next) { +- if ((bond_proc_dir->namelen == len) && +- !memcmp(bond_proc_dir->name, DRV_NAME, len)) { +- break; +- } +- } +- + if (!bond_proc_dir) { + bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net); +- if (bond_proc_dir) { +- bond_proc_dir->owner = THIS_MODULE; +- } else { ++ if (!bond_proc_dir) + printk(KERN_WARNING DRV_NAME + ": Warning: cannot create /proc/net/%s\n", + DRV_NAME); +- } + } + } + +@@ -3471,25 +3458,7 @@ static void bond_create_proc_dir(void) + */ + static void bond_destroy_proc_dir(void) + { +- struct proc_dir_entry *de; +- +- if (!bond_proc_dir) { +- return; +- } +- +- /* verify that the /proc dir is empty */ +- for (de = bond_proc_dir->subdir; de; de = de->next) { +- /* ignore . and .. */ +- if (*(de->name) != '.') { +- break; +- } +- } +- +- if (de) { +- if (bond_proc_dir->owner == THIS_MODULE) { +- bond_proc_dir->owner = NULL; +- } +- } else { ++ if (bond_proc_dir) { + remove_proc_entry(DRV_NAME, init_net.proc_net); + bond_proc_dir = NULL; + } +diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c +index 1243bc8..ac0e4b6 100644 +--- a/drivers/net/irda/vlsi_ir.c ++++ b/drivers/net/irda/vlsi_ir.c +@@ -1871,13 +1871,6 @@ static int __init vlsi_mod_init(void) + * without procfs - it's not required for the driver to work. + */ + vlsi_proc_root = proc_mkdir(PROC_DIR, NULL); +- if (vlsi_proc_root) { +- /* protect registered procdir against module removal. +- * Because we are in the module init path there's no race +- * window after create_proc_entry (and no barrier needed). +- */ +- vlsi_proc_root->owner = THIS_MODULE; +- } + + ret = pci_register_driver(&vlsi_irda_driver); + +diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c +index 7e80aba..31b1cc2 100644 +--- a/drivers/net/wireless/airo.c ++++ b/drivers/net/wireless/airo.c +@@ -4494,7 +4494,6 @@ static int setup_proc_entry( struct net_device *dev, + goto fail; + apriv->proc_entry->uid = proc_uid; + apriv->proc_entry->gid = proc_gid; +- apriv->proc_entry->owner = THIS_MODULE; + + /* Setup the StatsDelta */ + entry = proc_create_data("StatsDelta", +diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c +index d63f26e..ba1f749 100644 +--- a/drivers/platform/x86/asus_acpi.c ++++ b/drivers/platform/x86/asus_acpi.c +@@ -987,7 +987,6 @@ asus_proc_add(char *name, proc_writefunc *writefunc, + proc->write_proc = writefunc; + proc->read_proc = readfunc; + proc->data = acpi_driver_data(device); +- proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid; + return 0; +@@ -1020,7 +1019,6 @@ static int asus_hotk_add_fs(struct acpi_device *device) + if (proc) { + proc->read_proc = proc_read_info; + proc->data = acpi_driver_data(device); +- proc->owner = THIS_MODULE; + proc->uid = asus_uid; + proc->gid = asus_gid; + } else { +@@ -1436,7 +1434,6 @@ static int __init asus_acpi_init(void) + printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); + return -ENODEV; + } +- asus_proc_dir->owner = THIS_MODULE; + + result = acpi_bus_register_driver(&asus_hotk_driver); + if (result < 0) { +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index d243320..3dad27a 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -6992,7 +6992,6 @@ static int __init ibm_init(struct ibm_init_struct *iibm) + ret = -ENODEV; + goto err_out; + } +- entry->owner = THIS_MODULE; + entry->data = ibm; + entry->read_proc = &dispatch_procfs_read; + if (ibm->write) +@@ -7405,7 +7404,6 @@ static int __init thinkpad_acpi_module_init(void) + thinkpad_acpi_module_exit(); + return -ENODEV; + } +- proc_dir->owner = THIS_MODULE; + + ret = platform_driver_register(&tpacpi_pdriver); + if (ret) { +diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c +index 40e60fc..9f18726 100644 +--- a/drivers/platform/x86/toshiba_acpi.c ++++ b/drivers/platform/x86/toshiba_acpi.c +@@ -679,8 +679,6 @@ static acpi_status __init add_device(void) + toshiba_proc_dir, + (read_proc_t *) dispatch_read, + item); +- if (proc) +- proc->owner = THIS_MODULE; + if (proc && item->write_func) + proc->write_proc = (write_proc_t *) dispatch_write; + } +@@ -772,7 +770,6 @@ static int __init toshiba_acpi_init(void) + toshiba_acpi_exit(); + return -ENODEV; + } else { +- toshiba_proc_dir->owner = THIS_MODULE; + status = add_device(); + if (ACPI_FAILURE(status)) { + toshiba_acpi_exit(); +diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c +index 0c6257a..c086fc3 100644 +--- a/drivers/rtc/rtc-proc.c ++++ b/drivers/rtc/rtc-proc.c +@@ -105,14 +105,8 @@ static const struct file_operations rtc_proc_fops = { + + void rtc_proc_add_device(struct rtc_device *rtc) + { +- if (rtc->id == 0) { +- struct proc_dir_entry *ent; +- +- ent = proc_create_data("driver/rtc", 0, NULL, +- &rtc_proc_fops, rtc); +- if (ent) +- ent->owner = rtc->owner; +- } ++ if (rtc->id == 0) ++ proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc); + } + + void rtc_proc_del_device(struct rtc_device *rtc) +diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c +index 2080ba6..654daa3 100644 +--- a/drivers/s390/block/dasd_proc.c ++++ b/drivers/s390/block/dasd_proc.c +@@ -320,7 +320,6 @@ dasd_proc_init(void) + dasd_proc_root_entry = proc_mkdir("dasd", NULL); + if (!dasd_proc_root_entry) + goto out_nodasd; +- dasd_proc_root_entry->owner = THIS_MODULE; + dasd_devices_entry = proc_create("devices", + S_IFREG | S_IRUGO | S_IWUSR, + dasd_proc_root_entry, +@@ -334,7 +333,6 @@ dasd_proc_init(void) + goto out_nostatistics; + dasd_statistics_entry->read_proc = dasd_statistics_read; + dasd_statistics_entry->write_proc = dasd_statistics_write; +- dasd_statistics_entry->owner = THIS_MODULE; + return 0; + + out_nostatistics: +diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c +index 099b545..b134813 100644 +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -596,8 +596,6 @@ int __init scsi_init_devinfo(void) + error = -ENOMEM; + goto out; + } +- +- p->owner = THIS_MODULE; + #endif /* CONFIG_SCSI_PROC_FS */ + + out: +diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c +index 82f7b2d..77fbddb 100644 +--- a/drivers/scsi/scsi_proc.c ++++ b/drivers/scsi/scsi_proc.c +@@ -115,8 +115,6 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht) + if (!sht->proc_dir) + printk(KERN_ERR "%s: proc_mkdir failed for %s\n", + __func__, sht->proc_name); +- else +- sht->proc_dir->owner = sht->module; + } + mutex_unlock(&global_host_template_mutex); + } +@@ -163,7 +161,6 @@ void scsi_proc_host_add(struct Scsi_Host *shost) + } + + p->write_proc = proc_scsi_write_proc; +- p->owner = sht->module; + } + + /** +diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c +index 37b433a..e327b84 100644 +--- a/drivers/video/via/viafbdev.c ++++ b/drivers/video/via/viafbdev.c +@@ -2059,25 +2059,21 @@ static void viafb_init_proc(struct proc_dir_entry **viafb_entry) + if (viafb_entry) { + entry = create_proc_entry("dvp0", 0, *viafb_entry); + if (entry) { +- entry->owner = THIS_MODULE; + entry->read_proc = viafb_dvp0_proc_read; + entry->write_proc = viafb_dvp0_proc_write; + } + entry = create_proc_entry("dvp1", 0, *viafb_entry); + if (entry) { +- entry->owner = THIS_MODULE; + entry->read_proc = viafb_dvp1_proc_read; + entry->write_proc = viafb_dvp1_proc_write; + } + entry = create_proc_entry("dfph", 0, *viafb_entry); + if (entry) { +- entry->owner = THIS_MODULE; + entry->read_proc = viafb_dfph_proc_read; + entry->write_proc = viafb_dfph_proc_write; + } + entry = create_proc_entry("dfpl", 0, *viafb_entry); + if (entry) { +- entry->owner = THIS_MODULE; + entry->read_proc = viafb_dfpl_proc_read; + entry->write_proc = viafb_dfpl_proc_write; + } +@@ -2086,7 +2082,6 @@ static void viafb_init_proc(struct proc_dir_entry **viafb_entry) + viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { + entry = create_proc_entry("vt1636", 0, *viafb_entry); + if (entry) { +- entry->owner = THIS_MODULE; + entry->read_proc = viafb_vt1636_proc_read; + entry->write_proc = viafb_vt1636_proc_write; + } +diff --git a/fs/afs/proc.c b/fs/afs/proc.c +index 7578c1a..8630615 100644 +--- a/fs/afs/proc.c ++++ b/fs/afs/proc.c +@@ -146,7 +146,6 @@ int afs_proc_init(void) + proc_afs = proc_mkdir("fs/afs", NULL); + if (!proc_afs) + goto error_dir; +- proc_afs->owner = THIS_MODULE; + + p = proc_create("cells", 0, proc_afs, &afs_proc_cells_fops); + if (!p) +diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c +index 877e4d9..7f19fef 100644 +--- a/fs/cifs/cifs_debug.c ++++ b/fs/cifs/cifs_debug.c +@@ -404,7 +404,6 @@ cifs_proc_init(void) + if (proc_fs_cifs == NULL) + return; + +- proc_fs_cifs->owner = THIS_MODULE; + proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops); + + #ifdef CONFIG_CIFS_STATS +diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c +index 6a73de8..dd824d9 100644 +--- a/fs/jfs/jfs_debug.c ++++ b/fs/jfs/jfs_debug.c +@@ -90,7 +90,6 @@ void jfs_proc_init(void) + + if (!(base = proc_mkdir("fs/jfs", NULL))) + return; +- base->owner = THIS_MODULE; + + for (i = 0; i < NPROCENT; i++) + proc_create(Entries[i].name, 0, base, Entries[i].proc_fops); +diff --git a/fs/nfs/client.c b/fs/nfs/client.c +index 574158a..2277421 100644 +--- a/fs/nfs/client.c ++++ b/fs/nfs/client.c +@@ -1606,8 +1606,6 @@ int __init nfs_fs_proc_init(void) + if (!proc_fs_nfs) + goto error_0; + +- proc_fs_nfs->owner = THIS_MODULE; +- + /* a file of servers with which we're dealing */ + p = proc_create("servers", S_IFREG|S_IRUGO, + proc_fs_nfs, &nfs_server_list_fops); +diff --git a/fs/proc/inode.c b/fs/proc/inode.c +index e11dc22..d78ade3 100644 +--- a/fs/proc/inode.c ++++ b/fs/proc/inode.c +@@ -58,11 +58,8 @@ static void proc_delete_inode(struct inode *inode) + + /* Let go of any associated proc directory entry */ + de = PROC_I(inode)->pde; +- if (de) { +- if (de->owner) +- module_put(de->owner); ++ if (de) + de_put(de); +- } + if (PROC_I(inode)->sysctl) + sysctl_head_put(PROC_I(inode)->sysctl); + clear_inode(inode); +@@ -449,12 +446,9 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, + { + struct inode * inode; + +- if (!try_module_get(de->owner)) +- goto out_mod; +- + inode = iget_locked(sb, ino); + if (!inode) +- goto out_ino; ++ return NULL; + if (inode->i_state & I_NEW) { + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + PROC_I(inode)->fd = 0; +@@ -485,16 +479,9 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, + } + } + unlock_new_inode(inode); +- } else { +- module_put(de->owner); ++ } else + de_put(de); +- } + return inode; +- +-out_ino: +- module_put(de->owner); +-out_mod: +- return NULL; + } + + int proc_fill_super(struct super_block *s) +diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c +index d153946..4a9e0f6 100644 +--- a/fs/proc/proc_tty.c ++++ b/fs/proc/proc_tty.c +@@ -152,7 +152,6 @@ void proc_tty_register_driver(struct tty_driver *driver) + if (!ent) + return; + ent->read_proc = driver->ops->read_proc; +- ent->owner = driver->owner; + ent->data = driver; + + driver->proc_entry = ent; +diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c +index d506640..9229e55 100644 +--- a/fs/reiserfs/procfs.c ++++ b/fs/reiserfs/procfs.c +@@ -492,7 +492,6 @@ int reiserfs_proc_info_init(struct super_block *sb) + spin_lock_init(&__PINFO(sb).lock); + REISERFS_SB(sb)->procdir = proc_mkdir(b, proc_info_root); + if (REISERFS_SB(sb)->procdir) { +- REISERFS_SB(sb)->procdir->owner = THIS_MODULE; + REISERFS_SB(sb)->procdir->data = sb; + add_file(sb, "version", show_version); + add_file(sb, "super", show_super); +@@ -556,9 +555,7 @@ int reiserfs_proc_info_global_init(void) + { + if (proc_info_root == NULL) { + proc_info_root = proc_mkdir(proc_info_root_name, NULL); +- if (proc_info_root) { +- proc_info_root->owner = THIS_MODULE; +- } else { ++ if (!proc_info_root) { + reiserfs_warning(NULL, "cannot create /proc/%s", + proc_info_root_name); + return 1; +diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h +index 62b7366..f7c9c75 100644 +--- a/include/linux/ipmi_smi.h ++++ b/include/linux/ipmi_smi.h +@@ -230,6 +230,6 @@ static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg) + automatically be dstroyed when the interface is destroyed. */ + int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, + read_proc_t *read_proc, +- void *data, struct module *owner); ++ void *data); + + #endif /* __LINUX_IPMI_SMI_H */ +diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h +index b8bdb96..fbfa3d4 100644 +--- a/include/linux/proc_fs.h ++++ b/include/linux/proc_fs.h +@@ -41,9 +41,6 @@ enum { + * while parent/subdir create the directory structure (every + * /proc file has a parent, but "subdir" is NULL for all + * non-directory entries). +- * +- * "owner" is used to protect module +- * from unloading while proc_dir_entry is in use + */ + + typedef int (read_proc_t)(char *page, char **start, off_t off, +@@ -70,7 +67,6 @@ struct proc_dir_entry { + * somewhere. + */ + const struct file_operations *proc_fops; +- struct module *owner; + struct proc_dir_entry *next, *parent, *subdir; + void *data; + read_proc_t *read_proc; +diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c +index 162199a..fd8e084 100644 +--- a/net/appletalk/atalk_proc.c ++++ b/net/appletalk/atalk_proc.c +@@ -281,7 +281,6 @@ int __init atalk_proc_init(void) + atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net); + if (!atalk_proc_dir) + goto out; +- atalk_proc_dir->owner = THIS_MODULE; + + p = proc_create("interface", S_IRUGO, atalk_proc_dir, + &atalk_seq_interface_fops); +diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c +index 4990541..1a0f5cc 100644 +--- a/net/atm/mpoa_proc.c ++++ b/net/atm/mpoa_proc.c +@@ -281,7 +281,6 @@ int mpc_proc_init(void) + printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME); + return -ENOMEM; + } +- p->owner = THIS_MODULE; + return 0; + } + +diff --git a/net/atm/proc.c b/net/atm/proc.c +index 49487b3..e7b3b27 100644 +--- a/net/atm/proc.c ++++ b/net/atm/proc.c +@@ -476,7 +476,6 @@ int __init atm_proc_init(void) + atm_proc_root, e->proc_fops); + if (!dirent) + goto err_out_remove; +- dirent->owner = THIS_MODULE; + e->dirent = dirent; + } + ret = 0; +diff --git a/net/can/bcm.c b/net/can/bcm.c +index b7c7d46..95d7f32 100644 +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -1604,10 +1604,6 @@ static int __init bcm_module_init(void) + + /* create /proc/net/can-bcm directory */ + proc_dir = proc_mkdir("can-bcm", init_net.proc_net); +- +- if (proc_dir) +- proc_dir->owner = THIS_MODULE; +- + return 0; + } + +diff --git a/net/can/proc.c b/net/can/proc.c +index 520fef5..1463653 100644 +--- a/net/can/proc.c ++++ b/net/can/proc.c +@@ -473,8 +473,6 @@ void can_init_proc(void) + return; + } + +- can_dir->owner = THIS_MODULE; +- + /* own procfs entries from the AF_CAN core */ + pde_version = can_create_proc_readentry(CAN_PROC_VERSION, 0644, + can_proc_read_version, NULL); +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index 32d419f..3779c14 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -3806,7 +3806,6 @@ static int __init pg_init(void) + pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net); + if (!pg_proc_dir) + return -ENODEV; +- pg_proc_dir->owner = THIS_MODULE; + + pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops); + if (pe == NULL) { +diff --git a/net/irda/irproc.c b/net/irda/irproc.c +index 88e80a3..8ff1861 100644 +--- a/net/irda/irproc.c ++++ b/net/irda/irproc.c +@@ -70,7 +70,6 @@ void __init irda_proc_register(void) + proc_irda = proc_mkdir("irda", init_net.proc_net); + if (proc_irda == NULL) + return; +- proc_irda->owner = THIS_MODULE; + + for (i = 0; i < ARRAY_SIZE(irda_dirs); i++) + d = proc_create(irda_dirs[i].name, 0, proc_irda, +diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c +index b58bd7c..d208b33 100644 +--- a/net/llc/llc_proc.c ++++ b/net/llc/llc_proc.c +@@ -236,7 +236,6 @@ int __init llc_proc_init(void) + llc_proc_dir = proc_mkdir("llc", init_net.proc_net); + if (!llc_proc_dir) + goto out; +- llc_proc_dir->owner = THIS_MODULE; + + p = proc_create("socket", S_IRUGO, llc_proc_dir, &llc_seq_socket_fops); + if (!p) +diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c +index cb198af..8eb3e61 100644 +--- a/net/sctp/protocol.c ++++ b/net/sctp/protocol.c +@@ -106,12 +106,8 @@ static __init int sctp_proc_init(void) + goto out_nomem; + #ifdef CONFIG_PROC_FS + if (!proc_net_sctp) { +- struct proc_dir_entry *ent; +- ent = proc_mkdir("sctp", init_net.proc_net); +- if (ent) { +- ent->owner = THIS_MODULE; +- proc_net_sctp = ent; +- } else ++ proc_net_sctp = proc_mkdir("sctp", init_net.proc_net); ++ if (!proc_net_sctp) + goto out_free_percpu; + } + +diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c +index 4735caa..20029a7 100644 +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -313,7 +313,6 @@ static int create_cache_proc_entries(struct cache_detail *cd) + cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); + if (cd->proc_ent == NULL) + goto out_nomem; +- cd->proc_ent->owner = cd->owner; + cd->channel_ent = cd->content_ent = NULL; + + p = proc_create_data("flush", S_IFREG|S_IRUSR|S_IWUSR, +@@ -321,7 +320,6 @@ static int create_cache_proc_entries(struct cache_detail *cd) + cd->flush_ent = p; + if (p == NULL) + goto out_nomem; +- p->owner = cd->owner; + + if (cd->cache_request || cd->cache_parse) { + p = proc_create_data("channel", S_IFREG|S_IRUSR|S_IWUSR, +@@ -329,7 +327,6 @@ static int create_cache_proc_entries(struct cache_detail *cd) + cd->channel_ent = p; + if (p == NULL) + goto out_nomem; +- p->owner = cd->owner; + } + if (cd->cache_show) { + p = proc_create_data("content", S_IFREG|S_IRUSR|S_IWUSR, +@@ -337,7 +334,6 @@ static int create_cache_proc_entries(struct cache_detail *cd) + cd->content_ent = p; + if (p == NULL) + goto out_nomem; +- p->owner = cd->owner; + } + return 0; + out_nomem: +diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c +index 085372e..1ef6e46 100644 +--- a/net/sunrpc/stats.c ++++ b/net/sunrpc/stats.c +@@ -262,14 +262,8 @@ void + rpc_proc_init(void) + { + dprintk("RPC: registering /proc/net/rpc\n"); +- if (!proc_net_rpc) { +- struct proc_dir_entry *ent; +- ent = proc_mkdir("rpc", init_net.proc_net); +- if (ent) { +- ent->owner = THIS_MODULE; +- proc_net_rpc = ent; +- } +- } ++ if (!proc_net_rpc) ++ proc_net_rpc = proc_mkdir("rpc", init_net.proc_net); + } + + void +diff --git a/sound/core/info.c b/sound/core/info.c +index 70fa871..35df614 100644 +--- a/sound/core/info.c ++++ b/sound/core/info.c +@@ -154,11 +154,6 @@ EXPORT_SYMBOL(snd_seq_root); + struct snd_info_entry *snd_oss_root; + #endif + +-static inline void snd_info_entry_prepare(struct proc_dir_entry *de) +-{ +- de->owner = THIS_MODULE; +-} +- + static void snd_remove_proc_entry(struct proc_dir_entry *parent, + struct proc_dir_entry *de) + { +@@ -522,32 +517,11 @@ static const struct file_operations snd_info_entry_operations = + .release = snd_info_entry_release, + }; + +-/** +- * snd_create_proc_entry - create a procfs entry +- * @name: the name of the proc file +- * @mode: the file permission bits, S_Ixxx +- * @parent: the parent proc-directory entry +- * +- * Creates a new proc file entry with the given name and permission +- * on the given directory. +- * +- * Returns the pointer of new instance or NULL on failure. +- */ +-static struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode, +- struct proc_dir_entry *parent) +-{ +- struct proc_dir_entry *p; +- p = create_proc_entry(name, mode, parent); +- if (p) +- snd_info_entry_prepare(p); +- return p; +-} +- + int __init snd_info_init(void) + { + struct proc_dir_entry *p; + +- p = snd_create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); ++ p = create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL); + if (p == NULL) + return -ENOMEM; + snd_proc_root = p; +@@ -974,12 +948,11 @@ int snd_info_register(struct snd_info_entry * entry) + return -ENXIO; + root = entry->parent == NULL ? snd_proc_root : entry->parent->p; + mutex_lock(&info_mutex); +- p = snd_create_proc_entry(entry->name, entry->mode, root); ++ p = create_proc_entry(entry->name, entry->mode, root); + if (!p) { + mutex_unlock(&info_mutex); + return -ENOMEM; + } +- p->owner = entry->module; + if (!S_ISDIR(entry->mode)) + p->proc_fops = &snd_info_entry_operations; + p->size = entry->size; +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0003-thinkpad-acpi-update-copyright-notices.patch b/releases/upstream/2.6.30-rc1/0003-thinkpad-acpi-update-copyright-notices.patch new file mode 100644 index 00000000000..1bdaa8bc0a9 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0003-thinkpad-acpi-update-copyright-notices.patch @@ -0,0 +1,29 @@ +From 1c762ca438447fa3525d84f4a0784a2021a66200 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:42 +0000 +Subject: thinkpad-acpi: update copyright notices + +It is that time of the year again... + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + drivers/platform/x86/thinkpad_acpi.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index d243320..792d22e 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -3,7 +3,7 @@ + * + * + * Copyright (C) 2004-2005 Borislav Deianov +- * Copyright (C) 2006-2008 Henrique de Moraes Holschuh ++ * Copyright (C) 2006-2009 Henrique de Moraes Holschuh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0004-thinkpad-acpi-drop-ibm-acpi-alias.patch b/releases/upstream/2.6.30-rc1/0004-thinkpad-acpi-drop-ibm-acpi-alias.patch new file mode 100644 index 00000000000..38c210e21f1 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0004-thinkpad-acpi-drop-ibm-acpi-alias.patch @@ -0,0 +1,32 @@ +From 257bc1cb3e29c8da62b9c9e0a4505011776c7040 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:43 +0000 +Subject: thinkpad-acpi: drop ibm-acpi alias + +The driver was renamed two years ago, on 2.6.21. Drop the old +compatibility alias, we have given everybody quite enough time +to update their configs to the new name. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + drivers/platform/x86/thinkpad_acpi.c | 3 --- + 1 files changed, 0 insertions(+), 3 deletions(-) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 792d22e..c83ec94 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -7517,9 +7517,6 @@ static int __init thinkpad_acpi_module_init(void) + return 0; + } + +-/* Please remove this in year 2009 */ +-MODULE_ALIAS("ibm_acpi"); +- + MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); + + /* +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0005-thinkpad-acpi-documentation-cleanup.patch b/releases/upstream/2.6.30-rc1/0005-thinkpad-acpi-documentation-cleanup.patch new file mode 100644 index 00000000000..1c6c4ad9c76 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0005-thinkpad-acpi-documentation-cleanup.patch @@ -0,0 +1,301 @@ +From 078ac19ed8f476a7c2d729712e15f5ab516ff491 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:44 +0000 +Subject: thinkpad-acpi: documentation cleanup + +Some cleanups to the documentation of the driver. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 76 +++++++++++++++++++++---------- + 1 files changed, 52 insertions(+), 24 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index 41bc99f..f6e6bc6 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -20,7 +20,8 @@ moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel + kernel 2.6.29 and release 0.22. + + The driver is named "thinkpad-acpi". In some places, like module +-names, "thinkpad_acpi" is used because of userspace issues. ++names and log messages, "thinkpad_acpi" is used because of userspace ++issues. + + "tpacpi" is used as a shorthand where "thinkpad-acpi" would be too + long due to length limitations on some Linux kernel versions. +@@ -37,7 +38,7 @@ detailed description): + - ThinkLight on and off + - limited docking and undocking + - UltraBay eject +- - CMOS control ++ - CMOS/UCMS control + - LED control + - ACPI sounds + - temperature sensors +@@ -46,6 +47,7 @@ detailed description): + - Volume control + - Fan control and monitoring: fan speed, fan enable/disable + - WAN enable and disable ++ - UWB enable and disable + + A compatibility table by model and feature is maintained on the web + site, http://ibm-acpi.sf.net/. I appreciate any success or failure +@@ -53,7 +55,7 @@ reports, especially if they add to or correct the compatibility table. + Please include the following information in your report: + + - ThinkPad model name +- - a copy of your DSDT, from /proc/acpi/dsdt ++ - a copy of your ACPI tables, using the "acpidump" utility + - a copy of the output of dmidecode, with serial numbers + and UUIDs masked off + - which driver features work and which don't +@@ -66,17 +68,18 @@ Installation + ------------ + + If you are compiling this driver as included in the Linux kernel +-sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally +-enable the CONFIG_THINKPAD_ACPI_BAY option if you want the +-thinkpad-specific bay functionality. ++sources, look for the CONFIG_THINKPAD_ACPI Kconfig option. ++It is located on the menu path: "Device Drivers" -> "X86 Platform ++Specific Device Drivers" -> "ThinkPad ACPI Laptop Extras". ++ + + Features + -------- + + The driver exports two different interfaces to userspace, which can be + used to access the features it provides. One is a legacy procfs-based +-interface, which will be removed at some time in the distant future. +-The other is a new sysfs-based interface which is not complete yet. ++interface, which will be removed at some time in the future. The other ++is a new sysfs-based interface which is not complete yet. + + The procfs interface creates the /proc/acpi/ibm directory. There is a + file under that directory for each feature it supports. The procfs +@@ -111,15 +114,17 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver + as a driver attribute (see below). + + Sysfs driver attributes are on the driver's sysfs attribute space, +-for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and ++for 2.6.23+ this is /sys/bus/platform/drivers/thinkpad_acpi/ and + /sys/bus/platform/drivers/thinkpad_hwmon/ + + Sysfs device attributes are on the thinkpad_acpi device sysfs attribute +-space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/. ++space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/. + + Sysfs device attributes for the sensors and fan are on the + thinkpad_hwmon device's sysfs attribute space, but you should locate it +-looking for a hwmon device with the name attribute of "thinkpad". ++looking for a hwmon device with the name attribute of "thinkpad", or ++better yet, through libsensors. ++ + + Driver version + -------------- +@@ -129,6 +134,7 @@ sysfs driver attribute: version + + The driver name and version. No commands can be written to this file. + ++ + Sysfs interface version + ----------------------- + +@@ -160,6 +166,7 @@ expect that an attribute might not be there, and deal with it properly + (an attribute not being there *is* a valid way to make it clear that a + feature is not available in sysfs). + ++ + Hot keys + -------- + +@@ -618,6 +625,7 @@ For Lenovo models *with* ACPI backlight control: + and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process + these keys on userspace somehow (e.g. by calling xbacklight). + ++ + Bluetooth + --------- + +@@ -628,6 +636,9 @@ sysfs rfkill class: switch "tpacpi_bluetooth_sw" + This feature shows the presence and current state of a ThinkPad + Bluetooth device in the internal ThinkPad CDC slot. + ++If the ThinkPad supports it, the Bluetooth state is stored in NVRAM, ++so it is kept across reboots and power-off. ++ + Procfs notes: + + If Bluetooth is installed, the following commands can be used: +@@ -652,6 +663,7 @@ Sysfs notes: + rfkill controller switch "tpacpi_bluetooth_sw": refer to + Documentation/rfkill.txt for details. + ++ + Video output control -- /proc/acpi/ibm/video + -------------------------------------------- + +@@ -693,11 +705,8 @@ Fn-F7 from working. This also disables the video output switching + features of this driver, as it uses the same ACPI methods as + Fn-F7. Video switching on the console should still work. + +-UPDATE: There's now a patch for the X.org Radeon driver which +-addresses this issue. Some people are reporting success with the patch +-while others are still having problems. For more information: ++UPDATE: refer to https://bugs.freedesktop.org/show_bug.cgi?id=2000 + +-https://bugs.freedesktop.org/show_bug.cgi?id=2000 + + ThinkLight control + ------------------ +@@ -720,10 +729,11 @@ The ThinkLight sysfs interface is documented by the LED class + documentation, in Documentation/leds-class.txt. The ThinkLight LED name + is "tpacpi::thinklight". + +-Due to limitations in the sysfs LED class, if the status of the thinklight ++Due to limitations in the sysfs LED class, if the status of the ThinkLight + cannot be read or if it is unknown, thinkpad-acpi will report it as "off". + It is impossible to know if the status returned through sysfs is valid. + ++ + Docking / undocking -- /proc/acpi/ibm/dock + ------------------------------------------ + +@@ -784,6 +794,7 @@ the only docking stations currently supported are the X-series + UltraBase docks and "dumb" port replicators like the Mini Dock (the + latter don't need any ACPI support, actually). + ++ + UltraBay eject -- /proc/acpi/ibm/bay + ------------------------------------ + +@@ -847,8 +858,9 @@ supported. Use "eject2" instead of "eject" for the second bay. + Note: the UltraBay eject support on the 600e/x, A22p and A3x is + EXPERIMENTAL and may not work as expected. USE WITH CAUTION! + +-CMOS control +------------- ++ ++CMOS/UCMS control ++----------------- + + procfs: /proc/acpi/ibm/cmos + sysfs device attribute: cmos_command +@@ -882,6 +894,7 @@ The cmos command interface is prone to firmware split-brain problems, as + in newer ThinkPads it is just a compatibility layer. Do not use it, it is + exported just as a debug tool. + ++ + LED control + ----------- + +@@ -939,6 +952,7 @@ ThinkPad indicator LED should blink in hardware accelerated mode, use the + "timer" trigger, and leave the delay_on and delay_off parameters set to + zero (to request hardware acceleration autodetection). + ++ + ACPI sounds -- /proc/acpi/ibm/beep + ---------------------------------- + +@@ -968,6 +982,7 @@ X40: + 16 - one medium-pitched beep repeating constantly, stop with 17 + 17 - stop 16 + ++ + Temperature sensors + ------------------- + +@@ -1115,6 +1130,7 @@ registers contain the current battery capacity, etc. If you experiment + with this, do send me your results (including some complete dumps with + a description of the conditions when they were taken.) + ++ + LCD brightness control + ---------------------- + +@@ -1124,10 +1140,9 @@ sysfs backlight device "thinkpad_screen" + This feature allows software control of the LCD brightness on ThinkPad + models which don't have a hardware brightness slider. + +-It has some limitations: the LCD backlight cannot be actually turned on or +-off by this interface, and in many ThinkPad models, the "dim while on +-battery" functionality will be enabled by the BIOS when this interface is +-used, and cannot be controlled. ++It has some limitations: the LCD backlight cannot be actually turned ++on or off by this interface, it just controls the backlight brightness ++level. + + On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control + has eight brightness levels, ranging from 0 to 7. Some of the levels +@@ -1201,6 +1216,7 @@ WARNING: + and maybe reduce the life of the backlight lamps by needlessly kicking + its level up and down at every change. + ++ + Volume control -- /proc/acpi/ibm/volume + --------------------------------------- + +@@ -1217,6 +1233,11 @@ distinct. The unmute the volume after the mute command, use either the + up or down command (the level command will not unmute the volume). + The current volume level and mute state is shown in the file. + ++The ALSA mixer interface to this feature is still missing, but patches ++to add it exist. That problem should be addressed in the not so ++distant future. ++ ++ + Fan control and monitoring: fan speed, fan enable/disable + --------------------------------------------------------- + +@@ -1383,8 +1404,11 @@ procfs: /proc/acpi/ibm/wan + sysfs device attribute: wwan_enable (deprecated) + sysfs rfkill class: switch "tpacpi_wwan_sw" + +-This feature shows the presence and current state of a W-WAN (Sierra +-Wireless EV-DO) device. ++This feature shows the presence and current state of the built-in ++Wireless WAN device. ++ ++If the ThinkPad supports it, the WWAN state is stored in NVRAM, ++so it is kept across reboots and power-off. + + It was tested on a Lenovo ThinkPad X60. It should probably work on other + ThinkPad models which come with this module installed. +@@ -1413,6 +1437,7 @@ Sysfs notes: + rfkill controller switch "tpacpi_wwan_sw": refer to + Documentation/rfkill.txt for details. + ++ + EXPERIMENTAL: UWB + ----------------- + +@@ -1431,6 +1456,7 @@ Sysfs notes: + rfkill controller switch "tpacpi_uwb_sw": refer to + Documentation/rfkill.txt for details. + ++ + Multiple Commands, Module Parameters + ------------------------------------ + +@@ -1445,6 +1471,7 @@ for example: + + modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable + ++ + Enabling debugging output + ------------------------- + +@@ -1467,6 +1494,7 @@ The level of debugging information output by the driver can be changed + at runtime through sysfs, using the driver attribute debug_level. The + attribute takes the same bitmask as the debug module parameter above. + ++ + Force loading of module + ----------------------- + +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0006-thinkpad-acpi-cleanup-debug-helpers.patch b/releases/upstream/2.6.30-rc1/0006-thinkpad-acpi-cleanup-debug-helpers.patch new file mode 100644 index 00000000000..4ad47593de7 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0006-thinkpad-acpi-cleanup-debug-helpers.patch @@ -0,0 +1,68 @@ +From 3dcc2c3b00cad01a0e3667607f8644e891e4dc8b Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:45 +0000 +Subject: thinkpad-acpi: cleanup debug helpers + +Fix the vdbg_printk macro definition to be sane when +CONFIG_THINKPAD_ACPI_DEBUG is undefined, and move the mess into a file +section of its own. + +This doesn't change anything in the current code, but future code will +need the proper behaviour. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + drivers/platform/x86/thinkpad_acpi.c | 29 ++++++++++++++++++----------- + 1 files changed, 18 insertions(+), 11 deletions(-) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index c83ec94..3367df9 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -184,17 +184,6 @@ enum { + #define TPACPI_DBG_ALL 0xffff + #define TPACPI_DBG_INIT 0x0001 + #define TPACPI_DBG_EXIT 0x0002 +-#define dbg_printk(a_dbg_level, format, arg...) \ +- do { if (dbg_level & a_dbg_level) \ +- printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ +- } while (0) +-#ifdef CONFIG_THINKPAD_ACPI_DEBUG +-#define vdbg_printk(a_dbg_level, format, arg...) \ +- dbg_printk(a_dbg_level, format, ## arg) +-static const char *str_supported(int is_supported); +-#else +-#define vdbg_printk(a_dbg_level, format, arg...) +-#endif + + #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") + #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") +@@ -326,6 +315,24 @@ static int tpacpi_uwb_emulstate; + #endif + + ++/************************************************************************* ++ * Debugging helpers ++ */ ++ ++#define dbg_printk(a_dbg_level, format, arg...) \ ++ do { if (dbg_level & (a_dbg_level)) \ ++ printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ ++ } while (0) ++ ++#ifdef CONFIG_THINKPAD_ACPI_DEBUG ++#define vdbg_printk dbg_printk ++static const char *str_supported(int is_supported); ++#else ++#define vdbg_printk(a_dbg_level, format, arg...) \ ++ do { } while (0) ++#endif ++ ++ + /**************************************************************************** + **************************************************************************** + * +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0007-thinkpad-acpi-add-missing-log-levels.patch b/releases/upstream/2.6.30-rc1/0007-thinkpad-acpi-add-missing-log-levels.patch new file mode 100644 index 00000000000..af07bb20484 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0007-thinkpad-acpi-add-missing-log-levels.patch @@ -0,0 +1,49 @@ +From 7ff8d62f7f055aaffbeb493863136c1b876bbe2e Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:46 +0000 +Subject: thinkpad-acpi: add missing log levels + +Add missing log levels in a standalone commit, to avoid dependencies in +future unrelated changes, just because they wanted to use one of the +missing log levels. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + drivers/platform/x86/thinkpad_acpi.c | 19 +++++++++++-------- + 1 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 3367df9..6331b88 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -172,15 +172,18 @@ enum { + TPACPI_RFK_UWB_SW_ID, + }; + +-/* Debugging */ ++/* printk headers */ + #define TPACPI_LOG TPACPI_FILE ": " +-#define TPACPI_ALERT KERN_ALERT TPACPI_LOG +-#define TPACPI_CRIT KERN_CRIT TPACPI_LOG +-#define TPACPI_ERR KERN_ERR TPACPI_LOG +-#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG +-#define TPACPI_INFO KERN_INFO TPACPI_LOG +-#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG +- ++#define TPACPI_EMERG KERN_EMERG TPACPI_LOG ++#define TPACPI_ALERT KERN_ALERT TPACPI_LOG ++#define TPACPI_CRIT KERN_CRIT TPACPI_LOG ++#define TPACPI_ERR KERN_ERR TPACPI_LOG ++#define TPACPI_WARN KERN_WARNING TPACPI_LOG ++#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG ++#define TPACPI_INFO KERN_INFO TPACPI_LOG ++#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG ++ ++/* Debugging printk groups */ + #define TPACPI_DBG_ALL 0xffff + #define TPACPI_DBG_INIT 0x0001 + #define TPACPI_DBG_EXIT 0x0002 +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0008-thinkpad-acpi-add-new-debug-helpers-and-warn-of-dep.patch b/releases/upstream/2.6.30-rc1/0008-thinkpad-acpi-add-new-debug-helpers-and-warn-of-dep.patch new file mode 100644 index 00000000000..76a88910484 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0008-thinkpad-acpi-add-new-debug-helpers-and-warn-of-dep.patch @@ -0,0 +1,139 @@ +From 73a94d86a8625371f76de0ee12dc5bacd3ed42c0 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:47 +0000 +Subject: thinkpad-acpi: add new debug helpers and warn of deprecated atts + +Add a debug helper that discloses the TGID of the userspace task +attempting to access the driver. This is highly useful when dealing +with bug reports, since often the user has no idea that some userspace +application is accessing thinkpad-acpi... + +Also add a helper to log warnings about sysfs attributes that are +deprecated. + +Use the new helpers to issue deprecation warnings for bluetooth_enable +and wwan_enabled, that have been deprecated for a while, now. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 2 + + drivers/platform/x86/thinkpad_acpi.c | 40 +++++++++++++++++++++++++++++++ + 2 files changed, 42 insertions(+), 0 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index f6e6bc6..e8f52fb 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -1484,6 +1484,8 @@ will enable all debugging output classes. It takes a bitmask, so + to enable more than one output class, just add their values. + + Debug bitmask Description ++ 0x8000 Disclose PID of userspace programs ++ accessing some functions of the driver + 0x0001 Initialization and probing + 0x0002 Removal + +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 6331b88..852be7c 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -185,6 +186,7 @@ enum { + + /* Debugging printk groups */ + #define TPACPI_DBG_ALL 0xffff ++#define TPACPI_DBG_DISCLOSETASK 0x8000 + #define TPACPI_DBG_INIT 0x0001 + #define TPACPI_DBG_EXIT 0x0002 + +@@ -335,6 +337,21 @@ static const char *str_supported(int is_supported); + do { } while (0) + #endif + ++static void tpacpi_log_usertask(const char * const what) ++{ ++ printk(TPACPI_DEBUG "%s: access by process with PID %d\n", ++ what, task_tgid_vnr(current)); ++} ++ ++#define tpacpi_disclose_usertask(what, format, arg...) \ ++ do { \ ++ if (unlikely( \ ++ (dbg_level & TPACPI_DBG_DISCLOSETASK) && \ ++ (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ ++ printk(TPACPI_DEBUG "%s: PID %d: " format, \ ++ what, task_tgid_vnr(current), ## arg); \ ++ } \ ++ } while (0) + + /**************************************************************************** + **************************************************************************** +@@ -1030,6 +1047,21 @@ static int __init tpacpi_new_rfkill(const unsigned int id, + return 0; + } + ++static void printk_deprecated_attribute(const char * const what, ++ const char * const details) ++{ ++ tpacpi_log_usertask("deprecated sysfs attribute"); ++ printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " ++ "will be removed. %s\n", ++ what, details); ++} ++ ++static void printk_deprecated_rfkill_attribute(const char * const what) ++{ ++ printk_deprecated_attribute(what, ++ "Please switch to generic rfkill before year 2010"); ++} ++ + /************************************************************************* + * thinkpad-acpi driver attributes + */ +@@ -3070,6 +3102,8 @@ static ssize_t bluetooth_enable_show(struct device *dev, + { + int status; + ++ printk_deprecated_rfkill_attribute("bluetooth_enable"); ++ + status = bluetooth_get_radiosw(); + if (status < 0) + return status; +@@ -3085,6 +3119,8 @@ static ssize_t bluetooth_enable_store(struct device *dev, + unsigned long t; + int res; + ++ printk_deprecated_rfkill_attribute("bluetooth_enable"); ++ + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + +@@ -3347,6 +3383,8 @@ static ssize_t wan_enable_show(struct device *dev, + { + int status; + ++ printk_deprecated_rfkill_attribute("wwan_enable"); ++ + status = wan_get_radiosw(); + if (status < 0) + return status; +@@ -3362,6 +3400,8 @@ static ssize_t wan_enable_store(struct device *dev, + unsigned long t; + int res; + ++ printk_deprecated_rfkill_attribute("wwan_enable"); ++ + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0009-thinkpad-acpi-remove-HKEY-disable-functionality.patch b/releases/upstream/2.6.30-rc1/0009-thinkpad-acpi-remove-HKEY-disable-functionality.patch new file mode 100644 index 00000000000..27ecd400c95 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0009-thinkpad-acpi-remove-HKEY-disable-functionality.patch @@ -0,0 +1,271 @@ +From 2586d5663d0a17d69383acf6110f16a979a07c4e Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:48 +0000 +Subject: thinkpad-acpi: remove HKEY disable functionality + +The HKEY disable functionality basically cripples the entire event +model of the ThinkPad firmware and of the thinkpad-acpi driver. +Remove this functionality from the driver. HKEY must be enabled at +all times while thinkpad-acpi is loaded, and disabled otherwise. + +For sysfs, according to the sysfs ABI and the thinkpad-acpi sysfs +rules of engagement, we will just remove the attributes. This will be +done in two stages: disable their function now, after two kernel +releases, remove the attributes. + +For procfs, we call WARN(). If nothing triggers it, I will simply +remove the enable/disable commands entirely in the future along with +the sysfs attributes. + +I don't expect much, if any fallout from this. There really isn't any +reason to mess with hotkey_enable or with the enable/disable commands +to /proc/acpi/ibm/hotkey, and this has been true for years... + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 39 ++++++++++++------------ + drivers/platform/x86/thinkpad_acpi.c | 49 +++++++++++++++++-------------- + 2 files changed, 46 insertions(+), 42 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index e8f52fb..de6f14c 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -179,17 +179,14 @@ system. Enabling the hotkey functionality of thinkpad-acpi signals the + firmware that such a driver is present, and modifies how the ThinkPad + firmware will behave in many situations. + +-The driver enables the hot key feature automatically when loaded. The +-feature can later be disabled and enabled back at runtime. The driver +-will also restore the hot key feature to its previous state and mask +-when it is unloaded. ++The driver enables the HKEY ("hot key") event reporting automatically ++when loaded, and disables it when it is removed. + +-When the hotkey feature is enabled and the hot key mask is set (see +-below), the driver will report HKEY events in the following format: ++The driver will report HKEY events in the following format: + + ibm/hotkey HKEY 00000080 0000xxxx + +-Some of these events refer to hot key presses, but not all. ++Some of these events refer to hot key presses, but not all of them. + + The driver will generate events over the input layer for hot keys and + radio switches, and over the ACPI netlink layer for other events. The +@@ -221,13 +218,17 @@ procfs notes: + + The following commands can be written to the /proc/acpi/ibm/hotkey file: + +- echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature +- echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature + echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys + echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys + ... any other 8-hex-digit mask ... + echo reset > /proc/acpi/ibm/hotkey -- restore the original mask + ++The following commands have been deprecated and will cause the kernel ++to log a warning: ++ ++ echo enable > /proc/acpi/ibm/hotkey -- does nothing ++ echo disable > /proc/acpi/ibm/hotkey -- returns an error ++ + The procfs interface does not support NVRAM polling control. So as to + maintain maximum bug-to-bug compatibility, it does not report any masks, + nor does it allow one to manipulate the hot key mask when the firmware +@@ -236,12 +237,9 @@ does not support masks at all, even if NVRAM polling is in use. + sysfs notes: + + hotkey_bios_enabled: +- Returns the status of the hot keys feature when +- thinkpad-acpi was loaded. Upon module unload, the hot +- key feature status will be restored to this value. ++ DEPRECATED, WILL BE REMOVED SOON. + +- 0: hot keys were disabled +- 1: hot keys were enabled (unusual) ++ Returns 0. + + hotkey_bios_mask: + Returns the hot keys mask when thinkpad-acpi was loaded. +@@ -249,13 +247,10 @@ sysfs notes: + to this value. + + hotkey_enable: +- Enables/disables the hot keys feature in the ACPI +- firmware, and reports current status of the hot keys +- feature. Has no effect on the NVRAM hot key polling +- functionality. ++ DEPRECATED, WILL BE REMOVED SOON. + +- 0: disables the hot keys feature / feature disabled +- 1: enables the hot keys feature / feature enabled ++ 0: returns -EPERM ++ 1: does nothing + + hotkey_mask: + bit mask to enable driver-handling (and depending on +@@ -1535,3 +1530,7 @@ Sysfs interface changelog: + + 0x020200: Add poll()/select() support to the following attributes: + hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason ++ ++0x020300: hotkey enable/disable support removed, attributes ++ hotkey_bios_enabled and hotkey_enable deprecated and ++ marked for removal. +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 852be7c..f003fb7 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -22,7 +22,7 @@ + */ + + #define TPACPI_VERSION "0.22" +-#define TPACPI_SYSFS_VERSION 0x020200 ++#define TPACPI_SYSFS_VERSION 0x020300 + + /* + * Changelog: +@@ -1424,7 +1424,6 @@ static enum { /* Reasons for waking up */ + + static int hotkey_autosleep_ack; + +-static int hotkey_orig_status; + static u32 hotkey_orig_mask; + static u32 hotkey_all_mask; + static u32 hotkey_reserved_mask; +@@ -1571,9 +1570,9 @@ static int hotkey_status_get(int *status) + return 0; + } + +-static int hotkey_status_set(int status) ++static int hotkey_status_set(bool enable) + { +- if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) ++ if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0)) + return -EIO; + + return 0; +@@ -1889,6 +1888,9 @@ static ssize_t hotkey_enable_show(struct device *dev, + { + int res, status; + ++ printk_deprecated_attribute("hotkey_enable", ++ "Hotkey reporting is always enabled"); ++ + res = hotkey_status_get(&status); + if (res) + return res; +@@ -1901,14 +1903,17 @@ static ssize_t hotkey_enable_store(struct device *dev, + const char *buf, size_t count) + { + unsigned long t; +- int res; ++ ++ printk_deprecated_attribute("hotkey_enable", ++ "Hotkeys can be disabled through hotkey_mask"); + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + +- res = hotkey_status_set(t); ++ if (t == 0) ++ return -EPERM; + +- return (res) ? res : count; ++ return count; + } + + static struct device_attribute dev_attr_hotkey_enable = +@@ -1964,7 +1969,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); ++ return sprintf(buf, "0\n"); + } + + static struct device_attribute dev_attr_hotkey_bios_enabled = +@@ -2243,7 +2248,7 @@ static void hotkey_exit(void) + "restoring original hot key mask\n"); + /* no short-circuit boolean operator below! */ + if ((hotkey_mask_set(hotkey_orig_mask) | +- hotkey_status_set(hotkey_orig_status)) != 0) ++ hotkey_status_set(false)) != 0) + printk(TPACPI_ERR + "failed to restore hot key mask " + "to BIOS defaults\n"); +@@ -2438,10 +2443,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + + /* hotkey_source_mask *must* be zero for + * the first hotkey_mask_get */ +- res = hotkey_status_get(&hotkey_orig_status); +- if (res) +- goto err_exit; +- + if (tp_features.hotkey_mask) { + res = hotkey_mask_get(); + if (res) +@@ -2581,7 +2582,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + } + + dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); +- res = hotkey_status_set(1); ++ res = hotkey_status_set(true); + if (res) { + hotkey_exit(); + return res; +@@ -2926,9 +2927,17 @@ static int hotkey_read(char *p) + return len; + } + ++static void hotkey_enabledisable_warn(void) ++{ ++ tpacpi_log_usertask("procfs hotkey enable/disable"); ++ WARN(1, TPACPI_WARN ++ "hotkey enable/disable functionality has been " ++ "removed from the driver. Hotkeys are always enabled.\n"); ++} ++ + static int hotkey_write(char *buf) + { +- int res, status; ++ int res; + u32 mask; + char *cmd; + +@@ -2938,17 +2947,16 @@ static int hotkey_write(char *buf) + if (mutex_lock_killable(&hotkey_mutex)) + return -ERESTARTSYS; + +- status = -1; + mask = hotkey_mask; + + res = 0; + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { +- status = 1; ++ hotkey_enabledisable_warn(); + } else if (strlencmp(cmd, "disable") == 0) { +- status = 0; ++ hotkey_enabledisable_warn(); ++ res = -EPERM; + } else if (strlencmp(cmd, "reset") == 0) { +- status = hotkey_orig_status; + mask = hotkey_orig_mask; + } else if (sscanf(cmd, "0x%x", &mask) == 1) { + /* mask set */ +@@ -2959,9 +2967,6 @@ static int hotkey_write(char *buf) + goto errexit; + } + } +- if (status != -1) +- res = hotkey_status_set(status); +- + if (!res && mask != hotkey_mask) + res = hotkey_mask_set(mask); + +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0010-thinkpad-acpi-restrict-access-to-some-firmware-LEDs.patch b/releases/upstream/2.6.30-rc1/0010-thinkpad-acpi-restrict-access-to-some-firmware-LEDs.patch new file mode 100644 index 00000000000..eaa57811fda --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0010-thinkpad-acpi-restrict-access-to-some-firmware-LEDs.patch @@ -0,0 +1,216 @@ +From a4d5effcc73749ee3ebbf578d162905e6fa4e07d Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:49 +0000 +Subject: thinkpad-acpi: restrict access to some firmware LEDs + +Some of the ThinkPad LEDs indicate critical conditions that can cause +data loss or cause hardware damage when ignored (e.g. force-ejecting +a powered up bay; ignoring a failing battery, or empty battery; force- +undocking with the dock buses still active, etc). + +On almost all ThinkPads, LED access is write-only, and the firmware +usually does fire-and-forget signaling on them, so you effectively +lose whatever message the firmware was trying to convey to the user +when you override the LED state, without any chance to restore it. + +Restrict access to all LEDs that can convey important alarms, or that +could mislead the user into incorrectly operating the hardware. This +will make the Lenovo engineers less unhappy about the whole issue. + +Allow users that really want it to still control all LEDs, it is the +unaware user that we have to worry about. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 11 +++++ + drivers/platform/x86/Kconfig | 24 ++++++++++ + drivers/platform/x86/thinkpad_acpi.c | 76 +++++++++++++++++++++++-------- + 3 files changed, 91 insertions(+), 20 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index de6f14c..bce1d95 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -901,6 +901,17 @@ some older ThinkPad models, it is possible to query the status of the + LED indicators as well. Newer ThinkPads cannot query the real status + of the LED indicators. + ++Because misuse of the LEDs could induce an unaware user to perform ++dangerous actions (like undocking or ejecting a bay device while the ++buses are still active), or mask an important alarm (such as a nearly ++empty battery, or a broken battery), access to most LEDs is ++restricted. ++ ++Unrestricted access to all LEDs requires that thinkpad-acpi be ++compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled. ++Distributions must never enable this option. Individual users that ++are aware of the consequences are welcome to enabling it. ++ + procfs notes: + + The available commands are: +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 3608081..d45c6ab 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -226,6 +226,30 @@ config THINKPAD_ACPI_DEBUG + + If you are not sure, say N here. + ++config THINKPAD_ACPI_UNSAFE_LEDS ++ bool "Allow control of important LEDs (unsafe)" ++ depends on THINKPAD_ACPI ++ default n ++ ---help--- ++ Overriding LED state on ThinkPads can mask important ++ firmware alerts (like critical battery condition), or misled ++ the user into damaging the hardware (undocking or ejecting ++ the bay while buses are still active), etc. ++ ++ LED control on the ThinkPad is write-only (with very few ++ exceptions on very ancient models), which makes it ++ impossible to know beforehand if important information will ++ be lost when one changes LED state. ++ ++ Users that know what they are doing can enable this option ++ and the driver will allow control of every LED, including ++ the ones on the dock stations. ++ ++ Never enable this option on a distribution kernel. ++ ++ Say N here, unless you are building a kernel for your own ++ use, and need to control the important firmware LEDs. ++ + config THINKPAD_ACPI_DOCK + bool "Legacy Docking Station Support" + depends on THINKPAD_ACPI +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index f003fb7..38c34c7 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -4657,6 +4657,16 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { + "tpacpi::unknown_led", + "tpacpi::standby", + }; ++#define TPACPI_SAFE_LEDS 0x0081U ++ ++static inline bool tpacpi_is_led_restricted(const unsigned int led) ++{ ++#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS ++ return false; ++#else ++ return (TPACPI_SAFE_LEDS & (1 << led)) == 0; ++#endif ++} + + static int led_get_status(const unsigned int led) + { +@@ -4694,16 +4704,20 @@ static int led_set_status(const unsigned int led, + switch (led_supported) { + case TPACPI_LED_570: + /* 570 */ +- if (led > 7) ++ if (unlikely(led > 7)) + return -EINVAL; ++ if (unlikely(tpacpi_is_led_restricted(led))) ++ return -EPERM; + if (!acpi_evalf(led_handle, NULL, NULL, "vdd", + (1 << led), led_sled_arg1[ledstatus])) + rc = -EIO; + break; + case TPACPI_LED_OLD: + /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ +- if (led > 7) ++ if (unlikely(led > 7)) + return -EINVAL; ++ if (unlikely(tpacpi_is_led_restricted(led))) ++ return -EPERM; + rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); + if (rc >= 0) + rc = ec_write(TPACPI_LED_EC_HLBL, +@@ -4714,6 +4728,10 @@ static int led_set_status(const unsigned int led, + break; + case TPACPI_LED_NEW: + /* all others */ ++ if (unlikely(led >= TPACPI_LED_NUMLEDS)) ++ return -EINVAL; ++ if (unlikely(tpacpi_is_led_restricted(led))) ++ return -EPERM; + if (!acpi_evalf(led_handle, NULL, NULL, "vdd", + led, led_led_arg1[ledstatus])) + rc = -EIO; +@@ -4806,6 +4824,30 @@ static void led_exit(void) + kfree(tpacpi_leds); + } + ++static int __init tpacpi_init_led(unsigned int led) ++{ ++ int rc; ++ ++ tpacpi_leds[led].led = led; ++ ++ tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set; ++ tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set; ++ if (led_supported == TPACPI_LED_570) ++ tpacpi_leds[led].led_classdev.brightness_get = ++ &led_sysfs_get; ++ ++ tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led]; ++ ++ INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker); ++ ++ rc = led_classdev_register(&tpacpi_pdev->dev, ++ &tpacpi_leds[led].led_classdev); ++ if (rc < 0) ++ tpacpi_leds[led].led_classdev.name = NULL; ++ ++ return rc; ++} ++ + static int __init led_init(struct ibm_init_struct *iibm) + { + unsigned int i; +@@ -4839,27 +4881,21 @@ static int __init led_init(struct ibm_init_struct *iibm) + } + + for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { +- tpacpi_leds[i].led = i; +- +- tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set; +- tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set; +- if (led_supported == TPACPI_LED_570) +- tpacpi_leds[i].led_classdev.brightness_get = +- &led_sysfs_get; +- +- tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i]; +- +- INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker); +- +- rc = led_classdev_register(&tpacpi_pdev->dev, +- &tpacpi_leds[i].led_classdev); +- if (rc < 0) { +- tpacpi_leds[i].led_classdev.name = NULL; +- led_exit(); +- return rc; ++ if (!tpacpi_is_led_restricted(i)) { ++ rc = tpacpi_init_led(i); ++ if (rc < 0) { ++ led_exit(); ++ return rc; ++ } + } + } + ++#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS ++ if (led_supported != TPACPI_LED_NONE) ++ printk(TPACPI_NOTICE ++ "warning: userspace override of important " ++ "firmware LEDs is enabled\n"); ++#endif + return (led_supported != TPACPI_LED_NONE)? 0 : 1; + } + +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0011-thinkpad-acpi-enhanced-debugging-messages-for-rfkil.patch b/releases/upstream/2.6.30-rc1/0011-thinkpad-acpi-enhanced-debugging-messages-for-rfkil.patch new file mode 100644 index 00000000000..140a164eaeb --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0011-thinkpad-acpi-enhanced-debugging-messages-for-rfkil.patch @@ -0,0 +1,414 @@ +From bee4cd9b9eaa8c72832e1ee7f4940604e94beb27 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:50 +0000 +Subject: thinkpad-acpi: enhanced debugging messages for rfkill subdrivers + +Enhance debugging messages for all rfkill subdrivers in thinkpad-acpi. + +Also, log a warning if the deprecated sysfs attributes are in use. +These attributes are going to be removed sometime in 2010. + +There is an user-visible side-effect: we now coalesce attempts to +enable/disable bluetooth or WWAN in the procfs interface, instead of +hammering the firmware with multiple requests. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 2 + + drivers/platform/x86/thinkpad_acpi.c | 117 +++++++++++++++++++++++++------ + 2 files changed, 98 insertions(+), 21 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index bce1d95..7daca05 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -1494,6 +1494,8 @@ to enable more than one output class, just add their values. + accessing some functions of the driver + 0x0001 Initialization and probing + 0x0002 Removal ++ 0x0004 RF Transmitter control (RFKILL) ++ (bluetooth, WWAN, UWB...) + + There is also a kernel build option to enable more debugging + information, which may be necessary to debug driver problems. +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 38c34c7..57ab551 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -189,6 +189,7 @@ enum { + #define TPACPI_DBG_DISCLOSETASK 0x8000 + #define TPACPI_DBG_INIT 0x0001 + #define TPACPI_DBG_EXIT 0x0002 ++#define TPACPI_DBG_RFKILL 0x0004 + + #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") + #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") +@@ -1016,10 +1017,13 @@ static int __init tpacpi_new_rfkill(const unsigned int id, + /* try to set the initial state as the default for the rfkill + * type, since we ask the firmware to preserve it across S5 in + * NVRAM */ +- rfkill_set_default(rfktype, ++ if (rfkill_set_default(rfktype, + (initial_state == RFKILL_STATE_UNBLOCKED) ? + RFKILL_STATE_UNBLOCKED : +- RFKILL_STATE_SOFT_BLOCKED); ++ RFKILL_STATE_SOFT_BLOCKED) == -EPERM) ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "Default state for %s cannot be changed\n", ++ name); + } + + *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); +@@ -3018,13 +3022,17 @@ enum { + TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */ + }; + ++#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" ++ + static struct rfkill *tpacpi_bluetooth_rfkill; + + static void bluetooth_suspend(pm_message_t state) + { + /* Try to make sure radio will resume powered off */ +- acpi_evalf(NULL, NULL, "\\BLTH", "vd", +- TP_ACPI_BLTH_PWR_OFF_ON_RESUME); ++ if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", ++ TP_ACPI_BLTH_PWR_OFF_ON_RESUME)) ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "bluetooth power down on resume request failed\n"); + } + + static int bluetooth_get_radiosw(void) +@@ -3062,6 +3070,10 @@ static void bluetooth_update_rfk(void) + if (status < 0) + return; + rfkill_force_state(tpacpi_bluetooth_rfkill, status); ++ ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "forced rfkill state to %d\n", ++ status); + } + + static int bluetooth_set_radiosw(int radio_on, int update_rfk) +@@ -3077,6 +3089,9 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk) + && radio_on) + return -EPERM; + ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "will %s bluetooth\n", radio_on ? "enable" : "disable"); ++ + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_bluetoothemul) { + tpacpi_bluetooth_emulstate = !!radio_on; +@@ -3129,6 +3144,8 @@ static ssize_t bluetooth_enable_store(struct device *dev, + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + ++ tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t); ++ + res = bluetooth_set_radiosw(t, 1); + + return (res) ? res : count; +@@ -3162,6 +3179,8 @@ static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) + + static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) + { ++ dbg_printk(TPACPI_DBG_RFKILL, ++ "request to change radio state to %d\n", state); + return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); + } + +@@ -3172,6 +3191,9 @@ static void bluetooth_shutdown(void) + TP_ACPI_BLTH_SAVE_STATE)) + printk(TPACPI_NOTICE + "failed to save bluetooth state to NVRAM\n"); ++ else ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "bluestooth state saved to NVRAM\n"); + } + + static void bluetooth_exit(void) +@@ -3190,7 +3212,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) + int res; + int status = 0; + +- vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ "initializing bluetooth subdriver\n"); + + TPACPI_ACPIHANDLE_INIT(hkey); + +@@ -3199,7 +3222,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) + tp_features.bluetooth = hkey_handle && + acpi_evalf(hkey_handle, &status, "GBDC", "qd"); + +- vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n", ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ "bluetooth is %s, status 0x%02x\n", + str_supported(tp_features.bluetooth), + status); + +@@ -3214,7 +3238,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) + !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { + /* no bluetooth hardware present in system */ + tp_features.bluetooth = 0; +- dbg_printk(TPACPI_DBG_INIT, ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, + "bluetooth hardware not installed\n"); + } + +@@ -3229,7 +3253,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) + res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, + &tpacpi_bluetooth_rfkill, + RFKILL_TYPE_BLUETOOTH, +- "tpacpi_bluetooth_sw", ++ TPACPI_RFK_BLUETOOTH_SW_NAME, + true, + tpacpi_bluetooth_rfk_set, + tpacpi_bluetooth_rfk_get); +@@ -3262,19 +3286,27 @@ static int bluetooth_read(char *p) + static int bluetooth_write(char *buf) + { + char *cmd; ++ int state = -1; + + if (!tp_features.bluetooth) + return -ENODEV; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { +- bluetooth_set_radiosw(1, 1); ++ state = 1; + } else if (strlencmp(cmd, "disable") == 0) { +- bluetooth_set_radiosw(0, 1); ++ state = 0; + } else + return -EINVAL; + } + ++ if (state != -1) { ++ tpacpi_disclose_usertask("procfs bluetooth", ++ "attempt to %s\n", ++ state ? "enable" : "disable"); ++ bluetooth_set_radiosw(state, 1); ++ } ++ + return 0; + } + +@@ -3299,13 +3331,17 @@ enum { + off / last state */ + }; + ++#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" ++ + static struct rfkill *tpacpi_wan_rfkill; + + static void wan_suspend(pm_message_t state) + { + /* Try to make sure radio will resume powered off */ +- acpi_evalf(NULL, NULL, "\\WGSV", "qvd", +- TP_ACPI_WGSV_PWR_OFF_ON_RESUME); ++ if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd", ++ TP_ACPI_WGSV_PWR_OFF_ON_RESUME)) ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "WWAN power down on resume request failed\n"); + } + + static int wan_get_radiosw(void) +@@ -3343,6 +3379,10 @@ static void wan_update_rfk(void) + if (status < 0) + return; + rfkill_force_state(tpacpi_wan_rfkill, status); ++ ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "forced rfkill state to %d\n", ++ status); + } + + static int wan_set_radiosw(int radio_on, int update_rfk) +@@ -3358,6 +3398,9 @@ static int wan_set_radiosw(int radio_on, int update_rfk) + && radio_on) + return -EPERM; + ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "will %s WWAN\n", radio_on ? "enable" : "disable"); ++ + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_wwanemul) { + tpacpi_wwan_emulstate = !!radio_on; +@@ -3410,6 +3453,8 @@ static ssize_t wan_enable_store(struct device *dev, + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + ++ tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t); ++ + res = wan_set_radiosw(t, 1); + + return (res) ? res : count; +@@ -3443,6 +3488,8 @@ static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) + + static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) + { ++ dbg_printk(TPACPI_DBG_RFKILL, ++ "request to change radio state to %d\n", state); + return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); + } + +@@ -3453,6 +3500,9 @@ static void wan_shutdown(void) + TP_ACPI_WGSV_SAVE_STATE)) + printk(TPACPI_NOTICE + "failed to save WWAN state to NVRAM\n"); ++ else ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "WWAN state saved to NVRAM\n"); + } + + static void wan_exit(void) +@@ -3471,14 +3521,16 @@ static int __init wan_init(struct ibm_init_struct *iibm) + int res; + int status = 0; + +- vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ "initializing wan subdriver\n"); + + TPACPI_ACPIHANDLE_INIT(hkey); + + tp_features.wan = hkey_handle && + acpi_evalf(hkey_handle, &status, "GWAN", "qd"); + +- vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n", ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ "wan is %s, status 0x%02x\n", + str_supported(tp_features.wan), + status); + +@@ -3493,7 +3545,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) + !(status & TP_ACPI_WANCARD_HWPRESENT)) { + /* no wan hardware present in system */ + tp_features.wan = 0; +- dbg_printk(TPACPI_DBG_INIT, ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, + "wan hardware not installed\n"); + } + +@@ -3508,7 +3560,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) + res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, + &tpacpi_wan_rfkill, + RFKILL_TYPE_WWAN, +- "tpacpi_wwan_sw", ++ TPACPI_RFK_WWAN_SW_NAME, + true, + tpacpi_wan_rfk_set, + tpacpi_wan_rfk_get); +@@ -3526,6 +3578,8 @@ static int wan_read(char *p) + int len = 0; + int status = wan_get_radiosw(); + ++ tpacpi_disclose_usertask("procfs wan", "read"); ++ + if (!tp_features.wan) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else { +@@ -3541,19 +3595,27 @@ static int wan_read(char *p) + static int wan_write(char *buf) + { + char *cmd; ++ int state = -1; + + if (!tp_features.wan) + return -ENODEV; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { +- wan_set_radiosw(1, 1); ++ state = 1; + } else if (strlencmp(cmd, "disable") == 0) { +- wan_set_radiosw(0, 1); ++ state = 0; + } else + return -EINVAL; + } + ++ if (state != -1) { ++ tpacpi_disclose_usertask("procfs wan", ++ "attempt to %s\n", ++ state ? "enable" : "disable"); ++ wan_set_radiosw(state, 1); ++ } ++ + return 0; + } + +@@ -3576,6 +3638,8 @@ enum { + TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */ + }; + ++#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" ++ + static struct rfkill *tpacpi_uwb_rfkill; + + static int uwb_get_radiosw(void) +@@ -3613,6 +3677,10 @@ static void uwb_update_rfk(void) + if (status < 0) + return; + rfkill_force_state(tpacpi_uwb_rfkill, status); ++ ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "forced rfkill state to %d\n", ++ status); + } + + static int uwb_set_radiosw(int radio_on, int update_rfk) +@@ -3628,6 +3696,9 @@ static int uwb_set_radiosw(int radio_on, int update_rfk) + && radio_on) + return -EPERM; + ++ vdbg_printk(TPACPI_DBG_RFKILL, ++ "will %s UWB\n", radio_on ? "enable" : "disable"); ++ + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES + if (dbg_uwbemul) { + tpacpi_uwb_emulstate = !!radio_on; +@@ -3662,6 +3733,8 @@ static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) + + static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) + { ++ dbg_printk(TPACPI_DBG_RFKILL, ++ "request to change radio state to %d\n", state); + return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); + } + +@@ -3676,14 +3749,16 @@ static int __init uwb_init(struct ibm_init_struct *iibm) + int res; + int status = 0; + +- vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n"); ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ "initializing uwb subdriver\n"); + + TPACPI_ACPIHANDLE_INIT(hkey); + + tp_features.uwb = hkey_handle && + acpi_evalf(hkey_handle, &status, "GUWB", "qd"); + +- vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n", ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, ++ "uwb is %s, status 0x%02x\n", + str_supported(tp_features.uwb), + status); + +@@ -3708,7 +3783,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm) + res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, + &tpacpi_uwb_rfkill, + RFKILL_TYPE_UWB, +- "tpacpi_uwb_sw", ++ TPACPI_RFK_UWB_SW_NAME, + false, + tpacpi_uwb_rfk_set, + tpacpi_uwb_rfk_get); +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0012-thinkpad-acpi-enhanced-debugging-messages-for-the-h.patch b/releases/upstream/2.6.30-rc1/0012-thinkpad-acpi-enhanced-debugging-messages-for-the-h.patch new file mode 100644 index 00000000000..6a80cefc561 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0012-thinkpad-acpi-enhanced-debugging-messages-for-the-h.patch @@ -0,0 +1,170 @@ +From 56e2c200945dafafb86169762eb1e88aed0ce69e Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:51 +0000 +Subject: thinkpad-acpi: enhanced debugging messages for the hotkey subdriver + +Enhance debugging messages for the hotkey subdriver. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 1 + + drivers/platform/x86/thinkpad_acpi.c | 39 +++++++++++++++++++++++-------- + 2 files changed, 30 insertions(+), 10 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index 7daca05..abbbe78 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -1496,6 +1496,7 @@ to enable more than one output class, just add their values. + 0x0002 Removal + 0x0004 RF Transmitter control (RFKILL) + (bluetooth, WWAN, UWB...) ++ 0x0008 HKEY event interface, hotkeys + + There is also a kernel build option to enable more debugging + information, which may be necessary to debug driver problems. +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 57ab551..0a4796a 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -190,6 +190,7 @@ enum { + #define TPACPI_DBG_INIT 0x0001 + #define TPACPI_DBG_EXIT 0x0002 + #define TPACPI_DBG_RFKILL 0x0004 ++#define TPACPI_DBG_HKEY 0x0008 + + #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") + #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") +@@ -1961,6 +1962,8 @@ static ssize_t hotkey_mask_store(struct device *dev, + + mutex_unlock(&hotkey_mutex); + ++ tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t); ++ + return (res) ? res : count; + } + +@@ -2047,6 +2050,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev, + + mutex_unlock(&hotkey_mutex); + ++ tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); ++ + return count; + } + +@@ -2079,6 +2084,8 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, + hotkey_poll_setup(1); + mutex_unlock(&hotkey_mutex); + ++ tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t); ++ + return count; + } + +@@ -2248,7 +2255,7 @@ static void hotkey_exit(void) + kfree(hotkey_keycode_map); + + if (tp_features.hotkey) { +- dbg_printk(TPACPI_DBG_EXIT, ++ dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, + "restoring original hot key mask\n"); + /* no short-circuit boolean operator below! */ + if ((hotkey_mask_set(hotkey_orig_mask) | +@@ -2378,7 +2385,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + int status; + int hkeyv; + +- vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "initializing hotkey subdriver\n"); + + BUG_ON(!tpacpi_inputdev); + BUG_ON(tpacpi_inputdev->open != NULL || +@@ -2395,7 +2403,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + /* hotkey not supported on 570 */ + tp_features.hotkey = hkey_handle != NULL; + +- vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "hotkeys are %s\n", + str_supported(tp_features.hotkey)); + + if (!tp_features.hotkey) +@@ -2427,10 +2436,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + * T4x, X31, and later + */ + tp_features.hotkey_mask = 1; ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "firmware HKEY interface version: 0x%x\n", ++ hkeyv); + } + } + +- vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "hotkey masks are %s\n", + str_supported(tp_features.hotkey_mask)); + + if (tp_features.hotkey_mask) { +@@ -2469,7 +2482,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; + } + +- vdbg_printk(TPACPI_DBG_INIT, ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "hotkey source mask 0x%08x, polling freq %d\n", + hotkey_source_mask, hotkey_poll_freq); + #endif +@@ -2523,12 +2536,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + } + + if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { +- dbg_printk(TPACPI_DBG_INIT, ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "using Lenovo default hot key map\n"); + memcpy(hotkey_keycode_map, &lenovo_keycode_map, + TPACPI_HOTKEY_MAP_SIZE); + } else { +- dbg_printk(TPACPI_DBG_INIT, ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "using IBM default hot key map\n"); + memcpy(hotkey_keycode_map, &ibm_keycode_map, + TPACPI_HOTKEY_MAP_SIZE); +@@ -2585,7 +2598,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + | (1 << TP_ACPI_HOTKEYSCAN_FNEND); + } + +- dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "enabling firmware HKEY event interface...\n"); + res = hotkey_status_set(true); + if (res) { + hotkey_exit(); +@@ -2599,8 +2613,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + return res; + } + +- dbg_printk(TPACPI_DBG_INIT, +- "legacy hot key reporting over procfs %s\n", ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "legacy ibm/hotkey event reporting over procfs %s\n", + (hotkey_report_mode < 2) ? + "enabled" : "disabled"); + +@@ -2971,6 +2985,11 @@ static int hotkey_write(char *buf) + goto errexit; + } + } ++ ++ if (!res) ++ tpacpi_disclose_usertask("procfs hotkey", ++ "set mask to 0x%08x\n", mask); ++ + if (!res && mask != hotkey_mask) + res = hotkey_mask_set(mask); + +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0013-thinkpad-acpi-enhanced-debugging-messages-for-the-f.patch b/releases/upstream/2.6.30-rc1/0013-thinkpad-acpi-enhanced-debugging-messages-for-the-f.patch new file mode 100644 index 00000000000..2942d72791d --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0013-thinkpad-acpi-enhanced-debugging-messages-for-the-f.patch @@ -0,0 +1,192 @@ +From 74a60c0f828016456fc635feae388ffd12bb3bb9 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:52 +0000 +Subject: thinkpad-acpi: enhanced debugging messages for the fan subdriver + +Enhance debugging messages for the fan subdriver. + +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 1 + + drivers/platform/x86/thinkpad_acpi.c | 46 +++++++++++++++++++++++++++--- + 2 files changed, 42 insertions(+), 5 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index abbbe78..25ed43d 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -1497,6 +1497,7 @@ to enable more than one output class, just add their values. + 0x0004 RF Transmitter control (RFKILL) + (bluetooth, WWAN, UWB...) + 0x0008 HKEY event interface, hotkeys ++ 0x0010 Fan control + + There is also a kernel build option to enable more debugging + information, which may be necessary to debug driver problems. +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 0a4796a..4eec770 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -191,6 +191,7 @@ enum { + #define TPACPI_DBG_EXIT 0x0002 + #define TPACPI_DBG_RFKILL 0x0004 + #define TPACPI_DBG_HKEY 0x0008 ++#define TPACPI_DBG_FAN 0x0010 + + #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") + #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") +@@ -6271,6 +6272,9 @@ static int fan_set_level(int level) + default: + return -ENXIO; + } ++ ++ vdbg_printk(TPACPI_DBG_FAN, ++ "fan control: set fan control register to 0x%02x\n", level); + return 0; + } + +@@ -6348,6 +6352,11 @@ static int fan_set_enable(void) + } + + mutex_unlock(&fan_mutex); ++ ++ if (!rc) ++ vdbg_printk(TPACPI_DBG_FAN, ++ "fan control: set fan control register to 0x%02x\n", ++ s); + return rc; + } + +@@ -6384,6 +6393,9 @@ static int fan_set_disable(void) + rc = -ENXIO; + } + ++ if (!rc) ++ vdbg_printk(TPACPI_DBG_FAN, ++ "fan control: set fan control register to 0\n"); + + mutex_unlock(&fan_mutex); + return rc; +@@ -6512,6 +6524,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev, + if (parse_strtoul(buf, 2, &t)) + return -EINVAL; + ++ tpacpi_disclose_usertask("hwmon pwm1_enable", ++ "set fan mode to %lu\n", t); ++ + switch (t) { + case 0: + level = TP_EC_FAN_FULLSPEED; +@@ -6577,6 +6592,9 @@ static ssize_t fan_pwm1_store(struct device *dev, + if (parse_strtoul(buf, 255, &s)) + return -EINVAL; + ++ tpacpi_disclose_usertask("hwmon pwm1", ++ "set fan speed to %lu\n", s); ++ + /* scale down from 0-255 to 0-7 */ + newlevel = (s >> 5) & 0x07; + +@@ -6643,6 +6661,8 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv, + fan_watchdog_maxinterval = t; + fan_watchdog_reset(); + ++ tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t); ++ + return count; + } + +@@ -6664,7 +6684,8 @@ static int __init fan_init(struct ibm_init_struct *iibm) + { + int rc; + +- vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n"); ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, ++ "initializing fan subdriver\n"); + + mutex_init(&fan_mutex); + fan_status_access_mode = TPACPI_FAN_NONE; +@@ -6723,7 +6744,8 @@ static int __init fan_init(struct ibm_init_struct *iibm) + } + } + +- vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n", ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, ++ "fan is %s, modes %d, %d\n", + str_supported(fan_status_access_mode != TPACPI_FAN_NONE || + fan_control_access_mode != TPACPI_FAN_WR_NONE), + fan_status_access_mode, fan_control_access_mode); +@@ -6732,7 +6754,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) + if (!fan_control_allowed) { + fan_control_access_mode = TPACPI_FAN_WR_NONE; + fan_control_commands = 0; +- dbg_printk(TPACPI_DBG_INIT, ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, + "fan control features disabled by parameter\n"); + } + +@@ -6761,7 +6783,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) + + static void fan_exit(void) + { +- vdbg_printk(TPACPI_DBG_EXIT, ++ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN, + "cancelling any pending fan watchdog tasks\n"); + + /* FIXME: can we really do this unconditionally? */ +@@ -6942,6 +6964,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc) + if (*rc == -ENXIO) + printk(TPACPI_ERR "level command accepted for unsupported " + "access mode %d", fan_control_access_mode); ++ else if (!*rc) ++ tpacpi_disclose_usertask("procfs fan", ++ "set level to %d\n", level); + + return 1; + } +@@ -6955,6 +6980,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc) + if (*rc == -ENXIO) + printk(TPACPI_ERR "enable command accepted for unsupported " + "access mode %d", fan_control_access_mode); ++ else if (!*rc) ++ tpacpi_disclose_usertask("procfs fan", "enable\n"); + + return 1; + } +@@ -6968,6 +6995,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc) + if (*rc == -ENXIO) + printk(TPACPI_ERR "disable command accepted for unsupported " + "access mode %d", fan_control_access_mode); ++ else if (!*rc) ++ tpacpi_disclose_usertask("procfs fan", "disable\n"); + + return 1; + } +@@ -6986,6 +7015,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) + if (*rc == -ENXIO) + printk(TPACPI_ERR "speed command accepted for unsupported " + "access mode %d", fan_control_access_mode); ++ else if (!*rc) ++ tpacpi_disclose_usertask("procfs fan", ++ "set speed to %d\n", speed); + + return 1; + } +@@ -6999,8 +7031,12 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc) + + if (interval < 0 || interval > 120) + *rc = -EINVAL; +- else ++ else { + fan_watchdog_maxinterval = interval; ++ tpacpi_disclose_usertask("procfs fan", ++ "set watchdog timer to %d\n", ++ interval); ++ } + + return 1; + } +-- +1.6.2.1 + diff --git a/releases/upstream/2.6.30-rc1/0014-thinkpad-acpi-rework-brightness-support.patch b/releases/upstream/2.6.30-rc1/0014-thinkpad-acpi-rework-brightness-support.patch new file mode 100644 index 00000000000..08364c62059 --- /dev/null +++ b/releases/upstream/2.6.30-rc1/0014-thinkpad-acpi-rework-brightness-support.patch @@ -0,0 +1,513 @@ +From 0e501834f8c2ba7de2a56e332d346dcf4ac0b593 Mon Sep 17 00:00:00 2001 +From: Henrique de Moraes Holschuh +Date: Sat, 4 Apr 2009 04:25:53 +0000 +Subject: thinkpad-acpi: rework brightness support + +Refactor and redesign the brightness control backend... + +In order to fix bugzilla #11750... + +Add a new brightness control mode: support direct NVRAM checkpointing +of the backlight level (i.e. store directly to NVRAM without the need +for UCMS calls), and use that together with the EC-based control. +Disallow UCMS+EC, thus avoiding races with the SMM firmware. + +Switch the models that define HBRV (EC Brightness Value) in the DSDT +to the new mode. These are: T40-T43, R50-R52, R50e, R51e, X31-X41. + +Change the default for all other IBM ThinkPads to UCMS-only. The +Lenovo models already default to UCMS-only. + +Reported-by: Alexey Fisher +Signed-off-by: Henrique de Moraes Holschuh +Signed-off-by: Len Brown +--- + Documentation/laptops/thinkpad-acpi.txt | 12 +- + drivers/platform/x86/thinkpad_acpi.c | 317 +++++++++++++++++++++---------- + 2 files changed, 227 insertions(+), 102 deletions(-) + +diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt +index 25ed43d..3d76507 100644 +--- a/Documentation/laptops/thinkpad-acpi.txt ++++ b/Documentation/laptops/thinkpad-acpi.txt +@@ -1157,10 +1157,15 @@ display backlight brightness control methods have 16 levels, ranging + from 0 to 15. + + There are two interfaces to the firmware for direct brightness control, +-EC and CMOS. To select which one should be used, use the ++EC and UCMS (or CMOS). To select which one should be used, use the + brightness_mode module parameter: brightness_mode=1 selects EC mode, +-brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC +-and CMOS. The driver tries to auto-detect which interface to use. ++brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC ++mode with NVRAM backing (so that brightness changes are remembered ++across shutdown/reboot). ++ ++The driver tries to select which interface to use from a table of ++defaults for each ThinkPad model. If it makes a wrong choice, please ++report this as a bug, so that we can fix it. + + When display backlight brightness controls are available through the + standard ACPI interface, it is best to use it instead of this direct +@@ -1498,6 +1503,7 @@ to enable more than one output class, just add their values. + (bluetooth, WWAN, UWB...) + 0x0008 HKEY event interface, hotkeys + 0x0010 Fan control ++ 0x0020 Backlight brightness + + There is also a kernel build option to enable more debugging + information, which may be necessary to debug driver problems. +diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c +index 4eec770..ba3682c 100644 +--- a/drivers/platform/x86/thinkpad_acpi.c ++++ b/drivers/platform/x86/thinkpad_acpi.c +@@ -192,6 +192,7 @@ enum { + #define TPACPI_DBG_RFKILL 0x0004 + #define TPACPI_DBG_HKEY 0x0008 + #define TPACPI_DBG_FAN 0x0010 ++#define TPACPI_DBG_BRGHT 0x0020 + + #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") + #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") +@@ -274,7 +275,6 @@ static struct { + + static struct { + u16 hotkey_mask_ff:1; +- u16 bright_cmos_ec_unsync:1; + } tp_warned; + + struct thinkpad_id_data { +@@ -5526,6 +5526,20 @@ static struct ibm_struct ecdump_driver_data = { + + #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" + ++/* ++ * ThinkPads can read brightness from two places: EC HBRV (0x31), or ++ * CMOS NVRAM byte 0x5E, bits 0-3. ++ * ++ * EC HBRV (0x31) has the following layout ++ * Bit 7: unknown function ++ * Bit 6: unknown function ++ * Bit 5: Z: honour scale changes, NZ: ignore scale changes ++ * Bit 4: must be set to zero to avoid problems ++ * Bit 3-0: backlight brightness level ++ * ++ * brightness_get_raw returns status data in the HBRV layout ++ */ ++ + enum { + TP_EC_BACKLIGHT = 0x31, + +@@ -5535,108 +5549,164 @@ enum { + TP_EC_BACKLIGHT_MAPSW = 0x20, + }; + ++enum tpacpi_brightness_access_mode { ++ TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */ ++ TPACPI_BRGHT_MODE_EC, /* EC control */ ++ TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */ ++ TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */ ++ TPACPI_BRGHT_MODE_MAX ++}; ++ + static struct backlight_device *ibm_backlight_device; +-static int brightness_mode; ++ ++static enum tpacpi_brightness_access_mode brightness_mode = ++ TPACPI_BRGHT_MODE_MAX; ++ + static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ + + static struct mutex brightness_mutex; + +-/* +- * ThinkPads can read brightness from two places: EC 0x31, or +- * CMOS NVRAM byte 0x5E, bits 0-3. +- * +- * EC 0x31 has the following layout +- * Bit 7: unknown function +- * Bit 6: unknown function +- * Bit 5: Z: honour scale changes, NZ: ignore scale changes +- * Bit 4: must be set to zero to avoid problems +- * Bit 3-0: backlight brightness level +- * +- * brightness_get_raw returns status data in the EC 0x31 layout +- */ +-static int brightness_get_raw(int *status) ++/* NVRAM brightness access, ++ * call with brightness_mutex held! */ ++static unsigned int tpacpi_brightness_nvram_get(void) + { +- u8 lec = 0, lcmos = 0, level = 0; ++ u8 lnvram; + +- if (brightness_mode & 1) { +- if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec)) +- return -EIO; +- level = lec & TP_EC_BACKLIGHT_LVLMSK; +- }; +- if (brightness_mode & 2) { +- lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) +- & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) +- >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; +- lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; +- level = lcmos; +- } +- +- if (brightness_mode == 3) { +- *status = lec; /* Prefer EC, CMOS is just a backing store */ +- lec &= TP_EC_BACKLIGHT_LVLMSK; +- if (lec == lcmos) +- tp_warned.bright_cmos_ec_unsync = 0; +- else { +- if (!tp_warned.bright_cmos_ec_unsync) { +- printk(TPACPI_ERR +- "CMOS NVRAM (%u) and EC (%u) do not " +- "agree on display brightness level\n", +- (unsigned int) lcmos, +- (unsigned int) lec); +- tp_warned.bright_cmos_ec_unsync = 1; +- } ++ lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) ++ & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) ++ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; ++ lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07; ++ ++ return lnvram; ++} ++ ++static void tpacpi_brightness_checkpoint_nvram(void) ++{ ++ u8 lec = 0; ++ u8 b_nvram; ++ ++ if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM) ++ return; ++ ++ vdbg_printk(TPACPI_DBG_BRGHT, ++ "trying to checkpoint backlight level to NVRAM...\n"); ++ ++ if (mutex_lock_killable(&brightness_mutex) < 0) ++ return; ++ ++ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec))) ++ goto unlock; ++ lec &= TP_EC_BACKLIGHT_LVLMSK; ++ b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS); ++ ++ if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) ++ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) { ++ /* NVRAM needs update */ ++ b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS << ++ TP_NVRAM_POS_LEVEL_BRIGHTNESS); ++ b_nvram |= lec; ++ nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS); ++ dbg_printk(TPACPI_DBG_BRGHT, ++ "updated NVRAM backlight level to %u (0x%02x)\n", ++ (unsigned int) lec, (unsigned int) b_nvram); ++ } else ++ vdbg_printk(TPACPI_DBG_BRGHT, ++ "NVRAM backlight level already is %u (0x%02x)\n", ++ (unsigned int) lec, (unsigned int) b_nvram); ++ ++unlock: ++ mutex_unlock(&brightness_mutex); ++} ++ ++ ++/* call with brightness_mutex held! */ ++static int tpacpi_brightness_get_raw(int *status) ++{ ++ u8 lec = 0; ++ ++ switch (brightness_mode) { ++ case TPACPI_BRGHT_MODE_UCMS_STEP: ++ *status = tpacpi_brightness_nvram_get(); ++ return 0; ++ case TPACPI_BRGHT_MODE_EC: ++ case TPACPI_BRGHT_MODE_ECNVRAM: ++ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec))) + return -EIO; +- } +- } else { +- *status = level; ++ *status = lec; ++ return 0; ++ default: ++ return -ENXIO; + } ++} ++ ++/* call with brightness_mutex held! */ ++/* do NOT call with illegal backlight level value */ ++static int tpacpi_brightness_set_ec(unsigned int value) ++{ ++ u8 lec = 0; ++ ++ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec))) ++ return -EIO; ++ ++ if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT, ++ (lec & TP_EC_BACKLIGHT_CMDMSK) | ++ (value & TP_EC_BACKLIGHT_LVLMSK)))) ++ return -EIO; ++ ++ return 0; ++} ++ ++/* call with brightness_mutex held! */ ++static int tpacpi_brightness_set_ucmsstep(unsigned int value) ++{ ++ int cmos_cmd, inc; ++ unsigned int current_value, i; ++ ++ current_value = tpacpi_brightness_nvram_get(); ++ ++ if (value == current_value) ++ return 0; ++ ++ cmos_cmd = (value > current_value) ? ++ TP_CMOS_BRIGHTNESS_UP : ++ TP_CMOS_BRIGHTNESS_DOWN; ++ inc = (value > current_value) ? 1 : -1; ++ ++ for (i = current_value; i != value; i += inc) ++ if (issue_thinkpad_cmos_command(cmos_cmd)) ++ return -EIO; + + return 0; + } + + /* May return EINTR which can always be mapped to ERESTARTSYS */ +-static int brightness_set(int value) ++static int brightness_set(unsigned int value) + { +- int cmos_cmd, inc, i, res; +- int current_value; +- int command_bits; ++ int res; + + if (value > ((tp_features.bright_16levels)? 15 : 7) || + value < 0) + return -EINVAL; + ++ vdbg_printk(TPACPI_DBG_BRGHT, ++ "set backlight level to %d\n", value); ++ + res = mutex_lock_killable(&brightness_mutex); + if (res < 0) + return res; + +- res = brightness_get_raw(¤t_value); +- if (res < 0) +- goto errout; +- +- command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK; +- current_value &= TP_EC_BACKLIGHT_LVLMSK; +- +- cmos_cmd = value > current_value ? +- TP_CMOS_BRIGHTNESS_UP : +- TP_CMOS_BRIGHTNESS_DOWN; +- inc = (value > current_value)? 1 : -1; +- +- res = 0; +- for (i = current_value; i != value; i += inc) { +- if ((brightness_mode & 2) && +- issue_thinkpad_cmos_command(cmos_cmd)) { +- res = -EIO; +- goto errout; +- } +- if ((brightness_mode & 1) && +- !acpi_ec_write(TP_EC_BACKLIGHT, +- (i + inc) | command_bits)) { +- res = -EIO; +- goto errout;; +- } ++ switch (brightness_mode) { ++ case TPACPI_BRGHT_MODE_EC: ++ case TPACPI_BRGHT_MODE_ECNVRAM: ++ res = tpacpi_brightness_set_ec(value); ++ break; ++ case TPACPI_BRGHT_MODE_UCMS_STEP: ++ res = tpacpi_brightness_set_ucmsstep(value); ++ break; ++ default: ++ res = -ENXIO; + } + +-errout: + mutex_unlock(&brightness_mutex); + return res; + } +@@ -5645,21 +5715,34 @@ errout: + + static int brightness_update_status(struct backlight_device *bd) + { +- /* it is the backlight class's job (caller) to handle +- * EINTR and other errors properly */ +- return brightness_set( ++ unsigned int level = + (bd->props.fb_blank == FB_BLANK_UNBLANK && + bd->props.power == FB_BLANK_UNBLANK) ? +- bd->props.brightness : 0); ++ bd->props.brightness : 0; ++ ++ dbg_printk(TPACPI_DBG_BRGHT, ++ "backlight: attempt to set level to %d\n", ++ level); ++ ++ /* it is the backlight class's job (caller) to handle ++ * EINTR and other errors properly */ ++ return brightness_set(level); + } + + static int brightness_get(struct backlight_device *bd) + { + int status, res; + +- res = brightness_get_raw(&status); ++ res = mutex_lock_killable(&brightness_mutex); + if (res < 0) +- return 0; /* FIXME: teach backlight about error handling */ ++ return 0; ++ ++ res = tpacpi_brightness_get_raw(&status); ++ ++ mutex_unlock(&brightness_mutex); ++ ++ if (res < 0) ++ return 0; + + return status & TP_EC_BACKLIGHT_LVLMSK; + } +@@ -5709,7 +5792,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) + } + + if (!brightness_enable) { +- dbg_printk(TPACPI_DBG_INIT, ++ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, + "brightness support disabled by " + "module parameter\n"); + return 1; +@@ -5724,20 +5807,38 @@ static int __init brightness_init(struct ibm_init_struct *iibm) + if (b == 16) + tp_features.bright_16levels = 1; + +- if (!brightness_mode) { +- if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) +- brightness_mode = 2; +- else +- brightness_mode = 3; ++ /* ++ * Check for module parameter bogosity, note that we ++ * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be ++ * able to detect "unspecified" ++ */ ++ if (brightness_mode > TPACPI_BRGHT_MODE_MAX) ++ return -EINVAL; + +- dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", +- brightness_mode); +- } ++ /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */ ++ if (brightness_mode == TPACPI_BRGHT_MODE_AUTO || ++ brightness_mode == TPACPI_BRGHT_MODE_MAX) { ++ if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) { ++ /* ++ * IBM models that define HBRV probably have ++ * EC-based backlight level control ++ */ ++ if (acpi_evalf(ec_handle, NULL, "HBRV", "qd")) ++ /* T40-T43, R50-R52, R50e, R51e, X31-X41 */ ++ brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM; ++ else ++ /* all other IBM ThinkPads */ ++ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; ++ } else ++ /* All Lenovo ThinkPads */ ++ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; + +- if (brightness_mode > 3) +- return -EINVAL; ++ dbg_printk(TPACPI_DBG_BRGHT, ++ "selected brightness_mode=%d\n", ++ brightness_mode); ++ } + +- if (brightness_get_raw(&b) < 0) ++ if (tpacpi_brightness_get_raw(&b) < 0) + return 1; + + if (tp_features.bright_16levels) +@@ -5751,7 +5852,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm) + printk(TPACPI_ERR "Could not register backlight device\n"); + return PTR_ERR(ibm_backlight_device); + } +- vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, ++ "brightness is supported\n"); + + ibm_backlight_device->props.max_brightness = + (tp_features.bright_16levels)? 15 : 7; +@@ -5761,13 +5863,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm) + return 0; + } + ++static void brightness_suspend(pm_message_t state) ++{ ++ tpacpi_brightness_checkpoint_nvram(); ++} ++ ++static void brightness_shutdown(void) ++{ ++ tpacpi_brightness_checkpoint_nvram(); ++} ++ + static void brightness_exit(void) + { + if (ibm_backlight_device) { +- vdbg_printk(TPACPI_DBG_EXIT, ++ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT, + "calling backlight_device_unregister()\n"); + backlight_device_unregister(ibm_backlight_device); + } ++ ++ tpacpi_brightness_checkpoint_nvram(); + } + + static int brightness_read(char *p) +@@ -5814,6 +5928,9 @@ static int brightness_write(char *buf) + return -EINVAL; + } + ++ tpacpi_disclose_usertask("procfs brightness", ++ "set level to %d\n", level); ++ + /* + * Now we know what the final level should be, so we try to set it. + * Doing it this way makes the syscall restartable in case of EINTR +@@ -5827,6 +5944,8 @@ static struct ibm_struct brightness_driver_data = { + .read = brightness_read, + .write = brightness_write, + .exit = brightness_exit, ++ .suspend = brightness_suspend, ++ .shutdown = brightness_shutdown, + }; + + /************************************************************************* +@@ -7465,10 +7584,10 @@ module_param_named(fan_control, fan_control_allowed, bool, 0); + MODULE_PARM_DESC(fan_control, + "Enables setting fan parameters features when true"); + +-module_param_named(brightness_mode, brightness_mode, int, 0); ++module_param_named(brightness_mode, brightness_mode, uint, 0); + MODULE_PARM_DESC(brightness_mode, + "Selects brightness control strategy: " +- "0=auto, 1=EC, 2=CMOS, 3=both"); ++ "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM"); + + module_param(brightness_enable, uint, 0); + MODULE_PARM_DESC(brightness_enable, +-- +1.6.2.1 +