コード例 #1
0
ファイル: imr.c プロジェクト: Altoyyr/linux
/**
 * imr_write - write an IMR at a given index.
 *
 * Requires caller to hold imr mutex.
 * Note lock bits need to be written independently of address bits.
 *
 * @idev:	pointer to imr_device structure.
 * @imr_id:	IMR entry to write.
 * @imr:	IMR structure representing address and access masks.
 * @lock:	indicates if the IMR lock bit should be applied.
 * @return:	0 on success or error code passed from mbi_iosf on failure.
 */
static int imr_write(struct imr_device *idev, u32 imr_id,
		     struct imr_regs *imr, bool lock)
{
	unsigned long flags;
	u32 reg = imr_id * IMR_NUM_REGS + idev->reg_base;
	int ret;

	local_irq_save(flags);

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_lo);
	if (ret)
		goto failed;

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->addr_hi);
	if (ret)
		goto failed;

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->rmask);
	if (ret)
		goto failed;

	ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE, reg++, imr->wmask);
	if (ret)
		goto failed;

	/* Lock bit must be set separately to addr_lo address bits. */
	if (lock) {
		imr->addr_lo |= IMR_LOCK;
		ret = iosf_mbi_write(QRK_MBI_UNIT_MM, MBI_REG_WRITE,
				     reg - IMR_NUM_REGS, imr->addr_lo);
		if (ret)
			goto failed;
	}

	local_irq_restore(flags);
	return 0;
failed:
	/*
	 * If writing to the IOSF failed then we're in an unknown state,
	 * likely a very bad state. An IMR in an invalid state will almost
	 * certainly lead to a memory access violation.
	 */
	local_irq_restore(flags);
	WARN(ret, "IOSF-MBI write fail range 0x%08x-0x%08x unreliable\n",
	     imr_to_phys(imr->addr_lo), imr_to_phys(imr->addr_hi) + IMR_MASK);

	return ret;
}
コード例 #2
0
ファイル: sdhci-acpi.c プロジェクト: zefie/nxt_andx86_kernel
static void sdhci_acpi_byt_setting(struct device *dev)
{
	u32 val = 0;

	if (!sdhci_acpi_byt())
		return;

	if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0,
			  &val)) {
		dev_err(dev, "%s read error\n", __func__);
		return;
	}

	if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE))
		return;

	val &= ~BYT_IOSF_OCP_TIMEOUT_BASE;

	if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0,
			   val)) {
		dev_err(dev, "%s write error\n", __func__);
		return;
	}

	dev_dbg(dev, "%s completed\n", __func__);
}
コード例 #3
0
static void reset_semaphore(struct device *dev)
{
    u32 data;

    if (iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &data)) {
        dev_err(dev, "iosf failed to reset punit semaphore during read\n");
        return;
    }

    data &= ~PUNIT_SEMAPHORE_BIT;
    if (iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, data))
        dev_err(dev, "iosf failed to reset punit semaphore during write\n");
}
コード例 #4
0
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
{
    u32 sem = PUNIT_SEMAPHORE_ACQUIRE;
    int ret;
    unsigned long start, end;

    might_sleep();

    if (!dev || !dev->dev)
        return -ENODEV;

    if (!dev->release_lock)
        return 0;

    /* host driver writes to side band semaphore register */
    ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, PUNIT_SEMAPHORE, sem);
    if (ret) {
        dev_err(dev->dev, "iosf punit semaphore request failed\n");
        return ret;
    }

    /* host driver waits for bit 0 to be set in semaphore register */
    start = jiffies;
    end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
    do {
        ret = get_sem(dev->dev, &sem);
        if (!ret && sem) {
            acquired = jiffies;
            dev_dbg(dev->dev, "punit semaphore acquired after %ums\n",
                    jiffies_to_msecs(jiffies - start));
            return 0;
        }

        usleep_range(1000, 2000);
    } while (time_before(jiffies, end));

    dev_err(dev->dev, "punit semaphore timed out, resetting\n");
    reset_semaphore(dev->dev);

    ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, PUNIT_SEMAPHORE, &sem);
    if (ret)
        dev_err(dev->dev, "iosf failed to read punit semaphore\n");
    else
        dev_err(dev->dev, "PUNIT SEM: %d\n", sem);

    WARN_ON(1);

    return -ETIMEDOUT;
}
コード例 #5
0
ファイル: i2c-designware-baytrail.c プロジェクト: Lyude/linux
static int baytrail_i2c_acquire(struct dw_i2c_dev *dev)
{
	u32 addr;
	u32 sem = PUNIT_SEMAPHORE_ACQUIRE;
	int ret;
	unsigned long start, end;

	might_sleep();

	if (!dev || !dev->dev)
		return -ENODEV;

	if (!dev->release_lock)
		return 0;

	iosf_mbi_punit_acquire();
	iosf_mbi_call_pmic_bus_access_notifier_chain(MBI_PMIC_BUS_ACCESS_BEGIN,
						     NULL);

	/*
	 * Disallow the CPU to enter C6 or C7 state, entering these states
	 * requires the punit to talk to the pmic and if this happens while
	 * we're holding the semaphore, the SoC hangs.
	 */
	pm_qos_update_request(&dev->pm_qos, 0);

	addr = get_sem_addr(dev);

	/* host driver writes to side band semaphore register */
	ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, addr, sem);
	if (ret) {
		dev_err(dev->dev, "iosf punit semaphore request failed\n");
		goto out;
	}

	/* host driver waits for bit 0 to be set in semaphore register */
	start = jiffies;
	end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
	do {
		ret = get_sem(dev, &sem);
		if (!ret && sem) {
			acquired = jiffies;
			dev_dbg(dev->dev, "punit semaphore acquired after %ums\n",
				jiffies_to_msecs(jiffies - start));
			return 0;
		}

		usleep_range(1000, 2000);
	} while (time_before(jiffies, end));

	dev_err(dev->dev, "punit semaphore timed out, resetting\n");
out:
	reset_semaphore(dev);

	ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, addr, &sem);
	if (ret)
		dev_err(dev->dev, "iosf failed to read punit semaphore\n");
	else
		dev_err(dev->dev, "PUNIT SEM: %d\n", sem);

	WARN_ON(1);

	return -ETIMEDOUT;
}