xref: /openbmc/linux/drivers/ssb/main.c (revision a24853aab59184ebd19c5e078c7b29e1c316e3a1)
161e115a5SMichael Buesch /*
261e115a5SMichael Buesch  * Sonics Silicon Backplane
361e115a5SMichael Buesch  * Subsystem core
461e115a5SMichael Buesch  *
561e115a5SMichael Buesch  * Copyright 2005, Broadcom Corporation
6eb032b98SMichael Büsch  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
761e115a5SMichael Buesch  *
861e115a5SMichael Buesch  * Licensed under the GNU/GPL. See COPYING for details.
961e115a5SMichael Buesch  */
1061e115a5SMichael Buesch 
1161e115a5SMichael Buesch #include "ssb_private.h"
1261e115a5SMichael Buesch 
1361e115a5SMichael Buesch #include <linux/delay.h>
146faf035cSGeert Uytterhoeven #include <linux/io.h>
1520a112d0SPaul Gortmaker #include <linux/module.h>
16bde327efSHauke Mehrtens #include <linux/platform_device.h>
1761e115a5SMichael Buesch #include <linux/ssb/ssb.h>
1861e115a5SMichael Buesch #include <linux/ssb/ssb_regs.h>
19aab547ceSMichael Buesch #include <linux/ssb/ssb_driver_gige.h>
2061e115a5SMichael Buesch #include <linux/dma-mapping.h>
2161e115a5SMichael Buesch #include <linux/pci.h>
2224ea602eSAlbert Herranz #include <linux/mmc/sdio_func.h>
235a0e3ad6STejun Heo #include <linux/slab.h>
2461e115a5SMichael Buesch 
2561e115a5SMichael Buesch #include <pcmcia/cistpl.h>
2661e115a5SMichael Buesch #include <pcmcia/ds.h>
2761e115a5SMichael Buesch 
2861e115a5SMichael Buesch 
2961e115a5SMichael Buesch MODULE_DESCRIPTION("Sonics Silicon Backplane driver");
3061e115a5SMichael Buesch MODULE_LICENSE("GPL");
3161e115a5SMichael Buesch 
3261e115a5SMichael Buesch 
3361e115a5SMichael Buesch /* Temporary list of yet-to-be-attached buses */
3461e115a5SMichael Buesch static LIST_HEAD(attach_queue);
3561e115a5SMichael Buesch /* List if running buses */
3661e115a5SMichael Buesch static LIST_HEAD(buses);
3761e115a5SMichael Buesch /* Software ID counter */
3861e115a5SMichael Buesch static unsigned int next_busnumber;
3961e115a5SMichael Buesch /* buses_mutes locks the two buslists and the next_busnumber.
4061e115a5SMichael Buesch  * Don't lock this directly, but use ssb_buses_[un]lock() below. */
4161e115a5SMichael Buesch static DEFINE_MUTEX(buses_mutex);
4261e115a5SMichael Buesch 
4361e115a5SMichael Buesch /* There are differences in the codeflow, if the bus is
4461e115a5SMichael Buesch  * initialized from early boot, as various needed services
4561e115a5SMichael Buesch  * are not available early. This is a mechanism to delay
4661e115a5SMichael Buesch  * these initializations to after early boot has finished.
4761e115a5SMichael Buesch  * It's also used to avoid mutex locking, as that's not
4861e115a5SMichael Buesch  * available and needed early. */
4961e115a5SMichael Buesch static bool ssb_is_early_boot = 1;
5061e115a5SMichael Buesch 
5161e115a5SMichael Buesch static void ssb_buses_lock(void);
5261e115a5SMichael Buesch static void ssb_buses_unlock(void);
5361e115a5SMichael Buesch 
5461e115a5SMichael Buesch 
5561e115a5SMichael Buesch #ifdef CONFIG_SSB_PCIHOST
5661e115a5SMichael Buesch struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev)
5761e115a5SMichael Buesch {
5861e115a5SMichael Buesch 	struct ssb_bus *bus;
5961e115a5SMichael Buesch 
6061e115a5SMichael Buesch 	ssb_buses_lock();
6161e115a5SMichael Buesch 	list_for_each_entry(bus, &buses, list) {
6261e115a5SMichael Buesch 		if (bus->bustype == SSB_BUSTYPE_PCI &&
6361e115a5SMichael Buesch 		    bus->host_pci == pdev)
6461e115a5SMichael Buesch 			goto found;
6561e115a5SMichael Buesch 	}
6661e115a5SMichael Buesch 	bus = NULL;
6761e115a5SMichael Buesch found:
6861e115a5SMichael Buesch 	ssb_buses_unlock();
6961e115a5SMichael Buesch 
7061e115a5SMichael Buesch 	return bus;
7161e115a5SMichael Buesch }
7261e115a5SMichael Buesch #endif /* CONFIG_SSB_PCIHOST */
7361e115a5SMichael Buesch 
74e7ec2e32SMichael Buesch #ifdef CONFIG_SSB_PCMCIAHOST
75e7ec2e32SMichael Buesch struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev)
76e7ec2e32SMichael Buesch {
77e7ec2e32SMichael Buesch 	struct ssb_bus *bus;
78e7ec2e32SMichael Buesch 
79e7ec2e32SMichael Buesch 	ssb_buses_lock();
80e7ec2e32SMichael Buesch 	list_for_each_entry(bus, &buses, list) {
81e7ec2e32SMichael Buesch 		if (bus->bustype == SSB_BUSTYPE_PCMCIA &&
82e7ec2e32SMichael Buesch 		    bus->host_pcmcia == pdev)
83e7ec2e32SMichael Buesch 			goto found;
84e7ec2e32SMichael Buesch 	}
85e7ec2e32SMichael Buesch 	bus = NULL;
86e7ec2e32SMichael Buesch found:
87e7ec2e32SMichael Buesch 	ssb_buses_unlock();
88e7ec2e32SMichael Buesch 
89e7ec2e32SMichael Buesch 	return bus;
90e7ec2e32SMichael Buesch }
91e7ec2e32SMichael Buesch #endif /* CONFIG_SSB_PCMCIAHOST */
92e7ec2e32SMichael Buesch 
93aab547ceSMichael Buesch int ssb_for_each_bus_call(unsigned long data,
94aab547ceSMichael Buesch 			  int (*func)(struct ssb_bus *bus, unsigned long data))
95aab547ceSMichael Buesch {
96aab547ceSMichael Buesch 	struct ssb_bus *bus;
97aab547ceSMichael Buesch 	int res;
98aab547ceSMichael Buesch 
99aab547ceSMichael Buesch 	ssb_buses_lock();
100aab547ceSMichael Buesch 	list_for_each_entry(bus, &buses, list) {
101aab547ceSMichael Buesch 		res = func(bus, data);
102aab547ceSMichael Buesch 		if (res >= 0) {
103aab547ceSMichael Buesch 			ssb_buses_unlock();
104aab547ceSMichael Buesch 			return res;
105aab547ceSMichael Buesch 		}
106aab547ceSMichael Buesch 	}
107aab547ceSMichael Buesch 	ssb_buses_unlock();
108aab547ceSMichael Buesch 
109aab547ceSMichael Buesch 	return -ENODEV;
110aab547ceSMichael Buesch }
111aab547ceSMichael Buesch 
11261e115a5SMichael Buesch static struct ssb_device *ssb_device_get(struct ssb_device *dev)
11361e115a5SMichael Buesch {
11461e115a5SMichael Buesch 	if (dev)
11561e115a5SMichael Buesch 		get_device(dev->dev);
11661e115a5SMichael Buesch 	return dev;
11761e115a5SMichael Buesch }
11861e115a5SMichael Buesch 
11961e115a5SMichael Buesch static void ssb_device_put(struct ssb_device *dev)
12061e115a5SMichael Buesch {
12161e115a5SMichael Buesch 	if (dev)
12261e115a5SMichael Buesch 		put_device(dev->dev);
12361e115a5SMichael Buesch }
12461e115a5SMichael Buesch 
12561e115a5SMichael Buesch static int ssb_device_resume(struct device *dev)
12661e115a5SMichael Buesch {
12761e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
12861e115a5SMichael Buesch 	struct ssb_driver *ssb_drv;
12961e115a5SMichael Buesch 	int err = 0;
13061e115a5SMichael Buesch 
13161e115a5SMichael Buesch 	if (dev->driver) {
13261e115a5SMichael Buesch 		ssb_drv = drv_to_ssb_drv(dev->driver);
13361e115a5SMichael Buesch 		if (ssb_drv && ssb_drv->resume)
13461e115a5SMichael Buesch 			err = ssb_drv->resume(ssb_dev);
13561e115a5SMichael Buesch 		if (err)
13661e115a5SMichael Buesch 			goto out;
13761e115a5SMichael Buesch 	}
13861e115a5SMichael Buesch out:
13961e115a5SMichael Buesch 	return err;
14061e115a5SMichael Buesch }
14161e115a5SMichael Buesch 
14261e115a5SMichael Buesch static int ssb_device_suspend(struct device *dev, pm_message_t state)
14361e115a5SMichael Buesch {
14461e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
14561e115a5SMichael Buesch 	struct ssb_driver *ssb_drv;
14661e115a5SMichael Buesch 	int err = 0;
14761e115a5SMichael Buesch 
14861e115a5SMichael Buesch 	if (dev->driver) {
14961e115a5SMichael Buesch 		ssb_drv = drv_to_ssb_drv(dev->driver);
15061e115a5SMichael Buesch 		if (ssb_drv && ssb_drv->suspend)
15161e115a5SMichael Buesch 			err = ssb_drv->suspend(ssb_dev, state);
15261e115a5SMichael Buesch 		if (err)
15361e115a5SMichael Buesch 			goto out;
15461e115a5SMichael Buesch 	}
15561e115a5SMichael Buesch out:
15661e115a5SMichael Buesch 	return err;
15761e115a5SMichael Buesch }
15861e115a5SMichael Buesch 
1598fe2b65aSMichael Buesch int ssb_bus_resume(struct ssb_bus *bus)
1608fe2b65aSMichael Buesch {
1618fe2b65aSMichael Buesch 	int err;
1628fe2b65aSMichael Buesch 
1638fe2b65aSMichael Buesch 	/* Reset HW state information in memory, so that HW is
1648fe2b65aSMichael Buesch 	 * completely reinitialized. */
1658fe2b65aSMichael Buesch 	bus->mapped_device = NULL;
1668fe2b65aSMichael Buesch #ifdef CONFIG_SSB_DRIVER_PCICORE
1678fe2b65aSMichael Buesch 	bus->pcicore.setup_done = 0;
1688fe2b65aSMichael Buesch #endif
1698fe2b65aSMichael Buesch 
1708fe2b65aSMichael Buesch 	err = ssb_bus_powerup(bus, 0);
1718fe2b65aSMichael Buesch 	if (err)
1728fe2b65aSMichael Buesch 		return err;
1738fe2b65aSMichael Buesch 	err = ssb_pcmcia_hardware_setup(bus);
1748fe2b65aSMichael Buesch 	if (err) {
1758fe2b65aSMichael Buesch 		ssb_bus_may_powerdown(bus);
1768fe2b65aSMichael Buesch 		return err;
1778fe2b65aSMichael Buesch 	}
1788fe2b65aSMichael Buesch 	ssb_chipco_resume(&bus->chipco);
1798fe2b65aSMichael Buesch 	ssb_bus_may_powerdown(bus);
1808fe2b65aSMichael Buesch 
1818fe2b65aSMichael Buesch 	return 0;
1828fe2b65aSMichael Buesch }
1838fe2b65aSMichael Buesch EXPORT_SYMBOL(ssb_bus_resume);
1848fe2b65aSMichael Buesch 
1858fe2b65aSMichael Buesch int ssb_bus_suspend(struct ssb_bus *bus)
1868fe2b65aSMichael Buesch {
1878fe2b65aSMichael Buesch 	ssb_chipco_suspend(&bus->chipco);
1888fe2b65aSMichael Buesch 	ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
1898fe2b65aSMichael Buesch 
1908fe2b65aSMichael Buesch 	return 0;
1918fe2b65aSMichael Buesch }
1928fe2b65aSMichael Buesch EXPORT_SYMBOL(ssb_bus_suspend);
1938fe2b65aSMichael Buesch 
194d72bb40fSMichael Buesch #ifdef CONFIG_SSB_SPROM
1953ba6018aSMichael Buesch /** ssb_devices_freeze - Freeze all devices on the bus.
1963ba6018aSMichael Buesch  *
1973ba6018aSMichael Buesch  * After freezing no device driver will be handling a device
1983ba6018aSMichael Buesch  * on this bus anymore. ssb_devices_thaw() must be called after
1993ba6018aSMichael Buesch  * a successful freeze to reactivate the devices.
2003ba6018aSMichael Buesch  *
2013ba6018aSMichael Buesch  * @bus: The bus.
2023ba6018aSMichael Buesch  * @ctx: Context structure. Pass this to ssb_devices_thaw().
2033ba6018aSMichael Buesch  */
2043ba6018aSMichael Buesch int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx)
20561e115a5SMichael Buesch {
2063ba6018aSMichael Buesch 	struct ssb_device *sdev;
2073ba6018aSMichael Buesch 	struct ssb_driver *sdrv;
2083ba6018aSMichael Buesch 	unsigned int i;
20961e115a5SMichael Buesch 
2103ba6018aSMichael Buesch 	memset(ctx, 0, sizeof(*ctx));
2113ba6018aSMichael Buesch 	ctx->bus = bus;
2123ba6018aSMichael Buesch 	SSB_WARN_ON(bus->nr_devices > ARRAY_SIZE(ctx->device_frozen));
2133ba6018aSMichael Buesch 
21461e115a5SMichael Buesch 	for (i = 0; i < bus->nr_devices; i++) {
2153ba6018aSMichael Buesch 		sdev = ssb_device_get(&bus->devices[i]);
2163ba6018aSMichael Buesch 
2173ba6018aSMichael Buesch 		if (!sdev->dev || !sdev->dev->driver ||
2183ba6018aSMichael Buesch 		    !device_is_registered(sdev->dev)) {
2193ba6018aSMichael Buesch 			ssb_device_put(sdev);
22061e115a5SMichael Buesch 			continue;
22161e115a5SMichael Buesch 		}
222f3ff9247SAlan Stern 		sdrv = drv_to_ssb_drv(sdev->dev->driver);
223f3ff9247SAlan Stern 		if (SSB_WARN_ON(!sdrv->remove))
22461e115a5SMichael Buesch 			continue;
2253ba6018aSMichael Buesch 		sdrv->remove(sdev);
2263ba6018aSMichael Buesch 		ctx->device_frozen[i] = 1;
22761e115a5SMichael Buesch 	}
22861e115a5SMichael Buesch 
22961e115a5SMichael Buesch 	return 0;
23061e115a5SMichael Buesch }
23161e115a5SMichael Buesch 
2323ba6018aSMichael Buesch /** ssb_devices_thaw - Unfreeze all devices on the bus.
2333ba6018aSMichael Buesch  *
2343ba6018aSMichael Buesch  * This will re-attach the device drivers and re-init the devices.
2353ba6018aSMichael Buesch  *
2363ba6018aSMichael Buesch  * @ctx: The context structure from ssb_devices_freeze()
2373ba6018aSMichael Buesch  */
2383ba6018aSMichael Buesch int ssb_devices_thaw(struct ssb_freeze_context *ctx)
23961e115a5SMichael Buesch {
2403ba6018aSMichael Buesch 	struct ssb_bus *bus = ctx->bus;
2413ba6018aSMichael Buesch 	struct ssb_device *sdev;
2423ba6018aSMichael Buesch 	struct ssb_driver *sdrv;
2433ba6018aSMichael Buesch 	unsigned int i;
2443ba6018aSMichael Buesch 	int err, result = 0;
24561e115a5SMichael Buesch 
24661e115a5SMichael Buesch 	for (i = 0; i < bus->nr_devices; i++) {
2473ba6018aSMichael Buesch 		if (!ctx->device_frozen[i])
24861e115a5SMichael Buesch 			continue;
2493ba6018aSMichael Buesch 		sdev = &bus->devices[i];
2503ba6018aSMichael Buesch 
2513ba6018aSMichael Buesch 		if (SSB_WARN_ON(!sdev->dev || !sdev->dev->driver))
25261e115a5SMichael Buesch 			continue;
2533ba6018aSMichael Buesch 		sdrv = drv_to_ssb_drv(sdev->dev->driver);
2543ba6018aSMichael Buesch 		if (SSB_WARN_ON(!sdrv || !sdrv->probe))
25561e115a5SMichael Buesch 			continue;
2563ba6018aSMichael Buesch 
2573ba6018aSMichael Buesch 		err = sdrv->probe(sdev, &sdev->id);
25861e115a5SMichael Buesch 		if (err) {
25933a606acSJoe Perches 			ssb_err("Failed to thaw device %s\n",
2603ba6018aSMichael Buesch 				dev_name(sdev->dev));
2613ba6018aSMichael Buesch 			result = err;
26261e115a5SMichael Buesch 		}
2633ba6018aSMichael Buesch 		ssb_device_put(sdev);
26461e115a5SMichael Buesch 	}
26561e115a5SMichael Buesch 
2663ba6018aSMichael Buesch 	return result;
26761e115a5SMichael Buesch }
268d72bb40fSMichael Buesch #endif /* CONFIG_SSB_SPROM */
26961e115a5SMichael Buesch 
27061e115a5SMichael Buesch static void ssb_device_shutdown(struct device *dev)
27161e115a5SMichael Buesch {
27261e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
27361e115a5SMichael Buesch 	struct ssb_driver *ssb_drv;
27461e115a5SMichael Buesch 
27561e115a5SMichael Buesch 	if (!dev->driver)
27661e115a5SMichael Buesch 		return;
27761e115a5SMichael Buesch 	ssb_drv = drv_to_ssb_drv(dev->driver);
27861e115a5SMichael Buesch 	if (ssb_drv && ssb_drv->shutdown)
27961e115a5SMichael Buesch 		ssb_drv->shutdown(ssb_dev);
28061e115a5SMichael Buesch }
28161e115a5SMichael Buesch 
28261e115a5SMichael Buesch static int ssb_device_remove(struct device *dev)
28361e115a5SMichael Buesch {
28461e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
28561e115a5SMichael Buesch 	struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
28661e115a5SMichael Buesch 
28761e115a5SMichael Buesch 	if (ssb_drv && ssb_drv->remove)
28861e115a5SMichael Buesch 		ssb_drv->remove(ssb_dev);
28961e115a5SMichael Buesch 	ssb_device_put(ssb_dev);
29061e115a5SMichael Buesch 
29161e115a5SMichael Buesch 	return 0;
29261e115a5SMichael Buesch }
29361e115a5SMichael Buesch 
29461e115a5SMichael Buesch static int ssb_device_probe(struct device *dev)
29561e115a5SMichael Buesch {
29661e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
29761e115a5SMichael Buesch 	struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
29861e115a5SMichael Buesch 	int err = 0;
29961e115a5SMichael Buesch 
30061e115a5SMichael Buesch 	ssb_device_get(ssb_dev);
30161e115a5SMichael Buesch 	if (ssb_drv && ssb_drv->probe)
30261e115a5SMichael Buesch 		err = ssb_drv->probe(ssb_dev, &ssb_dev->id);
30361e115a5SMichael Buesch 	if (err)
30461e115a5SMichael Buesch 		ssb_device_put(ssb_dev);
30561e115a5SMichael Buesch 
30661e115a5SMichael Buesch 	return err;
30761e115a5SMichael Buesch }
30861e115a5SMichael Buesch 
30961e115a5SMichael Buesch static int ssb_match_devid(const struct ssb_device_id *tabid,
31061e115a5SMichael Buesch 			   const struct ssb_device_id *devid)
31161e115a5SMichael Buesch {
31261e115a5SMichael Buesch 	if ((tabid->vendor != devid->vendor) &&
31361e115a5SMichael Buesch 	    tabid->vendor != SSB_ANY_VENDOR)
31461e115a5SMichael Buesch 		return 0;
31561e115a5SMichael Buesch 	if ((tabid->coreid != devid->coreid) &&
31661e115a5SMichael Buesch 	    tabid->coreid != SSB_ANY_ID)
31761e115a5SMichael Buesch 		return 0;
31861e115a5SMichael Buesch 	if ((tabid->revision != devid->revision) &&
31961e115a5SMichael Buesch 	    tabid->revision != SSB_ANY_REV)
32061e115a5SMichael Buesch 		return 0;
32161e115a5SMichael Buesch 	return 1;
32261e115a5SMichael Buesch }
32361e115a5SMichael Buesch 
32461e115a5SMichael Buesch static int ssb_bus_match(struct device *dev, struct device_driver *drv)
32561e115a5SMichael Buesch {
32661e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
32761e115a5SMichael Buesch 	struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv);
32861e115a5SMichael Buesch 	const struct ssb_device_id *id;
32961e115a5SMichael Buesch 
33061e115a5SMichael Buesch 	for (id = ssb_drv->id_table;
33161e115a5SMichael Buesch 	     id->vendor || id->coreid || id->revision;
33261e115a5SMichael Buesch 	     id++) {
33361e115a5SMichael Buesch 		if (ssb_match_devid(id, &ssb_dev->id))
33461e115a5SMichael Buesch 			return 1; /* found */
33561e115a5SMichael Buesch 	}
33661e115a5SMichael Buesch 
33761e115a5SMichael Buesch 	return 0;
33861e115a5SMichael Buesch }
33961e115a5SMichael Buesch 
3407ac0326cSAl Viro static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env)
34161e115a5SMichael Buesch {
34261e115a5SMichael Buesch 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
34361e115a5SMichael Buesch 
34461e115a5SMichael Buesch 	if (!dev)
34561e115a5SMichael Buesch 		return -ENODEV;
34661e115a5SMichael Buesch 
3477ac0326cSAl Viro 	return add_uevent_var(env,
34861e115a5SMichael Buesch 			     "MODALIAS=ssb:v%04Xid%04Xrev%02X",
34961e115a5SMichael Buesch 			     ssb_dev->id.vendor, ssb_dev->id.coreid,
35061e115a5SMichael Buesch 			     ssb_dev->id.revision);
35161e115a5SMichael Buesch }
35261e115a5SMichael Buesch 
353aa3bf280SHauke Mehrtens #define ssb_config_attr(attrib, field, format_string) \
354aa3bf280SHauke Mehrtens static ssize_t \
355aa3bf280SHauke Mehrtens attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
356aa3bf280SHauke Mehrtens { \
357aa3bf280SHauke Mehrtens 	return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
3584e9072d6SGreg Kroah-Hartman } \
3594e9072d6SGreg Kroah-Hartman static DEVICE_ATTR_RO(attrib);
360aa3bf280SHauke Mehrtens 
361aa3bf280SHauke Mehrtens ssb_config_attr(core_num, core_index, "%u\n")
362aa3bf280SHauke Mehrtens ssb_config_attr(coreid, id.coreid, "0x%04x\n")
363aa3bf280SHauke Mehrtens ssb_config_attr(vendor, id.vendor, "0x%04x\n")
364aa3bf280SHauke Mehrtens ssb_config_attr(revision, id.revision, "%u\n")
365aa3bf280SHauke Mehrtens ssb_config_attr(irq, irq, "%u\n")
366aa3bf280SHauke Mehrtens static ssize_t
367aa3bf280SHauke Mehrtens name_show(struct device *dev, struct device_attribute *attr, char *buf)
368aa3bf280SHauke Mehrtens {
369aa3bf280SHauke Mehrtens 	return sprintf(buf, "%s\n",
370aa3bf280SHauke Mehrtens 		       ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
371aa3bf280SHauke Mehrtens }
3724e9072d6SGreg Kroah-Hartman static DEVICE_ATTR_RO(name);
373aa3bf280SHauke Mehrtens 
3744e9072d6SGreg Kroah-Hartman static struct attribute *ssb_device_attrs[] = {
3754e9072d6SGreg Kroah-Hartman 	&dev_attr_name.attr,
3764e9072d6SGreg Kroah-Hartman 	&dev_attr_core_num.attr,
3774e9072d6SGreg Kroah-Hartman 	&dev_attr_coreid.attr,
3784e9072d6SGreg Kroah-Hartman 	&dev_attr_vendor.attr,
3794e9072d6SGreg Kroah-Hartman 	&dev_attr_revision.attr,
3804e9072d6SGreg Kroah-Hartman 	&dev_attr_irq.attr,
3814e9072d6SGreg Kroah-Hartman 	NULL,
382aa3bf280SHauke Mehrtens };
3834e9072d6SGreg Kroah-Hartman ATTRIBUTE_GROUPS(ssb_device);
384aa3bf280SHauke Mehrtens 
38561e115a5SMichael Buesch static struct bus_type ssb_bustype = {
38661e115a5SMichael Buesch 	.name		= "ssb",
38761e115a5SMichael Buesch 	.match		= ssb_bus_match,
38861e115a5SMichael Buesch 	.probe		= ssb_device_probe,
38961e115a5SMichael Buesch 	.remove		= ssb_device_remove,
39061e115a5SMichael Buesch 	.shutdown	= ssb_device_shutdown,
39161e115a5SMichael Buesch 	.suspend	= ssb_device_suspend,
39261e115a5SMichael Buesch 	.resume		= ssb_device_resume,
39361e115a5SMichael Buesch 	.uevent		= ssb_device_uevent,
3944e9072d6SGreg Kroah-Hartman 	.dev_groups	= ssb_device_groups,
39561e115a5SMichael Buesch };
39661e115a5SMichael Buesch 
39761e115a5SMichael Buesch static void ssb_buses_lock(void)
39861e115a5SMichael Buesch {
39961e115a5SMichael Buesch 	/* See the comment at the ssb_is_early_boot definition */
40061e115a5SMichael Buesch 	if (!ssb_is_early_boot)
40161e115a5SMichael Buesch 		mutex_lock(&buses_mutex);
40261e115a5SMichael Buesch }
40361e115a5SMichael Buesch 
40461e115a5SMichael Buesch static void ssb_buses_unlock(void)
40561e115a5SMichael Buesch {
40661e115a5SMichael Buesch 	/* See the comment at the ssb_is_early_boot definition */
40761e115a5SMichael Buesch 	if (!ssb_is_early_boot)
40861e115a5SMichael Buesch 		mutex_unlock(&buses_mutex);
40961e115a5SMichael Buesch }
41061e115a5SMichael Buesch 
41161e115a5SMichael Buesch static void ssb_devices_unregister(struct ssb_bus *bus)
41261e115a5SMichael Buesch {
41361e115a5SMichael Buesch 	struct ssb_device *sdev;
41461e115a5SMichael Buesch 	int i;
41561e115a5SMichael Buesch 
41661e115a5SMichael Buesch 	for (i = bus->nr_devices - 1; i >= 0; i--) {
41761e115a5SMichael Buesch 		sdev = &(bus->devices[i]);
41861e115a5SMichael Buesch 		if (sdev->dev)
41961e115a5SMichael Buesch 			device_unregister(sdev->dev);
42061e115a5SMichael Buesch 	}
421bde327efSHauke Mehrtens 
422bde327efSHauke Mehrtens #ifdef CONFIG_SSB_EMBEDDED
423bde327efSHauke Mehrtens 	if (bus->bustype == SSB_BUSTYPE_SSB)
424bde327efSHauke Mehrtens 		platform_device_unregister(bus->watchdog);
425bde327efSHauke Mehrtens #endif
42661e115a5SMichael Buesch }
42761e115a5SMichael Buesch 
42861e115a5SMichael Buesch void ssb_bus_unregister(struct ssb_bus *bus)
42961e115a5SMichael Buesch {
430600485edSHauke Mehrtens 	int err;
431600485edSHauke Mehrtens 
432600485edSHauke Mehrtens 	err = ssb_gpio_unregister(bus);
433600485edSHauke Mehrtens 	if (err == -EBUSY)
43433a606acSJoe Perches 		ssb_dbg("Some GPIOs are still in use\n");
435600485edSHauke Mehrtens 	else if (err)
43633a606acSJoe Perches 		ssb_dbg("Can not unregister GPIO driver: %i\n", err);
437600485edSHauke Mehrtens 
43861e115a5SMichael Buesch 	ssb_buses_lock();
43961e115a5SMichael Buesch 	ssb_devices_unregister(bus);
44061e115a5SMichael Buesch 	list_del(&bus->list);
44161e115a5SMichael Buesch 	ssb_buses_unlock();
44261e115a5SMichael Buesch 
443e7ec2e32SMichael Buesch 	ssb_pcmcia_exit(bus);
44461e115a5SMichael Buesch 	ssb_pci_exit(bus);
44561e115a5SMichael Buesch 	ssb_iounmap(bus);
44661e115a5SMichael Buesch }
44761e115a5SMichael Buesch EXPORT_SYMBOL(ssb_bus_unregister);
44861e115a5SMichael Buesch 
44961e115a5SMichael Buesch static void ssb_release_dev(struct device *dev)
45061e115a5SMichael Buesch {
45161e115a5SMichael Buesch 	struct __ssb_dev_wrapper *devwrap;
45261e115a5SMichael Buesch 
45361e115a5SMichael Buesch 	devwrap = container_of(dev, struct __ssb_dev_wrapper, dev);
45461e115a5SMichael Buesch 	kfree(devwrap);
45561e115a5SMichael Buesch }
45661e115a5SMichael Buesch 
45761e115a5SMichael Buesch static int ssb_devices_register(struct ssb_bus *bus)
45861e115a5SMichael Buesch {
45961e115a5SMichael Buesch 	struct ssb_device *sdev;
46061e115a5SMichael Buesch 	struct device *dev;
46161e115a5SMichael Buesch 	struct __ssb_dev_wrapper *devwrap;
46261e115a5SMichael Buesch 	int i, err = 0;
46361e115a5SMichael Buesch 	int dev_idx = 0;
46461e115a5SMichael Buesch 
46561e115a5SMichael Buesch 	for (i = 0; i < bus->nr_devices; i++) {
46661e115a5SMichael Buesch 		sdev = &(bus->devices[i]);
46761e115a5SMichael Buesch 
46861e115a5SMichael Buesch 		/* We don't register SSB-system devices to the kernel,
46961e115a5SMichael Buesch 		 * as the drivers for them are built into SSB. */
47061e115a5SMichael Buesch 		switch (sdev->id.coreid) {
47161e115a5SMichael Buesch 		case SSB_DEV_CHIPCOMMON:
47261e115a5SMichael Buesch 		case SSB_DEV_PCI:
47361e115a5SMichael Buesch 		case SSB_DEV_PCIE:
47461e115a5SMichael Buesch 		case SSB_DEV_PCMCIA:
47561e115a5SMichael Buesch 		case SSB_DEV_MIPS:
47661e115a5SMichael Buesch 		case SSB_DEV_MIPS_3302:
47761e115a5SMichael Buesch 		case SSB_DEV_EXTIF:
47861e115a5SMichael Buesch 			continue;
47961e115a5SMichael Buesch 		}
48061e115a5SMichael Buesch 
48161e115a5SMichael Buesch 		devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL);
48261e115a5SMichael Buesch 		if (!devwrap) {
48361e115a5SMichael Buesch 			err = -ENOMEM;
48461e115a5SMichael Buesch 			goto error;
48561e115a5SMichael Buesch 		}
48661e115a5SMichael Buesch 		dev = &devwrap->dev;
48761e115a5SMichael Buesch 		devwrap->sdev = sdev;
48861e115a5SMichael Buesch 
48961e115a5SMichael Buesch 		dev->release = ssb_release_dev;
49061e115a5SMichael Buesch 		dev->bus = &ssb_bustype;
491b7b05fe7SKay Sievers 		dev_set_name(dev, "ssb%u:%d", bus->busnumber, dev_idx);
49261e115a5SMichael Buesch 
49361e115a5SMichael Buesch 		switch (bus->bustype) {
49461e115a5SMichael Buesch 		case SSB_BUSTYPE_PCI:
49561e115a5SMichael Buesch #ifdef CONFIG_SSB_PCIHOST
49661e115a5SMichael Buesch 			sdev->irq = bus->host_pci->irq;
49761e115a5SMichael Buesch 			dev->parent = &bus->host_pci->dev;
49814f92952SFUJITA Tomonori 			sdev->dma_dev = dev->parent;
49961e115a5SMichael Buesch #endif
50061e115a5SMichael Buesch 			break;
50161e115a5SMichael Buesch 		case SSB_BUSTYPE_PCMCIA:
50261e115a5SMichael Buesch #ifdef CONFIG_SSB_PCMCIAHOST
503eb14120fSDominik Brodowski 			sdev->irq = bus->host_pcmcia->irq;
50461e115a5SMichael Buesch 			dev->parent = &bus->host_pcmcia->dev;
50561e115a5SMichael Buesch #endif
50661e115a5SMichael Buesch 			break;
50724ea602eSAlbert Herranz 		case SSB_BUSTYPE_SDIO:
508391ae22aSMichael Buesch #ifdef CONFIG_SSB_SDIOHOST
50924ea602eSAlbert Herranz 			dev->parent = &bus->host_sdio->dev;
51024ea602eSAlbert Herranz #endif
51124ea602eSAlbert Herranz 			break;
51261e115a5SMichael Buesch 		case SSB_BUSTYPE_SSB:
513ac82da33SAurelien Jarno 			dev->dma_mask = &dev->coherent_dma_mask;
51414f92952SFUJITA Tomonori 			sdev->dma_dev = dev;
51561e115a5SMichael Buesch 			break;
51661e115a5SMichael Buesch 		}
51761e115a5SMichael Buesch 
51861e115a5SMichael Buesch 		sdev->dev = dev;
51961e115a5SMichael Buesch 		err = device_register(dev);
52061e115a5SMichael Buesch 		if (err) {
52133a606acSJoe Perches 			ssb_err("Could not register %s\n", dev_name(dev));
52261e115a5SMichael Buesch 			/* Set dev to NULL to not unregister
52361e115a5SMichael Buesch 			 * dev on error unwinding. */
52461e115a5SMichael Buesch 			sdev->dev = NULL;
525*a24853aaSArvind Yadav 			put_device(dev);
52661e115a5SMichael Buesch 			goto error;
52761e115a5SMichael Buesch 		}
52861e115a5SMichael Buesch 		dev_idx++;
52961e115a5SMichael Buesch 	}
53061e115a5SMichael Buesch 
531c7a4a9e3SRafał Miłecki #ifdef CONFIG_SSB_DRIVER_MIPS
532c7a4a9e3SRafał Miłecki 	if (bus->mipscore.pflash.present) {
533c7a4a9e3SRafał Miłecki 		err = platform_device_register(&ssb_pflash_dev);
534c7a4a9e3SRafał Miłecki 		if (err)
535c7a4a9e3SRafał Miłecki 			pr_err("Error registering parallel flash\n");
536c7a4a9e3SRafał Miłecki 	}
537c7a4a9e3SRafał Miłecki #endif
538c7a4a9e3SRafał Miłecki 
5397b5d6043SRafał Miłecki #ifdef CONFIG_SSB_SFLASH
5407b5d6043SRafał Miłecki 	if (bus->mipscore.sflash.present) {
5417b5d6043SRafał Miłecki 		err = platform_device_register(&ssb_sflash_dev);
5427b5d6043SRafał Miłecki 		if (err)
5437b5d6043SRafał Miłecki 			pr_err("Error registering serial flash\n");
5447b5d6043SRafał Miłecki 	}
5457b5d6043SRafał Miłecki #endif
5467b5d6043SRafał Miłecki 
54761e115a5SMichael Buesch 	return 0;
54861e115a5SMichael Buesch error:
54961e115a5SMichael Buesch 	/* Unwind the already registered devices. */
55061e115a5SMichael Buesch 	ssb_devices_unregister(bus);
55161e115a5SMichael Buesch 	return err;
55261e115a5SMichael Buesch }
55361e115a5SMichael Buesch 
55461e115a5SMichael Buesch /* Needs ssb_buses_lock() */
555163247c1SGreg Kroah-Hartman static int ssb_attach_queued_buses(void)
55661e115a5SMichael Buesch {
55761e115a5SMichael Buesch 	struct ssb_bus *bus, *n;
55861e115a5SMichael Buesch 	int err = 0;
55961e115a5SMichael Buesch 	int drop_them_all = 0;
56061e115a5SMichael Buesch 
56161e115a5SMichael Buesch 	list_for_each_entry_safe(bus, n, &attach_queue, list) {
56261e115a5SMichael Buesch 		if (drop_them_all) {
56361e115a5SMichael Buesch 			list_del(&bus->list);
56461e115a5SMichael Buesch 			continue;
56561e115a5SMichael Buesch 		}
56661e115a5SMichael Buesch 		/* Can't init the PCIcore in ssb_bus_register(), as that
56761e115a5SMichael Buesch 		 * is too early in boot for embedded systems
56861e115a5SMichael Buesch 		 * (no udelay() available). So do it here in attach stage.
56961e115a5SMichael Buesch 		 */
57061e115a5SMichael Buesch 		err = ssb_bus_powerup(bus, 0);
57161e115a5SMichael Buesch 		if (err)
57261e115a5SMichael Buesch 			goto error;
57361e115a5SMichael Buesch 		ssb_pcicore_init(&bus->pcicore);
574bde327efSHauke Mehrtens 		if (bus->bustype == SSB_BUSTYPE_SSB)
575bde327efSHauke Mehrtens 			ssb_watchdog_register(bus);
5767c1bc0daSRafał Miłecki 
5777c1bc0daSRafał Miłecki 		err = ssb_gpio_init(bus);
5787c1bc0daSRafał Miłecki 		if (err == -ENOTSUPP)
5797c1bc0daSRafał Miłecki 			ssb_dbg("GPIO driver not activated\n");
5807c1bc0daSRafał Miłecki 		else if (err)
5817c1bc0daSRafał Miłecki 			ssb_dbg("Error registering GPIO driver: %i\n", err);
5827c1bc0daSRafał Miłecki 
58361e115a5SMichael Buesch 		ssb_bus_may_powerdown(bus);
58461e115a5SMichael Buesch 
58561e115a5SMichael Buesch 		err = ssb_devices_register(bus);
58661e115a5SMichael Buesch error:
58761e115a5SMichael Buesch 		if (err) {
58861e115a5SMichael Buesch 			drop_them_all = 1;
58961e115a5SMichael Buesch 			list_del(&bus->list);
59061e115a5SMichael Buesch 			continue;
59161e115a5SMichael Buesch 		}
59261e115a5SMichael Buesch 		list_move_tail(&bus->list, &buses);
59361e115a5SMichael Buesch 	}
59461e115a5SMichael Buesch 
59561e115a5SMichael Buesch 	return err;
59661e115a5SMichael Buesch }
59761e115a5SMichael Buesch 
59861e115a5SMichael Buesch static int ssb_fetch_invariants(struct ssb_bus *bus,
59961e115a5SMichael Buesch 				ssb_invariants_func_t get_invariants)
60061e115a5SMichael Buesch {
60161e115a5SMichael Buesch 	struct ssb_init_invariants iv;
60261e115a5SMichael Buesch 	int err;
60361e115a5SMichael Buesch 
60461e115a5SMichael Buesch 	memset(&iv, 0, sizeof(iv));
60561e115a5SMichael Buesch 	err = get_invariants(bus, &iv);
60661e115a5SMichael Buesch 	if (err)
60761e115a5SMichael Buesch 		goto out;
60861e115a5SMichael Buesch 	memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo));
60961e115a5SMichael Buesch 	memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom));
6107cb44615SMichael Buesch 	bus->has_cardbus_slot = iv.has_cardbus_slot;
61161e115a5SMichael Buesch out:
61261e115a5SMichael Buesch 	return err;
61361e115a5SMichael Buesch }
61461e115a5SMichael Buesch 
615b7e2d195SArnd Bergmann static int __maybe_unused
616b7e2d195SArnd Bergmann ssb_bus_register(struct ssb_bus *bus,
61761e115a5SMichael Buesch 		 ssb_invariants_func_t get_invariants,
61861e115a5SMichael Buesch 		 unsigned long baseaddr)
61961e115a5SMichael Buesch {
62061e115a5SMichael Buesch 	int err;
62161e115a5SMichael Buesch 
62261e115a5SMichael Buesch 	spin_lock_init(&bus->bar_lock);
62361e115a5SMichael Buesch 	INIT_LIST_HEAD(&bus->list);
62453521d8cSMichael Buesch #ifdef CONFIG_SSB_EMBEDDED
62553521d8cSMichael Buesch 	spin_lock_init(&bus->gpio_lock);
62653521d8cSMichael Buesch #endif
62761e115a5SMichael Buesch 
62861e115a5SMichael Buesch 	/* Powerup the bus */
62961e115a5SMichael Buesch 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
63061e115a5SMichael Buesch 	if (err)
63161e115a5SMichael Buesch 		goto out;
63224ea602eSAlbert Herranz 
63324ea602eSAlbert Herranz 	/* Init SDIO-host device (if any), before the scan */
63424ea602eSAlbert Herranz 	err = ssb_sdio_init(bus);
63524ea602eSAlbert Herranz 	if (err)
63624ea602eSAlbert Herranz 		goto err_disable_xtal;
63724ea602eSAlbert Herranz 
63861e115a5SMichael Buesch 	ssb_buses_lock();
63961e115a5SMichael Buesch 	bus->busnumber = next_busnumber;
64061e115a5SMichael Buesch 	/* Scan for devices (cores) */
64161e115a5SMichael Buesch 	err = ssb_bus_scan(bus, baseaddr);
64261e115a5SMichael Buesch 	if (err)
64324ea602eSAlbert Herranz 		goto err_sdio_exit;
64461e115a5SMichael Buesch 
64561e115a5SMichael Buesch 	/* Init PCI-host device (if any) */
64661e115a5SMichael Buesch 	err = ssb_pci_init(bus);
64761e115a5SMichael Buesch 	if (err)
64861e115a5SMichael Buesch 		goto err_unmap;
64961e115a5SMichael Buesch 	/* Init PCMCIA-host device (if any) */
65061e115a5SMichael Buesch 	err = ssb_pcmcia_init(bus);
65161e115a5SMichael Buesch 	if (err)
65261e115a5SMichael Buesch 		goto err_pci_exit;
65361e115a5SMichael Buesch 
65461e115a5SMichael Buesch 	/* Initialize basic system devices (if available) */
65561e115a5SMichael Buesch 	err = ssb_bus_powerup(bus, 0);
65661e115a5SMichael Buesch 	if (err)
65761e115a5SMichael Buesch 		goto err_pcmcia_exit;
65861e115a5SMichael Buesch 	ssb_chipcommon_init(&bus->chipco);
659394bc7e3SHauke Mehrtens 	ssb_extif_init(&bus->extif);
66061e115a5SMichael Buesch 	ssb_mipscore_init(&bus->mipscore);
66161e115a5SMichael Buesch 	err = ssb_fetch_invariants(bus, get_invariants);
66261e115a5SMichael Buesch 	if (err) {
66361e115a5SMichael Buesch 		ssb_bus_may_powerdown(bus);
66461e115a5SMichael Buesch 		goto err_pcmcia_exit;
66561e115a5SMichael Buesch 	}
66661e115a5SMichael Buesch 	ssb_bus_may_powerdown(bus);
66761e115a5SMichael Buesch 
66861e115a5SMichael Buesch 	/* Queue it for attach.
66961e115a5SMichael Buesch 	 * See the comment at the ssb_is_early_boot definition. */
67061e115a5SMichael Buesch 	list_add_tail(&bus->list, &attach_queue);
67161e115a5SMichael Buesch 	if (!ssb_is_early_boot) {
67261e115a5SMichael Buesch 		/* This is not early boot, so we must attach the bus now */
67361e115a5SMichael Buesch 		err = ssb_attach_queued_buses();
67461e115a5SMichael Buesch 		if (err)
67561e115a5SMichael Buesch 			goto err_dequeue;
67661e115a5SMichael Buesch 	}
67761e115a5SMichael Buesch 	next_busnumber++;
67861e115a5SMichael Buesch 	ssb_buses_unlock();
67961e115a5SMichael Buesch 
68061e115a5SMichael Buesch out:
68161e115a5SMichael Buesch 	return err;
68261e115a5SMichael Buesch 
68361e115a5SMichael Buesch err_dequeue:
68461e115a5SMichael Buesch 	list_del(&bus->list);
68561e115a5SMichael Buesch err_pcmcia_exit:
686e7ec2e32SMichael Buesch 	ssb_pcmcia_exit(bus);
68761e115a5SMichael Buesch err_pci_exit:
68861e115a5SMichael Buesch 	ssb_pci_exit(bus);
68961e115a5SMichael Buesch err_unmap:
69061e115a5SMichael Buesch 	ssb_iounmap(bus);
69124ea602eSAlbert Herranz err_sdio_exit:
69224ea602eSAlbert Herranz 	ssb_sdio_exit(bus);
69361e115a5SMichael Buesch err_disable_xtal:
69461e115a5SMichael Buesch 	ssb_buses_unlock();
69561e115a5SMichael Buesch 	ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
69661e115a5SMichael Buesch 	return err;
69761e115a5SMichael Buesch }
69861e115a5SMichael Buesch 
69961e115a5SMichael Buesch #ifdef CONFIG_SSB_PCIHOST
700163247c1SGreg Kroah-Hartman int ssb_bus_pcibus_register(struct ssb_bus *bus, struct pci_dev *host_pci)
70161e115a5SMichael Buesch {
70261e115a5SMichael Buesch 	int err;
70361e115a5SMichael Buesch 
70461e115a5SMichael Buesch 	bus->bustype = SSB_BUSTYPE_PCI;
70561e115a5SMichael Buesch 	bus->host_pci = host_pci;
70661e115a5SMichael Buesch 	bus->ops = &ssb_pci_ops;
70761e115a5SMichael Buesch 
70861e115a5SMichael Buesch 	err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
70961e115a5SMichael Buesch 	if (!err) {
71033a606acSJoe Perches 		ssb_info("Sonics Silicon Backplane found on PCI device %s\n",
71133a606acSJoe Perches 			 dev_name(&host_pci->dev));
712ce9626eaSLarry Finger 	} else {
71333a606acSJoe Perches 		ssb_err("Failed to register PCI version of SSB with error %d\n",
71433a606acSJoe Perches 			err);
71561e115a5SMichael Buesch 	}
71661e115a5SMichael Buesch 
71761e115a5SMichael Buesch 	return err;
71861e115a5SMichael Buesch }
71961e115a5SMichael Buesch #endif /* CONFIG_SSB_PCIHOST */
72061e115a5SMichael Buesch 
72161e115a5SMichael Buesch #ifdef CONFIG_SSB_PCMCIAHOST
722163247c1SGreg Kroah-Hartman int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
72361e115a5SMichael Buesch 			       struct pcmcia_device *pcmcia_dev,
72461e115a5SMichael Buesch 			       unsigned long baseaddr)
72561e115a5SMichael Buesch {
72661e115a5SMichael Buesch 	int err;
72761e115a5SMichael Buesch 
72861e115a5SMichael Buesch 	bus->bustype = SSB_BUSTYPE_PCMCIA;
72961e115a5SMichael Buesch 	bus->host_pcmcia = pcmcia_dev;
73061e115a5SMichael Buesch 	bus->ops = &ssb_pcmcia_ops;
73161e115a5SMichael Buesch 
73261e115a5SMichael Buesch 	err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr);
73361e115a5SMichael Buesch 	if (!err) {
73433a606acSJoe Perches 		ssb_info("Sonics Silicon Backplane found on PCMCIA device %s\n",
73533a606acSJoe Perches 			 pcmcia_dev->devname);
73661e115a5SMichael Buesch 	}
73761e115a5SMichael Buesch 
73861e115a5SMichael Buesch 	return err;
73961e115a5SMichael Buesch }
74061e115a5SMichael Buesch #endif /* CONFIG_SSB_PCMCIAHOST */
74161e115a5SMichael Buesch 
74224ea602eSAlbert Herranz #ifdef CONFIG_SSB_SDIOHOST
743163247c1SGreg Kroah-Hartman int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
74424ea602eSAlbert Herranz 			     unsigned int quirks)
74524ea602eSAlbert Herranz {
74624ea602eSAlbert Herranz 	int err;
74724ea602eSAlbert Herranz 
74824ea602eSAlbert Herranz 	bus->bustype = SSB_BUSTYPE_SDIO;
74924ea602eSAlbert Herranz 	bus->host_sdio = func;
75024ea602eSAlbert Herranz 	bus->ops = &ssb_sdio_ops;
75124ea602eSAlbert Herranz 	bus->quirks = quirks;
75224ea602eSAlbert Herranz 
75324ea602eSAlbert Herranz 	err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0);
75424ea602eSAlbert Herranz 	if (!err) {
75533a606acSJoe Perches 		ssb_info("Sonics Silicon Backplane found on SDIO device %s\n",
75633a606acSJoe Perches 			 sdio_func_id(func));
75724ea602eSAlbert Herranz 	}
75824ea602eSAlbert Herranz 
75924ea602eSAlbert Herranz 	return err;
76024ea602eSAlbert Herranz }
76124ea602eSAlbert Herranz EXPORT_SYMBOL(ssb_bus_sdiobus_register);
76224ea602eSAlbert Herranz #endif /* CONFIG_SSB_PCMCIAHOST */
76324ea602eSAlbert Herranz 
764845da6e5SRafał Miłecki #ifdef CONFIG_SSB_HOST_SOC
765541c9a84SRafał Miłecki int ssb_bus_host_soc_register(struct ssb_bus *bus, unsigned long baseaddr)
76661e115a5SMichael Buesch {
76761e115a5SMichael Buesch 	int err;
76861e115a5SMichael Buesch 
76961e115a5SMichael Buesch 	bus->bustype = SSB_BUSTYPE_SSB;
770830c7df4SRafał Miłecki 	bus->ops = &ssb_host_soc_ops;
77161e115a5SMichael Buesch 
772541c9a84SRafał Miłecki 	err = ssb_bus_register(bus, ssb_host_soc_get_invariants, baseaddr);
77361e115a5SMichael Buesch 	if (!err) {
77433a606acSJoe Perches 		ssb_info("Sonics Silicon Backplane found at address 0x%08lX\n",
77533a606acSJoe Perches 			 baseaddr);
77661e115a5SMichael Buesch 	}
77761e115a5SMichael Buesch 
77861e115a5SMichael Buesch 	return err;
77961e115a5SMichael Buesch }
780845da6e5SRafał Miłecki #endif
78161e115a5SMichael Buesch 
78261e115a5SMichael Buesch int __ssb_driver_register(struct ssb_driver *drv, struct module *owner)
78361e115a5SMichael Buesch {
78461e115a5SMichael Buesch 	drv->drv.name = drv->name;
78561e115a5SMichael Buesch 	drv->drv.bus = &ssb_bustype;
78661e115a5SMichael Buesch 	drv->drv.owner = owner;
78761e115a5SMichael Buesch 
78861e115a5SMichael Buesch 	return driver_register(&drv->drv);
78961e115a5SMichael Buesch }
79061e115a5SMichael Buesch EXPORT_SYMBOL(__ssb_driver_register);
79161e115a5SMichael Buesch 
79261e115a5SMichael Buesch void ssb_driver_unregister(struct ssb_driver *drv)
79361e115a5SMichael Buesch {
79461e115a5SMichael Buesch 	driver_unregister(&drv->drv);
79561e115a5SMichael Buesch }
79661e115a5SMichael Buesch EXPORT_SYMBOL(ssb_driver_unregister);
79761e115a5SMichael Buesch 
79861e115a5SMichael Buesch void ssb_set_devtypedata(struct ssb_device *dev, void *data)
79961e115a5SMichael Buesch {
80061e115a5SMichael Buesch 	struct ssb_bus *bus = dev->bus;
80161e115a5SMichael Buesch 	struct ssb_device *ent;
80261e115a5SMichael Buesch 	int i;
80361e115a5SMichael Buesch 
80461e115a5SMichael Buesch 	for (i = 0; i < bus->nr_devices; i++) {
80561e115a5SMichael Buesch 		ent = &(bus->devices[i]);
80661e115a5SMichael Buesch 		if (ent->id.vendor != dev->id.vendor)
80761e115a5SMichael Buesch 			continue;
80861e115a5SMichael Buesch 		if (ent->id.coreid != dev->id.coreid)
80961e115a5SMichael Buesch 			continue;
81061e115a5SMichael Buesch 
81161e115a5SMichael Buesch 		ent->devtypedata = data;
81261e115a5SMichael Buesch 	}
81361e115a5SMichael Buesch }
81461e115a5SMichael Buesch EXPORT_SYMBOL(ssb_set_devtypedata);
81561e115a5SMichael Buesch 
81661e115a5SMichael Buesch static u32 clkfactor_f6_resolve(u32 v)
81761e115a5SMichael Buesch {
81861e115a5SMichael Buesch 	/* map the magic values */
81961e115a5SMichael Buesch 	switch (v) {
82061e115a5SMichael Buesch 	case SSB_CHIPCO_CLK_F6_2:
82161e115a5SMichael Buesch 		return 2;
82261e115a5SMichael Buesch 	case SSB_CHIPCO_CLK_F6_3:
82361e115a5SMichael Buesch 		return 3;
82461e115a5SMichael Buesch 	case SSB_CHIPCO_CLK_F6_4:
82561e115a5SMichael Buesch 		return 4;
82661e115a5SMichael Buesch 	case SSB_CHIPCO_CLK_F6_5:
82761e115a5SMichael Buesch 		return 5;
82861e115a5SMichael Buesch 	case SSB_CHIPCO_CLK_F6_6:
82961e115a5SMichael Buesch 		return 6;
83061e115a5SMichael Buesch 	case SSB_CHIPCO_CLK_F6_7:
83161e115a5SMichael Buesch 		return 7;
83261e115a5SMichael Buesch 	}
83361e115a5SMichael Buesch 	return 0;
83461e115a5SMichael Buesch }
83561e115a5SMichael Buesch 
83661e115a5SMichael Buesch /* Calculate the speed the backplane would run at a given set of clockcontrol values */
83761e115a5SMichael Buesch u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m)
83861e115a5SMichael Buesch {
83961e115a5SMichael Buesch 	u32 n1, n2, clock, m1, m2, m3, mc;
84061e115a5SMichael Buesch 
84161e115a5SMichael Buesch 	n1 = (n & SSB_CHIPCO_CLK_N1);
84261e115a5SMichael Buesch 	n2 = ((n & SSB_CHIPCO_CLK_N2) >> SSB_CHIPCO_CLK_N2_SHIFT);
84361e115a5SMichael Buesch 
84461e115a5SMichael Buesch 	switch (plltype) {
84561e115a5SMichael Buesch 	case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
84661e115a5SMichael Buesch 		if (m & SSB_CHIPCO_CLK_T6_MMASK)
84761e115a5SMichael Buesch 			return SSB_CHIPCO_CLK_T6_M1;
848e913d468SHauke Mehrtens 		return SSB_CHIPCO_CLK_T6_M0;
84961e115a5SMichael Buesch 	case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
85061e115a5SMichael Buesch 	case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
85161e115a5SMichael Buesch 	case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
85261e115a5SMichael Buesch 	case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
85361e115a5SMichael Buesch 		n1 = clkfactor_f6_resolve(n1);
85461e115a5SMichael Buesch 		n2 += SSB_CHIPCO_CLK_F5_BIAS;
85561e115a5SMichael Buesch 		break;
85661e115a5SMichael Buesch 	case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */
85761e115a5SMichael Buesch 		n1 += SSB_CHIPCO_CLK_T2_BIAS;
85861e115a5SMichael Buesch 		n2 += SSB_CHIPCO_CLK_T2_BIAS;
85961e115a5SMichael Buesch 		SSB_WARN_ON(!((n1 >= 2) && (n1 <= 7)));
86061e115a5SMichael Buesch 		SSB_WARN_ON(!((n2 >= 5) && (n2 <= 23)));
86161e115a5SMichael Buesch 		break;
86261e115a5SMichael Buesch 	case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */
86361e115a5SMichael Buesch 		return 100000000;
86461e115a5SMichael Buesch 	default:
86561e115a5SMichael Buesch 		SSB_WARN_ON(1);
86661e115a5SMichael Buesch 	}
86761e115a5SMichael Buesch 
86861e115a5SMichael Buesch 	switch (plltype) {
86961e115a5SMichael Buesch 	case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
87061e115a5SMichael Buesch 	case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
87161e115a5SMichael Buesch 		clock = SSB_CHIPCO_CLK_BASE2 * n1 * n2;
87261e115a5SMichael Buesch 		break;
87361e115a5SMichael Buesch 	default:
87461e115a5SMichael Buesch 		clock = SSB_CHIPCO_CLK_BASE1 * n1 * n2;
87561e115a5SMichael Buesch 	}
87661e115a5SMichael Buesch 	if (!clock)
87761e115a5SMichael Buesch 		return 0;
87861e115a5SMichael Buesch 
87961e115a5SMichael Buesch 	m1 = (m & SSB_CHIPCO_CLK_M1);
88061e115a5SMichael Buesch 	m2 = ((m & SSB_CHIPCO_CLK_M2) >> SSB_CHIPCO_CLK_M2_SHIFT);
88161e115a5SMichael Buesch 	m3 = ((m & SSB_CHIPCO_CLK_M3) >> SSB_CHIPCO_CLK_M3_SHIFT);
88261e115a5SMichael Buesch 	mc = ((m & SSB_CHIPCO_CLK_MC) >> SSB_CHIPCO_CLK_MC_SHIFT);
88361e115a5SMichael Buesch 
88461e115a5SMichael Buesch 	switch (plltype) {
88561e115a5SMichael Buesch 	case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
88661e115a5SMichael Buesch 	case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
88761e115a5SMichael Buesch 	case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
88861e115a5SMichael Buesch 	case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
88961e115a5SMichael Buesch 		m1 = clkfactor_f6_resolve(m1);
89061e115a5SMichael Buesch 		if ((plltype == SSB_PLLTYPE_1) ||
89161e115a5SMichael Buesch 		    (plltype == SSB_PLLTYPE_3))
89261e115a5SMichael Buesch 			m2 += SSB_CHIPCO_CLK_F5_BIAS;
89361e115a5SMichael Buesch 		else
89461e115a5SMichael Buesch 			m2 = clkfactor_f6_resolve(m2);
89561e115a5SMichael Buesch 		m3 = clkfactor_f6_resolve(m3);
89661e115a5SMichael Buesch 
89761e115a5SMichael Buesch 		switch (mc) {
89861e115a5SMichael Buesch 		case SSB_CHIPCO_CLK_MC_BYPASS:
89961e115a5SMichael Buesch 			return clock;
90061e115a5SMichael Buesch 		case SSB_CHIPCO_CLK_MC_M1:
90161e115a5SMichael Buesch 			return (clock / m1);
90261e115a5SMichael Buesch 		case SSB_CHIPCO_CLK_MC_M1M2:
90361e115a5SMichael Buesch 			return (clock / (m1 * m2));
90461e115a5SMichael Buesch 		case SSB_CHIPCO_CLK_MC_M1M2M3:
90561e115a5SMichael Buesch 			return (clock / (m1 * m2 * m3));
90661e115a5SMichael Buesch 		case SSB_CHIPCO_CLK_MC_M1M3:
90761e115a5SMichael Buesch 			return (clock / (m1 * m3));
90861e115a5SMichael Buesch 		}
90961e115a5SMichael Buesch 		return 0;
91061e115a5SMichael Buesch 	case SSB_PLLTYPE_2:
91161e115a5SMichael Buesch 		m1 += SSB_CHIPCO_CLK_T2_BIAS;
91261e115a5SMichael Buesch 		m2 += SSB_CHIPCO_CLK_T2M2_BIAS;
91361e115a5SMichael Buesch 		m3 += SSB_CHIPCO_CLK_T2_BIAS;
91461e115a5SMichael Buesch 		SSB_WARN_ON(!((m1 >= 2) && (m1 <= 7)));
91561e115a5SMichael Buesch 		SSB_WARN_ON(!((m2 >= 3) && (m2 <= 10)));
91661e115a5SMichael Buesch 		SSB_WARN_ON(!((m3 >= 2) && (m3 <= 7)));
91761e115a5SMichael Buesch 
91861e115a5SMichael Buesch 		if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP))
91961e115a5SMichael Buesch 			clock /= m1;
92061e115a5SMichael Buesch 		if (!(mc & SSB_CHIPCO_CLK_T2MC_M2BYP))
92161e115a5SMichael Buesch 			clock /= m2;
92261e115a5SMichael Buesch 		if (!(mc & SSB_CHIPCO_CLK_T2MC_M3BYP))
92361e115a5SMichael Buesch 			clock /= m3;
92461e115a5SMichael Buesch 		return clock;
92561e115a5SMichael Buesch 	default:
92661e115a5SMichael Buesch 		SSB_WARN_ON(1);
92761e115a5SMichael Buesch 	}
92861e115a5SMichael Buesch 	return 0;
92961e115a5SMichael Buesch }
93061e115a5SMichael Buesch 
93161e115a5SMichael Buesch /* Get the current speed the backplane is running at */
93261e115a5SMichael Buesch u32 ssb_clockspeed(struct ssb_bus *bus)
93361e115a5SMichael Buesch {
93461e115a5SMichael Buesch 	u32 rate;
93561e115a5SMichael Buesch 	u32 plltype;
93661e115a5SMichael Buesch 	u32 clkctl_n, clkctl_m;
93761e115a5SMichael Buesch 
938d486a5b4SHauke Mehrtens 	if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
939d486a5b4SHauke Mehrtens 		return ssb_pmu_get_controlclock(&bus->chipco);
940d486a5b4SHauke Mehrtens 
94161e115a5SMichael Buesch 	if (ssb_extif_available(&bus->extif))
94261e115a5SMichael Buesch 		ssb_extif_get_clockcontrol(&bus->extif, &plltype,
94361e115a5SMichael Buesch 					   &clkctl_n, &clkctl_m);
94461e115a5SMichael Buesch 	else if (bus->chipco.dev)
94561e115a5SMichael Buesch 		ssb_chipco_get_clockcontrol(&bus->chipco, &plltype,
94661e115a5SMichael Buesch 					    &clkctl_n, &clkctl_m);
94761e115a5SMichael Buesch 	else
94861e115a5SMichael Buesch 		return 0;
94961e115a5SMichael Buesch 
95061e115a5SMichael Buesch 	if (bus->chip_id == 0x5365) {
95161e115a5SMichael Buesch 		rate = 100000000;
95261e115a5SMichael Buesch 	} else {
95361e115a5SMichael Buesch 		rate = ssb_calc_clock_rate(plltype, clkctl_n, clkctl_m);
95461e115a5SMichael Buesch 		if (plltype == SSB_PLLTYPE_3) /* 25Mhz, 2 dividers */
95561e115a5SMichael Buesch 			rate /= 2;
95661e115a5SMichael Buesch 	}
95761e115a5SMichael Buesch 
95861e115a5SMichael Buesch 	return rate;
95961e115a5SMichael Buesch }
96061e115a5SMichael Buesch EXPORT_SYMBOL(ssb_clockspeed);
96161e115a5SMichael Buesch 
96261e115a5SMichael Buesch static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
96361e115a5SMichael Buesch {
964c272ef44SLarry Finger 	u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
965c272ef44SLarry Finger 
96604ad1fb2SRafał Miłecki 	/* The REJECT bit seems to be different for Backplane rev 2.3 */
967c272ef44SLarry Finger 	switch (rev) {
96861e115a5SMichael Buesch 	case SSB_IDLOW_SSBREV_22:
96904ad1fb2SRafał Miłecki 	case SSB_IDLOW_SSBREV_24:
97004ad1fb2SRafał Miłecki 	case SSB_IDLOW_SSBREV_26:
97104ad1fb2SRafał Miłecki 		return SSB_TMSLOW_REJECT;
97261e115a5SMichael Buesch 	case SSB_IDLOW_SSBREV_23:
97361e115a5SMichael Buesch 		return SSB_TMSLOW_REJECT_23;
97404ad1fb2SRafał Miłecki 	case SSB_IDLOW_SSBREV_25:     /* TODO - find the proper REJECT bit */
975c272ef44SLarry Finger 	case SSB_IDLOW_SSBREV_27:     /* same here */
97604ad1fb2SRafał Miłecki 		return SSB_TMSLOW_REJECT;	/* this is a guess */
97716f7031aSLarry Finger 	case SSB_IDLOW_SSBREV:
97816f7031aSLarry Finger 		break;
97961e115a5SMichael Buesch 	default:
9806cdd6400SCong Ding 		WARN(1, KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
98161e115a5SMichael Buesch 	}
98204ad1fb2SRafał Miłecki 	return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
98361e115a5SMichael Buesch }
98461e115a5SMichael Buesch 
98561e115a5SMichael Buesch int ssb_device_is_enabled(struct ssb_device *dev)
98661e115a5SMichael Buesch {
98761e115a5SMichael Buesch 	u32 val;
98861e115a5SMichael Buesch 	u32 reject;
98961e115a5SMichael Buesch 
99061e115a5SMichael Buesch 	reject = ssb_tmslow_reject_bitmask(dev);
99161e115a5SMichael Buesch 	val = ssb_read32(dev, SSB_TMSLOW);
99261e115a5SMichael Buesch 	val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | reject;
99361e115a5SMichael Buesch 
99461e115a5SMichael Buesch 	return (val == SSB_TMSLOW_CLOCK);
99561e115a5SMichael Buesch }
99661e115a5SMichael Buesch EXPORT_SYMBOL(ssb_device_is_enabled);
99761e115a5SMichael Buesch 
99861e115a5SMichael Buesch static void ssb_flush_tmslow(struct ssb_device *dev)
99961e115a5SMichael Buesch {
100061e115a5SMichael Buesch 	/* Make _really_ sure the device has finished the TMSLOW
100161e115a5SMichael Buesch 	 * register write transaction, as we risk running into
100261e115a5SMichael Buesch 	 * a machine check exception otherwise.
100361e115a5SMichael Buesch 	 * Do this by reading the register back to commit the
100461e115a5SMichael Buesch 	 * PCI write and delay an additional usec for the device
100561e115a5SMichael Buesch 	 * to react to the change. */
100661e115a5SMichael Buesch 	ssb_read32(dev, SSB_TMSLOW);
100761e115a5SMichael Buesch 	udelay(1);
100861e115a5SMichael Buesch }
100961e115a5SMichael Buesch 
101061e115a5SMichael Buesch void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags)
101161e115a5SMichael Buesch {
101261e115a5SMichael Buesch 	u32 val;
101361e115a5SMichael Buesch 
101461e115a5SMichael Buesch 	ssb_device_disable(dev, core_specific_flags);
101561e115a5SMichael Buesch 	ssb_write32(dev, SSB_TMSLOW,
101661e115a5SMichael Buesch 		    SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK |
101761e115a5SMichael Buesch 		    SSB_TMSLOW_FGC | core_specific_flags);
101861e115a5SMichael Buesch 	ssb_flush_tmslow(dev);
101961e115a5SMichael Buesch 
102061e115a5SMichael Buesch 	/* Clear SERR if set. This is a hw bug workaround. */
102161e115a5SMichael Buesch 	if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR)
102261e115a5SMichael Buesch 		ssb_write32(dev, SSB_TMSHIGH, 0);
102361e115a5SMichael Buesch 
102461e115a5SMichael Buesch 	val = ssb_read32(dev, SSB_IMSTATE);
102561e115a5SMichael Buesch 	if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
102661e115a5SMichael Buesch 		val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
102761e115a5SMichael Buesch 		ssb_write32(dev, SSB_IMSTATE, val);
102861e115a5SMichael Buesch 	}
102961e115a5SMichael Buesch 
103061e115a5SMichael Buesch 	ssb_write32(dev, SSB_TMSLOW,
103161e115a5SMichael Buesch 		    SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC |
103261e115a5SMichael Buesch 		    core_specific_flags);
103361e115a5SMichael Buesch 	ssb_flush_tmslow(dev);
103461e115a5SMichael Buesch 
103561e115a5SMichael Buesch 	ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK |
103661e115a5SMichael Buesch 		    core_specific_flags);
103761e115a5SMichael Buesch 	ssb_flush_tmslow(dev);
103861e115a5SMichael Buesch }
103961e115a5SMichael Buesch EXPORT_SYMBOL(ssb_device_enable);
104061e115a5SMichael Buesch 
10418c68bd40SMichael Büsch /* Wait for bitmask in a register to get set or cleared.
104261e115a5SMichael Buesch  * timeout is in units of ten-microseconds */
10438c68bd40SMichael Büsch static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask,
104461e115a5SMichael Buesch 			 int timeout, int set)
104561e115a5SMichael Buesch {
104661e115a5SMichael Buesch 	int i;
104761e115a5SMichael Buesch 	u32 val;
104861e115a5SMichael Buesch 
104961e115a5SMichael Buesch 	for (i = 0; i < timeout; i++) {
105061e115a5SMichael Buesch 		val = ssb_read32(dev, reg);
105161e115a5SMichael Buesch 		if (set) {
10528c68bd40SMichael Büsch 			if ((val & bitmask) == bitmask)
105361e115a5SMichael Buesch 				return 0;
105461e115a5SMichael Buesch 		} else {
105561e115a5SMichael Buesch 			if (!(val & bitmask))
105661e115a5SMichael Buesch 				return 0;
105761e115a5SMichael Buesch 		}
105861e115a5SMichael Buesch 		udelay(10);
105961e115a5SMichael Buesch 	}
106061e115a5SMichael Buesch 	printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on "
106161e115a5SMichael Buesch 			    "register %04X to %s.\n",
106261e115a5SMichael Buesch 	       bitmask, reg, (set ? "set" : "clear"));
106361e115a5SMichael Buesch 
106461e115a5SMichael Buesch 	return -ETIMEDOUT;
106561e115a5SMichael Buesch }
106661e115a5SMichael Buesch 
106761e115a5SMichael Buesch void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
106861e115a5SMichael Buesch {
1069b1a1bcf7SRafał Miłecki 	u32 reject, val;
107061e115a5SMichael Buesch 
107161e115a5SMichael Buesch 	if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
107261e115a5SMichael Buesch 		return;
107361e115a5SMichael Buesch 
107461e115a5SMichael Buesch 	reject = ssb_tmslow_reject_bitmask(dev);
1075011d1835SRafał Miłecki 
1076011d1835SRafał Miłecki 	if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) {
107761e115a5SMichael Buesch 		ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
10788c68bd40SMichael Büsch 		ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1);
10798c68bd40SMichael Büsch 		ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
1080b1a1bcf7SRafał Miłecki 
1081b1a1bcf7SRafał Miłecki 		if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
1082b1a1bcf7SRafał Miłecki 			val = ssb_read32(dev, SSB_IMSTATE);
1083b1a1bcf7SRafał Miłecki 			val |= SSB_IMSTATE_REJECT;
1084b1a1bcf7SRafał Miłecki 			ssb_write32(dev, SSB_IMSTATE, val);
1085011d1835SRafał Miłecki 			ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000,
1086011d1835SRafał Miłecki 				      0);
1087b1a1bcf7SRafał Miłecki 		}
1088b1a1bcf7SRafał Miłecki 
108961e115a5SMichael Buesch 		ssb_write32(dev, SSB_TMSLOW,
109061e115a5SMichael Buesch 			SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
109161e115a5SMichael Buesch 			reject | SSB_TMSLOW_RESET |
109261e115a5SMichael Buesch 			core_specific_flags);
109361e115a5SMichael Buesch 		ssb_flush_tmslow(dev);
109461e115a5SMichael Buesch 
1095b1a1bcf7SRafał Miłecki 		if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
1096b1a1bcf7SRafał Miłecki 			val = ssb_read32(dev, SSB_IMSTATE);
1097b1a1bcf7SRafał Miłecki 			val &= ~SSB_IMSTATE_REJECT;
1098b1a1bcf7SRafał Miłecki 			ssb_write32(dev, SSB_IMSTATE, val);
1099b1a1bcf7SRafał Miłecki 		}
1100011d1835SRafał Miłecki 	}
1101b1a1bcf7SRafał Miłecki 
110261e115a5SMichael Buesch 	ssb_write32(dev, SSB_TMSLOW,
110361e115a5SMichael Buesch 		    reject | SSB_TMSLOW_RESET |
110461e115a5SMichael Buesch 		    core_specific_flags);
110561e115a5SMichael Buesch 	ssb_flush_tmslow(dev);
110661e115a5SMichael Buesch }
110761e115a5SMichael Buesch EXPORT_SYMBOL(ssb_device_disable);
110861e115a5SMichael Buesch 
110904023afcSRafał Miłecki /* Some chipsets need routing known for PCIe and 64-bit DMA */
111004023afcSRafał Miłecki static bool ssb_dma_translation_special_bit(struct ssb_device *dev)
111104023afcSRafał Miłecki {
111204023afcSRafał Miłecki 	u16 chip_id = dev->bus->chip_id;
111304023afcSRafał Miłecki 
111404023afcSRafał Miłecki 	if (dev->id.coreid == SSB_DEV_80211) {
111504023afcSRafał Miłecki 		return (chip_id == 0x4322 || chip_id == 43221 ||
111604023afcSRafał Miłecki 			chip_id == 43231 || chip_id == 43222);
111704023afcSRafał Miłecki 	}
111804023afcSRafał Miłecki 
1119bd42cd02SGustavo A. R. Silva 	return false;
112004023afcSRafał Miłecki }
112104023afcSRafał Miłecki 
112261e115a5SMichael Buesch u32 ssb_dma_translation(struct ssb_device *dev)
112361e115a5SMichael Buesch {
112461e115a5SMichael Buesch 	switch (dev->bus->bustype) {
112561e115a5SMichael Buesch 	case SSB_BUSTYPE_SSB:
112661e115a5SMichael Buesch 		return 0;
112761e115a5SMichael Buesch 	case SSB_BUSTYPE_PCI:
112804023afcSRafał Miłecki 		if (pci_is_pcie(dev->bus->host_pci) &&
112904023afcSRafał Miłecki 		    ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) {
113004023afcSRafał Miłecki 			return SSB_PCIE_DMA_H32;
113104023afcSRafał Miłecki 		} else {
113204023afcSRafał Miłecki 			if (ssb_dma_translation_special_bit(dev))
1133a9770a81SRafał Miłecki 				return SSB_PCIE_DMA_H32;
1134a9770a81SRafał Miłecki 			else
113561e115a5SMichael Buesch 				return SSB_PCI_DMA;
113604023afcSRafał Miłecki 		}
1137f225763aSMichael Buesch 	default:
1138f225763aSMichael Buesch 		__ssb_dma_not_implemented(dev);
113961e115a5SMichael Buesch 	}
114061e115a5SMichael Buesch 	return 0;
114161e115a5SMichael Buesch }
114261e115a5SMichael Buesch EXPORT_SYMBOL(ssb_dma_translation);
114361e115a5SMichael Buesch 
114461e115a5SMichael Buesch int ssb_bus_may_powerdown(struct ssb_bus *bus)
114561e115a5SMichael Buesch {
114661e115a5SMichael Buesch 	struct ssb_chipcommon *cc;
114761e115a5SMichael Buesch 	int err = 0;
114861e115a5SMichael Buesch 
114961e115a5SMichael Buesch 	/* On buses where more than one core may be working
115061e115a5SMichael Buesch 	 * at a time, we must not powerdown stuff if there are
115161e115a5SMichael Buesch 	 * still cores that may want to run. */
115261e115a5SMichael Buesch 	if (bus->bustype == SSB_BUSTYPE_SSB)
115361e115a5SMichael Buesch 		goto out;
115461e115a5SMichael Buesch 
115561e115a5SMichael Buesch 	cc = &bus->chipco;
1156881400a2SStefano Brivio 
1157881400a2SStefano Brivio 	if (!cc->dev)
1158881400a2SStefano Brivio 		goto out;
1159881400a2SStefano Brivio 	if (cc->dev->id.revision < 5)
1160881400a2SStefano Brivio 		goto out;
1161881400a2SStefano Brivio 
116261e115a5SMichael Buesch 	ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);
116361e115a5SMichael Buesch 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
116461e115a5SMichael Buesch 	if (err)
116561e115a5SMichael Buesch 		goto error;
116661e115a5SMichael Buesch out:
116761e115a5SMichael Buesch #ifdef CONFIG_SSB_DEBUG
116861e115a5SMichael Buesch 	bus->powered_up = 0;
116961e115a5SMichael Buesch #endif
117061e115a5SMichael Buesch 	return err;
117161e115a5SMichael Buesch error:
117233a606acSJoe Perches 	ssb_err("Bus powerdown failed\n");
117361e115a5SMichael Buesch 	goto out;
117461e115a5SMichael Buesch }
117561e115a5SMichael Buesch EXPORT_SYMBOL(ssb_bus_may_powerdown);
117661e115a5SMichael Buesch 
117761e115a5SMichael Buesch int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
117861e115a5SMichael Buesch {
117961e115a5SMichael Buesch 	int err;
118061e115a5SMichael Buesch 	enum ssb_clkmode mode;
118161e115a5SMichael Buesch 
118261e115a5SMichael Buesch 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
118361e115a5SMichael Buesch 	if (err)
118461e115a5SMichael Buesch 		goto error;
118561e115a5SMichael Buesch 
118661e115a5SMichael Buesch #ifdef CONFIG_SSB_DEBUG
118761e115a5SMichael Buesch 	bus->powered_up = 1;
118861e115a5SMichael Buesch #endif
1189a6ef8143SRafał Miłecki 
1190a6ef8143SRafał Miłecki 	mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
1191a6ef8143SRafał Miłecki 	ssb_chipco_set_clockmode(&bus->chipco, mode);
1192a6ef8143SRafał Miłecki 
119361e115a5SMichael Buesch 	return 0;
119461e115a5SMichael Buesch error:
119533a606acSJoe Perches 	ssb_err("Bus powerup failed\n");
119661e115a5SMichael Buesch 	return err;
119761e115a5SMichael Buesch }
119861e115a5SMichael Buesch EXPORT_SYMBOL(ssb_bus_powerup);
119961e115a5SMichael Buesch 
12008576f815SRafał Miłecki static void ssb_broadcast_value(struct ssb_device *dev,
12018576f815SRafał Miłecki 				u32 address, u32 data)
12028576f815SRafał Miłecki {
12031159024dSJohn W. Linville #ifdef CONFIG_SSB_DRIVER_PCICORE
12048576f815SRafał Miłecki 	/* This is used for both, PCI and ChipCommon core, so be careful. */
12058576f815SRafał Miłecki 	BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
12068576f815SRafał Miłecki 	BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
12071159024dSJohn W. Linville #endif
12088576f815SRafał Miłecki 
12091159024dSJohn W. Linville 	ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
12101159024dSJohn W. Linville 	ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
12111159024dSJohn W. Linville 	ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
12121159024dSJohn W. Linville 	ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
12138576f815SRafał Miłecki }
12148576f815SRafał Miłecki 
12158576f815SRafał Miłecki void ssb_commit_settings(struct ssb_bus *bus)
12168576f815SRafał Miłecki {
12178576f815SRafał Miłecki 	struct ssb_device *dev;
12188576f815SRafał Miłecki 
12191159024dSJohn W. Linville #ifdef CONFIG_SSB_DRIVER_PCICORE
12208576f815SRafał Miłecki 	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
12211159024dSJohn W. Linville #else
12221159024dSJohn W. Linville 	dev = bus->chipco.dev;
12231159024dSJohn W. Linville #endif
12248576f815SRafał Miłecki 	if (WARN_ON(!dev))
12258576f815SRafał Miłecki 		return;
12268576f815SRafał Miłecki 	/* This forces an update of the cached registers. */
12278576f815SRafał Miłecki 	ssb_broadcast_value(dev, 0xFD8, 0);
12288576f815SRafał Miłecki }
12298576f815SRafał Miłecki EXPORT_SYMBOL(ssb_commit_settings);
12308576f815SRafał Miłecki 
123161e115a5SMichael Buesch u32 ssb_admatch_base(u32 adm)
123261e115a5SMichael Buesch {
123361e115a5SMichael Buesch 	u32 base = 0;
123461e115a5SMichael Buesch 
123561e115a5SMichael Buesch 	switch (adm & SSB_ADM_TYPE) {
123661e115a5SMichael Buesch 	case SSB_ADM_TYPE0:
123761e115a5SMichael Buesch 		base = (adm & SSB_ADM_BASE0);
123861e115a5SMichael Buesch 		break;
123961e115a5SMichael Buesch 	case SSB_ADM_TYPE1:
124061e115a5SMichael Buesch 		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
124161e115a5SMichael Buesch 		base = (adm & SSB_ADM_BASE1);
124261e115a5SMichael Buesch 		break;
124361e115a5SMichael Buesch 	case SSB_ADM_TYPE2:
124461e115a5SMichael Buesch 		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
124561e115a5SMichael Buesch 		base = (adm & SSB_ADM_BASE2);
124661e115a5SMichael Buesch 		break;
124761e115a5SMichael Buesch 	default:
124861e115a5SMichael Buesch 		SSB_WARN_ON(1);
124961e115a5SMichael Buesch 	}
125061e115a5SMichael Buesch 
125161e115a5SMichael Buesch 	return base;
125261e115a5SMichael Buesch }
125361e115a5SMichael Buesch EXPORT_SYMBOL(ssb_admatch_base);
125461e115a5SMichael Buesch 
125561e115a5SMichael Buesch u32 ssb_admatch_size(u32 adm)
125661e115a5SMichael Buesch {
125761e115a5SMichael Buesch 	u32 size = 0;
125861e115a5SMichael Buesch 
125961e115a5SMichael Buesch 	switch (adm & SSB_ADM_TYPE) {
126061e115a5SMichael Buesch 	case SSB_ADM_TYPE0:
126161e115a5SMichael Buesch 		size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT);
126261e115a5SMichael Buesch 		break;
126361e115a5SMichael Buesch 	case SSB_ADM_TYPE1:
126461e115a5SMichael Buesch 		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
126561e115a5SMichael Buesch 		size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT);
126661e115a5SMichael Buesch 		break;
126761e115a5SMichael Buesch 	case SSB_ADM_TYPE2:
126861e115a5SMichael Buesch 		SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
126961e115a5SMichael Buesch 		size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT);
127061e115a5SMichael Buesch 		break;
127161e115a5SMichael Buesch 	default:
127261e115a5SMichael Buesch 		SSB_WARN_ON(1);
127361e115a5SMichael Buesch 	}
127461e115a5SMichael Buesch 	size = (1 << (size + 1));
127561e115a5SMichael Buesch 
127661e115a5SMichael Buesch 	return size;
127761e115a5SMichael Buesch }
127861e115a5SMichael Buesch EXPORT_SYMBOL(ssb_admatch_size);
127961e115a5SMichael Buesch 
128061e115a5SMichael Buesch static int __init ssb_modinit(void)
128161e115a5SMichael Buesch {
128261e115a5SMichael Buesch 	int err;
128361e115a5SMichael Buesch 
128461e115a5SMichael Buesch 	/* See the comment at the ssb_is_early_boot definition */
128561e115a5SMichael Buesch 	ssb_is_early_boot = 0;
128661e115a5SMichael Buesch 	err = bus_register(&ssb_bustype);
128761e115a5SMichael Buesch 	if (err)
128861e115a5SMichael Buesch 		return err;
128961e115a5SMichael Buesch 
129061e115a5SMichael Buesch 	/* Maybe we already registered some buses at early boot.
129161e115a5SMichael Buesch 	 * Check for this and attach them
129261e115a5SMichael Buesch 	 */
129361e115a5SMichael Buesch 	ssb_buses_lock();
129461e115a5SMichael Buesch 	err = ssb_attach_queued_buses();
129561e115a5SMichael Buesch 	ssb_buses_unlock();
1296e6c463e3SMichael Buesch 	if (err) {
129761e115a5SMichael Buesch 		bus_unregister(&ssb_bustype);
1298e6c463e3SMichael Buesch 		goto out;
1299e6c463e3SMichael Buesch 	}
130061e115a5SMichael Buesch 
130161e115a5SMichael Buesch 	err = b43_pci_ssb_bridge_init();
130261e115a5SMichael Buesch 	if (err) {
130333a606acSJoe Perches 		ssb_err("Broadcom 43xx PCI-SSB-bridge initialization failed\n");
1304aab547ceSMichael Buesch 		/* don't fail SSB init because of this */
1305aab547ceSMichael Buesch 		err = 0;
1306aab547ceSMichael Buesch 	}
1307399500daSRafał Miłecki 	err = ssb_host_pcmcia_init();
1308399500daSRafał Miłecki 	if (err) {
1309399500daSRafał Miłecki 		ssb_err("PCMCIA host initialization failed\n");
1310399500daSRafał Miłecki 		/* don't fail SSB init because of this */
1311399500daSRafał Miłecki 		err = 0;
1312399500daSRafał Miłecki 	}
1313aab547ceSMichael Buesch 	err = ssb_gige_init();
1314aab547ceSMichael Buesch 	if (err) {
131533a606acSJoe Perches 		ssb_err("SSB Broadcom Gigabit Ethernet driver initialization failed\n");
131661e115a5SMichael Buesch 		/* don't fail SSB init because of this */
131761e115a5SMichael Buesch 		err = 0;
131861e115a5SMichael Buesch 	}
1319e6c463e3SMichael Buesch out:
132061e115a5SMichael Buesch 	return err;
132161e115a5SMichael Buesch }
13228d8c90e3SMichael Buesch /* ssb must be initialized after PCI but before the ssb drivers.
13238d8c90e3SMichael Buesch  * That means we must use some initcall between subsys_initcall
13248d8c90e3SMichael Buesch  * and device_initcall. */
13258d8c90e3SMichael Buesch fs_initcall(ssb_modinit);
132661e115a5SMichael Buesch 
132761e115a5SMichael Buesch static void __exit ssb_modexit(void)
132861e115a5SMichael Buesch {
1329aab547ceSMichael Buesch 	ssb_gige_exit();
1330399500daSRafał Miłecki 	ssb_host_pcmcia_exit();
133161e115a5SMichael Buesch 	b43_pci_ssb_bridge_exit();
133261e115a5SMichael Buesch 	bus_unregister(&ssb_bustype);
133361e115a5SMichael Buesch }
133461e115a5SMichael Buesch module_exit(ssb_modexit)
1335