1 #include <linux/types.h>
2 #include <linux/ioport.h>
3 #include <linux/slab.h>
4 #include <linux/export.h>
8 #include "mcb-internal.h"
10 struct mcb_parse_priv
{
15 #define for_each_chameleon_cell(dtype, p) \
16 for ((dtype) = get_next_dtype((p)); \
17 (dtype) != CHAMELEON_DTYPE_END; \
18 (dtype) = get_next_dtype((p)))
20 static inline uint32_t get_next_dtype(void __iomem
*p
)
28 static int chameleon_parse_bdd(struct mcb_bus
*bus
,
35 static int chameleon_parse_gdd(struct mcb_bus
*bus
,
39 struct chameleon_gdd __iomem
*gdd
=
40 (struct chameleon_gdd __iomem
*) base
;
41 struct mcb_device
*mdev
;
48 mdev
= mcb_alloc_dev(bus
);
52 reg1
= readl(&gdd
->reg1
);
53 reg2
= readl(&gdd
->reg2
);
54 offset
= readl(&gdd
->offset
);
55 size
= readl(&gdd
->size
);
57 mdev
->id
= GDD_DEV(reg1
);
58 mdev
->rev
= GDD_REV(reg1
);
59 mdev
->var
= GDD_VAR(reg1
);
60 mdev
->bar
= GDD_BAR(reg1
);
61 mdev
->group
= GDD_GRP(reg2
);
62 mdev
->inst
= GDD_INS(reg2
);
64 pr_debug("Found a 16z%03d\n", mdev
->id
);
66 mdev
->irq
.start
= GDD_IRQ(reg1
);
67 mdev
->irq
.end
= GDD_IRQ(reg1
);
68 mdev
->irq
.flags
= IORESOURCE_IRQ
;
70 mdev
->mem
.start
= mapbase
+ offset
;
71 mdev
->mem
.end
= mdev
->mem
.start
+ size
- 1;
72 mdev
->mem
.flags
= IORESOURCE_MEM
;
74 mdev
->is_added
= false;
76 ret
= mcb_device_register(bus
, mdev
);
88 int chameleon_parse_cells(struct mcb_bus
*bus
, phys_addr_t mapbase
,
91 char __iomem
*p
= base
;
92 struct chameleon_fpga_header
*header
;
98 hsize
= sizeof(struct chameleon_fpga_header
);
100 header
= kzalloc(hsize
, GFP_KERNEL
);
104 /* Extract header information */
105 memcpy_fromio(header
, p
, hsize
);
106 /* We only support chameleon v2 at the moment */
107 header
->magic
= le16_to_cpu(header
->magic
);
108 if (header
->magic
!= CHAMELEONV2_MAGIC
) {
109 pr_err("Unsupported chameleon version 0x%x\n",
116 pr_debug("header->revision = %d\n", header
->revision
);
117 pr_debug("header->model = 0x%x ('%c')\n", header
->model
,
119 pr_debug("header->minor = %d\n", header
->minor
);
120 pr_debug("header->bus_type = 0x%x\n", header
->bus_type
);
123 pr_debug("header->magic = 0x%x\n", header
->magic
);
124 pr_debug("header->filename = \"%.*s\"\n", CHAMELEON_FILENAME_LEN
,
127 for_each_chameleon_cell(dtype
, p
) {
129 case CHAMELEON_DTYPE_GENERAL
:
130 ret
= chameleon_parse_gdd(bus
, mapbase
, p
);
133 p
+= sizeof(struct chameleon_gdd
);
135 case CHAMELEON_DTYPE_BRIDGE
:
136 chameleon_parse_bdd(bus
, mapbase
, p
);
137 p
+= sizeof(struct chameleon_bdd
);
139 case CHAMELEON_DTYPE_END
:
142 pr_err("Invalid chameleon descriptor type 0x%x\n",
160 EXPORT_SYMBOL_GPL(chameleon_parse_cells
);