コード例 #1
0
ファイル: opal-dump.c プロジェクト: MaybeS/linux
static int process_dump(void)
{
	int rc;
	uint32_t dump_id, dump_size, dump_type;
	struct dump_obj *dump;
	char name[22];

	rc = dump_read_info(&dump_id, &dump_size, &dump_type);
	if (rc != OPAL_SUCCESS)
		return rc;

	sprintf(name, "0x%x-0x%x", dump_type, dump_id);

	/* we may get notified twice, let's handle
	 * that gracefully and not create two conflicting
	 * entries.
	 */
	if (kset_find_obj(dump_kset, name))
		return 0;

	dump = create_dump_obj(dump_id, dump_size, dump_type);
	if (!dump)
		return -1;

	return 0;
}
コード例 #2
0
/*
 * Add sysfs entries for the sleep modes.
 */
static int __init msm_pm_mode_sysfs_add(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *modes_kobj = NULL;
	unsigned int cpu;
	int ret;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		printk(KERN_ERR "%s: cannot find kobject for module %s\n",
			__func__, KBUILD_MODNAME);
		ret = -ENOENT;
		goto mode_sysfs_add_exit;
	}

	modes_kobj = kobject_create_and_add("modes", module_kobj);
	if (!modes_kobj) {
		printk(KERN_ERR "%s: cannot create modes kobject\n", __func__);
		ret = -ENOMEM;
		goto mode_sysfs_add_exit;
	}

	for_each_possible_cpu(cpu) {
		ret = msm_pm_mode_sysfs_add_cpu(cpu, modes_kobj);
		if (ret)
			goto mode_sysfs_add_exit;
	}

	ret = 0;

mode_sysfs_add_exit:
	return ret;
}
コード例 #3
0
/**
 *	driver_find - locate driver on a bus by its name.
 *	@name:	name of the driver.
 *	@bus:	bus to scan for the driver.
 *
 *	Call kset_find_obj() to iterate over list of drivers on
 *	a bus to find driver by name. Return driver if found.
 *
 *	Note that kset_find_obj increments driver's reference count.
 */
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
	struct kobject *k = kset_find_obj(&bus->drivers, name);
	if (k)
		return to_drv(k);
	return NULL;
}
コード例 #4
0
static __init int msm_thermal_add_cc_nodes(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *cc_kobj = NULL;
	int ret = 0;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		pr_err("%s: cannot find kobject for module\n",
			KBUILD_MODNAME);
		ret = -ENOENT;
		goto done_cc_nodes;
	}

	cc_kobj = kobject_create_and_add("core_control", module_kobj);
	if (!cc_kobj) {
		pr_err("%s: cannot create core control kobj\n",
				KBUILD_MODNAME);
		ret = -ENOMEM;
		goto done_cc_nodes;
	}

	ret = sysfs_create_group(cc_kobj, &cc_attr_group);
	if (ret) {
		pr_err("%s: cannot create group\n", KBUILD_MODNAME);
		goto done_cc_nodes;
	}

	return 0;

done_cc_nodes:
	if (cc_kobj)
		kobject_del(cc_kobj);
	return ret;
}
コード例 #5
0
ファイル: msm_thermal.c プロジェクト: sparkmbox/singh-kernel
static __init int msm_thermal_add_timer_nodes(void)
{
	struct kobject *module_kobj = NULL;
	int ret = 0;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		pr_err("%s: cannot find kobject for module\n",
			KBUILD_MODNAME);
		ret = -ENOENT;
		goto failed;
	}

	tt_kobj = kobject_create_and_add("thermal_timer", module_kobj);
	if (!tt_kobj) {
		pr_err("%s: cannot create timer kobj\n",
				KBUILD_MODNAME);
		ret = -ENOMEM;
		goto failed;
	}

	ret = sysfs_create_group(tt_kobj, &tt_attr_group);
	if (ret) {
		pr_err("%s: cannot create group\n", KBUILD_MODNAME);
		goto failed;
	}

	return 0;

failed:
	if (tt_kobj)
		kobject_del(tt_kobj);
	return ret;
}
コード例 #6
0
ファイル: vio.c プロジェクト: PennPanda/linux-repo
/* vio_find_name() - internal because only vio.c knows how we formatted the
 * kobject name
 * XXX once vio_bus_type.devices is actually used as a kset in
 * drivers/base/bus.c, this function should be removed in favor of
 * "device_find(kobj_name, &vio_bus_type)"
 */
static struct vio_dev *vio_find_name(const char *kobj_name)
{
	struct kobject *found;

	found = kset_find_obj(&devices_subsys, kobj_name);
	if (!found)
		return NULL;

	return to_vio_dev(container_of(found, struct device, kobj));
}
コード例 #7
0
ファイル: driver.c プロジェクト: Aresthu/ucore_plus
/**
 * driver_find - locate driver on a bus by its name.
 * @name: name of the driver.
 * @bus: bus to scan for the driver.
 *
 * Call kset_find_obj() to iterate over list of drivers on
 * a bus to find driver by name. Return driver if found.
 *
 * Note that kset_find_obj increments driver's reference count.
 */
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
	struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
	struct driver_private *priv;

	if (k) {
		priv = to_driver(k);
		return priv->driver;
	}
	return NULL;
}
コード例 #8
0
ファイル: driver.c プロジェクト: nos1609/Chrono_Kernel-1
/**
 * driver_find - locate driver on a bus by its name.
 * @name: name of the driver.
 * @bus: bus to scan for the driver.
 *
 * Call kset_find_obj() to iterate over list of drivers on
 * a bus to find driver by name. Return driver if found.
 *
 * This routine provides no locking to prevent the driver it returns
 * from being unregistered or unloaded while the caller is using it.
 * The caller is responsible for preventing this.
 */
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
	struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
	struct driver_private *priv;

	if (k) {
		/* Drop reference added by kset_find_obj() */
		kobject_put(k);
		priv = to_driver(k);
		return priv->driver;
	}
	return NULL;
}
コード例 #9
0
ファイル: ipcp-factories.c プロジェクト: javiergll/stack
struct ipcp_factory * ipcpf_find(struct ipcp_factories * factories,
                                 const char *            name)
{
        struct kobject * k;

        if (!factories || !factories->set || !string_is_ok(name))
                return NULL;

        k = kset_find_obj(factories->set, name);
        if (k) {
                kobject_put(k);
                return to_ipcp(k);
        }

        return NULL;
}
コード例 #10
0
ファイル: slot.c プロジェクト: Lyude/linux
/**
 * pci_hp_create_link - create symbolic link to the hotplug driver module.
 * @pci_slot: struct pci_slot
 *
 * Helper function for pci_hotplug_core.c to create symbolic link to
 * the hotplug driver module.
 */
void pci_hp_create_module_link(struct pci_slot *pci_slot)
{
	struct hotplug_slot *slot = pci_slot->hotplug;
	struct kobject *kobj = NULL;
	int ret;

	if (!slot || !slot->ops)
		return;
	kobj = kset_find_obj(module_kset, slot->ops->mod_name);
	if (!kobj)
		return;
	ret = sysfs_create_link(&pci_slot->kobj, kobj, "module");
	if (ret)
		dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n",
			ret);
	kobject_put(kobj);
}
コード例 #11
0
ファイル: opal-elog.c プロジェクト: KutuSystems/kutu_linux
static irqreturn_t elog_event(int irq, void *data)
{
	__be64 size;
	__be64 id;
	__be64 type;
	uint64_t elog_size;
	uint64_t log_id;
	uint64_t elog_type;
	int rc;
	char name[2+16+1];
	struct kobject *kobj;

	rc = opal_get_elog_size(&id, &size, &type);
	if (rc != OPAL_SUCCESS) {
		pr_err("ELOG: OPAL log info read failed\n");
		return IRQ_HANDLED;
	}

	elog_size = be64_to_cpu(size);
	log_id = be64_to_cpu(id);
	elog_type = be64_to_cpu(type);

	WARN_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);

	if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
		elog_size  =  OPAL_MAX_ERRLOG_SIZE;

	sprintf(name, "0x%llx", log_id);

	/* we may get notified twice, let's handle
	 * that gracefully and not create two conflicting
	 * entries.
	 */
	kobj = kset_find_obj(elog_kset, name);
	if (kobj) {
		/* Drop reference added by kset_find_obj() */
		kobject_put(kobj);
		return IRQ_HANDLED;
	}

	create_elog_obj(log_id, elog_size, elog_type);

	return IRQ_HANDLED;
}
コード例 #12
0
static int __init qdss_sysfs_init(void)
{
	int ret;

	qdss.modulekobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!qdss.modulekobj) {
		pr_err("failed to find QDSS sysfs module kobject\n");
		ret = -ENOENT;
		goto err;
	}

	ret = sysfs_create_file(qdss.modulekobj, &max_clk_attr.attr);
	if (ret) {
		pr_err("failed to create QDSS sysfs max_clk attribute\n");
		goto err;
	}

	return 0;
