2 * linux/drivers/devfreq/governor_simpleondemand.c
4 * Copyright (C) 2011 Samsung Electronics
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
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.
12 #include <linux/slab.h>
13 #include <linux/device.h>
14 #include <linux/devfreq.h>
16 #include <linux/mutex.h>
19 struct userspace_data
{
20 unsigned long user_frequency
;
24 static int devfreq_userspace_func(struct devfreq
*df
, unsigned long *freq
)
26 struct userspace_data
*data
= df
->data
;
29 unsigned long adjusted_freq
= data
->user_frequency
;
31 if (df
->max_freq
&& adjusted_freq
> df
->max_freq
)
32 adjusted_freq
= df
->max_freq
;
34 if (df
->min_freq
&& adjusted_freq
< df
->min_freq
)
35 adjusted_freq
= df
->min_freq
;
37 *freq
= adjusted_freq
;
39 *freq
= df
->previous_freq
; /* No user freq specified yet */
44 static ssize_t
store_freq(struct device
*dev
, struct device_attribute
*attr
,
45 const char *buf
, size_t count
)
47 struct devfreq
*devfreq
= to_devfreq(dev
);
48 struct userspace_data
*data
;
53 mutex_lock(&devfreq
->lock
);
56 sscanf(buf
, "%lu", &wanted
);
57 data
->user_frequency
= wanted
;
59 err
= update_devfreq(devfreq
);
62 mutex_unlock(&devfreq
->lock
);
66 static ssize_t
show_freq(struct device
*dev
, struct device_attribute
*attr
,
69 struct devfreq
*devfreq
= to_devfreq(dev
);
70 struct userspace_data
*data
;
73 mutex_lock(&devfreq
->lock
);
77 err
= sprintf(buf
, "%lu\n", data
->user_frequency
);
79 err
= sprintf(buf
, "undefined\n");
80 mutex_unlock(&devfreq
->lock
);
84 static DEVICE_ATTR(set_freq
, 0644, show_freq
, store_freq
);
85 static struct attribute
*dev_entries
[] = {
86 &dev_attr_set_freq
.attr
,
89 static struct attribute_group dev_attr_group
= {
94 static int userspace_init(struct devfreq
*devfreq
)
97 struct userspace_data
*data
= kzalloc(sizeof(struct userspace_data
),
105 devfreq
->data
= data
;
107 err
= sysfs_create_group(&devfreq
->dev
.kobj
, &dev_attr_group
);
112 static void userspace_exit(struct devfreq
*devfreq
)
114 sysfs_remove_group(&devfreq
->dev
.kobj
, &dev_attr_group
);
115 kfree(devfreq
->data
);
116 devfreq
->data
= NULL
;
119 const struct devfreq_governor devfreq_userspace
= {
121 .get_target_freq
= devfreq_userspace_func
,
122 .init
= userspace_init
,
123 .exit
= userspace_exit
,
124 .no_central_polling
= true,