Linux Audio

Check our new training course

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