Commit 6567954b authored by Bartosz Golaszewski's avatar Bartosz Golaszewski Committed by Sekhar Nori

ARM: davinci: cp-intc: use the new-style config structure

Modify the cp-intc driver to take all its configuration from the new
config structure. Stop referencing davinci_soc_info in any way.
Move the declaration for davinci_cp_intc_init() to
irq-davinci-cp-intc.h and make it take the new config structure as
parameter. Convert all users to the new version.

Also: since the two da8xx SoCs default all irq priorities to 7, just
drop the priority configuration at all and hardcode the channels to 7.

It will simplify the driver code and make our lives easier when it
comes to device-tree support.
Reviewed-by: default avatarDavid Lechner <david@lechnology.com>
Signed-off-by: default avatarBartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: default avatarSekhar Nori <nsekhar@ti.com>
parent 3b5d1c50
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/irqchip/irq-davinci-cp-intc.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -20,7 +21,6 @@ ...@@ -20,7 +21,6 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <asm/exception.h> #include <asm/exception.h>
#include <mach/common.h>
#define DAVINCI_CP_INTC_CTRL 0x04 #define DAVINCI_CP_INTC_CTRL 0x04
#define DAVINCI_CP_INTC_HOST_CTRL 0x0c #define DAVINCI_CP_INTC_HOST_CTRL 0x0c
...@@ -158,22 +158,15 @@ static const struct irq_domain_ops davinci_cp_intc_irq_domain_ops = { ...@@ -158,22 +158,15 @@ static const struct irq_domain_ops davinci_cp_intc_irq_domain_ops = {
.xlate = irq_domain_xlate_onetwocell, .xlate = irq_domain_xlate_onetwocell,
}; };
static int __init davinci_cp_intc_of_init(struct device_node *node, static int __init
struct device_node *parent) davinci_cp_intc_do_init(const struct davinci_cp_intc_config *config,
struct device_node *node)
{ {
u32 num_irq = davinci_soc_info.intc_irq_num; unsigned int num_regs = BITS_TO_LONGS(config->num_irqs);
u8 *irq_prio = davinci_soc_info.intc_irq_prios; int offset, irq_base;
unsigned num_reg = BITS_TO_LONGS(num_irq);
int i, irq_base; davinci_cp_intc_base = ioremap(config->reg.start,
resource_size(&config->reg));
if (node) {
davinci_cp_intc_base = of_iomap(node, 0);
if (of_property_read_u32(node, "ti,intc-size", &num_irq))
pr_warn("unable to get intc-size, default to %d\n",
num_irq);
} else {
davinci_cp_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K);
}
if (WARN_ON(!davinci_cp_intc_base)) if (WARN_ON(!davinci_cp_intc_base))
return -EINVAL; return -EINVAL;
...@@ -183,51 +176,29 @@ static int __init davinci_cp_intc_of_init(struct device_node *node, ...@@ -183,51 +176,29 @@ static int __init davinci_cp_intc_of_init(struct device_node *node,
davinci_cp_intc_write(0, DAVINCI_CP_INTC_HOST_ENABLE(0)); davinci_cp_intc_write(0, DAVINCI_CP_INTC_HOST_ENABLE(0));
/* Disable system interrupts */ /* Disable system interrupts */
for (i = 0; i < num_reg; i++) for (offset = 0; offset < num_regs; offset++)
davinci_cp_intc_write(~0, DAVINCI_CP_INTC_SYS_ENABLE_CLR(i)); davinci_cp_intc_write(~0,
DAVINCI_CP_INTC_SYS_ENABLE_CLR(offset));
/* Set to normal mode, no nesting, no priority hold */ /* Set to normal mode, no nesting, no priority hold */
davinci_cp_intc_write(0, DAVINCI_CP_INTC_CTRL); davinci_cp_intc_write(0, DAVINCI_CP_INTC_CTRL);
davinci_cp_intc_write(0, DAVINCI_CP_INTC_HOST_CTRL); davinci_cp_intc_write(0, DAVINCI_CP_INTC_HOST_CTRL);
/* Clear system interrupt status */ /* Clear system interrupt status */
for (i = 0; i < num_reg; i++) for (offset = 0; offset < num_regs; offset++)
davinci_cp_intc_write(~0, DAVINCI_CP_INTC_SYS_STAT_CLR(i)); davinci_cp_intc_write(~0,
DAVINCI_CP_INTC_SYS_STAT_CLR(offset));
/* Enable nIRQ (what about nFIQ?) */ /* Enable nIRQ (what about nFIQ?) */
davinci_cp_intc_write(1, DAVINCI_CP_INTC_HOST_ENABLE_IDX_SET); davinci_cp_intc_write(1, DAVINCI_CP_INTC_HOST_ENABLE_IDX_SET);
/* /* Default all priorities to channel 7. */
* Priority is determined by host channel: lower channel number has num_regs = (config->num_irqs + 3) >> 2; /* 4 channels per register */
* higher priority i.e. channel 0 has highest priority and channel 31 for (offset = 0; offset < num_regs; offset++)
* had the lowest priority. davinci_cp_intc_write(0x07070707,
*/ DAVINCI_CP_INTC_CHAN_MAP(offset));
num_reg = (num_irq + 3) >> 2; /* 4 channels per register */
if (irq_prio) {
unsigned j, k;
u32 val;
for (k = i = 0; i < num_reg; i++) {
for (val = j = 0; j < 4; j++, k++) {
val >>= 8;
if (k < num_irq)
val |= irq_prio[k] << 24;
}
davinci_cp_intc_write(val, DAVINCI_CP_INTC_CHAN_MAP(i));
}
} else {
/*
* Default everything to channel 15 if priority not specified.
* Note that channel 0-1 are mapped to nFIQ and channels 2-31
* are mapped to nIRQ.
*/
for (i = 0; i < num_reg; i++)
davinci_cp_intc_write(0x0f0f0f0f,
DAVINCI_CP_INTC_CHAN_MAP(i));
}
irq_base = irq_alloc_descs(-1, 0, num_irq, 0); irq_base = irq_alloc_descs(-1, 0, config->num_irqs, 0);
if (irq_base < 0) { if (irq_base < 0) {
pr_warn("Couldn't allocate IRQ numbers\n"); pr_warn("Couldn't allocate IRQ numbers\n");
irq_base = 0; irq_base = 0;
...@@ -235,7 +206,7 @@ static int __init davinci_cp_intc_of_init(struct device_node *node, ...@@ -235,7 +206,7 @@ static int __init davinci_cp_intc_of_init(struct device_node *node,
/* create a legacy host */ /* create a legacy host */
davinci_cp_intc_irq_domain = irq_domain_add_legacy( davinci_cp_intc_irq_domain = irq_domain_add_legacy(
node, num_irq, irq_base, 0, node, config->num_irqs, irq_base, 0,
&davinci_cp_intc_irq_domain_ops, NULL); &davinci_cp_intc_irq_domain_ops, NULL);
if (!davinci_cp_intc_irq_domain) { if (!davinci_cp_intc_irq_domain) {
...@@ -251,9 +222,31 @@ static int __init davinci_cp_intc_of_init(struct device_node *node, ...@@ -251,9 +222,31 @@ static int __init davinci_cp_intc_of_init(struct device_node *node,
return 0; return 0;
} }
void __init davinci_cp_intc_init(void) int __init davinci_cp_intc_init(const struct davinci_cp_intc_config *config)
{ {
davinci_cp_intc_of_init(NULL, NULL); return davinci_cp_intc_do_init(config, NULL);
} }
static int __init davinci_cp_intc_of_init(struct device_node *node,
struct device_node *parent)
{
struct davinci_cp_intc_config config = { };
int ret;
ret = of_address_to_resource(node, 0, &config.reg);
if (ret) {
pr_err("%s: unable to get the register range from device-tree\n",
__func__);
return ret;
}
ret = of_property_read_u32(node, "ti,intc-size", &config.num_irqs);
if (ret) {
pr_err("%s: unable to read the 'ti,intc-size' property\n",
__func__);
return ret;
}
return davinci_cp_intc_do_init(&config, node);
}
IRQCHIP_DECLARE(cp_intc, "ti,cp-intc", davinci_cp_intc_of_init); IRQCHIP_DECLARE(cp_intc, "ti,cp-intc", davinci_cp_intc_of_init);
...@@ -833,7 +833,7 @@ static const struct davinci_cp_intc_config da830_cp_intc_config = { ...@@ -833,7 +833,7 @@ static const struct davinci_cp_intc_config da830_cp_intc_config = {
void __init da830_init_irq(void) void __init da830_init_irq(void)
{ {
davinci_cp_intc_init(); davinci_cp_intc_init(&da830_cp_intc_config);
} }
void __init da830_init_time(void) void __init da830_init_time(void)
......
...@@ -771,7 +771,7 @@ static const struct davinci_cp_intc_config da850_cp_intc_config = { ...@@ -771,7 +771,7 @@ static const struct davinci_cp_intc_config da850_cp_intc_config = {
void __init da850_init_irq(void) void __init da850_init_irq(void)
{ {
davinci_cp_intc_init(); davinci_cp_intc_init(&da850_cp_intc_config);
} }
void __init da850_init_time(void) void __init da850_init_time(void)
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#define DAVINCI_INTC_START NR_IRQS #define DAVINCI_INTC_START NR_IRQS
#define DAVINCI_INTC_IRQ(_irqnum) (DAVINCI_INTC_START + (_irqnum)) #define DAVINCI_INTC_IRQ(_irqnum) (DAVINCI_INTC_START + (_irqnum))
void davinci_cp_intc_init(void);
void davinci_timer_init(struct clk *clk); void davinci_timer_init(struct clk *clk);
struct davinci_timer_instance { struct davinci_timer_instance {
......
...@@ -20,4 +20,6 @@ struct davinci_cp_intc_config { ...@@ -20,4 +20,6 @@ struct davinci_cp_intc_config {
unsigned int num_irqs; unsigned int num_irqs;
}; };
int davinci_cp_intc_init(const struct davinci_cp_intc_config *config);
#endif /* _LINUX_IRQ_DAVINCI_CP_INTC_ */ #endif /* _LINUX_IRQ_DAVINCI_CP_INTC_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment