in ptp_clockmatrix.c [1233:1305]
static int idtcm_load_firmware(struct idtcm *idtcm,
struct device *dev)
{
u16 scratch = IDTCM_FW_REG(idtcm->fw_ver, V520, SCRATCH);
char fname[128] = FW_FILENAME;
const struct firmware *fw;
struct idtcm_fwrc *rec;
u32 regaddr;
int err;
s32 len;
u8 val;
u8 loaddr;
if (firmware) /* module parameter */
snprintf(fname, sizeof(fname), "%s", firmware);
dev_info(idtcm->dev, "requesting firmware '%s'", fname);
err = request_firmware(&fw, fname, dev);
if (err) {
dev_err(idtcm->dev,
"Failed at line %d in %s!", __LINE__, __func__);
return err;
}
dev_dbg(idtcm->dev, "firmware size %zu bytes", fw->size);
rec = (struct idtcm_fwrc *) fw->data;
if (contains_full_configuration(idtcm, fw))
idtcm_state_machine_reset(idtcm);
for (len = fw->size; len > 0; len -= sizeof(*rec)) {
if (rec->reserved) {
dev_err(idtcm->dev,
"bad firmware, reserved field non-zero");
err = -EINVAL;
} else {
regaddr = rec->hiaddr << 8;
regaddr |= rec->loaddr;
val = rec->value;
loaddr = rec->loaddr;
rec++;
err = check_and_set_masks(idtcm, regaddr, val);
}
if (err != -EINVAL) {
err = 0;
/* Top (status registers) and bottom are read-only */
if (regaddr < GPIO_USER_CONTROL || regaddr >= scratch)
continue;
/* Page size 128, last 4 bytes of page skipped */
if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)
continue;
err = idtcm_write(idtcm, regaddr, 0, &val, sizeof(val));
}
if (err)
goto out;
}
display_pll_and_masks(idtcm);
out:
release_firmware(fw);
return err;
}