Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2015-2017 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de>
0004  */
0005 #include <linux/kernel.h>
0006 #include <linux/device.h>
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/sysfs.h>
0010 
0011 #include "siox.h"
0012 
0013 /*
0014  * The lowest bit in the SIOX status word signals if the in-device watchdog is
0015  * ok. If the bit is set, the device is functional.
0016  *
0017  * On writing the watchdog timer is reset when this bit toggles.
0018  */
0019 #define SIOX_STATUS_WDG         0x01
0020 
0021 /*
0022  * Bits 1 to 3 of the status word read as the bitwise negation of what was
0023  * clocked in before. The value clocked in is changed in each cycle and so
0024  * allows to detect transmit/receive problems.
0025  */
0026 #define SIOX_STATUS_COUNTER     0x0e
0027 
0028 /*
0029  * Each Siox-Device has a 4 bit type number that is neither 0 nor 15. This is
0030  * available in the upper nibble of the read status.
0031  *
0032  * On write these bits are DC.
0033  */
0034 #define SIOX_STATUS_TYPE        0xf0
0035 
0036 #define CREATE_TRACE_POINTS
0037 #include <trace/events/siox.h>
0038 
0039 static bool siox_is_registered;
0040 
0041 static void siox_master_lock(struct siox_master *smaster)
0042 {
0043     mutex_lock(&smaster->lock);
0044 }
0045 
0046 static void siox_master_unlock(struct siox_master *smaster)
0047 {
0048     mutex_unlock(&smaster->lock);
0049 }
0050 
0051 static inline u8 siox_status_clean(u8 status_read, u8 status_written)
0052 {
0053     /*
0054      * bits 3:1 of status sample the respective bit in the status
0055      * byte written in the previous cycle but inverted. So if you wrote the
0056      * status word as 0xa before (counter = 0b101), it is expected to get
0057      * back the counter bits as 0b010.
0058      *
0059      * So given the last status written this function toggles the there
0060      * unset counter bits in the read value such that the counter bits in
0061      * the return value are all zero iff the bits were read as expected to
0062      * simplify error detection.
0063      */
0064 
0065     return status_read ^ (~status_written & 0xe);
0066 }
0067 
0068 static bool siox_device_counter_error(struct siox_device *sdevice,
0069                       u8 status_clean)
0070 {
0071     return (status_clean & SIOX_STATUS_COUNTER) != 0;
0072 }
0073 
0074 static bool siox_device_type_error(struct siox_device *sdevice, u8 status_clean)
0075 {
0076     u8 statustype = (status_clean & SIOX_STATUS_TYPE) >> 4;
0077 
0078     /*
0079      * If the device knows which value the type bits should have, check
0080      * against this value otherwise just rule out the invalid values 0b0000
0081      * and 0b1111.
0082      */
0083     if (sdevice->statustype) {
0084         if (statustype != sdevice->statustype)
0085             return true;
0086     } else {
0087         switch (statustype) {
0088         case 0:
0089         case 0xf:
0090             return true;
0091         }
0092     }
0093 
0094     return false;
0095 }
0096 
0097 static bool siox_device_wdg_error(struct siox_device *sdevice, u8 status_clean)
0098 {
0099     return (status_clean & SIOX_STATUS_WDG) == 0;
0100 }
0101 
0102 /*
0103  * If there is a type or counter error the device is called "unsynced".
0104  */
0105 bool siox_device_synced(struct siox_device *sdevice)
0106 {
0107     if (siox_device_type_error(sdevice, sdevice->status_read_clean))
0108         return false;
0109 
0110     return !siox_device_counter_error(sdevice, sdevice->status_read_clean);
0111 
0112 }
0113 EXPORT_SYMBOL_GPL(siox_device_synced);
0114 
0115 /*
0116  * A device is called "connected" if it is synced and the watchdog is not
0117  * asserted.
0118  */
0119 bool siox_device_connected(struct siox_device *sdevice)
0120 {
0121     if (!siox_device_synced(sdevice))
0122         return false;
0123 
0124     return !siox_device_wdg_error(sdevice, sdevice->status_read_clean);
0125 }
0126 EXPORT_SYMBOL_GPL(siox_device_connected);
0127 
0128 static void siox_poll(struct siox_master *smaster)
0129 {
0130     struct siox_device *sdevice;
0131     size_t i = smaster->setbuf_len;
0132     unsigned int devno = 0;
0133     int unsync_error = 0;
0134 
0135     smaster->last_poll = jiffies;
0136 
0137     /*
0138      * The counter bits change in each second cycle, the watchdog bit
0139      * toggles each time.
0140      * The counter bits hold values from [0, 6]. 7 would be possible
0141      * theoretically but the protocol designer considered that a bad idea
0142      * for reasons unknown today. (Maybe that's because then the status read
0143      * back has only zeros in the counter bits then which might be confused
0144      * with a stuck-at-0 error. But for the same reason (with s/0/1/) 0
0145      * could be skipped.)
0146      */
0147     if (++smaster->status > 0x0d)
0148         smaster->status = 0;
0149 
0150     memset(smaster->buf, 0, smaster->setbuf_len);
0151 
0152     /* prepare data pushed out to devices in buf[0..setbuf_len) */
0153     list_for_each_entry(sdevice, &smaster->devices, node) {
0154         struct siox_driver *sdriver =
0155             to_siox_driver(sdevice->dev.driver);
0156         sdevice->status_written = smaster->status;
0157 
0158         i -= sdevice->inbytes;
0159 
0160         /*
0161          * If the device or a previous one is unsynced, don't pet the
0162          * watchdog. This is done to ensure that the device is kept in
0163          * reset when something is wrong.
0164          */
0165         if (!siox_device_synced(sdevice))
0166             unsync_error = 1;
0167 
0168         if (sdriver && !unsync_error)
0169             sdriver->set_data(sdevice, sdevice->status_written,
0170                       &smaster->buf[i + 1]);
0171         else
0172             /*
0173              * Don't trigger watchdog if there is no driver or a
0174              * sync problem
0175              */
0176             sdevice->status_written &= ~SIOX_STATUS_WDG;
0177 
0178         smaster->buf[i] = sdevice->status_written;
0179 
0180         trace_siox_set_data(smaster, sdevice, devno, i);
0181 
0182         devno++;
0183     }
0184 
0185     smaster->pushpull(smaster, smaster->setbuf_len, smaster->buf,
0186               smaster->getbuf_len,
0187               smaster->buf + smaster->setbuf_len);
0188 
0189     unsync_error = 0;
0190 
0191     /* interpret data pulled in from devices in buf[setbuf_len..] */
0192     devno = 0;
0193     i = smaster->setbuf_len;
0194     list_for_each_entry(sdevice, &smaster->devices, node) {
0195         struct siox_driver *sdriver =
0196             to_siox_driver(sdevice->dev.driver);
0197         u8 status = smaster->buf[i + sdevice->outbytes - 1];
0198         u8 status_clean;
0199         u8 prev_status_clean = sdevice->status_read_clean;
0200         bool synced = true;
0201         bool connected = true;
0202 
0203         if (!siox_device_synced(sdevice))
0204             unsync_error = 1;
0205 
0206         /*
0207          * If the watchdog bit wasn't toggled in this cycle, report the
0208          * watchdog as active to give a consistent view for drivers and
0209          * sysfs consumers.
0210          */
0211         if (!sdriver || unsync_error)
0212             status &= ~SIOX_STATUS_WDG;
0213 
0214         status_clean =
0215             siox_status_clean(status,
0216                       sdevice->status_written_lastcycle);
0217 
0218         /* Check counter and type bits */
0219         if (siox_device_counter_error(sdevice, status_clean) ||
0220             siox_device_type_error(sdevice, status_clean)) {
0221             bool prev_error;
0222 
0223             synced = false;
0224 
0225             /* only report a new error if the last cycle was ok */
0226             prev_error =
0227                 siox_device_counter_error(sdevice,
0228                               prev_status_clean) ||
0229                 siox_device_type_error(sdevice,
0230                                prev_status_clean);
0231 
0232             if (!prev_error) {
0233                 sdevice->status_errors++;
0234                 sysfs_notify_dirent(sdevice->status_errors_kn);
0235             }
0236         }
0237 
0238         /* If the device is unsynced report the watchdog as active */
0239         if (!synced) {
0240             status &= ~SIOX_STATUS_WDG;
0241             status_clean &= ~SIOX_STATUS_WDG;
0242         }
0243 
0244         if (siox_device_wdg_error(sdevice, status_clean))
0245             connected = false;
0246 
0247         /* The watchdog state changed just now */
0248         if ((status_clean ^ prev_status_clean) & SIOX_STATUS_WDG) {
0249             sysfs_notify_dirent(sdevice->watchdog_kn);
0250 
0251             if (siox_device_wdg_error(sdevice, status_clean)) {
0252                 struct kernfs_node *wd_errs =
0253                     sdevice->watchdog_errors_kn;
0254 
0255                 sdevice->watchdog_errors++;
0256                 sysfs_notify_dirent(wd_errs);
0257             }
0258         }
0259 
0260         if (connected != sdevice->connected)
0261             sysfs_notify_dirent(sdevice->connected_kn);
0262 
0263         sdevice->status_read_clean = status_clean;
0264         sdevice->status_written_lastcycle = sdevice->status_written;
0265         sdevice->connected = connected;
0266 
0267         trace_siox_get_data(smaster, sdevice, devno, status_clean, i);
0268 
0269         /* only give data read to driver if the device is connected */
0270         if (sdriver && connected)
0271             sdriver->get_data(sdevice, &smaster->buf[i]);
0272 
0273         devno++;
0274         i += sdevice->outbytes;
0275     }
0276 }
0277 
0278 static int siox_poll_thread(void *data)
0279 {
0280     struct siox_master *smaster = data;
0281     signed long timeout = 0;
0282 
0283     get_device(&smaster->dev);
0284 
0285     for (;;) {
0286         if (kthread_should_stop()) {
0287             put_device(&smaster->dev);
0288             return 0;
0289         }
0290 
0291         siox_master_lock(smaster);
0292 
0293         if (smaster->active) {
0294             unsigned long next_poll =
0295                 smaster->last_poll + smaster->poll_interval;
0296             if (time_is_before_eq_jiffies(next_poll))
0297                 siox_poll(smaster);
0298 
0299             timeout = smaster->poll_interval -
0300                 (jiffies - smaster->last_poll);
0301         } else {
0302             timeout = MAX_SCHEDULE_TIMEOUT;
0303         }
0304 
0305         /*
0306          * Set the task to idle while holding the lock. This makes sure
0307          * that we don't sleep too long when the bus is reenabled before
0308          * schedule_timeout is reached.
0309          */
0310         if (timeout > 0)
0311             set_current_state(TASK_IDLE);
0312 
0313         siox_master_unlock(smaster);
0314 
0315         if (timeout > 0)
0316             schedule_timeout(timeout);
0317 
0318         /*
0319          * I'm not clear if/why it is important to set the state to
0320          * RUNNING again, but it fixes a "do not call blocking ops when
0321          * !TASK_RUNNING;"-warning.
0322          */
0323         set_current_state(TASK_RUNNING);
0324     }
0325 }
0326 
0327 static int __siox_start(struct siox_master *smaster)
0328 {
0329     if (!(smaster->setbuf_len + smaster->getbuf_len))
0330         return -ENODEV;
0331 
0332     if (!smaster->buf)
0333         return -ENOMEM;
0334 
0335     if (smaster->active)
0336         return 0;
0337 
0338     smaster->active = 1;
0339     wake_up_process(smaster->poll_thread);
0340 
0341     return 1;
0342 }
0343 
0344 static int siox_start(struct siox_master *smaster)
0345 {
0346     int ret;
0347 
0348     siox_master_lock(smaster);
0349     ret = __siox_start(smaster);
0350     siox_master_unlock(smaster);
0351 
0352     return ret;
0353 }
0354 
0355 static int __siox_stop(struct siox_master *smaster)
0356 {
0357     if (smaster->active) {
0358         struct siox_device *sdevice;
0359 
0360         smaster->active = 0;
0361 
0362         list_for_each_entry(sdevice, &smaster->devices, node) {
0363             if (sdevice->connected)
0364                 sysfs_notify_dirent(sdevice->connected_kn);
0365             sdevice->connected = false;
0366         }
0367 
0368         return 1;
0369     }
0370     return 0;
0371 }
0372 
0373 static int siox_stop(struct siox_master *smaster)
0374 {
0375     int ret;
0376 
0377     siox_master_lock(smaster);
0378     ret = __siox_stop(smaster);
0379     siox_master_unlock(smaster);
0380 
0381     return ret;
0382 }
0383 
0384 static ssize_t type_show(struct device *dev,
0385              struct device_attribute *attr, char *buf)
0386 {
0387     struct siox_device *sdev = to_siox_device(dev);
0388 
0389     return sprintf(buf, "%s\n", sdev->type);
0390 }
0391 
0392 static DEVICE_ATTR_RO(type);
0393 
0394 static ssize_t inbytes_show(struct device *dev,
0395                 struct device_attribute *attr, char *buf)
0396 {
0397     struct siox_device *sdev = to_siox_device(dev);
0398 
0399     return sprintf(buf, "%zu\n", sdev->inbytes);
0400 }
0401 
0402 static DEVICE_ATTR_RO(inbytes);
0403 
0404 static ssize_t outbytes_show(struct device *dev,
0405                  struct device_attribute *attr, char *buf)
0406 {
0407     struct siox_device *sdev = to_siox_device(dev);
0408 
0409     return sprintf(buf, "%zu\n", sdev->outbytes);
0410 }
0411 
0412 static DEVICE_ATTR_RO(outbytes);
0413 
0414 static ssize_t status_errors_show(struct device *dev,
0415                   struct device_attribute *attr, char *buf)
0416 {
0417     struct siox_device *sdev = to_siox_device(dev);
0418     unsigned int status_errors;
0419 
0420     siox_master_lock(sdev->smaster);
0421 
0422     status_errors = sdev->status_errors;
0423 
0424     siox_master_unlock(sdev->smaster);
0425 
0426     return sprintf(buf, "%u\n", status_errors);
0427 }
0428 
0429 static DEVICE_ATTR_RO(status_errors);
0430 
0431 static ssize_t connected_show(struct device *dev,
0432                   struct device_attribute *attr, char *buf)
0433 {
0434     struct siox_device *sdev = to_siox_device(dev);
0435     bool connected;
0436 
0437     siox_master_lock(sdev->smaster);
0438 
0439     connected = sdev->connected;
0440 
0441     siox_master_unlock(sdev->smaster);
0442 
0443     return sprintf(buf, "%u\n", connected);
0444 }
0445 
0446 static DEVICE_ATTR_RO(connected);
0447 
0448 static ssize_t watchdog_show(struct device *dev,
0449                  struct device_attribute *attr, char *buf)
0450 {
0451     struct siox_device *sdev = to_siox_device(dev);
0452     u8 status;
0453 
0454     siox_master_lock(sdev->smaster);
0455 
0456     status = sdev->status_read_clean;
0457 
0458     siox_master_unlock(sdev->smaster);
0459 
0460     return sprintf(buf, "%d\n", status & SIOX_STATUS_WDG);
0461 }
0462 
0463 static DEVICE_ATTR_RO(watchdog);
0464 
0465 static ssize_t watchdog_errors_show(struct device *dev,
0466                     struct device_attribute *attr, char *buf)
0467 {
0468     struct siox_device *sdev = to_siox_device(dev);
0469     unsigned int watchdog_errors;
0470 
0471     siox_master_lock(sdev->smaster);
0472 
0473     watchdog_errors = sdev->watchdog_errors;
0474 
0475     siox_master_unlock(sdev->smaster);
0476 
0477     return sprintf(buf, "%u\n", watchdog_errors);
0478 }
0479 
0480 static DEVICE_ATTR_RO(watchdog_errors);
0481 
0482 static struct attribute *siox_device_attrs[] = {
0483     &dev_attr_type.attr,
0484     &dev_attr_inbytes.attr,
0485     &dev_attr_outbytes.attr,
0486     &dev_attr_status_errors.attr,
0487     &dev_attr_connected.attr,
0488     &dev_attr_watchdog.attr,
0489     &dev_attr_watchdog_errors.attr,
0490     NULL
0491 };
0492 ATTRIBUTE_GROUPS(siox_device);
0493 
0494 static void siox_device_release(struct device *dev)
0495 {
0496     struct siox_device *sdevice = to_siox_device(dev);
0497 
0498     kfree(sdevice);
0499 }
0500 
0501 static struct device_type siox_device_type = {
0502     .groups = siox_device_groups,
0503     .release = siox_device_release,
0504 };
0505 
0506 static int siox_match(struct device *dev, struct device_driver *drv)
0507 {
0508     if (dev->type != &siox_device_type)
0509         return 0;
0510 
0511     /* up to now there is only a single driver so keeping this simple */
0512     return 1;
0513 }
0514 
0515 static int siox_probe(struct device *dev)
0516 {
0517     struct siox_driver *sdriver = to_siox_driver(dev->driver);
0518     struct siox_device *sdevice = to_siox_device(dev);
0519 
0520     return sdriver->probe(sdevice);
0521 }
0522 
0523 static void siox_remove(struct device *dev)
0524 {
0525     struct siox_driver *sdriver =
0526         container_of(dev->driver, struct siox_driver, driver);
0527     struct siox_device *sdevice = to_siox_device(dev);
0528 
0529     if (sdriver->remove)
0530         sdriver->remove(sdevice);
0531 }
0532 
0533 static void siox_shutdown(struct device *dev)
0534 {
0535     struct siox_device *sdevice = to_siox_device(dev);
0536     struct siox_driver *sdriver;
0537 
0538     if (!dev->driver)
0539         return;
0540 
0541     sdriver = container_of(dev->driver, struct siox_driver, driver);
0542     if (sdriver->shutdown)
0543         sdriver->shutdown(sdevice);
0544 }
0545 
0546 static struct bus_type siox_bus_type = {
0547     .name = "siox",
0548     .match = siox_match,
0549     .probe = siox_probe,
0550     .remove = siox_remove,
0551     .shutdown = siox_shutdown,
0552 };
0553 
0554 static ssize_t active_show(struct device *dev,
0555                struct device_attribute *attr, char *buf)
0556 {
0557     struct siox_master *smaster = to_siox_master(dev);
0558 
0559     return sprintf(buf, "%d\n", smaster->active);
0560 }
0561 
0562 static ssize_t active_store(struct device *dev,
0563                 struct device_attribute *attr,
0564                 const char *buf, size_t count)
0565 {
0566     struct siox_master *smaster = to_siox_master(dev);
0567     int ret;
0568     int active;
0569 
0570     ret = kstrtoint(buf, 0, &active);
0571     if (ret < 0)
0572         return ret;
0573 
0574     if (active)
0575         ret = siox_start(smaster);
0576     else
0577         ret = siox_stop(smaster);
0578 
0579     if (ret < 0)
0580         return ret;
0581 
0582     return count;
0583 }
0584 
0585 static DEVICE_ATTR_RW(active);
0586 
0587 static struct siox_device *siox_device_add(struct siox_master *smaster,
0588                        const char *type, size_t inbytes,
0589                        size_t outbytes, u8 statustype);
0590 
0591 static ssize_t device_add_store(struct device *dev,
0592                 struct device_attribute *attr,
0593                 const char *buf, size_t count)
0594 {
0595     struct siox_master *smaster = to_siox_master(dev);
0596     int ret;
0597     char type[20] = "";
0598     size_t inbytes = 0, outbytes = 0;
0599     u8 statustype = 0;
0600 
0601     ret = sscanf(buf, "%19s %zu %zu %hhu", type, &inbytes,
0602              &outbytes, &statustype);
0603     if (ret != 3 && ret != 4)
0604         return -EINVAL;
0605 
0606     if (strcmp(type, "siox-12x8") || inbytes != 2 || outbytes != 4)
0607         return -EINVAL;
0608 
0609     siox_device_add(smaster, "siox-12x8", inbytes, outbytes, statustype);
0610 
0611     return count;
0612 }
0613 
0614 static DEVICE_ATTR_WO(device_add);
0615 
0616 static void siox_device_remove(struct siox_master *smaster);
0617 
0618 static ssize_t device_remove_store(struct device *dev,
0619                    struct device_attribute *attr,
0620                    const char *buf, size_t count)
0621 {
0622     struct siox_master *smaster = to_siox_master(dev);
0623 
0624     /* XXX? require to write <type> <inbytes> <outbytes> */
0625     siox_device_remove(smaster);
0626 
0627     return count;
0628 }
0629 
0630 static DEVICE_ATTR_WO(device_remove);
0631 
0632 static ssize_t poll_interval_ns_show(struct device *dev,
0633                      struct device_attribute *attr, char *buf)
0634 {
0635     struct siox_master *smaster = to_siox_master(dev);
0636 
0637     return sprintf(buf, "%lld\n", jiffies_to_nsecs(smaster->poll_interval));
0638 }
0639 
0640 static ssize_t poll_interval_ns_store(struct device *dev,
0641                       struct device_attribute *attr,
0642                       const char *buf, size_t count)
0643 {
0644     struct siox_master *smaster = to_siox_master(dev);
0645     int ret;
0646     u64 val;
0647 
0648     ret = kstrtou64(buf, 0, &val);
0649     if (ret < 0)
0650         return ret;
0651 
0652     siox_master_lock(smaster);
0653 
0654     smaster->poll_interval = nsecs_to_jiffies(val);
0655 
0656     siox_master_unlock(smaster);
0657 
0658     return count;
0659 }
0660 
0661 static DEVICE_ATTR_RW(poll_interval_ns);
0662 
0663 static struct attribute *siox_master_attrs[] = {
0664     &dev_attr_active.attr,
0665     &dev_attr_device_add.attr,
0666     &dev_attr_device_remove.attr,
0667     &dev_attr_poll_interval_ns.attr,
0668     NULL
0669 };
0670 ATTRIBUTE_GROUPS(siox_master);
0671 
0672 static void siox_master_release(struct device *dev)
0673 {
0674     struct siox_master *smaster = to_siox_master(dev);
0675 
0676     kfree(smaster);
0677 }
0678 
0679 static struct device_type siox_master_type = {
0680     .groups = siox_master_groups,
0681     .release = siox_master_release,
0682 };
0683 
0684 struct siox_master *siox_master_alloc(struct device *dev,
0685                       size_t size)
0686 {
0687     struct siox_master *smaster;
0688 
0689     if (!dev)
0690         return NULL;
0691 
0692     smaster = kzalloc(sizeof(*smaster) + size, GFP_KERNEL);
0693     if (!smaster)
0694         return NULL;
0695 
0696     device_initialize(&smaster->dev);
0697 
0698     smaster->busno = -1;
0699     smaster->dev.bus = &siox_bus_type;
0700     smaster->dev.type = &siox_master_type;
0701     smaster->dev.parent = dev;
0702     smaster->poll_interval = DIV_ROUND_UP(HZ, 40);
0703 
0704     dev_set_drvdata(&smaster->dev, &smaster[1]);
0705 
0706     return smaster;
0707 }
0708 EXPORT_SYMBOL_GPL(siox_master_alloc);
0709 
0710 int siox_master_register(struct siox_master *smaster)
0711 {
0712     int ret;
0713 
0714     if (!siox_is_registered)
0715         return -EPROBE_DEFER;
0716 
0717     if (!smaster->pushpull)
0718         return -EINVAL;
0719 
0720     dev_set_name(&smaster->dev, "siox-%d", smaster->busno);
0721 
0722     mutex_init(&smaster->lock);
0723     INIT_LIST_HEAD(&smaster->devices);
0724 
0725     smaster->last_poll = jiffies;
0726     smaster->poll_thread = kthread_run(siox_poll_thread, smaster,
0727                        "siox-%d", smaster->busno);
0728     if (IS_ERR(smaster->poll_thread)) {
0729         smaster->active = 0;
0730         return PTR_ERR(smaster->poll_thread);
0731     }
0732 
0733     ret = device_add(&smaster->dev);
0734     if (ret)
0735         kthread_stop(smaster->poll_thread);
0736 
0737     return ret;
0738 }
0739 EXPORT_SYMBOL_GPL(siox_master_register);
0740 
0741 void siox_master_unregister(struct siox_master *smaster)
0742 {
0743     /* remove device */
0744     device_del(&smaster->dev);
0745 
0746     siox_master_lock(smaster);
0747 
0748     __siox_stop(smaster);
0749 
0750     while (smaster->num_devices) {
0751         struct siox_device *sdevice;
0752 
0753         sdevice = container_of(smaster->devices.prev,
0754                        struct siox_device, node);
0755         list_del(&sdevice->node);
0756         smaster->num_devices--;
0757 
0758         siox_master_unlock(smaster);
0759 
0760         device_unregister(&sdevice->dev);
0761 
0762         siox_master_lock(smaster);
0763     }
0764 
0765     siox_master_unlock(smaster);
0766 
0767     put_device(&smaster->dev);
0768 }
0769 EXPORT_SYMBOL_GPL(siox_master_unregister);
0770 
0771 static struct siox_device *siox_device_add(struct siox_master *smaster,
0772                        const char *type, size_t inbytes,
0773                        size_t outbytes, u8 statustype)
0774 {
0775     struct siox_device *sdevice;
0776     int ret;
0777     size_t buf_len;
0778 
0779     sdevice = kzalloc(sizeof(*sdevice), GFP_KERNEL);
0780     if (!sdevice)
0781         return ERR_PTR(-ENOMEM);
0782 
0783     sdevice->type = type;
0784     sdevice->inbytes = inbytes;
0785     sdevice->outbytes = outbytes;
0786     sdevice->statustype = statustype;
0787 
0788     sdevice->smaster = smaster;
0789     sdevice->dev.parent = &smaster->dev;
0790     sdevice->dev.bus = &siox_bus_type;
0791     sdevice->dev.type = &siox_device_type;
0792 
0793     siox_master_lock(smaster);
0794 
0795     dev_set_name(&sdevice->dev, "siox-%d-%d",
0796              smaster->busno, smaster->num_devices);
0797 
0798     buf_len = smaster->setbuf_len + inbytes +
0799         smaster->getbuf_len + outbytes;
0800     if (smaster->buf_len < buf_len) {
0801         u8 *buf = krealloc(smaster->buf, buf_len, GFP_KERNEL);
0802 
0803         if (!buf) {
0804             dev_err(&smaster->dev,
0805                 "failed to realloc buffer to %zu\n", buf_len);
0806             ret = -ENOMEM;
0807             goto err_buf_alloc;
0808         }
0809 
0810         smaster->buf_len = buf_len;
0811         smaster->buf = buf;
0812     }
0813 
0814     ret = device_register(&sdevice->dev);
0815     if (ret) {
0816         dev_err(&smaster->dev, "failed to register device: %d\n", ret);
0817 
0818         goto err_device_register;
0819     }
0820 
0821     smaster->num_devices++;
0822     list_add_tail(&sdevice->node, &smaster->devices);
0823 
0824     smaster->setbuf_len += sdevice->inbytes;
0825     smaster->getbuf_len += sdevice->outbytes;
0826 
0827     sdevice->status_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
0828                              "status_errors");
0829     sdevice->watchdog_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
0830                         "watchdog");
0831     sdevice->watchdog_errors_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
0832                                "watchdog_errors");
0833     sdevice->connected_kn = sysfs_get_dirent(sdevice->dev.kobj.sd,
0834                          "connected");
0835 
0836     siox_master_unlock(smaster);
0837 
0838     return sdevice;
0839 
0840 err_device_register:
0841     /* don't care to make the buffer smaller again */
0842 
0843 err_buf_alloc:
0844     siox_master_unlock(smaster);
0845 
0846     kfree(sdevice);
0847 
0848     return ERR_PTR(ret);
0849 }
0850 
0851 static void siox_device_remove(struct siox_master *smaster)
0852 {
0853     struct siox_device *sdevice;
0854 
0855     siox_master_lock(smaster);
0856 
0857     if (!smaster->num_devices) {
0858         siox_master_unlock(smaster);
0859         return;
0860     }
0861 
0862     sdevice = container_of(smaster->devices.prev, struct siox_device, node);
0863     list_del(&sdevice->node);
0864     smaster->num_devices--;
0865 
0866     smaster->setbuf_len -= sdevice->inbytes;
0867     smaster->getbuf_len -= sdevice->outbytes;
0868 
0869     if (!smaster->num_devices)
0870         __siox_stop(smaster);
0871 
0872     siox_master_unlock(smaster);
0873 
0874     /*
0875      * This must be done without holding the master lock because we're
0876      * called from device_remove_store which also holds a sysfs mutex.
0877      * device_unregister tries to aquire the same lock.
0878      */
0879     device_unregister(&sdevice->dev);
0880 }
0881 
0882 int __siox_driver_register(struct siox_driver *sdriver, struct module *owner)
0883 {
0884     int ret;
0885 
0886     if (unlikely(!siox_is_registered))
0887         return -EPROBE_DEFER;
0888 
0889     if (!sdriver->probe ||
0890         (!sdriver->set_data && !sdriver->get_data)) {
0891         pr_err("Driver %s doesn't provide needed callbacks\n",
0892                sdriver->driver.name);
0893         return -EINVAL;
0894     }
0895 
0896     sdriver->driver.owner = owner;
0897     sdriver->driver.bus = &siox_bus_type;
0898 
0899     ret = driver_register(&sdriver->driver);
0900     if (ret)
0901         pr_err("Failed to register siox driver %s (%d)\n",
0902                sdriver->driver.name, ret);
0903 
0904     return ret;
0905 }
0906 EXPORT_SYMBOL_GPL(__siox_driver_register);
0907 
0908 static int __init siox_init(void)
0909 {
0910     int ret;
0911 
0912     ret = bus_register(&siox_bus_type);
0913     if (ret) {
0914         pr_err("Registration of SIOX bus type failed: %d\n", ret);
0915         return ret;
0916     }
0917 
0918     siox_is_registered = true;
0919 
0920     return 0;
0921 }
0922 subsys_initcall(siox_init);
0923 
0924 static void __exit siox_exit(void)
0925 {
0926     bus_unregister(&siox_bus_type);
0927 }
0928 module_exit(siox_exit);
0929 
0930 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
0931 MODULE_DESCRIPTION("Eckelmann SIOX driver core");
0932 MODULE_LICENSE("GPL v2");