From: malattia@linux.it
To: lenb@kernel.org
Cc: linux-acpi@vger.kernel.org, akpm@linux-foundation.org,
stelian@popies.net
Subject: [patch 2/9] Prepare the platform driver for multiple users.
Date: Mon, 9 Apr 2007 19:20:19 +0200 [thread overview]
Message-ID: <20070409172019.GC10646@inferi.kami.home> (raw)
In-Reply-To: 20070409081903.057292676@linux.it
[-- Attachment #1: 0002-prepare-pfdriver-for-multiple-users.patch --]
[-- Type: text/plain, Size: 7255 bytes --]
Both the SNC and SPIC device drivers will create attributes and thus
there's the need to have an internal usage count to avoid
re-registering or de-registering at the wrong time.
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
drivers/misc/sony-laptop.c | 212 ++++++++++++++++++++++++++++++----------------------------
1 file changed, 112 insertions(+), 100 deletions(-)
Index: linux-2.6/drivers/misc/sony-laptop.c
===================================================================
--- linux-2.6.orig/drivers/misc/sony-laptop.c 2007-03-16 16:08:17.490191147 +0100
+++ linux-2.6/drivers/misc/sony-laptop.c 2007-03-18 18:50:17.769519953 +0100
@@ -54,6 +54,64 @@ module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "
"the development of this driver");
+/*********** Platform Device ***********/
+
+static atomic_t sony_pf_users = ATOMIC_INIT(0);
+static struct platform_driver sony_pf_driver = {
+ .driver = {
+ .name = "sony-laptop",
+ .owner = THIS_MODULE,
+ }
+};
+static struct platform_device *sony_pf_device;
+
+static int sony_pf_add(void)
+{
+ int ret = 0;
+
+ /* don't run again if already initialized */
+ if (atomic_add_return(1, &sony_pf_users) > 1)
+ return 0;
+
+ ret = platform_driver_register(&sony_pf_driver);
+ if (ret)
+ goto out;
+
+ sony_pf_device = platform_device_alloc("sony-laptop", -1);
+ if (!sony_pf_device) {
+ ret = -ENOMEM;
+ goto out_platform_registered;
+ }
+
+ ret = platform_device_add(sony_pf_device);
+ if (ret)
+ goto out_platform_alloced;
+
+ return 0;
+
+ out_platform_alloced:
+ platform_device_put(sony_pf_device);
+ sony_pf_device = NULL;
+ out_platform_registered:
+ platform_driver_unregister(&sony_pf_driver);
+ out:
+ atomic_dec(&sony_pf_users);
+ return ret;
+}
+
+static void sony_pf_remove(void)
+{
+ /* deregister only after the last user has gone */
+ if (!atomic_dec_and_test(&sony_pf_users))
+ return;
+
+ platform_device_del(sony_pf_device);
+ platform_device_put(sony_pf_device);
+ platform_driver_unregister(&sony_pf_driver);
+}
+
+/*********** SNC (SNY5001) Device ***********/
+
static ssize_t sony_nc_sysfs_show(struct device *, struct device_attribute *,
char *);
static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *,
@@ -279,104 +337,6 @@ static ssize_t sony_nc_sysfs_store(struc
return count;
}
-/*
- * Platform device
- */
-static struct platform_driver sncpf_driver = {
- .driver = {
- .name = "sony-laptop",
- .owner = THIS_MODULE,
- }
-};
-static struct platform_device *sncpf_device;
-
-static int sony_nc_pf_add(void)
-{
- acpi_handle handle;
- struct sony_nc_value *item;
- int ret = 0;
-
- ret = platform_driver_register(&sncpf_driver);
- if (ret)
- goto out;
-
- sncpf_device = platform_device_alloc("sony-laptop", -1);
- if (!sncpf_device) {
- ret = -ENOMEM;
- goto out_platform_registered;
- }
-
- ret = platform_device_add(sncpf_device);
- if (ret)
- goto out_platform_alloced;
-
- for (item = sony_nc_values; item->name; ++item) {
-
- if (!debug && item->debug)
- continue;
-
- /* find the available acpiget as described in the DSDT */
- for (; item->acpiget && *item->acpiget; ++item->acpiget) {
- if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle,
- *item->acpiget,
- &handle))) {
- if (debug)
- printk(LOG_PFX "Found %s getter: %s\n",
- item->name, *item->acpiget);
- item->devattr.attr.mode |= S_IRUGO;
- break;
- }
- }
-
- /* find the available acpiset as described in the DSDT */
- for (; item->acpiset && *item->acpiset; ++item->acpiset) {
- if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle,
- *item->acpiset,
- &handle))) {
- if (debug)
- printk(LOG_PFX "Found %s setter: %s\n",
- item->name, *item->acpiset);
- item->devattr.attr.mode |= S_IWUSR;
- break;
- }
- }
-
- if (item->devattr.attr.mode != 0) {
- ret =
- device_create_file(&sncpf_device->dev,
- &item->devattr);
- if (ret)
- goto out_sysfs;
- }
- }
-
- return 0;
-
- out_sysfs:
- for (item = sony_nc_values; item->name; ++item) {
- device_remove_file(&sncpf_device->dev, &item->devattr);
- }
- platform_device_del(sncpf_device);
- out_platform_alloced:
- platform_device_put(sncpf_device);
- out_platform_registered:
- platform_driver_unregister(&sncpf_driver);
- out:
- return ret;
-}
-
-static void sony_nc_pf_remove(void)
-{
- struct sony_nc_value *item;
-
- for (item = sony_nc_values; item->name; ++item) {
- device_remove_file(&sncpf_device->dev, &item->devattr);
- }
-
- platform_device_del(sncpf_device);
- platform_device_put(sncpf_device);
- platform_driver_unregister(&sncpf_driver);
-}
/*
* Backlight device
@@ -455,6 +415,7 @@ static int sony_nc_add(struct acpi_devic
acpi_status status;
int result = 0;
acpi_handle handle;
+ struct sony_nc_value *item;
sony_nc_acpi_device = device;
@@ -497,13 +458,59 @@ static int sony_nc_add(struct acpi_devic
}
- if (sony_nc_pf_add())
+ if (sony_pf_add())
goto outbacklight;
+ /* create sony_pf sysfs attributes related to the SNC device */
+ for (item = sony_nc_values; item->name; ++item) {
+
+ if (!debug && item->debug)
+ continue;
+
+ /* find the available acpiget as described in the DSDT */
+ for (; item->acpiget && *item->acpiget; ++item->acpiget) {
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle,
+ *item->acpiget,
+ &handle))) {
+ if (debug)
+ printk(LOG_PFX "Found %s getter: %s\n",
+ item->name, *item->acpiget);
+ item->devattr.attr.mode |= S_IRUGO;
+ break;
+ }
+ }
+
+ /* find the available acpiset as described in the DSDT */
+ for (; item->acpiset && *item->acpiset; ++item->acpiset) {
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle,
+ *item->acpiset,
+ &handle))) {
+ if (debug)
+ printk(LOG_PFX "Found %s setter: %s\n",
+ item->name, *item->acpiset);
+ item->devattr.attr.mode |= S_IWUSR;
+ break;
+ }
+ }
+
+ if (item->devattr.attr.mode != 0) {
+ result =
+ device_create_file(&sony_pf_device->dev,
+ &item->devattr);
+ if (result)
+ goto out_sysfs;
+ }
+ }
+
printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully installed\n");
return 0;
+ out_sysfs:
+ for (item = sony_nc_values; item->name; ++item) {
+ device_remove_file(&sony_pf_device->dev, &item->devattr);
+ }
+ sony_pf_remove();
outbacklight:
if (sony_backlight_device)
backlight_device_unregister(sony_backlight_device);
@@ -520,6 +527,7 @@ static int sony_nc_add(struct acpi_devic
static int sony_nc_remove(struct acpi_device *device, int type)
{
acpi_status status;
+ struct sony_nc_value *item;
if (sony_backlight_device)
backlight_device_unregister(sony_backlight_device);
@@ -532,7 +540,11 @@ static int sony_nc_remove(struct acpi_de
if (ACPI_FAILURE(status))
printk(LOG_PFX "unable to remove notify handler\n");
- sony_nc_pf_remove();
+ for (item = sony_nc_values; item->name; ++item) {
+ device_remove_file(&sony_pf_device->dev, &item->devattr);
+ }
+
+ sony_pf_remove();
printk(KERN_INFO SONY_NC_DRIVER_NAME " successfully removed\n");
--
--
mattia
:wq!
next prev parent reply other threads:[~2007-04-09 17:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20070409081903.057292676@linux.it>
2007-04-09 17:18 ` [patch 1/9] Remove ACPI references from variable and function names malattia
2007-04-09 17:20 ` malattia [this message]
2007-04-09 17:22 ` [patch 3/9] Add debug macros also used by the sonypi reimplementation malattia
2007-04-09 17:26 ` [patch 4/9] Add SNY6001 device handling (sonypi reimplementation) malattia
2007-04-09 17:28 ` [patch 5/9] Unify the input subsystem event forwarding malattia
2007-04-09 17:28 ` [patch 6/9] additional platform attributes coming from SNY6001 malattia
2007-04-09 17:31 ` [patch 7/9] sanitize printks malattia
2007-04-09 17:31 ` [patch 8/9] update documentation and Kconfig help malattia
2007-04-09 17:31 ` [patch 9/9] sonypi backward compatibility code malattia
2007-04-10 20:13 ` [patch 0/9] [RFC] sonypi ACPI reimplementation (resend 3) Len Brown
2007-04-10 22:04 ` Mattia Dongili
2007-04-12 9:20 ` Stelian Pop
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=20070409172019.GC10646@inferi.kami.home \
--to=malattia@linux.it \
--cc=akpm@linux-foundation.org \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=stelian@popies.net \
/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