1 /* linux/arch/arm/mach-exynos/dev.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * EXYNOS4 Device List support
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/device.h>
14 #include <linux/list.h>
15 #include <linux/mutex.h>
16 #include <linux/err.h>
17 #include <linux/slab.h>
20 #ifdef CONFIG_ARCH_EXYNOS4
21 #include <mach/busfreq_exynos4.h>
23 #include <mach/busfreq_exynos5.h>
26 static LIST_HEAD(domains_list);
27 static DEFINE_MUTEX(domains_mutex);
29 static struct device_domain *find_device_domain(struct device *dev)
31 struct device_domain *tmp_domain, *domain = ERR_PTR(-ENODEV);
33 mutex_lock(&domains_mutex);
34 list_for_each_entry(tmp_domain, &domains_list, node) {
35 if (tmp_domain->device == dev) {
41 mutex_unlock(&domains_mutex);
45 int dev_add(struct device_domain *dev, struct device *device)
50 mutex_lock(&domains_mutex);
51 INIT_LIST_HEAD(&dev->domain_list);
53 list_add(&dev->node, &domains_list);
54 mutex_unlock(&domains_mutex);
59 struct device *dev_get(const char *name)
61 struct device_domain *domain;
63 mutex_lock(&domains_mutex);
64 list_for_each_entry(domain, &domains_list, node)
65 if (strcmp(name, dev_name(domain->device)) == 0)
68 mutex_unlock(&domains_mutex);
69 return ERR_PTR(-ENODEV);
71 mutex_unlock(&domains_mutex);
72 return domain->device;
75 void dev_put(const char *name)
80 int dev_lock(struct device *device, struct device *dev,
83 struct device_domain *domain;
84 struct domain_lock *lock;
87 domain = find_device_domain(device);
90 dev_err(dev, "Can't find device domain.\n");
94 mutex_lock(&domains_mutex);
95 list_for_each_entry(lock, &domain->domain_list, node) {
96 if (lock->device == dev) {
97 /* If the lock already exist, only update the freq */
103 lock = kzalloc(sizeof(struct domain_lock), GFP_KERNEL);
105 dev_err(device, "Unable to create domain_lock");
112 list_add(&lock->node, &domain->domain_list);
115 mutex_unlock(&domains_mutex);
116 exynos_request_apply(freq);
120 int dev_unlock(struct device *device, struct device *dev)
122 struct device_domain *domain;
123 struct domain_lock *lock;
125 domain = find_device_domain(device);
127 if (IS_ERR(domain)) {
128 dev_err(dev, "Can't find device domain.\n");
132 mutex_lock(&domains_mutex);
133 list_for_each_entry(lock, &domain->domain_list, node) {
134 if (lock->device == dev) {
135 list_del(&lock->node);
141 mutex_unlock(&domains_mutex);
146 unsigned long dev_max_freq(struct device *device)
148 struct device_domain *domain;
149 struct domain_lock *lock;
150 unsigned long freq = 0;
152 domain = find_device_domain(device);
153 if (IS_ERR(domain)) {
154 dev_dbg(device, "Can't find device domain.\n");
158 mutex_lock(&domains_mutex);
159 list_for_each_entry(lock, &domain->domain_list, node)
160 if (lock->freq > freq)
163 mutex_unlock(&domains_mutex);
168 int dev_lock_list(struct device *device, char *buf)
170 struct device_domain *domain;
171 struct domain_lock *lock;
174 domain = find_device_domain(device);
175 if (IS_ERR(domain)) {
176 dev_dbg(device, "Can't find device domain.\n");
180 mutex_lock(&domains_mutex);
181 count = sprintf(buf, "Lock List\n");
182 list_for_each_entry(lock, &domain->domain_list, node)
183 count += sprintf(buf + count, "%s : %lu\n", dev_name(lock->device), lock->freq);
185 mutex_unlock(&domains_mutex);