in pmbus/ibm-cffps.c [489:612]
static int ibm_cffps_probe(struct i2c_client *client)
{
int i, rc;
enum versions vs = cffps_unknown;
struct dentry *debugfs;
struct dentry *ibm_cffps_dir;
struct ibm_cffps *psu;
const void *md = of_device_get_match_data(&client->dev);
const struct i2c_device_id *id;
if (md) {
vs = (enum versions)md;
} else {
id = i2c_match_id(ibm_cffps_id, client);
if (id)
vs = (enum versions)id->driver_data;
}
if (vs == cffps_unknown) {
u16 ccin_revision = 0;
u16 ccin_version = CFFPS_CCIN_VERSION_1;
int ccin = i2c_smbus_read_word_swapped(client, CFFPS_CCIN_CMD);
char mfg_id[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
if (ccin > 0) {
ccin_revision = FIELD_GET(CFFPS_CCIN_REVISION, ccin);
ccin_version = FIELD_GET(CFFPS_CCIN_VERSION, ccin);
}
rc = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, mfg_id);
if (rc < 0) {
dev_err(&client->dev, "Failed to read Manufacturer ID\n");
return rc;
}
switch (ccin_version) {
default:
case CFFPS_CCIN_VERSION_1:
if ((strncmp(mfg_id, "ACBE", 4) == 0) ||
(strncmp(mfg_id, "ARTE", 4) == 0))
vs = cffps1;
else
vs = cffps2;
break;
case CFFPS_CCIN_VERSION_2:
vs = cffps2;
break;
case CFFPS_CCIN_VERSION_3:
if (ccin_revision == CFFPS_CCIN_REVISION_LEGACY)
vs = cffps1;
else
vs = cffps2;
break;
}
/* Set the client name to include the version number. */
snprintf(client->name, I2C_NAME_SIZE, "cffps%d", vs + 1);
}
client->dev.platform_data = &ibm_cffps_pdata;
rc = pmbus_do_probe(client, &ibm_cffps_info[vs]);
if (rc)
return rc;
/*
* Don't fail the probe if there isn't enough memory for leds and
* debugfs.
*/
psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
if (!psu)
return 0;
psu->version = vs;
psu->client = client;
mutex_init(&psu->input_history.update_lock);
psu->input_history.last_update = jiffies - HZ;
ibm_cffps_create_led_class(psu);
/* Don't fail the probe if we can't create debugfs */
debugfs = pmbus_get_debugfs_dir(client);
if (!debugfs)
return 0;
ibm_cffps_dir = debugfs_create_dir(client->name, debugfs);
if (!ibm_cffps_dir)
return 0;
for (i = 0; i < CFFPS_DEBUGFS_NUM_ENTRIES; ++i)
psu->debugfs_entries[i] = i;
debugfs_create_file("input_history", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_INPUT_HISTORY],
&ibm_cffps_fops);
debugfs_create_file("mfg_id", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_MFG_ID],
&ibm_cffps_fops);
debugfs_create_file("fru", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_FRU],
&ibm_cffps_fops);
debugfs_create_file("part_number", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_PN],
&ibm_cffps_fops);
debugfs_create_file("header", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_HEADER],
&ibm_cffps_fops);
debugfs_create_file("serial_number", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_SN],
&ibm_cffps_fops);
debugfs_create_file("max_power_out", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_MAX_POWER_OUT],
&ibm_cffps_fops);
debugfs_create_file("ccin", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_CCIN],
&ibm_cffps_fops);
debugfs_create_file("fw_version", 0444, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_FW],
&ibm_cffps_fops);
debugfs_create_file("on_off_config", 0644, ibm_cffps_dir,
&psu->debugfs_entries[CFFPS_DEBUGFS_ON_OFF_CONFIG],
&ibm_cffps_fops);
return 0;
}