예제 #1
0
int omap_mbox_register(struct device *parent, struct omap_mbox **list)
{
	int ret;
	int i;

	mboxes = list;
	if (!mboxes)
		return -EINVAL;

	for (i = 0; mboxes[i]; i++) {
		struct omap_mbox *mbox = mboxes[i];
		mbox->dev = device_create(&omap_mbox_class,
				parent, 0, mbox, "%s", mbox->name);
		if (IS_ERR(mbox->dev)) {
			ret = PTR_ERR(mbox->dev);
			goto err_out;
		}

		BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
	}
	return 0;

err_out:
	while (i--)
		device_unregister(mboxes[i]->dev);
	return ret;
}
static int __devinit axp_mfd_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct axp_platform_data *pdata = client->dev.platform_data;
	struct axp_mfd_chip *chip;
	int ret;
	chip = kzalloc(sizeof(struct axp_mfd_chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	axp = client;
	axp_cfg_board = pdata->axp_cfg;

	chip->client = client;
	chip->dev = &client->dev;
	chip->ops = &axp_mfd_ops[id->driver_data];

	mutex_init(&chip->lock);
	INIT_WORK(&chip->irq_work, axp_mfd_irq_work);
	BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);

	i2c_set_clientdata(client, chip);

	ret = chip->ops->init_chip(chip);
	if (ret)
		goto out_free_chip;
    /*
	ret = request_irq(client->irq, axp_mfd_irq_handler,
		IRQF_DISABLED, "axp_mfd", chip);
  	if (ret) {
  		dev_err(&client->dev, "failed to request irq %d\n",
  				client->irq);
  		goto out_free_chip;
  	}
    */

	ret = axp_mfd_add_subdevs(chip, pdata);
	if (ret)
		goto out_free_irq;

	/* PM hookup */
	if(!pm_power_off)
		pm_power_off = axp_power_off;

	ret = axp_mfd_create_attrs(chip);
	if(ret){
		return ret;
	}

	return 0;

out_free_irq:
	free_irq(client->irq, chip);

out_free_chip:
	i2c_set_clientdata(client, NULL);
	kfree(chip);

	return ret;
}
예제 #3
0
static int __devinit bq27541_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    struct bq27541_info *di;
    int ret;
    int error;

    printk(KERN_INFO "%s\n",__func__);
    di = kzalloc(sizeof(*di), GFP_KERNEL);
    if (!di) {
        return -ENOMEM;
    }
    di->bat_client                     = client;
    di->dev                        = &client->dev;
    di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
    di->bat.name = "battery";
    di->bat.properties = bq27x00_battery_props;
    di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
    di->bat.get_property = bq27x00_get_property;
    di->bat.external_power_changed = NULL;
    di->temp = 0;
    di->ntc_temp = 0;
    di->voltage = 0;
    di->current_avg = 0;
    di->capacity = 0;
    di->status = 0;
    di->sec = 0;
/*Manufacturer id check function */
    di->manufacturer = UNKNOW;
    di->battery_polling = 1;fake_temp=-990;fake_full_available_capacity=0;
    di->disable_led=0;
    di->health = POWER_SUPPLY_HEALTH_GOOD;
    i2c_set_clientdata(client, di);
    ret = power_supply_register(di->dev, &di->bat);
    if (ret) {
    	dev_dbg(di->dev,"failed to register battery\n");
    	//goto bk_batt_failed;
    }
/*Manufacturer id check function */
    di->manufacturer=check_manufacturer(di);
    bq27x00_read(REG_FULL_AVAILABLE_CHARGE, &g_full_available_capacity, 0, di);
    create_bq_procfs(di);
#ifdef BAT_LOG
    INIT_DELAYED_WORK_DEFERRABLE(&di->bat_log_work,bat_log_work_func);
#endif
    INIT_DELAYED_WORK_DEFERRABLE(&di->bat_monitor_work,bat_monitor_work_func);
    queue_delayed_work(bat_work_queue,&di->bat_monitor_work,
            msecs_to_jiffies(1000 * 1));
    BLOCKING_INIT_NOTIFIER_HEAD(&notifier_list);

    /* Create a sysfs node */
    error = sysfs_create_group(&di->dev->kobj, &bq_attr_grp);
    if (error) {
    	dev_dbg(di->dev,"could not create sysfs_create_group\n");
    	return -1;
    }
    return 0;
}
예제 #4
0
/**
 * @brief open a IPC pipe.
 * 
 * @param[in] pipe_id : IPC pipe ID.
 *
 * @return  not NULL means success, NULL means failure.
 */
struct ipc_pipe* ipc_pipe_open(int pipe_id)
{
	struct ipc_pipe *pipe;
	int ret;
	int first;

	if (pipe_id < 0 || pipe_id >= __IPC_PIPE_NUM_MAX)
		return NULL;

	pipe = idr_find(&ipc_pipe_idr, pipe_id);
	if (pipe != NULL) {
		return NULL;
	}

	pipe = (struct ipc_pipe*)kzalloc(sizeof(*pipe), GFP_KERNEL);
	if (pipe == NULL)
		return NULL;

	pipe->id = pipe_id;
	pipe->freeQ = ipcmsg_queue_create();
	pipe->recvQ = ipcmsg_queue_create();
	pipe->sendQ = ipcmsg_queue_create();
	pipe->qset = 0;
	pipe->quantum = DEFAULT_PIPE_QUANTUM;
	pipe->qset_limit = DEFAULT_PIPE_QSET;

	spin_lock_init(&pipe->lock);
	
	BLOCKING_INIT_NOTIFIER_HEAD(&pipe->notifier);
	init_waitqueue_head(&pipe->write_wq);
	init_waitqueue_head(&pipe->read_wq);

	first = all_pipes_unused();

	mark_pipe_used(pipe);

	ret = save_opened_pipe(pipe);
	if (ret)
		goto _error;

	switch_pipe_state(pipe, IPC_PIPE_STATE_OPENED);

	if (first) {
		// we are the first opened pipe.
		ipc_msg_register_handler(IPCMSG_CMD_PIPE, pipe_ipcmsg_handler, NULL);
	}

	return pipe;

_error:
	mark_pipe_unused(pipe);

	kfree(pipe);

	return NULL;
}
예제 #5
0
파일: iommu.c 프로젝트: ramlaxman/linux
/**
 * iommu_group_alloc - Allocate a new group
 * @name: Optional name to associate with group, visible in sysfs
 *
 * This function is called by an iommu driver to allocate a new iommu
 * group.  The iommu group represents the minimum granularity of the iommu.
 * Upon successful return, the caller holds a reference to the supplied
 * group in order to hold the group until devices are added.  Use
 * iommu_group_put() to release this extra reference count, allowing the
 * group to be automatically reclaimed once it has no devices or external
 * references.
 */
struct iommu_group *iommu_group_alloc(void)
{
	struct iommu_group *group;
	int ret;

	group = kzalloc(sizeof(*group), GFP_KERNEL);
	if (!group)
		return ERR_PTR(-ENOMEM);

	group->kobj.kset = iommu_group_kset;
	mutex_init(&group->mutex);
	INIT_LIST_HEAD(&group->devices);
	BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);

	mutex_lock(&iommu_group_mutex);

again:
	if (unlikely(0 == ida_pre_get(&iommu_group_ida, GFP_KERNEL))) {
		kfree(group);
		mutex_unlock(&iommu_group_mutex);
		return ERR_PTR(-ENOMEM);
	}

	if (-EAGAIN == ida_get_new(&iommu_group_ida, &group->id))
		goto again;

	mutex_unlock(&iommu_group_mutex);

	ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype,
				   NULL, "%d", group->id);
	if (ret) {
		mutex_lock(&iommu_group_mutex);
		ida_remove(&iommu_group_ida, group->id);
		mutex_unlock(&iommu_group_mutex);
		kfree(group);
		return ERR_PTR(ret);
	}

	group->devices_kobj = kobject_create_and_add("devices", &group->kobj);
	if (!group->devices_kobj) {
		kobject_put(&group->kobj); /* triggers .release & free */
		return ERR_PTR(-ENOMEM);
	}

	/*
	 * The devices_kobj holds a reference on the group kobject, so
	 * as long as that exists so will the group.  We can therefore
	 * use the devices_kobj for reference counting.
	 */
	kobject_put(&group->kobj);

	pr_debug("Allocated group %d\n", group->id);

	return group;
}
예제 #6
0
/**
 *	bus_register - register a bus with the system.
 *	@bus:	bus.
 *
 *	Once we have that, we registered the bus with the kobject
 *	infrastructure, then register the children subsystems it has:
 *	the devices and drivers that belong to the bus.
 */
int bus_register(struct bus_type * bus)
{
	int retval = -ENOMEM;
	struct blocking_notifier_head *notifier_head;

	notifier_head = alloc_save_notifier_for_bus(bus);
	if (!notifier_head)
		goto out;

	BLOCKING_INIT_NOTIFIER_HEAD(notifier_head);

	retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
	if (retval)
		goto out;

	subsys_set_kset(bus, bus_subsys);
	retval = subsystem_register(&bus->subsys);
	if (retval)
		goto out;

	kobject_set_name(&bus->devices.kobj, "devices");
	bus->devices.subsys = &bus->subsys;
	retval = kset_register(&bus->devices);
	if (retval)
		goto bus_devices_fail;

	kobject_set_name(&bus->drivers.kobj, "drivers");
	bus->drivers.subsys = &bus->subsys;
	bus->drivers.ktype = &ktype_driver;
	retval = kset_register(&bus->drivers);
	if (retval)
		goto bus_drivers_fail;

	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&bus->klist_drivers, klist_drivers_get, klist_drivers_put);

	retval = add_probe_files(bus);
	if (retval)
		goto bus_probe_files_fail;

	bus_add_attrs(bus);

	pr_debug("bus type '%s' registered\n", bus->name);
	return 0;

bus_probe_files_fail:
	kset_unregister(&bus->drivers);
bus_drivers_fail:
	kset_unregister(&bus->devices);
bus_devices_fail:
	subsystem_unregister(&bus->subsys);
out:
	return retval;
}
struct mmi_hall_data *mmi_hall_init(void)
{
	struct mmi_hall_data *mdata = kzalloc(
			sizeof(struct mmi_hall_data), GFP_KERNEL);
	if (mdata) {
		int i;
		for (i = 0; i < MMI_HALL_MAX; i++)
			BLOCKING_INIT_NOTIFIER_HEAD(&mdata->nhead[i]);
		pr_debug("%s: data structure init-ed\n", __func__);
	}
	return mdata;
}
예제 #8
0
int omap_dss_register_device(struct omap_dss_device *dssdev)
{
	static int dev_num;

	WARN_ON(!dssdev->driver_name);

	reset_device(&dssdev->dev, 1);
	dssdev->dev.bus = &dss_bus_type;
	dssdev->dev.parent = &dss_bus;
	dssdev->dev.release = omap_dss_dev_release;
	dev_set_name(&dssdev->dev, "display%d", dev_num++);

	BLOCKING_INIT_NOTIFIER_HEAD(&dssdev->notifier);

	return device_register(&dssdev->dev);
}
예제 #9
0
파일: bus.c 프로젝트: B-Rich/linux_drivers
/**
 *	bus_register - register a bus with the system.
 *	@bus:	bus.
 *
 *	Once we have that, we registered the bus with the kobject
 *	infrastructure, then register the children subsystems it has:
 *	the devices and drivers that belong to the bus.
 */
int bus_register(struct bus_type * bus)
{
	int retval;

	BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);

	retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
	if (retval)
		goto out;

	subsys_set_kset(bus, bus_subsys);
	retval = subsystem_register(&bus->subsys);
	if (retval)
		goto out;

	kobject_set_name(&bus->devices.kobj, "devices");
	bus->devices.subsys = &bus->subsys;
	retval = kset_register(&bus->devices);
	if (retval)
		goto bus_devices_fail;

	kobject_set_name(&bus->drivers.kobj, "drivers");
	bus->drivers.subsys = &bus->subsys;
	bus->drivers.ktype = &ktype_driver;
	retval = kset_register(&bus->drivers);
	if (retval)
		goto bus_drivers_fail;

	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&bus->klist_drivers, NULL, NULL);
	retval = bus_add_attrs(bus);
	if (retval)
		goto bus_attrs_fail;

	pr_debug("bus type '%s' registered\n", bus->name);
	return 0;

bus_attrs_fail:
	kset_unregister(&bus->drivers);
bus_drivers_fail:
	kset_unregister(&bus->devices);
bus_devices_fail:
	subsystem_unregister(&bus->subsys);
out:
	return retval;
}
예제 #10
0
static int __init muic_notifier_init(void)
{
	int ret = 0;

	pr_info("%s\n", __func__);

	switch_device = sec_device_create(NULL, "switch");
	if (IS_ERR(switch_device)) {
		pr_err("%s Failed to create device(switch)!\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	BLOCKING_INIT_NOTIFIER_HEAD(&(muic_notifier.notifier_call_chain));
	muic_notifier.cmd = MUIC_NOTIFY_CMD_DETACH;
	muic_notifier.attached_dev = ATTACHED_DEV_UNKNOWN_MUIC;

out:
	return ret;
}
예제 #11
0
int wcd9xxx_resmgr_init(struct wcd9xxx_resmgr *resmgr,
			struct snd_soc_codec *codec,
			struct wcd9xxx *wcd9xxx,
			struct wcd9xxx_pdata *pdata,
			struct wcd9xxx_reg_address *reg_addr)
{
	WARN(ARRAY_SIZE(wcd9xxx_event_string) != WCD9XXX_EVENT_LAST + 1,
	     "Event string table isn't up to date!, %d != %d\n",
	     ARRAY_SIZE(wcd9xxx_event_string), WCD9XXX_EVENT_LAST + 1);

	resmgr->bandgap_type = WCD9XXX_BANDGAP_OFF;
	resmgr->codec = codec;
	/* This gives access of core handle to lock/unlock suspend */
	resmgr->core = wcd9xxx;
	resmgr->pdata = pdata;
	resmgr->reg_addr = reg_addr;

	BLOCKING_INIT_NOTIFIER_HEAD(&resmgr->notifier);

	mutex_init(&resmgr->codec_resource_lock);

	return 0;
}
예제 #12
0
static int __init muic_notifier_init(void)
{
	int ret = 0;

	printk(KERN_DEBUG "[muic] %s\n", __func__);

#ifdef CONFIG_SEC_SYSFS
	switch_device = sec_device_create(NULL, "switch");
	if (IS_ERR(switch_device)) {
		printk(KERN_ERR "[muic] Failed to create device(switch)!\n");
		ret = -ENODEV;
		goto out;
	}
#endif

	BLOCKING_INIT_NOTIFIER_HEAD(&(muic_notifier.notifier_call_chain));
	muic_notifier.cmd = MUIC_NOTIFY_CMD_DETACH;
	muic_notifier.attached_dev = ATTACHED_DEV_UNKNOWN_MUIC;

#ifdef CONFIG_SEC_SYSFS
out:
#endif
	return ret;
}
예제 #13
0
/**
 * bus_register - register a bus with the system.
 * @bus: bus.
 *
 * Once we have that, we registered the bus with the kobject
 * infrastructure, then register the children subsystems it has:
 * the devices and drivers that belong to the bus.
 */
int bus_register(struct bus_type *bus)
{
	int retval;
	struct bus_type_private *priv;

	priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->bus = bus;
	bus->p = priv;

	BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);

	retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
	if (retval)
		goto out;

	priv->subsys.kobj.kset = bus_kset;
	priv->subsys.kobj.ktype = &bus_ktype;
	priv->drivers_autoprobe = 1;

	retval = kset_register(&priv->subsys);
	if (retval)
		goto out;

	retval = bus_create_file(bus, &bus_attr_uevent);
	if (retval)
		goto bus_uevent_fail;

	priv->devices_kset = kset_create_and_add("devices", NULL,
						 &priv->subsys.kobj);
	if (!priv->devices_kset) {
		retval = -ENOMEM;
		goto bus_devices_fail;
	}

	priv->drivers_kset = kset_create_and_add("drivers", NULL,
						 &priv->subsys.kobj);
	if (!priv->drivers_kset) {
		retval = -ENOMEM;
		goto bus_drivers_fail;
	}

	klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&priv->klist_drivers, NULL, NULL);

	retval = add_probe_files(bus);
	if (retval)
		goto bus_probe_files_fail;

	retval = bus_add_attrs(bus);
	if (retval)
		goto bus_attrs_fail;

	pr_debug("bus: '%s': registered\n", bus->name);
	return 0;

bus_attrs_fail:
	remove_probe_files(bus);
bus_probe_files_fail:
	kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
	kset_unregister(bus->p->devices_kset);
bus_devices_fail:
	bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
	kset_unregister(&bus->p->subsys);
	kfree(bus->p);
out:
	bus->p = NULL;
	return retval;
}
예제 #14
0
void dss_init_device(struct platform_device *pdev,
		struct omap_dss_device *dssdev)
{
	struct device_attribute *attr;
	int i;
	int r;

	switch (dssdev->type) {
#ifdef CONFIG_OMAP2_DSS_DPI
	case OMAP_DISPLAY_TYPE_DPI:
		r = dpi_init_display(dssdev);
		break;
#endif
#ifdef CONFIG_OMAP2_DSS_RFBI
	case OMAP_DISPLAY_TYPE_DBI:
		r = rfbi_init_display(dssdev);
		break;
#endif
#ifdef CONFIG_OMAP2_DSS_VENC
	case OMAP_DISPLAY_TYPE_VENC:
		r = venc_init_display(dssdev);
		break;
#endif
#ifdef CONFIG_OMAP2_DSS_SDI
	case OMAP_DISPLAY_TYPE_SDI:
		r = sdi_init_display(dssdev);
		break;
#endif
#ifdef CONFIG_OMAP2_DSS_DSI
	case OMAP_DISPLAY_TYPE_DSI:
		r = dsi_init_display(dssdev);
		break;
#endif
	case OMAP_DISPLAY_TYPE_HDMI:
		r = hdmi_init_display(dssdev);
		break;
	default:
		DSSERR("Support for display '%s' not compiled in.\n",
				dssdev->name);
		return;
	}

	if (r) {
		DSSERR("failed to init display %s\n", dssdev->name);
		return;
	}

	BLOCKING_INIT_NOTIFIER_HEAD(&dssdev->state_notifiers);

	/* create device sysfs files */
	i = 0;
	while ((attr = display_sysfs_attrs[i++]) != NULL) {
		r = device_create_file(&dssdev->dev, attr);
		if (r)
			DSSERR("failed to create sysfs file\n");
	}

	/* create display? sysfs links */
	r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
			dev_name(&dssdev->dev));
	if (r)
		DSSERR("failed to create sysfs display link\n");
}
예제 #15
0
static int __devinit axp_mfd_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct axp_platform_data *pdata = client->dev.platform_data;
	struct axp_mfd_chip *chip;
	int ret;
	chip = kzalloc(sizeof(struct axp_mfd_chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	axp = client;

	chip->client = client;
	chip->dev = &client->dev;
	chip->ops = &axp_mfd_ops[id->driver_data];

	mutex_init(&chip->lock);
	INIT_WORK(&chip->irq_work, axp_mfd_irq_work);
	BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);

	i2c_set_clientdata(client, chip);

	ret = chip->ops->init_chip(chip);
	if (ret)
		goto out_free_chip;

	ret = request_irq(client->irq, axp_mfd_irq_handler,
		IRQF_DISABLED, "axp_mfd", chip);
  	if (ret) {
  		dev_err(&client->dev, "failed to request irq %d\n",
  				client->irq);
  		goto out_free_chip;
  	}

	/* The irq for the A20 NMI pin needs to be enabled separately */
	if (sunxi_is_sun7i() && client->irq == SW_INT_IRQNO_ENMI) {
		writel(0x01, NMI_IRQ_PEND_REG);   /* Clear any pending irqs */
		writel(0x01, NMI_IRQ_ENABLE_REG); /* Enable NMI irq pin */
	}

	ret = axp_mfd_add_subdevs(chip, pdata);
	if (ret)
		goto out_free_irq;

	/* PM hookup */
	if(!pm_power_off)
		pm_power_off = axp_power_off;

	ret = axp_mfd_create_attrs(chip);
	if(ret){
		return ret;
	}
	
	/* set ac/usb_in shutdown mean restart */
  	ret = script_parser_fetch("target", "power_start", &power_start, sizeof(int));
  	if (ret)
  	{
    	printk("[AXP]axp driver uning configuration failed(%d)\n", __LINE__);
     	power_start = 0;
     	printk("[AXP]power_start = %d\n",power_start);
  	}
  	
	return 0;

out_free_irq:
	free_irq(client->irq, chip);

out_free_chip:
	i2c_set_clientdata(client, NULL);
	kfree(chip);

	return ret;
}
예제 #16
0
static int __devinit twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
	struct twl4030_usb	*twl;
	int			status, err;

#ifdef CONFIG_LGE_OMAP3_EXT_PWR
	INIT_WORK(&set_ext_pwr_twl_usb_work, twl_usb_ext_pwr_work);
#endif 

#if 1 /* mbk_wake mbk_temp */ 
	// LGE_CHANGE wake lock for usb connection
	wake_lock_init(&the_wlock.wake_lock, WAKE_LOCK_SUSPEND, "twl4030_usb_connection");
	the_wlock.wake_lock_on=0;
	// LGE_CHANGE wake lock for usb connection

	// LGE_CHANGE work queue
	INIT_DELAYED_WORK(&twl4030_usb_wq, twl4030_usb_wq_func);
	// LGE_CHANGE work queue
#endif

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	twl->dev		= &pdev->dev;
	twl->irq		= platform_get_irq(pdev, 0);
	twl->otg.dev		= twl->dev;
	twl->otg.label		= "twl4030";
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;
	twl->usb_mode		= pdata->usb_mode;
	twl->asleep		= 1;

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl4030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(twl);
		return err;
	}
	otg_set_transceiver(&twl->otg);

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);

	/* Our job is to use irqs and status from the power module
	 * to keep the transceiver disabled when nothing's connected.
	 *
	 * FIXME we actually shouldn't start enabling it until the
	 * USB controller drivers have said they're ready, by calling
	 * set_host() and/or set_peripheral() ... OTG_capable boards
	 * need both handles, otherwise just one suffices.
	 */
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl4030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return status;
	}
	
	//regulator_enable(twl->usb3v1);
	/* The IRQ handler just handles changes from the previous states
	 * of the ID and VBUS pins ... in probe() we must initialize that
	 * previous state.  The easy way:  fake an IRQ.
	 *
	 * REVISIT:  a real IRQ might have happened already, if PREEMPT is
	 * enabled.  Else the IRQ may not yet be configured or enabled,
	 * because of scheduling delays.
	 */
	twl4030_usb_irq(twl->irq, twl);
	//if (twl4030_usb_linkstat(twl) == USB_EVENT_NONE) {
	//	regulator_disable(twl->usb3v1);
	//}

