net: ipa: support IPA interrupt addresses for IPA v4.7
Starting with IPA v4.7, registers related to IPA interrupts are located at a fixed offset 0x1000 above than the addresses used for earlier versions. Define and use functions to provide the offset to use for these registers based on IPA version. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
cc5199ed50
Коммит
e666aa978a
|
@ -54,12 +54,14 @@ static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id)
|
||||||
bool uc_irq = ipa_interrupt_uc(interrupt, irq_id);
|
bool uc_irq = ipa_interrupt_uc(interrupt, irq_id);
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
u32 mask = BIT(irq_id);
|
u32 mask = BIT(irq_id);
|
||||||
|
u32 offset;
|
||||||
|
|
||||||
/* For microcontroller interrupts, clear the interrupt right away,
|
/* For microcontroller interrupts, clear the interrupt right away,
|
||||||
* "to avoid clearing unhandled interrupts."
|
* "to avoid clearing unhandled interrupts."
|
||||||
*/
|
*/
|
||||||
|
offset = ipa_reg_irq_clr_offset(ipa->version);
|
||||||
if (uc_irq)
|
if (uc_irq)
|
||||||
iowrite32(mask, ipa->reg_virt + IPA_REG_IRQ_CLR_OFFSET);
|
iowrite32(mask, ipa->reg_virt + offset);
|
||||||
|
|
||||||
if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id])
|
if (irq_id < IPA_IRQ_COUNT && interrupt->handler[irq_id])
|
||||||
interrupt->handler[irq_id](interrupt->ipa, irq_id);
|
interrupt->handler[irq_id](interrupt->ipa, irq_id);
|
||||||
|
@ -69,7 +71,7 @@ static void ipa_interrupt_process(struct ipa_interrupt *interrupt, u32 irq_id)
|
||||||
* so defer clearing until after the handler has been called.
|
* so defer clearing until after the handler has been called.
|
||||||
*/
|
*/
|
||||||
if (!uc_irq)
|
if (!uc_irq)
|
||||||
iowrite32(mask, ipa->reg_virt + IPA_REG_IRQ_CLR_OFFSET);
|
iowrite32(mask, ipa->reg_virt + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process all IPA interrupt types that have been signaled */
|
/* Process all IPA interrupt types that have been signaled */
|
||||||
|
@ -77,13 +79,15 @@ static void ipa_interrupt_process_all(struct ipa_interrupt *interrupt)
|
||||||
{
|
{
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
u32 enabled = interrupt->enabled;
|
u32 enabled = interrupt->enabled;
|
||||||
|
u32 offset;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
/* The status register indicates which conditions are present,
|
/* The status register indicates which conditions are present,
|
||||||
* including conditions whose interrupt is not enabled. Handle
|
* including conditions whose interrupt is not enabled. Handle
|
||||||
* only the enabled ones.
|
* only the enabled ones.
|
||||||
*/
|
*/
|
||||||
mask = ioread32(ipa->reg_virt + IPA_REG_IRQ_STTS_OFFSET);
|
offset = ipa_reg_irq_stts_offset(ipa->version);
|
||||||
|
mask = ioread32(ipa->reg_virt + offset);
|
||||||
while ((mask &= enabled)) {
|
while ((mask &= enabled)) {
|
||||||
do {
|
do {
|
||||||
u32 irq_id = __ffs(mask);
|
u32 irq_id = __ffs(mask);
|
||||||
|
@ -92,7 +96,7 @@ static void ipa_interrupt_process_all(struct ipa_interrupt *interrupt)
|
||||||
|
|
||||||
ipa_interrupt_process(interrupt, irq_id);
|
ipa_interrupt_process(interrupt, irq_id);
|
||||||
} while (mask);
|
} while (mask);
|
||||||
mask = ioread32(ipa->reg_virt + IPA_REG_IRQ_STTS_OFFSET);
|
mask = ioread32(ipa->reg_virt + offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,14 +119,17 @@ static irqreturn_t ipa_isr(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct ipa_interrupt *interrupt = dev_id;
|
struct ipa_interrupt *interrupt = dev_id;
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
|
u32 offset;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
mask = ioread32(ipa->reg_virt + IPA_REG_IRQ_STTS_OFFSET);
|
offset = ipa_reg_irq_stts_offset(ipa->version);
|
||||||
|
mask = ioread32(ipa->reg_virt + offset);
|
||||||
if (mask & interrupt->enabled)
|
if (mask & interrupt->enabled)
|
||||||
return IRQ_WAKE_THREAD;
|
return IRQ_WAKE_THREAD;
|
||||||
|
|
||||||
/* Nothing in the mask was supposed to cause an interrupt */
|
/* Nothing in the mask was supposed to cause an interrupt */
|
||||||
iowrite32(mask, ipa->reg_virt + IPA_REG_IRQ_CLR_OFFSET);
|
offset = ipa_reg_irq_clr_offset(ipa->version);
|
||||||
|
iowrite32(mask, ipa->reg_virt + offset);
|
||||||
|
|
||||||
dev_err(&ipa->pdev->dev, "%s: unexpected interrupt, mask 0x%08x\n",
|
dev_err(&ipa->pdev->dev, "%s: unexpected interrupt, mask 0x%08x\n",
|
||||||
__func__, mask);
|
__func__, mask);
|
||||||
|
@ -136,15 +143,22 @@ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt,
|
||||||
{
|
{
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
u32 mask = BIT(endpoint_id);
|
u32 mask = BIT(endpoint_id);
|
||||||
|
u32 offset;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
/* assert(mask & ipa->available); */
|
/* assert(mask & ipa->available); */
|
||||||
val = ioread32(ipa->reg_virt + IPA_REG_IRQ_SUSPEND_EN_OFFSET);
|
|
||||||
|
/* IPA version 3.0 does not support TX_SUSPEND interrupt control */
|
||||||
|
if (ipa->version == IPA_VERSION_3_0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
offset = ipa_reg_irq_suspend_en_offset(ipa->version);
|
||||||
|
val = ioread32(ipa->reg_virt + offset);
|
||||||
if (enable)
|
if (enable)
|
||||||
val |= mask;
|
val |= mask;
|
||||||
else
|
else
|
||||||
val &= ~mask;
|
val &= ~mask;
|
||||||
iowrite32(val, ipa->reg_virt + IPA_REG_IRQ_SUSPEND_EN_OFFSET);
|
iowrite32(val, ipa->reg_virt + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable TX_SUSPEND for an endpoint */
|
/* Enable TX_SUSPEND for an endpoint */
|
||||||
|
@ -165,10 +179,18 @@ ipa_interrupt_suspend_disable(struct ipa_interrupt *interrupt, u32 endpoint_id)
|
||||||
void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt)
|
void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt)
|
||||||
{
|
{
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
|
u32 offset;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
val = ioread32(ipa->reg_virt + IPA_REG_IRQ_SUSPEND_INFO_OFFSET);
|
offset = ipa_reg_irq_suspend_info_offset(ipa->version);
|
||||||
iowrite32(val, ipa->reg_virt + IPA_REG_IRQ_SUSPEND_CLR_OFFSET);
|
val = ioread32(ipa->reg_virt + offset);
|
||||||
|
|
||||||
|
/* SUSPEND interrupt status isn't cleared on IPA version 3.0 */
|
||||||
|
if (ipa->version == IPA_VERSION_3_0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
offset = ipa_reg_irq_suspend_clr_offset(ipa->version);
|
||||||
|
iowrite32(val, ipa->reg_virt + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simulate arrival of an IPA TX_SUSPEND interrupt */
|
/* Simulate arrival of an IPA TX_SUSPEND interrupt */
|
||||||
|
@ -182,13 +204,15 @@ void ipa_interrupt_add(struct ipa_interrupt *interrupt,
|
||||||
enum ipa_irq_id ipa_irq, ipa_irq_handler_t handler)
|
enum ipa_irq_id ipa_irq, ipa_irq_handler_t handler)
|
||||||
{
|
{
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
|
u32 offset;
|
||||||
|
|
||||||
/* assert(ipa_irq < IPA_IRQ_COUNT); */
|
/* assert(ipa_irq < IPA_IRQ_COUNT); */
|
||||||
interrupt->handler[ipa_irq] = handler;
|
interrupt->handler[ipa_irq] = handler;
|
||||||
|
|
||||||
/* Update the IPA interrupt mask to enable it */
|
/* Update the IPA interrupt mask to enable it */
|
||||||
interrupt->enabled |= BIT(ipa_irq);
|
interrupt->enabled |= BIT(ipa_irq);
|
||||||
iowrite32(interrupt->enabled, ipa->reg_virt + IPA_REG_IRQ_EN_OFFSET);
|
offset = ipa_reg_irq_en_offset(ipa->version);
|
||||||
|
iowrite32(interrupt->enabled, ipa->reg_virt + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the handler for an IPA interrupt type */
|
/* Remove the handler for an IPA interrupt type */
|
||||||
|
@ -196,11 +220,13 @@ void
|
||||||
ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq)
|
ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq)
|
||||||
{
|
{
|
||||||
struct ipa *ipa = interrupt->ipa;
|
struct ipa *ipa = interrupt->ipa;
|
||||||
|
u32 offset;
|
||||||
|
|
||||||
/* assert(ipa_irq < IPA_IRQ_COUNT); */
|
/* assert(ipa_irq < IPA_IRQ_COUNT); */
|
||||||
/* Update the IPA interrupt mask to disable it */
|
/* Update the IPA interrupt mask to disable it */
|
||||||
interrupt->enabled &= ~BIT(ipa_irq);
|
interrupt->enabled &= ~BIT(ipa_irq);
|
||||||
iowrite32(interrupt->enabled, ipa->reg_virt + IPA_REG_IRQ_EN_OFFSET);
|
offset = ipa_reg_irq_en_offset(ipa->version);
|
||||||
|
iowrite32(interrupt->enabled, ipa->reg_virt + offset);
|
||||||
|
|
||||||
interrupt->handler[ipa_irq] = NULL;
|
interrupt->handler[ipa_irq] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +237,7 @@ struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa)
|
||||||
struct device *dev = &ipa->pdev->dev;
|
struct device *dev = &ipa->pdev->dev;
|
||||||
struct ipa_interrupt *interrupt;
|
struct ipa_interrupt *interrupt;
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
|
u32 offset;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = platform_get_irq_byname(ipa->pdev, "ipa");
|
ret = platform_get_irq_byname(ipa->pdev, "ipa");
|
||||||
|
@ -228,7 +255,8 @@ struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa)
|
||||||
interrupt->irq = irq;
|
interrupt->irq = irq;
|
||||||
|
|
||||||
/* Start with all IPA interrupts disabled */
|
/* Start with all IPA interrupts disabled */
|
||||||
iowrite32(0, ipa->reg_virt + IPA_REG_IRQ_EN_OFFSET);
|
offset = ipa_reg_irq_en_offset(ipa->version);
|
||||||
|
iowrite32(0, ipa->reg_virt + offset);
|
||||||
|
|
||||||
ret = request_threaded_irq(irq, ipa_isr, ipa_isr_thread, IRQF_ONESHOT,
|
ret = request_threaded_irq(irq, ipa_isr, ipa_isr_thread, IRQF_ONESHOT,
|
||||||
"ipa", interrupt);
|
"ipa", interrupt);
|
||||||
|
|
|
@ -717,20 +717,46 @@ enum ipa_seq_rep_type {
|
||||||
#define ROUTER_HASH_MSK_METADATA_FMASK GENMASK(22, 22)
|
#define ROUTER_HASH_MSK_METADATA_FMASK GENMASK(22, 22)
|
||||||
#define IPA_REG_ENDP_ROUTER_HASH_MSK_ALL GENMASK(22, 16)
|
#define IPA_REG_ENDP_ROUTER_HASH_MSK_ALL GENMASK(22, 16)
|
||||||
|
|
||||||
#define IPA_REG_IRQ_STTS_OFFSET \
|
static inline u32 ipa_reg_irq_stts_ee_n_offset(enum ipa_version version,
|
||||||
IPA_REG_IRQ_STTS_EE_N_OFFSET(GSI_EE_AP)
|
u32 ee)
|
||||||
#define IPA_REG_IRQ_STTS_EE_N_OFFSET(ee) \
|
{
|
||||||
(0x00003008 + 0x1000 * (ee))
|
if (version < IPA_VERSION_4_9)
|
||||||
|
return 0x00003008 + 0x1000 * ee;
|
||||||
|
|
||||||
#define IPA_REG_IRQ_EN_OFFSET \
|
return 0x00004008 + 0x1000 * ee;
|
||||||
IPA_REG_IRQ_EN_EE_N_OFFSET(GSI_EE_AP)
|
}
|
||||||
#define IPA_REG_IRQ_EN_EE_N_OFFSET(ee) \
|
|
||||||
(0x0000300c + 0x1000 * (ee))
|
static inline u32 ipa_reg_irq_stts_offset(enum ipa_version version)
|
||||||
|
{
|
||||||
|
return ipa_reg_irq_stts_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ipa_reg_irq_en_ee_n_offset(enum ipa_version version, u32 ee)
|
||||||
|
{
|
||||||
|
if (version < IPA_VERSION_4_9)
|
||||||
|
return 0x0000300c + 0x1000 * ee;
|
||||||
|
|
||||||
|
return 0x0000400c + 0x1000 * ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ipa_reg_irq_en_offset(enum ipa_version version)
|
||||||
|
{
|
||||||
|
return ipa_reg_irq_en_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ipa_reg_irq_clr_ee_n_offset(enum ipa_version version, u32 ee)
|
||||||
|
{
|
||||||
|
if (version < IPA_VERSION_4_9)
|
||||||
|
return 0x00003010 + 0x1000 * ee;
|
||||||
|
|
||||||
|
return 0x00004010 + 0x1000 * ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ipa_reg_irq_clr_offset(enum ipa_version version)
|
||||||
|
{
|
||||||
|
return ipa_reg_irq_clr_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
#define IPA_REG_IRQ_CLR_OFFSET \
|
|
||||||
IPA_REG_IRQ_CLR_EE_N_OFFSET(GSI_EE_AP)
|
|
||||||
#define IPA_REG_IRQ_CLR_EE_N_OFFSET(ee) \
|
|
||||||
(0x00003010 + 0x1000 * (ee))
|
|
||||||
/**
|
/**
|
||||||
* enum ipa_irq_id - Bit positions representing type of IPA IRQ
|
* enum ipa_irq_id - Bit positions representing type of IPA IRQ
|
||||||
* @IPA_IRQ_UC_0: Microcontroller event interrupt
|
* @IPA_IRQ_UC_0: Microcontroller event interrupt
|
||||||
|
@ -806,32 +832,75 @@ enum ipa_irq_id {
|
||||||
IPA_IRQ_COUNT, /* Last; not an id */
|
IPA_IRQ_COUNT, /* Last; not an id */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IPA_REG_IRQ_UC_OFFSET \
|
static inline u32 ipa_reg_irq_uc_ee_n_offset(enum ipa_version version, u32 ee)
|
||||||
IPA_REG_IRQ_UC_EE_N_OFFSET(GSI_EE_AP)
|
{
|
||||||
#define IPA_REG_IRQ_UC_EE_N_OFFSET(ee) \
|
if (version < IPA_VERSION_4_9)
|
||||||
(0x0000301c + 0x1000 * (ee))
|
return 0x0000301c + 0x1000 * ee;
|
||||||
|
|
||||||
|
return 0x0000401c + 0x1000 * ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ipa_reg_irq_uc_offset(enum ipa_version version)
|
||||||
|
{
|
||||||
|
return ipa_reg_irq_uc_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
#define UC_INTR_FMASK GENMASK(0, 0)
|
#define UC_INTR_FMASK GENMASK(0, 0)
|
||||||
|
|
||||||
/* ipa->available defines the valid bits in the SUSPEND_INFO register */
|
/* ipa->available defines the valid bits in the SUSPEND_INFO register */
|
||||||
#define IPA_REG_IRQ_SUSPEND_INFO_OFFSET \
|
static inline u32
|
||||||
IPA_REG_IRQ_SUSPEND_INFO_EE_N_OFFSET(GSI_EE_AP)
|
ipa_reg_irq_suspend_info_ee_n_offset(enum ipa_version version, u32 ee)
|
||||||
/* This register is at (0x00003098 + 0x1000 * (ee)) for IPA v3.0 */
|
{
|
||||||
#define IPA_REG_IRQ_SUSPEND_INFO_EE_N_OFFSET(ee) \
|
if (version == IPA_VERSION_3_0)
|
||||||
(0x00003030 + 0x1000 * (ee))
|
return 0x00003098 + 0x1000 * ee;
|
||||||
|
|
||||||
/* ipa->available defines the valid bits in the IRQ_SUSPEND_EN register */
|
if (version < IPA_VERSION_4_9)
|
||||||
/* This register is present for IPA v3.1+ */
|
return 0x00003030 + 0x1000 * ee;
|
||||||
#define IPA_REG_IRQ_SUSPEND_EN_OFFSET \
|
|
||||||
IPA_REG_IRQ_SUSPEND_EN_EE_N_OFFSET(GSI_EE_AP)
|
|
||||||
#define IPA_REG_IRQ_SUSPEND_EN_EE_N_OFFSET(ee) \
|
|
||||||
(0x00003034 + 0x1000 * (ee))
|
|
||||||
|
|
||||||
/* ipa->available defines the valid bits in the IRQ_SUSPEND_CLR register */
|
return 0x00004030 + 0x1000 * ee;
|
||||||
/* This register is present for IPA v3.1+ */
|
}
|
||||||
#define IPA_REG_IRQ_SUSPEND_CLR_OFFSET \
|
|
||||||
IPA_REG_IRQ_SUSPEND_CLR_EE_N_OFFSET(GSI_EE_AP)
|
static inline u32
|
||||||
#define IPA_REG_IRQ_SUSPEND_CLR_EE_N_OFFSET(ee) \
|
ipa_reg_irq_suspend_info_offset(enum ipa_version version)
|
||||||
(0x00003038 + 0x1000 * (ee))
|
{
|
||||||
|
return ipa_reg_irq_suspend_info_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ipa->available defines the valid bits in the SUSPEND_EN register */
|
||||||
|
static inline u32
|
||||||
|
ipa_reg_irq_suspend_en_ee_n_offset(enum ipa_version version, u32 ee)
|
||||||
|
{
|
||||||
|
/* assert(version != IPA_VERSION_3_0); */
|
||||||
|
|
||||||
|
if (version < IPA_VERSION_4_9)
|
||||||
|
return 0x00003034 + 0x1000 * ee;
|
||||||
|
|
||||||
|
return 0x00004034 + 0x1000 * ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32
|
||||||
|
ipa_reg_irq_suspend_en_offset(enum ipa_version version)
|
||||||
|
{
|
||||||
|
return ipa_reg_irq_suspend_en_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ipa->available defines the valid bits in the SUSPEND_CLR register */
|
||||||
|
static inline u32
|
||||||
|
ipa_reg_irq_suspend_clr_ee_n_offset(enum ipa_version version, u32 ee)
|
||||||
|
{
|
||||||
|
/* assert(version != IPA_VERSION_3_0); */
|
||||||
|
|
||||||
|
if (version < IPA_VERSION_4_9)
|
||||||
|
return 0x00003038 + 0x1000 * ee;
|
||||||
|
|
||||||
|
return 0x00004038 + 0x1000 * ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32
|
||||||
|
ipa_reg_irq_suspend_clr_offset(enum ipa_version version)
|
||||||
|
{
|
||||||
|
return ipa_reg_irq_suspend_clr_ee_n_offset(version, GSI_EE_AP);
|
||||||
|
}
|
||||||
|
|
||||||
int ipa_reg_init(struct ipa *ipa);
|
int ipa_reg_init(struct ipa *ipa);
|
||||||
void ipa_reg_exit(struct ipa *ipa);
|
void ipa_reg_exit(struct ipa *ipa);
|
||||||
|
|
|
@ -192,6 +192,7 @@ void ipa_uc_teardown(struct ipa *ipa)
|
||||||
static void send_uc_command(struct ipa *ipa, u32 command, u32 command_param)
|
static void send_uc_command(struct ipa *ipa, u32 command, u32 command_param)
|
||||||
{
|
{
|
||||||
struct ipa_uc_mem_area *shared = ipa_uc_shared(ipa);
|
struct ipa_uc_mem_area *shared = ipa_uc_shared(ipa);
|
||||||
|
u32 offset;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
/* Fill in the command data */
|
/* Fill in the command data */
|
||||||
|
@ -203,8 +204,8 @@ static void send_uc_command(struct ipa *ipa, u32 command, u32 command_param)
|
||||||
|
|
||||||
/* Use an interrupt to tell the microcontroller the command is ready */
|
/* Use an interrupt to tell the microcontroller the command is ready */
|
||||||
val = u32_encode_bits(1, UC_INTR_FMASK);
|
val = u32_encode_bits(1, UC_INTR_FMASK);
|
||||||
|
offset = ipa_reg_irq_uc_offset(ipa->version);
|
||||||
iowrite32(val, ipa->reg_virt + IPA_REG_IRQ_UC_OFFSET);
|
iowrite32(val, ipa->reg_virt + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the microcontroller the AP is shutting down */
|
/* Tell the microcontroller the AP is shutting down */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче