diff -urN corig/arch/ppc64/kernel/vio.c c/arch/ppc64/kernel/vio.c --- corig/arch/ppc64/kernel/vio.c 2005-07-14 16:55:41.000000000 -0500 +++ c/arch/ppc64/kernel/vio.c 2005-07-14 20:02:51.000000000 -0500 @@ -632,9 +632,32 @@ return 0; } +static int vio_device_suspend(struct device * dev, pm_message_t state) +{ + struct vio_dev * vio_dev = to_vio_dev(dev); + struct vio_driver *drv = to_vio_driver(dev->driver); + + if (drv && drv->suspend) + return drv->suspend(vio_dev, state); + else + return 0; +} + +static int vio_device_resume(struct device * dev) +{ + struct vio_dev * vio_dev = to_vio_dev(dev); + struct vio_driver *drv = to_vio_driver(dev->driver); + + if (drv && drv->resume) + drv->resume(vio_dev); + return 0; +} + struct bus_type vio_bus_type = { .name = "vio", .match = vio_bus_match, + .suspend = vio_device_suspend, + .resume = vio_device_resume, }; EXPORT_SYMBOL(vio_bus_type); diff -urN corig/drivers/char/hvc_console.c c/drivers/char/hvc_console.c --- corig/drivers/char/hvc_console.c 2005-07-14 17:02:22.000000000 -0500 +++ c/drivers/char/hvc_console.c 2005-07-14 19:56:28.000000000 -0500 @@ -674,11 +674,33 @@ return 0; } +static int hvc_suspend(struct vio_dev *dev, pm_message_t state) +{ + if (dev->irq != NO_IRQ) + free_irq(dev->irq, dev->dev.driver_data); + + return 0; +} + +static int hvc_resume(struct vio_dev *dev) +{ + int rc = 0; + if (dev->irq != NO_IRQ) + rc = request_irq(dev->irq, hvc_handle_interrupt, SA_INTERRUPT, + "hvc_console", dev->dev.driver_data); + if (rc) + printk(KERN_ERR "hvc_resume: req_irq failed with rc %d.\n", rc); + + return rc; +} + static struct vio_driver hvc_vio_driver = { .name = hvc_driver_name, .id_table = hvc_driver_table, .probe = hvc_probe, .remove = hvc_remove, + .suspend = hvc_suspend, + .resume = hvc_resume, }; /* Driver initialization. Follow console initialization. This is where the TTY diff -urN corig/drivers/net/ibmveth.c c/drivers/net/ibmveth.c --- corig/drivers/net/ibmveth.c 2005-07-14 16:55:44.000000000 -0500 +++ c/drivers/net/ibmveth.c 2005-07-15 08:54:04.000000000 -0500 @@ -105,7 +105,7 @@ static const char ibmveth_driver_name[] = "ibmveth"; static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; -#define ibmveth_driver_version "1.03" +#define ibmveth_driver_version "1.04" MODULE_AUTHOR("Santiago Leon "); MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); @@ -1149,11 +1149,29 @@ MODULE_DEVICE_TABLE(vio, ibmveth_device_table); +static int ibmveth_suspend(struct vio_dev *dev, pm_message_t state) +{ + struct net_device *netdev = dev->dev.driver_data; + if(netif_running(netdev)) + ibmveth_close(netdev); + return 0; +} + +static int ibmveth_resume(struct vio_dev *dev) +{ + struct net_device *netdev = dev->dev.driver_data; + if(netif_running(netdev)) + ibmveth_open(netdev); + return 0; +} + static struct vio_driver ibmveth_driver = { .name = (char *)ibmveth_driver_name, .id_table = ibmveth_device_table, .probe = ibmveth_probe, - .remove = ibmveth_remove + .remove = ibmveth_remove, + .suspend = ibmveth_suspend, + .resume = ibmveth_resume }; static int __init ibmveth_module_init(void) diff -urN corig/drivers/scsi/ibmvscsi/ibmvscsi.c c/drivers/scsi/ibmvscsi/ibmvscsi.c --- corig/drivers/scsi/ibmvscsi/ibmvscsi.c 2005-07-14 16:55:47.000000000 -0500 +++ c/drivers/scsi/ibmvscsi/ibmvscsi.c 2005-07-15 08:54:20.000000000 -0500 @@ -87,7 +87,7 @@ static int init_timeout = 5; static int max_requests = 50; -#define IBMVSCSI_VERSION "1.5.5" +#define IBMVSCSI_VERSION "1.5.6" MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_AUTHOR("Dave Boutcher"); @@ -1442,6 +1442,33 @@ return 0; } +static int ibmvscsi_suspend(struct vio_dev *dev, pm_message_t state) +{ + struct ibmvscsi_host_data *hostdata = dev->dev.driver_data; + + release_event_pool(&hostdata->pool, hostdata); + ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); + return 0; +} + +static int ibmvscsi_resume(struct vio_dev *dev) +{ + struct ibmvscsi_host_data *hostdata = dev->dev.driver_data; + + + if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests)) { + printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); + return 1; + } + if (initialize_event_pool(&hostdata->pool, max_requests, hostdata)) { + printk(KERN_ERR "ibmvscsi: couldn't initialize event pool\n"); + ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, + max_requests); + return 1; + } + return 0; +} + /** * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we * support. @@ -1456,7 +1483,9 @@ .name = "ibmvscsi", .id_table = ibmvscsi_device_table, .probe = ibmvscsi_probe, - .remove = ibmvscsi_remove + .remove = ibmvscsi_remove, + .suspend = ibmvscsi_suspend, + .resume = ibmvscsi_resume }; int __init ibmvscsi_module_init(void) diff -urN corig/include/asm-ppc64/vio.h c/include/asm-ppc64/vio.h --- corig/include/asm-ppc64/vio.h 2005-07-14 16:55:59.000000000 -0500 +++ c/include/asm-ppc64/vio.h 2005-07-14 20:00:03.000000000 -0500 @@ -72,6 +72,9 @@ const struct vio_device_id *id_table; /* NULL if wants all devices */ int (*probe) (struct vio_dev *dev, const struct vio_device_id *id); /* New device inserted */ int (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ + int (*suspend) (struct vio_dev *dev, pm_message_t state); + int (*resume) (struct vio_dev *dev); + unsigned long driver_data; struct device_driver driver; @@ -79,7 +82,7 @@ static inline struct vio_driver *to_vio_driver(struct device_driver *drv) { - return container_of(drv, struct vio_driver, driver); + return drv ? container_of(drv, struct vio_driver, driver) : NULL; } /*