Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
main.c
Go to the documentation of this file.
1 /*
2  * Broadcom specific AMBA
3  * Bus subsystem
4  *
5  * Licensed under the GNU/GPL. See COPYING for details.
6  */
7 
8 #include "bcma_private.h"
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/bcma/bcma.h>
12 #include <linux/slab.h>
13 
14 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
15 MODULE_LICENSE("GPL");
16 
17 /* contains the number the next bus should get. */
18 static unsigned int bcma_bus_next_num = 0;
19 
20 /* bcma_buses_mutex locks the bcma_bus_next_num */
21 static DEFINE_MUTEX(bcma_buses_mutex);
22 
23 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
24 static int bcma_device_probe(struct device *dev);
25 static int bcma_device_remove(struct device *dev);
26 static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
27 
28 static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
29 {
30  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
31  return sprintf(buf, "0x%03X\n", core->id.manuf);
32 }
33 static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
34 {
35  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
36  return sprintf(buf, "0x%03X\n", core->id.id);
37 }
38 static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
39 {
40  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
41  return sprintf(buf, "0x%02X\n", core->id.rev);
42 }
43 static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
44 {
45  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
46  return sprintf(buf, "0x%X\n", core->id.class);
47 }
48 static struct device_attribute bcma_device_attrs[] = {
49  __ATTR_RO(manuf),
50  __ATTR_RO(id),
51  __ATTR_RO(rev),
52  __ATTR_RO(class),
54 };
55 
56 static struct bus_type bcma_bus_type = {
57  .name = "bcma",
58  .match = bcma_bus_match,
59  .probe = bcma_device_probe,
60  .remove = bcma_device_remove,
61  .uevent = bcma_device_uevent,
62  .dev_attrs = bcma_device_attrs,
63 };
64 
65 static u16 bcma_cc_core_id(struct bcma_bus *bus)
66 {
67  if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
69  return BCMA_CORE_CHIPCOMMON;
70 }
71 
72 struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
73 {
74  struct bcma_device *core;
75 
76  list_for_each_entry(core, &bus->cores, list) {
77  if (core->id.id == coreid)
78  return core;
79  }
80  return NULL;
81 }
83 
84 static void bcma_release_core_dev(struct device *dev)
85 {
86  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
87  if (core->io_addr)
88  iounmap(core->io_addr);
89  if (core->io_wrap)
90  iounmap(core->io_wrap);
91  kfree(core);
92 }
93 
94 static int bcma_register_cores(struct bcma_bus *bus)
95 {
96  struct bcma_device *core;
97  int err, dev_id = 0;
98 
99  list_for_each_entry(core, &bus->cores, list) {
100  /* We support that cores ourself */
101  switch (core->id.id) {
104  case BCMA_CORE_PCI:
105  case BCMA_CORE_PCIE:
106  case BCMA_CORE_MIPS_74K:
108  continue;
109  }
110 
111  core->dev.release = bcma_release_core_dev;
112  core->dev.bus = &bcma_bus_type;
113  dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
114 
115  switch (bus->hosttype) {
116  case BCMA_HOSTTYPE_PCI:
117  core->dev.parent = &bus->host_pci->dev;
118  core->dma_dev = &bus->host_pci->dev;
119  core->irq = bus->host_pci->irq;
120  break;
121  case BCMA_HOSTTYPE_SOC:
122  core->dev.dma_mask = &core->dev.coherent_dma_mask;
123  core->dma_dev = &core->dev;
124  break;
125  case BCMA_HOSTTYPE_SDIO:
126  break;
127  }
128 
129  err = device_register(&core->dev);
130  if (err) {
131  bcma_err(bus,
132  "Could not register dev for core 0x%03X\n",
133  core->id.id);
134  continue;
135  }
136  core->dev_registered = true;
137  dev_id++;
138  }
139 
140 #ifdef CONFIG_BCMA_SFLASH
141  if (bus->drv_cc.sflash.present) {
143  if (err)
144  bcma_err(bus, "Error registering serial flash\n");
145  }
146 #endif
147 
148 #ifdef CONFIG_BCMA_NFLASH
149  if (bus->drv_cc.nflash.present) {
151  if (err)
152  bcma_err(bus, "Error registering NAND flash\n");
153  }
154 #endif
155 
156  return 0;
157 }
158 
159 static void bcma_unregister_cores(struct bcma_bus *bus)
160 {
161  struct bcma_device *core, *tmp;
162 
163  list_for_each_entry_safe(core, tmp, &bus->cores, list) {
164  list_del(&core->list);
165  if (core->dev_registered)
166  device_unregister(&core->dev);
167  }
168 }
169 
171 {
172  int err;
173  struct bcma_device *core;
174 
175  mutex_lock(&bcma_buses_mutex);
176  bus->num = bcma_bus_next_num++;
177  mutex_unlock(&bcma_buses_mutex);
178 
179  /* Scan for devices (cores) */
180  err = bcma_bus_scan(bus);
181  if (err) {
182  bcma_err(bus, "Failed to scan: %d\n", err);
183  return -1;
184  }
185 
186  /* Init CC core */
187  core = bcma_find_core(bus, bcma_cc_core_id(bus));
188  if (core) {
189  bus->drv_cc.core = core;
191  }
192 
193  /* Init MIPS core */
194  core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
195  if (core) {
196  bus->drv_mips.core = core;
198  }
199 
200  /* Init PCIE core */
201  core = bcma_find_core(bus, BCMA_CORE_PCIE);
202  if (core) {
203  bus->drv_pci.core = core;
205  }
206 
207  /* Init GBIT MAC COMMON core */
209  if (core) {
210  bus->drv_gmac_cmn.core = core;
212  }
213 
214  /* Try to get SPROM */
215  err = bcma_sprom_get(bus);
216  if (err == -ENOENT) {
217  bcma_err(bus, "No SPROM available\n");
218  } else if (err)
219  bcma_err(bus, "Failed to get SPROM: %d\n", err);
220 
221  /* Register found cores */
222  bcma_register_cores(bus);
223 
224  bcma_info(bus, "Bus registered\n");
225 
226  return 0;
227 }
228 
229 void bcma_bus_unregister(struct bcma_bus *bus)
230 {
231  struct bcma_device *cores[3];
232 
233  cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
234  cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
236 
237  bcma_unregister_cores(bus);
238 
239  kfree(cores[2]);
240  kfree(cores[1]);
241  kfree(cores[0]);
242 }
243 
245  struct bcma_device *core_cc,
246  struct bcma_device *core_mips)
247 {
248  int err;
249  struct bcma_device *core;
250  struct bcma_device_id match;
251 
252  bcma_init_bus(bus);
253 
254  match.manuf = BCMA_MANUF_BCM;
255  match.id = bcma_cc_core_id(bus);
256  match.class = BCMA_CL_SIM;
257  match.rev = BCMA_ANY_REV;
258 
259  /* Scan for chip common core */
260  err = bcma_bus_scan_early(bus, &match, core_cc);
261  if (err) {
262  bcma_err(bus, "Failed to scan for common core: %d\n", err);
263  return -1;
264  }
265 
266  match.manuf = BCMA_MANUF_MIPS;
267  match.id = BCMA_CORE_MIPS_74K;
268  match.class = BCMA_CL_SIM;
269  match.rev = BCMA_ANY_REV;
270 
271  /* Scan for mips core */
272  err = bcma_bus_scan_early(bus, &match, core_mips);
273  if (err) {
274  bcma_err(bus, "Failed to scan for mips core: %d\n", err);
275  return -1;
276  }
277 
278  /* Init CC core */
279  core = bcma_find_core(bus, bcma_cc_core_id(bus));
280  if (core) {
281  bus->drv_cc.core = core;
283  }
284 
285  /* Init MIPS core */
286  core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
287  if (core) {
288  bus->drv_mips.core = core;
290  }
291 
292  bcma_info(bus, "Early bus registered\n");
293 
294  return 0;
295 }
296 
297 #ifdef CONFIG_PM
298 int bcma_bus_suspend(struct bcma_bus *bus)
299 {
300  struct bcma_device *core;
301 
302  list_for_each_entry(core, &bus->cores, list) {
303  struct device_driver *drv = core->dev.driver;
304  if (drv) {
305  struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
306  if (adrv->suspend)
307  adrv->suspend(core);
308  }
309  }
310  return 0;
311 }
312 
313 int bcma_bus_resume(struct bcma_bus *bus)
314 {
315  struct bcma_device *core;
316 
317  /* Init CC core */
318  if (bus->drv_cc.core) {
319  bus->drv_cc.setup_done = false;
321  }
322 
323  list_for_each_entry(core, &bus->cores, list) {
324  struct device_driver *drv = core->dev.driver;
325  if (drv) {
326  struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
327  if (adrv->resume)
328  adrv->resume(core);
329  }
330  }
331 
332  return 0;
333 }
334 #endif
335 
337 {
338  drv->drv.name = drv->name;
339  drv->drv.bus = &bcma_bus_type;
340  drv->drv.owner = owner;
341 
342  return driver_register(&drv->drv);
343 }
345 
347 {
348  driver_unregister(&drv->drv);
349 }
351 
352 static int bcma_bus_match(struct device *dev, struct device_driver *drv)
353 {
354  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
355  struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
356  const struct bcma_device_id *cid = &core->id;
357  const struct bcma_device_id *did;
358 
359  for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
360  if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
361  (did->id == cid->id || did->id == BCMA_ANY_ID) &&
362  (did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
363  (did->class == cid->class || did->class == BCMA_ANY_CLASS))
364  return 1;
365  }
366  return 0;
367 }
368 
369 static int bcma_device_probe(struct device *dev)
370 {
371  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
372  struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
373  drv);
374  int err = 0;
375 
376  if (adrv->probe)
377  err = adrv->probe(core);
378 
379  return err;
380 }
381 
382 static int bcma_device_remove(struct device *dev)
383 {
384  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
385  struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
386  drv);
387 
388  if (adrv->remove)
389  adrv->remove(core);
390 
391  return 0;
392 }
393 
394 static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
395 {
396  struct bcma_device *core = container_of(dev, struct bcma_device, dev);
397 
398  return add_uevent_var(env,
399  "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
400  core->id.manuf, core->id.id,
401  core->id.rev, core->id.class);
402 }
403 
404 static int __init bcma_modinit(void)
405 {
406  int err;
407 
408  err = bus_register(&bcma_bus_type);
409  if (err)
410  return err;
411 
412 #ifdef CONFIG_BCMA_HOST_PCI
413  err = bcma_host_pci_init();
414  if (err) {
415  pr_err("PCI host initialization failed\n");
416  err = 0;
417  }
418 #endif
419 
420  return err;
421 }
422 fs_initcall(bcma_modinit);
423 
424 static void __exit bcma_modexit(void)
425 {
426 #ifdef CONFIG_BCMA_HOST_PCI
428 #endif
429  bus_unregister(&bcma_bus_type);
430 }
431 module_exit(bcma_modexit)