From 178783622ce0fd629fad21b33b8f8f56b64c5e45 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Jul 2011 23:24:21 +0100 Subject: [PATCH 1/9] ARM: dmabounce: fix map_single() error return value When map_single() is unable to obtain a safe buffer, we must return the dma_addr_t error value, which is ~0 rather than 0. Signed-off-by: Russell King --- arch/arm/common/dmabounce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index e5681636626f..841df7d21c2f 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -255,7 +255,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, if (buf == 0) { dev_err(dev, "%s: unable to map unsafe buffer %p!\n", __func__, ptr); - return 0; + return ~0; } dev_dbg(dev, From f4f38430c94c38187db73a2cf3892cc8b12a2713 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 1 Jul 2011 14:38:12 +0100 Subject: [PATCH 2/9] ARM: 6989/1: perf: do not start the PMU when no events are present armpmu_enable can be called in situations where no events are present (for example, from the event rotation tick after a profiled task has exited). In this case, we currently start the PMU anyway which may leave it active inevitably without any events being monitored. This patch adds a simple check to the enabling code so that we avoid starting the PMU when no events are present. Cc: Reported-by: Ashwin Chaugle Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/perf_event.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index d53c0abc4dd3..2b5b1421596c 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -583,7 +583,7 @@ static int armpmu_event_init(struct perf_event *event) static void armpmu_enable(struct pmu *pmu) { /* Enable all of the perf events on hardware. */ - int idx; + int idx, enabled = 0; struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); if (!armpmu) @@ -596,9 +596,11 @@ static void armpmu_enable(struct pmu *pmu) continue; armpmu->enable(&event->hw, idx); + enabled = 1; } - armpmu->start(); + if (enabled) + armpmu->start(); } static void armpmu_disable(struct pmu *pmu) From 6f96521fab978046070a697926cf351c2c37af29 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 1 Jul 2011 14:38:53 +0100 Subject: [PATCH 3/9] ARM: 6990/1: MAINTAINERS: add entry for ARM PMU profiling and debugging Following a request from Russell King: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-June/055031.html Add myself as the ARM PMU profiling and debugging maintainer. This covers the ARM implementations of perf, oprofile and hw_breakpoint along with the glue for this to work on different platforms. Cc: Jean Pihet Acked-by: Jamie Iles Acked-by: Linus Walleij Signed-off-by: Will Deacon Signed-off-by: Russell King --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d2dcef7cd9b2..ec32825ca319 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -594,6 +594,16 @@ S: Maintained F: arch/arm/lib/floppydma.S F: arch/arm/include/asm/floppy.h +ARM PMU PROFILING AND DEBUGGING +M: Will Deacon +S: Maintained +F: arch/arm/kernel/perf_event* +F: arch/arm/oprofile/common.c +F: arch/arm/kernel/pmu.c +F: arch/arm/include/asm/pmu.h +F: arch/arm/kernel/hw_breakpoint.c +F: arch/arm/include/asm/hw_breakpoint.h + ARM PORT M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) From 0371d3f7e8f1cddaee1f215e42c09a40e235d810 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 5 Jul 2011 19:58:29 +0100 Subject: [PATCH 4/9] ARM: move memory layout sanity checking before meminfo initialization Ensure that the meminfo array is sanity checked before we pass the memory to memblock. This helps to ensure that memblock and meminfo agree on the dimensions of memory, especially when more memory is passed than the kernel can deal with. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 2 ++ arch/arm/mm/mmu.c | 5 +++-- arch/arm/mm/nommu.c | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index ed11fb08b05a..acbb447ac6b5 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -73,6 +73,7 @@ __setup("fpe=", fpe_setup); #endif extern void paging_init(struct machine_desc *desc); +extern void sanity_check_meminfo(void); extern void reboot_setup(char *str); unsigned int processor_id; @@ -900,6 +901,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); + sanity_check_meminfo(); arm_memblock_init(&meminfo, mdesc); paging_init(mdesc); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9d9e736c2b4f..594d677b92c8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -759,7 +759,7 @@ early_param("vmalloc", early_vmalloc); static phys_addr_t lowmem_limit __initdata = 0; -static void __init sanity_check_meminfo(void) +void __init sanity_check_meminfo(void) { int i, j, highmem = 0; @@ -1032,8 +1032,9 @@ void __init paging_init(struct machine_desc *mdesc) { void *zero_page; + memblock_set_current_limit(lowmem_limit); + build_mem_type_table(); - sanity_check_meminfo(); prepare_page_table(); map_lowmem(); devicemaps_init(mdesc); diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 687d02319a41..941a98c9e8aa 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -27,6 +27,10 @@ void __init arm_mm_memblock_reserve(void) memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); } +void __init sanity_check_meminfo(void) +{ +} + /* * paging_init() sets up the page tables, initialises the zone memory * maps, and sets up the zero page, bad page and bad page tables. From 2eb5af44b1d22d7f7b715e0b9a4e516eb4451bf9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 28 Jun 2011 09:53:20 +0100 Subject: [PATCH 5/9] ARM: 6979/1: mach-vt8500: add forgotten irq_data conversion This platform has not been converted to 'struct irq_data' when the big pile was done and fails to compile nowadays. Tested on a JayPC-Tablet. Signed-off-by: Wolfram Sang Acked-by: Alexey Charkov Signed-off-by: Russell King --- arch/arm/mach-vt8500/irq.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c index 245140c0df10..642de0408f25 100644 --- a/arch/arm/mach-vt8500/irq.c +++ b/arch/arm/mach-vt8500/irq.c @@ -39,9 +39,10 @@ static void __iomem *ic_regbase; static void __iomem *sic_regbase; -static void vt8500_irq_mask(unsigned int irq) +static void vt8500_irq_mask(struct irq_data *d) { void __iomem *base = ic_regbase; + unsigned irq = d->irq; u8 edge; if (irq >= 64) { @@ -64,9 +65,10 @@ static void vt8500_irq_mask(unsigned int irq) } } -static void vt8500_irq_unmask(unsigned int irq) +static void vt8500_irq_unmask(struct irq_data *d) { void __iomem *base = ic_regbase; + unsigned irq = d->irq; u8 dctr; if (irq >= 64) { @@ -78,10 +80,11 @@ static void vt8500_irq_unmask(unsigned int irq) writeb(dctr, base + VT8500_IC_DCTR + irq); } -static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type) +static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type) { void __iomem *base = ic_regbase; - unsigned int orig_irq = irq; + unsigned irq = d->irq; + unsigned orig_irq = irq; u8 dctr; if (irq >= 64) { @@ -114,11 +117,11 @@ static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type) } static struct irq_chip vt8500_irq_chip = { - .name = "vt8500", - .ack = vt8500_irq_mask, - .mask = vt8500_irq_mask, - .unmask = vt8500_irq_unmask, - .set_type = vt8500_irq_set_type, + .name = "vt8500", + .irq_ack = vt8500_irq_mask, + .irq_mask = vt8500_irq_mask, + .irq_unmask = vt8500_irq_unmask, + .irq_set_type = vt8500_irq_set_type, }; void __init vt8500_init_irq(void) From 757df746fc5db0020ddab45914617a19d149c252 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 30 Jun 2011 15:10:21 +0100 Subject: [PATCH 6/9] ARM: 6980/1: mmci: use StartBitErr to detect bad connections Stresstesting insert/remove of SD-cards can trigger a StartBitErr. This made the driver to hang in forever waiting for a non ocurring data timeout. This bit and interrupt is documented in the original PL180 TRM, just never implemented until now. Signed-off-by: Ulf Hansson Reviewed-by: Linus Walleij Reviewed-by: Jonas Aberg Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 2 ++ drivers/mmc/host/mmci.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7721de942c69..fe140724a02e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -582,6 +582,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, data->error = -EILSEQ; } else if (status & MCI_DATATIMEOUT) { data->error = -ETIMEDOUT; + } else if (status & MCI_STARTBITERR) { + data->error = -ECOMM; } else if (status & MCI_TXUNDERRUN) { data->error = -EIO; } else if (status & MCI_RXOVERRUN) { diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index bb32e21c09db..2164e8c6476c 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -86,6 +86,7 @@ #define MCI_CMDRESPEND (1 << 6) #define MCI_CMDSENT (1 << 7) #define MCI_DATAEND (1 << 8) +#define MCI_STARTBITERR (1 << 9) #define MCI_DATABLOCKEND (1 << 10) #define MCI_CMDACTIVE (1 << 11) #define MCI_TXACTIVE (1 << 12) @@ -112,6 +113,7 @@ #define MCI_CMDRESPENDCLR (1 << 6) #define MCI_CMDSENTCLR (1 << 7) #define MCI_DATAENDCLR (1 << 8) +#define MCI_STARTBITERRCLR (1 << 9) #define MCI_DATABLOCKENDCLR (1 << 10) /* Extended status bits for the ST Micro variants */ #define MCI_ST_SDIOITC (1 << 22) @@ -127,6 +129,7 @@ #define MCI_CMDRESPENDMASK (1 << 6) #define MCI_CMDSENTMASK (1 << 7) #define MCI_DATAENDMASK (1 << 8) +#define MCI_STARTBITERRMASK (1 << 9) #define MCI_DATABLOCKENDMASK (1 << 10) #define MCI_CMDACTIVEMASK (1 << 11) #define MCI_TXACTIVEMASK (1 << 12) @@ -150,7 +153,7 @@ #define MCI_IRQENABLE \ (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ - MCI_CMDRESPENDMASK|MCI_CMDSENTMASK) + MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_STARTBITERRMASK) /* These interrupts are directed to IRQ1 when two IRQ lines are available */ #define MCI_IRQ1MASK \ From 186dcaa448c0a7a99933efac2af225fc4fe82c53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0tetiar?= Date: Fri, 17 Jun 2011 11:10:04 +0100 Subject: [PATCH 7/9] ARM: 6966/1: ep93xx: fix inverted RTS/DTR signals on uart1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was discovered by Roberto Bergo, that RTS/DTR signals are inverted after the boot, because it was causing him problems with hardware controlled modem connected on ttyAM0. Todd Valentic came with this patch for the issue. Discussion: http://tech.groups.yahoo.com/group/ts-7000/message/20259 Comments from Petr Štetiar: Sorry, but forget to add Acked-by[1]: 1. https://patchwork.kernel.org/patch/873052/ Cc: Ryan Mallon Cc: Hartley Sweeten Signed-off-by: Todd Valentic Tested-by: Roberto Bergo Signed-off-by: Petr Štetiar Acked-by: H Hartley Sweeten Signed-off-by: Russell King --- arch/arm/mach-ep93xx/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 1d4b65fd673e..6659a0d137a3 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -251,9 +251,9 @@ static void ep93xx_uart_set_mctrl(struct amba_device *dev, unsigned int mcr; mcr = 0; - if (!(mctrl & TIOCM_RTS)) + if (mctrl & TIOCM_RTS) mcr |= 2; - if (!(mctrl & TIOCM_DTR)) + if (mctrl & TIOCM_DTR) mcr |= 1; __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET); From 38a8914f9ac2379293944f613e6ca24b61373de8 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 1 Jul 2011 14:36:19 +0100 Subject: [PATCH 8/9] ARM: 6987/1: l2x0: fix disabling function to avoid deadlock The l2x0_disable function attempts to writel with the l2x0_lock held. This results in deadlock when the writel contains an outer_sync call for the platform since the l2x0_lock is already held by the disable function. A further problem is that disabling the L2 without flushing it first can lead to the spin_lock operation becoming visible after the spin_unlock, causing any subsequent L2 maintenance to deadlock. This patch replaces the writel with a call to writel_relaxed in the disabling code and adds a flush before disabling in the control register, preventing livelock from occurring. Acked-by: Catalin Marinas Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/mm/cache-l2x0.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index ef59099a5463..44c086710d2b 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -120,17 +120,22 @@ static void l2x0_cache_sync(void) spin_unlock_irqrestore(&l2x0_lock, flags); } +static void __l2x0_flush_all(void) +{ + debug_writel(0x03); + writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); + cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); + cache_sync(); + debug_writel(0x00); +} + static void l2x0_flush_all(void) { unsigned long flags; /* clean all ways */ spin_lock_irqsave(&l2x0_lock, flags); - debug_writel(0x03); - writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); - cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); - cache_sync(); - debug_writel(0x00); + __l2x0_flush_all(); spin_unlock_irqrestore(&l2x0_lock, flags); } @@ -266,7 +271,9 @@ static void l2x0_disable(void) unsigned long flags; spin_lock_irqsave(&l2x0_lock, flags); - writel(0, l2x0_base + L2X0_CTRL); + __l2x0_flush_all(); + writel_relaxed(0, l2x0_base + L2X0_CTRL); + dsb(); spin_unlock_irqrestore(&l2x0_lock, flags); } From 90c5ffe592ff3b33afe2bdfe5e9ec630fc599e32 Mon Sep 17 00:00:00 2001 From: Vitaly Kuzmichev Date: Thu, 7 Jul 2011 14:56:05 +0100 Subject: [PATCH 9/9] ARM: 6994/1: smp_twd: Fix typo in 'twd_timer_rate' printing To get hundredths of MHz the rate needs to be divided by 10'000. Here is an example: twd_timer_rate = 123456789 Before the patch: twd_timer_rate / 1000000 = 123 (twd_timer_rate / 1000000) % 100 = 23 Result: 123.23MHz. After being fixed: twd_timer_rate / 1000000 = 123 (twd_timer_rate / 10000) % 100 = 45 Result: 123.45MHz. Signed-off-by: Vitaly Kuzmichev Signed-off-by: Russell King --- arch/arm/kernel/smp_twd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 60636f499cb3..2c277d40cee6 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -115,7 +115,7 @@ static void __cpuinit twd_calibrate_rate(void) twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, - (twd_timer_rate / 1000000) % 100); + (twd_timer_rate / 10000) % 100); } }