Beispiel #1
0
static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
{
	struct gpio_button_data *bdata = dev_id;
	const struct gpio_keys_button *button = bdata->button;
	struct input_dev *input = bdata->input;
	unsigned long flags;

	BUG_ON(irq != bdata->irq);

	spin_lock_irqsave(&bdata->lock, flags);

	if (!bdata->key_pressed) {
		if (bdata->button->wakeup)
			pm_wakeup_event(bdata->input->dev.parent, 0);

		input_event(input, EV_KEY, button->code, 1);
		input_sync(input);

		if (!bdata->release_delay) {
			input_event(input, EV_KEY, button->code, 0);
			input_sync(input);
			goto out;
		}

		bdata->key_pressed = true;
	}

	if (bdata->release_delay)
		mod_timer(&bdata->release_timer,
			jiffies + msecs_to_jiffies(bdata->release_delay));
out:
	spin_unlock_irqrestore(&bdata->lock, flags);
	return IRQ_HANDLED;
}
Beispiel #2
0
static irqreturn_t wl1271_hardirq(int irq, void *cookie)
{
	struct wl1271 *wl = cookie;
	unsigned long flags;

	wl1271_debug(DEBUG_IRQ, "IRQ");

	/* complete the ELP completion */
	spin_lock_irqsave(&wl->wl_lock, flags);
	set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
	if (wl->elp_compl) {
		complete(wl->elp_compl);
		wl->elp_compl = NULL;
	}

	if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
		/* don't enqueue a work right now. mark it as pending */
		set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
		wl1271_debug(DEBUG_IRQ, "should not enqueue work");
		disable_irq_nosync(wl->irq);
		pm_wakeup_event(wl1271_sdio_wl_to_dev(wl), 0);
		spin_unlock_irqrestore(&wl->wl_lock, flags);
		return IRQ_HANDLED;
	}
	spin_unlock_irqrestore(&wl->wl_lock, flags);

	return IRQ_WAKE_THREAD;
}
Beispiel #3
0
static irqreturn_t link_pm_irq_handler(int irq, void *data)
{
	int value;
	struct link_pm_data *pm_data = data;

#if defined(CONFIG_SLP)
	pm_wakeup_event(pm_data->miscdev.this_device, 0);
#endif

	if (!pm_data->link_pm_active)
		return IRQ_HANDLED;

	/* host wake up HIGH */
	/*
		resume usb runtime pm start
	*/
	/* host wake up LOW */
	/*
		slave usb enumeration end,
		host can send usb packet after
		runtime pm status changes to ACTIVE
	*/
	value = gpio_get_value(pm_data->gpio_link_hostwake);
	mif_debug("gpio [HWK] get [%d]\n", value);

	/*
	* igonore host wakeup interrupt at suspending kernel
	*/
	if (pm_data->dpm_suspending) {
		mif_info("ignore request by suspending\n");
		/* Ignore HWK but AP got to L2 by suspending fail */
		wake_lock(&pm_data->l2_wake);
		return IRQ_HANDLED;
	}

	if (value == HOSTWAKE_TRIGLEVEL) {
		/* move to slave wake function */
		/* runtime pm goes to active */
		/*
		if (gpio_get_value(pm_data->gpio_link_active)) {
			mif_err("gpio [H ACTV : %d] set 1\n",
				gpio_get_value(pm_data->gpio_link_active));
			gpio_set_value(pm_data->gpio_link_active, 1);
		}
		*/
		queue_delayed_work(pm_data->wq, &pm_data->link_pm_work, 0);
	} else {
		/* notification of enumeration process from slave device
		 * But it does not mean whole connection is in resume, so do not
		 * notify resume completion here.

		if (pm_data->link_pm_active && !pm_data->active_done.done)
			complete(&pm_data->active_done);
		*/
		/* clear slave cpu wake up pin */
		gpio_set_value(pm_data->gpio_link_slavewake, 0);
		mif_debug("gpio [SWK] set [0]\n");
	}
	return IRQ_HANDLED;
}
Beispiel #4
0
/**
 * acpi_wakeup_device - Wakeup notification handler for ACPI devices.
 * @handle: ACPI handle of the device the notification is for.
 * @event: Type of the signaled event.
 * @context: Device corresponding to @handle.
 */
static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context)
{
	struct device *dev = context;

	if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) {
		pm_wakeup_event(dev, 0);
		pm_runtime_resume(dev);
	}
}
Beispiel #5
0
static u32 rtc_handler(void *context)
{
	struct device *dev = context;

	pm_wakeup_event(dev, 0);
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_disable_event(ACPI_EVENT_RTC, 0);
	return ACPI_INTERRUPT_HANDLED;
}
Beispiel #6
0
/**
 * acpi_pm_notify_work_func - ACPI devices wakeup notification work function.
 * @work: Work item to handle.
 */
