static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err)
{
	struct cx18 *cx = s->cx;
	struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
	struct cx18_buffer *buf;
	DEFINE_WAIT(wait);

	*err = 0;
	while (1) {
		if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
			/* Process pending program info updates and pending
			   VBI data */

			if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
				cx->dualwatch_jiffies = jiffies;
				cx18_dualwatch(cx);
			}
			if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
			    !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
				while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
					/* byteswap and process VBI data */
					cx18_process_vbi_data(cx, buf,
							      s_vbi->type);
					cx18_stream_put_buf_fw(s_vbi, buf);
				}
			}
			buf = &cx->vbi.sliced_mpeg_buf;
			if (buf->readpos != buf->bytesused)
				return buf;
		}

		/* do we have new data? */
		buf = cx18_dequeue(s, &s->q_full);
		if (buf) {
			if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP,
						&buf->b_flags))
				return buf;
			if (s->type == CX18_ENC_STREAM_TYPE_MPG)
				/* byteswap MPG data */
				cx18_buf_swap(buf);
			else {
				/* byteswap and process VBI data */
				cx18_process_vbi_data(cx, buf, s->type);
			}
			return buf;
		}

		/* return if end of stream */
		if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
			CX18_DEBUG_INFO("EOS %s\n", s->name);
			return NULL;
		}

		/* return if file was opened with O_NONBLOCK */
		if (non_block) {
			*err = -EAGAIN;
			return NULL;
		}

		/* wait for more data to arrive */
		prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
		/* New buffers might have become available before we were added
		   to the waitqueue */
		if (!atomic_read(&s->q_full.buffers))
			schedule();
		finish_wait(&s->waitq, &wait);
		if (signal_pending(current)) {
			/* return if a signal was received */
			CX18_DEBUG_INFO("User stopped %s\n", s->name);
			*err = -EINTR;
			return NULL;
		}
	}
}
Esempio n. 2
0
static int pm8058_tz_get_temp(struct thermal_zone_device *thermal,
			      unsigned long *temp)
{
	struct pm8058_tm_device *tm = thermal->devdata;
	DECLARE_COMPLETION_ONSTACK(wait);
	struct adc_chan_result adc_result = {
		.physical = 0lu,
	};
	int rc;
#ifdef CONFIG_LGE_PM
    int wait_ret;
#endif

	if (!tm || !temp)
		return -EINVAL;

	*temp = tm->temp;

	rc = adc_channel_request_conv(tm->adc_handle, &wait);
	if (rc < 0) {
		pr_err("%s: adc_channel_request_conv() failed, rc = %d\n",
			__func__, rc);
		return rc;
	}

#ifdef CONFIG_LGE_PM
    wait_ret = wait_for_completion_timeout(&wait, msecs_to_jiffies(MSM_PMIC_ADC_READ_TIMEOUT));
    if(wait_ret <= 0)
    {
		printk(KERN_ERR "===%s: failed to adc wait for completion!===\n",__func__);
        goto sanity_out;
    }
#else
	wait_for_completion(&wait);
#endif

	rc = adc_channel_read_result(tm->adc_handle, &adc_result);
	if (rc < 0) {
		pr_err("%s: adc_channel_read_result() failed, rc = %d\n",
			__func__, rc);
		return rc;
	}

	*temp = adc_result.physical;
	tm->temp = adc_result.physical;

	return 0;

#ifdef CONFIG_LGE_PM
sanity_out:

    pm8058_xoadc_clear_recentQ();

	*temp = MSM_CHARGER_GAUGE_MISSING_TEMP;
	tm->temp = MSM_CHARGER_GAUGE_MISSING_TEMP;
    
    printk(KERN_ERR "============== batt temp adc read fail so default temp ===============\n");
    return 0;
#endif    

}

static int pm8058_tz_get_mode(struct thermal_zone_device *thermal,
			      enum thermal_device_mode *mode)
{
	struct pm8058_tm_device *tm = thermal->devdata;

	if (!tm || !mode)
		return -EINVAL;

	*mode = tm->mode;

	return 0;
}

static int pm8058_tz_set_mode(struct thermal_zone_device *thermal,
			      enum thermal_device_mode mode)
{
	struct pm8058_tm_device *tm = thermal->devdata;

	if (!tm)
		return -EINVAL;

	if (mode != tm->mode) {
		if (mode == THERMAL_DEVICE_ENABLED)
			pm8058_tm_shutdown_override(tm->pm_chip,
						    SOFTWARE_OVERRIDE_ENABLED);
		else
			pm8058_tm_shutdown_override(tm->pm_chip,
						    SOFTWARE_OVERRIDE_DISABLED);
	}
	tm->mode = mode;

	return 0;
}

