blob: f9fc40c0f1a850bd0e7c1c4dd9a79a2c3670e0a6 [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2002,2007-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#ifndef __KGSL_DEVICE_H
14#define __KGSL_DEVICE_H
15
16#include <linux/idr.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070017#include <linux/pm_qos.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070018#include <linux/earlysuspend.h>
19
20#include "kgsl.h"
21#include "kgsl_mmu.h"
22#include "kgsl_pwrctrl.h"
23#include "kgsl_log.h"
24#include "kgsl_pwrscale.h"
Jeff Boodyfe6c39c2012-08-09 13:54:50 -060025#include <linux/sync.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070026
Tarun Karra696f89e2013-01-27 21:31:40 -080027#define KGSL_TIMEOUT_NONE 0
28#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF
29#define KGSL_TIMEOUT_PART 50 /* 50 msec */
30#define KGSL_TIMEOUT_LONG_IB_DETECTION 2000 /* 2 sec*/
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031
32#define FIRST_TIMEOUT (HZ / 2)
33
34
35/* KGSL device state is initialized to INIT when platform_probe *
36 * sucessfully initialized the device. Once a device has been opened *
37 * (started) it becomes active. NAP implies that only low latency *
38 * resources (for now clocks on some platforms) are off. SLEEP implies *
39 * that the KGSL module believes a device is idle (has been inactive *
40 * past its timer) and all system resources are released. SUSPEND is *
41 * requested by the kernel and will be enforced upon all open devices. */
42
43#define KGSL_STATE_NONE 0x00000000
44#define KGSL_STATE_INIT 0x00000001
45#define KGSL_STATE_ACTIVE 0x00000002
46#define KGSL_STATE_NAP 0x00000004
47#define KGSL_STATE_SLEEP 0x00000008
48#define KGSL_STATE_SUSPEND 0x00000010
49#define KGSL_STATE_HUNG 0x00000020
Tarun Karrad20d71a2013-01-25 15:38:57 -080050#define KGSL_STATE_DUMP_AND_FT 0x00000040
Suman Tatiraju24569022011-10-27 11:11:12 -070051#define KGSL_STATE_SLUMBER 0x00000080
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052
53#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000
54
55#define KGSL_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
56
57struct kgsl_device;
58struct platform_device;
59struct kgsl_device_private;
60struct kgsl_context;
61struct kgsl_power_stats;
Jordan Crouse313faf62012-11-20 15:12:28 -070062struct kgsl_event;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070063
64struct kgsl_functable {
65 /* Mandatory functions - these functions must be implemented
66 by the client device. The driver will not check for a NULL
67 pointer before calling the hook.
68 */
69 void (*regread) (struct kgsl_device *device,
70 unsigned int offsetwords, unsigned int *value);
71 void (*regwrite) (struct kgsl_device *device,
72 unsigned int offsetwords, unsigned int value);
Jordan Crousea29a2e02012-08-14 09:09:23 -060073 int (*idle) (struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070074 unsigned int (*isidle) (struct kgsl_device *device);
75 int (*suspend_context) (struct kgsl_device *device);
76 int (*start) (struct kgsl_device *device, unsigned int init_ram);
77 int (*stop) (struct kgsl_device *device);
78 int (*getproperty) (struct kgsl_device *device,
79 enum kgsl_property_type type, void *value,
80 unsigned int sizebytes);
81 int (*waittimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070082 struct kgsl_context *context, unsigned int timestamp,
83 unsigned int msecs);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084 unsigned int (*readtimestamp) (struct kgsl_device *device,
Carter Cooper7e7f02e2012-02-15 09:36:31 -070085 struct kgsl_context *context, enum kgsl_timestamp_type type);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086 int (*issueibcmds) (struct kgsl_device_private *dev_priv,
87 struct kgsl_context *context, struct kgsl_ibdesc *ibdesc,
88 unsigned int sizedwords, uint32_t *timestamp,
89 unsigned int flags);
90 int (*setup_pt)(struct kgsl_device *device,
91 struct kgsl_pagetable *pagetable);
Jordan Crouse9f739212011-07-28 08:37:57 -060092 void (*cleanup_pt)(struct kgsl_device *device,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093 struct kgsl_pagetable *pagetable);
94 void (*power_stats)(struct kgsl_device *device,
95 struct kgsl_power_stats *stats);
96 void (*irqctrl)(struct kgsl_device *device, int state);
Jordan Croused6535882012-06-20 08:22:16 -060097 unsigned int (*gpuid)(struct kgsl_device *device, unsigned int *chipid);
Jordan Crouse156cfbc2012-01-24 09:32:04 -070098 void * (*snapshot)(struct kgsl_device *device, void *snapshot,
99 int *remain, int hang);
Jordan Crouseb368e9b2012-04-27 14:01:59 -0600100 irqreturn_t (*irq_handler)(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101 /* Optional functions - these functions are not mandatory. The
102 driver will check that the function pointer is not NULL before
103 calling the hook */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -0600104 void (*setstate) (struct kgsl_device *device, unsigned int context_id,
105 uint32_t flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106 int (*drawctxt_create) (struct kgsl_device *device,
107 struct kgsl_pagetable *pagetable, struct kgsl_context *context,
Jordan Crouse72bb70b2013-05-28 17:03:52 -0600108 uint32_t *flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700109 void (*drawctxt_destroy) (struct kgsl_device *device,
110 struct kgsl_context *context);
111 long (*ioctl) (struct kgsl_device_private *dev_priv,
112 unsigned int cmd, void *data);
Jordan Crouseed7dd7f2012-03-29 13:16:02 -0600113 int (*setproperty) (struct kgsl_device *device,
114 enum kgsl_property_type type, void *value,
115 unsigned int sizebytes);
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -0600116 int (*postmortem_dump) (struct kgsl_device *device, int manual);
Jordan Crouseed8c2dd2013-01-28 16:58:45 -0700117 int (*next_event)(struct kgsl_device *device,
Jordan Crouse313faf62012-11-20 15:12:28 -0700118 struct kgsl_event *event);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700119};
120
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600121/* MH register values */
122struct kgsl_mh {
123 unsigned int mharb;
124 unsigned int mh_intf_cfg1;
125 unsigned int mh_intf_cfg2;
126 uint32_t mpu_base;
127 int mpu_range;
128};
129
Jordan Croused4bc9d22011-11-17 13:39:21 -0700130struct kgsl_event {
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700131 struct kgsl_context *context;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700132 uint32_t timestamp;
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700133 void (*func)(struct kgsl_device *, void *, u32, u32);
Jordan Croused4bc9d22011-11-17 13:39:21 -0700134 void *priv;
135 struct list_head list;
Shubhraprakash Dascb068072012-06-07 17:52:41 -0600136 void *owner;
Jordan Crouse2c22e912013-02-28 13:40:56 -0700137 unsigned int created;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700138};
139
140
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700141struct kgsl_device {
142 struct device *dev;
143 const char *name;
144 unsigned int ver_major;
145 unsigned int ver_minor;
146 uint32_t flags;
147 enum kgsl_deviceid id;
Jordan Crouse7501d452012-04-19 08:58:44 -0600148 unsigned long reg_phys;
149 void *reg_virt;
150 unsigned int reg_len;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700151 struct kgsl_memdesc memstore;
152 const char *iomemname;
153
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600154 struct kgsl_mh mh;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700155 struct kgsl_mmu mmu;
156 struct completion hwaccess_gate;
157 const struct kgsl_functable *ftbl;
158 struct work_struct idle_check_ws;
159 struct timer_list idle_timer;
160 struct kgsl_pwrctrl pwrctrl;
161 int open_count;
162
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700163 struct mutex mutex;
164 uint32_t state;
165 uint32_t requested_state;
166
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700167 unsigned int active_cnt;
168 struct completion suspend_gate;
169
170 wait_queue_head_t wait_queue;
171 struct workqueue_struct *work_queue;
172 struct device *parentdev;
Tarun Karrad20d71a2013-01-25 15:38:57 -0800173 struct completion ft_gate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700174 struct dentry *d_debugfs;
175 struct idr context_idr;
176 struct early_suspend display_off;
177
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700178 void *snapshot; /* Pointer to the snapshot memory region */
179 int snapshot_maxsize; /* Max size of the snapshot region */
180 int snapshot_size; /* Current size of the snapshot region */
181 u32 snapshot_timestamp; /* Timestamp of the last valid snapshot */
182 int snapshot_frozen; /* 1 if the snapshot output is frozen until
183 it gets read by the user. This avoids
184 losing the output on multiple hangs */
185 struct kobject snapshot_kobj;
186
Jordan Crouse9610b6b2012-03-16 14:53:42 -0600187 /*
188 * List of GPU buffers that have been frozen in memory until they can be
189 * dumped
190 */
191 struct list_head snapshot_obj_list;
192
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700193 /* Logging levels */
194 int cmd_log;
195 int ctxt_log;
196 int drv_log;
197 int mem_log;
198 int pwr_log;
Tarun Karrad20d71a2013-01-25 15:38:57 -0800199 int ft_log;
Tarun Karra45a50d62013-01-28 21:47:37 -0800200 int pm_dump_enable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700201 struct kgsl_pwrscale pwrscale;
202 struct kobject pwrscale_kobj;
Steve Mucklef132c6c2012-06-06 18:30:57 -0700203 struct pm_qos_request pm_qos_req_dma;
Jordan Crouse1bf80aa2011-10-12 16:57:47 -0600204 struct work_struct ts_expired_ws;
Jordan Croused4bc9d22011-11-17 13:39:21 -0700205 struct list_head events;
Jordan Crouseef3456c2013-01-04 16:46:51 -0700206 struct list_head events_pending_list;
Lucille Sylvester808eca22011-11-03 10:26:29 -0700207 s64 on_time;
Harsh Vardhan Dwivedi715fb832012-05-18 00:24:18 -0600208
209 /* Postmortem Control switches */
210 int pm_regs_enabled;
211 int pm_ib_enabled;
Jordan Crouse013cf422013-05-28 17:03:32 -0600212
213 int reset_counter; /* Track how many GPU core resets have occured */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700214};
215
Jordan Crouseef3456c2013-01-04 16:46:51 -0700216void kgsl_process_events(struct work_struct *work);
217void kgsl_check_fences(struct work_struct *work);
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700218
219#define KGSL_DEVICE_COMMON_INIT(_dev) \
220 .hwaccess_gate = COMPLETION_INITIALIZER((_dev).hwaccess_gate),\
221 .suspend_gate = COMPLETION_INITIALIZER((_dev).suspend_gate),\
Tarun Karrad20d71a2013-01-25 15:38:57 -0800222 .ft_gate = COMPLETION_INITIALIZER((_dev).ft_gate),\
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700223 .idle_check_ws = __WORK_INITIALIZER((_dev).idle_check_ws,\
224 kgsl_idle_check),\
225 .ts_expired_ws = __WORK_INITIALIZER((_dev).ts_expired_ws,\
Jordan Crouseef3456c2013-01-04 16:46:51 -0700226 kgsl_process_events),\
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700227 .context_idr = IDR_INIT((_dev).context_idr),\
228 .events = LIST_HEAD_INIT((_dev).events),\
Jordan Crouseef3456c2013-01-04 16:46:51 -0700229 .events_pending_list = LIST_HEAD_INIT((_dev).events_pending_list), \
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700230 .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\
231 .mutex = __MUTEX_INITIALIZER((_dev).mutex),\
232 .state = KGSL_STATE_INIT,\
233 .ver_major = DRIVER_VERSION_MAJOR,\
Carter Cooper12481fd2012-06-05 11:18:34 -0600234 .ver_minor = DRIVER_VERSION_MINOR
Jeremy Gebben84d75d02012-03-01 14:47:45 -0700235
Jordan Crouseef3456c2013-01-04 16:46:51 -0700236
237/**
238 * struct kgsl_context - Master structure for a KGSL context object
239 * @refcount - kref object for reference counting the context
240 * @id - integer identifier for the context
241 * @dev_priv - pointer to the owning device instance
242 * @devctxt - pointer to the device specific context information
243 * @reset_status - status indication whether a gpu reset occured and whether
244 * this context was responsible for causing it
245 * @wait_on_invalid_ts - flag indicating if this context has tried to wait on a
246 * bad timestamp
247 * @timeline - sync timeline used to create fences that can be signaled when a
248 * sync_pt timestamp expires
249 * @events - list head of pending events for this context
250 * @events_list - list node for the list of all contexts that have pending events
251 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252struct kgsl_context {
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600253 struct kref refcount;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700254 uint32_t id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700255 struct kgsl_device_private *dev_priv;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700256 void *devctxt;
Shubhraprakash Das2dfe5dd2012-02-10 13:49:53 -0700257 unsigned int reset_status;
Rajeev Kulkarni46ee1092012-12-14 14:47:55 -0800258 bool wait_on_invalid_ts;
Jeff Boodyfe6c39c2012-08-09 13:54:50 -0600259 struct sync_timeline *timeline;
Jordan Crouseef3456c2013-01-04 16:46:51 -0700260 struct list_head events;
261 struct list_head events_list;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262};
263
264struct kgsl_process_private {
265 unsigned int refcnt;
266 pid_t pid;
267 spinlock_t mem_lock;
Jordan Crousec9559e42012-04-05 16:55:56 -0600268 struct rb_root mem_rb;
Jeremy Gebbena46f4272013-05-28 16:54:09 -0600269 struct idr mem_idr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700270 struct kgsl_pagetable *pagetable;
271 struct list_head list;
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600272 struct kobject kobj;
Jeremy Gebbenddf93012012-09-25 10:57:38 -0600273 struct dentry *debug_root;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700274
275 struct {
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600276 unsigned int cur;
277 unsigned int max;
278 } stats[KGSL_MEM_ENTRY_MAX];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700279};
280
281struct kgsl_device_private {
282 struct kgsl_device *device;
283 struct kgsl_process_private *process_priv;
284};
285
286struct kgsl_power_stats {
287 s64 total_time;
288 s64 busy_time;
289};
290
291struct kgsl_device *kgsl_get_device(int dev_idx);
292
Jordan Crouse1b897cf2011-10-12 16:57:48 -0600293static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
294 unsigned int type, size_t size)
295{
296 priv->stats[type].cur += size;
297 if (priv->stats[type].max < priv->stats[type].cur)
298 priv->stats[type].max = priv->stats[type].cur;
299}
300
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700301static inline void kgsl_regread(struct kgsl_device *device,
302 unsigned int offsetwords,
303 unsigned int *value)
304{
305 device->ftbl->regread(device, offsetwords, value);
306}
307
308static inline void kgsl_regwrite(struct kgsl_device *device,
309 unsigned int offsetwords,
310 unsigned int value)
311{
312 device->ftbl->regwrite(device, offsetwords, value);
313}
314
Jordan Crousea29a2e02012-08-14 09:09:23 -0600315static inline int kgsl_idle(struct kgsl_device *device)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700316{
Jordan Crousea29a2e02012-08-14 09:09:23 -0600317 return device->ftbl->idle(device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700318}
319
Jordan Croused6535882012-06-20 08:22:16 -0600320static inline unsigned int kgsl_gpuid(struct kgsl_device *device,
321 unsigned int *chipid)
Jordan Crousea0758f22011-12-07 11:19:22 -0700322{
Jordan Croused6535882012-06-20 08:22:16 -0600323 return device->ftbl->gpuid(device, chipid);
Jordan Crousea0758f22011-12-07 11:19:22 -0700324}
325
Jeremy Gebben731dac52012-05-10 11:13:42 -0600326static inline unsigned int kgsl_readtimestamp(struct kgsl_device *device,
327 struct kgsl_context *context,
328 enum kgsl_timestamp_type type)
329{
330 return device->ftbl->readtimestamp(device, context, type);
331}
332
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333static inline int kgsl_create_device_sysfs_files(struct device *root,
334 const struct device_attribute **list)
335{
336 int ret = 0, i;
337 for (i = 0; list[i] != NULL; i++)
338 ret |= device_create_file(root, list[i]);
339 return ret;
340}
341
342static inline void kgsl_remove_device_sysfs_files(struct device *root,
343 const struct device_attribute **list)
344{
345 int i;
346 for (i = 0; list[i] != NULL; i++)
347 device_remove_file(root, list[i]);
348}
349
350static inline struct kgsl_mmu *
351kgsl_get_mmu(struct kgsl_device *device)
352{
353 return (struct kgsl_mmu *) (device ? &device->mmu : NULL);
354}
355
356static inline struct kgsl_device *kgsl_device_from_dev(struct device *dev)
357{
358 int i;
359
360 for (i = 0; i < KGSL_DEVICE_MAX; i++) {
361 if (kgsl_driver.devp[i] && kgsl_driver.devp[i]->dev == dev)
362 return kgsl_driver.devp[i];
363 }
364
365 return NULL;
366}
367
368static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
369{
Steve Muckle3e042df2011-11-18 11:25:04 -0800370 device->work_queue = create_singlethread_workqueue(device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700371 if (!device->work_queue) {
Steve Muckle3e042df2011-11-18 11:25:04 -0800372 KGSL_DRV_ERR(device,
373 "create_singlethread_workqueue(%s) failed\n",
374 device->name);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700375 return -EINVAL;
376 }
377 return 0;
378}
379
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700380
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381
Carter Cooper7e7f02e2012-02-15 09:36:31 -0700382int kgsl_check_timestamp(struct kgsl_device *device,
383 struct kgsl_context *context, unsigned int timestamp);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700384
Jordan Crouseb368e9b2012-04-27 14:01:59 -0600385int kgsl_device_platform_probe(struct kgsl_device *device);
386
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387void kgsl_device_platform_remove(struct kgsl_device *device);
388
Jeremy Gebbenb50f3312011-12-16 08:58:33 -0700389const char *kgsl_pwrstate_to_str(unsigned int state);
390
Jordan Crouse156cfbc2012-01-24 09:32:04 -0700391int kgsl_device_snapshot_init(struct kgsl_device *device);
392int kgsl_device_snapshot(struct kgsl_device *device, int hang);
393void kgsl_device_snapshot_close(struct kgsl_device *device);
394
Jordan Croused8aa4be2012-04-18 09:31:07 -0600395static inline struct kgsl_device_platform_data *
396kgsl_device_get_drvdata(struct kgsl_device *dev)
397{
398 struct platform_device *pdev =
399 container_of(dev->parentdev, struct platform_device, dev);
400
401 return pdev->dev.platform_data;
402}
403
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600404void kgsl_context_destroy(struct kref *kref);
405
406/**
407 * kgsl_context_put - Release context reference count
408 * @context
409 *
410 */
411static inline void
412kgsl_context_put(struct kgsl_context *context)
413{
Jordan Crouse67db48d2013-05-28 17:04:17 -0600414 if (context)
415 kref_put(&context->refcount, kgsl_context_destroy);
416}
417
418/**
419 * _kgsl_context_get() - lightweight function to just increment the ref count
420 * @context: Pointer to the KGSL context
421 *
422 * Get a reference to the specified KGSL context structure. This is a
423 * lightweight way to just increase the refcount on a known context rather then
424 * walking through kgsl_context_get and searching the iterator
425 */
426static inline void _kgsl_context_get(struct kgsl_context *context)
427{
428 if (context)
429 kref_get(&context->refcount);
430}
431
432/**
433 * kgsl_context_get - get a pointer to a KGSL context
434 * @devicex - Pointer to the KGSL device that owns the context
435 * @id - Context ID to return
436 *
437 * Find the context associated with the given ID number, increase the reference
438 * count on it and return it. The caller must make sure that this call is
439 * paired with a kgsl_context_put. This function is for internal use because it
440 * doesn't validate the ownership of the context with the calling process - use
441 * kgsl_context_get_owner for that
442 */
443static inline struct kgsl_context *kgsl_context_get(struct kgsl_device *device,
444 uint32_t id)
445{
446 struct kgsl_context *context = NULL;
447
448 rcu_read_lock();
449 context = idr_find(&device->context_idr, id);
450
451 _kgsl_context_get(context);
452
453 rcu_read_unlock();
454 return context;
455}
456
457/**
458 * kgsl_context_get_owner - get a pointer to a KGSL context
459 * @dev_priv - Pointer to the owner of the requesting process
460 * @id - Context ID to return
461 *
462 * Find the context associated with the given ID number, increase the reference
463 * count on it and return it. The caller must make sure that this call is
464 * paired with a kgsl_context_put. This function validates that the context id
465 * given is owned by the dev_priv instancet that is passed in. see
466 * kgsl_context_get for the internal version that doesn't do the check
467 */
468static inline struct kgsl_context *kgsl_context_get_owner(
469 struct kgsl_device_private *dev_priv, uint32_t id)
470{
471 struct kgsl_context *context;
472
473 context = kgsl_context_get(dev_priv->device, id);
474
475 /* Verify that the context belongs to the dev_priv instance */
476 if (context && context->dev_priv != dev_priv) {
477 kgsl_context_put(context);
478 return NULL;
479 }
480
481 return context;
Jeremy Gebben9ad86922012-05-08 15:33:23 -0600482}
483
Jordan Crouseab601992013-03-05 11:18:20 -0700484/**
485 * kgsl_active_count_put - Decrease the device active count
486 * @device: Pointer to a KGSL device
487 *
488 * Decrease the active count for the KGSL device and trigger the suspend_gate
489 * completion if it hits zero
490 */
491static inline void
492kgsl_active_count_put(struct kgsl_device *device)
493{
494 if (device->active_cnt == 1)
495 INIT_COMPLETION(device->suspend_gate);
496
497 device->active_cnt--;
498
499 if (device->active_cnt == 0)
500 complete(&device->suspend_gate);
501}
502
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700503#endif /* __KGSL_DEVICE_H */