static void acpi_pm_notify_work_func(struct work_struct *work)
{
	struct device *dev;

	dev = container_of(work, struct acpi_device_wakeup_context, work)->dev;
	if (dev) {
		pm_wakeup_event(dev, 0);
		pm_runtime_resume(dev);
	}
}
Beispiel #7
0
static void stm32_receive_chars(struct uart_port *port, bool threaded)
{
	struct tty_port *tport = &port->state->port;
	struct stm32_port *stm32_port = to_stm32_port(port);
	struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
	unsigned long c;
	u32 sr;
	char flag;

	if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
		pm_wakeup_event(tport->tty->dev, 0);

	while (stm32_pending_rx(port, &sr, &stm32_port->last_res, threaded)) {
		sr |= USART_SR_DUMMY_RX;
		c = stm32_get_char(port, &sr, &stm32_port->last_res);
		flag = TTY_NORMAL;
		port->icount.rx++;

		if (sr & USART_SR_ERR_MASK) {
			if (sr & USART_SR_LBD) {
				port->icount.brk++;
				if (uart_handle_break(port))
					continue;
			} else if (sr & USART_SR_ORE) {
				if (ofs->icr != UNDEF_REG)
					writel_relaxed(USART_ICR_ORECF,
						       port->membase +
						       ofs->icr);
				port->icount.overrun++;
			} else if (sr & USART_SR_PE) {
				port->icount.parity++;
			} else if (sr & USART_SR_FE) {
				port->icount.frame++;
			}

			sr &= port->read_status_mask;

			if (sr & USART_SR_LBD)
				flag = TTY_BREAK;
			else if (sr & USART_SR_PE)
				flag = TTY_PARITY;
			else if (sr & USART_SR_FE)
				flag = TTY_FRAME;
		}

		if (uart_handle_sysrq_char(port, c))
			continue;
		uart_insert_char(port, sr, USART_SR_ORE, c, flag);
	}

	spin_unlock(&port->lock);
	tty_flip_buffer_push(tport);
	spin_lock(&port->lock);
}
irqreturn_t gp2a_irq_handler(int irq, void *gp2a_data_p)
{
	struct gp2a_data *data = gp2a_data_p;

	wake_lock_timeout(&data->prx_wake_lock, 3 * HZ);
#ifdef CONFIG_SLP
	pm_wakeup_event(data->proximity_dev, 0);
#endif

	schedule_work(&data->work);

	gprintk("[PROXIMITY] IRQ_HANDLED.\n");
	return IRQ_HANDLED;
}
Beispiel #9
0
static irqreturn_t ec_irq_thread(int irq, void *data)
{
	struct cros_ec_device *ec_dev = data;
	int ret;

	if (device_may_wakeup(ec_dev->dev))
		pm_wakeup_event(ec_dev->dev, 0);

	ret = cros_ec_get_next_event(ec_dev);
	if (ret > 0)
		blocking_notifier_call_chain(&ec_dev->event_notifier,
					     0, ec_dev);
	return IRQ_HANDLED;
}
Beispiel #10
0
static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
{
	struct platform_device *pdev = dev_id;
	struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
	u32 lp_status;

	pm_wakeup_event(pdata->input->dev.parent, 0);

	regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status);
	if (lp_status & SNVS_LPSR_SPO)
		mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME));

	/* clear SPO status */
	regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);

	return IRQ_HANDLED;
}
Beispiel #11
0
static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
	struct cros_ec_keyb *ckdev = data;
	struct cros_ec_device *ec = ckdev->ec;
	int ret;
	uint8_t kb_state[ckdev->cols];

	if (device_may_wakeup(ec->dev))
		pm_wakeup_event(ec->dev, 0);

	ret = cros_ec_keyb_get_state(ckdev, kb_state);
	if (ret >= 0)
		cros_ec_keyb_process(ckdev, kb_state, ret);
	else
		dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);

	return IRQ_HANDLED;
}
Beispiel #12
0
static irqreturn_t powerbutton_irq(int irq, void *_pwr)
{
	struct input_dev *pwr = _pwr;
	int err;
	u8 value;

	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &value, STS_HW_CONDITIONS);
	if (!err)  {
		pm_wakeup_event(pwr->dev.parent, 0);
		input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);
		input_sync(pwr);
	} else {
		dev_err(pwr->dev.parent, "twl4030: i2c error %d while reading"
			" TWL4030 PM_MASTER STS_HW_CONDITIONS register\n", err);
	}

	return IRQ_HANDLED;
}
Beispiel #13
0
static irqreturn_t wake_timer_irq(int irq, void *dev_id)
{
	struct wake_timer *tm = dev_id;
	int stat = 0;

	if(irq == tm->irq[0]) {
		/*clear interrupt*/
		readl(tm->mmio + EOI); 
		pm_wakeup_event(&tm->pdev->dev, 0);
		pm_relax(&tm->pdev->dev);

#ifdef CONFIG_PM_WAKEUP_DEVICE_AUTO_TEST_SUSPEND
		input_report_key(tm->input_dev, KEY_POWER, 1);
		input_sync(tm->input_dev);

		input_report_key(tm->input_dev, KEY_POWER, 0);
		input_sync(tm->input_dev);
#endif

#ifdef MANU_UNLOCK
 		wake_lock(&tm->wake_lock);
#else
 		wake_lock_timeout(&tm->wake_lock, tm->wake_ms/1000*HZ);
#endif
	} else if(irq == tm->irq[1]) {
		/*clear interrupt*/
		readl(tm->mmio + EOI + OFFSET); 
		if(tm->stat == STAT_ON) {
			stat = pm_runtime_put(&tm->pdev->dev);
		} else {
			stat = pm_runtime_get(&tm->pdev->dev);
		}
		if(stat)
			dev_err(&tm->pdev->dev, "pm runtime ret %d", stat);
#ifdef MANU_UNLOCK
		wake_unlock(&tm->wake_lock);
#endif
	}
	/*dev_info(&tm->pdev->dev, "irq %d", irq);*/

        return IRQ_HANDLED;
}
Beispiel #14
0
/**
 * handle_threaded_wake_irq - Handler for dedicated wake-up interrupts
 * @irq: Device specific dedicated wake-up interrupt
 * @_wirq: Wake IRQ data
 *
 * Some devices have a separate wake-up interrupt in addition to the
 * device IO interrupt. The wake-up interrupt signals that a device
 * should be woken up from it's idle state. This handler uses device
 * specific pm_runtime functions to wake the device, and then it's
 * up to the device to do whatever it needs to. Note that as the
 * device may need to restore context and start up regulators, we
 * use a threaded IRQ.
 *
 * Also note that we are not resending the lost device interrupts.
 * We assume that the wake-up interrupt just needs to wake-up the
 * device, and then device's pm_runtime_resume() can deal with the
 * situation.
 */