static int pm8058_tz_get_trip_type(struct thermal_zone_device *thermal,
				   int trip, enum thermal_trip_type *type)
{
	struct pm8058_tm_device *tm = thermal->devdata;

	if (!tm || trip < 0 || !type)
		return -EINVAL;

	switch (trip) {
	case PM8058_TRIP_STAGE3:
		*type = THERMAL_TRIP_CRITICAL;
		break;
	case PM8058_TRIP_STAGE2:
		*type = THERMAL_TRIP_HOT;
		break;
	case PM8058_TRIP_STAGE1:
		*type = THERMAL_TRIP_HOT;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int pm8058_tz_get_trip_temp(struct thermal_zone_device *thermal,
				   int trip, unsigned long *temp)
{
	struct pm8058_tm_device *tm = thermal->devdata;
	int thresh_temp;

	if (!tm || trip < 0 || !temp)
		return -EINVAL;

	thresh_temp = tm->thresh * PM8058_TEMP_THRESH_STEP +
		      PM8058_TEMP_THRESH_MIN;

	switch (trip) {
	case PM8058_TRIP_STAGE3:
		thresh_temp += 2 * PM8058_TEMP_STAGE_STEP;
		break;
	case PM8058_TRIP_STAGE2:
		thresh_temp += PM8058_TEMP_STAGE_STEP;
		break;
	case PM8058_TRIP_STAGE1:
		break;
	default:
		return -EINVAL;
	}

	*temp = thresh_temp;

	return 0;
}

static int pm8058_tz_get_crit_temp(struct thermal_zone_device *thermal,
				   unsigned long *temp)
{
	struct pm8058_tm_device *tm = thermal->devdata;

	if (!tm || !temp)
		return -EINVAL;

	*temp = tm->thresh * PM8058_TEMP_THRESH_STEP + PM8058_TEMP_THRESH_MIN +
		2 * PM8058_TEMP_STAGE_STEP;

	return 0;
}

static struct thermal_zone_device_ops pm8058_thermal_zone_ops = {
	.get_temp = pm8058_tz_get_temp,
	.get_mode = pm8058_tz_get_mode,
	.set_mode = pm8058_tz_set_mode,
	.get_trip_type = pm8058_tz_get_trip_type,
	.get_trip_temp = pm8058_tz_get_trip_temp,
	.get_crit_temp = pm8058_tz_get_crit_temp,
};

static irqreturn_t pm8058_tm_isr(int irq, void *data)
{
	struct pm8058_tm_device *tm = data;
	int rc;
	u8 reg;

	rc = pm8058_tm_read_ctrl(tm->pm_chip, &reg);
	if (rc < 0)
		goto isr_handled;

	tm->stage = (reg & PM8058_TEMP_STATUS_MASK) >> PM8058_TEMP_STATUS_SHIFT;
	tm->thresh = (reg & PM8058_TEMP_THRESH_MASK) >>
			PM8058_TEMP_THRESH_SHIFT;

	if (reg & (PM8058_TEMP_ST2_SD | PM8058_TEMP_ST3_SD)) {
		reg &= ~(PM8058_TEMP_ST2_SD | PM8058_TEMP_ST3_SD |
			 PM8058_TEMP_STATUS_MASK);
		pm8058_tm_write_ctrl(tm->pm_chip, reg);
	}

	thermal_zone_device_update(tm->tz_dev);

	/* Notify user space */
	if (tm->mode == THERMAL_DEVICE_ENABLED)
		kobject_uevent(&tm->tz_dev->device.kobj, KOBJ_CHANGE);

isr_handled:
	return IRQ_HANDLED;
}

static int pm8058_tm_init_reg(struct pm8058_tm_device *tm)
{
	int rc;
	u8 reg;

	rc = pm8058_tm_read_ctrl(tm->pm_chip, &reg);
	if (rc < 0)
		return rc;

	tm->stage = (reg & PM8058_TEMP_STATUS_MASK) >> PM8058_TEMP_STATUS_SHIFT;
	tm->temp = 0;

	/* Use temperature threshold set 0: (105, 125, 145) */
	tm->thresh = 0;
	reg = (tm->thresh << PM8058_TEMP_THRESH_SHIFT) &
	      PM8058_TEMP_THRESH_MASK;
	rc = pm8058_tm_write_ctrl(tm->pm_chip, reg);
	if (rc < 0)
		return rc;

	/*
	 * Set the PMIC alarm module PWM to have a frequency of 8 Hz. This
	 * helps cut down on the number of unnecessary interrupts fired when
	 * changing between thermal stages.  Also, Enable the over temperature
	 * PWM whenever the PMIC is enabled.
	 */
	reg =  1 << PM8058_TEMP_PWM_EN_SHIFT |
	       3 << PM8058_TEMP_PWM_PER_PRE_SHIFT |
	       3 << PM8058_TEMP_PWM_PER_DIV_SHIFT;

	rc = pm8058_tm_write_pwm(tm->pm_chip, reg);

	return rc;
}
static irqreturn_t ehci_irq (struct usb_hcd *hcd)
{
	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
	u32			status, masked_status, pcd_status = 0, cmd;
	int			bh;

	spin_lock (&ehci->lock);

	status = ehci_readl(ehci, &ehci->regs->status);

	/* e.g. cardbus physical eject */
	if (status == ~(u32) 0) {
		ehci_dbg (ehci, "device removed\n");
		goto dead;
	}

	masked_status = status & INTR_MASK;
	if (!masked_status) {		/* irq sharing? */
		spin_unlock(&ehci->lock);
		return IRQ_NONE;
	}

	/* clear (just) interrupts */
	ehci_writel(ehci, masked_status, &ehci->regs->status);
	cmd = ehci_readl(ehci, &ehci->regs->command);
	bh = 0;

#ifdef	VERBOSE_DEBUG
	/* unrequested/ignored: Frame List Rollover */
	dbg_status (ehci, "irq", status);
#endif

	/* INT, ERR, and IAA interrupt rates can be throttled */

	/* normal [4.15.1.2] or error [4.15.1.1] completion */
	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
		if (likely ((status & STS_ERR) == 0))
			COUNT (ehci->stats.normal);
		else
			COUNT (ehci->stats.error);
		bh = 1;
	}

	/* complete the unlinking of some qh [4.15.2.3] */
	if (status & STS_IAA) {
		/* guard against (alleged) silicon errata */
		if (cmd & CMD_IAAD) {
			ehci_writel(ehci, cmd & ~CMD_IAAD,
					&ehci->regs->command);
			ehci_dbg(ehci, "IAA with IAAD still set?\n");
		}
		if (ehci->reclaim) {
			COUNT(ehci->stats.reclaim);
			end_unlink_async(ehci);
		} else
			ehci_dbg(ehci, "IAA with nothing to reclaim?\n");
	}

	/* remote wakeup [4.3.1] */
	if (status & STS_PCD) {
		unsigned	i = HCS_N_PORTS (ehci->hcs_params);

		/* kick root hub later */
		pcd_status = status;

		/* resume root hub? */
		if (!(cmd & CMD_RUN))
			usb_hcd_resume_root_hub(hcd);

		while (i--) {
			int pstatus = ehci_readl(ehci,
						 &ehci->regs->port_status [i]);

			if (pstatus & PORT_OWNER)
				continue;
			if (!(test_bit(i, &ehci->suspended_ports) &&
					((pstatus & PORT_RESUME) ||
						!(pstatus & PORT_SUSPEND)) &&
					(pstatus & PORT_PE) &&
					ehci->reset_done[i] == 0))
				continue;

			/* start 20 msec resume signaling from this port,
			 * and make khubd collect PORT_STAT_C_SUSPEND to
			 * stop that signaling.
			 */
			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
			mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
		}
	}

	/* PCI errors [4.15.2.4] */
	if (unlikely ((status & STS_FATAL) != 0)) {
		ehci_err(ehci, "fatal error\n");
		dbg_cmd(ehci, "fatal", cmd);
		dbg_status(ehci, "fatal", status);
		ehci_halt(ehci);
dead:
		ehci_reset(ehci);
		ehci_writel(ehci, 0, &ehci->regs->configured_flag);
		/* generic layer kills/unlinks all urbs, then
		 * uses ehci_stop to clean up the rest
		 */
		bh = 1;
	}

	if (bh)
		ehci_work (ehci);
	spin_unlock (&ehci->lock);
	if (pcd_status)
		usb_hcd_poll_rh_status(hcd);
	return IRQ_HANDLED;
}
Esempio n. 4
0
static int start_ipc(struct link_device *ld, struct io_device *iod)
{
	struct sk_buff *skb;
	char data[1] = {'a'};
	int err;
	struct usb_link_device *usb_ld = to_usb_link_device(ld);
	struct link_pm_data *pm_data = usb_ld->link_pm_data;
	struct device *dev = &usb_ld->usbdev->dev;
	struct if_usb_devdata *pipe_data = &usb_ld->devdata[IF_USB_FMT_EP];

	if (!usb_ld->if_usb_connected) {
		mif_err("HSIC not connected, skip start ipc\n");
		err = -ENODEV;
		goto exit;
	}

retry:
	if (ld->mc->phone_state != STATE_ONLINE) {
		mif_err("MODEM is not online, skip start ipc\n");
		err = -ENODEV;
		goto exit;
	}

	/* check usb runtime pm first */
	if (dev->power.runtime_status != RPM_ACTIVE) {
		if (!pm_data->resume_requested) {
			mif_debug("QW PM\n");
			INIT_COMPLETION(pm_data->active_done);
			queue_delayed_work(pm_data->wq,
					&pm_data->link_pm_work, 0);
		}
		mif_debug("Wait pm\n");
		err = wait_for_completion_timeout(&pm_data->active_done,
							msecs_to_jiffies(500));
		/* timeout or -ERESTARTSYS */
		if (err <= 0)
			goto retry;
	}

	pm_runtime_get_sync(dev);

	mif_err("send 'a'\n");

	skb = alloc_skb(16, GFP_ATOMIC);
	if (unlikely(!skb)) {
		pm_runtime_put(dev);
		return -ENOMEM;
	}
	memcpy(skb_put(skb, 1), data, 1);
	skbpriv(skb)->iod = iod;
	skbpriv(skb)->ld = ld;

	if (!usb_ld->if_usb_connected || !usb_ld->usbdev)
		return -ENODEV;

	usb_mark_last_busy(usb_ld->usbdev);
	err = usb_tx_urb_with_skb(usb_ld->usbdev, skb, pipe_data);
	if (err < 0) {
		mif_err("usb_tx_urb fail\n");
		dev_kfree_skb_any(skb);
	}

	pm_runtime_put(dev);
exit:
	return err;
}
Esempio n. 5
0
static void link_pm_runtime_work(struct work_struct *work)
{
	int ret;
	struct link_pm_data *pm_data =
		container_of(work, struct link_pm_data, link_pm_work.work);
	struct device *dev = &pm_data->usb_ld->usbdev->dev;

	if (!pm_data->usb_ld->if_usb_connected || pm_data->dpm_suspending)
		return;

	if (pm_data->usb_ld->ld.com_state == COM_NONE)
		return;

	mif_debug("for dev 0x%p : current %d\n", dev,
					dev->power.runtime_status);

	switch (dev->power.runtime_status) {
	case RPM_ACTIVE:
		pm_data->resume_retry_cnt = 0;
		pm_data->resume_requested = false;
		complete(&pm_data->active_done);

		return;
	case RPM_SUSPENDED:
		if (pm_data->resume_requested)
			break;
		pm_data->resume_requested = true;
		wake_lock(&pm_data->rpm_wake);
		ret = link_pm_slave_wake(pm_data);
		if (ret < 0) {
			mif_err("slave wake fail\n");
			wake_unlock(&pm_data->rpm_wake);
			break;
		}

		if (!pm_data->usb_ld->if_usb_connected) {
			wake_unlock(&pm_data->rpm_wake);
			return;
		}

		ret = pm_runtime_resume(dev);
		if (ret < 0) {
			mif_err("resume error(%d)\n", ret);
			if (!pm_data->usb_ld->if_usb_connected) {
				wake_unlock(&pm_data->rpm_wake);
				return;
			}
			/* force to go runtime idle before retry resume */
			if (dev->power.timer_expires == 0 &&
						!dev->power.request_pending) {
				mif_debug("run time idle\n");
				pm_runtime_idle(dev);
			}
		}
		wake_unlock(&pm_data->rpm_wake);
		break;
	case RPM_SUSPENDING:
		/* Checking the usb_runtime_suspend running time.*/
		mif_info("rpm_states=%d", dev->power.runtime_status);
		msleep(20);
		break;
	default:
		break;
	}
	pm_data->resume_requested = false;

	/* check until runtime_status goes to active */
	/* attemp 10 times, or re-establish modem-link */
	/* if pm_runtime_resume run properly, rpm status must be in ACTIVE */
	if (dev->power.runtime_status == RPM_ACTIVE) {
		pm_data->resume_retry_cnt = 0;
		complete(&pm_data->active_done);
	} else if (pm_data->resume_retry_cnt++ > 10) {
		mif_err("runtime_status(%d), retry_cnt(%d)\n",
			dev->power.runtime_status, pm_data->resume_retry_cnt);
		link_pm_change_modem_state(pm_data, STATE_CRASH_RESET);
	} else
		queue_delayed_work(pm_data->wq, &pm_data->link_pm_work,
							msecs_to_jiffies(20));
}
Esempio n. 6
0
static int ath9k_htc_start(struct ieee80211_hw *hw)
{
	struct ath9k_htc_priv *priv = hw->priv;
	struct ath_hw *ah = priv->ah;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ieee80211_channel *curchan = hw->conf.channel;
	struct ath9k_channel *init_channel;
	int ret = 0;
	enum htc_phymode mode;
	__be16 htc_mode;
	u8 cmd_rsp;

	mutex_lock(&priv->mutex);

	ath_dbg(common, ATH_DBG_CONFIG,
		"Starting driver with initial channel: %d MHz\n",
		curchan->center_freq);

	/* Ensure that HW is awake before flushing RX */
	ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
	WMI_CMD(WMI_FLUSH_RECV_CMDID);

	/* setup initial channel */
	init_channel = ath9k_cmn_get_curchannel(hw, ah);

	ath9k_hw_htc_resetinit(ah);
	ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
	if (ret) {
		ath_err(common,
			"Unable to reset hardware; reset status %d (freq %u MHz)\n",
			ret, curchan->center_freq);
		mutex_unlock(&priv->mutex);
		return ret;
	}

	ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
			       &priv->curtxpow);

	mode = ath9k_htc_get_curmode(priv, init_channel);
	htc_mode = cpu_to_be16(mode);
	WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
	WMI_CMD(WMI_ATH_INIT_CMDID);
	WMI_CMD(WMI_START_RECV_CMDID);

	ath9k_host_rx_init(priv);

	ret = ath9k_htc_update_cap_target(priv, 0);
	if (ret)
		ath_dbg(common, ATH_DBG_CONFIG,
			"Failed to update capability in target\n");

	priv->op_flags &= ~OP_INVALID;
	htc_start(priv->htc);

	spin_lock_bh(&priv->tx.tx_lock);
	priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
	spin_unlock_bh(&priv->tx.tx_lock);

	ieee80211_wake_queues(hw);

	mod_timer(&priv->tx.cleanup_timer,
		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));

	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
					   AR_STOMP_LOW_WLAN_WGHT);
		ath9k_hw_btcoex_enable(ah);
		ath_htc_resume_btcoex_work(priv);
	}
	mutex_unlock(&priv->mutex);

	return ret;
}
Esempio n. 7
0
static void type_det_work(struct work_struct *work)
{
    NvU32 hook_value =0;
	if (headset_off) return;

    NvOdmGpioGetState(s_hHeadsetHandle.hGpio, s_hHeadsetHandle.h_Headset_Detection, &headset_gpio_status);	
	headset_status = headset_gpio_status;
    
	if( (headset_status == 1) && (headset_type == STAR_NONE))	
	{
#if defined(CONFIG_MACH_STAR_SKT_REV_A)  
		 if(star_get_i2c_busy())
		 {
			  schedule_delayed_work(&headset_sw_data->delayed_work,	msecs_to_jiffies(type_detection_time));	
			lprintk(D_AUDIO, KERN_ERR "@@(Headset_det.c)@@ type_det_work(), i2c is busy\n");
			return;
		 }
		 star_set_i2c_busy();
		star_headsetdet_bias(1);
#else
		headset_Mic_Bias(1);
#endif

	#if HOOK_USE_ADC
		hook_value = headset_get_hook_adc_value();	

		if(hook_value > 350) //20101127  detect adc 1200==>350[LGE_LAB1]
			headset_type = STAR_HEADSET;	
		else
			headset_type = STAR_HEADPHONE;
	#else
		NvOdmGpioGetState(s_hHeadsetHandle.hGpio, s_hHeadsetHandle.h_Hookkey_Detection, &hookkey_gpio_status);	// 20100419 for nVidia headset driver
		if(hookkey_gpio_status == 0){ 
		   headset_type = STAR_HEADPHONE;
			hook_value = 1111;
		}
		else{
		   headset_type = STAR_HEADSET;
			hook_value = 2222;
		}
	#endif
	}
	else if(headset_status == 0){
		headset_type = STAR_NONE;
        hook_status = HOOK_RELEASED; 
		input_report_key(headset_sw_data->ip_dev, KEY_HOOK, 0);
		input_sync(headset_sw_data->ip_dev);
    }

	lprintk(D_AUDIO, KERN_ERR "@@(Headset_det.c)@@ type_det_work(), HOOKVALUE %d headset_type = %d\n", hook_value, headset_type);
#if defined(CONFIG_MACH_STAR_SKT_REV_A)  
	if(headset_type != STAR_HEADSET){
		block_hook_int =1;
		star_headsetdet_bias(0);	//20100419   for Headset MIC Bias  ==> framwork function used in kernel ==> error [LGE]
	}
	else{
        block_hook_int =0;
	}
	star_unset_i2c_busy();
#else
	if(headset_type != STAR_HEADSET){
        block_hook_int =1;
		headset_Mic_Bias(0);
	}
    else{
        block_hook_int =0;
	}
#endif
	headset_detecting = 0;

	switch_set_state(&headset_sw_data->sdev, headset_type); 
}
Esempio n. 8
0
static void s3c_sdi_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
    struct s3c_sdi_host *host = mmc_priv(mmc);
    u32 sdi_carg, sdi_ccon, sdi_timer, sdi_fsta;
    u32 sdi_bsize, sdi_dcon = 0, sdi_imsk;
    u32 dma_dir = 0;
    unsigned long complete_timeout = msecs_to_jiffies( 1000 ); // 1000 msec timeout on wait for command completion
    WARN_ON(host->mrq != NULL);
    DBG("#############request: [CMD] opcode:0x%02x arg:0x%08x flags:%x retries:%u\n",
        mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags, mrq->cmd->retries);

    host->mrq = mrq;

    sdi_ccon = mrq->cmd->opcode & S3C_SDICCON_INDEX;
    sdi_ccon|= (S3C_SDICCON_SENDERHOST | S3C_SDICCON_CMDSTART);

