Commit e37aa63e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-20121212' of...

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
parents 9977d9b3 76583cff
......@@ -14,6 +14,7 @@
#include <asm/page.h> /* I/O is all done through memory accesses */
#include <asm/cpu-regs.h>
#include <asm/cacheflush.h>
#include <asm-generic/pci_iomap.h>
#define mmiowb() do {} while (0)
......@@ -258,7 +259,7 @@ static inline void __iomem *__ioremap(unsigned long offset, unsigned long size,
static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
return (void __iomem *) offset;
return (void __iomem *)(offset & ~0x20000000);
}
/*
......
......@@ -96,7 +96,7 @@ void foo(void)
OFFSET(__rx_outp, mn10300_serial_port, rx_outp);
OFFSET(__uart_state, mn10300_serial_port, uart.state);
OFFSET(__tx_xchar, mn10300_serial_port, tx_xchar);
OFFSET(__tx_break, mn10300_serial_port, tx_break);
OFFSET(__tx_flags, mn10300_serial_port, tx_flags);
OFFSET(__intr_flags, mn10300_serial_port, intr_flags);
OFFSET(__rx_icr, mn10300_serial_port, rx_icr);
OFFSET(__tx_icr, mn10300_serial_port, tx_icr);
......
......@@ -142,57 +142,11 @@ mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask,
bool force)
{
unsigned long flags;
int err;
flags = arch_local_cli_save();
/* check irq no */
switch (d->irq) {
case TMJCIRQ:
case RESCHEDULE_IPI:
case CALL_FUNC_SINGLE_IPI:
case LOCAL_TIMER_IPI:
case FLUSH_CACHE_IPI:
case CALL_FUNCTION_NMI_IPI:
case DEBUGGER_NMI_IPI:
#ifdef CONFIG_MN10300_TTYSM0
case SC0RXIRQ:
case SC0TXIRQ:
#ifdef CONFIG_MN10300_TTYSM0_TIMER8
case TM8IRQ:
#elif CONFIG_MN10300_TTYSM0_TIMER2
case TM2IRQ:
#endif /* CONFIG_MN10300_TTYSM0_TIMER8 */
#endif /* CONFIG_MN10300_TTYSM0 */
#ifdef CONFIG_MN10300_TTYSM1
case SC1RXIRQ:
case SC1TXIRQ:
#ifdef CONFIG_MN10300_TTYSM1_TIMER12
case TM12IRQ:
#elif defined(CONFIG_MN10300_TTYSM1_TIMER9)
case TM9IRQ:
#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
case TM3IRQ:
#endif /* CONFIG_MN10300_TTYSM1_TIMER12 */
#endif /* CONFIG_MN10300_TTYSM1 */
#ifdef CONFIG_MN10300_TTYSM2
case SC2RXIRQ:
case SC2TXIRQ:
case TM10IRQ:
#endif /* CONFIG_MN10300_TTYSM2 */
err = -1;
break;
default:
set_bit(d->irq, irq_affinity_request);
err = 0;
break;
}
arch_local_irq_restore(flags);
return err;
return 0;
}
#endif /* CONFIG_SMP */
......
......@@ -118,8 +118,8 @@ ENTRY(mn10300_serial_vdma_tx_handler)
movbu d2,(e3) # ACK the interrupt
movhu (e3),d2 # flush
btst 0x01,(__tx_break,a3) # handle transmit break request
bne mnsc_vdma_tx_break
btst 0xFF,(__tx_flags,a3) # handle transmit flags
bne mnsc_vdma_tx_flags
movbu (SCxSTR,e2),d2 # don't try and transmit a char if the
# buffer is not empty
......@@ -171,10 +171,13 @@ mnsc_vdma_tx_empty:
bset MNSCx_TX_EMPTY,(__intr_flags,a3)
bra mnsc_vdma_tx_done
mnsc_vdma_tx_break:
mnsc_vdma_tx_flags:
btst MNSCx_TX_STOP,(__tx_flags,a3)
bne mnsc_vdma_tx_stop
movhu (SCxCTR,e2),d2 # turn on break mode
or SC01CTR_BKE,d2
movhu d2,(SCxCTR,e2)
mnsc_vdma_tx_stop:
mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
movhu d2,(e3) # disable transmit interrupts on this
# channel
......
This diff is collapsed.
......@@ -29,6 +29,10 @@
#define MNSCx_TX_SPACE 0x04
#define MNSCx_TX_EMPTY 0x08
/* tx_flags bits */
#define MNSCx_TX_BREAK 0x01
#define MNSCx_TX_STOP 0x02
#ifndef __ASSEMBLY__
struct mn10300_serial_port {
......@@ -36,7 +40,7 @@ struct mn10300_serial_port {
unsigned rx_inp; /* pointer to rx input offset */
unsigned rx_outp; /* pointer to rx output offset */
u8 tx_xchar; /* high-priority XON/XOFF buffer */
u8 tx_break; /* transmit break request */
u8 tx_flags; /* transmit break/stop request */
u8 intr_flags; /* interrupt flags */
volatile u16 *rx_icr; /* Rx interrupt control register */
volatile u16 *tx_icr; /* Tx interrupt control register */
......@@ -54,8 +58,8 @@ struct mn10300_serial_port {
volatile u16 *_control; /* control register pointer */
volatile u8 *_status; /* status register pointer */
volatile u8 *_intr; /* interrupt register pointer */
volatile void *_rxb; /* receive buffer register pointer */
volatile void *_txb; /* transmit buffer register pointer */
volatile u8 *_rxb; /* receive buffer register pointer */
volatile u8 *_txb; /* transmit buffer register pointer */
volatile u16 *_tmicr; /* timer interrupt control register */
volatile u8 *_tmxmd; /* baud rate timer mode register */
volatile u16 *_tmxbr; /* baud rate timer base register */
......
......@@ -130,10 +130,12 @@ static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id);
static struct irqaction reschedule_ipi = {
.handler = smp_reschedule_interrupt,
.flags = IRQF_NOBALANCING,
.name = "smp reschedule IPI"
};
static struct irqaction call_function_ipi = {
.handler = smp_call_function_interrupt,
.flags = IRQF_NOBALANCING,
.name = "smp call function IPI"
};
......@@ -141,7 +143,7 @@ static struct irqaction call_function_ipi = {
static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id);
static struct irqaction local_timer_ipi = {
.handler = smp_ipi_timer_interrupt,
.flags = IRQF_DISABLED,
.flags = IRQF_DISABLED | IRQF_NOBALANCING,
.name = "smp local timer IPI"
};
#endif
......@@ -180,6 +182,7 @@ static void init_ipi(void)
#ifdef CONFIG_MN10300_CACHE_ENABLED
/* set up the cache flush IPI */
irq_set_chip(FLUSH_CACHE_IPI, &mn10300_ipi_type);
flags = arch_local_cli_save();
__set_intr_stub(NUM2EXCEP_IRQ_LEVEL(FLUSH_CACHE_GxICR_LV),
mn10300_low_ipi_handler);
......@@ -189,6 +192,7 @@ static void init_ipi(void)
#endif
/* set up the NMI call function IPI */
irq_set_chip(CALL_FUNCTION_NMI_IPI, &mn10300_ipi_type);
flags = arch_local_cli_save();
GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
......@@ -199,6 +203,10 @@ static void init_ipi(void)
__set_intr_stub(NUM2EXCEP_IRQ_LEVEL(SMP_BOOT_GxICR_LV),
mn10300_low_ipi_handler);
arch_local_irq_restore(flags);
#ifdef CONFIG_KERNEL_DEBUGGER
irq_set_chip(DEBUGGER_NMI_IPI, &mn10300_ipi_type);
#endif
}
/**
......
......@@ -123,7 +123,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
struct mm_struct *mm;
unsigned long page;
siginfo_t info;
int write, fault;
int fault;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
#ifdef CONFIG_GDBSTUB
/* handle GDB stub causing a fault */
......@@ -170,6 +171,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
if (in_atomic() || !mm)
goto no_context;
retry:
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
......@@ -220,7 +222,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
*/
good_area:
info.si_code = SEGV_ACCERR;
write = 0;
switch (fault_code & (MMUFCR_xFC_PGINVAL|MMUFCR_xFC_TYPE)) {
default: /* 3: write, present */
case MMUFCR_xFC_TYPE_WRITE:
......@@ -232,7 +233,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
case MMUFCR_xFC_PGINVAL | MMUFCR_xFC_TYPE_WRITE:
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
write++;
flags |= FAULT_FLAG_WRITE;
break;
/* read from protected page */
......@@ -251,7 +252,11 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
fault = handle_mm_fault(mm, vma, address, flags);
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
return;
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
......@@ -259,10 +264,22 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
goto do_sigbus;
BUG();
}
if (flags & FAULT_FLAG_ALLOW_RETRY) {
if (fault & VM_FAULT_MAJOR)
current->maj_flt++;
else
current->min_flt++;
if (fault & VM_FAULT_RETRY) {
flags &= ~FAULT_FLAG_ALLOW_RETRY;
/* No need to up_read(&mm->mmap_sem) as we would
* have already released it in __lock_page_or_retry
* in mm/filemap.c.
*/
goto retry;
}
}
up_read(&mm->mmap_sem);
return;
......
/* ASB2305 PCI I/O mapping handler
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#include <linux/pci.h>
#include <linux/module.h>
/*
* Create a virtual mapping cookie for a PCI BAR (memory or IO)
*/
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
resource_size_t start = pci_resource_start(dev, bar);
resource_size_t len = pci_resource_len(dev, bar);
unsigned long flags = pci_resource_flags(dev, bar);
if (!len || !start)
return NULL;
if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM)) {
if (flags & IORESOURCE_CACHEABLE && !(flags & IORESOURCE_IO))
return ioremap(start, len);
else
return ioremap_nocache(start, len);
}
return NULL;
}
EXPORT_SYMBOL(pci_iomap);
......@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/io.h>
#include "pci-asb2305.h"
......@@ -303,9 +304,7 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
{
struct pci_bus_region region;
int i;
int limit;
int limit, i;
if (dev->bus->number != 0)
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment