From 650e3f0d66ade2a614d854765dae3bbc9a87f58d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:33:03 -0800 Subject: ARM: msm: Consolidate and move DEBUG_LL to DEBUG_LL choice Now that DEBUG_LL is a choice we can move MSM's homegrown choice menu to DEBUG_LL. Signed-off-by: Stephen Boyd Signed-off-by: David Brown diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c5213e7..333b6a4 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -247,6 +247,27 @@ choice their output to the standard serial port on the RealView PB1176 platform. + config DEBUG_MSM_UART1 + bool "Kernel low-level debugging messages via MSM UART1" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + help + Say Y here if you want the debug print routines to direct + their output to the first serial port on MSM devices. + + config DEBUG_MSM_UART2 + bool "Kernel low-level debugging messages via MSM UART2" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + help + Say Y here if you want the debug print routines to direct + their output to the second serial port on MSM devices. + + config DEBUG_MSM_UART3 + bool "Kernel low-level debugging messages via MSM UART3" + depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50 + help + Say Y here if you want the debug print routines to direct + their output to the third serial port on MSM devices. + endchoice config EARLY_PRINTK diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index ebde97f..5b07b61 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -13,7 +13,6 @@ config ARCH_MSM7X00A select CPU_V6 select GPIO_MSM_V1 select MSM_PROC_COMM - select HAS_MSM_DEBUG_UART_PHYS config ARCH_MSM7X30 bool "MSM7x30" @@ -25,7 +24,6 @@ config ARCH_MSM7X30 select MSM_GPIOMUX select GPIO_MSM_V1 select MSM_PROC_COMM - select HAS_MSM_DEBUG_UART_PHYS config ARCH_QSD8X50 bool "QSD8X50" @@ -37,7 +35,6 @@ config ARCH_QSD8X50 select MSM_GPIOMUX select GPIO_MSM_V1 select MSM_PROC_COMM - select HAS_MSM_DEBUG_UART_PHYS config ARCH_MSM8X60 bool "MSM8X60" @@ -73,9 +70,6 @@ config ARCH_MSM_ARM11 config ARCH_MSM_SCORPION bool -config HAS_MSM_DEBUG_UART_PHYS - bool - config MSM_VIC bool @@ -152,32 +146,6 @@ config MACH_MSM8960_RUMI3 endmenu -config MSM_DEBUG_UART - int - default 1 if MSM_DEBUG_UART1 - default 2 if MSM_DEBUG_UART2 - default 3 if MSM_DEBUG_UART3 - -if HAS_MSM_DEBUG_UART_PHYS -choice - prompt "Debug UART" - - default MSM_DEBUG_UART_NONE - - config MSM_DEBUG_UART_NONE - bool "None" - - config MSM_DEBUG_UART1 - bool "UART1" - - config MSM_DEBUG_UART2 - bool "UART2" - - config MSM_DEBUG_UART3 - bool "UART3" -endchoice -endif - config MSM_SMD_PKG3 bool diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index 2dc73cc..db1f228 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -1,4 +1,4 @@ -/* arch/arm/mach-msm7200/include/mach/debug-macro.S +/* * * Copyright (C) 2007 Google, Inc. * Author: Brian Swetland @@ -14,15 +14,14 @@ * */ - - #include #include -#if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE) .macro addruart, rp, rv, tmp +#ifdef MSM_DEBUG_UART_PHYS ldr \rp, =MSM_DEBUG_UART_PHYS ldr \rv, =MSM_DEBUG_UART_BASE +#endif .endm .macro senduart,rd,rx @@ -36,18 +35,6 @@ tst \rd, #0x04 beq 1001b .endm -#else - .macro addruart, rp, rv, tmp - mov \rv, #0xff000000 - orr \rv, \rv, #0x00f00000 - .endm - - .macro senduart,rd,rx - .endm - - .macro waituart,rd,rx - .endm -#endif .macro busyuart,rd,rx .endm diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h index 94fe9fe..8af4612 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h @@ -78,18 +78,6 @@ #define MSM_UART3_PHYS 0xA9C00000 #define MSM_UART3_SIZE SZ_4K -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - #define MSM_SDC1_PHYS 0xA0400000 #define MSM_SDC1_SIZE SZ_4K diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h index 3769444..198202c 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h @@ -89,18 +89,6 @@ #define MSM_UART3_PHYS 0xACC00000 #define MSM_UART3_SIZE SZ_4K -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - #define MSM_MDC_BASE IOMEM(0xE0200000) #define MSM_MDC_PHYS 0xAA500000 #define MSM_MDC_SIZE SZ_1M diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h index d67cd73..0faa894 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h @@ -83,18 +83,6 @@ #define MSM_UART3_PHYS 0xA9C00000 #define MSM_UART3_SIZE SZ_4K -#ifdef CONFIG_MSM_DEBUG_UART -#define MSM_DEBUG_UART_BASE 0xE1000000 -#if CONFIG_MSM_DEBUG_UART == 1 -#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS -#elif CONFIG_MSM_DEBUG_UART == 2 -#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS -#elif CONFIG_MSM_DEBUG_UART == 3 -#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS -#endif -#define MSM_DEBUG_UART_SIZE SZ_4K -#endif - #define MSM_MDC_BASE IOMEM(0xE0200000) #define MSM_MDC_PHYS 0xAA500000 #define MSM_MDC_SIZE SZ_1M diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 4ded152..90682f4 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -55,6 +55,18 @@ #include "msm_iomap-8960.h" +#define MSM_DEBUG_UART_SIZE SZ_4K +#if defined(CONFIG_DEBUG_MSM_UART1) +#define MSM_DEBUG_UART_BASE 0xE1000000 +#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS +#elif defined(CONFIG_DEBUG_MSM_UART2) +#define MSM_DEBUG_UART_BASE 0xE1000000 +#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS +#elif defined(CONFIG_DEBUG_MSM_UART3) +#define MSM_DEBUG_UART_BASE 0xE1000000 +#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS +#endif + /* Virtual addresses shared across all MSM targets. */ #define MSM_CSR_BASE IOMEM(0xE0001000) #define MSM_QGIC_DIST_BASE IOMEM(0xF0000000) diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 8759ecf..03036af 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -47,7 +47,8 @@ static struct map_desc msm_io_desc[] __initdata = { MSM_CHIP_DEVICE(GPIO1, MSM7X00), MSM_CHIP_DEVICE(GPIO2, MSM7X00), MSM_DEVICE(CLK_CTL), -#ifdef CONFIG_MSM_DEBUG_UART +#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \ + defined(CONFIG_DEBUG_MSM_UART3) MSM_DEVICE(DEBUG_UART), #endif #ifdef CONFIG_ARCH_MSM7X30 @@ -84,7 +85,8 @@ static struct map_desc qsd8x50_io_desc[] __initdata = { MSM_DEVICE(SCPLL), MSM_DEVICE(AD5), MSM_DEVICE(MDC), -#ifdef CONFIG_MSM_DEBUG_UART +#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \ + defined(CONFIG_DEBUG_MSM_UART3) MSM_DEVICE(DEBUG_UART), #endif { @@ -146,7 +148,8 @@ static struct map_desc msm7x30_io_desc[] __initdata = { MSM_DEVICE(SAW), MSM_DEVICE(GCC), MSM_DEVICE(TCSR), -#ifdef CONFIG_MSM_DEBUG_UART +#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \ + defined(CONFIG_DEBUG_MSM_UART3) MSM_DEVICE(DEBUG_UART), #endif { -- cgit v0.10.2 From a3d3ef9d4fd57cfd407c8d2d0a7daec000468ebf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 8 Nov 2011 10:33:04 -0800 Subject: msm: Support DEBUG_LL on MSM8660 and MSM8960 Add support for DEBUG_LL on the 8660 and 8960 development boards. While we're here cleanup the uncompress.h code a bit. Avoid the use of readl/writel as those are Linux specific APIs that aren't guaranteed to work in the decompressor. Cc: Nicolas Pitre Signed-off-by: Stephen Boyd Acked-by: Nicolas Pitre Signed-off-by: David Brown diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 333b6a4..4c1eb7d 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -268,6 +268,22 @@ choice Say Y here if you want the debug print routines to direct their output to the third serial port on MSM devices. + config DEBUG_MSM8660_UART + bool "Kernel low-level debugging messages via MSM 8660 UART" + depends on ARCH_MSM8X60 + select MSM_HAS_DEBUG_UART_HS + help + Say Y here if you want the debug print routines to direct + their output to the serial port on MSM 8660 devices. + + config DEBUG_MSM8960_UART + bool "Kernel low-level debugging messages via MSM 8960 UART" + depends on ARCH_MSM8960 + select MSM_HAS_DEBUG_UART_HS + help + Say Y here if you want the debug print routines to direct + their output to the serial port on MSM 8960 devices. + endchoice config EARLY_PRINTK diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 5b07b61..000ddf0 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -60,6 +60,9 @@ config ARCH_MSM8960 endchoice +config MSM_HAS_DEBUG_UART_HS + bool + config MSM_SOC_REV_A bool config ARCH_MSM_SCORPIONMP diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index db1f228..3ffd866 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -1,6 +1,7 @@ /* * * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * Author: Brian Swetland * * This software is licensed under the terms of the GNU General Public @@ -24,17 +25,42 @@ #endif .endm - .macro senduart,rd,rx + .macro senduart, rd, rx +#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS + @ Write the 1 character to UARTDM_TF + str \rd, [\rx, #0x70] +#else teq \rx, #0 strne \rd, [\rx, #0x0C] +#endif .endm - .macro waituart,rd,rx + .macro waituart, rd, rx +#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS + @ check for TX_EMT in UARTDM_SR + ldr \rd, [\rx, #0x08] + tst \rd, #0x08 + bne 1002f + @ wait for TXREADY in UARTDM_ISR +1001: ldr \rd, [\rx, #0x14] + tst \rd, #0x80 + beq 1001b +1002: + @ Clear TX_READY by writing to the UARTDM_CR register + mov \rd, #0x300 + str \rd, [\rx, #0x10] + @ Write 0x1 to NCF register + mov \rd, #0x1 + str \rd, [\rx, #0x40] + @ UARTDM reg. Read to induce delay + ldr \rd, [\rx, #0x08] +#else @ wait for TX_READY 1001: ldr \rd, [\rx, #0x08] tst \rd, #0x04 beq 1001b +#endif .endm - .macro busyuart,rd,rx + .macro busyuart, rd, rx .endm diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h index 3c9d960..800b557 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h @@ -45,4 +45,9 @@ #define MSM8960_TMR0_PHYS 0x0208A000 #define MSM8960_TMR0_SIZE SZ_4K +#ifdef CONFIG_DEBUG_MSM8960_UART +#define MSM_DEBUG_UART_BASE 0xE1040000 +#define MSM_DEBUG_UART_PHYS 0x16440000 +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h index 3b19b8f..54e12ca 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h @@ -62,4 +62,9 @@ #define MSM8X60_TMR0_PHYS 0x02040000 #define MSM8X60_TMR0_SIZE SZ_4K +#ifdef CONFIG_DEBUG_MSM8660_UART +#define MSM_DEBUG_UART_BASE 0xE1040000 +#define MSM_DEBUG_UART_PHYS 0x19C40000 +#endif + #endif diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h index d94292c..169a840 100644 --- a/arch/arm/mach-msm/include/mach/uncompress.h +++ b/arch/arm/mach-msm/include/mach/uncompress.h @@ -1,6 +1,6 @@ -/* arch/arm/mach-msm/include/mach/uncompress.h - * +/* * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,17 +14,40 @@ */ #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H +#define __ASM_ARCH_MSM_UNCOMPRESS_H + +#include +#include + +#define UART_CSR (*(volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x08)) +#define UART_TF (*(volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x0c)) -#include "hardware.h" -#include "linux/io.h" -#include "mach/msm_iomap.h" +#define UART_DM_SR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x08))) +#define UART_DM_CR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x10))) +#define UART_DM_ISR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x14))) +#define UART_DM_NCHAR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x40))) +#define UART_DM_TF (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x70))) static void putc(int c) { #if defined(MSM_DEBUG_UART_PHYS) - unsigned base = MSM_DEBUG_UART_PHYS; - while (!(readl(base + 0x08) & 0x04)) ; - writel(c, base + 0x0c); +#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS + /* + * Wait for TX_READY to be set; but skip it if we have a + * TX underrun. + */ + if (UART_DM_SR & 0x08) + while (!(UART_DM_ISR & 0x80)) + cpu_relax(); + + UART_DM_CR = 0x300; + UART_DM_NCHAR = 0x1; + UART_DM_TF = c; +#else + while (!(UART_CSR & 0x04)) + cpu_relax(); + UART_TF = c; +#endif #endif } diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 03036af..578b04e 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -111,6 +111,9 @@ static struct map_desc msm8x60_io_desc[] __initdata = { MSM_CHIP_DEVICE(TMR0, MSM8X60), MSM_DEVICE(ACC), MSM_DEVICE(GCC), +#ifdef CONFIG_DEBUG_MSM8660_UART + MSM_DEVICE(DEBUG_UART), +#endif }; void __init msm_map_msm8x60_io(void) @@ -125,6 +128,9 @@ static struct map_desc msm8960_io_desc[] __initdata = { MSM_CHIP_DEVICE(QGIC_CPU, MSM8960), MSM_CHIP_DEVICE(TMR, MSM8960), MSM_CHIP_DEVICE(TMR0, MSM8960), +#ifdef CONFIG_DEBUG_MSM8960_UART + MSM_DEVICE(DEBUG_UART), +#endif }; void __init msm_map_msm8960_io(void) -- cgit v0.10.2 From 2b222a2971e4d73fc25c09aeb203c16c0c3c142e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 19 Sep 2011 10:54:04 -0700 Subject: msm: platsmp: Mark ioremapped memory as __iomem Fixes a handful of sparse warnings. Signed-off-by: Stephen Boyd Signed-off-by: David Brown diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index fdec58a..0b3e357 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -79,7 +79,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu) ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup), SCM_FLAG_COLDBOOT_CPU1); if (ret == 0) { - void *sc1_base_ptr; + void __iomem *sc1_base_ptr; sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); if (sc1_base_ptr) { writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); -- cgit v0.10.2 From 63b870f149cdcd253ae8da88d8b5a0b43a68965c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 17 Nov 2011 01:19:11 +0900 Subject: ARM: EXYNOS: remove exynos4_scu_enable() The exynos4_scu_enable() is a duplication of scu_enable(). Since commit '26a527e ARM: 7100/1: smp_scu: remove __init annotation from scu_enable()' makes scu_enable() available for non-init codes, exynos can directly call scu_enable() and save exynos4_scu_enable() now. Signed-off-by: Shawn Guo [kgene.kim@samsung.com: added missing header] Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 509a435..4093fea 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -213,27 +214,6 @@ static int exynos4_pm_add(struct sys_device *sysdev) return 0; } -/* This function copy from linux/arch/arm/kernel/smp_scu.c */ - -void exynos4_scu_enable(void __iomem *scu_base) -{ - u32 scu_ctrl; - - scu_ctrl = __raw_readl(scu_base); - /* already enabled? */ - if (scu_ctrl & 1) - return; - - scu_ctrl |= 1; - __raw_writel(scu_ctrl, scu_base); - - /* - * Ensure that the data accessed by CPU0 before the SCU was - * initialised is visible to the other CPUs. - */ - flush_cache_all(); -} - static unsigned long pll_base_rate; static void exynos4_restore_pll(void) @@ -402,7 +382,7 @@ static void exynos4_pm_resume(void) exynos4_restore_pll(); - exynos4_scu_enable(S5P_VA_SCU); + scu_enable(S5P_VA_SCU); #ifdef CONFIG_CACHE_L2X0 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); -- cgit v0.10.2 From 19d7ca2998e095086869318dd2ad966952f5ac82 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 18 Nov 2011 16:32:34 +0900 Subject: sh: fix build warning in board-sh7757lcr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixed the following build warnings: CC arch/sh/boards/board-sh7757lcr.o arch/sh/boards/board-sh7757lcr.c:77: warning: initialization from incompatible pointer type arch/sh/boards/board-sh7757lcr.c:106: warning: initialization from incompatible pointer type arch/sh/boards/board-sh7757lcr.c:151: warning: initialization from incompatible pointer type arch/sh/boards/board-sh7757lcr.c:181: warning: initialization from incompatible pointer type arch/sh/boards/board-sh7757lcr.c:213: warning: missing braces around initializer arch/sh/boards/board-sh7757lcr.c:213: warning: (near initialization for ‘sh7757lcr_mmcif_dma.chan_priv_tx’) Signed-off-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index ec8c84c..895e337 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c @@ -50,9 +50,9 @@ static struct platform_device heartbeat_device = { #define GBECONT 0xffc10100 #define GBECONT_RMII1 BIT(17) #define GBECONT_RMII0 BIT(16) -static void sh7757_eth_set_mdio_gate(unsigned long addr) +static void sh7757_eth_set_mdio_gate(void *addr) { - if ((addr & 0x00000fff) < 0x0800) + if (((unsigned long)addr & 0x00000fff) < 0x0800) writel(readl(GBECONT) | GBECONT_RMII0, GBECONT); else writel(readl(GBECONT) | GBECONT_RMII1, GBECONT); @@ -116,9 +116,9 @@ static struct platform_device sh7757_eth1_device = { }, }; -static void sh7757_eth_giga_set_mdio_gate(unsigned long addr) +static void sh7757_eth_giga_set_mdio_gate(void *addr) { - if ((addr & 0x00000fff) < 0x0800) { + if (((unsigned long)addr & 0x00000fff) < 0x0800) { gpio_set_value(GPIO_PTT4, 1); writel(readl(GBECONT) & ~GBECONT_RMII0, GBECONT); } else { @@ -210,8 +210,12 @@ static struct resource sh_mmcif_resources[] = { }; static struct sh_mmcif_dma sh7757lcr_mmcif_dma = { - .chan_priv_tx = SHDMA_SLAVE_MMCIF_TX, - .chan_priv_rx = SHDMA_SLAVE_MMCIF_RX, + .chan_priv_tx = { + .slave_id = SHDMA_SLAVE_MMCIF_TX, + }, + .chan_priv_rx = { + .slave_id = SHDMA_SLAVE_MMCIF_RX, + } }; static struct sh_mmcif_plat_data sh_mmcif_plat = { -- cgit v0.10.2 From 865d605ee81813dc73d5422fd2f9bd132d10d194 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Tue, 9 Aug 2011 16:51:11 +0200 Subject: at91: provide macb clks with "pclk" and "hclk" name The macb driver expects clocks with the names "pclk" and "hclk". We currently provide "macb_clk" but to fit in line with other architectures (namely AVR32), provide "pclk" and a fake "hclk". Cc: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Jamie Iles Acked-by: David S. Miller Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index ecdd54d..17632b8 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -137,7 +137,7 @@ static struct clk pwm_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91CAP9_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -210,6 +210,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_clk), CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b84a9f6..249ed1f 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -120,7 +120,7 @@ static struct clk ohci_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91SAM9260_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -190,6 +190,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index f83fbb0..182d112 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -118,7 +118,7 @@ static struct clk pwm_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91SAM9263_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -182,6 +182,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 318b040..5a0e522 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -150,7 +150,7 @@ static struct clk ac97_clk = { .type = CLK_TYPE_PERIPHERAL, }; static struct clk macb_clk = { - .name = "macb_clk", + .name = "pclk", .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; @@ -209,6 +209,8 @@ static struct clk *periph_clocks[] __initdata = { }; static struct clk_lookup periph_clocks_lookups[] = { + /* One additional fake clock for macb_hclk */ + CLKDEV_CON_ID("hclk", &macb_clk), /* One additional fake clock for ohci */ CLKDEV_CON_ID("ohci_clk", &uhphs_clk), CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), -- cgit v0.10.2 From 461845db2176d2e11b45f1f24cbd0ed8ddf26fcb Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Tue, 8 Mar 2011 20:19:23 +0000 Subject: macb: remove conditional clk handling AT91 now provides both "pclk" and "hclk" aliases for the the macb device so we can use the same clk handling paths for both AT91 and AVR32. Signed-off-by: Jamie Iles Acked-by: David S. Miller Acked-by: Nicolas Ferre Tested-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index a437b46..b0fa478 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1152,28 +1152,19 @@ static int __init macb_probe(struct platform_device *pdev) spin_lock_init(&bp->lock); -#if defined(CONFIG_ARCH_AT91) - bp->pclk = clk_get(&pdev->dev, "macb_clk"); + bp->pclk = clk_get(&pdev->dev, "pclk"); if (IS_ERR(bp->pclk)) { dev_err(&pdev->dev, "failed to get macb_clk\n"); goto err_out_free_dev; } clk_enable(bp->pclk); -#else - bp->pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(bp->pclk)) { - dev_err(&pdev->dev, "failed to get pclk\n"); - goto err_out_free_dev; - } + bp->hclk = clk_get(&pdev->dev, "hclk"); if (IS_ERR(bp->hclk)) { dev_err(&pdev->dev, "failed to get hclk\n"); goto err_out_put_pclk; } - - clk_enable(bp->pclk); clk_enable(bp->hclk); -#endif bp->regs = ioremap(regs->start, resource_size(regs)); if (!bp->regs) { @@ -1256,14 +1247,10 @@ err_out_free_irq: err_out_iounmap: iounmap(bp->regs); err_out_disable_clocks: -#ifndef CONFIG_ARCH_AT91 clk_disable(bp->hclk); clk_put(bp->hclk); -#endif clk_disable(bp->pclk); -#ifndef CONFIG_ARCH_AT91 err_out_put_pclk: -#endif clk_put(bp->pclk); err_out_free_dev: free_netdev(dev); @@ -1289,10 +1276,8 @@ static int __exit macb_remove(struct platform_device *pdev) unregister_netdev(dev); free_irq(dev->irq, dev); iounmap(bp->regs); -#ifndef CONFIG_ARCH_AT91 clk_disable(bp->hclk); clk_put(bp->hclk); -#endif clk_disable(bp->pclk); clk_put(bp->pclk); free_netdev(dev); @@ -1310,9 +1295,7 @@ static int macb_suspend(struct platform_device *pdev, pm_message_t state) netif_device_detach(netdev); -#ifndef CONFIG_ARCH_AT91 clk_disable(bp->hclk); -#endif clk_disable(bp->pclk); return 0; @@ -1324,9 +1307,7 @@ static int macb_resume(struct platform_device *pdev) struct macb *bp = netdev_priv(netdev); clk_enable(bp->pclk); -#ifndef CONFIG_ARCH_AT91 clk_enable(bp->hclk); -#endif netif_device_attach(netdev); -- cgit v0.10.2 From 84e0cdb0a262483a3618091c43dae33d36226430 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Tue, 8 Mar 2011 20:17:06 +0000 Subject: macb: unify at91 and avr32 platform data Both at91 and avr32 defines its own platform data structure for the macb driver and both share common structures though at91 includes a currently unused phy_irq_pin. Create a common macb_platform_data for macb that both at91 and avr32 can use. In future we can use this to support other architectures that use the same IP block with the macb driver. v2: rename eth_platform_data to macb_platform_data and allow at91_ether to share the platform data with macb. Signed-off-by: Jamie Iles Acked-by: Nicolas Ferre Tested-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index adad70d..695aeca 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -200,7 +200,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -227,7 +227,7 @@ static struct platform_device at91cap9_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -264,7 +264,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91cap9_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 66591fa..5610f14 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -135,7 +135,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -162,7 +162,7 @@ static struct platform_device at91rm9200_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -199,7 +199,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91rm9200_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 25e3464..ff75f7d 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -136,7 +136,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -163,7 +163,7 @@ static struct platform_device at91sam9260_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -200,7 +200,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91sam9260_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ad017eb..68562ce 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -144,7 +144,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -171,7 +171,7 @@ static struct platform_device at91sam9263_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -208,7 +208,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91sam9263_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 09a16d6..e2cb835 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -284,7 +284,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {} #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) static u64 eth_dmamask = DMA_BIT_MASK(32); -static struct at91_eth_data eth_data; +static struct macb_platform_data eth_data; static struct resource eth_resources[] = { [0] = { @@ -311,7 +311,7 @@ static struct platform_device at91sam9g45_eth_device = { .num_resources = ARRAY_SIZE(eth_resources), }; -void __init at91_add_device_eth(struct at91_eth_data *data) +void __init at91_add_device_eth(struct macb_platform_data *data) { if (!data) return; @@ -348,7 +348,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data) platform_device_register(&at91sam9g45_eth_device); } #else -void __init at91_add_device_eth(struct at91_eth_data *data) {} +void __init at91_add_device_eth(struct macb_platform_data *data) {} #endif diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index 367d5cd..a60d98d 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c @@ -63,7 +63,7 @@ static void __init onearm_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata onearm_eth_data = { +static struct macb_platform_data __initdata onearm_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 4282d96..17fc779 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -103,7 +103,7 @@ static struct spi_board_info afeb9260_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata afeb9260_macb_data = { +static struct macb_platform_data __initdata afeb9260_macb_data = { .phy_irq_pin = AT91_PIN_PA9, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index f90cfb3..2037d2c4 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -115,7 +115,7 @@ static struct spi_board_info cam60_spi_devices[] __initdata = { /* * MACB Ethernet device */ -static struct __initdata at91_eth_data cam60_macb_data = { +static struct __initdata macb_platform_data cam60_macb_data = { .phy_irq_pin = AT91_PIN_PB5, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 5dffd3b..af5520c 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -153,7 +153,7 @@ static struct at91_mmc_data __initdata cap9adk_mmc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata cap9adk_macb_data = { +static struct macb_platform_data __initdata cap9adk_macb_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index 774c87f..529b356 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -57,7 +57,7 @@ static void __init carmeva_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata carmeva_eth_data = { +static struct macb_platform_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index fc885a4..04d2b9b 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -99,7 +99,7 @@ static struct at91_udc_data __initdata cpu9krea_udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata cpu9krea_macb_data = { +static struct macb_platform_data __initdata cpu9krea_macb_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index d35e65b..7a4c82e 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -82,7 +82,7 @@ static void __init cpuat91_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata cpuat91_eth_data = { +static struct macb_platform_data __initdata cpuat91_eth_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index c393666..b004b20 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c @@ -58,7 +58,7 @@ static void __init csb337_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata csb337_eth_data = { +static struct macb_platform_data __initdata csb337_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index 586100e..e966de5 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c @@ -52,7 +52,7 @@ static void __init csb637_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata csb637_eth_data = { +static struct macb_platform_data __initdata csb637_eth_data = { .phy_irq_pin = AT91_PIN_PC0, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c index 45db7a3..3788fa5 100644 --- a/arch/arm/mach-at91/board-eb9200.c +++ b/arch/arm/mach-at91/board-eb9200.c @@ -60,7 +60,7 @@ static void __init eb9200_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata eb9200_eth_data = { +static struct macb_platform_data __initdata eb9200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index 2f9c16d2..af7622e 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -64,7 +64,7 @@ static void __init ecb_at91init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata ecb_at91eth_data = { +static struct macb_platform_data __initdata ecb_at91eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index 8252c72..8e75867 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -47,7 +47,7 @@ static void __init eco920_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata eco920_eth_data = { +static struct macb_platform_data __initdata eco920_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index f27d1a7..de8e096 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c @@ -135,7 +135,7 @@ static struct spi_board_info foxg20_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata foxg20_macb_data = { +static struct macb_platform_data __initdata foxg20_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index 2e95949..51c82f1 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -93,7 +93,7 @@ static struct at91_udc_data __initdata udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata macb_data = { +static struct macb_platform_data __initdata macb_data = { .phy_irq_pin = AT91_PIN_PA28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c index 3bae73e..9628a3d 100644 --- a/arch/arm/mach-at91/board-kafa.c +++ b/arch/arm/mach-at91/board-kafa.c @@ -61,7 +61,7 @@ static void __init kafa_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata kafa_eth_data = { +static struct macb_platform_data __initdata kafa_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index e61351f..5ba5244 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -69,7 +69,7 @@ static void __init kb9202_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata kb9202_eth_data = { +static struct macb_platform_data __initdata kb9202_eth_data = { .phy_irq_pin = AT91_PIN_PB29, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index ef816c1..56e7aee 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -155,7 +155,7 @@ static struct at91_mmc_data __initdata neocore926_mmc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata neocore926_macb_data = { +static struct macb_platform_data __initdata neocore926_macb_data = { .phy_irq_pin = AT91_PIN_PE31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 49e3f69..c545a3e 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -122,7 +122,7 @@ static struct at91_udc_data __initdata pcontrol_g20_udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata macb_data = { +static struct macb_platform_data __initdata macb_data = { .phy_irq_pin = AT91_PIN_PA28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index 0a8fe6a..dc18759 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -60,7 +60,7 @@ static void __init picotux200_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata picotux200_eth_data = { +static struct macb_platform_data __initdata picotux200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 07421bd..5444d6a 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -104,7 +104,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 80a8c9c..022d0ce 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -65,7 +65,7 @@ static void __init dk_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata dk_eth_data = { +static struct macb_platform_data __initdata dk_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index 99fd7f8..ed27586 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -65,7 +65,7 @@ static void __init ek_init_early(void) at91_set_serial_console(0); } -static struct at91_eth_data __initdata ek_eth_data = { +static struct macb_platform_data __initdata ek_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-rsi-ews.c b/arch/arm/mach-at91/board-rsi-ews.c index e927df0..ed3b21f 100644 --- a/arch/arm/mach-at91/board-rsi-ews.c +++ b/arch/arm/mach-at91/board-rsi-ews.c @@ -60,7 +60,7 @@ static void __init rsi_ews_init_early(void) /* * Ethernet */ -static struct at91_eth_data rsi_ews_eth_data __initdata = { +static struct macb_platform_data rsi_ews_eth_data __initdata = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 072d53a..3e4b50e 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -109,7 +109,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 0, }; diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 4f10181..13478e1 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -151,7 +151,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index bccdcf2..fcf194e 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -158,7 +158,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PE31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 64fc75c..78d27cc 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -123,7 +123,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 92de912..4e1ee9d 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -115,7 +115,7 @@ static struct mci_platform_data __initdata mci1_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PD5, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 0df01c6..fbec934 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -65,7 +65,7 @@ static struct at91_udc_data __initdata snapper9260_udc_data = { .vbus_polled = 1, }; -static struct at91_eth_data snapper9260_macb_data = { +static struct macb_platform_data snapper9260_macb_data = { .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 936e5fd..7c06c07 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -157,7 +157,7 @@ static struct at91_udc_data __initdata stamp9g20evb_udc_data = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata macb_data = { +static struct macb_platform_data __initdata macb_data = { .phy_irq_pin = AT91_PIN_PA28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 0a20bab..3d84233 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -146,7 +146,7 @@ static void __init ek_add_device_spi(void) /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct macb_platform_data __initdata ek_macb_data = { .phy_irq_pin = AT91_PIN_PE31, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index 12a3f95..2c40a21 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -110,7 +110,7 @@ static struct gpio_led yl9200_leds[] = { /* * Ethernet */ -static struct at91_eth_data __initdata yl9200_eth_data = { +static struct macb_platform_data __initdata yl9200_eth_data = { .phy_irq_pin = AT91_PIN_PB28, .is_rmii = 1, }; diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index eac92e9..e209a29 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -40,6 +40,7 @@ #include #include #include +#include /* USB Device */ struct at91_udc_data { @@ -81,18 +82,7 @@ extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) /* atmel-mci platform config */ extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); - /* Ethernet (EMAC & MACB) */ -struct at91_eth_data { - u32 phy_mask; - u8 phy_irq_pin; /* PHY IRQ */ - u8 is_rmii; /* using RMII interface? */ -}; -extern void __init at91_add_device_eth(struct at91_eth_data *data); - -#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) -#define eth_platform_data at91_eth_data -#endif +extern void __init at91_add_device_eth(struct macb_platform_data *data); /* USB Host */ struct at91_usbh_data { diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c index 1f17bde..7c756fb 100644 --- a/arch/avr32/boards/atngw100/setup.c +++ b/arch/avr32/boards/atngw100/setup.c @@ -109,7 +109,7 @@ struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2]; +static struct macb_platform_data __initdata eth_data[2]; static struct spi_board_info spi0_board_info[] __initdata = { { diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 4643ff5..c56ddac 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -105,7 +105,7 @@ struct eth_addr { }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2] = { +static struct macb_platform_data __initdata eth_data[2] = { { /* * The MDIO pullups on STK1000 are a bit too weak for diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c index 86fab77..27bd6fb 100644 --- a/arch/avr32/boards/favr-32/setup.c +++ b/arch/avr32/boards/favr-32/setup.c @@ -50,7 +50,7 @@ struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[1]; -static struct eth_platform_data __initdata eth_data[1] = { +static struct macb_platform_data __initdata eth_data[1] = { { .phy_mask = ~(1U << 1), }, diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c index da14fbd..9d1efd1 100644 --- a/arch/avr32/boards/hammerhead/setup.c +++ b/arch/avr32/boards/hammerhead/setup.c @@ -102,7 +102,7 @@ struct eth_addr { }; static struct eth_addr __initdata hw_addr[1]; -static struct eth_platform_data __initdata eth_data[1]; +static struct macb_platform_data __initdata eth_data[1]; /* * The next two functions should go away as the boot loader is diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c index e61bc94..ed137e3 100644 --- a/arch/avr32/boards/merisc/setup.c +++ b/arch/avr32/boards/merisc/setup.c @@ -52,7 +52,7 @@ struct eth_addr { }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2]; +static struct macb_platform_data __initdata eth_data[2]; static int ads7846_get_pendown_state_PB26(void) { diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c index c4da5cb..05358aa 100644 --- a/arch/avr32/boards/mimc200/setup.c +++ b/arch/avr32/boards/mimc200/setup.c @@ -86,7 +86,7 @@ struct eth_addr { u8 addr[6]; }; static struct eth_addr __initdata hw_addr[2]; -static struct eth_platform_data __initdata eth_data[2]; +static struct macb_platform_data __initdata eth_data[2]; static struct spi_eeprom eeprom_25lc010 = { .name = "25lc010", diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 7fbf0dc..402a7bb 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -1067,7 +1067,7 @@ void __init at32_setup_serial_console(unsigned int usart_id) * -------------------------------------------------------------------- */ #ifdef CONFIG_CPU_AT32AP7000 -static struct eth_platform_data macb0_data; +static struct macb_platform_data macb0_data; static struct resource macb0_resource[] = { PBMEM(0xfff01800), IRQ(25), @@ -1076,7 +1076,7 @@ DEFINE_DEV_DATA(macb, 0); DEV_CLK(hclk, macb0, hsb, 8); DEV_CLK(pclk, macb0, pbb, 6); -static struct eth_platform_data macb1_data; +static struct macb_platform_data macb1_data; static struct resource macb1_resource[] = { PBMEM(0xfff01c00), IRQ(26), @@ -1086,7 +1086,7 @@ DEV_CLK(hclk, macb1, hsb, 9); DEV_CLK(pclk, macb1, pbb, 7); struct platform_device *__init -at32_add_device_eth(unsigned int id, struct eth_platform_data *data) +at32_add_device_eth(unsigned int id, struct macb_platform_data *data) { struct platform_device *pdev; u32 pin_mask; @@ -1163,7 +1163,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) return NULL; } - memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data)); + memcpy(pdev->dev.platform_data, data, sizeof(struct macb_platform_data)); platform_device_register(pdev); return pdev; diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h index 5d7ffca..67b111c 100644 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ b/arch/avr32/mach-at32ap/include/mach/board.h @@ -6,6 +6,7 @@ #include #include +#include #define GPIO_PIN_NONE (-1) @@ -42,12 +43,8 @@ struct atmel_uart_data { void at32_map_usart(unsigned int hw_id, unsigned int line, int flags); struct platform_device *at32_add_device_usart(unsigned int id); -struct eth_platform_data { - u32 phy_mask; - u8 is_rmii; -}; struct platform_device * -at32_add_device_eth(unsigned int id, struct eth_platform_data *data); +at32_add_device_eth(unsigned int id, struct macb_platform_data *data); struct spi_board_info; struct platform_device * diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 56624d3..dfeb46c 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -984,7 +985,7 @@ static const struct net_device_ops at91ether_netdev_ops = { static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev, struct clk *ether_clk) { - struct at91_eth_data *board_data = pdev->dev.platform_data; + struct macb_platform_data *board_data = pdev->dev.platform_data; struct net_device *dev; struct at91_private *lp; unsigned int val; diff --git a/drivers/net/ethernet/cadence/at91_ether.h b/drivers/net/ethernet/cadence/at91_ether.h index 353f4da..3725fbb0 100644 --- a/drivers/net/ethernet/cadence/at91_ether.h +++ b/drivers/net/ethernet/cadence/at91_ether.h @@ -85,7 +85,9 @@ struct recv_desc_bufs struct at91_private { struct mii_if_info mii; /* ethtool support */ - struct at91_eth_data board_data; /* board-specific configuration */ + struct macb_platform_data board_data; /* board-specific + * configuration (shared with + * macb for common data */ struct clk *ether_clk; /* clock */ /* PHY */ diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index b0fa478..d97d9ce 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -19,12 +19,10 @@ #include #include #include +#include #include #include -#include -#include - #include "macb.h" #define RX_BUFFER_SIZE 128 @@ -191,7 +189,7 @@ static int macb_mii_probe(struct net_device *dev) { struct macb *bp = netdev_priv(dev); struct phy_device *phydev; - struct eth_platform_data *pdata; + struct macb_platform_data *pdata; int ret; phydev = phy_find_first(bp->mii_bus); @@ -228,7 +226,7 @@ static int macb_mii_probe(struct net_device *dev) static int macb_mii_init(struct macb *bp) { - struct eth_platform_data *pdata; + struct macb_platform_data *pdata; int err = -ENXIO, i; /* Enable management port */ @@ -1119,7 +1117,7 @@ static const struct net_device_ops macb_netdev_ops = { static int __init macb_probe(struct platform_device *pdev) { - struct eth_platform_data *pdata; + struct macb_platform_data *pdata; struct resource *regs; struct net_device *dev; struct macb *bp; diff --git a/include/linux/platform_data/macb.h b/include/linux/platform_data/macb.h new file mode 100644 index 0000000..e7c748f --- /dev/null +++ b/include/linux/platform_data/macb.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __MACB_PDATA_H__ +#define __MACB_PDATA_H__ + +struct macb_platform_data { + u32 phy_mask; + u8 phy_irq_pin; /* PHY IRQ */ + u8 is_rmii; /* using RMII interface? */ +}; + +#endif /* __MACB_PDATA_H__ */ -- cgit v0.10.2 From c220f8cd01198552a616c4216f2a8e719fdb5fd9 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Tue, 8 Mar 2011 20:27:08 +0000 Subject: macb: convert printk to netdev_ and friends macb is already using the dev_dbg() and friends helpers so use netdev_() along with a pr_fmt() definition to make the printing a little cleaner. Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Jamie Iles Acked-by: David S. Miller Acked-by: Nicolas Ferre Tested-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index d97d9ce..aa1d597 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include @@ -82,7 +83,7 @@ static void __init macb_get_hwaddr(struct macb *bp) if (is_valid_ether_addr(addr)) { memcpy(bp->dev->dev_addr, addr, sizeof(addr)); } else { - dev_info(&bp->pdev->dev, "invalid hw address, using random\n"); + netdev_info(bp->dev, "invalid hw address, using random\n"); random_ether_addr(bp->dev->dev_addr); } } @@ -176,11 +177,12 @@ static void macb_handle_link_change(struct net_device *dev) if (status_change) { if (phydev->link) - printk(KERN_INFO "%s: link up (%d/%s)\n", - dev->name, phydev->speed, - DUPLEX_FULL == phydev->duplex ? "Full":"Half"); + netdev_info(dev, "link up (%d/%s)\n", + phydev->speed, + phydev->duplex == DUPLEX_FULL ? + "Full" : "Half"); else - printk(KERN_INFO "%s: link down\n", dev->name); + netdev_info(dev, "link down\n"); } } @@ -194,7 +196,7 @@ static int macb_mii_probe(struct net_device *dev) phydev = phy_find_first(bp->mii_bus); if (!phydev) { - printk (KERN_ERR "%s: no PHY found\n", dev->name); + netdev_err(dev, "no PHY found\n"); return -1; } @@ -207,7 +209,7 @@ static int macb_mii_probe(struct net_device *dev) PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII); if (ret) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); + netdev_err(dev, "Could not attach to PHY\n"); return ret; } @@ -301,14 +303,13 @@ static void macb_tx(struct macb *bp) status = macb_readl(bp, TSR); macb_writel(bp, TSR, status); - dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n", - (unsigned long)status); + netdev_dbg(bp->dev, "macb_tx status = %02lx\n", (unsigned long)status); if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) { int i; - printk(KERN_ERR "%s: TX %s, resetting buffers\n", - bp->dev->name, status & MACB_BIT(UND) ? - "underrun" : "retry limit exceeded"); + netdev_err(bp->dev, "TX %s, resetting buffers\n", + status & MACB_BIT(UND) ? + "underrun" : "retry limit exceeded"); /* Transfer ongoing, disable transmitter, to avoid confusion */ if (status & MACB_BIT(TGO)) @@ -367,8 +368,8 @@ static void macb_tx(struct macb *bp) if (!(bufstat & MACB_BIT(TX_USED))) break; - dev_dbg(&bp->pdev->dev, "skb %u (data %p) TX complete\n", - tail, skb->data); + netdev_dbg(bp->dev, "skb %u (data %p) TX complete\n", + tail, skb->data); dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, DMA_TO_DEVICE); bp->stats.tx_packets++; @@ -393,8 +394,8 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl); - dev_dbg(&bp->pdev->dev, "macb_rx_frame frags %u - %u (len %u)\n", - first_frag, last_frag, len); + netdev_dbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n", + first_frag, last_frag, len); skb = dev_alloc_skb(len + RX_OFFSET); if (!skb) { @@ -435,8 +436,8 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, bp->stats.rx_packets++; bp->stats.rx_bytes += len; - dev_dbg(&bp->pdev->dev, "received skb of length %u, csum: %08x\n", - skb->len, skb->csum); + netdev_dbg(bp->dev, "received skb of length %u, csum: %08x\n", + skb->len, skb->csum); netif_receive_skb(skb); return 0; @@ -513,8 +514,8 @@ static int macb_poll(struct napi_struct *napi, int budget) work_done = 0; - dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n", - (unsigned long)status, budget); + netdev_dbg(bp->dev, "poll: status = %08lx, budget = %d\n", + (unsigned long)status, budget); work_done = macb_rx(bp, budget); if (work_done < budget) { @@ -563,8 +564,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) macb_writel(bp, IDR, MACB_RX_INT_FLAGS); if (napi_schedule_prep(&bp->napi)) { - dev_dbg(&bp->pdev->dev, - "scheduling RX softirq\n"); + netdev_dbg(bp->dev, "scheduling RX softirq\n"); __napi_schedule(&bp->napi); } } @@ -585,11 +585,11 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) if (status & MACB_BIT(HRESP)) { /* - * TODO: Reset the hardware, and maybe move the printk - * to a lower-priority context as well (work queue?) + * TODO: Reset the hardware, and maybe move the + * netdev_err to a lower-priority context as well + * (work queue?) */ - printk(KERN_ERR "%s: DMA bus error: HRESP not OK\n", - dev->name); + netdev_err(dev, "DMA bus error: HRESP not OK\n"); } status = macb_readl(bp, ISR); @@ -624,16 +624,12 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; #ifdef DEBUG - int i; - dev_dbg(&bp->pdev->dev, - "start_xmit: len %u head %p data %p tail %p end %p\n", - skb->len, skb->head, skb->data, - skb_tail_pointer(skb), skb_end_pointer(skb)); - dev_dbg(&bp->pdev->dev, - "data:"); - for (i = 0; i < 16; i++) - printk(" %02x", (unsigned int)skb->data[i]); - printk("\n"); + netdev_dbg(bp->dev, + "start_xmit: len %u head %p data %p tail %p end %p\n", + skb->len, skb->head, skb->data, + skb_tail_pointer(skb), skb_end_pointer(skb)); + print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1, + skb->data, 16, true); #endif len = skb->len; @@ -643,21 +639,20 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) if (TX_BUFFS_AVAIL(bp) < 1) { netif_stop_queue(dev); spin_unlock_irqrestore(&bp->lock, flags); - dev_err(&bp->pdev->dev, - "BUG! Tx Ring full when queue awake!\n"); - dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n", - bp->tx_head, bp->tx_tail); + netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n"); + netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n", + bp->tx_head, bp->tx_tail); return NETDEV_TX_BUSY; } entry = bp->tx_head; - dev_dbg(&bp->pdev->dev, "Allocated ring entry %u\n", entry); + netdev_dbg(bp->dev, "Allocated ring entry %u\n", entry); mapping = dma_map_single(&bp->pdev->dev, skb->data, len, DMA_TO_DEVICE); bp->tx_skb[entry].skb = skb; bp->tx_skb[entry].mapping = mapping; - dev_dbg(&bp->pdev->dev, "Mapped skb data %p to DMA addr %08lx\n", - skb->data, (unsigned long)mapping); + netdev_dbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n", + skb->data, (unsigned long)mapping); ctrl = MACB_BF(TX_FRMLEN, len); ctrl |= MACB_BIT(TX_LAST); @@ -721,27 +716,27 @@ static int macb_alloc_consistent(struct macb *bp) &bp->rx_ring_dma, GFP_KERNEL); if (!bp->rx_ring) goto out_err; - dev_dbg(&bp->pdev->dev, - "Allocated RX ring of %d bytes at %08lx (mapped %p)\n", - size, (unsigned long)bp->rx_ring_dma, bp->rx_ring); + netdev_dbg(bp->dev, + "Allocated RX ring of %d bytes at %08lx (mapped %p)\n", + size, (unsigned long)bp->rx_ring_dma, bp->rx_ring); size = TX_RING_BYTES; bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size, &bp->tx_ring_dma, GFP_KERNEL); if (!bp->tx_ring) goto out_err; - dev_dbg(&bp->pdev->dev, - "Allocated TX ring of %d bytes at %08lx (mapped %p)\n", - size, (unsigned long)bp->tx_ring_dma, bp->tx_ring); + netdev_dbg(bp->dev, + "Allocated TX ring of %d bytes at %08lx (mapped %p)\n", + size, (unsigned long)bp->tx_ring_dma, bp->tx_ring); size = RX_RING_SIZE * RX_BUFFER_SIZE; bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size, &bp->rx_buffers_dma, GFP_KERNEL); if (!bp->rx_buffers) goto out_err; - dev_dbg(&bp->pdev->dev, - "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n", - size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers); + netdev_dbg(bp->dev, + "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n", + size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers); return 0; @@ -952,7 +947,7 @@ static int macb_open(struct net_device *dev) struct macb *bp = netdev_priv(dev); int err; - dev_dbg(&bp->pdev->dev, "open\n"); + netdev_dbg(bp->dev, "open\n"); /* if the phy is not yet register, retry later*/ if (!bp->phy_dev) @@ -963,9 +958,8 @@ static int macb_open(struct net_device *dev) err = macb_alloc_consistent(bp); if (err) { - printk(KERN_ERR - "%s: Unable to allocate DMA memory (error %d)\n", - dev->name, err); + netdev_err(dev, "Unable to allocate DMA memory (error %d)\n", + err); return err; } @@ -1174,9 +1168,8 @@ static int __init macb_probe(struct platform_device *pdev) dev->irq = platform_get_irq(pdev, 0); err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev); if (err) { - printk(KERN_ERR - "%s: Unable to request IRQ %d (error %d)\n", - dev->name, dev->irq, err); + dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n", + dev->irq, err); goto err_out_iounmap; } @@ -1228,13 +1221,12 @@ static int __init macb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d (%pM)\n", - dev->name, dev->base_addr, dev->irq, dev->dev_addr); + netdev_info(dev, "Atmel MACB at 0x%08lx irq %d (%pM)\n", + dev->base_addr, dev->irq, dev->dev_addr); phydev = bp->phy_dev; - printk(KERN_INFO "%s: attached PHY driver [%s] " - "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, - phydev->drv->name, dev_name(&phydev->dev), phydev->irq); + netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", + phydev->drv->name, dev_name(&phydev->dev), phydev->irq); return 0; -- cgit v0.10.2 From 1b6cec8a6910ca08d727898453baad22b0122920 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Nov 2011 15:15:57 +0900 Subject: ARM: mach-shmobile: Kota2 PINT fix Support PINT on sh73a0 and Kota2 using INTC PINT macros. With this patch applied the Kota2 ethernet is handled through one of the chained sh73a0 PINT interrupt controllers. sh73a0 PINT support is included in 3.2-rc but the Kota2 board code does not make use of this shared code base without this patch. Without this patch kota2 on-board ethernet is broken. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index bd9a784..5e084b9 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -56,7 +56,7 @@ static struct resource smsc9220_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = gic_spi(33), /* PINTA2 @ PORT144 */ + .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */ .flags = IORESOURCE_IRQ, }, }; @@ -317,18 +317,6 @@ static void __init kota2_map_io(void) shmobile_setup_console(); } -#define PINTER0A 0xe69000a0 -#define PINTCR0A 0xe69000b0 - -void __init kota2_init_irq(void) -{ - sh73a0_init_irq(); - - /* setup PINT: enable PINTA2 as active low */ - __raw_writel(1 << 29, PINTER0A); - __raw_writew(2 << 10, PINTCR0A); -} - static void __init kota2_init(void) { sh73a0_pinmux_init(); @@ -447,7 +435,7 @@ struct sys_timer kota2_timer = { MACHINE_START(KOTA2, "kota2") .map_io = kota2_map_io, - .init_irq = kota2_init_irq, + .init_irq = sh73a0_init_irq, .handle_irq = shmobile_handle_irq_gic, .init_machine = kota2_init, .timer = &kota2_timer, -- cgit v0.10.2 From dcb4ea869877b00fd1c761662bfd9359d15a8c2a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Nov 2011 15:29:54 +0900 Subject: ARM: mach-shmobile: Kota2 GIC Sparse IRQ fix Fix IRQ support on the Kota2 board. The sh73a0 and the Kota2 board make use of the ARM GIC hardware block as main interrupt controller. The following commit changed the default behaviour for non-device tree platforms and broke Kota2 irq support: f37a53c ARM: gic: fix irq_alloc_descs handling for sparse irq Without this fix the following warning triggers at boot: NR_IRQS:1024 nr_irqs:1024 1024 ------------[ cut here ]------------ WARNING: at arch/arm/common/gic.c:607 gic_init+0x90/0x2e4() Cannot allocate irq_descs @ IRQ16, assuming pre-allocated [] (unwind_backtrace+0x0/0xe0) from [] (warn_slowpath_commo) [] (warn_slowpath_common+0x48/0x60) from [] (warn_slowpath_) [] (warn_slowpath_fmt+0x2c/0x3c) from [] (gic_init+0x90/0x2) [] (gic_init+0x90/0x2e4) from [] (sh73a0_init_irq+0x30/0x18) [] (sh73a0_init_irq+0x30/0x184) from [] (init_IRQ+0x14/0x1c) [] (init_IRQ+0x14/0x1c) from [] (start_kernel+0x15c/0x2b8) [] (start_kernel+0x15c/0x2b8) from [<4000803c>] (0x4000803c) ---[ end trace 1b75b31a2719ed1c ]--- With this fix applied interrupts work as expected. Signed-off-by: Magnus Damm Acked-by: Rob Herring Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index 5e084b9..53e5e45 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -435,6 +435,7 @@ struct sys_timer kota2_timer = { MACHINE_START(KOTA2, "kota2") .map_io = kota2_map_io, + .nr_irqs = NR_IRQS_LEGACY, .init_irq = sh73a0_init_irq, .handle_irq = shmobile_handle_irq_gic, .init_machine = kota2_init, -- cgit v0.10.2 From 33661c9e2062865acde9d421c971f1c142cf99ca Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Nov 2011 15:44:58 +0900 Subject: ARM: mach-shmobile: Kota2 TPU LED platform data This patch updates the Kota2 board support code to use the recently merged TPU LED driver whenever possible. The sh73a0 SoC has 5 TPU hardware blocks each with 4 timer channels which in theory allows a total of 20 LEDs to be controlled by "leds-renesas-tpu" driver instances. The Kota2 board has 4 LEDs connected to GPIO pins that also come with TPU pin functions, so this patch ties up these 4 LEDS and leaves the remaining 3 LEDS for the GPIO based LED driver. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index 53e5e45..f44150b 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -157,10 +158,6 @@ static struct platform_device gpio_keys_device = { #define GPIO_LED(n, g) { .name = n, .gpio = g } static struct gpio_led gpio_leds[] = { - GPIO_LED("V2513", GPIO_PORT153), /* PORT153 [TPU1T02] -> V2513 */ - GPIO_LED("V2514", GPIO_PORT199), /* PORT199 [TPU4TO1] -> V2514 */ - GPIO_LED("V2515", GPIO_PORT197), /* PORT197 [TPU2TO1] -> V2515 */ - GPIO_LED("KEYLED", GPIO_PORT163), /* PORT163 [TPU3TO0] -> KEYLED */ GPIO_LED("G", GPIO_PORT20), /* PORT20 [GPO0] -> LED7 -> "G" */ GPIO_LED("H", GPIO_PORT21), /* PORT21 [GPO1] -> LED8 -> "H" */ GPIO_LED("J", GPIO_PORT22), /* PORT22 [GPO2] -> LED9 -> "J" */ @@ -179,6 +176,119 @@ static struct platform_device gpio_leds_device = { }, }; +/* TPU LED */ +static struct led_renesas_tpu_config led_renesas_tpu12_pdata = { + .name = "V2513", + .pin_gpio_fn = GPIO_FN_TPU1TO2, + .pin_gpio = GPIO_PORT153, + .channel_offset = 0x90, + .timer_bit = 2, + .max_brightness = 1000, +}; + +static struct resource tpu12_resources[] = { + [0] = { + .name = "TPU12", + .start = 0xe6610090, + .end = 0xe66100b5, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device leds_tpu12_device = { + .name = "leds-renesas-tpu", + .id = 12, + .dev = { + .platform_data = &led_renesas_tpu12_pdata, + }, + .num_resources = ARRAY_SIZE(tpu12_resources), + .resource = tpu12_resources, +}; + +static struct led_renesas_tpu_config led_renesas_tpu41_pdata = { + .name = "V2514", + .pin_gpio_fn = GPIO_FN_TPU4TO1, + .pin_gpio = GPIO_PORT199, + .channel_offset = 0x50, + .timer_bit = 1, + .max_brightness = 1000, +}; + +static struct resource tpu41_resources[] = { + [0] = { + .name = "TPU41", + .start = 0xe6640050, + .end = 0xe6640075, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device leds_tpu41_device = { + .name = "leds-renesas-tpu", + .id = 41, + .dev = { + .platform_data = &led_renesas_tpu41_pdata, + }, + .num_resources = ARRAY_SIZE(tpu41_resources), + .resource = tpu41_resources, +}; + +static struct led_renesas_tpu_config led_renesas_tpu21_pdata = { + .name = "V2515", + .pin_gpio_fn = GPIO_FN_TPU2TO1, + .pin_gpio = GPIO_PORT197, + .channel_offset = 0x50, + .timer_bit = 1, + .max_brightness = 1000, +}; + +static struct resource tpu21_resources[] = { + [0] = { + .name = "TPU21", + .start = 0xe6620050, + .end = 0xe6620075, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device leds_tpu21_device = { + .name = "leds-renesas-tpu", + .id = 21, + .dev = { + .platform_data = &led_renesas_tpu21_pdata, + }, + .num_resources = ARRAY_SIZE(tpu21_resources), + .resource = tpu21_resources, +}; + +static struct led_renesas_tpu_config led_renesas_tpu30_pdata = { + .name = "KEYLED", + .pin_gpio_fn = GPIO_FN_TPU3TO0, + .pin_gpio = GPIO_PORT163, + .channel_offset = 0x10, + .timer_bit = 0, + .max_brightness = 1000, +}; + +static struct resource tpu30_resources[] = { + [0] = { + .name = "TPU30", + .start = 0xe6630010, + .end = 0xe6630035, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device leds_tpu30_device = { + .name = "leds-renesas-tpu", + .id = 30, + .dev = { + .platform_data = &led_renesas_tpu30_pdata, + }, + .num_resources = ARRAY_SIZE(tpu30_resources), + .resource = tpu30_resources, +}; + /* MMCIF */ static struct resource mmcif_resources[] = { [0] = { @@ -291,6 +401,10 @@ static struct platform_device *kota2_devices[] __initdata = { &keysc_device, &gpio_keys_device, &gpio_leds_device, + &leds_tpu12_device, + &leds_tpu41_device, + &leds_tpu21_device, + &leds_tpu30_device, &mmcif_device, &sdhi0_device, &sdhi1_device, diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 61a846b..a56d6c6 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -113,6 +113,12 @@ static struct clk main_clk = { .ops = &main_clk_ops, }; +/* Divide Main clock by two */ +static struct clk main_div2_clk = { + .ops = &div2_clk_ops, + .parent = &main_clk, +}; + /* PLL0, PLL1, PLL2, PLL3 */ static unsigned long pll_recalc(struct clk *clk) { @@ -181,6 +187,7 @@ static struct clk *main_clks[] = { &extal1_div2_clk, &extal2_div2_clk, &main_clk, + &main_div2_clk, &pll0_clk, &pll1_clk, &pll2_clk, @@ -268,6 +275,7 @@ enum { MSTP001, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, MSTP331, MSTP329, MSTP325, MSTP323, MSTP318, MSTP314, MSTP313, MSTP312, MSTP311, + MSTP303, MSTP302, MSTP301, MSTP300, MSTP411, MSTP410, MSTP403, MSTP_NR }; @@ -301,6 +309,10 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */ [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */ + [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */ + [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */ + [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */ + [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */ [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */ [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */ @@ -350,6 +362,10 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ + CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ + CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ + CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ + CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ -- cgit v0.10.2 From eded9143151a116753b1d8e893bc2d37f8687e0b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Nov 2011 15:31:40 +0900 Subject: ARM: mach-shmobile: AG5EVM GIC Sparse IRQ fix Fix IRQ support on the AG5EVM board. The sh73a0 and the AG5EVM board make use of the ARM GIC hardware block as main interrupt controller. The following commit changed the default behaviour for non-device tree platforms and broke AG5EVM irq support: f37a53c ARM: gic: fix irq_alloc_descs handling for sparse irq Without this fix the following warning triggers at boot: NR_IRQS:1024 nr_irqs:1024 1024 ------------[ cut here ]------------ WARNING: at arch/arm/common/gic.c:607 gic_init+0x90/0x2e4() Cannot allocate irq_descs @ IRQ16, assuming pre-allocated [] (unwind_backtrace+0x0/0xe0) from [] (warn_slowpath_commo) [] (warn_slowpath_common+0x48/0x60) from [] (warn_slowpath_) [] (warn_slowpath_fmt+0x2c/0x3c) from [] (gic_init+0x90/0x2) [] (gic_init+0x90/0x2e4) from [] (sh73a0_init_irq+0x30/0x18) [] (sh73a0_init_irq+0x30/0x184) from [] (init_IRQ+0x14/0x1c) [] (init_IRQ+0x14/0x1c) from [] (start_kernel+0x15c/0x2b8) [] (start_kernel+0x15c/0x2b8) from [<4000803c>] (0x4000803c) ---[ end trace 1b75b31a2719ed1c ]--- With this fix applied interrupts work as expected. Signed-off-by: Magnus Damm Acked-by: Rob Herring Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index b862e9f..7119b87 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -607,6 +607,7 @@ struct sys_timer ag5evm_timer = { MACHINE_START(AG5EVM, "ag5evm") .map_io = ag5evm_map_io, + .nr_irqs = NR_IRQS_LEGACY, .init_irq = sh73a0_init_irq, .handle_irq = shmobile_handle_irq_gic, .init_machine = ag5evm_init, -- cgit v0.10.2 From 9bcc0a5d0de137b3a154dc951c5ff70dce815879 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 22 Nov 2011 15:23:17 +0900 Subject: ARM: mach-shmobile: SH73A0 external Ethernet fix Keep the ZB clock enabled on sh73a0 to allow the BSC to access external peripherals hooked up to CS signals. This is needed to unbreak Ethernet support on sh73a0 boards such as AG5EVM and Kota2 together with the following patch: 794d78f drivers: sh: late disabling of clocks V2 Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 61a846b..84fd33c 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -243,7 +243,7 @@ static struct clk div6_clks[DIV6_NR] = { [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0), [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0), [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0), - [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0), + [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT), [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0), [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0), [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0), -- cgit v0.10.2 From ff83bd82cb343d37b5ab8e402aaad9ef33d03f1e Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 12 Nov 2011 22:33:30 -0300 Subject: [media] af9015: limit I2C access to keep FW happy AF9015 firmware does not like if it gets interrupted by I2C adapter request on some critical phases. During normal operation I2C adapter is used only 2nd demodulator and tuner on dual tuner devices. Override demodulator callbacks and use mutex for limit access to those "critical" paths to keep AF9015 happy. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index c6c275b..033aa8a 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1093,9 +1093,80 @@ error: return ret; } +/* override demod callbacks for resource locking */ +static int af9015_af9013_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->set_frontend[adap->id](fe, params); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_read_status(struct dvb_frontend *fe, + fe_status_t *status) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->read_status[adap->id](fe, status); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_init(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->init[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override demod callbacks for resource locking */ +static int af9015_af9013_sleep(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->init[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { int ret; + struct af9015_state *state = adap->dev->priv; if (adap->id == 1) { /* copy firmware to 2nd demodulator */ @@ -1116,6 +1187,32 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], &adap->dev->i2c_adap); + /* + * AF9015 firmware does not like if it gets interrupted by I2C adapter + * request on some critical phases. During normal operation I2C adapter + * is used only 2nd demodulator and tuner on dual tuner devices. + * Override demodulator callbacks and use mutex for limit access to + * those "critical" paths to keep AF9015 happy. + * Note: we abuse unused usb_mutex here. + */ + if (adap->fe_adap[0].fe) { + state->set_frontend[adap->id] = + adap->fe_adap[0].fe->ops.set_frontend; + adap->fe_adap[0].fe->ops.set_frontend = + af9015_af9013_set_frontend; + + state->read_status[adap->id] = + adap->fe_adap[0].fe->ops.read_status; + adap->fe_adap[0].fe->ops.read_status = + af9015_af9013_read_status; + + state->init[adap->id] = adap->fe_adap[0].fe->ops.init; + adap->fe_adap[0].fe->ops.init = af9015_af9013_init; + + state->sleep[adap->id] = adap->fe_adap[0].fe->ops.sleep; + adap->fe_adap[0].fe->ops.sleep = af9015_af9013_sleep; + } + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 6252ea6..4a12617 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -102,6 +102,13 @@ struct af9015_state { u8 rc_repeat; u32 rc_keycode; u8 rc_last[4]; + + /* for demod callback override */ + int (*set_frontend[2]) (struct dvb_frontend *fe, + struct dvb_frontend_parameters *params); + int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); + int (*init[2]) (struct dvb_frontend *fe); + int (*sleep[2]) (struct dvb_frontend *fe); }; struct af9015_config { -- cgit v0.10.2 From d7d89dc85b9ec0e94f16e811d5f440106e2e77c0 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 13 Nov 2011 00:22:33 -0300 Subject: [media] tda18218: fix 6 MHz default IF frequency Default IF for 6 MHz bandwidth is 3 MHz. Use that. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c index aacfe23..4fc2973 100644 --- a/drivers/media/common/tuners/tda18218.c +++ b/drivers/media/common/tuners/tda18218.c @@ -141,7 +141,7 @@ static int tda18218_set_params(struct dvb_frontend *fe, switch (params->u.ofdm.bandwidth) { case BANDWIDTH_6_MHZ: LP_Fc = 0; - LO_Frac = params->frequency + 4000000; + LO_Frac = params->frequency + 3000000; break; case BANDWIDTH_7_MHZ: LP_Fc = 1; -- cgit v0.10.2 From 576b849ea7af9ac05dca3ca92bc62c7528e8f0ef Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sun, 9 Oct 2011 08:59:16 -0300 Subject: [media] mxl5007t: fix reg read Register to read should be written to register 0xfb and then perform I2C read to get reg value. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 7eb1bf7..5d02221 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c @@ -488,9 +488,10 @@ static int mxl5007t_write_regs(struct mxl5007t_state *state, static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) { + u8 buf[2] = { 0xfb, reg }; struct i2c_msg msg[] = { { .addr = state->i2c_props.addr, .flags = 0, - .buf = ®, .len = 1 }, + .buf = buf, .len = 2 }, { .addr = state->i2c_props.addr, .flags = I2C_M_RD, .buf = val, .len = 1 }, }; -- cgit v0.10.2 From ffe06198876a3cbda1cd642883adcec5304d9442 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Nov 2011 19:22:10 -0200 Subject: MAINTAINERS: Update media entries Now that we've created a /drivers/staging/media, put it together with /drivers/media. Also, added there a missing entry for the Media API spec. Signed-off-by: Mauro Carvalho Chehab diff --git a/MAINTAINERS b/MAINTAINERS index e839b95..273b049 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4234,7 +4234,9 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git S: Maintained F: Documentation/dvb/ F: Documentation/video4linux/ +F: Documentation/DocBook/media/ F: drivers/media/ +F: drivers/staging/media/ F: include/media/ F: include/linux/dvb/ F: include/linux/videodev*.h -- cgit v0.10.2 From e067d5abdd04cbf1bed466f95682c67e2496ba42 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 16 Nov 2011 22:17:03 -0300 Subject: [media] media/staging: fix allyesconfig build error Fix x86 allyesconfig builds. Builds fail due to a non-static variable named 'debug' in drivers/staging/media/as102/. Signed-off-by: Randy Dunlap Cc: Pierrick Hascoet Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c index d335c7d..828526d 100644 --- a/drivers/staging/media/as102/as102_drv.c +++ b/drivers/staging/media/as102/as102_drv.c @@ -32,8 +32,8 @@ #include "as102_fw.h" #include "dvbdev.h" -int debug; -module_param_named(debug, debug, int, 0644); +int as102_debug; +module_param_named(debug, as102_debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)"); int dual_tuner; diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h index bcda635..fd33f5a 100644 --- a/drivers/staging/media/as102/as102_drv.h +++ b/drivers/staging/media/as102/as102_drv.h @@ -37,7 +37,8 @@ extern struct spi_driver as102_spi_driver; #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver" #define DRIVER_NAME "as10x_usb" -extern int debug; +extern int as102_debug; +#define debug as102_debug #define dprintk(debug, args...) \ do { if (debug) { \ -- cgit v0.10.2 From 7acde02a5bf4d3c32cd197eb7ce2257e6a0e17b7 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 13 Sep 2011 14:07:09 -0300 Subject: [media] s5p-fimc: Fix wrong pointer dereference when unregistering sensors After i2c_unregister_device() has been called the client object can already be freed and thus using the client pointer may lead to dereferencing freed memory. Avoid this by saving the adapter pointer for further use before i2c_unregister_device() call. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index cc337b1..d558ae7 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -220,6 +220,7 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, s_info->pdata->board_info, NULL); if (IS_ERR_OR_NULL(sd)) { + i2c_put_adapter(adapter); v4l2_err(&fmd->v4l2_dev, "Failed to acquire subdev\n"); return NULL; } @@ -234,12 +235,15 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) { struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_adapter *adapter; if (!client) return; v4l2_device_unregister_subdev(sd); + adapter = client->adapter; i2c_unregister_device(client); - i2c_put_adapter(client->adapter); + if (adapter) + i2c_put_adapter(adapter); } static int fimc_md_register_sensor_entities(struct fimc_md *fmd) -- cgit v0.10.2 From 64c570f505a0eac4914402bb7832d019c44eabd8 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Sun, 11 Sep 2011 10:36:13 -0300 Subject: [media] s5p-fimc: Fix error in the capture subdev deinitialization Make sure the subdev pointer is cleared when the subdev object has been freed. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index c8d91b0..382dacd 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -1375,7 +1375,7 @@ static void fimc_destroy_capture_subdev(struct fimc_dev *fimc) media_entity_cleanup(&sd->entity); v4l2_device_unregister_subdev(sd); kfree(sd); - sd = NULL; + fimc->vid_cap.subdev = NULL; } /* Set default format at the sensor and host interface */ -- cgit v0.10.2 From 7aa9f1844a3aac428ef7977a9f1da706718afe0d Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 4 Nov 2011 09:59:52 -0300 Subject: [media] s5p-fimc: Fix initialization for proper system suspend support ST_LPM bit must not be initially set, so the first resume helper call properly quiesce the device's operation. Also fimc_runtime_suspend() at device remove is unneeded and leads to unbalanced clock disable so remove it. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 19ca6db..ef535289 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -1615,7 +1615,6 @@ static int fimc_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; fimc->pdata = pdata; - set_bit(ST_LPM, &fimc->state); init_waitqueue_head(&fimc->irq_queue); spin_lock_init(&fimc->slock); @@ -1780,7 +1779,6 @@ static int __devexit fimc_remove(struct platform_device *pdev) struct fimc_dev *fimc = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - fimc_runtime_suspend(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); -- cgit v0.10.2 From 2c1bb62e217f4f2eb6fa9734dcb331bc09c7768e Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 5 Oct 2011 14:20:45 -0300 Subject: [media] s5p-fimc: Fix buffer dequeue order issue When requested more than 2 buffers the buffer dequeue order was wrong due to erroneous updating FIMC registers in every interrupt handler call. This also fixes regression of resetting the output DMA buffer pointer at wrong time, when some buffers are already queued in hardware. The hardware is reset in the start_streaming callback in order to align the H/W state with the software output buffer pointer (buf_index). Additionally a simple write to S5P_CISCCTRL register is replaced with a read/modification/write to make sure the scaler is not being disabled in fimc_hw_set_scaler(). Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 382dacd..70f741f 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -98,6 +98,10 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend) vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); } set_bit(ST_CAPT_SUSPENDED, &fimc->state); + + fimc_hw_reset(fimc); + cap->buf_index = 0; + spin_unlock_irqrestore(&fimc->slock, flags); if (streaming) @@ -137,7 +141,7 @@ int fimc_capture_config_update(struct fimc_ctx *ctx) struct fimc_dev *fimc = ctx->fimc_dev; int ret; - if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state)) + if (!test_bit(ST_CAPT_APPLY_CFG, &fimc->state)) return 0; spin_lock(&ctx->slock); @@ -150,7 +154,7 @@ int fimc_capture_config_update(struct fimc_ctx *ctx) fimc_hw_set_rotation(ctx); fimc_prepare_dma_offset(ctx, &ctx->d_frame); fimc_hw_set_out_dma(ctx); - set_bit(ST_CAPT_APPLY_CFG, &fimc->state); + clear_bit(ST_CAPT_APPLY_CFG, &fimc->state); } spin_unlock(&ctx->slock); return ret; @@ -164,7 +168,6 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) int min_bufs; int ret; - fimc_hw_reset(fimc); vid_cap->frame_count = 0; ret = fimc_init_capture(fimc); diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index ef535289..9c3a8c5 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -1706,8 +1706,6 @@ static int fimc_runtime_resume(struct device *dev) /* Enable clocks and perform basic initalization */ clk_enable(fimc->clock[CLK_GATE]); fimc_hw_reset(fimc); - if (fimc->variant->out_buf_count > 4) - fimc_hw_set_dma_seq(fimc, 0xF); /* Resume the capture or mem-to-mem device */ if (fimc_capture_busy(fimc)) @@ -1749,8 +1747,6 @@ static int fimc_resume(struct device *dev) return 0; } fimc_hw_reset(fimc); - if (fimc->variant->out_buf_count > 4) - fimc_hw_set_dma_seq(fimc, 0xF); spin_unlock_irqrestore(&fimc->slock, flags); if (fimc_capture_busy(fimc)) diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c index 20e664e..44f5c2d 100644 --- a/drivers/media/video/s5p-fimc/fimc-reg.c +++ b/drivers/media/video/s5p-fimc/fimc-reg.c @@ -35,6 +35,9 @@ void fimc_hw_reset(struct fimc_dev *dev) cfg = readl(dev->regs + S5P_CIGCTRL); cfg &= ~S5P_CIGCTRL_SWRST; writel(cfg, dev->regs + S5P_CIGCTRL); + + if (dev->variant->out_buf_count > 4) + fimc_hw_set_dma_seq(dev, 0xF); } static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx) @@ -251,7 +254,14 @@ static void fimc_hw_set_scaler(struct fimc_ctx *ctx) struct fimc_scaler *sc = &ctx->scaler; struct fimc_frame *src_frame = &ctx->s_frame; struct fimc_frame *dst_frame = &ctx->d_frame; - u32 cfg = 0; + + u32 cfg = readl(dev->regs + S5P_CISCCTRL); + + cfg &= ~(S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE | + S5P_CISCCTRL_SCALEUP_H | S5P_CISCCTRL_SCALEUP_V | + S5P_CISCCTRL_SCALERBYPASS | S5P_CISCCTRL_ONE2ONE | + S5P_CISCCTRL_INRGB_FMT_MASK | S5P_CISCCTRL_OUTRGB_FMT_MASK | + S5P_CISCCTRL_INTERLACE | S5P_CISCCTRL_RGB_EXT); if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); @@ -308,9 +318,9 @@ void fimc_hw_set_mainscaler(struct fimc_ctx *ctx) fimc_hw_set_scaler(ctx); cfg = readl(dev->regs + S5P_CISCCTRL); + cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); if (variant->has_mainscaler_ext) { - cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio); cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio); writel(cfg, dev->regs + S5P_CISCCTRL); @@ -323,7 +333,6 @@ void fimc_hw_set_mainscaler(struct fimc_ctx *ctx) cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio); writel(cfg, dev->regs + S5P_CIEXTEN); } else { - cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio); cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio); writel(cfg, dev->regs + S5P_CISCCTRL); -- cgit v0.10.2 From 5cbf6f16ecc07e9f73107c1adf95013bce9f2cf6 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 7 Oct 2011 07:40:00 -0300 Subject: [media] s5p-fimc: Allow probe() to succeed with null platform data The "s5p-fimc-md" platform device platform_data is used to pass attached camera sensor data. Not allowing device probe() to succeed when it's null prevents using FIMC as a mem-to-mem device only. Fix this by removing the platform_data check against null and registering sensors only if platform_data is specified. Also add logging of the information which /dev/video is assigned to which device during probe(). Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index d558ae7..fc81f6f 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -385,20 +385,28 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) static int fimc_md_register_video_nodes(struct fimc_md *fmd) { + struct video_device *vdev; int i, ret = 0; for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) { if (!fmd->fimc[i]) continue; - if (fmd->fimc[i]->m2m.vfd) - ret = video_register_device(fmd->fimc[i]->m2m.vfd, - VFL_TYPE_GRABBER, -1); - if (ret) - break; - if (fmd->fimc[i]->vid_cap.vfd) - ret = video_register_device(fmd->fimc[i]->vid_cap.vfd, - VFL_TYPE_GRABBER, -1); + vdev = fmd->fimc[i]->m2m.vfd; + if (vdev) { + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + if (ret) + break; + v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", + vdev->name, video_device_node_name(vdev)); + } + + vdev = fmd->fimc[i]->vid_cap.vfd; + if (vdev == NULL) + continue; + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", + vdev->name, video_device_node_name(vdev)); } return ret; @@ -746,9 +754,6 @@ static int __devinit fimc_md_probe(struct platform_device *pdev) struct fimc_md *fmd; int ret; - if (WARN(!pdev->dev.platform_data, "Platform data not specified!\n")) - return -EINVAL; - fmd = kzalloc(sizeof(struct fimc_md), GFP_KERNEL); if (!fmd) return -ENOMEM; @@ -786,9 +791,11 @@ static int __devinit fimc_md_probe(struct platform_device *pdev) if (ret) goto err3; - ret = fimc_md_register_sensor_entities(fmd); - if (ret) - goto err3; + if (pdev->dev.platform_data) { + ret = fimc_md_register_sensor_entities(fmd); + if (ret) + goto err3; + } ret = fimc_md_create_links(fmd); if (ret) goto err3; -- cgit v0.10.2 From 9c63afcb02b4313838d83c3660e45544d9fc9976 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 27 May 2011 13:12:23 -0300 Subject: [media] s5p-fimc: Adjust pixel height alignments according to the IP revision Minimum vertical pixel size alignment for input and output DMA and the scaler depend on color format, rotation, the IP instance and revision. Make vertical pixel size of format and crop better fit for each SoC revision and the IP instance by adding min_vsize_align attribute to the FIMC variant data structure. It's now common for the DMA engines and the scaler. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 70f741f..82d9ab6 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -526,7 +526,7 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; min_w = ctx->state & FIMC_DST_CROP ? dst->width : var->min_out_pixsize; min_h = ctx->state & FIMC_DST_CROP ? dst->height : var->min_out_pixsize; - if (fimc->id == 1 && var->pix_hoff) + if (var->min_vsize_align == 1 && !rotation) align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; depth = fimc_get_format_depth(ffmt); diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 9c3a8c5..7c22d78 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -1038,12 +1038,11 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f) mod_x = 6; /* 64 x 32 pixels tile */ mod_y = 5; } else { - if (fimc->id == 1 && variant->pix_hoff) + if (variant->min_vsize_align == 1) mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1; else - mod_y = mod_x; + mod_y = ffs(variant->min_vsize_align) - 1; } - dbg("mod_x: %d, mod_y: %d, max_w: %d", mod_x, mod_y, max_w); v4l_bound_align_image(&pix->width, 16, max_w, mod_x, &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0); @@ -1226,10 +1225,10 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; /* Get pixel alignment constraints. */ - if (fimc->id == 1 && fimc->variant->pix_hoff) + if (fimc->variant->min_vsize_align == 1) halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1; else - halign = ffs(min_size) - 1; + halign = ffs(fimc->variant->min_vsize_align) - 1; for (i = 0; i < f->fmt->colplanes; i++) depth += f->fmt->depth[i]; @@ -1834,6 +1833,7 @@ static struct samsung_fimc_variant fimc0_variant_s5p = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 8, + .min_vsize_align = 16, .out_buf_count = 4, .pix_limit = &s5p_pix_limit[0], }; @@ -1843,6 +1843,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 8, + .min_vsize_align = 16, .out_buf_count = 4, .pix_limit = &s5p_pix_limit[1], }; @@ -1855,6 +1856,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv210 = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 8, + .min_vsize_align = 16, .out_buf_count = 4, .pix_limit = &s5p_pix_limit[1], }; @@ -1868,6 +1870,7 @@ static struct samsung_fimc_variant fimc1_variant_s5pv210 = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 1, + .min_vsize_align = 1, .out_buf_count = 4, .pix_limit = &s5p_pix_limit[2], }; @@ -1878,6 +1881,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 8, + .min_vsize_align = 16, .out_buf_count = 4, .pix_limit = &s5p_pix_limit[2], }; @@ -1892,6 +1896,7 @@ static struct samsung_fimc_variant fimc0_variant_exynos4 = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 2, + .min_vsize_align = 1, .out_buf_count = 32, .pix_limit = &s5p_pix_limit[1], }; @@ -1904,6 +1909,7 @@ static struct samsung_fimc_variant fimc3_variant_exynos4 = { .min_inp_pixsize = 16, .min_out_pixsize = 16, .hor_offs_align = 2, + .min_vsize_align = 1, .out_buf_count = 32, .pix_limit = &s5p_pix_limit[3], }; diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index a6936da..c7f01c4 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -377,6 +377,7 @@ struct fimc_pix_limit { * @min_inp_pixsize: minimum input pixel size * @min_out_pixsize: minimum output pixel size * @hor_offs_align: horizontal pixel offset aligment + * @min_vsize_align: minimum vertical pixel size alignment * @out_buf_count: the number of buffers in output DMA sequence */ struct samsung_fimc_variant { @@ -390,6 +391,7 @@ struct samsung_fimc_variant { u16 min_inp_pixsize; u16 min_out_pixsize; u16 hor_offs_align; + u16 min_vsize_align; u16 out_buf_count; }; -- cgit v0.10.2 From d12392ec006d94e5cf6c98f7ed56ff0c881ec33f Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 20 Oct 2011 05:15:59 -0300 Subject: [media] s5p-fimc: Fail driver probing when sensor configuration is wrong When a sensor with MIPI-CSI interface is attached through platform data definition and the MIPI-CSI receiver is not selected in kernel configuration s5p-fimc driver probe() will now succeed, issuing only a warning. It was done this way to allow the driver to work even if system configuration is not exactly right. Instead make the driver's probe() fail if a MIPI-CSI sensor was requested but s5p-csis module is not present. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index fc81f6f..615c862 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -514,7 +514,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) if (WARN(csis == NULL, "MIPI-CSI interface specified " "but s5p-csis module is not loaded!\n")) - continue; + return -EINVAL; ret = media_entity_create_link(&sensor->entity, 0, &csis->entity, CSIS_PAD_SINK, -- cgit v0.10.2 From f83f71fda27650ae43558633be93652577dbc38c Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 4 Nov 2011 10:07:06 -0300 Subject: [media] s5p-fimc: Use correct fourcc for RGB565 colour format With 16-bit RGB565 colour format pixels are stored by the device in memory in the following order: | b3 | b2 | b1 | b0 | ~+-----+-----+-----+-----+ | R5 G6 B5 | R5 G6 B5 | This corresponds to V4L2_PIX_FMT_RGB565 fourcc, not V4L2_PIX_FMT_RGB565X. This change is required to avoid trouble when setting up video pipeline with the s5p-tv devices, so the colour formats at both devices can be properly matched. Cc: Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 7c22d78..07c6254 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -37,7 +37,7 @@ static char *fimc_clocks[MAX_FIMC_CLOCKS] = { static struct fimc_fmt fimc_formats[] = { { .name = "RGB565", - .fourcc = V4L2_PIX_FMT_RGB565X, + .fourcc = V4L2_PIX_FMT_RGB565, .depth = { 16 }, .color = S5P_FIMC_RGB565, .memplanes = 1, -- cgit v0.10.2 From fbe78ddde1f217044ed854eff92e4d22112871cb Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 16 Nov 2011 08:19:58 -0300 Subject: [media] m5mols: Fix set_fmt to return proper pixel format code In case pixel format is modified in set_fmt by the driver, the changes are not propagated back to the caller. Fix this by adjusting passed data for TRY and ACTIVE format. Also remove redundant pixel format code information from struct m5mols_info, it's already available in 'ffmt' array. Remove pad number validation in set/get_fmt, this is already done in the core. Signed-off-by: Sylwester Nawrocki Acked-by: HeungJun Kim Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h index 89d09a8..82c8817 100644 --- a/drivers/media/video/m5mols/m5mols.h +++ b/drivers/media/video/m5mols/m5mols.h @@ -162,7 +162,6 @@ struct m5mols_version { * @pad: media pad * @ffmt: current fmt according to resolution type * @res_type: current resolution type - * @code: current code * @irq_waitq: waitqueue for the capture * @work_irq: workqueue for the IRQ * @flags: state variable for the interrupt handler @@ -192,7 +191,6 @@ struct m5mols_info { struct media_pad pad; struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX]; int res_type; - enum v4l2_mbus_pixelcode code; wait_queue_head_t irq_waitq; struct work_struct work_irq; unsigned long flags; diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c index 5d21d05..68497f8 100644 --- a/drivers/media/video/m5mols/m5mols_core.c +++ b/drivers/media/video/m5mols/m5mols_core.c @@ -510,9 +510,6 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct m5mols_info *info = to_m5mols(sd); struct v4l2_mbus_framefmt *format; - if (fmt->pad != 0) - return -EINVAL; - format = __find_format(info, fh, fmt->which, info->res_type); if (!format) return -EINVAL; @@ -531,9 +528,6 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, u32 resolution = 0; int ret; - if (fmt->pad != 0) - return -EINVAL; - ret = __find_resolution(sd, format, &type, &resolution); if (ret < 0) return ret; @@ -542,13 +536,14 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, if (!sfmt) return 0; - *sfmt = m5mols_default_ffmt[type]; - sfmt->width = format->width; - sfmt->height = format->height; + + format->code = m5mols_default_ffmt[type].code; + format->colorspace = V4L2_COLORSPACE_JPEG; + format->field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + *sfmt = *format; info->resolution = resolution; - info->code = format->code; info->res_type = type; } @@ -625,13 +620,14 @@ static int m5mols_start_monitor(struct m5mols_info *info) static int m5mols_s_stream(struct v4l2_subdev *sd, int enable) { struct m5mols_info *info = to_m5mols(sd); + u32 code = info->ffmt[info->res_type].code; if (enable) { int ret = -EINVAL; - if (is_code(info->code, M5MOLS_RESTYPE_MONITOR)) + if (is_code(code, M5MOLS_RESTYPE_MONITOR)) ret = m5mols_start_monitor(info); - if (is_code(info->code, M5MOLS_RESTYPE_CAPTURE)) + if (is_code(code, M5MOLS_RESTYPE_CAPTURE)) ret = m5mols_start_capture(info); return ret; -- cgit v0.10.2 From 025521f917b9a36d76fb701609b3578b1563818b Mon Sep 17 00:00:00 2001 From: Dmitry Artamonow Date: Sun, 20 Nov 2011 12:54:26 -0300 Subject: [media] omap3isp: fix compilation of ispvideo.c Fix following build error by explicitely including header file. CC drivers/media/video/omap3isp/ispvideo.o Signed-off-by: Dmitry Artamonow Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index d100072..f229057 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From fc8ac777ae39409e81f7dd2d123d980c0dfb528e Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 21 Nov 2011 05:02:38 -0300 Subject: [media] media: video: s5p-tv: fix build break This patch fixes following build break: Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c index e16d3a4..b47d0c0 100644 --- a/drivers/media/video/s5p-tv/mixer_video.c +++ b/drivers/media/video/s5p-tv/mixer_video.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 2f5893cf42ca10a1eb73bc527e2198847f4d0a79 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 16 Oct 2011 18:17:09 +0800 Subject: ARM: at91: define CLOCK_TICK_RATE to bogus value except A91X40 We have a clocksource which renders CLOCK_TICK_RATE useless. Define it to a bogus value to get rid of some ifdeffery. use local LATCH for at91rm9200 timer but keep it for A91X40 as we do not use a clocksource Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 1dd69c8..a028cdf 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -32,6 +32,8 @@ static unsigned long last_crtr; static u32 irqmask; static struct clock_event_device clkevt; +#define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) + /* * The ST_CRTR is updated asynchronously to the master clock ... but * the updates as seen by the CPU don't seem to be strictly monotonic. @@ -74,8 +76,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) if (sr & AT91_ST_PITS) { u32 crtr = read_CRTR(); - while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) { - last_crtr += LATCH; + while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) { + last_crtr += RM9200_TIMER_LATCH; clkevt.event_handler(&clkevt); } return IRQ_HANDLED; @@ -116,7 +118,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; - at91_sys_write(AT91_ST_PIMR, LATCH); + at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h index 85820ad..5e917a6 100644 --- a/arch/arm/mach-at91/include/mach/timex.h +++ b/arch/arm/mach-at91/include/mach/timex.h @@ -23,70 +23,15 @@ #include -#if defined(CONFIG_ARCH_AT91RM9200) +#ifdef CONFIG_ARCH_AT91X40 -#define CLOCK_TICK_RATE (AT91_SLOW_CLOCK) - -#elif defined(CONFIG_ARCH_AT91SAM9260) - -#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260) -#define AT91SAM9_MASTER_CLOCK 90000000 -#else -#define AT91SAM9_MASTER_CLOCK 99300000 -#endif - -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9261) - -#define AT91SAM9_MASTER_CLOCK 99300000 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9G10) - -#define AT91SAM9_MASTER_CLOCK 133000000 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9263) - -#if defined(CONFIG_MACH_USB_A9263) -#define AT91SAM9_MASTER_CLOCK 90000000 -#else -#define AT91SAM9_MASTER_CLOCK 99959500 -#endif - -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9RL) - -#define AT91SAM9_MASTER_CLOCK 100000000 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9G20) +#define AT91X40_MASTER_CLOCK 40000000 +#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) -#if defined(CONFIG_MACH_USB_A9G20) -#define AT91SAM9_MASTER_CLOCK 133000000 #else -#define AT91SAM9_MASTER_CLOCK 132096000 -#endif - -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91SAM9G45) -#define AT91SAM9_MASTER_CLOCK 133333333 -#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91CAP9) - -#define AT91CAP9_MASTER_CLOCK 100000000 -#define CLOCK_TICK_RATE (AT91CAP9_MASTER_CLOCK/16) - -#elif defined(CONFIG_ARCH_AT91X40) - -#define AT91X40_MASTER_CLOCK 40000000 -#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK) +#define CLOCK_TICK_RATE 12345678 #endif -#endif +#endif /* __ASM_ARCH_TIMEX_H */ -- cgit v0.10.2 From 80e91cb8023fbc07b2410c4ce5a2da12fbcebca4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 16 Sep 2011 23:37:50 +0800 Subject: ARM: at91: make gpio register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre Reviewed-by: Ryan Mallon diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index ecdd54d..fe00dce 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -296,19 +296,19 @@ void __init at91cap9_set_console_clock(int id) static struct at91_gpio_bank at91cap9_gpio[] = { { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOA, + .regbase = AT91CAP9_BASE_PIOA, .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOB, + .regbase = AT91CAP9_BASE_PIOB, .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOC, + .regbase = AT91CAP9_BASE_PIOC, .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, - .offset = AT91_PIOD, + .regbase = AT91CAP9_BASE_PIOD, .clock = &pioABCD_clk, } }; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 713d3bd..8ce8675 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -271,19 +271,19 @@ void __init at91rm9200_set_console_clock(int id) static struct at91_gpio_bank at91rm9200_gpio[] = { { .id = AT91RM9200_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91RM9200_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91RM9200_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91RM9200_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91RM9200_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91RM9200_BASE_PIOC, .clock = &pioC_clk, }, { .id = AT91RM9200_ID_PIOD, - .offset = AT91_PIOD, + .regbase = AT91RM9200_BASE_PIOD, .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b84a9f6..1e9c79f 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -273,15 +273,15 @@ void __init at91sam9260_set_console_clock(int id) static struct at91_gpio_bank at91sam9260_gpio[] = { { .id = AT91SAM9260_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9260_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9260_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9260_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9260_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9260_BASE_PIOC, .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 658a518..574aa6b 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -254,15 +254,15 @@ void __init at91sam9261_set_console_clock(int id) static struct at91_gpio_bank at91sam9261_gpio[] = { { .id = AT91SAM9261_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9261_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9261_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9261_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9261_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9261_BASE_PIOC, .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index f83fbb0..dee0ed7 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -266,23 +266,23 @@ void __init at91sam9263_set_console_clock(int id) static struct at91_gpio_bank at91sam9263_gpio[] = { { .id = AT91SAM9263_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9263_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9263_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9263_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9263_ID_PIOCDE, - .offset = AT91_PIOC, + .regbase = AT91SAM9263_BASE_PIOC, .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, - .offset = AT91_PIOD, + .regbase = AT91SAM9263_BASE_PIOD, .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, - .offset = AT91_PIOE, + .regbase = AT91SAM9263_BASE_PIOE, .clock = &pioCDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 318b040..404d70c 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -296,23 +296,23 @@ void __init at91sam9g45_set_console_clock(int id) static struct at91_gpio_bank at91sam9g45_gpio[] = { { .id = AT91SAM9G45_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9G45_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9G45_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9G45_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9G45_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9G45_BASE_PIOC, .clock = &pioC_clk, }, { .id = AT91SAM9G45_ID_PIODE, - .offset = AT91_PIOD, + .regbase = AT91SAM9G45_BASE_PIOD, .clock = &pioDE_clk, }, { .id = AT91SAM9G45_ID_PIODE, - .offset = AT91_PIOE, + .regbase = AT91SAM9G45_BASE_PIOE, .clock = &pioDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index a238105..c4004e2 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -246,19 +246,19 @@ void __init at91sam9rl_set_console_clock(int id) static struct at91_gpio_bank at91sam9rl_gpio[] = { { .id = AT91SAM9RL_ID_PIOA, - .offset = AT91_PIOA, + .regbase = AT91SAM9RL_BASE_PIOA, .clock = &pioA_clk, }, { .id = AT91SAM9RL_ID_PIOB, - .offset = AT91_PIOB, + .regbase = AT91SAM9RL_BASE_PIOB, .clock = &pioB_clk, }, { .id = AT91SAM9RL_ID_PIOC, - .offset = AT91_PIOC, + .regbase = AT91SAM9RL_BASE_PIOC, .clock = &pioC_clk, }, { .id = AT91SAM9RL_ID_PIOD, - .offset = AT91_PIOD, + .regbase = AT91SAM9RL_BASE_PIOD, .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 938b34f..11d7297 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -65,7 +65,7 @@ extern void at91sam9_alt_reset(void); struct at91_gpio_bank { unsigned short id; /* peripheral ID */ - unsigned long offset; /* offset from system peripheral base */ + unsigned long regbase; /* offset from system peripheral base */ struct clk *clock; /* associated clock */ }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 224e9e2..cedb753 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -614,8 +614,12 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) at91_gpio->bank = &data[i]; at91_gpio->chip.base = PIN_BASE + i * 32; - at91_gpio->regbase = at91_gpio->bank->offset + - (void __iomem *)AT91_VA_BASE_SYS; + + at91_gpio->regbase = ioremap(at91_gpio->bank->regbase, 512); + if (!at91_gpio->regbase) { + pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); + continue; + } /* enable PIO controller's clock */ clk_enable(at91_gpio->bank->clock); diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index c5df1e8..f65d083 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -88,10 +88,6 @@ #define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -102,6 +98,11 @@ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) +#define AT91CAP9_BASE_PIOA 0xfffff200 +#define AT91CAP9_BASE_PIOB 0xfffff400 +#define AT91CAP9_BASE_PIOC 0xfffff600 +#define AT91CAP9_BASE_PIOD 0xfffff800 + #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 #define AT91_USART2 AT91CAP9_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index e4037b5..5740954 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -81,15 +81,16 @@ */ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */ -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */ -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */ -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */ -#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ #define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ +#define AT91RM9200_BASE_PIOA 0xfffff400 /* PIO Controller A */ +#define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */ +#define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */ +#define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */ + #define AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART1 AT91RM9200_BASE_US1 #define AT91_USART2 AT91RM9200_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 9a79116..1bea3dc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -87,9 +87,6 @@ #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -98,6 +95,10 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9260_BASE_PIOA 0xfffff400 +#define AT91SAM9260_BASE_PIOB 0xfffff600 +#define AT91SAM9260_BASE_PIOC 0xfffff800 + #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 #define AT91_USART2 AT91SAM9260_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index ce59620..17ae9c7 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -70,9 +70,6 @@ #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -81,6 +78,10 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9261_BASE_PIOA 0xfffff400 +#define AT91SAM9261_BASE_PIOB 0xfffff600 +#define AT91SAM9261_BASE_PIOC 0xfffff800 + #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 #define AT91_USART2 AT91SAM9261_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index f1b9296..dd54079 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -84,11 +84,6 @@ #define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) -#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -98,6 +93,12 @@ #define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) +#define AT91SAM9263_BASE_PIOA 0xfffff200 +#define AT91SAM9263_BASE_PIOB 0xfffff400 +#define AT91SAM9263_BASE_PIOC 0xfffff600 +#define AT91SAM9263_BASE_PIOD 0xfffff800 +#define AT91SAM9263_BASE_PIOE 0xfffffa00 + #define AT91_USART0 AT91SAM9263_BASE_US0 #define AT91_USART1 AT91SAM9263_BASE_US1 #define AT91_USART2 AT91SAM9263_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 406bb64..a487af5 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -94,11 +94,6 @@ #define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) -#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -108,6 +103,12 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) +#define AT91SAM9G45_BASE_PIOA 0xfffff200 +#define AT91SAM9G45_BASE_PIOB 0xfffff400 +#define AT91SAM9G45_BASE_PIOC 0xfffff600 +#define AT91SAM9G45_BASE_PIOD 0xfffff800 +#define AT91SAM9G45_BASE_PIOE 0xfffffa00 + #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 #define AT91_USART2 AT91SAM9G45_BASE_US2 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 1aabacd..d3ef11a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -77,10 +77,6 @@ #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) -#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) -#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) -#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) -#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) @@ -91,6 +87,11 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) +#define AT91SAM9RL_BASE_PIOA 0xfffff400 +#define AT91SAM9RL_BASE_PIOB 0xfffff600 +#define AT91SAM9RL_BASE_PIOC 0xfffff800 +#define AT91SAM9RL_BASE_PIOD 0xfffffa00 + #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 #define AT91_USART2 AT91SAM9RL_BASE_US2 -- cgit v0.10.2 From d28edd1bc4d1cd92f0ab129ac71892eead47d8a2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 09:31:56 +0800 Subject: ARM: at91: make ecc register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index adad70d..fb525f4 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -398,8 +398,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91CAP9_BASE_ECC, + .end = AT91CAP9_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 25e3464..067c168 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -399,8 +399,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91SAM9260_BASE_ECC, + .end = AT91SAM9260_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ad017eb..0b1a28e 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -473,8 +473,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC0, - .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1, + .start = AT91SAM9263_BASE_ECC0, + .end = AT91SAM9263_BASE_ECC0 + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 09a16d6..d19d720 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -529,8 +529,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91SAM9G45_BASE_ECC, + .end = AT91SAM9G45_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 628eb56..e63ab90 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -248,8 +248,8 @@ static struct resource nand_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_BASE_SYS + AT91_ECC, - .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, + .start = AT91SAM9RL_BASE_ECC, + .end = AT91SAM9RL_BASE_ECC + SZ_512 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index f65d083..5fd105d 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -79,7 +79,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC (0xffffe200 - AT91_BASE_SYS) #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) +#define AT91CAP9_BASE_ECC 0xffffe200 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 1bea3dc..6974656 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -80,7 +80,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC (0xffffe800 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) @@ -95,6 +94,7 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9260_BASE_ECC 0xffffe800 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index dd54079..a668538 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -74,10 +74,8 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS) -#define AT91_ECC1 (0xffffe600 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) @@ -93,6 +91,8 @@ #define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) +#define AT91SAM9263_BASE_ECC0 0xffffe000 +#define AT91SAM9263_BASE_ECC1 0xffffe600 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 #define AT91SAM9263_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index a487af5..3c0b7c1 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -86,7 +86,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_ECC (0xffffe200 - AT91_BASE_SYS) #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) @@ -103,6 +102,7 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) +#define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index d3ef11a..d9efe5a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -70,7 +70,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_DMA (0xffffe600 - AT91_BASE_SYS) -#define AT91_ECC (0xffffe800 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) @@ -87,6 +86,7 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) +#define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 -- cgit v0.10.2 From 9627b200eddb7755d62c4c5638c40e476cf61647 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 15 Oct 2011 15:47:51 +0800 Subject: ARM: at91: make dma register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index d19d720..42bf770 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -44,8 +44,8 @@ static struct at_dma_platform_data atdma_pdata = { static struct resource hdmac_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DMA, - .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, + .start = AT91SAM9G45_BASE_DMA, + .end = AT91SAM9G45_BASE_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index e63ab90..34fe5dd 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -39,8 +39,8 @@ static struct at_dma_platform_data atdma_pdata = { static struct resource hdmac_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DMA, - .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, + .start = AT91SAM9RL_BASE_DMA, + .end = AT91SAM9RL_BASE_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [2] = { diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 5fd105d..a2eccb9 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -84,7 +84,6 @@ #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) -#define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ (0xfffffd60 - AT91_BASE_SYS)) #define AT91CAP9_BASE_ECC 0xffffe200 +#define AT91CAP9_BASE_DMA 0xffffec00 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 3c0b7c1..29e577f 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -90,7 +90,6 @@ #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_DMA (0xffffec00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) @@ -103,6 +102,7 @@ #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) #define AT91SAM9G45_BASE_ECC 0xffffe200 +#define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index d9efe5a..e564650 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -69,7 +69,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_DMA (0xffffe600 - AT91_BASE_SYS) #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) @@ -86,6 +85,7 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) +#define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 -- cgit v0.10.2 From eab5fd67d6d144ae9877a3de307714836bd1fbf0 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 10:12:00 +0800 Subject: ARM: at91: make rtt register base soc independant Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index fb525f4..3262a7e 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -670,8 +670,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91CAP9_BASE_RTT, + .end = AT91CAP9_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 067c168..63cbfb8 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -714,8 +714,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9260_BASE_RTT, + .end = AT91SAM9260_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index ae78f4d..d5bd1e7 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -600,8 +600,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9261_BASE_RTT, + .end = AT91SAM9261_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 0b1a28e..5d2b061 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -956,8 +956,8 @@ static void __init at91_add_device_tc(void) { } static struct resource rtt0_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT0, - .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1, + .start = AT91SAM9263_BASE_RTT0, + .end = AT91SAM9263_BASE_RTT0 + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; @@ -971,8 +971,8 @@ static struct platform_device at91sam9263_rtt0_device = { static struct resource rtt1_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT1, - .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1, + .start = AT91SAM9263_BASE_RTT1, + .end = AT91SAM9263_BASE_RTT1 + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 42bf770..bb2ba0c 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1081,8 +1081,8 @@ void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {} static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9G45_BASE_RTT, + .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 34fe5dd..f9b423b 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -685,8 +685,8 @@ static void __init at91_add_device_rtc(void) {} static struct resource rtt_resources[] = { { - .start = AT91_BASE_SYS + AT91_RTT, - .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, + .start = AT91SAM9RL_BASE_RTT, + .end = AT91SAM9RL_BASE_RTT + SZ_16 - 1, .flags = IORESOURCE_MEM, } }; diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index a2eccb9..1cb42a6 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ @@ -102,6 +101,7 @@ #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 +#define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 6974656..6aa7ca9 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 +#define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 17ae9c7..f84b713 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -73,7 +73,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -81,6 +80,7 @@ #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 +#define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index a668538..938965e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -85,10 +85,8 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT0 (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) -#define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 @@ -98,6 +96,8 @@ #define AT91SAM9263_BASE_PIOC 0xfffff600 #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 +#define AT91SAM9263_BASE_RTT0 0xfffffd20 +#define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91_USART0 AT91SAM9263_BASE_US0 #define AT91_USART1 AT91SAM9263_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 29e577f..00638c6 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -95,7 +95,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -108,6 +107,7 @@ #define AT91SAM9G45_BASE_PIOC 0xfffff600 #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 +#define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index e564650..099cefc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -78,7 +78,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) @@ -91,6 +90,7 @@ #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 +#define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 -- cgit v0.10.2 From cfa5a1fe7e65bacdee59d5df60a9f44b0c030532 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 14 Oct 2011 01:17:18 +0800 Subject: ARM: at91: add ioremap_registers entry point to soc setup this will allow to ioremap the register of the PIT, PMC and others and make the code soc independent Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index fe00dce..3687207 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -333,6 +333,10 @@ static void __init at91cap9_map_io(void) at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); } +static void __init at91cap9_ioremap_registers(void) +{ +} + static void __init at91cap9_initialize(void) { at91_arch_reset = at91cap9_reset; @@ -394,6 +398,7 @@ static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91cap9_soc = { .map_io = at91cap9_map_io, .default_irq_priority = at91cap9_default_irq_priority, + .ioremap_registers = at91cap9_ioremap_registers, .register_clocks = at91cap9_register_clocks, .init = at91cap9_initialize, }; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 8ce8675..c67d50c 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -307,6 +307,10 @@ static void __init at91rm9200_map_io(void) iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); } +static void __init at91rm9200_ioremap_registers(void) +{ +} + static void __init at91rm9200_initialize(void) { at91_arch_reset = at91rm9200_reset; @@ -366,6 +370,7 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91rm9200_soc = { .map_io = at91rm9200_map_io, .default_irq_priority = at91rm9200_default_irq_priority, + .ioremap_registers = at91rm9200_ioremap_registers, .register_clocks = at91rm9200_register_clocks, .init = at91rm9200_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 1e9c79f..0e54928 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -325,6 +325,10 @@ static void __init at91sam9260_map_io(void) } } +static void __init at91sam9260_ioremap_registers(void) +{ +} + static void __init at91sam9260_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -381,6 +385,7 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9260_soc = { .map_io = at91sam9260_map_io, .default_irq_priority = at91sam9260_default_irq_priority, + .ioremap_registers = at91sam9260_ioremap_registers, .register_clocks = at91sam9260_register_clocks, .init = at91sam9260_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 574aa6b..dde8318 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -285,6 +285,10 @@ static void __init at91sam9261_map_io(void) at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE); } +static void __init at91sam9261_ioremap_registers(void) +{ +} + static void __init at91sam9261_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -341,6 +345,7 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9261_soc = { .map_io = at91sam9261_map_io, .default_irq_priority = at91sam9261_default_irq_priority, + .ioremap_registers = at91sam9261_ioremap_registers, .register_clocks = at91sam9261_register_clocks, .init = at91sam9261_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index dee0ed7..fc442dd 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -303,6 +303,10 @@ static void __init at91sam9263_map_io(void) at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE); } +static void __init at91sam9263_ioremap_registers(void) +{ +} + static void __init at91sam9263_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -358,6 +362,7 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9263_soc = { .map_io = at91sam9263_map_io, .default_irq_priority = at91sam9263_default_irq_priority, + .ioremap_registers = at91sam9263_ioremap_registers, .register_clocks = at91sam9263_register_clocks, .init = at91sam9263_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 404d70c..56282b2 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -338,6 +338,10 @@ static void __init at91sam9g45_map_io(void) init_consistent_dma_size(SZ_4M); } +static void __init at91sam9g45_ioremap_registers(void) +{ +} + static void __init at91sam9g45_initialize(void) { at91_arch_reset = at91sam9g45_reset; @@ -393,6 +397,7 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9g45_soc = { .map_io = at91sam9g45_map_io, .default_irq_priority = at91sam9g45_default_irq_priority, + .ioremap_registers = at91sam9g45_ioremap_registers, .register_clocks = at91sam9g45_register_clocks, .init = at91sam9g45_initialize, }; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index c4004e2..29dae9b 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -290,6 +290,10 @@ static void __init at91sam9rl_map_io(void) at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size); } +static void __init at91sam9rl_ioremap_registers(void) +{ +} + static void __init at91sam9rl_initialize(void) { at91_arch_reset = at91sam9_alt_reset; @@ -345,6 +349,7 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { struct at91_init_soc __initdata at91sam9rl_soc = { .map_io = at91sam9rl_map_io, .default_irq_priority = at91sam9rl_default_irq_priority, + .ioremap_registers = at91sam9rl_ioremap_registers, .register_clocks = at91sam9rl_register_clocks, .init = at91sam9rl_initialize, }; diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index aa64294..63b3ac2 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -287,6 +287,8 @@ void __init at91_map_io(void) void __init at91_initialize(unsigned long main_clock) { + at91_boot_soc.ioremap_registers(); + /* Init clock subsystem */ at91_clock_init(main_clock); diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index 21ed881..4588ae6 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -7,6 +7,7 @@ struct at91_init_soc { unsigned int *default_irq_priority; void (*map_io)(void); + void (*ioremap_registers)(void); void (*register_clocks)(void); void (*init)(void); }; -- cgit v0.10.2 From 4ab0c5998d327cba5b7e0dc8ce67f45859997669 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 22:29:50 +0800 Subject: ARM: at91: make pit register base soc independent Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 3687207..abfe368 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -335,6 +335,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); } static void __init at91cap9_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 0e54928..0030d5f 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -327,6 +327,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); } static void __init at91sam9260_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index dde8318..348d5ae 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -287,6 +287,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); } static void __init at91sam9261_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index fc442dd..09ccf73 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -305,6 +305,7 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); } static void __init at91sam9263_initialize(void) diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index 4ba8549..d89ead7 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -25,7 +25,17 @@ static u32 pit_cycle; /* write-once */ static u32 pit_cnt; /* access only w/system irq blocked */ +static void __iomem *pit_base_addr __read_mostly; +static inline unsigned int pit_read(unsigned int reg_offset) +{ + return __raw_readl(pit_base_addr + reg_offset); +} + +static inline void pit_write(unsigned int reg_offset, unsigned long value) +{ + __raw_writel(value, pit_base_addr + reg_offset); +} /* * Clocksource: just a monotonic counter of MCK/16 cycles. @@ -39,7 +49,7 @@ static cycle_t read_pit_clk(struct clocksource *cs) raw_local_irq_save(flags); elapsed = pit_cnt; - t = at91_sys_read(AT91_PIT_PIIR); + t = pit_read(AT91_PIT_PIIR); raw_local_irq_restore(flags); elapsed += PIT_PICNT(t) * pit_cycle; @@ -64,8 +74,8 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* update clocksource counter */ - pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); - at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN + pit_cnt += pit_cycle * PIT_PICNT(pit_read(AT91_PIT_PIVR)); + pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN | AT91_PIT_PITIEN); break; case CLOCK_EVT_MODE_ONESHOT: @@ -74,7 +84,7 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: /* disable irq, leaving the clocksource active */ - at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); + pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); break; case CLOCK_EVT_MODE_RESUME: break; @@ -103,11 +113,11 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) /* The PIT interrupt may be disabled, and is shared */ if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC) - && (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS)) { + && (pit_read(AT91_PIT_SR) & AT91_PIT_PITS)) { unsigned nr_ticks; /* Get number of ticks performed before irq, and ack it */ - nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); + nr_ticks = PIT_PICNT(pit_read(AT91_PIT_PIVR)); do { pit_cnt += pit_cycle; pit_clkevt.event_handler(&pit_clkevt); @@ -129,14 +139,14 @@ static struct irqaction at91sam926x_pit_irq = { static void at91sam926x_pit_reset(void) { /* Disable timer and irqs */ - at91_sys_write(AT91_PIT_MR, 0); + pit_write(AT91_PIT_MR, 0); /* Clear any pending interrupts, wait for PIT to stop counting */ - while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0) + while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0) cpu_relax(); /* Start PIT but don't enable IRQ */ - at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); + pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); } /* @@ -178,7 +188,15 @@ static void __init at91sam926x_pit_init(void) static void at91sam926x_pit_suspend(void) { /* Disable timer */ - at91_sys_write(AT91_PIT_MR, 0); + pit_write(AT91_PIT_MR, 0); +} + +void __init at91sam926x_ioremap_pit(u32 addr) +{ + pit_base_addr = ioremap(addr, 16); + + if (!pit_base_addr) + panic("Impossible to ioremap PIT\n"); } struct sys_timer at91sam926x_timer = { diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 56282b2..aa8b441 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -340,6 +340,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); } static void __init at91sam9g45_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 29dae9b..291fc99 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -292,6 +292,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { + at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); } static void __init at91sam9rl_initialize(void) diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 11d7297..8196ecc 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -29,6 +29,7 @@ extern void __init at91_aic_init(unsigned int priority[]); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; +extern void at91sam926x_ioremap_pit(u32 addr); extern struct sys_timer at91sam926x_timer; extern struct sys_timer at91x40_timer; diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h index 974d0bd..d1f80ad 100644 --- a/arch/arm/mach-at91/include/mach/at91_pit.h +++ b/arch/arm/mach-at91/include/mach/at91_pit.h @@ -16,16 +16,16 @@ #ifndef AT91_PIT_H #define AT91_PIT_H -#define AT91_PIT_MR (AT91_PIT + 0x00) /* Mode Register */ +#define AT91_PIT_MR 0x00 /* Mode Register */ #define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */ #define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */ #define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */ -#define AT91_PIT_SR (AT91_PIT + 0x04) /* Status Register */ +#define AT91_PIT_SR 0x04 /* Status Register */ #define AT91_PIT_PITS (1 << 0) /* Timer Status */ -#define AT91_PIT_PIVR (AT91_PIT + 0x08) /* Periodic Interval Value Register */ -#define AT91_PIT_PIIR (AT91_PIT + 0x0c) /* Periodic Interval Image Register */ +#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */ +#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */ #define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */ #define AT91_PIT_CPIV (0xfffff) /* Inverval Value */ diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 1cb42a6..ad8d298 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ @@ -102,6 +101,7 @@ #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 #define AT91CAP9_BASE_RTT 0xfffffd20 +#define AT91CAP9_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 6aa7ca9..b8c85dc 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -89,7 +89,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -98,6 +97,7 @@ #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 #define AT91SAM9260_BASE_RTT 0xfffffd20 +#define AT91SAM9260_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index f84b713..0dccaff 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -73,7 +73,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -81,6 +80,7 @@ #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 #define AT91SAM9261_BASE_RTT 0xfffffd20 +#define AT91SAM9261_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 938965e..735408e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -85,7 +85,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -97,6 +96,7 @@ #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 #define AT91SAM9263_BASE_RTT0 0xfffffd20 +#define AT91SAM9263_BASE_PIT 0xfffffd30 #define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91_USART0 AT91SAM9263_BASE_US0 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 00638c6..ba609f3 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -95,7 +95,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) @@ -108,6 +107,7 @@ #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 #define AT91SAM9G45_BASE_RTT 0xfffffd20 +#define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 099cefc..bab09a7 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -78,7 +78,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) -#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -91,6 +90,7 @@ #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 #define AT91SAM9RL_BASE_RTT 0xfffffd20 +#define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 -- cgit v0.10.2 From faee0cc33c3df3b63314926eecef77d384ae9cd4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 14 Oct 2011 01:37:09 +0800 Subject: ARM: at91: make smc register base soc independent now sam9_smc_configure will take as first parameter is the SMC id Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index abfe368..1ea9312 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -28,6 +28,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -336,6 +337,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); + at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); } static void __init at91cap9_initialize(void) diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index c67d50c..c06c14f 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -23,6 +23,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" static struct map_desc at91rm9200_io_desc[] __initdata = { { diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 0030d5f..fc1f734 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -26,6 +26,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -328,6 +329,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); } static void __init at91sam9260_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 348d5ae..804181a 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -25,6 +25,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -288,6 +289,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); } static void __init at91sam9261_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 09ccf73..b8f4996 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -24,6 +24,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -306,6 +307,8 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); + at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); } static void __init at91sam9263_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index aa8b441..ce3233f 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -26,6 +26,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -341,6 +342,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); } static void __init at91sam9g45_initialize(void) diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 291fc99..1bcccd7 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -25,6 +25,7 @@ #include "soc.h" #include "generic.h" #include "clock.h" +#include "sam9_smc.h" /* -------------------------------------------------------------------- * Clocks @@ -293,6 +294,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); + at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); } static void __init at91sam9rl_initialize(void) diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index f90cfb3..02ded92 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -163,7 +163,7 @@ static struct sam9_smc_config __initdata cam60_nand_smc_config = { static void __init cam60_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &cam60_nand_smc_config); + sam9_smc_configure(0, 3, &cam60_nand_smc_config); at91_add_device_nand(&cam60_nand_data); } diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 5dffd3b..da2616f 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -212,7 +212,7 @@ static void __init cap9adk_add_device_nand(void) cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &cap9adk_nand_smc_config); + sam9_smc_configure(0, 3, &cap9adk_nand_smc_config); at91_add_device_nand(&cap9adk_nand_data); } @@ -282,7 +282,7 @@ static __init void cap9adk_add_device_nor(void) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, &cap9adk_nor_smc_config); + sam9_smc_configure(0, 0, &cap9adk_nor_smc_config); platform_device_register(&cap9adk_nor_flash); } diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index fc885a4..7dd752e 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -156,7 +156,7 @@ static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { static void __init cpu9krea_add_device_nand(void) { - sam9_smc_configure(3, &cpu9krea_nand_smc_config); + sam9_smc_configure(0, 3, &cpu9krea_nand_smc_config); at91_add_device_nand(&cpu9krea_nand_data); } @@ -238,7 +238,7 @@ static __init void cpu9krea_add_device_nor(void) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); /* configure chip-select 0 (NOR) */ - sam9_smc_configure(0, &cpu9krea_nor_smc_config); + sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config); platform_device_register(&cpu9krea_nor_flash); } diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index 0b7d327..41d84d9 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -82,7 +82,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index ef816c1..a9b9adc 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -213,7 +213,7 @@ static struct sam9_smc_config __initdata neocore926_nand_smc_config = { static void __init neocore926_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &neocore926_nand_smc_config); + sam9_smc_configure(0, 3, &neocore926_nand_smc_config); at91_add_device_nand(&neocore926_nand_data); } diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 49e3f69..0e3c632 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -96,9 +96,9 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { static void __init add_device_pcontrol(void) { /* configure chip-select 4 (IO compatible to 8051 X4 ) */ - sam9_smc_configure(4, &pcontrol_smc_config[0]); + sam9_smc_configure(0, 4, &pcontrol_smc_config[0]); /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */ - sam9_smc_configure(7, &pcontrol_smc_config[1]); + sam9_smc_configure(0, 7, &pcontrol_smc_config[1]); } diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 07421bd..89d44c0 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -161,7 +161,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { static void __init ek_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 072d53a..e0283c5 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -162,7 +162,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { static void __init ek_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index 4f10181..00db0f8 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -211,7 +211,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index b005b73..a879b33 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -131,7 +131,7 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init ek_add_device_dm9000(void) { /* Configure chip-select 2 (DM9000) */ - sam9_smc_configure(2, &dm9000_smc_config); + sam9_smc_configure(0, 2, &dm9000_smc_config); /* Configure Reset signal as output */ at91_set_gpio_output(AT91_PIN_PC10, 0); @@ -217,7 +217,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index bccdcf2..7b25ca1 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -218,7 +218,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 64fc75c..0579f06 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -195,7 +195,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 92de912..3e0d5a9 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -175,7 +175,7 @@ static void __init ek_add_device_nand(void) ek_nand_smc_config.mode |= AT91_SMC_DBW_8; /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index b2b7482..c561eda 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -119,7 +119,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = { static void __init ek_add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); + sam9_smc_configure(0, 3, &ek_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 0df01c6..645d833 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -149,7 +149,7 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = { static void __init snapper9260_add_device_nand(void) { at91_set_A_periph(AT91_PIN_PC14, 0); - sam9_smc_configure(3, &snapper9260_nand_smc_config); + sam9_smc_configure(0, 3, &snapper9260_nand_smc_config); at91_add_device_nand(&snapper9260_nand_data); } diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 936e5fd..f94ac86 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -108,7 +108,7 @@ static struct sam9_smc_config __initdata nand_smc_config = { static void __init add_device_nand(void) { /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &nand_smc_config); + sam9_smc_configure(0, 3, &nand_smc_config); at91_add_device_nand(&nand_data); } diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 0a20bab..6f893cf 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -245,9 +245,9 @@ static void __init ek_add_device_nand(void) /* configure chip-select 3 (NAND) */ if (machine_is_usb_a9g20()) - sam9_smc_configure(3, &usb_a9g20_nand_smc_config); + sam9_smc_configure(0, 3, &usb_a9g20_nand_smc_config); else - sam9_smc_configure(3, &usb_a9260_nand_smc_config); + sam9_smc_configure(0, 3, &usb_a9260_nand_smc_config); at91_add_device_nand(&ek_nand_data); } diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index ad8d298..d7d0b68 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -81,7 +81,6 @@ */ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) @@ -96,6 +95,7 @@ #define AT91CAP9_BASE_ECC 0xffffe200 #define AT91CAP9_BASE_DMA 0xffffec00 +#define AT91CAP9_BASE_SMC 0xffffe800 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index b8c85dc..e55ab6a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -81,7 +81,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) @@ -93,6 +92,7 @@ #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 +#define AT91SAM9260_BASE_SMC 0xffffec00 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 0dccaff..1ea2d6b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -66,7 +66,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) @@ -76,6 +75,7 @@ #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) +#define AT91SAM9261_BASE_SMC 0xffffec00 #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 735408e..b827ff7 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -75,9 +75,7 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) -#define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) -#define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) @@ -89,7 +87,9 @@ #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 +#define AT91SAM9263_BASE_SMC0 0xffffe400 #define AT91SAM9263_BASE_ECC1 0xffffe600 +#define AT91SAM9263_BASE_SMC1 0xffffea00 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 #define AT91SAM9263_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h index 57de620..eb18a70 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9_smc.h +++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h @@ -16,7 +16,9 @@ #ifndef AT91SAM9_SMC_H #define AT91SAM9_SMC_H -#define AT91_SMC_SETUP(n) (AT91_SMC + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ +#include + +#define AT91_SMC_SETUP 0x00 /* Setup Register for CS n */ #define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */ #define AT91_SMC_NWESETUP_(x) ((x) << 0) #define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */ @@ -26,7 +28,7 @@ #define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */ #define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24) -#define AT91_SMC_PULSE(n) (AT91_SMC + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ +#define AT91_SMC_PULSE 0x04 /* Pulse Register for CS n */ #define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */ #define AT91_SMC_NWEPULSE_(x) ((x) << 0) #define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */ @@ -36,13 +38,13 @@ #define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */ #define AT91_SMC_NCS_RDPULSE_(x)((x) << 24) -#define AT91_SMC_CYCLE(n) (AT91_SMC + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ +#define AT91_SMC_CYCLE 0x08 /* Cycle Register for CS n */ #define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */ #define AT91_SMC_NWECYCLE_(x) ((x) << 0) #define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */ #define AT91_SMC_NRDCYCLE_(x) ((x) << 16) -#define AT91_SMC_MODE(n) (AT91_SMC + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ +#define AT91_SMC_MODE 0x0c /* Mode Register for CS n */ #define AT91_SMC_READMODE (1 << 0) /* Read Mode */ #define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */ #define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */ @@ -66,11 +68,4 @@ #define AT91_SMC_PS_16 (2 << 28) #define AT91_SMC_PS_32 (3 << 28) -#if defined(AT91_SMC1) /* The AT91SAM9263 has 2 Static Memory contollers */ -#define AT91_SMC1_SETUP(n) (AT91_SMC1 + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ -#define AT91_SMC1_PULSE(n) (AT91_SMC1 + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ -#define AT91_SMC1_CYCLE(n) (AT91_SMC1 + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ -#define AT91_SMC1_MODE(n) (AT91_SMC1 + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ -#endif - #endif diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index ba609f3..ac051d4 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -88,7 +88,6 @@ */ #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) -#define AT91_SMC (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) @@ -101,6 +100,7 @@ #define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_DMA 0xffffec00 +#define AT91SAM9G45_BASE_SMC 0xffffe800 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index bab09a7..846139d 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -70,7 +70,6 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) -#define AT91_SMC (0xffffec00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) @@ -85,6 +84,7 @@ #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 +#define AT91SAM9RL_BASE_SMC 0xffffec00 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c index 5eab6aa6..8294783 100644 --- a/arch/arm/mach-at91/sam9_smc.c +++ b/arch/arm/mach-at91/sam9_smc.c @@ -10,38 +10,58 @@ #include #include +#include +#include #include #include "sam9_smc.h" -void __init sam9_smc_configure(int cs, struct sam9_smc_config* config) + +#define AT91_SMC_CS(id, n) (smc_base_addr[id] + ((n) * 0x10)) + +static void __iomem *smc_base_addr[2]; + +static void __init sam9_smc_cs_configure(void __iomem *base, struct sam9_smc_config* config) { + /* Setup register */ - at91_sys_write(AT91_SMC_SETUP(cs), - AT91_SMC_NWESETUP_(config->nwe_setup) - | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup) - | AT91_SMC_NRDSETUP_(config->nrd_setup) - | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup) - ); + __raw_writel(AT91_SMC_NWESETUP_(config->nwe_setup) + | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup) + | AT91_SMC_NRDSETUP_(config->nrd_setup) + | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup), + base + AT91_SMC_SETUP); /* Pulse register */ - at91_sys_write(AT91_SMC_PULSE(cs), - AT91_SMC_NWEPULSE_(config->nwe_pulse) - | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse) - | AT91_SMC_NRDPULSE_(config->nrd_pulse) - | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse) - ); + __raw_writel(AT91_SMC_NWEPULSE_(config->nwe_pulse) + | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse) + | AT91_SMC_NRDPULSE_(config->nrd_pulse) + | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse), + base + AT91_SMC_PULSE); /* Cycle register */ - at91_sys_write(AT91_SMC_CYCLE(cs), - AT91_SMC_NWECYCLE_(config->write_cycle) - | AT91_SMC_NRDCYCLE_(config->read_cycle) - ); + __raw_writel(AT91_SMC_NWECYCLE_(config->write_cycle) + | AT91_SMC_NRDCYCLE_(config->read_cycle), + base + AT91_SMC_CYCLE); /* Mode register */ - at91_sys_write(AT91_SMC_MODE(cs), - config->mode - | AT91_SMC_TDF_(config->tdf_cycles) - ); + __raw_writel(config->mode + | AT91_SMC_TDF_(config->tdf_cycles), + base + AT91_SMC_MODE); +} + +void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config) +{ + sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config); +} + +void __init at91sam9_ioremap_smc(int id, u32 addr) +{ + if (id > 1) { + pr_warn("%s: id > 2\n", __func__); + return; + } + smc_base_addr[id] = ioremap(addr, 512); + if (!smc_base_addr[id]) + pr_warn("Impossible to ioremap smc.%d 0x%x\n", id, addr); } diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h index bf72cfb..039c5ce 100644 --- a/arch/arm/mach-at91/sam9_smc.h +++ b/arch/arm/mach-at91/sam9_smc.h @@ -30,4 +30,5 @@ struct sam9_smc_config { u8 tdf_cycles:4; }; -extern void __init sam9_smc_configure(int cs, struct sam9_smc_config* config); +extern void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config); +extern void __init at91sam9_ioremap_smc(int id, u32 addr); -- cgit v0.10.2 From f466f3bc92eb6857181bb033d14b1e9b1dd52140 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 1 Nov 2011 01:55:11 +0800 Subject: ARM: at91: drop CCFG never used in the kernel Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index d7d0b68..cd19f05 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -82,7 +82,6 @@ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index e55ab6a..f964cfa 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -82,7 +82,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index b827ff7..a62a3a8 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -77,7 +77,6 @@ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffed10 - AT91_BASE_SYS) #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 846139d..c945d4d 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -71,7 +71,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) -- cgit v0.10.2 From f22deee523e0ff49c3be01dd6f979d374230725a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 1 Nov 2011 01:23:20 +0800 Subject: ARM: at91: make shutdown controler soc independent Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 1ea9312..652dbe1 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -13,7 +13,6 @@ */ #include -#include #include #include @@ -23,7 +22,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -319,12 +317,6 @@ static void at91cap9_reset(void) at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); } -static void at91cap9_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91CAP9 processor initialization * -------------------------------------------------------------------- */ @@ -336,6 +328,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { + at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); } @@ -343,7 +336,6 @@ static void __init at91cap9_ioremap_registers(void) static void __init at91cap9_initialize(void) { at91_arch_reset = at91cap9_reset; - pm_power_off = at91cap9_poweroff; at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index fc1f734..5a17a23 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -287,12 +285,6 @@ static struct at91_gpio_bank at91sam9260_gpio[] = { } }; -static void at91sam9260_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9260 processor initialization * -------------------------------------------------------------------- */ @@ -328,6 +320,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); } @@ -335,7 +328,6 @@ static void __init at91sam9260_ioremap_registers(void) static void __init at91sam9260_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9260_poweroff; at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | (1 << AT91SAM9260_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 804181a..80e3e0f 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -268,12 +266,6 @@ static struct at91_gpio_bank at91sam9261_gpio[] = { } }; -static void at91sam9261_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9261 processor initialization * -------------------------------------------------------------------- */ @@ -288,6 +280,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); } @@ -295,7 +288,6 @@ static void __init at91sam9261_ioremap_registers(void) static void __init at91sam9261_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | (1 << AT91SAM9261_ID_IRQ2); diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index b8f4996..2a42b99 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -19,7 +18,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -288,12 +286,6 @@ static struct at91_gpio_bank at91sam9263_gpio[] = { } }; -static void at91sam9263_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9263 processor initialization * -------------------------------------------------------------------- */ @@ -306,6 +298,7 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); @@ -314,7 +307,6 @@ static void __init at91sam9263_ioremap_registers(void) static void __init at91sam9263_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9263_poweroff; at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index ce3233f..7fdf964 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -11,7 +11,6 @@ */ #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include #include "soc.h" @@ -323,12 +321,6 @@ static void at91sam9g45_reset(void) at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); } -static void at91sam9g45_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9G45 processor initialization * -------------------------------------------------------------------- */ @@ -341,6 +333,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); } @@ -348,7 +341,6 @@ static void __init at91sam9g45_ioremap_registers(void) static void __init at91sam9g45_initialize(void) { at91_arch_reset = at91sam9g45_reset; - pm_power_off = at91sam9g45_poweroff; at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 1bcccd7..6856bad 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -10,7 +10,6 @@ */ #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include "soc.h" #include "generic.h" @@ -264,12 +262,6 @@ static struct at91_gpio_bank at91sam9rl_gpio[] = { } }; -static void at91sam9rl_poweroff(void) -{ - at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); -} - - /* -------------------------------------------------------------------- * AT91SAM9RL processor initialization * -------------------------------------------------------------------- */ @@ -293,6 +285,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { + at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); } @@ -300,7 +293,6 @@ static void __init at91sam9rl_ioremap_registers(void) static void __init at91sam9rl_initialize(void) { at91_arch_reset = at91sam9_alt_reset; - pm_power_off = at91sam9rl_poweroff; at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); /* Register GPIO subsystem */ diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 89d44c0..6eb0c93 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -251,7 +251,7 @@ static void __init ek_board_init(void) /* LEDs */ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); /* shutdown controller, wakeup button (5 msec low) */ - at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW + at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW | AT91_SHDW_RTTWKEN); } diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 6f893cf..dbc2609 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -344,7 +344,7 @@ static void __init ek_board_init(void) /* I2C */ at91_add_device_i2c(NULL, 0); /* shutdown controller, wakeup button (5 msec low) */ - at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) + at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW | AT91_SHDW_RTTWKEN); } diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 8196ecc..bc17764 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -60,6 +60,9 @@ extern void at91_irq_resume(void); /* reset */ extern void at91sam9_alt_reset(void); +/* shutdown */ +extern void at91_ioremap_shdwc(u32 base_addr); + /* GPIO */ #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h index c4ce07e..1d4fe82 100644 --- a/arch/arm/mach-at91/include/mach/at91_shdwc.h +++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h @@ -16,11 +16,21 @@ #ifndef AT91_SHDWC_H #define AT91_SHDWC_H -#define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_shdwc_base; + +#define at91_shdwc_read(field) \ + __raw_readl(at91_shdwc_base + field) + +#define at91_shdwc_write(field, value) \ + __raw_writel(value, at91_shdwc_base + field); +#endif + +#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */ #define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */ #define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */ +#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */ #define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ #define AT91_SHDW_WKMODE0_NONE 0 #define AT91_SHDW_WKMODE0_HIGH 1 @@ -30,7 +40,7 @@ #define AT91_SHDW_CPTWK0_(x) ((x) << 4) #define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ -#define AT91_SHDW_SR (AT91_SHDWC + 0x08) /* Shut Down Status Register */ +#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */ #define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ #define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */ #define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */ diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index cd19f05..5ac468c 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -86,7 +86,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ @@ -99,6 +98,7 @@ #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 +#define AT91CAP9_BASE_SHDWC 0xfffffd10 #define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91CAP9_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index f964cfa..e3c819a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -86,7 +86,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -95,6 +94,7 @@ #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 +#define AT91SAM9260_BASE_SHDWC 0xfffffd10 #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 1ea2d6b..f9b5163 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -71,7 +71,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) @@ -79,6 +78,7 @@ #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 +#define AT91SAM9261_BASE_SHDWC 0xfffffd10 #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index a62a3a8..28d52d5 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -81,7 +81,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -94,6 +93,7 @@ #define AT91SAM9263_BASE_PIOC 0xfffff600 #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 +#define AT91SAM9263_BASE_SHDWC 0xfffffd10 #define AT91SAM9263_BASE_RTT0 0xfffffd20 #define AT91SAM9263_BASE_PIT 0xfffffd30 #define AT91SAM9263_BASE_RTT1 0xfffffd50 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index ac051d4..5f3453e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -93,7 +93,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) @@ -106,6 +105,7 @@ #define AT91SAM9G45_BASE_PIOC 0xfffff600 #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 +#define AT91SAM9G45_BASE_SHDWC 0xfffffd10 #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index c945d4d..6f3a4ee 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -75,7 +75,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -88,6 +87,7 @@ #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 +#define AT91SAM9RL_BASE_SHDWC 0xfffffd10 #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 7046158..3a5b7b4 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -34,7 +34,7 @@ /* * Show the reason for the previous system reset. */ -#if defined(AT91_SHDWC) +#if defined(AT91_RSTC) #include #include @@ -58,8 +58,11 @@ static void __init show_reset_status(void) char *reason, *r2 = reset; u32 reset_type, wake_type; + if (!at91_shdwc_base) + return; + reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; - wake_type = at91_sys_read(AT91_SHDW_SR); + wake_type = at91_shdwc_read(AT91_SHDW_SR); switch (reset_type) { case AT91_RSTC_RSTTYP_GENERAL: diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 63b3ac2..053c369 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include "soc.h" #include "generic.h" @@ -285,6 +287,21 @@ void __init at91_map_io(void) at91_boot_soc.map_io(); } +void __iomem *at91_shdwc_base = NULL; + +static void at91sam9_poweroff(void) +{ + at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); +} + +void __init at91_ioremap_shdwc(u32 base_addr) +{ + at91_shdwc_base = ioremap(base_addr, 16); + if (!at91_shdwc_base) + panic("Impossible to ioremap at91_shdwc_base\n"); + pm_power_off = at91sam9_poweroff; +} + void __init at91_initialize(unsigned long main_clock) { at91_boot_soc.ioremap_registers(); -- cgit v0.10.2 From c1c30a29df7e47310caa979dc48f715ae478de5f Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 2 Nov 2011 01:43:31 +0800 Subject: ARM: at91: make watchdog drivers soc independent switch the watchdog drivers to resource and pass it via platform_device Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre Signed-off-by: Wim Van Sebroeck diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 3262a7e..019dac0 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -694,10 +694,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91CAP9_BASE_WDT, + .end = AT91CAP9_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91cap9_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 63cbfb8..9cdaffa 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -738,10 +738,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9260_BASE_WDT, + .end = AT91SAM9260_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9260_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index d5bd1e7..c59e1e9 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -624,10 +624,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9261_BASE_WDT, + .end = AT91SAM9261_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9261_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 5d2b061..b5f4e25 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -996,10 +996,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9263_BASE_WDT, + .end = AT91SAM9263_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9263_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index bb2ba0c..3b91706 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1133,10 +1133,19 @@ static void __init at91_add_device_trng(void) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9G45_BASE_WDT, + .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9g45_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index f9b423b..c7961b4 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -709,10 +709,19 @@ static void __init at91_add_device_rtt(void) * -------------------------------------------------------------------- */ #if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) +static struct resource wdt_resources[] = { + { + .start = AT91SAM9RL_BASE_WDT, + .end = AT91SAM9RL_BASE_WDT + SZ_16 - 1, + .flags = IORESOURCE_MEM, + } +}; + static struct platform_device at91sam9rl_wdt_device = { .name = "at91_wdt", .id = -1, - .num_resources = 0, + .resource = wdt_resources, + .num_resources = ARRAY_SIZE(wdt_resources), }; static void __init at91_add_device_watchdog(void) diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 5ac468c..750ba85 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -86,7 +86,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) @@ -101,6 +100,7 @@ #define AT91CAP9_BASE_SHDWC 0xfffffd10 #define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91CAP9_BASE_PIT 0xfffffd30 +#define AT91CAP9_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91CAP9_BASE_US0 #define AT91_USART1 AT91CAP9_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index e3c819a..05860c5 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -86,7 +86,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 @@ -97,6 +96,7 @@ #define AT91SAM9260_BASE_SHDWC 0xfffffd10 #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 +#define AT91SAM9260_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9260_BASE_US0 #define AT91_USART1 AT91SAM9260_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index f9b5163..df2ddfd 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -71,7 +71,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9261_BASE_SMC 0xffffec00 @@ -81,6 +80,7 @@ #define AT91SAM9261_BASE_SHDWC 0xfffffd10 #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 +#define AT91SAM9261_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9261_BASE_US0 #define AT91_USART1 AT91SAM9261_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 28d52d5..0eb614e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -81,7 +81,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 @@ -96,6 +95,7 @@ #define AT91SAM9263_BASE_SHDWC 0xfffffd10 #define AT91SAM9263_BASE_RTT0 0xfffffd20 #define AT91SAM9263_BASE_PIT 0xfffffd30 +#define AT91SAM9263_BASE_WDT 0xfffffd40 #define AT91SAM9263_BASE_RTT1 0xfffffd50 #define AT91_USART0 AT91SAM9263_BASE_US0 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 5f3453e..65098c3 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -93,7 +93,6 @@ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) @@ -108,6 +107,7 @@ #define AT91SAM9G45_BASE_SHDWC 0xfffffd10 #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 +#define AT91SAM9G45_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 6f3a4ee..46e136d 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -75,7 +75,6 @@ #define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) -#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) @@ -90,6 +89,7 @@ #define AT91SAM9RL_BASE_SHDWC 0xfffffd10 #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 +#define AT91SAM9RL_BASE_WDT 0xfffffd40 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 87445b2..0056256 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c @@ -35,6 +35,11 @@ #define DRV_NAME "AT91SAM9 Watchdog" +#define wdt_read(field) \ + __raw_readl(at91wdt_private.base + field) +#define wdt_write(field, val) \ + __raw_writel((val), at91wdt_private.base + field) + /* AT91SAM9 watchdog runs a 12bit counter @ 256Hz, * use this to convert a watchdog * value from/to milliseconds. @@ -63,6 +68,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " static void at91_ping(unsigned long data); static struct { + void __iomem *base; unsigned long next_heartbeat; /* the next_heartbeat for the timer */ unsigned long open; char expect_close; @@ -77,7 +83,7 @@ static struct { */ static inline void at91_wdt_reset(void) { - at91_sys_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); + wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT); } /* @@ -132,7 +138,7 @@ static int at91_wdt_settimeout(unsigned int timeout) unsigned int mr; /* Check if disabled */ - mr = at91_sys_read(AT91_WDT_MR); + mr = wdt_read(AT91_WDT_MR); if (mr & AT91_WDT_WDDIS) { printk(KERN_ERR DRV_NAME": sorry, watchdog is disabled\n"); return -EIO; @@ -149,7 +155,7 @@ static int at91_wdt_settimeout(unsigned int timeout) | AT91_WDT_WDDBGHLT /* disabled in debug mode */ | AT91_WDT_WDD /* restart at any time */ | (timeout & AT91_WDT_WDV); /* timer value */ - at91_sys_write(AT91_WDT_MR, reg); + wdt_write(AT91_WDT_MR, reg); return 0; } @@ -248,12 +254,22 @@ static struct miscdevice at91wdt_miscdev = { static int __init at91wdt_probe(struct platform_device *pdev) { + struct resource *r; int res; if (at91wdt_miscdev.parent) return -EBUSY; at91wdt_miscdev.parent = &pdev->dev; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + at91wdt_private.base = ioremap(r->start, resource_size(r)); + if (!at91wdt_private.base) { + dev_err(&pdev->dev, "failed to map registers, aborting.\n"); + return -ENOMEM; + } + /* Set watchdog */ res = at91_wdt_settimeout(ms_to_ticks(WDT_HW_TIMEOUT * 1000)); if (res) diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h index 757f9ca..c6fbb2e6 100644 --- a/drivers/watchdog/at91sam9_wdt.h +++ b/drivers/watchdog/at91sam9_wdt.h @@ -16,11 +16,11 @@ #ifndef AT91_WDT_H #define AT91_WDT_H -#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ +#define AT91_WDT_CR 0x00 /* Watchdog Control Register */ #define AT91_WDT_WDRSTT (1 << 0) /* Restart */ #define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ +#define AT91_WDT_MR 0x04 /* Watchdog Mode Register */ #define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ #define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */ #define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */ @@ -30,7 +30,7 @@ #define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */ #define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */ -#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */ +#define AT91_WDT_SR 0x08 /* Watchdog Status Register */ #define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */ #define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */ -- cgit v0.10.2 From 13079a733313c00ca92fc6716383dd126caa7276 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 2 Nov 2011 01:43:31 +0800 Subject: ARM: at91: make DBGU soc independent we will select now the DBGU used by the soc at Kconfig level For the DEBUG_LL and early_printk this will allow to select which DBGU to use this will also allow to select them when multiple SOC are enabled Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c5213e7..0608c0b 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -100,6 +100,14 @@ choice Note that the system will appear to hang during boot if there is nothing connected to read from the DCC. + config AT91_DEBUG_LL_DBGU0 + bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" + depends on HAVE_AT91_DBGU0 + + config AT91_DEBUG_LL_DBGU1 + bool "Kernel low-level debugging on 9263, 9g45 and cap9" + depends on HAVE_AT91_DBGU1 + config DEBUG_FOOTBRIDGE_COM1 bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" depends on FOOTBRIDGE diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index d111c3e9..4f991f2 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -3,6 +3,12 @@ if ARCH_AT91 config HAVE_AT91_DATAFLASH_CARD bool +config HAVE_AT91_DBGU0 + bool + +config HAVE_AT91_DBGU1 + bool + config HAVE_AT91_USART3 bool @@ -21,12 +27,14 @@ config ARCH_AT91RM9200 bool "AT91RM9200" select CPU_ARM920T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_AT91_USART3 config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE" select CPU_ARM926T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_AT91_USART3 select HAVE_AT91_USART4 select HAVE_AT91_USART5 @@ -37,11 +45,13 @@ config ARCH_AT91SAM9261 select CPU_ARM926T select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL + select HAVE_AT91_DBGU0 config ARCH_AT91SAM9G10 bool "AT91SAM9G10" select CPU_ARM926T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL config ARCH_AT91SAM9263 @@ -50,6 +60,7 @@ config ARCH_AT91SAM9263 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91SAM9RL bool "AT91SAM9RL" @@ -57,11 +68,13 @@ config ARCH_AT91SAM9RL select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_FB_ATMEL + select HAVE_AT91_DBGU0 config ARCH_AT91SAM9G20 bool "AT91SAM9G20" select CPU_ARM926T select GENERIC_CLOCKEVENTS + select HAVE_AT91_DBGU0 select HAVE_AT91_USART3 select HAVE_AT91_USART4 select HAVE_AT91_USART5 @@ -74,6 +87,7 @@ config ARCH_AT91SAM9G45 select HAVE_AT91_USART3 select HAVE_FB_ATMEL select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91CAP9 bool "AT91CAP9" @@ -81,6 +95,7 @@ config ARCH_AT91CAP9 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_NET_MACB + select HAVE_AT91_DBGU1 config ARCH_AT91X40 bool "AT91x40" @@ -510,8 +525,13 @@ config AT91_TIMER_HZ choice prompt "Select a UART for early kernel messages" -config AT91_EARLY_DBGU - bool "DBGU" +config AT91_EARLY_DBGU0 + bool "DBGU on rm9200, 9260/9g20, 9261/9g10 and 9rl" + depends on HAVE_AT91_DBGU0 + +config AT91_EARLY_DBGU1 + bool "DBGU on 9263, 9g45 and cap9" + depends on HAVE_AT91_DBGU1 config AT91_EARLY_USART0 bool "USART0" diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 019dac0..19975cf 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -1030,8 +1030,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91CAP9_BASE_DBGU, + .end = AT91CAP9_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 66591fa..1007ba8 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -877,8 +877,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91RM9200_BASE_DBGU, + .end = AT91RM9200_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 9cdaffa..5b424fc 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -846,8 +846,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9260_BASE_DBGU, + .end = AT91SAM9260_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index c59e1e9..e5cff1d 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -825,8 +825,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9261_BASE_DBGU, + .end = AT91SAM9261_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b5f4e25..20e681c 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -1205,8 +1205,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9263_BASE_DBGU, + .end = AT91SAM9263_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 3b91706..153dad0 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1341,8 +1341,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9G45_BASE_DBGU, + .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index c7961b4..366c1cf 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -917,8 +917,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_BASE_SYS + AT91_DBGU, - .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91SAM9RL_BASE_DBGU, + .end = AT91SAM9RL_BASE_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h index dbfe455a..2aa0c5e 100644 --- a/arch/arm/mach-at91/include/mach/at91_dbgu.h +++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h @@ -19,7 +19,7 @@ #define dbgu_readl(dbgu, field) \ __raw_readl(AT91_VA_BASE_SYS + dbgu + AT91_DBGU_ ## field) -#ifdef AT91_DBGU +#if !defined(CONFIG_ARCH_AT91X40) #define AT91_DBGU_CR (0x00) /* Control Register */ #define AT91_DBGU_MR (0x04) /* Mode Register */ #define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */ diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index 750ba85..bca2b54 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -82,7 +82,6 @@ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) @@ -93,6 +92,7 @@ #define AT91CAP9_BASE_ECC 0xffffe200 #define AT91CAP9_BASE_DMA 0xffffec00 #define AT91CAP9_BASE_SMC 0xffffe800 +#define AT91CAP9_BASE_DBGU AT91_BASE_DBGU1 #define AT91CAP9_BASE_PIOA 0xfffff200 #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 5740954..1f767e2 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -80,12 +80,12 @@ * System Peripherals (offset from AT91_BASE_SYS) */ #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ #define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ +#define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */ #define AT91RM9200_BASE_PIOA 0xfffff400 /* PIO Controller A */ #define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */ #define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 05860c5..e360d66 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -83,13 +83,13 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 #define AT91SAM9260_BASE_SMC 0xffffec00 +#define AT91SAM9260_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index df2ddfd..2ccc8a53 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -68,12 +68,12 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9261_BASE_SMC 0xffffec00 +#define AT91SAM9261_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index 0eb614e..aee137b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -77,7 +77,6 @@ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) @@ -87,6 +86,7 @@ #define AT91SAM9263_BASE_SMC0 0xffffe400 #define AT91SAM9263_BASE_ECC1 0xffffe600 #define AT91SAM9263_BASE_SMC1 0xffffea00 +#define AT91SAM9263_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9263_BASE_PIOA 0xfffff200 #define AT91SAM9263_BASE_PIOB 0xfffff400 #define AT91SAM9263_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 65098c3..211721b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -89,7 +89,6 @@ #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) @@ -99,6 +98,7 @@ #define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_DMA 0xffffec00 #define AT91SAM9G45_BASE_SMC 0xffffe800 +#define AT91SAM9G45_BASE_DBGU AT91_BASE_DBGU1 #define AT91SAM9G45_BASE_PIOA 0xfffff200 #define AT91SAM9G45_BASE_PIOB 0xfffff400 #define AT91SAM9G45_BASE_PIOC 0xfffff600 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 46e136d..4f7367a 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -72,7 +72,6 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) -#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) @@ -82,6 +81,7 @@ #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 #define AT91SAM9RL_BASE_SMC 0xffffec00 +#define AT91SAM9RL_BASE_DBGU AT91_BASE_DBGU0 #define AT91SAM9RL_BASE_PIOA 0xfffff400 #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S index 0ed8648..c6bb9e2 100644 --- a/arch/arm/mach-at91/include/mach/debug-macro.S +++ b/arch/arm/mach-at91/include/mach/debug-macro.S @@ -14,9 +14,15 @@ #include #include +#if defined(CONFIG_AT91_DEBUG_LL_DBGU0) +#define AT91_DBGU AT91_BASE_DBGU0 +#else +#define AT91_DBGU AT91_BASE_DBGU1 +#endif + .macro addruart, rp, rv, tmp - ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address) - ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address) + ldr \rp, =AT91_DBGU @ System peripherals (phys address) + ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address) .endm .macro senduart,rd,rx diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 483478d..435764e 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -16,6 +16,12 @@ #include +/* DBGU base */ +/* rm9200, 9260/9g20, 9261/9g10, 9rl */ +#define AT91_BASE_DBGU0 0xfffff200 +/* 9263, 9g45, cap9 */ +#define AT91_BASE_DBGU1 0xffffee00 + #if defined(CONFIG_ARCH_AT91RM9200) #include #elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h index 18bdcde..0234fd9 100644 --- a/arch/arm/mach-at91/include/mach/uncompress.h +++ b/arch/arm/mach-at91/include/mach/uncompress.h @@ -24,8 +24,10 @@ #include #include -#if defined(CONFIG_AT91_EARLY_DBGU) -#define UART_OFFSET (AT91_DBGU + AT91_BASE_SYS) +#if defined(CONFIG_AT91_EARLY_DBGU0) +#define UART_OFFSET AT91_BASE_DBGU0 +#elif defined(CONFIG_AT91_EARLY_DBGU1) +#define UART_OFFSET AT91_BASE_DBGU1 #elif defined(CONFIG_AT91_EARLY_USART0) #define UART_OFFSET AT91_USART0 #elif defined(CONFIG_AT91_EARLY_USART1) diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 053c369..242c26b 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -93,9 +93,6 @@ void at91_iounmap(volatile void __iomem *addr) } EXPORT_SYMBOL(at91_iounmap); -#define AT91_DBGU0 0xfffff200 -#define AT91_DBGU1 0xffffee00 - static void __init soc_detect(u32 dbgu_base) { u32 cidr, socid; @@ -268,9 +265,9 @@ void __init at91_map_io(void) at91_soc_initdata.type = AT91_SOC_NONE; at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; - soc_detect(AT91_DBGU0); + soc_detect(AT91_BASE_DBGU0); if (!at91_soc_is_detected()) - soc_detect(AT91_DBGU1); + soc_detect(AT91_BASE_DBGU1); if (!at91_soc_is_detected()) panic("AT91: Impossible to detect the SOC type"); -- cgit v0.10.2 From be6d4321720cd56623c1d5be311bde65c2c91229 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 3 Nov 2011 01:12:50 +0800 Subject: ARM: at91: make aic soc independent on all at91 have the Advanced Interrupt Controller starts at address 0xfffff000 Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/include/mach/at91_aic.h b/arch/arm/mach-at91/include/mach/at91_aic.h index 0356679..3045781 100644 --- a/arch/arm/mach-at91/include/mach/at91_aic.h +++ b/arch/arm/mach-at91/include/mach/at91_aic.h @@ -16,7 +16,19 @@ #ifndef AT91_AIC_H #define AT91_AIC_H -#define AT91_AIC_SMR(n) (AT91_AIC + ((n) * 4)) /* Source Mode Registers 0-31 */ +#ifndef __ASSEMBLY__ +extern void __iomem *at91_aic_base; + +#define at91_aic_read(field) \ + __raw_readl(at91_aic_base + field) + +#define at91_aic_write(field, value) \ + __raw_writel(value, at91_aic_base + field); +#else +.extern at91_aic_base +#endif + +#define AT91_AIC_SMR(n) ((n) * 4) /* Source Mode Registers 0-31 */ #define AT91_AIC_PRIOR (7 << 0) /* Priority Level */ #define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */ #define AT91_AIC_SRCTYPE_LOW (0 << 5) @@ -24,30 +36,30 @@ #define AT91_AIC_SRCTYPE_HIGH (2 << 5) #define AT91_AIC_SRCTYPE_RISING (3 << 5) -#define AT91_AIC_SVR(n) (AT91_AIC + 0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ -#define AT91_AIC_IVR (AT91_AIC + 0x100) /* Interrupt Vector Register */ -#define AT91_AIC_FVR (AT91_AIC + 0x104) /* Fast Interrupt Vector Register */ -#define AT91_AIC_ISR (AT91_AIC + 0x108) /* Interrupt Status Register */ +#define AT91_AIC_SVR(n) (0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ +#define AT91_AIC_IVR 0x100 /* Interrupt Vector Register */ +#define AT91_AIC_FVR 0x104 /* Fast Interrupt Vector Register */ +#define AT91_AIC_ISR 0x108 /* Interrupt Status Register */ #define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */ -#define AT91_AIC_IPR (AT91_AIC + 0x10c) /* Interrupt Pending Register */ -#define AT91_AIC_IMR (AT91_AIC + 0x110) /* Interrupt Mask Register */ -#define AT91_AIC_CISR (AT91_AIC + 0x114) /* Core Interrupt Status Register */ +#define AT91_AIC_IPR 0x10c /* Interrupt Pending Register */ +#define AT91_AIC_IMR 0x110 /* Interrupt Mask Register */ +#define AT91_AIC_CISR 0x114 /* Core Interrupt Status Register */ #define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */ #define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */ -#define AT91_AIC_IECR (AT91_AIC + 0x120) /* Interrupt Enable Command Register */ -#define AT91_AIC_IDCR (AT91_AIC + 0x124) /* Interrupt Disable Command Register */ -#define AT91_AIC_ICCR (AT91_AIC + 0x128) /* Interrupt Clear Command Register */ -#define AT91_AIC_ISCR (AT91_AIC + 0x12c) /* Interrupt Set Command Register */ -#define AT91_AIC_EOICR (AT91_AIC + 0x130) /* End of Interrupt Command Register */ -#define AT91_AIC_SPU (AT91_AIC + 0x134) /* Spurious Interrupt Vector Register */ -#define AT91_AIC_DCR (AT91_AIC + 0x138) /* Debug Control Register */ +#define AT91_AIC_IECR 0x120 /* Interrupt Enable Command Register */ +#define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */ +#define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */ +#define AT91_AIC_ISCR 0x12c /* Interrupt Set Command Register */ +#define AT91_AIC_EOICR 0x130 /* End of Interrupt Command Register */ +#define AT91_AIC_SPU 0x134 /* Spurious Interrupt Vector Register */ +#define AT91_AIC_DCR 0x138 /* Debug Control Register */ #define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */ #define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */ -#define AT91_AIC_FFER (AT91_AIC + 0x140) /* Fast Forcing Enable Register [SAM9 only] */ -#define AT91_AIC_FFDR (AT91_AIC + 0x144) /* Fast Forcing Disable Register [SAM9 only] */ -#define AT91_AIC_FFSR (AT91_AIC + 0x148) /* Fast Forcing Status Register [SAM9 only] */ +#define AT91_AIC_FFER 0x140 /* Fast Forcing Enable Register [SAM9 only] */ +#define AT91_AIC_FFDR 0x144 /* Fast Forcing Disable Register [SAM9 only] */ +#define AT91_AIC_FFSR 0x148 /* Fast Forcing Status Register [SAM9 only] */ #endif diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h index bca2b54..4c0e2f6 100644 --- a/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/arch/arm/mach-at91/include/mach/at91cap9.h @@ -82,7 +82,6 @@ #define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 1f767e2..90e92a8 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -79,7 +79,6 @@ /* * System Peripherals (offset from AT91_BASE_SYS) */ -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ #define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index e360d66..f937c47 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -82,7 +82,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 2ccc8a53..175604e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -67,7 +67,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h index aee137b..80c9150 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -77,7 +77,6 @@ #define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 211721b..ac5c471 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -89,7 +89,6 @@ #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index 4f7367a..c466e8c 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -71,7 +71,6 @@ */ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h index a152ff8..a57829f 100644 --- a/arch/arm/mach-at91/include/mach/at91x40.h +++ b/arch/arm/mach-at91/include/mach/at91x40.h @@ -40,7 +40,6 @@ #define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */ #define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */ #define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */ -#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */ /* * The AT91x40 series doesn't have a debug unit like the other AT91 parts. diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S index 7ab68f9..423eea0 100644 --- a/arch/arm/mach-at91/include/mach/entry-macro.S +++ b/arch/arm/mach-at91/include/mach/entry-macro.S @@ -17,16 +17,17 @@ .endm .macro get_irqnr_preamble, base, tmp - ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral + ldr \base, =at91_aic_base @ base virtual address of AIC peripheral + ldr \base, [\base] .endm .macro arch_ret_to_user, tmp1, tmp2 .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) - ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number - teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt - streq \tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)] @ not going to be handled further, then ACK it now. + ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) + ldr \irqstat, [\base, #AT91_AIC_ISR] @ read interrupt source number + teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt + streq \tmp, [\base, #AT91_AIC_EOICR] @ not going to be handled further, then ACK it now. .endm diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 435764e..2d0e4e9 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -58,6 +58,12 @@ #endif /* + * On all at91 have the Advanced Interrupt Controller starts at address + * 0xfffff000 + */ +#define AT91_AIC 0xfffff000 + +/* * Peripheral identifiers/interrupts. */ #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h index 36bd55f..ac8b7df 100644 --- a/arch/arm/mach-at91/include/mach/irqs.h +++ b/arch/arm/mach-at91/include/mach/irqs.h @@ -31,7 +31,7 @@ * Acknowledge interrupt with AIC after interrupt has been handled. * (by kernel/irq.c) */ -#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0) +#define irq_finish(irq) do { at91_aic_write(AT91_AIC_EOICR, 0); } while (0) /* diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index 9665265e..be6b639 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -33,17 +33,18 @@ #include #include +void __iomem *at91_aic_base; static void at91_aic_mask_irq(struct irq_data *d) { /* Disable interrupt on AIC */ - at91_sys_write(AT91_AIC_IDCR, 1 << d->irq); + at91_aic_write(AT91_AIC_IDCR, 1 << d->irq); } static void at91_aic_unmask_irq(struct irq_data *d) { /* Enable interrupt on AIC */ - at91_sys_write(AT91_AIC_IECR, 1 << d->irq); + at91_aic_write(AT91_AIC_IECR, 1 << d->irq); } unsigned int at91_extern_irq; @@ -77,8 +78,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) return -EINVAL; } - smr = at91_sys_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; - at91_sys_write(AT91_AIC_SMR(d->irq), smr | srctype); + smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; + at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype); return 0; } @@ -102,15 +103,15 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value) void at91_irq_suspend(void) { - backups = at91_sys_read(AT91_AIC_IMR); - at91_sys_write(AT91_AIC_IDCR, backups); - at91_sys_write(AT91_AIC_IECR, wakeups); + backups = at91_aic_read(AT91_AIC_IMR); + at91_aic_write(AT91_AIC_IDCR, backups); + at91_aic_write(AT91_AIC_IECR, wakeups); } void at91_irq_resume(void) { - at91_sys_write(AT91_AIC_IDCR, wakeups); - at91_sys_write(AT91_AIC_IECR, backups); + at91_aic_write(AT91_AIC_IDCR, wakeups); + at91_aic_write(AT91_AIC_IECR, backups); } #else @@ -133,34 +134,39 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) { unsigned int i; + at91_aic_base = ioremap(AT91_AIC, 512); + + if (!at91_aic_base) + panic("Impossible to ioremap AT91_AIC\n"); + /* * The IVR is used by macro get_irqnr_and_base to read and verify. * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. */ for (i = 0; i < NR_AIC_IRQS; i++) { /* Put irq number in Source Vector Register: */ - at91_sys_write(AT91_AIC_SVR(i), i); + at91_aic_write(AT91_AIC_SVR(i), i); /* Active Low interrupt, with the specified priority */ - at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); + at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ if (i < 8) - at91_sys_write(AT91_AIC_EOICR, 0); + at91_aic_write(AT91_AIC_EOICR, 0); } /* * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU */ - at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS); + at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS); /* No debugging in AIC: Debug (Protect) Control Register */ - at91_sys_write(AT91_AIC_DCR, 0); + at91_aic_write(AT91_AIC_DCR, 0); /* Disable and clear all interrupts initially */ - at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); + at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); } diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 3a5b7b4..62ad955 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -218,7 +218,7 @@ static int at91_pm_enter(suspend_state_t state) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) | (at91_extern_irq)) - & at91_sys_read(AT91_AIC_IMR), + & at91_aic_read(AT91_AIC_IMR), state); switch (state) { @@ -286,7 +286,7 @@ static int at91_pm_enter(suspend_state_t state) } pr_debug("AT91: PM - wakeup %08x\n", - at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); + at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; -- cgit v0.10.2 From d28bdfc5c80fb64bf50824920bf9b554732dec74 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 14 Nov 2011 14:24:53 +0800 Subject: ARM: at91: make rm9200 rtc drivers soc independent switch the rtc drivers to resource and pass it via platform_device Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 1007ba8..ba4fefe 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -665,10 +665,24 @@ static void __init at91_add_device_tc(void) { } * -------------------------------------------------------------------- */ #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct resource rtc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_RTC, + .end = AT91RM9200_BASE_RTC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device at91rm9200_rtc_device = { .name = "at91_rtc", .id = -1, - .num_resources = 0, + .resource = rtc_resources, + .num_resources = ARRAY_SIZE(rtc_resources), }; static void __init at91_add_device_rtc(void) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 153dad0..2c64e01 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1009,10 +1009,24 @@ static void __init at91_add_device_tc(void) { } * -------------------------------------------------------------------- */ #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) +static struct resource rtc_resources[] = { + [0] = { + .start = AT91SAM9G45_BASE_RTC, + .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device at91sam9g45_rtc_device = { .name = "at91_rtc", .id = -1, - .num_resources = 0, + .resource = rtc_resources, + .num_resources = ARRAY_SIZE(rtc_resources), }; static void __init at91_add_device_rtc(void) diff --git a/arch/arm/mach-at91/include/mach/at91_rtc.h b/arch/arm/mach-at91/include/mach/at91_rtc.h index e56f470..da1945e 100644 --- a/arch/arm/mach-at91/include/mach/at91_rtc.h +++ b/arch/arm/mach-at91/include/mach/at91_rtc.h @@ -16,7 +16,7 @@ #ifndef AT91_RTC_H #define AT91_RTC_H -#define AT91_RTC_CR (AT91_RTC + 0x00) /* Control Register */ +#define AT91_RTC_CR 0x00 /* Control Register */ #define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ #define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ #define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ @@ -29,44 +29,44 @@ #define AT91_RTC_CALEVSEL_MONTH (1 << 16) #define AT91_RTC_CALEVSEL_YEAR (2 << 16) -#define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */ +#define AT91_RTC_MR 0x04 /* Mode Register */ #define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ -#define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */ +#define AT91_RTC_TIMR 0x08 /* Time Register */ #define AT91_RTC_SEC (0x7f << 0) /* Current Second */ #define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ #define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ #define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ -#define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */ +#define AT91_RTC_CALR 0x0c /* Calendar Register */ #define AT91_RTC_CENT (0x7f << 0) /* Current Century */ #define AT91_RTC_YEAR (0xff << 8) /* Current Year */ #define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ #define AT91_RTC_DAY (7 << 21) /* Current Day */ #define AT91_RTC_DATE (0x3f << 24) /* Current Date */ -#define AT91_RTC_TIMALR (AT91_RTC + 0x10) /* Time Alarm Register */ +#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */ #define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ #define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ #define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ -#define AT91_RTC_CALALR (AT91_RTC + 0x14) /* Calendar Alarm Register */ +#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */ #define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ #define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ -#define AT91_RTC_SR (AT91_RTC + 0x18) /* Status Register */ +#define AT91_RTC_SR 0x18 /* Status Register */ #define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ #define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ #define AT91_RTC_SECEV (1 << 2) /* Second Event */ #define AT91_RTC_TIMEV (1 << 3) /* Time Event */ #define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ -#define AT91_RTC_SCCR (AT91_RTC + 0x1c) /* Status Clear Command Register */ -#define AT91_RTC_IER (AT91_RTC + 0x20) /* Interrupt Enable Register */ -#define AT91_RTC_IDR (AT91_RTC + 0x24) /* Interrupt Disable Register */ -#define AT91_RTC_IMR (AT91_RTC + 0x28) /* Interrupt Mask Register */ +#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */ +#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */ +#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ +#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ -#define AT91_RTC_VER (AT91_RTC + 0x2c) /* Valid Entry Register */ +#define AT91_RTC_VER 0x2c /* Valid Entry Register */ #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ #define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ #define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 90e92a8..bacb511 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -81,7 +81,6 @@ */ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ #define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ -#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */ #define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ #define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */ @@ -89,6 +88,7 @@ #define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */ #define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */ #define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */ +#define AT91RM9200_BASE_RTC 0xfffffe00 /* Real-Time Clock */ #define AT91_USART0 AT91RM9200_BASE_US0 #define AT91_USART1 AT91RM9200_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index ac5c471..f0c23c9 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -92,7 +92,6 @@ #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) -#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) #define AT91SAM9G45_BASE_ECC 0xffffe200 #define AT91SAM9G45_BASE_DMA 0xffffec00 @@ -107,6 +106,7 @@ #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 #define AT91SAM9G45_BASE_WDT 0xfffffd40 +#define AT91SAM9G45_BASE_RTC 0xfffffdb0 #define AT91_USART0 AT91SAM9G45_BASE_US0 #define AT91_USART1 AT91SAM9G45_BASE_US1 diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h index c466e8c..2bb359e 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -75,7 +75,6 @@ #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) -#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) #define AT91SAM9RL_BASE_DMA 0xffffe600 #define AT91SAM9RL_BASE_ECC 0xffffe800 @@ -89,6 +88,7 @@ #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 #define AT91SAM9RL_BASE_WDT 0xfffffd40 +#define AT91SAM9RL_BASE_RTC 0xfffffe00 #define AT91_USART0 AT91SAM9RL_BASE_US0 #define AT91_USART1 AT91SAM9RL_BASE_US1 diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index e39b77a..dc474bc 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -32,11 +32,17 @@ #include +#define at91_rtc_read(field) \ + __raw_readl(at91_rtc_regs + field) +#define at91_rtc_write(field, val) \ + __raw_writel((val), at91_rtc_regs + field) #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ static DECLARE_COMPLETION(at91_rtc_updated); static unsigned int at91_alarm_year = AT91_RTC_EPOCH; +static void __iomem *at91_rtc_regs; +static int irq; /* * Decode time/date into rtc_time structure @@ -48,10 +54,10 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, /* must read twice in case it changes */ do { - time = at91_sys_read(timereg); - date = at91_sys_read(calreg); - } while ((time != at91_sys_read(timereg)) || - (date != at91_sys_read(calreg))); + time = at91_rtc_read(timereg); + date = at91_rtc_read(calreg); + } while ((time != at91_rtc_read(timereg)) || + (date != at91_rtc_read(calreg))); tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0); tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8); @@ -98,19 +104,19 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) tm->tm_hour, tm->tm_min, tm->tm_sec); /* Stop Time/Calendar from counting */ - cr = at91_sys_read(AT91_RTC_CR); - at91_sys_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); + cr = at91_rtc_read(AT91_RTC_CR); + at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ACKUPD); + at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD); wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); - at91_sys_write(AT91_RTC_TIMR, + at91_rtc_write(AT91_RTC_TIMR, bin2bcd(tm->tm_sec) << 0 | bin2bcd(tm->tm_min) << 8 | bin2bcd(tm->tm_hour) << 16); - at91_sys_write(AT91_RTC_CALR, + at91_rtc_write(AT91_RTC_CALR, bin2bcd((tm->tm_year + 1900) / 100) /* century */ | bin2bcd(tm->tm_year % 100) << 8 /* year */ | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ @@ -118,8 +124,8 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | bin2bcd(tm->tm_mday) << 24); /* Restart Time/Calendar */ - cr = at91_sys_read(AT91_RTC_CR); - at91_sys_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); + cr = at91_rtc_read(AT91_RTC_CR); + at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); return 0; } @@ -135,7 +141,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_year = at91_alarm_year - 1900; - alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM) + alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) ? 1 : 0; pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -160,20 +166,20 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) tm.tm_min = alrm->time.tm_min; tm.tm_sec = alrm->time.tm_sec; - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_TIMALR, + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_TIMALR, bin2bcd(tm.tm_sec) << 0 | bin2bcd(tm.tm_min) << 8 | bin2bcd(tm.tm_hour) << 16 | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); - at91_sys_write(AT91_RTC_CALALR, + at91_rtc_write(AT91_RTC_CALALR, bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ | bin2bcd(tm.tm_mday) << 24 | AT91_RTC_DATEEN | AT91_RTC_MTHEN); if (alrm->enabled) { - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); } pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -188,10 +194,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) pr_debug("%s(): cmd=%08x\n", __func__, enabled); if (enabled) { - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); } else - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); return 0; } @@ -200,7 +206,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) */ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned long imr = at91_sys_read(AT91_RTC_IMR); + unsigned long imr = at91_rtc_read(AT91_RTC_IMR); seq_printf(seq, "update_IRQ\t: %s\n", (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); @@ -220,7 +226,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) unsigned int rtsr; unsigned long events = 0; - rtsr = at91_sys_read(AT91_RTC_SR) & at91_sys_read(AT91_RTC_IMR); + rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR); if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) events |= (RTC_AF | RTC_IRQF); @@ -229,7 +235,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) if (rtsr & AT91_RTC_ACKUPD) complete(&at91_rtc_updated); - at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ + at91_rtc_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ rtc_update_irq(rtc, 1, events); @@ -256,22 +262,41 @@ static const struct rtc_class_ops at91_rtc_ops = { static int __init at91_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - int ret; + struct resource *regs; + int ret = 0; - at91_sys_write(AT91_RTC_CR, 0); - at91_sys_write(AT91_RTC_MR, 0); /* 24 hour mode */ + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "no mmio resource defined\n"); + return -ENXIO; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource defined\n"); + return -ENXIO; + } + + at91_rtc_regs = ioremap(regs->start, resource_size(regs)); + if (!at91_rtc_regs) { + dev_err(&pdev->dev, "failed to map registers, aborting.\n"); + return -ENOMEM; + } + + at91_rtc_write(AT91_RTC_CR, 0); + at91_rtc_write(AT91_RTC_MR, 0); /* 24 hour mode */ /* Disable all interrupts */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); - ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, + ret = request_irq(irq, at91_rtc_interrupt, IRQF_SHARED, "at91_rtc", pdev); if (ret) { printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", - AT91_ID_SYS); + irq); return ret; } @@ -284,7 +309,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) rtc = rtc_device_register(pdev->name, &pdev->dev, &at91_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - free_irq(AT91_ID_SYS, pdev); + free_irq(irq, pdev); return PTR_ERR(rtc); } platform_set_drvdata(pdev, rtc); @@ -301,10 +326,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) struct rtc_device *rtc = platform_get_drvdata(pdev); /* Disable all interrupts */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | + at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); - free_irq(AT91_ID_SYS, pdev); + free_irq(irq, pdev); rtc_device_unregister(rtc); platform_set_drvdata(pdev, NULL); @@ -323,13 +348,13 @@ static int at91_rtc_suspend(struct device *dev) /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... */ - at91_rtc_imr = at91_sys_read(AT91_RTC_IMR) + at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR) & (AT91_RTC_ALARM|AT91_RTC_SECEV); if (at91_rtc_imr) { if (device_may_wakeup(dev)) - enable_irq_wake(AT91_ID_SYS); + enable_irq_wake(irq); else - at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); + at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr); } return 0; } @@ -338,9 +363,9 @@ static int at91_rtc_resume(struct device *dev) { if (at91_rtc_imr) { if (device_may_wakeup(dev)) - disable_irq_wake(AT91_ID_SYS); + disable_irq_wake(irq); else - at91_sys_write(AT91_RTC_IER, at91_rtc_imr); + at91_rtc_write(AT91_RTC_IER, at91_rtc_imr); } return 0; } -- cgit v0.10.2 From 619d4a4b40f44c1b45263a0e0c9598e3139a1fec Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 13 Nov 2011 13:00:58 +0800 Subject: ARM: at91: switch gpio clock to clkdev Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index dcfa8af..f7f7e1e 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -222,6 +222,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioABCD_clk), + CLKDEV_CON_ID("pioB", &pioABCD_clk), + CLKDEV_CON_ID("pioC", &pioABCD_clk), + CLKDEV_CON_ID("pioD", &pioABCD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -298,19 +302,15 @@ static struct at91_gpio_bank at91cap9_gpio[] = { { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOA, - .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOB, - .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOC, - .clock = &pioABCD_clk, }, { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOD, - .clock = &pioABCD_clk, } }; diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index c06c14f..7470f63 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -196,6 +196,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_ID("pioD", &pioD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -273,19 +277,15 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { { .id = AT91RM9200_ID_PIOA, .regbase = AT91RM9200_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91RM9200_ID_PIOB, .regbase = AT91RM9200_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91RM9200_ID_PIOC, .regbase = AT91RM9200_BASE_PIOC, - .clock = &pioC_clk, }, { .id = AT91RM9200_ID_PIOD, .regbase = AT91RM9200_BASE_PIOD, - .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index e94cc22..943da21 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -210,6 +210,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -275,15 +278,12 @@ static struct at91_gpio_bank at91sam9260_gpio[] = { { .id = AT91SAM9260_ID_PIOA, .regbase = AT91SAM9260_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9260_ID_PIOB, .regbase = AT91SAM9260_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9260_ID_PIOC, .regbase = AT91SAM9260_BASE_PIOC, - .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 80e3e0f..dd7924c 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -175,6 +175,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -254,15 +257,12 @@ static struct at91_gpio_bank at91sam9261_gpio[] = { { .id = AT91SAM9261_ID_PIOA, .regbase = AT91SAM9261_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9261_ID_PIOB, .regbase = AT91SAM9261_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9261_ID_PIOC, .regbase = AT91SAM9261_BASE_PIOC, - .clock = &pioC_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 5c14b22..5a74741 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -192,6 +192,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioCDE_clk), + CLKDEV_CON_ID("pioD", &pioCDE_clk), + CLKDEV_CON_ID("pioE", &pioCDE_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -268,23 +273,18 @@ static struct at91_gpio_bank at91sam9263_gpio[] = { { .id = AT91SAM9263_ID_PIOA, .regbase = AT91SAM9263_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9263_ID_PIOB, .regbase = AT91SAM9263_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9263_ID_PIOCDE, .regbase = AT91SAM9263_BASE_PIOC, - .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, .regbase = AT91SAM9263_BASE_PIOD, - .clock = &pioCDE_clk, }, { .id = AT91SAM9263_ID_PIOCDE, .regbase = AT91SAM9263_BASE_PIOE, - .clock = &pioCDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index c0c9fa7..4bb0bf0 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -232,6 +232,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_ID("pioD", &pioDE_clk), + CLKDEV_CON_ID("pioE", &pioDE_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -298,23 +303,18 @@ static struct at91_gpio_bank at91sam9g45_gpio[] = { { .id = AT91SAM9G45_ID_PIOA, .regbase = AT91SAM9G45_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9G45_ID_PIOB, .regbase = AT91SAM9G45_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9G45_ID_PIOC, .regbase = AT91SAM9G45_BASE_PIOC, - .clock = &pioC_clk, }, { .id = AT91SAM9G45_ID_PIODE, .regbase = AT91SAM9G45_BASE_PIOD, - .clock = &pioDE_clk, }, { .id = AT91SAM9G45_ID_PIODE, .regbase = AT91SAM9G45_BASE_PIOE, - .clock = &pioDE_clk, } }; diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 6856bad..60555d4 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -183,6 +183,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), + CLKDEV_CON_ID("pioB", &pioB_clk), + CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_ID("pioD", &pioD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { @@ -246,19 +250,15 @@ static struct at91_gpio_bank at91sam9rl_gpio[] = { { .id = AT91SAM9RL_ID_PIOA, .regbase = AT91SAM9RL_BASE_PIOA, - .clock = &pioA_clk, }, { .id = AT91SAM9RL_ID_PIOB, .regbase = AT91SAM9RL_BASE_PIOB, - .clock = &pioB_clk, }, { .id = AT91SAM9RL_ID_PIOC, .regbase = AT91SAM9RL_BASE_PIOC, - .clock = &pioC_clk, }, { .id = AT91SAM9RL_ID_PIOD, .regbase = AT91SAM9RL_BASE_PIOD, - .clock = &pioD_clk, } }; diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index bc17764..4030958 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -70,7 +70,6 @@ extern void at91_ioremap_shdwc(u32 base_addr); struct at91_gpio_bank { unsigned short id; /* peripheral ID */ unsigned long regbase; /* offset from system peripheral base */ - struct clk *clock; /* associated clock */ }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index cedb753..4059f07 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -31,6 +31,7 @@ struct at91_gpio_chip { struct at91_gpio_chip *next; /* Bank sharing same clock */ struct at91_gpio_bank *bank; /* Bank definition */ void __iomem *regbase; /* Base of register bank */ + struct clk *clock; /* associated clock */ }; #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) @@ -58,11 +59,11 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32), - AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32), - AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32), - AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32), - AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioA", 0x00 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioB", 0x20 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioC", 0x40 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioD", 0x60 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioE", 0x80 + PIN_BASE, 32), }; static int gpio_banks; @@ -302,7 +303,7 @@ void at91_gpio_suspend(void) __raw_writel(wakeups[i], pio + PIO_IER); if (!wakeups[i]) - clk_disable(gpio_chip[i].bank->clock); + clk_disable(gpio_chip[i].clock); else { #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); @@ -319,7 +320,7 @@ void at91_gpio_resume(void) void __iomem *pio = gpio_chip[i].regbase; if (!wakeups[i]) - clk_enable(gpio_chip[i].bank->clock); + clk_enable(gpio_chip[i].clock); __raw_writel(wakeups[i], pio + PIO_IDR); __raw_writel(backups[i], pio + PIO_IER); @@ -621,8 +622,14 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) continue; } + at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label); + if (!at91_gpio->clock) { + pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i); + continue; + } + /* enable PIO controller's clock */ - clk_enable(at91_gpio->bank->clock); + clk_enable(at91_gpio->clock); /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ if (last && last->bank->id == at91_gpio->bank->id) -- cgit v0.10.2 From 1a2d9156b5fc92b40aa2ffbc2fdf6d88bbf74f3a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 17 Oct 2011 14:28:38 +0800 Subject: ARM: at91: gpio make struct at91_gpio_bank an initdata this will simplify the switch to the DT and later to the platform_device Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index f7f7e1e..506a26c 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -298,7 +298,7 @@ void __init at91cap9_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91cap9_gpio[] = { +static struct at91_gpio_bank at91cap9_gpio[] __initdata = { { .id = AT91CAP9_ID_PIOABCD, .regbase = AT91CAP9_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 7470f63..9163d7d 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -273,7 +273,7 @@ void __init at91rm9200_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91rm9200_gpio[] = { +static struct at91_gpio_bank at91rm9200_gpio[] __initdata = { { .id = AT91RM9200_ID_PIOA, .regbase = AT91RM9200_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 943da21..3f6c6a1 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -274,7 +274,7 @@ void __init at91sam9260_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9260_gpio[] = { +static struct at91_gpio_bank at91sam9260_gpio[] __initdata = { { .id = AT91SAM9260_ID_PIOA, .regbase = AT91SAM9260_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index dd7924c..a0538c5 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -253,7 +253,7 @@ void __init at91sam9261_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9261_gpio[] = { +static struct at91_gpio_bank at91sam9261_gpio[] __initdata = { { .id = AT91SAM9261_ID_PIOA, .regbase = AT91SAM9261_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 5a74741..5ffbbb0 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -269,7 +269,7 @@ void __init at91sam9263_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9263_gpio[] = { +static struct at91_gpio_bank at91sam9263_gpio[] __initdata = { { .id = AT91SAM9263_ID_PIOA, .regbase = AT91SAM9263_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 4bb0bf0..f61eb64 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -299,7 +299,7 @@ void __init at91sam9g45_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9g45_gpio[] = { +static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = { { .id = AT91SAM9G45_ID_PIOA, .regbase = AT91SAM9G45_BASE_PIOA, diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 60555d4..96247f6 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -246,7 +246,7 @@ void __init at91sam9rl_set_console_clock(int id) * GPIO * -------------------------------------------------------------------- */ -static struct at91_gpio_bank at91sam9rl_gpio[] = { +static struct at91_gpio_bank at91sam9rl_gpio[] __initdata = { { .id = AT91SAM9RL_ID_PIOA, .regbase = AT91SAM9RL_BASE_PIOA, diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 4059f07..163c724 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -29,7 +29,7 @@ struct at91_gpio_chip { struct gpio_chip chip; struct at91_gpio_chip *next; /* Bank sharing same clock */ - struct at91_gpio_bank *bank; /* Bank definition */ + int id; /* ID of register bank */ void __iomem *regbase; /* Base of register bank */ struct clk *clock; /* associated clock */ }; @@ -286,7 +286,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state) else wakeups[bank] &= ~mask; - irq_set_irq_wake(gpio_chip[bank].bank->id, state); + irq_set_irq_wake(gpio_chip[bank].id, state); return 0; } @@ -498,7 +498,7 @@ void __init at91_gpio_irq_setup(void) for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL; pioc++ < gpio_banks; prev = this, this++) { - unsigned id = this->bank->id; + unsigned id = this->id; unsigned i; __raw_writel(~0, this->regbase + PIO_IDR); @@ -613,10 +613,10 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) for (i = 0; i < nr_banks; i++) { at91_gpio = &gpio_chip[i]; - at91_gpio->bank = &data[i]; + at91_gpio->id = data[i].id; at91_gpio->chip.base = PIN_BASE + i * 32; - at91_gpio->regbase = ioremap(at91_gpio->bank->regbase, 512); + at91_gpio->regbase = ioremap(data[i].regbase, 512); if (!at91_gpio->regbase) { pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i); continue; @@ -632,7 +632,7 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) clk_enable(at91_gpio->clock); /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ - if (last && last->bank->id == at91_gpio->bank->id) + if (last && last->id == at91_gpio->id) last->next = at91_gpio; last = at91_gpio; -- cgit v0.10.2 From 63b4c2967850033de0a488d2ba7cd09052199d99 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 25 Nov 2011 01:51:06 +0800 Subject: ARM: at91/boards: use -EINVAL for invalid gpio this will allow to use gpio_is_valid Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c index a60d98d..2628384 100644 --- a/arch/arm/mach-at91/board-1arm.c +++ b/arch/arm/mach-at91/board-1arm.c @@ -70,6 +70,8 @@ static struct macb_platform_data __initdata onearm_eth_data = { static struct at91_usbh_data __initdata onearm_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata onearm_udc_data = { diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 17fc779..3bb4069 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c @@ -75,6 +75,8 @@ static void __init afeb9260_init_early(void) */ static struct at91_usbh_data __initdata afeb9260_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -82,7 +84,7 @@ static struct at91_usbh_data __initdata afeb9260_usbh_data = { */ static struct at91_udc_data __initdata afeb9260_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -138,6 +140,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = { .bus_width_16 = 0, .parts = afeb9260_nand_partition, .num_parts = ARRAY_SIZE(afeb9260_nand_partition), + .det_pin = -EINVAL, }; @@ -149,6 +152,7 @@ static struct at91_mmc_data __initdata afeb9260_mmc_data = { .wp_pin = AT91_PIN_PC4, .slot_b = 1, .wire4 = 1, + .vcc_pin = -EINVAL, }; @@ -169,6 +173,8 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = { static struct at91_cf_data afeb9260_cf_data = { .chipselect = 4, .irq_pin = AT91_PIN_PA6, + .det_pin = -EINVAL, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PA7, .flags = AT91_CF_TRUE_IDE, }; diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c index 18c90c4..8510e9e 100644 --- a/arch/arm/mach-at91/board-cam60.c +++ b/arch/arm/mach-at91/board-cam60.c @@ -62,6 +62,8 @@ static void __init cam60_init_early(void) */ static struct at91_usbh_data __initdata cam60_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -135,7 +137,7 @@ static struct mtd_partition __initdata cam60_nand_partition[] = { static struct atmel_nand_data __initdata cam60_nand_data = { .ale = 21, .cle = 22, - // .det_pin = ... not there + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA9, .enable_pin = AT91_PIN_PA7, .parts = cam60_nand_partition, diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c index 14d1d05..ac3de4f 100644 --- a/arch/arm/mach-at91/board-cap9adk.c +++ b/arch/arm/mach-at91/board-cap9adk.c @@ -70,6 +70,8 @@ static void __init cap9adk_init_early(void) */ static struct at91_usbh_data __initdata cap9adk_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -144,9 +146,9 @@ static struct spi_board_info cap9adk_spi_devices[] = { */ static struct at91_mmc_data __initdata cap9adk_mmc_data = { .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; @@ -154,6 +156,7 @@ static struct at91_mmc_data __initdata cap9adk_mmc_data = { * MACB Ethernet device */ static struct macb_platform_data __initdata cap9adk_macb_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; @@ -172,8 +175,8 @@ static struct mtd_partition __initdata cap9adk_nand_partitions[] = { static struct atmel_nand_data __initdata cap9adk_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected -// .rdy_pin = ... not connected + .det_pin = -EINVAL, + .rdy_pin = -EINVAL, .enable_pin = AT91_PIN_PD15, .parts = cap9adk_nand_partitions, .num_parts = ARRAY_SIZE(cap9adk_nand_partitions), @@ -351,7 +354,7 @@ static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data; * AC97 */ static struct ac97c_platform_data cap9adk_ac97_data = { -// .reset_pin = ... not connected + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c index 529b356..59d9cf9 100644 --- a/arch/arm/mach-at91/board-carmeva.c +++ b/arch/arm/mach-at91/board-carmeva.c @@ -64,6 +64,8 @@ static struct macb_platform_data __initdata carmeva_eth_data = { static struct at91_usbh_data __initdata carmeva_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata carmeva_udc_data = { @@ -75,8 +77,8 @@ static struct at91_udc_data __initdata carmeva_udc_data = { // static struct at91_cf_data __initdata carmeva_cf_data = { // .det_pin = AT91_PIN_PB0, // .rst_pin = AT91_PIN_PC5, - // .irq_pin = ... not connected - // .vcc_pin = ... always powered + // .irq_pin = -EINVAL, + // .vcc_pin = -EINVAL, // }; static struct at91_mmc_data __initdata carmeva_mmc_data = { @@ -84,6 +86,7 @@ static struct at91_mmc_data __initdata carmeva_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PB10, .wp_pin = AT91_PIN_PC14, + .vcc_pin = -EINVAL, }; static struct spi_board_info carmeva_spi_devices[] = { diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c index 5b55525..9ab3d1e 100644 --- a/arch/arm/mach-at91/board-cpu9krea.c +++ b/arch/arm/mach-at91/board-cpu9krea.c @@ -86,6 +86,8 @@ static void __init cpu9krea_init_early(void) */ static struct at91_usbh_data __initdata cpu9krea_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -93,13 +95,14 @@ static struct at91_usbh_data __initdata cpu9krea_usbh_data = { */ static struct at91_udc_data __initdata cpu9krea_udc_data = { .vbus_pin = AT91_PIN_PC8, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* * MACB Ethernet device */ static struct macb_platform_data __initdata cpu9krea_macb_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; @@ -112,6 +115,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = { .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, + .det_pin = -EINVAL, }; #ifdef CONFIG_MACH_CPU9260 @@ -337,6 +341,8 @@ static struct at91_mmc_data __initdata cpu9krea_mmc_data = { .slot_b = 0, .wire4 = 1, .det_pin = AT91_PIN_PA29, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static void __init cpu9krea_board_init(void) diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c index 7a4c82e..368e142 100644 --- a/arch/arm/mach-at91/board-cpuat91.c +++ b/arch/arm/mach-at91/board-cpuat91.c @@ -83,11 +83,14 @@ static void __init cpuat91_init_early(void) } static struct macb_platform_data __initdata cpuat91_eth_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; static struct at91_usbh_data __initdata cpuat91_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata cpuat91_udc_data = { @@ -98,6 +101,8 @@ static struct at91_udc_data __initdata cpuat91_udc_data = { static struct at91_mmc_data __initdata cpuat91_mmc_data = { .det_pin = AT91_PIN_PC2, .wire4 = 1, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct physmap_flash_data cpuat91_flash_data = { diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c index b004b20..1a1547b 100644 --- a/arch/arm/mach-at91/board-csb337.c +++ b/arch/arm/mach-at91/board-csb337.c @@ -65,11 +65,13 @@ static struct macb_platform_data __initdata csb337_eth_data = { static struct at91_usbh_data __initdata csb337_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata csb337_udc_data = { - // this has no VBUS sensing pin .pullup_pin = AT91_PIN_PA24, + .vbus_pin = -EINVAL, }; static struct i2c_board_info __initdata csb337_i2c_devices[] = { @@ -98,6 +100,7 @@ static struct at91_mmc_data __initdata csb337_mmc_data = { .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PD6, + .vcc_pin = -EINVAL, }; static struct spi_board_info csb337_spi_devices[] = { diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c index e966de5..f650bf3 100644 --- a/arch/arm/mach-at91/board-csb637.c +++ b/arch/arm/mach-at91/board-csb637.c @@ -59,6 +59,8 @@ static struct macb_platform_data __initdata csb637_eth_data = { static struct at91_usbh_data __initdata csb637_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata csb637_udc_data = { diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index 41d84d9..bb6b434 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -50,6 +50,7 @@ static void __init ek_init_early(void) static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC8, .enable_pin = AT91_PIN_PC14, }; diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c index 3788fa5..d302ca3 100644 --- a/arch/arm/mach-at91/board-eb9200.c +++ b/arch/arm/mach-at91/board-eb9200.c @@ -67,6 +67,8 @@ static struct macb_platform_data __initdata eb9200_eth_data = { static struct at91_usbh_data __initdata eb9200_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata eb9200_udc_data = { @@ -75,15 +77,18 @@ static struct at91_udc_data __initdata eb9200_udc_data = { }; static struct at91_cf_data __initdata eb9200_cf_data = { + .irq_pin = -EINVAL, .det_pin = AT91_PIN_PB0, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PC5, - // .irq_pin = ... not connected - // .vcc_pin = ... always powered }; static struct at91_mmc_data __initdata eb9200_mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct i2c_board_info __initdata eb9200_i2c_devices[] = { diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index af7622e..69966ce 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -71,11 +71,16 @@ static struct macb_platform_data __initdata ecb_at91eth_data = { static struct at91_usbh_data __initdata ecb_at91usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_mmc_data __initdata ecb_at91mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c index 8e75867..07ef35b 100644 --- a/arch/arm/mach-at91/board-eco920.c +++ b/arch/arm/mach-at91/board-eco920.c @@ -54,6 +54,8 @@ static struct macb_platform_data __initdata eco920_eth_data = { static struct at91_usbh_data __initdata eco920_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata eco920_udc_data = { @@ -64,6 +66,9 @@ static struct at91_udc_data __initdata eco920_udc_data = { static struct at91_mmc_data __initdata eco920_mmc_data = { .slot_b = 0, .wire4 = 0, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct physmap_flash_data eco920_flash_data = { diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c index 4c3f65d..eec02cd 100644 --- a/arch/arm/mach-at91/board-flexibity.c +++ b/arch/arm/mach-at91/board-flexibity.c @@ -52,12 +52,14 @@ static void __init flexibity_init_early(void) /* USB Host port */ static struct at91_usbh_data __initdata flexibity_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* USB Device port */ static struct at91_udc_data __initdata flexibity_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* SPI devices */ @@ -76,6 +78,7 @@ static struct at91_mmc_data __initdata flexibity_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PC9, .wp_pin = AT91_PIN_PC4, + .vcc_pin = -EINVAL, }; /* LEDs */ diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c index de8e096..caf017f 100644 --- a/arch/arm/mach-at91/board-foxg20.c +++ b/arch/arm/mach-at91/board-foxg20.c @@ -106,6 +106,8 @@ static void __init foxg20_init_early(void) */ static struct at91_usbh_data __initdata foxg20_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -113,7 +115,7 @@ static struct at91_usbh_data __initdata foxg20_usbh_data = { */ static struct at91_udc_data __initdata foxg20_udc_data = { .vbus_pin = AT91_PIN_PC6, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -147,6 +149,9 @@ static struct macb_platform_data __initdata foxg20_macb_data = { static struct at91_mmc_data __initdata foxg20_mmc_data = { .slot_b = 1, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c index 51c82f1..230e719 100644 --- a/arch/arm/mach-at91/board-gsia18s.c +++ b/arch/arm/mach-at91/board-gsia18s.c @@ -80,6 +80,8 @@ static void __init gsia18s_init_early(void) */ static struct at91_usbh_data __initdata usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -87,7 +89,7 @@ static struct at91_usbh_data __initdata usbh_data = { */ static struct at91_udc_data __initdata udc_data = { .vbus_pin = AT91_PIN_PA22, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* @@ -530,6 +532,7 @@ static struct i2c_board_info __initdata gsia18s_i2c_devices[] = { static struct at91_cf_data __initdata gsia18s_cf1_data = { .irq_pin = AT91_PIN_PA27, .det_pin = AT91_PIN_PB30, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PB31, .chipselect = 5, .flags = AT91_CF_TRUE_IDE, diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c index 9628a3d..efde1b2 100644 --- a/arch/arm/mach-at91/board-kafa.c +++ b/arch/arm/mach-at91/board-kafa.c @@ -68,6 +68,8 @@ static struct macb_platform_data __initdata kafa_eth_data = { static struct at91_usbh_data __initdata kafa_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata kafa_udc_data = { diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index 5ba5244..d75a4a2 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c @@ -76,6 +76,8 @@ static struct macb_platform_data __initdata kb9202_eth_data = { static struct at91_usbh_data __initdata kb9202_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata kb9202_udc_data = { @@ -87,6 +89,8 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = { .det_pin = AT91_PIN_PB2, .slot_b = 0, .wire4 = 1, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; static struct mtd_partition __initdata kb9202_nand_partition[] = { @@ -100,7 +104,7 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = { static struct atmel_nand_data __initdata kb9202_nand_data = { .ale = 22, .cle = 21, - // .det_pin = ... not there + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC29, .enable_pin = AT91_PIN_PC28, .parts = kb9202_nand_partition, diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c index 7d24d84..3f8617c 100644 --- a/arch/arm/mach-at91/board-neocore926.c +++ b/arch/arm/mach-at91/board-neocore926.c @@ -72,6 +72,7 @@ static void __init neocore926_init_early(void) static struct at91_usbh_data __initdata neocore926_usbh_data = { .ports = 2, .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -79,7 +80,7 @@ static struct at91_usbh_data __initdata neocore926_usbh_data = { */ static struct at91_udc_data __initdata neocore926_udc_data = { .vbus_pin = AT91_PIN_PA25, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -149,6 +150,7 @@ static struct at91_mmc_data __initdata neocore926_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PE18, .wp_pin = AT91_PIN_PE19, + .vcc_pin = -EINVAL, }; @@ -190,6 +192,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = { .enable_pin = AT91_PIN_PD15, .parts = neocore926_nand_partition, .num_parts = ARRAY_SIZE(neocore926_nand_partition), + .det_pin = -EINVAL, }; static struct sam9_smc_config __initdata neocore926_nand_smc_config = { diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index 9a6e021..b4a12fc 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c @@ -107,6 +107,8 @@ static void __init add_device_pcontrol(void) */ static struct at91_usbh_data __initdata usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c index dc18759..ab024fa 100644 --- a/arch/arm/mach-at91/board-picotux200.c +++ b/arch/arm/mach-at91/board-picotux200.c @@ -67,6 +67,8 @@ static struct macb_platform_data __initdata picotux200_eth_data = { static struct at91_usbh_data __initdata picotux200_usbh_data = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_mmc_data __initdata picotux200_mmc_data = { @@ -74,6 +76,7 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = { .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PA17, + .vcc_pin = -EINVAL, }; #define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c index 04be427..e029d22 100644 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ b/arch/arm/mach-at91/board-qil-a9260.c @@ -77,6 +77,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -84,7 +86,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; /* @@ -133,7 +135,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -172,9 +174,9 @@ static void __init ek_add_device_nand(void) static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 0, .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; /* diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c index 022d0ce..782f379 100644 --- a/arch/arm/mach-at91/board-rm9200dk.c +++ b/arch/arm/mach-at91/board-rm9200dk.c @@ -72,6 +72,8 @@ static struct macb_platform_data __initdata dk_eth_data = { static struct at91_usbh_data __initdata dk_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata dk_udc_data = { @@ -80,16 +82,19 @@ static struct at91_udc_data __initdata dk_udc_data = { }; static struct at91_cf_data __initdata dk_cf_data = { + .irq_pin = -EINVAL, .det_pin = AT91_PIN_PB0, + .vcc_pin = -EINVAL, .rst_pin = AT91_PIN_PC5, - // .irq_pin = ... not connected - // .vcc_pin = ... always powered }; #ifndef CONFIG_MTD_AT91_DATAFLASH_CARD static struct at91_mmc_data __initdata dk_mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif @@ -143,7 +148,7 @@ static struct atmel_nand_data __initdata dk_nand_data = { .cle = 21, .det_pin = AT91_PIN_PB1, .rdy_pin = AT91_PIN_PC2, - // .enable_pin = ... not there + .enable_pin = -EINVAL, .parts = dk_nand_partition, .num_parts = ARRAY_SIZE(dk_nand_partition), }; diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c index ed27586..ef7c12a 100644 --- a/arch/arm/mach-at91/board-rm9200ek.c +++ b/arch/arm/mach-at91/board-rm9200ek.c @@ -72,6 +72,8 @@ static struct macb_platform_data __initdata ek_eth_data = { static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata ek_udc_data = { @@ -85,6 +87,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PA17, + .vcc_pin = -EINVAL, }; #endif diff --git a/arch/arm/mach-at91/board-rsi-ews.c b/arch/arm/mach-at91/board-rsi-ews.c index ed3b21f..af0750f 100644 --- a/arch/arm/mach-at91/board-rsi-ews.c +++ b/arch/arm/mach-at91/board-rsi-ews.c @@ -70,6 +70,8 @@ static struct macb_platform_data rsi_ews_eth_data __initdata = { */ static struct at91_usbh_data rsi_ews_usbh_data __initdata = { .ports = 1, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c index 1e1834b..84bce58 100644 --- a/arch/arm/mach-at91/board-sam9-l9260.c +++ b/arch/arm/mach-at91/board-sam9-l9260.c @@ -72,6 +72,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -79,7 +81,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -134,7 +136,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -176,7 +178,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PC8, .wp_pin = AT91_PIN_PC4, -// .vcc_pin = ... not connected + .vcc_pin = -EINVAL, }; static void __init ek_board_init(void) diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c index e1b250e..be8233b 100644 --- a/arch/arm/mach-at91/board-sam9260ek.c +++ b/arch/arm/mach-at91/board-sam9260ek.c @@ -75,6 +75,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -82,7 +84,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -176,7 +178,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -223,9 +225,9 @@ static void __init ek_add_device_nand(void) static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 1, .wire4 = 1, -// .det_pin = ... not connected -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index a879b33..4089507 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c @@ -151,6 +151,8 @@ static void __init ek_add_device_dm9000(void) {} */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -159,7 +161,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PB29, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -182,7 +184,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 22, .cle = 21, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC15, .enable_pin = AT91_PIN_PC14, .parts = ek_nand_partition, @@ -345,6 +347,9 @@ static struct spi_board_info ek_spi_devices[] = { */ static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif /* CONFIG_SPI_ATMEL_* */ diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 3ce0b17..29f6605 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -74,6 +74,7 @@ static void __init ek_init_early(void) static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -81,7 +82,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PA25, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -151,7 +152,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PE18, .wp_pin = AT91_PIN_PE19, -// .vcc_pin = ... not connected + .vcc_pin = -EINVAL, }; @@ -183,7 +184,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, .parts = ek_nand_partition, @@ -353,6 +354,7 @@ static void __init ek_add_device_buttons(void) {} * reset_pin is not connected: NRST */ static struct ac97c_platform_data ek_ac97_data = { + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index a67b269..843d628 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -86,6 +86,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -93,7 +95,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; @@ -163,6 +165,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { .cle = 22, .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, + .det_pin = -EINVAL, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; @@ -210,6 +213,7 @@ static struct mci_platform_data __initdata ek_mmc_data = { .slot[1] = { .bus_width = 4, .detect_pin = AT91_PIN_PC9, + .wp_pin = -EINVAL, }, }; @@ -218,6 +222,8 @@ static struct at91_mmc_data __initdata ek_mmc_data = { .slot_b = 1, /* Only one slot so use slot B */ .wire4 = 1, .det_pin = AT91_PIN_PC9, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif @@ -227,6 +233,7 @@ static void __init ek_add_device_mmc(void) if (ek_have_2mmc()) { ek_mmc_data.slot[0].bus_width = 4; ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2; + ek_mmc_data.slot[0].wp_pin = -1; } at91_add_device_mci(0, &ek_mmc_data); #else diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 061465d..ea0d1b9 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -69,6 +69,7 @@ static void __init ek_init_early(void) static struct at91_usbh_data __initdata ek_usbh_hs_data = { .ports = 2, .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -100,6 +101,7 @@ static struct mci_platform_data __initdata mci0_data = { .slot[0] = { .bus_width = 4, .detect_pin = AT91_PIN_PD10, + .wp_pin = -EINVAL, }, }; @@ -143,6 +145,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { .cle = 22, .rdy_pin = AT91_PIN_PC8, .enable_pin = AT91_PIN_PC14, + .det_pin = -EINVAL, .parts = ek_nand_partition, .num_parts = ARRAY_SIZE(ek_nand_partition), }; @@ -330,6 +333,7 @@ static void __init ek_add_device_buttons(void) {} * reset_pin is not connected: NRST */ static struct ac97c_platform_data ek_ac97_data = { + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index c561eda..c1366d0 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -67,8 +67,8 @@ static struct usba_platform_data __initdata ek_usba_udc_data = { static struct at91_mmc_data __initdata ek_mmc_data = { .wire4 = 1, .det_pin = AT91_PIN_PA15, -// .wp_pin = ... not connected -// .vcc_pin = ... not connected + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; @@ -91,7 +91,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PD17, .enable_pin = AT91_PIN_PB6, .parts = ek_nand_partition, @@ -204,6 +204,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data; * reset_pin is not connected: NRST */ static struct ac97c_platform_data ek_ac97_data = { + .reset_pin = -EINVAL, }; diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c index 73ed8c7..4770db0 100644 --- a/arch/arm/mach-at91/board-snapper9260.c +++ b/arch/arm/mach-at91/board-snapper9260.c @@ -57,15 +57,19 @@ static void __init snapper9260_init_early(void) static struct at91_usbh_data __initdata snapper9260_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; static struct at91_udc_data __initdata snapper9260_udc_data = { .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5), .vbus_active_low = 1, .vbus_polled = 1, + .pullup_pin = -EINVAL, }; static struct macb_platform_data snapper9260_macb_data = { + .phy_irq_pin = -EINVAL, .is_rmii = 1, }; @@ -104,6 +108,8 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = { .parts = snapper9260_nand_partitions, .num_parts = ARRAY_SIZE(snapper9260_nand_partitions), .bus_width_16 = 0, + .enable_pin = -EINVAL, + .det_pin = -EINVAL, }; static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index f4b9b6f..e8d3d5b 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -85,6 +85,7 @@ static struct atmel_nand_data __initdata nand_data = { .rdy_pin = AT91_PIN_PC13, .enable_pin = AT91_PIN_PC14, .bus_width_16 = 0, + .det_pin = -EINVAL, }; static struct sam9_smc_config __initdata nand_smc_config = { @@ -122,12 +123,17 @@ static void __init add_device_nand(void) static struct mci_platform_data __initdata mmc_data = { .slot[0] = { .bus_width = 4, + .detect_pin = -1; + .wp_pin = -1; }, }; #else static struct at91_mmc_data __initdata mmc_data = { .slot_b = 0, .wire4 = 1, + .det_pin = -EINVAL, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; #endif @@ -137,6 +143,8 @@ static struct at91_mmc_data __initdata mmc_data = { */ static struct at91_usbh_data __initdata usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; @@ -145,12 +153,12 @@ static struct at91_usbh_data __initdata usbh_data = { */ static struct at91_udc_data __initdata portuxg20_udc_data = { .vbus_pin = AT91_PIN_PC7, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; static struct at91_udc_data __initdata stamp9g20evb_udc_data = { .vbus_pin = AT91_PIN_PA22, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c index 2ffb2c8..26c36fc 100644 --- a/arch/arm/mach-at91/board-usb-a926x.c +++ b/arch/arm/mach-at91/board-usb-a926x.c @@ -66,6 +66,8 @@ static void __init ek_init_early(void) */ static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -73,7 +75,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = { */ static struct at91_udc_data __initdata ek_udc_data = { .vbus_pin = AT91_PIN_PB11, - .pullup_pin = 0, /* pull-up driven by UDC */ + .pullup_pin = -EINVAL, /* pull-up driven by UDC */ }; static void __init ek_add_device_udc(void) @@ -193,7 +195,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { static struct atmel_nand_data __initdata ek_nand_data = { .ale = 21, .cle = 22, -// .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PA22, .enable_pin = AT91_PIN_PD15, .parts = ek_nand_partition, diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index 2c40a21..bbd553e 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -120,6 +120,8 @@ static struct macb_platform_data __initdata yl9200_eth_data = { */ static struct at91_usbh_data __initdata yl9200_usbh_data = { .ports = 1, /* PQFP version of AT91RM9200 */ + .vbus_pin = {-EINVAL, -EINVAL}, + .overcurrent_pin= {-EINVAL, -EINVAL}, }; /* @@ -137,8 +139,9 @@ static struct at91_udc_data __initdata yl9200_udc_data = { */ static struct at91_mmc_data __initdata yl9200_mmc_data = { .det_pin = AT91_PIN_PB9, - // .wp_pin = ... not connected .wire4 = 1, + .wp_pin = -EINVAL, + .vcc_pin = -EINVAL, }; /* @@ -175,7 +178,7 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = { static struct atmel_nand_data __initdata yl9200_nand_data = { .ale = 6, .cle = 7, - // .det_pin = ... not connected + .det_pin = -EINVAL, .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ .parts = yl9200_nand_partition, diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index e209a29..d0b377b 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -44,10 +44,10 @@ /* USB Device */ struct at91_udc_data { - u8 vbus_pin; /* high == host powering us */ + int vbus_pin; /* high == host powering us */ u8 vbus_active_low; /* vbus polarity */ u8 vbus_polled; /* Use polling, not interrupt */ - u8 pullup_pin; /* active == D+ pulled up */ + int pullup_pin; /* active == D+ pulled up */ u8 pullup_active_low; /* true == pullup_pin is active low */ }; extern void __init at91_add_device_udc(struct at91_udc_data *data); @@ -57,10 +57,10 @@ extern void __init at91_add_device_usba(struct usba_platform_data *data); /* Compact Flash */ struct at91_cf_data { - u8 irq_pin; /* I/O IRQ */ - u8 det_pin; /* Card detect */ - u8 vcc_pin; /* power switching */ - u8 rst_pin; /* card reset */ + int irq_pin; /* I/O IRQ */ + int det_pin; /* Card detect */ + int vcc_pin; /* power switching */ + int rst_pin; /* card reset */ u8 chipselect; /* EBI Chip Select number */ u8 flags; #define AT91_CF_TRUE_IDE 0x01 @@ -71,11 +71,11 @@ extern void __init at91_add_device_cf(struct at91_cf_data *data); /* MMC / SD */ /* at91_mci platform config */ struct at91_mmc_data { - u8 det_pin; /* card detect IRQ */ + int det_pin; /* card detect IRQ */ unsigned slot_b:1; /* uses Slot B */ unsigned wire4:1; /* (SD) supports DAT0..DAT3 */ - u8 wp_pin; /* (SD) writeprotect detect */ - u8 vcc_pin; /* power switching (high == on) */ + int wp_pin; /* (SD) writeprotect detect */ + int vcc_pin; /* power switching (high == on) */ }; extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); @@ -87,10 +87,10 @@ extern void __init at91_add_device_eth(struct macb_platform_data *data); /* USB Host */ struct at91_usbh_data { u8 ports; /* number of ports on root hub */ - u8 vbus_pin[2]; /* port power-control pin */ + int vbus_pin[2]; /* port power-control pin */ u8 vbus_pin_inverted; u8 overcurrent_supported; - u8 overcurrent_pin[2]; + int overcurrent_pin[2]; u8 overcurrent_status[2]; u8 overcurrent_changed[2]; }; @@ -100,9 +100,9 @@ extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); /* NAND / SmartMedia */ struct atmel_nand_data { - u8 enable_pin; /* chip enable */ - u8 det_pin; /* card detect */ - u8 rdy_pin; /* ready/busy */ + int enable_pin; /* chip enable */ + int det_pin; /* card detect */ + int rdy_pin; /* ready/busy */ u8 rdy_pin_active_low; /* rdy_pin value is inverted */ u8 ale; /* address line number connected to ALE */ u8 cle; /* address line number connected to CLE */ diff --git a/include/linux/platform_data/macb.h b/include/linux/platform_data/macb.h index e7c748f..b081c72 100644 --- a/include/linux/platform_data/macb.h +++ b/include/linux/platform_data/macb.h @@ -10,7 +10,7 @@ struct macb_platform_data { u32 phy_mask; - u8 phy_irq_pin; /* PHY IRQ */ + int phy_irq_pin; /* PHY IRQ */ u8 is_rmii; /* using RMII interface? */ }; -- cgit v0.10.2 From cc9f9aef6ad3ebdda911e25b38222c215f7634f9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:28:25 +0800 Subject: ARM: at91/soc: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index 3f54eca..d298fb7 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -76,7 +76,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { - if (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -179,7 +179,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - if (data && data->vbus_pin > 0) { + if (data && gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); usba_udc_data.pdata.vbus_pin = data->vbus_pin; @@ -232,7 +232,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + if (gpio_is_valid(data->phy_irq_pin)) { at91_set_gpio_input(data->phy_irq_pin, 0); at91_set_deglitch(data->phy_irq_pin, 1); } @@ -332,13 +332,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); if (mmc_id == 0) { /* MCI0 */ @@ -425,15 +425,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -816,7 +816,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index cb22440..064bbae 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -114,11 +114,11 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } - if (data->pullup_pin) + if (gpio_is_valid(data->pullup_pin)) at91_set_gpio_output(data->pullup_pin, 0); udc_data = *data; @@ -167,7 +167,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + if (gpio_is_valid(data->phy_irq_pin)) { at91_set_gpio_input(data->phy_irq_pin, 0); at91_set_deglitch(data->phy_irq_pin, 1); } @@ -260,7 +260,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) ); /* input/irq */ - if (data->irq_pin) { + if (gpio_is_valid(data->irq_pin)) { at91_set_gpio_input(data->irq_pin, 1); at91_set_deglitch(data->irq_pin, 1); } @@ -268,7 +268,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_set_deglitch(data->det_pin, 1); /* outputs, initially off */ - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); at91_set_gpio_output(data->rst_pin, 0); @@ -328,13 +328,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -419,15 +419,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) ); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index f6d8ccf..f9bcb25 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -115,7 +115,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } @@ -168,7 +168,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + if (gpio_is_valid(data->phy_irq_pin)) { at91_set_gpio_input(data->phy_irq_pin, 0); at91_set_deglitch(data->phy_irq_pin, 1); } @@ -243,13 +243,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -330,11 +330,11 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { if (data->slot[i].bus_width) { /* input/irq */ - if (data->slot[i].detect_pin) { + if (gpio_is_valid(data->slot[i].detect_pin)) { at91_set_gpio_input(data->slot[i].detect_pin, 1); at91_set_deglitch(data->slot[i].detect_pin, 1); } - if (data->slot[i].wp_pin) + if (gpio_is_valid(data->slot[i].wp_pin)) at91_set_gpio_input(data->slot[i].wp_pin, 1); switch (i) { @@ -426,15 +426,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -1290,17 +1290,17 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa); - if (data->rst_pin) { + if (gpio_is_valid(data->rst_pin)) { at91_set_multi_drive(data->rst_pin, 0); at91_set_gpio_output(data->rst_pin, 1); } - if (data->irq_pin) { + if (gpio_is_valid(data->irq_pin)) { at91_set_gpio_input(data->irq_pin, 0); at91_set_deglitch(data->irq_pin, 1); } - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 0); at91_set_deglitch(data->det_pin, 1); } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index e5cff1d..dff4c2d 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -118,7 +118,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } @@ -171,13 +171,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -240,15 +240,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b344ec8..a1d452b 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -70,7 +70,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { - if (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -123,7 +123,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) if (!data) return; - if (data->vbus_pin) { + if (gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); } @@ -176,7 +176,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + if (gpio_is_valid(data->phy_irq_pin)) { at91_set_gpio_input(data->phy_irq_pin, 0); at91_set_deglitch(data->phy_irq_pin, 1); } @@ -276,13 +276,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); if (mmc_id == 0) { /* MCI0 */ @@ -430,17 +430,17 @@ void __init at91_add_device_cf(struct at91_cf_data *data) } at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->irq_pin) { + if (gpio_is_valid(data->irq_pin)) { at91_set_gpio_input(data->irq_pin, 1); at91_set_deglitch(data->irq_pin, 1); } - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) /* initially off */ at91_set_gpio_output(data->vcc_pin, 0); @@ -500,15 +500,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -749,7 +749,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index fc3eb4d..b7582dd 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -120,7 +120,7 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { - if (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -181,7 +181,7 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { - if (data->vbus_pin[i]) + if (gpio_is_valid(data->vbus_pin[i])) at91_set_gpio_output(data->vbus_pin[i], 0); } @@ -263,7 +263,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - if (data && data->vbus_pin > 0) { + if (data && gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); usba_udc_data.pdata.vbus_pin = data->vbus_pin; @@ -316,7 +316,7 @@ void __init at91_add_device_eth(struct macb_platform_data *data) if (!data) return; - if (data->phy_irq_pin) { + if (gpio_is_valid(data->phy_irq_pin)) { at91_set_gpio_input(data->phy_irq_pin, 0); at91_set_deglitch(data->phy_irq_pin, 1); } @@ -449,11 +449,11 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) /* input/irq */ - if (data->slot[0].detect_pin) { + if (gpio_is_valid(data->slot[0].detect_pin)) { at91_set_gpio_input(data->slot[0].detect_pin, 1); at91_set_deglitch(data->slot[0].detect_pin, 1); } - if (data->slot[0].wp_pin) + if (gpio_is_valid(data->slot[0].wp_pin)) at91_set_gpio_input(data->slot[0].wp_pin, 1); if (mmc_id == 0) { /* MCI0 */ @@ -556,15 +556,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); nand_data = *data; @@ -859,7 +859,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 366c1cf..61908dc 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -147,7 +147,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); - if (data && data->vbus_pin > 0) { + if (data && gpio_is_valid(data->vbus_pin)) { at91_set_gpio_input(data->vbus_pin, 0); at91_set_deglitch(data->vbus_pin, 1); usba_udc_data.pdata.vbus_pin = data->vbus_pin; @@ -201,13 +201,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) return; /* input/irq */ - if (data->det_pin) { + if (gpio_is_valid(data->det_pin)) { at91_set_gpio_input(data->det_pin, 1); at91_set_deglitch(data->det_pin, 1); } - if (data->wp_pin) + if (gpio_is_valid(data->wp_pin)) at91_set_gpio_input(data->wp_pin, 1); - if (data->vcc_pin) + if (gpio_is_valid(data->vcc_pin)) at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ @@ -275,15 +275,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data) at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); /* enable pin */ - if (data->enable_pin) + if (gpio_is_valid(data->enable_pin)) at91_set_gpio_output(data->enable_pin, 1); /* ready/busy pin */ - if (data->rdy_pin) + if (gpio_is_valid(data->rdy_pin)) at91_set_gpio_input(data->rdy_pin, 1); /* card detect pin */ - if (data->det_pin) + if (gpio_is_valid(data->det_pin)) at91_set_gpio_input(data->det_pin, 1); at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */ @@ -483,7 +483,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data) at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */ /* reset */ - if (data->reset_pin) + if (gpio_is_valid(data->reset_pin)) at91_set_gpio_output(data->reset_pin, 0); ac97_data = *data; -- cgit v0.10.2 From 477c87e90853d136b188c50c0e4a93d01cad872e Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:29:53 +0800 Subject: ARM: at91/pata: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index a76f24a..5249e6d 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -360,7 +360,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) ap->flags |= ATA_FLAG_SLAVE_POSS; ap->pio_mask = ATA_PIO4; - if (!irq) { + if (!gpio_is_valid(irq)) { ap->flags |= ATA_FLAG_PIO_POLLING; ata_port_desc(ap, "no IRQ, using PIO polling"); } @@ -414,8 +414,8 @@ static int __devinit pata_at91_probe(struct platform_device *pdev) host->private_data = info; - ret = ata_host_activate(host, irq ? gpio_to_irq(irq) : 0, - irq ? ata_sff_interrupt : NULL, + return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, + gpio_is_valid(irq) ? ata_sff_interrupt : NULL, irq_flags, &pata_at91_sht); if (!ret) -- cgit v0.10.2 From 43d91483536437bac009f9dc6428b1828909e55a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:30:14 +0800 Subject: ARM: at91/ide: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c index 6dede8f..41d4155 100644 --- a/drivers/ide/at91_ide.c +++ b/drivers/ide/at91_ide.c @@ -314,7 +314,7 @@ static int __init at91_ide_probe(struct platform_device *pdev) apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0); /* with GPIO interrupt we have to do quirks in handler */ - if (board->irq_pin >= PIN_BASE) + if (gpio_is_valid(board->irq_pin)) host->irq_handler = at91_irq_handler; host->ports[0]->select_data = board->chipselect; -- cgit v0.10.2 From 53a33bded0ee7989a94b10719f14e52ed2f9eb48 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:30:58 +0800 Subject: ARM: at91/mmc: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index a8b4d2a..f437c3e 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -741,7 +741,7 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); /* maybe switch power to the card */ - if (host->board->vcc_pin) { + if (gpio_is_valid(host->board->vcc_pin)) { switch (ios->power_mode) { case MMC_POWER_OFF: gpio_set_value(host->board->vcc_pin, 0); @@ -897,7 +897,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc) { struct at91mci_host *host = mmc_priv(mmc); - if (host->board->wp_pin) + if (gpio_is_valid(host->board->wp_pin)) return !!gpio_get_value(host->board->wp_pin); /* * Board doesn't support read only detection; let the mmc core @@ -991,21 +991,21 @@ static int __init at91_mci_probe(struct platform_device *pdev) * Reserve GPIOs ... board init code makes sure these pins are set * up as GPIOs with the right direction (input, except for vcc) */ - if (host->board->det_pin) { + if (gpio_is_valid(host->board->det_pin)) { ret = gpio_request(host->board->det_pin, "mmc_detect"); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); goto fail4b; } } - if (host->board->wp_pin) { + if (gpio_is_valid(host->board->wp_pin)) { ret = gpio_request(host->board->wp_pin, "mmc_wp"); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n"); goto fail4; } } - if (host->board->vcc_pin) { + if (gpio_is_valid(host->board->vcc_pin)) { ret = gpio_request(host->board->vcc_pin, "mmc_vcc"); if (ret < 0) { dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n"); @@ -1057,7 +1057,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) /* * Add host to MMC layer */ - if (host->board->det_pin) { + if (gpio_is_valid(host->board->det_pin)) { host->present = !gpio_get_value(host->board->det_pin); } else @@ -1068,7 +1068,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) /* * monitor card insertion/removal if we can */ - if (host->board->det_pin) { + if (gpio_is_valid(host->board->det_pin)) { ret = request_irq(gpio_to_irq(host->board->det_pin), at91_mmc_det_irq, 0, mmc_hostname(mmc), host); if (ret) @@ -1087,13 +1087,13 @@ fail0: fail1: clk_put(host->mci_clk); fail2: - if (host->board->vcc_pin) + if (gpio_is_valid(host->board->vcc_pin)) gpio_free(host->board->vcc_pin); fail3: - if (host->board->wp_pin) + if (gpio_is_valid(host->board->wp_pin)) gpio_free(host->board->wp_pin); fail4: - if (host->board->det_pin) + if (gpio_is_valid(host->board->det_pin)) gpio_free(host->board->det_pin); fail4b: if (host->buffer) @@ -1125,7 +1125,7 @@ static int __exit at91_mci_remove(struct platform_device *pdev) dma_free_coherent(&pdev->dev, MCI_BUFSIZE, host->buffer, host->physical_address); - if (host->board->det_pin) { + if (gpio_is_valid(host->board->det_pin)) { if (device_can_wakeup(&pdev->dev)) free_irq(gpio_to_irq(host->board->det_pin), host); device_init_wakeup(&pdev->dev, 0); @@ -1140,9 +1140,9 @@ static int __exit at91_mci_remove(struct platform_device *pdev) clk_disable(host->mci_clk); /* Disable the peripheral clock */ clk_put(host->mci_clk); - if (host->board->vcc_pin) + if (gpio_is_valid(host->board->vcc_pin)) gpio_free(host->board->vcc_pin); - if (host->board->wp_pin) + if (gpio_is_valid(host->board->wp_pin)) gpio_free(host->board->wp_pin); iounmap(host->baseaddr); @@ -1163,7 +1163,7 @@ static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state) struct at91mci_host *host = mmc_priv(mmc); int ret = 0; - if (host->board->det_pin && device_may_wakeup(&pdev->dev)) + if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev)) enable_irq_wake(host->board->det_pin); if (mmc) @@ -1178,7 +1178,7 @@ static int at91_mci_resume(struct platform_device *pdev) struct at91mci_host *host = mmc_priv(mmc); int ret = 0; - if (host->board->det_pin && device_may_wakeup(&pdev->dev)) + if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev)) disable_irq_wake(host->board->det_pin); if (mmc) -- cgit v0.10.2 From 1d6dc0683d434c084ac067220c3e58d058c434a1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:31:37 +0800 Subject: ARM: at91/nand: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 23e5d77..4dd056e 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -113,7 +113,7 @@ static int cpu_has_dma(void) */ static void atmel_nand_enable(struct atmel_nand_host *host) { - if (host->board->enable_pin) + if (gpio_is_valid(host->board->enable_pin)) gpio_set_value(host->board->enable_pin, 0); } @@ -122,7 +122,7 @@ static void atmel_nand_enable(struct atmel_nand_host *host) */ static void atmel_nand_disable(struct atmel_nand_host *host) { - if (host->board->enable_pin) + if (gpio_is_valid(host->board->enable_pin)) gpio_set_value(host->board->enable_pin, 1); } @@ -492,7 +492,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->IO_ADDR_W = host->io_base; nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; - if (host->board->rdy_pin) + if (gpio_is_valid(host->board->rdy_pin)) nand_chip->dev_ready = atmel_nand_device_ready; regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -530,7 +530,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); atmel_nand_enable(host); - if (host->board->det_pin) { + if (gpio_is_valid(host->board->det_pin)) { if (gpio_get_value(host->board->det_pin)) { printk(KERN_INFO "No SmartMedia card inserted.\n"); res = -ENXIO; -- cgit v0.10.2 From 8a7a49d18b6bc0a5fd6f356b09ef3d649c7f9010 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:32:23 +0800 Subject: ARM: at91/ohci: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 95a9fec..5df0b0e 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -223,7 +223,7 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int if (port < 0 || port >= 2) return; - if (pdata->vbus_pin[port] <= 0) + if (!gpio_is_valid(pdata->vbus_pin[port])) return; gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable); @@ -234,7 +234,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) if (port < 0 || port >= 2) return -EINVAL; - if (pdata->vbus_pin[port] <= 0) + if (!gpio_is_valid(pdata->vbus_pin[port])) return -EINVAL; return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted; @@ -465,7 +465,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) if (pdata) { for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { - if (pdata->vbus_pin[i] <= 0) + if (!gpio_is_valid(pdata->vbus_pin[i])) continue; gpio_request(pdata->vbus_pin[i], "ohci_vbus"); ohci_at91_usb_set_power(pdata, i, 1); @@ -474,7 +474,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { int ret; - if (pdata->overcurrent_pin[i] <= 0) + if (!gpio_is_valid(pdata->overcurrent_pin[i])) continue; gpio_request(pdata->overcurrent_pin[i], "ohci_overcurrent"); @@ -499,14 +499,14 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) if (pdata) { for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { - if (pdata->vbus_pin[i] <= 0) + if (!gpio_is_valid(pdata->vbus_pin[i])) continue; ohci_at91_usb_set_power(pdata, i, 0); gpio_free(pdata->vbus_pin[i]); } for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { - if (pdata->overcurrent_pin[i] <= 0) + if (!gpio_is_valid(pdata->overcurrent_pin[i])) continue; free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev); gpio_free(pdata->overcurrent_pin[i]); -- cgit v0.10.2 From 3285e0ec088febc5a88f57ddd78385a7da71476c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 15:31:58 +0800 Subject: ARM: at91/udc: use gpio_is_valid to check the gpio Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 8efe0fa..1ed56d8 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1748,7 +1748,7 @@ static int __init at91udc_probe(struct platform_device *pdev) /* rm9200 needs manual D+ pullup; off by default */ if (cpu_is_at91rm9200()) { - if (udc->board.pullup_pin <= 0) { + if (gpio_is_valid(udc->board.pullup_pin)) { DBG("no D+ pullup?\n"); retval = -ENODEV; goto fail0; @@ -1815,7 +1815,7 @@ static int __init at91udc_probe(struct platform_device *pdev) DBG("request irq %d failed\n", udc->udp_irq); goto fail1; } - if (udc->board.vbus_pin > 0) { + if (gpio_is_valid(udc->board.vbus_pin)) { retval = gpio_request(udc->board.vbus_pin, "udc_vbus"); if (retval < 0) { DBG("request vbus pin failed\n"); @@ -1859,10 +1859,10 @@ static int __init at91udc_probe(struct platform_device *pdev) INFO("%s version %s\n", driver_name, DRIVER_VERSION); return 0; fail4: - if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled) + if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) free_irq(udc->board.vbus_pin, udc); fail3: - if (udc->board.vbus_pin > 0) + if (gpio_is_valid(udc->board.vbus_pin)) gpio_free(udc->board.vbus_pin); fail2: free_irq(udc->udp_irq, udc); @@ -1897,7 +1897,7 @@ static int __exit at91udc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); - if (udc->board.vbus_pin > 0) { + if (gpio_is_valid(udc->board.vbus_pin)) { free_irq(udc->board.vbus_pin, udc); gpio_free(udc->board.vbus_pin); } @@ -1941,7 +1941,7 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg) enable_irq_wake(udc->udp_irq); udc->active_suspend = wake; - if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled && wake) + if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled && wake) enable_irq_wake(udc->board.vbus_pin); return 0; } @@ -1951,7 +1951,7 @@ static int at91udc_resume(struct platform_device *pdev) struct at91_udc *udc = platform_get_drvdata(pdev); unsigned long flags; - if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled && + if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled && udc->active_suspend) disable_irq_wake(udc->board.vbus_pin); -- cgit v0.10.2 From d0fbda9add3281c97205649150fc99fc26148792 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 17 Sep 2011 21:49:36 +0800 Subject: ARM: at91/gpio: drop PIN_BASE Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 163c724..d000448 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -59,18 +59,17 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA", 0x00 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioB", 0x20 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioC", 0x40 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioD", 0x60 + PIN_BASE, 32), - AT91_GPIO_CHIP("pioE", 0x80 + PIN_BASE, 32), + AT91_GPIO_CHIP("pioA", 0x00, 32), + AT91_GPIO_CHIP("pioB", 0x20, 32), + AT91_GPIO_CHIP("pioC", 0x40, 32), + AT91_GPIO_CHIP("pioD", 0x60, 32), + AT91_GPIO_CHIP("pioE", 0x80, 32), }; static int gpio_banks; static inline void __iomem *pin_to_controller(unsigned pin) { - pin -= PIN_BASE; pin /= 32; if (likely(pin < gpio_banks)) return gpio_chip[pin].regbase; @@ -80,7 +79,6 @@ static inline void __iomem *pin_to_controller(unsigned pin) static inline unsigned pin_to_mask(unsigned pin) { - pin -= PIN_BASE; return 1 << (pin % 32); } @@ -275,8 +273,9 @@ static u32 backups[MAX_GPIO_BANKS]; static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { - unsigned mask = pin_to_mask(d->irq); - unsigned bank = (d->irq - PIN_BASE) / 32; + unsigned pin = irq_to_gpio(d->irq); + unsigned mask = pin_to_mask(pin); + unsigned bank = pin / 32; if (unlikely(bank >= MAX_GPIO_BANKS)) return -EINVAL; @@ -345,8 +344,9 @@ void at91_gpio_resume(void) static void gpio_irq_mask(struct irq_data *d) { - void __iomem *pio = pin_to_controller(d->irq); - unsigned mask = pin_to_mask(d->irq); + unsigned pin = irq_to_gpio(d->irq); + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); if (pio) __raw_writel(mask, pio + PIO_IDR); @@ -354,8 +354,9 @@ static void gpio_irq_mask(struct irq_data *d) static void gpio_irq_unmask(struct irq_data *d) { - void __iomem *pio = pin_to_controller(d->irq); - unsigned mask = pin_to_mask(d->irq); + unsigned pin = irq_to_gpio(d->irq); + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); if (pio) __raw_writel(mask, pio + PIO_IER); @@ -383,7 +384,7 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - unsigned pin; + unsigned irq_pin; struct irq_data *idata = irq_desc_get_irq_data(desc); struct irq_chip *chip = irq_data_get_irq_chip(idata); struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); @@ -406,12 +407,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) continue; } - pin = at91_gpio->chip.base; + irq_pin = gpio_to_irq(at91_gpio->chip.base); while (isr) { if (isr & 1) - generic_handle_irq(pin); - pin++; + generic_handle_irq(irq_pin); + irq_pin++; isr >>= 1; } } @@ -439,7 +440,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused) seq_printf(s, "%i:\t", j); for (bank = 0; bank < gpio_banks; bank++) { - unsigned pin = PIN_BASE + (32 * bank) + j; + unsigned pin = (32 * bank) + j; void __iomem *pio = pin_to_controller(pin); unsigned mask = pin_to_mask(pin); @@ -492,10 +493,10 @@ static struct lock_class_key gpio_lock_class; */ void __init at91_gpio_irq_setup(void) { - unsigned pioc, pin; + unsigned pioc, irq = gpio_to_irq(0); struct at91_gpio_chip *this, *prev; - for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL; + for (pioc = 0, this = gpio_chip, prev = NULL; pioc++ < gpio_banks; prev = this, this++) { unsigned id = this->id; @@ -503,16 +504,17 @@ void __init at91_gpio_irq_setup(void) __raw_writel(~0, this->regbase + PIO_IDR); - for (i = 0, pin = this->chip.base; i < 32; i++, pin++) { - irq_set_lockdep_class(pin, &gpio_lock_class); + for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32; + i++, irq++) { + irq_set_lockdep_class(irq, &gpio_lock_class); /* * Can use the "simple" and not "edge" handler since it's * shorter, and the AIC handles interrupts sanely. */ - irq_set_chip_and_handler(pin, &gpio_irqchip, + irq_set_chip_and_handler(irq, &gpio_irqchip, handle_simple_irq); - set_irq_flags(pin, IRQF_VALID); + set_irq_flags(irq, IRQF_VALID); } /* The toplevel handler handles one bank of GPIOs, except @@ -525,7 +527,7 @@ void __init at91_gpio_irq_setup(void) irq_set_chip_data(id, this); irq_set_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); + pr_info("AT91: %d gpio irqs in %d banks\n", irq, gpio_banks); } /* gpiolib support */ @@ -614,7 +616,7 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) at91_gpio = &gpio_chip[i]; at91_gpio->id = data[i].id; - at91_gpio->chip.base = PIN_BASE + i * 32; + at91_gpio->chip.base = i * 32; at91_gpio->regbase = ioremap(data[i].regbase, 512); if (!at91_gpio->regbase) { diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index 2b9a1f5..e3fd225 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -16,177 +16,175 @@ #include #include -#define PIN_BASE NR_AIC_IRQS - #define MAX_GPIO_BANKS 5 -#define NR_BUILTIN_GPIO (PIN_BASE + (MAX_GPIO_BANKS * 32)) +#define NR_BUILTIN_GPIO (MAX_GPIO_BANKS * 32) /* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ -#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) -#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) -#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) -#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) -#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) -#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) -#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) -#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) -#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) -#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) -#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) -#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) -#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) -#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) -#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) -#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) -#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) -#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) -#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) -#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) -#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) -#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) -#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) -#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) -#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) -#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) -#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) -#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) -#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) -#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) -#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) -#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) - -#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) -#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) -#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) -#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) -#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) -#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) -#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) -#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) -#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) -#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) -#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) -#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) -#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) -#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) -#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) -#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) -#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) -#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) -#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) -#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) -#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) -#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) -#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) -#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) -#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) -#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) -#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) -#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) -#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) -#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) -#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) -#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) - -#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) -#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) -#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) -#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) -#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) -#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) -#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) -#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) -#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) -#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) -#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) -#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) -#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) -#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) -#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) -#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) -#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) -#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) -#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) -#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) -#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) -#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) -#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) -#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) -#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) -#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) -#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) -#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) -#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) -#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) -#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) -#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) - -#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) -#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) -#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) -#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) -#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) -#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) -#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) -#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) -#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) -#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) -#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) -#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) -#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) -#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) -#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) -#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) -#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) -#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) -#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) -#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) -#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) -#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) -#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) -#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) -#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) -#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) -#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) -#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) -#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) -#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) -#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) -#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) - -#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) -#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) -#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) -#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) -#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) -#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) -#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) -#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) -#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) -#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) -#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) -#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) -#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) -#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) -#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) -#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) -#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) -#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) -#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) -#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) -#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) -#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) -#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) -#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) -#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) -#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) -#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) -#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) -#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) -#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) -#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) -#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) +#define AT91_PIN_PA0 (0x00 + 0) +#define AT91_PIN_PA1 (0x00 + 1) +#define AT91_PIN_PA2 (0x00 + 2) +#define AT91_PIN_PA3 (0x00 + 3) +#define AT91_PIN_PA4 (0x00 + 4) +#define AT91_PIN_PA5 (0x00 + 5) +#define AT91_PIN_PA6 (0x00 + 6) +#define AT91_PIN_PA7 (0x00 + 7) +#define AT91_PIN_PA8 (0x00 + 8) +#define AT91_PIN_PA9 (0x00 + 9) +#define AT91_PIN_PA10 (0x00 + 10) +#define AT91_PIN_PA11 (0x00 + 11) +#define AT91_PIN_PA12 (0x00 + 12) +#define AT91_PIN_PA13 (0x00 + 13) +#define AT91_PIN_PA14 (0x00 + 14) +#define AT91_PIN_PA15 (0x00 + 15) +#define AT91_PIN_PA16 (0x00 + 16) +#define AT91_PIN_PA17 (0x00 + 17) +#define AT91_PIN_PA18 (0x00 + 18) +#define AT91_PIN_PA19 (0x00 + 19) +#define AT91_PIN_PA20 (0x00 + 20) +#define AT91_PIN_PA21 (0x00 + 21) +#define AT91_PIN_PA22 (0x00 + 22) +#define AT91_PIN_PA23 (0x00 + 23) +#define AT91_PIN_PA24 (0x00 + 24) +#define AT91_PIN_PA25 (0x00 + 25) +#define AT91_PIN_PA26 (0x00 + 26) +#define AT91_PIN_PA27 (0x00 + 27) +#define AT91_PIN_PA28 (0x00 + 28) +#define AT91_PIN_PA29 (0x00 + 29) +#define AT91_PIN_PA30 (0x00 + 30) +#define AT91_PIN_PA31 (0x00 + 31) + +#define AT91_PIN_PB0 (0x20 + 0) +#define AT91_PIN_PB1 (0x20 + 1) +#define AT91_PIN_PB2 (0x20 + 2) +#define AT91_PIN_PB3 (0x20 + 3) +#define AT91_PIN_PB4 (0x20 + 4) +#define AT91_PIN_PB5 (0x20 + 5) +#define AT91_PIN_PB6 (0x20 + 6) +#define AT91_PIN_PB7 (0x20 + 7) +#define AT91_PIN_PB8 (0x20 + 8) +#define AT91_PIN_PB9 (0x20 + 9) +#define AT91_PIN_PB10 (0x20 + 10) +#define AT91_PIN_PB11 (0x20 + 11) +#define AT91_PIN_PB12 (0x20 + 12) +#define AT91_PIN_PB13 (0x20 + 13) +#define AT91_PIN_PB14 (0x20 + 14) +#define AT91_PIN_PB15 (0x20 + 15) +#define AT91_PIN_PB16 (0x20 + 16) +#define AT91_PIN_PB17 (0x20 + 17) +#define AT91_PIN_PB18 (0x20 + 18) +#define AT91_PIN_PB19 (0x20 + 19) +#define AT91_PIN_PB20 (0x20 + 20) +#define AT91_PIN_PB21 (0x20 + 21) +#define AT91_PIN_PB22 (0x20 + 22) +#define AT91_PIN_PB23 (0x20 + 23) +#define AT91_PIN_PB24 (0x20 + 24) +#define AT91_PIN_PB25 (0x20 + 25) +#define AT91_PIN_PB26 (0x20 + 26) +#define AT91_PIN_PB27 (0x20 + 27) +#define AT91_PIN_PB28 (0x20 + 28) +#define AT91_PIN_PB29 (0x20 + 29) +#define AT91_PIN_PB30 (0x20 + 30) +#define AT91_PIN_PB31 (0x20 + 31) + +#define AT91_PIN_PC0 (0x40 + 0) +#define AT91_PIN_PC1 (0x40 + 1) +#define AT91_PIN_PC2 (0x40 + 2) +#define AT91_PIN_PC3 (0x40 + 3) +#define AT91_PIN_PC4 (0x40 + 4) +#define AT91_PIN_PC5 (0x40 + 5) +#define AT91_PIN_PC6 (0x40 + 6) +#define AT91_PIN_PC7 (0x40 + 7) +#define AT91_PIN_PC8 (0x40 + 8) +#define AT91_PIN_PC9 (0x40 + 9) +#define AT91_PIN_PC10 (0x40 + 10) +#define AT91_PIN_PC11 (0x40 + 11) +#define AT91_PIN_PC12 (0x40 + 12) +#define AT91_PIN_PC13 (0x40 + 13) +#define AT91_PIN_PC14 (0x40 + 14) +#define AT91_PIN_PC15 (0x40 + 15) +#define AT91_PIN_PC16 (0x40 + 16) +#define AT91_PIN_PC17 (0x40 + 17) +#define AT91_PIN_PC18 (0x40 + 18) +#define AT91_PIN_PC19 (0x40 + 19) +#define AT91_PIN_PC20 (0x40 + 20) +#define AT91_PIN_PC21 (0x40 + 21) +#define AT91_PIN_PC22 (0x40 + 22) +#define AT91_PIN_PC23 (0x40 + 23) +#define AT91_PIN_PC24 (0x40 + 24) +#define AT91_PIN_PC25 (0x40 + 25) +#define AT91_PIN_PC26 (0x40 + 26) +#define AT91_PIN_PC27 (0x40 + 27) +#define AT91_PIN_PC28 (0x40 + 28) +#define AT91_PIN_PC29 (0x40 + 29) +#define AT91_PIN_PC30 (0x40 + 30) +#define AT91_PIN_PC31 (0x40 + 31) + +#define AT91_PIN_PD0 (0x60 + 0) +#define AT91_PIN_PD1 (0x60 + 1) +#define AT91_PIN_PD2 (0x60 + 2) +#define AT91_PIN_PD3 (0x60 + 3) +#define AT91_PIN_PD4 (0x60 + 4) +#define AT91_PIN_PD5 (0x60 + 5) +#define AT91_PIN_PD6 (0x60 + 6) +#define AT91_PIN_PD7 (0x60 + 7) +#define AT91_PIN_PD8 (0x60 + 8) +#define AT91_PIN_PD9 (0x60 + 9) +#define AT91_PIN_PD10 (0x60 + 10) +#define AT91_PIN_PD11 (0x60 + 11) +#define AT91_PIN_PD12 (0x60 + 12) +#define AT91_PIN_PD13 (0x60 + 13) +#define AT91_PIN_PD14 (0x60 + 14) +#define AT91_PIN_PD15 (0x60 + 15) +#define AT91_PIN_PD16 (0x60 + 16) +#define AT91_PIN_PD17 (0x60 + 17) +#define AT91_PIN_PD18 (0x60 + 18) +#define AT91_PIN_PD19 (0x60 + 19) +#define AT91_PIN_PD20 (0x60 + 20) +#define AT91_PIN_PD21 (0x60 + 21) +#define AT91_PIN_PD22 (0x60 + 22) +#define AT91_PIN_PD23 (0x60 + 23) +#define AT91_PIN_PD24 (0x60 + 24) +#define AT91_PIN_PD25 (0x60 + 25) +#define AT91_PIN_PD26 (0x60 + 26) +#define AT91_PIN_PD27 (0x60 + 27) +#define AT91_PIN_PD28 (0x60 + 28) +#define AT91_PIN_PD29 (0x60 + 29) +#define AT91_PIN_PD30 (0x60 + 30) +#define AT91_PIN_PD31 (0x60 + 31) + +#define AT91_PIN_PE0 (0x80 + 0) +#define AT91_PIN_PE1 (0x80 + 1) +#define AT91_PIN_PE2 (0x80 + 2) +#define AT91_PIN_PE3 (0x80 + 3) +#define AT91_PIN_PE4 (0x80 + 4) +#define AT91_PIN_PE5 (0x80 + 5) +#define AT91_PIN_PE6 (0x80 + 6) +#define AT91_PIN_PE7 (0x80 + 7) +#define AT91_PIN_PE8 (0x80 + 8) +#define AT91_PIN_PE9 (0x80 + 9) +#define AT91_PIN_PE10 (0x80 + 10) +#define AT91_PIN_PE11 (0x80 + 11) +#define AT91_PIN_PE12 (0x80 + 12) +#define AT91_PIN_PE13 (0x80 + 13) +#define AT91_PIN_PE14 (0x80 + 14) +#define AT91_PIN_PE15 (0x80 + 15) +#define AT91_PIN_PE16 (0x80 + 16) +#define AT91_PIN_PE17 (0x80 + 17) +#define AT91_PIN_PE18 (0x80 + 18) +#define AT91_PIN_PE19 (0x80 + 19) +#define AT91_PIN_PE20 (0x80 + 20) +#define AT91_PIN_PE21 (0x80 + 21) +#define AT91_PIN_PE22 (0x80 + 22) +#define AT91_PIN_PE23 (0x80 + 23) +#define AT91_PIN_PE24 (0x80 + 24) +#define AT91_PIN_PE25 (0x80 + 25) +#define AT91_PIN_PE26 (0x80 + 26) +#define AT91_PIN_PE27 (0x80 + 27) +#define AT91_PIN_PE28 (0x80 + 28) +#define AT91_PIN_PE29 (0x80 + 29) +#define AT91_PIN_PE30 (0x80 + 30) +#define AT91_PIN_PE31 (0x80 + 31) #ifndef __ASSEMBLY__ /* setup setup routines, called from board init or driver probe() */ @@ -215,8 +213,8 @@ extern void at91_gpio_resume(void); #include -#define gpio_to_irq(gpio) (gpio) -#define irq_to_gpio(irq) (irq) +#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS) +#define irq_to_gpio(irq) (irq - NR_AIC_IRQS) #endif /* __ASSEMBLY__ */ -- cgit v0.10.2 From 1e81799bd62d42bb6d5ec5c74e9b022e7d44f11c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 03:04:30 +0800 Subject: ARM: at91/gpio: fix display of number of irq setuped Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index d000448..74d6783 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -527,7 +527,7 @@ void __init at91_gpio_irq_setup(void) irq_set_chip_data(id, this); irq_set_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", irq, gpio_banks); + pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks); } /* gpiolib support */ -- cgit v0.10.2 From 61b3875382bc335423ccd7cbf2736c70175a54dd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 28 Nov 2011 12:20:53 +0100 Subject: ARM: 7179/1: nomadik: localize cpu-8815 header The symbols from cpu-8815.c were being broadcast across the entire kernel but are only really used locally in mach-nomadik so let's localize them. Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 0cbb74c..4518050 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -34,6 +34,8 @@ #include #include +#include "cpu-8815.h" + /* Initial value for SRC control register: all timers use MXTAL/8 source */ #define SRC_CR_INIT_MASK 0x00007fff #define SRC_CR_INIT_VAL 0x2aaa8000 diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index dc67717..c087ea9 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -32,6 +32,7 @@ #include #include "clock.h" +#include "cpu-8815.h" #define __MEM_4K_RESOURCE(x) \ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} diff --git a/arch/arm/mach-nomadik/cpu-8815.h b/arch/arm/mach-nomadik/cpu-8815.h new file mode 100644 index 0000000..e041794 --- /dev/null +++ b/arch/arm/mach-nomadik/cpu-8815.h @@ -0,0 +1,3 @@ +extern void cpu8815_map_io(void); +extern void cpu8815_platform_init(void); +extern void cpu8815_init_irq(void); diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h index b7897ed..bcaeaf4 100644 --- a/arch/arm/mach-nomadik/include/mach/setup.h +++ b/arch/arm/mach-nomadik/include/mach/setup.h @@ -12,9 +12,6 @@ #ifdef CONFIG_NOMADIK_8815 -extern void cpu8815_map_io(void); -extern void cpu8815_platform_init(void); -extern void cpu8815_init_irq(void); extern void nmdk_timer_init(void); #endif /* NOMADIK_8815 */ -- cgit v0.10.2 From 7fdcf13b292e8b2e38e42de24be2503e37b2cf97 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 1 Dec 2011 14:00:15 -0500 Subject: SUNRPC: Fix the execution time statistics in the face of RPC restarts If the rpc_task gets restarted, then we want to ensure that we don't double-count the execution time statistics, timeout data, etc. Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index d12ffa5..00a1a2a 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -590,6 +590,27 @@ void rpc_prepare_task(struct rpc_task *task) task->tk_ops->rpc_call_prepare(task, task->tk_calldata); } +static void +rpc_init_task_statistics(struct rpc_task *task) +{ + /* Initialize retry counters */ + task->tk_garb_retry = 2; + task->tk_cred_retry = 2; + task->tk_rebind_retry = 2; + + /* starting timestamp */ + task->tk_start = ktime_get(); +} + +static void +rpc_reset_task_statistics(struct rpc_task *task) +{ + task->tk_timeouts = 0; + task->tk_flags &= ~(RPC_CALL_MAJORSEEN|RPC_TASK_KILLED|RPC_TASK_SENT); + + rpc_init_task_statistics(task); +} + /* * Helper that calls task->tk_ops->rpc_call_done if it exists */ @@ -602,6 +623,7 @@ void rpc_exit_task(struct rpc_task *task) WARN_ON(RPC_ASSASSINATED(task)); /* Always release the RPC slot and buffer memory */ xprt_release(task); + rpc_reset_task_statistics(task); } } } @@ -804,11 +826,6 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta task->tk_calldata = task_setup_data->callback_data; INIT_LIST_HEAD(&task->tk_task); - /* Initialize retry counters */ - task->tk_garb_retry = 2; - task->tk_cred_retry = 2; - task->tk_rebind_retry = 2; - task->tk_priority = task_setup_data->priority - RPC_PRIORITY_LOW; task->tk_owner = current->tgid; @@ -818,8 +835,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta if (task->tk_ops->rpc_call_prepare != NULL) task->tk_action = rpc_prepare_task; - /* starting timestamp */ - task->tk_start = ktime_get(); + rpc_init_task_statistics(task); dprintk("RPC: new task initialized, procpid %u\n", task_pid_nr(current)); -- cgit v0.10.2 From c25573b5134294c0be82bfaecc6d08136835b271 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 1 Dec 2011 14:16:17 -0500 Subject: SUNRPC: Ensure we always bump the backlog queue in xprt_free_slot Whenever we free a slot, we know that the resulting xprt->num_reqs will be less than xprt->max_reqs, so we know that we can release at least one backlogged rpc_task. Signed-off-by: Trond Myklebust Cc: stable@vger.kernel.org [>=3.1] diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index f4385e4..c64c0ef 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -995,13 +995,11 @@ out_init_req: static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) { - if (xprt_dynamic_free_slot(xprt, req)) - return; - - memset(req, 0, sizeof(*req)); /* mark unused */ - spin_lock(&xprt->reserve_lock); - list_add(&req->rq_list, &xprt->free); + if (!xprt_dynamic_free_slot(xprt, req)) { + memset(req, 0, sizeof(*req)); /* mark unused */ + list_add(&req->rq_list, &xprt->free); + } rpc_wake_up_next(&xprt->backlog); spin_unlock(&xprt->reserve_lock); } -- cgit v0.10.2 From 4f38e4aadcca319650c0de31edf7193d7c384de2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 1 Dec 2011 16:31:34 -0500 Subject: NFSv4: Don't error if we handled it in nfs4_recovery_handle_error If we handled an error condition, then nfs4_recovery_handle_error should return '0' so that the state recovery thread can continue. Also ensure that nfs4_check_lease() continues to abort if we haven't got any credentials by having it return ENOKEY (which is not handled). Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 39914be..1da95e3 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1350,12 +1350,14 @@ static void nfs4_warn_keyexpired(const char *s) static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) { switch (error) { + case 0: + break; case -NFS4ERR_CB_PATH_DOWN: nfs_handle_cb_pathdown(clp); - return 0; + break; case -NFS4ERR_NO_GRACE: nfs4_state_end_reclaim_reboot(clp); - return 0; + break; case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_LEASE_MOVED: set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); @@ -1375,13 +1377,15 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) case -NFS4ERR_SEQ_MISORDERED: set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); /* Zero session reset errors */ - return 0; + break; case -EKEYEXPIRED: /* Nothing we can do */ nfs4_warn_keyexpired(clp->cl_hostname); - return 0; + break; + default: + return error; } - return error; + return 0; } static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) @@ -1428,7 +1432,7 @@ static int nfs4_check_lease(struct nfs_client *clp) struct rpc_cred *cred; const struct nfs4_state_maintenance_ops *ops = clp->cl_mvops->state_renewal_ops; - int status = -NFS4ERR_EXPIRED; + int status; /* Is the client already known to have an expired lease? */ if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) @@ -1438,6 +1442,7 @@ static int nfs4_check_lease(struct nfs_client *clp) spin_unlock(&clp->cl_lock); if (cred == NULL) { cred = nfs4_get_setclientid_cred(clp); + status = -ENOKEY; if (cred == NULL) goto out; } @@ -1662,10 +1667,10 @@ static void nfs4_state_manager(struct nfs_client *clp) if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { status = nfs4_check_lease(clp); + if (status < 0) + goto out_error; if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) continue; - if (status < 0 && status != -NFS4ERR_CB_PATH_DOWN) - goto out_error; } /* Initialize or reset the session */ -- cgit v0.10.2 From 111d489f0fb431f4ae85d96851fbf8d3248c09d8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 1 Dec 2011 16:37:42 -0500 Subject: NFSv4.1: Ensure that we handle _all_ SEQUENCE status bits. Currently, the code assumes that the SEQUENCE status bits are mutually exclusive. They are not... Signed-off-by: Trond Myklebust Cc: stable@vger.kernel.org [>= 2.6.34] diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 1da95e3..da8d73e 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1530,16 +1530,16 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) { if (!flags) return; - else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) + if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) nfs41_handle_server_reboot(clp); - else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED | + if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED | SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED | SEQ4_STATUS_ADMIN_STATE_REVOKED | SEQ4_STATUS_LEASE_MOVED)) nfs41_handle_state_revoked(clp); - else if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED) + if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED) nfs41_handle_recallable_state_revoked(clp); - else if (flags & (SEQ4_STATUS_CB_PATH_DOWN | + if (flags & (SEQ4_STATUS_CB_PATH_DOWN | SEQ4_STATUS_BACKCHANNEL_FAULT | SEQ4_STATUS_CB_PATH_DOWN_SESSION)) nfs41_handle_cb_path_down(clp); -- cgit v0.10.2 From 629be5f275ddf0791614f8cbdafc11bde4247850 Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Tue, 22 Nov 2011 15:39:11 +1100 Subject: mtd: ndfc: fix typo in structure dereference In commit 9d7948c50055e74b693ce9e99a709b2e5bbc1942 (mtd: ndfc: use ofpart through generic parsing) we dereference a non pointer type causing the following compiler error: drivers/mtd/nand/ndfc.c: In function 'ndfc_chip_init': drivers/mtd/nand/ndfc.c:191: error: invalid type argument of '->' (have 'struct mtd_part_parser_data') Fix that. Signed-off-by: Tony Breeds Acked-by: Dmitry Eremin-Solenikov Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index ee17139..f8aacf4 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -188,7 +188,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, if (!flash_np) return -ENODEV; - ppdata->of_node = flash_np; + ppdata.of_node = flash_np; ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), flash_np->name); if (!ndfc->mtd.name) { -- cgit v0.10.2 From e13c692b1f97a6a4f753695b4f28b7f10e5d79ae Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Sat, 12 Nov 2011 20:36:02 +0530 Subject: ARM: davinci: vpif: move code to driver core header from platform Move vpif related definitions for capture and display drivers from dm646x platform header file to vpif_types.h inside the driver as these definitions are related to driver code rather than the platform or board. This enables reusing this IP across platforms. Signed-off-by: Manjunath Hadli Acked-by: Mauro Carvalho Chehab Signed-off-by: Sekhar Nori diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index 2a00fe5..a8ee6c9 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -16,6 +16,7 @@ #include #include #include +#include #define DM646X_EMAC_BASE (0x01C80000) #define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) @@ -34,58 +35,6 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv); void dm646x_video_init(void); -enum vpif_if_type { - VPIF_IF_BT656, - VPIF_IF_BT1120, - VPIF_IF_RAW_BAYER -}; - -struct vpif_interface { - enum vpif_if_type if_type; - unsigned hd_pol:1; - unsigned vd_pol:1; - unsigned fid_pol:1; -}; - -struct vpif_subdev_info { - const char *name; - struct i2c_board_info board_info; - u32 input; - u32 output; - unsigned can_route:1; - struct vpif_interface vpif_if; -}; - -struct vpif_display_config { - int (*set_clock)(int, int); - struct vpif_subdev_info *subdevinfo; - int subdev_count; - const char **output; - int output_count; - const char *card_name; -}; - -struct vpif_input { - struct v4l2_input input; - const char *subdev_name; -}; - -#define VPIF_CAPTURE_MAX_CHANNELS 2 - -struct vpif_capture_chan_config { - const struct vpif_input *inputs; - int input_count; -}; - -struct vpif_capture_config { - int (*setup_input_channel_mode)(int); - int (*setup_input_path)(int, const char *); - struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS]; - struct vpif_subdev_info *subdev_info; - int subdev_count; - const char *card_name; -}; - void dm646x_setup_vpif(struct vpif_display_config *, struct vpif_capture_config *); diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index 10550bd..25036cb 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h @@ -20,6 +20,7 @@ #include #include #include +#include /* Maximum channel allowed */ #define VPIF_NUM_CHANNELS (4) diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h index 064550f..a693d4e 100644 --- a/drivers/media/video/davinci/vpif_capture.h +++ b/drivers/media/video/davinci/vpif_capture.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "vpif.h" diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h index 5d1936d..56879d1 100644 --- a/drivers/media/video/davinci/vpif_display.h +++ b/drivers/media/video/davinci/vpif_display.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "vpif.h" diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h new file mode 100644 index 0000000..9929b05 --- /dev/null +++ b/include/media/davinci/vpif_types.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2011 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _VPIF_TYPES_H +#define _VPIF_TYPES_H + +#define VPIF_CAPTURE_MAX_CHANNELS 2 + +enum vpif_if_type { + VPIF_IF_BT656, + VPIF_IF_BT1120, + VPIF_IF_RAW_BAYER +}; + +struct vpif_interface { + enum vpif_if_type if_type; + unsigned hd_pol:1; + unsigned vd_pol:1; + unsigned fid_pol:1; +}; + +struct vpif_subdev_info { + const char *name; + struct i2c_board_info board_info; + u32 input; + u32 output; + unsigned can_route:1; + struct vpif_interface vpif_if; +}; + +struct vpif_display_config { + int (*set_clock)(int, int); + struct vpif_subdev_info *subdevinfo; + int subdev_count; + const char **output; + int output_count; + const char *card_name; +}; + +struct vpif_input { + struct v4l2_input input; + const char *subdev_name; +}; + +struct vpif_capture_chan_config { + const struct vpif_input *inputs; + int input_count; +}; + +struct vpif_capture_config { + int (*setup_input_channel_mode)(int); + int (*setup_input_path)(int, const char *); + struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS]; + struct vpif_subdev_info *subdev_info; + int subdev_count; + const char *card_name; +}; +#endif /* _VPIF_TYPES_H */ -- cgit v0.10.2 From df16c86a56595d1c28e58532ec25dd612c39c6c7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Nov 2011 15:57:06 +0100 Subject: mtd: gpmi: add missing include 'module.h' Fixes: drivers/mtd/nand/gpmi-nand/gpmi-nand.c: In function 'gpmi_nfc_init': drivers/mtd/nand/gpmi-nand/gpmi-nand.c:1475:16: error: 'THIS_MODULE' undeclared (first use in this function) drivers/mtd/nand/gpmi-nand/gpmi-nand.c:1475:16: note: each undeclared identifier is reported only once for each function it appears in drivers/mtd/nand/gpmi-nand/gpmi-nand.c: At top level: drivers/mtd/nand/gpmi-nand/gpmi-nand.c:1617:15: error: expected declaration specifiers or '...' before string constant drivers/mtd/nand/gpmi-nand/gpmi-nand.c:1617:1: warning: data definition has no type or storage class drivers/mtd/nand/gpmi-nand/gpmi-nand.c:1617:1: warning: type defaults to 'int' in declaration of 'MODULE_AUTHOR' and some more... Signed-off-by: Wolfram Sang Acked-by: Huang Shijie Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 071b634..493ec2f 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -21,9 +21,9 @@ #include #include #include +#include #include #include - #include "gpmi-nand.h" /* add our owner bbt descriptor */ -- cgit v0.10.2 From bbef98ab0f019f1b0c25c1acdf1683c68933d41b Mon Sep 17 00:00:00 2001 From: Ram Pai Date: Sun, 6 Nov 2011 10:33:10 +0800 Subject: PCI: defer enablement of SRIOV BARS All the PCI BARs of a device are enabled when the device is enabled using pci_enable_device(). This unnecessarily enables SRIOV BARs of the device. On some platforms, which do not support SRIOV as yet, the pci_enable_device() fails to enable the device if its SRIOV BARs are not allocated resources correctly. The following patch fixes the above problem. The SRIOV BARs are now enabled when IOV capability of the device is enabled in sriov_enable(). NOTE: Note, there is subtle change in the pci_enable_device() API. Any driver that depends on SRIOV BARS to be enabled in pci_enable_device() can fail. The patch has been touch tested on power and x86 platform. Tested-by: Michael Wang Signed-off-by: Ram Pai Signed-off-by: Jesse Barnes diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index b82c155..1969a3e 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -283,6 +283,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) struct resource *res; struct pci_dev *pdev; struct pci_sriov *iov = dev->sriov; + int bars = 0; if (!nr_virtfn) return 0; @@ -307,6 +308,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) nres = 0; for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { + bars |= (1 << (i + PCI_IOV_RESOURCES)); res = dev->resource + PCI_IOV_RESOURCES + i; if (res->parent) nres++; @@ -324,6 +326,11 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) return -ENOMEM; } + if (pci_enable_resources(dev, bars)) { + dev_err(&dev->dev, "SR-IOV: IOV BARS not allocated\n"); + return -ENOMEM; + } + if (iov->link != dev->devfn) { pdev = pci_get_slot(dev->bus, iov->link); if (!pdev) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6f45a73..4788413 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1126,7 +1126,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, if (atomic_add_return(1, &dev->enable_cnt) > 1) return 0; /* already enabled */ - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + for (i = 0; i < PCI_ROM_RESOURCE; i++) if (dev->resource[i].flags & flags) bars |= (1 << i); -- cgit v0.10.2 From 8c4519456713628cbb457c77bf06684aace67f69 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 29 Nov 2011 19:20:23 +0000 Subject: PCI: fix ats compile failure I get this compile failure on parisc: drivers/pci/ats.c: In function 'ats_alloc_one': drivers/pci/ats.c:29: error: implicit declaration of function 'kzalloc' drivers/pci/ats.c:29: warning: assignment makes pointer from integer without a cast drivers/pci/ats.c: In function 'ats_free_one': drivers/pci/ats.c:45: error: implicit declaration of function 'kfree' Because ats.c is missing linux/slab.h as an include. This patch fixes it Signed-off-by: James Bottomley Signed-off-by: Jesse Barnes diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index 7ec56fb..b0dd08e 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "pci.h" -- cgit v0.10.2 From 75fc2d3797c47f5f70ca71c41c342c352845cd06 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 5 Dec 2011 17:27:08 +0100 Subject: MAINTAINERS: Update tip.git related git trees Update the six major subsystem trees hosted in the tip tree to the new location (or add the location if it was missing). Acked-by: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-w0z98as3kwy9bo1o3k2mmuvi@git.kernel.org Signed-off-by: Ingo Molnar diff --git a/MAINTAINERS b/MAINTAINERS index 4475602..9706a21 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3118,6 +3118,7 @@ F: include/linux/hid* HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS M: Thomas Gleixner +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Maintained F: Documentation/timers/ F: kernel/hrtimer.c @@ -3627,7 +3628,7 @@ F: net/irda/ IRQ SUBSYSTEM M: Thomas Gleixner S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core F: kernel/irq/ ISAPNP @@ -4115,7 +4116,7 @@ F: drivers/hwmon/lm90.c LOCKDEP AND LOCKSTAT M: Peter Zijlstra M: Ingo Molnar -T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/locking S: Maintained F: Documentation/lockdep*.txt F: Documentation/lockstat.txt @@ -5102,6 +5103,7 @@ M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar M: Arnaldo Carvalho de Melo +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Supported F: kernel/events/* F: include/linux/perf_event.h @@ -5181,6 +5183,7 @@ F: drivers/scsi/pm8001/ POSIX CLOCKS and TIMERS M: Thomas Gleixner +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Supported F: fs/timerfd.c F: include/linux/timer* @@ -5696,6 +5699,7 @@ F: drivers/dma/dw_dmac.c TIMEKEEPING, NTP M: John Stultz M: Thomas Gleixner +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Supported F: include/linux/clocksource.h F: include/linux/time.h @@ -5720,6 +5724,7 @@ F: drivers/watchdog/sc1200wdt.c SCHEDULER M: Ingo Molnar M: Peter Zijlstra +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core S: Maintained F: kernel/sched* F: include/linux/sched.h @@ -6647,7 +6652,7 @@ TRACING M: Steven Rostedt M: Frederic Weisbecker M: Ingo Molnar -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perf/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Maintained F: Documentation/trace/ftrace.txt F: arch/*/*/*/ftrace.h @@ -7397,7 +7402,7 @@ M: Thomas Gleixner M: Ingo Molnar M: "H. Peter Anvin" M: x86@kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core S: Maintained F: Documentation/x86/ F: arch/x86/ -- cgit v0.10.2 From 023bfa3dc7ec8316a499d247c2734a54a9763708 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 25 Oct 2011 12:42:33 +0100 Subject: ARM: 7140/1: remove NR_IRQS dependency for ARM-specific HARDIRQ_BITS definition As a first step towards removing NR_IRQS, remove the ARM customization of HARDIRQ_BITS based on NR_IRQS. The generic code in already has a default value of 10 for HARDIRQ_BITS which is the max used on ARM, so let's just remove the NR_IRQS based customization and use the generic default. Signed-off-by: Kevin Hilman Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index ddf07a9..436e60b 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -27,23 +27,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu); #define arch_irq_stat_cpu smp_irq_stat_cpu -#if NR_IRQS > 512 -#define HARDIRQ_BITS 10 -#elif NR_IRQS > 256 -#define HARDIRQ_BITS 9 -#else -#define HARDIRQ_BITS 8 -#endif - -/* - * The hardirq mask has to be large enough to have space - * for potentially all IRQ sources in the system nesting - * on a single CPU: - */ -#if (1 << HARDIRQ_BITS) < NR_IRQS -# error HARDIRQ_BITS is too low! -#endif - #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 #endif /* __ASM_HARDIRQ_H */ -- cgit v0.10.2 From d22759ed5680055fdecbdcf6644dbc8a467ab801 Mon Sep 17 00:00:00 2001 From: "Jon Medhurst (Tixy)" Date: Tue, 6 Dec 2011 09:59:38 +0100 Subject: ARM: 7193/1: Fix machine_is_xxx() naming for eSata SheevaPlug and QNAP TS-209 The eSata SheevaPlug and QNAP TS-209 devices were removed from mach-types due to naming mismatches between machine_is_xxx(), CONFIG_XXX and MACH_TYPE_XXX. This patch fixes those mismatches and adds the devices back into mach-types. Acked-by: Nicolas Pitre Signed-off-by: Jon Medhurst Signed-off-by: Russell King diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c index 8b102d6..046eeb6 100644 --- a/arch/arm/mach-kirkwood/sheevaplug-setup.c +++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c @@ -107,7 +107,7 @@ static void __init sheevaplug_init(void) kirkwood_init(); /* setup gpio pin select */ - if (machine_is_sheeva_esata()) + if (machine_is_esata_sheevaplug()) kirkwood_mpp_conf(sheeva_esata_mpp_config); else kirkwood_mpp_conf(sheevaplug_mpp_config); @@ -123,11 +123,11 @@ static void __init sheevaplug_init(void) kirkwood_ge00_init(&sheevaplug_ge00_data); /* honor lower power consumption for plugs with out eSATA */ - if (machine_is_sheeva_esata()) + if (machine_is_esata_sheevaplug()) kirkwood_sata_init(&sheeva_esata_sata_data); /* enable sd wp and sd cd on plugs with esata */ - if (machine_is_sheeva_esata()) + if (machine_is_esata_sheevaplug()) kirkwood_sdio_init(&sheeva_esata_mvsdio_data); else kirkwood_sdio_init(&sheevaplug_mvsdio_data); diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 31e51f9..fbf66ea 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -178,7 +178,7 @@ static struct hw_pci qnap_ts209_pci __initdata = { static int __init qnap_ts209_pci_init(void) { - if (machine_is_ts_x09()) + if (machine_is_ts209()) pci_common_init(&qnap_ts209_pci); return 0; diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index ccbe16f..9e66ebc 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -269,7 +269,7 @@ dns323 MACH_DNS323 DNS323 1542 omap3_beagle MACH_OMAP3_BEAGLE OMAP3_BEAGLE 1546 nokia_n810 MACH_NOKIA_N810 NOKIA_N810 1548 pcm038 MACH_PCM038 PCM038 1551 -ts_x09 MACH_TS209 TS209 1565 +ts209 MACH_TS209 TS209 1565 at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566 mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574 vision_ep9307 MACH_VISION_EP9307 VISION_EP9307 1578 @@ -459,7 +459,7 @@ guruplug MACH_GURUPLUG GURUPLUG 2659 spear310 MACH_SPEAR310 SPEAR310 2660 spear320 MACH_SPEAR320 SPEAR320 2661 aquila MACH_AQUILA AQUILA 2676 -sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678 +esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678 msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679 ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683 terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697 -- cgit v0.10.2 From 7dbaa466780a754154531b44c2086f6618cee3a8 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 22 Nov 2011 04:01:07 +0100 Subject: ARM: 7169/1: topdown mmap support Similar to other architectures, this adds topdown mmap support in user process address space allocation policy. This allows mmap sizes greater than 2GB. This support is largely copied from MIPS and the generic implementations. The address space randomization is moved into arch_pick_mmap_layout. Tested on V-Express with ubuntu and a mmap test from here: https://bugs.launchpad.net/bugs/861296 Signed-off-by: Rob Herring Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 9451dce..2f659e2 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -336,6 +336,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * We provide our own arch_get_unmapped_area to cope with VIPT caches. */ #define HAVE_ARCH_UNMAPPED_AREA +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN /* * remap a physical page `pfn' of size `size' with page protection `prot' diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index b2d9df5..ce280b8 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -123,6 +123,8 @@ static inline void prefetch(const void *ptr) #endif +#define HAVE_ARCH_PICK_MMAP_LAYOUT + #endif #endif /* __ASM_ARM_PROCESSOR_H */ diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 44b628e..ce8cb19 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -11,10 +11,49 @@ #include #include +static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr, + unsigned long pgoff) +{ + unsigned long base = addr & ~(SHMLBA-1); + unsigned long off = (pgoff << PAGE_SHIFT) & (SHMLBA-1); + + if (base + off <= addr) + return base + off; + + return base - off; +} + #define COLOUR_ALIGN(addr,pgoff) \ ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ (((pgoff)<personality & ADDR_COMPAT_LAYOUT) + return 1; + + if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) + return 1; + + return sysctl_legacy_va_layout; +} + +static unsigned long mmap_base(unsigned long rnd) +{ + unsigned long gap = rlimit(RLIMIT_STACK); + + if (gap < MIN_GAP) + gap = MIN_GAP; + else if (gap > MAX_GAP) + gap = MAX_GAP; + + return PAGE_ALIGN(TASK_SIZE - gap - rnd); +} + /* * We need to ensure that shared mappings are correctly aligned to * avoid aliasing issues with VIPT caches. We need to ensure that @@ -68,13 +107,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, if (len > mm->cached_hole_size) { start_addr = addr = mm->free_area_cache; } else { - start_addr = addr = TASK_UNMAPPED_BASE; + start_addr = addr = mm->mmap_base; mm->cached_hole_size = 0; } - /* 8 bits of randomness in 20 address space bits */ - if ((current->flags & PF_RANDOMIZE) && - !(current->personality & ADDR_NO_RANDOMIZE)) - addr += (get_random_int() % (1 << 8)) << PAGE_SHIFT; full_search: if (do_align) @@ -111,6 +146,134 @@ full_search: } } +unsigned long +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, + const unsigned long len, const unsigned long pgoff, + const unsigned long flags) +{ + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + unsigned long addr = addr0; + int do_align = 0; + int aliasing = cache_is_vipt_aliasing(); + + /* + * We only need to do colour alignment if either the I or D + * caches alias. + */ + if (aliasing) + do_align = filp || (flags & MAP_SHARED); + + /* requested length too big for entire address space */ + if (len > TASK_SIZE) + return -ENOMEM; + + if (flags & MAP_FIXED) { + if (aliasing && flags & MAP_SHARED && + (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) + return -EINVAL; + return addr; + } + + /* requesting a specific address */ + if (addr) { + if (do_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && + (!vma || addr + len <= vma->vm_start)) + return addr; + } + + /* check if free_area_cache is useful for us */ + if (len <= mm->cached_hole_size) { + mm->cached_hole_size = 0; + mm->free_area_cache = mm->mmap_base; + } + + /* either no address requested or can't fit in requested address hole */ + addr = mm->free_area_cache; + if (do_align) { + unsigned long base = COLOUR_ALIGN_DOWN(addr - len, pgoff); + addr = base + len; + } + + /* make sure it can fit in the remaining address space */ + if (addr > len) { + vma = find_vma(mm, addr-len); + if (!vma || addr <= vma->vm_start) + /* remember the address as a hint for next time */ + return (mm->free_area_cache = addr-len); + } + + if (mm->mmap_base < len) + goto bottomup; + + addr = mm->mmap_base - len; + if (do_align) + addr = COLOUR_ALIGN_DOWN(addr, pgoff); + + do { + /* + * Lookup failure means no vma is above this address, + * else if new region fits below vma->vm_start, + * return with success: + */ + vma = find_vma(mm, addr); + if (!vma || addr+len <= vma->vm_start) + /* remember the address as a hint for next time */ + return (mm->free_area_cache = addr); + + /* remember the largest hole we saw so far */ + if (addr + mm->cached_hole_size < vma->vm_start) + mm->cached_hole_size = vma->vm_start - addr; + + /* try just below the current vma->vm_start */ + addr = vma->vm_start - len; + if (do_align) + addr = COLOUR_ALIGN_DOWN(addr, pgoff); + } while (len < vma->vm_start); + +bottomup: + /* + * A failed mmap() very likely causes application failure, + * so fall back to the bottom-up function here. This scenario + * can happen with large stack limits and large mmap() + * allocations. + */ + mm->cached_hole_size = ~0UL; + mm->free_area_cache = TASK_UNMAPPED_BASE; + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); + /* + * Restore the topdown base: + */ + mm->free_area_cache = mm->mmap_base; + mm->cached_hole_size = ~0UL; + + return addr; +} + +void arch_pick_mmap_layout(struct mm_struct *mm) +{ + unsigned long random_factor = 0UL; + + /* 8 bits of randomness in 20 address space bits */ + if ((current->flags & PF_RANDOMIZE) && + !(current->personality & ADDR_NO_RANDOMIZE)) + random_factor = (get_random_int() % (1 << 8)) << PAGE_SHIFT; + + if (mmap_is_legacy()) { + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; + mm->get_unmapped_area = arch_get_unmapped_area; + mm->unmap_area = arch_unmap_area; + } else { + mm->mmap_base = mmap_base(random_factor); + mm->get_unmapped_area = arch_get_unmapped_area_topdown; + mm->unmap_area = arch_unmap_area_topdown; + } +} /* * You really shouldn't be using read() or write() on /dev/mem. This -- cgit v0.10.2 From df0e74da6df1568e3722466f85f2f08324bc767e Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Thu, 24 Nov 2011 12:23:18 +0100 Subject: ARM: 7173/1: Add optimised swahb32() byteswap helper for v6 and above ARMv6 and later processors have the REV16 instruction, which swaps the bytes within each halfword of a register value. This is already used to implement swab16(), but since the native operation performaed by REV16 is actually swahb32(), this patch renames the existing swab16() helper accordingly and defines __arch_swab16() in terms of it. This allows calls to both swab16() and swahb32() to be optimised. The compiler's generated code might improve someday, but as of 4.5.2 the code generated for pure C implementing these 16-bit bytesswaps remains pessimal. swahb32() is useful for converting 32-bit Thumb instructions between integer and memory representation on BE8 platforms (among other uses). Signed-off-by: Dave Martin Reviewed-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h index 9997ad2..32ee164 100644 --- a/arch/arm/include/asm/swab.h +++ b/arch/arm/include/asm/swab.h @@ -24,12 +24,13 @@ #if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6 -static inline __attribute_const__ __u16 __arch_swab16(__u16 x) +static inline __attribute_const__ __u32 __arch_swahb32(__u32 x) { __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); return x; } -#define __arch_swab16 __arch_swab16 +#define __arch_swahb32 __arch_swahb32 +#define __arch_swab16(x) ((__u16)__arch_swahb32(x)) static inline __attribute_const__ __u32 __arch_swab32(__u32 x) { -- cgit v0.10.2 From 8878a539ff19a43cf3729e7562cd528f490246ae Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Sun, 27 Nov 2011 17:49:50 +0100 Subject: ARM: 7178/1: fault.c: Port OOM changes into do_page_fault Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable) The above commits introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable. These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation. Port these changes to ARM. Without these changes, my ARM board encounters many hang and livelock scenarios. After applying this patch, OOM feature performance improves according to my testing. Signed-off-by: Kautuk Consul Signed-off-by: Russell King diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index aa33949..4aabeae 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -231,7 +231,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) static int __kprobes __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, - struct task_struct *tsk) + unsigned int flags, struct task_struct *tsk) { struct vm_area_struct *vma; int fault; @@ -253,18 +253,7 @@ good_area: goto out; } - /* - * If for any reason at all we couldn't handle the fault, make - * sure we exit gracefully rather than endlessly redo the fault. - */ - fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, (fsr & FSR_WRITE) ? FAULT_FLAG_WRITE : 0); - if (unlikely(fault & VM_FAULT_ERROR)) - return fault; - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; - return fault; + return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); check_stack: if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) @@ -279,6 +268,9 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; + int write = fsr & FSR_WRITE; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + (write ? FAULT_FLAG_WRITE : 0); if (notify_page_fault(regs, fsr)) return 0; @@ -305,6 +297,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!down_read_trylock(&mm->mmap_sem)) { if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc)) goto no_context; +retry: down_read(&mm->mmap_sem); } else { /* @@ -320,14 +313,41 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) #endif } - fault = __do_page_fault(mm, addr, fsr, tsk); - up_read(&mm->mmap_sem); + fault = __do_page_fault(mm, addr, fsr, flags, tsk); + + /* If we need to retry but a fatal signal is pending, handle the + * signal first. We do not need to release the mmap_sem because + * it would already be released in __lock_page_or_retry in + * mm/filemap.c. */ + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return 0; + + /* + * Major/minor page fault accounting is only done on the + * initial attempt. If we go through a retry, it is extremely + * likely that the page will be found in page cache at that point. + */ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); - if (fault & VM_FAULT_MAJOR) - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, addr); - else if (fault & VM_FAULT_MINOR) - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, addr); + if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (fault & VM_FAULT_MAJOR) { + tsk->maj_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, + regs, addr); + } else { + tsk->min_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, + regs, addr); + } + if (fault & VM_FAULT_RETRY) { + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk + * of starvation. */ + flags &= ~FAULT_FLAG_ALLOW_RETRY; + goto retry; + } + } + + up_read(&mm->mmap_sem); /* * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR -- cgit v0.10.2 From 4af3ce0de0c12e5c17811eaefad36ab8e146c0fd Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 6 Dec 2011 10:47:37 -0800 Subject: IB/mlx4: Fix shutdown crash accessing a non-existent bitmap Commit cfcde11c3d7a ("IB/mlx4: Use flow counters on IBoE ports") added code that sets elements of counters[] to -1 if no counter is allocated, but then goes ahead and passes every entry to mlx4_counter_free() on shutdown. This is a bad idea, especially if MLX4_DEV_CAP_FLAG_COUNTERS isn't set so there isn't even an underlying bitmap to free from. Tested-by: Sean Hefty Cc: Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 77f3dbc..18836cd 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1244,7 +1244,8 @@ err_reg: err_counter: for (; i; --i) - mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]); + if (ibdev->counters[i - 1] != -1) + mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]); err_map: iounmap(ibdev->uar_map); @@ -1275,7 +1276,8 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) } iounmap(ibdev->uar_map); for (p = 0; p < ibdev->num_ports; ++p) - mlx4_counter_free(ibdev->dev, ibdev->counters[p]); + if (ibdev->counters[p] != -1) + mlx4_counter_free(ibdev->dev, ibdev->counters[p]); mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) mlx4_CLOSE_PORT(dev, p); -- cgit v0.10.2 From 7148b7999277e2794cec90d8cb47d2a238e0bd0d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Nov 2011 17:06:20 +0000 Subject: mtd: pxa2xx-flash.c: It used to fall back to provided table. Make this work again. Signed-off-by: Jonathan Cameron Acked-by: Dmitry Eremin-Solenikov Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 411a17d..2a25b67 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -98,7 +98,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) } info->mtd->owner = THIS_MODULE; - mtd_device_parse_register(info->mtd, probes, 0, NULL, 0); + mtd_device_parse_register(info->mtd, probes, 0, flash->parts, flash->nr_parts); platform_set_drvdata(pdev, info); return 0; -- cgit v0.10.2 From 71c7a97289571ef5246b7f20d60b44961144c82f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 14 Nov 2011 04:28:59 -0300 Subject: [media] omap_vout: fix crash if no driver for a display omap_vout crashes on start if a corresponding driver is not loaded for a display device. This patch changes omap_vout init sequence to skip devices without a driver. Signed-off-by: Tomi Valkeinen Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 9c5c19f..2d2a136 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2169,6 +2169,14 @@ static int __init omap_vout_probe(struct platform_device *pdev) vid_dev->num_displays = 0; for_each_dss_dev(dssdev) { omap_dss_get_device(dssdev); + + if (!dssdev->driver) { + dev_warn(&pdev->dev, "no driver for display: %s\n", + dssdev->name); + omap_dss_put_device(dssdev); + continue; + } + vid_dev->displays[vid_dev->num_displays++] = dssdev; } -- cgit v0.10.2 From 7803c7aa8ef262a63e91ee0b04470715a7dc2eb0 Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Thu, 8 Dec 2011 10:05:52 +0900 Subject: ARM: SAMSUNG: Use kmemdup rather than duplicating its implementation The semantic patch that makes this change is available in scripts/coccinelle/api/memdup.cocci. Signed-off-by: Thomas Meyer Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 53754bcf..9fe3534 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1437,11 +1437,10 @@ int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel) size_t map_sz = sizeof(*nmap) * sel->map_size; int ptr; - nmap = kmalloc(map_sz, GFP_KERNEL); + nmap = kmemdup(sel->map, map_sz, GFP_KERNEL); if (nmap == NULL) return -ENOMEM; - memcpy(nmap, sel->map, map_sz); memcpy(&dma_sel, sel, sizeof(*sel)); dma_sel.map = nmap; -- cgit v0.10.2 From 584634e327bc34cfcddae38b604a10b901263970 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 9 Nov 2011 10:33:23 -0800 Subject: arm/tegra: fix variable formatting in makefile For some reason it started out using {} instead of (), and it's proliferated from there. Switch back to (). Signed-off-by: Olof Johansson Acked-by: Colin Cross diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 91a07e1..5be8e9e 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -18,20 +18,20 @@ obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o obj-$(CONFIG_TEGRA_PCI) += pcie.o obj-$(CONFIG_USB_SUPPORT) += usb_phy.o -obj-${CONFIG_MACH_HARMONY} += board-harmony.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o -obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-pinmux.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-pcie.o +obj-$(CONFIG_MACH_HARMONY) += board-harmony-power.o -obj-${CONFIG_MACH_PAZ00} += board-paz00.o -obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o +obj-$(CONFIG_MACH_PAZ00) += board-paz00.o +obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o -obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o -obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_SEABOARD) += board-seaboard.o +obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o -obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o -obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o -obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-dt.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o +obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o -obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o -obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o +obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o +obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o -- cgit v0.10.2 From 103c43a2c6aaf7fc4932513e2991cdec60411b18 Mon Sep 17 00:00:00 2001 From: "pdeschrijver@nvidia.com" Date: Wed, 2 Nov 2011 05:25:23 +0000 Subject: arm/tegra: remove unused defines PPI_NR is never used in arch/arm/mach-tegra/irq.c. Remove it. Signed-off-by: Peter De Schrijver Acked-by: Stephen Warren Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 4956c3c..8ad82af 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -28,10 +28,6 @@ #include "board.h" -#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE) -#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE) -#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ) - #define ICTLR_CPU_IEP_VFIQ 0x08 #define ICTLR_CPU_IEP_FIR 0x14 #define ICTLR_CPU_IEP_FIR_SET 0x18 -- cgit v0.10.2 From f5ce5e7e9cc3f69c3e6a0a4599262f740aff92c0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 2 Nov 2011 13:50:43 -0600 Subject: arm/tegra: Remove code that's ifndef CONFIG_ARM_GIC entry-macro.S contains some stale code for chips before Tegra20 that apparently didn't use an ARM GIC. All chips supported by mainline use an ARM GIC, so rip out the stale code. Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S index dd165c5..485a11e 100644 --- a/arch/arm/mach-tegra/include/mach/entry-macro.S +++ b/arch/arm/mach-tegra/include/mach/entry-macro.S @@ -15,7 +15,6 @@ #include #include -#if defined(CONFIG_ARM_GIC) #define HAVE_GET_IRQNR_PREAMBLE #include @@ -32,25 +31,3 @@ .macro arch_ret_to_user, tmp1, tmp2 .endm -#else - /* legacy interrupt controller for AP16 */ - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - @ enable imprecise aborts - cpsie a - @ EVP base at 0xf010f000 - mov \base, #0xf0000000 - orr \base, #0x00100000 - orr \base, #0x0000f000 - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS - cmp \irqnr, #0x80 - .endm -#endif -- cgit v0.10.2 From 4b44b40e04a758e2242ff4a3f7c15982801ec8bc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 9 Dec 2011 16:31:52 -0500 Subject: NFSv4: Ensure correct locking when accessing the 'lock_states' list There are currently 2 places in the state recovery code, where we do not take sufficient precautions before accessing the state->lock_states. In both cases, we should be holding the state->state_lock. Reported-by: Pascal Bouchareine Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index da8d73e..6a7107a 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1156,11 +1156,13 @@ restart: if (status >= 0) { status = nfs4_reclaim_locks(state, ops); if (status >= 0) { + spin_lock(&state->state_lock); list_for_each_entry(lock, &state->lock_states, ls_locks) { if (!(lock->ls_flags & NFS_LOCK_INITIALIZED)) printk("%s: Lock reclaim failed!\n", __func__); } + spin_unlock(&state->state_lock); nfs4_put_open_state(state); goto restart; } @@ -1224,10 +1226,12 @@ static void nfs4_clear_open_state(struct nfs4_state *state) clear_bit(NFS_O_RDONLY_STATE, &state->flags); clear_bit(NFS_O_WRONLY_STATE, &state->flags); clear_bit(NFS_O_RDWR_STATE, &state->flags); + spin_lock(&state->state_lock); list_for_each_entry(lock, &state->lock_states, ls_locks) { lock->ls_seqid.flags = 0; lock->ls_flags &= ~NFS_LOCK_INITIALIZED; } + spin_unlock(&state->state_lock); } static void nfs4_reset_seqids(struct nfs_server *server, -- cgit v0.10.2 From 9aa7705c966c750dda3d5c8d8a20f8e46668911c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 27 Nov 2011 15:42:15 -0300 Subject: [media] [trivial] omap24xxcam-dma: Fix logical test Likely misuse of & vs &&. Signed-off-by: Joe Perches Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/video/omap24xxcam-dma.c index 1d54b86..3ea38a8 100644 --- a/drivers/media/video/omap24xxcam-dma.c +++ b/drivers/media/video/omap24xxcam-dma.c @@ -506,7 +506,7 @@ int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma, unsigned long flags; struct sgdma_state *sg_state; - if ((sglen < 0) || ((sglen > 0) & !sglist)) + if ((sglen < 0) || ((sglen > 0) && !sglist)) return -EINVAL; spin_lock_irqsave(&sgdma->lock, flags); -- cgit v0.10.2 From 652f89f64fabcdae9143ee2b4253cfa838fb0279 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 9 Dec 2011 19:05:58 -0500 Subject: NFSv4: Do not accept delegated opens when a delegation recall is in effect ...and report the servers that try to return a delegation when the client is using the CLAIM_DELEG_CUR open mode. That behaviour is explicitly forbidden in RFC3530. Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index be2bbac..d9f4d78 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include #include @@ -894,6 +896,8 @@ out: static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) { + if (delegation == NULL) + return 0; if ((delegation->type & fmode) != fmode) return 0; if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) @@ -1036,8 +1040,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) } rcu_read_lock(); delegation = rcu_dereference(nfsi->delegation); - if (delegation == NULL || - !can_open_delegated(delegation, fmode)) { + if (!can_open_delegated(delegation, fmode)) { rcu_read_unlock(); break; } @@ -1091,7 +1094,12 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data if (delegation) delegation_flags = delegation->flags; rcu_read_unlock(); - if ((delegation_flags & 1UL<o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) { + pr_err_ratelimited("NFS: Broken NFSv4 server %s is " + "returning a delegation for " + "OPEN(CLAIM_DELEGATE_CUR)\n", + NFS_CLIENT(inode)->cl_server); + } else if ((delegation_flags & 1UL<inode, data->owner->so_cred, &data->o_res); @@ -1423,11 +1431,9 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) goto out_no_action; rcu_read_lock(); delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); - if (delegation != NULL && - test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0) { - rcu_read_unlock(); - goto out_no_action; - } + if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR && + can_open_delegated(delegation, data->o_arg.fmode)) + goto unlock_no_action; rcu_read_unlock(); } /* Update sequence id. */ @@ -1444,6 +1450,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) return; rpc_call_start(task); return; +unlock_no_action: + rcu_read_unlock(); out_no_action: task->tk_action = NULL; -- cgit v0.10.2 From 786a767465b12cb4c1a45421b12fbf6bff45b0ea Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 9 Dec 2011 17:58:35 +0100 Subject: ARM: 7201/1: add EDAC atomic_scrub function Add support for architecture specific EDAC atomic_scrub to ARM. Only ARMv6+ is implemented as ldrex/strex instructions are needed. Supporting EDAC on ARMv5 or earlier is unlikely at this point anyway. Signed-off-by: Rob Herring Signed-off-by: Russell King diff --git a/arch/arm/include/asm/edac.h b/arch/arm/include/asm/edac.h new file mode 100644 index 0000000..0df7a2c --- /dev/null +++ b/arch/arm/include/asm/edac.h @@ -0,0 +1,48 @@ +/* + * Copyright 2011 Calxeda, Inc. + * Based on PPC version Copyright 2007 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +#ifndef ASM_EDAC_H +#define ASM_EDAC_H +/* + * ECC atomic, DMA, SMP and interrupt safe scrub function. + * Implements the per arch atomic_scrub() that EDAC use for software + * ECC scrubbing. It reads memory and then writes back the original + * value, allowing the hardware to detect and correct memory errors. + */ +static inline void atomic_scrub(void *va, u32 size) +{ +#if __LINUX_ARM_ARCH__ >= 6 + unsigned int *virt_addr = va; + unsigned int temp, temp2; + unsigned int i; + + for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) { + /* Very carefully read and write to memory atomically + * so we are interrupt, DMA and SMP safe. + */ + __asm__ __volatile__("\n" + "1: ldrex %0, [%2]\n" + " strex %1, %0, [%2]\n" + " teq %1, #0\n" + " bne 1b\n" + : "=&r"(temp), "=&r"(temp2) + : "r"(virt_addr) + : "cc"); + } +#endif +} + +#endif -- cgit v0.10.2 From b4244738d20a631cd27fa105a2db71622618ab4e Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Fri, 9 Dec 2011 20:00:39 +0100 Subject: ARM: 7202/1: Add Cortex-A7 proc info This patch adds processor info for ARM Ltd. Cortex-A7. A7 is architecturally identical to A15 so it shares the same SMP initialization code and hwcaps. Tested-by: Will Deacon Signed-off-by: Pawel Moll Signed-off-by: Russell King diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 2c559ac..ea679ec 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -284,6 +284,7 @@ __v7_ca5mp_setup: __v7_ca9mp_setup: mov r10, #(1 << 0) @ TLB ops broadcasting b 1f +__v7_ca7mp_setup: __v7_ca15mp_setup: mov r10, #0 1: @@ -463,6 +464,16 @@ __v7_ca5mp_proc_info: .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info /* + * ARM Ltd. Cortex A7 processor. + */ + .type __v7_ca7mp_proc_info, #object +__v7_ca7mp_proc_info: + .long 0x410fc070 + .long 0xff0ffff0 + __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV + .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info + + /* * ARM Ltd. Cortex A9 processor. */ .type __v7_ca9mp_proc_info, #object -- cgit v0.10.2 From 23bbba3411715736ad1942f3bdbb18e1bbe6d45f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 29 Nov 2011 18:21:41 -0300 Subject: [media] au0828: add missing USB ID 2040:7260 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 39fc923..2e72bbd 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -324,6 +324,8 @@ struct usb_device_id au0828_usb_id_table[] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, { USB_DEVICE(0x2040, 0x8200), .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY }, + { USB_DEVICE(0x2040, 0x7260), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { }, }; -- cgit v0.10.2 From 64a6b6cbfad64dae8230ff999394a4b1b9e82ceb Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 29 Nov 2011 18:23:11 -0300 Subject: [media] au0828: add missing USB ID 2040:7213 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 2e72bbd..2dba8c1 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -326,6 +326,8 @@ struct usb_device_id au0828_usb_id_table[] = { .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY }, { USB_DEVICE(0x2040, 0x7260), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x7213), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { }, }; -- cgit v0.10.2 From 6b536a6ca52ae12b5378de6fb5da305a3c54dbd8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 29 Nov 2011 18:55:04 -0300 Subject: [media] au0828: add missing models 72101, 72201 & 72261 to the model matrix Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 2dba8c1..1c6015a 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -162,11 +162,14 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) switch (tv.model) { case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ + case 72101: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ + case 72201: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */ case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ + case 72261: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */ case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ break; -- cgit v0.10.2 From d1ee8878a142f81ea1b40d602c6360b752829437 Mon Sep 17 00:00:00 2001 From: Gary Thomas Date: Thu, 1 Dec 2011 08:51:09 -0300 Subject: [media] omap_vout: Fix compile error in 3.1 This patch is against the mainline v3.1 release (c3b92c8) and fixes a compile error when building for OMAP3+DSS+VOUT Acked-by: Laurent Pinchart Signed-off-by: Gary Thomas Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 2d2a136..ee0d0b3 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From a626f3945208af1d60d3dccf064cac3b15bc54ca Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 5 Dec 2011 06:12:15 -0300 Subject: [media] s5p_mfc_enc: fix s/H264/H263/ typo Signed-off-by: Peter Korsgaard Aked-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 1e8cdb7..dff9dc7 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -61,7 +61,7 @@ static struct s5p_mfc_fmt formats[] = { .num_planes = 1, }, { - .name = "H264 Encoded Stream", + .name = "H263 Encoded Stream", .fourcc = V4L2_PIX_FMT_H263, .codec_mode = S5P_FIMV_CODEC_H263_ENC, .type = MFC_FMT_ENC, -- cgit v0.10.2 From 4c0b036db808054f10f79e9a3d7928cf90aeb186 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 5 Dec 2011 16:01:13 -0300 Subject: [media] V4L: soc-camera: fix compiler warnings on 64-bit platforms On 64-bit platforms assigning a pointer to a 32-bit variable causes a compiler warning and cannot actually work. Soc-camera currently doesn't support any 64-bit systems, but such platforms can be added in the and in any case compiler warnings should be avoided. Signed-off-by: Guennadi Liakhovetski Acked-by: Janusz Krzysztofik Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c index d5b0572..577941f 100644 --- a/drivers/media/video/ov6650.c +++ b/drivers/media/video/ov6650.c @@ -539,7 +539,7 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe, static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id; + struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); struct soc_camera_sense *sense = icd->sense; struct ov6650 *priv = to_ov6650(client); bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index f390682..c51decf 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -566,8 +566,10 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) ret = sh_mobile_ceu_soft_reset(pcdev); csi2_sd = find_csi2(pcdev); - if (csi2_sd) - csi2_sd->grp_id = (long)icd; + if (csi2_sd) { + csi2_sd->grp_id = soc_camera_grp_id(icd); + v4l2_set_subdev_hostdata(csi2_sd, icd); + } ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) { @@ -768,7 +770,7 @@ static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, { if (pcdev->csi2_pdev) { struct v4l2_subdev *csi2_sd = find_csi2(pcdev); - if (csi2_sd && csi2_sd->grp_id == (u32)icd) + if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd)) return csi2_sd; } @@ -1089,8 +1091,9 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int /* Try 2560x1920, 1280x960, 640x480, 320x240 */ mf.width = 2560 >> shift; mf.height = 1920 >> shift; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, - s_mbus_fmt, &mf); + ret = v4l2_device_call_until_err(sd->v4l2_dev, + soc_camera_grp_id(icd), video, + s_mbus_fmt, &mf); if (ret < 0) return ret; shift++; @@ -1389,7 +1392,8 @@ static int client_s_fmt(struct soc_camera_device *icd, bool ceu_1to1; int ret; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, + ret = v4l2_device_call_until_err(sd->v4l2_dev, + soc_camera_grp_id(icd), video, s_mbus_fmt, mf); if (ret < 0) return ret; @@ -1426,8 +1430,9 @@ static int client_s_fmt(struct soc_camera_device *icd, tmp_h = min(2 * tmp_h, max_height); mf->width = tmp_w; mf->height = tmp_h; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, - s_mbus_fmt, mf); + ret = v4l2_device_call_until_err(sd->v4l2_dev, + soc_camera_grp_id(icd), video, + s_mbus_fmt, mf); dev_geo(dev, "Camera scaled to %ux%u\n", mf->width, mf->height); if (ret < 0) { @@ -1580,8 +1585,9 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, } if (interm_width < icd->user_width || interm_height < icd->user_height) { - ret = v4l2_device_call_until_err(sd->v4l2_dev, (int)icd, video, - s_mbus_fmt, &mf); + ret = v4l2_device_call_until_err(sd->v4l2_dev, + soc_camera_grp_id(icd), video, + s_mbus_fmt, &mf); if (ret < 0) return ret; @@ -1867,7 +1873,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, mf.code = xlate->code; mf.colorspace = pix->colorspace; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, try_mbus_fmt, &mf); + ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), + video, try_mbus_fmt, &mf); if (ret < 0) return ret; @@ -1891,8 +1898,9 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, */ mf.width = 2560; mf.height = 1920; - ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, - try_mbus_fmt, &mf); + ret = v4l2_device_call_until_err(sd->v4l2_dev, + soc_camera_grp_id(icd), video, + try_mbus_fmt, &mf); if (ret < 0) { /* Shouldn't actually happen... */ dev_err(icd->parent, diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c index 37706eb..bd0ca0e 100644 --- a/drivers/media/video/sh_mobile_csi2.c +++ b/drivers/media/video/sh_mobile_csi2.c @@ -142,7 +142,7 @@ static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); - struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id; + struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2, .flags = priv->mipi_flags}; @@ -201,7 +201,7 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv) static int sh_csi2_client_connect(struct sh_csi2 *priv) { struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; - struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id; + struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev); struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); struct device *dev = v4l2_get_subdevdata(&priv->subdev); struct v4l2_mbus_config cfg; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b72580c..62e4312 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -1103,7 +1103,8 @@ static int soc_camera_probe(struct soc_camera_device *icd) } sd = soc_camera_to_subdev(icd); - sd->grp_id = (long)icd; + sd->grp_id = soc_camera_grp_id(icd); + v4l2_set_subdev_hostdata(sd, icd); if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler)) goto ectrl; diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index b1377b9..5fb2c3d 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -254,7 +254,7 @@ unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl, static inline struct video_device *soc_camera_i2c_to_vdev(const struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id; + struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); return icd ? icd->vdev : NULL; } @@ -279,6 +279,11 @@ static inline struct soc_camera_device *soc_camera_from_vbq(const struct videobu return container_of(vq, struct soc_camera_device, vb_vidq); } +static inline u32 soc_camera_grp_id(const struct soc_camera_device *icd) +{ + return (icd->iface << 8) | (icd->devnum + 1); +} + void soc_camera_lock(struct vb2_queue *vq); void soc_camera_unlock(struct vb2_queue *vq); -- cgit v0.10.2 From 08da558ae0aaa488d8273ee44177c86580ba0d5a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 7 Nov 2011 15:44:12 -0300 Subject: [media] V4L: mt9t112: use after free in mt9t112_probe() priv gets dereferenced in mt9t112_set_params() so we should return before calling that. Signed-off-by: Dan Carpenter Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index 32114a3..7b34b11 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c @@ -1083,8 +1083,10 @@ static int mt9t112_probe(struct i2c_client *client, v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); ret = mt9t112_camera_probe(client); - if (ret) + if (ret) { kfree(priv); + return ret; + } /* Cannot fail: using the default supported pixel code */ mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); -- cgit v0.10.2 From 9c0223b53a26c506ecc7a36ec491afa688eebee1 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 24 Nov 2011 20:16:35 -0300 Subject: [media] V4L: omap1_camera: fix missing include Otherwise compilation breaks with: ... after apparently no longer included recursively from other header files. Signed-off-by: Janusz Krzysztofik Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c index e87ae2f..6a6cf38 100644 --- a/drivers/media/video/omap1_camera.c +++ b/drivers/media/video/omap1_camera.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From 6b806e30a3149816454a7ab71d50c244ebdb27d1 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 3 Nov 2011 08:12:00 -0300 Subject: [media] V4L: mt9m111: fix uninitialised mutex Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index f023cc0..dda4685 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -954,6 +954,7 @@ static int mt9m111_probe(struct i2c_client *client, mt9m111->rect.height = MT9M111_MAX_HEIGHT; mt9m111->fmt = &mt9m111_colour_fmts[0]; mt9m111->lastpage = -1; + mutex_init(&mt9m111->power_lock); ret = mt9m111_video_probe(client); if (ret) { -- cgit v0.10.2 From 5eefb4f09bd8b250421fbd055e67d136d57f4030 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 6 Dec 2011 22:34:29 -0300 Subject: [media] ati_remote: switch to single-byte scancodes The ati_remote driver currently uses 2-byte scancodes. However, one of those bytes is actually a checksum and therefore shouldn't be considered as part of the scancode. Fix the driver to only use the actual data byte as a scancode and to check the checksum itself. Update the bundled keymaps accordingly. Since ati_remote was only migrated to the rc subsystem for 3.2, the previous scancodes weren't emitted on any stable kernel. Reported-by: George Spelvin Signed-off-by: Anssi Hannula Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index 303f22e..01bb8da 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -189,7 +189,7 @@ struct ati_remote { dma_addr_t inbuf_dma; dma_addr_t outbuf_dma; - unsigned char old_data[2]; /* Detect duplicate events */ + unsigned char old_data; /* Detect duplicate events */ unsigned long old_jiffies; unsigned long acc_jiffies; /* handle acceleration */ unsigned long first_jiffies; @@ -221,35 +221,35 @@ struct ati_remote { /* Translation table from hardware messages to input events. */ static const struct { short kind; - unsigned char data1, data2; + unsigned char data; int type; unsigned int code; int value; } ati_remote_tbl[] = { /* Directional control pad axes */ - {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ - {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ - {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */ - {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */ + {KIND_ACCEL, 0x70, EV_REL, REL_X, -1}, /* left */ + {KIND_ACCEL, 0x71, EV_REL, REL_X, 1}, /* right */ + {KIND_ACCEL, 0x72, EV_REL, REL_Y, -1}, /* up */ + {KIND_ACCEL, 0x73, EV_REL, REL_Y, 1}, /* down */ /* Directional control pad diagonals */ - {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */ - {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */ - {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */ - {KIND_RD, 0x3b, 0x76, EV_REL, 0, 0}, /* right down */ + {KIND_LU, 0x74, EV_REL, 0, 0}, /* left up */ + {KIND_RU, 0x75, EV_REL, 0, 0}, /* right up */ + {KIND_LD, 0x77, EV_REL, 0, 0}, /* left down */ + {KIND_RD, 0x76, EV_REL, 0, 0}, /* right down */ /* "Mouse button" buttons */ - {KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ - {KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ - {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ - {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ + {KIND_LITERAL, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ + {KIND_LITERAL, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ + {KIND_LITERAL, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ + {KIND_LITERAL, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ /* Artificial "doubleclick" events are generated by the hardware. * They are mapped to the "side" and "extra" mouse buttons here. */ - {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ - {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ + {KIND_FILTERED, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ + {KIND_FILTERED, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ /* Non-mouse events are handled by rc-core */ - {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} + {KIND_END, 0x00, EV_MAX + 1, 0, 0} }; /* Local function prototypes */ @@ -397,25 +397,6 @@ static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigne } /* - * ati_remote_event_lookup - */ -static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) -{ - int i; - - for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { - /* - * Decide if the table entry matches the remote input. - */ - if (ati_remote_tbl[i].data1 == d1 && - ati_remote_tbl[i].data2 == d2) - return i; - - } - return -1; -} - -/* * ati_remote_compute_accel * * Implements acceleration curve for directional control pad @@ -463,7 +444,15 @@ static void ati_remote_input_report(struct urb *urb) int index = -1; int acc; int remote_num; - unsigned char scancode[2]; + unsigned char scancode; + int i; + + /* + * data[0] = 0x14 + * data[1] = data[2] + data[3] + 0xd5 (a checksum byte) + * data[2] = the key code (with toggle bit in MSB with some models) + * data[3] = channel << 4 (the low 4 bits must be zero) + */ /* Deal with strange looking inputs */ if ( (urb->actual_length != 4) || (data[0] != 0x14) || @@ -472,6 +461,13 @@ static void ati_remote_input_report(struct urb *urb) return; } + if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) { + dbginfo(&ati_remote->interface->dev, + "wrong checksum in input: %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3]); + return; + } + /* Mask unwanted remote channels. */ /* note: remote_num is 0-based, channel 1 on remote == 0 here */ remote_num = (data[3] >> 4) & 0x0f; @@ -482,31 +478,30 @@ static void ati_remote_input_report(struct urb *urb) return; } - scancode[0] = (((data[1] - ((remote_num + 1) << 4)) & 0xf0) | (data[1] & 0x0f)); - /* - * Some devices (e.g. SnapStream Firefly) use 8080 as toggle code, - * so we have to clear them. The first bit is a bit tricky as the - * "non-toggled" state depends on remote_num, so we xor it with the - * second bit which is only used for toggle. + * MSB is a toggle code, though only used by some devices + * (e.g. SnapStream Firefly) */ - scancode[0] ^= (data[2] & 0x80); - - scancode[1] = data[2] & ~0x80; + scancode = data[2] & 0x7f; - /* Look up event code index in mouse translation table. */ - index = ati_remote_event_lookup(remote_num, scancode[0], scancode[1]); + /* Look up event code index in the mouse translation table. */ + for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { + if (scancode == ati_remote_tbl[i].data) { + index = i; + break; + } + } if (index >= 0) { dbginfo(&ati_remote->interface->dev, - "channel 0x%02x; mouse data %02x,%02x; index %d; keycode %d\n", - remote_num, data[1], data[2], index, ati_remote_tbl[index].code); + "channel 0x%02x; mouse data %02x; index %d; keycode %d\n", + remote_num, data[2], index, ati_remote_tbl[index].code); if (!dev) return; /* no mouse device */ } else dbginfo(&ati_remote->interface->dev, - "channel 0x%02x; key data %02x,%02x, scancode %02x,%02x\n", - remote_num, data[1], data[2], scancode[0], scancode[1]); + "channel 0x%02x; key data %02x, scancode %02x\n", + remote_num, data[2], scancode); if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { @@ -523,8 +518,7 @@ static void ati_remote_input_report(struct urb *urb) unsigned long now = jiffies; /* Filter duplicate events which happen "too close" together. */ - if (ati_remote->old_data[0] == data[1] && - ati_remote->old_data[1] == data[2] && + if (ati_remote->old_data == data[2] && time_before(now, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { ati_remote->repeat_count++; @@ -533,8 +527,7 @@ static void ati_remote_input_report(struct urb *urb) ati_remote->first_jiffies = now; } - ati_remote->old_data[0] = data[1]; - ati_remote->old_data[1] = data[2]; + ati_remote->old_data = data[2]; ati_remote->old_jiffies = now; /* Ensure we skip at least the 4 first duplicate events (generated @@ -549,14 +542,13 @@ static void ati_remote_input_report(struct urb *urb) if (index < 0) { /* Not a mouse event, hand it to rc-core. */ - u32 rc_code = (scancode[0] << 8) | scancode[1]; /* * We don't use the rc-core repeat handling yet as * it would cause ghost repeats which would be a * regression for this driver. */ - rc_keydown_notimeout(ati_remote->rdev, rc_code, + rc_keydown_notimeout(ati_remote->rdev, scancode, data[2]); rc_keyup(ati_remote->rdev); return; @@ -607,8 +599,7 @@ static void ati_remote_input_report(struct urb *urb) input_sync(dev); ati_remote->old_jiffies = jiffies; - ati_remote->old_data[0] = data[1]; - ati_remote->old_data[1] = data[2]; + ati_remote->old_data = data[2]; } } diff --git a/drivers/media/rc/keymaps/rc-ati-x10.c b/drivers/media/rc/keymaps/rc-ati-x10.c index e1b8b26..8150644 100644 --- a/drivers/media/rc/keymaps/rc-ati-x10.c +++ b/drivers/media/rc/keymaps/rc-ati-x10.c @@ -27,55 +27,55 @@ #include static struct rc_map_table ati_x10[] = { - { 0xd20d, KEY_1 }, - { 0xd30e, KEY_2 }, - { 0xd40f, KEY_3 }, - { 0xd510, KEY_4 }, - { 0xd611, KEY_5 }, - { 0xd712, KEY_6 }, - { 0xd813, KEY_7 }, - { 0xd914, KEY_8 }, - { 0xda15, KEY_9 }, - { 0xdc17, KEY_0 }, - { 0xc500, KEY_A }, - { 0xc601, KEY_B }, - { 0xde19, KEY_C }, - { 0xe01b, KEY_D }, - { 0xe621, KEY_E }, - { 0xe823, KEY_F }, + { 0x0d, KEY_1 }, + { 0x0e, KEY_2 }, + { 0x0f, KEY_3 }, + { 0x10, KEY_4 }, + { 0x11, KEY_5 }, + { 0x12, KEY_6 }, + { 0x13, KEY_7 }, + { 0x14, KEY_8 }, + { 0x15, KEY_9 }, + { 0x17, KEY_0 }, + { 0x00, KEY_A }, + { 0x01, KEY_B }, + { 0x19, KEY_C }, + { 0x1b, KEY_D }, + { 0x21, KEY_E }, + { 0x23, KEY_F }, - { 0xdd18, KEY_KPENTER }, /* "check" */ - { 0xdb16, KEY_MENU }, /* "menu" */ - { 0xc702, KEY_POWER }, /* Power */ - { 0xc803, KEY_TV }, /* TV */ - { 0xc904, KEY_DVD }, /* DVD */ - { 0xca05, KEY_WWW }, /* WEB */ - { 0xcb06, KEY_BOOKMARKS }, /* "book" */ - { 0xcc07, KEY_EDIT }, /* "hand" */ - { 0xe11c, KEY_COFFEE }, /* "timer" */ - { 0xe520, KEY_FRONT }, /* "max" */ - { 0xe21d, KEY_LEFT }, /* left */ - { 0xe41f, KEY_RIGHT }, /* right */ - { 0xe722, KEY_DOWN }, /* down */ - { 0xdf1a, KEY_UP }, /* up */ - { 0xe31e, KEY_OK }, /* "OK" */ - { 0xce09, KEY_VOLUMEDOWN }, /* VOL + */ - { 0xcd08, KEY_VOLUMEUP }, /* VOL - */ - { 0xcf0a, KEY_MUTE }, /* MUTE */ - { 0xd00b, KEY_CHANNELUP }, /* CH + */ - { 0xd10c, KEY_CHANNELDOWN },/* CH - */ - { 0xec27, KEY_RECORD }, /* ( o) red */ - { 0xea25, KEY_PLAY }, /* ( >) */ - { 0xe924, KEY_REWIND }, /* (<<) */ - { 0xeb26, KEY_FORWARD }, /* (>>) */ - { 0xed28, KEY_STOP }, /* ([]) */ - { 0xee29, KEY_PAUSE }, /* ('') */ - { 0xf02b, KEY_PREVIOUS }, /* (<-) */ - { 0xef2a, KEY_NEXT }, /* (>+) */ - { 0xf22d, KEY_INFO }, /* PLAYING */ - { 0xf32e, KEY_HOME }, /* TOP */ - { 0xf42f, KEY_END }, /* END */ - { 0xf530, KEY_SELECT }, /* SELECT */ + { 0x18, KEY_KPENTER }, /* "check" */ + { 0x16, KEY_MENU }, /* "menu" */ + { 0x02, KEY_POWER }, /* Power */ + { 0x03, KEY_TV }, /* TV */ + { 0x04, KEY_DVD }, /* DVD */ + { 0x05, KEY_WWW }, /* WEB */ + { 0x06, KEY_BOOKMARKS }, /* "book" */ + { 0x07, KEY_EDIT }, /* "hand" */ + { 0x1c, KEY_COFFEE }, /* "timer" */ + { 0x20, KEY_FRONT }, /* "max" */ + { 0x1d, KEY_LEFT }, /* left */ + { 0x1f, KEY_RIGHT }, /* right */ + { 0x22, KEY_DOWN }, /* down */ + { 0x1a, KEY_UP }, /* up */ + { 0x1e, KEY_OK }, /* "OK" */ + { 0x09, KEY_VOLUMEDOWN }, /* VOL + */ + { 0x08, KEY_VOLUMEUP }, /* VOL - */ + { 0x0a, KEY_MUTE }, /* MUTE */ + { 0x0b, KEY_CHANNELUP }, /* CH + */ + { 0x0c, KEY_CHANNELDOWN },/* CH - */ + { 0x27, KEY_RECORD }, /* ( o) red */ + { 0x25, KEY_PLAY }, /* ( >) */ + { 0x24, KEY_REWIND }, /* (<<) */ + { 0x26, KEY_FORWARD }, /* (>>) */ + { 0x28, KEY_STOP }, /* ([]) */ + { 0x29, KEY_PAUSE }, /* ('') */ + { 0x2b, KEY_PREVIOUS }, /* (<-) */ + { 0x2a, KEY_NEXT }, /* (>+) */ + { 0x2d, KEY_INFO }, /* PLAYING */ + { 0x2e, KEY_HOME }, /* TOP */ + { 0x2f, KEY_END }, /* END */ + { 0x30, KEY_SELECT }, /* SELECT */ }; static struct rc_map_list ati_x10_map = { diff --git a/drivers/media/rc/keymaps/rc-medion-x10.c b/drivers/media/rc/keymaps/rc-medion-x10.c index 09e2cc0..479cdb8 100644 --- a/drivers/media/rc/keymaps/rc-medion-x10.c +++ b/drivers/media/rc/keymaps/rc-medion-x10.c @@ -25,70 +25,70 @@ #include static struct rc_map_table medion_x10[] = { - { 0xf12c, KEY_TV }, /* TV */ - { 0xf22d, KEY_VCR }, /* VCR */ - { 0xc904, KEY_DVD }, /* DVD */ - { 0xcb06, KEY_AUDIO }, /* MUSIC */ - - { 0xf32e, KEY_RADIO }, /* RADIO */ - { 0xca05, KEY_DIRECTORY }, /* PHOTO */ - { 0xf42f, KEY_INFO }, /* TV-PREVIEW */ - { 0xf530, KEY_LIST }, /* CHANNEL-LST */ - - { 0xe01b, KEY_SETUP }, /* SETUP */ - { 0xf631, KEY_VIDEO }, /* VIDEO DESKTOP */ - - { 0xcd08, KEY_VOLUMEDOWN }, /* VOL - */ - { 0xce09, KEY_VOLUMEUP }, /* VOL + */ - { 0xd00b, KEY_CHANNELUP }, /* CHAN + */ - { 0xd10c, KEY_CHANNELDOWN }, /* CHAN - */ - { 0xc500, KEY_MUTE }, /* MUTE */ - - { 0xf732, KEY_RED }, /* red */ - { 0xf833, KEY_GREEN }, /* green */ - { 0xf934, KEY_YELLOW }, /* yellow */ - { 0xfa35, KEY_BLUE }, /* blue */ - { 0xdb16, KEY_TEXT }, /* TXT */ - - { 0xd20d, KEY_1 }, - { 0xd30e, KEY_2 }, - { 0xd40f, KEY_3 }, - { 0xd510, KEY_4 }, - { 0xd611, KEY_5 }, - { 0xd712, KEY_6 }, - { 0xd813, KEY_7 }, - { 0xd914, KEY_8 }, - { 0xda15, KEY_9 }, - { 0xdc17, KEY_0 }, - { 0xe11c, KEY_SEARCH }, /* TV/RAD, CH SRC */ - { 0xe520, KEY_DELETE }, /* DELETE */ - - { 0xfb36, KEY_KEYBOARD }, /* RENAME */ - { 0xdd18, KEY_SCREEN }, /* SNAPSHOT */ - - { 0xdf1a, KEY_UP }, /* up */ - { 0xe722, KEY_DOWN }, /* down */ - { 0xe21d, KEY_LEFT }, /* left */ - { 0xe41f, KEY_RIGHT }, /* right */ - { 0xe31e, KEY_OK }, /* OK */ - - { 0xfc37, KEY_SELECT }, /* ACQUIRE IMAGE */ - { 0xfd38, KEY_EDIT }, /* EDIT IMAGE */ - - { 0xe924, KEY_REWIND }, /* rewind (<<) */ - { 0xea25, KEY_PLAY }, /* play ( >) */ - { 0xeb26, KEY_FORWARD }, /* forward (>>) */ - { 0xec27, KEY_RECORD }, /* record ( o) */ - { 0xed28, KEY_STOP }, /* stop ([]) */ - { 0xee29, KEY_PAUSE }, /* pause ('') */ - - { 0xe621, KEY_PREVIOUS }, /* prev */ - { 0xfe39, KEY_SWITCHVIDEOMODE }, /* F SCR */ - { 0xe823, KEY_NEXT }, /* next */ - { 0xde19, KEY_MENU }, /* MENU */ - { 0xff3a, KEY_LANGUAGE }, /* AUDIO */ - - { 0xc702, KEY_POWER }, /* POWER */ + { 0x2c, KEY_TV }, /* TV */ + { 0x2d, KEY_VCR }, /* VCR */ + { 0x04, KEY_DVD }, /* DVD */ + { 0x06, KEY_AUDIO }, /* MUSIC */ + + { 0x2e, KEY_RADIO }, /* RADIO */ + { 0x05, KEY_DIRECTORY }, /* PHOTO */ + { 0x2f, KEY_INFO }, /* TV-PREVIEW */ + { 0x30, KEY_LIST }, /* CHANNEL-LST */ + + { 0x1b, KEY_SETUP }, /* SETUP */ + { 0x31, KEY_VIDEO }, /* VIDEO DESKTOP */ + + { 0x08, KEY_VOLUMEDOWN }, /* VOL - */ + { 0x09, KEY_VOLUMEUP }, /* VOL + */ + { 0x0b, KEY_CHANNELUP }, /* CHAN + */ + { 0x0c, KEY_CHANNELDOWN }, /* CHAN - */ + { 0x00, KEY_MUTE }, /* MUTE */ + + { 0x32, KEY_RED }, /* red */ + { 0x33, KEY_GREEN }, /* green */ + { 0x34, KEY_YELLOW }, /* yellow */ + { 0x35, KEY_BLUE }, /* blue */ + { 0x16, KEY_TEXT }, /* TXT */ + + { 0x0d, KEY_1 }, + { 0x0e, KEY_2 }, + { 0x0f, KEY_3 }, + { 0x10, KEY_4 }, + { 0x11, KEY_5 }, + { 0x12, KEY_6 }, + { 0x13, KEY_7 }, + { 0x14, KEY_8 }, + { 0x15, KEY_9 }, + { 0x17, KEY_0 }, + { 0x1c, KEY_SEARCH }, /* TV/RAD, CH SRC */ + { 0x20, KEY_DELETE }, /* DELETE */ + + { 0x36, KEY_KEYBOARD }, /* RENAME */ + { 0x18, KEY_SCREEN }, /* SNAPSHOT */ + + { 0x1a, KEY_UP }, /* up */ + { 0x22, KEY_DOWN }, /* down */ + { 0x1d, KEY_LEFT }, /* left */ + { 0x1f, KEY_RIGHT }, /* right */ + { 0x1e, KEY_OK }, /* OK */ + + { 0x37, KEY_SELECT }, /* ACQUIRE IMAGE */ + { 0x38, KEY_EDIT }, /* EDIT IMAGE */ + + { 0x24, KEY_REWIND }, /* rewind (<<) */ + { 0x25, KEY_PLAY }, /* play ( >) */ + { 0x26, KEY_FORWARD }, /* forward (>>) */ + { 0x27, KEY_RECORD }, /* record ( o) */ + { 0x28, KEY_STOP }, /* stop ([]) */ + { 0x29, KEY_PAUSE }, /* pause ('') */ + + { 0x21, KEY_PREVIOUS }, /* prev */ + { 0x39, KEY_SWITCHVIDEOMODE }, /* F SCR */ + { 0x23, KEY_NEXT }, /* next */ + { 0x19, KEY_MENU }, /* MENU */ + { 0x3a, KEY_LANGUAGE }, /* AUDIO */ + + { 0x02, KEY_POWER }, /* POWER */ }; static struct rc_map_list medion_x10_map = { diff --git a/drivers/media/rc/keymaps/rc-snapstream-firefly.c b/drivers/media/rc/keymaps/rc-snapstream-firefly.c index ef14652..c7f33ec 100644 --- a/drivers/media/rc/keymaps/rc-snapstream-firefly.c +++ b/drivers/media/rc/keymaps/rc-snapstream-firefly.c @@ -22,63 +22,63 @@ #include static struct rc_map_table snapstream_firefly[] = { - { 0xf12c, KEY_ZOOM }, /* Maximize */ - { 0xc702, KEY_CLOSE }, - - { 0xd20d, KEY_1 }, - { 0xd30e, KEY_2 }, - { 0xd40f, KEY_3 }, - { 0xd510, KEY_4 }, - { 0xd611, KEY_5 }, - { 0xd712, KEY_6 }, - { 0xd813, KEY_7 }, - { 0xd914, KEY_8 }, - { 0xda15, KEY_9 }, - { 0xdc17, KEY_0 }, - { 0xdb16, KEY_BACK }, - { 0xdd18, KEY_KPENTER }, /* ent */ - - { 0xce09, KEY_VOLUMEUP }, - { 0xcd08, KEY_VOLUMEDOWN }, - { 0xcf0a, KEY_MUTE }, - { 0xd00b, KEY_CHANNELUP }, - { 0xd10c, KEY_CHANNELDOWN }, - { 0xc500, KEY_VENDOR }, /* firefly */ - - { 0xf32e, KEY_INFO }, - { 0xf42f, KEY_OPTION }, - - { 0xe21d, KEY_LEFT }, - { 0xe41f, KEY_RIGHT }, - { 0xe722, KEY_DOWN }, - { 0xdf1a, KEY_UP }, - { 0xe31e, KEY_OK }, - - { 0xe11c, KEY_MENU }, - { 0xe520, KEY_EXIT }, - - { 0xec27, KEY_RECORD }, - { 0xea25, KEY_PLAY }, - { 0xed28, KEY_STOP }, - { 0xe924, KEY_REWIND }, - { 0xeb26, KEY_FORWARD }, - { 0xee29, KEY_PAUSE }, - { 0xf02b, KEY_PREVIOUS }, - { 0xef2a, KEY_NEXT }, - - { 0xcb06, KEY_AUDIO }, /* Music */ - { 0xca05, KEY_IMAGES }, /* Photos */ - { 0xc904, KEY_DVD }, - { 0xc803, KEY_TV }, - { 0xcc07, KEY_VIDEO }, - - { 0xc601, KEY_HELP }, - { 0xf22d, KEY_MODE }, /* Mouse */ - - { 0xde19, KEY_A }, - { 0xe01b, KEY_B }, - { 0xe621, KEY_C }, - { 0xe823, KEY_D }, + { 0x2c, KEY_ZOOM }, /* Maximize */ + { 0x02, KEY_CLOSE }, + + { 0x0d, KEY_1 }, + { 0x0e, KEY_2 }, + { 0x0f, KEY_3 }, + { 0x10, KEY_4 }, + { 0x11, KEY_5 }, + { 0x12, KEY_6 }, + { 0x13, KEY_7 }, + { 0x14, KEY_8 }, + { 0x15, KEY_9 }, + { 0x17, KEY_0 }, + { 0x16, KEY_BACK }, + { 0x18, KEY_KPENTER }, /* ent */ + + { 0x09, KEY_VOLUMEUP }, + { 0x08, KEY_VOLUMEDOWN }, + { 0x0a, KEY_MUTE }, + { 0x0b, KEY_CHANNELUP }, + { 0x0c, KEY_CHANNELDOWN }, + { 0x00, KEY_VENDOR }, /* firefly */ + + { 0x2e, KEY_INFO }, + { 0x2f, KEY_OPTION }, + + { 0x1d, KEY_LEFT }, + { 0x1f, KEY_RIGHT }, + { 0x22, KEY_DOWN }, + { 0x1a, KEY_UP }, + { 0x1e, KEY_OK }, + + { 0x1c, KEY_MENU }, + { 0x20, KEY_EXIT }, + + { 0x27, KEY_RECORD }, + { 0x25, KEY_PLAY }, + { 0x28, KEY_STOP }, + { 0x24, KEY_REWIND }, + { 0x26, KEY_FORWARD }, + { 0x29, KEY_PAUSE }, + { 0x2b, KEY_PREVIOUS }, + { 0x2a, KEY_NEXT }, + + { 0x06, KEY_AUDIO }, /* Music */ + { 0x05, KEY_IMAGES }, /* Photos */ + { 0x04, KEY_DVD }, + { 0x03, KEY_TV }, + { 0x07, KEY_VIDEO }, + + { 0x01, KEY_HELP }, + { 0x2d, KEY_MODE }, /* Mouse */ + + { 0x19, KEY_A }, + { 0x1b, KEY_B }, + { 0x21, KEY_C }, + { 0x23, KEY_D }, }; static struct rc_map_list snapstream_firefly_map = { -- cgit v0.10.2 From a32390d808b5b7a6b1c7f9236673c917b4733f13 Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Sat, 15 Oct 2011 18:38:40 -0300 Subject: [media] m5mols: Fix logic in sanity check Detected by "cppcheck". Signed-off-by: Thomas Jarosch Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c index 68497f8..5da8d74 100644 --- a/drivers/media/video/m5mols/m5mols_core.c +++ b/drivers/media/video/m5mols/m5mols_core.c @@ -333,7 +333,7 @@ int m5mols_mode(struct m5mols_info *info, u8 mode) int ret = -EINVAL; u8 reg; - if (mode < REG_PARAMETER && mode > REG_CAPTURE) + if (mode < REG_PARAMETER || mode > REG_CAPTURE) return ret; ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, ®); -- cgit v0.10.2 From 393a23fc9377ac3deaa97c5cc00b5c78746c8570 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 8 Dec 2011 06:56:22 -0300 Subject: [media] s5p-fimc: Fix camera input configuration in subdev operations When using only subdev user-space operations the camera interface input was not configured properly. Fix this by updating the corresponding data structure in set_fmt operation. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 82d9ab6..2cc3b91 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -1242,6 +1242,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, mutex_lock(&fimc->lock); set_frame_bounds(ff, mf->width, mf->height); + fimc->vid_cap.mf = *mf; ff->fmt = ffmt; /* Reset the crop rectangle if required. */ -- cgit v0.10.2 From 0d0e3064a88cc8d6bd3a9b43c5ae069ca838fc6e Mon Sep 17 00:00:00 2001 From: Chris Bagwell Date: Sun, 11 Dec 2011 23:50:59 -0800 Subject: Input: wacom - add product id used by Samsung Slate 7 New product ID reported by Harvey Braun on linuxwacom mailing list and also tested this patch with new hardware. Signed-off-by: Chris Bagwell Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index da0d876..2ee47d0 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1470,6 +1470,9 @@ static const struct wacom_features wacom_features_0xE3 = static const struct wacom_features wacom_features_0xE6 = { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xEC = + { "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x47 = { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -1611,6 +1614,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xE2) }, { USB_DEVICE_WACOM(0xE3) }, { USB_DEVICE_WACOM(0xE6) }, + { USB_DEVICE_WACOM(0xEC) }, { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_LENOVO(0x6004) }, { } -- cgit v0.10.2 From 3a7f8fb1d8c9b6a066b0452cea47c85547c97723 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sun, 11 Dec 2011 23:40:56 -0800 Subject: Input: cma3000_d0x - fix signedness bug in cma3000_thread_irq() The error check (intr_status < 0) didn't work because intr_status is a u8. Change its type to signed int. Signed-off-by: Xi Wang Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index 1633b63..09f8f20 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c @@ -114,8 +114,8 @@ static void decode_mg(struct cma3000_accl_data *data, int *datax, static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) { struct cma3000_accl_data *data = dev_id; - int datax, datay, dataz; - u8 ctrl, mode, range, intr_status; + int datax, datay, dataz, intr_status; + u8 ctrl, mode, range; intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); if (intr_status < 0) -- cgit v0.10.2 From 8521478f67e95ada4e87970c7b41e504c724b2cf Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 12 Dec 2011 00:05:53 -0800 Subject: Input: synaptics - fix touchpad not working after S2R on Vostro V13 Synaptics touchpads on several Dell laptops, particularly Vostro V13 systems, may not respond properly to PS/2 commands and queries immediately after resuming from suspend to RAM. This leads to unresponsive touchpad after suspend/resume cycle. Adding a 1-second delay after resetting the device allows touchpad to finish initializing (calibrating?) and start reacting properly. Reported-by: Daniel Manrique Tested-by: Daniel Manrique Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c080b82..a6dcd18 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -1220,6 +1221,16 @@ static int synaptics_reconnect(struct psmouse *psmouse) do { psmouse_reset(psmouse); + if (retry) { + /* + * On some boxes, right after resuming, the touchpad + * needs some time to finish initializing (I assume + * it needs time to calibrate) and start responding + * to Synaptics-specific queries, so let's wait a + * bit. + */ + ssleep(1); + } error = synaptics_detect(psmouse, 0); } while (error && ++retry < 3); -- cgit v0.10.2 From f6a290b419a2675c4b77a6b0731cd2a64332365e Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 7 Nov 2011 22:05:21 +1100 Subject: [SCSI] mpt2sas: _scsih_smart_predicted_fault uses GFP_KERNEL in interrupt context _scsih_smart_predicted_fault is called in an interrupt and therefore must allocate memory using GFP_ATOMIC. Signed-off-by: Anton Blanchard Cc: Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 4e041f6..d570573 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -4335,7 +4335,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) /* insert into event log */ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + sizeof(Mpi2EventDataSasDeviceStatusChange_t); - event_reply = kzalloc(sz, GFP_KERNEL); + event_reply = kzalloc(sz, GFP_ATOMIC); if (!event_reply) { printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); -- cgit v0.10.2 From ad537689c30d8e35300dcc93a109a966b8a89478 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Fri, 18 Nov 2011 09:02:09 -0800 Subject: [SCSI] qla2xxx: Remove qla2x00_wait_for_loop_ready function. This function can wait for 5min under certain scenarios. One of them is when the port is down from switch and bus reset is issued. The bus reset used to wait for 5 minutes for the loop and upper layer callers used to hang and give stack trace because of getting stuck for 120 sec. It is legacy code that was used when the driver used to do queuing of the commands. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index fd14c7b..93673d3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -814,49 +814,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) return return_status; } -/* - * qla2x00_wait_for_loop_ready - * Wait for MAX_LOOP_TIMEOUT(5 min) value for loop - * to be in LOOP_READY state. - * Input: - * ha - pointer to host adapter structure - * - * Note: - * Does context switching-Release SPIN_LOCK - * (if any) before calling this routine. - * - * - * Return: - * Success (LOOP_READY) : 0 - * Failed (LOOP_NOT_READY) : 1 - */ -static inline int -qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha) -{ - int return_status = QLA_SUCCESS; - unsigned long loop_timeout ; - struct qla_hw_data *ha = vha->hw; - scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); - - /* wait for 5 min at the max for loop to be ready */ - loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ); - - while ((!atomic_read(&base_vha->loop_down_timer) && - atomic_read(&base_vha->loop_state) == LOOP_DOWN) || - atomic_read(&base_vha->loop_state) != LOOP_READY) { - if (atomic_read(&base_vha->loop_state) == LOOP_DEAD) { - return_status = QLA_FUNCTION_FAILED; - break; - } - msleep(1000); - if (time_after_eq(jiffies, loop_timeout)) { - return_status = QLA_FUNCTION_FAILED; - break; - } - } - return (return_status); -} - static void sp_get(struct srb *sp) { @@ -1035,12 +992,6 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, "Wait for hba online failed for cmd=%p.\n", cmd); goto eh_reset_failed; } - err = 1; - if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x800b, - "Wait for loop ready failed for cmd=%p.\n", cmd); - goto eh_reset_failed; - } err = 2; if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1) != QLA_SUCCESS) { @@ -1137,10 +1088,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) goto eh_bus_reset_done; } - if (qla2x00_wait_for_loop_ready(vha) == QLA_SUCCESS) { - if (qla2x00_loop_reset(vha) == QLA_SUCCESS) - ret = SUCCESS; - } + if (qla2x00_loop_reset(vha) == QLA_SUCCESS) + ret = SUCCESS; + if (ret == FAILED) goto eh_bus_reset_done; @@ -1206,15 +1156,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS) goto eh_host_reset_lock; - /* - * Fixme-may be dpc thread is active and processing - * loop_resync,so wait a while for it to - * be completed and then issue big hammer.Otherwise - * it may cause I/O failure as big hammer marks the - * devices as lost kicking of the port_down_timer - * while dpc is stuck for the mailbox to complete. - */ - qla2x00_wait_for_loop_ready(vha); if (vha != base_vha) { if (qla2x00_vp_abort_isp(vha)) goto eh_host_reset_lock; @@ -1297,16 +1238,13 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); qla2x00_mark_all_devices_lost(vha, 0); - qla2x00_wait_for_loop_ready(vha); } if (ha->flags.enable_lip_reset) { ret = qla2x00_lip_reset(vha); - if (ret != QLA_SUCCESS) { + if (ret != QLA_SUCCESS) ql_dbg(ql_dbg_taskm, vha, 0x802e, "lip_reset failed (%d).\n", ret); - } else - qla2x00_wait_for_loop_ready(vha); } /* Issue marker command only when we are going to start the I/O */ -- cgit v0.10.2 From 4e85e3d92fd1b52989882062f5cb143a31375b62 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Fri, 18 Nov 2011 09:02:10 -0800 Subject: [SCSI] qla2xxx: Check for SCSI status on underruns. Signed-off-by: Arun Easi Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 2516adf..7b91b29 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1741,7 +1741,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) resid, scsi_bufflen(cp)); cp->result = DID_ERROR << 16 | lscsi_status; - break; + goto check_scsi_status; } if (!lscsi_status && -- cgit v0.10.2 From be5ea3cfa15ddef0bee9dfbc214c2113119087a2 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Fri, 18 Nov 2011 09:02:11 -0800 Subject: [SCSI] qla2xxx: Don't call alloc_fw_dump for ISP82XX. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f03e915f..54ea68c 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1509,7 +1509,8 @@ enable_82xx_npiv: &ha->fw_xcb_count, NULL, NULL, &ha->max_npiv_vports, NULL); - if (!fw_major_version && ql2xallocfwdump) + if (!fw_major_version && ql2xallocfwdump + && !IS_QLA82XX(ha)) qla2x00_alloc_fw_dump(vha); } } else { -- cgit v0.10.2 From 0cd33fcfb54f2eb053ead3cca35ad9775fc01301 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 18 Nov 2011 09:02:12 -0800 Subject: [SCSI] qla2xxx: Revert back the request queue mapping to request queue 0. If there is an error creating multiple response queues then we need to revert the request queue mapping back to request queue 0. Signed-off-by: Giridhar Malavali Signed-off-by: Andrew Vasquez Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 93673d3..01c8700 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -423,6 +423,7 @@ fail2: qla25xx_delete_queues(vha); destroy_workqueue(ha->wq); ha->wq = NULL; + vha->req = ha->req_q_map[0]; fail: ha->mqenable = 0; kfree(ha->req_q_map); -- cgit v0.10.2 From 841c5e5cee140115b03355c39e4c3f1798ec34bc Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 18 Nov 2011 09:02:13 -0800 Subject: [SCSI] qla2xxx: Stop unconditional completion of mailbox commands issued in interrupt mode during firmware hang. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 94bded5..d2005c3 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -4075,7 +4075,10 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) ha->flags.isp82xx_fw_hung = 1; if (ha->flags.mbox_busy) { ha->flags.mbox_int = 1; - complete(&ha->mbx_intr_comp); + if (test_bit(MBX_INTR_WAIT, + &ha->mbx_cmd_flags)) { + complete(&ha->mbx_intr_comp); + } } break; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 01c8700..abec1dd 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4014,7 +4014,10 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) ql_dbg(ql_dbg_aer, vha, 0x9001, "Due to pci channel io frozen, doing premature " "completion of mbx command.\n"); - complete(&ha->mbx_intr_comp); + if (test_bit(MBX_INTR_WAIT, + &ha->mbx_cmd_flags)) { + complete(&ha->mbx_intr_comp); + } } } qla2x00_free_irqs(vha); -- cgit v0.10.2 From 3aadff356bb80dae1ebb0a2e68974fdbb39fe034 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 18 Nov 2011 09:02:14 -0800 Subject: [SCSI] qla2xxx: Enable Minidump by default with default capture mask 0x1f. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index abec1dd..71d6259 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -201,12 +201,12 @@ MODULE_PARM_DESC(ql2xmdcapmask, "Set the Minidump driver capture mask level. " "Default is 0x7F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F."); -int ql2xmdenable; +int ql2xmdenable = 1; module_param(ql2xmdenable, int, S_IRUGO); MODULE_PARM_DESC(ql2xmdenable, "Enable/disable MiniDump. " - "0 (Default) - MiniDump disabled. " - "1 - MiniDump enabled."); + "0 - MiniDump disabled. " + "1 (Default) - MiniDump enabled."); /* * SCSI host template entry points -- cgit v0.10.2 From 1806fcd5d3d7644511e57b1d0a397837b0b38623 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 18 Nov 2011 09:02:15 -0800 Subject: [SCSI] qla2xxx: Return the correct value for a mailbox command if 82xx is in reset recovery. We need to return QLA_FUNCTION_TIMEOUT immediately otherwise we mess up the mailbox command state machine. Signed-off-by: Andrew Vasquez Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 3b3cec9..f965a57 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -79,8 +79,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) mcp->mb[0] = MBS_LINK_DOWN_ERROR; ql_log(ql_log_warn, base_vha, 0x1004, "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); - rval = QLA_FUNCTION_FAILED; - goto premature_exit; + return QLA_FUNCTION_TIMEOUT; } /* -- cgit v0.10.2 From 10a340e6415d938939724743a4da71fd63f5a95c Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Fri, 18 Nov 2011 09:02:16 -0800 Subject: [SCSI] qla2xxx: Display IPE error message for ISP82xx. [jejb: fixup checkpatch error] Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index d2005c3..8dd96da 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -3858,6 +3858,11 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) QLA82XX_CRB_PEG_NET_3 + 0x3c), qla82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c)); + if (LSW(MSB(halt_status)) == 0x67) + ql_log(ql_log_warn, vha, 0xb052, + "Firmware aborted with " + "error code 0x00006700. Device is " + "being reset.\n"); if (halt_status & HALT_STATUS_UNRECOVERABLE) { set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); -- cgit v0.10.2 From c8f6544e6d831f05720687f3536d5cbc290ff181 Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Fri, 18 Nov 2011 09:02:17 -0800 Subject: [SCSI] qla2xxx: Encapsulate prematurely completing mailbox commands during ISP82xx firmware hang. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 9df4787..e320d54 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -17,12 +17,12 @@ * | Queue Command and IO tracing | 0x302e | 0x3008 | * | DPC Thread | 0x401c | | * | Async Events | 0x5059 | | - * | Timer Routines | 0x600d | | + * | Timer Routines | 0x6010 | 0x600e,0x600f | * | User Space Interactions | 0x709d | | - * | Task Management | 0x8041 | | + * | Task Management | 0x8041 | 0x800b | * | AER/EEH | 0x900f | | * | Virtual Port | 0xa007 | | - * | ISP82XX Specific | 0xb051 | | + * | ISP82XX Specific | 0xb052 | | * | MultiQ | 0xc00b | | * | Misc | 0xd00b | | * ---------------------------------------------------------------------- diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index ce32d81..c0c11af 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -578,6 +578,7 @@ extern int qla82xx_check_md_needed(scsi_qla_host_t *); extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *); extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int); extern char *qdev_state(uint32_t); +extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *); /* BSG related functions */ extern int qla24xx_bsg_request(struct fc_bsg_job *); diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 8dd96da..60d999d 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -3817,6 +3817,19 @@ exit: return rval; } +void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + + if (ha->flags.mbox_busy) { + ha->flags.mbox_int = 1; + ql_log(ql_log_warn, vha, 0x6010, + "Doing premature completion of mbx command.\n"); + if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) + complete(&ha->mbx_intr_comp); + } +} + void qla82xx_watchdog(scsi_qla_host_t *vha) { uint32_t dev_state, halt_status; @@ -3874,16 +3887,8 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) } qla2xxx_wake_dpc(vha); ha->flags.isp82xx_fw_hung = 1; - if (ha->flags.mbox_busy) { - ha->flags.mbox_int = 1; - ql_log(ql_log_warn, vha, 0x6007, - "Due to FW hung, doing " - "premature completion of mbx " - "command.\n"); - if (test_bit(MBX_INTR_WAIT, - &ha->mbx_cmd_flags)) - complete(&ha->mbx_intr_comp); - } + ql_log(ql_log_warn, vha, 0x6007, "Firmware hung.\n"); + qla82xx_clear_pending_mbx(vha); } } } @@ -4078,13 +4083,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) msleep(1000); if (qla82xx_check_fw_alive(vha)) { ha->flags.isp82xx_fw_hung = 1; - if (ha->flags.mbox_busy) { - ha->flags.mbox_int = 1; - if (test_bit(MBX_INTR_WAIT, - &ha->mbx_cmd_flags)) { - complete(&ha->mbx_intr_comp); - } - } + qla82xx_clear_pending_mbx(vha); break; } } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 71d6259..f9e5b85 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4009,16 +4009,8 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) /* For ISP82XX complete any pending mailbox cmd */ if (IS_QLA82XX(ha)) { ha->flags.isp82xx_fw_hung = 1; - if (ha->flags.mbox_busy) { - ha->flags.mbox_int = 1; - ql_dbg(ql_dbg_aer, vha, 0x9001, - "Due to pci channel io frozen, doing premature " - "completion of mbx command.\n"); - if (test_bit(MBX_INTR_WAIT, - &ha->mbx_cmd_flags)) { - complete(&ha->mbx_intr_comp); - } - } + ql_dbg(ql_dbg_aer, vha, 0x9001, "Pci channel io frozen\n"); + qla82xx_clear_pending_mbx(vha); } qla2x00_free_irqs(vha); pci_disable_device(pdev); -- cgit v0.10.2 From 8937f2f1c4bc6a9098fd71eb4a7deba5f0683118 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 18 Nov 2011 09:02:18 -0800 Subject: [SCSI] qla2xxx: Clear mailbox busy flag during premature mailbox completion for ISP82xx. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index f965a57..6ff7c3c 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -162,6 +162,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) HINT_MBX_INT_PENDING) { spin_unlock_irqrestore(&ha->hardware_lock, flags); + ha->flags.mbox_busy = 0; ql_dbg(ql_dbg_mbx, base_vha, 0x1010, "Pending mailbox timeout, exiting.\n"); rval = QLA_FUNCTION_TIMEOUT; @@ -187,6 +188,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) HINT_MBX_INT_PENDING) { spin_unlock_irqrestore(&ha->hardware_lock, flags); + ha->flags.mbox_busy = 0; ql_dbg(ql_dbg_mbx, base_vha, 0x1012, "Pending mailbox timeout, exiting.\n"); rval = QLA_FUNCTION_TIMEOUT; diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 60d999d..54246f9 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -3823,6 +3823,7 @@ void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha) if (ha->flags.mbox_busy) { ha->flags.mbox_int = 1; + ha->flags.mbox_busy = 0; ql_log(ql_log_warn, vha, 0x6010, "Doing premature completion of mbx command.\n"); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) -- cgit v0.10.2 From 631549169801df054210839cfda0aceef78966af Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 18 Nov 2011 09:02:19 -0800 Subject: [SCSI] qla2xxx: Disable generating pause frames when firmware hang detected for ISP82xx. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index e320d54..f3cddd5 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -12,7 +12,7 @@ * | Level | Last Value Used | Holes | * ---------------------------------------------------------------------- * | Module Init and Probe | 0x0116 | | - * | Mailbox commands | 0x1129 | | + * | Mailbox commands | 0x112b | | * | Device Discovery | 0x2083 | | * | Queue Command and IO tracing | 0x302e | 0x3008 | * | DPC Thread | 0x401c | | diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 6ff7c3c..82a3353 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -303,7 +303,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { - + if (IS_QLA82XX(ha)) { + ql_dbg(ql_dbg_mbx, vha, 0x112a, + "disabling pause transmit on port " + "0 & 1.\n"); + qla82xx_wr_32(ha, + QLA82XX_CRB_NIU + 0x98, + CRB_NIU_XG_PAUSE_CTL_P0| + CRB_NIU_XG_PAUSE_CTL_P1); + } ql_log(ql_log_info, base_vha, 0x101c, "Mailbox cmd timeout occured. " "Scheduling ISP abort eeh_busy=0x%x.\n", @@ -319,7 +327,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { - + if (IS_QLA82XX(ha)) { + ql_dbg(ql_dbg_mbx, vha, 0x112b, + "disabling pause transmit on port " + "0 & 1.\n"); + qla82xx_wr_32(ha, + QLA82XX_CRB_NIU + 0x98, + CRB_NIU_XG_PAUSE_CTL_P0| + CRB_NIU_XG_PAUSE_CTL_P1); + } ql_log(ql_log_info, base_vha, 0x101e, "Mailbox cmd timeout occured. " "Scheduling ISP abort.\n"); diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 54246f9..0355493 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -3853,9 +3853,13 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) qla2xxx_wake_dpc(vha); } else { if (qla82xx_check_fw_alive(vha)) { + ql_dbg(ql_dbg_timer, vha, 0x6011, + "disabling pause transmit on port 0 & 1.\n"); + qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, + CRB_NIU_XG_PAUSE_CTL_P0|CRB_NIU_XG_PAUSE_CTL_P1); halt_status = qla82xx_rd_32(ha, QLA82XX_PEG_HALT_STATUS1); - ql_dbg(ql_dbg_timer, vha, 0x6005, + ql_log(ql_log_info, vha, 0x6005, "dumping hw/fw registers:.\n " " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,.\n " " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,.\n " diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 57820c1..57a226b 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h @@ -1173,4 +1173,8 @@ struct qla82xx_md_entry_queue { static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC, 0x410000B8, 0x410000BC }; + +#define CRB_NIU_XG_PAUSE_CTL_P0 0x1 +#define CRB_NIU_XG_PAUSE_CTL_P1 0x8 + #endif -- cgit v0.10.2 From 49e85c23beb1f12aba59450126ff7e803fbc767d Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Fri, 18 Nov 2011 09:02:20 -0800 Subject: [SCSI] qla2xxx: Correct fc_host port_state display. [jejb: checkpatch fixes] Add more fine grain parsing of vha->loop_state to export a more accurate fc_host port_state. Signed-off-by: Saurav Kashyap Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ac326c4..6465dae 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1762,12 +1762,31 @@ qla2x00_get_host_port_state(struct Scsi_Host *shost) scsi_qla_host_t *vha = shost_priv(shost); struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev); - if (!base_vha->flags.online) + if (!base_vha->flags.online) { fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; - else if (atomic_read(&base_vha->loop_state) == LOOP_TIMEOUT) - fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; - else + return; + } + + switch (atomic_read(&base_vha->loop_state)) { + case LOOP_UPDATE: + fc_host_port_state(shost) = FC_PORTSTATE_DIAGNOSTICS; + break; + case LOOP_DOWN: + if (test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags)) + fc_host_port_state(shost) = FC_PORTSTATE_DIAGNOSTICS; + else + fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; + break; + case LOOP_DEAD: + fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; + break; + case LOOP_READY: fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; + break; + default: + fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; + break; + } } static int -- cgit v0.10.2 From 0d2aa38ee9b11be35ef6f91c938dd3441cf64ea4 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 18 Nov 2011 09:02:21 -0800 Subject: [SCSI] qla2xxx: Submit all chained IOCBs for passthrough commands on request queue 0. Signed-off-by: Giridhar Malavali Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index dbec896..a4b267e 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -120,11 +120,10 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha) * Returns a pointer to the continuation type 1 IOCB packet. */ static inline cont_a64_entry_t * -qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha) +qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req) { cont_a64_entry_t *cont_pkt; - struct req_que *req = vha->req; /* Adjust ring index. */ req->ring_index++; if (req->ring_index == req->length) { @@ -292,7 +291,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, * Five DSDs are available in the Continuation * Type 1 IOCB. */ - cont_pkt = qla2x00_prep_cont_type1_iocb(vha); + cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; avail_dsds = 5; } @@ -684,7 +683,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, * Five DSDs are available in the Continuation * Type 1 IOCB. */ - cont_pkt = qla2x00_prep_cont_type1_iocb(vha); + cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; avail_dsds = 5; } @@ -2070,7 +2069,8 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) * Five DSDs are available in the Cont. * Type 1 IOCB. */ - cont_pkt = qla2x00_prep_cont_type1_iocb(vha); + cont_pkt = qla2x00_prep_cont_type1_iocb(vha, + vha->hw->req_q_map[0]); cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; avail_dsds = 5; cont_iocb_prsnt = 1; @@ -2096,6 +2096,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) int index; uint16_t tot_dsds; scsi_qla_host_t *vha = sp->fcport->vha; + struct qla_hw_data *ha = vha->hw; struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; int loop_iterartion = 0; int cont_iocb_prsnt = 0; @@ -2141,7 +2142,8 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) * Five DSDs are available in the Cont. * Type 1 IOCB. */ - cont_pkt = qla2x00_prep_cont_type1_iocb(vha); + cont_pkt = qla2x00_prep_cont_type1_iocb(vha, + ha->req_q_map[0]); cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; avail_dsds = 5; cont_iocb_prsnt = 1; -- cgit v0.10.2 From 09b4402d2c8e36b8d4270c4da235fd7bb312118d Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Fri, 18 Nov 2011 09:02:22 -0800 Subject: [SCSI] qla2xxx: Update version number to 8.03.07.12-k. Signed-off-by: Chad Dupuis Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 13b6357..23f33a6 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.07.07-k" +#define QLA2XXX_VERSION "8.03.07.12-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 -- cgit v0.10.2 From 4b5d8da88e3fab76700e89488a8c65c54facb9a3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 12 Dec 2011 16:02:15 -0200 Subject: Revert "[media] af9015: limit I2C access to keep FW happy" This reverts commit ff83bd82cb343d37b5ab8e402aaad9ef33d03f1e. As requested by Antti: From a talk with him at #linuxtv irc, he strong feeling that some apps like MythTV will do a lot a lot of I2C I/O and now it adds locks, with utimatelly means more delays. This could cause bad effects. There is a new patch for 3.3 that re-writes af9013 in order to limit I2C I/O. and thus those patches could be nice to have together because those user who has has problems are most likely MythTV users. So, let's revert this commit for now. Requested-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 033aa8a..c6c275b 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1093,80 +1093,9 @@ error: return ret; } -/* override demod callbacks for resource locking */ -static int af9015_af9013_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - int ret; - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct af9015_state *priv = adap->dev->priv; - - if (mutex_lock_interruptible(&adap->dev->usb_mutex)) - return -EAGAIN; - - ret = priv->set_frontend[adap->id](fe, params); - - mutex_unlock(&adap->dev->usb_mutex); - - return ret; -} - -/* override demod callbacks for resource locking */ -static int af9015_af9013_read_status(struct dvb_frontend *fe, - fe_status_t *status) -{ - int ret; - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct af9015_state *priv = adap->dev->priv; - - if (mutex_lock_interruptible(&adap->dev->usb_mutex)) - return -EAGAIN; - - ret = priv->read_status[adap->id](fe, status); - - mutex_unlock(&adap->dev->usb_mutex); - - return ret; -} - -/* override demod callbacks for resource locking */ -static int af9015_af9013_init(struct dvb_frontend *fe) -{ - int ret; - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct af9015_state *priv = adap->dev->priv; - - if (mutex_lock_interruptible(&adap->dev->usb_mutex)) - return -EAGAIN; - - ret = priv->init[adap->id](fe); - - mutex_unlock(&adap->dev->usb_mutex); - - return ret; -} - -/* override demod callbacks for resource locking */ -static int af9015_af9013_sleep(struct dvb_frontend *fe) -{ - int ret; - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct af9015_state *priv = adap->dev->priv; - - if (mutex_lock_interruptible(&adap->dev->usb_mutex)) - return -EAGAIN; - - ret = priv->init[adap->id](fe); - - mutex_unlock(&adap->dev->usb_mutex); - - return ret; -} - static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { int ret; - struct af9015_state *state = adap->dev->priv; if (adap->id == 1) { /* copy firmware to 2nd demodulator */ @@ -1187,32 +1116,6 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], &adap->dev->i2c_adap); - /* - * AF9015 firmware does not like if it gets interrupted by I2C adapter - * request on some critical phases. During normal operation I2C adapter - * is used only 2nd demodulator and tuner on dual tuner devices. - * Override demodulator callbacks and use mutex for limit access to - * those "critical" paths to keep AF9015 happy. - * Note: we abuse unused usb_mutex here. - */ - if (adap->fe_adap[0].fe) { - state->set_frontend[adap->id] = - adap->fe_adap[0].fe->ops.set_frontend; - adap->fe_adap[0].fe->ops.set_frontend = - af9015_af9013_set_frontend; - - state->read_status[adap->id] = - adap->fe_adap[0].fe->ops.read_status; - adap->fe_adap[0].fe->ops.read_status = - af9015_af9013_read_status; - - state->init[adap->id] = adap->fe_adap[0].fe->ops.init; - adap->fe_adap[0].fe->ops.init = af9015_af9013_init; - - state->sleep[adap->id] = adap->fe_adap[0].fe->ops.sleep; - adap->fe_adap[0].fe->ops.sleep = af9015_af9013_sleep; - } - return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 4a12617..6252ea6 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -102,13 +102,6 @@ struct af9015_state { u8 rc_repeat; u32 rc_keycode; u8 rc_last[4]; - - /* for demod callback override */ - int (*set_frontend[2]) (struct dvb_frontend *fe, - struct dvb_frontend_parameters *params); - int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); - int (*init[2]) (struct dvb_frontend *fe); - int (*sleep[2]) (struct dvb_frontend *fe); }; struct af9015_config { -- cgit v0.10.2 From 123877b80ed62c3b897c53357b622574c023b642 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 8 Dec 2011 15:52:00 -0800 Subject: iwlwifi: do not set the sequence control bit is not needed Check the IEEE80211_TX_CTL_ASSIGN_SEQ flag from mac80211, then decide how to set the TX_CMD_FLG_SEQ_CTL_MSK bit. Setting the wrong bit in BAR frame whill make the firmware to increment the sequence number which is incorrect and cause unknown behavior. CC: stable@vger.kernel.org #3.0+ Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 35a6b71..df1540c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -91,7 +91,10 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, tx_cmd->tid_tspec = qc[0] & 0xf; tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; } else { - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + else + tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; } iwlagn_tx_cmd_protection(priv, info, fc, &tx_flags); -- cgit v0.10.2 From f8c141c3e915e3a040d4c1badde28e23f8cbe255 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 9 Dec 2011 09:35:39 +0300 Subject: nfc: signedness bug in __nci_request() wait_for_completion_interruptible_timeout() returns -ERESTARTSYS if interrupted so completion_rc needs to be signed. The current code probably returns -ETIMEDOUT if we hit this situation, but after this patch is applied it will return -ERESTARTSYS. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 4047e29..25dae3f 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -68,7 +68,7 @@ static int __nci_request(struct nci_dev *ndev, __u32 timeout) { int rc = 0; - unsigned long completion_rc; + long completion_rc; ndev->req_status = NCI_REQ_PEND; -- cgit v0.10.2 From 10636bc2d60942254bda149827b922c41f4cb4af Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 10 Dec 2011 18:59:43 +0530 Subject: ath9k: fix max phy rate at rate control init The stations always chooses 1Mbps for all trasmitting frames, whenever the AP is configured to lock the supported rates. As the max phy rate is always set with the 4th from highest phy rate, this assumption might be wrong if we have less than that. Fix that. Cc: stable@kernel.org Cc: Paul Stewart Reported-by: Ajay Gummalla Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 8448281..cc5703b 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1270,7 +1270,9 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_priv->max_valid_rate = k; ath_rc_sort_validrates(rate_table, ath_rc_priv); - ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; + ath_rc_priv->rate_max_phy = (k > 4) ? + ath_rc_priv->valid_rate_index[k-4] : + ath_rc_priv->valid_rate_index[k-1]; ath_rc_priv->rate_table = rate_table; ath_dbg(common, ATH_DBG_CONFIG, -- cgit v0.10.2 From f88e1ae8acb8affac29034ed79d4fff95ac8c29d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 12 Dec 2011 09:26:00 -0700 Subject: dt/device: Fix auxdata matching to handle entries without a name override There is no requirement to override name entries in auxdata. Fix the entry matching to use .compatible instead of .name to find the end of the list. Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index cbd5d70..63b3ec4 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -314,7 +314,7 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l if (!lookup) return NULL; - for(; lookup->name != NULL; lookup++) { + for(; lookup->compatible != NULL; lookup++) { if (!of_device_is_compatible(np, lookup->compatible)) continue; if (of_address_to_resource(np, 0, &res)) -- cgit v0.10.2 From 958cab0fbe13dc89b6f779d495fed283c0e7de5a Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 11 Dec 2011 10:04:00 +0000 Subject: ARM: Allow Kconfig to control the definition of NR_BANKS Move the sizing of NR_BANKS to a Kconfig control instead of selecting it in a header file depending on platform selection. This allows new additions to its dependencies to be handled more gracefully. Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e084b7e..928cbcc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1125,6 +1125,11 @@ config ARM_TIMER_SP804 source arch/arm/mm/Kconfig +config ARM_NR_BANKS + int + default 16 if ARCH_EP93XX + default 8 + config IWMMXT bool "Enable iWMMXt support" depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 915696d..23ebc0c 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -192,11 +192,7 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn } /* * Memory map description */ -#ifdef CONFIG_ARCH_EP93XX -# define NR_BANKS 16 -#else -# define NR_BANKS 8 -#endif +#define NR_BANKS CONFIG_ARM_NR_BANKS struct membank { phys_addr_t start; -- cgit v0.10.2 From 90b9222ec632bc8b262981768c7b16f7e67dfe58 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 12 Dec 2011 09:24:40 +0100 Subject: ARM: 7199/2: only look for TCM on ARMv5 and later The Integrator AP/CP can have a varying set of core modules, some (like ARM920T) are so old that trying to read the TCM status register with CP15 will make them hang. So we need to make sure that we are running on v5 or later in order to be able to activate this for the Integrator. (The Integrator with CM926EJ-S has 32+32 kb of TCM memory.) Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index 30e302d..01ec453 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -180,9 +180,9 @@ static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, */ void __init tcm_init(void) { - u32 tcm_status = read_cpuid_tcmstatus(); - u8 dtcm_banks = (tcm_status >> 16) & 0x03; - u8 itcm_banks = (tcm_status & 0x03); + u32 tcm_status; + u8 dtcm_banks; + u8 itcm_banks; size_t dtcm_code_sz = &__edtcm_data - &__sdtcm_data; size_t itcm_code_sz = &__eitcm_text - &__sitcm_text; char *start; @@ -191,6 +191,22 @@ void __init tcm_init(void) int ret; int i; + /* + * Prior to ARMv5 there is no TCM, and trying to read the status + * register will hang the processor. + */ + if (cpu_architecture() < CPU_ARCH_ARMv5) { + if (dtcm_code_sz || itcm_code_sz) + pr_info("CPU TCM: %u bytes of DTCM and %u bytes of " + "ITCM code compiled in, but no TCM present " + "in pre-v5 CPU\n", dtcm_code_sz, itcm_code_sz); + return; + } + + tcm_status = read_cpuid_tcmstatus(); + dtcm_banks = (tcm_status >> 16) & 0x03; + itcm_banks = (tcm_status & 0x03); + /* Values greater than 2 for D/ITCM banks are "reserved" */ if (dtcm_banks > 2) dtcm_banks = 0; -- cgit v0.10.2 From 9904f7933bd3b6aef880f7a91ddd8b19420ffd11 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 9 Dec 2011 10:29:23 +0100 Subject: ARM: 7200/1: activate TCM on the Integrator Some Integrator core modules have TCM memory, so let's turn it on if it's there. Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 928cbcc..e063d34 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -257,6 +257,7 @@ config ARCH_INTEGRATOR select ARCH_HAS_CPUFREQ select CLKDEV_LOOKUP select HAVE_MACH_CLKDEV + select HAVE_TCM select ICST select GENERIC_CLOCKEVENTS select PLAT_VERSATILE -- cgit v0.10.2 From 0c9030deaf59d444f9e757ee73d6d81bfe2d3376 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Mon, 12 Dec 2011 19:31:55 +0100 Subject: ARM: 7206/1: Add generic ARM instruction set condition code checks. This patch breaks the ARM condition checking code out of nwfpe/fpopcode.{ch} into a standalone file for opcode operations. It also modifies the code somewhat for coding style adherence, and adds some temporary variables for increased readability. Signed-off-by: Leif Lindholm Reviewed-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h new file mode 100644 index 0000000..c0efdd6 --- /dev/null +++ b/arch/arm/include/asm/opcodes.h @@ -0,0 +1,20 @@ +/* + * arch/arm/include/asm/opcodes.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARM_OPCODES_H +#define __ASM_ARM_OPCODES_H + +#ifndef __ASSEMBLY__ +extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); +#endif + +#define ARM_OPCODE_CONDTEST_FAIL 0 +#define ARM_OPCODE_CONDTEST_PASS 1 +#define ARM_OPCODE_CONDTEST_UNCOND 2 + +#endif /* __ASM_ARM_OPCODES_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 16eed6a..43b740d 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -13,7 +13,7 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := elf.o entry-armv.o entry-common.o irq.o \ +obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o setup.o signal.o \ sys_arm.o stacktrace.o time.o traps.o diff --git a/arch/arm/kernel/opcodes.c b/arch/arm/kernel/opcodes.c new file mode 100644 index 0000000..f8179c6 --- /dev/null +++ b/arch/arm/kernel/opcodes.c @@ -0,0 +1,72 @@ +/* + * linux/arch/arm/kernel/opcodes.c + * + * A32 condition code lookup feature moved from nwfpe/fpopcode.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#define ARM_OPCODE_CONDITION_UNCOND 0xf + +/* + * condition code lookup table + * index into the table is test code: EQ, NE, ... LT, GT, AL, NV + * + * bit position in short is condition code: NZCV + */ +static const unsigned short cc_map[16] = { + 0xF0F0, /* EQ == Z set */ + 0x0F0F, /* NE */ + 0xCCCC, /* CS == C set */ + 0x3333, /* CC */ + 0xFF00, /* MI == N set */ + 0x00FF, /* PL */ + 0xAAAA, /* VS == V set */ + 0x5555, /* VC */ + 0x0C0C, /* HI == C set && Z clear */ + 0xF3F3, /* LS == C clear || Z set */ + 0xAA55, /* GE == (N==V) */ + 0x55AA, /* LT == (N!=V) */ + 0x0A05, /* GT == (!Z && (N==V)) */ + 0xF5FA, /* LE == (Z || (N!=V)) */ + 0xFFFF, /* AL always */ + 0 /* NV */ +}; + +/* + * Returns: + * ARM_OPCODE_CONDTEST_FAIL - if condition fails + * ARM_OPCODE_CONDTEST_PASS - if condition passes (including AL) + * ARM_OPCODE_CONDTEST_UNCOND - if NV condition, or separate unconditional + * opcode space from v5 onwards + * + * Code that tests whether a conditional instruction would pass its condition + * check should check that return value == ARM_OPCODE_CONDTEST_PASS. + * + * Code that tests if a condition means that the instruction would be executed + * (regardless of conditional or unconditional) should instead check that the + * return value != ARM_OPCODE_CONDTEST_FAIL. + */ +asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr) +{ + u32 cc_bits = opcode >> 28; + u32 psr_cond = psr >> 28; + unsigned int ret; + + if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) { + if ((cc_map[cc_bits] >> (psr_cond)) & 1) + ret = ARM_OPCODE_CONDTEST_PASS; + else + ret = ARM_OPCODE_CONDTEST_FAIL; + } else { + ret = ARM_OPCODE_CONDTEST_UNCOND; + } + + return ret; +} +EXPORT_SYMBOL_GPL(arm_check_condition); -- cgit v0.10.2 From e7f626db83689f55089717a6d771c57afe1adc1a Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Mon, 12 Dec 2011 19:44:49 +0100 Subject: ARM: 7207/1: Use generic ARM instruction set condition code checks for nwfpe. This patch changes the nwfpe implementation to use the new generic ARM instruction set condition code checks, rather than a local implementation. It also removes the existing condition code checking, which has been used for the generic support (in kernel/opcodes.{ch}). This code has not been tested beyond building, linking and booting. Signed-off-by: Leif Lindholm Reviewed-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S index cafa183..d18dde9 100644 --- a/arch/arm/nwfpe/entry.S +++ b/arch/arm/nwfpe/entry.S @@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + /* This is the kernel's entry point into the floating point emulator. It is called from the kernel with code similar to this: @@ -81,11 +83,11 @@ nwfpe_enter: mov r6, r0 @ save the opcode emulate: ldr r1, [sp, #S_PSR] @ fetch the PSR - bl checkCondition @ check the condition - cmp r0, #0 @ r0 = 0 ==> condition failed + bl arm_check_condition @ check the condition + cmp r0, #ARM_OPCODE_CONDTEST_PASS @ condition passed? @ if condition code failed to match, next insn - beq next @ get the next instruction; + bne next @ get the next instruction; mov r0, r6 @ prepare for EmulateAll() bl EmulateAll @ emulate the instruction diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c index 922b811..ff983467 100644 --- a/arch/arm/nwfpe/fpopcode.c +++ b/arch/arm/nwfpe/fpopcode.c @@ -61,29 +61,3 @@ const float32 float32Constant[] = { 0x41200000 /* single 10.0 */ }; -/* condition code lookup table - index into the table is test code: EQ, NE, ... LT, GT, AL, NV - bit position in short is condition code: NZCV */ -static const unsigned short aCC[16] = { - 0xF0F0, // EQ == Z set - 0x0F0F, // NE - 0xCCCC, // CS == C set - 0x3333, // CC - 0xFF00, // MI == N set - 0x00FF, // PL - 0xAAAA, // VS == V set - 0x5555, // VC - 0x0C0C, // HI == C set && Z clear - 0xF3F3, // LS == C clear || Z set - 0xAA55, // GE == (N==V) - 0x55AA, // LT == (N!=V) - 0x0A05, // GT == (!Z && (N==V)) - 0xF5FA, // LE == (Z || (N!=V)) - 0xFFFF, // AL always - 0 // NV -}; - -unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes) -{ - return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1; -} diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h index 786e4c9..78f02db 100644 --- a/arch/arm/nwfpe/fpopcode.h +++ b/arch/arm/nwfpe/fpopcode.h @@ -475,9 +475,6 @@ static inline unsigned int getDestinationSize(const unsigned int opcode) return (nRc); } -extern unsigned int checkCondition(const unsigned int opcode, - const unsigned int ccodes); - extern const float64 float64Constant[]; extern const float32 float32Constant[]; -- cgit v0.10.2 From c245dcd326fb9f8cca4b396796f0d2e54171b5c9 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Mon, 12 Dec 2011 19:45:24 +0100 Subject: ARM: 7208/1: Add condition code checking to SWP emulation handler. This patch fixes two separate issues with the SWP emulation handler: 1: Certain processors implementing ARMv7-A can (legally) take an undef exception even when the condition code would have meant that the instruction should not have been executed. 2: Opcodes with all flags set (condition code = 0xf) have been reused in recent, and not-so-recent, versions of the ARM architecture to implement unconditional extensions to the instruction set. The existing code would still have processed any undefs triggered by executing an opcode with such a value. This patch uses the new generic ARM instruction set condition code checks to implement proper handling of these situations. Signed-off-by: Leif Lindholm Reviewed-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 5f452f8..df74518 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -185,6 +186,21 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr) perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->ARM_pc); + res = arm_check_condition(instr, regs->ARM_cpsr); + switch (res) { + case ARM_OPCODE_CONDTEST_PASS: + break; + case ARM_OPCODE_CONDTEST_FAIL: + /* Condition failed - return to next instruction */ + regs->ARM_pc += 4; + return 0; + case ARM_OPCODE_CONDTEST_UNCOND: + /* If unconditional encoding - not a SWP, undef */ + return -EFAULT; + default: + return -EINVAL; + } + if (current->pid != previous_pid) { pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n", current->comm, (unsigned long)current->pid); -- cgit v0.10.2 From c41584ddc1b9c7d06726057456d188d4eefec60b Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Mon, 12 Dec 2011 19:45:36 +0100 Subject: ARM: 7209/1: Use generic ARM instruction set condition code checks for kprobes. This patch changes the kprobes implementation to use the generic ARM instruction set condition code checks, rather than a dedicated implementation. Signed-off-by: Leif Lindholm Acked-by: Jon Medhurst Reviewed-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c index e17cdd6..1862d8f 100644 --- a/arch/arm/kernel/kprobes-test.c +++ b/arch/arm/kernel/kprobes-test.c @@ -202,6 +202,8 @@ #include #include +#include + #include "kprobes.h" #include "kprobes-test.h" @@ -1050,65 +1052,9 @@ static int test_instance; static unsigned long test_check_cc(int cc, unsigned long cpsr) { - unsigned long temp; - - switch (cc) { - case 0x0: /* eq */ - return cpsr & PSR_Z_BIT; - - case 0x1: /* ne */ - return (~cpsr) & PSR_Z_BIT; - - case 0x2: /* cs */ - return cpsr & PSR_C_BIT; - - case 0x3: /* cc */ - return (~cpsr) & PSR_C_BIT; - - case 0x4: /* mi */ - return cpsr & PSR_N_BIT; - - case 0x5: /* pl */ - return (~cpsr) & PSR_N_BIT; - - case 0x6: /* vs */ - return cpsr & PSR_V_BIT; - - case 0x7: /* vc */ - return (~cpsr) & PSR_V_BIT; + int ret = arm_check_condition(cc << 28, cpsr); - case 0x8: /* hi */ - cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ - return cpsr & PSR_C_BIT; - - case 0x9: /* ls */ - cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ - return (~cpsr) & PSR_C_BIT; - - case 0xa: /* ge */ - cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - return (~cpsr) & PSR_N_BIT; - - case 0xb: /* lt */ - cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - return cpsr & PSR_N_BIT; - - case 0xc: /* gt */ - temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ - return (~temp) & PSR_N_BIT; - - case 0xd: /* le */ - temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ - temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ - return temp & PSR_N_BIT; - - case 0xe: /* al */ - case 0xf: /* unconditional */ - return true; - } - BUG(); - return false; + return (ret != ARM_OPCODE_CONDTEST_FAIL); } static int is_last_scenario; @@ -1128,7 +1074,9 @@ static unsigned long test_context_cpsr(int scenario) if (!test_case_is_thumb) { /* Testing ARM code */ - probe_should_run = test_check_cc(current_instruction >> 28, cpsr) != 0; + int cc = current_instruction >> 28; + + probe_should_run = test_check_cc(cc, cpsr) != 0; if (scenario == 15) is_last_scenario = true; -- cgit v0.10.2 From 619a5182d1f38a3d629ee48e04fa182ef9170052 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 13 Dec 2011 00:02:28 +0100 Subject: PCI hotplug: Always allow acpiphp to handle non-PCIe bridges Commit 0d52f54e2ef64c189dedc332e680b2eb4a34590a (PCI / ACPI: Make acpiphp ignore root bridges using PCIe native hotplug) added code that made the acpiphp driver completely ignore PCIe root complexes for which the kernel had been granted control of the native PCIe hotplug feature by the BIOS through _OSC. Unfortunately, however, this was a mistake, because on some systems there were PCI bridges supporting PCI (non-PCIe) hotplug under such root complexes and those bridges should have been handled by acpiphp. For this reason, revert the changes made by the commit mentioned above and make register_slot() in drivers/pci/hotplug/acpiphp_glue.c avoid registering hotplug slots for PCIe ports that belong to root complexes with native PCIe hotplug enabled (which means that the BIOS has granted the kernel control of this feature for the given root complex). This is reported to address the original issue fixed by commit 0d52f54e2ef64c189dedc332e680b2eb4a34590a and to work on the system where that commit broke things. Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index fce1c54..68360d5 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -132,6 +132,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; + pdev = pbus->self; + if (pdev && pci_is_pcie(pdev)) { + tmp = acpi_find_root_bridge_handle(pdev); + if (tmp) { + struct acpi_pci_root *root = acpi_pci_find_root(tmp); + + if (root && (root->osc_control_set & + OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) + return AE_OK; + } + } + acpi_evaluate_integer(handle, "_ADR", NULL, &adr); device = (adr >> 16) & 0xffff; function = adr & 0xffff; @@ -459,17 +471,8 @@ static int add_bridge(acpi_handle handle) { acpi_status status; unsigned long long tmp; - struct acpi_pci_root *root; acpi_handle dummy_handle; - /* - * We shouldn't use this bridge if PCIe native hotplug control has been - * granted by the BIOS for it. - */ - root = acpi_pci_find_root(handle); - if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) - return -ENODEV; - /* if the bridge doesn't have _STA, we assume it is always there */ status = acpi_get_handle(handle, "_STA", &dummy_handle); if (ACPI_SUCCESS(status)) { @@ -1385,19 +1388,11 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, static acpi_status find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { - struct acpi_pci_root *root; int *count = (int *)context; if (!acpi_is_root_bridge(handle)) return AE_OK; - root = acpi_pci_find_root(handle); - if (!root) - return AE_OK; - - if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) - return AE_OK; - (*count)++; acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge, NULL); -- cgit v0.10.2 From 93b2ec0128c431148b216b8f7337c1a52131ef03 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Dec 2011 09:39:15 +1100 Subject: rtc: Expire alarms after the time is set. If the alarm time programming in the rtc is ever in the past, it won't fire, and any other alarm will be queued after it so they won't fire either. So any time that the alarm might be in the past, we need to trigger the irq handler to ensure the old alarm is cleared and the timer queue is fully in the future. This can happen: - when we first initialise the alarm - when we set the time in the rtc. so follow both of these by scheduling the timer work function. CC: stable@kernel.org Signed-off-by: NeilBrown [Also catch set_mmss case -jstultz] Signed-off-by: John Stultz diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index fa4d9f3..3bcc7cf 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } @@ -403,6 +407,8 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); } mutex_unlock(&rtc->ops_lock); + /* maybe that was in the past.*/ + schedule_work(&rtc->irqwork); return err; } EXPORT_SYMBOL_GPL(rtc_initialize_alarm); -- cgit v0.10.2 From c3b79770e51ab1fd4201f3b54edf30113b9ce74f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 12 Dec 2011 13:57:52 -0800 Subject: rtc: m41t80: Workaround broken alarm functionality The m41t80 driver can read and set the alarm, but it doesn't seem to have a functional alarm irq. This causes failures when the generic core sees alarm functions, but then cannot use them properly for things like UIE mode. Disabling the alarm functions allows proper error reporting, and possible fallback to emulated modes. Once someone fixes the alarm irq functionality, this can be restored. CC: stable@kernel.org CC: Matt Turner CC: Nico Macrionitis CC: Atsushi Nemoto Reported-by: Matt Turner Reported-by: Nico Macrionitis Tested-by: Nico Macrionitis Signed-off-by: John Stultz diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index eda128f..64aedd8 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -357,10 +357,19 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) static struct rtc_class_ops m41t80_rtc_ops = { .read_time = m41t80_rtc_read_time, .set_time = m41t80_rtc_set_time, + /* + * XXX - m41t80 alarm functionality is reported broken. + * until it is fixed, don't register alarm functions. + * .read_alarm = m41t80_rtc_read_alarm, .set_alarm = m41t80_rtc_set_alarm, + */ .proc = m41t80_rtc_proc, + /* + * See above comment on broken alarm + * .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, + */ }; #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) -- cgit v0.10.2 From ccc080c77cd47fde5eb097058fae930b956096eb Mon Sep 17 00:00:00 2001 From: Ajay Kumar Gupta Date: Tue, 13 Dec 2011 10:32:42 +0530 Subject: usb: musb: fix reset issue with full speed device TXMAXP register is not getting programmed correctly for a full speed device as can_bulk_split() have been removed by "0662481: usb: musb: disable double buffering when it's broken" patch. Adding back the case for can_bulk_split() to fix the reset message seen with a full speed stick. Signed-off-by: Ajay Kumar Gupta Signed-off-by: Felipe Balbi diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 60ddba8..79cb0af 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -774,6 +774,10 @@ static void musb_ep_program(struct musb *musb, u8 epnum, if (musb->double_buffer_not_ok) musb_writew(epio, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); + else if (can_bulk_split(musb, qh->type)) + musb_writew(epio, MUSB_TXMAXP, packet_sz + | ((hw_ep->max_packet_sz_tx / + packet_sz) - 1) << 11); else musb_writew(epio, MUSB_TXMAXP, qh->maxpacket | -- cgit v0.10.2 From 44b7f4b98d8877e2a4427f2a2f2e42ae8227a58f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 13 Dec 2011 20:40:45 +0100 Subject: perf events: Fix ring_buffer_wakeup() brown paperbag bug Commit 10c6db11 ("perf: Fix loss of notification with multi-event") seems to unconditionally dereference event->rb in the wakeup handler, this is wrong, there might not be a buffer attached. Signed-off-by: Will Deacon Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20111213152651.GP20297@mudshark.cambridge.arm.com [ minor edits ] Signed-off-by: Ingo Molnar diff --git a/kernel/events/core.c b/kernel/events/core.c index d3b9df5..58690af 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3558,9 +3558,13 @@ static void ring_buffer_wakeup(struct perf_event *event) rcu_read_lock(); rb = rcu_dereference(event->rb); - list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { + if (!rb) + goto unlock; + + list_for_each_entry_rcu(event, &rb->event_list, rb_entry) wake_up_all(&event->waitq); - } + +unlock: rcu_read_unlock(); } -- cgit v0.10.2 From 7e1e7ead88dff75b11b86ee0d5232c4591be1326 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 11 Nov 2011 20:52:01 +0100 Subject: [SCSI] fcoe: Fix preempt count leak in fcoe_filter_frames() The error exit path leaks preempt count. Add the missing put_cpu(). Signed-off-by: Thomas Gleixner Reviewed-by: Yi Zou Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index cefbe44..f3f440c 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1624,6 +1624,7 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, stats->InvalidCRCCount++; if (stats->InvalidCRCCount < 5) printk(KERN_WARNING "fcoe: dropping frame with CRC error\n"); + put_cpu(); return -EINVAL; } -- cgit v0.10.2 From 44f747fff6e9f027a4866c1a6864e26ae7c510c8 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Fri, 18 Nov 2011 20:00:40 +0100 Subject: [SCSI] zfcp: return early from slave_destroy if slave_alloc returned early zfcp_scsi_slave_destroy erroneously always tried to finish its task even if the corresponding previous zfcp_scsi_slave_alloc returned early. This can lead to kernel page faults on accessing uninitialized fields of struct zfcp_scsi_dev in zfcp_erp_lun_shutdown_wait. Take the port field of the struct to determine if slave_alloc returned early. This zfcp bug is exposed by 4e6c82b (in turn fixing f7c9c6b to be compatible with 21208ae) which can call slave_destroy for a corresponding previous slave_alloc that did not finish. This patch is based on James Bottomley's fix suggestion in http://www.spinics.net/lists/linux-scsi/msg55449.html. Signed-off-by: Steffen Maier Cc: #2.6.38+ Signed-off-by: James Bottomley diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 11f07f8..b79576b 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -55,6 +55,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) { struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); + /* if previous slave_alloc returned early, there is nothing to do */ + if (!zfcp_sdev->port) + return; + zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); put_device(&zfcp_sdev->port->dev); } -- cgit v0.10.2 From 13483730a13bef372894aefcf73760f5c6c297be Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 1 Dec 2011 21:38:41 -0600 Subject: [SCSI] qla4xxx: fix flash/ddb support With open-iscsi support, target entries persisted in the FLASH were not login. Added support in the qla4xxx driver to do the login on probe time to the target entries saved in the FLASH by user. With this changes upgrade to the new kernel with open-iscsi support in qla4xxx will ensure users original target entries login on driver load Signed-off-by: Manish Rangankar Signed-off-by: Ravi Anand Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index ace637b..fd5edc6 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -147,7 +147,7 @@ #define ISCSI_ALIAS_SIZE 32 /* ISCSI Alias name size */ #define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size */ -#define QL4_SESS_RECOVERY_TMO 30 /* iSCSI session */ +#define QL4_SESS_RECOVERY_TMO 120 /* iSCSI session */ /* recovery timeout */ #define LSDW(x) ((u32)((u64)(x))) @@ -173,6 +173,8 @@ #define ISNS_DEREG_TOV 5 #define HBA_ONLINE_TOV 30 #define DISABLE_ACB_TOV 30 +#define IP_CONFIG_TOV 30 +#define LOGIN_TOV 12 #define MAX_RESET_HA_RETRIES 2 @@ -240,6 +242,45 @@ struct ddb_entry { uint16_t fw_ddb_index; /* DDB firmware index */ uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ + uint16_t ddb_type; +#define FLASH_DDB 0x01 + + struct dev_db_entry fw_ddb_entry; + int (*unblock_sess)(struct iscsi_cls_session *cls_session); + int (*ddb_change)(struct scsi_qla_host *ha, uint32_t fw_ddb_index, + struct ddb_entry *ddb_entry, uint32_t state); + + /* Driver Re-login */ + unsigned long flags; /* DDB Flags */ + uint16_t default_relogin_timeout; /* Max time to wait for + * relogin to complete */ + atomic_t retry_relogin_timer; /* Min Time between relogins + * (4000 only) */ + atomic_t relogin_timer; /* Max Time to wait for + * relogin to complete */ + atomic_t relogin_retry_count; /* Num of times relogin has been + * retried */ + uint32_t default_time2wait; /* Default Min time between + * relogins (+aens) */ + +}; + +struct qla_ddb_index { + struct list_head list; + uint16_t fw_ddb_idx; + struct dev_db_entry fw_ddb; +}; + +#define DDB_IPADDR_LEN 64 + +struct ql4_tuple_ddb { + int port; + int tpgt; + char ip_addr[DDB_IPADDR_LEN]; + char iscsi_name[ISCSI_NAME_SIZE]; + uint16_t options; +#define DDB_OPT_IPV6 0x0e0e +#define DDB_OPT_IPV4 0x0f0f }; /* @@ -411,7 +452,7 @@ struct scsi_qla_host { #define AF_FW_RECOVERY 19 /* 0x00080000 */ #define AF_EEH_BUSY 20 /* 0x00100000 */ #define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */ - +#define AF_BUILD_DDB_LIST 22 /* 0x00400000 */ unsigned long dpc_flags; #define DPC_RESET_HA 1 /* 0x00000002 */ @@ -604,6 +645,7 @@ struct scsi_qla_host { uint16_t bootload_minor; uint16_t bootload_patch; uint16_t bootload_build; + uint16_t def_timeout; /* Default login timeout */ uint32_t flash_state; #define QLFLASH_WAITING 0 @@ -623,6 +665,11 @@ struct scsi_qla_host { uint16_t iscsi_pci_func_cnt; uint8_t model_name[16]; struct completion disable_acb_comp; + struct dma_pool *fw_ddb_dma_pool; +#define DDB_DMA_BLOCK_SIZE 512 + uint16_t pri_ddb_idx; + uint16_t sec_ddb_idx; + int is_reset; }; struct ql4_task_data { @@ -835,6 +882,10 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha) /*---------------------------------------------------------------------------*/ /* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ + +#define INIT_ADAPTER 0 +#define RESET_ADAPTER 1 + #define PRESERVE_DDB_LIST 0 #define REBUILD_DDB_LIST 1 diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index cbd5a20..4ac07f8 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h @@ -12,6 +12,7 @@ #define MAX_PRST_DEV_DB_ENTRIES 64 #define MIN_DISC_DEV_DB_ENTRY MAX_PRST_DEV_DB_ENTRIES #define MAX_DEV_DB_ENTRIES 512 +#define MAX_DEV_DB_ENTRIES_40XX 256 /************************************************************************* * @@ -604,6 +605,13 @@ struct addr_ctrl_blk { uint8_t res14[140]; /* 274-2FF */ }; +#define IP_ADDR_COUNT 4 /* Total 4 IP address supported in one interface + * One IPv4, one IPv6 link local and 2 IPv6 + */ + +#define IP_STATE_MASK 0x0F000000 +#define IP_STATE_SHIFT 24 + struct init_fw_ctrl_blk { struct addr_ctrl_blk pri; /* struct addr_ctrl_blk sec;*/ diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 160db9d..d0dd4b3 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -13,7 +13,7 @@ struct iscsi_cls_conn; int qla4xxx_hw_reset(struct scsi_qla_host *ha); int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb); -int qla4xxx_initialize_adapter(struct scsi_qla_host *ha); +int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset); int qla4xxx_soft_reset(struct scsi_qla_host *ha); irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); @@ -153,10 +153,13 @@ int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index, uint32_t *mbx_sts); int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index); int qla4xxx_send_passthru0(struct iscsi_task *task); +void qla4xxx_free_ddb_index(struct scsi_qla_host *ha); int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index, uint16_t stats_size, dma_addr_t stats_dma); void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry); +void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry); int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha, struct dev_db_entry *fw_ddb_entry, dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index); @@ -169,11 +172,22 @@ int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, uint32_t region, uint32_t field0, uint32_t field1); +int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index); +void qla4xxx_login_flash_ddb(struct iscsi_cls_session *cls_session); +int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session); +int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session); +int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, + struct ddb_entry *ddb_entry, uint32_t state); +int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, + struct ddb_entry *ddb_entry, uint32_t state); +void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset); /* BSG Functions */ int qla4xxx_bsg_request(struct bsg_job *bsg_job); int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job); +void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry); + extern int ql4xextended_error_logging; extern int ql4xdontresethba; extern int ql4xenablemsix; diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 3075fba..0497873 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -773,14 +773,14 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha) * be freed so that when login happens from user space there are free DDB * indices available. **/ -static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) +void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) { int max_ddbs; int ret; uint32_t idx = 0, next_idx = 0; uint32_t state = 0, conn_err = 0; - max_ddbs = is_qla40XX(ha) ? MAX_PRST_DEV_DB_ENTRIES : + max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : MAX_DEV_DB_ENTRIES; for (idx = 0; idx < max_ddbs; idx = next_idx) { @@ -804,7 +804,6 @@ static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) } } - /** * qla4xxx_initialize_adapter - initiailizes hba * @ha: Pointer to host adapter structure. @@ -812,7 +811,7 @@ static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) * This routine parforms all of the steps necessary to initialize the adapter. * **/ -int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) +int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset) { int status = QLA_ERROR; @@ -840,7 +839,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) if (status == QLA_ERROR) goto exit_init_hba; - qla4xxx_free_ddb_index(ha); + if (is_reset == RESET_ADAPTER) + qla4xxx_build_ddb_list(ha, is_reset); set_bit(AF_ONLINE, &ha->flags); exit_init_hba: @@ -855,38 +855,12 @@ exit_init_hba: return status; } -/** - * qla4xxx_process_ddb_changed - process ddb state change - * @ha - Pointer to host adapter structure. - * @fw_ddb_index - Firmware's device database index - * @state - Device state - * - * This routine processes a Decive Database Changed AEN Event. - **/ -int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, - uint32_t state, uint32_t conn_err) +int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, + struct ddb_entry *ddb_entry, uint32_t state) { - struct ddb_entry * ddb_entry; uint32_t old_fw_ddb_device_state; int status = QLA_ERROR; - /* check for out of range index */ - if (fw_ddb_index >= MAX_DDB_ENTRIES) - goto exit_ddb_event; - - /* Get the corresponging ddb entry */ - ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index); - /* Device does not currently exist in our database. */ - if (ddb_entry == NULL) { - ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", - __func__, fw_ddb_index); - - if (state == DDB_DS_NO_CONNECTION_ACTIVE) - clear_bit(fw_ddb_index, ha->ddb_idx_map); - - goto exit_ddb_event; - } - old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB - old state = 0x%x, new state = 0x%x for " @@ -900,9 +874,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, switch (state) { case DDB_DS_SESSION_ACTIVE: case DDB_DS_DISCOVERY: - iscsi_conn_start(ddb_entry->conn); - iscsi_conn_login_event(ddb_entry->conn, - ISCSI_CONN_STATE_LOGGED_IN); + ddb_entry->unblock_sess(ddb_entry->sess); qla4xxx_update_session_conn_param(ha, ddb_entry); status = QLA_SUCCESS; break; @@ -936,9 +908,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, switch (state) { case DDB_DS_SESSION_ACTIVE: case DDB_DS_DISCOVERY: - iscsi_conn_start(ddb_entry->conn); - iscsi_conn_login_event(ddb_entry->conn, - ISCSI_CONN_STATE_LOGGED_IN); + ddb_entry->unblock_sess(ddb_entry->sess); qla4xxx_update_session_conn_param(ha, ddb_entry); status = QLA_SUCCESS; break; @@ -954,7 +924,198 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, __func__)); break; } + return status; +} + +void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry) +{ + /* + * This triggers a relogin. After the relogin_timer + * expires, the relogin gets scheduled. We must wait a + * minimum amount of time since receiving an 0x8014 AEN + * with failed device_state or a logout response before + * we can issue another relogin. + * + * Firmware pads this timeout: (time2wait +1). + * Driver retry to login should be longer than F/W. + * Otherwise F/W will fail + * set_ddb() mbx cmd with 0x4005 since it still + * counting down its time2wait. + */ + atomic_set(&ddb_entry->relogin_timer, 0); + atomic_set(&ddb_entry->retry_relogin_timer, + ddb_entry->default_time2wait + 4); + +} + +int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, + struct ddb_entry *ddb_entry, uint32_t state) +{ + uint32_t old_fw_ddb_device_state; + int status = QLA_ERROR; + + old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; + DEBUG2(ql4_printk(KERN_INFO, ha, + "%s: DDB - old state = 0x%x, new state = 0x%x for " + "index [%d]\n", __func__, + ddb_entry->fw_ddb_device_state, state, fw_ddb_index)); + + ddb_entry->fw_ddb_device_state = state; + + switch (old_fw_ddb_device_state) { + case DDB_DS_LOGIN_IN_PROCESS: + case DDB_DS_NO_CONNECTION_ACTIVE: + switch (state) { + case DDB_DS_SESSION_ACTIVE: + ddb_entry->unblock_sess(ddb_entry->sess); + qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry); + status = QLA_SUCCESS; + break; + case DDB_DS_SESSION_FAILED: + iscsi_block_session(ddb_entry->sess); + if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) + qla4xxx_arm_relogin_timer(ddb_entry); + status = QLA_SUCCESS; + break; + } + break; + case DDB_DS_SESSION_ACTIVE: + switch (state) { + case DDB_DS_SESSION_FAILED: + iscsi_block_session(ddb_entry->sess); + if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) + qla4xxx_arm_relogin_timer(ddb_entry); + status = QLA_SUCCESS; + break; + } + break; + case DDB_DS_SESSION_FAILED: + switch (state) { + case DDB_DS_SESSION_ACTIVE: + ddb_entry->unblock_sess(ddb_entry->sess); + qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry); + status = QLA_SUCCESS; + break; + case DDB_DS_SESSION_FAILED: + if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) + qla4xxx_arm_relogin_timer(ddb_entry); + status = QLA_SUCCESS; + break; + } + break; + default: + DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Unknown Event\n", + __func__)); + break; + } + return status; +} + +/** + * qla4xxx_process_ddb_changed - process ddb state change + * @ha - Pointer to host adapter structure. + * @fw_ddb_index - Firmware's device database index + * @state - Device state + * + * This routine processes a Decive Database Changed AEN Event. + **/ +int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, + uint32_t fw_ddb_index, + uint32_t state, uint32_t conn_err) +{ + struct ddb_entry *ddb_entry; + int status = QLA_ERROR; + + /* check for out of range index */ + if (fw_ddb_index >= MAX_DDB_ENTRIES) + goto exit_ddb_event; + + /* Get the corresponging ddb entry */ + ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index); + /* Device does not currently exist in our database. */ + if (ddb_entry == NULL) { + ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", + __func__, fw_ddb_index); + + if (state == DDB_DS_NO_CONNECTION_ACTIVE) + clear_bit(fw_ddb_index, ha->ddb_idx_map); + + goto exit_ddb_event; + } + + ddb_entry->ddb_change(ha, fw_ddb_index, ddb_entry, state); exit_ddb_event: return status; } + +/** + * qla4xxx_login_flash_ddb - Login to target (DDB) + * @cls_session: Pointer to the session to login + * + * This routine logins to the target. + * Issues setddb and conn open mbx + **/ +void qla4xxx_login_flash_ddb(struct iscsi_cls_session *cls_session) +{ + struct iscsi_session *sess; + struct ddb_entry *ddb_entry; + struct scsi_qla_host *ha; + struct dev_db_entry *fw_ddb_entry = NULL; + dma_addr_t fw_ddb_dma; + uint32_t mbx_sts = 0; + int ret; + + sess = cls_session->dd_data; + ddb_entry = sess->dd_data; + ha = ddb_entry->ha; + + if (!test_bit(AF_LINK_UP, &ha->flags)) + return; + + if (ddb_entry->ddb_type != FLASH_DDB) { + DEBUG2(ql4_printk(KERN_INFO, ha, + "Skipping login to non FLASH DB")); + goto exit_login; + } + + fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, + &fw_ddb_dma); + if (fw_ddb_entry == NULL) { + DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); + goto exit_login; + } + + if (ddb_entry->fw_ddb_index == INVALID_ENTRY) { + ret = qla4xxx_get_ddb_index(ha, &ddb_entry->fw_ddb_index); + if (ret == QLA_ERROR) + goto exit_login; + + ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; + ha->tot_ddbs++; + } + + memcpy(fw_ddb_entry, &ddb_entry->fw_ddb_entry, + sizeof(struct dev_db_entry)); + ddb_entry->sess->target_id = ddb_entry->fw_ddb_index; + + ret = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, + fw_ddb_dma, &mbx_sts); + if (ret == QLA_ERROR) { + DEBUG2(ql4_printk(KERN_ERR, ha, "Set DDB failed\n")); + goto exit_login; + } + + ddb_entry->fw_ddb_device_state = DDB_DS_LOGIN_IN_PROCESS; + ret = qla4xxx_conn_open(ha, ddb_entry->fw_ddb_index); + if (ret == QLA_ERROR) { + ql4_printk(KERN_ERR, ha, "%s: Login failed: %s\n", __func__, + sess->targetname); + goto exit_login; + } + +exit_login: + if (fw_ddb_entry) + dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); +} + diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 4c2b848..c259378 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -41,6 +41,16 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, return status; } + if (is_qla40XX(ha)) { + if (test_bit(AF_HA_REMOVAL, &ha->flags)) { + DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " + "prematurely completing mbx cmd as " + "adapter removal detected\n", + ha->host_no, __func__)); + return status; + } + } + if (is_qla8022(ha)) { if (test_bit(AF_FW_RECOVERY, &ha->flags)) { DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " @@ -413,6 +423,7 @@ qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, memcpy(ha->name_string, init_fw_cb->iscsi_name, min(sizeof(ha->name_string), sizeof(init_fw_cb->iscsi_name))); + ha->def_timeout = le16_to_cpu(init_fw_cb->def_timeout); /*memcpy(ha->alias, init_fw_cb->Alias, min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 30f31b1..95910c9 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,13 @@ static struct kmem_cache *srb_cachep; /* * Module parameter information and variables */ +int ql4xdisablesysfsboot = 1; +module_param(ql4xdisablesysfsboot, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ql4xdisablesysfsboot, + "Set to disable exporting boot targets to sysfs\n" + " 0 - Export boot targets\n" + " 1 - Do not export boot targets (Default)"); + int ql4xdontresethba = 0; module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ql4xdontresethba, @@ -63,7 +71,7 @@ static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO; module_param(ql4xsess_recovery_tmo, int, S_IRUGO); MODULE_PARM_DESC(ql4xsess_recovery_tmo, "Target Session Recovery Timeout.\n" - " Default: 30 sec."); + " Default: 120 sec."); static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); /* @@ -415,7 +423,7 @@ static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) qla_ep = ep->dd_data; ha = to_qla_host(qla_ep->host); - if (adapter_up(ha)) + if (adapter_up(ha) && !test_bit(AF_BUILD_DDB_LIST, &ha->flags)) ret = 1; return ret; @@ -975,6 +983,150 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn, } +int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index) +{ + uint32_t mbx_sts = 0; + uint16_t tmp_ddb_index; + int ret; + +get_ddb_index: + tmp_ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); + + if (tmp_ddb_index >= MAX_DDB_ENTRIES) { + DEBUG2(ql4_printk(KERN_INFO, ha, + "Free DDB index not available\n")); + ret = QLA_ERROR; + goto exit_get_ddb_index; + } + + if (test_and_set_bit(tmp_ddb_index, ha->ddb_idx_map)) + goto get_ddb_index; + + DEBUG2(ql4_printk(KERN_INFO, ha, + "Found a free DDB index at %d\n", tmp_ddb_index)); + ret = qla4xxx_req_ddb_entry(ha, tmp_ddb_index, &mbx_sts); + if (ret == QLA_ERROR) { + if (mbx_sts == MBOX_STS_COMMAND_ERROR) { + ql4_printk(KERN_INFO, ha, + "DDB index = %d not available trying next\n", + tmp_ddb_index); + goto get_ddb_index; + } + DEBUG2(ql4_printk(KERN_INFO, ha, + "Free FW DDB not available\n")); + } + + *ddb_index = tmp_ddb_index; + +exit_get_ddb_index: + return ret; +} + +static int qla4xxx_match_ipaddress(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry, + char *existing_ipaddr, + char *user_ipaddr) +{ + uint8_t dst_ipaddr[IPv6_ADDR_LEN]; + char formatted_ipaddr[DDB_IPADDR_LEN]; + int status = QLA_SUCCESS, ret = 0; + + if (ddb_entry->fw_ddb_entry.options & DDB_OPT_IPV6_DEVICE) { + ret = in6_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr, + '\0', NULL); + if (ret == 0) { + status = QLA_ERROR; + goto out_match; + } + ret = sprintf(formatted_ipaddr, "%pI6", dst_ipaddr); + } else { + ret = in4_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr, + '\0', NULL); + if (ret == 0) { + status = QLA_ERROR; + goto out_match; + } + ret = sprintf(formatted_ipaddr, "%pI4", dst_ipaddr); + } + + if (strcmp(existing_ipaddr, formatted_ipaddr)) + status = QLA_ERROR; + +out_match: + return status; +} + +static int qla4xxx_match_fwdb_session(struct scsi_qla_host *ha, + struct iscsi_cls_conn *cls_conn) +{ + int idx = 0, max_ddbs, rval; + struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn); + struct iscsi_session *sess, *existing_sess; + struct iscsi_conn *conn, *existing_conn; + struct ddb_entry *ddb_entry; + + sess = cls_sess->dd_data; + conn = cls_conn->dd_data; + + if (sess->targetname == NULL || + conn->persistent_address == NULL || + conn->persistent_port == 0) + return QLA_ERROR; + + max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : + MAX_DEV_DB_ENTRIES; + + for (idx = 0; idx < max_ddbs; idx++) { + ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx); + if (ddb_entry == NULL) + continue; + + if (ddb_entry->ddb_type != FLASH_DDB) + continue; + + existing_sess = ddb_entry->sess->dd_data; + existing_conn = ddb_entry->conn->dd_data; + + if (existing_sess->targetname == NULL || + existing_conn->persistent_address == NULL || + existing_conn->persistent_port == 0) + continue; + + DEBUG2(ql4_printk(KERN_INFO, ha, + "IQN = %s User IQN = %s\n", + existing_sess->targetname, + sess->targetname)); + + DEBUG2(ql4_printk(KERN_INFO, ha, + "IP = %s User IP = %s\n", + existing_conn->persistent_address, + conn->persistent_address)); + + DEBUG2(ql4_printk(KERN_INFO, ha, + "Port = %d User Port = %d\n", + existing_conn->persistent_port, + conn->persistent_port)); + + if (strcmp(existing_sess->targetname, sess->targetname)) + continue; + rval = qla4xxx_match_ipaddress(ha, ddb_entry, + existing_conn->persistent_address, + conn->persistent_address); + if (rval == QLA_ERROR) + continue; + if (existing_conn->persistent_port != conn->persistent_port) + continue; + break; + } + + if (idx == max_ddbs) + return QLA_ERROR; + + DEBUG2(ql4_printk(KERN_INFO, ha, + "Match found in fwdb sessions\n")); + return QLA_SUCCESS; +} + static struct iscsi_cls_session * qla4xxx_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, uint16_t qdepth, @@ -984,8 +1136,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, struct scsi_qla_host *ha; struct qla_endpoint *qla_ep; struct ddb_entry *ddb_entry; - uint32_t ddb_index; - uint32_t mbx_sts = 0; + uint16_t ddb_index; struct iscsi_session *sess; struct sockaddr *dst_addr; int ret; @@ -1000,32 +1151,9 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, dst_addr = (struct sockaddr *)&qla_ep->dst_addr; ha = to_qla_host(qla_ep->host); -get_ddb_index: - ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); - - if (ddb_index >= MAX_DDB_ENTRIES) { - DEBUG2(ql4_printk(KERN_INFO, ha, - "Free DDB index not available\n")); + ret = qla4xxx_get_ddb_index(ha, &ddb_index); + if (ret == QLA_ERROR) return NULL; - } - - if (test_and_set_bit(ddb_index, ha->ddb_idx_map)) - goto get_ddb_index; - - DEBUG2(ql4_printk(KERN_INFO, ha, - "Found a free DDB index at %d\n", ddb_index)); - ret = qla4xxx_req_ddb_entry(ha, ddb_index, &mbx_sts); - if (ret == QLA_ERROR) { - if (mbx_sts == MBOX_STS_COMMAND_ERROR) { - ql4_printk(KERN_INFO, ha, - "DDB index = %d not available trying next\n", - ddb_index); - goto get_ddb_index; - } - DEBUG2(ql4_printk(KERN_INFO, ha, - "Free FW DDB not available\n")); - return NULL; - } cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host, cmds_max, sizeof(struct ddb_entry), @@ -1040,6 +1168,8 @@ get_ddb_index: ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; ddb_entry->ha = ha; ddb_entry->sess = cls_sess; + ddb_entry->unblock_sess = qla4xxx_unblock_ddb; + ddb_entry->ddb_change = qla4xxx_ddb_change; cls_sess->recovery_tmo = ql4xsess_recovery_tmo; ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; ha->tot_ddbs++; @@ -1109,7 +1239,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) struct iscsi_session *sess; struct ddb_entry *ddb_entry; struct scsi_qla_host *ha; - struct dev_db_entry *fw_ddb_entry; + struct dev_db_entry *fw_ddb_entry = NULL; dma_addr_t fw_ddb_entry_dma; uint32_t mbx_sts = 0; int ret = 0; @@ -1120,12 +1250,25 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) ddb_entry = sess->dd_data; ha = ddb_entry->ha; + /* Check if we have matching FW DDB, if yes then do not + * login to this target. This could cause target to logout previous + * connection + */ + ret = qla4xxx_match_fwdb_session(ha, cls_conn); + if (ret == QLA_SUCCESS) { + ql4_printk(KERN_INFO, ha, + "Session already exist in FW.\n"); + ret = -EEXIST; + goto exit_conn_start; + } + fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), &fw_ddb_entry_dma, GFP_KERNEL); if (!fw_ddb_entry) { ql4_printk(KERN_ERR, ha, "%s: Unable to allocate dma buffer\n", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto exit_conn_start; } ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts); @@ -1138,9 +1281,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) if (mbx_sts) if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { - iscsi_conn_start(ddb_entry->conn); - iscsi_conn_login_event(ddb_entry->conn, - ISCSI_CONN_STATE_LOGGED_IN); + ddb_entry->unblock_sess(ddb_entry->sess); goto exit_set_param; } @@ -1167,8 +1308,9 @@ exit_set_param: ret = 0; exit_conn_start: - dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), - fw_ddb_entry, fw_ddb_entry_dma); + if (fw_ddb_entry) + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), + fw_ddb_entry, fw_ddb_entry_dma); return ret; } @@ -1344,6 +1486,101 @@ static int qla4xxx_task_xmit(struct iscsi_task *task) return -ENOSYS; } +static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha, + struct dev_db_entry *fw_ddb_entry, + struct iscsi_cls_session *cls_sess, + struct iscsi_cls_conn *cls_conn) +{ + int buflen = 0; + struct iscsi_session *sess; + struct iscsi_conn *conn; + char ip_addr[DDB_IPADDR_LEN]; + uint16_t options = 0; + + sess = cls_sess->dd_data; + conn = cls_conn->dd_data; + + conn->max_recv_dlength = BYTE_UNITS * + le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); + + conn->max_xmit_dlength = BYTE_UNITS * + le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len); + + sess->initial_r2t_en = + (BIT_10 & le16_to_cpu(fw_ddb_entry->iscsi_options)); + + sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t); + + sess->imm_data_en = (BIT_11 & le16_to_cpu(fw_ddb_entry->iscsi_options)); + + sess->first_burst = BYTE_UNITS * + le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len); + + sess->max_burst = BYTE_UNITS * + le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len); + + sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); + + sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain); + + conn->persistent_port = le16_to_cpu(fw_ddb_entry->port); + + sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); + + options = le16_to_cpu(fw_ddb_entry->options); + if (options & DDB_OPT_IPV6_DEVICE) + sprintf(ip_addr, "%pI6", fw_ddb_entry->ip_addr); + else + sprintf(ip_addr, "%pI4", fw_ddb_entry->ip_addr); + + iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_NAME, + (char *)fw_ddb_entry->iscsi_name, buflen); + iscsi_set_param(cls_conn, ISCSI_PARAM_INITIATOR_NAME, + (char *)ha->name_string, buflen); + iscsi_set_param(cls_conn, ISCSI_PARAM_PERSISTENT_ADDRESS, + (char *)ip_addr, buflen); +} + +void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry) +{ + struct iscsi_cls_session *cls_sess; + struct iscsi_cls_conn *cls_conn; + uint32_t ddb_state; + dma_addr_t fw_ddb_entry_dma; + struct dev_db_entry *fw_ddb_entry; + + fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), + &fw_ddb_entry_dma, GFP_KERNEL); + if (!fw_ddb_entry) { + ql4_printk(KERN_ERR, ha, + "%s: Unable to allocate dma buffer\n", __func__); + goto exit_session_conn_fwddb_param; + } + + if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, + fw_ddb_entry_dma, NULL, NULL, &ddb_state, + NULL, NULL, NULL) == QLA_ERROR) { + DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed " + "get_ddb_entry for fw_ddb_index %d\n", + ha->host_no, __func__, + ddb_entry->fw_ddb_index)); + goto exit_session_conn_fwddb_param; + } + + cls_sess = ddb_entry->sess; + + cls_conn = ddb_entry->conn; + + /* Update params */ + qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn); + +exit_session_conn_fwddb_param: + if (fw_ddb_entry) + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), + fw_ddb_entry, fw_ddb_entry_dma); +} + void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry) { @@ -1360,7 +1597,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, if (!fw_ddb_entry) { ql4_printk(KERN_ERR, ha, "%s: Unable to allocate dma buffer\n", __func__); - return; + goto exit_session_conn_param; } if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, @@ -1370,7 +1607,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, "get_ddb_entry for fw_ddb_index %d\n", ha->host_no, __func__, ddb_entry->fw_ddb_index)); - return; + goto exit_session_conn_param; } cls_sess = ddb_entry->sess; @@ -1379,6 +1616,12 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, cls_conn = ddb_entry->conn; conn = cls_conn->dd_data; + /* Update timers after login */ + ddb_entry->default_relogin_timeout = + le16_to_cpu(fw_ddb_entry->def_timeout); + ddb_entry->default_time2wait = + le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); + /* Update params */ conn->max_recv_dlength = BYTE_UNITS * le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); @@ -1407,6 +1650,11 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, memcpy(sess->initiatorname, ha->name_string, min(sizeof(ha->name_string), sizeof(sess->initiatorname))); + +exit_session_conn_param: + if (fw_ddb_entry) + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), + fw_ddb_entry, fw_ddb_entry_dma); } /* @@ -1607,6 +1855,9 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) vfree(ha->chap_list); ha->chap_list = NULL; + if (ha->fw_ddb_dma_pool) + dma_pool_destroy(ha->fw_ddb_dma_pool); + /* release io space registers */ if (is_qla8022(ha)) { if (ha->nx_pcibase) @@ -1689,6 +1940,16 @@ static int qla4xxx_mem_alloc(struct scsi_qla_host *ha) goto mem_alloc_error_exit; } + ha->fw_ddb_dma_pool = dma_pool_create("ql4_fw_ddb", &ha->pdev->dev, + DDB_DMA_BLOCK_SIZE, 8, 0); + + if (ha->fw_ddb_dma_pool == NULL) { + ql4_printk(KERN_WARNING, ha, + "%s: fw_ddb_dma_pool allocation failed..\n", + __func__); + goto mem_alloc_error_exit; + } + return QLA_SUCCESS; mem_alloc_error_exit: @@ -1800,6 +2061,60 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) } } +void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) +{ + struct iscsi_session *sess; + struct ddb_entry *ddb_entry; + struct scsi_qla_host *ha; + + sess = cls_sess->dd_data; + ddb_entry = sess->dd_data; + ha = ddb_entry->ha; + + if (!(ddb_entry->ddb_type == FLASH_DDB)) + return; + + if (adapter_up(ha) && !test_bit(DF_RELOGIN, &ddb_entry->flags) && + !iscsi_is_session_online(cls_sess)) { + if (atomic_read(&ddb_entry->retry_relogin_timer) != + INVALID_ENTRY) { + if (atomic_read(&ddb_entry->retry_relogin_timer) == + 0) { + atomic_set(&ddb_entry->retry_relogin_timer, + INVALID_ENTRY); + set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); + set_bit(DF_RELOGIN, &ddb_entry->flags); + DEBUG2(ql4_printk(KERN_INFO, ha, + "%s: index [%d] login device\n", + __func__, ddb_entry->fw_ddb_index)); + } else + atomic_dec(&ddb_entry->retry_relogin_timer); + } + } + + /* Wait for relogin to timeout */ + if (atomic_read(&ddb_entry->relogin_timer) && + (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) { + /* + * If the relogin times out and the device is + * still NOT ONLINE then try and relogin again. + */ + if (!iscsi_is_session_online(cls_sess)) { + /* Reset retry relogin timer */ + atomic_inc(&ddb_entry->relogin_retry_count); + DEBUG2(ql4_printk(KERN_INFO, ha, + "%s: index[%d] relogin timed out-retrying" + " relogin (%d), retry (%d)\n", __func__, + ddb_entry->fw_ddb_index, + atomic_read(&ddb_entry->relogin_retry_count), + ddb_entry->default_time2wait + 4)); + set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); + atomic_set(&ddb_entry->retry_relogin_timer, + ddb_entry->default_time2wait + 4); + } + } +} + /** * qla4xxx_timer - checks every second for work to do. * @ha: Pointer to host adapter structure. @@ -1809,6 +2124,8 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) int start_dpc = 0; uint16_t w; + iscsi_host_for_each_session(ha->host, qla4xxx_check_relogin_flash_ddb); + /* If we are in the middle of AER/EEH processing * skip any processing and reschedule the timer */ @@ -2078,7 +2395,12 @@ static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session) sess = cls_session->dd_data; ddb_entry = sess->dd_data; ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED; - iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); + + if (ddb_entry->ddb_type == FLASH_DDB) + iscsi_block_session(ddb_entry->sess); + else + iscsi_session_failure(cls_session->dd_data, + ISCSI_ERR_CONN_FAILED); } /** @@ -2163,7 +2485,7 @@ recover_ha_init_adapter: /* NOTE: AF_ONLINE flag set upon successful completion of * qla4xxx_initialize_adapter */ - status = qla4xxx_initialize_adapter(ha); + status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); } /* Retry failed adapter initialization, if necessary @@ -2245,17 +2567,108 @@ static void qla4xxx_relogin_devices(struct iscsi_cls_session *cls_session) iscsi_unblock_session(ddb_entry->sess); } else { /* Trigger relogin */ - iscsi_session_failure(cls_session->dd_data, - ISCSI_ERR_CONN_FAILED); + if (ddb_entry->ddb_type == FLASH_DDB) { + if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) + qla4xxx_arm_relogin_timer(ddb_entry); + } else + iscsi_session_failure(cls_session->dd_data, + ISCSI_ERR_CONN_FAILED); } } } +int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session) +{ + struct iscsi_session *sess; + struct ddb_entry *ddb_entry; + struct scsi_qla_host *ha; + + sess = cls_session->dd_data; + ddb_entry = sess->dd_data; + ha = ddb_entry->ha; + ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" + " unblock session\n", ha->host_no, __func__, + ddb_entry->fw_ddb_index); + + iscsi_unblock_session(ddb_entry->sess); + + /* Start scan target */ + if (test_bit(AF_ONLINE, &ha->flags)) { + ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" + " start scan\n", ha->host_no, __func__, + ddb_entry->fw_ddb_index); + scsi_queue_work(ha->host, &ddb_entry->sess->scan_work); + } + return QLA_SUCCESS; +} + +int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session) +{ + struct iscsi_session *sess; + struct ddb_entry *ddb_entry; + struct scsi_qla_host *ha; + + sess = cls_session->dd_data; + ddb_entry = sess->dd_data; + ha = ddb_entry->ha; + ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" + " unblock user space session\n", ha->host_no, __func__, + ddb_entry->fw_ddb_index); + iscsi_conn_start(ddb_entry->conn); + iscsi_conn_login_event(ddb_entry->conn, + ISCSI_CONN_STATE_LOGGED_IN); + + return QLA_SUCCESS; +} + static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) { iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices); } +static void qla4xxx_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) +{ + uint16_t relogin_timer; + struct iscsi_session *sess; + struct ddb_entry *ddb_entry; + struct scsi_qla_host *ha; + + sess = cls_sess->dd_data; + ddb_entry = sess->dd_data; + ha = ddb_entry->ha; + + relogin_timer = max(ddb_entry->default_relogin_timeout, + (uint16_t)RELOGIN_TOV); + atomic_set(&ddb_entry->relogin_timer, relogin_timer); + + DEBUG2(ql4_printk(KERN_INFO, ha, + "scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no, + ddb_entry->fw_ddb_index, relogin_timer)); + + qla4xxx_login_flash_ddb(cls_sess); +} + +static void qla4xxx_dpc_relogin(struct iscsi_cls_session *cls_sess) +{ + struct iscsi_session *sess; + struct ddb_entry *ddb_entry; + struct scsi_qla_host *ha; + + sess = cls_sess->dd_data; + ddb_entry = sess->dd_data; + ha = ddb_entry->ha; + + if (!(ddb_entry->ddb_type == FLASH_DDB)) + return; + + if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) && + !iscsi_is_session_online(cls_sess)) { + DEBUG2(ql4_printk(KERN_INFO, ha, + "relogin issued\n")); + qla4xxx_relogin_flash_ddb(cls_sess); + } +} + void qla4xxx_wake_dpc(struct scsi_qla_host *ha) { if (ha->dpc_thread) @@ -2356,6 +2769,12 @@ dpc_post_reset_ha: if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) qla4xxx_get_dhcp_ip_address(ha); + /* ---- relogin device? --- */ + if (adapter_up(ha) && + test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) { + iscsi_host_for_each_session(ha->host, qla4xxx_dpc_relogin); + } + /* ---- link change? --- */ if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { if (!test_bit(AF_LINK_UP, &ha->flags)) { @@ -2368,8 +2787,12 @@ dpc_post_reset_ha: * fatal error recovery. Therefore, the driver must * manually relogin to devices when recovering from * connection failures, logouts, expired KATO, etc. */ - - qla4xxx_relogin_all_devices(ha); + if (test_and_clear_bit(AF_BUILD_DDB_LIST, &ha->flags)) { + qla4xxx_build_ddb_list(ha, ha->is_reset); + iscsi_host_for_each_session(ha->host, + qla4xxx_login_flash_ddb); + } else + qla4xxx_relogin_all_devices(ha); } } } @@ -2867,6 +3290,9 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[]) " target ID %d\n", __func__, ddb_index[0], ddb_index[1])); + ha->pri_ddb_idx = ddb_index[0]; + ha->sec_ddb_idx = ddb_index[1]; + exit_boot_info_free: dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma); exit_boot_info: @@ -3034,6 +3460,9 @@ static int qla4xxx_get_boot_info(struct scsi_qla_host *ha) return ret; } + if (ql4xdisablesysfsboot) + return QLA_SUCCESS; + if (ddb_index[0] == 0xffff) goto sec_target; @@ -3066,7 +3495,15 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha) struct iscsi_boot_kobj *boot_kobj; if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS) - return 0; + return QLA_ERROR; + + if (ql4xdisablesysfsboot) { + ql4_printk(KERN_INFO, ha, + "%s: syfsboot disabled - driver will trigger login" + "and publish session for discovery .\n", __func__); + return QLA_SUCCESS; + } + ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no); if (!ha->boot_kset) @@ -3108,7 +3545,7 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha) if (!boot_kobj) goto put_host; - return 0; + return QLA_SUCCESS; put_host: scsi_host_put(ha->host); @@ -3174,9 +3611,507 @@ static void qla4xxx_create_chap_list(struct scsi_qla_host *ha) exit_chap_list: dma_free_coherent(&ha->pdev->dev, chap_size, chap_flash_data, chap_dma); - return; } +static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry, + struct ql4_tuple_ddb *tddb) +{ + struct scsi_qla_host *ha; + struct iscsi_cls_session *cls_sess; + struct iscsi_cls_conn *cls_conn; + struct iscsi_session *sess; + struct iscsi_conn *conn; + + DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); + ha = ddb_entry->ha; + cls_sess = ddb_entry->sess; + sess = cls_sess->dd_data; + cls_conn = ddb_entry->conn; + conn = cls_conn->dd_data; + + tddb->tpgt = sess->tpgt; + tddb->port = conn->persistent_port; + strncpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE); + strncpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN); +} + +static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry, + struct ql4_tuple_ddb *tddb) +{ + uint16_t options = 0; + + tddb->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); + memcpy(&tddb->iscsi_name[0], &fw_ddb_entry->iscsi_name[0], + min(sizeof(tddb->iscsi_name), sizeof(fw_ddb_entry->iscsi_name))); + + options = le16_to_cpu(fw_ddb_entry->options); + if (options & DDB_OPT_IPV6_DEVICE) + sprintf(tddb->ip_addr, "%pI6", fw_ddb_entry->ip_addr); + else + sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr); + + tddb->port = le16_to_cpu(fw_ddb_entry->port); +} + +static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha, + struct ql4_tuple_ddb *old_tddb, + struct ql4_tuple_ddb *new_tddb) +{ + if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name)) + return QLA_ERROR; + + if (strcmp(old_tddb->ip_addr, new_tddb->ip_addr)) + return QLA_ERROR; + + if (old_tddb->port != new_tddb->port) + return QLA_ERROR; + + DEBUG2(ql4_printk(KERN_INFO, ha, + "Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]", + old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr, + old_tddb->iscsi_name, new_tddb->port, new_tddb->tpgt, + new_tddb->ip_addr, new_tddb->iscsi_name)); + + return QLA_SUCCESS; +} + +static int qla4xxx_is_session_exists(struct scsi_qla_host *ha, + struct dev_db_entry *fw_ddb_entry) +{ + struct ddb_entry *ddb_entry; + struct ql4_tuple_ddb *fw_tddb = NULL; + struct ql4_tuple_ddb *tmp_tddb = NULL; + int idx; + int ret = QLA_ERROR; + + fw_tddb = vzalloc(sizeof(*fw_tddb)); + if (!fw_tddb) { + DEBUG2(ql4_printk(KERN_WARNING, ha, + "Memory Allocation failed.\n")); + ret = QLA_SUCCESS; + goto exit_check; + } + + tmp_tddb = vzalloc(sizeof(*tmp_tddb)); + if (!tmp_tddb) { + DEBUG2(ql4_printk(KERN_WARNING, ha, + "Memory Allocation failed.\n")); + ret = QLA_SUCCESS; + goto exit_check; + } + + qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb); + + for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) { + ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx); + if (ddb_entry == NULL) + continue; + + qla4xxx_get_param_ddb(ddb_entry, tmp_tddb); + if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) { + ret = QLA_SUCCESS; /* found */ + goto exit_check; + } + } + +exit_check: + if (fw_tddb) + vfree(fw_tddb); + if (tmp_tddb) + vfree(tmp_tddb); + return ret; +} + +static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha, + struct list_head *list_nt, + struct dev_db_entry *fw_ddb_entry) +{ + struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp; + struct ql4_tuple_ddb *fw_tddb = NULL; + struct ql4_tuple_ddb *tmp_tddb = NULL; + int ret = QLA_ERROR; + + fw_tddb = vzalloc(sizeof(*fw_tddb)); + if (!fw_tddb) { + DEBUG2(ql4_printk(KERN_WARNING, ha, + "Memory Allocation failed.\n")); + ret = QLA_SUCCESS; + goto exit_check; + } + + tmp_tddb = vzalloc(sizeof(*tmp_tddb)); + if (!tmp_tddb) { + DEBUG2(ql4_printk(KERN_WARNING, ha, + "Memory Allocation failed.\n")); + ret = QLA_SUCCESS; + goto exit_check; + } + + qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb); + + list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { + qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb); + if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) { + ret = QLA_SUCCESS; /* found */ + goto exit_check; + } + } + +exit_check: + if (fw_tddb) + vfree(fw_tddb); + if (tmp_tddb) + vfree(tmp_tddb); + return ret; +} + +static void qla4xxx_free_nt_list(struct list_head *list_nt) +{ + struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp; + + /* Free up the normaltargets list */ + list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { + list_del_init(&nt_ddb_idx->list); + vfree(nt_ddb_idx); + } + +} + +static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, + struct dev_db_entry *fw_ddb_entry) +{ + struct iscsi_endpoint *ep; + struct sockaddr_in *addr; + struct sockaddr_in6 *addr6; + struct sockaddr *dst_addr; + char *ip; + + /* TODO: need to destroy on unload iscsi_endpoint*/ + dst_addr = vmalloc(sizeof(*dst_addr)); + if (!dst_addr) + return NULL; + + if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) { + dst_addr->sa_family = AF_INET6; + addr6 = (struct sockaddr_in6 *)dst_addr; + ip = (char *)&addr6->sin6_addr; + memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN); + addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port)); + + } else { + dst_addr->sa_family = AF_INET; + addr = (struct sockaddr_in *)dst_addr; + ip = (char *)&addr->sin_addr; + memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN); + addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port)); + } + + ep = qla4xxx_ep_connect(ha->host, dst_addr, 0); + vfree(dst_addr); + return ep; +} + +static int qla4xxx_verify_boot_idx(struct scsi_qla_host *ha, uint16_t idx) +{ + if (ql4xdisablesysfsboot) + return QLA_SUCCESS; + if (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx) + return QLA_ERROR; + return QLA_SUCCESS; +} + +static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry) +{ + ddb_entry->ddb_type = FLASH_DDB; + ddb_entry->fw_ddb_index = INVALID_ENTRY; + ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; + ddb_entry->ha = ha; + ddb_entry->unblock_sess = qla4xxx_unblock_flash_ddb; + ddb_entry->ddb_change = qla4xxx_flash_ddb_change; + + atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY); + atomic_set(&ddb_entry->relogin_timer, 0); + atomic_set(&ddb_entry->relogin_retry_count, 0); + + ddb_entry->default_relogin_timeout = + le16_to_cpu(ddb_entry->fw_ddb_entry.def_timeout); + ddb_entry->default_time2wait = + le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait); +} + +static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) +{ + uint32_t idx = 0; + uint32_t ip_idx[IP_ADDR_COUNT] = {0, 1, 2, 3}; /* 4 IP interfaces */ + uint32_t sts[MBOX_REG_COUNT]; + uint32_t ip_state; + unsigned long wtime; + int ret; + + wtime = jiffies + (HZ * IP_CONFIG_TOV); + do { + for (idx = 0; idx < IP_ADDR_COUNT; idx++) { + if (ip_idx[idx] == -1) + continue; + + ret = qla4xxx_get_ip_state(ha, 0, ip_idx[idx], sts); + + if (ret == QLA_ERROR) { + ip_idx[idx] = -1; + continue; + } + + ip_state = (sts[1] & IP_STATE_MASK) >> IP_STATE_SHIFT; + + DEBUG2(ql4_printk(KERN_INFO, ha, + "Waiting for IP state for idx = %d, state = 0x%x\n", + ip_idx[idx], ip_state)); + if (ip_state == IP_ADDRSTATE_UNCONFIGURED || + ip_state == IP_ADDRSTATE_INVALID || + ip_state == IP_ADDRSTATE_PREFERRED || + ip_state == IP_ADDRSTATE_DEPRICATED || + ip_state == IP_ADDRSTATE_DISABLING) + ip_idx[idx] = -1; + + } + + /* Break if all IP states checked */ + if ((ip_idx[0] == -1) && + (ip_idx[1] == -1) && + (ip_idx[2] == -1) && + (ip_idx[3] == -1)) + break; + schedule_timeout_uninterruptible(HZ); + } while (time_after(wtime, jiffies)); +} + +void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) +{ + int max_ddbs; + int ret; + uint32_t idx = 0, next_idx = 0; + uint32_t state = 0, conn_err = 0; + uint16_t conn_id; + struct dev_db_entry *fw_ddb_entry; + struct ddb_entry *ddb_entry = NULL; + dma_addr_t fw_ddb_dma; + struct iscsi_cls_session *cls_sess; + struct iscsi_session *sess; + struct iscsi_cls_conn *cls_conn; + struct iscsi_endpoint *ep; + uint16_t cmds_max = 32, tmo = 0; + uint32_t initial_cmdsn = 0; + struct list_head list_st, list_nt; /* List of sendtargets */ + struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp; + int fw_idx_size; + unsigned long wtime; + struct qla_ddb_index *nt_ddb_idx; + + if (!test_bit(AF_LINK_UP, &ha->flags)) { + set_bit(AF_BUILD_DDB_LIST, &ha->flags); + ha->is_reset = is_reset; + return; + } + max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : + MAX_DEV_DB_ENTRIES; + + fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, + &fw_ddb_dma); + if (fw_ddb_entry == NULL) { + DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); + goto exit_ddb_list; + } + + INIT_LIST_HEAD(&list_st); + INIT_LIST_HEAD(&list_nt); + fw_idx_size = sizeof(struct qla_ddb_index); + + for (idx = 0; idx < max_ddbs; idx = next_idx) { + ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, + fw_ddb_dma, NULL, + &next_idx, &state, &conn_err, + NULL, &conn_id); + if (ret == QLA_ERROR) + break; + + if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS) + goto continue_next_st; + + /* Check if ST, add to the list_st */ + if (strlen((char *) fw_ddb_entry->iscsi_name) != 0) + goto continue_next_st; + + st_ddb_idx = vzalloc(fw_idx_size); + if (!st_ddb_idx) + break; + + st_ddb_idx->fw_ddb_idx = idx; + + list_add_tail(&st_ddb_idx->list, &list_st); +continue_next_st: + if (next_idx == 0) + break; + } + + /* Before issuing conn open mbox, ensure all IPs states are configured + * Note, conn open fails if IPs are not configured + */ + qla4xxx_wait_for_ip_configuration(ha); + + /* Go thru the STs and fire the sendtargets by issuing conn open mbx */ + list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { + qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx); + } + + /* Wait to ensure all sendtargets are done for min 12 sec wait */ + tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout); + DEBUG2(ql4_printk(KERN_INFO, ha, + "Default time to wait for build ddb %d\n", tmo)); + + wtime = jiffies + (HZ * tmo); + do { + list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, + list) { + ret = qla4xxx_get_fwddb_entry(ha, + st_ddb_idx->fw_ddb_idx, + NULL, 0, NULL, &next_idx, + &state, &conn_err, NULL, + NULL); + if (ret == QLA_ERROR) + continue; + + if (state == DDB_DS_NO_CONNECTION_ACTIVE || + state == DDB_DS_SESSION_FAILED) { + list_del_init(&st_ddb_idx->list); + vfree(st_ddb_idx); + } + } + schedule_timeout_uninterruptible(HZ / 10); + } while (time_after(wtime, jiffies)); + + /* Free up the sendtargets list */ + list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { + list_del_init(&st_ddb_idx->list); + vfree(st_ddb_idx); + } + + for (idx = 0; idx < max_ddbs; idx = next_idx) { + ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, + fw_ddb_dma, NULL, + &next_idx, &state, &conn_err, + NULL, &conn_id); + if (ret == QLA_ERROR) + break; + + if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS) + goto continue_next_nt; + + /* Check if NT, then add to list it */ + if (strlen((char *) fw_ddb_entry->iscsi_name) == 0) + goto continue_next_nt; + + if (state == DDB_DS_NO_CONNECTION_ACTIVE || + state == DDB_DS_SESSION_FAILED) { + DEBUG2(ql4_printk(KERN_INFO, ha, + "Adding DDB to session = 0x%x\n", + idx)); + if (is_reset == INIT_ADAPTER) { + nt_ddb_idx = vmalloc(fw_idx_size); + if (!nt_ddb_idx) + break; + + nt_ddb_idx->fw_ddb_idx = idx; + + memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry, + sizeof(struct dev_db_entry)); + + if (qla4xxx_is_flash_ddb_exists(ha, &list_nt, + fw_ddb_entry) == QLA_SUCCESS) { + vfree(nt_ddb_idx); + goto continue_next_nt; + } + list_add_tail(&nt_ddb_idx->list, &list_nt); + } else if (is_reset == RESET_ADAPTER) { + if (qla4xxx_is_session_exists(ha, + fw_ddb_entry) == QLA_SUCCESS) + goto continue_next_nt; + } + + /* Create session object, with INVALID_ENTRY, + * the targer_id would get set when we issue the login + */ + cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, + ha->host, cmds_max, + sizeof(struct ddb_entry), + sizeof(struct ql4_task_data), + initial_cmdsn, INVALID_ENTRY); + if (!cls_sess) + goto exit_ddb_list; + + /* + * iscsi_session_setup increments the driver reference + * count which wouldn't let the driver to be unloaded. + * so calling module_put function to decrement the + * reference count. + **/ + module_put(qla4xxx_iscsi_transport.owner); + sess = cls_sess->dd_data; + ddb_entry = sess->dd_data; + ddb_entry->sess = cls_sess; + + cls_sess->recovery_tmo = ql4xsess_recovery_tmo; + memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry, + sizeof(struct dev_db_entry)); + + qla4xxx_setup_flash_ddb_entry(ha, ddb_entry); + + cls_conn = iscsi_conn_setup(cls_sess, + sizeof(struct qla_conn), + conn_id); + if (!cls_conn) + goto exit_ddb_list; + + ddb_entry->conn = cls_conn; + + /* Setup ep, for displaying attributes in sysfs */ + ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry); + if (ep) { + ep->conn = cls_conn; + cls_conn->ep = ep; + } else { + DEBUG2(ql4_printk(KERN_ERR, ha, + "Unable to get ep\n")); + } + + /* Update sess/conn params */ + qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, + cls_conn); + + if (is_reset == RESET_ADAPTER) { + iscsi_block_session(cls_sess); + /* Use the relogin path to discover new devices + * by short-circuting the logic of setting + * timer to relogin - instead set the flags + * to initiate login right away. + */ + set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); + set_bit(DF_RELOGIN, &ddb_entry->flags); + } + } +continue_next_nt: + if (next_idx == 0) + break; + } +exit_ddb_list: + qla4xxx_free_nt_list(&list_nt); + if (fw_ddb_entry) + dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); + + qla4xxx_free_ddb_index(ha); +} + + /** * qla4xxx_probe_adapter - callback function to probe HBA * @pdev: pointer to pci_dev structure @@ -3298,7 +4233,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, * firmware * NOTE: interrupts enabled upon successful completion */ - status = qla4xxx_initialize_adapter(ha); + status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); while ((!test_bit(AF_ONLINE, &ha->flags)) && init_retry_count++ < MAX_INIT_RETRIES) { @@ -3319,7 +4254,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) continue; - status = qla4xxx_initialize_adapter(ha); + status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); } if (!test_bit(AF_ONLINE, &ha->flags)) { @@ -3386,12 +4321,16 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, ha->host_no, ha->firmware_version[0], ha->firmware_version[1], ha->patch_number, ha->build_number); - qla4xxx_create_chap_list(ha); - if (qla4xxx_setup_boot_info(ha)) ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n", __func__); + /* Perform the build ddb list and login to each */ + qla4xxx_build_ddb_list(ha, INIT_ADAPTER); + iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb); + + qla4xxx_create_chap_list(ha); + qla4xxx_create_ifaces(ha); return 0; @@ -3449,6 +4388,38 @@ static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha) } } +static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha) +{ + struct ddb_entry *ddb_entry; + int options; + int idx; + + for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) { + + ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx); + if ((ddb_entry != NULL) && + (ddb_entry->ddb_type == FLASH_DDB)) { + + options = LOGOUT_OPTION_CLOSE_SESSION; + if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) + == QLA_ERROR) + ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", + __func__); + + qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); + /* + * we have decremented the reference count of the driver + * when we setup the session to have the driver unload + * to be seamless without actually destroying the + * session + **/ + try_module_get(qla4xxx_iscsi_transport.owner); + iscsi_destroy_endpoint(ddb_entry->conn->ep); + qla4xxx_free_ddb(ha, ddb_entry); + iscsi_session_teardown(ddb_entry->sess); + } + } +} /** * qla4xxx_remove_adapter - calback function to remove adapter. * @pci_dev: PCI device pointer @@ -3465,9 +4436,11 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) /* destroy iface from sysfs */ qla4xxx_destroy_ifaces(ha); - if (ha->boot_kset) + if ((!ql4xdisablesysfsboot) && ha->boot_kset) iscsi_boot_destroy_kset(ha->boot_kset); + qla4xxx_destroy_fw_ddb_session(ha); + scsi_remove_host(ha->host); qla4xxx_free_adapter(ha); @@ -4115,7 +5088,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) qla4_8xxx_idc_unlock(ha); clear_bit(AF_FW_RECOVERY, &ha->flags); - rval = qla4xxx_initialize_adapter(ha); + rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); qla4_8xxx_idc_lock(ha); if (rval != QLA_SUCCESS) { @@ -4151,7 +5124,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == QLA82XX_DEV_READY)) { clear_bit(AF_FW_RECOVERY, &ha->flags); - rval = qla4xxx_initialize_adapter(ha); + rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); if (rval == QLA_SUCCESS) { ret = qla4xxx_request_irqs(ha); if (ret) { diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index c15347d..5254e57 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.02.00-k8" +#define QLA4XXX_DRIVER_VERSION "5.02.00-k9" -- cgit v0.10.2 From e1cd89c507b41e4021ce6fb0d19d230f6a932ccd Mon Sep 17 00:00:00 2001 From: Tomas Henzl Date: Thu, 1 Dec 2011 21:38:42 -0600 Subject: [SCSI] qla4xxx: a small loop fix When the qla4xxx_get_fwddb_entry returns QLA_ERROR the nex_idx is not updated, for (idx = 0; idx < max_ddbs; idx = next_idx) { ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL, &next_idx, &state, &conn_err, NULL, NULL); if (ret == QLA_ERROR) continue; This means there is a risk that the 'idx < max_ddbs' condition will never met and the loop will loop forever. Fix this by explicitly increasing the next_idx in the error condition. Maybe a break instead of continue is more appropriate, leaving the decision on the qlogic maintainer. Signed-off-by: Tomas Henzl Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 0497873..1bdfa81 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -787,8 +787,10 @@ void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL, &next_idx, &state, &conn_err, NULL, NULL); - if (ret == QLA_ERROR) + if (ret == QLA_ERROR) { + next_idx++; continue; + } if (state == DDB_DS_NO_CONNECTION_ACTIVE || state == DDB_DS_SESSION_FAILED) { DEBUG2(ql4_printk(KERN_INFO, ha, -- cgit v0.10.2 From ff1d0319ac6a5fd859884b30c0a3cb6733b8fb2d Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 1 Dec 2011 21:38:43 -0600 Subject: [SCSI] qla4xxx: check for failed conn setup iscsi_conn_setup can fail so we must check for NULL being returned. Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 95910c9..4169c8b 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -1207,6 +1207,9 @@ qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx) DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), conn_idx); + if (!cls_conn) + return NULL; + sess = cls_sess->dd_data; ddb_entry = sess->dd_data; ddb_entry->conn = cls_conn; -- cgit v0.10.2 From a878185c3b93e692ace0d1628a47f3d75504ab4f Mon Sep 17 00:00:00 2001 From: Eddie Wai Date: Tue, 6 Dec 2011 22:41:21 -0800 Subject: [SCSI] bnx2i: Fixed kernel panic caused by unprotected task->sc->request deref During session recovery, the conn_stop call will trigger a flush to all outstanding SCSI cmds in the xmit queue. This will set all outstanding task->sc to NULL prior to the session_teardown call which frees the task memory. In the bnx2i SCSI response processing path, only the task was being checked for NULL under the session lock before the task->sc->request dereferencing. If there are outstanding SCSI cmd responses pending for process, the following kernel panic can be exposed where task->sc was found to be NULL. Call Trace: [ 69.720205] [] bnx2i_process_new_cqes+0x290/0x3c0 [bnx2i] [ 69.804289] [] bnx2i_fastpath_notification+0x33/0xa0 [bnx2 i] [ 69.891490] [] bnx2i_indicate_kcqe+0xdb/0x330 [bnx2i] [ 69.971427] [] service_kcqes+0x16e/0x1d0 [cnic] [ 70.045132] [] cnic_service_bnx2x_kcq+0x2a/0x50 [cnic] [ 70.126105] [] cnic_service_bnx2x_bh+0x43/0x140 [cnic] [ 70.207081] [] tasklet_action+0x66/0x110 [ 70.273521] [] __do_softirq+0xef/0x220 [ 70.337887] [] call_softirq+0x1c/0x30 This patch adds the !task->sc check and also protects the sc dereferencing under the session lock. Signed-off-by: Eddie Wai Signed-off-by: James Bottomley diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index dba72a4..1ad0b82 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -1906,18 +1906,19 @@ static int bnx2i_queue_scsi_cmd_resp(struct iscsi_session *session, spin_lock(&session->lock); task = iscsi_itt_to_task(bnx2i_conn->cls_conn->dd_data, cqe->itt & ISCSI_CMD_RESPONSE_INDEX); - if (!task) { + if (!task || !task->sc) { spin_unlock(&session->lock); return -EINVAL; } sc = task->sc; - spin_unlock(&session->lock); if (!blk_rq_cpu_valid(sc->request)) cpu = smp_processor_id(); else cpu = sc->request->cpu; + spin_unlock(&session->lock); + p = &per_cpu(bnx2i_percpu, cpu); spin_lock(&p->p_work_lock); if (unlikely(!p->iothread)) { -- cgit v0.10.2 From b51306c63449d7f06ffa689036ba49eb46e898b5 Mon Sep 17 00:00:00 2001 From: Ajaykumar Hotchandani Date: Mon, 12 Dec 2011 13:57:36 +0530 Subject: PCI: Set device power state to PCI_D0 for device without native PM support During test of one IB card with guest VM, found that, msi is not initialized properly. It turns out __write_msi_msg will do nothing if device current_state is not PCI_D0. And, that pci device does not have pm_cap in guest VM. There is an error in setting of power state to PCI_D0 in pci_enable_device(), but error is not returned for this. Following is code flow: pci_enable_device() --> __pci_enable_device_flags() --> do_pci_enable_device() --> pci_set_power_state() --> __pci_start_power_transition() We have following condition inside __pci_start_power_transition(): if (platform_pci_power_manageable(dev)) { error = platform_pci_set_power_state(dev, state); if (!error) pci_update_current_state(dev, state); } else { error = -ENODEV; /* Fall back to PCI_D0 if native PM is not supported */ if (!dev->pm_cap) dev->current_state = PCI_D0; } Here, from platform_pci_set_power_state(), acpi_pci_set_power_state() is getting called and that is failing with ENODEV because of following condition: if (!handle || ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0",&tmp))) return -ENODEV; Because of that, pci_update_current_state() is not getting called. With this patch, if device power state can not be set via platform_pci_set_power_state and that device does not have native pm support, then PCI device power state will be set to PCI_D0. -v2: This also reverts 47e9037ac16637cd7f12b8790ea7ce6680e42168, as it's not needed after this change. Acked-by: "Rafael J. Wysocki" Signed-off-by: Ajaykumar Hotchandani Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 68360d5..9ddf69e 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -225,7 +225,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); if (pdev) { - pdev->current_state = PCI_D0; slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); pci_dev_put(pdev); } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4788413..faccb89 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -664,6 +664,9 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) error = platform_pci_set_power_state(dev, state); if (!error) pci_update_current_state(dev, state); + /* Fall back to PCI_D0 if native PM is not supported */ + if (!dev->pm_cap) + dev->current_state = PCI_D0; } else { error = -ENODEV; /* Fall back to PCI_D0 if native PM is not supported */ -- cgit v0.10.2 From 51e708c1049e721b9c5c48d026bc97ca8497d39a Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Tue, 13 Dec 2011 20:43:16 -0800 Subject: mwifiex: avoid double list_del in command cancel path Command cancel path cancels the current command and moves it to free command queue. While doing that it deletes the command entry from the pending list. This is not correct as the entry has been already deleted from the pending list at 'mwifiex_exec_next_cmd'. Fixing it. Also making sure the stale command pointer is cleaned and unaccessible for later use. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index ac27815..6e0a3ea 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -939,7 +939,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; unsigned long cmd_flags; - unsigned long cmd_pending_q_flags; unsigned long scan_pending_q_flags; uint16_t cancel_scan_cmd = false; @@ -949,12 +948,9 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) cmd_node = adapter->curr_cmd; cmd_node->wait_q_enabled = false; cmd_node->cmd_flag |= CMD_F_CANCELED; - spin_lock_irqsave(&adapter->cmd_pending_q_lock, - cmd_pending_q_flags); - list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, - cmd_pending_q_flags); mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + mwifiex_complete_cmd(adapter, adapter->curr_cmd); + adapter->curr_cmd = NULL; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } @@ -981,7 +977,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); } adapter->cmd_wait_q.status = -1; - mwifiex_complete_cmd(adapter, adapter->curr_cmd); } /* -- cgit v0.10.2 From 81670a491849127cd5f86defd2cd03cef1b08d07 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 14 Dec 2011 08:22:35 -0800 Subject: iwlwifi: tx_sync only on PAN context Ted reported that he couldn't connect to some APs and bisected it to the tx_sync implementation. Disable it for the BSS context to fix this issue. Reported-by: Ted Ts'o Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bacc06c..e0e9a3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2850,6 +2850,9 @@ static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, int ret; u8 sta_id; + if (ctx->ctxid != IWL_RXON_CTX_PAN) + return 0; + IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->shrd->mutex); @@ -2898,6 +2901,9 @@ static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *ctx = vif_priv->ctx; + if (ctx->ctxid != IWL_RXON_CTX_PAN) + return; + IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->shrd->mutex); -- cgit v0.10.2 From 78feb35b8161acd95c33a703ed6ab6f554d29387 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 14 Dec 2011 08:22:36 -0800 Subject: iwlwifi: allow to switch to HT40 if not associated My previous patch 34a5b4b6af104cf18eb50748509528b9bdbc4036 iwlwifi: do not re-configure HT40 after associated Fix the case of HT40 after association on specified AP, but it break the association for some APs and cause not able to establish connection. We need to address HT40 before and after addociation. CC: stable@vger.kernel.org #3.0+ Reported-by: Andrej Gelenberg Signed-off-by: Wey-Yi Guy Tested-by: Andrej Gelenberg Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a7a6def..5c7c17c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -606,8 +606,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) if (ctx->ht.enabled) { /* if HT40 is used, it should not change * after associated except channel switch */ - if (iwl_is_associated_ctx(ctx) && - !ctx->ht.is_40mhz) + if (!ctx->ht.is_40mhz || + !iwl_is_associated_ctx(ctx)) iwlagn_config_ht40(conf, ctx); } else ctx->ht.is_40mhz = false; -- cgit v0.10.2 From 248b122b131202de95aaa3670e48465619bdff14 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 14 Dec 2011 21:59:30 +0200 Subject: usb: dwc3: core: fix cached revision on our structure All our revision macros are defined with the entire 32-bits which we read from GSNPSID register, so we must cache all 32-bits properly rather than masking the top 16-bits. This will fix all revision checks we have on current driver. Signed-off-by: Felipe Balbi diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 717ebc9..600d823 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -264,7 +264,7 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc) ret = -ENODEV; goto err0; } - dwc->revision = reg & DWC3_GSNPSREV_MASK; + dwc->revision = reg; dwc3_core_soft_reset(dwc); -- cgit v0.10.2 From 6f6c2aa33b915c574543f176dee89d7aefc115c1 Mon Sep 17 00:00:00 2001 From: john fastabend Date: Fri, 18 Nov 2011 13:35:56 -0800 Subject: [SCSI] fcoe: fix fcoe in a DCB environment by adding DCB notifiers to set skb priority Use DCB notifiers to set the skb priority to allow packets to be steered and tagged correctly over DCB enabled drivers that setup traffic classes. This allows queue_mapping() routines to be removed in these drivers that were previously inspecting the ethertype of every skb to mark FCoE/FIP frames. Signed-off-by: John Fastabend Signed-off-by: Robert Love Signed-off-by: James Bottomley diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index f3f440c..8d67467 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include #include #include @@ -101,6 +103,8 @@ static int fcoe_ddp_done(struct fc_lport *, u16); static int fcoe_ddp_target(struct fc_lport *, u16, struct scatterlist *, unsigned int); static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); +static int fcoe_dcb_app_notification(struct notifier_block *notifier, + ulong event, void *ptr); static bool fcoe_match(struct net_device *netdev); static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode); @@ -129,6 +133,11 @@ static struct notifier_block fcoe_cpu_notifier = { .notifier_call = fcoe_cpu_callback, }; +/* notification function for DCB events */ +static struct notifier_block dcb_notifier = { + .notifier_call = fcoe_dcb_app_notification, +}; + static struct scsi_transport_template *fcoe_nport_scsi_transport; static struct scsi_transport_template *fcoe_vport_scsi_transport; @@ -1522,6 +1531,8 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) skb_reset_network_header(skb); skb->mac_len = elen; skb->protocol = htons(ETH_P_FCOE); + skb->priority = port->priority; + if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && fcoe->realdev->features & NETIF_F_HW_VLAN_TX) { skb->vlan_tci = VLAN_TAG_PRESENT | @@ -1747,6 +1758,7 @@ int fcoe_percpu_receive_thread(void *arg) */ static void fcoe_dev_setup(void) { + register_dcbevent_notifier(&dcb_notifier); register_netdevice_notifier(&fcoe_notifier); } @@ -1755,9 +1767,69 @@ static void fcoe_dev_setup(void) */ static void fcoe_dev_cleanup(void) { + unregister_dcbevent_notifier(&dcb_notifier); unregister_netdevice_notifier(&fcoe_notifier); } +static struct fcoe_interface * +fcoe_hostlist_lookup_realdev_port(struct net_device *netdev) +{ + struct fcoe_interface *fcoe; + struct net_device *real_dev; + + list_for_each_entry(fcoe, &fcoe_hostlist, list) { + if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN) + real_dev = vlan_dev_real_dev(fcoe->netdev); + else + real_dev = fcoe->netdev; + + if (netdev == real_dev) + return fcoe; + } + return NULL; +} + +static int fcoe_dcb_app_notification(struct notifier_block *notifier, + ulong event, void *ptr) +{ + struct dcb_app_type *entry = ptr; + struct fcoe_interface *fcoe; + struct net_device *netdev; + struct fcoe_port *port; + int prio; + + if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE) + return NOTIFY_OK; + + netdev = dev_get_by_index(&init_net, entry->ifindex); + if (!netdev) + return NOTIFY_OK; + + fcoe = fcoe_hostlist_lookup_realdev_port(netdev); + dev_put(netdev); + if (!fcoe) + return NOTIFY_OK; + + if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) + prio = ffs(entry->app.priority) - 1; + else + prio = entry->app.priority; + + if (prio < 0) + return NOTIFY_OK; + + if (entry->app.protocol == ETH_P_FIP || + entry->app.protocol == ETH_P_FCOE) + fcoe->ctlr.priority = prio; + + if (entry->app.protocol == ETH_P_FCOE) { + port = lport_priv(fcoe->ctlr.lp); + port->priority = prio; + } + + return NOTIFY_OK; +} + /** * fcoe_device_notification() - Handler for net device events * @notifier: The context of the notification @@ -1966,6 +2038,46 @@ static bool fcoe_match(struct net_device *netdev) } /** + * fcoe_dcb_create() - Initialize DCB attributes and hooks + * @netdev: The net_device object of the L2 link that should be queried + * @port: The fcoe_port to bind FCoE APP priority with + * @ + */ +static void fcoe_dcb_create(struct fcoe_interface *fcoe) +{ +#ifdef CONFIG_DCB + int dcbx; + u8 fup, up; + struct net_device *netdev = fcoe->realdev; + struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); + struct dcb_app app = { + .priority = 0, + .protocol = ETH_P_FCOE + }; + + /* setup DCB priority attributes. */ + if (netdev && netdev->dcbnl_ops && netdev->dcbnl_ops->getdcbx) { + dcbx = netdev->dcbnl_ops->getdcbx(netdev); + + if (dcbx & DCB_CAP_DCBX_VER_IEEE) { + app.selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE; + up = dcb_ieee_getapp_mask(netdev, &app); + app.protocol = ETH_P_FIP; + fup = dcb_ieee_getapp_mask(netdev, &app); + } else { + app.selector = DCB_APP_IDTYPE_ETHTYPE; + up = dcb_getapp(netdev, &app); + app.protocol = ETH_P_FIP; + fup = dcb_getapp(netdev, &app); + } + + port->priority = ffs(up) ? ffs(up) - 1 : 0; + fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority; + } +#endif +} + +/** * fcoe_create() - Create a fcoe interface * @netdev : The net_device object the Ethernet interface to create on * @fip_mode: The FIP mode for this creation @@ -2008,6 +2120,9 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) /* Make this the "master" N_Port */ fcoe->ctlr.lp = lport; + /* setup DCB priority attributes. */ + fcoe_dcb_create(fcoe); + /* add to lports list */ fcoe_hostlist_add(lport); diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index c74c4b8..e7522dc 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -320,6 +320,7 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) skb_put(skb, sizeof(*sol)); skb->protocol = htons(ETH_P_FIP); + skb->priority = fip->priority; skb_reset_mac_header(skb); skb_reset_network_header(skb); fip->send(fip, skb); @@ -474,6 +475,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, } skb_put(skb, len); skb->protocol = htons(ETH_P_FIP); + skb->priority = fip->priority; skb_reset_mac_header(skb); skb_reset_network_header(skb); fip->send(fip, skb); @@ -566,6 +568,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport, cap->fip.fip_dl_len = htons(dlen / FIP_BPW); skb->protocol = htons(ETH_P_FIP); + skb->priority = fip->priority; skb_reset_mac_header(skb); skb_reset_network_header(skb); return 0; @@ -1911,6 +1914,7 @@ static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip, skb_put(skb, len); skb->protocol = htons(ETH_P_FIP); + skb->priority = fip->priority; skb_reset_mac_header(skb); skb_reset_network_header(skb); diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index d1e95c6..5a35a2a 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -147,6 +147,7 @@ struct fcoe_ctlr { u8 map_dest; u8 spma; u8 probe_tries; + u8 priority; u8 dest_addr[ETH_ALEN]; u8 ctl_src_addr[ETH_ALEN]; @@ -301,6 +302,7 @@ struct fcoe_percpu_s { * @lport: The associated local port * @fcoe_pending_queue: The pending Rx queue of skbs * @fcoe_pending_queue_active: Indicates if the pending queue is active + * @priority: Packet priority (DCB) * @max_queue_depth: Max queue depth of pending queue * @min_queue_depth: Min queue depth of pending queue * @timer: The queue timer @@ -316,6 +318,7 @@ struct fcoe_port { struct fc_lport *lport; struct sk_buff_head fcoe_pending_queue; u8 fcoe_pending_queue_active; + u8 priority; u32 max_queue_depth; u32 min_queue_depth; struct timer_list timer; -- cgit v0.10.2 From 2d173def737946d776110f044a811ecfe772e18b Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 7 Dec 2011 20:47:29 -0500 Subject: ARM: at91: delete the pcontrol_g20_defconfig In routine testing I found this file should not specify a site specific toolchain path. I suggested that the defconfigs should not be calling out site specific toolchain locations, so we should delete the setting of CROSS_COMPILE. In response, it was indicated that this is an obsolete defconfig and it should simply be deleted. Signed-off-by: Paul Gortmaker Acked-by: Jean-Christophe Plagniol-Villard diff --git a/arch/arm/configs/pcontrol_g20_defconfig b/arch/arm/configs/pcontrol_g20_defconfig deleted file mode 100644 index c75c9fc..0000000 --- a/arch/arm/configs/pcontrol_g20_defconfig +++ /dev/null @@ -1,175 +0,0 @@ -CONFIG_EXPERIMENTAL=y -CONFIG_CROSS_COMPILE="/opt/arm-2010q1/bin/arm-none-linux-gnueabi-" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_TREE_PREEMPT_RCU=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_NAMESPACES=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -# CONFIG_KALLSYMS is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_LBDAF is not set -# CONFIG_BLK_DEV_BSG is not set -CONFIG_DEFAULT_DEADLINE=y -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91SAM9G20=y -CONFIG_MACH_PCONTROL_G20=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_PREEMPT=y -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 mem=128M mtdparts=atmel_nand:128k(bootstrap)ro,256k(uboot)ro,128k(env1)ro,128k(env2)ro,2M(linux),-(root) root=/dev/mmcblk0p1 rootwait rw" -CONFIG_VFP=y -CONFIG_BINFMT_MISC=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_VLAN_8021Q=y -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_PHRAM=m -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_ATMEL_TCLIB=y -CONFIG_EEPROM_AT24=m -CONFIG_SCSI=m -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=m -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_MACVLAN=m -CONFIG_TUN=m -CONFIG_SMSC_PHY=m -CONFIG_BROADCOM_PHY=m -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_MACB=y -CONFIG_SMSC911X=m -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -# CONFIG_WLAN is not set -CONFIG_PPP=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_MPPE=m -CONFIG_INPUT_POLLDEV=y -CONFIG_INPUT_SPARSEKMAP=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=m -CONFIG_INPUT_EVBUG=m -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=m -CONFIG_KEYBOARD_MATRIX=m -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_INPUT_MISC=y -CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -# CONFIG_SERIO is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_SERIAL_MAX3100=m -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set -CONFIG_R3964=m -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -# CONFIG_I2C_HELPER_AUTO is not set -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=m -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -CONFIG_W1=m -CONFIG_W1_MASTER_GPIO=m -CONFIG_W1_SLAVE_DS2431=m -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT91SAM9X_WATCHDOG=y -# CONFIG_MFD_SUPPORT is not set -# CONFIG_HID_SUPPORT is not set -CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=m -CONFIG_USB_LIBUSUAL=y -CONFIG_USB_SERIAL=m -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_G_HID=m -CONFIG_MMC=y -CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_AUXDISPLAY=y -CONFIG_UIO=y -CONFIG_UIO_PDRV=y -CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set -CONFIG_IIO=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_V4=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ANSI_CPRNG=y -# CONFIG_CRYPTO_HW is not set -CONFIG_CRC_CCITT=y -- cgit v0.10.2 From 9f57bd4d6dc69a4e3bf43044fa00fcd24dd363e3 Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Thu, 15 Dec 2011 11:25:59 -0800 Subject: percpu: fix per_cpu_ptr_to_phys() handling of non-page-aligned addresses per_cpu_ptr_to_phys() incorrectly rounds up its result for non-kmalloc case to the page boundary, which is bogus for any non-page-aligned address. This affects the only in-tree user of this function - sysfs handler for per-cpu 'crash_notes' physical address. The trouble is that the crash_notes per-cpu variable is not page-aligned: crash_notes = 0xc08e8ed4 PER-CPU OFFSET VALUES: CPU 0: 3711f000 CPU 1: 37129000 CPU 2: 37133000 CPU 3: 3713d000 So, the per-cpu addresses are: crash_notes on CPU 0: f7a07ed4 => phys 36b57ed4 crash_notes on CPU 1: f7a11ed4 => phys 36b4ded4 crash_notes on CPU 2: f7a1bed4 => phys 36b43ed4 crash_notes on CPU 3: f7a25ed4 => phys 36b39ed4 However, /sys/devices/system/cpu/cpu*/crash_notes says: /sys/devices/system/cpu/cpu0/crash_notes: 36b57000 /sys/devices/system/cpu/cpu1/crash_notes: 36b4d000 /sys/devices/system/cpu/cpu2/crash_notes: 36b43000 /sys/devices/system/cpu/cpu3/crash_notes: 36b39000 As you can see, all values are rounded down to a page boundary. Consequently, this is where kexec sets up the NOTE segments, and thus where the secondary kernel is looking for them. However, when the first kernel crashes, it saves the notes to the unaligned addresses, where they are not found. Fix it by adding offset_in_page() to the translated page address. -tj: Combined Eugene's and Petr's commit messages. Signed-off-by: Eugene Surovegin Signed-off-by: Tejun Heo Reported-by: Petr Tesarik Cc: stable@kernel.org diff --git a/mm/percpu.c b/mm/percpu.c index 3bb810a..716eb4a 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1023,9 +1023,11 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr) if (!is_vmalloc_addr(addr)) return __pa(addr); else - return page_to_phys(vmalloc_to_page(addr)); + return page_to_phys(vmalloc_to_page(addr)) + + offset_in_page(addr); } else - return page_to_phys(pcpu_addr_to_page(addr)); + return page_to_phys(pcpu_addr_to_page(addr)) + + offset_in_page(addr); } /** -- cgit v0.10.2 From 6c52961743f38747401b47127b82159ab6d8a7a4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 15 Dec 2011 18:38:10 -0500 Subject: NFS: Fix a regression in nfs_file_llseek() After commit 06222e491e663dac939f04b125c9dc52126a75c4 (fs: handle SEEK_HOLE/SEEK_DATA properly in all fs's that define their own llseek) the behaviour of llseek() was changed so that it always revalidates the file size. The bug appears to be due to a logic error in the afore-mentioned commit, which always evaluates to 'true'. Reported-by: Roel Kluin Signed-off-by: Trond Myklebust Cc: stable@vger.kernel.org [>=3.1] diff --git a/fs/nfs/file.c b/fs/nfs/file.c index eca56d4..606ef0f 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -147,7 +147,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate * the cached file length */ - if (origin != SEEK_SET || origin != SEEK_CUR) { + if (origin != SEEK_SET && origin != SEEK_CUR) { struct inode *inode = filp->f_mapping->host; int retval = nfs_revalidate_file_size(inode, filp); -- cgit v0.10.2 From 7c17c7701cf3c176dc245aeabecb3ae4b166618f Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Thu, 15 Dec 2011 22:38:36 -0700 Subject: ARM: OMAP: hwmod data: fix iva and mailbox hwmods for OMAP 3 Seems the commit 7e89098 was overly aggressive in adding iva and mailbox hwmods so now they are registered twice. ------------[ cut here ]------------ WARNING: at arch/arm/mach-omap2/omap_hwmod.c:1959 omap_hwmod_register+0x104/0x12c() omap_hwmod: iva: _register returned -22 Modules linked in: [] (unwind_backtrace+0x0/0xec) from [] (warn_slowpath_common+0x4c/0x64) [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x2c/0x3c) [] (warn_slowpath_fmt+0x2c/0x3c) from [] (omap_hwmod_register+0x104/0x12c) [] (omap_hwmod_register+0x104/0x12c) from [] (omap3_init_early+0x1c/0x28) [] (omap3_init_early+0x1c/0x28) from [] (setup_arch+0x6b8/0x7a4) [] (setup_arch+0x6b8/0x7a4) from [] (start_kernel+0x6c/0x264) [] (start_kernel+0x6c/0x264) from [<80008040>] (0x80008040) ---[ end trace 1b75b31a2719ed1c ]--- ------------[ cut here ]------------ WARNING: at arch/arm/mach-omap2/omap_hwmod.c:1959 omap_hwmod_register+0x104/0x12c() omap_hwmod: mailbox: _register returned -22 Modules linked in: [] (unwind_backtrace+0x0/0xec) from [] (warn_slowpath_common+0x4c/0x64) [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x2c/0x3c) [] (warn_slowpath_fmt+0x2c/0x3c) from [] (omap_hwmod_register+0x104/0x12c) [] (omap_hwmod_register+0x104/0x12c) from [] (omap3_init_early+0x1c/0x28) [] (omap3_init_early+0x1c/0x28) from [] (setup_arch+0x6b8/0x7a4) [] (setup_arch+0x6b8/0x7a4) from [] (start_kernel+0x6c/0x264) [] (start_kernel+0x6c/0x264) from [<80008040>] (0x80008040) ---[ end trace 1b75b31a2719ed1d ]--- Signed-off-by: Felipe Contreras Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 7f8915a..eef43e2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3247,18 +3247,14 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { /* 3430ES1-only hwmods */ static __initdata struct omap_hwmod *omap3430es1_hwmods[] = { - &omap3xxx_iva_hwmod, &omap3430es1_dss_core_hwmod, - &omap3xxx_mailbox_hwmod, NULL }; /* 3430ES2+-only hwmods */ static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = { - &omap3xxx_iva_hwmod, &omap3xxx_dss_core_hwmod, &omap3xxx_usbhsotg_hwmod, - &omap3xxx_mailbox_hwmod, NULL }; -- cgit v0.10.2 From ab2789213d224202237292d78aaa0c386c7b28b2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 15 Dec 2011 11:47:00 -0800 Subject: sched: Fix select_idle_sibling() regression in selecting an idle SMT sibling Mike Galbraith reported that this recent commit: commit 4dcfe1025b513c2c1da5bf5586adb0e80148f612 Author: Peter Zijlstra Date: Thu Nov 10 13:01:10 2011 +0100 sched: Avoid SMT siblings in select_idle_sibling() if possible stopped selecting an idle SMT sibling when there are no idle cores in a single socket system. Intent of the select_idle_sibling() was to fallback to an idle SMT sibling, if it fails to identify an idle core. But this fallback was not happening on systems where all the scheduler domains had `SD_SHARE_PKG_RESOURCES' flag set. Fix it. Slightly bigger patch of cleaning all these goto's etc is queued up for the next release. Reported-by: Mike Galbraith Reported-by: Alex Shi Signed-off-by: Peter Zijlstra Signed-off-by: Suresh Siddha Link: http://lkml.kernel.org/r/1323978421.1984.244.camel@sbsiddha-desk.sc.intel.com Signed-off-by: Ingo Molnar diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index a78ed27..8a39fa3 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -2352,13 +2352,11 @@ again: if (!smt && (sd->flags & SD_SHARE_CPUPOWER)) continue; - if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) { - if (!smt) { - smt = 1; - goto again; - } + if (smt && !(sd->flags & SD_SHARE_CPUPOWER)) + break; + + if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) break; - } sg = sd->groups; do { @@ -2378,6 +2376,10 @@ next: sg = sg->next; } while (sg != sd->groups); } + if (!smt) { + smt = 1; + goto again; + } done: rcu_read_unlock(); -- cgit v0.10.2 From 6ae0516b8a50ece5d766be608a305707e0450060 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 16 Dec 2011 14:04:23 +0100 Subject: block, cfq: fix empty queue crash caused by request merge All requests of a queue could be merged to other requests of other queue. Such queue will not have request in it, but it's in service tree. This will cause kernel oops. I encounter a BUG_ON() in cfq_dispatch_request() with next patch, but the issue should exist without the patch. Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 4c12869..3548705 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1655,6 +1655,8 @@ cfq_merged_requests(struct request_queue *q, struct request *rq, struct request *next) { struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_data *cfqd = q->elevator->elevator_data; + /* * reposition in fifo if next is older than rq */ @@ -1669,6 +1671,16 @@ cfq_merged_requests(struct request_queue *q, struct request *rq, cfq_remove_request(next); cfq_blkiocg_update_io_merged_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(next), rq_is_sync(next)); + + cfqq = RQ_CFQQ(next); + /* + * all requests of this queue are merged to other queues, delete it + * from the service tree. If it's the active_queue, + * cfq_dispatch_requests() will choose to expire it or do idle + */ + if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list) && + cfqq != cfqd->active_queue) + cfq_del_cfqq_rr(cfqd, cfqq); } static int cfq_allow_merge(struct request_queue *q, struct request *rq, -- cgit v0.10.2 From 8bd6960c6ae65d7f92bfb708154ee813417d7b26 Mon Sep 17 00:00:00 2001 From: KyongHo Cho Date: Fri, 16 Dec 2011 21:38:25 +0900 Subject: iommu: Initialize domain->handler in iommu_domain_alloc() Since it is not guaranteed that an iommu driver initializes in its domain_init() function, it must be initialized with NULL to prevent calling a function in an arbitrary location when iommu fault occurred. Signed-off-by: KyongHo Cho Signed-off-by: Joerg Roedel diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 2fb2963..5b5fa5c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -90,7 +90,7 @@ struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) if (bus == NULL || bus->iommu_ops == NULL) return NULL; - domain = kmalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc(sizeof(*domain), GFP_KERNEL); if (!domain) return NULL; -- cgit v0.10.2 From b3bba872ddb0320a7ecb54decae53c13ceb2ed4c Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Thu, 8 Dec 2011 16:53:54 -0600 Subject: writeback: show writeback reason with __print_symbolic This makes the binary trace understandable by trace-cmd. CC: Dave Chinner CC: Curt Wohlgemuth CC: Steven Rostedt Signed-off-by: Wu Fengguang diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ac86f8b..517f211 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -47,17 +47,6 @@ struct wb_writeback_work { struct completion *done; /* set if the caller waits */ }; -const char *wb_reason_name[] = { - [WB_REASON_BACKGROUND] = "background", - [WB_REASON_TRY_TO_FREE_PAGES] = "try_to_free_pages", - [WB_REASON_SYNC] = "sync", - [WB_REASON_PERIODIC] = "periodic", - [WB_REASON_LAPTOP_TIMER] = "laptop_timer", - [WB_REASON_FREE_MORE_MEM] = "free_more_memory", - [WB_REASON_FS_FREE_SPACE] = "fs_free_space", - [WB_REASON_FORKER_THREAD] = "forker_thread" -}; - /* * Include the creation of the trace points after defining the * wb_writeback_work structure so that the definition remains local to this diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index b99caa8..99d1d0d 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h @@ -21,6 +21,16 @@ {I_REFERENCED, "I_REFERENCED"} \ ) +#define WB_WORK_REASON \ + {WB_REASON_BACKGROUND, "background"}, \ + {WB_REASON_TRY_TO_FREE_PAGES, "try_to_free_pages"}, \ + {WB_REASON_SYNC, "sync"}, \ + {WB_REASON_PERIODIC, "periodic"}, \ + {WB_REASON_LAPTOP_TIMER, "laptop_timer"}, \ + {WB_REASON_FREE_MORE_MEM, "free_more_memory"}, \ + {WB_REASON_FS_FREE_SPACE, "fs_free_space"}, \ + {WB_REASON_FORKER_THREAD, "forker_thread"} + struct wb_writeback_work; DECLARE_EVENT_CLASS(writeback_work_class, @@ -55,7 +65,7 @@ DECLARE_EVENT_CLASS(writeback_work_class, __entry->for_kupdate, __entry->range_cyclic, __entry->for_background, - wb_reason_name[__entry->reason] + __print_symbolic(__entry->reason, WB_WORK_REASON) ) ); #define DEFINE_WRITEBACK_WORK_EVENT(name) \ @@ -184,7 +194,8 @@ TRACE_EVENT(writeback_queue_io, __entry->older, /* older_than_this in jiffies */ __entry->age, /* older_than_this in relative milliseconds */ __entry->moved, - wb_reason_name[__entry->reason]) + __print_symbolic(__entry->reason, WB_WORK_REASON) + ) ); TRACE_EVENT(global_dirty_state, -- cgit v0.10.2 From 513c4dd698d1341a53d8a7530ecefb44cb1e2395 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 12 Dec 2011 20:06:49 +0000 Subject: ARM: picoxcell: remove mach/memory.h mach/memory.h is no longer required for simple platforms so remove it for picoxcell. Signed-off-by: Jamie Iles diff --git a/arch/arm/mach-picoxcell/include/mach/memory.h b/arch/arm/mach-picoxcell/include/mach/memory.h deleted file mode 100644 index 40a8c17..0000000 --- a/arch/arm/mach-picoxcell/include/mach/memory.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ -- cgit v0.10.2 From 98e27a5c13badb5c56d9d1d6c8ec210753ac1195 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 12 Dec 2011 20:17:37 +0000 Subject: ARM: picoxcell: don't reserve irq_descs All irq_desc's are now dynamically allocated so we don't need to statically reserve them. v2: - select SPARSE_IRQ and set .nr_irqs to NR_IRQS_LEGACY to skip ISA and IRQ 0. Signed-off-by: Jamie Iles diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index abba5b8..0d961cb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -650,6 +650,7 @@ config ARCH_PICOXCELL select HAVE_SCHED_CLOCK select HAVE_TCM select NO_IOPORT + select SPARSE_IRQ select USE_OF help This enables support for systems based on the Picochip picoXcell diff --git a/arch/arm/mach-picoxcell/common.c b/arch/arm/mach-picoxcell/common.c index ad871bd..d34b333 100644 --- a/arch/arm/mach-picoxcell/common.c +++ b/arch/arm/mach-picoxcell/common.c @@ -45,7 +45,7 @@ static void __init picoxcell_init_irq(void) DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") .map_io = picoxcell_map_io, - .nr_irqs = ARCH_NR_IRQS, + .nr_irqs = NR_IRQS_LEGACY, .init_irq = picoxcell_init_irq, .handle_irq = vic_handle_irq, .timer = &picoxcell_timer, diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h index 4d13ed9..59eac1e 100644 --- a/arch/arm/mach-picoxcell/include/mach/irqs.h +++ b/arch/arm/mach-picoxcell/include/mach/irqs.h @@ -1,8 +1,6 @@ /* * Copyright (c) 2011 Picochip Ltd., Jamie Iles * - * This file contains the hardware definitions of the picoXcell SoC devices. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -16,10 +14,7 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -#define ARCH_NR_IRQS 64 -#define NR_IRQS (128 + ARCH_NR_IRQS) - -#define IRQ_VIC0_BASE 0 -#define IRQ_VIC1_BASE 32 +/* We dynamically allocate our irq_desc's. */ +#define NR_IRQS 0 #endif /* __MACH_IRQS_H */ -- cgit v0.10.2 From 8f37a0b49656ed961598351da3ebdd89f2d2e5b4 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 12 Dec 2011 20:21:39 +0000 Subject: ARM: picoxcell: move io mappings to common.c Now that we have lost our machine specific ioremap() we just have one mapping that covers all peripherals. Move this to common.c to simplify things a little. Signed-off-by: Jamie Iles diff --git a/arch/arm/mach-picoxcell/Makefile b/arch/arm/mach-picoxcell/Makefile index c550b63..e5ec4a8 100644 --- a/arch/arm/mach-picoxcell/Makefile +++ b/arch/arm/mach-picoxcell/Makefile @@ -1,3 +1,2 @@ obj-y := common.o obj-y += time.o -obj-y += io.o diff --git a/arch/arm/mach-picoxcell/common.c b/arch/arm/mach-picoxcell/common.c index d34b333..febee47 100644 --- a/arch/arm/mach-picoxcell/common.c +++ b/arch/arm/mach-picoxcell/common.c @@ -16,12 +16,25 @@ #include #include +#include #include #include #include "common.h" +static struct map_desc io_map __initdata = { + .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE), + .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE), + .length = PICOXCELL_PERIPH_LENGTH, + .type = MT_DEVICE, +}; + +static void __init picoxcell_map_io(void) +{ + iotable_init(&io_map, 1); +} + static void __init picoxcell_init_machine(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); diff --git a/arch/arm/mach-picoxcell/common.h b/arch/arm/mach-picoxcell/common.h index 5263f0f..83d55ab 100644 --- a/arch/arm/mach-picoxcell/common.h +++ b/arch/arm/mach-picoxcell/common.h @@ -13,6 +13,5 @@ #include extern struct sys_timer picoxcell_timer; -extern void picoxcell_map_io(void); #endif /* __PICOXCELL_COMMON_H__ */ diff --git a/arch/arm/mach-picoxcell/io.c b/arch/arm/mach-picoxcell/io.c deleted file mode 100644 index 39e9b9e..0000000 --- a/arch/arm/mach-picoxcell/io.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * All enquiries to support@picochip.com - */ -#include -#include -#include -#include - -#include - -#include -#include - -#include "common.h" - -void __init picoxcell_map_io(void) -{ - struct map_desc io_map = { - .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE), - .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE), - .length = PICOXCELL_PERIPH_LENGTH, - .type = MT_DEVICE, - }; - - iotable_init(&io_map, 1); -} -- cgit v0.10.2 From a53bfa07369b7c3448a60d29f0fc2e81751ed0b7 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 12 Dec 2011 20:28:42 +0000 Subject: MAINTAINERS: add maintainer entry for Picochip picoxcell Add maintainer entry for the picoxcell machine support and associated drivers. v2: - add 2-level pattern for drivers Signed-off-by: Jamie Iles diff --git a/MAINTAINERS b/MAINTAINERS index 4475602..4b823ff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5133,6 +5133,15 @@ L: linux-mtd@lists.infradead.org S: Maintained F: drivers/mtd/devices/phram.c +PICOXCELL SUPPORT +M: Jamie Iles +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +T: git git://github.com/jamieiles/linux-2.6-ji.git +S: Supported +F: arch/arm/mach-picoxcell +F: drivers/*/picoxcell* +F: drivers/*/*/picoxcell* + PIN CONTROL SUBSYSTEM M: Linus Walleij S: Maintained -- cgit v0.10.2 From 37de03ea1246c8280f6c8c6f61ea98973e9b9448 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 9 Dec 2011 20:55:03 +0800 Subject: i2c: i2c-s3c2410: Add a cpu_relax() to busy wait for bus idle Be a bit more friendly. Signed-off-by: Mark Brown Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 2754cef..37b2de1 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -534,6 +534,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, /* first, try busy waiting briefly */ do { + cpu_relax(); iicstat = readl(i2c->regs + S3C2410_IICSTAT); } while ((iicstat & S3C2410_IICSTAT_START) && --spins); -- cgit v0.10.2 From 8ebe661dd2ab16e2e9c272ed5c86019c7407b9a1 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Fri, 9 Dec 2011 15:33:55 +0530 Subject: i2c-s3c2410: Fix return code of s3c24xx_i2c_parse_dt_gpio s3c24xx_i2c_parse_dt_gpio is called when cfg_gpio is not defined in the platform data of the i2c device. When DT is not enabled, the above function always returns -EINVAL. Since there can be some i2c devices which don't need to configure any gpio lines, the probe of such devices would fail here. Changing the default return value to success would fix this issue. Signed-off-by: Tushar Behera Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 37b2de1..4c17180 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -787,7 +787,7 @@ static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) #else static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) { - return -EINVAL; + return 0; } static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) -- cgit v0.10.2 From 1d5a34fe990c9e2e2f672b238ad881d0d4ed376b Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Tue, 6 Dec 2011 10:25:58 -0800 Subject: I2C: OMAP: fix FIFO usage for OMAP4 Currently the fifo depth is set to zero for OMAP4 which disables the FIFO usage. This patch enables the FIFO usage for I2C transactions on OMAP4 also. Tested on omap4430 and 3430. Tested-and-Reported-by: Nishanth Menon Signed-off-by: Shubhrajyoti D Signed-off-by: Kevin Hilman Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index a43d002..fa23faa 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1047,13 +1047,14 @@ omap_i2c_probe(struct platform_device *pdev) * size. This is to ensure that we can handle the status on int * call back latencies. */ - if (dev->rev >= OMAP_I2C_REV_ON_3530_4430) { - dev->fifo_size = 0; + + dev->fifo_size = (dev->fifo_size / 2); + + if (dev->rev >= OMAP_I2C_REV_ON_3530_4430) dev->b_hw = 0; /* Disable hardware fixes */ - } else { - dev->fifo_size = (dev->fifo_size / 2); + else dev->b_hw = 1; /* Enable hardware fixes */ - } + /* calculate wakeup latency constraint for MPU */ if (dev->set_mpu_wkup_lat != NULL) dev->latency = (1000000 * dev->fifo_size) / -- cgit v0.10.2 From 0d5fb5ea7d0e6bc84a523c39a666d7eb1a7e43de Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 29 Nov 2011 15:19:10 +0800 Subject: i2c-eg20t: correct the driver init order of pch_i2c_probe() Before registering an adapter to i2c subsystem, we need make sure driver is ready for incoming i2c xfer, becasue the i2c_add_adapter() may trigger a i2c device driver's proble function which may start some real i2c xfer. I met this issue when integrating a TSC2007 i2c touch screen device with the i2c-eg20t driver. This patch will call request_irq() and hw init before calling i2c_add_adapter(). Signed-off-by: Feng Tang Signed-off-by: Ben Dooks diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 8cebef4..18936ac 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -893,6 +893,13 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev, /* Set the number of I2C channel instance */ adap_info->ch_num = id->driver_data; + ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, + KBUILD_MODNAME, adap_info); + if (ret) { + pch_pci_err(pdev, "request_irq FAILED\n"); + goto err_request_irq; + } + for (i = 0; i < adap_info->ch_num; i++) { pch_adap = &adap_info->pch_data[i].pch_adapter; adap_info->pch_i2c_suspended = false; @@ -910,28 +917,23 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev, pch_adap->dev.parent = &pdev->dev; + pch_i2c_init(&adap_info->pch_data[i]); ret = i2c_add_adapter(pch_adap); if (ret) { pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i); - goto err_i2c_add_adapter; + goto err_add_adapter; } - - pch_i2c_init(&adap_info->pch_data[i]); - } - ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, - KBUILD_MODNAME, adap_info); - if (ret) { - pch_pci_err(pdev, "request_irq FAILED\n"); - goto err_i2c_add_adapter; } pci_set_drvdata(pdev, adap_info); pch_pci_dbg(pdev, "returns %d.\n", ret); return 0; -err_i2c_add_adapter: +err_add_adapter: for (j = 0; j < i; j++) i2c_del_adapter(&adap_info->pch_data[j].pch_adapter); + free_irq(pdev->irq, adap_info); +err_request_irq: pci_iounmap(pdev, base_addr); err_pci_iomap: pci_release_regions(pdev); -- cgit v0.10.2 From fa0ad6575f6d459e215dded90b10cc455a889145 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sat, 5 Nov 2011 12:21:30 +0100 Subject: kconfig: adapt update-po-config to new UML layout Commit 5c48b108 ("um: take arch/um/sys-x86 to arch/x86/um") broke the make target update-po-config, as its symlink trick (again) fails. (Previous breakage was fixed with commit bdc69ca4 ("kconfig: change update-po-config to reflect new layout of arch/um").) The new UML layout allows to drop the symlick trick entirely. And if, one day, another architecture supports UML too, that should now work without again breaking this make target. Signed-off-by: Paul Bolle Signed-off-by: Michal Marek diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index ba573fe..914833d 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -60,8 +60,8 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h --directory=$(srctree) --directory=$(objtree) \ --output $(obj)/config.pot $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot - $(Q)ln -fs Kconfig.x86 arch/um/Kconfig - $(Q)(for i in `ls $(srctree)/arch/*/Kconfig`; \ + $(Q)(for i in `ls $(srctree)/arch/*/Kconfig \ + $(srctree)/arch/*/um/Kconfig`; \ do \ echo " GEN $$i"; \ $(obj)/kxgettext $$i \ @@ -69,7 +69,6 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h done ) $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ --output $(obj)/linux.pot - $(Q)rm -f $(srctree)/arch/um/Kconfig $(Q)rm -f $(obj)/config.pot PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig -- cgit v0.10.2 From 497f16f21a04060098c0da6ed522fbcafb90c0db Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 17 Dec 2011 18:33:37 -0800 Subject: pci: Fix hotplug of Express Module with pci bridges I noticed that hotplug of one setup does not work with recent change in pci tree. After checking the bridge conf setup, I noticed that the bridges get assigned but do not get enabled. The reason is the following commit, while simply ignores bridge resources when enabling a pci device: | commit bbef98ab0f019f1b0c25c1acdf1683c68933d41b | Author: Ram Pai | Date: Sun Nov 6 10:33:10 2011 +0800 | | PCI: defer enablement of SRIOV BARS |... | NOTE: Note, there is subtle change in the pci_enable_device() API. Any | driver that depends on SRIOV BARS to be enabled in pci_enable_device() | can fail. Put back bridge resource and ROM resource checking to fix the problem. That should fix regression like BIOS does not assign correct resource to bridge. Discussion can be found at: http://www.spinics.net/lists/linux-pci/msg12874.html Signed-off-by: Yinghai Lu Acked-by: Jesse Barnes Signed-off-by: Linus Torvalds diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index faccb89..6d4a531 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1129,7 +1129,11 @@ static int __pci_enable_device_flags(struct pci_dev *dev, if (atomic_add_return(1, &dev->enable_cnt) > 1) return 0; /* already enabled */ - for (i = 0; i < PCI_ROM_RESOURCE; i++) + /* only skip sriov related */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) + if (dev->resource[i].flags & flags) + bars |= (1 << i); + for (i = PCI_BRIDGE_RESOURCES; i < DEVICE_COUNT_RESOURCE; i++) if (dev->resource[i].flags & flags) bars |= (1 << i); -- cgit v0.10.2 From 2f0778afac79bd8d226225556858a636931eeabc Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 15 Dec 2011 12:19:23 +0100 Subject: ARM: 7205/2: sched_clock: allow sched_clock to be selected at runtime sched_clock() is yet another blocker on the road to the single image. This patch implements an idea by Russell King: http://www.spinics.net/lists/linux-omap/msg49561.html Instead of asking the platform to implement both sched_clock() itself and the rollover callback, simply register a read() function, and let the ARM code care about sched_clock() itself, the conversion to ns and the rollover. sched_clock() uses this read() function as an indirection to the platform code. If the platform doesn't provide a read(), the code falls back to the jiffy counter (just like the default sched_clock). This allow some simplifications and possibly some footprint gain when multiple platforms are compiled in. Among the drawbacks, the removal of the *_fixed_sched_clock optimization which could negatively impact some platforms (sa1100, tegra, versatile and omap). Tested on 11MPCore, OMAP4 and Tegra. Cc: Imre Kaloz Cc: Eric Miao Cc: Colin Cross Cc: Erik Gilling Cc: Olof Johansson Cc: Sascha Hauer Cc: Alessandro Rubini Cc: STEricsson Cc: Lennert Buytenhek Cc: Ben Dooks Tested-by: Jamie Iles Tested-by: Tony Lindgren Tested-by: Kyungmin Park Acked-by: Linus Walleij Acked-by: Nicolas Pitre Acked-by: Krzysztof Halasa Acked-by: Kukjin Kim Signed-off-by: Marc Zyngier Signed-off-by: Russell King diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h index c8e6ddf..e3f7572 100644 --- a/arch/arm/include/asm/sched_clock.h +++ b/arch/arm/include/asm/sched_clock.h @@ -8,113 +8,7 @@ #ifndef ASM_SCHED_CLOCK #define ASM_SCHED_CLOCK -#include -#include - -struct clock_data { - u64 epoch_ns; - u32 epoch_cyc; - u32 epoch_cyc_copy; - u32 mult; - u32 shift; -}; - -#define DEFINE_CLOCK_DATA(name) struct clock_data name - -static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) -{ - return (cyc * mult) >> shift; -} - -/* - * Atomically update the sched_clock epoch. Your update callback will - * be called from a timer before the counter wraps - read the current - * counter value, and call this function to safely move the epochs - * forward. Only use this from the update callback. - */ -static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask) -{ - unsigned long flags; - u64 ns = cd->epoch_ns + - cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift); - - /* - * Write epoch_cyc and epoch_ns in a way that the update is - * detectable in cyc_to_fixed_sched_clock(). - */ - raw_local_irq_save(flags); - cd->epoch_cyc = cyc; - smp_wmb(); - cd->epoch_ns = ns; - smp_wmb(); - cd->epoch_cyc_copy = cyc; - raw_local_irq_restore(flags); -} - -/* - * If your clock rate is known at compile time, using this will allow - * you to optimize the mult/shift loads away. This is paired with - * init_fixed_sched_clock() to ensure that your mult/shift are correct. - */ -static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd, - u32 cyc, u32 mask, u32 mult, u32 shift) -{ - u64 epoch_ns; - u32 epoch_cyc; - - /* - * Load the epoch_cyc and epoch_ns atomically. We do this by - * ensuring that we always write epoch_cyc, epoch_ns and - * epoch_cyc_copy in strict order, and read them in strict order. - * If epoch_cyc and epoch_cyc_copy are not equal, then we're in - * the middle of an update, and we should repeat the load. - */ - do { - epoch_cyc = cd->epoch_cyc; - smp_rmb(); - epoch_ns = cd->epoch_ns; - smp_rmb(); - } while (epoch_cyc != cd->epoch_cyc_copy); - - return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift); -} - -/* - * Otherwise, you need to use this, which will obtain the mult/shift - * from the clock_data structure. Use init_sched_clock() with this. - */ -static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd, - u32 cyc, u32 mask) -{ - return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift); -} - -/* - * Initialize the clock data - calculate the appropriate multiplier - * and shift. Also setup a timer to ensure that the epoch is refreshed - * at the appropriate time interval, which will call your update - * handler. - */ -void init_sched_clock(struct clock_data *, void (*)(void), - unsigned int, unsigned long); - -/* - * Use this initialization function rather than init_sched_clock() if - * you're using cyc_to_fixed_sched_clock, which will warn if your - * constants are incorrect. - */ -static inline void init_fixed_sched_clock(struct clock_data *cd, - void (*update)(void), unsigned int bits, unsigned long rate, - u32 mult, u32 shift) -{ - init_sched_clock(cd, update, bits, rate); - if (cd->mult != mult || cd->shift != shift) { - pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n" - "sched_clock: fix multiply/shift to avoid scheduler hiccups\n", - mult, shift, cd->mult, cd->shift); - } -} - extern void sched_clock_postinit(void); +extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); #endif diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 9a46370..5416c7c 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -14,61 +14,153 @@ #include +struct clock_data { + u64 epoch_ns; + u32 epoch_cyc; + u32 epoch_cyc_copy; + u32 mult; + u32 shift; +}; + static void sched_clock_poll(unsigned long wrap_ticks); static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); -static void (*sched_clock_update_fn)(void); + +static struct clock_data cd = { + .mult = NSEC_PER_SEC / HZ, +}; + +static u32 __read_mostly sched_clock_mask = 0xffffffff; + +static u32 notrace jiffy_sched_clock_read(void) +{ + return (u32)(jiffies - INITIAL_JIFFIES); +} + +static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; + +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) +{ + return (cyc * mult) >> shift; +} + +static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) +{ + u64 epoch_ns; + u32 epoch_cyc; + + /* + * Load the epoch_cyc and epoch_ns atomically. We do this by + * ensuring that we always write epoch_cyc, epoch_ns and + * epoch_cyc_copy in strict order, and read them in strict order. + * If epoch_cyc and epoch_cyc_copy are not equal, then we're in + * the middle of an update, and we should repeat the load. + */ + do { + epoch_cyc = cd.epoch_cyc; + smp_rmb(); + epoch_ns = cd.epoch_ns; + smp_rmb(); + } while (epoch_cyc != cd.epoch_cyc_copy); + + return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, cd.mult, cd.shift); +} + +/* + * Atomically update the sched_clock epoch. + */ +static void notrace update_sched_clock(void) +{ + unsigned long flags; + u32 cyc; + u64 ns; + + cyc = read_sched_clock(); + ns = cd.epoch_ns + + cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask, + cd.mult, cd.shift); + /* + * Write epoch_cyc and epoch_ns in a way that the update is + * detectable in cyc_to_fixed_sched_clock(). + */ + raw_local_irq_save(flags); + cd.epoch_cyc = cyc; + smp_wmb(); + cd.epoch_ns = ns; + smp_wmb(); + cd.epoch_cyc_copy = cyc; + raw_local_irq_restore(flags); +} static void sched_clock_poll(unsigned long wrap_ticks) { mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks)); - sched_clock_update_fn(); + update_sched_clock(); } -void __init init_sched_clock(struct clock_data *cd, void (*update)(void), - unsigned int clock_bits, unsigned long rate) +void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) { unsigned long r, w; u64 res, wrap; char r_unit; - sched_clock_update_fn = update; + BUG_ON(bits > 32); + WARN_ON(!irqs_disabled()); + WARN_ON(read_sched_clock != jiffy_sched_clock_read); + read_sched_clock = read; + sched_clock_mask = (1 << bits) - 1; /* calculate the mult/shift to convert counter ticks to ns. */ - clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0); + clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0); r = rate; if (r >= 4000000) { r /= 1000000; r_unit = 'M'; - } else { + } else if (r >= 1000) { r /= 1000; r_unit = 'k'; - } + } else + r_unit = ' '; /* calculate how many ns until we wrap */ - wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift); + wrap = cyc_to_ns((1ULL << bits) - 1, cd.mult, cd.shift); do_div(wrap, NSEC_PER_MSEC); w = wrap; /* calculate the ns resolution of this counter */ - res = cyc_to_ns(1ULL, cd->mult, cd->shift); + res = cyc_to_ns(1ULL, cd.mult, cd.shift); pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n", - clock_bits, r, r_unit, res, w); + bits, r, r_unit, res, w); /* * Start the timer to keep sched_clock() properly updated and * sets the initial epoch. */ sched_clock_timer.data = msecs_to_jiffies(w - (w / 10)); - update(); + update_sched_clock(); /* * Ensure that sched_clock() starts off at 0ns */ - cd->epoch_ns = 0; + cd.epoch_ns = 0; + + pr_debug("Registered %pF as sched_clock source\n", read); +} + +unsigned long long notrace sched_clock(void) +{ + u32 cyc = read_sched_clock(); + return cyc_to_sched_clock(cyc, sched_clock_mask); } void __init sched_clock_postinit(void) { + /* + * If no sched_clock function has been provided at that point, + * make it the final one one. + */ + if (read_sched_clock == jiffy_sched_clock_read) + setup_sched_clock(jiffy_sched_clock_read, 32, HZ); + sched_clock_poll(sched_clock_timer.data); } diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index b86a005..c1b12f9 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -403,18 +402,9 @@ void __init ixp4xx_sys_init(void) /* * sched_clock() */ -static DEFINE_CLOCK_DATA(cd); - -unsigned long long notrace sched_clock(void) +static u32 notrace ixp4xx_read_sched_clock(void) { - u32 cyc = *IXP4XX_OSTS; - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace ixp4xx_update_sched_clock(void) -{ - u32 cyc = *IXP4XX_OSTS; - update_sched_clock(&cd, cyc, (u32)~0); + return *IXP4XX_OSTS; } /* @@ -430,7 +420,7 @@ unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; EXPORT_SYMBOL(ixp4xx_timer_freq); static void __init ixp4xx_clocksource_init(void) { - init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); + setup_sched_clock(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq); clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32, ixp4xx_clocksource_read); diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 4e91ee6..71fc4ee 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -42,8 +41,6 @@ #define MAX_DELTA (0xfffffffe) #define MIN_DELTA (16) -static DEFINE_CLOCK_DATA(cd); - /* * FIXME: the timer needs some delay to stablize the counter capture */ @@ -59,16 +56,9 @@ static inline uint32_t timer_read(void) return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1)); } -unsigned long long notrace sched_clock(void) +static u32 notrace mmp_read_sched_clock(void) { - u32 cyc = timer_read(); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace mmp_update_sched_clock(void) -{ - u32 cyc = timer_read(); - update_sched_clock(&cd, cyc, (u32)~0); + return timer_read(); } static irqreturn_t timer_interrupt(int irq, void *dev_id) @@ -201,7 +191,7 @@ void __init timer_init(int irq) { timer_config(); - init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE); + setup_sched_clock(mmp_read_sched_clock, 32, CLOCK_TICK_RATE); ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index 485a21d..b8faffa 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -190,30 +189,9 @@ static __init void omap_init_mpu_timer(unsigned long rate) * --------------------------------------------------------------------------- */ -static DEFINE_CLOCK_DATA(cd); - -static inline unsigned long long notrace _omap_mpu_sched_clock(void) -{ - u32 cyc = ~omap_mpu_timer_read(1); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -#ifndef CONFIG_OMAP_32K_TIMER -unsigned long long notrace sched_clock(void) -{ - return _omap_mpu_sched_clock(); -} -#else -static unsigned long long notrace omap_mpu_sched_clock(void) -{ - return _omap_mpu_sched_clock(); -} -#endif - -static void notrace mpu_update_sched_clock(void) +static u32 notrace omap_mpu_read_sched_clock(void) { - u32 cyc = ~omap_mpu_timer_read(1); - update_sched_clock(&cd, cyc, (u32)~0); + return ~omap_mpu_timer_read(1); } static void __init omap_init_clocksource(unsigned long rate) @@ -223,7 +201,7 @@ static void __init omap_init_clocksource(unsigned long rate) "%s: can't register clocksource!\n"; omap_mpu_timer_start(1, ~0, 1); - init_sched_clock(&cd, mpu_update_sched_clock, 32, rate); + setup_sched_clock(omap_mpu_read_sched_clock, 32, rate); if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate, 300, 32, clocksource_mmio_readl_down)) @@ -254,30 +232,6 @@ static inline void omap_mpu_timer_init(void) } #endif /* CONFIG_OMAP_MPU_TIMER */ -#if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER) -static unsigned long long (*preferred_sched_clock)(void); - -unsigned long long notrace sched_clock(void) -{ - if (!preferred_sched_clock) - return 0; - - return preferred_sched_clock(); -} - -static inline void preferred_sched_clock_init(bool use_32k_sched_clock) -{ - if (use_32k_sched_clock) - preferred_sched_clock = omap_32k_sched_clock; - else - preferred_sched_clock = omap_mpu_sched_clock; -} -#else -static inline void preferred_sched_clock_init(bool use_32k_sched_clcok) -{ -} -#endif - static inline int omap_32k_timer_usable(void) { int res = false; @@ -299,12 +253,8 @@ static inline int omap_32k_timer_usable(void) */ static void __init omap1_timer_init(void) { - if (omap_32k_timer_usable()) { - preferred_sched_clock_init(1); - } else { + if (!omap_32k_timer_usable()) omap_mpu_timer_init(); - preferred_sched_clock_init(0); - } } struct sys_timer omap1_timer = { diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 9edcd52..6eeff0e 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -254,7 +254,6 @@ static struct omap_dm_timer clksrc; /* * clocksource */ -static DEFINE_CLOCK_DATA(cd); static cycle_t clocksource_read_cycles(struct clocksource *cs) { return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1); @@ -268,23 +267,12 @@ static struct clocksource clocksource_gpt = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void notrace dmtimer_update_sched_clock(void) +static u32 notrace dmtimer_read_sched_clock(void) { - u32 cyc; - - cyc = __omap_dm_timer_read_counter(&clksrc, 1); - - update_sched_clock(&cd, cyc, (u32)~0); -} - -unsigned long long notrace sched_clock(void) -{ - u32 cyc = 0; - if (clksrc.reserved) - cyc = __omap_dm_timer_read_counter(&clksrc, 1); + return __omap_dm_timer_read_counter(clksrc.io_base, 1); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); + return 0; } /* Setup free-running counter for clocksource */ @@ -301,7 +289,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id, __omap_dm_timer_load_start(&clksrc, OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); - init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); + setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate); if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) pr_err("Could not register clocksource %s\n", diff --git a/arch/arm/mach-picoxcell/time.c b/arch/arm/mach-picoxcell/time.c index 90a554f..6c89cf8 100644 --- a/arch/arm/mach-picoxcell/time.c +++ b/arch/arm/mach-picoxcell/time.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -66,21 +65,11 @@ static void picoxcell_add_clocksource(struct device_node *source_timer) dw_apb_clocksource_register(cs); } -static DEFINE_CLOCK_DATA(cd); static void __iomem *sched_io_base; -unsigned long long notrace sched_clock(void) +unsigned u32 notrace picoxcell_read_sched_clock(void) { - cycle_t cyc = sched_io_base ? __raw_readl(sched_io_base) : 0; - - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace picoxcell_update_sched_clock(void) -{ - cycle_t cyc = sched_io_base ? __raw_readl(sched_io_base) : 0; - - update_sched_clock(&cd, cyc, (u32)~0); + return __raw_readl(sched_io_base); } static const struct of_device_id picoxcell_rtc_ids[] __initconst = { @@ -100,7 +89,7 @@ static void picoxcell_init_sched_clock(void) timer_get_base_and_rate(sched_timer, &sched_io_base, &rate); of_node_put(sched_timer); - init_sched_clock(&cd, picoxcell_update_sched_clock, 32, rate); + setup_sched_clock(picoxcell_read_sched_clock, 32, rate); } static const struct of_device_id picoxcell_timer_ids[] __initconst = { diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index de68470..b503049 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -32,18 +31,10 @@ * long as there is always less than 582 seconds between successive * calls to sched_clock() which should always be the case in practice. */ -static DEFINE_CLOCK_DATA(cd); -unsigned long long notrace sched_clock(void) +static u32 notrace pxa_read_sched_clock(void) { - u32 cyc = OSCR; - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace pxa_update_sched_clock(void) -{ - u32 cyc = OSCR; - update_sched_clock(&cd, cyc, (u32)~0); + return OSCR; } @@ -119,7 +110,7 @@ static void __init pxa_timer_init(void) OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; - init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); + setup_sched_clock(pxa_read_sched_clock, 32, clock_tick_rate); clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4); ckevt_pxa_osmr0.max_delta_ns = diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index fa66024..1ee6d4c 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -12,7 +12,6 @@ #include #include #include -#include /* just for sched_clock() - funny that */ #include #include @@ -20,29 +19,9 @@ #include #include -/* - * This is the SA11x0 sched_clock implementation. - */ -static DEFINE_CLOCK_DATA(cd); - -/* - * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz, - * NSEC_PER_SEC, 60). - * This gives a resolution of about 271ns and a wrap period of about 19min. - */ -#define SC_MULT 2275555556u -#define SC_SHIFT 23 - -unsigned long long notrace sched_clock(void) -{ - u32 cyc = OSCR; - return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); -} - -static void notrace sa1100_update_sched_clock(void) +static u32 notrace sa100_read_sched_clock(void) { - u32 cyc = OSCR; - update_sched_clock(&cd, cyc, (u32)~0); + return OSCR; } #define MIN_OSCR_DELTA 2 @@ -109,8 +88,7 @@ static void __init sa1100_timer_init(void) OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; - init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32, - 3686400, SC_MULT, SC_SHIFT); + setup_sched_clock(sa1100_read_sched_clock, 32, 3686400); clockevents_calc_mult_shift(&ckevt_sa1100_osmr0, 3686400, 4); ckevt_sa1100_osmr0.max_delta_ns = diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index e2272d2..732c724 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -106,25 +105,9 @@ static struct clock_event_device tegra_clockevent = { .set_mode = tegra_timer_set_mode, }; -static DEFINE_CLOCK_DATA(cd); - -/* - * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60). - * This gives a resolution of about 1us and a wrap period of about 1h11min. - */ -#define SC_MULT 4194304000u -#define SC_SHIFT 22 - -unsigned long long notrace sched_clock(void) -{ - u32 cyc = timer_readl(TIMERUS_CNTR_1US); - return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); -} - -static void notrace tegra_update_sched_clock(void) +static u32 notrace tegra_read_sched_clock(void) { - u32 cyc = timer_readl(TIMERUS_CNTR_1US); - update_sched_clock(&cd, cyc, (u32)~0); + return timer_readl(TIMERUS_CNTR_1US); } /* @@ -218,8 +201,7 @@ static void __init tegra_init_timer(void) WARN(1, "Unknown clock rate"); } - init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32, - 1000000, SC_MULT, SC_SHIFT); + setup_sched_clock(tegra_read_sched_clock, 32, 1000000); if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) { diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index 5f51bde..bc1c789 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c @@ -9,7 +9,6 @@ * Author: Linus Walleij */ #include -#include #include #include #include @@ -337,18 +336,10 @@ static struct irqaction u300_timer_irq = { * this wraps around for now, since it is just a relative time * stamp. (Inspired by OMAP implementation.) */ -static DEFINE_CLOCK_DATA(cd); -unsigned long long notrace sched_clock(void) +static u32 notrace u300_read_sched_clock(void) { - u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace u300_update_sched_clock(void) -{ - u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); - update_sched_clock(&cd, cyc, (u32)~0); + return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); } @@ -366,7 +357,7 @@ static void __init u300_timer_init(void) clk_enable(clk); rate = clk_get_rate(clk); - init_sched_clock(&cd, u300_update_sched_clock, 32, rate); + setup_sched_clock(u300_read_sched_clock, 32, rate); /* * Disable the "OS" and "DD" timers - these are designed for Symbian! diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 568dd02..cbfbbe4 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -52,21 +51,12 @@ static struct clocksource iop_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static DEFINE_CLOCK_DATA(cd); - /* * IOP sched_clock() implementation via its clocksource. */ -unsigned long long notrace sched_clock(void) +static u32 notrace iop_read_sched_clock(void) { - u32 cyc = 0xffffffffu - read_tcr1(); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace iop_update_sched_clock(void) -{ - u32 cyc = 0xffffffffu - read_tcr1(); - update_sched_clock(&cd, cyc, (u32)~0); + return 0xffffffffu - read_tcr1(); } /* @@ -152,7 +142,7 @@ void __init iop_init_time(unsigned long tick_rate) { u32 timer_ctl; - init_sched_clock(&cd, iop_update_sched_clock, 32, tick_rate); + setup_sched_clock(iop_read_sched_clock, 32, tick_rate); ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ); iop_tick_rate = tick_rate; diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 4b0fe28..1c96cdb 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -108,18 +108,9 @@ static void gpt_irq_acknowledge(void) static void __iomem *sched_clock_reg; -static DEFINE_CLOCK_DATA(cd); -unsigned long long notrace sched_clock(void) +static u32 notrace mxc_read_sched_clock(void) { - cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; - - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace mxc_update_sched_clock(void) -{ - cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; - update_sched_clock(&cd, cyc, (u32)~0); + return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; } static int __init mxc_clocksource_init(struct clk *timer_clk) @@ -129,7 +120,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk) sched_clock_reg = reg; - init_sched_clock(&cd, mxc_update_sched_clock, 32, c); + setup_sched_clock(mxc_read_sched_clock, 32, c); return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, clocksource_mmio_readl_up); } diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index 30b6433..ad1b45b 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -79,23 +78,12 @@ void __iomem *mtu_base; /* Assigned by machine code */ * local implementation which uses the clocksource to get some * better resolution when scheduling the kernel. */ -static DEFINE_CLOCK_DATA(cd); - -unsigned long long notrace sched_clock(void) +static u32 notrace nomadik_read_sched_clock(void) { - u32 cyc; - if (unlikely(!mtu_base)) return 0; - cyc = -readl(mtu_base + MTU_VAL(0)); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - -static void notrace nomadik_update_sched_clock(void) -{ - u32 cyc = -readl(mtu_base + MTU_VAL(0)); - update_sched_clock(&cd, cyc, (u32)~0); + return -readl(mtu_base + MTU_VAL(0)); } #endif @@ -231,9 +219,11 @@ void __init nmdk_timer_init(void) rate, 200, 32, clocksource_mmio_readl_down)) pr_err("timer: failed to initialize clock source %s\n", "mtu_0"); + #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK - init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate); + setup_sched_clock(nomadik_read_sched_clock, 32, rate); #endif + /* Timer 1 is used for events */ clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index a6cbb71..5f0f229 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -37,41 +36,9 @@ static void __iomem *timer_32k_base; #define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410 -/* - * Returns current time from boot in nsecs. It's OK for this to wrap - * around for now, as it's just a relative time stamp. - */ -static DEFINE_CLOCK_DATA(cd); - -/* - * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60). - * This gives a resolution of about 30us and a wrap period of about 36hrs. - */ -#define SC_MULT 4000000000u -#define SC_SHIFT 17 - -static inline unsigned long long notrace _omap_32k_sched_clock(void) -{ - u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0; - return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); -} - -#if defined(CONFIG_OMAP_32K_TIMER) && !defined(CONFIG_OMAP_MPU_TIMER) -unsigned long long notrace sched_clock(void) -{ - return _omap_32k_sched_clock(); -} -#else -unsigned long long notrace omap_32k_sched_clock(void) -{ - return _omap_32k_sched_clock(); -} -#endif - -static void notrace omap_update_sched_clock(void) +static u32 notrace omap_32k_read_sched_clock(void) { - u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0; - update_sched_clock(&cd, cyc, (u32)~0); + return timer_32k_base ? __raw_readl(timer_32k_base) : 0; } /** @@ -147,8 +114,7 @@ int __init omap_init_clocksource_32k(void) clocksource_mmio_readl_up)) printk(err, "32k_counter"); - init_fixed_sched_clock(&cd, omap_update_sched_clock, 32, - 32768, SC_MULT, SC_SHIFT); + setup_sched_clock(omap_32k_read_sched_clock, 32, 32768); } return 0; } diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 257f977..b4d7ec3 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -31,7 +31,6 @@ #include extern int __init omap_init_clocksource_32k(void); -extern unsigned long long notrace omap_32k_sched_clock(void); extern void omap_reserve(void); extern int omap_dss_reset(struct omap_hwmod *); diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 69a6136..1ed8d13 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -60,24 +59,10 @@ static u32 ticks_per_jiffy; * Orion's sched_clock implementation. It has a resolution of * at least 7.5ns (133MHz TCLK). */ -static DEFINE_CLOCK_DATA(cd); -unsigned long long notrace sched_clock(void) +static u32 notrace orion_read_sched_clock(void) { - u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF); - return cyc_to_sched_clock(&cd, cyc, (u32)~0); -} - - -static void notrace orion_update_sched_clock(void) -{ - u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF); - update_sched_clock(&cd, cyc, (u32)~0); -} - -static void __init setup_sched_clock(unsigned long tclk) -{ - init_sched_clock(&cd, orion_update_sched_clock, 32, tclk); + return ~readl(timer_base + TIMER0_VAL_OFF); } /* @@ -217,7 +202,7 @@ orion_time_init(u32 _bridge_base, u32 _bridge_timer1_clr_mask, /* * Set scale and timer for sched_clock. */ - setup_sched_clock(tclk); + setup_sched_clock(orion_read_sched_clock, 32, tclk); /* * Setup free-running clocksource timer (interrupts diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c index c833e7b..17c0a2c 100644 --- a/arch/arm/plat-s5p/s5p-time.c +++ b/arch/arm/plat-s5p/s5p-time.c @@ -10,7 +10,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include @@ -321,26 +320,14 @@ static void __iomem *s5p_timer_reg(void) * this wraps around for now, since it is just a relative time * stamp. (Inspired by U300 implementation.) */ -static DEFINE_CLOCK_DATA(cd); - -unsigned long long notrace sched_clock(void) +static u32 notrace s5p_read_sched_clock(void) { void __iomem *reg = s5p_timer_reg(); if (!reg) return 0; - return cyc_to_sched_clock(&cd, ~__raw_readl(reg), (u32)~0); -} - -static void notrace s5p_update_sched_clock(void) -{ - void __iomem *reg = s5p_timer_reg(); - - if (!reg) - return; - - update_sched_clock(&cd, ~__raw_readl(reg), (u32)~0); + return ~__raw_readl(reg); } static void __init s5p_clocksource_init(void) @@ -358,7 +345,7 @@ static void __init s5p_clocksource_init(void) s5p_time_setup(timer_source.source_id, TCNT_MAX); s5p_time_start(timer_source.source_id, PERIODIC); - init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate); + setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", clock_rate, 250, 32, clocksource_mmio_readl_down)) diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c index 3d6a4c2..b33b74c 100644 --- a/arch/arm/plat-versatile/sched-clock.c +++ b/arch/arm/plat-versatile/sched-clock.c @@ -18,41 +18,24 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include -#include #include #include -static DEFINE_CLOCK_DATA(cd); static void __iomem *ctr; -/* - * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60). - * This gives a resolution of about 41ns and a wrap period of about 178s. - */ -#define SC_MULT 2796202667u -#define SC_SHIFT 26 - -unsigned long long notrace sched_clock(void) +static u32 notrace versatile_read_sched_clock(void) { - if (ctr) { - u32 cyc = readl(ctr); - return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, - SC_MULT, SC_SHIFT); - } else - return 0; -} + if (ctr) + return readl(ctr); -static void notrace versatile_update_sched_clock(void) -{ - u32 cyc = readl(ctr); - update_sched_clock(&cd, cyc, (u32)~0); + return 0; } void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate) { ctr = reg; - init_fixed_sched_clock(&cd, versatile_update_sched_clock, - 32, rate, SC_MULT, SC_SHIFT); + setup_sched_clock(versatile_read_sched_clock, 32, rate); } -- cgit v0.10.2 From 215e83d971a04f04d191c7f702943412a19408fd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 14 Dec 2011 18:15:42 +0100 Subject: ARM: 7233/1: ux500: remove overlapping iotable entries The overlapping iotable mapping entries for the ux500 Cortex A9 SCU, CPU control and TWD are no longer accepted by the kernel. Remove the overlaps so the machine boots again. Cc: Srinidhi Kasagar Cc: Rabin Vincent Reported-by: Daniel Lezcano Acked-by: Nicolas Pitre Signed-off-by: Linus Walleij Signed-off-by: Russell King diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 9de1af0..5323286 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -30,12 +30,11 @@ static struct map_desc u5500_uart_io_desc[] __initdata = { }; static struct map_desc u5500_io_desc[] __initdata = { - __IO_DEV_DESC(U5500_GIC_CPU_BASE, SZ_4K), + /* SCU base also covers GIC CPU BASE and TWD with its 4K page */ + __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K), __IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K), - __IO_DEV_DESC(U5500_TWD_BASE, SZ_4K), __IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K), - __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K), __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 13e8890..7f2729c 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -35,12 +35,11 @@ static struct map_desc u8500_uart_io_desc[] __initdata = { }; static struct map_desc u8500_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), + /* SCU base also covers GIC CPU BASE and TWD with its 4K page */ + __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), - __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), - __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K), -- cgit v0.10.2 From b63038d6f4ca5d1849ce01d9fc5bb9cb426dec73 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:51:04 +0100 Subject: ARM: 7214/1: mmc: mmci: Fixup handling of MCI_STARTBITERR The interrupt was previously enabled and then correctly cleared. Now we also handle it correctly. Cc: Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 50b5f99..82659811 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -675,7 +675,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, unsigned int status) { /* First check for errors */ - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| + MCI_TXUNDERRUN|MCI_RXOVERRUN)) { u32 remain, success; /* Terminate the DMA transfer */ @@ -955,8 +956,9 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); data = host->data; - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| - MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND) && data) + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| + MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| + MCI_DATABLOCKEND) && data) mmci_data_irq(host, data, status); cmd = host->cmd; -- cgit v0.10.2 From 3b6e3c73851a9a4b0e6ed9d378206341dd65e8a5 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:58:43 +0100 Subject: ARM: 7220/1: mmc: mmci: Fixup error handling for dma When getting a cmd irq during an ongoing data transfer with dma, the dma job were never terminated. This is now corrected. Cc: Tested-by: Linus Walleij Signed-off-by: Per Forlin Signed-off-by: Ulf Hansson Signed-off-by: Russell King diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 82659811..0726e59 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -755,8 +755,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } if (!cmd->data || cmd->error) { - if (host->data) + if (host->data) { + /* Terminate the DMA transfer */ + if (dma_inprogress(host)) + mmci_dma_data_error(host); mmci_stop_data(host); + } mmci_request_end(host, cmd->mrq); } else if (!(cmd->data->flags & MMC_DATA_READ)) { mmci_start_data(host, cmd->data); -- cgit v0.10.2 From bfd912c0dd119d98923494d0cbeee571df756b8a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 29 Nov 2011 14:51:15 +0100 Subject: ARM: u300: delete memory.h Last merge window the memory maps for U300 were simplified so we can now safely delete memory.h. Acked-by: Nicolas Pitre Signed-off-by: Linus Walleij diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e084b7e..a814f93 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -892,7 +892,6 @@ config ARCH_U300 select HAVE_MACH_CLKDEV select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB - select NEED_MACH_MEMORY_H help Support for ST-Ericsson U300 series mobile platforms. diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h deleted file mode 100644 index c808f34..0000000 --- a/arch/arm/mach-u300/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * - * arch/arm/mach-u300/include/mach/memory.h - * - * - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * Memory virtual/physical mapping constants. - * Author: Linus Walleij - * Author: Jonas Aaberg - */ - -#ifndef __MACH_MEMORY_H -#define __MACH_MEMORY_H - -#define PLAT_PHYS_OFFSET UL(0x48000000) -#define BOOT_PARAMS_OFFSET 0x100 - -#endif diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c index 89422ee..b200312 100644 --- a/arch/arm/mach-u300/u300.c +++ b/arch/arm/mach-u300/u300.c @@ -46,7 +46,7 @@ static void __init u300_init_machine(void) MACHINE_START(U300, MACH_U300_STRING) /* Maintainer: Linus Walleij */ - .atag_offset = BOOT_PARAMS_OFFSET, + .atag_offset = 0x100, .map_io = u300_map_io, .init_irq = u300_init_irq, .timer = &u300_timer, -- cgit v0.10.2 From 36e999a83a4a4badd389901eb6d23a30e199b8db Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 8 Dec 2011 17:23:21 -0800 Subject: Bluetooth: Prevent uninitialized data access in L2CAP configuration When configuring an ERTM or streaming mode connection, remote devices are expected to send an RFC option in a successful config response. A misbehaving remote device might not send an RFC option, and the L2CAP code should not access uninitialized data in this case. Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 5ea94a1..17b5b1c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2152,7 +2152,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi void *ptr = req->data; int type, olen; unsigned long val; - struct l2cap_conf_rfc rfc; + struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data); @@ -2271,6 +2271,16 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) } } + /* Use sane default values in case a misbehaving remote device + * did not send an RFC option. + */ + rfc.mode = chan->mode; + rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); + rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); + rfc.max_pdu_size = cpu_to_le16(chan->imtu); + + BT_ERR("Expected RFC option was not found, using defaults"); + done: switch (rfc.mode) { case L2CAP_MODE_ERTM: -- cgit v0.10.2 From 79e654787c67f6b05f73366ff8ccac72ba7249e6 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Tue, 6 Dec 2011 16:23:26 -0800 Subject: Bluetooth: Clear RFCOMM session timer when disconnecting last channel When the last RFCOMM data channel is closed, a timer is normally set up to disconnect the control channel at a later time. If the control channel disconnect command is sent with the timer pending, the timer needs to be cancelled. If the timer is not cancelled in this situation, the reference counting logic for the RFCOMM session does not work correctly when the remote device closes the L2CAP connection. The session is freed at the wrong time, leading to a kernel panic. Signed-off-by: Mat Martineau Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 4e32e18..2d28dfe 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1146,6 +1146,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) if (list_empty(&s->dlcs)) { s->state = BT_DISCONN; rfcomm_send_disc(s, 0); + rfcomm_session_clear_timer(s); } break; -- cgit v0.10.2 From d7660918fce210f421cc58c060ca3de71e4ffd37 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Sun, 18 Dec 2011 22:33:30 -0200 Subject: Revert "Bluetooth: Revert: Fix L2CAP connection establishment" This reverts commit 4dff523a913197e3314c7b0d08734ab037709093. It was reported that this patch cause issues when trying to connect to legacy devices so reverting it. Reported-by: David Fries Signed-off-by: Gustavo F. Padovan diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index e0af723..c1c597e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) goto encrypt; auth: - if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) + if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) return 0; if (!hci_conn_auth(conn, sec_level, auth_type)) -- cgit v0.10.2 From 8015e3defe491d305b20c2e64b154b999e6da065 Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Mon, 19 Dec 2011 17:57:52 +0800 Subject: ALSA: atmel/ac97c: using software reset instead hardware reset if not available Signed-off-by: Bo Shen Acked-by: Nicolas Ferre Signed-off-by: Takashi Iwai diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 6e5adde..73516f6 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -899,6 +899,10 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) /* AC97 v2.2 specifications says minimum 1 us. */ udelay(2); gpio_set_value(chip->reset_pin, 1); + } else { + ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA); + udelay(2); + ac97c_writel(chip, MR, AC97C_MR_ENA); } } -- cgit v0.10.2 From b1b73d095084e754562961c443aa8f6587a55f8e Mon Sep 17 00:00:00 2001 From: Kusanagi Kouichi Date: Mon, 19 Dec 2011 18:13:19 +0900 Subject: time/clocksource: Fix kernel-doc warnings Fix various KernelDoc build warnings. Signed-off-by: Kusanagi Kouichi Cc: John Stultz Link: http://lkml.kernel.org/r/20111219091320.0D5AF6FC03D@msa105.auone-net.jp Signed-off-by: Ingo Molnar diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index c86c940..081147d 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -71,7 +71,7 @@ struct timecounter { /** * cyclecounter_cyc2ns - converts cycle counter cycles to nanoseconds - * @tc: Pointer to cycle counter. + * @cc: Pointer to cycle counter. * @cycles: Cycles * * XXX - This could use some mult_lxl_ll() asm optimization. Same code @@ -114,7 +114,7 @@ extern u64 timecounter_read(struct timecounter *tc); * time base as values returned by * timecounter_read() * @tc: Pointer to time counter. - * @cycle: a value returned by tc->cc->read() + * @cycle_tstamp: a value returned by tc->cc->read() * * Cycle counts that are converted correctly as long as they * fall into the interval [-1/2 max cycle count, +1/2 max cycle count], @@ -156,11 +156,12 @@ extern u64 timecounter_cyc2time(struct timecounter *tc, * @mult: cycle to nanosecond multiplier * @shift: cycle to nanosecond divisor (power of two) * @max_idle_ns: max idle time permitted by the clocksource (nsecs) - * @maxadj maximum adjustment value to mult (~11%) + * @maxadj: maximum adjustment value to mult (~11%) * @flags: flags describing special properties * @archdata: arch-specific data * @suspend: suspend function for the clocksource, if necessary * @resume: resume function for the clocksource, if necessary + * @cycle_last: most recent cycle counter value seen by ::read() */ struct clocksource { /* @@ -187,6 +188,7 @@ struct clocksource { void (*suspend)(struct clocksource *cs); void (*resume)(struct clocksource *cs); + /* private: */ #ifdef CONFIG_CLOCKSOURCE_WATCHDOG /* Watchdog related data, used by the framework */ struct list_head wd_list; @@ -261,6 +263,9 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant) /** * clocksource_cyc2ns - converts clocksource cycles to nanoseconds + * @cycles: cycles + * @mult: cycle to nanosecond multiplier + * @shift: cycle to nanosecond divisor (power of two) * * Converts cycles to nanoseconds, using the given mult and shift. * diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index da2f760..d3ad022 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -647,7 +647,7 @@ static void clocksource_enqueue(struct clocksource *cs) /** * __clocksource_updatefreq_scale - Used update clocksource with new freq - * @t: clocksource to be registered + * @cs: clocksource to be registered * @scale: Scale factor multiplied against freq to get clocksource hz * @freq: clocksource frequency (cycles per second) divided by scale * @@ -699,7 +699,7 @@ EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale); /** * __clocksource_register_scale - Used to install new clocksources - * @t: clocksource to be registered + * @cs: clocksource to be registered * @scale: Scale factor multiplied against freq to get clocksource hz * @freq: clocksource frequency (cycles per second) divided by scale * @@ -727,7 +727,7 @@ EXPORT_SYMBOL_GPL(__clocksource_register_scale); /** * clocksource_register - Used to install new clocksources - * @t: clocksource to be registered + * @cs: clocksource to be registered * * Returns -EBUSY if registration fails, zero otherwise. */ @@ -761,6 +761,8 @@ static void __clocksource_change_rating(struct clocksource *cs, int rating) /** * clocksource_change_rating - Change the rating of a registered clocksource + * @cs: clocksource to be changed + * @rating: new rating */ void clocksource_change_rating(struct clocksource *cs, int rating) { @@ -772,6 +774,7 @@ EXPORT_SYMBOL(clocksource_change_rating); /** * clocksource_unregister - remove a registered clocksource + * @cs: clocksource to be unregistered */ void clocksource_unregister(struct clocksource *cs) { @@ -787,6 +790,7 @@ EXPORT_SYMBOL(clocksource_unregister); /** * sysfs_show_current_clocksources - sysfs interface for current clocksource * @dev: unused + * @attr: unused * @buf: char buffer to be filled with clocksource list * * Provides sysfs interface for listing current clocksource. @@ -807,6 +811,7 @@ sysfs_show_current_clocksources(struct sys_device *dev, /** * sysfs_override_clocksource - interface for manually overriding clocksource * @dev: unused + * @attr: unused * @buf: name of override clocksource * @count: length of buffer * @@ -842,6 +847,7 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, /** * sysfs_show_available_clocksources - sysfs interface for listing clocksource * @dev: unused + * @attr: unused * @buf: char buffer to be filled with clocksource list * * Provides sysfs interface for listing registered clocksources -- cgit v0.10.2 From c32987918efaa6949c5b2f3e43b654a742b18f7d Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Tue, 13 Dec 2011 00:37:56 +0100 Subject: mtd: plat_ram: call mtd_device_register only if partition data exists mtd_device_parse_register() registers the device as a whole if no partition data is passed so there is no reason to call mtd_device_register() after that. Signed-off-by: Ilya Yanok Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 94f5534..45876d0 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -227,10 +227,14 @@ static int platram_probe(struct platform_device *pdev) if (!err) dev_info(&pdev->dev, "registered mtd device\n"); - /* add the whole device. */ - err = mtd_device_register(info->mtd, NULL, 0); - if (err) - dev_err(&pdev->dev, "failed to register the entire device\n"); + if (pdata->nr_partitions) { + /* add the whole device. */ + err = mtd_device_register(info->mtd, NULL, 0); + if (err) { + dev_err(&pdev->dev, + "failed to register the entire device\n"); + } + } return err; -- cgit v0.10.2 From 5776ac2eb33164c77cdb4d2b48feee15616eaba3 Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Mon, 19 Dec 2011 11:23:28 +0800 Subject: ARM:imx:fix pwm period value According to imx pwm RM, the real period value should be PERIOD value in PWMPR plus 2. PWMO (Hz) = PCLK(Hz) / (period +2) Signed-off-by: Jason Chen Signed-off-by: Sascha Hauer Cc: stable@kernel.org diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index 845de59..e032717 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c @@ -77,6 +77,15 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) do_div(c, period_ns); duty_cycles = c; + /* + * according to imx pwm RM, the real period value should be + * PERIOD value in PWMPR plus 2. + */ + if (period_cycles > 2) + period_cycles -= 2; + else + period_cycles = 0; + writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); writel(period_cycles, pwm->mmio_base + MX3_PWMPR); -- cgit v0.10.2 From e1bff3149a68baaa9bbc3c38da04690df340b173 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Tue, 13 Dec 2011 14:25:27 +0800 Subject: arm/imx: fix cpufreq section mismatch WARNING: arch/arm/plat-mxc/built-in.o(.data+0x488): Section mismatch in reference from the variable mxc_driver to the function .init.text:mxc_cpufreq_init() The variable mxc_driver references the function __init mxc_cpufreq_init() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c index adbff70..73db34b 100644 --- a/arch/arm/plat-mxc/cpufreq.c +++ b/arch/arm/plat-mxc/cpufreq.c @@ -98,7 +98,7 @@ static int mxc_set_target(struct cpufreq_policy *policy, return ret; } -static int __init mxc_cpufreq_init(struct cpufreq_policy *policy) +static int mxc_cpufreq_init(struct cpufreq_policy *policy) { int ret; int i; -- cgit v0.10.2 From 01dd520a5029bc8ec30375e7b16a87c06658ee30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 07:31:35 +0100 Subject: cpuimx25sd: fix Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in 0d6cfa3a75f5cde5b3ca0dde748fd22625b4f34c I fixed the mach-types records. We also need to make the name consistent in Kconfig else the machine_is_eukrea_cpuimx25sd macro fails, and thus audio codec is not properly initalized. Signed-off-by: Eric Bénard Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c44aa97..d2c24d5 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -132,7 +132,7 @@ config MACH_MX25_3DS select IMX_HAVE_PLATFORM_MXC_NAND select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX -config MACH_EUKREA_CPUIMX25 +config MACH_EUKREA_CPUIMX25SD bool "Support Eukrea CPUIMX25 Platform" select SOC_IMX25 select IMX_HAVE_PLATFORM_FLEXCAN @@ -148,7 +148,7 @@ config MACH_EUKREA_CPUIMX25 choice prompt "Baseboard" - depends on MACH_EUKREA_CPUIMX25 + depends on MACH_EUKREA_CPUIMX25SD default MACH_EUKREA_MBIMXSD25_BASEBOARD config MACH_EUKREA_MBIMXSD25_BASEBOARD diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index aba7321..646f643 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o # i.MX25 based machines obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o -obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-eukrea_cpuimx25.o +obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o # i.MX27 based machines -- cgit v0.10.2 From 83f250625b44dead19d8479b315815698f348c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 07:31:39 +0100 Subject: imx_v4_v5_defconfig: update default configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add new machine APF9328 - update CPUIMX25 -> CPUIMX25SD - add drivers : - MXC nand driver - DM9000 - SMSC Phy - SPIdev - Led GPIO Signed-off-by: Eric Bénard Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index 11a4192..cf497ce 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -18,9 +18,10 @@ CONFIG_ARCH_MXC=y CONFIG_ARCH_IMX_V4_V5=y CONFIG_ARCH_MX1ADS=y CONFIG_MACH_SCB9328=y +CONFIG_MACH_APF9328=y CONFIG_MACH_MX21ADS=y CONFIG_MACH_MX25_3DS=y -CONFIG_MACH_EUKREA_CPUIMX25=y +CONFIG_MACH_EUKREA_CPUIMX25SD=y CONFIG_MACH_MX27ADS=y CONFIG_MACH_PCM038=y CONFIG_MACH_CPUIMX27=y @@ -72,17 +73,16 @@ CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_MXC=y CONFIG_MTD_UBI=y CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y CONFIG_DM9000=y +CONFIG_SMC91X=y CONFIG_SMC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +CONFIG_SMSC_PHY=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set @@ -100,6 +100,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y +CONFIG_SPI_SPIDEV=y CONFIG_W1=y CONFIG_W1_MASTER_MXC=y CONFIG_W1_SLAVE_THERM=y @@ -139,6 +140,7 @@ CONFIG_MMC=y CONFIG_MMC_MXC=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y CONFIG_LEDS_MC13783=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y -- cgit v0.10.2 From eb444fee92895cd793911b002b7e56795caf9914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 15:12:55 +0100 Subject: dma: MX3_IPU fix depends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ARCH_MX3 was removed in commit a89cf59 : "arm/imx: merge i.MX3 and i.MX6" thus preventing to select MX3_IPU, thus preventing IPU and display to work on i.MX3x SOC. i.MX SDMA support is also affected. Signed-off-by: Eric Bénard Cc: Sascha Hauer Cc: Vinod Koul Cc: Dan Williams Signed-off-by: Sascha Hauer diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index ab8f469..5a99bb3 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -124,7 +124,7 @@ config MV_XOR config MX3_IPU bool "MX3x Image Processing Unit support" - depends on ARCH_MX3 + depends on SOC_IMX31 || SOC_IMX35 select DMA_ENGINE default y help @@ -216,7 +216,7 @@ config PCH_DMA config IMX_SDMA tristate "i.MX SDMA support" - depends on ARCH_MX25 || ARCH_MX3 || ARCH_MX5 + depends on ARCH_MX25 || SOC_IMX31 || SOC_IMX35 || ARCH_MX5 select DMA_ENGINE help Support the i.MX SDMA engine. This engine is integrated into -- cgit v0.10.2 From 9cd39fba1b877e194a8d9bbec02dfa1fdd48f0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 15:13:19 +0100 Subject: clock-imx35: fix reboot in internal boot mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 8d75a26 "ARM: mx35: use generic function for displaying silicon revision" disabled IIM clock after reading silicon revision which will prevent reboot in internal boot mode. Signed-off-by: Eric Bénard Cc: Jason Liu Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c index 8116f11..ac8238c 100644 --- a/arch/arm/mach-imx/clock-imx35.c +++ b/arch/arm/mach-imx/clock-imx35.c @@ -507,7 +507,7 @@ static struct clk_lookup lookups[] = { int __init mx35_clocks_init() { - unsigned int cgr2 = 3 << 26, cgr3 = 0; + unsigned int cgr2 = 3 << 26; #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) cgr2 |= 3 << 16; @@ -521,6 +521,12 @@ int __init mx35_clocks_init() __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), CCM_BASE + CCM_CGR1); + __raw_writel(cgr2, CCM_BASE + CCM_CGR2); + __raw_writel(0, CCM_BASE + CCM_CGR3); + + clk_enable(&iim_clk); + imx_print_silicon_rev("i.MX35", mx35_revision()); + clk_disable(&iim_clk); /* * Check if we came up in internal boot mode. If yes, we need some @@ -529,17 +535,11 @@ int __init mx35_clocks_init() */ if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) { /* Additionally turn on UART1, SCC, and IIM clocks */ - cgr2 |= 3 << 16 | 3 << 4; - cgr3 |= 3 << 2; + clk_enable(&iim_clk); + clk_enable(&uart1_clk); + clk_enable(&scc_clk); } - __raw_writel(cgr2, CCM_BASE + CCM_CGR2); - __raw_writel(cgr3, CCM_BASE + CCM_CGR3); - - clk_enable(&iim_clk); - imx_print_silicon_rev("i.MX35", mx35_revision()); - clk_disable(&iim_clk); - #ifdef CONFIG_MXC_USE_EPIT epit_timer_init(&epit1_clk, MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); -- cgit v0.10.2 From a69aa72af34f051b0ddd0d553f6a7b5098878c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 07:31:43 +0100 Subject: cpuimx35sd: fix Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in 0d6cfa3a75f5cde5b3ca0dde748fd22625b4f34c I fixed the mach-types records. We also need to make the name consistent in Kconfig else the machine_is_eukrea_cpuimx35sd macro fails, and thus audio codec is not properly initalized. Signed-off-by: Eric Bénard Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d2c24d5..0e6f1af 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -542,7 +542,7 @@ config MACH_MX35_3DS Include support for MX35PDK platform. This includes specific configurations for the board and its peripherals. -config MACH_EUKREA_CPUIMX35 +config MACH_EUKREA_CPUIMX35SD bool "Support Eukrea CPUIMX35 Platform" select SOC_IMX35 select IMX_HAVE_PLATFORM_FLEXCAN @@ -560,7 +560,7 @@ config MACH_EUKREA_CPUIMX35 choice prompt "Baseboard" - depends on MACH_EUKREA_CPUIMX35 + depends on MACH_EUKREA_CPUIMX35SD default MACH_EUKREA_MBIMXSD35_BASEBOARD config MACH_EUKREA_MBIMXSD35_BASEBOARD diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 646f643..d97f409 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -57,7 +57,7 @@ obj-$(CONFIG_MACH_BUG) += mach-bug.o # i.MX35 based machines obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o -obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o +obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o -- cgit v0.10.2 From 4d4b2562fc9f47becffa4593e254c16a59e87d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 07:31:44 +0100 Subject: cpuimx35: fix touchscreen support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eric Bénard Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 66af2e8..362aae7 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -53,12 +53,18 @@ static const struct imxi2c_platform_data .bitrate = 100000, }; +#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2) +static int tsc2007_get_pendown_state(void) +{ + return !gpio_get_value(TSC2007_IRQGPIO); +} + static struct tsc2007_platform_data tsc2007_info = { .model = 2007, .x_plate_ohms = 180, + .get_pendown_state = tsc2007_get_pendown_state, }; -#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2) static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { { I2C_BOARD_INFO("pcf8563", 0x51), -- cgit v0.10.2 From 334fef05fd8f9be55f9982f788f2e85925bb2684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20B=C3=A9nard?= Date: Tue, 13 Dec 2011 07:31:45 +0100 Subject: enable uncompress log on cpuimx35sd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Eric Bénard Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index 88fd404..477971b 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h @@ -98,6 +98,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) case MACH_TYPE_PCM043: case MACH_TYPE_LILLY1131: case MACH_TYPE_VPR200: + case MACH_TYPE_EUKREA_CPUIMX35SD: uart_base = MX3X_UART1_BASE_ADDR; break; case MACH_TYPE_MAGX_ZN5: -- cgit v0.10.2 From 7422ba5343b8c1dbe1a517d0fcc15e7d671ca960 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 19 Dec 2011 13:45:01 +0200 Subject: usb: gadget: epautoconf: do not change number of streams We should not change gadget driver's descriptors just because we think it's right to do so. There are several of reasons which would support this statement but it suffices to say that this was probably never tested because it updates bmAttributes without asking the driver if it's ok to do so. This means that e.g. on UASP gadget it would enable stream support even for the command endpoint which must not have stream support enabled. In fact, this change is fixing the bug introduced by commit a59d6b9 (usb: gadget: add streams support to the gadget framework) which was caught when testing UASP gadget with dwc3 driver. Cc: Tatyana Brokhman Signed-off-by: Felipe Balbi diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 596a0b4..4dff83d 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -130,9 +130,6 @@ ep_matches ( num_req_streams = ep_comp->bmAttributes & 0x1f; if (num_req_streams > ep->max_streams) return 0; - /* Update the ep_comp descriptor if needed */ - if (num_req_streams != ep->max_streams) - ep_comp->bmAttributes = ep->max_streams; } } -- cgit v0.10.2 From ce5ea9f3767e8589521319cae2eb6e05c52bd056 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Tue, 29 Nov 2011 15:56:19 +0000 Subject: ARM: l2x0/pl310: Refactor Kconfig to be more maintainable Making CACHE_L2X0 depend on (huge list of MACH_ and ARCH_ configs) is bothersome to maintain and likely to lead to merge conflicts. This patch moves the knowledge of which platforms have a L2x0 or PL310 cache controller to the individual machines. To enable this, a new MIGHT_HAVE_CACHE_L2X0 config option is introduced to allow machines to indicate that they may have such a cache controller independently of each other. Boards/SoCs which cannot reliably operate without the L2 cache controller support will need to select CACHE_L2X0 directly from their own Kconfigs instead. This applies to some TrustZone-enabled boards where Linux runs in the Normal World, for example. Signed-off-by: Dave Martin Acked-by: Anton Vorontsov (for cns3xxx) Acked-by: Tony Lindgren (for omap) Acked-by: Shawn Guo (for imx) Acked-by: Kukjin Kim (for exynos) Acked-by: Sascha Hauer (for imx) Acked-by: Olof Johansson (for tegra) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 44789ef..16a4b9e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -344,6 +344,7 @@ config ARCH_HIGHBANK select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU + select MIGHT_HAVE_CACHE_L2X0 select USE_OF help Support for the Calxeda Highbank SoC based boards. @@ -361,6 +362,7 @@ config ARCH_CNS3XXX select CPU_V6K select GENERIC_CLOCKEVENTS select ARM_GIC + select MIGHT_HAVE_CACHE_L2X0 select MIGHT_HAVE_PCI select PCI_DOMAINS if PCI help @@ -381,6 +383,7 @@ config ARCH_PRIMA2 select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP select GENERIC_IRQ_CHIP + select MIGHT_HAVE_CACHE_L2X0 select USE_OF select ZONE_DMA help @@ -633,6 +636,7 @@ config ARCH_TEGRA select GENERIC_GPIO select HAVE_CLK select HAVE_SCHED_CLOCK + select MIGHT_HAVE_CACHE_L2X0 select ARCH_HAS_CPUFREQ help This enables support for NVIDIA Tegra based systems (Tegra APX, @@ -703,6 +707,7 @@ config ARCH_SHMOBILE select CLKDEV_LOOKUP select HAVE_MACH_CLKDEV select GENERIC_CLOCKEVENTS + select MIGHT_HAVE_CACHE_L2X0 select NO_IOPORT select SPARSE_IRQ select MULTI_IRQ_HANDLER @@ -904,6 +909,7 @@ config ARCH_U8500 select CLKDEV_LOOKUP select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ + select MIGHT_HAVE_CACHE_L2X0 help Support for ST-Ericsson's Ux500 architecture @@ -914,6 +920,7 @@ config ARCH_NOMADIK select CPU_ARM926T select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS + select MIGHT_HAVE_CACHE_L2X0 select ARCH_REQUIRE_GPIOLIB help Support for the Nomadik platform by ST-Ericsson @@ -973,6 +980,7 @@ config ARCH_ZYNQ select ARM_GIC select ARM_AMBA select ICST + select MIGHT_HAVE_CACHE_L2X0 select USE_OF help Support for Xilinx Zynq ARM Cortex A9 Platform diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 724ec0f..7f2347b 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -17,6 +17,7 @@ choice config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" + select MIGHT_HAVE_CACHE_L2X0 help Samsung EXYNOS4 SoCs based systems diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 5034147..c841578 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -44,6 +44,7 @@ config ARCH_OMAP4 select CPU_V7 select ARM_GIC select LOCAL_TIMERS if SMP + select MIGHT_HAVE_CACHE_L2X0 select PL310_ERRATA_588369 select PL310_ERRATA_727915 select ARM_ERRATA_720789 diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index dba6d0c..3dd620f8 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -12,6 +12,7 @@ config REALVIEW_EB_A9MP bool "Support Multicore Cortex-A9 Tile" depends on MACH_REALVIEW_EB select CPU_V7 + select MIGHT_HAVE_CACHE_L2X0 help Enable support for the Cortex-A9MPCore tile fitted to the Realview(R) Emulation Baseboard platform. @@ -21,6 +22,7 @@ config REALVIEW_EB_ARM11MP depends on MACH_REALVIEW_EB select CPU_V6K select ARCH_HAS_BARRIERS if SMP + select MIGHT_HAVE_CACHE_L2X0 help Enable support for the ARM11MPCore tile fitted to the Realview(R) Emulation Baseboard platform. @@ -39,6 +41,7 @@ config MACH_REALVIEW_PB11MP select CPU_V6K select ARM_GIC select HAVE_PATA_PLATFORM + select MIGHT_HAVE_CACHE_L2X0 select ARCH_HAS_BARRIERS if SMP help Include support for the ARM(R) RealView(R) Platform Baseboard for @@ -51,6 +54,7 @@ config MACH_REALVIEW_PB1176 select CPU_V6 select ARM_GIC select HAVE_TCM + select MIGHT_HAVE_CACHE_L2X0 help Include support for the ARM(R) RealView(R) Platform Baseboard for ARM1176JZF-S. @@ -78,6 +82,7 @@ config MACH_REALVIEW_PBX bool "Support RealView(R) Platform Baseboard Explore" select ARM_GIC select HAVE_PATA_PLATFORM + select MIGHT_HAVE_CACHE_L2X0 select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET select ZONE_DMA if SPARSEMEM help diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 9311484..a8aefc8 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -8,5 +8,6 @@ config ARCH_VEXPRESS_CA9X4 select ARM_ERRATA_720789 select ARM_ERRATA_751472 select ARM_ERRATA_753970 + select MIGHT_HAVE_CACHE_L2X0 endmenu diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 67f75a0..acb1c36 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -816,14 +816,23 @@ config CACHE_FEROCEON_L2_WRITETHROUGH Say Y here to use the Feroceon L2 cache in writethrough mode. Unless you specifically require this, say N for writeback mode. +config MIGHT_HAVE_CACHE_L2X0 + bool + help + This option should be selected by machines which have a L2x0 + or PL310 cache controller, but where its use is optional. + + The only effect of this option is to make CACHE_L2X0 and + related options available to the user for configuration. + + Boards or SoCs which always require the cache controller + support to be present should select CACHE_L2X0 directly + instead of this option, thus preventing the user from + inadvertently configuring a broken kernel. + config CACHE_L2X0 - bool "Enable the L2x0 outer cache controller" - depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ - REALVIEW_EB_A9MP || ARCH_IMX_V6_V7 || MACH_REALVIEW_PBX || \ - ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ - ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || \ - ARCH_PRIMA2 || ARCH_ZYNQ || ARCH_CNS3XXX || ARCH_HIGHBANK - default y + bool "Enable the L2x0 outer cache controller" if MIGHT_HAVE_CACHE_L2X0 + default MIGHT_HAVE_CACHE_L2X0 select OUTER_CACHE select OUTER_CACHE_SYNC help diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index b3a1f2b3..b30708e 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -20,6 +20,7 @@ config ARCH_IMX_V6_V7 bool "i.MX3, i.MX6" select AUTO_ZRELADDR if !ZBOOT_ROM select ARM_PATCH_PHYS_VIRT + select MIGHT_HAVE_CACHE_L2X0 help This enables support for systems based on the Freescale i.MX3 and i.MX6 family. -- cgit v0.10.2 From 3b55658aefbf82646a246f3c8a14b9b8a24198a9 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Wed, 7 Dec 2011 15:38:04 +0000 Subject: ARM: SMP: Refactor Kconfig to be more maintainable Making SMP depend on (huge list of MACH_ and ARCH_ configs) is bothersome to maintain and likely to lead to merge conflicts. This patch moves the knowledge of which platforms are SMP-capable to the individual machines. To enable this, a new HAVE_SMP config option is introduced to allow machines to indicate that they can run in a SMP configuration. Signed-off-by: Dave Martin Acked-by: Linus Walleij (for nomadik, ux500) Acked-by: Tony Lindgren (for omap) Acked-by: Kukjin Kim (for exynos) Acked-by: Sascha Hauer (for imx) Acked-by: Olof Johansson (for tegra) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 16a4b9e..eca82f9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -344,6 +344,7 @@ config ARCH_HIGHBANK select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select USE_OF help @@ -636,6 +637,7 @@ config ARCH_TEGRA select GENERIC_GPIO select HAVE_CLK select HAVE_SCHED_CLOCK + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select ARCH_HAS_CPUFREQ help @@ -706,6 +708,7 @@ config ARCH_SHMOBILE select HAVE_CLK select CLKDEV_LOOKUP select HAVE_MACH_CLKDEV + select HAVE_SMP select GENERIC_CLOCKEVENTS select MIGHT_HAVE_CACHE_L2X0 select NO_IOPORT @@ -909,6 +912,7 @@ config ARCH_U8500 select CLKDEV_LOOKUP select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help Support for ST-Ericsson's Ux500 architecture @@ -1430,14 +1434,20 @@ menu "Kernel Features" source "kernel/time/Kconfig" +config HAVE_SMP + bool + help + This option should be selected by machines which have an SMP- + capable CPU. + + The only effect of this option is to make the SMP-related + options available to the user for configuration. + config SMP bool "Symmetric Multi-Processing" depends on CPU_V6K || CPU_V7 depends on GENERIC_CLOCKEVENTS - depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ - MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ - ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ - ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK || SOC_IMX6Q + depends on HAVE_SMP depends on MMU select USE_GENERIC_SMP_HELPERS select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 7f2347b..e1efbca 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -17,6 +17,7 @@ choice config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help Samsung EXYNOS4 SoCs based systems diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 5f7f9c2..29a3d61 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -615,6 +615,7 @@ config SOC_IMX6Q select HAVE_IMX_GPC select HAVE_IMX_MMDC select HAVE_IMX_SRC + select HAVE_SMP select USE_OF help diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index ebde97f..e6beaff 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -67,6 +67,7 @@ config MSM_SOC_REV_A bool config ARCH_MSM_SCORPIONMP bool + select HAVE_SMP config ARCH_MSM_ARM11 bool diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index c841578..bb1b670 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -43,6 +43,7 @@ config ARCH_OMAP4 depends on ARCH_OMAP2PLUS select CPU_V7 select ARM_GIC + select HAVE_SMP select LOCAL_TIMERS if SMP select MIGHT_HAVE_CACHE_L2X0 select PL310_ERRATA_588369 diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index 3dd620f8..c593be4 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -12,6 +12,7 @@ config REALVIEW_EB_A9MP bool "Support Multicore Cortex-A9 Tile" depends on MACH_REALVIEW_EB select CPU_V7 + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help Enable support for the Cortex-A9MPCore tile fitted to the @@ -22,6 +23,7 @@ config REALVIEW_EB_ARM11MP depends on MACH_REALVIEW_EB select CPU_V6K select ARCH_HAS_BARRIERS if SMP + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 help Enable support for the ARM11MPCore tile fitted to the Realview(R) @@ -41,6 +43,7 @@ config MACH_REALVIEW_PB11MP select CPU_V6K select ARM_GIC select HAVE_PATA_PLATFORM + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select ARCH_HAS_BARRIERS if SMP help @@ -82,6 +85,7 @@ config MACH_REALVIEW_PBX bool "Support RealView(R) Platform Baseboard Explore" select ARM_GIC select HAVE_PATA_PLATFORM + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET select ZONE_DMA if SPARSEMEM diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index a8aefc8..9b3d0fb 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -8,6 +8,7 @@ config ARCH_VEXPRESS_CA9X4 select ARM_ERRATA_720789 select ARM_ERRATA_751472 select ARM_ERRATA_753970 + select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 endmenu -- cgit v0.10.2 From c957445bf960047cf1e9d3aa764beb18f3fbb734 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 12 Dec 2011 16:17:34 +0000 Subject: omap4: Unconditionally require l2x0 L2 cache controller support If running in the Normal World on a TrustZone-enabled SoC, Linux does not have complete control over the L2 cache controller configuration. The kernel cannot work reliably on such platforms without the l2x0 cache support code built in. This patch unconditionally enables l2x0 support for the OMAP4 SoCs. Thanks to Rob Herring for this suggestion. [1] [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html Signed-off-by: Dave Martin Acked-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index bb1b670..94e568a 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -41,11 +41,11 @@ config ARCH_OMAP4 bool "TI OMAP4" default y depends on ARCH_OMAP2PLUS + select CACHE_L2X0 select CPU_V7 select ARM_GIC select HAVE_SMP select LOCAL_TIMERS if SMP - select MIGHT_HAVE_CACHE_L2X0 select PL310_ERRATA_588369 select PL310_ERRATA_727915 select ARM_ERRATA_720789 -- cgit v0.10.2 From 22d80379e9b6b167e145c12099705bc8e9946d84 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 12 Dec 2011 16:17:34 +0000 Subject: highbank: Unconditionally require l2x0 L2 cache controller support If running in the Normal World on a TrustZone-enabled SoC, Linux does not have complete control over the L2 cache controller configuration. The kernel cannot work reliably on such platforms without the l2x0 cache support code built in. This patch unconditionally enables l2x0 support for the Highbank SoC. Thanks to Rob Herring for this suggestion. [1] [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074495.html Signed-off-by: Dave Martin Acked-by: Rob Herring diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index eca82f9..1792146 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -340,12 +340,12 @@ config ARCH_HIGHBANK select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 + select CACHE_L2X0 select CLKDEV_LOOKUP select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU select HAVE_SMP - select MIGHT_HAVE_CACHE_L2X0 select USE_OF help Support for the Calxeda Highbank SoC based boards. -- cgit v0.10.2 From a2075a7aff5f469b91029c14f216dc169d1bd5f3 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 12 Dec 2011 16:17:34 +0000 Subject: imx6q: Remove unconditional dependency on l2x0 L2 cache support The i.MX6 Quad SoC will work without the l2x0 L2 cache controller support built into the kernel, so this patch removes the dependency on CACHE_L2X0. This makes the l2x0 support optional, so that it can be turned off when desired for debugging purposes etc. Since SOC_IMX6Q already depends on ARCH_IMX_V6_V7 and ARCH_IMX_V6_V7 selects MIGHT_HAVE_CACHE_L2X0, there is no need to select that option explicitly from SOC_IMX6Q. Thanks to Shawn Guo for this suggestion. [1] [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/074602.html Acked-by: Shawn Guo Tested-by: Shawn Guo Acked-by: Sascha Hauer diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 29a3d61..1530678 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -609,7 +609,6 @@ comment "i.MX6 family:" config SOC_IMX6Q bool "i.MX6 Quad support" select ARM_GIC - select CACHE_L2X0 select CPU_V7 select HAVE_ARM_SCU select HAVE_IMX_GPC -- cgit v0.10.2 From ebd4c6f6261c96d1cf9f004965384d57c4202fd6 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 28 Nov 2011 13:19:08 +0100 Subject: vmwgfx: Use the revised fifo hw version register when present The driver implements the needed resource management required to use that register. Signed-off-by: Thomas Hellstrom Reviewed-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 03bbc2a..a0c2f12 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -33,6 +33,7 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) { __le32 __iomem *fifo_mem = dev_priv->mmio_virt; uint32_t fifo_min, hwversion; + const struct vmw_fifo_state *fifo = &dev_priv->fifo; if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) return false; @@ -41,7 +42,12 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int)) return false; - hwversion = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION); + hwversion = ioread32(fifo_mem + + ((fifo->capabilities & + SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ? + SVGA_FIFO_3D_HWVERSION_REVISED : + SVGA_FIFO_3D_HWVERSION)); + if (hwversion == 0) return false; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 5ff561d..1edb63e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -58,8 +58,14 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, case DRM_VMW_PARAM_FIFO_HW_VERSION: { __le32 __iomem *fifo_mem = dev_priv->mmio_virt; - - param->value = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION); + const struct vmw_fifo_state *fifo = &dev_priv->fifo; + + param->value = + ioread32(fifo_mem + + ((fifo->capabilities & + SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ? + SVGA_FIFO_3D_HWVERSION_REVISED : + SVGA_FIFO_3D_HWVERSION)); break; } default: -- cgit v0.10.2 From ef5ab24bd3373941bd27e371512c0009eb11581c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:09 +0100 Subject: vmwgfx: Remove dmabuf check in present ioctl Doesn't protect any error code and only gets in the way of debugging. Signed-off-by: Jakob Bornecrantz Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 1edb63e..66917c6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -172,13 +172,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, ret = -EINVAL; goto out_no_fb; } - vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj)); - if (!vfb->dmabuf) { - DRM_ERROR("Framebuffer not dmabuf backed.\n"); - ret = -EINVAL; - goto out_no_fb; - } ret = ttm_read_lock(&vmaster->lock, true); if (unlikely(ret != 0)) -- cgit v0.10.2 From 6a91d97e02d7efde955c25a5b0fbf950cd2a6efa Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:10 +0100 Subject: vmwgfx: Refactor cursor update Signed-off-by: Jakob Bornecrantz Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 37d4054..bee6716 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -82,6 +82,43 @@ int vmw_cursor_update_image(struct vmw_private *dev_priv, return 0; } +int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv, + struct vmw_dma_buffer *dmabuf, + u32 width, u32 height, + u32 hotspotX, u32 hotspotY) +{ + struct ttm_bo_kmap_obj map; + unsigned long kmap_offset; + unsigned long kmap_num; + void *virtual; + bool dummy; + int ret; + + kmap_offset = 0; + kmap_num = (width*height*4 + PAGE_SIZE - 1) >> PAGE_SHIFT; + + ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0); + if (unlikely(ret != 0)) { + DRM_ERROR("reserve failed\n"); + return -EINVAL; + } + + ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map); + if (unlikely(ret != 0)) + goto err_unreserve; + + virtual = ttm_kmap_obj_virtual(&map, &dummy); + ret = vmw_cursor_update_image(dev_priv, virtual, width, height, + hotspotX, hotspotY); + + ttm_bo_kunmap(&map); +err_unreserve: + ttm_bo_unreserve(&dmabuf->base); + + return ret; +} + + void vmw_cursor_update_position(struct vmw_private *dev_priv, bool show, int x, int y) { @@ -146,36 +183,11 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, vmw_cursor_update_image(dev_priv, surface->snooper.image, 64, 64, du->hotspot_x, du->hotspot_y); } else if (dmabuf) { - struct ttm_bo_kmap_obj map; - unsigned long kmap_offset; - unsigned long kmap_num; - void *virtual; - bool dummy; - /* vmw_user_surface_lookup takes one reference */ du->cursor_dmabuf = dmabuf; - kmap_offset = 0; - kmap_num = (64*64*4) >> PAGE_SHIFT; - - ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0); - if (unlikely(ret != 0)) { - DRM_ERROR("reserve failed\n"); - return -EINVAL; - } - - ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map); - if (unlikely(ret != 0)) - goto err_unreserve; - - virtual = ttm_kmap_obj_virtual(&map, &dummy); - vmw_cursor_update_image(dev_priv, virtual, 64, 64, - du->hotspot_x, du->hotspot_y); - - ttm_bo_kunmap(&map); -err_unreserve: - ttm_bo_unreserve(&dmabuf->base); - + ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height, + du->hotspot_x, du->hotspot_y); } else { vmw_cursor_update_position(dev_priv, false, 0, 0); return 0; -- cgit v0.10.2 From 551a6697d08f92a311d6adbf8d03af2bc7f9e2ee Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:11 +0100 Subject: vmwgfx: Add helper function to get surface or dmabuf Signed-off-by: Jakob Bornecrantz Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 8cca91a..dc27970 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -390,6 +390,11 @@ extern int vmw_context_check(struct vmw_private *dev_priv, struct ttm_object_file *tfile, int id, struct vmw_resource **p_res); +extern int vmw_user_lookup_handle(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t handle, + struct vmw_surface **out_surf, + struct vmw_dma_buffer **out_buf); extern void vmw_surface_res_free(struct vmw_resource *res); extern int vmw_surface_init(struct vmw_private *dev_priv, struct vmw_surface *srf, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 86c5e4c..1c7f09e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -1190,6 +1190,29 @@ void vmw_resource_unreserve(struct list_head *list) write_unlock(lock); } +/** + * Helper function that looks either a surface or dmabuf. + * + * The pointer this pointed at by out_surf and out_buf needs to be null. + */ +int vmw_user_lookup_handle(struct vmw_private *dev_priv, + struct ttm_object_file *tfile, + uint32_t handle, + struct vmw_surface **out_surf, + struct vmw_dma_buffer **out_buf) +{ + int ret; + + BUG_ON(*out_surf || *out_buf); + + ret = vmw_user_surface_lookup_handle(dev_priv, tfile, handle, out_surf); + if (!ret) + return 0; + + ret = vmw_user_dmabuf_lookup(tfile, handle, out_buf); + return ret; +} + int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, struct ttm_object_file *tfile, -- cgit v0.10.2 From e7ac9211f29f2fc2e7d11586a33267d2a26d3f2f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:12 +0100 Subject: vmwgfx: Refactor kms code to use vmw_user_lookup_handle helper Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index bee6716..ac24cfd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -147,24 +147,21 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, return -EINVAL; if (handle) { - ret = vmw_user_surface_lookup_handle(dev_priv, tfile, - handle, &surface); - if (!ret) { - if (!surface->snooper.image) { - DRM_ERROR("surface not suitable for cursor\n"); - vmw_surface_unreference(&surface); - return -EINVAL; - } - } else { - ret = vmw_user_dmabuf_lookup(tfile, - handle, &dmabuf); - if (ret) { - DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); - return -EINVAL; - } + ret = vmw_user_lookup_handle(dev_priv, tfile, + handle, &surface, &dmabuf); + if (ret) { + DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); + return -EINVAL; } } + /* need to do this before taking down old image */ + if (surface && !surface->snooper.image) { + DRM_ERROR("surface not suitable for cursor\n"); + vmw_surface_unreference(&surface); + return -EINVAL; + } + /* takedown old cursor */ if (du->cursor_surface) { du->cursor_surface->snooper.crtc = NULL; @@ -568,6 +565,10 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, * Sanity checks. */ + /* Surface must be marked as a scanout. */ + if (unlikely(!surface->scanout)) + return -EINVAL; + if (unlikely(surface->mip_levels[0] != 1 || surface->num_sizes != 1 || surface->sizes[0].width < mode_cmd->width || @@ -1045,46 +1046,29 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, return ERR_PTR(-ENOENT); } - /** - * End conditioned code. - */ - - ret = vmw_user_surface_lookup_handle(dev_priv, tfile, - mode_cmd->handle, &surface); + /* returns either a dmabuf or surface */ + ret = vmw_user_lookup_handle(dev_priv, tfile, + mode_cmd->handle, + &surface, &bo); if (ret) - goto try_dmabuf; - - if (!surface->scanout) - goto err_not_scanout; - - ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv, surface, - &vfb, mode_cmd); - - /* vmw_user_surface_lookup takes one ref so does new_fb */ - vmw_surface_unreference(&surface); - - if (ret) { - DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); - ttm_base_object_unref(&user_obj); - return ERR_PTR(ret); - } else - vfb->user_obj = user_obj; - return &vfb->base; - -try_dmabuf: - DRM_INFO("%s: trying buffer\n", __func__); - - ret = vmw_user_dmabuf_lookup(tfile, mode_cmd->handle, &bo); - if (ret) { - DRM_ERROR("failed to find buffer: %i\n", ret); - return ERR_PTR(-ENOENT); - } - - ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb, - mode_cmd); + goto err_out; + + /* Create the new framebuffer depending one what we got back */ + if (bo) + ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb, + mode_cmd); + else if (surface) + ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv, + surface, &vfb, mode_cmd); + else + BUG(); - /* vmw_user_dmabuf_lookup takes one ref so does new_fb */ - vmw_dmabuf_unreference(&bo); +err_out: + /* vmw_user_lookup_handle takes one ref so does new_fb */ + if (bo) + vmw_dmabuf_unreference(&bo); + if (surface) + vmw_surface_unreference(&surface); if (ret) { DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); @@ -1094,14 +1078,6 @@ try_dmabuf: vfb->user_obj = user_obj; return &vfb->base; - -err_not_scanout: - DRM_ERROR("surface not marked as scanout\n"); - /* vmw_user_surface_lookup takes one ref */ - vmw_surface_unreference(&surface); - ttm_base_object_unref(&user_obj); - - return ERR_PTR(-EINVAL); } static struct drm_mode_config_funcs vmw_kms_funcs = { -- cgit v0.10.2 From 203dc2201326fa64411158c84ab0745546300310 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:13 +0100 Subject: vmwgfx: Do better culling of presents Signed-off-by: Jakob Bornecrantz Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ac24cfd..d31ae33 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1098,6 +1098,7 @@ int vmw_kms_present(struct vmw_private *dev_priv, size_t fifo_size; int i, k, num_units; int ret = 0; /* silence warning */ + int left, right, top, bottom; struct { SVGA3dCmdHeader header; @@ -1122,30 +1123,42 @@ int vmw_kms_present(struct vmw_private *dev_priv, return -ENOMEM; } + left = clips->x; + right = clips->x + clips->w; + top = clips->y; + bottom = clips->y + clips->h; + + for (i = 1; i < num_clips; i++) { + left = min_t(int, left, (int)clips[i].x); + right = max_t(int, right, (int)clips[i].x + clips[i].w); + top = min_t(int, top, (int)clips[i].y); + bottom = max_t(int, bottom, (int)clips[i].y + clips[i].h); + } + /* only need to do this once */ memset(cmd, 0, fifo_size); cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); - cmd->body.srcRect.left = 0; - cmd->body.srcRect.right = surface->sizes[0].width; - cmd->body.srcRect.top = 0; - cmd->body.srcRect.bottom = surface->sizes[0].height; + cmd->body.srcRect.left = left; + cmd->body.srcRect.right = right; + cmd->body.srcRect.top = top; + cmd->body.srcRect.bottom = bottom; blits = (SVGASignedRect *)&cmd[1]; for (i = 0; i < num_clips; i++) { - blits[i].left = clips[i].x; - blits[i].right = clips[i].x + clips[i].w; - blits[i].top = clips[i].y; - blits[i].bottom = clips[i].y + clips[i].h; + blits[i].left = clips[i].x - left; + blits[i].right = clips[i].x + clips[i].w - left; + blits[i].top = clips[i].y - top; + blits[i].bottom = clips[i].y + clips[i].h - top; } for (k = 0; k < num_units; k++) { struct vmw_display_unit *unit = units[k]; - int clip_x1 = destX - unit->crtc.x; - int clip_y1 = destY - unit->crtc.y; - int clip_x2 = clip_x1 + surface->sizes[0].width; - int clip_y2 = clip_y1 + surface->sizes[0].height; + int clip_x1 = left + destX - unit->crtc.x; + int clip_y1 = top + destY - unit->crtc.y; + int clip_x2 = right + destX - unit->crtc.x; + int clip_y2 = bottom + destY - unit->crtc.y; /* skip any crtcs that misses the clip region */ if (clip_x1 >= unit->crtc.mode.hdisplay || -- cgit v0.10.2 From bfc2638dc05f2b27538e40821fdbc8399730b1ea Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:14 +0100 Subject: vmwgfx: Resend the cursor after legacy modeset Signed-off-by: Jakob Bornecrantz Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index af8e6e5..e1cb855 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -62,9 +62,14 @@ struct vmw_framebuffer { int vmw_cursor_update_image(struct vmw_private *dev_priv, u32 *image, u32 width, u32 height, u32 hotspotX, u32 hotspotY); +int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv, + struct vmw_dma_buffer *dmabuf, + u32 width, u32 height, + u32 hotspotX, u32 hotspotY); void vmw_cursor_update_position(struct vmw_private *dev_priv, bool show, int x, int y); + /** * Base class display unit. * diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 90c5e39..8f8dbd4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -74,9 +74,10 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) { struct vmw_legacy_display *lds = dev_priv->ldu_priv; struct vmw_legacy_display_unit *entry; + struct vmw_display_unit *du = NULL; struct drm_framebuffer *fb = NULL; struct drm_crtc *crtc = NULL; - int i = 0; + int i = 0, ret; /* If there is no display topology the host just assumes * that the guest will set the same layout as the host. @@ -129,6 +130,25 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) lds->last_num_active = lds->num_active; + + /* Find the first du with a cursor. */ + list_for_each_entry(entry, &lds->active, active) { + du = &entry->base; + + if (!du->cursor_dmabuf) + continue; + + ret = vmw_cursor_update_dmabuf(dev_priv, + du->cursor_dmabuf, + 64, 64, + du->hotspot_x, + du->hotspot_y); + if (ret == 0) + break; + + DRM_ERROR("Could not update cursor image\n"); + } + return 0; } -- cgit v0.10.2 From 6abff3c78051e40130a1c653f874fb12b9d40254 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 28 Nov 2011 13:19:15 +0100 Subject: vmwgfx: Clip cliprects against screen boundaries in present and dirty Signed-off-by: Jakob Bornecrantz Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index d31ae33..8aa1dbb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -31,6 +31,44 @@ /* Might need a hrtimer here? */ #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) + +struct vmw_clip_rect { + int x1, x2, y1, y2; +}; + +/** + * Clip @num_rects number of @rects against @clip storing the + * results in @out_rects and the number of passed rects in @out_num. + */ +void vmw_clip_cliprects(struct drm_clip_rect *rects, + int num_rects, + struct vmw_clip_rect clip, + SVGASignedRect *out_rects, + int *out_num) +{ + int i, k; + + for (i = 0, k = 0; i < num_rects; i++) { + int x1 = max_t(int, clip.x1, rects[i].x1); + int y1 = max_t(int, clip.y1, rects[i].y1); + int x2 = min_t(int, clip.x2, rects[i].x2); + int y2 = min_t(int, clip.y2, rects[i].y2); + + if (x1 >= x2) + continue; + if (y1 >= y2) + continue; + + out_rects[k].left = x1; + out_rects[k].top = y1; + out_rects[k].right = x2; + out_rects[k].bottom = y2; + k++; + } + + *out_num = k; +} + void vmw_display_unit_cleanup(struct vmw_display_unit *du) { if (du->cursor_surface) @@ -386,8 +424,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, struct drm_clip_rect *clips, unsigned num_clips, int inc) { - struct drm_clip_rect *clips_ptr; struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; + struct drm_clip_rect *clips_ptr; + struct drm_clip_rect *tmp; struct drm_crtc *crtc; size_t fifo_size; int i, num_units; @@ -400,7 +439,6 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, } *cmd; SVGASignedRect *blits; - num_units = 0; list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { @@ -411,13 +449,24 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, BUG_ON(!clips || !num_clips); + tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL); + if (unlikely(tmp == NULL)) { + DRM_ERROR("Temporary cliprect memory alloc failed.\n"); + return -ENOMEM; + } + fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; cmd = kzalloc(fifo_size, GFP_KERNEL); if (unlikely(cmd == NULL)) { DRM_ERROR("Temporary fifo memory alloc failed.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto out_free_tmp; } + /* setup blits pointer */ + blits = (SVGASignedRect *)&cmd[1]; + + /* initial clip region */ left = clips->x1; right = clips->x2; top = clips->y1; @@ -443,45 +492,60 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, cmd->body.srcRect.bottom = bottom; clips_ptr = clips; - blits = (SVGASignedRect *)&cmd[1]; for (i = 0; i < num_clips; i++, clips_ptr += inc) { - blits[i].left = clips_ptr->x1 - left; - blits[i].right = clips_ptr->x2 - left; - blits[i].top = clips_ptr->y1 - top; - blits[i].bottom = clips_ptr->y2 - top; + tmp[i].x1 = clips_ptr->x1 - left; + tmp[i].x2 = clips_ptr->x2 - left; + tmp[i].y1 = clips_ptr->y1 - top; + tmp[i].y2 = clips_ptr->y2 - top; } /* do per unit writing, reuse fifo for each */ for (i = 0; i < num_units; i++) { struct vmw_display_unit *unit = units[i]; - int clip_x1 = left - unit->crtc.x; - int clip_y1 = top - unit->crtc.y; - int clip_x2 = right - unit->crtc.x; - int clip_y2 = bottom - unit->crtc.y; + struct vmw_clip_rect clip; + int num; + + clip.x1 = left - unit->crtc.x; + clip.y1 = top - unit->crtc.y; + clip.x2 = right - unit->crtc.x; + clip.y2 = bottom - unit->crtc.y; /* skip any crtcs that misses the clip region */ - if (clip_x1 >= unit->crtc.mode.hdisplay || - clip_y1 >= unit->crtc.mode.vdisplay || - clip_x2 <= 0 || clip_y2 <= 0) + if (clip.x1 >= unit->crtc.mode.hdisplay || + clip.y1 >= unit->crtc.mode.vdisplay || + clip.x2 <= 0 || clip.y2 <= 0) continue; + /* + * In order for the clip rects to be correctly scaled + * the src and dest rects needs to be the same size. + */ + cmd->body.destRect.left = clip.x1; + cmd->body.destRect.right = clip.x2; + cmd->body.destRect.top = clip.y1; + cmd->body.destRect.bottom = clip.y2; + + /* create a clip rect of the crtc in dest coords */ + clip.x2 = unit->crtc.mode.hdisplay - clip.x1; + clip.y2 = unit->crtc.mode.vdisplay - clip.y1; + clip.x1 = 0 - clip.x1; + clip.y1 = 0 - clip.y1; + /* need to reset sid as it is changed by execbuf */ cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle); - cmd->body.destScreenId = unit->unit; - /* - * The blit command is a lot more resilient then the - * readback command when it comes to clip rects. So its - * okay to go out of bounds. - */ + /* clip and write blits to cmd stream */ + vmw_clip_cliprects(tmp, num_clips, clip, blits, &num); - cmd->body.destRect.left = clip_x1; - cmd->body.destRect.right = clip_x2; - cmd->body.destRect.top = clip_y1; - cmd->body.destRect.bottom = clip_y2; + /* if no cliprects hit skip this */ + if (num == 0) + continue; + /* recalculate package length */ + fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; + cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size, 0, NULL); @@ -489,7 +553,10 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, break; } + kfree(cmd); +out_free_tmp: + kfree(tmp); return ret; } @@ -795,6 +862,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, int clip_y1 = clips_ptr->y1 - unit->crtc.y; int clip_x2 = clips_ptr->x2 - unit->crtc.x; int clip_y2 = clips_ptr->y2 - unit->crtc.y; + int move_x, move_y; /* skip any crtcs that misses the clip region */ if (clip_x1 >= unit->crtc.mode.hdisplay || @@ -802,12 +870,21 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, clip_x2 <= 0 || clip_y2 <= 0) continue; + /* clip size to crtc size */ + clip_x2 = min_t(int, clip_x2, unit->crtc.mode.hdisplay); + clip_y2 = min_t(int, clip_y2, unit->crtc.mode.vdisplay); + + /* translate both src and dest to bring clip into screen */ + move_x = min_t(int, clip_x1, 0); + move_y = min_t(int, clip_y1, 0); + + /* actual translate done here */ blits[hit_num].header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN; blits[hit_num].body.destScreenId = unit->unit; - blits[hit_num].body.srcOrigin.x = clips_ptr->x1; - blits[hit_num].body.srcOrigin.y = clips_ptr->y1; - blits[hit_num].body.destRect.left = clip_x1; - blits[hit_num].body.destRect.top = clip_y1; + blits[hit_num].body.srcOrigin.x = clips_ptr->x1 - move_x; + blits[hit_num].body.srcOrigin.y = clips_ptr->y1 - move_y; + blits[hit_num].body.destRect.left = clip_x1 - move_x; + blits[hit_num].body.destRect.top = clip_y1 - move_y; blits[hit_num].body.destRect.right = clip_x2; blits[hit_num].body.destRect.bottom = clip_y2; hit_num++; @@ -1094,6 +1171,7 @@ int vmw_kms_present(struct vmw_private *dev_priv, uint32_t num_clips) { struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; + struct drm_clip_rect *tmp; struct drm_crtc *crtc; size_t fifo_size; int i, k, num_units; @@ -1116,11 +1194,18 @@ int vmw_kms_present(struct vmw_private *dev_priv, BUG_ON(surface == NULL); BUG_ON(!clips || !num_clips); + tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL); + if (unlikely(tmp == NULL)) { + DRM_ERROR("Temporary cliprect memory alloc failed.\n"); + return -ENOMEM; + } + fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; cmd = kmalloc(fifo_size, GFP_KERNEL); if (unlikely(cmd == NULL)) { DRM_ERROR("Failed to allocate temporary fifo memory.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto out_free_tmp; } left = clips->x; @@ -1138,50 +1223,66 @@ int vmw_kms_present(struct vmw_private *dev_priv, /* only need to do this once */ memset(cmd, 0, fifo_size); cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); - cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); + + blits = (SVGASignedRect *)&cmd[1]; cmd->body.srcRect.left = left; cmd->body.srcRect.right = right; cmd->body.srcRect.top = top; cmd->body.srcRect.bottom = bottom; - blits = (SVGASignedRect *)&cmd[1]; for (i = 0; i < num_clips; i++) { - blits[i].left = clips[i].x - left; - blits[i].right = clips[i].x + clips[i].w - left; - blits[i].top = clips[i].y - top; - blits[i].bottom = clips[i].y + clips[i].h - top; + tmp[i].x1 = clips[i].x - left; + tmp[i].x2 = clips[i].x + clips[i].w - left; + tmp[i].y1 = clips[i].y - top; + tmp[i].y2 = clips[i].y + clips[i].h - top; } for (k = 0; k < num_units; k++) { struct vmw_display_unit *unit = units[k]; - int clip_x1 = left + destX - unit->crtc.x; - int clip_y1 = top + destY - unit->crtc.y; - int clip_x2 = right + destX - unit->crtc.x; - int clip_y2 = bottom + destY - unit->crtc.y; + struct vmw_clip_rect clip; + int num; + + clip.x1 = left + destX - unit->crtc.x; + clip.y1 = top + destY - unit->crtc.y; + clip.x2 = right + destX - unit->crtc.x; + clip.y2 = bottom + destY - unit->crtc.y; /* skip any crtcs that misses the clip region */ - if (clip_x1 >= unit->crtc.mode.hdisplay || - clip_y1 >= unit->crtc.mode.vdisplay || - clip_x2 <= 0 || clip_y2 <= 0) + if (clip.x1 >= unit->crtc.mode.hdisplay || + clip.y1 >= unit->crtc.mode.vdisplay || + clip.x2 <= 0 || clip.y2 <= 0) continue; + /* + * In order for the clip rects to be correctly scaled + * the src and dest rects needs to be the same size. + */ + cmd->body.destRect.left = clip.x1; + cmd->body.destRect.right = clip.x2; + cmd->body.destRect.top = clip.y1; + cmd->body.destRect.bottom = clip.y2; + + /* create a clip rect of the crtc in dest coords */ + clip.x2 = unit->crtc.mode.hdisplay - clip.x1; + clip.y2 = unit->crtc.mode.vdisplay - clip.y1; + clip.x1 = 0 - clip.x1; + clip.y1 = 0 - clip.y1; + /* need to reset sid as it is changed by execbuf */ cmd->body.srcImage.sid = sid; - cmd->body.destScreenId = unit->unit; - /* - * The blit command is a lot more resilient then the - * readback command when it comes to clip rects. So its - * okay to go out of bounds. - */ + /* clip and write blits to cmd stream */ + vmw_clip_cliprects(tmp, num_clips, clip, blits, &num); - cmd->body.destRect.left = clip_x1; - cmd->body.destRect.right = clip_x2; - cmd->body.destRect.top = clip_y1; - cmd->body.destRect.bottom = clip_y2; + /* if no cliprects hit skip this */ + if (num == 0) + continue; + /* recalculate package length */ + fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; + cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size, 0, NULL); @@ -1190,6 +1291,8 @@ int vmw_kms_present(struct vmw_private *dev_priv, } kfree(cmd); +out_free_tmp: + kfree(tmp); return ret; } -- cgit v0.10.2 From 12275dd4b747f5d87fa36229774d76bca8e63068 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 19 Dec 2011 09:30:35 -0500 Subject: Revert "xen/pv-on-hvm kexec: add xs_reset_watches to shutdown watches from old kernel" This reverts commit ddacf5ef684a655abe2bb50c4b2a5b72ae0d5e05. As when booting the kernel under Amazon EC2 as an HVM guest it ends up hanging during startup. Reverting this we loose the fix for kexec booting to the crash kernels. Fixes Canonical BZ #901305 (http://bugs.launchpad.net/bugs/901305) Tested-by: Alessandro Salvatori Reported-by: Stefan Bader Acked-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index b3b8f2f..ede860f 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -621,15 +621,6 @@ static struct xenbus_watch *find_watch(const char *token) return NULL; } -static void xs_reset_watches(void) -{ - int err; - - err = xs_error(xs_single(XBT_NIL, XS_RESET_WATCHES, "", NULL)); - if (err && err != -EEXIST) - printk(KERN_WARNING "xs_reset_watches failed: %d\n", err); -} - /* Register callback to watch this node. */ int register_xenbus_watch(struct xenbus_watch *watch) { @@ -906,9 +897,5 @@ int xs_init(void) if (IS_ERR(task)) return PTR_ERR(task); - /* shutdown watches for kexec boot */ - if (xen_hvm_domain()) - xs_reset_watches(); - return 0; } diff --git a/include/xen/interface/io/xs_wire.h b/include/xen/interface/io/xs_wire.h index f0b6890..f6f07aa 100644 --- a/include/xen/interface/io/xs_wire.h +++ b/include/xen/interface/io/xs_wire.h @@ -29,8 +29,7 @@ enum xsd_sockmsg_type XS_IS_DOMAIN_INTRODUCED, XS_RESUME, XS_SET_TARGET, - XS_RESTRICT, - XS_RESET_WATCHES + XS_RESTRICT }; #define XS_WRITE_NONE "NONE" -- cgit v0.10.2 From 913050b91eb94f194392dd797b1ff3779f606ac0 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 19 Dec 2011 16:38:30 +0100 Subject: oprofile: Fix uninitialized memory access when writing to writing to oprofilefs If oprofilefs_ulong_from_user() is called with count equals zero, *val remains unchanged. Depending on the implementation it might be uninitialized. Change oprofilefs_ulong_from_user()'s interface to return count on success. Thus, we are able to return early if count equals zero which avoids using *val uninitialized. Fixing all users of oprofilefs_ulong_ from_user(). This follows write syscall implementation when count is zero: "If count is zero ... [and if] no errors are detected, 0 will be returned without causing any other effect." (man 2 write) Reported-By: Mike Waychison Signed-off-by: Robert Richter Cc: Andrew Morton Cc: Cc: oprofile-list Link: http://lkml.kernel.org/r/20111219153830.GH16765@erda.amd.com Signed-off-by: Ingo Molnar diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 6efc18b..bd58b72 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c @@ -88,7 +88,7 @@ static ssize_t hwsampler_write(struct file *file, char const __user *buf, return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval) + if (retval <= 0) return retval; if (oprofile_started) diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index 89f6345..84a208d 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c @@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf, return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval) + if (retval <= 0) return retval; retval = oprofile_set_timeout(val); @@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval) + if (retval <= 0) return retval; retval = oprofile_set_ulong(&oprofile_backtrace_depth, val); @@ -141,9 +141,10 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t co return -EINVAL; retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval) + if (retval <= 0) return retval; + retval = 0; if (val) retval = oprofile_start(); else diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index d0de6cc..2f0aa0f 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c @@ -60,6 +60,13 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t cou } +/* + * Note: If oprofilefs_ulong_from_user() returns 0, then *val remains + * unchanged and might be uninitialized. This follows write syscall + * implementation when count is zero: "If count is zero ... [and if] + * no errors are detected, 0 will be returned without causing any + * other effect." (man 2 write) + */ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) { char tmpbuf[TMPBUFSIZE]; @@ -79,7 +86,7 @@ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_ raw_spin_lock_irqsave(&oprofilefs_lock, flags); *val = simple_strtoul(tmpbuf, NULL, 0); raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); - return 0; + return count; } @@ -99,7 +106,7 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_ return -EINVAL; retval = oprofilefs_ulong_from_user(&value, buf, count); - if (retval) + if (retval <= 0) return retval; retval = oprofile_set_ulong(file->private_data, value); -- cgit v0.10.2 From e0197aae59e55c06db172bfbe1a1cdb8c0e1cab3 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Thu, 15 Dec 2011 11:36:43 -0800 Subject: cgroups: fix a css_set not found bug in cgroup_attach_proc There is a BUG when migrating a PF_EXITING proc. Since css_set_prefetch() is not called for the PF_EXITING case, find_existing_css_set() will return NULL inside cgroup_task_migrate() causing a BUG. This bug is easy to reproduce. Create a zombie and echo its pid to cgroup.procs. $ cat zombie.c \#include int main() { if (fork()) pause(); return 0; } $ We are hitting this bug pretty regularly on ChromeOS. This bug is already fixed by Tejun Heo's cgroup patchset which is targetted for the next merge window: https://lkml.org/lkml/2011/11/1/356 I've create a smaller patch here which just fixes this bug so that a fix can be merged into the current release and stable. Signed-off-by: Mandeep Singh Baines Downstream-Bug-Report: http://crosbug.com/23953 Reviewed-by: Li Zefan Signed-off-by: Tejun Heo Cc: containers@lists.linux-foundation.org Cc: cgroups@vger.kernel.org Cc: stable@kernel.org Cc: KAMEZAWA Hiroyuki Cc: Frederic Weisbecker Cc: Oleg Nesterov Cc: Andrew Morton Cc: Paul Menage Cc: Olof Johansson diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d9d5648..a184470 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2098,11 +2098,6 @@ int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader) continue; /* get old css_set pointer */ task_lock(tsk); - if (tsk->flags & PF_EXITING) { - /* ignore this task if it's going away */ - task_unlock(tsk); - continue; - } oldcg = tsk->cgroups; get_css_set(oldcg); task_unlock(tsk); -- cgit v0.10.2 From 04ded1672402577cd3f390c764f3046cc704a42a Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 6 Dec 2011 21:17:11 +0000 Subject: RDMA/cma: Verify private data length private_data_len is defined as a u8. If the user specifies a large private_data size (> 220 bytes), we will calculate a total length that exceeds 255, resulting in private_data_len wrapping back to 0. This can lead to overwriting random kernel memory. Avoid this by verifying that the resulting size fits into a u8. Reported-by: B. Thery Addresses: Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 75ff821..d0d4aa9 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -2513,6 +2513,9 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv, req.private_data_len = sizeof(struct cma_hdr) + conn_param->private_data_len; + if (req.private_data_len < conn_param->private_data_len) + return -EINVAL; + req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC); if (!req.private_data) return -ENOMEM; @@ -2562,6 +2565,9 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, memset(&req, 0, sizeof req); offset = cma_user_data_offset(id_priv->id.ps); req.private_data_len = offset + conn_param->private_data_len; + if (req.private_data_len < conn_param->private_data_len) + return -EINVAL; + private_data = kzalloc(req.private_data_len, GFP_ATOMIC); if (!private_data) return -ENOMEM; -- cgit v0.10.2 From 29d1b16145e78e0f4af54751965c4a09e83bd872 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Fri, 2 Dec 2011 12:41:30 -0500 Subject: IB/qib: Correct sense on freectxts increment and decrement Commit 53ab1c64983 ("IB/qib: Correct nfreectxts for multiple HCAs") reversed the increments and decrements of dd->nfreectxts. Fix it. Reviewed-by: Ram Vepa Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 574600e..a740324 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -1285,7 +1285,7 @@ static int setup_ctxt(struct qib_pportdata *ppd, int ctxt, strlcpy(rcd->comm, current->comm, sizeof(rcd->comm)); ctxt_fp(fp) = rcd; qib_stats.sps_ctxts++; - dd->freectxts++; + dd->freectxts--; ret = 0; goto bail; @@ -1794,7 +1794,7 @@ static int qib_close(struct inode *in, struct file *fp) if (dd->pageshadow) unlock_expected_tids(rcd); qib_stats.sps_ctxts--; - dd->freectxts--; + dd->freectxts++; } mutex_unlock(&qib_mutex); -- cgit v0.10.2 From 96f1f05af76b601ab21a7dc603ae0a1cea4efc3d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Fri, 16 Dec 2011 07:53:18 -0800 Subject: iwlwifi: update SCD BC table for all SCD queues Since we configure all the queues as CHAINABLE, we need to update the byte count for all the queues, not only the AGGREGATABLE ones. Not doing so can confuse the SCD and make the fw assert. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ce91898..5f17ab8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1197,9 +1197,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); /* Set up entry for this TFD in Tx byte-count array */ - if (is_agg) - iwl_trans_txq_update_byte_cnt_tbl(trans, txq, - le16_to_cpu(tx_cmd->len)); + iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, DMA_BIDIRECTIONAL); -- cgit v0.10.2 From c070e38e4ee005f55895df177a9e14d90d6204b3 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 16 Nov 2011 10:54:02 -0300 Subject: [media] omap3isp: Fix crash caused by subdevs now having a pointer to devnodes Commit 3e0ec41c5c5ee14e27f65e28d4a616de34f59a97 ("V4L: dynamically allocate video_device nodes in subdevices") makes the embedding video_device directly. Fix accesses to the devnode accordingly. Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index b0b0fa5..54a4a3f 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c @@ -1408,7 +1408,7 @@ static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc) { struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->video_out.video.entity); - struct video_device *vdev = &ccdc->subdev.devnode; + struct video_device *vdev = ccdc->subdev.devnode; struct v4l2_event event; memset(&event, 0, sizeof(event)); diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c index 68d5394..bc0b2c7 100644 --- a/drivers/media/video/omap3isp/ispstat.c +++ b/drivers/media/video/omap3isp/ispstat.c @@ -496,7 +496,7 @@ static int isp_stat_bufs_alloc(struct ispstat *stat, u32 size) static void isp_stat_queue_event(struct ispstat *stat, int err) { - struct video_device *vdev = &stat->subdev.devnode; + struct video_device *vdev = stat->subdev.devnode; struct v4l2_event event; struct omap3isp_stat_event_status *status = (void *)event.u.data; -- cgit v0.10.2 From a03ffcf873fe0f2565386ca8ef832144c42e67fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Sat, 17 Dec 2011 11:39:08 +0000 Subject: net: bpf_jit: fix an off-one bug in x86_64 cond jump target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit x86 jump instruction size is 2 or 5 bytes (near/long jump), not 2 or 6 bytes. In case a conditional jump is followed by a long jump, conditional jump target is one byte past the start of target instruction. Signed-off-by: Markus Kötter Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index bfab3fa..7b65f75 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -568,8 +568,8 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; break; } if (filter[i].jt != 0) { - if (filter[i].jf) - t_offset += is_near(f_offset) ? 2 : 6; + if (filter[i].jf && f_offset) + t_offset += is_near(f_offset) ? 2 : 5; EMIT_COND_JMP(t_op, t_offset); if (filter[i].jf) EMIT_JMP(f_offset); -- cgit v0.10.2 From 9cef310fcdee12b49b8b4c96fd8f611c8873d284 Mon Sep 17 00:00:00 2001 From: Alex Juncu Date: Thu, 15 Dec 2011 23:01:25 +0000 Subject: llc: llc_cmsg_rcv was getting called after sk_eat_skb. Received non stream protocol packets were calling llc_cmsg_rcv that used a skb after that skb was released by sk_eat_skb. This caused received STP packets to generate kernel panics. Signed-off-by: Alexandru Juncu Signed-off-by: Kunjan Naik Signed-off-by: David S. Miller diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index dfd3a64..a18e6c3 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -833,15 +833,15 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, copied += used; len -= used; + /* For non stream protcols we get one packet per recvmsg call */ + if (sk->sk_type != SOCK_STREAM) + goto copy_uaddr; + if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, 0); *seq = 0; } - /* For non stream protcols we get one packet per recvmsg call */ - if (sk->sk_type != SOCK_STREAM) - goto copy_uaddr; - /* Partial read */ if (used + offset < skb->len) continue; @@ -857,6 +857,12 @@ copy_uaddr: } if (llc_sk(sk)->cmsg_flags) llc_cmsg_rcv(msg, skb); + + if (!(flags & MSG_PEEK)) { + sk_eat_skb(sk, skb, 0); + *seq = 0; + } + goto out; } -- cgit v0.10.2 From 2ca6cf06d988fea21e812a86be79353352677c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fran=C3=A7ois=20romieu?= Date: Thu, 15 Dec 2011 08:37:43 +0000 Subject: r8169: fix Config2 MSIEnable bit setting. The MSIEnable bit is only available for the 8169. Avoid Config2 writes for the post-8169 8168 and 810x. Reported-by: Su Kang Yin Signed-off-by: Francois Romieu Cc: Hayes Wang Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 67bf078..c8f47f1 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -477,7 +477,6 @@ enum rtl_register_content { /* Config1 register p.24 */ LEDS1 = (1 << 7), LEDS0 = (1 << 6), - MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ Speed_down = (1 << 4), MEMMAP = (1 << 3), IOMAP = (1 << 2), @@ -485,6 +484,7 @@ enum rtl_register_content { PMEnable = (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ + MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, @@ -3426,22 +3426,24 @@ static const struct rtl_cfg_info { }; /* Cfg9346_Unlock assumed. */ -static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, +static unsigned rtl_try_msi(struct rtl8169_private *tp, const struct rtl_cfg_info *cfg) { + void __iomem *ioaddr = tp->mmio_addr; unsigned msi = 0; u8 cfg2; cfg2 = RTL_R8(Config2) & ~MSIEnable; if (cfg->features & RTL_FEATURE_MSI) { - if (pci_enable_msi(pdev)) { - dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); + if (pci_enable_msi(tp->pci_dev)) { + netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); } else { cfg2 |= MSIEnable; msi = RTL_FEATURE_MSI; } } - RTL_W8(Config2, cfg2); + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) + RTL_W8(Config2, cfg2); return msi; } @@ -4077,7 +4079,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->features |= RTL_FEATURE_WOL; if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) tp->features |= RTL_FEATURE_WOL; - tp->features |= rtl_try_msi(pdev, ioaddr, cfg); + tp->features |= rtl_try_msi(tp, cfg); RTL_W8(Cfg9346, Cfg9346_Lock); if (rtl_tbi_enabled(tp)) { -- cgit v0.10.2 From 13f541c10b30fc6529200d7f9a0073217709622f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 19 Dec 2011 22:07:58 +0100 Subject: x86, dumpstack: Fix code bytes breakage due to missing KERN_CONT When printing the code bytes in show_registers(), the markers around the byte at the fault address could make the printk() format string look like a valid log level and facility code. This would prevent this byte from being printed and result in a spurious newline: [ 7555.765589] Code: 8b 32 e9 94 00 00 00 81 7d 00 ff 00 00 00 0f 87 96 00 00 00 48 8b 83 c0 00 00 00 44 89 e2 44 89 e6 48 89 df 48 8b 80 d8 02 00 00 [ 7555.765683] 8b 48 28 48 89 d0 81 e2 ff 0f 00 00 48 c1 e8 0c 48 c1 e0 04 Add KERN_CONT where needed, and elsewhere in show_registers() for consistency. Signed-off-by: Clemens Ladisch Link: http://lkml.kernel.org/r/4EEFA7AE.9020407@ladisch.de Signed-off-by: H. Peter Anvin diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index 3b97a80..c99f9ed 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -116,16 +116,16 @@ void show_registers(struct pt_regs *regs) for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - printk(" Bad EIP value."); + printk(KERN_CONT " Bad EIP value."); break; } if (ip == (u8 *)regs->ip) - printk("<%02x> ", c); + printk(KERN_CONT "<%02x> ", c); else - printk("%02x ", c); + printk(KERN_CONT "%02x ", c); } } - printk("\n"); + printk(KERN_CONT "\n"); } int is_valid_bugaddr(unsigned long ip) diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 19853ad..6d728d9 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -284,16 +284,16 @@ void show_registers(struct pt_regs *regs) for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { - printk(" Bad RIP value."); + printk(KERN_CONT " Bad RIP value."); break; } if (ip == (u8 *)regs->ip) - printk("<%02x> ", c); + printk(KERN_CONT "<%02x> ", c); else - printk("%02x ", c); + printk(KERN_CONT "%02x ", c); } } - printk("\n"); + printk(KERN_CONT "\n"); } int is_valid_bugaddr(unsigned long ip) -- cgit v0.10.2 From 2692ba61a82203404abd7dd2a027bda962861f74 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Fri, 16 Dec 2011 12:44:15 +0000 Subject: sctp: fix incorrect overflow check on autoclose Commit 8ffd3208 voids the previous patches f6778aab and 810c0719 for limiting the autoclose value. If userspace passes in -1 on 32-bit platform, the overflow check didn't work and autoclose would be set to 0xffffffff. This patch defines a max_autoclose (in seconds) for limiting the value and exposes it through sysctl, with the following intentions. 1) Avoid overflowing autoclose * HZ. 2) Keep the default autoclose bound consistent across 32- and 64-bit platforms (INT_MAX / HZ in this patch). 3) Keep the autoclose value consistent between setsockopt() and getsockopt() calls. Suggested-by: Vlad Yasevich Signed-off-by: Xi Wang Signed-off-by: David S. Miller diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index e90e7a9..a15432da 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -241,6 +241,9 @@ extern struct sctp_globals { * bits is an indicator of when to send and window update SACK. */ int rwnd_update_shift; + + /* Threshold for autoclose timeout, in seconds. */ + unsigned long max_autoclose; } sctp_globals; #define sctp_rto_initial (sctp_globals.rto_initial) @@ -281,6 +284,7 @@ extern struct sctp_globals { #define sctp_auth_enable (sctp_globals.auth_enable) #define sctp_checksum_disable (sctp_globals.checksum_disable) #define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift) +#define sctp_max_autoclose (sctp_globals.max_autoclose) /* SCTP Socket type: UDP or TCP style. */ typedef enum { diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 152b5b3..acd2edb 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -173,7 +173,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = - (unsigned long)sp->autoclose * HZ; + min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ; /* Initializes the timers */ for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 61b9fca..6f6ad86 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1285,6 +1285,9 @@ SCTP_STATIC __init int sctp_init(void) sctp_max_instreams = SCTP_DEFAULT_INSTREAMS; sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS; + /* Initialize maximum autoclose timeout. */ + sctp_max_autoclose = INT_MAX / HZ; + /* Initialize handle used for association ids. */ idr_init(&sctp_assocs_id); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 13bf5fc..54a7cd2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2200,8 +2200,6 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, return -EINVAL; if (copy_from_user(&sp->autoclose, optval, optlen)) return -EFAULT; - /* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */ - sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ); return 0; } diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 6b39529..60ffbd0 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -53,6 +53,10 @@ static int sack_timer_min = 1; static int sack_timer_max = 500; static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ static int rwnd_scale_max = 16; +static unsigned long max_autoclose_min = 0; +static unsigned long max_autoclose_max = + (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX) + ? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ; extern long sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; @@ -258,6 +262,15 @@ static ctl_table sctp_table[] = { .extra1 = &one, .extra2 = &rwnd_scale_max, }, + { + .procname = "max_autoclose", + .data = &sctp_max_autoclose, + .maxlen = sizeof(unsigned long), + .mode = 0644, + .proc_handler = &proc_doulongvec_minmax, + .extra1 = &max_autoclose_min, + .extra2 = &max_autoclose_max, + }, { /* sentinel */ } }; -- cgit v0.10.2 From 7746ab0abb512826540a9a0c917519d11a7bf392 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Sun, 18 Dec 2011 10:02:04 +0000 Subject: davinci-cpdma: fix locking issue in cpdma_chan_stop Free the channel lock before calling __cpdma_chan_process to prevent dead lock. Signed-off-by: Ilya Yanok Tested-by: Ameya Palande <2ameya@gmail.com> Signed-off-by: David S. Miller diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index dca9d33..c97d2f5 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c @@ -836,11 +836,13 @@ int cpdma_chan_stop(struct cpdma_chan *chan) chan_write(chan, cp, CPDMA_TEARDOWN_VALUE); /* handle completed packets */ + spin_unlock_irqrestore(&chan->lock, flags); do { ret = __cpdma_chan_process(chan); if (ret < 0) break; } while ((ret & CPDMA_DESC_TD_COMPLETE) == 0); + spin_lock_irqsave(&chan->lock, flags); /* remaining packets haven't been tx/rx'ed, clean them up */ while (chan->head) { -- cgit v0.10.2 From e8303a3b2196272c3eb994d0fd1a189a958a2bdd Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Fri, 16 Dec 2011 10:49:22 +0000 Subject: asix: new device id Adds the device id needed for the USB Ethernet Adapter delivered by ASUS with their Zenbook. Signed-off-by: Aurelien Jacobs Acked-by: Grant Grundler Signed-off-by: David S. Miller diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index e6fed4d..e95f0e6 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -1655,6 +1655,10 @@ static const struct usb_device_id products [] = { // ASIX 88772a USB_DEVICE(0x0db0, 0xa877), .driver_info = (unsigned long) &ax88772_info, +}, { + // Asus USB Ethernet Adapter + USB_DEVICE (0x0b95, 0x7e2b), + .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; -- cgit v0.10.2 From 29495aa04a30c21565243c5b9c028510446d242c Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Thu, 3 Nov 2011 11:09:45 +0100 Subject: mmc: sdhci: remove "state" argument from sdhci_suspend_host Drop the "state" argument from sdhci_suspend_host. Its only user is the PCI glue; this allows to move all SDHCI glues to use dev_pm_ops instead. Signed-off-by: Manuel Lauss Acked-by: Adrian Hunter Signed-off-by: Chris Ball diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c index 87b6f07..b4257e7 100644 --- a/drivers/mmc/host/sdhci-cns3xxx.c +++ b/drivers/mmc/host/sdhci-cns3xxx.c @@ -109,13 +109,10 @@ static struct platform_driver sdhci_cns3xxx_driver = { .driver = { .name = "sdhci-cns3xxx", .owner = THIS_MODULE, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_cns3xxx_probe, .remove = __devexit_p(sdhci_cns3xxx_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_cns3xxx_init(void) diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index f2d29dc..a81312c 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c @@ -82,13 +82,10 @@ static struct platform_driver sdhci_dove_driver = { .driver = { .name = "sdhci-dove", .owner = THIS_MODULE, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_dove_probe, .remove = __devexit_p(sdhci_dove_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_dove_init(void) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 4b976f0..38ebc4e 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -599,14 +599,11 @@ static struct platform_driver sdhci_esdhc_imx_driver = { .name = "sdhci-esdhc-imx", .owner = THIS_MODULE, .of_match_table = imx_esdhc_dt_ids, + .pm = SDHCI_PLTFM_PMOPS, }, .id_table = imx_esdhc_devtype, .probe = sdhci_esdhc_imx_probe, .remove = __devexit_p(sdhci_esdhc_imx_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_esdhc_imx_init(void) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 59e9d00..01e5f62 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -125,13 +125,10 @@ static struct platform_driver sdhci_esdhc_driver = { .name = "sdhci-esdhc", .owner = THIS_MODULE, .of_match_table = sdhci_esdhc_of_match, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_esdhc_probe, .remove = __devexit_p(sdhci_esdhc_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_esdhc_init(void) diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 9b0d794..3619adc 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c @@ -87,13 +87,10 @@ static struct platform_driver sdhci_hlwd_driver = { .name = "sdhci-hlwd", .owner = THIS_MODULE, .of_match_table = sdhci_hlwd_of_match, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_hlwd_probe, .remove = __devexit_p(sdhci_hlwd_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_hlwd_init(void) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d833d9c..6878a946 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -54,8 +54,7 @@ struct sdhci_pci_fixes { int (*probe_slot) (struct sdhci_pci_slot *); void (*remove_slot) (struct sdhci_pci_slot *, int); - int (*suspend) (struct sdhci_pci_chip *, - pm_message_t); + int (*suspend) (struct sdhci_pci_chip *); int (*resume) (struct sdhci_pci_chip *); }; @@ -549,7 +548,7 @@ static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead) jmicron_enable_mmc(slot->host, 0); } -static int jmicron_suspend(struct sdhci_pci_chip *chip, pm_message_t state) +static int jmicron_suspend(struct sdhci_pci_chip *chip) { int i; @@ -993,8 +992,9 @@ static struct sdhci_ops sdhci_pci_ops = { #ifdef CONFIG_PM -static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int sdhci_pci_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct sdhci_pci_chip *chip; struct sdhci_pci_slot *slot; mmc_pm_flag_t slot_pm_flags; @@ -1010,7 +1010,7 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) if (!slot) continue; - ret = sdhci_suspend_host(slot->host, state); + ret = sdhci_suspend_host(slot->host); if (ret) { for (i--; i >= 0; i--) @@ -1026,7 +1026,7 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) } if (chip->fixes && chip->fixes->suspend) { - ret = chip->fixes->suspend(chip, state); + ret = chip->fixes->suspend(chip); if (ret) { for (i = chip->num_slots - 1; i >= 0; i--) sdhci_resume_host(chip->slots[i]->host); @@ -1042,16 +1042,17 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) } pci_set_power_state(pdev, PCI_D3hot); } else { - pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + pci_enable_wake(pdev, PCI_D3hot, 0); pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + pci_set_power_state(pdev, PCI_D3hot); } return 0; } -static int sdhci_pci_resume(struct pci_dev *pdev) +static int sdhci_pci_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct sdhci_pci_chip *chip; struct sdhci_pci_slot *slot; int i, ret; @@ -1099,7 +1100,6 @@ static int sdhci_pci_runtime_suspend(struct device *dev) struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); struct sdhci_pci_chip *chip; struct sdhci_pci_slot *slot; - pm_message_t state = { .event = PM_EVENT_SUSPEND }; int i, ret; chip = pci_get_drvdata(pdev); @@ -1121,7 +1121,7 @@ static int sdhci_pci_runtime_suspend(struct device *dev) } if (chip->fixes && chip->fixes->suspend) { - ret = chip->fixes->suspend(chip, state); + ret = chip->fixes->suspend(chip); if (ret) { for (i = chip->num_slots - 1; i >= 0; i--) sdhci_runtime_resume_host(chip->slots[i]->host); @@ -1176,6 +1176,8 @@ static int sdhci_pci_runtime_idle(struct device *dev) #endif static const struct dev_pm_ops sdhci_pci_pm_ops = { + .suspend = sdhci_pci_suspend, + .resume = sdhci_pci_resume, .runtime_suspend = sdhci_pci_runtime_suspend, .runtime_resume = sdhci_pci_runtime_resume, .runtime_idle = sdhci_pci_runtime_idle, @@ -1428,8 +1430,6 @@ static struct pci_driver sdhci_driver = { .id_table = pci_ids, .probe = sdhci_pci_probe, .remove = __devexit_p(sdhci_pci_remove), - .suspend = sdhci_pci_suspend, - .resume = sdhci_pci_resume, .driver = { .pm = &sdhci_pci_pm_ops }, diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index a9e12ea..03970bc 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -194,21 +194,25 @@ int sdhci_pltfm_unregister(struct platform_device *pdev) EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); #ifdef CONFIG_PM -int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state) +static int sdhci_pltfm_suspend(struct device *dev) { - struct sdhci_host *host = platform_get_drvdata(dev); + struct sdhci_host *host = dev_get_drvdata(dev); - return sdhci_suspend_host(host, state); + return sdhci_suspend_host(host); } -EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend); -int sdhci_pltfm_resume(struct platform_device *dev) +static int sdhci_pltfm_resume(struct device *dev) { - struct sdhci_host *host = platform_get_drvdata(dev); + struct sdhci_host *host = dev_get_drvdata(dev); return sdhci_resume_host(host); } -EXPORT_SYMBOL_GPL(sdhci_pltfm_resume); + +const struct dev_pm_ops sdhci_pltfm_pmops = { + .suspend = sdhci_pltfm_suspend, + .resume = sdhci_pltfm_resume, +}; +EXPORT_SYMBOL_GPL(sdhci_pltfm_pmops); #endif /* CONFIG_PM */ static int __init sdhci_pltfm_drv_init(void) diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h index 3a9fc3f..37e0e18 100644 --- a/drivers/mmc/host/sdhci-pltfm.h +++ b/drivers/mmc/host/sdhci-pltfm.h @@ -99,8 +99,10 @@ extern int sdhci_pltfm_register(struct platform_device *pdev, extern int sdhci_pltfm_unregister(struct platform_device *pdev); #ifdef CONFIG_PM -extern int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state); -extern int sdhci_pltfm_resume(struct platform_device *dev); +extern const struct dev_pm_ops sdhci_pltfm_pmops; +#define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops) +#else +#define SDHCI_PLTFM_PMOPS NULL #endif #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index d4bf6d3..7a039c3 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -218,13 +218,10 @@ static struct platform_driver sdhci_pxav2_driver = { .driver = { .name = "sdhci-pxav2", .owner = THIS_MODULE, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_pxav2_probe, .remove = __devexit_p(sdhci_pxav2_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_pxav2_init(void) { diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index cff4ad3..15673a7 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -264,13 +264,10 @@ static struct platform_driver sdhci_pxav3_driver = { .driver = { .name = "sdhci-pxav3", .owner = THIS_MODULE, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_pxav3_probe, .remove = __devexit_p(sdhci_pxav3_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_pxav3_init(void) { diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index cb60c41..0d33ff0 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -622,23 +622,29 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) #ifdef CONFIG_PM -static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm) +static int sdhci_s3c_suspend(struct device *dev) { - struct sdhci_host *host = platform_get_drvdata(dev); + struct sdhci_host *host = dev_get_drvdata(dev); - return sdhci_suspend_host(host, pm); + return sdhci_suspend_host(host); } -static int sdhci_s3c_resume(struct platform_device *dev) +static int sdhci_s3c_resume(struct device *dev) { - struct sdhci_host *host = platform_get_drvdata(dev); + struct sdhci_host *host = dev_get_drvdata(dev); return sdhci_resume_host(host); } +static const struct dev_pm_ops sdhci_s3c_pmops = { + .suspend = sdhci_s3c_suspend, + .resume = sdhci_s3c_resume, +}; + +#define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) + #else -#define sdhci_s3c_suspend NULL -#define sdhci_s3c_resume NULL +#define SDHCI_S3C_PMOPS NULL #endif static struct platform_driver sdhci_s3c_driver = { @@ -647,6 +653,7 @@ static struct platform_driver sdhci_s3c_driver = { .driver = { .owner = THIS_MODULE, .name = "s3c-sdhci", + .pm = SDHCI_S3C_PMOPS, }, }; diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 89699e8..e2e18d3 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -318,13 +318,10 @@ static struct platform_driver sdhci_tegra_driver = { .name = "sdhci-tegra", .owner = THIS_MODULE, .of_match_table = sdhci_tegra_dt_match, + .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_tegra_probe, .remove = __devexit_p(sdhci_tegra_remove), -#ifdef CONFIG_PM - .suspend = sdhci_pltfm_suspend, - .resume = sdhci_pltfm_resume, -#endif }; static int __init sdhci_tegra_init(void) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6d8eea3..19ed580 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2327,7 +2327,7 @@ out: #ifdef CONFIG_PM -int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) +int sdhci_suspend_host(struct sdhci_host *host) { int ret; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0a5b654..a04d4d0 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -374,7 +374,7 @@ extern int sdhci_add_host(struct sdhci_host *host); extern void sdhci_remove_host(struct sdhci_host *host, int dead); #ifdef CONFIG_PM -extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); +extern int sdhci_suspend_host(struct sdhci_host *host); extern int sdhci_resume_host(struct sdhci_host *host); extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); #endif -- cgit v0.10.2 From 5c7f0e083d2d98ba14ddd10e88f001a0ead4cae4 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Mon, 19 Dec 2011 15:51:38 -0800 Subject: Revert "mmc: enable runtime PM by default" When SDIO runtime PM was originally introduced, we immediately faced two regressions with two different chipsets, and in response decided not to enable it by default. With the recent work on the 8686 we hoped we found all the gotchas, so 08da834 did make sense (at least experimentally). Unfortunately we now see that some setups out there still refuse to work when SDIO runtime PM is enabled by default (see http://www.spinics.net/lists/linux-mmc/msg11161.html), and obviously we can't live with these kind of regressions. This reverts commit 08da834a24312157f512224691ad1fddd11c1073. Signed-off-by: Ohad Ben-Cohen Cc: Daniel Drake Signed-off-by: Chris Ball diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index e8a5eb3..d31c78b 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -302,17 +302,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) host->max_blk_size = 512; host->max_blk_count = PAGE_CACHE_SIZE / 512; - /* - * Enable runtime power management by default. This flag was added due - * to runtime power management causing disruption for some users, but - * the power on/off code has been improved since then. - * - * We'll enable this flag by default as an experiment, and if no - * problems are reported, we will follow up later and remove the flag - * altogether. - */ - host->caps = MMC_CAP_POWER_OFF_CARD; - return host; free: -- cgit v0.10.2 From 61074287c2965edf0fc75b54ae8f4ce99f182669 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 15 Dec 2011 13:34:50 +1030 Subject: mmc: vub300: fix type of firmware_rom_wait_states module parameter You didn't mean this to be a bool. Signed-off-by: Rusty Russell Acked-by: Tony Olech Cc: Signed-off-by: Chris Ball diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index e8f6e65..2ec978b 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -259,7 +259,7 @@ static int firmware_rom_wait_states = 0x04; static int firmware_rom_wait_states = 0x1C; #endif -module_param(firmware_rom_wait_states, bool, 0644); +module_param(firmware_rom_wait_states, int, 0644); MODULE_PARM_DESC(firmware_rom_wait_states, "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); -- cgit v0.10.2 From 0b35a45bde561d67ffd83b352764b48f936f46bb Mon Sep 17 00:00:00 2001 From: Holger Brunck Date: Mon, 19 Dec 2011 17:49:48 +0100 Subject: ARM: plat-orion: make gpiochip label unique The former implementation adds a fix gpiochip label string to the framework. This is confusing because orion_gpio_init is called more than once and this ends up in different gpiochips with the same label. This patch adds the already present orion_gpio_chip_count to the label string to make it unique in the system. Signed-off-by: Holger Brunck Cc: Lennert Buytenhek Acked-by: Nicolas Pitre Signed-off-by: Olof Johansson diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index 41ab97e..10d1608 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c @@ -384,12 +384,16 @@ void __init orion_gpio_init(int gpio_base, int ngpio, struct orion_gpio_chip *ochip; struct irq_chip_generic *gc; struct irq_chip_type *ct; + char gc_label[16]; if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips)) return; + snprintf(gc_label, sizeof(gc_label), "orion_gpio%d", + orion_gpio_chip_count); + ochip = orion_gpio_chips + orion_gpio_chip_count; - ochip->chip.label = "orion_gpio"; + ochip->chip.label = kstrdup(gc_label, GFP_KERNEL); ochip->chip.request = orion_gpio_request; ochip->chip.direction_input = orion_gpio_direction_input; ochip->chip.get = orion_gpio_get; -- cgit v0.10.2 From d21b59451886cb82448302f8d6f9ac87c3bd56cf Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Mon, 5 Dec 2011 13:17:41 +0200 Subject: evm: key must be set once during initialization On multi-core systems, setting of the key before every caclculation, causes invalid HMAC calculation for other tfm users, because internal state (ipad, opad) can be invalid before set key call returns. It needs to be set only once during initialization. Signed-off-by: Dmitry Kasatkin Acked-by: Mimi Zohar Signed-off-by: James Morris diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 5dd5b140..4ad657d 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -41,6 +41,12 @@ static struct shash_desc *init_desc(void) hmac_tfm = NULL; return ERR_PTR(rc); } + rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len); + if (rc) { + crypto_free_shash(hmac_tfm); + hmac_tfm = NULL; + return ERR_PTR(rc); + } } desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm), @@ -51,11 +57,7 @@ static struct shash_desc *init_desc(void) desc->tfm = hmac_tfm; desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; - rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len); - if (rc) - goto out; rc = crypto_shash_init(desc); -out: if (rc) { kfree(desc); return ERR_PTR(rc); -- cgit v0.10.2 From 97426f985729573cea06e82e271cc3929f1f5f8e Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Mon, 5 Dec 2011 13:17:42 +0200 Subject: evm: prevent racing during tfm allocation There is a small chance of racing during tfm allocation. This patch fixes it. Signed-off-by: Dmitry Kasatkin Acked-by: Mimi Zohar Signed-off-by: James Morris diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 4ad657d..8738def 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -27,26 +27,35 @@ static int evmkey_len = MAX_KEY_SIZE; struct crypto_shash *hmac_tfm; +static DEFINE_MUTEX(mutex); + static struct shash_desc *init_desc(void) { int rc; struct shash_desc *desc; if (hmac_tfm == NULL) { + mutex_lock(&mutex); + if (hmac_tfm) + goto out; hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(hmac_tfm)) { pr_err("Can not allocate %s (reason: %ld)\n", evm_hmac, PTR_ERR(hmac_tfm)); rc = PTR_ERR(hmac_tfm); hmac_tfm = NULL; + mutex_unlock(&mutex); return ERR_PTR(rc); } rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len); if (rc) { crypto_free_shash(hmac_tfm); hmac_tfm = NULL; + mutex_unlock(&mutex); return ERR_PTR(rc); } +out: + mutex_unlock(&mutex); } desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm), -- cgit v0.10.2 From 9ad33ba51a1ac29ba3cf90d95e4b7f7eba278f6c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 31 Oct 2011 10:34:01 +0800 Subject: mfd: Add missed free_irq in da903x_remove Signed-off-by: Axel Lin Acked-by: Eric Miao Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 1b79c37..62ce685 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -549,6 +549,7 @@ static int __devexit da903x_remove(struct i2c_client *client) struct da903x_chip *chip = i2c_get_clientdata(client); da903x_remove_subdevs(chip); + free_irq(client->irq, chip); kfree(chip); return 0; } -- cgit v0.10.2 From 890c98e3746fa8705cc9c70979e64360cf2d8a31 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 31 Oct 2011 11:00:06 +0800 Subject: mfd: Set adp5520 bits if new value is different from the old one Current code checks if all the bit_mask bits are all zero is wrong. We need to write new value if the bit mask fields of new value is not equal to old value. Signed-off-by: Axel Lin Acked-by: Michael Hennerich Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index f1d8848..8d816cc 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -109,7 +109,7 @@ int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask) ret = __adp5520_read(chip->client, reg, ®_val); - if (!ret && ((reg_val & bit_mask) == 0)) { + if (!ret && ((reg_val & bit_mask) != bit_mask)) { reg_val |= bit_mask; ret = __adp5520_write(chip->client, reg, reg_val); } -- cgit v0.10.2 From af65e6cef488be0bd15932c8ce9801a47a183051 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 31 Oct 2011 14:23:03 +0800 Subject: mfd: Set da903x bits if new value is different from the old one It does not make sense to write new value only when all the bit_mask bits are zero. We need to write new value if the bit mask fields of new value is not equal to old value. Signed-off-by: Axel Lin Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 62ce685..1924b85 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -182,7 +182,7 @@ int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask) if (ret) goto out; - if ((reg_val & bit_mask) == 0) { + if ((reg_val & bit_mask) != bit_mask) { reg_val |= bit_mask; ret = __da903x_write(chip->client, reg, reg_val); } -- cgit v0.10.2 From 26bc4e0cc5426e86398d6780d160f02c0a347087 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 31 Oct 2011 14:24:30 +0800 Subject: mfd: Set tps6586x bits if new value is different from the old one It does not make sense to write new value only when all the bit_mask bits are zero. We need to write new value if the bit mask fields of new value is not equal to old value. Signed-off-by: Axel Lin Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index bba26d9..a5ddf31 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -197,7 +197,7 @@ int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask) if (ret) goto out; - if ((reg_val & bit_mask) == 0) { + if ((reg_val & bit_mask) != bit_mask) { reg_val |= bit_mask; ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); } -- cgit v0.10.2 From b5488b6e868454fb10d23278de5038cda98b13ab Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Nov 2011 23:14:46 +0000 Subject: mfd: Update wm8994 active device checks for WM1811 This didn't go in as part of the original MFD patch for WM1811 due to cross tree issues. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 5d6ba13..61894fc 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -239,6 +239,7 @@ static int wm8994_suspend(struct device *dev) switch (wm8994->type) { case WM8958: + case WM1811: ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); if (ret < 0) { dev_err(dev, "Failed to read power status: %d\n", ret); -- cgit v0.10.2 From 858a6303f2b14945447a964563f54c918ef3927e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 7 Nov 2011 11:20:09 +0800 Subject: mfd: include linux/module.h for ab5500-debugfs Include linux/module.h to fix below build error: CC drivers/mfd/ab5500-debugfs.o drivers/mfd/ab5500-debugfs.c:571: error: 'THIS_MODULE' undeclared here (not in a function) make[2]: *** [drivers/mfd/ab5500-debugfs.o] Error 1 Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c index 43c0ebb..b7b2d348 100644 --- a/drivers/mfd/ab5500-debugfs.c +++ b/drivers/mfd/ab5500-debugfs.c @@ -4,7 +4,7 @@ * Debugfs support for the AB5500 MFD driver */ -#include +#include #include #include #include -- cgit v0.10.2 From 8653be1afd60d6e8c36139b487e375b70357d9ef Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 1 Aug 2011 23:00:28 +0200 Subject: mfd: Fix twl-core oops while calling twl_i2c_* for unbound driver Check inuse variable before trying to access twl_map to prevent dereferencing of uninitialized variable. Signed-off-by: Ilya Yanok Cc: stable@kernel.org Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index bfbd660..61e70cf 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -363,13 +363,13 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); return -EPERM; } - sid = twl_map[mod_no].sid; - twl = &twl_modules[sid]; - if (unlikely(!inuse)) { - pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); + pr_err("%s: not initialized\n", DRIVER_NAME); return -EPERM; } + sid = twl_map[mod_no].sid; + twl = &twl_modules[sid]; + mutex_lock(&twl->xfer_lock); /* * [MSG1]: fill the register address data @@ -420,13 +420,13 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); return -EPERM; } - sid = twl_map[mod_no].sid; - twl = &twl_modules[sid]; - if (unlikely(!inuse)) { - pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); + pr_err("%s: not initialized\n", DRIVER_NAME); return -EPERM; } + sid = twl_map[mod_no].sid; + twl = &twl_modules[sid]; + mutex_lock(&twl->xfer_lock); /* [MSG1] fill the register address data */ msg = &twl->xfer_msg[0]; -- cgit v0.10.2 From df7206477e36bb73e81b99c2cbbc1b91e4b1c8ac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 10 Nov 2011 09:56:18 +0800 Subject: mfd: add #ifdef CONFIG_DEBUG_FS guard for ab8500_debug_resources Fix below build warning if CONFIG_DEBUG_FS is disabled. CC drivers/mfd/ab8500-core.o drivers/mfd/ab8500-core.c:623: warning: 'ab8500_debug_resources' defined but not used Signed-off-by: Axel Lin Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 1e91738..d3d572b 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -620,6 +620,7 @@ static struct resource __devinitdata ab8500_fg_resources[] = { static struct resource __devinitdata ab8500_chargalg_resources[] = {}; +#ifdef CONFIG_DEBUG_FS static struct resource __devinitdata ab8500_debug_resources[] = { { .name = "IRQ_FIRST", @@ -634,6 +635,7 @@ static struct resource __devinitdata ab8500_debug_resources[] = { .flags = IORESOURCE_IRQ, }, }; +#endif static struct resource __devinitdata ab8500_usb_resources[] = { { -- cgit v0.10.2 From 8f6a459a9daa6ce76d7c192f2cb3047fffb45ec8 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Tue, 22 Nov 2011 14:39:51 +0100 Subject: mfd: Handle tps65910 clear-mask correctly The function is not actually cleaing the bitmask. Signed-off-by: Marcus Folkesson Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 6f5b8cf..c1da84b 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -120,7 +120,7 @@ int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask) goto out; } - data &= mask; + data &= ~mask; err = tps65910_i2c_write(tps65910, reg, 1, &data); if (err) dev_err(tps65910->dev, "write to reg %x failed\n", reg); -- cgit v0.10.2 From 286f8f3cd615177d5d0f8af8059a3fa39f51fa97 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 27 Nov 2011 07:17:41 +1100 Subject: mfd: Base interrupt for twl4030-irq must be one-shot As the interrupt source is only cleared by the threaded interrupt service routine, we need to make the base interrupt IRQF_ONESHOT. Without this, the first interrupt from the TWL4030 cause the CPU to enter an infinite loop trying to handle to interrupt but never clearing it. Signed-off-by: NeilBrown Tested-by: Felipe Contreras Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index f062c8c..3d3d6ed 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -733,8 +733,9 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) } /* install an irq handler to demultiplex the TWL4030 interrupt */ - status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 0, - "TWL4030-PIH", NULL); + status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, + IRQF_ONESHOT, + "TWL4030-PIH", NULL); if (status < 0) { pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); goto fail_rqirq; -- cgit v0.10.2 From c1e61bcf8269d3bc4390a363ad2e1bc1dc226bda Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 27 Nov 2011 07:17:41 +1100 Subject: mfd: Use request_threaded_irq for twl4030-irq instead of irq_set_chained_handler irq_set_chained_handler sets 'desc->handle_irq'. However this irq is called by handle_nested_irq from handle_twl4030_pih, and that uses action->thread_fn. So the handled set with irq_set_chained_handler is never called. So change to use request_threaded_irq instead - that sets the correct field. Tested on GTA04 Phoenux. Signed-off-by: NeilBrown Tested-by: Felipe Contreras Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 3d3d6ed..29f11e0 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -432,6 +432,7 @@ struct sih_agent { u32 edge_change; struct mutex irq_lock; + char *irq_name; }; /*----------------------------------------------------------------------*/ @@ -589,7 +590,7 @@ static inline int sih_read_isr(const struct sih *sih) * Generic handler for SIH interrupts ... we "know" this is called * in task context, with IRQs enabled. */ -static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) +static irqreturn_t handle_twl4030_sih(int irq, void *data) { struct sih_agent *agent = irq_get_handler_data(irq); const struct sih *sih = agent->sih; @@ -602,7 +603,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) pr_err("twl4030: %s SIH, read ISR error %d\n", sih->name, isr); /* REVISIT: recover; eventually mask it all, etc */ - return; + return IRQ_HANDLED; } while (isr) { @@ -616,6 +617,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) pr_err("twl4030: %s SIH, invalid ISR bit %d\n", sih->name, irq); } + return IRQ_HANDLED; } static unsigned twl4030_irq_next; @@ -668,18 +670,19 @@ int twl4030_sih_setup(int module) activate_irq(irq); } - status = irq_base; twl4030_irq_next += i; /* replace generic PIH handler (handle_simple_irq) */ irq = sih_mod + twl4030_irq_base; irq_set_handler_data(irq, agent); - irq_set_chained_handler(irq, handle_twl4030_sih); + agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); + status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, + agent->irq_name ?: sih->name, NULL); pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, irq, irq_base, twl4030_irq_next - 1); - return status; + return status < 0 ? status : irq_base; } /* FIXME need a call to reverse twl4030_sih_setup() ... */ -- cgit v0.10.2 From fa860403e61cf5201e2f03b726aa53c30ae9a659 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 9 Dec 2011 11:27:55 +0800 Subject: mfd: Include linux/io.h to jz4740-adc Include linux/io.h to fix below build error: CC drivers/mfd/jz4740-adc.o drivers/mfd/jz4740-adc.c: In function 'jz4740_adc_irq_demux': drivers/mfd/jz4740-adc.c:73: error: implicit declaration of function 'readb' drivers/mfd/jz4740-adc.c: In function 'jz4740_adc_set_enabled': drivers/mfd/jz4740-adc.c:110: error: implicit declaration of function 'writeb' drivers/mfd/jz4740-adc.c: In function 'jz4740_adc_set_config': drivers/mfd/jz4740-adc.c:146: error: implicit declaration of function 'readl' drivers/mfd/jz4740-adc.c:151: error: implicit declaration of function 'writel' drivers/mfd/jz4740-adc.c: In function 'jz4740_adc_probe': drivers/mfd/jz4740-adc.c:249: error: implicit declaration of function 'ioremap_nocache' drivers/mfd/jz4740-adc.c:249: warning: assignment makes pointer from integer without a cast drivers/mfd/jz4740-adc.c:289: warning: passing argument 3 of 'mfd_add_devices' discards qualifiers from pointer target type include/linux/mfd/core.h:93: note: expected 'struct mfd_cell *' but argument is of type 'const struct mfd_cell *' drivers/mfd/jz4740-adc.c:299: error: implicit declaration of function 'iounmap' make[2]: *** [drivers/mfd/jz4740-adc.o] Error 1 make[1]: *** [drivers/mfd] Error 2 make: *** [drivers] Error 2 Signed-off-by: Axel Lin Acked-by: Lars-Peter Clausen Signed-off-by: Samuel Ortiz diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 1e9ee53..ef39528 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include -- cgit v0.10.2 From b246272ecc5ac68c743b15c9e41a2275f7ce70e2 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 19 Dec 2011 17:11:52 -0800 Subject: cpusets: stall when updating mems_allowed for mempolicy or disjoint nodemask Kernels where MAX_NUMNODES > BITS_PER_LONG may temporarily see an empty nodemask in a tsk's mempolicy if its previous nodemask is remapped onto a new set of allowed cpuset nodes where the two nodemasks, as a result of the remap, are now disjoint. c0ff7453bb5c ("cpuset,mm: fix no node to alloc memory when changing cpuset's mems") adds get_mems_allowed() to prevent the set of allowed nodes from changing for a thread. This causes any update to a set of allowed nodes to stall until put_mems_allowed() is called. This stall is unncessary, however, if at least one node remains unchanged in the update to the set of allowed nodes. This was addressed by 89e8a244b97e ("cpusets: avoid looping when storing to mems_allowed if one node remains set"), but it's still possible that an empty nodemask may be read from a mempolicy because the old nodemask may be remapped to the new nodemask during rebind. To prevent this, only avoid the stall if there is no mempolicy for the thread being changed. This is a temporary solution until all reads from mempolicy nodemasks can be guaranteed to not be empty without the get_mems_allowed() synchronization. Also moves the check for nodemask intersection inside task_lock() so that tsk->mems_allowed cannot change. This ensures that nothing can set this tsk's mems_allowed out from under us and also protects tsk->mempolicy. Reported-by: Miao Xie Signed-off-by: David Rientjes Cc: KOSAKI Motohiro Cc: Paul Menage Cc: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 9fe58c4..0b1712d 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -123,6 +123,19 @@ static inline struct cpuset *task_cs(struct task_struct *task) struct cpuset, css); } +#ifdef CONFIG_NUMA +static inline bool task_has_mempolicy(struct task_struct *task) +{ + return task->mempolicy; +} +#else +static inline bool task_has_mempolicy(struct task_struct *task) +{ + return false; +} +#endif + + /* bits in struct cpuset flags field */ typedef enum { CS_CPU_EXCLUSIVE, @@ -949,7 +962,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, static void cpuset_change_task_nodemask(struct task_struct *tsk, nodemask_t *newmems) { - bool masks_disjoint = !nodes_intersects(*newmems, tsk->mems_allowed); + bool need_loop; repeat: /* @@ -962,6 +975,14 @@ repeat: return; task_lock(tsk); + /* + * Determine if a loop is necessary if another thread is doing + * get_mems_allowed(). If at least one node remains unchanged and + * tsk does not have a mempolicy, then an empty nodemask will not be + * possible when mems_allowed is larger than a word. + */ + need_loop = task_has_mempolicy(tsk) || + !nodes_intersects(*newmems, tsk->mems_allowed); nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems); mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1); @@ -981,11 +1002,9 @@ repeat: /* * Allocation of memory is very fast, we needn't sleep when waiting - * for the read-side. No wait is necessary, however, if at least one - * node remains unchanged. + * for the read-side. */ - while (masks_disjoint && - ACCESS_ONCE(tsk->mems_allowed_change_disable)) { + while (need_loop && ACCESS_ONCE(tsk->mems_allowed_change_disable)) { task_unlock(tsk); if (!task_curr(tsk)) yield(); -- cgit v0.10.2 From 695c60f21c69e525a89279a5f35bae4ff237afbc Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Mon, 19 Dec 2011 17:11:55 -0800 Subject: nilfs2: unbreak compat ioctl commit 828b1c50ae ("nilfs2: add compat ioctl") incidentally broke all other NILFS compat ioctls. Make them work again. Signed-off-by: Thomas Meyer Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi Cc: [3.0+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 41d6743..3e65427 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -842,6 +842,19 @@ long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case FS_IOC32_GETVERSION: cmd = FS_IOC_GETVERSION; break; + case NILFS_IOCTL_CHANGE_CPMODE: + case NILFS_IOCTL_DELETE_CHECKPOINT: + case NILFS_IOCTL_GET_CPINFO: + case NILFS_IOCTL_GET_CPSTAT: + case NILFS_IOCTL_GET_SUINFO: + case NILFS_IOCTL_GET_SUSTAT: + case NILFS_IOCTL_GET_VINFO: + case NILFS_IOCTL_GET_BDESCS: + case NILFS_IOCTL_CLEAN_SEGMENTS: + case NILFS_IOCTL_SYNC: + case NILFS_IOCTL_RESIZE: + case NILFS_IOCTL_SET_ALLOC_RANGE: + break; default: return -ENOIOCTLCMD; } -- cgit v0.10.2 From 481fe17e973fb97aa3edf17c69557afe88d8334f Mon Sep 17 00:00:00 2001 From: Haogang Chen Date: Mon, 19 Dec 2011 17:11:56 -0800 Subject: nilfs2: potential integer overflow in nilfs_ioctl_clean_segments() There is a potential integer overflow in nilfs_ioctl_clean_segments(). When a large argv[n].v_nmembs is passed from the userspace, the subsequent call to vmalloc() will allocate a buffer smaller than expected, which leads to out-of-bound access in nilfs_ioctl_move_blocks() and lfs_clean_segments(). The following check does not prevent the overflow because nsegs is also controlled by the userspace and could be very large. if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment) goto out_free; This patch clamps argv[n].v_nmembs to UINT_MAX / argv[n].v_size, and returns -EINVAL when overflow. Signed-off-by: Haogang Chen Signed-off-by: Ryusuke Konishi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 3e65427..ac258be 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -625,6 +625,9 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment) goto out_free; + if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size) + goto out_free; + len = argv[n].v_size * argv[n].v_nmembs; base = (void __user *)(unsigned long)argv[n].v_base; if (len == 0) { -- cgit v0.10.2 From a41c58a6665cc995e237303b05db42100b71b65e Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Mon, 19 Dec 2011 17:11:57 -0800 Subject: memcg: keep root group unchanged if creation fails If the request is to create non-root group and we fail to meet it, we should leave the root unchanged. Signed-off-by: Hillf Danton Acked-by: Hugh Dickins Acked-by: KAMEZAWA Hiroyuki Acked-by: Michal Hocko Cc: Balbir Singh Cc: David Rientjes Cc: Andrea Arcangeli Cc: Johannes Weiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 6aff93c..b63f5f7 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4907,9 +4907,9 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) int cpu; enable_swap_cgroup(); parent = NULL; - root_mem_cgroup = memcg; if (mem_cgroup_soft_limit_tree_init()) goto free_out; + root_mem_cgroup = memcg; for_each_possible_cpu(cpu) { struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); @@ -4948,7 +4948,6 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) return &memcg->css; free_out: __mem_cgroup_free(memcg); - root_mem_cgroup = NULL; return ERR_PTR(error); } -- cgit v0.10.2 From ff05b6f7ae762b6eb464183eec994b28ea09f6dd Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 19 Dec 2011 17:11:59 -0800 Subject: oom: fix integer overflow of points in oom_badness An integer overflow will happen on 64bit archs if task's sum of rss, swapents and nr_ptes exceeds (2^31)/1000 value. This was introduced by commit f755a04 oom: use pte pages in OOM score where the oom score computation was divided into several steps and it's no longer computed as one expression in unsigned long(rss, swapents, nr_pte are unsigned long), where the result value assigned to points(int) is in range(1..1000). So there could be an int overflow while computing 176 points *= 1000; and points may have negative value. Meaning the oom score for a mem hog task will be one. 196 if (points <= 0) 197 return 1; For example: [ 3366] 0 3366 35390480 24303939 5 0 0 oom01 Out of memory: Kill process 3366 (oom01) score 1 or sacrifice child Here the oom1 process consumes more than 24303939(rss)*4096~=92GB physical memory, but it's oom score is one. In this situation the mem hog task is skipped and oom killer kills another and most probably innocent task with oom score greater than one. The points variable should be of type long instead of int to prevent the int overflow. Signed-off-by: Frantisek Hrbata Acked-by: KOSAKI Motohiro Acked-by: Oleg Nesterov Acked-by: David Rientjes Cc: [2.6.36+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 76f2c5a..069b64e 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -176,7 +176,7 @@ static bool oom_unkillable_task(struct task_struct *p, unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, const nodemask_t *nodemask, unsigned long totalpages) { - int points; + long points; if (oom_unkillable_task(p, mem, nodemask)) return 0; -- cgit v0.10.2 From b75d91f7ca513f0a4d0d1ad0942fb90cf5a2bc88 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 19 Dec 2011 17:12:02 -0800 Subject: ipmi_watchdog: restore settings when BMC reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the BMC gets reset, it will return 0x80 response errors. In less than a week # grep "Error 80 on cmd 22" /var/log/kernel |wc -l 378681 In this case, it is probably a good idea to restore the IPMI settings. Signed-off-by: Corey Minyard Tested-by: Arkadiusz Miśkiewicz Reported-by: Arkadiusz Miśkiewicz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index c2917ffa..34767a6 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -139,6 +139,8 @@ #define IPMI_WDOG_SET_TIMER 0x24 #define IPMI_WDOG_GET_TIMER 0x25 +#define IPMI_WDOG_TIMER_NOT_INIT_RESP 0x80 + /* These are here until the real ones get into the watchdog.h interface. */ #ifndef WDIOC_GETTIMEOUT #define WDIOC_GETTIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 20, int) @@ -596,6 +598,7 @@ static int ipmi_heartbeat(void) struct kernel_ipmi_msg msg; int rv; struct ipmi_system_interface_addr addr; + int timeout_retries = 0; if (ipmi_ignore_heartbeat) return 0; @@ -616,6 +619,7 @@ static int ipmi_heartbeat(void) mutex_lock(&heartbeat_lock); +restart: atomic_set(&heartbeat_tofree, 2); /* @@ -653,7 +657,33 @@ static int ipmi_heartbeat(void) /* Wait for the heartbeat to be sent. */ wait_for_completion(&heartbeat_wait); - if (heartbeat_recv_msg.msg.data[0] != 0) { + if (heartbeat_recv_msg.msg.data[0] == IPMI_WDOG_TIMER_NOT_INIT_RESP) { + timeout_retries++; + if (timeout_retries > 3) { + printk(KERN_ERR PFX ": Unable to restore the IPMI" + " watchdog's settings, giving up.\n"); + rv = -EIO; + goto out_unlock; + } + + /* + * The timer was not initialized, that means the BMC was + * probably reset and lost the watchdog information. Attempt + * to restore the timer's info. Note that we still hold + * the heartbeat lock, to keep a heartbeat from happening + * in this process, so must say no heartbeat to avoid a + * deadlock on this mutex. + */ + rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); + if (rv) { + printk(KERN_ERR PFX ": Unable to send the command to" + " set the watchdog's settings, giving up.\n"); + goto out_unlock; + } + + /* We might need a new heartbeat, so do it now */ + goto restart; + } else if (heartbeat_recv_msg.msg.data[0] != 0) { /* * Got an error in the heartbeat response. It was already * reported in ipmi_wdog_msg_handler, but we should return @@ -662,6 +692,7 @@ static int ipmi_heartbeat(void) rv = -EINVAL; } +out_unlock: mutex_unlock(&heartbeat_lock); return rv; @@ -922,11 +953,15 @@ static struct miscdevice ipmi_wdog_miscdev = { static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, void *handler_data) { - if (msg->msg.data[0] != 0) { + if (msg->msg.cmd == IPMI_WDOG_RESET_TIMER && + msg->msg.data[0] == IPMI_WDOG_TIMER_NOT_INIT_RESP) + printk(KERN_INFO PFX "response: The IPMI controller appears" + " to have been reset, will attempt to reinitialize" + " the watchdog timer\n"); + else if (msg->msg.data[0] != 0) printk(KERN_ERR PFX "response: Error %x on cmd %x\n", msg->msg.data[0], msg->msg.cmd); - } ipmi_free_recv_msg(msg); } -- cgit v0.10.2 From 0006526d78e93c3684c806bf7cf3f67dfa49c3c8 Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Mon, 19 Dec 2011 17:12:04 -0800 Subject: mm/vmalloc.c: remove static declaration of va from __get_vm_area_node Static storage is not required for the struct vmap_area in __get_vm_area_node. Removing "static" to store this variable on the stack instead. Signed-off-by: Kautuk Consul Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 1d8b32f..27be2f0 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1290,7 +1290,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long align, unsigned long flags, unsigned long start, unsigned long end, int node, gfp_t gfp_mask, void *caller) { - static struct vmap_area *va; + struct vmap_area *va; struct vm_struct *area; BUG_ON(in_interrupt()); -- cgit v0.10.2 From 3d3c8f93a237b64580c5c5e138edeb1377e98230 Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Mon, 19 Dec 2011 17:12:06 -0800 Subject: binary_sysctl(): fix memory leak binary_sysctl() calls sysctl_getname() which allocates from names_cache slab usin __getname() The matching function to free the name is __putname(), and not putname() which should be used only to match getname() allocations. This is because when auditing is enabled, putname() calls audit_putname *instead* (not in addition) to __putname(). Then, if a syscall is in progress, audit_putname does not release the name - instead, it expects the name to get released when the syscall completes, but that will happen only if audit_getname() was called previously, i.e. if the name was allocated with getname() rather than the naked __getname(). So, __getname() followed by putname() ends up leaking memory. Signed-off-by: Michel Lespinasse Acked-by: Al Viro Cc: Christoph Hellwig Cc: Eric Paris Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 6318b51..a650694 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -1354,7 +1354,7 @@ static ssize_t binary_sysctl(const int *name, int nlen, fput(file); out_putname: - putname(pathname); + __putname(pathname); out: return result; } -- cgit v0.10.2 From a76c0adf60f6ca5ff3481992e4ea0383776b24d2 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Mon, 19 Dec 2011 04:11:40 +0000 Subject: sctp: Do not account for sizeof(struct sk_buff) in estimated rwnd When checking whether a DATA chunk fits into the estimated rwnd a full sizeof(struct sk_buff) is added to the needed chunk size. This quickly exhausts the available rwnd space and leads to packets being sent which are much below the PMTU limit. This can lead to much worse performance. The reason for this behaviour was to avoid putting too much memory pressure on the receiver. The concept is not completely irational because a Linux receiver does in fact clone an skb for each DATA chunk delivered. However, Linux also reserves half the available socket buffer space for data structures therefore usage of it is already accounted for. When proposing to change this the last time it was noted that this behaviour was introduced to solve a performance issue caused by rwnd overusage in combination with small DATA chunks. Trying to reproduce this I found that with the sk_buff overhead removed, the performance would improve significantly unless socket buffer limits are increased. The following numbers have been gathered using a patched iperf supporting SCTP over a live 1 Gbit ethernet network. The -l option was used to limit DATA chunk sizes. The numbers listed are based on the average of 3 test runs each. Default values have been used for sk_(r|w)mem. Chunk Size Unpatched No Overhead ------------------------------------- 4 15.2 Kbit [!] 12.2 Mbit [!] 8 35.8 Kbit [!] 26.0 Mbit [!] 16 95.5 Kbit [!] 54.4 Mbit [!] 32 106.7 Mbit 102.3 Mbit 64 189.2 Mbit 188.3 Mbit 128 331.2 Mbit 334.8 Mbit 256 537.7 Mbit 536.0 Mbit 512 766.9 Mbit 766.6 Mbit 1024 810.1 Mbit 808.6 Mbit Signed-off-by: Thomas Graf Signed-off-by: David S. Miller diff --git a/net/sctp/output.c b/net/sctp/output.c index 08b3cea..817174e 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -697,13 +697,7 @@ static void sctp_packet_append_data(struct sctp_packet *packet, /* Keep track of how many bytes are in flight to the receiver. */ asoc->outqueue.outstanding_bytes += datasize; - /* Update our view of the receiver's rwnd. Include sk_buff overhead - * while updating peer.rwnd so that it reduces the chances of a - * receiver running out of receive buffer space even when receive - * window is still open. This can happen when a sender is sending - * sending small messages. - */ - datasize += sizeof(struct sk_buff); + /* Update our view of the receiver's rwnd. */ if (datasize < rwnd) rwnd -= datasize; else diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 14c2b06..cfeb1d4 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -411,8 +411,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, chunk->transport->flight_size -= sctp_data_size(chunk); q->outstanding_bytes -= sctp_data_size(chunk); - q->asoc->peer.rwnd += (sctp_data_size(chunk) + - sizeof(struct sk_buff)); + q->asoc->peer.rwnd += sctp_data_size(chunk); } continue; } @@ -432,8 +431,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, * (Section 7.2.4)), add the data size of those * chunks to the rwnd. */ - q->asoc->peer.rwnd += (sctp_data_size(chunk) + - sizeof(struct sk_buff)); + q->asoc->peer.rwnd += sctp_data_size(chunk); q->outstanding_bytes -= sctp_data_size(chunk); if (chunk->transport) transport->flight_size -= sctp_data_size(chunk); -- cgit v0.10.2 From cd7816d14953c8af910af5bb92f488b0b277e29d Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Mon, 19 Dec 2011 22:58:04 +0000 Subject: net: have ipconfig not wait if no dev is available previous commit 3fb72f1e6e6165c5f495e8dc11c5bbd14c73385c makes IP-Config wait for carrier on at least one network device. Before waiting (predefined value 120s), check that at least one device was successfully brought up. Otherwise (e.g. buggy bootloader which does not set the MAC address) there is no point in waiting for carrier. Cc: Micha Nelissen Cc: Holger Brunck Signed-off-by: Gerlando Falauto Signed-off-by: David S. Miller diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 0da2afc..99ec116 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -253,6 +253,10 @@ static int __init ic_open_devs(void) } } + /* no point in waiting if we could not bring up at least one device */ + if (!ic_first_dev) + goto have_carrier; + /* wait for a carrier on at least one device */ start = jiffies; while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) { -- cgit v0.10.2 From 50345f1ea9cda4618d9c26e590a97ecd4bc7ac75 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 13 Dec 2011 14:49:04 +0000 Subject: SELinux: Fix RCU deref check warning in sel_netport_insert() Fix the following bug in sel_netport_insert() where rcu_dereference() should be rcu_dereference_protected() as sel_netport_lock is held. =================================================== [ INFO: suspicious rcu_dereference_check() usage. ] --------------------------------------------------- security/selinux/netport.c:127 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by ossec-rootcheck/3323: #0: (sel_netport_lock){+.....}, at: [] sel_netport_sid+0xbb/0x226 stack backtrace: Pid: 3323, comm: ossec-rootcheck Not tainted 3.1.0-rc8-fsdevel+ #1095 Call Trace: [] lockdep_rcu_dereference+0xa7/0xb0 [] sel_netport_sid+0x1b7/0x226 [] ? sel_netport_avc_callback+0xbc/0xbc [] selinux_socket_bind+0x115/0x230 [] ? might_fault+0x4e/0x9e [] ? might_fault+0x97/0x9e [] security_socket_bind+0x11/0x13 [] sys_bind+0x56/0x95 [] ? sysret_check+0x27/0x62 [] ? trace_hardirqs_on_caller+0x11e/0x155 [] ? audit_syscall_entry+0x17b/0x1ae [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b Signed-off-by: David Howells Acked-by: Paul Moore Acked-by: Eric Dumazet Cc: stable@kernel.org Signed-off-by: James Morris diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 0b62bd1..7b9eb1f 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c @@ -123,7 +123,9 @@ static void sel_netport_insert(struct sel_netport *port) if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { struct sel_netport *tail; tail = list_entry( - rcu_dereference(sel_netport_hash[idx].list.prev), + rcu_dereference_protected( + sel_netport_hash[idx].list.prev, + lockdep_is_held(&sel_netport_lock)), struct sel_netport, list); list_del_rcu(&tail->list); kfree_rcu(tail, rcu); -- cgit v0.10.2 From 7b21a202b87b7f18587bd15ee6bdb477fed0fb43 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 21 Dec 2011 03:54:24 +0000 Subject: firmware: Refer to the co-maintained linux-firmware.git repository David and I are sharing maintenance of this repository. Patches should be sent to both of us. Signed-off-by: Ben Hutchings Signed-off-by: Linus Torvalds diff --git a/firmware/README.AddingFirmware b/firmware/README.AddingFirmware index e24cd89..ea78c3a 100644 --- a/firmware/README.AddingFirmware +++ b/firmware/README.AddingFirmware @@ -12,7 +12,7 @@ here. This directory is _NOT_ for adding arbitrary new firmware images. The place to add those is the separate linux-firmware repository: - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git + git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git That repository contains all these firmware images which have been extracted from older drivers, as well various new firmware images which @@ -22,6 +22,7 @@ been permitted to redistribute under separate cover. To submit firmware to that repository, please send either a git binary diff or preferably a git pull request to: David Woodhouse + Ben Hutchings Your commit should include an update to the WHENCE file clearly identifying the licence under which the firmware is available, and -- cgit v0.10.2 From 609f6ea1c9cdfe0c43a927e13205a57d0c266d5a Mon Sep 17 00:00:00 2001 From: majianpeng Date: Wed, 21 Dec 2011 15:27:24 +0100 Subject: block: re-use existing 'reading' variable instead of checking direction again Signed-off-by: majianpeng Signed-off-by: Jens Axboe diff --git a/block/blk-map.c b/block/blk-map.c index 164cd00..623e1cd 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -311,7 +311,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, if (IS_ERR(bio)) return PTR_ERR(bio); - if (rq_data_dir(rq) == WRITE) + if (!reading) bio->bi_rw |= REQ_WRITE; if (do_copy) -- cgit v0.10.2 From 9f28a2fc0bd77511f649c0a788c7bf9a5fd04edb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 21 Dec 2011 15:47:16 -0500 Subject: ipv4: reintroduce route cache garbage collector Commit 2c8cec5c10b (ipv4: Cache learned PMTU information in inetpeer) removed IP route cache garbage collector a bit too soon, as this gc was responsible for expired routes cleanup, releasing their neighbour reference. As pointed out by Robert Gladewitz, recent kernels can fill and exhaust their neighbour cache. Reintroduce the garbage collection, since we'll have to wait our neighbour lookups become refcount-less to not depend on this stuff. Reported-by: Robert Gladewitz Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 46af623..252c512 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -120,6 +120,7 @@ static int ip_rt_max_size; static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT; +static int ip_rt_gc_interval __read_mostly = 60 * HZ; static int ip_rt_gc_min_interval __read_mostly = HZ / 2; static int ip_rt_redirect_number __read_mostly = 9; static int ip_rt_redirect_load __read_mostly = HZ / 50; @@ -133,6 +134,9 @@ static int ip_rt_min_advmss __read_mostly = 256; static int rt_chain_length_max __read_mostly = 20; static int redirect_genid; +static struct delayed_work expires_work; +static unsigned long expires_ljiffies; + /* * Interface to generic destination cache. */ @@ -830,6 +834,97 @@ static int has_noalias(const struct rtable *head, const struct rtable *rth) return ONE; } +static void rt_check_expire(void) +{ + static unsigned int rover; + unsigned int i = rover, goal; + struct rtable *rth; + struct rtable __rcu **rthp; + unsigned long samples = 0; + unsigned long sum = 0, sum2 = 0; + unsigned long delta; + u64 mult; + + delta = jiffies - expires_ljiffies; + expires_ljiffies = jiffies; + mult = ((u64)delta) << rt_hash_log; + if (ip_rt_gc_timeout > 1) + do_div(mult, ip_rt_gc_timeout); + goal = (unsigned int)mult; + if (goal > rt_hash_mask) + goal = rt_hash_mask + 1; + for (; goal > 0; goal--) { + unsigned long tmo = ip_rt_gc_timeout; + unsigned long length; + + i = (i + 1) & rt_hash_mask; + rthp = &rt_hash_table[i].chain; + + if (need_resched()) + cond_resched(); + + samples++; + + if (rcu_dereference_raw(*rthp) == NULL) + continue; + length = 0; + spin_lock_bh(rt_hash_lock_addr(i)); + while ((rth = rcu_dereference_protected(*rthp, + lockdep_is_held(rt_hash_lock_addr(i)))) != NULL) { + prefetch(rth->dst.rt_next); + if (rt_is_expired(rth)) { + *rthp = rth->dst.rt_next; + rt_free(rth); + continue; + } + if (rth->dst.expires) { + /* Entry is expired even if it is in use */ + if (time_before_eq(jiffies, rth->dst.expires)) { +nofree: + tmo >>= 1; + rthp = &rth->dst.rt_next; + /* + * We only count entries on + * a chain with equal hash inputs once + * so that entries for different QOS + * levels, and other non-hash input + * attributes don't unfairly skew + * the length computation + */ + length += has_noalias(rt_hash_table[i].chain, rth); + continue; + } + } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) + goto nofree; + + /* Cleanup aged off entries. */ + *rthp = rth->dst.rt_next; + rt_free(rth); + } + spin_unlock_bh(rt_hash_lock_addr(i)); + sum += length; + sum2 += length*length; + } + if (samples) { + unsigned long avg = sum / samples; + unsigned long sd = int_sqrt(sum2 / samples - avg*avg); + rt_chain_length_max = max_t(unsigned long, + ip_rt_gc_elasticity, + (avg + 4*sd) >> FRACT_BITS); + } + rover = i; +} + +/* + * rt_worker_func() is run in process context. + * we call rt_check_expire() to scan part of the hash table + */ +static void rt_worker_func(struct work_struct *work) +{ + rt_check_expire(); + schedule_delayed_work(&expires_work, ip_rt_gc_interval); +} + /* * Perturbation of rt_genid by a small quantity [1..256] * Using 8 bits of shuffling ensure we can call rt_cache_invalidate() @@ -3179,6 +3274,13 @@ static ctl_table ipv4_route_table[] = { .proc_handler = proc_dointvec_jiffies, }, { + .procname = "gc_interval", + .data = &ip_rt_gc_interval, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { .procname = "redirect_load", .data = &ip_rt_redirect_load, .maxlen = sizeof(int), @@ -3388,6 +3490,11 @@ int __init ip_rt_init(void) devinet_init(); ip_fib_init(); + INIT_DELAYED_WORK_DEFERRABLE(&expires_work, rt_worker_func); + expires_ljiffies = jiffies; + schedule_delayed_work(&expires_work, + net_random() % ip_rt_gc_interval + ip_rt_gc_interval); + if (ip_rt_proc_init()) printk(KERN_ERR "Unable to create route proc files\n"); #ifdef CONFIG_XFRM -- cgit v0.10.2 From c0ed1c14a72ca9ebacd51fb94a8aca488b0d361e Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Wed, 21 Dec 2011 16:48:08 -0500 Subject: net: Add a flow_cache_flush_deferred function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit flow_cach_flush() might sleep but can be called from atomic context via the xfrm garbage collector. So add a flow_cache_flush_deferred() function and use this if the xfrm garbage colector is invoked from within the packet path. Signed-off-by: Steffen Klassert Acked-by: Timo Teräs Signed-off-by: David S. Miller diff --git a/include/net/flow.h b/include/net/flow.h index a094477..57f15a7 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -207,6 +207,7 @@ extern struct flow_cache_object *flow_cache_lookup( u8 dir, flow_resolve_t resolver, void *ctx); extern void flow_cache_flush(void); +extern void flow_cache_flush_deferred(void); extern atomic_t flow_cache_genid; #endif diff --git a/net/core/flow.c b/net/core/flow.c index 8ae42de..e318c7e 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -358,6 +358,18 @@ void flow_cache_flush(void) put_online_cpus(); } +static void flow_cache_flush_task(struct work_struct *work) +{ + flow_cache_flush(); +} + +static DECLARE_WORK(flow_cache_flush_work, flow_cache_flush_task); + +void flow_cache_flush_deferred(void) +{ + schedule_work(&flow_cache_flush_work); +} + static int __cpuinit flow_cache_cpu_prepare(struct flow_cache *fc, int cpu) { struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2118d64..9049a5c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2276,8 +2276,6 @@ static void __xfrm_garbage_collect(struct net *net) { struct dst_entry *head, *next; - flow_cache_flush(); - spin_lock_bh(&xfrm_policy_sk_bundle_lock); head = xfrm_policy_sk_bundles; xfrm_policy_sk_bundles = NULL; @@ -2290,6 +2288,18 @@ static void __xfrm_garbage_collect(struct net *net) } } +static void xfrm_garbage_collect(struct net *net) +{ + flow_cache_flush(); + __xfrm_garbage_collect(net); +} + +static void xfrm_garbage_collect_deferred(struct net *net) +{ + flow_cache_flush_deferred(); + __xfrm_garbage_collect(net); +} + static void xfrm_init_pmtu(struct dst_entry *dst) { do { @@ -2422,7 +2432,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) if (likely(dst_ops->neigh_lookup == NULL)) dst_ops->neigh_lookup = xfrm_neigh_lookup; if (likely(afinfo->garbage_collect == NULL)) - afinfo->garbage_collect = __xfrm_garbage_collect; + afinfo->garbage_collect = xfrm_garbage_collect_deferred; xfrm_policy_afinfo[afinfo->family] = afinfo; } write_unlock_bh(&xfrm_policy_afinfo_lock); @@ -2516,7 +2526,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void switch (event) { case NETDEV_DOWN: - __xfrm_garbage_collect(dev_net(dev)); + xfrm_garbage_collect(dev_net(dev)); } return NOTIFY_DONE; } -- cgit v0.10.2 From 0363e3dae1001179c9d26a44391bb8557dc2f240 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 20 Dec 2011 13:27:38 -0800 Subject: arm/at91: fix build of stamp9g20 Fixes build: arch/arm/mach-at91/board-stamp9g20.c:126: error: expected '}' before ';' token Signed-off-by: Olof Johansson Acked-by: Nicolas Ferre diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index e8d3d5b..72eb3b4 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c @@ -123,8 +123,8 @@ static void __init add_device_nand(void) static struct mci_platform_data __initdata mmc_data = { .slot[0] = { .bus_width = 4, - .detect_pin = -1; - .wp_pin = -1; + .detect_pin = -1, + .wp_pin = -1, }, }; #else -- cgit v0.10.2 From abf058e10c2614c36ba217405768e8e74853fc80 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 21 Dec 2011 17:31:54 -0500 Subject: USB: Fix usb/isp1760 build on sparc This commit: commit 8f5d621543cb064d2989fc223d3c2bc61a43981e Author: Joachim Foerster Date: Mon Oct 10 18:06:54 2011 +0200 usb/isp1760: Let OF bindings depend on general CONFIG_OF instead of PPC_OF . To be able to use the driver on other OF-aware architectures, too. And add necessary OF related #includes to fix compilation error. Signed-off-by: Joachim Foerster Signed-off-by: Greg Kroah-Hartman enabled the build on all CONFIG_OF architectures, but it cannot do this. This driver depends upon CONFIG_OF_IRQ but not all CONFIG_OF platforms support that infrastructure, in particular Sparc does not so the build fails. Please push a patch like the following to Linus so that this code only gets built where it actually should. -------------------- usb/isp1760: Add missing CONFIG_OF_IRQ dependency on OF code. Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index a7dc1e1..2ac4ac2 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -18,7 +18,7 @@ #include "isp1760-hcd.h" -#ifdef CONFIG_OF +#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) #include #include #include @@ -31,7 +31,7 @@ #include #endif -#ifdef CONFIG_OF +#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) struct isp1760 { struct usb_hcd *hcd; int rst_gpio; @@ -437,7 +437,7 @@ static int __init isp1760_init(void) ret = platform_driver_register(&isp1760_plat_driver); if (!ret) any_ret = 0; -#ifdef CONFIG_OF +#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) ret = platform_driver_register(&isp1760_of_driver); if (!ret) any_ret = 0; @@ -457,7 +457,7 @@ module_init(isp1760_init); static void __exit isp1760_exit(void) { platform_driver_unregister(&isp1760_plat_driver); -#ifdef CONFIG_OF +#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) platform_driver_unregister(&isp1760_of_driver); #endif #ifdef CONFIG_PCI -- cgit v0.10.2 From e6f67b8c05f5e129e126f4409ddac6f25f58ffcb Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 21 Dec 2011 11:05:48 -0600 Subject: vfs: __read_cache_page should use gfp argument rather than GFP_KERNEL lockdep reports a deadlock in jfs because a special inode's rw semaphore is taken recursively. The mapping's gfp mask is GFP_NOFS, but is not used when __read_cache_page() calls add_to_page_cache_lru(). Signed-off-by: Dave Kleikamp Acked-by: Hugh Dickins Acked-by: Al Viro Cc: stable@kernel.org Signed-off-by: Linus Torvalds diff --git a/mm/filemap.c b/mm/filemap.c index c106d3b..5f0a3c9 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1828,7 +1828,7 @@ repeat: page = __page_cache_alloc(gfp | __GFP_COLD); if (!page) return ERR_PTR(-ENOMEM); - err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); + err = add_to_page_cache_lru(page, mapping, index, gfp); if (unlikely(err)) { page_cache_release(page); if (err == -EEXIST) @@ -1925,10 +1925,7 @@ static struct page *wait_on_page_read(struct page *page) * @gfp: the page allocator flags to use if allocating * * This is the same as "read_mapping_page(mapping, index, NULL)", but with - * any new page allocations done using the specified allocation flags. Note - * that the Radix tree operations will still use GFP_KERNEL, so you can't - * expect to do this atomically or anything like that - but you can pass in - * other page requirements. + * any new page allocations done using the specified allocation flags. * * If the page does not get brought uptodate, return -EIO. */ -- cgit v0.10.2 From e30e2fdfe56288576ee9e04dbb06b4bd5f282203 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Thu, 22 Dec 2011 02:45:29 +0530 Subject: VFS: Fix race between CPU hotplug and lglocks Currently, the *_global_[un]lock_online() routines are not at all synchronized with CPU hotplug. Soft-lockups detected as a consequence of this race was reported earlier at https://lkml.org/lkml/2011/8/24/185. (Thanks to Cong Meng for finding out that the root-cause of this issue is the race condition between br_write_[un]lock() and CPU hotplug, which results in the lock states getting messed up). Fixing this race by just adding {get,put}_online_cpus() at appropriate places in *_global_[un]lock_online() is not a good option, because, then suddenly br_write_[un]lock() would become blocking, whereas they have been kept as non-blocking all this time, and we would want to keep them that way. So, overall, we want to ensure 3 things: 1. br_write_lock() and br_write_unlock() must remain as non-blocking. 2. The corresponding lock and unlock of the per-cpu spinlocks must not happen for different sets of CPUs. 3. Either prevent any new CPU online operation in between this lock-unlock, or ensure that the newly onlined CPU does not proceed with its corresponding per-cpu spinlock unlocked. To achieve all this: (a) We introduce a new spinlock that is taken by the *_global_lock_online() routine and released by the *_global_unlock_online() routine. (b) We register a callback for CPU hotplug notifications, and this callback takes the same spinlock as above. (c) We maintain a bitmap which is close to the cpu_online_mask, and once it is initialized in the lock_init() code, all future updates to it are done in the callback, under the above spinlock. (d) The above bitmap is used (instead of cpu_online_mask) while locking and unlocking the per-cpu locks. The callback takes the spinlock upon the CPU_UP_PREPARE event. So, if the br_write_lock-unlock sequence is in progress, the callback keeps spinning, thus preventing the CPU online operation till the lock-unlock sequence is complete. This takes care of requirement (3). The bitmap that we maintain remains unmodified throughout the lock-unlock sequence, since all updates to it are managed by the callback, which takes the same spinlock as the one taken by the lock code and released only by the unlock routine. Combining this with (d) above, satisfies requirement (2). Overall, since we use a spinlock (mentioned in (a)) to prevent CPU hotplug operations from racing with br_write_lock-unlock, requirement (1) is also taken care of. By the way, it is to be noted that a CPU offline operation can actually run in parallel with our lock-unlock sequence, because our callback doesn't react to notifications earlier than CPU_DEAD (in order to maintain our bitmap properly). And this means, since we use our own bitmap (which is stale, on purpose) during the lock-unlock sequence, we could end up unlocking the per-cpu lock of an offline CPU (because we had locked it earlier, when the CPU was online), in order to satisfy requirement (2). But this is harmless, though it looks a bit awkward. Debugged-by: Cong Meng Signed-off-by: Srivatsa S. Bhat Signed-off-by: Al Viro Cc: stable@vger.kernel.org diff --git a/include/linux/lglock.h b/include/linux/lglock.h index f549056..87f402c 100644 --- a/include/linux/lglock.h +++ b/include/linux/lglock.h @@ -22,6 +22,7 @@ #include #include #include +#include /* can make br locks by using local lock for read side, global lock for write */ #define br_lock_init(name) name##_lock_init() @@ -72,9 +73,31 @@ #define DEFINE_LGLOCK(name) \ \ + DEFINE_SPINLOCK(name##_cpu_lock); \ + cpumask_t name##_cpus __read_mostly; \ DEFINE_PER_CPU(arch_spinlock_t, name##_lock); \ DEFINE_LGLOCK_LOCKDEP(name); \ \ + static int \ + name##_lg_cpu_callback(struct notifier_block *nb, \ + unsigned long action, void *hcpu) \ + { \ + switch (action & ~CPU_TASKS_FROZEN) { \ + case CPU_UP_PREPARE: \ + spin_lock(&name##_cpu_lock); \ + cpu_set((unsigned long)hcpu, name##_cpus); \ + spin_unlock(&name##_cpu_lock); \ + break; \ + case CPU_UP_CANCELED: case CPU_DEAD: \ + spin_lock(&name##_cpu_lock); \ + cpu_clear((unsigned long)hcpu, name##_cpus); \ + spin_unlock(&name##_cpu_lock); \ + } \ + return NOTIFY_OK; \ + } \ + static struct notifier_block name##_lg_cpu_notifier = { \ + .notifier_call = name##_lg_cpu_callback, \ + }; \ void name##_lock_init(void) { \ int i; \ LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \ @@ -83,6 +106,11 @@ lock = &per_cpu(name##_lock, i); \ *lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; \ } \ + register_hotcpu_notifier(&name##_lg_cpu_notifier); \ + get_online_cpus(); \ + for_each_online_cpu(i) \ + cpu_set(i, name##_cpus); \ + put_online_cpus(); \ } \ EXPORT_SYMBOL(name##_lock_init); \ \ @@ -124,9 +152,9 @@ \ void name##_global_lock_online(void) { \ int i; \ - preempt_disable(); \ + spin_lock(&name##_cpu_lock); \ rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ - for_each_online_cpu(i) { \ + for_each_cpu(i, &name##_cpus) { \ arch_spinlock_t *lock; \ lock = &per_cpu(name##_lock, i); \ arch_spin_lock(lock); \ @@ -137,12 +165,12 @@ void name##_global_unlock_online(void) { \ int i; \ rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ - for_each_online_cpu(i) { \ + for_each_cpu(i, &name##_cpus) { \ arch_spinlock_t *lock; \ lock = &per_cpu(name##_lock, i); \ arch_spin_unlock(lock); \ } \ - preempt_enable(); \ + spin_unlock(&name##_cpu_lock); \ } \ EXPORT_SYMBOL(name##_global_unlock_online); \ \ -- cgit v0.10.2 From 77e00f2ea94abee1ad13bdfde19cf7aa25992b0e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 21 Dec 2011 11:58:17 -0500 Subject: drm/radeon/kms: bail on BTC parts if MC ucode is missing We already do this for cayman, need to also do it for BTC parts. The default memory and voltage setup is not adequate for advanced operation. Continuing will result in an unusable display. Signed-off-by: Alex Deucher Cc: stable@kernel.org Cc: Jean Delvare Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 5e00d16..92c9628 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3276,6 +3276,18 @@ int evergreen_init(struct radeon_device *rdev) rdev->accel_working = false; } } + + /* Don't start up if the MC ucode is missing on BTC parts. + * The default clocks and voltages before the MC ucode + * is loaded are not suffient for advanced operations. + */ + if (ASIC_IS_DCE5(rdev)) { + if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { + DRM_ERROR("radeon: MC ucode required for NI+.\n"); + return -EINVAL; + } + } + return 0; } -- cgit v0.10.2 From 8a78389651b3e411ec5a7df61404734f52d6f4eb Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Wed, 21 Dec 2011 05:18:33 -0500 Subject: vmwgfx: fix incorrect VRAM size check in vmw_kms_fb_create() Commit e133e737 didn't correctly fix the integer overflow issue. - unsigned int required_size; + u64 required_size; ... required_size = mode_cmd->pitch * mode_cmd->height; - if (unlikely(required_size > dev_priv->vram_size)) { + if (unlikely(required_size > (u64) dev_priv->vram_size)) { Note that both pitch and height are u32. Their product is still u32 and would overflow before being assigned to required_size. A correct way is to convert pitch and height to u64 before the multiplication. required_size = (u64)mode_cmd->pitch * (u64)mode_cmd->height; This patch calls the existing vmw_kms_validate_mode_vram() for validation. Signed-off-by: Xi Wang Reviewed-and-tested-by: Thomas Hellstrom Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 8aa1dbb..f94b33a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1093,7 +1093,6 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, struct vmw_surface *surface = NULL; struct vmw_dma_buffer *bo = NULL; struct ttm_base_object *user_obj; - u64 required_size; int ret; /** @@ -1102,8 +1101,9 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, * requested framebuffer. */ - required_size = mode_cmd->pitch * mode_cmd->height; - if (unlikely(required_size > (u64) dev_priv->vram_size)) { + if (!vmw_kms_validate_mode_vram(dev_priv, + mode_cmd->pitch, + mode_cmd->height)) { DRM_ERROR("VRAM size is too small for requested mode.\n"); return ERR_PTR(-ENOMEM); } -- cgit v0.10.2 From b9eda06f80b0db61a73bd87c6b0eb67d8aca55ad Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 22 Dec 2011 17:03:29 +1100 Subject: ipv4: using prefetch requires including prefetch.h Signed-off-by: Stephen Rothwell Acked-by: Eric Dumazet Acked-by: David Miller Signed-off-by: Linus Torvalds diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 252c512..85cc053 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 19d40dcabf1cdf84e1a76c147b7177b5a6c21943 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 21 Dec 2011 17:38:10 -0500 Subject: pata_of_platform: Add missing CONFIG_OF_IRQ dependency. Signed-off-by: David S. Miller Signed-off-by: Jeff Garzik diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 6bdedd7..cf047c4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -820,7 +820,7 @@ config PATA_PLATFORM config PATA_OF_PLATFORM tristate "OpenFirmware platform device PATA support" - depends on PATA_PLATFORM && OF + depends on PATA_PLATFORM && OF && OF_IRQ help This option enables support for generic directly connected ATA devices commonly found on embedded systems with OpenFirmware -- cgit v0.10.2 From 7cc8583372a21d98a23b703ad96cab03180b5030 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 22 Dec 2011 13:23:59 -0800 Subject: sparc64: Fix MSIQ HV call ordering in pci_sun4v_msiq_build_irq(). This silently was working for many years and stopped working on Niagara-T3 machines. We need to set the MSIQ to VALID before we can set it's state to IDLE. On Niagara-T3, setting the state to IDLE first was causing HV_EINVAL errors. The hypervisor documentation says, rather ambiguously, that the MSIQ must be "initialized" before one can set the state. I previously understood this to mean merely that a successful setconf() operation has been performed on the MSIQ, which we have done at this point. But it seems to also mean that it has been set VALID too. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index b272cda..af5755d 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -849,10 +849,10 @@ static int pci_sun4v_msiq_build_irq(struct pci_pbm_info *pbm, if (!irq) return -ENOMEM; - if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) - return -EINVAL; if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) return -EINVAL; + if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) + return -EINVAL; return irq; } -- cgit v0.10.2 From 09cd9270ea52e0f9851528e8ed028073f96b3c34 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 23 Dec 2011 09:56:55 +1100 Subject: md/linear: fix hot-add of devices to linear arrays. commit d70ed2e4fafdbef0800e73942482bb075c21578b broke hot-add to a linear array. After that commit, metadata if not written to devices until they have been fully integrated into the array as determined by saved_raid_disk. That patch arranged to clear that field after a recovery completed. However for linear arrays, there is no recovery - the integration is instantaneous. So we need to explicitly clear the saved_raid_disk field. Signed-off-by: NeilBrown diff --git a/drivers/md/linear.c b/drivers/md/linear.c index c3273ef..6274565 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -230,6 +230,7 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev) return -EINVAL; rdev->raid_disk = rdev->saved_raid_disk; + rdev->saved_raid_disk = -1; newconf = linear_conf(mddev,mddev->raid_disks+1); -- cgit v0.10.2 From 30d7a4836847bdb10b32c78a4879d4aebe0f193b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 23 Dec 2011 09:57:00 +1100 Subject: md/raid5: ensure correct assessment of drives during degraded reshape. While reshaping a degraded array (as when reshaping a RAID0 by first converting it to a degraded RAID4) we currently get confused about which devices are in_sync. In most cases we get it right, but in the region that is being reshaped we need to treat non-failed devices as in-sync when we have the data but haven't actually written it out yet. Reported-by: Adam Kwolek Signed-off-by: NeilBrown diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 31670f8..858fdbb 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3065,11 +3065,17 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) } } else if (test_bit(In_sync, &rdev->flags)) set_bit(R5_Insync, &dev->flags); - else { + else if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) /* in sync if before recovery_offset */ - if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) - set_bit(R5_Insync, &dev->flags); - } + set_bit(R5_Insync, &dev->flags); + else if (test_bit(R5_UPTODATE, &dev->flags) && + test_bit(R5_Expanded, &dev->flags)) + /* If we've reshaped into here, we assume it is Insync. + * We will shortly update recovery_offset to make + * it official. + */ + set_bit(R5_Insync, &dev->flags); + if (rdev && test_bit(R5_WriteError, &dev->flags)) { clear_bit(R5_Insync, &dev->flags); if (!test_bit(Faulty, &rdev->flags)) { -- cgit v0.10.2 From 60fc13702a1b35118c1548e9c257fa038cecb658 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 23 Dec 2011 09:57:19 +1100 Subject: md: don't give up looking for spares on first failure-to-add Before performing a recovery we try to remove any spares that might not be working, then add any that might have become relevant. Currently we abort on the first spare that cannot be added. This is a false optimisation. It is conceivable that - depending on rules in the personality - a subsequent spare might be accepted. Also the loop does other things like count the available spares and reset the 'recovery_offset' value. If we abort early these might not happen properly. So remove the early abort. In particular if you have an array what is undergoing recovery and which has extra spares, then the recovery may not restart after as reboot as the could of 'spares' might end up as zero. Reported-by: Anssi Hannula Signed-off-by: NeilBrown diff --git a/drivers/md/md.c b/drivers/md/md.c index ee98173..f47f1f8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7360,8 +7360,7 @@ static int remove_and_add_spares(struct mddev *mddev) spares++; md_new_event(mddev); set_bit(MD_CHANGE_DEVS, &mddev->flags); - } else - break; + } } } } -- cgit v0.10.2 From 961902c0f8240175729274cd14198872f42072b7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 23 Dec 2011 09:57:48 +1100 Subject: md/bitmap: It is OK to clear bits during recovery. commit d0a4bb492772ce5c4bdfba3744a99ed6f6fb238f introduced a regression which is annoying but fairly harmless. When writing to an array that is undergoing recovery (a spare in being integrated into the array), writing to the array will set bits in the bitmap, but they will not be cleared when the write completes. For bits covering areas that have not been recovered yet this is not a problem as the recovery will clear the bits. However bits set in already-recovered region will stay set and never be cleared. This doesn't risk data integrity. The only negatives are: - next time there is a crash, more resyncing than necessary will be done. - the bitmap doesn't look clean, which is confusing. While an array is recovering we don't want to update the 'events_cleared' setting in the bitmap but we do still want to clear bits that have very recently been set - providing they were written to the recovering device. So split those two needs - which previously both depended on 'success' and always clear the bit of the write went to all devices. Signed-off-by: NeilBrown diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index b690711..6d03774 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1393,9 +1393,6 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto atomic_read(&bitmap->behind_writes), bitmap->mddev->bitmap_info.max_write_behind); } - if (bitmap->mddev->degraded) - /* Never clear bits or update events_cleared when degraded */ - success = 0; while (sectors) { sector_t blocks; @@ -1409,7 +1406,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto return; } - if (success && + if (success && !bitmap->mddev->degraded && bitmap->events_cleared < bitmap->mddev->events) { bitmap->events_cleared = bitmap->mddev->events; bitmap->need_sync = 1; -- cgit v0.10.2 From 1fb3726cf33a7402d797231fdba6ba49ed5eba75 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 2 Nov 2011 19:13:25 +0900 Subject: ARM: SAMSUNG: Move timer irq numbers to end of linux irq space The timer irqs statically mapped from linux irq numbers 11 to 15 are moved to the end of the statically mapped linux irq space. The GIC PPI and SPI interrupts are relocated to start from 16 and 32 of the linux irq space. This is a required to add device tree support for GIC and Interrupt combiner for EXYNOS4. A new macro 'IRQ_TIMER_BASE' specifies a platform specific base of the linux virq number for the timer interrupts. For exynos4, this base is set to end of the linux virq space. For the other S5P platforms, the existing base '11' is retained. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S index f5e9fd8..d7dfcd7 100644 --- a/arch/arm/mach-exynos/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos/include/mach/entry-macro.S @@ -72,7 +72,6 @@ cmpcc \irqnr, \irqnr cmpne \irqnr, \tmp cmpcs \irqnr, \irqnr - addne \irqnr, \irqnr, #32 .endm diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h index dfd4b7e..713dd52 100644 --- a/arch/arm/mach-exynos/include/mach/irqs.h +++ b/arch/arm/mach-exynos/include/mach/irqs.h @@ -17,13 +17,13 @@ /* PPI: Private Peripheral Interrupt */ -#define IRQ_PPI(x) S5P_IRQ(x+16) +#define IRQ_PPI(x) (x+16) #define IRQ_MCT_LOCALTIMER IRQ_PPI(12) /* SPI: Shared Peripheral Interrupt */ -#define IRQ_SPI(x) S5P_IRQ(x+32) +#define IRQ_SPI(x) (x+32) #define IRQ_EINT0 IRQ_SPI(16) #define IRQ_EINT1 IRQ_SPI(17) @@ -163,7 +163,9 @@ #define IRQ_GPIO2_NR_GROUPS 9 #define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) +#define IRQ_TIMER_BASE (IRQ_GPIO_END + 64) + /* Set the default NR_IRQS */ -#define NR_IRQS (IRQ_GPIO_END + 64) +#define NR_IRQS (IRQ_TIMER_BASE + IRQ_TIMER_COUNT) #endif /* __ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h index 53982db..5b845e8 100644 --- a/arch/arm/mach-s5p64x0/include/mach/irqs.h +++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h @@ -141,6 +141,8 @@ #define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x)) +#define IRQ_TIMER_BASE (11) + /* Set the default NR_IRQS */ #define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h index d2eb475..2870f12 100644 --- a/arch/arm/mach-s5pc100/include/mach/irqs.h +++ b/arch/arm/mach-s5pc100/include/mach/irqs.h @@ -97,6 +97,8 @@ #define IRQ_SDMFIQ S5P_IRQ_VIC2(31) #define IRQ_VIC_END S5P_IRQ_VIC2(31) +#define IRQ_TIMER_BASE (11) + #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h index 5e0de3a..e777e01 100644 --- a/arch/arm/mach-s5pv210/include/mach/irqs.h +++ b/arch/arm/mach-s5pv210/include/mach/irqs.h @@ -118,6 +118,8 @@ #define IRQ_MDNIE3 S5P_IRQ_VIC3(8) #define IRQ_VIC_END S5P_IRQ_VIC3(31) +#define IRQ_TIMER_BASE (11) + #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) #define S5P_EINT_BASE2 (IRQ_VIC_END + 1) diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h index 08d1a7e..df46b77 100644 --- a/arch/arm/plat-samsung/include/plat/irqs.h +++ b/arch/arm/plat-samsung/include/plat/irqs.h @@ -44,13 +44,14 @@ #define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) #define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) -#define S5P_TIMER_IRQ(x) (11 + (x)) +#define S5P_TIMER_IRQ(x) (IRQ_TIMER_BASE + (x)) #define IRQ_TIMER0 S5P_TIMER_IRQ(0) #define IRQ_TIMER1 S5P_TIMER_IRQ(1) #define IRQ_TIMER2 S5P_TIMER_IRQ(2) #define IRQ_TIMER3 S5P_TIMER_IRQ(3) #define IRQ_TIMER4 S5P_TIMER_IRQ(4) +#define IRQ_TIMER_COUNT (5) #define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ : ((x) - 16 + S5P_EINT_BASE2)) -- cgit v0.10.2 From f983575aa90ceeb2cc7923223882dcf1debf5aa2 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 2 Nov 2011 19:14:37 +0900 Subject: ARM: EXYNOS: Enable conversion of GIC dt irq specifier to linux virq Enable conversion of device tree interrupt specifier to linux virq domain for GIC controller. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/cpu.c b/arch/arm/mach-exynos/cpu.c index 90ec247..0eb7b6a 100644 --- a/arch/arm/mach-exynos/cpu.c +++ b/arch/arm/mach-exynos/cpu.c @@ -10,6 +10,8 @@ #include #include +#include +#include #include #include @@ -218,13 +220,26 @@ static void exynos4_gic_irq_fix_base(struct irq_data *d) (gic_bank_offset * smp_processor_id()); } +#ifdef CONFIG_OF +static const struct of_device_id exynos4_dt_irq_match[] = { + { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, + {}, +}; +#endif + void __init exynos4_init_irq(void) { int irq; gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; - gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); + if (!of_have_populated_dt()) + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); +#ifdef CONFIG_OF + else + of_irq_init(exynos4_dt_irq_match); +#endif + gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; -- cgit v0.10.2 From 659d73ada5d6869dc18838c9125731a750389019 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 7 Nov 2011 01:02:21 +0530 Subject: gpio/samsung: Add device tree support for EXYNOS4 As gpio chips get registered, a device tree node which represents the gpio chip is searched and attached to it. A translate function is also provided to convert the gpio specifier into actual platform settings for pin function selection, pull up/down and driver strength settings. Signed-off-by: Thomas Abraham Acked-by: Grant Likely [kgene.kim@samsung.com: fixed build error] Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt new file mode 100644 index 0000000..8f50fe5 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt @@ -0,0 +1,40 @@ +Samsung Exynos4 GPIO Controller + +Required properties: +- compatible: Compatible property value should be "samsung,exynos4-gpio>". + +- reg: Physical base address of the controller and length of memory mapped + region. + +- #gpio-cells: Should be 4. The syntax of the gpio specifier used by client nodes + should be the following with values derived from the SoC user manual. + <[phandle of the gpio controller node] + [pin number within the gpio controller] + [mux function] + [pull up/down] + [drive strength]> + + Values for gpio specifier: + - Pin number: is a value between 0 to 7. + - Pull Up/Down: 0 - Pull Up/Down Disabled. + 1 - Pull Down Enabled. + 3 - Pull Up Enabled. + - Drive Strength: 0 - 1x, + 1 - 3x, + 2 - 2x, + 3 - 4x + +- gpio-controller: Specifies that the node is a gpio controller. +- #address-cells: should be 1. +- #size-cells: should be 1. + +Example: + + gpa0: gpio-controller@11400000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "samsung,exynos4-gpio"; + reg = <0x11400000 0x20>; + #gpio-cells = <4>; + gpio-controller; + }; diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 8662518..6b4d23f 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include @@ -2374,6 +2377,63 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { #endif }; +#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) +static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags) +{ + const __be32 *gpio = gpio_spec; + const u32 n = be32_to_cpup(gpio); + unsigned int pin = gc->base + be32_to_cpu(gpio[0]); + + if (WARN_ON(gc->of_gpio_n_cells < 4)) + return -EINVAL; + + if (n > gc->ngpio) + return -EINVAL; + + if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1])))) + pr_warn("gpio_xlate: failed to set pin function\n"); + if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2]))) + pr_warn("gpio_xlate: failed to set pin pull up/down\n"); + if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3]))) + pr_warn("gpio_xlate: failed to set pin drive strength\n"); + + return n; +} + +static const struct of_device_id exynos4_gpio_dt_match[] __initdata = { + { .compatible = "samsung,exynos4-gpio", }, + {} +}; + +static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, + u64 base, u64 offset) +{ + struct gpio_chip *gc = &chip->chip; + u64 address; + + if (!of_have_populated_dt()) + return; + + address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset; + gc->of_node = of_find_matching_node_by_address(NULL, + exynos4_gpio_dt_match, address); + if (!gc->of_node) { + pr_info("gpio: device tree node not found for gpio controller" + " with base address %08llx\n", address); + return; + } + gc->of_gpio_n_cells = 4; + gc->of_xlate = exynos4_gpio_xlate; +} +#elif defined(CONFIG_ARCH_EXYNOS4) +static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, + u64 base, u64 offset) +{ + return; +} +#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */ + /* TODO: cleanup soc_is_* */ static __init int samsung_gpiolib_init(void) { @@ -2455,6 +2515,10 @@ static __init int samsung_gpiolib_init(void) chip->config = &exynos4_gpio_cfg; chip->group = group++; } +#ifdef CONFIG_CPU_EXYNOS4210 + exynos4_gpiolib_attach_ofnode(chip, + EXYNOS4_PA_GPIO1, i * 0x20); +#endif } samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1); @@ -2467,6 +2531,10 @@ static __init int samsung_gpiolib_init(void) chip->config = &exynos4_gpio_cfg; chip->group = group++; } +#ifdef CONFIG_CPU_EXYNOS4210 + exynos4_gpiolib_attach_ofnode(chip, + EXYNOS4_PA_GPIO2, i * 0x20); +#endif } samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2); @@ -2479,6 +2547,10 @@ static __init int samsung_gpiolib_init(void) chip->config = &exynos4_gpio_cfg; chip->group = group++; } +#ifdef CONFIG_CPU_EXYNOS4210 + exynos4_gpiolib_attach_ofnode(chip, + EXYNOS4_PA_GPIO3, i * 0x20); +#endif } samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3); -- cgit v0.10.2 From 4d84e970d0faec772a9eaa818feee38aeca121b2 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:47:25 +0200 Subject: serial: samsung: Keep a copy of the location of platform data in driver's private data Add a pointer to the location of the platform data in the driver's private data. When instantiated using device tree, pdev->dev->platform_data does not necessarily point to a valid instance of platform data. The platform data pointer in the driver's private data could be set to pdev->dev->platform_data or platform data instance created from device tree. Cc: Ben Dooks Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index 8b0b888..03b249e 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c @@ -28,9 +28,13 @@ static int s5pv210_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *clk) { - struct s3c2410_uartcfg *cfg = port->dev->platform_data; + struct s3c24xx_uart_port *ourport; + struct s3c2410_uartcfg *cfg; unsigned long ucon = rd_regl(port, S3C2410_UCON); + ourport = container_of(port, struct s3c24xx_uart_port, port); + cfg = ourport->cfg; + if (cfg->flags & NO_NEED_CHECK_CLKSRC) return 0; @@ -51,9 +55,13 @@ static int s5pv210_serial_setsource(struct uart_port *port, static int s5pv210_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *clk) { - struct s3c2410_uartcfg *cfg = port->dev->platform_data; + struct s3c24xx_uart_port *ourport; + struct s3c2410_uartcfg *cfg; u32 ucon = rd_regl(port, S3C2410_UCON); + ourport = container_of(port, struct s3c24xx_uart_port, port); + cfg = ourport->cfg; + clk->divisor = 1; if (cfg->flags & NO_NEED_CHECK_CLKSRC) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index b31f1c3..51cfb9f 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -190,10 +190,13 @@ static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *p static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port) { + struct s3c24xx_uart_port *ourport; + if (port->dev == NULL) return NULL; - return (struct s3c2410_uartcfg *)port->dev->platform_data; + ourport = container_of(port, struct s3c24xx_uart_port, port); + return ourport->cfg; } static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, @@ -1125,7 +1128,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, struct platform_device *platdev) { struct uart_port *port = &ourport->port; - struct s3c2410_uartcfg *cfg; + struct s3c2410_uartcfg *cfg = platdev->dev.platform_data; struct resource *res; int ret; @@ -1134,11 +1137,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, if (platdev == NULL) return -ENODEV; - cfg = s3c24xx_dev_to_cfg(&platdev->dev); - if (port->mapbase != 0) return 0; + /* + * If platform data is supplied, keep a copy of the location of + * platform data in the driver's private data. + */ + if (cfg) + ourport->cfg = cfg; + if (cfg->hwport > CONFIG_SERIAL_SAMSUNG_UARTS) { printk(KERN_ERR "%s: port %d bigger than %d\n", __func__, cfg->hwport, CONFIG_SERIAL_SAMSUNG_UARTS); diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 8e87b78..6c9cb9d 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -48,6 +48,9 @@ struct s3c24xx_uart_port { struct clk *baudclk; struct uart_port port; + /* reference to platform data */ + struct s3c2410_uartcfg *cfg; + #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif @@ -56,7 +59,6 @@ struct s3c24xx_uart_port { /* conversion functions */ #define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev) -#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data) /* register access controls */ -- cgit v0.10.2 From 046c217c65a7670b4ee1aecdb9854284e32b2d6c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:47:40 +0200 Subject: ARM: S3C2440: move handling of fclk/n clock to platform code s3c2440 uses fclk/n (fclk divided by n) clock as one of the possible clocks used to generate the baud rate clock. The divider 'n' in this case can be logically represented outside of the uart controller. This patch creates a new clock by name "fclk_n" for s3c2440 based platforms to represent the fclk/n clock in the platform code. This clock provides a get_rate callback that checks the UCON0/1/2 registers to determine the clock rate. The samsung uart driver would receive the "fclk_n" clock name as one of the possible baud rate clock options and the driver need not determine clock rate of fclk/n. Cc: Ben Dooks Cc: Vasily Khoruzhick Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c index f9e6bda..f85853c 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c2440/clock.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,7 @@ #include #include +#include /* S3C2440 extended clock support */ @@ -108,6 +110,40 @@ static struct clk s3c2440_clk_ac97 = { .ctrlbit = S3C2440_CLKCON_CAMERA, }; +static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) +{ + unsigned long ucon0, ucon1, ucon2, divisor; + + /* the fun of calculating the uart divisors on the s3c2440 */ + ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON); + ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON); + ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON); + + ucon0 &= S3C2440_UCON0_DIVMASK; + ucon1 &= S3C2440_UCON1_DIVMASK; + ucon2 &= S3C2440_UCON2_DIVMASK; + + if (ucon0 != 0) + divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6; + else if (ucon1 != 0) + divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21; + else if (ucon2 != 0) + divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36; + else + /* manual calims 44, seems to be 9 */ + divisor = 9; + + return clk_get_rate(clk->parent) / divisor; +} + +static struct clk s3c2440_clk_fclk_n = { + .name = "fclk_n", + .parent = &clk_f, + .ops = &(struct clk_ops) { + .get_rate = s3c2440_fclk_n_getrate, + }, +}; + static int s3c2440_clk_add(struct sys_device *sysdev) { struct clk *clock_upll; @@ -126,6 +162,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev) s3c2440_clk_cam.parent = clock_h; s3c2440_clk_ac97.parent = clock_p; s3c2440_clk_cam_upll.parent = clock_upll; + s3c24xx_register_clock(&s3c2440_clk_fclk_n); s3c24xx_register_clock(&s3c2440_clk_ac97); s3c24xx_register_clock(&s3c2440_clk_cam); diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index 0d3453b..094c4bf 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -70,8 +70,8 @@ static struct map_desc rx1950_iodesc[] __initdata = { static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = { [0] = { - .name = "fclk", - .divisor = 0x0a, + .name = "fclk_n", + .divisor = 1, .min_baud = 0, .max_baud = 0, }, diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index e19499c..f934f5b 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -70,8 +70,8 @@ static struct map_desc rx3715_iodesc[] __initdata = { static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = { [0] = { - .name = "fclk", - .divisor = 0, + .name = "fclk_n", + .divisor = 1, .min_baud = 0, .max_baud = 0, } diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c index 1d0c324..4498828 100644 --- a/drivers/tty/serial/s3c2440.c +++ b/drivers/tty/serial/s3c2440.c @@ -39,7 +39,7 @@ static int s3c2440_serial_setsource(struct uart_port *port, ucon |= S3C2440_UCON_UCLK; else if (strcmp(clk->name, "pclk") == 0) ucon |= S3C2440_UCON_PCLK; - else if (strcmp(clk->name, "fclk") == 0) + else if (strcmp(clk->name, "fclk_n") == 0) ucon |= S3C2440_UCON_FCLK; else { printk(KERN_ERR "unknown clock source %s\n", clk->name); @@ -55,7 +55,6 @@ static int s3c2440_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *clk) { unsigned long ucon = rd_regl(port, S3C2410_UCON); - unsigned long ucon0, ucon1, ucon2; switch (ucon & S3C2440_UCON_CLKMASK) { case S3C2440_UCON_UCLK: @@ -70,34 +69,8 @@ static int s3c2440_serial_getsource(struct uart_port *port, break; case S3C2440_UCON_FCLK: - /* the fun of calculating the uart divisors on - * the s3c2440 */ - - ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON); - ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON); - ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON); - - printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2); - - ucon0 &= S3C2440_UCON0_DIVMASK; - ucon1 &= S3C2440_UCON1_DIVMASK; - ucon2 &= S3C2440_UCON2_DIVMASK; - - if (ucon0 != 0) { - clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT; - clk->divisor += 6; - } else if (ucon1 != 0) { - clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT; - clk->divisor += 21; - } else if (ucon2 != 0) { - clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT; - clk->divisor += 36; - } else { - /* manual calims 44, seems to be 9 */ - clk->divisor = 9; - } - - clk->name = "fclk"; + clk->divisor = 1; + clk->name = "fclk_n"; break; } diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 51cfb9f..fc242b2 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -649,27 +649,6 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port, if (cfg->clocks_size == 0) clkp = &tmp_clksrc; - /* check to see if we're sourcing fclk, and if so we're - * going to have to update the clock source - */ - - if (strcmp(clkp->name, "fclk") == 0) { - struct s3c24xx_uart_clksrc src; - - s3c24xx_serial_getsource(port, &src); - - /* check that the port already using fclk, and if - * not, then re-select fclk - */ - - if (strcmp(src.name, clkp->name) == 0) { - s3c24xx_serial_setsource(port, clkp); - s3c24xx_serial_getsource(port, &src); - } - - clkp->divisor = src.divisor; - } - s3c24xx_serial_calcbaud(res, port, clkp, baud); best = res; resptr = best + 1; -- cgit v0.10.2 From 5f5a7a5578c5885201cf9c85856f023fe8b81765 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:47:46 +0200 Subject: serial: samsung: switch to clkdev based clock lookup Instead of using clock names supplied in platform data, use a generic clock name 'clk_uart_baud' to look up clocks. The platform code should register clocks with the name 'clk_uart_baud' which can be used by the baud rate generator. The clock lookup and selection of the best clock as baud rate clock is reworked. Platform code can specify the clocks that can be used as source for the baud clock (as supported previously by passing names of clocks). A new member is added to the platform data 'clk_sel' which holds a bit-field value with each bit representing a baud source clock. If a bit at any bit position is set, that clock is looked up to participate in the selection of the baud clock source. Cc: Ben Dooks Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index 7207348..b493d8d 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h @@ -222,6 +222,10 @@ #define S5PV210_UFSTAT_RXSHIFT (0) #define NO_NEED_CHECK_CLKSRC 1 +#define S3C2410_UCON_CLKSEL0 (1 << 0) +#define S3C2410_UCON_CLKSEL1 (1 << 1) +#define S3C2410_UCON_CLKSEL2 (1 << 2) +#define S3C2410_UCON_CLKSEL3 (1 << 3) #ifndef __ASSEMBLY__ @@ -257,6 +261,7 @@ struct s3c2410_uartcfg { unsigned char unused; unsigned short flags; upf_t uart_flags; /* default uart flags */ + unsigned int clk_sel; unsigned int has_fracval; diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index fc242b2..dc5a4ed 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -49,6 +49,7 @@ #include #include +#include #include "samsung.h" @@ -558,133 +559,98 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, * */ +#define MAX_CLK_NAME_LENGTH 15 -#define MAX_CLKS (8) - -static struct s3c24xx_uart_clksrc tmp_clksrc = { - .name = "pclk", - .min_baud = 0, - .max_baud = 0, - .divisor = 1, -}; - -static inline int -s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c) +static inline int s3c24xx_serial_getsource(struct uart_port *port) { struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); + unsigned int ucon; - return (info->get_clksrc)(port, c); -} - -static inline int -s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c) -{ - struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); + if (info->num_clks == 1) + return 0; - return (info->set_clksrc)(port, c); + ucon = rd_regl(port, S3C2410_UCON); + ucon &= info->clksel_mask; + return ucon >> info->clksel_shift; } -struct baud_calc { - struct s3c24xx_uart_clksrc *clksrc; - unsigned int calc; - unsigned int divslot; - unsigned int quot; - struct clk *src; -}; - -static int s3c24xx_serial_calcbaud(struct baud_calc *calc, - struct uart_port *port, - struct s3c24xx_uart_clksrc *clksrc, - unsigned int baud) +static void s3c24xx_serial_setsource(struct uart_port *port, + unsigned int clk_sel) { - struct s3c24xx_uart_port *ourport = to_ourport(port); - unsigned long rate; - - calc->src = clk_get(port->dev, clksrc->name); - if (calc->src == NULL || IS_ERR(calc->src)) - return 0; - - rate = clk_get_rate(calc->src); - rate /= clksrc->divisor; + struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); + unsigned int ucon; - calc->clksrc = clksrc; + if (info->num_clks == 1) + return; - if (ourport->info->has_divslot) { - unsigned long div = rate / baud; - - /* The UDIVSLOT register on the newer UARTs allows us to - * get a divisor adjustment of 1/16th on the baud clock. - * - * We don't keep the UDIVSLOT value (the 16ths we calculated - * by not multiplying the baud by 16) as it is easy enough - * to recalculate. - */ - - calc->quot = div / 16; - calc->calc = rate / div; - } else { - calc->quot = (rate + (8 * baud)) / (16 * baud); - calc->calc = (rate / (calc->quot * 16)); - } + ucon = rd_regl(port, S3C2410_UCON); + if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel) + return; - calc->quot--; - return 1; + ucon &= ~info->clksel_mask; + ucon |= clk_sel << info->clksel_shift; + wr_regl(port, S3C2410_UCON, ucon); } -static unsigned int s3c24xx_serial_getclk(struct uart_port *port, - struct s3c24xx_uart_clksrc **clksrc, - struct clk **clk, - unsigned int baud) +static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, + unsigned int req_baud, struct clk **best_clk, + unsigned int *clk_num) { - struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); - struct s3c24xx_uart_clksrc *clkp; - struct baud_calc res[MAX_CLKS]; - struct baud_calc *resptr, *best, *sptr; - int i; - - clkp = cfg->clocks; - best = NULL; - - if (cfg->clocks_size < 2) { - if (cfg->clocks_size == 0) - clkp = &tmp_clksrc; - - s3c24xx_serial_calcbaud(res, port, clkp, baud); - best = res; - resptr = best + 1; - } else { - resptr = res; - - for (i = 0; i < cfg->clocks_size; i++, clkp++) { - if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud)) - resptr++; + struct s3c24xx_uart_info *info = ourport->info; + struct clk *clk; + unsigned long rate; + unsigned int cnt, baud, quot, clk_sel, best_quot = 0; + char clkname[MAX_CLK_NAME_LENGTH]; + int calc_deviation, deviation = (1 << 30) - 1; + + *best_clk = NULL; + clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : + ourport->info->def_clk_sel; + for (cnt = 0; cnt < info->num_clks; cnt++) { + if (!(clk_sel & (1 << cnt))) + continue; + + sprintf(clkname, "clk_uart_baud%d", cnt); + clk = clk_get(ourport->port.dev, clkname); + if (IS_ERR_OR_NULL(clk)) + continue; + + rate = clk_get_rate(clk); + if (!rate) + continue; + + if (ourport->info->has_divslot) { + unsigned long div = rate / req_baud; + + /* The UDIVSLOT register on the newer UARTs allows us to + * get a divisor adjustment of 1/16th on the baud clock. + * + * We don't keep the UDIVSLOT value (the 16ths we + * calculated by not multiplying the baud by 16) as it + * is easy enough to recalculate. + */ + + quot = div / 16; + baud = rate / div; + } else { + quot = (rate + (8 * req_baud)) / (16 * req_baud); + baud = rate / (quot * 16); } - } - - /* ok, we now need to select the best clock we found */ - - if (!best) { - unsigned int deviation = (1<<30)|((1<<30)-1); - int calc_deviation; + quot--; - for (sptr = res; sptr < resptr; sptr++) { - calc_deviation = baud - sptr->calc; - if (calc_deviation < 0) - calc_deviation = -calc_deviation; + calc_deviation = req_baud - baud; + if (calc_deviation < 0) + calc_deviation = -calc_deviation; - if (calc_deviation < deviation) { - best = sptr; - deviation = calc_deviation; - } + if (calc_deviation < deviation) { + *best_clk = clk; + best_quot = quot; + *clk_num = cnt; + deviation = calc_deviation; } } - /* store results to pass back */ - - *clksrc = best->clksrc; - *clk = best->src; - - return best->quot; + return best_quot; } /* udivslot_table[] @@ -717,10 +683,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, { struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); struct s3c24xx_uart_port *ourport = to_ourport(port); - struct s3c24xx_uart_clksrc *clksrc = NULL; struct clk *clk = NULL; unsigned long flags; - unsigned int baud, quot; + unsigned int baud, quot, clk_sel = 0; unsigned int ulcon; unsigned int umcon; unsigned int udivslot = 0; @@ -736,17 +701,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, */ baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); - + quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) quot = port->custom_divisor; - else - quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud); + if (!clk) + return; /* check to see if we need to change clock source */ - if (ourport->clksrc != clksrc || ourport->baudclk != clk) { - dbg("selecting clock %p\n", clk); - s3c24xx_serial_setsource(port, clksrc); + if (ourport->baudclk != clk) { + s3c24xx_serial_setsource(port, clk_sel); if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { clk_disable(ourport->baudclk); @@ -755,7 +719,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, clk_enable(clk); - ourport->clksrc = clksrc; ourport->baudclk = clk; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; } @@ -1202,7 +1165,7 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, struct uart_port *port = s3c24xx_dev_to_port(dev); struct s3c24xx_uart_port *ourport = to_ourport(port); - return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name); + return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name); } static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); @@ -1382,12 +1345,13 @@ static void __init s3c24xx_serial_get_options(struct uart_port *port, int *baud, int *parity, int *bits) { - struct s3c24xx_uart_clksrc clksrc; struct clk *clk; unsigned int ulcon; unsigned int ucon; unsigned int ubrdiv; unsigned long rate; + unsigned int clk_sel; + char clk_name[MAX_CLK_NAME_LENGTH]; ulcon = rd_regl(port, S3C2410_ULCON); ucon = rd_regl(port, S3C2410_UCON); @@ -1432,11 +1396,12 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, /* now calculate the baud rate */ - s3c24xx_serial_getsource(port, &clksrc); + clk_sel = s3c24xx_serial_getsource(port); + sprintf(clk_name, "clk_uart_baud%d", clk_sel); - clk = clk_get(port->dev, clksrc.name); + clk = clk_get(port->dev, clk_name); if (!IS_ERR(clk) && clk != NULL) - rate = clk_get_rate(clk) / clksrc.divisor; + rate = clk_get_rate(clk); else rate = 1; diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 6c9cb9d..11369f31 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -19,6 +19,10 @@ struct s3c24xx_uart_info { unsigned long tx_fifomask; unsigned long tx_fifoshift; unsigned long tx_fifofull; + unsigned int def_clk_sel; + unsigned long num_clks; + unsigned long clksel_mask; + unsigned long clksel_shift; /* uart port features */ -- cgit v0.10.2 From afba7f91e64025748a2cfec181e5a910fd0dee0e Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:47:51 +0200 Subject: ARM: SAMSUNG: remove struct 's3c24xx_uart_clksrc' and all uses of it With clkdev based clock lookup added to samsung serial driver, the use of 'struct s3c24xx_uart_clksrc' to supply clock names in platform data is removed from all the Samsung platform code. Cc: Ben Dooks Cc: Ramax Lo Cc: Vasily Khoruzhick Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/init.c b/arch/arm/mach-exynos/init.c index a8a83e3..e836c9c 100644 --- a/arch/arm/mach-exynos/init.c +++ b/arch/arm/mach-exynos/init.c @@ -14,15 +14,6 @@ #include #include -static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = { - [0] = { - .name = "uclk1", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - /* uart registration process */ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) { @@ -30,11 +21,7 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) u32 ucnt; for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { - if (!tcfg->clocks) { - tcfg->has_fracval = 1; - tcfg->clocks = exynos4_serial_clocks; - tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks); - } + tcfg->has_fracval = 1; tcfg->flags |= NO_NEED_CHECK_CLKSRC; } diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index a20ae1a..71b9558 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -164,22 +164,6 @@ static struct map_desc bast_iodesc[] __initdata = { #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE -static struct s3c24xx_uart_clksrc bast_serial_clocks[] = { - [0] = { - .name = "uclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - } -}; - - static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { [0] = { .hwport = 0, @@ -187,8 +171,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = bast_serial_clocks, - .clocks_size = ARRAY_SIZE(bast_serial_clocks), }, [1] = { .hwport = 1, @@ -196,8 +178,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = bast_serial_clocks, - .clocks_size = ARRAY_SIZE(bast_serial_clocks), }, /* port 2 is not actually used */ [2] = { @@ -206,8 +186,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = bast_serial_clocks, - .clocks_size = ARRAY_SIZE(bast_serial_clocks), } }; diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index df47e8e..0f0a9a1 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -109,23 +109,6 @@ static struct map_desc vr1000_iodesc[] __initdata = { #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE -/* uart clock source(s) */ - -static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = { - [0] = { - .name = "uclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0. - } -}; - static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { [0] = { .hwport = 0, @@ -133,8 +116,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = vr1000_serial_clocks, - .clocks_size = ARRAY_SIZE(vr1000_serial_clocks), }, [1] = { .hwport = 1, @@ -142,8 +123,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = vr1000_serial_clocks, - .clocks_size = ARRAY_SIZE(vr1000_serial_clocks), }, /* port 2 is not actually used */ [2] = { @@ -152,9 +131,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = vr1000_serial_clocks, - .clocks_size = ARRAY_SIZE(vr1000_serial_clocks), - } }; diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index 74f92fc..d8f36c0 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -96,22 +96,6 @@ static struct map_desc anubis_iodesc[] __initdata = { #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE -static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = { - [0] = { - .name = "uclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - } -}; - - static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { [0] = { .hwport = 0, @@ -119,8 +103,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = anubis_serial_clocks, - .clocks_size = ARRAY_SIZE(anubis_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, }, [1] = { .hwport = 2, @@ -128,8 +111,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = anubis_serial_clocks, - .clocks_size = ARRAY_SIZE(anubis_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, }, }; diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c index 38887ee..aa86ca8 100644 --- a/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/arch/arm/mach-s3c2440/mach-at2440evb.c @@ -57,22 +57,6 @@ static struct map_desc at2440evb_iodesc[] __initdata = { #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) -static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = { - [0] = { - .name = "uclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - } -}; - - static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { [0] = { .hwport = 0, @@ -80,8 +64,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = at2440evb_serial_clocks, - .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, }, [1] = { .hwport = 1, @@ -89,8 +72,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = at2440evb_serial_clocks, - .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, }, }; diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index dc142eb..d7e47b2 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -100,21 +100,6 @@ static struct map_desc osiris_iodesc[] __initdata = { #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE -static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = { - [0] = { - .name = "uclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - } -}; - static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { [0] = { .hwport = 0, @@ -122,8 +107,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = osiris_serial_clocks, - .clocks_size = ARRAY_SIZE(osiris_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, }, [1] = { .hwport = 1, @@ -131,8 +115,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = osiris_serial_clocks, - .clocks_size = ARRAY_SIZE(osiris_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, }, [2] = { .hwport = 2, @@ -140,8 +123,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { .ucon = UCON, .ulcon = ULCON, .ufcon = UFCON, - .clocks = osiris_serial_clocks, - .clocks_size = ARRAY_SIZE(osiris_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2, } }; diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index 094c4bf..4267cd5 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -68,15 +68,6 @@ static struct map_desc rx1950_iodesc[] __initdata = { }; -static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = { - [0] = { - .name = "fclk_n", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { [0] = { .hwport = 0, @@ -84,8 +75,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, - .clocks = rx1950_serial_clocks, - .clocks_size = ARRAY_SIZE(rx1950_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL3, }, [1] = { .hwport = 1, @@ -93,8 +83,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, - .clocks = rx1950_serial_clocks, - .clocks_size = ARRAY_SIZE(rx1950_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL3, }, /* IR port */ [2] = { @@ -103,8 +92,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { .ucon = 0x3c5, .ulcon = 0x43, .ufcon = 0xf1, - .clocks = rx1950_serial_clocks, - .clocks_size = ARRAY_SIZE(rx1950_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL3, }, }; diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index f934f5b..3d5e2e6 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -67,16 +67,6 @@ static struct map_desc rx3715_iodesc[] __initdata = { }, }; - -static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = { - [0] = { - .name = "fclk_n", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - } -}; - static struct s3c2410_uartcfg rx3715_uartcfgs[] = { [0] = { .hwport = 0, @@ -84,8 +74,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x51, - .clocks = rx3715_serial_clocks, - .clocks_size = ARRAY_SIZE(rx3715_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL3, }, [1] = { .hwport = 1, @@ -93,8 +82,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { .ucon = 0x3c5, .ulcon = 0x03, .ufcon = 0x00, - .clocks = rx3715_serial_clocks, - .clocks_size = ARRAY_SIZE(rx3715_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL3, }, /* IR port */ [2] = { @@ -103,8 +91,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = { .ucon = 0x3c5, .ulcon = 0x43, .ufcon = 0x51, - .clocks = rx3715_serial_clocks, - .clocks_size = ARRAY_SIZE(rx3715_serial_clocks), + .clk_sel = S3C2410_UCON_CLKSEL3, } }; diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c index 79833ca..659a66c 100644 --- a/arch/arm/mach-s5p64x0/init.c +++ b/arch/arm/mach-s5p64x0/init.c @@ -23,36 +23,7 @@ #include #include -static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = { - [0] = { - .name = "pclk_low", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "uclk1", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - /* uart registration process */ - -void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - struct s3c2410_uartcfg *tcfg = cfg; - u32 ucnt; - - for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { - if (!tcfg->clocks) { - tcfg->clocks = s5p64x0_serial_clocks; - tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks); - } - } -} - void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) { int uart; @@ -62,12 +33,10 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; } - s5p64x0_common_init_uarts(cfg, no); s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); } void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) { - s5p64x0_common_init_uarts(cfg, no); s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); } diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c index 4865ae2..468a5f8 100644 --- a/arch/arm/mach-s5pv210/init.c +++ b/arch/arm/mach-s5pv210/init.c @@ -18,27 +18,8 @@ #include #include -static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = { - [0] = { - .name = "pclk", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - /* uart registration process */ void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) { - struct s3c2410_uartcfg *tcfg = cfg; - u32 ucnt; - - for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { - if (!tcfg->clocks) { - tcfg->clocks = s5pv210_serial_clocks; - tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks); - } - } - s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); } diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index b493d8d..25f0c36 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h @@ -229,26 +229,6 @@ #ifndef __ASSEMBLY__ -/* struct s3c24xx_uart_clksrc - * - * this structure defines a named clock source that can be used for the - * uart, so that the best clock can be selected for the requested baud - * rate. - * - * min_baud and max_baud define the range of baud-rates this clock is - * acceptable for, if they are both zero, it is assumed any baud rate that - * can be generated from this clock will be used. - * - * divisor gives the divisor from the clock to the one seen by the uart -*/ - -struct s3c24xx_uart_clksrc { - const char *name; - unsigned int divisor; - unsigned int min_baud; - unsigned int max_baud; -}; - /* configuration structure for per-machine configurations for the * serial port * @@ -268,9 +248,6 @@ struct s3c2410_uartcfg { unsigned long ucon; /* value of ucon for port */ unsigned long ulcon; /* value of ulcon for port */ unsigned long ufcon; /* value of ufcon for port */ - - struct s3c24xx_uart_clksrc *clocks; - unsigned int clocks_size; }; /* s3c24xx_uart_devs diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 11369f31..40e9ef1 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -47,7 +47,6 @@ struct s3c24xx_uart_port { unsigned int tx_irq; struct s3c24xx_uart_info *info; - struct s3c24xx_uart_clksrc *clksrc; struct clk *clk; struct clk *baudclk; struct uart_port port; -- cgit v0.10.2 From c3310fbbeb9db6967900ed22eb3d0bd0bb0e892c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:47:57 +0200 Subject: serial: samsung: remove all uses of get_clksrc and set_clksrc With clkdev based clock lookup support, the clock set and get operation using clock names communicated between the samsung uart driver and the SoC specific extension can be removed. In addition to that, for each platform specific extension, add the default clock selection, number of clock options for uart baud generator, clock selection bit mask and shift values which is required by the clkdev support in samsung uart driver. The default clock selection value 'def_clk_sel' specifies the default clock to be used as the source clock for baud rate generator in case the platform code does not specify the same. Cc: Ben Dooks Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/init.c b/arch/arm/mach-exynos/init.c index e836c9c..3c9590b 100644 --- a/arch/arm/mach-exynos/init.c +++ b/arch/arm/mach-exynos/init.c @@ -20,10 +20,8 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) struct s3c2410_uartcfg *tcfg = cfg; u32 ucnt; - for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { + for (ucnt = 0; ucnt < no; ucnt++, tcfg++) tcfg->has_fracval = 1; - tcfg->flags |= NO_NEED_CHECK_CLKSRC; - } s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); } diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index 25f0c36..133fa97 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h @@ -71,6 +71,7 @@ #define S3C2410_LCON_IRM (1<<6) #define S3C2440_UCON_CLKMASK (3<<10) +#define S3C2440_UCON_CLKSHIFT (10) #define S3C2440_UCON_PCLK (0<<10) #define S3C2440_UCON_UCLK (1<<10) #define S3C2440_UCON_PCLK2 (2<<10) @@ -78,6 +79,7 @@ #define S3C2443_UCON_EPLL (3<<10) #define S3C6400_UCON_CLKMASK (3<<10) +#define S3C6400_UCON_CLKSHIFT (10) #define S3C6400_UCON_PCLK (0<<10) #define S3C6400_UCON_PCLK2 (2<<10) #define S3C6400_UCON_UCLK0 (1<<10) @@ -90,11 +92,14 @@ #define S3C2440_UCON_DIVSHIFT (12) #define S3C2412_UCON_CLKMASK (3<<10) +#define S3C2412_UCON_CLKSHIFT (10) #define S3C2412_UCON_UCLK (1<<10) #define S3C2412_UCON_USYSCLK (3<<10) #define S3C2412_UCON_PCLK (0<<10) #define S3C2412_UCON_PCLK2 (2<<10) +#define S3C2410_UCON_CLKMASK (1 << 10) +#define S3C2410_UCON_CLKSHIFT (10) #define S3C2410_UCON_UCLK (1<<10) #define S3C2410_UCON_SBREAK (1<<4) @@ -193,6 +198,7 @@ /* Following are specific to S5PV210 */ #define S5PV210_UCON_CLKMASK (1<<10) +#define S5PV210_UCON_CLKSHIFT (10) #define S5PV210_UCON_PCLK (0<<10) #define S5PV210_UCON_UCLK (1<<10) @@ -221,7 +227,6 @@ #define S5PV210_UFSTAT_RXMASK (255<<0) #define S5PV210_UFSTAT_RXSHIFT (0) -#define NO_NEED_CHECK_CLKSRC 1 #define S3C2410_UCON_CLKSEL0 (1 << 0) #define S3C2410_UCON_CLKSEL1 (1 << 1) #define S3C2410_UCON_CLKSEL2 (1 << 2) diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c index b1d7e7c..e668a9d 100644 --- a/drivers/tty/serial/s3c2410.c +++ b/drivers/tty/serial/s3c2410.c @@ -25,31 +25,6 @@ #include "samsung.h" -static int s3c2410_serial_setsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - if (strcmp(clk->name, "uclk") == 0) - ucon |= S3C2410_UCON_UCLK; - else - ucon &= ~S3C2410_UCON_UCLK; - - wr_regl(port, S3C2410_UCON, ucon); - return 0; -} - -static int s3c2410_serial_getsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - clk->divisor = 1; - clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk"; - - return 0; -} - static int s3c2410_serial_resetport(struct uart_port *port, struct s3c2410_uartcfg *cfg) { @@ -77,8 +52,10 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = { .tx_fifofull = S3C2410_UFSTAT_TXFULL, .tx_fifomask = S3C2410_UFSTAT_TXMASK, .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT, - .get_clksrc = s3c2410_serial_getsource, - .set_clksrc = s3c2410_serial_setsource, + .def_clk_sel = S3C2410_UCON_CLKSEL0, + .num_clks = 2, + .clksel_mask = S3C2410_UCON_CLKMASK, + .clksel_shift = S3C2410_UCON_CLKSHIFT, .reset_port = s3c2410_serial_resetport, }; diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c index 2234bf9..5b85c19 100644 --- a/drivers/tty/serial/s3c2412.c +++ b/drivers/tty/serial/s3c2412.c @@ -25,55 +25,6 @@ #include "samsung.h" -static int s3c2412_serial_setsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - ucon &= ~S3C2412_UCON_CLKMASK; - - if (strcmp(clk->name, "uclk") == 0) - ucon |= S3C2440_UCON_UCLK; - else if (strcmp(clk->name, "pclk") == 0) - ucon |= S3C2440_UCON_PCLK; - else if (strcmp(clk->name, "usysclk") == 0) - ucon |= S3C2412_UCON_USYSCLK; - else { - printk(KERN_ERR "unknown clock source %s\n", clk->name); - return -EINVAL; - } - - wr_regl(port, S3C2410_UCON, ucon); - return 0; -} - - -static int s3c2412_serial_getsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - switch (ucon & S3C2412_UCON_CLKMASK) { - case S3C2412_UCON_UCLK: - clk->divisor = 1; - clk->name = "uclk"; - break; - - case S3C2412_UCON_PCLK: - case S3C2412_UCON_PCLK2: - clk->divisor = 1; - clk->name = "pclk"; - break; - - case S3C2412_UCON_USYSCLK: - clk->divisor = 1; - clk->name = "usysclk"; - break; - } - - return 0; -} - static int s3c2412_serial_resetport(struct uart_port *port, struct s3c2410_uartcfg *cfg) { @@ -108,8 +59,10 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = { .tx_fifofull = S3C2440_UFSTAT_TXFULL, .tx_fifomask = S3C2440_UFSTAT_TXMASK, .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .get_clksrc = s3c2412_serial_getsource, - .set_clksrc = s3c2412_serial_setsource, + .def_clk_sel = S3C2410_UCON_CLKSEL2, + .num_clks = 4, + .clksel_mask = S3C2412_UCON_CLKMASK, + .clksel_shift = S3C2412_UCON_CLKSHIFT, .reset_port = s3c2412_serial_resetport, }; diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c index 4498828..39930f8 100644 --- a/drivers/tty/serial/s3c2440.c +++ b/drivers/tty/serial/s3c2440.c @@ -25,58 +25,6 @@ #include "samsung.h" - -static int s3c2440_serial_setsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - /* todo - proper fclk<>nonfclk switch. */ - - ucon &= ~S3C2440_UCON_CLKMASK; - - if (strcmp(clk->name, "uclk") == 0) - ucon |= S3C2440_UCON_UCLK; - else if (strcmp(clk->name, "pclk") == 0) - ucon |= S3C2440_UCON_PCLK; - else if (strcmp(clk->name, "fclk_n") == 0) - ucon |= S3C2440_UCON_FCLK; - else { - printk(KERN_ERR "unknown clock source %s\n", clk->name); - return -EINVAL; - } - - wr_regl(port, S3C2410_UCON, ucon); - return 0; -} - - -static int s3c2440_serial_getsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - switch (ucon & S3C2440_UCON_CLKMASK) { - case S3C2440_UCON_UCLK: - clk->divisor = 1; - clk->name = "uclk"; - break; - - case S3C2440_UCON_PCLK: - case S3C2440_UCON_PCLK2: - clk->divisor = 1; - clk->name = "pclk"; - break; - - case S3C2440_UCON_FCLK: - clk->divisor = 1; - clk->name = "fclk_n"; - break; - } - - return 0; -} - static int s3c2440_serial_resetport(struct uart_port *port, struct s3c2410_uartcfg *cfg) { @@ -110,8 +58,10 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = { .tx_fifofull = S3C2440_UFSTAT_TXFULL, .tx_fifomask = S3C2440_UFSTAT_TXMASK, .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .get_clksrc = s3c2440_serial_getsource, - .set_clksrc = s3c2440_serial_setsource, + .def_clk_sel = S3C2410_UCON_CLKSEL2, + .num_clks = 4, + .clksel_mask = S3C2440_UCON_CLKMASK, + .clksel_shift = S3C2440_UCON_CLKSHIFT, .reset_port = s3c2440_serial_resetport, }; diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c index e2f6913..c5a6d46 100644 --- a/drivers/tty/serial/s3c6400.c +++ b/drivers/tty/serial/s3c6400.c @@ -26,54 +26,6 @@ #include "samsung.h" -static int s3c6400_serial_setsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - if (strcmp(clk->name, "uclk0") == 0) { - ucon &= ~S3C6400_UCON_CLKMASK; - ucon |= S3C6400_UCON_UCLK0; - } else if (strcmp(clk->name, "uclk1") == 0) - ucon |= S3C6400_UCON_UCLK1; - else if (strcmp(clk->name, "pclk") == 0) { - /* See notes about transitioning from UCLK to PCLK */ - ucon &= ~S3C6400_UCON_UCLK0; - } else { - printk(KERN_ERR "unknown clock source %s\n", clk->name); - return -EINVAL; - } - - wr_regl(port, S3C2410_UCON, ucon); - return 0; -} - - -static int s3c6400_serial_getsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - u32 ucon = rd_regl(port, S3C2410_UCON); - - clk->divisor = 1; - - switch (ucon & S3C6400_UCON_CLKMASK) { - case S3C6400_UCON_UCLK0: - clk->name = "uclk0"; - break; - - case S3C6400_UCON_UCLK1: - clk->name = "uclk1"; - break; - - case S3C6400_UCON_PCLK: - case S3C6400_UCON_PCLK2: - clk->name = "pclk"; - break; - } - - return 0; -} - static int s3c6400_serial_resetport(struct uart_port *port, struct s3c2410_uartcfg *cfg) { @@ -108,8 +60,10 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = { .tx_fifofull = S3C2440_UFSTAT_TXFULL, .tx_fifomask = S3C2440_UFSTAT_TXMASK, .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .get_clksrc = s3c6400_serial_getsource, - .set_clksrc = s3c6400_serial_setsource, + .def_clk_sel = S3C2410_UCON_CLKSEL2, + .num_clks = 4, + .clksel_mask = S3C6400_UCON_CLKMASK, + .clksel_shift = S3C6400_UCON_CLKSHIFT, .reset_port = s3c6400_serial_resetport, }; diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index 03b249e..173df5a 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c @@ -25,60 +25,6 @@ #include #include "samsung.h" -static int s5pv210_serial_setsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - struct s3c24xx_uart_port *ourport; - struct s3c2410_uartcfg *cfg; - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - ourport = container_of(port, struct s3c24xx_uart_port, port); - cfg = ourport->cfg; - - if (cfg->flags & NO_NEED_CHECK_CLKSRC) - return 0; - - if (strcmp(clk->name, "pclk") == 0) - ucon &= ~S5PV210_UCON_CLKMASK; - else if (strcmp(clk->name, "uclk1") == 0) - ucon |= S5PV210_UCON_CLKMASK; - else { - printk(KERN_ERR "unknown clock source %s\n", clk->name); - return -EINVAL; - } - - wr_regl(port, S3C2410_UCON, ucon); - return 0; -} - - -static int s5pv210_serial_getsource(struct uart_port *port, - struct s3c24xx_uart_clksrc *clk) -{ - struct s3c24xx_uart_port *ourport; - struct s3c2410_uartcfg *cfg; - u32 ucon = rd_regl(port, S3C2410_UCON); - - ourport = container_of(port, struct s3c24xx_uart_port, port); - cfg = ourport->cfg; - - clk->divisor = 1; - - if (cfg->flags & NO_NEED_CHECK_CLKSRC) - return 0; - - switch (ucon & S5PV210_UCON_CLKMASK) { - case S5PV210_UCON_PCLK: - clk->name = "pclk"; - break; - case S5PV210_UCON_UCLK: - clk->name = "uclk1"; - break; - } - - return 0; -} - static int s5pv210_serial_resetport(struct uart_port *port, struct s3c2410_uartcfg *cfg) { @@ -109,8 +55,10 @@ static int s5pv210_serial_resetport(struct uart_port *port, .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ - .get_clksrc = s5pv210_serial_getsource, \ - .set_clksrc = s5pv210_serial_setsource, \ + .def_clk_sel = S3C2410_UCON_CLKSEL0, \ + .num_clks = 2, \ + .clksel_mask = S5PV210_UCON_CLKMASK, \ + .clksel_shift = S5PV210_UCON_CLKSHIFT, \ .reset_port = s5pv210_serial_resetport static struct s3c24xx_uart_info s5p_port_fifo256 = { diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 40e9ef1..c9cab2c 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -28,11 +28,6 @@ struct s3c24xx_uart_info { unsigned int has_divslot:1; - /* clock source control */ - - int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk); - int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk); - /* uart controls */ int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *); }; -- cgit v0.10.2 From 0cfb26e1fb9d7afe9c79a40a257808eafb2aff34 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 12:08:42 +0200 Subject: ARM: SAMSUNG: register uart clocks to clock lookup list Samsung uart driver lookups the clock using the connection id 'clk_uart_baud'. The uart clocks for all Samsung platforms are reorganized to register them with the lookup name as required by the uart driver. Cc: Ben Dooks Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index 2894f0a..fe18519 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c @@ -1009,46 +1009,6 @@ static struct clksrc_clk clk_dout_mmc4 = { static struct clksrc_clk clksrcs[] = { { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.0", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 0), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.1", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 4), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.2", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.3", - .enable = exynos4_clksrc_mask_peril0_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &clkset_group, - .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, - .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 }, - }, { .clk = { .name = "sclk_pwm", .enable = exynos4_clksrc_mask_peril0_ctrl, @@ -1237,6 +1197,54 @@ static struct clksrc_clk clksrcs[] = { } }; +static struct clksrc_clk clk_sclk_uart0 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.0", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 0), + }, + .sources = &clkset_group, + .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, + .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_uart1 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.1", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 4), + }, + .sources = &clkset_group, + .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, + .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_uart2 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.2", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &clkset_group, + .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, + .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_uart3 = { + .clk = { + .name = "uclk1", + .devname = "exynos4210-uart.3", + .enable = exynos4_clksrc_mask_peril0_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &clkset_group, + .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, + .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 }, +}; + /* Clock initialization code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -1271,6 +1279,20 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_mfc1, }; +static struct clksrc_clk *clksrc_cdev[] = { + &clk_sclk_uart0, + &clk_sclk_uart1, + &clk_sclk_uart2, + &clk_sclk_uart3, +}; + +static struct clk_lookup exynos4_clk_lookup[] = { + CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk), + CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk), + CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk), + CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk), +}; + static int xtal_rate; static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) @@ -1478,11 +1500,15 @@ void __init exynos4_register_clocks(void) for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) s3c_register_clksrc(sclk_tv[ptr], 1); + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) + s3c_register_clksrc(clksrc_cdev[ptr], 1); + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup)); register_syscore_ops(&exynos4_clock_syscore_ops); s3c24xx_register_clock(&dummy_apb_pclk); diff --git a/arch/arm/mach-exynos/init.c b/arch/arm/mach-exynos/init.c index 3c9590b..5b35978 100644 --- a/arch/arm/mach-exynos/init.c +++ b/arch/arm/mach-exynos/init.c @@ -23,5 +23,5 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) for (ucnt = 0; ucnt < no; ucnt++, tcfg++) tcfg->has_fracval = 1; - s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); + s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no); } diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index 3d7ebc5..af74927 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -123,12 +123,18 @@ static struct clk s3c2410_armclk = { .id = -1, }; +static struct clk_lookup s3c2410_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), +}; + void __init s3c2410_init_clocks(int xtal) { s3c24xx_register_baseclocks(xtal); s3c2410_setup_clocks(); s3c2410_baseclk_add(); s3c24xx_register_clock(&s3c2410_armclk); + clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup)); } struct sysdev_class s3c2410_sysclass = { diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 140711d..cd50291 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c @@ -659,6 +659,12 @@ static struct clk *clks[] __initdata = { &clk_armclk, }; +static struct clk_lookup s3c2412_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk), +}; + int __init s3c2412_baseclk_add(void) { unsigned long clkcon = __raw_readl(S3C2410_CLKCON); @@ -751,6 +757,7 @@ int __init s3c2412_baseclk_add(void) s3c2412_clkcon_enable(clkp, 0); } + clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup)); s3c_pwmclk_init(); return 0; } diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c index f85853c..c9879af 100644 --- a/arch/arm/mach-s3c2440/clock.c +++ b/arch/arm/mach-s3c2440/clock.c @@ -144,6 +144,12 @@ static struct clk s3c2440_clk_fclk_n = { }, }; +static struct clk_lookup s3c2440_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n), +}; + static int s3c2440_clk_add(struct sys_device *sysdev) { struct clk *clock_upll; @@ -167,6 +173,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev) s3c24xx_register_clock(&s3c2440_clk_ac97); s3c24xx_register_clock(&s3c2440_clk_cam); s3c24xx_register_clock(&s3c2440_clk_cam_upll); + clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup)); clk_disable(&s3c2440_clk_ac97); clk_disable(&s3c2440_clk_cam); diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 39c238d..2addd98 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -617,16 +617,6 @@ static struct clksrc_clk clksrcs[] = { .sources = &clkset_uhost, }, { .clk = { - .name = "uclk1", - .ctrlbit = S3C_CLKCON_SCLK_UART, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 }, - .sources = &clkset_uart, - }, { -/* Where does UCLK0 come from? */ - .clk = { .name = "spi-bus", .devname = "s3c64xx-spi.0", .ctrlbit = S3C_CLKCON_SCLK_SPI0, @@ -695,6 +685,18 @@ static struct clksrc_clk clksrcs[] = { }, }; +/* Where does UCLK0 come from? */ +static struct clksrc_clk clk_sclk_uclk = { + .clk = { + .name = "uclk1", + .ctrlbit = S3C_CLKCON_SCLK_UART, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 }, + .sources = &clkset_uart, +}; + /* Clock initialisation code */ static struct clksrc_clk *init_parents[] = { @@ -703,6 +705,15 @@ static struct clksrc_clk *init_parents[] = { &clk_mout_mpll, }; +static struct clksrc_clk *clksrc_cdev[] = { + &clk_sclk_uclk, +}; + +static struct clk_lookup s3c64xx_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), +}; + #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) void __init_or_cpufreq s3c6400_setup_clocks(void) @@ -811,6 +822,8 @@ static struct clk *clks[] __initdata = { void __init s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_divlimit) { + unsigned int cnt; + armclk_mask = armclk_divlimit; s3c24xx_register_baseclocks(xtal); @@ -823,5 +836,9 @@ void __init s3c64xx_register_clocks(unsigned long xtal, s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++) + s3c_register_clksrc(clksrc_cdev[cnt], 1); + clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup)); + s3c_pwmclk_init(); } diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index c54c65d..bfb1917 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -421,15 +421,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, }, { .clk = { - .name = "uclk1", - .ctrlbit = (1 << 5), - .enable = s5p64x0_sclk_ctrl, - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, - .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, - }, { - .clk = { .name = "sclk_spi", .devname = "s3c64xx-spi.0", .ctrlbit = (1 << 20), @@ -487,6 +478,17 @@ static struct clksrc_clk clksrcs[] = { }, }; +static struct clksrc_clk clk_sclk_uclk = { + .clk = { + .name = "uclk1", + .ctrlbit = (1 << 5), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, +}; + /* Clock initialization code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -505,6 +507,15 @@ static struct clk dummy_apb_pclk = { .id = -1, }; +static struct clksrc_clk *clksrc_cdev[] = { + &clk_sclk_uclk, +}; + +static struct clk_lookup s5p6440_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), +}; + void __init_or_cpufreq s5p6440_setup_clocks(void) { struct clk *xtal_clk; @@ -583,9 +594,12 @@ void __init s5p6440_register_clocks(void) s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) + s3c_register_clksrc(clksrc_cdev[ptr], 1); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup)); s3c24xx_register_clock(&dummy_apb_pclk); diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 2d04abf..d132638 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -443,15 +443,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, }, { .clk = { - .name = "uclk1", - .ctrlbit = (1 << 5), - .enable = s5p64x0_sclk_ctrl, - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, - .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, - }, { - .clk = { .name = "sclk_spi", .devname = "s3c64xx-spi.0", .ctrlbit = (1 << 20), @@ -536,6 +527,26 @@ static struct clksrc_clk clksrcs[] = { }, }; +static struct clksrc_clk clk_sclk_uclk = { + .clk = { + .name = "uclk1", + .ctrlbit = (1 << 5), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk *clksrc_cdev[] = { + &clk_sclk_uclk, +}; + +static struct clk_lookup s5p6450_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), +}; + /* Clock initialization code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -634,9 +645,12 @@ void __init s5p6450_register_clocks(void) s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) + s3c_register_clksrc(clksrc_cdev[ptr], 1); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup)); s3c24xx_register_clock(&dummy_apb_pclk); diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 8d47709..9d644ec 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -962,16 +962,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 }, }, { .clk = { - .name = "uclk1", - .ctrlbit = (1 << 3), - .enable = s5pc100_sclk0_ctrl, - - }, - .sources = &clk_src_group2, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, - }, { - .clk = { .name = "sclk_mixer", .ctrlbit = (1 << 6), .enable = s5pc100_sclk0_ctrl, @@ -1098,6 +1088,17 @@ static struct clksrc_clk clksrcs[] = { }, }; +static struct clksrc_clk clk_sclk_uart = { + .clk = { + .name = "uclk1", + .ctrlbit = (1 << 3), + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clk_src_group2, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, +}; + /* Clock initialisation code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -1127,6 +1128,10 @@ static struct clksrc_clk *sysclks[] = { &clk_sclk_spdif, }; +static struct clksrc_clk *clksrc_cdev[] = { + &clk_sclk_uart, +}; + void __init_or_cpufreq s5pc100_setup_clocks(void) { unsigned long xtal; @@ -1266,6 +1271,11 @@ static struct clk *clks[] __initdata = { &clk_pcmcdclk1, }; +static struct clk_lookup s5pc100_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk), +}; + void __init s5pc100_register_clocks(void) { int ptr; @@ -1277,9 +1287,12 @@ void __init s5pc100_register_clocks(void) s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) + s3c_register_clksrc(clksrc_cdev[ptr], 1); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup)); s3c24xx_register_clock(&dummy_apb_pclk); diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 4c5ac7a..43a045d 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -809,46 +809,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 }, }, { .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.0", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 12), - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.1", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 13), - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.2", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 14), - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .devname = "s5pv210-uart.3", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 15), - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, - }, { - .clk = { .name = "sclk_fimc", .devname = "s5pv210-fimc.0", .enable = s5pv210_clk_mask1_ctrl, @@ -1022,6 +982,61 @@ static struct clksrc_clk clksrcs[] = { }, }; +static struct clksrc_clk clk_sclk_uart0 = { + .clk = { + .name = "uclk1", + .devname = "s5pv210-uart.0", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 12), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_uart1 = { + .clk = { + .name = "uclk1", + .devname = "s5pv210-uart.1", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 13), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_uart2 = { + .clk = { + .name = "uclk1", + .devname = "s5pv210-uart.2", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 14), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_uart3 = { + .clk = { + .name = "uclk1", + .devname = "s5pv210-uart.3", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 15), + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, +}; + +static struct clksrc_clk *clksrc_cdev[] = { + &clk_sclk_uart0, + &clk_sclk_uart1, + &clk_sclk_uart2, + &clk_sclk_uart3, +}; + /* Clock initialisation code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -1261,6 +1276,14 @@ static struct clk *clks[] __initdata = { &clk_pcmcdclk2, }; +static struct clk_lookup s5pv210_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p), + CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk), + CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk), + CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk), + CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk), +}; + void __init s5pv210_register_clocks(void) { int ptr; @@ -1273,11 +1296,15 @@ void __init s5pv210_register_clocks(void) for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) s3c_register_clksrc(sclk_tv[ptr], 1); + for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++) + s3c_register_clksrc(clksrc_cdev[ptr], 1); + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup)); s3c24xx_register_clock(&dummy_apb_pclk); s3c_pwmclk_init(); diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index 5a21b15..4eab2cc 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c @@ -297,13 +297,6 @@ static struct clksrc_clk clk_usb_bus_host = { static struct clksrc_clk clksrc_clks[] = { { - /* ART baud-rate clock sourced from esysclk via a divisor */ - .clk = { - .name = "uartclk", - .parent = &clk_esysclk.clk, - }, - .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, - }, { /* camera interface bus-clock, divided down from esysclk */ .clk = { .name = "camif-upll", /* same as 2440 name */ @@ -323,6 +316,15 @@ static struct clksrc_clk clksrc_clks[] = { }, }; +static struct clksrc_clk clk_esys_uart = { + /* ART baud-rate clock sourced from esysclk via a divisor */ + .clk = { + .name = "uartclk", + .parent = &clk_esysclk.clk, + }, + .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 }, +}; + static struct clk clk_i2s_ext = { .name = "i2s-ext", }; @@ -589,6 +591,12 @@ static struct clksrc_clk *clksrcs[] __initdata = { &clk_arm, }; +static struct clk_lookup s3c2443_clk_lookup[] = { + CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), + CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), + CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk), +}; + void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, unsigned int *divs, int nr_divs, int divmask) @@ -618,6 +626,7 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, /* See s3c2443/etc notes on disabling clocks at init time */ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup)); s3c2443_common_setup_clocks(get_mpll); } -- cgit v0.10.2 From 0dfb3b41be4ca3c9d1688f6c2d00bfa178356494 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:48:21 +0200 Subject: serial: samsung: merge all SoC specific port reset functions The port reset function in each of the platform specific extension performs the same operations and hence all the reset port functions can be merged into one and moved into the common samsung uart driver. The SoC specific port reset functions are removed from SoC extensions. Cc: Ben Dooks Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c index e668a9d..1491c32 100644 --- a/drivers/tty/serial/s3c2410.c +++ b/drivers/tty/serial/s3c2410.c @@ -25,23 +25,6 @@ #include "samsung.h" -static int s3c2410_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) -{ - dbg("s3c2410_serial_resetport: port=%p (%08lx), cfg=%p\n", - port, port->mapbase, cfg); - - wr_regl(port, S3C2410_UCON, cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); - - /* reset both fifos */ - - wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); - wr_regl(port, S3C2410_UFCON, cfg->ufcon); - - return 0; -} - static struct s3c24xx_uart_info s3c2410_uart_inf = { .name = "Samsung S3C2410 UART", .type = PORT_S3C2410, @@ -56,7 +39,6 @@ static struct s3c24xx_uart_info s3c2410_uart_inf = { .num_clks = 2, .clksel_mask = S3C2410_UCON_CLKMASK, .clksel_shift = S3C2410_UCON_CLKSHIFT, - .reset_port = s3c2410_serial_resetport, }; static int s3c2410_serial_probe(struct platform_device *dev) diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c index 5b85c19..38ae730 100644 --- a/drivers/tty/serial/s3c2412.c +++ b/drivers/tty/serial/s3c2412.c @@ -25,29 +25,6 @@ #include "samsung.h" -static int s3c2412_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - dbg("%s: port=%p (%08lx), cfg=%p\n", - __func__, port, port->mapbase, cfg); - - /* ensure we don't change the clock settings... */ - - ucon &= S3C2412_UCON_CLKMASK; - - wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); - - /* reset both fifos */ - - wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); - wr_regl(port, S3C2410_UFCON, cfg->ufcon); - - return 0; -} - static struct s3c24xx_uart_info s3c2412_uart_inf = { .name = "Samsung S3C2412 UART", .type = PORT_S3C2412, @@ -63,7 +40,6 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = { .num_clks = 4, .clksel_mask = S3C2412_UCON_CLKMASK, .clksel_shift = S3C2412_UCON_CLKSHIFT, - .reset_port = s3c2412_serial_resetport, }; /* device management */ diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c index 39930f8..70652f5 100644 --- a/drivers/tty/serial/s3c2440.c +++ b/drivers/tty/serial/s3c2440.c @@ -25,29 +25,6 @@ #include "samsung.h" -static int s3c2440_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n", - port, port->mapbase, cfg); - - /* ensure we don't change the clock settings... */ - - ucon &= (S3C2440_UCON0_DIVMASK | (3<<10)); - - wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); - - /* reset both fifos */ - - wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); - wr_regl(port, S3C2410_UFCON, cfg->ufcon); - - return 0; -} - static struct s3c24xx_uart_info s3c2440_uart_inf = { .name = "Samsung S3C2440 UART", .type = PORT_S3C2440, @@ -62,7 +39,6 @@ static struct s3c24xx_uart_info s3c2440_uart_inf = { .num_clks = 4, .clksel_mask = S3C2440_UCON_CLKMASK, .clksel_shift = S3C2440_UCON_CLKSHIFT, - .reset_port = s3c2440_serial_resetport, }; /* device management */ diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c index c5a6d46..30a69f1 100644 --- a/drivers/tty/serial/s3c6400.c +++ b/drivers/tty/serial/s3c6400.c @@ -26,29 +26,6 @@ #include "samsung.h" -static int s3c6400_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - dbg("s3c6400_serial_resetport: port=%p (%08lx), cfg=%p\n", - port, port->mapbase, cfg); - - /* ensure we don't change the clock settings... */ - - ucon &= S3C6400_UCON_CLKMASK; - - wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); - - /* reset both fifos */ - - wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); - wr_regl(port, S3C2410_UFCON, cfg->ufcon); - - return 0; -} - static struct s3c24xx_uart_info s3c6400_uart_inf = { .name = "Samsung S3C6400 UART", .type = PORT_S3C6400, @@ -64,7 +41,6 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = { .num_clks = 4, .clksel_mask = S3C6400_UCON_CLKMASK, .clksel_shift = S3C6400_UCON_CLKSHIFT, - .reset_port = s3c6400_serial_resetport, }; /* device management */ diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index 173df5a..d232094 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c @@ -25,25 +25,6 @@ #include #include "samsung.h" -static int s5pv210_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) -{ - unsigned long ucon = rd_regl(port, S3C2410_UCON); - - ucon &= S5PV210_UCON_CLKMASK; - wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); - - /* reset both fifos */ - wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); - wr_regl(port, S3C2410_UFCON, cfg->ufcon); - - /* It is need to delay When reset FIFO register */ - udelay(1); - - return 0; -} - #define S5PV210_UART_DEFAULT_INFO(fifo_size) \ .name = "Samsung S5PV210 UART0", \ .type = PORT_S3C6400, \ @@ -58,8 +39,7 @@ static int s5pv210_serial_resetport(struct uart_port *port, .def_clk_sel = S3C2410_UCON_CLKSEL0, \ .num_clks = 2, \ .clksel_mask = S5PV210_UCON_CLKMASK, \ - .clksel_shift = S5PV210_UCON_CLKSHIFT, \ - .reset_port = s5pv210_serial_resetport + .clksel_shift = S5PV210_UCON_CLKSHIFT static struct s3c24xx_uart_info s5p_port_fifo256 = { S5PV210_UART_DEFAULT_INFO(256), diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index dc5a4ed..78aea1a 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -965,16 +965,29 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS /* s3c24xx_serial_resetport * - * wrapper to call the specific reset for this port (reset the fifos - * and the settings) + * reset the fifos and other the settings. */ -static inline int s3c24xx_serial_resetport(struct uart_port *port, - struct s3c2410_uartcfg *cfg) +static void s3c24xx_serial_resetport(struct uart_port *port, + struct s3c2410_uartcfg *cfg) { struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); + unsigned long ucon = rd_regl(port, S3C2410_UCON); + unsigned int ucon_mask; - return (info->reset_port)(port, cfg); + ucon_mask = info->clksel_mask; + if (info->type == PORT_S3C2440) + ucon_mask |= S3C2440_UCON0_DIVMASK; + + ucon &= ucon_mask; + wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); + + /* reset both fifos */ + wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); + wr_regl(port, S3C2410_UFCON, cfg->ufcon); + + /* some delay is required after fifo reset */ + udelay(1); } -- cgit v0.10.2 From da121506eb03ee5daea55404709110b798bd61d9 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 2 Nov 2011 19:23:25 +0900 Subject: serial: samsung: merge probe() function from all SoC specific extensions With reset port, set clock and get clock functions in SoC specific extentions being removed, only the driver probe is left over in these extensions. The probe function itself can be merged into one and moved into the samsung common serial driver. With driver probe also moved, all the SoC specific extentions are no longer required and they are deleted. Cc: Ben Dooks Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index 133fa97..29c26a8 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h @@ -232,6 +232,18 @@ #define S3C2410_UCON_CLKSEL2 (1 << 2) #define S3C2410_UCON_CLKSEL3 (1 << 3) +/* Default values for s5pv210 UCON and UFCON uart registers */ +#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI | \ + S3C2443_UCON_RXERR_IRQEN) + +#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S5PV210_UFCON_TXTRIG4 | \ + S5PV210_UFCON_RXTRIG4) + #ifndef __ASSEMBLY__ /* configuration structure for per-machine configurations for the diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 925a1e5..fb89b85 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -457,7 +457,7 @@ config SERIAL_SAMSUNG config SERIAL_SAMSUNG_UARTS_4 bool depends on ARM && PLAT_SAMSUNG - default y if CPU_S3C2443 + default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) help Internal node for the common case of 4 Samsung compatible UARTs @@ -465,7 +465,7 @@ config SERIAL_SAMSUNG_UARTS int depends on ARM && PLAT_SAMSUNG default 6 if ARCH_S5P6450 - default 4 if SERIAL_SAMSUNG_UARTS_4 + default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 default 3 help Select the number of available UART ports for the Samsung S3C @@ -495,47 +495,6 @@ config SERIAL_SAMSUNG_CONSOLE your boot loader about how to pass options to the kernel at boot time.) -config SERIAL_S3C2410 - tristate "Samsung S3C2410 Serial port support" - depends on SERIAL_SAMSUNG && CPU_S3C2410 - default y if CPU_S3C2410 - help - Serial port support for the Samsung S3C2410 SoC - -config SERIAL_S3C2412 - tristate "Samsung S3C2412/S3C2413 Serial port support" - depends on SERIAL_SAMSUNG && CPU_S3C2412 - default y if CPU_S3C2412 - help - Serial port support for the Samsung S3C2412 and S3C2413 SoC - -config SERIAL_S3C2440 - tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416) - default y if CPU_S3C2440 - default y if CPU_S3C2442 - select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416 - help - Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC - -config SERIAL_S3C6400 - tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100) - select SERIAL_SAMSUNG_UARTS_4 - default y - help - Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450 - and S5PC100 SoCs - -config SERIAL_S5PV210 - tristate "Samsung S5PV210 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212) - select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212) - default y - help - Serial port support for Samsung's S5P Family of SoC's - - config SERIAL_MAX3100 tristate "MAX3100 support" depends on SPI diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index e10cf5b..84bc2e5 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -39,11 +39,6 @@ obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o -obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o -obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o -obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o -obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o -obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3107) += max3107.o obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c deleted file mode 100644 index 1491c32..0000000 --- a/drivers/tty/serial/s3c2410.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Driver for Samsung S3C2410 SoC onboard UARTs. - * - * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "samsung.h" - -static struct s3c24xx_uart_info s3c2410_uart_inf = { - .name = "Samsung S3C2410 UART", - .type = PORT_S3C2410, - .fifosize = 16, - .rx_fifomask = S3C2410_UFSTAT_RXMASK, - .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT, - .rx_fifofull = S3C2410_UFSTAT_RXFULL, - .tx_fifofull = S3C2410_UFSTAT_TXFULL, - .tx_fifomask = S3C2410_UFSTAT_TXMASK, - .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT, - .def_clk_sel = S3C2410_UCON_CLKSEL0, - .num_clks = 2, - .clksel_mask = S3C2410_UCON_CLKMASK, - .clksel_shift = S3C2410_UCON_CLKSHIFT, -}; - -static int s3c2410_serial_probe(struct platform_device *dev) -{ - return s3c24xx_serial_probe(dev, &s3c2410_uart_inf); -} - -static struct platform_driver s3c2410_serial_driver = { - .probe = s3c2410_serial_probe, - .remove = __devexit_p(s3c24xx_serial_remove), - .driver = { - .name = "s3c2410-uart", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c2410_serial_init(void) -{ - return s3c24xx_serial_init(&s3c2410_serial_driver, &s3c2410_uart_inf); -} - -static void __exit s3c2410_serial_exit(void) -{ - platform_driver_unregister(&s3c2410_serial_driver); -} - -module_init(s3c2410_serial_init); -module_exit(s3c2410_serial_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("Samsung S3C2410 SoC Serial port driver"); -MODULE_ALIAS("platform:s3c2410-uart"); diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c deleted file mode 100644 index 38ae730..0000000 --- a/drivers/tty/serial/s3c2412.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs. - * - * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "samsung.h" - -static struct s3c24xx_uart_info s3c2412_uart_inf = { - .name = "Samsung S3C2412 UART", - .type = PORT_S3C2412, - .fifosize = 64, - .has_divslot = 1, - .rx_fifomask = S3C2440_UFSTAT_RXMASK, - .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, - .rx_fifofull = S3C2440_UFSTAT_RXFULL, - .tx_fifofull = S3C2440_UFSTAT_TXFULL, - .tx_fifomask = S3C2440_UFSTAT_TXMASK, - .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .def_clk_sel = S3C2410_UCON_CLKSEL2, - .num_clks = 4, - .clksel_mask = S3C2412_UCON_CLKMASK, - .clksel_shift = S3C2412_UCON_CLKSHIFT, -}; - -/* device management */ - -static int s3c2412_serial_probe(struct platform_device *dev) -{ - dbg("s3c2440_serial_probe: dev=%p\n", dev); - return s3c24xx_serial_probe(dev, &s3c2412_uart_inf); -} - -static struct platform_driver s3c2412_serial_driver = { - .probe = s3c2412_serial_probe, - .remove = __devexit_p(s3c24xx_serial_remove), - .driver = { - .name = "s3c2412-uart", - .owner = THIS_MODULE, - }, -}; - -static inline int s3c2412_serial_init(void) -{ - return s3c24xx_serial_init(&s3c2412_serial_driver, &s3c2412_uart_inf); -} - -static inline void s3c2412_serial_exit(void) -{ - platform_driver_unregister(&s3c2412_serial_driver); -} - -module_init(s3c2412_serial_init); -module_exit(s3c2412_serial_exit); - -MODULE_DESCRIPTION("Samsung S3C2412,S3C2413 SoC Serial port driver"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:s3c2412-uart"); diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c deleted file mode 100644 index 70652f5..0000000 --- a/drivers/tty/serial/s3c2440.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs. - * - * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "samsung.h" - -static struct s3c24xx_uart_info s3c2440_uart_inf = { - .name = "Samsung S3C2440 UART", - .type = PORT_S3C2440, - .fifosize = 64, - .rx_fifomask = S3C2440_UFSTAT_RXMASK, - .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, - .rx_fifofull = S3C2440_UFSTAT_RXFULL, - .tx_fifofull = S3C2440_UFSTAT_TXFULL, - .tx_fifomask = S3C2440_UFSTAT_TXMASK, - .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .def_clk_sel = S3C2410_UCON_CLKSEL2, - .num_clks = 4, - .clksel_mask = S3C2440_UCON_CLKMASK, - .clksel_shift = S3C2440_UCON_CLKSHIFT, -}; - -/* device management */ - -static int s3c2440_serial_probe(struct platform_device *dev) -{ - dbg("s3c2440_serial_probe: dev=%p\n", dev); - return s3c24xx_serial_probe(dev, &s3c2440_uart_inf); -} - -static struct platform_driver s3c2440_serial_driver = { - .probe = s3c2440_serial_probe, - .remove = __devexit_p(s3c24xx_serial_remove), - .driver = { - .name = "s3c2440-uart", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c2440_serial_init(void) -{ - return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf); -} - -static void __exit s3c2440_serial_exit(void) -{ - platform_driver_unregister(&s3c2440_serial_driver); -} - -module_init(s3c2440_serial_init); -module_exit(s3c2440_serial_exit); - -MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:s3c2440-uart"); diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c deleted file mode 100644 index 30a69f1..0000000 --- a/drivers/tty/serial/s3c6400.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs. - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "samsung.h" - -static struct s3c24xx_uart_info s3c6400_uart_inf = { - .name = "Samsung S3C6400 UART", - .type = PORT_S3C6400, - .fifosize = 64, - .has_divslot = 1, - .rx_fifomask = S3C2440_UFSTAT_RXMASK, - .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, - .rx_fifofull = S3C2440_UFSTAT_RXFULL, - .tx_fifofull = S3C2440_UFSTAT_TXFULL, - .tx_fifomask = S3C2440_UFSTAT_TXMASK, - .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, - .def_clk_sel = S3C2410_UCON_CLKSEL2, - .num_clks = 4, - .clksel_mask = S3C6400_UCON_CLKMASK, - .clksel_shift = S3C6400_UCON_CLKSHIFT, -}; - -/* device management */ - -static int s3c6400_serial_probe(struct platform_device *dev) -{ - dbg("s3c6400_serial_probe: dev=%p\n", dev); - return s3c24xx_serial_probe(dev, &s3c6400_uart_inf); -} - -static struct platform_driver s3c6400_serial_driver = { - .probe = s3c6400_serial_probe, - .remove = __devexit_p(s3c24xx_serial_remove), - .driver = { - .name = "s3c6400-uart", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c6400_serial_init(void) -{ - return s3c24xx_serial_init(&s3c6400_serial_driver, &s3c6400_uart_inf); -} - -static void __exit s3c6400_serial_exit(void) -{ - platform_driver_unregister(&s3c6400_serial_driver); -} - -module_init(s3c6400_serial_init); -module_exit(s3c6400_serial_exit); - -MODULE_DESCRIPTION("Samsung S3C6400,S3C6410 SoC Serial port driver"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:s3c6400-uart"); diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c deleted file mode 100644 index d232094..0000000 --- a/drivers/tty/serial/s5pv210.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Based on drivers/serial/s3c6400.c - * - * Driver for Samsung S5PV210 SoC UARTs. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "samsung.h" - -#define S5PV210_UART_DEFAULT_INFO(fifo_size) \ - .name = "Samsung S5PV210 UART0", \ - .type = PORT_S3C6400, \ - .fifosize = fifo_size, \ - .has_divslot = 1, \ - .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ - .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ - .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ - .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ - .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ - .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ - .def_clk_sel = S3C2410_UCON_CLKSEL0, \ - .num_clks = 2, \ - .clksel_mask = S5PV210_UCON_CLKMASK, \ - .clksel_shift = S5PV210_UCON_CLKSHIFT - -static struct s3c24xx_uart_info s5p_port_fifo256 = { - S5PV210_UART_DEFAULT_INFO(256), -}; - -static struct s3c24xx_uart_info s5p_port_fifo64 = { - S5PV210_UART_DEFAULT_INFO(64), -}; - -static struct s3c24xx_uart_info s5p_port_fifo16 = { - S5PV210_UART_DEFAULT_INFO(16), -}; - -static struct s3c24xx_uart_info *s5p_uart_inf[] = { - [0] = &s5p_port_fifo256, - [1] = &s5p_port_fifo64, - [2] = &s5p_port_fifo16, - [3] = &s5p_port_fifo16, -}; - -/* device management */ -static int s5p_serial_probe(struct platform_device *pdev) -{ - return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); -} - -static struct platform_driver s5p_serial_driver = { - .probe = s5p_serial_probe, - .remove = __devexit_p(s3c24xx_serial_remove), - .driver = { - .name = "s5pv210-uart", - .owner = THIS_MODULE, - }, -}; - -static int __init s5p_serial_init(void) -{ - return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf); -} - -static void __exit s5p_serial_exit(void) -{ - platform_driver_unregister(&s5p_serial_driver); -} - -module_init(s5p_serial_init); -module_exit(s5p_serial_exit); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s5pv210-uart"); -MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support"); -MODULE_AUTHOR("Thomas Abraham "); diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 78aea1a..c89987b 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -206,7 +206,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, struct s3c24xx_uart_info *info = ourport->info; if (ufstat & info->rx_fifofull) - return info->fifosize; + return ourport->port.fifosize; return (ufstat & info->rx_fifomask) >> info->rx_fifoshift; } @@ -1079,11 +1079,10 @@ static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *p */ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, - struct s3c24xx_uart_info *info, struct platform_device *platdev) { struct uart_port *port = &ourport->port; - struct s3c2410_uartcfg *cfg = platdev->dev.platform_data; + struct s3c2410_uartcfg *cfg = ourport->cfg; struct resource *res; int ret; @@ -1095,32 +1094,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, if (port->mapbase != 0) return 0; - /* - * If platform data is supplied, keep a copy of the location of - * platform data in the driver's private data. - */ - if (cfg) - ourport->cfg = cfg; - - if (cfg->hwport > CONFIG_SERIAL_SAMSUNG_UARTS) { - printk(KERN_ERR "%s: port %d bigger than %d\n", __func__, - cfg->hwport, CONFIG_SERIAL_SAMSUNG_UARTS); - return -ERANGE; - } - /* setup info for port */ port->dev = &platdev->dev; - ourport->info = info; /* Startup sequence is different for s3c64xx and higher SoC's */ if (s3c24xx_serial_has_interrupt_mask(port)) s3c24xx_serial_ops.startup = s3c64xx_serial_startup; - /* copy the info in from provided structure */ - ourport->port.fifosize = info->fifosize; - - dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport); - port->uartclk = 1; if (cfg->uart_flags & UPF_CONS_FLOW) { @@ -1187,34 +1167,46 @@ static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); static int probe_index; -int s3c24xx_serial_probe(struct platform_device *dev, - struct s3c24xx_uart_info *info) +static int s3c24xx_serial_probe(struct platform_device *pdev) { struct s3c24xx_uart_port *ourport; int ret; - dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index); + dbg("s3c24xx_serial_probe(%p) %d\n", pdev, probe_index); ourport = &s3c24xx_serial_ports[probe_index]; + + ourport->drv_data = (struct s3c24xx_serial_drv_data *) + platform_get_device_id(pdev)->driver_data; + + ourport->info = ourport->drv_data->info; + ourport->cfg = (pdev->dev.platform_data) ? + (struct s3c2410_uartcfg *)pdev->dev.platform_data : + ourport->drv_data->def_cfg; + + ourport->port.fifosize = (ourport->info->fifosize) ? + ourport->info->fifosize : + ourport->drv_data->fifosize[probe_index]; + probe_index++; dbg("%s: initialising port %p...\n", __func__, ourport); - ret = s3c24xx_serial_init_port(ourport, info, dev); + ret = s3c24xx_serial_init_port(ourport, pdev); if (ret < 0) goto probe_err; dbg("%s: adding port\n", __func__); uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); - platform_set_drvdata(dev, &ourport->port); + platform_set_drvdata(pdev, &ourport->port); - ret = device_create_file(&dev->dev, &dev_attr_clock_source); + ret = device_create_file(&pdev->dev, &dev_attr_clock_source); if (ret < 0) - printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__); + dev_err(&pdev->dev, "failed to add clock source attr.\n"); ret = s3c24xx_serial_cpufreq_register(ourport); if (ret < 0) - dev_err(&dev->dev, "failed to add cpufreq notifier\n"); + dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); return 0; @@ -1222,9 +1214,7 @@ int s3c24xx_serial_probe(struct platform_device *dev, return ret; } -EXPORT_SYMBOL_GPL(s3c24xx_serial_probe); - -int __devexit s3c24xx_serial_remove(struct platform_device *dev) +static int __devexit s3c24xx_serial_remove(struct platform_device *dev) { struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); @@ -1237,8 +1227,6 @@ int __devexit s3c24xx_serial_remove(struct platform_device *dev) return 0; } -EXPORT_SYMBOL_GPL(s3c24xx_serial_remove); - /* UART power management code */ #ifdef CONFIG_PM_SLEEP static int s3c24xx_serial_suspend(struct device *dev) @@ -1278,41 +1266,6 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = { #define SERIAL_SAMSUNG_PM_OPS NULL #endif /* CONFIG_PM_SLEEP */ -int s3c24xx_serial_init(struct platform_driver *drv, - struct s3c24xx_uart_info *info) -{ - dbg("s3c24xx_serial_init(%p,%p)\n", drv, info); - - drv->driver.pm = SERIAL_SAMSUNG_PM_OPS; - - return platform_driver_register(drv); -} - -EXPORT_SYMBOL_GPL(s3c24xx_serial_init); - -/* module initialisation code */ - -static int __init s3c24xx_serial_modinit(void) -{ - int ret; - - ret = uart_register_driver(&s3c24xx_uart_drv); - if (ret < 0) { - printk(KERN_ERR "failed to register UART driver\n"); - return -1; - } - - return 0; -} - -static void __exit s3c24xx_serial_modexit(void) -{ - uart_unregister_driver(&s3c24xx_uart_drv); -} - -module_init(s3c24xx_serial_modinit); -module_exit(s3c24xx_serial_modexit); - /* Console code */ #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE @@ -1418,36 +1371,12 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, else rate = 1; - *baud = rate / (16 * (ubrdiv + 1)); dbg("calculated baud %d\n", *baud); } } -/* s3c24xx_serial_init_ports - * - * initialise the serial ports from the machine provided initialisation - * data. -*/ - -static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info) -{ - struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports; - struct platform_device **platdev_ptr; - int i; - - dbg("s3c24xx_serial_init_ports: initialising ports...\n"); - - platdev_ptr = s3c24xx_uart_devs; - - for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) { - s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr); - } - - return 0; -} - static int __init s3c24xx_serial_console_setup(struct console *co, char *options) { @@ -1491,11 +1420,6 @@ s3c24xx_serial_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -/* s3c24xx_serial_initconsole - * - * initialise the console from one of the uart drivers -*/ - static struct console s3c24xx_serial_console = { .name = S3C24XX_SERIAL_NAME, .device = uart_console_device, @@ -1505,34 +1429,238 @@ static struct console s3c24xx_serial_console = { .setup = s3c24xx_serial_console_setup, .data = &s3c24xx_uart_drv, }; +#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */ + +#ifdef CONFIG_CPU_S3C2410 +static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = { + .info = &(struct s3c24xx_uart_info) { + .name = "Samsung S3C2410 UART", + .type = PORT_S3C2410, + .fifosize = 16, + .rx_fifomask = S3C2410_UFSTAT_RXMASK, + .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT, + .rx_fifofull = S3C2410_UFSTAT_RXFULL, + .tx_fifofull = S3C2410_UFSTAT_TXFULL, + .tx_fifomask = S3C2410_UFSTAT_TXMASK, + .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT, + .def_clk_sel = S3C2410_UCON_CLKSEL0, + .num_clks = 2, + .clksel_mask = S3C2410_UCON_CLKMASK, + .clksel_shift = S3C2410_UCON_CLKSHIFT, + }, + .def_cfg = &(struct s3c2410_uartcfg) { + .ucon = S3C2410_UCON_DEFAULT, + .ufcon = S3C2410_UFCON_DEFAULT, + }, +}; +#define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data) +#else +#define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#endif -int s3c24xx_serial_initconsole(struct platform_driver *drv, - struct s3c24xx_uart_info **info) +#ifdef CONFIG_CPU_S3C2412 +static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = { + .info = &(struct s3c24xx_uart_info) { + .name = "Samsung S3C2412 UART", + .type = PORT_S3C2412, + .fifosize = 64, + .has_divslot = 1, + .rx_fifomask = S3C2440_UFSTAT_RXMASK, + .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, + .rx_fifofull = S3C2440_UFSTAT_RXFULL, + .tx_fifofull = S3C2440_UFSTAT_TXFULL, + .tx_fifomask = S3C2440_UFSTAT_TXMASK, + .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, + .def_clk_sel = S3C2410_UCON_CLKSEL2, + .num_clks = 4, + .clksel_mask = S3C2412_UCON_CLKMASK, + .clksel_shift = S3C2412_UCON_CLKSHIFT, + }, + .def_cfg = &(struct s3c2410_uartcfg) { + .ucon = S3C2410_UCON_DEFAULT, + .ufcon = S3C2410_UFCON_DEFAULT, + }, +}; +#define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data) +#else +#define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#endif -{ - struct platform_device *dev = s3c24xx_uart_devs[0]; +#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \ + defined(CONFIG_CPU_S3C2443) +static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = { + .info = &(struct s3c24xx_uart_info) { + .name = "Samsung S3C2440 UART", + .type = PORT_S3C2440, + .fifosize = 64, + .has_divslot = 1, + .rx_fifomask = S3C2440_UFSTAT_RXMASK, + .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, + .rx_fifofull = S3C2440_UFSTAT_RXFULL, + .tx_fifofull = S3C2440_UFSTAT_TXFULL, + .tx_fifomask = S3C2440_UFSTAT_TXMASK, + .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, + .def_clk_sel = S3C2410_UCON_CLKSEL2, + .num_clks = 4, + .clksel_mask = S3C2412_UCON_CLKMASK, + .clksel_shift = S3C2412_UCON_CLKSHIFT, + }, + .def_cfg = &(struct s3c2410_uartcfg) { + .ucon = S3C2410_UCON_DEFAULT, + .ufcon = S3C2410_UFCON_DEFAULT, + }, +}; +#define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data) +#else +#define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#endif - dbg("s3c24xx_serial_initconsole\n"); +#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) || \ + defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) || \ + defined(CONFIG_CPU_S5PC100) +static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = { + .info = &(struct s3c24xx_uart_info) { + .name = "Samsung S3C6400 UART", + .type = PORT_S3C6400, + .fifosize = 64, + .has_divslot = 1, + .rx_fifomask = S3C2440_UFSTAT_RXMASK, + .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT, + .rx_fifofull = S3C2440_UFSTAT_RXFULL, + .tx_fifofull = S3C2440_UFSTAT_TXFULL, + .tx_fifomask = S3C2440_UFSTAT_TXMASK, + .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT, + .def_clk_sel = S3C2410_UCON_CLKSEL2, + .num_clks = 4, + .clksel_mask = S3C6400_UCON_CLKMASK, + .clksel_shift = S3C6400_UCON_CLKSHIFT, + }, + .def_cfg = &(struct s3c2410_uartcfg) { + .ucon = S3C2410_UCON_DEFAULT, + .ufcon = S3C2410_UFCON_DEFAULT, + }, +}; +#define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data) +#else +#define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#endif - /* select driver based on the cpu */ +#ifdef CONFIG_CPU_S5PV210 +static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { + .info = &(struct s3c24xx_uart_info) { + .name = "Samsung S5PV210 UART", + .type = PORT_S3C6400, + .has_divslot = 1, + .rx_fifomask = S5PV210_UFSTAT_RXMASK, + .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, + .rx_fifofull = S5PV210_UFSTAT_RXFULL, + .tx_fifofull = S5PV210_UFSTAT_TXFULL, + .tx_fifomask = S5PV210_UFSTAT_TXMASK, + .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, + .def_clk_sel = S3C2410_UCON_CLKSEL0, + .num_clks = 2, + .clksel_mask = S5PV210_UCON_CLKMASK, + .clksel_shift = S5PV210_UCON_CLKSHIFT, + }, + .def_cfg = &(struct s3c2410_uartcfg) { + .ucon = S5PV210_UCON_DEFAULT, + .ufcon = S5PV210_UFCON_DEFAULT, + }, + .fifosize = { 256, 64, 16, 16 }, +}; +#define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data) +#else +#define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#endif - if (dev == NULL) { - printk(KERN_ERR "s3c24xx: no devices for console init\n"); - return 0; - } +#ifdef CONFIG_CPU_EXYNOS4210 +static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { + .info = &(struct s3c24xx_uart_info) { + .name = "Samsung Exynos4 UART", + .type = PORT_S3C6400, + .has_divslot = 1, + .rx_fifomask = S5PV210_UFSTAT_RXMASK, + .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, + .rx_fifofull = S5PV210_UFSTAT_RXFULL, + .tx_fifofull = S5PV210_UFSTAT_TXFULL, + .tx_fifomask = S5PV210_UFSTAT_TXMASK, + .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, + .def_clk_sel = S3C2410_UCON_CLKSEL0, + .num_clks = 1, + .clksel_mask = 0, + .clksel_shift = 0, + }, + .def_cfg = &(struct s3c2410_uartcfg) { + .ucon = S5PV210_UCON_DEFAULT, + .ufcon = S5PV210_UFCON_DEFAULT, + .has_fracval = 1, + }, + .fifosize = { 256, 64, 16, 16 }, +}; +#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) +#else +#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#endif - if (strcmp(dev->name, drv->driver.name) != 0) - return 0; +static struct platform_device_id s3c24xx_serial_driver_ids[] = { + { + .name = "s3c2410-uart", + .driver_data = S3C2410_SERIAL_DRV_DATA, + }, { + .name = "s3c2412-uart", + .driver_data = S3C2412_SERIAL_DRV_DATA, + }, { + .name = "s3c2440-uart", + .driver_data = S3C2440_SERIAL_DRV_DATA, + }, { + .name = "s3c6400-uart", + .driver_data = S3C6400_SERIAL_DRV_DATA, + }, { + .name = "s5pv210-uart", + .driver_data = S5PV210_SERIAL_DRV_DATA, + }, { + .name = "exynos4210-uart", + .driver_data = EXYNOS4210_SERIAL_DRV_DATA, + }, + { }, +}; +MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids); + +static struct platform_driver samsung_serial_driver = { + .probe = s3c24xx_serial_probe, + .remove = __devexit_p(s3c24xx_serial_remove), + .id_table = s3c24xx_serial_driver_ids, + .driver = { + .name = "samsung-uart", + .owner = THIS_MODULE, + .pm = SERIAL_SAMSUNG_PM_OPS, + }, +}; - s3c24xx_serial_console.data = &s3c24xx_uart_drv; - s3c24xx_serial_init_ports(info); +/* module initialisation code */ - register_console(&s3c24xx_serial_console); - return 0; +static int __init s3c24xx_serial_modinit(void) +{ + int ret; + + ret = uart_register_driver(&s3c24xx_uart_drv); + if (ret < 0) { + printk(KERN_ERR "failed to register UART driver\n"); + return -1; + } + + return platform_driver_register(&samsung_serial_driver); } -#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */ +static void __exit s3c24xx_serial_modexit(void) +{ + uart_unregister_driver(&s3c24xx_uart_drv); +} + +module_init(s3c24xx_serial_modinit); +module_exit(s3c24xx_serial_modexit); +MODULE_ALIAS("platform:samsung-uart"); MODULE_DESCRIPTION("Samsung SoC Serial port driver"); MODULE_AUTHOR("Ben Dooks "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index c9cab2c..1a4bca3 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -32,6 +32,12 @@ struct s3c24xx_uart_info { int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *); }; +struct s3c24xx_serial_drv_data { + struct s3c24xx_uart_info *info; + struct s3c2410_uartcfg *def_cfg; + unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS]; +}; + struct s3c24xx_uart_port { unsigned char rx_claimed; unsigned char tx_claimed; @@ -45,6 +51,7 @@ struct s3c24xx_uart_port { struct clk *clk; struct clk *baudclk; struct uart_port port; + struct s3c24xx_serial_drv_data *drv_data; /* reference to platform data */ struct s3c2410_uartcfg *cfg; @@ -69,17 +76,6 @@ struct s3c24xx_uart_port { #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) -extern int s3c24xx_serial_probe(struct platform_device *dev, - struct s3c24xx_uart_info *uart); - -extern int __devexit s3c24xx_serial_remove(struct platform_device *dev); - -extern int s3c24xx_serial_initconsole(struct platform_driver *drv, - struct s3c24xx_uart_info **uart); - -extern int s3c24xx_serial_init(struct platform_driver *drv, - struct s3c24xx_uart_info *info); - #ifdef CONFIG_SERIAL_SAMSUNG_DEBUG extern void printascii(const char *); -- cgit v0.10.2 From 26c919e1d3f4dff87ad50e104670f048cbc69b17 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sun, 6 Nov 2011 22:10:44 +0530 Subject: serial: samsung: add device tree support Add device tree based discovery support for Samsung's uart controller. Cc: Ben Dooks Acked-by: Grant Likely Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.txt b/Documentation/devicetree/bindings/serial/samsung_uart.txt new file mode 100644 index 0000000..2c8a17c --- /dev/null +++ b/Documentation/devicetree/bindings/serial/samsung_uart.txt @@ -0,0 +1,14 @@ +* Samsung's UART Controller + +The Samsung's UART controller is used for interfacing SoC with serial communicaion +devices. + +Required properties: +- compatible: should be + - "samsung,exynos4210-uart", for UART's compatible with Exynos4210 uart ports. + +- reg: base physical address of the controller and length of memory mapped + region. + +- interrupts: interrupt number to the cpu. The interrupt specifier format depends + on the interrupt controller parent. diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index c89987b..efe3756 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -1163,10 +1164,26 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); + /* Device driver serial port probe */ +static const struct of_device_id s3c24xx_uart_dt_match[]; static int probe_index; +static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data( + struct platform_device *pdev) +{ +#ifdef CONFIG_OF + if (pdev->dev.of_node) { + const struct of_device_id *match; + match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node); + return (struct s3c24xx_serial_drv_data *)match->data; + } +#endif + return (struct s3c24xx_serial_drv_data *) + platform_get_device_id(pdev)->driver_data; +} + static int s3c24xx_serial_probe(struct platform_device *pdev) { struct s3c24xx_uart_port *ourport; @@ -1176,8 +1193,11 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) ourport = &s3c24xx_serial_ports[probe_index]; - ourport->drv_data = (struct s3c24xx_serial_drv_data *) - platform_get_device_id(pdev)->driver_data; + ourport->drv_data = s3c24xx_get_driver_data(pdev); + if (!ourport->drv_data) { + dev_err(&pdev->dev, "could not find driver data\n"); + return -ENODEV; + } ourport->info = ourport->drv_data->info; ourport->cfg = (pdev->dev.platform_data) ? @@ -1626,6 +1646,17 @@ static struct platform_device_id s3c24xx_serial_driver_ids[] = { }; MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids); +#ifdef CONFIG_OF +static const struct of_device_id s3c24xx_uart_dt_match[] = { + { .compatible = "samsung,exynos4210-uart", + .data = &exynos4210_serial_drv_data }, + {}, +}; +MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); +#else +#define s3c24xx_uart_dt_match NULL +#endif + static struct platform_driver samsung_serial_driver = { .probe = s3c24xx_serial_probe, .remove = __devexit_p(s3c24xx_serial_remove), @@ -1634,6 +1665,7 @@ static struct platform_driver samsung_serial_driver = { .name = "samsung-uart", .owner = THIS_MODULE, .pm = SERIAL_SAMSUNG_PM_OPS, + .of_match_table = s3c24xx_uart_dt_match, }, }; -- cgit v0.10.2 From a169a888bf8c5490ae0377fcd0ad22c6af9fd8e7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 8 Nov 2011 17:00:14 +0900 Subject: serial: samsung: Fix build for non-Exynos4210 devices exynos4120_serial_drv_data is only defined when building with support for Exynos4210 so use the already provided define to ensure that we don't reference it when building for other SoCs. Signed-off-by: Mark Brown [kgene.kim@samsung.com: Fixed build warning] Signed-off-by: Kukjin Kim diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index efe3756..f96f37b 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1649,7 +1649,7 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids); #ifdef CONFIG_OF static const struct of_device_id s3c24xx_uart_dt_match[] = { { .compatible = "samsung,exynos4210-uart", - .data = &exynos4210_serial_drv_data }, + .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, {}, }; MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); -- cgit v0.10.2 From 3e2ec13a8185183cd7ff237dadc948a0f9f7398f Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:43:02 +0200 Subject: DMA: PL330: move filter function into driver The dma channel selection filter function is moved from plat-samsung into the pl330 driver. In additon to that, a check is added in the filter function to ensure that the channel on which the filter has been invoked is pl330 channel instance (and avoid any incorrect access of chan->private in a system with multiple types of DMA drivers). Suggested-by: Russell King Signed-off-by: Thomas Abraham Acked-by: Jassi Brar Acked-by: Grant Likely Acked-by: Vinod Koul Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index 93a994a..889c2c2 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -18,12 +18,6 @@ #include -static inline bool pl330_filter(struct dma_chan *chan, void *param) -{ - struct dma_pl330_peri *peri = chan->private; - return peri->peri_id == (unsigned)param; -} - static unsigned samsung_dmadev_request(enum dma_ch dma_ch, struct samsung_dma_info *info) { diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 57104147..0c434dc 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -116,6 +116,9 @@ struct dma_pl330_desc { struct dma_pl330_chan *pchan; }; +/* forward declaration */ +static struct amba_driver pl330_driver; + static inline struct dma_pl330_chan * to_pchan(struct dma_chan *ch) { @@ -267,6 +270,18 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err) tasklet_schedule(&pch->task); } +bool pl330_filter(struct dma_chan *chan, void *param) +{ + struct dma_pl330_peri *peri; + + if (chan->device->dev->driver != &pl330_driver.drv) + return false; + + peri = chan->private; + return peri->peri_id == (unsigned)param; +} +EXPORT_SYMBOL(pl330_filter); + static int pl330_alloc_chan_resources(struct dma_chan *chan) { struct dma_pl330_chan *pch = to_pchan(chan); diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index d12f077..6db72da 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -12,6 +12,7 @@ #ifndef __AMBA_PL330_H_ #define __AMBA_PL330_H_ +#include #include struct dma_pl330_peri { @@ -38,4 +39,5 @@ struct dma_pl330_platdata { unsigned mcbuf_sz; }; +extern bool pl330_filter(struct dma_chan *chan, void *param); #endif /* __AMBA_PL330_H_ */ -- cgit v0.10.2 From cd072515215ccc37051cadc516ce28545257be41 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:43:11 +0200 Subject: DMA: PL330: Infer transfer direction from transfer request instead of platform data The transfer direction for a channel can be inferred from the transfer request and the need for specifying transfer direction in platfrom data can be eliminated. So the structure definition 'struct dma_pl330_peri' is no longer required. The channel's private data is set to point to a channel id specified in the platform data (instead of an instance of type 'struct dma_pl330_peri'). The filter function is correspondingly modified to match the channel id. With the 'struct dma_pl330_peri' removed from platform data, the dma controller transfer capabilities cannot be inferred any more. Hence, the dma controller capabilities is specified using platform data. Acked-by: Jassi Brar Acked-by: Boojin Kim Signed-off-by: Thomas Abraham Acked-by: Grant Likely Acked-by: Vinod Koul Signed-off-by: Kukjin Kim diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0c434dc..317aaea 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -272,13 +272,13 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err) bool pl330_filter(struct dma_chan *chan, void *param) { - struct dma_pl330_peri *peri; + u8 *peri_id; if (chan->device->dev->driver != &pl330_driver.drv) return false; - peri = chan->private; - return peri->peri_id == (unsigned)param; + peri_id = chan->private; + return *peri_id == (unsigned)param; } EXPORT_SYMBOL(pl330_filter); @@ -512,7 +512,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac) static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) { struct dma_pl330_dmac *pdmac = pch->dmac; - struct dma_pl330_peri *peri = pch->chan.private; + u8 *peri_id = pch->chan.private; struct dma_pl330_desc *desc; /* Pluck one desc from the pool of DMAC */ @@ -537,13 +537,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) desc->txd.cookie = 0; async_tx_ack(&desc->txd); - if (peri) { - desc->req.rqtype = peri->rqtype; - desc->req.peri = pch->chan.chan_id; - } else { - desc->req.rqtype = MEMTOMEM; - desc->req.peri = 0; - } + desc->req.peri = peri_id ? pch->chan.chan_id : 0; dma_async_tx_descriptor_init(&desc->txd, &pch->chan); @@ -630,12 +624,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( case DMA_TO_DEVICE: desc->rqcfg.src_inc = 1; desc->rqcfg.dst_inc = 0; + desc->req.rqtype = MEMTODEV; src = dma_addr; dst = pch->fifo_addr; break; case DMA_FROM_DEVICE: desc->rqcfg.src_inc = 0; desc->rqcfg.dst_inc = 1; + desc->req.rqtype = DEVTOMEM; src = pch->fifo_addr; dst = dma_addr; break; @@ -661,16 +657,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, { struct dma_pl330_desc *desc; struct dma_pl330_chan *pch = to_pchan(chan); - struct dma_pl330_peri *peri = chan->private; struct pl330_info *pi; int burst; if (unlikely(!pch || !len)) return NULL; - if (peri && peri->rqtype != MEMTOMEM) - return NULL; - pi = &pch->dmac->pif; desc = __pl330_prep_dma_memcpy(pch, dst, src, len); @@ -679,6 +671,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, desc->rqcfg.src_inc = 1; desc->rqcfg.dst_inc = 1; + desc->req.rqtype = MEMTOMEM; /* Select max possible burst size */ burst = pi->pcfg.data_bus_width / 8; @@ -707,24 +700,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, { struct dma_pl330_desc *first, *desc = NULL; struct dma_pl330_chan *pch = to_pchan(chan); - struct dma_pl330_peri *peri = chan->private; struct scatterlist *sg; unsigned long flags; int i; dma_addr_t addr; - if (unlikely(!pch || !sgl || !sg_len || !peri)) - return NULL; - - /* Make sure the direction is consistent */ - if ((direction == DMA_TO_DEVICE && - peri->rqtype != MEMTODEV) || - (direction == DMA_FROM_DEVICE && - peri->rqtype != DEVTOMEM)) { - dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n", - __func__, __LINE__); + if (unlikely(!pch || !sgl || !sg_len)) return NULL; - } addr = pch->fifo_addr; @@ -765,11 +747,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (direction == DMA_TO_DEVICE) { desc->rqcfg.src_inc = 1; desc->rqcfg.dst_inc = 0; + desc->req.rqtype = MEMTODEV; fill_px(&desc->px, addr, sg_dma_address(sg), sg_dma_len(sg)); } else { desc->rqcfg.src_inc = 0; desc->rqcfg.dst_inc = 1; + desc->req.rqtype = DEVTOMEM; fill_px(&desc->px, sg_dma_address(sg), addr, sg_dma_len(sg)); } @@ -876,28 +860,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) for (i = 0; i < num_chan; i++) { pch = &pdmac->peripherals[i]; - if (pdat) { - struct dma_pl330_peri *peri = &pdat->peri[i]; - - switch (peri->rqtype) { - case MEMTOMEM: - dma_cap_set(DMA_MEMCPY, pd->cap_mask); - break; - case MEMTODEV: - case DEVTOMEM: - dma_cap_set(DMA_SLAVE, pd->cap_mask); - dma_cap_set(DMA_CYCLIC, pd->cap_mask); - break; - default: - dev_err(&adev->dev, "DEVTODEV Not Supported\n"); - continue; - } - pch->chan.private = peri; - } else { - dma_cap_set(DMA_MEMCPY, pd->cap_mask); - pch->chan.private = NULL; - } - + pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; INIT_LIST_HEAD(&pch->work_list); spin_lock_init(&pch->lock); pch->pl330_chid = NULL; @@ -909,6 +872,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) } pd->dev = &adev->dev; + if (pdat) + pd->cap_mask = pdat->cap_mask; + else + dma_cap_set(DMA_MEMCPY, pd->cap_mask); pd->device_alloc_chan_resources = pl330_alloc_chan_resources; pd->device_free_chan_resources = pl330_free_chan_resources; diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h index 6db72da..12e023c 100644 --- a/include/linux/amba/pl330.h +++ b/include/linux/amba/pl330.h @@ -15,15 +15,6 @@ #include #include -struct dma_pl330_peri { - /* - * Peri_Req i/f of the DMAC that is - * peripheral could be reached from. - */ - u8 peri_id; /* specific dma id */ - enum pl330_reqtype rqtype; -}; - struct dma_pl330_platdata { /* * Number of valid peripherals connected to DMAC. @@ -34,7 +25,9 @@ struct dma_pl330_platdata { */ u8 nr_valid_peri; /* Array of valid peripherals */ - struct dma_pl330_peri *peri; + u8 *peri_id; + /* Operational capabilities */ + dma_cap_mask_t cap_mask; /* Bytes to allocate for MC buffer */ unsigned mcbuf_sz; }; -- cgit v0.10.2 From e1cd8454dac99473c2349efce1346264c494f28d Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:43:22 +0200 Subject: ARM: EXYNOS: Modify platform data for pl330 driver With the 'struct dma_pl330_peri' removed, the platfrom data for dma driver can be simplified to a simple list of peripheral request ids. Cc: Jassi Brar Acked-by: Boojin Kim Signed-off-by: Thomas Abraham Acked-by: Grant Likely Acked-by: Vinod Koul Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index 9667c61..141093d 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -35,95 +35,42 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -struct dma_pl330_peri pdma0_peri[28] = { - { - .peri_id = (u8)DMACH_PCM0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MSM_REQ0, - }, { - .peri_id = (u8)DMACH_MSM_REQ2, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0S_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART4_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART4_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SLIMBUS0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SLIMBUS0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SLIMBUS2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SLIMBUS2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SLIMBUS4_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SLIMBUS4_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_AC97_MICIN, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_AC97_PCMIN, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_AC97_PCMOUT, - .rqtype = MEMTODEV, - }, +u8 pdma0_peri[] = { + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM2_RX, + DMACH_PCM2_TX, + DMACH_MSM_REQ0, + DMACH_MSM_REQ2, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_I2S0S_TX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART4_RX, + DMACH_UART4_TX, + DMACH_SLIMBUS0_RX, + DMACH_SLIMBUS0_TX, + DMACH_SLIMBUS2_RX, + DMACH_SLIMBUS2_TX, + DMACH_SLIMBUS4_RX, + DMACH_SLIMBUS4_TX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, }; struct dma_pl330_platdata exynos4_pdma0_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma0_peri), - .peri = pdma0_peri, + .peri_id = pdma0_peri, }; struct amba_device exynos4_device_pdma0 = { @@ -142,86 +89,37 @@ struct amba_device exynos4_device_pdma0 = { .periphid = 0x00041330, }; -struct dma_pl330_peri pdma1_peri[25] = { - { - .peri_id = (u8)DMACH_PCM0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MSM_REQ1, - }, { - .peri_id = (u8)DMACH_MSM_REQ3, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0S_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SLIMBUS1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SLIMBUS1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SLIMBUS3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SLIMBUS3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SLIMBUS5_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SLIMBUS5_TX, - .rqtype = MEMTODEV, - }, +u8 pdma1_peri[] = { + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM1_RX, + DMACH_PCM1_TX, + DMACH_MSM_REQ1, + DMACH_MSM_REQ3, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_I2S0S_TX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_SLIMBUS1_RX, + DMACH_SLIMBUS1_TX, + DMACH_SLIMBUS3_RX, + DMACH_SLIMBUS3_TX, + DMACH_SLIMBUS5_RX, + DMACH_SLIMBUS5_TX, }; struct dma_pl330_platdata exynos4_pdma1_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma1_peri), - .peri = pdma1_peri, + .peri_id = pdma1_peri, }; struct amba_device exynos4_device_pdma1 = { @@ -242,7 +140,12 @@ struct amba_device exynos4_device_pdma1 = { static int __init exynos4_dma_init(void) { + dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask); amba_device_register(&exynos4_device_pdma0, &iomem_resource); + + dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask); amba_device_register(&exynos4_device_pdma1, &iomem_resource); return 0; -- cgit v0.10.2 From 93ed55441245a39e3935f5cf1af3e22febcce905 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:43:31 +0200 Subject: DMA: PL330: Add device tree support For PL330 dma controllers instantiated from device tree, the channel lookup is based on phandle of the dma controller and dma request id specified by the client node. During probe, the private data of each channel of the controller is set to point to the device node of the dma controller. The 'chan_id' of the each channel is used as the dma request id. Client driver requesting dma channels specify the phandle of the dma controller and the request id. The pl330 filter function converts the phandle to the device node pointer and matches that with channel's private data. If a match is found, the request id from the client node and the 'chan_id' of the channel is matched. A channel is found if both the values match. Acked-by: Jassi Brar Acked-by: Boojin Kim Signed-off-by: Thomas Abraham Reviewed-by: Rob Herring Acked-by: Grant Likely Acked-by: Vinod Koul Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt new file mode 100644 index 0000000..a4cd273 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt @@ -0,0 +1,30 @@ +* ARM PrimeCell PL330 DMA Controller + +The ARM PrimeCell PL330 DMA controller can move blocks of memory contents +between memory and peripherals or memory to memory. + +Required properties: + - compatible: should include both "arm,pl330" and "arm,primecell". + - reg: physical base address of the controller and length of memory mapped + region. + - interrupts: interrupt number to the cpu. + +Example: + + pdma0: pdma@12680000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x12680000 0x1000>; + interrupts = <99>; + }; + +Client drivers (device nodes requiring dma transfers from dev-to-mem or +mem-to-dev) should specify the DMA channel numbers using a two-value pair +as shown below. + + [property name] = <[phandle of the dma controller] [dma request id]>; + + where 'dma request id' is the dma request number which is connected + to the client controller. The 'property name' is recommended to be + of the form -dma-channel. + + Example: tx-dma-channel = <&pdma0 12>; diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 317aaea..a626e15 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -19,6 +19,7 @@ #include #include #include +#include #define NR_DEFAULT_DESC 16 @@ -277,6 +278,20 @@ bool pl330_filter(struct dma_chan *chan, void *param) if (chan->device->dev->driver != &pl330_driver.drv) return false; +#ifdef CONFIG_OF + if (chan->device->dev->of_node) { + const __be32 *prop_value; + phandle phandle; + struct device_node *node; + + prop_value = ((struct property *)param)->value; + phandle = be32_to_cpup(prop_value++); + node = of_find_node_by_phandle(phandle); + return ((chan->private == node) && + (chan->chan_id == be32_to_cpup(prop_value))); + } +#endif + peri_id = chan->private; return *peri_id == (unsigned)param; } @@ -855,12 +870,17 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) INIT_LIST_HEAD(&pd->channels); /* Initialize channel parameters */ - num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan); + num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri, + (u8)pi->pcfg.num_chan); pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); for (i = 0; i < num_chan; i++) { pch = &pdmac->peripherals[i]; - pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; + if (!adev->dev.of_node) + pch->chan.private = pdat ? &pdat->peri_id[i] : NULL; + else + pch->chan.private = adev->dev.of_node; + INIT_LIST_HEAD(&pch->work_list); spin_lock_init(&pch->lock); pch->pl330_chid = NULL; @@ -872,10 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) } pd->dev = &adev->dev; - if (pdat) + if (pdat) { pd->cap_mask = pdat->cap_mask; - else + } else { dma_cap_set(DMA_MEMCPY, pd->cap_mask); + if (pi->pcfg.num_peri) { + dma_cap_set(DMA_SLAVE, pd->cap_mask); + dma_cap_set(DMA_CYCLIC, pd->cap_mask); + } + } pd->device_alloc_chan_resources = pl330_alloc_chan_resources; pd->device_free_chan_resources = pl330_free_chan_resources; -- cgit v0.10.2 From 4972a80e16a206149729be887285f4494b6826dc Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:43:38 +0200 Subject: ARM: SAMSUNG: Add device tree support for pl330 dma engine wrappers A new dma request id 'DMACH_DT_PROP' is introduced for client drivers requesting a dma channel. This request indicates that a device tree node property represting the dma channel is available in 'struct samsung_dma_info'. The dma channel request wrapper uses the node property value as the value for the filter parameter. Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c index 889c2c2..2cded87 100644 --- a/arch/arm/plat-samsung/dma-ops.c +++ b/arch/arm/plat-samsung/dma-ops.c @@ -24,11 +24,18 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch, struct dma_chan *chan; dma_cap_mask_t mask; struct dma_slave_config slave_config; + void *filter_param; dma_cap_zero(mask); dma_cap_set(info->cap, mask); - chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); + /* + * If a dma channel property of a device node from device tree is + * specified, use that as the fliter parameter. + */ + filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop : + (void *)dma_ch; + chan = dma_request_channel(mask, pl330_filter, filter_param); if (info->direction == DMA_FROM_DEVICE) { memset(&slave_config, 0, sizeof(struct dma_slave_config)); diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h index 4c1a363..22eafc3 100644 --- a/arch/arm/plat-samsung/include/plat/dma-ops.h +++ b/arch/arm/plat-samsung/include/plat/dma-ops.h @@ -31,6 +31,7 @@ struct samsung_dma_info { enum dma_slave_buswidth width; dma_addr_t fifo; struct s3c2410_dma_client *client; + struct property *dt_dmach_prop; }; struct samsung_dma_ops { diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h index 2e55e59..c5eaad5 100644 --- a/arch/arm/plat-samsung/include/plat/dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h @@ -21,7 +21,8 @@ * use these just as IDs. */ enum dma_ch { - DMACH_UART0_RX, + DMACH_DT_PROP = -1, + DMACH_UART0_RX = 0, DMACH_UART0_TX, DMACH_UART1_RX, DMACH_UART1_TX, -- cgit v0.10.2 From fca3de6ab9bfc6f3b5beebd8f9792357c4e4d441 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 13:57:43 +0200 Subject: ARM: EXYNOS: Limit usage of pl330 device instance to non-dt build The pl330 device instances and associated platform data is required only for non-device-tree builds. With device tree enabled, the data about the platform is obtained from the device tree. For images that include both dt and non-dt platforms, an addditional check is added to ensure that static amba device registrations is applicable to only non-dt platforms. Cc: Kukjin Kim Cc: Kyungmin Park Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 724ec0f..68e4ab0 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -57,6 +57,11 @@ config EXYNOS4_MCT help Use MCT (Multi Core Timer) as kernel timers +config EXYNOS4_DEV_DMA + bool + help + Compile in amba device definitions for DMA controller + config EXYNOS4_DEV_AHCI bool help @@ -177,6 +182,7 @@ config MACH_SMDKV310 select SAMSUNG_DEV_BACKLIGHT select EXYNOS4_DEV_AHCI select SAMSUNG_DEV_KEYPAD + select EXYNOS4_DEV_DMA select EXYNOS4_DEV_PD select SAMSUNG_DEV_PWM select EXYNOS4_DEV_SYSMMU @@ -197,6 +203,7 @@ config MACH_ARMLEX4210 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 select EXYNOS4_DEV_AHCI + select EXYNOS4_DEV_DMA select EXYNOS4_DEV_SYSMMU select EXYNOS4_SETUP_SDHCI help @@ -222,6 +229,7 @@ config MACH_UNIVERSAL_C210 select S5P_DEV_MFC select S5P_DEV_ONENAND select S5P_DEV_TV + select EXYNOS4_DEV_DMA select EXYNOS4_DEV_PD select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 @@ -255,6 +263,7 @@ config MACH_NURI select S5P_DEV_MFC select S5P_DEV_USB_EHCI select S5P_SETUP_MIPIPHY + select EXYNOS4_DEV_DMA select EXYNOS4_DEV_PD select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMD0 @@ -287,6 +296,7 @@ config MACH_ORIGEN select S5P_DEV_USB_EHCI select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_PWM + select EXYNOS4_DEV_DMA select EXYNOS4_DEV_PD select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_SDHCI diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 59069a3..cb6fb0e 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -13,7 +13,7 @@ obj- := # Core support for EXYNOS4 system obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o setup-i2c0.o -obj-$(CONFIG_ARCH_EXYNOS4) += irq-eint.o dma.o pmu.o +obj-$(CONFIG_ARCH_EXYNOS4) += irq-eint.o pmu.o obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o obj-$(CONFIG_PM) += pm.o @@ -44,6 +44,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o +obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index 141093d..b10fcd2 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -140,6 +141,9 @@ struct amba_device exynos4_device_pdma1 = { static int __init exynos4_dma_init(void) { + if (of_have_populated_dt()) + return 0; + dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask); dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask); amba_device_register(&exynos4_device_pdma0, &iomem_resource); -- cgit v0.10.2 From 66fdb29d370436ca43a0637f831a2b4d92b243ca Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 14:01:03 +0200 Subject: ARM: EXYNOS: Add a alias for pdma clocks PDMA controllers when instantiated from device tree are registered using amba_device_register(). The registration process enables clock to the controllers to read the peripheral id of the PDMA amba device. In case of Exynos4, the clocks to the PDMA controllers are named as 'dma' but amba_device_register() looks up the clock using the name 'apb_pclk'. Hence, alias clocks with name 'apb_pclk' clock are created for clocks with name 'dma'. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index fe18519..7dee869 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c @@ -553,16 +553,6 @@ static struct clk init_clocks_off[] = { .enable = exynos4_clk_dac_ctrl, .ctrlbit = (1 << 0), }, { - .name = "dma", - .devname = "dma-pl330.0", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "dma", - .devname = "dma-pl330.1", - .enable = exynos4_clk_ip_fsys_ctrl, - .ctrlbit = (1 << 1), - }, { .name = "adc", .enable = exynos4_clk_ip_peril_ctrl, .ctrlbit = (1 << 15), @@ -778,6 +768,20 @@ static struct clk init_clocks[] = { } }; +static struct clk clk_pdma0 = { + .name = "dma", + .devname = "dma-pl330.0", + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 0), +}; + +static struct clk clk_pdma1 = { + .name = "dma", + .devname = "dma-pl330.1", + .enable = exynos4_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 1), +}; + struct clk *clkset_group_list[] = { [0] = &clk_ext_xtal_mux, [1] = &clk_xusbxti, @@ -1279,6 +1283,11 @@ static struct clksrc_clk *sysclks[] = { &clk_mout_mfc1, }; +static struct clk *clk_cdev[] = { + &clk_pdma0, + &clk_pdma1, +}; + static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uart0, &clk_sclk_uart1, @@ -1291,6 +1300,8 @@ static struct clk_lookup exynos4_clk_lookup[] = { CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk), CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk), CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk), + CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0), + CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1), }; static int xtal_rate; @@ -1506,6 +1517,10 @@ void __init exynos4_register_clocks(void) s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); + for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++) + s3c_disable_clocks(clk_cdev[ptr], 1); + s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup)); -- cgit v0.10.2 From dc732f50e2bb74d406d168626816fd7487b55f57 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:45:01 +0200 Subject: ARM: S5P64x0: Modify platform data for pl330 driver With the 'struct dma_pl330_peri' removed, the platfrom data for dma driver can be simplified to a simple list of peripheral request ids. Cc: Jassi Brar Cc: Boojin Kim Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c index 442dd4a..f820c07 100644 --- a/arch/arm/mach-s5p64x0/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -38,176 +38,74 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -struct dma_pl330_peri s5p6440_pdma_peri[22] = { - { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = DMACH_MAX, - }, { - .peri_id = DMACH_MAX, - }, { - .peri_id = (u8)DMACH_PCM0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, +u8 s5p6440_pdma_peri[] = { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_MAX, + DMACH_MAX, + DMACH_PCM0_TX, + DMACH_PCM0_RX, + DMACH_I2S0_TX, + DMACH_I2S0_RX, + DMACH_SPI0_TX, + DMACH_SPI0_RX, + DMACH_MAX, + DMACH_MAX, + DMACH_MAX, + DMACH_MAX, + DMACH_SPI1_TX, + DMACH_SPI1_RX, }; struct dma_pl330_platdata s5p6440_pdma_pdata = { .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri), - .peri = s5p6440_pdma_peri, + .peri_id = s5p6440_pdma_peri, }; -struct dma_pl330_peri s5p6450_pdma_peri[32] = { - { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART4_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART4_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_USI_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_USI_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_I2S1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PWM, - }, { - .peri_id = (u8)DMACH_UART5_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART5_TX, - .rqtype = MEMTODEV, - }, +u8 s5p6450_pdma_peri[] = { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_UART4_RX, + DMACH_UART4_TX, + DMACH_PCM0_TX, + DMACH_PCM0_RX, + DMACH_I2S0_TX, + DMACH_I2S0_RX, + DMACH_SPI0_TX, + DMACH_SPI0_RX, + DMACH_PCM1_TX, + DMACH_PCM1_RX, + DMACH_PCM2_TX, + DMACH_PCM2_RX, + DMACH_SPI1_TX, + DMACH_SPI1_RX, + DMACH_USI_TX, + DMACH_USI_RX, + DMACH_MAX, + DMACH_I2S1_TX, + DMACH_I2S1_RX, + DMACH_I2S2_TX, + DMACH_I2S2_RX, + DMACH_PWM, + DMACH_UART5_RX, + DMACH_UART5_TX, }; struct dma_pl330_platdata s5p6450_pdma_pdata = { .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri), - .peri = s5p6450_pdma_peri, + .peri_id = s5p6450_pdma_peri, }; struct amba_device s5p64x0_device_pdma = { @@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = { static int __init s5p64x0_dma_init(void) { - if (soc_is_s5p6450()) + if (soc_is_s5p6450()) { + dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask); s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; - else + } else { + dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask); s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; + } amba_device_register(&s5p64x0_device_pdma, &iomem_resource); -- cgit v0.10.2 From 7c4cab7f401a834bdf3878d417bf77d3290d4cfc Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:45:08 +0200 Subject: ARM: S5PC100: Modify platform data for pl330 driver With the 'struct dma_pl330_peri' removed, the platfrom data for dma driver can be simplified to a simple list of peripheral request ids. Cc: Jassi Brar Acked-by: Boojin Kim Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c index 065a087..c841f4d3 100644 --- a/arch/arm/mach-s5pc100/dma.c +++ b/arch/arm/mach-s5pc100/dma.c @@ -35,100 +35,42 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -struct dma_pl330_peri pdma0_peri[30] = { - { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = DMACH_IRDA, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0S_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_AC97_MICIN, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_AC97_PCMIN, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_AC97_PCMOUT, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_EXTERNAL, - }, { - .peri_id = (u8)DMACH_PWM, - }, { - .peri_id = (u8)DMACH_SPDIF, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_HSI_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_HSI_TX, - .rqtype = MEMTODEV, - }, +u8 pdma0_peri[] = { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_IRDA, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S0S_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, + DMACH_EXTERNAL, + DMACH_PWM, + DMACH_SPDIF, + DMACH_HSI_RX, + DMACH_HSI_TX, }; struct dma_pl330_platdata s5pc100_pdma0_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma0_peri), - .peri = pdma0_peri, + .peri_id = pdma0_peri, }; struct amba_device s5pc100_device_pdma0 = { @@ -147,98 +89,42 @@ struct amba_device s5pc100_device_pdma0 = { .periphid = 0x00041330, }; -struct dma_pl330_peri pdma1_peri[30] = { - { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = DMACH_IRDA, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0S_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MSM_REQ0, - }, { - .peri_id = (u8)DMACH_MSM_REQ1, - }, { - .peri_id = (u8)DMACH_MSM_REQ2, - }, { - .peri_id = (u8)DMACH_MSM_REQ3, - }, +u8 pdma1_peri[] = { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_IRDA, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S0S_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_SPI2_RX, + DMACH_SPI2_TX, + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM1_RX, + DMACH_PCM1_TX, + DMACH_MSM_REQ0, + DMACH_MSM_REQ1, + DMACH_MSM_REQ2, + DMACH_MSM_REQ3, }; struct dma_pl330_platdata s5pc100_pdma1_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma1_peri), - .peri = pdma1_peri, + .peri_id = pdma1_peri, }; struct amba_device s5pc100_device_pdma1 = { @@ -259,7 +145,12 @@ struct amba_device s5pc100_device_pdma1 = { static int __init s5pc100_dma_init(void) { + dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask); amba_device_register(&s5pc100_device_pdma0, &iomem_resource); + + dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask); amba_device_register(&s5pc100_device_pdma1, &iomem_resource); return 0; -- cgit v0.10.2 From 8742e0441d6530d40d85d65a6bcc5a6c0c4eab13 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 11:45:14 +0200 Subject: ARM: S5PV210: Modify platform data for pl330 driver With the 'struct dma_pl330_peri' removed, the platfrom data for dma driver can be simplified to a simple list of peripheral request ids. Cc: Jassi Brar Acked-by: Boojin Kim Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c index 86b749c..a6113e0 100644 --- a/arch/arm/mach-s5pv210/dma.c +++ b/arch/arm/mach-s5pv210/dma.c @@ -35,90 +35,40 @@ static u64 dma_dmamask = DMA_BIT_MASK(32); -struct dma_pl330_peri pdma0_peri[28] = { - { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = DMACH_MAX, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0S_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_AC97_MICIN, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_AC97_PCMIN, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_AC97_PCMOUT, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_PWM, - }, { - .peri_id = (u8)DMACH_SPDIF, - .rqtype = MEMTODEV, - }, +u8 pdma0_peri[] = { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_MAX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S0S_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_MAX, + DMACH_MAX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_MAX, + DMACH_MAX, + DMACH_AC97_MICIN, + DMACH_AC97_PCMIN, + DMACH_AC97_PCMOUT, + DMACH_MAX, + DMACH_PWM, + DMACH_SPDIF, }; struct dma_pl330_platdata s5pv210_pdma0_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma0_peri), - .peri = pdma0_peri, + .peri_id = pdma0_peri, }; struct amba_device s5pv210_device_pdma0 = { @@ -137,102 +87,44 @@ struct amba_device s5pv210_device_pdma0 = { .periphid = 0x00041330, }; -struct dma_pl330_peri pdma1_peri[32] = { - { - .peri_id = (u8)DMACH_UART0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_UART3_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_UART3_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = DMACH_MAX, - }, { - .peri_id = (u8)DMACH_I2S0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S0S_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_I2S2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_I2S2_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_SPI1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_SPI1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_MAX, - }, { - .peri_id = (u8)DMACH_PCM0_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM0_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_PCM1_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM1_TX, - .rqtype = MEMTODEV, - }, { - .peri_id = (u8)DMACH_MSM_REQ0, - }, { - .peri_id = (u8)DMACH_MSM_REQ1, - }, { - .peri_id = (u8)DMACH_MSM_REQ2, - }, { - .peri_id = (u8)DMACH_MSM_REQ3, - }, { - .peri_id = (u8)DMACH_PCM2_RX, - .rqtype = DEVTOMEM, - }, { - .peri_id = (u8)DMACH_PCM2_TX, - .rqtype = MEMTODEV, - }, +u8 pdma1_peri[] = { + DMACH_UART0_RX, + DMACH_UART0_TX, + DMACH_UART1_RX, + DMACH_UART1_TX, + DMACH_UART2_RX, + DMACH_UART2_TX, + DMACH_UART3_RX, + DMACH_UART3_TX, + DMACH_MAX, + DMACH_I2S0_RX, + DMACH_I2S0_TX, + DMACH_I2S0S_TX, + DMACH_I2S1_RX, + DMACH_I2S1_TX, + DMACH_I2S2_RX, + DMACH_I2S2_TX, + DMACH_SPI0_RX, + DMACH_SPI0_TX, + DMACH_SPI1_RX, + DMACH_SPI1_TX, + DMACH_MAX, + DMACH_MAX, + DMACH_PCM0_RX, + DMACH_PCM0_TX, + DMACH_PCM1_RX, + DMACH_PCM1_TX, + DMACH_MSM_REQ0, + DMACH_MSM_REQ1, + DMACH_MSM_REQ2, + DMACH_MSM_REQ3, + DMACH_PCM2_RX, + DMACH_PCM2_TX, }; struct dma_pl330_platdata s5pv210_pdma1_pdata = { .nr_valid_peri = ARRAY_SIZE(pdma1_peri), - .peri = pdma1_peri, + .peri_id = pdma1_peri, }; struct amba_device s5pv210_device_pdma1 = { @@ -253,7 +145,12 @@ struct amba_device s5pv210_device_pdma1 = { static int __init s5pv210_dma_init(void) { + dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask); amba_device_register(&s5pv210_device_pdma0, &iomem_resource); + + dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask); + dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask); amba_device_register(&s5pv210_device_pdma1, &iomem_resource); return 0; -- cgit v0.10.2 From b3d6ac3e5f937440a362c0fa187257fa1197f5b9 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 2 Nov 2011 19:37:22 +0900 Subject: input: samsung-keypad: Add device tree support Add device tree based discovery support for Samsung's keypad controller. Cc: Joonyoung Shim Cc: Donghwa Lee Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/input/samsung-keypad.txt b/Documentation/devicetree/bindings/input/samsung-keypad.txt new file mode 100644 index 0000000..ce3e394 --- /dev/null +++ b/Documentation/devicetree/bindings/input/samsung-keypad.txt @@ -0,0 +1,88 @@ +* Samsung's Keypad Controller device tree bindings + +Samsung's Keypad controller is used to interface a SoC with a matrix-type +keypad device. The keypad controller supports multiple row and column lines. +A key can be placed at each intersection of a unique row and a unique column. +The keypad controller can sense a key-press and key-release and report the +event using a interrupt to the cpu. + +Required SoC Specific Properties: +- compatible: should be one of the following + - "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad + controller. + - "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad + controller. + +- reg: physical base address of the controller and length of memory mapped + region. + +- interrupts: The interrupt number to the cpu. + +Required Board Specific Properties: +- samsung,keypad-num-rows: Number of row lines connected to the keypad + controller. + +- samsung,keypad-num-columns: Number of column lines connected to the + keypad controller. + +- row-gpios: List of gpios used as row lines. The gpio specifier for + this property depends on the gpio controller to which these row lines + are connected. + +- col-gpios: List of gpios used as column lines. The gpio specifier for + this property depends on the gpio controller to which these column + lines are connected. + +- Keys represented as child nodes: Each key connected to the keypad + controller is represented as a child node to the keypad controller + device node and should include the following properties. + - keypad,row: the row number to which the key is connected. + - keypad,column: the column number to which the key is connected. + - linux,code: the key-code to be reported when the key is pressed + and released. + +Optional Properties specific to linux: +- linux,keypad-no-autorepeat: do no enable autorepeat feature. +- linux,keypad-wakeup: use any event on keypad as wakeup event. + + +Example: + keypad@100A0000 { + compatible = "samsung,s5pv210-keypad"; + reg = <0x100A0000 0x100>; + interrupts = <173>; + samsung,keypad-num-rows = <2>; + samsung,keypad-num-columns = <8>; + linux,input-no-autorepeat; + linux,input-wakeup; + + row-gpios = <&gpx2 0 3 3 0 + &gpx2 1 3 3 0>; + + col-gpios = <&gpx1 0 3 0 0 + &gpx1 1 3 0 0 + &gpx1 2 3 0 0 + &gpx1 3 3 0 0 + &gpx1 4 3 0 0 + &gpx1 5 3 0 0 + &gpx1 6 3 0 0 + &gpx1 7 3 0 0>; + + key_1 { + keypad,row = <0>; + keypad,column = <3>; + linux,code = <2>; + }; + + key_2 { + keypad,row = <0>; + keypad,column = <4>; + linux,code = <3>; + }; + + key_3 { + keypad,row = <0>; + keypad,column = <5>; + linux,code = <4>; + }; + }; diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index f689f49..8a0060c 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -68,31 +70,26 @@ struct samsung_keypad { wait_queue_head_t wait; bool stopped; int irq; + enum samsung_keypad_type type; unsigned int row_shift; unsigned int rows; unsigned int cols; unsigned int row_state[SAMSUNG_MAX_COLS]; +#ifdef CONFIG_OF + int row_gpios[SAMSUNG_MAX_ROWS]; + int col_gpios[SAMSUNG_MAX_COLS]; +#endif unsigned short keycodes[]; }; -static int samsung_keypad_is_s5pv210(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - enum samsung_keypad_type type = - platform_get_device_id(pdev)->driver_data; - - return type == KEYPAD_TYPE_S5PV210; -} - static void samsung_keypad_scan(struct samsung_keypad *keypad, unsigned int *row_state) { - struct device *dev = keypad->input_dev->dev.parent; unsigned int col; unsigned int val; for (col = 0; col < keypad->cols; col++) { - if (samsung_keypad_is_s5pv210(dev)) { + if (keypad->type == KEYPAD_TYPE_S5PV210) { val = S5PV210_KEYIFCOLEN_MASK; val &= ~(1 << col) << 8; } else { @@ -235,6 +232,126 @@ static void samsung_keypad_close(struct input_dev *input_dev) samsung_keypad_stop(keypad); } +#ifdef CONFIG_OF +static struct samsung_keypad_platdata *samsung_keypad_parse_dt( + struct device *dev) +{ + struct samsung_keypad_platdata *pdata; + struct matrix_keymap_data *keymap_data; + uint32_t *keymap, num_rows = 0, num_cols = 0; + struct device_node *np = dev->of_node, *key_np; + unsigned int key_count = 0; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(dev, "could not allocate memory for platform data\n"); + return NULL; + } + + of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows); + of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols); + if (!num_rows || !num_cols) { + dev_err(dev, "number of keypad rows/columns not specified\n"); + return NULL; + } + pdata->rows = num_rows; + pdata->cols = num_cols; + + keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL); + if (!keymap_data) { + dev_err(dev, "could not allocate memory for keymap data\n"); + return NULL; + } + pdata->keymap_data = keymap_data; + + for_each_child_of_node(np, key_np) + key_count++; + + keymap_data->keymap_size = key_count; + keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); + if (!keymap) { + dev_err(dev, "could not allocate memory for keymap\n"); + return NULL; + } + keymap_data->keymap = keymap; + + for_each_child_of_node(np, key_np) { + u32 row, col, key_code; + of_property_read_u32(key_np, "keypad,row", &row); + of_property_read_u32(key_np, "keypad,column", &col); + of_property_read_u32(key_np, "linux,code", &key_code); + *keymap++ = KEY(row, col, key_code); + } + + if (of_get_property(np, "linux,input-no-autorepeat", NULL)) + pdata->no_autorepeat = true; + if (of_get_property(np, "linux,input-wakeup", NULL)) + pdata->wakeup = true; + + return pdata; +} + +static void samsung_keypad_parse_dt_gpio(struct device *dev, + struct samsung_keypad *keypad) +{ + struct device_node *np = dev->of_node; + int gpio, ret, row, col; + + for (row = 0; row < keypad->rows; row++) { + gpio = of_get_named_gpio(np, "row-gpios", row); + keypad->row_gpios[row] = gpio; + if (!gpio_is_valid(gpio)) { + dev_err(dev, "keypad row[%d]: invalid gpio %d\n", + row, gpio); + continue; + } + + ret = gpio_request(gpio, "keypad-row"); + if (ret) + dev_err(dev, "keypad row[%d] gpio request failed\n", + row); + } + + for (col = 0; col < keypad->cols; col++) { + gpio = of_get_named_gpio(np, "col-gpios", col); + keypad->col_gpios[col] = gpio; + if (!gpio_is_valid(gpio)) { + dev_err(dev, "keypad column[%d]: invalid gpio %d\n", + col, gpio); + continue; + } + + ret = gpio_request(gpio, "keypad-col"); + if (ret) + dev_err(dev, "keypad column[%d] gpio request failed\n", + col); + } +} + +static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad) +{ + int cnt; + + for (cnt = 0; cnt < keypad->rows; cnt++) + if (gpio_is_valid(keypad->row_gpios[cnt])) + gpio_free(keypad->row_gpios[cnt]); + + for (cnt = 0; cnt < keypad->cols; cnt++) + if (gpio_is_valid(keypad->col_gpios[cnt])) + gpio_free(keypad->col_gpios[cnt]); +} +#else +static +struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) +{ + return NULL; +} + +static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad) +{ +} +#endif + static int __devinit samsung_keypad_probe(struct platform_device *pdev) { const struct samsung_keypad_platdata *pdata; @@ -246,7 +363,10 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) unsigned int keymap_size; int error; - pdata = pdev->dev.platform_data; + if (pdev->dev.of_node) + pdata = samsung_keypad_parse_dt(&pdev->dev); + else + pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; @@ -303,6 +423,16 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) keypad->cols = pdata->cols; init_waitqueue_head(&keypad->wait); + if (pdev->dev.of_node) { +#ifdef CONFIG_OF + samsung_keypad_parse_dt_gpio(&pdev->dev, keypad); + keypad->type = of_device_is_compatible(pdev->dev.of_node, + "samsung,s5pv210-keypad"); +#endif + } else { + keypad->type = platform_get_device_id(pdev)->driver_data; + } + input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; @@ -343,12 +473,19 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); + + if (pdev->dev.of_node) { + devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); + devm_kfree(&pdev->dev, (void *)pdata->keymap_data); + devm_kfree(&pdev->dev, (void *)pdata); + } return 0; err_free_irq: free_irq(keypad->irq, keypad); err_put_clk: clk_put(keypad->clk); + samsung_keypad_dt_gpio_free(keypad); err_unmap_base: iounmap(keypad->base); err_free_mem: @@ -374,6 +511,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev) free_irq(keypad->irq, keypad); clk_put(keypad->clk); + samsung_keypad_dt_gpio_free(keypad); iounmap(keypad->base); kfree(keypad); @@ -447,6 +585,17 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = { }; #endif +#ifdef CONFIG_OF +static const struct of_device_id samsung_keypad_dt_match[] = { + { .compatible = "samsung,s3c6410-keypad" }, + { .compatible = "samsung,s5pv210-keypad" }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match); +#else +#define samsung_keypad_dt_match NULL +#endif + static struct platform_device_id samsung_keypad_driver_ids[] = { { .name = "samsung-keypad", @@ -465,6 +614,7 @@ static struct platform_driver samsung_keypad_driver = { .driver = { .name = "samsung-keypad", .owner = THIS_MODULE, + .of_match_table = samsung_keypad_dt_match, #ifdef CONFIG_PM .pm = &samsung_keypad_pm_ops, #endif -- cgit v0.10.2 From 39ce4084a604a3ef0e2836e074c02bbbcc7c1509 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 Oct 2011 14:49:04 +0200 Subject: rtc: rtc-s3c: Add device tree support Add device tree based discovery support for Samsung's rtc controller. Cc: Ben Dooks Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.txt b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt new file mode 100644 index 0000000..90ec45f --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt @@ -0,0 +1,20 @@ +* Samsung's S3C Real Time Clock controller + +Required properties: +- compatible: should be one of the following. + * "samsung,s3c2410-rtc" - for controllers compatible with s3c2410 rtc. + * "samsung,s3c6410-rtc" - for controllers compatible with s3c6410 rtc. +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: Two interrupt numbers to the cpu should be specified. First + interrupt number is the rtc alarm interupt and second interrupt number + is the rtc tick interrupt. The number of cells representing a interrupt + depends on the parent interrupt controller. + +Example: + + rtc@10070000 { + compatible = "samsung,s3c6410-rtc"; + reg = <0x10070000 0x100>; + interrupts = <44 0 45 0>; + }; diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 5b979d9..175067a 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -507,7 +508,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) goto err_nortc; } - s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; +#ifdef CONFIG_OF + if (pdev->dev.of_node) + s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node, + "samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410; + else +#endif + s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; /* Check RTC Time */ @@ -629,6 +636,17 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif +#ifdef CONFIG_OF +static const struct of_device_id s3c_rtc_dt_match[] = { + { .compatible = "samsung,s3c2410-rtc" }, + { .compatible = "samsung,s3c6410-rtc" }, + {}, +}; +MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); +#else +#define s3c_rtc_dt_match NULL +#endif + static struct platform_device_id s3c_rtc_driver_ids[] = { { .name = "s3c2410-rtc", @@ -651,6 +669,7 @@ static struct platform_driver s3c_rtc_driver = { .driver = { .name = "s3c-rtc", .owner = THIS_MODULE, + .of_match_table = s3c_rtc_dt_match, }, }; -- cgit v0.10.2 From 6b5ab4f442e32f248b6fad29aafd1d5153f4dbd3 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sun, 6 Nov 2011 21:54:27 +0530 Subject: ARM: EXYNOS: Add Exynos4 device tree enabled board file Add a new EXYNOS4 compatible device tree enabled board file. Boards based on the EXYNOS4 family of SoC's can use this as the machine/board file. When using this machine fike, a corresponding device tree blob which describes the board's properties should be supplied at boot time to the kernel. Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/Documentation/devicetree/bindings/arm/insignal-boards.txt b/Documentation/devicetree/bindings/arm/insignal-boards.txt new file mode 100644 index 0000000..524c3dc --- /dev/null +++ b/Documentation/devicetree/bindings/arm/insignal-boards.txt @@ -0,0 +1,8 @@ +* Insignal's Exynos4210 based Origen evaluation board + +Origen low-cost evaluation board is based on Samsung's Exynos4210 SoC. + +Required root node properties: + - compatible = should be one or more of the following. + (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board. + (b) "samsung,exynos4210" - for boards based on Exynos4210 SoC. diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt new file mode 100644 index 0000000..0bf68be --- /dev/null +++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt @@ -0,0 +1,8 @@ +* Samsung's Exynos4210 based SMDKV310 evaluation board + +SMDKV310 evaluation board is based on Samsung's Exynos4210 SoC. + +Required root node properties: + - compatible = should be one or more of the following. + (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board. + (b) "samsung,exynos4210" - for boards based on Exynos4210 SoC. diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 68e4ab0..0afcc3b 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -337,6 +337,20 @@ config MACH_SMDK4412 Machine support for Samsung SMDK4412 endif +comment "Flattened Device Tree based board for Exynos4 based SoC" + +config MACH_EXYNOS4_DT + bool "Samsung Exynos4 Machine using device tree" + select CPU_EXYNOS4210 + select USE_OF + select ARM_AMBA + select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD + help + Machine support for Samsung Exynos4 machine with device tree enabled. + Select this if a fdt blob is available for the Exynos4 SoC based board. + Note: This is under development and not all peripherals can be supported + with this machine file. + if ARCH_EXYNOS4 comment "Configuration for HSMMC 8-bit bus width" diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index cb6fb0e..8d85ae6 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -37,6 +37,8 @@ obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o +obj-$(CONFIG_MACH_EXYNOS4_DT) += mach-exynos4-dt.o + # device support obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c new file mode 100644 index 0000000..85fa027 --- /dev/null +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -0,0 +1,85 @@ +/* + * Samsung's Exynos4210 flattened device tree enabled machine + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Copyright (c) 2010-2011 Linaro Ltd. + * www.linaro.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include + +#include +#include + +#include +#include +#include + +/* + * The following lookup table is used to override device names when devices + * are registered from device tree. This is temporarily added to enable + * device tree support addition for the Exynos4 architecture. + * + * For drivers that require platform data to be provided from the machine + * file, a platform data pointer can also be supplied along with the + * devices names. Usually, the platform data elements that cannot be parsed + * from the device tree by the drivers (example: function pointers) are + * supplied. But it should be noted that this is a temporary mechanism and + * at some point, the drivers should be capable of parsing all the platform + * data from the device tree. + */ +static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = { + OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0, + "exynos4210-uart.0", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1, + "exynos4210-uart.1", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2, + "exynos4210-uart.2", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3, + "exynos4210-uart.3", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0), + "exynos4-sdhci.0", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1), + "exynos4-sdhci.1", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2), + "exynos4-sdhci.2", NULL), + OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3), + "exynos4-sdhci.3", NULL), + OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0), + "s3c2440-i2c.0", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL), + {}, +}; + +static void __init exynos4210_dt_map_io(void) +{ + s5p_init_io(NULL, 0, S5P_VA_CHIPID); + s3c24xx_init_clocks(24000000); +} + +static void __init exynos4210_dt_machine_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, + exynos4210_auxdata_lookup, NULL); +} + +static char const *exynos4210_dt_compat[] __initdata = { + "samsung,exynos4210", + NULL +}; + +DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") + /* Maintainer: Thomas Abraham */ + .init_irq = exynos4_init_irq, + .map_io = exynos4210_dt_map_io, + .init_machine = exynos4210_dt_machine_init, + .timer = &exynos4_timer, + .dt_compat = exynos4210_dt_compat, +MACHINE_END -- cgit v0.10.2 From 0561ceabd0f13871900d116278fe9268aeb714d1 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 2 Nov 2011 19:31:15 +0900 Subject: ARM: dts: Add intial dts file for EXYNOS4210 SoC, SMDKV310 and ORIGEN Add initial dts file for EXYNOS4210 SoC. This dts file describes the SoC specific devices and properties. Along with this, add dts file for Samsung's SMDKV310 board and Insignal's ORIGEN board which uses the EXYNOS4210 dts file and extends it to describe the board specific properties. Signed-off-by: Thomas Abraham Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts new file mode 100644 index 0000000..b8c4763 --- /dev/null +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -0,0 +1,137 @@ +/* + * Samsung's Exynos4210 based Origen board device tree source + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Copyright (c) 2010-2011 Linaro Ltd. + * www.linaro.org + * + * Device tree source file for Insignal's Origen board which is based on + * Samsung's Exynos4210 SoC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +/include/ "exynos4210.dtsi" + +/ { + model = "Insignal Origen evaluation board based on Exynos4210"; + compatible = "insignal,origen", "samsung,exynos4210"; + + memory { + reg = <0x40000000 0x40000000>; + }; + + chosen { + bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc"; + }; + + sdhci@12530000 { + samsung,sdhci-bus-width = <4>; + linux,mmc_cap_4_bit_data; + samsung,sdhci-cd-internal; + gpio-cd = <&gpk2 2 2 3 3>; + gpios = <&gpk2 0 2 0 3>, + <&gpk2 1 2 0 3>, + <&gpk2 3 2 3 3>, + <&gpk2 4 2 3 3>, + <&gpk2 5 2 3 3>, + <&gpk2 6 2 3 3>; + }; + + sdhci@12510000 { + samsung,sdhci-bus-width = <4>; + linux,mmc_cap_4_bit_data; + samsung,sdhci-cd-internal; + gpio-cd = <&gpk0 2 2 3 3>; + gpios = <&gpk0 0 2 0 3>, + <&gpk0 1 2 0 3>, + <&gpk0 3 2 3 3>, + <&gpk0 4 2 3 3>, + <&gpk0 5 2 3 3>, + <&gpk0 6 2 3 3>; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + up { + label = "Up"; + gpios = <&gpx2 0 0 0 2>; + linux,code = <103>; + }; + + down { + label = "Down"; + gpios = <&gpx2 1 0 0 2>; + linux,code = <108>; + }; + + back { + label = "Back"; + gpios = <&gpx1 7 0 0 2>; + linux,code = <158>; + }; + + home { + label = "Home"; + gpios = <&gpx1 6 0 0 2>; + linux,code = <102>; + }; + + menu { + label = "Menu"; + gpios = <&gpx1 5 0 0 2>; + linux,code = <139>; + }; + }; + + keypad@100A0000 { + status = "disabled"; + }; + + sdhci@12520000 { + status = "disabled"; + }; + + sdhci@12540000 { + status = "disabled"; + }; + + i2c@13860000 { + status = "disabled"; + }; + + i2c@13870000 { + status = "disabled"; + }; + + i2c@13880000 { + status = "disabled"; + }; + + i2c@13890000 { + status = "disabled"; + }; + + i2c@138A0000 { + status = "disabled"; + }; + + i2c@138B0000 { + status = "disabled"; + }; + + i2c@138C0000 { + status = "disabled"; + }; + + i2c@138D0000 { + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts new file mode 100644 index 0000000..27afc8e --- /dev/null +++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -0,0 +1,182 @@ +/* + * Samsung's Exynos4210 based SMDKV310 board device tree source + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Copyright (c) 2010-2011 Linaro Ltd. + * www.linaro.org + * + * Device tree source file for Samsung's SMDKV310 board which is based on + * Samsung's Exynos4210 SoC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +/include/ "exynos4210.dtsi" + +/ { + model = "Samsung smdkv310 evaluation board based on Exynos4210"; + compatible = "samsung,smdkv310", "samsung,exynos4210"; + + memory { + reg = <0x40000000 0x80000000>; + }; + + chosen { + bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc"; + }; + + sdhci@12530000 { + samsung,sdhci-bus-width = <4>; + linux,mmc_cap_4_bit_data; + samsung,sdhci-cd-internal; + gpio-cd = <&gpk2 2 2 3 3>; + gpios = <&gpk2 0 2 0 3>, + <&gpk2 1 2 0 3>, + <&gpk2 3 2 3 3>, + <&gpk2 4 2 3 3>, + <&gpk2 5 2 3 3>, + <&gpk2 6 2 3 3>; + }; + + keypad@100A0000 { + samsung,keypad-num-rows = <2>; + samsung,keypad-num-columns = <8>; + linux,keypad-no-autorepeat; + linux,keypad-wakeup; + + row-gpios = <&gpx2 0 3 3 0>, + <&gpx2 1 3 3 0>; + + col-gpios = <&gpx1 0 3 0 0>, + <&gpx1 1 3 0 0>, + <&gpx1 2 3 0 0>, + <&gpx1 3 3 0 0>, + <&gpx1 4 3 0 0>, + <&gpx1 5 3 0 0>, + <&gpx1 6 3 0 0>, + <&gpx1 7 3 0 0>; + + key_1 { + keypad,row = <0>; + keypad,column = <3>; + linux,code = <2>; + }; + + key_2 { + keypad,row = <0>; + keypad,column = <4>; + linux,code = <3>; + }; + + key_3 { + keypad,row = <0>; + keypad,column = <5>; + linux,code = <4>; + }; + + key_4 { + keypad,row = <0>; + keypad,column = <6>; + linux,code = <5>; + }; + + key_5 { + keypad,row = <0>; + keypad,column = <7>; + linux,code = <6>; + }; + + key_a { + keypad,row = <1>; + keypad,column = <3>; + linux,code = <30>; + }; + + key_b { + keypad,row = <1>; + keypad,column = <4>; + linux,code = <48>; + }; + + key_c { + keypad,row = <1>; + keypad,column = <5>; + linux,code = <46>; + }; + + key_d { + keypad,row = <1>; + keypad,column = <6>; + linux,code = <32>; + }; + + key_e { + keypad,row = <1>; + keypad,column = <7>; + linux,code = <18>; + }; + }; + + i2c@13860000 { + #address-cells = <1>; + #size-cells = <0>; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <20000>; + gpios = <&gpd1 0 2 3 0>, + <&gpd1 1 2 3 0>; + + eeprom@50 { + compatible = "samsung,24ad0xd1"; + reg = <0x50>; + }; + + eeprom@52 { + compatible = "samsung,24ad0xd1"; + reg = <0x52>; + }; + }; + + sdhci@12510000 { + status = "disabled"; + }; + + sdhci@12520000 { + status = "disabled"; + }; + + sdhci@12540000 { + status = "disabled"; + }; + + i2c@13870000 { + status = "disabled"; + }; + + i2c@13880000 { + status = "disabled"; + }; + + i2c@13890000 { + status = "disabled"; + }; + + i2c@138A0000 { + status = "disabled"; + }; + + i2c@138B0000 { + status = "disabled"; + }; + + i2c@138C0000 { + status = "disabled"; + }; + + i2c@138D0000 { + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi new file mode 100644 index 0000000..63d7578 --- /dev/null +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -0,0 +1,397 @@ +/* + * Samsung's Exynos4210 SoC device tree source + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Copyright (c) 2010-2011 Linaro Ltd. + * www.linaro.org + * + * Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210 + * based board files can include this file and provide values for board specfic + * bindings. + * + * Note: This file does not include device nodes for all the controllers in + * Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional + * nodes can be added to this file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/include/ "skeleton.dtsi" + +/ { + compatible = "samsung,exynos4210"; + interrupt-parent = <&gic>; + + gic:interrupt-controller@10490000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x10490000 0x1000>, <0x10480000 0x100>; + }; + + watchdog@10060000 { + compatible = "samsung,s3c2410-wdt"; + reg = <0x10060000 0x100>; + interrupts = <0 43 0>; + }; + + rtc@10070000 { + compatible = "samsung,s3c6410-rtc"; + reg = <0x10070000 0x100>; + interrupts = <0 44 0>, <0 45 0>; + }; + + keypad@100A0000 { + compatible = "samsung,s5pv210-keypad"; + reg = <0x100A0000 0x100>; + interrupts = <0 109 0>; + }; + + sdhci@12510000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12510000 0x100>; + interrupts = <0 73 0>; + }; + + sdhci@12520000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12520000 0x100>; + interrupts = <0 74 0>; + }; + + sdhci@12530000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12530000 0x100>; + interrupts = <0 75 0>; + }; + + sdhci@12540000 { + compatible = "samsung,exynos4210-sdhci"; + reg = <0x12540000 0x100>; + interrupts = <0 76 0>; + }; + + serial@13800000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13800000 0x100>; + interrupts = <0 52 0>; + }; + + serial@13810000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13810000 0x100>; + interrupts = <0 53 0>; + }; + + serial@13820000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13820000 0x100>; + interrupts = <0 54 0>; + }; + + serial@13830000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13830000 0x100>; + interrupts = <0 55 0>; + }; + + i2c@13860000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x13860000 0x100>; + interrupts = <0 58 0>; + }; + + i2c@13870000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x13870000 0x100>; + interrupts = <0 59 0>; + }; + + i2c@13880000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x13880000 0x100>; + interrupts = <0 60 0>; + }; + + i2c@13890000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x13890000 0x100>; + interrupts = <0 61 0>; + }; + + i2c@138A0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x138A0000 0x100>; + interrupts = <0 62 0>; + }; + + i2c@138B0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x138B0000 0x100>; + interrupts = <0 63 0>; + }; + + i2c@138C0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x138C0000 0x100>; + interrupts = <0 64 0>; + }; + + i2c@138D0000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x138D0000 0x100>; + interrupts = <0 65 0>; + }; + + amba { + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus"; + interrupt-parent = <&gic>; + ranges; + + pdma0: pdma@12680000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x12680000 0x1000>; + interrupts = <0 35 0>; + }; + + pdma1: pdma@12690000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x12690000 0x1000>; + interrupts = <0 36 0>; + }; + }; + + gpio-controllers { + #address-cells = <1>; + #size-cells = <1>; + gpio-controller; + ranges; + + gpa0: gpio-controller@11400000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400000 0x20>; + #gpio-cells = <4>; + }; + + gpa1: gpio-controller@11400020 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400020 0x20>; + #gpio-cells = <4>; + }; + + gpb: gpio-controller@11400040 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400040 0x20>; + #gpio-cells = <4>; + }; + + gpc0: gpio-controller@11400060 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400060 0x20>; + #gpio-cells = <4>; + }; + + gpc1: gpio-controller@11400080 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400080 0x20>; + #gpio-cells = <4>; + }; + + gpd0: gpio-controller@114000A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114000A0 0x20>; + #gpio-cells = <4>; + }; + + gpd1: gpio-controller@114000C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114000C0 0x20>; + #gpio-cells = <4>; + }; + + gpe0: gpio-controller@114000E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114000E0 0x20>; + #gpio-cells = <4>; + }; + + gpe1: gpio-controller@11400100 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400100 0x20>; + #gpio-cells = <4>; + }; + + gpe2: gpio-controller@11400120 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400120 0x20>; + #gpio-cells = <4>; + }; + + gpe3: gpio-controller@11400140 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400140 0x20>; + #gpio-cells = <4>; + }; + + gpe4: gpio-controller@11400160 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400160 0x20>; + #gpio-cells = <4>; + }; + + gpf0: gpio-controller@11400180 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11400180 0x20>; + #gpio-cells = <4>; + }; + + gpf1: gpio-controller@114001A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114001A0 0x20>; + #gpio-cells = <4>; + }; + + gpf2: gpio-controller@114001C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114001C0 0x20>; + #gpio-cells = <4>; + }; + + gpf3: gpio-controller@114001E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x114001E0 0x20>; + #gpio-cells = <4>; + }; + + gpj0: gpio-controller@11000000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000000 0x20>; + #gpio-cells = <4>; + }; + + gpj1: gpio-controller@11000020 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000020 0x20>; + #gpio-cells = <4>; + }; + + gpk0: gpio-controller@11000040 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000040 0x20>; + #gpio-cells = <4>; + }; + + gpk1: gpio-controller@11000060 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000060 0x20>; + #gpio-cells = <4>; + }; + + gpk2: gpio-controller@11000080 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000080 0x20>; + #gpio-cells = <4>; + }; + + gpk3: gpio-controller@110000A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x110000A0 0x20>; + #gpio-cells = <4>; + }; + + gpl0: gpio-controller@110000C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x110000C0 0x20>; + #gpio-cells = <4>; + }; + + gpl1: gpio-controller@110000E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x110000E0 0x20>; + #gpio-cells = <4>; + }; + + gpl2: gpio-controller@11000100 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000100 0x20>; + #gpio-cells = <4>; + }; + + gpy0: gpio-controller@11000120 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000120 0x20>; + #gpio-cells = <4>; + }; + + gpy1: gpio-controller@11000140 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000140 0x20>; + #gpio-cells = <4>; + }; + + gpy2: gpio-controller@11000160 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000160 0x20>; + #gpio-cells = <4>; + }; + + gpy3: gpio-controller@11000180 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000180 0x20>; + #gpio-cells = <4>; + }; + + gpy4: gpio-controller@110001A0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x110001A0 0x20>; + #gpio-cells = <4>; + }; + + gpy5: gpio-controller@110001C0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x110001C0 0x20>; + #gpio-cells = <4>; + }; + + gpy6: gpio-controller@110001E0 { + compatible = "samsung,exynos4-gpio"; + reg = <0x110001E0 0x20>; + #gpio-cells = <4>; + }; + + gpx0: gpio-controller@11000C00 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000C00 0x20>; + #gpio-cells = <4>; + }; + + gpx1: gpio-controller@11000C20 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000C20 0x20>; + #gpio-cells = <4>; + }; + + gpx2: gpio-controller@11000C40 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000C40 0x20>; + #gpio-cells = <4>; + }; + + gpx3: gpio-controller@11000C60 { + compatible = "samsung,exynos4-gpio"; + reg = <0x11000C60 0x20>; + #gpio-cells = <4>; + }; + + gpz: gpio-controller@03860000 { + compatible = "samsung,exynos4-gpio"; + reg = <0x03860000 0x20>; + #gpio-cells = <4>; + }; + }; +}; -- cgit v0.10.2 From a60879e7ca17ea41bacd57e3cb2b56e48135f7a3 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Mon, 24 Oct 2011 17:05:24 +0200 Subject: ARM: SAMSUNG: Remove SDHCI bus clocks from platform data The bus clocks previously sent through platform data to SDHCI controller are removed. Signed-off-by: Rajeshwari Shinde Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 8d85ae6..57e5296 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -58,6 +58,5 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o -obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o diff --git a/arch/arm/mach-exynos/setup-sdhci.c b/arch/arm/mach-exynos/setup-sdhci.c deleted file mode 100644 index 92937b4..0000000 --- a/arch/arm/mach-exynos/setup-sdhci.c +++ /dev/null @@ -1,22 +0,0 @@ -/* linux/arch/arm/mach-exynos4/setup-sdhci.c - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include - -/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ - -char *exynos4_hsmmc_clksrcs[4] = { - [0] = NULL, - [1] = NULL, - [2] = "sclk_mmc", /* mmc_bus */ - [3] = NULL, -}; diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile index 7b805b2..ca0cd22 100644 --- a/arch/arm/mach-s3c2416/Makefile +++ b/arch/arm/mach-s3c2416/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_S3C2416_PM) += pm.o #obj-$(CONFIG_S3C2416_DMA) += dma.o # Device setup -obj-$(CONFIG_S3C2416_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o # Machine support diff --git a/arch/arm/mach-s3c2416/setup-sdhci.c b/arch/arm/mach-s3c2416/setup-sdhci.c deleted file mode 100644 index cee5395..0000000 --- a/arch/arm/mach-s3c2416/setup-sdhci.c +++ /dev/null @@ -1,24 +0,0 @@ -/* linux/arch/arm/mach-s3c2416/setup-sdhci.c - * - * Copyright 2010 Promwad Innovation Company - * Yauhen Kharuzhy - * - * S3C2416 - Helper functions for settign up SDHCI device(s) (HSMMC) - * - * Based on mach-s3c64xx/setup-sdhci.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include - -/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ - -char *s3c2416_hsmmc_clksrcs[4] = { - [0] = "hsmmc", - [1] = "hsmmc", - [2] = "hsmmc-if", - /* [3] = "48m", - note not successfully used yet */ -}; diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index cfc0b99..e32093c 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o -obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o diff --git a/arch/arm/mach-s3c64xx/setup-sdhci.c b/arch/arm/mach-s3c64xx/setup-sdhci.c deleted file mode 100644 index c75a71b..0000000 --- a/arch/arm/mach-s3c64xx/setup-sdhci.c +++ /dev/null @@ -1,24 +0,0 @@ -/* linux/arch/arm/mach-s3c64xx/setup-sdhci.c - * - * Copyright 2008 Simtec Electronics - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * S3C6400/S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include - -/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ - -char *s3c64xx_hsmmc_clksrcs[4] = { - [0] = "hsmmc", - [1] = "hsmmc", - [2] = "mmc_bus", - /* [3] = "48m", - note not successfully used yet */ -}; diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index a5e6e60..2320e54 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S5PC100_SETUP_KEYPAD) += setup-keypad.o -obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o # device support diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c deleted file mode 100644 index 6418c6e..0000000 --- a/arch/arm/mach-s5pc100/setup-sdhci.c +++ /dev/null @@ -1,23 +0,0 @@ -/* linux/arch/arm/mach-s5pc100/setup-sdhci.c - * - * Copyright 2008 Samsung Electronics - * - * S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC) - * - * Based on mach-s3c6410/setup-sdhci.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include - -/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ - -char *s5pc100_hsmmc_clksrcs[4] = { - [0] = "hsmmc", /* HCLK */ - /* [1] = "hsmmc", - duplicate HCLK entry */ - [2] = "sclk_mmc", /* mmc_bus */ - /* [3] = "48m", - note not successfully used yet */ -}; diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 009fbe5..53c346a 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -35,5 +35,4 @@ obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o -obj-$(CONFIG_S5PV210_SETUP_SDHCI) += setup-sdhci.o obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c deleted file mode 100644 index 6b8ccc4..0000000 --- a/arch/arm/mach-s5pv210/setup-sdhci.c +++ /dev/null @@ -1,22 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/setup-sdhci.c - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5PV210 - Helper functions for settign up SDHCI device(s) (HSMMC) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include - -/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ - -char *s5pv210_hsmmc_clksrcs[4] = { - [0] = "hsmmc", /* HCLK */ - /* [1] = "hsmmc", - duplicate HCLK entry */ - [2] = "sclk_mmc", /* mmc_bus */ - /* [3] = NULL, - reserved */ -}; diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index e7b3c75..dcff7dd 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -66,8 +66,6 @@ struct s3c_sdhci_platdata { enum cd_types cd_type; enum clk_types clk_type; - char **clocks; /* set of clock sources */ - int ext_cd_gpio; bool ext_cd_gpio_invert; int (*ext_cd_init)(void (*notify_func)(struct platform_device *, @@ -129,12 +127,9 @@ extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w); /* S3C2416 SDHCI setup */ #ifdef CONFIG_S3C2416_SETUP_SDHCI -extern char *s3c2416_hsmmc_clksrcs[4]; - static inline void s3c2416_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio; #endif /* CONFIG_S3C_DEV_HSMMC */ } @@ -142,7 +137,6 @@ static inline void s3c2416_default_sdhci0(void) static inline void s3c2416_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio; #endif /* CONFIG_S3C_DEV_HSMMC1 */ } @@ -155,12 +149,9 @@ static inline void s3c2416_default_sdhci1(void) { } /* S3C64XX SDHCI setup */ #ifdef CONFIG_S3C64XX_SETUP_SDHCI -extern char *s3c64xx_hsmmc_clksrcs[4]; - static inline void s3c6400_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; #endif } @@ -168,7 +159,6 @@ static inline void s3c6400_default_sdhci0(void) static inline void s3c6400_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; #endif } @@ -176,7 +166,6 @@ static inline void s3c6400_default_sdhci1(void) static inline void s3c6400_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; #endif } @@ -184,7 +173,6 @@ static inline void s3c6400_default_sdhci2(void) static inline void s3c6410_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; #endif } @@ -192,7 +180,6 @@ static inline void s3c6410_default_sdhci0(void) static inline void s3c6410_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; #endif } @@ -200,7 +187,6 @@ static inline void s3c6410_default_sdhci1(void) static inline void s3c6410_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; #endif } @@ -218,12 +204,9 @@ static inline void s3c6400_default_sdhci2(void) { } /* S5PC100 SDHCI setup */ #ifdef CONFIG_S5PC100_SETUP_SDHCI -extern char *s5pc100_hsmmc_clksrcs[4]; - static inline void s5pc100_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio; #endif } @@ -231,7 +214,6 @@ static inline void s5pc100_default_sdhci0(void) static inline void s5pc100_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio; #endif } @@ -239,7 +221,6 @@ static inline void s5pc100_default_sdhci1(void) static inline void s5pc100_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio; #endif } @@ -254,12 +235,9 @@ static inline void s5pc100_default_sdhci2(void) { } /* S5PV210 SDHCI setup */ #ifdef CONFIG_S5PV210_SETUP_SDHCI -extern char *s5pv210_hsmmc_clksrcs[4]; - static inline void s5pv210_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio; #endif } @@ -267,7 +245,6 @@ static inline void s5pv210_default_sdhci0(void) static inline void s5pv210_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio; #endif } @@ -275,7 +252,6 @@ static inline void s5pv210_default_sdhci1(void) static inline void s5pv210_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio; #endif } @@ -283,7 +259,6 @@ static inline void s5pv210_default_sdhci2(void) static inline void s5pv210_default_sdhci3(void) { #ifdef CONFIG_S3C_DEV_HSMMC3 - s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs; s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio; #endif } @@ -298,12 +273,9 @@ static inline void s5pv210_default_sdhci3(void) { } /* EXYNOS4 SDHCI setup */ #ifdef CONFIG_EXYNOS4_SETUP_SDHCI -extern char *exynos4_hsmmc_clksrcs[4]; - static inline void exynos4_default_sdhci0(void) { #ifdef CONFIG_S3C_DEV_HSMMC - s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs; s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio; #endif } @@ -311,7 +283,6 @@ static inline void exynos4_default_sdhci0(void) static inline void exynos4_default_sdhci1(void) { #ifdef CONFIG_S3C_DEV_HSMMC1 - s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs; s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio; #endif } @@ -319,7 +290,6 @@ static inline void exynos4_default_sdhci1(void) static inline void exynos4_default_sdhci2(void) { #ifdef CONFIG_S3C_DEV_HSMMC2 - s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs; s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio; #endif } @@ -327,7 +297,6 @@ static inline void exynos4_default_sdhci2(void) static inline void exynos4_default_sdhci3(void) { #ifdef CONFIG_S3C_DEV_HSMMC3 - s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs; s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio; #endif } -- cgit v0.10.2 From a361d10a2b490812b051433b1aad5b4351372597 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Mon, 24 Oct 2011 17:05:58 +0200 Subject: ARM: SAMSUNG: Add lookup of sdhci-s3c clocks using generic names Add support for lookup of sdhci-s3c controller clocks using generic names for s3c2416, s3c64xx, s5pc100, s5pv210 and exynos4 SoC's. Signed-off-by: Rajeshwari Shinde [kgene.kim@samsung.com: fixed trailing whitespace] Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c index 7dee869..5d8d483 100644 --- a/arch/arm/mach-exynos/clock.c +++ b/arch/arm/mach-exynos/clock.c @@ -1156,42 +1156,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 }, }, { .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.0", - .parent = &clk_dout_mmc0.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 0), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.1", - .parent = &clk_dout_mmc1.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 4), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.2", - .parent = &clk_dout_mmc2.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 8), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.3", - .parent = &clk_dout_mmc3.clk, - .enable = exynos4_clksrc_mask_fsys_ctrl, - .ctrlbit = (1 << 12), - }, - .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 }, - }, { - .clk = { .name = "sclk_dwmmc", .parent = &clk_dout_mmc4.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, @@ -1249,6 +1213,50 @@ static struct clksrc_clk clk_sclk_uart3 = { .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 }, }; +static struct clksrc_clk clk_sclk_mmc0 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.0", + .parent = &clk_dout_mmc0.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 0), + }, + .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 }, +}; + +static struct clksrc_clk clk_sclk_mmc1 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.1", + .parent = &clk_dout_mmc1.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 4), + }, + .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 }, +}; + +static struct clksrc_clk clk_sclk_mmc2 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.2", + .parent = &clk_dout_mmc2.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 8), + }, + .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 }, +}; + +static struct clksrc_clk clk_sclk_mmc3 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.3", + .parent = &clk_dout_mmc3.clk, + .enable = exynos4_clksrc_mask_fsys_ctrl, + .ctrlbit = (1 << 12), + }, + .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 }, +}; + /* Clock initialization code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -1293,6 +1301,10 @@ static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uart1, &clk_sclk_uart2, &clk_sclk_uart3, + &clk_sclk_mmc0, + &clk_sclk_mmc1, + &clk_sclk_mmc2, + &clk_sclk_mmc3, }; static struct clk_lookup exynos4_clk_lookup[] = { @@ -1300,6 +1312,10 @@ static struct clk_lookup exynos4_clk_lookup[] = { CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk), CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk), CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk), CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0), CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1), }; diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c index afbbe8b..59f54d1 100644 --- a/arch/arm/mach-s3c2416/clock.c +++ b/arch/arm/mach-s3c2416/clock.c @@ -90,39 +90,38 @@ static struct clksrc_clk hsmmc_div[] = { }, }; -static struct clksrc_clk hsmmc_mux[] = { - [0] = { - .clk = { - .name = "hsmmc-if", - .devname = "s3c-sdhci.0", - .ctrlbit = (1 << 6), - .enable = s3c2443_clkcon_enable_s, - }, - .sources = &(struct clksrc_sources) { - .nr_sources = 2, - .sources = (struct clk *[]) { - [0] = &hsmmc_div[0].clk, - [1] = NULL, /* to fix */ - }, - }, - .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 }, +static struct clksrc_clk hsmmc_mux0 = { + .clk = { + .name = "hsmmc-if", + .devname = "s3c-sdhci.0", + .ctrlbit = (1 << 6), + .enable = s3c2443_clkcon_enable_s, }, - [1] = { - .clk = { - .name = "hsmmc-if", - .devname = "s3c-sdhci.1", - .ctrlbit = (1 << 12), - .enable = s3c2443_clkcon_enable_s, + .sources = &(struct clksrc_sources) { + .nr_sources = 2, + .sources = (struct clk * []) { + [0] = &hsmmc_div[0].clk, + [1] = NULL, /* to fix */ }, - .sources = &(struct clksrc_sources) { - .nr_sources = 2, - .sources = (struct clk *[]) { - [0] = &hsmmc_div[1].clk, - [1] = NULL, /* to fix */ - }, + }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 }, +}; + +static struct clksrc_clk hsmmc_mux1 = { + .clk = { + .name = "hsmmc-if", + .devname = "s3c-sdhci.1", + .ctrlbit = (1 << 12), + .enable = s3c2443_clkcon_enable_s, + }, + .sources = &(struct clksrc_sources) { + .nr_sources = 2, + .sources = (struct clk * []) { + [0] = &hsmmc_div[1].clk, + [1] = NULL, /* to fix */ }, - .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 }, }, + .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 }, }; static struct clk hsmmc0_clk = { @@ -144,8 +143,14 @@ static struct clksrc_clk *clksrcs[] __initdata = { &hsspi_mux, &hsmmc_div[0], &hsmmc_div[1], - &hsmmc_mux[0], - &hsmmc_mux[1], + &hsmmc_mux0, + &hsmmc_mux1, +}; + +static struct clk_lookup s3c2416_clk_lookup[] = { + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk), }; void __init s3c2416_init_clocks(int xtal) @@ -167,6 +172,7 @@ void __init s3c2416_init_clocks(int xtal) s3c_register_clksrc(clksrcs[ptr], 1); s3c24xx_register_clock(&hsmmc0_clk); + clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup)); s3c_pwmclk_init(); diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 2addd98..415c540 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -243,24 +243,6 @@ static struct clk init_clocks[] = { .enable = s3c64xx_hclk_ctrl, .ctrlbit = S3C_CLKCON_HCLK_UHOST, }, { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC0, - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC1, - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, - }, { .name = "otg", .parent = &clk_h, .enable = s3c64xx_hclk_ctrl, @@ -310,6 +292,29 @@ static struct clk init_clocks[] = { } }; +static struct clk clk_hsmmc0 = { + .name = "hsmmc", + .devname = "s3c-sdhci.0", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_HSMMC0, +}; + +static struct clk clk_hsmmc1 = { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_HSMMC1, +}; + +static struct clk clk_hsmmc2 = { + .name = "hsmmc", + .devname = "s3c-sdhci.2", + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, +}; static struct clk clk_fout_apll = { .name = "fout_apll", @@ -578,36 +583,6 @@ static struct clksrc_sources clkset_camif = { static struct clksrc_clk clksrcs[] = { { .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.0", - .ctrlbit = S3C_CLKCON_SCLK_MMC0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, - }, { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.1", - .ctrlbit = S3C_CLKCON_SCLK_MMC1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, - }, { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.2", - .ctrlbit = S3C_CLKCON_SCLK_MMC2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 }, - .sources = &clkset_spi_mmc, - }, { - .clk = { .name = "usb-bus-host", .ctrlbit = S3C_CLKCON_SCLK_UHOST, .enable = s3c64xx_sclk_ctrl, @@ -697,6 +672,42 @@ static struct clksrc_clk clk_sclk_uclk = { .sources = &clkset_uart, }; +static struct clksrc_clk clk_sclk_mmc0 = { + .clk = { + .name = "mmc_bus", + .devname = "s3c-sdhci.0", + .ctrlbit = S3C_CLKCON_SCLK_MMC0, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 }, + .sources = &clkset_spi_mmc, +}; + +static struct clksrc_clk clk_sclk_mmc1 = { + .clk = { + .name = "mmc_bus", + .devname = "s3c-sdhci.1", + .ctrlbit = S3C_CLKCON_SCLK_MMC1, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 }, + .sources = &clkset_spi_mmc, +}; + +static struct clksrc_clk clk_sclk_mmc2 = { + .clk = { + .name = "mmc_bus", + .devname = "s3c-sdhci.2", + .ctrlbit = S3C_CLKCON_SCLK_MMC2, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 }, + .sources = &clkset_spi_mmc, +}; + /* Clock initialisation code */ static struct clksrc_clk *init_parents[] = { @@ -707,11 +718,26 @@ static struct clksrc_clk *init_parents[] = { static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uclk, + &clk_sclk_mmc0, + &clk_sclk_mmc1, + &clk_sclk_mmc2, +}; + +static struct clk *clk_cdev[] = { + &clk_hsmmc0, + &clk_hsmmc1, + &clk_hsmmc2, }; static struct clk_lookup s3c64xx_clk_lookup[] = { CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) @@ -834,6 +860,10 @@ void __init s3c64xx_register_clocks(unsigned long xtal, s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); + s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); + for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++) + s3c_disable_clocks(clk_cdev[cnt], 1); + s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++) diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 9d644ec..69829ba 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -426,24 +426,6 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d0_2_ctrl, .ctrlbit = (1 << 1), }, { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_div_d1_bus.clk, - .enable = s5pc100_d1_0_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_div_d1_bus.clk, - .enable = s5pc100_d1_0_ctrl, - .ctrlbit = (1 << 6), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_div_d1_bus.clk, - .enable = s5pc100_d1_0_ctrl, - .ctrlbit = (1 << 5), - }, { .name = "modemif", .parent = &clk_div_d1_bus.clk, .enable = s5pc100_d1_0_ctrl, @@ -711,6 +693,30 @@ static struct clk init_clocks_off[] = { }, }; +static struct clk clk_hsmmc2 = { + .name = "hsmmc", + .devname = "s3c-sdhci.2", + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 7), +}; + +static struct clk clk_hsmmc1 = { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 6), +}; + +static struct clk clk_hsmmc0 = { + .name = "hsmmc", + .devname = "s3c-sdhci.0", + .parent = &clk_div_d1_bus.clk, + .enable = s5pc100_d1_0_ctrl, + .ctrlbit = (1 << 5), +}; + static struct clk clk_vclk54m = { .name = "vclk_54m", .rate = 54000000, @@ -1014,39 +1020,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 }, }, { .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.0", - .ctrlbit = (1 << 12), - .enable = s5pc100_sclk1_ctrl, - - }, - .sources = &clk_src_mmc0, - .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.1", - .ctrlbit = (1 << 13), - .enable = s5pc100_sclk1_ctrl, - - }, - .sources = &clk_src_mmc12, - .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.2", - .ctrlbit = (1 << 14), - .enable = s5pc100_sclk1_ctrl, - - }, - .sources = &clk_src_mmc12, - .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, - }, { - .clk = { .name = "sclk_irda", .ctrlbit = (1 << 10), .enable = s5pc100_sclk0_ctrl, @@ -1099,6 +1072,42 @@ static struct clksrc_clk clk_sclk_uart = { .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, }; +static struct clksrc_clk clk_sclk_mmc0 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.0", + .ctrlbit = (1 << 12), + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clk_src_mmc0, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_mmc1 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.1", + .ctrlbit = (1 << 13), + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clk_src_mmc12, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_mmc2 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.2", + .ctrlbit = (1 << 14), + .enable = s5pc100_sclk1_ctrl, + }, + .sources = &clk_src_mmc12, + .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, +}; + /* Clock initialisation code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -1128,8 +1137,17 @@ static struct clksrc_clk *sysclks[] = { &clk_sclk_spdif, }; +static struct clk *clk_cdev[] = { + &clk_hsmmc0, + &clk_hsmmc1, + &clk_hsmmc2, +}; + static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uart, + &clk_sclk_mmc0, + &clk_sclk_mmc1, + &clk_sclk_mmc2, }; void __init_or_cpufreq s5pc100_setup_clocks(void) @@ -1274,6 +1292,12 @@ static struct clk *clks[] __initdata = { static struct clk_lookup s5pc100_clk_lookup[] = { CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), }; void __init s5pc100_register_clocks(void) @@ -1294,6 +1318,10 @@ void __init s5pc100_register_clocks(void) s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup)); + s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); + for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++) + s3c_disable_clocks(clk_cdev[ptr], 1); + s3c24xx_register_clock(&dummy_apb_pclk); s3c_pwmclk_init(); diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 43a045d..dc4586b 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -399,30 +399,6 @@ static struct clk init_clocks_off[] = { .enable = s5pv210_clk_ip1_ctrl, .ctrlbit = (1<<25), }, { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip2_ctrl, - .ctrlbit = (1<<16), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip2_ctrl, - .ctrlbit = (1<<17), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip2_ctrl, - .ctrlbit = (1<<18), - }, { - .name = "hsmmc", - .devname = "s3c-sdhci.3", - .parent = &clk_hclk_psys.clk, - .enable = s5pv210_clk_ip2_ctrl, - .ctrlbit = (1<<19), - }, { .name = "systimer", .parent = &clk_pclk_psys.clk, .enable = s5pv210_clk_ip3_ctrl, @@ -559,6 +535,38 @@ static struct clk init_clocks[] = { }, }; +static struct clk clk_hsmmc0 = { + .name = "hsmmc", + .devname = "s3c-sdhci.0", + .parent = &clk_hclk_psys.clk, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1<<16), +}; + +static struct clk clk_hsmmc1 = { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &clk_hclk_psys.clk, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1<<17), +}; + +static struct clk clk_hsmmc2 = { + .name = "hsmmc", + .devname = "s3c-sdhci.2", + .parent = &clk_hclk_psys.clk, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1<<18), +}; + +static struct clk clk_hsmmc3 = { + .name = "hsmmc", + .devname = "s3c-sdhci.3", + .parent = &clk_hclk_psys.clk, + .enable = s5pv210_clk_ip2_ctrl, + .ctrlbit = (1<<19), +}; + static struct clk *clkset_uart_list[] = { [6] = &clk_mout_mpll.clk, [7] = &clk_mout_epll.clk, @@ -866,46 +874,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 }, }, { .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.0", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 8), - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.1", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 9), - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.2", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 10), - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "sclk_mmc", - .devname = "s3c-sdhci.3", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 11), - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, - }, { - .clk = { .name = "sclk_mfc", .devname = "s5p-mfc", .enable = s5pv210_clk_ip0_ctrl, @@ -1030,11 +998,70 @@ static struct clksrc_clk clk_sclk_uart3 = { .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, }; +static struct clksrc_clk clk_sclk_mmc0 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.0", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 8), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_mmc1 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.1", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 9), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_mmc2 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.2", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 10), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_mmc3 = { + .clk = { + .name = "sclk_mmc", + .devname = "s3c-sdhci.3", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 11), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, +}; + static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uart0, &clk_sclk_uart1, &clk_sclk_uart2, &clk_sclk_uart3, + &clk_sclk_mmc0, + &clk_sclk_mmc1, + &clk_sclk_mmc2, + &clk_sclk_mmc3, +}; + +static struct clk *clk_cdev[] = { + &clk_hsmmc0, + &clk_hsmmc1, + &clk_hsmmc2, + &clk_hsmmc3, }; /* Clock initialisation code */ @@ -1282,6 +1309,14 @@ static struct clk_lookup s5pv210_clk_lookup[] = { CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk), CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk), CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk), }; void __init s5pv210_register_clocks(void) @@ -1306,6 +1341,10 @@ void __init s5pv210_register_clocks(void) s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup)); + s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); + for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++) + s3c_disable_clocks(clk_cdev[ptr], 1); + s3c24xx_register_clock(&dummy_apb_pclk); s3c_pwmclk_init(); } diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c index 4eab2cc..95e6819 100644 --- a/arch/arm/plat-s3c24xx/s3c2443-clock.c +++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c @@ -427,12 +427,6 @@ static struct clk init_clocks[] = { .enable = s3c2443_clkcon_enable_h, .ctrlbit = S3C2443_HCLKCON_DMA5, }, { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_h, - .enable = s3c2443_clkcon_enable_h, - .ctrlbit = S3C2443_HCLKCON_HSMMC, - }, { .name = "gpio", .parent = &clk_p, .enable = s3c2443_clkcon_enable_p, @@ -514,6 +508,14 @@ static struct clk init_clocks[] = { } }; +static struct clk hsmmc1_clk = { + .name = "hsmmc", + .devname = "s3c-sdhci.1", + .parent = &clk_h, + .enable = s3c2443_clkcon_enable_h, + .ctrlbit = S3C2443_HCLKCON_HSMMC, +}; + static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) { clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; @@ -579,6 +581,7 @@ static struct clk *clks[] __initdata = { &clk_epll, &clk_usb_bus, &clk_armdiv, + &hsmmc1_clk, }; static struct clksrc_clk *clksrcs[] __initdata = { @@ -595,6 +598,7 @@ static struct clk_lookup s3c2443_clk_lookup[] = { CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk), CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk), }; void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, -- cgit v0.10.2 From 4346b6d9c6651121f35ae9e42f240f36a8e56ce6 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Thu, 3 Nov 2011 10:52:58 +0900 Subject: mmc: sdhci-s3c: Use generic clock names for sdhci bus clock options This patch modifies the driver to stop depending on the clock names being passed from the platform and switch over to bus clock lookup using generic clock names. Signed-off-by: Rajeshwari Shinde Acked-by: Chris Ball Signed-off-by: Kukjin Kim diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index cb60c41..6b3f366 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -435,14 +435,11 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { struct clk *clk; - char *name = pdata->clocks[ptr]; - - if (name == NULL) - continue; + char name[14]; + snprintf(name, 14, "mmc_busclk.%d", ptr); clk = clk_get(dev, name); if (IS_ERR(clk)) { - dev_err(dev, "failed to get clock %s\n", name); continue; } -- cgit v0.10.2 From a24d850b9b317b6168a65ff8918c5b0820ca0675 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Wed, 2 Nov 2011 20:04:19 +0900 Subject: spi/s3c64xx: Use bus clocks created using clkdev This patch modifies the driver to stop depending on the clock names being passed from platform and switch over to lookup clocks generic names using clkdev Signed-off-by: Padmavathi Venna Acked-by: Grant Likely Signed-off-by: Kukjin Kim diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 019a716..dcf7e10 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -971,6 +971,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) struct s3c64xx_spi_info *sci; struct spi_master *master; int ret; + char clk_name[16]; if (pdev->id < 0) { dev_err(&pdev->dev, @@ -984,11 +985,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) } sci = pdev->dev.platform_data; - if (!sci->src_clk_name) { - dev_err(&pdev->dev, - "Board init must call s3c64xx_spi_set_info()\n"); - return -EINVAL; - } /* Check for availability of necessary resource */ @@ -1073,17 +1069,17 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) goto err4; } - sdd->src_clk = clk_get(&pdev->dev, sci->src_clk_name); + sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr); + sdd->src_clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(sdd->src_clk)) { dev_err(&pdev->dev, - "Unable to acquire clock '%s'\n", sci->src_clk_name); + "Unable to acquire clock '%s'\n", clk_name); ret = PTR_ERR(sdd->src_clk); goto err5; } if (clk_enable(sdd->src_clk)) { - dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", - sci->src_clk_name); + dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name); ret = -EBUSY; goto err6; } -- cgit v0.10.2 From ba47917c686b287430bd6e3e019e187666df3e33 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Wed, 2 Nov 2011 20:04:08 +0900 Subject: ARM: S3C64XX: Add SPI clkdev support Registered the SPI bus clocks with clkdev using generic connection id. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 415c540..0187cde 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -184,18 +184,6 @@ static struct clk init_clocks_off[] = { .enable = s3c64xx_pclk_ctrl, .ctrlbit = S3C_CLKCON_PCLK_SPI1, }, { - .name = "spi_48m", - .devname = "s3c64xx-spi.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, - }, { - .name = "spi_48m", - .devname = "s3c64xx-spi.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, - }, { .name = "48m", .devname = "s3c-sdhci.0", .parent = &clk_48m, @@ -226,6 +214,22 @@ static struct clk init_clocks_off[] = { }, }; +static struct clk clk_48m_spi0 = { + .name = "spi_48m", + .devname = "s3c64xx-spi.0", + .parent = &clk_48m, + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, +}; + +static struct clk clk_48m_spi1 = { + .name = "spi_48m", + .devname = "s3c64xx-spi.1", + .parent = &clk_48m, + .enable = s3c64xx_sclk_ctrl, + .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, +}; + static struct clk init_clocks[] = { { .name = "lcd", @@ -592,25 +596,6 @@ static struct clksrc_clk clksrcs[] = { .sources = &clkset_uhost, }, { .clk = { - .name = "spi-bus", - .devname = "s3c64xx-spi.0", - .ctrlbit = S3C_CLKCON_SCLK_SPI0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, - }, { - .clk = { - .name = "spi-bus", - .devname = "s3c64xx-spi.1", - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, - }, { - .clk = { .name = "audio-bus", .devname = "samsung-i2s.0", .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, @@ -708,6 +693,30 @@ static struct clksrc_clk clk_sclk_mmc2 = { .sources = &clkset_spi_mmc, }; +static struct clksrc_clk clk_sclk_spi0 = { + .clk = { + .name = "spi-bus", + .devname = "s3c64xx-spi.0", + .ctrlbit = S3C_CLKCON_SCLK_SPI0, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, + .sources = &clkset_spi_mmc, +}; + +static struct clksrc_clk clk_sclk_spi1 = { + .clk = { + .name = "spi-bus", + .devname = "s3c64xx-spi.1", + .ctrlbit = S3C_CLKCON_SCLK_SPI1, + .enable = s3c64xx_sclk_ctrl, + }, + .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, + .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, + .sources = &clkset_spi_mmc, +}; + /* Clock initialisation code */ static struct clksrc_clk *init_parents[] = { @@ -721,12 +730,16 @@ static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_mmc0, &clk_sclk_mmc1, &clk_sclk_mmc2, + &clk_sclk_spi0, + &clk_sclk_spi1, }; static struct clk *clk_cdev[] = { &clk_hsmmc0, &clk_hsmmc1, &clk_hsmmc2, + &clk_48m_spi0, + &clk_48m_spi1, }; static struct clk_lookup s3c64xx_clk_lookup[] = { @@ -738,6 +751,11 @@ static struct clk_lookup s3c64xx_clk_lookup[] = { CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), + CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_48m_spi0), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_48m_spi1), }; #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) -- cgit v0.10.2 From 02717bb9aaa0dd3a9fa9d61eb88beb35fccd8153 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Wed, 2 Nov 2011 20:04:08 +0900 Subject: ARM: S5PC100: Add SPI clkdev support Registered the SPI bus clocks with clkdev using generic connection id. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 69829ba..eba721b 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c @@ -655,24 +655,6 @@ static struct clk init_clocks_off[] = { .enable = s5pc100_d1_5_ctrl, .ctrlbit = (1 << 8), }, { - .name = "spi_48m", - .devname = "s3c64xx-spi.0", - .parent = &clk_mout_48m.clk, - .enable = s5pc100_sclk0_ctrl, - .ctrlbit = (1 << 7), - }, { - .name = "spi_48m", - .devname = "s3c64xx-spi.1", - .parent = &clk_mout_48m.clk, - .enable = s5pc100_sclk0_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "spi_48m", - .devname = "s3c64xx-spi.2", - .parent = &clk_mout_48m.clk, - .enable = s5pc100_sclk0_ctrl, - .ctrlbit = (1 << 9), - }, { .name = "mmc_48m", .devname = "s3c-sdhci.0", .parent = &clk_mout_48m.clk, @@ -717,6 +699,30 @@ static struct clk clk_hsmmc0 = { .ctrlbit = (1 << 5), }; +static struct clk clk_48m_spi0 = { + .name = "spi_48m", + .devname = "s3c64xx-spi.0", + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 7), +}; + +static struct clk clk_48m_spi1 = { + .name = "spi_48m", + .devname = "s3c64xx-spi.1", + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 8), +}; + +static struct clk clk_48m_spi2 = { + .name = "spi_48m", + .devname = "s3c64xx-spi.2", + .parent = &clk_mout_48m.clk, + .enable = s5pc100_sclk0_ctrl, + .ctrlbit = (1 << 9), +}; + static struct clk clk_vclk54m = { .name = "vclk_54m", .rate = 54000000, @@ -935,39 +941,6 @@ static struct clksrc_clk clk_sclk_spdif = { static struct clksrc_clk clksrcs[] = { { .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.0", - .ctrlbit = (1 << 4), - .enable = s5pc100_sclk0_ctrl, - - }, - .sources = &clk_src_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.1", - .ctrlbit = (1 << 5), - .enable = s5pc100_sclk0_ctrl, - - }, - .sources = &clk_src_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.2", - .ctrlbit = (1 << 6), - .enable = s5pc100_sclk0_ctrl, - - }, - .sources = &clk_src_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 }, - }, { - .clk = { .name = "sclk_mixer", .ctrlbit = (1 << 6), .enable = s5pc100_sclk0_ctrl, @@ -1108,6 +1081,42 @@ static struct clksrc_clk clk_sclk_mmc2 = { .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, }; +static struct clksrc_clk clk_sclk_spi0 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.0", + .ctrlbit = (1 << 4), + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clk_src_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_spi1 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.1", + .ctrlbit = (1 << 5), + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clk_src_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_spi2 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.2", + .ctrlbit = (1 << 6), + .enable = s5pc100_sclk0_ctrl, + }, + .sources = &clk_src_group1, + .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 }, + .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 }, +}; + /* Clock initialisation code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -1141,6 +1150,9 @@ static struct clk *clk_cdev[] = { &clk_hsmmc0, &clk_hsmmc1, &clk_hsmmc2, + &clk_48m_spi0, + &clk_48m_spi1, + &clk_48m_spi2, }; static struct clksrc_clk *clksrc_cdev[] = { @@ -1148,6 +1160,9 @@ static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_mmc0, &clk_sclk_mmc1, &clk_sclk_mmc2, + &clk_sclk_spi0, + &clk_sclk_spi1, + &clk_sclk_spi2, }; void __init_or_cpufreq s5pc100_setup_clocks(void) @@ -1298,6 +1313,13 @@ static struct clk_lookup s5pc100_clk_lookup[] = { CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), + CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_48m_spi0), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_sclk_spi0.clk), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_48m_spi1), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_sclk_spi1.clk), + CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk1", &clk_48m_spi2), + CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk2", &clk_sclk_spi2.clk), }; void __init s5pc100_register_clocks(void) -- cgit v0.10.2 From c596704f733f10686a10e494d947762803555270 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Wed, 2 Nov 2011 20:04:08 +0900 Subject: ARM: S5P64X0: Add SPI clkdev support Registered the SPI bus clocks with clkdev using generic connection id. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index bfb1917..73c7cc9 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -268,18 +268,6 @@ static struct clk init_clocks_off[] = { .enable = s5p64x0_pclk_ctrl, .ctrlbit = (1 << 31), }, { - .name = "sclk_spi_48", - .devname = "s3c64xx-spi.0", - .parent = &clk_48m, - .enable = s5p64x0_sclk_ctrl, - .ctrlbit = (1 << 22), - }, { - .name = "sclk_spi_48", - .devname = "s3c64xx-spi.1", - .parent = &clk_48m, - .enable = s5p64x0_sclk_ctrl, - .ctrlbit = (1 << 23), - }, { .name = "mmc_48m", .devname = "s3c-sdhci.0", .parent = &clk_48m, @@ -421,26 +409,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, }, { .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.0", - .ctrlbit = (1 << 20), - .enable = s5p64x0_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, - .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.1", - .ctrlbit = (1 << 21), - .enable = s5p64x0_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, - .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, - }, { - .clk = { .name = "sclk_post", .ctrlbit = (1 << 10), .enable = s5p64x0_sclk_ctrl, @@ -489,6 +457,30 @@ static struct clksrc_clk clk_sclk_uclk = { .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, }; +static struct clksrc_clk clk_sclk_spi0 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.0", + .ctrlbit = (1 << 20), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_spi1 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.1", + .ctrlbit = (1 << 21), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, +}; + /* Clock initialization code */ static struct clksrc_clk *sysclks[] = { &clk_mout_apll, @@ -509,11 +501,16 @@ static struct clk dummy_apb_pclk = { static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uclk, + &clk_sclk_spi0, + &clk_sclk_spi1, }; static struct clk_lookup s5p6440_clk_lookup[] = { CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), + CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), }; void __init_or_cpufreq s5p6440_setup_clocks(void) diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index d132638..50f90cb 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -443,26 +443,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, }, { .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.0", - .ctrlbit = (1 << 20), - .enable = s5p64x0_sclk_ctrl, - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, - .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.1", - .ctrlbit = (1 << 21), - .enable = s5p64x0_sclk_ctrl, - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, - .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, - }, { - .clk = { .name = "sclk_fimc", .ctrlbit = (1 << 10), .enable = s5p64x0_sclk_ctrl, @@ -538,13 +518,42 @@ static struct clksrc_clk clk_sclk_uclk = { .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, }; +static struct clksrc_clk clk_sclk_spi0 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.0", + .ctrlbit = (1 << 20), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, +}; + +static struct clksrc_clk clk_sclk_spi1 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.1", + .ctrlbit = (1 << 21), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, +}; + static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uclk, + &clk_sclk_spi0, + &clk_sclk_spi1, }; static struct clk_lookup s5p6450_clk_lookup[] = { CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), + CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), }; /* Clock initialization code */ -- cgit v0.10.2 From 8c4b8e718c9462c1beaa7db734bf5ec0b317ac8b Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Wed, 2 Nov 2011 20:04:08 +0900 Subject: ARM: S5PV210: Add SPI clkdev support Registered the SPI bus clocks with clkdev using generic connection id. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index dc4586b..cead513 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -911,26 +911,6 @@ static struct clksrc_clk clksrcs[] = { .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 }, }, { .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.0", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 16), - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_spi", - .devname = "s3c64xx-spi.1", - .enable = s5pv210_clk_mask0_ctrl, - .ctrlbit = (1 << 17), - }, - .sources = &clkset_group2, - .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 }, - .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 }, - }, { - .clk = { .name = "sclk_pwi", .enable = s5pv210_clk_mask0_ctrl, .ctrlbit = (1 << 29), @@ -1046,6 +1026,31 @@ static struct clksrc_clk clk_sclk_mmc3 = { .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, }; +static struct clksrc_clk clk_sclk_spi0 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.0", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 16), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 }, + }; + +static struct clksrc_clk clk_sclk_spi1 = { + .clk = { + .name = "sclk_spi", + .devname = "s3c64xx-spi.1", + .enable = s5pv210_clk_mask0_ctrl, + .ctrlbit = (1 << 17), + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 }, + .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 }, + }; + + static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_uart0, &clk_sclk_uart1, @@ -1055,6 +1060,8 @@ static struct clksrc_clk *clksrc_cdev[] = { &clk_sclk_mmc1, &clk_sclk_mmc2, &clk_sclk_mmc3, + &clk_sclk_spi0, + &clk_sclk_spi1, }; static struct clk *clk_cdev[] = { @@ -1317,6 +1324,9 @@ static struct clk_lookup s5pv210_clk_lookup[] = { CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk), + CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), + CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), + CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), }; void __init s5pv210_register_clocks(void) -- cgit v0.10.2 From a153e31abb01484d0088ac28425dc98204848ad4 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Wed, 2 Nov 2011 20:08:57 +0900 Subject: ARM: SAMSUNG: Remove SPI bus clocks from platform data SPI bus clocks can be avoided passing through platform data as spi driver is getting the bus clock using the generic clock connection id registered via clkdev. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index 3341fd1..3f437e7 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c @@ -24,12 +24,6 @@ #include #include -static char *spi_src_clks[] = { - [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", - [S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus", - [S3C64XX_SPI_SRCCLK_48M] = "spi_48m", -}; - /* SPI Controller platform_devices */ /* Since we emulate multi-cs capability, we do not touch the GPC-3,7. @@ -176,5 +170,4 @@ void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; - pd->src_clk_name = spi_src_clks[src_clk_nr]; } diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c index 1fd9c79..5b5d3c0 100644 --- a/arch/arm/mach-s5p64x0/dev-spi.c +++ b/arch/arm/mach-s5p64x0/dev-spi.c @@ -25,11 +25,6 @@ #include #include -static char *s5p64x0_spi_src_clks[] = { - [S5P64X0_SPI_SRCCLK_PCLK] = "pclk", - [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi", -}; - /* SPI Controller platform_devices */ /* Since we emulate multi-cs capability, we do not touch the CS. @@ -220,5 +215,4 @@ void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; - pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr]; } diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c index e5d6c4d..155f50d 100644 --- a/arch/arm/mach-s5pc100/dev-spi.c +++ b/arch/arm/mach-s5pc100/dev-spi.c @@ -21,12 +21,6 @@ #include #include -static char *spi_src_clks[] = { - [S5PC100_SPI_SRCCLK_PCLK] = "pclk", - [S5PC100_SPI_SRCCLK_48M] = "spi_48m", - [S5PC100_SPI_SRCCLK_SPIBUS] = "spi_bus", -}; - /* SPI Controller platform_devices */ /* Since we emulate multi-cs capability, we do not touch the CS. @@ -223,5 +217,4 @@ void __init s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; - pd->src_clk_name = spi_src_clks[src_clk_nr]; } diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c index eaf9a7b..39bef19 100644 --- a/arch/arm/mach-s5pv210/dev-spi.c +++ b/arch/arm/mach-s5pv210/dev-spi.c @@ -20,11 +20,6 @@ #include #include -static char *spi_src_clks[] = { - [S5PV210_SPI_SRCCLK_PCLK] = "pclk", - [S5PV210_SPI_SRCCLK_SCLK] = "sclk_spi", -}; - /* SPI Controller platform_devices */ /* Since we emulate multi-cs capability, we do not touch the CS. @@ -171,5 +166,4 @@ void __init s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; - pd->src_clk_name = spi_src_clks[src_clk_nr]; } diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index 4c16fa3..c3d82a5 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -31,7 +31,6 @@ struct s3c64xx_spi_csinfo { /** * struct s3c64xx_spi_info - SPI Controller defining structure * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. - * @src_clk_name: Platform name of the corresponding clock. * @clk_from_cmu: If the SPI clock/prescalar control block is present * by the platform's clock-management-unit and not in SPI controller. * @num_cs: Number of CS this controller emulates. @@ -43,7 +42,6 @@ struct s3c64xx_spi_csinfo { */ struct s3c64xx_spi_info { int src_clk_nr; - char *src_clk_name; bool clk_from_cmu; int num_cs; -- cgit v0.10.2 From 875a59374cd10200ac24f03877ccd8f73af590cc Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 23 Dec 2011 10:14:31 +0900 Subject: ARM: SAMSUNG: Consolidation of SPI platform devices to plat-samsung SPI platform device definitions consolidated from respective machine folder to plat-samsung Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index e32093c..d1d0f09 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -59,4 +59,3 @@ obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o obj-y += dev-uart.o obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c deleted file mode 100644 index 3f437e7..0000000 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ /dev/null @@ -1,173 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/dev-spi.c - * - * Copyright (C) 2009 Samsung Electronics Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -/* SPI Controller platform_devices */ - -/* Since we emulate multi-cs capability, we do not touch the GPC-3,7. - * The emulated CS is toggled by board specific mechanism, as it can - * be either some immediate GPIO or some signal out of some other - * chip in between ... or some yet another way. - * We simply do not assume anything about CS. - */ -static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev) -{ - unsigned int base; - - switch (pdev->id) { - case 0: - base = S3C64XX_GPC(0); - break; - - case 1: - base = S3C64XX_GPC(4); - break; - - default: - dev_err(&pdev->dev, "Invalid SPI Controller number!"); - return -EINVAL; - } - - s3c_gpio_cfgall_range(base, 3, - S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); - - return 0; -} - -static struct resource s3c64xx_spi0_resource[] = { - [0] = { - .start = S3C64XX_PA_SPI0, - .end = S3C64XX_PA_SPI0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI0_TX, - .end = DMACH_SPI0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI0_RX, - .end = DMACH_SPI0_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI0, - .end = IRQ_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s3c64xx_spi0_pdata = { - .cfg_gpio = s3c64xx_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .tx_st_done = 21, -}; - -static u64 spi_dmamask = DMA_BIT_MASK(32); - -struct platform_device s3c64xx_device_spi0 = { - .name = "s3c64xx-spi", - .id = 0, - .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), - .resource = s3c64xx_spi0_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s3c64xx_spi0_pdata, - }, -}; -EXPORT_SYMBOL(s3c64xx_device_spi0); - -static struct resource s3c64xx_spi1_resource[] = { - [0] = { - .start = S3C64XX_PA_SPI1, - .end = S3C64XX_PA_SPI1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI1_TX, - .end = DMACH_SPI1_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI1_RX, - .end = DMACH_SPI1_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI1, - .end = IRQ_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s3c64xx_spi1_pdata = { - .cfg_gpio = s3c64xx_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .tx_st_done = 21, -}; - -struct platform_device s3c64xx_device_spi1 = { - .name = "s3c64xx-spi", - .id = 1, - .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), - .resource = s3c64xx_spi1_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s3c64xx_spi1_pdata, - }, -}; -EXPORT_SYMBOL(s3c64xx_device_spi1); - -void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) -{ - struct s3c64xx_spi_info *pd; - - /* Reject invalid configuration */ - if (!num_cs || src_clk_nr < 0 - || src_clk_nr > S3C64XX_SPI_SRCCLK_48M) { - printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); - return; - } - - switch (cntrlr) { - case 0: - pd = &s3c64xx_spi0_pdata; - break; - case 1: - pd = &s3c64xx_spi1_pdata; - break; - default: - printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", - __func__, cntrlr); - return; - } - - pd->num_cs = num_cs; - pd->src_clk_nr = src_clk_nr; -} diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile index a1324d8..e24d316 100644 --- a/arch/arm/mach-s5p64x0/Makefile +++ b/arch/arm/mach-s5p64x0/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o # device support obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c deleted file mode 100644 index 5b5d3c0..0000000 --- a/arch/arm/mach-s5p64x0/dev-spi.c +++ /dev/null @@ -1,218 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/dev-spi.c - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -/* SPI Controller platform_devices */ - -/* Since we emulate multi-cs capability, we do not touch the CS. - * The emulated CS is toggled by board specific mechanism, as it can - * be either some immediate GPIO or some signal out of some other - * chip in between ... or some yet another way. - * We simply do not assume anything about CS. - */ -static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) -{ - unsigned int base; - - switch (pdev->id) { - case 0: - base = S5P6440_GPC(0); - break; - - case 1: - base = S5P6440_GPC(4); - break; - - default: - dev_err(&pdev->dev, "Invalid SPI Controller number!"); - return -EINVAL; - } - - s3c_gpio_cfgall_range(base, 3, - S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); - - return 0; -} - -static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) -{ - unsigned int base; - - switch (pdev->id) { - case 0: - base = S5P6450_GPC(0); - break; - - case 1: - base = S5P6450_GPC(4); - break; - - default: - dev_err(&pdev->dev, "Invalid SPI Controller number!"); - return -EINVAL; - } - - s3c_gpio_cfgall_range(base, 3, - S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); - - return 0; -} - -static struct resource s5p64x0_spi0_resource[] = { - [0] = { - .start = S5P64X0_PA_SPI0, - .end = S5P64X0_PA_SPI0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI0_TX, - .end = DMACH_SPI0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI0_RX, - .end = DMACH_SPI0_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI0, - .end = IRQ_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5p6440_spi0_pdata = { - .cfg_gpio = s5p6440_spi_cfg_gpio, - .fifo_lvl_mask = 0x1ff, - .rx_lvl_offset = 15, - .tx_st_done = 25, -}; - -static struct s3c64xx_spi_info s5p6450_spi0_pdata = { - .cfg_gpio = s5p6450_spi_cfg_gpio, - .fifo_lvl_mask = 0x1ff, - .rx_lvl_offset = 15, - .tx_st_done = 25, -}; - -static u64 spi_dmamask = DMA_BIT_MASK(32); - -struct platform_device s5p64x0_device_spi0 = { - .name = "s3c64xx-spi", - .id = 0, - .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource), - .resource = s5p64x0_spi0_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -static struct resource s5p64x0_spi1_resource[] = { - [0] = { - .start = S5P64X0_PA_SPI1, - .end = S5P64X0_PA_SPI1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI1_TX, - .end = DMACH_SPI1_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI1_RX, - .end = DMACH_SPI1_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI1, - .end = IRQ_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5p6440_spi1_pdata = { - .cfg_gpio = s5p6440_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 15, - .tx_st_done = 25, -}; - -static struct s3c64xx_spi_info s5p6450_spi1_pdata = { - .cfg_gpio = s5p6450_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 15, - .tx_st_done = 25, -}; - -struct platform_device s5p64x0_device_spi1 = { - .name = "s3c64xx-spi", - .id = 1, - .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource), - .resource = s5p64x0_spi1_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, -}; - -void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) -{ - struct s3c64xx_spi_info *pd; - - /* Reject invalid configuration */ - if (!num_cs || src_clk_nr < 0 - || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) { - printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); - return; - } - - switch (cntrlr) { - case 0: - if (soc_is_s5p6450()) - pd = &s5p6450_spi0_pdata; - else - pd = &s5p6440_spi0_pdata; - - s5p64x0_device_spi0.dev.platform_data = pd; - break; - case 1: - if (soc_is_s5p6450()) - pd = &s5p6450_spi1_pdata; - else - pd = &s5p6440_spi1_pdata; - - s5p64x0_device_spi1.dev.platform_data = pd; - break; - default: - printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", - __func__, cntrlr); - return; - } - - pd->num_cs = num_cs; - pd->src_clk_nr = src_clk_nr; -} diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index 2320e54..238a836 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o # device support obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o # machine support diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c deleted file mode 100644 index 155f50d..0000000 --- a/arch/arm/mach-s5pc100/dev-spi.c +++ /dev/null @@ -1,220 +0,0 @@ -/* linux/arch/arm/mach-s5pc100/dev-spi.c - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -/* SPI Controller platform_devices */ - -/* Since we emulate multi-cs capability, we do not touch the CS. - * The emulated CS is toggled by board specific mechanism, as it can - * be either some immediate GPIO or some signal out of some other - * chip in between ... or some yet another way. - * We simply do not assume anything about CS. - */ -static int s5pc100_spi_cfg_gpio(struct platform_device *pdev) -{ - switch (pdev->id) { - case 0: - s3c_gpio_cfgall_range(S5PC100_GPB(0), 3, - S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); - break; - - case 1: - s3c_gpio_cfgall_range(S5PC100_GPB(4), 3, - S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); - break; - - case 2: - s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3)); - s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP); - s3c_gpio_cfgall_range(S5PC100_GPB(2), 2, - S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP); - break; - - default: - dev_err(&pdev->dev, "Invalid SPI Controller number!"); - return -EINVAL; - } - - return 0; -} - -static struct resource s5pc100_spi0_resource[] = { - [0] = { - .start = S5PC100_PA_SPI0, - .end = S5PC100_PA_SPI0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI0_TX, - .end = DMACH_SPI0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI0_RX, - .end = DMACH_SPI0_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI0, - .end = IRQ_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5pc100_spi0_pdata = { - .cfg_gpio = s5pc100_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .high_speed = 1, - .tx_st_done = 21, -}; - -static u64 spi_dmamask = DMA_BIT_MASK(32); - -struct platform_device s5pc100_device_spi0 = { - .name = "s3c64xx-spi", - .id = 0, - .num_resources = ARRAY_SIZE(s5pc100_spi0_resource), - .resource = s5pc100_spi0_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_spi0_pdata, - }, -}; - -static struct resource s5pc100_spi1_resource[] = { - [0] = { - .start = S5PC100_PA_SPI1, - .end = S5PC100_PA_SPI1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI1_TX, - .end = DMACH_SPI1_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI1_RX, - .end = DMACH_SPI1_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI1, - .end = IRQ_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5pc100_spi1_pdata = { - .cfg_gpio = s5pc100_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .high_speed = 1, - .tx_st_done = 21, -}; - -struct platform_device s5pc100_device_spi1 = { - .name = "s3c64xx-spi", - .id = 1, - .num_resources = ARRAY_SIZE(s5pc100_spi1_resource), - .resource = s5pc100_spi1_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_spi1_pdata, - }, -}; - -static struct resource s5pc100_spi2_resource[] = { - [0] = { - .start = S5PC100_PA_SPI2, - .end = S5PC100_PA_SPI2 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI2_TX, - .end = DMACH_SPI2_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI2_RX, - .end = DMACH_SPI2_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI2, - .end = IRQ_SPI2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5pc100_spi2_pdata = { - .cfg_gpio = s5pc100_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 13, - .high_speed = 1, - .tx_st_done = 21, -}; - -struct platform_device s5pc100_device_spi2 = { - .name = "s3c64xx-spi", - .id = 2, - .num_resources = ARRAY_SIZE(s5pc100_spi2_resource), - .resource = s5pc100_spi2_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pc100_spi2_pdata, - }, -}; - -void __init s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) -{ - struct s3c64xx_spi_info *pd; - - /* Reject invalid configuration */ - if (!num_cs || src_clk_nr < 0 - || src_clk_nr > S5PC100_SPI_SRCCLK_SPIBUS) { - printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); - return; - } - - switch (cntrlr) { - case 0: - pd = &s5pc100_spi0_pdata; - break; - case 1: - pd = &s5pc100_spi1_pdata; - break; - case 2: - pd = &s5pc100_spi2_pdata; - break; - default: - printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", - __func__, cntrlr); - return; - } - - pd->num_cs = num_cs; - pd->src_clk_nr = src_clk_nr; -} diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 53c346a..7eb8677 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o # device support obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S5PV210_SETUP_FIMC) += setup-fimc.o diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c deleted file mode 100644 index 39bef19..0000000 --- a/arch/arm/mach-s5pv210/dev-spi.c +++ /dev/null @@ -1,169 +0,0 @@ -/* linux/arch/arm/mach-s5pv210/dev-spi.c - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -/* SPI Controller platform_devices */ - -/* Since we emulate multi-cs capability, we do not touch the CS. - * The emulated CS is toggled by board specific mechanism, as it can - * be either some immediate GPIO or some signal out of some other - * chip in between ... or some yet another way. - * We simply do not assume anything about CS. - */ -static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) -{ - unsigned int base; - - switch (pdev->id) { - case 0: - base = S5PV210_GPB(0); - break; - - case 1: - base = S5PV210_GPB(4); - break; - - default: - dev_err(&pdev->dev, "Invalid SPI Controller number!"); - return -EINVAL; - } - - s3c_gpio_cfgall_range(base, 3, - S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); - - return 0; -} - -static struct resource s5pv210_spi0_resource[] = { - [0] = { - .start = S5PV210_PA_SPI0, - .end = S5PV210_PA_SPI0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI0_TX, - .end = DMACH_SPI0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI0_RX, - .end = DMACH_SPI0_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI0, - .end = IRQ_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5pv210_spi0_pdata = { - .cfg_gpio = s5pv210_spi_cfg_gpio, - .fifo_lvl_mask = 0x1ff, - .rx_lvl_offset = 15, - .high_speed = 1, - .tx_st_done = 25, -}; - -static u64 spi_dmamask = DMA_BIT_MASK(32); - -struct platform_device s5pv210_device_spi0 = { - .name = "s3c64xx-spi", - .id = 0, - .num_resources = ARRAY_SIZE(s5pv210_spi0_resource), - .resource = s5pv210_spi0_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pv210_spi0_pdata, - }, -}; - -static struct resource s5pv210_spi1_resource[] = { - [0] = { - .start = S5PV210_PA_SPI1, - .end = S5PV210_PA_SPI1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI1_TX, - .end = DMACH_SPI1_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI1_RX, - .end = DMACH_SPI1_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI1, - .end = IRQ_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5pv210_spi1_pdata = { - .cfg_gpio = s5pv210_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 15, - .high_speed = 1, - .tx_st_done = 25, -}; - -struct platform_device s5pv210_device_spi1 = { - .name = "s3c64xx-spi", - .id = 1, - .num_resources = ARRAY_SIZE(s5pv210_spi1_resource), - .resource = s5pv210_spi1_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5pv210_spi1_pdata, - }, -}; - -void __init s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) -{ - struct s3c64xx_spi_info *pd; - - /* Reject invalid configuration */ - if (!num_cs || src_clk_nr < 0 - || src_clk_nr > S5PV210_SPI_SRCCLK_SCLK) { - printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); - return; - } - - switch (cntrlr) { - case 0: - pd = &s5pv210_spi0_pdata; - break; - case 1: - pd = &s5pv210_spi1_pdata; - break; - default: - printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", - __func__, cntrlr); - return; - } - - pd->num_cs = num_cs; - pd->src_clk_nr = src_clk_nr; -} diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 313eb26..160eea1 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -226,11 +226,23 @@ config SAMSUNG_DEV_IDE help Compile in platform device definitions for IDE -config S3C64XX_DEV_SPI +config S3C64XX_DEV_SPI0 bool help Compile in platform device definitions for S3C64XX's type - SPI controllers. + SPI controller 0 + +config S3C64XX_DEV_SPI1 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 1 + +config S3C64XX_DEV_SPI2 + bool + help + Compile in platform device definitions for S3C64XX's type + SPI controller 2 config SAMSUNG_DEV_TS bool diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 4ca8b57..8b27e61 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -61,6 +61,7 @@ #include #include #include +#include static u64 samsung_device_dma_mask = DMA_BIT_MASK(32); @@ -1461,3 +1462,120 @@ struct platform_device s3c_device_wdt = { .resource = s3c_wdt_resource, }; #endif /* CONFIG_S3C_DEV_WDT */ + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +static struct resource s3c64xx_spi0_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_SPI0_TX), + [2] = DEFINE_RES_DMA(DMACH_SPI0_RX), + [3] = DEFINE_RES_IRQ(IRQ_SPI0), +}; + +struct platform_device s3c64xx_device_spi0 = { + .name = "s3c64xx-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), + .resource = s3c64xx_spi0_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd, + int src_clk_nr, int num_cs) +{ + if (!pd) { + pr_err("%s:Need to pass platform data\n", __func__); + return; + } + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd->num_cs = num_cs; + pd->src_clk_nr = src_clk_nr; + s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi0); +} +#endif /* CONFIG_S3C64XX_DEV_SPI0 */ + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +static struct resource s3c64xx_spi1_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_SPI1_TX), + [2] = DEFINE_RES_DMA(DMACH_SPI1_RX), + [3] = DEFINE_RES_IRQ(IRQ_SPI1), +}; + +struct platform_device s3c64xx_device_spi1 = { + .name = "s3c64xx-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), + .resource = s3c64xx_spi1_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, + int src_clk_nr, int num_cs) +{ + if (!pd) { + pr_err("%s:Need to pass platform data\n", __func__); + return; + } + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd->num_cs = num_cs; + pd->src_clk_nr = src_clk_nr; + s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi1); +} +#endif /* CONFIG_S3C64XX_DEV_SPI1 */ + +#ifdef CONFIG_S3C64XX_DEV_SPI2 +static struct resource s3c64xx_spi2_resource[] = { + [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256), + [1] = DEFINE_RES_DMA(DMACH_SPI2_TX), + [2] = DEFINE_RES_DMA(DMACH_SPI2_RX), + [3] = DEFINE_RES_IRQ(IRQ_SPI2), +}; + +struct platform_device s3c64xx_device_spi2 = { + .name = "s3c64xx-spi", + .id = 2, + .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource), + .resource = s3c64xx_spi2_resource, + .dev = { + .dma_mask = &samsung_device_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, + int src_clk_nr, int num_cs) +{ + if (!pd) { + pr_err("%s:Need to pass platform data\n", __func__); + return; + } + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0) { + pr_err("%s: Invalid SPI configuration\n", __func__); + return; + } + + pd->num_cs = num_cs; + pd->src_clk_nr = src_clk_nr; + s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi2); +} +#endif /* CONFIG_S3C64XX_DEV_SPI2 */ diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index ab633c9..83b1e31 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -39,6 +39,7 @@ extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; extern struct platform_device s3c64xx_device_spi0; extern struct platform_device s3c64xx_device_spi1; +extern struct platform_device s3c64xx_device_spi2; extern struct platform_device s3c_device_adc; extern struct platform_device s3c_device_cfcon; @@ -98,8 +99,6 @@ extern struct platform_device s5p6450_device_iis1; extern struct platform_device s5p6450_device_iis2; extern struct platform_device s5p6450_device_pcm0; -extern struct platform_device s5p64x0_device_spi0; -extern struct platform_device s5p64x0_device_spi1; extern struct platform_device s5pc100_device_ac97; extern struct platform_device s5pc100_device_iis0; @@ -108,9 +107,6 @@ extern struct platform_device s5pc100_device_iis2; extern struct platform_device s5pc100_device_pcm0; extern struct platform_device s5pc100_device_pcm1; extern struct platform_device s5pc100_device_spdif; -extern struct platform_device s5pc100_device_spi0; -extern struct platform_device s5pc100_device_spi1; -extern struct platform_device s5pc100_device_spi2; extern struct platform_device s5pv210_device_ac97; extern struct platform_device s5pv210_device_iis0; @@ -120,8 +116,6 @@ extern struct platform_device s5pv210_device_pcm0; extern struct platform_device s5pv210_device_pcm1; extern struct platform_device s5pv210_device_pcm2; extern struct platform_device s5pv210_device_spdif; -extern struct platform_device s5pv210_device_spi0; -extern struct platform_device s5pv210_device_spi1; extern struct platform_device exynos4_device_ac97; extern struct platform_device exynos4_device_ahci; diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index c3d82a5..effca53 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -56,18 +56,19 @@ struct s3c64xx_spi_info { }; /** - * s3c64xx_spi_set_info - SPI Controller configure callback by the board + * s3c64xx_spi_set_platdata - SPI Controller configure callback by the board * initialization code. - * @cntrlr: SPI controller number the configuration is for. + * @pd: SPI platform data to set. * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks. * @num_cs: Number of elements in the 'cs' array. * * Call this from machine init code for each SPI Controller that * has some chips attached to it. */ -extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); - +extern void s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd, + int src_clk_nr, int num_cs); +extern void s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, + int src_clk_nr, int num_cs); +extern void s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, + int src_clk_nr, int num_cs); #endif /* __S3C64XX_PLAT_SPI_H */ -- cgit v0.10.2 From 4566c7f7612fc2323cfae1556c012bb096380a90 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 23 Dec 2011 10:14:36 +0900 Subject: ARM: S3C64XX: Modified files for SPI consolidation work As SPI platform devices are consolidated to plat-samsung, some corresponding changes are required in the respective machine folder. Setup files are added for SPI GPIO configurations and platform data initialization. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 5552e04..4388186 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -77,6 +77,11 @@ config S3C64XX_SETUP_SDHCI_GPIO help Common setup code for S3C64XX SDHCI GPIO configurations +config S3C64XX_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations + # S36400 Macchine support config MACH_SMDK6400 diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index d1d0f09..d7d9bb5 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o # PM diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h index 23a1d71..8e2097b 100644 --- a/arch/arm/mach-s3c64xx/include/mach/map.h +++ b/arch/arm/mach-s3c64xx/include/mach/map.h @@ -115,6 +115,8 @@ #define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG #define S3C_PA_RTC S3C64XX_PA_RTC #define S3C_PA_WDT S3C64XX_PA_WATCHDOG +#define S3C_PA_SPI0 S3C64XX_PA_SPI0 +#define S3C_PA_SPI1 S3C64XX_PA_SPI1 #define SAMSUNG_PA_ADC S3C64XX_PA_ADC #define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c new file mode 100644 index 0000000..d9592ad --- /dev/null +++ b/arch/arm/mach-s3c64xx/setup-spi.c @@ -0,0 +1,45 @@ +/* linux/arch/arm/mach-s3c64xx/setup-spi.c + * + * Copyright (C) 2011 Samsung Electronics Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, + .tx_st_done = 21, +}; + +int s3c64xx_spi0_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, + .tx_st_done = 21, +}; + +int s3c64xx_spi1_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 8b27e61..080ea18 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -1498,6 +1498,9 @@ void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd, pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; + if (!pd->cfg_gpio) + pd->cfg_gpio = s3c64xx_spi0_cfg_gpio; + s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi0); } #endif /* CONFIG_S3C64XX_DEV_SPI0 */ @@ -1537,6 +1540,9 @@ void __init s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; + if (!pd->cfg_gpio) + pd->cfg_gpio = s3c64xx_spi1_cfg_gpio; + s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi1); } #endif /* CONFIG_S3C64XX_DEV_SPI1 */ diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index effca53..d3e2209 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -71,4 +71,11 @@ extern void s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, int src_clk_nr, int num_cs); extern void s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, int src_clk_nr, int num_cs); + +/* defined by architecture to configure gpio */ +extern int s3c64xx_spi0_cfg_gpio(struct platform_device *dev); +extern int s3c64xx_spi1_cfg_gpio(struct platform_device *dev); + +extern struct s3c64xx_spi_info s3c64xx_spi0_pdata; +extern struct s3c64xx_spi_info s3c64xx_spi1_pdata; #endif /* __S3C64XX_PLAT_SPI_H */ -- cgit v0.10.2 From 323d7717455e7709a2c923f42349bf2ed36992a3 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 23 Dec 2011 10:14:45 +0900 Subject: ARM: S5PC100: Modified files for SPI consolidation work As SPI platform devices are consolidated to plat-samsung, some corresponding changes are required in the respective machine folder. Added SPI Setup file for GPIO configurations and platform data initialization. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig index e538a4c..75a26ea 100644 --- a/arch/arm/mach-s5pc100/Kconfig +++ b/arch/arm/mach-s5pc100/Kconfig @@ -45,6 +45,11 @@ config S5PC100_SETUP_SDHCI_GPIO help Common setup code for SDHCI gpio. +config S5PC100_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations. + config MACH_SMDKC100 bool "SMDKC100" select CPU_S5PC100 diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile index 238a836..291e246 100644 --- a/arch/arm/mach-s5pc100/Makefile +++ b/arch/arm/mach-s5pc100/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S5PC100_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_S5PC100_SETUP_SPI) += setup-spi.o # device support obj-y += dev-audio.o diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h index ccbe6b7..54bc4f8 100644 --- a/arch/arm/mach-s5pc100/include/mach/map.h +++ b/arch/arm/mach-s5pc100/include/mach/map.h @@ -100,6 +100,9 @@ #define S3C_PA_USB_HSOTG S5PC100_PA_USB_HSOTG #define S3C_PA_USB_HSPHY S5PC100_PA_USB_HSPHY #define S3C_PA_WDT S5PC100_PA_WATCHDOG +#define S3C_PA_SPI0 S5PC100_PA_SPI0 +#define S3C_PA_SPI1 S5PC100_PA_SPI1 +#define S3C_PA_SPI2 S5PC100_PA_SPI2 #define S5P_PA_CHIPID S5PC100_PA_CHIPID #define S5P_PA_FIMC0 S5PC100_PA_FIMC0 diff --git a/arch/arm/mach-s5pc100/setup-spi.c b/arch/arm/mach-s5pc100/setup-spi.c new file mode 100644 index 0000000..431a6f7 --- /dev/null +++ b/arch/arm/mach-s5pc100/setup-spi.c @@ -0,0 +1,65 @@ +/* linux/arch/arm/mach-s5pc100/setup-spi.c + * + * Copyright (C) 2011 Samsung Electronics Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, + .high_speed = 1, + .tx_st_done = 21, +}; + +int s3c64xx_spi0_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgall_range(S5PC100_GPB(0), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, + .high_speed = 1, + .tx_st_done = 21, +}; + +int s3c64xx_spi1_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgall_range(S5PC100_GPB(4), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif + +#ifdef CONFIG_S3C64XX_DEV_SPI2 +struct s3c64xx_spi_info s3c64xx_spi2_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 13, + .high_speed = 1, + .tx_st_done = 21, +}; + +int s3c64xx_spi2_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3)); + s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP); + s3c_gpio_cfgall_range(S5PC100_GPB(2), 2, + S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP); + return 0; +} +#endif diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 080ea18..de0d88d 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -1582,6 +1582,9 @@ void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, pd->num_cs = num_cs; pd->src_clk_nr = src_clk_nr; + if (!pd->cfg_gpio) + pd->cfg_gpio = s3c64xx_spi2_cfg_gpio; + s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi2); } #endif /* CONFIG_S3C64XX_DEV_SPI2 */ diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index d3e2209..aea68b6 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -75,7 +75,9 @@ extern void s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, /* defined by architecture to configure gpio */ extern int s3c64xx_spi0_cfg_gpio(struct platform_device *dev); extern int s3c64xx_spi1_cfg_gpio(struct platform_device *dev); +extern int s3c64xx_spi2_cfg_gpio(struct platform_device *dev); extern struct s3c64xx_spi_info s3c64xx_spi0_pdata; extern struct s3c64xx_spi_info s3c64xx_spi1_pdata; +extern struct s3c64xx_spi_info s3c64xx_spi2_pdata; #endif /* __S3C64XX_PLAT_SPI_H */ -- cgit v0.10.2 From 25dada97a977e27fd59eed154290c8b03f0ccf17 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 23 Dec 2011 10:14:50 +0900 Subject: ARM: S5P64X0: Modified files for SPI consolidation work As SPI platform devices are consolidated to plat-samsung, some corresponding changes are required in the respective machine folder. Added SPI Setup file for GPIO configurations and platform data initialization. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig index 18690c5..dd8c85e 100644 --- a/arch/arm/mach-s5p64x0/Kconfig +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -36,6 +36,11 @@ config S5P64X0_SETUP_I2C1 help Common setup code for i2c bus 1. +config S5P64X0_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations + # machine support config MACH_SMDK6440 @@ -45,7 +50,6 @@ config MACH_SMDK6440 select S3C_DEV_I2C1 select S3C_DEV_RTC select S3C_DEV_WDT - select S3C64XX_DEV_SPI select SAMSUNG_DEV_ADC select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_PWM @@ -62,7 +66,6 @@ config MACH_SMDK6450 select S3C_DEV_I2C1 select S3C_DEV_RTC select S3C_DEV_WDT - select S3C64XX_DEV_SPI select SAMSUNG_DEV_ADC select SAMSUNG_DEV_BACKLIGHT select SAMSUNG_DEV_PWM diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile index e24d316..a7d7a49 100644 --- a/arch/arm/mach-s5p64x0/Makefile +++ b/arch/arm/mach-s5p64x0/Makefile @@ -29,3 +29,4 @@ obj-y += dev-audio.o obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o +obj-$(CONFIG_S5P64X0_SETUP_SPI) += setup-spi.o diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h index 4d3ac8a..0c0175d 100644 --- a/arch/arm/mach-s5p64x0/include/mach/map.h +++ b/arch/arm/mach-s5p64x0/include/mach/map.h @@ -67,6 +67,8 @@ #define S3C_PA_RTC S5P64X0_PA_RTC #define S3C_PA_WDT S5P64X0_PA_WDT #define S3C_PA_FB S5P64X0_PA_FB +#define S3C_PA_SPI0 S5P64X0_PA_SPI0 +#define S3C_PA_SPI1 S5P64X0_PA_SPI1 #define S5P_PA_CHIPID S5P64X0_PA_CHIPID #define S5P_PA_SROMC S5P64X0_PA_SROMC diff --git a/arch/arm/mach-s5p64x0/setup-spi.c b/arch/arm/mach-s5p64x0/setup-spi.c new file mode 100644 index 0000000..e9b8412 --- /dev/null +++ b/arch/arm/mach-s5p64x0/setup-spi.c @@ -0,0 +1,55 @@ +/* linux/arch/arm/mach-s5p64x0/setup-spi.c + * + * Copyright (C) 2011 Samsung Electronics Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { + .fifo_lvl_mask = 0x1ff, + .rx_lvl_offset = 15, + .tx_st_done = 25, +}; + +int s3c64xx_spi0_cfg_gpio(struct platform_device *dev) +{ + if (soc_is_s5p6450()) + s3c_gpio_cfgall_range(S5P6450_GPC(0), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + else + s3c_gpio_cfgall_range(S5P6440_GPC(0), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 15, + .tx_st_done = 25, +}; + +int s3c64xx_spi1_cfg_gpio(struct platform_device *dev) +{ + if (soc_is_s5p6450()) + s3c_gpio_cfgall_range(S5P6450_GPC(4), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + else + s3c_gpio_cfgall_range(S5P6440_GPC(4), 3, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif -- cgit v0.10.2 From 5aa4a395af55df284b2a8a2a587c451b0940aab0 Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 23 Dec 2011 10:14:55 +0900 Subject: ARM: S5PV210: Modified files for SPI consolidation work As SPI platform devices are consolidated to plat-samsung, some corresponding changes are required in the respective machine folder. Added SPI Setup file for GPIO configurations and platform data initialization. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 646057a..2cdc42e 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -60,6 +60,11 @@ config S5PV210_SETUP_FIMC help Common setup code for the camera interfaces. +config S5PV210_SETUP_SPI + bool + help + Common setup code for SPI GPIO configurations. + menu "S5PC110 Machines" config MACH_AQUILA diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 7eb8677..471df5d 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -35,3 +35,4 @@ obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index 7ff609f..89c34b8 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -109,6 +109,8 @@ #define S3C_PA_RTC S5PV210_PA_RTC #define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG #define S3C_PA_WDT S5PV210_PA_WATCHDOG +#define S3C_PA_SPI0 S5PV210_PA_SPI0 +#define S3C_PA_SPI1 S5PV210_PA_SPI1 #define S5P_PA_CHIPID S5PV210_PA_CHIPID #define S5P_PA_FIMC0 S5PV210_PA_FIMC0 diff --git a/arch/arm/mach-s5pv210/setup-spi.c b/arch/arm/mach-s5pv210/setup-spi.c new file mode 100644 index 0000000..f43c504 --- /dev/null +++ b/arch/arm/mach-s5pv210/setup-spi.c @@ -0,0 +1,51 @@ +/* linux/arch/arm/mach-s5pv210/setup-spi.c + * + * Copyright (C) 2011 Samsung Electronics Ltd. + * http://www.samsung.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +#ifdef CONFIG_S3C64XX_DEV_SPI0 +struct s3c64xx_spi_info s3c64xx_spi0_pdata = { + .fifo_lvl_mask = 0x1ff, + .rx_lvl_offset = 15, + .high_speed = 1, + .tx_st_done = 25, +}; + +int s3c64xx_spi0_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP); + s3c_gpio_cfgall_range(S5PV210_GPB(2), 2, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif + +#ifdef CONFIG_S3C64XX_DEV_SPI1 +struct s3c64xx_spi_info s3c64xx_spi1_pdata = { + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 15, + .high_speed = 1, + .tx_st_done = 25, +}; + +int s3c64xx_spi1_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP); + s3c_gpio_cfgall_range(S5PV210_GPB(6), 2, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); + return 0; +} +#endif -- cgit v0.10.2 From 7d38af51d587ad953eef786a6922bcd1482cae5c Mon Sep 17 00:00:00 2001 From: Padmavathi Venna Date: Fri, 23 Dec 2011 10:16:19 +0900 Subject: ARM: S3C64XX: Modified according to SPI consolidation work As SPI platform devices are consolidated to plat-samsung, some corresponding changes are required in the s3c6410 varient SoCs. Signed-off-by: Padmavathi Venna Signed-off-by: Kukjin Kim diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 4388186..90b34ab 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -281,6 +281,7 @@ config MACH_WLF_CRAGG_6410 select S3C64XX_SETUP_IDE select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_KEYPAD + select S3C64XX_SETUP_SPI select SAMSUNG_DEV_ADC select SAMSUNG_DEV_KEYPAD select S3C_DEV_USB_HOST @@ -291,7 +292,7 @@ config MACH_WLF_CRAGG_6410 select S3C_DEV_I2C1 select S3C_DEV_WDT select S3C_DEV_RTC - select S3C64XX_DEV_SPI + select S3C64XX_DEV_SPI0 select S3C24XX_GPIO_EXTRA128 select I2C help -- cgit v0.10.2 From a13861a28b90541aa207532d237e7a940f1b1c7b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 21 Dec 2011 20:00:32 +0000 Subject: bridge: provide a mtu() method for fake_dst_ops Commit 618f9bc74a039da76 (net: Move mtu handling down to the protocol depended handlers) forgot the bridge netfilter case, adding a NULL dereference in ip_fragment(). Reported-by: Chris Boot CC: Steffen Klassert Signed-off-by: Eric Dumazet Acked-by: Steffen Klassert Signed-off-by: David S. Miller diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index d6ec372..08757dc 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -114,12 +114,18 @@ static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const vo return NULL; } +static unsigned int fake_mtu(const struct dst_entry *dst) +{ + return dst->dev->mtu; +} + static struct dst_ops fake_dst_ops = { .family = AF_INET, .protocol = cpu_to_be16(ETH_P_IP), .update_pmtu = fake_update_pmtu, .cow_metrics = fake_cow_metrics, .neigh_lookup = fake_neigh_lookup, + .mtu = fake_mtu, }; /* -- cgit v0.10.2 From 7838f2ce36b6ab5c13ef20b1857e3bbd567f1759 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 22 Dec 2011 02:05:07 +0000 Subject: mqprio: Avoid panic if no options are provided Userspace may not provide TCA_OPTIONS, in fact tc currently does so not do so if no arguments are specified on the command line. Return EINVAL instead of panicing. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index f88256c..28de430 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -107,7 +107,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) if (!netif_is_multiqueue(dev)) return -EOPNOTSUPP; - if (nla_len(opt) < sizeof(*qopt)) + if (!opt || nla_len(opt) < sizeof(*qopt)) return -EINVAL; qopt = nla_data(opt); -- cgit v0.10.2 From e688a604807647c9450f9c12a7cb6d027150a895 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 22 Dec 2011 04:15:53 +0000 Subject: net: introduce DST_NOPEER dst flag Chris Boot reported crashes occurring in ipv6_select_ident(). [ 461.457562] RIP: 0010:[] [] ipv6_select_ident+0x31/0xa7 [ 461.578229] Call Trace: [ 461.580742] [ 461.582870] [] ? udp6_ufo_fragment+0x124/0x1a2 [ 461.589054] [] ? ipv6_gso_segment+0xc0/0x155 [ 461.595140] [] ? skb_gso_segment+0x208/0x28b [ 461.601198] [] ? ipv6_confirm+0x146/0x15e [nf_conntrack_ipv6] [ 461.608786] [] ? nf_iterate+0x41/0x77 [ 461.614227] [] ? dev_hard_start_xmit+0x357/0x543 [ 461.620659] [] ? nf_hook_slow+0x73/0x111 [ 461.626440] [] ? br_parse_ip_options+0x19a/0x19a [bridge] [ 461.633581] [] ? dev_queue_xmit+0x3af/0x459 [ 461.639577] [] ? br_dev_queue_push_xmit+0x72/0x76 [bridge] [ 461.646887] [] ? br_nf_post_routing+0x17d/0x18f [bridge] [ 461.653997] [] ? nf_iterate+0x41/0x77 [ 461.659473] [] ? br_flood+0xfa/0xfa [bridge] [ 461.665485] [] ? nf_hook_slow+0x73/0x111 [ 461.671234] [] ? br_flood+0xfa/0xfa [bridge] [ 461.677299] [] ? nf_bridge_update_protocol+0x20/0x20 [bridge] [ 461.684891] [] ? nf_ct_zone+0xa/0x17 [nf_conntrack] [ 461.691520] [] ? br_flood+0xfa/0xfa [bridge] [ 461.697572] [] ? NF_HOOK.constprop.8+0x3c/0x56 [bridge] [ 461.704616] [] ? nf_bridge_push_encap_header+0x1c/0x26 [bridge] [ 461.712329] [] ? br_nf_forward_finish+0x8a/0x95 [bridge] [ 461.719490] [] ? nf_bridge_pull_encap_header+0x1c/0x27 [bridge] [ 461.727223] [] ? br_nf_forward_ip+0x1c0/0x1d4 [bridge] [ 461.734292] [] ? nf_iterate+0x41/0x77 [ 461.739758] [] ? __br_deliver+0xa0/0xa0 [bridge] [ 461.746203] [] ? nf_hook_slow+0x73/0x111 [ 461.751950] [] ? __br_deliver+0xa0/0xa0 [bridge] [ 461.758378] [] ? NF_HOOK.constprop.4+0x56/0x56 [bridge] This is caused by bridge netfilter special dst_entry (fake_rtable), a special shared entry, where attaching an inetpeer makes no sense. Problem is present since commit 87c48fa3b46 (ipv6: make fragment identifications less predictable) Introduce DST_NOPEER dst flag and make sure ipv6_select_ident() and __ip_select_ident() fallback to the 'no peer attached' handling. Reported-by: Chris Boot Tested-by: Chris Boot Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/net/dst.h b/include/net/dst.h index 6faec1a..75766b4 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -53,6 +53,7 @@ struct dst_entry { #define DST_NOHASH 0x0008 #define DST_NOCACHE 0x0010 #define DST_NOCOUNT 0x0020 +#define DST_NOPEER 0x0040 short error; short obsolete; diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 08757dc..fa8b8f7 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -147,7 +147,7 @@ void br_netfilter_rtable_init(struct net_bridge *br) rt->dst.dev = br->dev; rt->dst.path = &rt->dst; dst_init_metrics(&rt->dst, br_dst_default_metrics, true); - rt->dst.flags = DST_NOXFRM; + rt->dst.flags = DST_NOXFRM | DST_NOPEER; rt->dst.ops = &fake_dst_ops; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 85cc053..94cdbc5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1367,7 +1367,7 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) { struct rtable *rt = (struct rtable *) dst; - if (rt) { + if (rt && !(rt->dst.flags & DST_NOPEER)) { if (rt->peer == NULL) rt_bind_peer(rt, rt->rt_dst, 1); @@ -1378,7 +1378,7 @@ void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) iph->id = htons(inet_getid(rt->peer, more)); return; } - } else + } else if (!rt) printk(KERN_DEBUG "rt_bind_peer(0) @%p\n", __builtin_return_address(0)); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 84d0bd5..ec56271 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -603,7 +603,7 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) static atomic_t ipv6_fragmentation_id; int old, new; - if (rt) { + if (rt && !(rt->dst.flags & DST_NOPEER)) { struct inet_peer *peer; if (!rt->rt6i_peer) -- cgit v0.10.2 From a0a129f8b6cff54ab479324a54aefdab5db4f240 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Thu, 22 Dec 2011 13:35:22 +0000 Subject: rps: fix insufficient bounds checking in store_rps_dev_flow_table_cnt() Setting a large rps_flow_cnt like (1 << 30) on 32-bit platform will cause a kernel oops due to insufficient bounds checking. if (count > 1<<30) { /* Enforce a limit to prevent overflow */ return -EINVAL; } count = roundup_pow_of_two(count); table = vmalloc(RPS_DEV_FLOW_TABLE_SIZE(count)); Note that the macro RPS_DEV_FLOW_TABLE_SIZE(count) is defined as: ... + (count * sizeof(struct rps_dev_flow)) where sizeof(struct rps_dev_flow) is 8. (1 << 30) * 8 will overflow 32 bits. This patch replaces the magic number (1 << 30) with a symbolic bound. Suggested-by: Eric Dumazet Signed-off-by: Xi Wang Signed-off-by: David S. Miller diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c71c434..385aefe 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -665,11 +665,14 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue, if (count) { int i; - if (count > 1<<30) { + if (count > INT_MAX) + return -EINVAL; + count = roundup_pow_of_two(count); + if (count > (ULONG_MAX - sizeof(struct rps_dev_flow_table)) + / sizeof(struct rps_dev_flow)) { /* Enforce a limit to prevent overflow */ return -EINVAL; } - count = roundup_pow_of_two(count); table = vmalloc(RPS_DEV_FLOW_TABLE_SIZE(count)); if (!table) return -ENOMEM; -- cgit v0.10.2 From 0fd7bac6b6157eed6cf0cb86a1e88ba29e57c033 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 21 Dec 2011 07:11:44 +0000 Subject: net: relax rcvbuf limits skb->truesize might be big even for a small packet. Its even bigger after commit 87fb4b7b533 (net: more accurate skb truesize) and big MTU. We should allow queueing at least one packet per receiver, even with a low RCVBUF setting. Reported-by: Michal Simek Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index abb6e0f..32e3937 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -637,12 +637,14 @@ static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) /* * Take into account size of receive queue and backlog queue + * Do not take into account this skb truesize, + * to allow even a single big packet to come. */ static inline bool sk_rcvqueues_full(const struct sock *sk, const struct sk_buff *skb) { unsigned int qsize = sk->sk_backlog.len + atomic_read(&sk->sk_rmem_alloc); - return qsize + skb->truesize > sk->sk_rcvbuf; + return qsize > sk->sk_rcvbuf; } /* The per-socket spinlock must be held here. */ diff --git a/net/core/sock.c b/net/core/sock.c index 4ed7b1d..b23f174 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -288,11 +288,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) unsigned long flags; struct sk_buff_head *list = &sk->sk_receive_queue; - /* Cast sk->rcvbuf to unsigned... It's pointless, but reduces - number of warnings when compiling with -W --ANK - */ - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= - (unsigned)sk->sk_rcvbuf) { + if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) { atomic_inc(&sk->sk_drops); trace_sock_rcvqueue_full(sk, skb); return -ENOMEM; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 82a6f34..3891702 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1630,8 +1630,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, if (snaplen > res) snaplen = res; - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= - (unsigned)sk->sk_rcvbuf) + if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) goto drop_n_acct; if (skb_shared(skb)) { @@ -1762,8 +1761,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, if (po->tp_version <= TPACKET_V2) { if (macoff + snaplen > po->rx_ring.frame_size) { if (po->copy_thresh && - atomic_read(&sk->sk_rmem_alloc) + skb->truesize - < (unsigned)sk->sk_rcvbuf) { + atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf) { if (skb_shared(skb)) { copy_skb = skb_clone(skb, GFP_ATOMIC); } else { -- cgit v0.10.2 From d9bae67a7a91a6cc2e7a99d5ae72ada62abcc993 Mon Sep 17 00:00:00 2001 From: Tai-hwa Liang Date: Fri, 23 Dec 2011 01:14:31 -0800 Subject: Input: sentelic - release mutex upon register write failure Make sure that mutex is released upon register writing failure. This fixes boot freezing observed on ARM based OLPC (http://dev.laptop.org/ticket/11357). Signed-off-by: Paul Fox Signed-off-by: Tai-hwa Liang Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index c5b12d2..a2c15e9 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -162,7 +162,7 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val) ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) - return -1; + goto out; if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { /* inversion is required */ @@ -261,7 +261,7 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val) ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2); if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0) - return -1; + goto out; if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) { ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2); -- cgit v0.10.2 From 55205c916e179e09773d98d290334d319f45ac6b Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Thu, 22 Dec 2011 16:15:40 +0100 Subject: oprofile, arm/sh: Fix oprofile_arch_exit() linkage issue This change fixes a linking problem, which happens if oprofile is selected to be compiled as built-in: `oprofile_arch_exit' referenced in section `.init.text' of arch/arm/oprofile/built-in.o: defined in discarded section `.exit.text' of arch/arm/oprofile/built-in.o The problem is appeared after commit 87121ca504, which introduced oprofile_arch_exit() calls from __init function. Note that the aforementioned commit has been backported to stable branches, and the problem is known to be reproduced at least with 3.0.13 and 3.1.5 kernels. Signed-off-by: Vladimir Zapolskiy Signed-off-by: Robert Richter Cc: Will Deacon Cc: oprofile-list Cc: Link: http://lkml.kernel.org/r/20111222151540.GB16765@erda.amd.com Signed-off-by: Ingo Molnar diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index c074e66..4e0a371 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -116,7 +116,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) return oprofile_perf_init(ops); } -void __exit oprofile_arch_exit(void) +void oprofile_arch_exit(void) { oprofile_perf_exit(); } diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c index b4c2d2b..e4dd5d5 100644 --- a/arch/sh/oprofile/common.c +++ b/arch/sh/oprofile/common.c @@ -49,7 +49,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) return oprofile_perf_init(ops); } -void __exit oprofile_arch_exit(void) +void oprofile_arch_exit(void) { oprofile_perf_exit(); kfree(sh_pmu_op_name); @@ -60,5 +60,5 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->backtrace = sh_backtrace; return -ENODEV; } -void __exit oprofile_arch_exit(void) {} +void oprofile_arch_exit(void) {} #endif /* CONFIG_HW_PERF_EVENTS */ -- cgit v0.10.2 From 8d532b2afb2eacc84588db709ec280a3d1219be3 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 23 Dec 2011 07:53:00 -0500 Subject: Btrfs: fix worker lock misuse in find_worker Dan Carpenter noticed that we were doing a double unlock on the worker lock, and sometimes picking a worker thread without the lock held. This fixes both errors. Signed-off-by: Chris Mason Reported-by: Dan Carpenter diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index cb97174..0b39458 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -563,8 +563,8 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers) struct list_head *fallback; int ret; -again: spin_lock_irqsave(&workers->lock, flags); +again: worker = next_worker(workers); if (!worker) { @@ -579,6 +579,7 @@ again: spin_unlock_irqrestore(&workers->lock, flags); /* we're below the limit, start another worker */ ret = __btrfs_start_workers(workers); + spin_lock_irqsave(&workers->lock, flags); if (ret) goto fallback; goto again; -- cgit v0.10.2 From 08c422c27f855d27b0b3d9fa30ebd938d4ae6f1f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 23 Dec 2011 07:58:13 -0500 Subject: Btrfs: call d_instantiate after all ops are setup This closes races where btrfs is calling d_instantiate too soon during inode creation. All of the callers of btrfs_add_nondir are updated to instantiate after the inode is fully setup in memory. Signed-off-by: Al Viro Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 740e67b..13b0542 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4590,10 +4590,6 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans, int err = btrfs_add_link(trans, dir, inode, dentry->d_name.name, dentry->d_name.len, backref, index); - if (!err) { - d_instantiate(dentry, inode); - return 0; - } if (err > 0) err = -EEXIST; return err; @@ -4655,6 +4651,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, else { init_special_inode(inode, inode->i_mode, rdev); btrfs_update_inode(trans, root, inode); + d_instantiate(dentry, inode); } out_unlock: nr = trans->blocks_used; @@ -4722,6 +4719,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, inode->i_mapping->a_ops = &btrfs_aops; inode->i_mapping->backing_dev_info = &root->fs_info->bdi; BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; + d_instantiate(dentry, inode); } out_unlock: nr = trans->blocks_used; @@ -4779,6 +4777,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *parent = dentry->d_parent; err = btrfs_update_inode(trans, root, inode); BUG_ON(err); + d_instantiate(dentry, inode); btrfs_log_new_name(trans, inode, NULL, parent); } @@ -7245,6 +7244,8 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, drop_inode = 1; out_unlock: + if (!err) + d_instantiate(dentry, inode); nr = trans->blocks_used; btrfs_end_transaction_throttle(trans, root); if (drop_inode) { -- cgit v0.10.2 From 0354b48f633ae435acbc01b470a1ce8cfeff3e9f Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 16 Dec 2011 18:35:15 +0100 Subject: netfilter: xt_connbytes: handle negation correctly "! --connbytes 23:42" should match if the packet/byte count is not in range. As there is no explict "invert match" toggle in the match structure, userspace swaps the from and to arguments (i.e., as if "--connbytes 42:23" were given). However, "what <= 23 && what >= 42" will always be false. Change things so we use "||" in case "from" is larger than "to". This change may look like it breaks backwards compatibility when "to" is 0. However, older iptables binaries will refuse "connbytes 42:0", and current releases treat it to mean "! --connbytes 0:42", so we should be fine. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index 5b13850..9ddf1c3 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c @@ -87,10 +87,10 @@ connbytes_mt(const struct sk_buff *skb, struct xt_action_param *par) break; } - if (sinfo->count.to) + if (sinfo->count.to >= sinfo->count.from) return what <= sinfo->count.to && what >= sinfo->count.from; - else - return what >= sinfo->count.from; + else /* inverted */ + return what < sinfo->count.to || what > sinfo->count.from; } static int connbytes_mt_check(const struct xt_mtchk_param *par) -- cgit v0.10.2 From 2e64694de21a812d637dcbea4471ad1f7897b049 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 23 Dec 2011 14:24:25 +0100 Subject: perf/x86: Fix raw_spin_unlock_irqrestore() usage Use raw_spin_unlock_irqrestore() as equivalent to raw_spin_lock_irqsave(). Signed-off-by: Robert Richter Cc: Stephane Eranian Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1324646665-13334-1-git-send-email-robert.richter@amd.com Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 8d601b1..121f1be 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1169,7 +1169,7 @@ again: */ c = &unconstrained; } else if (intel_try_alt_er(event, orig_idx)) { - raw_spin_unlock(&era->lock); + raw_spin_unlock_irqrestore(&era->lock, flags); goto again; } raw_spin_unlock_irqrestore(&era->lock, flags); -- cgit v0.10.2 From 990fc3d0b2c27a9633b8f4566273da60aebe5941 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Fri, 23 Dec 2011 17:32:25 +0100 Subject: ASoC: wm8776: add missing break in sample size switch Broken in commit d1dc698a54259cb454284456483b45f67c865cf8 Signed-off-by: Joachim Eastwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index bfdc523..d3b0a20 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -235,6 +235,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream, switch (snd_pcm_format_width(params_format(params))) { case 16: iface = 0; + break; case 20: iface = 0x10; break; -- cgit v0.10.2 From b024043b6d0d3feecb1de350de9762a00a79eda1 Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Thu, 22 Dec 2011 23:27:42 +0100 Subject: ARM: 7245/1: S3C64XX: introduce arch/arm/mach-s3c64xx/common.[ch] This patch introduces common.[ch] which are used only in the arch/arm/mach-s3c64xx/ directory. The common.c file merges the cpu.c, irq.c and irq-eint.c which are used commonly on S3C64XX SoCs and the common.h file replaces with plat/s3c6400.h and plat/s3c6410.h files. Cc: Ben Dooks Signed-off-by: Kukjin Kim Signed-off-by: Russell King diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index cfc0b99..f37016c 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -10,54 +10,49 @@ obj-m := obj-n := obj- := -# Core files -obj-y += cpu.o -obj-y += clock.o +# Core -# Core support for S3C6400 system +obj-y += common.o clock.o + +# Core support obj-$(CONFIG_CPU_S3C6400) += s3c6400.o obj-$(CONFIG_CPU_S3C6410) += s3c6410.o -obj-y += irq.o -obj-y += irq-eint.o +# PM + +obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o # DMA support obj-$(CONFIG_S3C64XX_DMA) += dma.o -# Device setup +# Device support -obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o -obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o -obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o -obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o -obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o -obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o -obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o +obj-y += dev-uart.o +obj-y += dev-audio.o +obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o -# PM +# Device setup -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += sleep.o -obj-$(CONFIG_PM) += irq-pm.o +obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o +obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o +obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o +obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o +obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o +obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o +obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o # Machine support -obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o -obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o -obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o -obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o -obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o -obj-$(CONFIG_MACH_NCP) += mach-ncp.o -obj-$(CONFIG_MACH_HMT) += mach-hmt.o -obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o -obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o -obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o -obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o - -# device support - -obj-y += dev-uart.o -obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o +obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o +obj-$(CONFIG_MACH_HMT) += mach-hmt.o +obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o +obj-$(CONFIG_MACH_NCP) += mach-ncp.o +obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o +obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o +obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o +obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o +obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o +obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o +obj-$(CONFIG_MACH_WLF_CRAGG_6410) += mach-crag6410.o mach-crag6410-module.o diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 39c238d..625219b 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -705,7 +705,7 @@ static struct clksrc_clk *init_parents[] = { #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) -void __init_or_cpufreq s3c6400_setup_clocks(void) +void __init_or_cpufreq s3c64xx_setup_clocks(void) { struct clk *xtal_clk; unsigned long xtal; @@ -804,7 +804,7 @@ static struct clk *clks[] __initdata = { * as ARMCLK as well as the necessary parent clocks. * * This call does not setup the clocks, which is left to the - * s3c6400_setup_clocks() call which may be needed by the cpufreq + * s3c64xx_setup_clocks() call which may be needed by the cpufreq * or resume code to re-set the clocks if the bootloader has changed * them. */ diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c new file mode 100644 index 0000000..8ae5b16 --- /dev/null +++ b/arch/arm/mach-s3c64xx/common.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * Common Codes for S3C64XX machines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +/* uart registration process */ + +void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no); +} + +/* table of supported CPUs */ + +static const char name_s3c6400[] = "S3C6400"; +static const char name_s3c6410[] = "S3C6410"; + +static struct cpu_table cpu_ids[] __initdata = { + { + .idcode = S3C6400_CPU_ID, + .idmask = S3C64XX_CPU_MASK, + .map_io = s3c6400_map_io, + .init_clocks = s3c6400_init_clocks, + .init_uarts = s3c64xx_init_uarts, + .init = s3c6400_init, + .name = name_s3c6400, + }, { + .idcode = S3C6410_CPU_ID, + .idmask = S3C64XX_CPU_MASK, + .map_io = s3c6410_map_io, + .init_clocks = s3c6410_init_clocks, + .init_uarts = s3c64xx_init_uarts, + .init = s3c6410_init, + .name = name_s3c6410, + }, +}; + +/* minimal IO mapping */ + +/* see notes on uart map in arch/arm/mach-s3c64xx/include/mach/debug-macro.S */ +#define UART_OFFS (S3C_PA_UART & 0xfffff) + +static struct map_desc s3c_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_SYS, + .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_MEM, + .pfn = __phys_to_pfn(S3C64XX_PA_SROM), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS), + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S3C64XX_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S3C64XX_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_TIMER, + .pfn = __phys_to_pfn(S3C_PA_TIMER), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C64XX_VA_GPIO, + .pfn = __phys_to_pfn(S3C64XX_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C64XX_VA_MODEM, + .pfn = __phys_to_pfn(S3C64XX_PA_MODEM), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_WATCHDOG, + .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_USB_HSPHY, + .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY), + .length = SZ_1K, + .type = MT_DEVICE, + }, +}; + +struct sysdev_class s3c64xx_sysclass = { + .name = "s3c64xx-core", +}; + +static struct sys_device s3c64xx_sysdev = { + .cls = &s3c64xx_sysclass, +}; + +/* read cpu identification code */ + +void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) +{ + /* initialise the io descriptors we need for initialisation */ + iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); + iotable_init(mach_desc, size); + init_consistent_dma_size(SZ_8M); + + /* detect cpu id */ + s3c64xx_init_cpu(); + + s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); +} + +static __init int s3c64xx_sysdev_init(void) +{ + sysdev_class_register(&s3c64xx_sysclass); + return sysdev_register(&s3c64xx_sysdev); +} +core_initcall(s3c64xx_sysdev_init); + +/* + * setup the sources the vic should advertise resume + * for, even though it is not doing the wake + * (set_irq_wake needs to be valid) + */ +#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE)) +#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \ + 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \ + 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \ + 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \ + 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE)) + +void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) +{ + printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); + + /* initialise the pair of VICs */ + vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME); + vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME); + + /* add the timer sub-irqs */ + s3c_init_vic_timer_irq(5, IRQ_TIMER0); +} + +#define eint_offset(irq) ((irq) - IRQ_EINT(0)) +#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq))) + +static inline void s3c_irq_eint_mask(struct irq_data *data) +{ + u32 mask; + + mask = __raw_readl(S3C64XX_EINT0MASK); + mask |= (u32)data->chip_data; + __raw_writel(mask, S3C64XX_EINT0MASK); +} + +static void s3c_irq_eint_unmask(struct irq_data *data) +{ + u32 mask; + + mask = __raw_readl(S3C64XX_EINT0MASK); + mask &= ~((u32)data->chip_data); + __raw_writel(mask, S3C64XX_EINT0MASK); +} + +static inline void s3c_irq_eint_ack(struct irq_data *data) +{ + __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND); +} + +static void s3c_irq_eint_maskack(struct irq_data *data) +{ + /* compiler should in-line these */ + s3c_irq_eint_mask(data); + s3c_irq_eint_ack(data); +} + +static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type) +{ + int offs = eint_offset(data->irq); + int pin, pin_val; + int shift; + u32 ctrl, mask; + u32 newvalue = 0; + void __iomem *reg; + + if (offs > 27) + return -EINVAL; + + if (offs <= 15) + reg = S3C64XX_EINT0CON0; + else + reg = S3C64XX_EINT0CON1; + + switch (type) { + case IRQ_TYPE_NONE: + printk(KERN_WARNING "No edge setting!\n"); + break; + + case IRQ_TYPE_EDGE_RISING: + newvalue = S3C2410_EXTINT_RISEEDGE; + break; + + case IRQ_TYPE_EDGE_FALLING: + newvalue = S3C2410_EXTINT_FALLEDGE; + break; + + case IRQ_TYPE_EDGE_BOTH: + newvalue = S3C2410_EXTINT_BOTHEDGE; + break; + + case IRQ_TYPE_LEVEL_LOW: + newvalue = S3C2410_EXTINT_LOWLEV; + break; + + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S3C2410_EXTINT_HILEV; + break; + + default: + printk(KERN_ERR "No such irq type %d", type); + return -1; + } + + if (offs <= 15) + shift = (offs / 2) * 4; + else + shift = ((offs - 16) / 2) * 4; + mask = 0x7 << shift; + + ctrl = __raw_readl(reg); + ctrl &= ~mask; + ctrl |= newvalue << shift; + __raw_writel(ctrl, reg); + + /* set the GPIO pin appropriately */ + + if (offs < 16) { + pin = S3C64XX_GPN(offs); + pin_val = S3C_GPIO_SFN(2); + } else if (offs < 23) { + pin = S3C64XX_GPL(offs + 8 - 16); + pin_val = S3C_GPIO_SFN(3); + } else { + pin = S3C64XX_GPM(offs - 23); + pin_val = S3C_GPIO_SFN(3); + } + + s3c_gpio_cfgpin(pin, pin_val); + + return 0; +} + +static struct irq_chip s3c_irq_eint = { + .name = "s3c-eint", + .irq_mask = s3c_irq_eint_mask, + .irq_unmask = s3c_irq_eint_unmask, + .irq_mask_ack = s3c_irq_eint_maskack, + .irq_ack = s3c_irq_eint_ack, + .irq_set_type = s3c_irq_eint_set_type, + .irq_set_wake = s3c_irqext_wake, +}; + +/* s3c_irq_demux_eint + * + * This function demuxes the IRQ from the group0 external interrupts, + * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into + * the specific handlers s3c_irq_demux_eintX_Y. + */ +static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end) +{ + u32 status = __raw_readl(S3C64XX_EINT0PEND); + u32 mask = __raw_readl(S3C64XX_EINT0MASK); + unsigned int irq; + + status &= ~mask; + status >>= start; + status &= (1 << (end - start + 1)) - 1; + + for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) { + if (status & 1) + generic_handle_irq(irq); + + status >>= 1; + } +} + +static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc) +{ + s3c_irq_demux_eint(0, 3); +} + +static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc) +{ + s3c_irq_demux_eint(4, 11); +} + +static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc) +{ + s3c_irq_demux_eint(12, 19); +} + +static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc) +{ + s3c_irq_demux_eint(20, 27); +} + +static int __init s3c64xx_init_irq_eint(void) +{ + int irq; + + for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { + irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq); + irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq)); + set_irq_flags(irq, IRQF_VALID); + } + + irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3); + irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11); + irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19); + irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27); + + return 0; +} +arch_initcall(s3c64xx_init_irq_eint); diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h new file mode 100644 index 0000000..9f523a2 --- /dev/null +++ b/arch/arm/mach-s3c64xx/common.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * Ben Dooks + * http://armlinux.simtec.co.uk/ + * + * Common Header for S3C64XX machines + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_MACH_S3C64XX_COMMON_H +#define __ARCH_ARM_MACH_S3C64XX_COMMON_H + +void s3c64xx_init_irq(u32 vic0, u32 vic1); +void s3c64xx_init_io(struct map_desc *mach_desc, int size); + +void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit); +void s3c64xx_setup_clocks(void); + +extern struct syscore_ops s3c64xx_irq_syscore_ops; +extern struct sysdev_class s3c64xx_sysclass; + +#ifdef CONFIG_CPU_S3C6400 + +extern int s3c6400_init(void); +extern void s3c6400_init_irq(void); +extern void s3c6400_map_io(void); +extern void s3c6400_init_clocks(int xtal); + +#else +#define s3c6400_init_clocks NULL +#define s3c6400_map_io NULL +#define s3c6400_init NULL +#endif + +#ifdef CONFIG_CPU_S3C6410 + +extern int s3c6410_init(void); +extern void s3c6410_init_irq(void); +extern void s3c6410_map_io(void); +extern void s3c6410_init_clocks(int xtal); + +#else +#define s3c6410_init_clocks NULL +#define s3c6410_map_io NULL +#define s3c6410_init NULL +#endif + +#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c deleted file mode 100644 index de085b7..0000000 --- a/arch/arm/mach-s3c64xx/cpu.c +++ /dev/null @@ -1,161 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/cpu.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * S3C64XX CPU Support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include -#include - -/* table of supported CPUs */ - -static const char name_s3c6400[] = "S3C6400"; -static const char name_s3c6410[] = "S3C6410"; - -static struct cpu_table cpu_ids[] __initdata = { - { - .idcode = S3C6400_CPU_ID, - .idmask = S3C64XX_CPU_MASK, - .map_io = s3c6400_map_io, - .init_clocks = s3c6400_init_clocks, - .init_uarts = s3c6400_init_uarts, - .init = s3c6400_init, - .name = name_s3c6400, - }, { - .idcode = S3C6410_CPU_ID, - .idmask = S3C64XX_CPU_MASK, - .map_io = s3c6410_map_io, - .init_clocks = s3c6410_init_clocks, - .init_uarts = s3c6410_init_uarts, - .init = s3c6410_init, - .name = name_s3c6410, - }, -}; - -/* minimal IO mapping */ - -/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */ -#define UART_OFFS (S3C_PA_UART & 0xfffff) - -static struct map_desc s3c_iodesc[] __initdata = { - { - .virtual = (unsigned long)S3C_VA_SYS, - .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_MEM, - .pfn = __phys_to_pfn(S3C64XX_PA_SROM), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS), - .pfn = __phys_to_pfn(S3C_PA_UART), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)VA_VIC0, - .pfn = __phys_to_pfn(S3C64XX_PA_VIC0), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)VA_VIC1, - .pfn = __phys_to_pfn(S3C64XX_PA_VIC1), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_TIMER, - .pfn = __phys_to_pfn(S3C_PA_TIMER), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C64XX_VA_GPIO, - .pfn = __phys_to_pfn(S3C64XX_PA_GPIO), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C64XX_VA_MODEM, - .pfn = __phys_to_pfn(S3C64XX_PA_MODEM), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_WATCHDOG, - .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_USB_HSPHY, - .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY), - .length = SZ_1K, - .type = MT_DEVICE, - }, -}; - - -struct sysdev_class s3c64xx_sysclass = { - .name = "s3c64xx-core", -}; - -static struct sys_device s3c64xx_sysdev = { - .cls = &s3c64xx_sysclass, -}; - -/* uart registration process */ - -void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no); -} - -/* read cpu identification code */ - -void __init s3c64xx_init_io(struct map_desc *mach_desc, int size) -{ - /* initialise the io descriptors we need for initialisation */ - iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); - iotable_init(mach_desc, size); - init_consistent_dma_size(SZ_8M); - - /* detect cpu id */ - s3c64xx_init_cpu(); - - s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); -} - -static __init int s3c64xx_sysdev_init(void) -{ - sysdev_class_register(&s3c64xx_sysclass); - return sysdev_register(&s3c64xx_sysdev); -} - -core_initcall(s3c64xx_sysdev_init); diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c deleted file mode 100644 index 4d203be..0000000 --- a/arch/arm/mach-s3c64xx/irq-eint.c +++ /dev/null @@ -1,213 +0,0 @@ -/* arch/arm/plat-s3c64xx/irq-eint.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * S3C64XX - Interrupt handling for IRQ_EINT(x) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include - -#define eint_offset(irq) ((irq) - IRQ_EINT(0)) -#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq))) - -static inline void s3c_irq_eint_mask(struct irq_data *data) -{ - u32 mask; - - mask = __raw_readl(S3C64XX_EINT0MASK); - mask |= (u32)data->chip_data; - __raw_writel(mask, S3C64XX_EINT0MASK); -} - -static void s3c_irq_eint_unmask(struct irq_data *data) -{ - u32 mask; - - mask = __raw_readl(S3C64XX_EINT0MASK); - mask &= ~((u32)data->chip_data); - __raw_writel(mask, S3C64XX_EINT0MASK); -} - -static inline void s3c_irq_eint_ack(struct irq_data *data) -{ - __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND); -} - -static void s3c_irq_eint_maskack(struct irq_data *data) -{ - /* compiler should in-line these */ - s3c_irq_eint_mask(data); - s3c_irq_eint_ack(data); -} - -static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type) -{ - int offs = eint_offset(data->irq); - int pin, pin_val; - int shift; - u32 ctrl, mask; - u32 newvalue = 0; - void __iomem *reg; - - if (offs > 27) - return -EINVAL; - - if (offs <= 15) - reg = S3C64XX_EINT0CON0; - else - reg = S3C64XX_EINT0CON1; - - switch (type) { - case IRQ_TYPE_NONE: - printk(KERN_WARNING "No edge setting!\n"); - break; - - case IRQ_TYPE_EDGE_RISING: - newvalue = S3C2410_EXTINT_RISEEDGE; - break; - - case IRQ_TYPE_EDGE_FALLING: - newvalue = S3C2410_EXTINT_FALLEDGE; - break; - - case IRQ_TYPE_EDGE_BOTH: - newvalue = S3C2410_EXTINT_BOTHEDGE; - break; - - case IRQ_TYPE_LEVEL_LOW: - newvalue = S3C2410_EXTINT_LOWLEV; - break; - - case IRQ_TYPE_LEVEL_HIGH: - newvalue = S3C2410_EXTINT_HILEV; - break; - - default: - printk(KERN_ERR "No such irq type %d", type); - return -1; - } - - if (offs <= 15) - shift = (offs / 2) * 4; - else - shift = ((offs - 16) / 2) * 4; - mask = 0x7 << shift; - - ctrl = __raw_readl(reg); - ctrl &= ~mask; - ctrl |= newvalue << shift; - __raw_writel(ctrl, reg); - - /* set the GPIO pin appropriately */ - - if (offs < 16) { - pin = S3C64XX_GPN(offs); - pin_val = S3C_GPIO_SFN(2); - } else if (offs < 23) { - pin = S3C64XX_GPL(offs + 8 - 16); - pin_val = S3C_GPIO_SFN(3); - } else { - pin = S3C64XX_GPM(offs - 23); - pin_val = S3C_GPIO_SFN(3); - } - - s3c_gpio_cfgpin(pin, pin_val); - - return 0; -} - -static struct irq_chip s3c_irq_eint = { - .name = "s3c-eint", - .irq_mask = s3c_irq_eint_mask, - .irq_unmask = s3c_irq_eint_unmask, - .irq_mask_ack = s3c_irq_eint_maskack, - .irq_ack = s3c_irq_eint_ack, - .irq_set_type = s3c_irq_eint_set_type, - .irq_set_wake = s3c_irqext_wake, -}; - -/* s3c_irq_demux_eint - * - * This function demuxes the IRQ from the group0 external interrupts, - * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into - * the specific handlers s3c_irq_demux_eintX_Y. - */ -static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end) -{ - u32 status = __raw_readl(S3C64XX_EINT0PEND); - u32 mask = __raw_readl(S3C64XX_EINT0MASK); - unsigned int irq; - - status &= ~mask; - status >>= start; - status &= (1 << (end - start + 1)) - 1; - - for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) { - if (status & 1) - generic_handle_irq(irq); - - status >>= 1; - } -} - -static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_eint(0, 3); -} - -static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_eint(4, 11); -} - -static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_eint(12, 19); -} - -static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc) -{ - s3c_irq_demux_eint(20, 27); -} - -static int __init s3c64xx_init_irq_eint(void) -{ - int irq; - - for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { - irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq); - irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq)); - set_irq_flags(irq, IRQF_VALID); - } - - irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3); - irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11); - irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19); - irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27); - - return 0; -} - -arch_initcall(s3c64xx_init_irq_eint); diff --git a/arch/arm/mach-s3c64xx/irq.c b/arch/arm/mach-s3c64xx/irq.c deleted file mode 100644 index b07357e..0000000 --- a/arch/arm/mach-s3c64xx/irq.c +++ /dev/null @@ -1,47 +0,0 @@ -/* arch/arm/plat-s3c64xx/irq.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * S3C64XX - Interrupt handling - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -/* setup the sources the vic should advertise resume for, even though it - * is not doing the wake (set_irq_wake needs to be valid) */ -#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE)) -#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \ - 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \ - 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \ - 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \ - 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE)) - -void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) -{ - printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); - - /* initialise the pair of VICs */ - vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME); - vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME); - - /* add the timer sub-irqs */ - s3c_init_vic_timer_irq(5, IRQ_TIMER0); -} diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index 8eba88e..4949bcd 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -45,13 +45,14 @@ #include #include -#include #include #include #include #include #include +#include "common.h" + /* DM9000 */ #define ANW6410_PA_DM9000 (0x18000000) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index d04b654..954a44e 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -50,7 +50,6 @@ #include -#include #include #include #include @@ -66,6 +65,8 @@ #include #include +#include "common.h" + /* serial port setup */ #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index 952f75f..b6231d5 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -37,12 +37,13 @@ #include #include -#include #include #include #include #include +#include "common.h" + #define UCON S3C2410_UCON_DEFAULT #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index 1bc85c3..ed02e7e 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -45,6 +44,8 @@ #include