xref: /openbmc/linux/drivers/ssb/driver_mipscore.c (revision df561f66)
161e115a5SMichael Buesch /*
261e115a5SMichael Buesch  * Sonics Silicon Backplane
361e115a5SMichael Buesch  * Broadcom MIPS core driver
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 
11b8b6069cSMichael Büsch #include "ssb_private.h"
12b8b6069cSMichael Büsch 
1361e115a5SMichael Buesch #include <linux/ssb/ssb.h>
1461e115a5SMichael Buesch 
15c7a4a9e3SRafał Miłecki #include <linux/mtd/physmap.h>
1661e115a5SMichael Buesch #include <linux/serial.h>
1761e115a5SMichael Buesch #include <linux/serial_core.h>
1861e115a5SMichael Buesch #include <linux/serial_reg.h>
1961e115a5SMichael Buesch #include <linux/time.h>
2021400f25SRafał Miłecki #ifdef CONFIG_BCM47XX
21138173d4SRafał Miłecki #include <linux/bcm47xx_nvram.h>
2221400f25SRafał Miłecki #endif
2361e115a5SMichael Buesch 
24255e9fd4SArtem Bityutskiy static const char * const part_probes[] = { "bcm47xxpart", NULL };
25c7a4a9e3SRafał Miłecki 
26c7a4a9e3SRafał Miłecki static struct physmap_flash_data ssb_pflash_data = {
27c7a4a9e3SRafał Miłecki 	.part_probe_types	= part_probes,
28c7a4a9e3SRafał Miłecki };
29c7a4a9e3SRafał Miłecki 
30c7a4a9e3SRafał Miłecki static struct resource ssb_pflash_resource = {
31c7a4a9e3SRafał Miłecki 	.name	= "ssb_pflash",
32c7a4a9e3SRafał Miłecki 	.flags  = IORESOURCE_MEM,
33c7a4a9e3SRafał Miłecki };
34c7a4a9e3SRafał Miłecki 
35c7a4a9e3SRafał Miłecki struct platform_device ssb_pflash_dev = {
36c7a4a9e3SRafał Miłecki 	.name		= "physmap-flash",
37c7a4a9e3SRafał Miłecki 	.dev		= {
38c7a4a9e3SRafał Miłecki 		.platform_data  = &ssb_pflash_data,
39c7a4a9e3SRafał Miłecki 	},
40c7a4a9e3SRafał Miłecki 	.resource	= &ssb_pflash_resource,
41c7a4a9e3SRafał Miłecki 	.num_resources	= 1,
42c7a4a9e3SRafał Miłecki };
4361e115a5SMichael Buesch 
mips_read32(struct ssb_mipscore * mcore,u16 offset)4461e115a5SMichael Buesch static inline u32 mips_read32(struct ssb_mipscore *mcore,
4561e115a5SMichael Buesch 			      u16 offset)
4661e115a5SMichael Buesch {
4761e115a5SMichael Buesch 	return ssb_read32(mcore->dev, offset);
4861e115a5SMichael Buesch }
4961e115a5SMichael Buesch 
mips_write32(struct ssb_mipscore * mcore,u16 offset,u32 value)5061e115a5SMichael Buesch static inline void mips_write32(struct ssb_mipscore *mcore,
5161e115a5SMichael Buesch 				u16 offset,
5261e115a5SMichael Buesch 				u32 value)
5361e115a5SMichael Buesch {
5461e115a5SMichael Buesch 	ssb_write32(mcore->dev, offset, value);
5561e115a5SMichael Buesch }
5661e115a5SMichael Buesch 
5761e115a5SMichael Buesch static const u32 ipsflag_irq_mask[] = {
5861e115a5SMichael Buesch 	0,
5961e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ1,
6061e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ2,
6161e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ3,
6261e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ4,
6361e115a5SMichael Buesch };
6461e115a5SMichael Buesch 
6561e115a5SMichael Buesch static const u32 ipsflag_irq_shift[] = {
6661e115a5SMichael Buesch 	0,
6761e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ1_SHIFT,
6861e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ2_SHIFT,
6961e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ3_SHIFT,
7061e115a5SMichael Buesch 	SSB_IPSFLAG_IRQ4_SHIFT,
7161e115a5SMichael Buesch };
7261e115a5SMichael Buesch 
ssb_irqflag(struct ssb_device * dev)7361e115a5SMichael Buesch static inline u32 ssb_irqflag(struct ssb_device *dev)
7461e115a5SMichael Buesch {
75ea4bbfd0Smatthieu castet 	u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG);
76ea4bbfd0Smatthieu castet 	if (tpsflag)
7761e115a5SMichael Buesch 		return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
78ea4bbfd0Smatthieu castet 	else
79ea4bbfd0Smatthieu castet 		/* not irq supported */
80ea4bbfd0Smatthieu castet 		return 0x3f;
81ea4bbfd0Smatthieu castet }
82ea4bbfd0Smatthieu castet 
find_device(struct ssb_device * rdev,int irqflag)83ea4bbfd0Smatthieu castet static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag)
84ea4bbfd0Smatthieu castet {
85ea4bbfd0Smatthieu castet 	struct ssb_bus *bus = rdev->bus;
86ea4bbfd0Smatthieu castet 	int i;
87ea4bbfd0Smatthieu castet 	for (i = 0; i < bus->nr_devices; i++) {
88ea4bbfd0Smatthieu castet 		struct ssb_device *dev;
89ea4bbfd0Smatthieu castet 		dev = &(bus->devices[i]);
90ea4bbfd0Smatthieu castet 		if (ssb_irqflag(dev) == irqflag)
91ea4bbfd0Smatthieu castet 			return dev;
92ea4bbfd0Smatthieu castet 	}
93ea4bbfd0Smatthieu castet 	return NULL;
9461e115a5SMichael Buesch }
9561e115a5SMichael Buesch 
9661e115a5SMichael Buesch /* Get the MIPS IRQ assignment for a specified device.
9761e115a5SMichael Buesch  * If unassigned, 0 is returned.
98ea4bbfd0Smatthieu castet  * If disabled, 5 is returned.
99ea4bbfd0Smatthieu castet  * If not supported, 6 is returned.
10061e115a5SMichael Buesch  */
ssb_mips_irq(struct ssb_device * dev)10161e115a5SMichael Buesch unsigned int ssb_mips_irq(struct ssb_device *dev)
10261e115a5SMichael Buesch {
10361e115a5SMichael Buesch 	struct ssb_bus *bus = dev->bus;
104ea4bbfd0Smatthieu castet 	struct ssb_device *mdev = bus->mipscore.dev;
10561e115a5SMichael Buesch 	u32 irqflag;
10661e115a5SMichael Buesch 	u32 ipsflag;
10761e115a5SMichael Buesch 	u32 tmp;
10861e115a5SMichael Buesch 	unsigned int irq;
10961e115a5SMichael Buesch 
11061e115a5SMichael Buesch 	irqflag = ssb_irqflag(dev);
111ea4bbfd0Smatthieu castet 	if (irqflag == 0x3f)
112ea4bbfd0Smatthieu castet 		return 6;
11361e115a5SMichael Buesch 	ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG);
11461e115a5SMichael Buesch 	for (irq = 1; irq <= 4; irq++) {
11561e115a5SMichael Buesch 		tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]);
11661e115a5SMichael Buesch 		if (tmp == irqflag)
11761e115a5SMichael Buesch 			break;
11861e115a5SMichael Buesch 	}
119ea4bbfd0Smatthieu castet 	if (irq	== 5) {
120ea4bbfd0Smatthieu castet 		if ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))
12161e115a5SMichael Buesch 			irq = 0;
122ea4bbfd0Smatthieu castet 	}
12361e115a5SMichael Buesch 
12461e115a5SMichael Buesch 	return irq;
12561e115a5SMichael Buesch }
12661e115a5SMichael Buesch 
clear_irq(struct ssb_bus * bus,unsigned int irq)12761e115a5SMichael Buesch static void clear_irq(struct ssb_bus *bus, unsigned int irq)
12861e115a5SMichael Buesch {
12961e115a5SMichael Buesch 	struct ssb_device *dev = bus->mipscore.dev;
13061e115a5SMichael Buesch 
13161e115a5SMichael Buesch 	/* Clear the IRQ in the MIPScore backplane registers */
13261e115a5SMichael Buesch 	if (irq == 0) {
13361e115a5SMichael Buesch 		ssb_write32(dev, SSB_INTVEC, 0);
13461e115a5SMichael Buesch 	} else {
13561e115a5SMichael Buesch 		ssb_write32(dev, SSB_IPSFLAG,
13661e115a5SMichael Buesch 			    ssb_read32(dev, SSB_IPSFLAG) |
13761e115a5SMichael Buesch 			    ipsflag_irq_mask[irq]);
13861e115a5SMichael Buesch 	}
13961e115a5SMichael Buesch }
14061e115a5SMichael Buesch 
set_irq(struct ssb_device * dev,unsigned int irq)14161e115a5SMichael Buesch static void set_irq(struct ssb_device *dev, unsigned int irq)
14261e115a5SMichael Buesch {
14361e115a5SMichael Buesch 	unsigned int oldirq = ssb_mips_irq(dev);
14461e115a5SMichael Buesch 	struct ssb_bus *bus = dev->bus;
14561e115a5SMichael Buesch 	struct ssb_device *mdev = bus->mipscore.dev;
14661e115a5SMichael Buesch 	u32 irqflag = ssb_irqflag(dev);
14761e115a5SMichael Buesch 
148ea4bbfd0Smatthieu castet 	BUG_ON(oldirq == 6);
149ea4bbfd0Smatthieu castet 
15061e115a5SMichael Buesch 	dev->irq = irq + 2;
15161e115a5SMichael Buesch 
15261e115a5SMichael Buesch 	/* clear the old irq */
15361e115a5SMichael Buesch 	if (oldirq == 0)
15461e115a5SMichael Buesch 		ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
155ea4bbfd0Smatthieu castet 	else if (oldirq != 5)
15661e115a5SMichael Buesch 		clear_irq(bus, oldirq);
15761e115a5SMichael Buesch 
15861e115a5SMichael Buesch 	/* assign the new one */
1592633da23SMichael Buesch 	if (irq == 0) {
1602633da23SMichael Buesch 		ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC)));
1612633da23SMichael Buesch 	} else {
162ea4bbfd0Smatthieu castet 		u32 ipsflag = ssb_read32(mdev, SSB_IPSFLAG);
163ea4bbfd0Smatthieu castet 		if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) {
164ea4bbfd0Smatthieu castet 			u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq];
165ea4bbfd0Smatthieu castet 			struct ssb_device *olddev = find_device(dev, oldipsflag);
166ea4bbfd0Smatthieu castet 			if (olddev)
167ea4bbfd0Smatthieu castet 				set_irq(olddev, 0);
168ea4bbfd0Smatthieu castet 		}
16961e115a5SMichael Buesch 		irqflag <<= ipsflag_irq_shift[irq];
170ea4bbfd0Smatthieu castet 		irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]);
17161e115a5SMichael Buesch 		ssb_write32(mdev, SSB_IPSFLAG, irqflag);
17261e115a5SMichael Buesch 	}
173b8b6069cSMichael Büsch 	dev_dbg(dev->dev, "set_irq: core 0x%04x, irq %d => %d\n",
174ea4bbfd0Smatthieu castet 		dev->id.coreid, oldirq+2, irq+2);
175ea4bbfd0Smatthieu castet }
176ea4bbfd0Smatthieu castet 
print_irq(struct ssb_device * dev,unsigned int irq)177ea4bbfd0Smatthieu castet static void print_irq(struct ssb_device *dev, unsigned int irq)
178ea4bbfd0Smatthieu castet {
179ea4bbfd0Smatthieu castet 	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
180b8b6069cSMichael Büsch 	dev_dbg(dev->dev,
181b8b6069cSMichael Büsch 		"core 0x%04x, irq : %s%s %s%s %s%s %s%s %s%s %s%s %s%s\n",
18233a606acSJoe Perches 		dev->id.coreid,
18333a606acSJoe Perches 		irq_name[0], irq == 0 ? "*" : " ",
18433a606acSJoe Perches 		irq_name[1], irq == 1 ? "*" : " ",
18533a606acSJoe Perches 		irq_name[2], irq == 2 ? "*" : " ",
18633a606acSJoe Perches 		irq_name[3], irq == 3 ? "*" : " ",
18733a606acSJoe Perches 		irq_name[4], irq == 4 ? "*" : " ",
18833a606acSJoe Perches 		irq_name[5], irq == 5 ? "*" : " ",
18933a606acSJoe Perches 		irq_name[6], irq == 6 ? "*" : " ");
190ea4bbfd0Smatthieu castet }
191ea4bbfd0Smatthieu castet 
dump_irq(struct ssb_bus * bus)192ea4bbfd0Smatthieu castet static void dump_irq(struct ssb_bus *bus)
193ea4bbfd0Smatthieu castet {
194ea4bbfd0Smatthieu castet 	int i;
195ea4bbfd0Smatthieu castet 	for (i = 0; i < bus->nr_devices; i++) {
196ea4bbfd0Smatthieu castet 		struct ssb_device *dev;
197ea4bbfd0Smatthieu castet 		dev = &(bus->devices[i]);
198ea4bbfd0Smatthieu castet 		print_irq(dev, ssb_mips_irq(dev));
199ea4bbfd0Smatthieu castet 	}
2002633da23SMichael Buesch }
20161e115a5SMichael Buesch 
ssb_mips_serial_init(struct ssb_mipscore * mcore)20261e115a5SMichael Buesch static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
20361e115a5SMichael Buesch {
20461e115a5SMichael Buesch 	struct ssb_bus *bus = mcore->dev->bus;
20561e115a5SMichael Buesch 
2060362063bSHauke Mehrtens 	if (ssb_extif_available(&bus->extif))
20761e115a5SMichael Buesch 		mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
2080362063bSHauke Mehrtens 	else if (ssb_chipco_available(&bus->chipco))
20961e115a5SMichael Buesch 		mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
21061e115a5SMichael Buesch 	else
21161e115a5SMichael Buesch 		mcore->nr_serial_ports = 0;
21261e115a5SMichael Buesch }
21361e115a5SMichael Buesch 
ssb_mips_flash_detect(struct ssb_mipscore * mcore)21461e115a5SMichael Buesch static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
21561e115a5SMichael Buesch {
21661e115a5SMichael Buesch 	struct ssb_bus *bus = mcore->dev->bus;
21721400f25SRafał Miłecki 	struct ssb_sflash *sflash = &mcore->sflash;
218f1ab57e3SRafał Miłecki 	struct ssb_pflash *pflash = &mcore->pflash;
21961e115a5SMichael Buesch 
220902d9e0fSRafał Miłecki 	/* When there is no chipcommon on the bus there is 4MB flash */
2210362063bSHauke Mehrtens 	if (!ssb_chipco_available(&bus->chipco)) {
222f1ab57e3SRafał Miłecki 		pflash->present = true;
223f1ab57e3SRafał Miłecki 		pflash->buswidth = 2;
224f1ab57e3SRafał Miłecki 		pflash->window = SSB_FLASH1;
225f1ab57e3SRafał Miłecki 		pflash->window_size = SSB_FLASH1_SZ;
226c7a4a9e3SRafał Miłecki 		goto ssb_pflash;
227902d9e0fSRafał Miłecki 	}
228902d9e0fSRafał Miłecki 
229902d9e0fSRafał Miłecki 	/* There is ChipCommon, so use it to read info about flash */
230902d9e0fSRafał Miłecki 	switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
231902d9e0fSRafał Miłecki 	case SSB_CHIPCO_FLASHT_STSER:
232902d9e0fSRafał Miłecki 	case SSB_CHIPCO_FLASHT_ATSER:
233b8b6069cSMichael Büsch 		dev_dbg(mcore->dev->dev, "Found serial flash\n");
23472a525cbSRafał Miłecki 		ssb_sflash_init(&bus->chipco);
235902d9e0fSRafał Miłecki 		break;
236902d9e0fSRafał Miłecki 	case SSB_CHIPCO_FLASHT_PARA:
237b8b6069cSMichael Büsch 		dev_dbg(mcore->dev->dev, "Found parallel flash\n");
238f1ab57e3SRafał Miłecki 		pflash->present = true;
239f1ab57e3SRafał Miłecki 		pflash->window = SSB_FLASH2;
240f1ab57e3SRafał Miłecki 		pflash->window_size = SSB_FLASH2_SZ;
24161e115a5SMichael Buesch 		if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
24261e115a5SMichael Buesch 		               & SSB_CHIPCO_CFG_DS16) == 0)
243f1ab57e3SRafał Miłecki 			pflash->buswidth = 1;
244902d9e0fSRafał Miłecki 		else
245f1ab57e3SRafał Miłecki 			pflash->buswidth = 2;
246902d9e0fSRafał Miłecki 		break;
24761e115a5SMichael Buesch 	}
248c7a4a9e3SRafał Miłecki 
249c7a4a9e3SRafał Miłecki ssb_pflash:
25021400f25SRafał Miłecki 	if (sflash->present) {
25121400f25SRafał Miłecki #ifdef CONFIG_BCM47XX
25221400f25SRafał Miłecki 		bcm47xx_nvram_init_from_mem(sflash->window, sflash->size);
25321400f25SRafał Miłecki #endif
25421400f25SRafał Miłecki 	} else if (pflash->present) {
25521400f25SRafał Miłecki #ifdef CONFIG_BCM47XX
25621400f25SRafał Miłecki 		bcm47xx_nvram_init_from_mem(pflash->window, pflash->window_size);
25721400f25SRafał Miłecki #endif
25821400f25SRafał Miłecki 
259c7a4a9e3SRafał Miłecki 		ssb_pflash_data.width = pflash->buswidth;
260c7a4a9e3SRafał Miłecki 		ssb_pflash_resource.start = pflash->window;
261c7a4a9e3SRafał Miłecki 		ssb_pflash_resource.end = pflash->window + pflash->window_size;
262c7a4a9e3SRafał Miłecki 	}
26361e115a5SMichael Buesch }
26461e115a5SMichael Buesch 
ssb_cpu_clock(struct ssb_mipscore * mcore)26561e115a5SMichael Buesch u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
26661e115a5SMichael Buesch {
26761e115a5SMichael Buesch 	struct ssb_bus *bus = mcore->dev->bus;
26861e115a5SMichael Buesch 	u32 pll_type, n, m, rate = 0;
26961e115a5SMichael Buesch 
270d486a5b4SHauke Mehrtens 	if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
271d486a5b4SHauke Mehrtens 		return ssb_pmu_get_cpu_clock(&bus->chipco);
272d486a5b4SHauke Mehrtens 
2730362063bSHauke Mehrtens 	if (ssb_extif_available(&bus->extif)) {
27461e115a5SMichael Buesch 		ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
2750362063bSHauke Mehrtens 	} else if (ssb_chipco_available(&bus->chipco)) {
27661e115a5SMichael Buesch 		ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
27761e115a5SMichael Buesch 	} else
27861e115a5SMichael Buesch 		return 0;
27961e115a5SMichael Buesch 
28061e115a5SMichael Buesch 	if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) {
28161e115a5SMichael Buesch 		rate = 200000000;
28261e115a5SMichael Buesch 	} else {
28361e115a5SMichael Buesch 		rate = ssb_calc_clock_rate(pll_type, n, m);
28461e115a5SMichael Buesch 	}
28561e115a5SMichael Buesch 
28661e115a5SMichael Buesch 	if (pll_type == SSB_PLLTYPE_6) {
28761e115a5SMichael Buesch 		rate *= 2;
28861e115a5SMichael Buesch 	}
28961e115a5SMichael Buesch 
29061e115a5SMichael Buesch 	return rate;
29161e115a5SMichael Buesch }
29261e115a5SMichael Buesch 
ssb_mipscore_init(struct ssb_mipscore * mcore)29361e115a5SMichael Buesch void ssb_mipscore_init(struct ssb_mipscore *mcore)
29461e115a5SMichael Buesch {
2957007d00cSFelix Fietkau 	struct ssb_bus *bus;
29661e115a5SMichael Buesch 	struct ssb_device *dev;
29761e115a5SMichael Buesch 	unsigned long hz, ns;
29861e115a5SMichael Buesch 	unsigned int irq, i;
29961e115a5SMichael Buesch 
30061e115a5SMichael Buesch 	if (!mcore->dev)
30161e115a5SMichael Buesch 		return; /* We don't have a MIPS core */
30261e115a5SMichael Buesch 
303b8b6069cSMichael Büsch 	dev_dbg(mcore->dev->dev, "Initializing MIPS core...\n");
30461e115a5SMichael Buesch 
3057007d00cSFelix Fietkau 	bus = mcore->dev->bus;
30661e115a5SMichael Buesch 	hz = ssb_clockspeed(bus);
30761e115a5SMichael Buesch 	if (!hz)
30861e115a5SMichael Buesch 		hz = 100000000;
30961e115a5SMichael Buesch 	ns = 1000000000 / hz;
31061e115a5SMichael Buesch 
3110362063bSHauke Mehrtens 	if (ssb_extif_available(&bus->extif))
31261e115a5SMichael Buesch 		ssb_extif_timing_init(&bus->extif, ns);
3130362063bSHauke Mehrtens 	else if (ssb_chipco_available(&bus->chipco))
31461e115a5SMichael Buesch 		ssb_chipco_timing_init(&bus->chipco, ns);
31561e115a5SMichael Buesch 
31661e115a5SMichael Buesch 	/* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
31761e115a5SMichael Buesch 	for (irq = 2, i = 0; i < bus->nr_devices; i++) {
318ea4bbfd0Smatthieu castet 		int mips_irq;
31961e115a5SMichael Buesch 		dev = &(bus->devices[i]);
320ea4bbfd0Smatthieu castet 		mips_irq = ssb_mips_irq(dev);
321ea4bbfd0Smatthieu castet 		if (mips_irq > 4)
322ea4bbfd0Smatthieu castet 			dev->irq = 0;
323ea4bbfd0Smatthieu castet 		else
324ea4bbfd0Smatthieu castet 			dev->irq = mips_irq + 2;
325ea4bbfd0Smatthieu castet 		if (dev->irq > 5)
326ea4bbfd0Smatthieu castet 			continue;
32761e115a5SMichael Buesch 		switch (dev->id.coreid) {
32861e115a5SMichael Buesch 		case SSB_DEV_USB11_HOST:
32961e115a5SMichael Buesch 			/* shouldn't need a separate irq line for non-4710, most of them have a proper
33061e115a5SMichael Buesch 			 * external usb controller on the pci */
33161e115a5SMichael Buesch 			if ((bus->chip_id == 0x4710) && (irq <= 4)) {
33261e115a5SMichael Buesch 				set_irq(dev, irq++);
33361e115a5SMichael Buesch 			}
334ea4bbfd0Smatthieu castet 			break;
33561e115a5SMichael Buesch 		case SSB_DEV_PCI:
33661e115a5SMichael Buesch 		case SSB_DEV_ETHERNET:
337aab547ceSMichael Buesch 		case SSB_DEV_ETHERNET_GBIT:
33861e115a5SMichael Buesch 		case SSB_DEV_80211:
33961e115a5SMichael Buesch 		case SSB_DEV_USB20_HOST:
34061e115a5SMichael Buesch 			/* These devices get their own IRQ line if available, the rest goes on IRQ0 */
34161e115a5SMichael Buesch 			if (irq <= 4) {
34261e115a5SMichael Buesch 				set_irq(dev, irq++);
34361e115a5SMichael Buesch 				break;
34461e115a5SMichael Buesch 			}
345df561f66SGustavo A. R. Silva 			fallthrough;
34683e34f03SJochen Friedrich 		case SSB_DEV_EXTIF:
34783e34f03SJochen Friedrich 			set_irq(dev, 0);
34883e34f03SJochen Friedrich 			break;
34961e115a5SMichael Buesch 		}
35061e115a5SMichael Buesch 	}
351b8b6069cSMichael Büsch 	dev_dbg(mcore->dev->dev, "after irq reconfiguration\n");
352ea4bbfd0Smatthieu castet 	dump_irq(bus);
35361e115a5SMichael Buesch 
35461e115a5SMichael Buesch 	ssb_mips_serial_init(mcore);
35561e115a5SMichael Buesch 	ssb_mips_flash_detect(mcore);
35661e115a5SMichael Buesch }
357