err:
	return ret;
}
コード例 #13
0
ファイル: coresight.c プロジェクト: 0x7678/SJKernel-gn2
static int __init coresight_sysfs_init(void)
{
	int ret;

	coresight.modulekobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!coresight.modulekobj) {
		pr_err("failed to find CORESIGHT sysfs module kobject\n");
		ret = -ENOENT;
		goto err;
	}

	ret = sysfs_create_file(coresight.modulekobj, &max_clk_attr.attr);
	if (ret) {
		pr_err("failed to create CORESIGHT sysfs max_clk attribute\n");
		goto err;
	}

	return 0;
err:
	return ret;
}
コード例 #14
0
ファイル: iommu.c プロジェクト: ramlaxman/linux
struct iommu_group *iommu_group_get_by_id(int id)
{
	struct kobject *group_kobj;
	struct iommu_group *group;
	const char *name;

	if (!iommu_group_kset)
		return NULL;

	name = kasprintf(GFP_KERNEL, "%d", id);
	if (!name)
		return NULL;

	group_kobj = kset_find_obj(iommu_group_kset, name);
	kfree(name);

	if (!group_kobj)
		return NULL;

	group = container_of(group_kobj, struct iommu_group, kobj);
	BUG_ON(group->id != 
コード例 #15
0
ファイル: module.c プロジェクト: CSCLOG/beaglebone
void module_add_driver(struct module *mod, struct device_driver *drv)
{
	char *driver_name;
	int no_warn;
	struct module_kobject *mk = NULL;

	if (!drv)
		return;

	if (mod)
		mk = &mod->mkobj;
	else if (drv->mod_name) {
		struct kobject *mkobj;

		/* Lookup built-in module entry in /sys/modules */
		mkobj = kset_find_obj(module_kset, drv->mod_name);
		if (mkobj) {
			mk = container_of(mkobj, struct module_kobject, kobj);
			/* remember our module structure */
			drv->p->mkobj = mk;
			/* kset_find_obj took a reference */
			kobject_put(mkobj);
		}
	}

	if (!mk)
		return;

	/* Don't check return codes; these calls are idempotent */
	no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
	driver_name = make_driver_name(drv);
	if (driver_name) {
		module_create_drivers_dir(mk);
		no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
					    driver_name);
		kfree(driver_name);
	}
}
コード例 #16
0
void module_add_driver(struct module *mod, struct device_driver *drv)
{
	char *driver_name;
	int no_warn;
	struct module_kobject *mk = NULL;

	if (!drv)
		return;

	if (mod)
		mk = &mod->mkobj;
	else if (drv->mod_name) {
		struct kobject *mkobj;

		
		mkobj = kset_find_obj(module_kset, drv->mod_name);
		if (mkobj) {
			mk = container_of(mkobj, struct module_kobject, kobj);
			
			drv->p->mkobj = mk;
			
			kobject_put(mkobj);
		}
	}

	if (!mk)
		return;

	
	no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
	driver_name = make_driver_name(drv);
	if (driver_name) {
		module_create_drivers_dir(mk);
		no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
					    driver_name);
		kfree(driver_name);
	}
}
コード例 #17
0
ファイル: slot.c プロジェクト: Lyude/linux
static char *make_slot_name(const char *name)
{
	char *new_name;
	int len, max, dup;

	new_name = kstrdup(name, GFP_KERNEL);
	if (!new_name)
		return NULL;

	/*
	 * Make sure we hit the realloc case the first time through the
	 * loop.  'len' will be strlen(name) + 3 at that point which is
	 * enough space for "name-X" and the trailing NUL.
	 */
	len = strlen(name) + 2;
	max = 1;
	dup = 1;

	for (;;) {
		struct kobject *dup_slot;
		dup_slot = kset_find_obj(pci_slots_kset, new_name);
		if (!dup_slot)
			break;
		kobject_put(dup_slot);
		if (dup == max) {
			len++;
			max *= 10;
			kfree(new_name);
			new_name = kmalloc(len, GFP_KERNEL);
			if (!new_name)
				break;
		}
		sprintf(new_name, "%s-%d", name, dup++);
	}

	return new_name;
}
コード例 #18
0
ファイル: opal-elog.c プロジェクト: envieid0c/kernel
static void elog_work_fn(struct work_struct *work)
{
	__be64 size;
	__be64 id;
	__be64 type;
	uint64_t elog_size;
	uint64_t log_id;
	uint64_t elog_type;
	int rc;
	char name[2+16+1];

	rc = opal_get_elog_size(&id, &size, &type);
	if (rc != OPAL_SUCCESS) {
		pr_err("ELOG: OPAL log info read failed\n");
		return;
	}

	elog_size = be64_to_cpu(size);
	log_id = be64_to_cpu(id);
	elog_type = be64_to_cpu(type);

	WARN_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);

	if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
		elog_size  =  OPAL_MAX_ERRLOG_SIZE;

	sprintf(name, "0x%llx", log_id);

	/* we may get notified twice, let's handle
	 * that gracefully and not create two conflicting
	 * entries.
	 */
	if (kset_find_obj(elog_kset, name))
		return;

	create_elog_obj(log_id, elog_size, elog_type);
}
コード例 #19
0
ファイル: msm_thermal.c プロジェクト: sparkmbox/singh-kernel
static int msm_thermal_add_vdd_rstr_nodes(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *vdd_rstr_kobj = NULL;
	struct kobject *vdd_rstr_reg_kobj[MAX_RAILS] = {0};
	int rc = 0;
	int i = 0;

	if (!vdd_rstr_probed) {
		vdd_rstr_nodes_called = true;
		return rc;
	}

	if (vdd_rstr_probed && rails_cnt == 0)
		return rc;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		pr_err("%s: cannot find kobject for module %s\n",
			__func__, KBUILD_MODNAME);
		rc = -ENOENT;
		goto thermal_sysfs_add_exit;
	}

	vdd_rstr_kobj = kobject_create_and_add("vdd_restriction", module_kobj);
	if (!vdd_rstr_kobj) {
		pr_err("%s: cannot create vdd_restriction kobject\n", __func__);
		rc = -ENOMEM;
		goto thermal_sysfs_add_exit;
	}

	rc = sysfs_create_group(vdd_rstr_kobj, &vdd_rstr_en_attribs_gp);
	if (rc) {
		pr_err("%s: cannot create kobject attribute group\n", __func__);
		rc = -ENOMEM;
		goto thermal_sysfs_add_exit;
	}

	for (i = 0; i < rails_cnt; i++) {
		vdd_rstr_reg_kobj[i] = kobject_create_and_add(rails[i].name,
					vdd_rstr_kobj);
		if (!vdd_rstr_reg_kobj[i]) {
			pr_err("%s: cannot create for kobject for %s\n",
					__func__, rails[i].name);
			rc = -ENOMEM;
			goto thermal_sysfs_add_exit;
		}

		rails[i].attr_gp.attrs = kzalloc(sizeof(struct attribute *) * 3,
					GFP_KERNEL);
		if (!rails[i].attr_gp.attrs) {
			rc = -ENOMEM;
			goto thermal_sysfs_add_exit;
		}

		VDD_RES_RW_ATTRIB(rails[i], rails[i].level_attr, 0, level);
		VDD_RES_RO_ATTRIB(rails[i], rails[i].value_attr, 1, value);
		rails[i].attr_gp.attrs[2] = NULL;

		rc = sysfs_create_group(vdd_rstr_reg_kobj[i],
				&rails[i].attr_gp);
		if (rc) {
			pr_err("%s: cannot create attribute group for %s\n",
					__func__, rails[i].name);
			goto thermal_sysfs_add_exit;
		}
	}

	return rc;

thermal_sysfs_add_exit:
	if (rc) {
		for (i = 0; i < rails_cnt; i++) {
			kobject_del(vdd_rstr_reg_kobj[i]);
			kfree(rails[i].attr_gp.attrs);
		}
		if (vdd_rstr_kobj)
			kobject_del(vdd_rstr_kobj);
	}
	return rc;
}
コード例 #20
0
/*
 * Add sysfs entries for the sleep modes.
 */
static int __init msm_pm_mode_sysfs_add(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *modes_kobj = NULL;

	struct kobject *kobj;
	struct attribute_group *attr_group;
	struct attribute **attrs;
	struct kobj_attribute *kobj_attrs;

	int i, k;
	int ret;
    KDEBUG_FUNC();
	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		printk(KERN_ERR "%s: cannot find kobject for module %s\n",
			__func__, KBUILD_MODNAME);
		ret = -ENOENT;
		goto mode_sysfs_add_cleanup;
	}

	modes_kobj = kobject_create_and_add("modes", module_kobj);
	if (!modes_kobj) {
		printk(KERN_ERR "%s: cannot create modes kobject\n", __func__);
		ret = -ENOMEM;
		goto mode_sysfs_add_cleanup;
	}

	for (i = 0; i < ARRAY_SIZE(msm_pm_mode_kobjs); i++) {
		if (!msm_pm_modes[i].supported)
			continue;

		kobj = kobject_create_and_add(
				msm_pm_sleep_mode_labels[i], modes_kobj);
		attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
		attrs = kzalloc(sizeof(*attrs) * (MSM_PM_MODE_ATTR_NR + 1),
				GFP_KERNEL);
		kobj_attrs = kzalloc(sizeof(*kobj_attrs) * MSM_PM_MODE_ATTR_NR,
				GFP_KERNEL);

		if (!kobj || !attr_group || !attrs || !kobj_attrs) {
			printk(KERN_ERR
				"%s: cannot create kobject or attributes\n",
				__func__);
			ret = -ENOMEM;
			goto mode_sysfs_add_abort;
		}

		kobj_attrs[0].attr.name = MSM_PM_MODE_ATTR_SUSPEND_ENABLED;
		kobj_attrs[1].attr.name = MSM_PM_MODE_ATTR_IDLE_ENABLED;
		kobj_attrs[2].attr.name = MSM_PM_MODE_ATTR_LATENCY;
		kobj_attrs[3].attr.name = MSM_PM_MODE_ATTR_RESIDENCY;

		for (k = 0; k < MSM_PM_MODE_ATTR_NR; k++) {
			kobj_attrs[k].attr.mode = 0644;
			kobj_attrs[k].show = msm_pm_mode_attr_show;
			kobj_attrs[k].store = msm_pm_mode_attr_store;

			attrs[k] = &kobj_attrs[k].attr;
		}
		attrs[MSM_PM_MODE_ATTR_NR] = NULL;

		attr_group->attrs = attrs;
		ret = sysfs_create_group(kobj, attr_group);
		if (ret) {
			printk(KERN_ERR
				"%s: cannot create kobject attribute group\n",
				__func__);
			goto mode_sysfs_add_abort;
		}

		msm_pm_mode_kobjs[i] = kobj;
		msm_pm_mode_attr_group[i] = attr_group;
		msm_pm_mode_attrs[i] = attrs;
		msm_pm_mode_kobj_attrs[i] = kobj_attrs;
	}

	return 0;

