linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Samu Onkalo <samu.p.onkalo@nokia.com>
To: gregkh@suse.de, hmh@hmh.eng.br, alan@linux.intel.com,
	akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org
Subject: [RFC PATCH] device-core: sysfs open - close notify
Date: Sun, 31 Oct 2010 14:46:10 +0200	[thread overview]
Message-ID: <1288529170-28890-1-git-send-email-samu.p.onkalo@nokia.com> (raw)

Device drivers have no idea when somebody in userspace keeps some sysfs entry
open. The driver just received read or write calls. The driver may want to
control HW state based on activity so it either have to turn HW on and off
for each sysfs access or it needs separate enable disable entry which controls
the HW state. In cases where sysfs is used to pass some events under interrupt
control (like proximity events from the proximity sensors) it is not enough to
just keep sysfs entry open in userspace.

This patch adds a possibility for driver to know when some sysfs entry is
open.

Device driver structure is enhanced with optional open and close methods.
Device driver can provide those if it needs information about the sysfs
activity. Device core is enhanced to provide open / close methods for
sysfs file operations. Sysfs open / close operations call open / close
methods if they are provided.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/base/core.c    |   24 ++++++++++++++++++++++++
 fs/sysfs/file.c        |   16 +++++++++++++++-
 include/linux/device.h |    2 ++
 include/linux/sysfs.h  |    2 ++
 4 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6ed6454..f9c5810 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -112,9 +112,33 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr,
 	return ret;
 }
 
+static int dev_attr_open(struct kobject *kobj, struct attribute *attr)
+{
+	struct device *dev = to_dev(kobj);
+	int ret = 0;
+	if (dev->driver && unlikely(dev->driver->open)) {
+		ret = dev->driver->open(dev, attr);
+		if (unlikely(ret > 0)) {
+			WARN(1, KERN_ERR "%s driver open call returned "
+				"positive value\n", dev->driver->name);
+			ret = -EPERM;
+		}
+	}
+	return ret;
+}
+
+static void dev_attr_close(struct kobject *kobj, struct attribute *attr)
+{
+	struct device *dev = to_dev(kobj);
+	if (dev->driver && dev->driver->close)
+		dev->driver->close(dev, attr);
+}
+
 static const struct sysfs_ops dev_sysfs_ops = {
 	.show	= dev_attr_show,
 	.store	= dev_attr_store,
+	.open	= dev_attr_open,
+	.close	= dev_attr_close,
 };
 
 
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index da3fefe..4feaec2 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -392,10 +392,18 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
 	if (error)
 		goto err_free;
 
+	/* Notify about open dirent */
+	if (ops->open) {
+		error = ops->open(kobj, attr_sd->s_attr.attr);
+		if (error)
+			goto err_open;
+	}
+
 	/* open succeeded, put active references */
 	sysfs_put_active(attr_sd);
 	return 0;
-
+err_open:
+	sysfs_put_open_dirent(attr_sd, buffer);
  err_free:
 	kfree(buffer);
  err_out:
@@ -407,6 +415,12 @@ static int sysfs_release(struct inode *inode, struct file *filp)
 {
 	struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
 	struct sysfs_buffer *buffer = filp->private_data;
+	struct kobject *kobj = sd->s_parent->s_dir.kobj;
+	const struct sysfs_ops *ops = kobj->ktype->sysfs_ops;
+
+	/* Notify about dirent release */
+	if (ops->close)
+		ops->close(kobj, sd->s_attr.attr);
 
 	sysfs_put_open_dirent(sd, buffer);
 
diff --git a/include/linux/device.h b/include/linux/device.h
index dd48953..788d982 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -138,6 +138,8 @@ struct device_driver {
 	void (*shutdown) (struct device *dev);
 	int (*suspend) (struct device *dev, pm_message_t state);
 	int (*resume) (struct device *dev);
+	int (*open) (struct device *dev, struct attribute *);
+	void (*close) (struct device *dev, struct attribute *);
 	const struct attribute_group **groups;
 
 	const struct dev_pm_ops *pm;
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 30b8815..9b92c29 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -112,6 +112,8 @@ struct bin_attribute {
 struct sysfs_ops {
 	ssize_t	(*show)(struct kobject *, struct attribute *,char *);
 	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t);
+	int (*open)(struct kobject *, struct attribute *);
+	void (*close)(struct kobject *, struct attribute *);
 };
 
 struct sysfs_dirent;
-- 
1.6.0.4


             reply	other threads:[~2010-10-31 12:47 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-31 12:46 Samu Onkalo [this message]
2010-10-31 16:14 ` [RFC PATCH] device-core: sysfs open - close notify Ming Lei
2010-11-01 17:11   ` Alan Cox
2010-11-02  6:30     ` Onkalo Samu
2010-11-16  3:14       ` Enrico Weigelt

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=1288529170-28890-1-git-send-email-samu.p.onkalo@nokia.com \
    --to=samu.p.onkalo@nokia.com \
    --cc=akpm@linux-foundation.org \
    --cc=alan@linux.intel.com \
    --cc=gregkh@suse.de \
    --cc=hmh@hmh.eng.br \
    --cc=linux-kernel@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 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).