static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq)
{
	struct wake_irq *wirq = _wirq;
	int res;

	/* Maybe abort suspend? */
	if (irqd_is_wakeup_set(irq_get_irq_data(irq))) {
		pm_wakeup_event(wirq->dev, 0);

		return IRQ_HANDLED;
	}

	/* We don't want RPM_ASYNC or RPM_NOWAIT here */
	res = pm_runtime_resume(wirq->dev);
	if (res < 0)
		dev_warn(wirq->dev,
			 "wake IRQ with no resume: %i\n", res);

	return IRQ_HANDLED;
}
Beispiel #15
0
static irqreturn_t ec_irq_thread(int irq, void *data)
{
	struct cros_ec_device *ec_dev = data;
	bool wake_event = true;
	int ret;

	ret = cros_ec_get_next_event(ec_dev, &wake_event);

	/*
	 * Signal only if wake host events or any interrupt if
	 * cros_ec_get_next_event() returned an error (default value for
	 * wake_event is true)
	 */
	if (wake_event && device_may_wakeup(ec_dev->dev))
		pm_wakeup_event(ec_dev->dev, 0);

	if (ret > 0)
		blocking_notifier_call_chain(&ec_dev->event_notifier,
					     0, ec_dev);
	return IRQ_HANDLED;
}
Beispiel #16
0
int fts_sensor_read_data(struct fts_ts_data *data)
{
    int ret = 0;
    if (fts_psensor_support_enabled() && data->psensor_pdata->tp_psensor_opened)
    {
        ret = fts_read_tp_psensor_data(data);
        if ( !ret )
        {
            if (data->suspended)
            {
                pm_wakeup_event(&data->client->dev, FTS_PSENSOR_WAKEUP_TIMEOUT);
            }
            input_report_abs(data->psensor_pdata->input_psensor_dev,
                             ABS_DISTANCE,
                             data->psensor_pdata->tp_psensor_data);
            input_sync(data->psensor_pdata->input_psensor_dev);
        }
        return 1;
    }
    return 0;
}
Beispiel #17
0
static u32 rtc_handler(void *context)
{
	struct device *dev = context;
	struct cmos_rtc *cmos = dev_get_drvdata(dev);
	unsigned char rtc_control = 0;
	unsigned char rtc_intr;

	spin_lock_irq(&rtc_lock);
	if (cmos_rtc.suspend_ctrl)
		rtc_control = CMOS_READ(RTC_CONTROL);
	if (rtc_control & RTC_AIE) {
		cmos_rtc.suspend_ctrl &= ~RTC_AIE;
		CMOS_WRITE(rtc_control, RTC_CONTROL);
		rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
		rtc_update_irq(cmos->rtc, 1, rtc_intr);
	}
	spin_unlock_irq(&rtc_lock);

	pm_wakeup_event(dev, 0);
	acpi_clear_event(ACPI_EVENT_RTC);
	acpi_disable_event(ACPI_EVENT_RTC, 0);
	return ACPI_INTERRUPT_HANDLED;
}
Beispiel #18
0
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
	int ret;
	struct cros_ec_command msg = {
		.version = 0,
		.command = EC_CMD_MKBP_STATE,
		.outdata = NULL,
		.outsize = 0,
		.indata = kb_state,
		.insize = ckdev->cols,
	};

	ret = cros_ec_cmd_xfer_status(ckdev->ec, &msg);
	return ret;
}

static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
	struct cros_ec_keyb *ckdev = data;
	struct cros_ec_device *ec = ckdev->ec;
	int ret;
	uint8_t kb_state[ckdev->cols];

	if (device_may_wakeup(ec->dev))
		pm_wakeup_event(ec->dev, 0);

	ret = cros_ec_keyb_get_state(ckdev, kb_state);
	if (ret >= 0)
		cros_ec_keyb_process(ckdev, kb_state, ret);
	else
		dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);

	return IRQ_HANDLED;
}

static int cros_ec_keyb_open(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					"cros_ec_keyb", ckdev);
}

static void cros_ec_keyb_close(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	free_irq(ec->irq, ckdev);
}

static int cros_ec_keyb_probe(struct platform_device *pdev)
{
	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
	struct device *dev = ec->dev;
	struct cros_ec_keyb *ckdev;
	struct input_dev *idev;
	struct device_node *np;
	int err;

	np = pdev->dev.of_node;
	if (!np)
		return -ENODEV;

	ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL);
	if (!ckdev)
		return -ENOMEM;
	err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows,
					    &ckdev->cols);
	if (err)
		return err;
	ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL);
	if (!ckdev->old_kb_state)
		return -ENOMEM;

	idev = devm_input_allocate_device(&pdev->dev);
	if (!idev)
		return -ENOMEM;

	if (!ec->irq) {
		dev_err(dev, "no EC IRQ specified\n");
		return -EINVAL;
	}

	ckdev->ec = ec;
	ckdev->dev = dev;
	dev_set_drvdata(&pdev->dev, ckdev);

	idev->name = CROS_EC_DEV_NAME;
	idev->phys = ec->phys_name;
	__set_bit(EV_REP, idev->evbit);

	idev->id.bustype = BUS_VIRTUAL;
	idev->id.version = 1;
	idev->id.product = 0;
	idev->dev.parent = &pdev->dev;
	idev->open = cros_ec_keyb_open;
	idev->close = cros_ec_keyb_close;

	ckdev->ghost_filter = of_property_read_bool(np,
					"google,needs-ghost-filter");

	err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
					 NULL, idev);
	if (err) {
		dev_err(dev, "cannot build key matrix\n");
		return err;
	}

	ckdev->row_shift = get_count_order(ckdev->cols);

	input_set_capability(idev, EV_MSC, MSC_SCAN);
	input_set_drvdata(idev, ckdev);
	ckdev->idev = idev;
	err = input_register_device(ckdev->idev);
	if (err) {
		dev_err(dev, "cannot register input device\n");
		return err;
	}

	return 0;
}

