public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* ACPI & driver patch candidates for 2.6.33-rc4
@ 2010-01-16  7:32 Len Brown
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
  2010-01-16 11:58 ` ACPI & driver patch candidates for 2.6.33-rc4 Mattia Dongili
  0 siblings, 2 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi

please speak up now if any of these should not go upstream.

thanks,
-Len


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 01/16] ACPI: EC: Accelerate query execution
  2010-01-16  7:32 ACPI & driver patch candidates for 2.6.33-rc4 Len Brown
@ 2010-01-16  7:32 ` Len Brown
  2010-01-16  7:32   ` [PATCH 02/16] acpi_pad: fix error checks Len Brown
                     ` (14 more replies)
  2010-01-16 11:58 ` ACPI & driver patch candidates for 2.6.33-rc4 Mattia Dongili
  1 sibling, 15 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <astarikovskiy@suse.de>

Split EC query handling into acknowledge and execution phase.
This allows much smaller pending query lattency and lowers chances
of EC going "wild" and losing events.

Reference: http://bugzilla.kernel.org/show_bug.cgi?id=14858

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |  122 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 77 insertions(+), 45 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index fd1801b..9cc3885 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -201,14 +201,13 @@ unlock:
 	spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
 
-static void acpi_ec_gpe_query(void *ec_cxt);
+static int acpi_ec_sync_query(struct acpi_ec *ec);
 
-static int ec_check_sci(struct acpi_ec *ec, u8 state)
+static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
 {
 	if (state & ACPI_EC_FLAG_SCI) {
 		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-			return acpi_os_execute(OSL_EC_BURST_HANDLER,
-				acpi_ec_gpe_query, ec);
+			return acpi_ec_sync_query(ec);
 	}
 	return 0;
 }
@@ -249,11 +248,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 {
 	unsigned long tmp;
 	int ret = 0;
-	pr_debug(PREFIX "transaction start\n");
-	/* disable GPE during transaction if storm is detected */
-	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-		acpi_disable_gpe(NULL, ec->gpe);
-	}
 	if (EC_FLAGS_MSI)
 		udelay(ACPI_EC_MSI_UDELAY);
 	/* start transaction */
@@ -269,16 +263,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	ec->curr = NULL;
 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
-	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-		/* check if we received SCI during transaction */
-		ec_check_sci(ec, acpi_ec_read_status(ec));
-		/* it is safe to enable GPE outside of transaction */
-		acpi_enable_gpe(NULL, ec->gpe);
-	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
-		pr_info(PREFIX "GPE storm detected, "
-			"transactions will use polling mode\n");
-		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
-	}
 	return ret;
 }
 
@@ -321,7 +305,24 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
 		status = -ETIME;
 		goto end;
 	}
+	pr_debug(PREFIX "transaction start\n");
+	/* disable GPE during transaction if storm is detected */
+	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		acpi_disable_gpe(NULL, ec->gpe);
+	}
+
 	status = acpi_ec_transaction_unlocked(ec, t);
+
+	/* check if we received SCI during transaction */
+	ec_check_sci_sync(ec, acpi_ec_read_status(ec));
+	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		/* it is safe to enable GPE outside of transaction */
+		acpi_enable_gpe(NULL, ec->gpe);
+	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+		pr_info(PREFIX "GPE storm detected, "
+			"transactions will use polling mode\n");
+		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+	}
 end:
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
@@ -443,7 +444,7 @@ int ec_transaction(u8 command,
 
 EXPORT_SYMBOL(ec_transaction);
 
-static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
 {
 	int result;
 	u8 d;
@@ -452,20 +453,16 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 				.wlen = 0, .rlen = 1};
 	if (!ec || !data)
 		return -EINVAL;
-
 	/*
 	 * Query the EC to find out which _Qxx method we need to evaluate.
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
-
-	result = acpi_ec_transaction(ec, &t);
+	result = acpi_ec_transaction_unlocked(ec, &t);
 	if (result)
 		return result;
-
 	if (!d)
 		return -ENODATA;
-
 	*data = d;
 	return 0;
 }
@@ -509,43 +506,78 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
 
 EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
-static void acpi_ec_gpe_query(void *ec_cxt)
+static void acpi_ec_run(void *cxt)
 {
-	struct acpi_ec *ec = ec_cxt;
-	u8 value = 0;
-	struct acpi_ec_query_handler *handler, copy;
-
-	if (!ec || acpi_ec_query(ec, &value))
+	struct acpi_ec_query_handler *handler = cxt;
+	if (!handler)
 		return;
-	mutex_lock(&ec->lock);
+	pr_debug(PREFIX "start query execution\n");
+	if (handler->func)
+		handler->func(handler->data);
+	else if (handler->handle)
+		acpi_evaluate_object(handler->handle, NULL, NULL, NULL);
+	pr_debug(PREFIX "stop query execution\n");
+	kfree(handler);
+}
+
+static int acpi_ec_sync_query(struct acpi_ec *ec)
+{
+	u8 value = 0;
+	int status;
+	struct acpi_ec_query_handler *handler, *copy;
+	if ((status = acpi_ec_query_unlocked(ec, &value)))
+		return status;
 	list_for_each_entry(handler, &ec->list, node) {
 		if (value == handler->query_bit) {
 			/* have custom handler for this bit */
-			memcpy(&copy, handler, sizeof(copy));
-			mutex_unlock(&ec->lock);
-			if (copy.func) {
-				copy.func(copy.data);
-			} else if (copy.handle) {
-				acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
-			}
-			return;
+			copy = kmalloc(sizeof(*handler), GFP_KERNEL);
+			if (!copy)
+				return -ENOMEM;
+			memcpy(copy, handler, sizeof(*copy));
+			pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
+			return acpi_os_execute(OSL_GPE_HANDLER,
+				acpi_ec_run, copy);
 		}
 	}
+	return 0;
+}
+
+static void acpi_ec_gpe_query(void *ec_cxt)
+{
+	struct acpi_ec *ec = ec_cxt;
+	if (!ec)
+		return;
+	mutex_lock(&ec->lock);
+	acpi_ec_sync_query(ec);
 	mutex_unlock(&ec->lock);
 }
 
+static void acpi_ec_gpe_query(void *ec_cxt);
+
+static int ec_check_sci(struct acpi_ec *ec, u8 state)
+{
+	if (state & ACPI_EC_FLAG_SCI) {
+		if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+			pr_debug(PREFIX "push gpe query to the queue\n");
+			return acpi_os_execute(OSL_NOTIFY_HANDLER,
+				acpi_ec_gpe_query, ec);
+		}
+	}
+	return 0;
+}
+
 static u32 acpi_ec_gpe_handler(void *data)
 {
 	struct acpi_ec *ec = data;
-	u8 status;
 
 	pr_debug(PREFIX "~~~> interrupt\n");
-	status = acpi_ec_read_status(ec);
 
-	advance_transaction(ec, status);
-	if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+	advance_transaction(ec, acpi_ec_read_status(ec));
+	if (ec_transaction_done(ec) &&
+	    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
 		wake_up(&ec->wait);
-	ec_check_sci(ec, status);
+		ec_check_sci(ec, acpi_ec_read_status(ec));
+	}
 	return ACPI_INTERRUPT_HANDLED;
 }
 
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 02/16] acpi_pad: fix error checks
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 03/16] ACPI video: Prune dupe video devices, unless "video.allow_duplicates" Len Brown
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Chen Gong, Len Brown

From: Chen Gong <gong.chen@linux.intel.com>

There are some fixes listed below:
1. When met a bogus BIOS, the return value of cpu number maybe is
   a negative value so that acpi_pad_pur get an unexpected result.
2. the return value of function acpi_pad_idle_cpus is useless.
3. enhance the process of create_power_saving_task/destroy_power_saving_task
4. Add more error checks when evaluating _PUR object.
5. one typo fix

Signed-off-by: Chen Gong <gong.chen@linux.intel.com>
Acked-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/acpi_pad.c |   37 ++++++++++++++++++++-----------------
 1 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 0d2cdb8..a7bd49f 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -207,7 +207,7 @@ static int power_saving_thread(void *data)
 		 * the mechanism only works when all CPUs have RT task running,
 		 * as if one CPU hasn't RT task, RT task from other CPUs will
 		 * borrow CPU time from this CPU and cause RT task use > 95%
-		 * CPU time. To make 'avoid staration' work, takes a nap here.
+		 * CPU time. To make 'avoid starvation' work, takes a nap here.
 		 */
 		if (do_sleep)
 			schedule_timeout_killable(HZ * idle_pct / 100);
@@ -221,14 +221,18 @@ static struct task_struct *ps_tsks[NR_CPUS];
 static unsigned int ps_tsk_num;
 static int create_power_saving_task(void)
 {
+	int rc = -ENOMEM;
+
 	ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
 		(void *)(unsigned long)ps_tsk_num,
 		"power_saving/%d", ps_tsk_num);
-	if (ps_tsks[ps_tsk_num]) {
+	rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
+	if (!rc)
 		ps_tsk_num++;
-		return 0;
-	}
-	return -EINVAL;
+	else
+		ps_tsks[ps_tsk_num] = NULL;
+
+	return rc;
 }
 
 static void destroy_power_saving_task(void)
@@ -236,6 +240,7 @@ static void destroy_power_saving_task(void)
 	if (ps_tsk_num > 0) {
 		ps_tsk_num--;
 		kthread_stop(ps_tsks[ps_tsk_num]);
+		ps_tsks[ps_tsk_num] = NULL;
 	}
 }
 
@@ -252,7 +257,7 @@ static void set_power_saving_task_num(unsigned int num)
 	}
 }
 
-static int acpi_pad_idle_cpus(unsigned int num_cpus)
+static void acpi_pad_idle_cpus(unsigned int num_cpus)
 {
 	get_online_cpus();
 
@@ -260,7 +265,6 @@ static int acpi_pad_idle_cpus(unsigned int num_cpus)
 	set_power_saving_task_num(num_cpus);
 
 	put_online_cpus();
-	return 0;
 }
 
 static uint32_t acpi_pad_idle_cpus_num(void)
@@ -368,19 +372,21 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device)
 static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
 {
 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	acpi_status status;
 	union acpi_object *package;
 	int rev, num, ret = -EINVAL;
 
-	status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
+		return -EINVAL;
+
+	if (!buffer.length || !buffer.pointer)
 		return -EINVAL;
+
 	package = buffer.pointer;
 	if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
 		goto out;
 	rev = package->package.elements[0].integer.value;
 	num = package->package.elements[1].integer.value;
-	if (rev != 1)
+	if (rev != 1 || num < 0)
 		goto out;
 	*num_cpus = num;
 	ret = 0;
@@ -409,7 +415,7 @@ static void acpi_pad_ost(acpi_handle handle, int stat,
 
 static void acpi_pad_handle_notify(acpi_handle handle)
 {
-	int num_cpus, ret;
+	int num_cpus;
 	uint32_t idle_cpus;
 
 	mutex_lock(&isolated_cpus_lock);
@@ -417,12 +423,9 @@ static void acpi_pad_handle_notify(acpi_handle handle)
 		mutex_unlock(&isolated_cpus_lock);
 		return;
 	}
-	ret = acpi_pad_idle_cpus(num_cpus);
+	acpi_pad_idle_cpus(num_cpus);
 	idle_cpus = acpi_pad_idle_cpus_num();
-	if (!ret)
-		acpi_pad_ost(handle, 0, idle_cpus);
-	else
-		acpi_pad_ost(handle, 1, 0);
+	acpi_pad_ost(handle, 0, idle_cpus);
 	mutex_unlock(&isolated_cpus_lock);
 }
 
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 03/16] ACPI video: Prune dupe video devices, unless "video.allow_duplicates"
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
  2010-01-16  7:32   ` [PATCH 02/16] acpi_pad: fix error checks Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 04/16] x86, ACPI: delete acpi_boot_table_init() return value Len Brown
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Zhang Rui, Len Brown

From: Zhang Rui <rui.zhang@intel.com>

Some buggy BIOS exports multiple ACPI video bus devices for the same
VGA controller, and multiple backlight control methods as well.
This messes up the ACPI video backlight control.

http://bugzilla.kernel.org/show_bug.cgi?id=13577

With this patch applied, only the FIRST ACPI video bus device
under a PCI device node is bind to ACPI video driver by default.

If the first ACPI video bus device doesn't work well, we can use
video.allow_duplicates=1 to go back to the old behavior.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/video.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 05dff63..45e6a29 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -78,6 +78,13 @@ MODULE_LICENSE("GPL");
 static int brightness_switch_enabled = 1;
 module_param(brightness_switch_enabled, bool, 0644);
 
+/*
+ * By default, we don't allow duplicate ACPI video bus devices
+ * under the same VGA controller
+ */
+static int allow_duplicates;
+module_param(allow_duplicates, bool, 0644);
+
 static int register_count = 0;
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
@@ -2233,11 +2240,47 @@ static int acpi_video_resume(struct acpi_device *device)
 	return AE_OK;
 }
 
+static acpi_status
+acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
+			void **return_value)
+{
+	struct acpi_device *device = context;
+	struct acpi_device *sibling;
+	int result;
+
+	if (handle == device->handle)
+		return AE_CTRL_TERMINATE;
+
+	result = acpi_bus_get_device(handle, &sibling);
+	if (result)
+		return AE_OK;
+
+	if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))
+			return AE_ALREADY_EXISTS;
+
+	return AE_OK;
+}
+
 static int acpi_video_bus_add(struct acpi_device *device)
 {
 	struct acpi_video_bus *video;
 	struct input_dev *input;
 	int error;
+	acpi_status status;
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
+				device->parent->handle, 1,
+				acpi_video_bus_match, NULL,
+				device, NULL);
+	if (status == AE_ALREADY_EXISTS) {
+		printk(KERN_WARNING FW_BUG
+			"Duplicate ACPI video bus devices for the"
+			" same VGA controller, please try module "
+			"parameter \"video.allow_duplicates=1\""
+			"if the current driver doesn't work.\n");
+		if (!allow_duplicates)
+			return -ENODEV;
+	}
 
 	video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
 	if (!video)
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 04/16] x86, ACPI: delete acpi_boot_table_init() return value
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
  2010-01-16  7:32   ` [PATCH 02/16] acpi_pad: fix error checks Len Brown
  2010-01-16  7:32   ` [PATCH 03/16] ACPI video: Prune dupe video devices, unless "video.allow_duplicates" Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 05/16] drm/i915: Add HP nx9020/Samsung SX20S to ACPI LID quirk list Len Brown
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Len Brown

From: Len Brown <len.brown@intel.com>

cleanup only.

setup_arch(), doesn't care care if ACPI initialization succeeded
or failed, so delete acpi_boot_table_init()'s return value.

Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/x86/kernel/acpi/boot.c |   22 ++++++----------------
 include/linux/acpi.h        |    6 +++---
 2 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index fb1035c..036d28a 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1529,16 +1529,10 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = {
  *	if acpi_blacklisted() acpi_disabled = 1;
  *	acpi_irq_model=...
  *	...
- *
- * return value: (currently ignored)
- *	0: success
- *	!0: failure
  */
 
-int __init acpi_boot_table_init(void)
+void __init acpi_boot_table_init(void)
 {
-	int error;
-
 	dmi_check_system(acpi_dmi_table);
 
 	/*
@@ -1546,15 +1540,14 @@ int __init acpi_boot_table_init(void)
 	 * One exception: acpi=ht continues far enough to enumerate LAPICs
 	 */
 	if (acpi_disabled && !acpi_ht)
-		return 1;
+		return; 
 
 	/*
 	 * Initialize the ACPI boot-time table parser.
 	 */
-	error = acpi_table_init();
-	if (error) {
+	if (acpi_table_init()) {
 		disable_acpi();
-		return error;
+		return;
 	}
 
 	acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
@@ -1562,18 +1555,15 @@ int __init acpi_boot_table_init(void)
 	/*
 	 * blacklist may disable ACPI entirely
 	 */
-	error = acpi_blacklisted();
-	if (error) {
+	if (acpi_blacklisted()) {
 		if (acpi_force) {
 			printk(KERN_WARNING PREFIX "acpi=force override\n");
 		} else {
 			printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
 			disable_acpi();
-			return error;
+			return;
 		}
 	}
-
-	return 0;
 }
 
 int __init early_acpi_boot_init(void)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 3692425..b926afe 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -80,7 +80,7 @@ char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
 int acpi_boot_init (void);
-int acpi_boot_table_init (void);
+void acpi_boot_table_init (void);
 int acpi_mps_check (void);
 int acpi_numa_init (void);
 
@@ -321,9 +321,9 @@ static inline int acpi_boot_init(void)
 	return 0;
 }
 
-static inline int acpi_boot_table_init(void)
+static inline void acpi_boot_table_init(void)
 {
-	return 0;
+	return;
 }
 
 static inline int acpi_mps_check(void)
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 05/16] drm/i915: Add HP nx9020/Samsung SX20S to ACPI LID quirk list
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (2 preceding siblings ...)
  2010-01-16  7:32   ` [PATCH 04/16] x86, ACPI: delete acpi_boot_table_init() return value Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 06/16] ACPI: SBS: Move SBS HC callback to faster Notify queue Len Brown
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Zhao Yakui, Len Brown

From: Zhao Yakui <yakui.zhao@intel.com>

The HP comaq nx9020/Samsung SX20S laptop always report that the LID status is
closed and we can't use it reliabily for LVDS detection. So add the two boxes
into the quirk list.

http://bugzilla.kernel.org/show_bug.cgi?id=14957
http://bugzilla.kernel.org/show_bug.cgi?id=14554

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Tested-by: Philipp Kohlbecher<xt28@gmx.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/gpu/drm/i915/intel_lvds.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index f4b4aa2..160283a 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -602,6 +602,20 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
 /* Some lid devices report incorrect lid status, assume they're connected */
 static const struct dmi_system_id bad_lid_status[] = {
 	{
+		.ident = "Compaq nx9020",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_BOARD_NAME, "3084"),
+		},
+	},
+	{
+		.ident = "Samsung SX20S",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
+			DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
+		},
+	},
+	{
 		.ident = "Aspire One",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 06/16] ACPI: SBS: Move SBS HC callback to faster Notify queue
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (3 preceding siblings ...)
  2010-01-16  7:32   ` [PATCH 05/16] drm/i915: Add HP nx9020/Samsung SX20S to ACPI LID quirk list Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 07/16] ACPI: EC: Add wait for irq storm Len Brown
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <astarikovskiy@suse.de>

SBS transactions should happen in Notify work queue, to not create
a dead lock with GPE execution accessing SBS devices.

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c    |    3 ++-
 drivers/acpi/sbshc.c |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 9cc3885..0473309 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -535,7 +535,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec)
 				return -ENOMEM;
 			memcpy(copy, handler, sizeof(*copy));
 			pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
-			return acpi_os_execute(OSL_GPE_HANDLER,
+			return acpi_os_execute((copy->func) ?
+				OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER,
 				acpi_ec_run, copy);
 		}
 	}
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index d933980..fd09229 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -242,7 +242,7 @@ static int smbus_alarm(void *context)
 		case ACPI_SBS_CHARGER:
 		case ACPI_SBS_MANAGER:
 		case ACPI_SBS_BATTERY:
-			acpi_os_execute(OSL_GPE_HANDLER,
+			acpi_os_execute(OSL_NOTIFY_HANDLER,
 					acpi_smbus_callback, hc);
 		default:;
 	}
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 07/16] ACPI: EC: Add wait for irq storm
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (4 preceding siblings ...)
  2010-01-16  7:32   ` [PATCH 06/16] ACPI: SBS: Move SBS HC callback to faster Notify queue Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 08/16] ACPI: Advertise to BIOS in _OSC: _OST on _PPC changes Len Brown
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alexey Starikovskiy, Len Brown

From: Alexey Starikovskiy <astarikovskiy@suse.de>

Merge of poll and irq modes accelerated EC transaction, so
that keyboard starts to suffer again. Add msleep(1) into
transaction path for the storm to allow keyboard controller
to do its job.

Reference: http://bugzilla.kernel.org/show_bug.cgi?id=14747

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/ec.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 0473309..d6471bb 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -259,7 +259,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
 	ret = ec_poll(ec);
-	pr_debug(PREFIX "transaction end\n");
 	spin_lock_irqsave(&ec->curr_lock, tmp);
 	ec->curr = NULL;
 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
@@ -316,6 +315,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
 	/* check if we received SCI during transaction */
 	ec_check_sci_sync(ec, acpi_ec_read_status(ec));
 	if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+		msleep(1);
 		/* it is safe to enable GPE outside of transaction */
 		acpi_enable_gpe(NULL, ec->gpe);
 	} else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
@@ -323,6 +323,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
 			"transactions will use polling mode\n");
 		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
 	}
+	pr_debug(PREFIX "transaction end\n");
 end:
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 08/16] ACPI: Advertise to BIOS in _OSC: _OST on _PPC changes
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (5 preceding siblings ...)
  2010-01-16  7:32   ` [PATCH 07/16] ACPI: EC: Add wait for irq storm Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:32   ` [PATCH 09/16] ACPI: Remove unnecessary cast Len Brown
                     ` (7 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: Zhao Yakui, Len Brown

From: Zhao Yakui <yakui.zhao@intel.com>

If the BIOS pokes the system-wide OSC bits to see if Linux
supports evaluating _OST after a _PPC change notification,
answer yes.

Also, fix an oversight where we neglected to set the OSC
bit advertising processor aggregator device support
when acpi-pad is compiled as a module.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/bus.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index cf761b9..a52126e 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -490,9 +490,14 @@ static void acpi_bus_osc_support(void)
 
 	capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
 	capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
-#ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
+#if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\
+			defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
 	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
 #endif
+
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+	capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT;
+#endif
 	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
 		return;
 	if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 09/16] ACPI: Remove unnecessary cast.
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (6 preceding siblings ...)
  2010-01-16  7:32   ` [PATCH 08/16] ACPI: Advertise to BIOS in _OSC: _OST on _PPC changes Len Brown
@ 2010-01-16  7:32   ` Len Brown
  2010-01-16  7:33   ` [PATCH 10/16] ACPI: don't cond_resched if irq is disabled Len Brown
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:32 UTC (permalink / raw)
  To: linux-acpi; +Cc: H Hartley Sweeten, H Hartley Sweeten, Len Brown

From: H Hartley Sweeten <hartleys@visionengravers.com>

The struct seq_file 'private' member is a void *, the cast is not needed.
Also, remove an extra whitespace line.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/processor_thermal.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 140c5c5..6deafb4 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -443,8 +443,7 @@ struct thermal_cooling_device_ops processor_cooling_ops = {
 #ifdef CONFIG_ACPI_PROCFS
 static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_processor *pr = (struct acpi_processor *)seq->private;
-
+	struct acpi_processor *pr = seq->private;
 
 	if (!pr)
 		goto end;
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 10/16] ACPI: don't cond_resched if irq is disabled
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (7 preceding siblings ...)
  2010-01-16  7:32   ` [PATCH 09/16] ACPI: Remove unnecessary cast Len Brown
@ 2010-01-16  7:33   ` Len Brown
  2010-01-16  7:33   ` [PATCH 11/16] eeepc-laptop: disable cpu speed control on EeePC 701 Len Brown
                     ` (5 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Xiaotian Feng, Len Brown

From: Xiaotian Feng <dfeng@redhat.com>

commit 8bd108d adds preemption point after each opcode parse, then
a sleeping function called from invalid context bug was founded
during suspend/resume stage. this was fixed in commit abe1dfa by
don't cond_resched when irq_disabled. But recent commit 138d156 changes
the behaviour to don't cond_resched when in_atomic. This makes the
sleeping function called from invalid context bug happen again, which
is reported in http://lkml.org/lkml/2009/12/1/371.

This patch also fixes http://bugzilla.kernel.org/show_bug.cgi?id=14483

Reported-and-bisected-by: Larry Finger <Larry.Finger@lwfinger.net>
Reported-and-bisected-by: Justin P. Mattock <justinmattock@gmail.com>
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
Acked-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 include/acpi/platform/aclinux.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 9d7febd..0946997 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -152,7 +152,7 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
 #include <linux/hardirq.h>
 #define ACPI_PREEMPTION_POINT() \
 	do { \
-		if (!in_atomic_preempt_off()) \
+		if (!in_atomic_preempt_off() && !irqs_disabled()) \
 			cond_resched(); \
 	} while (0)
 
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 11/16] eeepc-laptop: disable cpu speed control on EeePC 701
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (8 preceding siblings ...)
  2010-01-16  7:33   ` [PATCH 10/16] ACPI: don't cond_resched if irq is disabled Len Brown
