static void handle_only_power_key(unsigned int code, int value)
{
	struct gpio_input_state *ds = gb_ddata;

	if (code == KEY_POWER && ds->disable_reset_flag != 0) {
		if (value) {
			queue_delayed_work(ds->disable_reset_wq,
					&ds->clear_hw_reset_work,
					msecs_to_jiffies(0));
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
			clear_kpdpwr_s2_rst_flag = 1;
			KEY_LOGD("%s: Enable kpdpwr s2 reset clear up [%d]\n",
						__func__, clear_kpdpwr_s2_rst_flag);
			hrtimer_start(&clr_kpd_reset_timer,
				ktime_set(0, KPDPWR_CLR_RESET_TIMER), HRTIMER_MODE_REL);
#endif 
		} else {
			__cancel_delayed_work(&ds->clear_hw_reset_work);
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
			clear_kpdpwr_s2_rst_flag = 0;
			KEY_LOGD("%s: Disable kpdpwr s2 reset clear up [%d]\n",
						__func__, clear_kpdpwr_s2_rst_flag);
			if (hrtimer_is_queued(&clr_kpd_reset_timer))
				hrtimer_cancel(&clr_kpd_reset_timer);
			if (hrtimer_is_queued(&enable_kpd_s2_timer))
				hrtimer_cancel(&enable_kpd_s2_timer);
#endif 
		}
	}
}
static void handle_transition_according_to_power_key(int value)
{
	struct gpio_input_state *ds = gb_ddata;

#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
	clear_kpdpwr_s2_rst_flag = 0;
	if (hrtimer_is_queued(&clr_kpd_reset_timer))
		hrtimer_cancel(&clr_kpd_reset_timer);
	if (hrtimer_is_queued(&enable_kpd_s2_timer))
		hrtimer_cancel(&enable_kpd_s2_timer);
#endif 

	if (ds->disable_reset_flag == 0 && value) {
		
#ifdef CONFIG_POWER_VOLUP_RESET
		wake_lock_timeout(&key_reset_clr_wake_lock, msecs_to_jiffies(1000));
		if (!schedule_delayed_work(&power_key_check_reset_work, msecs_to_jiffies(0)))
#else
		wake_lock_timeout(&key_reset_clr_wake_lock, PWRKEYCHKRST_WAKELOCK_TIMEOUT);
		if (!schedule_delayed_work(&power_key_check_reset_work, PWRKEYCHKRST_DELAY))
#endif
			KEY_LOGI("[PWR] the reset work in already in the queue\n");
	} else if (ds->disable_reset_flag != 0) {
		
		handle_only_power_key(KEY_POWER, value);
	}
}
/*
 * remove hrtimer, called with base lock held
 */
static inline int
remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
{
	if (hrtimer_is_queued(timer)) {
		unsigned long state;
		int reprogram;

		/*
		 * Remove the timer and force reprogramming when high
		 * resolution mode is active and the timer is on the current
		 * CPU. If we remove a timer on another CPU, reprogramming is
		 * skipped. The interrupt event on this CPU is fired and
		 * reprogramming happens in the interrupt handler. This is a
		 * rare case and less expensive than a smp call.
		 */
		debug_deactivate(timer);
		timer_stats_hrtimer_clear_start_info(timer);
		reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases);
		/*
		 * We must preserve the CALLBACK state flag here,
		 * otherwise we could move the timer base in
		 * switch_hrtimer_base.
		 */
		state = timer->state & HRTIMER_STATE_CALLBACK;
		__remove_hrtimer(timer, base, state, reprogram);
		return 1;
	}
	return 0;
}
Example #4
0
/**
 * hrtimer_forward - forward the timer expiry
 * @timer:	hrtimer to forward
 * @now:	forward past this time
 * @interval:	the interval to forward
 *
 * Forward the timer expiry so it will expire in the future.
 * Returns the number of overruns.
 */
u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
{
	u64 orun = 1;
	ktime_t delta;

	WARN_ON(hrtimer_is_queued(timer));

	delta = ktime_sub(now, hrtimer_get_expires(timer));

	if (delta.tv64 < 0)
		return 0;

	if (interval.tv64 < timer->base->resolution.tv64)
		interval.tv64 = timer->base->resolution.tv64;

	if (unlikely(delta.tv64 >= interval.tv64)) {
		s64 incr = ktime_to_ns(interval);

		orun = ktime_divns(delta, incr);
		hrtimer_add_expires_ns(timer, incr * orun);
		if (hrtimer_get_expires_tv64(timer) > now.tv64)
			return orun;
		/*
		 * This (and the ktime_add() below) is the
		 * correction for exact:
		 */
		orun++;
	}
	hrtimer_add_expires(timer, interval);

	return orun;
}
Example #5
0
/*
 * remove hrtimer, called with base lock held
 */
