root/drivers/misc/mic/cosm/cosm_sysfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. cosm_set_shutdown_status
  2. cosm_set_state
  3. family_show
  4. stepping_show
  5. state_show
  6. state_store
  7. shutdown_status_show
  8. heartbeat_enable_show
  9. heartbeat_enable_store
  10. cmdline_show
  11. cmdline_store
  12. firmware_show
  13. firmware_store
  14. ramdisk_show
  15. ramdisk_store
  16. bootmode_show
  17. bootmode_store
  18. log_buf_addr_show
  19. log_buf_addr_store
  20. log_buf_len_show
  21. log_buf_len_store
  22. cosm_sysfs_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Intel MIC Platform Software Stack (MPSS)
   4  *
   5  * Copyright(c) 2015 Intel Corporation.
   6  *
   7  * Intel MIC Coprocessor State Management (COSM) Driver
   8  */
   9 #include <linux/slab.h>
  10 #include "cosm_main.h"
  11 
  12 /*
  13  * A state-to-string lookup table, for exposing a human readable state
  14  * via sysfs. Always keep in sync with enum cosm_states
  15  */
  16 const char * const cosm_state_string[] = {
  17         [MIC_READY] = "ready",
  18         [MIC_BOOTING] = "booting",
  19         [MIC_ONLINE] = "online",
  20         [MIC_SHUTTING_DOWN] = "shutting_down",
  21         [MIC_RESETTING] = "resetting",
  22         [MIC_RESET_FAILED] = "reset_failed",
  23 };
  24 
  25 /*
  26  * A shutdown-status-to-string lookup table, for exposing a human
  27  * readable state via sysfs. Always keep in sync with enum cosm_shutdown_status
  28  */
  29 const char * const cosm_shutdown_status_string[] = {
  30         [MIC_NOP] = "nop",
  31         [MIC_CRASHED] = "crashed",
  32         [MIC_HALTED] = "halted",
  33         [MIC_POWER_OFF] = "poweroff",
  34         [MIC_RESTART] = "restart",
  35 };
  36 
  37 void cosm_set_shutdown_status(struct cosm_device *cdev, u8 shutdown_status)
  38 {
  39         dev_dbg(&cdev->dev, "Shutdown Status %s -> %s\n",
  40                 cosm_shutdown_status_string[cdev->shutdown_status],
  41                 cosm_shutdown_status_string[shutdown_status]);
  42         cdev->shutdown_status = shutdown_status;
  43 }
  44 
  45 void cosm_set_state(struct cosm_device *cdev, u8 state)
  46 {
  47         dev_dbg(&cdev->dev, "State %s -> %s\n",
  48                 cosm_state_string[cdev->state],
  49                 cosm_state_string[state]);
  50         cdev->state = state;
  51         sysfs_notify_dirent(cdev->state_sysfs);
  52 }
  53 
  54 static ssize_t
  55 family_show(struct device *dev, struct device_attribute *attr, char *buf)
  56 {
  57         struct cosm_device *cdev = dev_get_drvdata(dev);
  58 
  59         if (!cdev)
  60                 return -EINVAL;
  61 
  62         return cdev->hw_ops->family(cdev, buf);
  63 }
  64 static DEVICE_ATTR_RO(family);
  65 
  66 static ssize_t
  67 stepping_show(struct device *dev, struct device_attribute *attr, char *buf)
  68 {
  69         struct cosm_device *cdev = dev_get_drvdata(dev);
  70 
  71         if (!cdev)
  72                 return -EINVAL;
  73 
  74         return cdev->hw_ops->stepping(cdev, buf);
  75 }
  76 static DEVICE_ATTR_RO(stepping);
  77 
  78 static ssize_t
  79 state_show(struct device *dev, struct device_attribute *attr, char *buf)
  80 {
  81         struct cosm_device *cdev = dev_get_drvdata(dev);
  82 
  83         if (!cdev || cdev->state >= MIC_LAST)
  84                 return -EINVAL;
  85 
  86         return scnprintf(buf, PAGE_SIZE, "%s\n",
  87                 cosm_state_string[cdev->state]);
  88 }
  89 
  90 static ssize_t
  91 state_store(struct device *dev, struct device_attribute *attr,
  92             const char *buf, size_t count)
  93 {
  94         struct cosm_device *cdev = dev_get_drvdata(dev);
  95         int rc;
  96 
  97         if (!cdev)
  98                 return -EINVAL;
  99 
 100         if (sysfs_streq(buf, "boot")) {
 101                 rc = cosm_start(cdev);
 102                 goto done;
 103         }
 104         if (sysfs_streq(buf, "reset")) {
 105                 rc = cosm_reset(cdev);
 106                 goto done;
 107         }
 108 
 109         if (sysfs_streq(buf, "shutdown")) {
 110                 rc = cosm_shutdown(cdev);
 111                 goto done;
 112         }
 113         rc = -EINVAL;
 114 done:
 115         if (rc)
 116                 count = rc;
 117         return count;
 118 }
 119 static DEVICE_ATTR_RW(state);
 120 
 121 static ssize_t shutdown_status_show(struct device *dev,
 122                                     struct device_attribute *attr, char *buf)
 123 {
 124         struct cosm_device *cdev = dev_get_drvdata(dev);
 125 
 126         if (!cdev || cdev->shutdown_status >= MIC_STATUS_LAST)
 127                 return -EINVAL;
 128 
 129         return scnprintf(buf, PAGE_SIZE, "%s\n",
 130                 cosm_shutdown_status_string[cdev->shutdown_status]);
 131 }
 132 static DEVICE_ATTR_RO(shutdown_status);
 133 
 134 static ssize_t
 135 heartbeat_enable_show(struct device *dev,
 136                       struct device_attribute *attr, char *buf)
 137 {
 138         struct cosm_device *cdev = dev_get_drvdata(dev);
 139 
 140         if (!cdev)
 141                 return -EINVAL;
 142 
 143         return scnprintf(buf, PAGE_SIZE, "%d\n", cdev->sysfs_heartbeat_enable);
 144 }
 145 
 146 static ssize_t
 147 heartbeat_enable_store(struct device *dev,
 148                        struct device_attribute *attr,
 149                        const char *buf, size_t count)
 150 {
 151         struct cosm_device *cdev = dev_get_drvdata(dev);
 152         int enable;
 153         int ret;
 154 
 155         if (!cdev)
 156                 return -EINVAL;
 157 
 158         mutex_lock(&cdev->cosm_mutex);
 159         ret = kstrtoint(buf, 10, &enable);
 160         if (ret)
 161                 goto unlock;
 162 
 163         cdev->sysfs_heartbeat_enable = enable;
 164         /* if state is not online, cdev->heartbeat_watchdog_enable is 0 */
 165         if (cdev->state == MIC_ONLINE)
 166                 cdev->heartbeat_watchdog_enable = enable;
 167         ret = count;
 168 unlock:
 169         mutex_unlock(&cdev->cosm_mutex);
 170         return ret;
 171 }
 172 static DEVICE_ATTR_RW(heartbeat_enable);
 173 
 174 static ssize_t
 175 cmdline_show(struct device *dev, struct device_attribute *attr, char *buf)
 176 {
 177         struct cosm_device *cdev = dev_get_drvdata(dev);
 178         char *cmdline;
 179 
 180         if (!cdev)
 181                 return -EINVAL;
 182 
 183         cmdline = cdev->cmdline;
 184 
 185         if (cmdline)
 186                 return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline);
 187         return 0;
 188 }
 189 
 190 static ssize_t
 191 cmdline_store(struct device *dev, struct device_attribute *attr,
 192               const char *buf, size_t count)
 193 {
 194         struct cosm_device *cdev = dev_get_drvdata(dev);
 195 
 196         if (!cdev)
 197                 return -EINVAL;
 198 
 199         mutex_lock(&cdev->cosm_mutex);
 200         kfree(cdev->cmdline);
 201 
 202         cdev->cmdline = kmalloc(count + 1, GFP_KERNEL);
 203         if (!cdev->cmdline) {
 204                 count = -ENOMEM;
 205                 goto unlock;
 206         }
 207 
 208         strncpy(cdev->cmdline, buf, count);
 209 
 210         if (cdev->cmdline[count - 1] == '\n')
 211                 cdev->cmdline[count - 1] = '\0';
 212         else
 213                 cdev->cmdline[count] = '\0';
 214 unlock:
 215         mutex_unlock(&cdev->cosm_mutex);
 216         return count;
 217 }
 218 static DEVICE_ATTR_RW(cmdline);
 219 
 220 static ssize_t
 221 firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
 222 {
 223         struct cosm_device *cdev = dev_get_drvdata(dev);
 224         char *firmware;
 225 
 226         if (!cdev)
 227                 return -EINVAL;
 228 
 229         firmware = cdev->firmware;
 230 
 231         if (firmware)
 232                 return scnprintf(buf, PAGE_SIZE, "%s\n", firmware);
 233         return 0;
 234 }
 235 
 236 static ssize_t
 237 firmware_store(struct device *dev, struct device_attribute *attr,
 238                const char *buf, size_t count)
 239 {
 240         struct cosm_device *cdev = dev_get_drvdata(dev);
 241 
 242         if (!cdev)
 243                 return -EINVAL;
 244 
 245         mutex_lock(&cdev->cosm_mutex);
 246         kfree(cdev->firmware);
 247 
 248         cdev->firmware = kmalloc(count + 1, GFP_KERNEL);
 249         if (!cdev->firmware) {
 250                 count = -ENOMEM;
 251                 goto unlock;
 252         }
 253         strncpy(cdev->firmware, buf, count);
 254 
 255         if (cdev->firmware[count - 1] == '\n')
 256                 cdev->firmware[count - 1] = '\0';
 257         else
 258                 cdev->firmware[count] = '\0';
 259 unlock:
 260         mutex_unlock(&cdev->cosm_mutex);
 261         return count;
 262 }
 263 static DEVICE_ATTR_RW(firmware);
 264 
 265 static ssize_t
 266 ramdisk_show(struct device *dev, struct device_attribute *attr, char *buf)
 267 {
 268         struct cosm_device *cdev = dev_get_drvdata(dev);
 269         char *ramdisk;
 270 
 271         if (!cdev)
 272                 return -EINVAL;
 273 
 274         ramdisk = cdev->ramdisk;
 275 
 276         if (ramdisk)
 277                 return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk);
 278         return 0;
 279 }
 280 
 281 static ssize_t
 282 ramdisk_store(struct device *dev, struct device_attribute *attr,
 283               const char *buf, size_t count)
 284 {
 285         struct cosm_device *cdev = dev_get_drvdata(dev);
 286 
 287         if (!cdev)
 288                 return -EINVAL;
 289 
 290         mutex_lock(&cdev->cosm_mutex);
 291         kfree(cdev->ramdisk);
 292 
 293         cdev->ramdisk = kmalloc(count + 1, GFP_KERNEL);
 294         if (!cdev->ramdisk) {
 295                 count = -ENOMEM;
 296                 goto unlock;
 297         }
 298 
 299         strncpy(cdev->ramdisk, buf, count);
 300 
 301         if (cdev->ramdisk[count - 1] == '\n')
 302                 cdev->ramdisk[count - 1] = '\0';
 303         else
 304                 cdev->ramdisk[count] = '\0';
 305 unlock:
 306         mutex_unlock(&cdev->cosm_mutex);
 307         return count;
 308 }
 309 static DEVICE_ATTR_RW(ramdisk);
 310 
 311 static ssize_t
 312 bootmode_show(struct device *dev, struct device_attribute *attr, char *buf)
 313 {
 314         struct cosm_device *cdev = dev_get_drvdata(dev);
 315         char *bootmode;
 316 
 317         if (!cdev)
 318                 return -EINVAL;
 319 
 320         bootmode = cdev->bootmode;
 321 
 322         if (bootmode)
 323                 return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode);
 324         return 0;
 325 }
 326 
 327 static ssize_t
 328 bootmode_store(struct device *dev, struct device_attribute *attr,
 329                const char *buf, size_t count)
 330 {
 331         struct cosm_device *cdev = dev_get_drvdata(dev);
 332 
 333         if (!cdev)
 334                 return -EINVAL;
 335 
 336         if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "flash"))
 337                 return -EINVAL;
 338 
 339         mutex_lock(&cdev->cosm_mutex);
 340         kfree(cdev->bootmode);
 341 
 342         cdev->bootmode = kmalloc(count + 1, GFP_KERNEL);
 343         if (!cdev->bootmode) {
 344                 count = -ENOMEM;
 345                 goto unlock;
 346         }
 347 
 348         strncpy(cdev->bootmode, buf, count);
 349 
 350         if (cdev->bootmode[count - 1] == '\n')
 351                 cdev->bootmode[count - 1] = '\0';
 352         else
 353                 cdev->bootmode[count] = '\0';
 354 unlock:
 355         mutex_unlock(&cdev->cosm_mutex);
 356         return count;
 357 }
 358 static DEVICE_ATTR_RW(bootmode);
 359 
 360 static ssize_t
 361 log_buf_addr_show(struct device *dev, struct device_attribute *attr,
 362                   char *buf)
 363 {
 364         struct cosm_device *cdev = dev_get_drvdata(dev);
 365 
 366         if (!cdev)
 367                 return -EINVAL;
 368 
 369         return scnprintf(buf, PAGE_SIZE, "%p\n", cdev->log_buf_addr);
 370 }
 371 
 372 static ssize_t
 373 log_buf_addr_store(struct device *dev, struct device_attribute *attr,
 374                    const char *buf, size_t count)
 375 {
 376         struct cosm_device *cdev = dev_get_drvdata(dev);
 377         int ret;
 378         unsigned long addr;
 379 
 380         if (!cdev)
 381                 return -EINVAL;
 382 
 383         ret = kstrtoul(buf, 16, &addr);
 384         if (ret)
 385                 goto exit;
 386 
 387         cdev->log_buf_addr = (void *)addr;
 388         ret = count;
 389 exit:
 390         return ret;
 391 }
 392 static DEVICE_ATTR_RW(log_buf_addr);
 393 
 394 static ssize_t
 395 log_buf_len_show(struct device *dev, struct device_attribute *attr,
 396                  char *buf)
 397 {
 398         struct cosm_device *cdev = dev_get_drvdata(dev);
 399 
 400         if (!cdev)
 401                 return -EINVAL;
 402 
 403         return scnprintf(buf, PAGE_SIZE, "%p\n", cdev->log_buf_len);
 404 }
 405 
 406 static ssize_t
 407 log_buf_len_store(struct device *dev, struct device_attribute *attr,
 408                   const char *buf, size_t count)
 409 {
 410         struct cosm_device *cdev = dev_get_drvdata(dev);
 411         int ret;
 412         unsigned long addr;
 413 
 414         if (!cdev)
 415                 return -EINVAL;
 416 
 417         ret = kstrtoul(buf, 16, &addr);
 418         if (ret)
 419                 goto exit;
 420 
 421         cdev->log_buf_len = (int *)addr;
 422         ret = count;
 423 exit:
 424         return ret;
 425 }
 426 static DEVICE_ATTR_RW(log_buf_len);
 427 
 428 static struct attribute *cosm_default_attrs[] = {
 429         &dev_attr_family.attr,
 430         &dev_attr_stepping.attr,
 431         &dev_attr_state.attr,
 432         &dev_attr_shutdown_status.attr,
 433         &dev_attr_heartbeat_enable.attr,
 434         &dev_attr_cmdline.attr,
 435         &dev_attr_firmware.attr,
 436         &dev_attr_ramdisk.attr,
 437         &dev_attr_bootmode.attr,
 438         &dev_attr_log_buf_addr.attr,
 439         &dev_attr_log_buf_len.attr,
 440 
 441         NULL
 442 };
 443 
 444 ATTRIBUTE_GROUPS(cosm_default);
 445 
 446 void cosm_sysfs_init(struct cosm_device *cdev)
 447 {
 448         cdev->attr_group = cosm_default_groups;
 449 }

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