1 // SPDX-License-Identifier: GPL-2.0-only
3 * Industry-pack bus support functions.
5 * Copyright (C) 2011-2012 CERN (www.cern.ch)
6 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/idr.h>
13 #include <linux/ipack.h>
15 #define to_ipack_dev(device) container_of(device, struct ipack_device, dev)
16 #define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver)
18 static DEFINE_IDA(ipack_ida
);
20 static void ipack_device_release(struct device
*dev
)
22 struct ipack_device
*device
= to_ipack_dev(dev
);
24 device
->release(device
);
27 static inline const struct ipack_device_id
*
28 ipack_match_one_device(const struct ipack_device_id
*id
,
29 const struct ipack_device
*device
)
31 if ((id
->format
== IPACK_ANY_FORMAT
||
32 id
->format
== device
->id_format
) &&
33 (id
->vendor
== IPACK_ANY_ID
|| id
->vendor
== device
->id_vendor
) &&
34 (id
->device
== IPACK_ANY_ID
|| id
->device
== device
->id_device
))
39 static const struct ipack_device_id
*
40 ipack_match_id(const struct ipack_device_id
*ids
, struct ipack_device
*idev
)
43 while (ids
->vendor
|| ids
->device
) {
44 if (ipack_match_one_device(ids
, idev
))
52 static int ipack_bus_match(struct device
*dev
, struct device_driver
*drv
)
54 struct ipack_device
*idev
= to_ipack_dev(dev
);
55 struct ipack_driver
*idrv
= to_ipack_driver(drv
);
56 const struct ipack_device_id
*found_id
;
58 found_id
= ipack_match_id(idrv
->id_table
, idev
);
59 return found_id
? 1 : 0;
62 static int ipack_bus_probe(struct device
*device
)
64 struct ipack_device
*dev
= to_ipack_dev(device
);
65 struct ipack_driver
*drv
= to_ipack_driver(device
->driver
);
70 return drv
->ops
->probe(dev
);
73 static int ipack_bus_remove(struct device
*device
)
75 struct ipack_device
*dev
= to_ipack_dev(device
);
76 struct ipack_driver
*drv
= to_ipack_driver(device
->driver
);
78 if (!drv
->ops
->remove
)
81 drv
->ops
->remove(dev
);
85 static int ipack_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
87 struct ipack_device
*idev
;
92 idev
= to_ipack_dev(dev
);
94 if (add_uevent_var(env
,
95 "MODALIAS=ipack:f%02Xv%08Xd%08X", idev
->id_format
,
96 idev
->id_vendor
, idev
->id_device
))
102 #define ipack_device_attr(field, format_string) \
104 field##_show(struct device *dev, struct device_attribute *attr, \
107 struct ipack_device *idev = to_ipack_dev(dev); \
108 return sprintf(buf, format_string, idev->field); \
111 static ssize_t
id_show(struct device
*dev
,
112 struct device_attribute
*attr
, char *buf
)
114 unsigned int i
, c
, l
, s
;
115 struct ipack_device
*idev
= to_ipack_dev(dev
);
118 switch (idev
->id_format
) {
119 case IPACK_ID_VERSION_1
:
120 l
= 0x7; s
= 1; break;
121 case IPACK_ID_VERSION_2
:
122 l
= 0xf; s
= 2; break;
127 for (i
= 0; i
< idev
->id_avail
; i
++) {
131 else if ((i
& s
) == 0)
134 sprintf(&buf
[c
], "%02x", idev
->id
[i
]);
142 id_vendor_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
144 struct ipack_device
*idev
= to_ipack_dev(dev
);
145 switch (idev
->id_format
) {
146 case IPACK_ID_VERSION_1
:
147 return sprintf(buf
, "0x%02x\n", idev
->id_vendor
);
148 case IPACK_ID_VERSION_2
:
149 return sprintf(buf
, "0x%06x\n", idev
->id_vendor
);
156 id_device_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
158 struct ipack_device
*idev
= to_ipack_dev(dev
);
159 switch (idev
->id_format
) {
160 case IPACK_ID_VERSION_1
:
161 return sprintf(buf
, "0x%02x\n", idev
->id_device
);
162 case IPACK_ID_VERSION_2
:
163 return sprintf(buf
, "0x%04x\n", idev
->id_device
);
169 static ssize_t
modalias_show(struct device
*dev
, struct device_attribute
*attr
,
172 struct ipack_device
*idev
= to_ipack_dev(dev
);
174 return sprintf(buf
, "ipac:f%02Xv%08Xd%08X", idev
->id_format
,
175 idev
->id_vendor
, idev
->id_device
);
178 ipack_device_attr(id_format
, "0x%hhx\n");
180 static DEVICE_ATTR_RO(id
);
181 static DEVICE_ATTR_RO(id_device
);
182 static DEVICE_ATTR_RO(id_format
);
183 static DEVICE_ATTR_RO(id_vendor
);
184 static DEVICE_ATTR_RO(modalias
);
186 static struct attribute
*ipack_attrs
[] = {
188 &dev_attr_id_device
.attr
,
189 &dev_attr_id_format
.attr
,
190 &dev_attr_id_vendor
.attr
,
191 &dev_attr_modalias
.attr
,
194 ATTRIBUTE_GROUPS(ipack
);
196 static struct bus_type ipack_bus_type
= {
198 .probe
= ipack_bus_probe
,
199 .match
= ipack_bus_match
,
200 .remove
= ipack_bus_remove
,
201 .dev_groups
= ipack_groups
,
202 .uevent
= ipack_uevent
,
205 struct ipack_bus_device
*ipack_bus_register(struct device
*parent
, int slots
,
206 const struct ipack_bus_ops
*ops
,
207 struct module
*owner
)
210 struct ipack_bus_device
*bus
;
212 bus
= kzalloc(sizeof(*bus
), GFP_KERNEL
);
216 bus_nr
= ida_simple_get(&ipack_ida
, 0, 0, GFP_KERNEL
);
222 bus
->bus_nr
= bus_nr
;
223 bus
->parent
= parent
;
229 EXPORT_SYMBOL_GPL(ipack_bus_register
);
231 static int ipack_unregister_bus_member(struct device
*dev
, void *data
)
233 struct ipack_device
*idev
= to_ipack_dev(dev
);
234 struct ipack_bus_device
*bus
= data
;
236 if (idev
->bus
== bus
)
237 ipack_device_del(idev
);
242 int ipack_bus_unregister(struct ipack_bus_device
*bus
)
244 bus_for_each_dev(&ipack_bus_type
, NULL
, bus
,
245 ipack_unregister_bus_member
);
246 ida_simple_remove(&ipack_ida
, bus
->bus_nr
);
250 EXPORT_SYMBOL_GPL(ipack_bus_unregister
);
252 int ipack_driver_register(struct ipack_driver
*edrv
, struct module
*owner
,
255 edrv
->driver
.owner
= owner
;
256 edrv
->driver
.name
= name
;
257 edrv
->driver
.bus
= &ipack_bus_type
;
258 return driver_register(&edrv
->driver
);
260 EXPORT_SYMBOL_GPL(ipack_driver_register
);
262 void ipack_driver_unregister(struct ipack_driver
*edrv
)
264 driver_unregister(&edrv
->driver
);
266 EXPORT_SYMBOL_GPL(ipack_driver_unregister
);
268 static u16
ipack_crc_byte(u16 crc
, u8 c
)
273 for (i
= 0; i
< 8; i
++)
274 crc
= (crc
<< 1) ^ ((crc
& 0x8000) ? 0x1021 : 0);
279 * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the
280 * opposite bit ordering.
282 static u8
ipack_calc_crc1(struct ipack_device
*dev
)
289 for (i
= 0; i
< dev
->id_avail
; i
++) {
290 c
= (i
!= 11) ? dev
->id
[i
] : 0;
291 crc
= ipack_crc_byte(crc
, c
);
297 static u16
ipack_calc_crc2(struct ipack_device
*dev
)
304 for (i
= 0; i
< dev
->id_avail
; i
++) {
305 c
= ((i
!= 0x18) && (i
!= 0x19)) ? dev
->id
[i
] : 0;
306 crc
= ipack_crc_byte(crc
, c
);
312 static void ipack_parse_id1(struct ipack_device
*dev
)
317 dev
->id_vendor
= id
[4];
318 dev
->id_device
= id
[5];
320 dev
->speed_32mhz
= (id
[7] == 'H');
321 crc
= ipack_calc_crc1(dev
);
322 dev
->id_crc_correct
= (crc
== id
[11]);
323 if (!dev
->id_crc_correct
) {
324 dev_warn(&dev
->dev
, "ID CRC invalid found 0x%x, expected 0x%x.\n",
329 static void ipack_parse_id2(struct ipack_device
*dev
)
331 __be16
*id
= (__be16
*) dev
->id
;
334 dev
->id_vendor
= ((be16_to_cpu(id
[3]) & 0xff) << 16)
335 + be16_to_cpu(id
[4]);
336 dev
->id_device
= be16_to_cpu(id
[5]);
337 flags
= be16_to_cpu(id
[10]);
338 dev
->speed_8mhz
= !!(flags
& 2);
339 dev
->speed_32mhz
= !!(flags
& 4);
340 crc
= ipack_calc_crc2(dev
);
341 dev
->id_crc_correct
= (crc
== be16_to_cpu(id
[12]));
342 if (!dev
->id_crc_correct
) {
343 dev_warn(&dev
->dev
, "ID CRC invalid found 0x%x, expected 0x%x.\n",
348 static int ipack_device_read_id(struct ipack_device
*dev
)
354 idmem
= ioremap(dev
->region
[IPACK_ID_SPACE
].start
,
355 dev
->region
[IPACK_ID_SPACE
].size
);
357 dev_err(&dev
->dev
, "error mapping memory\n");
361 /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH"
362 * we are dealing with a IndustryPack format 1 device. If we detect
363 * "VITA4 " (16 bit big endian formatted) we are dealing with a
364 * IndustryPack format 2 device */
365 if ((ioread8(idmem
+ 1) == 'I') &&
366 (ioread8(idmem
+ 3) == 'P') &&
367 (ioread8(idmem
+ 5) == 'A') &&
368 ((ioread8(idmem
+ 7) == 'C') ||
369 (ioread8(idmem
+ 7) == 'H'))) {
370 dev
->id_format
= IPACK_ID_VERSION_1
;
371 dev
->id_avail
= ioread8(idmem
+ 0x15);
372 if ((dev
->id_avail
< 0x0c) || (dev
->id_avail
> 0x40)) {
373 dev_warn(&dev
->dev
, "invalid id size");
374 dev
->id_avail
= 0x0c;
376 } else if ((ioread8(idmem
+ 0) == 'I') &&
377 (ioread8(idmem
+ 1) == 'V') &&
378 (ioread8(idmem
+ 2) == 'A') &&
379 (ioread8(idmem
+ 3) == 'T') &&
380 (ioread8(idmem
+ 4) == ' ') &&
381 (ioread8(idmem
+ 5) == '4')) {
382 dev
->id_format
= IPACK_ID_VERSION_2
;
383 dev
->id_avail
= ioread16be(idmem
+ 0x16);
384 if ((dev
->id_avail
< 0x1a) || (dev
->id_avail
> 0x40)) {
385 dev_warn(&dev
->dev
, "invalid id size");
386 dev
->id_avail
= 0x1a;
389 dev
->id_format
= IPACK_ID_VERSION_INVALID
;
393 if (!dev
->id_avail
) {
398 /* Obtain the amount of memory required to store a copy of the complete
400 dev
->id
= kmalloc(dev
->id_avail
, GFP_KERNEL
);
405 for (i
= 0; i
< dev
->id_avail
; i
++) {
406 if (dev
->id_format
== IPACK_ID_VERSION_1
)
407 dev
->id
[i
] = ioread8(idmem
+ (i
<< 1) + 1);
409 dev
->id
[i
] = ioread8(idmem
+ i
);
412 /* now we can finally work with the copy */
413 switch (dev
->id_format
) {
414 case IPACK_ID_VERSION_1
:
415 ipack_parse_id1(dev
);
417 case IPACK_ID_VERSION_2
:
418 ipack_parse_id2(dev
);
428 int ipack_device_init(struct ipack_device
*dev
)
432 dev
->dev
.bus
= &ipack_bus_type
;
433 dev
->dev
.release
= ipack_device_release
;
434 dev
->dev
.parent
= dev
->bus
->parent
;
435 dev_set_name(&dev
->dev
,
436 "ipack-dev.%u.%u", dev
->bus
->bus_nr
, dev
->slot
);
437 device_initialize(&dev
->dev
);
439 if (dev
->bus
->ops
->set_clockrate(dev
, 8))
440 dev_warn(&dev
->dev
, "failed to switch to 8 MHz operation for reading of device ID.\n");
441 if (dev
->bus
->ops
->reset_timeout(dev
))
442 dev_warn(&dev
->dev
, "failed to reset potential timeout.");
444 ret
= ipack_device_read_id(dev
);
446 dev_err(&dev
->dev
, "error reading device id section.\n");
450 /* if the device supports 32 MHz operation, use it. */
451 if (dev
->speed_32mhz
) {
452 ret
= dev
->bus
->ops
->set_clockrate(dev
, 32);
454 dev_err(&dev
->dev
, "failed to switch to 32 MHz operation.\n");
459 EXPORT_SYMBOL_GPL(ipack_device_init
);
461 int ipack_device_add(struct ipack_device
*dev
)
463 return device_add(&dev
->dev
);
465 EXPORT_SYMBOL_GPL(ipack_device_add
);
467 void ipack_device_del(struct ipack_device
*dev
)
469 device_del(&dev
->dev
);
470 ipack_put_device(dev
);
472 EXPORT_SYMBOL_GPL(ipack_device_del
);
474 void ipack_get_device(struct ipack_device
*dev
)
476 get_device(&dev
->dev
);
478 EXPORT_SYMBOL_GPL(ipack_get_device
);
480 void ipack_put_device(struct ipack_device
*dev
)
482 put_device(&dev
->dev
);
484 EXPORT_SYMBOL_GPL(ipack_put_device
);
486 static int __init
ipack_init(void)
488 ida_init(&ipack_ida
);
489 return bus_register(&ipack_bus_type
);
492 static void __exit
ipack_exit(void)
494 bus_unregister(&ipack_bus_type
);
495 ida_destroy(&ipack_ida
);
498 module_init(ipack_init
);
499 module_exit(ipack_exit
);
501 MODULE_AUTHOR("Samuel Iglesias Gonsalvez <siglesias@igalia.com>");
502 MODULE_LICENSE("GPL");
503 MODULE_DESCRIPTION("Industry-pack bus core");