mirror of https://github.com/hak5/openwrt-owl.git
parent
3875f85110
commit
359f611957
|
@ -128,7 +128,170 @@
|
||||||
+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
|
+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
|
||||||
--- a/drivers/ssb/main.c
|
--- a/drivers/ssb/main.c
|
||||||
+++ b/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:
|
case SSB_BUSTYPE_SSB:
|
||||||
dev->dma_mask = &dev->coherent_dma_mask;
|
dev->dma_mask = &dev->coherent_dma_mask;
|
||||||
break;
|
break;
|
||||||
|
@ -137,7 +300,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
sdev->dev = dev;
|
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();
|
ssb_buses_lock();
|
||||||
err = ssb_attach_queued_buses();
|
err = ssb_attach_queued_buses();
|
||||||
ssb_buses_unlock();
|
ssb_buses_unlock();
|
||||||
|
@ -149,7 +312,7 @@
|
||||||
|
|
||||||
err = b43_pci_ssb_bridge_init();
|
err = b43_pci_ssb_bridge_init();
|
||||||
if (err) {
|
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 */
|
/* don't fail SSB init because of this */
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue