diff options
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 73 |
1 files changed, 66 insertions, 7 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index ef0bc02c3a70..73a2b786b5e9 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -115,12 +115,12 @@ EXPORT_SYMBOL(synchronize_irq); | |||
115 | #ifdef CONFIG_SMP | 115 | #ifdef CONFIG_SMP |
116 | cpumask_var_t irq_default_affinity; | 116 | cpumask_var_t irq_default_affinity; |
117 | 117 | ||
118 | static int __irq_can_set_affinity(struct irq_desc *desc) | 118 | static bool __irq_can_set_affinity(struct irq_desc *desc) |
119 | { | 119 | { |
120 | if (!desc || !irqd_can_balance(&desc->irq_data) || | 120 | if (!desc || !irqd_can_balance(&desc->irq_data) || |
121 | !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity) | 121 | !desc->irq_data.chip || !desc->irq_data.chip->irq_set_affinity) |
122 | return 0; | 122 | return false; |
123 | return 1; | 123 | return true; |
124 | } | 124 | } |
125 | 125 | ||
126 | /** | 126 | /** |
@@ -134,6 +134,21 @@ int irq_can_set_affinity(unsigned int irq) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | /** | 136 | /** |
137 | * irq_can_set_affinity_usr - Check if affinity of a irq can be set from user space | ||
138 | * @irq: Interrupt to check | ||
139 | * | ||
140 | * Like irq_can_set_affinity() above, but additionally checks for the | ||
141 | * AFFINITY_MANAGED flag. | ||
142 | */ | ||
143 | bool irq_can_set_affinity_usr(unsigned int irq) | ||
144 | { | ||
145 | struct irq_desc *desc = irq_to_desc(irq); | ||
146 | |||
147 | return __irq_can_set_affinity(desc) && | ||
148 | !irqd_affinity_is_managed(&desc->irq_data); | ||
149 | } | ||
150 | |||
151 | /** | ||
137 | * irq_set_thread_affinity - Notify irq threads to adjust affinity | 152 | * irq_set_thread_affinity - Notify irq threads to adjust affinity |
138 | * @desc: irq descriptor which has affitnity changed | 153 | * @desc: irq descriptor which has affitnity changed |
139 | * | 154 | * |
@@ -338,10 +353,11 @@ static int setup_affinity(struct irq_desc *desc, struct cpumask *mask) | |||
338 | return 0; | 353 | return 0; |
339 | 354 | ||
340 | /* | 355 | /* |
341 | * Preserve an userspace affinity setup, but make sure that | 356 | * Preserve the managed affinity setting and an userspace affinity |
342 | * one of the targets is online. | 357 | * setup, but make sure that one of the targets is online. |
343 | */ | 358 | */ |
344 | if (irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) { | 359 | if (irqd_affinity_is_managed(&desc->irq_data) || |
360 | irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) { | ||
345 | if (cpumask_intersects(desc->irq_common_data.affinity, | 361 | if (cpumask_intersects(desc->irq_common_data.affinity, |
346 | cpu_online_mask)) | 362 | cpu_online_mask)) |
347 | set = desc->irq_common_data.affinity; | 363 | set = desc->irq_common_data.affinity; |
@@ -1117,6 +1133,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1117 | new->irq = irq; | 1133 | new->irq = irq; |
1118 | 1134 | ||
1119 | /* | 1135 | /* |
1136 | * If the trigger type is not specified by the caller, | ||
1137 | * then use the default for this interrupt. | ||
1138 | */ | ||
1139 | if (!(new->flags & IRQF_TRIGGER_MASK)) | ||
1140 | new->flags |= irqd_get_trigger_type(&desc->irq_data); | ||
1141 | |||
1142 | /* | ||
1120 | * Check whether the interrupt nests into another interrupt | 1143 | * Check whether the interrupt nests into another interrupt |
1121 | * thread. | 1144 | * thread. |
1122 | */ | 1145 | */ |
@@ -1409,10 +1432,18 @@ int setup_irq(unsigned int irq, struct irqaction *act) | |||
1409 | 1432 | ||
1410 | if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc))) | 1433 | if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc))) |
1411 | return -EINVAL; | 1434 | return -EINVAL; |
1435 | |||
1436 | retval = irq_chip_pm_get(&desc->irq_data); | ||
1437 | if (retval < 0) | ||
1438 | return retval; | ||
1439 | |||
1412 | chip_bus_lock(desc); | 1440 | chip_bus_lock(desc); |
1413 | retval = __setup_irq(irq, desc, act); | 1441 | retval = __setup_irq(irq, desc, act); |
1414 | chip_bus_sync_unlock(desc); | 1442 | chip_bus_sync_unlock(desc); |
1415 | 1443 | ||
1444 | if (retval) | ||
1445 | irq_chip_pm_put(&desc->irq_data); | ||
1446 | |||
1416 | return retval; | 1447 | return retval; |
1417 | } | 1448 | } |
1418 | EXPORT_SYMBOL_GPL(setup_irq); | 1449 | EXPORT_SYMBOL_GPL(setup_irq); |
@@ -1506,6 +1537,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id) | |||
1506 | } | 1537 | } |
1507 | } | 1538 | } |
1508 | 1539 | ||
1540 | irq_chip_pm_put(&desc->irq_data); | ||
1509 | module_put(desc->owner); | 1541 | module_put(desc->owner); |
1510 | kfree(action->secondary); | 1542 | kfree(action->secondary); |
1511 | return action; | 1543 | return action; |
@@ -1648,11 +1680,16 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler, | |||
1648 | action->name = devname; | 1680 | action->name = devname; |
1649 | action->dev_id = dev_id; | 1681 | action->dev_id = dev_id; |
1650 | 1682 | ||
1683 | retval = irq_chip_pm_get(&desc->irq_data); | ||
1684 | if (retval < 0) | ||
1685 | return retval; | ||
1686 | |||
1651 | chip_bus_lock(desc); | 1687 | chip_bus_lock(desc); |
1652 | retval = __setup_irq(irq, desc, action); | 1688 | retval = __setup_irq(irq, desc, action); |
1653 | chip_bus_sync_unlock(desc); | 1689 | chip_bus_sync_unlock(desc); |
1654 | 1690 | ||
1655 | if (retval) { | 1691 | if (retval) { |
1692 | irq_chip_pm_put(&desc->irq_data); | ||
1656 | kfree(action->secondary); | 1693 | kfree(action->secondary); |
1657 | kfree(action); | 1694 | kfree(action); |
1658 | } | 1695 | } |
@@ -1730,7 +1767,14 @@ void enable_percpu_irq(unsigned int irq, unsigned int type) | |||
1730 | if (!desc) | 1767 | if (!desc) |
1731 | return; | 1768 | return; |
1732 | 1769 | ||
1770 | /* | ||
1771 | * If the trigger type is not specified by the caller, then | ||
1772 | * use the default for this interrupt. | ||
1773 | */ | ||
1733 | type &= IRQ_TYPE_SENSE_MASK; | 1774 | type &= IRQ_TYPE_SENSE_MASK; |
1775 | if (type == IRQ_TYPE_NONE) | ||
1776 | type = irqd_get_trigger_type(&desc->irq_data); | ||
1777 | |||
1734 | if (type != IRQ_TYPE_NONE) { | 1778 | if (type != IRQ_TYPE_NONE) { |
1735 | int ret; | 1779 | int ret; |
1736 | 1780 | ||
@@ -1822,6 +1866,7 @@ static struct irqaction *__free_percpu_irq(unsigned int irq, void __percpu *dev_ | |||
1822 | 1866 | ||
1823 | unregister_handler_proc(irq, action); | 1867 | unregister_handler_proc(irq, action); |
1824 | 1868 | ||
1869 | irq_chip_pm_put(&desc->irq_data); | ||
1825 | module_put(desc->owner); | 1870 | module_put(desc->owner); |
1826 | return action; | 1871 | return action; |
1827 | 1872 | ||
@@ -1884,10 +1929,18 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act) | |||
1884 | 1929 | ||
1885 | if (!desc || !irq_settings_is_per_cpu_devid(desc)) | 1930 | if (!desc || !irq_settings_is_per_cpu_devid(desc)) |
1886 | return -EINVAL; | 1931 | return -EINVAL; |
1932 | |||
1933 | retval = irq_chip_pm_get(&desc->irq_data); | ||
1934 | if (retval < 0) | ||
1935 | return retval; | ||
1936 | |||
1887 | chip_bus_lock(desc); | 1937 | chip_bus_lock(desc); |
1888 | retval = __setup_irq(irq, desc, act); | 1938 | retval = __setup_irq(irq, desc, act); |
1889 | chip_bus_sync_unlock(desc); | 1939 | chip_bus_sync_unlock(desc); |
1890 | 1940 | ||
1941 | if (retval) | ||
1942 | irq_chip_pm_put(&desc->irq_data); | ||
1943 | |||
1891 | return retval; | 1944 | return retval; |
1892 | } | 1945 | } |
1893 | 1946 | ||
@@ -1931,12 +1984,18 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler, | |||
1931 | action->name = devname; | 1984 | action->name = devname; |
1932 | action->percpu_dev_id = dev_id; | 1985 | action->percpu_dev_id = dev_id; |
1933 | 1986 | ||
1987 | retval = irq_chip_pm_get(&desc->irq_data); | ||
1988 | if (retval < 0) | ||
1989 | return retval; | ||
1990 | |||
1934 | chip_bus_lock(desc); | 1991 | chip_bus_lock(desc); |
1935 | retval = __setup_irq(irq, desc, action); | 1992 | retval = __setup_irq(irq, desc, action); |
1936 | chip_bus_sync_unlock(desc); | 1993 | chip_bus_sync_unlock(desc); |
1937 | 1994 | ||
1938 | if (retval) | 1995 | if (retval) { |
1996 | irq_chip_pm_put(&desc->irq_data); | ||
1939 | kfree(action); | 1997 | kfree(action); |
1998 | } | ||
1940 | 1999 | ||
1941 | return retval; | 2000 | return retval; |
1942 | } | 2001 | } |