#ifdef CONFIG_PM_SLEEP
/* Clear any keys in the buffer */
static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
{
	uint8_t old_state[ckdev->cols];
	uint8_t new_state[ckdev->cols];
	unsigned long duration;
	int i, ret;

	/*
	 * Keep reading until we see that the scan state does not change.
	 * That indicates that we are done.
	 *
	 * Assume that the EC keyscan buffer is at most 32 deep.
	 */
	duration = jiffies;
	ret = cros_ec_keyb_get_state(ckdev, new_state);
	for (i = 1; !ret && i < 32; i++) {
		memcpy(old_state, new_state, sizeof(old_state));
		ret = cros_ec_keyb_get_state(ckdev, new_state);
		if (0 == memcmp(old_state, new_state, sizeof(old_state)))
			break;
	}
	duration = jiffies - duration;
	dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
		jiffies_to_usecs(duration));
}
Beispiel #19
0
static void asc_receive_chars(struct uart_port *port)
{
	struct tty_port *tport = &port->state->port;
	unsigned long status, mode;
	unsigned long c = 0;
	char flag;
	bool ignore_pe = false;

	/*
	 * Datasheet states: If the MODE field selects an 8-bit frame then
	 * this [parity error] bit is undefined. Software should ignore this
	 * bit when reading 8-bit frames.
	 */
	mode = asc_in(port, ASC_CTL) & ASC_CTL_MODE_MSK;
	if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR)
		ignore_pe = true;

	if (irqd_is_wakeup_set(irq_get_irq_data(port->irq)))
		pm_wakeup_event(tport->tty->dev, 0);

	while ((status = asc_in(port, ASC_STA)) & ASC_STA_RBF) {
		c = asc_in(port, ASC_RXBUF) | ASC_RXBUF_DUMMY_RX;
		flag = TTY_NORMAL;
		port->icount.rx++;

		if (status & ASC_STA_OE || c & ASC_RXBUF_FE ||
		    (c & ASC_RXBUF_PE && !ignore_pe)) {

			if (c & ASC_RXBUF_FE) {
				if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {
					port->icount.brk++;
					if (uart_handle_break(port))
						continue;
					c |= ASC_RXBUF_DUMMY_BE;
				} else {
					port->icount.frame++;
				}
			} else if (c & ASC_RXBUF_PE) {
				port->icount.parity++;
			}
			/*
			 * Reading any data from the RX FIFO clears the
			 * overflow error condition.
			 */
			if (status & ASC_STA_OE) {
				port->icount.overrun++;
				c |= ASC_RXBUF_DUMMY_OE;
			}

			c &= port->read_status_mask;

			if (c & ASC_RXBUF_DUMMY_BE)
				flag = TTY_BREAK;
			else if (c & ASC_RXBUF_PE)
				flag = TTY_PARITY;
			else if (c & ASC_RXBUF_FE)
				flag = TTY_FRAME;
		}

		if (uart_handle_sysrq_char(port, c & 0xff))
			continue;

		uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag);
	}

	/* Tell the rest of the system the news. New characters! */
	tty_flip_buffer_push(tport);
}
Beispiel #20
0
static void olpc_xo175_ec_complete(void *arg)
{
	struct olpc_xo175_ec *priv = arg;
	struct device *dev = &priv->spi->dev;
	struct power_supply *psy;
	unsigned long flags;
	u8 channel;
	u8 byte;
	int ret;

	ret = priv->msg.status;
	if (ret) {
		dev_err(dev, "SPI transfer failed: %d\n", ret);

		spin_lock_irqsave(&priv->cmd_state_lock, flags);
		if (priv->cmd_running) {
			priv->resp_len = 0;
			priv->cmd_state = CMD_STATE_ERROR_RECEIVED;
			complete(&priv->cmd_done);
		}
		spin_unlock_irqrestore(&priv->cmd_state_lock, flags);

		if (ret != -EINTR)
			olpc_xo175_ec_read_packet(priv);

		return;
	}

	channel = priv->rx_buf.resp.channel;
	byte = priv->rx_buf.resp.byte;

	switch (channel) {
	case CHAN_NONE:
		spin_lock_irqsave(&priv->cmd_state_lock, flags);

		if (!priv->cmd_running) {
			/* We can safely ignore these */
			dev_err(dev, "spurious FIFO read packet\n");
			spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
			return;
		}

		priv->cmd_state = CMD_STATE_CMD_SENT;
		if (!priv->expected_resp_len)
			complete(&priv->cmd_done);
		olpc_xo175_ec_read_packet(priv);

		spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
		return;

	case CHAN_SWITCH:
		spin_lock_irqsave(&priv->cmd_state_lock, flags);

		if (!priv->cmd_running) {
			/* Just go with the flow */
			dev_err(dev, "spurious SWITCH packet\n");
			memset(&priv->cmd, 0, sizeof(priv->cmd));
			priv->cmd.command = CMD_ECHO;
		}

		priv->cmd_state = CMD_STATE_CMD_IN_TX_FIFO;

		/* Throw command into TxFIFO */
		gpiod_set_value_cansleep(priv->gpio_cmd, 0);
		olpc_xo175_ec_send_command(priv, &priv->cmd, sizeof(priv->cmd));

		spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
		return;

	case CHAN_CMD_RESP:
		spin_lock_irqsave(&priv->cmd_state_lock, flags);

		if (!priv->cmd_running) {
			dev_err(dev, "spurious response packet\n");
		} else if (priv->resp_len >= priv->expected_resp_len) {
			dev_err(dev, "too many response packets\n");
		} else {
			priv->resp_data[priv->resp_len++] = byte;
			if (priv->resp_len == priv->expected_resp_len) {
				priv->cmd_state = CMD_STATE_RESP_RECEIVED;
				complete(&priv->cmd_done);
			}
		}

		spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
		break;

	case CHAN_CMD_ERROR:
		spin_lock_irqsave(&priv->cmd_state_lock, flags);

		if (!priv->cmd_running) {
			dev_err(dev, "spurious cmd error packet\n");
		} else {
			priv->resp_data[0] = byte;
			priv->resp_len = 1;
			priv->cmd_state = CMD_STATE_ERROR_RECEIVED;
			complete(&priv->cmd_done);
		}
		spin_unlock_irqrestore(&priv->cmd_state_lock, flags);
		break;

	case CHAN_KEYBOARD:
		dev_warn(dev, "keyboard is not supported\n");
		break;

	case CHAN_TOUCHPAD:
		dev_warn(dev, "touchpad is not supported\n");
		break;

	case CHAN_EVENT:
		dev_dbg(dev, "got event %.2x\n", byte);
		switch (byte) {
		case EVENT_AC_CHANGE:
			psy = power_supply_get_by_name("olpc-ac");
			if (psy) {
				power_supply_changed(psy);
				power_supply_put(psy);
			}
			break;
		case EVENT_BATTERY_STATUS:
		case EVENT_BATTERY_CRITICAL:
		case EVENT_BATTERY_SOC_CHANGE:
		case EVENT_BATTERY_ERROR:
			psy = power_supply_get_by_name("olpc-battery");
			if (psy) {
				power_supply_changed(psy);
				power_supply_put(psy);
			}
			break;
		case EVENT_POWER_PRESSED:
			input_report_key(priv->pwrbtn, KEY_POWER, 1);
			input_sync(priv->pwrbtn);
			input_report_key(priv->pwrbtn, KEY_POWER, 0);
			input_sync(priv->pwrbtn);
			/* fall through */
		case EVENT_POWER_PRESS_WAKE:
		case EVENT_TIMED_HOST_WAKE:
			pm_wakeup_event(priv->pwrbtn->dev.parent,
						PM_WAKEUP_TIME);
			break;
		default:
			dev_dbg(dev, "ignored unknown event %.2x\n", byte);
			break;
		}
		break;

	case CHAN_DEBUG:
		if (byte == '\n') {
			olpc_xo175_ec_flush_logbuf(priv);
		} else if (isprint(byte)) {
			priv->logbuf[priv->logbuf_len++] = byte;
			if (priv->logbuf_len == LOG_BUF_SIZE)
				olpc_xo175_ec_flush_logbuf(priv);
		}
		break;

	default:
		dev_warn(dev, "unknown channel: %d, %.2x\n", channel, byte);
		break;
	}

	/* Most non-command packets get the TxFIFO refilled and an ACK. */
	olpc_xo175_ec_read_packet(priv);
}
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
	int ret;
	struct cros_ec_command msg = {
		.version = 0,
		.command = EC_CMD_MKBP_STATE,
		.outdata = NULL,
		.outsize = 0,
		.indata = kb_state,
		.insize = ckdev->cols,
	};

	ret = cros_ec_cmd_xfer(ckdev->ec, &msg);
	/* FIXME: This assumes msg.result == EC_RES_SUCCESS */
	return ret;
}