static inline int
remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base, bool restart)
{
	if (hrtimer_is_queued(timer)) {
		u8 state = timer->state;
		int reprogram;

		/*
		 * Remove the timer and force reprogramming when high
		 * resolution mode is active and the timer is on the current
		 * CPU. If we remove a timer on another CPU, reprogramming is
		 * skipped. The interrupt event on this CPU is fired and
		 * reprogramming happens in the interrupt handler. This is a
		 * rare case and less expensive than a smp call.
		 */
		debug_deactivate(timer);
		timer_stats_hrtimer_clear_start_info(timer);
		reprogram = base->cpu_base == this_cpu_ptr(&hrtimer_bases);

		if (!restart)
			state = HRTIMER_STATE_INACTIVE;

		__remove_hrtimer(timer, base, state, reprogram);
		return 1;
	}
	return 0;
}
Example #6
0
static int hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
    struct hip04_priv *priv = netdev_priv(ndev);
    struct net_device_stats *stats = &ndev->stats;
    unsigned int tx_head = priv->tx_head, count;
    struct tx_desc *desc = &priv->tx_desc[tx_head];
    dma_addr_t phys;

    smp_rmb();
    count = tx_count(tx_head, ACCESS_ONCE(priv->tx_tail));
    if (count == (TX_DESC_NUM - 1)) {
        netif_stop_queue(ndev);
        return NETDEV_TX_BUSY;
    }

    phys = dma_map_single(&ndev->dev, skb->data, skb->len, DMA_TO_DEVICE);
    if (dma_mapping_error(&ndev->dev, phys)) {
        dev_kfree_skb(skb);
        return NETDEV_TX_OK;
    }

    priv->tx_skb[tx_head] = skb;
    priv->tx_phys[tx_head] = phys;
    desc->send_addr = cpu_to_be32(phys);
    desc->send_size = cpu_to_be32(skb->len);
    desc->cfg = cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV);
    phys = priv->tx_desc_dma + tx_head * sizeof(struct tx_desc);
    desc->wb_addr = cpu_to_be32(phys);
    skb_tx_timestamp(skb);

    hip04_set_xmit_desc(priv, phys);
    priv->tx_head = TX_NEXT(tx_head);
    count++;
    netdev_sent_queue(ndev, skb->len);

    stats->tx_bytes += skb->len;
    stats->tx_packets++;

    /* Ensure tx_head update visible to tx reclaim */
    smp_wmb();

    /* queue is getting full, better start cleaning up now */
    if (count >= priv->tx_coalesce_frames) {
        if (napi_schedule_prep(&priv->napi)) {
            /* disable rx interrupt and timer */
            priv->reg_inten &= ~(RCV_INT);
            writel_relaxed(DEF_INT_MASK & ~RCV_INT,
                           priv->base + PPE_INTEN);
            hrtimer_cancel(&priv->tx_coalesce_timer);
            __napi_schedule(&priv->napi);
        }
    } else if (!hrtimer_is_queued(&priv->tx_coalesce_timer)) {
        /* cleanup not pending yet, start a new timer */
        hip04_start_tx_timer(priv);
    }

    return NETDEV_TX_OK;
}
Example #7
0
static inline int
remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
{
    if (hrtimer_is_queued(timer)) {
        unsigned long state;
        int reprogram;

        debug_deactivate(timer);
        timer_stats_hrtimer_clear_start_info(timer);
        reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases);
        state = timer->state & HRTIMER_STATE_CALLBACK;
        __remove_hrtimer(timer, base, state, reprogram);
        return 1;
    }
    return 0;
}
Example #8
0
static inline void start_tx_timer(struct mem_link_device *mld,
				  struct hrtimer *timer)
{
	struct link_device *ld = &mld->link_dev;
	struct modem_ctl *mc = ld->mc;
	unsigned long flags;

	spin_lock_irqsave(&mc->lock, flags);

	if (unlikely(cp_offline(mc)))
		goto exit;

