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 int siox_probe(struct device
*dev
)
517 struct siox_driver
*sdriver
= to_siox_driver(dev
->driver
);
518 struct siox_device
*sdevice
= to_siox_device(dev
);
520 return sdriver
->probe(sdevice
);
523 static int siox_remove(struct device
*dev
)
525 struct siox_driver
*sdriver
=
526 container_of(dev
->driver
, struct siox_driver
, driver
);
527 struct siox_device
*sdevice
= to_siox_device(dev
);
530 sdriver
->remove(sdevice
);
535 static void siox_shutdown(struct device
*dev
)
537 struct siox_device
*sdevice
= to_siox_device(dev
);
538 struct siox_driver
*sdriver
;
543 sdriver
= container_of(dev
->driver
, struct siox_driver
, driver
);
544 if (sdriver
->shutdown
)
545 sdriver
->shutdown(sdevice
);
548 static struct bus_type siox_bus_type
= {
552 .remove
= siox_remove
,
553 .shutdown
= siox_shutdown
,
556 static ssize_t
active_show(struct device
*dev
,
557 struct device_attribute
*attr
, char *buf
)
559 struct siox_master
*smaster
= to_siox_master(dev
);
561 return sprintf(buf
, "%d\n", smaster
->active
);
564 static ssize_t
active_store(struct device
*dev
,
565 struct device_attribute
*attr
,
566 const char *buf
, size_t count
)
568 struct siox_master
*smaster
= to_siox_master(dev
);
572 ret
= kstrtoint(buf
, 0, &active
);
577 ret
= siox_start(smaster
);
579 ret
= siox_stop(smaster
);
587 static DEVICE_ATTR_RW(active
);
589 static struct siox_device
*siox_device_add(struct siox_master
*smaster
,
590 const char *type
, size_t inbytes
,
591 size_t outbytes
, u8 statustype
);
593 static ssize_t
device_add_store(struct device
*dev
,
594 struct device_attribute
*attr
,
595 const char *buf
, size_t count
)
597 struct siox_master
*smaster
= to_siox_master(dev
);
600 size_t inbytes
= 0, outbytes
= 0;
603 ret
= sscanf(buf
, "%19s %zu %zu %hhu", type
, &inbytes
,
604 &outbytes
, &statustype
);
605 if (ret
!= 3 && ret
!= 4)
608 if (strcmp(type
, "siox-12x8") || inbytes
!= 2 || outbytes
!= 4)
611 siox_device_add(smaster
, "siox-12x8", inbytes
, outbytes
, statustype
);
616 static DEVICE_ATTR_WO(device_add
);
618 static void siox_device_remove(struct siox_master
*smaster
);
620 static ssize_t
device_remove_store(struct device
*dev
,
621 struct device_attribute
*attr
,
622 const char *buf
, size_t count
)
624 struct siox_master
*smaster
= to_siox_master(dev
);
626 /* XXX? require to write <type> <inbytes> <outbytes> */
627 siox_device_remove(smaster
);
632 static DEVICE_ATTR_WO(device_remove
);
634 static ssize_t
poll_interval_ns_show(struct device
*dev
,
635 struct device_attribute
*attr
, char *buf
)
637 struct siox_master
*smaster
= to_siox_master(dev
);
639 return sprintf(buf
, "%lld\n", jiffies_to_nsecs(smaster
->poll_interval
));
642 static ssize_t
poll_interval_ns_store(struct device
*dev
,
643 struct device_attribute
*attr
,
644 const char *buf
, size_t count
)
646 struct siox_master
*smaster
= to_siox_master(dev
);
650 ret
= kstrtou64(buf
, 0, &val
);
654 siox_master_lock(smaster
);
656 smaster
->poll_interval
= nsecs_to_jiffies(val
);
658 siox_master_unlock(smaster
);
663 static DEVICE_ATTR_RW(poll_interval_ns
);
665 static struct attribute
*siox_master_attrs
[] = {
666 &dev_attr_active
.attr
,
667 &dev_attr_device_add
.attr
,
668 &dev_attr_device_remove
.attr
,
669 &dev_attr_poll_interval_ns
.attr
,
672 ATTRIBUTE_GROUPS(siox_master
);
674 static void siox_master_release(struct device
*dev
)
676 struct siox_master
*smaster
= to_siox_master(dev
);
681 static struct device_type siox_master_type
= {
682 .groups
= siox_master_groups
,
683 .release
= siox_master_release
,
686 struct siox_master
*siox_master_alloc(struct device
*dev
,
689 struct siox_master
*smaster
;
694 smaster
= kzalloc(sizeof(*smaster
) + size
, GFP_KERNEL
);
698 device_initialize(&smaster
->dev
);
701 smaster
->dev
.bus
= &siox_bus_type
;
702 smaster
->dev
.type
= &siox_master_type
;
703 smaster
->dev
.parent
= dev
;
704 smaster
->poll_interval
= DIV_ROUND_UP(HZ
, 40);
706 dev_set_drvdata(&smaster
->dev
, &smaster
[1]);
710 EXPORT_SYMBOL_GPL(siox_master_alloc
);
712 int siox_master_register(struct siox_master
*smaster
)
716 if (!siox_is_registered
)
717 return -EPROBE_DEFER
;
719 if (!smaster
->pushpull
)
722 dev_set_name(&smaster
->dev
, "siox-%d", smaster
->busno
);
724 mutex_init(&smaster
->lock
);
725 INIT_LIST_HEAD(&smaster
->devices
);
727 smaster
->last_poll
= jiffies
;
728 smaster
->poll_thread
= kthread_run(siox_poll_thread
, smaster
,
729 "siox-%d", smaster
->busno
);
730 if (IS_ERR(smaster
->poll_thread
)) {
732 return PTR_ERR(smaster
->poll_thread
);
735 ret
= device_add(&smaster
->dev
);
737 kthread_stop(smaster
->poll_thread
);
741 EXPORT_SYMBOL_GPL(siox_master_register
);
743 void siox_master_unregister(struct siox_master
*smaster
)
746 device_del(&smaster
->dev
);
748 siox_master_lock(smaster
);
750 __siox_stop(smaster
);
752 while (smaster
->num_devices
) {
753 struct siox_device
*sdevice
;
755 sdevice
= container_of(smaster
->devices
.prev
,
756 struct siox_device
, node
);
757 list_del(&sdevice
->node
);
758 smaster
->num_devices
--;
760 siox_master_unlock(smaster
);
762 device_unregister(&sdevice
->dev
);
764 siox_master_lock(smaster
);
767 siox_master_unlock(smaster
);
769 put_device(&smaster
->dev
);
771 EXPORT_SYMBOL_GPL(siox_master_unregister
);
773 static struct siox_device
*siox_device_add(struct siox_master
*smaster
,
774 const char *type
, size_t inbytes
,
775 size_t outbytes
, u8 statustype
)
777 struct siox_device
*sdevice
;
781 sdevice
= kzalloc(sizeof(*sdevice
), GFP_KERNEL
);
783 return ERR_PTR(-ENOMEM
);
785 sdevice
->type
= type
;
786 sdevice
->inbytes
= inbytes
;
787 sdevice
->outbytes
= outbytes
;
788 sdevice
->statustype
= statustype
;
790 sdevice
->smaster
= smaster
;
791 sdevice
->dev
.parent
= &smaster
->dev
;
792 sdevice
->dev
.bus
= &siox_bus_type
;
793 sdevice
->dev
.type
= &siox_device_type
;
795 siox_master_lock(smaster
);
797 dev_set_name(&sdevice
->dev
, "siox-%d-%d",
798 smaster
->busno
, smaster
->num_devices
);
800 buf_len
= smaster
->setbuf_len
+ inbytes
+
801 smaster
->getbuf_len
+ outbytes
;
802 if (smaster
->buf_len
< buf_len
) {
803 u8
*buf
= krealloc(smaster
->buf
, buf_len
, GFP_KERNEL
);
806 dev_err(&smaster
->dev
,
807 "failed to realloc buffer to %zu\n", buf_len
);
812 smaster
->buf_len
= buf_len
;
816 ret
= device_register(&sdevice
->dev
);
818 dev_err(&smaster
->dev
, "failed to register device: %d\n", ret
);
820 goto err_device_register
;
823 smaster
->num_devices
++;
824 list_add_tail(&sdevice
->node
, &smaster
->devices
);
826 smaster
->setbuf_len
+= sdevice
->inbytes
;
827 smaster
->getbuf_len
+= sdevice
->outbytes
;
829 sdevice
->status_errors_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
831 sdevice
->watchdog_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
833 sdevice
->watchdog_errors_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
835 sdevice
->connected_kn
= sysfs_get_dirent(sdevice
->dev
.kobj
.sd
,
838 siox_master_unlock(smaster
);
843 /* don't care to make the buffer smaller again */
846 siox_master_unlock(smaster
);
853 static void siox_device_remove(struct siox_master
*smaster
)
855 struct siox_device
*sdevice
;
857 siox_master_lock(smaster
);
859 if (!smaster
->num_devices
) {
860 siox_master_unlock(smaster
);
864 sdevice
= container_of(smaster
->devices
.prev
, struct siox_device
, node
);
865 list_del(&sdevice
->node
);
866 smaster
->num_devices
--;
868 smaster
->setbuf_len
-= sdevice
->inbytes
;
869 smaster
->getbuf_len
-= sdevice
->outbytes
;
871 if (!smaster
->num_devices
)
872 __siox_stop(smaster
);
874 siox_master_unlock(smaster
);
877 * This must be done without holding the master lock because we're
878 * called from device_remove_store which also holds a sysfs mutex.
879 * device_unregister tries to aquire the same lock.
881 device_unregister(&sdevice
->dev
);
884 int __siox_driver_register(struct siox_driver
*sdriver
, struct module
*owner
)
888 if (unlikely(!siox_is_registered
))
889 return -EPROBE_DEFER
;
891 if (!sdriver
->probe
||
892 (!sdriver
->set_data
&& !sdriver
->get_data
)) {
893 pr_err("Driver %s doesn't provide needed callbacks\n",
894 sdriver
->driver
.name
);
898 sdriver
->driver
.owner
= owner
;
899 sdriver
->driver
.bus
= &siox_bus_type
;
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");