|
@@ -145,3 +145,89 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
|
|
|
/* XXX check return code */
|
|
|
odpl->activate_func(od);
|
|
|
|
|
|
+ read_persistent_clock(&b);
|
|
|
+
|
|
|
+ c = timespec_sub(b, a);
|
|
|
+ act_lat = timespec_to_ns(&c);
|
|
|
+
|
|
|
+ dev_dbg(&od->pdev->dev,
|
|
|
+ "omap_device: pm_lat %d: activate: elapsed time %llu nsec\n",
|
|
|
+ od->pm_lat_level, act_lat);
|
|
|
+
|
|
|
+ if (act_lat > odpl->activate_lat) {
|
|
|
+ odpl->activate_lat_worst = act_lat;
|
|
|
+ if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
|
|
|
+ odpl->activate_lat = act_lat;
|
|
|
+ dev_dbg(&od->pdev->dev,
|
|
|
+ "new worst case activate latency %d: %llu\n",
|
|
|
+ od->pm_lat_level, act_lat);
|
|
|
+ } else
|
|
|
+ dev_warn(&od->pdev->dev,
|
|
|
+ "activate latency %d higher than expected. (%llu > %d)\n",
|
|
|
+ od->pm_lat_level, act_lat,
|
|
|
+ odpl->activate_lat);
|
|
|
+ }
|
|
|
+
|
|
|
+ od->dev_wakeup_lat -= odpl->activate_lat;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _omap_device_deactivate - decrease device readiness
|
|
|
+ * @od: struct omap_device *
|
|
|
+ * @ignore_lat: decrease to latency target (0) or full inactivity (1)?
|
|
|
+ *
|
|
|
+ * Decrease readiness of omap_device @od (thus increasing device
|
|
|
+ * wakeup latency, but conserving power). If @ignore_lat is
|
|
|
+ * IGNORE_WAKEUP_LAT, make the omap_device fully inactive. Otherwise,
|
|
|
+ * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
|
|
|
+ * latency is less than the requested maximum wakeup latency, step
|
|
|
+ * forwards in the omap_device_pm_latency table to ensure the device's
|
|
|
+ * maximum wakeup latency is less than or equal to the requested
|
|
|
+ * maximum wakeup latency. Returns 0.
|
|
|
+ */
|
|
|
+static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
|
|
|
+{
|
|
|
+ struct timespec a, b, c;
|
|
|
+
|
|
|
+ dev_dbg(&od->pdev->dev, "omap_device: deactivating\n");
|
|
|
+
|
|
|
+ while (od->pm_lat_level < od->pm_lats_cnt) {
|
|
|
+ struct omap_device_pm_latency *odpl;
|
|
|
+ unsigned long long deact_lat = 0;
|
|
|
+
|
|
|
+ odpl = od->pm_lats + od->pm_lat_level;
|
|
|
+
|
|
|
+ if (!ignore_lat &&
|
|
|
+ ((od->dev_wakeup_lat + odpl->activate_lat) >
|
|
|
+ od->_dev_wakeup_lat_limit))
|
|
|
+ break;
|
|
|
+
|
|
|
+ read_persistent_clock(&a);
|
|
|
+
|
|
|
+ /* XXX check return code */
|
|
|
+ odpl->deactivate_func(od);
|
|
|
+
|
|
|
+ read_persistent_clock(&b);
|
|
|
+
|
|
|
+ c = timespec_sub(b, a);
|
|
|
+ deact_lat = timespec_to_ns(&c);
|
|
|
+
|
|
|
+ dev_dbg(&od->pdev->dev,
|
|
|
+ "omap_device: pm_lat %d: deactivate: elapsed time %llu nsec\n",
|
|
|
+ od->pm_lat_level, deact_lat);
|
|
|
+
|
|
|
+ if (deact_lat > odpl->deactivate_lat) {
|
|
|
+ odpl->deactivate_lat_worst = deact_lat;
|
|
|
+ if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
|
|
|
+ odpl->deactivate_lat = deact_lat;
|
|
|
+ dev_dbg(&od->pdev->dev,
|
|
|
+ "new worst case deactivate latency %d: %llu\n",
|
|
|
+ od->pm_lat_level, deact_lat);
|
|
|
+ } else
|
|
|
+ dev_warn(&od->pdev->dev,
|
|
|
+ "deactivate latency %d higher than expected. (%llu > %d)\n",
|
|
|
+ od->pm_lat_level, deact_lat,
|
|
|
+ odpl->deactivate_lat);
|