All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Lutomirski <luto@kernel.org>
To: Darren Hart <dvhart@infradead.org>
Cc: "Matthew Garrett" <mjg59@srcf.ucam.org>,
	linux-acpi@vger.kernel.org, platform-driver-x86@vger.kernel.org,
	"Mario Limonciello" <mario_limonciello@dell.com>,
	"Pali Rohár" <pali.rohar@gmail.com>,
	"Andy Lutomirski" <luto@kernel.org>
Subject: [PATCH 09/14] wmi: Instantiate all devices before adding them
Date: Mon, 30 Nov 2015 17:05:59 -0800	[thread overview]
Message-ID: <344ad68ef32ea13d2a7bb81e3ced15c4507a6cc8.1448931782.git.luto@kernel.org> (raw)
In-Reply-To: <cover.1448931782.git.luto@kernel.org>
In-Reply-To: <cover.1448931782.git.luto@kernel.org>

At some point, we'll want to subdrivers to get references to other
devices on the same WMI bus.  This change is needed to avoid races.

This ends up simplifying the setup code and fixng some leaks, too.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 drivers/platform/x86/wmi.c | 49 +++++++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 49be61207c4a..7d8a11a45bf9 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -869,7 +869,7 @@ static struct device_type wmi_type_data = {
 	.release = wmi_dev_release,
 };
 
-static int wmi_create_device(struct device *wmi_bus_dev,
+static void wmi_create_device(struct device *wmi_bus_dev,
 			     const struct guid_block *gblock,
 			     struct wmi_block *wblock,
 			     struct acpi_device *device)
@@ -923,7 +923,7 @@ static int wmi_create_device(struct device *wmi_bus_dev,
 
 	}
 
-	return device_register(&wblock->dev.dev);
+	device_initialize(&wblock->dev.dev);
 }
 
 static void wmi_free_devices(struct acpi_device *device)
@@ -934,10 +934,14 @@ static void wmi_free_devices(struct acpi_device *device)
 	list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
 		if (wblock->acpi_device == device) {
 			list_del(&wblock->list);
-			if (wblock->dev.dev.bus)
-				device_unregister(&wblock->dev.dev);
-			else
+			if (wblock->dev.dev.bus) {
+				/* Device was initialized. */
+				device_del(&wblock->dev.dev);
+				put_device(&wblock->dev.dev);
+			} else {
+				/* device_initialize was not called. */
 				kfree(wblock);
+			}
 		}
 	}
 }
@@ -972,9 +976,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
 	struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
 	union acpi_object *obj;
 	const struct guid_block *gblock;
-	struct wmi_block *wblock;
+	struct wmi_block *wblock, *next;
 	acpi_status status;
-	int retval;
+	int retval = 0;
 	u32 i, total;
 
 	status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
@@ -1007,19 +1011,15 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
 			continue;
 
 		wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
-		if (!wblock)
-			return -ENOMEM;
+		if (!wblock) {
+			retval = -ENOMEM;
+			break;
+		}
 
 		wblock->acpi_device = device;
 		wblock->gblock = gblock[i];
 
-		retval = wmi_create_device(wmi_bus_dev, &gblock[i],
-					   wblock, device);
-		if (retval) {
-			put_device(&wblock->dev.dev);
-			wmi_free_devices(device);
-			goto out_free_pointer;
-		}
+		wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device);
 
 		list_add_tail(&wblock->list, &wmi_block_list);
 
@@ -1029,11 +1029,24 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
 		}
 	}
 
-	retval = 0;
-
 out_free_pointer:
 	kfree(out.pointer);
 
+	/*
+	 * Now that all of the devices are created, add them to the
+	 * device tree and probe subdrivers.
+	 */
+	list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
+		if (wblock->acpi_device == device) {
+			if (device_add(&wblock->dev.dev) != 0) {
+				dev_err(wmi_bus_dev,
+					"failed to register %pULL\n",
+					wblock->gblock.guid);
+				list_del(&wblock->list);
+			}
+		}
+	}
+
 	return retval;
 }
 
-- 
2.5.0


  parent reply	other threads:[~2015-12-01  1:06 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-01  1:05 [PATCH 00/14] Big WMI driver rework Andy Lutomirski
2015-12-01  1:05 ` [PATCH 01/14] wmi: Drop "Mapper (un)loaded" messages Andy Lutomirski
2015-12-01  1:05 ` [PATCH 02/14] wmi: Pass the acpi_device through to parse_wdg Andy Lutomirski
2015-12-01  1:05 ` [PATCH 03/14] wmi: Clean up acpi_wmi_add Andy Lutomirski
2015-12-01  1:05 ` [PATCH 04/14] wmi: Track wmi devices per ACPI device Andy Lutomirski
2015-12-01  1:05 ` [PATCH 05/14] wmi: Turn WMI into a bus driver Andy Lutomirski
2016-01-16 12:56   ` Michał Kępień
2016-01-16 16:19     ` Andy Lutomirski
2015-12-01  1:05 ` [PATCH 06/14] wmi: Fix error handling when creating devices Andy Lutomirski
2015-12-01  1:05 ` [PATCH 07/14] wmi: Split devices into types and add basic sysfs attributes Andy Lutomirski
2015-12-01  1:05 ` [PATCH 08/14] wmi: Probe data objects for read and write capabilities Andy Lutomirski
2016-01-16 13:11   ` Michał Kępień
2016-01-16 16:14     ` Andy Lutomirski
2017-01-10  5:56       ` Michał Kępień
2017-01-10 10:05         ` Andy Lutomirski
2017-01-12  5:01           ` Michał Kępień
2017-01-13  1:42             ` Andy Lutomirski
2015-12-01  1:05 ` Andy Lutomirski [this message]
2016-01-17 14:06   ` [PATCH 09/14] wmi: Instantiate all devices before adding them Michał Kępień
2015-12-01  1:06 ` [PATCH 10/14] wmi: Add a driver .notify function Andy Lutomirski
2015-12-01  1:06 ` [PATCH 11/14] wmi: Add a new interface to read block data Andy Lutomirski
2015-12-01  1:06 ` [PATCH 12/14] wmi: Switch from acpi_driver.notify to acpi_install_notify_handler Andy Lutomirski
2015-12-01  1:06 ` [PATCH 13/14] wmi: Bind the platform device, not the ACPI node Andy Lutomirski
2015-12-01  1:06 ` [PATCH 14/14] dell-wmi: Convert to the WMI bus infrastructure Andy Lutomirski

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=344ad68ef32ea13d2a7bb81e3ced15c4507a6cc8.1448931782.git.luto@kernel.org \
    --to=luto@kernel.org \
    --cc=dvhart@infradead.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=mario_limonciello@dell.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=pali.rohar@gmail.com \
    --cc=platform-driver-x86@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.