summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Salomon <dilinger@debian.org>2008-09-12 18:33:57 -0400
committerAndres Salomon <dilinger@debian.org>2008-09-12 18:33:57 -0400
commitfff47581179f48a2bc5bcc83b691d23de4185bc0 (patch)
treef9456132c3200326b640c265942ab47ea90a31bc
parent93970329291a9ff73301a96a27c4af274f096835 (diff)
parent850b087f7daf1b0251d299cfd04a4aa7b043ba4e (diff)
downloadlwn-fff47581179f48a2bc5bcc83b691d23de4185bc0.tar.gz
lwn-fff47581179f48a2bc5bcc83b691d23de4185bc0.zip
Merge branch 'testing' of git+ssh://dev.laptop.org/git/olpc-2.6 into testing
-rw-r--r--arch/x86/kernel/olpc-pm.c51
-rw-r--r--drivers/net/wireless/libertas/main.c19
2 files changed, 70 insertions, 0 deletions
diff --git a/arch/x86/kernel/olpc-pm.c b/arch/x86/kernel/olpc-pm.c
index acedefbba498..4c758f7e6e02 100644
--- a/arch/x86/kernel/olpc-pm.c
+++ b/arch/x86/kernel/olpc-pm.c
@@ -373,6 +373,15 @@ void olpc_fixup_wakeup(void)
/* tell the wireless module to restart USB communication */
olpc_ec_cmd(0x24, NULL, 0, NULL, 0);
}
+
+ /*
+ * Re-enable all LID events
+ */
+ if (olpc_board_at_least(olpc_board(0xb2))) {
+ geode_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
+ geode_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
+ geode_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
+ }
}
int olpc_fixup_sleep(void)
@@ -711,6 +720,9 @@ static struct attribute_group olpc_attrs = {
static ssize_t wackup_event_show(struct kobject *s, struct kobj_attribute *attr, char *buf);
static ssize_t wackup_event_store(struct kobject *s, struct kobj_attribute *attr, const char *buf, size_t n);
+static ssize_t wackup_all_show(struct kobject *s, struct kobj_attribute *attr, char *buf);
+static ssize_t wackup_all_store(struct kobject *s, struct kobj_attribute *attr, const char *buf, size_t n);
+
static struct kobj_attribute wackup_event_attr[] = {
__ATTR(ps2event, 0600, wackup_event_show, wackup_event_store),
__ATTR(battery_state, 0600, wackup_event_show, wackup_event_store),
@@ -719,6 +731,7 @@ static struct kobj_attribute wackup_event_attr[] = {
__ATTR(ebook_mode_change, 0600, wackup_event_show, wackup_event_store),
__ATTR(wlan, 0600, wackup_event_show, wackup_event_store),
__ATTR(ac_power, 0600, wackup_event_show, wackup_event_store),
+ __ATTR(all, 0600, wackup_all_show, wackup_all_store)
};
static DEFINE_RWLOCK(wackup_event_lock);
@@ -758,6 +771,43 @@ static ssize_t wackup_event_store(struct kobject *s, struct kobj_attribute *attr
return n;
}
+static ssize_t wackup_all_show(struct kobject *s, struct kobj_attribute *attr, char *buf)
+{
+ u8 data;
+
+ read_lock(&wackup_event_lock);
+ olpc_ec_cmd(EC_READ_SCI_MASK, NULL, 0, &data, 1);
+ read_unlock(&wackup_event_lock);
+
+ if (data == 0xff)
+ return sprintf(buf, "1\n");
+ else
+ return sprintf(buf, "0\n");
+}
+
+static ssize_t wackup_all_store(struct kobject *s, struct kobj_attribute *attr, const char *buf, size_t n)
+{
+ unsigned enabled;
+ u8 data;
+ unsigned char shift = attr - wackup_event_attr;
+
+ if (sscanf(buf, "%d\n", &enabled) != 1)
+ return -EINVAL;
+
+ if (enabled == 1)
+ data = 0xff;
+ else if (!enabled)
+ data = 0;
+ else
+ return -EINVAL;
+
+ write_lock(&wackup_event_lock);
+ olpc_ec_cmd(EC_WRITE_SCI_MASK, &data, 1, NULL, 0);
+ write_unlock(&wackup_event_lock);
+
+ return n;
+}
+
static struct attribute * olpc_wackup_event_attributes[] = {
&wackup_event_attr[0].attr,
&wackup_event_attr[1].attr,
@@ -766,6 +816,7 @@ static struct attribute * olpc_wackup_event_attributes[] = {
&wackup_event_attr[4].attr,
&wackup_event_attr[5].attr,
&wackup_event_attr[6].attr,
+ &wackup_event_attr[7].attr,
NULL
};
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 87972fb17569..6ccd395d0972 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1212,7 +1212,13 @@ int lbs_remove_card(struct lbs_private *priv)
cancel_delayed_work(&priv->scan_work);
cancel_delayed_work(&priv->assoc_work);
cancel_work_sync(&priv->mcast_work);
+
+ /* worker thread destruction blocks on the in-flight command which
+ * should have been cleared already in lbs_stop_card().
+ */
+ lbs_deb_main("destroying worker thread\n");
destroy_workqueue(priv->work_thread);
+ lbs_deb_main("done destroying worker thread\n");
if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
priv->psmode = LBS802_11POWERMODECAM;
@@ -1324,13 +1330,26 @@ int lbs_stop_card(struct lbs_private *priv)
device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
}
+ /* Delete the timeout of the currently processing command */
+ del_timer_sync(&priv->command_timer);
+
/* Flush pending command nodes */
spin_lock_irqsave(&priv->driver_lock, flags);
+ lbs_deb_main("clearing pending commands\n");
list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
cmdnode->result = -ENOENT;
cmdnode->cmdwaitqwoken = 1;
wake_up_interruptible(&cmdnode->cmdwait_q);
}
+
+ /* Flush the command the card is currently processing */
+ if (priv->cur_cmd) {
+ lbs_deb_main("clearing current command\n");
+ priv->cur_cmd->result = -ENOENT;
+ priv->cur_cmd->cmdwaitqwoken = 1;
+ wake_up_interruptible(&priv->cur_cmd->cmdwait_q);
+ }
+ lbs_deb_main("done clearing commands\n");
spin_unlock_irqrestore(&priv->driver_lock, flags);
unregister_netdev(dev);