#ifdef CONFIG_S3CMCI_DEBUG
    {
        cmd_rec[cmd_idx] = mrq->cmd->opcode;
        cmd_idx++;
        cmd_idx %= 40;
    }
#endif
    sdi_carg = mrq->cmd->arg;

    /* XXX: Timer value ?! */
    /* If the workaround for read is enabled, change the timer value. */
    if( host->ena_2410_workaround )
        sdi_timer=0xFFFF;
    else
        sdi_timer= 0x7fffff;

    sdi_bsize= 0;

    /* enable interrupts for transmission errors */
    sdi_imsk = (S3C_SDIIMSK_RESPONSEND | S3C_SDIIMSK_CRCSTATUS);

    host->complete_what = COMPLETION_CMDSENT;

    if (RSP_TYPE(mmc_resp_type(mrq->cmd))) {
        host->complete_what = COMPLETION_RSPFIN;

        sdi_ccon |= S3C_SDICCON_WAITRSP;
        sdi_imsk |= S3C_SDIIMSK_CMDTIMEOUT;
    } else {
        /* We need the CMDSENT-Interrupt only if we want are not waiting
         * for a response
         */
        sdi_imsk |= S3C_SDIIMSK_CMDSENT;
    }

    if (mrq->cmd->flags & MMC_RSP_136) {
        sdi_ccon|= S3C_SDICCON_LONGRSP;
    }

    if (mrq->cmd->flags & MMC_RSP_CRC) {
        sdi_imsk |= S3C_SDIIMSK_RESPONSECRC;
    }

    if (mrq->data) {
        host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
        sdi_ccon|= S3C_SDICCON_WITHDATA;

        sdi_bsize = mrq->data->blksz;

        sdi_dcon  = (mrq->data->blocks & S3C_SDIDCON_BLKNUM_MASK);
        sdi_dcon |= S3C_SDIDCON_DMAEN;

        if( !host->ena_2410_workaround )
            sdi_dcon |= S3C_SDIDCON_WORDTX;

        if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
            sdi_dcon |= S3C_SDIDCON_WIDEBUS;
        }

        sdi_imsk |= 0xFFFFFFE0;

        DBG(PFX "request: [DAT] bsize:%u blocks:%u bytes:%u\n",
            sdi_bsize, mrq->data->blocks, mrq->data->blocks * sdi_bsize);

        if (!(mrq->data->flags & MMC_DATA_STREAM)) {
            sdi_dcon |= S3C_SDIDCON_BLOCKMODE;
        }

        if (mrq->data->flags & MMC_DATA_WRITE) {
            sdi_dcon |= S3C_SDIDCON_TXAFTERRESP;
            sdi_dcon |= S3C_SDIDCON_XFER_TX;
            if( !host->ena_2410_workaround )
                sdi_dcon |= S3C_SDIDCON_DSTART;
            s3c_sdi_dma_setup(host, DMAP_WRITE);
            dma_dir = DMA_TO_DEVICE;
        } else {

            sdi_dcon |= S3C_SDIDCON_RXAFTERCMD;
            sdi_dcon |= S3C_SDIDCON_XFER_RX;
            if( !host->ena_2410_workaround )
                sdi_dcon |= S3C_SDIDCON_DSTART;
            s3c_sdi_dma_setup(host, DMAP_READ);
            dma_dir = DMA_FROM_DEVICE;
        }

        /* Clear FAIL bits also for the fifo. */
        sdi_fsta = S3C_SDIFSTA_FRST | S3C_SDIFSTA_FIFOFAIL;
        __raw_writel(sdi_fsta,host->base + S3C_SDIFSTA);

        /* start DMA */
        dma_map_sg(mmc_dev(mmc), mrq->data->sg, mrq->data->sg_len, dma_dir);
#ifdef CONFIG_ARCH_MDIRAC3
        s3c_dma_enqueue(host->dma,host->subchannel,(void *) host,
                        sg_dma_address(mrq->data->sg),
                        (mrq->data->blocks * mrq->data->blksz) );
#else
        s3c_dma_enqueue(host->dma, (void *) host,
                        sg_dma_address(mrq->data->sg),
                        (mrq->data->blocks * mrq->data->blksz) );
