diff options
167 files changed, 1889 insertions, 1672 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 4f3443230d89..edad99abec21 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
| @@ -349,6 +349,7 @@ STAC92HD83* | |||
| 349 | ref Reference board | 349 | ref Reference board |
| 350 | mic-ref Reference board with power management for ports | 350 | mic-ref Reference board with power management for ports |
| 351 | dell-s14 Dell laptop | 351 | dell-s14 Dell laptop |
| 352 | dell-vostro-3500 Dell Vostro 3500 laptop | ||
| 352 | hp HP laptops with (inverted) mute-LED | 353 | hp HP laptops with (inverted) mute-LED |
| 353 | hp-dv7-4000 HP dv-7 4000 | 354 | hp-dv7-4000 HP dv-7 4000 |
| 354 | auto BIOS setup (default) | 355 | auto BIOS setup (default) |
| @@ -92,7 +92,7 @@ always += missing-syscalls | |||
| 92 | targets += missing-syscalls | 92 | targets += missing-syscalls |
| 93 | 93 | ||
| 94 | quiet_cmd_syscalls = CALL $< | 94 | quiet_cmd_syscalls = CALL $< |
| 95 | cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) | 95 | cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) $(missing_syscalls_flags) |
| 96 | 96 | ||
| 97 | missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE | 97 | missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE |
| 98 | $(call cmd,syscalls) | 98 | $(call cmd,syscalls) |
diff --git a/MAINTAINERS b/MAINTAINERS index 4808256446f2..071a99674347 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1106,6 +1106,7 @@ F: drivers/media/video/s5p-fimc/ | |||
| 1106 | ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT | 1106 | ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT |
| 1107 | M: Kyungmin Park <kyungmin.park@samsung.com> | 1107 | M: Kyungmin Park <kyungmin.park@samsung.com> |
| 1108 | M: Kamil Debski <k.debski@samsung.com> | 1108 | M: Kamil Debski <k.debski@samsung.com> |
| 1109 | M: Jeongtae Park <jtp.park@samsung.com> | ||
| 1109 | L: linux-arm-kernel@lists.infradead.org | 1110 | L: linux-arm-kernel@lists.infradead.org |
| 1110 | L: linux-media@vger.kernel.org | 1111 | L: linux-media@vger.kernel.org |
| 1111 | S: Maintained | 1112 | S: Maintained |
| @@ -2342,6 +2343,13 @@ S: Supported | |||
| 2342 | F: drivers/gpu/drm/i915 | 2343 | F: drivers/gpu/drm/i915 |
| 2343 | F: include/drm/i915* | 2344 | F: include/drm/i915* |
| 2344 | 2345 | ||
| 2346 | DRM DRIVERS FOR EXYNOS | ||
| 2347 | M: Inki Dae <inki.dae@samsung.com> | ||
| 2348 | L: dri-devel@lists.freedesktop.org | ||
| 2349 | S: Supported | ||
| 2350 | F: drivers/gpu/drm/exynos | ||
| 2351 | F: include/drm/exynos* | ||
| 2352 | |||
| 2345 | DSCC4 DRIVER | 2353 | DSCC4 DRIVER |
| 2346 | M: Francois Romieu <romieu@fr.zoreil.com> | 2354 | M: Francois Romieu <romieu@fr.zoreil.com> |
| 2347 | L: netdev@vger.kernel.org | 2355 | L: netdev@vger.kernel.org |
| @@ -6122,7 +6130,7 @@ F: sound/ | |||
| 6122 | SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) | 6130 | SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) |
| 6123 | M: Liam Girdwood <lrg@ti.com> | 6131 | M: Liam Girdwood <lrg@ti.com> |
| 6124 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6132 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 6125 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git | 6133 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git |
| 6126 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 6134 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 6127 | W: http://alsa-project.org/main/index.php/ASoC | 6135 | W: http://alsa-project.org/main/index.php/ASoC |
| 6128 | S: Supported | 6136 | S: Supported |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 6c28582fb98f..361d54019bb0 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
| @@ -4,8 +4,8 @@ config M68K | |||
| 4 | select HAVE_IDE | 4 | select HAVE_IDE |
| 5 | select HAVE_AOUT if MMU | 5 | select HAVE_AOUT if MMU |
| 6 | select GENERIC_ATOMIC64 if MMU | 6 | select GENERIC_ATOMIC64 if MMU |
| 7 | select HAVE_GENERIC_HARDIRQS if !MMU | 7 | select HAVE_GENERIC_HARDIRQS |
| 8 | select GENERIC_IRQ_SHOW if !MMU | 8 | select GENERIC_IRQ_SHOW |
| 9 | select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS | 9 | select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS |
| 10 | 10 | ||
| 11 | config RWSEM_GENERIC_SPINLOCK | 11 | config RWSEM_GENERIC_SPINLOCK |
diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus index 8294f0c1785e..3adb499584fb 100644 --- a/arch/m68k/Kconfig.bus +++ b/arch/m68k/Kconfig.bus | |||
| @@ -2,6 +2,15 @@ if MMU | |||
| 2 | 2 | ||
| 3 | comment "Bus Support" | 3 | comment "Bus Support" |
| 4 | 4 | ||
| 5 | config DIO | ||
| 6 | bool "DIO bus support" | ||
| 7 | depends on HP300 | ||
| 8 | default y | ||
| 9 | help | ||
| 10 | Say Y here to enable support for the "DIO" expansion bus used in | ||
| 11 | HP300 machines. If you are using such a system you almost certainly | ||
| 12 | want this. | ||
| 13 | |||
| 5 | config NUBUS | 14 | config NUBUS |
| 6 | bool | 15 | bool |
| 7 | depends on MAC | 16 | depends on MAC |
diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices index d214034be6a6..6033f5d4e67e 100644 --- a/arch/m68k/Kconfig.devices +++ b/arch/m68k/Kconfig.devices | |||
| @@ -24,6 +24,37 @@ config PROC_HARDWARE | |||
| 24 | including the model, CPU, MMU, clock speed, BogoMIPS rating, | 24 | including the model, CPU, MMU, clock speed, BogoMIPS rating, |
| 25 | and memory size. | 25 | and memory size. |
| 26 | 26 | ||
| 27 | config NATFEAT | ||
| 28 | bool "ARAnyM emulator support" | ||
| 29 | depends on ATARI | ||
| 30 | help | ||
| 31 | This option enables support for ARAnyM native features, such as | ||
| 32 | access to a disk image as /dev/hda. | ||
| 33 | |||
| 34 | config NFBLOCK | ||
| 35 | tristate "NatFeat block device support" | ||
| 36 | depends on BLOCK && NATFEAT | ||
| 37 | help | ||
| 38 | Say Y to include support for the ARAnyM NatFeat block device | ||
| 39 | which allows direct access to the hard drives without using | ||
| 40 | the hardware emulation. | ||
| 41 | |||
| 42 | config NFCON | ||
| 43 | tristate "NatFeat console driver" | ||
| 44 | depends on NATFEAT | ||
| 45 | help | ||
| 46 | Say Y to include support for the ARAnyM NatFeat console driver | ||
| 47 | which allows the console output to be redirected to the stderr | ||
| 48 | output of ARAnyM. | ||
| 49 | |||
| 50 | config NFETH | ||
| 51 | tristate "NatFeat Ethernet support" | ||
| 52 | depends on ETHERNET && NATFEAT | ||
| 53 | help | ||
| 54 | Say Y to include support for the ARAnyM NatFeat network device | ||
| 55 | which will emulate a regular ethernet device while presenting an | ||
| 56 | ethertap device to the host system. | ||
| 57 | |||
| 27 | endmenu | 58 | endmenu |
| 28 | 59 | ||
| 29 | menu "Character devices" | 60 | menu "Character devices" |
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index c5b5212cc3f9..47b5f90002ab 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c | |||
| @@ -1,43 +1,15 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code | 2 | * Amiga Linux interrupt handling code |
| 3 | * | 3 | * |
| 4 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
| 5 | * License. See the file COPYING in the main directory of this archive | 5 | * License. See the file COPYING in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | ||
| 8 | * 11/07/96: rewritten interrupt handling, irq lists are exists now only for | ||
| 9 | * this sources where it makes sense (VERTB/PORTS/EXTER) and you must | ||
| 10 | * be careful that dev_id for this sources is unique since this the | ||
| 11 | * only possibility to distinguish between different handlers for | ||
| 12 | * free_irq. irq lists also have different irq flags: | ||
| 13 | * - IRQ_FLG_FAST: handler is inserted at top of list (after other | ||
| 14 | * fast handlers) | ||
| 15 | * - IRQ_FLG_SLOW: handler is inserted at bottom of list and before | ||
| 16 | * they're executed irq level is set to the previous | ||
| 17 | * one, but handlers don't need to be reentrant, if | ||
| 18 | * reentrance occurred, slow handlers will be just | ||
| 19 | * called again. | ||
| 20 | * The whole interrupt handling for CIAs is moved to cia.c | ||
| 21 | * /Roman Zippel | ||
| 22 | * | ||
| 23 | * 07/08/99: rewamp of the interrupt handling - we now have two types of | ||
| 24 | * interrupts, normal and fast handlers, fast handlers being | ||
| 25 | * marked with IRQF_DISABLED and runs with all other interrupts | ||
| 26 | * disabled. Normal interrupts disable their own source but | ||
| 27 | * run with all other interrupt sources enabled. | ||
| 28 | * PORTS and EXTER interrupts are always shared even if the | ||
| 29 | * drivers do not explicitly mark this when calling | ||
| 30 | * request_irq which they really should do. | ||
| 31 | * This is similar to the way interrupts are handled on all | ||
| 32 | * other architectures and makes a ton of sense besides | ||
| 33 | * having the advantage of making it easier to share | ||
| 34 | * drivers. | ||
| 35 | * /Jes | ||
| 36 | */ | 7 | */ |
| 37 | 8 | ||
| 38 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 39 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
| 40 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
| 12 | #include <linux/irq.h> | ||
| 41 | 13 | ||
| 42 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
| 43 | #include <asm/traps.h> | 15 | #include <asm/traps.h> |
| @@ -45,56 +17,6 @@ | |||
| 45 | #include <asm/amigaints.h> | 17 | #include <asm/amigaints.h> |
| 46 | #include <asm/amipcmcia.h> | 18 | #include <asm/amipcmcia.h> |
| 47 | 19 | ||
| 48 | static void amiga_enable_irq(unsigned int irq); | ||
| 49 | static void amiga_disable_irq(unsigned int irq); | ||
| 50 | static irqreturn_t ami_int1(int irq, void *dev_id); | ||
| 51 | static irqreturn_t ami_int3(int irq, void *dev_id); | ||
| 52 | static irqreturn_t ami_int4(int irq, void *dev_id); | ||
| 53 | static irqreturn_t ami_int5(int irq, void *dev_id); | ||
| 54 | |||
| 55 | static struct irq_controller amiga_irq_controller = { | ||
| 56 | .name = "amiga", | ||
| 57 | .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock), | ||
| 58 | .enable = amiga_enable_irq, | ||
| 59 | .disable = amiga_disable_irq, | ||
| 60 | }; | ||
| 61 | |||
| 62 | /* | ||
| 63 | * void amiga_init_IRQ(void) | ||
| 64 | * | ||
| 65 | * Parameters: None | ||
| 66 | * | ||
| 67 | * Returns: Nothing | ||
| 68 | * | ||
| 69 | * This function should be called during kernel startup to initialize | ||
| 70 | * the amiga IRQ handling routines. | ||
| 71 | */ | ||
| 72 | |||
| 73 | void __init amiga_init_IRQ(void) | ||
| 74 | { | ||
| 75 | if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) | ||
| 76 | pr_err("Couldn't register int%d\n", 1); | ||
| 77 | if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) | ||
| 78 | pr_err("Couldn't register int%d\n", 3); | ||
| 79 | if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL)) | ||
| 80 | pr_err("Couldn't register int%d\n", 4); | ||
| 81 | if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) | ||
| 82 | pr_err("Couldn't register int%d\n", 5); | ||
| 83 | |||
| 84 | m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); | ||
| 85 | |||
| 86 | /* turn off PCMCIA interrupts */ | ||
| 87 | if (AMIGAHW_PRESENT(PCMCIA)) | ||
| 88 | gayle.inten = GAYLE_IRQ_IDE; | ||
| 89 | |||
| 90 | /* turn off all interrupts and enable the master interrupt bit */ | ||
| 91 | amiga_custom.intena = 0x7fff; | ||
| 92 | amiga_custom.intreq = 0x7fff; | ||
| 93 | amiga_custom.intena = IF_SETCLR | IF_INTEN; | ||
| 94 | |||
| 95 | cia_init_IRQ(&ciaa_base); | ||
| 96 | cia_init_IRQ(&ciab_base); | ||
| 97 | } | ||
| 98 | 20 | ||
| 99 | /* | 21 | /* |
| 100 | * Enable/disable a particular machine specific interrupt source. | 22 | * Enable/disable a particular machine specific interrupt source. |
| @@ -103,112 +25,150 @@ void __init amiga_init_IRQ(void) | |||
| 103 | * internal data, that may not be changed by the interrupt at the same time. | 25 | * internal data, that may not be changed by the interrupt at the same time. |
| 104 | */ | 26 | */ |
| 105 | 27 | ||
| 106 | static void amiga_enable_irq(unsigned int irq) | 28 | static void amiga_irq_enable(struct irq_data *data) |
| 107 | { | 29 | { |
| 108 | amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); | 30 | amiga_custom.intena = IF_SETCLR | (1 << (data->irq - IRQ_USER)); |
| 109 | } | 31 | } |
| 110 | 32 | ||
| 111 | static void amiga_disable_irq(unsigned int irq) | 33 | static void amiga_irq_disable(struct irq_data *data) |
| 112 | { | 34 | { |
| 113 | amiga_custom.intena = 1 << (irq - IRQ_USER); | 35 | amiga_custom.intena = 1 << (data->irq - IRQ_USER); |
| 114 | } | 36 | } |
| 115 | 37 | ||
| 38 | static struct irq_chip amiga_irq_chip = { | ||
| 39 | .name = "amiga", | ||
| 40 | .irq_enable = amiga_irq_enable, | ||
| 41 | .irq_disable = amiga_irq_disable, | ||
| 42 | }; | ||
| 43 | |||
| 44 | |||
| 116 | /* | 45 | /* |
| 117 | * The builtin Amiga hardware interrupt handlers. | 46 | * The builtin Amiga hardware interrupt handlers. |
| 118 | */ | 47 | */ |
| 119 | 48 | ||
| 120 | static irqreturn_t ami_int1(int irq, void *dev_id) | 49 | static void ami_int1(unsigned int irq, struct irq_desc *desc) |
| 121 | { | 50 | { |
| 122 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | 51 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
| 123 | 52 | ||
| 124 | /* if serial transmit buffer empty, interrupt */ | 53 | /* if serial transmit buffer empty, interrupt */ |
| 125 | if (ints & IF_TBE) { | 54 | if (ints & IF_TBE) { |
| 126 | amiga_custom.intreq = IF_TBE; | 55 | amiga_custom.intreq = IF_TBE; |
| 127 | m68k_handle_int(IRQ_AMIGA_TBE); | 56 | generic_handle_irq(IRQ_AMIGA_TBE); |
| 128 | } | 57 | } |
| 129 | 58 | ||
| 130 | /* if floppy disk transfer complete, interrupt */ | 59 | /* if floppy disk transfer complete, interrupt */ |
| 131 | if (ints & IF_DSKBLK) { | 60 | if (ints & IF_DSKBLK) { |
| 132 | amiga_custom.intreq = IF_DSKBLK; | 61 | amiga_custom.intreq = IF_DSKBLK; |
| 133 | m68k_handle_int(IRQ_AMIGA_DSKBLK); | 62 | generic_handle_irq(IRQ_AMIGA_DSKBLK); |
| 134 | } | 63 | } |
| 135 | 64 | ||
| 136 | /* if software interrupt set, interrupt */ | 65 | /* if software interrupt set, interrupt */ |
| 137 | if (ints & IF_SOFT) { | 66 | if (ints & IF_SOFT) { |
| 138 | amiga_custom.intreq = IF_SOFT; | 67 | amiga_custom.intreq = IF_SOFT; |
| 139 | m68k_handle_int(IRQ_AMIGA_SOFT); | 68 | generic_handle_irq(IRQ_AMIGA_SOFT); |
| 140 | } | 69 | } |
| 141 | return IRQ_HANDLED; | ||
| 142 | } | 70 | } |
| 143 | 71 | ||
| 144 | static irqreturn_t ami_int3(int irq, void *dev_id) | 72 | static void ami_int3(unsigned int irq, struct irq_desc *desc) |
| 145 | { | 73 | { |
| 146 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | 74 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
| 147 | 75 | ||
| 148 | /* if a blitter interrupt */ | 76 | /* if a blitter interrupt */ |
| 149 | if (ints & IF_BLIT) { | 77 | if (ints & IF_BLIT) { |
| 150 | amiga_custom.intreq = IF_BLIT; | 78 | amiga_custom.intreq = IF_BLIT; |
| 151 | m68k_handle_int(IRQ_AMIGA_BLIT); | 79 | generic_handle_irq(IRQ_AMIGA_BLIT); |
| 152 | } | 80 | } |
| 153 | 81 | ||
| 154 | /* if a copper interrupt */ | 82 | /* if a copper interrupt */ |
| 155 | if (ints & IF_COPER) { | 83 | if (ints & IF_COPER) { |
| 156 | amiga_custom.intreq = IF_COPER; | 84 | amiga_custom.intreq = IF_COPER; |
| 157 | m68k_handle_int(IRQ_AMIGA_COPPER); | 85 | generic_handle_irq(IRQ_AMIGA_COPPER); |
| 158 | } | 86 | } |
| 159 | 87 | ||
| 160 | /* if a vertical blank interrupt */ | 88 | /* if a vertical blank interrupt */ |
| 161 | if (ints & IF_VERTB) { | 89 | if (ints & IF_VERTB) { |
| 162 | amiga_custom.intreq = IF_VERTB; | 90 | amiga_custom.intreq = IF_VERTB; |
| 163 | m68k_handle_int(IRQ_AMIGA_VERTB); | 91 | generic_handle_irq(IRQ_AMIGA_VERTB); |
| 164 | } | 92 | } |
| 165 | return IRQ_HANDLED; | ||
| 166 | } | 93 | } |
| 167 | 94 | ||
| 168 | static irqreturn_t ami_int4(int irq, void *dev_id) | 95 | static void ami_int4(unsigned int irq, struct irq_desc *desc) |
| 169 | { | 96 | { |
| 170 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | 97 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
| 171 | 98 | ||
| 172 | /* if audio 0 interrupt */ | 99 | /* if audio 0 interrupt */ |
| 173 | if (ints & IF_AUD0) { | 100 | if (ints & IF_AUD0) { |
| 174 | amiga_custom.intreq = IF_AUD0; | 101 | amiga_custom.intreq = IF_AUD0; |
| 175 | m68k_handle_int(IRQ_AMIGA_AUD0); | 102 | generic_handle_irq(IRQ_AMIGA_AUD0); |
| 176 | } | 103 | } |
| 177 | 104 | ||
| 178 | /* if audio 1 interrupt */ | 105 | /* if audio 1 interrupt */ |
| 179 | if (ints & IF_AUD1) { | 106 | if (ints & IF_AUD1) { |
| 180 | amiga_custom.intreq = IF_AUD1; | 107 | amiga_custom.intreq = IF_AUD1; |
| 181 | m68k_handle_int(IRQ_AMIGA_AUD1); | 108 | generic_handle_irq(IRQ_AMIGA_AUD1); |
| 182 | } | 109 | } |
| 183 | 110 | ||
| 184 | /* if audio 2 interrupt */ | 111 | /* if audio 2 interrupt */ |
| 185 | if (ints & IF_AUD2) { | 112 | if (ints & IF_AUD2) { |
| 186 | amiga_custom.intreq = IF_AUD2; | 113 | amiga_custom.intreq = IF_AUD2; |
| 187 | m68k_handle_int(IRQ_AMIGA_AUD2); | 114 | generic_handle_irq(IRQ_AMIGA_AUD2); |
| 188 | } | 115 | } |
| 189 | 116 | ||
| 190 | /* if audio 3 interrupt */ | 117 | /* if audio 3 interrupt */ |
| 191 | if (ints & IF_AUD3) { | 118 | if (ints & IF_AUD3) { |
| 192 | amiga_custom.intreq = IF_AUD3; | 119 | amiga_custom.intreq = IF_AUD3; |
| 193 | m68k_handle_int(IRQ_AMIGA_AUD3); | 120 | generic_handle_irq(IRQ_AMIGA_AUD3); |
| 194 | } | 121 | } |
| 195 | return IRQ_HANDLED; | ||
| 196 | } | 122 | } |
| 197 | 123 | ||
| 198 | static irqreturn_t ami_int5(int irq, void *dev_id) | 124 | static void ami_int5(unsigned int irq, struct irq_desc *desc) |
| 199 | { | 125 | { |
| 200 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; | 126 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
| 201 | 127 | ||
| 202 | /* if serial receive buffer full interrupt */ | 128 | /* if serial receive buffer full interrupt */ |
| 203 | if (ints & IF_RBF) { | 129 | if (ints & IF_RBF) { |
| 204 | /* acknowledge of IF_RBF must be done by the serial interrupt */ | 130 | /* acknowledge of IF_RBF must be done by the serial interrupt */ |
| 205 | m68k_handle_int(IRQ_AMIGA_RBF); | 131 | generic_handle_irq(IRQ_AMIGA_RBF); |
| 206 | } | 132 | } |
| 207 | 133 | ||
| 208 | /* if a disk sync interrupt */ | 134 | /* if a disk sync interrupt */ |
| 209 | if (ints & IF_DSKSYN) { | 135 | if (ints & IF_DSKSYN) { |
| 210 | amiga_custom.intreq = IF_DSKSYN; | 136 | amiga_custom.intreq = IF_DSKSYN; |
| 211 | m68k_handle_int(IRQ_AMIGA_DSKSYN); | 137 | generic_handle_irq(IRQ_AMIGA_DSKSYN); |
| 212 | } | 138 | } |
| 213 | return IRQ_HANDLED; | 139 | } |
| 140 | |||
| 141 | |||
| 142 | /* | ||
| 143 | * void amiga_init_IRQ(void) | ||
| 144 | * | ||
| 145 | * Parameters: None | ||
| 146 | * | ||
| 147 | * Returns: Nothing | ||
| 148 | * | ||
| 149 | * This function should be called during kernel startup to initialize | ||
| 150 | * the amiga IRQ handling routines. | ||
| 151 | */ | ||
| 152 | |||
| 153 | void __init amiga_init_IRQ(void) | ||
| 154 | { | ||
| 155 | m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, | ||
| 156 | AMI_STD_IRQS); | ||
| 157 | |||
| 158 | irq_set_chained_handler(IRQ_AUTO_1, ami_int1); | ||
| 159 | irq_set_chained_handler(IRQ_AUTO_3, ami_int3); | ||
| 160 | irq_set_chained_handler(IRQ_AUTO_4, ami_int4); | ||
| 161 | irq_set_chained_handler(IRQ_AUTO_5, ami_int5); | ||
| 162 | |||
| 163 | /* turn off PCMCIA interrupts */ | ||
| 164 | if (AMIGAHW_PRESENT(PCMCIA)) | ||
| 165 | gayle.inten = GAYLE_IRQ_IDE; | ||
| 166 | |||
| 167 | /* turn off all interrupts and enable the master interrupt bit */ | ||
| 168 | amiga_custom.intena = 0x7fff; | ||
| 169 | amiga_custom.intreq = 0x7fff; | ||
| 170 | amiga_custom.intena = IF_SETCLR | IF_INTEN; | ||
| 171 | |||
| 172 | cia_init_IRQ(&ciaa_base); | ||
| 173 | cia_init_IRQ(&ciab_base); | ||
| 214 | } | 174 | } |
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index ecd0f7ca6f0e..18c0e29976e3 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c | |||
| @@ -93,13 +93,14 @@ static irqreturn_t cia_handler(int irq, void *dev_id) | |||
| 93 | amiga_custom.intreq = base->int_mask; | 93 | amiga_custom.intreq = base->int_mask; |
| 94 | for (; ints; mach_irq++, ints >>= 1) { | 94 | for (; ints; mach_irq++, ints >>= 1) { |
| 95 | if (ints & 1) | 95 | if (ints & 1) |
| 96 | m68k_handle_int(mach_irq); | 96 | generic_handle_irq(mach_irq); |
| 97 | } | 97 | } |
| 98 | return IRQ_HANDLED; | 98 | return IRQ_HANDLED; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static void cia_enable_irq(unsigned int irq) | 101 | static void cia_irq_enable(struct irq_data *data) |
| 102 | { | 102 | { |
| 103 | unsigned int irq = data->irq; | ||
| 103 | unsigned char mask; | 104 | unsigned char mask; |
| 104 | 105 | ||
| 105 | if (irq >= IRQ_AMIGA_CIAB) { | 106 | if (irq >= IRQ_AMIGA_CIAB) { |
| @@ -113,19 +114,20 @@ static void cia_enable_irq(unsigned int irq) | |||
| 113 | } | 114 | } |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | static void cia_disable_irq(unsigned int irq) | 117 | static void cia_irq_disable(struct irq_data *data) |
| 117 | { | 118 | { |
| 119 | unsigned int irq = data->irq; | ||
| 120 | |||
| 118 | if (irq >= IRQ_AMIGA_CIAB) | 121 | if (irq >= IRQ_AMIGA_CIAB) |
| 119 | cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); | 122 | cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); |
| 120 | else | 123 | else |
| 121 | cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); | 124 | cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); |
| 122 | } | 125 | } |
| 123 | 126 | ||
| 124 | static struct irq_controller cia_irq_controller = { | 127 | static struct irq_chip cia_irq_chip = { |
| 125 | .name = "cia", | 128 | .name = "cia", |
| 126 | .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock), | 129 | .irq_enable = cia_irq_enable, |
| 127 | .enable = cia_enable_irq, | 130 | .irq_disable = cia_irq_disable, |
| 128 | .disable = cia_disable_irq, | ||
| 129 | }; | 131 | }; |
| 130 | 132 | ||
| 131 | /* | 133 | /* |
| @@ -134,9 +136,9 @@ static struct irq_controller cia_irq_controller = { | |||
| 134 | * into this chain. | 136 | * into this chain. |
| 135 | */ | 137 | */ |
| 136 | 138 | ||
| 137 | static void auto_enable_irq(unsigned int irq) | 139 | static void auto_irq_enable(struct irq_data *data) |
| 138 | { | 140 | { |
| 139 | switch (irq) { | 141 | switch (data->irq) { |
| 140 | case IRQ_AUTO_2: | 142 | case IRQ_AUTO_2: |
| 141 | amiga_custom.intena = IF_SETCLR | IF_PORTS; | 143 | amiga_custom.intena = IF_SETCLR | IF_PORTS; |
| 142 | break; | 144 | break; |
| @@ -146,9 +148,9 @@ static void auto_enable_irq(unsigned int irq) | |||
| 146 | } | 148 | } |
| 147 | } | 149 | } |
| 148 | 150 | ||
| 149 | static void auto_disable_irq(unsigned int irq) | 151 | static void auto_irq_disable(struct irq_data *data) |
| 150 | { | 152 | { |
| 151 | switch (irq) { | 153 | switch (data->irq) { |
| 152 | case IRQ_AUTO_2: | 154 | case IRQ_AUTO_2: |
| 153 | amiga_custom.intena = IF_PORTS; | 155 | amiga_custom.intena = IF_PORTS; |
| 154 | break; | 156 | break; |
| @@ -158,24 +160,25 @@ static void auto_disable_irq(unsigned int irq) | |||
| 158 | } | 160 | } |
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | static struct irq_controller auto_irq_controller = { | 163 | static struct irq_chip auto_irq_chip = { |
| 162 | .name = "auto", | 164 | .name = "auto", |
| 163 | .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), | 165 | .irq_enable = auto_irq_enable, |
| 164 | .enable = auto_enable_irq, | 166 | .irq_disable = auto_irq_disable, |
| 165 | .disable = auto_disable_irq, | ||
| 166 | }; | 167 | }; |
| 167 | 168 | ||
| 168 | void __init cia_init_IRQ(struct ciabase *base) | 169 | void __init cia_init_IRQ(struct ciabase *base) |
| 169 | { | 170 | { |
| 170 | m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); | 171 | m68k_setup_irq_controller(&cia_irq_chip, handle_simple_irq, |
| 172 | base->cia_irq, CIA_IRQS); | ||
| 171 | 173 | ||
| 172 | /* clear any pending interrupt and turn off all interrupts */ | 174 | /* clear any pending interrupt and turn off all interrupts */ |
| 173 | cia_set_irq(base, CIA_ICR_ALL); | 175 | cia_set_irq(base, CIA_ICR_ALL); |
| 174 | cia_able_irq(base, CIA_ICR_ALL); | 176 | cia_able_irq(base, CIA_ICR_ALL); |
| 175 | 177 | ||
| 176 | /* override auto int and install CIA handler */ | 178 | /* override auto int and install CIA handler */ |
| 177 | m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); | 179 | m68k_setup_irq_controller(&auto_irq_chip, handle_simple_irq, |
| 178 | m68k_irq_startup(base->handler_irq); | 180 | base->handler_irq, 1); |
| 181 | m68k_irq_startup_irq(base->handler_irq); | ||
| 179 | if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, | 182 | if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, |
| 180 | base->name, base)) | 183 | base->name, base)) |
| 181 | pr_err("Couldn't register %s interrupt\n", base->name); | 184 | pr_err("Couldn't register %s interrupt\n", base->name); |
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 5d47f3aa3810..17be1e7e2df2 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c | |||
| @@ -1,19 +1,13 @@ | |||
| 1 | #include <linux/interrupt.h> | 1 | #include <linux/interrupt.h> |
| 2 | #include <linux/irq.h> | ||
| 2 | 3 | ||
| 3 | #include <asm/irq.h> | ||
| 4 | #include <asm/traps.h> | 4 | #include <asm/traps.h> |
| 5 | #include <asm/apollohw.h> | 5 | #include <asm/apollohw.h> |
| 6 | 6 | ||
| 7 | void dn_process_int(unsigned int irq, struct pt_regs *fp) | 7 | unsigned int apollo_irq_startup(struct irq_data *data) |
| 8 | { | 8 | { |
| 9 | __m68k_handle_int(irq, fp); | 9 | unsigned int irq = data->irq; |
| 10 | 10 | ||
| 11 | *(volatile unsigned char *)(pica)=0x20; | ||
| 12 | *(volatile unsigned char *)(picb)=0x20; | ||
| 13 | } | ||
| 14 | |||
| 15 | int apollo_irq_startup(unsigned int irq) | ||
| 16 | { | ||
| 17 | if (irq < 8) | 11 | if (irq < 8) |
| 18 | *(volatile unsigned char *)(pica+1) &= ~(1 << irq); | 12 | *(volatile unsigned char *)(pica+1) &= ~(1 << irq); |
| 19 | else | 13 | else |
| @@ -21,24 +15,33 @@ int apollo_irq_startup(unsigned int irq) | |||
| 21 | return 0; | 15 | return 0; |
| 22 | } | 16 | } |
| 23 | 17 | ||
| 24 | void apollo_irq_shutdown(unsigned int irq) | 18 | void apollo_irq_shutdown(struct irq_data *data) |
| 25 | { | 19 | { |
| 20 | unsigned int irq = data->irq; | ||
| 21 | |||
| 26 | if (irq < 8) | 22 | if (irq < 8) |
| 27 | *(volatile unsigned char *)(pica+1) |= (1 << irq); | 23 | *(volatile unsigned char *)(pica+1) |= (1 << irq); |
| 28 | else | 24 | else |
| 29 | *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); | 25 | *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); |
| 30 | } | 26 | } |
| 31 | 27 | ||
| 32 | static struct irq_controller apollo_irq_controller = { | 28 | void apollo_irq_eoi(struct irq_data *data) |
| 29 | { | ||
| 30 | *(volatile unsigned char *)(pica) = 0x20; | ||
| 31 | *(volatile unsigned char *)(picb) = 0x20; | ||
| 32 | } | ||
| 33 | |||
| 34 | static struct irq_chip apollo_irq_chip = { | ||
| 33 | .name = "apollo", | 35 | .name = "apollo", |
| 34 | .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock), | 36 | .irq_startup = apollo_irq_startup, |
| 35 | .startup = apollo_irq_startup, | 37 | .irq_shutdown = apollo_irq_shutdown, |
| 36 | .shutdown = apollo_irq_shutdown, | 38 | .irq_eoi = apollo_irq_eoi, |
| 37 | }; | 39 | }; |
| 38 | 40 | ||
| 39 | 41 | ||
| 40 | void __init dn_init_IRQ(void) | 42 | void __init dn_init_IRQ(void) |
| 41 | { | 43 | { |
| 42 | m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); | 44 | m68k_setup_user_interrupt(VEC_USER + 96, 16); |
| 43 | m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); | 45 | m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq, |
| 46 | IRQ_APOLLO, 16); | ||
| 44 | } | 47 | } |
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 26a804e67bce..6d196dadfdbc 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c | |||
| @@ -60,243 +60,7 @@ | |||
| 60 | * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP, | 60 | * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP, |
| 61 | * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can | 61 | * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can |
| 62 | * be allocated by atari_register_vme_int(). | 62 | * be allocated by atari_register_vme_int(). |
| 63 | * | ||
| 64 | * Each interrupt can be of three types: | ||
| 65 | * | ||
| 66 | * - SLOW: The handler runs with all interrupts enabled, except the one it | ||
| 67 | * was called by (to avoid reentering). This should be the usual method. | ||
| 68 | * But it is currently possible only for MFP ints, since only the MFP | ||
| 69 | * offers an easy way to mask interrupts. | ||
| 70 | * | ||
| 71 | * - FAST: The handler runs with all interrupts disabled. This should be used | ||
| 72 | * only for really fast handlers, that just do actions immediately | ||
| 73 | * necessary, and let the rest do a bottom half or task queue. | ||
| 74 | * | ||
| 75 | * - PRIORITIZED: The handler can be interrupted by higher-level ints | ||
| 76 | * (greater IPL, no MFP priorities!). This is the method of choice for ints | ||
| 77 | * which should be slow, but are not from a MFP. | ||
| 78 | * | ||
| 79 | * The feature of more than one handler for one int source is still there, but | ||
| 80 | * only applicable if all handers are of the same type. To not slow down | ||
| 81 | * processing of ints with only one handler by the chaining feature, the list | ||
| 82 | * calling function atari_call_irq_list() is only plugged in at the time the | ||
| 83 | * second handler is registered. | ||
| 84 | * | ||
| 85 | * Implementation notes: For fast-as-possible int handling, there are separate | ||
| 86 | * entry points for each type (slow/fast/prio). The assembler handler calls | ||
| 87 | * the irq directly in the usual case, no C wrapper is involved. In case of | ||
| 88 | * multiple handlers, atari_call_irq_list() is registered as handler and calls | ||
| 89 | * in turn the real irq's. To ease access from assembler level to the irq | ||
| 90 | * function pointer and accompanying data, these two are stored in a separate | ||
| 91 | * array, irq_handler[]. The rest of data (type, name) are put into a second | ||
| 92 | * array, irq_param, that is accessed from C only. For each slow interrupt (32 | ||
| 93 | * in all) there are separate handler functions, which makes it possible to | ||
| 94 | * hard-code the MFP register address and value, are necessary to mask the | ||
| 95 | * int. If there'd be only one generic function, lots of calculations would be | ||
| 96 | * needed to determine MFP register and int mask from the vector number :-( | ||
| 97 | * | ||
| 98 | * Furthermore, slow ints may not lower the IPL below its previous value | ||
| 99 | * (before the int happened). This is needed so that an int of class PRIO, on | ||
| 100 | * that this int may be stacked, cannot be reentered. This feature is | ||
| 101 | * implemented as follows: If the stack frame format is 1 (throwaway), the int | ||
| 102 | * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level | ||
| 103 | * 2, which still blocks the HSYNC, but no interrupts of interest. If the | ||
| 104 | * frame format is 0, the int is nested, and the old IPL value can be found in | ||
| 105 | * the sr copy in the frame. | ||
| 106 | */ | ||
| 107 | |||
| 108 | #if 0 | ||
| 109 | |||
| 110 | #define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES) | ||
| 111 | |||
| 112 | typedef void (*asm_irq_handler)(void); | ||
| 113 | |||
| 114 | struct irqhandler { | ||
| 115 | irqreturn_t (*handler)(int, void *, struct pt_regs *); | ||
| 116 | void *dev_id; | ||
| 117 | }; | ||
| 118 | |||
| 119 | struct irqparam { | ||
| 120 | unsigned long flags; | ||
| 121 | const char *devname; | ||
| 122 | }; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Array with irq's and their parameter data. This array is accessed from low | ||
| 126 | * level assembler code, so an element size of 8 allows usage of index scaling | ||
| 127 | * addressing mode. | ||
| 128 | */ | 63 | */ |
| 129 | static struct irqhandler irq_handler[NUM_INT_SOURCES]; | ||
| 130 | |||
| 131 | /* | ||
| 132 | * This array hold the rest of parameters of int handlers: type | ||
| 133 | * (slow,fast,prio) and the name of the handler. These values are only | ||
| 134 | * accessed from C | ||
| 135 | */ | ||
| 136 | static struct irqparam irq_param[NUM_INT_SOURCES]; | ||
| 137 | |||
| 138 | /* check for valid int number (complex, sigh...) */ | ||
| 139 | #define IS_VALID_INTNO(n) \ | ||
| 140 | ((n) > 0 && \ | ||
| 141 | /* autovec and ST-MFP ok anyway */ \ | ||
| 142 | (((n) < TTMFP_SOURCE_BASE) || \ | ||
| 143 | /* TT-MFP ok if present */ \ | ||
| 144 | ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE && \ | ||
| 145 | ATARIHW_PRESENT(TT_MFP)) || \ | ||
| 146 | /* SCC ok if present and number even */ \ | ||
| 147 | ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE && \ | ||
| 148 | !((n) & 1) && ATARIHW_PRESENT(SCC)) || \ | ||
| 149 | /* greater numbers ok if they are registered VME vectors */ \ | ||
| 150 | ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \ | ||
| 151 | free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE))))) | ||
| 152 | |||
| 153 | |||
| 154 | /* | ||
| 155 | * Here start the assembler entry points for interrupts | ||
| 156 | */ | ||
| 157 | |||
| 158 | #define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void) | ||
| 159 | |||
| 160 | #define BUILD_SLOW_IRQ(n) \ | ||
| 161 | asmlinkage void IRQ_NAME(n); \ | ||
| 162 | /* Dummy function to allow asm with operands. */ \ | ||
| 163 | void atari_slow_irq_##n##_dummy (void) { \ | ||
| 164 | __asm__ (__ALIGN_STR "\n" \ | ||
| 165 | "atari_slow_irq_" #n "_handler:\t" \ | ||
| 166 | " addl %6,%5\n" /* preempt_count() += HARDIRQ_OFFSET */ \ | ||
| 167 | SAVE_ALL_INT "\n" \ | ||
| 168 | GET_CURRENT(%%d0) "\n" \ | ||
| 169 | " andb #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */ \ | ||
| 170 | /* get old IPL from stack frame */ \ | ||
| 171 | " bfextu %%sp@(%c2){#5,#3},%%d0\n" \ | ||
| 172 | " movew %%sr,%%d1\n" \ | ||
| 173 | " bfins %%d0,%%d1{#21,#3}\n" \ | ||
| 174 | " movew %%d1,%%sr\n" /* set IPL = previous value */ \ | ||
| 175 | " addql #1,%a0\n" \ | ||
| 176 | " lea %a1,%%a0\n" \ | ||
| 177 | " pea %%sp@\n" /* push addr of frame */ \ | ||
| 178 | " movel %%a0@(4),%%sp@-\n" /* push handler data */ \ | ||
| 179 | " pea (%c3+8)\n" /* push int number */ \ | ||
| 180 | " movel %%a0@,%%a0\n" \ | ||
| 181 | " jbsr %%a0@\n" /* call the handler */ \ | ||
| 182 | " addql #8,%%sp\n" \ | ||
| 183 | " addql #4,%%sp\n" \ | ||
| 184 | " orw #0x0600,%%sr\n" \ | ||
| 185 | " andw #0xfeff,%%sr\n" /* set IPL = 6 again */ \ | ||
| 186 | " orb #(1<<(%c3&7)),%a4:w\n" /* now unmask the int again */ \ | ||
| 187 | " jbra ret_from_interrupt\n" \ | ||
| 188 | : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \ | ||
| 189 | "n" (PT_OFF_SR), "n" (n), \ | ||
| 190 | "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \ | ||
| 191 | : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \ | ||
| 192 | "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \ | ||
| 193 | ); \ | ||
| 194 | for (;;); /* fake noreturn */ \ | ||
| 195 | } | ||
| 196 | |||
| 197 | BUILD_SLOW_IRQ(0); | ||
| 198 | BUILD_SLOW_IRQ(1); | ||
| 199 | BUILD_SLOW_IRQ(2); | ||
| 200 | BUILD_SLOW_IRQ(3); | ||
| 201 | BUILD_SLOW_IRQ(4); | ||
| 202 | BUILD_SLOW_IRQ(5); | ||
| 203 | BUILD_SLOW_IRQ(6); | ||
| 204 | BUILD_SLOW_IRQ(7); | ||
| 205 | BUILD_SLOW_IRQ(8); | ||
| 206 | BUILD_SLOW_IRQ(9); | ||
| 207 | BUILD_SLOW_IRQ(10); | ||
| 208 | BUILD_SLOW_IRQ(11); | ||
| 209 | BUILD_SLOW_IRQ(12); | ||
| 210 | BUILD_SLOW_IRQ(13); | ||
| 211 | BUILD_SLOW_IRQ(14); | ||
| 212 | BUILD_SLOW_IRQ(15); | ||
| 213 | BUILD_SLOW_IRQ(16); | ||
| 214 | BUILD_SLOW_IRQ(17); | ||
| 215 | BUILD_SLOW_IRQ(18); | ||
| 216 | BUILD_SLOW_IRQ(19); | ||
| 217 | BUILD_SLOW_IRQ(20); | ||
| 218 | BUILD_SLOW_IRQ(21); | ||
| 219 | BUILD_SLOW_IRQ(22); | ||
| 220 | BUILD_SLOW_IRQ(23); | ||
| 221 | BUILD_SLOW_IRQ(24); | ||
| 222 | BUILD_SLOW_IRQ(25); | ||
| 223 | BUILD_SLOW_IRQ(26); | ||
| 224 | BUILD_SLOW_IRQ(27); | ||
| 225 | BUILD_SLOW_IRQ(28); | ||
| 226 | BUILD_SLOW_IRQ(29); | ||
| 227 | BUILD_SLOW_IRQ(30); | ||
| 228 | BUILD_SLOW_IRQ(31); | ||
| 229 | |||
| 230 | asm_irq_handler slow_handlers[32] = { | ||
| 231 | [0] = atari_slow_irq_0_handler, | ||
| 232 | [1] = atari_slow_irq_1_handler, | ||
| 233 | [2] = atari_slow_irq_2_handler, | ||
| 234 | [3] = atari_slow_irq_3_handler, | ||
| 235 | [4] = atari_slow_irq_4_handler, | ||
| 236 | [5] = atari_slow_irq_5_handler, | ||
| 237 | [6] = atari_slow_irq_6_handler, | ||
| 238 | [7] = atari_slow_irq_7_handler, | ||
| 239 | [8] = atari_slow_irq_8_handler, | ||
| 240 | [9] = atari_slow_irq_9_handler, | ||
| 241 | [10] = atari_slow_irq_10_handler, | ||
| 242 | [11] = atari_slow_irq_11_handler, | ||
| 243 | [12] = atari_slow_irq_12_handler, | ||
| 244 | [13] = atari_slow_irq_13_handler, | ||
| 245 | [14] = atari_slow_irq_14_handler, | ||
| 246 | [15] = atari_slow_irq_15_handler, | ||
| 247 | [16] = atari_slow_irq_16_handler, | ||
| 248 | [17] = atari_slow_irq_17_handler, | ||
| 249 | [18] = atari_slow_irq_18_handler, | ||
| 250 | [19] = atari_slow_irq_19_handler, | ||
| 251 | [20] = atari_slow_irq_20_handler, | ||
| 252 | [21] = atari_slow_irq_21_handler, | ||
| 253 | [22] = atari_slow_irq_22_handler, | ||
| 254 | [23] = atari_slow_irq_23_handler, | ||
| 255 | [24] = atari_slow_irq_24_handler, | ||
| 256 | [25] = atari_slow_irq_25_handler, | ||
| 257 | [26] = atari_slow_irq_26_handler, | ||
| 258 | [27] = atari_slow_irq_27_handler, | ||
| 259 | [28] = atari_slow_irq_28_handler, | ||
| 260 | [29] = atari_slow_irq_29_handler, | ||
| 261 | [30] = atari_slow_irq_30_handler, | ||
| 262 | [31] = atari_slow_irq_31_handler | ||
| 263 | }; | ||
| 264 | |||
| 265 | asmlinkage void atari_fast_irq_handler( void ); | ||
| 266 | asmlinkage void atari_prio_irq_handler( void ); | ||
| 267 | |||
| 268 | /* Dummy function to allow asm with operands. */ | ||
| 269 | void atari_fast_prio_irq_dummy (void) { | ||
| 270 | __asm__ (__ALIGN_STR "\n" | ||
| 271 | "atari_fast_irq_handler:\n\t" | ||
| 272 | "orw #0x700,%%sr\n" /* disable all interrupts */ | ||
| 273 | "atari_prio_irq_handler:\n\t" | ||
| 274 | "addl %3,%2\n\t" /* preempt_count() += HARDIRQ_OFFSET */ | ||
| 275 | SAVE_ALL_INT "\n\t" | ||
| 276 | GET_CURRENT(%%d0) "\n\t" | ||
| 277 | /* get vector number from stack frame and convert to source */ | ||
| 278 | "bfextu %%sp@(%c1){#4,#10},%%d0\n\t" | ||
| 279 | "subw #(0x40-8),%%d0\n\t" | ||
| 280 | "jpl 1f\n\t" | ||
| 281 | "addw #(0x40-8-0x18),%%d0\n" | ||
| 282 | "1:\tlea %a0,%%a0\n\t" | ||
| 283 | "addql #1,%%a0@(%%d0:l:4)\n\t" | ||
| 284 | "lea irq_handler,%%a0\n\t" | ||
| 285 | "lea %%a0@(%%d0:l:8),%%a0\n\t" | ||
| 286 | "pea %%sp@\n\t" /* push frame address */ | ||
| 287 | "movel %%a0@(4),%%sp@-\n\t" /* push handler data */ | ||
| 288 | "movel %%d0,%%sp@-\n\t" /* push int number */ | ||
| 289 | "movel %%a0@,%%a0\n\t" | ||
| 290 | "jsr %%a0@\n\t" /* and call the handler */ | ||
| 291 | "addql #8,%%sp\n\t" | ||
| 292 | "addql #4,%%sp\n\t" | ||
| 293 | "jbra ret_from_interrupt" | ||
| 294 | : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC), | ||
| 295 | "m" (preempt_count()), "di" (HARDIRQ_OFFSET) | ||
| 296 | ); | ||
| 297 | for (;;); | ||
| 298 | } | ||
| 299 | #endif | ||
| 300 | 64 | ||
| 301 | /* | 65 | /* |
| 302 | * Bitmap for free interrupt vector numbers | 66 | * Bitmap for free interrupt vector numbers |
| @@ -320,31 +84,44 @@ extern void atari_microwire_cmd(int cmd); | |||
| 320 | 84 | ||
| 321 | extern int atari_SCC_reset_done; | 85 | extern int atari_SCC_reset_done; |
| 322 | 86 | ||
| 323 | static int atari_startup_irq(unsigned int irq) | 87 | static unsigned int atari_irq_startup(struct irq_data *data) |
| 324 | { | 88 | { |
| 325 | m68k_irq_startup(irq); | 89 | unsigned int irq = data->irq; |
| 90 | |||
| 91 | m68k_irq_startup(data); | ||
| 326 | atari_turnon_irq(irq); | 92 | atari_turnon_irq(irq); |
| 327 | atari_enable_irq(irq); | 93 | atari_enable_irq(irq); |
| 328 | return 0; | 94 | return 0; |
| 329 | } | 95 | } |
| 330 | 96 | ||
| 331 | static void atari_shutdown_irq(unsigned int irq) | 97 | static void atari_irq_shutdown(struct irq_data *data) |
| 332 | { | 98 | { |
| 99 | unsigned int irq = data->irq; | ||
| 100 | |||
| 333 | atari_disable_irq(irq); | 101 | atari_disable_irq(irq); |
| 334 | atari_turnoff_irq(irq); | 102 | atari_turnoff_irq(irq); |
| 335 | m68k_irq_shutdown(irq); | 103 | m68k_irq_shutdown(data); |
| 336 | 104 | ||
| 337 | if (irq == IRQ_AUTO_4) | 105 | if (irq == IRQ_AUTO_4) |
| 338 | vectors[VEC_INT4] = falcon_hblhandler; | 106 | vectors[VEC_INT4] = falcon_hblhandler; |
| 339 | } | 107 | } |
| 340 | 108 | ||
| 341 | static struct irq_controller atari_irq_controller = { | 109 | static void atari_irq_enable(struct irq_data *data) |
| 110 | { | ||
| 111 | atari_enable_irq(data->irq); | ||
| 112 | } | ||
| 113 | |||
| 114 | static void atari_irq_disable(struct irq_data *data) | ||
| 115 | { | ||
| 116 | atari_disable_irq(data->irq); | ||
| 117 | } | ||
| 118 | |||
| 119 | static struct irq_chip atari_irq_chip = { | ||
| 342 | .name = "atari", | 120 | .name = "atari", |
| 343 | .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock), | 121 | .irq_startup = atari_irq_startup, |
| 344 | .startup = atari_startup_irq, | 122 | .irq_shutdown = atari_irq_shutdown, |
| 345 | .shutdown = atari_shutdown_irq, | 123 | .irq_enable = atari_irq_enable, |
| 346 | .enable = atari_enable_irq, | 124 | .irq_disable = atari_irq_disable, |
| 347 | .disable = atari_disable_irq, | ||
| 348 | }; | 125 | }; |
| 349 | 126 | ||
| 350 | /* | 127 | /* |
| @@ -360,8 +137,9 @@ static struct irq_controller atari_irq_controller = { | |||
| 360 | 137 | ||
| 361 | void __init atari_init_IRQ(void) | 138 | void __init atari_init_IRQ(void) |
| 362 | { | 139 | { |
| 363 | m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); | 140 | m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER); |
| 364 | m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); | 141 | m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1, |
| 142 | NUM_ATARI_SOURCES - 1); | ||
| 365 | 143 | ||
| 366 | /* Initialize the MFP(s) */ | 144 | /* Initialize the MFP(s) */ |
| 367 | 145 | ||
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index 1edd95095cb4..81286476f740 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c | |||
| @@ -86,7 +86,7 @@ static void bvme6000_get_model(char *model) | |||
| 86 | */ | 86 | */ |
| 87 | static void __init bvme6000_init_IRQ(void) | 87 | static void __init bvme6000_init_IRQ(void) |
| 88 | { | 88 | { |
| 89 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); | 89 | m68k_setup_user_interrupt(VEC_USER, 192); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void __init config_bvme6000(void) | 92 | void __init config_bvme6000(void) |
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c index f6312c7d8727..c87fe69b0728 100644 --- a/arch/m68k/hp300/time.c +++ b/arch/m68k/hp300/time.c | |||
| @@ -70,7 +70,7 @@ void __init hp300_sched_init(irq_handler_t vector) | |||
| 70 | 70 | ||
| 71 | asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); | 71 | asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); |
| 72 | 72 | ||
| 73 | if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector)) | 73 | if (request_irq(IRQ_AUTO_6, hp300_tick, 0, "timer tick", vector)) |
| 74 | pr_err("Couldn't register timer interrupt\n"); | 74 | pr_err("Couldn't register timer interrupt\n"); |
| 75 | 75 | ||
| 76 | out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ | 76 | out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ |
diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h index 870e5347155b..db30ed276878 100644 --- a/arch/m68k/include/asm/hardirq.h +++ b/arch/m68k/include/asm/hardirq.h | |||
| @@ -18,6 +18,11 @@ | |||
| 18 | 18 | ||
| 19 | #ifdef CONFIG_MMU | 19 | #ifdef CONFIG_MMU |
| 20 | 20 | ||
| 21 | static inline void ack_bad_irq(unsigned int irq) | ||
| 22 | { | ||
| 23 | pr_crit("unexpected IRQ trap at vector %02x\n", irq); | ||
| 24 | } | ||
| 25 | |||
| 21 | /* entry.S is sensitive to the offsets of these fields */ | 26 | /* entry.S is sensitive to the offsets of these fields */ |
| 22 | typedef struct { | 27 | typedef struct { |
| 23 | unsigned int __softirq_pending; | 28 | unsigned int __softirq_pending; |
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 69ed0d74d532..6198df5ff245 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h | |||
| @@ -27,11 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | #ifdef CONFIG_MMU | 28 | #ifdef CONFIG_MMU |
| 29 | 29 | ||
| 30 | #include <linux/linkage.h> | ||
| 31 | #include <linux/hardirq.h> | ||
| 32 | #include <linux/irqreturn.h> | ||
| 33 | #include <linux/spinlock_types.h> | ||
| 34 | |||
| 35 | /* | 30 | /* |
| 36 | * Interrupt source definitions | 31 | * Interrupt source definitions |
| 37 | * General interrupt sources are the level 1-7. | 32 | * General interrupt sources are the level 1-7. |
| @@ -54,10 +49,6 @@ | |||
| 54 | 49 | ||
| 55 | #define IRQ_USER 8 | 50 | #define IRQ_USER 8 |
| 56 | 51 | ||
| 57 | extern unsigned int irq_canonicalize(unsigned int irq); | ||
| 58 | |||
| 59 | struct pt_regs; | ||
| 60 | |||
| 61 | /* | 52 | /* |
| 62 | * various flags for request_irq() - the Amiga now uses the standard | 53 | * various flags for request_irq() - the Amiga now uses the standard |
| 63 | * mechanism like all other architectures - IRQF_DISABLED and | 54 | * mechanism like all other architectures - IRQF_DISABLED and |
| @@ -71,57 +62,27 @@ struct pt_regs; | |||
| 71 | #define IRQ_FLG_STD (0x8000) /* internally used */ | 62 | #define IRQ_FLG_STD (0x8000) /* internally used */ |
| 72 | #endif | 63 | #endif |
| 73 | 64 | ||
| 74 | /* | 65 | struct irq_data; |
| 75 | * This structure is used to chain together the ISRs for a particular | 66 | struct irq_chip; |
| 76 | * interrupt source (if it supports chaining). | 67 | struct irq_desc; |
| 77 | */ | 68 | extern unsigned int m68k_irq_startup(struct irq_data *data); |
| 78 | typedef struct irq_node { | 69 | extern unsigned int m68k_irq_startup_irq(unsigned int irq); |
| 79 | irqreturn_t (*handler)(int, void *); | 70 | extern void m68k_irq_shutdown(struct irq_data *data); |
| 80 | void *dev_id; | 71 | extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, |
| 81 | struct irq_node *next; | 72 | struct pt_regs *)); |
| 82 | unsigned long flags; | 73 | extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt); |
| 83 | const char *devname; | 74 | extern void m68k_setup_irq_controller(struct irq_chip *, |
| 84 | } irq_node_t; | 75 | void (*handle)(unsigned int irq, |
| 85 | 76 | struct irq_desc *desc), | |
| 86 | /* | 77 | unsigned int irq, unsigned int cnt); |
| 87 | * This structure has only 4 elements for speed reasons | ||
| 88 | */ | ||
| 89 | struct irq_handler { | ||
| 90 | int (*handler)(int, void *); | ||
| 91 | unsigned long flags; | ||
| 92 | void *dev_id; | ||
| 93 | const char *devname; | ||
| 94 | }; | ||
| 95 | |||
| 96 | struct irq_controller { | ||
| 97 | const char *name; | ||
| 98 | spinlock_t lock; | ||
| 99 | int (*startup)(unsigned int irq); | ||
| 100 | void (*shutdown)(unsigned int irq); | ||
| 101 | void (*enable)(unsigned int irq); | ||
| 102 | void (*disable)(unsigned int irq); | ||
| 103 | }; | ||
| 104 | |||
| 105 | extern int m68k_irq_startup(unsigned int); | ||
| 106 | extern void m68k_irq_shutdown(unsigned int); | ||
| 107 | |||
| 108 | /* | ||
| 109 | * This function returns a new irq_node_t | ||
| 110 | */ | ||
| 111 | extern irq_node_t *new_irq_node(void); | ||
| 112 | 78 | ||
| 113 | extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); | 79 | extern unsigned int irq_canonicalize(unsigned int irq); |
| 114 | extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, | ||
| 115 | void (*handler)(unsigned int, struct pt_regs *)); | ||
| 116 | extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); | ||
| 117 | |||
| 118 | asmlinkage void m68k_handle_int(unsigned int); | ||
| 119 | asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); | ||
| 120 | 80 | ||
| 121 | #else | 81 | #else |
| 122 | #define irq_canonicalize(irq) (irq) | 82 | #define irq_canonicalize(irq) (irq) |
| 123 | #endif /* CONFIG_MMU */ | 83 | #endif /* CONFIG_MMU */ |
| 124 | 84 | ||
| 125 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs); | 85 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs); |
| 86 | extern atomic_t irq_err_count; | ||
| 126 | 87 | ||
| 127 | #endif /* _M68K_IRQ_H_ */ | 88 | #endif /* _M68K_IRQ_H_ */ |
diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h index c2a1c5eac1a6..12ebe43b008b 100644 --- a/arch/m68k/include/asm/macintosh.h +++ b/arch/m68k/include/asm/macintosh.h | |||
| @@ -12,6 +12,8 @@ extern void mac_reset(void); | |||
| 12 | extern void mac_poweroff(void); | 12 | extern void mac_poweroff(void); |
| 13 | extern void mac_init_IRQ(void); | 13 | extern void mac_init_IRQ(void); |
| 14 | extern int mac_irq_pending(unsigned int); | 14 | extern int mac_irq_pending(unsigned int); |
| 15 | extern void mac_irq_enable(struct irq_data *data); | ||
| 16 | extern void mac_irq_disable(struct irq_data *data); | ||
| 15 | 17 | ||
| 16 | /* | 18 | /* |
| 17 | * Floppy driver magic hook - probably shouldn't be here | 19 | * Floppy driver magic hook - probably shouldn't be here |
diff --git a/arch/m68k/include/asm/q40ints.h b/arch/m68k/include/asm/q40ints.h index 3d970afb708f..22f12c9eb910 100644 --- a/arch/m68k/include/asm/q40ints.h +++ b/arch/m68k/include/asm/q40ints.h | |||
| @@ -24,6 +24,3 @@ | |||
| 24 | #define Q40_IRQ10_MASK (1<<5) | 24 | #define Q40_IRQ10_MASK (1<<5) |
| 25 | #define Q40_IRQ14_MASK (1<<6) | 25 | #define Q40_IRQ14_MASK (1<<6) |
| 26 | #define Q40_IRQ15_MASK (1<<7) | 26 | #define Q40_IRQ15_MASK (1<<7) |
| 27 | |||
| 28 | extern unsigned long q40_probe_irq_on (void); | ||
| 29 | extern int q40_probe_irq_off (unsigned long irqs); | ||
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index e7f0f2e5ad44..c5696193281a 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile | |||
| @@ -6,16 +6,15 @@ extra-$(CONFIG_MMU) := head.o | |||
| 6 | extra-$(CONFIG_SUN3) := sun3-head.o | 6 | extra-$(CONFIG_SUN3) := sun3-head.o |
| 7 | extra-y += vmlinux.lds | 7 | extra-y += vmlinux.lds |
| 8 | 8 | ||
| 9 | obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \ | 9 | obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o setup.o \ |
| 10 | sys_m68k.o syscalltable.o time.o traps.o | 10 | signal.o sys_m68k.o syscalltable.o time.o traps.o |
| 11 | 11 | ||
| 12 | obj-$(CONFIG_MMU) += ints.o devres.o vectors.o | 12 | obj-$(CONFIG_MMU) += ints.o vectors.o |
| 13 | devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o | ||
| 14 | 13 | ||
| 15 | ifndef CONFIG_MMU_SUN3 | 14 | ifndef CONFIG_MMU_SUN3 |
| 16 | obj-y += dma.o | 15 | obj-y += dma.o |
| 17 | endif | 16 | endif |
| 18 | ifndef CONFIG_MMU | 17 | ifndef CONFIG_MMU |
| 19 | obj-y += init_task.o irq.o | 18 | obj-y += init_task.o |
| 20 | endif | 19 | endif |
| 21 | 20 | ||
diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S index bd0ec05263b2..c713f514843d 100644 --- a/arch/m68k/kernel/entry_mm.S +++ b/arch/m68k/kernel/entry_mm.S | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | .globl sys_fork, sys_clone, sys_vfork | 48 | .globl sys_fork, sys_clone, sys_vfork |
| 49 | .globl ret_from_interrupt, bad_interrupt | 49 | .globl ret_from_interrupt, bad_interrupt |
| 50 | .globl auto_irqhandler_fixup | 50 | .globl auto_irqhandler_fixup |
| 51 | .globl user_irqvec_fixup, user_irqhandler_fixup | 51 | .globl user_irqvec_fixup |
| 52 | 52 | ||
| 53 | .text | 53 | .text |
| 54 | ENTRY(buserr) | 54 | ENTRY(buserr) |
| @@ -207,7 +207,7 @@ ENTRY(auto_inthandler) | |||
| 207 | movel %sp,%sp@- | 207 | movel %sp,%sp@- |
| 208 | movel %d0,%sp@- | put vector # on stack | 208 | movel %d0,%sp@- | put vector # on stack |
| 209 | auto_irqhandler_fixup = . + 2 | 209 | auto_irqhandler_fixup = . + 2 |
| 210 | jsr __m68k_handle_int | process the IRQ | 210 | jsr do_IRQ | process the IRQ |
| 211 | addql #8,%sp | pop parameters off stack | 211 | addql #8,%sp | pop parameters off stack |
| 212 | 212 | ||
| 213 | ret_from_interrupt: | 213 | ret_from_interrupt: |
| @@ -240,8 +240,7 @@ user_irqvec_fixup = . + 2 | |||
| 240 | 240 | ||
| 241 | movel %sp,%sp@- | 241 | movel %sp,%sp@- |
| 242 | movel %d0,%sp@- | put vector # on stack | 242 | movel %d0,%sp@- | put vector # on stack |
| 243 | user_irqhandler_fixup = . + 2 | 243 | jsr do_IRQ | process the IRQ |
| 244 | jsr __m68k_handle_int | process the IRQ | ||
| 245 | addql #8,%sp | pop parameters off stack | 244 | addql #8,%sp | pop parameters off stack |
| 246 | 245 | ||
| 247 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | 246 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) |
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 761ee0440c99..74fefac00899 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c | |||
| @@ -4,25 +4,6 @@ | |||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
| 5 | * License. See the file COPYING in the main directory of this archive | 5 | * License. See the file COPYING in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | ||
| 8 | * 07/03/96: Timer initialization, and thus mach_sched_init(), | ||
| 9 | * removed from request_irq() and moved to init_time(). | ||
| 10 | * We should therefore consider renaming our add_isr() and | ||
| 11 | * remove_isr() to request_irq() and free_irq() | ||
| 12 | * respectively, so they are compliant with the other | ||
| 13 | * architectures. /Jes | ||
| 14 | * 11/07/96: Changed all add_/remove_isr() to request_/free_irq() calls. | ||
| 15 | * Removed irq list support, if any machine needs an irq server | ||
| 16 | * it must implement this itself (as it's already done), instead | ||
| 17 | * only default handler are used with mach_default_handler. | ||
| 18 | * request_irq got some flags different from other architectures: | ||
| 19 | * - IRQ_FLG_REPLACE : Replace an existing handler (the default one | ||
| 20 | * can be replaced without this flag) | ||
| 21 | * - IRQ_FLG_LOCK : handler can't be replaced | ||
| 22 | * There are other machine depending flags, see there | ||
| 23 | * If you want to replace a default handler you should know what | ||
| 24 | * you're doing, since it might handle different other irq sources | ||
| 25 | * which must be served /Roman Zippel | ||
| 26 | */ | 7 | */ |
| 27 | 8 | ||
| 28 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| @@ -47,33 +28,22 @@ | |||
| 47 | #endif | 28 | #endif |
| 48 | 29 | ||
| 49 | extern u32 auto_irqhandler_fixup[]; | 30 | extern u32 auto_irqhandler_fixup[]; |
| 50 | extern u32 user_irqhandler_fixup[]; | ||
| 51 | extern u16 user_irqvec_fixup[]; | 31 | extern u16 user_irqvec_fixup[]; |
| 52 | 32 | ||
| 53 | /* table for system interrupt handlers */ | ||
| 54 | static struct irq_node *irq_list[NR_IRQS]; | ||
| 55 | static struct irq_controller *irq_controller[NR_IRQS]; | ||
| 56 | static int irq_depth[NR_IRQS]; | ||
| 57 | |||
| 58 | static int m68k_first_user_vec; | 33 | static int m68k_first_user_vec; |
| 59 | 34 | ||
| 60 | static struct irq_controller auto_irq_controller = { | 35 | static struct irq_chip auto_irq_chip = { |
| 61 | .name = "auto", | 36 | .name = "auto", |
| 62 | .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), | 37 | .irq_startup = m68k_irq_startup, |
| 63 | .startup = m68k_irq_startup, | 38 | .irq_shutdown = m68k_irq_shutdown, |
| 64 | .shutdown = m68k_irq_shutdown, | ||
| 65 | }; | 39 | }; |
| 66 | 40 | ||
| 67 | static struct irq_controller user_irq_controller = { | 41 | static struct irq_chip user_irq_chip = { |
| 68 | .name = "user", | 42 | .name = "user", |
| 69 | .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock), | 43 | .irq_startup = m68k_irq_startup, |
| 70 | .startup = m68k_irq_startup, | 44 | .irq_shutdown = m68k_irq_shutdown, |
| 71 | .shutdown = m68k_irq_shutdown, | ||
| 72 | }; | 45 | }; |
| 73 | 46 | ||
| 74 | #define NUM_IRQ_NODES 100 | ||
| 75 | static irq_node_t nodes[NUM_IRQ_NODES]; | ||
| 76 | |||
| 77 | /* | 47 | /* |
| 78 | * void init_IRQ(void) | 48 | * void init_IRQ(void) |
| 79 | * | 49 | * |
| @@ -96,7 +66,7 @@ void __init init_IRQ(void) | |||
| 96 | } | 66 | } |
| 97 | 67 | ||
| 98 | for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) | 68 | for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) |
| 99 | irq_controller[i] = &auto_irq_controller; | 69 | irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq); |
| 100 | 70 | ||
| 101 | mach_init_IRQ(); | 71 | mach_init_IRQ(); |
| 102 | } | 72 | } |
| @@ -106,7 +76,7 @@ void __init init_IRQ(void) | |||
| 106 | * @handler: called from auto vector interrupts | 76 | * @handler: called from auto vector interrupts |
| 107 | * | 77 | * |
| 108 | * setup the handler to be called from auto vector interrupts instead of the | 78 | * setup the handler to be called from auto vector interrupts instead of the |
| 109 | * standard __m68k_handle_int(), it will be called with irq numbers in the range | 79 | * standard do_IRQ(), it will be called with irq numbers in the range |
| 110 | * from IRQ_AUTO_1 - IRQ_AUTO_7. | 80 | * from IRQ_AUTO_1 - IRQ_AUTO_7. |
| 111 | */ | 81 | */ |
| 112 | void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) | 82 | void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) |
| @@ -120,217 +90,49 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re | |||
| 120 | * m68k_setup_user_interrupt | 90 | * m68k_setup_user_interrupt |
| 121 | * @vec: first user vector interrupt to handle | 91 | * @vec: first user vector interrupt to handle |
| 122 | * @cnt: number of active user vector interrupts | 92 | * @cnt: number of active user vector interrupts |
| 123 | * @handler: called from user vector interrupts | ||
| 124 | * | 93 | * |
| 125 | * setup user vector interrupts, this includes activating the specified range | 94 | * setup user vector interrupts, this includes activating the specified range |
| 126 | * of interrupts, only then these interrupts can be requested (note: this is | 95 | * of interrupts, only then these interrupts can be requested (note: this is |
| 127 | * different from auto vector interrupts). An optional handler can be installed | 96 | * different from auto vector interrupts). |
| 128 | * to be called instead of the default __m68k_handle_int(), it will be called | ||
| 129 | * with irq numbers starting from IRQ_USER. | ||
| 130 | */ | 97 | */ |
| 131 | void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, | 98 | void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt) |
| 132 | void (*handler)(unsigned int, struct pt_regs *)) | ||
| 133 | { | 99 | { |
| 134 | int i; | 100 | int i; |
| 135 | 101 | ||
| 136 | BUG_ON(IRQ_USER + cnt > NR_IRQS); | 102 | BUG_ON(IRQ_USER + cnt > NR_IRQS); |
| 137 | m68k_first_user_vec = vec; | 103 | m68k_first_user_vec = vec; |
| 138 | for (i = 0; i < cnt; i++) | 104 | for (i = 0; i < cnt; i++) |
| 139 | irq_controller[IRQ_USER + i] = &user_irq_controller; | 105 | irq_set_chip(IRQ_USER + i, &user_irq_chip); |
| 140 | *user_irqvec_fixup = vec - IRQ_USER; | 106 | *user_irqvec_fixup = vec - IRQ_USER; |
| 141 | if (handler) | ||
| 142 | *user_irqhandler_fixup = (u32)handler; | ||
| 143 | flush_icache(); | 107 | flush_icache(); |
| 144 | } | 108 | } |
| 145 | 109 | ||
| 146 | /** | 110 | /** |
| 147 | * m68k_setup_irq_controller | 111 | * m68k_setup_irq_controller |
| 148 | * @contr: irq controller which controls specified irq | 112 | * @chip: irq chip which controls specified irq |
| 113 | * @handle: flow handler which handles specified irq | ||
| 149 | * @irq: first irq to be managed by the controller | 114 | * @irq: first irq to be managed by the controller |
| 115 | * @cnt: number of irqs to be managed by the controller | ||
| 150 | * | 116 | * |
| 151 | * Change the controller for the specified range of irq, which will be used to | 117 | * Change the controller for the specified range of irq, which will be used to |
| 152 | * manage these irq. auto/user irq already have a default controller, which can | 118 | * manage these irq. auto/user irq already have a default controller, which can |
| 153 | * be changed as well, but the controller probably should use m68k_irq_startup/ | 119 | * be changed as well, but the controller probably should use m68k_irq_startup/ |
| 154 | * m68k_irq_shutdown. | 120 | * m68k_irq_shutdown. |
| 155 | */ | 121 | */ |
| 156 | void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, | 122 | void m68k_setup_irq_controller(struct irq_chip *chip, |
| 123 | irq_flow_handler_t handle, unsigned int irq, | ||
| 157 | unsigned int cnt) | 124 | unsigned int cnt) |
| 158 | { | 125 | { |
| 159 | int i; | 126 | int i; |
| 160 | 127 | ||
| 161 | for (i = 0; i < cnt; i++) | 128 | for (i = 0; i < cnt; i++) { |
| 162 | irq_controller[irq + i] = contr; | 129 | irq_set_chip(irq + i, chip); |
| 163 | } | 130 | if (handle) |
| 164 | 131 | irq_set_handler(irq + i, handle); | |
| 165 | irq_node_t *new_irq_node(void) | ||
| 166 | { | ||
| 167 | irq_node_t *node; | ||
| 168 | short i; | ||
| 169 | |||
| 170 | for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { | ||
| 171 | if (!node->handler) { | ||
| 172 | memset(node, 0, sizeof(*node)); | ||
| 173 | return node; | ||
| 174 | } | ||
| 175 | } | 132 | } |
| 176 | |||
| 177 | printk ("new_irq_node: out of nodes\n"); | ||
| 178 | return NULL; | ||
| 179 | } | 133 | } |
| 180 | 134 | ||
| 181 | int setup_irq(unsigned int irq, struct irq_node *node) | 135 | unsigned int m68k_irq_startup_irq(unsigned int irq) |
| 182 | { | ||
| 183 | struct irq_controller *contr; | ||
| 184 | struct irq_node **prev; | ||
| 185 | unsigned long flags; | ||
| 186 | |||
| 187 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | ||
| 188 | printk("%s: Incorrect IRQ %d from %s\n", | ||
| 189 | __func__, irq, node->devname); | ||
| 190 | return -ENXIO; | ||
| 191 | } | ||
| 192 | |||
| 193 | spin_lock_irqsave(&contr->lock, flags); | ||
| 194 | |||
| 195 | prev = irq_list + irq; | ||
| 196 | if (*prev) { | ||
| 197 | /* Can't share interrupts unless both agree to */ | ||
| 198 | if (!((*prev)->flags & node->flags & IRQF_SHARED)) { | ||
| 199 | spin_unlock_irqrestore(&contr->lock, flags); | ||
| 200 | return -EBUSY; | ||
| 201 | } | ||
| 202 | while (*prev) | ||
| 203 | prev = &(*prev)->next; | ||
| 204 | } | ||
| 205 | |||
| 206 | if (!irq_list[irq]) { | ||
| 207 | if (contr->startup) | ||
| 208 | contr->startup(irq); | ||
| 209 | else | ||
| 210 | contr->enable(irq); | ||
| 211 | } | ||
| 212 | node->next = NULL; | ||
| 213 | *prev = node; | ||
| 214 | |||
| 215 | spin_unlock_irqrestore(&contr->lock, flags); | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | int request_irq(unsigned int irq, | ||
| 221 | irq_handler_t handler, | ||
| 222 | unsigned long flags, const char *devname, void *dev_id) | ||
| 223 | { | ||
| 224 | struct irq_node *node; | ||
| 225 | int res; | ||
| 226 | |||
| 227 | node = new_irq_node(); | ||
| 228 | if (!node) | ||
| 229 | return -ENOMEM; | ||
| 230 | |||
| 231 | node->handler = handler; | ||
| 232 | node->flags = flags; | ||
| 233 | node->dev_id = dev_id; | ||
| 234 | node->devname = devname; | ||
| 235 | |||
| 236 | res = setup_irq(irq, node); | ||
| 237 | if (res) | ||
| 238 | node->handler = NULL; | ||
| 239 | |||
| 240 | return res; | ||
| 241 | } | ||
| 242 | |||
| 243 | EXPORT_SYMBOL(request_irq); | ||
| 244 | |||
| 245 | void free_irq(unsigned int irq, void *dev_id) | ||
| 246 | { | ||
| 247 | struct irq_controller *contr; | ||
| 248 | struct irq_node **p, *node; | ||
| 249 | unsigned long flags; | ||
| 250 | |||
| 251 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | ||
| 252 | printk("%s: Incorrect IRQ %d\n", __func__, irq); | ||
| 253 | return; | ||
| 254 | } | ||
| 255 | |||
| 256 | spin_lock_irqsave(&contr->lock, flags); | ||
| 257 | |||
| 258 | p = irq_list + irq; | ||
| 259 | while ((node = *p)) { | ||
| 260 | if (node->dev_id == dev_id) | ||
| 261 | break; | ||
| 262 | p = &node->next; | ||
| 263 | } | ||
| 264 | |||
| 265 | if (node) { | ||
| 266 | *p = node->next; | ||
| 267 | node->handler = NULL; | ||
| 268 | } else | ||
| 269 | printk("%s: Removing probably wrong IRQ %d\n", | ||
| 270 | __func__, irq); | ||
| 271 | |||
| 272 | if (!irq_list[irq]) { | ||
| 273 | if (contr->shutdown) | ||
| 274 | contr->shutdown(irq); | ||
| 275 | else | ||
| 276 | contr->disable(irq); | ||
| 277 | } | ||
| 278 | |||
| 279 | spin_unlock_irqrestore(&contr->lock, flags); | ||
| 280 | } | ||
| 281 | |||
| 282 | EXPORT_SYMBOL(free_irq); | ||
| 283 | |||
| 284 | void enable_irq(unsigned int irq) | ||
| 285 | { | ||
| 286 | struct irq_controller *contr; | ||
| 287 | unsigned long flags; | ||
| 288 | |||
| 289 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | ||
| 290 | printk("%s: Incorrect IRQ %d\n", | ||
| 291 | __func__, irq); | ||
| 292 | return; | ||
| 293 | } | ||
| 294 | |||
| 295 | spin_lock_irqsave(&contr->lock, flags); | ||
| 296 | if (irq_depth[irq]) { | ||
| 297 | if (!--irq_depth[irq]) { | ||
| 298 | if (contr->enable) | ||
| 299 | contr->enable(irq); | ||
| 300 | } | ||
| 301 | } else | ||
| 302 | WARN_ON(1); | ||
| 303 | spin_unlock_irqrestore(&contr->lock, flags); | ||
| 304 | } | ||
| 305 | |||
| 306 | EXPORT_SYMBOL(enable_irq); | ||
| 307 | |||
| 308 | void disable_irq(unsigned int irq) | ||
| 309 | { | ||
| 310 | struct irq_controller *contr; | ||
| 311 | unsigned long flags; | ||
| 312 | |||
| 313 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | ||
| 314 | printk("%s: Incorrect IRQ %d\n", | ||
| 315 | __func__, irq); | ||
| 316 | return; | ||
| 317 | } | ||
| 318 | |||
| 319 | spin_lock_irqsave(&contr->lock, flags); | ||
| 320 | if (!irq_depth[irq]++) { | ||
| 321 | if (contr->disable) | ||
| 322 | contr->disable(irq); | ||
| 323 | } | ||
| 324 | spin_unlock_irqrestore(&contr->lock, flags); | ||
| 325 | } | ||
| 326 | |||
| 327 | EXPORT_SYMBOL(disable_irq); | ||
| 328 | |||
| 329 | void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); | ||
| 330 | |||
| 331 | EXPORT_SYMBOL(disable_irq_nosync); | ||
| 332 | |||
| 333 | int m68k_irq_startup(unsigned int irq) | ||
| 334 | { | 136 | { |
| 335 | if (irq <= IRQ_AUTO_7) | 137 | if (irq <= IRQ_AUTO_7) |
| 336 | vectors[VEC_SPUR + irq] = auto_inthandler; | 138 | vectors[VEC_SPUR + irq] = auto_inthandler; |
| @@ -339,41 +141,21 @@ int m68k_irq_startup(unsigned int irq) | |||
| 339 | return 0; | 141 | return 0; |
| 340 | } | 142 | } |
| 341 | 143 | ||
| 342 | void m68k_irq_shutdown(unsigned int irq) | 144 | unsigned int m68k_irq_startup(struct irq_data *data) |
| 343 | { | 145 | { |
| 344 | if (irq <= IRQ_AUTO_7) | 146 | return m68k_irq_startup_irq(data->irq); |
| 345 | vectors[VEC_SPUR + irq] = bad_inthandler; | ||
| 346 | else | ||
| 347 | vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; | ||
| 348 | } | 147 | } |
| 349 | 148 | ||
| 350 | 149 | void m68k_irq_shutdown(struct irq_data *data) | |
| 351 | /* | ||
| 352 | * Do we need these probe functions on the m68k? | ||
| 353 | * | ||
| 354 | * ... may be useful with ISA devices | ||
| 355 | */ | ||
| 356 | unsigned long probe_irq_on (void) | ||
| 357 | { | 150 | { |
| 358 | #ifdef CONFIG_Q40 | 151 | unsigned int irq = data->irq; |
| 359 | if (MACH_IS_Q40) | ||
| 360 | return q40_probe_irq_on(); | ||
| 361 | #endif | ||
| 362 | return 0; | ||
| 363 | } | ||
| 364 | 152 | ||
| 365 | EXPORT_SYMBOL(probe_irq_on); | 153 | if (irq <= IRQ_AUTO_7) |
| 366 | 154 | vectors[VEC_SPUR + irq] = bad_inthandler; | |
| 367 | int probe_irq_off (unsigned long irqs) | 155 | else |
| 368 | { | 156 | vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; |
| 369 | #ifdef CONFIG_Q40 | ||
| 370 | if (MACH_IS_Q40) | ||
| 371 | return q40_probe_irq_off(irqs); | ||
| 372 | #endif | ||
| 373 | return 0; | ||
| 374 | } | 157 | } |
| 375 | 158 | ||
| 376 | EXPORT_SYMBOL(probe_irq_off); | ||
| 377 | 159 | ||
| 378 | unsigned int irq_canonicalize(unsigned int irq) | 160 | unsigned int irq_canonicalize(unsigned int irq) |
| 379 | { | 161 | { |
| @@ -386,52 +168,9 @@ unsigned int irq_canonicalize(unsigned int irq) | |||
| 386 | 168 | ||
| 387 | EXPORT_SYMBOL(irq_canonicalize); | 169 | EXPORT_SYMBOL(irq_canonicalize); |
| 388 | 170 | ||
| 389 | asmlinkage void m68k_handle_int(unsigned int irq) | ||
| 390 | { | ||
| 391 | struct irq_node *node; | ||
| 392 | kstat_cpu(0).irqs[irq]++; | ||
| 393 | node = irq_list[irq]; | ||
| 394 | do { | ||
| 395 | node->handler(irq, node->dev_id); | ||
| 396 | node = node->next; | ||
| 397 | } while (node); | ||
| 398 | } | ||
| 399 | |||
| 400 | asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs) | ||
| 401 | { | ||
| 402 | struct pt_regs *old_regs; | ||
| 403 | old_regs = set_irq_regs(regs); | ||
| 404 | m68k_handle_int(irq); | ||
| 405 | set_irq_regs(old_regs); | ||
| 406 | } | ||
| 407 | 171 | ||
| 408 | asmlinkage void handle_badint(struct pt_regs *regs) | 172 | asmlinkage void handle_badint(struct pt_regs *regs) |
| 409 | { | 173 | { |
| 410 | kstat_cpu(0).irqs[0]++; | 174 | atomic_inc(&irq_err_count); |
| 411 | printk("unexpected interrupt from %u\n", regs->vector); | 175 | pr_warn("unexpected interrupt from %u\n", regs->vector); |
| 412 | } | ||
| 413 | |||
| 414 | int show_interrupts(struct seq_file *p, void *v) | ||
| 415 | { | ||
| 416 | struct irq_controller *contr; | ||
| 417 | struct irq_node *node; | ||
| 418 | int i = *(loff_t *) v; | ||
| 419 | |||
| 420 | /* autovector interrupts */ | ||
| 421 | if (irq_list[i]) { | ||
| 422 | contr = irq_controller[i]; | ||
| 423 | node = irq_list[i]; | ||
| 424 | seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); | ||
| 425 | while ((node = node->next)) | ||
| 426 | seq_printf(p, ", %s", node->devname); | ||
| 427 | seq_puts(p, "\n"); | ||
| 428 | } | ||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | |||
| 432 | #ifdef CONFIG_PROC_FS | ||
| 433 | void init_irq_proc(void) | ||
| 434 | { | ||
| 435 | /* Insert /proc/irq driver here */ | ||
| 436 | } | 176 | } |
| 437 | #endif | ||
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 2a96bebd8969..b403924a1cad 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
| 12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/irq.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/traps.h> | 16 | #include <asm/traps.h> |
| 16 | #include <asm/bootinfo.h> | 17 | #include <asm/bootinfo.h> |
| @@ -20,9 +21,6 @@ | |||
| 20 | 21 | ||
| 21 | /* #define DEBUG_IRQS */ | 22 | /* #define DEBUG_IRQS */ |
| 22 | 23 | ||
| 23 | extern void mac_enable_irq(unsigned int); | ||
| 24 | extern void mac_disable_irq(unsigned int); | ||
| 25 | |||
| 26 | int baboon_present; | 24 | int baboon_present; |
| 27 | static volatile struct baboon *baboon; | 25 | static volatile struct baboon *baboon; |
| 28 | static unsigned char baboon_disabled; | 26 | static unsigned char baboon_disabled; |
| @@ -53,7 +51,7 @@ void __init baboon_init(void) | |||
| 53 | * Baboon interrupt handler. This works a lot like a VIA. | 51 | * Baboon interrupt handler. This works a lot like a VIA. |
| 54 | */ | 52 | */ |
| 55 | 53 | ||
| 56 | static irqreturn_t baboon_irq(int irq, void *dev_id) | 54 | static void baboon_irq(unsigned int irq, struct irq_desc *desc) |
| 57 | { | 55 | { |
| 58 | int irq_bit, irq_num; | 56 | int irq_bit, irq_num; |
| 59 | unsigned char events; | 57 | unsigned char events; |
| @@ -64,15 +62,16 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) | |||
| 64 | (uint) baboon->mb_status); | 62 | (uint) baboon->mb_status); |
| 65 | #endif | 63 | #endif |
| 66 | 64 | ||
| 67 | if (!(events = baboon->mb_ifr & 0x07)) | 65 | events = baboon->mb_ifr & 0x07; |
| 68 | return IRQ_NONE; | 66 | if (!events) |
| 67 | return; | ||
| 69 | 68 | ||
| 70 | irq_num = IRQ_BABOON_0; | 69 | irq_num = IRQ_BABOON_0; |
| 71 | irq_bit = 1; | 70 | irq_bit = 1; |
| 72 | do { | 71 | do { |
| 73 | if (events & irq_bit) { | 72 | if (events & irq_bit) { |
| 74 | baboon->mb_ifr &= ~irq_bit; | 73 | baboon->mb_ifr &= ~irq_bit; |
| 75 | m68k_handle_int(irq_num); | 74 | generic_handle_irq(irq_num); |
| 76 | } | 75 | } |
| 77 | irq_bit <<= 1; | 76 | irq_bit <<= 1; |
| 78 | irq_num++; | 77 | irq_num++; |
| @@ -82,7 +81,6 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) | |||
| 82 | /* for now we need to smash all interrupts */ | 81 | /* for now we need to smash all interrupts */ |
| 83 | baboon->mb_ifr &= ~events; | 82 | baboon->mb_ifr &= ~events; |
| 84 | #endif | 83 | #endif |
| 85 | return IRQ_HANDLED; | ||
| 86 | } | 84 | } |
| 87 | 85 | ||
| 88 | /* | 86 | /* |
| @@ -92,8 +90,7 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) | |||
| 92 | void __init baboon_register_interrupts(void) | 90 | void __init baboon_register_interrupts(void) |
| 93 | { | 91 | { |
| 94 | baboon_disabled = 0; | 92 | baboon_disabled = 0; |
| 95 | if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon)) | 93 | irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); |
| 96 | pr_err("Couldn't register baboon interrupt\n"); | ||
| 97 | } | 94 | } |
| 98 | 95 | ||
| 99 | /* | 96 | /* |
| @@ -111,7 +108,7 @@ void baboon_irq_enable(int irq) | |||
| 111 | 108 | ||
| 112 | baboon_disabled &= ~(1 << irq_idx); | 109 | baboon_disabled &= ~(1 << irq_idx); |
| 113 | if (!baboon_disabled) | 110 | if (!baboon_disabled) |
| 114 | mac_enable_irq(IRQ_NUBUS_C); | 111 | mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C)); |
| 115 | } | 112 | } |
| 116 | 113 | ||
| 117 | void baboon_irq_disable(int irq) | 114 | void baboon_irq_disable(int irq) |
| @@ -124,7 +121,7 @@ void baboon_irq_disable(int irq) | |||
| 124 | 121 | ||
| 125 | baboon_disabled |= 1 << irq_idx; | 122 | baboon_disabled |= 1 << irq_idx; |
| 126 | if (baboon_disabled) | 123 | if (baboon_disabled) |
| 127 | mac_disable_irq(IRQ_NUBUS_C); | 124 | mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C)); |
| 128 | } | 125 | } |
| 129 | 126 | ||
| 130 | void baboon_irq_clear(int irq) | 127 | void baboon_irq_clear(int irq) |
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c index 1ad4e9d80eba..a5462cc0bfd6 100644 --- a/arch/m68k/mac/iop.c +++ b/arch/m68k/mac/iop.c | |||
| @@ -305,15 +305,13 @@ void __init iop_register_interrupts(void) | |||
| 305 | { | 305 | { |
| 306 | if (iop_ism_present) { | 306 | if (iop_ism_present) { |
| 307 | if (oss_present) { | 307 | if (oss_present) { |
| 308 | if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, | 308 | if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, 0, |
| 309 | IRQ_FLG_LOCK, "ISM IOP", | 309 | "ISM IOP", (void *)IOP_NUM_ISM)) |
| 310 | (void *) IOP_NUM_ISM)) | ||
| 311 | pr_err("Couldn't register ISM IOP interrupt\n"); | 310 | pr_err("Couldn't register ISM IOP interrupt\n"); |
| 312 | oss_irq_enable(IRQ_MAC_ADB); | 311 | oss_irq_enable(IRQ_MAC_ADB); |
| 313 | } else { | 312 | } else { |
| 314 | if (request_irq(IRQ_VIA2_0, iop_ism_irq, | 313 | if (request_irq(IRQ_VIA2_0, iop_ism_irq, 0, "ISM IOP", |
| 315 | IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP", | 314 | (void *)IOP_NUM_ISM)) |
| 316 | (void *) IOP_NUM_ISM)) | ||
| 317 | pr_err("Couldn't register ISM IOP interrupt\n"); | 315 | pr_err("Couldn't register ISM IOP interrupt\n"); |
| 318 | } | 316 | } |
| 319 | if (!iop_alive(iop_base[IOP_NUM_ISM])) { | 317 | if (!iop_alive(iop_base[IOP_NUM_ISM])) { |
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index f92190c159b4..ba220b70ab8c 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c | |||
| @@ -190,14 +190,10 @@ irqreturn_t mac_debug_handler(int, void *); | |||
| 190 | 190 | ||
| 191 | /* #define DEBUG_MACINTS */ | 191 | /* #define DEBUG_MACINTS */ |
| 192 | 192 | ||
| 193 | void mac_enable_irq(unsigned int irq); | 193 | static struct irq_chip mac_irq_chip = { |
| 194 | void mac_disable_irq(unsigned int irq); | ||
| 195 | |||
| 196 | static struct irq_controller mac_irq_controller = { | ||
| 197 | .name = "mac", | 194 | .name = "mac", |
| 198 | .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock), | 195 | .irq_enable = mac_irq_enable, |
| 199 | .enable = mac_enable_irq, | 196 | .irq_disable = mac_irq_disable, |
| 200 | .disable = mac_disable_irq, | ||
| 201 | }; | 197 | }; |
| 202 | 198 | ||
| 203 | void __init mac_init_IRQ(void) | 199 | void __init mac_init_IRQ(void) |
| @@ -205,7 +201,7 @@ void __init mac_init_IRQ(void) | |||
| 205 | #ifdef DEBUG_MACINTS | 201 | #ifdef DEBUG_MACINTS |
| 206 | printk("mac_init_IRQ(): Setting things up...\n"); | 202 | printk("mac_init_IRQ(): Setting things up...\n"); |
| 207 | #endif | 203 | #endif |
| 208 | m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, | 204 | m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER, |
| 209 | NUM_MAC_SOURCES - IRQ_USER); | 205 | NUM_MAC_SOURCES - IRQ_USER); |
| 210 | /* Make sure the SONIC interrupt is cleared or things get ugly */ | 206 | /* Make sure the SONIC interrupt is cleared or things get ugly */ |
| 211 | #ifdef SHUTUP_SONIC | 207 | #ifdef SHUTUP_SONIC |
| @@ -241,16 +237,17 @@ void __init mac_init_IRQ(void) | |||
| 241 | } | 237 | } |
| 242 | 238 | ||
| 243 | /* | 239 | /* |
| 244 | * mac_enable_irq - enable an interrupt source | 240 | * mac_irq_enable - enable an interrupt source |
| 245 | * mac_disable_irq - disable an interrupt source | 241 | * mac_irq_disable - disable an interrupt source |
| 246 | * mac_clear_irq - clears a pending interrupt | 242 | * mac_clear_irq - clears a pending interrupt |
| 247 | * mac_pending_irq - Returns the pending status of an IRQ (nonzero = pending) | 243 | * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending) |
| 248 | * | 244 | * |
| 249 | * These routines are just dispatchers to the VIA/OSS/PSC routines. | 245 | * These routines are just dispatchers to the VIA/OSS/PSC routines. |
| 250 | */ | 246 | */ |
| 251 | 247 | ||
| 252 | void mac_enable_irq(unsigned int irq) | 248 | void mac_irq_enable(struct irq_data *data) |
| 253 | { | 249 | { |
| 250 | int irq = data->irq; | ||
| 254 | int irq_src = IRQ_SRC(irq); | 251 | int irq_src = IRQ_SRC(irq); |
| 255 | 252 | ||
| 256 | switch(irq_src) { | 253 | switch(irq_src) { |
| @@ -283,8 +280,9 @@ void mac_enable_irq(unsigned int irq) | |||
| 283 | } | 280 | } |
| 284 | } | 281 | } |
| 285 | 282 | ||
| 286 | void mac_disable_irq(unsigned int irq) | 283 | void mac_irq_disable(struct irq_data *data) |
| 287 | { | 284 | { |
| 285 | int irq = data->irq; | ||
| 288 | int irq_src = IRQ_SRC(irq); | 286 | int irq_src = IRQ_SRC(irq); |
| 289 | 287 | ||
| 290 | switch(irq_src) { | 288 | switch(irq_src) { |
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index a9c0f5ab4cc0..a4c82dab9ff1 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
| 20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/irq.h> | ||
| 22 | 23 | ||
| 23 | #include <asm/bootinfo.h> | 24 | #include <asm/bootinfo.h> |
| 24 | #include <asm/macintosh.h> | 25 | #include <asm/macintosh.h> |
| @@ -29,10 +30,7 @@ | |||
| 29 | int oss_present; | 30 | int oss_present; |
| 30 | volatile struct mac_oss *oss; | 31 | volatile struct mac_oss *oss; |
| 31 | 32 | ||
| 32 | static irqreturn_t oss_irq(int, void *); | 33 | extern void via1_irq(unsigned int irq, struct irq_desc *desc); |
| 33 | static irqreturn_t oss_nubus_irq(int, void *); | ||
| 34 | |||
| 35 | extern irqreturn_t via1_irq(int, void *); | ||
| 36 | 34 | ||
| 37 | /* | 35 | /* |
| 38 | * Initialize the OSS | 36 | * Initialize the OSS |
| @@ -60,26 +58,6 @@ void __init oss_init(void) | |||
| 60 | } | 58 | } |
| 61 | 59 | ||
| 62 | /* | 60 | /* |
| 63 | * Register the OSS and NuBus interrupt dispatchers. | ||
| 64 | */ | ||
| 65 | |||
| 66 | void __init oss_register_interrupts(void) | ||
| 67 | { | ||
| 68 | if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, | ||
| 69 | "scsi", (void *) oss)) | ||
| 70 | pr_err("Couldn't register %s interrupt\n", "scsi"); | ||
| 71 | if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, | ||
| 72 | "nubus", (void *) oss)) | ||
| 73 | pr_err("Couldn't register %s interrupt\n", "nubus"); | ||
| 74 | if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, | ||
| 75 | "sound", (void *) oss)) | ||
| 76 | pr_err("Couldn't register %s interrupt\n", "sound"); | ||
| 77 | if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, | ||
| 78 | "via1", (void *) via1)) | ||
| 79 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Initialize OSS for Nubus access | 61 | * Initialize OSS for Nubus access |
| 84 | */ | 62 | */ |
| 85 | 63 | ||
| @@ -92,17 +70,17 @@ void __init oss_nubus_init(void) | |||
| 92 | * and SCSI; everything else is routed to its own autovector IRQ. | 70 | * and SCSI; everything else is routed to its own autovector IRQ. |
| 93 | */ | 71 | */ |
| 94 | 72 | ||
| 95 | static irqreturn_t oss_irq(int irq, void *dev_id) | 73 | static void oss_irq(unsigned int irq, struct irq_desc *desc) |
| 96 | { | 74 | { |
| 97 | int events; | 75 | int events; |
| 98 | 76 | ||
| 99 | events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); | 77 | events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); |
| 100 | if (!events) | 78 | if (!events) |
| 101 | return IRQ_NONE; | 79 | return; |
| 102 | 80 | ||
| 103 | #ifdef DEBUG_IRQS | 81 | #ifdef DEBUG_IRQS |
| 104 | if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { | 82 | if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { |
| 105 | printk("oss_irq: irq %d events = 0x%04X\n", irq, | 83 | printk("oss_irq: irq %u events = 0x%04X\n", irq, |
| 106 | (int) oss->irq_pending); | 84 | (int) oss->irq_pending); |
| 107 | } | 85 | } |
| 108 | #endif | 86 | #endif |
| @@ -113,11 +91,10 @@ static irqreturn_t oss_irq(int irq, void *dev_id) | |||
| 113 | /* FIXME: call sound handler */ | 91 | /* FIXME: call sound handler */ |
| 114 | } else if (events & OSS_IP_SCSI) { | 92 | } else if (events & OSS_IP_SCSI) { |
| 115 | oss->irq_pending &= ~OSS_IP_SCSI; | 93 | oss->irq_pending &= ~OSS_IP_SCSI; |
| 116 | m68k_handle_int(IRQ_MAC_SCSI); | 94 | generic_handle_irq(IRQ_MAC_SCSI); |
| 117 | } else { | 95 | } else { |
| 118 | /* FIXME: error check here? */ | 96 | /* FIXME: error check here? */ |
| 119 | } | 97 | } |
| 120 | return IRQ_HANDLED; | ||
| 121 | } | 98 | } |
| 122 | 99 | ||
| 123 | /* | 100 | /* |
| @@ -126,13 +103,13 @@ static irqreturn_t oss_irq(int irq, void *dev_id) | |||
| 126 | * Unlike the VIA/RBV this is on its own autovector interrupt level. | 103 | * Unlike the VIA/RBV this is on its own autovector interrupt level. |
| 127 | */ | 104 | */ |
| 128 | 105 | ||
| 129 | static irqreturn_t oss_nubus_irq(int irq, void *dev_id) | 106 | static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) |
| 130 | { | 107 | { |
| 131 | int events, irq_bit, i; | 108 | int events, irq_bit, i; |
| 132 | 109 | ||
| 133 | events = oss->irq_pending & OSS_IP_NUBUS; | 110 | events = oss->irq_pending & OSS_IP_NUBUS; |
| 134 | if (!events) | 111 | if (!events) |
| 135 | return IRQ_NONE; | 112 | return; |
| 136 | 113 | ||
| 137 | #ifdef DEBUG_NUBUS_INT | 114 | #ifdef DEBUG_NUBUS_INT |
| 138 | if (console_loglevel > 7) { | 115 | if (console_loglevel > 7) { |
| @@ -148,10 +125,21 @@ static irqreturn_t oss_nubus_irq(int irq, void *dev_id) | |||
| 148 | irq_bit >>= 1; | 125 | irq_bit >>= 1; |
| 149 | if (events & irq_bit) { | 126 | if (events & irq_bit) { |
| 150 | oss->irq_pending &= ~irq_bit; | 127 | oss->irq_pending &= ~irq_bit; |
| 151 | m68k_handle_int(NUBUS_SOURCE_BASE + i); | 128 | generic_handle_irq(NUBUS_SOURCE_BASE + i); |
| 152 | } | 129 | } |
| 153 | } while(events & (irq_bit - 1)); | 130 | } while(events & (irq_bit - 1)); |
| 154 | return IRQ_HANDLED; | 131 | } |
| 132 | |||
| 133 | /* | ||
| 134 | * Register the OSS and NuBus interrupt dispatchers. | ||
| 135 | */ | ||
| 136 | |||
| 137 | void __init oss_register_interrupts(void) | ||
| 138 | { | ||
| 139 | irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq); | ||
| 140 | irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq); | ||
| 141 | irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq); | ||
| 142 | irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq); | ||
| 155 | } | 143 | } |
| 156 | 144 | ||
| 157 | /* | 145 | /* |
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index a4c3eb60706e..e6c2d20f328d 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
| 19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/irq.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/traps.h> | 23 | #include <asm/traps.h> |
| 23 | #include <asm/bootinfo.h> | 24 | #include <asm/bootinfo.h> |
| @@ -30,8 +31,6 @@ | |||
| 30 | int psc_present; | 31 | int psc_present; |
| 31 | volatile __u8 *psc; | 32 | volatile __u8 *psc; |
| 32 | 33 | ||
| 33 | irqreturn_t psc_irq(int, void *); | ||
| 34 | |||
| 35 | /* | 34 | /* |
| 36 | * Debugging dump, used in various places to see what's going on. | 35 | * Debugging dump, used in various places to see what's going on. |
| 37 | */ | 36 | */ |
| @@ -112,52 +111,52 @@ void __init psc_init(void) | |||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | /* | 113 | /* |
| 115 | * Register the PSC interrupt dispatchers for autovector interrupts 3-6. | ||
| 116 | */ | ||
| 117 | |||
| 118 | void __init psc_register_interrupts(void) | ||
| 119 | { | ||
| 120 | if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30)) | ||
| 121 | pr_err("Couldn't register psc%d interrupt\n", 3); | ||
| 122 | if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40)) | ||
| 123 | pr_err("Couldn't register psc%d interrupt\n", 4); | ||
| 124 | if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50)) | ||
| 125 | pr_err("Couldn't register psc%d interrupt\n", 5); | ||
| 126 | if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60)) | ||
| 127 | pr_err("Couldn't register psc%d interrupt\n", 6); | ||
| 128 | } | ||
| 129 | |||
| 130 | /* | ||
| 131 | * PSC interrupt handler. It's a lot like the VIA interrupt handler. | 114 | * PSC interrupt handler. It's a lot like the VIA interrupt handler. |
| 132 | */ | 115 | */ |
| 133 | 116 | ||
| 134 | irqreturn_t psc_irq(int irq, void *dev_id) | 117 | static void psc_irq(unsigned int irq, struct irq_desc *desc) |
| 135 | { | 118 | { |
| 136 | int pIFR = pIFRbase + ((int) dev_id); | 119 | unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); |
| 137 | int pIER = pIERbase + ((int) dev_id); | 120 | int pIFR = pIFRbase + offset; |
| 121 | int pIER = pIERbase + offset; | ||
| 138 | int irq_num; | 122 | int irq_num; |
| 139 | unsigned char irq_bit, events; | 123 | unsigned char irq_bit, events; |
| 140 | 124 | ||
| 141 | #ifdef DEBUG_IRQS | 125 | #ifdef DEBUG_IRQS |
| 142 | printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", | 126 | printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n", |
| 143 | irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); | 127 | irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); |
| 144 | #endif | 128 | #endif |
| 145 | 129 | ||
| 146 | events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; | 130 | events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; |
| 147 | if (!events) | 131 | if (!events) |
| 148 | return IRQ_NONE; | 132 | return; |
| 149 | 133 | ||
| 150 | irq_num = irq << 3; | 134 | irq_num = irq << 3; |
| 151 | irq_bit = 1; | 135 | irq_bit = 1; |
| 152 | do { | 136 | do { |
| 153 | if (events & irq_bit) { | 137 | if (events & irq_bit) { |
| 154 | psc_write_byte(pIFR, irq_bit); | 138 | psc_write_byte(pIFR, irq_bit); |
| 155 | m68k_handle_int(irq_num); | 139 | generic_handle_irq(irq_num); |
| 156 | } | 140 | } |
| 157 | irq_num++; | 141 | irq_num++; |
| 158 | irq_bit <<= 1; | 142 | irq_bit <<= 1; |
| 159 | } while (events >= irq_bit); | 143 | } while (events >= irq_bit); |
| 160 | return IRQ_HANDLED; | 144 | } |
| 145 | |||
| 146 | /* | ||
| 147 | * Register the PSC interrupt dispatchers for autovector interrupts 3-6. | ||
| 148 | */ | ||
| 149 | |||
| 150 | void __init psc_register_interrupts(void) | ||
| 151 | { | ||
| 152 | irq_set_chained_handler(IRQ_AUTO_3, psc_irq); | ||
| 153 | irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); | ||
| 154 | irq_set_chained_handler(IRQ_AUTO_4, psc_irq); | ||
| 155 | irq_set_handler_data(IRQ_AUTO_4, (void *)0x40); | ||
| 156 | irq_set_chained_handler(IRQ_AUTO_5, psc_irq); | ||
| 157 | irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); | ||
| 158 | irq_set_chained_handler(IRQ_AUTO_6, psc_irq); | ||
| 159 | irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); | ||
| 161 | } | 160 | } |
| 162 | 161 | ||
| 163 | void psc_irq_enable(int irq) { | 162 | void psc_irq_enable(int irq) { |
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index e71166daec6a..f1600ad26621 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/irq.h> | ||
| 31 | 32 | ||
| 32 | #include <asm/bootinfo.h> | 33 | #include <asm/bootinfo.h> |
| 33 | #include <asm/macintosh.h> | 34 | #include <asm/macintosh.h> |
| @@ -77,9 +78,6 @@ static int gIER,gIFR,gBufA,gBufB; | |||
| 77 | static u8 nubus_disabled; | 78 | static u8 nubus_disabled; |
| 78 | 79 | ||
| 79 | void via_debug_dump(void); | 80 | void via_debug_dump(void); |
| 80 | irqreturn_t via1_irq(int, void *); | ||
| 81 | irqreturn_t via2_irq(int, void *); | ||
| 82 | irqreturn_t via_nubus_irq(int, void *); | ||
| 83 | void via_irq_enable(int irq); | 81 | void via_irq_enable(int irq); |
| 84 | void via_irq_disable(int irq); | 82 | void via_irq_disable(int irq); |
| 85 | void via_irq_clear(int irq); | 83 | void via_irq_clear(int irq); |
| @@ -281,40 +279,11 @@ void __init via_init_clock(irq_handler_t func) | |||
| 281 | via1[vT1CL] = MAC_CLOCK_LOW; | 279 | via1[vT1CL] = MAC_CLOCK_LOW; |
| 282 | via1[vT1CH] = MAC_CLOCK_HIGH; | 280 | via1[vT1CH] = MAC_CLOCK_HIGH; |
| 283 | 281 | ||
| 284 | if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func)) | 282 | if (request_irq(IRQ_MAC_TIMER_1, func, 0, "timer", func)) |
| 285 | pr_err("Couldn't register %s interrupt\n", "timer"); | 283 | pr_err("Couldn't register %s interrupt\n", "timer"); |
| 286 | } | 284 | } |
| 287 | 285 | ||
| 288 | /* | 286 | /* |
| 289 | * Register the interrupt dispatchers for VIA or RBV machines only. | ||
| 290 | */ | ||
| 291 | |||
| 292 | void __init via_register_interrupts(void) | ||
| 293 | { | ||
| 294 | if (via_alt_mapping) { | ||
| 295 | if (request_irq(IRQ_AUTO_1, via1_irq, | ||
| 296 | IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", | ||
| 297 | (void *) via1)) | ||
| 298 | pr_err("Couldn't register %s interrupt\n", "software"); | ||
| 299 | if (request_irq(IRQ_AUTO_6, via1_irq, | ||
| 300 | IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", | ||
| 301 | (void *) via1)) | ||
| 302 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
| 303 | } else { | ||
| 304 | if (request_irq(IRQ_AUTO_1, via1_irq, | ||
| 305 | IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", | ||
| 306 | (void *) via1)) | ||
| 307 | pr_err("Couldn't register %s interrupt\n", "via1"); | ||
| 308 | } | ||
| 309 | if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, | ||
| 310 | "via2", (void *) via2)) | ||
| 311 | pr_err("Couldn't register %s interrupt\n", "via2"); | ||
| 312 | if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, | ||
| 313 | IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2)) | ||
| 314 | pr_err("Couldn't register %s interrupt\n", "nubus"); | ||
| 315 | } | ||
| 316 | |||
| 317 | /* | ||
| 318 | * Debugging dump, used in various places to see what's going on. | 287 | * Debugging dump, used in various places to see what's going on. |
| 319 | */ | 288 | */ |
| 320 | 289 | ||
| @@ -446,48 +415,46 @@ void __init via_nubus_init(void) | |||
| 446 | * via6522.c :-), disable/pending masks added. | 415 | * via6522.c :-), disable/pending masks added. |
| 447 | */ | 416 | */ |
| 448 | 417 | ||
| 449 | irqreturn_t via1_irq(int irq, void *dev_id) | 418 | void via1_irq(unsigned int irq, struct irq_desc *desc) |
| 450 | { | 419 | { |
| 451 | int irq_num; | 420 | int irq_num; |
| 452 | unsigned char irq_bit, events; | 421 | unsigned char irq_bit, events; |
| 453 | 422 | ||
| 454 | events = via1[vIFR] & via1[vIER] & 0x7F; | 423 | events = via1[vIFR] & via1[vIER] & 0x7F; |
| 455 | if (!events) | 424 | if (!events) |
| 456 | return IRQ_NONE; | 425 | return; |
| 457 | 426 | ||
| 458 | irq_num = VIA1_SOURCE_BASE; | 427 | irq_num = VIA1_SOURCE_BASE; |
| 459 | irq_bit = 1; | 428 | irq_bit = 1; |
| 460 | do { | 429 | do { |
| 461 | if (events & irq_bit) { | 430 | if (events & irq_bit) { |
| 462 | via1[vIFR] = irq_bit; | 431 | via1[vIFR] = irq_bit; |
| 463 | m68k_handle_int(irq_num); | 432 | generic_handle_irq(irq_num); |
| 464 | } | 433 | } |
| 465 | ++irq_num; | 434 | ++irq_num; |
| 466 | irq_bit <<= 1; | 435 | irq_bit <<= 1; |
| 467 | } while (events >= irq_bit); | 436 | } while (events >= irq_bit); |
| 468 | return IRQ_HANDLED; | ||
| 469 | } | 437 | } |
| 470 | 438 | ||
| 471 | irqreturn_t via2_irq(int irq, void *dev_id) | 439 | static void via2_irq(unsigned int irq, struct irq_desc *desc) |
| 472 | { | 440 | { |
| 473 | int irq_num; | 441 | int irq_num; |
| 474 | unsigned char irq_bit, events; | 442 | unsigned char irq_bit, events; |
| 475 | 443 | ||
| 476 | events = via2[gIFR] & via2[gIER] & 0x7F; | 444 | events = via2[gIFR] & via2[gIER] & 0x7F; |
| 477 | if (!events) | 445 | if (!events) |
| 478 | return IRQ_NONE; | 446 | return; |
| 479 | 447 | ||
| 480 | irq_num = VIA2_SOURCE_BASE; | 448 | irq_num = VIA2_SOURCE_BASE; |
| 481 | irq_bit = 1; | 449 | irq_bit = 1; |
| 482 | do { | 450 | do { |
| 483 | if (events & irq_bit) { | 451 | if (events & irq_bit) { |
| 484 | via2[gIFR] = irq_bit | rbv_clear; | 452 | via2[gIFR] = irq_bit | rbv_clear; |
| 485 | m68k_handle_int(irq_num); | 453 | generic_handle_irq(irq_num); |
| 486 | } | 454 | } |
| 487 | ++irq_num; | 455 | ++irq_num; |
| 488 | irq_bit <<= 1; | 456 | irq_bit <<= 1; |
| 489 | } while (events >= irq_bit); | 457 | } while (events >= irq_bit); |
| 490 | return IRQ_HANDLED; | ||
| 491 | } | 458 | } |
| 492 | 459 | ||
| 493 | /* | 460 | /* |
| @@ -495,7 +462,7 @@ irqreturn_t via2_irq(int irq, void *dev_id) | |||
| 495 | * VIA2 dispatcher as a fast interrupt handler. | 462 | * VIA2 dispatcher as a fast interrupt handler. |
| 496 | */ | 463 | */ |
| 497 | 464 | ||
| 498 | irqreturn_t via_nubus_irq(int irq, void *dev_id) | 465 | void via_nubus_irq(unsigned int irq, struct irq_desc *desc) |
| 499 | { | 466 | { |
| 500 | int slot_irq; | 467 | int slot_irq; |
| 501 | unsigned char slot_bit, events; | 468 | unsigned char slot_bit, events; |
| @@ -506,7 +473,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) | |||
| 506 | else | 473 | else |
| 507 | events &= ~via2[vDirA]; | 474 | events &= ~via2[vDirA]; |
| 508 | if (!events) | 475 | if (!events) |
| 509 | return IRQ_NONE; | 476 | return; |
| 510 | 477 | ||
| 511 | do { | 478 | do { |
| 512 | slot_irq = IRQ_NUBUS_F; | 479 | slot_irq = IRQ_NUBUS_F; |
| @@ -514,7 +481,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) | |||
| 514 | do { | 481 | do { |
| 515 | if (events & slot_bit) { | 482 | if (events & slot_bit) { |
| 516 | events &= ~slot_bit; | 483 | events &= ~slot_bit; |
| 517 | m68k_handle_int(slot_irq); | 484 | generic_handle_irq(slot_irq); |
| 518 | } | 485 | } |
| 519 | --slot_irq; | 486 | --slot_irq; |
| 520 | slot_bit >>= 1; | 487 | slot_bit >>= 1; |
| @@ -528,7 +495,24 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) | |||
| 528 | else | 495 | else |
| 529 | events &= ~via2[vDirA]; | 496 | events &= ~via2[vDirA]; |
| 530 | } while (events); | 497 | } while (events); |
| 531 | return IRQ_HANDLED; | 498 | } |
| 499 | |||
| 500 | /* | ||
| 501 | * Register the interrupt dispatchers for VIA or RBV machines only. | ||
| 502 | */ | ||
| 503 | |||
| 504 | void __init via_register_interrupts(void) | ||
| 505 | { | ||
| 506 | if (via_alt_mapping) { | ||
| 507 | /* software interrupt */ | ||
| 508 | irq_set_chained_handler(IRQ_AUTO_1, via1_irq); | ||
| 509 | /* via1 interrupt */ | ||
| 510 | irq_set_chained_handler(IRQ_AUTO_6, via1_irq); | ||
| 511 | } else { | ||
| 512 | irq_set_chained_handler(IRQ_AUTO_1, via1_irq); | ||
| 513 | } | ||
| 514 | irq_set_chained_handler(IRQ_AUTO_2, via2_irq); | ||
| 515 | irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq); | ||
| 532 | } | 516 | } |
| 533 | 517 | ||
| 534 | void via_irq_enable(int irq) { | 518 | void via_irq_enable(int irq) { |
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index 6cb9c3a9b6c9..5de924ef42ed 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c | |||
| @@ -81,7 +81,7 @@ static void mvme147_get_model(char *model) | |||
| 81 | 81 | ||
| 82 | void __init mvme147_init_IRQ(void) | 82 | void __init mvme147_init_IRQ(void) |
| 83 | { | 83 | { |
| 84 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); | 84 | m68k_setup_user_interrupt(VEC_USER, 192); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | void __init config_mvme147(void) | 87 | void __init config_mvme147(void) |
| @@ -114,8 +114,7 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id) | |||
| 114 | void mvme147_sched_init (irq_handler_t timer_routine) | 114 | void mvme147_sched_init (irq_handler_t timer_routine) |
| 115 | { | 115 | { |
| 116 | tick_handler = timer_routine; | 116 | tick_handler = timer_routine; |
| 117 | if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE, | 117 | if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL)) |
| 118 | "timer 1", NULL)) | ||
| 119 | pr_err("Couldn't register timer interrupt\n"); | 118 | pr_err("Couldn't register timer interrupt\n"); |
| 120 | 119 | ||
| 121 | /* Init the clock with a value */ | 120 | /* Init the clock with a value */ |
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 0b28e2621653..31a66d99cbca 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c | |||
| @@ -117,7 +117,7 @@ static void mvme16x_get_hardware_list(struct seq_file *m) | |||
| 117 | 117 | ||
| 118 | static void __init mvme16x_init_IRQ (void) | 118 | static void __init mvme16x_init_IRQ (void) |
| 119 | { | 119 | { |
| 120 | m68k_setup_user_interrupt(VEC_USER, 192, NULL); | 120 | m68k_setup_user_interrupt(VEC_USER, 192); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | #define pcc2chip ((volatile u_char *)0xfff42000) | 123 | #define pcc2chip ((volatile u_char *)0xfff42000) |
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index 9f0e3d59bf92..2b888491f29a 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c | |||
| @@ -15,10 +15,10 @@ | |||
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/irq.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
| 20 | #include <asm/system.h> | 21 | #include <asm/system.h> |
| 21 | #include <asm/irq.h> | ||
| 22 | #include <asm/traps.h> | 22 | #include <asm/traps.h> |
| 23 | 23 | ||
| 24 | #include <asm/q40_master.h> | 24 | #include <asm/q40_master.h> |
| @@ -35,35 +35,36 @@ | |||
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | static void q40_irq_handler(unsigned int, struct pt_regs *fp); | 37 | static void q40_irq_handler(unsigned int, struct pt_regs *fp); |
| 38 | static void q40_enable_irq(unsigned int); | 38 | static void q40_irq_enable(struct irq_data *data); |
| 39 | static void q40_disable_irq(unsigned int); | 39 | static void q40_irq_disable(struct irq_data *data); |
| 40 | 40 | ||
| 41 | unsigned short q40_ablecount[35]; | 41 | unsigned short q40_ablecount[35]; |
| 42 | unsigned short q40_state[35]; | 42 | unsigned short q40_state[35]; |
| 43 | 43 | ||
| 44 | static int q40_irq_startup(unsigned int irq) | 44 | static unsigned int q40_irq_startup(struct irq_data *data) |
| 45 | { | 45 | { |
| 46 | unsigned int irq = data->irq; | ||
| 47 | |||
| 46 | /* test for ISA ints not implemented by HW */ | 48 | /* test for ISA ints not implemented by HW */ |
| 47 | switch (irq) { | 49 | switch (irq) { |
| 48 | case 1: case 2: case 8: case 9: | 50 | case 1: case 2: case 8: case 9: |
| 49 | case 11: case 12: case 13: | 51 | case 11: case 12: case 13: |
| 50 | printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq); | 52 | printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq); |
| 51 | return -ENXIO; | 53 | /* FIXME return -ENXIO; */ |
| 52 | } | 54 | } |
| 53 | return 0; | 55 | return 0; |
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | static void q40_irq_shutdown(unsigned int irq) | 58 | static void q40_irq_shutdown(struct irq_data *data) |
| 57 | { | 59 | { |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | static struct irq_controller q40_irq_controller = { | 62 | static struct irq_chip q40_irq_chip = { |
| 61 | .name = "q40", | 63 | .name = "q40", |
| 62 | .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock), | 64 | .irq_startup = q40_irq_startup, |
| 63 | .startup = q40_irq_startup, | 65 | .irq_shutdown = q40_irq_shutdown, |
| 64 | .shutdown = q40_irq_shutdown, | 66 | .irq_enable = q40_irq_enable, |
| 65 | .enable = q40_enable_irq, | 67 | .irq_disable = q40_irq_disable, |
| 66 | .disable = q40_disable_irq, | ||
| 67 | }; | 68 | }; |
| 68 | 69 | ||
| 69 | /* | 70 | /* |
| @@ -81,13 +82,14 @@ static int disabled; | |||
| 81 | 82 | ||
| 82 | void __init q40_init_IRQ(void) | 83 | void __init q40_init_IRQ(void) |
| 83 | { | 84 | { |
| 84 | m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); | 85 | m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, |
| 86 | Q40_IRQ_MAX); | ||
| 85 | 87 | ||
| 86 | /* setup handler for ISA ints */ | 88 | /* setup handler for ISA ints */ |
| 87 | m68k_setup_auto_interrupt(q40_irq_handler); | 89 | m68k_setup_auto_interrupt(q40_irq_handler); |
| 88 | 90 | ||
| 89 | m68k_irq_startup(IRQ_AUTO_2); | 91 | m68k_irq_startup_irq(IRQ_AUTO_2); |
| 90 | m68k_irq_startup(IRQ_AUTO_4); | 92 | m68k_irq_startup_irq(IRQ_AUTO_4); |
| 91 | 93 | ||
| 92 | /* now enable some ints.. */ | 94 | /* now enable some ints.. */ |
| 93 | master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ | 95 | master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ |
| @@ -218,11 +220,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) | |||
| 218 | switch (irq) { | 220 | switch (irq) { |
| 219 | case 4: | 221 | case 4: |
| 220 | case 6: | 222 | case 6: |
| 221 | __m68k_handle_int(Q40_IRQ_SAMPLE, fp); | 223 | do_IRQ(Q40_IRQ_SAMPLE, fp); |
| 222 | return; | 224 | return; |
| 223 | } | 225 | } |
| 224 | if (mir & Q40_IRQ_FRAME_MASK) { | 226 | if (mir & Q40_IRQ_FRAME_MASK) { |
| 225 | __m68k_handle_int(Q40_IRQ_FRAME, fp); | 227 | do_IRQ(Q40_IRQ_FRAME, fp); |
| 226 | master_outb(-1, FRAME_CLEAR_REG); | 228 | master_outb(-1, FRAME_CLEAR_REG); |
| 227 | } | 229 | } |
| 228 | if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { | 230 | if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { |
| @@ -257,7 +259,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) | |||
| 257 | goto iirq; | 259 | goto iirq; |
| 258 | } | 260 | } |
| 259 | q40_state[irq] |= IRQ_INPROGRESS; | 261 | q40_state[irq] |= IRQ_INPROGRESS; |
| 260 | __m68k_handle_int(irq, fp); | 262 | do_IRQ(irq, fp); |
| 261 | q40_state[irq] &= ~IRQ_INPROGRESS; | 263 | q40_state[irq] &= ~IRQ_INPROGRESS; |
| 262 | 264 | ||
| 263 | /* naively enable everything, if that fails than */ | 265 | /* naively enable everything, if that fails than */ |
| @@ -288,25 +290,29 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) | |||
| 288 | mir = master_inb(IIRQ_REG); | 290 | mir = master_inb(IIRQ_REG); |
| 289 | /* should test whether keyboard irq is really enabled, doing it in defhand */ | 291 | /* should test whether keyboard irq is really enabled, doing it in defhand */ |
| 290 | if (mir & Q40_IRQ_KEYB_MASK) | 292 | if (mir & Q40_IRQ_KEYB_MASK) |
| 291 | __m68k_handle_int(Q40_IRQ_KEYBOARD, fp); | 293 | do_IRQ(Q40_IRQ_KEYBOARD, fp); |
| 292 | 294 | ||
| 293 | return; | 295 | return; |
| 294 | } | 296 | } |
| 295 | 297 | ||
| 296 | void q40_enable_irq(unsigned int irq) | 298 | void q40_irq_enable(struct irq_data *data) |
| 297 | { | 299 | { |
| 300 | unsigned int irq = data->irq; | ||
| 301 | |||
| 298 | if (irq >= 5 && irq <= 15) { | 302 | if (irq >= 5 && irq <= 15) { |
| 299 | mext_disabled--; | 303 | mext_disabled--; |
| 300 | if (mext_disabled > 0) | 304 | if (mext_disabled > 0) |
| 301 | printk("q40_enable_irq : nested disable/enable\n"); | 305 | printk("q40_irq_enable : nested disable/enable\n"); |
| 302 | if (mext_disabled == 0) | 306 | if (mext_disabled == 0) |
| 303 | master_outb(1, EXT_ENABLE_REG); | 307 | master_outb(1, EXT_ENABLE_REG); |
| 304 | } | 308 | } |
| 305 | } | 309 | } |
| 306 | 310 | ||
| 307 | 311 | ||
| 308 | void q40_disable_irq(unsigned int irq) | 312 | void q40_irq_disable(struct irq_data *data) |
| 309 | { | 313 | { |
| 314 | unsigned int irq = data->irq; | ||
| 315 | |||
| 310 | /* disable ISA iqs : only do something if the driver has been | 316 | /* disable ISA iqs : only do something if the driver has been |
| 311 | * verified to be Q40 "compatible" - right now IDE, NE2K | 317 | * verified to be Q40 "compatible" - right now IDE, NE2K |
| 312 | * Any driver should not attempt to sleep across disable_irq !! | 318 | * Any driver should not attempt to sleep across disable_irq !! |
| @@ -319,13 +325,3 @@ void q40_disable_irq(unsigned int irq) | |||
| 319 | printk("disable_irq nesting count %d\n",mext_disabled); | 325 | printk("disable_irq nesting count %d\n",mext_disabled); |
| 320 | } | 326 | } |
| 321 | } | 327 | } |
| 322 | |||
| 323 | unsigned long q40_probe_irq_on(void) | ||
| 324 | { | ||
| 325 | printk("irq probing not working - reconfigure the driver to avoid this\n"); | ||
| 326 | return -1; | ||
| 327 | } | ||
| 328 | int q40_probe_irq_off(unsigned long irqs) | ||
| 329 | { | ||
| 330 | return -1; | ||
| 331 | } | ||
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 6464ad3ae3e6..78b60f53e90a 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c | |||
| @@ -51,25 +51,29 @@ void sun3_disable_irq(unsigned int irq) | |||
| 51 | 51 | ||
| 52 | static irqreturn_t sun3_int7(int irq, void *dev_id) | 52 | static irqreturn_t sun3_int7(int irq, void *dev_id) |
| 53 | { | 53 | { |
| 54 | *sun3_intreg |= (1 << irq); | 54 | unsigned int cnt; |
| 55 | if (!(kstat_cpu(0).irqs[irq] % 2000)) | 55 | |
| 56 | sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 16000) / 2000]); | 56 | cnt = kstat_irqs_cpu(irq, 0); |
| 57 | if (!(cnt % 2000)) | ||
| 58 | sun3_leds(led_pattern[cnt % 16000 / 2000]); | ||
| 57 | return IRQ_HANDLED; | 59 | return IRQ_HANDLED; |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | static irqreturn_t sun3_int5(int irq, void *dev_id) | 62 | static irqreturn_t sun3_int5(int irq, void *dev_id) |
| 61 | { | 63 | { |
| 64 | unsigned int cnt; | ||
| 65 | |||
| 62 | #ifdef CONFIG_SUN3 | 66 | #ifdef CONFIG_SUN3 |
| 63 | intersil_clear(); | 67 | intersil_clear(); |
| 64 | #endif | 68 | #endif |
| 65 | *sun3_intreg |= (1 << irq); | ||
| 66 | #ifdef CONFIG_SUN3 | 69 | #ifdef CONFIG_SUN3 |
| 67 | intersil_clear(); | 70 | intersil_clear(); |
| 68 | #endif | 71 | #endif |
| 69 | xtime_update(1); | 72 | xtime_update(1); |
| 70 | update_process_times(user_mode(get_irq_regs())); | 73 | update_process_times(user_mode(get_irq_regs())); |
| 71 | if (!(kstat_cpu(0).irqs[irq] % 20)) | 74 | cnt = kstat_irqs_cpu(irq, 0); |
| 72 | sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]); | 75 | if (!(cnt % 20)) |
| 76 | sun3_leds(led_pattern[cnt % 160 / 20]); | ||
| 73 | return IRQ_HANDLED; | 77 | return IRQ_HANDLED; |
| 74 | } | 78 | } |
| 75 | 79 | ||
| @@ -79,29 +83,33 @@ static irqreturn_t sun3_vec255(int irq, void *dev_id) | |||
| 79 | return IRQ_HANDLED; | 83 | return IRQ_HANDLED; |
| 80 | } | 84 | } |
| 81 | 85 | ||
| 82 | static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) | 86 | static void sun3_irq_enable(struct irq_data *data) |
| 83 | { | 87 | { |
| 84 | *sun3_intreg &= ~(1 << irq); | 88 | sun3_enable_irq(data->irq); |
| 89 | }; | ||
| 85 | 90 | ||
| 86 | __m68k_handle_int(irq, fp); | 91 | static void sun3_irq_disable(struct irq_data *data) |
| 87 | } | 92 | { |
| 93 | sun3_disable_irq(data->irq); | ||
| 94 | }; | ||
| 88 | 95 | ||
| 89 | static struct irq_controller sun3_irq_controller = { | 96 | static struct irq_chip sun3_irq_chip = { |
| 90 | .name = "sun3", | 97 | .name = "sun3", |
| 91 | .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock), | 98 | .irq_startup = m68k_irq_startup, |
| 92 | .startup = m68k_irq_startup, | 99 | .irq_shutdown = m68k_irq_shutdown, |
| 93 | .shutdown = m68k_irq_shutdown, | 100 | .irq_enable = sun3_irq_enable, |
| 94 | .enable = sun3_enable_irq, | 101 | .irq_disable = sun3_irq_disable, |
| 95 | .disable = sun3_disable_irq, | 102 | .irq_mask = sun3_irq_disable, |
| 103 | .irq_unmask = sun3_irq_enable, | ||
| 96 | }; | 104 | }; |
| 97 | 105 | ||
| 98 | void __init sun3_init_IRQ(void) | 106 | void __init sun3_init_IRQ(void) |
| 99 | { | 107 | { |
| 100 | *sun3_intreg = 1; | 108 | *sun3_intreg = 1; |
| 101 | 109 | ||
| 102 | m68k_setup_auto_interrupt(sun3_inthandle); | 110 | m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1, |
| 103 | m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); | 111 | 7); |
| 104 | m68k_setup_user_interrupt(VEC_USER, 128, NULL); | 112 | m68k_setup_user_interrupt(VEC_USER, 128); |
| 105 | 113 | ||
| 106 | if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) | 114 | if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) |
| 107 | pr_err("Couldn't register %s interrupt\n", "int5"); | 115 | pr_err("Couldn't register %s interrupt\n", "int5"); |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9b4cb00407d7..0be318609fc6 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
| @@ -286,11 +286,11 @@ CLEAN_FILES += vmlinux.32 vmlinux.64 | |||
| 286 | archprepare: | 286 | archprepare: |
| 287 | ifdef CONFIG_MIPS32_N32 | 287 | ifdef CONFIG_MIPS32_N32 |
| 288 | @echo ' Checking missing-syscalls for N32' | 288 | @echo ' Checking missing-syscalls for N32' |
| 289 | $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=n32" | 289 | $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=n32" |
| 290 | endif | 290 | endif |
| 291 | ifdef CONFIG_MIPS32_O32 | 291 | ifdef CONFIG_MIPS32_O32 |
| 292 | @echo ' Checking missing-syscalls for O32' | 292 | @echo ' Checking missing-syscalls for O32' |
| 293 | $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=32" | 293 | $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=32" |
| 294 | endif | 294 | endif |
| 295 | 295 | ||
| 296 | install: | 296 | install: |
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts new file mode 100644 index 000000000000..0e00e508eaa6 --- /dev/null +++ b/arch/powerpc/boot/dts/charon.dts | |||
| @@ -0,0 +1,236 @@ | |||
| 1 | /* | ||
| 2 | * charon board Device Tree Source | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007 Semihalf | ||
| 5 | * Marian Balakowicz <m8@semihalf.com> | ||
| 6 | * | ||
| 7 | * Copyright (C) 2010 DENX Software Engineering GmbH | ||
| 8 | * Heiko Schocher <hs@denx.de> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 13 | * option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /dts-v1/; | ||
| 17 | |||
| 18 | / { | ||
| 19 | model = "anon,charon"; | ||
| 20 | compatible = "anon,charon"; | ||
| 21 | #address-cells = <1>; | ||
| 22 | #size-cells = <1>; | ||
| 23 | interrupt-parent = <&mpc5200_pic>; | ||
| 24 | |||
| 25 | cpus { | ||
| 26 | #address-cells = <1>; | ||
| 27 | #size-cells = <0>; | ||
| 28 | |||
| 29 | PowerPC,5200@0 { | ||
| 30 | device_type = "cpu"; | ||
| 31 | reg = <0>; | ||
| 32 | d-cache-line-size = <32>; | ||
| 33 | i-cache-line-size = <32>; | ||
| 34 | d-cache-size = <0x4000>; // L1, 16K | ||
| 35 | i-cache-size = <0x4000>; // L1, 16K | ||
| 36 | timebase-frequency = <0>; // from bootloader | ||
| 37 | bus-frequency = <0>; // from bootloader | ||
| 38 | clock-frequency = <0>; // from bootloader | ||
| 39 | }; | ||
| 40 | }; | ||
| 41 | |||
| 42 | memory { | ||
| 43 | device_type = "memory"; | ||
| 44 | reg = <0x00000000 0x08000000>; // 128MB | ||
| 45 | }; | ||
| 46 | |||
| 47 | soc5200@f0000000 { | ||
| 48 | #address-cells = <1>; | ||
| 49 | #size-cells = <1>; | ||
| 50 | compatible = "fsl,mpc5200-immr"; | ||
| 51 | ranges = <0 0xf0000000 0x0000c000>; | ||
| 52 | reg = <0xf0000000 0x00000100>; | ||
| 53 | bus-frequency = <0>; // from bootloader | ||
| 54 | system-frequency = <0>; // from bootloader | ||
| 55 | |||
| 56 | cdm@200 { | ||
| 57 | compatible = "fsl,mpc5200-cdm"; | ||
| 58 | reg = <0x200 0x38>; | ||
| 59 | }; | ||
| 60 | |||
| 61 | mpc5200_pic: interrupt-controller@500 { | ||
| 62 | // 5200 interrupts are encoded into two levels; | ||
| 63 | interrupt-controller; | ||
| 64 | #interrupt-cells = <3>; | ||
| 65 | compatible = "fsl,mpc5200-pic"; | ||
| 66 | reg = <0x500 0x80>; | ||
| 67 | }; | ||
| 68 | |||
| 69 | timer@600 { // General Purpose Timer | ||
| 70 | compatible = "fsl,mpc5200-gpt"; | ||
| 71 | reg = <0x600 0x10>; | ||
| 72 | interrupts = <1 9 0>; | ||
| 73 | fsl,has-wdt; | ||
| 74 | }; | ||
| 75 | |||
| 76 | can@900 { | ||
| 77 | compatible = "fsl,mpc5200-mscan"; | ||
| 78 | interrupts = <2 17 0>; | ||
| 79 | reg = <0x900 0x80>; | ||
| 80 | }; | ||
| 81 | |||
| 82 | can@980 { | ||
| 83 | compatible = "fsl,mpc5200-mscan"; | ||
| 84 | interrupts = <2 18 0>; | ||
| 85 | reg = <0x980 0x80>; | ||
| 86 | }; | ||
| 87 | |||
| 88 | gpio_simple: gpio@b00 { | ||
| 89 | compatible = "fsl,mpc5200-gpio"; | ||
| 90 | reg = <0xb00 0x40>; | ||
| 91 | interrupts = <1 7 0>; | ||
| 92 | gpio-controller; | ||
| 93 | #gpio-cells = <2>; | ||
| 94 | }; | ||
| 95 | |||
| 96 | usb@1000 { | ||
| 97 | compatible = "fsl,mpc5200-ohci","ohci-be"; | ||
| 98 | reg = <0x1000 0xff>; | ||
| 99 | interrupts = <2 6 0>; | ||
| 100 | }; | ||
| 101 | |||
| 102 | dma-controller@1200 { | ||
| 103 | device_type = "dma-controller"; | ||
| 104 | compatible = "fsl,mpc5200-bestcomm"; | ||
| 105 | reg = <0x1200 0x80>; | ||
| 106 | interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 | ||
| 107 | 3 4 0 3 5 0 3 6 0 3 7 0 | ||
| 108 | 3 8 0 3 9 0 3 10 0 3 11 0 | ||
| 109 | 3 12 0 3 13 0 3 14 0 3 15 0>; | ||
| 110 | }; | ||
| 111 | |||
| 112 | xlb@1f00 { | ||
| 113 | compatible = "fsl,mpc5200-xlb"; | ||
| 114 | reg = <0x1f00 0x100>; | ||
| 115 | }; | ||
| 116 | |||
| 117 | serial@2000 { // PSC1 | ||
| 118 | compatible = "fsl,mpc5200-psc-uart"; | ||
| 119 | reg = <0x2000 0x100>; | ||
| 120 | interrupts = <2 1 0>; | ||
| 121 | }; | ||
| 122 | |||
| 123 | serial@2400 { // PSC3 | ||
| 124 | compatible = "fsl,mpc5200-psc-uart"; | ||
| 125 | reg = <0x2400 0x100>; | ||
| 126 | interrupts = <2 3 0>; | ||
| 127 | }; | ||
| 128 | |||
| 129 | ethernet@3000 { | ||
| 130 | compatible = "fsl,mpc5200-fec"; | ||
| 131 | reg = <0x3000 0x400>; | ||
| 132 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
| 133 | interrupts = <2 5 0>; | ||
| 134 | fixed-link = <1 1 100 0 0>; | ||
| 135 | }; | ||
| 136 | |||
| 137 | mdio@3000 { | ||
| 138 | #address-cells = <1>; | ||
| 139 | #size-cells = <0>; | ||
| 140 | compatible = "fsl,mpc5200-mdio"; | ||
| 141 | reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts | ||
| 142 | interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. | ||
| 143 | }; | ||
| 144 | |||
| 145 | ata@3a00 { | ||
| 146 | compatible = "fsl,mpc5200-ata"; | ||
| 147 | reg = <0x3a00 0x100>; | ||
| 148 | interrupts = <2 7 0>; | ||
| 149 | }; | ||
| 150 | |||
| 151 | i2c@3d00 { | ||
| 152 | #address-cells = <1>; | ||
| 153 | #size-cells = <0>; | ||
| 154 | compatible = "fsl,mpc5200-i2c","fsl-i2c"; | ||
| 155 | reg = <0x3d00 0x40>; | ||
| 156 | interrupts = <2 15 0>; | ||
| 157 | }; | ||
| 158 | |||
| 159 | |||
| 160 | i2c@3d40 { | ||
| 161 | #address-cells = <1>; | ||
| 162 | #size-cells = <0>; | ||
| 163 | compatible = "fsl,mpc5200-i2c","fsl-i2c"; | ||
| 164 | reg = <0x3d40 0x40>; | ||
| 165 | interrupts = <2 16 0>; | ||
| 166 | |||
| 167 | dtt@28 { | ||
| 168 | compatible = "national,lm80"; | ||
| 169 | reg = <0x28>; | ||
| 170 | }; | ||
| 171 | |||
| 172 | rtc@68 { | ||
| 173 | compatible = "dallas,ds1374"; | ||
| 174 | reg = <0x68>; | ||
| 175 | }; | ||
| 176 | }; | ||
| 177 | |||
| 178 | sram@8000 { | ||
| 179 | compatible = "fsl,mpc5200-sram"; | ||
| 180 | reg = <0x8000 0x4000>; | ||
| 181 | }; | ||
| 182 | }; | ||
| 183 | |||
| 184 | localbus { | ||
| 185 | compatible = "fsl,mpc5200-lpb","simple-bus"; | ||
| 186 | #address-cells = <2>; | ||
| 187 | #size-cells = <1>; | ||
| 188 | ranges = < 0 0 0xfc000000 0x02000000 | ||
| 189 | 1 0 0xe0000000 0x04000000 // CS1 range, SM501 | ||
| 190 | 3 0 0xe8000000 0x00080000>; | ||
| 191 | |||
| 192 | flash@0,0 { | ||
| 193 | compatible = "cfi-flash"; | ||
| 194 | reg = <0 0 0x02000000>; | ||
| 195 | bank-width = <4>; | ||
| 196 | device-width = <2>; | ||
| 197 | #size-cells = <1>; | ||
| 198 | #address-cells = <1>; | ||
| 199 | }; | ||
| 200 | |||
| 201 | display@1,0 { | ||
| 202 | compatible = "smi,sm501"; | ||
| 203 | reg = <1 0x00000000 0x00800000 | ||
| 204 | 1 0x03e00000 0x00200000>; | ||
| 205 | mode = "640x480-32@60"; | ||
| 206 | interrupts = <1 1 3>; | ||
| 207 | little-endian; | ||
| 208 | }; | ||
| 209 | |||
| 210 | mram0@3,0 { | ||
| 211 | compatible = "mtd-ram"; | ||
| 212 | reg = <3 0x00000 0x80000>; | ||
| 213 | bank-width = <1>; | ||
| 214 | }; | ||
| 215 | }; | ||
| 216 | |||
| 217 | pci@f0000d00 { | ||
| 218 | #interrupt-cells = <1>; | ||
| 219 | #size-cells = <2>; | ||
| 220 | #address-cells = <3>; | ||
| 221 | device_type = "pci"; | ||
| 222 | compatible = "fsl,mpc5200-pci"; | ||
| 223 | reg = <0xf0000d00 0x100>; | ||
| 224 | interrupt-map-mask = <0xf800 0 0 7>; | ||
| 225 | interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 | ||
| 226 | 0xc000 0 0 2 &mpc5200_pic 0 0 3 | ||
| 227 | 0xc000 0 0 3 &mpc5200_pic 0 0 3 | ||
| 228 | 0xc000 0 0 4 &mpc5200_pic 0 0 3>; | ||
| 229 | clock-frequency = <0>; // From boot loader | ||
| 230 | interrupts = <2 8 0 2 9 0 2 10 0>; | ||
| 231 | bus-range = <0 0>; | ||
| 232 | ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000 | ||
| 233 | 0x02000000 0 0x90000000 0x90000000 0 0x10000000 | ||
| 234 | 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>; | ||
| 235 | }; | ||
| 236 | }; | ||
diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index 959cd2cfc275..716a37be16e3 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | CONFIG_EXPERIMENTAL=y | 1 | CONFIG_EXPERIMENTAL=y |
| 2 | CONFIG_SYSVIPC=y | 2 | CONFIG_SYSVIPC=y |
| 3 | CONFIG_SPARSE_IRQ=y | ||
| 3 | CONFIG_LOG_BUF_SHIFT=14 | 4 | CONFIG_LOG_BUF_SHIFT=14 |
| 4 | CONFIG_BLK_DEV_INITRD=y | 5 | CONFIG_BLK_DEV_INITRD=y |
| 5 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 6 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
| 6 | CONFIG_EXPERT=y | 7 | CONFIG_EMBEDDED=y |
| 7 | # CONFIG_SYSCTL_SYSCALL is not set | 8 | # CONFIG_SYSCTL_SYSCALL is not set |
| 8 | # CONFIG_KALLSYMS is not set | 9 | # CONFIG_KALLSYMS is not set |
| 9 | # CONFIG_EPOLL is not set | 10 | # CONFIG_EPOLL is not set |
| @@ -17,7 +18,6 @@ CONFIG_PPC_MPC5200_SIMPLE=y | |||
| 17 | CONFIG_PPC_MPC5200_BUGFIX=y | 18 | CONFIG_PPC_MPC5200_BUGFIX=y |
| 18 | # CONFIG_PPC_PMAC is not set | 19 | # CONFIG_PPC_PMAC is not set |
| 19 | CONFIG_PPC_BESTCOMM=y | 20 | CONFIG_PPC_BESTCOMM=y |
| 20 | CONFIG_SPARSE_IRQ=y | ||
| 21 | CONFIG_PM=y | 21 | CONFIG_PM=y |
| 22 | # CONFIG_PCI is not set | 22 | # CONFIG_PCI is not set |
| 23 | CONFIG_NET=y | 23 | CONFIG_NET=y |
| @@ -38,17 +38,18 @@ CONFIG_MTD=y | |||
| 38 | CONFIG_MTD_CONCAT=y | 38 | CONFIG_MTD_CONCAT=y |
| 39 | CONFIG_MTD_PARTITIONS=y | 39 | CONFIG_MTD_PARTITIONS=y |
| 40 | CONFIG_MTD_CMDLINE_PARTS=y | 40 | CONFIG_MTD_CMDLINE_PARTS=y |
| 41 | CONFIG_MTD_OF_PARTS=y | ||
| 41 | CONFIG_MTD_CHAR=y | 42 | CONFIG_MTD_CHAR=y |
| 42 | CONFIG_MTD_BLOCK=y | 43 | CONFIG_MTD_BLOCK=y |
| 43 | CONFIG_MTD_CFI=y | 44 | CONFIG_MTD_CFI=y |
| 44 | CONFIG_MTD_CFI_AMDSTD=y | 45 | CONFIG_MTD_CFI_AMDSTD=y |
| 45 | CONFIG_MTD_ROM=y | 46 | CONFIG_MTD_ROM=y |
| 46 | CONFIG_MTD_PHYSMAP_OF=y | 47 | CONFIG_MTD_PHYSMAP_OF=y |
| 48 | CONFIG_MTD_PLATRAM=y | ||
| 47 | CONFIG_PROC_DEVICETREE=y | 49 | CONFIG_PROC_DEVICETREE=y |
| 48 | CONFIG_BLK_DEV_LOOP=y | 50 | CONFIG_BLK_DEV_LOOP=y |
| 49 | CONFIG_BLK_DEV_RAM=y | 51 | CONFIG_BLK_DEV_RAM=y |
| 50 | CONFIG_BLK_DEV_RAM_SIZE=32768 | 52 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
| 51 | # CONFIG_MISC_DEVICES is not set | ||
| 52 | CONFIG_BLK_DEV_SD=y | 53 | CONFIG_BLK_DEV_SD=y |
| 53 | CONFIG_CHR_DEV_SG=y | 54 | CONFIG_CHR_DEV_SG=y |
| 54 | CONFIG_ATA=y | 55 | CONFIG_ATA=y |
| @@ -56,13 +57,11 @@ CONFIG_PATA_MPC52xx=y | |||
| 56 | CONFIG_PATA_PLATFORM=y | 57 | CONFIG_PATA_PLATFORM=y |
| 57 | CONFIG_NETDEVICES=y | 58 | CONFIG_NETDEVICES=y |
| 58 | CONFIG_LXT_PHY=y | 59 | CONFIG_LXT_PHY=y |
| 60 | CONFIG_FIXED_PHY=y | ||
| 59 | CONFIG_NET_ETHERNET=y | 61 | CONFIG_NET_ETHERNET=y |
| 60 | CONFIG_FEC_MPC52xx=y | 62 | CONFIG_FEC_MPC52xx=y |
| 61 | # CONFIG_NETDEV_1000 is not set | 63 | # CONFIG_NETDEV_1000 is not set |
| 62 | # CONFIG_NETDEV_10000 is not set | 64 | # CONFIG_NETDEV_10000 is not set |
| 63 | # CONFIG_INPUT is not set | ||
| 64 | # CONFIG_SERIO is not set | ||
| 65 | # CONFIG_VT is not set | ||
| 66 | CONFIG_SERIAL_MPC52xx=y | 65 | CONFIG_SERIAL_MPC52xx=y |
| 67 | CONFIG_SERIAL_MPC52xx_CONSOLE=y | 66 | CONFIG_SERIAL_MPC52xx_CONSOLE=y |
| 68 | CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 | 67 | CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 |
| @@ -70,7 +69,13 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 | |||
| 70 | CONFIG_I2C=y | 69 | CONFIG_I2C=y |
| 71 | CONFIG_I2C_CHARDEV=y | 70 | CONFIG_I2C_CHARDEV=y |
| 72 | CONFIG_I2C_MPC=y | 71 | CONFIG_I2C_MPC=y |
| 72 | CONFIG_SENSORS_LM80=y | ||
| 73 | CONFIG_WATCHDOG=y | 73 | CONFIG_WATCHDOG=y |
| 74 | CONFIG_MFD_SM501=y | ||
| 75 | CONFIG_FB=y | ||
| 76 | CONFIG_FB_FOREIGN_ENDIAN=y | ||
| 77 | CONFIG_FB_SM501=y | ||
| 78 | CONFIG_FRAMEBUFFER_CONSOLE=y | ||
| 74 | CONFIG_USB=y | 79 | CONFIG_USB=y |
| 75 | CONFIG_USB_DEVICEFS=y | 80 | CONFIG_USB_DEVICEFS=y |
| 76 | # CONFIG_USB_DEVICE_CLASS is not set | 81 | # CONFIG_USB_DEVICE_CLASS is not set |
| @@ -80,10 +85,10 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y | |||
| 80 | CONFIG_USB_STORAGE=y | 85 | CONFIG_USB_STORAGE=y |
| 81 | CONFIG_RTC_CLASS=y | 86 | CONFIG_RTC_CLASS=y |
| 82 | CONFIG_RTC_DRV_DS1307=y | 87 | CONFIG_RTC_DRV_DS1307=y |
| 88 | CONFIG_RTC_DRV_DS1374=y | ||
| 83 | CONFIG_EXT2_FS=y | 89 | CONFIG_EXT2_FS=y |
| 84 | CONFIG_EXT3_FS=y | 90 | CONFIG_EXT3_FS=y |
| 85 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | 91 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set |
| 86 | CONFIG_INOTIFY=y | ||
| 87 | CONFIG_MSDOS_FS=y | 92 | CONFIG_MSDOS_FS=y |
| 88 | CONFIG_VFAT_FS=y | 93 | CONFIG_VFAT_FS=y |
| 89 | CONFIG_PROC_KCORE=y | 94 | CONFIG_PROC_KCORE=y |
| @@ -102,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y | |||
| 102 | CONFIG_DETECT_HUNG_TASK=y | 107 | CONFIG_DETECT_HUNG_TASK=y |
| 103 | # CONFIG_DEBUG_BUGVERBOSE is not set | 108 | # CONFIG_DEBUG_BUGVERBOSE is not set |
| 104 | CONFIG_DEBUG_INFO=y | 109 | CONFIG_DEBUG_INFO=y |
| 105 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 106 | CONFIG_CRYPTO_ECB=y | 110 | CONFIG_CRYPTO_ECB=y |
| 107 | CONFIG_CRYPTO_PCBC=y | 111 | CONFIG_CRYPTO_PCBC=y |
| 108 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 112 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 84a685a505fe..535711fcb13c 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig | |||
| @@ -485,3 +485,7 @@ CONFIG_CRYPTO_TWOFISH=m | |||
| 485 | CONFIG_CRYPTO_LZO=m | 485 | CONFIG_CRYPTO_LZO=m |
| 486 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 486 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 487 | # CONFIG_CRYPTO_HW is not set | 487 | # CONFIG_CRYPTO_HW is not set |
| 488 | CONFIG_VIRTUALIZATION=y | ||
| 489 | CONFIG_KVM_BOOK3S_64=m | ||
| 490 | CONFIG_KVM_BOOK3S_64_HV=y | ||
| 491 | CONFIG_VHOST_NET=m | ||
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 96a58b709705..a72f2415a647 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
| @@ -362,3 +362,7 @@ CONFIG_CRYPTO_TWOFISH=m | |||
| 362 | CONFIG_CRYPTO_LZO=m | 362 | CONFIG_CRYPTO_LZO=m |
| 363 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 363 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
| 364 | # CONFIG_CRYPTO_HW is not set | 364 | # CONFIG_CRYPTO_HW is not set |
| 365 | CONFIG_VIRTUALIZATION=y | ||
| 366 | CONFIG_KVM_BOOK3S_64=m | ||
| 367 | CONFIG_KVM_BOOK3S_64_HV=y | ||
| 368 | CONFIG_VHOST_NET=m | ||
diff --git a/arch/powerpc/include/asm/floppy.h b/arch/powerpc/include/asm/floppy.h index 24bd34c57e9d..936a904ae78c 100644 --- a/arch/powerpc/include/asm/floppy.h +++ b/arch/powerpc/include/asm/floppy.h | |||
| @@ -108,10 +108,10 @@ static int fd_request_irq(void) | |||
| 108 | { | 108 | { |
| 109 | if (can_use_virtual_dma) | 109 | if (can_use_virtual_dma) |
| 110 | return request_irq(FLOPPY_IRQ, floppy_hardint, | 110 | return request_irq(FLOPPY_IRQ, floppy_hardint, |
| 111 | IRQF_DISABLED, "floppy", NULL); | 111 | 0, "floppy", NULL); |
| 112 | else | 112 | else |
| 113 | return request_irq(FLOPPY_IRQ, floppy_interrupt, | 113 | return request_irq(FLOPPY_IRQ, floppy_interrupt, |
| 114 | IRQF_DISABLED, "floppy", NULL); | 114 | 0, "floppy", NULL); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) | 117 | static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) |
diff --git a/arch/powerpc/include/asm/lv1call.h b/arch/powerpc/include/asm/lv1call.h index 9cd5fc828a37..f77c708c67a0 100644 --- a/arch/powerpc/include/asm/lv1call.h +++ b/arch/powerpc/include/asm/lv1call.h | |||
| @@ -316,7 +316,7 @@ LV1_CALL(gpu_context_free, 1, 0, 218 ) | |||
| 316 | LV1_CALL(gpu_context_iomap, 5, 0, 221 ) | 316 | LV1_CALL(gpu_context_iomap, 5, 0, 221 ) |
| 317 | LV1_CALL(gpu_context_attribute, 6, 0, 225 ) | 317 | LV1_CALL(gpu_context_attribute, 6, 0, 225 ) |
| 318 | LV1_CALL(gpu_context_intr, 1, 1, 227 ) | 318 | LV1_CALL(gpu_context_intr, 1, 1, 227 ) |
| 319 | LV1_CALL(gpu_attribute, 5, 0, 228 ) | 319 | LV1_CALL(gpu_attribute, 3, 0, 228 ) |
| 320 | LV1_CALL(get_rtc, 0, 2, 232 ) | 320 | LV1_CALL(get_rtc, 0, 2, 232 ) |
| 321 | LV1_CALL(set_ppe_periodic_tracer_frequency, 1, 0, 240 ) | 321 | LV1_CALL(set_ppe_periodic_tracer_frequency, 1, 0, 240 ) |
| 322 | LV1_CALL(start_ppe_periodic_tracer, 5, 0, 241 ) | 322 | LV1_CALL(start_ppe_periodic_tracer, 5, 0, 241 ) |
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index bd6c401c0ee5..c48de98ba94e 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h | |||
| @@ -15,8 +15,8 @@ | |||
| 15 | #define DEFAULT_PRIORITY 5 | 15 | #define DEFAULT_PRIORITY 5 |
| 16 | 16 | ||
| 17 | /* | 17 | /* |
| 18 | * Mark IPIs as higher priority so we can take them inside interrupts that | 18 | * Mark IPIs as higher priority so we can take them inside interrupts |
| 19 | * arent marked IRQF_DISABLED | 19 | * FIXME: still true now? |
| 20 | */ | 20 | */ |
| 21 | #define IPI_PRIORITY 4 | 21 | #define IPI_PRIORITY 4 |
| 22 | 22 | ||
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index a54d92fec612..cf9c69b9189c 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -267,7 +267,7 @@ vsx_unavailable_pSeries_1: | |||
| 267 | 267 | ||
| 268 | #ifdef CONFIG_CBE_RAS | 268 | #ifdef CONFIG_CBE_RAS |
| 269 | STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) | 269 | STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) |
| 270 | KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1202) | 270 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) |
| 271 | #endif /* CONFIG_CBE_RAS */ | 271 | #endif /* CONFIG_CBE_RAS */ |
| 272 | 272 | ||
| 273 | STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) | 273 | STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) |
| @@ -275,7 +275,7 @@ vsx_unavailable_pSeries_1: | |||
| 275 | 275 | ||
| 276 | #ifdef CONFIG_CBE_RAS | 276 | #ifdef CONFIG_CBE_RAS |
| 277 | STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) | 277 | STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) |
| 278 | KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1602) | 278 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602) |
| 279 | #endif /* CONFIG_CBE_RAS */ | 279 | #endif /* CONFIG_CBE_RAS */ |
| 280 | 280 | ||
| 281 | STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) | 281 | STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) |
| @@ -283,7 +283,7 @@ vsx_unavailable_pSeries_1: | |||
| 283 | 283 | ||
| 284 | #ifdef CONFIG_CBE_RAS | 284 | #ifdef CONFIG_CBE_RAS |
| 285 | STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) | 285 | STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) |
| 286 | KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1802) | 286 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802) |
| 287 | #endif /* CONFIG_CBE_RAS */ | 287 | #endif /* CONFIG_CBE_RAS */ |
| 288 | 288 | ||
| 289 | . = 0x3000 | 289 | . = 0x3000 |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 25ddbfc7dd36..6df70907d60a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
| @@ -187,7 +187,7 @@ int smp_request_message_ipi(int virq, int msg) | |||
| 187 | return 1; | 187 | return 1; |
| 188 | } | 188 | } |
| 189 | #endif | 189 | #endif |
| 190 | err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU, | 190 | err = request_irq(virq, smp_ipi_action[msg], IRQF_PERCPU, |
| 191 | smp_ipi_name[msg], 0); | 191 | smp_ipi_name[msg], 0); |
| 192 | WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n", | 192 | WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n", |
| 193 | virq, smp_ipi_name[msg], err); | 193 | virq, smp_ipi_name[msg], err); |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index f422231d9235..44d8829334ab 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
| @@ -1263,7 +1263,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) | |||
| 1263 | addi r6,r5,VCORE_NAPPING_THREADS | 1263 | addi r6,r5,VCORE_NAPPING_THREADS |
| 1264 | 31: lwarx r4,0,r6 | 1264 | 31: lwarx r4,0,r6 |
| 1265 | or r4,r4,r0 | 1265 | or r4,r4,r0 |
| 1266 | popcntw r7,r4 | 1266 | PPC_POPCNTW(r7,r4) |
| 1267 | cmpw r7,r8 | 1267 | cmpw r7,r8 |
| 1268 | bge 2f | 1268 | bge 2f |
| 1269 | stwcx. r4,0,r6 | 1269 | stwcx. r4,0,r6 |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 16da595ff402..2dd6bdd31fe1 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/suspend.h> | 34 | #include <linux/suspend.h> |
| 35 | #include <linux/memblock.h> | 35 | #include <linux/memblock.h> |
| 36 | #include <linux/hugetlb.h> | 36 | #include <linux/hugetlb.h> |
| 37 | #include <linux/slab.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/pgalloc.h> | 39 | #include <asm/pgalloc.h> |
| 39 | #include <asm/prom.h> | 40 | #include <asm/prom.h> |
| @@ -555,3 +556,32 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, | |||
| 555 | book3e_hugetlb_preload(vma->vm_mm, address, *ptep); | 556 | book3e_hugetlb_preload(vma->vm_mm, address, *ptep); |
| 556 | #endif | 557 | #endif |
| 557 | } | 558 | } |
| 559 | |||
| 560 | /* | ||
| 561 | * System memory should not be in /proc/iomem but various tools expect it | ||
| 562 | * (eg kdump). | ||
| 563 | */ | ||
| 564 | static int add_system_ram_resources(void) | ||
| 565 | { | ||
| 566 | struct memblock_region *reg; | ||
| 567 | |||
| 568 | for_each_memblock(memory, reg) { | ||
| 569 | struct resource *res; | ||
| 570 | unsigned long base = reg->base; | ||
| 571 | unsigned long size = reg->size; | ||
| 572 | |||
| 573 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | ||
| 574 | WARN_ON(!res); | ||
| 575 | |||
| 576 | if (res) { | ||
| 577 | res->name = "System RAM"; | ||
| 578 | res->start = base; | ||
| 579 | res->end = base + size - 1; | ||
| 580 | res->flags = IORESOURCE_MEM; | ||
| 581 | WARN_ON(request_resource(&iomem_resource, res) < 0); | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 585 | return 0; | ||
| 586 | } | ||
| 587 | subsys_initcall(add_system_ram_resources); | ||
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index c7dd4dec4df8..b22a83a91cb8 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
| @@ -315,7 +315,10 @@ static int __init find_min_common_depth(void) | |||
| 315 | struct device_node *root; | 315 | struct device_node *root; |
| 316 | const char *vec5; | 316 | const char *vec5; |
| 317 | 317 | ||
| 318 | root = of_find_node_by_path("/rtas"); | 318 | if (firmware_has_feature(FW_FEATURE_OPAL)) |
| 319 | root = of_find_node_by_path("/ibm,opal"); | ||
| 320 | else | ||
| 321 | root = of_find_node_by_path("/rtas"); | ||
| 319 | if (!root) | 322 | if (!root) |
| 320 | root = of_find_node_by_path("/"); | 323 | root = of_find_node_by_path("/"); |
| 321 | 324 | ||
| @@ -344,12 +347,19 @@ static int __init find_min_common_depth(void) | |||
| 344 | 347 | ||
| 345 | #define VEC5_AFFINITY_BYTE 5 | 348 | #define VEC5_AFFINITY_BYTE 5 |
| 346 | #define VEC5_AFFINITY 0x80 | 349 | #define VEC5_AFFINITY 0x80 |
| 347 | chosen = of_find_node_by_path("/chosen"); | 350 | |
| 348 | if (chosen) { | 351 | if (firmware_has_feature(FW_FEATURE_OPAL)) |
| 349 | vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); | 352 | form1_affinity = 1; |
| 350 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { | 353 | else { |
| 351 | dbg("Using form 1 affinity\n"); | 354 | chosen = of_find_node_by_path("/chosen"); |
| 352 | form1_affinity = 1; | 355 | if (chosen) { |
| 356 | vec5 = of_get_property(chosen, | ||
| 357 | "ibm,architecture-vec-5", NULL); | ||
| 358 | if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & | ||
| 359 | VEC5_AFFINITY)) { | ||
| 360 | dbg("Using form 1 affinity\n"); | ||
| 361 | form1_affinity = 1; | ||
| 362 | } | ||
| 353 | } | 363 | } |
| 354 | } | 364 | } |
| 355 | 365 | ||
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c index e36d6e232ae6..846b789fb195 100644 --- a/arch/powerpc/platforms/52xx/mpc5200_simple.c +++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c | |||
| @@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void) | |||
| 50 | 50 | ||
| 51 | /* list of the supported boards */ | 51 | /* list of the supported boards */ |
| 52 | static const char *board[] __initdata = { | 52 | static const char *board[] __initdata = { |
| 53 | "anon,charon", | ||
| 53 | "intercontrol,digsy-mtc", | 54 | "intercontrol,digsy-mtc", |
| 54 | "manroland,mucmc52", | 55 | "manroland,mucmc52", |
| 55 | "manroland,uc101", | 56 | "manroland,uc101", |
diff --git a/arch/powerpc/platforms/cell/beat.c b/arch/powerpc/platforms/cell/beat.c index 232fc384e855..852592b2b712 100644 --- a/arch/powerpc/platforms/cell/beat.c +++ b/arch/powerpc/platforms/cell/beat.c | |||
| @@ -230,7 +230,7 @@ static int __init beat_register_event(void) | |||
| 230 | } | 230 | } |
| 231 | ev->virq = virq; | 231 | ev->virq = virq; |
| 232 | 232 | ||
| 233 | rc = request_irq(virq, ev->handler, IRQF_DISABLED, | 233 | rc = request_irq(virq, ev->handler, 0, |
| 234 | ev->typecode, NULL); | 234 | ev->typecode, NULL); |
| 235 | if (rc != 0) { | 235 | if (rc != 0) { |
| 236 | printk(KERN_ERR "Beat: failed to request virtual IRQ" | 236 | printk(KERN_ERR "Beat: failed to request virtual IRQ" |
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index ae790ac4a589..14be2bd358b8 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c | |||
| @@ -514,7 +514,7 @@ static __init int celleb_setup_pciex(struct device_node *node, | |||
| 514 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | 514 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
| 515 | oirq.size); | 515 | oirq.size); |
| 516 | if (request_irq(virq, pciex_handle_internal_irq, | 516 | if (request_irq(virq, pciex_handle_internal_irq, |
| 517 | IRQF_DISABLED, "pciex", (void *)phb)) { | 517 | 0, "pciex", (void *)phb)) { |
| 518 | pr_err("PCIEXC:Failed to request irq\n"); | 518 | pr_err("PCIEXC:Failed to request irq\n"); |
| 519 | goto error; | 519 | goto error; |
| 520 | } | 520 | } |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index fc46fcac3921..592c3d51b817 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
| @@ -412,8 +412,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) | |||
| 412 | IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT)); | 412 | IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT)); |
| 413 | BUG_ON(virq == NO_IRQ); | 413 | BUG_ON(virq == NO_IRQ); |
| 414 | 414 | ||
| 415 | ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED, | 415 | ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu); |
| 416 | iommu->name, iommu); | ||
| 417 | BUG_ON(ret); | 416 | BUG_ON(ret); |
| 418 | 417 | ||
| 419 | /* set the IOC segment table origin register (and turn on the iommu) */ | 418 | /* set the IOC segment table origin register (and turn on the iommu) */ |
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 1acf36010423..59c1a1694104 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c | |||
| @@ -392,7 +392,7 @@ static int __init cbe_init_pm_irq(void) | |||
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | rc = request_irq(irq, cbe_pm_irq, | 394 | rc = request_irq(irq, cbe_pm_irq, |
| 395 | IRQF_DISABLED, "cbe-pmu-0", NULL); | 395 | 0, "cbe-pmu-0", NULL); |
| 396 | if (rc) { | 396 | if (rc) { |
| 397 | printk("ERROR: Request for irq on node %d failed\n", | 397 | printk("ERROR: Request for irq on node %d failed\n", |
| 398 | node); | 398 | node); |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 3675da73623f..e94d3ecdd8bb 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
| @@ -442,8 +442,7 @@ static int spu_request_irqs(struct spu *spu) | |||
| 442 | snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", | 442 | snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", |
| 443 | spu->number); | 443 | spu->number); |
| 444 | ret = request_irq(spu->irqs[0], spu_irq_class_0, | 444 | ret = request_irq(spu->irqs[0], spu_irq_class_0, |
| 445 | IRQF_DISABLED, | 445 | 0, spu->irq_c0, spu); |
| 446 | spu->irq_c0, spu); | ||
| 447 | if (ret) | 446 | if (ret) |
| 448 | goto bail0; | 447 | goto bail0; |
| 449 | } | 448 | } |
| @@ -451,8 +450,7 @@ static int spu_request_irqs(struct spu *spu) | |||
| 451 | snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", | 450 | snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", |
| 452 | spu->number); | 451 | spu->number); |
| 453 | ret = request_irq(spu->irqs[1], spu_irq_class_1, | 452 | ret = request_irq(spu->irqs[1], spu_irq_class_1, |
| 454 | IRQF_DISABLED, | 453 | 0, spu->irq_c1, spu); |
| 455 | spu->irq_c1, spu); | ||
| 456 | if (ret) | 454 | if (ret) |
| 457 | goto bail1; | 455 | goto bail1; |
| 458 | } | 456 | } |
| @@ -460,8 +458,7 @@ static int spu_request_irqs(struct spu *spu) | |||
| 460 | snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", | 458 | snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", |
| 461 | spu->number); | 459 | spu->number); |
| 462 | ret = request_irq(spu->irqs[2], spu_irq_class_2, | 460 | ret = request_irq(spu->irqs[2], spu_irq_class_2, |
| 463 | IRQF_DISABLED, | 461 | 0, spu->irq_c2, spu); |
| 464 | spu->irq_c2, spu); | ||
| 465 | if (ret) | 462 | if (ret) |
| 466 | goto bail2; | 463 | goto bail2; |
| 467 | } | 464 | } |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index cb40e921a565..901bfbddc3dd 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
| @@ -272,7 +272,6 @@ static struct irqaction xmon_action = { | |||
| 272 | 272 | ||
| 273 | static struct irqaction gatwick_cascade_action = { | 273 | static struct irqaction gatwick_cascade_action = { |
| 274 | .handler = gatwick_action, | 274 | .handler = gatwick_action, |
| 275 | .flags = IRQF_DISABLED, | ||
| 276 | .name = "cascade", | 275 | .name = "cascade", |
| 277 | }; | 276 | }; |
| 278 | 277 | ||
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 9a521dc8e485..9b6a820bdd7d 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
| @@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void) | |||
| 200 | 200 | ||
| 201 | if (psurge_secondary_virq) | 201 | if (psurge_secondary_virq) |
| 202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, | 202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, |
| 203 | IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL); | 203 | IRQF_PERCPU, "IPI", NULL); |
| 204 | 204 | ||
| 205 | if (rc) | 205 | if (rc) |
| 206 | pr_err("Failed to setup secondary cpu IPI\n"); | 206 | pr_err("Failed to setup secondary cpu IPI\n"); |
| @@ -408,7 +408,7 @@ static int __init smp_psurge_kick_cpu(int nr) | |||
| 408 | 408 | ||
| 409 | static struct irqaction psurge_irqaction = { | 409 | static struct irqaction psurge_irqaction = { |
| 410 | .handler = psurge_ipi_intr, | 410 | .handler = psurge_ipi_intr, |
| 411 | .flags = IRQF_DISABLED|IRQF_PERCPU, | 411 | .flags = IRQF_PERCPU, |
| 412 | .name = "primary IPI", | 412 | .name = "primary IPI", |
| 413 | }; | 413 | }; |
| 414 | 414 | ||
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 6c4b5837fc8a..3f175e8aedb4 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c | |||
| @@ -825,7 +825,7 @@ static int ps3_probe_thread(void *data) | |||
| 825 | 825 | ||
| 826 | spin_lock_init(&dev.lock); | 826 | spin_lock_init(&dev.lock); |
| 827 | 827 | ||
| 828 | res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED, | 828 | res = request_irq(irq, ps3_notification_interrupt, 0, |
| 829 | "ps3_notification", &dev); | 829 | "ps3_notification", &dev); |
| 830 | if (res) { | 830 | if (res) { |
| 831 | pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, | 831 | pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, |
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 5e304c292f68..ca40f6afd35d 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c | |||
| @@ -184,7 +184,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index, | |||
| 184 | enum ps3_bus_type *bus_type) | 184 | enum ps3_bus_type *bus_type) |
| 185 | { | 185 | { |
| 186 | int result; | 186 | int result; |
| 187 | u64 v1; | 187 | u64 v1 = 0; |
| 188 | 188 | ||
| 189 | result = read_node(PS3_LPAR_ID_PME, | 189 | result = read_node(PS3_LPAR_ID_PME, |
| 190 | make_first_field("bus", bus_index), | 190 | make_first_field("bus", bus_index), |
| @@ -199,7 +199,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index, | |||
| 199 | unsigned int *num_dev) | 199 | unsigned int *num_dev) |
| 200 | { | 200 | { |
| 201 | int result; | 201 | int result; |
| 202 | u64 v1; | 202 | u64 v1 = 0; |
| 203 | 203 | ||
| 204 | result = read_node(PS3_LPAR_ID_PME, | 204 | result = read_node(PS3_LPAR_ID_PME, |
| 205 | make_first_field("bus", bus_index), | 205 | make_first_field("bus", bus_index), |
| @@ -239,7 +239,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index, | |||
| 239 | unsigned int dev_index, enum ps3_dev_type *dev_type) | 239 | unsigned int dev_index, enum ps3_dev_type *dev_type) |
| 240 | { | 240 | { |
| 241 | int result; | 241 | int result; |
| 242 | u64 v1; | 242 | u64 v1 = 0; |
| 243 | 243 | ||
| 244 | result = read_node(PS3_LPAR_ID_PME, | 244 | result = read_node(PS3_LPAR_ID_PME, |
| 245 | make_first_field("bus", bus_index), | 245 | make_first_field("bus", bus_index), |
| @@ -256,8 +256,8 @@ int ps3_repository_read_dev_intr(unsigned int bus_index, | |||
| 256 | enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id) | 256 | enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id) |
| 257 | { | 257 | { |
| 258 | int result; | 258 | int result; |
| 259 | u64 v1; | 259 | u64 v1 = 0; |
| 260 | u64 v2; | 260 | u64 v2 = 0; |
| 261 | 261 | ||
| 262 | result = read_node(PS3_LPAR_ID_PME, | 262 | result = read_node(PS3_LPAR_ID_PME, |
| 263 | make_first_field("bus", bus_index), | 263 | make_first_field("bus", bus_index), |
| @@ -275,7 +275,7 @@ int ps3_repository_read_dev_reg_type(unsigned int bus_index, | |||
| 275 | enum ps3_reg_type *reg_type) | 275 | enum ps3_reg_type *reg_type) |
| 276 | { | 276 | { |
| 277 | int result; | 277 | int result; |
| 278 | u64 v1; | 278 | u64 v1 = 0; |
| 279 | 279 | ||
| 280 | result = read_node(PS3_LPAR_ID_PME, | 280 | result = read_node(PS3_LPAR_ID_PME, |
| 281 | make_first_field("bus", bus_index), | 281 | make_first_field("bus", bus_index), |
| @@ -615,7 +615,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, | |||
| 615 | unsigned int dev_index, unsigned int *num_regions) | 615 | unsigned int dev_index, unsigned int *num_regions) |
| 616 | { | 616 | { |
| 617 | int result; | 617 | int result; |
| 618 | u64 v1; | 618 | u64 v1 = 0; |
| 619 | 619 | ||
| 620 | result = read_node(PS3_LPAR_ID_PME, | 620 | result = read_node(PS3_LPAR_ID_PME, |
| 621 | make_first_field("bus", bus_index), | 621 | make_first_field("bus", bus_index), |
| @@ -631,7 +631,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, | |||
| 631 | unsigned int *region_id) | 631 | unsigned int *region_id) |
| 632 | { | 632 | { |
| 633 | int result; | 633 | int result; |
| 634 | u64 v1; | 634 | u64 v1 = 0; |
| 635 | 635 | ||
| 636 | result = read_node(PS3_LPAR_ID_PME, | 636 | result = read_node(PS3_LPAR_ID_PME, |
| 637 | make_first_field("bus", bus_index), | 637 | make_first_field("bus", bus_index), |
| @@ -786,7 +786,7 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total) | |||
| 786 | int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) | 786 | int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) |
| 787 | { | 787 | { |
| 788 | int result; | 788 | int result; |
| 789 | u64 v1; | 789 | u64 v1 = 0; |
| 790 | 790 | ||
| 791 | result = read_node(PS3_LPAR_ID_CURRENT, | 791 | result = read_node(PS3_LPAR_ID_CURRENT, |
| 792 | make_first_field("bi", 0), | 792 | make_first_field("bi", 0), |
| @@ -805,7 +805,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) | |||
| 805 | int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) | 805 | int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) |
| 806 | { | 806 | { |
| 807 | int result; | 807 | int result; |
| 808 | u64 v1; | 808 | u64 v1 = 0; |
| 809 | 809 | ||
| 810 | result = read_node(PS3_LPAR_ID_CURRENT, | 810 | result = read_node(PS3_LPAR_ID_CURRENT, |
| 811 | make_first_field("bi", 0), | 811 | make_first_field("bi", 0), |
| @@ -827,8 +827,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index, | |||
| 827 | enum ps3_spu_resource_type *resource_type, unsigned int *resource_id) | 827 | enum ps3_spu_resource_type *resource_type, unsigned int *resource_id) |
| 828 | { | 828 | { |
| 829 | int result; | 829 | int result; |
| 830 | u64 v1; | 830 | u64 v1 = 0; |
| 831 | u64 v2; | 831 | u64 v2 = 0; |
| 832 | 832 | ||
| 833 | result = read_node(PS3_LPAR_ID_CURRENT, | 833 | result = read_node(PS3_LPAR_ID_CURRENT, |
| 834 | make_first_field("bi", 0), | 834 | make_first_field("bi", 0), |
| @@ -854,7 +854,7 @@ static int ps3_repository_read_boot_dat_address(u64 *address) | |||
| 854 | int ps3_repository_read_boot_dat_size(unsigned int *size) | 854 | int ps3_repository_read_boot_dat_size(unsigned int *size) |
| 855 | { | 855 | { |
| 856 | int result; | 856 | int result; |
| 857 | u64 v1; | 857 | u64 v1 = 0; |
| 858 | 858 | ||
| 859 | result = read_node(PS3_LPAR_ID_CURRENT, | 859 | result = read_node(PS3_LPAR_ID_CURRENT, |
| 860 | make_first_field("bi", 0), | 860 | make_first_field("bi", 0), |
| @@ -869,7 +869,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size) | |||
| 869 | int ps3_repository_read_vuart_av_port(unsigned int *port) | 869 | int ps3_repository_read_vuart_av_port(unsigned int *port) |
| 870 | { | 870 | { |
| 871 | int result; | 871 | int result; |
| 872 | u64 v1; | 872 | u64 v1 = 0; |
| 873 | 873 | ||
| 874 | result = read_node(PS3_LPAR_ID_CURRENT, | 874 | result = read_node(PS3_LPAR_ID_CURRENT, |
| 875 | make_first_field("bi", 0), | 875 | make_first_field("bi", 0), |
| @@ -884,7 +884,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port) | |||
| 884 | int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) | 884 | int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) |
| 885 | { | 885 | { |
| 886 | int result; | 886 | int result; |
| 887 | u64 v1; | 887 | u64 v1 = 0; |
| 888 | 888 | ||
| 889 | result = read_node(PS3_LPAR_ID_CURRENT, | 889 | result = read_node(PS3_LPAR_ID_CURRENT, |
| 890 | make_first_field("bi", 0), | 890 | make_first_field("bi", 0), |
| @@ -919,7 +919,7 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size) | |||
| 919 | int ps3_repository_read_num_be(unsigned int *num_be) | 919 | int ps3_repository_read_num_be(unsigned int *num_be) |
| 920 | { | 920 | { |
| 921 | int result; | 921 | int result; |
| 922 | u64 v1; | 922 | u64 v1 = 0; |
| 923 | 923 | ||
| 924 | result = read_node(PS3_LPAR_ID_PME, | 924 | result = read_node(PS3_LPAR_ID_PME, |
| 925 | make_first_field("ben", 0), | 925 | make_first_field("ben", 0), |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 0842c6f8a3e6..8c7e8528e7c4 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -800,8 +800,6 @@ static void mpic_end_ipi(struct irq_data *d) | |||
| 800 | * IPIs are marked IRQ_PER_CPU. This has the side effect of | 800 | * IPIs are marked IRQ_PER_CPU. This has the side effect of |
| 801 | * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from | 801 | * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from |
| 802 | * applying to them. We EOI them late to avoid re-entering. | 802 | * applying to them. We EOI them late to avoid re-entering. |
| 803 | * We mark IPI's with IRQF_DISABLED as they must run with | ||
| 804 | * irqs disabled. | ||
| 805 | */ | 803 | */ |
| 806 | mpic_eoi(mpic); | 804 | mpic_eoi(mpic); |
| 807 | } | 805 | } |
diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c index d3d6ce3c33b4..0debcc31ad70 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/sysdev/ppc4xx_soc.c | |||
| @@ -115,7 +115,7 @@ static int __init ppc4xx_l2c_probe(void) | |||
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | /* Install error handler */ | 117 | /* Install error handler */ |
| 118 | if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) { | 118 | if (request_irq(irq, l2c_error_handler, 0, "L2C", 0) < 0) { |
| 119 | printk(KERN_ERR "Cannot install L2C error handler" | 119 | printk(KERN_ERR "Cannot install L2C error handler" |
| 120 | ", cache is not enabled\n"); | 120 | ", cache is not enabled\n"); |
| 121 | of_node_put(np); | 121 | of_node_put(np); |
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 3d93a8ded0f8..63762c672a03 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c | |||
| @@ -134,11 +134,10 @@ static void xics_request_ipi(void) | |||
| 134 | BUG_ON(ipi == NO_IRQ); | 134 | BUG_ON(ipi == NO_IRQ); |
| 135 | 135 | ||
| 136 | /* | 136 | /* |
| 137 | * IPIs are marked IRQF_DISABLED as they must run with irqs | 137 | * IPIs are marked IRQF_PERCPU. The handler was set in map. |
| 138 | * disabled, and PERCPU. The handler was set in map. | ||
| 139 | */ | 138 | */ |
| 140 | BUG_ON(request_irq(ipi, icp_ops->ipi_action, | 139 | BUG_ON(request_irq(ipi, icp_ops->ipi_action, |
| 141 | IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL)); | 140 | IRQF_PERCPU, "IPI", NULL)); |
| 142 | } | 141 | } |
| 143 | 142 | ||
| 144 | int __init xics_smp_probe(void) | 143 | int __init xics_smp_probe(void) |
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 28071bb31db7..4c61b52191eb 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c | |||
| @@ -109,7 +109,7 @@ static __init void sdv_serial_fixup(void) | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | #else | 111 | #else |
| 112 | static inline void sdv_serial_fixup(void); | 112 | static inline void sdv_serial_fixup(void) {}; |
| 113 | #endif | 113 | #endif |
| 114 | 114 | ||
| 115 | static void __init sdv_arch_setup(void) | 115 | static void __init sdv_arch_setup(void) |
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index 6ed7afdaf4af..541020df0da6 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c | |||
| @@ -608,6 +608,7 @@ static void *msic_ocd_platform_data(void *info) | |||
| 608 | } | 608 | } |
| 609 | 609 | ||
| 610 | static const struct devs_id __initconst device_ids[] = { | 610 | static const struct devs_id __initconst device_ids[] = { |
| 611 | {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data}, | ||
| 611 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, | 612 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, |
| 612 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, | 613 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, |
| 613 | {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, | 614 | {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, |
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c index a8ac6f1eb66d..225bd0f0f675 100644 --- a/arch/x86/platform/mrst/vrtc.c +++ b/arch/x86/platform/mrst/vrtc.c | |||
| @@ -76,8 +76,8 @@ unsigned long vrtc_get_time(void) | |||
| 76 | 76 | ||
| 77 | spin_unlock_irqrestore(&rtc_lock, flags); | 77 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 78 | 78 | ||
| 79 | /* vRTC YEAR reg contains the offset to 1960 */ | 79 | /* vRTC YEAR reg contains the offset to 1972 */ |
| 80 | year += 1960; | 80 | year += 1972; |
| 81 | 81 | ||
| 82 | printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d " | 82 | printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d " |
| 83 | "mon: %d year: %d\n", sec, min, hour, mday, mon, year); | 83 | "mon: %d year: %d\n", sec, min, hour, mday, mon, year); |
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index a816f24f2d52..a0f768c1d9aa 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c | |||
| @@ -383,6 +383,7 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, | |||
| 383 | return 0; | 383 | return 0; |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | #ifdef CONFIG_NET | ||
| 386 | static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | 387 | static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 387 | { | 388 | { |
| 388 | struct crypto_report_blkcipher rblkcipher; | 389 | struct crypto_report_blkcipher rblkcipher; |
| @@ -404,6 +405,12 @@ static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 404 | nla_put_failure: | 405 | nla_put_failure: |
| 405 | return -EMSGSIZE; | 406 | return -EMSGSIZE; |
| 406 | } | 407 | } |
| 408 | #else | ||
| 409 | static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 410 | { | ||
| 411 | return -ENOSYS; | ||
| 412 | } | ||
| 413 | #endif | ||
| 407 | 414 | ||
| 408 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 415 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| 409 | __attribute__ ((unused)); | 416 | __attribute__ ((unused)); |
| @@ -457,6 +464,7 @@ static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type, | |||
| 457 | return 0; | 464 | return 0; |
| 458 | } | 465 | } |
| 459 | 466 | ||
| 467 | #ifdef CONFIG_NET | ||
| 460 | static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | 468 | static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 461 | { | 469 | { |
| 462 | struct crypto_report_blkcipher rblkcipher; | 470 | struct crypto_report_blkcipher rblkcipher; |
| @@ -478,6 +486,12 @@ static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 478 | nla_put_failure: | 486 | nla_put_failure: |
| 479 | return -EMSGSIZE; | 487 | return -EMSGSIZE; |
| 480 | } | 488 | } |
| 489 | #else | ||
| 490 | static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 491 | { | ||
| 492 | return -ENOSYS; | ||
| 493 | } | ||
| 494 | #endif | ||
| 481 | 495 | ||
| 482 | static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) | 496 | static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| 483 | __attribute__ ((unused)); | 497 | __attribute__ ((unused)); |
diff --git a/crypto/aead.c b/crypto/aead.c index 701556ffaaef..04add3dca6fe 100644 --- a/crypto/aead.c +++ b/crypto/aead.c | |||
| @@ -111,6 +111,7 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 111 | return 0; | 111 | return 0; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | #ifdef CONFIG_NET | ||
| 114 | static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) | 115 | static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 115 | { | 116 | { |
| 116 | struct crypto_report_aead raead; | 117 | struct crypto_report_aead raead; |
| @@ -132,6 +133,12 @@ static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 132 | nla_put_failure: | 133 | nla_put_failure: |
| 133 | return -EMSGSIZE; | 134 | return -EMSGSIZE; |
| 134 | } | 135 | } |
| 136 | #else | ||
| 137 | static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 138 | { | ||
| 139 | return -ENOSYS; | ||
| 140 | } | ||
| 141 | #endif | ||
| 135 | 142 | ||
| 136 | static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) | 143 | static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) |
| 137 | __attribute__ ((unused)); | 144 | __attribute__ ((unused)); |
| @@ -190,6 +197,7 @@ static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 190 | return 0; | 197 | return 0; |
| 191 | } | 198 | } |
| 192 | 199 | ||
| 200 | #ifdef CONFIG_NET | ||
| 193 | static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg) | 201 | static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 194 | { | 202 | { |
| 195 | struct crypto_report_aead raead; | 203 | struct crypto_report_aead raead; |
| @@ -210,6 +218,12 @@ static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 210 | nla_put_failure: | 218 | nla_put_failure: |
| 211 | return -EMSGSIZE; | 219 | return -EMSGSIZE; |
| 212 | } | 220 | } |
| 221 | #else | ||
| 222 | static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 223 | { | ||
| 224 | return -ENOSYS; | ||
| 225 | } | ||
| 226 | #endif | ||
| 213 | 227 | ||
| 214 | 228 | ||
| 215 | static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) | 229 | static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) |
diff --git a/crypto/ahash.c b/crypto/ahash.c index a3e6ef99394a..ac93c99cfae8 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
| @@ -399,6 +399,7 @@ static unsigned int crypto_ahash_extsize(struct crypto_alg *alg) | |||
| 399 | return sizeof(struct crypto_shash *); | 399 | return sizeof(struct crypto_shash *); |
| 400 | } | 400 | } |
| 401 | 401 | ||
| 402 | #ifdef CONFIG_NET | ||
| 402 | static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg) | 403 | static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 403 | { | 404 | { |
| 404 | struct crypto_report_hash rhash; | 405 | struct crypto_report_hash rhash; |
| @@ -416,6 +417,12 @@ static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 416 | nla_put_failure: | 417 | nla_put_failure: |
| 417 | return -EMSGSIZE; | 418 | return -EMSGSIZE; |
| 418 | } | 419 | } |
| 420 | #else | ||
| 421 | static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 422 | { | ||
| 423 | return -ENOSYS; | ||
| 424 | } | ||
| 425 | #endif | ||
| 419 | 426 | ||
| 420 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) | 427 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) |
| 421 | __attribute__ ((unused)); | 428 | __attribute__ ((unused)); |
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index 2572d2600136..1e61d1a888b2 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
| @@ -494,6 +494,7 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 494 | return crypto_init_blkcipher_ops_async(tfm); | 494 | return crypto_init_blkcipher_ops_async(tfm); |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | #ifdef CONFIG_NET | ||
| 497 | static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | 498 | static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 498 | { | 499 | { |
| 499 | struct crypto_report_blkcipher rblkcipher; | 500 | struct crypto_report_blkcipher rblkcipher; |
| @@ -515,6 +516,12 @@ static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 515 | nla_put_failure: | 516 | nla_put_failure: |
| 516 | return -EMSGSIZE; | 517 | return -EMSGSIZE; |
| 517 | } | 518 | } |
| 519 | #else | ||
| 520 | static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 521 | { | ||
| 522 | return -ENOSYS; | ||
| 523 | } | ||
| 524 | #endif | ||
| 518 | 525 | ||
| 519 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 526 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| 520 | __attribute__ ((unused)); | 527 | __attribute__ ((unused)); |
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 2abca780312d..0605a2bbba75 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c | |||
| @@ -44,9 +44,6 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) | |||
| 44 | 44 | ||
| 45 | down_read(&crypto_alg_sem); | 45 | down_read(&crypto_alg_sem); |
| 46 | 46 | ||
| 47 | if (list_empty(&crypto_alg_list)) | ||
| 48 | return NULL; | ||
| 49 | |||
| 50 | list_for_each_entry(q, &crypto_alg_list, cra_list) { | 47 | list_for_each_entry(q, &crypto_alg_list, cra_list) { |
| 51 | int match = 0; | 48 | int match = 0; |
| 52 | 49 | ||
diff --git a/crypto/pcompress.c b/crypto/pcompress.c index fefda78a6a2a..2e458e5482d0 100644 --- a/crypto/pcompress.c +++ b/crypto/pcompress.c | |||
| @@ -48,6 +48,7 @@ static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm) | |||
| 48 | return 0; | 48 | return 0; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | #ifdef CONFIG_NET | ||
| 51 | static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) | 52 | static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 52 | { | 53 | { |
| 53 | struct crypto_report_comp rpcomp; | 54 | struct crypto_report_comp rpcomp; |
| @@ -62,6 +63,12 @@ static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 62 | nla_put_failure: | 63 | nla_put_failure: |
| 63 | return -EMSGSIZE; | 64 | return -EMSGSIZE; |
| 64 | } | 65 | } |
| 66 | #else | ||
| 67 | static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 68 | { | ||
| 69 | return -ENOSYS; | ||
| 70 | } | ||
| 71 | #endif | ||
| 65 | 72 | ||
| 66 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) | 73 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) |
| 67 | __attribute__ ((unused)); | 74 | __attribute__ ((unused)); |
diff --git a/crypto/rng.c b/crypto/rng.c index feb7de00f437..64f864fa8043 100644 --- a/crypto/rng.c +++ b/crypto/rng.c | |||
| @@ -60,6 +60,7 @@ static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 60 | return 0; | 60 | return 0; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | #ifdef CONFIG_NET | ||
| 63 | static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) | 64 | static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 64 | { | 65 | { |
| 65 | struct crypto_report_rng rrng; | 66 | struct crypto_report_rng rrng; |
| @@ -76,6 +77,12 @@ static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 76 | nla_put_failure: | 77 | nla_put_failure: |
| 77 | return -EMSGSIZE; | 78 | return -EMSGSIZE; |
| 78 | } | 79 | } |
| 80 | #else | ||
| 81 | static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 82 | { | ||
| 83 | return -ENOSYS; | ||
| 84 | } | ||
| 85 | #endif | ||
| 79 | 86 | ||
| 80 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) | 87 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) |
| 81 | __attribute__ ((unused)); | 88 | __attribute__ ((unused)); |
diff --git a/crypto/shash.c b/crypto/shash.c index ea8a9c6e21e3..9100912716ae 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
| @@ -524,6 +524,7 @@ static unsigned int crypto_shash_extsize(struct crypto_alg *alg) | |||
| 524 | return alg->cra_ctxsize; | 524 | return alg->cra_ctxsize; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | #ifdef CONFIG_NET | ||
| 527 | static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) | 528 | static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) |
| 528 | { | 529 | { |
| 529 | struct crypto_report_hash rhash; | 530 | struct crypto_report_hash rhash; |
| @@ -541,6 +542,12 @@ static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) | |||
| 541 | nla_put_failure: | 542 | nla_put_failure: |
| 542 | return -EMSGSIZE; | 543 | return -EMSGSIZE; |
| 543 | } | 544 | } |
| 545 | #else | ||
| 546 | static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 547 | { | ||
| 548 | return -ENOSYS; | ||
| 549 | } | ||
| 550 | #endif | ||
| 544 | 551 | ||
| 545 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) | 552 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) |
| 546 | __attribute__ ((unused)); | 553 | __attribute__ ((unused)); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fb7b90b05922..cf26222a93c5 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -390,6 +390,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 390 | /* Promise */ | 390 | /* Promise */ |
| 391 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 391 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
| 392 | 392 | ||
| 393 | /* Asmedia */ | ||
| 394 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1061 */ | ||
| 395 | |||
| 393 | /* Generic, PCI class code for AHCI */ | 396 | /* Generic, PCI class code for AHCI */ |
| 394 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 397 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| 395 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, | 398 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 004f2ce3dc73..ec555951176e 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
| @@ -65,7 +65,7 @@ static struct scsi_host_template ahci_platform_sht = { | |||
| 65 | static int __init ahci_probe(struct platform_device *pdev) | 65 | static int __init ahci_probe(struct platform_device *pdev) |
| 66 | { | 66 | { |
| 67 | struct device *dev = &pdev->dev; | 67 | struct device *dev = &pdev->dev; |
| 68 | struct ahci_platform_data *pdata = dev->platform_data; | 68 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
| 69 | const struct platform_device_id *id = platform_get_device_id(pdev); | 69 | const struct platform_device_id *id = platform_get_device_id(pdev); |
| 70 | struct ata_port_info pi = ahci_port_info[id->driver_data]; | 70 | struct ata_port_info pi = ahci_port_info[id->driver_data]; |
| 71 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 71 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
| @@ -191,7 +191,7 @@ err0: | |||
| 191 | static int __devexit ahci_remove(struct platform_device *pdev) | 191 | static int __devexit ahci_remove(struct platform_device *pdev) |
| 192 | { | 192 | { |
| 193 | struct device *dev = &pdev->dev; | 193 | struct device *dev = &pdev->dev; |
| 194 | struct ahci_platform_data *pdata = dev->platform_data; | 194 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
| 195 | struct ata_host *host = dev_get_drvdata(dev); | 195 | struct ata_host *host = dev_get_drvdata(dev); |
| 196 | 196 | ||
| 197 | ata_host_detach(host); | 197 | ata_host_detach(host); |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f22957c2769a..a9b282038000 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -2883,7 +2883,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2883 | sata_scr_read(link, SCR_STATUS, &sstatus)) | 2883 | sata_scr_read(link, SCR_STATUS, &sstatus)) |
| 2884 | rc = -ERESTART; | 2884 | rc = -ERESTART; |
| 2885 | 2885 | ||
| 2886 | if (rc == -ERESTART || try >= max_tries) { | 2886 | if (try >= max_tries) { |
| 2887 | /* | 2887 | /* |
| 2888 | * Thaw host port even if reset failed, so that the port | 2888 | * Thaw host port even if reset failed, so that the port |
| 2889 | * can be retried on the next phy event. This risks | 2889 | * can be retried on the next phy event. This risks |
| @@ -2909,6 +2909,16 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2909 | ata_eh_acquire(ap); | 2909 | ata_eh_acquire(ap); |
| 2910 | } | 2910 | } |
| 2911 | 2911 | ||
| 2912 | /* | ||
| 2913 | * While disks spinup behind PMP, some controllers fail sending SRST. | ||
| 2914 | * They need to be reset - as well as the PMP - before retrying. | ||
| 2915 | */ | ||
| 2916 | if (rc == -ERESTART) { | ||
| 2917 | if (ata_is_host_link(link)) | ||
| 2918 | ata_eh_thaw_port(ap); | ||
| 2919 | goto out; | ||
| 2920 | } | ||
| 2921 | |||
| 2912 | if (try == max_tries - 1) { | 2922 | if (try == max_tries - 1) { |
| 2913 | sata_down_spd_limit(link, 0); | 2923 | sata_down_spd_limit(link, 0); |
| 2914 | if (slave) | 2924 | if (slave) |
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 104462dbc524..21b80c555c60 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
| @@ -389,12 +389,9 @@ static void sata_pmp_quirks(struct ata_port *ap) | |||
| 389 | /* link reports offline after LPM */ | 389 | /* link reports offline after LPM */ |
| 390 | link->flags |= ATA_LFLAG_NO_LPM; | 390 | link->flags |= ATA_LFLAG_NO_LPM; |
| 391 | 391 | ||
| 392 | /* Class code report is unreliable and SRST | 392 | /* Class code report is unreliable. */ |
| 393 | * times out under certain configurations. | ||
| 394 | */ | ||
| 395 | if (link->pmp < 5) | 393 | if (link->pmp < 5) |
| 396 | link->flags |= ATA_LFLAG_NO_SRST | | 394 | link->flags |= ATA_LFLAG_ASSUME_ATA; |
| 397 | ATA_LFLAG_ASSUME_ATA; | ||
| 398 | 395 | ||
| 399 | /* port 5 is for SEMB device and it doesn't like SRST */ | 396 | /* port 5 is for SEMB device and it doesn't like SRST */ |
| 400 | if (link->pmp == 5) | 397 | if (link->pmp == 5) |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 72a9770ac42f..2a5412e7e9c1 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -1217,6 +1217,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) | |||
| 1217 | 1217 | ||
| 1218 | /** | 1218 | /** |
| 1219 | * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth | 1219 | * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth |
| 1220 | * @ap: ATA port to which the device change the queue depth | ||
| 1221 | * @sdev: SCSI device to configure queue depth for | ||
| 1222 | * @queue_depth: new queue depth | ||
| 1223 | * @reason: calling context | ||
| 1220 | * | 1224 | * |
| 1221 | * libsas and libata have different approaches for associating a sdev to | 1225 | * libsas and libata have different approaches for associating a sdev to |
| 1222 | * its ata_port. | 1226 | * its ata_port. |
diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index a72ab0dde4e5..2a472c5bb7db 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c | |||
| @@ -52,7 +52,7 @@ static int __devinit pata_of_platform_probe(struct platform_device *ofdev) | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | ret = of_irq_to_resource(dn, 0, &irq_res); | 54 | ret = of_irq_to_resource(dn, 0, &irq_res); |
| 55 | if (ret == NO_IRQ) | 55 | if (!ret) |
| 56 | irq_res.start = irq_res.end = 0; | 56 | irq_res.start = irq_res.end = 0; |
| 57 | else | 57 | else |
| 58 | irq_res.flags = 0; | 58 | irq_res.flags = 0; |
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 447d9c05fb5a..95ec435f0eb4 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
| @@ -104,7 +104,7 @@ static const struct ata_port_info sis_port_info = { | |||
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | MODULE_AUTHOR("Uwe Koziolek"); | 106 | MODULE_AUTHOR("Uwe Koziolek"); |
| 107 | MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller"); | 107 | MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller"); |
| 108 | MODULE_LICENSE("GPL"); | 108 | MODULE_LICENSE("GPL"); |
| 109 | MODULE_DEVICE_TABLE(pci, sis_pci_tbl); | 109 | MODULE_DEVICE_TABLE(pci, sis_pci_tbl); |
| 110 | MODULE_VERSION(DRV_VERSION); | 110 | MODULE_VERSION(DRV_VERSION); |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 66cd0b8096ca..c92424ca1a55 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
| @@ -1186,10 +1186,11 @@ static void gen6_cleanup(void) | |||
| 1186 | /* Certain Gen5 chipsets require require idling the GPU before | 1186 | /* Certain Gen5 chipsets require require idling the GPU before |
| 1187 | * unmapping anything from the GTT when VT-d is enabled. | 1187 | * unmapping anything from the GTT when VT-d is enabled. |
| 1188 | */ | 1188 | */ |
| 1189 | extern int intel_iommu_gfx_mapped; | ||
| 1190 | static inline int needs_idle_maps(void) | 1189 | static inline int needs_idle_maps(void) |
| 1191 | { | 1190 | { |
| 1191 | #ifdef CONFIG_INTEL_IOMMU | ||
| 1192 | const unsigned short gpu_devid = intel_private.pcidev->device; | 1192 | const unsigned short gpu_devid = intel_private.pcidev->device; |
| 1193 | extern int intel_iommu_gfx_mapped; | ||
| 1193 | 1194 | ||
| 1194 | /* Query intel_iommu to see if we need the workaround. Presumably that | 1195 | /* Query intel_iommu to see if we need the workaround. Presumably that |
| 1195 | * was loaded first. | 1196 | * was loaded first. |
| @@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void) | |||
| 1198 | gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && | 1199 | gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && |
| 1199 | intel_iommu_gfx_mapped) | 1200 | intel_iommu_gfx_mapped) |
| 1200 | return 1; | 1201 | return 1; |
| 1201 | 1202 | #endif | |
| 1202 | return 0; | 1203 | return 0; |
| 1203 | } | 1204 | } |
| 1204 | 1205 | ||
| @@ -1236,7 +1237,7 @@ static int i9xx_setup(void) | |||
| 1236 | intel_private.gtt_bus_addr = reg_addr + gtt_offset; | 1237 | intel_private.gtt_bus_addr = reg_addr + gtt_offset; |
| 1237 | } | 1238 | } |
| 1238 | 1239 | ||
| 1239 | if (needs_idle_maps()); | 1240 | if (needs_idle_maps()) |
| 1240 | intel_private.base.do_idle_maps = 1; | 1241 | intel_private.base.do_idle_maps = 1; |
| 1241 | 1242 | ||
| 1242 | intel_i9xx_setup_flush(); | 1243 | intel_i9xx_setup_flush(); |
diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index edaa987621ea..f5002015d82e 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c | |||
| @@ -109,7 +109,7 @@ static unsigned int db8500_cpufreq_getspeed(unsigned int cpu) | |||
| 109 | 109 | ||
| 110 | static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) | 110 | static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) |
| 111 | { | 111 | { |
| 112 | int res; | 112 | int i, res; |
| 113 | 113 | ||
| 114 | BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); | 114 | BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); |
| 115 | 115 | ||
| @@ -120,8 +120,8 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) | |||
| 120 | freq_table[3].frequency = 1000000; | 120 | freq_table[3].frequency = 1000000; |
| 121 | } | 121 | } |
| 122 | pr_info("db8500-cpufreq : Available frequencies:\n"); | 122 | pr_info("db8500-cpufreq : Available frequencies:\n"); |
| 123 | while (freq_table[i].frequency != CPUFREQ_TABLE_END) | 123 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) |
| 124 | pr_info(" %d Mhz\n", freq_table[i++].frequency/1000); | 124 | pr_info(" %d Mhz\n", freq_table[i].frequency/1000); |
| 125 | 125 | ||
| 126 | /* get policy fields based on the table */ | 126 | /* get policy fields based on the table */ |
| 127 | res = cpufreq_frequency_table_cpuinfo(policy, freq_table); | 127 | res = cpufreq_frequency_table_cpuinfo(policy, freq_table); |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 785127cb281b..1368826ef284 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
| @@ -9,7 +9,6 @@ menuconfig DRM | |||
| 9 | depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU | 9 | depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU |
| 10 | select I2C | 10 | select I2C |
| 11 | select I2C_ALGOBIT | 11 | select I2C_ALGOBIT |
| 12 | select SLOW_WORK | ||
| 13 | help | 12 | help |
| 14 | Kernel-level support for the Direct Rendering Infrastructure (DRI) | 13 | Kernel-level support for the Direct Rendering Infrastructure (DRI) |
| 15 | introduced in XFree86 4.0. If you say Y here, you need to select | 14 | introduced in XFree86 4.0. If you say Y here, you need to select |
| @@ -96,6 +95,7 @@ config DRM_I915 | |||
| 96 | select FB_CFB_IMAGEBLIT | 95 | select FB_CFB_IMAGEBLIT |
| 97 | # i915 depends on ACPI_VIDEO when ACPI is enabled | 96 | # i915 depends on ACPI_VIDEO when ACPI is enabled |
| 98 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | 97 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick |
| 98 | select BACKLIGHT_LCD_SUPPORT if ACPI | ||
| 99 | select BACKLIGHT_CLASS_DEVICE if ACPI | 99 | select BACKLIGHT_CLASS_DEVICE if ACPI |
| 100 | select VIDEO_OUTPUT_CONTROL if ACPI | 100 | select VIDEO_OUTPUT_CONTROL if ACPI |
| 101 | select INPUT if ACPI | 101 | select INPUT if ACPI |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9a2e2a14b3bb..405c63b9d539 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -2118,8 +2118,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, | |||
| 2118 | property->num_values = num_values; | 2118 | property->num_values = num_values; |
| 2119 | INIT_LIST_HEAD(&property->enum_blob_list); | 2119 | INIT_LIST_HEAD(&property->enum_blob_list); |
| 2120 | 2120 | ||
| 2121 | if (name) | 2121 | if (name) { |
| 2122 | strncpy(property->name, name, DRM_PROP_NAME_LEN); | 2122 | strncpy(property->name, name, DRM_PROP_NAME_LEN); |
| 2123 | property->name[DRM_PROP_NAME_LEN-1] = '\0'; | ||
| 2124 | } | ||
| 2123 | 2125 | ||
| 2124 | list_add_tail(&property->head, &dev->mode_config.property_list); | 2126 | list_add_tail(&property->head, &dev->mode_config.property_list); |
| 2125 | return property; | 2127 | return property; |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 2957636161e8..3969f7553fe7 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -484,6 +484,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 484 | struct drm_connector *save_connectors, *connector; | 484 | struct drm_connector *save_connectors, *connector; |
| 485 | int count = 0, ro, fail = 0; | 485 | int count = 0, ro, fail = 0; |
| 486 | struct drm_crtc_helper_funcs *crtc_funcs; | 486 | struct drm_crtc_helper_funcs *crtc_funcs; |
| 487 | struct drm_mode_set save_set; | ||
| 487 | int ret = 0; | 488 | int ret = 0; |
| 488 | int i; | 489 | int i; |
| 489 | 490 | ||
| @@ -556,6 +557,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 556 | save_connectors[count++] = *connector; | 557 | save_connectors[count++] = *connector; |
| 557 | } | 558 | } |
| 558 | 559 | ||
| 560 | save_set.crtc = set->crtc; | ||
| 561 | save_set.mode = &set->crtc->mode; | ||
| 562 | save_set.x = set->crtc->x; | ||
| 563 | save_set.y = set->crtc->y; | ||
| 564 | save_set.fb = set->crtc->fb; | ||
| 565 | |||
| 559 | /* We should be able to check here if the fb has the same properties | 566 | /* We should be able to check here if the fb has the same properties |
| 560 | * and then just flip_or_move it */ | 567 | * and then just flip_or_move it */ |
| 561 | if (set->crtc->fb != set->fb) { | 568 | if (set->crtc->fb != set->fb) { |
| @@ -721,6 +728,12 @@ fail: | |||
| 721 | *connector = save_connectors[count++]; | 728 | *connector = save_connectors[count++]; |
| 722 | } | 729 | } |
| 723 | 730 | ||
| 731 | /* Try to restore the config */ | ||
| 732 | if (mode_changed && | ||
| 733 | !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x, | ||
| 734 | save_set.y, save_set.fb)) | ||
| 735 | DRM_ERROR("failed to restore config after modeset failure\n"); | ||
| 736 | |||
| 724 | kfree(save_connectors); | 737 | kfree(save_connectors); |
| 725 | kfree(save_encoders); | 738 | kfree(save_encoders); |
| 726 | kfree(save_crtcs); | 739 | kfree(save_crtcs); |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index d067c12ba940..1c7a1c0d3edd 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
| @@ -118,7 +118,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, | |||
| 118 | tmp->minor = minor; | 118 | tmp->minor = minor; |
| 119 | tmp->dent = ent; | 119 | tmp->dent = ent; |
| 120 | tmp->info_ent = &files[i]; | 120 | tmp->info_ent = &files[i]; |
| 121 | list_add(&(tmp->list), &(minor->debugfs_nodes.list)); | 121 | |
| 122 | mutex_lock(&minor->debugfs_lock); | ||
| 123 | list_add(&tmp->list, &minor->debugfs_list); | ||
| 124 | mutex_unlock(&minor->debugfs_lock); | ||
| 122 | } | 125 | } |
| 123 | return 0; | 126 | return 0; |
| 124 | 127 | ||
| @@ -146,7 +149,8 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id, | |||
| 146 | char name[64]; | 149 | char name[64]; |
| 147 | int ret; | 150 | int ret; |
| 148 | 151 | ||
| 149 | INIT_LIST_HEAD(&minor->debugfs_nodes.list); | 152 | INIT_LIST_HEAD(&minor->debugfs_list); |
| 153 | mutex_init(&minor->debugfs_lock); | ||
| 150 | sprintf(name, "%d", minor_id); | 154 | sprintf(name, "%d", minor_id); |
| 151 | minor->debugfs_root = debugfs_create_dir(name, root); | 155 | minor->debugfs_root = debugfs_create_dir(name, root); |
| 152 | if (!minor->debugfs_root) { | 156 | if (!minor->debugfs_root) { |
| @@ -192,8 +196,9 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |||
| 192 | struct drm_info_node *tmp; | 196 | struct drm_info_node *tmp; |
| 193 | int i; | 197 | int i; |
| 194 | 198 | ||
| 199 | mutex_lock(&minor->debugfs_lock); | ||
| 195 | for (i = 0; i < count; i++) { | 200 | for (i = 0; i < count; i++) { |
| 196 | list_for_each_safe(pos, q, &minor->debugfs_nodes.list) { | 201 | list_for_each_safe(pos, q, &minor->debugfs_list) { |
| 197 | tmp = list_entry(pos, struct drm_info_node, list); | 202 | tmp = list_entry(pos, struct drm_info_node, list); |
| 198 | if (tmp->info_ent == &files[i]) { | 203 | if (tmp->info_ent == &files[i]) { |
| 199 | debugfs_remove(tmp->dent); | 204 | debugfs_remove(tmp->dent); |
| @@ -202,6 +207,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |||
| 202 | } | 207 | } |
| 203 | } | 208 | } |
| 204 | } | 209 | } |
| 210 | mutex_unlock(&minor->debugfs_lock); | ||
| 205 | return 0; | 211 | return 0; |
| 206 | } | 212 | } |
| 207 | EXPORT_SYMBOL(drm_debugfs_remove_files); | 213 | EXPORT_SYMBOL(drm_debugfs_remove_files); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index fc81af9dbf42..40c187c60f44 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -125,7 +125,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
| 125 | DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 125 | DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 126 | DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 126 | DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
| 127 | 127 | ||
| 128 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), | 128 | DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED), |
| 129 | 129 | ||
| 130 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), | 130 | DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0), |
| 131 | 131 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cb3794a00f98..68b756253f9f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -407,13 +407,16 @@ int drm_irq_uninstall(struct drm_device *dev) | |||
| 407 | /* | 407 | /* |
| 408 | * Wake up any waiters so they don't hang. | 408 | * Wake up any waiters so they don't hang. |
| 409 | */ | 409 | */ |
| 410 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 410 | if (dev->num_crtcs) { |
| 411 | for (i = 0; i < dev->num_crtcs; i++) { | 411 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
| 412 | DRM_WAKEUP(&dev->vbl_queue[i]); | 412 | for (i = 0; i < dev->num_crtcs; i++) { |
| 413 | dev->vblank_enabled[i] = 0; | 413 | DRM_WAKEUP(&dev->vbl_queue[i]); |
| 414 | dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); | 414 | dev->vblank_enabled[i] = 0; |
| 415 | dev->last_vblank[i] = | ||
| 416 | dev->driver->get_vblank_counter(dev, i); | ||
| 417 | } | ||
| 418 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
| 415 | } | 419 | } |
| 416 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
| 417 | 420 | ||
| 418 | if (!irq_enabled) | 421 | if (!irq_enabled) |
| 419 | return -EINVAL; | 422 | return -EINVAL; |
| @@ -1125,6 +1128,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
| 1125 | trace_drm_vblank_event_delivered(current->pid, pipe, | 1128 | trace_drm_vblank_event_delivered(current->pid, pipe, |
| 1126 | vblwait->request.sequence); | 1129 | vblwait->request.sequence); |
| 1127 | } else { | 1130 | } else { |
| 1131 | /* drm_handle_vblank_events will call drm_vblank_put */ | ||
| 1128 | list_add_tail(&e->base.link, &dev->vblank_event_list); | 1132 | list_add_tail(&e->base.link, &dev->vblank_event_list); |
| 1129 | vblwait->reply.sequence = vblwait->request.sequence; | 1133 | vblwait->reply.sequence = vblwait->request.sequence; |
| 1130 | } | 1134 | } |
| @@ -1205,8 +1209,12 @@ int drm_wait_vblank(struct drm_device *dev, void *data, | |||
| 1205 | goto done; | 1209 | goto done; |
| 1206 | } | 1210 | } |
| 1207 | 1211 | ||
| 1208 | if (flags & _DRM_VBLANK_EVENT) | 1212 | if (flags & _DRM_VBLANK_EVENT) { |
| 1213 | /* must hold on to the vblank ref until the event fires | ||
| 1214 | * drm_vblank_put will be called asynchronously | ||
| 1215 | */ | ||
| 1209 | return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); | 1216 | return drm_queue_vblank_event(dev, crtc, vblwait, file_priv); |
| 1217 | } | ||
| 1210 | 1218 | ||
| 1211 | if ((flags & _DRM_VBLANK_NEXTONMISS) && | 1219 | if ((flags & _DRM_VBLANK_NEXTONMISS) && |
| 1212 | (seq - vblwait->request.sequence) <= (1<<23)) { | 1220 | (seq - vblwait->request.sequence) <= (1<<23)) { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d14b44e13f51..4f40f1ce1d8e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -1506,7 +1506,10 @@ drm_add_fake_info_node(struct drm_minor *minor, | |||
| 1506 | node->minor = minor; | 1506 | node->minor = minor; |
| 1507 | node->dent = ent; | 1507 | node->dent = ent; |
| 1508 | node->info_ent = (void *) key; | 1508 | node->info_ent = (void *) key; |
| 1509 | list_add(&node->list, &minor->debugfs_nodes.list); | 1509 | |
| 1510 | mutex_lock(&minor->debugfs_lock); | ||
| 1511 | list_add(&node->list, &minor->debugfs_list); | ||
| 1512 | mutex_unlock(&minor->debugfs_lock); | ||
| 1510 | 1513 | ||
| 1511 | return 0; | 1514 | return 0; |
| 1512 | } | 1515 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6651c36b6e8a..d18b07adcffa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file, | |||
| 1396 | 1396 | ||
| 1397 | if (obj->base.size > dev_priv->mm.gtt_mappable_end) { | 1397 | if (obj->base.size > dev_priv->mm.gtt_mappable_end) { |
| 1398 | ret = -E2BIG; | 1398 | ret = -E2BIG; |
| 1399 | goto unlock; | 1399 | goto out; |
| 1400 | } | 1400 | } |
| 1401 | 1401 | ||
| 1402 | if (obj->madv != I915_MADV_WILLNEED) { | 1402 | if (obj->madv != I915_MADV_WILLNEED) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 032a82098136..5fc201b49d30 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -640,10 +640,9 @@ static int | |||
| 640 | nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | 640 | nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) |
| 641 | { | 641 | { |
| 642 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 642 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 643 | uint32_t reg0 = nv_rd32(dev, reg + 0); | ||
| 644 | uint32_t reg1 = nv_rd32(dev, reg + 4); | ||
| 645 | struct nouveau_pll_vals pll; | 643 | struct nouveau_pll_vals pll; |
| 646 | struct pll_lims pll_limits; | 644 | struct pll_lims pll_limits; |
| 645 | u32 ctrl, mask, coef; | ||
| 647 | int ret; | 646 | int ret; |
| 648 | 647 | ||
| 649 | ret = get_pll_limits(dev, reg, &pll_limits); | 648 | ret = get_pll_limits(dev, reg, &pll_limits); |
| @@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | |||
| 654 | if (!clk) | 653 | if (!clk) |
| 655 | return -ERANGE; | 654 | return -ERANGE; |
| 656 | 655 | ||
| 657 | reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); | 656 | coef = pll.N1 << 8 | pll.M1; |
| 658 | reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; | 657 | ctrl = pll.log2P << 16; |
| 659 | 658 | mask = 0x00070000; | |
| 660 | if (dev_priv->vbios.execute) { | 659 | if (reg == 0x004008) { |
| 661 | still_alive(); | 660 | mask |= 0x01f80000; |
| 662 | nv_wr32(dev, reg + 4, reg1); | 661 | ctrl |= (pll_limits.log2p_bias << 19); |
| 663 | nv_wr32(dev, reg + 0, reg0); | 662 | ctrl |= (pll.log2P << 22); |
| 664 | } | 663 | } |
| 665 | 664 | ||
| 665 | if (!dev_priv->vbios.execute) | ||
| 666 | return 0; | ||
| 667 | |||
| 668 | nv_mask(dev, reg + 0, mask, ctrl); | ||
| 669 | nv_wr32(dev, reg + 4, coef); | ||
| 666 | return 0; | 670 | return 0; |
| 667 | } | 671 | } |
| 668 | 672 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7226f419e178..7cc37e690860 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type) | |||
| 148 | 148 | ||
| 149 | if (dev_priv->card_type == NV_10 && | 149 | if (dev_priv->card_type == NV_10 && |
| 150 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && | 150 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && |
| 151 | nvbo->bo.mem.num_pages < vram_pages / 2) { | 151 | nvbo->bo.mem.num_pages < vram_pages / 4) { |
| 152 | /* | 152 | /* |
| 153 | * Make sure that the color and depth buffers are handled | 153 | * Make sure that the color and depth buffers are handled |
| 154 | * by independent memory controller units. Up to a 9x | 154 | * by independent memory controller units. Up to a 9x |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a319d5646ea9..bb6ec9ef8676 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
| @@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
| 158 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); | 158 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); |
| 159 | INIT_LIST_HEAD(&chan->nvsw.flip); | 159 | INIT_LIST_HEAD(&chan->nvsw.flip); |
| 160 | INIT_LIST_HEAD(&chan->fence.pending); | 160 | INIT_LIST_HEAD(&chan->fence.pending); |
| 161 | spin_lock_init(&chan->fence.lock); | ||
| 161 | 162 | ||
| 162 | /* setup channel's memory and vm */ | 163 | /* setup channel's memory and vm */ |
| 163 | ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); | 164 | ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index e0d275e1c96c..cea6696b1906 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
| @@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
| 710 | case OUTPUT_DP: | 710 | case OUTPUT_DP: |
| 711 | max_clock = nv_encoder->dp.link_nr; | 711 | max_clock = nv_encoder->dp.link_nr; |
| 712 | max_clock *= nv_encoder->dp.link_bw; | 712 | max_clock *= nv_encoder->dp.link_bw; |
| 713 | clock = clock * nouveau_connector_bpp(connector) / 8; | 713 | clock = clock * nouveau_connector_bpp(connector) / 10; |
| 714 | break; | 714 | break; |
| 715 | default: | 715 | default: |
| 716 | BUG_ON(1); | 716 | BUG_ON(1); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 14a8627efe4d..3a4cc32b9e44 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
| @@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev) | |||
| 487 | { | 487 | { |
| 488 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 488 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 489 | struct nouveau_fbdev *nfbdev; | 489 | struct nouveau_fbdev *nfbdev; |
| 490 | int preferred_bpp; | ||
| 490 | int ret; | 491 | int ret; |
| 491 | 492 | ||
| 492 | nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); | 493 | nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); |
| @@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev) | |||
| 505 | } | 506 | } |
| 506 | 507 | ||
| 507 | drm_fb_helper_single_add_all_connectors(&nfbdev->helper); | 508 | drm_fb_helper_single_add_all_connectors(&nfbdev->helper); |
| 508 | drm_fb_helper_initial_config(&nfbdev->helper, 32); | 509 | |
| 510 | if (dev_priv->vram_size <= 32 * 1024 * 1024) | ||
| 511 | preferred_bpp = 8; | ||
| 512 | else if (dev_priv->vram_size <= 64 * 1024 * 1024) | ||
| 513 | preferred_bpp = 16; | ||
| 514 | else | ||
| 515 | preferred_bpp = 32; | ||
| 516 | |||
| 517 | drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp); | ||
| 509 | return 0; | 518 | return 0; |
| 510 | } | 519 | } |
| 511 | 520 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 81116cfea275..2f6daae68b9d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
| @@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) | |||
| 539 | return ret; | 539 | return ret; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | INIT_LIST_HEAD(&chan->fence.pending); | ||
| 543 | spin_lock_init(&chan->fence.lock); | ||
| 544 | atomic_set(&chan->fence.last_sequence_irq, 0); | 542 | atomic_set(&chan->fence.last_sequence_irq, 0); |
| 545 | return 0; | 543 | return 0; |
| 546 | } | 544 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index c6143df48b9f..d39b2202b197 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
| @@ -333,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what, | |||
| 333 | 333 | ||
| 334 | NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); | 334 | NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); |
| 335 | 335 | ||
| 336 | for (i = 0; info[i].addr; i++) { | 336 | for (i = 0; i2c && info[i].addr; i++) { |
| 337 | if (nouveau_probe_i2c_addr(i2c, info[i].addr) && | 337 | if (nouveau_probe_i2c_addr(i2c, info[i].addr) && |
| 338 | (!match || match(i2c, &info[i]))) { | 338 | (!match || match(i2c, &info[i]))) { |
| 339 | NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); | 339 | NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index 9f178aa94162..33d03fbf00df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c | |||
| @@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev) | |||
| 239 | if(version == 0x15) { | 239 | if(version == 0x15) { |
| 240 | memtimings->timing = | 240 | memtimings->timing = |
| 241 | kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL); | 241 | kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL); |
| 242 | if(!memtimings) { | 242 | if (!memtimings->timing) { |
| 243 | NV_WARN(dev,"Could not allocate memtiming table\n"); | 243 | NV_WARN(dev,"Could not allocate memtiming table\n"); |
| 244 | return; | 244 | return; |
| 245 | } | 245 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 82478e0998e5..d8831ab42bb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
| @@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev) | |||
| 579 | if (ret) | 579 | if (ret) |
| 580 | goto out_display_early; | 580 | goto out_display_early; |
| 581 | 581 | ||
| 582 | /* workaround an odd issue on nvc1 by disabling the device's | ||
| 583 | * nosnoop capability. hopefully won't cause issues until a | ||
| 584 | * better fix is found - assuming there is one... | ||
| 585 | */ | ||
| 586 | if (dev_priv->chipset == 0xc1) { | ||
| 587 | nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); | ||
| 588 | } | ||
| 589 | |||
| 582 | nouveau_pm_init(dev); | 590 | nouveau_pm_init(dev); |
| 583 | 591 | ||
| 584 | ret = engine->vram.init(dev); | 592 | ret = engine->vram.init(dev); |
| @@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
| 1102 | dev_priv->noaccel = !!nouveau_noaccel; | 1110 | dev_priv->noaccel = !!nouveau_noaccel; |
| 1103 | if (nouveau_noaccel == -1) { | 1111 | if (nouveau_noaccel == -1) { |
| 1104 | switch (dev_priv->chipset) { | 1112 | switch (dev_priv->chipset) { |
| 1105 | case 0xc1: /* known broken */ | 1113 | #if 0 |
| 1106 | case 0xc8: /* never tested */ | 1114 | case 0xXX: /* known broken */ |
| 1107 | NV_INFO(dev, "acceleration disabled by default, pass " | 1115 | NV_INFO(dev, "acceleration disabled by default, pass " |
| 1108 | "noaccel=0 to force enable\n"); | 1116 | "noaccel=0 to force enable\n"); |
| 1109 | dev_priv->noaccel = true; | 1117 | dev_priv->noaccel = true; |
| 1110 | break; | 1118 | break; |
| 1119 | #endif | ||
| 1111 | default: | 1120 | default: |
| 1112 | dev_priv->noaccel = false; | 1121 | dev_priv->noaccel = false; |
| 1113 | break; | 1122 | break; |
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c index bbc0b9c7e1f7..e676b0d53478 100644 --- a/drivers/gpu/drm/nouveau/nv40_pm.c +++ b/drivers/gpu/drm/nouveau/nv40_pm.c | |||
| @@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg) | |||
| 57 | int P = (ctrl & 0x00070000) >> 16; | 57 | int P = (ctrl & 0x00070000) >> 16; |
| 58 | u32 ref = 27000, clk = 0; | 58 | u32 ref = 27000, clk = 0; |
| 59 | 59 | ||
| 60 | if (ctrl & 0x80000000) | 60 | if ((ctrl & 0x80000000) && M1) { |
| 61 | clk = ref * N1 / M1; | 61 | clk = ref * N1 / M1; |
| 62 | 62 | if ((ctrl & 0x40000100) == 0x40000000) { | |
| 63 | if (!(ctrl & 0x00000100)) { | 63 | if (M2) |
| 64 | if (ctrl & 0x40000000) | 64 | clk = clk * N2 / M2; |
| 65 | clk = clk * N2 / M2; | 65 | else |
| 66 | clk = 0; | ||
| 67 | } | ||
| 66 | } | 68 | } |
| 67 | 69 | ||
| 68 | return clk >> P; | 70 | return clk >> P; |
| @@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) | |||
| 177 | } | 179 | } |
| 178 | 180 | ||
| 179 | /* memory clock */ | 181 | /* memory clock */ |
| 182 | if (!perflvl->memory) { | ||
| 183 | info->mpll_ctrl = 0x00000000; | ||
| 184 | goto out; | ||
| 185 | } | ||
| 186 | |||
| 180 | ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, | 187 | ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, |
| 181 | &N1, &M1, &N2, &M2, &log2P); | 188 | &N1, &M1, &N2, &M2, &log2P); |
| 182 | if (ret < 0) | 189 | if (ret < 0) |
| @@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state) | |||
| 264 | mdelay(5); | 271 | mdelay(5); |
| 265 | nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); | 272 | nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); |
| 266 | 273 | ||
| 274 | if (!info->mpll_ctrl) | ||
| 275 | goto resume; | ||
| 276 | |||
| 267 | /* wait for vblank start on active crtcs, disable memory access */ | 277 | /* wait for vblank start on active crtcs, disable memory access */ |
| 268 | for (i = 0; i < 2; i++) { | 278 | for (i = 0; i < 2; i++) { |
| 269 | if (!(crtc_mask & (1 << i))) | 279 | if (!(crtc_mask & (1 << i))) |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 8c979b31ff61..ac601f7c4e1a 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
| @@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine) | |||
| 131 | NV_DEBUG(dev, "\n"); | 131 | NV_DEBUG(dev, "\n"); |
| 132 | 132 | ||
| 133 | /* master reset */ | 133 | /* master reset */ |
| 134 | nv_mask(dev, 0x000200, 0x00200100, 0x00000000); | 134 | nv_mask(dev, 0x000200, 0x00201000, 0x00000000); |
| 135 | nv_mask(dev, 0x000200, 0x00200100, 0x00200100); | 135 | nv_mask(dev, 0x000200, 0x00201000, 0x00201000); |
| 136 | nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ | 136 | nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ |
| 137 | 137 | ||
| 138 | /* reset/enable traps and interrupts */ | 138 | /* reset/enable traps and interrupts */ |
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index d05c2c3b2444..4b46d6968566 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c | |||
| @@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
| 601 | gr_def(ctx, offset + 0x1c, 0x00880000); | 601 | gr_def(ctx, offset + 0x1c, 0x00880000); |
| 602 | break; | 602 | break; |
| 603 | case 0x86: | 603 | case 0x86: |
| 604 | gr_def(ctx, offset + 0x1c, 0x008c0000); | 604 | gr_def(ctx, offset + 0x1c, 0x018c0000); |
| 605 | break; | 605 | break; |
| 606 | case 0x92: | 606 | case 0x92: |
| 607 | case 0x96: | 607 | case 0x96: |
diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 9da23838e63e..2e45e57fd869 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c | |||
| @@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev) | |||
| 160 | colbits = (r4 & 0x0000f000) >> 12; | 160 | colbits = (r4 & 0x0000f000) >> 12; |
| 161 | rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; | 161 | rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; |
| 162 | rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; | 162 | rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; |
| 163 | banks = ((r4 & 0x01000000) ? 8 : 4); | 163 | banks = 1 << (((r4 & 0x03000000) >> 24) + 2); |
| 164 | 164 | ||
| 165 | rowsize = parts * banks * (1 << colbits) * 8; | 165 | rowsize = parts * banks * (1 << colbits) * 8; |
| 166 | predicted = rowsize << rowbitsa; | 166 | predicted = rowsize << rowbitsa; |
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index bbdbc51830c8..a74e501afd25 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c | |||
| @@ -157,8 +157,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) | |||
| 157 | struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); | 157 | struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR); |
| 158 | struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; | 158 | struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR]; |
| 159 | struct drm_device *dev = chan->dev; | 159 | struct drm_device *dev = chan->dev; |
| 160 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 160 | int i = 0, gpc, tp, ret; | 161 | int i = 0, gpc, tp, ret; |
| 161 | u32 magic; | ||
| 162 | 162 | ||
| 163 | ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM, | 163 | ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM, |
| 164 | &grch->unk408004); | 164 | &grch->unk408004); |
| @@ -207,14 +207,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) | |||
| 207 | nv_wo32(grch->mmio, i++ * 4, 0x0041880c); | 207 | nv_wo32(grch->mmio, i++ * 4, 0x0041880c); |
| 208 | nv_wo32(grch->mmio, i++ * 4, 0x80000018); | 208 | nv_wo32(grch->mmio, i++ * 4, 0x80000018); |
| 209 | 209 | ||
| 210 | magic = 0x02180000; | 210 | if (dev_priv->chipset != 0xc1) { |
| 211 | nv_wo32(grch->mmio, i++ * 4, 0x00405830); | 211 | u32 magic = 0x02180000; |
| 212 | nv_wo32(grch->mmio, i++ * 4, magic); | 212 | nv_wo32(grch->mmio, i++ * 4, 0x00405830); |
| 213 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) { | 213 | nv_wo32(grch->mmio, i++ * 4, magic); |
| 214 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) { | 214 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) { |
| 215 | u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800); | 215 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { |
| 216 | nv_wo32(grch->mmio, i++ * 4, reg); | 216 | u32 reg = TP_UNIT(gpc, tp, 0x520); |
| 217 | nv_wo32(grch->mmio, i++ * 4, magic); | 217 | nv_wo32(grch->mmio, i++ * 4, reg); |
| 218 | nv_wo32(grch->mmio, i++ * 4, magic); | ||
| 219 | magic += 0x0324; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | } else { | ||
| 223 | u32 magic = 0x02180000; | ||
| 224 | nv_wo32(grch->mmio, i++ * 4, 0x00405830); | ||
| 225 | nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218); | ||
| 226 | nv_wo32(grch->mmio, i++ * 4, 0x004064c4); | ||
| 227 | nv_wo32(grch->mmio, i++ * 4, 0x0086ffff); | ||
| 228 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) { | ||
| 229 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { | ||
| 230 | u32 reg = TP_UNIT(gpc, tp, 0x520); | ||
| 231 | nv_wo32(grch->mmio, i++ * 4, reg); | ||
| 232 | nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic); | ||
| 233 | magic += 0x0324; | ||
| 234 | } | ||
| 235 | for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { | ||
| 236 | u32 reg = TP_UNIT(gpc, tp, 0x544); | ||
| 237 | nv_wo32(grch->mmio, i++ * 4, reg); | ||
| 238 | nv_wo32(grch->mmio, i++ * 4, magic); | ||
| 239 | magic += 0x0324; | ||
| 240 | } | ||
| 218 | } | 241 | } |
| 219 | } | 242 | } |
| 220 | 243 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c index dd0e6a736b3b..96b0b93d94ca 100644 --- a/drivers/gpu/drm/nouveau/nvc0_grctx.c +++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c | |||
| @@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan) | |||
| 1812 | /* calculate first set of magics */ | 1812 | /* calculate first set of magics */ |
| 1813 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); | 1813 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); |
| 1814 | 1814 | ||
| 1815 | gpc = -1; | ||
| 1815 | for (tp = 0; tp < priv->tp_total; tp++) { | 1816 | for (tp = 0; tp < priv->tp_total; tp++) { |
| 1816 | do { | 1817 | do { |
| 1817 | gpc = (gpc + 1) % priv->gpc_nr; | 1818 | gpc = (gpc + 1) % priv->gpc_nr; |
| @@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan) | |||
| 1861 | 1862 | ||
| 1862 | if (1) { | 1863 | if (1) { |
| 1863 | u32 tp_mask = 0, tp_set = 0; | 1864 | u32 tp_mask = 0, tp_set = 0; |
| 1864 | u8 tpnr[GPC_MAX]; | 1865 | u8 tpnr[GPC_MAX], a, b; |
| 1865 | 1866 | ||
| 1866 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); | 1867 | memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); |
| 1867 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) | 1868 | for (gpc = 0; gpc < priv->gpc_nr; gpc++) |
| 1868 | tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); | 1869 | tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); |
| 1869 | 1870 | ||
| 1870 | gpc = -1; | 1871 | for (i = 0, gpc = -1, b = -1; i < 32; i++) { |
| 1871 | for (i = 0, gpc = -1; i < 32; i++) { | 1872 | a = (i * (priv->tp_total - 1)) / 32; |
| 1872 | int ltp = i * (priv->tp_total - 1) / 32; | 1873 | if (a != b) { |
| 1873 | 1874 | b = a; | |
| 1874 | do { | 1875 | do { |
| 1875 | gpc = (gpc + 1) % priv->gpc_nr; | 1876 | gpc = (gpc + 1) % priv->gpc_nr; |
| 1876 | } while (!tpnr[gpc]); | 1877 | } while (!tpnr[gpc]); |
| 1877 | tp = priv->tp_nr[gpc] - tpnr[gpc]--; | 1878 | tp = priv->tp_nr[gpc] - tpnr[gpc]--; |
| 1878 | 1879 | ||
| 1879 | tp_set |= 1 << ((gpc * 8) + tp); | 1880 | tp_set |= 1 << ((gpc * 8) + tp); |
| 1881 | } | ||
| 1880 | 1882 | ||
| 1881 | do { | 1883 | nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); |
| 1882 | nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); | 1884 | nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask); |
| 1883 | tp_set ^= tp_mask; | ||
| 1884 | nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set); | ||
| 1885 | tp_set ^= tp_mask; | ||
| 1886 | } while (ltp == (++i * (priv->tp_total - 1) / 32)); | ||
| 1887 | i--; | ||
| 1888 | } | 1885 | } |
| 1889 | } | 1886 | } |
| 1890 | 1887 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index edbfe9360ae2..ce984d573a51 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c | |||
| @@ -43,7 +43,7 @@ static const u8 types[256] = { | |||
| 43 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 43 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 44 | 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, | 44 | 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, |
| 45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, | 45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, |
| 46 | 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, | 46 | 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, |
| 47 | 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, | 47 | 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, |
| 48 | 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, | 48 | 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, |
| 49 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 | 49 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 |
| @@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev) | |||
| 110 | u32 bsize = nv_rd32(dev, 0x10f20c); | 110 | u32 bsize = nv_rd32(dev, 0x10f20c); |
| 111 | u32 offset, length; | 111 | u32 offset, length; |
| 112 | bool uniform = true; | 112 | bool uniform = true; |
| 113 | int ret, i; | 113 | int ret, part; |
| 114 | 114 | ||
| 115 | NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); | 115 | NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); |
| 116 | NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize); | 116 | NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize); |
| 117 | 117 | ||
| 118 | /* read amount of vram attached to each memory controller */ | 118 | /* read amount of vram attached to each memory controller */ |
| 119 | for (i = 0; i < parts; i++) { | 119 | part = 0; |
| 120 | u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000)); | 120 | while (parts) { |
| 121 | u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000)); | ||
| 122 | if (psize == 0) | ||
| 123 | continue; | ||
| 124 | parts--; | ||
| 125 | |||
| 121 | if (psize != bsize) { | 126 | if (psize != bsize) { |
| 122 | if (psize < bsize) | 127 | if (psize < bsize) |
| 123 | bsize = psize; | 128 | bsize = psize; |
| 124 | uniform = false; | 129 | uniform = false; |
| 125 | } | 130 | } |
| 126 | 131 | ||
| 127 | NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize); | 132 | NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize); |
| 128 | |||
| 129 | dev_priv->vram_size += (u64)psize << 20; | 133 | dev_priv->vram_size += (u64)psize << 20; |
| 130 | } | 134 | } |
| 131 | 135 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 87921c88a95c..87631fede1f8 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -1522,12 +1522,6 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 1522 | struct drm_display_mode *mode, | 1522 | struct drm_display_mode *mode, |
| 1523 | struct drm_display_mode *adjusted_mode) | 1523 | struct drm_display_mode *adjusted_mode) |
| 1524 | { | 1524 | { |
| 1525 | struct drm_device *dev = crtc->dev; | ||
| 1526 | struct radeon_device *rdev = dev->dev_private; | ||
| 1527 | |||
| 1528 | /* adjust pm to upcoming mode change */ | ||
| 1529 | radeon_pm_compute_clocks(rdev); | ||
| 1530 | |||
| 1531 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 1525 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
| 1532 | return false; | 1526 | return false; |
| 1533 | return true; | 1527 | return true; |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index a0de48542f71..6fb335a4fdda 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -283,7 +283,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
| 283 | } | 283 | } |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | DRM_ERROR("aux i2c too many retries, giving up\n"); | 286 | DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); |
| 287 | return -EREMOTEIO; | 287 | return -EREMOTEIO; |
| 288 | } | 288 | } |
| 289 | 289 | ||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e4c384b9511c..1d603a3335db 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -157,6 +157,57 @@ int sumo_get_temp(struct radeon_device *rdev) | |||
| 157 | return actual_temp * 1000; | 157 | return actual_temp * 1000; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | void sumo_pm_init_profile(struct radeon_device *rdev) | ||
| 161 | { | ||
| 162 | int idx; | ||
| 163 | |||
| 164 | /* default */ | ||
| 165 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; | ||
| 166 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; | ||
| 167 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; | ||
| 168 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; | ||
| 169 | |||
| 170 | /* low,mid sh/mh */ | ||
| 171 | if (rdev->flags & RADEON_IS_MOBILITY) | ||
| 172 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | ||
| 173 | else | ||
| 174 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 175 | |||
| 176 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; | ||
| 177 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; | ||
| 178 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | ||
| 179 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | ||
| 180 | |||
| 181 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; | ||
| 182 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; | ||
| 183 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | ||
| 184 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | ||
| 185 | |||
| 186 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; | ||
| 187 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; | ||
| 188 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
| 189 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; | ||
| 190 | |||
| 191 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; | ||
| 192 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; | ||
| 193 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
| 194 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; | ||
| 195 | |||
| 196 | /* high sh/mh */ | ||
| 197 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 198 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; | ||
| 199 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; | ||
| 200 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; | ||
| 201 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = | ||
| 202 | rdev->pm.power_state[idx].num_clock_modes - 1; | ||
| 203 | |||
| 204 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; | ||
| 205 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; | ||
| 206 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; | ||
| 207 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = | ||
| 208 | rdev->pm.power_state[idx].num_clock_modes - 1; | ||
| 209 | } | ||
| 210 | |||
| 160 | void evergreen_pm_misc(struct radeon_device *rdev) | 211 | void evergreen_pm_misc(struct radeon_device *rdev) |
| 161 | { | 212 | { |
| 162 | int req_ps_idx = rdev->pm.requested_power_state_index; | 213 | int req_ps_idx = rdev->pm.requested_power_state_index; |
| @@ -1219,7 +1270,7 @@ void evergreen_mc_program(struct radeon_device *rdev) | |||
| 1219 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 1270 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
| 1220 | rdev->mc.vram_end >> 12); | 1271 | rdev->mc.vram_end >> 12); |
| 1221 | } | 1272 | } |
| 1222 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1273 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
| 1223 | if (rdev->flags & RADEON_IS_IGP) { | 1274 | if (rdev->flags & RADEON_IS_IGP) { |
| 1224 | tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; | 1275 | tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; |
| 1225 | tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; | 1276 | tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 19afc43ad173..9cdda0b3b081 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -288,24 +288,6 @@ void r600_pm_get_dynpm_state(struct radeon_device *rdev) | |||
| 288 | pcie_lanes); | 288 | pcie_lanes); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | static int r600_pm_get_type_index(struct radeon_device *rdev, | ||
| 292 | enum radeon_pm_state_type ps_type, | ||
| 293 | int instance) | ||
| 294 | { | ||
| 295 | int i; | ||
| 296 | int found_instance = -1; | ||
| 297 | |||
| 298 | for (i = 0; i < rdev->pm.num_power_states; i++) { | ||
| 299 | if (rdev->pm.power_state[i].type == ps_type) { | ||
| 300 | found_instance++; | ||
| 301 | if (found_instance == instance) | ||
| 302 | return i; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | /* return default if no match */ | ||
| 306 | return rdev->pm.default_power_state_index; | ||
| 307 | } | ||
| 308 | |||
| 309 | void rs780_pm_init_profile(struct radeon_device *rdev) | 291 | void rs780_pm_init_profile(struct radeon_device *rdev) |
| 310 | { | 292 | { |
| 311 | if (rdev->pm.num_power_states == 2) { | 293 | if (rdev->pm.num_power_states == 2) { |
| @@ -421,6 +403,8 @@ void rs780_pm_init_profile(struct radeon_device *rdev) | |||
| 421 | 403 | ||
| 422 | void r600_pm_init_profile(struct radeon_device *rdev) | 404 | void r600_pm_init_profile(struct radeon_device *rdev) |
| 423 | { | 405 | { |
| 406 | int idx; | ||
| 407 | |||
| 424 | if (rdev->family == CHIP_R600) { | 408 | if (rdev->family == CHIP_R600) { |
| 425 | /* XXX */ | 409 | /* XXX */ |
| 426 | /* default */ | 410 | /* default */ |
| @@ -502,81 +486,43 @@ void r600_pm_init_profile(struct radeon_device *rdev) | |||
| 502 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; | 486 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; |
| 503 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; | 487 | rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; |
| 504 | /* low sh */ | 488 | /* low sh */ |
| 505 | if (rdev->flags & RADEON_IS_MOBILITY) { | 489 | if (rdev->flags & RADEON_IS_MOBILITY) |
| 506 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = | 490 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); |
| 507 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | 491 | else |
| 508 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = | 492 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); |
| 509 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | 493 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; |
| 510 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | 494 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; |
| 511 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | 495 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; |
| 512 | } else { | 496 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; |
| 513 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = | ||
| 514 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 515 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = | ||
| 516 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 517 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; | ||
| 518 | rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; | ||
| 519 | } | ||
| 520 | /* mid sh */ | 497 | /* mid sh */ |
| 521 | if (rdev->flags & RADEON_IS_MOBILITY) { | 498 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; |
| 522 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = | 499 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; |
| 523 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | 500 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; |
| 524 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = | 501 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; |
| 525 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); | ||
| 526 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
| 527 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; | ||
| 528 | } else { | ||
| 529 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = | ||
| 530 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 531 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = | ||
| 532 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 533 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; | ||
| 534 | rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; | ||
| 535 | } | ||
| 536 | /* high sh */ | 502 | /* high sh */ |
| 537 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = | 503 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); |
| 538 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | 504 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; |
| 539 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = | 505 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; |
| 540 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); | ||
| 541 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; | 506 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; |
| 542 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; | 507 | rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; |
| 543 | /* low mh */ | 508 | /* low mh */ |
| 544 | if (rdev->flags & RADEON_IS_MOBILITY) { | 509 | if (rdev->flags & RADEON_IS_MOBILITY) |
| 545 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = | 510 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); |
| 546 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | 511 | else |
| 547 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = | 512 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); |
| 548 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | 513 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; |
| 549 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | 514 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; |
| 550 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | 515 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; |
| 551 | } else { | 516 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; |
| 552 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = | ||
| 553 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
| 554 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = | ||
| 555 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
| 556 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; | ||
| 557 | rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; | ||
| 558 | } | ||
| 559 | /* mid mh */ | 517 | /* mid mh */ |
| 560 | if (rdev->flags & RADEON_IS_MOBILITY) { | 518 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; |
| 561 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = | 519 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; |
| 562 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | 520 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; |
| 563 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = | 521 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; |
| 564 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1); | ||
| 565 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
| 566 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; | ||
| 567 | } else { | ||
| 568 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = | ||
| 569 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
| 570 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = | ||
| 571 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
| 572 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; | ||
| 573 | rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; | ||
| 574 | } | ||
| 575 | /* high mh */ | 522 | /* high mh */ |
| 576 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = | 523 | idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); |
| 577 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | 524 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; |
| 578 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = | 525 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; |
| 579 | r600_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1); | ||
| 580 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; | 526 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; |
| 581 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; | 527 | rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; |
| 582 | } | 528 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b316b301152f..fc5a1d642cb5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -784,8 +784,7 @@ struct radeon_pm_clock_info { | |||
| 784 | 784 | ||
| 785 | struct radeon_power_state { | 785 | struct radeon_power_state { |
| 786 | enum radeon_pm_state_type type; | 786 | enum radeon_pm_state_type type; |
| 787 | /* XXX: use a define for num clock modes */ | 787 | struct radeon_pm_clock_info *clock_info; |
| 788 | struct radeon_pm_clock_info clock_info[8]; | ||
| 789 | /* number of valid clock modes in this power state */ | 788 | /* number of valid clock modes in this power state */ |
| 790 | int num_clock_modes; | 789 | int num_clock_modes; |
| 791 | struct radeon_pm_clock_info *default_clock_mode; | 790 | struct radeon_pm_clock_info *default_clock_mode; |
| @@ -855,6 +854,9 @@ struct radeon_pm { | |||
| 855 | struct device *int_hwmon_dev; | 854 | struct device *int_hwmon_dev; |
| 856 | }; | 855 | }; |
| 857 | 856 | ||
| 857 | int radeon_pm_get_type_index(struct radeon_device *rdev, | ||
| 858 | enum radeon_pm_state_type ps_type, | ||
| 859 | int instance); | ||
| 858 | 860 | ||
| 859 | /* | 861 | /* |
| 860 | * Benchmarking | 862 | * Benchmarking |
| @@ -1142,6 +1144,48 @@ struct r600_vram_scratch { | |||
| 1142 | u64 gpu_addr; | 1144 | u64 gpu_addr; |
| 1143 | }; | 1145 | }; |
| 1144 | 1146 | ||
| 1147 | |||
| 1148 | /* | ||
| 1149 | * Mutex which allows recursive locking from the same process. | ||
| 1150 | */ | ||
| 1151 | struct radeon_mutex { | ||
| 1152 | struct mutex mutex; | ||
| 1153 | struct task_struct *owner; | ||
| 1154 | int level; | ||
| 1155 | }; | ||
| 1156 | |||
| 1157 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
| 1158 | { | ||
| 1159 | mutex_init(&mutex->mutex); | ||
| 1160 | mutex->owner = NULL; | ||
| 1161 | mutex->level = 0; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
| 1165 | { | ||
| 1166 | if (mutex_trylock(&mutex->mutex)) { | ||
| 1167 | /* The mutex was unlocked before, so it's ours now */ | ||
| 1168 | mutex->owner = current; | ||
| 1169 | } else if (mutex->owner != current) { | ||
| 1170 | /* Another process locked the mutex, take it */ | ||
| 1171 | mutex_lock(&mutex->mutex); | ||
| 1172 | mutex->owner = current; | ||
| 1173 | } | ||
| 1174 | /* Otherwise the mutex was already locked by this process */ | ||
| 1175 | |||
| 1176 | mutex->level++; | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
| 1180 | { | ||
| 1181 | if (--mutex->level > 0) | ||
| 1182 | return; | ||
| 1183 | |||
| 1184 | mutex->owner = NULL; | ||
| 1185 | mutex_unlock(&mutex->mutex); | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | |||
| 1145 | /* | 1189 | /* |
| 1146 | * Core structure, functions and helpers. | 1190 | * Core structure, functions and helpers. |
| 1147 | */ | 1191 | */ |
| @@ -1197,7 +1241,7 @@ struct radeon_device { | |||
| 1197 | struct radeon_gem gem; | 1241 | struct radeon_gem gem; |
| 1198 | struct radeon_pm pm; | 1242 | struct radeon_pm pm; |
| 1199 | uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; | 1243 | uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; |
| 1200 | struct mutex cs_mutex; | 1244 | struct radeon_mutex cs_mutex; |
| 1201 | struct radeon_wb wb; | 1245 | struct radeon_wb wb; |
| 1202 | struct radeon_dummy_page dummy_page; | 1246 | struct radeon_dummy_page dummy_page; |
| 1203 | bool gpu_lockup; | 1247 | bool gpu_lockup; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e2944566ffea..a2e1eae114ef 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -834,7 +834,7 @@ static struct radeon_asic sumo_asic = { | |||
| 834 | .pm_misc = &evergreen_pm_misc, | 834 | .pm_misc = &evergreen_pm_misc, |
| 835 | .pm_prepare = &evergreen_pm_prepare, | 835 | .pm_prepare = &evergreen_pm_prepare, |
| 836 | .pm_finish = &evergreen_pm_finish, | 836 | .pm_finish = &evergreen_pm_finish, |
| 837 | .pm_init_profile = &rs780_pm_init_profile, | 837 | .pm_init_profile = &sumo_pm_init_profile, |
| 838 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, | 838 | .pm_get_dynpm_state = &r600_pm_get_dynpm_state, |
| 839 | .pre_page_flip = &evergreen_pre_page_flip, | 839 | .pre_page_flip = &evergreen_pre_page_flip, |
| 840 | .page_flip = &evergreen_page_flip, | 840 | .page_flip = &evergreen_page_flip, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 85f14f0337e4..59914842a729 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -413,6 +413,7 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p); | |||
| 413 | extern void evergreen_pm_misc(struct radeon_device *rdev); | 413 | extern void evergreen_pm_misc(struct radeon_device *rdev); |
| 414 | extern void evergreen_pm_prepare(struct radeon_device *rdev); | 414 | extern void evergreen_pm_prepare(struct radeon_device *rdev); |
| 415 | extern void evergreen_pm_finish(struct radeon_device *rdev); | 415 | extern void evergreen_pm_finish(struct radeon_device *rdev); |
| 416 | extern void sumo_pm_init_profile(struct radeon_device *rdev); | ||
| 416 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); | 417 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); |
| 417 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | 418 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); |
| 418 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); | 419 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 08d0b94332e6..d2d179267af3 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
| 1999 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 1999 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; |
| 2000 | switch (frev) { | 2000 | switch (frev) { |
| 2001 | case 1: | 2001 | case 1: |
| 2002 | rdev->pm.power_state[state_index].clock_info = | ||
| 2003 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); | ||
| 2004 | if (!rdev->pm.power_state[state_index].clock_info) | ||
| 2005 | return state_index; | ||
| 2002 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2006 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 2003 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 2007 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
| 2004 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | 2008 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); |
| @@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
| 2035 | state_index++; | 2039 | state_index++; |
| 2036 | break; | 2040 | break; |
| 2037 | case 2: | 2041 | case 2: |
| 2042 | rdev->pm.power_state[state_index].clock_info = | ||
| 2043 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); | ||
| 2044 | if (!rdev->pm.power_state[state_index].clock_info) | ||
| 2045 | return state_index; | ||
| 2038 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2046 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 2039 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 2047 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
| 2040 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | 2048 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); |
| @@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | |||
| 2072 | state_index++; | 2080 | state_index++; |
| 2073 | break; | 2081 | break; |
| 2074 | case 3: | 2082 | case 3: |
| 2083 | rdev->pm.power_state[state_index].clock_info = | ||
| 2084 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); | ||
| 2085 | if (!rdev->pm.power_state[state_index].clock_info) | ||
| 2086 | return state_index; | ||
| 2075 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2087 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 2076 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 2088 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
| 2077 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | 2089 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); |
| @@ -2257,7 +2269,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde | |||
| 2257 | rdev->pm.default_power_state_index = state_index; | 2269 | rdev->pm.default_power_state_index = state_index; |
| 2258 | rdev->pm.power_state[state_index].default_clock_mode = | 2270 | rdev->pm.power_state[state_index].default_clock_mode = |
| 2259 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | 2271 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; |
| 2260 | if (ASIC_IS_DCE5(rdev)) { | 2272 | if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) { |
| 2261 | /* NI chips post without MC ucode, so default clocks are strobe mode only */ | 2273 | /* NI chips post without MC ucode, so default clocks are strobe mode only */ |
| 2262 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; | 2274 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
| 2263 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; | 2275 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
| @@ -2377,17 +2389,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) | |||
| 2377 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + | 2389 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + |
| 2378 | (power_state->v1.ucNonClockStateIndex * | 2390 | (power_state->v1.ucNonClockStateIndex * |
| 2379 | power_info->pplib.ucNonClockSize)); | 2391 | power_info->pplib.ucNonClockSize)); |
| 2380 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { | 2392 | rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * |
| 2381 | clock_info = (union pplib_clock_info *) | 2393 | ((power_info->pplib.ucStateEntrySize - 1) ? |
| 2382 | (mode_info->atom_context->bios + data_offset + | 2394 | (power_info->pplib.ucStateEntrySize - 1) : 1), |
| 2383 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + | 2395 | GFP_KERNEL); |
| 2384 | (power_state->v1.ucClockStateIndices[j] * | 2396 | if (!rdev->pm.power_state[i].clock_info) |
| 2385 | power_info->pplib.ucClockInfoSize)); | 2397 | return state_index; |
| 2386 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | 2398 | if (power_info->pplib.ucStateEntrySize - 1) { |
| 2387 | state_index, mode_index, | 2399 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { |
| 2388 | clock_info); | 2400 | clock_info = (union pplib_clock_info *) |
| 2389 | if (valid) | 2401 | (mode_info->atom_context->bios + data_offset + |
| 2390 | mode_index++; | 2402 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + |
| 2403 | (power_state->v1.ucClockStateIndices[j] * | ||
| 2404 | power_info->pplib.ucClockInfoSize)); | ||
| 2405 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
| 2406 | state_index, mode_index, | ||
| 2407 | clock_info); | ||
| 2408 | if (valid) | ||
| 2409 | mode_index++; | ||
| 2410 | } | ||
| 2411 | } else { | ||
| 2412 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
| 2413 | rdev->clock.default_mclk; | ||
| 2414 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
| 2415 | rdev->clock.default_sclk; | ||
| 2416 | mode_index++; | ||
| 2391 | } | 2417 | } |
| 2392 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | 2418 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; |
| 2393 | if (mode_index) { | 2419 | if (mode_index) { |
| @@ -2456,18 +2482,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) | |||
| 2456 | non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ | 2482 | non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ |
| 2457 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | 2483 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) |
| 2458 | &non_clock_info_array->nonClockInfo[non_clock_array_index]; | 2484 | &non_clock_info_array->nonClockInfo[non_clock_array_index]; |
| 2459 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { | 2485 | rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) * |
| 2460 | clock_array_index = power_state->v2.clockInfoIndex[j]; | 2486 | (power_state->v2.ucNumDPMLevels ? |
| 2461 | /* XXX this might be an inagua bug... */ | 2487 | power_state->v2.ucNumDPMLevels : 1), |
| 2462 | if (clock_array_index >= clock_info_array->ucNumEntries) | 2488 | GFP_KERNEL); |
| 2463 | continue; | 2489 | if (!rdev->pm.power_state[i].clock_info) |
| 2464 | clock_info = (union pplib_clock_info *) | 2490 | return state_index; |
| 2465 | &clock_info_array->clockInfo[clock_array_index]; | 2491 | if (power_state->v2.ucNumDPMLevels) { |
| 2466 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | 2492 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { |
| 2467 | state_index, mode_index, | 2493 | clock_array_index = power_state->v2.clockInfoIndex[j]; |
| 2468 | clock_info); | 2494 | /* XXX this might be an inagua bug... */ |
| 2469 | if (valid) | 2495 | if (clock_array_index >= clock_info_array->ucNumEntries) |
| 2470 | mode_index++; | 2496 | continue; |
| 2497 | clock_info = (union pplib_clock_info *) | ||
| 2498 | &clock_info_array->clockInfo[clock_array_index]; | ||
| 2499 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
| 2500 | state_index, mode_index, | ||
| 2501 | clock_info); | ||
| 2502 | if (valid) | ||
| 2503 | mode_index++; | ||
| 2504 | } | ||
| 2505 | } else { | ||
| 2506 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
| 2507 | rdev->clock.default_mclk; | ||
| 2508 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
| 2509 | rdev->clock.default_sclk; | ||
| 2510 | mode_index++; | ||
| 2471 | } | 2511 | } |
| 2472 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | 2512 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; |
| 2473 | if (mode_index) { | 2513 | if (mode_index) { |
| @@ -2524,19 +2564,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
| 2524 | } else { | 2564 | } else { |
| 2525 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); | 2565 | rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); |
| 2526 | if (rdev->pm.power_state) { | 2566 | if (rdev->pm.power_state) { |
| 2527 | /* add the default mode */ | 2567 | rdev->pm.power_state[0].clock_info = |
| 2528 | rdev->pm.power_state[state_index].type = | 2568 | kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL); |
| 2529 | POWER_STATE_TYPE_DEFAULT; | 2569 | if (rdev->pm.power_state[0].clock_info) { |
| 2530 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 2570 | /* add the default mode */ |
| 2531 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; | 2571 | rdev->pm.power_state[state_index].type = |
| 2532 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; | 2572 | POWER_STATE_TYPE_DEFAULT; |
| 2533 | rdev->pm.power_state[state_index].default_clock_mode = | 2573 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
| 2534 | &rdev->pm.power_state[state_index].clock_info[0]; | 2574 | rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; |
| 2535 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 2575 | rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; |
| 2536 | rdev->pm.power_state[state_index].pcie_lanes = 16; | 2576 | rdev->pm.power_state[state_index].default_clock_mode = |
| 2537 | rdev->pm.default_power_state_index = state_index; | 2577 | &rdev->pm.power_state[state_index].clock_info[0]; |
| 2538 | rdev->pm.power_state[state_index].flags = 0; | 2578 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; |
| 2539 | state_index++; | 2579 | rdev->pm.power_state[state_index].pcie_lanes = 16; |
| 2580 | rdev->pm.default_power_state_index = state_index; | ||
| 2581 | rdev->pm.power_state[state_index].flags = 0; | ||
| 2582 | state_index++; | ||
| 2583 | } | ||
| 2540 | } | 2584 | } |
| 2541 | } | 2585 | } |
| 2542 | 2586 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 5cafc90de7f8..17e1a9b2d8fb 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
| @@ -98,7 +98,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, | |||
| 98 | struct radeon_bo *sobj = NULL; | 98 | struct radeon_bo *sobj = NULL; |
| 99 | uint64_t saddr, daddr; | 99 | uint64_t saddr, daddr; |
| 100 | int r, n; | 100 | int r, n; |
| 101 | unsigned int time; | 101 | int time; |
| 102 | 102 | ||
| 103 | n = RADEON_BENCHMARK_ITERATIONS; | 103 | n = RADEON_BENCHMARK_ITERATIONS; |
| 104 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); | 104 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index fae00c0d75aa..ccaa243c1442 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -222,7 +222,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 222 | struct radeon_cs_chunk *ib_chunk; | 222 | struct radeon_cs_chunk *ib_chunk; |
| 223 | int r; | 223 | int r; |
| 224 | 224 | ||
| 225 | mutex_lock(&rdev->cs_mutex); | 225 | radeon_mutex_lock(&rdev->cs_mutex); |
| 226 | /* initialize parser */ | 226 | /* initialize parser */ |
| 227 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); | 227 | memset(&parser, 0, sizeof(struct radeon_cs_parser)); |
| 228 | parser.filp = filp; | 228 | parser.filp = filp; |
| @@ -233,14 +233,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 233 | if (r) { | 233 | if (r) { |
| 234 | DRM_ERROR("Failed to initialize parser !\n"); | 234 | DRM_ERROR("Failed to initialize parser !\n"); |
| 235 | radeon_cs_parser_fini(&parser, r); | 235 | radeon_cs_parser_fini(&parser, r); |
| 236 | mutex_unlock(&rdev->cs_mutex); | 236 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 237 | return r; | 237 | return r; |
| 238 | } | 238 | } |
| 239 | r = radeon_ib_get(rdev, &parser.ib); | 239 | r = radeon_ib_get(rdev, &parser.ib); |
| 240 | if (r) { | 240 | if (r) { |
| 241 | DRM_ERROR("Failed to get ib !\n"); | 241 | DRM_ERROR("Failed to get ib !\n"); |
| 242 | radeon_cs_parser_fini(&parser, r); | 242 | radeon_cs_parser_fini(&parser, r); |
| 243 | mutex_unlock(&rdev->cs_mutex); | 243 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 244 | return r; | 244 | return r; |
| 245 | } | 245 | } |
| 246 | r = radeon_cs_parser_relocs(&parser); | 246 | r = radeon_cs_parser_relocs(&parser); |
| @@ -248,7 +248,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 248 | if (r != -ERESTARTSYS) | 248 | if (r != -ERESTARTSYS) |
| 249 | DRM_ERROR("Failed to parse relocation %d!\n", r); | 249 | DRM_ERROR("Failed to parse relocation %d!\n", r); |
| 250 | radeon_cs_parser_fini(&parser, r); | 250 | radeon_cs_parser_fini(&parser, r); |
| 251 | mutex_unlock(&rdev->cs_mutex); | 251 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 252 | return r; | 252 | return r; |
| 253 | } | 253 | } |
| 254 | /* Copy the packet into the IB, the parser will read from the | 254 | /* Copy the packet into the IB, the parser will read from the |
| @@ -260,14 +260,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 260 | if (r || parser.parser_error) { | 260 | if (r || parser.parser_error) { |
| 261 | DRM_ERROR("Invalid command stream !\n"); | 261 | DRM_ERROR("Invalid command stream !\n"); |
| 262 | radeon_cs_parser_fini(&parser, r); | 262 | radeon_cs_parser_fini(&parser, r); |
| 263 | mutex_unlock(&rdev->cs_mutex); | 263 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 264 | return r; | 264 | return r; |
| 265 | } | 265 | } |
| 266 | r = radeon_cs_finish_pages(&parser); | 266 | r = radeon_cs_finish_pages(&parser); |
| 267 | if (r) { | 267 | if (r) { |
| 268 | DRM_ERROR("Invalid command stream !\n"); | 268 | DRM_ERROR("Invalid command stream !\n"); |
| 269 | radeon_cs_parser_fini(&parser, r); | 269 | radeon_cs_parser_fini(&parser, r); |
| 270 | mutex_unlock(&rdev->cs_mutex); | 270 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 271 | return r; | 271 | return r; |
| 272 | } | 272 | } |
| 273 | r = radeon_ib_schedule(rdev, parser.ib); | 273 | r = radeon_ib_schedule(rdev, parser.ib); |
| @@ -275,7 +275,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 275 | DRM_ERROR("Failed to schedule IB !\n"); | 275 | DRM_ERROR("Failed to schedule IB !\n"); |
| 276 | } | 276 | } |
| 277 | radeon_cs_parser_fini(&parser, r); | 277 | radeon_cs_parser_fini(&parser, r); |
| 278 | mutex_unlock(&rdev->cs_mutex); | 278 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 279 | return r; | 279 | return r; |
| 280 | } | 280 | } |
| 281 | 281 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c33bc914d93d..c4d00a171411 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -716,7 +716,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 716 | 716 | ||
| 717 | /* mutex initialization are all done here so we | 717 | /* mutex initialization are all done here so we |
| 718 | * can recall function without having locking issues */ | 718 | * can recall function without having locking issues */ |
| 719 | mutex_init(&rdev->cs_mutex); | 719 | radeon_mutex_init(&rdev->cs_mutex); |
| 720 | mutex_init(&rdev->ib_pool.mutex); | 720 | mutex_init(&rdev->ib_pool.mutex); |
| 721 | mutex_init(&rdev->cp.mutex); | 721 | mutex_init(&rdev->cp.mutex); |
| 722 | mutex_init(&rdev->dc_hw_i2c_mutex); | 722 | mutex_init(&rdev->dc_hw_i2c_mutex); |
| @@ -955,6 +955,9 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
| 955 | int r; | 955 | int r; |
| 956 | int resched; | 956 | int resched; |
| 957 | 957 | ||
| 958 | /* Prevent CS ioctl from interfering */ | ||
| 959 | radeon_mutex_lock(&rdev->cs_mutex); | ||
| 960 | |||
| 958 | radeon_save_bios_scratch_regs(rdev); | 961 | radeon_save_bios_scratch_regs(rdev); |
| 959 | /* block TTM */ | 962 | /* block TTM */ |
| 960 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); | 963 | resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
| @@ -967,10 +970,15 @@ int radeon_gpu_reset(struct radeon_device *rdev) | |||
| 967 | radeon_restore_bios_scratch_regs(rdev); | 970 | radeon_restore_bios_scratch_regs(rdev); |
| 968 | drm_helper_resume_force_mode(rdev->ddev); | 971 | drm_helper_resume_force_mode(rdev->ddev); |
| 969 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); | 972 | ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); |
| 970 | return 0; | ||
| 971 | } | 973 | } |
| 972 | /* bad news, how to tell it to userspace ? */ | 974 | |
| 973 | dev_info(rdev->dev, "GPU reset failed\n"); | 975 | radeon_mutex_unlock(&rdev->cs_mutex); |
| 976 | |||
| 977 | if (r) { | ||
| 978 | /* bad news, how to tell it to userspace ? */ | ||
| 979 | dev_info(rdev->dev, "GPU reset failed\n"); | ||
| 980 | } | ||
| 981 | |||
| 974 | return r; | 982 | return r; |
| 975 | } | 983 | } |
| 976 | 984 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 41a5d48e657b..daadf2111040 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -991,12 +991,6 @@ static bool radeon_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 991 | struct drm_display_mode *mode, | 991 | struct drm_display_mode *mode, |
| 992 | struct drm_display_mode *adjusted_mode) | 992 | struct drm_display_mode *adjusted_mode) |
| 993 | { | 993 | { |
| 994 | struct drm_device *dev = crtc->dev; | ||
| 995 | struct radeon_device *rdev = dev->dev_private; | ||
| 996 | |||
| 997 | /* adjust pm to upcoming mode change */ | ||
| 998 | radeon_pm_compute_clocks(rdev); | ||
| 999 | |||
| 1000 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) | 994 | if (!radeon_crtc_scaling_mode_fixup(crtc, mode, adjusted_mode)) |
| 1001 | return false; | 995 | return false; |
| 1002 | return true; | 996 | return true; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 6fabe89fa6a1..78a665bd9519 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
| @@ -53,6 +53,24 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev); | |||
| 53 | 53 | ||
| 54 | #define ACPI_AC_CLASS "ac_adapter" | 54 | #define ACPI_AC_CLASS "ac_adapter" |
| 55 | 55 | ||
| 56 | int radeon_pm_get_type_index(struct radeon_device *rdev, | ||
| 57 | enum radeon_pm_state_type ps_type, | ||
| 58 | int instance) | ||
| 59 | { | ||
| 60 | int i; | ||
| 61 | int found_instance = -1; | ||
| 62 | |||
| 63 | for (i = 0; i < rdev->pm.num_power_states; i++) { | ||
| 64 | if (rdev->pm.power_state[i].type == ps_type) { | ||
| 65 | found_instance++; | ||
| 66 | if (found_instance == instance) | ||
| 67 | return i; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | /* return default if no match */ | ||
| 71 | return rdev->pm.default_power_state_index; | ||
| 72 | } | ||
| 73 | |||
| 56 | #ifdef CONFIG_ACPI | 74 | #ifdef CONFIG_ACPI |
| 57 | static int radeon_acpi_event(struct notifier_block *nb, | 75 | static int radeon_acpi_event(struct notifier_block *nb, |
| 58 | unsigned long val, | 76 | unsigned long val, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 03daefa73397..880e285d7578 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -105,6 +105,10 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
| 105 | struct vmw_dma_buffer *dmabuf = NULL; | 105 | struct vmw_dma_buffer *dmabuf = NULL; |
| 106 | int ret; | 106 | int ret; |
| 107 | 107 | ||
| 108 | /* A lot of the code assumes this */ | ||
| 109 | if (handle && (width != 64 || height != 64)) | ||
| 110 | return -EINVAL; | ||
| 111 | |||
| 108 | if (handle) { | 112 | if (handle) { |
| 109 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, | 113 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, |
| 110 | handle, &surface); | 114 | handle, &surface); |
| @@ -410,8 +414,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
| 410 | top = clips->y1; | 414 | top = clips->y1; |
| 411 | bottom = clips->y2; | 415 | bottom = clips->y2; |
| 412 | 416 | ||
| 413 | clips_ptr = clips; | 417 | /* skip the first clip rect */ |
| 414 | for (i = 1; i < num_clips; i++, clips_ptr += inc) { | 418 | for (i = 1, clips_ptr = clips + inc; |
| 419 | i < num_clips; i++, clips_ptr += inc) { | ||
| 415 | left = min_t(int, left, (int)clips_ptr->x1); | 420 | left = min_t(int, left, (int)clips_ptr->x1); |
| 416 | right = max_t(int, right, (int)clips_ptr->x2); | 421 | right = max_t(int, right, (int)clips_ptr->x2); |
| 417 | top = min_t(int, top, (int)clips_ptr->y1); | 422 | top = min_t(int, top, (int)clips_ptr->y1); |
| @@ -1323,7 +1328,10 @@ int vmw_kms_close(struct vmw_private *dev_priv) | |||
| 1323 | * drm_encoder_cleanup which takes the lock we deadlock. | 1328 | * drm_encoder_cleanup which takes the lock we deadlock. |
| 1324 | */ | 1329 | */ |
| 1325 | drm_mode_config_cleanup(dev_priv->dev); | 1330 | drm_mode_config_cleanup(dev_priv->dev); |
| 1326 | vmw_kms_close_legacy_display_system(dev_priv); | 1331 | if (dev_priv->sou_priv) |
| 1332 | vmw_kms_close_screen_object_display(dev_priv); | ||
| 1333 | else | ||
| 1334 | vmw_kms_close_legacy_display_system(dev_priv); | ||
| 1327 | return 0; | 1335 | return 0; |
| 1328 | } | 1336 | } |
| 1329 | 1337 | ||
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 04b09564bfa9..8126824daccb 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | /* For SCSI -> ATAPI command conversion */ | 43 | /* For SCSI -> ATAPI command conversion */ |
| 44 | #include <scsi/scsi.h> | 44 | #include <scsi/scsi.h> |
| 45 | 45 | ||
| 46 | #include <linux/irq.h> | ||
| 47 | #include <linux/io.h> | 46 | #include <linux/io.h> |
| 48 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
| 49 | #include <linux/uaccess.h> | 48 | #include <linux/uaccess.h> |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 61fdf544fbd6..3d42043fec51 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <scsi/scsi_ioctl.h> | 35 | #include <scsi/scsi_ioctl.h> |
| 36 | 36 | ||
| 37 | #include <asm/byteorder.h> | 37 | #include <asm/byteorder.h> |
| 38 | #include <linux/irq.h> | ||
| 39 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
| 40 | #include <linux/io.h> | 39 | #include <linux/io.h> |
| 41 | #include <asm/unaligned.h> | 40 | #include <asm/unaligned.h> |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7ecb1ade8874..ce8237d36159 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <scsi/scsi.h> | 41 | #include <scsi/scsi.h> |
| 42 | 42 | ||
| 43 | #include <asm/byteorder.h> | 43 | #include <asm/byteorder.h> |
| 44 | #include <linux/irq.h> | ||
| 45 | #include <linux/uaccess.h> | 44 | #include <linux/uaccess.h> |
| 46 | #include <linux/io.h> | 45 | #include <linux/io.h> |
| 47 | #include <asm/unaligned.h> | 46 | #include <asm/unaligned.h> |
diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c index 817f37a875c9..c9570fcf1cce 100644 --- a/drivers/macintosh/via-macii.c +++ b/drivers/macintosh/via-macii.c | |||
| @@ -159,7 +159,7 @@ int macii_init(void) | |||
| 159 | err = macii_init_via(); | 159 | err = macii_init_via(); |
| 160 | if (err) goto out; | 160 | if (err) goto out; |
| 161 | 161 | ||
| 162 | err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB", | 162 | err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB", |
| 163 | macii_interrupt); | 163 | macii_interrupt); |
| 164 | if (err) goto out; | 164 | if (err) goto out; |
| 165 | 165 | ||
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c index 9ab5b0c34f0d..34d02a91b29f 100644 --- a/drivers/macintosh/via-maciisi.c +++ b/drivers/macintosh/via-maciisi.c | |||
| @@ -122,8 +122,8 @@ maciisi_init(void) | |||
| 122 | return err; | 122 | return err; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, | 125 | if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB", |
| 126 | "ADB", maciisi_interrupt)) { | 126 | maciisi_interrupt)) { |
| 127 | printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB); | 127 | printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB); |
| 128 | return -EAGAIN; | 128 | return -EAGAIN; |
| 129 | } | 129 | } |
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c index 2e8c288258a9..34434557ef65 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c | |||
| @@ -398,7 +398,6 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state, | |||
| 398 | u8 i2c_r_data[24]; | 398 | u8 i2c_r_data[24]; |
| 399 | u8 i = 0; | 399 | u8 i = 0; |
| 400 | u8 fifo_status = 0; | 400 | u8 fifo_status = 0; |
| 401 | int ret; | ||
| 402 | int status = 0; | 401 | int status = 0; |
| 403 | 402 | ||
| 404 | mxl_i2c("read %d bytes", count); | 403 | mxl_i2c("read %d bytes", count); |
| @@ -418,7 +417,7 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state, | |||
| 418 | i2c_w_data[4+(i*3)] = 0x00; | 417 | i2c_w_data[4+(i*3)] = 0x00; |
| 419 | } | 418 | } |
| 420 | 419 | ||
| 421 | ret = mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data); | 420 | mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data); |
| 422 | 421 | ||
| 423 | /* Check for I2C NACK status */ | 422 | /* Check for I2C NACK status */ |
| 424 | if (mxl111sf_i2c_check_status(state) == 1) { | 423 | if (mxl111sf_i2c_check_status(state) == 1) { |
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c index 91dc1fc2825b..b741b3a7a325 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c | |||
| @@ -296,8 +296,7 @@ int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff) | |||
| 296 | goto fail; | 296 | goto fail; |
| 297 | 297 | ||
| 298 | ret = mxl111sf_write_reg(state, 0x00, 0x00); | 298 | ret = mxl111sf_write_reg(state, 0x00, 0x00); |
| 299 | if (mxl_fail(ret)) | 299 | mxl_fail(ret); |
| 300 | goto fail; | ||
| 301 | fail: | 300 | fail: |
| 302 | return ret; | 301 | return ret; |
| 303 | } | 302 | } |
| @@ -328,11 +327,13 @@ int mxl111sf_idac_config(struct mxl111sf_state *state, | |||
| 328 | /* set hysteresis value reg: 0x0B<5:0> */ | 327 | /* set hysteresis value reg: 0x0B<5:0> */ |
| 329 | ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG, | 328 | ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG, |
| 330 | (hysteresis_value & 0x3F)); | 329 | (hysteresis_value & 0x3F)); |
| 330 | mxl_fail(ret); | ||
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val); | 333 | ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val); |
| 334 | mxl_fail(ret); | ||
| 334 | 335 | ||
| 335 | return val; | 336 | return ret; |
| 336 | } | 337 | } |
| 337 | 338 | ||
| 338 | /* | 339 | /* |
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index 725634d9736d..844a4d7797bc 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c | |||
| @@ -220,8 +220,8 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 220 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); | 220 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); |
| 221 | cap->bus_info[0] = 0; | 221 | cap->bus_info[0] = 0; |
| 222 | cap->version = KERNEL_VERSION(1, 0, 0); | 222 | cap->version = KERNEL_VERSION(1, 0, 0); |
| 223 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | 223 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
| 224 | | V4L2_CAP_STREAMING; | 224 | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; |
| 225 | return 0; | 225 | return 0; |
| 226 | } | 226 | } |
| 227 | 227 | ||
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index ecef127dbc66..1e8cdb77d4b8 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c | |||
| @@ -785,8 +785,8 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 785 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); | 785 | strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); |
| 786 | cap->bus_info[0] = 0; | 786 | cap->bus_info[0] = 0; |
| 787 | cap->version = KERNEL_VERSION(1, 0, 0); | 787 | cap->version = KERNEL_VERSION(1, 0, 0); |
| 788 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 788 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
| 789 | | V4L2_CAP_VIDEO_OUTPUT | 789 | | V4L2_CAP_VIDEO_OUTPUT_MPLANE |
| 790 | | V4L2_CAP_STREAMING; | 790 | | V4L2_CAP_STREAMING; |
| 791 | return 0; | 791 | return 0; |
| 792 | } | 792 | } |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 10c2364f3e8a..254d32688843 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
| @@ -1016,7 +1016,8 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | |||
| 1016 | 1016 | ||
| 1017 | menu_info = &mapping->menu_info[query_menu->index]; | 1017 | menu_info = &mapping->menu_info[query_menu->index]; |
| 1018 | 1018 | ||
| 1019 | if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { | 1019 | if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && |
| 1020 | (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { | ||
| 1020 | s32 bitmap; | 1021 | s32 bitmap; |
| 1021 | 1022 | ||
| 1022 | if (!ctrl->cached) { | 1023 | if (!ctrl->cached) { |
| @@ -1225,7 +1226,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
| 1225 | /* Valid menu indices are reported by the GET_RES request for | 1226 | /* Valid menu indices are reported by the GET_RES request for |
| 1226 | * UVC controls that support it. | 1227 | * UVC controls that support it. |
| 1227 | */ | 1228 | */ |
| 1228 | if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { | 1229 | if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && |
| 1230 | (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { | ||
| 1229 | if (!ctrl->cached) { | 1231 | if (!ctrl->cached) { |
| 1230 | ret = uvc_ctrl_populate_cache(chain, ctrl); | 1232 | ret = uvc_ctrl_populate_cache(chain, ctrl); |
| 1231 | if (ret < 0) | 1233 | if (ret < 0) |
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index f17f92b86a30..0f415dade05a 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c | |||
| @@ -821,8 +821,8 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) | |||
| 821 | fill_event(&ev, ctrl, changes); | 821 | fill_event(&ev, ctrl, changes); |
| 822 | 822 | ||
| 823 | list_for_each_entry(sev, &ctrl->ev_subs, node) | 823 | list_for_each_entry(sev, &ctrl->ev_subs, node) |
| 824 | if (sev->fh && (sev->fh != fh || | 824 | if (sev->fh != fh || |
| 825 | (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))) | 825 | (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)) |
| 826 | v4l2_event_queue_fh(sev->fh, &ev); | 826 | v4l2_event_queue_fh(sev->fh, &ev); |
| 827 | } | 827 | } |
| 828 | 828 | ||
| @@ -947,6 +947,7 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, | |||
| 947 | if (ctrl->cluster[0]->has_volatiles) | 947 | if (ctrl->cluster[0]->has_volatiles) |
| 948 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; | 948 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; |
| 949 | } | 949 | } |
| 950 | fh = NULL; | ||
| 950 | } | 951 | } |
| 951 | if (changed || update_inactive) { | 952 | if (changed || update_inactive) { |
| 952 | /* If a control was changed that was not one of the controls | 953 | /* If a control was changed that was not one of the controls |
diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index 46037f225529..c26ad9637143 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c | |||
| @@ -216,6 +216,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, | |||
| 216 | unsigned long flags; | 216 | unsigned long flags; |
| 217 | unsigned i; | 217 | unsigned i; |
| 218 | 218 | ||
| 219 | if (sub->type == V4L2_EVENT_ALL) | ||
| 220 | return -EINVAL; | ||
| 221 | |||
| 219 | if (elems < 1) | 222 | if (elems < 1) |
| 220 | elems = 1; | 223 | elems = 1; |
| 221 | if (sub->type == V4L2_EVENT_CTRL) { | 224 | if (sub->type == V4L2_EVENT_CTRL) { |
| @@ -283,6 +286,7 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
| 283 | { | 286 | { |
| 284 | struct v4l2_subscribed_event *sev; | 287 | struct v4l2_subscribed_event *sev; |
| 285 | unsigned long flags; | 288 | unsigned long flags; |
| 289 | int i; | ||
| 286 | 290 | ||
| 287 | if (sub->type == V4L2_EVENT_ALL) { | 291 | if (sub->type == V4L2_EVENT_ALL) { |
| 288 | v4l2_event_unsubscribe_all(fh); | 292 | v4l2_event_unsubscribe_all(fh); |
| @@ -293,8 +297,12 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
| 293 | 297 | ||
| 294 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); | 298 | sev = v4l2_event_subscribed(fh, sub->type, sub->id); |
| 295 | if (sev != NULL) { | 299 | if (sev != NULL) { |
| 300 | /* Remove any pending events for this subscription */ | ||
| 301 | for (i = 0; i < sev->in_use; i++) { | ||
| 302 | list_del(&sev->events[sev_pos(sev, i)].list); | ||
| 303 | fh->navailable--; | ||
| 304 | } | ||
| 296 | list_del(&sev->list); | 305 | list_del(&sev->list); |
| 297 | sev->fh = NULL; | ||
| 298 | } | 306 | } |
| 299 | 307 | ||
| 300 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); | 308 | spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); |
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 979e544388cb..95a3f5e82aef 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c | |||
| @@ -131,6 +131,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) | |||
| 131 | continue; | 131 | continue; |
| 132 | 132 | ||
| 133 | for (plane = 0; plane < vb->num_planes; ++plane) { | 133 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 134 | vb->v4l2_planes[plane].length = q->plane_sizes[plane]; | ||
| 134 | vb->v4l2_planes[plane].m.mem_offset = off; | 135 | vb->v4l2_planes[plane].m.mem_offset = off; |
| 135 | 136 | ||
| 136 | dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n", | 137 | dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n", |
| @@ -264,6 +265,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) | |||
| 264 | q->num_buffers -= buffers; | 265 | q->num_buffers -= buffers; |
| 265 | if (!q->num_buffers) | 266 | if (!q->num_buffers) |
| 266 | q->memory = 0; | 267 | q->memory = 0; |
| 268 | INIT_LIST_HEAD(&q->queued_list); | ||
| 267 | } | 269 | } |
| 268 | 270 | ||
| 269 | /** | 271 | /** |
| @@ -296,14 +298,14 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) | |||
| 296 | { | 298 | { |
| 297 | unsigned int plane; | 299 | unsigned int plane; |
| 298 | for (plane = 0; plane < vb->num_planes; ++plane) { | 300 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 301 | void *mem_priv = vb->planes[plane].mem_priv; | ||
| 299 | /* | 302 | /* |
| 300 | * If num_users() has not been provided, call_memop | 303 | * If num_users() has not been provided, call_memop |
| 301 | * will return 0, apparently nobody cares about this | 304 | * will return 0, apparently nobody cares about this |
| 302 | * case anyway. If num_users() returns more than 1, | 305 | * case anyway. If num_users() returns more than 1, |
| 303 | * we are not the only user of the plane's memory. | 306 | * we are not the only user of the plane's memory. |
| 304 | */ | 307 | */ |
| 305 | if (call_memop(q, plane, num_users, | 308 | if (mem_priv && call_memop(q, plane, num_users, mem_priv) > 1) |
| 306 | vb->planes[plane].mem_priv) > 1) | ||
| 307 | return true; | 309 | return true; |
| 308 | } | 310 | } |
| 309 | return false; | 311 | return false; |
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index d9fb729535a1..fb7300837fee 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c | |||
| @@ -952,7 +952,7 @@ static int ps3_vuart_bus_interrupt_get(void) | |||
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler, | 954 | result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler, |
| 955 | IRQF_DISABLED, "vuart", &vuart_bus_priv); | 955 | 0, "vuart", &vuart_bus_priv); |
| 956 | 956 | ||
| 957 | if (result) { | 957 | if (result) { |
| 958 | pr_debug("%s:%d: request_irq failed (%d)\n", | 958 | pr_debug("%s:%d: request_irq failed (%d)\n", |
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index cc328dec946b..8c3f5adf1bc6 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c | |||
| @@ -167,7 +167,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler) | |||
| 167 | goto fail_close_device; | 167 | goto fail_close_device; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | error = request_irq(dev->irq, handler, IRQF_DISABLED, | 170 | error = request_irq(dev->irq, handler, 0, |
| 171 | dev->sbd.core.driver->name, dev); | 171 | dev->sbd.core.driver->name, dev); |
| 172 | if (error) { | 172 | if (error) { |
| 173 | dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n", | 173 | dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n", |
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index d33544802a2e..bb21f443fb70 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c | |||
| @@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void) | |||
| 76 | /* | 76 | /* |
| 77 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR | 77 | * rtc_time's year contains the increment over 1900, but vRTC's YEAR |
| 78 | * register can't be programmed to value larger than 0x64, so vRTC | 78 | * register can't be programmed to value larger than 0x64, so vRTC |
| 79 | * driver chose to use 1960 (1970 is UNIX time start point) as the base, | 79 | * driver chose to use 1972 (1970 is UNIX time start point) as the base, |
| 80 | * and does the translation at read/write time. | 80 | * and does the translation at read/write time. |
| 81 | * | 81 | * |
| 82 | * Why not just use 1970 as the offset? it's because using 1960 will | 82 | * Why not just use 1970 as the offset? it's because using 1972 will |
| 83 | * make it consistent in leap year setting for both vrtc and low-level | 83 | * make it consistent in leap year setting for both vrtc and low-level |
| 84 | * physical rtc devices. | 84 | * physical rtc devices. Then why not use 1960 as the offset? If we use |
| 85 | * 1960, for a device's first use, its YEAR register is 0 and the system | ||
| 86 | * year will be parsed as 1960 which is not a valid UNIX time and will | ||
| 87 | * cause many applications to fail mysteriously. | ||
| 85 | */ | 88 | */ |
| 86 | static int mrst_read_time(struct device *dev, struct rtc_time *time) | 89 | static int mrst_read_time(struct device *dev, struct rtc_time *time) |
| 87 | { | 90 | { |
| @@ -99,10 +102,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time) | |||
| 99 | time->tm_year = vrtc_cmos_read(RTC_YEAR); | 102 | time->tm_year = vrtc_cmos_read(RTC_YEAR); |
| 100 | spin_unlock_irqrestore(&rtc_lock, flags); | 103 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 101 | 104 | ||
| 102 | /* Adjust for the 1960/1900 */ | 105 | /* Adjust for the 1972/1900 */ |
| 103 | time->tm_year += 60; | 106 | time->tm_year += 72; |
| 104 | time->tm_mon--; | 107 | time->tm_mon--; |
| 105 | return RTC_24H; | 108 | return rtc_valid_tm(time); |
| 106 | } | 109 | } |
| 107 | 110 | ||
| 108 | static int mrst_set_time(struct device *dev, struct rtc_time *time) | 111 | static int mrst_set_time(struct device *dev, struct rtc_time *time) |
| @@ -119,9 +122,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time) | |||
| 119 | min = time->tm_min; | 122 | min = time->tm_min; |
| 120 | sec = time->tm_sec; | 123 | sec = time->tm_sec; |
| 121 | 124 | ||
| 122 | if (yrs < 70 || yrs > 138) | 125 | if (yrs < 72 || yrs > 138) |
| 123 | return -EINVAL; | 126 | return -EINVAL; |
| 124 | yrs -= 60; | 127 | yrs -= 72; |
| 125 | 128 | ||
| 126 | spin_lock_irqsave(&rtc_lock, flags); | 129 | spin_lock_irqsave(&rtc_lock, flags); |
| 127 | 130 | ||
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 5a5d325a3935..634608d2a6d0 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
| @@ -147,14 +147,12 @@ struct btrfs_inode { | |||
| 147 | * the btrfs file release call will add this inode to the | 147 | * the btrfs file release call will add this inode to the |
| 148 | * ordered operations list so that we make sure to flush out any | 148 | * ordered operations list so that we make sure to flush out any |
| 149 | * new data the application may have written before commit. | 149 | * new data the application may have written before commit. |
| 150 | * | ||
| 151 | * yes, its silly to have a single bitflag, but we might grow more | ||
| 152 | * of these. | ||
| 153 | */ | 150 | */ |
| 154 | unsigned ordered_data_close:1; | 151 | unsigned ordered_data_close:1; |
| 155 | unsigned orphan_meta_reserved:1; | 152 | unsigned orphan_meta_reserved:1; |
| 156 | unsigned dummy_inode:1; | 153 | unsigned dummy_inode:1; |
| 157 | unsigned in_defrag:1; | 154 | unsigned in_defrag:1; |
| 155 | unsigned delalloc_meta_reserved:1; | ||
| 158 | 156 | ||
| 159 | /* | 157 | /* |
| 160 | * always compress this one file | 158 | * always compress this one file |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 3a1b939c9ae2..5b163572e0ca 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
| @@ -617,12 +617,14 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, | |||
| 617 | static int btrfs_delayed_inode_reserve_metadata( | 617 | static int btrfs_delayed_inode_reserve_metadata( |
| 618 | struct btrfs_trans_handle *trans, | 618 | struct btrfs_trans_handle *trans, |
| 619 | struct btrfs_root *root, | 619 | struct btrfs_root *root, |
| 620 | struct inode *inode, | ||
| 620 | struct btrfs_delayed_node *node) | 621 | struct btrfs_delayed_node *node) |
| 621 | { | 622 | { |
| 622 | struct btrfs_block_rsv *src_rsv; | 623 | struct btrfs_block_rsv *src_rsv; |
| 623 | struct btrfs_block_rsv *dst_rsv; | 624 | struct btrfs_block_rsv *dst_rsv; |
| 624 | u64 num_bytes; | 625 | u64 num_bytes; |
| 625 | int ret; | 626 | int ret; |
| 627 | int release = false; | ||
| 626 | 628 | ||
| 627 | src_rsv = trans->block_rsv; | 629 | src_rsv = trans->block_rsv; |
| 628 | dst_rsv = &root->fs_info->delayed_block_rsv; | 630 | dst_rsv = &root->fs_info->delayed_block_rsv; |
| @@ -652,12 +654,65 @@ static int btrfs_delayed_inode_reserve_metadata( | |||
| 652 | if (!ret) | 654 | if (!ret) |
| 653 | node->bytes_reserved = num_bytes; | 655 | node->bytes_reserved = num_bytes; |
| 654 | return ret; | 656 | return ret; |
| 657 | } else if (src_rsv == &root->fs_info->delalloc_block_rsv) { | ||
| 658 | spin_lock(&BTRFS_I(inode)->lock); | ||
| 659 | if (BTRFS_I(inode)->delalloc_meta_reserved) { | ||
| 660 | BTRFS_I(inode)->delalloc_meta_reserved = 0; | ||
| 661 | spin_unlock(&BTRFS_I(inode)->lock); | ||
| 662 | release = true; | ||
| 663 | goto migrate; | ||
| 664 | } | ||
| 665 | spin_unlock(&BTRFS_I(inode)->lock); | ||
| 666 | |||
| 667 | /* Ok we didn't have space pre-reserved. This shouldn't happen | ||
| 668 | * too often but it can happen if we do delalloc to an existing | ||
| 669 | * inode which gets dirtied because of the time update, and then | ||
| 670 | * isn't touched again until after the transaction commits and | ||
| 671 | * then we try to write out the data. First try to be nice and | ||
| 672 | * reserve something strictly for us. If not be a pain and try | ||
| 673 | * to steal from the delalloc block rsv. | ||
| 674 | */ | ||
| 675 | ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes); | ||
| 676 | if (!ret) | ||
| 677 | goto out; | ||
| 678 | |||
| 679 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | ||
| 680 | if (!ret) | ||
| 681 | goto out; | ||
| 682 | |||
| 683 | /* | ||
| 684 | * Ok this is a problem, let's just steal from the global rsv | ||
| 685 | * since this really shouldn't happen that often. | ||
| 686 | */ | ||
| 687 | WARN_ON(1); | ||
| 688 | ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, | ||
| 689 | dst_rsv, num_bytes); | ||
| 690 | goto out; | ||
| 655 | } | 691 | } |
| 656 | 692 | ||
| 693 | migrate: | ||
| 657 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 694 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
| 695 | |||
| 696 | out: | ||
| 697 | /* | ||
| 698 | * Migrate only takes a reservation, it doesn't touch the size of the | ||
| 699 | * block_rsv. This is to simplify people who don't normally have things | ||
| 700 | * migrated from their block rsv. If they go to release their | ||
| 701 | * reservation, that will decrease the size as well, so if migrate | ||
| 702 | * reduced size we'd end up with a negative size. But for the | ||
| 703 | * delalloc_meta_reserved stuff we will only know to drop 1 reservation, | ||
| 704 | * but we could in fact do this reserve/migrate dance several times | ||
| 705 | * between the time we did the original reservation and we'd clean it | ||
| 706 | * up. So to take care of this, release the space for the meta | ||
| 707 | * reservation here. I think it may be time for a documentation page on | ||
| 708 | * how block rsvs. work. | ||
| 709 | */ | ||
| 658 | if (!ret) | 710 | if (!ret) |
| 659 | node->bytes_reserved = num_bytes; | 711 | node->bytes_reserved = num_bytes; |
| 660 | 712 | ||
| 713 | if (release) | ||
| 714 | btrfs_block_rsv_release(root, src_rsv, num_bytes); | ||
| 715 | |||
| 661 | return ret; | 716 | return ret; |
| 662 | } | 717 | } |
| 663 | 718 | ||
| @@ -1708,7 +1763,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | |||
| 1708 | goto release_node; | 1763 | goto release_node; |
| 1709 | } | 1764 | } |
| 1710 | 1765 | ||
| 1711 | ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); | 1766 | ret = btrfs_delayed_inode_reserve_metadata(trans, root, inode, |
| 1767 | delayed_node); | ||
| 1712 | if (ret) | 1768 | if (ret) |
| 1713 | goto release_node; | 1769 | goto release_node; |
| 1714 | 1770 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 102c176fc29c..62afe5c5694e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1890,31 +1890,32 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1890 | u64 features; | 1890 | u64 features; |
| 1891 | struct btrfs_key location; | 1891 | struct btrfs_key location; |
| 1892 | struct buffer_head *bh; | 1892 | struct buffer_head *bh; |
| 1893 | struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), | 1893 | struct btrfs_super_block *disk_super; |
| 1894 | GFP_NOFS); | ||
| 1895 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | ||
| 1896 | GFP_NOFS); | ||
| 1897 | struct btrfs_root *tree_root = btrfs_sb(sb); | 1894 | struct btrfs_root *tree_root = btrfs_sb(sb); |
| 1898 | struct btrfs_fs_info *fs_info = NULL; | 1895 | struct btrfs_fs_info *fs_info = tree_root->fs_info; |
| 1899 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), | 1896 | struct btrfs_root *extent_root; |
| 1900 | GFP_NOFS); | 1897 | struct btrfs_root *csum_root; |
| 1901 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1898 | struct btrfs_root *chunk_root; |
| 1902 | GFP_NOFS); | 1899 | struct btrfs_root *dev_root; |
| 1903 | struct btrfs_root *log_tree_root; | 1900 | struct btrfs_root *log_tree_root; |
| 1904 | |||
| 1905 | int ret; | 1901 | int ret; |
| 1906 | int err = -EINVAL; | 1902 | int err = -EINVAL; |
| 1907 | int num_backups_tried = 0; | 1903 | int num_backups_tried = 0; |
| 1908 | int backup_index = 0; | 1904 | int backup_index = 0; |
| 1909 | 1905 | ||
| 1910 | struct btrfs_super_block *disk_super; | 1906 | extent_root = fs_info->extent_root = |
| 1907 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 1908 | csum_root = fs_info->csum_root = | ||
| 1909 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 1910 | chunk_root = fs_info->chunk_root = | ||
| 1911 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 1912 | dev_root = fs_info->dev_root = | ||
| 1913 | kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 1911 | 1914 | ||
| 1912 | if (!extent_root || !tree_root || !tree_root->fs_info || | 1915 | if (!extent_root || !csum_root || !chunk_root || !dev_root) { |
| 1913 | !chunk_root || !dev_root || !csum_root) { | ||
| 1914 | err = -ENOMEM; | 1916 | err = -ENOMEM; |
| 1915 | goto fail; | 1917 | goto fail; |
| 1916 | } | 1918 | } |
| 1917 | fs_info = tree_root->fs_info; | ||
| 1918 | 1919 | ||
| 1919 | ret = init_srcu_struct(&fs_info->subvol_srcu); | 1920 | ret = init_srcu_struct(&fs_info->subvol_srcu); |
| 1920 | if (ret) { | 1921 | if (ret) { |
| @@ -1954,12 +1955,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1954 | mutex_init(&fs_info->reloc_mutex); | 1955 | mutex_init(&fs_info->reloc_mutex); |
| 1955 | 1956 | ||
| 1956 | init_completion(&fs_info->kobj_unregister); | 1957 | init_completion(&fs_info->kobj_unregister); |
| 1957 | fs_info->tree_root = tree_root; | ||
| 1958 | fs_info->extent_root = extent_root; | ||
| 1959 | fs_info->csum_root = csum_root; | ||
| 1960 | fs_info->chunk_root = chunk_root; | ||
| 1961 | fs_info->dev_root = dev_root; | ||
| 1962 | fs_info->fs_devices = fs_devices; | ||
| 1963 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); | 1958 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); |
| 1964 | INIT_LIST_HEAD(&fs_info->space_info); | 1959 | INIT_LIST_HEAD(&fs_info->space_info); |
| 1965 | btrfs_mapping_init(&fs_info->mapping_tree); | 1960 | btrfs_mapping_init(&fs_info->mapping_tree); |
| @@ -2465,21 +2460,20 @@ fail_sb_buffer: | |||
| 2465 | btrfs_stop_workers(&fs_info->caching_workers); | 2460 | btrfs_stop_workers(&fs_info->caching_workers); |
| 2466 | fail_alloc: | 2461 | fail_alloc: |
| 2467 | fail_iput: | 2462 | fail_iput: |
| 2463 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | ||
| 2464 | |||
| 2468 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2465 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
| 2469 | iput(fs_info->btree_inode); | 2466 | iput(fs_info->btree_inode); |
| 2470 | |||
| 2471 | btrfs_close_devices(fs_info->fs_devices); | ||
| 2472 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | ||
| 2473 | fail_bdi: | 2467 | fail_bdi: |
| 2474 | bdi_destroy(&fs_info->bdi); | 2468 | bdi_destroy(&fs_info->bdi); |
| 2475 | fail_srcu: | 2469 | fail_srcu: |
| 2476 | cleanup_srcu_struct(&fs_info->subvol_srcu); | 2470 | cleanup_srcu_struct(&fs_info->subvol_srcu); |
| 2477 | fail: | 2471 | fail: |
| 2472 | btrfs_close_devices(fs_info->fs_devices); | ||
| 2478 | free_fs_info(fs_info); | 2473 | free_fs_info(fs_info); |
| 2479 | return ERR_PTR(err); | 2474 | return ERR_PTR(err); |
| 2480 | 2475 | ||
| 2481 | recovery_tree_root: | 2476 | recovery_tree_root: |
| 2482 | |||
| 2483 | if (!btrfs_test_opt(tree_root, RECOVERY)) | 2477 | if (!btrfs_test_opt(tree_root, RECOVERY)) |
| 2484 | goto fail_tree_roots; | 2478 | goto fail_tree_roots; |
| 2485 | 2479 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9879bd474632..b232150b5b6b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -3797,16 +3797,16 @@ void btrfs_free_block_rsv(struct btrfs_root *root, | |||
| 3797 | kfree(rsv); | 3797 | kfree(rsv); |
| 3798 | } | 3798 | } |
| 3799 | 3799 | ||
| 3800 | int btrfs_block_rsv_add(struct btrfs_root *root, | 3800 | static inline int __block_rsv_add(struct btrfs_root *root, |
| 3801 | struct btrfs_block_rsv *block_rsv, | 3801 | struct btrfs_block_rsv *block_rsv, |
| 3802 | u64 num_bytes) | 3802 | u64 num_bytes, int flush) |
| 3803 | { | 3803 | { |
| 3804 | int ret; | 3804 | int ret; |
| 3805 | 3805 | ||
| 3806 | if (num_bytes == 0) | 3806 | if (num_bytes == 0) |
| 3807 | return 0; | 3807 | return 0; |
| 3808 | 3808 | ||
| 3809 | ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1); | 3809 | ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush); |
| 3810 | if (!ret) { | 3810 | if (!ret) { |
| 3811 | block_rsv_add_bytes(block_rsv, num_bytes, 1); | 3811 | block_rsv_add_bytes(block_rsv, num_bytes, 1); |
| 3812 | return 0; | 3812 | return 0; |
| @@ -3815,22 +3815,18 @@ int btrfs_block_rsv_add(struct btrfs_root *root, | |||
| 3815 | return ret; | 3815 | return ret; |
| 3816 | } | 3816 | } |
| 3817 | 3817 | ||
| 3818 | int btrfs_block_rsv_add(struct btrfs_root *root, | ||
| 3819 | struct btrfs_block_rsv *block_rsv, | ||
| 3820 | u64 num_bytes) | ||
| 3821 | { | ||
| 3822 | return __block_rsv_add(root, block_rsv, num_bytes, 1); | ||
| 3823 | } | ||
| 3824 | |||
| 3818 | int btrfs_block_rsv_add_noflush(struct btrfs_root *root, | 3825 | int btrfs_block_rsv_add_noflush(struct btrfs_root *root, |
| 3819 | struct btrfs_block_rsv *block_rsv, | 3826 | struct btrfs_block_rsv *block_rsv, |
| 3820 | u64 num_bytes) | 3827 | u64 num_bytes) |
| 3821 | { | 3828 | { |
| 3822 | int ret; | 3829 | return __block_rsv_add(root, block_rsv, num_bytes, 0); |
| 3823 | |||
| 3824 | if (num_bytes == 0) | ||
| 3825 | return 0; | ||
| 3826 | |||
| 3827 | ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 0); | ||
| 3828 | if (!ret) { | ||
| 3829 | block_rsv_add_bytes(block_rsv, num_bytes, 1); | ||
| 3830 | return 0; | ||
| 3831 | } | ||
| 3832 | |||
| 3833 | return ret; | ||
| 3834 | } | 3830 | } |
| 3835 | 3831 | ||
| 3836 | int btrfs_block_rsv_check(struct btrfs_root *root, | 3832 | int btrfs_block_rsv_check(struct btrfs_root *root, |
| @@ -4064,23 +4060,30 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 4064 | */ | 4060 | */ |
| 4065 | static unsigned drop_outstanding_extent(struct inode *inode) | 4061 | static unsigned drop_outstanding_extent(struct inode *inode) |
| 4066 | { | 4062 | { |
| 4063 | unsigned drop_inode_space = 0; | ||
| 4067 | unsigned dropped_extents = 0; | 4064 | unsigned dropped_extents = 0; |
| 4068 | 4065 | ||
| 4069 | BUG_ON(!BTRFS_I(inode)->outstanding_extents); | 4066 | BUG_ON(!BTRFS_I(inode)->outstanding_extents); |
| 4070 | BTRFS_I(inode)->outstanding_extents--; | 4067 | BTRFS_I(inode)->outstanding_extents--; |
| 4071 | 4068 | ||
| 4069 | if (BTRFS_I(inode)->outstanding_extents == 0 && | ||
| 4070 | BTRFS_I(inode)->delalloc_meta_reserved) { | ||
| 4071 | drop_inode_space = 1; | ||
| 4072 | BTRFS_I(inode)->delalloc_meta_reserved = 0; | ||
| 4073 | } | ||
| 4074 | |||
| 4072 | /* | 4075 | /* |
| 4073 | * If we have more or the same amount of outsanding extents than we have | 4076 | * If we have more or the same amount of outsanding extents than we have |
| 4074 | * reserved then we need to leave the reserved extents count alone. | 4077 | * reserved then we need to leave the reserved extents count alone. |
| 4075 | */ | 4078 | */ |
| 4076 | if (BTRFS_I(inode)->outstanding_extents >= | 4079 | if (BTRFS_I(inode)->outstanding_extents >= |
| 4077 | BTRFS_I(inode)->reserved_extents) | 4080 | BTRFS_I(inode)->reserved_extents) |
| 4078 | return 0; | 4081 | return drop_inode_space; |
| 4079 | 4082 | ||
| 4080 | dropped_extents = BTRFS_I(inode)->reserved_extents - | 4083 | dropped_extents = BTRFS_I(inode)->reserved_extents - |
| 4081 | BTRFS_I(inode)->outstanding_extents; | 4084 | BTRFS_I(inode)->outstanding_extents; |
| 4082 | BTRFS_I(inode)->reserved_extents -= dropped_extents; | 4085 | BTRFS_I(inode)->reserved_extents -= dropped_extents; |
| 4083 | return dropped_extents; | 4086 | return dropped_extents + drop_inode_space; |
| 4084 | } | 4087 | } |
| 4085 | 4088 | ||
| 4086 | /** | 4089 | /** |
| @@ -4166,9 +4169,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
| 4166 | nr_extents = BTRFS_I(inode)->outstanding_extents - | 4169 | nr_extents = BTRFS_I(inode)->outstanding_extents - |
| 4167 | BTRFS_I(inode)->reserved_extents; | 4170 | BTRFS_I(inode)->reserved_extents; |
| 4168 | BTRFS_I(inode)->reserved_extents += nr_extents; | 4171 | BTRFS_I(inode)->reserved_extents += nr_extents; |
| 4172 | } | ||
| 4169 | 4173 | ||
| 4170 | to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); | 4174 | /* |
| 4175 | * Add an item to reserve for updating the inode when we complete the | ||
| 4176 | * delalloc io. | ||
| 4177 | */ | ||
| 4178 | if (!BTRFS_I(inode)->delalloc_meta_reserved) { | ||
| 4179 | nr_extents++; | ||
| 4180 | BTRFS_I(inode)->delalloc_meta_reserved = 1; | ||
| 4171 | } | 4181 | } |
| 4182 | |||
| 4183 | to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); | ||
| 4172 | to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); | 4184 | to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); |
| 4173 | spin_unlock(&BTRFS_I(inode)->lock); | 4185 | spin_unlock(&BTRFS_I(inode)->lock); |
| 4174 | 4186 | ||
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 7a15fcfb3e1f..181760f9d2ab 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -537,6 +537,13 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl, | |||
| 537 | struct btrfs_free_space *entry, u8 *type) | 537 | struct btrfs_free_space *entry, u8 *type) |
| 538 | { | 538 | { |
| 539 | struct btrfs_free_space_entry *e; | 539 | struct btrfs_free_space_entry *e; |
| 540 | int ret; | ||
| 541 | |||
| 542 | if (!io_ctl->cur) { | ||
| 543 | ret = io_ctl_check_crc(io_ctl, io_ctl->index); | ||
| 544 | if (ret) | ||
| 545 | return ret; | ||
| 546 | } | ||
| 540 | 547 | ||
| 541 | e = io_ctl->cur; | 548 | e = io_ctl->cur; |
| 542 | entry->offset = le64_to_cpu(e->offset); | 549 | entry->offset = le64_to_cpu(e->offset); |
| @@ -550,10 +557,7 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl, | |||
| 550 | 557 | ||
| 551 | io_ctl_unmap_page(io_ctl); | 558 | io_ctl_unmap_page(io_ctl); |
| 552 | 559 | ||
| 553 | if (io_ctl->index >= io_ctl->num_pages) | 560 | return 0; |
| 554 | return 0; | ||
| 555 | |||
| 556 | return io_ctl_check_crc(io_ctl, io_ctl->index); | ||
| 557 | } | 561 | } |
| 558 | 562 | ||
| 559 | static int io_ctl_read_bitmap(struct io_ctl *io_ctl, | 563 | static int io_ctl_read_bitmap(struct io_ctl *io_ctl, |
| @@ -561,9 +565,6 @@ static int io_ctl_read_bitmap(struct io_ctl *io_ctl, | |||
| 561 | { | 565 | { |
| 562 | int ret; | 566 | int ret; |
| 563 | 567 | ||
| 564 | if (io_ctl->cur && io_ctl->cur != io_ctl->orig) | ||
| 565 | io_ctl_unmap_page(io_ctl); | ||
| 566 | |||
| 567 | ret = io_ctl_check_crc(io_ctl, io_ctl->index); | 568 | ret = io_ctl_check_crc(io_ctl, io_ctl->index); |
| 568 | if (ret) | 569 | if (ret) |
| 569 | return ret; | 570 | return ret; |
| @@ -699,6 +700,8 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
| 699 | num_entries--; | 700 | num_entries--; |
| 700 | } | 701 | } |
| 701 | 702 | ||
| 703 | io_ctl_unmap_page(&io_ctl); | ||
| 704 | |||
| 702 | /* | 705 | /* |
| 703 | * We add the bitmaps at the end of the entries in order that | 706 | * We add the bitmaps at the end of the entries in order that |
| 704 | * the bitmap entries are added to the cache. | 707 | * the bitmap entries are added to the cache. |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 53dcbdf446cd..f8962a957d65 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
| @@ -398,6 +398,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
| 398 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | 398 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
| 399 | struct btrfs_path *path; | 399 | struct btrfs_path *path; |
| 400 | struct inode *inode; | 400 | struct inode *inode; |
| 401 | struct btrfs_block_rsv *rsv; | ||
| 402 | u64 num_bytes; | ||
| 401 | u64 alloc_hint = 0; | 403 | u64 alloc_hint = 0; |
| 402 | int ret; | 404 | int ret; |
| 403 | int prealloc; | 405 | int prealloc; |
| @@ -421,11 +423,26 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
| 421 | if (!path) | 423 | if (!path) |
| 422 | return -ENOMEM; | 424 | return -ENOMEM; |
| 423 | 425 | ||
| 426 | rsv = trans->block_rsv; | ||
| 427 | trans->block_rsv = &root->fs_info->trans_block_rsv; | ||
| 428 | |||
| 429 | num_bytes = trans->bytes_reserved; | ||
| 430 | /* | ||
| 431 | * 1 item for inode item insertion if need | ||
| 432 | * 3 items for inode item update (in the worst case) | ||
| 433 | * 1 item for free space object | ||
| 434 | * 3 items for pre-allocation | ||
| 435 | */ | ||
| 436 | trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8); | ||
| 437 | ret = btrfs_block_rsv_add_noflush(root, trans->block_rsv, | ||
| 438 | trans->bytes_reserved); | ||
| 439 | if (ret) | ||
| 440 | goto out; | ||
| 424 | again: | 441 | again: |
| 425 | inode = lookup_free_ino_inode(root, path); | 442 | inode = lookup_free_ino_inode(root, path); |
| 426 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { | 443 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { |
| 427 | ret = PTR_ERR(inode); | 444 | ret = PTR_ERR(inode); |
| 428 | goto out; | 445 | goto out_release; |
| 429 | } | 446 | } |
| 430 | 447 | ||
| 431 | if (IS_ERR(inode)) { | 448 | if (IS_ERR(inode)) { |
| @@ -434,7 +451,7 @@ again: | |||
| 434 | 451 | ||
| 435 | ret = create_free_ino_inode(root, trans, path); | 452 | ret = create_free_ino_inode(root, trans, path); |
| 436 | if (ret) | 453 | if (ret) |
| 437 | goto out; | 454 | goto out_release; |
| 438 | goto again; | 455 | goto again; |
| 439 | } | 456 | } |
| 440 | 457 | ||
| @@ -477,11 +494,14 @@ again: | |||
| 477 | } | 494 | } |
| 478 | btrfs_free_reserved_data_space(inode, prealloc); | 495 | btrfs_free_reserved_data_space(inode, prealloc); |
| 479 | 496 | ||
| 497 | ret = btrfs_write_out_ino_cache(root, trans, path); | ||
| 480 | out_put: | 498 | out_put: |
| 481 | iput(inode); | 499 | iput(inode); |
| 500 | out_release: | ||
| 501 | btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); | ||
| 482 | out: | 502 | out: |
| 483 | if (ret == 0) | 503 | trans->block_rsv = rsv; |
| 484 | ret = btrfs_write_out_ino_cache(root, trans, path); | 504 | trans->bytes_reserved = num_bytes; |
| 485 | 505 | ||
| 486 | btrfs_free_path(path); | 506 | btrfs_free_path(path); |
| 487 | return ret; | 507 | return ret; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 966ddcc4c63d..116ab67a06df 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -93,6 +93,8 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 93 | struct page *locked_page, | 93 | struct page *locked_page, |
| 94 | u64 start, u64 end, int *page_started, | 94 | u64 start, u64 end, int *page_started, |
| 95 | unsigned long *nr_written, int unlock); | 95 | unsigned long *nr_written, int unlock); |
| 96 | static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, | ||
| 97 | struct btrfs_root *root, struct inode *inode); | ||
| 96 | 98 | ||
| 97 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, | 99 | static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, |
| 98 | struct inode *inode, struct inode *dir, | 100 | struct inode *inode, struct inode *dir, |
| @@ -1741,7 +1743,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1741 | trans = btrfs_join_transaction(root); | 1743 | trans = btrfs_join_transaction(root); |
| 1742 | BUG_ON(IS_ERR(trans)); | 1744 | BUG_ON(IS_ERR(trans)); |
| 1743 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1745 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
| 1744 | ret = btrfs_update_inode(trans, root, inode); | 1746 | ret = btrfs_update_inode_fallback(trans, root, inode); |
| 1745 | BUG_ON(ret); | 1747 | BUG_ON(ret); |
| 1746 | } | 1748 | } |
| 1747 | goto out; | 1749 | goto out; |
| @@ -1791,7 +1793,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
| 1791 | 1793 | ||
| 1792 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1794 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
| 1793 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { | 1795 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { |
| 1794 | ret = btrfs_update_inode(trans, root, inode); | 1796 | ret = btrfs_update_inode_fallback(trans, root, inode); |
| 1795 | BUG_ON(ret); | 1797 | BUG_ON(ret); |
| 1796 | } | 1798 | } |
| 1797 | ret = 0; | 1799 | ret = 0; |
| @@ -2199,6 +2201,9 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
| 2199 | if (ret) | 2201 | if (ret) |
| 2200 | goto out; | 2202 | goto out; |
| 2201 | } | 2203 | } |
| 2204 | /* release the path since we're done with it */ | ||
| 2205 | btrfs_release_path(path); | ||
| 2206 | |||
| 2202 | root->orphan_cleanup_state = ORPHAN_CLEANUP_DONE; | 2207 | root->orphan_cleanup_state = ORPHAN_CLEANUP_DONE; |
| 2203 | 2208 | ||
| 2204 | if (root->orphan_block_rsv) | 2209 | if (root->orphan_block_rsv) |
| @@ -2426,7 +2431,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
| 2426 | /* | 2431 | /* |
| 2427 | * copy everything in the in-memory inode into the btree. | 2432 | * copy everything in the in-memory inode into the btree. |
| 2428 | */ | 2433 | */ |
| 2429 | noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | 2434 | static noinline int btrfs_update_inode_item(struct btrfs_trans_handle *trans, |
| 2430 | struct btrfs_root *root, struct inode *inode) | 2435 | struct btrfs_root *root, struct inode *inode) |
| 2431 | { | 2436 | { |
| 2432 | struct btrfs_inode_item *inode_item; | 2437 | struct btrfs_inode_item *inode_item; |
| @@ -2434,21 +2439,6 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
| 2434 | struct extent_buffer *leaf; | 2439 | struct extent_buffer *leaf; |
| 2435 | int ret; | 2440 | int ret; |
| 2436 | 2441 | ||
| 2437 | /* | ||
| 2438 | * If the inode is a free space inode, we can deadlock during commit | ||
| 2439 | * if we put it into the delayed code. | ||
| 2440 | * | ||
| 2441 | * The data relocation inode should also be directly updated | ||
| 2442 | * without delay | ||
| 2443 | */ | ||
| 2444 | if (!btrfs_is_free_space_inode(root, inode) | ||
| 2445 | && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) { | ||
| 2446 | ret = btrfs_delayed_update_inode(trans, root, inode); | ||
| 2447 | if (!ret) | ||
| 2448 | btrfs_set_inode_last_trans(trans, inode); | ||
| 2449 | return ret; | ||
| 2450 | } | ||
| 2451 | |||
| 2452 | path = btrfs_alloc_path(); | 2442 | path = btrfs_alloc_path(); |
| 2453 | if (!path) | 2443 | if (!path) |
| 2454 | return -ENOMEM; | 2444 | return -ENOMEM; |
| @@ -2477,6 +2467,43 @@ failed: | |||
| 2477 | } | 2467 | } |
| 2478 | 2468 | ||
| 2479 | /* | 2469 | /* |
| 2470 | * copy everything in the in-memory inode into the btree. | ||
| 2471 | */ | ||
| 2472 | noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | ||
| 2473 | struct btrfs_root *root, struct inode *inode) | ||
| 2474 | { | ||
| 2475 | int ret; | ||
| 2476 | |||
| 2477 | /* | ||
| 2478 | * If the inode is a free space inode, we can deadlock during commit | ||
| 2479 | * if we put it into the delayed code. | ||
| 2480 | * | ||
| 2481 | * The data relocation inode should also be directly updated | ||
| 2482 | * without delay | ||
| 2483 | */ | ||
| 2484 | if (!btrfs_is_free_space_inode(root, inode) | ||
| 2485 | && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) { | ||
| 2486 | ret = btrfs_delayed_update_inode(trans, root, inode); | ||
| 2487 | if (!ret) | ||
| 2488 | btrfs_set_inode_last_trans(trans, inode); | ||
| 2489 | return ret; | ||
| 2490 | } | ||
| 2491 | |||
| 2492 | return btrfs_update_inode_item(trans, root, inode); | ||
| 2493 | } | ||
| 2494 | |||
| 2495 | static noinline int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans, | ||
| 2496 | struct btrfs_root *root, struct inode *inode) | ||
| 2497 | { | ||
| 2498 | int ret; | ||
| 2499 | |||
| 2500 | ret = btrfs_update_inode(trans, root, inode); | ||
| 2501 | if (ret == -ENOSPC) | ||
| 2502 | return btrfs_update_inode_item(trans, root, inode); | ||
| 2503 | return ret; | ||
| 2504 | } | ||
| 2505 | |||
| 2506 | /* | ||
| 2480 | * unlink helper that gets used here in inode.c and in the tree logging | 2507 | * unlink helper that gets used here in inode.c and in the tree logging |
| 2481 | * recovery code. It remove a link in a directory with a given name, and | 2508 | * recovery code. It remove a link in a directory with a given name, and |
| 2482 | * also drops the back refs in the inode to the directory | 2509 | * also drops the back refs in the inode to the directory |
| @@ -5632,7 +5659,7 @@ again: | |||
| 5632 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) { | 5659 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) { |
| 5633 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); | 5660 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
| 5634 | if (!ret) | 5661 | if (!ret) |
| 5635 | err = btrfs_update_inode(trans, root, inode); | 5662 | err = btrfs_update_inode_fallback(trans, root, inode); |
| 5636 | goto out; | 5663 | goto out; |
| 5637 | } | 5664 | } |
| 5638 | 5665 | ||
| @@ -5670,7 +5697,7 @@ again: | |||
| 5670 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); | 5697 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); |
| 5671 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); | 5698 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
| 5672 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) | 5699 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) |
| 5673 | btrfs_update_inode(trans, root, inode); | 5700 | btrfs_update_inode_fallback(trans, root, inode); |
| 5674 | ret = 0; | 5701 | ret = 0; |
| 5675 | out_unlock: | 5702 | out_unlock: |
| 5676 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, | 5703 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, |
| @@ -6529,14 +6556,16 @@ end_trans: | |||
| 6529 | ret = btrfs_orphan_del(NULL, inode); | 6556 | ret = btrfs_orphan_del(NULL, inode); |
| 6530 | } | 6557 | } |
| 6531 | 6558 | ||
| 6532 | trans->block_rsv = &root->fs_info->trans_block_rsv; | 6559 | if (trans) { |
| 6533 | ret = btrfs_update_inode(trans, root, inode); | 6560 | trans->block_rsv = &root->fs_info->trans_block_rsv; |
| 6534 | if (ret && !err) | 6561 | ret = btrfs_update_inode(trans, root, inode); |
| 6535 | err = ret; | 6562 | if (ret && !err) |
| 6563 | err = ret; | ||
| 6536 | 6564 | ||
| 6537 | nr = trans->blocks_used; | 6565 | nr = trans->blocks_used; |
| 6538 | ret = btrfs_end_transaction_throttle(trans, root); | 6566 | ret = btrfs_end_transaction_throttle(trans, root); |
| 6539 | btrfs_btree_balance_dirty(root, nr); | 6567 | btrfs_btree_balance_dirty(root, nr); |
| 6568 | } | ||
| 6540 | 6569 | ||
| 6541 | out: | 6570 | out: |
| 6542 | btrfs_free_block_rsv(root, rsv); | 6571 | btrfs_free_block_rsv(root, rsv); |
| @@ -6605,6 +6634,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
| 6605 | ei->orphan_meta_reserved = 0; | 6634 | ei->orphan_meta_reserved = 0; |
| 6606 | ei->dummy_inode = 0; | 6635 | ei->dummy_inode = 0; |
| 6607 | ei->in_defrag = 0; | 6636 | ei->in_defrag = 0; |
| 6637 | ei->delalloc_meta_reserved = 0; | ||
| 6608 | ei->force_compress = BTRFS_COMPRESS_NONE; | 6638 | ei->force_compress = BTRFS_COMPRESS_NONE; |
| 6609 | 6639 | ||
| 6610 | ei->delayed_node = NULL; | 6640 | ei->delayed_node = NULL; |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 24d654ce7a06..dff29d5e151a 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -1174,6 +1174,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, | |||
| 1174 | list_add_tail(&new_edge->list[UPPER], | 1174 | list_add_tail(&new_edge->list[UPPER], |
| 1175 | &new_node->lower); | 1175 | &new_node->lower); |
| 1176 | } | 1176 | } |
| 1177 | } else { | ||
| 1178 | list_add_tail(&new_node->lower, &cache->leaves); | ||
| 1177 | } | 1179 | } |
| 1178 | 1180 | ||
| 1179 | rb_node = tree_insert(&cache->rb_root, new_node->bytenr, | 1181 | rb_node = tree_insert(&cache->rb_root, new_node->bytenr, |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index ed11d3866afd..f4190f22edfb 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
| @@ -944,50 +944,18 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer) | |||
| 944 | static int scrub_submit(struct scrub_dev *sdev) | 944 | static int scrub_submit(struct scrub_dev *sdev) |
| 945 | { | 945 | { |
| 946 | struct scrub_bio *sbio; | 946 | struct scrub_bio *sbio; |
| 947 | struct bio *bio; | ||
| 948 | int i; | ||
| 949 | 947 | ||
| 950 | if (sdev->curr == -1) | 948 | if (sdev->curr == -1) |
| 951 | return 0; | 949 | return 0; |
| 952 | 950 | ||
| 953 | sbio = sdev->bios[sdev->curr]; | 951 | sbio = sdev->bios[sdev->curr]; |
| 954 | |||
| 955 | bio = bio_alloc(GFP_NOFS, sbio->count); | ||
| 956 | if (!bio) | ||
| 957 | goto nomem; | ||
| 958 | |||
| 959 | bio->bi_private = sbio; | ||
| 960 | bio->bi_end_io = scrub_bio_end_io; | ||
| 961 | bio->bi_bdev = sdev->dev->bdev; | ||
| 962 | bio->bi_sector = sbio->physical >> 9; | ||
| 963 | |||
| 964 | for (i = 0; i < sbio->count; ++i) { | ||
| 965 | struct page *page; | ||
| 966 | int ret; | ||
| 967 | |||
| 968 | page = alloc_page(GFP_NOFS); | ||
| 969 | if (!page) | ||
| 970 | goto nomem; | ||
| 971 | |||
| 972 | ret = bio_add_page(bio, page, PAGE_SIZE, 0); | ||
| 973 | if (!ret) { | ||
| 974 | __free_page(page); | ||
| 975 | goto nomem; | ||
| 976 | } | ||
| 977 | } | ||
| 978 | |||
| 979 | sbio->err = 0; | 952 | sbio->err = 0; |
| 980 | sdev->curr = -1; | 953 | sdev->curr = -1; |
| 981 | atomic_inc(&sdev->in_flight); | 954 | atomic_inc(&sdev->in_flight); |
| 982 | 955 | ||
| 983 | submit_bio(READ, bio); | 956 | submit_bio(READ, sbio->bio); |
| 984 | 957 | ||
| 985 | return 0; | 958 | return 0; |
| 986 | |||
| 987 | nomem: | ||
| 988 | scrub_free_bio(bio); | ||
| 989 | |||
| 990 | return -ENOMEM; | ||
| 991 | } | 959 | } |
| 992 | 960 | ||
| 993 | static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, | 961 | static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, |
| @@ -995,6 +963,8 @@ static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, | |||
| 995 | u8 *csum, int force) | 963 | u8 *csum, int force) |
| 996 | { | 964 | { |
| 997 | struct scrub_bio *sbio; | 965 | struct scrub_bio *sbio; |
| 966 | struct page *page; | ||
| 967 | int ret; | ||
| 998 | 968 | ||
| 999 | again: | 969 | again: |
| 1000 | /* | 970 | /* |
| @@ -1015,12 +985,22 @@ again: | |||
| 1015 | } | 985 | } |
| 1016 | sbio = sdev->bios[sdev->curr]; | 986 | sbio = sdev->bios[sdev->curr]; |
| 1017 | if (sbio->count == 0) { | 987 | if (sbio->count == 0) { |
| 988 | struct bio *bio; | ||
| 989 | |||
| 1018 | sbio->physical = physical; | 990 | sbio->physical = physical; |
| 1019 | sbio->logical = logical; | 991 | sbio->logical = logical; |
| 992 | bio = bio_alloc(GFP_NOFS, SCRUB_PAGES_PER_BIO); | ||
| 993 | if (!bio) | ||
| 994 | return -ENOMEM; | ||
| 995 | |||
| 996 | bio->bi_private = sbio; | ||
| 997 | bio->bi_end_io = scrub_bio_end_io; | ||
| 998 | bio->bi_bdev = sdev->dev->bdev; | ||
| 999 | bio->bi_sector = sbio->physical >> 9; | ||
| 1000 | sbio->err = 0; | ||
| 1001 | sbio->bio = bio; | ||
| 1020 | } else if (sbio->physical + sbio->count * PAGE_SIZE != physical || | 1002 | } else if (sbio->physical + sbio->count * PAGE_SIZE != physical || |
| 1021 | sbio->logical + sbio->count * PAGE_SIZE != logical) { | 1003 | sbio->logical + sbio->count * PAGE_SIZE != logical) { |
| 1022 | int ret; | ||
| 1023 | |||
| 1024 | ret = scrub_submit(sdev); | 1004 | ret = scrub_submit(sdev); |
| 1025 | if (ret) | 1005 | if (ret) |
| 1026 | return ret; | 1006 | return ret; |
| @@ -1030,6 +1010,20 @@ again: | |||
| 1030 | sbio->spag[sbio->count].generation = gen; | 1010 | sbio->spag[sbio->count].generation = gen; |
| 1031 | sbio->spag[sbio->count].have_csum = 0; | 1011 | sbio->spag[sbio->count].have_csum = 0; |
| 1032 | sbio->spag[sbio->count].mirror_num = mirror_num; | 1012 | sbio->spag[sbio->count].mirror_num = mirror_num; |
| 1013 | |||
| 1014 | page = alloc_page(GFP_NOFS); | ||
| 1015 | if (!page) | ||
| 1016 | return -ENOMEM; | ||
| 1017 | |||
| 1018 | ret = bio_add_page(sbio->bio, page, PAGE_SIZE, 0); | ||
| 1019 | if (!ret) { | ||
| 1020 | __free_page(page); | ||
| 1021 | ret = scrub_submit(sdev); | ||
| 1022 | if (ret) | ||
| 1023 | return ret; | ||
| 1024 | goto again; | ||
| 1025 | } | ||
| 1026 | |||
| 1033 | if (csum) { | 1027 | if (csum) { |
| 1034 | sbio->spag[sbio->count].have_csum = 1; | 1028 | sbio->spag[sbio->count].have_csum = 1; |
| 1035 | memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size); | 1029 | memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 57080dffdfc6..8bd9d6d0e07a 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -197,7 +197,7 @@ static match_table_t tokens = { | |||
| 197 | {Opt_subvolrootid, "subvolrootid=%d"}, | 197 | {Opt_subvolrootid, "subvolrootid=%d"}, |
| 198 | {Opt_defrag, "autodefrag"}, | 198 | {Opt_defrag, "autodefrag"}, |
| 199 | {Opt_inode_cache, "inode_cache"}, | 199 | {Opt_inode_cache, "inode_cache"}, |
| 200 | {Opt_no_space_cache, "no_space_cache"}, | 200 | {Opt_no_space_cache, "nospace_cache"}, |
| 201 | {Opt_recovery, "recovery"}, | 201 | {Opt_recovery, "recovery"}, |
| 202 | {Opt_err, NULL}, | 202 | {Opt_err, NULL}, |
| 203 | }; | 203 | }; |
| @@ -448,6 +448,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
| 448 | token = match_token(p, tokens, args); | 448 | token = match_token(p, tokens, args); |
| 449 | switch (token) { | 449 | switch (token) { |
| 450 | case Opt_subvol: | 450 | case Opt_subvol: |
| 451 | kfree(*subvol_name); | ||
| 451 | *subvol_name = match_strdup(&args[0]); | 452 | *subvol_name = match_strdup(&args[0]); |
| 452 | break; | 453 | break; |
| 453 | case Opt_subvolid: | 454 | case Opt_subvolid: |
| @@ -710,7 +711,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 710 | if (btrfs_test_opt(root, SPACE_CACHE)) | 711 | if (btrfs_test_opt(root, SPACE_CACHE)) |
| 711 | seq_puts(seq, ",space_cache"); | 712 | seq_puts(seq, ",space_cache"); |
| 712 | else | 713 | else |
| 713 | seq_puts(seq, ",no_space_cache"); | 714 | seq_puts(seq, ",nospace_cache"); |
| 714 | if (btrfs_test_opt(root, CLEAR_CACHE)) | 715 | if (btrfs_test_opt(root, CLEAR_CACHE)) |
| 715 | seq_puts(seq, ",clear_cache"); | 716 | seq_puts(seq, ",clear_cache"); |
| 716 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | 717 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) |
| @@ -890,7 +891,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 890 | struct super_block *s; | 891 | struct super_block *s; |
| 891 | struct dentry *root; | 892 | struct dentry *root; |
| 892 | struct btrfs_fs_devices *fs_devices = NULL; | 893 | struct btrfs_fs_devices *fs_devices = NULL; |
| 893 | struct btrfs_root *tree_root = NULL; | ||
| 894 | struct btrfs_fs_info *fs_info = NULL; | 894 | struct btrfs_fs_info *fs_info = NULL; |
| 895 | fmode_t mode = FMODE_READ; | 895 | fmode_t mode = FMODE_READ; |
| 896 | char *subvol_name = NULL; | 896 | char *subvol_name = NULL; |
| @@ -904,8 +904,10 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 904 | error = btrfs_parse_early_options(data, mode, fs_type, | 904 | error = btrfs_parse_early_options(data, mode, fs_type, |
| 905 | &subvol_name, &subvol_objectid, | 905 | &subvol_name, &subvol_objectid, |
| 906 | &subvol_rootid, &fs_devices); | 906 | &subvol_rootid, &fs_devices); |
| 907 | if (error) | 907 | if (error) { |
| 908 | kfree(subvol_name); | ||
| 908 | return ERR_PTR(error); | 909 | return ERR_PTR(error); |
| 910 | } | ||
| 909 | 911 | ||
| 910 | if (subvol_name) { | 912 | if (subvol_name) { |
| 911 | root = mount_subvol(subvol_name, flags, device_name, data); | 913 | root = mount_subvol(subvol_name, flags, device_name, data); |
| @@ -917,15 +919,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 917 | if (error) | 919 | if (error) |
| 918 | return ERR_PTR(error); | 920 | return ERR_PTR(error); |
| 919 | 921 | ||
| 920 | error = btrfs_open_devices(fs_devices, mode, fs_type); | ||
| 921 | if (error) | ||
| 922 | return ERR_PTR(error); | ||
| 923 | |||
| 924 | if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { | ||
| 925 | error = -EACCES; | ||
| 926 | goto error_close_devices; | ||
| 927 | } | ||
| 928 | |||
| 929 | /* | 922 | /* |
| 930 | * Setup a dummy root and fs_info for test/set super. This is because | 923 | * Setup a dummy root and fs_info for test/set super. This is because |
| 931 | * we don't actually fill this stuff out until open_ctree, but we need | 924 | * we don't actually fill this stuff out until open_ctree, but we need |
| @@ -933,24 +926,36 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 933 | * then open_ctree will properly initialize everything later. | 926 | * then open_ctree will properly initialize everything later. |
| 934 | */ | 927 | */ |
| 935 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); | 928 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); |
| 936 | tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | 929 | if (!fs_info) |
| 937 | if (!fs_info || !tree_root) { | 930 | return ERR_PTR(-ENOMEM); |
| 931 | |||
| 932 | fs_info->tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 933 | if (!fs_info->tree_root) { | ||
| 938 | error = -ENOMEM; | 934 | error = -ENOMEM; |
| 939 | goto error_close_devices; | 935 | goto error_fs_info; |
| 940 | } | 936 | } |
| 941 | fs_info->tree_root = tree_root; | 937 | fs_info->tree_root->fs_info = fs_info; |
| 942 | fs_info->fs_devices = fs_devices; | 938 | fs_info->fs_devices = fs_devices; |
| 943 | tree_root->fs_info = fs_info; | ||
| 944 | 939 | ||
| 945 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 940 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
| 946 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 941 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
| 947 | if (!fs_info->super_copy || !fs_info->super_for_commit) { | 942 | if (!fs_info->super_copy || !fs_info->super_for_commit) { |
| 948 | error = -ENOMEM; | 943 | error = -ENOMEM; |
| 944 | goto error_fs_info; | ||
| 945 | } | ||
| 946 | |||
| 947 | error = btrfs_open_devices(fs_devices, mode, fs_type); | ||
| 948 | if (error) | ||
| 949 | goto error_fs_info; | ||
| 950 | |||
| 951 | if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { | ||
| 952 | error = -EACCES; | ||
| 949 | goto error_close_devices; | 953 | goto error_close_devices; |
| 950 | } | 954 | } |
| 951 | 955 | ||
| 952 | bdev = fs_devices->latest_bdev; | 956 | bdev = fs_devices->latest_bdev; |
| 953 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); | 957 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, |
| 958 | fs_info->tree_root); | ||
| 954 | if (IS_ERR(s)) { | 959 | if (IS_ERR(s)) { |
| 955 | error = PTR_ERR(s); | 960 | error = PTR_ERR(s); |
| 956 | goto error_close_devices; | 961 | goto error_close_devices; |
| @@ -959,12 +964,12 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 959 | if (s->s_root) { | 964 | if (s->s_root) { |
| 960 | if ((flags ^ s->s_flags) & MS_RDONLY) { | 965 | if ((flags ^ s->s_flags) & MS_RDONLY) { |
| 961 | deactivate_locked_super(s); | 966 | deactivate_locked_super(s); |
| 962 | return ERR_PTR(-EBUSY); | 967 | error = -EBUSY; |
| 968 | goto error_close_devices; | ||
| 963 | } | 969 | } |
| 964 | 970 | ||
| 965 | btrfs_close_devices(fs_devices); | 971 | btrfs_close_devices(fs_devices); |
| 966 | free_fs_info(fs_info); | 972 | free_fs_info(fs_info); |
| 967 | kfree(tree_root); | ||
| 968 | } else { | 973 | } else { |
| 969 | char b[BDEVNAME_SIZE]; | 974 | char b[BDEVNAME_SIZE]; |
| 970 | 975 | ||
| @@ -991,8 +996,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 991 | 996 | ||
| 992 | error_close_devices: | 997 | error_close_devices: |
| 993 | btrfs_close_devices(fs_devices); | 998 | btrfs_close_devices(fs_devices); |
| 999 | error_fs_info: | ||
| 994 | free_fs_info(fs_info); | 1000 | free_fs_info(fs_info); |
| 995 | kfree(tree_root); | ||
| 996 | return ERR_PTR(error); | 1001 | return ERR_PTR(error); |
| 997 | } | 1002 | } |
| 998 | 1003 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 960835eaf4da..6a0574e923bc 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -882,8 +882,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 882 | btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); | 882 | btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); |
| 883 | 883 | ||
| 884 | if (to_reserve > 0) { | 884 | if (to_reserve > 0) { |
| 885 | ret = btrfs_block_rsv_add(root, &pending->block_rsv, | 885 | ret = btrfs_block_rsv_add_noflush(root, &pending->block_rsv, |
| 886 | to_reserve); | 886 | to_reserve); |
| 887 | if (ret) { | 887 | if (ret) { |
| 888 | pending->error = ret; | 888 | pending->error = ret; |
| 889 | goto fail; | 889 | goto fail; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f8e2943101a1..c37433d3cd82 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -999,7 +999,7 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, | |||
| 999 | key.objectid = device->devid; | 999 | key.objectid = device->devid; |
| 1000 | key.offset = start; | 1000 | key.offset = start; |
| 1001 | key.type = BTRFS_DEV_EXTENT_KEY; | 1001 | key.type = BTRFS_DEV_EXTENT_KEY; |
| 1002 | 1002 | again: | |
| 1003 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 1003 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| 1004 | if (ret > 0) { | 1004 | if (ret > 0) { |
| 1005 | ret = btrfs_previous_item(root, path, key.objectid, | 1005 | ret = btrfs_previous_item(root, path, key.objectid, |
| @@ -1012,6 +1012,9 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, | |||
| 1012 | struct btrfs_dev_extent); | 1012 | struct btrfs_dev_extent); |
| 1013 | BUG_ON(found_key.offset > start || found_key.offset + | 1013 | BUG_ON(found_key.offset > start || found_key.offset + |
| 1014 | btrfs_dev_extent_length(leaf, extent) < start); | 1014 | btrfs_dev_extent_length(leaf, extent) < start); |
| 1015 | key = found_key; | ||
| 1016 | btrfs_release_path(path); | ||
| 1017 | goto again; | ||
| 1015 | } else if (ret == 0) { | 1018 | } else if (ret == 0) { |
| 1016 | leaf = path->nodes[0]; | 1019 | leaf = path->nodes[0]; |
| 1017 | extent = btrfs_item_ptr(leaf, path->slots[0], | 1020 | extent = btrfs_item_ptr(leaf, path->slots[0], |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 2db1bd3173b2..851ba3dcdc29 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -1652,46 +1652,12 @@ out: | |||
| 1652 | return error; | 1652 | return error; |
| 1653 | } | 1653 | } |
| 1654 | 1654 | ||
| 1655 | static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
| 1656 | struct kstat *stat) | ||
| 1657 | { | ||
| 1658 | struct inode *inode = dentry->d_inode; | ||
| 1659 | struct task_struct *task = get_proc_task(inode); | ||
| 1660 | int rc; | ||
| 1661 | |||
| 1662 | if (task == NULL) | ||
| 1663 | return -ESRCH; | ||
| 1664 | |||
| 1665 | rc = -EACCES; | ||
| 1666 | if (lock_trace(task)) | ||
| 1667 | goto out_task; | ||
| 1668 | |||
| 1669 | generic_fillattr(inode, stat); | ||
| 1670 | unlock_trace(task); | ||
| 1671 | rc = 0; | ||
| 1672 | out_task: | ||
| 1673 | put_task_struct(task); | ||
| 1674 | return rc; | ||
| 1675 | } | ||
| 1676 | |||
| 1677 | static const struct inode_operations proc_pid_link_inode_operations = { | 1655 | static const struct inode_operations proc_pid_link_inode_operations = { |
| 1678 | .readlink = proc_pid_readlink, | 1656 | .readlink = proc_pid_readlink, |
| 1679 | .follow_link = proc_pid_follow_link, | 1657 | .follow_link = proc_pid_follow_link, |
| 1680 | .setattr = proc_setattr, | 1658 | .setattr = proc_setattr, |
| 1681 | }; | 1659 | }; |
| 1682 | 1660 | ||
| 1683 | static const struct inode_operations proc_fdinfo_link_inode_operations = { | ||
| 1684 | .setattr = proc_setattr, | ||
| 1685 | .getattr = proc_pid_fd_link_getattr, | ||
| 1686 | }; | ||
| 1687 | |||
| 1688 | static const struct inode_operations proc_fd_link_inode_operations = { | ||
| 1689 | .readlink = proc_pid_readlink, | ||
| 1690 | .follow_link = proc_pid_follow_link, | ||
| 1691 | .setattr = proc_setattr, | ||
| 1692 | .getattr = proc_pid_fd_link_getattr, | ||
| 1693 | }; | ||
| 1694 | |||
| 1695 | 1661 | ||
| 1696 | /* building an inode */ | 1662 | /* building an inode */ |
| 1697 | 1663 | ||
| @@ -1923,61 +1889,49 @@ out: | |||
| 1923 | 1889 | ||
| 1924 | static int proc_fd_info(struct inode *inode, struct path *path, char *info) | 1890 | static int proc_fd_info(struct inode *inode, struct path *path, char *info) |
| 1925 | { | 1891 | { |
| 1926 | struct task_struct *task; | 1892 | struct task_struct *task = get_proc_task(inode); |
| 1927 | struct files_struct *files; | 1893 | struct files_struct *files = NULL; |
| 1928 | struct file *file; | 1894 | struct file *file; |
| 1929 | int fd = proc_fd(inode); | 1895 | int fd = proc_fd(inode); |
| 1930 | int rc; | ||
| 1931 | |||
| 1932 | task = get_proc_task(inode); | ||
| 1933 | if (!task) | ||
| 1934 | return -ENOENT; | ||
| 1935 | |||
| 1936 | rc = -EACCES; | ||
| 1937 | if (lock_trace(task)) | ||
| 1938 | goto out_task; | ||
| 1939 | |||
| 1940 | rc = -ENOENT; | ||
| 1941 | files = get_files_struct(task); | ||
| 1942 | if (files == NULL) | ||
| 1943 | goto out_unlock; | ||
| 1944 | 1896 | ||
| 1945 | /* | 1897 | if (task) { |
| 1946 | * We are not taking a ref to the file structure, so we must | 1898 | files = get_files_struct(task); |
| 1947 | * hold ->file_lock. | 1899 | put_task_struct(task); |
| 1948 | */ | 1900 | } |
| 1949 | spin_lock(&files->file_lock); | 1901 | if (files) { |
| 1950 | file = fcheck_files(files, fd); | 1902 | /* |
| 1951 | if (file) { | 1903 | * We are not taking a ref to the file structure, so we must |
| 1952 | unsigned int f_flags; | 1904 | * hold ->file_lock. |
| 1953 | struct fdtable *fdt; | 1905 | */ |
| 1954 | 1906 | spin_lock(&files->file_lock); | |
| 1955 | fdt = files_fdtable(files); | 1907 | file = fcheck_files(files, fd); |
| 1956 | f_flags = file->f_flags & ~O_CLOEXEC; | 1908 | if (file) { |
| 1957 | if (FD_ISSET(fd, fdt->close_on_exec)) | 1909 | unsigned int f_flags; |
| 1958 | f_flags |= O_CLOEXEC; | 1910 | struct fdtable *fdt; |
| 1959 | 1911 | ||
| 1960 | if (path) { | 1912 | fdt = files_fdtable(files); |
| 1961 | *path = file->f_path; | 1913 | f_flags = file->f_flags & ~O_CLOEXEC; |
| 1962 | path_get(&file->f_path); | 1914 | if (FD_ISSET(fd, fdt->close_on_exec)) |
| 1915 | f_flags |= O_CLOEXEC; | ||
| 1916 | |||
| 1917 | if (path) { | ||
| 1918 | *path = file->f_path; | ||
| 1919 | path_get(&file->f_path); | ||
| 1920 | } | ||
| 1921 | if (info) | ||
| 1922 | snprintf(info, PROC_FDINFO_MAX, | ||
| 1923 | "pos:\t%lli\n" | ||
| 1924 | "flags:\t0%o\n", | ||
| 1925 | (long long) file->f_pos, | ||
| 1926 | f_flags); | ||
| 1927 | spin_unlock(&files->file_lock); | ||
| 1928 | put_files_struct(files); | ||
| 1929 | return 0; | ||
| 1963 | } | 1930 | } |
| 1964 | if (info) | 1931 | spin_unlock(&files->file_lock); |
| 1965 | snprintf(info, PROC_FDINFO_MAX, | 1932 | put_files_struct(files); |
| 1966 | "pos:\t%lli\n" | 1933 | } |
| 1967 | "flags:\t0%o\n", | 1934 | return -ENOENT; |
| 1968 | (long long) file->f_pos, | ||
| 1969 | f_flags); | ||
| 1970 | rc = 0; | ||
| 1971 | } else | ||
| 1972 | rc = -ENOENT; | ||
| 1973 | spin_unlock(&files->file_lock); | ||
| 1974 | put_files_struct(files); | ||
| 1975 | |||
| 1976 | out_unlock: | ||
| 1977 | unlock_trace(task); | ||
| 1978 | out_task: | ||
| 1979 | put_task_struct(task); | ||
| 1980 | return rc; | ||
| 1981 | } | 1935 | } |
| 1982 | 1936 | ||
| 1983 | static int proc_fd_link(struct inode *inode, struct path *path) | 1937 | static int proc_fd_link(struct inode *inode, struct path *path) |
| @@ -2072,7 +2026,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, | |||
| 2072 | spin_unlock(&files->file_lock); | 2026 | spin_unlock(&files->file_lock); |
| 2073 | put_files_struct(files); | 2027 | put_files_struct(files); |
| 2074 | 2028 | ||
| 2075 | inode->i_op = &proc_fd_link_inode_operations; | 2029 | inode->i_op = &proc_pid_link_inode_operations; |
| 2076 | inode->i_size = 64; | 2030 | inode->i_size = 64; |
| 2077 | ei->op.proc_get_link = proc_fd_link; | 2031 | ei->op.proc_get_link = proc_fd_link; |
| 2078 | d_set_d_op(dentry, &tid_fd_dentry_operations); | 2032 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
| @@ -2104,12 +2058,7 @@ static struct dentry *proc_lookupfd_common(struct inode *dir, | |||
| 2104 | if (fd == ~0U) | 2058 | if (fd == ~0U) |
| 2105 | goto out; | 2059 | goto out; |
| 2106 | 2060 | ||
| 2107 | result = ERR_PTR(-EACCES); | ||
| 2108 | if (lock_trace(task)) | ||
| 2109 | goto out; | ||
| 2110 | |||
| 2111 | result = instantiate(dir, dentry, task, &fd); | 2061 | result = instantiate(dir, dentry, task, &fd); |
| 2112 | unlock_trace(task); | ||
| 2113 | out: | 2062 | out: |
| 2114 | put_task_struct(task); | 2063 | put_task_struct(task); |
| 2115 | out_no_task: | 2064 | out_no_task: |
| @@ -2129,28 +2078,23 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
| 2129 | retval = -ENOENT; | 2078 | retval = -ENOENT; |
| 2130 | if (!p) | 2079 | if (!p) |
| 2131 | goto out_no_task; | 2080 | goto out_no_task; |
| 2132 | |||
| 2133 | retval = -EACCES; | ||
| 2134 | if (lock_trace(p)) | ||
| 2135 | goto out; | ||
| 2136 | |||
| 2137 | retval = 0; | 2081 | retval = 0; |
| 2138 | 2082 | ||
| 2139 | fd = filp->f_pos; | 2083 | fd = filp->f_pos; |
| 2140 | switch (fd) { | 2084 | switch (fd) { |
| 2141 | case 0: | 2085 | case 0: |
| 2142 | if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) | 2086 | if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) |
| 2143 | goto out_unlock; | 2087 | goto out; |
| 2144 | filp->f_pos++; | 2088 | filp->f_pos++; |
| 2145 | case 1: | 2089 | case 1: |
| 2146 | ino = parent_ino(dentry); | 2090 | ino = parent_ino(dentry); |
| 2147 | if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) | 2091 | if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) |
| 2148 | goto out_unlock; | 2092 | goto out; |
| 2149 | filp->f_pos++; | 2093 | filp->f_pos++; |
| 2150 | default: | 2094 | default: |
| 2151 | files = get_files_struct(p); | 2095 | files = get_files_struct(p); |
| 2152 | if (!files) | 2096 | if (!files) |
| 2153 | goto out_unlock; | 2097 | goto out; |
| 2154 | rcu_read_lock(); | 2098 | rcu_read_lock(); |
| 2155 | for (fd = filp->f_pos-2; | 2099 | for (fd = filp->f_pos-2; |
| 2156 | fd < files_fdtable(files)->max_fds; | 2100 | fd < files_fdtable(files)->max_fds; |
| @@ -2174,9 +2118,6 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
| 2174 | rcu_read_unlock(); | 2118 | rcu_read_unlock(); |
| 2175 | put_files_struct(files); | 2119 | put_files_struct(files); |
| 2176 | } | 2120 | } |
| 2177 | |||
| 2178 | out_unlock: | ||
| 2179 | unlock_trace(p); | ||
| 2180 | out: | 2121 | out: |
| 2181 | put_task_struct(p); | 2122 | put_task_struct(p); |
| 2182 | out_no_task: | 2123 | out_no_task: |
| @@ -2254,7 +2195,6 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir, | |||
| 2254 | ei->fd = fd; | 2195 | ei->fd = fd; |
| 2255 | inode->i_mode = S_IFREG | S_IRUSR; | 2196 | inode->i_mode = S_IFREG | S_IRUSR; |
| 2256 | inode->i_fop = &proc_fdinfo_file_operations; | 2197 | inode->i_fop = &proc_fdinfo_file_operations; |
| 2257 | inode->i_op = &proc_fdinfo_link_inode_operations; | ||
| 2258 | d_set_d_op(dentry, &tid_fd_dentry_operations); | 2198 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
| 2259 | d_add(dentry, inode); | 2199 | d_add(dentry, inode); |
| 2260 | /* Close the race of the process dying before we return the dentry */ | 2200 | /* Close the race of the process dying before we return the dentry */ |
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 33b13310ee0c..574d4ee9b625 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
| @@ -189,7 +189,7 @@ xfs_end_io( | |||
| 189 | int error = 0; | 189 | int error = 0; |
| 190 | 190 | ||
| 191 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 191 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
| 192 | error = -EIO; | 192 | ioend->io_error = -EIO; |
| 193 | goto done; | 193 | goto done; |
| 194 | } | 194 | } |
| 195 | if (ioend->io_error) | 195 | if (ioend->io_error) |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 1a3513881bce..eac97ef81e2a 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -656,7 +656,7 @@ xfs_buf_item_committing( | |||
| 656 | /* | 656 | /* |
| 657 | * This is the ops vector shared by all buf log items. | 657 | * This is the ops vector shared by all buf log items. |
| 658 | */ | 658 | */ |
| 659 | static struct xfs_item_ops xfs_buf_item_ops = { | 659 | static const struct xfs_item_ops xfs_buf_item_ops = { |
| 660 | .iop_size = xfs_buf_item_size, | 660 | .iop_size = xfs_buf_item_size, |
| 661 | .iop_format = xfs_buf_item_format, | 661 | .iop_format = xfs_buf_item_format, |
| 662 | .iop_pin = xfs_buf_item_pin, | 662 | .iop_pin = xfs_buf_item_pin, |
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index bb3f71d236d2..0dee0b71029d 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c | |||
| @@ -295,7 +295,7 @@ xfs_qm_dquot_logitem_committing( | |||
| 295 | /* | 295 | /* |
| 296 | * This is the ops vector for dquots | 296 | * This is the ops vector for dquots |
| 297 | */ | 297 | */ |
| 298 | static struct xfs_item_ops xfs_dquot_item_ops = { | 298 | static const struct xfs_item_ops xfs_dquot_item_ops = { |
| 299 | .iop_size = xfs_qm_dquot_logitem_size, | 299 | .iop_size = xfs_qm_dquot_logitem_size, |
| 300 | .iop_format = xfs_qm_dquot_logitem_format, | 300 | .iop_format = xfs_qm_dquot_logitem_format, |
| 301 | .iop_pin = xfs_qm_dquot_logitem_pin, | 301 | .iop_pin = xfs_qm_dquot_logitem_pin, |
| @@ -483,7 +483,7 @@ xfs_qm_qoff_logitem_committing( | |||
| 483 | { | 483 | { |
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { | 486 | static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { |
| 487 | .iop_size = xfs_qm_qoff_logitem_size, | 487 | .iop_size = xfs_qm_qoff_logitem_size, |
| 488 | .iop_format = xfs_qm_qoff_logitem_format, | 488 | .iop_format = xfs_qm_qoff_logitem_format, |
| 489 | .iop_pin = xfs_qm_qoff_logitem_pin, | 489 | .iop_pin = xfs_qm_qoff_logitem_pin, |
| @@ -498,7 +498,7 @@ static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { | |||
| 498 | /* | 498 | /* |
| 499 | * This is the ops vector shared by all quotaoff-start log items. | 499 | * This is the ops vector shared by all quotaoff-start log items. |
| 500 | */ | 500 | */ |
| 501 | static struct xfs_item_ops xfs_qm_qoff_logitem_ops = { | 501 | static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { |
| 502 | .iop_size = xfs_qm_qoff_logitem_size, | 502 | .iop_size = xfs_qm_qoff_logitem_size, |
| 503 | .iop_format = xfs_qm_qoff_logitem_format, | 503 | .iop_format = xfs_qm_qoff_logitem_format, |
| 504 | .iop_pin = xfs_qm_qoff_logitem_pin, | 504 | .iop_pin = xfs_qm_qoff_logitem_pin, |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index d22e62623437..35c2aff38b20 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
| @@ -217,7 +217,7 @@ xfs_efi_item_committing( | |||
| 217 | /* | 217 | /* |
| 218 | * This is the ops vector shared by all efi log items. | 218 | * This is the ops vector shared by all efi log items. |
| 219 | */ | 219 | */ |
| 220 | static struct xfs_item_ops xfs_efi_item_ops = { | 220 | static const struct xfs_item_ops xfs_efi_item_ops = { |
| 221 | .iop_size = xfs_efi_item_size, | 221 | .iop_size = xfs_efi_item_size, |
| 222 | .iop_format = xfs_efi_item_format, | 222 | .iop_format = xfs_efi_item_format, |
| 223 | .iop_pin = xfs_efi_item_pin, | 223 | .iop_pin = xfs_efi_item_pin, |
| @@ -477,7 +477,7 @@ xfs_efd_item_committing( | |||
| 477 | /* | 477 | /* |
| 478 | * This is the ops vector shared by all efd log items. | 478 | * This is the ops vector shared by all efd log items. |
| 479 | */ | 479 | */ |
| 480 | static struct xfs_item_ops xfs_efd_item_ops = { | 480 | static const struct xfs_item_ops xfs_efd_item_ops = { |
| 481 | .iop_size = xfs_efd_item_size, | 481 | .iop_size = xfs_efd_item_size, |
| 482 | .iop_format = xfs_efd_item_format, | 482 | .iop_format = xfs_efd_item_format, |
| 483 | .iop_pin = xfs_efd_item_pin, | 483 | .iop_pin = xfs_efd_item_pin, |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index b7cf21ba240f..abaafdbb3e65 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
| @@ -795,7 +795,7 @@ xfs_inode_item_committing( | |||
| 795 | /* | 795 | /* |
| 796 | * This is the ops vector shared by all buf log items. | 796 | * This is the ops vector shared by all buf log items. |
| 797 | */ | 797 | */ |
| 798 | static struct xfs_item_ops xfs_inode_item_ops = { | 798 | static const struct xfs_item_ops xfs_inode_item_ops = { |
| 799 | .iop_size = xfs_inode_item_size, | 799 | .iop_size = xfs_inode_item_size, |
| 800 | .iop_format = xfs_inode_item_format, | 800 | .iop_format = xfs_inode_item_format, |
| 801 | .iop_pin = xfs_inode_item_pin, | 801 | .iop_pin = xfs_inode_item_pin, |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 2758a6277c52..a14cd89fe465 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -626,7 +626,7 @@ xfs_log_item_init( | |||
| 626 | struct xfs_mount *mp, | 626 | struct xfs_mount *mp, |
| 627 | struct xfs_log_item *item, | 627 | struct xfs_log_item *item, |
| 628 | int type, | 628 | int type, |
| 629 | struct xfs_item_ops *ops) | 629 | const struct xfs_item_ops *ops) |
| 630 | { | 630 | { |
| 631 | item->li_mountp = mp; | 631 | item->li_mountp = mp; |
| 632 | item->li_ailp = mp->m_ail; | 632 | item->li_ailp = mp->m_ail; |
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 78c9039994af..3f7bf451c034 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
| @@ -137,7 +137,7 @@ struct xfs_trans; | |||
| 137 | void xfs_log_item_init(struct xfs_mount *mp, | 137 | void xfs_log_item_init(struct xfs_mount *mp, |
| 138 | struct xfs_log_item *item, | 138 | struct xfs_log_item *item, |
| 139 | int type, | 139 | int type, |
| 140 | struct xfs_item_ops *ops); | 140 | const struct xfs_item_ops *ops); |
| 141 | 141 | ||
| 142 | xfs_lsn_t xfs_log_done(struct xfs_mount *mp, | 142 | xfs_lsn_t xfs_log_done(struct xfs_mount *mp, |
| 143 | struct xlog_ticket *ticket, | 143 | struct xlog_ticket *ticket, |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 603f3eb52041..3ae713c0abd9 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
| @@ -326,7 +326,7 @@ typedef struct xfs_log_item { | |||
| 326 | struct xfs_log_item *); | 326 | struct xfs_log_item *); |
| 327 | /* buffer item iodone */ | 327 | /* buffer item iodone */ |
| 328 | /* callback func */ | 328 | /* callback func */ |
| 329 | struct xfs_item_ops *li_ops; /* function list */ | 329 | const struct xfs_item_ops *li_ops; /* function list */ |
| 330 | 330 | ||
| 331 | /* delayed logging */ | 331 | /* delayed logging */ |
| 332 | struct list_head li_cil; /* CIL pointers */ | 332 | struct list_head li_cil; /* CIL pointers */ |
| @@ -341,7 +341,7 @@ typedef struct xfs_log_item { | |||
| 341 | { XFS_LI_IN_AIL, "IN_AIL" }, \ | 341 | { XFS_LI_IN_AIL, "IN_AIL" }, \ |
| 342 | { XFS_LI_ABORTED, "ABORTED" } | 342 | { XFS_LI_ABORTED, "ABORTED" } |
| 343 | 343 | ||
| 344 | typedef struct xfs_item_ops { | 344 | struct xfs_item_ops { |
| 345 | uint (*iop_size)(xfs_log_item_t *); | 345 | uint (*iop_size)(xfs_log_item_t *); |
| 346 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); | 346 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); |
| 347 | void (*iop_pin)(xfs_log_item_t *); | 347 | void (*iop_pin)(xfs_log_item_t *); |
| @@ -352,7 +352,7 @@ typedef struct xfs_item_ops { | |||
| 352 | void (*iop_push)(xfs_log_item_t *); | 352 | void (*iop_push)(xfs_log_item_t *); |
| 353 | bool (*iop_pushbuf)(xfs_log_item_t *); | 353 | bool (*iop_pushbuf)(xfs_log_item_t *); |
| 354 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); | 354 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); |
| 355 | } xfs_item_ops_t; | 355 | }; |
| 356 | 356 | ||
| 357 | #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) | 357 | #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) |
| 358 | #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) | 358 | #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 4ecf2a549060..ce9268a2f56b 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -112,7 +112,7 @@ xfs_readlink( | |||
| 112 | char *link) | 112 | char *link) |
| 113 | { | 113 | { |
| 114 | xfs_mount_t *mp = ip->i_mount; | 114 | xfs_mount_t *mp = ip->i_mount; |
| 115 | int pathlen; | 115 | xfs_fsize_t pathlen; |
| 116 | int error = 0; | 116 | int error = 0; |
| 117 | 117 | ||
| 118 | trace_xfs_readlink(ip); | 118 | trace_xfs_readlink(ip); |
| @@ -122,13 +122,19 @@ xfs_readlink( | |||
| 122 | 122 | ||
| 123 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 123 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| 124 | 124 | ||
| 125 | ASSERT(S_ISLNK(ip->i_d.di_mode)); | ||
| 126 | ASSERT(ip->i_d.di_size <= MAXPATHLEN); | ||
| 127 | |||
| 128 | pathlen = ip->i_d.di_size; | 125 | pathlen = ip->i_d.di_size; |
| 129 | if (!pathlen) | 126 | if (!pathlen) |
| 130 | goto out; | 127 | goto out; |
| 131 | 128 | ||
| 129 | if (pathlen < 0 || pathlen > MAXPATHLEN) { | ||
| 130 | xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)", | ||
| 131 | __func__, (unsigned long long) ip->i_ino, | ||
| 132 | (long long) pathlen); | ||
| 133 | ASSERT(0); | ||
| 134 | return XFS_ERROR(EFSCORRUPTED); | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 132 | if (ip->i_df.if_flags & XFS_IFINLINE) { | 138 | if (ip->i_df.if_flags & XFS_IFINLINE) { |
| 133 | memcpy(link, ip->i_df.if_u1.if_data, pathlen); | 139 | memcpy(link, ip->i_df.if_u1.if_data, pathlen); |
| 134 | link[pathlen] = '\0'; | 140 | link[pathlen] = '\0'; |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index cf399495d38f..1f9e9516e2b7 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -990,7 +990,9 @@ struct drm_minor { | |||
| 990 | struct proc_dir_entry *proc_root; /**< proc directory entry */ | 990 | struct proc_dir_entry *proc_root; /**< proc directory entry */ |
| 991 | struct drm_info_node proc_nodes; | 991 | struct drm_info_node proc_nodes; |
| 992 | struct dentry *debugfs_root; | 992 | struct dentry *debugfs_root; |
| 993 | struct drm_info_node debugfs_nodes; | 993 | |
| 994 | struct list_head debugfs_list; | ||
| 995 | struct mutex debugfs_lock; /* Protects debugfs_list. */ | ||
| 994 | 996 | ||
| 995 | struct drm_master *master; /* currently active master for this node */ | 997 | struct drm_master *master; /* currently active master for this node */ |
| 996 | struct list_head master_list; | 998 | struct list_head master_list; |
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h index 874c4d271328..1d161cb3aca5 100644 --- a/include/drm/exynos_drm.h +++ b/include/drm/exynos_drm.h | |||
| @@ -36,11 +36,13 @@ | |||
| 36 | * - this size value would be page-aligned internally. | 36 | * - this size value would be page-aligned internally. |
| 37 | * @flags: user request for setting memory type or cache attributes. | 37 | * @flags: user request for setting memory type or cache attributes. |
| 38 | * @handle: returned handle for the object. | 38 | * @handle: returned handle for the object. |
| 39 | * @pad: just padding to be 64-bit aligned. | ||
| 39 | */ | 40 | */ |
| 40 | struct drm_exynos_gem_create { | 41 | struct drm_exynos_gem_create { |
| 41 | unsigned int size; | 42 | unsigned int size; |
| 42 | unsigned int flags; | 43 | unsigned int flags; |
| 43 | unsigned int handle; | 44 | unsigned int handle; |
| 45 | unsigned int pad; | ||
| 44 | }; | 46 | }; |
| 45 | 47 | ||
| 46 | /** | 48 | /** |
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index fae295048a8b..83a9caec0e43 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h | |||
| @@ -1963,6 +1963,21 @@ | |||
| 1963 | #define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ | 1963 | #define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ |
| 1964 | 1964 | ||
| 1965 | /* | 1965 | /* |
| 1966 | * R210 (0xD2) - Mic Detect 3 | ||
| 1967 | */ | ||
| 1968 | #define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ | ||
| 1969 | #define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ | ||
| 1970 | #define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ | ||
| 1971 | #define WM8958_MICD_VALID 0x0002 /* MICD_VALID */ | ||
| 1972 | #define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */ | ||
| 1973 | #define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */ | ||
| 1974 | #define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */ | ||
| 1975 | #define WM8958_MICD_STS 0x0001 /* MICD_STS */ | ||
| 1976 | #define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */ | ||
| 1977 | #define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */ | ||
| 1978 | #define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */ | ||
| 1979 | |||
| 1980 | /* | ||
| 1966 | * R76 (0x4C) - Charge Pump (1) | 1981 | * R76 (0x4C) - Charge Pump (1) |
| 1967 | */ | 1982 | */ |
| 1968 | #define WM8994_CP_ENA 0x8000 /* CP_ENA */ | 1983 | #define WM8994_CP_ENA 0x8000 /* CP_ENA */ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 3fdf251389de..172ba70306d1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2405,6 +2405,8 @@ | |||
| 2405 | 2405 | ||
| 2406 | #define PCI_VENDOR_ID_AZWAVE 0x1a3b | 2406 | #define PCI_VENDOR_ID_AZWAVE 0x1a3b |
| 2407 | 2407 | ||
| 2408 | #define PCI_VENDOR_ID_ASMEDIA 0x1b21 | ||
| 2409 | |||
| 2408 | #define PCI_VENDOR_ID_TEKRAM 0x1de1 | 2410 | #define PCI_VENDOR_ID_TEKRAM 0x1de1 |
| 2409 | #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 | 2411 | #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 |
| 2410 | 2412 | ||
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 5dbab38d04af..130cfe677d60 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c | |||
| @@ -52,6 +52,7 @@ struct link_slave { | |||
| 52 | struct link_ctl_info info; | 52 | struct link_ctl_info info; |
| 53 | int vals[2]; /* current values */ | 53 | int vals[2]; /* current values */ |
| 54 | unsigned int flags; | 54 | unsigned int flags; |
| 55 | struct snd_kcontrol *kctl; /* original kcontrol pointer */ | ||
| 55 | struct snd_kcontrol slave; /* the copy of original control entry */ | 56 | struct snd_kcontrol slave; /* the copy of original control entry */ |
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| @@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, | |||
| 252 | slave->count * sizeof(*slave->vd), GFP_KERNEL); | 253 | slave->count * sizeof(*slave->vd), GFP_KERNEL); |
| 253 | if (!srec) | 254 | if (!srec) |
| 254 | return -ENOMEM; | 255 | return -ENOMEM; |
| 256 | srec->kctl = slave; | ||
| 255 | srec->slave = *slave; | 257 | srec->slave = *slave; |
| 256 | memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); | 258 | memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); |
| 257 | srec->master = master_link; | 259 | srec->master = master_link; |
| @@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, | |||
| 333 | static void master_free(struct snd_kcontrol *kcontrol) | 335 | static void master_free(struct snd_kcontrol *kcontrol) |
| 334 | { | 336 | { |
| 335 | struct link_master *master = snd_kcontrol_chip(kcontrol); | 337 | struct link_master *master = snd_kcontrol_chip(kcontrol); |
| 336 | struct link_slave *slave; | 338 | struct link_slave *slave, *n; |
| 337 | 339 | ||
| 338 | list_for_each_entry(slave, &master->slaves, list) | 340 | /* free all slave links and retore the original slave kctls */ |
| 339 | slave->master = NULL; | 341 | list_for_each_entry_safe(slave, n, &master->slaves, list) { |
| 342 | struct snd_kcontrol *sctl = slave->kctl; | ||
| 343 | struct list_head olist = sctl->list; | ||
| 344 | memcpy(sctl, &slave->slave, sizeof(*sctl)); | ||
| 345 | memcpy(sctl->vd, slave->slave.vd, | ||
| 346 | sctl->count * sizeof(*sctl->vd)); | ||
| 347 | sctl->list = olist; /* keep the current linked-list */ | ||
| 348 | kfree(slave); | ||
| 349 | } | ||
| 340 | kfree(master); | 350 | kfree(master); |
| 341 | } | 351 | } |
| 342 | 352 | ||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 916a1863af73..e44b107fdc75 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
| 2331 | return 0; | 2331 | return 0; |
| 2332 | } | 2332 | } |
| 2333 | 2333 | ||
| 2334 | typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | ||
| 2335 | |||
| 2336 | /* apply the function to all matching slave ctls in the mixer list */ | ||
| 2337 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, | ||
| 2338 | map_slave_func_t func, void *data) | ||
| 2339 | { | ||
| 2340 | struct hda_nid_item *items; | ||
| 2341 | const char * const *s; | ||
| 2342 | int i, err; | ||
| 2343 | |||
| 2344 | items = codec->mixers.list; | ||
| 2345 | for (i = 0; i < codec->mixers.used; i++) { | ||
| 2346 | struct snd_kcontrol *sctl = items[i].kctl; | ||
| 2347 | if (!sctl || !sctl->id.name || | ||
| 2348 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) | ||
| 2349 | continue; | ||
| 2350 | for (s = slaves; *s; s++) { | ||
| 2351 | if (!strcmp(sctl->id.name, *s)) { | ||
| 2352 | err = func(data, sctl); | ||
| 2353 | if (err) | ||
| 2354 | return err; | ||
| 2355 | break; | ||
| 2356 | } | ||
| 2357 | } | ||
| 2358 | } | ||
| 2359 | return 0; | ||
| 2360 | } | ||
| 2361 | |||
| 2362 | static int check_slave_present(void *data, struct snd_kcontrol *sctl) | ||
| 2363 | { | ||
| 2364 | return 1; | ||
| 2365 | } | ||
| 2366 | |||
| 2334 | /** | 2367 | /** |
| 2335 | * snd_hda_add_vmaster - create a virtual master control and add slaves | 2368 | * snd_hda_add_vmaster - create a virtual master control and add slaves |
| 2336 | * @codec: HD-audio codec | 2369 | * @codec: HD-audio codec |
| @@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
| 2351 | unsigned int *tlv, const char * const *slaves) | 2384 | unsigned int *tlv, const char * const *slaves) |
| 2352 | { | 2385 | { |
| 2353 | struct snd_kcontrol *kctl; | 2386 | struct snd_kcontrol *kctl; |
| 2354 | const char * const *s; | ||
| 2355 | int err; | 2387 | int err; |
| 2356 | 2388 | ||
| 2357 | for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) | 2389 | err = map_slaves(codec, slaves, check_slave_present, NULL); |
| 2358 | ; | 2390 | if (err != 1) { |
| 2359 | if (!*s) { | ||
| 2360 | snd_printdd("No slave found for %s\n", name); | 2391 | snd_printdd("No slave found for %s\n", name); |
| 2361 | return 0; | 2392 | return 0; |
| 2362 | } | 2393 | } |
| @@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
| 2367 | if (err < 0) | 2398 | if (err < 0) |
| 2368 | return err; | 2399 | return err; |
| 2369 | 2400 | ||
| 2370 | for (s = slaves; *s; s++) { | 2401 | err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, |
| 2371 | struct snd_kcontrol *sctl; | 2402 | kctl); |
| 2372 | int i = 0; | 2403 | if (err < 0) |
| 2373 | for (;;) { | 2404 | return err; |
| 2374 | sctl = _snd_hda_find_mixer_ctl(codec, *s, i); | ||
| 2375 | if (!sctl) { | ||
| 2376 | if (!i) | ||
| 2377 | snd_printdd("Cannot find slave %s, " | ||
| 2378 | "skipped\n", *s); | ||
| 2379 | break; | ||
| 2380 | } | ||
| 2381 | err = snd_ctl_add_slave(kctl, sctl); | ||
| 2382 | if (err < 0) | ||
| 2383 | return err; | ||
| 2384 | i++; | ||
| 2385 | } | ||
| 2386 | } | ||
| 2387 | return 0; | 2405 | return 0; |
| 2388 | } | 2406 | } |
| 2389 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); | 2407 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); |
| @@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
| 4752 | memset(sequences_hp, 0, sizeof(sequences_hp)); | 4770 | memset(sequences_hp, 0, sizeof(sequences_hp)); |
| 4753 | assoc_line_out = 0; | 4771 | assoc_line_out = 0; |
| 4754 | 4772 | ||
| 4773 | codec->ignore_misc_bit = true; | ||
| 4755 | end_nid = codec->start_nid + codec->num_nodes; | 4774 | end_nid = codec->start_nid + codec->num_nodes; |
| 4756 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 4775 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
| 4757 | unsigned int wid_caps = get_wcaps(codec, nid); | 4776 | unsigned int wid_caps = get_wcaps(codec, nid); |
| @@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
| 4767 | continue; | 4786 | continue; |
| 4768 | 4787 | ||
| 4769 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4788 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
| 4789 | if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
| 4790 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
| 4791 | codec->ignore_misc_bit = false; | ||
| 4770 | conn = get_defcfg_connect(def_conf); | 4792 | conn = get_defcfg_connect(def_conf); |
| 4771 | if (conn == AC_JACK_PORT_NONE) | 4793 | if (conn == AC_JACK_PORT_NONE) |
| 4772 | continue; | 4794 | continue; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 755f2b0f9d8e..564471169cae 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -854,6 +854,7 @@ struct hda_codec { | |||
| 854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ | 854 | unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ |
| 855 | unsigned int pins_shutup:1; /* pins are shut up */ | 855 | unsigned int pins_shutup:1; /* pins are shut up */ |
| 856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
| 857 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | ||
| 857 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 858 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
| 858 | unsigned int power_on :1; /* current (global) power-state */ | 859 | unsigned int power_on :1; /* current (global) power-state */ |
| 859 | unsigned int power_transition :1; /* power-state in transition */ | 860 | unsigned int power_transition :1; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index dcbea0da0fa2..6579e0f2bb57 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | |||
| 510 | 510 | ||
| 511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 511 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) |
| 512 | { | 512 | { |
| 513 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && | 513 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) |
| 514 | /* disable MISC_NO_PRESENCE check because it may break too | 514 | return false; |
| 515 | * many devices | 515 | if (!codec->ignore_misc_bit && |
| 516 | */ | 516 | (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & |
| 517 | /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & | 517 | AC_DEFCFG_MISC_NO_PRESENCE)) |
| 518 | AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ | 518 | return false; |
| 519 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); | 519 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) |
| 520 | return false; | ||
| 521 | return true; | ||
| 520 | } | 522 | } |
| 521 | 523 | ||
| 522 | /* flags for hda_nid_item */ | 524 | /* flags for hda_nid_item */ |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5e706e4d1737..0de21193a2b0 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -3062,7 +3062,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
| 3062 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), | 3062 | SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), |
| 3063 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), | 3063 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), |
| 3064 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3064 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
| 3065 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | ||
| 3066 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", | 3065 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", |
| 3067 | CXT5066_LAPTOP), | 3066 | CXT5066_LAPTOP), |
| 3068 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3067 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a24e068a021b..308bb575bc06 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -284,7 +284,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
| 284 | struct alc_spec *spec = codec->spec; | 284 | struct alc_spec *spec = codec->spec; |
| 285 | const struct hda_input_mux *imux; | 285 | const struct hda_input_mux *imux; |
| 286 | unsigned int mux_idx; | 286 | unsigned int mux_idx; |
| 287 | int i, type; | 287 | int i, type, num_conns; |
| 288 | hda_nid_t nid; | 288 | hda_nid_t nid; |
| 289 | 289 | ||
| 290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
| @@ -307,16 +307,17 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
| 307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | 307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; |
| 308 | 308 | ||
| 309 | /* no selection? */ | 309 | /* no selection? */ |
| 310 | if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) | 310 | num_conns = snd_hda_get_conn_list(codec, nid, NULL); |
| 311 | if (num_conns <= 1) | ||
| 311 | return 1; | 312 | return 1; |
| 312 | 313 | ||
| 313 | type = get_wcaps_type(get_wcaps(codec, nid)); | 314 | type = get_wcaps_type(get_wcaps(codec, nid)); |
| 314 | if (type == AC_WID_AUD_MIX) { | 315 | if (type == AC_WID_AUD_MIX) { |
| 315 | /* Matrix-mixer style (e.g. ALC882) */ | 316 | /* Matrix-mixer style (e.g. ALC882) */ |
| 316 | for (i = 0; i < imux->num_items; i++) { | 317 | int active = imux->items[idx].index; |
| 317 | unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; | 318 | for (i = 0; i < num_conns; i++) { |
| 318 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, | 319 | unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; |
| 319 | imux->items[i].index, | 320 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, |
| 320 | HDA_AMP_MUTE, v); | 321 | HDA_AMP_MUTE, v); |
| 321 | } | 322 | } |
| 322 | } else { | 323 | } else { |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4e715fefebef..edc2b7bc177c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -95,6 +95,7 @@ enum { | |||
| 95 | STAC_92HD83XXX_REF, | 95 | STAC_92HD83XXX_REF, |
| 96 | STAC_92HD83XXX_PWR_REF, | 96 | STAC_92HD83XXX_PWR_REF, |
| 97 | STAC_DELL_S14, | 97 | STAC_DELL_S14, |
| 98 | STAC_DELL_VOSTRO_3500, | ||
| 98 | STAC_92HD83XXX_HP, | 99 | STAC_92HD83XXX_HP, |
| 99 | STAC_92HD83XXX_HP_cNB11_INTQUAD, | 100 | STAC_92HD83XXX_HP_cNB11_INTQUAD, |
| 100 | STAC_HP_DV7_4000, | 101 | STAC_HP_DV7_4000, |
| @@ -1659,6 +1660,12 @@ static const unsigned int dell_s14_pin_configs[10] = { | |||
| 1659 | 0x40f000f0, 0x40f000f0, | 1660 | 0x40f000f0, 0x40f000f0, |
| 1660 | }; | 1661 | }; |
| 1661 | 1662 | ||
| 1663 | static const unsigned int dell_vostro_3500_pin_configs[10] = { | ||
| 1664 | 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, | ||
| 1665 | 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, | ||
| 1666 | 0x400000f4, 0x400000f5, | ||
| 1667 | }; | ||
| 1668 | |||
| 1662 | static const unsigned int hp_dv7_4000_pin_configs[10] = { | 1669 | static const unsigned int hp_dv7_4000_pin_configs[10] = { |
| 1663 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, | 1670 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, |
| 1664 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, | 1671 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, |
| @@ -1675,6 +1682,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | |||
| 1675 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1682 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
| 1676 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 1683 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, |
| 1677 | [STAC_DELL_S14] = dell_s14_pin_configs, | 1684 | [STAC_DELL_S14] = dell_s14_pin_configs, |
| 1685 | [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, | ||
| 1678 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, | 1686 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, |
| 1679 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, | 1687 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, |
| 1680 | }; | 1688 | }; |
| @@ -1684,6 +1692,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
| 1684 | [STAC_92HD83XXX_REF] = "ref", | 1692 | [STAC_92HD83XXX_REF] = "ref", |
| 1685 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 1693 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", |
| 1686 | [STAC_DELL_S14] = "dell-s14", | 1694 | [STAC_DELL_S14] = "dell-s14", |
| 1695 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", | ||
| 1687 | [STAC_92HD83XXX_HP] = "hp", | 1696 | [STAC_92HD83XXX_HP] = "hp", |
| 1688 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", | 1697 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", |
| 1689 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 1698 | [STAC_HP_DV7_4000] = "hp-dv7-4000", |
| @@ -1697,6 +1706,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
| 1697 | "DFI LanParty", STAC_92HD83XXX_REF), | 1706 | "DFI LanParty", STAC_92HD83XXX_REF), |
| 1698 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, | 1707 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, |
| 1699 | "unknown Dell", STAC_DELL_S14), | 1708 | "unknown Dell", STAC_DELL_S14), |
| 1709 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, | ||
| 1710 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), | ||
| 1700 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, | 1711 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, |
| 1701 | "HP", STAC_92HD83XXX_HP), | 1712 | "HP", STAC_92HD83XXX_HP), |
| 1702 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, | 1713 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 29e312597f20..11718b49b2e2 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
| @@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs | |||
| 1077 | } | 1077 | } |
| 1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) | 1078 | if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) |
| 1079 | continue; | 1079 | continue; |
| 1080 | |||
| 1081 | /* IO read operation is very expensive inside virtual machine | ||
| 1082 | * as it is emulated. The probability that subsequent PICB read | ||
| 1083 | * will return different result is high enough to loop till | ||
| 1084 | * timeout here. | ||
| 1085 | * Same CIV is strict enough condition to be sure that PICB | ||
| 1086 | * is valid inside VM on emulated card. */ | ||
| 1080 | if (chip->inside_vm) | 1087 | if (chip->inside_vm) |
| 1081 | break; | 1088 | break; |
| 1082 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) | 1089 | if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) |
| @@ -2930,6 +2937,45 @@ static unsigned int sis_codec_bits[3] = { | |||
| 2930 | ICH_PCR, ICH_SCR, ICH_SIS_TCR | 2937 | ICH_PCR, ICH_SCR, ICH_SIS_TCR |
| 2931 | }; | 2938 | }; |
| 2932 | 2939 | ||
| 2940 | static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci) | ||
| 2941 | { | ||
| 2942 | int result = inside_vm; | ||
| 2943 | char *msg = NULL; | ||
| 2944 | |||
| 2945 | /* check module parameter first (override detection) */ | ||
| 2946 | if (result >= 0) { | ||
| 2947 | msg = result ? "enable (forced) VM" : "disable (forced) VM"; | ||
| 2948 | goto fini; | ||
| 2949 | } | ||
| 2950 | |||
| 2951 | /* detect KVM and Parallels virtual environments */ | ||
| 2952 | result = kvm_para_available(); | ||
| 2953 | #ifdef X86_FEATURE_HYPERVISOR | ||
| 2954 | result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
| 2955 | #endif | ||
| 2956 | if (!result) | ||
| 2957 | goto fini; | ||
| 2958 | |||
| 2959 | /* check for known (emulated) devices */ | ||
| 2960 | if (pci->subsystem_vendor == 0x1af4 && | ||
| 2961 | pci->subsystem_device == 0x1100) { | ||
| 2962 | /* KVM emulated sound, PCI SSID: 1af4:1100 */ | ||
| 2963 | msg = "enable KVM"; | ||
| 2964 | } else if (pci->subsystem_vendor == 0x1ab8) { | ||
| 2965 | /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */ | ||
| 2966 | msg = "enable Parallels VM"; | ||
| 2967 | } else { | ||
| 2968 | msg = "disable (unknown or VT-d) VM"; | ||
| 2969 | result = 0; | ||
| 2970 | } | ||
| 2971 | |||
| 2972 | fini: | ||
| 2973 | if (msg != NULL) | ||
| 2974 | printk(KERN_INFO "intel8x0: %s optimization\n", msg); | ||
| 2975 | |||
| 2976 | return result; | ||
| 2977 | } | ||
| 2978 | |||
| 2933 | static int __devinit snd_intel8x0_create(struct snd_card *card, | 2979 | static int __devinit snd_intel8x0_create(struct snd_card *card, |
| 2934 | struct pci_dev *pci, | 2980 | struct pci_dev *pci, |
| 2935 | unsigned long device_type, | 2981 | unsigned long device_type, |
| @@ -2997,9 +3043,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
| 2997 | if (xbox) | 3043 | if (xbox) |
| 2998 | chip->xbox = 1; | 3044 | chip->xbox = 1; |
| 2999 | 3045 | ||
| 3000 | chip->inside_vm = inside_vm; | 3046 | chip->inside_vm = snd_intel8x0_inside_vm(pci); |
| 3001 | if (inside_vm) | ||
| 3002 | printk(KERN_INFO "intel8x0: enable KVM optimization\n"); | ||
| 3003 | 3047 | ||
| 3004 | if (pci->vendor == PCI_VENDOR_ID_INTEL && | 3048 | if (pci->vendor == PCI_VENDOR_ID_INTEL && |
| 3005 | pci->device == PCI_DEVICE_ID_INTEL_440MX) | 3049 | pci->device == PCI_DEVICE_ID_INTEL_440MX) |
| @@ -3243,14 +3287,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
| 3243 | buggy_irq = 0; | 3287 | buggy_irq = 0; |
| 3244 | } | 3288 | } |
| 3245 | 3289 | ||
| 3246 | if (inside_vm < 0) { | ||
| 3247 | /* detect KVM and Parallels virtual environments */ | ||
| 3248 | inside_vm = kvm_para_available(); | ||
| 3249 | #if defined(__i386__) || defined(__x86_64__) | ||
| 3250 | inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); | ||
| 3251 | #endif | ||
| 3252 | } | ||
| 3253 | |||
| 3254 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, | 3290 | if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, |
| 3255 | &chip)) < 0) { | 3291 | &chip)) < 0) { |
| 3256 | snd_card_free(card); | 3292 | snd_card_free(card); |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index a3ce1b22620d..1aa52eff526a 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
| @@ -876,7 +876,7 @@ static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) | |||
| 876 | (0x0fUL << 12) | | 876 | (0x0fUL << 12) | |
| 877 | (PS3_AUDIO_IOID); | 877 | (PS3_AUDIO_IOID); |
| 878 | 878 | ||
| 879 | ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); | 879 | ret = lv1_gpu_attribute(0x100, 0x007, val); |
| 880 | if (ret) | 880 | if (ret) |
| 881 | pr_info("%s: gpu_attribute failed %d\n", __func__, | 881 | pr_info("%s: gpu_attribute failed %d\n", __func__, |
| 882 | ret); | 882 | ret); |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6b73efd26991..9c982e47eb99 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
| @@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = { | |||
| 56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) | 56 | static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) |
| 57 | { | 57 | { |
| 58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 58 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
| 59 | struct wm8994 *control = wm8994->control_data; | 59 | struct wm8994 *control = codec->control_data; |
| 60 | 60 | ||
| 61 | switch (reg) { | 61 | switch (reg) { |
| 62 | case WM8994_GPIO_1: | 62 | case WM8994_GPIO_1: |
| @@ -3030,19 +3030,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
| 3030 | { | 3030 | { |
| 3031 | struct wm8994_priv *wm8994 = data; | 3031 | struct wm8994_priv *wm8994 = data; |
| 3032 | struct snd_soc_codec *codec = wm8994->codec; | 3032 | struct snd_soc_codec *codec = wm8994->codec; |
| 3033 | int reg; | 3033 | int reg, count; |
| 3034 | 3034 | ||
| 3035 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); | 3035 | /* We may occasionally read a detection without an impedence |
| 3036 | if (reg < 0) { | 3036 | * range being provided - if that happens loop again. |
| 3037 | dev_err(codec->dev, "Failed to read mic detect status: %d\n", | 3037 | */ |
| 3038 | reg); | 3038 | count = 10; |
| 3039 | return IRQ_NONE; | 3039 | do { |
| 3040 | } | 3040 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); |
| 3041 | if (reg < 0) { | ||
| 3042 | dev_err(codec->dev, | ||
| 3043 | "Failed to read mic detect status: %d\n", | ||
| 3044 | reg); | ||
| 3045 | return IRQ_NONE; | ||
| 3046 | } | ||
| 3041 | 3047 | ||
| 3042 | if (!(reg & WM8958_MICD_VALID)) { | 3048 | if (!(reg & WM8958_MICD_VALID)) { |
| 3043 | dev_dbg(codec->dev, "Mic detect data not valid\n"); | 3049 | dev_dbg(codec->dev, "Mic detect data not valid\n"); |
| 3044 | goto out; | 3050 | goto out; |
| 3045 | } | 3051 | } |
| 3052 | |||
| 3053 | if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) | ||
| 3054 | break; | ||
| 3055 | |||
| 3056 | msleep(1); | ||
| 3057 | } while (count--); | ||
| 3058 | |||
| 3059 | if (count == 0) | ||
| 3060 | dev_warn(codec->dev, "No impedence range reported for jack\n"); | ||
| 3046 | 3061 | ||
| 3047 | #ifndef CONFIG_SND_SOC_WM8994_MODULE | 3062 | #ifndef CONFIG_SND_SOC_WM8994_MODULE |
| 3048 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3063 | trace_snd_soc_jack_irq(dev_name(codec->dev)); |
| @@ -3180,9 +3195,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 3180 | 3195 | ||
| 3181 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, | 3196 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, |
| 3182 | wm8994_fifo_error, "FIFO error", codec); | 3197 | wm8994_fifo_error, "FIFO error", codec); |
| 3183 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, | 3198 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, |
| 3184 | wm8994_temp_warn, "Thermal warning", codec); | 3199 | wm8994_temp_warn, "Thermal warning", codec); |
| 3185 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, | 3200 | wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, |
| 3186 | wm8994_temp_shut, "Thermal shutdown", codec); | 3201 | wm8994_temp_shut, "Thermal shutdown", codec); |
| 3187 | 3202 | ||
| 3188 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3203 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 60f65ace7474..ab23869c01bb 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -765,10 +765,61 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |||
| 765 | * interface to ALSA control for feature/mixer units | 765 | * interface to ALSA control for feature/mixer units |
| 766 | */ | 766 | */ |
| 767 | 767 | ||
| 768 | /* volume control quirks */ | ||
| 769 | static void volume_control_quirks(struct usb_mixer_elem_info *cval, | ||
| 770 | struct snd_kcontrol *kctl) | ||
| 771 | { | ||
| 772 | switch (cval->mixer->chip->usb_id) { | ||
| 773 | case USB_ID(0x0471, 0x0101): | ||
| 774 | case USB_ID(0x0471, 0x0104): | ||
| 775 | case USB_ID(0x0471, 0x0105): | ||
| 776 | case USB_ID(0x0672, 0x1041): | ||
| 777 | /* quirk for UDA1321/N101. | ||
| 778 | * note that detection between firmware 2.1.1.7 (N101) | ||
| 779 | * and later 2.1.1.21 is not very clear from datasheets. | ||
| 780 | * I hope that the min value is -15360 for newer firmware --jk | ||
| 781 | */ | ||
| 782 | if (!strcmp(kctl->id.name, "PCM Playback Volume") && | ||
| 783 | cval->min == -15616) { | ||
| 784 | snd_printk(KERN_INFO | ||
| 785 | "set volume quirk for UDA1321/N101 chip\n"); | ||
| 786 | cval->max = -256; | ||
| 787 | } | ||
| 788 | break; | ||
| 789 | |||
| 790 | case USB_ID(0x046d, 0x09a4): | ||
| 791 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
| 792 | snd_printk(KERN_INFO | ||
| 793 | "set volume quirk for QuickCam E3500\n"); | ||
| 794 | cval->min = 6080; | ||
| 795 | cval->max = 8768; | ||
| 796 | cval->res = 192; | ||
| 797 | } | ||
| 798 | break; | ||
| 799 | |||
| 800 | case USB_ID(0x046d, 0x0808): | ||
| 801 | case USB_ID(0x046d, 0x0809): | ||
| 802 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ | ||
| 803 | case USB_ID(0x046d, 0x0991): | ||
| 804 | /* Most audio usb devices lie about volume resolution. | ||
| 805 | * Most Logitech webcams have res = 384. | ||
| 806 | * Proboly there is some logitech magic behind this number --fishor | ||
| 807 | */ | ||
| 808 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
| 809 | snd_printk(KERN_INFO | ||
| 810 | "set resolution quirk: cval->res = 384\n"); | ||
| 811 | cval->res = 384; | ||
| 812 | } | ||
| 813 | break; | ||
| 814 | |||
| 815 | } | ||
| 816 | } | ||
| 817 | |||
| 768 | /* | 818 | /* |
| 769 | * retrieve the minimum and maximum values for the specified control | 819 | * retrieve the minimum and maximum values for the specified control |
| 770 | */ | 820 | */ |
| 771 | static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | 821 | static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, |
| 822 | int default_min, struct snd_kcontrol *kctl) | ||
| 772 | { | 823 | { |
| 773 | /* for failsafe */ | 824 | /* for failsafe */ |
| 774 | cval->min = default_min; | 825 | cval->min = default_min; |
| @@ -844,6 +895,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
| 844 | cval->initialized = 1; | 895 | cval->initialized = 1; |
| 845 | } | 896 | } |
| 846 | 897 | ||
| 898 | if (kctl) | ||
| 899 | volume_control_quirks(cval, kctl); | ||
| 900 | |||
| 847 | /* USB descriptions contain the dB scale in 1/256 dB unit | 901 | /* USB descriptions contain the dB scale in 1/256 dB unit |
| 848 | * while ALSA TLV contains in 1/100 dB unit | 902 | * while ALSA TLV contains in 1/100 dB unit |
| 849 | */ | 903 | */ |
| @@ -864,6 +918,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) | |||
| 864 | return 0; | 918 | return 0; |
| 865 | } | 919 | } |
| 866 | 920 | ||
| 921 | #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) | ||
| 867 | 922 | ||
| 868 | /* get a feature/mixer unit info */ | 923 | /* get a feature/mixer unit info */ |
| 869 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 924 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
| @@ -882,7 +937,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
| 882 | uinfo->value.integer.max = 1; | 937 | uinfo->value.integer.max = 1; |
| 883 | } else { | 938 | } else { |
| 884 | if (!cval->initialized) { | 939 | if (!cval->initialized) { |
| 885 | get_min_max(cval, 0); | 940 | get_min_max_with_quirks(cval, 0, kcontrol); |
| 886 | if (cval->initialized && cval->dBmin >= cval->dBmax) { | 941 | if (cval->initialized && cval->dBmin >= cval->dBmax) { |
| 887 | kcontrol->vd[0].access &= | 942 | kcontrol->vd[0].access &= |
| 888 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 943 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
| @@ -1045,9 +1100,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
| 1045 | cval->ch_readonly = readonly_mask; | 1100 | cval->ch_readonly = readonly_mask; |
| 1046 | } | 1101 | } |
| 1047 | 1102 | ||
| 1048 | /* get min/max values */ | ||
| 1049 | get_min_max(cval, 0); | ||
| 1050 | |||
| 1051 | /* if all channels in the mask are marked read-only, make the control | 1103 | /* if all channels in the mask are marked read-only, make the control |
| 1052 | * read-only. set_cur_mix_value() will check the mask again and won't | 1104 | * read-only. set_cur_mix_value() will check the mask again and won't |
| 1053 | * issue write commands to read-only channels. */ | 1105 | * issue write commands to read-only channels. */ |
| @@ -1069,6 +1121,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
| 1069 | len = snd_usb_copy_string_desc(state, nameid, | 1121 | len = snd_usb_copy_string_desc(state, nameid, |
| 1070 | kctl->id.name, sizeof(kctl->id.name)); | 1122 | kctl->id.name, sizeof(kctl->id.name)); |
| 1071 | 1123 | ||
| 1124 | /* get min/max values */ | ||
| 1125 | get_min_max_with_quirks(cval, 0, kctl); | ||
| 1126 | |||
| 1072 | switch (control) { | 1127 | switch (control) { |
| 1073 | case UAC_FU_MUTE: | 1128 | case UAC_FU_MUTE: |
| 1074 | case UAC_FU_VOLUME: | 1129 | case UAC_FU_VOLUME: |
| @@ -1118,51 +1173,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
| 1118 | break; | 1173 | break; |
| 1119 | } | 1174 | } |
| 1120 | 1175 | ||
| 1121 | /* volume control quirks */ | ||
| 1122 | switch (state->chip->usb_id) { | ||
| 1123 | case USB_ID(0x0471, 0x0101): | ||
| 1124 | case USB_ID(0x0471, 0x0104): | ||
| 1125 | case USB_ID(0x0471, 0x0105): | ||
| 1126 | case USB_ID(0x0672, 0x1041): | ||
| 1127 | /* quirk for UDA1321/N101. | ||
| 1128 | * note that detection between firmware 2.1.1.7 (N101) | ||
| 1129 | * and later 2.1.1.21 is not very clear from datasheets. | ||
| 1130 | * I hope that the min value is -15360 for newer firmware --jk | ||
| 1131 | */ | ||
| 1132 | if (!strcmp(kctl->id.name, "PCM Playback Volume") && | ||
| 1133 | cval->min == -15616) { | ||
| 1134 | snd_printk(KERN_INFO | ||
| 1135 | "set volume quirk for UDA1321/N101 chip\n"); | ||
| 1136 | cval->max = -256; | ||
| 1137 | } | ||
| 1138 | break; | ||
| 1139 | |||
| 1140 | case USB_ID(0x046d, 0x09a4): | ||
| 1141 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
| 1142 | snd_printk(KERN_INFO | ||
| 1143 | "set volume quirk for QuickCam E3500\n"); | ||
| 1144 | cval->min = 6080; | ||
| 1145 | cval->max = 8768; | ||
| 1146 | cval->res = 192; | ||
| 1147 | } | ||
| 1148 | break; | ||
| 1149 | |||
| 1150 | case USB_ID(0x046d, 0x0808): | ||
| 1151 | case USB_ID(0x046d, 0x0809): | ||
| 1152 | case USB_ID(0x046d, 0x0991): | ||
| 1153 | /* Most audio usb devices lie about volume resolution. | ||
| 1154 | * Most Logitech webcams have res = 384. | ||
| 1155 | * Proboly there is some logitech magic behind this number --fishor | ||
| 1156 | */ | ||
| 1157 | if (!strcmp(kctl->id.name, "Mic Capture Volume")) { | ||
| 1158 | snd_printk(KERN_INFO | ||
| 1159 | "set resolution quirk: cval->res = 384\n"); | ||
| 1160 | cval->res = 384; | ||
| 1161 | } | ||
| 1162 | break; | ||
| 1163 | |||
| 1164 | } | ||
| 1165 | |||
| 1166 | range = (cval->max - cval->min) / cval->res; | 1176 | range = (cval->max - cval->min) / cval->res; |
| 1167 | /* Are there devices with volume range more than 255? I use a bit more | 1177 | /* Are there devices with volume range more than 255? I use a bit more |
| 1168 | * to be sure. 384 is a resolution magic number found on Logitech | 1178 | * to be sure. 384 is a resolution magic number found on Logitech |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 2e5bc7344026..a3ddac0deffd 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
| @@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
| 137 | return -ENOMEM; | 137 | return -ENOMEM; |
| 138 | } | 138 | } |
| 139 | if (fp->nr_rates > 0) { | 139 | if (fp->nr_rates > 0) { |
| 140 | rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); | 140 | rate_table = kmemdup(fp->rate_table, |
| 141 | sizeof(int) * fp->nr_rates, GFP_KERNEL); | ||
| 141 | if (!rate_table) { | 142 | if (!rate_table) { |
| 142 | kfree(fp); | 143 | kfree(fp); |
| 143 | return -ENOMEM; | 144 | return -ENOMEM; |
| 144 | } | 145 | } |
| 145 | memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); | ||
| 146 | fp->rate_table = rate_table; | 146 | fp->rate_table = rate_table; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| @@ -224,10 +224,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
| 224 | if (altsd->bNumEndpoints != 1) | 224 | if (altsd->bNumEndpoints != 1) |
| 225 | return -ENXIO; | 225 | return -ENXIO; |
| 226 | 226 | ||
| 227 | fp = kmalloc(sizeof(*fp), GFP_KERNEL); | 227 | fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); |
| 228 | if (!fp) | 228 | if (!fp) |
| 229 | return -ENOMEM; | 229 | return -ENOMEM; |
| 230 | memcpy(fp, &ua_format, sizeof(*fp)); | ||
| 231 | 230 | ||
| 232 | fp->iface = altsd->bInterfaceNumber; | 231 | fp->iface = altsd->bInterfaceNumber; |
| 233 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 232 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; |