mode_sysfs_add_abort:
	kfree(kobj_attrs);
	kfree(attrs);
	kfree(attr_group);
	kobject_put(kobj);

mode_sysfs_add_cleanup:
	for (i = ARRAY_SIZE(msm_pm_mode_kobjs) - 1; i >= 0; i--) {
		if (!msm_pm_mode_kobjs[i])
			continue;

		sysfs_remove_group(
			msm_pm_mode_kobjs[i], msm_pm_mode_attr_group[i]);

		kfree(msm_pm_mode_kobj_attrs[i]);
		kfree(msm_pm_mode_attrs[i]);
		kfree(msm_pm_mode_attr_group[i]);
		kobject_put(msm_pm_mode_kobjs[i]);
	}

	return ret;
}
コード例 #21
0
struct bus_type *find_bus(char *name)
{
	struct kobject *k = kset_find_obj(bus_kset, name);
	return k ? to_bus(k) : NULL;
}
コード例 #22
0
ファイル: msm_thermal.c プロジェクト: sparkmbox/singh-kernel
static int msm_thermal_add_psm_nodes(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *psm_kobj = NULL;
	struct kobject *psm_reg_kobj[MAX_RAILS] = {0};
	int rc = 0;
	int i = 0;

	if (!psm_probed) {
		psm_nodes_called = true;
		return rc;
	}

	if (psm_probed && psm_rails_cnt == 0)
		return rc;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		pr_err("%s: cannot find kobject for module %s\n",
			__func__, KBUILD_MODNAME);
		rc = -ENOENT;
		goto psm_node_exit;
	}

	psm_kobj = kobject_create_and_add("pmic_sw_mode", module_kobj);
	if (!psm_kobj) {
		pr_err("%s: cannot create psm kobject\n", KBUILD_MODNAME);
		rc = -ENOMEM;
		goto psm_node_exit;
	}

	for (i = 0; i < psm_rails_cnt; i++) {
		psm_reg_kobj[i] = kobject_create_and_add(psm_rails[i].name,
					psm_kobj);
		if (!psm_reg_kobj[i]) {
			pr_err("%s: cannot create for kobject for %s\n",
					KBUILD_MODNAME, psm_rails[i].name);
			rc = -ENOMEM;
			goto psm_node_exit;
		}
		psm_rails[i].attr_gp.attrs = kzalloc( \
				sizeof(struct attribute *) * 2, GFP_KERNEL);
		if (!psm_rails[i].attr_gp.attrs) {
			rc = -ENOMEM;
			goto psm_node_exit;
		}

		PSM_RW_ATTRIB(psm_rails[i], psm_rails[i].mode_attr, 0, mode);
		psm_rails[i].attr_gp.attrs[1] = NULL;

		rc = sysfs_create_group(psm_reg_kobj[i], &psm_rails[i].attr_gp);
		if (rc) {
			pr_err("%s: cannot create attribute group for %s\n",
					KBUILD_MODNAME, psm_rails[i].name);
			goto psm_node_exit;
		}
	}

	return rc;