#endif
        /* Check if we should enable the workaround for timeouts in the 2410 soc. */
        /* Since we want to go as fast as possible, don't use the maximum divider.*/
        /* dividing by 90 will give a clock of roughly 553MHz. This should be safe*/
        /* enough. */
        host->prescaler=readl( host->base + S3C_SDIPRE );
        if( host->ena_2410_workaround && (mrq->data->flags & MMC_DATA_READ) )
            writel( (clk_get_rate( host->clk )/533000), host->base + S3C_SDIPRE );
    }

    host->mrq = mrq;
    init_completion(&host->complete_request);
    init_completion(&host->complete_dma);

    /* Clear command and data status registers */
    writel(0xFFFFFFFF, host->base + S3C_SDICSTA);
    writel(0xFFFFFFFF, host->base + S3C_SDIDSTA);

    /* Setup SDI controller */
    writel(sdi_bsize,host->base + S3C_SDIBSIZE);
    writel(sdi_timer,host->base + S3C_SDITIMER);

    writel(sdi_imsk,host->base + S3C_SDIIMSK);

    /* Setup SDI command argument and data control */
    writel(sdi_carg, host->base + S3C_SDICARG);
    writel(sdi_dcon, host->base + S3C_SDIDCON);

    /* This initiates transfer */
    writel(sdi_ccon, host->base + S3C_SDICCON);

    /* Workaround for S3C2410. When the receive transfer has started we can write the */
    /* original prescaler back to transfer at maximum speed. Talk about a dirty hack...*/
    if( host->ena_2410_workaround && (mrq->data != NULL) && (mrq->data->flags & MMC_DATA_READ) )
    {
        /* Start polling if the receive transfer has started.... */
        while( ((readl( host->base + S3C_SDIFSTA ) & 0x7F) == 0) && ((readl( host->base + S3C_SDIDSTA ) & 0x30) == 0) )
        {
            /* Ensure that if an error occurs, we can still exit. */
            if( readl( host->base + S3C_SDIDSTA ) & (S3C_SDIDSTA_FIFOFAIL | S3C_SDIDSTA_CRCFAIL |
                    S3C_SDIDSTA_RXCRCFAIL | S3C_SDIDSTA_DATATIMEOUT |
                    S3C_SDIDSTA_SBITERR) )
                break;
        }
        writel( host->prescaler, host->base + S3C_SDIPRE );
    }

    /* this wait is very important to sd/mmc run correctly.
     * Without this blocking code, operation sequence may be crashed.
     * by scsuh.
     */
    /* Wait for transfer to complete */
    wait_for_completion_timeout(&host->complete_request, complete_timeout);
    if (mrq->data && (host->mrq->data->error == MMC_ERR_NONE)) {
        if (wait_for_completion_timeout(&host->complete_dma, complete_timeout) == 0)
        {
#ifdef CONFIG_ARCH_MDIRAC3
            s3c_dma_ctrl(host->dma,host->subchannel, S3C_DMAOP_FLUSH);
#else
            s3c_dma_ctrl(host->dma, S3C_DMAOP_FLUSH);
#endif
        }
        DBG("[DAT] DMA complete.\n");
        sdi_fsta = readl(host->base + S3C_SDIFSTA);
        writel(sdi_fsta,host->base + S3C_SDIFSTA);
    }

    /* Cleanup controller */
    writel(0, host->base + S3C_SDICARG);
    writel(0, host->base + S3C_SDIDCON);
    writel(0, host->base + S3C_SDICCON);
    writel(0, host->base + S3C_SDIIMSK);

    /* Read response */
    mrq->cmd->resp[0] = readl(host->base + S3C_SDIRSP0);
    mrq->cmd->resp[1] = readl(host->base + S3C_SDIRSP1);
    mrq->cmd->resp[2] = readl(host->base + S3C_SDIRSP2);
    mrq->cmd->resp[3] = readl(host->base + S3C_SDIRSP3);

    host->mrq = NULL;

    DBG(PFX "request done.\n");

    if (mrq->data) {
        dma_unmap_sg(mmc_dev(mmc), mrq->data->sg, mrq->data->sg_len, dma_dir);

        /* Calculate the about of bytes transfer, but only if there was
         * no error
         */
        if (mrq->data->error == MMC_ERR_NONE)
            mrq->data->bytes_xfered = (mrq->data->blocks * mrq->data->blksz);
        else
            mrq->data->bytes_xfered = 0;

        /* If we had an error while transferring data we flush the
         * DMA channel to clear out any garbage
         */
        if (mrq->data->error != MMC_ERR_NONE) {
#ifdef CONFIG_ARCH_MDIRAC3
            s3c_dma_ctrl(host->dma,host->subchannel, S3C_DMAOP_FLUSH);
#else
            s3c_dma_ctrl(host->dma, S3C_DMAOP_FLUSH);
#endif
            DBG(PFX "flushing DMA.\n");
        }
        /* Issue stop command */
        if (mrq->data->stop)
            mmc_wait_for_cmd(mmc, mrq->data->stop, 3);
    }

    mrq->done(mrq);
}
u32	_mali_osk_time_mstoticks( u32 ms )
{
	return msecs_to_jiffies(ms);
}
Esempio n. 10
0
static int smd_tty_open(struct tty_struct *tty, struct file *f)
{
	int res = 0;
	unsigned int n = tty->index;
	struct smd_tty_info *info;
	const char *peripheral = NULL;


	if (n >= MAX_SMD_TTYS || !smd_tty[n].smd)
		return -ENODEV;

	info = smd_tty + n;

	mutex_lock(&smd_tty_lock);
	tty->driver_data = info;

	if (info->open_count++ == 0) {
		peripheral = smd_edge_to_subsystem(smd_tty[n].smd->edge);
		if (peripheral) {
			info->pil = pil_get(peripheral);
			if (IS_ERR(info->pil)) {
				res = PTR_ERR(info->pil);
				goto out;
			}

			/* Wait for the modem SMSM to be inited for the SMD
			 * Loopback channel to be allocated at the modem. Since
			 * the wait need to be done atmost once, using msleep
			 * doesn't degrade the performance.
			 */
			if (n == LOOPBACK_IDX) {
				if (!is_modem_smsm_inited())
					msleep(5000);
				smsm_change_state(SMSM_APPS_STATE,
					0, SMSM_SMD_LOOPBACK);
				msleep(100);
			}


			/*
			 * Wait for a channel to be allocated so we know
			 * the modem is ready enough.
			 */
			if (smd_tty_modem_wait) {
				res = wait_for_completion_interruptible_timeout(
					&info->ch_allocated,
					msecs_to_jiffies(smd_tty_modem_wait *
									1000));

				if (res == 0) {
					pr_err("Timed out waiting for SMD"
								" channel\n");
					res = -ETIMEDOUT;
					goto release_pil;
				} else if (res < 0) {
					pr_err("Error waiting for SMD channel:"
									" %d\n",
						res);
					goto release_pil;
				}

				res = 0;
			}

#ifdef CONFIG_LGE_USES_SMD_DS_TTY
			/*           
                                                      
                                
    */
			if (n == DS_IDX) {
				/* wait for open ready status in seconds */
				pr_info("%s: checking DS modem status\n", __func__);
				res = wait_event_interruptible_timeout(
						info->ch_opened_wait_queue,
						info->is_dsmodem_ready, (lge_ds_modem_wait * HZ));
				if (res == 0) {
					res = -ETIMEDOUT;
					pr_err("%s: timeout to wait for %s modem: %d\n",
							__func__, smd_tty[n].smd->port_name, res);
					goto release_pil;
				}
				if (res < 0) {
					pr_err("%s: timeout to wait for %s modem: %d\n",
							__func__, smd_tty[n].smd->port_name, res);
					goto release_pil;
				}
				pr_info("%s: DS modem is OK, open smd0..\n", __func__);
			}
#endif
		}


		info->tty = tty;
		tasklet_init(&info->tty_tsklt, smd_tty_read,
			     (unsigned long)info);
		wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND,
				smd_tty[n].smd->port_name);
		if (!info->ch) {
			res = smd_named_open_on_edge(smd_tty[n].smd->port_name,
							smd_tty[n].smd->edge,
							&info->ch, info,
							smd_tty_notify);
			if (res < 0) {
				pr_err("%s: %s open failed %d\n", __func__,
					smd_tty[n].smd->port_name, res);
				goto release_pil;
			}

			res = wait_event_interruptible_timeout(
				info->ch_opened_wait_queue,
				info->is_open, (2 * HZ));
			if (res == 0)
				res = -ETIMEDOUT;
			if (res < 0) {
				pr_err("%s: wait for %s smd_open failed %d\n",
					__func__, smd_tty[n].smd->port_name,
					res);
				goto release_pil;
			}
			res = 0;
		}
	}

release_pil:
	if (res < 0)
		pil_put(info->pil);
	else
		smd_disable_read_intr(info->ch);
out:
	mutex_unlock(&smd_tty_lock);

	return res;
}
static int dhd_wifi_platform_load_sdio(void)
{
	int i;
	int err = 0;
	wifi_adapter_info_t *adapter;

	BCM_REFERENCE(i);
	BCM_REFERENCE(adapter);
	/* Sanity check on the module parameters
	 * - Both watchdog and DPC as tasklets are ok
	 * - If both watchdog and DPC are threads, TX must be deferred
	 */
	if (!(dhd_watchdog_prio < 0 && dhd_dpc_prio < 0) &&
		!(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx))
		return -EINVAL;

#if defined(BCMLXSDMMC)
	if (dhd_wifi_platdata == NULL) {
		DHD_ERROR(("DHD wifi platform data is required for Android build\n"));
		return -EINVAL;
	}

	sema_init(&dhd_registration_sem, 0);
	/* power up all adapters */
	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
		bool chip_up = FALSE;
		int retry = POWERUP_MAX_RETRY;
		struct semaphore dhd_chipup_sem;

		adapter = &dhd_wifi_platdata->adapters[i];

		DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
		DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
			adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path));
		DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
			adapter->bus_type, adapter->bus_num, adapter->slot_num));

		do {
			sema_init(&dhd_chipup_sem, 0);
			err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
			if (err) {
				DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n",
					__FUNCTION__, err));
				return err;
			}
			err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
			if (err) {
				/* WL_REG_ON state unknown, Power off forcely */
				wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
				continue;
			} else {
				wifi_platform_bus_enumerate(adapter, TRUE);
				err = 0;
			}

			if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
				dhd_bus_unreg_sdio_notify();
				chip_up = TRUE;
				break;
			}

			DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry));
			dhd_bus_unreg_sdio_notify();
			wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
			wifi_platform_bus_enumerate(adapter, FALSE);
		} while (retry--);

		if (!chip_up) {
			DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name));
			return -ENODEV;
		}

	}

	err = dhd_bus_register();

	if (err) {
		DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
		goto fail;
	}


	/*
	 * Wait till MMC sdio_register_driver callback called and made driver attach.
	 * It's needed to make sync up exit from dhd insmod  and
	 * Kernel MMC sdio device callback registration
	 */
	err = down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
	if (err) {
		DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__));
		dhd_bus_unregister();
		goto fail;
	}

	return err;

fail:
	/* power down all adapters */
	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
		adapter = &dhd_wifi_platdata->adapters[i];
		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
		wifi_platform_bus_enumerate(adapter, FALSE);
	}
#else

	/* x86 bring-up PC needs no power-up operations */
	err = dhd_bus_register();

#endif 

	return err;
}
Esempio n. 12
0
static void smd_tty_notify(void *priv, unsigned event)
{
	struct smd_tty_info *info = priv;
	unsigned long flags;

	switch (event) {
	case SMD_EVENT_DATA:
		spin_lock_irqsave(&info->reset_lock, flags);
		if (!info->is_open) {
			spin_unlock_irqrestore(&info->reset_lock, flags);
			break;
		}
		spin_unlock_irqrestore(&info->reset_lock, flags);
		/* There may be clients (tty framework) that are blocked
		 * waiting for space to write data, so if a possible read
		 * interrupt came in wake anyone waiting and disable the
		 * interrupts
		 */
		if (smd_write_avail(info->ch)) {
			smd_disable_read_intr(info->ch);
			if (info->tty)
				wake_up_interruptible(&info->tty->write_wait);
		}
		tasklet_hi_schedule(&info->tty_tsklt);
		break;

	case SMD_EVENT_OPEN:
		spin_lock_irqsave(&info->reset_lock, flags);
		info->in_reset = 0;
		info->in_reset_updated = 1;
		info->is_open = 1;
		wake_up_interruptible(&info->ch_opened_wait_queue);
		spin_unlock_irqrestore(&info->reset_lock, flags);
		break;

	case SMD_EVENT_CLOSE:
		spin_lock_irqsave(&info->reset_lock, flags);
		info->in_reset = 1;
		info->in_reset_updated = 1;
		info->is_open = 0;
		wake_up_interruptible(&info->ch_opened_wait_queue);
		spin_unlock_irqrestore(&info->reset_lock, flags);
		/* schedule task to send TTY_BREAK */
		tasklet_hi_schedule(&info->tty_tsklt);

		if (info->tty->index == LOOPBACK_IDX)
			schedule_delayed_work(&loopback_work,
					msecs_to_jiffies(1000));
		break;
#ifdef CONFIG_LGE_USES_SMD_DS_TTY
		/*           
                                                        
                                                    
                                                 
                                                       
                                                       
                                                   
                                                       
                                                 
                                     
   */
	case SMD_EVENT_REOPEN_READY:
		/* smd channel is closed completely */
		spin_lock_irqsave(&info->reset_lock, flags);
		info->in_reset = 1;
		info->in_reset_updated = 1;
		info->is_open = 0;
		wake_up_interruptible(&info->ch_opened_wait_queue);
		spin_unlock_irqrestore(&info->reset_lock, flags);
		break;
#endif
	}
}
Esempio n. 13
0
static int s5p_hpd_irq_hdmi(int irq)
{
	u8 flag;
	int ret = IRQ_HANDLED;
	HPDIFPRINTK("\n");

	/* read flag register */
	flag = s5p_hdmi_reg_intc_status();

	if (s5p_hdmi_reg_get_hpd_status())
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_PLUG);
	else
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_UNPLUG);

	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 0);
	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 0);

	/* is this our interrupt? */
	if (!(flag & (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG))) {
		printk(KERN_WARNING "%s() flag is wrong : 0x%x\n",
		       __func__, flag);
		ret = IRQ_NONE;

		goto out;
	}

	if (flag == (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_HI && HPD_LO\n");

		if (last_hpd_state == HPD_HI && s5p_hdmi_reg_get_hpd_status())
			flag = 1 << HDMI_IRQ_HPD_UNPLUG;
		else
			flag = 1 << HDMI_IRQ_HPD_PLUG;
	}

	if (flag & (1 << HDMI_IRQ_HPD_PLUG)) {
		HPDIFPRINTK("HPD_HI\n");

		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 1);
		if (atomic_read(&hpd_struct.state) == HPD_HI)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);

	} else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_LO\n");
