void dev_pm_qos_constraints_destroy()

in power/qos.c [246:319]


void dev_pm_qos_constraints_destroy(struct device *dev)
{
	struct dev_pm_qos *qos;
	struct dev_pm_qos_request *req, *tmp;
	struct pm_qos_constraints *c;
	struct pm_qos_flags *f;

	mutex_lock(&dev_pm_qos_sysfs_mtx);

	/*
	 * If the device's PM QoS resume latency limit or PM QoS flags have been
	 * exposed to user space, they have to be hidden at this point.
	 */
	pm_qos_sysfs_remove_resume_latency(dev);
	pm_qos_sysfs_remove_flags(dev);

	mutex_lock(&dev_pm_qos_mtx);

	__dev_pm_qos_hide_latency_limit(dev);
	__dev_pm_qos_hide_flags(dev);

	qos = dev->power.qos;
	if (!qos)
		goto out;

	/* Flush the constraints lists for the device. */
	c = &qos->resume_latency;
	plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) {
		/*
		 * Update constraints list and call the notification
		 * callbacks if needed
		 */
		apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
		memset(req, 0, sizeof(*req));
	}

	c = &qos->latency_tolerance;
	plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) {
		apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
		memset(req, 0, sizeof(*req));
	}

	c = &qos->freq.min_freq;
	plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
		apply_constraint(req, PM_QOS_REMOVE_REQ,
				 PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE);
		memset(req, 0, sizeof(*req));
	}

	c = &qos->freq.max_freq;
	plist_for_each_entry_safe(req, tmp, &c->list, data.freq.pnode) {
		apply_constraint(req, PM_QOS_REMOVE_REQ,
				 PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
		memset(req, 0, sizeof(*req));
	}

	f = &qos->flags;
	list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) {
		apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
		memset(req, 0, sizeof(*req));
	}

	spin_lock_irq(&dev->power.lock);
	dev->power.qos = ERR_PTR(-ENODEV);
	spin_unlock_irq(&dev->power.lock);

	kfree(qos->resume_latency.notifiers);
	kfree(qos);

 out:
	mutex_unlock(&dev_pm_qos_mtx);

	mutex_unlock(&dev_pm_qos_sysfs_mtx);
}