Example #1
0
static int stu300_await_event(struct stu300_dev *dev,
				enum stu300_event mr_event)
{
	int ret;

	if (unlikely(irqs_disabled())) {
		
		dev_err(&dev->pdev->dev, "irqs are disabled on this "
			"system!\n");
		return -EIO;
	}

	
	spin_lock_irq(&dev->cmd_issue_lock);
	dev->cmd_err = STU300_ERROR_NONE;
	dev->cmd_event = mr_event;

	init_completion(&dev->cmd_complete);

	
	stu300_irq_enable(dev);

	
	spin_unlock_irq(&dev->cmd_issue_lock);

	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
							STU300_TIMEOUT);
	if (ret < 0) {
		dev_err(&dev->pdev->dev,
		       "wait_for_completion_interruptible_timeout()"
		       "returned %d waiting for event %04x\n", ret, mr_event);
		return ret;
	}

	if (ret == 0) {
		if (mr_event != STU300_EVENT_6) {
			dev_err(&dev->pdev->dev, "controller "
				"timed out waiting for event %d, reinit "
				"hardware\n", mr_event);
			(void) stu300_init_hw(dev);
		}
		return -ETIMEDOUT;
	}

	if (dev->cmd_err != STU300_ERROR_NONE) {
		if (mr_event != STU300_EVENT_6) {
			dev_err(&dev->pdev->dev, "controller "
				"error (await_event) %d waiting for event %d, "
			       "reinit hardware\n", dev->cmd_err, mr_event);
			(void) stu300_init_hw(dev);
		}
		return -EIO;
	}

	return 0;
}
static int stu300_await_event(struct stu300_dev *dev,
				enum stu300_event mr_event)
{
	int ret;

	if (unlikely(irqs_disabled())) {
		/* TODO: implement polling for this case if need be. */
		dev_err(&dev->pdev->dev, "irqs are disabled on this "
			"system!\n");
		return -EIO;
	}

	/* Is it already here? */
	spin_lock_irq(&dev->cmd_issue_lock);
	dev->cmd_err = STU300_ERROR_NONE;
	dev->cmd_event = mr_event;

	init_completion(&dev->cmd_complete);

	/* Turn on the I2C interrupt for current operation */
	stu300_irq_enable(dev);

	/* Unlock the command block and wait for the event to occur */
	spin_unlock_irq(&dev->cmd_issue_lock);

	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
							STU300_TIMEOUT);
	if (ret < 0) {
		dev_err(&dev->pdev->dev,
		       "wait_for_completion_interruptible_timeout()"
		       "returned %d waiting for event %04x\n", ret, mr_event);
		return ret;
	}

	if (ret == 0) {
		if (mr_event != STU300_EVENT_6) {
			dev_err(&dev->pdev->dev, "controller "
				"timed out waiting for event %d, reinit "
				"hardware\n", mr_event);
			(void) stu300_init_hw(dev);
		}
		return -ETIMEDOUT;
	}

	if (dev->cmd_err != STU300_ERROR_NONE) {
		if (mr_event != STU300_EVENT_6) {
			dev_err(&dev->pdev->dev, "controller "
				"error (await_event) %d waiting for event %d, "
			       "reinit hardware\n", dev->cmd_err, mr_event);
			(void) stu300_init_hw(dev);
		}
		return -EIO;
	}

	return 0;
}
Example #3
0
static int stu300_start_and_await_event(struct stu300_dev *dev,
					  u8 cr_value,
					  enum stu300_event mr_event)
{
	int ret;

	if (unlikely(irqs_disabled())) {
		
		WARN(1, "irqs are disabled, cannot poll for event\n");
		return -EIO;
	}

	
	spin_lock_irq(&dev->cmd_issue_lock);
	init_completion(&dev->cmd_complete);
	dev->cmd_err = STU300_ERROR_NONE;
	dev->cmd_event = mr_event;
	spin_unlock_irq(&dev->cmd_issue_lock);

	
	cr_value |= I2C_CR_INTERRUPT_ENABLE;
	stu300_wr8(cr_value, dev->virtbase + I2C_CR);
	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
							STU300_TIMEOUT);
	if (ret < 0) {
		dev_err(&dev->pdev->dev,
		       "wait_for_completion_interruptible_timeout() "
		       "returned %d waiting for event %04x\n", ret, mr_event);
		return ret;
	}

	if (ret == 0) {
		dev_err(&dev->pdev->dev, "controller timed out "
		       "waiting for event %d, reinit hardware\n", mr_event);
		(void) stu300_init_hw(dev);
		return -ETIMEDOUT;
	}

	if (dev->cmd_err != STU300_ERROR_NONE) {
		dev_err(&dev->pdev->dev, "controller (start) "
		       "error %d waiting for event %d, reinit hardware\n",
		       dev->cmd_err, mr_event);
		(void) stu300_init_hw(dev);
		return -EIO;
	}

	return 0;
}
Example #4
0
static int stu300_wait_while_busy(struct stu300_dev *dev)
{
	unsigned long timeout;
	int i;

	for (i = 0; i < BUSY_RELEASE_ATTEMPTS; i++) {
		timeout = jiffies + STU300_TIMEOUT;

		while (!time_after(jiffies, timeout)) {
			
			if ((stu300_r8(dev->virtbase + I2C_SR1) &
			     I2C_SR1_BUSY_IND) == 0)
				return 0;
			msleep(1);
		}

		dev_err(&dev->pdev->dev, "transaction timed out "
			"waiting for device to be free (not busy). "
		       "Attempt: %d\n", i+1);

		dev_err(&dev->pdev->dev, "base address = "
			"0x%08x, reinit hardware\n", (u32) dev->virtbase);

		(void) stu300_init_hw(dev);
	}

	dev_err(&dev->pdev->dev, "giving up after %d attempts "
		"to reset the bus.\n",  BUSY_RELEASE_ATTEMPTS);

	return -ETIMEDOUT;
}