#if defined(CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE) &&\
	!defined(CONFIG_SAMSUNG_MHL_9290)
		call_sched_mhl_hpd_handler();
#endif

		s5p_hdcp_stop();

		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 1);
		if (atomic_read(&hpd_struct.state) == HPD_LO)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
		schedule_delayed_work(&ext_ic_control_dwork ,
				msecs_to_jiffies(1000));
#endif

		wake_up_interruptible(&hpd_struct.waitq);
	}

	schedule_work(&hpd_work);

 out:
	return IRQ_HANDLED;
}
Esempio n. 14
0
static int Fb_wait_for_vsync(struct fb_info *info)
{
	unsigned long count;
	__u32 sel = 0;
	int ret;

    for(sel = 0; sel < 2; sel++)
    {
        if(((sel==0) && (g_fbi.fb_mode[info->node] != FB_MODE_SCREEN1))
            || ((sel==1) && (g_fbi.fb_mode[info->node] != FB_MODE_SCREEN0)))
        {
            if(BSP_disp_get_output_type(sel) == DISP_OUTPUT_TYPE_NONE)
            {
                return 0;
            }

        	count = g_fbi.wait_count[sel];
        	ret = wait_event_interruptible_timeout(g_fbi.wait[sel], count != g_fbi.wait_count[sel], msecs_to_jiffies(50));
        	if (ret == 0)
        	{
        	    __inf("timeout\n");
        		return -ETIMEDOUT;
        	}
        }
    }

	return 0;
}
Esempio n. 15
0
static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
				 struct ieee80211_hw *hw,
				 struct ath9k_channel *hchan)
{
	struct ath_hw *ah = priv->ah;
	struct ath_common *common = ath9k_hw_common(ah);
	struct ieee80211_conf *conf = &common->hw->conf;
	bool fastcc;
	struct ieee80211_channel *channel = hw->conf.channel;
	struct ath9k_hw_cal_data *caldata = NULL;
	enum htc_phymode mode;
	__be16 htc_mode;
	u8 cmd_rsp;
	int ret;

	if (priv->op_flags & OP_INVALID)
		return -EIO;

	fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);

	ath9k_htc_ps_wakeup(priv);

	del_timer_sync(&priv->tx.cleanup_timer);
	ath9k_htc_tx_drain(priv);

	WMI_CMD(WMI_DISABLE_INTR_CMDID);
	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
	WMI_CMD(WMI_STOP_RECV_CMDID);

	ath9k_wmi_event_drain(priv);

	ath_dbg(common, ATH_DBG_CONFIG,
		"(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
		priv->ah->curchan->channel,
		channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
		fastcc);

	if (!fastcc)
		caldata = &priv->caldata;

	ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
	if (ret) {
		ath_err(common,
			"Unable to reset channel (%u Mhz) reset status %d\n",
			channel->center_freq, ret);
		goto err;
	}

	ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
			       &priv->curtxpow);

	WMI_CMD(WMI_START_RECV_CMDID);
	if (ret)
		goto err;

	ath9k_host_rx_init(priv);

	mode = ath9k_htc_get_curmode(priv, hchan);
	htc_mode = cpu_to_be16(mode);
	WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
	if (ret)
		goto err;

	WMI_CMD(WMI_ENABLE_INTR_CMDID);
	if (ret)
		goto err;

	htc_start(priv->htc);

	if (!(priv->op_flags & OP_SCANNING) &&
	    !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
		ath9k_htc_vif_reconfig(priv);

	mod_timer(&priv->tx.cleanup_timer,
		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));

err:
	ath9k_htc_ps_restore(priv);
	return ret;
}
Esempio n. 16
0
static int tegra_ehci_hub_control(
	struct usb_hcd	*hcd,
	u16		typeReq,
	u16		wValue,
	u16		wIndex,
	char		*buf,
	u16		wLength
)
{
	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
	struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
	u32 __iomem	*status_reg;
	u32		temp;
	unsigned long	flags;
	int		retval = 0;

	status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];

	spin_lock_irqsave(&ehci->lock, flags);

	/*
	 * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits
	 * that are write on clear, by writing back the register read value, so
	 * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits
	 */
	if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) {
		temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
		ehci_writel(ehci, temp & ~PORT_PE, status_reg);
		goto done;
	}

	else if (typeReq == GetPortStatus) {
		temp = ehci_readl(ehci, status_reg);
		if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
			/* Resume completed, re-enable disconnect detection */
			tegra->port_resuming = 0;
			tegra_usb_phy_postresume(tegra->phy);
		}
	}

	else if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
		temp = ehci_readl(ehci, status_reg);
		if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
			retval = -EPIPE;
			goto done;
		}

		temp &= ~PORT_WKCONN_E;
		temp |= PORT_WKDISC_E | PORT_WKOC_E;
		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);

		/*
		 * If a transaction is in progress, there may be a delay in
		 * suspending the port. Poll until the port is suspended.
		 */
		if (handshake(ehci, status_reg, PORT_SUSPEND,
						PORT_SUSPEND, 5000))
			pr_err("%s: timeout waiting for SUSPEND\n", __func__);

		set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
		goto done;
	}

	/* For USB1 port we need to issue Port Reset twice internally */
	if (tegra->phy->instance == 0 &&
	   (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) {
		spin_unlock_irqrestore(&ehci->lock, flags);
		return tegra_ehci_internal_port_reset(ehci, status_reg);
	}

	/*
	 * Tegra host controller will time the resume operation to clear the bit
	 * when the port control state switches to HS or FS Idle. This behavior
	 * is different from EHCI where the host controller driver is required
	 * to set this bit to a zero after the resume duration is timed in the
	 * driver.
	 */
	else if (typeReq == ClearPortFeature &&
					wValue == USB_PORT_FEAT_SUSPEND) {
		temp = ehci_readl(ehci, status_reg);
		if ((temp & PORT_RESET) || !(temp & PORT_PE)) {
			retval = -EPIPE;
			goto done;
		}

		if (!(temp & PORT_SUSPEND))
			goto done;

		/* Disable disconnect detection during port resume */
		tegra_usb_phy_preresume(tegra->phy);

		ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25);

		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
		/* start resume signalling */
		ehci_writel(ehci, temp | PORT_RESUME, status_reg);

		spin_unlock_irqrestore(&ehci->lock, flags);
		msleep(20);
		spin_lock_irqsave(&ehci->lock, flags);

		/* Poll until the controller clears RESUME and SUSPEND */
		if (handshake(ehci, status_reg, PORT_RESUME, 0, 2000))
			pr_err("%s: timeout waiting for RESUME\n", __func__);
		if (handshake(ehci, status_reg, PORT_SUSPEND, 0, 2000))
			pr_err("%s: timeout waiting for SUSPEND\n", __func__);

		ehci->reset_done[wIndex-1] = 0;

		tegra->port_resuming = 1;
		goto done;
	}

	spin_unlock_irqrestore(&ehci->lock, flags);

	/* Handle the hub control events here */
	return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
done:
	spin_unlock_irqrestore(&ehci->lock, flags);
	return retval;
}
Esempio n. 17
0
void ath9k_htc_ani_work(struct work_struct *work)
{
	struct ath9k_htc_priv *priv =
		container_of(work, struct ath9k_htc_priv, ani_work.work);
	struct ath_hw *ah = priv->ah;
	struct ath_common *common = ath9k_hw_common(ah);
	bool longcal = false;
	bool shortcal = false;
	bool aniflag = false;
	unsigned int timestamp = jiffies_to_msecs(jiffies);
	u32 cal_interval, short_cal_interval;

	short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
		ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;

	/* Only calibrate if awake */
	if (ah->power_mode != ATH9K_PM_AWAKE)
		goto set_timer;

	/* Long calibration runs independently of short calibration. */
	if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
		longcal = true;
		ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
		common->ani.longcal_timer = timestamp;
	}

	/* Short calibration applies only while caldone is false */
	if (!common->ani.caldone) {
		if ((timestamp - common->ani.shortcal_timer) >=
		    short_cal_interval) {
			shortcal = true;
			ath_dbg(common, ATH_DBG_ANI,
				"shortcal @%lu\n", jiffies);
			common->ani.shortcal_timer = timestamp;
			common->ani.resetcal_timer = timestamp;
		}
	} else {
		if ((timestamp - common->ani.resetcal_timer) >=
		    ATH_RESTART_CALINTERVAL) {
			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
			if (common->ani.caldone)
				common->ani.resetcal_timer = timestamp;
		}
	}

	/* Verify whether we must check ANI */
	if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
		aniflag = true;
		common->ani.checkani_timer = timestamp;
	}

	/* Skip all processing if there's nothing to do. */
	if (longcal || shortcal || aniflag) {

		ath9k_htc_ps_wakeup(priv);

		/* Call ANI routine if necessary */
		if (aniflag)
			ath9k_hw_ani_monitor(ah, ah->curchan);

		/* Perform calibration if necessary */
		if (longcal || shortcal)
			common->ani.caldone =
				ath9k_hw_calibrate(ah, ah->curchan,
						   ah->rxchainmask, longcal);

		ath9k_htc_ps_restore(priv);
	}

set_timer:
	/*
	* Set timer interval based on previous results.
	* The interval must be the shortest necessary to satisfy ANI,
	* short calibration and long calibration.
	*/
	cal_interval = ATH_LONG_CALINTERVAL;
	if (priv->ah->config.enable_ani)
		cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
	if (!common->ani.caldone)
		cal_interval = min(cal_interval, (u32)short_cal_interval);

	ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
				     msecs_to_jiffies(cal_interval));
}
int InterfaceAbortIdlemode(PMINI_ADAPTER Adapter, unsigned int Pattern)
{
    int 	status = STATUS_SUCCESS;
    unsigned int value;
    unsigned int chip_id ;
    unsigned long timeout = 0 ,itr = 0;

    int 	lenwritten = 0;
    unsigned char aucAbortPattern[8]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter;

    //Abort Bus suspend if its already suspended
    if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend))
    {
        status = usb_autopm_get_interface(psInterfaceAdapter->interface);
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Bus got wakeup..Aborting Idle mode... status:%d \n",status);

    }

    if((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
            ||
            (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE))
    {
        //write the SW abort pattern.
        BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern);
        status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern));
        if(status)
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
            return status;
        }
    }

    if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
    {
        value = 0x80000000;
        status = wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value));
        if(status)
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed");
            return status;
        }
    }
    else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
    {
        /*
         * Get a Interrupt Out URB and send 8 Bytes Down
         * To be Done in Thread Context.
         * Not using Asynchronous Mechanism.
         */
        status = usb_interrupt_msg (psInterfaceAdapter->udev,
                                    usb_sndintpipe(psInterfaceAdapter->udev,
                                            psInterfaceAdapter->sIntrOut.int_out_endpointAddr),
                                    aucAbortPattern,
                                    8,
                                    &lenwritten,
                                    5000);
        if(status)
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n",status);
            return status;
        }
        else
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten);
        }

        //mdelay(25);

        timeout= jiffies +  msecs_to_jiffies(50) ;
        while( timeout > jiffies )
        {
            itr++ ;
            rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT));
            if(0xbece3200==(chip_id&~(0xF0)))
            {
                chip_id = chip_id&~(0xF0);
            }
            if(chip_id == Adapter->chip_id)
                break;
        }
        if(timeout < jiffies )
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Not able to read chip-id even after 25 msec");
        }
        else
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Number of completed iteration to read chip-id :%lu", itr);
        }

        status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status));
        if(status)
        {
            BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
            return status;
        }
    }
    return status;
}
Esempio n. 19
0
/*
 * mdss_check_dsi_ctrl_status() - Check MDP5 DSI controller status periodically.
 * @work     : dsi controller status data
 * @interval : duration in milliseconds to schedule work queue
 *
 * This function calls check_status API on DSI controller to send the BTA
 * command. If DSI controller fails to acknowledge the BTA command, it sends
 * the PANEL_ALIVE=0 status to HAL layer.
 */
void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval)
{
	struct dsi_status_data *pstatus_data = NULL;
	struct mdss_panel_data *pdata = NULL;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct mdss_overlay_private *mdp5_data = NULL;
	struct mdss_mdp_ctl *ctl = NULL;
	int ret = 0;

	pstatus_data = container_of(to_delayed_work(work),
		struct dsi_status_data, check_status);
	if (!pstatus_data || !(pstatus_data->mfd)) {
		pr_err("%s: mfd not available\n", __func__);
		return;
	}

	pdata = dev_get_platdata(&pstatus_data->mfd->pdev->dev);
	if (!pdata) {
		pr_err("%s: Panel data not available\n", __func__);
		return;
	}

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
							panel_data);
	if (!ctrl_pdata || !ctrl_pdata->check_status) {
		pr_err("%s: DSI ctrl or status_check callback not available\n",
								__func__);
		return;
	}

	mdp5_data = mfd_to_mdp5_data(pstatus_data->mfd);
	ctl = mfd_to_ctl(pstatus_data->mfd);

	if (!ctl) {
		pr_err("%s: Display is off\n", __func__);
		return;
	}

	if (ctl->power_state == MDSS_PANEL_POWER_OFF) {
		schedule_delayed_work(&pstatus_data->check_status,
			msecs_to_jiffies(interval));
		pr_err("%s: ctl not powered on\n", __func__);
		return;
	}

	mutex_lock(&ctrl_pdata->mutex);
	if (ctl->shared_lock)
		mutex_lock(ctl->shared_lock);
	mutex_lock(&mdp5_data->ov_lock);

	if (mdss_panel_is_power_off(pstatus_data->mfd->panel_power_state)) {
		mutex_unlock(&mdp5_data->ov_lock);
		if (ctl->shared_lock)
			mutex_unlock(ctl->shared_lock);
		mutex_unlock(&ctrl_pdata->mutex);
		pr_err("%s: DSI turning off, avoiding panel status check\n",
							__func__);
		return;
	}

	/*
	 * For the command mode panels, we return pan display
	 * IOCTL on vsync interrupt. So, after vsync interrupt comes
	 * and when DMA_P is in progress, if the panel stops responding
	 * and if we trigger BTA before DMA_P finishes, then the DSI
	 * FIFO will not be cleared since the DSI data bus control
	 * doesn't come back to the host after BTA. This may cause the
	 * display reset not to be proper. Hence, wait for DMA_P done
	 * for command mode panels before triggering BTA.
	 */
	if (ctl->wait_pingpong)
		ctl->wait_pingpong(ctl, NULL);

	pr_debug("%s: DSI ctrl wait for ping pong done\n", __func__);

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
	ret = ctrl_pdata->check_status(ctrl_pdata);
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);

	mutex_unlock(&mdp5_data->ov_lock);
	if (ctl->shared_lock)
		mutex_unlock(ctl->shared_lock);
	mutex_unlock(&ctrl_pdata->mutex);

	if ((pstatus_data->mfd->panel_power_state == MDSS_PANEL_POWER_ON)) {
		if (ret > 0) {
			schedule_delayed_work(&pstatus_data->check_status,
				msecs_to_jiffies(interval));
		} else {
			char *envp[2] = {"PANEL_ALIVE=0", NULL};
			pdata->panel_info.panel_dead = true;
			ret = kobject_uevent_env(
				&pstatus_data->mfd->fbi->dev->kobj,
							KOBJ_CHANGE, envp);
			pr_err("%s: Panel has gone bad, sending uevent - %s\n",
							__func__, envp[0]);
		}
	}
}
Esempio n. 20
0
void wl1271_scan_stm(struct wl1271 *wl)
{
	int ret = 0;

	switch (wl->scan.state) {
	case WL1271_SCAN_STATE_IDLE:
		break;

	case WL1271_SCAN_STATE_2GHZ_ACTIVE:
		ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false,
				       wl->conf.tx.basic_rate);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_2GHZ_PASSIVE:
		ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
				       wl->conf.tx.basic_rate);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			if (wl->enable_11a)
				wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
			else
				wl->scan.state = WL1271_SCAN_STATE_DONE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_5GHZ_ACTIVE:
		ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false,
				       wl->conf.tx.basic_rate_5);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_5GHZ_PASSIVE:
		ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true,
				       wl->conf.tx.basic_rate_5);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			wl->scan.state = WL1271_SCAN_STATE_DONE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_DONE:
		wl->scan.failed = false;
		cancel_delayed_work(&wl->scan_complete_work);
		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
					     msecs_to_jiffies(0));
		break;

	default:
		wl1271_error("invalid scan state");
		break;
	}

	if (ret < 0) {
		cancel_delayed_work(&wl->scan_complete_work);
		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
					     msecs_to_jiffies(0));
	}
}
static void run_boost_migration(unsigned int cpu)
{
	int dest_cpu = cpu;
	int src_cpu, ret;
	struct cpu_sync *s = &per_cpu(sync_info, dest_cpu);
	struct cpufreq_policy dest_policy;
	struct cpufreq_policy src_policy;
	unsigned long flags;
	unsigned int req_freq;

	spin_lock_irqsave(&s->lock, flags);
	s->pending = false;
	src_cpu = s->src_cpu;
	spin_unlock_irqrestore(&s->lock, flags);

	ret = cpufreq_get_policy(&src_policy, src_cpu);
	if (ret)
		return;

	ret = cpufreq_get_policy(&dest_policy, dest_cpu);
	if (ret)
		return;

	req_freq = load_based_syncs ?
		(dest_policy.max * s->task_load) / 100 :
						src_policy.cur;

	if (req_freq <= dest_policy.cpuinfo.min_freq) {
			pr_debug("No sync. Sync Freq:%u\n", req_freq);
		return;
	}

	if (sync_threshold)
		req_freq = min(sync_threshold, req_freq);

	cancel_delayed_work_sync(&s->boost_rem);

	s->boost_min = req_freq;

	/* Force policy re-evaluation to trigger adjust notifier. */
	get_online_cpus();
	if (cpu_online(src_cpu))
		/*
		 * Send an unchanged policy update to the source
		 * CPU. Even though the policy isn't changed from
		 * its existing boosted or non-boosted state
		 * notifying the source CPU will let the governor
		 * know a boost happened on another CPU and that it
		 * should re-evaluate the frequency at the next timer
		 * event without interference from a min sample time.
		 */
		cpufreq_update_policy(src_cpu);
	if (cpu_online(dest_cpu)) {
		cpufreq_update_policy(dest_cpu);
		queue_delayed_work_on(0, cpu_boost_wq,
			&s->boost_rem, msecs_to_jiffies(boost_ms));
	} else {
		s->boost_min = 0;
	}
	put_online_cpus();
}
Esempio n. 22
0
/*
 * returns,
 * plus: processed without an error
 * zero: unprocessed
 */
static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
			 struct au_opts *opts)
{
	int err;
	struct au_sbinfo *sbinfo;

	SiMustWriteLock(sb);

	err = 1; /* handled */
	sbinfo = au_sbi(sb);
	switch (opt->type) {
	case Opt_udba:
		sbinfo->si_mntflags &= ~AuOptMask_UDBA;
		sbinfo->si_mntflags |= opt->udba;
		opts->given_udba |= opt->udba;
		break;

	case Opt_plink:
		au_opt_set(sbinfo->si_mntflags, PLINK);
		break;
	case Opt_noplink:
		if (au_opt_test(sbinfo->si_mntflags, PLINK))
			au_plink_put(sb, /*verbose*/1);
		au_opt_clr(sbinfo->si_mntflags, PLINK);
		break;
	case Opt_list_plink:
		if (au_opt_test(sbinfo->si_mntflags, PLINK))
			au_plink_list(sb);
		break;

	case Opt_dio:
		au_opt_set(sbinfo->si_mntflags, DIO);
		au_fset_opts(opts->flags, REFRESH_DYAOP);
		break;
	case Opt_nodio:
		au_opt_clr(sbinfo->si_mntflags, DIO);
		au_fset_opts(opts->flags, REFRESH_DYAOP);
		break;

	case Opt_fhsm_sec:
		au_fhsm_set(sbinfo, opt->fhsm_second);
		break;

	case Opt_diropq_a:
		au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ);
		break;
	case Opt_diropq_w:
		au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ);
		break;

	case Opt_warn_perm:
		au_opt_set(sbinfo->si_mntflags, WARN_PERM);
		break;
	case Opt_nowarn_perm:
		au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
		break;

	case Opt_refrof:
		au_opt_set(sbinfo->si_mntflags, REFROF);
		break;
	case Opt_norefrof:
		au_opt_clr(sbinfo->si_mntflags, REFROF);
		break;

	case Opt_verbose:
		au_opt_set(sbinfo->si_mntflags, VERBOSE);
		break;
	case Opt_noverbose:
		au_opt_clr(sbinfo->si_mntflags, VERBOSE);
		break;

	case Opt_sum:
		au_opt_set(sbinfo->si_mntflags, SUM);
		break;
	case Opt_wsum:
		au_opt_clr(sbinfo->si_mntflags, SUM);
		au_opt_set(sbinfo->si_mntflags, SUM_W);
	case Opt_nosum:
		au_opt_clr(sbinfo->si_mntflags, SUM);
		au_opt_clr(sbinfo->si_mntflags, SUM_W);
		break;

	case Opt_wbr_create:
		err = au_opt_wbr_create(sb, &opt->wbr_create);
		break;
	case Opt_wbr_copyup:
		sbinfo->si_wbr_copyup = opt->wbr_copyup;
		sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup;
		break;

	case Opt_dirwh:
		sbinfo->si_dirwh = opt->dirwh;
		break;

	case Opt_rdcache:
		sbinfo->si_rdcache
			= msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC);
		break;
	case Opt_rdblk:
		sbinfo->si_rdblk = opt->rdblk;
		break;
	case Opt_rdblk_def:
		sbinfo->si_rdblk = AUFS_RDBLK_DEF;
		break;
	case Opt_rdhash:
		sbinfo->si_rdhash = opt->rdhash;
		break;
	case Opt_rdhash_def:
		sbinfo->si_rdhash = AUFS_RDHASH_DEF;
		break;

	case Opt_shwh:
		au_opt_set(sbinfo->si_mntflags, SHWH);
		break;
	case Opt_noshwh:
		au_opt_clr(sbinfo->si_mntflags, SHWH);
		break;

	case Opt_dirperm1:
		au_opt_set(sbinfo->si_mntflags, DIRPERM1);
		break;
	case Opt_nodirperm1:
		au_opt_clr(sbinfo->si_mntflags, DIRPERM1);
		break;

	case Opt_trunc_xino:
		au_opt_set(sbinfo->si_mntflags, TRUNC_XINO);
		break;
	case Opt_notrunc_xino:
		au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO);
		break;

	case Opt_trunc_xino_path:
	case Opt_itrunc_xino:
		err = au_xino_trunc(sb, opt->xino_itrunc.bindex);
		if (!err)
			err = 1;
		break;

	case Opt_trunc_xib:
		au_fset_opts(opts->flags, TRUNC_XIB);
		break;
	case Opt_notrunc_xib:
		au_fclr_opts(opts->flags, TRUNC_XIB);
		break;

	case Opt_acl:
		sb->s_flags |= MS_POSIXACL;
		break;
	case Opt_noacl:
		sb->s_flags &= ~MS_POSIXACL;
		break;

	default:
		err = 0;
		break;
	}

	return err;
}
Esempio n. 23
0
static void usb_tx_work(struct work_struct *work)
{
	int ret = 0;
	struct link_device *ld =
		container_of(work, struct link_device, tx_delayed_work.work);
	struct usb_link_device *usb_ld = to_usb_link_device(ld);
	struct sk_buff *skb;
	struct link_pm_data *pm_data = usb_ld->link_pm_data;

	if (!usb_ld->usbdev) {
		mif_info("usbdev is invalid\n");
		return;
	}

	pm_data->tx_cnt++;

	while (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen) {
		/* request and check usb runtime pm first */
		ret = link_pm_runtime_get_active(pm_data);
		if (ret < 0) {
			if (ret == -ENODEV) {
				mif_err("link not avail, retry reconnect.\n");
				goto exit;
			}
			goto retry_tx_work;
		}

		/* If AP try to tx when interface disconnect->reconnect probe,
		 * usbdev was created but one of interface channel device are
		 * probing, _usb_tx_work return to -ENOENT then runtime usage
		 * count allways positive and never enter to L2
		 */
		if (!usb_ld->if_usb_connected) {
			mif_info("link is available, but if  was not readey\n");
			goto retry_tx_work;
		}
		pm_runtime_get_sync(&usb_ld->usbdev->dev);

		ret = 0;
		/* send skb from fmt_txq and raw_txq,*/
		/* one by one for fair flow control */
		skb = skb_dequeue(&ld->sk_fmt_tx_q);
		if (skb)
			ret = _usb_tx_work(skb);

		if (ret) {
			mif_err("usb_tx_urb_with_skb for fmt_q %d\n", ret);
			skb_queue_head(&ld->sk_fmt_tx_q, skb);

			if (ret == -ENODEV || ret == -ENOENT)
				goto exit;

			/* tx fail and usbdev alived, retry tx work */
			pm_runtime_put(&usb_ld->usbdev->dev);
			goto retry_tx_work;
		}

		skb = skb_dequeue(&ld->sk_raw_tx_q);
		if (skb)
			ret = _usb_tx_work(skb);

		if (ret) {
			mif_err("usb_tx_urb_with_skb for raw_q %d\n", ret);
			skb_queue_head(&ld->sk_raw_tx_q, skb);

			if (ret == -ENODEV || ret == -ENOENT)
				goto exit;

			pm_runtime_put(&usb_ld->usbdev->dev);
			goto retry_tx_work;
		}

		pm_runtime_put(&usb_ld->usbdev->dev);
	}
	wake_unlock(&pm_data->tx_async_wake);
exit:
	return;

retry_tx_work:
	queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work,
		msecs_to_jiffies(20));
	return;
}
Esempio n. 24
0
static int aml_asoc_init(struct snd_soc_pcm_runtime *rtd)
{
    struct snd_soc_card *card = rtd->card;
    struct snd_soc_codec *codec = rtd->codec;
    struct snd_soc_dapm_context *dapm = &codec->dapm;
    struct aml_audio_private_data * p_aml_audio;
    int ret = 0;
    int hp_paraments[5];
    
    printk(KERN_DEBUG "enter %s \n", __func__);
    p_aml_audio = snd_soc_card_get_drvdata(card);
    
    ret = snd_soc_add_card_controls(codec->card, aml_m8_controls,
                ARRAY_SIZE(aml_m8_controls));
    if (ret)
       return ret;

    /* Add specific widgets */
    snd_soc_dapm_new_controls(dapm, aml_asoc_dapm_widgets,
                  ARRAY_SIZE(aml_asoc_dapm_widgets));
    if (ret)
        return ret;
    
#if HP_DET

    p_aml_audio->sdev.name = "h2w";//for report headphone to android
    ret = switch_dev_register(&p_aml_audio->sdev);
    if (ret < 0){
        printk(KERN_ERR "ASoC: register hp switch dev failed\n");
        return ret;
    }

    p_aml_audio->mic_sdev.name = "mic_dev";//for micphone detect
    ret = switch_dev_register(&p_aml_audio->mic_sdev);
    if (ret < 0){
        printk(KERN_ERR "ASoC: register mic switch dev failed\n");
        return ret;
    }

    ret = snd_soc_jack_new(codec, "hp switch", SND_JACK_HEADPHONE, &p_aml_audio->jack);
    if (ret < 0) {
        printk(KERN_WARNING "Failed to alloc resource for hp switch\n");
    } else {
        ret = snd_soc_jack_add_pins(&p_aml_audio->jack, ARRAY_SIZE(jack_pins), jack_pins);
        if (ret < 0) {
            printk(KERN_WARNING "Failed to setup hp pins\n");
        }
    }

    p_aml_audio->mic_det = of_property_read_bool(card->dev->of_node,"mic_det");

    printk("entern %s : mic_det=%d \n",__func__,p_aml_audio->mic_det);
    ret = of_property_read_u32_array(card->dev->of_node, "hp_paraments", &hp_paraments[0], 5);
    if(ret){
        printk("falied to get hp detect paraments from dts file\n");
    }else{
        p_aml_audio->hp_val_h  = hp_paraments[0];  // hp adc value higher base, hp unplugged
        p_aml_audio->hp_val_l  = hp_paraments[1];  // hp adc value low base, 3 section hp plugged.
        p_aml_audio->mic_val   = hp_paraments[2];  // hp adc value mic detect value.
        p_aml_audio->hp_detal  = hp_paraments[3];  // hp adc value test toerance
        p_aml_audio->hp_adc_ch = hp_paraments[4];  // get adc value from which adc port for hp detect

        printk("hp detect paraments: h=%d,l=%d,mic=%d,det=%d,ch=%d \n",p_aml_audio->hp_val_h,p_aml_audio->hp_val_l,
            p_aml_audio->mic_val,p_aml_audio->hp_detal,p_aml_audio->hp_adc_ch);
    }
    init_timer(&p_aml_audio->timer);
    p_aml_audio->timer.function = aml_asoc_timer_func;
    p_aml_audio->timer.data = (unsigned long)p_aml_audio;
    p_aml_audio->data= (void*)card;

    INIT_WORK(&p_aml_audio->work, aml_asoc_work_func);
    mutex_init(&p_aml_audio->lock);

    mutex_lock(&p_aml_audio->lock);
    if (!p_aml_audio->timer_en) {
        aml_audio_start_timer(p_aml_audio, msecs_to_jiffies(100));
    }
    mutex_unlock(&p_aml_audio->lock);

#endif

    return 0;
}
Esempio n. 25
0
static struct rdma_cm_id *
rpcrdma_create_id(struct rpcrdma_xprt *xprt,
			struct rpcrdma_ia *ia, struct sockaddr *addr)
{
	struct rdma_cm_id *id;
	int rc;

	init_completion(&ia->ri_done);

