Merge branch 'devfreq-for-next' of git://git.infradead.org/users/kmpark/linux-samsung...
[deliverable/linux.git] / drivers / devfreq / devfreq.c
index 59d24e9cb8c512a949a24803c5bf11a143fc649d..a129a7b6bfd121a603f401053bbe0a11865ce03a 100644 (file)
@@ -347,7 +347,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
                if (!IS_ERR(devfreq)) {
                        dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__);
                        err = -EINVAL;
-                       goto out;
+                       goto err_out;
                }
        }
 
@@ -356,7 +356,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
                dev_err(dev, "%s: Unable to create devfreq for the device\n",
                        __func__);
                err = -ENOMEM;
-               goto out;
+               goto err_out;
        }
 
        mutex_init(&devfreq->lock);
@@ -399,17 +399,16 @@ struct devfreq *devfreq_add_device(struct device *dev,
                                   devfreq->next_polling);
        }
        mutex_unlock(&devfreq_list_lock);
-       goto out;
+out:
+       return devfreq;
+
 err_init:
        device_unregister(&devfreq->dev);
 err_dev:
        mutex_unlock(&devfreq->lock);
        kfree(devfreq);
-out:
-       if (err)
-               return ERR_PTR(err);
-       else
-               return devfreq;
+err_out:
+       return ERR_PTR(err);
 }
 
 /**
@@ -502,12 +501,82 @@ static ssize_t show_central_polling(struct device *dev,
                       !to_devfreq(dev)->governor->no_central_polling);
 }
 
+static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+{
+       struct devfreq *df = to_devfreq(dev);
+       unsigned long value;
+       int ret;
+       unsigned long max;
+
+       ret = sscanf(buf, "%lu", &value);
+       if (ret != 1)
+               goto out;
+
+       mutex_lock(&df->lock);
+       max = df->max_freq;
+       if (value && max && value > max) {
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+       df->min_freq = value;
+       update_devfreq(df);
+       ret = count;
+unlock:
+       mutex_unlock(&df->lock);
+out:
+       return ret;
+}
+
+static ssize_t show_min_freq(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq);
+}
+
+static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+{
+       struct devfreq *df = to_devfreq(dev);
+       unsigned long value;
+       int ret;
+       unsigned long min;
+
+       ret = sscanf(buf, "%lu", &value);
+       if (ret != 1)
+               goto out;
+
+       mutex_lock(&df->lock);
+       min = df->min_freq;
+       if (value && min && value < min) {
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+       df->max_freq = value;
+       update_devfreq(df);
+       ret = count;
+unlock:
+       mutex_unlock(&df->lock);
+out:
+       return ret;
+}
+
+static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq);
+}
+
 static struct device_attribute devfreq_attrs[] = {
        __ATTR(governor, S_IRUGO, show_governor, NULL),
        __ATTR(cur_freq, S_IRUGO, show_freq, NULL),
        __ATTR(central_polling, S_IRUGO, show_central_polling, NULL),
        __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval,
               store_polling_interval),
+       __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq),
+       __ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq),
        { },
 };
 
This page took 0.026719 seconds and 5 git commands to generate.