mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'pm-devfreq'
* pm-devfreq: PM / devfreq: Modify the device name as devfreq(X) for sysfs PM / devfreq: Simplify the sysfs name of devfreq-event device PM / devfreq: Remove unnecessary separate _remove_devfreq() PM / devfreq: Fix wrong trans_stat of passive devfreq device PM / devfreq: Fix available_governor sysfs PM / devfreq: exynos-ppmu: Show the registred device for ppmu device PM / devfreq: Fix the wrong description for userspace governor PM / devfreq: Fix the checkpatch warnings PM / devfreq: exynos-bus: Print the real clock rate of bus PM / devfreq: exynos-ppmu: Use the regmap interface to handle the registers PM / devfreq: exynos-bus: Add the detailed correlation for Exynos5433 PM / devfreq: Don't delete sysfs group twice
This commit is contained in:
commit
41ef3d1df0
10 files changed
+349
-125
No files matched your search
@@ -0,0 +1,25 @@
|
||||
What: /sys/class/devfreq-event/event(x)/
|
||||
Date: January 2017
|
||||
Contact: Chanwoo Choi <cw00.choi@samsung.com>
|
||||
Description:
|
||||
Provide a place in sysfs for the devfreq-event objects.
|
||||
This allows accessing various devfreq-event specific variables.
|
||||
The name of devfreq-event object denoted as 'event(x)' which
|
||||
includes the unique number of 'x' for each devfreq-event object.
|
||||
|
||||
What: /sys/class/devfreq-event/event(x)/name
|
||||
Date: January 2017
|
||||
Contact: Chanwoo Choi <cw00.choi@samsung.com>
|
||||
Description:
|
||||
The /sys/class/devfreq-event/event(x)/name attribute contains
|
||||
the name of the devfreq-event object. This attribute is
|
||||
read-only.
|
||||
|
||||
What: /sys/class/devfreq-event/event(x)/enable_count
|
||||
Date: January 2017
|
||||
Contact: Chanwoo Choi <cw00.choi@samsung.com>
|
||||
Description:
|
||||
The /sys/class/devfreq-event/event(x)/enable_count attribute
|
||||
contains the reference count to enable the devfreq-event
|
||||
object. If the device is enabled, the value of attribute is
|
||||
greater than zero.
|
||||
@@ -123,6 +123,20 @@ Detailed correlation between sub-blocks and power line according to Exynos SoC:
|
||||
|--- FSYS
|
||||
|--- FSYS2
|
||||
|
||||
- In case of Exynos5433, there is VDD_INT power line as following:
|
||||
VDD_INT |--- G2D (parent device)
|
||||
|--- MSCL
|
||||
|--- GSCL
|
||||
|--- JPEG
|
||||
|--- MFC
|
||||
|--- HEVC
|
||||
|--- BUS0
|
||||
|--- BUS1
|
||||
|--- BUS2
|
||||
|--- PERIS (Fixed clock rate)
|
||||
|--- PERIC (Fixed clock rate)
|
||||
|--- FSYS (Fixed clock rate)
|
||||
|
||||
Example1:
|
||||
Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to
|
||||
power line (regulator). The MIF (Memory Interface) AXI bus is used to
|
||||
|
||||
@@ -306,7 +306,7 @@ struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
|
||||
struct devfreq_event_desc *desc)
|
||||
{
|
||||
struct devfreq_event_dev *edev;
|
||||
static atomic_t event_no = ATOMIC_INIT(0);
|
||||
static atomic_t event_no = ATOMIC_INIT(-1);
|
||||
int ret;
|
||||
|
||||
if (!dev || !desc)
|
||||
@@ -329,7 +329,7 @@ struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev,
|
||||
edev->dev.class = devfreq_event_class;
|
||||
edev->dev.release = devfreq_event_release_edev;
|
||||
|
||||
dev_set_name(&edev->dev, "event.%d", atomic_inc_return(&event_no) - 1);
|
||||
dev_set_name(&edev->dev, "event%d", atomic_inc_return(&event_no));
|
||||
ret = device_register(&edev->dev);
|
||||
if (ret < 0) {
|
||||
put_device(&edev->dev);
|
||||
|
||||
+46
-28
@@ -128,7 +128,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
|
||||
* @devfreq: the devfreq instance
|
||||
* @freq: the update target frequency
|
||||
*/
|
||||
static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
|
||||
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
|
||||
{
|
||||
int lev, prev_lev, ret = 0;
|
||||
unsigned long cur_time;
|
||||
@@ -164,6 +164,7 @@ out:
|
||||
devfreq->last_stat_updated = cur_time;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(devfreq_update_status);
|
||||
|
||||
/**
|
||||
* find_devfreq_governor() - find devfreq governor from name
|
||||
@@ -472,11 +473,15 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
|
||||
}
|
||||
|
||||
/**
|
||||
* _remove_devfreq() - Remove devfreq from the list and release its resources.
|
||||
* @devfreq: the devfreq struct
|
||||
* devfreq_dev_release() - Callback for struct device to release the device.
|
||||
* @dev: the devfreq device
|
||||
*
|
||||
* Remove devfreq from the list and release its resources.
|
||||
*/
|
||||
static void _remove_devfreq(struct devfreq *devfreq)
|
||||
static void devfreq_dev_release(struct device *dev)
|
||||
{
|
||||
struct devfreq *devfreq = to_devfreq(dev);
|
||||
|
||||
mutex_lock(&devfreq_list_lock);
|
||||
if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) {
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
@@ -497,19 +502,6 @@ static void _remove_devfreq(struct devfreq *devfreq)
|
||||
kfree(devfreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* devfreq_dev_release() - Callback for struct device to release the device.
|
||||
* @dev: the devfreq device
|
||||
*
|
||||
* This calls _remove_devfreq() if _remove_devfreq() is not called.
|
||||
*/
|
||||
static void devfreq_dev_release(struct device *dev)
|
||||
{
|
||||
struct devfreq *devfreq = to_devfreq(dev);
|
||||
|
||||
_remove_devfreq(devfreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* devfreq_add_device() - Add devfreq feature to the device
|
||||
* @dev: the device to add devfreq feature.
|
||||
@@ -525,6 +517,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
|
||||
{
|
||||
struct devfreq *devfreq;
|
||||
struct devfreq_governor *governor;
|
||||
static atomic_t devfreq_no = ATOMIC_INIT(-1);
|
||||
int err = 0;
|
||||
|
||||
if (!dev || !profile || !governor_name) {
|
||||
@@ -536,15 +529,14 @@ struct devfreq *devfreq_add_device(struct device *dev,
|
||||
devfreq = find_device_devfreq(dev);
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
if (!IS_ERR(devfreq)) {
|
||||
dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__);
|
||||
dev_err(dev, "%s: Unable to create devfreq for the device.\n",
|
||||
__func__);
|
||||
err = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL);
|
||||
if (!devfreq) {
|
||||
dev_err(dev, "%s: Unable to create devfreq for the device\n",
|
||||
__func__);
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
@@ -567,18 +559,21 @@ struct devfreq *devfreq_add_device(struct device *dev,
|
||||
mutex_lock(&devfreq->lock);
|
||||
}
|
||||
|
||||
dev_set_name(&devfreq->dev, "%s", dev_name(dev));
|
||||
dev_set_name(&devfreq->dev, "devfreq%d",
|
||||
atomic_inc_return(&devfreq_no));
|
||||
err = device_register(&devfreq->dev);
|
||||
if (err) {
|
||||
mutex_unlock(&devfreq->lock);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
devfreq->trans_table = devm_kzalloc(&devfreq->dev, sizeof(unsigned int) *
|
||||
devfreq->trans_table = devm_kzalloc(&devfreq->dev,
|
||||
sizeof(unsigned int) *
|
||||
devfreq->profile->max_state *
|
||||
devfreq->profile->max_state,
|
||||
GFP_KERNEL);
|
||||
devfreq->time_in_state = devm_kzalloc(&devfreq->dev, sizeof(unsigned long) *
|
||||
devfreq->time_in_state = devm_kzalloc(&devfreq->dev,
|
||||
sizeof(unsigned long) *
|
||||
devfreq->profile->max_state,
|
||||
GFP_KERNEL);
|
||||
devfreq->last_stat_updated = jiffies;
|
||||
@@ -937,6 +932,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
|
||||
if (df->governor == governor) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
} else if (df->governor->immutable || governor->immutable) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (df->governor) {
|
||||
@@ -966,13 +964,33 @@ static ssize_t available_governors_show(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct devfreq_governor *tmp_governor;
|
||||
struct devfreq *df = to_devfreq(d);
|
||||
ssize_t count = 0;
|
||||
|
||||
mutex_lock(&devfreq_list_lock);
|
||||
list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%s ", tmp_governor->name);
|
||||
|
||||
/*
|
||||
* The devfreq with immutable governor (e.g., passive) shows
|
||||
* only own governor.
|
||||
*/
|
||||
if (df->governor->immutable) {
|
||||
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
|
||||
"%s ", df->governor_name);
|
||||
/*
|
||||
* The devfreq device shows the registered governor except for
|
||||
* immutable governors such as passive governor .
|
||||
*/
|
||||
} else {
|
||||
struct devfreq_governor *governor;
|
||||
|
||||
list_for_each_entry(governor, &devfreq_governor_list, node) {
|
||||
if (governor->immutable)
|
||||
continue;
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%s ", governor->name);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&devfreq_list_lock);
|
||||
|
||||
/* Truncate the trailing space */
|
||||
@@ -993,7 +1011,7 @@ static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
if (devfreq->profile->get_cur_freq &&
|
||||
!devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
|
||||
return sprintf(buf, "%lu\n", freq);
|
||||
return sprintf(buf, "%lu\n", freq);
|
||||
|
||||
return sprintf(buf, "%lu\n", devfreq->previous_freq);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -146,8 +146,8 @@ static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
|
||||
}
|
||||
bus->curr_freq = new_freq;
|
||||
|
||||
dev_dbg(dev, "Set the frequency of bus (%lukHz -> %lukHz)\n",
|
||||
old_freq/1000, new_freq/1000);
|
||||
dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
|
||||
old_freq, new_freq, clk_get_rate(bus->clk));
|
||||
out:
|
||||
mutex_unlock(&bus->lock);
|
||||
|
||||
@@ -239,8 +239,8 @@ static int exynos_bus_passive_target(struct device *dev, unsigned long *freq,
|
||||
*freq = new_freq;
|
||||
bus->curr_freq = new_freq;
|
||||
|
||||
dev_dbg(dev, "Set the frequency of bus (%lukHz -> %lukHz)\n",
|
||||
old_freq/1000, new_freq/1000);
|
||||
dev_dbg(dev, "Set the frequency of bus (%luHz -> %luHz, %luHz)\n",
|
||||
old_freq, new_freq, clk_get_rate(bus->clk));
|
||||
out:
|
||||
mutex_unlock(&bus->lock);
|
||||
|
||||
|
||||
@@ -38,4 +38,6 @@ extern void devfreq_interval_update(struct devfreq *devfreq,
|
||||
extern int devfreq_add_governor(struct devfreq_governor *governor);
|
||||
extern int devfreq_remove_governor(struct devfreq_governor *governor);
|
||||
|
||||
extern int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
|
||||
|
||||
#endif /* _GOVERNOR_H */
|
||||
@@ -112,6 +112,11 @@ static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (devfreq->profile->freq_table
|
||||
&& (devfreq_update_status(devfreq, freq)))
|
||||
dev_err(&devfreq->dev,
|
||||
"Couldn't update frequency transition information.\n");
|
||||
|
||||
devfreq->previous_freq = freq;
|
||||
|
||||
out:
|
||||
@@ -179,6 +184,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
|
||||
|
||||
static struct devfreq_governor devfreq_passive = {
|
||||
.name = "passive",
|
||||
.immutable = 1,
|
||||
.get_target_freq = devfreq_passive_get_target_freq,
|
||||
.event_handler = devfreq_passive_event_handler,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* linux/drivers/devfreq/governor_simpleondemand.c
|
||||
* linux/drivers/devfreq/governor_userspace.c
|
||||
*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
@@ -50,7 +50,6 @@ static ssize_t store_freq(struct device *dev, struct device_attribute *attr,
|
||||
unsigned long wanted;
|
||||
int err = 0;
|
||||
|
||||
|
||||
mutex_lock(&devfreq->lock);
|
||||
data = devfreq->data;
|
||||
|
||||
@@ -112,7 +111,13 @@ out:
|
||||
|
||||
static void userspace_exit(struct devfreq *devfreq)
|
||||
{
|
||||
sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
|
||||
/*
|
||||
* Remove the sysfs entry, unless this is being called after
|
||||
* device_del(), which should have done this already via kobject_del().
|
||||
*/
|
||||
if (devfreq->dev.kobj.sd)
|
||||
sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
|
||||
|
||||
kfree(devfreq->data);
|
||||
devfreq->data = NULL;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ struct devfreq_dev_profile {
|
||||
* struct devfreq_governor - Devfreq policy governor
|
||||
* @node: list node - contains registered devfreq governors
|
||||
* @name: Governor's name
|
||||
* @immutable: Immutable flag for governor. If the value is 1,
|
||||
* this govenror is never changeable to other governor.
|
||||
* @get_target_freq: Returns desired operating frequency for the device.
|
||||
* Basically, get_target_freq will run
|
||||
* devfreq_dev_profile.get_dev_status() to get the
|
||||
@@ -121,6 +123,7 @@ struct devfreq_governor {
|
||||
struct list_head node;
|
||||
|
||||
const char name[DEVFREQ_NAME_LEN];
|
||||
const unsigned int immutable;
|
||||
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
|
||||
int (*event_handler)(struct devfreq *devfreq,
|
||||
unsigned int event, void *data);
|
||||
|
||||
Reference in new issue
Block a user