1919#include <linux/dma-mapping.h>
2020#include <linux/interrupt.h>
2121#include <linux/clk.h>
22+ #include <linux/pm_runtime.h>
2223#include <linux/regmap.h>
2324#include <linux/reset.h>
2425#include <linux/soc/sunxi/sunxi_sram.h>
@@ -140,6 +141,64 @@ static irqreturn_t cedrus_irq(int irq, void *data)
140141 return IRQ_HANDLED ;
141142}
142143
144+ int cedrus_hw_suspend (struct device * device )
145+ {
146+ struct cedrus_dev * dev = dev_get_drvdata (device );
147+
148+ reset_control_assert (dev -> rstc );
149+
150+ clk_disable_unprepare (dev -> ram_clk );
151+ clk_disable_unprepare (dev -> mod_clk );
152+ clk_disable_unprepare (dev -> ahb_clk );
153+
154+ return 0 ;
155+ }
156+
157+ int cedrus_hw_resume (struct device * device )
158+ {
159+ struct cedrus_dev * dev = dev_get_drvdata (device );
160+ int ret ;
161+
162+ ret = clk_prepare_enable (dev -> ahb_clk );
163+ if (ret ) {
164+ dev_err (dev -> dev , "Failed to enable AHB clock\n" );
165+
166+ return ret ;
167+ }
168+
169+ ret = clk_prepare_enable (dev -> mod_clk );
170+ if (ret ) {
171+ dev_err (dev -> dev , "Failed to enable MOD clock\n" );
172+
173+ goto err_ahb_clk ;
174+ }
175+
176+ ret = clk_prepare_enable (dev -> ram_clk );
177+ if (ret ) {
178+ dev_err (dev -> dev , "Failed to enable RAM clock\n" );
179+
180+ goto err_mod_clk ;
181+ }
182+
183+ ret = reset_control_reset (dev -> rstc );
184+ if (ret ) {
185+ dev_err (dev -> dev , "Failed to apply reset\n" );
186+
187+ goto err_ram_clk ;
188+ }
189+
190+ return 0 ;
191+
192+ err_ram_clk :
193+ clk_disable_unprepare (dev -> ram_clk );
194+ err_mod_clk :
195+ clk_disable_unprepare (dev -> mod_clk );
196+ err_ahb_clk :
197+ clk_disable_unprepare (dev -> ahb_clk );
198+
199+ return ret ;
200+ }
201+
143202int cedrus_hw_probe (struct cedrus_dev * dev )
144203{
145204 const struct cedrus_variant * variant ;
@@ -236,42 +295,17 @@ int cedrus_hw_probe(struct cedrus_dev *dev)
236295 goto err_sram ;
237296 }
238297
239- ret = clk_prepare_enable (dev -> ahb_clk );
240- if (ret ) {
241- dev_err (dev -> dev , "Failed to enable AHB clock\n" );
242-
243- goto err_sram ;
244- }
245-
246- ret = clk_prepare_enable (dev -> mod_clk );
247- if (ret ) {
248- dev_err (dev -> dev , "Failed to enable MOD clock\n" );
249-
250- goto err_ahb_clk ;
251- }
252-
253- ret = clk_prepare_enable (dev -> ram_clk );
254- if (ret ) {
255- dev_err (dev -> dev , "Failed to enable RAM clock\n" );
256-
257- goto err_mod_clk ;
258- }
259-
260- ret = reset_control_reset (dev -> rstc );
261- if (ret ) {
262- dev_err (dev -> dev , "Failed to apply reset\n" );
263-
264- goto err_ram_clk ;
298+ pm_runtime_enable (dev -> dev );
299+ if (!pm_runtime_enabled (dev -> dev )) {
300+ ret = cedrus_hw_resume (dev -> dev );
301+ if (ret )
302+ goto err_pm ;
265303 }
266304
267305 return 0 ;
268306
269- err_ram_clk :
270- clk_disable_unprepare (dev -> ram_clk );
271- err_mod_clk :
272- clk_disable_unprepare (dev -> mod_clk );
273- err_ahb_clk :
274- clk_disable_unprepare (dev -> ahb_clk );
307+ err_pm :
308+ pm_runtime_disable (dev -> dev );
275309err_sram :
276310 sunxi_sram_release (dev -> dev );
277311err_mem :
@@ -282,11 +316,9 @@ int cedrus_hw_probe(struct cedrus_dev *dev)
282316
283317void cedrus_hw_remove (struct cedrus_dev * dev )
284318{
285- reset_control_assert (dev -> rstc );
286-
287- clk_disable_unprepare (dev -> ram_clk );
288- clk_disable_unprepare (dev -> mod_clk );
289- clk_disable_unprepare (dev -> ahb_clk );
319+ pm_runtime_disable (dev -> dev );
320+ if (!pm_runtime_status_suspended (dev -> dev ))
321+ cedrus_hw_suspend (dev -> dev );
290322
291323 sunxi_sram_release (dev -> dev );
292324
0 commit comments