aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/ibmebus.c100
1 files changed, 82 insertions, 18 deletions
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index af21306e2ef9..d21658140b6e 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -51,6 +51,13 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
51 51
52struct bus_type ibmebus_bus_type; 52struct bus_type ibmebus_bus_type;
53 53
54/* These devices will automatically be added to the bus during init */
55static struct of_device_id builtin_matches[] = {
56 { .compatible = "IBM,lhca" },
57 { .compatible = "IBM,lhea" },
58 {},
59};
60
54static void *ibmebus_alloc_coherent(struct device *dev, 61static void *ibmebus_alloc_coherent(struct device *dev,
55 size_t size, 62 size_t size,
56 dma_addr_t *dma_handle, 63 dma_addr_t *dma_handle,
@@ -125,6 +132,67 @@ static struct dma_mapping_ops ibmebus_dma_ops = {
125 .dma_supported = ibmebus_dma_supported, 132 .dma_supported = ibmebus_dma_supported,
126}; 133};
127 134
135static int ibmebus_match_path(struct device *dev, void *data)
136{
137 struct device_node *dn = to_of_device(dev)->node;
138 return (dn->full_name &&
139 (strcasecmp((char *)data, dn->full_name) == 0));
140}
141
142static int ibmebus_match_node(struct device *dev, void *data)
143{
144 * defines the generic type and initializers * * linux/spinlock_up.h: * contains the arch_spin_*()/etc. version of UP * builds. (which are NOPs on non-debug, non-preempt * builds) * * (included on UP-non-debug builds:) * * linux/spinlock_api_up.h: * builds the _spin_*() APIs. * * linux/spinlock.h: builds the final spin_*() APIs. */ #include <linux/typecheck.h> #include <linux/preempt.h> #include <linux/linkage.h> #include <linux/compiler.h> #include <linux/irqflags.h> #include <linux/thread_info.h> #include <linux/kernel.h> #include <linux/stringify.h> #include <linux/bottom_half.h> #include <asm/barrier.h> /* * Must define these before including other files, inline functions need them */ #define LOCK_SECTION_NAME ".text..lock."KBUILD_BASENAME #define LOCK_SECTION_START(extra) \ ".subsection 1\n\t" \ extra \ ".ifndef " LOCK_SECTION_NAME "\n\t" \ LOCK_SECTION_NAME ":\n\t" \ ".endif\n" #define LOCK_SECTION_END \ ".previous\n\t" #define __lockfunc __attribute__((section(".spinlock.text"))) /* * Pull the arch_spinlock_t and arch_rwlock_t definitions: */ #include <linux/spinlock_types.h> /* * Pull the arch_spin*() functions/declarations (UP-nondebug doesn't need them): */ #ifdef CONFIG_SMP # include <asm/spinlock.h> #else # include <linux/spinlock_up.h> #endif #ifdef CONFIG_DEBUG_SPINLOCK extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, struct lock_class_key *key); # define raw_spin_lock_init(lock) \ do { \ static struct lock_class_key __key; \ \ __raw_spin_lock_init((lock), #lock, &__key); \ } while (0) #else # define raw_spin_lock_init(lock) \ do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0) #endif #define raw_spin_is_locked(lock) arch_spin_is_locked(&(lock)->raw_lock) #ifdef CONFIG_GENERIC_LOCKBREAK #define raw_spin_is_contended(lock) ((lock)->break_lock) #else #ifdef arch_spin_is_contended #define raw_spin_is_contended(lock) arch_spin_is_contended(&(lock)->raw_lock) #else #define raw_spin_is_contended(lock) (((void)(lock), 0)) #endif /*arch_spin_is_contended*/ #endif /* * Despite its name it doesn't necessarily has to be a full barrier. * It should only guarantee that a STORE before the critical section * can not be reordered with a LOAD inside this section. * spin_lock() is the one-way barrier, this LOAD can not escape out * of the region. So the default implementation simply ensures that * a STORE can not move into the critical section, smp_wmb() should * serialize it with another STORE done by spin_lock(). */ #ifndef smp_mb__before_spinlock #define smp_mb__before_spinlock() smp_wmb() #endif /** * raw_spin_unlock_wait - wait until the spinlock gets unlocked * @lock: the spinlock in question. */ #define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) #ifdef CONFIG_DEBUG_SPINLOCK extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); #define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock) extern int do_raw_spin_trylock(raw_spinlock_t *lock); extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock); #else static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock) { __acquire(lock); arch_spin_lock(&lock->raw_lock); } static inline void do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) __acquires(lock) { __acquire(lock); arch_spin_lock_flags(&lock->raw_lock, *flags); } ibmebus_match_node))
181 continue;
182
183 ret = ibmebus_create_device(child);
184 if (ret) {
185 printk(KERN_ERR "%s: failed to create device (%i)",
186 __FUNCTION__, ret);
187 of_node_put(child);
188 break;
189 }
190 }
191
192 of_node_put(root);
193 return ret;
194}
195
128int ibmebus_register_driver(struct ibmebus_driver *drv) 196int ibmebus_register_driver(struct ibmebus_driver *drv)
129{ 197{
130 return 0; 198 return 0;
@@ -173,18 +241,6 @@ static struct device_attribute ibmebus_dev_attrs[] = {
173 __ATTR_NULL 241 __ATTR_NULL
174}; 242};
175 243
176static int ibmebus_match_path(struct device *dev, void *data)
177{
178 int rc;
179 struct device_node *dn =
180 of_node_get(to_ibmebus_dev(dev)->ofdev.node);
181
182 rc = (dn->full_name && (strcasecmp((char*)data, dn->full_name) == 0));
183
184 of_node_put(dn);
185 return rc;
186}
187
188static char *ibmebus_chomp(const char *in, size_t count) 244static char *ibmebus_chomp(const char *in, size_t count)
189{ 245{
190 char *out = kmalloc(count + 1, GFP_KERNEL); 246 char *out = kmalloc(count + 1, GFP_KERNEL);
@@ -204,9 +260,8 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
204 const char *buf, size_t count) 260 const char *buf, size_t count)
205{ 261{
206 struct device_node *dn = NULL; 262 struct device_node *dn = NULL;
207 struct ibmebus_dev *dev;
208 char *path; 263 char *path;
209 ssize_t rc; 264 ssize_t rc = 0;
210 265
211 path = ibmebus_chomp(buf, count); 266 path = ibmebus_chomp(buf, count);
212 if (!path) 267 if (!path)
@@ -221,9 +276,8 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
221 } 276 }
222 277
223 if ((dn = of_find_node_by_path(path))) { 278 if ((dn = of_find_node_by_path(path))) {
224/* dev = ibmebus_register_device_node(dn); */ 279 rc = ibmebus_create_device(dn);
225 of_node_put(dn); 280 of_node_put(dn);
226 rc = IS_ERR(dev) ? PTR_ERR(dev) : count;
227 } else { 281 } else {
228 printk(KERN_WARNING "%s: no such device node: %s\n", 282 printk(KERN_WARNING "%s: no such device node: %s\n",
229 __FUNCTION__, path); 283 __FUNCTION__, path);
@@ -232,7 +286,9 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
232 286
233out: 287out:
234 kfree(path); 288 kfree(path);
235 return rc; 289 if (rc)
290 return rc;
291 return count;
236} 292}
237 293
238static ssize_t ibmebus_store_remove(struct bus_type *bus, 294static ssize_t ibmebus_store_remove(struct bus_type *bus,
@@ -247,7 +303,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
247 303
248 if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, 304 if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
249 ibmebus_match_path))) { 305 ibmebus_match_path))) {
250/* ibmebus_unregister_device(dev); */ 306 of_device_unregister(to_of_device(dev));
251 307
252 kfree(path); 308 kfree(path);
253 return count; 309 return count;
@@ -267,6 +323,7 @@ static struct bus_attribute ibmebus_bus_attrs[] = {
267}; 323};
268 324
269struct bus_type ibmebus_bus_type = { 325struct bus_type ibmebus_bus_type = {
326 .uevent = of_device_uevent,
270 .dev_attrs = ibmebus_dev_attrs, 327 .dev_attrs = ibmebus_dev_attrs,
271 .bus_attrs = ibmebus_bus_attrs 328 .bus_attrs = ibmebus_bus_attrs
272}; 329};
@@ -294,6 +351,13 @@ static int __init ibmebus_bus_init(void)
294 return err; 351 return err;
295 } 352 }
296 353
354 err = ibmebus_create_devices(builtin_matches);
355 if (err) {
356 device_unregister(&ibmebus_bus_device);
357 bus_unregister(&ibmebus_bus_type);
358 return err;
359 }
360
297 return 0; 361 return 0;
298} 362}
299postcore_initcall(ibmebus_bus_init); 363postcore_initcall(ibmebus_bus_init);