Jelajahi Sumber

target/generic-2.6: add missing bits for 2.6.30 ssb update

SVN-Revision: 21507
Nicolas Thill 15 tahun lalu
induk
melakukan
359f611957
1 mengubah file dengan 166 tambahan dan 3 penghapusan
  1. 166 3
      target/linux/generic-2.6/patches-2.6.30/941-ssb_update.patch

+ 166 - 3
target/linux/generic-2.6/patches-2.6.30/941-ssb_update.patch

@@ -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;
  	}