target/generic-2.6: add missing bits for 2.6.30 ssb update
SVN-Revision: 21507
This commit is contained in:
parent
3875f85110
commit
359f611957
1 changed files with 166 additions and 3 deletions
|
@ -128,7 +128,170 @@
|
|||
+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
|
||||
--- a/drivers/ssb/main.c
|
||||
+++ b/drivers/ssb/main.c
|
||||
@@ -472,6 +472,8 @@ static int ssb_devices_register(struct s
|
||||
@@ -120,6 +120,19 @@ static void ssb_device_put(struct ssb_de
|
||||
put_device(dev->dev);
|
||||
}
|
||||
|
||||
+static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
|
||||
+{
|
||||
+ if (drv)
|
||||
+ get_driver(&drv->drv);
|
||||
+ return drv;
|
||||
+}
|
||||
+
|
||||
+static inline void ssb_driver_put(struct ssb_driver *drv)
|
||||
+{
|
||||
+ if (drv)
|
||||
+ put_driver(&drv->drv);
|
||||
+}
|
||||
+
|
||||
static int ssb_device_resume(struct device *dev)
|
||||
{
|
||||
struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
|
||||
@@ -190,90 +203,81 @@ int ssb_bus_suspend(struct ssb_bus *bus)
|
||||
EXPORT_SYMBOL(ssb_bus_suspend);
|
||||
|
||||
#ifdef CONFIG_SSB_SPROM
|
||||
-int ssb_devices_freeze(struct ssb_bus *bus)
|
||||
+/** ssb_devices_freeze - Freeze all devices on the bus.
|
||||
+ *
|
||||
+ * After freezing no device driver will be handling a device
|
||||
+ * on this bus anymore. ssb_devices_thaw() must be called after
|
||||
+ * a successful freeze to reactivate the devices.
|
||||
+ *
|
||||
+ * @bus: The bus.
|
||||
+ * @ctx: Context structure. Pass this to ssb_devices_thaw().
|
||||
+ */
|
||||
+int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx)
|
||||
{
|
||||
- struct ssb_device *dev;
|
||||
- struct ssb_driver *drv;
|
||||
- int err = 0;
|
||||
- int i;
|
||||
- pm_message_t state = PMSG_FREEZE;
|
||||
+ struct ssb_device *sdev;
|
||||
+ struct ssb_driver *sdrv;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ memset(ctx, 0, sizeof(*ctx));
|
||||
+ ctx->bus = bus;
|
||||
+ SSB_WARN_ON(bus->nr_devices > ARRAY_SIZE(ctx->device_frozen));
|
||||
|
||||
- /* First check that we are capable to freeze all devices. */
|
||||
for (i = 0; i < bus->nr_devices; i++) {
|
||||
- dev = &(bus->devices[i]);
|
||||
- if (!dev->dev ||
|
||||
- !dev->dev->driver ||
|
||||
- !device_is_registered(dev->dev))
|
||||
- continue;
|
||||
- drv = drv_to_ssb_drv(dev->dev->driver);
|
||||
- if (!drv)
|
||||
+ sdev = ssb_device_get(&bus->devices[i]);
|
||||
+
|
||||
+ if (!sdev->dev || !sdev->dev->driver ||
|
||||
+ !device_is_registered(sdev->dev)) {
|
||||
+ ssb_device_put(sdev);
|
||||
continue;
|
||||
- if (!drv->suspend) {
|
||||
- /* Nope, can't suspend this one. */
|
||||
- return -EOPNOTSUPP;
|
||||
}
|
||||
- }
|
||||
- /* Now suspend all devices */
|
||||
- for (i = 0; i < bus->nr_devices; i++) {
|
||||
- dev = &(bus->devices[i]);
|
||||
- if (!dev->dev ||
|
||||
- !dev->dev->driver ||
|
||||
- !device_is_registered(dev->dev))
|
||||
- continue;
|
||||
- drv = drv_to_ssb_drv(dev->dev->driver);
|
||||
- if (!drv)
|
||||
+ sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
|
||||
+ if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
|
||||
+ ssb_device_put(sdev);
|
||||
continue;
|
||||
- err = drv->suspend(dev, state);
|
||||
- if (err) {
|
||||
- ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
|
||||
- dev_name(dev->dev));
|
||||
- goto err_unwind;
|
||||
}
|
||||
+ sdrv->remove(sdev);
|
||||
+ ctx->device_frozen[i] = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
-err_unwind:
|
||||
- for (i--; i >= 0; i--) {
|
||||
- dev = &(bus->devices[i]);
|
||||
- if (!dev->dev ||
|
||||
- !dev->dev->driver ||
|
||||
- !device_is_registered(dev->dev))
|
||||
- continue;
|
||||
- drv = drv_to_ssb_drv(dev->dev->driver);
|
||||
- if (!drv)
|
||||
- continue;
|
||||
- if (drv->resume)
|
||||
- drv->resume(dev);
|
||||
- }
|
||||
- return err;
|
||||
}
|
||||
|
||||
-int ssb_devices_thaw(struct ssb_bus *bus)
|
||||
+/** ssb_devices_thaw - Unfreeze all devices on the bus.
|
||||
+ *
|
||||
+ * This will re-attach the device drivers and re-init the devices.
|
||||
+ *
|
||||
+ * @ctx: The context structure from ssb_devices_freeze()
|
||||
+ */
|
||||
+int ssb_devices_thaw(struct ssb_freeze_context *ctx)
|
||||
{
|
||||
- struct ssb_device *dev;
|
||||
- struct ssb_driver *drv;
|
||||
- int err;
|
||||
- int i;
|
||||
+ struct ssb_bus *bus = ctx->bus;
|
||||
+ struct ssb_device *sdev;
|
||||
+ struct ssb_driver *sdrv;
|
||||
+ unsigned int i;
|
||||
+ int err, result = 0;
|
||||
|
||||
for (i = 0; i < bus->nr_devices; i++) {
|
||||
- dev = &(bus->devices[i]);
|
||||
- if (!dev->dev ||
|
||||
- !dev->dev->driver ||
|
||||
- !device_is_registered(dev->dev))
|
||||
+ if (!ctx->device_frozen[i])
|
||||
continue;
|
||||
- drv = drv_to_ssb_drv(dev->dev->driver);
|
||||
- if (!drv)
|
||||
+ sdev = &bus->devices[i];
|
||||
+
|
||||
+ if (SSB_WARN_ON(!sdev->dev || !sdev->dev->driver))
|
||||
continue;
|
||||
- if (SSB_WARN_ON(!drv->resume))
|
||||
+ sdrv = drv_to_ssb_drv(sdev->dev->driver);
|
||||
+ if (SSB_WARN_ON(!sdrv || !sdrv->probe))
|
||||
continue;
|
||||
- err = drv->resume(dev);
|
||||
+
|
||||
+ err = sdrv->probe(sdev, &sdev->id);
|
||||
if (err) {
|
||||
ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
|
||||
- dev_name(dev->dev));
|
||||
+ dev_name(sdev->dev));
|
||||
+ result = err;
|
||||
}
|
||||
+ ssb_driver_put(sdrv);
|
||||
+ ssb_device_put(sdev);
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return result;
|
||||
}
|
||||
#endif /* CONFIG_SSB_SPROM */
|
||||
|
||||
@@ -472,6 +476,8 @@ static int ssb_devices_register(struct s
|
||||
case SSB_BUSTYPE_SSB:
|
||||
dev->dma_mask = &dev->coherent_dma_mask;
|
||||
break;
|
||||
|
@ -137,7 +300,7 @@
|
|||
}
|
||||
|
||||
sdev->dev = dev;
|
||||
@@ -1358,8 +1360,10 @@ static int __init ssb_modinit(void)
|
||||
@@ -1358,8 +1364,10 @@ static int __init ssb_modinit(void)
|
||||
ssb_buses_lock();
|
||||
err = ssb_attach_queued_buses();
|
||||
ssb_buses_unlock();
|
||||
|
@ -149,7 +312,7 @@
|
|||
|
||||
err = b43_pci_ssb_bridge_init();
|
||||
if (err) {
|
||||
@@ -1375,7 +1379,7 @@ static int __init ssb_modinit(void)
|
||||
@@ -1375,7 +1383,7 @@ static int __init ssb_modinit(void)
|
||||
/* don't fail SSB init because of this */
|
||||
err = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue