Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsi: scom: Major overhaul

This was too hard to split ... this adds a number of features
to the SCOM user interface:

- Support for indirect SCOMs

- read()/write() interface now handle errors and retries

- New ioctl() "raw" interface for use by debuggers

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Eddie James <eajames@linux.vnet.ibm.com>
Reviewed-by: Alistair Popple <alistair@popple.id.au>

+452 -30
+394 -30
drivers/fsi/fsi-scom.c
··· 24 24 #include <linux/list.h> 25 25 #include <linux/idr.h> 26 26 27 + #include <uapi/linux/fsi.h> 28 + 27 29 #define FSI_ENGID_SCOM 0x5 28 30 29 31 /* SCOM engine register set */ ··· 43 41 /* Status register bits */ 44 42 #define SCOM_STATUS_ERR_SUMMARY 0x80000000 45 43 #define SCOM_STATUS_PROTECTION 0x01000000 44 + #define SCOM_STATUS_PARITY 0x04000000 46 45 #define SCOM_STATUS_PIB_ABORT 0x00100000 47 46 #define SCOM_STATUS_PIB_RESP_MASK 0x00007000 48 47 #define SCOM_STATUS_PIB_RESP_SHIFT 12 49 48 50 49 #define SCOM_STATUS_ANY_ERR (SCOM_STATUS_ERR_SUMMARY | \ 51 50 SCOM_STATUS_PROTECTION | \ 51 + SCOM_STATUS_PARITY | \ 52 52 SCOM_STATUS_PIB_ABORT | \ 53 53 SCOM_STATUS_PIB_RESP_MASK) 54 + /* SCOM address encodings */ 55 + #define XSCOM_ADDR_IND_FLAG BIT_ULL(63) 56 + #define XSCOM_ADDR_INF_FORM1 BIT_ULL(60) 57 + 58 + /* SCOM indirect stuff */ 59 + #define XSCOM_ADDR_DIRECT_PART 0x7fffffffull 60 + #define XSCOM_ADDR_INDIRECT_PART 0x000fffff00000000ull 61 + #define XSCOM_DATA_IND_READ BIT_ULL(63) 62 + #define XSCOM_DATA_IND_COMPLETE BIT_ULL(31) 63 + #define XSCOM_DATA_IND_ERR_MASK 0x70000000ull 64 + #define XSCOM_DATA_IND_ERR_SHIFT 28 65 + #define XSCOM_DATA_IND_DATA 0x0000ffffull 66 + #define XSCOM_DATA_IND_FORM1_DATA 0x000fffffffffffffull 67 + #define XSCOM_ADDR_FORM1_LOW 0x000ffffffffull 68 + #define XSCOM_ADDR_FORM1_HI 0xfff00000000ull 69 + #define XSCOM_ADDR_FORM1_HI_SHIFT 20 70 + 71 + /* Retries */ 72 + #define SCOM_MAX_RETRIES 100 /* Retries on busy */ 73 + #define SCOM_MAX_IND_RETRIES 10 /* Retries indirect not ready */ 54 74 55 75 struct scom_device { 56 76 struct list_head link; ··· 80 56 struct miscdevice mdev; 81 57 struct mutex lock; 82 58 char name[32]; 83 - int idx; 59 + int idx; 84 60 }; 85 61 86 62 #define to_scom_dev(x) container_of((x), struct scom_device, mdev) ··· 89 65 90 66 static DEFINE_IDA(scom_ida); 91 67 92 - static int put_scom(struct scom_device *scom_dev, uint64_t value, 93 - uint32_t addr) 68 + static int __put_scom(struct scom_device *scom_dev, uint64_t value, 69 + uint32_t addr, uint32_t *status) 94 70 { 95 - __be32 data; 71 + __be32 data, raw_status; 96 72 int rc; 97 - 98 - mutex_lock(&scom_dev->lock); 99 73 100 74 data = cpu_to_be32((value >> 32) & 0xffffffff); 101 75 rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA0_REG, &data, 102 76 sizeof(uint32_t)); 103 77 if (rc) 104 - goto bail; 78 + return rc; 105 79 106 80 data = cpu_to_be32(value & 0xffffffff); 107 81 rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA1_REG, &data, 108 82 sizeof(uint32_t)); 109 83 if (rc) 110 - goto bail; 84 + return rc; 111 85 112 86 data = cpu_to_be32(SCOM_WRITE_CMD | addr); 113 87 rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, &data, 114 88 sizeof(uint32_t)); 115 - bail: 116 - mutex_unlock(&scom_dev->lock); 117 - return rc; 89 + if (rc) 90 + return rc; 91 + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, &raw_status, 92 + sizeof(uint32_t)); 93 + if (rc) 94 + return rc; 95 + *status = be32_to_cpu(raw_status); 96 + 97 + return 0; 118 98 } 119 99 120 - static int get_scom(struct scom_device *scom_dev, uint64_t *value, 121 - uint32_t addr) 100 + static int __get_scom(struct scom_device *scom_dev, uint64_t *value, 101 + uint32_t addr, uint32_t *status) 122 102 { 123 - __be32 result, data; 103 + __be32 data, raw_status; 124 104 int rc; 125 105 126 106 127 - mutex_lock(&scom_dev->lock); 128 107 *value = 0ULL; 129 108 data = cpu_to_be32(SCOM_READ_CMD | addr); 130 109 rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, &data, 131 110 sizeof(uint32_t)); 132 111 if (rc) 133 - goto bail; 112 + return rc; 113 + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, &raw_status, 114 + sizeof(uint32_t)); 115 + if (rc) 116 + return rc; 134 117 135 - rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, &result, 118 + /* 119 + * Read the data registers even on error, so we don't have 120 + * to interpret the status register here. 121 + */ 122 + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, &data, 136 123 sizeof(uint32_t)); 137 124 if (rc) 138 - goto bail; 139 - 140 - *value |= (uint64_t)be32_to_cpu(result) << 32; 141 - rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, &result, 125 + return rc; 126 + *value |= (uint64_t)be32_to_cpu(data) << 32; 127 + rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, &data, 142 128 sizeof(uint32_t)); 143 129 if (rc) 144 - goto bail; 130 + return rc; 131 + *value |= be32_to_cpu(data); 132 + *status = be32_to_cpu(raw_status); 145 133 146 - *value |= be32_to_cpu(result); 147 - bail: 148 - mutex_unlock(&scom_dev->lock); 134 + return rc; 135 + } 136 + 137 + static int put_indirect_scom_form0(struct scom_device *scom, uint64_t value, 138 + uint64_t addr, uint32_t *status) 139 + { 140 + uint64_t ind_data, ind_addr; 141 + int rc, retries, err = 0; 142 + 143 + if (value & ~XSCOM_DATA_IND_DATA) 144 + return -EINVAL; 145 + 146 + ind_addr = addr & XSCOM_ADDR_DIRECT_PART; 147 + ind_data = (addr & XSCOM_ADDR_INDIRECT_PART) | value; 148 + rc = __put_scom(scom, ind_data, ind_addr, status); 149 + if (rc || (*status & SCOM_STATUS_ANY_ERR)) 150 + return rc; 151 + 152 + for (retries = 0; retries < SCOM_MAX_IND_RETRIES; retries++) { 153 + rc = __get_scom(scom, &ind_data, addr, status); 154 + if (rc || (*status & SCOM_STATUS_ANY_ERR)) 155 + return rc; 156 + 157 + err = (ind_data & XSCOM_DATA_IND_ERR_MASK) >> XSCOM_DATA_IND_ERR_SHIFT; 158 + *status = err << SCOM_STATUS_PIB_RESP_SHIFT; 159 + if ((ind_data & XSCOM_DATA_IND_COMPLETE) || (err != SCOM_PIB_BLOCKED)) 160 + return 0; 161 + 162 + msleep(1); 163 + } 164 + return rc; 165 + } 166 + 167 + static int put_indirect_scom_form1(struct scom_device *scom, uint64_t value, 168 + uint64_t addr, uint32_t *status) 169 + { 170 + uint64_t ind_data, ind_addr; 171 + 172 + if (value & ~XSCOM_DATA_IND_FORM1_DATA) 173 + return -EINVAL; 174 + 175 + ind_addr = addr & XSCOM_ADDR_FORM1_LOW; 176 + ind_data = value | (addr & XSCOM_ADDR_FORM1_HI) << XSCOM_ADDR_FORM1_HI_SHIFT; 177 + return __put_scom(scom, ind_data, ind_addr, status); 178 + } 179 + 180 + static int get_indirect_scom_form0(struct scom_device *scom, uint64_t *value, 181 + uint64_t addr, uint32_t *status) 182 + { 183 + uint64_t ind_data, ind_addr; 184 + int rc, retries, err = 0; 185 + 186 + ind_addr = addr & XSCOM_ADDR_DIRECT_PART; 187 + ind_data = (addr & XSCOM_ADDR_INDIRECT_PART) | XSCOM_DATA_IND_READ; 188 + rc = __put_scom(scom, ind_data, ind_addr, status); 189 + if (rc || (*status & SCOM_STATUS_ANY_ERR)) 190 + return rc; 191 + 192 + for (retries = 0; retries < SCOM_MAX_IND_RETRIES; retries++) { 193 + rc = __get_scom(scom, &ind_data, addr, status); 194 + if (rc || (*status & SCOM_STATUS_ANY_ERR)) 195 + return rc; 196 + 197 + err = (ind_data & XSCOM_DATA_IND_ERR_MASK) >> XSCOM_DATA_IND_ERR_SHIFT; 198 + *status = err << SCOM_STATUS_PIB_RESP_SHIFT; 199 + *value = ind_data & XSCOM_DATA_IND_DATA; 200 + 201 + if ((ind_data & XSCOM_DATA_IND_COMPLETE) || (err != SCOM_PIB_BLOCKED)) 202 + return 0; 203 + 204 + msleep(1); 205 + } 206 + return rc; 207 + } 208 + 209 + static int raw_put_scom(struct scom_device *scom, uint64_t value, 210 + uint64_t addr, uint32_t *status) 211 + { 212 + if (addr & XSCOM_ADDR_IND_FLAG) { 213 + if (addr & XSCOM_ADDR_INF_FORM1) 214 + return put_indirect_scom_form1(scom, value, addr, status); 215 + else 216 + return put_indirect_scom_form0(scom, value, addr, status); 217 + } else 218 + return __put_scom(scom, value, addr, status); 219 + } 220 + 221 + static int raw_get_scom(struct scom_device *scom, uint64_t *value, 222 + uint64_t addr, uint32_t *status) 223 + { 224 + if (addr & XSCOM_ADDR_IND_FLAG) { 225 + if (addr & XSCOM_ADDR_INF_FORM1) 226 + return -ENXIO; 227 + return get_indirect_scom_form0(scom, value, addr, status); 228 + } else 229 + return __get_scom(scom, value, addr, status); 230 + } 231 + 232 + static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status) 233 + { 234 + uint32_t dummy = -1; 235 + 236 + if (status & SCOM_STATUS_PROTECTION) 237 + return -EPERM; 238 + if (status & SCOM_STATUS_PARITY) { 239 + fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, 240 + sizeof(uint32_t)); 241 + return -EIO; 242 + } 243 + /* Return -EBUSY on PIB abort to force a retry */ 244 + if (status & SCOM_STATUS_PIB_ABORT) 245 + return -EBUSY; 246 + if (status & SCOM_STATUS_ERR_SUMMARY) { 247 + fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, 248 + sizeof(uint32_t)); 249 + return -EIO; 250 + } 251 + return 0; 252 + } 253 + 254 + static int handle_pib_status(struct scom_device *scom, uint8_t status) 255 + { 256 + uint32_t dummy = -1; 257 + 258 + if (status == SCOM_PIB_SUCCESS) 259 + return 0; 260 + if (status == SCOM_PIB_BLOCKED) 261 + return -EBUSY; 262 + 263 + /* Reset the bridge */ 264 + fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, 265 + sizeof(uint32_t)); 266 + 267 + switch(status) { 268 + case SCOM_PIB_OFFLINE: 269 + return -ENODEV; 270 + case SCOM_PIB_BAD_ADDR: 271 + return -ENXIO; 272 + case SCOM_PIB_TIMEOUT: 273 + return -ETIMEDOUT; 274 + case SCOM_PIB_PARTIAL: 275 + case SCOM_PIB_CLK_ERR: 276 + case SCOM_PIB_PARITY_ERR: 277 + default: 278 + return -EIO; 279 + } 280 + } 281 + 282 + static int put_scom(struct scom_device *scom, uint64_t value, 283 + uint64_t addr) 284 + { 285 + uint32_t status, dummy = -1; 286 + int rc, retries; 287 + 288 + for (retries = 0; retries < SCOM_MAX_RETRIES; retries++) { 289 + rc = raw_put_scom(scom, value, addr, &status); 290 + if (rc) { 291 + /* Try resetting the bridge if FSI fails */ 292 + if (rc != -ENODEV && retries == 0) { 293 + fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, 294 + &dummy, sizeof(uint32_t)); 295 + rc = -EBUSY; 296 + } else 297 + return rc; 298 + } else 299 + rc = handle_fsi2pib_status(scom, status); 300 + if (rc && rc != -EBUSY) 301 + break; 302 + if (rc == 0) { 303 + rc = handle_pib_status(scom, 304 + (status & SCOM_STATUS_PIB_RESP_MASK) 305 + >> SCOM_STATUS_PIB_RESP_SHIFT); 306 + if (rc && rc != -EBUSY) 307 + break; 308 + } 309 + if (rc == 0) 310 + break; 311 + msleep(1); 312 + } 313 + return rc; 314 + } 315 + 316 + static int get_scom(struct scom_device *scom, uint64_t *value, 317 + uint64_t addr) 318 + { 319 + uint32_t status, dummy = -1; 320 + int rc, retries; 321 + 322 + for (retries = 0; retries < SCOM_MAX_RETRIES; retries++) { 323 + rc = raw_get_scom(scom, value, addr, &status); 324 + if (rc) { 325 + /* Try resetting the bridge if FSI fails */ 326 + if (rc != -ENODEV && retries == 0) { 327 + fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, 328 + &dummy, sizeof(uint32_t)); 329 + rc = -EBUSY; 330 + } else 331 + return rc; 332 + } else 333 + rc = handle_fsi2pib_status(scom, status); 334 + if (rc && rc != -EBUSY) 335 + break; 336 + if (rc == 0) { 337 + rc = handle_pib_status(scom, 338 + (status & SCOM_STATUS_PIB_RESP_MASK) 339 + >> SCOM_STATUS_PIB_RESP_SHIFT); 340 + if (rc && rc != -EBUSY) 341 + break; 342 + } 343 + if (rc == 0) 344 + break; 345 + msleep(1); 346 + } 149 347 return rc; 150 348 } 151 349 152 350 static ssize_t scom_read(struct file *filep, char __user *buf, size_t len, 153 351 loff_t *offset) 154 352 { 155 - int rc; 156 353 struct miscdevice *mdev = 157 354 (struct miscdevice *)filep->private_data; 158 355 struct scom_device *scom = to_scom_dev(mdev); 159 356 struct device *dev = &scom->fsi_dev->dev; 160 357 uint64_t val; 358 + int rc; 161 359 162 360 if (len != sizeof(uint64_t)) 163 361 return -EINVAL; 164 362 363 + mutex_lock(&scom->lock); 165 364 rc = get_scom(scom, &val, *offset); 365 + mutex_unlock(&scom->lock); 166 366 if (rc) { 167 367 dev_dbg(dev, "get_scom fail:%d\n", rc); 168 368 return rc; ··· 417 169 return -EINVAL; 418 170 } 419 171 172 + mutex_lock(&scom->lock); 420 173 rc = put_scom(scom, val, *offset); 174 + mutex_unlock(&scom->lock); 421 175 if (rc) { 422 176 dev_dbg(dev, "put_scom failed with:%d\n", rc); 423 177 return rc; ··· 443 193 return offset; 444 194 } 445 195 196 + static void raw_convert_status(struct scom_access *acc, uint32_t status) 197 + { 198 + acc->pib_status = (status & SCOM_STATUS_PIB_RESP_MASK) >> 199 + SCOM_STATUS_PIB_RESP_SHIFT; 200 + acc->intf_errors = 0; 201 + 202 + if (status & SCOM_STATUS_PROTECTION) 203 + acc->intf_errors |= SCOM_INTF_ERR_PROTECTION; 204 + else if (status & SCOM_STATUS_PARITY) 205 + acc->intf_errors |= SCOM_INTF_ERR_PARITY; 206 + else if (status & SCOM_STATUS_PIB_ABORT) 207 + acc->intf_errors |= SCOM_INTF_ERR_ABORT; 208 + else if (status & SCOM_STATUS_ERR_SUMMARY) 209 + acc->intf_errors |= SCOM_INTF_ERR_UNKNOWN; 210 + } 211 + 212 + static int scom_raw_read(struct scom_device *scom, void __user *argp) 213 + { 214 + struct scom_access acc; 215 + uint32_t status; 216 + int rc; 217 + 218 + if (copy_from_user(&acc, argp, sizeof(struct scom_access))) 219 + return -EFAULT; 220 + 221 + rc = raw_get_scom(scom, &acc.data, acc.addr, &status); 222 + if (rc) 223 + return rc; 224 + raw_convert_status(&acc, status); 225 + if (copy_to_user(argp, &acc, sizeof(struct scom_access))) 226 + return -EFAULT; 227 + return 0; 228 + } 229 + 230 + static int scom_raw_write(struct scom_device *scom, void __user *argp) 231 + { 232 + u64 prev_data, mask, data; 233 + struct scom_access acc; 234 + uint32_t status; 235 + int rc; 236 + 237 + if (copy_from_user(&acc, argp, sizeof(struct scom_access))) 238 + return -EFAULT; 239 + 240 + if (acc.mask) { 241 + rc = raw_get_scom(scom, &prev_data, acc.addr, &status); 242 + if (rc) 243 + return rc; 244 + if (status & SCOM_STATUS_ANY_ERR) 245 + goto fail; 246 + mask = acc.mask; 247 + } else { 248 + prev_data = mask = -1ull; 249 + } 250 + data = (prev_data & ~mask) | (acc.data & mask); 251 + rc = raw_put_scom(scom, data, acc.addr, &status); 252 + if (rc) 253 + return rc; 254 + fail: 255 + raw_convert_status(&acc, status); 256 + if (copy_to_user(argp, &acc, sizeof(struct scom_access))) 257 + return -EFAULT; 258 + return 0; 259 + } 260 + 261 + static int scom_reset(struct scom_device *scom, void __user *argp) 262 + { 263 + uint32_t flags, dummy = -1; 264 + int rc = 0; 265 + 266 + if (get_user(flags, (__u32 __user *)argp)) 267 + return -EFAULT; 268 + if (flags & SCOM_RESET_PIB) 269 + rc = fsi_device_write(scom->fsi_dev, SCOM_PIB_RESET_REG, &dummy, 270 + sizeof(uint32_t)); 271 + if (!rc && (flags & (SCOM_RESET_PIB | SCOM_RESET_INTF))) 272 + rc = fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, 273 + sizeof(uint32_t)); 274 + return rc; 275 + } 276 + 277 + static int scom_check(struct scom_device *scom, void __user *argp) 278 + { 279 + /* Still need to find out how to get "protected" */ 280 + return put_user(SCOM_CHECK_SUPPORTED, (__u32 __user *)argp); 281 + } 282 + 283 + static long scom_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 284 + { 285 + struct miscdevice *mdev = file->private_data; 286 + struct scom_device *scom = to_scom_dev(mdev); 287 + void __user *argp = (void __user *)arg; 288 + int rc = -ENOTTY; 289 + 290 + mutex_lock(&scom->lock); 291 + switch(cmd) { 292 + case FSI_SCOM_CHECK: 293 + rc = scom_check(scom, argp); 294 + break; 295 + case FSI_SCOM_READ: 296 + rc = scom_raw_read(scom, argp); 297 + break; 298 + case FSI_SCOM_WRITE: 299 + rc = scom_raw_write(scom, argp); 300 + break; 301 + case FSI_SCOM_RESET: 302 + rc = scom_reset(scom, argp); 303 + break; 304 + } 305 + mutex_unlock(&scom->lock); 306 + return rc; 307 + } 308 + 446 309 static const struct file_operations scom_fops = { 447 - .owner = THIS_MODULE, 448 - .llseek = scom_llseek, 449 - .read = scom_read, 450 - .write = scom_write, 310 + .owner = THIS_MODULE, 311 + .llseek = scom_llseek, 312 + .read = scom_read, 313 + .write = scom_write, 314 + .unlocked_ioctl = scom_ioctl, 451 315 }; 452 316 453 317 static int scom_probe(struct device *dev)
+58
include/uapi/linux/fsi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ 2 + #ifndef _UAPI_LINUX_FSI_H 3 + #define _UAPI_LINUX_FSI_H 4 + 5 + #include <linux/types.h> 6 + #include <linux/ioctl.h> 7 + 8 + /* 9 + * /dev/scom "raw" ioctl interface 10 + * 11 + * The driver supports a high level "read/write" interface which 12 + * handles retries and converts the status to Linux error codes, 13 + * however low level tools an debugger need to access the "raw" 14 + * HW status information and interpret it themselves, so this 15 + * ioctl interface is also provided for their use case. 16 + */ 17 + 18 + /* Structure for SCOM read/write */ 19 + struct scom_access { 20 + __u64 addr; /* SCOM address, supports indirect */ 21 + __u64 data; /* SCOM data (in for write, out for read) */ 22 + __u64 mask; /* Data mask for writes */ 23 + __u32 intf_errors; /* Interface error flags */ 24 + #define SCOM_INTF_ERR_PARITY 0x00000001 /* Parity error */ 25 + #define SCOM_INTF_ERR_PROTECTION 0x00000002 /* Blocked by secure boot */ 26 + #define SCOM_INTF_ERR_ABORT 0x00000004 /* PIB reset during access */ 27 + #define SCOM_INTF_ERR_UNKNOWN 0x80000000 /* Unknown error */ 28 + /* 29 + * Note: Any other bit set in intf_errors need to be considered as an 30 + * error. Future implementations may define new error conditions. The 31 + * pib_status below is only valid if intf_errors is 0. 32 + */ 33 + __u8 pib_status; /* 3-bit PIB status */ 34 + #define SCOM_PIB_SUCCESS 0 /* Access successful */ 35 + #define SCOM_PIB_BLOCKED 1 /* PIB blocked, pls retry */ 36 + #define SCOM_PIB_OFFLINE 2 /* Chiplet offline */ 37 + #define SCOM_PIB_PARTIAL 3 /* Partial good */ 38 + #define SCOM_PIB_BAD_ADDR 4 /* Invalid address */ 39 + #define SCOM_PIB_CLK_ERR 5 /* Clock error */ 40 + #define SCOM_PIB_PARITY_ERR 6 /* Parity error on the PIB bus */ 41 + #define SCOM_PIB_TIMEOUT 7 /* Bus timeout */ 42 + __u8 pad; 43 + }; 44 + 45 + /* Flags for SCOM check */ 46 + #define SCOM_CHECK_SUPPORTED 0x00000001 /* Interface supported */ 47 + #define SCOM_CHECK_PROTECTED 0x00000002 /* Interface blocked by secure boot */ 48 + 49 + /* Flags for SCOM reset */ 50 + #define SCOM_RESET_INTF 0x00000001 /* Reset interface */ 51 + #define SCOM_RESET_PIB 0x00000002 /* Reset PIB */ 52 + 53 + #define FSI_SCOM_CHECK _IOR('s', 0x00, __u32) 54 + #define FSI_SCOM_READ _IOWR('s', 0x01, struct scom_access) 55 + #define FSI_SCOM_WRITE _IOWR('s', 0x02, struct scom_access) 56 + #define FSI_SCOM_RESET _IOW('s', 0x03, __u32) 57 + 58 + #endif /* _UAPI_LINUX_FSI_H */