//20110829 [email protected] [LS855] reset USB1.8V LDO when phone reset [START]
	backuptwl = twl;
//20110829 [email protected] [LS855] reset USB1.8V LDO when phone reset [END]	


	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
예제 #17
0
static int __devinit adp5520_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	struct adp5520_platform_data *pdata = client->dev.platform_data;
	struct platform_device *pdev;
	struct adp5520_chip *chip;
	int ret;

	if (!i2c_check_functionality(client->adapter,
					I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "SMBUS Word Data not Supported\n");
		return -EIO;
	}

	if (pdata == NULL) {
		dev_err(&client->dev, "missing platform data\n");
		return -ENODEV;
	}

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	i2c_set_clientdata(client, chip);
	chip->client = client;

	chip->dev = &client->dev;
	chip->irq = client->irq;
	chip->id = id->driver_data;
	mutex_init(&chip->lock);

	if (chip->irq) {
		BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);

		ret = request_threaded_irq(chip->irq, NULL, adp5520_irq_thread,
				IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				"adp5520", chip);
		if (ret) {
			dev_err(&client->dev, "failed to request irq %d\n",
					chip->irq);
			goto out_free_chip;
		}
	}

	ret = adp5520_write(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
	if (ret) {
		dev_err(&client->dev, "failed to write\n");
		goto out_free_irq;
	}

	if (pdata->keys) {
		pdev = platform_device_register_data(chip->dev, "adp5520-keys",
				chip->id, pdata->keys, sizeof(*pdata->keys));
		if (IS_ERR(pdev)) {
			ret = PTR_ERR(pdev);
			goto out_remove_subdevs;
		}
	}

	if (pdata->gpio) {
		pdev = platform_device_register_data(chip->dev, "adp5520-gpio",
				chip->id, pdata->gpio, sizeof(*pdata->gpio));
		if (IS_ERR(pdev)) {
			ret = PTR_ERR(pdev);
			goto out_remove_subdevs;
		}
	}

	if (pdata->leds) {
		pdev = platform_device_register_data(chip->dev, "adp5520-led",
				chip->id, pdata->leds, sizeof(*pdata->leds));
		if (IS_ERR(pdev)) {
			ret = PTR_ERR(pdev);
			goto out_remove_subdevs;
		}
	}

	if (pdata->backlight) {
		pdev = platform_device_register_data(chip->dev,
						"adp5520-backlight",
						chip->id,
						pdata->backlight,
						sizeof(*pdata->backlight));
		if (IS_ERR(pdev)) {
			ret = PTR_ERR(pdev);
			goto out_remove_subdevs;
		}
	}

	return 0;

out_remove_subdevs:
	adp5520_remove_subdevs(chip);

out_free_irq:
	if (chip->irq)
		free_irq(chip->irq, chip);

out_free_chip:
	kfree(chip);

	return ret;
}
static int __devinit twl6030_usb_probe(struct platform_device *pdev)
{
	struct twl6030_usb	*twl;
	int			status,err,vbus_state;
	struct twl4030_usb_data *pdata;
	struct device *dev = &pdev->dev;
	pdata = dev->platform_data;

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	twl->dev		= &pdev->dev;
	twl->irq1		= platform_get_irq(pdev, 0);
	twl->irq2		= platform_get_irq(pdev, 1);
	twl->otg.dev		= twl->dev;
	twl->otg.label		= "twl6030";
	twl->otg.set_host	= twl6030_set_host;
	twl->otg.set_peripheral	= twl6030_set_peripheral;
	twl->otg.set_suspend	= twl6030_set_suspend;
	twl->asleep		= 1;
	#ifndef CONFIG_USB_ETH_RNDIS
	twl->otg.set_power	= twl6030_set_input_current_limit;
	twl->otg.set_vbus	= twl6030_set_vbus;
	#endif
	twl->otg.set_hz_mode	= twl6030_set_hz_mode;
	twl->otg.init		= phy_init;
	twl->otg.shutdown	= phy_shutdown;
	twl->otg.enable_irq	= twl6030_enable_irq;
	twl->otg.set_clk	= set_phy_clk;
	twl->otg.shutdown	= phy_shutdown;
	twl->prev_vbus		= 0;
	twl->vusb = regulator_get(NULL, "usb-phy");
        if (IS_ERR(twl->vusb)) {
            pr_err("Unable to get usb-phy regulator\n");
        }
        
        twl->mbid=quanta_get_mbid();
        printk(KERN_INFO "%s mbid=%d\n",__func__,twl->mbid);
        err = regulator_set_voltage(twl->vusb, 3300000,
                    3300000);
        //regulator_disable(twl->vusb);

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl6030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(twl);
		return err;
	}
	otg_set_transceiver(&twl->otg);

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);
        INIT_WORK(&twl->vbus_work, vbus_monitor_work_func);
        INIT_WORK(&twl->id_work, id_monitor_work_func);
	/* Our job is to use irqs and status from the power module
	 * to keep the transceiver disabled when nothing's connected.
	 *
	 * FIXME we actually shouldn't start enabling it until the
	 * USB controller drivers have said they're ready, by calling
	 * set_host() and/or set_peripheral() ... OTG_capable boards
	 * need both handles, otherwise just one suffices.
	 */
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq1, status);
		kfree(twl);
		return status;
	}

	status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq2, status);
		kfree(twl);
		return status;
	}

        vbus_state = twl6030_readb(twl, TWL6030_MODULE_CHARGER,
						CONTROLLER_STAT1);
        wake_lock_init(&twlusb_lock, WAKE_LOCK_SUSPEND, "usb_wake_lock");

	ctrl_base = ioremap(0x4A002000, SZ_1K);
	/* power down the phy by default can be enabled on connect */
	__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);

	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
	return 0;
}
예제 #19
0
파일: bus.c 프로젝트: loginab/esxdrivers
/* _VMKLNX_CODECHECK_: bus_register */
int bus_register(struct bus_type * bus)
{
	int retval;

#if defined(__VMKLNX__)
	VMK_ReturnStatus status;
	bus->bus_notifier.head = NULL;
	status = vmk_SemaCreate(&bus->bus_notifier.rwsem,
		vmk_ModuleStackTop(), bus->name, 1);
	if (status != VMK_OK) {
		retval = -EINVAL;
		goto out;
	}
#else
	BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
#endif

	retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);
	if (retval)
		goto out;

	bus->subsys.kobj.kset = &bus_subsys;

	retval = subsystem_register(&bus->subsys);
	if (retval)
		goto out;

	retval = bus_create_file(bus, &bus_attr_uevent);
	if (retval)
		goto bus_uevent_fail;

	kobject_set_name(&bus->devices.kobj, "devices");
	bus->devices.kobj.parent = &bus->subsys.kobj;
	retval = kset_register(&bus->devices);
	if (retval)
		goto bus_devices_fail;

	kobject_set_name(&bus->drivers.kobj, "drivers");
	bus->drivers.kobj.parent = &bus->subsys.kobj;
	bus->drivers.ktype = &driver_ktype;
	retval = kset_register(&bus->drivers);
	if (retval)
		goto bus_drivers_fail;

	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&bus->klist_drivers, NULL, NULL);

	bus->drivers_autoprobe = 1;
	retval = add_probe_files(bus);
	if (retval)
		goto bus_probe_files_fail;

	retval = bus_add_attrs(bus);
	if (retval)
		goto bus_attrs_fail;

	pr_debug("bus type '%s' registered\n", bus->name);
	return 0;