	if (!hrtimer_is_queued(timer)) {
		ktime_t ktime = ktime_set(0, tx_timer_ns);
		hrtimer_start(timer, ktime, HRTIMER_MODE_REL);
	}

exit:
	spin_unlock_irqrestore(&mc->lock, flags);
}
static void handle_power_key_reset(unsigned int code, int value)
{
#ifdef CONFIG_POWER_VOLUP_RESET
	uint8_t i = 0, read_val = 0;
	struct gpio_event_input_info *aa = gis;
	if (code == KEY_POWER || code == KEY_VOLUMEUP) {
		if (!value && code == KEY_VOLUMEUP) {
			KEY_LOGI("[VUP] start count for power key led off\n");
			schedule_delayed_work(&power_key_led_off_work, PWRKEYLEDOFF_DELAY);
		}
		for (i = 0; (i < aa->keymap_size && code != KEY_POWER); i++) {
			if (aa->keymap[i].code == KEY_POWER) {
				read_val = gpio_get_value(aa->keymap[i].gpio);
				KEY_LOGI("Idx[%d] GPIO_%d:PWR is %s\n",
						i, aa->keymap[i].gpio,
						(read_val ? "NOT pressed" : "PRESSED" ));
				if (read_val) {
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
					clear_kpdpwr_s2_rst_flag = 0;
					KEY_LOGD("%s: Disable kpdpwr s2 reset clear up [%d]\n",
								__func__, clear_kpdpwr_s2_rst_flag);
#endif 
					return;
				} else {
					KEY_LOGI("[PWR+VUP] start count for power key led on\n");
					schedule_delayed_work(&power_key_led_on_work, PWRKEYLEDON_DELAY);
					power_key_led_requested = 1;
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
					clear_kpdpwr_s2_rst_flag = 1;
					KEY_LOGD("%s: Enable kpdpwr s2 reset clear up [%d]\n",
								__func__, clear_kpdpwr_s2_rst_flag);
#endif 
					break;
				}
			}
		}
		for (i = aa->keymap_size; (i > 0  && code != KEY_VOLUMEUP); i--) {
			if (aa->keymap[i-1].code == KEY_VOLUMEUP) {
				read_val = gpio_get_value(aa->keymap[i-1].gpio);
				KEY_LOGI("Idx[%d] GPIO_%d:VOL_UP is %s\n",
						i-1, aa->keymap[i-1].gpio,
						(read_val ? "NOT pressed" : "PRESSED" ));
				if (read_val) {
					goto KEY_PWR;
				} else {
					KEY_LOGI("[VUP+PWR] start count for power key led on\n");
					schedule_delayed_work(&power_key_led_on_work, PWRKEYLEDON_DELAY);
					power_key_led_requested = 1;
					break;
				}
			}
		}
KEY_PWR:
#else
	if (code == KEY_POWER) {
#endif
		if (value) {
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
			clear_kpdpwr_s2_rst_flag = 1;
			KEY_LOGD("%s: Enable kpdpwr s2 reset clear up [%d]\n",
						__func__, clear_kpdpwr_s2_rst_flag);
			hrtimer_start(&clr_kpd_reset_timer,
				ktime_set(0, KPDPWR_CLR_RESET_TIMER), HRTIMER_MODE_REL);
#endif 
#ifdef CONFIG_POWER_VOLUP_RESET
			wake_lock_timeout(&key_reset_clr_wake_lock, msecs_to_jiffies(2000));
			KEY_LOGI("[PWR] start count for power key check reset\n");
			if (!schedule_delayed_work(&power_key_check_reset_work, msecs_to_jiffies(1000)))
#else
			wake_lock_timeout(&key_reset_clr_wake_lock, PWRKEYCHKRST_WAKELOCK_TIMEOUT);
			KEY_LOGI("[PWR] start count for power key check reset\n");
			if (!schedule_delayed_work(&power_key_check_reset_work, PWRKEYCHKRST_DELAY))
#endif
				KEY_LOGI("[PWR] the reset work in already in the queue\n");
		} else {
			KEY_LOGI("[PWR] start count for power key clear check\n");

			if (!schedule_delayed_work(&power_key_clr_check_work, PWRKEYCLRCHK_DELAY))
				KEY_LOGI("[PWR] the clear work in already in the queue\n");
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
			clear_kpdpwr_s2_rst_flag = 0;
			KEY_LOGD("%s: Disable kpdpwr s2 reset clear up [%d]\n",
						__func__, clear_kpdpwr_s2_rst_flag);
			if (hrtimer_is_queued(&clr_kpd_reset_timer))
				hrtimer_cancel(&clr_kpd_reset_timer);
			if (hrtimer_is_queued(&enable_kpd_s2_timer))
				hrtimer_cancel(&enable_kpd_s2_timer);
#endif 
		}
	}
}

#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
static enum hrtimer_restart clr_kpd_rst_timer_func(struct hrtimer *timer)
{
	if (qpnp_get_reset_en(PON_KPDPWR) > 0) {
		qpnp_config_reset_enable(PON_KPDPWR, 0);
		qpnp_config_reset_enable(PON_KPDPWR, 1);
		hrtimer_start(&enable_kpd_s2_timer, ktime_set(0, 0), HRTIMER_MODE_REL);
	}

	return HRTIMER_NORESTART;
}

static enum hrtimer_restart enable_kpd_s2_timer_func(struct hrtimer *timer)
{
	qpnp_config_reset_enable(PON_KPDPWR, 1);
	if (clear_kpdpwr_s2_rst_flag) {
		hrtimer_start(&clr_kpd_reset_timer,
			ktime_set(0, KPDPWR_CLR_RESET_TIMER), HRTIMER_MODE_REL);
	} else {
	        if (hrtimer_is_queued(&clr_kpd_reset_timer))
			hrtimer_cancel(&clr_kpd_reset_timer);
		if (hrtimer_is_queued(&enable_kpd_s2_timer))
			hrtimer_cancel(&enable_kpd_s2_timer);
	}

	return HRTIMER_NORESTART;
}
static void power_key_check_reset_work_func(struct work_struct *dummy)
{
	struct gpio_event_input_info *aa = gis;
#ifdef CONFIG_POWER_VOLUP_RESET
	uint8_t val = 0, i = 0;
#else
	int pocket_mode = 0;
#endif
	KEY_LOGI("[PWR] %s\n", __func__);

#ifdef CONFIG_OF
	if ((aa->dt_clear_hw_reset)) {
		if (aa->info.rrm1_mode) {
			KEY_LOGI(" Power key check in Lab Test RRM1 mode.\n");
			aa->dt_clear_hw_reset(aa->clr_gpio);
#else
	if ((aa->clear_hw_reset)) {
		if (aa->info.rrm1_mode) {
			printk(KERN_INFO "[KEY] Power key check in Lab Test RRM1 mode.\n");
			aa->clear_hw_reset();
#endif
#ifndef CONFIG_POWER_VOLUP_RESET
		} else if (board_mfg_mode() == MFG_MODE_NORMAL) {
			
			pocket_mode = power_key_check_in_pocket();
			if (pocket_mode) {
				printk(KERN_INFO "[KEY] power_key_check_in_pocket = %d\n", pocket_mode);
#ifdef CONFIG_OF
				aa->dt_clear_hw_reset(aa->clr_gpio);
#else
				aa->clear_hw_reset();
#endif
			}
		} else
			printk(KERN_INFO "[KEY] Not in normal OS mode, mode=%d\n", board_mfg_mode());
#else	
		} else {
			printk(KERN_INFO "[KEY] OS Mode=%d\n", board_mfg_mode());
			for (i = 0; i < aa->keymap_size; i++) {
				if (aa->keymap[i].code == KEY_VOLUMEUP) {
					val = gpio_get_value(aa->keymap[i].gpio);
					break;
				}
			}
			if (!val) { 	
				KEY_LOGI("HW RESET continue");
			} else {	
#ifdef CONFIG_OF
				aa->dt_clear_hw_reset(aa->clr_gpio);
#else
				aa->clear_hw_reset();
#endif
			}
		}
#endif	
	} else {
		KEY_LOGI("[PWR] No reset  clear function\n");
	}
	handle_power_key_reset(KEY_POWER, 1);
}
static DECLARE_DELAYED_WORK(power_key_check_reset_work, power_key_check_reset_work_func);

static void power_key_clr_check_work_func(struct work_struct *dummy)
{
#ifdef CONFIG_POWER_VOLUP_RESET
	uint8_t i = 0, val = 0, pwr_idx = 0;
	struct gpio_event_input_info *aa = gis;

	for (i = 0; i < aa->keymap_size; i++) {
		if (aa->keymap[i].code == KEY_VOLUMEUP) {
			val = gpio_get_value(aa->keymap[i].gpio);
			if (val) {
				KEY_LOGI("volUP clear");
#ifdef CONFIG_OF
				aa->dt_clear_hw_reset(aa->clr_gpio);
#else
				aa->clear_hw_reset();
#endif
			}
			break;
		}
		if (aa->keymap[i].code == KEY_POWER)
			pwr_idx = i;
	}

	val = gpio_get_value(aa->keymap[pwr_idx].gpio);

	if (val) {
#endif 
		if (cancel_delayed_work_sync(&power_key_check_reset_work))
			KEY_LOGI("[PWR] cancel power key check reset work successfully\n");
		else
			KEY_LOGI("[PWR] cancel power key check reset work unsuccessfully\n");
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
		clear_kpdpwr_s2_rst_flag = 0;
		KEY_LOGD("%s: Disable kpdpwr s2 reset clear up [%d]\n", __func__, clear_kpdpwr_s2_rst_flag);
		if (hrtimer_is_queued(&clr_kpd_reset_timer))
			hrtimer_cancel(&clr_kpd_reset_timer);
		if (hrtimer_is_queued(&enable_kpd_s2_timer))
			hrtimer_cancel(&enable_kpd_s2_timer);
#endif 
#ifdef CONFIG_POWER_VOLUP_RESET
	}
#endif
	wake_unlock(&key_reset_clr_wake_lock);
}