Пример #1
0
/*
 * Add entries in sysfs onto the existing network class device
 * for the bridge.
 *   Adds a attribute group "bridge" containing tuning parameters.
 *   Binary attribute containing the forward table
 *   Sub directory to hold links to interfaces.
 *
 * Note: the ifobj exists only to be a subdirectory
 *   to hold links.  The ifobj exists in same data structure
 *   as it's parent the bridge so reference counting works.
 */
int br_sysfs_addbr(struct net_device *dev)
{
	struct kobject *brobj = &dev->dev.kobj;
	struct net_bridge *br = netdev_priv(dev);
	int err;

	err = sysfs_create_group(brobj, &bridge_group);
	if (err) {
		pr_info("%s: can't create group %s/%s\n",
			__func__, dev->name, bridge_group.name);
		goto out1;
	}

	err = sysfs_create_bin_file(brobj, &bridge_forward);
	if (err) {
		pr_info("%s: can't create attribute file %s/%s\n",
			__func__, dev->name, bridge_forward.attr.name);
		goto out2;
	}

	br->ifobj = kobject_create_and_add(SYSFS_BRIDGE_PORT_SUBDIR, brobj);
	if (!br->ifobj) {
		pr_info("%s: can't add kobject (directory) %s/%s\n",
			__func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
		err = -ENOMEM;
		goto out3;
	}
	return 0;
 out3:
	sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
 out2:
	sysfs_remove_group(&dev->dev.kobj, &bridge_group);
 out1:
	return err;

}
Пример #2
0
static void __exit cmos_do_remove(struct device *dev)
{
	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
	struct resource *ports;

	cmos_do_shutdown();

	sysfs_remove_bin_file(&dev->kobj, &nvram);

	if (is_valid_irq(cmos->irq)) {
		free_irq(cmos->irq, cmos->rtc);
		hpet_unregister_irq_handler(cmos_interrupt);
	}

	rtc_device_unregister(cmos->rtc);
	cmos->rtc = NULL;

	ports = cmos->iomem;
	release_region(ports->start, ports->end + 1 - ports->start);
	cmos->iomem = NULL;

	cmos->dev = NULL;
	dev_set_drvdata(dev, NULL);
}
Пример #3
0
static int m48t59_rtc_remove(struct platform_device *pdev)
{
	sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
	return 0;
}
Пример #4
0
void
qedi_remove_sysfs_attr(struct Scsi_Host *shost, struct sysfs_bin_attrs *iter)
{
	for (; iter->name; iter++)
		sysfs_remove_bin_file(&shost->shost_gendev.kobj, iter->attr);
}
Пример #5
0
static void w1_therm_remove_slave(struct w1_slave *sl)
{
	sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
}
Пример #6
0
void memconsole_exit(void)
{
	sysfs_remove_bin_file(firmware_kobj, &memconsole_bin_attr);
}
Пример #7
0
int qib_create_port_files(struct ib_device *ibdev, u8 port_num,
			  struct kobject *kobj)
{
	struct qib_pportdata *ppd;
	struct qib_devdata *dd = dd_from_ibdev(ibdev);
	int ret;

	if (!port_num || port_num > dd->num_pports) {
		qib_dev_err(dd,
			"Skipping infiniband class with invalid port %u\n",
			port_num);
		ret = -ENODEV;
		goto bail;
	}
	ppd = &dd->pport[port_num - 1];

	ret = kobject_init_and_add(&ppd->pport_kobj, &qib_port_ktype, kobj,
				   "linkcontrol");
	if (ret) {
		qib_dev_err(dd,
			"Skipping linkcontrol sysfs info, (err %d) port %u\n",
			ret, port_num);
		goto bail;
	}
	kobject_uevent(&ppd->pport_kobj, KOBJ_ADD);

	ret = kobject_init_and_add(&ppd->sl2vl_kobj, &qib_sl2vl_ktype, kobj,
				   "sl2vl");
	if (ret) {
		qib_dev_err(dd,
			"Skipping sl2vl sysfs info, (err %d) port %u\n",
			ret, port_num);
		goto bail_link;
	}
	kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD);

	ret = kobject_init_and_add(&ppd->diagc_kobj, &qib_diagc_ktype, kobj,
				   "diag_counters");
	if (ret) {
		qib_dev_err(dd,
			"Skipping diag_counters sysfs info, (err %d) port %u\n",
			ret, port_num);
		goto bail_sl;
	}
	kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD);

	if (!qib_cc_table_size || !ppd->congestion_entries_shadow)
		return 0;

	ret = kobject_init_and_add(&ppd->pport_cc_kobj, &qib_port_cc_ktype,
				kobj, "CCMgtA");
	if (ret) {
		qib_dev_err(dd,
		 "Skipping Congestion Control sysfs info, (err %d) port %u\n",
		 ret, port_num);
		goto bail_diagc;
	}

	kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD);

	ret = sysfs_create_bin_file(&ppd->pport_cc_kobj,
				&cc_setting_bin_attr);
	if (ret) {
		qib_dev_err(dd,
		 "Skipping Congestion Control setting sysfs info, (err %d) port %u\n",
		 ret, port_num);
		goto bail_cc;
	}

	ret = sysfs_create_bin_file(&ppd->pport_cc_kobj,
				&cc_table_bin_attr);
	if (ret) {
		qib_dev_err(dd,
		 "Skipping Congestion Control table sysfs info, (err %d) port %u\n",
		 ret, port_num);
		goto bail_cc_entry_bin;
	}

	qib_devinfo(dd->pcidev,
		"IB%u: Congestion Control Agent enabled for port %d\n",
		dd->unit, port_num);

	return 0;

bail_cc_entry_bin:
	sysfs_remove_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr);
bail_cc:
	kobject_put(&ppd->pport_cc_kobj);
bail_diagc:
	kobject_put(&ppd->diagc_kobj);
bail_sl:
	kobject_put(&ppd->sl2vl_kobj);
bail_link:
	kobject_put(&ppd->pport_kobj);
bail:
	return ret;
}
Пример #8
0
void pccard_sysfs_remove_socket(struct device *dev)
{
	sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
	sysfs_remove_group(&dev->kobj, &socket_attrs);
}
Пример #9
0
static void lua_remove_sysfs_attributes(struct usb_interface *intf)
{
	sysfs_remove_bin_file(&intf->dev.kobj, &lua_control_attr);
}
Пример #10
0
static void __exit sunxi_hw_exit(void) {
	pr_info("%s: exit\n", __func__);
	misc_deregister(&sunxi_hw_dev);
	sysfs_remove_bin_file(&sunxi_hw_dev.this_device->kobj, &sunxi_hw_attrs);
}
Пример #11
0
static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	dev_t dev_no;
	struct device *device_ptr;
	struct rmidev_handle *rmidev = NULL;

	rmidev = kzalloc(sizeof(struct rmidev_handle), GFP_KERNEL);
	if (!rmidev) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to alloc mem for rmidev\n",
				__func__);
		retval = -ENOMEM;
		goto err_rmidev;
	}

	rmi4_data->rmidev = rmidev;
	rmidev->rmi4_data = rmi4_data;

	retval = rmidev_create_device_class(rmi4_data);
	if (retval < 0) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to create device class\n",
				__func__);
		goto err_device_class;
	}

	if (rmidev_major_num) {
		dev_no = MKDEV(rmidev_major_num, DEV_NUMBER);
		retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
	} else {
		retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
		if (retval < 0) {
			dev_err(&rmi4_data->i2c_client->dev,
					"%s: Failed to allocate char device region\n",
					__func__);
			goto err_device_region;
		}

		rmidev_major_num = MAJOR(dev_no);
		dev_dbg(&rmi4_data->i2c_client->dev,
				"%s: Major number of rmidev = %d\n",
				__func__, rmidev_major_num);
	}

	mutex_init(&rmidev->dev_data.file_mutex);
	cdev_init(&rmidev->dev_data.main_dev, &rmidev_fops);

	retval = cdev_add(&rmidev->dev_data.main_dev, dev_no, 1);
	if (retval < 0) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to add rmi char device\n",
				__func__);
		goto err_char_device;
	}

	dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no));
	rmidev->dev_data.device_class = rmidev_device_class;

	device_ptr = device_create(rmidev->dev_data.device_class, NULL, dev_no,
			NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no));
	if (IS_ERR(device_ptr)) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to create rmi char device\n",
				__func__);
		retval = -ENODEV;
		goto err_char_device;
	}

	retval = gpio_export(rmi4_data->board->gpio, false);
	if (retval < 0) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to export attention gpio\n",
				__func__);
	} else {
		retval = gpio_export_link(&(rmi4_data->input_dev->dev),
				"attn", rmi4_data->board->gpio);
		if (retval < 0) {
			dev_err(&rmi4_data->input_dev->dev,
					"%s Failed to create gpio symlink\n",
					__func__);
		} else {
			dev_dbg(&rmi4_data->input_dev->dev,
					"%s: Exported attention gpio %d\n",
					__func__, rmi4_data->board->gpio);
		}
	}

	rmidev->attr_dir = kobject_create_and_add(ATTRIBUTE_FOLDER_NAME,
			&rmi4_data->input_dev->dev.kobj);
	if (!rmidev->attr_dir) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to create sysfs directory\n",
				__func__);
		retval = -ENODEV;
		goto err_attr_dir;
	}

	retval = sysfs_create_bin_file(rmidev->attr_dir,
			&attr_data);
	if (retval < 0) {
		dev_err(&rmi4_data->i2c_client->dev,
				"%s: Failed to create sysfs bin file\n",
				__func__);
		goto err_sysfs_bin;
	}

	retval = sysfs_create_group(rmidev->attr_dir, &attr_group);
	if (retval < 0) {
		dev_err(&rmi4_data->input_dev->dev,
					"%s: Failed to create sysfs attributes\n", __func__);
			retval = -ENODEV;
			goto err_sysfs_attrs;
	}

	return 0;

err_sysfs_attrs:
	sysfs_remove_group(rmidev->attr_dir, &attr_group);
	sysfs_remove_bin_file(rmidev->attr_dir, &attr_data);

err_sysfs_bin:
	kobject_put(rmidev->attr_dir);

err_attr_dir:
err_char_device:
	rmidev_device_cleanup(&rmidev->dev_data);
	mutex_destroy(&rmidev->dev_data.file_mutex);
	unregister_chrdev_region(dev_no, 1);

err_device_region:
	class_destroy(rmidev_device_class);

err_device_class:
	kfree(rmidev);
	rmi4_data->rmidev = NULL;

err_rmidev:
	return retval;
}
Пример #12
0
static void __exit compbench_cleanup(void)
{
    sysfs_remove_bin_file(cb_kobj, &bin_attr_in);
    kobject_put(cb_kobj);
}
Пример #13
0
/*
 * When a device set is registered, all eeproms must be read
 * and all FRUs must be parsed
 */
int fmc_device_register_n_gw(struct fmc_device **devs, int n,
			  struct fmc_gateware *gw)
{
	struct fmc_device *fmc, **devarray;
	uint32_t device_id;
	int i, ret = 0;

	if (n < 1)
		return 0;

	/* Check the version of the first data structure (function prints) */
	if (fmc_check_version(devs[0]->version, devs[0]->carrier_name))
		return -EINVAL;

	devarray = kmemdup(devs, n * sizeof(*devs), GFP_KERNEL);
	if (!devarray)
		return -ENOMEM;

	/* Make all other checks before continuing, for all devices */
	for (i = 0; i < n; i++) {
		fmc = devarray[i];
		if (!fmc->hwdev) {
			pr_err("%s: device nr. %i has no hwdev pointer\n",
			       __func__, i);
			ret = -EINVAL;
			break;
		}
		if (fmc->flags & FMC_DEVICE_NO_MEZZANINE) {
			dev_info(fmc->hwdev, "absent mezzanine in slot %d\n",
				 fmc->slot_id);
			continue;
		}
		if (!fmc->eeprom) {
			dev_err(fmc->hwdev, "no eeprom provided for slot %i\n",
				fmc->slot_id);
			ret = -EINVAL;
		}
		if (!fmc->eeprom_addr) {
			dev_err(fmc->hwdev, "no eeprom_addr for slot %i\n",
				fmc->slot_id);
			ret = -EINVAL;
		}
		if (!fmc->carrier_name || !fmc->carrier_data ||
		    !fmc->device_id) {
			dev_err(fmc->hwdev,
				"device nr %i: carrier name, "
				"data or dev_id not set\n", i);
			ret = -EINVAL;
		}
		if (ret)
			break;

	}
	if (ret) {
		kfree(devarray);
		return ret;
	}

	/* Validation is ok. Now init and register the devices */
	for (i = 0; i < n; i++) {
		fmc = devarray[i];

		fmc->nr_slots = n; /* each slot must know how many are there */
		fmc->devarray = devarray;

		device_initialize(&fmc->dev);
		fmc->dev.release = fmc_release;
		fmc->dev.parent = fmc->hwdev;

		/* Fill the identification stuff (may fail) */
		fmc_fill_id_info(fmc);

		fmc->dev.bus = &fmc_bus_type;

		/* Name from mezzanine info or carrier info. Or 0,1,2.. */
		device_id = fmc->device_id;
		if (!fmc->mezzanine_name)
			dev_set_name(&fmc->dev, "fmc-%04x", device_id);
		else
			dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
				     device_id);

		if (gw) {
			/*
			 * The carrier already know the bitstream to load
			 * for this set of FMC mezzanines.
			 */
			ret = fmc->op->reprogram_raw(fmc, NULL,
						     gw->bitstream, gw->len);
			if (ret) {
				dev_warn(fmc->hwdev,
					 "Invalid gateware for FMC mezzanine\n");
				goto out;
			}
		}

		ret = device_add(&fmc->dev);
		if (ret < 0) {
			dev_err(fmc->hwdev, "Slot %i: Failed in registering "
				"\"%s\"\n", fmc->slot_id, fmc->dev.kobj.name);
			goto out;
		}
		ret = sysfs_create_bin_file(&fmc->dev.kobj, &fmc_eeprom_attr);
		if (ret < 0) {
			dev_err(&fmc->dev, "Failed in registering eeprom\n");
			goto out1;
		}
		/* This device went well, give information to the user */
		fmc_dump_eeprom(fmc);
		fmc_debug_init(fmc);
	}
	return 0;

out1:
	device_del(&fmc->dev);