bus_attrs_fail:
	remove_probe_files(bus);
bus_probe_files_fail:
	kset_unregister(&bus->drivers);
bus_drivers_fail:
	kset_unregister(&bus->devices);
bus_devices_fail:
	bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
	subsystem_unregister(&bus->subsys);
out:
	return retval;
}
static int __init smsc43340_usb_probe(struct platform_device *pdev)
{
	struct smsc43340_usb_data *pdata = pdev->dev.platform_data;
	struct smsc43340_usb	  *smsc;
	int			status;

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	smsc = kzalloc(sizeof *smsc, GFP_KERNEL);
	if (!smsc)
		return -ENOMEM;

	smsc->dev                 = &pdev->dev;
	smsc->otg.dev             = smsc->dev;
	smsc->otg.label           = "smsc43340";
	smsc->otg.set_host        = smsc43340_set_host;
	smsc->otg.set_peripheral  = smsc43340_set_peripheral;
	smsc->otg.set_suspend     = smsc43340_set_suspend;
	smsc->otg.init		  = smsc43340_phy_init;
	smsc->otg.shutdown	  = smsc43340_phy_shutdown;
	smsc->otg.set_clk	  = smsc43340_set_phy_clk;
	smsc->otg.set_vbus	  = smsc43340_set_vbus;
	smsc->asleep              = 1;
	smsc->gpio_reset          = pdata->gpio_reset;
	smsc->gpio_overcurrent    = pdata->gpio_overcurrent;

	if (!gpio_is_valid(smsc->gpio_reset)) {
		kfree(smsc);
		return -EINVAL;
	}

	// Init IRQ
	if (gpio_is_valid(smsc->gpio_overcurrent)) {
		// Get IRQ
		smsc->irq = OMAP_GPIO_IRQ(smsc->gpio_overcurrent);

		if (gpio_request(smsc->gpio_overcurrent, "smsc43340_usb_irq") < 0) {
			printk(KERN_ERR "Failed to request GPIO%d for smsc43340 IRQ\n",
				smsc->gpio_overcurrent);
			return -EIO;
		}
		gpio_direction_input(smsc->gpio_overcurrent);
	}

	smsc43340_phy_init(&smsc->otg);

	otg_set_transceiver(&smsc->otg);

	platform_set_drvdata(pdev, smsc);

        status = request_irq(smsc->irq, smsc43340_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"smsc43340_usb", smsc);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			smsc->irq, status);
		kfree(smsc);
		return status;
	}

        INIT_WORK(&smsc->irq_work, smsc43340_irq_work_handler);

        /* Generate first IRQ */
        smsc43340_usb_irq(smsc->irq, (void *) smsc );

	dev_info(&pdev->dev, "Initialized SMSC 43340 USB module for OMAP 3630 USB OTG\n");
	BLOCKING_INIT_NOTIFIER_HEAD(&smsc->otg.notifier);
	return 0;
}
예제 #21
0
static int omap_rproc_probe(struct platform_device *pdev)
{
	int ret = 0, major, minor;
	struct device *tmpdev;
	struct device *dev = &pdev->dev;
	struct omap_rproc_platform_data *pdata = dev->platform_data;
	struct omap_rproc *rproc;

	if (!pdata || !pdata->name || !pdata->oh_name || !pdata->ops)
		return -EINVAL;

	dev_info(dev, "%s: adding rproc %s\n", __func__, pdata->name);

	rproc = kzalloc(sizeof(struct omap_rproc), GFP_KERNEL);
	if (!rproc) {
		dev_err(dev, "%s: kzalloc failed\n", __func__);
		ret = -ENOMEM;
		goto out;
	}

	platform_set_drvdata(pdev, rproc);
	major = MAJOR(omap_rproc_dev);
	minor = atomic_read(&num_of_rprocs);
	atomic_inc(&num_of_rprocs);

	rproc->dev = dev;
	rproc->minor = minor;
	atomic_set(&rproc->count, 0);
	rproc->name = pdata->name;

	mutex_init(&rproc->lock);
	BLOCKING_INIT_NOTIFIER_HEAD(&rproc->notifier);

	cdev_init(&rproc->cdev, &omap_rproc_fops);
	rproc->cdev.owner = THIS_MODULE;
	ret = cdev_add(&rproc->cdev, MKDEV(major, minor), 1);
	if (ret) {
		dev_err(dev, "%s: cdev_add failed: %d\n", __func__, ret);
		goto free_rproc;
	}

	tmpdev = device_create(omap_rproc_class, NULL,
				MKDEV(major, minor),
				NULL,
				OMAP_RPROC_NAME "%d", minor);
	if (IS_ERR(tmpdev)) {
		ret = PTR_ERR(tmpdev);
		pr_err("%s: device_create failed: %d\n", __func__, ret);
		goto clean_cdev;
	}

	pr_info("%s initialized %s, major: %d, base-minor: %d\n",
			OMAP_RPROC_NAME,
			pdata->name,
			MAJOR(omap_rproc_dev),
			minor);
	return 0;

clean_cdev:
	cdev_del(&rproc->cdev);
free_rproc:
	kfree(rproc);
out:
	return ret;
}
예제 #22
0
static int __devinit rk3190_mbox_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct device *dev;
	void __iomem *base;
	struct rk3190_mbox *pmb;
	int i;

	dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (unlikely(res == NULL)) {
		dev_err(dev, "Invalid IRQ resource!\n");
		return -ENODEV;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(res == NULL)) {
		dev_err(dev, "Invalid MEM resource!\n");
		return -ENODEV;
	}
	
	base = ioremap(res->start, resource_size(res));
	if (base == NULL) {
		dev_err(dev, "Could not ioremap mailbox!\n");
		return -ENOMEM;
	}

	pmb = kzalloc(sizeof(*pmb), GFP_KERNEL);
	if (pmb == NULL) {
		dev_err(dev, "No more memory!\n");
		return -ENOMEM;
	}

	for (i=0; i<ARRAY_SIZE(pmb->irq); i++) {
		pmb->irq[i] = platform_get_irq(pdev, i);
	}
	pmb->base = base;

	pmb->mbox.name = DRV_NAME;
	pmb->mbox.startup = rk3190_mbox_startup;
	pmb->mbox.shutdown = rk3190_mbox_shutdown;
	pmb->mbox.reset = rk3190_mbox_reset;
	pmb->mbox.msg_write = rk3190_mbox_msg_put;
	pmb->mbox.msg_read = rk3190_mbox_msg_get;
	pmb->mbox.notifier_register = rk3190_mbox_notifier_register;
	pmb->mbox.notifier_unregister = rk3190_mbox_notifier_unregister;

	rk_mbox_register(&pmb->mbox);

	BLOCKING_INIT_NOTIFIER_HEAD(&pmb->notifier);

	kfifo_alloc(&pmb->in_fifo, 512, GFP_KERNEL);

	pmb->chan_free_bitmask = 0;	//MBOX_CHAN_MASKBITS;

	spin_lock_init(&pmb->lock);
	
	hw_mbox = pmb;
	pr_info("%s:probe ok\n",__func__);
	return 0;
}
예제 #23
0
/**
 * bus_register - register a bus with the system.
 * @bus: bus.
 *
 * Once we have that, we registered the bus with the kobject
 * infrastructure, then register the children subsystems it has:
 * the devices and drivers that belong to the bus.
 */
