diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 20:50:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 20:50:34 -0500 |
commit | e37aa63e87bd581f9be5555ed0ba83f5295c92fc (patch) | |
tree | 83b57ba86bb9526f08ff4ed99e7e432dfceef4f6 /arch | |
parent | 9977d9b379cb77e0f67bd6f4563618106e58e11d (diff) | |
parent | 76583cffb77533fe564aaf21d184b89a5f419ffe (diff) |
Merge tag 'for-linus-20121212' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-mn10300
Pull MN10300 changes from David Howells:
"miscellaneous MN10300 arch patches. I've based it on top of Al Viro's
signal tree - so these patches should be pulled after that."
* tag 'for-linus-20121212' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-mn10300:
MN10300: Use asm-generic/pci_iomap.h
MN10300: Get rid of unused variable from ASB2305 PCI code
MN10300: ASB2305 PCI code needs linux/irq.h
mn10300/mm/fault.c: Port OOM changes to do_page_fault
MN10300: Handle cacheable PCI regions in pci_iomap()
MN10300: fix debug polling in ttySM driver
MN10300: ttySM: clean up unnecessary casting
MN10300: fix SMP synchronization between txdma and serial driver
MN10300: fix serial port vdma irq setup for SMP
MN10300: cleanup IRQ affinity setting
MN10300: ttySM: Use memory barriers correctly in circular buffer logic
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mn10300/include/asm/io.h | 3 | ||||
-rw-r--r-- | arch/mn10300/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/mn10300/kernel/irq.c | 50 | ||||
-rw-r--r-- | arch/mn10300/kernel/mn10300-serial-low.S | 9 | ||||
-rw-r--r-- | arch/mn10300/kernel/mn10300-serial.c | 213 | ||||
-rw-r--r-- | arch/mn10300/kernel/mn10300-serial.h | 10 | ||||
-rw-r--r-- | arch/mn10300/kernel/smp.c | 10 | ||||
-rw-r--r-- | arch/mn10300/mm/fault.c | 33 | ||||
-rw-r--r-- | arch/mn10300/unit-asb2305/pci-iomap.c | 35 | ||||
-rw-r--r-- | arch/mn10300/unit-asb2305/pci.c | 5 |
10 files changed, 234 insertions, 136 deletions
diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h index 139df8c53de8..e6ed0d897ccc 100644 --- a/arch/mn10300/include/asm/io.h +++ b/arch/mn10300/include/asm/io.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/page.h> /* I/O is all done through memory accesses */ | 14 | #include <asm/page.h> /* I/O is all done through memory accesses */ |
15 | #include <asm/cpu-regs.h> | 15 | #include <asm/cpu-regs.h> |
16 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
17 | #include <asm-generic/pci_iomap.h> | ||
17 | 18 | ||
18 | #define mmiowb() do {} while (0) | 19 | #define mmiowb() do {} while (0) |
19 | 20 | ||
@@ -258,7 +259,7 @@ static inline void __iomem *__ioremap(unsigned long offset, unsigned long size, | |||
258 | 259 | ||
259 | static inline void __iomem *ioremap(unsigned long offset, unsigned long size) | 260 | static inline void __iomem *ioremap(unsigned long offset, unsigned long size) |
260 | { | 261 | { |
261 | return (void __iomem *) offset; | 262 | return (void __iomem *)(offset & ~0x20000000); |
262 | } | 263 | } |
263 | 264 | ||
264 | /* | 265 | /* |
diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c index 96f24fab7de6..47b3bb0c04ff 100644 --- a/arch/mn10300/kernel/asm-offsets.c +++ b/arch/mn10300/kernel/asm-offsets.c | |||
@@ -96,7 +96,7 @@ void foo(void) | |||
96 | OFFSET(__rx_outp, mn10300_serial_port, rx_outp); | 96 | OFFSET(__rx_outp, mn10300_serial_port, rx_outp); |
97 | OFFSET(__uart_state, mn10300_serial_port, uart.state); | 97 | OFFSET(__uart_state, mn10300_serial_port, uart.state); |
98 | OFFSET(__tx_xchar, mn10300_serial_port, tx_xchar); | 98 | OFFSET(__tx_xchar, mn10300_serial_port, tx_xchar); |
99 | OFFSET(__tx_break, mn10300_serial_port, tx_break); | 99 | OFFSET(__tx_flags, mn10300_serial_port, tx_flags); |
100 | OFFSET(__intr_flags, mn10300_serial_port, intr_flags); | 100 | OFFSET(__intr_flags, mn10300_serial_port, intr_flags); |
101 | OFFSET(__rx_icr, mn10300_serial_port, rx_icr); | 101 | OFFSET(__rx_icr, mn10300_serial_port, rx_icr); |
102 | OFFSET(__tx_icr, mn10300_serial_port, tx_icr); | 102 | OFFSET(__tx_icr, mn10300_serial_port, tx_icr); |
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index 35932a8de8b8..6ab3b73efcf8 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c | |||
@@ -142,57 +142,11 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask, | |||
142 | bool force) | 142 | bool force) |
143 | { | 143 | { |
144 | unsigned long flags; | 144 | unsigned long flags; |
145 | int err; | ||
146 | 145 | ||
147 | flags = arch_local_cli_save(); | 146 | flags = arch_local_cli_save(); |
148 | 147 | set_bit(d->irq, irq_affinity_request); | |
149 | /* check irq no */ | ||
150 | switch (d->irq) { | ||
151 | case TMJCIRQ: | ||
152 | case RESCHEDULE_IPI: | ||
153 | case CALL_FUNC_SINGLE_IPI: | ||
154 | case LOCAL_TIMER_IPI: | ||
155 | case FLUSH_CACHE_IPI: | ||
156 | case CALL_FUNCTION_NMI_IPI: | ||
157 | case DEBUGGER_NMI_IPI: | ||
158 | #ifdef CONFIG_MN10300_TTYSM0 | ||
159 | case SC0RXIRQ: | ||
160 | case SC0TXIRQ: | ||
161 | #ifdef CONFIG_MN10300_TTYSM0_TIMER8 | ||
162 | case TM8IRQ: | ||
163 | #elif CONFIG_MN10300_TTYSM0_TIMER2 | ||
164 | case TM2IRQ: | ||
165 | #endif /* CONFIG_MN10300_TTYSM0_TIMER8 */ | ||
166 | #endif /* CONFIG_MN10300_TTYSM0 */ | ||
167 | |||
168 | #ifdef CONFIG_MN10300_TTYSM1 | ||
169 | case SC1RXIRQ: | ||
170 | case SC1TXIRQ: | ||
171 | #ifdef CONFIG_MN10300_TTYSM1_TIMER12 | ||
172 | case TM12IRQ: | ||
173 | #elif defined(CONFIG_MN10300_TTYSM1_TIMER9) | ||
174 | case TM9IRQ: | ||
175 | #elif defined(CONFIG_MN10300_TTYSM1_TIMER3) | ||
176 | case TM3IRQ: | ||
177 | #endif /* CONFIG_MN10300_TTYSM1_TIMER12 */ | ||
178 | #endif /* CONFIG_MN10300_TTYSM1 */ | ||
179 | |||
180 | #ifdef CONFIG_MN10300_TTYSM2 | ||
181 | case SC2RXIRQ: | ||
182 | case SC2TXIRQ: | ||
183 | case TM10IRQ: | ||
184 | #endif /* CONFIG_MN10300_TTYSM2 */ | ||
185 | err = -1; | ||
186 | break; | ||
187 | |||
188 | default: | ||
189 | set_bit(d->irq, irq_affinity_request); | ||
190 | err = 0; | ||
191 | break; | ||
192 | } | ||
193 | |||
194 | arch_local_irq_restore(flags); | 148 | arch_local_irq_restore(flags); |
195 | return err; | 149 | return 0; |
196 | } | 150 | } |
197 | #endif /* CONFIG_SMP */ | 151 | #endif /* CONFIG_SMP */ |
198 | 152 | ||
diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S index dfc1b6f2fa9a..b95e76caf4fa 100644 --- a/arch/mn10300/kernel/mn10300-serial-low.S +++ b/arch/mn10300/kernel/mn10300-serial-low.S | |||
@@ -118,8 +118,8 @@ ENTRY(mn10300_serial_vdma_tx_handler) | |||
118 | movbu d2,(e3) # ACK the interrupt | 118 | movbu d2,(e3) # ACK the interrupt |
119 | movhu (e3),d2 # flush | 119 | movhu (e3),d2 # flush |
120 | 120 | ||
121 | btst 0x01,(__tx_break,a3) # handle transmit break request | 121 | btst 0xFF,(__tx_flags,a3) # handle transmit flags |
122 | bne mnsc_vdma_tx_break | 122 | bne mnsc_vdma_tx_flags |
123 | 123 | ||
124 | movbu (SCxSTR,e2),d2 # don't try and transmit a char if the | 124 | movbu (SCxSTR,e2),d2 # don't try and transmit a char if the |
125 | # buffer is not empty | 125 | # buffer is not empty |
@@ -171,10 +171,13 @@ mnsc_vdma_tx_empty: | |||
171 | bset MNSCx_TX_EMPTY,(__intr_flags,a3) | 171 | bset MNSCx_TX_EMPTY,(__intr_flags,a3) |
172 | bra mnsc_vdma_tx_done | 172 | bra mnsc_vdma_tx_done |
173 | 173 | ||
174 | mnsc_vdma_tx_break: | 174 | mnsc_vdma_tx_flags: |
175 | btst MNSCx_TX_STOP,(__tx_flags,a3) | ||
176 | bne mnsc_vdma_tx_stop | ||
175 | movhu (SCxCTR,e2),d2 # turn on break mode | 177 | movhu (SCxCTR,e2),d2 # turn on break mode |
176 | or SC01CTR_BKE,d2 | 178 | or SC01CTR_BKE,d2 |
177 | movhu d2,(SCxCTR,e2) | 179 | movhu d2,(SCxCTR,e2) |
180 | mnsc_vdma_tx_stop: | ||
178 | mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2 | 181 | mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2 |
179 | movhu d2,(e3) # disable transmit interrupts on this | 182 | movhu d2,(e3) # disable transmit interrupts on this |
180 | # channel | 183 | # channel |
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 339cef4c8256..81d5cb9b6569 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c | |||
@@ -408,6 +408,34 @@ static struct irq_chip mn10300_serial_pic = { | |||
408 | .irq_unmask = mn10300_serial_nop, | 408 | .irq_unmask = mn10300_serial_nop, |
409 | }; | 409 | }; |
410 | 410 | ||
411 | static void mn10300_serial_low_mask(struct irq_data *d) | ||
412 | { | ||
413 | unsigned long flags; | ||
414 | u16 tmp; | ||
415 | |||
416 | flags = arch_local_cli_save(); | ||
417 | GxICR(d->irq) = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | ||
418 | tmp = GxICR(d->irq); /* flush write buffer */ | ||
419 | arch_local_irq_restore(flags); | ||
420 | } | ||
421 | |||
422 | static void mn10300_serial_low_unmask(struct irq_data *d) | ||
423 | { | ||
424 | unsigned long flags; | ||
425 | u16 tmp; | ||
426 | |||
427 | flags = arch_local_cli_save(); | ||
428 | GxICR(d->irq) = | ||
429 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE; | ||
430 | tmp = GxICR(d->irq); /* flush write buffer */ | ||
431 | arch_local_irq_restore(flags); | ||
432 | } | ||
433 | |||
434 | static struct irq_chip mn10300_serial_low_pic = { | ||
435 | .name = "mnserial-low", | ||
436 | .irq_mask = mn10300_serial_low_mask, | ||
437 | .irq_unmask = mn10300_serial_low_unmask, | ||
438 | }; | ||
411 | 439 | ||
412 | /* | 440 | /* |
413 | * serial virtual DMA interrupt jump table | 441 | * serial virtual DMA interrupt jump table |
@@ -416,25 +444,53 @@ struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS]; | |||
416 | 444 | ||
417 | static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port) | 445 | static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port) |
418 | { | 446 | { |
419 | unsigned long flags; | 447 | int retries = 100; |
420 | u16 x; | 448 | u16 x; |
421 | 449 | ||
422 | flags = arch_local_cli_save(); | 450 | /* nothing to do if irq isn't set up */ |
423 | *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | 451 | if (!mn10300_serial_int_tbl[port->tx_irq].port) |
424 | x = *port->tx_icr; | 452 | return; |
425 | arch_local_irq_restore(flags); | 453 | |
454 | port->tx_flags |= MNSCx_TX_STOP; | ||
455 | mb(); | ||
456 | |||
457 | /* | ||
458 | * Here we wait for the irq to be disabled. Either it already is | ||
459 | * disabled or we wait some number of retries for the VDMA handler | ||
460 | * to disable it. The retries give the VDMA handler enough time to | ||
461 | * run to completion if it was already in progress. If the VDMA IRQ | ||
462 | * is enabled but the handler is not yet running when arrive here, | ||
463 | * the STOP flag will prevent the handler from conflicting with the | ||
464 | * driver code following this loop. | ||
465 | */ | ||
466 | while ((*port->tx_icr & GxICR_ENABLE) && retries-- > 0) | ||
467 | ; | ||
468 | if (retries <= 0) { | ||
469 | *port->tx_icr = | ||
470 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | ||
471 | x = *port->tx_icr; | ||
472 | } | ||
426 | } | 473 | } |
427 | 474 | ||
428 | static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port) | 475 | static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port) |
429 | { | 476 | { |
430 | unsigned long flags; | ||
431 | u16 x; | 477 | u16 x; |
432 | 478 | ||
433 | flags = arch_local_cli_save(); | 479 | /* nothing to do if irq isn't set up */ |
480 | if (!mn10300_serial_int_tbl[port->tx_irq].port) | ||
481 | return; | ||
482 | |||
483 | /* stop vdma irq if not already stopped */ | ||
484 | if (!(port->tx_flags & MNSCx_TX_STOP)) | ||
485 | mn10300_serial_dis_tx_intr(port); | ||
486 | |||
487 | port->tx_flags &= ~MNSCx_TX_STOP; | ||
488 | mb(); | ||
489 | |||
434 | *port->tx_icr = | 490 | *port->tx_icr = |
435 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE; | 491 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | |
492 | GxICR_ENABLE | GxICR_REQUEST | GxICR_DETECT; | ||
436 | x = *port->tx_icr; | 493 | x = *port->tx_icr; |
437 | arch_local_irq_restore(flags); | ||
438 | } | 494 | } |
439 | 495 | ||
440 | static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port) | 496 | static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port) |
@@ -487,16 +543,17 @@ static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) | |||
487 | 543 | ||
488 | try_again: | 544 | try_again: |
489 | /* pull chars out of the hat */ | 545 | /* pull chars out of the hat */ |
490 | ix = port->rx_outp; | 546 | ix = ACCESS_ONCE(port->rx_outp); |
491 | if (ix == port->rx_inp) { | 547 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) { |
492 | if (push && !tty->low_latency) | 548 | if (push && !tty->low_latency) |
493 | tty_flip_buffer_push(tty); | 549 | tty_flip_buffer_push(tty); |
494 | return; | 550 | return; |
495 | } | 551 | } |
496 | 552 | ||
553 | smp_read_barrier_depends(); | ||
497 | ch = port->rx_buffer[ix++]; | 554 | ch = port->rx_buffer[ix++]; |
498 | st = port->rx_buffer[ix++]; | 555 | st = port->rx_buffer[ix++]; |
499 | smp_rmb(); | 556 | smp_mb(); |
500 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | 557 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); |
501 | port->uart.icount.rx++; | 558 | port->uart.icount.rx++; |
502 | 559 | ||
@@ -778,8 +835,6 @@ static void mn10300_serial_start_tx(struct uart_port *_port) | |||
778 | struct mn10300_serial_port *port = | 835 | struct mn10300_serial_port *port = |
779 | container_of(_port, struct mn10300_serial_port, uart); | 836 | container_of(_port, struct mn10300_serial_port, uart); |
780 | 837 | ||
781 | u16 x; | ||
782 | |||
783 | _enter("%s{%lu}", | 838 | _enter("%s{%lu}", |
784 | port->name, | 839 | port->name, |
785 | CIRC_CNT(&port->uart.state->xmit.head, | 840 | CIRC_CNT(&port->uart.state->xmit.head, |
@@ -787,14 +842,7 @@ static void mn10300_serial_start_tx(struct uart_port *_port) | |||
787 | UART_XMIT_SIZE)); | 842 | UART_XMIT_SIZE)); |
788 | 843 | ||
789 | /* kick the virtual DMA controller */ | 844 | /* kick the virtual DMA controller */ |
790 | arch_local_cli(); | 845 | mn10300_serial_en_tx_intr(port); |
791 | x = *port->tx_icr; | ||
792 | x |= GxICR_ENABLE; | ||
793 | |||
794 | if (*port->_status & SC01STR_TBF) | ||
795 | x &= ~(GxICR_REQUEST | GxICR_DETECT); | ||
796 | else | ||
797 | x |= GxICR_REQUEST | GxICR_DETECT; | ||
798 | 846 | ||
799 | _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx", | 847 | _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx", |
800 | *port->_control, *port->_intr, *port->_status, | 848 | *port->_control, *port->_intr, *port->_status, |
@@ -802,10 +850,6 @@ static void mn10300_serial_start_tx(struct uart_port *_port) | |||
802 | (port->div_timer == MNSCx_DIV_TIMER_8BIT) ? | 850 | (port->div_timer == MNSCx_DIV_TIMER_8BIT) ? |
803 | *(volatile u8 *)port->_tmxbr : *port->_tmxbr, | 851 | *(volatile u8 *)port->_tmxbr : *port->_tmxbr, |
804 | *port->tx_icr); | 852 | *port->tx_icr); |
805 | |||
806 | *port->tx_icr = x; | ||
807 | x = *port->tx_icr; | ||
808 | arch_local_sti(); | ||
809 | } | 853 | } |
810 | 854 | ||
811 | /* | 855 | /* |
@@ -815,13 +859,17 @@ static void mn10300_serial_send_xchar(struct uart_port *_port, char ch) | |||
815 | { | 859 | { |
816 | struct mn10300_serial_port *port = | 860 | struct mn10300_serial_port *port = |
817 | container_of(_port, struct mn10300_serial_port, uart); | 861 | container_of(_port, struct mn10300_serial_port, uart); |
862 | unsigned long flags; | ||
818 | 863 | ||
819 | _enter("%s,%02x", port->name, ch); | 864 | _enter("%s,%02x", port->name, ch); |
820 | 865 | ||
821 | if (likely(port->gdbstub)) { | 866 | if (likely(port->gdbstub)) { |
822 | port->tx_xchar = ch; | 867 | port->tx_xchar = ch; |
823 | if (ch) | 868 | if (ch) { |
869 | spin_lock_irqsave(&port->uart.lock, flags); | ||
824 | mn10300_serial_en_tx_intr(port); | 870 | mn10300_serial_en_tx_intr(port); |
871 | spin_unlock_irqrestore(&port->uart.lock, flags); | ||
872 | } | ||
825 | } | 873 | } |
826 | } | 874 | } |
827 | 875 | ||
@@ -882,18 +930,21 @@ static void mn10300_serial_break_ctl(struct uart_port *_port, int ctl) | |||
882 | { | 930 | { |
883 | struct mn10300_serial_port *port = | 931 | struct mn10300_serial_port *port = |
884 | container_of(_port, struct mn10300_serial_port, uart); | 932 | container_of(_port, struct mn10300_serial_port, uart); |
933 | unsigned long flags; | ||
885 | 934 | ||
886 | _enter("%s,%d", port->name, ctl); | 935 | _enter("%s,%d", port->name, ctl); |
887 | 936 | ||
937 | spin_lock_irqsave(&port->uart.lock, flags); | ||
888 | if (ctl) { | 938 | if (ctl) { |
889 | /* tell the virtual DMA handler to assert BREAK */ | 939 | /* tell the virtual DMA handler to assert BREAK */ |
890 | port->tx_break = 1; | 940 | port->tx_flags |= MNSCx_TX_BREAK; |
891 | mn10300_serial_en_tx_intr(port); | 941 | mn10300_serial_en_tx_intr(port); |
892 | } else { | 942 | } else { |
893 | port->tx_break = 0; | 943 | port->tx_flags &= ~MNSCx_TX_BREAK; |
894 | *port->_control &= ~SC01CTR_BKE; | 944 | *port->_control &= ~SC01CTR_BKE; |
895 | mn10300_serial_en_tx_intr(port); | 945 | mn10300_serial_en_tx_intr(port); |
896 | } | 946 | } |
947 | spin_unlock_irqrestore(&port->uart.lock, flags); | ||
897 | } | 948 | } |
898 | 949 | ||
899 | /* | 950 | /* |
@@ -916,6 +967,7 @@ static int mn10300_serial_startup(struct uart_port *_port) | |||
916 | return -ENOMEM; | 967 | return -ENOMEM; |
917 | 968 | ||
918 | port->rx_inp = port->rx_outp = 0; | 969 | port->rx_inp = port->rx_outp = 0; |
970 | port->tx_flags = 0; | ||
919 | 971 | ||
920 | /* finally, enable the device */ | 972 | /* finally, enable the device */ |
921 | *port->_intr = SC01ICR_TI; | 973 | *port->_intr = SC01ICR_TI; |
@@ -928,22 +980,23 @@ static int mn10300_serial_startup(struct uart_port *_port) | |||
928 | pint->port = port; | 980 | pint->port = port; |
929 | pint->vdma = mn10300_serial_vdma_tx_handler; | 981 | pint->vdma = mn10300_serial_vdma_tx_handler; |
930 | 982 | ||
931 | set_intr_level(port->rx_irq, | 983 | irq_set_chip(port->rx_irq, &mn10300_serial_low_pic); |
932 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)); | 984 | irq_set_chip(port->tx_irq, &mn10300_serial_low_pic); |
933 | set_intr_level(port->tx_irq, | ||
934 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)); | ||
935 | irq_set_chip(port->tm_irq, &mn10300_serial_pic); | 985 | irq_set_chip(port->tm_irq, &mn10300_serial_pic); |
936 | 986 | ||
937 | if (request_irq(port->rx_irq, mn10300_serial_interrupt, | 987 | if (request_irq(port->rx_irq, mn10300_serial_interrupt, |
938 | IRQF_DISABLED, port->rx_name, port) < 0) | 988 | IRQF_DISABLED | IRQF_NOBALANCING, |
989 | port->rx_name, port) < 0) | ||
939 | goto error; | 990 | goto error; |
940 | 991 | ||
941 | if (request_irq(port->tx_irq, mn10300_serial_interrupt, | 992 | if (request_irq(port->tx_irq, mn10300_serial_interrupt, |
942 | IRQF_DISABLED, port->tx_name, port) < 0) | 993 | IRQF_DISABLED | IRQF_NOBALANCING, |
994 | port->tx_name, port) < 0) | ||
943 | goto error2; | 995 | goto error2; |
944 | 996 | ||
945 | if (request_irq(port->tm_irq, mn10300_serial_interrupt, | 997 | if (request_irq(port->tm_irq, mn10300_serial_interrupt, |
946 | IRQF_DISABLED, port->tm_name, port) < 0) | 998 | IRQF_DISABLED | IRQF_NOBALANCING, |
999 | port->tm_name, port) < 0) | ||
947 | goto error3; | 1000 | goto error3; |
948 | mn10300_serial_mask_ack(port->tm_irq); | 1001 | mn10300_serial_mask_ack(port->tm_irq); |
949 | 1002 | ||
@@ -964,14 +1017,22 @@ error: | |||
964 | */ | 1017 | */ |
965 | static void mn10300_serial_shutdown(struct uart_port *_port) | 1018 | static void mn10300_serial_shutdown(struct uart_port *_port) |
966 | { | 1019 | { |
1020 | unsigned long flags; | ||
967 | u16 x; | 1021 | u16 x; |
968 | struct mn10300_serial_port *port = | 1022 | struct mn10300_serial_port *port = |
969 | container_of(_port, struct mn10300_serial_port, uart); | 1023 | container_of(_port, struct mn10300_serial_port, uart); |
970 | 1024 | ||
971 | _enter("%s", port->name); | 1025 | _enter("%s", port->name); |
972 | 1026 | ||
1027 | spin_lock_irqsave(&_port->lock, flags); | ||
1028 | mn10300_serial_dis_tx_intr(port); | ||
1029 | |||
1030 | *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | ||
1031 | x = *port->rx_icr; | ||
1032 | port->tx_flags = 0; | ||
1033 | spin_unlock_irqrestore(&_port->lock, flags); | ||
1034 | |||
973 | /* disable the serial port and its baud rate timer */ | 1035 | /* disable the serial port and its baud rate timer */ |
974 | port->tx_break = 0; | ||
975 | *port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE); | 1036 | *port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE); |
976 | *port->_tmxmd = 0; | 1037 | *port->_tmxmd = 0; |
977 | 1038 | ||
@@ -986,12 +1047,8 @@ static void mn10300_serial_shutdown(struct uart_port *_port) | |||
986 | free_irq(port->rx_irq, port); | 1047 | free_irq(port->rx_irq, port); |
987 | free_irq(port->tx_irq, port); | 1048 | free_irq(port->tx_irq, port); |
988 | 1049 | ||
989 | arch_local_cli(); | 1050 | mn10300_serial_int_tbl[port->tx_irq].port = NULL; |
990 | *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | 1051 | mn10300_serial_int_tbl[port->rx_irq].port = NULL; |
991 | x = *port->rx_icr; | ||
992 | *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | ||
993 | x = *port->tx_icr; | ||
994 | arch_local_sti(); | ||
995 | } | 1052 | } |
996 | 1053 | ||
997 | /* | 1054 | /* |
@@ -1317,7 +1374,8 @@ timer_okay: | |||
1317 | if ((new->c_cflag & CREAD) == 0) | 1374 | if ((new->c_cflag & CREAD) == 0) |
1318 | port->uart.ignore_status_mask |= (1 << TTY_NORMAL); | 1375 | port->uart.ignore_status_mask |= (1 << TTY_NORMAL); |
1319 | 1376 | ||
1320 | scxctr |= *port->_control & (SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE); | 1377 | scxctr |= SC01CTR_TXE | SC01CTR_RXE; |
1378 | scxctr |= *port->_control & SC01CTR_BKE; | ||
1321 | *port->_control = scxctr; | 1379 | *port->_control = scxctr; |
1322 | 1380 | ||
1323 | spin_unlock_irqrestore(&port->uart.lock, flags); | 1381 | spin_unlock_irqrestore(&port->uart.lock, flags); |
@@ -1519,17 +1577,24 @@ static void mn10300_serial_console_write(struct console *co, | |||
1519 | { | 1577 | { |
1520 | struct mn10300_serial_port *port; | 1578 | struct mn10300_serial_port *port; |
1521 | unsigned i; | 1579 | unsigned i; |
1522 | u16 scxctr, txicr, tmp; | 1580 | u16 scxctr; |
1523 | u8 tmxmd; | 1581 | u8 tmxmd; |
1582 | unsigned long flags; | ||
1583 | int locked = 1; | ||
1524 | 1584 | ||
1525 | port = mn10300_serial_ports[co->index]; | 1585 | port = mn10300_serial_ports[co->index]; |
1526 | 1586 | ||
1587 | local_irq_save(flags); | ||
1588 | if (port->uart.sysrq) { | ||
1589 | /* mn10300_serial_interrupt() already took the lock */ | ||
1590 | locked = 0; | ||
1591 | } else if (oops_in_progress) { | ||
1592 | locked = spin_trylock(&port->uart.lock); | ||
1593 | } else | ||
1594 | spin_lock(&port->uart.lock); | ||
1595 | |||
1527 | /* firstly hijack the serial port from the "virtual DMA" controller */ | 1596 | /* firstly hijack the serial port from the "virtual DMA" controller */ |
1528 | arch_local_cli(); | 1597 | mn10300_serial_dis_tx_intr(port); |
1529 | txicr = *port->tx_icr; | ||
1530 | *port->tx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | ||
1531 | tmp = *port->tx_icr; | ||
1532 | arch_local_sti(); | ||
1533 | 1598 | ||
1534 | /* the transmitter may be disabled */ | 1599 | /* the transmitter may be disabled */ |
1535 | scxctr = *port->_control; | 1600 | scxctr = *port->_control; |
@@ -1565,12 +1630,12 @@ static void mn10300_serial_console_write(struct console *co, | |||
1565 | 1630 | ||
1566 | while (*port->_status & SC01STR_TBF) | 1631 | while (*port->_status & SC01STR_TBF) |
1567 | continue; | 1632 | continue; |
1568 | *(u8 *) port->_txb = ch; | 1633 | *port->_txb = ch; |
1569 | 1634 | ||
1570 | if (ch == 0x0a) { | 1635 | if (ch == 0x0a) { |
1571 | while (*port->_status & SC01STR_TBF) | 1636 | while (*port->_status & SC01STR_TBF) |
1572 | continue; | 1637 | continue; |
1573 | *(u8 *) port->_txb = 0xd; | 1638 | *port->_txb = 0xd; |
1574 | } | 1639 | } |
1575 | } | 1640 | } |
1576 | 1641 | ||
@@ -1583,10 +1648,11 @@ static void mn10300_serial_console_write(struct console *co, | |||
1583 | if (!(scxctr & SC01CTR_TXE)) | 1648 | if (!(scxctr & SC01CTR_TXE)) |
1584 | *port->_control = scxctr; | 1649 | *port->_control = scxctr; |
1585 | 1650 | ||
1586 | arch_local_cli(); | 1651 | mn10300_serial_en_tx_intr(port); |
1587 | *port->tx_icr = txicr; | 1652 | |
1588 | tmp = *port->tx_icr; | 1653 | if (locked) |
1589 | arch_local_sti(); | 1654 | spin_unlock(&port->uart.lock); |
1655 | local_irq_restore(flags); | ||
1590 | } | 1656 | } |
1591 | 1657 | ||
1592 | /* | 1658 | /* |
@@ -1655,18 +1721,29 @@ static int mn10300_serial_poll_get_char(struct uart_port *_port) | |||
1655 | 1721 | ||
1656 | _enter("%s", port->name); | 1722 | _enter("%s", port->name); |
1657 | 1723 | ||
1658 | do { | 1724 | if (mn10300_serial_int_tbl[port->rx_irq].port != NULL) { |
1659 | /* pull chars out of the hat */ | 1725 | do { |
1660 | ix = port->rx_outp; | 1726 | /* pull chars out of the hat */ |
1661 | if (ix == port->rx_inp) | 1727 | ix = ACCESS_ONCE(port->rx_outp); |
1662 | return NO_POLL_CHAR; | 1728 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) |
1729 | return NO_POLL_CHAR; | ||
1663 | 1730 | ||
1664 | ch = port->rx_buffer[ix++]; | 1731 | smp_read_barrier_depends(); |
1665 | st = port->rx_buffer[ix++]; | 1732 | ch = port->rx_buffer[ix++]; |
1666 | smp_rmb(); | 1733 | st = port->rx_buffer[ix++]; |
1667 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | 1734 | smp_mb(); |
1735 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | ||
1668 | 1736 | ||
1669 | } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)); | 1737 | } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)); |
1738 | } else { | ||
1739 | do { | ||
1740 | st = *port->_status; | ||
1741 | if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)) | ||
1742 | continue; | ||
1743 | } while (!(st & SC01STR_RBF)); | ||
1744 | |||
1745 | ch = *port->_rxb; | ||
1746 | } | ||
1670 | 1747 | ||
1671 | return ch; | 1748 | return ch; |
1672 | } | 1749 | } |
@@ -1693,12 +1770,12 @@ static void mn10300_serial_poll_put_char(struct uart_port *_port, | |||
1693 | tmp = *port->_intr; | 1770 | tmp = *port->_intr; |
1694 | 1771 | ||
1695 | if (ch == 0x0a) { | 1772 | if (ch == 0x0a) { |
1696 | *(u8 *) port->_txb = 0x0d; | 1773 | *port->_txb = 0x0d; |
1697 | while (*port->_status & SC01STR_TBF) | 1774 | while (*port->_status & SC01STR_TBF) |
1698 | continue; | 1775 | continue; |
1699 | } | 1776 | } |
1700 | 1777 | ||
1701 | *(u8 *) port->_txb = ch; | 1778 | *port->_txb = ch; |
1702 | while (*port->_status & SC01STR_TBF) | 1779 | while (*port->_status & SC01STR_TBF) |
1703 | continue; | 1780 | continue; |
1704 | 1781 | ||
diff --git a/arch/mn10300/kernel/mn10300-serial.h b/arch/mn10300/kernel/mn10300-serial.h index 6796499bf789..01791c68ea1f 100644 --- a/arch/mn10300/kernel/mn10300-serial.h +++ b/arch/mn10300/kernel/mn10300-serial.h | |||
@@ -29,6 +29,10 @@ | |||
29 | #define MNSCx_TX_SPACE 0x04 | 29 | #define MNSCx_TX_SPACE 0x04 |
30 | #define MNSCx_TX_EMPTY 0x08 | 30 | #define MNSCx_TX_EMPTY 0x08 |
31 | 31 | ||
32 | /* tx_flags bits */ | ||
33 | #define MNSCx_TX_BREAK 0x01 | ||
34 | #define MNSCx_TX_STOP 0x02 | ||
35 | |||
32 | #ifndef __ASSEMBLY__ | 36 | #ifndef __ASSEMBLY__ |
33 | 37 | ||
34 | struct mn10300_serial_port { | 38 | struct mn10300_serial_port { |
@@ -36,7 +40,7 @@ struct mn10300_serial_port { | |||
36 | unsigned rx_inp; /* pointer to rx input offset */ | 40 | unsigned rx_inp; /* pointer to rx input offset */ |
37 | unsigned rx_outp; /* pointer to rx output offset */ | 41 | unsigned rx_outp; /* pointer to rx output offset */ |
38 | u8 tx_xchar; /* high-priority XON/XOFF buffer */ | 42 | u8 tx_xchar; /* high-priority XON/XOFF buffer */ |
39 | u8 tx_break; /* transmit break request */ | 43 | u8 tx_flags; /* transmit break/stop request */ |
40 | u8 intr_flags; /* interrupt flags */ | 44 | u8 intr_flags; /* interrupt flags */ |
41 | volatile u16 *rx_icr; /* Rx interrupt control register */ | 45 | volatile u16 *rx_icr; /* Rx interrupt control register */ |
42 | volatile u16 *tx_icr; /* Tx interrupt control register */ | 46 | volatile u16 *tx_icr; /* Tx interrupt control register */ |
@@ -54,8 +58,8 @@ struct mn10300_serial_port { | |||
54 | volatile u16 *_control; /* control register pointer */ | 58 | volatile u16 *_control; /* control register pointer */ |
55 | volatile u8 *_status; /* status register pointer */ | 59 | volatile u8 *_status; /* status register pointer */ |
56 | volatile u8 *_intr; /* interrupt register pointer */ | 60 | volatile u8 *_intr; /* interrupt register pointer */ |
57 | volatile void *_rxb; /* receive buffer register pointer */ | 61 | volatile u8 *_rxb; /* receive buffer register pointer */ |
58 | volatile void *_txb; /* transmit buffer register pointer */ | 62 | volatile u8 *_txb; /* transmit buffer register pointer */ |
59 | volatile u16 *_tmicr; /* timer interrupt control register */ | 63 | volatile u16 *_tmicr; /* timer interrupt control register */ |
60 | volatile u8 *_tmxmd; /* baud rate timer mode register */ | 64 | volatile u8 *_tmxmd; /* baud rate timer mode register */ |
61 | volatile u16 *_tmxbr; /* baud rate timer base register */ | 65 | volatile u16 *_tmxbr; /* baud rate timer base register */ |
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index e62c223e4c45..95983cd21e77 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c | |||
@@ -130,10 +130,12 @@ static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id); | |||
130 | 130 | ||
131 | static struct irqaction reschedule_ipi = { | 131 | static struct irqaction reschedule_ipi = { |
132 | .handler = smp_reschedule_interrupt, | 132 | .handler = smp_reschedule_interrupt, |
133 | .flags = IRQF_NOBALANCING, | ||
133 | .name = "smp reschedule IPI" | 134 | .name = "smp reschedule IPI" |
134 | }; | 135 | }; |
135 | static struct irqaction call_function_ipi = { | 136 | static struct irqaction call_function_ipi = { |
136 | .handler = smp_call_function_interrupt, | 137 | .handler = smp_call_function_interrupt, |
138 | .flags = IRQF_NOBALANCING, | ||
137 | .name = "smp call function IPI" | 139 | .name = "smp call function IPI" |
138 | }; | 140 | }; |
139 | 141 | ||
@@ -141,7 +143,7 @@ static struct irqaction call_function_ipi = { | |||
141 | static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id); | 143 | static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id); |
142 | static struct irqaction local_timer_ipi = { | 144 | static struct irqaction local_timer_ipi = { |
143 | .handler = smp_ipi_timer_interrupt, | 145 | .handler = smp_ipi_timer_interrupt, |
144 | .flags = IRQF_DISABLED, | 146 | .flags = IRQF_DISABLED | IRQF_NOBALANCING, |
145 | .name = "smp local timer IPI" | 147 | .name = "smp local timer IPI" |
146 | }; | 148 | }; |
147 | #endif | 149 | #endif |
@@ -180,6 +182,7 @@ static void init_ipi(void) | |||
180 | 182 | ||
181 | #ifdef CONFIG_MN10300_CACHE_ENABLED | 183 | #ifdef CONFIG_MN10300_CACHE_ENABLED |
182 | /* set up the cache flush IPI */ | 184 | /* set up the cache flush IPI */ |
185 | irq_set_chip(FLUSH_CACHE_IPI, &mn10300_ipi_type); | ||
183 | flags = arch_local_cli_save(); | 186 | flags = arch_local_cli_save(); |
184 | __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(FLUSH_CACHE_GxICR_LV), | 187 | __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(FLUSH_CACHE_GxICR_LV), |
185 | mn10300_low_ipi_handler); | 188 | mn10300_low_ipi_handler); |
@@ -189,6 +192,7 @@ static void init_ipi(void) | |||
189 | #endif | 192 | #endif |
190 | 193 | ||
191 | /* set up the NMI call function IPI */ | 194 | /* set up the NMI call function IPI */ |
195 | irq_set_chip(CALL_FUNCTION_NMI_IPI, &mn10300_ipi_type); | ||
192 | flags = arch_local_cli_save(); | 196 | flags = arch_local_cli_save(); |
193 | GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; | 197 | GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT; |
194 | tmp16 = GxICR(CALL_FUNCTION_NMI_IPI); | 198 | tmp16 = GxICR(CALL_FUNCTION_NMI_IPI); |
@@ -199,6 +203,10 @@ static void init_ipi(void) | |||
199 | __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(SMP_BOOT_GxICR_LV), | 203 | __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(SMP_BOOT_GxICR_LV), |
200 | mn10300_low_ipi_handler); | 204 | mn10300_low_ipi_handler); |
201 | arch_local_irq_restore(flags); | 205 | arch_local_irq_restore(flags); |
206 | |||
207 | #ifdef CONFIG_KERNEL_DEBUGGER | ||
208 | irq_set_chip(DEBUGGER_NMI_IPI, &mn10300_ipi_type); | ||
209 | #endif | ||
202 | } | 210 | } |
203 | 211 | ||
204 | /** | 212 | /** |
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c index 90f346f7392d..d48a84fd7fae 100644 --- a/arch/mn10300/mm/fault.c +++ b/arch/mn10300/mm/fault.c | |||
@@ -123,7 +123,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code, | |||
123 | struct mm_struct *mm; | 123 | struct mm_struct *mm; |
124 | unsigned long page; | 124 | unsigned long page; |
125 | siginfo_t info; | 125 | siginfo_t info; |
126 | int write, fault; | 126 | int fault; |
127 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | ||
127 | 128 | ||
128 | #ifdef CONFIG_GDBSTUB | 129 | #ifdef CONFIG_GDBSTUB |
129 | /* handle GDB stub causing a fault */ | 130 | /* handle GDB stub causing a fault */ |
@@ -170,6 +171,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code, | |||
170 | if (in_atomic() || !mm) | 171 | if (in_atomic() || !mm) |
171 | goto no_context; | 172 | goto no_context; |
172 | 173 | ||
174 | retry: | ||
173 | down_read(&mm->mmap_sem); | 175 | down_read(&mm->mmap_sem); |
174 | 176 | ||
175 | vma = find_vma(mm, address); | 177 | vma = find_vma(mm, address); |
@@ -220,7 +222,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code, | |||
220 | */ | 222 | */ |
221 | good_area: | 223 | good_area: |
222 | info.si_code = SEGV_ACCERR; | 224 | info.si_code = SEGV_ACCERR; |
223 | write = 0; | ||
224 | switch (fault_code & (MMUFCR_xFC_PGINVAL|MMUFCR_xFC_TYPE)) { | 225 | switch (fault_code & (MMUFCR_xFC_PGINVAL|MMUFCR_xFC_TYPE)) { |
225 | default: /* 3: write, present */ | 226 | default: /* 3: write, present */ |
226 | case MMUFCR_xFC_TYPE_WRITE: | 227 | case MMUFCR_xFC_TYPE_WRITE: |
@@ -232,7 +233,7 @@ good_area: | |||
232 | case MMUFCR_xFC_PGINVAL | MMUFCR_xFC_TYPE_WRITE: | 233 | case MMUFCR_xFC_PGINVAL | MMUFCR_xFC_TYPE_WRITE: |
233 | if (!(vma->vm_flags & VM_WRITE)) | 234 | if (!(vma->vm_flags & VM_WRITE)) |
234 | goto bad_area; | 235 | goto bad_area; |
235 | write++; | 236 | flags |= FAULT_FLAG_WRITE; |
236 | break; | 237 | break; |
237 | 238 | ||
238 | /* read from protected page */ | 239 | /* read from protected page */ |
@@ -251,7 +252,11 @@ good_area: | |||
251 | * make sure we exit gracefully rather than endlessly redo | 252 | * make sure we exit gracefully rather than endlessly redo |
252 | * the fault. | 253 | * the fault. |
253 | */ | 254 | */ |
254 | fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); | 255 | fault = handle_mm_fault(mm, vma, address, flags); |
256 | |||
257 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
258 | return; | ||
259 | |||
255 | if (unlikely(fault & VM_FAULT_ERROR)) { | 260 | if (unlikely(fault & VM_FAULT_ERROR)) { |
256 | if (fault & VM_FAULT_OOM) | 261 | if (fault & VM_FAULT_OOM) |
257 | goto out_of_memory; | 262 | goto out_of_memory; |
@@ -259,10 +264,22 @@ good_area: | |||
259 | goto do_sigbus; | 264 | goto do_sigbus; |
260 | BUG(); | 265 | BUG(); |
261 | } | 266 | } |
262 | if (fault & VM_FAULT_MAJOR) | 267 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
263 | current->maj_flt++; | 268 | if (fault & VM_FAULT_MAJOR) |
264 | else | 269 | current->maj_flt++; |
265 | current->min_flt++; | 270 | else |
271 | current->min_flt++; | ||
272 | if (fault & VM_FAULT_RETRY) { | ||
273 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
274 | |||
275 | /* No need to up_read(&mm->mmap_sem) as we would | ||
276 | * have already released it in __lock_page_or_retry | ||
277 | * in mm/filemap.c. | ||
278 | */ | ||
279 | |||
280 | goto retry; | ||
281 | } | ||
282 | } | ||
266 | 283 | ||
267 | up_read(&mm->mmap_sem); | 284 | up_read(&mm->mmap_sem); |
268 | return; | 285 | return; |
diff --git a/arch/mn10300/unit-asb2305/pci-iomap.c b/arch/mn10300/unit-asb2305/pci-iomap.c new file mode 100644 index 000000000000..bd65dae17f32 --- /dev/null +++ b/arch/mn10300/unit-asb2305/pci-iomap.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* ASB2305 PCI I/O mapping handler | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/pci.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | /* | ||
15 | * Create a virtual mapping cookie for a PCI BAR (memory or IO) | ||
16 | */ | ||
17 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | ||
18 | { | ||
19 | resource_size_t start = pci_resource_start(dev, bar); | ||
20 | resource_size_t len = pci_resource_len(dev, bar); | ||
21 | unsigned long flags = pci_resource_flags(dev, bar); | ||
22 | |||
23 | if (!len || !start) | ||
24 | return NULL; | ||
25 | |||
26 | if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM)) { | ||
27 | if (flags & IORESOURCE_CACHEABLE && !(flags & IORESOURCE_IO)) | ||
28 | return ioremap(start, len); | ||
29 | else | ||
30 | return ioremap_nocache(start, len); | ||
31 | } | ||
32 | |||
33 | return NULL; | ||
34 | } | ||
35 | EXPORT_SYMBOL(pci_iomap); | ||
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index 6dce9fc2cf3c..e2059486d3f8 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/irq.h> | ||
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
21 | #include "pci-asb2305.h" | 22 | #include "pci-asb2305.h" |
22 | 23 | ||
@@ -303,9 +304,7 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | |||
303 | 304 | ||
304 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 305 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
305 | { | 306 | { |
306 | struct pci_bus_region region; | 307 | int limit, i; |
307 | int i; | ||
308 | int limit; | ||
309 | 308 | ||
310 | if (dev->bus->number != 0) | 309 | if (dev->bus->number != 0) |
311 | return; | 310 | return; |