static void create_sysfs_files()

in devfreq.c [768:958]


static void create_sysfs_files(struct devfreq *devfreq,
				const struct devfreq_governor *gov);
static void remove_sysfs_files(struct devfreq *devfreq,
				const struct devfreq_governor *gov);

/**
 * devfreq_add_device() - Add devfreq feature to the device
 * @dev:	the device to add devfreq feature.
 * @profile:	device-specific profile to run devfreq.
 * @governor_name:	name of the policy to choose frequency.
 * @data:	private data for the governor. The devfreq framework does not
 *		touch this value.
 */
struct devfreq *devfreq_add_device(struct device *dev,
				   struct devfreq_dev_profile *profile,
				   const char *governor_name,
				   void *data)
{
	struct devfreq *devfreq;
	struct devfreq_governor *governor;
	int err = 0;

	if (!dev || !profile || !governor_name) {
		dev_err(dev, "%s: Invalid parameters.\n", __func__);
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&devfreq_list_lock);
	devfreq = find_device_devfreq(dev);
	mutex_unlock(&devfreq_list_lock);
	if (!IS_ERR(devfreq)) {
		dev_err(dev, "%s: devfreq device already exists!\n",
			__func__);
		err = -EINVAL;
		goto err_out;
	}

	devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL);
	if (!devfreq) {
		err = -ENOMEM;
		goto err_out;
	}

	mutex_init(&devfreq->lock);
	mutex_lock(&devfreq->lock);
	devfreq->dev.parent = dev;
	devfreq->dev.class = devfreq_class;
	devfreq->dev.release = devfreq_dev_release;
	INIT_LIST_HEAD(&devfreq->node);
	devfreq->profile = profile;
	devfreq->previous_freq = profile->initial_freq;
	devfreq->last_status.current_frequency = profile->initial_freq;
	devfreq->data = data;
	devfreq->nb.notifier_call = devfreq_notifier_call;

	if (devfreq->profile->timer < 0
		|| devfreq->profile->timer >= DEVFREQ_TIMER_NUM) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}

	if (!devfreq->profile->max_state || !devfreq->profile->freq_table) {
		mutex_unlock(&devfreq->lock);
		err = set_freq_table(devfreq);
		if (err < 0)
			goto err_dev;
		mutex_lock(&devfreq->lock);
	}

	devfreq->scaling_min_freq = find_available_min_freq(devfreq);
	if (!devfreq->scaling_min_freq) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}

	devfreq->scaling_max_freq = find_available_max_freq(devfreq);
	if (!devfreq->scaling_max_freq) {
		mutex_unlock(&devfreq->lock);
		err = -EINVAL;
		goto err_dev;
	}

	devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);
	devfreq->opp_table = dev_pm_opp_get_opp_table(dev);
	if (IS_ERR(devfreq->opp_table))
		devfreq->opp_table = NULL;

	atomic_set(&devfreq->suspend_count, 0);

	dev_set_name(&devfreq->dev, "%s", dev_name(dev));
	err = device_register(&devfreq->dev);
	if (err) {
		mutex_unlock(&devfreq->lock);
		put_device(&devfreq->dev);
		goto err_out;
	}

	devfreq->stats.trans_table = devm_kzalloc(&devfreq->dev,
			array3_size(sizeof(unsigned int),
				    devfreq->profile->max_state,
				    devfreq->profile->max_state),
			GFP_KERNEL);
	if (!devfreq->stats.trans_table) {
		mutex_unlock(&devfreq->lock);
		err = -ENOMEM;
		goto err_devfreq;
	}

	devfreq->stats.time_in_state = devm_kcalloc(&devfreq->dev,
			devfreq->profile->max_state,
			sizeof(*devfreq->stats.time_in_state),
			GFP_KERNEL);
	if (!devfreq->stats.time_in_state) {
		mutex_unlock(&devfreq->lock);
		err = -ENOMEM;
		goto err_devfreq;
	}

	devfreq->stats.total_trans = 0;
	devfreq->stats.last_update = get_jiffies_64();

	srcu_init_notifier_head(&devfreq->transition_notifier_list);

	mutex_unlock(&devfreq->lock);

	err = dev_pm_qos_add_request(dev, &devfreq->user_min_freq_req,
				     DEV_PM_QOS_MIN_FREQUENCY, 0);
	if (err < 0)
		goto err_devfreq;
	err = dev_pm_qos_add_request(dev, &devfreq->user_max_freq_req,
				     DEV_PM_QOS_MAX_FREQUENCY,
				     PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
	if (err < 0)
		goto err_devfreq;

	devfreq->nb_min.notifier_call = qos_min_notifier_call;
	err = dev_pm_qos_add_notifier(dev, &devfreq->nb_min,
				      DEV_PM_QOS_MIN_FREQUENCY);
	if (err)
		goto err_devfreq;

	devfreq->nb_max.notifier_call = qos_max_notifier_call;
	err = dev_pm_qos_add_notifier(dev, &devfreq->nb_max,
				      DEV_PM_QOS_MAX_FREQUENCY);
	if (err)
		goto err_devfreq;

	mutex_lock(&devfreq_list_lock);

	governor = try_then_request_governor(governor_name);
	if (IS_ERR(governor)) {
		dev_err(dev, "%s: Unable to find governor for the device\n",
			__func__);
		err = PTR_ERR(governor);
		goto err_init;
	}

	devfreq->governor = governor;
	err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START,
						NULL);
	if (err) {
		dev_err(dev, "%s: Unable to start governor for the device\n",
			__func__);
		goto err_init;
	}
	create_sysfs_files(devfreq, devfreq->governor);

	list_add(&devfreq->node, &devfreq_list);

	mutex_unlock(&devfreq_list_lock);

	if (devfreq->profile->is_cooling_device) {
		devfreq->cdev = devfreq_cooling_em_register(devfreq, NULL);
		if (IS_ERR(devfreq->cdev))
			devfreq->cdev = NULL;
	}

	return devfreq;

err_init:
	mutex_unlock(&devfreq_list_lock);
err_devfreq:
	devfreq_remove_device(devfreq);
	devfreq = NULL;
err_dev:
	kfree(devfreq);
err_out:
	return ERR_PTR(err);
}