int bus_register(struct bus_type *bus)
{
	int retval;
	struct bus_type_private *priv;

	priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->bus = bus;
	bus->p = priv;

	BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);

	/*设置bus对象的名字*/
	retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
	if (retval)
		goto out;

	/*待注册的总线属于nus_kset集合,因此,位于/sys/bus/目录下*/
	priv->subsys.kobj.kset = bus_kset;
	priv->subsys.kobj.ktype = &bus_ktype;
	priv->drivers_autoprobe = 1;

	/*将bus对象增加到bus_sket容器中去*/
	retval = kset_register(&priv->subsys);
	if (retval)
		goto out;

	/*为bus创建属性文件*/
	retval = bus_create_file(bus, &bus_attr_uevent);
	if (retval)
		goto bus_uevent_fail;

	/*在bus->subsys,kobj目录项下创建"devices"与"drivers目录容器"*/
	priv->devices_kset = kset_create_and_add("devices", NULL,
						 &priv->subsys.kobj);
	if (!priv->devices_kset) {
		retval = -ENOMEM;
		goto bus_devices_fail;
	}

	priv->drivers_kset = kset_create_and_add("drivers", NULL,
						 &priv->subsys.kobj);
	if (!priv->drivers_kset) {
		retval = -ENOMEM;
		goto bus_drivers_fail;
	}

	klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&priv->klist_drivers, NULL, NULL);

	/*增加总线探测与自动探测属性文件*/
	retval = add_probe_files(bus);
	if (retval)
		goto bus_probe_files_fail;

	/*创建bus的默认属性文件*/
	retval = bus_add_attrs(bus);
	if (retval)
		goto bus_attrs_fail;

	pr_debug("bus: '%s': registered\n", bus->name);
	return 0;

bus_attrs_fail:
	remove_probe_files(bus);
bus_probe_files_fail:
	kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
	kset_unregister(bus->p->devices_kset);
bus_devices_fail:
	bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
	kset_unregister(&bus->p->subsys);
	kfree(bus->p);
out:
	bus->p = NULL;
	return retval;
}
예제 #24
0
파일: bus.c 프로젝트: PennPanda/linux-repo
/**
 *	bus_register - register a bus with the system.
 *	@bus:	bus.
 *
 *	Once we have that, we registered the bus with the kobject
 *	infrastructure, then register the children subsystems it has:
 *	the devices and drivers that belong to the bus.
 */
int bus_register(struct bus_type * bus)
{
	int retval;

	BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);

	retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name);
	if (retval)
		goto out;

	bus->subsys.kobj.kset = &bus_subsys;

	retval = subsystem_register(&bus->subsys);
	if (retval)
		goto out;

	retval = bus_create_file(bus, &bus_attr_uevent);
	if (retval)
		goto bus_uevent_fail;

	kobject_set_name(&bus->devices.kobj, "devices");
	bus->devices.kobj.parent = &bus->subsys.kobj;
	retval = kset_register(&bus->devices);
	if (retval)
		goto bus_devices_fail;

	kobject_set_name(&bus->drivers.kobj, "drivers");
	bus->drivers.kobj.parent = &bus->subsys.kobj;
	bus->drivers.ktype = &driver_ktype;
	retval = kset_register(&bus->drivers);
	if (retval)
		goto bus_drivers_fail;

	klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
	klist_init(&bus->klist_drivers, NULL, NULL);

	bus->drivers_autoprobe = 1;
	retval = add_probe_files(bus);
	if (retval)
		goto bus_probe_files_fail;

	retval = bus_add_attrs(bus);
	if (retval)
		goto bus_attrs_fail;

	pr_debug("bus type '%s' registered\n", bus->name);
	return 0;

bus_attrs_fail:
	remove_probe_files(bus);
bus_probe_files_fail:
	kset_unregister(&bus->drivers);
bus_drivers_fail:
	kset_unregister(&bus->devices);
bus_devices_fail:
	bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
	subsystem_unregister(&bus->subsys);
out:
	return retval;
}
예제 #25
0
int cros_ec_register(struct cros_ec_device *ec_dev)
{
	struct device *dev = ec_dev->dev;
	int err = 0;

	BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);

	ec_dev->max_request = sizeof(struct ec_params_hello);
	ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
	ec_dev->max_passthru = 0;

	ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
	if (!ec_dev->din)
		return -ENOMEM;

	ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
	if (!ec_dev->dout)
		return -ENOMEM;

	mutex_init(&ec_dev->lock);

	err = cros_ec_query_all(ec_dev);
	if (err) {
		dev_err(dev, "Cannot identify the EC: error %d\n", err);
		return err;
	}

	if (ec_dev->irq) {
		err = devm_request_threaded_irq(dev, ec_dev->irq, NULL,
				ec_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				"chromeos-ec", ec_dev);
		if (err) {
			dev_err(dev, "Failed to request IRQ %d: %d",
				ec_dev->irq, err);
			return err;
		}
	}

	err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1,
			      NULL, ec_dev->irq, NULL);
	if (err) {
		dev_err(dev,
			"Failed to register Embedded Controller subdevice %d\n",
			err);
		return err;
	}

	if (ec_dev->max_passthru) {
		/*
		 * Register a PD device as well on top of this device.
		 * We make the following assumptions:
		 * - behind an EC, we have a pd
		 * - only one device added.
		 * - the EC is responsive at init time (it is not true for a
		 *   sensor hub.
		 */
		err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO,
				      &ec_pd_cell, 1, NULL, ec_dev->irq, NULL);
		if (err) {
			dev_err(dev,
				"Failed to register Power Delivery subdevice %d\n",
				err);
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
		err = devm_of_platform_populate(dev);
		if (err) {
			mfd_remove_devices(dev);
			dev_err(dev, "Failed to register sub-devices\n");
			return err;
		}
	}

	/*
	 * Clear sleep event - this will fail harmlessly on platforms that
	 * don't implement the sleep event host command.
	 */
	err = cros_ec_sleep_event(ec_dev, 0);
	if (err < 0)
		dev_dbg(ec_dev->dev, "Error %d clearing sleep event to ec",
			err);

	dev_info(dev, "Chrome EC device registered\n");

	return 0;
}
예제 #26
0
파일: twl4030-usb.c 프로젝트: UAVXP/A10
static int __devinit twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
	struct twl4030_usb	*twl;
	int			status, err;
	int OTG_ID_detect_irq = 0;

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

   twl4030_otg_enable(0);
	twl->dev		= &pdev->dev;
	twl->irq		= platform_get_irq(pdev, 0);
	twl->otg.dev		= twl->dev;
	twl->otg.label		= "twl4030";
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;
	twl->usb_mode		= pdata->usb_mode;
	twl->asleep		= 1;

#ifdef CONFIG_HAS_EARLYSUSPEND
	twl->early_suspend.suspend = twl4030_usb_early_suspend;
	twl->early_suspend.resume = twl4030_usb_late_resume;
	register_early_suspend(&twl->early_suspend);
#endif
	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);
//&*&*&*SJ1_20110701, fix adb connect issue.
	INIT_DELAYED_WORK(&twl->usb_irq_delay_work, do_softint_usb_irq);