out:
	kfree(devarray);
	for (i--; i >= 0; i--) {
		fmc_debug_exit(devs[i]);
		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
		device_del(&devs[i]->dev);
		fmc_free_id_info(devs[i]);
		put_device(&devs[i]->dev);
	}
	return ret;

}
static int __devinit mmi_battery_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct mmi_battery_info *dev_info;

	dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
	if (!dev_info) {
		ret = -ENOMEM;
		goto fail;
	}

	platform_set_drvdata(pdev, dev_info);

	dev_info->dev = &pdev->dev;
	dev_info->w1_dev = container_of(pdev->dev.parent, struct w1_slave, dev);

	dev_info->eeprom_read_cnt = 0;
	dev_info->cell_info.batt_valid = MMI_BATTERY_UNKNOWN;

	ret = device_create_file(dev_info->dev, &dev_attr_capacity);
	if (ret < 0) {
		pr_err("Failed to create capacity attribute : %d\n", ret);
		goto fail_free_dev;
	}

	ret = device_create_file(dev_info->dev, &dev_attr_is_valid);
	if (ret < 0) {
		pr_err("Failed to create is_valid attribute : %d\n", ret);
		goto fail_free_cap;
	}

	ret = device_create_file(dev_info->dev, &dev_attr_uid);
	if (ret < 0) {
		pr_err("Failed to create uid attribute : %d\n", ret);
		goto fail_free_is_valid;
	}

	ret = sysfs_create_bin_file(&dev_info->dev->kobj,
				    &mmi_battery_eeprom_attr);
	if (ret) {
		pr_err("Failed to create eeprom_bin attribute : %d\n", ret);
		goto error_create_eeprom_file;
	}

	ret = sysfs_create_bin_file(&dev_info->dev->kobj,
				    &mmi_battery_uid_attr);
	if (ret) {
		pr_err("Failed to create uid_bin attribute : %d\n", ret);
		goto error_create_uid_file;
	}

	the_batt = dev_info;

	dev_info->wq = create_singlethread_workqueue("mmi_batt_wq");
	if (!dev_info->wq) {
		ret = -ENOMEM;
		goto error_create_wq;
	}
	INIT_DELAYED_WORK(&dev_info->work,  mmi_battery_eeprom_read_work);
	queue_delayed_work(dev_info->wq, &dev_info->work,
					msecs_to_jiffies(100));
	return 0;

error_create_wq:
	sysfs_remove_bin_file(&dev_info->dev->kobj, &mmi_battery_uid_attr);
error_create_uid_file:
	sysfs_remove_bin_file(&dev_info->dev->kobj, &mmi_battery_eeprom_attr);
error_create_eeprom_file:
	device_remove_file(dev_info->dev, &dev_attr_uid);
fail_free_is_valid:
	device_remove_file(dev_info->dev, &dev_attr_is_valid);
fail_free_cap:
	device_remove_file(dev_info->dev, &dev_attr_capacity);
fail_free_dev:
	kfree(dev_info);
fail:
	return ret;
}
Пример #15
0
static int ds1682_remove(struct i2c_client *client)
{
	sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
	sysfs_remove_group(&client->dev.kobj, &ds1682_group);
	return 0;
}
Пример #16
0
void chp_remove_cmg_attr(struct channel_path *chp)
{
	sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_chars_attr);
	sysfs_remove_bin_file(&chp->dev.kobj, &chp_measurement_attr);
}
Пример #17
0
int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num,
			   struct kobject *kobj)
{
	struct hfi1_pportdata *ppd;
	struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
	int ret;

	if (!port_num || port_num > dd->num_pports) {
		dd_dev_err(dd,
			   "Skipping infiniband class with invalid port %u\n",
			   port_num);
		return -ENODEV;
	}
	ppd = &dd->pport[port_num - 1];

	ret = kobject_init_and_add(&ppd->sc2vl_kobj, &hfi1_sc2vl_ktype, kobj,
				   "sc2vl");
	if (ret) {
		dd_dev_err(dd,
			   "Skipping sc2vl sysfs info, (err %d) port %u\n",
			   ret, port_num);
		goto bail;
	}
	kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD);

	ret = kobject_init_and_add(&ppd->sl2sc_kobj, &hfi1_sl2sc_ktype, kobj,
				   "sl2sc");
	if (ret) {
		dd_dev_err(dd,
			   "Skipping sl2sc sysfs info, (err %d) port %u\n",
			   ret, port_num);
		goto bail_sc2vl;
	}
	kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD);

	ret = kobject_init_and_add(&ppd->vl2mtu_kobj, &hfi1_vl2mtu_ktype, kobj,
				   "vl2mtu");
	if (ret) {
		dd_dev_err(dd,
			   "Skipping vl2mtu sysfs info, (err %d) port %u\n",
			   ret, port_num);
		goto bail_sl2sc;
	}
	kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD);

	ret = kobject_init_and_add(&ppd->pport_cc_kobj, &port_cc_ktype,
				   kobj, "CCMgtA");
	if (ret) {
		dd_dev_err(dd,
			   "Skipping Congestion Control sysfs info, (err %d) port %u\n",
			   ret, port_num);
		goto bail_vl2mtu;
	}

	kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD);

	ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_setting_bin_attr);
	if (ret) {
		dd_dev_err(dd,
			   "Skipping Congestion Control setting sysfs info, (err %d) port %u\n",
			   ret, port_num);
		goto bail_cc;
	}

	ret = sysfs_create_bin_file(&ppd->pport_cc_kobj, &cc_table_bin_attr);
	if (ret) {
		dd_dev_err(dd,
			   "Skipping Congestion Control table sysfs info, (err %d) port %u\n",
			   ret, port_num);
		goto bail_cc_entry_bin;
	}

	dd_dev_info(dd,
		    "Congestion Control Agent enabled for port %d\n",
		    port_num);

	return 0;

