コード例 #1
0
ファイル: gpio-msic.c プロジェクト: 0x000000FF/edison-linux
static void msic_bus_sync_unlock(struct irq_data *data)
{
	struct msic_gpio *mg = irq_data_get_irq_chip_data(data);
	int offset;
	int reg;
	u8 trig = 0;

	/* We can only get one change at a time as the buslock covers the
	   entire transaction. The irq_desc->lock is dropped before we are
	   called but that is fine */
	if (mg->trig_change_mask) {
		offset = __ffs(mg->trig_change_mask);

		reg = msic_gpio_to_ireg(offset);
		if (reg < 0)
			goto out;

		if (mg->trig_type & IRQ_TYPE_EDGE_RISING)
			trig |= MSIC_GPIO_TRIG_RISE;
		if (mg->trig_type & IRQ_TYPE_EDGE_FALLING)
			trig |= MSIC_GPIO_TRIG_FALL;

		intel_msic_reg_update(reg, trig, MSIC_GPIO_INTCNT_MASK);
		mg->trig_change_mask = 0;
	}
out:
	mutex_unlock(&mg->buslock);
}
コード例 #2
0
ファイル: gpio-msic.c プロジェクト: 0x000000FF/edison-linux
static void msic_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	int reg;

	reg = msic_gpio_to_oreg(offset);
	if (reg < 0)
		return;

	intel_msic_reg_update(reg, !!value , MSIC_GPIO_DOUT_MASK);
}
コード例 #3
0
ファイル: gpio-msic.c プロジェクト: 0x000000FF/edison-linux
static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	int reg;

	reg = msic_gpio_to_oreg(offset);
	if (reg < 0)
		return reg;

	return intel_msic_reg_update(reg, MSIC_GPIO_DIR_IN, MSIC_GPIO_DIR_MASK);
}
コード例 #4
0
static int __devinit mfld_pb_probe(struct platform_device *pdev)
{
	struct input_dev *input;
	int irq = platform_get_irq(pdev, 0);
	int error;

	if (irq < 0)
		return -EINVAL;

	input = input_allocate_device();
	if (!input) {
		dev_err(&pdev->dev, "Input device allocation error\n");
		return -ENOMEM;
	}

	input->name = pdev->name;
	input->phys = "power-button/input0";
	input->id.bustype = BUS_HOST;
	input->dev.parent = &pdev->dev;

	input_set_capability(input, EV_KEY, KEY_POWER);

	error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND,
			DRIVER_NAME, input);
	if (error) {
		dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
				"button\n", irq);
		goto err_free_input;
	}

	error = input_register_device(input);
	if (error) {
		dev_err(&pdev->dev, "Unable to register input dev, error "
				"%d\n", error);
		goto err_free_irq;
	}

	platform_set_drvdata(pdev, input);

	error = intel_msic_reg_update(INTEL_MSIC_IRQLVL1MSK, 0, MSIC_PWRBTNM);
	if (error) {
		dev_err(&pdev->dev, "Unable to clear power button interrupt, "
				"error: %d\n", error);
		goto err_free_irq;
	}

	return 0;

err_free_irq:
	free_irq(irq, input);
err_free_input:
	input_free_device(input);
	return error;
}
コード例 #5
0
ファイル: gpio-msic.c プロジェクト: 0x000000FF/edison-linux
static int msic_gpio_direction_output(struct gpio_chip *chip,
			unsigned offset, int value)
{
	int reg;
	unsigned mask;

	value = (!!value) | MSIC_GPIO_DIR_OUT;
	mask = MSIC_GPIO_DIR_MASK | MSIC_GPIO_DOUT_MASK;

	reg = msic_gpio_to_oreg(offset);
	if (reg < 0)
		return reg;

	return intel_msic_reg_update(reg, value, mask);
}
コード例 #6
0
static int mfld_pb_probe(struct platform_device *pdev)
{
	struct input_dev *input;
	int irq = platform_get_irq(pdev, 0);
	int error;

	if (irq < 0)
		return -EINVAL;

	input = input_allocate_device();
	if (!input) {
		dev_err(&pdev->dev, "Input device allocation error\n");
		return -ENOMEM;
	}

	input->name = pdev->name;
	input->phys = "power-button/input0";
	input->id.bustype = BUS_HOST;
	input->dev.parent = &pdev->dev;

	input_set_capability(input, EV_KEY, KEY_POWER);

	error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND,
			DRIVER_NAME, input);
	if (error) {
		dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
				"button\n", irq);
		goto err_free_input;
	}

	error = input_register_device(input);
	if (error) {
		dev_err(&pdev->dev, "Unable to register input dev, error "
				"%d\n", error);
		goto err_free_irq;
	}

	platform_set_drvdata(pdev, input);

	/*
	 * SCU firmware might send power button interrupts to IA core before
	 * kernel boots and doesn't get EOI from IA core. The first bit of
	 * MSIC reg 0x21 is kept masked, and SCU firmware doesn't send new
	 * power interrupt to Android kernel. Unmask the bit when probing
	 * power button in kernel.
	 * There is a very narrow race between irq handler and power button
	 * initialization. The race happens rarely. So we needn't worry
	 * about it.
	 */
	error = intel_msic_reg_update(INTEL_MSIC_IRQLVL1MSK, 0, MSIC_PWRBTNM);
	if (error) {
		dev_err(&pdev->dev, "Unable to clear power button interrupt, "
				"error: %d\n", error);
		goto err_free_irq;
	}

	return 0;

err_free_irq:
	free_irq(irq, input);
err_free_input:
	input_free_device(input);
	return error;
}