mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
Merge branch 'develop-3.10-next' of ssh://10.10.10.29/rk/kernel into develop-3.10-next
This commit is contained in:
@@ -38,8 +38,6 @@ its hardware characteristcs.
|
||||
AMBA markee):
|
||||
- "arm,coresight-replicator"
|
||||
|
||||
* id: a unique number that will identify this replicator.
|
||||
|
||||
* port or ports: same as above.
|
||||
|
||||
* Optional properties for ETM/PTMs:
|
||||
@@ -94,8 +92,6 @@ Example:
|
||||
* AMBA bus. As such no need to add "arm,primecell".
|
||||
*/
|
||||
compatible = "arm,coresight-replicator";
|
||||
/* this will show up in debugfs as "0.replicator" */
|
||||
id = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
|
||||
@@ -46,7 +46,7 @@ At typical coresight system would look like this:
|
||||
| | . | ! | | . | ! | ! . | | SWD/
|
||||
| | . | ! | | . | ! | ! . | | JTAG
|
||||
*****************************************************************<-|
|
||||
*************************** AMBA Debug ABP ************************
|
||||
*************************** AMBA Debug APB ************************
|
||||
*****************************************************************
|
||||
| . ! . ! ! . |
|
||||
| . * . * * . |
|
||||
@@ -79,7 +79,7 @@ At typical coresight system would look like this:
|
||||
To trace port TPIU= Trace Port Interface Unit
|
||||
SWD = Serial Wire Debug
|
||||
|
||||
While on target configuration of the components is done via the ABP bus,
|
||||
While on target configuration of the components is done via the APB bus,
|
||||
all trace data are carried out-of-band on the ATB bus. The CTM provides
|
||||
a way to aggregate and distribute signals between CoreSight components.
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/async.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <trace/events/power.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/wakeup_reason.h>
|
||||
@@ -777,8 +775,6 @@ void dpm_resume(pm_message_t state)
|
||||
mutex_unlock(&dpm_list_mtx);
|
||||
async_synchronize_full();
|
||||
dpm_show_time(starttime, state, NULL);
|
||||
|
||||
cpufreq_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1260,8 +1256,6 @@ int dpm_suspend(pm_message_t state)
|
||||
|
||||
might_sleep();
|
||||
|
||||
cpufreq_suspend();
|
||||
|
||||
mutex_lock(&dpm_list_mtx);
|
||||
pm_transition = state;
|
||||
async_error = 0;
|
||||
|
||||
@@ -454,7 +454,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
|
||||
drvdata->buffer_depth = etb_get_buffer_depth(drvdata);
|
||||
clk_disable_unprepare(drvdata->clk);
|
||||
|
||||
if (drvdata->buffer_depth < 0)
|
||||
@@ -521,17 +521,7 @@ static struct amba_driver etb_driver = {
|
||||
.id_table = etb_ids,
|
||||
};
|
||||
|
||||
static int __init etb_init(void)
|
||||
{
|
||||
return amba_driver_register(&etb_driver);
|
||||
}
|
||||
module_init(etb_init);
|
||||
|
||||
static void __exit etb_exit(void)
|
||||
{
|
||||
amba_driver_unregister(&etb_driver);
|
||||
}
|
||||
module_exit(etb_exit);
|
||||
module_amba_driver(etb_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("CoreSight Embedded Trace Buffer driver");
|
||||
|
||||
@@ -34,14 +34,8 @@
|
||||
|
||||
#include "coresight-etm.h"
|
||||
|
||||
#ifdef CONFIG_CORESIGHT_SOURCE_ETM_DEFAULT_ENABLE
|
||||
static int boot_enable = 1;
|
||||
#else
|
||||
static int boot_enable;
|
||||
#endif
|
||||
module_param_named(
|
||||
boot_enable, boot_enable, int, S_IRUGO
|
||||
);
|
||||
module_param_named(boot_enable, boot_enable, int, S_IRUGO);
|
||||
|
||||
/* The number of ETM/PTM currently registered */
|
||||
static int etm_count;
|
||||
@@ -573,7 +567,8 @@ static ssize_t mode_store(struct device *dev,
|
||||
if (drvdata->mode & ETM_MODE_STALL) {
|
||||
if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) {
|
||||
dev_warn(drvdata->dev, "stall mode not supported\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_unlock;
|
||||
}
|
||||
drvdata->ctrl |= ETMCR_STALL_MODE;
|
||||
} else
|
||||
@@ -582,7 +577,8 @@ static ssize_t mode_store(struct device *dev,
|
||||
if (drvdata->mode & ETM_MODE_TIMESTAMP) {
|
||||
if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) {
|
||||
dev_warn(drvdata->dev, "timestamp not supported\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_unlock;
|
||||
}
|
||||
drvdata->ctrl |= ETMCR_TIMESTAMP_EN;
|
||||
} else
|
||||
@@ -595,6 +591,10 @@ static ssize_t mode_store(struct device *dev,
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
|
||||
return size;
|
||||
|
||||
err_unlock:
|
||||
spin_unlock(&drvdata->spinlock);
|
||||
return ret;
|
||||
}
|
||||
static DEVICE_ATTR_RW(mode);
|
||||
|
||||
@@ -1743,7 +1743,11 @@ static void etm_init_arch_data(void *info)
|
||||
|
||||
static void etm_init_default_data(struct etm_drvdata *drvdata)
|
||||
{
|
||||
static int etm3x_traceid;
|
||||
/*
|
||||
* A trace ID of value 0 is invalid, so let's start at some
|
||||
* random value that fits in 7 bits and will be just as good.
|
||||
*/
|
||||
static int etm3x_traceid = 0x10;
|
||||
|
||||
u32 flags = (1 << 0 | /* instruction execute*/
|
||||
3 << 3 | /* ARM instruction */
|
||||
|
||||
@@ -252,17 +252,7 @@ static struct amba_driver funnel_driver = {
|
||||
.id_table = funnel_ids,
|
||||
};
|
||||
|
||||
static int __init funnel_init(void)
|
||||
{
|
||||
return amba_driver_register(&funnel_driver);
|
||||
}
|
||||
module_init(funnel_init);
|
||||
|
||||
static void __exit funnel_exit(void)
|
||||
{
|
||||
amba_driver_unregister(&funnel_driver);
|
||||
}
|
||||
module_exit(funnel_exit);
|
||||
module_amba_driver(funnel_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("CoreSight Funnel driver");
|
||||
|
||||
@@ -57,7 +57,7 @@ extern int etm_readl_cp14(u32 off, unsigned int *val);
|
||||
extern int etm_writel_cp14(u32 off, u32 val);
|
||||
#else
|
||||
static inline int etm_readl_cp14(u32 off, unsigned int *val) { return 0; }
|
||||
static inline int etm_writel_cp14(u32 val, u32 off) { return 0; }
|
||||
static inline int etm_writel_cp14(u32 off, u32 val) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -87,7 +87,7 @@ static int replicator_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
desc->type = CORESIGHT_DEV_TYPE_LINK;
|
||||
desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
|
||||
desc->subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_SPLIT;
|
||||
desc->ops = &replicator_cs_ops;
|
||||
desc->pdata = pdev->dev.platform_data;
|
||||
desc->dev = &pdev->dev;
|
||||
|
||||
@@ -760,17 +760,7 @@ static struct amba_driver tmc_driver = {
|
||||
.id_table = tmc_ids,
|
||||
};
|
||||
|
||||
static int __init tmc_init(void)
|
||||
{
|
||||
return amba_driver_register(&tmc_driver);
|
||||
}
|
||||
module_init(tmc_init);
|
||||
|
||||
static void __exit tmc_exit(void)
|
||||
{
|
||||
amba_driver_unregister(&tmc_driver);
|
||||
}
|
||||
module_exit(tmc_exit);
|
||||
module_amba_driver(tmc_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("CoreSight Trace Memory Controller driver");
|
||||
|
||||
@@ -201,17 +201,7 @@ static struct amba_driver tpiu_driver = {
|
||||
.id_table = tpiu_ids,
|
||||
};
|
||||
|
||||
static int __init tpiu_init(void)
|
||||
{
|
||||
return amba_driver_register(&tpiu_driver);
|
||||
}
|
||||
module_init(tpiu_init);
|
||||
|
||||
static void __exit tpiu_exit(void)
|
||||
{
|
||||
amba_driver_unregister(&tpiu_driver);
|
||||
}
|
||||
module_exit(tpiu_exit);
|
||||
module_amba_driver(tpiu_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("CoreSight Trace Port Interface Unit driver");
|
||||
|
||||
@@ -498,17 +498,18 @@ static int coresight_orphan_match(struct device *dev, void *data)
|
||||
* Circle throuch all the connection of that component. If we find
|
||||
* an orphan connection whose name matches @csdev, link it.
|
||||
*/
|
||||
for (i = 0; i < i_csdev->nr_outport; i++) {
|
||||
for (i = 0; i < i_csdev->nr_outport; i++) {
|
||||
conn = &i_csdev->conns[i];
|
||||
|
||||
/* We have found at least one orphan connection */
|
||||
if (conn->child_dev == NULL) {
|
||||
/* Does it match this newly added device? */
|
||||
if (!strcmp(dev_name(&csdev->dev), conn->child_name))
|
||||
if (!strcmp(dev_name(&csdev->dev), conn->child_name)) {
|
||||
conn->child_dev = csdev;
|
||||
} else {
|
||||
/* Too bad, this component still has an orphan */
|
||||
still_orphan = true;
|
||||
} else {
|
||||
/* This component still has an orphan */
|
||||
still_orphan = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ static int of_coresight_alloc_memory(struct device *dev,
|
||||
if (!pdata->outports)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Children connected to this component via @outport */
|
||||
/* Children connected to this component via @outports */
|
||||
pdata->child_names = devm_kzalloc(dev, pdata->nr_outport *
|
||||
sizeof(*pdata->child_names),
|
||||
GFP_KERNEL);
|
||||
@@ -117,7 +117,7 @@ struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
struct coresight_platform_data *pdata;
|
||||
struct of_endpoint endpoint, rendpoint;
|
||||
struct device *rdev;
|
||||
struct device_node *cpu;
|
||||
struct device_node *dn;
|
||||
struct device_node *ep = NULL;
|
||||
struct device_node *rparent = NULL;
|
||||
struct device_node *rport = NULL;
|
||||
@@ -126,7 +126,7 @@ struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
if (!pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* Use device name as debugfs handle */
|
||||
/* Use device name as sysfs handle */
|
||||
pdata->name = dev_name(dev);
|
||||
|
||||
/* Get the number of input and output port for this component */
|
||||
@@ -174,7 +174,7 @@ struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
continue;
|
||||
|
||||
rdev = of_coresight_get_endpoint_device(rparent);
|
||||
if (!dev)
|
||||
if (!rdev)
|
||||
continue;
|
||||
|
||||
pdata->child_names[i] = dev_name(rdev);
|
||||
@@ -186,14 +186,16 @@ struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
|
||||
/* Affinity defaults to CPU0 */
|
||||
pdata->cpu = 0;
|
||||
cpu = of_parse_phandle(node, "cpu", 0);
|
||||
if (cpu) {
|
||||
const u32 *mpidr;
|
||||
dn = of_parse_phandle(node, "cpu", 0);
|
||||
if (dn) {
|
||||
const u32 *cell;
|
||||
int len, index;
|
||||
u64 hwid;
|
||||
|
||||
mpidr = of_get_property(cpu, "reg", &len);
|
||||
if (mpidr && len == 4) {
|
||||
index = get_logical_index(be32_to_cpup(mpidr));
|
||||
cell = of_get_property(dn, "reg", &len);
|
||||
if (cell) {
|
||||
hwid = of_read_number(cell, of_n_addr_cells(dn));
|
||||
index = get_logical_index(hwid);
|
||||
if (index != -EINVAL)
|
||||
pdata->cpu = index;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/tick.h>
|
||||
|
||||
#include <trace/events/power.h>
|
||||
|
||||
@@ -53,14 +51,6 @@ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
|
||||
static DEFINE_RWLOCK(cpufreq_driver_lock);
|
||||
static DEFINE_MUTEX(cpufreq_governor_lock);
|
||||
|
||||
/* Flag to suspend/resume CPUFreq governors */
|
||||
static bool cpufreq_suspended;
|
||||
|
||||
static inline bool has_target(void)
|
||||
{
|
||||
return cpufreq_driver->target;
|
||||
}
|
||||
|
||||
/*
|
||||
* cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
|
||||
* all cpufreq/hotplug/workqueue/etc related lock issues.
|
||||
@@ -1333,72 +1323,83 @@ static struct subsys_interface cpufreq_interface = {
|
||||
|
||||
|
||||
/**
|
||||
* cpufreq_suspend() - Suspend CPUFreq governors
|
||||
* cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
|
||||
*
|
||||
* Called during system wide Suspend/Hibernate cycles for suspending governors
|
||||
* as some platforms can't change frequency after this point in suspend cycle.
|
||||
* Because some of the devices (like: i2c, regulators, etc) they use for
|
||||
* changing frequency are suspended quickly after this point.
|
||||
* This function is only executed for the boot processor. The other CPUs
|
||||
* have been put offline by means of CPU hotplug.
|
||||
*/
|
||||
void cpufreq_suspend(void)
|
||||
static int cpufreq_bp_suspend(void)
|
||||
{
|
||||
struct cpufreq_policy *policy;
|
||||
int ret = 0;
|
||||
|
||||
if (!cpufreq_driver)
|
||||
return;
|
||||
int cpu = smp_processor_id();
|
||||
struct cpufreq_policy *cpu_policy;
|
||||
|
||||
if (!has_target())
|
||||
return;
|
||||
pr_debug("suspending cpu %u\n", cpu);
|
||||
|
||||
pr_debug("%s: Suspending Governors\n", __func__);
|
||||
/* If there's no policy for the boot CPU, we have nothing to do. */
|
||||
cpu_policy = cpufreq_cpu_get(cpu);
|
||||
if (!cpu_policy)
|
||||
return 0;
|
||||
|
||||
policy = cpufreq_cpu_get(0);
|
||||
if (cpufreq_driver->suspend) {
|
||||
ret = cpufreq_driver->suspend(cpu_policy);
|
||||
if (ret)
|
||||
printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
|
||||
"step on CPU %u\n", cpu_policy->cpu);
|
||||
}
|
||||
|
||||
if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP))
|
||||
pr_err("%s: Failed to stop governor for policy: %p\n",
|
||||
__func__, policy);
|
||||
else if (cpufreq_driver->suspend
|
||||
&& cpufreq_driver->suspend(policy))
|
||||
pr_err("%s: Failed to suspend driver: %p\n", __func__,
|
||||
policy);
|
||||
|
||||
cpufreq_suspended = true;
|
||||
cpufreq_cpu_put(cpu_policy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpufreq_resume() - Resume CPUFreq governors
|
||||
* cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
|
||||
*
|
||||
* Called during system wide Suspend/Hibernate cycle for resuming governors that
|
||||
* are suspended with cpufreq_suspend().
|
||||
* 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
|
||||
* 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
|
||||
* restored. It will verify that the current freq is in sync with
|
||||
* what we believe it to be. This is a bit later than when it
|
||||
* should be, but nonethteless it's better than calling
|
||||
* cpufreq_driver->get() here which might re-enable interrupts...
|
||||
*
|
||||
* This function is only executed for the boot CPU. The other CPUs have not
|
||||
* been turned on yet.
|
||||
*/
|
||||
void cpufreq_resume(void)
|
||||
static void cpufreq_bp_resume(void)
|
||||
{
|
||||
struct cpufreq_policy *policy;
|
||||
int ret = 0;
|
||||
|
||||
if (!cpufreq_driver)
|
||||
int cpu = smp_processor_id();
|
||||
struct cpufreq_policy *cpu_policy;
|
||||
|
||||
pr_debug("resuming cpu %u\n", cpu);
|
||||
|
||||
/* If there's no policy for the boot CPU, we have nothing to do. */
|
||||
cpu_policy = cpufreq_cpu_get(cpu);
|
||||
if (!cpu_policy)
|
||||
return;
|
||||
|
||||
if (!has_target())
|
||||
return;
|
||||
if (cpufreq_driver->resume) {
|
||||
ret = cpufreq_driver->resume(cpu_policy);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "cpufreq: resume failed in ->resume "
|
||||
"step on CPU %u\n", cpu_policy->cpu);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("%s: Resuming Governors\n", __func__);
|
||||
schedule_work(&cpu_policy->update);
|
||||
|
||||
cpufreq_suspended = false;
|
||||
|
||||
policy = cpufreq_cpu_get(0);
|
||||
|
||||
if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
|
||||
|| __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
|
||||
pr_err("%s: Failed to start governor for policy: %p\n",
|
||||
__func__, policy);
|
||||
else if (cpufreq_driver->resume
|
||||
&& cpufreq_driver->resume(policy))
|
||||
pr_err("%s: Failed to resume driver: %p\n", __func__,
|
||||
policy);
|
||||
|
||||
schedule_work(&policy->update);
|
||||
fail:
|
||||
cpufreq_cpu_put(cpu_policy);
|
||||
}
|
||||
|
||||
static struct syscore_ops cpufreq_syscore_ops = {
|
||||
.suspend = cpufreq_bp_suspend,
|
||||
.resume = cpufreq_bp_resume,
|
||||
};
|
||||
|
||||
/**
|
||||
* cpufreq_get_current_driver - return current driver's name
|
||||
*
|
||||
@@ -1591,10 +1592,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
|
||||
struct cpufreq_governor *gov = NULL;
|
||||
#endif
|
||||
|
||||
/* Don't start any governor operations if we are entering suspend */
|
||||
if (cpufreq_suspended)
|
||||
return 0;
|
||||
|
||||
if (policy->governor->max_transition_latency &&
|
||||
policy->cpuinfo.transition_latency >
|
||||
policy->governor->max_transition_latency) {
|
||||
@@ -2052,6 +2049,7 @@ static int __init cpufreq_core_init(void)
|
||||
|
||||
cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
|
||||
BUG_ON(!cpufreq_global_kobject);
|
||||
register_syscore_ops(&cpufreq_syscore_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -179,15 +179,6 @@ struct coresight_device {
|
||||
#define sink_ops(csdev) csdev->ops->sink_ops
|
||||
#define link_ops(csdev) csdev->ops->link_ops
|
||||
|
||||
#define CORESIGHT_DEBUGFS_ENTRY(__name, __entry_name, \
|
||||
__mode, __get, __set, __fmt) \
|
||||
DEFINE_SIMPLE_ATTRIBUTE(__name ## _ops, __get, __set, __fmt); \
|
||||
static const struct coresight_ops_entry __name ## _entry = { \
|
||||
.name = __entry_name, \
|
||||
.mode = __mode, \
|
||||
.ops = &__name ## _ops \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct coresight_ops_sink - basic operations for a sink
|
||||
* Operations available for sinks
|
||||
@@ -236,13 +227,8 @@ coresight_register(struct coresight_desc *desc);
|
||||
extern void coresight_unregister(struct coresight_device *csdev);
|
||||
extern int coresight_enable(struct coresight_device *csdev);
|
||||
extern void coresight_disable(struct coresight_device *csdev);
|
||||
extern int coresight_is_bit_set(u32 val, int position, int value);
|
||||
extern int coresight_timeout(void __iomem *addr, u32 offset,
|
||||
int position, int value);
|
||||
#ifdef CONFIG_OF
|
||||
extern struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
struct device *dev, struct device_node *node);
|
||||
#endif
|
||||
#else
|
||||
static inline struct coresight_device *
|
||||
coresight_register(struct coresight_desc *desc) { return NULL; }
|
||||
@@ -250,14 +236,16 @@ static inline void coresight_unregister(struct coresight_device *csdev) {}
|
||||
static inline int
|
||||
coresight_enable(struct coresight_device *csdev) { return -ENOSYS; }
|
||||
static inline void coresight_disable(struct coresight_device *csdev) {}
|
||||
static inline int coresight_is_bit_set(u32 val, int position, int value)
|
||||
{ return 0; }
|
||||
static inline int coresight_timeout(void __iomem *addr, u32 offset,
|
||||
int position, int value) { return 1; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
extern struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
struct device *dev, struct device_node *node);
|
||||
#else
|
||||
static inline struct coresight_platform_data *of_get_coresight_platform_data(
|
||||
struct device *dev, struct device_node *node) { return NULL; }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -307,18 +307,6 @@ struct freq_attr {
|
||||
static struct freq_attr _name = \
|
||||
__ATTR(_name, 0444, show_##_name, NULL)
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
void cpufreq_suspend(void);
|
||||
void cpufreq_resume(void);
|
||||
#else
|
||||
static inline void cpufreq_suspend(void) {}
|
||||
static inline void cpufreq_resume(void) {}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* CPUFREQ NOTIFIER INTERFACE *
|
||||
*********************************************************************/
|
||||
|
||||
#define cpufreq_freq_attr_ro_perm(_name, _perm) \
|
||||
static struct freq_attr _name = \
|
||||
__ATTR(_name, _perm, show_##_name, NULL)
|
||||
|
||||
Reference in New Issue
Block a user