diff options
Diffstat (limited to 'arch/arm/mach-omap2/opp.c')
-rw-r--r-- | arch/arm/mach-omap2/opp.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c new file mode 100644 index 000000000000..ab8b35b780b5 --- /dev/null +++ b/arch/arm/mach-omap2/opp.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * OMAP SoC specific OPP wrapper function | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * Nishanth Menon | ||
6 | * Kevin Hilman | ||
7 | * Copyright (C) 2010 Nokia Corporation. | ||
8 | * Eduardo Valentin | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
15 | * kind, whether express or implied; without even the implied warranty | ||
16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/opp.h> | ||
21 | |||
22 | #include <plat/omap_device.h> | ||
23 | |||
24 | #include "omap_opp_data.h" | ||
25 | |||
26 | /* Temp variable to allow multiple calls */ | ||
27 | static u8 __initdata omap_table_init; | ||
28 | |||
29 | /** | ||
30 | * omap_init_opp_table() - Initialize opp table as per the CPU type | ||
31 | * @opp_def: opp default list for this silicon | ||
32 | * @opp_def_size: number of opp entries for this silicon | ||
33 | * | ||
34 | * Register the initial OPP table with the OPP library based on the CPU | ||
35 | * type. This is meant to be used only by SoC specific registration. | ||
36 | */ | ||
37 | int __init omap_init_opp_table(struct omap_opp_def *opp_def, | ||
38 | u32 opp_def_size) | ||
39 | { | ||
40 | int i, r; | ||
41 | |||
42 | if (!opp_def || !opp_def_size) { | ||
43 | pr_err("%s: invalid params!\n", __func__); | ||
44 | return -EINVAL; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Initialize only if not already initialized even if the previous | ||
49 | * call failed, because, no reason we'd succeed again. | ||
50 | */ | ||
51 | if (omap_table_init) | ||
52 | return -EEXIST; | ||
53 | omap_table_init = 1; | ||
54 | |||
55 | /* Lets now register with OPP library */ | ||
56 | for (i = 0; i < opp_def_size; i++) { | ||
57 | struct omap_hwmod *oh; | ||
58 | struct device *dev; | ||
59 | |||
60 | if (!opp_def->hwmod_name) { | ||
61 | pr_err("%s: NULL name of omap_hwmod, failing [%d].\n", | ||
62 | __func__, i); | ||
63 | return -EINVAL; | ||
64 | } | ||
65 | oh = omap_hwmod_lookup(opp_def->hwmod_name); | ||
66 | if (!oh || !oh->od) { | ||
67 | pr_warn("%s: no hwmod or odev for %s, [%d] " | ||
68 | "cannot add OPPs.\n", __func__, | ||
69 | opp_def->hwmod_name, i); | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | dev = &oh->od->pdev.dev; | ||
73 | |||
74 | r = opp_add(dev, opp_def->freq, opp_def->u_volt); | ||
75 | if (r) { | ||
76 | dev_err(dev, "%s: add OPP %ld failed for %s [%d] " | ||
77 | "result=%d\n", | ||
78 | __func__, opp_def->freq, | ||
79 | opp_def->hwmod_name, i, r); | ||
80 | } else { | ||
81 | if (!opp_def->default_available) | ||
82 | r = opp_disable(dev, opp_def->freq); | ||
83 | if (r) | ||
84 | dev_err(dev, "%s: disable %ld failed for %s " | ||
85 | "[%d] result=%d\n", | ||
86 | __func__, opp_def->freq, | ||
87 | opp_def->hwmod_name, i, r); | ||
88 | } | ||
89 | opp_def++; | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||