static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
	struct cros_ec_keyb *ckdev = data;
	struct cros_ec_device *ec = ckdev->ec;
	int ret;
	uint8_t kb_state[ckdev->cols];

	if (device_may_wakeup(ec->dev))
		pm_wakeup_event(ec->dev, 0);

	ret = cros_ec_keyb_get_state(ckdev, kb_state);
	if (ret >= 0)
		cros_ec_keyb_process(ckdev, kb_state, ret);
	else
		dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);

	return IRQ_HANDLED;
}

static int cros_ec_keyb_open(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					"cros_ec_keyb", ckdev);
}

static void cros_ec_keyb_close(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	free_irq(ec->irq, ckdev);
}

/* Clear any keys in the buffer */
static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
{
	uint8_t old_state[ckdev->cols];
	uint8_t new_state[ckdev->cols];
	unsigned long duration;
	int i, ret;

	/*
	 * Keep reading until we see that the scan state does not change.
	 * That indicates that we are done.
	 *
	 * Assume that the EC keyscan buffer is at most 32 deep.
	 */
	duration = jiffies;
	ret = cros_ec_keyb_get_state(ckdev, new_state);
	for (i = 1; !ret && i < 32; i++) {
		memcpy(old_state, new_state, sizeof(old_state));
		ret = cros_ec_keyb_get_state(ckdev, new_state);
		if (0 == memcmp(old_state, new_state, sizeof(old_state)))
			break;
	}
	duration = jiffies - duration;
	dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
		jiffies_to_usecs(duration));
}
static int sdio_irq_thread(void *_host)
{
	struct mmc_host *host = _host;
	struct sched_param param = { .sched_priority = 1 };
	unsigned long period, idle_period;
	int ret;
	bool ws;

	sched_setscheduler(current, SCHED_FIFO, &param);

	/*
	 * We want to allow for SDIO cards to work even on non SDIO
	 * aware hosts.  One thing that non SDIO host cannot do is
	 * asynchronous notification of pending SDIO card interrupts
	 * hence we poll for them in that case.
	 */
	idle_period = msecs_to_jiffies(10);
	period = (host->caps & MMC_CAP_SDIO_IRQ) ?
		MAX_SCHEDULE_TIMEOUT : idle_period;

	pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
		 mmc_hostname(host), period);

	do {
		/*
		 * We claim the host here on drivers behalf for a couple
		 * reasons:
		 *
		 * 1) it is already needed to retrieve the CCCR_INTx;
		 * 2) we want the driver(s) to clear the IRQ condition ASAP;
		 * 3) we need to control the abort condition locally.
		 *
		 * Just like traditional hard IRQ handlers, we expect SDIO
		 * IRQ handlers to be quick and to the point, so that the
		 * holding of the host lock does not cover too much work
		 * that doesn't require that lock to be held.
		 */
		ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
		if (ret)
			break;
		ws = false;
		/*
		 * prevent suspend if it has started when scheduled;
		 * 100 msec (approx. value) should be enough for the system to
		 * resume and attend to the card's request
		 */
		if ((host->dev_status == DEV_SUSPENDING) ||
		    (host->dev_status == DEV_SUSPENDED)) {
			pm_wakeup_event(&host->card->dev, 100);
			ws = true;
		}

		ret = process_sdio_pending_irqs(host);
		host->sdio_irq_pending = false;
		mmc_release_host(host);

		/*
		 * Give other threads a chance to run in the presence of
		 * errors.
		 */
		if (ret < 0) {
			set_current_state(TASK_INTERRUPTIBLE);
			if (!kthread_should_stop())
				schedule_timeout(HZ);
			set_current_state(TASK_RUNNING);
		}

		/*
		 * Adaptive polling frequency based on the assumption
		 * that an interrupt will be closely followed by more.
		 * This has a substantial benefit for network devices.
		 */
		if (!(host->caps & MMC_CAP_SDIO_IRQ)) {
			if (ret > 0)
				period /= 2;
			else {
				period++;
				if (period > idle_period)
					period = idle_period;
			}
		}

		set_current_state(TASK_INTERRUPTIBLE);
		if (host->caps & MMC_CAP_SDIO_IRQ) {
			mmc_host_clk_hold(host);
			host->ops->enable_sdio_irq(host, 1);
			mmc_host_clk_release(host);
		}
		/*
		 * function drivers would have processed the event from card
		 * unless suspended, hence release wake source
		 */
		if (ws && (host->dev_status == DEV_RESUMED))
			pm_relax(&host->card->dev);

		if (!kthread_should_stop())
			schedule_timeout(period);
		set_current_state(TASK_RUNNING);
	} while (!kthread_should_stop());

	if (host->caps & MMC_CAP_SDIO_IRQ) {
		mmc_host_clk_hold(host);
		host->ops->enable_sdio_irq(host, 0);
		mmc_host_clk_release(host);
	}

	pr_debug("%s: IRQ thread exiting with code %d\n",
		 mmc_hostname(host), ret);

	return ret;
}

static int sdio_card_irq_get(struct mmc_card *card)
{
	struct mmc_host *host = card->host;

	WARN_ON(!host->claimed);

	if (!host->sdio_irqs++) {
		atomic_set(&host->sdio_irq_thread_abort, 0);
		host->sdio_irq_thread =
			kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
				mmc_hostname(host));
		if (IS_ERR(host->sdio_irq_thread)) {
			int err = PTR_ERR(host->sdio_irq_thread);
			host->sdio_irqs--;
			return err;
		}
	}

	return 0;
}