bail_cc_entry_bin:
	sysfs_remove_bin_file(&ppd->pport_cc_kobj,
			      &cc_setting_bin_attr);
bail_cc:
	kobject_put(&ppd->pport_cc_kobj);
bail_vl2mtu:
	kobject_put(&ppd->vl2mtu_kobj);
bail_sl2sc:
	kobject_put(&ppd->sl2sc_kobj);
bail_sc2vl:
	kobject_put(&ppd->sc2vl_kobj);
bail:
	return ret;
}
Пример #18
0
static int ds2780_battery_probe(struct platform_device *pdev)
{
	struct power_supply_config psy_cfg = {};
	int ret = 0;
	struct ds2780_device_info *dev_info;

	dev_info = devm_kzalloc(&pdev->dev, sizeof(*dev_info), GFP_KERNEL);
	if (!dev_info) {
		ret = -ENOMEM;
		goto fail;
	}

	platform_set_drvdata(pdev, dev_info);

	dev_info->dev			= &pdev->dev;
	dev_info->w1_dev		= pdev->dev.parent;
	dev_info->bat_desc.name		= dev_name(&pdev->dev);
	dev_info->bat_desc.type		= POWER_SUPPLY_TYPE_BATTERY;
	dev_info->bat_desc.properties	= ds2780_battery_props;
	dev_info->bat_desc.num_properties = ARRAY_SIZE(ds2780_battery_props);
	dev_info->bat_desc.get_property	= ds2780_battery_get_property;

	psy_cfg.drv_data		= dev_info;

	dev_info->bat = power_supply_register(&pdev->dev, &dev_info->bat_desc,
					      &psy_cfg);
	if (IS_ERR(dev_info->bat)) {
		dev_err(dev_info->dev, "failed to register battery\n");
		ret = PTR_ERR(dev_info->bat);
		goto fail;
	}

	ret = sysfs_create_group(&dev_info->bat->dev.kobj, &ds2780_attr_group);
	if (ret) {
		dev_err(dev_info->dev, "failed to create sysfs group\n");
		goto fail_unregister;
	}

	ret = sysfs_create_bin_file(&dev_info->bat->dev.kobj,
					&ds2780_param_eeprom_bin_attr);
	if (ret) {
		dev_err(dev_info->dev,
				"failed to create param eeprom bin file");
		goto fail_remove_group;
	}

	ret = sysfs_create_bin_file(&dev_info->bat->dev.kobj,
					&ds2780_user_eeprom_bin_attr);
	if (ret) {
		dev_err(dev_info->dev,
				"failed to create user eeprom bin file");
		goto fail_remove_bin_file;
	}

	return 0;

fail_remove_bin_file:
	sysfs_remove_bin_file(&dev_info->bat->dev.kobj,
				&ds2780_param_eeprom_bin_attr);
fail_remove_group:
	sysfs_remove_group(&dev_info->bat->dev.kobj, &ds2780_attr_group);
fail_unregister:
	power_supply_unregister(dev_info->bat);
fail:
	return ret;
}