summaryrefslogtreecommitdiff
path: root/arch/mips/cavium-octeon/octeon-irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/cavium-octeon/octeon-irq.c')
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c119
1 files changed, 73 insertions, 46 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index f97be32bf699..5c3de175ef5b 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -127,6 +127,16 @@ static void octeon_irq_free_cd(struct irq_domain *d, unsigned int irq)
static int octeon_irq_force_ciu_mapping(struct irq_domain *domain,
int irq, int line, int bit)
{
+ struct device_node *of_node;
+ int ret;
+
+ of_node = irq_domain_get_of_node(domain);
+ if (!of_node)
+ return -EINVAL;
+ ret = irq_alloc_desc_at(irq, of_node_to_nid(of_node));
+ if (ret < 0)
+ return ret;
+
return irq_domain_associate(domain, irq, line << 6 | bit);
}
@@ -263,7 +273,7 @@ static int next_cpu_for_irq(struct irq_data *data)
#ifdef CONFIG_SMP
int cpu;
- struct cpumask *mask = irq_data_get_affinity_mask(data);
+ const struct cpumask *mask = irq_data_get_affinity_mask(data);
int weight = cpumask_weight(mask);
struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data);
@@ -758,7 +768,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
{
int cpu = smp_processor_id();
cpumask_t new_affinity;
- struct cpumask *mask = irq_data_get_affinity_mask(data);
+ const struct cpumask *mask = irq_data_get_affinity_mask(data);
if (!cpumask_test_cpu(cpu, mask))
return;
@@ -1274,13 +1284,13 @@ static int octeon_irq_gpio_map(struct irq_domain *d,
return r;
}
-static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
+static const struct irq_domain_ops octeon_irq_domain_ciu_ops = {
.map = octeon_irq_ciu_map,
.unmap = octeon_irq_free_cd,
.xlate = octeon_irq_ciu_xlat,
};
-static struct irq_domain_ops octeon_irq_domain_gpio_ops = {
+static const struct irq_domain_ops octeon_irq_domain_gpio_ops = {
.map = octeon_irq_gpio_map,
.unmap = octeon_irq_free_cd,
.xlate = octeon_irq_gpio_xlat,
@@ -1405,7 +1415,7 @@ static void octeon_irq_init_ciu2_percpu(void)
* completed.
*
* There are 9 registers and 3 IPX levels with strides 0x1000
- * and 0x200 respectivly. Use loops to clear them.
+ * and 0x200 respectively. Use loops to clear them.
*/
for (regx = 0; regx <= 0x8000; regx += 0x1000) {
for (ipx = 0; ipx <= 0x400; ipx += 0x200)
@@ -1444,7 +1454,7 @@ static void octeon_irq_setup_secondary_ciu2(void)
static int __init octeon_irq_init_ciu(
struct device_node *ciu_node, struct device_node *parent)
{
- unsigned int i, r;
+ int i, r;
struct irq_chip *chip;
struct irq_chip *chip_edge;
struct irq_chip *chip_mbox;
@@ -1493,9 +1503,9 @@ static int __init octeon_irq_init_ciu(
/* Mips internal */
octeon_irq_init_core();
- ciu_domain = irq_domain_add_tree(
- ciu_node, &octeon_irq_domain_ciu_ops, dd);
- irq_set_default_host(ciu_domain);
+ ciu_domain = irq_domain_create_tree(of_fwnode_handle(ciu_node), &octeon_irq_domain_ciu_ops,
+ dd);
+ irq_set_default_domain(ciu_domain);
/* CIU_0 */
for (i = 0; i < 16; i++) {
@@ -1505,10 +1515,20 @@ static int __init octeon_irq_init_ciu(
goto err;
}
+ r = irq_alloc_desc_at(OCTEON_IRQ_MBOX0, -1);
+ if (r < 0) {
+ pr_err("Failed to allocate desc for %s\n", "OCTEON_IRQ_MBOX0");
+ goto err;
+ }
r = octeon_irq_set_ciu_mapping(
OCTEON_IRQ_MBOX0, 0, 32, 0, chip_mbox, handle_percpu_irq);
if (r)
goto err;
+ r = irq_alloc_desc_at(OCTEON_IRQ_MBOX1, -1);
+ if (r < 0) {
+ pr_err("Failed to allocate desc for %s\n", "OCTEON_IRQ_MBOX1");
+ goto err;
+ }
r = octeon_irq_set_ciu_mapping(
OCTEON_IRQ_MBOX1, 0, 33, 0, chip_mbox, handle_percpu_irq);
if (r)
@@ -1546,6 +1566,11 @@ static int __init octeon_irq_init_ciu(
if (r)
goto err;
+ r = irq_alloc_descs(OCTEON_IRQ_WDOG0, OCTEON_IRQ_WDOG0, 16, -1);
+ if (r < 0) {
+ pr_err("Failed to allocate desc for %s\n", "OCTEON_IRQ_WDOGx");
+ goto err;
+ }
/* CIU_1 */
for (i = 0; i < 16; i++) {
r = octeon_irq_set_ciu_mapping(
@@ -1612,8 +1637,8 @@ static int __init octeon_irq_init_gpio(
if (gpiod) {
/* gpio domain host_data is the base hwirq number. */
gpiod->base_hwirq = base_hwirq;
- irq_domain_add_linear(
- gpio_node, 16, &octeon_irq_domain_gpio_ops, gpiod);
+ irq_domain_create_linear(of_fwnode_handle(gpio_node), 16,
+ &octeon_irq_domain_gpio_ops, gpiod);
} else {
pr_warn("Cannot allocate memory for GPIO irq_domain.\n");
return -ENOMEM;
@@ -1959,7 +1984,7 @@ static int octeon_irq_ciu2_map(struct irq_domain *d,
return 0;
}
-static struct irq_domain_ops octeon_irq_domain_ciu2_ops = {
+static const struct irq_domain_ops octeon_irq_domain_ciu2_ops = {
.map = octeon_irq_ciu2_map,
.unmap = octeon_irq_free_cd,
.xlate = octeon_irq_ciu2_xlat,
@@ -2049,9 +2074,9 @@ static int __init octeon_irq_init_ciu2(
/* Mips internal */
octeon_irq_init_core();
- ciu_domain = irq_domain_add_tree(
- ciu_node, &octeon_irq_domain_ciu2_ops, NULL);
- irq_set_default_host(ciu_domain);
+ ciu_domain = irq_domain_create_tree(of_fwnode_handle(ciu_node), &octeon_irq_domain_ciu2_ops,
+ NULL);
+ irq_set_default_domain(ciu_domain);
/* CUI2 */
for (i = 0; i < 64; i++) {
@@ -2193,12 +2218,15 @@ static int octeon_irq_cib_map(struct irq_domain *d,
struct octeon_irq_cib_chip_data *cd;
if (hw >= host_data->max_bits) {
- pr_err("ERROR: %s mapping %u is to big!\n",
+ pr_err("ERROR: %s mapping %u is too big!\n",
irq_domain_get_of_node(d)->name, (unsigned)hw);
return -EINVAL;
}
cd = kzalloc(sizeof(*cd), GFP_KERNEL);
+ if (!cd)
+ return -ENOMEM;
+
cd->host_data = host_data;
cd->bit = hw;
@@ -2208,7 +2236,7 @@ static int octeon_irq_cib_map(struct irq_domain *d,
return 0;
}
-static struct irq_domain_ops octeon_irq_domain_cib_ops = {
+static const struct irq_domain_ops octeon_irq_domain_cib_ops = {
.map = octeon_irq_cib_map,
.unmap = octeon_irq_free_cd,
.xlate = octeon_irq_cib_xlat,
@@ -2262,7 +2290,7 @@ static irqreturn_t octeon_irq_cib_handler(int my_irq, void *data)
static int __init octeon_irq_init_cib(struct device_node *ciu_node,
struct device_node *parent)
{
- const __be32 *addr;
+ struct resource res;
u32 val;
struct octeon_irq_cib_host_data *host_data;
int parent_irq;
@@ -2281,21 +2309,19 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
return -ENOMEM;
raw_spin_lock_init(&host_data->lock);
- addr = of_get_address(ciu_node, 0, NULL, NULL);
- if (!addr) {
+ r = of_address_to_resource(ciu_node, 0, &res);
+ if (r) {
pr_err("ERROR: Couldn't acquire reg(0) %pOFn\n", ciu_node);
- return -EINVAL;
+ return r;
}
- host_data->raw_reg = (u64)phys_to_virt(
- of_translate_address(ciu_node, addr));
+ host_data->raw_reg = (u64)phys_to_virt(res.start);
- addr = of_get_address(ciu_node, 1, NULL, NULL);
- if (!addr) {
+ r = of_address_to_resource(ciu_node, 1, &res);
+ if (r) {
pr_err("ERROR: Couldn't acquire reg(1) %pOFn\n", ciu_node);
- return -EINVAL;
+ return r;
}
- host_data->en_reg = (u64)phys_to_virt(
- of_translate_address(ciu_node, addr));
+ host_data->en_reg = (u64)phys_to_virt(res.start);
r = of_property_read_u32(ciu_node, "cavium,max-bits", &val);
if (r) {
@@ -2305,11 +2331,12 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
}
host_data->max_bits = val;
- cib_domain = irq_domain_add_linear(ciu_node, host_data->max_bits,
- &octeon_irq_domain_cib_ops,
- host_data);
+ cib_domain = irq_domain_create_linear(of_fwnode_handle(ciu_node),
+ host_data->max_bits,
+ &octeon_irq_domain_cib_ops,
+ host_data);
if (!cib_domain) {
- pr_err("ERROR: Couldn't irq_domain_add_linear()\n");
+ pr_err("ERROR: Couldn't irq_domain_create_linear()\n");
return -ENOMEM;
}
@@ -2560,7 +2587,7 @@ static int octeon_irq_ciu3_map(struct irq_domain *d,
return octeon_irq_ciu3_mapx(d, virq, hw, &octeon_irq_chip_ciu3);
}
-static struct irq_domain_ops octeon_dflt_domain_ciu3_ops = {
+static const struct irq_domain_ops octeon_dflt_domain_ciu3_ops = {
.map = octeon_irq_ciu3_map,
.unmap = octeon_irq_free_cd,
.xlate = octeon_irq_ciu3_xlat,
@@ -2591,7 +2618,10 @@ static void octeon_irq_ciu3_ip2(void)
else
hw = intsn;
- ret = handle_domain_irq(domain, hw, NULL);
+ irq_enter();
+ ret = generic_handle_domain_irq(domain, hw);
+ irq_exit();
+
if (ret < 0) {
union cvmx_ciu3_iscx_w1c isc_w1c;
u64 isc_w1c_addr = ciu3_addr + CIU3_ISC_W1C(intsn);
@@ -2843,11 +2873,11 @@ static struct irq_chip octeon_irq_chip_ciu3_mbox = {
static int __init octeon_irq_init_ciu3(struct device_node *ciu_node,
struct device_node *parent)
{
- int i;
+ int i, ret;
int node;
struct irq_domain *domain;
struct octeon_ciu3_info *ciu3_info;
- const __be32 *zero_addr;
+ struct resource res;
u64 base_addr;
union cvmx_ciu3_const consts;
@@ -2857,14 +2887,11 @@ static int __init octeon_irq_init_ciu3(struct device_node *ciu_node,
if (!ciu3_info)
return -ENOMEM;
- zero_addr = of_get_address(ciu_node, 0, NULL, NULL);
- if (WARN_ON(!zero_addr))
- return -EINVAL;
-
- base_addr = of_translate_address(ciu_node, zero_addr);
- base_addr = (u64)phys_to_virt(base_addr);
+ ret = of_address_to_resource(ciu_node, 0, &res);
+ if (WARN_ON(ret))
+ return ret;
- ciu3_info->ciu3_addr = base_addr;
+ ciu3_info->ciu3_addr = base_addr = (u64)phys_to_virt(res.start);
ciu3_info->node = node;
consts.u64 = cvmx_read_csr(base_addr + CIU3_CONST);
@@ -2892,8 +2919,8 @@ static int __init octeon_irq_init_ciu3(struct device_node *ciu_node,
* Initialize all domains to use the default domain. Specific major
* blocks will overwrite the default domain as needed.
*/
- domain = irq_domain_add_tree(ciu_node, &octeon_dflt_domain_ciu3_ops,
- ciu3_info);
+ domain = irq_domain_create_tree(of_fwnode_handle(ciu_node), &octeon_dflt_domain_ciu3_ops,
+ ciu3_info);
for (i = 0; i < MAX_CIU3_DOMAINS; i++)
ciu3_info->domain[i] = domain;
@@ -2903,7 +2930,7 @@ static int __init octeon_irq_init_ciu3(struct device_node *ciu_node,
/* Only do per CPU things if it is the CIU of the boot node. */
octeon_irq_ciu3_alloc_resources(ciu3_info);
if (node == 0)
- irq_set_default_host(domain);
+ irq_set_default_domain(domain);
octeon_irq_use_ip4 = false;
/* Enable the CIU lines */