static int sdio_card_irq_put(struct mmc_card *card)
{
	struct mmc_host *host = card->host;

	WARN_ON(!host->claimed);
	BUG_ON(host->sdio_irqs < 1);

	if (!--host->sdio_irqs) {
		atomic_set(&host->sdio_irq_thread_abort, 1);
		kthread_stop(host->sdio_irq_thread);
	}

	return 0;
}

/* If there is only 1 function registered set sdio_single_irq */
static void sdio_single_irq_set(struct mmc_card *card)
{
	struct sdio_func *func;
	int i;

	card->sdio_single_irq = NULL;
	if ((card->host->caps & MMC_CAP_SDIO_IRQ) &&
	    card->host->sdio_irqs == 1)
		for (i = 0; i < card->sdio_funcs; i++) {
		       func = card->sdio_func[i];
		       if (func && func->irq_handler) {
			       card->sdio_single_irq = func;
			       break;
		       }
	       }
}

/**
 *	sdio_claim_irq - claim the IRQ for a SDIO function
 *	@func: SDIO function
 *	@handler: IRQ handler callback
 *
 *	Claim and activate the IRQ for the given SDIO function. The provided
 *	handler will be called when that IRQ is asserted.  The host is always
 *	claimed already when the handler is called so the handler must not
 *	call sdio_claim_host() nor sdio_release_host().
 */
int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
{
	int ret;
	unsigned char reg;

	BUG_ON(!func);
	BUG_ON(!func->card);

	pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));

	if (func->irq_handler) {
		pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
		return -EBUSY;
	}

	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
	if (ret)
		return ret;

	reg |= 1 << func->num;

	reg |= 1; /* Master interrupt enable */

	ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
	if (ret)
		return ret;

	func->irq_handler = handler;
	ret = sdio_card_irq_get(func->card);
	if (ret)
		func->irq_handler = NULL;
	sdio_single_irq_set(func->card);

	return ret;
}
Beispiel #23
0
static void mousevsc_on_receive(struct hv_device *device,
				struct vmpacket_descriptor *packet)
{
	struct pipe_prt_msg *pipe_msg;
	struct synthhid_msg *hid_msg;
	struct mousevsc_dev *input_dev = hv_get_drvdata(device);
	struct synthhid_input_report *input_report;
	size_t len;

	pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
						(packet->offset8 << 3));

	if (pipe_msg->type != PIPE_MESSAGE_DATA)
		return;

	hid_msg = (struct synthhid_msg *)pipe_msg->data;

	switch (hid_msg->header.type) {
	case SYNTH_HID_PROTOCOL_RESPONSE:
		/*
		 * While it will be impossible for us to protect against
		 * malicious/buggy hypervisor/host, add a check here to
		 * ensure we don't corrupt memory.
		 */
		if ((pipe_msg->size + sizeof(struct pipe_prt_msg)
			- sizeof(unsigned char))
			> sizeof(struct mousevsc_prt_msg)) {
			WARN_ON(1);
			break;
		}

		memcpy(&input_dev->protocol_resp, pipe_msg,
		       pipe_msg->size + sizeof(struct pipe_prt_msg) -
		       sizeof(unsigned char));
		complete(&input_dev->wait_event);
		break;

	case SYNTH_HID_INITIAL_DEVICE_INFO:
		WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));

		/*
		 * Parse out the device info into device attr,
		 * hid desc and report desc
		 */
		mousevsc_on_receive_device_info(input_dev,
			(struct synthhid_device_info *)pipe_msg->data);
		break;
	case SYNTH_HID_INPUT_REPORT:
		input_report =
			(struct synthhid_input_report *)pipe_msg->data;
		if (!input_dev->init_complete)
			break;

		len = min(input_report->header.size,
			  (u32)sizeof(input_dev->input_buf));
		memcpy(input_dev->input_buf, input_report->buffer, len);
		hid_input_report(input_dev->hid_device, HID_INPUT_REPORT,
				 input_dev->input_buf, len, 1);

		pm_wakeup_event(&input_dev->device->device, 0);

		break;
	default:
		pr_err("unsupported hid msg type - type %d len %d",
		       hid_msg->header.type, hid_msg->header.size);
		break;
	}

}
Beispiel #24
0
static irqreturn_t st_rc_rx_interrupt(int irq, void *data)
{
	unsigned int symbol, mark = 0;
	struct st_rc_device *dev = data;
	int last_symbol = 0;
	u32 status;
	DEFINE_IR_RAW_EVENT(ev);

	if (dev->irq_wake)
		pm_wakeup_event(dev->dev, 0);

	status  = readl(dev->rx_base + IRB_RX_STATUS);

	while (status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)) {
		u32 int_status = readl(dev->rx_base + IRB_RX_INT_STATUS);
		if (unlikely(int_status & IRB_RX_OVERRUN_INT)) {
			/* discard the entire collection in case of errors!  */
			ir_raw_event_reset(dev->rdev);
			dev_info(dev->dev, "IR RX overrun\n");
			writel(IRB_RX_OVERRUN_INT,
					dev->rx_base + IRB_RX_INT_CLEAR);
			continue;
		}

		symbol = readl(dev->rx_base + IRB_RX_SYS);
		mark = readl(dev->rx_base + IRB_RX_ON);

		if (symbol == IRB_TIMEOUT)
			last_symbol = 1;

		 /* Ignore any noise */
		if ((mark > 2) && (symbol > 1)) {
			symbol -= mark;
			if (dev->overclocking) { /* adjustments to timings */
				symbol *= dev->sample_mult;
				symbol /= dev->sample_div;
				mark *= dev->sample_mult;
				mark /= dev->sample_div;
			}

			ev.duration = US_TO_NS(mark);
			ev.pulse = true;
			ir_raw_event_store(dev->rdev, &ev);

			if (!last_symbol) {
				ev.duration = US_TO_NS(symbol);
				ev.pulse = false;
				ir_raw_event_store(dev->rdev, &ev);
			} else  {
				st_rc_send_lirc_timeout(dev->rdev);
			}

		}
		last_symbol = 0;
		status  = readl(dev->rx_base + IRB_RX_STATUS);
	}

	writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR);

	/* Empty software fifo */
	ir_raw_event_handle(dev->rdev);
	return IRQ_HANDLED;
}
Beispiel #25
0
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
	struct cros_ec_command msg = {
		.version = 0,
		.command = EC_CMD_MKBP_STATE,
		.outdata = NULL,
		.outsize = 0,
		.indata = kb_state,
		.insize = ckdev->cols,
	};

	return cros_ec_cmd_xfer(ckdev->ec, &msg);
}