@ 2010-01-16  7:33   ` Len Brown
  2010-01-16  7:33   ` [PATCH 12/16] eeepc-laptop: dmi blacklist to disable pci hotplug code Len Brown
                     ` (4 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Alan Jenkins, Corentin Chary, Len Brown

From: Alan Jenkins <alan-jenkins@tuffmail.co.uk>

The EeePC 4G ("701") implements CFVS, but it is not supported by the
pre-installed OS, and the original option to change it in the BIOS
setup screen was removed in later versions.  Judging by the lack of
"Super Hybrid Engine" on Asus product pages, this applies to all "701"
models (4G/4G Surf/2G Surf).

So Asus made a deliberate decision not to support it on this model.
We have several reports that using it can cause the system to hang [1].
That said, it does not happen all the time.  Some users do not
experience it at all (and apparently wish to continue "right-clocking").

Check for the EeePC 701 using DMI.  If met, then disable writes to the
"cpufv" sysfs attribute and log an explanatory message.

Add a "cpufv_disabled" attribute which allow users to override this
policy.  Writing to this attribute will log a second message.

The sysfs attribute is more useful than a module option, because it
makes it easier for userspace scripts to provide consistent behaviour
(according to user configuration), regardless of whether the kernel
includes this change.

[1] <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=559578>

Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/platform/x86/eeepc-laptop.c |   87 +++++++++++++++++++++++++++++++++++
 1 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 5838c69..e954f2a 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -35,6 +35,7 @@
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/leds.h>
+#include <linux/dmi.h>
 
 #define EEEPC_LAPTOP_VERSION	"0.1"
 #define EEEPC_LAPTOP_NAME	"Eee PC Hotkey Driver"
@@ -159,6 +160,7 @@ struct eeepc_laptop {
 	acpi_handle handle;		/* the handle of the acpi device */
 	u32 cm_supported;		/* the control methods supported
 					   by this BIOS */
+	bool cpufv_disabled;
 	u16 event_count[128];		/* count for each event */
 
 	struct platform_device *platform_device;
@@ -378,6 +380,8 @@ static ssize_t store_cpufv(struct device *dev,
 	struct eeepc_cpufv c;
 	int rv, value;
 
+	if (eeepc->cpufv_disabled)
+		return -EPERM;
 	if (get_cpufv(eeepc, &c))
 		return -ENODEV;
 	rv = parse_arg(buf, count, &value);
@@ -389,6 +393,41 @@ static ssize_t store_cpufv(struct device *dev,
 	return rv;
 }
 
+static ssize_t show_cpufv_disabled(struct device *dev,
+			  struct device_attribute *attr,
+			  char *buf)
+{
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
+}
+
+static ssize_t store_cpufv_disabled(struct device *dev,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+	int rv, value;
+
+	rv = parse_arg(buf, count, &value);
+	if (rv < 0)
+		return rv;
+
+	switch (value) {
+	case 0:
+		if (eeepc->cpufv_disabled)
+			pr_warning("cpufv enabled (not officially supported "
+				"on this model)\n");
+		eeepc->cpufv_disabled = false;
+		return rv;
+	case 1:
+		return -EPERM;
+	default:
+		return -EINVAL;
+	}
+}
+
+
 static struct device_attribute dev_attr_cpufv = {
 	.attr = {
 		.name = "cpufv",
@@ -404,12 +443,22 @@ static struct device_attribute dev_attr_available_cpufv = {
 	.show   = show_available_cpufv
 };
 
+static struct device_attribute dev_attr_cpufv_disabled = {
+	.attr = {
+		.name = "cpufv_disabled",
+		.mode = 0644 },
+	.show   = show_cpufv_disabled,
+	.store  = store_cpufv_disabled
+};
+
+
 static struct attribute *platform_attributes[] = {
 	&dev_attr_camera.attr,
 	&dev_attr_cardr.attr,
 	&dev_attr_disp.attr,
 	&dev_attr_cpufv.attr,
 	&dev_attr_available_cpufv.attr,
+	&dev_attr_cpufv_disabled.attr,
 	NULL
 };
 
@@ -1261,6 +1310,42 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
 	}
 }
 
+static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
+{
+	const char *model;
+
+	/*
+	 * Blacklist for setting cpufv (cpu speed).
+	 *
+	 * EeePC 4G ("701") implements CFVS, but it is not supported
+	 * by the pre-installed OS, and the original option to change it
+	 * in the BIOS setup screen was removed in later versions.
+	 *
+	 * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
+	 * this applies to all "701" models (4G/4G Surf/2G Surf).
+	 *
+	 * So Asus made a deliberate decision not to support it on this model.
+	 * We have several reports that using it can cause the system to hang
+	 *
+	 * The hang has also been reported on a "702" (Model name "8G"?).
+	 *
+	 * We avoid dmi_check_system() / dmi_match(), because they use
+	 * substring matching.  We don't want to affect the "701SD"
+	 * and "701SDX" models, because they do support S.H.E.
+	 */
+
+	model = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!model)
+		return;
+
+	if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
+		eeepc->cpufv_disabled = true;
+		pr_info("model %s does not officially support setting cpu "
+			"speed\n", model);
+		pr_info("cpufv disabled to avoid instability\n");
+	}
+}
+
 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
 {
 	int dummy;
@@ -1342,6 +1427,8 @@ static int __devinit eeepc_acpi_add(struct acpi_device *device)
 	strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
 	device->driver_data = eeepc;
 
+	eeepc_dmi_check(eeepc);
+
 	result = eeepc_acpi_init(eeepc, device);
 	if (result)
 		goto fail_platform;
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 12/16] eeepc-laptop: dmi blacklist to disable pci hotplug code
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (9 preceding siblings ...)
  2010-01-16  7:33   ` [PATCH 11/16] eeepc-laptop: disable cpu speed control on EeePC 701 Len Brown