//&*&*&*SJ2_20110701, fix adb connect issue.

	err = twl4030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(twl);
		return err;
	}
	otg_set_transceiver(&twl->otg);

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);

	/* Our job is to use irqs and status from the power module
	 * to keep the transceiver disabled when nothing's connected.
	 *
	 * FIXME we actually shouldn't start enabling it until the
	 * USB controller drivers have said they're ready, by calling
	 * set_host() and/or set_peripheral() ... OTG_capable boards
	 * need both handles, otherwise just one suffices.
	 */
	twl->irq_enabled = true;
	g_twl_usb = twl;

	
	//&*&*&*AL1_20110523, USB OTG/Charger switch on EVT3 of EP10
	status = gpio_request(OTG_EN_1V8, "otg_charger_en");
	if (status < 0) {
		dev_dbg(&pdev->dev, "couldn't request OTG_EN_1V8 GPIO: %d\n",
			OTG_EN_1V8);
	}
	//ret = gpio_direction_output(OTG_EN_1V8, 0);
	status = gpio_request(CHG_OFFMODE, "otg_vbus_out_en");
	if (status < 0) {
		dev_dbg(&pdev->dev, "couldn't request CHG_OFFMODE GPIO: %d\n",
			CHG_OFFMODE);
	}
	//ret = gpio_direction_output(CHG_OFFMODE, 0);
	//&*&*&*AL1_20110523, USB OTG/Charger switch on EVT3 of EP10
	
	status = request_irq(twl->irq, twl4030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl4030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return status;
	}
	
	
	//&*&*&*Simon_20110615, register Interrupt handling function for GPIO-41
   
   if(gpio_request(41, "OTG_ID_GPIO") < 0)			
   {
		printk("[simon]Failed to request GPIO%d fOTG_ID_GPIO\n", 41);
	}
	else
	{
		gpio_direction_input(41);		  
      OTG_ID_detect_irq = OMAP_GPIO_IRQ(41);
       
		printk("[Simon] GPIO-41 irq=%d \n",OTG_ID_detect_irq);
			
		status = request_threaded_irq(OTG_ID_detect_irq, NULL,twl4030_OTG_irq,    	
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |IRQF_DISABLED ,
			"OTG_ID_irq", twl);	
			
		if (status < 0) 
		{
			dev_dbg(&pdev->dev, "can't get OTG IRQ %d, err %d\n",
				OTG_ID_detect_irq, status);
			kfree(twl);
			return status;
		}
	}
   //&*&*&*Simon_20110615 end.

	wake_lock_init(&usb_lock, WAKE_LOCK_SUSPEND, "twl4030_musb_wake_lock");
	
	/* The IRQ handler just handles changes from the previous states
	 * of the ID and VBUS pins ... in probe() we must initialize that
	 * previous state.  The easy way:  fake an IRQ.
	 *
	 * REVISIT:  a real IRQ might have happened already, if PREEMPT is
	 * enabled.  Else the IRQ may not yet be configured or enabled,
	 * because of scheduling delays.
	 */
	twl4030_usb_irq(twl->irq, twl);

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
예제 #27
0
static int uh_setup(struct platform_device *pdev, int gpio_irq, int gpio_pin)
{
	struct uh_data *uh;

	unsigned long status = 0;

        int rv;
	
	g_puh_data = (struct uh_data *)kzalloc(sizeof(struct uh_data), GFP_KERNEL);
	if (!g_puh_data) {
		printk(KERN_ERR JZ_VH_PFX": Failed to allocate memory.\n");
		return -ENOMEM;
	}
	
	uh = g_puh_data;

	uh->pdev = pdev;
	uh->gpio_irq = gpio_irq;
	uh->gpio_pin = gpio_pin;

	set_bit(1, &status);
	
	init_waitqueue_head(&uh->kthread_wq);
	init_waitqueue_head(&uh->timer_wq);
	init_waitqueue_head(&uh->finish_wq);

	BLOCKING_INIT_NOTIFIER_HEAD(&uh->notifier_head);

	setup_timer(&uh->keep_alive_timer, uh_keep_alive_timer_func, (unsigned long)uh);
	setup_timer(&uh->stable_timer, uh_stable_timer_func, (unsigned long)uh);
	
	uh->kthread = kthread_run(uh_thread, uh, "kuhd");
	if (IS_ERR(uh->kthread)) {
		printk(KERN_ERR JZ_VH_PFX": Failed to create UDC hotplug monitor thread.\n");
		rv = PTR_ERR(uh->kthread);
		goto err;
	}
	
	set_bit(2, &status);

	uh_init_gpio(uh);

	rv = uh_register_attr(pdev);
	if (rv) {
		printk(KERN_ERR JZ_VH_PFX": Failed to register UDC sysfs interface.\n");
		goto err;
	}
	
	set_bit(3, &status);
	
        rv = request_irq(uh->gpio_irq, uh_irq, 0, JZ_VH_PFX, uh);
        if (rv) {
                printk(KERN_ERR JZ_VH_PFX": Could not get udc hotplug irq %d\n", uh->gpio_irq);
		goto err;
        }
	
	uh_enable();

	uh_set_counter(DEFAULT_KEEP_ALIVE_TIMER_INTERVAL, DEFAULT_KEEP_ALIVE_COUNTER_LIMIT);
	
	uh_start_work(uh, DO_DETECT);	

	printk(KERN_ERR JZ_VH_PFX": Registered.\n");	

	return 0;

err:
	if (test_bit(3, &status)) {
		uh_unregister_attr(pdev);
	}

	if (test_bit(2, &status)) {
		uh->thread_state = UH_THREAD_STATE_START;
		kthread_stop(uh->kthread);
	}
	
	if (test_bit(1, &status)) {
		kfree(g_puh_data);
	}

	return rv;
}
int set_otg_notify(struct otg_notify *n)
{
	int ret = 0;

	if (!u_notify) {
		ret = create_usb_notify();
		if (ret) {
			pr_err("unable create_usb_notify\n");
			goto err;
		}
	}

	if (u_notify->o_notify && n) {
		pr_err("error : already set o_notify\n");
		goto err;
	}

	pr_info("registered otg_notify +\n");
	if (!n) {
		pr_err("otg notify structure is null\n");
		ret = -EFAULT;
		goto err1;
	}
	u_notify->o_notify = n;

	ATOMIC_INIT_NOTIFIER_HEAD(&u_notify->o_notify->otg_notifier);
	u_notify->otg_nb.notifier_call = otg_notifier_callback;
	ret = atomic_notifier_chain_register(&u_notify->o_notify->otg_notifier,
				&u_notify->otg_nb);
	if (ret < 0) {
		pr_err("atomic_notifier_chain_register failed\n");
		goto err1;
	}

	BLOCKING_INIT_NOTIFIER_HEAD(&u_notify->o_notify->extra_notifier);
	u_notify->extra_nb.notifier_call = extra_notifier_callback;
	ret = blocking_notifier_chain_register
		(&u_notify->o_notify->extra_notifier, &u_notify->extra_nb);
	if (ret < 0) {
		pr_err("blocking_notifier_chain_register failed\n");
		goto err2;
	}

	if (!n->unsupport_host) {
		u_notify->ndev.name = "usb_otg";
		u_notify->ndev.set_booster = n->vbus_drive;
		ret = host_notify_dev_register(&u_notify->ndev);
		if (ret < 0) {
			pr_err("host_notify_dev_register is failed\n");
			goto err3;
		}

		if (!n->vbus_drive) {
			pr_err("vbus_drive is null\n");
			goto err4;
		}
	}

	if (gpio_is_valid(n->vbus_detect_gpio) ||
			gpio_is_valid(n->redriver_en_gpio)) {
		ret = register_gpios(n);
		if (ret < 0) {
			pr_err("register_gpios is failed\n");
			goto err4;
		}
	}

	if (n->is_wakelock)
		wake_lock_init(&u_notify->wlock,
			WAKE_LOCK_SUSPEND, "usb_notify");

	if (n->booting_delay_sec) {
		INIT_DELAYED_WORK(&u_notify->b_delay.booting_work,
				  reserve_state_check);
		schedule_delayed_work(&u_notify->b_delay.booting_work,
				n->booting_delay_sec*HZ);
	}
	register_usbdev_notify();

	pr_info("registered otg_notify -\n");
	return 0;
err4:
	if (!n->unsupport_host)
		host_notify_dev_unregister(&u_notify->ndev);
err3:
	blocking_notifier_chain_unregister(&u_notify->o_notify->extra_notifier,
				&u_notify->extra_nb);
err2:
	atomic_notifier_chain_unregister(&u_notify->o_notify->otg_notifier,
				&u_notify->otg_nb);
err1:
	u_notify->o_notify = NULL;
err:
	return ret;
}
예제 #29
0
int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
	struct msm_mdp_interface *mdp3_interface = &mfd->mdp;
	struct mdp3_session_data *mdp3_session = NULL;
	u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
	int rc;
	int splash_mismatch = 0;

	pr_info("mdp3_ctrl_init\n");
	rc = mdp3_parse_dt_splash(mfd);
	if (rc)
		splash_mismatch = 1;

	mdp3_interface->on_fnc = mdp3_ctrl_on;
	mdp3_interface->off_fnc = mdp3_ctrl_off;
	mdp3_interface->do_histogram = NULL;
	mdp3_interface->cursor_update = NULL;
	mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
	mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
	mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
	mdp3_interface->lut_update = mdp3_ctrl_lut_update;
	mdp3_interface->configure_panel = mdp3_update_panel_info;

	mdp3_session = kzalloc(sizeof(struct mdp3_session_data), GFP_KERNEL);
	if (!mdp3_session) {
		pr_err("fail to allocate mdp3 private data structure");
		return -ENOMEM;
	}
	mutex_init(&mdp3_session->lock);
	INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
	INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
	atomic_set(&mdp3_session->vsync_countdown, 0);
	mutex_init(&mdp3_session->histo_lock);
	mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
	if (!mdp3_session->dma) {
		rc = -ENODEV;
		goto init_done;
	}

	rc = mdp3_dma_init(mdp3_session->dma);
	if (rc) {
		pr_err("fail to init dma\n");
		goto init_done;
	}

	intf_type = mdp3_ctrl_get_intf_type(mfd);
	mdp3_session->intf = mdp3_get_display_intf(intf_type);
	if (!mdp3_session->intf) {
		rc = -ENODEV;
		goto init_done;
	}
	rc = mdp3_intf_init(mdp3_session->intf);
	if (rc) {
		pr_err("fail to init interface\n");
		goto init_done;
	}

	mdp3_session->dma->output_config.out_sel = intf_type;
	mdp3_session->mfd = mfd;
	mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev);
	mdp3_session->status = mdp3_session->intf->active;
	mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
	mdp3_bufq_init(&mdp3_session->bufq_in);
	mdp3_bufq_init(&mdp3_session->bufq_out);
	mdp3_session->histo_status = 0;
	mdp3_session->lut_sel = 0;
	BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head);

	init_timer(&mdp3_session->vsync_timer);
	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
	mdp3_session->vsync_timer.data = (u32)mdp3_session;
	mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate;
	mfd->mdp.private1 = mdp3_session;
	init_completion(&mdp3_session->dma_completion);
	if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO)
		mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done;

	rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group);
	if (rc) {
		pr_err("vsync sysfs group creation failed, ret=%d\n", rc);
		goto init_done;
	}

	mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL,
							"vsync_event");
	if (!mdp3_session->vsync_event_sd) {
		pr_err("vsync_event sysfs lookup failed\n");
		rc = -ENODEV;
		goto init_done;
	}

	rc = mdp3_create_sysfs_link(dev);
	if (rc)
		pr_warn("problem creating link to mdp sysfs\n");

	kobject_uevent(&dev->kobj, KOBJ_ADD);
	pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");

	if (mdp3_get_cont_spash_en()) {
		mdp3_session->clk_on = 1;
		mdp3_session->in_splash_screen = 1;
		mdp3_ctrl_notifier_register(mdp3_session,
			&mdp3_session->mfd->mdp_sync_pt_data.notifier);
	}

	if (splash_mismatch) {
		pr_err("splash memory mismatch, stop splash\n");
		mdp3_ctrl_off(mfd);
	}

	mdp3_session->vsync_before_commit = true;
