All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
To: greg@kroah.com
Cc: s.hauer@pengutronix.de, linux-arm-kernel@lists.arm.linux.org.uk,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 1/3] platform_device: add init() exit() callbacks
Date: Tue, 24 Feb 2009 17:57:31 +0200	[thread overview]
Message-ID: <20090224155731.28880.77132.stgit@Programuotojas> (raw)

Some(many?) platform drivers needs board specific callbacks
to initialize/deinitialize(request/release) GPIO pins,
generic bus initialization, board specific configuration
and etc.

Currently this is done by passing pointers to such functions
through platform_data. It is common for such drivers to have
init()/exit() functions declared in platform_data structure.

Using platform_data for this purpose has some drawbacks:
1. You have to write checks for platform_data and functions
   pointers existance and ensure correct error path in every
   platform driver.
2. Since part of the code is in driver and another in board
   specific code, usually you have to push this code through
   different maintainers. This also adds some not necessary work
   to ensure that adding changes to the board code, while changes
   to the driver are still pending, will not break this board
   compilation.
3. In my case, I am adding support for new ARM CPU, this needs
   to be done for some already existing drivers like serial 8250,
   mtd physmap and etc. this becomes pain in the ...

Adding init()/exit() callbacks to the platform_device eliminates
these drawbacks and you can simply add board specific init()/exit()
without changing any code in the driver itself.

Signed-off-by: Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
---

 Documentation/driver-model/platform.txt |    8 ++++++--
 drivers/base/platform.c                 |   21 +++++++++++++++++++--
 include/linux/platform_device.h         |    2 ++
 3 files changed, 27 insertions(+), 4 deletions(-)


diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt
index 83009fd..9bac835 100644
--- a/Documentation/driver-model/platform.txt
+++ b/Documentation/driver-model/platform.txt
@@ -18,8 +18,10 @@ is direct addressing from a CPU bus.  Rarely, a platform_device will
 be connected through a segment of some other kind of bus; but its
 registers will still be directly addressable.
 
-Platform devices are given a name, used in driver binding, and a
-list of resources such as addresses and IRQs.
+Platform devices are given a name, used in driver binding, a list
+of resources such as addresses and IRQs, and optionaly board/platform
+specific init()/exit() functions called before probing and after removing
+platform driver.
 
 struct platform_device {
 	const char	*name;
@@ -27,6 +29,8 @@ struct platform_device {
 	struct device	dev;
 	u32		num_resources;
 	struct resource	*resource;
+	int (*init)(struct platform_device *);
+	void (*exit)(struct platform_device *);
 };
 
 
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 349a101..c3ef008 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -444,8 +444,19 @@ static int platform_drv_probe(struct device *_dev)
 {
 	struct platform_driver *drv = to_platform_driver(_dev->driver);
 	struct platform_device *dev = to_platform_device(_dev);
+	int retval;
+
+	if (dev->init) {
+		retval = dev->init(dev);
+		if (retval)
+			return retval;
+	}
+
+	retval = drv->probe(dev);
+	if (retval && dev->exit)
+		dev->exit(dev);
 
-	return drv->probe(dev);
+	return retval;
 }
 
 static int platform_drv_probe_fail(struct device *_dev)
@@ -457,8 +468,14 @@ static int platform_drv_remove(struct device *_dev)
 {
 	struct platform_driver *drv = to_platform_driver(_dev->driver);
 	struct platform_device *dev = to_platform_device(_dev);
+	int retval;
+
+	retval = drv->remove(dev);
 
-	return drv->remove(dev);
+	if (!retval && dev->exit)
+		dev->exit(dev);
+
+	return retval;
 }
 
 static void platform_drv_shutdown(struct device *_dev)
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 9a34269..d51f19e 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -19,6 +19,8 @@ struct platform_device {
 	struct device	dev;
 	u32		num_resources;
 	struct resource	* resource;
+	int (*init)(struct platform_device *);
+	void (*exit)(struct platform_device *);
 };
 
 #define to_platform_device(x) container_of((x), struct platform_device, dev)


             reply	other threads:[~2009-02-24 15:57 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-24 15:57 Paulius Zaleckas [this message]
2009-02-24 18:29 ` [RFC PATCH 1/3] platform_device: add init() exit() callbacks Uwe Kleine-König

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=20090224155731.28880.77132.stgit@Programuotojas \
    --to=paulius.zaleckas@teltonika.lt \
    --cc=greg@kroah.com \
    --cc=linux-arm-kernel@lists.arm.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=s.hauer@pengutronix.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 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.