Source
x
static int altera_freeze_br_do_unfreeze(struct altera_freeze_br_data *priv,
// SPDX-License-Identifier: GPL-2.0
/*
* FPGA Freeze Bridge Controller
*
* Copyright (C) 2016 Altera Corporation. All rights reserved.
*/
struct altera_freeze_br_data {
struct device *dev;
void __iomem *base_addr;
bool enable;
};
/*
* Poll status until status bit is set or we have a timeout.
*/
static int altera_freeze_br_req_ack(struct altera_freeze_br_data *priv,
u32 timeout, u32 req_ack)
{
struct device *dev = priv->dev;
void __iomem *csr_illegal_req_addr = priv->base_addr +
FREEZE_CSR_ILLEGAL_REQ_OFFSET;
u32 status, illegal, ctrl;
int ret = -ETIMEDOUT;
do {
illegal = readl(csr_illegal_req_addr);
if (illegal) {
dev_err(dev, "illegal request detected 0x%x", illegal);
writel(1, csr_illegal_req_addr);
illegal = readl(csr_illegal_req_addr);
if (illegal)
dev_err(dev, "illegal request not cleared 0x%x",
illegal);
ret = -EINVAL;
break;
}
status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
dev_dbg(dev, "%s %x %x\n", __func__, status, req_ack);
status &= req_ack;
if (status) {
ctrl = readl(priv->base_addr + FREEZE_CSR_CTRL_OFFSET);
dev_dbg(dev, "%s request %x acknowledged %x %x\n",
__func__, req_ack, status, ctrl);
ret = 0;
break;
}
udelay(1);
} while (timeout--);
if (ret == -ETIMEDOUT)
dev_err(dev, "%s timeout waiting for 0x%x\n",
__func__, req_ack);
return ret;
}
static int altera_freeze_br_do_freeze(struct altera_freeze_br_data *priv,
u32 timeout)
{
struct device *dev = priv->dev;
void __iomem *csr_ctrl_addr = priv->base_addr +
FREEZE_CSR_CTRL_OFFSET;
u32 status;