From: Pierre Ossman <drzeus-list@drzeus.cx>
To: Andrew Morton <akpm@osdl.org>
Cc: LKML <linux-kernel@vger.kernel.org>, Adam Belay <ambx1@neo.rr.com>
Subject: [Fwd: [PATCH] [PNP][RFC] Suspend support for PNP bus.]
Date: Fri, 04 Nov 2005 10:21:29 +0100 [thread overview]
Message-ID: <436B2819.4090909@drzeus.cx> (raw)
[-- Attachment #1: Type: text/plain, Size: 94 bytes --]
Perhaps Mr Morton can have a look? This patch is probably -mm material
anyhow.
Rgds
Pierre
[-- Attachment #2: [PATCH] [PNP][RFC] Suspend support for PNP bus. --]
[-- Type: message/rfc822, Size: 9280 bytes --]
From: Pierre Ossman <drzeus@drzeus.cx>
To: ambx1@neo.rr.com
Cc: Pierre Ossman <drzeus-list@drzeus.cx>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] [PNP][RFC] Suspend support for PNP bus.
Date: Fri, 28 Oct 2005 09:39:01 +0200
Message-ID: <20051028073900.4148.83481.stgit@poseidon.drzeus.cx>
Add support for suspending devices connected to the PNP bus. New
callbacks are added for the drivers and the PNP hardware layer is
told to disable the device during the suspend.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
---
drivers/pnp/driver.c | 51 +++++++++++++++++++++++++++++++-
drivers/pnp/manager.c | 78 +++++++++++++++++++++++++++++++++++++------------
include/linux/pnp.h | 10 +++++-
3 files changed, 116 insertions(+), 23 deletions(-)
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -146,10 +146,57 @@ static int pnp_bus_match(struct device *
return 1;
}
+static int pnp_bus_suspend(struct device *dev, pm_message_t state)
+{
+ struct pnp_dev * pnp_dev = to_pnp_dev(dev);
+ struct pnp_driver * drv = pnp_dev->driver;
+ int error;
+
+ if (!drv)
+ return 0;
+
+ if (drv->suspend) {
+ error = drv->suspend(pnp_dev, state);
+ if (error)
+ return error;
+ }
+
+ if (!(drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) &&
+ pnp_can_disable(pnp_dev)) {
+ error = pnp_stop_dev(pnp_dev);
+ if (error)
+ return error;
+ }
+
+ return 0;
+}
+
+static int pnp_bus_resume(struct device *dev)
+{
+ struct pnp_dev * pnp_dev = to_pnp_dev(dev);
+ struct pnp_driver * drv = pnp_dev->driver;
+ int error;
+
+ if (!drv)
+ return 0;
+
+ if (!(drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
+ error = pnp_start_dev(pnp_dev);
+ if (error)
+ return error;
+ }
+
+ if (drv->resume)
+ return drv->resume(pnp_dev);
+
+ return 0;
+}
struct bus_type pnp_bus_type = {
- .name = "pnp",
- .match = pnp_bus_match,
+ .name = "pnp",
+ .match = pnp_bus_match,
+ .suspend = pnp_bus_suspend,
+ .resume = pnp_bus_resume,
};
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -468,6 +468,53 @@ int pnp_auto_config_dev(struct pnp_dev *
}
/**
+ * pnp_start_dev - low-level start of the PnP device
+ * @dev: pointer to the desired device
+ *
+ * assumes that resources have alread been allocated
+ */
+
+int pnp_start_dev(struct pnp_dev *dev)
+{
+ if (!pnp_can_write(dev)) {
+ pnp_info("Device %s does not supported activation.", dev->dev.bus_id);
+ return -EINVAL;
+ }
+
+ if (dev->protocol->set(dev, &dev->res)<0) {
+ pnp_err("Failed to activate device %s.", dev->dev.bus_id);
+ return -EIO;
+ }
+
+ pnp_info("Device %s activated.", dev->dev.bus_id);
+
+ return 0;
+}
+
+/**
+ * pnp_stop_dev - low-level disable of the PnP device
+ * @dev: pointer to the desired device
+ *
+ * does not free resources
+ */
+
+int pnp_stop_dev(struct pnp_dev *dev)
+{
+ if (!pnp_can_disable(dev)) {
+ pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
+ return -EINVAL;
+ }
+ if (dev->protocol->disable(dev)<0) {
+ pnp_err("Failed to disable device %s.", dev->dev.bus_id);
+ return -EIO;
+ }
+
+ pnp_info("Device %s disabled.", dev->dev.bus_id);
+
+ return 0;
+}
+
+/**
* pnp_activate_dev - activates a PnP device for use
* @dev: pointer to the desired device
*
@@ -475,6 +522,8 @@ int pnp_auto_config_dev(struct pnp_dev *
*/
int pnp_activate_dev(struct pnp_dev *dev)
{
+ int error;
+
if (!dev)
return -EINVAL;
if (dev->active) {
@@ -485,18 +534,11 @@ int pnp_activate_dev(struct pnp_dev *dev
if (pnp_auto_config_dev(dev))
return -EBUSY;
- if (!pnp_can_write(dev)) {
- pnp_info("Device %s does not supported activation.", dev->dev.bus_id);
- return -EINVAL;
- }
-
- if (dev->protocol->set(dev, &dev->res)<0) {
- pnp_err("Failed to activate device %s.", dev->dev.bus_id);
- return -EIO;
- }
+ error = pnp_start_dev(dev);
+ if (error)
+ return error;
dev->active = 1;
- pnp_info("Device %s activated.", dev->dev.bus_id);
return 1;
}
@@ -509,23 +551,19 @@ int pnp_activate_dev(struct pnp_dev *dev
*/
int pnp_disable_dev(struct pnp_dev *dev)
{
+ int error;
+
if (!dev)
return -EINVAL;
if (!dev->active) {
return 0; /* the device is already disabled */
}
- if (!pnp_can_disable(dev)) {
- pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
- return -EINVAL;
- }
- if (dev->protocol->disable(dev)<0) {
- pnp_err("Failed to disable device %s.", dev->dev.bus_id);
- return -EIO;
- }
+ error = pnp_stop_dev(dev);
+ if (error)
+ return error;
dev->active = 0;
- pnp_info("Device %s disabled.", dev->dev.bus_id);
/* release the resources so that other devices can use them */
down(&pnp_res_mutex);
@@ -554,6 +592,8 @@ void pnp_resource_change(struct resource
EXPORT_SYMBOL(pnp_manual_config_dev);
EXPORT_SYMBOL(pnp_auto_config_dev);
+EXPORT_SYMBOL(pnp_start_dev);
+EXPORT_SYMBOL(pnp_stop_dev);
EXPORT_SYMBOL(pnp_activate_dev);
EXPORT_SYMBOL(pnp_disable_dev);
EXPORT_SYMBOL(pnp_resource_change);
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -292,8 +292,10 @@ struct pnp_driver {
char * name;
const struct pnp_device_id *id_table;
unsigned int flags;
- int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
- void (*remove) (struct pnp_dev *dev);
+ int (*probe) (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
+ void (*remove) (struct pnp_dev *dev);
+ int (*suspend) (struct pnp_dev *dev, pm_message_t state);
+ int (*resume) (struct pnp_dev *dev);
struct device_driver driver;
};
@@ -381,6 +383,8 @@ void pnp_init_resource_table(struct pnp_
int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
int pnp_auto_config_dev(struct pnp_dev *dev);
int pnp_validate_config(struct pnp_dev *dev);
+int pnp_start_dev(struct pnp_dev *dev);
+int pnp_stop_dev(struct pnp_dev *dev);
int pnp_activate_dev(struct pnp_dev *dev);
int pnp_disable_dev(struct pnp_dev *dev);
void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size);
@@ -425,6 +429,8 @@ static inline void pnp_init_resource_tab
static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_validate_config(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
next reply other threads:[~2005-11-04 9:21 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-04 9:21 Pierre Ossman [this message]
2005-11-04 14:49 ` [Fwd: [PATCH] [PNP][RFC] Suspend support for PNP bus.] Dmitry Torokhov
2005-11-04 15:16 ` Pierre Ossman
2005-11-04 15:27 ` Dmitry Torokhov
2005-11-04 15:52 ` Pierre Ossman
2005-11-04 16:09 ` Dmitry Torokhov
2005-11-04 16:12 ` Dmitry Torokhov
2005-11-05 7:15 ` Andrew Morton
2005-11-06 16:50 ` Dmitry Torokhov
2005-11-29 19:32 ` Andrew Morton
2005-11-29 18:50 ` Pierre Ossman
2005-11-29 20:02 ` Andrew Morton
2005-11-29 19:49 ` Pierre Ossman
2005-11-29 21:01 ` Andrew Morton
2005-11-29 20:44 ` Pierre Ossman
2005-11-30 10:12 ` Pierre Ossman
2005-11-30 10:44 ` Takashi Iwai
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=436B2819.4090909@drzeus.cx \
--to=drzeus-list@drzeus.cx \
--cc=akpm@osdl.org \
--cc=ambx1@neo.rr.com \
--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