linux/drivers/devfreq/governor_userspace.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/devfreq/governor_simpleondemand.c
   3 *
   4 *  Copyright (C) 2011 Samsung Electronics
   5 *      MyungJoo Ham <myungjoo.ham@samsung.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/slab.h>
  13#include <linux/device.h>
  14#include <linux/devfreq.h>
  15#include <linux/pm.h>
  16#include <linux/mutex.h>
  17#include "governor.h"
  18
  19struct userspace_data {
  20        unsigned long user_frequency;
  21        bool valid;
  22};
  23
  24static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
  25{
  26        struct userspace_data *data = df->data;
  27
  28        if (data->valid) {
  29                unsigned long adjusted_freq = data->user_frequency;
  30
  31                if (df->max_freq && adjusted_freq > df->max_freq)
  32                        adjusted_freq = df->max_freq;
  33
  34                if (df->min_freq && adjusted_freq < df->min_freq)
  35                        adjusted_freq = df->min_freq;
  36
  37                *freq = adjusted_freq;
  38        } else {
  39                *freq = df->previous_freq; /* No user freq specified yet */
  40        }
  41        return 0;
  42}
  43
  44static ssize_t store_freq(struct device *dev, struct device_attribute *attr,
  45                          const char *buf, size_t count)
  46{
  47        struct devfreq *devfreq = to_devfreq(dev);
  48        struct userspace_data *data;
  49        unsigned long wanted;
  50        int err = 0;
  51
  52
  53        mutex_lock(&devfreq->lock);
  54        data = devfreq->data;
  55
  56        sscanf(buf, "%lu", &wanted);
  57        data->user_frequency = wanted;
  58        data->valid = true;
  59        err = update_devfreq(devfreq);
  60        if (err == 0)
  61                err = count;
  62        mutex_unlock(&devfreq->lock);
  63        return err;
  64}
  65
  66static ssize_t show_freq(struct device *dev, struct device_attribute *attr,
  67                         char *buf)
  68{
  69        struct devfreq *devfreq = to_devfreq(dev);
  70        struct userspace_data *data;
  71        int err = 0;
  72
  73        mutex_lock(&devfreq->lock);
  74        data = devfreq->data;
  75
  76        if (data->valid)
  77                err = sprintf(buf, "%lu\n", data->user_frequency);
  78        else
  79                err = sprintf(buf, "undefined\n");
  80        mutex_unlock(&devfreq->lock);
  81        return err;
  82}
  83
  84static DEVICE_ATTR(set_freq, 0644, show_freq, store_freq);
  85static struct attribute *dev_entries[] = {
  86        &dev_attr_set_freq.attr,
  87        NULL,
  88};
  89static struct attribute_group dev_attr_group = {
  90        .name   = "userspace",
  91        .attrs  = dev_entries,
  92};
  93
  94static int userspace_init(struct devfreq *devfreq)
  95{
  96        int err = 0;
  97        struct userspace_data *data = kzalloc(sizeof(struct userspace_data),
  98                                              GFP_KERNEL);
  99
 100        if (!data) {
 101                err = -ENOMEM;
 102                goto out;
 103        }
 104        data->valid = false;
 105        devfreq->data = data;
 106
 107        err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group);
 108out:
 109        return err;
 110}
 111
 112static void userspace_exit(struct devfreq *devfreq)
 113{
 114        sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
 115        kfree(devfreq->data);
 116        devfreq->data = NULL;
 117}
 118
 119const struct devfreq_governor devfreq_userspace = {
 120        .name = "userspace",
 121        .get_target_freq = devfreq_userspace_func,
 122        .init = userspace_init,
 123        .exit = userspace_exit,
 124        .no_central_polling = true,
 125};
 126
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.