Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1d1c5d4 authored by Hauke Mehrtens's avatar Hauke Mehrtens Committed by John W. Linville
Browse files

bcm47xx: add support for bcma bus



This patch add support for the bcma bus. Broadcom uses only Mips 74K
CPUs on the new SoC and on the old ons using ssb bus there are no Mips
74K CPUs.

Signed-off-by: default avatarHauke Mehrtens <hauke@hauke-m.de>
Acked-by: default avatarRalf Baechle <ralf@linux-mips.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a656ffcb
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -15,4 +15,17 @@ config BCM47XX_SSB

	 This will generate an image with support for SSB and MIPS32 R1 instruction set.

config BCM47XX_BCMA
	bool "BCMA Support for Broadcom BCM47XX"
	select SYS_HAS_CPU_MIPS32_R2
	select BCMA
	select BCMA_HOST_SOC
	select BCMA_DRIVER_MIPS
	select BCMA_DRIVER_PCI_HOSTMODE if PCI
	default y
	help
	 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.

	 This will generate an image with support for BCMA and MIPS32 R2 instruction set.

endif
+22 −0
Original line number Diff line number Diff line
@@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const char *tag)

		return 0;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
			return -EINVAL;

		if (test_and_set_bit(gpio, gpio_in_use))
			return -EBUSY;

		return 0;
#endif
	}
	return -EINVAL;
}
@@ -57,6 +67,14 @@ void gpio_free(unsigned gpio)
		clear_bit(gpio, gpio_in_use);
		return;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
			return;

		clear_bit(gpio, gpio_in_use);
		return;
#endif
	}
}
EXPORT_SYMBOL(gpio_free);
@@ -72,6 +90,10 @@ int gpio_to_irq(unsigned gpio)
			return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
		else
			return -EINVAL;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
#endif
	}
	return -EINVAL;
+10 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ static void early_nvram_init(void)
{
#ifdef CONFIG_BCM47XX_SSB
	struct ssb_mipscore *mcore_ssb;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	struct bcma_drv_cc *bcma_cc;
#endif
	struct nvram_header *header;
	int i;
@@ -43,6 +46,13 @@ static void early_nvram_init(void)
		base = mcore_ssb->flash_window;
		lim = mcore_ssb->flash_window_size;
		break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
		base = bcma_cc->pflash.window;
		lim = bcma_cc->pflash.window_size;
		break;
#endif
	}

+29 −0
Original line number Diff line number Diff line
@@ -47,12 +47,41 @@ static int __init uart8250_init_ssb(void)
}
#endif

#ifdef CONFIG_BCM47XX_BCMA
static int __init uart8250_init_bcma(void)
{
	int i;
	struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);

	memset(&uart8250_data, 0,  sizeof(uart8250_data));

	for (i = 0; i < cc->nr_serial_ports; i++) {
		struct plat_serial8250_port *p = &(uart8250_data[i]);
		struct bcma_serial_port *bcma_port;
		bcma_port = &(cc->serial_ports[i]);

		p->mapbase = (unsigned int) bcma_port->regs;
		p->membase = (void *) bcma_port->regs;
		p->irq = bcma_port->irq + 2;
		p->uartclk = bcma_port->baud_base;
		p->regshift = bcma_port->reg_shift;
		p->iotype = UPIO_MEM;
		p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
	}
	return platform_device_register(&uart8250_device);
}
#endif

static int __init uart8250_init(void)
{
	switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
	case BCM47XX_BUS_TYPE_SSB:
		return uart8250_init_ssb();
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		return uart8250_init_bcma();
#endif
	}
	return -EINVAL;
+51 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_embedded.h>
#include <linux/bcma/bcma_soc.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -51,6 +52,11 @@ static void bcm47xx_machine_restart(char *command)
	case BCM47XX_BUS_TYPE_SSB:
		ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
		break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
		break;
#endif
	}
	while (1)
@@ -66,6 +72,11 @@ static void bcm47xx_machine_halt(void)
	case BCM47XX_BUS_TYPE_SSB:
		ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
		break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
		break;
#endif
	}
	while (1)
@@ -295,16 +306,54 @@ static void __init bcm47xx_register_ssb(void)
}
#endif

#ifdef CONFIG_BCM47XX_BCMA
static void __init bcm47xx_register_bcma(void)
{
	int err;

	err = bcma_host_soc_register(&bcm47xx_bus.bcma);
	if (err)
		panic("Failed to initialize BCMA bus (err %d)\n", err);
}
#endif

void __init plat_mem_setup(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

	if (c->cputype == CPU_74K) {
		printk(KERN_INFO "bcm47xx: using bcma bus\n");
#ifdef CONFIG_BCM47XX_BCMA
		bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
		bcm47xx_register_bcma();
#endif
	} else {
		printk(KERN_INFO "bcm47xx: using ssb bus\n");
#ifdef CONFIG_BCM47XX_SSB
		bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
		bcm47xx_register_ssb();
#endif
	}

	_machine_restart = bcm47xx_machine_restart;
	_machine_halt = bcm47xx_machine_halt;
	pm_power_off = bcm47xx_machine_halt;
}

static int __init bcm47xx_register_bus_complete(void)
{
	switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
	case BCM47XX_BUS_TYPE_SSB:
		/* Nothing to do */
		break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		bcma_bus_register(&bcm47xx_bus.bcma.bus);
		break;
#endif
	}
	return 0;
}
device_initcall(bcm47xx_register_bus_complete);
Loading