	id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP, IB_QPT_RC);
	if (IS_ERR(id)) {
		rc = PTR_ERR(id);
		dprintk("RPC:       %s: rdma_create_id() failed %i\n",
			__func__, rc);
		return id;
	}

	ia->ri_async_rc = -ETIMEDOUT;
	rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT);
	if (rc) {
		dprintk("RPC:       %s: rdma_resolve_addr() failed %i\n",
			__func__, rc);
		goto out;
	}
	wait_for_completion_interruptible_timeout(&ia->ri_done,
				msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);

	/* FIXME:
	 * Until xprtrdma supports DEVICE_REMOVAL, the provider must
	 * be pinned while there are active NFS/RDMA mounts to prevent
	 * hangs and crashes at umount time.
	 */
	if (!ia->ri_async_rc && !try_module_get(id->device->owner)) {
		dprintk("RPC:       %s: Failed to get device module\n",
			__func__);
		ia->ri_async_rc = -ENODEV;
	}
	rc = ia->ri_async_rc;
	if (rc)
		goto out;

	ia->ri_async_rc = -ETIMEDOUT;
	rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
	if (rc) {
		dprintk("RPC:       %s: rdma_resolve_route() failed %i\n",
			__func__, rc);
		goto put;
	}
	wait_for_completion_interruptible_timeout(&ia->ri_done,
				msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
	rc = ia->ri_async_rc;
	if (rc)
		goto put;

	return id;
put:
	module_put(id->device->owner);
out:
	rdma_destroy_id(id);
	return ERR_PTR(rc);
}
Esempio n. 26
0
/**
 * Interrupt function is called whenever power button key is pressed
 * or released.
 */
static void retubutton_irq(unsigned long arg)
{
	retu_ack_irq(RETU_INT_PWR);
	mod_timer(&pwrbtn_timer, jiffies + msecs_to_jiffies(PWRBTN_DELAY));
}
Esempio n. 27
0
static void iwl3945_bg_rate_scale_flush(unsigned long data)
{
	struct iwl3945_rs_sta *rs_sta = (void *)data;
	struct iwl_priv *priv __maybe_unused = rs_sta->priv;
	int unflushed = 0;
	unsigned long flags;
	u32 packet_count, duration, pps;

	IWL_DEBUG_RATE(priv, "enter\n");

	unflushed = iwl3945_rate_scale_flush_windows(rs_sta);

	spin_lock_irqsave(&rs_sta->lock, flags);

	/* Number of packets Rx'd since last time this timer ran */
	packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1;

	rs_sta->last_tx_packets = rs_sta->tx_packets + 1;

	if (unflushed) {
		duration =
		    jiffies_to_msecs(jiffies - rs_sta->last_partial_flush);

		IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n",
			       packet_count, duration);

		/* Determine packets per second */
		if (duration)
			pps = (packet_count * 1000) / duration;
		else
			pps = 0;

		if (pps) {
			duration = (IWL_AVERAGE_PACKETS * 1000) / pps;
			if (duration < IWL_RATE_FLUSH_MIN)
				duration = IWL_RATE_FLUSH_MIN;
			else if (duration > IWL_RATE_FLUSH_MAX)
				duration = IWL_RATE_FLUSH_MAX;
		} else
			duration = IWL_RATE_FLUSH_MAX;

		rs_sta->flush_time = msecs_to_jiffies(duration);

		IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n",
			       duration, packet_count);

		mod_timer(&rs_sta->rate_scale_flush, jiffies +
			  rs_sta->flush_time);

		rs_sta->last_partial_flush = jiffies;
	} else {
		rs_sta->flush_time = IWL_RATE_FLUSH;
		rs_sta->flush_pending = 0;
	}
	/* If there weren't any unflushed entries, we don't schedule the timer
	 * to run again */

	rs_sta->last_flush = jiffies;

	spin_unlock_irqrestore(&rs_sta->lock, flags);

	IWL_DEBUG_RATE(priv, "leave\n");
}
Esempio n. 28
0
void s5p_mfc_clock_off(struct s5p_mfc_dev *dev)
{
	int state, val;
	unsigned long timeout, flags;
	int ret = 0;

	dev->pm.clock_off_steps = 1;

	MFC_TRACE_DEV("++ clock_off\n");
	if (IS_MFCV6(dev)) {
		spin_lock_irqsave(&dev->pm.clklock, flags);
		dev->pm.clock_off_steps = 2;
		if ((atomic_dec_return(&dev->clk_ref) == 0) &&
				FW_HAS_BUS_RESET(dev)) {
			s5p_mfc_write_reg(dev, 0x1, S5P_FIMV_MFC_BUS_RESET_CTRL);

			timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
			/* Check bus status */
			do {
				if (time_after(jiffies, timeout)) {
					mfc_err_dev("Timeout while resetting MFC.\n");
					break;
				}
				val = s5p_mfc_read_reg(dev,
						S5P_FIMV_MFC_BUS_RESET_CTRL);
			} while ((val & 0x2) == 0);
		dev->pm.clock_off_steps = 3;
		}
		spin_unlock_irqrestore(&dev->pm.clklock, flags);
	} else {
		atomic_dec_return(&dev->clk_ref);
	}

	dev->pm.clock_off_steps = 4;
	state = atomic_read(&dev->clk_ref);
	if (state < 0) {
		mfc_err_dev("Clock state is wrong(%d)\n", state);
		atomic_set(&dev->clk_ref, 0);
		dev->pm.clock_off_steps = 5;
	} else {
		if (dev->curr_ctx_drm && dev->is_support_smc) {
			mfc_debug(3, "Begin: disable protection\n");
			spin_lock_irqsave(&dev->pm.clklock, flags);
			dev->pm.clock_off_steps = 6;
			ret = exynos_smc(SMC_PROTECTION_SET, 0,
					dev->id, SMC_PROTECTION_DISABLE);
			if (!ret) {
				printk("Protection Disable failed! ret(%u)\n", ret);
				spin_unlock_irqrestore(&dev->pm.clklock, flags);
				clk_disable(dev->pm.clock);
				return;
			}
			mfc_debug(3, "End: disable protection\n");
			dev->pm.clock_off_steps = 7;
			spin_unlock_irqrestore(&dev->pm.clklock, flags);
		} else {
			dev->pm.clock_off_steps = 8;
			s5p_mfc_mem_suspend(dev->alloc_ctx[0]);
			dev->pm.clock_off_steps = 9;
		}
		dev->pm.clock_off_steps = 10;
		clk_disable(dev->pm.clock);
	}
	mfc_debug(2, "- %d\n", state);
	MFC_TRACE_DEV("-- clock_off: ref state(%d)\n", state);
	dev->pm.clock_off_steps = 11;
}
Esempio n. 29
0
void wl1271_scan_stm(struct wl1271 *wl)
{
	int ret = 0;
	enum ieee80211_band band;
	u32 rate;

	switch (wl->scan.state) {
	case WL1271_SCAN_STATE_IDLE:
		break;

	case WL1271_SCAN_STATE_2GHZ_ACTIVE:
		band = IEEE80211_BAND_2GHZ;
		if (wl->scan.req->no_cck)
			rate = wl1271_tx_min_rate_get(wl, CONF_TX_RATE_MASK_BASIC_P2P);
		else
			rate = wl1271_tx_min_rate_get(wl, CONF_TX_RATE_MASK_BASIC);
		ret = wl1271_scan_send(wl, band, false, rate);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_2GHZ_PASSIVE:
		band = IEEE80211_BAND_2GHZ;
		if (wl->scan.req->no_cck)
			rate = wl1271_tx_min_rate_get(wl, CONF_TX_RATE_MASK_BASIC_P2P);
		else
			rate = wl1271_tx_min_rate_get(wl, CONF_TX_RATE_MASK_BASIC);
		ret = wl1271_scan_send(wl, band, true, rate);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			if (wl->enable_11a)
				wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
			else
				wl->scan.state = WL1271_SCAN_STATE_DONE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_5GHZ_ACTIVE:
		band = IEEE80211_BAND_5GHZ;
		rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
		ret = wl1271_scan_send(wl, band, false, rate);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_5GHZ_PASSIVE:
		band = IEEE80211_BAND_5GHZ;
		rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
		ret = wl1271_scan_send(wl, band, true, rate);
		if (ret == WL1271_NOTHING_TO_SCAN) {
			wl->scan.state = WL1271_SCAN_STATE_DONE;
			wl1271_scan_stm(wl);
		}

		break;

	case WL1271_SCAN_STATE_DONE:
		wl->scan.failed = false;
		cancel_delayed_work(&wl->scan_complete_work);
		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
					     msecs_to_jiffies(0));
		break;

	default:
		wl1271_error("invalid scan state");
		break;
	}

	if (ret < 0) {
		cancel_delayed_work(&wl->scan_complete_work);
		ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
					     msecs_to_jiffies(0));
	}
}
Esempio n. 30
0
/* Called from HCI core to initialize the device */
static int ti_st_open(struct hci_dev *hdev)
{
	unsigned long timeleft;
	struct ti_st *hst;
	int err, i;

	BT_DBG("%s %p", hdev->name, hdev);

	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	/* provide contexts for callbacks from ST */
	hst = hdev->driver_data;

	for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
		ti_st_proto[i].priv_data = hst;
		ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE;
		ti_st_proto[i].recv = st_receive;
		ti_st_proto[i].reg_complete_cb = st_reg_completion_cb;

		/* Prepare wait-for-completion handler */
		init_completion(&hst->wait_reg_completion);
		/* Reset ST registration callback status flag,
		 * this value will be updated in
		 * st_reg_completion_cb()
		 * function whenever it called from ST driver.
		 */
		hst->reg_status = -EINPROGRESS;

		err = st_register(&ti_st_proto[i]);
		if (!err)
			goto done;

		if (err != -EINPROGRESS) {
			clear_bit(HCI_RUNNING, &hdev->flags);
			BT_ERR("st_register failed %d", err);
			return err;
		}

		/* ST is busy with either protocol
		 * registration or firmware download.
		 */
		BT_DBG("waiting for registration "
				"completion signal from ST");
		timeleft = wait_for_completion_timeout
			(&hst->wait_reg_completion,
			 msecs_to_jiffies(BT_REGISTER_TIMEOUT));
		if (!timeleft) {
			clear_bit(HCI_RUNNING, &hdev->flags);
			BT_ERR("Timeout(%d sec),didn't get reg "
					"completion signal from ST",
					BT_REGISTER_TIMEOUT / 1000);
			return -ETIMEDOUT;
		}

		/* Is ST registration callback
		 * called with ERROR status? */
		if (hst->reg_status != 0) {
			clear_bit(HCI_RUNNING, &hdev->flags);
			BT_ERR("ST registration completed with invalid "
					"status %d", hst->reg_status);
			return -EAGAIN;
		}

done:
		hst->st_write = ti_st_proto[i].write;
		if (!hst->st_write) {
			BT_ERR("undefined ST write function");
			clear_bit(HCI_RUNNING, &hdev->flags);
			for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
				/* Undo registration with ST */
				err = st_unregister(&ti_st_proto[i]);
				if (err)
					BT_ERR("st_unregister() failed with "
							"error %d", err);
				hst->st_write = NULL;
			}
			return -EIO;
		}
	}
	return 0;
}