Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 254832
b: refs/heads/master
c: 8875962
h: refs/heads/master
v: v3
  • Loading branch information
Colin Cross authored and Rafael J. Wysocki committed Jul 11, 2011
1 parent e00e4b0 commit 8d537c6
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 199 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 71a1b44b036457169e7974eea0b5b37f64176952
refs/heads/master: 887596224cca4dc4669c53e4d7a33fcfc9d9e823
5 changes: 0 additions & 5 deletions trunk/Documentation/laptops/thinkpad-acpi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,6 @@ Events that are never propagated by the driver:
0x2404 System is waking up from hibernation to undock
0x2405 System is waking up from hibernation to eject bay
0x5010 Brightness level changed/control event
0x6000 KEYBOARD: Numlock key pressed
0x6005 KEYBOARD: Fn key pressed (TO BE VERIFIED)

Events that are propagated by the driver to userspace:

Expand All @@ -547,16 +545,13 @@ Events that are propagated by the driver to userspace:
0x3006 Bay hotplug request (hint to power up SATA link when
the optical drive tray is ejected)
0x4003 Undocked (see 0x2x04), can sleep again
0x4010 Docked into hotplug port replicator (non-ACPI dock)
0x4011 Undocked from hotplug port replicator (non-ACPI dock)
0x500B Tablet pen inserted into its storage bay
0x500C Tablet pen removed from its storage bay
0x6011 ALARM: battery is too hot
0x6012 ALARM: battery is extremely hot
0x6021 ALARM: a sensor is too hot
0x6022 ALARM: a sensor is extremely hot
0x6030 System thermal table changed
0x6040 Nvidia Optimus/AC adapter related (TO BE VERIFIED)

Battery nearly empty alarms are a last resort attempt to get the
operating system to hibernate or shutdown cleanly (0x2313), or shutdown
Expand Down
45 changes: 38 additions & 7 deletions trunk/Documentation/spinlocks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@ static DEFINE_SPINLOCK(xxx_lock);
The above is always safe. It will disable interrupts _locally_, but the
spinlock itself will guarantee the global lock, so it will guarantee that
there is only one thread-of-control within the region(s) protected by that
lock. This works well even under UP also, so the code does _not_ need to
worry about UP vs SMP issues: the spinlocks work correctly under both.
lock. This works well even under UP. The above sequence under UP
essentially is just the same as doing

unsigned long flags;

save_flags(flags); cli();
... critical section ...
restore_flags(flags);

so the code does _not_ need to worry about UP vs SMP issues: the spinlocks
work correctly under both (and spinlocks are actually more efficient on
architectures that allow doing the "save_flags + cli" in one operation).

NOTE! Implications of spin_locks for memory are further described in:

Expand All @@ -26,7 +36,27 @@ The above is usually pretty simple (you usually need and want only one
spinlock for most things - using more than one spinlock can make things a
lot more complex and even slower and is usually worth it only for
sequences that you _know_ need to be split up: avoid it at all cost if you
aren't sure).
aren't sure). HOWEVER, it _does_ mean that if you have some code that does

cli();
.. critical section ..
sti();

and another sequence that does

spin_lock_irqsave(flags);
.. critical section ..
spin_unlock_irqrestore(flags);

then they are NOT mutually exclusive, and the critical regions can happen
at the same time on two different CPU's. That's fine per se, but the
critical regions had better be critical for different things (ie they
can't stomp on each other).

The above is a problem mainly if you end up mixing code - for example the
routines in ll_rw_block() tend to use cli/sti to protect the atomicity of
their actions, and if a driver uses spinlocks instead then you should
think about issues like the above.

This is really the only really hard part about spinlocks: once you start
using spinlocks they tend to expand to areas you might not have noticed
Expand Down Expand Up @@ -90,10 +120,11 @@ Lesson 3: spinlocks revisited.

The single spin-lock primitives above are by no means the only ones. They
are the most safe ones, and the ones that work under all circumstances,
but partly _because_ they are safe they are also fairly slow. They are slower
than they'd need to be, because they do have to disable interrupts
(which is just a single instruction on a x86, but it's an expensive one -
and on other architectures it can be worse).
but partly _because_ they are safe they are also fairly slow. They are
much faster than a generic global cli/sti pair, but slower than they'd
need to be, because they do have to disable interrupts (which is just a
single instruction on a x86, but it's an expensive one - and on other
architectures it can be worse).

If you have a case where you have to protect a data structure across
several CPU's and you want to use spinlocks you can potentially use
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/base/syscore.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/syscore_ops.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/interrupt.h>

static LIST_HEAD(syscore_ops_list);
static DEFINE_MUTEX(syscore_ops_lock);
Expand Down Expand Up @@ -48,6 +49,13 @@ int syscore_suspend(void)
struct syscore_ops *ops;
int ret = 0;

pr_debug("Checking wakeup interrupts\n");

/* Return error code if there are any wakeup interrupts pending. */
ret = check_wakeup_irqs();
if (ret)
return ret;

WARN_ONCE(!irqs_disabled(),
"Interrupts enabled before system core suspend.\n");

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ static void __exit acpi_cpufreq_exit(void)

cpufreq_unregister_driver(&acpi_cpufreq_driver);

free_acpi_perf_data();
free_percpu(acpi_perf_data);
}

module_param(acpi_pstate_strict, uint, 0644);
Expand Down
6 changes: 0 additions & 6 deletions trunk/drivers/firewire/ohci.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd

#define QUIRK_CYCLE_TIMER 1
#define QUIRK_RESET_PACKET 2
Expand Down Expand Up @@ -3191,11 +3190,6 @@ static int __devinit pci_probe(struct pci_dev *dev,
int i, err;
size_t size;

if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) {
dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n");
return -ENOSYS;
}

ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
if (ohci == NULL) {
err = -ENOMEM;
Expand Down
3 changes: 0 additions & 3 deletions trunk/drivers/net/wireless/ath/ath5k/desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,10 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
case AR5K_PKT_TYPE_BEACON:
case AR5K_PKT_TYPE_PROBE_RESP:
frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
break;
case AR5K_PKT_TYPE_PIFS:
frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
break;
default:
frame_type = type;
break;
}

tx_ctl->tx_control_0 |=
Expand Down
47 changes: 18 additions & 29 deletions trunk/drivers/platform/x86/acer-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1156,9 +1156,9 @@ static acpi_status wmid3_set_device_status(u32 value, u16 device)
struct wmid3_gds_input_param params = {
.function_num = 0x1,
.hotkey_number = 0x01,
.devices = ACER_WMID3_GDS_WIRELESS |
ACER_WMID3_GDS_THREEG |
ACER_WMID3_GDS_WIMAX |
.devices = ACER_WMID3_GDS_WIRELESS &
ACER_WMID3_GDS_THREEG &
ACER_WMID3_GDS_WIMAX &
ACER_WMID3_GDS_BLUETOOTH,
};
struct acpi_buffer input = {
Expand Down Expand Up @@ -1445,8 +1445,6 @@ static void acer_wmi_notify(u32 value, void *context)
union acpi_object *obj;
struct event_return_value return_value;
acpi_status status;
u16 device_state;
const struct key_entry *key;

status = wmi_get_event_data(value, &response);
if (status != AE_OK) {
Expand Down Expand Up @@ -1474,32 +1472,23 @@ static void acer_wmi_notify(u32 value, void *context)

switch (return_value.function) {
case WMID_HOTKEY_EVENT:
device_state = return_value.device_state;
pr_debug("device state: 0x%x\n", device_state);

key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
return_value.key_num);
if (!key) {
if (return_value.device_state) {
u16 device_state = return_value.device_state;
pr_debug("device state: 0x%x\n", device_state);
if (has_cap(ACER_CAP_WIRELESS))
rfkill_set_sw_state(wireless_rfkill,
!(device_state & ACER_WMID3_GDS_WIRELESS));
if (has_cap(ACER_CAP_BLUETOOTH))
rfkill_set_sw_state(bluetooth_rfkill,
!(device_state & ACER_WMID3_GDS_BLUETOOTH));
if (has_cap(ACER_CAP_THREEG))
rfkill_set_sw_state(threeg_rfkill,
!(device_state & ACER_WMID3_GDS_THREEG));
}
if (!sparse_keymap_report_event(acer_wmi_input_dev,
return_value.key_num, 1, true))
pr_warn("Unknown key number - 0x%x\n",
return_value.key_num);
} else {
switch (key->keycode) {
case KEY_WLAN:
case KEY_BLUETOOTH:
if (has_cap(ACER_CAP_WIRELESS))
rfkill_set_sw_state(wireless_rfkill,
!(device_state & ACER_WMID3_GDS_WIRELESS));
if (has_cap(ACER_CAP_THREEG))
rfkill_set_sw_state(threeg_rfkill,
!(device_state & ACER_WMID3_GDS_THREEG));
if (has_cap(ACER_CAP_BLUETOOTH))
rfkill_set_sw_state(bluetooth_rfkill,
!(device_state & ACER_WMID3_GDS_BLUETOOTH));
break;
}
sparse_keymap_report_entry(acer_wmi_input_dev, key,
1, true);
}
break;
default:
pr_warn("Unknown function number - %d - %d\n",
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/platform/x86/asus-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,6 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
return power;

memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_PLATFORM;
props.max_brightness = max;
bd = backlight_device_register(asus->driver->name,
&asus->platform_device->dev, asus,
Expand Down
4 changes: 1 addition & 3 deletions trunk/drivers/platform/x86/compal-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,10 +1030,8 @@ static int __devinit compal_probe(struct platform_device *pdev)
initialize_fan_control_data(data);

err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group);
if (err) {
kfree(data);
if (err)
return err;
}

data->hwmon_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(data->hwmon_dev)) {
Expand Down
30 changes: 25 additions & 5 deletions trunk/drivers/platform/x86/dell-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,12 @@ static int dell_rfkill_set(void *data, bool blocked)
dell_send_request(buffer, 17, 11);

/* If the hardware switch controls this radio, and the hardware
switch is disabled, don't allow changing the software state */
switch is disabled, don't allow changing the software state.
If the hardware switch is reported as not supported, always
fire the SMI to toggle the killswitch. */
if ((hwswitch_state & BIT(hwswitch_bit)) &&
!(buffer->output[1] & BIT(16))) {
!(buffer->output[1] & BIT(16)) &&
(buffer->output[1] & BIT(0))) {
ret = -EINVAL;
goto out;
}
Expand Down Expand Up @@ -400,6 +403,23 @@ static const struct file_operations dell_debugfs_fops = {

static void dell_update_rfkill(struct work_struct *ignored)
{
int status;

get_buffer();
dell_send_request(buffer, 17, 11);
status = buffer->output[1];
release_buffer();

/* if hardware rfkill is not supported, set it explicitly */
if (!(status & BIT(0))) {
if (wifi_rfkill)
dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17));
if (bluetooth_rfkill)
dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18));
if (wwan_rfkill)
dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19));
}

if (wifi_rfkill)
dell_rfkill_query(wifi_rfkill, (void *)1);
if (bluetooth_rfkill)
Expand Down Expand Up @@ -540,11 +560,11 @@ static int dell_get_intensity(struct backlight_device *bd)
else
dell_send_request(buffer, 0, 1);

ret = buffer->output[1];

out:
release_buffer();
return ret;
if (ret)
return ret;
return buffer->output[1];
}

static const struct backlight_ops dell_ops = {
Expand Down
11 changes: 5 additions & 6 deletions trunk/drivers/platform/x86/hp-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ static int hp_wmi_perform_query(int query, int write, void *buffer,
};
struct acpi_buffer input = { sizeof(struct bios_args), &args };
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
u32 rc;

if (WARN_ON(insize > sizeof(args.data)))
return -EINVAL;
Expand All @@ -225,13 +224,13 @@ static int hp_wmi_perform_query(int query, int write, void *buffer,
}

bios_return = (struct bios_return *)obj->buffer.pointer;
rc = bios_return->return_code;

if (rc) {
if (rc != HPWMI_RET_UNKNOWN_CMDTYPE)
pr_warn("query 0x%x returned error 0x%x\n", query, rc);
if (bios_return->return_code) {
if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE)
pr_warn("query 0x%x returned error 0x%x\n",
query, bios_return->return_code);
kfree(obj);
return rc;
return bios_return->return_code;
}

if (!outsize) {
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/platform/x86/intel_oaktrail.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ static int oaktrail_backlight_init(void)
struct backlight_properties props;

memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_PLATFORM;
props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX;
bd = backlight_device_register(DRIVER_NAME,
&oaktrail_device->dev, NULL,
Expand Down
Loading

0 comments on commit 8d537c6

Please sign in to comment.