static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
	struct cros_ec_keyb *ckdev = data;
	struct cros_ec_device *ec = ckdev->ec;
	int ret;
	uint8_t kb_state[ckdev->cols];

	if (device_may_wakeup(ec->dev))
		pm_wakeup_event(ec->dev, 0);

	ret = cros_ec_keyb_get_state(ckdev, kb_state);
	if (ret >= 0)
		cros_ec_keyb_process(ckdev, kb_state, ret);
	else
		dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);

	return IRQ_HANDLED;
}

static int cros_ec_keyb_open(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					"cros_ec_keyb", ckdev);
}

static void cros_ec_keyb_close(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	free_irq(ec->irq, ckdev);
}

/*
 * Walks keycodes flipping bit in buffer COLUMNS deep where bit is ROW.  Used by
 * ghosting logic to ignore NULL or virtual keys.
 */
static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev)
{
	int row, col;
	int row_shift = ckdev->row_shift;
	unsigned short *keymap = ckdev->idev->keycode;
	unsigned short code;

	BUG_ON(ckdev->idev->keycodesize != sizeof(*keymap));

	for (col = 0; col < ckdev->cols; col++) {
		for (row = 0; row < ckdev->rows; row++) {
			code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)];
			if (code && (code != KEY_BATTERY))
				ckdev->valid_keys[col] |= 1 << row;
		}
		dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n",
			col, ckdev->valid_keys[col]);
	}
}
Beispiel #26
0
static void hv_kbd_on_receive(struct hv_device *hv_dev,
			      struct synth_kbd_msg *msg, u32 msg_length)
{
	struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
	struct synth_kbd_keystroke *ks_msg;
	unsigned long flags;
	u32 msg_type = __le32_to_cpu(msg->header.type);
	u32 info;
	u16 scan_code;

	switch (msg_type) {
	case SYNTH_KBD_PROTOCOL_RESPONSE:
		/*
		 * Validate the information provided by the host.
		 * If the host is giving us a bogus packet,
		 * drop the packet (hoping the problem
		 * goes away).
		 */
		if (msg_length < sizeof(struct synth_kbd_protocol_response)) {
			dev_err(&hv_dev->device,
				"Illegal protocol response packet (len: %d)\n",
				msg_length);
			break;
		}

		memcpy(&kbd_dev->protocol_resp, msg,
			sizeof(struct synth_kbd_protocol_response));
		complete(&kbd_dev->wait_event);
		break;

	case SYNTH_KBD_EVENT:
		/*
		 * Validate the information provided by the host.
		 * If the host is giving us a bogus packet,
		 * drop the packet (hoping the problem
		 * goes away).
		 */
		if (msg_length < sizeof(struct  synth_kbd_keystroke)) {
			dev_err(&hv_dev->device,
				"Illegal keyboard event packet (len: %d)\n",
				msg_length);
			break;
		}

		ks_msg = (struct synth_kbd_keystroke *)msg;
		info = __le32_to_cpu(ks_msg->info);

		/*
		 * Inject the information through the serio interrupt.
		 */
		spin_lock_irqsave(&kbd_dev->lock, flags);
		if (kbd_dev->started) {
			if (info & IS_E0)
				serio_interrupt(kbd_dev->hv_serio,
						XTKBD_EMUL0, 0);
			if (info & IS_E1)
				serio_interrupt(kbd_dev->hv_serio,
						XTKBD_EMUL1, 0);
			scan_code = __le16_to_cpu(ks_msg->make_code);
			if (info & IS_BREAK)
				scan_code |= XTKBD_RELEASE;

			serio_interrupt(kbd_dev->hv_serio, scan_code, 0);
		}
		spin_unlock_irqrestore(&kbd_dev->lock, flags);

		/*
		 * Only trigger a wakeup on key down, otherwise
		 * "echo freeze > /sys/power/state" can't really enter the
		 * state because the Enter-UP can trigger a wakeup at once.
		 */
		if (!(info & IS_BREAK))
			pm_wakeup_event(&hv_dev->device, 0);

		break;

	default:
		dev_err(&hv_dev->device,
			"unhandled message type %d\n", msg_type);
	}
}