mirror of https://github.com/hak5/openwrt.git
brcm47xx: add initial support for devices with bcma bus.
Ethernet and wifi are not working and this is highly experimental. SVN-Revision: 27301lede-17.01
parent
3f0eed15a2
commit
4c18da3df6
|
@ -149,9 +149,9 @@ static void __init bcm4780_init(void) {
|
||||||
|
|
||||||
/* Enables GPIO 3 that controls HDD and led power on ASUS WL-700gE */
|
/* Enables GPIO 3 that controls HDD and led power on ASUS WL-700gE */
|
||||||
printk(MODULE_NAME ": Spinning up HDD and enabling leds\n");
|
printk(MODULE_NAME ": Spinning up HDD and enabling leds\n");
|
||||||
gpio_outen(pin, pin);
|
ssb_gpio_outen(&ssb_bcm47xx, pin, pin);
|
||||||
gpio_control(pin, 0);
|
ssb_gpio_control(&ssb_bcm47xx, pin, 0);
|
||||||
gpio_out(pin, pin);
|
ssb_gpio_out(&ssb_bcm47xx, pin, pin);
|
||||||
|
|
||||||
/* Wait 5s, so the HDD can spin up */
|
/* Wait 5s, so the HDD can spin up */
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
@ -161,14 +161,14 @@ static void __init bcm4780_init(void) {
|
||||||
static void __init NetCenter_init(void) {
|
static void __init NetCenter_init(void) {
|
||||||
/* unset pin 6 (+12V) */
|
/* unset pin 6 (+12V) */
|
||||||
int pin = 1 << 6;
|
int pin = 1 << 6;
|
||||||
gpio_outen(pin, pin);
|
ssb_gpio_outen(&ssb_bcm47xx, pin, pin);
|
||||||
gpio_control(pin, 0);
|
ssb_gpio_control(&ssb_bcm47xx, pin, 0);
|
||||||
gpio_out(pin, pin);
|
ssb_gpio_out(&ssb_bcm47xx, pin, pin);
|
||||||
/* unset pin 1 (turn off red led, blue will light alone if +5V comes up) */
|
/* unset pin 1 (turn off red led, blue will light alone if +5V comes up) */
|
||||||
pin = 1 << 1;
|
pin = 1 << 1;
|
||||||
gpio_outen(pin, pin);
|
ssb_gpio_outen(&ssb_bcm47xx, pin, pin);
|
||||||
gpio_control(pin, 0);
|
ssb_gpio_control(&ssb_bcm47xx, pin, 0);
|
||||||
gpio_out(pin, pin);
|
ssb_gpio_out(&ssb_bcm47xx, pin, pin);
|
||||||
/* unset pin 3 (+5V) and wait 5 seconds (harddisk spin up) */
|
/* unset pin 3 (+5V) and wait 5 seconds (harddisk spin up) */
|
||||||
bcm4780_init();
|
bcm4780_init();
|
||||||
}
|
}
|
||||||
|
@ -177,9 +177,9 @@ static void __init bcm57xx_init(void) {
|
||||||
int pin = 1 << 2;
|
int pin = 1 << 2;
|
||||||
|
|
||||||
/* FIXME: switch comes up, but port mappings/vlans not right */
|
/* FIXME: switch comes up, but port mappings/vlans not right */
|
||||||
gpio_outen(pin, pin);
|
ssb_gpio_outen(&ssb_bcm47xx, pin, pin);
|
||||||
gpio_control(pin, 0);
|
ssb_gpio_control(&ssb_bcm47xx, pin, 0);
|
||||||
gpio_out(pin, pin);
|
ssb_gpio_out(&ssb_bcm47xx, pin, pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_t __initdata platforms[] = {
|
static struct platform_t __initdata platforms[] = {
|
||||||
|
@ -1166,18 +1166,18 @@ static void register_buttons(struct button_t *b)
|
||||||
|
|
||||||
platform.button_mask &= ~gpiomask;
|
platform.button_mask &= ~gpiomask;
|
||||||
|
|
||||||
gpio_outen(platform.button_mask, 0);
|
ssb_gpio_outen(&ssb_bcm47xx, platform.button_mask, 0);
|
||||||
gpio_control(platform.button_mask, 0);
|
ssb_gpio_control(&ssb_bcm47xx, platform.button_mask, 0);
|
||||||
platform.button_polarity = gpio_in() & platform.button_mask;
|
platform.button_polarity = ssb_gpio_in(&ssb_bcm47xx, ~0) & platform.button_mask;
|
||||||
gpio_intpolarity(platform.button_mask, platform.button_polarity);
|
ssb_gpio_polarity(&ssb_bcm47xx, platform.button_mask, platform.button_polarity);
|
||||||
gpio_setintmask(platform.button_mask, platform.button_mask);
|
ssb_gpio_intmask(&ssb_bcm47xx, platform.button_mask, platform.button_mask);
|
||||||
|
|
||||||
gpio_set_irqenable(1, button_handler);
|
gpio_set_irqenable(1, button_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_buttons(struct button_t *b)
|
static void unregister_buttons(struct button_t *b)
|
||||||
{
|
{
|
||||||
gpio_setintmask(platform.button_mask, 0);
|
ssb_gpio_intmask(&ssb_bcm47xx, platform.button_mask, 0);
|
||||||
|
|
||||||
gpio_set_irqenable(0, button_handler);
|
gpio_set_irqenable(0, button_handler);
|
||||||
}
|
}
|
||||||
|
@ -1237,12 +1237,12 @@ static irqreturn_t button_handler(int irq, void *dev_id)
|
||||||
struct button_t *b;
|
struct button_t *b;
|
||||||
u32 in, changed;
|
u32 in, changed;
|
||||||
|
|
||||||
in = gpio_in() & platform.button_mask;
|
in = ssb_gpio_in(&ssb_bcm47xx, ~0) & platform.button_mask;
|
||||||
gpio_intpolarity(platform.button_mask, in);
|
ssb_gpio_polarity(&ssb_bcm47xx, platform.button_mask, in);
|
||||||
changed = platform.button_polarity ^ in;
|
changed = platform.button_polarity ^ in;
|
||||||
platform.button_polarity = in;
|
platform.button_polarity = in;
|
||||||
|
|
||||||
changed &= ~gpio_outen(0, 0);
|
changed &= ~ssb_gpio_outen(&ssb_bcm47xx, 0, 0);
|
||||||
|
|
||||||
for (b = platform.buttons; b->name; b++) {
|
for (b = platform.buttons; b->name; b++) {
|
||||||
struct event_t *event;
|
struct event_t *event;
|
||||||
|
@ -1298,10 +1298,10 @@ static void register_leds(struct led_t *l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_outen(mask, oe_mask);
|
ssb_gpio_outen(&ssb_bcm47xx, mask, oe_mask);
|
||||||
gpio_control(mask, 0);
|
ssb_gpio_control(&ssb_bcm47xx, mask, 0);
|
||||||
gpio_out(mask, val);
|
ssb_gpio_out(&ssb_bcm47xx, mask, val);
|
||||||
gpio_setintmask(mask, 0);
|
ssb_gpio_intmask(&ssb_bcm47xx, mask, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_leds(struct led_t *l)
|
static void unregister_leds(struct led_t *l)
|
||||||
|
@ -1336,11 +1336,11 @@ static void led_flash(unsigned long dummy) {
|
||||||
|
|
||||||
mask &= ~gpiomask;
|
mask &= ~gpiomask;
|
||||||
if (mask) {
|
if (mask) {
|
||||||
u32 val = ~gpio_in();
|
u32 val = ~ssb_gpio_in(&ssb_bcm47xx, ~0);
|
||||||
|
|
||||||
gpio_outen(mask, mask);
|
ssb_gpio_outen(&ssb_bcm47xx, mask, mask);
|
||||||
gpio_control(mask, 0);
|
ssb_gpio_control(&ssb_bcm47xx, mask, 0);
|
||||||
gpio_out(mask, val);
|
ssb_gpio_out(&ssb_bcm47xx, mask, val);
|
||||||
}
|
}
|
||||||
if (mask || extif_blink) {
|
if (mask || extif_blink) {
|
||||||
mod_timer(&led_timer, jiffies + FLASH_TIME);
|
mod_timer(&led_timer, jiffies + FLASH_TIME);
|
||||||
|
@ -1367,7 +1367,7 @@ static ssize_t diag_proc_read(struct file *file, char *buf, size_t count, loff_t
|
||||||
if (led->gpio & GPIO_TYPE_EXTIF) {
|
if (led->gpio & GPIO_TYPE_EXTIF) {
|
||||||
len = sprintf(page, "%d\n", led->state);
|
len = sprintf(page, "%d\n", led->state);
|
||||||
} else {
|
} else {
|
||||||
u32 in = (gpio_in() & led->gpio ? 1 : 0);
|
u32 in = (ssb_gpio_in(&ssb_bcm47xx, ~0) & led->gpio ? 1 : 0);
|
||||||
u8 p = (led->polarity == NORMAL ? 0 : 1);
|
u8 p = (led->polarity == NORMAL ? 0 : 1);
|
||||||
len = sprintf(page, "%d\n", ((in ^ p) ? 1 : 0));
|
len = sprintf(page, "%d\n", ((in ^ p) ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
@ -1431,9 +1431,9 @@ static ssize_t diag_proc_write(struct file *file, const char *buf, size_t count,
|
||||||
led->state = p ^ ((page[0] == '1') ? 1 : 0);
|
led->state = p ^ ((page[0] == '1') ? 1 : 0);
|
||||||
set_led_extif(led);
|
set_led_extif(led);
|
||||||
} else {
|
} else {
|
||||||
gpio_outen(led->gpio, led->gpio);
|
ssb_gpio_outen(&ssb_bcm47xx, led->gpio, led->gpio);
|
||||||
gpio_control(led->gpio, 0);
|
ssb_gpio_control(&ssb_bcm47xx, led->gpio, 0);
|
||||||
gpio_out(led->gpio, ((p ^ (page[0] == '1')) ? led->gpio : 0));
|
ssb_gpio_out(&ssb_bcm47xx, led->gpio, ((p ^ (page[0] == '1')) ? led->gpio : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1464,6 +1464,13 @@ static int __init diag_init(void)
|
||||||
static struct proc_dir_entry *p;
|
static struct proc_dir_entry *p;
|
||||||
static struct platform_t *detected;
|
static struct platform_t *detected;
|
||||||
|
|
||||||
|
#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB) {
|
||||||
|
printk(MODULE_NAME ": bcma bus is not supported.\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
detected = platform_detect();
|
detected = platform_detect();
|
||||||
if (!detected) {
|
if (!detected) {
|
||||||
printk(MODULE_NAME ": Router model not detected.\n");
|
printk(MODULE_NAME ": Router model not detected.\n");
|
||||||
|
|
|
@ -1,46 +1,12 @@
|
||||||
#ifndef __DIAG_GPIO_H
|
#ifndef __DIAG_GPIO_H
|
||||||
#define __DIAG_GPIO_H
|
#define __DIAG_GPIO_H
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
|
|
||||||
#ifndef BCMDRIVER
|
|
||||||
#include <linux/ssb/ssb_embedded.h>
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
|
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#define ssb ssb_bcm47xx
|
#include <asm/mach-bcm47xx/bcm47xx.h>
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
|
||||||
|
#define ssb_bcm47xx bcm47xx_bus.ssb
|
||||||
#endif
|
#endif
|
||||||
extern struct ssb_bus ssb;
|
|
||||||
|
|
||||||
|
|
||||||
static inline u32 gpio_in(void)
|
|
||||||
{
|
|
||||||
return ssb_gpio_in(&ssb, ~0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 gpio_out(u32 mask, u32 value)
|
|
||||||
{
|
|
||||||
return ssb_gpio_out(&ssb, mask, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 gpio_outen(u32 mask, u32 value)
|
|
||||||
{
|
|
||||||
return ssb_gpio_outen(&ssb, mask, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 gpio_control(u32 mask, u32 value)
|
|
||||||
{
|
|
||||||
return ssb_gpio_control(&ssb, mask, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 gpio_setintmask(u32 mask, u32 value)
|
|
||||||
{
|
|
||||||
return ssb_gpio_intmask(&ssb, mask, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 gpio_intpolarity(u32 mask, u32 value)
|
|
||||||
{
|
|
||||||
return ssb_gpio_polarity(&ssb, mask, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 __ssb_write32_masked(struct ssb_device *dev, u16 offset,
|
static inline u32 __ssb_write32_masked(struct ssb_device *dev, u16 offset,
|
||||||
u32 mask, u32 value)
|
u32 mask, u32 value)
|
||||||
|
@ -55,16 +21,8 @@ static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *))
|
||||||
{
|
{
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
|
|
||||||
irq = gpio_to_irq(0);
|
irq = gpio_to_irq(0);
|
||||||
if (irq == -EINVAL) return;
|
if (irq == -EINVAL) return;
|
||||||
#else
|
|
||||||
if (ssb.chipco.dev)
|
|
||||||
irq = ssb_mips_irq(ssb.chipco.dev) + 2;
|
|
||||||
else if (ssb.extif.dev)
|
|
||||||
irq = ssb_mips_irq(ssb.extif.dev) + 2;
|
|
||||||
else return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler))
|
if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler))
|
||||||
|
@ -73,71 +31,10 @@ static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *))
|
||||||
free_irq(irq, handler);
|
free_irq(irq, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ssb.chipco.dev)
|
if (ssb_bcm47xx.chipco.dev)
|
||||||
__ssb_write32_masked(ssb.chipco.dev, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0));
|
__ssb_write32_masked(ssb_bcm47xx.chipco.dev, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <typedefs.h>
|
|
||||||
#include <osl.h>
|
|
||||||
#include <bcmdevs.h>
|
|
||||||
#include <sbutils.h>
|
|
||||||
#include <sbconfig.h>
|
|
||||||
#include <sbchipc.h>
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
|
||||||
#include <sbmips.h>
|
|
||||||
#else
|
|
||||||
#include <hndcpu.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
|
||||||
#define sbh bcm947xx_sbh
|
|
||||||
#define sbh_lock bcm947xx_sbh_lock
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void *sbh;
|
|
||||||
extern spinlock_t sbh_lock;
|
|
||||||
|
|
||||||
#define gpio_in() sb_gpioin(sbh)
|
|
||||||
#define gpio_out(mask, value) sb_gpioout(sbh, mask, ((value) & (mask)), GPIO_DRV_PRIORITY)
|
|
||||||
#define gpio_outen(mask, value) sb_gpioouten(sbh, mask, value, GPIO_DRV_PRIORITY)
|
|
||||||
#define gpio_control(mask, value) sb_gpiocontrol(sbh, mask, value, GPIO_DRV_PRIORITY)
|
|
||||||
#define gpio_setintmask(mask, value) sb_gpiointmask(sbh, mask, value, GPIO_DRV_PRIORITY)
|
|
||||||
#define gpio_intpolarity(mask, value) sb_gpiointpolarity(sbh, mask, value, GPIO_DRV_PRIORITY)
|
|
||||||
|
|
||||||
static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *, struct pt_regs *))
|
|
||||||
{
|
|
||||||
unsigned int coreidx;
|
|
||||||
unsigned long flags;
|
|
||||||
chipcregs_t *cc;
|
|
||||||
int irq;
|
|
||||||
|
|
||||||
spin_lock_irqsave(sbh_lock, flags);
|
|
||||||
coreidx = sb_coreidx(sbh);
|
|
||||||
|
|
||||||
irq = sb_irq(sbh) + 2;
|
|
||||||
if (enabled)
|
|
||||||
request_irq(irq, handler, SA_SHIRQ | SA_SAMPLE_RANDOM, "gpio", handler);
|
|
||||||
else
|
|
||||||
free_irq(irq, handler);
|
|
||||||
|
|
||||||
if ((cc = sb_setcore(sbh, SB_CC, 0))) {
|
|
||||||
int intmask;
|
|
||||||
|
|
||||||
intmask = readl(&cc->intmask);
|
|
||||||
if (enabled)
|
|
||||||
intmask |= CI_GPIO;
|
|
||||||
else
|
|
||||||
intmask &= ~CI_GPIO;
|
|
||||||
writel(intmask, &cc->intmask);
|
|
||||||
}
|
|
||||||
sb_setcoreidx(sbh, coreidx);
|
|
||||||
spin_unlock_irqrestore(sbh_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* BCMDRIVER */
|
|
||||||
|
|
||||||
#define EXTIF_ADDR 0x1f000000
|
#define EXTIF_ADDR 0x1f000000
|
||||||
#define EXTIF_UART (EXTIF_ADDR + 0x00800000)
|
#define EXTIF_UART (EXTIF_ADDR + 0x00800000)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,16 @@ CONFIG_B44_PCI=y
|
||||||
CONFIG_B44_PCICORE_AUTOSELECT=y
|
CONFIG_B44_PCICORE_AUTOSELECT=y
|
||||||
CONFIG_B44_PCI_AUTOSELECT=y
|
CONFIG_B44_PCI_AUTOSELECT=y
|
||||||
CONFIG_BCM47XX=y
|
CONFIG_BCM47XX=y
|
||||||
|
CONFIG_BCM47XX_BCMA=y
|
||||||
|
CONFIG_BCM47XX_SSB=y
|
||||||
CONFIG_BCM47XX_WDT=y
|
CONFIG_BCM47XX_WDT=y
|
||||||
|
CONFIG_BCMA=y
|
||||||
|
CONFIG_BCMA_DEBUG=y
|
||||||
|
CONFIG_BCMA_DRIVER_MIPS=y
|
||||||
|
CONFIG_BCMA_DRIVER_PCI_HOSTMODE=y
|
||||||
|
CONFIG_BCMA_HOST_PCI=y
|
||||||
|
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
|
||||||
|
CONFIG_BCMA_HOST_SOC=y
|
||||||
CONFIG_BCMA_POSSIBLE=y
|
CONFIG_BCMA_POSSIBLE=y
|
||||||
# CONFIG_BRCMUTIL is not set
|
# CONFIG_BRCMUTIL is not set
|
||||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||||
|
@ -31,6 +40,7 @@ CONFIG_CPU_HAS_SYNC=y
|
||||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||||
CONFIG_CPU_MIPS32=y
|
CONFIG_CPU_MIPS32=y
|
||||||
CONFIG_CPU_MIPS32_R1=y
|
CONFIG_CPU_MIPS32_R1=y
|
||||||
|
# CONFIG_CPU_MIPS32_R2 is not set
|
||||||
CONFIG_CPU_MIPSR1=y
|
CONFIG_CPU_MIPSR1=y
|
||||||
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||||
|
@ -118,6 +128,7 @@ CONFIG_SSB_PCIHOST_POSSIBLE=y
|
||||||
CONFIG_SSB_SERIAL=y
|
CONFIG_SSB_SERIAL=y
|
||||||
CONFIG_SSB_SPROM=y
|
CONFIG_SSB_SPROM=y
|
||||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||||
|
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||||
|
|
|
@ -0,0 +1,274 @@
|
||||||
|
From c4fb5adbe45b3a1cfc509a64bb92429ab0d6fc37 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sat, 11 Jun 2011 16:47:38 +0200
|
||||||
|
Subject: [PATCH 01/14] bcma: move parsing of EEPROM into own function.
|
||||||
|
|
||||||
|
Move the parsing of the EEPROM data in scan function for one core into
|
||||||
|
an own function. Now we are able to use it in some other scan function
|
||||||
|
as well.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/scan.c | 230 ++++++++++++++++++++++++++-------------------------
|
||||||
|
1 files changed, 118 insertions(+), 112 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bcma/scan.c
|
||||||
|
+++ b/drivers/bcma/scan.c
|
||||||
|
@@ -200,16 +200,124 @@ static s32 bcma_erom_get_addr_desc(struc
|
||||||
|
return addrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
||||||
|
+ struct bcma_device *core)
|
||||||
|
+{
|
||||||
|
+ s32 tmp;
|
||||||
|
+ u8 i, j;
|
||||||
|
+ s32 cia, cib;
|
||||||
|
+ u8 ports[2], wrappers[2];
|
||||||
|
+
|
||||||
|
+ /* get CIs */
|
||||||
|
+ cia = bcma_erom_get_ci(bus, eromptr);
|
||||||
|
+ if (cia < 0) {
|
||||||
|
+ bcma_erom_push_ent(eromptr);
|
||||||
|
+ if (bcma_erom_is_end(bus, eromptr))
|
||||||
|
+ return -ESPIPE;
|
||||||
|
+ return -EILSEQ;
|
||||||
|
+ }
|
||||||
|
+ cib = bcma_erom_get_ci(bus, eromptr);
|
||||||
|
+ if (cib < 0)
|
||||||
|
+ return -EILSEQ;
|
||||||
|
+
|
||||||
|
+ /* parse CIs */
|
||||||
|
+ core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
|
||||||
|
+ core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
|
||||||
|
+ core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
|
||||||
|
+ ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
|
||||||
|
+ ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
|
||||||
|
+ wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
|
||||||
|
+ wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
|
||||||
|
+ core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
|
||||||
|
+
|
||||||
|
+ if (((core->id.manuf == BCMA_MANUF_ARM) &&
|
||||||
|
+ (core->id.id == 0xFFF)) ||
|
||||||
|
+ (ports[1] == 0)) {
|
||||||
|
+ bcma_erom_skip_component(bus, eromptr);
|
||||||
|
+ return -ENXIO;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check if component is a core at all */
|
||||||
|
+ if (wrappers[0] + wrappers[1] == 0) {
|
||||||
|
+ /* we could save addrl of the router
|
||||||
|
+ if (cid == BCMA_CORE_OOB_ROUTER)
|
||||||
|
+ */
|
||||||
|
+ bcma_erom_skip_component(bus, eromptr);
|
||||||
|
+ return -ENXIO;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (bcma_erom_is_bridge(bus, eromptr)) {
|
||||||
|
+ bcma_erom_skip_component(bus, eromptr);
|
||||||
|
+ return -ENXIO;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* get & parse master ports */
|
||||||
|
+ for (i = 0; i < ports[0]; i++) {
|
||||||
|
+ u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
|
||||||
|
+ if (mst_port_d < 0)
|
||||||
|
+ return -EILSEQ;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* get & parse slave ports */
|
||||||
|
+ for (i = 0; i < ports[1]; i++) {
|
||||||
|
+ for (j = 0; ; j++) {
|
||||||
|
+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
|
+ SCAN_ADDR_TYPE_SLAVE, i);
|
||||||
|
+ if (tmp < 0) {
|
||||||
|
+ /* no more entries for port _i_ */
|
||||||
|
+ /* pr_debug("erom: slave port %d "
|
||||||
|
+ * "has %d descriptors\n", i, j); */
|
||||||
|
+ break;
|
||||||
|
+ } else {
|
||||||
|
+ if (i == 0 && j == 0)
|
||||||
|
+ core->addr = tmp;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* get & parse master wrappers */
|
||||||
|
+ for (i = 0; i < wrappers[0]; i++) {
|
||||||
|
+ for (j = 0; ; j++) {
|
||||||
|
+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
|
+ SCAN_ADDR_TYPE_MWRAP, i);
|
||||||
|
+ if (tmp < 0) {
|
||||||
|
+ /* no more entries for port _i_ */
|
||||||
|
+ /* pr_debug("erom: master wrapper %d "
|
||||||
|
+ * "has %d descriptors\n", i, j); */
|
||||||
|
+ break;
|
||||||
|
+ } else {
|
||||||
|
+ if (i == 0 && j == 0)
|
||||||
|
+ core->wrap = tmp;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* get & parse slave wrappers */
|
||||||
|
+ for (i = 0; i < wrappers[1]; i++) {
|
||||||
|
+ u8 hack = (ports[1] == 1) ? 0 : 1;
|
||||||
|
+ for (j = 0; ; j++) {
|
||||||
|
+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
|
||||||
|
+ SCAN_ADDR_TYPE_SWRAP, i + hack);
|
||||||
|
+ if (tmp < 0) {
|
||||||
|
+ /* no more entries for port _i_ */
|
||||||
|
+ /* pr_debug("erom: master wrapper %d "
|
||||||
|
+ * has %d descriptors\n", i, j); */
|
||||||
|
+ break;
|
||||||
|
+ } else {
|
||||||
|
+ if (wrappers[0] == 0 && !i && !j)
|
||||||
|
+ core->wrap = tmp;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
{
|
||||||
|
u32 erombase;
|
||||||
|
u32 __iomem *eromptr, *eromend;
|
||||||
|
|
||||||
|
- s32 cia, cib;
|
||||||
|
- u8 ports[2], wrappers[2];
|
||||||
|
-
|
||||||
|
s32 tmp;
|
||||||
|
- u8 i, j;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
@@ -236,112 +344,13 @@ int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
INIT_LIST_HEAD(&core->list);
|
||||||
|
core->bus = bus;
|
||||||
|
|
||||||
|
- /* get CIs */
|
||||||
|
- cia = bcma_erom_get_ci(bus, &eromptr);
|
||||||
|
- if (cia < 0) {
|
||||||
|
- bcma_erom_push_ent(&eromptr);
|
||||||
|
- if (bcma_erom_is_end(bus, &eromptr))
|
||||||
|
- break;
|
||||||
|
- err= -EILSEQ;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
- cib = bcma_erom_get_ci(bus, &eromptr);
|
||||||
|
- if (cib < 0) {
|
||||||
|
- err= -EILSEQ;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* parse CIs */
|
||||||
|
- core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
|
||||||
|
- core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
|
||||||
|
- core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
|
||||||
|
- ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
|
||||||
|
- ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
|
||||||
|
- wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
|
||||||
|
- wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
|
||||||
|
- core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
|
||||||
|
-
|
||||||
|
- if (((core->id.manuf == BCMA_MANUF_ARM) &&
|
||||||
|
- (core->id.id == 0xFFF)) ||
|
||||||
|
- (ports[1] == 0)) {
|
||||||
|
- bcma_erom_skip_component(bus, &eromptr);
|
||||||
|
+ err = bcma_get_next_core(bus, &eromptr, core);
|
||||||
|
+ if (err == -ENXIO)
|
||||||
|
continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* check if component is a core at all */
|
||||||
|
- if (wrappers[0] + wrappers[1] == 0) {
|
||||||
|
- /* we could save addrl of the router
|
||||||
|
- if (cid == BCMA_CORE_OOB_ROUTER)
|
||||||
|
- */
|
||||||
|
- bcma_erom_skip_component(bus, &eromptr);
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (bcma_erom_is_bridge(bus, &eromptr)) {
|
||||||
|
- bcma_erom_skip_component(bus, &eromptr);
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* get & parse master ports */
|
||||||
|
- for (i = 0; i < ports[0]; i++) {
|
||||||
|
- u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
|
||||||
|
- if (mst_port_d < 0) {
|
||||||
|
- err= -EILSEQ;
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* get & parse slave ports */
|
||||||
|
- for (i = 0; i < ports[1]; i++) {
|
||||||
|
- for (j = 0; ; j++) {
|
||||||
|
- tmp = bcma_erom_get_addr_desc(bus, &eromptr,
|
||||||
|
- SCAN_ADDR_TYPE_SLAVE, i);
|
||||||
|
- if (tmp < 0) {
|
||||||
|
- /* no more entries for port _i_ */
|
||||||
|
- /* pr_debug("erom: slave port %d "
|
||||||
|
- * "has %d descriptors\n", i, j); */
|
||||||
|
- break;
|
||||||
|
- } else {
|
||||||
|
- if (i == 0 && j == 0)
|
||||||
|
- core->addr = tmp;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* get & parse master wrappers */
|
||||||
|
- for (i = 0; i < wrappers[0]; i++) {
|
||||||
|
- for (j = 0; ; j++) {
|
||||||
|
- tmp = bcma_erom_get_addr_desc(bus, &eromptr,
|
||||||
|
- SCAN_ADDR_TYPE_MWRAP, i);
|
||||||
|
- if (tmp < 0) {
|
||||||
|
- /* no more entries for port _i_ */
|
||||||
|
- /* pr_debug("erom: master wrapper %d "
|
||||||
|
- * "has %d descriptors\n", i, j); */
|
||||||
|
- break;
|
||||||
|
- } else {
|
||||||
|
- if (i == 0 && j == 0)
|
||||||
|
- core->wrap = tmp;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* get & parse slave wrappers */
|
||||||
|
- for (i = 0; i < wrappers[1]; i++) {
|
||||||
|
- u8 hack = (ports[1] == 1) ? 0 : 1;
|
||||||
|
- for (j = 0; ; j++) {
|
||||||
|
- tmp = bcma_erom_get_addr_desc(bus, &eromptr,
|
||||||
|
- SCAN_ADDR_TYPE_SWRAP, i + hack);
|
||||||
|
- if (tmp < 0) {
|
||||||
|
- /* no more entries for port _i_ */
|
||||||
|
- /* pr_debug("erom: master wrapper %d "
|
||||||
|
- * has %d descriptors\n", i, j); */
|
||||||
|
- break;
|
||||||
|
- } else {
|
||||||
|
- if (wrappers[0] == 0 && !i && !j)
|
||||||
|
- core->wrap = tmp;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ else if (err == -ESPIPE)
|
||||||
|
+ break;
|
||||||
|
+ else if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
|
||||||
|
pr_info("Core %d found: %s "
|
||||||
|
"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
|
||||||
|
@@ -351,9 +360,6 @@ int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
|
||||||
|
core->core_index = bus->nr_cores++;
|
||||||
|
list_add(&core->list, &bus->cores);
|
||||||
|
- continue;
|
||||||
|
-out:
|
||||||
|
- return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
|
@ -0,0 +1,48 @@
|
||||||
|
From dd6cbe9b9e2ae563659b34184f4cd9d905dc90d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sat, 18 Jun 2011 11:55:47 +0200
|
||||||
|
Subject: [PATCH 02/14] bcma: move initializing of struct bcma_bus to own function.
|
||||||
|
|
||||||
|
This makes it possible to use this code in some other method.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/scan.c | 17 +++++++++++------
|
||||||
|
1 files changed, 11 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bcma/scan.c
|
||||||
|
+++ b/drivers/bcma/scan.c
|
||||||
|
@@ -312,15 +312,10 @@ static int bcma_get_next_core(struct bcm
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
+static void bcma_init_bus(struct bcma_bus *bus)
|
||||||
|
{
|
||||||
|
- u32 erombase;
|
||||||
|
- u32 __iomem *eromptr, *eromend;
|
||||||
|
-
|
||||||
|
s32 tmp;
|
||||||
|
|
||||||
|
- int err;
|
||||||
|
-
|
||||||
|
INIT_LIST_HEAD(&bus->cores);
|
||||||
|
bus->nr_cores = 0;
|
||||||
|
|
||||||
|
@@ -330,6 +325,16 @@ int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
|
||||||
|
bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
|
||||||
|
bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
+{
|
||||||
|
+ u32 erombase;
|
||||||
|
+ u32 __iomem *eromptr, *eromend;
|
||||||
|
+
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ bcma_init_bus(bus);
|
||||||
|
|
||||||
|
erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
|
||||||
|
eromptr = bus->mmio;
|
|
@ -0,0 +1,307 @@
|
||||||
|
From 9a920f4d8eed485f7b73e9b13dab0e49c64d3ff8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sat, 18 Jun 2011 14:30:55 +0200
|
||||||
|
Subject: [PATCH 03/14] bcma: add functions to scan cores needed on SoCs
|
||||||
|
|
||||||
|
The chip common and mips core have to be setup early in the boot
|
||||||
|
process to get the cpu clock.
|
||||||
|
bcma_bus_early_register() gets pointers to some space to store the core
|
||||||
|
data and searches for the chip common and mips core and initializes
|
||||||
|
chip common. After that was done and the kernel is out of early boot we
|
||||||
|
just have to run bcma_bus_register() and it will search for the other
|
||||||
|
cores, initialize and register them.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/bcma_private.h | 7 ++
|
||||||
|
drivers/bcma/driver_chipcommon.c | 5 ++
|
||||||
|
drivers/bcma/driver_pci.c | 3 +
|
||||||
|
drivers/bcma/main.c | 45 +++++++++++++
|
||||||
|
drivers/bcma/scan.c | 95 +++++++++++++++++++++++++--
|
||||||
|
include/linux/bcma/bcma.h | 1 +
|
||||||
|
include/linux/bcma/bcma_driver_chipcommon.h | 1 +
|
||||||
|
7 files changed, 151 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bcma/bcma_private.h
|
||||||
|
+++ b/drivers/bcma/bcma_private.h
|
||||||
|
@@ -15,9 +15,16 @@ struct bcma_bus;
|
||||||
|
/* main.c */
|
||||||
|
int bcma_bus_register(struct bcma_bus *bus);
|
||||||
|
void bcma_bus_unregister(struct bcma_bus *bus);
|
||||||
|
+int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||||
|
+ struct bcma_device *core_cc,
|
||||||
|
+ struct bcma_device *core_mips);
|
||||||
|
|
||||||
|
/* scan.c */
|
||||||
|
int bcma_bus_scan(struct bcma_bus *bus);
|
||||||
|
+int __init bcma_bus_scan_early(struct bcma_bus *bus,
|
||||||
|
+ struct bcma_device_id *match,
|
||||||
|
+ struct bcma_device *core);
|
||||||
|
+void bcma_init_bus(struct bcma_bus *bus);
|
||||||
|
|
||||||
|
/* sprom.c */
|
||||||
|
int bcma_sprom_get(struct bcma_bus *bus);
|
||||||
|
--- a/drivers/bcma/driver_chipcommon.c
|
||||||
|
+++ b/drivers/bcma/driver_chipcommon.c
|
||||||
|
@@ -23,6 +23,9 @@ static inline u32 bcma_cc_write32_masked
|
||||||
|
|
||||||
|
void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
|
||||||
|
{
|
||||||
|
+ if (cc->setup_done)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (cc->core->id.rev >= 11)
|
||||||
|
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
|
||||||
|
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
|
||||||
|
@@ -38,6 +41,8 @@ void bcma_core_chipcommon_init(struct bc
|
||||||
|
bcma_pmu_init(cc);
|
||||||
|
if (cc->capabilities & BCMA_CC_CAP_PCTL)
|
||||||
|
pr_err("Power control not implemented!\n");
|
||||||
|
+
|
||||||
|
+ cc->setup_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
|
||||||
|
--- a/drivers/bcma/driver_pci.c
|
||||||
|
+++ b/drivers/bcma/driver_pci.c
|
||||||
|
@@ -159,7 +159,10 @@ static void bcma_pcicore_serdes_workarou
|
||||||
|
|
||||||
|
void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||||
|
{
|
||||||
|
+ if (pc->setup_done)
|
||||||
|
+ return;
|
||||||
|
bcma_pcicore_serdes_workaround(pc);
|
||||||
|
+ pc->setup_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
|
||||||
|
--- a/drivers/bcma/main.c
|
||||||
|
+++ b/drivers/bcma/main.c
|
||||||
|
@@ -167,6 +167,51 @@ void bcma_bus_unregister(struct bcma_bus
|
||||||
|
bcma_unregister_cores(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||||
|
+ struct bcma_device *core_cc,
|
||||||
|
+ struct bcma_device *core_mips)
|
||||||
|
+{
|
||||||
|
+ int err;
|
||||||
|
+ struct bcma_device *core;
|
||||||
|
+ struct bcma_device_id match;
|
||||||
|
+
|
||||||
|
+ bcma_init_bus(bus);
|
||||||
|
+
|
||||||
|
+ match.manuf = BCMA_MANUF_BCM;
|
||||||
|
+ match.id = BCMA_CORE_CHIPCOMMON;
|
||||||
|
+ match.class = BCMA_CL_SIM;
|
||||||
|
+ match.rev = BCMA_ANY_REV;
|
||||||
|
+
|
||||||
|
+ /* Scan for devices (cores) */
|
||||||
|
+ err = bcma_bus_scan_early(bus, &match, core_cc);
|
||||||
|
+ if (err) {
|
||||||
|
+ pr_err("Failed to scan for common core: %d\n", err);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ match.manuf = BCMA_MANUF_MIPS;
|
||||||
|
+ match.id = BCMA_CORE_MIPS_74K;
|
||||||
|
+ match.class = BCMA_CL_SIM;
|
||||||
|
+ match.rev = BCMA_ANY_REV;
|
||||||
|
+
|
||||||
|
+ err = bcma_bus_scan_early(bus, &match, core_mips);
|
||||||
|
+ if (err) {
|
||||||
|
+ pr_err("Failed to scan for mips core: %d\n", err);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Init CC core */
|
||||||
|
+ core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
|
||||||
|
+ if (core) {
|
||||||
|
+ bus->drv_cc.core = core;
|
||||||
|
+ bcma_core_chipcommon_init(&bus->drv_cc);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pr_info("Early bus registered\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
|
||||||
|
{
|
||||||
|
drv->drv.name = drv->name;
|
||||||
|
--- a/drivers/bcma/scan.c
|
||||||
|
+++ b/drivers/bcma/scan.c
|
||||||
|
@@ -200,7 +200,20 @@ static s32 bcma_erom_get_addr_desc(struc
|
||||||
|
return addrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
|
||||||
|
+ u16 index)
|
||||||
|
+{
|
||||||
|
+ struct bcma_device *core;
|
||||||
|
+
|
||||||
|
+ list_for_each_entry(core, &bus->cores, list) {
|
||||||
|
+ if (core->core_index == index)
|
||||||
|
+ return core;
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
|
||||||
|
+ struct bcma_device_id *match, int core_num,
|
||||||
|
struct bcma_device *core)
|
||||||
|
{
|
||||||
|
s32 tmp;
|
||||||
|
@@ -251,6 +264,21 @@ static int bcma_get_next_core(struct bcm
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (bcma_find_core_by_index(bus, core_num)) {
|
||||||
|
+ bcma_erom_skip_component(bus, eromptr);
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (match && ((match->manuf != BCMA_ANY_MANUF &&
|
||||||
|
+ match->manuf != core->id.manuf) ||
|
||||||
|
+ (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
|
||||||
|
+ (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
|
||||||
|
+ (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
|
||||||
|
+ )) {
|
||||||
|
+ bcma_erom_skip_component(bus, eromptr);
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* get & parse master ports */
|
||||||
|
for (i = 0; i < ports[0]; i++) {
|
||||||
|
u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
|
||||||
|
@@ -312,10 +340,13 @@ static int bcma_get_next_core(struct bcm
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void bcma_init_bus(struct bcma_bus *bus)
|
||||||
|
+void bcma_init_bus(struct bcma_bus *bus)
|
||||||
|
{
|
||||||
|
s32 tmp;
|
||||||
|
|
||||||
|
+ if (bus->init_done)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
INIT_LIST_HEAD(&bus->cores);
|
||||||
|
bus->nr_cores = 0;
|
||||||
|
|
||||||
|
@@ -325,6 +356,7 @@ static void bcma_init_bus(struct bcma_bu
|
||||||
|
bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
|
||||||
|
bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
|
||||||
|
bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
|
||||||
|
+ bus->init_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
@@ -332,7 +364,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
u32 erombase;
|
||||||
|
u32 __iomem *eromptr, *eromend;
|
||||||
|
|
||||||
|
- int err;
|
||||||
|
+ int err, core_num = 0;
|
||||||
|
|
||||||
|
bcma_init_bus(bus);
|
||||||
|
|
||||||
|
@@ -349,23 +381,74 @@ int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
INIT_LIST_HEAD(&core->list);
|
||||||
|
core->bus = bus;
|
||||||
|
|
||||||
|
- err = bcma_get_next_core(bus, &eromptr, core);
|
||||||
|
- if (err == -ENXIO)
|
||||||
|
+ err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
|
||||||
|
+ if (err == -ENODEV) {
|
||||||
|
+ core_num++;
|
||||||
|
+ continue;
|
||||||
|
+ } else if (err == -ENXIO)
|
||||||
|
continue;
|
||||||
|
else if (err == -ESPIPE)
|
||||||
|
break;
|
||||||
|
else if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
+ core->core_index = core_num++;
|
||||||
|
+ bus->nr_cores++;
|
||||||
|
+
|
||||||
|
pr_info("Core %d found: %s "
|
||||||
|
"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
|
||||||
|
- bus->nr_cores, bcma_device_name(&core->id),
|
||||||
|
+ core->core_index, bcma_device_name(&core->id),
|
||||||
|
core->id.manuf, core->id.id, core->id.rev,
|
||||||
|
core->id.class);
|
||||||
|
|
||||||
|
- core->core_index = bus->nr_cores++;
|
||||||
|
list_add(&core->list, &bus->cores);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int __init bcma_bus_scan_early(struct bcma_bus *bus,
|
||||||
|
+ struct bcma_device_id *match,
|
||||||
|
+ struct bcma_device *core)
|
||||||
|
+{
|
||||||
|
+ u32 erombase;
|
||||||
|
+ u32 __iomem *eromptr, *eromend;
|
||||||
|
+
|
||||||
|
+ int err, core_num = 0;
|
||||||
|
+
|
||||||
|
+ erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
|
||||||
|
+ eromptr = bus->mmio;
|
||||||
|
+ eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
|
||||||
|
+
|
||||||
|
+ bcma_scan_switch_core(bus, erombase);
|
||||||
|
+
|
||||||
|
+ while (eromptr < eromend) {
|
||||||
|
+ memset(core, 0, sizeof(*core));
|
||||||
|
+ INIT_LIST_HEAD(&core->list);
|
||||||
|
+ core->bus = bus;
|
||||||
|
+
|
||||||
|
+ err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
|
||||||
|
+ if (err == -ENODEV) {
|
||||||
|
+ core_num++;
|
||||||
|
+ continue;
|
||||||
|
+ } else if (err == -ENXIO)
|
||||||
|
+ continue;
|
||||||
|
+ else if (err == -ESPIPE)
|
||||||
|
+ break;
|
||||||
|
+ else if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ core->core_index = core_num++;
|
||||||
|
+ bus->nr_cores++;
|
||||||
|
+ pr_info("Core %d found: %s "
|
||||||
|
+ "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
|
||||||
|
+ core->core_index, bcma_device_name(&core->id),
|
||||||
|
+ core->id.manuf, core->id.id, core->id.rev,
|
||||||
|
+ core->id.class);
|
||||||
|
+
|
||||||
|
+ list_add(&core->list, &bus->cores);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return -ENODEV;
|
||||||
|
+}
|
||||||
|
--- a/include/linux/bcma/bcma.h
|
||||||
|
+++ b/include/linux/bcma/bcma.h
|
||||||
|
@@ -185,6 +185,7 @@ struct bcma_bus {
|
||||||
|
struct bcma_device *mapped_core;
|
||||||
|
struct list_head cores;
|
||||||
|
u8 nr_cores;
|
||||||
|
+ u8 init_done:1;
|
||||||
|
|
||||||
|
struct bcma_drv_cc drv_cc;
|
||||||
|
struct bcma_drv_pci drv_pci;
|
||||||
|
--- a/include/linux/bcma/bcma_driver_chipcommon.h
|
||||||
|
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
|
||||||
|
@@ -259,6 +259,7 @@ struct bcma_drv_cc {
|
||||||
|
u32 status;
|
||||||
|
u32 capabilities;
|
||||||
|
u32 capabilities_ext;
|
||||||
|
+ u8 setup_done:1;
|
||||||
|
/* Fast Powerup Delay constant */
|
||||||
|
u16 fast_pwrup_delay;
|
||||||
|
struct bcma_chipcommon_pmu pmu;
|
|
@ -0,0 +1,323 @@
|
||||||
|
From a807b2fb233af60028ed38ba237953bcffdf33e9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sat, 18 Jun 2011 14:31:53 +0200
|
||||||
|
Subject: [PATCH 04/14] bcma: add SOC bus
|
||||||
|
|
||||||
|
This patch adds support for using bcma on an embedded bus. An embedded
|
||||||
|
system like the bcm4716 could register this bus and it searches for the
|
||||||
|
bcma cores then.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/Kconfig | 5 +
|
||||||
|
drivers/bcma/Makefile | 1 +
|
||||||
|
drivers/bcma/host_soc.c | 178 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
drivers/bcma/main.c | 1 +
|
||||||
|
drivers/bcma/scan.c | 24 +++++-
|
||||||
|
include/linux/bcma/bcma.h | 4 +
|
||||||
|
include/linux/bcma/bcma_soc.h | 16 ++++
|
||||||
|
7 files changed, 227 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 drivers/bcma/host_soc.c
|
||||||
|
create mode 100644 include/linux/bcma/bcma_soc.h
|
||||||
|
|
||||||
|
--- a/drivers/bcma/Kconfig
|
||||||
|
+++ b/drivers/bcma/Kconfig
|
||||||
|
@@ -27,6 +27,11 @@ config BCMA_HOST_PCI
|
||||||
|
bool "Support for BCMA on PCI-host bus"
|
||||||
|
depends on BCMA_HOST_PCI_POSSIBLE
|
||||||
|
|
||||||
|
+config BCMA_HOST_SOC
|
||||||
|
+ bool
|
||||||
|
+ depends on BCMA && MIPS
|
||||||
|
+ default n
|
||||||
|
+
|
||||||
|
config BCMA_DEBUG
|
||||||
|
bool "BCMA debugging"
|
||||||
|
depends on BCMA
|
||||||
|
--- a/drivers/bcma/Makefile
|
||||||
|
+++ b/drivers/bcma/Makefile
|
||||||
|
@@ -2,6 +2,7 @@ bcma-y += main.o scan.o core.o sprom
|
||||||
|
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
||||||
|
bcma-y += driver_pci.o
|
||||||
|
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
|
||||||
|
+bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
|
||||||
|
obj-$(CONFIG_BCMA) += bcma.o
|
||||||
|
|
||||||
|
ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/bcma/host_soc.c
|
||||||
|
@@ -0,0 +1,178 @@
|
||||||
|
+/*
|
||||||
|
+ * Broadcom specific AMBA
|
||||||
|
+ * System on Chip (SoC) Host
|
||||||
|
+ *
|
||||||
|
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "bcma_private.h"
|
||||||
|
+#include "scan.h"
|
||||||
|
+#include <linux/bcma/bcma.h>
|
||||||
|
+#include <linux/bcma/bcma_soc.h>
|
||||||
|
+
|
||||||
|
+static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
|
||||||
|
+{
|
||||||
|
+ return readb(core->io_addr + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
|
||||||
|
+{
|
||||||
|
+ return readw(core->io_addr + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
|
||||||
|
+{
|
||||||
|
+ return readl(core->io_addr + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
|
||||||
|
+ u8 value)
|
||||||
|
+{
|
||||||
|
+ writeb(value, core->io_addr + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
|
||||||
|
+ u16 value)
|
||||||
|
+{
|
||||||
|
+ writew(value, core->io_addr + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
|
||||||
|
+ u32 value)
|
||||||
|
+{
|
||||||
|
+ writel(value, core->io_addr + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_BCMA_BLOCKIO
|
||||||
|
+static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
|
||||||
|
+ size_t count, u16 offset, u8 reg_width)
|
||||||
|
+{
|
||||||
|
+ void __iomem *addr = core->io_addr + offset;
|
||||||
|
+
|
||||||
|
+ switch (reg_width) {
|
||||||
|
+ case sizeof(u8): {
|
||||||
|
+ u8 *buf = buffer;
|
||||||
|
+
|
||||||
|
+ while (count) {
|
||||||
|
+ *buf = __raw_readb(addr);
|
||||||
|
+ buf++;
|
||||||
|
+ count--;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case sizeof(u16): {
|
||||||
|
+ __le16 *buf = buffer;
|
||||||
|
+
|
||||||
|
+ WARN_ON(count & 1);
|
||||||
|
+ while (count) {
|
||||||
|
+ *buf = (__force __le16)__raw_readw(addr);
|
||||||
|
+ buf++;
|
||||||
|
+ count -= 2;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case sizeof(u32): {
|
||||||
|
+ __le32 *buf = buffer;
|
||||||
|
+
|
||||||
|
+ WARN_ON(count & 3);
|
||||||
|
+ while (count) {
|
||||||
|
+ *buf = (__force __le32)__raw_readl(addr);
|
||||||
|
+ buf++;
|
||||||
|
+ count -= 4;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ default:
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_host_soc_block_write(struct bcma_device *core,
|
||||||
|
+ const void *buffer,
|
||||||
|
+ size_t count, u16 offset, u8 reg_width)
|
||||||
|
+{
|
||||||
|
+ void __iomem *addr = core->io_addr + offset;
|
||||||
|
+
|
||||||
|
+ switch (reg_width) {
|
||||||
|
+ case sizeof(u8): {
|
||||||
|
+ const u8 *buf = buffer;
|
||||||
|
+
|
||||||
|
+ while (count) {
|
||||||
|
+ __raw_writeb(*buf, addr);
|
||||||
|
+ buf++;
|
||||||
|
+ count--;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case sizeof(u16): {
|
||||||
|
+ const __le16 *buf = buffer;
|
||||||
|
+
|
||||||
|
+ WARN_ON(count & 1);
|
||||||
|
+ while (count) {
|
||||||
|
+ __raw_writew((__force u16)(*buf), addr);
|
||||||
|
+ buf++;
|
||||||
|
+ count -= 2;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case sizeof(u32): {
|
||||||
|
+ const __le32 *buf = buffer;
|
||||||
|
+
|
||||||
|
+ WARN_ON(count & 3);
|
||||||
|
+ while (count) {
|
||||||
|
+ __raw_writel((__force u32)(*buf), addr);
|
||||||
|
+ buf++;
|
||||||
|
+ count -= 4;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ default:
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+#endif /* CONFIG_BCMA_BLOCKIO */
|
||||||
|
+
|
||||||
|
+static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
|
||||||
|
+{
|
||||||
|
+ return readl(core->io_wrap + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
|
||||||
|
+ u32 value)
|
||||||
|
+{
|
||||||
|
+ writel(value, core->io_wrap + offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct bcma_host_ops bcma_host_soc_ops = {
|
||||||
|
+ .read8 = bcma_host_soc_read8,
|
||||||
|
+ .read16 = bcma_host_soc_read16,
|
||||||
|
+ .read32 = bcma_host_soc_read32,
|
||||||
|
+ .write8 = bcma_host_soc_write8,
|
||||||
|
+ .write16 = bcma_host_soc_write16,
|
||||||
|
+ .write32 = bcma_host_soc_write32,
|
||||||
|
+#ifdef CONFIG_BCMA_BLOCKIO
|
||||||
|
+ .block_read = bcma_host_soc_block_read,
|
||||||
|
+ .block_write = bcma_host_soc_block_write,
|
||||||
|
+#endif
|
||||||
|
+ .aread32 = bcma_host_soc_aread32,
|
||||||
|
+ .awrite32 = bcma_host_soc_awrite32,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int __init bcma_host_soc_register(struct bcma_soc *soc)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = &soc->bus;
|
||||||
|
+
|
||||||
|
+ /* iomap only first core. We have to read some register on this core
|
||||||
|
+ * to scan the bus.
|
||||||
|
+ */
|
||||||
|
+ bus->mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
|
||||||
|
+ if (!bus->mmio)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ /* Host specific */
|
||||||
|
+ bus->hosttype = BCMA_HOSTTYPE_SOC;
|
||||||
|
+ bus->ops = &bcma_host_soc_ops;
|
||||||
|
+
|
||||||
|
+ /* Register */
|
||||||
|
+ return bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
|
||||||
|
+}
|
||||||
|
--- a/drivers/bcma/main.c
|
||||||
|
+++ b/drivers/bcma/main.c
|
||||||
|
@@ -95,6 +95,7 @@ static int bcma_register_cores(struct bc
|
||||||
|
break;
|
||||||
|
case BCMA_HOSTTYPE_NONE:
|
||||||
|
case BCMA_HOSTTYPE_SDIO:
|
||||||
|
+ case BCMA_HOSTTYPE_SOC:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/drivers/bcma/scan.c
|
||||||
|
+++ b/drivers/bcma/scan.c
|
||||||
|
@@ -337,6 +337,14 @@ static int bcma_get_next_core(struct bcm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
|
||||||
|
+ core->io_addr = ioremap(core->addr, BCMA_CORE_SIZE);
|
||||||
|
+ if (!core->io_addr)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ core->io_wrap = ioremap(core->wrap, BCMA_CORE_SIZE);
|
||||||
|
+ if (!core->io_wrap)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -369,7 +377,13 @@ int bcma_bus_scan(struct bcma_bus *bus)
|
||||||
|
bcma_init_bus(bus);
|
||||||
|
|
||||||
|
erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
|
||||||
|
- eromptr = bus->mmio;
|
||||||
|
+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
|
||||||
|
+ eromptr = ioremap(erombase, BCMA_CORE_SIZE);
|
||||||
|
+ if (!eromptr)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ } else
|
||||||
|
+ eromptr = bus->mmio;
|
||||||
|
+
|
||||||
|
eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
|
||||||
|
|
||||||
|
bcma_scan_switch_core(bus, erombase);
|
||||||
|
@@ -417,7 +431,13 @@ int __init bcma_bus_scan_early(struct bc
|
||||||
|
int err, core_num = 0;
|
||||||
|
|
||||||
|
erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
|
||||||
|
- eromptr = bus->mmio;
|
||||||
|
+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
|
||||||
|
+ eromptr = ioremap(erombase, BCMA_CORE_SIZE);
|
||||||
|
+ if (!eromptr)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ } else
|
||||||
|
+ eromptr = bus->mmio;
|
||||||
|
+
|
||||||
|
eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
|
||||||
|
|
||||||
|
bcma_scan_switch_core(bus, erombase);
|
||||||
|
--- a/include/linux/bcma/bcma.h
|
||||||
|
+++ b/include/linux/bcma/bcma.h
|
||||||
|
@@ -17,6 +17,7 @@ enum bcma_hosttype {
|
||||||
|
BCMA_HOSTTYPE_NONE,
|
||||||
|
BCMA_HOSTTYPE_PCI,
|
||||||
|
BCMA_HOSTTYPE_SDIO,
|
||||||
|
+ BCMA_HOSTTYPE_SOC,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bcma_chipinfo {
|
||||||
|
@@ -133,6 +134,9 @@ struct bcma_device {
|
||||||
|
u32 addr;
|
||||||
|
u32 wrap;
|
||||||
|
|
||||||
|
+ void __iomem *io_addr;
|
||||||
|
+ void __iomem *io_wrap;
|
||||||
|
+
|
||||||
|
void *drvdata;
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/linux/bcma/bcma_soc.h
|
||||||
|
@@ -0,0 +1,16 @@
|
||||||
|
+#ifndef LINUX_BCMA_SOC_H_
|
||||||
|
+#define LINUX_BCMA_SOC_H_
|
||||||
|
+
|
||||||
|
+#include <linux/bcma/bcma.h>
|
||||||
|
+
|
||||||
|
+struct bcma_soc {
|
||||||
|
+ struct bcma_bus bus;
|
||||||
|
+ struct bcma_device core_cc;
|
||||||
|
+ struct bcma_device core_mips;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int __init bcma_host_soc_register(struct bcma_soc *soc);
|
||||||
|
+
|
||||||
|
+int bcma_bus_register(struct bcma_bus *bus);
|
||||||
|
+
|
||||||
|
+#endif /* LINUX_BCMA_SOC_H_ */
|
|
@ -0,0 +1,402 @@
|
||||||
|
From 0a1a5fd8aab864e7b531ab88fd317ff7278d884d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Mon, 6 Jun 2011 00:07:32 +0200
|
||||||
|
Subject: [PATCH 05/14] bcma: add mips driver
|
||||||
|
|
||||||
|
This adds a mips driver to bcma. This is only found on embedded
|
||||||
|
devices. For now the driver just initializes the irqs used on this
|
||||||
|
system.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/Kconfig | 11 ++-
|
||||||
|
drivers/bcma/Makefile | 1 +
|
||||||
|
drivers/bcma/driver_mips.c | 234 +++++++++++++++++++++++++++++++++
|
||||||
|
drivers/bcma/main.c | 19 +++
|
||||||
|
include/linux/bcma/bcma.h | 2 +
|
||||||
|
include/linux/bcma/bcma_driver_mips.h | 49 +++++++
|
||||||
|
6 files changed, 315 insertions(+), 1 deletions(-)
|
||||||
|
create mode 100644 drivers/bcma/driver_mips.c
|
||||||
|
create mode 100644 include/linux/bcma/bcma_driver_mips.h
|
||||||
|
|
||||||
|
--- a/drivers/bcma/Kconfig
|
||||||
|
+++ b/drivers/bcma/Kconfig
|
||||||
|
@@ -29,9 +29,18 @@ config BCMA_HOST_PCI
|
||||||
|
|
||||||
|
config BCMA_HOST_SOC
|
||||||
|
bool
|
||||||
|
- depends on BCMA && MIPS
|
||||||
|
+ depends on BCMA_DRIVER_MIPS
|
||||||
|
default n
|
||||||
|
|
||||||
|
+config BCMA_DRIVER_MIPS
|
||||||
|
+ bool "BCMA Broadcom MIPS core driver"
|
||||||
|
+ depends on BCMA && MIPS
|
||||||
|
+ help
|
||||||
|
+ Driver for the Broadcom MIPS core attached to Broadcom specific
|
||||||
|
+ Advanced Microcontroller Bus.
|
||||||
|
+
|
||||||
|
+ If unsure, say N
|
||||||
|
+
|
||||||
|
config BCMA_DEBUG
|
||||||
|
bool "BCMA debugging"
|
||||||
|
depends on BCMA
|
||||||
|
--- a/drivers/bcma/Makefile
|
||||||
|
+++ b/drivers/bcma/Makefile
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
bcma-y += main.o scan.o core.o sprom.o
|
||||||
|
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
||||||
|
bcma-y += driver_pci.o
|
||||||
|
+bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
|
||||||
|
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
|
||||||
|
bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
|
||||||
|
obj-$(CONFIG_BCMA) += bcma.o
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/bcma/driver_mips.c
|
||||||
|
@@ -0,0 +1,234 @@
|
||||||
|
+/*
|
||||||
|
+ * Broadcom specific AMBA
|
||||||
|
+ * Broadcom MIPS32 74K core driver
|
||||||
|
+ *
|
||||||
|
+ * Copyright 2009, Broadcom Corporation
|
||||||
|
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
|
||||||
|
+ * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
|
||||||
|
+ * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
+ *
|
||||||
|
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "bcma_private.h"
|
||||||
|
+
|
||||||
|
+#include <linux/bcma/bcma.h>
|
||||||
|
+
|
||||||
|
+#include <linux/serial.h>
|
||||||
|
+#include <linux/serial_core.h>
|
||||||
|
+#include <linux/serial_reg.h>
|
||||||
|
+#include <linux/time.h>
|
||||||
|
+
|
||||||
|
+/* The 47162a0 hangs when reading its registers */
|
||||||
|
+static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
|
||||||
|
+{
|
||||||
|
+ return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
|
||||||
|
+ dev->id.id == BCMA_CORE_MIPS_74K;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline u32 mips_read32(struct bcma_drv_mips *mcore,
|
||||||
|
+ u16 offset)
|
||||||
|
+{
|
||||||
|
+ return bcma_read32(mcore->core, offset);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void mips_write32(struct bcma_drv_mips *mcore,
|
||||||
|
+ u16 offset,
|
||||||
|
+ u32 value)
|
||||||
|
+{
|
||||||
|
+ bcma_write32(mcore->core, offset, value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const u32 ipsflag_irq_mask[] = {
|
||||||
|
+ 0,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ1,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ2,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ3,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ4,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const u32 ipsflag_irq_shift[] = {
|
||||||
|
+ 0,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
|
||||||
|
+ BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
|
||||||
|
+{
|
||||||
|
+ u32 flag;
|
||||||
|
+
|
||||||
|
+ if (bcma_core_mips_bcm47162a0_quirk(dev))
|
||||||
|
+ return dev->core_index;
|
||||||
|
+ flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
|
||||||
|
+
|
||||||
|
+ return flag & 0x1F;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Get the MIPS IRQ assignment for a specified device.
|
||||||
|
+ * If unassigned, 0 is returned.
|
||||||
|
+ * If disabled, 5 is returned.
|
||||||
|
+ */
|
||||||
|
+unsigned int bcma_core_mips_irq(struct bcma_device *dev)
|
||||||
|
+{
|
||||||
|
+ struct bcma_device *mdev = dev->bus->drv_mips.core;
|
||||||
|
+ u32 irqflag;
|
||||||
|
+ unsigned int irq;
|
||||||
|
+
|
||||||
|
+ irqflag = bcma_core_mips_irqflag(dev);
|
||||||
|
+
|
||||||
|
+ for (irq = 1; irq <= 4; irq++)
|
||||||
|
+ if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
|
||||||
|
+ (1 << irqflag))
|
||||||
|
+ return irq;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(bcma_core_mips_irq);
|
||||||
|
+
|
||||||
|
+static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||||
|
+{
|
||||||
|
+ unsigned int oldirq = bcma_core_mips_irq(dev);
|
||||||
|
+ struct bcma_bus *bus = dev->bus;
|
||||||
|
+ struct bcma_device *mdev = bus->drv_mips.core;
|
||||||
|
+ u32 irqflag;
|
||||||
|
+
|
||||||
|
+ irqflag = bcma_core_mips_irqflag(dev);
|
||||||
|
+ BUG_ON(oldirq == 6);
|
||||||
|
+
|
||||||
|
+ dev->irq = irq + 2;
|
||||||
|
+
|
||||||
|
+ /* clear the old irq */
|
||||||
|
+ if (oldirq == 0)
|
||||||
|
+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
|
||||||
|
+ bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
|
||||||
|
+ ~(1 << irqflag));
|
||||||
|
+ else
|
||||||
|
+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
|
||||||
|
+
|
||||||
|
+ /* assign the new one */
|
||||||
|
+ if (irq == 0) {
|
||||||
|
+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
|
||||||
|
+ bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
|
||||||
|
+ (1 << irqflag));
|
||||||
|
+ } else {
|
||||||
|
+ u32 oldirqflag = bcma_read32(mdev,
|
||||||
|
+ BCMA_MIPS_MIPS74K_INTMASK(irq));
|
||||||
|
+ if (oldirqflag) {
|
||||||
|
+ struct bcma_device *core;
|
||||||
|
+
|
||||||
|
+ /* backplane irq line is in use, find out who uses
|
||||||
|
+ * it and set user to irq 0
|
||||||
|
+ */
|
||||||
|
+ list_for_each_entry_reverse(core, &bus->cores, list) {
|
||||||
|
+ if ((1 << bcma_core_mips_irqflag(core)) ==
|
||||||
|
+ oldirqflag) {
|
||||||
|
+ bcma_core_mips_set_irq(core, 0);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
|
||||||
|
+ 1 << irqflag);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pr_info("set_irq: core 0x%04x, irq %d => %d\n",
|
||||||
|
+ dev->id.id, oldirq + 2, irq + 2);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
|
||||||
|
+ printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
|
||||||
|
+ for (i = 0; i <= 6; i++)
|
||||||
|
+ printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
|
||||||
|
+ printk("\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
|
||||||
|
+{
|
||||||
|
+ struct bcma_device *core;
|
||||||
|
+
|
||||||
|
+ list_for_each_entry_reverse(core, &bus->cores, list) {
|
||||||
|
+ bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = mcore->core->bus;
|
||||||
|
+
|
||||||
|
+ mcore->flash_buswidth = 2;
|
||||||
|
+ if (bus->drv_cc.core) {
|
||||||
|
+ mcore->flash_window = 0x1c000000;
|
||||||
|
+ mcore->flash_window_size = 0x02000000;
|
||||||
|
+ switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
|
||||||
|
+ case BCMA_CC_FLASHT_STSER:
|
||||||
|
+ case BCMA_CC_FLASHT_ATSER:
|
||||||
|
+ pr_err("Serial flash not supported.\n");
|
||||||
|
+ break;
|
||||||
|
+ case BCMA_CC_FLASHT_PARA:
|
||||||
|
+ if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
|
||||||
|
+ BCMA_CC_OTPS) == 0)
|
||||||
|
+ mcore->flash_buswidth = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ mcore->flash_window = 0x1fc00000;
|
||||||
|
+ mcore->flash_window_size = 0x00400000;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void bcma_core_mips_init(struct bcma_drv_mips *mcore)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus;
|
||||||
|
+ struct bcma_device *core;
|
||||||
|
+ bus = mcore->core->bus;
|
||||||
|
+
|
||||||
|
+ pr_info("Initializing MIPS core...\n");
|
||||||
|
+
|
||||||
|
+ if (!mcore->setup_done)
|
||||||
|
+ mcore->assigned_irqs = 1;
|
||||||
|
+
|
||||||
|
+ /* Assign IRQs to all cores on the bus */
|
||||||
|
+ list_for_each_entry_reverse(core, &bus->cores, list) {
|
||||||
|
+ int mips_irq;
|
||||||
|
+ if (core->irq)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ mips_irq = bcma_core_mips_irq(core);
|
||||||
|
+ if (mips_irq > 4)
|
||||||
|
+ core->irq = 0;
|
||||||
|
+ else
|
||||||
|
+ core->irq = mips_irq + 2;
|
||||||
|
+ if (core->irq > 5)
|
||||||
|
+ continue;
|
||||||
|
+ switch (core->id.id) {
|
||||||
|
+ case BCMA_CORE_PCI:
|
||||||
|
+ case BCMA_CORE_PCIE:
|
||||||
|
+ case BCMA_CORE_ETHERNET:
|
||||||
|
+ case BCMA_CORE_ETHERNET_GBIT:
|
||||||
|
+ case BCMA_CORE_MAC_GBIT:
|
||||||
|
+ case BCMA_CORE_80211:
|
||||||
|
+ case BCMA_CORE_USB20_HOST:
|
||||||
|
+ /* These devices get their own IRQ line if available,
|
||||||
|
+ * the rest goes on IRQ0
|
||||||
|
+ */
|
||||||
|
+ if (mcore->assigned_irqs <= 4)
|
||||||
|
+ bcma_core_mips_set_irq(core,
|
||||||
|
+ mcore->assigned_irqs++);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ pr_info("IRQ reconfiguration done\n");
|
||||||
|
+ bcma_core_mips_dump_irq(bus);
|
||||||
|
+
|
||||||
|
+ if (mcore->setup_done)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ bcma_core_mips_flash_detect(mcore);
|
||||||
|
+ mcore->setup_done = true;
|
||||||
|
+}
|
||||||
|
--- a/drivers/bcma/main.c
|
||||||
|
+++ b/drivers/bcma/main.c
|
||||||
|
@@ -80,6 +80,7 @@ static int bcma_register_cores(struct bc
|
||||||
|
case BCMA_CORE_CHIPCOMMON:
|
||||||
|
case BCMA_CORE_PCI:
|
||||||
|
case BCMA_CORE_PCIE:
|
||||||
|
+ case BCMA_CORE_MIPS_74K:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -141,6 +142,15 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
|
bcma_core_chipcommon_init(&bus->drv_cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
|
+ /* Init MIPS core */
|
||||||
|
+ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||||
|
+ if (core) {
|
||||||
|
+ bus->drv_mips.core = core;
|
||||||
|
+ bcma_core_mips_init(&bus->drv_mips);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Init PCIE core */
|
||||||
|
core = bcma_find_core(bus, BCMA_CORE_PCIE);
|
||||||
|
if (core) {
|
||||||
|
@@ -208,6 +218,15 @@ int __init bcma_bus_early_register(struc
|
||||||
|
bcma_core_chipcommon_init(&bus->drv_cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
|
+ /* Init MIPS core */
|
||||||
|
+ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||||
|
+ if (core) {
|
||||||
|
+ bus->drv_mips.core = core;
|
||||||
|
+ bcma_core_mips_init(&bus->drv_mips);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
pr_info("Early bus registered\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
--- a/include/linux/bcma/bcma.h
|
||||||
|
+++ b/include/linux/bcma/bcma.h
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
#include <linux/bcma/bcma_driver_chipcommon.h>
|
||||||
|
#include <linux/bcma/bcma_driver_pci.h>
|
||||||
|
+#include <linux/bcma/bcma_driver_mips.h>
|
||||||
|
#include <linux/ssb/ssb.h> /* SPROM sharing */
|
||||||
|
|
||||||
|
#include "bcma_regs.h"
|
||||||
|
@@ -193,6 +194,7 @@ struct bcma_bus {
|
||||||
|
|
||||||
|
struct bcma_drv_cc drv_cc;
|
||||||
|
struct bcma_drv_pci drv_pci;
|
||||||
|
+ struct bcma_drv_mips drv_mips;
|
||||||
|
|
||||||
|
/* We decided to share SPROM struct with SSB as long as we do not need
|
||||||
|
* any hacks for BCMA. This simplifies drivers code. */
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/linux/bcma/bcma_driver_mips.h
|
||||||
|
@@ -0,0 +1,49 @@
|
||||||
|
+#ifndef LINUX_BCMA_DRIVER_MIPS_H_
|
||||||
|
+#define LINUX_BCMA_DRIVER_MIPS_H_
|
||||||
|
+
|
||||||
|
+#define BCMA_MIPS_IPSFLAG 0x0F08
|
||||||
|
+/* which sbflags get routed to mips interrupt 1 */
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
|
||||||
|
+/* which sbflags get routed to mips interrupt 2 */
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
|
||||||
|
+/* which sbflags get routed to mips interrupt 3 */
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
|
||||||
|
+/* which sbflags get routed to mips interrupt 4 */
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
|
||||||
|
+#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
|
||||||
|
+
|
||||||
|
+/* MIPS 74K core registers */
|
||||||
|
+#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
|
||||||
|
+#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
|
||||||
|
+#define BCMA_MIPS_MIPS74K_BIST 0x000C
|
||||||
|
+#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
|
||||||
|
+#define BCMA_MIPS_MIPS74K_INTMASK(int) \
|
||||||
|
+ ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
|
||||||
|
+#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
|
||||||
|
+#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
|
||||||
|
+#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
|
||||||
|
+#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
|
||||||
|
+#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
|
||||||
|
+
|
||||||
|
+#define BCMA_MIPS_OOBSELOUTA30 0x100
|
||||||
|
+
|
||||||
|
+struct bcma_device;
|
||||||
|
+
|
||||||
|
+struct bcma_drv_mips {
|
||||||
|
+ struct bcma_device *core;
|
||||||
|
+ u8 setup_done:1;
|
||||||
|
+ unsigned int assigned_irqs;
|
||||||
|
+
|
||||||
|
+ u8 flash_buswidth;
|
||||||
|
+ u32 flash_window;
|
||||||
|
+ u32 flash_window_size;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
|
||||||
|
+
|
||||||
|
+extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
|
||||||
|
+
|
||||||
|
+#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
|
|
@ -0,0 +1,151 @@
|
||||||
|
From b7c100827012ba588089807475affe0c69a3f817 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Mon, 6 Jun 2011 00:07:33 +0200
|
||||||
|
Subject: [PATCH 06/14] bcma: add serial console support
|
||||||
|
|
||||||
|
This adds support for serial console to bcma, when operating on an
|
||||||
|
embedded device.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/bcma_private.h | 6 +++
|
||||||
|
drivers/bcma/driver_chipcommon.c | 64 +++++++++++++++++++++++++++++++++
|
||||||
|
drivers/bcma/driver_mips.c | 9 +++++
|
||||||
|
include/linux/bcma/bcma_driver_mips.h | 11 ++++++
|
||||||
|
4 files changed, 90 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bcma/bcma_private.h
|
||||||
|
+++ b/drivers/bcma/bcma_private.h
|
||||||
|
@@ -29,6 +29,12 @@ void bcma_init_bus(struct bcma_bus *bus)
|
||||||
|
/* sprom.c */
|
||||||
|
int bcma_sprom_get(struct bcma_bus *bus);
|
||||||
|
|
||||||
|
+/* driver_chipcommon.c */
|
||||||
|
+#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
|
+extern int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
|
||||||
|
+ struct bcma_drv_mips_serial_port *ports);
|
||||||
|
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_BCMA_HOST_PCI
|
||||||
|
/* host_pci.c */
|
||||||
|
extern int __init bcma_host_pci_init(void);
|
||||||
|
--- a/drivers/bcma/driver_chipcommon.c
|
||||||
|
+++ b/drivers/bcma/driver_chipcommon.c
|
||||||
|
@@ -92,3 +92,67 @@ u32 bcma_chipco_gpio_polarity(struct bcm
|
||||||
|
{
|
||||||
|
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
|
+int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
|
||||||
|
+ struct bcma_drv_mips_serial_port *ports)
|
||||||
|
+{
|
||||||
|
+ int nr_ports = 0;
|
||||||
|
+ u32 plltype;
|
||||||
|
+ unsigned int irq;
|
||||||
|
+ u32 baud_base, div;
|
||||||
|
+ u32 i, n;
|
||||||
|
+ unsigned int ccrev = cc->core->id.rev;
|
||||||
|
+
|
||||||
|
+ plltype = (cc->capabilities & BCMA_CC_CAP_PLLT);
|
||||||
|
+ irq = bcma_core_mips_irq(cc->core);
|
||||||
|
+
|
||||||
|
+ if ((ccrev >= 11) && (ccrev != 15) && (ccrev != 20)) {
|
||||||
|
+ /* Fixed ALP clock */
|
||||||
|
+ baud_base = 20000000;
|
||||||
|
+ if (cc->capabilities & BCMA_CC_CAP_PMU) {
|
||||||
|
+ /* FIXME: baud_base is different for devices with a PMU */
|
||||||
|
+ WARN_ON(1);
|
||||||
|
+ }
|
||||||
|
+ div = 1;
|
||||||
|
+ if (ccrev >= 21) {
|
||||||
|
+ /* Turn off UART clock before switching clocksource. */
|
||||||
|
+ bcma_cc_write32(cc, BCMA_CC_CORECTL,
|
||||||
|
+ bcma_cc_read32(cc, BCMA_CC_CORECTL)
|
||||||
|
+ & ~BCMA_CC_CORECTL_UARTCLKEN);
|
||||||
|
+ }
|
||||||
|
+ /* Set the override bit so we don't divide it */
|
||||||
|
+ bcma_cc_write32(cc, BCMA_CC_CORECTL,
|
||||||
|
+ bcma_cc_read32(cc, BCMA_CC_CORECTL)
|
||||||
|
+ | BCMA_CC_CORECTL_UARTCLK0);
|
||||||
|
+ if (ccrev >= 21) {
|
||||||
|
+ /* Re-enable the UART clock. */
|
||||||
|
+ bcma_cc_write32(cc, BCMA_CC_CORECTL,
|
||||||
|
+ bcma_cc_read32(cc, BCMA_CC_CORECTL)
|
||||||
|
+ | BCMA_CC_CORECTL_UARTCLKEN);
|
||||||
|
+ }
|
||||||
|
+ } else
|
||||||
|
+ pr_err("serial not supported on this device ccrev: 0x%x\n",
|
||||||
|
+ ccrev);
|
||||||
|
+
|
||||||
|
+ /* Determine the registers of the UARTs */
|
||||||
|
+ n = (cc->capabilities & BCMA_CC_CAP_NRUART);
|
||||||
|
+ for (i = 0; i < n; i++) {
|
||||||
|
+ void __iomem *cc_mmio;
|
||||||
|
+ void __iomem *uart_regs;
|
||||||
|
+
|
||||||
|
+ cc_mmio = cc->core->bus->mmio +
|
||||||
|
+ (cc->core->core_index * BCMA_CORE_SIZE);
|
||||||
|
+ uart_regs = cc_mmio + BCMA_CC_UART0_DATA;
|
||||||
|
+ uart_regs += (i * 256);
|
||||||
|
+
|
||||||
|
+ nr_ports++;
|
||||||
|
+ ports[i].regs = uart_regs;
|
||||||
|
+ ports[i].irq = irq;
|
||||||
|
+ ports[i].baud_base = baud_base;
|
||||||
|
+ ports[i].reg_shift = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return nr_ports;
|
||||||
|
+}
|
||||||
|
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
|
||||||
|
--- a/drivers/bcma/driver_mips.c
|
||||||
|
+++ b/drivers/bcma/driver_mips.c
|
||||||
|
@@ -157,6 +157,14 @@ static void bcma_core_mips_dump_irq(stru
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void bcma_core_mips_serial_init(struct bcma_drv_mips *mcore)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = mcore->core->bus;
|
||||||
|
+
|
||||||
|
+ mcore->nr_serial_ports = bcma_chipco_serial_init(&bus->drv_cc,
|
||||||
|
+ mcore->serial_ports);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
|
||||||
|
{
|
||||||
|
struct bcma_bus *bus = mcore->core->bus;
|
||||||
|
@@ -229,6 +237,7 @@ void bcma_core_mips_init(struct bcma_drv
|
||||||
|
if (mcore->setup_done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ bcma_core_mips_serial_init(mcore);
|
||||||
|
bcma_core_mips_flash_detect(mcore);
|
||||||
|
mcore->setup_done = true;
|
||||||
|
}
|
||||||
|
--- a/include/linux/bcma/bcma_driver_mips.h
|
||||||
|
+++ b/include/linux/bcma/bcma_driver_mips.h
|
||||||
|
@@ -32,11 +32,22 @@
|
||||||
|
|
||||||
|
struct bcma_device;
|
||||||
|
|
||||||
|
+struct bcma_drv_mips_serial_port {
|
||||||
|
+ void *regs;
|
||||||
|
+ unsigned long clockspeed;
|
||||||
|
+ unsigned int irq;
|
||||||
|
+ unsigned int baud_base;
|
||||||
|
+ unsigned int reg_shift;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct bcma_drv_mips {
|
||||||
|
struct bcma_device *core;
|
||||||
|
u8 setup_done:1;
|
||||||
|
unsigned int assigned_irqs;
|
||||||
|
|
||||||
|
+ int nr_serial_ports;
|
||||||
|
+ struct bcma_drv_mips_serial_port serial_ports[4];
|
||||||
|
+
|
||||||
|
u8 flash_buswidth;
|
||||||
|
u32 flash_window;
|
||||||
|
u32 flash_window_size;
|
|
@ -0,0 +1,204 @@
|
||||||
|
From 257d5fe12600f08df764cac0abc17bef7b6fae9b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sun, 19 Jun 2011 17:51:30 +0200
|
||||||
|
Subject: [PATCH 07/14] bcma: get CPU clock
|
||||||
|
|
||||||
|
Add method to return the clock of the CPU. This is needed by the arch
|
||||||
|
code to calculate the mips_hpt_frequency.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/bcma_private.h | 3 +
|
||||||
|
drivers/bcma/driver_chipcommon_pmu.c | 87 +++++++++++++++++++++++++++
|
||||||
|
drivers/bcma/driver_mips.c | 12 ++++
|
||||||
|
include/linux/bcma/bcma_driver_chipcommon.h | 35 +++++++++++
|
||||||
|
include/linux/bcma/bcma_driver_mips.h | 1 +
|
||||||
|
5 files changed, 138 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bcma/bcma_private.h
|
||||||
|
+++ b/drivers/bcma/bcma_private.h
|
||||||
|
@@ -29,6 +29,9 @@ void bcma_init_bus(struct bcma_bus *bus)
|
||||||
|
/* sprom.c */
|
||||||
|
int bcma_sprom_get(struct bcma_bus *bus);
|
||||||
|
|
||||||
|
+/* driver_chipcommon_pmu.c */
|
||||||
|
+extern u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
|
||||||
|
+
|
||||||
|
/* driver_chipcommon.c */
|
||||||
|
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
|
extern int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
|
||||||
|
--- a/drivers/bcma/driver_chipcommon_pmu.c
|
||||||
|
+++ b/drivers/bcma/driver_chipcommon_pmu.c
|
||||||
|
@@ -11,6 +11,13 @@
|
||||||
|
#include "bcma_private.h"
|
||||||
|
#include <linux/bcma/bcma.h>
|
||||||
|
|
||||||
|
+static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
|
||||||
|
+{
|
||||||
|
+ bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
|
||||||
|
+ bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
|
||||||
|
+ return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
|
||||||
|
u32 offset, u32 mask, u32 set)
|
||||||
|
{
|
||||||
|
@@ -136,3 +143,83 @@ void bcma_pmu_init(struct bcma_drv_cc *c
|
||||||
|
bcma_pmu_swreg_init(cc);
|
||||||
|
bcma_pmu_workarounds(cc);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = cc->core->bus;
|
||||||
|
+
|
||||||
|
+ switch (bus->chipinfo.id) {
|
||||||
|
+ case 0x4716:
|
||||||
|
+ case 0x4748:
|
||||||
|
+ case 47162:
|
||||||
|
+ /* always 20Mhz */
|
||||||
|
+ return 20000 * 1000;
|
||||||
|
+ default:
|
||||||
|
+ pr_warn("No ALP clock specified for %04X device, "
|
||||||
|
+ "pmu rev. %d, using default %d Hz\n",
|
||||||
|
+ bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
|
||||||
|
+ }
|
||||||
|
+ return BCMA_CC_PMU_ALP_CLOCK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Find the output of the "m" pll divider given pll controls that start with
|
||||||
|
+ * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
|
||||||
|
+ */
|
||||||
|
+static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||||
|
+{
|
||||||
|
+ u32 tmp, div, ndiv, p1, p2, fc;
|
||||||
|
+
|
||||||
|
+ BUG_ON(!m || m > 4);
|
||||||
|
+
|
||||||
|
+ BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
|
||||||
|
+
|
||||||
|
+ tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
|
||||||
|
+ p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
|
||||||
|
+ p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
|
||||||
|
+
|
||||||
|
+ tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
|
||||||
|
+ div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
|
||||||
|
+ BCMA_CC_PPL_MDIV_MASK;
|
||||||
|
+
|
||||||
|
+ tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
|
||||||
|
+ ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
|
||||||
|
+
|
||||||
|
+ /* Do calculation in Mhz */
|
||||||
|
+ fc = bcma_pmu_alp_clock(cc) / 1000000;
|
||||||
|
+ fc = (p1 * ndiv * fc) / p2;
|
||||||
|
+
|
||||||
|
+ /* Return clock in Hertz */
|
||||||
|
+ return (fc / div) * 1000000;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* query bus clock frequency for PMU-enabled chipcommon */
|
||||||
|
+u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = cc->core->bus;
|
||||||
|
+
|
||||||
|
+ switch (bus->chipinfo.id) {
|
||||||
|
+ case 0x4716:
|
||||||
|
+ case 0x4748:
|
||||||
|
+ case 47162:
|
||||||
|
+ return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
|
||||||
|
+ BCMA_CC_PMU5_MAINPLL_SSB);
|
||||||
|
+ default:
|
||||||
|
+ pr_warn("No backplane clock specified for %04X device, "
|
||||||
|
+ "pmu rev. %d, using default %d Hz\n",
|
||||||
|
+ bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
|
||||||
|
+ }
|
||||||
|
+ return BCMA_CC_PMU_HT_CLOCK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* query cpu clock frequency for PMU-enabled chipcommon */
|
||||||
|
+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = cc->core->bus;
|
||||||
|
+
|
||||||
|
+ if ((cc->pmu.rev == 5 || cc->pmu.rev == 6 || cc->pmu.rev == 7) &&
|
||||||
|
+ (bus->chipinfo.id != 0x4319))
|
||||||
|
+ return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
|
||||||
|
+ BCMA_CC_PMU5_MAINPLL_CPU);
|
||||||
|
+
|
||||||
|
+ return bcma_pmu_get_clockcontrol(cc);
|
||||||
|
+}
|
||||||
|
--- a/drivers/bcma/driver_mips.c
|
||||||
|
+++ b/drivers/bcma/driver_mips.c
|
||||||
|
@@ -157,6 +157,18 @@ static void bcma_core_mips_dump_irq(stru
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = mcore->core->bus;
|
||||||
|
+
|
||||||
|
+ if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
|
||||||
|
+ return bcma_pmu_get_clockcpu(&bus->drv_cc);
|
||||||
|
+
|
||||||
|
+ pr_err("No PMU available, need this to get the cpu clock\n");
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+EXPORT_SYMBOL(bcma_cpu_clock);
|
||||||
|
+
|
||||||
|
static void bcma_core_mips_serial_init(struct bcma_drv_mips *mcore)
|
||||||
|
{
|
||||||
|
struct bcma_bus *bus = mcore->core->bus;
|
||||||
|
--- a/include/linux/bcma/bcma_driver_chipcommon.h
|
||||||
|
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
|
||||||
|
@@ -246,6 +246,41 @@
|
||||||
|
#define BCMA_CC_PLLCTL_DATA 0x0664
|
||||||
|
#define BCMA_CC_SPROM 0x0830 /* SPROM beginning */
|
||||||
|
|
||||||
|
+/* Divider allocation in 4716/47162/5356 */
|
||||||
|
+#define BCMA_CC_PMU5_MAINPLL_CPU 1
|
||||||
|
+#define BCMA_CC_PMU5_MAINPLL_MEM 2
|
||||||
|
+#define BCMA_CC_PMU5_MAINPLL_SSB 3
|
||||||
|
+
|
||||||
|
+/* PLL usage in 4716/47162 */
|
||||||
|
+#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
|
||||||
|
+
|
||||||
|
+/* ALP clock on pre-PMU chips */
|
||||||
|
+#define BCMA_CC_PMU_ALP_CLOCK 20000000
|
||||||
|
+/* HT clock for systems with PMU-enabled chipcommon */
|
||||||
|
+#define BCMA_CC_PMU_HT_CLOCK 80000000
|
||||||
|
+
|
||||||
|
+/* PMU rev 5 (& 6) */
|
||||||
|
+#define BCMA_CC_PPL_P1P2_OFF 0
|
||||||
|
+#define BCMA_CC_PPL_P1_MASK 0x0f000000
|
||||||
|
+#define BCMA_CC_PPL_P1_SHIFT 24
|
||||||
|
+#define BCMA_CC_PPL_P2_MASK 0x00f00000
|
||||||
|
+#define BCMA_CC_PPL_P2_SHIFT 20
|
||||||
|
+#define BCMA_CC_PPL_M14_OFF 1
|
||||||
|
+#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
|
||||||
|
+#define BCMA_CC_PPL_MDIV_WIDTH 8
|
||||||
|
+#define BCMA_CC_PPL_NM5_OFF 2
|
||||||
|
+#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
|
||||||
|
+#define BCMA_CC_PPL_NDIV_SHIFT 20
|
||||||
|
+#define BCMA_CC_PPL_FMAB_OFF 3
|
||||||
|
+#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
|
||||||
|
+#define BCMA_CC_PPL_MRAT_SHIFT 28
|
||||||
|
+#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
|
||||||
|
+#define BCMA_CC_PPL_ABRAT_SHIFT 27
|
||||||
|
+#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
|
||||||
|
+#define BCMA_CC_PPL_PLLCTL_OFF 4
|
||||||
|
+#define BCMA_CC_PPL_PCHI_OFF 5
|
||||||
|
+#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
|
||||||
|
+
|
||||||
|
/* Data for the PMU, if available.
|
||||||
|
* Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
|
||||||
|
*/
|
||||||
|
--- a/include/linux/bcma/bcma_driver_mips.h
|
||||||
|
+++ b/include/linux/bcma/bcma_driver_mips.h
|
||||||
|
@@ -54,6 +54,7 @@ struct bcma_drv_mips {
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
|
||||||
|
+extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
|
||||||
|
|
||||||
|
extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
From f93062e72447b4a4a51afbe33ea086ce8c922587 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sun, 19 Jun 2011 17:52:09 +0200
|
||||||
|
Subject: [PATCH 08/14] bcma: add pci(e) host mode
|
||||||
|
|
||||||
|
This adds some stub for a pci(e) host controller. This controller is
|
||||||
|
found on some embedded devices to attach other chips.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/Kconfig | 6 ++++
|
||||||
|
drivers/bcma/Makefile | 1 +
|
||||||
|
drivers/bcma/bcma_private.h | 6 ++++
|
||||||
|
drivers/bcma/driver_pci.c | 14 ++++++++++-
|
||||||
|
drivers/bcma/driver_pci_host.c | 43 ++++++++++++++++++++++++++++++++++
|
||||||
|
include/linux/bcma/bcma_driver_pci.h | 1 +
|
||||||
|
6 files changed, 70 insertions(+), 1 deletions(-)
|
||||||
|
create mode 100644 drivers/bcma/driver_pci_host.c
|
||||||
|
|
||||||
|
--- a/drivers/bcma/Kconfig
|
||||||
|
+++ b/drivers/bcma/Kconfig
|
||||||
|
@@ -32,6 +32,12 @@ config BCMA_HOST_SOC
|
||||||
|
depends on BCMA_DRIVER_MIPS
|
||||||
|
default n
|
||||||
|
|
||||||
|
+config BCMA_DRIVER_PCI_HOSTMODE
|
||||||
|
+ bool "Hostmode support for BCMA PCI core"
|
||||||
|
+ depends on BCMA_DRIVER_MIPS
|
||||||
|
+ help
|
||||||
|
+ PCIcore hostmode operation (external PCI bus).
|
||||||
|
+
|
||||||
|
config BCMA_DRIVER_MIPS
|
||||||
|
bool "BCMA Broadcom MIPS core driver"
|
||||||
|
depends on BCMA && MIPS
|
||||||
|
--- a/drivers/bcma/Makefile
|
||||||
|
+++ b/drivers/bcma/Makefile
|
||||||
|
@@ -1,6 +1,7 @@
|
||||||
|
bcma-y += main.o scan.o core.o sprom.o
|
||||||
|
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
||||||
|
bcma-y += driver_pci.o
|
||||||
|
+bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
|
||||||
|
bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
|
||||||
|
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
|
||||||
|
bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
|
||||||
|
--- a/drivers/bcma/bcma_private.h
|
||||||
|
+++ b/drivers/bcma/bcma_private.h
|
||||||
|
@@ -38,6 +38,12 @@ extern int bcma_chipco_serial_init(struc
|
||||||
|
struct bcma_drv_mips_serial_port *ports);
|
||||||
|
#endif /* CONFIG_BCMA_DRIVER_MIPS */
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||||
|
+/* driver_pci_host.c */
|
||||||
|
+int bcma_core_pci_in_hostmode(struct bcma_drv_pci *pc);
|
||||||
|
+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
|
||||||
|
+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_BCMA_HOST_PCI
|
||||||
|
/* host_pci.c */
|
||||||
|
extern int __init bcma_host_pci_init(void);
|
||||||
|
--- a/drivers/bcma/driver_pci.c
|
||||||
|
+++ b/drivers/bcma/driver_pci.c
|
||||||
|
@@ -159,9 +159,21 @@ static void bcma_pcicore_serdes_workarou
|
||||||
|
|
||||||
|
void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||||
|
{
|
||||||
|
+ struct bcma_device *core = pc->core;
|
||||||
|
+
|
||||||
|
if (pc->setup_done)
|
||||||
|
return;
|
||||||
|
- bcma_pcicore_serdes_workaround(pc);
|
||||||
|
+
|
||||||
|
+ if (!bcma_core_is_enabled(core))
|
||||||
|
+ bcma_core_enable(core, 0);
|
||||||
|
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||||
|
+ pc->hostmode = bcma_core_pci_in_hostmode(pc);
|
||||||
|
+ if (pc->hostmode)
|
||||||
|
+ bcma_core_pci_hostmode_init(pc);
|
||||||
|
+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
|
||||||
|
+ if (!pc->hostmode)
|
||||||
|
+ bcma_pcicore_serdes_workaround(pc);
|
||||||
|
+
|
||||||
|
pc->setup_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/bcma/driver_pci_host.c
|
||||||
|
@@ -0,0 +1,43 @@
|
||||||
|
+/*
|
||||||
|
+ * Broadcom specific AMBA
|
||||||
|
+ * PCI Host mode
|
||||||
|
+ *
|
||||||
|
+ * Copyright 2005, Broadcom Corporation
|
||||||
|
+ *
|
||||||
|
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "bcma_private.h"
|
||||||
|
+#include <linux/bcma/bcma.h>
|
||||||
|
+
|
||||||
|
+#include <asm/paccess.h>
|
||||||
|
+/* Probe a 32bit value on the bus and catch bus exceptions.
|
||||||
|
+ * Returns nonzero on a bus exception.
|
||||||
|
+ * This is MIPS specific */
|
||||||
|
+#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||||
|
+{
|
||||||
|
+ /* TODO: implement PCI host mode */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int bcma_core_pci_in_hostmode(struct bcma_drv_pci *pc)
|
||||||
|
+{
|
||||||
|
+ struct bcma_bus *bus = pc->core->bus;
|
||||||
|
+ u16 chipid_top;
|
||||||
|
+ u32 tmp;
|
||||||
|
+
|
||||||
|
+ chipid_top = (bus->chipinfo.id & 0xFF00);
|
||||||
|
+ if (chipid_top != 0x4700 &&
|
||||||
|
+ chipid_top != 0x5300)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+/* TODO: add when sprom is available
|
||||||
|
+ * if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
|
||||||
|
+ * return 0;
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ return !mips_busprobe32(tmp, (bus->mmio + (pc->core->core_index *
|
||||||
|
+ BCMA_CORE_SIZE)));
|
||||||
|
+}
|
||||||
|
--- a/include/linux/bcma/bcma_driver_pci.h
|
||||||
|
+++ b/include/linux/bcma/bcma_driver_pci.h
|
||||||
|
@@ -78,6 +78,7 @@ struct pci_dev;
|
||||||
|
struct bcma_drv_pci {
|
||||||
|
struct bcma_device *core;
|
||||||
|
u8 setup_done:1;
|
||||||
|
+ u8 hostmode:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Register access */
|
|
@ -0,0 +1,37 @@
|
||||||
|
From 5972feafaa3c71c1497b4ef4101b3c6855b7b64e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Sun, 19 Jun 2011 19:14:11 +0200
|
||||||
|
Subject: [PATCH 09/14] bcma: add check if sprom is available before accessing it.
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
drivers/bcma/main.c | 4 +++-
|
||||||
|
drivers/bcma/sprom.c | 3 +++
|
||||||
|
2 files changed, 6 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/bcma/main.c
|
||||||
|
+++ b/drivers/bcma/main.c
|
||||||
|
@@ -160,7 +160,9 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
|
|
||||||
|
/* Try to get SPROM */
|
||||||
|
err = bcma_sprom_get(bus);
|
||||||
|
- if (err) {
|
||||||
|
+ if (err == -ENOENT) {
|
||||||
|
+ pr_err("No SPROM available\n");
|
||||||
|
+ } else if (err) {
|
||||||
|
pr_err("Failed to get SPROM: %d\n", err);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
--- a/drivers/bcma/sprom.c
|
||||||
|
+++ b/drivers/bcma/sprom.c
|
||||||
|
@@ -143,6 +143,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
|
||||||
|
if (!bus->drv_cc.core)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
+ if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
|
||||||
|
+ return -ENOENT;
|
||||||
|
+
|
||||||
|
sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!sprom)
|
|
@ -0,0 +1,439 @@
|
||||||
|
From c0886db6357de20fba4f7c0602eceefba3ad343b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Mon, 6 Jun 2011 00:07:36 +0200
|
||||||
|
Subject: [PATCH 10/14] bcm47xx: prepare to support different buses
|
||||||
|
|
||||||
|
The ssb bus is not hod directly any more. there is now a union which
|
||||||
|
contains all the supported buses, now just ssb. As just one system bus
|
||||||
|
can be used at a time the union does not cause any problems.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
arch/mips/bcm47xx/gpio.c | 56 ++++++++++++++++----------
|
||||||
|
arch/mips/bcm47xx/nvram.c | 15 +++++--
|
||||||
|
arch/mips/bcm47xx/serial.c | 13 +++++-
|
||||||
|
arch/mips/bcm47xx/setup.c | 32 +++++++++++---
|
||||||
|
arch/mips/bcm47xx/time.c | 9 +++-
|
||||||
|
arch/mips/bcm47xx/wgt634u.c | 13 ++++--
|
||||||
|
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 14 ++++++-
|
||||||
|
arch/mips/include/asm/mach-bcm47xx/gpio.h | 55 ++++++++++++++++++-------
|
||||||
|
drivers/watchdog/bcm47xx_wdt.c | 12 +++++-
|
||||||
|
9 files changed, 158 insertions(+), 61 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/bcm47xx/gpio.c
|
||||||
|
+++ b/arch/mips/bcm47xx/gpio.c
|
||||||
|
@@ -20,42 +20,54 @@ static DECLARE_BITMAP(gpio_in_use, BCM47
|
||||||
|
|
||||||
|
int gpio_request(unsigned gpio, const char *tag)
|
||||||
|
{
|
||||||
|
- if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
|
||||||
|
- ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- if (ssb_extif_available(&ssb_bcm47xx.extif) &&
|
||||||
|
- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- if (test_and_set_bit(gpio, gpio_in_use))
|
||||||
|
- return -EBUSY;
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
|
||||||
|
+ ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
|
||||||
|
+ ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ if (test_and_set_bit(gpio, gpio_in_use))
|
||||||
|
+ return -EBUSY;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(gpio_request);
|
||||||
|
|
||||||
|
void gpio_free(unsigned gpio)
|
||||||
|
{
|
||||||
|
- if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
|
||||||
|
- ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
|
||||||
|
- return;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
|
||||||
|
+ ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
|
||||||
|
+ ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
- if (ssb_extif_available(&ssb_bcm47xx.extif) &&
|
||||||
|
- ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
|
||||||
|
+ clear_bit(gpio, gpio_in_use);
|
||||||
|
return;
|
||||||
|
-
|
||||||
|
- clear_bit(gpio, gpio_in_use);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(gpio_free);
|
||||||
|
|
||||||
|
int gpio_to_irq(unsigned gpio)
|
||||||
|
{
|
||||||
|
- if (ssb_chipco_available(&ssb_bcm47xx.chipco))
|
||||||
|
- return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
|
||||||
|
- else if (ssb_extif_available(&ssb_bcm47xx.extif))
|
||||||
|
- return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
|
||||||
|
- else
|
||||||
|
- return -EINVAL;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
|
||||||
|
+ return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
|
||||||
|
+ else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
|
||||||
|
+ return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
|
||||||
|
+ else
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(gpio_to_irq);
|
||||||
|
--- a/arch/mips/bcm47xx/nvram.c
|
||||||
|
+++ b/arch/mips/bcm47xx/nvram.c
|
||||||
|
@@ -26,14 +26,21 @@ static char nvram_buf[NVRAM_SPACE];
|
||||||
|
/* Probe for NVRAM header */
|
||||||
|
static void early_nvram_init(void)
|
||||||
|
{
|
||||||
|
- struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
|
||||||
|
+ struct ssb_mipscore *mcore_ssb;
|
||||||
|
struct nvram_header *header;
|
||||||
|
int i;
|
||||||
|
- u32 base, lim, off;
|
||||||
|
+ u32 base = 0;
|
||||||
|
+ u32 lim = 0;
|
||||||
|
+ u32 off;
|
||||||
|
u32 *src, *dst;
|
||||||
|
|
||||||
|
- base = mcore->flash_window;
|
||||||
|
- lim = mcore->flash_window_size;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ mcore_ssb = &bcm47xx_bus.ssb.mipscore;
|
||||||
|
+ base = mcore_ssb->flash_window;
|
||||||
|
+ lim = mcore_ssb->flash_window_size;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
off = FLASH_MIN;
|
||||||
|
while (off <= lim) {
|
||||||
|
--- a/arch/mips/bcm47xx/serial.c
|
||||||
|
+++ b/arch/mips/bcm47xx/serial.c
|
||||||
|
@@ -23,10 +23,10 @@ static struct platform_device uart8250_d
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
-static int __init uart8250_init(void)
|
||||||
|
+static int __init uart8250_init_ssb(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
- struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore);
|
||||||
|
+ struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
|
||||||
|
|
||||||
|
memset(&uart8250_data, 0, sizeof(uart8250_data));
|
||||||
|
|
||||||
|
@@ -45,6 +45,15 @@ static int __init uart8250_init(void)
|
||||||
|
return platform_device_register(&uart8250_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int __init uart8250_init(void)
|
||||||
|
+{
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ return uart8250_init_ssb();
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
module_init(uart8250_init);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
|
||||||
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
|
@@ -35,15 +35,22 @@
|
||||||
|
#include <bcm47xx.h>
|
||||||
|
#include <asm/mach-bcm47xx/nvram.h>
|
||||||
|
|
||||||
|
-struct ssb_bus ssb_bcm47xx;
|
||||||
|
-EXPORT_SYMBOL(ssb_bcm47xx);
|
||||||
|
+union bcm47xx_bus bcm47xx_bus;
|
||||||
|
+EXPORT_SYMBOL(bcm47xx_bus);
|
||||||
|
+
|
||||||
|
+enum bcm47xx_bus_type bcm47xx_active_bus_type;
|
||||||
|
+EXPORT_SYMBOL(bcm47xx_active_bus_type);
|
||||||
|
|
||||||
|
static void bcm47xx_machine_restart(char *command)
|
||||||
|
{
|
||||||
|
printk(KERN_ALERT "Please stand by while rebooting the system...\n");
|
||||||
|
local_irq_disable();
|
||||||
|
/* Set the watchdog timer to reset immediately */
|
||||||
|
- ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
while (1)
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
@@ -52,7 +59,11 @@ static void bcm47xx_machine_halt(void)
|
||||||
|
{
|
||||||
|
/* Disable interrupts and watchdog and spin forever */
|
||||||
|
local_irq_disable();
|
||||||
|
- ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
while (1)
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
@@ -247,7 +258,7 @@ static int bcm47xx_get_invariants(struct
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void __init plat_mem_setup(void)
|
||||||
|
+static void __init bcm47xx_register_ssb(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
char buf[100];
|
||||||
|
@@ -258,12 +269,12 @@ void __init plat_mem_setup(void)
|
||||||
|
printk(KERN_WARNING "bcm47xx: someone else already registered"
|
||||||
|
" a ssb SPROM callback handler (err %d)\n", err);
|
||||||
|
|
||||||
|
- err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
|
||||||
|
+ err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
|
||||||
|
bcm47xx_get_invariants);
|
||||||
|
if (err)
|
||||||
|
panic("Failed to initialize SSB bus (err %d)\n", err);
|
||||||
|
|
||||||
|
- mcore = &ssb_bcm47xx.mipscore;
|
||||||
|
+ mcore = &bcm47xx_bus.ssb.mipscore;
|
||||||
|
if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
|
||||||
|
if (strstr(buf, "console=ttyS1")) {
|
||||||
|
struct ssb_serial_port port;
|
||||||
|
@@ -276,6 +287,14 @@ void __init plat_mem_setup(void)
|
||||||
|
memcpy(&mcore->serial_ports[1], &port, sizeof(port));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void __init plat_mem_setup(void)
|
||||||
|
+{
|
||||||
|
+ struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||||
|
+
|
||||||
|
+ bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
|
||||||
|
+ bcm47xx_register_ssb();
|
||||||
|
|
||||||
|
_machine_restart = bcm47xx_machine_restart;
|
||||||
|
_machine_halt = bcm47xx_machine_halt;
|
||||||
|
--- a/arch/mips/bcm47xx/time.c
|
||||||
|
+++ b/arch/mips/bcm47xx/time.c
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
|
||||||
|
void __init plat_time_init(void)
|
||||||
|
{
|
||||||
|
- unsigned long hz;
|
||||||
|
+ unsigned long hz = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use deterministic values for initial counter interrupt
|
||||||
|
@@ -39,7 +39,12 @@ void __init plat_time_init(void)
|
||||||
|
write_c0_count(0);
|
||||||
|
write_c0_compare(0xffff);
|
||||||
|
|
||||||
|
- hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!hz)
|
||||||
|
hz = 100000000;
|
||||||
|
|
||||||
|
--- a/arch/mips/bcm47xx/wgt634u.c
|
||||||
|
+++ b/arch/mips/bcm47xx/wgt634u.c
|
||||||
|
@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int ir
|
||||||
|
|
||||||
|
/* Interrupts are shared, check if the current one is
|
||||||
|
a GPIO interrupt. */
|
||||||
|
- if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
|
||||||
|
+ if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
|
||||||
|
SSB_CHIPCO_IRQ_GPIO))
|
||||||
|
return IRQ_NONE;
|
||||||
|
|
||||||
|
@@ -133,21 +133,24 @@ static int __init wgt634u_init(void)
|
||||||
|
* been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
|
||||||
|
+ if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB)
|
||||||
|
+ return -ENODEV;
|
||||||
|
+
|
||||||
|
+ u8 *et0mac = bcm47xx_bus.ssb.sprom.et0mac;
|
||||||
|
|
||||||
|
if (et0mac[0] == 0x00 &&
|
||||||
|
((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
|
||||||
|
(et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
|
||||||
|
- struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
|
||||||
|
+ struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
|
||||||
|
|
||||||
|
printk(KERN_INFO "WGT634U machine detected.\n");
|
||||||
|
|
||||||
|
if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
|
||||||
|
gpio_interrupt, IRQF_SHARED,
|
||||||
|
- "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
|
||||||
|
+ "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
|
||||||
|
gpio_direction_input(WGT634U_GPIO_RESET);
|
||||||
|
gpio_intmask(WGT634U_GPIO_RESET, 1);
|
||||||
|
- ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
|
||||||
|
+ ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
|
||||||
|
SSB_CHIPCO_IRQ_GPIO,
|
||||||
|
SSB_CHIPCO_IRQ_GPIO);
|
||||||
|
}
|
||||||
|
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
|
||||||
|
@@ -19,7 +19,17 @@
|
||||||
|
#ifndef __ASM_BCM47XX_H
|
||||||
|
#define __ASM_BCM47XX_H
|
||||||
|
|
||||||
|
-/* SSB bus */
|
||||||
|
-extern struct ssb_bus ssb_bcm47xx;
|
||||||
|
+#include <linux/ssb/ssb.h>
|
||||||
|
+
|
||||||
|
+enum bcm47xx_bus_type {
|
||||||
|
+ BCM47XX_BUS_TYPE_SSB,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+union bcm47xx_bus {
|
||||||
|
+ struct ssb_bus ssb;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern union bcm47xx_bus bcm47xx_bus;
|
||||||
|
+extern enum bcm47xx_bus_type bcm47xx_active_bus_type;
|
||||||
|
|
||||||
|
#endif /* __ASM_BCM47XX_H */
|
||||||
|
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
|
@@ -21,41 +21,66 @@ extern int gpio_to_irq(unsigned gpio);
|
||||||
|
|
||||||
|
static inline int gpio_get_value(unsigned gpio)
|
||||||
|
{
|
||||||
|
- return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gpio_set_value(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
- ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
+ value ? 1 << gpio : 0);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int gpio_direction_input(unsigned gpio)
|
||||||
|
{
|
||||||
|
- ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
|
||||||
|
- return 0;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int gpio_direction_output(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
- /* first set the gpio out value */
|
||||||
|
- ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
|
||||||
|
- /* then set the gpio mode */
|
||||||
|
- ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
|
||||||
|
- return 0;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ /* first set the gpio out value */
|
||||||
|
+ ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
+ value ? 1 << gpio : 0);
|
||||||
|
+ /* then set the gpio mode */
|
||||||
|
+ ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int gpio_intmask(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
- ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
|
||||||
|
- value ? 1 << gpio : 0);
|
||||||
|
- return 0;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
+ value ? 1 << gpio : 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int gpio_polarity(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
- ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
|
||||||
|
- value ? 1 << gpio : 0);
|
||||||
|
- return 0;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
+ value ? 1 << gpio : 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- a/drivers/watchdog/bcm47xx_wdt.c
|
||||||
|
+++ b/drivers/watchdog/bcm47xx_wdt.c
|
||||||
|
@@ -54,12 +54,20 @@ static atomic_t ticks;
|
||||||
|
static inline void bcm47xx_wdt_hw_start(void)
|
||||||
|
{
|
||||||
|
/* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
|
||||||
|
- ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff);
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bcm47xx_wdt_hw_stop(void)
|
||||||
|
{
|
||||||
|
- return ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
|
||||||
|
+ }
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bcm47xx_timer_tick(unsigned long unused)
|
|
@ -0,0 +1,395 @@
|
||||||
|
From 82d03f33ba3e41511e56bd6ae5ae93b3b1bd0b63 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Wed, 22 Jun 2011 22:16:35 +0200
|
||||||
|
Subject: [PATCH 11/14] bcm47xx: make it possible to build bcm47xx without ssb.
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
arch/mips/Kconfig | 8 +-------
|
||||||
|
arch/mips/bcm47xx/Kconfig | 18 ++++++++++++++++++
|
||||||
|
arch/mips/bcm47xx/Makefile | 3 ++-
|
||||||
|
arch/mips/bcm47xx/gpio.c | 6 ++++++
|
||||||
|
arch/mips/bcm47xx/nvram.c | 4 ++++
|
||||||
|
arch/mips/bcm47xx/serial.c | 4 ++++
|
||||||
|
arch/mips/bcm47xx/setup.c | 8 ++++++++
|
||||||
|
arch/mips/bcm47xx/time.c | 2 ++
|
||||||
|
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 4 ++++
|
||||||
|
arch/mips/include/asm/mach-bcm47xx/gpio.h | 12 ++++++++++++
|
||||||
|
arch/mips/pci/pci-bcm47xx.c | 6 ++++++
|
||||||
|
drivers/watchdog/bcm47xx_wdt.c | 4 ++++
|
||||||
|
12 files changed, 71 insertions(+), 8 deletions(-)
|
||||||
|
create mode 100644 arch/mips/bcm47xx/Kconfig
|
||||||
|
|
||||||
|
--- a/arch/mips/Kconfig
|
||||||
|
+++ b/arch/mips/Kconfig
|
||||||
|
@@ -91,15 +91,8 @@ config BCM47XX
|
||||||
|
select DMA_NONCOHERENT
|
||||||
|
select HW_HAS_PCI
|
||||||
|
select IRQ_CPU
|
||||||
|
- select SYS_HAS_CPU_MIPS32_R1
|
||||||
|
select SYS_SUPPORTS_32BIT_KERNEL
|
||||||
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
- select SSB
|
||||||
|
- select SSB_DRIVER_MIPS
|
||||||
|
- select SSB_DRIVER_EXTIF
|
||||||
|
- select SSB_EMBEDDED
|
||||||
|
- select SSB_B43_PCI_BRIDGE if PCI
|
||||||
|
- select SSB_PCICORE_HOSTMODE if PCI
|
||||||
|
select GENERIC_GPIO
|
||||||
|
select SYS_HAS_EARLY_PRINTK
|
||||||
|
select CFE
|
||||||
|
@@ -785,6 +778,7 @@ endchoice
|
||||||
|
|
||||||
|
source "arch/mips/alchemy/Kconfig"
|
||||||
|
source "arch/mips/ath79/Kconfig"
|
||||||
|
+source "arch/mips/bcm47xx/Kconfig"
|
||||||
|
source "arch/mips/bcm63xx/Kconfig"
|
||||||
|
source "arch/mips/jazz/Kconfig"
|
||||||
|
source "arch/mips/jz4740/Kconfig"
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/mips/bcm47xx/Kconfig
|
||||||
|
@@ -0,0 +1,18 @@
|
||||||
|
+if BCM47XX
|
||||||
|
+
|
||||||
|
+config BCM47XX_SSB
|
||||||
|
+ bool "SSB Support for Broadcom BCM47XX"
|
||||||
|
+ select SYS_HAS_CPU_MIPS32_R1
|
||||||
|
+ select SSB
|
||||||
|
+ select SSB_DRIVER_MIPS
|
||||||
|
+ select SSB_DRIVER_EXTIF
|
||||||
|
+ select SSB_EMBEDDED
|
||||||
|
+ select SSB_B43_PCI_BRIDGE if PCI
|
||||||
|
+ select SSB_PCICORE_HOSTMODE if PCI
|
||||||
|
+ default y
|
||||||
|
+ help
|
||||||
|
+ Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support bus.
|
||||||
|
+
|
||||||
|
+ This will generate an image with support for SSB and MIPS32 R2 instruction set.
|
||||||
|
+
|
||||||
|
+endif
|
||||||
|
--- a/arch/mips/bcm47xx/Makefile
|
||||||
|
+++ b/arch/mips/bcm47xx/Makefile
|
||||||
|
@@ -3,4 +3,5 @@
|
||||||
|
# under Linux.
|
||||||
|
#
|
||||||
|
|
||||||
|
-obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
|
||||||
|
+obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
|
||||||
|
+obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o
|
||||||
|
--- a/arch/mips/bcm47xx/gpio.c
|
||||||
|
+++ b/arch/mips/bcm47xx/gpio.c
|
||||||
|
@@ -21,6 +21,7 @@ static DECLARE_BITMAP(gpio_in_use, BCM47
|
||||||
|
int gpio_request(unsigned gpio, const char *tag)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
|
||||||
|
((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
|
||||||
|
@@ -34,6 +35,7 @@ int gpio_request(unsigned gpio, const ch
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -42,6 +44,7 @@ EXPORT_SYMBOL(gpio_request);
|
||||||
|
void gpio_free(unsigned gpio)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
|
||||||
|
((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
|
||||||
|
@@ -53,6 +56,7 @@ void gpio_free(unsigned gpio)
|
||||||
|
|
||||||
|
clear_bit(gpio, gpio_in_use);
|
||||||
|
return;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(gpio_free);
|
||||||
|
@@ -60,6 +64,7 @@ EXPORT_SYMBOL(gpio_free);
|
||||||
|
int gpio_to_irq(unsigned gpio)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
|
||||||
|
return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
|
||||||
|
@@ -67,6 +72,7 @@ int gpio_to_irq(unsigned gpio)
|
||||||
|
return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
--- a/arch/mips/bcm47xx/nvram.c
|
||||||
|
+++ b/arch/mips/bcm47xx/nvram.c
|
||||||
|
@@ -26,7 +26,9 @@ static char nvram_buf[NVRAM_SPACE];
|
||||||
|
/* Probe for NVRAM header */
|
||||||
|
static void early_nvram_init(void)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
struct ssb_mipscore *mcore_ssb;
|
||||||
|
+#endif
|
||||||
|
struct nvram_header *header;
|
||||||
|
int i;
|
||||||
|
u32 base = 0;
|
||||||
|
@@ -35,11 +37,13 @@ static void early_nvram_init(void)
|
||||||
|
u32 *src, *dst;
|
||||||
|
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
mcore_ssb = &bcm47xx_bus.ssb.mipscore;
|
||||||
|
base = mcore_ssb->flash_window;
|
||||||
|
lim = mcore_ssb->flash_window_size;
|
||||||
|
break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
off = FLASH_MIN;
|
||||||
|
--- a/arch/mips/bcm47xx/serial.c
|
||||||
|
+++ b/arch/mips/bcm47xx/serial.c
|
||||||
|
@@ -23,6 +23,7 @@ static struct platform_device uart8250_d
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
static int __init uart8250_init_ssb(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
@@ -44,12 +45,15 @@ static int __init uart8250_init_ssb(void
|
||||||
|
}
|
||||||
|
return platform_device_register(&uart8250_device);
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
static int __init uart8250_init(void)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
return uart8250_init_ssb();
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
|
@@ -47,9 +47,11 @@ static void bcm47xx_machine_restart(char
|
||||||
|
local_irq_disable();
|
||||||
|
/* Set the watchdog timer to reset immediately */
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
|
||||||
|
break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
while (1)
|
||||||
|
cpu_relax();
|
||||||
|
@@ -60,14 +62,17 @@ static void bcm47xx_machine_halt(void)
|
||||||
|
/* Disable interrupts and watchdog and spin forever */
|
||||||
|
local_irq_disable();
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
|
||||||
|
break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
while (1)
|
||||||
|
cpu_relax();
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
#define READ_FROM_NVRAM(_outvar, name, buf) \
|
||||||
|
if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
|
||||||
|
sprom->_outvar = simple_strtoul(buf, NULL, 0);
|
||||||
|
@@ -288,13 +293,16 @@ static void __init bcm47xx_register_ssb(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
void __init plat_mem_setup(void)
|
||||||
|
{
|
||||||
|
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
|
||||||
|
bcm47xx_register_ssb();
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
_machine_restart = bcm47xx_machine_restart;
|
||||||
|
_machine_halt = bcm47xx_machine_halt;
|
||||||
|
--- a/arch/mips/bcm47xx/time.c
|
||||||
|
+++ b/arch/mips/bcm47xx/time.c
|
||||||
|
@@ -40,9 +40,11 @@ void __init plat_time_init(void)
|
||||||
|
write_c0_compare(0xffff);
|
||||||
|
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
|
||||||
|
break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hz)
|
||||||
|
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
|
||||||
|
@@ -22,11 +22,15 @@
|
||||||
|
#include <linux/ssb/ssb.h>
|
||||||
|
|
||||||
|
enum bcm47xx_bus_type {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
BCM47XX_BUS_TYPE_SSB,
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
union bcm47xx_bus {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
struct ssb_bus ssb;
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern union bcm47xx_bus bcm47xx_bus;
|
||||||
|
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
|
@@ -22,8 +22,10 @@ extern int gpio_to_irq(unsigned gpio);
|
||||||
|
static inline int gpio_get_value(unsigned gpio)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -31,18 +33,22 @@ static inline int gpio_get_value(unsigne
|
||||||
|
static inline void gpio_set_value(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
value ? 1 << gpio : 0);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int gpio_direction_input(unsigned gpio)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
|
||||||
|
return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -50,6 +56,7 @@ static inline int gpio_direction_input(u
|
||||||
|
static inline int gpio_direction_output(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
/* first set the gpio out value */
|
||||||
|
ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
@@ -57,6 +64,7 @@ static inline int gpio_direction_output(
|
||||||
|
/* then set the gpio mode */
|
||||||
|
ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
|
||||||
|
return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -64,10 +72,12 @@ static inline int gpio_direction_output(
|
||||||
|
static inline int gpio_intmask(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
value ? 1 << gpio : 0);
|
||||||
|
return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -75,10 +85,12 @@ static inline int gpio_intmask(unsigned
|
||||||
|
static inline int gpio_polarity(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
value ? 1 << gpio : 0);
|
||||||
|
return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
--- a/arch/mips/pci/pci-bcm47xx.c
|
||||||
|
+++ b/arch/mips/pci/pci-bcm47xx.c
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/ssb/ssb.h>
|
||||||
|
+#include <bcm47xx.h>
|
||||||
|
|
||||||
|
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||||
|
{
|
||||||
|
@@ -33,9 +34,13 @@ int __init pcibios_map_irq(const struct
|
||||||
|
|
||||||
|
int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
int res;
|
||||||
|
u8 slot, pin;
|
||||||
|
|
||||||
|
+ if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
res = ssb_pcibios_plat_dev_init(dev);
|
||||||
|
if (res < 0) {
|
||||||
|
printk(KERN_ALERT "PCI: Failed to init device %s\n",
|
||||||
|
@@ -55,5 +60,6 @@ int pcibios_plat_dev_init(struct pci_dev
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->irq = res;
|
||||||
|
+#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--- a/drivers/watchdog/bcm47xx_wdt.c
|
||||||
|
+++ b/drivers/watchdog/bcm47xx_wdt.c
|
||||||
|
@@ -55,17 +55,21 @@ static inline void bcm47xx_wdt_hw_start(
|
||||||
|
{
|
||||||
|
/* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
|
||||||
|
break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int bcm47xx_wdt_hw_stop(void)
|
||||||
|
{
|
||||||
|
switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
|
@ -0,0 +1,410 @@
|
||||||
|
From 0b7b4817579b5b283e48b96de24b7b2c1a861644 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Mon, 6 Jun 2011 00:07:37 +0200
|
||||||
|
Subject: [PATCH 12/14] 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: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
arch/mips/bcm47xx/Kconfig | 13 ++++++
|
||||||
|
arch/mips/bcm47xx/gpio.c | 22 +++++++++++
|
||||||
|
arch/mips/bcm47xx/nvram.c | 10 +++++
|
||||||
|
arch/mips/bcm47xx/serial.c | 29 ++++++++++++++
|
||||||
|
arch/mips/bcm47xx/setup.c | 53 +++++++++++++++++++++++++-
|
||||||
|
arch/mips/bcm47xx/time.c | 5 ++
|
||||||
|
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 8 ++++
|
||||||
|
arch/mips/include/asm/mach-bcm47xx/gpio.h | 41 ++++++++++++++++++++
|
||||||
|
drivers/watchdog/bcm47xx_wdt.c | 11 +++++
|
||||||
|
9 files changed, 190 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/bcm47xx/Kconfig
|
||||||
|
+++ b/arch/mips/bcm47xx/Kconfig
|
||||||
|
@@ -15,4 +15,17 @@ config BCM47XX_SSB
|
||||||
|
|
||||||
|
This will generate an image with support for SSB and MIPS32 R2 instruction set.
|
||||||
|
|
||||||
|
+config BCM47XX_BCMA
|
||||||
|
+ bool "SSB 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
|
||||||
|
--- a/arch/mips/bcm47xx/gpio.c
|
||||||
|
+++ b/arch/mips/bcm47xx/gpio.c
|
||||||
|
@@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const ch
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ if ((unsigned)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 ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ clear_bit(gpio, gpio_in_use);
|
||||||
|
+ return;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(gpio_free);
|
||||||
|
@@ -73,6 +91,10 @@ int gpio_to_irq(unsigned gpio)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
--- a/arch/mips/bcm47xx/nvram.c
|
||||||
|
+++ b/arch/mips/bcm47xx/nvram.c
|
||||||
|
@@ -29,6 +29,9 @@ static void early_nvram_init(void)
|
||||||
|
#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
struct ssb_mipscore *mcore_ssb;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ struct bcma_drv_mips *mcore_bcma;
|
||||||
|
+#endif
|
||||||
|
struct nvram_header *header;
|
||||||
|
int i;
|
||||||
|
u32 base = 0;
|
||||||
|
@@ -44,6 +47,13 @@ static void early_nvram_init(void)
|
||||||
|
lim = mcore_ssb->flash_window_size;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ mcore_bcma = &bcm47xx_bus.bcma.bus.drv_mips;
|
||||||
|
+ base = mcore_bcma->flash_window;
|
||||||
|
+ lim = mcore_bcma->flash_window_size;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
off = FLASH_MIN;
|
||||||
|
--- a/arch/mips/bcm47xx/serial.c
|
||||||
|
+++ b/arch/mips/bcm47xx/serial.c
|
||||||
|
@@ -47,6 +47,31 @@ static int __init uart8250_init_ssb(void
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+static int __init uart8250_init_bcma(void)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ struct bcma_drv_mips *mcore = &(bcm47xx_bus.bcma.bus.drv_mips);
|
||||||
|
+
|
||||||
|
+ memset(&uart8250_data, 0, sizeof(uart8250_data));
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < mcore->nr_serial_ports; i++) {
|
||||||
|
+ struct plat_serial8250_port *p = &(uart8250_data[i]);
|
||||||
|
+ struct bcma_drv_mips_serial_port *bcma_port;
|
||||||
|
+ bcma_port = &(mcore->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_active_bus_type) {
|
||||||
|
@@ -54,6 +79,10 @@ static int __init uart8250_init(void)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
|
@@ -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>
|
||||||
|
@@ -52,6 +53,11 @@ static void bcm47xx_machine_restart(char
|
||||||
|
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)
|
||||||
|
cpu_relax();
|
||||||
|
@@ -67,6 +73,11 @@ static void bcm47xx_machine_halt(void)
|
||||||
|
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)
|
||||||
|
cpu_relax();
|
||||||
|
@@ -295,16 +306,54 @@ static void __init bcm47xx_register_ssb(
|
||||||
|
}
|
||||||
|
#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 = ¤t_cpu_data;
|
||||||
|
|
||||||
|
+ if (c->cputype == CPU_74K) {
|
||||||
|
+ printk(KERN_INFO "bcm47xx: using bcma bus\n");
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_BCMA;
|
||||||
|
+ bcm47xx_register_bcma();
|
||||||
|
+#endif
|
||||||
|
+ } else {
|
||||||
|
+ printk(KERN_INFO "bcm47xx: using ssb bus\n");
|
||||||
|
#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
- bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
|
||||||
|
- bcm47xx_register_ssb();
|
||||||
|
+ bcm47xx_active_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_active_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);
|
||||||
|
--- a/arch/mips/bcm47xx/time.c
|
||||||
|
+++ b/arch/mips/bcm47xx/time.c
|
||||||
|
@@ -45,6 +45,11 @@ void __init plat_time_init(void)
|
||||||
|
hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hz)
|
||||||
|
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
|
||||||
|
@@ -20,17 +20,25 @@
|
||||||
|
#define __ASM_BCM47XX_H
|
||||||
|
|
||||||
|
#include <linux/ssb/ssb.h>
|
||||||
|
+#include <linux/bcma/bcma.h>
|
||||||
|
+#include <linux/bcma/bcma_soc.h>
|
||||||
|
|
||||||
|
enum bcm47xx_bus_type {
|
||||||
|
#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
BCM47XX_BUS_TYPE_SSB,
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ BCM47XX_BUS_TYPE_BCMA,
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
union bcm47xx_bus {
|
||||||
|
#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
struct ssb_bus ssb;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ struct bcma_soc bcma;
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern union bcm47xx_bus bcm47xx_bus;
|
||||||
|
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
|
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#define __BCM47XX_GPIO_H
|
||||||
|
|
||||||
|
#include <linux/ssb/ssb_embedded.h>
|
||||||
|
+#include <linux/bcma/bcma.h>
|
||||||
|
#include <asm/mach-bcm47xx/bcm47xx.h>
|
||||||
|
|
||||||
|
#define BCM47XX_EXTIF_GPIO_LINES 5
|
||||||
|
@@ -26,6 +27,11 @@ static inline int gpio_get_value(unsigne
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
|
||||||
|
+ 1 << gpio);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -37,6 +43,13 @@ static inline void gpio_set_value(unsign
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
|
||||||
|
value ? 1 << gpio : 0);
|
||||||
|
+ return;
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
|
||||||
|
+ value ? 1 << gpio : 0);
|
||||||
|
+ return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -49,6 +62,12 @@ static inline int gpio_direction_input(u
|
||||||
|
ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
|
||||||
|
+ 0);
|
||||||
|
+ return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -65,6 +84,16 @@ static inline int gpio_direction_output(
|
||||||
|
ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ /* first set the gpio out value */
|
||||||
|
+ bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
|
||||||
|
+ value ? 1 << gpio : 0);
|
||||||
|
+ /* then set the gpio mode */
|
||||||
|
+ bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
|
||||||
|
+ 1 << gpio);
|
||||||
|
+ return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -78,6 +107,12 @@ static inline int gpio_intmask(unsigned
|
||||||
|
value ? 1 << gpio : 0);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
|
||||||
|
+ 1 << gpio, value ? 1 << gpio : 0);
|
||||||
|
+ return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -91,6 +126,12 @@ static inline int gpio_polarity(unsigned
|
||||||
|
value ? 1 << gpio : 0);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
|
||||||
|
+ 1 << gpio, value ? 1 << gpio : 0);
|
||||||
|
+ return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
--- a/drivers/watchdog/bcm47xx_wdt.c
|
||||||
|
+++ b/drivers/watchdog/bcm47xx_wdt.c
|
||||||
|
@@ -60,6 +60,12 @@ static inline void bcm47xx_wdt_hw_start(
|
||||||
|
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
|
||||||
|
+ 0xfffffff);
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -70,6 +76,11 @@ static inline int bcm47xx_wdt_hw_stop(vo
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
|
||||||
|
#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
|
||||||
|
+ return 0;
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
From 360eb82fd303ac24590a1b99ad1866162f6b0171 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
Date: Mon, 6 Jun 2011 00:07:38 +0200
|
||||||
|
Subject: [PATCH 13/14] bcm47xx: fix irq assignment for new SoCs.
|
||||||
|
|
||||||
|
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
---
|
||||||
|
arch/mips/bcm47xx/irq.c | 12 ++++++++++++
|
||||||
|
1 files changed, 12 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
--- a/arch/mips/bcm47xx/irq.c
|
||||||
|
+++ b/arch/mips/bcm47xx/irq.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <asm/irq_cpu.h>
|
||||||
|
+#include <bcm47xx.h>
|
||||||
|
|
||||||
|
void plat_irq_dispatch(void)
|
||||||
|
{
|
||||||
|
@@ -51,5 +52,16 @@ void plat_irq_dispatch(void)
|
||||||
|
|
||||||
|
void __init arch_init_irq(void)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ if (bcm47xx_active_bus_type == BCM47XX_BUS_TYPE_BCMA) {
|
||||||
|
+ bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
|
||||||
|
+ BCMA_MIPS_MIPS74K_INTMASK(5), 1 << 31);
|
||||||
|
+ /*
|
||||||
|
+ * the kernel reads the timer irq from some register and thinks
|
||||||
|
+ * it's #5, but we offset it by 2 and route to #7
|
||||||
|
+ */
|
||||||
|
+ cp0_compare_irq = 7;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
mips_cpu_irq_init();
|
||||||
|
}
|
|
@ -15,16 +15,16 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
|
||||||
--- a/arch/mips/bcm47xx/setup.c
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
+++ b/arch/mips/bcm47xx/setup.c
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
@@ -29,6 +29,8 @@
|
@@ -30,6 +30,8 @@
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/ssb/ssb.h>
|
#include <linux/ssb/ssb.h>
|
||||||
#include <linux/ssb/ssb_embedded.h>
|
#include <linux/ssb/ssb_embedded.h>
|
||||||
|
#include <linux/bcma/bcma_soc.h>
|
||||||
+#include <linux/serial.h>
|
+#include <linux/serial.h>
|
||||||
+#include <linux/serial_8250.h>
|
+#include <linux/serial_8250.h>
|
||||||
#include <asm/bootinfo.h>
|
#include <asm/bootinfo.h>
|
||||||
#include <asm/reboot.h>
|
#include <asm/reboot.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
@@ -247,6 +249,31 @@ static int bcm47xx_get_invariants(struct
|
@@ -274,6 +276,31 @@ static int bcm47xx_get_invariants(struct
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,17 +53,17 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
+}
|
+}
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
void __init plat_mem_setup(void)
|
static void __init bcm47xx_register_ssb(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
@@ -277,6 +304,10 @@ void __init plat_mem_setup(void)
|
@@ -303,6 +330,10 @@ static void __init bcm47xx_register_ssb(
|
||||||
|
memcpy(&mcore->serial_ports[1], &port, sizeof(port));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+
|
||||||
+#ifdef CONFIG_SERIAL_8250
|
+#ifdef CONFIG_SERIAL_8250
|
||||||
+ bcm47xx_early_serial_setup(mcore);
|
+ bcm47xx_early_serial_setup(mcore);
|
||||||
+#endif
|
+#endif
|
||||||
+
|
}
|
||||||
_machine_restart = bcm47xx_machine_restart;
|
#endif
|
||||||
_machine_halt = bcm47xx_machine_halt;
|
|
||||||
pm_power_off = bcm47xx_machine_halt;
|
|
||||||
|
|
|
@ -16,9 +16,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
|
||||||
--- a/arch/mips/Kconfig
|
--- a/arch/mips/Kconfig
|
||||||
+++ b/arch/mips/Kconfig
|
+++ b/arch/mips/Kconfig
|
||||||
@@ -101,7 +101,6 @@ config BCM47XX
|
@@ -94,7 +94,6 @@ config BCM47XX
|
||||||
select SSB_B43_PCI_BRIDGE if PCI
|
select SYS_SUPPORTS_32BIT_KERNEL
|
||||||
select SSB_PCICORE_HOSTMODE if PCI
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
select GENERIC_GPIO
|
select GENERIC_GPIO
|
||||||
- select SYS_HAS_EARLY_PRINTK
|
- select SYS_HAS_EARLY_PRINTK
|
||||||
select CFE
|
select CFE
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
|
||||||
@@ -58,6 +58,10 @@ static inline int gpio_polarity(unsigned
|
@@ -136,6 +136,10 @@ static inline int gpio_polarity(unsigned
|
||||||
return 0;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
+static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
|
+static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
--- a/drivers/mtd/maps/bcm47xx-flash.c
|
||||||
|
+++ b/drivers/mtd/maps/bcm47xx-flash.c
|
||||||
|
@@ -46,11 +46,9 @@
|
||||||
|
#include <linux/mtd/map.h>
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
|
-#ifdef CONFIG_SSB
|
||||||
|
-#include <linux/ssb/ssb.h>
|
||||||
|
-#endif
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/mach-bcm47xx/nvram.h>
|
||||||
|
+#include <asm/mach-bcm47xx/bcm47xx.h>
|
||||||
|
#include <asm/fw/cfe/cfe_api.h>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -90,9 +88,6 @@ struct trx_header {
|
||||||
|
#define ROUTER_NETGEAR_WNR3500L 4
|
||||||
|
#define ROUTER_SIMPLETECH_SIMPLESHARE 5
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SSB
|
||||||
|
-extern struct ssb_bus ssb_bcm47xx;
|
||||||
|
-#endif
|
||||||
|
static struct mtd_info *bcm47xx_mtd;
|
||||||
|
|
||||||
|
static void bcm47xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
|
||||||
|
@@ -552,27 +547,42 @@ init_mtd_partitions(struct mtd_info *mtd
|
||||||
|
|
||||||
|
int __init init_bcm47xx_map(void)
|
||||||
|
{
|
||||||
|
-#ifdef CONFIG_SSB
|
||||||
|
- struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
+ struct ssb_mipscore *mcore_ssb;
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ struct bcma_drv_mips *mcore_bcma;
|
||||||
|
#endif
|
||||||
|
size_t size;
|
||||||
|
int ret = 0;
|
||||||
|
+ u32 window = 0;
|
||||||
|
+ u32 window_size = 0;
|
||||||
|
struct mtd_partition *parts;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
-#ifdef CONFIG_SSB
|
||||||
|
- u32 window = mcore->flash_window;
|
||||||
|
- u32 window_size = mcore->flash_window_size;
|
||||||
|
+ switch (bcm47xx_active_bus_type) {
|
||||||
|
+#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
+ case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
+ mcore_ssb = &bcm47xx_bus.ssb.mipscore;
|
||||||
|
+ window = mcore_ssb->flash_window;
|
||||||
|
+ window_size = mcore_ssb->flash_window_size;
|
||||||
|
+ bcm47xx_map.bankwidth = mcore_ssb->flash_buswidth;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
+#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
+ case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
+ mcore_bcma = &bcm47xx_bus.bcma.bus.drv_mips;
|
||||||
|
+ window = mcore_bcma->flash_window;
|
||||||
|
+ window_size = mcore_bcma->flash_window_size;
|
||||||
|
+ bcm47xx_map.bankwidth = mcore_bcma->flash_buswidth;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
|
||||||
|
printk("flash init: 0x%08x 0x%08x\n", window, window_size);
|
||||||
|
bcm47xx_map.phys = window;
|
||||||
|
bcm47xx_map.size = window_size;
|
||||||
|
- bcm47xx_map.bankwidth = mcore->flash_buswidth;
|
||||||
|
bcm47xx_map.virt = ioremap_nocache(window, window_size);
|
||||||
|
-#else
|
||||||
|
- printk("flash init: 0x%08x 0x%08x\n", WINDOW_ADDR, WINDOW_SIZE);
|
||||||
|
- bcm47xx_map.virt = ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
if (!bcm47xx_map.virt) {
|
||||||
|
printk("Failed to ioremap\n");
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/arch/mips/bcm47xx/nvram.c
|
--- a/arch/mips/bcm47xx/nvram.c
|
||||||
+++ b/arch/mips/bcm47xx/nvram.c
|
+++ b/arch/mips/bcm47xx/nvram.c
|
||||||
@@ -93,3 +93,30 @@ int nvram_getenv(char *name, char *val,
|
@@ -114,3 +114,30 @@ int nvram_getenv(char *name, char *val,
|
||||||
return NVRAM_ERR_ENVNOTFOUND;
|
return NVRAM_ERR_ENVNOTFOUND;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(nvram_getenv);
|
EXPORT_SYMBOL(nvram_getenv);
|
||||||
|
@ -33,10 +33,10 @@
|
||||||
+EXPORT_SYMBOL(nvram_get);
|
+EXPORT_SYMBOL(nvram_get);
|
||||||
--- a/arch/mips/bcm47xx/setup.c
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
+++ b/arch/mips/bcm47xx/setup.c
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
@@ -312,3 +312,20 @@ void __init plat_mem_setup(void)
|
@@ -388,3 +388,20 @@ static int __init bcm47xx_register_bus_c
|
||||||
_machine_halt = bcm47xx_machine_halt;
|
return 0;
|
||||||
pm_power_off = bcm47xx_machine_halt;
|
|
||||||
}
|
}
|
||||||
|
device_initcall(bcm47xx_register_bus_complete);
|
||||||
+
|
+
|
||||||
+static int __init bcm47xx_register_gpiodev(void)
|
+static int __init bcm47xx_register_gpiodev(void)
|
||||||
+{
|
+{
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
--- a/arch/mips/bcm47xx/Makefile
|
--- a/arch/mips/bcm47xx/Makefile
|
||||||
+++ b/arch/mips/bcm47xx/Makefile
|
+++ b/arch/mips/bcm47xx/Makefile
|
||||||
@@ -3,4 +3,4 @@
|
@@ -4,4 +4,3 @@
|
||||||
# under Linux.
|
|
||||||
#
|
#
|
||||||
|
|
||||||
-obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
|
obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
|
||||||
+obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
|
-obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o
|
||||||
--- a/arch/mips/bcm47xx/wgt634u.c
|
--- a/arch/mips/bcm47xx/wgt634u.c
|
||||||
+++ /dev/null
|
+++ /dev/null
|
||||||
@@ -1,166 +0,0 @@
|
@@ -1,169 +0,0 @@
|
||||||
-/*
|
-/*
|
||||||
- * This file is subject to the terms and conditions of the GNU General Public
|
- * This file is subject to the terms and conditions of the GNU General Public
|
||||||
- * License. See the file "COPYING" in the main directory of this archive
|
- * License. See the file "COPYING" in the main directory of this archive
|
||||||
|
@ -119,7 +118,7 @@
|
||||||
-
|
-
|
||||||
- /* Interrupts are shared, check if the current one is
|
- /* Interrupts are shared, check if the current one is
|
||||||
- a GPIO interrupt. */
|
- a GPIO interrupt. */
|
||||||
- if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
|
- if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
|
||||||
- SSB_CHIPCO_IRQ_GPIO))
|
- SSB_CHIPCO_IRQ_GPIO))
|
||||||
- return IRQ_NONE;
|
- return IRQ_NONE;
|
||||||
-
|
-
|
||||||
|
@ -144,21 +143,24 @@
|
||||||
- * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
|
- * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
|
||||||
- */
|
- */
|
||||||
-
|
-
|
||||||
- u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
|
- if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB)
|
||||||
|
- return -ENODEV;
|
||||||
|
-
|
||||||
|
- u8 *et0mac = bcm47xx_bus.ssb.sprom.et0mac;
|
||||||
-
|
-
|
||||||
- if (et0mac[0] == 0x00 &&
|
- if (et0mac[0] == 0x00 &&
|
||||||
- ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
|
- ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
|
||||||
- (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
|
- (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
|
||||||
- struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
|
- struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
|
||||||
-
|
-
|
||||||
- printk(KERN_INFO "WGT634U machine detected.\n");
|
- printk(KERN_INFO "WGT634U machine detected.\n");
|
||||||
-
|
-
|
||||||
- if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
|
- if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
|
||||||
- gpio_interrupt, IRQF_SHARED,
|
- gpio_interrupt, IRQF_SHARED,
|
||||||
- "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
|
- "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
|
||||||
- gpio_direction_input(WGT634U_GPIO_RESET);
|
- gpio_direction_input(WGT634U_GPIO_RESET);
|
||||||
- gpio_intmask(WGT634U_GPIO_RESET, 1);
|
- gpio_intmask(WGT634U_GPIO_RESET, 1);
|
||||||
- ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
|
- ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
|
||||||
- SSB_CHIPCO_IRQ_GPIO,
|
- SSB_CHIPCO_IRQ_GPIO,
|
||||||
- SSB_CHIPCO_IRQ_GPIO);
|
- SSB_CHIPCO_IRQ_GPIO);
|
||||||
- }
|
- }
|
||||||
|
|
|
@ -9,8 +9,8 @@ out the configuration than the in kernel cfe config reader.
|
||||||
# under Linux.
|
# under Linux.
|
||||||
#
|
#
|
||||||
|
|
||||||
-obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
|
-obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
|
||||||
+obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o cfe_env.o
|
+obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o cfe_env.o
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/arch/mips/bcm47xx/cfe_env.c
|
+++ b/arch/mips/bcm47xx/cfe_env.c
|
||||||
@@ -0,0 +1,229 @@
|
@@ -0,0 +1,229 @@
|
||||||
|
@ -254,10 +254,10 @@ out the configuration than the in kernel cfe config reader.
|
||||||
|
|
||||||
/* Probe for NVRAM header */
|
/* Probe for NVRAM header */
|
||||||
static void early_nvram_init(void)
|
static void early_nvram_init(void)
|
||||||
@@ -34,6 +36,25 @@ static void early_nvram_init(void)
|
@@ -55,6 +57,25 @@ static void early_nvram_init(void)
|
||||||
|
break;
|
||||||
base = mcore->flash_window;
|
#endif
|
||||||
lim = mcore->flash_window_size;
|
}
|
||||||
+ cfe_env = 0;
|
+ cfe_env = 0;
|
||||||
+
|
+
|
||||||
+ /* XXX: hack for supporting the CFE environment stuff on WGT634U */
|
+ /* XXX: hack for supporting the CFE environment stuff on WGT634U */
|
||||||
|
@ -280,7 +280,7 @@ out the configuration than the in kernel cfe config reader.
|
||||||
|
|
||||||
off = FLASH_MIN;
|
off = FLASH_MIN;
|
||||||
while (off <= lim) {
|
while (off <= lim) {
|
||||||
@@ -75,6 +96,12 @@ int nvram_getenv(char *name, char *val,
|
@@ -96,6 +117,12 @@ int nvram_getenv(char *name, char *val,
|
||||||
if (!nvram_buf[0])
|
if (!nvram_buf[0])
|
||||||
early_nvram_init();
|
early_nvram_init();
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ out the configuration than the in kernel cfe config reader.
|
||||||
/* Look for name=value and return value */
|
/* Look for name=value and return value */
|
||||||
var = &nvram_buf[sizeof(struct nvram_header)];
|
var = &nvram_buf[sizeof(struct nvram_header)];
|
||||||
end = nvram_buf + sizeof(nvram_buf) - 2;
|
end = nvram_buf + sizeof(nvram_buf) - 2;
|
||||||
@@ -104,6 +131,9 @@ char *nvram_get(const char *name)
|
@@ -125,6 +152,9 @@ char *nvram_get(const char *name)
|
||||||
if (!nvram_buf[0])
|
if (!nvram_buf[0])
|
||||||
early_nvram_init();
|
early_nvram_init();
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
static int wdt_time = WDT_DEFAULT_TIME;
|
static int wdt_time = WDT_DEFAULT_TIME;
|
||||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||||
@@ -50,11 +51,11 @@ static unsigned long bcm47xx_wdt_busy;
|
@@ -50,20 +51,20 @@ static unsigned long bcm47xx_wdt_busy;
|
||||||
static char expect_release;
|
static char expect_release;
|
||||||
static struct timer_list wdt_timer;
|
static struct timer_list wdt_timer;
|
||||||
static atomic_t ticks;
|
static atomic_t ticks;
|
||||||
|
@ -18,12 +18,22 @@
|
||||||
+static inline void bcm47xx_wdt_hw_start(u32 ticks)
|
+static inline void bcm47xx_wdt_hw_start(u32 ticks)
|
||||||
{
|
{
|
||||||
- /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
|
- /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
|
||||||
- ssb_watchdog_timer_set(&ssb_bcm47xx, 0xfffffff);
|
switch (bcm47xx_active_bus_type) {
|
||||||
+ ssb_watchdog_timer_set(&ssb_bcm47xx, ticks);
|
#ifdef CONFIG_BCM47XX_SSB
|
||||||
|
case BCM47XX_BUS_TYPE_SSB:
|
||||||
|
- ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
|
||||||
|
+ ssb_watchdog_timer_set(&bcm47xx_bus.ssb, ticks);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BCM47XX_BCMA
|
||||||
|
case BCM47XX_BUS_TYPE_BCMA:
|
||||||
|
bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
|
||||||
|
- 0xfffffff);
|
||||||
|
+ ticks);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -88,33 +89,34 @@ static inline int bcm47xx_wdt_hw_stop(vo
|
||||||
static inline int bcm47xx_wdt_hw_stop(void)
|
|
||||||
@@ -65,33 +66,34 @@ static inline int bcm47xx_wdt_hw_stop(vo
|
|
||||||
static void bcm47xx_timer_tick(unsigned long unused)
|
static void bcm47xx_timer_tick(unsigned long unused)
|
||||||
{
|
{
|
||||||
if (!atomic_dec_and_test(&ticks)) {
|
if (!atomic_dec_and_test(&ticks)) {
|
||||||
|
@ -70,20 +80,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bcm47xx_wdt_settimeout(int new_time)
|
static int bcm47xx_wdt_settimeout(int new_time)
|
||||||
@@ -243,7 +245,15 @@ static int __init bcm47xx_wdt_init(void)
|
@@ -266,7 +268,20 @@ static int __init bcm47xx_wdt_init(void)
|
||||||
if (bcm47xx_wdt_hw_stop() < 0)
|
if (bcm47xx_wdt_hw_stop() < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
- setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
|
- setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
|
||||||
+ /* FIXME Other cores */
|
+ /* FIXME Other cores */
|
||||||
+ if(ssb_bcm47xx.chip_id == 0x5354) {
|
+#ifdef BCM47XX_BUS_TYPE_BCMA
|
||||||
|
+ if(bcm47xx_active_bus_type == BCM47XX_BUS_TYPE_BCMA &&
|
||||||
|
+ bcm47xx_bus.ssb.chip_id == 0x5354) {
|
||||||
+ /* Slow WDT clock, no pre-scaling */
|
+ /* Slow WDT clock, no pre-scaling */
|
||||||
+ needs_sw_scale = 0;
|
+ needs_sw_scale = 0;
|
||||||
+ } else {
|
+ } else {
|
||||||
|
+#endif
|
||||||
+ /* Fast WDT clock, needs software pre-scaling */
|
+ /* Fast WDT clock, needs software pre-scaling */
|
||||||
+ needs_sw_scale = 1;
|
+ needs_sw_scale = 1;
|
||||||
+ setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
|
+ setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
|
||||||
|
+#ifdef BCM47XX_BUS_TYPE_BCMA
|
||||||
+ }
|
+ }
|
||||||
|
+#endif
|
||||||
|
|
||||||
if (bcm47xx_wdt_settimeout(wdt_time)) {
|
if (bcm47xx_wdt_settimeout(wdt_time)) {
|
||||||
bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);
|
bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/arch/mips/bcm47xx/setup.c
|
--- a/arch/mips/bcm47xx/setup.c
|
||||||
+++ b/arch/mips/bcm47xx/setup.c
|
+++ b/arch/mips/bcm47xx/setup.c
|
||||||
@@ -246,6 +246,10 @@ static int bcm47xx_get_invariants(struct
|
@@ -273,6 +273,10 @@ static int bcm47xx_get_invariants(struct
|
||||||
if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||||
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue