Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller:
"Various sparc bug fixes, in particular:
1) TSB hashes have to be flushed before TLB on sparc64, from Dave
Kleikamp.
2) LEON timer interrupts can get stuck, from Andreas Larsson.
3) Sparc64 needs to handle lack of address-congruence devicetree
property, from Bob Picco"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc: tsb must be flushed before tlb
sparc,leon: Convert to use devm_ioremap_resource
sparc64 address-congruence property
sparc32, leon: Enable interrupts before going idle to avoid getting stuck
sparc32, leon: Remove separate "ticker" timer for SMP
sparc: kernel: using strlcpy() instead of strcpy()
arch: sparc: prom: looping issue, need additional length check in the outside looping
sparc: remove inline marking of EXPORT_SYMBOL functions
sparc: Switch to asm-generic/linkage.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 49d993c..2651b1d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1189,6 +1189,16 @@
is not correctly implemented in PL310 as clean lines are not
invalidated as a result of these operations.
+config ARM_ERRATA_643719
+ bool "ARM errata: LoUIS bit field in CLIDR register is incorrect"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 643719 Cortex-A9 (prior to
+ r1p0) erratum. On affected cores the LoUIS bit field of the CLIDR
+ register returns zero when it should return one. The workaround
+ corrects this value, ensuring cache maintenance operations which use
+ it behave as intended and avoiding data corruption.
+
config ARM_ERRATA_720789
bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
depends on CPU_V7
@@ -2006,7 +2016,7 @@
config KEXEC
bool "Kexec system call (EXPERIMENTAL)"
- depends on (!SMP || HOTPLUG_CPU)
+ depends on (!SMP || PM_SLEEP_SMP)
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 79e9bdb..120b83b 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -116,7 +116,8 @@
# Make sure files are removed during clean
extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \
- lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs)
+ lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \
+ hyp-stub.S
ifeq ($(CONFIG_FUNCTION_TRACER),y)
ORIG_CFLAGS := $(KBUILD_CFLAGS)
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index bff7138..17d0ae8 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -320,9 +320,7 @@
}
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
-static inline void flush_kernel_dcache_page(struct page *page)
-{
-}
+extern void flush_kernel_dcache_page(struct page *);
#define flush_dcache_mmap_lock(mapping) \
spin_lock_irq(&(mapping)->tree_lock)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 8ef8c93..4fb074c 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -134,6 +134,10 @@
unsigned long reboot_code_buffer_phys;
void *reboot_code_buffer;
+ if (num_online_cpus() > 1) {
+ pr_err("kexec: error: multiple CPUs still online\n");
+ return;
+ }
page_list = image->head & PAGE_MASK;
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 282de48..6e8931c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -184,30 +184,61 @@
__setup("reboot=", reboot_setup);
+/*
+ * Called by kexec, immediately prior to machine_kexec().
+ *
+ * This must completely disable all secondary CPUs; simply causing those CPUs
+ * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
+ * kexec'd kernel to use any and all RAM as it sees fit, without having to
+ * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
+ * functionality embodied in disable_nonboot_cpus() to achieve this.
+ */
void machine_shutdown(void)
{
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
+ disable_nonboot_cpus();
}
+/*
+ * Halting simply requires that the secondary CPUs stop performing any
+ * activity (executing tasks, handling interrupts). smp_send_stop()
+ * achieves this.
+ */
void machine_halt(void)
{
- machine_shutdown();
+ smp_send_stop();
+
local_irq_disable();
while (1);
}
+/*
+ * Power-off simply requires that the secondary CPUs stop performing any
+ * activity (executing tasks, handling interrupts). smp_send_stop()
+ * achieves this. When the system power is turned off, it will take all CPUs
+ * with it.
+ */
void machine_power_off(void)
{
- machine_shutdown();
+ smp_send_stop();
+
if (pm_power_off)
pm_power_off();
}
+/*
+ * Restart requires that the secondary CPUs stop performing any activity
+ * while the primary CPU resets the system. Systems with a single CPU can
+ * use soft_restart() as their machine descriptor's .restart hook, since that
+ * will cause the only available CPU to reset. Systems with multiple CPUs must
+ * provide a HW restart implementation, to ensure that all CPUs reset at once.
+ * This is required so that any code running after reset on the primary CPU
+ * doesn't have to co-ordinate with other CPUs to ensure they aren't still
+ * executing pre-reset code, and using RAM that the primary CPU's code wishes
+ * to use. Implementing such co-ordination would be essentially impossible.
+ */
void machine_restart(char *cmd)
{
- machine_shutdown();
+ smp_send_stop();
arm_pm_restart(reboot_mode, cmd);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 550d63c..5919eb4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -651,17 +651,6 @@
smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
}
-#ifdef CONFIG_HOTPLUG_CPU
-static void smp_kill_cpus(cpumask_t *mask)
-{
- unsigned int cpu;
- for_each_cpu(cpu, mask)
- platform_cpu_kill(cpu);
-}
-#else
-static void smp_kill_cpus(cpumask_t *mask) { }
-#endif
-
void smp_send_stop(void)
{
unsigned long timeout;
@@ -679,8 +668,6 @@
if (num_online_cpus() > 1)
pr_warning("SMP: failed to stop secondary CPUs\n");
-
- smp_kill_cpus(&mask);
}
/*
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 15451ee..515b000 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -92,6 +92,14 @@
mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr
ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr
ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr
+#ifdef CONFIG_ARM_ERRATA_643719
+ ALT_SMP(mrceq p15, 0, r2, c0, c0, 0) @ read main ID register
+ ALT_UP(moveq pc, lr) @ LoUU is zero, so nothing to do
+ ldreq r1, =0x410fc090 @ ID of ARM Cortex A9 r0p?
+ biceq r2, r2, #0x0000000f @ clear minor revision number
+ teqeq r2, r1 @ test for errata affected core and if so...
+ orreqs r3, #(1 << 21) @ fix LoUIS value (and set flags state to 'ne')
+#endif
ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2
ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2
moveq pc, lr @ return if level == 0
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 0d473cc..32aa586 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -301,6 +301,39 @@
EXPORT_SYMBOL(flush_dcache_page);
/*
+ * Ensure cache coherency for the kernel mapping of this page. We can
+ * assume that the page is pinned via kmap.
+ *
+ * If the page only exists in the page cache and there are no user
+ * space mappings, this is a no-op since the page was already marked
+ * dirty at creation. Otherwise, we need to flush the dirty kernel
+ * cache lines directly.
+ */
+void flush_kernel_dcache_page(struct page *page)
+{
+ if (cache_is_vivt() || cache_is_vipt_aliasing()) {
+ struct address_space *mapping;
+
+ mapping = page_mapping(page);
+
+ if (!mapping || mapping_mapped(mapping)) {
+ void *addr;
+
+ addr = page_address(page);
+ /*
+ * kmap_atomic() doesn't set the page virtual
+ * address for highmem pages, and
+ * kunmap_atomic() takes care of cache
+ * flushing already.
+ */
+ if (!IS_ENABLED(CONFIG_HIGHMEM) || addr)
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ }
+ }
+}
+EXPORT_SYMBOL(flush_kernel_dcache_page);
+
+/*
* Flush an anonymous page so that users of get_user_pages()
* can safely access the data. The expected sequence is:
*
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index e0d8565..4d409e6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -616,10 +616,12 @@
} while (pte++, addr += PAGE_SIZE, addr != end);
}
-static void __init map_init_section(pmd_t *pmd, unsigned long addr,
+static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
unsigned long end, phys_addr_t phys,
const struct mem_type *type)
{
+ pmd_t *p = pmd;
+
#ifndef CONFIG_ARM_LPAE
/*
* In classic MMU format, puds and pmds are folded in to
@@ -638,7 +640,7 @@
phys += SECTION_SIZE;
} while (pmd++, addr += SECTION_SIZE, addr != end);
- flush_pmd_entry(pmd);
+ flush_pmd_entry(p);
}
static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
@@ -661,7 +663,7 @@
*/
if (type->prot_sect &&
((addr | next | phys) & ~SECTION_MASK) == 0) {
- map_init_section(pmd, addr, next, phys, type);
+ __map_init_section(pmd, addr, next, phys, type);
} else {
alloc_init_pte(pmd, addr, next,
__phys_to_pfn(phys), type);
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 2c73a73..4c8c9c1 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -409,8 +409,8 @@
*/
.type __v7_pj4b_proc_info, #object
__v7_pj4b_proc_info:
- .long 0x562f5840
- .long 0xfffffff0
+ .long 0x560f5800
+ .long 0xff0fff00
__v7_proc __v7_pj4b_setup
.size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h
index f545477..471f481 100644
--- a/arch/metag/include/asm/hugetlb.h
+++ b/arch/metag/include/asm/hugetlb.h
@@ -2,6 +2,7 @@
#define _ASM_METAG_HUGETLB_H
#include <asm/page.h>
+#include <asm-generic/hugetlb.h>
static inline int is_hugepage_only_range(struct mm_struct *mm,
diff --git a/arch/parisc/include/asm/mmzone.h b/arch/parisc/include/asm/mmzone.h
index cc50d33..b6b34a0 100644
--- a/arch/parisc/include/asm/mmzone.h
+++ b/arch/parisc/include/asm/mmzone.h
@@ -27,7 +27,7 @@
#define PFNNID_SHIFT (30 - PAGE_SHIFT)
#define PFNNID_MAP_MAX 512 /* support 512GB */
-extern unsigned char pfnnid_map[PFNNID_MAP_MAX];
+extern signed char pfnnid_map[PFNNID_MAP_MAX];
#ifndef CONFIG_64BIT
#define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT))
@@ -46,7 +46,7 @@
i = pfn >> PFNNID_SHIFT;
BUG_ON(i >= ARRAY_SIZE(pfnnid_map));
- return (int)pfnnid_map[i];
+ return pfnnid_map[i];
}
static inline int pfn_valid(int pfn)
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 3234f49..4651540 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -225,4 +225,9 @@
return channel ? 15 : 14;
}
+#define HAVE_PCI_MMAP
+
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
+
#endif /* __ASM_PARISC_PCI_H */
diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c
index 9e2d2e4..8722756 100644
--- a/arch/parisc/kernel/hardware.c
+++ b/arch/parisc/kernel/hardware.c
@@ -1205,6 +1205,7 @@
{HPHW_FIO, 0x004, 0x00320, 0x0, "Metheus Frame Buffer"},
{HPHW_FIO, 0x004, 0x00340, 0x0, "BARCO CX4500 VME Grphx Cnsl"},
{HPHW_FIO, 0x004, 0x00360, 0x0, "Hughes TOG VME FDDI"},
+ {HPHW_FIO, 0x076, 0x000AD, 0x00, "Crestone Peak RS-232"},
{HPHW_IOA, 0x185, 0x0000B, 0x00, "Java BC Summit Port"},
{HPHW_IOA, 0x1FF, 0x0000B, 0x00, "Hitachi Ghostview Summit Port"},
{HPHW_IOA, 0x580, 0x0000B, 0x10, "U2-IOA BC Runway Port"},
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 36d7f40..b743a80 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -860,7 +860,7 @@
#endif
ldil L%dcache_stride, %r1
- ldw R%dcache_stride(%r1), %r1
+ ldw R%dcache_stride(%r1), r31
#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
@@ -868,26 +868,26 @@
depwi,z 1, 31-PAGE_SHIFT,1, %r25
#endif
add %r28, %r25, %r25
- sub %r25, %r1, %r25
+ sub %r25, r31, %r25
-1: fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
- fdc,m %r1(%r28)
+1: fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
+ fdc,m r31(%r28)
cmpb,COND(<<) %r28, %r25,1b
- fdc,m %r1(%r28)
+ fdc,m r31(%r28)
sync
@@ -936,7 +936,7 @@
#endif
ldil L%icache_stride, %r1
- ldw R%icache_stride(%r1), %r1
+ ldw R%icache_stride(%r1), %r31
#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
@@ -944,28 +944,28 @@
depwi,z 1, 31-PAGE_SHIFT,1, %r25
#endif
add %r28, %r25, %r25
- sub %r25, %r1, %r25
+ sub %r25, %r31, %r25
/* fic only has the type 26 form on PA1.1, requiring an
* explicit space specification, so use %sr4 */
-1: fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
- fic,m %r1(%sr4,%r28)
+1: fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
cmpb,COND(<<) %r28, %r25,1b
- fic,m %r1(%sr4,%r28)
+ fic,m %r31(%sr4,%r28)
sync
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 6030905..64f2764 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -220,6 +220,33 @@
}
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ unsigned long prot;
+
+ /*
+ * I/O space can be accessed via normal processor loads and stores on
+ * this platform but for now we elect not to do this and portable
+ * drivers should not do this anyway.
+ */
+ if (mmap_state == pci_mmap_io)
+ return -EINVAL;
+
+ if (write_combine)
+ return -EINVAL;
+
+ /*
+ * Ignore write-combine; for now only return uncached mappings.
+ */
+ prot = pgprot_val(vma->vm_page_prot);
+ prot |= _PAGE_NO_CACHE;
+ vma->vm_page_prot = __pgprot(prot);
+
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
/*
* A driver is enabling the device. We make sure that all the appropriate
* bits are set to allow the device to operate as the driver is expecting.
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 1c96564..505b56c 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -47,7 +47,7 @@
#ifdef CONFIG_DISCONTIGMEM
struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
-unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
+signed char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
#endif
static struct resource data_resource = {
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 9544cdc..e79e006 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -811,6 +811,70 @@
return pcidev->irq;
}
+static struct iosapic_info *first_isi = NULL;
+
+#ifdef CONFIG_64BIT
+int iosapic_serial_irq(int num)
+{
+ struct iosapic_info *isi = first_isi;
+ struct irt_entry *irte = NULL; /* only used if PAT PDC */
+ struct vector_info *vi;
+ int isi_line; /* line used by device */
+
+ /* lookup IRT entry for isi/slot/pin set */
+ irte = &irt_cell[num];
+
+ DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
+ irte,
+ irte->entry_type,
+ irte->entry_length,
+ irte->polarity_trigger,
+ irte->src_bus_irq_devno,
+ irte->src_bus_id,
+ irte->src_seg_id,
+ irte->dest_iosapic_intin,
+ (u32) irte->dest_iosapic_addr);
+ isi_line = irte->dest_iosapic_intin;
+
+ /* get vector info for this input line */
+ vi = isi->isi_vector + isi_line;
+ DBG_IRT("iosapic_serial_irq: line %d vi 0x%p\n", isi_line, vi);
+
+ /* If this IRQ line has already been setup, skip it */
+ if (vi->irte)
+ goto out;
+
+ vi->irte = irte;
+
+ /*
+ * Allocate processor IRQ
+ *
+ * XXX/FIXME The txn_alloc_irq() code and related code should be
+ * moved to enable_irq(). That way we only allocate processor IRQ
+ * bits for devices that actually have drivers claiming them.
+ * Right now we assign an IRQ to every PCI device present,
+ * regardless of whether it's used or not.
+ */
+ vi->txn_irq = txn_alloc_irq(8);
+
+ if (vi->txn_irq < 0)
+ panic("I/O sapic: couldn't get TXN IRQ\n");
+
+ /* enable_irq() will use txn_* to program IRdT */
+ vi->txn_addr = txn_alloc_addr(vi->txn_irq);
+ vi->txn_data = txn_alloc_data(vi->txn_irq);
+
+ vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
+ vi->eoi_data = cpu_to_le32(vi->txn_data);
+
+ cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
+
+ out:
+
+ return vi->txn_irq;
+}
+#endif
+
/*
** squirrel away the I/O Sapic Version
@@ -877,6 +941,8 @@
vip->irqline = (unsigned char) cnt;
vip->iosapic = isi;
}
+ if (!first_isi)
+ first_isi = isi;
return isi;
}
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c
index 097dff9..bb91b47 100644
--- a/drivers/tty/serial/8250/8250_gsc.c
+++ b/drivers/tty/serial/8250/8250_gsc.c
@@ -30,6 +30,12 @@
unsigned long address;
int err;
+#ifdef CONFIG_64BIT
+ extern int iosapic_serial_irq(int cellnum);
+ if (!dev->irq && (dev->id.sversion == 0xad))
+ dev->irq = iosapic_serial_irq(dev->mod_index-1);
+#endif
+
if (!dev->irq) {
/* We find some unattached serial ports by walking native
* busses. These should be silently ignored. Otherwise,
@@ -51,7 +57,8 @@
memset(&uart, 0, sizeof(uart));
uart.port.iotype = UPIO_MEM;
/* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */
- uart.port.uartclk = 7272727;
+ uart.port.uartclk = (dev->id.sversion != 0xad) ?
+ 7272727 : 1843200;
uart.port.mapbase = address;
uart.port.membase = ioremap_nocache(address, 16);
uart.port.irq = dev->irq;
@@ -73,6 +80,7 @@
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
+ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x000ad },
{ 0 }
};