b058a11e39e81ee510175ae66bada18d79f5c5dc
[linux-2.6.git] / drivers / video / tegra / host / nvhost_acm.c
1 /*
2  * drivers/video/tegra/host/nvhost_acm.c
3  *
4  * Tegra Graphics Host Automatic Clock Management
5  *
6  * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <linux/slab.h>
22 #include <linux/stat.h>
23 #include <linux/string.h>
24 #include <linux/sched.h>
25 #include <linux/err.h>
26 #include <linux/device.h>
27 #include <linux/delay.h>
28 #include <linux/platform_device.h>
29 #include <linux/pm.h>
30 #include <linux/pm_runtime.h>
31 #include <trace/events/nvhost.h>
32
33 #include <mach/powergate.h>
34 #include <mach/clk.h>
35 #include <mach/hardware.h>
36 #include <mach/mc.h>
37
38 #include "nvhost_acm.h"
39 #include "dev.h"
40
41 #define ACM_SUSPEND_WAIT_FOR_IDLE_TIMEOUT       (2 * HZ)
42 #define POWERGATE_DELAY                         10
43 #define MAX_DEVID_LENGTH                        16
44
45 DEFINE_MUTEX(client_list_lock);
46
47 struct nvhost_module_client {
48         struct list_head node;
49         unsigned long rate[NVHOST_MODULE_MAX_CLOCKS];
50         void *priv;
51 };
52
53 static void do_powergate_locked(int id)
54 {
55         if (id != -1 && tegra_powergate_is_powered(id))
56                 tegra_powergate_partition(id);
57 }
58
59 static void do_unpowergate_locked(int id)
60 {
61         int ret = 0;
62         if (id != -1) {
63                 ret = tegra_unpowergate_partition(id);
64                 if (ret)
65                         pr_err("%s: unpowergate failed: id = %d\n",
66                                         __func__, id);
67         }
68 }
69
70 static void do_module_reset_locked(struct platform_device *dev)
71 {
72         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
73
74         /* assert module and mc client reset */
75         if (pdata->powergate_ids[0] != -1)
76                 tegra_powergate_mc_flush(pdata->powergate_ids[0]);
77         if (pdata->powergate_ids[0] != -1)
78                 tegra_powergate_mc_disable(pdata->powergate_ids[0]);
79         if (pdata->clocks[0].reset)
80                 tegra_periph_reset_assert(pdata->clk[0]);
81
82         if (pdata->powergate_ids[1] != -1)
83                 tegra_powergate_mc_flush(pdata->powergate_ids[1]);
84         if (pdata->powergate_ids[1] != -1)
85                 tegra_powergate_mc_disable(pdata->powergate_ids[1]);
86         if (pdata->clocks[1].reset)
87                 tegra_periph_reset_assert(pdata->clk[1]);
88
89         udelay(POWERGATE_DELAY);
90
91         /* deassert reset */
92         if (pdata->clocks[0].reset)
93                 tegra_periph_reset_deassert(pdata->clk[0]);
94         if (pdata->powergate_ids[0] != -1)
95                 tegra_powergate_mc_enable(pdata->powergate_ids[0]);
96         if (pdata->powergate_ids[0] != -1)
97                 tegra_powergate_mc_flush_done(pdata->powergate_ids[0]);
98
99         if (pdata->clocks[1].reset)
100                 tegra_periph_reset_deassert(pdata->clk[1]);
101         if (pdata->powergate_ids[1] != -1)
102                 tegra_powergate_mc_enable(pdata->powergate_ids[1]);
103         if (pdata->powergate_ids[1] != -1)
104                 tegra_powergate_mc_flush_done(pdata->powergate_ids[1]);
105 }
106
107 void nvhost_module_reset(struct platform_device *dev)
108 {
109         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
110
111         dev_dbg(&dev->dev,
112                 "%s: asserting %s module reset (id %d, id2 %d)\n",
113                 __func__, dev_name(&dev->dev),
114                 pdata->powergate_ids[0], pdata->powergate_ids[1]);
115
116         mutex_lock(&pdata->lock);
117         do_module_reset_locked(dev);
118         mutex_unlock(&pdata->lock);
119
120         if (pdata->finalize_poweron)
121                 pdata->finalize_poweron(dev);
122
123         dev_dbg(&dev->dev, "%s: module %s out of reset\n",
124                 __func__, dev_name(&dev->dev));
125 }
126
127 static void to_state_clockgated_locked(struct platform_device *dev)
128 {
129         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
130
131         if (pdata->powerstate == NVHOST_POWER_STATE_RUNNING) {
132                 int i, err;
133                 if (pdata->prepare_clockoff) {
134                         err = pdata->prepare_clockoff(dev);
135                         if (err) {
136                                 dev_err(&dev->dev, "error clock gating");
137                                 return;
138                         }
139                 }
140
141                 for (i = 0; i < pdata->num_clks; i++)
142                         clk_disable_unprepare(pdata->clk[i]);
143
144                 if (dev->dev.parent)
145                         nvhost_module_idle(to_platform_device(dev->dev.parent));
146
147                 if (!pdata->can_powergate) {
148                         pm_runtime_mark_last_busy(&dev->dev);
149                         pm_runtime_put_autosuspend(&dev->dev);
150                 }
151         } else if (pdata->powerstate == NVHOST_POWER_STATE_POWERGATED
152                         && pdata->can_powergate) {
153                 do_unpowergate_locked(pdata->powergate_ids[0]);
154                 do_unpowergate_locked(pdata->powergate_ids[1]);
155
156                 if (pdata->powerup_reset)
157                         do_module_reset_locked(dev);
158         }
159         pdata->powerstate = NVHOST_POWER_STATE_CLOCKGATED;
160 }
161
162 static void to_state_running_locked(struct platform_device *dev)
163 {
164         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
165         int prev_state = pdata->powerstate;
166
167         if (pdata->powerstate == NVHOST_POWER_STATE_POWERGATED) {
168                 pm_runtime_get_sync(&dev->dev);
169                 to_state_clockgated_locked(dev);
170         }
171
172         if (pdata->powerstate == NVHOST_POWER_STATE_CLOCKGATED) {
173                 int i;
174
175                 if (!pdata->can_powergate)
176                         pm_runtime_get_sync(&dev->dev);
177
178                 if (dev->dev.parent)
179                         nvhost_module_busy(to_platform_device(dev->dev.parent));
180
181                 for (i = 0; i < pdata->num_clks; i++) {
182                         int err = clk_prepare_enable(pdata->clk[i]);
183                         if (err) {
184                                 dev_err(&dev->dev, "Cannot turn on clock %s",
185                                         pdata->clocks[i].name);
186                                 return;
187                         }
188                 }
189
190                 if (pdata->finalize_clockon)
191                         pdata->finalize_clockon(dev);
192
193                 /* Invoke callback after power un-gating. This is used for
194                  * restoring context. */
195                 if (prev_state == NVHOST_POWER_STATE_POWERGATED
196                                 && pdata->finalize_poweron)
197                         pdata->finalize_poweron(dev);
198         }
199         pdata->powerstate = NVHOST_POWER_STATE_RUNNING;
200 }
201
202 /* This gets called from powergate_handler() and from module suspend.
203  * Module suspend is done for all modules, runtime power gating only
204  * for modules with can_powergate set.
205  */
206 static int to_state_powergated_locked(struct platform_device *dev)
207 {
208         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
209         int err = 0;
210
211         if (pdata->prepare_poweroff &&
212                 pdata->powerstate != NVHOST_POWER_STATE_POWERGATED) {
213                 /* Clock needs to be on in prepare_poweroff */
214                 to_state_running_locked(dev);
215                 err = pdata->prepare_poweroff(dev);
216                 if (err)
217                         return err;
218         }
219
220         if (pdata->powerstate == NVHOST_POWER_STATE_RUNNING)
221                 to_state_clockgated_locked(dev);
222
223         if (pdata->can_powergate) {
224                 do_powergate_locked(pdata->powergate_ids[0]);
225                 do_powergate_locked(pdata->powergate_ids[1]);
226         }
227
228         pdata->powerstate = NVHOST_POWER_STATE_POWERGATED;
229         pm_runtime_mark_last_busy(&dev->dev);
230         pm_runtime_put_autosuspend(&dev->dev);
231         return 0;
232 }
233
234 static void schedule_powergating_locked(struct platform_device *dev)
235 {
236         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
237         if (pdata->can_powergate)
238                 schedule_delayed_work(&pdata->powerstate_down,
239                                 msecs_to_jiffies(pdata->powergate_delay));
240 }
241
242 static void schedule_clockgating_locked(struct platform_device *dev)
243 {
244         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
245         schedule_delayed_work(&pdata->powerstate_down,
246                         msecs_to_jiffies(pdata->clockgate_delay));
247 }
248
249 void nvhost_module_busy(struct platform_device *dev)
250 {
251         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
252
253         if (pdata->busy)
254                 pdata->busy(dev);
255
256         mutex_lock(&pdata->lock);
257         cancel_delayed_work(&pdata->powerstate_down);
258
259         pdata->refcount++;
260         if (pdata->refcount > 0 && !nvhost_module_powered(dev))
261                 to_state_running_locked(dev);
262         mutex_unlock(&pdata->lock);
263 }
264
265 static void powerstate_down_handler(struct work_struct *work)
266 {
267         struct platform_device *dev;
268         struct nvhost_device_data *pdata;
269
270         pdata = container_of(to_delayed_work(work),
271                         struct nvhost_device_data,
272                         powerstate_down);
273
274         dev = pdata->pdev;
275
276         mutex_lock(&pdata->lock);
277         if (pdata->refcount == 0) {
278                 switch (pdata->powerstate) {
279                 case NVHOST_POWER_STATE_RUNNING:
280                         to_state_clockgated_locked(dev);
281                         schedule_powergating_locked(dev);
282                         break;
283                 case NVHOST_POWER_STATE_CLOCKGATED:
284                         if (to_state_powergated_locked(dev))
285                                 schedule_powergating_locked(dev);
286                         break;
287                 default:
288                         break;
289                 }
290         }
291         mutex_unlock(&pdata->lock);
292 }
293
294 void nvhost_module_idle_mult(struct platform_device *dev, int refs)
295 {
296         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
297         bool kick = false;
298
299         mutex_lock(&pdata->lock);
300
301         pdata->refcount -= refs;
302
303         /* submits on the fly -> exit */
304         if (pdata->refcount)
305                 goto out;
306
307         if (pdata->idle) {
308                 /* give a reference for idle(). otherwise the dev can be
309                  * clockgated */
310                 pdata->refcount++;
311                 mutex_unlock(&pdata->lock);
312                 pdata->idle(dev);
313                 mutex_lock(&pdata->lock);
314                 pdata->refcount--;
315         }
316
317         /* check that we don't have any new submits on the channel */
318         if (pdata->refcount)
319                 goto out;
320
321         /* no new submits. just schedule clock gating */
322         kick = true;
323         if (nvhost_module_powered(dev))
324                 schedule_clockgating_locked(dev);
325
326 out:
327         mutex_unlock(&pdata->lock);
328
329         /* wake up a waiting thread if we actually went to idle state */
330         if (kick)
331                 wake_up(&pdata->idle_wq);
332
333 }
334
335 int nvhost_module_get_rate(struct platform_device *dev, unsigned long *rate,
336                 int index)
337 {
338         struct clk *c;
339         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
340
341         c = pdata->clk[index];
342         if (IS_ERR_OR_NULL(c))
343                 return -EINVAL;
344
345         /* Need to enable client to get correct rate */
346         nvhost_module_busy(dev);
347         *rate = clk_get_rate(c);
348         nvhost_module_idle(dev);
349         return 0;
350
351 }
352
353 static int nvhost_module_update_rate(struct platform_device *dev, int index)
354 {
355         unsigned long rate = 0;
356         struct nvhost_module_client *m;
357         unsigned long devfreq_rate, default_rate;
358         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
359         int ret;
360
361         if (!pdata->clk[index])
362                 return -EINVAL;
363
364         /* If devfreq is on, use that clock rate, otherwise default */
365         devfreq_rate = pdata->clocks[index].devfreq_rate;
366         default_rate = devfreq_rate ?
367                 devfreq_rate : pdata->clocks[index].default_rate;
368         default_rate = clk_round_rate(pdata->clk[index], default_rate);
369
370         list_for_each_entry(m, &pdata->client_list, node) {
371                 unsigned long r = m->rate[index];
372                 if (!r)
373                         r = default_rate;
374                 rate = max(r, rate);
375         }
376         if (!rate)
377                 rate = default_rate;
378
379         trace_nvhost_module_update_rate(dev->name,
380                         pdata->clocks[index].name, rate);
381
382         ret = clk_set_rate(pdata->clk[index], rate);
383
384         if (pdata->update_clk)
385                 pdata->update_clk(dev);
386
387         return ret;
388
389 }
390
391 int nvhost_module_set_rate(struct platform_device *dev, void *priv,
392                 unsigned long rate, int index, int bBW)
393 {
394         struct nvhost_module_client *m;
395         int ret = 0;
396         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
397
398         mutex_lock(&client_list_lock);
399         list_for_each_entry(m, &pdata->client_list, node) {
400                 if (m->priv == priv) {
401                         if (bBW) {
402                                 /*
403                                  * If client sets BW, then we need to
404                                  * convert it to freq.
405                                  * rate is Bps and input param of
406                                  * tegra_emc_bw_to_freq_req is KBps.
407                                  */
408                                 unsigned int freq_khz =
409                                 tegra_emc_bw_to_freq_req
410                                         ((unsigned long)(rate >> 10));
411
412                                 m->rate[index] =
413                                         clk_round_rate(pdata->clk[index],
414                                         (unsigned long)(freq_khz << 10));
415                         } else
416                                 m->rate[index] =
417                                         clk_round_rate(pdata->clk[index], rate);
418                 }
419         }
420
421         ret = nvhost_module_update_rate(dev, index);
422         mutex_unlock(&client_list_lock);
423         return ret;
424
425 }
426
427 int nvhost_module_add_client(struct platform_device *dev, void *priv)
428 {
429         struct nvhost_module_client *client;
430         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
431
432         client = kzalloc(sizeof(*client), GFP_KERNEL);
433         if (!client)
434                 return -ENOMEM;
435
436         INIT_LIST_HEAD(&client->node);
437         client->priv = priv;
438
439         mutex_lock(&client_list_lock);
440         list_add_tail(&client->node, &pdata->client_list);
441         mutex_unlock(&client_list_lock);
442
443         return 0;
444 }
445
446 void nvhost_module_remove_client(struct platform_device *dev, void *priv)
447 {
448         int i;
449         struct nvhost_module_client *m;
450         int found = 0;
451         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
452
453         mutex_lock(&client_list_lock);
454         list_for_each_entry(m, &pdata->client_list, node) {
455                 if (priv == m->priv) {
456                         list_del(&m->node);
457                         found = 1;
458                         break;
459                 }
460         }
461         if (found) {
462                 kfree(m);
463                 for (i = 0; i < pdata->num_clks; i++)
464                         nvhost_module_update_rate(dev, i);
465         }
466         mutex_unlock(&client_list_lock);
467 }
468
469 static ssize_t refcount_show(struct kobject *kobj,
470         struct kobj_attribute *attr, char *buf)
471 {
472         int ret;
473         struct nvhost_device_power_attr *power_attribute =
474                 container_of(attr, struct nvhost_device_power_attr, \
475                         power_attr[NVHOST_POWER_SYSFS_ATTRIB_REFCOUNT]);
476         struct platform_device *dev = power_attribute->ndev;
477         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
478
479         mutex_lock(&pdata->lock);
480         ret = sprintf(buf, "%d\n", pdata->refcount);
481         mutex_unlock(&pdata->lock);
482
483         return ret;
484 }
485
486 static ssize_t powergate_delay_store(struct kobject *kobj,
487         struct kobj_attribute *attr, const char *buf, size_t count)
488 {
489         int powergate_delay = 0, ret = 0;
490         struct nvhost_device_power_attr *power_attribute =
491                 container_of(attr, struct nvhost_device_power_attr, \
492                         power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY]);
493         struct platform_device *dev = power_attribute->ndev;
494         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
495
496         if (!pdata->can_powergate) {
497                 dev_info(&dev->dev, "does not support power-gating\n");
498                 return count;
499         }
500
501         mutex_lock(&pdata->lock);
502         ret = sscanf(buf, "%d", &powergate_delay);
503         if (ret == 1 && powergate_delay >= 0)
504                 pdata->powergate_delay = powergate_delay;
505         else
506                 dev_err(&dev->dev, "Invalid powergate delay\n");
507         mutex_unlock(&pdata->lock);
508
509         return count;
510 }
511
512 static ssize_t powergate_delay_show(struct kobject *kobj,
513         struct kobj_attribute *attr, char *buf)
514 {
515         int ret;
516         struct nvhost_device_power_attr *power_attribute =
517                 container_of(attr, struct nvhost_device_power_attr, \
518                         power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY]);
519         struct platform_device *dev = power_attribute->ndev;
520         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
521
522         mutex_lock(&pdata->lock);
523         ret = sprintf(buf, "%d\n", pdata->powergate_delay);
524         mutex_unlock(&pdata->lock);
525
526         return ret;
527 }
528
529 static ssize_t clockgate_delay_store(struct kobject *kobj,
530         struct kobj_attribute *attr, const char *buf, size_t count)
531 {
532         int clockgate_delay = 0, ret = 0;
533         struct nvhost_device_power_attr *power_attribute =
534                 container_of(attr, struct nvhost_device_power_attr, \
535                         power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY]);
536         struct platform_device *dev = power_attribute->ndev;
537         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
538
539         mutex_lock(&pdata->lock);
540         ret = sscanf(buf, "%d", &clockgate_delay);
541         if (ret == 1 && clockgate_delay >= 0)
542                 pdata->clockgate_delay = clockgate_delay;
543         else
544                 dev_err(&dev->dev, "Invalid clockgate delay\n");
545         mutex_unlock(&pdata->lock);
546
547         return count;
548 }
549
550 static ssize_t clockgate_delay_show(struct kobject *kobj,
551         struct kobj_attribute *attr, char *buf)
552 {
553         int ret;
554         struct nvhost_device_power_attr *power_attribute =
555                 container_of(attr, struct nvhost_device_power_attr, \
556                         power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY]);
557         struct platform_device *dev = power_attribute->ndev;
558         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
559
560         mutex_lock(&pdata->lock);
561         ret = sprintf(buf, "%d\n", pdata->clockgate_delay);
562         mutex_unlock(&pdata->lock);
563
564         return ret;
565 }
566
567 int nvhost_module_set_devfreq_rate(struct platform_device *dev, int index,
568                 unsigned long rate)
569 {
570         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
571
572         rate = clk_round_rate(pdata->clk[index], rate);
573         pdata->clocks[index].devfreq_rate = rate;
574
575         trace_nvhost_module_set_devfreq_rate(dev->name,
576                         pdata->clocks[index].name, rate);
577
578         return nvhost_module_update_rate(dev, index);
579 }
580
581 int nvhost_module_init(struct platform_device *dev)
582 {
583         int i = 0, err = 0;
584         struct kobj_attribute *attr = NULL;
585         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
586
587         /* initialize clocks to known state */
588         INIT_LIST_HEAD(&pdata->client_list);
589         while (pdata->clocks[i].name && i < NVHOST_MODULE_MAX_CLOCKS) {
590                 char devname[MAX_DEVID_LENGTH];
591                 long rate = pdata->clocks[i].default_rate;
592                 struct clk *c;
593
594                 snprintf(devname, MAX_DEVID_LENGTH, "tegra_%s",
595                         dev_name(&dev->dev));
596                 c = clk_get_sys(devname, pdata->clocks[i].name);
597                 if (IS_ERR_OR_NULL(c)) {
598                         dev_err(&dev->dev, "Cannot get clock %s\n",
599                                         pdata->clocks[i].name);
600                         continue;
601                 }
602
603                 rate = clk_round_rate(c, rate);
604                 clk_prepare_enable(c);
605                 clk_set_rate(c, rate);
606                 clk_disable_unprepare(c);
607                 pdata->clk[i] = c;
608                 i++;
609         }
610         pdata->num_clks = i;
611
612         mutex_init(&pdata->lock);
613         init_waitqueue_head(&pdata->idle_wq);
614         INIT_DELAYED_WORK(&pdata->powerstate_down, powerstate_down_handler);
615
616         /* reset the module */
617         do_module_reset_locked(dev);
618
619         /* power gate units that we can power gate */
620         if (pdata->can_powergate) {
621                 do_powergate_locked(pdata->powergate_ids[0]);
622                 do_powergate_locked(pdata->powergate_ids[1]);
623                 pdata->powerstate = NVHOST_POWER_STATE_POWERGATED;
624         } else {
625                 do_unpowergate_locked(pdata->powergate_ids[0]);
626                 do_unpowergate_locked(pdata->powergate_ids[1]);
627                 pdata->powerstate = NVHOST_POWER_STATE_CLOCKGATED;
628         }
629
630         /* Init the power sysfs attributes for this device */
631         pdata->power_attrib = kzalloc(sizeof(struct nvhost_device_power_attr),
632                 GFP_KERNEL);
633         if (!pdata->power_attrib) {
634                 dev_err(&dev->dev, "Unable to allocate sysfs attributes\n");
635                 return -ENOMEM;
636         }
637         pdata->power_attrib->ndev = dev;
638
639         pdata->power_kobj = kobject_create_and_add("acm", &dev->dev.kobj);
640         if (!pdata->power_kobj) {
641                 dev_err(&dev->dev, "Could not add dir 'power'\n");
642                 err = -EIO;
643                 goto fail_attrib_alloc;
644         }
645
646         attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY];
647         attr->attr.name = "clockgate_delay";
648         attr->attr.mode = S_IWUSR | S_IRUGO;
649         attr->show = clockgate_delay_show;
650         attr->store = clockgate_delay_store;
651 #ifdef CONFIG_DEBUG_LOCK_ALLOC
652         sysfs_attr_init(&attr->attr);
653 #endif
654         if (sysfs_create_file(pdata->power_kobj, &attr->attr)) {
655                 dev_err(&dev->dev, "Could not create sysfs attribute clockgate_delay\n");
656                 err = -EIO;
657                 goto fail_clockdelay;
658         }
659
660         attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY];
661         attr->attr.name = "powergate_delay";
662         attr->attr.mode = S_IWUSR | S_IRUGO;
663         attr->show = powergate_delay_show;
664         attr->store = powergate_delay_store;
665 #ifdef CONFIG_DEBUG_LOCK_ALLOC
666         sysfs_attr_init(&attr->attr);
667 #endif
668         if (sysfs_create_file(pdata->power_kobj, &attr->attr)) {
669                 dev_err(&dev->dev, "Could not create sysfs attribute powergate_delay\n");
670                 err = -EIO;
671                 goto fail_powergatedelay;
672         }
673
674         attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_REFCOUNT];
675         attr->attr.name = "refcount";
676         attr->attr.mode = S_IRUGO;
677         attr->show = refcount_show;
678 #ifdef CONFIG_DEBUG_LOCK_ALLOC
679         sysfs_attr_init(&attr->attr);
680 #endif
681         if (sysfs_create_file(pdata->power_kobj, &attr->attr)) {
682                 dev_err(&dev->dev, "Could not create sysfs attribute refcount\n");
683                 err = -EIO;
684                 goto fail_refcount;
685         }
686
687         return 0;
688
689 fail_refcount:
690         attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY];
691         sysfs_remove_file(pdata->power_kobj, &attr->attr);
692
693 fail_powergatedelay:
694         attr = &pdata->power_attrib->power_attr[NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY];
695         sysfs_remove_file(pdata->power_kobj, &attr->attr);
696
697 fail_clockdelay:
698         kobject_put(pdata->power_kobj);
699
700 fail_attrib_alloc:
701         kfree(pdata->power_attrib);
702
703         return err;
704 }
705
706 static int is_module_idle(struct platform_device *dev)
707 {
708         int count;
709         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
710
711         mutex_lock(&pdata->lock);
712         count = pdata->refcount;
713         mutex_unlock(&pdata->lock);
714
715         return (count == 0);
716 }
717
718 int nvhost_module_suspend(struct platform_device *dev)
719 {
720         int ret;
721         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
722
723         ret = wait_event_timeout(pdata->idle_wq, is_module_idle(dev),
724                         ACM_SUSPEND_WAIT_FOR_IDLE_TIMEOUT);
725         if (ret == 0) {
726                 dev_info(&dev->dev, "%s prevented suspend\n",
727                                 dev_name(&dev->dev));
728                 return -EBUSY;
729         }
730
731         mutex_lock(&pdata->lock);
732         cancel_delayed_work(&pdata->powerstate_down);
733         to_state_powergated_locked(dev);
734         mutex_unlock(&pdata->lock);
735
736         if (pdata->suspend_ndev)
737                 pdata->suspend_ndev(dev);
738
739         return 0;
740 }
741
742 void nvhost_module_deinit(struct platform_device *dev)
743 {
744         int i;
745         struct nvhost_device_data *pdata = platform_get_drvdata(dev);
746
747         nvhost_module_suspend(dev);
748         for (i = 0; i < pdata->num_clks; i++)
749                 clk_put(pdata->clk[i]);
750         pdata->powerstate = NVHOST_POWER_STATE_DEINIT;
751 }
752
753 /* public host1x power management APIs */
754 bool nvhost_module_powered_ext(struct platform_device *dev)
755 {
756         struct platform_device *pdev;
757
758         BUG_ON(!dev->dev.parent);
759
760         /* get the parent */
761         pdev = to_platform_device(dev->dev.parent);
762
763         return nvhost_module_powered(pdev);
764 }
765
766 void nvhost_module_busy_ext(struct platform_device *dev)
767 {
768         struct platform_device *pdev;
769
770         BUG_ON(!dev->dev.parent);
771
772         /* get the parent */
773         pdev = to_platform_device(dev->dev.parent);
774
775         nvhost_module_busy(pdev);
776 }
777
778 void nvhost_module_idle_ext(struct platform_device *dev)
779 {
780         struct platform_device *pdev;
781
782         BUG_ON(!dev->dev.parent);
783
784         /* get the parent */
785         pdev = to_platform_device(dev->dev.parent);
786
787         nvhost_module_idle(pdev);
788 }