in fsi-scom.c [432:461]
static int scom_raw_write(struct scom_device *scom, void __user *argp)
{
u64 prev_data, mask, data;
struct scom_access acc;
uint32_t status;
int rc;
if (copy_from_user(&acc, argp, sizeof(struct scom_access)))
return -EFAULT;
if (acc.mask) {
rc = raw_get_scom(scom, &prev_data, acc.addr, &status);
if (rc)
return rc;
if (status & SCOM_STATUS_ANY_ERR)
goto fail;
mask = acc.mask;
} else {
prev_data = mask = -1ull;
}
data = (prev_data & ~mask) | (acc.data & mask);
rc = raw_put_scom(scom, data, acc.addr, &status);
if (rc)
return rc;
fail:
raw_convert_status(&acc, status);
if (copy_to_user(argp, &acc, sizeof(struct scom_access)))
return -EFAULT;
return 0;
}