b43-dev.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] bcma: add support for embedded devices like bcm4716
@ 2011-07-09 11:05 Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 01/11] bcma: move parsing of EEPROM into own function Hauke Mehrtens
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

This patch series adds support for embedded devices like bcm47xx to 
bcma. Bcma is used on bcm4716 and bcm4718 SoCs as the system bus and
replaced ssb used on older devices. With these patches my bcm4716 
device boots up till it tries to access the flash, because the serial 
flash chip is unsupported for now, this will be my next task. This adds 
support for MIPS cores, interrupt configuration and the serial console.

These patches are not containing all functions needed to get the SoC to 
fully work and support every feature, but it is a good start.
These patches are now integrated in OpenWrt for everyone how wants to
test them.

This was tested with a BCM4704 device (SoC with ssb bus), a BCM4716 
device and a pcie wireless card supported by bcma.


@Rafa?: If you are fine with the bcma patches could you please give
your Signed-off on them.

PATCH v1:
 * rebased on mips tree (mips/queue)
 * drop pcie hostmode patch as Rafa? sent a better patch to wireless mailing list
 * drop sprom patch because sprom is not supported in bcma version from mips tree,
     I will send a separate patch to wireless mailing list.
 * fix compilation of arch/mips/bcm47xx/wgt634u.c
 * fix texts in arch/mips/bcm47xx/Kconfig
RFC v3:
 * make bcm47xx built either with bcma, ssb or both and use mips MIPS 74K optimizations if possible
 * add block io support
 * some minor fixes for code and doku
RFC v2:
 * use list and no arry to store cores
 * rename bcma_host_bcma_ to bcma_host_soc_
 * use core->io_addr and core->io_wrap to access cores
 * checkpatch fixes
 * some minor fixes


Hauke Mehrtens (11):
  bcma: move parsing of EEPROM into own function.
  bcma: move initializing of struct bcma_bus to own function.
  bcma: add functions to scan cores needed on SoCs
  bcma: add SOC bus
  bcma: add mips driver
  bcma: add serial console support
  bcma: get CPU clock
  bcm47xx: prepare to support different buses
  bcm47xx: make it possible to build bcm47xx without ssb.
  bcm47xx: add support for bcma bus
  bcm47xx: fix irq assignment for new SoCs.

 arch/mips/Kconfig                            |    8 +-
 arch/mips/bcm47xx/Kconfig                    |   31 +++
 arch/mips/bcm47xx/Makefile                   |    3 +-
 arch/mips/bcm47xx/gpio.c                     |   82 +++++--
 arch/mips/bcm47xx/irq.c                      |   12 +
 arch/mips/bcm47xx/nvram.c                    |   29 ++-
 arch/mips/bcm47xx/serial.c                   |   46 ++++-
 arch/mips/bcm47xx/setup.c                    |   90 +++++++-
 arch/mips/bcm47xx/time.c                     |   16 +-
 arch/mips/bcm47xx/wgt634u.c                  |   14 +-
 arch/mips/include/asm/mach-bcm47xx/bcm47xx.h |   26 ++-
 arch/mips/include/asm/mach-bcm47xx/gpio.h    |  108 +++++++--
 arch/mips/pci/pci-bcm47xx.c                  |    6 +
 drivers/bcma/Kconfig                         |   14 +
 drivers/bcma/Makefile                        |    2 +
 drivers/bcma/bcma_private.h                  |   16 ++
 drivers/bcma/driver_chipcommon.c             |   69 ++++++
 drivers/bcma/driver_chipcommon_pmu.c         |   87 +++++++
 drivers/bcma/driver_mips.c                   |  254 +++++++++++++++++++
 drivers/bcma/driver_pci.c                    |    3 +
 drivers/bcma/host_soc.c                      |  178 ++++++++++++++
 drivers/bcma/main.c                          |   65 +++++
 drivers/bcma/scan.c                          |  336 +++++++++++++++++---------
 drivers/watchdog/bcm47xx_wdt.c               |   27 ++-
 include/linux/bcma/bcma.h                    |    8 +
 include/linux/bcma/bcma_driver_chipcommon.h  |   36 +++
 include/linux/bcma/bcma_driver_mips.h        |   61 +++++
 include/linux/bcma/bcma_soc.h                |   16 ++
 28 files changed, 1464 insertions(+), 179 deletions(-)
 create mode 100644 arch/mips/bcm47xx/Kconfig
 create mode 100644 drivers/bcma/driver_mips.c
 create mode 100644 drivers/bcma/host_soc.c
 create mode 100644 include/linux/bcma/bcma_driver_mips.h
 create mode 100644 include/linux/bcma/bcma_soc.h

-- 
1.7.4.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/11] bcma: move parsing of EEPROM into own function.
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 02/11] bcma: move initializing of struct bcma_bus to " Hauke Mehrtens
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

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(-)

diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 40d7dcc..4012d8d 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -200,16 +200,124 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
 	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);
-			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);
+		err = bcma_get_next_core(bus, &eromptr, core);
+		if (err == -ENXIO)
 			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;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/11] bcma: move initializing of struct bcma_bus to own function.
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 01/11] bcma: move parsing of EEPROM into own function Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 03/11] bcma: add functions to scan cores needed on SoCs Hauke Mehrtens
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

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(-)

diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 4012d8d..7970553 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -312,15 +312,10 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 	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;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/11] bcma: add functions to scan cores needed on SoCs
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 01/11] bcma: move parsing of EEPROM into own function Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 02/11] bcma: move initializing of struct bcma_bus to " Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-09 11:05 ` [PATCH 04/11] bcma: add SOC bus Hauke Mehrtens
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

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.
The cores are getting the same numbers as before.

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(-)

diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 2f72e9c..830386c 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -15,9 +15,16 @@ struct bcma_bus;
 /* main.c */
 extern int bcma_bus_register(struct bcma_bus *bus);
 extern 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);
 
 #ifdef CONFIG_BCMA_HOST_PCI
 /* host_pci.c */
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 6061022..70321c6 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -23,6 +23,9 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
 
 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 bcma_drv_cc *cc)
 		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 */
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index e757e4e..f7378b3 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -159,5 +159,8 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
 
 void bcma_core_pci_init(struct bcma_drv_pci *pc)
 {
+	if (pc->setup_done)
+		return;
 	bcma_pcicore_serdes_workaround(pc);
+	pc->setup_done = true;
 }
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index be52344..e6c308c 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -159,6 +159,51 @@ void bcma_bus_unregister(struct bcma_bus *bus)
 }
 EXPORT_SYMBOL_GPL(bcma_bus_unregister);
 
+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;
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 7970553..bf9f806 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -200,7 +200,20 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
 	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 bcma_bus *bus, u32 __iomem **eromptr,
 		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 bcma_bus *bus, u32 __iomem **eromptr,
 	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_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;
+	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;
+}
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 08763e4..6bd7b7f 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -176,6 +176,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;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 083c3b6..837c176 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -258,6 +258,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;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/11] bcma: add SOC bus
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (2 preceding siblings ...)
  2011-07-09 11:05 ` [PATCH 03/11] bcma: add functions to scan cores needed on SoCs Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-13 19:36   ` Jonas Gorski
  2011-07-09 11:05 ` [PATCH 05/11] bcma: add mips driver Hauke Mehrtens
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

This patch adds support for using bcma on a Broadcom SoC as the system
bus. An SoC like the bcm4716 could register this bus and use it to
searches for the bcma cores and register the devices on this bus.

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

diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 353781b..8d82f42 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -22,6 +22,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
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 0d56245..42d61dd 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -2,6 +2,7 @@ bcma-y					+= main.o scan.o core.o
 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
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
new file mode 100644
index 0000000..a6fe724
--- /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);
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index e6c308c..2ca5eeb 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -92,6 +92,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
 			break;
 		case BCMA_HOSTTYPE_NONE:
 		case BCMA_HOSTTYPE_SDIO:
+		case BCMA_HOSTTYPE_SOC:
 			break;
 		}
 
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index bf9f806..202edc8 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -337,6 +337,14 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 			}
 		}
 	}
+	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 bcma_bus *bus,
 	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);
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 6bd7b7f..73fda1c 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -16,6 +16,7 @@ enum bcma_hosttype {
 	BCMA_HOSTTYPE_NONE,
 	BCMA_HOSTTYPE_PCI,
 	BCMA_HOSTTYPE_SDIO,
+	BCMA_HOSTTYPE_SOC,
 };
 
 struct bcma_chipinfo {
@@ -124,6 +125,9 @@ struct bcma_device {
 	u32 addr;
 	u32 wrap;
 
+	void __iomem *io_addr;
+	void __iomem *io_wrap;
+
 	void *drvdata;
 	struct list_head list;
 };
diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h
new file mode 100644
index 0000000..4203c55
--- /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_ */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/11] bcma: add mips driver
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (3 preceding siblings ...)
  2011-07-09 11:05 ` [PATCH 04/11] bcma: add SOC bus Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-13 20:39   ` Jonas Gorski
  2011-07-09 11:05 ` [PATCH 06/11] bcma: add serial console support Hauke Mehrtens
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

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            |  233 +++++++++++++++++++++++++++++++++
 drivers/bcma/main.c                   |   19 +++
 include/linux/bcma/bcma.h             |    3 +
 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

diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 8d82f42..81926ce 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -24,9 +24,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
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 42d61dd..a4352e5 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -1,6 +1,7 @@
 bcma-y					+= main.o scan.o core.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
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
new file mode 100644
index 0000000..605bb08
--- /dev/null
+++ b/drivers/bcma/driver_mips.c
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+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;
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 2ca5eeb..ba9a357 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -79,6 +79,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
 		case BCMA_CORE_CHIPCOMMON:
 		case BCMA_CORE_PCI:
 		case BCMA_CORE_PCIE:
+		case BCMA_CORE_MIPS_74K:
 			continue;
 		}
 
@@ -138,6 +139,15 @@ int bcma_bus_register(struct bcma_bus *bus)
 		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) {
@@ -200,6 +210,15 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
 		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;
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 73fda1c..12313fd 100644
--- 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 "bcma_regs.h"
 
@@ -118,6 +119,7 @@ struct bcma_device {
 	struct bcma_device_id id;
 
 	struct device dev;
+	unsigned int irq;
 	bool dev_registered;
 
 	u8 core_index;
@@ -184,6 +186,7 @@ struct bcma_bus {
 
 	struct bcma_drv_cc drv_cc;
 	struct bcma_drv_pci drv_pci;
+	struct bcma_drv_mips drv_mips;
 };
 
 extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
new file mode 100644
index 0000000..f19b21a
--- /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_ */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/11] bcma: add serial console support
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (4 preceding siblings ...)
  2011-07-09 11:05 ` [PATCH 05/11] bcma: add mips driver Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-13 20:56   ` Jonas Gorski
  2011-07-09 11:05 ` [PATCH 07/11] bcma: get CPU clock Hauke Mehrtens
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

This adds support for serial console to bcma, when operating on an SoC.

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(-)

diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 830386c..92ec671 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -26,6 +26,12 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus,
 			       struct bcma_device *core);
 void bcma_init_bus(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);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 70321c6..88533ca 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -92,3 +92,67 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
 	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 */
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
index 605bb08..3989fb9 100644
--- a/drivers/bcma/driver_mips.c
+++ b/drivers/bcma/driver_mips.c
@@ -156,6 +156,14 @@ static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
 	}
 }
 
+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;
@@ -228,6 +236,7 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore)
 	if (mcore->setup_done)
 		return;
 
+	bcma_core_mips_serial_init(mcore);
 	bcma_core_mips_flash_detect(mcore);
 	mcore->setup_done = true;
 }
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
index f19b21a..13b44c2 100644
--- 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;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/11] bcma: get CPU clock
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (5 preceding siblings ...)
  2011-07-09 11:05 ` [PATCH 06/11] bcma: add serial console support Hauke Mehrtens
@ 2011-07-09 11:05 ` Hauke Mehrtens
  2011-07-09 11:06 ` [PATCH 08/11] bcm47xx: prepare to support different buses Hauke Mehrtens
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:05 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

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(-)

diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 92ec671..7e126b9 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -26,6 +26,9 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus,
 			       struct bcma_device *core);
 void bcma_init_bus(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,
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index f44177a..83988be 100644
--- 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)
 {
@@ -132,3 +139,83 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
 	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);
+}
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
index 3989fb9..813f9df 100644
--- a/drivers/bcma/driver_mips.c
+++ b/drivers/bcma/driver_mips.c
@@ -156,6 +156,18 @@ static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
 	}
 }
 
+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;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 837c176..9da7562 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -245,6 +245,41 @@
 #define BCMA_CC_PLLCTL_ADDR		0x0660
 #define BCMA_CC_PLLCTL_DATA		0x0664
 
+/* 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)
  */
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
index 13b44c2..402af95 100644
--- 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);
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/11] bcm47xx: prepare to support different buses
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (6 preceding siblings ...)
  2011-07-09 11:05 ` [PATCH 07/11] bcma: get CPU clock Hauke Mehrtens
@ 2011-07-09 11:06 ` Hauke Mehrtens
  2011-07-09 11:06 ` [PATCH 09/11] bcm47xx: make it possible to build bcm47xx without ssb Hauke Mehrtens
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:06 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

Prepare bcm47xx to support different System buses. Before adding
support for bcma it should be possible to build bcm47xx without the
need of ssb. With this patch bcm47xx does not directly contain a
ssb_bus, but a union contain all the supported system buses. As a SoC
just uses one system bus a union is a good choice.

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                    |   33 ++++++++++++---
 arch/mips/bcm47xx/time.c                     |    9 +++-
 arch/mips/bcm47xx/wgt634u.c                  |   14 ++++--
 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, 160 insertions(+), 61 deletions(-)

diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
index e4a5ee9..2f6d2df 100644
--- a/arch/mips/bcm47xx/gpio.c
+++ b/arch/mips/bcm47xx/gpio.c
@@ -20,42 +20,54 @@ static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
 
 int gpio_request(unsigned gpio, const char *tag)
 {
-	if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-	    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-		return -EINVAL;
+	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(&ssb_bcm47xx.extif) &&
-	    ((unsigned)gpio >= BCM47XX_EXTIF_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;
+		if (test_and_set_bit(gpio, gpio_in_use))
+			return -EBUSY;
 
-	return 0;
+		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(&ssb_bcm47xx.extif) &&
-	    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-		return;
+		if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+		    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+			return;
 
-	clear_bit(gpio, gpio_in_use);
+		clear_bit(gpio, gpio_in_use);
+		return;
+	}
 }
 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);
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 54db815..d2304d0 100644
--- 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) {
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index 59c11af..87c2c5e 100644
--- a/arch/mips/bcm47xx/serial.c
+++ b/arch/mips/bcm47xx/serial.c
@@ -23,10 +23,10 @@ static struct platform_device uart8250_device = {
 	},
 };
 
-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>");
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 73b529b..bff4181 100644
--- 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 ssb_bus *bus,
 	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 = &current_cpu_data;
+
+	bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
+	bcm47xx_register_ssb();
 
 	_machine_restart = bcm47xx_machine_restart;
 	_machine_halt = bcm47xx_machine_halt;
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index 0c6f47b..a7be993 100644
--- 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;
 
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
index 74d0696..d4aedd5 100644
--- a/arch/mips/bcm47xx/wgt634u.c
+++ b/arch/mips/bcm47xx/wgt634u.c
@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int irq, void *ignored)
 
 	/* 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;
 
@@ -132,22 +132,26 @@ static int __init wgt634u_init(void)
 	 * machine. Use the MAC address as an heuristic. Netgear Inc. has
 	 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
 	 */
+	u8 *et0mac;
 
-	u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+	if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB)
+		return -ENODEV;
+
+	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);
 		}
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index d008f47..4be8b95 100644
--- 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 */
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 9850414..976b8aa 100644
--- 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;
 }
 
 
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index bd44417..7e4e063 100644
--- 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)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/11] bcm47xx: make it possible to build bcm47xx without ssb.
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (7 preceding siblings ...)
  2011-07-09 11:06 ` [PATCH 08/11] bcm47xx: prepare to support different buses Hauke Mehrtens
@ 2011-07-09 11:06 ` Hauke Mehrtens
  2011-07-09 11:06 ` [PATCH 10/11] bcm47xx: add support for bcma bus Hauke Mehrtens
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:06 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens


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

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 653da62..ac6f237 100644
--- 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"
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
new file mode 100644
index 0000000..0346f92
--- /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.
+
+	 This will generate an image with support for SSB and MIPS32 R1 instruction set.
+
+endif
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
index 7465e8a..4add173 100644
--- 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
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
index 2f6d2df..3320e91 100644
--- a/arch/mips/bcm47xx/gpio.c
+++ b/arch/mips/bcm47xx/gpio.c
@@ -21,6 +21,7 @@ static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
 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 char *tag)
 			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;
 }
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index d2304d0..d223dac 100644
--- 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;
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index 87c2c5e..e9258cb 100644
--- a/arch/mips/bcm47xx/serial.c
+++ b/arch/mips/bcm47xx/serial.c
@@ -23,6 +23,7 @@ static struct platform_device uart8250_device = {
 	},
 };
 
+#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;
 }
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index bff4181..9fc92bd 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -47,9 +47,11 @@ static void bcm47xx_machine_restart(char *command)
 	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(void)
 		}
 	}
 }
+#endif
 
 void __init plat_mem_setup(void)
 {
 	struct cpuinfo_mips *c = &current_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;
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index a7be993..02a652a 100644
--- 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)
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index 4be8b95..764afea 100644
--- 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;
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 976b8aa..0c3bd1f 100644
--- 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(unsigned gpio)
 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(unsigned gpio)
 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(unsigned gpio, int value)
 		/* 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(unsigned gpio, int value)
 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 gpio, int value)
 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;
 }
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c
index 455f8e5..924e158 100644
--- 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 pci_dev *dev, u8 slot, u8 pin)
 
 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)
 	}
 
 	dev->irq = res;
+#endif
 	return 0;
 }
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 7e4e063..beacd79 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -55,17 +55,21 @@ static inline void bcm47xx_wdt_hw_start(void)
 {
 	/* 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;
 }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/11] bcm47xx: add support for bcma bus
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (8 preceding siblings ...)
  2011-07-09 11:06 ` [PATCH 09/11] bcm47xx: make it possible to build bcm47xx without ssb Hauke Mehrtens
@ 2011-07-09 11:06 ` Hauke Mehrtens
  2011-07-13 19:52   ` Jonas Gorski
  2011-07-09 11:06 ` [PATCH 11/11] bcm47xx: fix irq assignment for new SoCs Hauke Mehrtens
  2011-07-13 18:33 ` [PATCH 00/11] bcma: add support for embedded devices like bcm4716 John W. Linville
  11 siblings, 1 reply; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:06 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

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(-)

diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
index 0346f92..6210b8d 100644
--- 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 R1 instruction set.
 
+config BCM47XX_BCMA
+	bool "BCMA Support for Broadcom BCM47XX"
+	select SYS_HAS_CPU_MIPS32_R2
+	select BCMA
+	select BCMA_HOST_SOC
+	select BCMA_DRIVER_MIPS
+	select BCMA_DRIVER_PCI_HOSTMODE if PCI
+	default y
+	help
+	 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
+
+	 This will generate an image with support for BCMA and MIPS32 R2 instruction set.
+
 endif
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
index 3320e91..9d5bafe 100644
--- a/arch/mips/bcm47xx/gpio.c
+++ b/arch/mips/bcm47xx/gpio.c
@@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const char *tag)
 
 		return 0;
 #endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		if ((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;
 }
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index d223dac..1dafb9b 100644
--- 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;
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index e9258cb..52ce06a 100644
--- 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;
 }
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 9fc92bd..612a5ec 100644
--- 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 *command)
 		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(void)
 }
 #endif
 
+#ifdef CONFIG_BCM47XX_BCMA
+static void __init bcm47xx_register_bcma(void)
+{
+	int err;
+
+	err = bcma_host_soc_register(&bcm47xx_bus.bcma);
+	if (err)
+		panic("Failed to initialize BCMA bus (err %d)\n", err);
+}
+#endif
+
 void __init plat_mem_setup(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 
+	if (c->cputype == CPU_74K) {
+		printk(KERN_INFO "bcm47xx: using bcma bus\n");
+#ifdef CONFIG_BCM47XX_BCMA
+		bcm47xx_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);
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index 02a652a..c10471a 100644
--- 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)
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index 764afea..3959485 100644
--- 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;
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 0c3bd1f..0dcb71a 100644
--- 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(unsigned gpio)
 	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(unsigned gpio, int value)
 	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(unsigned gpio)
 		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(unsigned gpio, int value)
 		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 gpio, int value)
 				 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 gpio, int value)
 				  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;
 }
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index beacd79..febce9b 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -60,6 +60,12 @@ static inline void bcm47xx_wdt_hw_start(void)
 		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(void)
 	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;
 }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/11] bcm47xx: fix irq assignment for new SoCs.
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (9 preceding siblings ...)
  2011-07-09 11:06 ` [PATCH 10/11] bcm47xx: add support for bcma bus Hauke Mehrtens
@ 2011-07-09 11:06 ` Hauke Mehrtens
  2011-07-13 18:33 ` [PATCH 00/11] bcma: add support for embedded devices like bcm4716 John W. Linville
  11 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-09 11:06 UTC (permalink / raw)
  To: ralf, linux-wireless, zajec5, linux-mips
  Cc: mb, george, arend, b43-dev, bernhardloos, arnd, julian.calaby,
	sshtylyov, Hauke Mehrtens

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 arch/mips/bcm47xx/irq.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
index 325757a..70bdcf0 100644
--- 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();
 }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 00/11] bcma: add support for embedded devices like bcm4716
  2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
                   ` (10 preceding siblings ...)
  2011-07-09 11:06 ` [PATCH 11/11] bcm47xx: fix irq assignment for new SoCs Hauke Mehrtens
@ 2011-07-13 18:33 ` John W. Linville
  11 siblings, 0 replies; 19+ messages in thread
From: John W. Linville @ 2011-07-13 18:33 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

On Sat, Jul 09, 2011 at 01:05:52PM +0200, Hauke Mehrtens wrote:
> This patch series adds support for embedded devices like bcm47xx to 
> bcma. Bcma is used on bcm4716 and bcm4718 SoCs as the system bus and
> replaced ssb used on older devices. With these patches my bcm4716 
> device boots up till it tries to access the flash, because the serial 
> flash chip is unsupported for now, this will be my next task. This adds 
> support for MIPS cores, interrupt configuration and the serial console.
> 
> These patches are not containing all functions needed to get the SoC to 
> fully work and support every feature, but it is a good start.
> These patches are now integrated in OpenWrt for everyone how wants to
> test them.
> 
> This was tested with a BCM4704 device (SoC with ssb bus), a BCM4716 
> device and a pcie wireless card supported by bcma.
> 
> 
> @Rafa?: If you are fine with the bcma patches could you please give
> your Signed-off on them.

Rafa?, ping?

-- 
John W. Linville		Someday the world will need a hero, and you
linville at tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 04/11] bcma: add SOC bus
  2011-07-09 11:05 ` [PATCH 04/11] bcma: add SOC bus Hauke Mehrtens
@ 2011-07-13 19:36   ` Jonas Gorski
  2011-07-14 20:37     ` Hauke Mehrtens
  0 siblings, 1 reply; 19+ messages in thread
From: Jonas Gorski @ 2011-07-13 19:36 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

Hi,

some minor things I saw:

On 9 July 2011 13:05, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> This patch adds support for using bcma on a Broadcom SoC as the system
> bus. An SoC like the bcm4716 could register this bus and use it to
> searches for the bcma cores and register the devices on this bus.
>
> 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
>
> diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
> index 353781b..8d82f42 100644
> --- a/drivers/bcma/Kconfig
> +++ b/drivers/bcma/Kconfig
> @@ -22,6 +22,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

Default default is already "n", so this line is superfluous.

> +
> ?config BCMA_DEBUG
> ? ? ? ?bool "BCMA debugging"
> ? ? ? ?depends on BCMA
> diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
> index 0d56245..42d61dd 100644
> --- a/drivers/bcma/Makefile
> +++ b/drivers/bcma/Makefile
> @@ -2,6 +2,7 @@ bcma-y ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?+= main.o scan.o core.o
> ?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
> diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
> new file mode 100644
> index 0000000..a6fe724
> --- /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);
> +}
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index e6c308c..2ca5eeb 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -92,6 +92,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_NONE:
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_SDIO:
> + ? ? ? ? ? ? ? case BCMA_HOSTTYPE_SOC:
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?}
>
> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
> index bf9f806..202edc8 100644
> --- a/drivers/bcma/scan.c
> +++ b/drivers/bcma/scan.c
> @@ -337,6 +337,14 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
> ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?}
> ? ? ? ?}
> + ? ? ? 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;

Shouldn't you unmap core->io_addr if remapping io_wrap fails?

> + ? ? ? }
> ? ? ? ?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;

Documentation/CodingStyle says use braces in both branches if one needs them.

> +
> ? ? ? ?eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
>
> ? ? ? ?bcma_scan_switch_core(bus, erombase);
> @@ -417,7 +431,13 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus,
> ? ? ? ?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;

Ditto.

> +
> ? ? ? ?eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
>
> ? ? ? ?bcma_scan_switch_core(bus, erombase);
> diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
> index 6bd7b7f..73fda1c 100644
> --- a/include/linux/bcma/bcma.h
> +++ b/include/linux/bcma/bcma.h
> @@ -16,6 +16,7 @@ enum bcma_hosttype {
> ? ? ? ?BCMA_HOSTTYPE_NONE,
> ? ? ? ?BCMA_HOSTTYPE_PCI,
> ? ? ? ?BCMA_HOSTTYPE_SDIO,
> + ? ? ? BCMA_HOSTTYPE_SOC,
> ?};
>
> ?struct bcma_chipinfo {
> @@ -124,6 +125,9 @@ struct bcma_device {
> ? ? ? ?u32 addr;
> ? ? ? ?u32 wrap;
>
> + ? ? ? void __iomem *io_addr;
> + ? ? ? void __iomem *io_wrap;
> +
> ? ? ? ?void *drvdata;
> ? ? ? ?struct list_head list;
> ?};
> diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h
> new file mode 100644
> index 0000000..4203c55
> --- /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_ */
> --
> 1.7.4.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 10/11] bcm47xx: add support for bcma bus
  2011-07-09 11:06 ` [PATCH 10/11] bcm47xx: add support for bcma bus Hauke Mehrtens
@ 2011-07-13 19:52   ` Jonas Gorski
  2011-07-13 20:05     ` Hauke Mehrtens
  0 siblings, 1 reply; 19+ messages in thread
From: Jonas Gorski @ 2011-07-13 19:52 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

On 9 July 2011 13:06, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> 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(-)
>
> diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
> index 0346f92..6210b8d 100644
> --- 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 R1 instruction set.
>
> +config BCM47XX_BCMA
> + ? ? ? bool "BCMA Support for Broadcom BCM47XX"
> + ? ? ? select SYS_HAS_CPU_MIPS32_R2
> + ? ? ? select BCMA
> + ? ? ? select BCMA_HOST_SOC
> + ? ? ? select BCMA_DRIVER_MIPS
> + ? ? ? select BCMA_DRIVER_PCI_HOSTMODE if PCI
> + ? ? ? default y
> + ? ? ? help
> + ? ? ? ?Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
> +
> + ? ? ? ?This will generate an image with support for BCMA and MIPS32 R2 instruction set.
> +

BCM47XX_SSB and BCM47XX_BCMA should either exclude each other, or
SYS_HAS_CPU_MIPS32_R2 should only be selected when BCM47XX_SSB isn't
selected.
I would expect an image built when having both selected to also
support both systems, but selecting MIPS32_R2 as the CPU this will
make it actually not work on SSB systems.

> diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
> index 3320e91..9d5bafe 100644
> --- a/arch/mips/bcm47xx/gpio.c
> +++ b/arch/mips/bcm47xx/gpio.c
> @@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const char *tag)
>
> ? ? ? ? ? ? ? ?return 0;
> ?#endif
> +#ifdef CONFIG_BCM47XX_BCMA
> + ? ? ? case BCM47XX_BUS_TYPE_BCMA:
> + ? ? ? ? ? ? ? if ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)

gpio is already unsigned, you shouldn't need to cast it.

> + ? ? ? ? ? ? ? ? ? ? ? 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)

Ditto.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 10/11] bcm47xx: add support for bcma bus
  2011-07-13 19:52   ` Jonas Gorski
@ 2011-07-13 20:05     ` Hauke Mehrtens
  0 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-13 20:05 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

Hi  Jonas,

Thank you for the review.

On 07/13/2011 09:52 PM, Jonas Gorski wrote:
> On 9 July 2011 13:06, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>> 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(-)
>>
>> diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
>> index 0346f92..6210b8d 100644
>> --- 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 R1 instruction set.
>>
>> +config BCM47XX_BCMA
>> +       bool "BCMA Support for Broadcom BCM47XX"
>> +       select SYS_HAS_CPU_MIPS32_R2
>> +       select BCMA
>> +       select BCMA_HOST_SOC
>> +       select BCMA_DRIVER_MIPS
>> +       select BCMA_DRIVER_PCI_HOSTMODE if PCI
>> +       default y
>> +       help
>> +        Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
>> +
>> +        This will generate an image with support for BCMA and MIPS32 R2 instruction set.
>> +
> 
> BCM47XX_SSB and BCM47XX_BCMA should either exclude each other, or
> SYS_HAS_CPU_MIPS32_R2 should only be selected when BCM47XX_SSB isn't
> selected.
> I would expect an image built when having both selected to also
> support both systems, but selecting MIPS32_R2 as the CPU this will
> make it actually not work on SSB systems.
It should be possible to build a kernel capable of running with both
versions. I would change "select SYS_HAS_CPU_MIPS32_R2" to "select
SYS_HAS_CPU_MIPS32_R2 if !BCM47XX_SSB" that should make the image mips
r1 compatible if it was build for older cpus.
> 
>> diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
>> index 3320e91..9d5bafe 100644
>> --- a/arch/mips/bcm47xx/gpio.c
>> +++ b/arch/mips/bcm47xx/gpio.c
>> @@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const char *tag)
>>
>>                return 0;
>>  #endif
>> +#ifdef CONFIG_BCM47XX_BCMA
>> +       case BCM47XX_BUS_TYPE_BCMA:
>> +               if ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)
> 
> gpio is already unsigned, you shouldn't need to cast it.
Will do that.
> 
>> +                       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)
> 
> Ditto.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 05/11] bcma: add mips driver
  2011-07-09 11:05 ` [PATCH 05/11] bcma: add mips driver Hauke Mehrtens
@ 2011-07-13 20:39   ` Jonas Gorski
  0 siblings, 0 replies; 19+ messages in thread
From: Jonas Gorski @ 2011-07-13 20:39 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

On 9 July 2011 13:05, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index 2ca5eeb..ba9a357 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -79,6 +79,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ?case BCMA_CORE_CHIPCOMMON:
> ? ? ? ? ? ? ? ?case BCMA_CORE_PCI:
> ? ? ? ? ? ? ? ?case BCMA_CORE_PCIE:
> + ? ? ? ? ? ? ? case BCMA_CORE_MIPS_74K:
> ? ? ? ? ? ? ? ? ? ? ? ?continue;
> ? ? ? ? ? ? ? ?}
>
> @@ -138,6 +139,15 @@ int bcma_bus_register(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ?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

You could avoid the ugly ifdefs here by moving it to
bcma_driver_mips.h and change

extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);

to
#ifdef CONFIG_BCMA_DRIVER_MIPS
extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
#else
static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
#endif

assuming the bus->drv_mips.core being set doesn't have any side
effects in the no mips core driver case.

> +
> ? ? ? ?/* Init PCIE core */
> ? ? ? ?core = bcma_find_core(bus, BCMA_CORE_PCIE);
> ? ? ? ?if (core) {
> @@ -200,6 +210,15 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
> ? ? ? ? ? ? ? ?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

Ditto.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 06/11] bcma: add serial console support
  2011-07-09 11:05 ` [PATCH 06/11] bcma: add serial console support Hauke Mehrtens
@ 2011-07-13 20:56   ` Jonas Gorski
  0 siblings, 0 replies; 19+ messages in thread
From: Jonas Gorski @ 2011-07-13 20:56 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

On 9 July 2011 13:05, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> This adds support for serial console to bcma, when operating on an SoC.
>
> 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(-)
>
> diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
> index 830386c..92ec671 100644
> --- a/drivers/bcma/bcma_private.h
> +++ b/drivers/bcma/bcma_private.h
> @@ -26,6 +26,12 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct bcma_device *core);
> ?void bcma_init_bus(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);
> diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
> index 70321c6..88533ca 100644
> --- a/drivers/bcma/driver_chipcommon.c
> +++ b/drivers/bcma/driver_chipcommon.c
> @@ -92,3 +92,67 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
> ?{
> ? ? ? ?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);

Documentation/CodingStyle and again ;-)

> +
> + ? ? ? /* 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);

cc_mmio is constant for all uarts, so you should move it out of the
loop and calculate it once.

> + ? ? ? ? ? ? ? uart_regs = cc_mmio + BCMA_CC_UART0_DATA;
> + ? ? ? ? ? ? ? uart_regs += (i * 256);

Same for the uart_regs base. If you don't modify it at all you could
drop the cc_mmio variable (since you only need it to calculate
uart_regs) and

> +
> + ? ? ? ? ? ? ? nr_ports++;
> + ? ? ? ? ? ? ? ports[i].regs = uart_regs;

use here
 ? ? ? ? ? ? ? ports[i].regs = uart_regs + (i * 256);

This would make the code a bit cleaner IMHO.

> + ? ? ? ? ? ? ? ports[i].irq = irq;
> + ? ? ? ? ? ? ? ports[i].baud_base = baud_base;
> + ? ? ? ? ? ? ? ports[i].reg_shift = 0;
> + ? ? ? }
> +
> + ? ? ? return nr_ports;

Isn't n always the same as nr_ports? At least I don't see any case
where it could differ, so you should be safe when directly using
nr_ports instead of n.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 04/11] bcma: add SOC bus
  2011-07-13 19:36   ` Jonas Gorski
@ 2011-07-14 20:37     ` Hauke Mehrtens
  0 siblings, 0 replies; 19+ messages in thread
From: Hauke Mehrtens @ 2011-07-14 20:37 UTC (permalink / raw)
  To: Jonas Gorski
  Cc: ralf, linux-wireless, zajec5, linux-mips, mb, george, arend,
	b43-dev, bernhardloos, arnd, julian.calaby, sshtylyov

Hi Jonas,


On 07/13/2011 09:36 PM, Jonas Gorski wrote:
> Hi,
> 
> some minor things I saw:
> 
> On 9 July 2011 13:05, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>> This patch adds support for using bcma on a Broadcom SoC as the system
>> bus. An SoC like the bcm4716 could register this bus and use it to
>> searches for the bcma cores and register the devices on this bus.
>>
>> 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
>>
>> diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
>> index 353781b..8d82f42 100644
>> --- a/drivers/bcma/Kconfig
>> +++ b/drivers/bcma/Kconfig
>> @@ -22,6 +22,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
> 
> Default default is already "n", so this line is superfluous.

Will remove this.

> 
>> +
>>  config BCMA_DEBUG
>>        bool "BCMA debugging"
>>        depends on BCMA
>> diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
>> index 0d56245..42d61dd 100644
>> --- a/drivers/bcma/Makefile
>> +++ b/drivers/bcma/Makefile
>> @@ -2,6 +2,7 @@ bcma-y                                  += main.o scan.o core.o
>>  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
>> diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
>> new file mode 100644
>> index 0000000..a6fe724
>> --- /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);
>> +}
>> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
>> index e6c308c..2ca5eeb 100644
>> --- a/drivers/bcma/main.c
>> +++ b/drivers/bcma/main.c
>> @@ -92,6 +92,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
>>                        break;
>>                case BCMA_HOSTTYPE_NONE:
>>                case BCMA_HOSTTYPE_SDIO:
>> +               case BCMA_HOSTTYPE_SOC:
>>                        break;
>>                }
>>
>> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
>> index bf9f806..202edc8 100644
>> --- a/drivers/bcma/scan.c
>> +++ b/drivers/bcma/scan.c
>> @@ -337,6 +337,14 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
>>                        }
>>                }
>>        }
>> +       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;
> 
> Shouldn't you unmap core->io_addr if remapping io_wrap fails?

Ok I will add iounmap() on the error path and when the core is freed.
> 
>> +       }
>>        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;
> 
> Documentation/CodingStyle says use braces in both branches if one needs them.
Will fix this.
> 
>> +
>>        eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
>>
>>        bcma_scan_switch_core(bus, erombase);
>> @@ -417,7 +431,13 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus,
>>        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;
> 
> Ditto.
> 
>> +
>>        eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
>>
>>        bcma_scan_switch_core(bus, erombase);
>> diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
>> index 6bd7b7f..73fda1c 100644
>> --- a/include/linux/bcma/bcma.h
>> +++ b/include/linux/bcma/bcma.h
>> @@ -16,6 +16,7 @@ enum bcma_hosttype {
>>        BCMA_HOSTTYPE_NONE,
>>        BCMA_HOSTTYPE_PCI,
>>        BCMA_HOSTTYPE_SDIO,
>> +       BCMA_HOSTTYPE_SOC,
>>  };
>>
>>  struct bcma_chipinfo {
>> @@ -124,6 +125,9 @@ struct bcma_device {
>>        u32 addr;
>>        u32 wrap;
>>
>> +       void __iomem *io_addr;
>> +       void __iomem *io_wrap;
>> +
>>        void *drvdata;
>>        struct list_head list;
>>  };
>> diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h
>> new file mode 100644
>> index 0000000..4203c55
>> --- /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_ */
>> --
>> 1.7.4.1

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-07-14 20:37 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-09 11:05 [PATCH 00/11] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
2011-07-09 11:05 ` [PATCH 01/11] bcma: move parsing of EEPROM into own function Hauke Mehrtens
2011-07-09 11:05 ` [PATCH 02/11] bcma: move initializing of struct bcma_bus to " Hauke Mehrtens
2011-07-09 11:05 ` [PATCH 03/11] bcma: add functions to scan cores needed on SoCs Hauke Mehrtens
2011-07-09 11:05 ` [PATCH 04/11] bcma: add SOC bus Hauke Mehrtens
2011-07-13 19:36   ` Jonas Gorski
2011-07-14 20:37     ` Hauke Mehrtens
2011-07-09 11:05 ` [PATCH 05/11] bcma: add mips driver Hauke Mehrtens
2011-07-13 20:39   ` Jonas Gorski
2011-07-09 11:05 ` [PATCH 06/11] bcma: add serial console support Hauke Mehrtens
2011-07-13 20:56   ` Jonas Gorski
2011-07-09 11:05 ` [PATCH 07/11] bcma: get CPU clock Hauke Mehrtens
2011-07-09 11:06 ` [PATCH 08/11] bcm47xx: prepare to support different buses Hauke Mehrtens
2011-07-09 11:06 ` [PATCH 09/11] bcm47xx: make it possible to build bcm47xx without ssb Hauke Mehrtens
2011-07-09 11:06 ` [PATCH 10/11] bcm47xx: add support for bcma bus Hauke Mehrtens
2011-07-13 19:52   ` Jonas Gorski
2011-07-13 20:05     ` Hauke Mehrtens
2011-07-09 11:06 ` [PATCH 11/11] bcm47xx: fix irq assignment for new SoCs Hauke Mehrtens
2011-07-13 18:33 ` [PATCH 00/11] bcma: add support for embedded devices like bcm4716 John W. Linville

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).