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
,
29 struct chameleon_bar
*cb
,
35 static int chameleon_parse_gdd(struct mcb_bus
*bus
,
36 struct chameleon_bar
*cb
,
37 void __iomem
*base
, int bar_count
)
39 struct chameleon_gdd __iomem
*gdd
=
40 (struct chameleon_gdd __iomem
*) base
;
41 struct mcb_device
*mdev
;
49 mdev
= mcb_alloc_dev(bus
);
53 reg1
= readl(&gdd
->reg1
);
54 reg2
= readl(&gdd
->reg2
);
55 offset
= readl(&gdd
->offset
);
56 size
= readl(&gdd
->size
);
58 mdev
->id
= GDD_DEV(reg1
);
59 mdev
->rev
= GDD_REV(reg1
);
60 mdev
->var
= GDD_VAR(reg1
);
61 mdev
->bar
= GDD_BAR(reg2
);
62 mdev
->group
= GDD_GRP(reg2
);
63 mdev
->inst
= GDD_INS(reg2
);
66 * If the BAR is missing, dev_mapbase is zero, or if the
67 * device is IO mapped we just print a warning and go on with the
68 * next device, instead of completely stop the gdd parser
70 if (mdev
->bar
> bar_count
- 1) {
71 pr_info("No BAR for 16z%03d\n", mdev
->id
);
76 dev_mapbase
= cb
[mdev
->bar
].addr
;
78 pr_info("BAR not assigned for 16z%03d\n", mdev
->id
);
83 if (dev_mapbase
& 0x01) {
84 pr_info("IO mapped Device (16z%03d) not yet supported\n",
90 pr_debug("Found a 16z%03d\n", mdev
->id
);
92 mdev
->irq
.start
= GDD_IRQ(reg1
);
93 mdev
->irq
.end
= GDD_IRQ(reg1
);
94 mdev
->irq
.flags
= IORESOURCE_IRQ
;
96 mdev
->mem
.start
= dev_mapbase
+ offset
;
98 mdev
->mem
.end
= mdev
->mem
.start
+ size
- 1;
99 mdev
->mem
.flags
= IORESOURCE_MEM
;
101 mdev
->is_added
= false;
103 ret
= mcb_device_register(bus
, mdev
);
115 static void chameleon_parse_bar(void __iomem
*base
,
116 struct chameleon_bar
*cb
, int bar_count
)
118 char __iomem
*p
= base
;
124 for (i
= 0; i
< bar_count
; i
++) {
125 cb
[i
].addr
= readl(p
);
126 cb
[i
].size
= readl(p
+ 4);
128 p
+= sizeof(struct chameleon_bar
);
132 static int chameleon_get_bar(char __iomem
**base
, phys_addr_t mapbase
,
133 struct chameleon_bar
**cb
)
135 struct chameleon_bar
*c
;
141 * For those devices which are not connected
142 * to the PCI Bus (e.g. LPC) there is a bar
143 * descriptor located directly after the
144 * chameleon header. This header is comparable
147 dtype
= get_next_dtype(*base
);
148 if (dtype
== CHAMELEON_DTYPE_BAR
) {
151 bar_count
= BAR_CNT(reg
);
152 if (bar_count
<= 0 && bar_count
> CHAMELEON_BAR_MAX
)
155 c
= kcalloc(bar_count
, sizeof(struct chameleon_bar
),
160 chameleon_parse_bar(*base
, c
, bar_count
);
161 *base
+= BAR_DESC_SIZE(bar_count
);
163 c
= kzalloc(sizeof(struct chameleon_bar
), GFP_KERNEL
);
176 int chameleon_parse_cells(struct mcb_bus
*bus
, phys_addr_t mapbase
,
179 struct chameleon_fpga_header
*header
;
180 struct chameleon_bar
*cb
;
181 char __iomem
*p
= base
;
188 hsize
= sizeof(struct chameleon_fpga_header
);
190 header
= kzalloc(hsize
, GFP_KERNEL
);
194 /* Extract header information */
195 memcpy_fromio(header
, p
, hsize
);
196 /* We only support chameleon v2 at the moment */
197 header
->magic
= le16_to_cpu(header
->magic
);
198 if (header
->magic
!= CHAMELEONV2_MAGIC
) {
199 pr_err("Unsupported chameleon version 0x%x\n",
206 bus
->revision
= header
->revision
;
207 bus
->model
= header
->model
;
208 bus
->minor
= header
->minor
;
209 snprintf(bus
->name
, CHAMELEON_FILENAME_LEN
+ 1, "%s",
212 bar_count
= chameleon_get_bar(&p
, mapbase
, &cb
);
216 for_each_chameleon_cell(dtype
, p
) {
218 case CHAMELEON_DTYPE_GENERAL
:
219 ret
= chameleon_parse_gdd(bus
, cb
, p
, bar_count
);
222 p
+= sizeof(struct chameleon_gdd
);
224 case CHAMELEON_DTYPE_BRIDGE
:
225 chameleon_parse_bdd(bus
, cb
, p
);
226 p
+= sizeof(struct chameleon_bdd
);
228 case CHAMELEON_DTYPE_END
:
231 pr_err("Invalid chameleon descriptor type 0x%x\n",
253 EXPORT_SYMBOL_GPL(chameleon_parse_cells
);