diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/dvfs/0012-OMAP-Introduce-device-scale.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap/dvfs/0012-OMAP-Introduce-device-scale.patch | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/dvfs/0012-OMAP-Introduce-device-scale.patch b/extras/recipes-kernel/linux/linux-omap/dvfs/0012-OMAP-Introduce-device-scale.patch new file mode 100644 index 00000000..a6d35bd6 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/dvfs/0012-OMAP-Introduce-device-scale.patch | |||
@@ -0,0 +1,134 @@ | |||
1 | From b461bd17384c73bbb243c54bf1d6466c94e594c3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Thara Gopinath <thara@ti.com> | ||
3 | Date: Fri, 2 Jul 2010 13:07:35 +0530 | ||
4 | Subject: [PATCH 12/20] OMAP: Introduce device scale | ||
5 | |||
6 | This patch adds omap_device_scale API which can be used to generic | ||
7 | device rate scaling. | ||
8 | |||
9 | Signed-off-by: Thara Gopinath <thara@ti.com> | ||
10 | --- | ||
11 | arch/arm/plat-omap/include/plat/omap_device.h | 3 +- | ||
12 | arch/arm/plat-omap/omap_device.c | 78 +++++++++++++++++++++++++ | ||
13 | 2 files changed, 80 insertions(+), 1 deletions(-) | ||
14 | |||
15 | diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h | ||
16 | index 1178b86..e44a0f7 100644 | ||
17 | --- a/arch/arm/plat-omap/include/plat/omap_device.h | ||
18 | +++ b/arch/arm/plat-omap/include/plat/omap_device.h | ||
19 | @@ -117,6 +117,8 @@ unsigned long omap_device_get_rate(struct device *dev); | ||
20 | void omap_device_populate_rate_fns(struct device *dev, | ||
21 | int (*set_rate)(struct device *dev, unsigned long rate), | ||
22 | unsigned long (*get_rate) (struct device *dev)); | ||
23 | +int omap_device_scale(struct device *req_dev, struct device *dev, | ||
24 | + unsigned long rate); | ||
25 | |||
26 | /* Other */ | ||
27 | |||
28 | @@ -126,7 +128,6 @@ int omap_device_enable_hwmods(struct omap_device *od); | ||
29 | int omap_device_disable_clocks(struct omap_device *od); | ||
30 | int omap_device_enable_clocks(struct omap_device *od); | ||
31 | |||
32 | - | ||
33 | /* | ||
34 | * Entries should be kept in latency order ascending | ||
35 | * | ||
36 | diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c | ||
37 | index 0d67af6..458d648 100644 | ||
38 | --- a/arch/arm/plat-omap/omap_device.c | ||
39 | +++ b/arch/arm/plat-omap/omap_device.c | ||
40 | @@ -83,6 +83,7 @@ | ||
41 | #include <linux/err.h> | ||
42 | #include <linux/io.h> | ||
43 | #include <linux/clk.h> | ||
44 | +#include <linux/opp.h> | ||
45 | |||
46 | #include <plat/omap_device.h> | ||
47 | #include <plat/omap_hwmod.h> | ||
48 | @@ -862,6 +863,83 @@ void omap_device_populate_rate_fns(struct device *dev, | ||
49 | od->get_rate = get_rate; | ||
50 | } | ||
51 | |||
52 | +/** | ||
53 | + * omap_device_scale() - Set a new rate at which the device is to operate | ||
54 | + * @req_dev: pointer to the device requesting the scaling. | ||
55 | + * @dev: pointer to the device that is to be scaled | ||
56 | + * @rate: the rnew rate for the device. | ||
57 | + * | ||
58 | + * This API gets the device opp table associated with this device and | ||
59 | + * tries putting the device to the requested rate and the voltage domain | ||
60 | + * associated with the device to the voltage corresponding to the | ||
61 | + * requested rate. Since multiple devices can be assocciated with a | ||
62 | + * voltage domain this API finds out the possible voltage the | ||
63 | + * voltage domain can enter and then decides on the final device | ||
64 | + * rate. Return 0 on success else the error value | ||
65 | + */ | ||
66 | +int omap_device_scale(struct device *req_dev, struct device *dev, | ||
67 | + unsigned long rate) | ||
68 | +{ | ||
69 | + struct opp *opp; | ||
70 | + unsigned long volt, freq, min_freq, max_freq; | ||
71 | + struct voltagedomain *voltdm; | ||
72 | + struct platform_device *pdev; | ||
73 | + struct omap_device *od; | ||
74 | + int ret; | ||
75 | + | ||
76 | + pdev = container_of(dev, struct platform_device, dev); | ||
77 | + od = _find_by_pdev(pdev); | ||
78 | + | ||
79 | + /* | ||
80 | + * Figure out if the desired frquency lies between the | ||
81 | + * maximum and minimum possible for the particular device | ||
82 | + */ | ||
83 | + min_freq = 0; | ||
84 | + if (IS_ERR(opp_find_freq_ceil(dev, &min_freq))) { | ||
85 | + dev_err(dev, "%s: Unable to find lowest opp\n", __func__); | ||
86 | + return -ENODEV; | ||
87 | + } | ||
88 | + | ||
89 | + max_freq = ULONG_MAX; | ||
90 | + if (IS_ERR(opp_find_freq_floor(dev, &max_freq))) { | ||
91 | + dev_err(dev, "%s: Unable to find highest opp\n", __func__); | ||
92 | + return -ENODEV; | ||
93 | + } | ||
94 | + | ||
95 | + if (rate < min_freq) | ||
96 | + freq = min_freq; | ||
97 | + else if (rate > max_freq) | ||
98 | + freq = max_freq; | ||
99 | + else | ||
100 | + freq = rate; | ||
101 | + | ||
102 | + opp = opp_find_freq_ceil(dev, &freq); | ||
103 | + if (IS_ERR(opp)) { | ||
104 | + dev_err(dev, "%s: Unable to find OPP for freq%ld\n", | ||
105 | + __func__, rate); | ||
106 | + return -ENODEV; | ||
107 | + } | ||
108 | + | ||
109 | + /* Get the voltage corresponding to the requested frequency */ | ||
110 | + volt = opp_get_voltage(opp); | ||
111 | + | ||
112 | + /* | ||
113 | + * Call into the voltage layer to get the final voltage possible | ||
114 | + * for the voltage domain associated with the device. | ||
115 | + */ | ||
116 | + voltdm = od->hwmods[0]->voltdm; | ||
117 | + ret = omap_voltage_add_request(voltdm, req_dev, &volt); | ||
118 | + if (ret) { | ||
119 | + dev_err(dev, "%s: Unable to get the final volt for scaling\n", | ||
120 | + __func__); | ||
121 | + return ret; | ||
122 | + } | ||
123 | + | ||
124 | + /* Do the actual scaling */ | ||
125 | + return omap_voltage_scale(voltdm, volt); | ||
126 | +} | ||
127 | +EXPORT_SYMBOL(omap_device_scale); | ||
128 | + | ||
129 | struct device omap_device_parent = { | ||
130 | .init_name = "omap", | ||
131 | .parent = &platform_bus, | ||
132 | -- | ||
133 | 1.6.6.1 | ||
134 | |||