981 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2015-2017 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>4 */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>10 11#include "siox.h"12 13/*14 * The lowest bit in the SIOX status word signals if the in-device watchdog is15 * ok. If the bit is set, the device is functional.16 *17 * On writing the watchdog timer is reset when this bit toggles.18 */19#define SIOX_STATUS_WDG 0x0120 21/*22 * Bits 1 to 3 of the status word read as the bitwise negation of what was23 * clocked in before. The value clocked in is changed in each cycle and so24 * allows to detect transmit/receive problems.25 */26#define SIOX_STATUS_COUNTER 0x0e27 28/*29 * Each Siox-Device has a 4 bit type number that is neither 0 nor 15. This is30 * available in the upper nibble of the read status.31 *32 * On write these bits are DC.33 */34#define SIOX_STATUS_TYPE 0xf035 36#define CREATE_TRACE_POINTS37#include <trace/events/siox.h>38 39static bool siox_is_registered;40 41static void siox_master_lock(struct siox_master *smaster)42{43 mutex_lock(&smaster->lock);44}45 46static void siox_master_unlock(struct siox_master *smaster)47{48 mutex_unlock(&smaster->lock);49}50 51static inline u8 siox_status_clean(u8 status_read, u8 status_written)52{53 /*54 * bits 3:1 of status sample the respective bit in the status55 * byte written in the previous cycle but inverted. So if you wrote the56 * status word as 0xa before (counter = 0b101), it is expected to get57 * back the counter bits as 0b010.58 *59 * So given the last status written this function toggles the there60 * unset counter bits in the read value such that the counter bits in61 * the return value are all zero iff the bits were read as expected to62 * simplify error detection.63 */64 65 return status_read ^ (~status_written & 0xe);66}67 68static bool siox_device_counter_error(struct siox_device *sdevice,69 u8 status_clean)70{71 return (status_clean & SIOX_STATUS_COUNTER) != 0;72}73 74static bool siox_device_type_error(struct siox_device *sdevice, u8 status_clean)75{76 u8 statustype = (status_clean & SIOX_STATUS_TYPE) >> 4;77 78 /*79 * If the device knows which value the type bits should have, check80 * against this value otherwise just rule out the invalid values 0b000081 * and 0b1111.82 */83 if (sdevice->statustype) {84 if (statustype != sdevice->statustype)85 return true;86 } else {87 switch (statustype) {88 case 0:89 case 0xf:90 return true;91 }92 }93 94 return false;95}96 97static bool siox_device_wdg_error(struct siox_device *sdevice, u8 status_clean)98{99 return (status_clean & SIOX_STATUS_WDG) == 0;100}101 102/*103 * If there is a type or counter error the device is called "unsynced".104 */105bool siox_device_synced(struct siox_device *sdevice)106{107 if (siox_device_type_error(sdevice, sdevice->status_read_clean))108 return false;109 110 return !siox_device_counter_error(sdevice, sdevice->status_read_clean);111 112}113EXPORT_SYMBOL_GPL(siox_device_synced);114 115/*116 * A device is called "connected" if it is synced and the watchdog is not117 * asserted.118 */119bool siox_device_connected(struct siox_device *sdevice)120{121 if (!siox_device_synced(sdevice))122 return false;123 124 return !siox_device_wdg_error(sdevice, sdevice->status_read_clean);125}126EXPORT_SYMBOL_GPL(siox_device_connected);127 128static void siox_poll(struct siox_master *smaster)129{130 struct siox_device *sdevice;131 size_t i = smaster->setbuf_len;132 unsigned int devno = 0;133 int unsync_error = 0;134 135 smaster->last_poll = jiffies;136 137 /*138 * The counter bits change in each second cycle, the watchdog bit139 * toggles each time.140 * The counter bits hold values from [0, 6]. 7 would be possible141 * theoretically but the protocol designer considered that a bad idea142 * for reasons unknown today. (Maybe that's because then the status read143 * back has only zeros in the counter bits then which might be confused144 * with a stuck-at-0 error. But for the same reason (with s/0/1/) 0145 * could be skipped.)146 */147 if (++smaster->status > 0x0d)148 smaster->status = 0;149 150 memset(smaster->buf, 0, smaster->setbuf_len);151 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;157 158 i -= sdevice->inbytes;159 160 /*161 * If the device or a previous one is unsynced, don't pet the162 * watchdog. This is done to ensure that the device is kept in163 * reset when something is wrong.164 */165 if (!siox_device_synced(sdevice))166 unsync_error = 1;167 168 if (sdriver && !unsync_error)169 sdriver->set_data(sdevice, sdevice->status_written,170 &smaster->buf[i + 1]);171 else172 /*173 * Don't trigger watchdog if there is no driver or a174 * sync problem175 */176 sdevice->status_written &= ~SIOX_STATUS_WDG;177 178 smaster->buf[i] = sdevice->status_written;179 180 trace_siox_set_data(smaster, sdevice, devno, i);181 182 devno++;183 }184 185 smaster->pushpull(smaster, smaster->setbuf_len, smaster->buf,186 smaster->getbuf_len,187 smaster->buf + smaster->setbuf_len);188 189 unsync_error = 0;190 191 /* interpret data pulled in from devices in buf[setbuf_len..] */192 devno = 0;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];198 u8 status_clean;199 u8 prev_status_clean = sdevice->status_read_clean;200 bool synced = true;201 bool connected = true;202 203 if (!siox_device_synced(sdevice))204 unsync_error = 1;205 206 /*207 * If the watchdog bit wasn't toggled in this cycle, report the208 * watchdog as active to give a consistent view for drivers and209 * sysfs consumers.210 */211 if (!sdriver || unsync_error)212 status &= ~SIOX_STATUS_WDG;213 214 status_clean =215 siox_status_clean(status,216 sdevice->status_written_lastcycle);217 218 /* Check counter and type bits */219 if (siox_device_counter_error(sdevice, status_clean) ||220 siox_device_type_error(sdevice, status_clean)) {221 bool prev_error;222 223 synced = false;224 225 /* only report a new error if the last cycle was ok */226 prev_error =227 siox_device_counter_error(sdevice,228 prev_status_clean) ||229 siox_device_type_error(sdevice,230 prev_status_clean);231 232 if (!prev_error) {233 sdevice->status_errors++;234 sysfs_notify_dirent(sdevice->status_errors_kn);235 }236 }237 238 /* If the device is unsynced report the watchdog as active */239 if (!synced) {240 status &= ~SIOX_STATUS_WDG;241 status_clean &= ~SIOX_STATUS_WDG;242 }243 244 if (siox_device_wdg_error(sdevice, status_clean))245 connected = false;246 247 /* The watchdog state changed just now */248 if ((status_clean ^ prev_status_clean) & SIOX_STATUS_WDG) {249 sysfs_notify_dirent(sdevice->watchdog_kn);250 251 if (siox_device_wdg_error(sdevice, status_clean)) {252 struct kernfs_node *wd_errs =253 sdevice->watchdog_errors_kn;254 255 sdevice->watchdog_errors++;256 sysfs_notify_dirent(wd_errs);257 }258 }259 260 if (connected != sdevice->connected)261 sysfs_notify_dirent(sdevice->connected_kn);262 263 sdevice->status_read_clean = status_clean;264 sdevice->status_written_lastcycle = sdevice->status_written;265 sdevice->connected = connected;266 267 trace_siox_get_data(smaster, sdevice, devno, status_clean, i);268 269 /* only give data read to driver if the device is connected */270 if (sdriver && connected)271 sdriver->get_data(sdevice, &smaster->buf[i]);272 273 devno++;274 i += sdevice->outbytes;275 }276}277 278static int siox_poll_thread(void *data)279{280 struct siox_master *smaster = data;281 signed long timeout = 0;282 283 get_device(&smaster->dev);284 285 for (;;) {286 if (kthread_should_stop()) {287 put_device(&smaster->dev);288 return 0;289 }290 291 siox_master_lock(smaster);292 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))297 siox_poll(smaster);298 299 timeout = smaster->poll_interval -300 (jiffies - smaster->last_poll);301 } else {302 timeout = MAX_SCHEDULE_TIMEOUT;303 }304 305 /*306 * Set the task to idle while holding the lock. This makes sure307 * that we don't sleep too long when the bus is reenabled before308 * schedule_timeout is reached.309 */310 if (timeout > 0)311 set_current_state(TASK_IDLE);312 313 siox_master_unlock(smaster);314 315 if (timeout > 0)316 schedule_timeout(timeout);317 318 /*319 * I'm not clear if/why it is important to set the state to320 * RUNNING again, but it fixes a "do not call blocking ops when321 * !TASK_RUNNING;"-warning.322 */323 set_current_state(TASK_RUNNING);324 }325}326 327static int __siox_start(struct siox_master *smaster)328{329 if (!(smaster->setbuf_len + smaster->getbuf_len))330 return -ENODEV;331 332 if (!smaster->buf)333 return -ENOMEM;334 335 if (smaster->active)336 return 0;337 338 smaster->active = 1;339 wake_up_process(smaster->poll_thread);340 341 return 1;342}343 344static int siox_start(struct siox_master *smaster)345{346 int ret;347 348 siox_master_lock(smaster);349 ret = __siox_start(smaster);350 siox_master_unlock(smaster);351 352 return ret;353}354 355static int __siox_stop(struct siox_master *smaster)356{357 if (smaster->active) {358 struct siox_device *sdevice;359 360 smaster->active = 0;361 362 list_for_each_entry(sdevice, &smaster->devices, node) {363 if (sdevice->connected)364 sysfs_notify_dirent(sdevice->connected_kn);365 sdevice->connected = false;366 }367 368 return 1;369 }370 return 0;371}372 373static int siox_stop(struct siox_master *smaster)374{375 int ret;376 377 siox_master_lock(smaster);378 ret = __siox_stop(smaster);379 siox_master_unlock(smaster);380 381 return ret;382}383 384static ssize_t type_show(struct device *dev,385 struct device_attribute *attr, char *buf)386{387 struct siox_device *sdev = to_siox_device(dev);388 389 return sprintf(buf, "%s\n", sdev->type);390}391 392static DEVICE_ATTR_RO(type);393 394static ssize_t inbytes_show(struct device *dev,395 struct device_attribute *attr, char *buf)396{397 struct siox_device *sdev = to_siox_device(dev);398 399 return sprintf(buf, "%zu\n", sdev->inbytes);400}401 402static DEVICE_ATTR_RO(inbytes);403 404static ssize_t outbytes_show(struct device *dev,405 struct device_attribute *attr, char *buf)406{407 struct siox_device *sdev = to_siox_device(dev);408 409 return sprintf(buf, "%zu\n", sdev->outbytes);410}411 412static DEVICE_ATTR_RO(outbytes);413 414static ssize_t status_errors_show(struct device *dev,415 struct device_attribute *attr, char *buf)416{417 struct siox_device *sdev = to_siox_device(dev);418 unsigned int status_errors;419 420 siox_master_lock(sdev->smaster);421 422 status_errors = sdev->status_errors;423 424 siox_master_unlock(sdev->smaster);425 426 return sprintf(buf, "%u\n", status_errors);427}428 429static DEVICE_ATTR_RO(status_errors);430 431static ssize_t connected_show(struct device *dev,432 struct device_attribute *attr, char *buf)433{434 struct siox_device *sdev = to_siox_device(dev);435 bool connected;436 437 siox_master_lock(sdev->smaster);438 439 connected = sdev->connected;440 441 siox_master_unlock(sdev->smaster);442 443 return sprintf(buf, "%u\n", connected);444}445 446static DEVICE_ATTR_RO(connected);447 448static ssize_t watchdog_show(struct device *dev,449 struct device_attribute *attr, char *buf)450{451 struct siox_device *sdev = to_siox_device(dev);452 u8 status;453 454 siox_master_lock(sdev->smaster);455 456 status = sdev->status_read_clean;457 458 siox_master_unlock(sdev->smaster);459 460 return sprintf(buf, "%d\n", status & SIOX_STATUS_WDG);461}462 463static DEVICE_ATTR_RO(watchdog);464 465static ssize_t watchdog_errors_show(struct device *dev,466 struct device_attribute *attr, char *buf)467{468 struct siox_device *sdev = to_siox_device(dev);469 unsigned int watchdog_errors;470 471 siox_master_lock(sdev->smaster);472 473 watchdog_errors = sdev->watchdog_errors;474 475 siox_master_unlock(sdev->smaster);476 477 return sprintf(buf, "%u\n", watchdog_errors);478}479 480static DEVICE_ATTR_RO(watchdog_errors);481 482static struct attribute *siox_device_attrs[] = {483 &dev_attr_type.attr,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,490 NULL491};492ATTRIBUTE_GROUPS(siox_device);493 494static void siox_device_release(struct device *dev)495{496 struct siox_device *sdevice = to_siox_device(dev);497 498 kfree(sdevice);499}500 501static const struct device_type siox_device_type = {502 .groups = siox_device_groups,503 .release = siox_device_release,504};505 506static int siox_match(struct device *dev, const struct device_driver *drv)507{508 if (dev->type != &siox_device_type)509 return 0;510 511 /* up to now there is only a single driver so keeping this simple */512 return 1;513}514 515static int siox_probe(struct device *dev)516{517 struct siox_driver *sdriver = to_siox_driver(dev->driver);518 struct siox_device *sdevice = to_siox_device(dev);519 520 return sdriver->probe(sdevice);521}522 523static void siox_remove(struct device *dev)524{525 struct siox_driver *sdriver =526 container_of(dev->driver, struct siox_driver, driver);527 struct siox_device *sdevice = to_siox_device(dev);528 529 if (sdriver->remove)530 sdriver->remove(sdevice);531}532 533static void siox_shutdown(struct device *dev)534{535 struct siox_device *sdevice = to_siox_device(dev);536 struct siox_driver *sdriver;537 538 if (!dev->driver)539 return;540 541 sdriver = container_of(dev->driver, struct siox_driver, driver);542 if (sdriver->shutdown)543 sdriver->shutdown(sdevice);544}545 546static const struct bus_type siox_bus_type = {547 .name = "siox",548 .match = siox_match,549 .probe = siox_probe,550 .remove = siox_remove,551 .shutdown = siox_shutdown,552};553 554static ssize_t active_show(struct device *dev,555 struct device_attribute *attr, char *buf)556{557 struct siox_master *smaster = to_siox_master(dev);558 559 return sprintf(buf, "%d\n", smaster->active);560}561 562static ssize_t active_store(struct device *dev,563 struct device_attribute *attr,564 const char *buf, size_t count)565{566 struct siox_master *smaster = to_siox_master(dev);567 int ret;568 int active;569 570 ret = kstrtoint(buf, 0, &active);571 if (ret < 0)572 return ret;573 574 if (active)575 ret = siox_start(smaster);576 else577 ret = siox_stop(smaster);578 579 if (ret < 0)580 return ret;581 582 return count;583}584 585static DEVICE_ATTR_RW(active);586 587static struct siox_device *siox_device_add(struct siox_master *smaster,588 const char *type, size_t inbytes,589 size_t outbytes, u8 statustype);590 591static ssize_t device_add_store(struct device *dev,592 struct device_attribute *attr,593 const char *buf, size_t count)594{595 struct siox_master *smaster = to_siox_master(dev);596 int ret;597 char type[20] = "";598 size_t inbytes = 0, outbytes = 0;599 u8 statustype = 0;600 601 ret = sscanf(buf, "%19s %zu %zu %hhu", type, &inbytes,602 &outbytes, &statustype);603 if (ret != 3 && ret != 4)604 return -EINVAL;605 606 if (strcmp(type, "siox-12x8") || inbytes != 2 || outbytes != 4)607 return -EINVAL;608 609 siox_device_add(smaster, "siox-12x8", inbytes, outbytes, statustype);610 611 return count;612}613 614static DEVICE_ATTR_WO(device_add);615 616static void siox_device_remove(struct siox_master *smaster);617 618static ssize_t device_remove_store(struct device *dev,619 struct device_attribute *attr,620 const char *buf, size_t count)621{622 struct siox_master *smaster = to_siox_master(dev);623 624 /* XXX? require to write <type> <inbytes> <outbytes> */625 siox_device_remove(smaster);626 627 return count;628}629 630static DEVICE_ATTR_WO(device_remove);631 632static ssize_t poll_interval_ns_show(struct device *dev,633 struct device_attribute *attr, char *buf)634{635 struct siox_master *smaster = to_siox_master(dev);636 637 return sprintf(buf, "%lld\n", jiffies_to_nsecs(smaster->poll_interval));638}639 640static ssize_t poll_interval_ns_store(struct device *dev,641 struct device_attribute *attr,642 const char *buf, size_t count)643{644 struct siox_master *smaster = to_siox_master(dev);645 int ret;646 u64 val;647 648 ret = kstrtou64(buf, 0, &val);649 if (ret < 0)650 return ret;651 652 siox_master_lock(smaster);653 654 smaster->poll_interval = nsecs_to_jiffies(val);655 656 siox_master_unlock(smaster);657 658 return count;659}660 661static DEVICE_ATTR_RW(poll_interval_ns);662 663static struct attribute *siox_master_attrs[] = {664 &dev_attr_active.attr,665 &dev_attr_device_add.attr,666 &dev_attr_device_remove.attr,667 &dev_attr_poll_interval_ns.attr,668 NULL669};670ATTRIBUTE_GROUPS(siox_master);671 672static void siox_master_release(struct device *dev)673{674 struct siox_master *smaster = to_siox_master(dev);675 676 kfree(smaster);677}678 679static const struct device_type siox_master_type = {680 .groups = siox_master_groups,681 .release = siox_master_release,682};683 684struct siox_master *siox_master_alloc(struct device *dev,685 size_t size)686{687 struct siox_master *smaster;688 689 if (!dev)690 return NULL;691 692 smaster = kzalloc(sizeof(*smaster) + size, GFP_KERNEL);693 if (!smaster)694 return NULL;695 696 device_initialize(&smaster->dev);697 698 smaster->busno = -1;699 smaster->dev.bus = &siox_bus_type;700 smaster->dev.type = &siox_master_type;701 smaster->dev.parent = dev;702 smaster->poll_interval = DIV_ROUND_UP(HZ, 40);703 704 dev_set_drvdata(&smaster->dev, &smaster[1]);705 706 return smaster;707}708EXPORT_SYMBOL_GPL(siox_master_alloc);709 710static void devm_siox_master_put(void *data)711{712 struct siox_master *smaster = data;713 714 siox_master_put(smaster);715}716 717struct siox_master *devm_siox_master_alloc(struct device *dev,718 size_t size)719{720 struct siox_master *smaster;721 int ret;722 723 smaster = siox_master_alloc(dev, size);724 if (!smaster)725 return NULL;726 727 ret = devm_add_action_or_reset(dev, devm_siox_master_put, smaster);728 if (ret)729 return NULL;730 731 return smaster;732}733EXPORT_SYMBOL_GPL(devm_siox_master_alloc);734 735int siox_master_register(struct siox_master *smaster)736{737 int ret;738 739 if (!siox_is_registered)740 return -EPROBE_DEFER;741 742 if (!smaster->pushpull)743 return -EINVAL;744 745 get_device(&smaster->dev);746 747 dev_set_name(&smaster->dev, "siox-%d", smaster->busno);748 749 mutex_init(&smaster->lock);750 INIT_LIST_HEAD(&smaster->devices);751 752 smaster->last_poll = jiffies;753 smaster->poll_thread = kthread_run(siox_poll_thread, smaster,754 "siox-%d", smaster->busno);755 if (IS_ERR(smaster->poll_thread)) {756 smaster->active = 0;757 return PTR_ERR(smaster->poll_thread);758 }759 760 ret = device_add(&smaster->dev);761 if (ret)762 kthread_stop(smaster->poll_thread);763 764 return ret;765}766EXPORT_SYMBOL_GPL(siox_master_register);767 768void siox_master_unregister(struct siox_master *smaster)769{770 /* remove device */771 device_del(&smaster->dev);772 773 siox_master_lock(smaster);774 775 __siox_stop(smaster);776 777 while (smaster->num_devices) {778 struct siox_device *sdevice;779 780 sdevice = container_of(smaster->devices.prev,781 struct siox_device, node);782 list_del(&sdevice->node);783 smaster->num_devices--;784 785 siox_master_unlock(smaster);786 787 device_unregister(&sdevice->dev);788 789 siox_master_lock(smaster);790 }791 792 siox_master_unlock(smaster);793 794 put_device(&smaster->dev);795}796EXPORT_SYMBOL_GPL(siox_master_unregister);797 798static void devm_siox_master_unregister(void *data)799{800 struct siox_master *smaster = data;801 802 siox_master_unregister(smaster);803}804 805int devm_siox_master_register(struct device *dev, struct siox_master *smaster)806{807 int ret;808 809 ret = siox_master_register(smaster);810 if (ret)811 return ret;812 813 return devm_add_action_or_reset(dev, devm_siox_master_unregister, smaster);814}815EXPORT_SYMBOL_GPL(devm_siox_master_register);816 817static struct siox_device *siox_device_add(struct siox_master *smaster,818 const char *type, size_t inbytes,819 size_t outbytes, u8 statustype)820{821 struct siox_device *sdevice;822 int ret;823 size_t buf_len;824 825 sdevice = kzalloc(sizeof(*sdevice), GFP_KERNEL);826 if (!sdevice)827 return ERR_PTR(-ENOMEM);828 829 sdevice->type = type;830 sdevice->inbytes = inbytes;831 sdevice->outbytes = outbytes;832 sdevice->statustype = statustype;833 834 sdevice->smaster = smaster;835 sdevice->dev.parent = &smaster->dev;836 sdevice->dev.bus = &siox_bus_type;837 sdevice->dev.type = &siox_device_type;838 839 siox_master_lock(smaster);840 841 dev_set_name(&sdevice->dev, "siox-%d-%d",842 smaster->busno, smaster->num_devices);843 844 buf_len = smaster->setbuf_len + inbytes +845 smaster->getbuf_len + outbytes;846 if (smaster->buf_len < buf_len) {847 u8 *buf = krealloc(smaster->buf, buf_len, GFP_KERNEL);848 849 if (!buf) {850 dev_err(&smaster->dev,851 "failed to realloc buffer to %zu\n", buf_len);852 ret = -ENOMEM;853 goto err_buf_alloc;854 }855 856 smaster->buf_len = buf_len;857 smaster->buf = buf;858 }859 860 ret = device_register(&sdevice->dev);861 if (ret) {862 dev_err(&smaster->dev, "failed to register device: %d\n", ret);863 864 goto err_device_register;865 }866 867 smaster->num_devices++;868 list_add_tail(&sdevice->node, &smaster->devices);869 870 smaster->setbuf_len += sdevice->inbytes;871 smaster->getbuf_len += sdevice->outbytes;872 873 sdevice->status_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,874 "status_errors");875 sdevice->watchdog_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,876 "watchdog");877 sdevice->watchdog_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,878 "watchdog_errors");879 sdevice->connected_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,880 "connected");881 882 siox_master_unlock(smaster);883 884 return sdevice;885 886err_device_register:887 /* don't care to make the buffer smaller again */888 put_device(&sdevice->dev);889 sdevice = NULL;890 891err_buf_alloc:892 siox_master_unlock(smaster);893 894 kfree(sdevice);895 896 return ERR_PTR(ret);897}898 899static void siox_device_remove(struct siox_master *smaster)900{901 struct siox_device *sdevice;902 903 siox_master_lock(smaster);904 905 if (!smaster->num_devices) {906 siox_master_unlock(smaster);907 return;908 }909 910 sdevice = container_of(smaster->devices.prev, struct siox_device, node);911 list_del(&sdevice->node);912 smaster->num_devices--;913 914 smaster->setbuf_len -= sdevice->inbytes;915 smaster->getbuf_len -= sdevice->outbytes;916 917 if (!smaster->num_devices)918 __siox_stop(smaster);919 920 siox_master_unlock(smaster);921 922 /*923 * This must be done without holding the master lock because we're924 * called from device_remove_store which also holds a sysfs mutex.925 * device_unregister tries to aquire the same lock.926 */927 device_unregister(&sdevice->dev);928}929 930int __siox_driver_register(struct siox_driver *sdriver, struct module *owner)931{932 int ret;933 934 if (unlikely(!siox_is_registered))935 return -EPROBE_DEFER;936 937 if (!sdriver->probe ||938 (!sdriver->set_data && !sdriver->get_data)) {939 pr_err("Driver %s doesn't provide needed callbacks\n",940 sdriver->driver.name);941 return -EINVAL;942 }943 944 sdriver->driver.owner = owner;945 sdriver->driver.bus = &siox_bus_type;946 947 ret = driver_register(&sdriver->driver);948 if (ret)949 pr_err("Failed to register siox driver %s (%d)\n",950 sdriver->driver.name, ret);951 952 return ret;953}954EXPORT_SYMBOL_GPL(__siox_driver_register);955 956static int __init siox_init(void)957{958 int ret;959 960 ret = bus_register(&siox_bus_type);961 if (ret) {962 pr_err("Registration of SIOX bus type failed: %d\n", ret);963 return ret;964 }965 966 siox_is_registered = true;967 968 return 0;969}970subsys_initcall(siox_init);971 972static void __exit siox_exit(void)973{974 bus_unregister(&siox_bus_type);975}976module_exit(siox_exit);977 978MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");979MODULE_DESCRIPTION("Eckelmann SIOX driver core");980MODULE_LICENSE("GPL v2");981