Lines Matching +full:re +full:- +full:clocked

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015-2017 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
14 * The lowest bit in the SIOX status word signals if the in-device watchdog is
23 * clocked in before. The value clocked in is changed in each cycle and so
29 * Each Siox-Device has a 4 bit type number that is neither 0 nor 15. This is
43 mutex_lock(&smaster->lock); in siox_master_lock()
48 mutex_unlock(&smaster->lock); in siox_master_unlock()
83 if (sdevice->statustype) { in siox_device_type_error()
84 if (statustype != sdevice->statustype) in siox_device_type_error()
107 if (siox_device_type_error(sdevice, sdevice->status_read_clean)) in siox_device_synced()
110 return !siox_device_counter_error(sdevice, sdevice->status_read_clean); in siox_device_synced()
124 return !siox_device_wdg_error(sdevice, sdevice->status_read_clean); in siox_device_connected()
131 size_t i = smaster->setbuf_len; in siox_poll()
135 smaster->last_poll = jiffies; in siox_poll()
144 * with a stuck-at-0 error. But for the same reason (with s/0/1/) 0 in siox_poll()
147 if (++smaster->status > 0x0d) in siox_poll()
148 smaster->status = 0; in siox_poll()
150 memset(smaster->buf, 0, smaster->setbuf_len); in siox_poll()
153 list_for_each_entry(sdevice, &smaster->devices, node) { in siox_poll()
155 to_siox_driver(sdevice->dev.driver); in siox_poll()
156 sdevice->status_written = smaster->status; in siox_poll()
158 i -= sdevice->inbytes; in siox_poll()
169 sdriver->set_data(sdevice, sdevice->status_written, in siox_poll()
170 &smaster->buf[i + 1]); in siox_poll()
176 sdevice->status_written &= ~SIOX_STATUS_WDG; in siox_poll()
178 smaster->buf[i] = sdevice->status_written; in siox_poll()
185 smaster->pushpull(smaster, smaster->setbuf_len, smaster->buf, in siox_poll()
186 smaster->getbuf_len, in siox_poll()
187 smaster->buf + smaster->setbuf_len); in siox_poll()
193 i = smaster->setbuf_len; in siox_poll()
194 list_for_each_entry(sdevice, &smaster->devices, node) { in siox_poll()
196 to_siox_driver(sdevice->dev.driver); in siox_poll()
197 u8 status = smaster->buf[i + sdevice->outbytes - 1]; in siox_poll()
199 u8 prev_status_clean = sdevice->status_read_clean; in siox_poll()
216 sdevice->status_written_lastcycle); in siox_poll()
233 sdevice->status_errors++; in siox_poll()
234 sysfs_notify_dirent(sdevice->status_errors_kn); in siox_poll()
249 sysfs_notify_dirent(sdevice->watchdog_kn); in siox_poll()
253 sdevice->watchdog_errors_kn; in siox_poll()
255 sdevice->watchdog_errors++; in siox_poll()
260 if (connected != sdevice->connected) in siox_poll()
261 sysfs_notify_dirent(sdevice->connected_kn); in siox_poll()
263 sdevice->status_read_clean = status_clean; in siox_poll()
264 sdevice->status_written_lastcycle = sdevice->status_written; in siox_poll()
265 sdevice->connected = connected; in siox_poll()
271 sdriver->get_data(sdevice, &smaster->buf[i]); in siox_poll()
274 i += sdevice->outbytes; in siox_poll()
283 get_device(&smaster->dev); in siox_poll_thread()
287 put_device(&smaster->dev); in siox_poll_thread()
293 if (smaster->active) { in siox_poll_thread()
295 smaster->last_poll + smaster->poll_interval; in siox_poll_thread()
299 timeout = smaster->poll_interval - in siox_poll_thread()
300 (jiffies - smaster->last_poll); in siox_poll_thread()
321 * !TASK_RUNNING;"-warning. in siox_poll_thread()
329 if (!(smaster->setbuf_len + smaster->getbuf_len)) in __siox_start()
330 return -ENODEV; in __siox_start()
332 if (!smaster->buf) in __siox_start()
333 return -ENOMEM; in __siox_start()
335 if (smaster->active) in __siox_start()
338 smaster->active = 1; in __siox_start()
339 wake_up_process(smaster->poll_thread); in __siox_start()
357 if (smaster->active) { in __siox_stop()
360 smaster->active = 0; in __siox_stop()
362 list_for_each_entry(sdevice, &smaster->devices, node) { in __siox_stop()
363 if (sdevice->connected) in __siox_stop()
364 sysfs_notify_dirent(sdevice->connected_kn); in __siox_stop()
365 sdevice->connected = false; in __siox_stop()
389 return sprintf(buf, "%s\n", sdev->type); in type_show()
399 return sprintf(buf, "%zu\n", sdev->inbytes); in inbytes_show()
409 return sprintf(buf, "%zu\n", sdev->outbytes); in outbytes_show()
420 siox_master_lock(sdev->smaster); in status_errors_show()
422 status_errors = sdev->status_errors; in status_errors_show()
424 siox_master_unlock(sdev->smaster); in status_errors_show()
437 siox_master_lock(sdev->smaster); in connected_show()
439 connected = sdev->connected; in connected_show()
441 siox_master_unlock(sdev->smaster); in connected_show()
454 siox_master_lock(sdev->smaster); in watchdog_show()
456 status = sdev->status_read_clean; in watchdog_show()
458 siox_master_unlock(sdev->smaster); in watchdog_show()
471 siox_master_lock(sdev->smaster); in watchdog_errors_show()
473 watchdog_errors = sdev->watchdog_errors; in watchdog_errors_show()
475 siox_master_unlock(sdev->smaster); in watchdog_errors_show()
508 if (dev->type != &siox_device_type) in siox_match()
517 struct siox_driver *sdriver = to_siox_driver(dev->driver); in siox_probe()
520 return sdriver->probe(sdevice); in siox_probe()
526 container_of(dev->driver, struct siox_driver, driver); in siox_remove()
529 if (sdriver->remove) in siox_remove()
530 sdriver->remove(sdevice); in siox_remove()
538 if (!dev->driver) in siox_shutdown()
541 sdriver = container_of(dev->driver, struct siox_driver, driver); in siox_shutdown()
542 if (sdriver->shutdown) in siox_shutdown()
543 sdriver->shutdown(sdevice); in siox_shutdown()
559 return sprintf(buf, "%d\n", smaster->active); in active_show()
604 return -EINVAL; in device_add_store()
606 if (strcmp(type, "siox-12x8") || inbytes != 2 || outbytes != 4) in device_add_store()
607 return -EINVAL; in device_add_store()
609 siox_device_add(smaster, "siox-12x8", inbytes, outbytes, statustype); in device_add_store()
637 return sprintf(buf, "%lld\n", jiffies_to_nsecs(smaster->poll_interval)); in poll_interval_ns_show()
654 smaster->poll_interval = nsecs_to_jiffies(val); in poll_interval_ns_store()
696 device_initialize(&smaster->dev); in siox_master_alloc()
698 smaster->busno = -1; in siox_master_alloc()
699 smaster->dev.bus = &siox_bus_type; in siox_master_alloc()
700 smaster->dev.type = &siox_master_type; in siox_master_alloc()
701 smaster->dev.parent = dev; in siox_master_alloc()
702 smaster->poll_interval = DIV_ROUND_UP(HZ, 40); in siox_master_alloc()
704 dev_set_drvdata(&smaster->dev, &smaster[1]); in siox_master_alloc()
740 return -EPROBE_DEFER; in siox_master_register()
742 if (!smaster->pushpull) in siox_master_register()
743 return -EINVAL; in siox_master_register()
745 get_device(&smaster->dev); in siox_master_register()
747 dev_set_name(&smaster->dev, "siox-%d", smaster->busno); in siox_master_register()
749 mutex_init(&smaster->lock); in siox_master_register()
750 INIT_LIST_HEAD(&smaster->devices); in siox_master_register()
752 smaster->last_poll = jiffies; in siox_master_register()
753 smaster->poll_thread = kthread_run(siox_poll_thread, smaster, in siox_master_register()
754 "siox-%d", smaster->busno); in siox_master_register()
755 if (IS_ERR(smaster->poll_thread)) { in siox_master_register()
756 smaster->active = 0; in siox_master_register()
757 return PTR_ERR(smaster->poll_thread); in siox_master_register()
760 ret = device_add(&smaster->dev); in siox_master_register()
762 kthread_stop(smaster->poll_thread); in siox_master_register()
771 device_del(&smaster->dev); in siox_master_unregister()
777 while (smaster->num_devices) { in siox_master_unregister()
780 sdevice = container_of(smaster->devices.prev, in siox_master_unregister()
782 list_del(&sdevice->node); in siox_master_unregister()
783 smaster->num_devices--; in siox_master_unregister()
787 device_unregister(&sdevice->dev); in siox_master_unregister()
794 put_device(&smaster->dev); in siox_master_unregister()
827 return ERR_PTR(-ENOMEM); in siox_device_add()
829 sdevice->type = type; in siox_device_add()
830 sdevice->inbytes = inbytes; in siox_device_add()
831 sdevice->outbytes = outbytes; in siox_device_add()
832 sdevice->statustype = statustype; in siox_device_add()
834 sdevice->smaster = smaster; in siox_device_add()
835 sdevice->dev.parent = &smaster->dev; in siox_device_add()
836 sdevice->dev.bus = &siox_bus_type; in siox_device_add()
837 sdevice->dev.type = &siox_device_type; in siox_device_add()
841 dev_set_name(&sdevice->dev, "siox-%d-%d", in siox_device_add()
842 smaster->busno, smaster->num_devices); in siox_device_add()
844 buf_len = smaster->setbuf_len + inbytes + in siox_device_add()
845 smaster->getbuf_len + outbytes; in siox_device_add()
846 if (smaster->buf_len < buf_len) { in siox_device_add()
847 u8 *buf = krealloc(smaster->buf, buf_len, GFP_KERNEL); in siox_device_add()
850 dev_err(&smaster->dev, in siox_device_add()
852 ret = -ENOMEM; in siox_device_add()
856 smaster->buf_len = buf_len; in siox_device_add()
857 smaster->buf = buf; in siox_device_add()
860 ret = device_register(&sdevice->dev); in siox_device_add()
862 dev_err(&smaster->dev, "failed to register device: %d\n", ret); in siox_device_add()
867 smaster->num_devices++; in siox_device_add()
868 list_add_tail(&sdevice->node, &smaster->devices); in siox_device_add()
870 smaster->setbuf_len += sdevice->inbytes; in siox_device_add()
871 smaster->getbuf_len += sdevice->outbytes; in siox_device_add()
873 sdevice->status_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd, in siox_device_add()
875 sdevice->watchdog_kn = sysfs_get_dirent(sdevice->dev.kobj.sd, in siox_device_add()
877 sdevice->watchdog_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd, in siox_device_add()
879 sdevice->connected_kn = sysfs_get_dirent(sdevice->dev.kobj.sd, in siox_device_add()
888 put_device(&sdevice->dev); in siox_device_add()
905 if (!smaster->num_devices) { in siox_device_remove()
910 sdevice = container_of(smaster->devices.prev, struct siox_device, node); in siox_device_remove()
911 list_del(&sdevice->node); in siox_device_remove()
912 smaster->num_devices--; in siox_device_remove()
914 smaster->setbuf_len -= sdevice->inbytes; in siox_device_remove()
915 smaster->getbuf_len -= sdevice->outbytes; in siox_device_remove()
917 if (!smaster->num_devices) in siox_device_remove()
923 * This must be done without holding the master lock because we're in siox_device_remove()
927 device_unregister(&sdevice->dev); in siox_device_remove()
935 return -EPROBE_DEFER; in __siox_driver_register()
937 if (!sdriver->probe || in __siox_driver_register()
938 (!sdriver->set_data && !sdriver->get_data)) { in __siox_driver_register()
940 sdriver->driver.name); in __siox_driver_register()
941 return -EINVAL; in __siox_driver_register()
944 sdriver->driver.owner = owner; in __siox_driver_register()
945 sdriver->driver.bus = &siox_bus_type; in __siox_driver_register()
947 ret = driver_register(&sdriver->driver); in __siox_driver_register()
950 sdriver->driver.name, ret); in __siox_driver_register()
978 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");