init_done:
	if (IS_ERR_VALUE(rc))
		kfree(mdp3_session);

	return rc;
}
예제 #30
0
/*
 *	OMAP Device MMU(IOMMU) detection
 */
static int __devinit omap_iommu_probe(struct platform_device *pdev)
{
	int err = -ENODEV;
	void *p;
	int irq;
	struct iommu *obj;
	struct resource *res;
	struct iommu_platform_data *pdata = pdev->dev.platform_data;

	if (pdev->num_resources != 2)
		return -EINVAL;

	obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
	if (!obj)
		return -ENOMEM;

	/* FIX ME: OMAP4 PM framework not ready */
	if (!cpu_is_omap44xx()) {
		obj->clk = clk_get(&pdev->dev, pdata->clk_name);
		if (IS_ERR(obj->clk))
			goto err_clk;
	}
	obj->nr_tlb_entries = pdata->nr_tlb_entries;
	obj->name = pdata->name;
	obj->dev = &pdev->dev;
	obj->ctx = (void *)obj + sizeof(*obj);

	mutex_init(&obj->iommu_lock);
	mutex_init(&obj->mmap_lock);
	spin_lock_init(&obj->page_table_lock);
	INIT_LIST_HEAD(&obj->mmap);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		err = -ENODEV;
		goto err_mem;
	}
	obj->regbase = ioremap(res->start, resource_size(res));
	if (!obj->regbase) {
		err = -ENOMEM;
		goto err_mem;
	}

	res = request_mem_region(res->start, resource_size(res),
				 dev_name(&pdev->dev));
	if (!res) {
		err = -EIO;
		goto err_mem;
	}
	spin_lock_init(&obj->event_lock);
	INIT_LIST_HEAD(&obj->event_list);

	BLOCKING_INIT_NOTIFIER_HEAD(&obj->notifier);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		err = -ENODEV;
		goto err_irq;
	}
	err = request_irq(irq, iommu_fault_handler, IRQF_SHARED,
			  dev_name(&pdev->dev), obj);
	if (err < 0)
		goto err_irq;
	platform_set_drvdata(pdev, obj);

	p = (void *)__get_free_pages(GFP_KERNEL, get_order(IOPGD_TABLE_SIZE));
	if (!p) {
		err = -ENOMEM;
		goto err_pgd;
	}
	memset(p, 0, IOPGD_TABLE_SIZE);
	clean_dcache_area(p, IOPGD_TABLE_SIZE);
	obj->iopgd = p;

	BUG_ON(!IS_ALIGNED((unsigned long)obj->iopgd, IOPGD_TABLE_SIZE));

	dev_info(&pdev->dev, "%s registered\n", obj->name);
	return 0;

err_pgd:
	free_irq(irq, obj);
err_irq:
	release_mem_region(res->start, resource_size(res));
	iounmap(obj->regbase);
err_mem:
	clk_put(obj->clk);
err_clk:
	kfree(obj);
	return err;
}