root/drivers/ptp/ptp_sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clock_name_show
  2. extts_enable_store
  3. extts_fifo_show
  4. period_store
  5. pps_enable_store
  6. ptp_is_attribute_visible
  7. ptp_pin_name2index
  8. ptp_pin_show
  9. ptp_pin_store
  10. ptp_populate_pin_groups
  11. ptp_cleanup_pin_groups

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * PTP 1588 clock support - sysfs interface.
   4  *
   5  * Copyright (C) 2010 OMICRON electronics GmbH
   6  */
   7 #include <linux/capability.h>
   8 #include <linux/slab.h>
   9 
  10 #include "ptp_private.h"
  11 
  12 static ssize_t clock_name_show(struct device *dev,
  13                                struct device_attribute *attr, char *page)
  14 {
  15         struct ptp_clock *ptp = dev_get_drvdata(dev);
  16         return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name);
  17 }
  18 static DEVICE_ATTR_RO(clock_name);
  19 
  20 #define PTP_SHOW_INT(name, var)                                         \
  21 static ssize_t var##_show(struct device *dev,                           \
  22                            struct device_attribute *attr, char *page)   \
  23 {                                                                       \
  24         struct ptp_clock *ptp = dev_get_drvdata(dev);                   \
  25         return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->var);     \
  26 }                                                                       \
  27 static DEVICE_ATTR(name, 0444, var##_show, NULL);
  28 
  29 PTP_SHOW_INT(max_adjustment, max_adj);
  30 PTP_SHOW_INT(n_alarms, n_alarm);
  31 PTP_SHOW_INT(n_external_timestamps, n_ext_ts);
  32 PTP_SHOW_INT(n_periodic_outputs, n_per_out);
  33 PTP_SHOW_INT(n_programmable_pins, n_pins);
  34 PTP_SHOW_INT(pps_available, pps);
  35 
  36 static ssize_t extts_enable_store(struct device *dev,
  37                                   struct device_attribute *attr,
  38                                   const char *buf, size_t count)
  39 {
  40         struct ptp_clock *ptp = dev_get_drvdata(dev);
  41         struct ptp_clock_info *ops = ptp->info;
  42         struct ptp_clock_request req = { .type = PTP_CLK_REQ_EXTTS };
  43         int cnt, enable;
  44         int err = -EINVAL;
  45 
  46         cnt = sscanf(buf, "%u %d", &req.extts.index, &enable);
  47         if (cnt != 2)
  48                 goto out;
  49         if (req.extts.index >= ops->n_ext_ts)
  50                 goto out;
  51 
  52         err = ops->enable(ops, &req, enable ? 1 : 0);
  53         if (err)
  54                 goto out;
  55 
  56         return count;
  57 out:
  58         return err;
  59 }
  60 static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store);
  61 
  62 static ssize_t extts_fifo_show(struct device *dev,
  63                                struct device_attribute *attr, char *page)
  64 {
  65         struct ptp_clock *ptp = dev_get_drvdata(dev);
  66         struct timestamp_event_queue *queue = &ptp->tsevq;
  67         struct ptp_extts_event event;
  68         unsigned long flags;
  69         size_t qcnt;
  70         int cnt = 0;
  71 
  72         memset(&event, 0, sizeof(event));
  73 
  74         if (mutex_lock_interruptible(&ptp->tsevq_mux))
  75                 return -ERESTARTSYS;
  76 
  77         spin_lock_irqsave(&queue->lock, flags);
  78         qcnt = queue_cnt(queue);
  79         if (qcnt) {
  80                 event = queue->buf[queue->head];
  81                 queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
  82         }
  83         spin_unlock_irqrestore(&queue->lock, flags);
  84 
  85         if (!qcnt)
  86                 goto out;
  87 
  88         cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n",
  89                        event.index, event.t.sec, event.t.nsec);
  90 out:
  91         mutex_unlock(&ptp->tsevq_mux);
  92         return cnt;
  93 }
  94 static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL);
  95 
  96 static ssize_t period_store(struct device *dev,
  97                             struct device_attribute *attr,
  98                             const char *buf, size_t count)
  99 {
 100         struct ptp_clock *ptp = dev_get_drvdata(dev);
 101         struct ptp_clock_info *ops = ptp->info;
 102         struct ptp_clock_request req = { .type = PTP_CLK_REQ_PEROUT };
 103         int cnt, enable, err = -EINVAL;
 104 
 105         cnt = sscanf(buf, "%u %lld %u %lld %u", &req.perout.index,
 106                      &req.perout.start.sec, &req.perout.start.nsec,
 107                      &req.perout.period.sec, &req.perout.period.nsec);
 108         if (cnt != 5)
 109                 goto out;
 110         if (req.perout.index >= ops->n_per_out)
 111                 goto out;
 112 
 113         enable = req.perout.period.sec || req.perout.period.nsec;
 114         err = ops->enable(ops, &req, enable);
 115         if (err)
 116                 goto out;
 117 
 118         return count;
 119 out:
 120         return err;
 121 }
 122 static DEVICE_ATTR(period, 0220, NULL, period_store);
 123 
 124 static ssize_t pps_enable_store(struct device *dev,
 125                                 struct device_attribute *attr,
 126                                 const char *buf, size_t count)
 127 {
 128         struct ptp_clock *ptp = dev_get_drvdata(dev);
 129         struct ptp_clock_info *ops = ptp->info;
 130         struct ptp_clock_request req = { .type = PTP_CLK_REQ_PPS };
 131         int cnt, enable;
 132         int err = -EINVAL;
 133 
 134         if (!capable(CAP_SYS_TIME))
 135                 return -EPERM;
 136 
 137         cnt = sscanf(buf, "%d", &enable);
 138         if (cnt != 1)
 139                 goto out;
 140 
 141         err = ops->enable(ops, &req, enable ? 1 : 0);
 142         if (err)
 143                 goto out;
 144 
 145         return count;
 146 out:
 147         return err;
 148 }
 149 static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store);
 150 
 151 static struct attribute *ptp_attrs[] = {
 152         &dev_attr_clock_name.attr,
 153 
 154         &dev_attr_max_adjustment.attr,
 155         &dev_attr_n_alarms.attr,
 156         &dev_attr_n_external_timestamps.attr,
 157         &dev_attr_n_periodic_outputs.attr,
 158         &dev_attr_n_programmable_pins.attr,
 159         &dev_attr_pps_available.attr,
 160 
 161         &dev_attr_extts_enable.attr,
 162         &dev_attr_fifo.attr,
 163         &dev_attr_period.attr,
 164         &dev_attr_pps_enable.attr,
 165         NULL
 166 };
 167 
 168 static umode_t ptp_is_attribute_visible(struct kobject *kobj,
 169                                         struct attribute *attr, int n)
 170 {
 171         struct device *dev = kobj_to_dev(kobj);
 172         struct ptp_clock *ptp = dev_get_drvdata(dev);
 173         struct ptp_clock_info *info = ptp->info;
 174         umode_t mode = attr->mode;
 175 
 176         if (attr == &dev_attr_extts_enable.attr ||
 177             attr == &dev_attr_fifo.attr) {
 178                 if (!info->n_ext_ts)
 179                         mode = 0;
 180         } else if (attr == &dev_attr_period.attr) {
 181                 if (!info->n_per_out)
 182                         mode = 0;
 183         } else if (attr == &dev_attr_pps_enable.attr) {
 184                 if (!info->pps)
 185                         mode = 0;
 186         }
 187 
 188         return mode;
 189 }
 190 
 191 static const struct attribute_group ptp_group = {
 192         .is_visible     = ptp_is_attribute_visible,
 193         .attrs          = ptp_attrs,
 194 };
 195 
 196 const struct attribute_group *ptp_groups[] = {
 197         &ptp_group,
 198         NULL
 199 };
 200 
 201 static int ptp_pin_name2index(struct ptp_clock *ptp, const char *name)
 202 {
 203         int i;
 204         for (i = 0; i < ptp->info->n_pins; i++) {
 205                 if (!strcmp(ptp->info->pin_config[i].name, name))
 206                         return i;
 207         }
 208         return -1;
 209 }
 210 
 211 static ssize_t ptp_pin_show(struct device *dev, struct device_attribute *attr,
 212                             char *page)
 213 {
 214         struct ptp_clock *ptp = dev_get_drvdata(dev);
 215         unsigned int func, chan;
 216         int index;
 217 
 218         index = ptp_pin_name2index(ptp, attr->attr.name);
 219         if (index < 0)
 220                 return -EINVAL;
 221 
 222         if (mutex_lock_interruptible(&ptp->pincfg_mux))
 223                 return -ERESTARTSYS;
 224 
 225         func = ptp->info->pin_config[index].func;
 226         chan = ptp->info->pin_config[index].chan;
 227 
 228         mutex_unlock(&ptp->pincfg_mux);
 229 
 230         return snprintf(page, PAGE_SIZE, "%u %u\n", func, chan);
 231 }
 232 
 233 static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr,
 234                              const char *buf, size_t count)
 235 {
 236         struct ptp_clock *ptp = dev_get_drvdata(dev);
 237         unsigned int func, chan;
 238         int cnt, err, index;
 239 
 240         cnt = sscanf(buf, "%u %u", &func, &chan);
 241         if (cnt != 2)
 242                 return -EINVAL;
 243 
 244         index = ptp_pin_name2index(ptp, attr->attr.name);
 245         if (index < 0)
 246                 return -EINVAL;
 247 
 248         if (mutex_lock_interruptible(&ptp->pincfg_mux))
 249                 return -ERESTARTSYS;
 250         err = ptp_set_pinfunc(ptp, index, func, chan);
 251         mutex_unlock(&ptp->pincfg_mux);
 252         if (err)
 253                 return err;
 254 
 255         return count;
 256 }
 257 
 258 int ptp_populate_pin_groups(struct ptp_clock *ptp)
 259 {
 260         struct ptp_clock_info *info = ptp->info;
 261         int err = -ENOMEM, i, n_pins = info->n_pins;
 262 
 263         if (!n_pins)
 264                 return 0;
 265 
 266         ptp->pin_dev_attr = kcalloc(n_pins, sizeof(*ptp->pin_dev_attr),
 267                                     GFP_KERNEL);
 268         if (!ptp->pin_dev_attr)
 269                 goto no_dev_attr;
 270 
 271         ptp->pin_attr = kcalloc(1 + n_pins, sizeof(*ptp->pin_attr), GFP_KERNEL);
 272         if (!ptp->pin_attr)
 273                 goto no_pin_attr;
 274 
 275         for (i = 0; i < n_pins; i++) {
 276                 struct device_attribute *da = &ptp->pin_dev_attr[i];
 277                 sysfs_attr_init(&da->attr);
 278                 da->attr.name = info->pin_config[i].name;
 279                 da->attr.mode = 0644;
 280                 da->show = ptp_pin_show;
 281                 da->store = ptp_pin_store;
 282                 ptp->pin_attr[i] = &da->attr;
 283         }
 284 
 285         ptp->pin_attr_group.name = "pins";
 286         ptp->pin_attr_group.attrs = ptp->pin_attr;
 287 
 288         ptp->pin_attr_groups[0] = &ptp->pin_attr_group;
 289 
 290         return 0;
 291 
 292 no_pin_attr:
 293         kfree(ptp->pin_dev_attr);
 294 no_dev_attr:
 295         return err;
 296 }
 297 
 298 void ptp_cleanup_pin_groups(struct ptp_clock *ptp)
 299 {
 300         kfree(ptp->pin_attr);
 301         kfree(ptp->pin_dev_attr);
 302 }

/* [<][>][^][v][top][bottom][index][help] */