| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * OMAP2/3/4 clockdomain framework functions |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Written by Paul Walmsley and Jouni Högander |
|---|
| 8 | 9 | * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com> |
|---|
| 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 | 10 | */ |
|---|
| 14 | 11 | #undef DEBUG |
|---|
| 15 | 12 | |
|---|
| .. | .. |
|---|
| 1150 | 1147 | |
|---|
| 1151 | 1148 | /* Clockdomain-to-clock/hwmod framework interface code */ |
|---|
| 1152 | 1149 | |
|---|
| 1153 | | -static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) |
|---|
| 1150 | +/** |
|---|
| 1151 | + * clkdm_clk_enable - add an enabled downstream clock to this clkdm |
|---|
| 1152 | + * @clkdm: struct clockdomain * |
|---|
| 1153 | + * @clk: struct clk * of the enabled downstream clock |
|---|
| 1154 | + * |
|---|
| 1155 | + * Increment the usecount of the clockdomain @clkdm and ensure that it |
|---|
| 1156 | + * is awake before @clk is enabled. Intended to be called by |
|---|
| 1157 | + * clk_enable() code. If the clockdomain is in software-supervised |
|---|
| 1158 | + * idle mode, force the clockdomain to wake. If the clockdomain is in |
|---|
| 1159 | + * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to |
|---|
| 1160 | + * ensure that devices in the clockdomain can be read from/written to |
|---|
| 1161 | + * by on-chip processors. Returns -EINVAL if passed null pointers; |
|---|
| 1162 | + * returns 0 upon success or if the clockdomain is in hwsup idle mode. |
|---|
| 1163 | + */ |
|---|
| 1164 | +int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *unused) |
|---|
| 1154 | 1165 | { |
|---|
| 1155 | 1166 | if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable) |
|---|
| 1156 | 1167 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 1178 | 1189 | } |
|---|
| 1179 | 1190 | |
|---|
| 1180 | 1191 | /** |
|---|
| 1181 | | - * clkdm_clk_enable - add an enabled downstream clock to this clkdm |
|---|
| 1182 | | - * @clkdm: struct clockdomain * |
|---|
| 1183 | | - * @clk: struct clk * of the enabled downstream clock |
|---|
| 1184 | | - * |
|---|
| 1185 | | - * Increment the usecount of the clockdomain @clkdm and ensure that it |
|---|
| 1186 | | - * is awake before @clk is enabled. Intended to be called by |
|---|
| 1187 | | - * clk_enable() code. If the clockdomain is in software-supervised |
|---|
| 1188 | | - * idle mode, force the clockdomain to wake. If the clockdomain is in |
|---|
| 1189 | | - * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to |
|---|
| 1190 | | - * ensure that devices in the clockdomain can be read from/written to |
|---|
| 1191 | | - * by on-chip processors. Returns -EINVAL if passed null pointers; |
|---|
| 1192 | | - * returns 0 upon success or if the clockdomain is in hwsup idle mode. |
|---|
| 1193 | | - */ |
|---|
| 1194 | | -int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) |
|---|
| 1195 | | -{ |
|---|
| 1196 | | - /* |
|---|
| 1197 | | - * XXX Rewrite this code to maintain a list of enabled |
|---|
| 1198 | | - * downstream clocks for debugging purposes? |
|---|
| 1199 | | - */ |
|---|
| 1200 | | - |
|---|
| 1201 | | - if (!clk) |
|---|
| 1202 | | - return -EINVAL; |
|---|
| 1203 | | - |
|---|
| 1204 | | - return _clkdm_clk_hwmod_enable(clkdm); |
|---|
| 1205 | | -} |
|---|
| 1206 | | - |
|---|
| 1207 | | -/** |
|---|
| 1208 | 1192 | * clkdm_clk_disable - remove an enabled downstream clock from this clkdm |
|---|
| 1209 | 1193 | * @clkdm: struct clockdomain * |
|---|
| 1210 | 1194 | * @clk: struct clk * of the disabled downstream clock |
|---|
| .. | .. |
|---|
| 1219 | 1203 | */ |
|---|
| 1220 | 1204 | int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) |
|---|
| 1221 | 1205 | { |
|---|
| 1222 | | - if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) |
|---|
| 1206 | + if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) |
|---|
| 1223 | 1207 | return -EINVAL; |
|---|
| 1224 | 1208 | |
|---|
| 1225 | 1209 | pwrdm_lock(clkdm->pwrdm.ptr); |
|---|
| 1226 | 1210 | |
|---|
| 1227 | 1211 | /* corner case: disabling unused clocks */ |
|---|
| 1228 | | - if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0) |
|---|
| 1212 | + if (clk && (__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0) |
|---|
| 1229 | 1213 | goto ccd_exit; |
|---|
| 1230 | 1214 | |
|---|
| 1231 | 1215 | if (clkdm->usecount == 0) { |
|---|
| .. | .. |
|---|
| 1280 | 1264 | if (!oh) |
|---|
| 1281 | 1265 | return -EINVAL; |
|---|
| 1282 | 1266 | |
|---|
| 1283 | | - return _clkdm_clk_hwmod_enable(clkdm); |
|---|
| 1267 | + return clkdm_clk_enable(clkdm, NULL); |
|---|
| 1284 | 1268 | } |
|---|
| 1285 | 1269 | |
|---|
| 1286 | 1270 | /** |
|---|
| .. | .. |
|---|
| 1303 | 1287 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) |
|---|
| 1304 | 1288 | return 0; |
|---|
| 1305 | 1289 | |
|---|
| 1306 | | - /* |
|---|
| 1307 | | - * XXX Rewrite this code to maintain a list of enabled |
|---|
| 1308 | | - * downstream hwmods for debugging purposes? |
|---|
| 1309 | | - */ |
|---|
| 1310 | | - |
|---|
| 1311 | | - if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable) |
|---|
| 1290 | + if (!oh) |
|---|
| 1312 | 1291 | return -EINVAL; |
|---|
| 1313 | 1292 | |
|---|
| 1314 | | - pwrdm_lock(clkdm->pwrdm.ptr); |
|---|
| 1315 | | - |
|---|
| 1316 | | - if (clkdm->usecount == 0) { |
|---|
| 1317 | | - pwrdm_unlock(clkdm->pwrdm.ptr); |
|---|
| 1318 | | - WARN_ON(1); /* underflow */ |
|---|
| 1319 | | - return -ERANGE; |
|---|
| 1320 | | - } |
|---|
| 1321 | | - |
|---|
| 1322 | | - clkdm->usecount--; |
|---|
| 1323 | | - if (clkdm->usecount > 0) { |
|---|
| 1324 | | - pwrdm_unlock(clkdm->pwrdm.ptr); |
|---|
| 1325 | | - return 0; |
|---|
| 1326 | | - } |
|---|
| 1327 | | - |
|---|
| 1328 | | - arch_clkdm->clkdm_clk_disable(clkdm); |
|---|
| 1329 | | - pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); |
|---|
| 1330 | | - pwrdm_unlock(clkdm->pwrdm.ptr); |
|---|
| 1331 | | - |
|---|
| 1332 | | - pr_debug("clockdomain: %s: disabled\n", clkdm->name); |
|---|
| 1333 | | - |
|---|
| 1334 | | - return 0; |
|---|
| 1293 | + return clkdm_clk_disable(clkdm, NULL); |
|---|
| 1335 | 1294 | } |
|---|
| 1336 | 1295 | |
|---|
| 1337 | 1296 | /** |
|---|