in mcb-parse.c [36:114]
static int chameleon_parse_gdd(struct mcb_bus *bus,
struct chameleon_bar *cb,
void __iomem *base, int bar_count)
{
struct chameleon_gdd __iomem *gdd =
(struct chameleon_gdd __iomem *) base;
struct mcb_device *mdev;
u32 dev_mapbase;
u32 offset;
u32 size;
int ret;
__le32 reg1;
__le32 reg2;
mdev = mcb_alloc_dev(bus);
if (!mdev)
return -ENOMEM;
reg1 = readl(&gdd->reg1);
reg2 = readl(&gdd->reg2);
offset = readl(&gdd->offset);
size = readl(&gdd->size);
mdev->id = GDD_DEV(reg1);
mdev->rev = GDD_REV(reg1);
mdev->var = GDD_VAR(reg1);
mdev->bar = GDD_BAR(reg2);
mdev->group = GDD_GRP(reg2);
mdev->inst = GDD_INS(reg2);
/*
* If the BAR is missing, dev_mapbase is zero, or if the
* device is IO mapped we just print a warning and go on with the
* next device, instead of completely stop the gdd parser
*/
if (mdev->bar > bar_count - 1) {
pr_info("No BAR for 16z%03d\n", mdev->id);
ret = 0;
goto err;
}
dev_mapbase = cb[mdev->bar].addr;
if (!dev_mapbase) {
pr_info("BAR not assigned for 16z%03d\n", mdev->id);
ret = 0;
goto err;
}
if (dev_mapbase & 0x01) {
pr_info("IO mapped Device (16z%03d) not yet supported\n",
mdev->id);
ret = 0;
goto err;
}
pr_debug("Found a 16z%03d\n", mdev->id);
mdev->irq.start = GDD_IRQ(reg1);
mdev->irq.end = GDD_IRQ(reg1);
mdev->irq.flags = IORESOURCE_IRQ;
mdev->mem.start = dev_mapbase + offset;
mdev->mem.end = mdev->mem.start + size - 1;
mdev->mem.flags = IORESOURCE_MEM;
mdev->is_added = false;
ret = mcb_device_register(bus, mdev);
if (ret < 0)
goto err;
return 0;
err:
mcb_free_dev(mdev);
return ret;
}