@ 2010-01-16  7:33   ` Len Brown
  2010-01-16  7:33   ` [PATCH 13/16] eeepc-laptop: switch to using sparse keymap library Len Brown
                     ` (3 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

This is a short term workaround for Eeepc 1005HA.

refs: <http://bugzilla.kernel.org/show_bug.cgi?id=14570>

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/platform/x86/eeepc-laptop.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index e954f2a..7fc944a 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -161,6 +161,7 @@ struct eeepc_laptop {
 	u32 cm_supported;		/* the control methods supported
 					   by this BIOS */
 	bool cpufv_disabled;
+	bool hotplug_disabled;
 	u16 event_count[128];		/* count for each event */
 
 	struct platform_device *platform_device;
@@ -845,6 +846,9 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
 	if (result && result != -ENODEV)
 		goto exit;
 
+	if (eeepc->hotplug_disabled)
+		return 0;
+
 	result = eeepc_setup_pci_hotplug(eeepc);
 	/*
 	 * If we get -EBUSY then something else is handling the PCI hotplug -
@@ -1314,6 +1318,10 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
 {
 	const char *model;
 
+	model = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!model)
+		return;
+
 	/*
 	 * Blacklist for setting cpufv (cpu speed).
 	 *
@@ -1333,17 +1341,24 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
 	 * substring matching.  We don't want to affect the "701SD"
 	 * and "701SDX" models, because they do support S.H.E.
 	 */
-
-	model = dmi_get_system_info(DMI_PRODUCT_NAME);
-	if (!model)
-		return;
-
 	if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
 		eeepc->cpufv_disabled = true;
 		pr_info("model %s does not officially support setting cpu "
 			"speed\n", model);
 		pr_info("cpufv disabled to avoid instability\n");
 	}
+
+	/*
+	 * Blacklist for wlan hotplug
+	 *
+	 * Eeepc 1005HA doesn't work like others models and don't need the
+	 * hotplug code. In fact, current hotplug code seems to unplug another
+	 * device...
+	 */
+	if (strcmp(model, "1005HA") == 0) {
+		eeepc->hotplug_disabled = true;
+		pr_info("wlan hotplug disabled\n");
+	}
 }
 
 static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 13/16] eeepc-laptop: switch to using sparse keymap library
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (10 preceding siblings ...)
  2010-01-16  7:33   ` [PATCH 12/16] eeepc-laptop: dmi blacklist to disable pci hotplug code Len Brown
@ 2010-01-16  7:33   ` Len Brown
  2010-01-16  7:33   ` [PATCH 14/16] eeepc-laptop: add hotplug_disable parameter Len Brown
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Dmitry Torokhov, Len Brown

From: Dmitry Torokhov <dtor@mail.ru>

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Tested-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Acked-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/platform/x86/Kconfig        |    1 +
 drivers/platform/x86/eeepc-laptop.c |  186 ++++++++++-------------------------
 2 files changed, 52 insertions(+), 135 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index db32c25..f526e73 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -364,6 +364,7 @@ config EEEPC_LAPTOP
 	select HWMON
 	select LEDS_CLASS
 	select NEW_LEDS
+	select INPUT_SPARSEKMAP
 	---help---
 	  This driver supports the Fn-Fx keys on Eee PC laptops.
 
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 7fc944a..07d7978 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -31,6 +31,7 @@
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
 #include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/rfkill.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
@@ -121,38 +122,28 @@ static const char *cm_setv[] = {
 	NULL, NULL, "PBPS", "TPDS"
 };
 
