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