psm_node_exit:
	if (rc) {
		for (i = 0; i < psm_rails_cnt; i++) {
			kobject_del(psm_reg_kobj[i]);
			kfree(psm_rails[i].attr_gp.attrs);
		}
		if (psm_kobj)
			kobject_del(psm_kobj);
	}
	return rc;
}
コード例 #23
0
static int intel_mid_gps_init(struct platform_device *pdev)
{
	int ret;
	struct intel_mid_gps_platform_data *pdata = dev_get_drvdata(&pdev->dev);
	struct kset *sysdev;
	struct kobject *plat;

	/* we need to rename the sysfs entry to match the one created with SFI,
	   and we are sure that there is always one GPS per platform */
	if (ACPI_HANDLE(&pdev->dev)) {
		ret = sysfs_rename_dir(&pdev->dev.kobj, DRIVER_NAME);
		if (ret)
			pr_err("%s: failed to rename sysfs entry\n", __func__);
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &intel_mid_gps_attr_group);
	if (ret)
		dev_err(&pdev->dev,
			"Failed to create intel_mid_gps sysfs interface\n");

	/* With ACPI device tree, GPS is UART child, we need to create symlink at
	   /sys/devices/platform/ level (user libgps is expecting this). */
	if (ACPI_HANDLE(&pdev->dev)) {
		sysdev = pdev->dev.kobj.kset;
		if (sysdev) {
			plat = kset_find_obj(sysdev, "platform");
			if (plat) {
				ret = sysfs_create_link(plat,
					&pdev->dev.kobj, DRIVER_NAME);
				if (ret)
					dev_err(&pdev->dev,
					"%s: symlink creation failed\n", __func__);
			}
		}
	}

	/* Handle reset GPIO */
	if (gpio_is_valid(pdata->gpio_reset)) {

		/* Request gpio */
		ret = gpio_request(pdata->gpio_reset, "intel_mid_gps_reset");
		if (ret < 0) {
			pr_err("%s: Unable to request GPIO:%d, err:%d\n",
					__func__, pdata->gpio_reset, ret);
			goto error_gpio_reset_request;
		}

		/* Force GPIO muxmode */
		lnw_gpio_set_alt(pdata->gpio_reset, LNW_GPIO);

		/* set gpio direction */
		ret = gpio_direction_output(pdata->gpio_reset, pdata->reset);
		if (ret < 0) {
			pr_err("%s: Unable to set GPIO:%d direction, err:%d\n",
					__func__, pdata->gpio_reset, ret);
			goto error_gpio_reset_direction;
		}
	}

	/* Handle enable GPIO */
	if (gpio_is_valid(pdata->gpio_enable)) {

		/* Request gpio */
		ret = gpio_request(pdata->gpio_enable, "intel_mid_gps_enable");
		if (ret < 0) {
			pr_err("%s: Unable to request GPIO:%d, err:%d\n",
					__func__, pdata->gpio_enable, ret);
			goto error_gpio_enable_request;
		}

		/* Force GPIO muxmode */
		lnw_gpio_set_alt(pdata->gpio_enable, LNW_GPIO);

		/* set gpio direction */
		ret = gpio_direction_output(pdata->gpio_enable, pdata->enable);
		if (ret < 0) {
			pr_err("%s: Unable to set GPIO:%d direction, err:%d\n",
					__func__, pdata->gpio_enable, ret);
			goto error_gpio_enable_direction;
		}
	}

	/* Handle hostwake GPIO */
	if (gpio_is_valid(pdata->gpio_hostwake)) {
		int irq_id = -EINVAL;

		/* Request gpio */
		ret = gpio_request(pdata->gpio_hostwake, "intel_mid_gps_hostwake");
		if (ret < 0) {
			pr_err("%s: Unable to request GPIO:%d, err:%d\n",
					__func__, pdata->gpio_hostwake, ret);
			goto error_gpio_hostwake_request;
		}

		/* Force GPIO muxmode */
		lnw_gpio_set_alt(pdata->gpio_hostwake, LNW_GPIO);

		/* set gpio direction */
		ret = gpio_direction_input(pdata->gpio_hostwake);
		if (ret < 0) {
			pr_err("%s: Unable to set GPIO:%d direction, err:%d\n",
					__func__, pdata->gpio_hostwake, ret);
			goto error_gpio_hostwake_direction;
		}

		/* configure irq handling */
		irq_id = gpio_to_irq(pdata->gpio_hostwake);
		irq_set_irq_wake(irq_id, 1);

		ret = request_irq(irq_id, intel_mid_gps_hostwake_isr,
				  IRQF_TRIGGER_RISING,
				  "gps_hostwake", &pdev->dev);
		if (ret) {
			pr_err("%s: unable to request irq %d \n", __func__, irq_id);
			goto error_gpio_hostwake_direction;
		}

		wake_lock_init(&hostwake_lock, WAKE_LOCK_SUSPEND, "gps_hostwake_lock");
	}

	return 0;

error_gpio_hostwake_direction:
	gpio_free(pdata->gpio_hostwake);
error_gpio_hostwake_request:
error_gpio_enable_direction:
	gpio_free(pdata->gpio_enable);
error_gpio_enable_request:
error_gpio_reset_direction:
	gpio_free(pdata->gpio_reset);
error_gpio_reset_request:
	sysfs_remove_group(&pdev->dev.kobj, &intel_mid_gps_attr_group);

	return ret;
}