From: Octavian Purdila <octavian.purdila@intel.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
Len Brown <lenb@kernel.org>,
Matt Fleming <matt@codeblueprint.co.uk>,
Mark Brown <broonie@kernel.org>, Wolfram Sang <wsa@the-dreams.de>
Cc: Joel Becker <jlbec@evilplan.org>,
linux-acpi@vger.kernel.org, linux-efi@vger.kernel.org,
linux-i2c@vger.kernel.org, linux-spi@vger.kernel.org,
linux-kernel@vger.kernel.org, irina.tirdea@intel.com,
Octavian Purdila <octavian.purdila@intel.com>
Subject: [RFC PATCH v2 04/10] acpi: add support for ACPI reconfiguration notifiers
Date: Wed, 20 Apr 2016 01:39:02 +0300 [thread overview]
Message-ID: <1461105548-20618-5-git-send-email-octavian.purdila@intel.com> (raw)
In-Reply-To: <1461105548-20618-1-git-send-email-octavian.purdila@intel.com>
Add support for ACPI reconfiguration notifiers to allow subsystems to
react to changes in the ACPI tables that happen after the initial
enumeration. This is similar with the way dynamic device tree
notifications work.
The reconfigure notifications supported for now are device add and
device remove.
Since ACPICA allows only one table notification handler, this patch
makes the table notifier function generic and moves it out of the
sysfs specific code.
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
---
drivers/acpi/bus.c | 9 +++++++
drivers/acpi/internal.h | 3 +++
drivers/acpi/scan.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-
drivers/acpi/sysfs.c | 6 ++---
include/acpi/acpi_bus.h | 18 +++++++++++++
5 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c068c82..dcac6f8 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -988,6 +988,13 @@ void __init acpi_subsystem_init(void)
}
}
+static acpi_status acpi_bus_table_handler(u32 event, void *table, void *context)
+{
+ acpi_scan_table_handler(event, table, context);
+
+ return acpi_sysfs_table_handler(event, table, context);
+}
+
static int __init acpi_bus_init(void)
{
int result;
@@ -1032,6 +1039,8 @@ static int __init acpi_bus_init(void)
* _PDC control method may load dynamic SSDT tables,
* and we need to install the table handler before that.
*/
+ status = acpi_install_table_handler(acpi_bus_table_handler, NULL);
+
acpi_sysfs_init();
acpi_early_processor_set_pdc();
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 7c18847..ba878d8 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -86,6 +86,9 @@ bool acpi_queue_hotplug_work(struct work_struct *work);
void acpi_device_hotplug(struct acpi_device *adev, u32 src);
bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
+acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context);
+void acpi_scan_table_handler(u32 event, void *table, void *context);
+
/* --------------------------------------------------------------------------
Device Node Initialization / Removal
-------------------------------------------------------------------------- */
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 7656ea4..343c105 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -494,6 +494,8 @@ static void acpi_device_del(struct acpi_device *device)
device_del(&device->dev);
}
+static BLOCKING_NOTIFIER_HEAD(acpi_reconfig_chain);
+
static LIST_HEAD(acpi_device_del_list);
static DEFINE_MUTEX(acpi_device_del_lock);
@@ -514,6 +516,9 @@ static void acpi_device_del_work_fn(struct work_struct *work_not_used)
mutex_unlock(&acpi_device_del_lock);
+ blocking_notifier_call_chain(&acpi_reconfig_chain,
+ ACPI_RECONFIG_DEVICE_REMOVE, adev);
+
acpi_device_del(adev);
/*
* Drop references to all power resources that might have been
@@ -1676,7 +1681,7 @@ static bool acpi_default_enumeration(struct acpi_device *device)
bool is_spi_i2c_slave = false;
/*
- * Do not enemerate SPI/I2C slaves as they will be enuerated by their
+ * Do not enemerate SPI/I2C slaves as they will be enumerated by their
* respective parents.
*/
INIT_LIST_HEAD(&resource_list);
@@ -1685,6 +1690,9 @@ static bool acpi_default_enumeration(struct acpi_device *device)
acpi_dev_free_resource_list(&resource_list);
if (!is_spi_i2c_slave)
acpi_create_platform_device(device);
+ else
+ blocking_notifier_call_chain(&acpi_reconfig_chain,
+ ACPI_RECONFIG_DEVICE_ADD, device);
return !is_spi_i2c_slave;
}
@@ -1919,6 +1927,8 @@ static int acpi_bus_scan_fixed(void)
return result < 0 ? result : 0;
}
+static bool acpi_scan_initialized;
+
int __init acpi_scan_init(void)
{
int result;
@@ -1963,6 +1973,8 @@ int __init acpi_scan_init(void)
acpi_update_all_gpes();
+ acpi_scan_initialized = true;
+
out:
mutex_unlock(&acpi_scan_lock);
return result;
@@ -2006,3 +2018,57 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
return count;
}
+
+struct acpi_table_events_work {
+ struct work_struct work;
+ void *table;
+ u32 event;
+};
+
+void acpi_table_events_fn(struct work_struct *work)
+{
+ struct acpi_table_events_work *tew;
+
+ tew = container_of(work, struct acpi_table_events_work, work);
+
+ if (tew->event == ACPI_TABLE_EVENT_LOAD) {
+ acpi_scan_lock_acquire();
+ acpi_bus_scan(ACPI_ROOT_OBJECT);
+ acpi_scan_lock_release();
+ }
+
+ kfree(tew);
+}
+
+void acpi_scan_table_handler(u32 event, void *table, void *context)
+{
+ struct acpi_table_events_work *tew;
+
+ if (!acpi_scan_initialized)
+ return;
+
+ if (event != ACPI_TABLE_EVENT_LOAD)
+ return;
+
+ tew = kmalloc(sizeof(*tew), GFP_KERNEL);
+ if (!tew)
+ return;
+
+ INIT_WORK(&tew->work, acpi_table_events_fn);
+ tew->table = table;
+ tew->event = event;
+
+ schedule_work(&tew->work);
+}
+
+int acpi_reconfig_notifier_register(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&acpi_reconfig_chain, nb);
+}
+EXPORT_SYMBOL(acpi_reconfig_notifier_register);
+
+int acpi_reconfig_notifier_unregister(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&acpi_reconfig_chain, nb);
+}
+EXPORT_SYMBOL(acpi_reconfig_notifier_unregister);
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 0243d37..d132d66 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -378,8 +378,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
return;
}
-static acpi_status
-acpi_sysfs_table_handler(u32 event, void *table, void *context)
+acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
{
struct acpi_table_attr *table_attr;
@@ -452,9 +451,8 @@ static int acpi_tables_sysfs_init(void)
kobject_uevent(tables_kobj, KOBJ_ADD);
kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
- status = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
- return ACPI_FAILURE(status) ? -EINVAL : 0;
+ return 0;
err_dynamic_tables:
kobject_put(tables_kobj);
err:
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 14362a8..05ba5d4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -518,6 +518,14 @@ int acpi_match_device_ids(struct acpi_device *device,
int acpi_create_dir(struct acpi_device *);
void acpi_remove_dir(struct acpi_device *);
+enum acpi_reconfig_event {
+ ACPI_RECONFIG_DEVICE_ADD = 0,
+ ACPI_RECONFIG_DEVICE_REMOVE,
+};
+
+int acpi_reconfig_notifier_register(struct notifier_block *nb);
+int acpi_reconfig_notifier_unregister(struct notifier_block *nb);
+
static inline bool acpi_device_enumerated(struct acpi_device *adev)
{
return adev && adev->flags.initialized && adev->flags.visited;
@@ -643,6 +651,16 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
static inline int register_acpi_bus_type(void *bus) { return 0; }
static inline int unregister_acpi_bus_type(void *bus) { return 0; }
+static inline int acpi_reconfig_notifier_register(struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+
+static inline int acpi_reconfig_notifier_unregister(struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+
#endif /* CONFIG_ACPI */
#endif /*__ACPI_BUS_H__*/
--
1.9.1
next prev parent reply other threads:[~2016-04-19 22:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-19 22:38 [RFC PATCH v2 00/10] ACPI overlays Octavian Purdila
2016-04-19 22:38 ` [RFC PATCH v2 01/10] kernel: add TAINT_OVERLAY_ACPI_TABLE Octavian Purdila
2016-04-19 22:39 ` [RFC PATCH v2 02/10] acpi: decouple initrd table install from CONFIG_ACPI_INITRD_TABLE_OVERRIDE Octavian Purdila
2016-04-19 22:39 ` [RFC PATCH v2 03/10] acpi: fix enumeration (visited) flags for bus rescans Octavian Purdila
2016-04-19 22:39 ` Octavian Purdila [this message]
2016-04-19 22:39 ` [RFC PATCH v2 05/10] i2c: add support for ACPI reconfigure notifications Octavian Purdila
[not found] ` <1461105548-20618-6-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-04-21 21:27 ` Andy Shevchenko
2016-04-21 21:41 ` Octavian Purdila
2016-04-28 14:58 ` Mika Westerberg
2016-04-19 22:39 ` [RFC PATCH v2 06/10] spi: " Octavian Purdila
[not found] ` <1461105548-20618-7-git-send-email-octavian.purdila-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-04-28 15:00 ` Mika Westerberg
2016-04-28 17:42 ` Mark Brown
2016-04-28 19:37 ` Octavian Purdila
2016-05-03 12:19 ` Mark Brown
[not found] ` <20160503121954.GQ6292-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2016-05-04 15:04 ` Octavian Purdila
2016-04-19 22:39 ` [RFC PATCH v2 07/10] efi: load SSTDs from EFI variables Octavian Purdila
2016-05-09 4:13 ` Jon Masters
[not found] ` <da0e65ef-7c04-e274-2f15-a50daa8c4c8c-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-05-09 9:59 ` Octavian Purdila
2016-04-19 22:39 ` [RFC PATCH v2 08/10] acpi: add support for configfs Octavian Purdila
2016-04-19 22:39 ` [RFC PATCH v2 09/10] acpi: add support for loading SSDTs via configfs Octavian Purdila
2016-04-19 22:39 ` [RFC PATCH v2 10/10] HACK: acpi: configfs: add unload_hanlde_path attribute for tables Octavian Purdila
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1461105548-20618-5-git-send-email-octavian.purdila@intel.com \
--to=octavian.purdila@intel.com \
--cc=broonie@kernel.org \
--cc=irina.tirdea@intel.com \
--cc=jlbec@evilplan.org \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=matt@codeblueprint.co.uk \
--cc=rjw@rjwysocki.net \
--cc=wsa@the-dreams.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).