Source
static acpi_status count_registers_cb(struct acpi_resource *ares, void *context)
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* Driver for interrupt combiners in the Top-level Control and Status
* Registers (TCSR) hardware block in Qualcomm Technologies chips.
* An interrupt combiner in this block combines a set of interrupts by
* OR'ing the individual interrupt signals into a summary interrupt
* signal routed to a parent interrupt controller, and provides read-
* only, 32-bit registers to query the status of individual interrupts.
* The status bit for IRQ n is bit (n % 32) within register (n / 32)
* of the given combiner. Thus, each combiner can be described as a set
* of register offsets and the number of IRQs managed.
*/
struct combiner_reg {
void __iomem *addr;
unsigned long enabled;
};
struct combiner {
struct irq_domain *domain;
int parent_irq;
u32 nirqs;
u32 nregs;
struct combiner_reg regs[0];
};
static inline int irq_nr(u32 reg, u32 bit)
{
return reg * REG_SIZE + bit;
}
/*
* Handler for the cascaded IRQ.
*/
static void combiner_handle_irq(struct irq_desc *desc)
{
struct combiner *combiner = irq_desc_get_handler_data(desc);
struct irq_chip *chip = irq_desc_get_chip(desc);
u32 reg;
chained_irq_enter(chip, desc);
for (reg = 0; reg < combiner->nregs; reg++) {