-struct key_entry {
-	char type;
-	u8 code;
-	u16 keycode;
-};
-
-enum { KE_KEY, KE_END };
-
 static const struct key_entry eeepc_keymap[] = {
-	/* Sleep already handled via generic ACPI code */
-	{KE_KEY, 0x10, KEY_WLAN },
-	{KE_KEY, 0x11, KEY_WLAN },
-	{KE_KEY, 0x12, KEY_PROG1 },
-	{KE_KEY, 0x13, KEY_MUTE },
-	{KE_KEY, 0x14, KEY_VOLUMEDOWN },
-	{KE_KEY, 0x15, KEY_VOLUMEUP },
-	{KE_KEY, 0x16, KEY_DISPLAY_OFF },
-	{KE_KEY, 0x1a, KEY_COFFEE },
-	{KE_KEY, 0x1b, KEY_ZOOM },
-	{KE_KEY, 0x1c, KEY_PROG2 },
-	{KE_KEY, 0x1d, KEY_PROG3 },
-	{KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
-	{KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP },
-	{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
-	{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
-	{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
-	{KE_KEY, 0x37, KEY_F13 }, /* Disable Touchpad */
-	{KE_KEY, 0x38, KEY_F14 },
-	{KE_END, 0},
+	{ KE_KEY, 0x10, { KEY_WLAN } },
+	{ KE_KEY, 0x11, { KEY_WLAN } },
+	{ KE_KEY, 0x12, { KEY_PROG1 } },
+	{ KE_KEY, 0x13, { KEY_MUTE } },
+	{ KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
+	{ KE_KEY, 0x15, { KEY_VOLUMEUP } },
+	{ KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
+	{ KE_KEY, 0x1a, { KEY_COFFEE } },
+	{ KE_KEY, 0x1b, { KEY_ZOOM } },
+	{ KE_KEY, 0x1c, { KEY_PROG2 } },
+	{ KE_KEY, 0x1d, { KEY_PROG3 } },
+	{ KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
+	{ KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
+	{ KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
+	{ KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
+	{ KE_KEY, 0x38, { KEY_F14 } },
+	{ KE_END, 0 },
 };
 
-
 /*
  * This is the main structure, we can use it to store useful information
  */
@@ -1143,120 +1134,42 @@ static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
 /*
  * Input device (i.e. hotkeys)
  */
-static struct key_entry *eeepc_get_entry_by_scancode(
-	struct eeepc_laptop *eeepc,
-	int code)
+static int eeepc_input_init(struct eeepc_laptop *eeepc)
 {
-	struct key_entry *key;
-
-	for (key = eeepc->keymap; key->type != KE_END; key++)
-		if (code == key->code)
-			return key;
+	struct input_dev *input;
+	int error;
 
-	return NULL;
-}
-
-static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
-{
-	static struct key_entry *key;
-
-	key = eeepc_get_entry_by_scancode(eeepc, event);
-	if (key) {
-		switch (key->type) {
-		case KE_KEY:
-			input_report_key(eeepc->inputdev, key->keycode,
-						1);
-			input_sync(eeepc->inputdev);
-			input_report_key(eeepc->inputdev, key->keycode,
-						0);
-			input_sync(eeepc->inputdev);
-			break;
-		}
+	input = input_allocate_device();
+	if (!input) {
+		pr_info("Unable to allocate input device\n");
+		return -ENOMEM;
 	}
-}
-
-static struct key_entry *eeepc_get_entry_by_keycode(
-	struct eeepc_laptop *eeepc, int code)
-{
-	struct key_entry *key;
-
-	for (key = eeepc->keymap; key->type != KE_END; key++)
-		if (code == key->keycode && key->type == KE_KEY)
-			return key;
 
-	return NULL;
-}
+	input->name = "Asus EeePC extra buttons";
+	input->phys = EEEPC_LAPTOP_FILE "/input0";
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = &eeepc->platform_device->dev;
 
-static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
-{
-	struct eeepc_laptop *eeepc = input_get_drvdata(dev);
-	struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode);
-
-	if (key && key->type == KE_KEY) {
-		*keycode = key->keycode;
-		return 0;
+	error = sparse_keymap_setup(input, eeepc_keymap, NULL);
+	if (error) {
+		pr_err("Unable to setup input device keymap\n");
+		goto err_free_dev;
 	}
 
-	return -EINVAL;
-}
-
-static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
-{
-	struct eeepc_laptop *eeepc = input_get_drvdata(dev);
-	struct key_entry *key;
-	int old_keycode;
-
-	if (keycode < 0 || keycode > KEY_MAX)
-		return -EINVAL;
-
-	key = eeepc_get_entry_by_scancode(eeepc, scancode);
-	if (key && key->type == KE_KEY) {
-		old_keycode = key->keycode;
-		key->keycode = keycode;
-		set_bit(keycode, dev->keybit);
-		if (!eeepc_get_entry_by_keycode(eeepc, old_keycode))
-			clear_bit(old_keycode, dev->keybit);
-		return 0;
+	error = input_register_device(input);
+	if (error) {
+		pr_err("Unable to register input device\n");
+		goto err_free_keymap;
 	}
 
-	return -EINVAL;
-}
-
-static int eeepc_input_init(struct eeepc_laptop *eeepc)
-{
-	const struct key_entry *key;
-	int result;
-
-	eeepc->inputdev = input_allocate_device();
-	if (!eeepc->inputdev) {
-		pr_info("Unable to allocate input device\n");
-		return -ENOMEM;
-	}
-	eeepc->inputdev->name = "Asus EeePC extra buttons";
-	eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
-	eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0";
-	eeepc->inputdev->id.bustype = BUS_HOST;
-	eeepc->inputdev->getkeycode = eeepc_getkeycode;
-	eeepc->inputdev->setkeycode = eeepc_setkeycode;
-	input_set_drvdata(eeepc->inputdev, eeepc);
-
-	eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap),
-				GFP_KERNEL);
-	for (key = eeepc_keymap; key->type != KE_END; key++) {
-		switch (key->type) {
-		case KE_KEY:
-			set_bit(EV_KEY, eeepc->inputdev->evbit);
-			set_bit(key->keycode, eeepc->inputdev->keybit);
-			break;
-		}
-	}
-	result = input_register_device(eeepc->inputdev);
-	if (result) {
-		pr_info("Unable to register input device\n");
-		input_free_device(eeepc->inputdev);
-		return result;
-	}
+	eeepc->inputdev = input;
 	return 0;
+
+ err_free_keymap:
+	sparse_keymap_free(input);
+ err_free_dev:
+	input_free_device(input);
+	return error;
 }
 
 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
@@ -1306,11 +1219,12 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
 				* event will be desired value (or else ignored)
 				*/
 			}
-			eeepc_input_notify(eeepc, event);
+			sparse_keymap_report_event(eeepc->inputdev, event,
+						   1, true);
 		}
 	} else {
 		/* Everything else is a bona-fide keypress event */
-		eeepc_input_notify(eeepc, event);
+		sparse_keymap_report_event(eeepc->inputdev, event, 1, true);
 	}
 }
 
@@ -1554,10 +1468,12 @@ static int __init eeepc_laptop_init(void)
 	result = acpi_bus_register_driver(&eeepc_acpi_driver);
 	if (result < 0)
 		goto fail_acpi_driver;
+
 	if (!eeepc_device_present) {
 		result = -ENODEV;
 		goto fail_no_device;
 	}
+
 	return 0;
 
 fail_no_device:
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 14/16] eeepc-laptop: add hotplug_disable parameter
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (11 preceding siblings ...)
  2010-01-16  7:33   ` [PATCH 13/16] eeepc-laptop: switch to using sparse keymap library Len Brown
@ 2010-01-16  7:33   ` Len Brown
  2010-01-16  7:33   ` [PATCH 15/16] eeepc-laptop: disable wireless hotplug for 1201N Len Brown
  2010-01-16  7:33   ` [PATCH 16/16] ACPI: Fix section mismatch error for acpi_early_processor_set_pdc() Len Brown
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Some new models need to disable wireless hotplug.
For the moment, we don't know excactly what models need that,
except 1005HA.
Users will be able to use that param as a workaround.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/platform/x86/eeepc-laptop.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 07d7978..a959abd 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -50,6 +50,14 @@ MODULE_AUTHOR("Corentin Chary, Eric Cooper");
 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
 MODULE_LICENSE("GPL");
 
+static bool hotplug_disabled;
+
+module_param(hotplug_disabled, bool, 0644);
+MODULE_PARM_DESC(hotplug_disabled,
+		 "Disable hotplug for wireless device. "
+		 "If your laptop need that, please report to "
+		 "acpi4asus-user@lists.sourceforge.net.");
+
 /*
  * Definitions for Asus EeePC
  */
@@ -1356,6 +1364,8 @@ static int __devinit eeepc_acpi_add(struct acpi_device *device)
 	strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
 	device->driver_data = eeepc;
 
+	eeepc->hotplug_disabled = hotplug_disabled;
+
 	eeepc_dmi_check(eeepc);
 
 	result = eeepc_acpi_init(eeepc, device);
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 15/16] eeepc-laptop: disable wireless hotplug for 1201N
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (12 preceding siblings ...)
  2010-01-16  7:33   ` [PATCH 14/16] eeepc-laptop: add hotplug_disable parameter Len Brown
@ 2010-01-16  7:33   ` Len Brown
  2010-01-16  7:33   ` [PATCH 16/16] ACPI: Fix section mismatch error for acpi_early_processor_set_pdc() Len Brown
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Corentin Chary, Len Brown

From: Corentin Chary <corentincj@iksaif.net>

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/platform/x86/eeepc-laptop.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index a959abd..e2be6bb 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -1277,7 +1277,7 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
 	 * hotplug code. In fact, current hotplug code seems to unplug another
 	 * device...
 	 */
-	if (strcmp(model, "1005HA") == 0) {
+	if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) {
 		eeepc->hotplug_disabled = true;
 		pr_info("wlan hotplug disabled\n");
 	}
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 16/16] ACPI: Fix section mismatch error for acpi_early_processor_set_pdc()
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
                     ` (13 preceding siblings ...)
  2010-01-16  7:33   ` [PATCH 15/16] eeepc-laptop: disable wireless hotplug for 1201N Len Brown
@ 2010-01-16  7:33   ` Len Brown
  14 siblings, 0 replies; 18+ messages in thread
From: Len Brown @ 2010-01-16  7:33 UTC (permalink / raw)
  To: linux-acpi; +Cc: Luck, Tony, Len Brown

From: Luck, Tony <tony.luck@intel.com>

Alex Chiang introduced acpi_early_processor_set_pdc() in commit:
 ACPI: processor: call _PDC early
 78f1699659963fff97975df44db6d5dbe7218e55

But this results in a section mismatch:

WARNING: drivers/acpi/acpi.o(.text+0xa9c1): Section mismatch in reference from the
function acpi_early_processor_set_pdc() to the variable .cpuinit.data:processor_idle_dmi_table
The function acpi_early_processor_set_pdc() references
the variable __cpuinitdata processor_idle_dmi_table.
This is often because acpi_early_processor_set_pdc lacks a __cpuinitdata
annotation or the annotation of processor_idle_dmi_table is wrong.

The only caller of acpi_early_processor_set_pdc() is acpi_bus_init() which
is an "__init" function. So the correct fix here is to mark
acpi_early_processor_set_pdc() "__init" too.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Acked-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/processor_pdc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
index 30e4dc0..7d4ee39 100644
--- a/drivers/acpi/processor_pdc.c
+++ b/drivers/acpi/processor_pdc.c
@@ -151,7 +151,7 @@ early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
 	return AE_OK;
 }
 
-void acpi_early_processor_set_pdc(void)
+void __init acpi_early_processor_set_pdc(void)
 {
 	/*
 	 * Check whether the system is DMI table. If yes, OSPM
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: ACPI & driver patch candidates for 2.6.33-rc4
  2010-01-16  7:32 ACPI & driver patch candidates for 2.6.33-rc4 Len Brown
  2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
@ 2010-01-16 11:58 ` Mattia Dongili
  1 sibling, 0 replies; 18+ messages in thread
From: Mattia Dongili @ 2010-01-16 11:58 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

On Sat, Jan 16, 2010 at 02:32:50AM -0500, Len Brown wrote:
> please speak up now if any of these should not go upstream.

Hi Len,

Please also apply 
  [PATCH] sony-laptop - fix using of uninitialized variable
from Dmitry on Jan 10th[1]

[1]: http://patchwork.kernel.org/patch/71976/
-- 
mattia
:wq!

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2010-01-16 11:58 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-16  7:32 ACPI & driver patch candidates for 2.6.33-rc4 Len Brown
2010-01-16  7:32 ` [PATCH 01/16] ACPI: EC: Accelerate query execution Len Brown
2010-01-16  7:32   ` [PATCH 02/16] acpi_pad: fix error checks Len Brown
2010-01-16  7:32   ` [PATCH 03/16] ACPI video: Prune dupe video devices, unless "video.allow_duplicates" Len Brown
2010-01-16  7:32   ` [PATCH 04/16] x86, ACPI: delete acpi_boot_table_init() return value Len Brown
2010-01-16  7:32   ` [PATCH 05/16] drm/i915: Add HP nx9020/Samsung SX20S to ACPI LID quirk list Len Brown
2010-01-16  7:32   ` [PATCH 06/16] ACPI: SBS: Move SBS HC callback to faster Notify queue Len Brown
2010-01-16  7:32   ` [PATCH 07/16] ACPI: EC: Add wait for irq storm Len Brown
2010-01-16  7:32   ` [PATCH 08/16] ACPI: Advertise to BIOS in _OSC: _OST on _PPC changes Len Brown
2010-01-16  7:32   ` [PATCH 09/16] ACPI: Remove unnecessary cast Len Brown
2010-01-16  7:33   ` [PATCH 10/16] ACPI: don't cond_resched if irq is disabled Len Brown
2010-01-16  7:33   ` [PATCH 11/16] eeepc-laptop: disable cpu speed control on EeePC 701 Len Brown
2010-01-16  7:33   ` [PATCH 12/16] eeepc-laptop: dmi blacklist to disable pci hotplug code Len Brown
2010-01-16  7:33   ` [PATCH 13/16] eeepc-laptop: switch to using sparse keymap library Len Brown
2010-01-16  7:33   ` [PATCH 14/16] eeepc-laptop: add hotplug_disable parameter Len Brown
2010-01-16  7:33   ` [PATCH 15/16] eeepc-laptop: disable wireless hotplug for 1201N Len Brown
2010-01-16  7:33   ` [PATCH 16/16] ACPI: Fix section mismatch error for acpi_early_processor_set_pdc() Len Brown
2010-01-16 11:58 ` ACPI & driver patch candidates for 2.6.33-rc4 Mattia Dongili

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox