1/* 2 * Intel MIC Platform Software Stack (MPSS) 3 * 4 * Copyright(c) 2015 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * The full GNU General Public License is included in this distribution in 16 * the file called "COPYING". 17 * 18 * Intel MIC Coprocessor State Management (COSM) Driver 19 * 20 */ 21 22#include <linux/debugfs.h> 23#include <linux/slab.h> 24#include <linux/io.h> 25#include "cosm_main.h" 26 27/* Debugfs parent dir */ 28static struct dentry *cosm_dbg; 29 30/** 31 * cosm_log_buf_show - Display MIC kernel log buffer 32 * 33 * log_buf addr/len is read from System.map by user space 34 * and populated in sysfs entries. 35 */ 36static int cosm_log_buf_show(struct seq_file *s, void *unused) 37{ 38 void __iomem *log_buf_va; 39 int __iomem *log_buf_len_va; 40 struct cosm_device *cdev = s->private; 41 void *kva; 42 int size; 43 u64 aper_offset; 44 45 if (!cdev || !cdev->log_buf_addr || !cdev->log_buf_len) 46 goto done; 47 48 mutex_lock(&cdev->cosm_mutex); 49 switch (cdev->state) { 50 case MIC_BOOTING: 51 case MIC_ONLINE: 52 case MIC_SHUTTING_DOWN: 53 break; 54 default: 55 goto unlock; 56 } 57 58 /* 59 * Card kernel will never be relocated and any kernel text/data mapping 60 * can be translated to phys address by subtracting __START_KERNEL_map. 61 */ 62 aper_offset = (u64)cdev->log_buf_len - __START_KERNEL_map; 63 log_buf_len_va = cdev->hw_ops->aper(cdev)->va + aper_offset; 64 aper_offset = (u64)cdev->log_buf_addr - __START_KERNEL_map; 65 log_buf_va = cdev->hw_ops->aper(cdev)->va + aper_offset; 66 67 size = ioread32(log_buf_len_va); 68 kva = kmalloc(size, GFP_KERNEL); 69 if (!kva) 70 goto unlock; 71 72 memcpy_fromio(kva, log_buf_va, size); 73 seq_write(s, kva, size); 74 kfree(kva); 75unlock: 76 mutex_unlock(&cdev->cosm_mutex); 77done: 78 return 0; 79} 80 81static int cosm_log_buf_open(struct inode *inode, struct file *file) 82{ 83 return single_open(file, cosm_log_buf_show, inode->i_private); 84} 85 86static const struct file_operations log_buf_ops = { 87 .owner = THIS_MODULE, 88 .open = cosm_log_buf_open, 89 .read = seq_read, 90 .llseek = seq_lseek, 91 .release = single_release 92}; 93 94/** 95 * cosm_force_reset_show - Force MIC reset 96 * 97 * Invokes the force_reset COSM bus op instead of the standard reset 98 * op in case a force reset of the MIC device is required 99 */ 100static int cosm_force_reset_show(struct seq_file *s, void *pos) 101{ 102 struct cosm_device *cdev = s->private; 103 104 cosm_stop(cdev, true); 105 return 0; 106} 107 108static int cosm_force_reset_debug_open(struct inode *inode, struct file *file) 109{ 110 return single_open(file, cosm_force_reset_show, inode->i_private); 111} 112 113static const struct file_operations force_reset_ops = { 114 .owner = THIS_MODULE, 115 .open = cosm_force_reset_debug_open, 116 .read = seq_read, 117 .llseek = seq_lseek, 118 .release = single_release 119}; 120 121void cosm_create_debug_dir(struct cosm_device *cdev) 122{ 123 char name[16]; 124 125 if (!cosm_dbg) 126 return; 127 128 scnprintf(name, sizeof(name), "mic%d", cdev->index); 129 cdev->dbg_dir = debugfs_create_dir(name, cosm_dbg); 130 if (!cdev->dbg_dir) 131 return; 132 133 debugfs_create_file("log_buf", 0444, cdev->dbg_dir, cdev, &log_buf_ops); 134 debugfs_create_file("force_reset", 0444, cdev->dbg_dir, cdev, 135 &force_reset_ops); 136} 137 138void cosm_delete_debug_dir(struct cosm_device *cdev) 139{ 140 if (!cdev->dbg_dir) 141 return; 142 143 debugfs_remove_recursive(cdev->dbg_dir); 144} 145 146void cosm_init_debugfs(void) 147{ 148 cosm_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); 149 if (!cosm_dbg) 150 pr_err("can't create debugfs dir\n"); 151} 152 153void cosm_exit_debugfs(void) 154{ 155 debugfs_remove(cosm_dbg); 156} 157