* [RFC][PATCH 01/10] bcma: Use array to store cores.
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 9:42 ` Rafał Miłecki
2011-06-05 22:07 ` [RFC][PATCH 02/10] bcma: Make it possible to run bcma_register_cores() later Hauke Mehrtens
` (9 subsequent siblings)
10 siblings, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
When using bcma on a embedded device it is initialized very early at
boot. We have to do so as the cpu and interrupt management and all
other devices are attached to this bus and it has to be initialized so
early. In that stage we can not allocate memory or sleep, just use the
memory on the stack and in the text segment as the kernel is not
initialized far enough. This patch removed the kzallocs from the scan
code. Some earlier version of the bcma implementation and the normal
ssb implementation are doing it like this.
The __bcma_dev_wrapper struct is used as the container for the device
struct as bcma_device will be too big if it includes struct device.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/main.c | 86 ++++++++++++++++++++++++++++----------------
drivers/bcma/scan.c | 58 +++++++++++-------------------
include/linux/bcma/bcma.h | 16 ++++++--
3 files changed, 89 insertions(+), 71 deletions(-)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index a2f6b18..b0e7f5e 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -17,23 +17,27 @@ static int bcma_device_remove(struct device *dev);
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
- return sprintf(buf, "0x%03X\n", core->id.manuf);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ return sprintf(buf, "0x%03X\n", wrapper->core->id.manuf);
}
static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
- return sprintf(buf, "0x%03X\n", core->id.id);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ return sprintf(buf, "0x%03X\n", wrapper->core->id.id);
}
static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
- return sprintf(buf, "0x%02X\n", core->id.rev);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ return sprintf(buf, "0x%02X\n", wrapper->core->id.rev);
}
static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
- return sprintf(buf, "0x%X\n", core->id.class);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ return sprintf(buf, "0x%X\n", wrapper->core->id.class);
}
static struct device_attribute bcma_device_attrs[] = {
__ATTR_RO(manuf),
@@ -53,27 +57,30 @@ static struct bus_type bcma_bus_type = {
static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
{
- struct bcma_device *core;
-
- list_for_each_entry(core, &bus->cores, list) {
- if (core->id.id == coreid)
- return core;
+ u8 i;
+ for (i = 0; i < bus->nr_cores; i++) {
+ if (bus->cores[i].id.id == coreid)
+ return &bus->cores[i];
}
return NULL;
}
static void bcma_release_core_dev(struct device *dev)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
- kfree(core);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ kfree(wrapper);
}
static int bcma_register_cores(struct bcma_bus *bus)
{
struct bcma_device *core;
- int err, dev_id = 0;
+ struct __bcma_dev_wrapper *wrapper;
+ int i, err, dev_id = 0;
+
+ for (i = 0; i < bus->nr_cores; i++) {
+ core = &(bus->cores[i]);
- list_for_each_entry(core, &bus->cores, list) {
/* We support that cores ourself */
switch (core->id.id) {
case BCMA_CORE_CHIPCOMMON:
@@ -82,28 +89,37 @@ static int bcma_register_cores(struct bcma_bus *bus)
continue;
}
- core->dev.release = bcma_release_core_dev;
- core->dev.bus = &bcma_bus_type;
- dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
+ wrapper = kzalloc(sizeof(*wrapper), GFP_KERNEL);
+ if (!wrapper) {
+ pr_err("Could not allocate wrapper for core 0x%03X\n",
+ core->id.id);
+ continue;
+ }
+
+ wrapper->core = core;
+ wrapper->dev.release = bcma_release_core_dev;
+ wrapper->dev.bus = &bcma_bus_type;
+ dev_set_name(&wrapper->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
- core->dev.parent = &bus->host_pci->dev;
- core->dma_dev = &bus->host_pci->dev;
- core->irq = bus->host_pci->irq;
+ wrapper->dev.parent = &bus->host_pci->dev;
+ wrapper->core->dma_dev = &bus->host_pci->dev;
+ wrapper->core->irq = bus->host_pci->irq;
break;
case BCMA_HOSTTYPE_NONE:
case BCMA_HOSTTYPE_SDIO:
break;
}
- err = device_register(&core->dev);
+ err = device_register(&wrapper->dev);
if (err) {
pr_err("Could not register dev for core 0x%03X\n",
core->id.id);
+ kfree(wrapper);
continue;
}
- core->dev_registered = true;
+ core->dev = &wrapper->dev;
dev_id++;
}
@@ -113,10 +129,12 @@ static int bcma_register_cores(struct bcma_bus *bus)
static void bcma_unregister_cores(struct bcma_bus *bus)
{
struct bcma_device *core;
+ int i;
- list_for_each_entry(core, &bus->cores, list) {
- if (core->dev_registered)
- device_unregister(&core->dev);
+ for (i = 0; i < bus->nr_cores; i++) {
+ core = &(bus->cores[i]);
+ if (core->dev)
+ device_unregister(core->dev);
}
}
@@ -179,7 +197,9 @@ EXPORT_SYMBOL_GPL(bcma_driver_unregister);
static int bcma_bus_match(struct device *dev, struct device_driver *drv)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ struct bcma_device *core = wrapper->core;
struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
const struct bcma_device_id *cid = &core->id;
const struct bcma_device_id *did;
@@ -196,7 +216,9 @@ static int bcma_bus_match(struct device *dev, struct device_driver *drv)
static int bcma_device_probe(struct device *dev)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ struct bcma_device *core = wrapper->core;
struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
drv);
int err = 0;
@@ -209,7 +231,9 @@ static int bcma_device_probe(struct device *dev)
static int bcma_device_remove(struct device *dev)
{
- struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+ struct __bcma_dev_wrapper *wrapper = container_of(dev,
+ struct __bcma_dev_wrapper, dev);
+ struct bcma_device *core = wrapper->core;
struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
drv);
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 40d7dcc..70b39f7 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -211,9 +211,6 @@ int bcma_bus_scan(struct bcma_bus *bus)
s32 tmp;
u8 i, j;
- int err;
-
- INIT_LIST_HEAD(&bus->cores);
bus->nr_cores = 0;
bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
@@ -230,11 +227,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
bcma_scan_switch_core(bus, erombase);
while (eromptr < eromend) {
- struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
- if (!core)
- return -ENOMEM;
- INIT_LIST_HEAD(&core->list);
- core->bus = bus;
+ struct bcma_device core = { };
+ core.bus = bus;
/* get CIs */
cia = bcma_erom_get_ci(bus, &eromptr);
@@ -242,27 +236,24 @@ int bcma_bus_scan(struct bcma_bus *bus)
bcma_erom_push_ent(&eromptr);
if (bcma_erom_is_end(bus, &eromptr))
break;
- err= -EILSEQ;
- goto out;
+ return -EILSEQ;
}
cib = bcma_erom_get_ci(bus, &eromptr);
- if (cib < 0) {
- err= -EILSEQ;
- goto out;
- }
+ 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;
+ 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;
+ core.id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
- if (((core->id.manuf == BCMA_MANUF_ARM) &&
- (core->id.id == 0xFFF)) ||
+ if (((core.id.manuf == BCMA_MANUF_ARM) &&
+ (core.id.id == 0xFFF)) ||
(ports[1] == 0)) {
bcma_erom_skip_component(bus, &eromptr);
continue;
@@ -285,10 +276,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
/* 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;
- }
+ if (mst_port_d < 0)
+ return -EILSEQ;
}
/* get & parse slave ports */
@@ -303,7 +292,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
break;
} else {
if (i == 0 && j == 0)
- core->addr = tmp;
+ core.addr = tmp;
}
}
}
@@ -320,7 +309,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
break;
} else {
if (i == 0 && j == 0)
- core->wrap = tmp;
+ core.wrap = tmp;
}
}
}
@@ -338,22 +327,19 @@ int bcma_bus_scan(struct bcma_bus *bus)
break;
} else {
if (wrappers[0] == 0 && !i && !j)
- core->wrap = tmp;
+ core.wrap = tmp;
}
}
}
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->id.manuf, core->id.id, core->id.rev,
- core->id.class);
-
- core->core_index = bus->nr_cores++;
- list_add(&core->list, &bus->cores);
- continue;
-out:
- return err;
+ bus->nr_cores, bcma_device_name(&core.id),
+ core.id.manuf, core.id.id, core.id.rev,
+ core.id.class);
+
+ core.core_index = bus->nr_cores;
+ bus->cores[bus->nr_cores++] = core;
}
return 0;
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 27a27a7..3dc5302 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -118,14 +118,23 @@ struct bcma_host_ops {
#define BCMA_MAX_NR_CORES 16
+/* 1) It is not allowed to put struct device statically in bcma_device
+ * 2) We can not just use pointer to struct device because we use container_of
+ * 3) We do not have pointer to struct bcma_device in struct device
+ * Solution: use such a dummy wrapper
+ */
+struct __bcma_dev_wrapper {
+ struct device dev;
+ struct bcma_device *core;
+};
+
struct bcma_device {
struct bcma_bus *bus;
struct bcma_device_id id;
- struct device dev;
+ struct device *dev;
struct device *dma_dev;
unsigned int irq;
- bool dev_registered;
u8 core_index;
@@ -133,7 +142,6 @@ struct bcma_device {
u32 wrap;
void *drvdata;
- struct list_head list;
};
static inline void *bcma_get_drvdata(struct bcma_device *core)
@@ -182,7 +190,7 @@ struct bcma_bus {
struct bcma_chipinfo chipinfo;
struct bcma_device *mapped_core;
- struct list_head cores;
+ struct bcma_device cores[BCMA_MAX_NR_CORES];
u8 nr_cores;
struct bcma_drv_cc drv_cc;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 01/10] bcma: Use array to store cores.
2011-06-05 22:07 ` [RFC][PATCH 01/10] bcma: Use array to store cores Hauke Mehrtens
@ 2011-06-06 9:42 ` Rafał Miłecki
0 siblings, 0 replies; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 9:42 UTC (permalink / raw)
To: Hauke Mehrtens, Arnd Bergmann, Greg KH
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
Greg, Arnd: could you take a look at this patch, please?
With proposed patch we are going back to this ugly array and wrappers hacks.
I was really happy with our final solution, but it seems it's not
doable for embedded systems...? Is there something better we can do
about this?
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> When using bcma on a embedded device it is initialized very early at
> boot. We have to do so as the cpu and interrupt management and all
> other devices are attached to this bus and it has to be initialized so
> early. In that stage we can not allocate memory or sleep, just use the
> memory on the stack and in the text segment as the kernel is not
> initialized far enough. This patch removed the kzallocs from the scan
> code. Some earlier version of the bcma implementation and the normal
> ssb implementation are doing it like this.
> The __bcma_dev_wrapper struct is used as the container for the device
> struct as bcma_device will be too big if it includes struct device.
>
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
> ?drivers/bcma/main.c ? ? ? | ? 86 ++++++++++++++++++++++++++++----------------
> ?drivers/bcma/scan.c ? ? ? | ? 58 +++++++++++-------------------
> ?include/linux/bcma/bcma.h | ? 16 ++++++--
> ?3 files changed, 89 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index a2f6b18..b0e7f5e 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -17,23 +17,27 @@ static int bcma_device_remove(struct device *dev);
>
> ?static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> - ? ? ? return sprintf(buf, "0x%03X\n", core->id.manuf);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? return sprintf(buf, "0x%03X\n", wrapper->core->id.manuf);
> ?}
> ?static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> - ? ? ? return sprintf(buf, "0x%03X\n", core->id.id);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? return sprintf(buf, "0x%03X\n", wrapper->core->id.id);
> ?}
> ?static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> - ? ? ? return sprintf(buf, "0x%02X\n", core->id.rev);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? return sprintf(buf, "0x%02X\n", wrapper->core->id.rev);
> ?}
> ?static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> - ? ? ? return sprintf(buf, "0x%X\n", core->id.class);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? return sprintf(buf, "0x%X\n", wrapper->core->id.class);
> ?}
> ?static struct device_attribute bcma_device_attrs[] = {
> ? ? ? ?__ATTR_RO(manuf),
> @@ -53,27 +57,30 @@ static struct bus_type bcma_bus_type = {
>
> ?static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
> ?{
> - ? ? ? struct bcma_device *core;
> -
> - ? ? ? list_for_each_entry(core, &bus->cores, list) {
> - ? ? ? ? ? ? ? if (core->id.id == coreid)
> - ? ? ? ? ? ? ? ? ? ? ? return core;
> + ? ? ? u8 i;
> + ? ? ? for (i = 0; i < bus->nr_cores; i++) {
> + ? ? ? ? ? ? ? if (bus->cores[i].id.id == coreid)
> + ? ? ? ? ? ? ? ? ? ? ? return &bus->cores[i];
> ? ? ? ?}
> ? ? ? ?return NULL;
> ?}
>
> ?static void bcma_release_core_dev(struct device *dev)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> - ? ? ? kfree(core);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? kfree(wrapper);
> ?}
>
> ?static int bcma_register_cores(struct bcma_bus *bus)
> ?{
> ? ? ? ?struct bcma_device *core;
> - ? ? ? int err, dev_id = 0;
> + ? ? ? struct __bcma_dev_wrapper *wrapper;
> + ? ? ? int i, err, dev_id = 0;
> +
> + ? ? ? for (i = 0; i < bus->nr_cores; i++) {
> + ? ? ? ? ? ? ? core = &(bus->cores[i]);
>
> - ? ? ? list_for_each_entry(core, &bus->cores, list) {
> ? ? ? ? ? ? ? ?/* We support that cores ourself */
> ? ? ? ? ? ? ? ?switch (core->id.id) {
> ? ? ? ? ? ? ? ?case BCMA_CORE_CHIPCOMMON:
> @@ -82,28 +89,37 @@ static int bcma_register_cores(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ?continue;
> ? ? ? ? ? ? ? ?}
>
> - ? ? ? ? ? ? ? core->dev.release = bcma_release_core_dev;
> - ? ? ? ? ? ? ? core->dev.bus = &bcma_bus_type;
> - ? ? ? ? ? ? ? dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
> + ? ? ? ? ? ? ? wrapper = kzalloc(sizeof(*wrapper), GFP_KERNEL);
> + ? ? ? ? ? ? ? if (!wrapper) {
> + ? ? ? ? ? ? ? ? ? ? ? pr_err("Could not allocate wrapper for core 0x%03X\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?core->id.id);
> + ? ? ? ? ? ? ? ? ? ? ? continue;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? wrapper->core = core;
> + ? ? ? ? ? ? ? wrapper->dev.release = bcma_release_core_dev;
> + ? ? ? ? ? ? ? wrapper->dev.bus = &bcma_bus_type;
> + ? ? ? ? ? ? ? dev_set_name(&wrapper->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
>
> ? ? ? ? ? ? ? ?switch (bus->hosttype) {
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_PCI:
> - ? ? ? ? ? ? ? ? ? ? ? core->dev.parent = &bus->host_pci->dev;
> - ? ? ? ? ? ? ? ? ? ? ? core->dma_dev = &bus->host_pci->dev;
> - ? ? ? ? ? ? ? ? ? ? ? core->irq = bus->host_pci->irq;
> + ? ? ? ? ? ? ? ? ? ? ? wrapper->dev.parent = &bus->host_pci->dev;
> + ? ? ? ? ? ? ? ? ? ? ? wrapper->core->dma_dev = &bus->host_pci->dev;
> + ? ? ? ? ? ? ? ? ? ? ? wrapper->core->irq = bus->host_pci->irq;
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_NONE:
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_SDIO:
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?}
>
> - ? ? ? ? ? ? ? err = device_register(&core->dev);
> + ? ? ? ? ? ? ? err = device_register(&wrapper->dev);
> ? ? ? ? ? ? ? ?if (err) {
> ? ? ? ? ? ? ? ? ? ? ? ?pr_err("Could not register dev for core 0x%03X\n",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core->id.id);
> + ? ? ? ? ? ? ? ? ? ? ? kfree(wrapper);
> ? ? ? ? ? ? ? ? ? ? ? ?continue;
> ? ? ? ? ? ? ? ?}
> - ? ? ? ? ? ? ? core->dev_registered = true;
> + ? ? ? ? ? ? ? core->dev = &wrapper->dev;
> ? ? ? ? ? ? ? ?dev_id++;
> ? ? ? ?}
>
> @@ -113,10 +129,12 @@ static int bcma_register_cores(struct bcma_bus *bus)
> ?static void bcma_unregister_cores(struct bcma_bus *bus)
> ?{
> ? ? ? ?struct bcma_device *core;
> + ? ? ? int i;
>
> - ? ? ? list_for_each_entry(core, &bus->cores, list) {
> - ? ? ? ? ? ? ? if (core->dev_registered)
> - ? ? ? ? ? ? ? ? ? ? ? device_unregister(&core->dev);
> + ? ? ? for (i = 0; i < bus->nr_cores; i++) {
> + ? ? ? ? ? ? ? core = &(bus->cores[i]);
> + ? ? ? ? ? ? ? if (core->dev)
> + ? ? ? ? ? ? ? ? ? ? ? device_unregister(core->dev);
> ? ? ? ?}
> ?}
>
> @@ -179,7 +197,9 @@ EXPORT_SYMBOL_GPL(bcma_driver_unregister);
>
> ?static int bcma_bus_match(struct device *dev, struct device_driver *drv)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? struct bcma_device *core = wrapper->core;
> ? ? ? ?struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
> ? ? ? ?const struct bcma_device_id *cid = &core->id;
> ? ? ? ?const struct bcma_device_id *did;
> @@ -196,7 +216,9 @@ static int bcma_bus_match(struct device *dev, struct device_driver *drv)
>
> ?static int bcma_device_probe(struct device *dev)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? struct bcma_device *core = wrapper->core;
> ? ? ? ?struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? drv);
> ? ? ? ?int err = 0;
> @@ -209,7 +231,9 @@ static int bcma_device_probe(struct device *dev)
>
> ?static int bcma_device_remove(struct device *dev)
> ?{
> - ? ? ? struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> + ? ? ? struct __bcma_dev_wrapper *wrapper = container_of(dev,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct __bcma_dev_wrapper, dev);
> + ? ? ? struct bcma_device *core = wrapper->core;
> ? ? ? ?struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? drv);
>
> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
> index 40d7dcc..70b39f7 100644
> --- a/drivers/bcma/scan.c
> +++ b/drivers/bcma/scan.c
> @@ -211,9 +211,6 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ?s32 tmp;
> ? ? ? ?u8 i, j;
>
> - ? ? ? int err;
> -
> - ? ? ? INIT_LIST_HEAD(&bus->cores);
> ? ? ? ?bus->nr_cores = 0;
>
> ? ? ? ?bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
> @@ -230,11 +227,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ?bcma_scan_switch_core(bus, erombase);
>
> ? ? ? ?while (eromptr < eromend) {
> - ? ? ? ? ? ? ? struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
> - ? ? ? ? ? ? ? if (!core)
> - ? ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
> - ? ? ? ? ? ? ? INIT_LIST_HEAD(&core->list);
> - ? ? ? ? ? ? ? core->bus = bus;
> + ? ? ? ? ? ? ? struct bcma_device core = { };
> + ? ? ? ? ? ? ? core.bus = bus;
>
> ? ? ? ? ? ? ? ?/* get CIs */
> ? ? ? ? ? ? ? ?cia = bcma_erom_get_ci(bus, &eromptr);
> @@ -242,27 +236,24 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ?bcma_erom_push_ent(&eromptr);
> ? ? ? ? ? ? ? ? ? ? ? ?if (bcma_erom_is_end(bus, &eromptr))
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
> - ? ? ? ? ? ? ? ? ? ? ? err= -EILSEQ;
> - ? ? ? ? ? ? ? ? ? ? ? goto out;
> + ? ? ? ? ? ? ? ? ? ? ? return -EILSEQ;
> ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?cib = bcma_erom_get_ci(bus, &eromptr);
> - ? ? ? ? ? ? ? if (cib < 0) {
> - ? ? ? ? ? ? ? ? ? ? ? err= -EILSEQ;
> - ? ? ? ? ? ? ? ? ? ? ? goto out;
> - ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? 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;
> + ? ? ? ? ? ? ? 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;
> + ? ? ? ? ? ? ? core.id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
>
> - ? ? ? ? ? ? ? if (((core->id.manuf == BCMA_MANUF_ARM) &&
> - ? ? ? ? ? ? ? ? ? ?(core->id.id == 0xFFF)) ||
> + ? ? ? ? ? ? ? if (((core.id.manuf == BCMA_MANUF_ARM) &&
> + ? ? ? ? ? ? ? ? ? ?(core.id.id == 0xFFF)) ||
> ? ? ? ? ? ? ? ? ? ?(ports[1] == 0)) {
> ? ? ? ? ? ? ? ? ? ? ? ?bcma_erom_skip_component(bus, &eromptr);
> ? ? ? ? ? ? ? ? ? ? ? ?continue;
> @@ -285,10 +276,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ?/* 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;
> - ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? ? if (mst_port_d < 0)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return -EILSEQ;
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?/* get & parse slave ports */
> @@ -303,7 +292,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else {
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (i == 0 && j == 0)
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core->addr = tmp;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core.addr = tmp;
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?}
> @@ -320,7 +309,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else {
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (i == 0 && j == 0)
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core->wrap = tmp;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core.wrap = tmp;
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?}
> @@ -338,22 +327,19 @@ int bcma_bus_scan(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else {
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (wrappers[0] == 0 && !i && !j)
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core->wrap = tmp;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? core.wrap = tmp;
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ? ? ? ? ?}
> ? ? ? ? ? ? ? ?}
>
> ? ? ? ? ? ? ? ?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->id.manuf, core->id.id, core->id.rev,
> - ? ? ? ? ? ? ? ? ? ? ? core->id.class);
> -
> - ? ? ? ? ? ? ? core->core_index = bus->nr_cores++;
> - ? ? ? ? ? ? ? list_add(&core->list, &bus->cores);
> - ? ? ? ? ? ? ? continue;
> -out:
> - ? ? ? ? ? ? ? return err;
> + ? ? ? ? ? ? ? ? ? ? ? bus->nr_cores, bcma_device_name(&core.id),
> + ? ? ? ? ? ? ? ? ? ? ? core.id.manuf, core.id.id, core.id.rev,
> + ? ? ? ? ? ? ? ? ? ? ? core.id.class);
> +
> + ? ? ? ? ? ? ? core.core_index = bus->nr_cores;
> + ? ? ? ? ? ? ? bus->cores[bus->nr_cores++] = core;
> ? ? ? ?}
>
> ? ? ? ?return 0;
> diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
> index 27a27a7..3dc5302 100644
> --- a/include/linux/bcma/bcma.h
> +++ b/include/linux/bcma/bcma.h
> @@ -118,14 +118,23 @@ struct bcma_host_ops {
>
> ?#define BCMA_MAX_NR_CORES ? ? ? ? ? ? ?16
>
> +/* 1) It is not allowed to put struct device statically in bcma_device
> + * 2) We can not just use pointer to struct device because we use container_of
> + * 3) We do not have pointer to struct bcma_device in struct device
> + * Solution: use such a dummy wrapper
> + */
> +struct __bcma_dev_wrapper {
> + ? ? ? struct device dev;
> + ? ? ? struct bcma_device *core;
> +};
> +
> ?struct bcma_device {
> ? ? ? ?struct bcma_bus *bus;
> ? ? ? ?struct bcma_device_id id;
>
> - ? ? ? struct device dev;
> + ? ? ? struct device *dev;
> ? ? ? ?struct device *dma_dev;
> ? ? ? ?unsigned int irq;
> - ? ? ? bool dev_registered;
>
> ? ? ? ?u8 core_index;
>
> @@ -133,7 +142,6 @@ struct bcma_device {
> ? ? ? ?u32 wrap;
>
> ? ? ? ?void *drvdata;
> - ? ? ? struct list_head list;
> ?};
>
> ?static inline void *bcma_get_drvdata(struct bcma_device *core)
> @@ -182,7 +190,7 @@ struct bcma_bus {
> ? ? ? ?struct bcma_chipinfo chipinfo;
>
> ? ? ? ?struct bcma_device *mapped_core;
> - ? ? ? struct list_head cores;
> + ? ? ? struct bcma_device cores[BCMA_MAX_NR_CORES];
> ? ? ? ?u8 nr_cores;
>
> ? ? ? ?struct bcma_drv_cc drv_cc;
> --
> 1.7.4.1
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 02/10] bcma: Make it possible to run bcma_register_cores() later
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
2011-06-05 22:07 ` [RFC][PATCH 01/10] bcma: Use array to store cores Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-05 22:07 ` [RFC][PATCH 03/10] bcma: add embedded bus Hauke Mehrtens
` (8 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
On embedded device we can not allocate memory with kalloc or sleep for
some time, when bcma is initialized, because this is done early in the
boot process. This patch makes it possible to do the
bcma_register_cores() sometime later and not directly after searching
for the cores. The initialization of the PCI(e) core is also done later
as it uses udelay(), which will not work so early. The buses are placed
into a list and bcma_register_cores() will be run when the bcma module
is initialized. When using bcma on a PCI-Bus in a normal PC
bcma_register_cores() is triggered directly after bcma_bus_register().
This patch is based on ssb code.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/main.c | 65 ++++++++++++++++++++++++++++++++++++++++++---
include/linux/bcma/bcma.h | 3 ++
2 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index b0e7f5e..1afa107 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -15,6 +15,16 @@ static int bcma_bus_match(struct device *dev, struct device_driver *drv);
static int bcma_device_probe(struct device *dev);
static int bcma_device_remove(struct device *dev);
+/* Temporary list of yet-to-be-attached buses */
+static LIST_HEAD(attach_queue);
+/* There are differences in the codeflow, if the bus is
+ * initialized from early boot, as various needed services
+ * are not available early. This is a mechanism to delay
+ * these initializations to after early boot has finished.
+ * It's also used to avoid mutex locking, as that's not
+ * available and needed early. */
+static bool bcma_is_early_boot = 1;
+
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct __bcma_dev_wrapper *wrapper = container_of(dev,
@@ -126,6 +136,36 @@ static int bcma_register_cores(struct bcma_bus *bus)
return 0;
}
+static int bcma_attach_queued_buses(void)
+{
+ struct bcma_bus *bus, *n;
+ int err = 0;
+ int drop_them_all = 0;
+
+ list_for_each_entry_safe(bus, n, &attach_queue, attach_list) {
+ if (drop_them_all) {
+ list_del(&bus->attach_list);
+ continue;
+ }
+ /* Can't init the PCIcore in bcma_bus_register(), as that
+ * is too early in boot for embedded systems
+ * (no udelay() available). So do it here in attach stage.
+ */
+ if (bus->drv_pci.core)
+ bcma_core_pci_init(&bus->drv_pci);
+
+ err = bcma_register_cores(bus);
+ if (err) {
+ drop_them_all = 1;
+ list_del(&bus->attach_list);
+ continue;
+ }
+ list_del(&bus->attach_list);
+ }
+
+ return err;
+}
+
static void bcma_unregister_cores(struct bcma_bus *bus)
{
struct bcma_device *core;
@@ -157,15 +197,20 @@ int bcma_bus_register(struct bcma_bus *bus)
bcma_core_chipcommon_init(&bus->drv_cc);
}
- /* Init PCIE core */
+ /* Find PCIE core */
core = bcma_find_core(bus, BCMA_CORE_PCIE);
if (core) {
+ /* will be initilized in bcma_attach_queued_buses() */
bus->drv_pci.core = core;
- bcma_core_pci_init(&bus->drv_pci);
}
- /* Register found cores */
- bcma_register_cores(bus);
+ /* Queue it for attach.
+ * See the comment at the bcma_is_early_boot definition. */
+ list_add_tail(&bus->attach_list, &attach_queue);
+ if (!bcma_is_early_boot) {
+ /* This is not early boot, so we must attach the bus now */
+ bcma_attach_queued_buses();
+ }
pr_info("Bus registered\n");
@@ -247,10 +292,22 @@ static int __init bcma_modinit(void)
{
int err;
+ /* See the comment at the bcma_is_early_boot definition */
+ bcma_is_early_boot = 0;
+
err = bus_register(&bcma_bus_type);
if (err)
return err;
+ /* Maybe we already registered some buses at early boot.
+ * Check for this and attach them.
+ */
+ err = bcma_attach_queued_buses();
+ if (err) {
+ pr_err("Attaching core registered in early boot failed\n");
+ err = 0;
+ }
+
#ifdef CONFIG_BCMA_HOST_PCI
err = bcma_host_pci_init();
if (err) {
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 3dc5302..8b6feca 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -195,6 +195,9 @@ struct bcma_bus {
struct bcma_drv_cc drv_cc;
struct bcma_drv_pci drv_pci;
+
+ /* Internal-only stuff follows. Do not touch. */
+ struct list_head attach_list;
};
extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 03/10] bcma: add embedded bus
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
2011-06-05 22:07 ` [RFC][PATCH 01/10] bcma: Use array to store cores Hauke Mehrtens
2011-06-05 22:07 ` [RFC][PATCH 02/10] bcma: Make it possible to run bcma_register_cores() later Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 10:22 ` Rafał Miłecki
[not found] ` <BANLkTi=atiB_=_N3xSJBAjRGXjTV8a97CA@mail.gmail.com>
2011-06-05 22:07 ` [RFC][PATCH 04/10] bcma: add mips driver Hauke Mehrtens
` (7 subsequent siblings)
10 siblings, 2 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
This patch adds support for using bcma on an embedded bus. An embedded
system like the bcm4716 could register this bus and it searches for the
bcma cores then.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/Kconfig | 5 ++
drivers/bcma/Makefile | 1 +
drivers/bcma/host_embedded.c | 93 ++++++++++++++++++++++++++++++++++++
drivers/bcma/main.c | 1 +
drivers/bcma/scan.c | 29 ++++++++++-
include/linux/bcma/bcma.h | 3 +
include/linux/bcma/bcma_embedded.h | 8 +++
7 files changed, 138 insertions(+), 2 deletions(-)
create mode 100644 drivers/bcma/host_embedded.c
create mode 100644 include/linux/bcma/bcma_embedded.h
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 83e9adf..0390e32 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -27,6 +27,11 @@ config BCMA_HOST_PCI
bool "Support for BCMA on PCI-host bus"
depends on BCMA_HOST_PCI_POSSIBLE
+config BCMA_HOST_EMBEDDED
+ 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..e509b1b 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_EMBEDDED) += host_embedded.o
obj-$(CONFIG_BCMA) += bcma.o
ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
diff --git a/drivers/bcma/host_embedded.c b/drivers/bcma/host_embedded.c
new file mode 100644
index 0000000..6942440
--- /dev/null
+++ b/drivers/bcma/host_embedded.c
@@ -0,0 +1,93 @@
+/*
+ * Broadcom specific AMBA
+ * PCI Host
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include "scan.h"
+#include <linux/bcma/bcma.h>
+
+static u8 bcma_host_bcma_read8(struct bcma_device *core, u16 offset)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ return readb(core->bus->mmio + offset);
+}
+
+static u16 bcma_host_bcma_read16(struct bcma_device *core, u16 offset)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ return readw(core->bus->mmio + offset);
+}
+
+static u32 bcma_host_bcma_read32(struct bcma_device *core, u16 offset)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ return readl(core->bus->mmio + offset);
+}
+
+static void bcma_host_bcma_write8(struct bcma_device *core, u16 offset,
+ u8 value)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ writeb(value, core->bus->mmio + offset);
+}
+
+static void bcma_host_bcma_write16(struct bcma_device *core, u16 offset,
+ u16 value)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ writew(value, core->bus->mmio + offset);
+}
+
+static void bcma_host_bcma_write32(struct bcma_device *core, u16 offset,
+ u32 value)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ writel(value, core->bus->mmio + offset);
+}
+
+static u32 bcma_host_bcma_aread32(struct bcma_device *core, u16 offset)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ return readl(core->bus->host_embedded + offset);
+}
+
+static void bcma_host_bcma_awrite32(struct bcma_device *core, u16 offset,
+ u32 value)
+{
+ offset += core->core_index * BCMA_CORE_SIZE;
+ writel(value, core->bus->host_embedded + offset);
+}
+
+const struct bcma_host_ops bcma_host_bcma_ops = {
+ .read8 = bcma_host_bcma_read8,
+ .read16 = bcma_host_bcma_read16,
+ .read32 = bcma_host_bcma_read32,
+ .write8 = bcma_host_bcma_write8,
+ .write16 = bcma_host_bcma_write16,
+ .write32 = bcma_host_bcma_write32,
+ .aread32 = bcma_host_bcma_aread32,
+ .awrite32 = bcma_host_bcma_awrite32,
+};
+
+int bcma_host_bcma_register(struct bcma_bus *bus)
+{
+ u32 __iomem *mmio;
+
+ /* iomap only first core. We have to read some register on this core
+ * to get the number of cores. This is sone in bcma_scan()
+ */
+ mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
+ if (!mmio)
+ return -ENOMEM;
+ bus->mmio = mmio;
+
+ /* Host specific */
+ bus->hosttype = BCMA_HOSTTYPE_EMBEDDED;
+ bus->ops = &bcma_host_bcma_ops;
+
+ /* Register */
+ return bcma_bus_register(bus);
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 1afa107..c5bcb5f 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -119,6 +119,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
break;
case BCMA_HOSTTYPE_NONE:
case BCMA_HOSTTYPE_SDIO:
+ case BCMA_HOSTTYPE_EMBEDDED:
break;
}
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 70b39f7..9229615 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -203,7 +203,7 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
int bcma_bus_scan(struct bcma_bus *bus)
{
u32 erombase;
- u32 __iomem *eromptr, *eromend;
+ u32 __iomem *eromptr, *eromend, *mmio;
s32 cia, cib;
u8 ports[2], wrappers[2];
@@ -219,9 +219,34 @@ 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;
+ bus->nr_cores = (tmp & BCMA_CC_ID_NRCORES) >> BCMA_CC_ID_NRCORES_SHIFT;
+
+ /* If we are an embedded device we now know the number of avaliable
+ * core and ioremap the correct space.
+ */
+ if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
+ iounmap(bus->mmio);
+ mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * bus->nr_cores);
+ if (!mmio)
+ return -ENOMEM;
+ bus->mmio = mmio;
+
+ mmio = ioremap(BCMA_WRAP_BASE, BCMA_CORE_SIZE * bus->nr_cores);
+ if (!mmio)
+ return -ENOMEM;
+ bus->host_embedded = mmio;
+ }
+ /* reset it to 0 as we use it for counting */
+ bus->nr_cores = 0;
erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
- eromptr = bus->mmio;
+ if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
+ 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 8b6feca..192c4ae 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_EMBEDDED,
};
struct bcma_chipinfo {
@@ -185,6 +186,8 @@ struct bcma_bus {
struct pci_dev *host_pci;
/* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
struct sdio_func *host_sdio;
+ /* Pointer to the embedded iomem (only for BCMA_HOSTTYPE_EMBEDDED) */
+ void __iomem *host_embedded;
};
struct bcma_chipinfo chipinfo;
diff --git a/include/linux/bcma/bcma_embedded.h b/include/linux/bcma/bcma_embedded.h
new file mode 100644
index 0000000..0faf46d
--- /dev/null
+++ b/include/linux/bcma/bcma_embedded.h
@@ -0,0 +1,8 @@
+#ifndef LINUX_BCMA_EMBEDDED_H_
+#define LINUX_BCMA_EMBEDDED_H_
+
+#include <linux/bcma/bcma.h>
+
+extern int bcma_host_bcma_register(struct bcma_bus *bus);
+
+#endif /* LINUX_BCMA_EMBEDDED_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 03/10] bcma: add embedded bus
2011-06-05 22:07 ` [RFC][PATCH 03/10] bcma: add embedded bus Hauke Mehrtens
@ 2011-06-06 10:22 ` Rafał Miłecki
[not found] ` <1307356322.28734.11.camel@dev.znau.edu.ua>
2011-06-06 22:00 ` Hauke Mehrtens
[not found] ` <BANLkTi=atiB_=_N3xSJBAjRGXjTV8a97CA@mail.gmail.com>
1 sibling, 2 replies; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 10:22 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
Hauke,
My idea for naming schema was to use:
bcma_host_TYPE_*
Like:
bcma_host_pci_*
bcma_host_sdio_*
You are using:
bcma_host_bcma_*
What do you think about changing this to:
bcma_host_embedded_*
or just some:
bcma_host_emb_*
?
Does it make more sense to you? I was trying to keep names in bcma
really clear, so every first-time-reader can see differences between
hosts, host and driver, etc.
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> --- /dev/null
> +++ b/drivers/bcma/host_embedded.c
> @@ -0,0 +1,93 @@
> +/*
> + * Broadcom specific AMBA
> + * PCI Host
s/PCI/Embedded/
> +int bcma_host_bcma_register(struct bcma_bus *bus)
> +{
> + ? ? ? u32 __iomem *mmio;
> + ? ? ? /* iomap only first core. We have to read some register on this core
> + ? ? ? ?* to get the number of cores. This is sone in bcma_scan()
> + ? ? ? ?*/
> + ? ? ? mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
> + ? ? ? if (!mmio)
> + ? ? ? ? ? ? ? return -ENOMEM;
> + ? ? ? bus->mmio = mmio;
Maybe just:
bus->mmio = ioremap(...);
? :)
> + ? ? ? /* Host specific */
> + ? ? ? bus->hosttype = BCMA_HOSTTYPE_EMBEDDED;
> + ? ? ? bus->ops = &bcma_host_bcma_ops;
> +
> + ? ? ? /* Register */
> + ? ? ? return bcma_bus_register(bus);
> +}
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index 1afa107..c5bcb5f 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -119,6 +119,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_NONE:
> ? ? ? ? ? ? ? ?case BCMA_HOSTTYPE_SDIO:
> + ? ? ? ? ? ? ? case BCMA_HOSTTYPE_EMBEDDED:
> ? ? ? ? ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ? ?}
>
> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
> index 70b39f7..9229615 100644
> --- a/drivers/bcma/scan.c
> +++ b/drivers/bcma/scan.c
> @@ -203,7 +203,7 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
> ?int bcma_bus_scan(struct bcma_bus *bus)
> ?{
> ? ? ? ?u32 erombase;
> - ? ? ? u32 __iomem *eromptr, *eromend;
> + ? ? ? u32 __iomem *eromptr, *eromend, *mmio;
>
> ? ? ? ?s32 cia, cib;
> ? ? ? ?u8 ports[2], wrappers[2];
> @@ -219,9 +219,34 @@ 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;
> + ? ? ? bus->nr_cores = (tmp & BCMA_CC_ID_NRCORES) >> BCMA_CC_ID_NRCORES_SHIFT;
I'd use different variable as Julian suggested.
> +
> + ? ? ? /* If we are an embedded device we now know the number of avaliable
> + ? ? ? ?* core and ioremap the correct space.
> + ? ? ? ?*/
Typo: avaliable
> + ? ? ? if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
> + ? ? ? ? ? ? ? iounmap(bus->mmio);
> + ? ? ? ? ? ? ? mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * bus->nr_cores);
> + ? ? ? ? ? ? ? if (!mmio)
> + ? ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
> + ? ? ? ? ? ? ? bus->mmio = mmio;
> +
> + ? ? ? ? ? ? ? mmio = ioremap(BCMA_WRAP_BASE, BCMA_CORE_SIZE * bus->nr_cores);
> + ? ? ? ? ? ? ? if (!mmio)
> + ? ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
> + ? ? ? ? ? ? ? bus->host_embedded = mmio;
Do we really need both? mmio and host_embedded? What about keeping
mmio only and using it in calculation for read/write[8,16,32]?
> + ? ? ? }
> + ? ? ? /* reset it to 0 as we use it for counting */
> + ? ? ? bus->nr_cores = 0;
>
> ? ? ? ?erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
> - ? ? ? eromptr = bus->mmio;
> + ? ? ? if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
> + ? ? ? ? ? ? ? eromptr = ioremap(erombase, BCMA_CORE_SIZE);
> + ? ? ? ? ? ? ? if (!eromptr)
> + ? ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
> + ? ? ? } else
> + ? ? ? ? ? ? ? eromptr = bus->mmio;
I though eromptr = bus->mmio; will do the trick for embedded as well.
I think I need some time to read about IO mapping and understand that.
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread[parent not found: <1307356322.28734.11.camel@dev.znau.edu.ua>]
* [RFC][PATCH 03/10] bcma: add embedded bus
[not found] ` <1307356322.28734.11.camel@dev.znau.edu.ua>
@ 2011-06-06 10:51 ` Rafał Miłecki
[not found] ` <4DECB232.70308@broadcom.com>
0 siblings, 1 reply; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 10:51 UTC (permalink / raw)
To: George Kashperko
Cc: Hauke Mehrtens, linux-wireless, linux-mips, mb, arend, b43-dev,
bernhardloos
W dniu 6 czerwca 2011 12:32 u?ytkownik George Kashperko
<george@znau.edu.ua> napisa?:
> Hi,
>
>> Hauke,
>>
>> My idea for naming schema was to use:
>> bcma_host_TYPE_*
>>
>> Like:
>> bcma_host_pci_*
>> bcma_host_sdio_*
>>
>> You are using:
>> bcma_host_bcma_*
>>
>> What do you think about changing this to:
>> bcma_host_embedded_*
>> or just some:
>> bcma_host_emb_*
>> ?
>>
>> Does it make more sense to you? I was trying to keep names in bcma
>> really clear, so every first-time-reader can see differences between
>> hosts, host and driver, etc.
>
> how about bcma_host_soc ?
We get then inconsistency with "BCMA_HOSTTYPE_EMBEDDED". I'd like to
1) See something like bcma_host_emb...
xor
2) Use bcma_host_soc_* and BCMA_HOSTTYPE_SOC
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 03/10] bcma: add embedded bus
2011-06-06 10:22 ` Rafał Miłecki
[not found] ` <1307356322.28734.11.camel@dev.znau.edu.ua>
@ 2011-06-06 22:00 ` Hauke Mehrtens
2011-06-07 0:33 ` Rafał Miłecki
1 sibling, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-06 22:00 UTC (permalink / raw)
To: Rafał Miłecki
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
On 06/06/2011 12:22 PM, Rafa? Mi?ecki wrote:
> Hauke,
>
> My idea for naming schema was to use:
> bcma_host_TYPE_*
>
> Like:
> bcma_host_pci_*
> bcma_host_sdio_*
>
> You are using:
> bcma_host_bcma_*
>
> What do you think about changing this to:
> bcma_host_embedded_*
> or just some:
> bcma_host_emb_*
> ?
>
> Does it make more sense to you? I was trying to keep names in bcma
> really clear, so every first-time-reader can see differences between
> hosts, host and driver, etc.
>
At first I named it bcma_host_bcma_ but then renamed the file name, but
forgot the function names. I will rename it all to bcma_host_soc_*
host_sco.c and so on.
> 2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
>> --- /dev/null
>> +++ b/drivers/bcma/host_embedded.c
>> @@ -0,0 +1,93 @@
>> +/*
>> + * Broadcom specific AMBA
>> + * PCI Host
>
> s/PCI/Embedded/
>
>
>> +int bcma_host_bcma_register(struct bcma_bus *bus)
>> +{
>> + u32 __iomem *mmio;
>> + /* iomap only first core. We have to read some register on this core
>> + * to get the number of cores. This is sone in bcma_scan()
>> + */
>> + mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
>> + if (!mmio)
>> + return -ENOMEM;
>> + bus->mmio = mmio;
>
> Maybe just:
> bus->mmio = ioremap(...);
> ? :)
yes makes sens.
>
>> + /* Host specific */
>> + bus->hosttype = BCMA_HOSTTYPE_EMBEDDED;
>> + bus->ops = &bcma_host_bcma_ops;
>> +
>> + /* Register */
>> + return bcma_bus_register(bus);
>> +}
>> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
>> index 1afa107..c5bcb5f 100644
>> --- a/drivers/bcma/main.c
>> +++ b/drivers/bcma/main.c
>> @@ -119,6 +119,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
>> break;
>> case BCMA_HOSTTYPE_NONE:
>> case BCMA_HOSTTYPE_SDIO:
>> + case BCMA_HOSTTYPE_EMBEDDED:
>> break;
>> }
>>
>> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
>> index 70b39f7..9229615 100644
>> --- a/drivers/bcma/scan.c
>> +++ b/drivers/bcma/scan.c
>> @@ -203,7 +203,7 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
>> int bcma_bus_scan(struct bcma_bus *bus)
>> {
>> u32 erombase;
>> - u32 __iomem *eromptr, *eromend;
>> + u32 __iomem *eromptr, *eromend, *mmio;
>>
>> s32 cia, cib;
>> u8 ports[2], wrappers[2];
>> @@ -219,9 +219,34 @@ 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;
>> + bus->nr_cores = (tmp & BCMA_CC_ID_NRCORES) >> BCMA_CC_ID_NRCORES_SHIFT;
>
> I'd use different variable as Julian suggested.
yes
>
>
>> +
>> + /* If we are an embedded device we now know the number of avaliable
>> + * core and ioremap the correct space.
>> + */
>
> Typo: avaliable
my favorite typo ;-)
>
>
>> + if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
>> + iounmap(bus->mmio);
>> + mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * bus->nr_cores);
>> + if (!mmio)
>> + return -ENOMEM;
>> + bus->mmio = mmio;
>> +
>> + mmio = ioremap(BCMA_WRAP_BASE, BCMA_CORE_SIZE * bus->nr_cores);
>> + if (!mmio)
>> + return -ENOMEM;
>> + bus->host_embedded = mmio;
>
> Do we really need both? mmio and host_embedded? What about keeping
> mmio only and using it in calculation for read/write[8,16,32]?
These are two different memory regions, it should be possible to
calculate the other address, but I do not like that. As host_embedded is
in a union this does not waste any memory.
>
>> + }
>> + /* reset it to 0 as we use it for counting */
>> + bus->nr_cores = 0;
>>
>> erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
>> - eromptr = bus->mmio;
>> + if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
>> + eromptr = ioremap(erombase, BCMA_CORE_SIZE);
>> + if (!eromptr)
>> + return -ENOMEM;
>> + } else
>> + eromptr = bus->mmio;
>
> I though eromptr = bus->mmio; will do the trick for embedded as well.
> I think I need some time to read about IO mapping and understand that.
>
No they are different eromptr is 0x1810e000 and bus->mmio is 0xb8000000
for example on my device. I tried using eromptr = bus->mmio; on embedded
and it did not work.
Hauke
^ permalink raw reply [flat|nested] 35+ messages in thread* [RFC][PATCH 03/10] bcma: add embedded bus
2011-06-06 22:00 ` Hauke Mehrtens
@ 2011-06-07 0:33 ` Rafał Miłecki
[not found] ` <4DEDFDC8.50005@broadcom.com>
0 siblings, 1 reply; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-07 0:33 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
W dniu 7 czerwca 2011 00:00 u?ytkownik Hauke Mehrtens
<hauke@hauke-m.de> napisa?:
> On 06/06/2011 12:22 PM, Rafa? Mi?ecki wrote:
>>> + ? ? ? if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
>>> + ? ? ? ? ? ? ? iounmap(bus->mmio);
>>> + ? ? ? ? ? ? ? mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * bus->nr_cores);
>>> + ? ? ? ? ? ? ? if (!mmio)
>>> + ? ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
>>> + ? ? ? ? ? ? ? bus->mmio = mmio;
>>> +
>>> + ? ? ? ? ? ? ? mmio = ioremap(BCMA_WRAP_BASE, BCMA_CORE_SIZE * bus->nr_cores);
>>> + ? ? ? ? ? ? ? if (!mmio)
>>> + ? ? ? ? ? ? ? ? ? ? ? return -ENOMEM;
>>> + ? ? ? ? ? ? ? bus->host_embedded = mmio;
>>
>> Do we really need both? mmio and host_embedded? What about keeping
>> mmio only and using it in calculation for read/write[8,16,32]?
>
> These are two different memory regions, it should be possible to
> calculate the other address, but I do not like that. As host_embedded is
> in a union this does not waste any memory.
Ah, OK, I can see what does happen here. You are using:
1) bus->mmio for first core
2) bus->host_embedded for first agent/wrapper
I'm not sure if this is a correct approach. Doing "core_index *
BCMA_CORE_SIZE" comes from ssb, where it was the way to calculate
offset. In case of BCMA we are reading all the info from (E)EPROM,
which also includes addresses of the cores.
IMO you should use core->addr and core->wrap for read/write ops. I
believe this is approach Broadcom decided to use for BCMA, when
designing (E)EPROM.
You should not need bus->host_embedded then, maybe you could even do
not set bus->mmio?
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
[parent not found: <BANLkTi=atiB_=_N3xSJBAjRGXjTV8a97CA@mail.gmail.com>]
* [RFC][PATCH 03/10] bcma: add embedded bus
[not found] ` <BANLkTi=atiB_=_N3xSJBAjRGXjTV8a97CA@mail.gmail.com>
@ 2011-06-06 21:40 ` Hauke Mehrtens
0 siblings, 0 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-06 21:40 UTC (permalink / raw)
To: Julian Calaby
Cc: linux-wireless, linux-mips, zajec5, mb, george, arend, b43-dev,
bernhardloos
On 06/06/2011 01:22 AM, Julian Calaby wrote:
> Hauke,
>
> Minor nit:
>
> On Mon, Jun 6, 2011 at 08:07, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>> This patch adds support for using bcma on an embedded bus. An embedded
>> system like the bcm4716 could register this bus and it searches for the
>> bcma cores then.
>>
>> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
>> ---
>> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
>> index 70b39f7..9229615 100644
>> --- a/drivers/bcma/scan.c
>> +++ b/drivers/bcma/scan.c
>> @@ -219,9 +219,34 @@ 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;
>> + bus->nr_cores = (tmp & BCMA_CC_ID_NRCORES) >> BCMA_CC_ID_NRCORES_SHIFT;
>> +
>> + /* If we are an embedded device we now know the number of avaliable
>> + * core and ioremap the correct space.
>> + */
>> + if (bus->hosttype == BCMA_HOSTTYPE_EMBEDDED) {
>> + iounmap(bus->mmio);
>> + mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * bus->nr_cores);
>> + if (!mmio)
>> + return -ENOMEM;
>> + bus->mmio = mmio;
>> +
>> + mmio = ioremap(BCMA_WRAP_BASE, BCMA_CORE_SIZE * bus->nr_cores);
>> + if (!mmio)
>> + return -ENOMEM;
>> + bus->host_embedded = mmio;
>> + }
>> + /* reset it to 0 as we use it for counting */
>> + bus->nr_cores = 0;
>
> Would it make sense to use a local variable for nr_cores, and only use
> it within the BCMA_HOSTTYPE_EMBEDDED if statement, rather than
> re-using bus->nr_cores and having to reset it?
Yes that looks better.
Hauke
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 04/10] bcma: add mips driver
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (2 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 03/10] bcma: add embedded bus Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 11:23 ` Rafał Miłecki
2011-06-05 22:07 ` [RFC][PATCH 05/10] bcma: add serial console support Hauke Mehrtens
` (6 subsequent siblings)
10 siblings, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, 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/bcma_private.h | 3 +
drivers/bcma/driver_mips.c | 227 +++++++++++++++++++++++++++++++++
drivers/bcma/main.c | 8 +
include/linux/bcma/bcma.h | 2 +
include/linux/bcma/bcma_driver_mips.h | 40 ++++++
7 files changed, 291 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 0390e32..568d30b 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -29,9 +29,18 @@ config BCMA_HOST_PCI
config BCMA_HOST_EMBEDDED
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 e509b1b..50ddab8 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_EMBEDDED) += host_embedded.o
obj-$(CONFIG_BCMA) += bcma.o
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 2f72e9c..842ee17 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -19,6 +19,9 @@ extern void bcma_bus_unregister(struct bcma_bus *bus);
/* scan.c */
int bcma_bus_scan(struct bcma_bus *bus);
+/* driver_mips.c */
+extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
+
#ifdef CONFIG_BCMA_HOST_PCI
/* host_pci.c */
extern int __init bcma_host_pci_init(void);
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
new file mode 100644
index 0000000..0a6c217
--- /dev/null
+++ b/drivers/bcma/driver_mips.c
@@ -0,0 +1,227 @@
+/*
+ * Sonics Silicon Backplane
+ * Broadcom MIPS core driver
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/bcma/bcma.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/time.h>
+
+#include "bcma_private.h"
+
+/* The 47162a0 hangs when reading its registers */
+static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
+{
+ return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
+ dev->id.id == BCMA_CORE_MIPS_74K;
+}
+
+static inline u32 mips_read32(struct bcma_drv_mips *mcore,
+ u16 offset)
+{
+ return bcma_read32(mcore->core, offset);
+}
+
+static inline void mips_write32(struct bcma_drv_mips *mcore,
+ u16 offset,
+ u32 value)
+{
+ bcma_write32(mcore->core, offset, value);
+}
+
+static const u32 ipsflag_irq_mask[] = {
+ 0,
+ BCMA_MIPS_IPSFLAG_IRQ1,
+ BCMA_MIPS_IPSFLAG_IRQ2,
+ BCMA_MIPS_IPSFLAG_IRQ3,
+ BCMA_MIPS_IPSFLAG_IRQ4,
+};
+
+static const u32 ipsflag_irq_shift[] = {
+ 0,
+ BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
+ BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
+ BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
+ BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
+};
+
+static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
+{
+ u32 flag;
+
+ if (bcma_core_mips_bcm47162a0_quirk(dev))
+ return dev->core_index;
+ flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
+
+ return flag & 0x1F;
+}
+
+
+/* Get the MIPS IRQ assignment for a specified device.
+ * If unassigned, 0 is returned.
+ * If disabled, 5 is returned.
+ * If not supported, 6 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))
+ break;
+
+ if (irq == 5)
+ irq = 0;
+
+ return 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) {
+ int i;
+ /* backplane irq line is in use, find out who uses
+ * it and set user to irq 0
+ */
+ for (i = 0; i < bus->nr_cores; i++)
+ if ((1 << bcma_core_mips_irqflag(&bus->cores[i])) == oldirqflag) {
+ bcma_core_mips_set_irq(&bus->cores[i], 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)
+{
+ int i;
+ for (i = 0; i < bus->nr_cores; i++) {
+ struct bcma_device *dev;
+ dev = &(bus->cores[i]);
+ bcma_core_mips_print_irq(dev, bcma_core_mips_irq(dev));
+ }
+}
+
+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 *dev;
+ unsigned int irq, i;
+
+ if (!mcore->core)
+ return; /* We don't have a MIPS core */
+
+ pr_info("Initializing MIPS core...\n");
+
+ bus = mcore->core->bus;
+
+ /* Assign IRQs to all cores on the bus */
+ for (irq = 1, i = 0; i < bus->nr_cores; i++) {
+ int mips_irq;
+ dev = &(bus->cores[i]);
+ mips_irq = bcma_core_mips_irq(dev);
+ if (mips_irq > 4)
+ dev->irq = 0;
+ else
+ dev->irq = mips_irq + 2;
+ if (dev->irq > 5)
+ continue;
+ switch (dev->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 (irq <= 4)
+ bcma_core_mips_set_irq(dev, irq++);
+ break;
+ }
+ }
+ pr_info("after irq reconfiguration\n");
+ bcma_core_mips_dump_irq(bus);
+
+ bcma_core_mips_flash_detect(mcore);
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index c5bcb5f..0b4e26d 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -96,6 +96,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;
}
@@ -198,6 +199,13 @@ int bcma_bus_register(struct bcma_bus *bus)
bcma_core_chipcommon_init(&bus->drv_cc);
}
+ /* 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);
+ }
+
/* Find PCIE core */
core = bcma_find_core(bus, BCMA_CORE_PCIE);
if (core) {
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 192c4ae..c5d7d4d 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"
@@ -198,6 +199,7 @@ struct bcma_bus {
struct bcma_drv_cc drv_cc;
struct bcma_drv_pci drv_pci;
+ struct bcma_drv_mips drv_mips;
/* Internal-only stuff follows. Do not touch. */
struct list_head attach_list;
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
new file mode 100644
index 0000000..5faf30c
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_mips.h
@@ -0,0 +1,40 @@
+#ifndef LINUX_BCMA_DRIVER_MIPS_H_
+#define LINUX_BCMA_DRIVER_MIPS_H_
+
+#define BCMA_MIPS_IPSFLAG 0x0F08
+#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F /* which sbflags get routed to mips interrupt 1 */
+#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
+#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00 /* which sbflags get routed to mips interrupt 2 */
+#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
+#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000 /* which sbflags get routed to mips interrupt 3 */
+#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
+#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000 /* which sbflags get routed to mips interrupt 4 */
+#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 flash_buswidth;
+ u32 flash_window;
+ u32 flash_window_size;
+};
+
+extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
+
+#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 04/10] bcma: add mips driver
2011-06-05 22:07 ` [RFC][PATCH 04/10] bcma: add mips driver Hauke Mehrtens
@ 2011-06-06 11:23 ` Rafał Miłecki
2011-06-06 22:06 ` Hauke Mehrtens
0 siblings, 1 reply; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 11:23 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> +/* driver_mips.c */
> +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
Does it compile without CONFIG_BCMA_DRIVER_MIPS?
> +/* Get the MIPS IRQ assignment for a specified device.
> + * If unassigned, 0 is returned.
> + * If disabled, 5 is returned.
> + * If not supported, 6 is returned.
> + */
Does it ever return 6?
> +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))
> + ? ? ? ? ? ? ? ? ? ? ? break;
Use scripts/checkpatch*. Braces around "for" and split line to match
80 chars width.
Why don't you just use "return irq;" instead of break?
> +
> + ? ? ? if (irq == 5)
> + ? ? ? ? ? ? ? irq = 0;
> +
> + ? ? ? return irq;
You can just make it "return 0;" after changing break to return.
> + ? ? ? ? ? ? ? ? ? ? ? for (i = 0; i < bus->nr_cores; i++)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((1 << bcma_core_mips_irqflag(&bus->cores[i])) == oldirqflag) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bcma_core_mips_set_irq(&bus->cores[i], 0);
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
Braces for "for".
> + ? ? ? pr_info("after irq reconfiguration\n");
Make first letter uppercase. I'm not English expert, but doesn't
something like "IRQ reconfiguration done" sound better?
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread* [RFC][PATCH 04/10] bcma: add mips driver
2011-06-06 11:23 ` Rafał Miłecki
@ 2011-06-06 22:06 ` Hauke Mehrtens
2011-06-06 22:50 ` Rafał Miłecki
0 siblings, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-06 22:06 UTC (permalink / raw)
To: Rafał Miłecki
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
On 06/06/2011 01:23 PM, Rafa? Mi?ecki wrote:
> 2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
>> +/* driver_mips.c */
>> +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
>
> Does it compile without CONFIG_BCMA_DRIVER_MIPS?
No ;-) Thought about it after sending these patches, some other patches
will have the same problem.
>
>
>> +/* Get the MIPS IRQ assignment for a specified device.
>> + * If unassigned, 0 is returned.
>> + * If disabled, 5 is returned.
>> + * If not supported, 6 is returned.
>> + */
>
> Does it ever return 6?
Some old comment, will fix this.
>
>> +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))
>> + break;
>
> Use scripts/checkpatch*. Braces around "for" and split line to match
> 80 chars width.
Will check all patches with scripts/checkpatch.sh
>
> Why don't you just use "return irq;" instead of break?
yes this will be better.
>
>
>> +
>> + if (irq == 5)
>> + irq = 0;
>> +
>> + return irq;
>
> You can just make it "return 0;" after changing break to return.
agree
>
>
>> + for (i = 0; i < bus->nr_cores; i++)
>> + if ((1 << bcma_core_mips_irqflag(&bus->cores[i])) == oldirqflag) {
>> + bcma_core_mips_set_irq(&bus->cores[i], 0);
>> + break;
>> + }
>
> Braces for "for".
Is this needed after the coding guildlines? Shouldn't they be removed if
they are not needed?
>
>> + pr_info("after irq reconfiguration\n");
>
> Make first letter uppercase. I'm not English expert, but doesn't
> something like "IRQ reconfiguration done" sound better?
>
Sounds better.
^ permalink raw reply [flat|nested] 35+ messages in thread* [RFC][PATCH 04/10] bcma: add mips driver
2011-06-06 22:06 ` Hauke Mehrtens
@ 2011-06-06 22:50 ` Rafał Miłecki
0 siblings, 0 replies; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 22:50 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
W dniu 7 czerwca 2011 00:06 u?ytkownik Hauke Mehrtens
<hauke@hauke-m.de> napisa?:
> On 06/06/2011 01:23 PM, Rafa? Mi?ecki wrote:
>>> + ? ? ? ? ? ? ? ? ? ? ? for (i = 0; i < bus->nr_cores; i++)
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((1 << bcma_core_mips_irqflag(&bus->cores[i])) == oldirqflag) {
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bcma_core_mips_set_irq(&bus->cores[i], 0);
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
>>
>> Braces for "for".
> Is this needed after the coding guildlines? Shouldn't they be removed if
> they are not needed?
Whoops, after re-checking coding style it seems I was wrong.
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 05/10] bcma: add serial console support
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (3 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 04/10] bcma: add mips driver Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 10:30 ` Rafał Miłecki
2011-06-05 22:07 ` [RFC][PATCH 06/10] bcma: get CPU clock Hauke Mehrtens
` (5 subsequent siblings)
10 siblings, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
This adds support for serial console to bcma, when operating on an
embedded device.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/bcma_private.h | 4 ++
drivers/bcma/driver_chipcommon.c | 62 +++++++++++++++++++++++++++++++++
drivers/bcma/driver_mips.c | 9 +++++
include/linux/bcma/bcma_driver_mips.h | 11 ++++++
4 files changed, 86 insertions(+), 0 deletions(-)
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 842ee17..c65a6e2 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -22,6 +22,10 @@ int bcma_bus_scan(struct bcma_bus *bus);
/* driver_mips.c */
extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
+/* driver_chipcommon.c */
+extern int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
+ struct bcma_drv_mips_serial_port *ports);
+
#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 6061022..b582570 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -87,3 +87,65 @@ 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);
}
+
+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;
+}
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
index 0a6c217..40e4a6d 100644
--- a/drivers/bcma/driver_mips.c
+++ b/drivers/bcma/driver_mips.c
@@ -155,6 +155,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;
@@ -223,5 +231,6 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore)
pr_info("after irq reconfiguration\n");
bcma_core_mips_dump_irq(bus);
+ bcma_core_mips_serial_init(mcore);
bcma_core_mips_flash_detect(mcore);
}
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
index 5faf30c..6584e7d 100644
--- a/include/linux/bcma/bcma_driver_mips.h
+++ b/include/linux/bcma/bcma_driver_mips.h
@@ -27,9 +27,20 @@
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;
+ 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] 35+ messages in thread* [RFC][PATCH 06/10] bcma: get CPU clock
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (4 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 05/10] bcma: add serial console support Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 10:34 ` Rafał Miłecki
2011-06-05 22:07 ` [RFC][PATCH 07/10] bcma: add pci(e) host mode Hauke Mehrtens
` (4 subsequent siblings)
10 siblings, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, 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 | 86 +++++++++++++++++++++++++++
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, 137 insertions(+), 0 deletions(-)
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index c65a6e2..fbabe19 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -22,6 +22,9 @@ int bcma_bus_scan(struct bcma_bus *bus);
/* driver_mips.c */
extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
+/* driver_chipcommon_pmu.c */
+extern u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
+
/* driver_chipcommon.c */
extern int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
struct bcma_drv_mips_serial_port *ports);
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index f44177a..4a700f8 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,82 @@ 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 40e4a6d..faaa232 100644
--- a/drivers/bcma/driver_mips.c
+++ b/drivers/bcma/driver_mips.c
@@ -155,6 +155,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 083c3b6..77dc08c 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 6584e7d..8346fde 100644
--- a/include/linux/bcma/bcma_driver_mips.h
+++ b/include/linux/bcma/bcma_driver_mips.h
@@ -47,5 +47,6 @@ 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);
#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 06/10] bcma: get CPU clock
2011-06-05 22:07 ` [RFC][PATCH 06/10] bcma: get CPU clock Hauke Mehrtens
@ 2011-06-06 10:34 ` Rafał Miłecki
2011-06-06 10:40 ` Rafał Miłecki
0 siblings, 1 reply; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 10:34 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> +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);
Are you really going to use this in some separated driver? If you're,
I heard that exporting symbol should go in pair with patch enabling
usage of such a symbol.
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread* [RFC][PATCH 06/10] bcma: get CPU clock
2011-06-06 10:34 ` Rafał Miłecki
@ 2011-06-06 10:40 ` Rafał Miłecki
0 siblings, 0 replies; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 10:40 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
W dniu 6 czerwca 2011 12:34 u?ytkownik Rafa? Mi?ecki <zajec5@gmail.com> napisa?:
> 2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
>> +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);
>
> Are you really going to use this in some separated driver? If you're,
> I heard that exporting symbol should go in pair with patch enabling
> usage of such a symbol.
I've just read patch 09/10, sorry for the noise :)
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 07/10] bcma: add pci(e) host mode
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (5 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 06/10] bcma: get CPU clock Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 11:32 ` Rafał Miłecki
2011-06-06 11:34 ` Rafał Miłecki
2011-06-05 22:07 ` [RFC][PATCH 08/10] bcm47xx: prepare to support different buses Hauke Mehrtens
` (3 subsequent siblings)
10 siblings, 2 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
This adds some stub for a pci(e) host controller. This controller is
found on some embedded devices to attach other chips.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/Kconfig | 6 ++++
drivers/bcma/Makefile | 1 +
drivers/bcma/bcma_private.h | 6 ++++
drivers/bcma/driver_pci.c | 12 ++++++++-
drivers/bcma/driver_pci_host.c | 44 ++++++++++++++++++++++++++++++++++
include/linux/bcma/bcma_driver_pci.h | 1 +
6 files changed, 69 insertions(+), 1 deletions(-)
create mode 100644 drivers/bcma/driver_pci_host.c
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 568d30b..c863a87 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -27,6 +27,12 @@ config BCMA_HOST_PCI
bool "Support for BCMA on PCI-host bus"
depends on BCMA_HOST_PCI_POSSIBLE
+config BCMA_PCICORE_HOSTMODE
+ bool "Hostmode support for BCMA PCI core"
+ depends on BCMA_DRIVER_MIPS
+ help
+ PCIcore hostmode operation (external PCI bus).
+
config BCMA_HOST_EMBEDDED
bool
depends on BCMA_DRIVER_MIPS
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 50ddab8..f99abfe 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_PCICORE_HOSTMODE) += driver_pci_host.o
bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
bcma-$(CONFIG_BCMA_HOST_EMBEDDED) += host_embedded.o
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index fbabe19..13cf25a 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -29,6 +29,12 @@ extern u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
extern int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
struct bcma_drv_mips_serial_port *ports);
+#ifdef CONFIG_BCMA_PCICORE_HOSTMODE
+/* driver_pci_host.c */
+extern int bcma_pcicore_is_in_hostmode(struct bcma_drv_pci *pc);
+extern void bcma_pcicore_init_hostmode(struct bcma_drv_pci *pc);
+#endif /* CONFIG_BCMA_PCICORE_HOSTMODE */
+
#ifdef CONFIG_BCMA_HOST_PCI
/* host_pci.c */
extern int __init bcma_host_pci_init(void);
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 789d68b..cf8cbe0 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -159,7 +159,17 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
void bcma_core_pci_init(struct bcma_drv_pci *pc)
{
- bcma_pcicore_serdes_workaround(pc);
+ struct bcma_device *core = pc->core;
+
+ if (!bcma_core_is_enabled(core))
+ bcma_core_enable(core, 0);
+#ifdef CONFIG_BCMA_PCICORE_HOSTMODE
+ pc->hostmode = bcma_pcicore_is_in_hostmode(pc);
+ if (pc->hostmode)
+ bcma_pcicore_init_hostmode(pc);
+#endif /* CONFIG_BCMA_PCICORE_HOSTMODE */
+ if (!pc->hostmode)
+ bcma_pcicore_serdes_workaround(pc);
}
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
new file mode 100644
index 0000000..b52c6c9
--- /dev/null
+++ b/drivers/bcma/driver_pci_host.c
@@ -0,0 +1,44 @@
+/*
+ * Broadcom specific AMBA
+ * PCI Core
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+#include <asm/paccess.h>
+/* Probe a 32bit value on the bus and catch bus exceptions.
+ * Returns nonzero on a bus exception.
+ * This is MIPS specific */
+#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
+
+
+void bcma_pcicore_init_hostmode(struct bcma_drv_pci *pc)
+{
+ /* TODO: implement PCI host mode */
+}
+
+int bcma_pcicore_is_in_hostmode(struct bcma_drv_pci *pc)
+{
+ struct bcma_bus *bus = pc->core->bus;
+ u16 chipid_top;
+ u32 tmp;
+
+ chipid_top = (bus->chipinfo.id & 0xFF00);
+ if (chipid_top != 0x4700 &&
+ chipid_top != 0x5300)
+ return 0;
+
+/* TODO: add when sprom is available
+ * if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
+ * return 0;
+ */
+
+ return !mips_busprobe32(tmp, (bus->mmio + (pc->core->core_index *
+ BCMA_CORE_SIZE)));
+}
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index b7e191c..5bbc58f 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -78,6 +78,7 @@ struct pci_dev;
struct bcma_drv_pci {
struct bcma_device *core;
u8 setup_done:1;
+ u8 hostmode:1;
};
/* Register access */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 07/10] bcma: add pci(e) host mode
2011-06-05 22:07 ` [RFC][PATCH 07/10] bcma: add pci(e) host mode Hauke Mehrtens
@ 2011-06-06 11:32 ` Rafał Miłecki
2011-06-06 22:11 ` Hauke Mehrtens
2011-06-06 11:34 ` Rafał Miłecki
1 sibling, 1 reply; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 11:32 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> +config BCMA_PCICORE_HOSTMODE
> + ? ? ? bool "Hostmode support for BCMA PCI core"
> + ? ? ? depends on BCMA_DRIVER_MIPS
> + ? ? ? help
> + ? ? ? ? PCIcore hostmode operation (external PCI bus).
I think you started to use BCMA_DRIVER_corename. Could you stick to it
(one schema), please? Maybe just
BCMA_DRIVER_PCI_HOSTMODE
?
> +#ifdef CONFIG_BCMA_PCICORE_HOSTMODE
> + ? ? ? pc->hostmode = bcma_pcicore_is_in_hostmode(pc);
> + ? ? ? if (pc->hostmode)
> + ? ? ? ? ? ? ? bcma_pcicore_init_hostmode(pc);
> +#endif /* CONFIG_BCMA_PCICORE_HOSTMODE */
> + ? ? ? if (!pc->hostmode)
> + ? ? ? ? ? ? ? bcma_pcicore_serdes_workaround(pc);
Does it make sense to init hostmode PCI like clientmode if we just
disable CONFIG_BCMA_PCICORE_HOSTMODE?
I think we should always check if core is host or client mode and use
correct initialization only. We should not init it as clientmode just
because we do not have driver for host mode.
> diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
> new file mode 100644
> index 0000000..b52c6c9
> --- /dev/null
> +++ b/drivers/bcma/driver_pci_host.c
> @@ -0,0 +1,44 @@
> +/*
> + * Broadcom specific AMBA
> + * PCI Core
Please rename "PCI Core", add something about hostmode.
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 07/10] bcma: add pci(e) host mode
2011-06-06 11:32 ` Rafał Miłecki
@ 2011-06-06 22:11 ` Hauke Mehrtens
0 siblings, 0 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-06 22:11 UTC (permalink / raw)
To: Rafał Miłecki
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
On 06/06/2011 01:32 PM, Rafa? Mi?ecki wrote:
> 2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
>> +config BCMA_PCICORE_HOSTMODE
>> + bool "Hostmode support for BCMA PCI core"
>> + depends on BCMA_DRIVER_MIPS
>> + help
>> + PCIcore hostmode operation (external PCI bus).
>
> I think you started to use BCMA_DRIVER_corename. Could you stick to it
> (one schema), please? Maybe just
> BCMA_DRIVER_PCI_HOSTMODE
> ?
>
Yes sounds better.
>
>> +#ifdef CONFIG_BCMA_PCICORE_HOSTMODE
>> + pc->hostmode = bcma_pcicore_is_in_hostmode(pc);
>> + if (pc->hostmode)
>> + bcma_pcicore_init_hostmode(pc);
>> +#endif /* CONFIG_BCMA_PCICORE_HOSTMODE */
>> + if (!pc->hostmode)
>> + bcma_pcicore_serdes_workaround(pc);
>
> Does it make sense to init hostmode PCI like clientmode if we just
> disable CONFIG_BCMA_PCICORE_HOSTMODE?
>
> I think we should always check if core is host or client mode and use
> correct initialization only. We should not init it as clientmode just
> because we do not have driver for host mode.
Yes we should not initialize a host mode pci core with client init code
as it will break my device. ;-) I will place
bcma_pcicore_is_in_hostmode() into the normal PCI driver code so it is
available all the time.
>
>
>> diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
>> new file mode 100644
>> index 0000000..b52c6c9
>> --- /dev/null
>> +++ b/drivers/bcma/driver_pci_host.c
>> @@ -0,0 +1,44 @@
>> +/*
>> + * Broadcom specific AMBA
>> + * PCI Core
>
> Please rename "PCI Core", add something about hostmode.
>
Missed that while copy and past.
Hauke
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 07/10] bcma: add pci(e) host mode
2011-06-05 22:07 ` [RFC][PATCH 07/10] bcma: add pci(e) host mode Hauke Mehrtens
2011-06-06 11:32 ` Rafał Miłecki
@ 2011-06-06 11:34 ` Rafał Miłecki
1 sibling, 0 replies; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 11:34 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> +#ifdef CONFIG_BCMA_PCICORE_HOSTMODE
> +/* driver_pci_host.c */
> +extern int bcma_pcicore_is_in_hostmode(struct bcma_drv_pci *pc);
> +extern void bcma_pcicore_init_hostmode(struct bcma_drv_pci *pc);
> +#endif /* CONFIG_BCMA_PCICORE_HOSTMODE */
I don't know if I'm overreacting, but I really don't like naming mess
in the ssb.
Why don't you use bcma_core_pci_* to be consistent?
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 08/10] bcm47xx: prepare to support different buses
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (6 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 07/10] bcma: add pci(e) host mode Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-05 22:07 ` [RFC][PATCH 09/10] bcm47xx: add support for bcma bus Hauke Mehrtens
` (2 subsequent siblings)
10 siblings, 0 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
The ssb bus is not hod directly any more. there is now a union which
contains all the supported buses, now just ssb. As just one system bus
can be used at a time the union does not cause any problems.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
arch/mips/bcm47xx/gpio.c | 56 ++++++++++++++++----------
arch/mips/bcm47xx/nvram.c | 15 +++++--
arch/mips/bcm47xx/serial.c | 13 +++++-
arch/mips/bcm47xx/setup.c | 32 +++++++++++---
arch/mips/bcm47xx/time.c | 9 +++-
arch/mips/bcm47xx/wgt634u.c | 13 ++++--
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 14 ++++++-
arch/mips/include/asm/mach-bcm47xx/gpio.h | 53 +++++++++++++++++-------
drivers/watchdog/bcm47xx_wdt.c | 12 +++++-
9 files changed, 156 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..c64b76d 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -35,15 +35,21 @@
#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;
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 +58,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 +257,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 +268,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 +286,14 @@ void __init plat_mem_setup(void)
memcpy(&mcore->serial_ports[1], &port, sizeof(port));
}
}
+}
+
+void __init plat_mem_setup(void)
+{
+ struct cpuinfo_mips *c = ¤t_cpu_data;
+
+ bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
+ bcm47xx_register_ssb();
_machine_restart = bcm47xx_machine_restart;
_machine_halt = bcm47xx_machine_halt;
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..79ecd0a 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;
@@ -133,21 +133,24 @@ static int __init wgt634u_init(void)
* been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
*/
- u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+ if (bcm47xx_active_bus_type != BCM47XX_BUS_TYPE_SSB)
+ return -ENODEV;
+
+ u8 *et0mac = bcm47xx_bus.ssb.sprom.et0mac;
if (et0mac[0] == 0x00 &&
((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
(et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
- struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+ struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
printk(KERN_INFO "WGT634U machine detected.\n");
if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
gpio_interrupt, IRQF_SHARED,
- "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
+ "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
gpio_direction_input(WGT634U_GPIO_RESET);
gpio_intmask(WGT634U_GPIO_RESET, 1);
- ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
+ ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
SSB_CHIPCO_IRQ_GPIO,
SSB_CHIPCO_IRQ_GPIO);
}
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..16d6c19 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -21,41 +21,64 @@ 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] 35+ messages in thread* [RFC][PATCH 09/10] bcm47xx: add support for bcma bus
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (7 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 08/10] bcm47xx: prepare to support different buses Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
2011-06-06 11:07 ` Rafał Miłecki
2011-06-05 22:07 ` [RFC][PATCH 10/10] bcm47xx: fix irq assignment for new SoCs Hauke Mehrtens
[not found] ` <201106061332.51661.arnd@arndb.de>
10 siblings, 1 reply; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, 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/Kconfig | 4 +++
arch/mips/bcm47xx/gpio.c | 9 ++++++++
arch/mips/bcm47xx/nvram.c | 6 +++++
arch/mips/bcm47xx/serial.c | 24 +++++++++++++++++++++++
arch/mips/bcm47xx/setup.c | 27 ++++++++++++++++++++++++-
arch/mips/bcm47xx/time.c | 3 ++
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 3 ++
arch/mips/include/asm/mach-bcm47xx/gpio.h | 18 +++++++++++++++++
drivers/watchdog/bcm47xx_wdt.c | 6 +++++
9 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 653da62..bdb0341 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -100,6 +100,10 @@ config BCM47XX
select SSB_EMBEDDED
select SSB_B43_PCI_BRIDGE if PCI
select SSB_PCICORE_HOSTMODE if PCI
+ select BCMA
+ select BCMA_HOST_EMBEDDED
+ select BCMA_DRIVER_MIPS
+ select BCMA_PCICORE_HOSTMODE
select GENERIC_GPIO
select SYS_HAS_EARLY_PRINTK
select CFE
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
index 2f6d2df..42af3f8 100644
--- a/arch/mips/bcm47xx/gpio.c
+++ b/arch/mips/bcm47xx/gpio.c
@@ -34,6 +34,9 @@ int gpio_request(unsigned gpio, const char *tag)
return -EBUSY;
return 0;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
@@ -53,6 +56,9 @@ void gpio_free(unsigned gpio)
clear_bit(gpio, gpio_in_use);
return;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return;
}
}
EXPORT_SYMBOL(gpio_free);
@@ -67,6 +73,9 @@ int gpio_to_irq(unsigned gpio)
return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
else
return -EINVAL;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index d2304d0..75c36c4 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -27,6 +27,7 @@ static char nvram_buf[NVRAM_SPACE];
static void early_nvram_init(void)
{
struct ssb_mipscore *mcore_ssb;
+ struct bcma_drv_mips *mcore_bcma;
struct nvram_header *header;
int i;
u32 base = 0;
@@ -40,6 +41,11 @@ static void early_nvram_init(void)
base = mcore_ssb->flash_window;
lim = mcore_ssb->flash_window_size;
break;
+ case BCM47XX_BUS_TYPE_BCMA:
+ mcore_bcma = &bcm47xx_bus.bcma.drv_mips;
+ base = mcore_bcma->flash_window;
+ lim = mcore_bcma->flash_window_size;
+ break;
}
off = FLASH_MIN;
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index 87c2c5e..ed74d975 100644
--- a/arch/mips/bcm47xx/serial.c
+++ b/arch/mips/bcm47xx/serial.c
@@ -45,11 +45,35 @@ static int __init uart8250_init_ssb(void)
return platform_device_register(&uart8250_device);
}
+static int __init uart8250_init_bcma(void)
+{
+ int i;
+ struct bcma_drv_mips *mcore = &(bcm47xx_bus.bcma.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 = &(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);
+}
+
static int __init uart8250_init(void)
{
switch (bcm47xx_active_bus_type) {
case BCM47XX_BUS_TYPE_SSB:
return uart8250_init_ssb();
+ case BCM47XX_BUS_TYPE_BCMA:
+ return uart8250_init_bcma();
}
return -EINVAL;
}
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index c64b76d..8dd82f3 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_embedded.h>
#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/time.h>
@@ -49,6 +50,9 @@ static void bcm47xx_machine_restart(char *command)
case BCM47XX_BUS_TYPE_SSB:
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
break;
+ case BCM47XX_BUS_TYPE_BCMA:
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.drv_cc, 1);
+ break;
}
while (1)
cpu_relax();
@@ -62,6 +66,9 @@ static void bcm47xx_machine_halt(void)
case BCM47XX_BUS_TYPE_SSB:
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
break;
+ case BCM47XX_BUS_TYPE_BCMA:
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.drv_cc, 0);
+ break;
}
while (1)
cpu_relax();
@@ -288,12 +295,28 @@ static void __init bcm47xx_register_ssb(void)
}
}
+static void __init bcm47xx_register_bcma(void)
+{
+ int err;
+
+ err = bcma_host_bcma_register(&bcm47xx_bus.bcma);
+ if (err)
+ panic("Failed to initialize BCMA bus (err %d)\n", err);
+}
+
void __init plat_mem_setup(void)
{
struct cpuinfo_mips *c = ¤t_cpu_data;
- bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_SSB;
- bcm47xx_register_ssb();
+ if (c->cputype == CPU_74K) {
+ printk(KERN_INFO "bcm47xx: using bcma bus\n");
+ bcm47xx_active_bus_type = BCM47XX_BUS_TYPE_BCMA;
+ bcm47xx_register_bcma();
+ } else {
+ printk(KERN_INFO "bcm47xx: using ssb bus\n");
+ 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 a7be993..ace3ba2 100644
--- a/arch/mips/bcm47xx/time.c
+++ b/arch/mips/bcm47xx/time.c
@@ -43,6 +43,9 @@ void __init plat_time_init(void)
case BCM47XX_BUS_TYPE_SSB:
hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
break;
+ case BCM47XX_BUS_TYPE_BCMA:
+ hz = bcma_cpu_clock(&bcm47xx_bus.bcma.drv_mips) / 2;
+ break;
}
if (!hz)
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index 4be8b95..3e6ccb9 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
@@ -20,13 +20,16 @@
#define __ASM_BCM47XX_H
#include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
enum bcm47xx_bus_type {
BCM47XX_BUS_TYPE_SSB,
+ BCM47XX_BUS_TYPE_BCMA,
};
union bcm47xx_bus {
struct ssb_bus ssb;
+ struct bcma_bus bcma;
};
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 16d6c19..e8629a8 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -24,6 +24,9 @@ static inline int gpio_get_value(unsigned gpio)
switch (bcm47xx_active_bus_type) {
case BCM47XX_BUS_TYPE_SSB:
return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
@@ -33,6 +36,9 @@ static inline void gpio_set_value(unsigned gpio, int value)
switch (bcm47xx_active_bus_type) {
case BCM47XX_BUS_TYPE_SSB:
ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, value ? 1 << gpio : 0);
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return;
}
}
@@ -42,6 +48,9 @@ static inline int gpio_direction_input(unsigned gpio)
case BCM47XX_BUS_TYPE_SSB:
ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
return 0;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
@@ -55,6 +64,9 @@ 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;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
@@ -66,6 +78,9 @@ static inline int gpio_intmask(unsigned gpio, int value)
ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
value ? 1 << gpio : 0);
return 0;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
@@ -77,6 +92,9 @@ static inline int gpio_polarity(unsigned gpio, int value)
ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
value ? 1 << gpio : 0);
return 0;
+ case BCM47XX_BUS_TYPE_BCMA:
+ /* Not implemenmted yet */
+ return -EINVAL;
}
return -EINVAL;
}
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 7e4e063..8a31494 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -58,6 +58,9 @@ static inline void bcm47xx_wdt_hw_start(void)
case BCM47XX_BUS_TYPE_SSB:
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
break;
+ case BCM47XX_BUS_TYPE_BCMA:
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.drv_cc, 0xfffffff);
+ break;
}
}
@@ -66,6 +69,9 @@ static inline int bcm47xx_wdt_hw_stop(void)
switch (bcm47xx_active_bus_type) {
case BCM47XX_BUS_TYPE_SSB:
return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+ case BCM47XX_BUS_TYPE_BCMA:
+ bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.drv_cc, 0);
+ return 0;
}
return -EINVAL;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread* [RFC][PATCH 09/10] bcm47xx: add support for bcma bus
2011-06-05 22:07 ` [RFC][PATCH 09/10] bcm47xx: add support for bcma bus Hauke Mehrtens
@ 2011-06-06 11:07 ` Rafał Miłecki
2011-06-06 22:13 ` Hauke Mehrtens
0 siblings, 1 reply; 35+ messages in thread
From: Rafał Miłecki @ 2011-06-06 11:07 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
> 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/Kconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?4 +++
> ?arch/mips/bcm47xx/gpio.c ? ? ? ? ? ? ? ? ? ? | ? ?9 ++++++++
> ?arch/mips/bcm47xx/nvram.c ? ? ? ? ? ? ? ? ? ?| ? ?6 +++++
> ?arch/mips/bcm47xx/serial.c ? ? ? ? ? ? ? ? ? | ? 24 +++++++++++++++++++++++
> ?arch/mips/bcm47xx/setup.c ? ? ? ? ? ? ? ? ? ?| ? 27 ++++++++++++++++++++++++-
> ?arch/mips/bcm47xx/time.c ? ? ? ? ? ? ? ? ? ? | ? ?3 ++
> ?arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | ? ?3 ++
> ?arch/mips/include/asm/mach-bcm47xx/gpio.h ? ?| ? 18 +++++++++++++++++
> ?drivers/watchdog/bcm47xx_wdt.c ? ? ? ? ? ? ? | ? ?6 +++++
> ?9 files changed, 98 insertions(+), 2 deletions(-)
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 653da62..bdb0341 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -100,6 +100,10 @@ config BCM47XX
> ? ? ? ?select SSB_EMBEDDED
> ? ? ? ?select SSB_B43_PCI_BRIDGE if PCI
> ? ? ? ?select SSB_PCICORE_HOSTMODE if PCI
> + ? ? ? select BCMA
> + ? ? ? select BCMA_HOST_EMBEDDED
> + ? ? ? select BCMA_DRIVER_MIPS
> + ? ? ? select BCMA_PCICORE_HOSTMODE
I'm not involved in development for embedded devices but I believe
that space is quite important for them.
You force compiling both: ssb and bcma for every device using bcm47xx.
I think ppl may want to compile only one bus driver.
--
Rafa?
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 09/10] bcm47xx: add support for bcma bus
2011-06-06 11:07 ` Rafał Miłecki
@ 2011-06-06 22:13 ` Hauke Mehrtens
0 siblings, 0 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-06 22:13 UTC (permalink / raw)
To: Rafał Miłecki
Cc: linux-wireless, linux-mips, mb, george, arend, b43-dev,
bernhardloos
On 06/06/2011 01:07 PM, Rafa? Mi?ecki wrote:
> 2011/6/6 Hauke Mehrtens <hauke@hauke-m.de>:
>> 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/Kconfig | 4 +++
>> arch/mips/bcm47xx/gpio.c | 9 ++++++++
>> arch/mips/bcm47xx/nvram.c | 6 +++++
>> arch/mips/bcm47xx/serial.c | 24 +++++++++++++++++++++++
>> arch/mips/bcm47xx/setup.c | 27 ++++++++++++++++++++++++-
>> arch/mips/bcm47xx/time.c | 3 ++
>> arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 3 ++
>> arch/mips/include/asm/mach-bcm47xx/gpio.h | 18 +++++++++++++++++
>> drivers/watchdog/bcm47xx_wdt.c | 6 +++++
>> 9 files changed, 98 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 653da62..bdb0341 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -100,6 +100,10 @@ config BCM47XX
>> select SSB_EMBEDDED
>> select SSB_B43_PCI_BRIDGE if PCI
>> select SSB_PCICORE_HOSTMODE if PCI
>> + select BCMA
>> + select BCMA_HOST_EMBEDDED
>> + select BCMA_DRIVER_MIPS
>> + select BCMA_PCICORE_HOSTMODE
>
> I'm not involved in development for embedded devices but I believe
> that space is quite important for them.
>
> You force compiling both: ssb and bcma for every device using bcm47xx.
> I think ppl may want to compile only one bus driver.
>
Yes that has to be improved as there should also be an option to use the
compiler optimazions for the new MIPS 74K CPU core.
Hauke
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC][PATCH 10/10] bcm47xx: fix irq assignment for new SoCs.
2011-06-05 22:07 [RFC][PATCH 00/10] bcma: add support for embedded devices like bcm4716 Hauke Mehrtens
` (8 preceding siblings ...)
2011-06-05 22:07 ` [RFC][PATCH 09/10] bcm47xx: add support for bcma bus Hauke Mehrtens
@ 2011-06-05 22:07 ` Hauke Mehrtens
[not found] ` <201106061332.51661.arnd@arndb.de>
10 siblings, 0 replies; 35+ messages in thread
From: Hauke Mehrtens @ 2011-06-05 22:07 UTC (permalink / raw)
To: linux-wireless, linux-mips
Cc: zajec5, mb, george, arend, b43-dev, bernhardloos, Hauke Mehrtens
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
arch/mips/bcm47xx/irq.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
index 325757a..3642cee 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,12 @@ void plat_irq_dispatch(void)
void __init arch_init_irq(void)
{
+ if (bcm47xx_active_bus_type == BCM47XX_BUS_TYPE_BCMA) {
+ bcma_write32(bcm47xx_bus.bcma.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;
+ }
mips_cpu_irq_init();
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 35+ messages in thread[parent not found: <201106061332.51661.arnd@arndb.de>]