1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015-2017 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
5 #include <linux/kernel.h>
6 #include <linux/device.h>
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/sysfs.h>
14 * The lowest bit in the SIOX status word signals if the in-device watchdog is
15 * ok. If the bit is set, the device is functional.
17 * On writing the watchdog timer is reset when this bit toggles.
19 #define SIOX_STATUS_WDG 0x01
22 * Bits 1 to 3 of the status word read as the bitwise negation of what was
23 * clocked in before. The value clocked in is changed in each cycle and so
24 * allows to detect transmit/receive problems.
26 #define SIOX_STATUS_COUNTER 0x0e
29 * Each Siox-Device has a 4 bit type number that is neither 0 nor 15. This is
30 * available in the upper nibble of the read status.
32 * On write these bits are DC.
34 #define SIOX_STATUS_TYPE 0xf0
36 #define CREATE_TRACE_POINTS
37 #include <trace/events/siox.h>
39 static bool siox_is_registered
;
41 static void siox_master_lock(struct siox_master
*smaster
)
43 mutex_lock(&smaster
->lock
);
46 static void siox_master_unlock(struct siox_master
*smaster
)
48 mutex_unlock(&smaster
->lock
);
51 static inline u8
siox_status_clean(u8 status_read
, u8 status_written
)
54 * bits 3:1 of status sample the respective bit in the status
55 * byte written in the previous cycle but inverted. So if you wrote the
56 * status word as 0xa before (counter = 0b101), it is expected to get
57 * back the counter bits as 0b010.
59 * So given the last status written this function toggles the there
60 * unset counter bits in the read value such that the counter bits in
61 * the return value are all zero iff the bits were read as expected to
62 * simplify error detection.
65 return status_read
^ (~status_written
& 0xe);
68 static bool siox_device_counter_error(struct siox_device
*sdevice
,
71 return (status_clean
& SIOX_STATUS_COUNTER
) != 0;
74 static bool siox_device_type_error(struct siox_device
*sdevice
, u8 status_clean
)
76 u8 statustype
= (status_clean
& SIOX_STATUS_TYPE
) >> 4;
79 * If the device knows which value the type bits should have, check
80 * against this value otherwise just rule out the invalid values 0b0000
83 if (sdevice
->statustype
) {
84 if (statustype
!= sdevice
->statustype
)
97 static bool siox_device_wdg_error(struct siox_device
*sdevice
, u8 status_clean
)
99 return (status_clean
& SIOX_STATUS_WDG
) == 0;
103 * If there is a type or counter error the device is called "unsynced".
105 bool siox_device_synced(struct siox_device
*sdevice
)
107 if (siox_device_type_error(sdevice
, sdevice
->status_read_clean
))
110 return !siox_device_counter_error(sdevice
, sdevice
->status_read_clean
);
113 EXPORT_SYMBOL_GPL(siox_device_synced
);
116 * A device is called "connected" if it is synced and the watchdog is not
119 bool siox_device_connected(struct siox_device
*sdevice
)
121 if (!siox_device_synced(sdevice
))
124 return !siox_device_wdg_error(sdevice
, sdevice
->status_read_clean
);
126 EXPORT_SYMBOL_GPL(siox_device_connected
);
128 static void siox_poll(struct siox_master
*smaster
)
130 struct siox_device
*sdevice
;
131 size_t i
= smaster
->setbuf_len
;
132 unsigned int devno
= 0;
133 int unsync_error
= 0;
135 smaster
->last_poll
= jiffies
;
138 * The counter bits change in each second cycle, the watchdog bit
140 * The counter bits hold values from [0, 6]. 7 would be possible
141 * theoretically but the protocol designer considered that a bad idea
142 * for reasons unknown today. (Maybe that's because then the status read
143 * back has only zeros in the counter bits then which might be confused
144 * with a stuck-at-0 error. But for the same reason (with s/0/1/) 0
147 if (++smaster
->status
> 0x0d)
150 memset(smaster
->buf
, 0, smaster
->setbuf_len
);
152 /* prepare data pushed out to devices in buf[0..setbuf_len) */
153 list_for_each_entry(sdevice
, &smaster
->devices
, node
) {
154 struct siox_driver
*sdriver
=
155 to_siox_driver(sdevice
->dev
.driver
);
156 sdevice
->status_written
= smaster
->status
;
158 i
-= sdevice
->inbytes
;
161 * If the device or a previous one is unsynced, don't pet the
162 * watchdog. This is done to ensure that the device is kept in
163 * reset when something is wrong.
165 if (!siox_device_synced(sdevice
))
168 if (sdriver
&& !unsync_error
)
169 sdriver
->set_data(sdevice
, sdevice
->status_written
,
170 &smaster
->buf
[i
+ 1]);
173 * Don't trigger watchdog if there is no driver or a
176 sdevice
->status_written
&= ~SIOX_STATUS_WDG
;
178 smaster
->buf
[i
] = sdevice
->status_written
;
180 trace_siox_set_data(smaster
, sdevice
, devno
, i
);
185 smaster
->pushpull(smaster
, smaster
->setbuf_len
, smaster
->buf
,
187 smaster
->buf
+ smaster
->setbuf_len
);
191 /* interpret data pulled in from devices in buf[setbuf_len..] */
193 i
= smaster
->setbuf_len
;
194 list_for_each_entry(sdevice
, &smaster
->devices
, node
) {
195 struct siox_driver
*sdriver
=
196 to_siox_driver(sdevice
->dev
.driver
);
197 u8 status
= smaster
->buf
[i
+ sdevice
->outbytes
- 1];
199 u8 prev_status_clean
= sdevice
->status_read_clean
;
201 bool connected
= true;
203 if (!siox_device_synced(sdevice
))
207 * If the watchdog bit wasn't toggled in this cycle, report the
208 * watchdog as active to give a consistent view for drivers and
211 if (!sdriver
|| unsync_error
)
212 status
&= ~SIOX_STATUS_WDG
;
215 siox_status_clean(status
,
216 sdevice
->status_written_lastcycle
);
218 /* Check counter and type bits */
219 if (siox_device_counter_error(sdevice
, status_clean
) ||
220 siox_device_type_error(sdevice
, status_clean
)) {
225 /* only report a new error if the last cycle was ok */
227 siox_device_counter_error(sdevice
,
228 prev_status_clean
) ||
229 siox_device_type_error(sdevice
,
233 sdevice
->status_errors
++;
234 sysfs_notify_dirent(sdevice
->status_errors_kn
);
238 /* If the device is unsynced report the watchdog as active */
240 status
&= ~SIOX_STATUS_WDG
;
241 status_clean
&= ~SIOX_STATUS_WDG
;
244 if (siox_device_wdg_error(sdevice
, status_clean
))
247 /* The watchdog state changed just now */
248 if ((status_clean
^ prev_status_clean
) & SIOX_STATUS_WDG
) {
249 sysfs_notify_dirent(sdevice
->watchdog_kn
);
251 if (siox_device_wdg_error(sdevice
, status_clean
)) {
252 struct kernfs_node
*wd_errs
=
253 sdevice
->watchdog_errors_kn
;
255 sdevice
->watchdog_errors
++;
256 sysfs_notify_dirent(wd_errs
);
260 if (connected
!= sdevice
->connected
)
261 sysfs_notify_dirent(sdevice
->connected_kn
);
263 sdevice
->status_read_clean
= status_clean
;
264 sdevice
->status_written_lastcycle
= sdevice
->status_written
;
265 sdevice
->connected
= connected
;
267 trace_siox_get_data(smaster
, sdevice
, devno
, status_clean
, i
);
269 /* only give data read to driver if the device is connected */
270 if (sdriver
&& connected
)
271 sdriver
->get_data(sdevice
, &smaster
->buf
[i
]);
274 i
+= sdevice
->outbytes
;
278 static int siox_poll_thread(void *data
)
280 struct siox_master
*smaster
= data
;
281 signed long timeout
= 0;
283 get_device(&smaster
->dev
);
286 if (kthread_should_stop()) {
287 put_device(&smaster
->dev
);
291 siox_master_lock(smaster
);
293 if (smaster
->active
) {
294 unsigned long next_poll
=
295 smaster
->last_poll
+ smaster
->poll_interval
;
296 if (time_is_before_eq_jiffies(next_poll
))
299 timeout
= smaster
->poll_interval
-
300 (jiffies
- smaster
->last_poll
);
302 timeout
= MAX_SCHEDULE_TIMEOUT
;
306 * Set the task to idle while holding the lock. This makes sure
307 * that we don't sleep too long when the bus is reenabled before
308 * schedule_timeout is reached.
311 set_current_state(TASK_IDLE
);
313 siox_master_unlock(smaster
);
316 schedule_timeout(timeout
);
319 * I'm not clear if/why it is important to set the state to
320 * RUNNING again, but it fixes a "do not call blocking ops when
321 * !TASK_RUNNING;"-warning.
323 set_current_state(TASK_RUNNING
);
327 static int __siox_start(struct siox_master
*smaster
)
329 if (!(smaster
->setbuf_len
+ smaster
->getbuf_len
))
339 wake_up_process(smaster
->poll_thread
);
344 static int siox_start(struct siox_master
*smaster
)
348 siox_master_lock(smaster
);
349 ret
= __siox_start(smaster
);
350 siox_master_unlock(smaster
);
355 static int __siox_stop(struct siox_master
*smaster
)
357 if (smaster
->active
) {
358 struct siox_device
*sdevice
;
362 list_for_each_entry(sdevice
, &smaster
->devices
, node
) {
363 if (sdevice
->connected
)
364 sysfs_notify_dirent(sdevice
->connected_kn
);
365 sdevice
->connected
= false;
373 static int siox_stop(struct siox_master
*smaster
)
377 siox_master_lock(smaster
);
378 ret
= __siox_stop(smaster
);
379 siox_master_unlock(smaster
);
384 static ssize_t
type_show(struct device
*dev
,
385 struct device_attribute
*attr
, char *buf
)
387 struct siox_device
*sdev
= to_siox_device(dev
);
389 return sprintf(buf
, "%s\n", sdev
->type
);
392 static DEVICE_ATTR_RO(type
);
394 static ssize_t
inbytes_show(struct device
*dev
,
395 struct device_attribute
*attr
, char *buf
)
397 struct siox_device
*sdev
= to_siox_device(dev
);
399 return sprintf(buf
, "%zu\n", sdev
->inbytes
);
402 static DEVICE_ATTR_RO(inbytes
);
404 static ssize_t
outbytes_show(struct device
*dev
,
405 struct device_attribute
*attr
, char *buf
)
407 struct siox_device
*sdev
= to_siox_device(dev
);
409 return sprintf(buf
, "%zu\n", sdev
->outbytes
);
412 static DEVICE_ATTR_RO(outbytes
);
414 static ssize_t
status_errors_show(struct device
*dev
,
415 struct device_attribute
*attr
, char *buf
)
417 struct siox_device
*sdev
= to_siox_device(dev
);
418 unsigned int status_errors
;
420 siox_master_lock(sdev
->smaster
);
422 status_errors
= sdev
->status_errors
;
424 siox_master_unlock(sdev
->smaster
);
426 return sprintf(buf
, "%u\n", status_errors
);
429 static DEVICE_ATTR_RO(status_errors
);
431 static ssize_t
connected_show(struct device
*dev
,
432 struct device_attribute
*attr
, char *buf
)
434 struct siox_device
*sdev
= to_siox_device(dev
);
437 siox_master_lock(sdev
->smaster
);
439 connected
= sdev
->connected
;
441 siox_master_unlock(sdev
->smaster
);
443 return sprintf(buf
, "%u\n", connected
);
446 static DEVICE_ATTR_RO(connected
);
448 static ssize_t
watchdog_show(struct device
*dev
,
449 struct device_attribute
*attr
, char *buf
)
451 struct siox_device
*sdev
= to_siox_device(dev
);
454 siox_master_lock(sdev
->smaster
);
456 status
= sdev
->status_read_clean
;
458 siox_master_unlock(sdev
->smaster
);
460 return sprintf(buf
, "%d\n", status
& SIOX_STATUS_WDG
);
463 static DEVICE_ATTR_RO(watchdog
);
465 static ssize_t
watchdog_errors_show(struct device
*dev
,
466 struct device_attribute
*attr
, char *buf
)
468 struct siox_device
*sdev
= to_siox_device(dev
);
469 unsigned int watchdog_errors
;
471 siox_master_lock(sdev
->smaster
);
473 watchdog_errors
= sdev
->watchdog_errors
;
475 siox_master_unlock(sdev
->smaster
);
477 return sprintf(buf
, "%u\n", watchdog_errors
);
480 static DEVICE_ATTR_RO(watchdog_errors
);
482 static struct attribute
*siox_device_attrs
[] = {
484 &dev_attr_inbytes
.attr
,
485 &dev_attr_outbytes
.attr
,
486 &dev_attr_status_errors
.attr
,
487 &dev_attr_connected
.attr
,
488 &dev_attr_watchdog
.attr
,
489 &dev_attr_watchdog_errors
.attr
,
492 ATTRIBUTE_GROUPS(siox_device
);
494 static void siox_device_release(struct device
*dev
)
496 struct siox_device
*sdevice
= to_siox_device(dev
);
501 static struct device_type siox_device_type
= {
502 .groups
= siox_device_groups
,
503 .release
= siox_device_release
,
506 static int siox_match(struct device
*dev
, struct device_driver
*drv
)
508 if (dev
->type
!= &siox_device_type
)
511 /* up to now there is only a single driver so keeping this simple */
515 static struct bus_type siox_bus_type
= {
520 static int siox_driver_probe(struct device
*dev
)
522 struct siox_driver
*sdriver
= to_siox_driver(dev
->driver
);
523 struct siox_device
*sdevice
= to_siox_device(dev
);
526 ret
= sdriver
->probe(sdevice
);
530 static int siox_driver_remove(struct device
*dev
)
532 struct siox_driver
*sdriver
=
533 container_of(dev
->driver
, struct siox_driver
, driver
);
534 struct siox_device
*sdevice
= to_siox_device(dev
);
537 ret
= sdriver
->remove(sdevice
);
541 static void siox_driver_shutdown(struct device
*dev
)
543 struct siox_driver
*sdriver
=
544 container_of(dev
->driver
, struct siox_driver
, driver
);
545 struct siox_device
*sdevice
= to_siox_device(dev
);
547 sdriver
->shutdown(sdevice
);
550 static ssize_t
active_show(struct device
*dev
,
551 struct device_attribute
*attr
, char *buf
)
553 struct siox_master
*smaster
= to_siox_master(dev
);
555 return sprintf(buf
, "%d\n", smaster
->active
);
558 static ssize_t
active_store(struct device
*dev
,
559 struct device_attribute
*attr
,
560 const char *buf
, size_t count
)
562 struct siox_master
*smaster
= to_siox_master(dev
);
566 ret
= kstrtoint(buf
, 0, &active
);
571 ret
= siox_start(smaster
);
573 ret
= siox_stop(smaster
);
581 static DEVICE_ATTR_RW(active
);
583 static struct siox_device
*siox_device_add(struct siox_master
*smaster
,
584 const char *type
, size_t inbytes
,
585 size_t outbytes
, u8 statustype
);
587 static ssize_t
device_add_store(struct device
*dev
,
588 struct device_attribute
*attr
,
589 const char *buf
, size_t count
)
591 struct siox_master
*smaster
= to_siox_master(dev
);
594 size_t inbytes
= 0, outbytes
= 0;
597 ret
= sscanf(buf
, "%19s %zu %zu %hhu", type
, &inbytes
,
598 &outbytes
, &statustype
);
599 if (ret
!= 3 && ret
!= 4)
602 if (strcmp(type
, "siox-12x8") || inbytes
!= 2 || outbytes
!= 4)
605 siox_device_add(smaster
, "siox-12x8", inbytes
, outbytes
, statustype
);
610 static DEVICE_ATTR_WO(device_add
);
612 static void siox_device_remove(struct siox_master
*smaster
);
614 static ssize_t
device_remove_store(struct device
*dev
,
615 struct device_attribute
*attr
,
616 const char *buf
, size_t count
)
618 struct siox_master
*smaster
= to_siox_master(dev
);
620 /* XXX? require to write <type> <inbytes> <outbytes> */
621 siox_device_remove(smaster
);
626 static DEVICE_ATTR_WO(device_remove
);
628 static ssize_t
poll_interval_ns_show(struct device
*dev
,
629 struct device_attribute
*attr
, char *buf
)
631 struct siox_master
*smaster
= to_siox_master(dev
);
633 return sprintf(buf
, "%lld\n", jiffies_to_nsecs(smaster
->poll_interval
));
636 static ssize_t
poll_interval_ns_store(struct device
*dev
,
637 struct device_attribute
*attr
,
638 const char *buf
, size_t count
)
640 struct siox_master
*smaster
= to_siox_master(dev
);
644 ret
= kstrtou64(buf
, 0, &val
);
648 siox_master_lock(smaster
);
650 smaster
->poll_interval
= nsecs_to_jiffies(val
);
652 siox_master_unlock(smaster
);
657 static DEVICE_ATTR_RW(poll_interval_ns
);
659 static struct attribute
*siox_master_attrs
[] = {
660 &dev_attr_active
.attr
,
661 &dev_attr_device_add
.attr
,
662 &dev_attr_device_remove
.attr
,
663 &dev_attr_poll_interval_ns
.attr
,
666 ATTRIBUTE_GROUPS(siox_master
);
668 static void siox_master_release(struct device
*dev
)
670 struct siox_master
*smaster
= to_siox_master(dev
);
675 static struct device_type siox_master_type
= {
676 .groups
= siox_master_groups
,
677 .release
= siox_master_release
,
680 struct siox_master
*siox_master_alloc(struct device
*dev
,
683 struct siox_master
*smaster
;
688 smaster
= kzalloc(sizeof(*smaster
) + size
, GFP_KERNEL
);
692 device_initialize(&smaster
->dev
);
695 smaster
->dev
.bus
= &siox_bus_type
;
696 smaster
->dev
.type
= &siox_master_type
;
697 smaster
->dev
.parent
= dev
;
698 smaster
->poll_interval
= DIV_ROUND_UP(HZ
, 40);
700 dev_set_drvdata(&smaster
->dev
, &smaster
[1]);
704 EXPORT_SYMBOL_GPL(siox_master_alloc
);
706 int siox_master_register(struct siox_master
*smaster
)
710 if (!siox_is_registered
)
711 return -EPROBE_DEFER
;
713 if (!smaster
->pushpull
)
716 dev_set_name(&smaster
->dev
, "siox-%d", smaster
->busno
);
718 mutex_init(&smaster
->lock
);
719 INIT_LIST_HEAD(&smaster
->devices
);
721 smaster
->last_poll
= jiffies
;
722 smaster
->poll_thread
= kthread_run(siox_poll_thread
, smaster
,
723 "siox-%d", smaster
->busno
);
724 if (IS_ERR(smaster
->poll_thread
)) {
726 return PTR_ERR(smaster
->poll_thread
);
729 ret
= device_add(&smaster
->dev
);
731 kthread_stop(smaster
->poll_thread
);
735 EXPORT_SYMBOL_GPL(siox_master_register
);
737 void siox_master_unregister(struct siox_master
*smaster
)
740 device_del(&smaster
->dev
);
742 siox_master_lock(smaster
);
744 __siox_stop(smaster
);
746 while (smaster
->num_devices
) {
747 struct siox_device
*sdevice
;
749 sdevice
= container_of(smaster
->devices
.prev
,
750 struct siox_device
, node
);
751 list_del(&sdevice
->node
);
752 smaster
->num_devices
--;
754 siox_master_unlock(smaster
);
756 device_unregister(&sdevice
->dev
);
758 siox_master_lock(smaster
);
761 siox_master_unlock(smaster
);
763 put_device(&smaster
->dev
);
765 EXPORT_SYMBOL_GPL(siox_master_unregister
);
767 static struct siox_device
*siox_device_add(struct siox_master
*smaster
,
768 const char *type
, size_t inbytes
,
769 size_t outbytes
, u8 statustype
)
771 struct siox_device
*sdevice
;
775 sdevice
= kzalloc(sizeof(*sdevice
), GFP_KERNEL
);
777 return ERR_PTR(-ENOMEM
);
779 sdevice
->type
= type
;
780 sdevice
->inbytes
= inbytes
;
781 sdevice
->outbytes
= outbytes
;
782 sdevice
->statustype
= statustype
;
784 sdevice
->smaster
= smaster
;
785 sdevice
->dev
.parent
= &smaster
->dev
;
786 sdevice
->dev
.bus
= &siox_bus_type
;
787 sdevice
->dev
.type
= &siox_device_type
;
789 siox_master_lock(smaster
);
791 dev_set_name(&sdevice
->dev
, "siox-%d-%d",
792 smaster
->busno
, smaster
->num_devices
);
794 buf_len
= smaster
->setbuf_len
+ inbytes
+
795 smaster
->getbuf_len
+ outbytes
;
796 if (smaster
->buf_len
< buf_len
) {
797 u8
*buf
= krealloc(smaster
->buf
, buf_len
, GFP_KERNEL
);
800 dev_err(&smaster
->dev
,
801 "failed to realloc buffer to %zu\n", buf_len
);
806 smaster
->buf_len
= buf_len
;
810 ret
= device_register(&sdevice
->dev
);
812 dev_err(&smaster
->dev
, "failed to register device: %d\n", ret
);
814 goto err_device_register
;
817 smaster
->num_devices
++;
818 list_add_tail(&sdevice
->node
, &smaster
->devices
);
820 smaster
->setbuf_len
+= sdevice
->inbytes
;
821 smaster
->getbuf_len
+= sdevice
->outbytes
;
823 sdevice
->status_errors_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
825 sdevice
->watchdog_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
827 sdevice
->watchdog_errors_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
829 sdevice
->connected_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
832 siox_master_unlock(smaster
);
837 /* don't care to make the buffer smaller again */
840 siox_master_unlock(smaster
);
847 static void siox_device_remove(struct siox_master
*smaster
)
849 struct siox_device
*sdevice
;
851 siox_master_lock(smaster
);
853 if (!smaster
->num_devices
) {
854 siox_master_unlock(smaster
);
858 sdevice
= container_of(smaster
->devices
.prev
, struct siox_device
, node
);
859 list_del(&sdevice
->node
);
860 smaster
->num_devices
--;
862 smaster
->setbuf_len
-= sdevice
->inbytes
;
863 smaster
->getbuf_len
-= sdevice
->outbytes
;
865 if (!smaster
->num_devices
)
866 __siox_stop(smaster
);
868 siox_master_unlock(smaster
);
871 * This must be done without holding the master lock because we're
872 * called from device_remove_store which also holds a sysfs mutex.
873 * device_unregister tries to aquire the same lock.
875 device_unregister(&sdevice
->dev
);
878 int __siox_driver_register(struct siox_driver
*sdriver
, struct module
*owner
)
882 if (unlikely(!siox_is_registered
))
883 return -EPROBE_DEFER
;
885 if (!sdriver
->set_data
&& !sdriver
->get_data
) {
886 pr_err("Driver %s doesn't provide needed callbacks\n",
887 sdriver
->driver
.name
);
891 sdriver
->driver
.owner
= owner
;
892 sdriver
->driver
.bus
= &siox_bus_type
;
895 sdriver
->driver
.probe
= siox_driver_probe
;
897 sdriver
->driver
.remove
= siox_driver_remove
;
898 if (sdriver
->shutdown
)
899 sdriver
->driver
.shutdown
= siox_driver_shutdown
;
901 ret
= driver_register(&sdriver
->driver
);
903 pr_err("Failed to register siox driver %s (%d)\n",
904 sdriver
->driver
.name
, ret
);
908 EXPORT_SYMBOL_GPL(__siox_driver_register
);
910 static int __init
siox_init(void)
914 ret
= bus_register(&siox_bus_type
);
916 pr_err("Registration of SIOX bus type failed: %d\n", ret
);
920 siox_is_registered
= true;
924 subsys_initcall(siox_init
);
926 static void __exit
siox_exit(void)
928 bus_unregister(&siox_bus_type
);
930 module_exit(siox_exit
);
932 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
933 MODULE_DESCRIPTION("Eckelmann SIOX driver core");
934 MODULE_LICENSE("GPL v2");