Ejemplo n.º 1
0
int ss300_init_modemctl_device(struct modem_ctl *mc, struct modem_data *pdata)
{
	int ret = 0;
	unsigned int irq = 0;
	unsigned long flag = 0;
	char name[MAX_NAME_LEN];
	mif_err("+++\n");

	if (!pdata->gpio_cp_on || !pdata->gpio_cp_reset
	    || !pdata->gpio_pda_active || !pdata->gpio_phone_active
	    || !pdata->gpio_ap_wakeup || !pdata->gpio_ap_status
	    || !pdata->gpio_cp_wakeup || !pdata->gpio_cp_status) {
		mif_err("ERR! no GPIO data\n");
		mif_err("xxx\n");
		return -ENXIO;
	}

	mc->gpio_cp_on = pdata->gpio_cp_on;
	mc->gpio_cp_reset = pdata->gpio_cp_reset;
	mc->gpio_pda_active = pdata->gpio_pda_active;
	mc->gpio_phone_active = pdata->gpio_phone_active;
	mc->gpio_ap_wakeup = pdata->gpio_ap_wakeup;
	mc->gpio_ap_status = pdata->gpio_ap_status;
	mc->gpio_cp_wakeup = pdata->gpio_cp_wakeup;
	mc->gpio_cp_status = pdata->gpio_cp_status;

	gpio_set_value(mc->gpio_cp_reset, 0);

	gpio_set_value(mc->gpio_cp_on, 0);

	ss300_get_ops(mc);
	dev_set_drvdata(mc->dev, mc);

	wake_lock_init(&mc_wake_lock, WAKE_LOCK_SUSPEND, "ss300_wake_lock");
	mc->wake_lock = &mc_wake_lock;

	irq = gpio_to_irq(mc->gpio_phone_active);
	if (!irq) {
		mif_err("ERR! no irq_cp_active\n");
		mif_err("xxx\n");
		return -EINVAL;
	}
	mif_err("PHONE_ACTIVE IRQ# = %d\n", irq);

	flag = IRQF_TRIGGER_RISING | IRQF_NO_THREAD | IRQF_NO_SUSPEND;
	snprintf(name, MAX_NAME_LEN, "%s_active", mc->name);
	mif_init_irq(&mc->irq_cp_active, irq, name, flag);

	ret = mif_request_irq(&mc->irq_cp_active, phone_active_handler, mc);
	if (ret) {
		mif_err("%s: ERR! request_irq(%s#%d) fail (%d)\n",
			mc->name, mc->irq_cp_active.name,
			mc->irq_cp_active.num, ret);
		mif_err("xxx\n");
		return ret;
	}

	mif_err("---\n");
	return 0;
}
static int init_pm(struct mem_link_device *mld)
{
	int err;
	unsigned int gpio;
	unsigned int irq_ap_wakeup;
	unsigned int irq_cp_status;
	unsigned long flags;

	gpio_set_value(mld->gpio_ap_status, 0);

	/*
	Retrieve GPIO#, IRQ#, and IRQ flags for PM
	*/
	gpio = mld->gpio_ap_wakeup;
	irq_ap_wakeup = gpio_to_irq(gpio);
	mif_err("CP2AP_WAKEUP GPIO:%d IRQ:%d\n", gpio, irq_ap_wakeup);

	gpio = mld->gpio_cp_wakeup;
	mif_err("AP2CP_WAKEUP GPIO:%d\n", gpio);

	gpio = mld->gpio_cp_status;
	irq_cp_status = gpio_to_irq(gpio);
	mif_err("CP2AP_STATUS GPIO:%d IRQ:%d\n", gpio, irq_cp_status);

	gpio = mld->gpio_ap_status;
	mif_err("AP2CP_STATUS GPIO:%d\n", gpio);

	/*
	Initialize locks, completions, bottom halves, etc.
	*/
	wake_lock_init(&mld->ap_wlock, WAKE_LOCK_SUSPEND, "lli_ap_wlock");

	wake_lock_init(&mld->cp_wlock, WAKE_LOCK_SUSPEND, "lli_cp_wlock");

	INIT_DELAYED_WORK(&mld->cp_sleep_dwork, release_cp_wakeup);

	spin_lock_init(&mld->pm_lock);
	spin_lock_init(&mld->sig_lock);
	atomic_set(&mld->ref_cnt, 0);

	/*
	Enable IRQs for PM
	*/
	print_pm_status(mld);

	flags = (IRQF_TRIGGER_HIGH | IRQF_ONESHOT);

	mif_init_irq(&mld->irq_ap_wakeup, irq_ap_wakeup,
		     "lli_cp2ap_wakeup", flags);
	err = mif_request_irq(&mld->irq_ap_wakeup, ap_wakeup_interrupt, mld);
	if (err)
		return err;
	mif_disable_irq(&mld->irq_ap_wakeup);

	mif_init_irq(&mld->irq_cp_status, irq_cp_status,
		     "lli_cp2ap_status", flags);
	err = mif_request_irq(&mld->irq_cp_status, cp_status_handler, mld);
	if (err)
		return err;
	mif_disable_irq(&mld->irq_cp_status);

	return 0;
}
Ejemplo n.º 3
0
int init_link_device_pm(struct link_device *ld,
			struct modem_link_pm *pm,
			struct link_pm_svc *pm_svc,
			void (*fail_fn)(struct modem_link_pm *),
			void (*cp_fail_fn)(struct modem_link_pm *))
{
	struct modem_data *mdata = ld->mdm_data;
	int err;
	int cp2ap_wakeup;
	int cp2ap_status;
	unsigned int num;
	unsigned long flags;
	char name[MAX_NAME_LEN];

	/*
	Set up variables for PM
	*/
	pm->link_name = ld->name;
	pm->fail_handler = fail_fn;
	pm->cp_fail_handler = cp_fail_fn;

	/*
	Retrieve GPIO pins and IRQ numbers for PM
	*/
	pm->gpio_cp2ap_wakeup = mdata->gpio_ap_wakeup;
	pm->gpio_ap2cp_wakeup = mdata->gpio_cp_wakeup;
	pm->gpio_cp2ap_status = mdata->gpio_cp_status;
	pm->gpio_ap2cp_status = mdata->gpio_ap_status;

	num = gpio_to_irq(pm->gpio_cp2ap_wakeup);
	flags = IRQF_NO_THREAD | IRQF_NO_SUSPEND | IRQF_ONESHOT;
	snprintf(name, MAX_NAME_LEN, "%s_cp2ap_wakeup", pm->link_name);
	mif_init_irq(&pm->cp2ap_wakeup_irq, num, name, flags);

	num = gpio_to_irq(pm->gpio_cp2ap_status);
	flags = IRQF_NO_THREAD | IRQF_NO_SUSPEND | IRQF_ONESHOT;
	snprintf(name, MAX_NAME_LEN, "%s_cp2ap_status", pm->link_name);
	mif_init_irq(&pm->cp2ap_status_irq, num, name, flags);

	mif_err("CP2AP_WAKEUP GPIO:%d IRQ:%d\n",
		pm->gpio_cp2ap_wakeup, pm->cp2ap_wakeup_irq.num);

	mif_err("AP2CP_WAKEUP GPIO:%d\n", pm->gpio_ap2cp_wakeup);

	mif_err("CP2AP_STATUS GPIO:%d IRQ:%d\n",
		pm->gpio_cp2ap_status, pm->cp2ap_status_irq.num);

	mif_err("AP2CP_STATUS GPIO:%d\n", pm->gpio_ap2cp_status);

	/*
	Register cp2ap_wakeup IRQ handler
	*/
	cp2ap_wakeup = gpio_get_value(pm->gpio_cp2ap_wakeup);
	change_irq_level(pm->cp2ap_wakeup_irq.num, cp2ap_wakeup);

	err = mif_request_irq(&pm->cp2ap_wakeup_irq, cp2ap_wakeup_handler, pm);
	if (err) {
		mif_err("%s: ERR! request_irq(%s#%d) fail (%d)\n",
			pm->link_name, pm->cp2ap_wakeup_irq.name,
			pm->cp2ap_wakeup_irq.num, err);
		return err;
	}
	mif_disable_irq(&pm->cp2ap_wakeup_irq);

	mif_err("%s: %s_irq#%d handler registered\n", pm->link_name,
		pm->cp2ap_wakeup_irq.name, pm->cp2ap_wakeup_irq.num);

	/*
	Register cp2ap_status IRQ handler
	*/
	cp2ap_status = gpio_get_value(pm->gpio_cp2ap_status);
	change_irq_level(pm->cp2ap_status_irq.num, cp2ap_status);

	err = mif_request_irq(&pm->cp2ap_status_irq, cp2ap_status_handler, pm);
	if (err) {
		mif_err("%s: ERR! request_irq(%s#%d) fail (%d)\n",
			pm->link_name, pm->cp2ap_status_irq.name,
			pm->cp2ap_status_irq.num, err);
		free_irq(pm->cp2ap_wakeup_irq.num, pm);
		return err;
	}
	mif_disable_irq(&pm->cp2ap_status_irq);

	mif_err("%s: %s_irq#%d handler registered\n", pm->link_name,
		pm->cp2ap_status_irq.name, pm->cp2ap_status_irq.num);

	/*
	Initialize common variables for PM
	*/
	spin_lock_init(&pm->lock);

	snprintf(pm->wlock_name, MAX_NAME_LEN, "%s_pm_wlock", pm->link_name);
	wake_lock_init(&pm->wlock, WAKE_LOCK_SUSPEND, pm->wlock_name);

	snprintf(pm->wq_name, MAX_NAME_LEN, "%s_pm_wq", pm->link_name);
	flags = WQ_NON_REENTRANT | WQ_UNBOUND | WQ_HIGHPRI;
	pm->wq = alloc_workqueue(pm->wq_name, flags, 1);
	if (!pm->wq) {
		mif_err("%s: ERR! fail to create %s\n",
			pm->link_name, pm->wq_name);
		return -EFAULT;
	}

	INIT_DELAYED_WORK(&pm->cp_free_dwork, cp_free_work_func);

	init_pm_fsm(pm);

	/*
	Register PM functions set by the common link PM framework and used by
	each link device driver
	*/
	pm->start = start_link_pm;
	pm->stop = stop_link_pm;
	pm->request_hold = request_hold;
	pm->release_hold = release_hold;
	pm->link_active = link_active;

	return 0;
}