Skip to content

Commit

Permalink
irq_domain: Create common xlate functions that device drivers can use
Browse files Browse the repository at this point in the history
Rather than having each interrupt controller driver creating its own barely
unique .xlate function for irq_domain, create a library of translators which
any driver can use directly.

v5: - Remove irq_domain_xlate_pci().  It was incorrect.

Signed-off-by: Grant Likely <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Mark Salter <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Milton Miller <[email protected]>
Tested-by: Olof Johansson <[email protected]>
  • Loading branch information
glikely committed Feb 16, 2012
1 parent 6b783f7 commit 16b2e6e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 10 deletions.
12 changes: 12 additions & 0 deletions include/linux/irqdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,18 @@ extern unsigned int irq_linear_revmap(struct irq_domain *host,
irq_hw_number_t hwirq);

extern struct irq_domain_ops irq_domain_simple_ops;

/* stock xlate functions */
int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type);
int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type);
int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type);

#if defined(CONFIG_OF_IRQ)
extern void irq_domain_generate_simple(const struct of_device_id *match,
u64 phys_base, unsigned int irq_start);
Expand Down
65 changes: 55 additions & 10 deletions kernel/irq/irqdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,25 +699,70 @@ int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
return 0;
}

int irq_domain_simple_xlate(struct irq_domain *d,
struct device_node *controller,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type)
/**
* irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
*
* Device Tree IRQ specifier translation function which works with one cell
* bindings where the cell value maps directly to the hwirq number.
*/
int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type)
{
if (d->of_node != controller)
return -EINVAL;
if (intsize < 1)
if (WARN_ON(intsize < 1))
return -EINVAL;
*out_hwirq = intspec[0];
*out_type = IRQ_TYPE_NONE;
if (intsize > 1)
*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
return 0;
}
EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell);

/**
* irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings
*
* Device Tree IRQ specifier translation function which works with two cell
* bindings where the cell values map directly to the hwirq number
* and linux irq flags.
*/
int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_type)
{
if (WARN_ON(intsize < 2))
return -EINVAL;
*out_hwirq = intspec[0];
*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
return 0;
}
EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);

/**
* irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
*
* Device Tree IRQ specifier translation function which works with either one
* or two cell bindings where the cell values map directly to the hwirq number
* and linux irq flags.
*
* Note: don't use this function unless your interrupt controller explicitly
* supports both one and two cell bindings. For the majority of controllers
* the _onecell() or _twocell() variants above should be used.
*/
int irq_domain_xlate_onetwocell(struct irq_domain *d,
struct device_node *ctrlr,
const u32 *intspec, unsigned int intsize,
unsigned long *out_hwirq, unsigned int *out_type)
{
if (WARN_ON(intsize < 1))
return -EINVAL;
*out_hwirq = intspec[0];
*out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE;
return 0;
}
EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell);

struct irq_domain_ops irq_domain_simple_ops = {
.map = irq_domain_simple_map,
.xlate = irq_domain_simple_xlate,
.xlate = irq_domain_xlate_onetwocell,
};
EXPORT_SYMBOL_GPL(irq_domain_simple_ops);

Expand Down

0 comments on commit 16b2e6e

Please sign in to comment.