Return-path: Received: from mail.academy.zt.ua ([82.207.120.245]:50966 "EHLO mail.academy.zt.ua" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755650Ab1BISld (ORCPT ); Wed, 9 Feb 2011 13:41:33 -0500 Received: from [10.0.2.42] by mail.academy.zt.ua (Cipher SSLv3:RC4-MD5:128) (MDaemon PRO v11.0.3) with ESMTP id md50000020066.msg for ; Wed, 09 Feb 2011 20:40:53 +0200 Subject: Re: SSB AI support code ([RFC11/11] SSB add AI-bus support) From: George Kashperko To: Larry Finger Cc: linux-wireless In-Reply-To: <4D52BFFF.3040205@lwfinger.net> References: <1297258590.17400.37.camel@dev.znau.edu.ua> <1297262780.18053.44.camel@dev.znau.edu.ua> <4D52BFFF.3040205@lwfinger.net> Content-Type: text/plain Date: Wed, 09 Feb 2011 20:33:59 +0200 Message-Id: <1297276439.3361.28.camel@dev.znau.edu.ua> Mime-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org List-ID: > On 02/09/2011 08:46 AM, George Kashperko wrote: > > From: Bernhard Loos > > Add support for AI-style ssb bus. > > Signed-off-by: George Kashperko > > --- > > drivers/ssb/Kconfig | 13 > > drivers/ssb/Makefile | 1 > > drivers/ssb/main.c | 2 > > drivers/ssb/scan.c | 42 +- > > drivers/ssb/ssb_ai.c | 381 ++++++++++++++++++++ > > drivers/ssb/ssb_ai.h | 61 +++ > > drivers/ssb/ssb_private.h | 9 > > include/linux/ssb/ssb.h | 12 > > include/linux/ssb/ssb_driver_chipcommon.h | 3 > > 9 files changed, 516 insertions(+), 8 deletions(-) > > --- linux-next-20110203.orig/drivers/ssb/Kconfig 2011-02-08 16:14:57.000000000 +0200 > > +++ linux-next-20110203/drivers/ssb/Kconfig 2011-02-08 21:01:34.000000000 +0200 > > @@ -9,7 +9,7 @@ menu "Sonics Silicon Backplane" > > config SSB > > tristate "Sonics Silicon Backplane support" > > depends on SSB_POSSIBLE > > - select SSB_BUS_SB > > + select SSB_BUS_SB if !SSB_BUS_AI > > help > > Support for the Sonics Silicon Backplane bus. > > You only need to enable this option, if you are > > @@ -32,6 +32,17 @@ config SSB_BUS_SB > > help > > Sonics Silicon Backplane SB-style bus > > > > +config SSB_BUS_AI_POSSIBLE > > + bool > > + default y if SSB && EXPERIMENTAL > > + > > +config SSB_BUS_AI > > + bool "AI style bus" > > + depends on SSB_BUS_AI_POSSIBLE > > + default n > > + help > > + Sonics Silicon Backplane AI-style bus > > + > > # Common SPROM support routines > > config SSB_SPROM > > bool > > --- linux-next-20110203.orig/drivers/ssb/main.c 2011-02-08 18:55:26.000000000 +0200 > > +++ linux-next-20110203/drivers/ssb/main.c 2011-02-08 21:01:34.000000000 +0200 > > @@ -842,6 +842,8 @@ static const char *ssb_chipco_chiptype_n > > switch (bus->chipco.chiptype) { > > case SSB_CHIPCO_SB: > > return "SB"; > > + case SSB_CHIPCO_AI: > > + return "AI"; > > default: > > return "UNKNOWN"; > > } > > --- linux-next-20110203.orig/drivers/ssb/Makefile 2011-02-08 16:14:57.000000000 +0200 > > +++ linux-next-20110203/drivers/ssb/Makefile 2011-02-08 21:01:34.000000000 +0200 > > @@ -1,6 +1,7 @@ > > # core > > ssb-y += main.o scan.o > > ssb-$(CONFIG_SSB_BUS_SB) += ssb_sb.o > > +ssb-$(CONFIG_SSB_BUS_AI) += ssb_ai.o > > ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o > > ssb-$(CONFIG_SSB_SPROM) += sprom.o > > > > --- linux-next-20110203.orig/drivers/ssb/scan.c 2011-02-08 18:33:58.000000000 +0200 > > +++ linux-next-20110203/drivers/ssb/scan.c 2011-02-08 21:01:34.000000000 +0200 > > @@ -212,6 +212,10 @@ void ssb_iounmap(struct ssb_bus *bus) > > case SSB_BUSTYPE_SSB: > > case SSB_BUSTYPE_PCMCIA: > > iounmap(bus->mmio); > > +#ifdef CONFIG_SSB_BUS_AI > > + if (bus->ai_mmio) > > + iounmap(bus->ai_mmio); > > +#endif > > break; > > case SSB_BUSTYPE_PCI: > > #ifdef CONFIG_SSB_PCIHOST > > @@ -364,18 +368,39 @@ int ssb_bus_check_core(struct ssb_device > > /* Detect bus type and major bus information */ > > static int ssb_bus_detect(struct ssb_bus *bus) > > { > > - u32 idhi, cc, rev, tmp; > > + u32 idhi, rev, tmp; > > + bool have_chipcommon = true; > > enum ssb_chipco_chiptype chiptype = SSB_CHIPCO_SB; > > > > - idhi = scan_read32(bus, 0, SSB_IDHIGH); > > - cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; > > - rev = (idhi & SSB_IDHIGH_RCLO); > > - rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT; > > + /* the problem goes like this: > > + * if we access the normal core id backplane registers on an AI soc, > > + * the thing hangs. > > + * To figure out, if we have an AI soc, we have to look in a > > + * chipcommon register. > > + * The 4710 doesn't have a chipcommon but we can't figure this out > > + * without scanning the cores, and we don't know, if we have to use > > + * the AI or normal method. > > + * All known AI socs have a 74k cpu, so let's take this as an > > + * indicator that we have a chipcommon core and hope for the best. > > + */ > > + rev = 0; > > + if (cpu_data[0].cputype != CPU_74K) { > > + idhi = scan_read32(bus, 0, SSB_IDHIGH); > > + if (((idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT) != > > + SSB_DEV_CHIPCOMMON) { > > + have_chipcommon = false; > > + } else { > > + rev = (idhi & SSB_IDHIGH_RCLO); > > + rev |= (idhi & SSB_IDHIGH_RCHI) >> > > + SSB_IDHIGH_RCHI_SHIFT; > > + } > > + } > > > > bus->nr_devices = 0; > > - if (cc == SSB_DEV_CHIPCOMMON) { > > + if (have_chipcommon) { > > tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID); > > > > + chiptype = SSB_CHIPCO_TYPE(tmp); > > bus->chip_id = (tmp & SSB_CHIPCO_IDMASK); > > bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >> > > SSB_CHIPCO_REVSHIFT; > > @@ -409,7 +434,7 @@ static int ssb_bus_detect(struct ssb_bus > > } > > > > bus->chipco.chiptype = chiptype; > > - return chiptype != SSB_CHIPCO_SB; > > + return (chiptype != SSB_CHIPCO_SB && chiptype != SSB_CHIPCO_AI); > > } > > > > int ssb_bus_scan(struct ssb_bus *bus, > > @@ -451,6 +476,9 @@ int ssb_bus_scan(struct ssb_bus *bus, > > case SSB_CHIPCO_SB: > > err = ssb_bus_scan_sb(bus, baseaddr); > > break; > > + case SSB_CHIPCO_AI: > > + err = ssb_bus_scan_ai(bus); > > + break; > > default: > > SSB_WARN_ON(1); > > err = -ENODEV; > > --- linux-next-20110203.orig/drivers/ssb/ssb_ai.c 1970-01-01 03:00:00.000000000 +0300 > > +++ linux-next-20110203/drivers/ssb/ssb_ai.c 2011-02-08 21:01:58.000000000 +0200 > > @@ -0,0 +1,381 @@ > > +/* > > + * Sonics Silicon Backplane > > + * AI Specific Subsystem core > > + * > > + * Copyright 2010, Bernhard Loos > > + * Copyright (C) 2006 Broadcom Corporation. > > + * > > + * Licensed under the GNU/GPL. See COPYING for details. > > + */ > > + > > +#include > > +#include > > +#include > > + > > +#include "ssb_private.h" > > +#include "ssb_ai.h" > > + > > + > > +static void ssb_ai_write32(struct ssb_device *dev, u16 offset, u32 value) > > +{ > > + struct ssb_bus *bus = dev->bus; > > + > > + offset += dev->core_index * SSB_CORE_SIZE; > > + return writel(value, bus->ai_mmio + offset); > > +} > > + > > +static u32 ssb_ai_read32(struct ssb_device *dev, u16 offset) > > +{ > > + struct ssb_bus *bus = dev->bus; > > + > > + offset += dev->core_index * SSB_CORE_SIZE; > > + return readl(bus->ai_mmio + offset); > > +} > > + > > +/* The 47162a0 hangs when reading its registers */ > > +static inline bool ssb_bcm47162a0_quirk(struct ssb_device *dev) > > +{ > > + return dev->bus->chip_id == 47162 && dev->bus->chip_rev == 0 && > > + dev->id.coreid == SSB_DEV_MIPS_74K; > > +} > > + > > +static void ssb_core_ctl_flags_ai(struct ssb_device *dev, u32 mask, > > + u32 val, u32 *res) > > +{ > > + if (ssb_bcm47162a0_quirk(dev)) { > > + printk("%s: Accessing MIPS DMP register (IOCTL) on 47162a0", > > + __FUNCTION__); > > + if (res) > > + *res = 0; > > + return; > > + } > > + > > + if (mask || val) { > > + u32 tmp = (ssb_ai_read32(dev, SSB_AI_IOCTL) & ~mask) | val; > > + ssb_ai_write32(dev, SSB_AI_IOCTL, tmp); > > + } > > + > > + if (res) > > + *res = ssb_ai_read32(dev, SSB_AI_IOCTL); > > +} > > + > > +static u32 ssb_core_state_flags_ai(struct ssb_device *dev, u32 mask, u32 val) > > +{ > > + if (ssb_bcm47162a0_quirk(dev)) { > > + printk("%s: Accessing MIPS DMP register (IOSTAT) on 47162a0", > > + __FUNCTION__); > > + return 0; > > + } > > + > > + if (mask || val) { > > + u32 tmp = (ssb_ai_read32(dev, SSB_AI_IOSTAT) & ~mask) | val; > > + ssb_ai_write32(dev, SSB_AI_IOSTAT, tmp); > > + } > > + > > + return ssb_ai_read32(dev, SSB_AI_IOSTAT); > > +} > > + > > +/* return -1 if no irq is supported */ > > +static u32 ssb_irqflag_ai(struct ssb_device *dev) > > +{ > > + u32 flag; > > + > > + /* The 47162a0 hangs when reading its registers */ > > + if (ssb_bcm47162a0_quirk(dev)) > > + return dev->core_index; > > + > > + flag = ssb_ai_read32(dev, SSB_AI_oobselouta30); > > + > > + if (flag) > > + return flag & 0x1F; > > + else > > + /* not irq supported */ > > + return -1; > > +} > > + > > +static int ssb_device_is_enabled_ai(struct ssb_device *dev) > > +{ > > + return (ssb_ai_read32(dev, SSB_AI_RESETCTL) & > > + SSB_AI_RESETCTL_RESET) == 0; > > +} > > + > > +static void ssb_ai_ioctl_write(struct ssb_device *dev, u32 flags) > > +{ > > + u32 dummy; > > + ssb_ai_write32(dev, SSB_AI_IOCTL, flags); > > + dummy = ssb_ai_read32(dev, SSB_AI_IOCTL); > > + udelay(1); > > +} > > + > > +static void ssb_device_disable_ai(struct ssb_device *dev, > > + u32 core_specific_flags) > > +{ > > + SSB_WARN_ON(core_specific_flags & 0xFFFF0000); > > + if (ssb_ai_read32(dev, SSB_AI_RESETCTL) & SSB_AI_RESETCTL_RESET) > > + return; > > + ssb_ai_ioctl_write(dev, core_specific_flags); > > + udelay(9); > > + ssb_ai_write32(dev, SSB_AI_RESETCTL, SSB_AI_RESETCTL_RESET); > > + udelay(1); > > +} > > + > > +static void ssb_device_enable_ai(struct ssb_device *dev, > > + u32 core_specific_flags) > > +{ > > + ssb_device_disable_ai(dev, core_specific_flags); > > + > > + ssb_ai_ioctl_write(dev, core_specific_flags | SSB_CORECTL_FGC | > > + SSB_CORECTL_CLOCK); > > + ssb_ai_write32(dev, SSB_AI_RESETCTL, 0); > > + udelay(1); > > + > > + ssb_ai_ioctl_write(dev, core_specific_flags | SSB_CORECTL_CLOCK); > > +} > > + > > +static u32 ssb_admatch_base_ai(struct ssb_device *dev, u32 adm) > > +{ > > + switch (adm) { > > + case SSB_ADMATCH0: > > + return dev->coresba; > > + case SSB_ADMATCH1: > > + return dev->coresba2; > > + default: > > + printk(KERN_ERR PFX "Need to parse the erom again " > > + "to find addr space %d\n", > > + adm & SSB_ADM_TYPE); > > + return 0; > > + } > > +} > > + > > +static u32 ssb_admatch_size_ai(struct ssb_device *dev, u32 adm) > > +{ > > + switch (adm) { > > + case SSB_ADMATCH0: > > + return dev->coresba_size; > > + case SSB_ADMATCH1: > > + return dev->coresba2_size; > > + default: > > + printk(KERN_ERR PFX "Need to parse the erom again " > > + "to find addr space %d size\n", > > + adm & SSB_ADM_TYPE); > > + return 0; > > + } > > +} > > + > > +/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ > > +static struct ssb_bus_ops ssb_ops_ai = { > > + .read8 = ssb_ssb_read8, > > + .read16 = ssb_ssb_read16, > > + .read32 = ssb_ssb_read32, > > + .write8 = ssb_ssb_write8, > > + .write16 = ssb_ssb_write16, > > + .write32 = ssb_ssb_write32, > > +#ifdef CONFIG_SSB_BLOCKIO > > + .block_read = ssb_ssb_block_read, > > + .block_write = ssb_ssb_block_write, > > +#endif > > + .device_is_enabled = ssb_device_is_enabled_ai, > > + .device_enable = ssb_device_enable_ai, > > + .device_disable = ssb_device_disable_ai, > > + .admatch_base = ssb_admatch_base_ai, > > + .admatch_size = ssb_admatch_size_ai, > > + .irqflag = ssb_irqflag_ai, > > + .core_ctl_flags = ssb_core_ctl_flags_ai, > > + .core_state_flags = ssb_core_state_flags_ai, > > +}; > > + > > +static u32 get_erom_ent(struct ssb_bus *bus, u32 **eromptr, u32 mask, u32 match) > > +{ > > + u32 ent; > > + > > + while (1) { > > + ent = readl(*eromptr); > > + (*eromptr)++; > > + > > + if (mask == 0) > > + break; > > + > > + if ((ent & SSB_EROM_VALID) == 0) > > + continue; > > + > > + if (ent == (SSB_EROM_END | SSB_EROM_VALID)) > > + break; > > + > > + if ((ent & mask) == match) > > + break; > > + } > > + return ent; > > +} > > + > > +static u32 get_adress_space_descriptor(struct ssb_bus *bus, u32 **eromptr, > > + uint st, u32 *addrl, u32 *sizel) > > +{ > > + u32 asd, sz, szd, expect; > > + > > + expect = SSB_EROM_ASD | st; > > + if (st == SSB_EROM_ASD_ST_SWRAP) > > + expect |= 1 << SSB_EROM_ASD_SP_SHIFT; > > + > > + asd = get_erom_ent(bus, eromptr, SSB_EROM_ASD_SP_MASK | SSB_EROM_TAG | > > + SSB_EROM_ASD_ST_MASK, expect); > > + > > + *addrl = asd & SSB_EROM_ASD_ADDR_MASK; > > + > > + /* 64bit addresses are not supported */ > > + BUG_ON(asd & SSB_EROM_ASD_AG32); > > + > > + sz = asd & SSB_EROM_ASD_SZ_MASK; > > + if (sz == SSB_EROM_ASD_SZ_SZD) { > > + szd = get_erom_ent(bus, eromptr, 0, 0); > > + *sizel = szd & SSB_EROM_ASD_SZ_MASK; > > + } else > > + *sizel = SSB_EROM_ASD_SZ_BASE << (sz >> SSB_EROM_ASD_SZ_SHIFT); > > + > > + return asd; > > +} > > + > > +int ssb_bus_scan_ai(struct ssb_bus *bus) > > +{ > > + int dev_i = 0; > > + struct ssb_device *dev; > > + int nr_80211_cores = 0; > > + void __iomem *mmio; > > + u32 __iomem *eromptr; > > + u32 __iomem *eromend; > > + > > + bus->ops = &ssb_ops_ai; > > + > > + mmio = ioremap(SSB_AI_BASE, SSB_CORE_SIZE * bus->nr_devices); > > + if (!mmio) > > + return -ENOMEM; > > + bus->ai_mmio = mmio; > > + > > + eromptr = ioremap(scan_read32(bus, 0, SSB_CHIPCO_EROM), SSB_CORE_SIZE); > > + if (!eromptr) > > + return -ENOMEM; > > + > > + eromend = eromptr + SSB_CORE_SIZE / sizeof(u32); > > + > > + while (eromptr < eromend) { > > + u32 cia, cib, asd, sizel, addrl, nmw, nsp; > > + > > + dev = &(bus->devices[dev_i]); > > + > > + cia = get_erom_ent(bus, &eromptr, SSB_EROM_TAG, SSB_EROM_CI); > > + if (cia == (SSB_EROM_END | SSB_EROM_VALID)) { > > + ssb_dprintk(KERN_INFO PFX > > + "Found END of erom after %d cores\n", > > + dev_i); > > + if (dev_i != bus->nr_devices) > > + ssb_printk(KERN_WARNING PFX > > + "Expected %d cores but got %d\n", > > + bus->nr_devices, dev_i); > > + break; > > + } > > + cib = get_erom_ent(bus, &eromptr, 0, 0); > > + if ((cib & SSB_EROM_TAG) != SSB_EROM_CI) { > > + ssb_printk(KERN_ERR PFX "CIA not followed by CIB\n"); > > + return -EIO; > > + } > > + > > + dev->id.coreid = SSB_EROM_CIA_CID(cia); > > + dev->id.vendor = SSB_EROM_CIA_MFG(cia); > > + dev->id.revision = SSB_EROM_CIB_REV(cib); > > + dev->core_index = dev_i; > > + dev->bus = bus; > > + dev->ops = bus->ops; > > + > > + nmw = SSB_EROM_CIB_NMW(cib); > > + nsp = SSB_EROM_CIB_NSP(cib); > > + > > + if (((dev->id.coreid == SSB_DEV_DEFAULT) && > > + (dev->id.vendor == SSB_VENDOR_ARM)) || > > + (nmw == 0 && SSB_EROM_CIB_NSW(cib) == 0) || (nsp == 0)) > > + continue; > > + > > + /* see if it is a bridge */ > > + if ((SSB_EROM_ASD_ST_MASK & > > + get_erom_ent(bus, &eromptr, SSB_EROM_TAG, SSB_EROM_ASD)) == > > + SSB_EROM_ASD_ST_BRIDGE) > > + /* don't record bridges */ > > + continue; > > + else > > + eromptr--; > > + > > + /* First Slave Address Descriptor should be port 0: > > + * the main register space for the core > > + */ > > + asd = get_adress_space_descriptor(bus, &eromptr, > > + SSB_EROM_ASD_ST_SLAVE, > > + &addrl, &sizel); > > + if (sizel != SSB_CORE_SIZE || > > + addrl != SSB_ENUM_BASE + SSB_CORE_SIZE * dev_i) { > > + ssb_printk(KERN_ERR PFX > > + "Malformed or unsupported register address " > > + "space descriptor for core %d:\n" > > + "\texpected 0x%x, got 0x%x, size 0x%x\n", > > + dev_i, SSB_ENUM_BASE + SSB_CORE_SIZE * dev_i, > > + addrl, sizel); > > + return -EIO; > > + } > > + > > + dev->coresba = addrl; > > + dev->coresba_size = sizel; > > + > > + /* Try to get one more Slave Address Descriptor in port 0 */ > > + asd = get_erom_ent(bus, &eromptr, SSB_EROM_VALID, > > + SSB_EROM_VALID) & (SSB_EROM_ASD_SP_MASK | > > + SSB_EROM_ASD_ST_MASK | > > + SSB_EROM_TAG); > > + eromptr--; > > + if (asd == SSB_EROM_ASD) { > > + asd = get_adress_space_descriptor(bus, &eromptr, > > + SSB_EROM_ASD_ST_SLAVE, > > + &addrl, &sizel); > > + if (sizel != SSB_CORE_SIZE) { > > + ssb_printk(KERN_ERR PFX > > + "Malformed or unsupported ai " > > + "address space descriptor for " > > + "core %d:\n\texpected 0x%x size, " > > + "got 0x%x size\n", > > + dev_i, SSB_CORE_SIZE, sizel); > > + return -EIO; > > + } > > + dev->coresba2 = addrl; > > + dev->coresba2_size = sizel; > > + } > > + > > + if (nmw) > > + asd = get_adress_space_descriptor(bus, &eromptr, > > + SSB_EROM_ASD_ST_MWRAP, > > + &addrl, &sizel); > > + else > > + asd = get_adress_space_descriptor(bus, &eromptr, > > + SSB_EROM_ASD_ST_SWRAP, > > + &addrl, &sizel); > > + > > + if (sizel != SSB_CORE_SIZE || > > + addrl != SSB_AI_BASE + SSB_CORE_SIZE * dev_i) { > > + ssb_printk(KERN_ERR PFX > > + "Malformed or unsupported ai " > > + "address space descriptor for " > > + "core %d:\n\texpected 0x%x, " > > + "got 0x%x, size 0x%x\n", > > + dev_i, SSB_AI_BASE + SSB_CORE_SIZE * dev_i, > > + addrl, sizel); > > + return -EIO; > > + } > > + > > + if (ssb_bus_check_core(dev, &nr_80211_cores, dev_i) < 0) > > + continue; > > + > > + dev_i++; > > + } > > + bus->nr_devices = dev_i; > > + > > + if (eromptr >= eromend) > > + ssb_printk(KERN_WARNING PFX > > + "Reached end of erom without finding END"); > > + > > + return 0; > > +} > > --- linux-next-20110203.orig/drivers/ssb/ssb_ai.h 1970-01-01 03:00:00.000000000 +0300 > > +++ linux-next-20110203/drivers/ssb/ssb_ai.h 2011-02-08 21:01:34.000000000 +0200 > > @@ -0,0 +1,61 @@ > > +#ifndef LINUX_SSB_AI_H_ > > +#define LINUX_SSB_AI_H_ > > + > > +#define SSB_AI_BASE 0x18100000 /* base for AI registers */ > > + > > +/* EROM parsing defines */ > > +#define SSB_EROM_VALID 1 > > +#define SSB_EROM_END 0x0E > > +#define SSB_EROM_TAG 0x0E > > + > > +/* Adress Space Descriptor */ > > +#define SSB_EROM_ASD 0x4 > > +#define SSB_EROM_ASD_SP_MASK 0x00000F00 > > +#define SSB_EROM_ASD_SP_SHIFT 8 > > +#define SSB_EROM_ASD_ST_MASK 0x000000c0 > > +#define SSB_EROM_ASD_ST_SLAVE 0x00000000 > > +#define SSB_EROM_ASD_ST_BRIDGE 0x00000040 > > +#define SSB_EROM_ASD_ST_MWRAP 0x000000C0 > > +#define SSB_EROM_ASD_ST_SWRAP 0x00000080 > > +#define SSB_EROM_ASD_ADDR_MASK 0xFFFFF000 > > +#define SSB_EROM_ASD_AG32 0x00000008 > > +#define SSB_EROM_ASD_SZ_MASK 0x00000030 > > +#define SSB_EROM_ASD_SZ_SZD 0x00000030 > > +#define SSB_EROM_ASD_SZ_SHIFT 4 > > +#define SSB_EROM_ASD_SZ_BASE 0x00001000 > > +#define SSB_EROM_CI 0 > > +#define SSB_EROM_CIA_CID_MASK 0x000FFF00 > > +#define SSB_EROM_CIA_CID_SHIFT 8 > > +#define SSB_EROM_CIA_MFG_MASK 0xFFF00000 > > +#define SSB_EROM_CIA_MFG_SHIFT 20 > > +#define SSB_EROM_CIB_REV_MASK 0xFF000000 > > +#define SSB_EROM_CIB_REV_SHIFT 24 > > +#define SSB_EROM_CIB_NMW_MASK 0x0007C000 > > +#define SSB_EROM_CIB_NMW_SHIFT 14 > > +#define SSB_EROM_CIB_NSW_MASK 0x00F80000 > > +#define SSB_EROM_CIB_NSW_SHIFT 19 > > +#define SSB_EROM_CIB_NSP_MASK 0x00003E00 > > +#define SSB_EROM_CIB_NSP_SHIFT 9 > > + > > +/* Adress Space Descriptor macro defs */ > > +#define SSB_EROM_CIA_CID(cia) (((cia) & SSB_EROM_CIA_CID_MASK) >> \ > > + SSB_EROM_CIA_CID_SHIFT) > > +#define SSB_EROM_CIA_MFG(cia) (((cia) & SSB_EROM_CIA_MFG_MASK) >> \ > > + SSB_EROM_CIA_MFG_SHIFT) > > +#define SSB_EROM_CIB_REV(cib) (((cib) & SSB_EROM_CIB_REV_MASK) >> \ > > + SSB_EROM_CIB_REV_SHIFT) > > +#define SSB_EROM_CIB_NMW(cib) (((cib) & SSB_EROM_CIB_NMW_MASK) >> \ > > + SSB_EROM_CIB_NMW_SHIFT) > > +#define SSB_EROM_CIB_NSW(cib) (((cib) & SSB_EROM_CIB_NSW_MASK) >> \ > > + SSB_EROM_CIB_NSW_SHIFT) > > +#define SSB_EROM_CIB_NSP(cib) (((cib) & SSB_EROM_CIB_NSP_MASK) >> \ > > + SSB_EROM_CIB_NSP_SHIFT) > > + > > +/* AI config space registers */ > > +#define SSB_AI_oobselouta30 0x100 > > +#define SSB_AI_IOCTL 0x408 /* maybe 0x40C for big endian */ > > +#define SSB_AI_IOSTAT 0x500 > > +#define SSB_AI_RESETCTL 0x800 /* maybe 0x804 for big endian */ > > +#define SSB_AI_RESETCTL_RESET 1 > > + > > +#endif /* LINUX_SSB_AI_H_ */ > > --- linux-next-20110203.orig/drivers/ssb/ssb_private.h 2011-02-08 16:14:57.000000000 +0200 > > +++ linux-next-20110203/drivers/ssb/ssb_private.h 2011-02-08 21:01:34.000000000 +0200 > > @@ -236,4 +236,13 @@ static inline int ssb_bus_scan_sb(struct > > } > > #endif /* CONFIG_SSB_BUS_SB */ > > > > +#ifdef CONFIG_SSB_BUS_AI > > +extern int ssb_bus_scan_ai(struct ssb_bus *bus); > > +#else /* CONFIG_SSB_BUS_AI */ > > +static inline int ssb_bus_scan_ai(struct ssb_bus *bus) > > +{ > > + return -ENODEV; > > +} > > +#endif /* CONFIG_SSB_BUS_AI */ > > + > > #endif /* LINUX_SSB_PRIVATE_H_ */ > > --- linux-next-20110203.orig/include/linux/ssb/ssb_driver_chipcommon.h 2011-02-08 13:49:32.000000000 +0200 > > +++ linux-next-20110203/include/linux/ssb/ssb_driver_chipcommon.h 2011-02-08 21:01:34.000000000 +0200 > > @@ -19,6 +19,7 @@ > > #define SSB_CHIPCO_TYPE_MASK 0xF0000000 > > #define SSB_CHIPCO_TYPE_SHIFT 28 > > #define SSB_CHIPCO_TYPE_SB 0 > > +#define SSB_CHIPCO_TYPE_AI 0x10000000 > > #define SSB_CHIPCO_IDMASK 0x0000FFFF > > #define SSB_CHIPCO_REVMASK 0x000F0000 > > #define SSB_CHIPCO_REVSHIFT 16 > > @@ -173,6 +174,7 @@ > > #define SSB_CHIPCO_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */ > > #define SSB_CHIPCO_SYSCLKCTL_CLKDIV_SHIFT 16 > > #define SSB_CHIPCO_CLKSTSTR 0x00C4 /* Rev >= 3 only */ > > +#define SSB_CHIPCO_EROM 0x00FC /* erom for AI socs */ > > #define SSB_CHIPCO_PCMCIA_CFG 0x0100 > > #define SSB_CHIPCO_PCMCIA_MEMWAIT 0x0104 > > #define SSB_CHIPCO_PCMCIA_ATTRWAIT 0x0108 > > @@ -584,6 +586,7 @@ struct ssb_chipcommon_pmu { > > /* Chipcommon implementation type */ > > enum ssb_chipco_chiptype { > > SSB_CHIPCO_SB = SSB_CHIPCO_TYPE(SSB_CHIPCO_TYPE_SB), /* SB-style bus */ > > + SSB_CHIPCO_AI = SSB_CHIPCO_TYPE(SSB_CHIPCO_TYPE_AI), /* AI-style bus */ > > }; > > > > struct ssb_chipcommon { > > --- linux-next-20110203.orig/include/linux/ssb/ssb.h 2011-02-08 18:33:58.000000000 +0200 > > +++ linux-next-20110203/include/linux/ssb/ssb.h 2011-02-08 21:01:34.000000000 +0200 > > @@ -168,9 +168,11 @@ struct ssb_bus_ops { > > #define SSB_DEV_MIPS_74K 0x82C > > #define SSB_DEV_DDR_CTRLR 0x82E > > #define SSB_DEV_I2S 0x834 > > +#define SSB_DEV_DEFAULT 0xFFF > > > > /* Vendor-ID values */ > > #define SSB_VENDOR_BROADCOM 0x4243 > > +#define SSB_VENDOR_ARM 0x043B > > > > /* Some kernel subsystems poke with dev->drvdata, so we must use the > > * following ugly workaround to get from struct device to struct ssb_device */ > > @@ -192,6 +194,13 @@ struct ssb_device { > > u8 core_index; > > unsigned int irq; > > > > +#ifdef CONFIG_SSB_BUS_AI > > + /* backplane address and size for core */ > > + u32 coresba, coresba_size; > > + /* address and size of core second register set (usbh20) */ > > + u32 coresba2, coresba2_size; > > +#endif > > + > > /* Internal-only stuff follows. */ > > void *drvdata; /* Per-device data */ > > void *devtypedata; /* Per-devicetype (eg 802.11) data */ > > @@ -283,6 +292,9 @@ enum ssb_bustype { > > struct ssb_bus { > > /* The MMIO area. */ > > void __iomem *mmio; > > +#ifdef CONFIG_SSB_BUS_AI > > + void __iomem *ai_mmio; > > +#endif > > > > const struct ssb_bus_ops *ops; > > > > > > > > This one also fails to apply: > > finger@larrylap:~/wireless-testing> quilt import ssb_AI_12 > Importing patch ssb_AI_12 (stored as patches/ssb_AI_12) > finger@larrylap:~/wireless-testing> quilt push > Applying patch patches/ssb_AI_12 > patching file drivers/ssb/Kconfig > patching file drivers/ssb/main.c > Hunk #1 succeeded at 841 (offset -1 lines). > patching file drivers/ssb/Makefile > patching file drivers/ssb/scan.c > Hunk #1 succeeded at 204 (offset -8 lines). > Hunk #2 succeeded at 360 (offset -8 lines). > Hunk #3 succeeded at 426 (offset -8 lines). > Hunk #4 succeeded at 468 (offset -8 lines). > patching file drivers/ssb/ssb_ai.c > patching file drivers/ssb/ssb_ai.h > patching file drivers/ssb/ssb_private.h > patching file include/linux/ssb/ssb_driver_chipcommon.h > patching file include/linux/ssb/ssb.h > Hunk #1 FAILED at 168. > Hunk #2 succeeded at 188 (offset -4 lines). > Hunk #3 succeeded at 286 (offset -4 lines). > 1 out of 3 hunks FAILED -- rejects in file include/linux/ssb/ssb.h > Patch patches/ssb_AI_12 does not apply (enforce with -f) > > Larry > Just found the source of unclean patch application. In my serie 11th one is actually 16th -.- To apply without reject I was to supply one more patch before 11th but I didn't. This one is for MIPS74k support and I completely missed that it is required for AI scan. Sorry. Missing part is attached. Please get it applied before 11th one. From: George Kashperko Defines neccesary for upcoming MIPS 74K ssb core support. Signed-off-by: George Kashperko --- drivers/ssb/scan.c | 8 ++++++++ include/linux/ssb/ssb.h | 4 ++++ 2 files changed, 12 insertions(+) --- linux-next-20110203.orig/drivers/ssb/scan.c 2011-02-08 17:32:03.000000000 +0200 +++ linux-next-20110203/drivers/ssb/scan.c 2011-02-08 18:25:39.000000000 +0200 @@ -90,6 +90,14 @@ const char *ssb_core_name(u16 coreid) return "ARM 1176"; case SSB_DEV_ARM_7TDMI: return "ARM 7TDMI"; + case SSB_DEV_ETHERNET_GMAC: + return "Gigabit MAC"; + case SSB_DEV_MIPS_74K: + return "MIPS 74K"; + case SSB_DEV_DDR_CTRLR: + return "DDR1/2 memory controller"; + case SSB_DEV_I2S: + return "I2S"; } return "UNKNOWN"; } --- linux-next-20110203.orig/include/linux/ssb/ssb.h 2011-02-08 18:25:22.000000000 +0200 +++ linux-next-20110203/include/linux/ssb/ssb.h 2011-02-08 18:25:55.000000000 +0200 @@ -164,6 +164,10 @@ struct ssb_bus_ops { #define SSB_DEV_MINI_MACPHY 0x823 #define SSB_DEV_ARM_1176 0x824 #define SSB_DEV_ARM_7TDMI 0x825 +#define SSB_DEV_ETHERNET_GMAC 0x82D +#define SSB_DEV_MIPS_74K 0x82C +#define SSB_DEV_DDR_CTRLR 0x82E +#define SSB_DEV_I2S 0x834 /* Vendor-ID values */ #define SSB_VENDOR_BROADCOM 0x4243