diff options
132 files changed, 1664 insertions, 1061 deletions
| diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index 44afa0e5057d..4ff65047bb9a 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -4,7 +4,7 @@ Required properties:  - compatible: Should be "cdns,[<chip>-]{macb|gem}"    Use "cdns,at91sam9260-macb" Atmel at91sam9260 and at91sam9263 SoCs.    Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb". -  Use "cnds,pc302-gem" for Picochip picoXcell pc302 and later devices based on +  Use "cdns,pc302-gem" for Picochip picoXcell pc302 and later devices based on    the Cadence GEM, or the generic form: "cdns,gem".  - reg: Address and length of the register set for the device  - interrupts: Should contain macb interrupt diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt new file mode 100644 index 000000000000..3ea460583111 --- /dev/null +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -0,0 +1,25 @@ +Simple Framebuffer + +A simple frame-buffer describes a raw memory region that may be rendered to, +with the assumption that the display hardware has already been set up to scan +out from that buffer. + +Required properties: +- compatible: "simple-framebuffer" +- reg: Should contain the location and size of the framebuffer memory. +- width: The width of the framebuffer in pixels. +- height: The height of the framebuffer in pixels. +- stride: The number of bytes in each line of the framebuffer. +- format: The format of the framebuffer surface. Valid values are: +  - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). + +Example: + +	framebuffer { +		compatible = "simple-framebuffer"; +		reg = <0x1d385000 (1600 * 1200 * 2)>; +		width = <1600>; +		height = <1200>; +		stride = <(1600 * 2)>; +		format = "r5g6b5"; +	}; diff --git a/Documentation/rapidio/rapidio.txt b/Documentation/rapidio/rapidio.txt index c75694b35d08..a9c16c979da2 100644 --- a/Documentation/rapidio/rapidio.txt +++ b/Documentation/rapidio/rapidio.txt @@ -79,20 +79,63 @@ master port that is used to communicate with devices within the network.  In order to initialize the RapidIO subsystem, a platform must initialize and  register at least one master port within the RapidIO network. To register mport  within the subsystem controller driver initialization code calls function -rio_register_mport() for each available master port. After all active master -ports are registered with a RapidIO subsystem, the rio_init_mports() routine -is called to perform enumeration and discovery. +rio_register_mport() for each available master port. -In the current PowerPC-based implementation a subsys_initcall() is specified to -perform controller initialization and mport registration. At the end it directly -calls rio_init_mports() to execute RapidIO enumeration and discovery. +RapidIO subsystem uses subsys_initcall() or device_initcall() to perform +controller initialization (depending on controller device type). + +After all active master ports are registered with a RapidIO subsystem, +an enumeration and/or discovery routine may be called automatically or +by user-space command.  4. Enumeration and Discovery  ---------------------------- -When rio_init_mports() is called it scans a list of registered master ports and -calls an enumeration or discovery routine depending on the configured role of a -master port: host or agent. +4.1 Overview +------------ + +RapidIO subsystem configuration options allow users to specify enumeration and +discovery methods as statically linked components or loadable modules. +An enumeration/discovery method implementation and available input parameters +define how any given method can be attached to available RapidIO mports: +simply to all available mports OR individually to the specified mport device. + +Depending on selected enumeration/discovery build configuration, there are +several methods to initiate an enumeration and/or discovery process: + +  (a) Statically linked enumeration and discovery process can be started +  automatically during kernel initialization time using corresponding module +  parameters. This was the original method used since introduction of RapidIO +  subsystem. Now this method relies on enumerator module parameter which is +  'rio-scan.scan' for existing basic enumeration/discovery method. +  When automatic start of enumeration/discovery is used a user has to ensure +  that all discovering endpoints are started before the enumerating endpoint +  and are waiting for enumeration to be completed. +  Configuration option CONFIG_RAPIDIO_DISC_TIMEOUT defines time that discovering +  endpoint waits for enumeration to be completed. If the specified timeout +  expires the discovery process is terminated without obtaining RapidIO network +  information. NOTE: a timed out discovery process may be restarted later using +  a user-space command as it is described later if the given endpoint was +  enumerated successfully. + +  (b) Statically linked enumeration and discovery process can be started by +  a command from user space. This initiation method provides more flexibility +  for a system startup compared to the option (a) above. After all participating +  endpoints have been successfully booted, an enumeration process shall be +  started first by issuing a user-space command, after an enumeration is +  completed a discovery process can be started on all remaining endpoints. + +  (c) Modular enumeration and discovery process can be started by a command from +  user space. After an enumeration/discovery module is loaded, a network scan +  process can be started by issuing a user-space command. +  Similar to the option (b) above, an enumerator has to be started first. + +  (d) Modular enumeration and discovery process can be started by a module +  initialization routine. In this case an enumerating module shall be loaded +  first. + +When a network scan process is started it calls an enumeration or discovery +routine depending on the configured role of a master port: host or agent.  Enumeration is performed by a master port if it is configured as a host port by  assigning a host device ID greater than or equal to zero. A host device ID is @@ -104,8 +147,58 @@ for it.  The enumeration and discovery routines use RapidIO maintenance transactions  to access the configuration space of devices. -The enumeration process is implemented according to the enumeration algorithm -outlined in the RapidIO Interconnect Specification: Annex I [1]. +4.2 Automatic Start of Enumeration and Discovery +------------------------------------------------ + +Automatic enumeration/discovery start method is applicable only to built-in +enumeration/discovery RapidIO configuration selection. To enable automatic +enumeration/discovery start by existing basic enumerator method set use boot +command line parameter "rio-scan.scan=1". + +This configuration requires synchronized start of all RapidIO endpoints that +form a network which will be enumerated/discovered. Discovering endpoints have +to be started before an enumeration starts to ensure that all RapidIO +controllers have been initialized and are ready to be discovered. Configuration +parameter CONFIG_RAPIDIO_DISC_TIMEOUT defines time (in seconds) which +a discovering endpoint will wait for enumeration to be completed. + +When automatic enumeration/discovery start is selected, basic method's +initialization routine calls rio_init_mports() to perform enumeration or +discovery for all known mport devices. + +Depending on RapidIO network size and configuration this automatic +enumeration/discovery start method may be difficult to use due to the +requirement for synchronized start of all endpoints. + +4.3 User-space Start of Enumeration and Discovery +------------------------------------------------- + +User-space start of enumeration and discovery can be used with built-in and +modular build configurations. For user-space controlled start RapidIO subsystem +creates the sysfs write-only attribute file '/sys/bus/rapidio/scan'. To initiate +an enumeration or discovery process on specific mport device, a user needs to +write mport_ID (not RapidIO destination ID) into that file. The mport_ID is a +sequential number (0 ... RIO_MAX_MPORTS) assigned during mport device +registration. For example for machine with single RapidIO controller, mport_ID +for that controller always will be 0. + +To initiate RapidIO enumeration/discovery on all available mports a user may +write '-1' (or RIO_MPORT_ANY) into the scan attribute file. + +4.4 Basic Enumeration Method +---------------------------- + +This is an original enumeration/discovery method which is available since +first release of RapidIO subsystem code. The enumeration process is +implemented according to the enumeration algorithm outlined in the RapidIO +Interconnect Specification: Annex I [1]. + +This method can be configured as statically linked or loadable module. +The method's single parameter "scan" allows to trigger the enumeration/discovery +process from module initialization routine. + +This enumeration/discovery method can be started only once and does not support +unloading if it is built as a module.  The enumeration process traverses the network using a recursive depth-first  algorithm. When a new device is found, the enumerator takes ownership of that @@ -160,6 +253,19 @@ time period. If this wait time period expires before enumeration is completed,  an agent skips RapidIO discovery and continues with remaining kernel  initialization. +4.5 Adding New Enumeration/Discovery Method +------------------------------------------- + +RapidIO subsystem code organization allows addition of new enumeration/discovery +methods as new configuration options without significant impact to to the core +RapidIO code. + +A new enumeration/discovery method has to be attached to one or more mport +devices before an enumeration/discovery process can be started. Normally, +method's module initialization routine calls rio_register_scan() to attach +an enumerator to a specified mport device (or devices). The basic enumerator +implementation demonstrates this process. +  5. References  ------------- diff --git a/Documentation/rapidio/sysfs.txt b/Documentation/rapidio/sysfs.txt index 97f71ce575d6..19878179da4c 100644 --- a/Documentation/rapidio/sysfs.txt +++ b/Documentation/rapidio/sysfs.txt @@ -88,3 +88,20 @@ that exports additional attributes.  IDT_GEN2:   errlog - reads contents of device error log until it is empty. + + +5. RapidIO Bus Attributes +------------------------- + +RapidIO bus subdirectory /sys/bus/rapidio implements the following bus-specific +attribute: + +  scan - allows to trigger enumeration discovery process from user space. This +	 is a write-only attribute. To initiate an enumeration or discovery +	 process on specific mport device, a user needs to write mport_ID (not +	 RapidIO destination ID) into this file. The mport_ID is a sequential +	 number (0 ... RIO_MAX_MPORTS) assigned to the mport device. +	 For example, for a machine with a single RapidIO controller, mport_ID +	 for that controller always will be 0. +	 To initiate RapidIO enumeration/discovery on all available mports +	 a user must write '-1' (or RIO_MPORT_ANY) into this attribute file. diff --git a/arch/arc/boot/dts/abilis_tb100_dvk.dts b/arch/arc/boot/dts/abilis_tb100_dvk.dts index c0fd3623c393..0fa0d4abe795 100644 --- a/arch/arc/boot/dts/abilis_tb100_dvk.dts +++ b/arch/arc/boot/dts/abilis_tb100_dvk.dts @@ -37,7 +37,7 @@  	soc100 {  		uart@FF100000 { -			pinctrl-names = "abilis,simple-default"; +			pinctrl-names = "default";  			pinctrl-0 = <&pctl_uart0>;  		};  		ethernet@FE100000 { diff --git a/arch/arc/boot/dts/abilis_tb101_dvk.dts b/arch/arc/boot/dts/abilis_tb101_dvk.dts index 6f8c381f6268..a4d80ce283ae 100644 --- a/arch/arc/boot/dts/abilis_tb101_dvk.dts +++ b/arch/arc/boot/dts/abilis_tb101_dvk.dts @@ -37,7 +37,7 @@  	soc100 {  		uart@FF100000 { -			pinctrl-names = "abilis,simple-default"; +			pinctrl-names = "default";  			pinctrl-0 = <&pctl_uart0>;  		};  		ethernet@FE100000 { diff --git a/arch/arc/boot/dts/abilis_tb10x.dtsi b/arch/arc/boot/dts/abilis_tb10x.dtsi index a6139fc5aaa3..b97e3051ba4b 100644 --- a/arch/arc/boot/dts/abilis_tb10x.dtsi +++ b/arch/arc/boot/dts/abilis_tb10x.dtsi @@ -88,8 +88,7 @@  		};  		uart@FF100000 { -			compatible = "snps,dw-apb-uart", -					"abilis,simple-pinctrl"; +			compatible = "snps,dw-apb-uart";  			reg = <0xFF100000 0x100>;  			clock-frequency = <166666666>;  			interrupts = <25 1>; @@ -184,8 +183,7 @@  			#address-cells = <1>;  			#size-cells = <0>;  			cell-index = <1>; -			compatible = "abilis,tb100-spi", -					"abilis,simple-pinctrl"; +			compatible = "abilis,tb100-spi";  			num-cs = <2>;  			reg = <0xFE011000 0x20>;  			interrupt-parent = <&tb10x_ictl>; diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h index 9f841af41092..ef62682e8d95 100644 --- a/arch/arc/include/asm/cacheflush.h +++ b/arch/arc/include/asm/cacheflush.h @@ -93,14 +93,16 @@ static inline int cache_is_vipt_aliasing(void)  #endif  } -#define CACHE_COLOR(addr)	(((unsigned long)(addr) >> (PAGE_SHIFT)) & 3) +#define CACHE_COLOR(addr)	(((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)  /*   * checks if two addresses (after page aligning) index into same cache set   */  #define addr_not_cache_congruent(addr1, addr2)				\ +({									\  	cache_is_vipt_aliasing() ? 					\ -		(CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0		\ +		(CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0;		\ +})  #define copy_to_user_page(vma, page, vaddr, dst, src, len)		\  do {									\ diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 374a35514116..ab84bf131fe1 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -19,13 +19,6 @@  #define clear_page(paddr)		memset((paddr), 0, PAGE_SIZE)  #define copy_page(to, from)		memcpy((to), (from), PAGE_SIZE) -#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING - -#define clear_user_page(addr, vaddr, pg)	clear_page(addr) -#define copy_user_page(vto, vfrom, vaddr, pg)	copy_page(vto, vfrom) - -#else	/* VIPT aliasing dcache */ -  struct vm_area_struct;  struct page; @@ -35,8 +28,6 @@ void copy_user_highpage(struct page *to, struct page *from,  			unsigned long u_vaddr, struct vm_area_struct *vma);  void clear_user_page(void *to, unsigned long u_vaddr, struct page *page); -#endif	/* CONFIG_ARC_CACHE_VIPT_ALIASING */ -  #undef STRICT_MM_TYPECHECKS  #ifdef STRICT_MM_TYPECHECKS diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index 1cc4720faccb..95b1522212a7 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -57,9 +57,9 @@  #define _PAGE_ACCESSED      (1<<1)	/* Page is accessed (S) */  #define _PAGE_CACHEABLE     (1<<2)	/* Page is cached (H) */ -#define _PAGE_EXECUTE       (1<<3)	/* Page has user execute perm (H) */ -#define _PAGE_WRITE         (1<<4)	/* Page has user write perm (H) */ -#define _PAGE_READ          (1<<5)	/* Page has user read perm (H) */ +#define _PAGE_U_EXECUTE     (1<<3)	/* Page has user execute perm (H) */ +#define _PAGE_U_WRITE       (1<<4)	/* Page has user write perm (H) */ +#define _PAGE_U_READ        (1<<5)	/* Page has user read perm (H) */  #define _PAGE_K_EXECUTE     (1<<6)	/* Page has kernel execute perm (H) */  #define _PAGE_K_WRITE       (1<<7)	/* Page has kernel write perm (H) */  #define _PAGE_K_READ        (1<<8)	/* Page has kernel perm (H) */ @@ -72,9 +72,9 @@  /* PD1 */  #define _PAGE_CACHEABLE     (1<<0)	/* Page is cached (H) */ -#define _PAGE_EXECUTE       (1<<1)	/* Page has user execute perm (H) */ -#define _PAGE_WRITE         (1<<2)	/* Page has user write perm (H) */ -#define _PAGE_READ          (1<<3)	/* Page has user read perm (H) */ +#define _PAGE_U_EXECUTE     (1<<1)	/* Page has user execute perm (H) */ +#define _PAGE_U_WRITE       (1<<2)	/* Page has user write perm (H) */ +#define _PAGE_U_READ        (1<<3)	/* Page has user read perm (H) */  #define _PAGE_K_EXECUTE     (1<<4)	/* Page has kernel execute perm (H) */  #define _PAGE_K_WRITE       (1<<5)	/* Page has kernel write perm (H) */  #define _PAGE_K_READ        (1<<6)	/* Page has kernel perm (H) */ @@ -93,7 +93,8 @@  #endif  /* Kernel allowed all permissions for all pages */ -#define _K_PAGE_PERMS  (_PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ) +#define _K_PAGE_PERMS  (_PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ | \ +			_PAGE_GLOBAL | _PAGE_PRESENT)  #ifdef CONFIG_ARC_CACHE_PAGES  #define _PAGE_DEF_CACHEABLE _PAGE_CACHEABLE @@ -106,7 +107,11 @@   * -by default cached, unless config otherwise   * -present in memory   */ -#define ___DEF (_PAGE_PRESENT | _K_PAGE_PERMS | _PAGE_DEF_CACHEABLE) +#define ___DEF (_PAGE_PRESENT | _PAGE_DEF_CACHEABLE) + +#define _PAGE_READ	(_PAGE_U_READ    | _PAGE_K_READ) +#define _PAGE_WRITE	(_PAGE_U_WRITE   | _PAGE_K_WRITE) +#define _PAGE_EXECUTE	(_PAGE_U_EXECUTE | _PAGE_K_EXECUTE)  /* Set of bits not changed in pte_modify */  #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED) @@ -125,11 +130,10 @@   * kernel vaddr space - visible in all addr spaces, but kernel mode only   * Thus Global, all-kernel-access, no-user-access, cached   */ -#define PAGE_KERNEL          __pgprot(___DEF | _PAGE_GLOBAL) +#define PAGE_KERNEL          __pgprot(_K_PAGE_PERMS | _PAGE_DEF_CACHEABLE)  /* ioremap */ -#define PAGE_KERNEL_NO_CACHE __pgprot(_PAGE_PRESENT | _K_PAGE_PERMS | \ -						     _PAGE_GLOBAL) +#define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)  /**************************************************************************   * Mapping of vm_flags (Generic VM) to PTE flags (arch specific) diff --git a/arch/arc/include/asm/tlb.h b/arch/arc/include/asm/tlb.h index 85b6df839bd7..cb0c708ca665 100644 --- a/arch/arc/include/asm/tlb.h +++ b/arch/arc/include/asm/tlb.h @@ -16,7 +16,7 @@  /* Masks for actual TLB "PD"s */  #define PTE_BITS_IN_PD0	(_PAGE_GLOBAL | _PAGE_PRESENT)  #define PTE_BITS_IN_PD1	(PAGE_MASK | _PAGE_CACHEABLE | \ -			 _PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ | \ +			 _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \  			 _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)  #ifndef __ASSEMBLY__ diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 2f12bca8aef3..aedce1905441 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c @@ -610,7 +610,7 @@ void __sync_icache_dcache(unsigned long paddr, unsigned long vaddr, int len)  	local_irq_save(flags);  	__ic_line_inv_vaddr(paddr, vaddr, len); -	__dc_line_op(paddr, vaddr, len, OP_FLUSH); +	__dc_line_op(paddr, vaddr, len, OP_FLUSH_N_INV);  	local_irq_restore(flags);  } @@ -676,6 +676,17 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,  	flush_cache_all();  } +void flush_anon_page(struct vm_area_struct *vma, struct page *page, +		     unsigned long u_vaddr) +{ +	/* TBD: do we really need to clear the kernel mapping */ +	__flush_dcache_page(page_address(page), u_vaddr); +	__flush_dcache_page(page_address(page), page_address(page)); + +} + +#endif +  void copy_user_highpage(struct page *to, struct page *from,  	unsigned long u_vaddr, struct vm_area_struct *vma)  { @@ -725,16 +736,6 @@ void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)  	set_bit(PG_arch_1, &page->flags);  } -void flush_anon_page(struct vm_area_struct *vma, struct page *page, -		     unsigned long u_vaddr) -{ -	/* TBD: do we really need to clear the kernel mapping */ -	__flush_dcache_page(page_address(page), u_vaddr); -	__flush_dcache_page(page_address(page), page_address(page)); - -} - -#endif  /**********************************************************************   * Explicit Cache flush request from user space via syscall diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 066145b5f348..fe1c5a073afe 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -444,7 +444,8 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,  	 *	       so userspace sees the right data.  	 *  (Avoids the flush for Non-exec + congruent mapping case)  	 */ -	if (vma->vm_flags & VM_EXEC || addr_not_cache_congruent(paddr, vaddr)) { +	if ((vma->vm_flags & VM_EXEC) || +	     addr_not_cache_congruent(paddr, vaddr)) {  		struct page *page = pfn_to_page(pte_pfn(*ptep));  		int dirty = test_and_clear_bit(PG_arch_1, &page->flags); diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index 9df765dc7c3a..3357d26ffe54 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -277,7 +277,7 @@ ARC_ENTRY EV_TLBMissI  	;----------------------------------------------------------------  	; VERIFY_PTE: Check if PTE permissions approp for executing code  	cmp_s   r2, VMALLOC_START -	mov.lo  r2, (_PAGE_PRESENT | _PAGE_READ | _PAGE_EXECUTE) +	mov.lo  r2, (_PAGE_PRESENT | _PAGE_U_READ | _PAGE_U_EXECUTE)  	mov.hs  r2, (_PAGE_PRESENT | _PAGE_K_READ | _PAGE_K_EXECUTE)  	and     r3, r0, r2  ; Mask out NON Flag bits from PTE @@ -320,9 +320,9 @@ ARC_ENTRY EV_TLBMissD  	mov_s   r2, 0  	lr      r3, [ecr]  	btst_s  r3, ECR_C_BIT_DTLB_LD_MISS	; Read Access -	or.nz   r2, r2, _PAGE_READ      	; chk for Read flag in PTE +	or.nz   r2, r2, _PAGE_U_READ      	; chk for Read flag in PTE  	btst_s  r3, ECR_C_BIT_DTLB_ST_MISS	; Write Access -	or.nz   r2, r2, _PAGE_WRITE     	; chk for Write flag in PTE +	or.nz   r2, r2, _PAGE_U_WRITE     	; chk for Write flag in PTE  	; Above laddering takes care of XCHG access  	;   which is both Read and Write diff --git a/arch/arc/plat-tb10x/tb10x.c b/arch/arc/plat-tb10x/tb10x.c index d3567691c7e1..06cb30929460 100644 --- a/arch/arc/plat-tb10x/tb10x.c +++ b/arch/arc/plat-tb10x/tb10x.c @@ -34,31 +34,6 @@ static void __init tb10x_platform_init(void)  	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);  } -static void __init tb10x_platform_late_init(void) -{ -	struct device_node *dn; - -	/* -	 * Pinctrl documentation recommends setting up the iomux here for -	 * all modules which don't require control over the pins themselves. -	 * Modules which need this kind of assistance are compatible with -	 * "abilis,simple-pinctrl", i.e. we can easily iterate over them. -	 * TODO: Does this recommended method work cleanly with pins required -	 * by modules? -	 */ -	for_each_compatible_node(dn, NULL, "abilis,simple-pinctrl") { -		struct platform_device *pd = of_find_device_by_node(dn); -		struct pinctrl *pctl; - -		pctl = pinctrl_get_select(&pd->dev, "abilis,simple-default"); -		if (IS_ERR(pctl)) { -			int ret = PTR_ERR(pctl); -			dev_err(&pd->dev, "Could not set up pinctrl: %d\n", -				ret); -		} -	} -} -  static const char *tb10x_compat[] __initdata = {  	"abilis,arc-tb10x",  	NULL, @@ -67,5 +42,4 @@ static const char *tb10x_compat[] __initdata = {  MACHINE_START(TB10x, "tb10x")  	.dt_compat	= tb10x_compat,  	.init_machine	= tb10x_platform_init, -	.init_late	= tb10x_platform_late_init,  MACHINE_END diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b9f7121e6ecf..f0895c581a89 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -177,7 +177,9 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \  	spear320-evb.dtb \  	spear320-hmi.dtb  dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb -dtb-$(CONFIG_ARCH_SUNXI) += sun4i-a10-cubieboard.dtb \ +dtb-$(CONFIG_ARCH_SUNXI) += \ +	sun4i-a10-cubieboard.dtb \ +	sun4i-a10-mini-xplus.dtb \  	sun4i-a10-hackberry.dtb \  	sun5i-a13-olinuxino.dtb  dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 272bbc65fab0..550eb772c30e 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -33,7 +33,8 @@  		#size-cells = <1>;  		compatible = "simple-bus";  		interrupt-parent = <&mpic>; -		ranges = <0 0 0xd0000000 0x100000>; +		ranges = <0          0 0xd0000000 0x0100000 /* internal registers */ +			  0xe0000000 0 0xe0000000 0x8100000 /* PCIe */>;  		internal-regs {  			compatible = "simple-bus"; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index b2c1b5af9749..aee2b1866ce2 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -29,7 +29,8 @@  	};  	soc { -		ranges = <0 0xd0000000 0x100000>; +		ranges = <0          0xd0000000 0x0100000 /* internal registers */ +			  0xe0000000 0xe0000000 0x8100000 /* PCIe */>;  		internal-regs {  			system-controller@18200 {  				compatible = "marvell,armada-370-xp-system-controller"; @@ -38,12 +39,12 @@  			L2: l2-cache {  				compatible = "marvell,aurora-outer-cache"; -				reg = <0xd0008000 0x1000>; +				reg = <0x08000 0x1000>;  				cache-id-part = <0x100>;  				wt-override;  			}; -			mpic: interrupt-controller@20000 { +			interrupt-controller@20000 {  				reg = <0x20a00 0x1d0>, <0x21870 0x58>;  			}; diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 26ad06fc147e..3ee63d128e27 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -39,6 +39,9 @@  	};  	soc { +		ranges = <0          0 0xd0000000 0x100000 +			  0xf0000000 0 0xf0000000 0x1000000>; +  		internal-regs {  			serial@12000 {  				clock-frequency = <250000000>; diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index f14d36c46159..46b785064dd8 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -27,6 +27,9 @@  	};  	soc { +		ranges = <0          0 0xd0000000 0x100000 +			  0xf0000000 0 0xf0000000 0x8000000>; +  		internal-regs {  			serial@12000 {  				clock-frequency = <250000000>; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index bacab11c10dc..5b902f9a3af2 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -31,7 +31,7 @@  				wt-override;  			}; -			mpic: interrupt-controller@20000 { +			interrupt-controller@20000 {  			      reg = <0x20a00 0x2d0>, <0x21070 0x58>;  			}; diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 70b5ccbac234..84c4bef2d726 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -264,7 +264,7 @@  						atmel,pins =  							<0 10 0x2 0x0	/* PA10 periph B */  							 0 11 0x2 0x0	/* PA11 periph B */ -							 0 24 0x2 0x0	/* PA24 periph B */ +							 0 22 0x2 0x0	/* PA22 periph B */  							 0 25 0x2 0x0	/* PA25 periph B */  							 0 26 0x2 0x0	/* PA26 periph B */  							 0 27 0x2 0x0	/* PA27 periph B */ diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 3de8e6dfbcb1..8d25f889928e 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -57,6 +57,7 @@  				compatible = "atmel,at91rm9200-aic";  				interrupt-controller;  				reg = <0xfffff000 0x200>; +				atmel,external-irqs = <31>;  			};  			ramc0: ramc@ffffe800 { diff --git a/arch/arm/boot/dts/at91sam9x25ek.dts b/arch/arm/boot/dts/at91sam9x25ek.dts index 3b40d11d65e7..315250b4995e 100644 --- a/arch/arm/boot/dts/at91sam9x25ek.dts +++ b/arch/arm/boot/dts/at91sam9x25ek.dts @@ -11,7 +11,7 @@  /include/ "at91sam9x5ek.dtsi"  / { -	model = "Atmel AT91SAM9G25-EK"; +	model = "Atmel AT91SAM9X25-EK";  	compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";  	ahb { diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 82a404da1c0d..99ba6e14ebf3 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -516,7 +516,7 @@  		usb_otg_hs: usb_otg_hs@480ab000 {  			compatible = "ti,omap3-musb";  			reg = <0x480ab000 0x1000>; -			interrupts = <0 92 0x4>, <0 93 0x4>; +			interrupts = <92>, <93>;  			interrupt-names = "mc", "dma";  			ti,hwmods = "usb_otg_hs";  			multipoint = <1>; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 2e643ea51cce..5000e0d42849 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -75,11 +75,6 @@  				compatible = "atmel,at91sam9x5-spi";  				reg = <0xf0004000 0x100>;  				interrupts = <24 4 3>; -				cs-gpios = <&pioD 13 0 -					    &pioD 14 0 /* conflicts with SCK0 and CANRX0 */ -					    &pioD 15 0 /* conflicts with CTS0 and CANTX0 */ -					    &pioD 16 0 /* conflicts with RTS0 and PWMFI3 */ -					   >;  				pinctrl-names = "default";  				pinctrl-0 = <&pinctrl_spi0>;  				status = "disabled"; @@ -156,7 +151,7 @@  			};  			macb0: ethernet@f0028000 { -				compatible = "cnds,pc302-gem", "cdns,gem"; +				compatible = "cdns,pc302-gem", "cdns,gem";  				reg = <0xf0028000 0x100>;  				interrupts = <34 4 3>;  				pinctrl-names = "default"; @@ -203,11 +198,6 @@  				compatible = "atmel,at91sam9x5-spi";  				reg = <0xf8008000 0x100>;  				interrupts = <25 4 3>; -				cs-gpios = <&pioC 25 0 -					    &pioC 26 0 /* conflitcs with TWD1 and ISI_D11 */ -					    &pioC 27 0 /* conflitcs with TWCK1 and ISI_D10 */ -					    &pioC 28 0 /* conflitcs with PWMFI0 and ISI_D9 */ -					   >;  				pinctrl-names = "default";  				pinctrl-0 = <&pinctrl_spi1>;  				status = "disabled"; diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi index 1f8ed404626c..b336e7787cb3 100644 --- a/arch/arm/boot/dts/sama5d3xcm.dtsi +++ b/arch/arm/boot/dts/sama5d3xcm.dtsi @@ -32,6 +32,10 @@  	ahb {  		apb { +			spi0: spi@f0004000 { +				cs-gpios = <&pioD 13 0>, <0>, <0>, <0>; +			}; +  			macb0: ethernet@f0028000 {  				phy-mode = "rgmii";  			}; diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts index b28fbf3408e3..6f82d9368948 100644 --- a/arch/arm/boot/dts/ste-nomadik-s8815.dts +++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts @@ -14,13 +14,19 @@  		bootargs = "root=/dev/ram0 console=ttyAMA1,115200n8 earlyprintk";  	}; +	/* This is where the interrupt is routed on the S8815 board */ +	external-bus@34000000 { +		ethernet@300 { +			interrupt-parent = <&gpio3>; +			interrupts = <8 0x1>; +		}; +	}; +  	/* Custom board node with GPIO pins to active etc */  	usb-s8815 {  		/* The S8815 is using this very GPIO pin for the SMSC91x IRQs */  		ethernet-gpio { -			gpios = <&gpio3 19 0x1>; -			interrupts = <19 0x1>; -			interrupt-parent = <&gpio3>; +			gpios = <&gpio3 8 0x1>;  		};  		/* This will bias the MMC/SD card detect line */  		mmcsd-gpio { diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts index 4a7c35d6726a..078ed7f618d7 100644 --- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts +++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts @@ -22,8 +22,8 @@  		bootargs = "earlyprintk console=ttyS0,115200";  	}; -	soc { -		uart0: uart@01c28000 { +	soc@01c20000 { +		uart0: serial@01c28000 {  			pinctrl-names = "default";  			pinctrl-0 = <&uart0_pins_a>;  			status = "okay"; diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 435d69b83e32..abbe31937c65 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -20,6 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y  CONFIG_MODVERSIONS=y  CONFIG_MODULE_SRCVERSION_ALL=y  # CONFIG_BLK_DEV_BSG is not set +CONFIG_ARCH_MULTI_V6=y  CONFIG_ARCH_OMAP2PLUS=y  CONFIG_OMAP_RESET_CLOCKS=y  CONFIG_OMAP_MUX_DEBUG=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index a5f0485133cf..f7ba316164d4 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -153,6 +153,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y  CONFIG_MEDIA_USB_SUPPORT=y  CONFIG_USB_VIDEO_CLASS=m  CONFIG_DRM=y +CONFIG_TEGRA_HOST1X=y  CONFIG_DRM_TEGRA=y  CONFIG_BACKLIGHT_LCD_SUPPORT=y  # CONFIG_LCD_CLASS_DEVICE is not set @@ -202,7 +203,7 @@ CONFIG_TEGRA20_APB_DMA=y  CONFIG_STAGING=y  CONFIG_SENSORS_ISL29018=y  CONFIG_SENSORS_ISL29028=y -CONFIG_SENSORS_AK8975=y +CONFIG_AK8975=y  CONFIG_MFD_NVEC=y  CONFIG_KEYBOARD_NVEC=y  CONFIG_SERIO_NVEC_PS2=y diff --git a/arch/arm/crypto/sha1-armv4-large.S b/arch/arm/crypto/sha1-armv4-large.S index 92c6eed7aac9..99207c45ec10 100644 --- a/arch/arm/crypto/sha1-armv4-large.S +++ b/arch/arm/crypto/sha1-armv4-large.S @@ -195,6 +195,7 @@ ENTRY(sha1_block_data_order)  	add	r3,r3,r10			@ E+=F_00_19(B,C,D)  	cmp	r14,sp  	bne	.L_00_15		@ [((11+4)*5+2)*3] +	sub	sp,sp,#25*4  #if __ARM_ARCH__<7  	ldrb	r10,[r1,#2]  	ldrb	r9,[r1,#3] @@ -290,7 +291,6 @@ ENTRY(sha1_block_data_order)  	add	r3,r3,r10			@ E+=F_00_19(B,C,D)  	ldr	r8,.LK_20_39		@ [+15+16*4] -	sub	sp,sp,#25*4  	cmn	sp,#0			@ [+3], clear carry to denote 20_39  .L_20_39_or_60_79:  	ldr	r9,[r14,#15*4] diff --git a/arch/arm/include/debug/ux500.S b/arch/arm/include/debug/ux500.S index 2848857f5b62..fbd24beeb1fa 100644 --- a/arch/arm/include/debug/ux500.S +++ b/arch/arm/include/debug/ux500.S @@ -24,9 +24,9 @@  #define U8500_UART0_PHYS_BASE	(0x80120000)  #define U8500_UART1_PHYS_BASE	(0x80121000)  #define U8500_UART2_PHYS_BASE	(0x80007000) -#define U8500_UART0_VIRT_BASE	(0xa8120000) -#define U8500_UART1_VIRT_BASE	(0xa8121000) -#define U8500_UART2_VIRT_BASE	(0xa8007000) +#define U8500_UART0_VIRT_BASE	(0xf8120000) +#define U8500_UART1_VIRT_BASE	(0xf8121000) +#define U8500_UART2_VIRT_BASE	(0xf8007000)  #define __UX500_PHYS_UART(n)	U8500_UART##n##_PHYS_BASE  #define __UX500_VIRT_UART(n)	U8500_UART##n##_VIRT_BASE  #endif diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index f21970316836..282de4826abb 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -411,7 +411,6 @@ static struct vm_area_struct gate_vma = {  	.vm_start	= 0xffff0000,  	.vm_end		= 0xffff0000 + PAGE_SIZE,  	.vm_flags	= VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC, -	.vm_mm		= &init_mm,  };  static int __init gate_vma_init(void) diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 2acdff4c1dfe..180b3024bec3 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -174,6 +174,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)  static struct clock_event_device clkevt = {  	.name		= "at91_tick",  	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, +	.shift		= 32,  	.rating		= 150,  	.set_next_event	= clkevt32k_next_event,  	.set_mode	= clkevt32k_mode, @@ -264,9 +265,11 @@ void __init at91rm9200_timer_init(void)  	at91_st_write(AT91_ST_RTMR, 1);  	/* Setup timer clockevent, with minimum of two ticks (important!!) */ +	clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); +	clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt); +	clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;  	clkevt.cpumask = cpumask_of(0); -	clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK, -					2, AT91_ST_ALMV); +	clockevents_register_device(&clkevt);  	/* register clocksource */  	clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 13cdbcd48f51..c7d670d11802 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -223,13 +223,7 @@ static void __init at91sam9n12_map_io(void)  	at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);  } -void __init at91sam9n12_initialize(void) -{ -	at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0); -} -  AT91_SOC_START(at91sam9n12)  	.map_io = at91sam9n12_map_io,  	.register_clocks = at91sam9n12_register_clocks, -	.init = at91sam9n12_initialize,  AT91_SOC_END diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 31df12029c4e..2bd7f51b0b82 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -179,9 +179,9 @@ extern void __iomem *at91_pmc_base;  #define		AT91_PMC_PCR_CMD	(0x1  <<  12)		/* Command (read=0, write=1) */  #define		AT91_PMC_PCR_DIV(n)	((n)  <<  16)		/* Divisor Value */  #define			AT91_PMC_PCR_DIV0	0x0			/* Peripheral clock is MCK */ -#define			AT91_PMC_PCR_DIV2	0x2			/* Peripheral clock is MCK/2 */ -#define			AT91_PMC_PCR_DIV4	0x4			/* Peripheral clock is MCK/4 */ -#define			AT91_PMC_PCR_DIV8	0x8			/* Peripheral clock is MCK/8 */ +#define			AT91_PMC_PCR_DIV2	0x1			/* Peripheral clock is MCK/2 */ +#define			AT91_PMC_PCR_DIV4	0x2			/* Peripheral clock is MCK/4 */ +#define			AT91_PMC_PCR_DIV8	0x3			/* Peripheral clock is MCK/8 */  #define		AT91_PMC_PCR_EN		(0x1  <<  28)		/* Enable */  #endif diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 151259003086..dda9a2bd3acb 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -177,7 +177,8 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)  static const char *step_sels[]	= { "osc", "pll2_pfd2_396m", };  static const char *pll1_sw_sels[]	= { "pll1_sys", "step", };  static const char *periph_pre_sels[]	= { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; -static const char *periph_clk2_sels[]	= { "pll3_usb_otg", "osc", }; +static const char *periph_clk2_sels[]	= { "pll3_usb_otg", "osc", "osc", "dummy", }; +static const char *periph2_clk2_sels[]	= { "pll3_usb_otg", "pll2_bus", };  static const char *periph_sels[]	= { "periph_pre", "periph_clk2", };  static const char *periph2_sels[]	= { "periph2_pre", "periph2_clk2", };  static const char *axi_sels[]		= { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; @@ -185,7 +186,7 @@ static const char *audio_sels[]	= { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd  static const char *gpu_axi_sels[]	= { "axi", "ahb", };  static const char *gpu2d_core_sels[]	= { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };  static const char *gpu3d_core_sels[]	= { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; -static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; +static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", };  static const char *ipu_sels[]		= { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };  static const char *ldb_di_sels[]	= { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", };  static const char *ipu_di_pre_sels[]	= { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; @@ -369,8 +370,8 @@ int __init mx6q_clocks_init(void)  	clk[pll1_sw]          = imx_clk_mux("pll1_sw",	        base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));  	clk[periph_pre]       = imx_clk_mux("periph_pre",       base + 0x18, 18, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels));  	clk[periph2_pre]      = imx_clk_mux("periph2_pre",      base + 0x18, 21, 2, periph_pre_sels,   ARRAY_SIZE(periph_pre_sels)); -	clk[periph_clk2_sel]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels)); -	clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels)); +	clk[periph_clk2_sel]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 2, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels)); +	clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));  	clk[axi_sel]          = imx_clk_mux("axi_sel",          base + 0x14, 6,  2, axi_sels,          ARRAY_SIZE(axi_sels));  	clk[esai_sel]         = imx_clk_mux("esai_sel",         base + 0x20, 19, 2, audio_sels,        ARRAY_SIZE(audio_sels));  	clk[asrc_sel]         = imx_clk_mux("asrc_sel",         base + 0x30, 7,  2, audio_sels,        ARRAY_SIZE(audio_sels)); @@ -498,7 +499,7 @@ int __init mx6q_clocks_init(void)  	clk[ldb_di1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      base + 0x74, 14);  	clk[ipu2_di1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      base + 0x74, 10);  	clk[hsi_tx]       = imx_clk_gate2("hsi_tx",        "hsi_tx_podf",       base + 0x74, 16); -	clk[mlb]          = imx_clk_gate2("mlb",           "pll8_mlb",          base + 0x74, 18); +	clk[mlb]          = imx_clk_gate2("mlb",           "axi",               base + 0x74, 18);  	clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20);  	clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi",  "mmdc_ch1_axi_podf", base + 0x74, 22);  	clk[ocram]        = imx_clk_gate2("ocram",         "ahb",               base + 0x74, 28); diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index 67b9c48dcafe..627f16f0e9d1 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -18,8 +18,20 @@  	.section ".text.head", "ax"  #ifdef CONFIG_SMP +diag_reg_offset: +	.word	g_diag_reg - . + +	.macro	set_diag_reg +	adr	r0, diag_reg_offset +	ldr	r1, [r0] +	add	r1, r1, r0		@ r1 = physical &g_diag_reg +	ldr	r0, [r1] +	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register +	.endm +  ENTRY(v7_secondary_startup)  	bl	v7_invalidate_l1 +	set_diag_reg  	b	secondary_startup  ENDPROC(v7_secondary_startup)  #endif diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 4a69305db65e..c6e1ab544882 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -12,6 +12,7 @@  #include <linux/init.h>  #include <linux/smp.h> +#include <asm/cacheflush.h>  #include <asm/page.h>  #include <asm/smp_scu.h>  #include <asm/mach/map.h> @@ -21,6 +22,7 @@  #define SCU_STANDBY_ENABLE	(1 << 5) +u32 g_diag_reg;  static void __iomem *scu_base;  static struct map_desc scu_io_desc __initdata = { @@ -80,6 +82,18 @@ void imx_smp_prepare(void)  static void __init imx_smp_prepare_cpus(unsigned int max_cpus)  {  	imx_smp_prepare(); + +	/* +	 * The diagnostic register holds the errata bits.  Mostly bootloader +	 * does not bring up secondary cores, so that when errata bits are set +	 * in bootloader, they are set only for boot cpu.  But on a SMP +	 * configuration, it should be equally done on every single core. +	 * Read the register from boot cpu here, and will replicate it into +	 * secondary cores when booting them. +	 */ +	asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc"); +	__cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg)); +	outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1));  }  struct smp_operations  imx_smp_ops __initdata = { diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c2cae69e6d2b..f38922897563 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -528,12 +528,6 @@ void __init kirkwood_init_early(void)  {  	orion_time_set_base(TIMER_VIRT_BASE); -	/* -	 * Some Kirkwood devices allocate their coherent buffers from atomic -	 * context. Increase size of atomic coherent pool to make sure such -	 * the allocations won't fail. -	 */ -	init_dma_coherent_pool_size(SZ_1M);  	mvebu_mbus_init("marvell,kirkwood-mbus",  			BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,  			DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ); diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c index 283abff90228..e1267d6b468f 100644 --- a/arch/arm/mach-kirkwood/ts219-setup.c +++ b/arch/arm/mach-kirkwood/ts219-setup.c @@ -124,7 +124,7 @@ static void __init qnap_ts219_init(void)  static int __init ts219_pci_init(void)  {  	if (machine_is_ts219()) -		kirkwood_pcie_init(KW_PCIE0); +		kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);  	return 0;  } diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index e11acbb0a46d..80a8bcacd9d5 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -15,6 +15,7 @@ config ARCH_MVEBU  	select MVEBU_CLK_GATING  	select MVEBU_MBUS  	select ZONE_DMA if ARM_LPAE +	select ARCH_REQUIRE_GPIOLIB  if ARCH_MVEBU diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index 42a4cb3087e2..1c48890bb72b 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -54,13 +54,6 @@ void __init armada_370_xp_init_early(void)  	char *mbus_soc_name;  	/* -	 * Some Armada 370/XP devices allocate their coherent buffers -	 * from atomic context. Increase size of atomic coherent pool -	 * to make sure such the allocations won't fail. -	 */ -	init_dma_coherent_pool_size(SZ_1M); - -	/*  	 * This initialization will be replaced by a DT-based  	 * initialization once the mvebu-mbus driver gains DT support.  	 */ diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 68ab858e27b7..a94b3a718d1a 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -345,6 +345,7 @@ static int __init omap1_system_dma_init(void)  		dev_err(&pdev->dev,  			"%s: Memory allocation failed for d->chan!\n",  			__func__); +		ret = -ENOMEM;  		goto exit_release_d;  	} diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c index 6ebc7803bc3e..af3544ce4f02 100644 --- a/arch/arm/mach-omap2/cclock33xx_data.c +++ b/arch/arm/mach-omap2/cclock33xx_data.c @@ -454,9 +454,29 @@ DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,   */  DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732); -DEFINE_CLK_GATE(clkdiv32k_ick, "clkdiv32k_ck", &clkdiv32k_ck, 0x0, -		AM33XX_CM_PER_CLKDIV32K_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); +static struct clk clkdiv32k_ick; + +static const char *clkdiv32k_ick_parent_names[] = { +	"clkdiv32k_ck", +}; + +static const struct clk_ops clkdiv32k_ick_ops = { +	.enable         = &omap2_dflt_clk_enable, +	.disable        = &omap2_dflt_clk_disable, +	.is_enabled     = &omap2_dflt_clk_is_enabled, +	.init           = &omap2_init_clk_clkdm, +}; + +static struct clk_hw_omap clkdiv32k_ick_hw = { +	.hw	= { +		.clk	= &clkdiv32k_ick, +	}, +	.enable_reg	= AM33XX_CM_PER_CLKDIV32K_CLKCTRL, +	.enable_bit	= AM33XX_MODULEMODE_SWCTRL_SHIFT, +	.clkdm_name	= "clk_24mhz_clkdm", +}; + +DEFINE_STRUCT_CLK(clkdiv32k_ick, clkdiv32k_ick_parent_names, clkdiv32k_ick_ops);  /* "usbotg_fck" is an additional clock and not really a modulemode */  DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0, diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d25a95fe9921..7341eff63f56 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1356,13 +1356,27 @@ static void _enable_sysc(struct omap_hwmod *oh)  	clkdm = _get_clkdm(oh);  	if (sf & SYSC_HAS_SIDLEMODE) { +		if (oh->flags & HWMOD_SWSUP_SIDLE || +		    oh->flags & HWMOD_SWSUP_SIDLE_ACT) { +			idlemode = HWMOD_IDLEMODE_NO; +		} else { +			if (sf & SYSC_HAS_ENAWAKEUP) +				_enable_wakeup(oh, &v); +			if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) +				idlemode = HWMOD_IDLEMODE_SMART_WKUP; +			else +				idlemode = HWMOD_IDLEMODE_SMART; +		} + +		/* +		 * This is special handling for some IPs like +		 * 32k sync timer. Force them to idle! +		 */  		clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);  		if (clkdm_act && !(oh->class->sysc->idlemodes &  				   (SIDLE_SMART | SIDLE_SMART_WKUP)))  			idlemode = HWMOD_IDLEMODE_FORCE; -		else -			idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? -				HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; +  		_set_slave_idlemode(oh, idlemode, &v);  	} @@ -1391,10 +1405,6 @@ static void _enable_sysc(struct omap_hwmod *oh)  	    (sf & SYSC_HAS_CLOCKACTIVITY))  		_set_clockactivity(oh, oh->class->sysc->clockact, &v); -	/* If slave is in SMARTIDLE, also enable wakeup */ -	if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE)) -		_enable_wakeup(oh, &v); -  	_write_sysconfig(v, oh);  	/* @@ -1430,13 +1440,16 @@ static void _idle_sysc(struct omap_hwmod *oh)  	sf = oh->class->sysc->sysc_flags;  	if (sf & SYSC_HAS_SIDLEMODE) { -		/* XXX What about HWMOD_IDLEMODE_SMART_WKUP? */ -		if (oh->flags & HWMOD_SWSUP_SIDLE || -		    !(oh->class->sysc->idlemodes & -		      (SIDLE_SMART | SIDLE_SMART_WKUP))) +		if (oh->flags & HWMOD_SWSUP_SIDLE) {  			idlemode = HWMOD_IDLEMODE_FORCE; -		else -			idlemode = HWMOD_IDLEMODE_SMART; +		} else { +			if (sf & SYSC_HAS_ENAWAKEUP) +				_enable_wakeup(oh, &v); +			if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) +				idlemode = HWMOD_IDLEMODE_SMART_WKUP; +			else +				idlemode = HWMOD_IDLEMODE_SMART; +		}  		_set_slave_idlemode(oh, idlemode, &v);  	} @@ -1455,10 +1468,6 @@ static void _idle_sysc(struct omap_hwmod *oh)  		_set_master_standbymode(oh, idlemode, &v);  	} -	/* If slave is in SMARTIDLE, also enable wakeup */ -	if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE)) -		_enable_wakeup(oh, &v); -  	_write_sysconfig(v, oh);  } @@ -2065,7 +2074,7 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh)   * do so is present in the hwmod data, then call it and pass along the   * return value; otherwise, return 0.   */ -static int __init _enable_preprogram(struct omap_hwmod *oh) +static int _enable_preprogram(struct omap_hwmod *oh)  {  	if (!oh->class->enable_preprogram)  		return 0; @@ -2246,42 +2255,6 @@ static int _idle(struct omap_hwmod *oh)  }  /** - * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit - * @oh: struct omap_hwmod * - * @autoidle: desired AUTOIDLE bitfield value (0 or 1) - * - * Sets the IP block's OCP autoidle bit in hardware, and updates our - * local copy. Intended to be used by drivers that require - * direct manipulation of the AUTOIDLE bits. - * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes - * along the return value from _set_module_autoidle(). - * - * Any users of this function should be scrutinized carefully. - */ -int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle) -{ -	u32 v; -	int retval = 0; -	unsigned long flags; - -	if (!oh || oh->_state != _HWMOD_STATE_ENABLED) -		return -EINVAL; - -	spin_lock_irqsave(&oh->_lock, flags); - -	v = oh->_sysc_cache; - -	retval = _set_module_autoidle(oh, autoidle, &v); - -	if (!retval) -		_write_sysconfig(v, oh); - -	spin_unlock_irqrestore(&oh->_lock, flags); - -	return retval; -} - -/**   * _shutdown - shutdown an omap_hwmod   * @oh: struct omap_hwmod *   * @@ -3180,38 +3153,6 @@ error:  }  /** - * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode - * @oh: struct omap_hwmod * - * @idlemode: SIDLEMODE field bits (shifted to bit 0) - * - * Sets the IP block's OCP slave idlemode in hardware, and updates our - * local copy.  Intended to be used by drivers that have some erratum - * that requires direct manipulation of the SIDLEMODE bits.  Returns - * -EINVAL if @oh is null, or passes along the return value from - * _set_slave_idlemode(). - * - * XXX Does this function have any current users?  If not, we should - * remove it; it is better to let the rest of the hwmod code handle this. - * Any users of this function should be scrutinized carefully. - */ -int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode) -{ -	u32 v; -	int retval = 0; - -	if (!oh) -		return -EINVAL; - -	v = oh->_sysc_cache; - -	retval = _set_slave_idlemode(oh, idlemode, &v); -	if (!retval) -		_write_sysconfig(v, oh); - -	return retval; -} - -/**   * omap_hwmod_lookup - look up a registered omap_hwmod by name   * @name: name of the omap_hwmod to look up   * diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index fe5962921f07..0c898f58ac9b 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -463,6 +463,9 @@ struct omap_hwmod_omap4_prcm {   *     is kept in force-standby mode. Failing to do so causes PM problems   *     with musb on OMAP3630 at least. Note that musb has a dedicated register   *     to control MSTANDBY signal when MIDLEMODE is set to force-standby. + * HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module + *     out of idle, but rely on smart-idle to the put it back in idle, + *     so the wakeups are still functional (Only known case for now is UART)   */  #define HWMOD_SWSUP_SIDLE			(1 << 0)  #define HWMOD_SWSUP_MSTANDBY			(1 << 1) @@ -476,6 +479,7 @@ struct omap_hwmod_omap4_prcm {  #define HWMOD_EXT_OPT_MAIN_CLK			(1 << 9)  #define HWMOD_BLOCK_WFI				(1 << 10)  #define HWMOD_FORCE_MSTANDBY			(1 << 11) +#define HWMOD_SWSUP_SIDLE_ACT			(1 << 12)  /*   * omap_hwmod._int_flags definitions @@ -641,9 +645,6 @@ int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);  int omap_hwmod_enable_clocks(struct omap_hwmod *oh);  int omap_hwmod_disable_clocks(struct omap_hwmod *oh); -int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode); -int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle); -  int omap_hwmod_reset(struct omap_hwmod *oh);  void omap_hwmod_ocp_barrier(struct omap_hwmod *oh); diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index c8c64b3e1acc..d05fc7b54567 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -512,6 +512,7 @@ struct omap_hwmod omap2xxx_uart1_hwmod = {  	.mpu_irqs	= omap2_uart1_mpu_irqs,  	.sdma_reqs	= omap2_uart1_sdma_reqs,  	.main_clk	= "uart1_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = CORE_MOD, @@ -531,6 +532,7 @@ struct omap_hwmod omap2xxx_uart2_hwmod = {  	.mpu_irqs	= omap2_uart2_mpu_irqs,  	.sdma_reqs	= omap2_uart2_sdma_reqs,  	.main_clk	= "uart2_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = CORE_MOD, @@ -550,6 +552,7 @@ struct omap_hwmod omap2xxx_uart3_hwmod = {  	.mpu_irqs	= omap2_uart3_mpu_irqs,  	.sdma_reqs	= omap2_uart3_sdma_reqs,  	.main_clk	= "uart3_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = CORE_MOD, diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 01d8f324450a..075f7cc51026 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1995,6 +1995,7 @@ static struct omap_hwmod am33xx_uart1_hwmod = {  	.name		= "uart1",  	.class		= &uart_class,  	.clkdm_name	= "l4_wkup_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= am33xx_uart1_irqs,  	.sdma_reqs	= uart1_edma_reqs,  	.main_clk	= "dpll_per_m2_div4_wkupdm_ck", @@ -2015,6 +2016,7 @@ static struct omap_hwmod am33xx_uart2_hwmod = {  	.name		= "uart2",  	.class		= &uart_class,  	.clkdm_name	= "l4ls_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= am33xx_uart2_irqs,  	.sdma_reqs	= uart1_edma_reqs,  	.main_clk	= "dpll_per_m2_div4_ck", @@ -2042,6 +2044,7 @@ static struct omap_hwmod am33xx_uart3_hwmod = {  	.name		= "uart3",  	.class		= &uart_class,  	.clkdm_name	= "l4ls_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= am33xx_uart3_irqs,  	.sdma_reqs	= uart3_edma_reqs,  	.main_clk	= "dpll_per_m2_div4_ck", @@ -2062,6 +2065,7 @@ static struct omap_hwmod am33xx_uart4_hwmod = {  	.name		= "uart4",  	.class		= &uart_class,  	.clkdm_name	= "l4ls_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= am33xx_uart4_irqs,  	.sdma_reqs	= uart1_edma_reqs,  	.main_clk	= "dpll_per_m2_div4_ck", @@ -2082,6 +2086,7 @@ static struct omap_hwmod am33xx_uart5_hwmod = {  	.name		= "uart5",  	.class		= &uart_class,  	.clkdm_name	= "l4ls_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= am33xx_uart5_irqs,  	.sdma_reqs	= uart1_edma_reqs,  	.main_clk	= "dpll_per_m2_div4_ck", @@ -2102,6 +2107,7 @@ static struct omap_hwmod am33xx_uart6_hwmod = {  	.name		= "uart6",  	.class		= &uart_class,  	.clkdm_name	= "l4ls_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= am33xx_uart6_irqs,  	.sdma_reqs	= uart1_edma_reqs,  	.main_clk	= "dpll_per_m2_div4_ck", diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 4083606ea1da..31c7126eb3bb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -490,6 +490,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = {  	.mpu_irqs	= omap2_uart1_mpu_irqs,  	.sdma_reqs	= omap2_uart1_sdma_reqs,  	.main_clk	= "uart1_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = CORE_MOD, @@ -508,6 +509,7 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = {  	.mpu_irqs	= omap2_uart2_mpu_irqs,  	.sdma_reqs	= omap2_uart2_sdma_reqs,  	.main_clk	= "uart2_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = CORE_MOD, @@ -526,6 +528,7 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = {  	.mpu_irqs	= omap2_uart3_mpu_irqs,  	.sdma_reqs	= omap2_uart3_sdma_reqs,  	.main_clk	= "uart3_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = OMAP3430_PER_MOD, @@ -555,6 +558,7 @@ static struct omap_hwmod omap36xx_uart4_hwmod = {  	.mpu_irqs	= uart4_mpu_irqs,  	.sdma_reqs	= uart4_sdma_reqs,  	.main_clk	= "uart4_fck", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.prcm		= {  		.omap2 = {  			.module_offs = OMAP3430_PER_MOD, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index eaba9dc91a0d..848b6dc67590 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -3434,6 +3434,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {  	.name		= "uart1",  	.class		= &omap44xx_uart_hwmod_class,  	.clkdm_name	= "l4_per_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= omap44xx_uart1_irqs,  	.sdma_reqs	= omap44xx_uart1_sdma_reqs,  	.main_clk	= "func_48m_fclk", @@ -3462,6 +3463,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {  	.name		= "uart2",  	.class		= &omap44xx_uart_hwmod_class,  	.clkdm_name	= "l4_per_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= omap44xx_uart2_irqs,  	.sdma_reqs	= omap44xx_uart2_sdma_reqs,  	.main_clk	= "func_48m_fclk", @@ -3490,7 +3492,8 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {  	.name		= "uart3",  	.class		= &omap44xx_uart_hwmod_class,  	.clkdm_name	= "l4_per_clkdm", -	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, +	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | +				HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= omap44xx_uart3_irqs,  	.sdma_reqs	= omap44xx_uart3_sdma_reqs,  	.main_clk	= "func_48m_fclk", @@ -3519,6 +3522,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {  	.name		= "uart4",  	.class		= &omap44xx_uart_hwmod_class,  	.clkdm_name	= "l4_per_clkdm", +	.flags		= HWMOD_SWSUP_SIDLE_ACT,  	.mpu_irqs	= omap44xx_uart4_irqs,  	.sdma_reqs	= omap44xx_uart4_sdma_reqs,  	.main_clk	= "func_48m_fclk", diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 8396b5b7e912..f6601563aa69 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -95,38 +95,9 @@ static void omap_uart_enable_wakeup(struct device *dev, bool enable)  		omap_hwmod_disable_wakeup(od->hwmods[0]);  } -/* - * Errata i291: [UART]:Cannot Acknowledge Idle Requests - * in Smartidle Mode When Configured for DMA Operations. - * WA: configure uart in force idle mode. - */ -static void omap_uart_set_noidle(struct device *dev) -{ -	struct platform_device *pdev = to_platform_device(dev); -	struct omap_device *od = to_omap_device(pdev); - -	omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); -} - -static void omap_uart_set_smartidle(struct device *dev) -{ -	struct platform_device *pdev = to_platform_device(dev); -	struct omap_device *od = to_omap_device(pdev); -	u8 idlemode; - -	if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) -		idlemode = HWMOD_IDLEMODE_SMART_WKUP; -	else -		idlemode = HWMOD_IDLEMODE_SMART; - -	omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode); -} -  #else  static void omap_uart_enable_wakeup(struct device *dev, bool enable)  {} -static void omap_uart_set_noidle(struct device *dev) {} -static void omap_uart_set_smartidle(struct device *dev) {}  #endif /* CONFIG_PM */  #ifdef CONFIG_OMAP_MUX @@ -299,8 +270,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,  	omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;  	omap_up.flags = UPF_BOOT_AUTOCONF;  	omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; -	omap_up.set_forceidle = omap_uart_set_smartidle; -	omap_up.set_noidle = omap_uart_set_noidle;  	omap_up.enable_wakeup = omap_uart_enable_wakeup;  	omap_up.dma_rx_buf_size = info->dma_rx_buf_size;  	omap_up.dma_rx_timeout = info->dma_rx_timeout; diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index b97fd672e89d..f8a6db9239bf 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -199,13 +199,6 @@ void __init orion5x_init_early(void)  	orion_time_set_base(TIMER_VIRT_BASE); -	/* -	 * Some Orion5x devices allocate their coherent buffers from atomic -	 * context. Increase size of atomic coherent pool to make sure such -	 * the allocations won't fail. -	 */ -	init_dma_coherent_pool_size(SZ_1M); -  	/* Initialize the MBUS driver */  	orion5x_pcie_id(&dev, &rev);  	if (dev == MV88F5281_DEV_ID) diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 91052855cc12..b9594e911ce7 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -212,8 +212,8 @@ static struct platform_device *marzen_devices[] __initdata = {  static struct usb_phy *phy;  static int usb_power_on(struct platform_device *pdev)  { -	if (!phy) -		return -EIO; +	if (IS_ERR(phy)) +		return PTR_ERR(phy);  	pm_runtime_enable(&pdev->dev);  	pm_runtime_get_sync(&pdev->dev); @@ -225,7 +225,7 @@ static int usb_power_on(struct platform_device *pdev)  static void usb_power_off(struct platform_device *pdev)  { -	if (!phy) +	if (IS_ERR(phy))  		return;  	usb_phy_shutdown(phy); diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index d259c782d742..5b045e302b43 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -1,5 +1,6 @@  config ARCH_SUNXI  	bool "Allwinner A1X SOCs" if ARCH_MULTI_V7 +	select ARCH_REQUIRE_GPIOLIB  	select CLKSRC_MMIO  	select CLKSRC_OF  	select COMMON_CLK diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 6a4387e39df8..b19b07204aaf 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -51,6 +51,7 @@ config MACH_MOP500  	bool "U8500 Development platform, MOP500 versions"  	select I2C  	select I2C_NOMADIK +	select REGULATOR  	select REGULATOR_FIXED_VOLTAGE  	select SOC_BUS  	select UX500_SOC_DB8500 diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 3cd555ac6d0a..78389de94dde 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -623,7 +623,7 @@ static void __init mop500_init_machine(void)  	sdi0_reg_info.gpios[0].gpio = GPIO_SDMMC_1V8_3V_SEL;  	mop500_pinmaps_init(); -	parent = u8500_init_devices(&ab8500_platdata); +	parent = u8500_init_devices();  	for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)  		mop500_platform_devs[i]->dev.parent = parent; @@ -660,7 +660,7 @@ static void __init snowball_init_machine(void)  	sdi0_reg_info.gpios[0].gpio = SNOWBALL_SDMMC_1V8_3V_GPIO;  	snowball_pinmaps_init(); -	parent = u8500_init_devices(&ab8500_platdata); +	parent = u8500_init_devices();  	for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)  		snowball_platform_devs[i]->dev.parent = parent; @@ -698,7 +698,7 @@ static void __init hrefv60_init_machine(void)  	sdi0_reg_info.gpios[0].gpio = HREFV60_SDMMC_1V8_3V_GPIO;  	hrefv60_pinmaps_init(); -	parent = u8500_init_devices(&ab8500_platdata); +	parent = u8500_init_devices();  	for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)  		mop500_platform_devs[i]->dev.parent = parent; diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index e90b5ab23b6d..46cca52890bc 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -206,7 +206,7 @@ static struct device * __init db8500_soc_device_init(void)  /*   * This function is called from the board init   */ -struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) +struct device * __init u8500_init_devices(void)  {  	struct device *parent;  	int i; @@ -220,8 +220,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500)  	for (i = 0; i < ARRAY_SIZE(platform_devs); i++)  		platform_devs[i]->dev.parent = parent; -	db8500_prcmu_device.dev.platform_data = ab8500; -  	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));  	return parent; @@ -278,7 +276,7 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {  	OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),  	OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",  			&db8500_prcmu_pdata), -	OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x", NULL), +	OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x.0", NULL),  	/* Requires device name bindings. */  	OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,  		"pinctrl-db8500", NULL), diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h index bddce2b49372..cad3ca86c540 100644 --- a/arch/arm/mach-ux500/setup.h +++ b/arch/arm/mach-ux500/setup.h @@ -18,7 +18,7 @@  void __init ux500_map_io(void);  extern void __init u8500_map_io(void); -extern struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500); +extern struct device * __init u8500_init_devices(void);  extern void __init ux500_init_irq(void);  extern void __init ux500_init_late(void); diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c index 1dd281efc020..f5c33df7a597 100644 --- a/arch/arm/mach-vt8500/vt8500.c +++ b/arch/arm/mach-vt8500/vt8500.c @@ -173,6 +173,7 @@ static const char * const vt8500_dt_compat[] = {  	"wm,wm8505",  	"wm,wm8750",  	"wm,wm8850", +	NULL  };  DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)") diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 251f827271e9..c019b7aaf776 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -383,7 +383,7 @@ static struct resource orion_ge10_shared_resources[] = {  static struct platform_device orion_ge10_shared = {  	.name		= MV643XX_ETH_SHARED_NAME, -	.id		= 1, +	.id		= 2,  	.dev		= {  		.platform_data	= &orion_ge10_shared_data,  	}, @@ -398,8 +398,8 @@ static struct resource orion_ge10_resources[] = {  static struct platform_device orion_ge10 = {  	.name		= MV643XX_ETH_NAME, -	.id		= 1, -	.num_resources	= 2, +	.id		= 2, +	.num_resources	= 1,  	.resource	= orion_ge10_resources,  	.dev		= {  		.coherent_dma_mask	= DMA_BIT_MASK(32), @@ -432,7 +432,7 @@ static struct resource orion_ge11_shared_resources[] = {  static struct platform_device orion_ge11_shared = {  	.name		= MV643XX_ETH_SHARED_NAME, -	.id		= 1, +	.id		= 3,  	.dev		= {  		.platform_data	= &orion_ge11_shared_data,  	}, @@ -447,8 +447,8 @@ static struct resource orion_ge11_resources[] = {  static struct platform_device orion_ge11 = {  	.name		= MV643XX_ETH_NAME, -	.id		= 1, -	.num_resources	= 2, +	.id		= 3, +	.num_resources	= 1,  	.resource	= orion_ge11_resources,  	.dev		= {  		.coherent_dma_mask	= DMA_BIT_MASK(32), diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index e06fc5fefa14..d9a24f605a2b 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -10,6 +10,7 @@  #ifndef __PLAT_COMMON_H  #include <linux/mv643xx_eth.h> +#include <linux/platform_data/usb-ehci-orion.h>  struct dsa_platform_data;  struct mv_sata_platform_data; diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index 323ce1a62bbf..46e17492fd1f 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S @@ -60,7 +60,7 @@ ENTRY(vfp_testing_entry)  	str	r11, [r10, #TI_PREEMPT]  #endif  	ldr	r0, VFP_arch_address -	str	r5, [r0]		@ known non-zero value +	str	r0, [r0]		@ set to non-zero value  	mov	pc, r9			@ we have handled the fault  ENDPROC(vfp_testing_entry) diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index d8f988a37d16..0940682ab38b 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c @@ -41,8 +41,6 @@  unsigned long empty_zero_page;  EXPORT_SYMBOL_GPL(empty_zero_page); -static struct kcore_list kcore_mem, kcore_vmalloc; -  static void setup_zero_page(void)  {  	struct page *page; diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index ecb743bf05a5..536562c626a2 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -24,7 +24,7 @@ acpi-y				+= nvs.o  # Power management related files  acpi-y				+= wakeup.o  acpi-y				+= sleep.o -acpi-$(CONFIG_PM)		+= device_pm.o +acpi-y				+= device_pm.o  acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o @@ -38,7 +38,6 @@ acpi-y				+= processor_core.o  acpi-y				+= ec.o  acpi-$(CONFIG_ACPI_DOCK)	+= dock.o  acpi-y				+= pci_root.o pci_link.o pci_irq.o -acpi-y				+= csrt.o  acpi-$(CONFIG_X86_INTEL_LPSS)	+= acpi_lpss.o  acpi-y				+= acpi_platform.o  acpi-y				+= power.o diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index b1c95422ce74..652fd5ce303c 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -35,11 +35,16 @@ ACPI_MODULE_NAME("acpi_lpss");  struct lpss_device_desc {  	bool clk_required; -	const char *clk_parent; +	const char *clkdev_name;  	bool ltr_required;  	unsigned int prv_offset;  }; +static struct lpss_device_desc lpss_dma_desc = { +	.clk_required = true, +	.clkdev_name = "hclk", +}; +  struct lpss_private_data {  	void __iomem *mmio_base;  	resource_size_t mmio_size; @@ -49,7 +54,6 @@ struct lpss_private_data {  static struct lpss_device_desc lpt_dev_desc = {  	.clk_required = true, -	.clk_parent = "lpss_clk",  	.prv_offset = 0x800,  	.ltr_required = true,  }; @@ -60,6 +64,9 @@ static struct lpss_device_desc lpt_sdio_dev_desc = {  };  static const struct acpi_device_id acpi_lpss_device_ids[] = { +	/* Generic LPSS devices */ +	{ "INTL9C60", (unsigned long)&lpss_dma_desc }, +  	/* Lynxpoint LPSS devices */  	{ "INT33C0", (unsigned long)&lpt_dev_desc },  	{ "INT33C1", (unsigned long)&lpt_dev_desc }, @@ -91,16 +98,27 @@ static int register_device_clock(struct acpi_device *adev,  				 struct lpss_private_data *pdata)  {  	const struct lpss_device_desc *dev_desc = pdata->dev_desc; +	struct lpss_clk_data *clk_data;  	if (!lpss_clk_dev)  		lpt_register_clock_device(); -	if (!dev_desc->clk_parent || !pdata->mmio_base +	clk_data = platform_get_drvdata(lpss_clk_dev); +	if (!clk_data) +		return -ENODEV; + +	if (dev_desc->clkdev_name) { +		clk_register_clkdev(clk_data->clk, dev_desc->clkdev_name, +				    dev_name(&adev->dev)); +		return 0; +	} + +	if (!pdata->mmio_base  	    || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)  		return -ENODATA;  	pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev), -				       dev_desc->clk_parent, 0, +				       clk_data->name, 0,  				       pdata->mmio_base + dev_desc->prv_offset,  				       0, 0, NULL);  	if (IS_ERR(pdata->clk)) diff --git a/drivers/acpi/csrt.c b/drivers/acpi/csrt.c deleted file mode 100644 index 5c15a91faf0b..000000000000 --- a/drivers/acpi/csrt.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Support for Core System Resources Table (CSRT) - * - * Copyright (C) 2013, Intel Corporation - * Authors: Mika Westerberg <mika.westerberg@linux.intel.com> - *	    Andy Shevchenko <andriy.shevchenko@linux.intel.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. - */ - -#define pr_fmt(fmt) "ACPI: CSRT: " fmt - -#include <linux/acpi.h> -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/sizes.h> - -ACPI_MODULE_NAME("CSRT"); - -static int __init acpi_csrt_parse_shared_info(struct platform_device *pdev, -					      const struct acpi_csrt_group *grp) -{ -	const struct acpi_csrt_shared_info *si; -	struct resource res[3]; -	size_t nres; -	int ret; - -	memset(res, 0, sizeof(res)); -	nres = 0; - -	si = (const struct acpi_csrt_shared_info *)&grp[1]; -	/* -	 * The peripherals that are listed on CSRT typically support only -	 * 32-bit addresses so we only use the low part of MMIO base for -	 * now. -	 */ -	if (!si->mmio_base_high && si->mmio_base_low) { -		/* -		 * There is no size of the memory resource in shared_info -		 * so we assume that it is 4k here. -		 */ -		res[nres].start = si->mmio_base_low; -		res[nres].end = res[0].start + SZ_4K - 1; -		res[nres++].flags = IORESOURCE_MEM; -	} - -	if (si->gsi_interrupt) { -		int irq = acpi_register_gsi(NULL, si->gsi_interrupt, -					    si->interrupt_mode, -					    si->interrupt_polarity); -		res[nres].start = irq; -		res[nres].end = irq; -		res[nres++].flags = IORESOURCE_IRQ; -	} - -	if (si->base_request_line || si->num_handshake_signals) { -		/* -		 * We pass the driver a DMA resource describing the range -		 * of request lines the device supports. -		 */ -		res[nres].start = si->base_request_line; -		res[nres].end = res[nres].start + si->num_handshake_signals - 1; -		res[nres++].flags = IORESOURCE_DMA; -	} - -	ret = platform_device_add_resources(pdev, res, nres); -	if (ret) { -		if (si->gsi_interrupt) -			acpi_unregister_gsi(si->gsi_interrupt); -		return ret; -	} - -	return 0; -} - -static int __init -acpi_csrt_parse_resource_group(const struct acpi_csrt_group *grp) -{ -	struct platform_device *pdev; -	char vendor[5], name[16]; -	int ret, i; - -	vendor[0] = grp->vendor_id; -	vendor[1] = grp->vendor_id >> 8; -	vendor[2] = grp->vendor_id >> 16; -	vendor[3] = grp->vendor_id >> 24; -	vendor[4] = '\0'; - -	if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) -		return -ENODEV; - -	snprintf(name, sizeof(name), "%s%04X", vendor, grp->device_id); -	pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO); -	if (!pdev) -		return -ENOMEM; - -	/* Add resources based on the shared info */ -	ret = acpi_csrt_parse_shared_info(pdev, grp); -	if (ret) -		goto fail; - -	ret = platform_device_add(pdev); -	if (ret) -		goto fail; - -	for (i = 0; i < pdev->num_resources; i++) -		dev_dbg(&pdev->dev, "%pR\n", &pdev->resource[i]); - -	return 0; - -fail: -	platform_device_put(pdev); -	return ret; -} - -/* - * CSRT or Core System Resources Table is a proprietary ACPI table - * introduced by Microsoft. This table can contain devices that are not in - * the system DSDT table. In particular DMA controllers might be described - * here. - * - * We present these devices as normal platform devices that don't have ACPI - * IDs or handle. The platform device name will be something like - * <VENDOR><DEVID>.<n>.auto for example: INTL9C06.0.auto. - */ -void __init acpi_csrt_init(void) -{ -	struct acpi_csrt_group *grp, *end; -	struct acpi_table_csrt *csrt; -	acpi_status status; -	int ret; - -	status = acpi_get_table(ACPI_SIG_CSRT, 0, -				(struct acpi_table_header **)&csrt); -	if (ACPI_FAILURE(status)) { -		if (status != AE_NOT_FOUND) -			pr_warn("failed to get the CSRT table\n"); -		return; -	} - -	pr_debug("parsing CSRT table for devices\n"); - -	grp = (struct acpi_csrt_group *)(csrt + 1); -	end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); - -	while (grp < end) { -		ret = acpi_csrt_parse_resource_group(grp); -		if (ret) { -			pr_warn("error in parsing resource group: %d\n", ret); -			return; -		} - -		grp = (struct acpi_csrt_group *)((void *)grp + grp->length); -	} -} diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 96de787e6104..bc493aa3af19 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -37,68 +37,6 @@  #define _COMPONENT	ACPI_POWER_COMPONENT  ACPI_MODULE_NAME("device_pm"); -static DEFINE_MUTEX(acpi_pm_notifier_lock); - -/** - * acpi_add_pm_notifier - Register PM notifier for given ACPI device. - * @adev: ACPI device to add the notifier for. - * @context: Context information to pass to the notifier routine. - * - * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of - * PM wakeup events.  For example, wakeup events may be generated for bridges - * if one of the devices below the bridge is signaling wakeup, even if the - * bridge itself doesn't have a wakeup GPE associated with it. - */ -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, -				 acpi_notify_handler handler, void *context) -{ -	acpi_status status = AE_ALREADY_EXISTS; - -	mutex_lock(&acpi_pm_notifier_lock); - -	if (adev->wakeup.flags.notifier_present) -		goto out; - -	status = acpi_install_notify_handler(adev->handle, -					     ACPI_SYSTEM_NOTIFY, -					     handler, context); -	if (ACPI_FAILURE(status)) -		goto out; - -	adev->wakeup.flags.notifier_present = true; - - out: -	mutex_unlock(&acpi_pm_notifier_lock); -	return status; -} - -/** - * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. - * @adev: ACPI device to remove the notifier from. - */ -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, -				    acpi_notify_handler handler) -{ -	acpi_status status = AE_BAD_PARAMETER; - -	mutex_lock(&acpi_pm_notifier_lock); - -	if (!adev->wakeup.flags.notifier_present) -		goto out; - -	status = acpi_remove_notify_handler(adev->handle, -					    ACPI_SYSTEM_NOTIFY, -					    handler); -	if (ACPI_FAILURE(status)) -		goto out; - -	adev->wakeup.flags.notifier_present = false; - - out: -	mutex_unlock(&acpi_pm_notifier_lock); -	return status; -} -  /**   * acpi_power_state_string - String representation of ACPI device power state.   * @state: ACPI device power state to return the string representation of. @@ -385,6 +323,69 @@ bool acpi_bus_power_manageable(acpi_handle handle)  }  EXPORT_SYMBOL(acpi_bus_power_manageable); +#ifdef CONFIG_PM +static DEFINE_MUTEX(acpi_pm_notifier_lock); + +/** + * acpi_add_pm_notifier - Register PM notifier for given ACPI device. + * @adev: ACPI device to add the notifier for. + * @context: Context information to pass to the notifier routine. + * + * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of + * PM wakeup events.  For example, wakeup events may be generated for bridges + * if one of the devices below the bridge is signaling wakeup, even if the + * bridge itself doesn't have a wakeup GPE associated with it. + */ +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, +				 acpi_notify_handler handler, void *context) +{ +	acpi_status status = AE_ALREADY_EXISTS; + +	mutex_lock(&acpi_pm_notifier_lock); + +	if (adev->wakeup.flags.notifier_present) +		goto out; + +	status = acpi_install_notify_handler(adev->handle, +					     ACPI_SYSTEM_NOTIFY, +					     handler, context); +	if (ACPI_FAILURE(status)) +		goto out; + +	adev->wakeup.flags.notifier_present = true; + + out: +	mutex_unlock(&acpi_pm_notifier_lock); +	return status; +} + +/** + * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. + * @adev: ACPI device to remove the notifier from. + */ +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, +				    acpi_notify_handler handler) +{ +	acpi_status status = AE_BAD_PARAMETER; + +	mutex_lock(&acpi_pm_notifier_lock); + +	if (!adev->wakeup.flags.notifier_present) +		goto out; + +	status = acpi_remove_notify_handler(adev->handle, +					    ACPI_SYSTEM_NOTIFY, +					    handler); +	if (ACPI_FAILURE(status)) +		goto out; + +	adev->wakeup.flags.notifier_present = false; + + out: +	mutex_unlock(&acpi_pm_notifier_lock); +	return status; +} +  bool acpi_bus_can_wakeup(acpi_handle handle)  {  	struct acpi_device *device; @@ -1023,3 +1024,4 @@ void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev)  	mutex_unlock(&adev->physical_node_lock);  }  EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent); +#endif /* CONFIG_PM */ diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 6f1afd9118c8..297cbf456f86 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -35,7 +35,6 @@ void acpi_pci_link_init(void);  void acpi_pci_root_hp_init(void);  void acpi_platform_init(void);  int acpi_sysfs_init(void); -void acpi_csrt_init(void);  #ifdef CONFIG_ACPI_CONTAINER  void acpi_container_init(void);  #else diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c1bc608339a6..44225cb15f3a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2043,7 +2043,6 @@ int __init acpi_scan_init(void)  	acpi_pci_link_init();  	acpi_platform_init();  	acpi_lpss_init(); -	acpi_csrt_init();  	acpi_container_init();  	acpi_memory_hotplug_init(); diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 66f67626f02e..e6bd910bc6ed 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -161,6 +161,14 @@ static struct dmi_system_id video_detect_dmi_table[] = {  		DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),  		},  	}, +	{ +	.callback = video_detect_force_vendor, +	.ident = "Asus UL30A", +	.matches = { +		DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), +		DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), +		}, +	},  	{ },  }; diff --git a/drivers/block/brd.c b/drivers/block/brd.c index f1a29f8e9d33..9bf4371755f2 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -117,13 +117,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector)  	spin_lock(&brd->brd_lock);  	idx = sector >> PAGE_SECTORS_SHIFT; +	page->index = idx;  	if (radix_tree_insert(&brd->brd_pages, idx, page)) {  		__free_page(page);  		page = radix_tree_lookup(&brd->brd_pages, idx);  		BUG_ON(!page);  		BUG_ON(page->index != idx); -	} else -		page->index = idx; +	}  	spin_unlock(&brd->brd_lock);  	radix_tree_preload_end(); diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index f8ef15f37c5e..3fd130fdfbc1 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1160,8 +1160,7 @@ static int ace_probe(struct platform_device *dev)  	dev_dbg(&dev->dev, "ace_probe(%p)\n", dev);  	/* device id and bus width */ -	of_property_read_u32(dev->dev.of_node, "port-number", &id); -	if (id < 0) +	if (of_property_read_u32(dev->dev.of_node, "port-number", &id))  		id = 0;  	if (of_find_property(dev->dev.of_node, "8-bit", NULL))  		bus_width = ACE_BUS_WIDTH_8; diff --git a/drivers/char/random.c b/drivers/char/random.c index cd9a6211dcad..35487e8ded59 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -865,16 +865,24 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,  	if (r->entropy_count / 8 < min + reserved) {  		nbytes = 0;  	} else { +		int entropy_count, orig; +retry: +		entropy_count = orig = ACCESS_ONCE(r->entropy_count);  		/* If limited, never pull more than available */ -		if (r->limit && nbytes + reserved >= r->entropy_count / 8) -			nbytes = r->entropy_count/8 - reserved; - -		if (r->entropy_count / 8 >= nbytes + reserved) -			r->entropy_count -= nbytes*8; -		else -			r->entropy_count = reserved; +		if (r->limit && nbytes + reserved >= entropy_count / 8) +			nbytes = entropy_count/8 - reserved; + +		if (entropy_count / 8 >= nbytes + reserved) { +			entropy_count -= nbytes*8; +			if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) +				goto retry; +		} else { +			entropy_count = reserved; +			if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) +				goto retry; +		} -		if (r->entropy_count < random_write_wakeup_thresh) +		if (entropy_count < random_write_wakeup_thresh)  			wakeup_write = 1;  	} @@ -957,10 +965,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,  {  	ssize_t ret = 0, i;  	__u8 tmp[EXTRACT_SIZE]; +	unsigned long flags;  	/* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */ -	if (fips_enabled && !r->last_data_init) -		nbytes += EXTRACT_SIZE; +	if (fips_enabled) { +		spin_lock_irqsave(&r->lock, flags); +		if (!r->last_data_init) { +			r->last_data_init = true; +			spin_unlock_irqrestore(&r->lock, flags); +			trace_extract_entropy(r->name, EXTRACT_SIZE, +					      r->entropy_count, _RET_IP_); +			xfer_secondary_pool(r, EXTRACT_SIZE); +			extract_buf(r, tmp); +			spin_lock_irqsave(&r->lock, flags); +			memcpy(r->last_data, tmp, EXTRACT_SIZE); +		} +		spin_unlock_irqrestore(&r->lock, flags); +	}  	trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);  	xfer_secondary_pool(r, nbytes); @@ -970,19 +991,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,  		extract_buf(r, tmp);  		if (fips_enabled) { -			unsigned long flags; - - -			/* prime last_data value if need be, per fips 140-2 */ -			if (!r->last_data_init) { -				spin_lock_irqsave(&r->lock, flags); -				memcpy(r->last_data, tmp, EXTRACT_SIZE); -				r->last_data_init = true; -				nbytes -= EXTRACT_SIZE; -				spin_unlock_irqrestore(&r->lock, flags); -				extract_buf(r, tmp); -			} -  			spin_lock_irqsave(&r->lock, flags);  			if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))  				panic("Hardware RNG duplicated output!\n"); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 8292a00c3de9..075db0c99edb 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -872,6 +872,14 @@ static void __init tegra20_periph_clk_init(void)  	struct clk *clk;  	int i; +	/* ac97 */ +	clk = tegra_clk_register_periph_gate("ac97", "pll_a_out0", +				    TEGRA_PERIPH_ON_APB, +				    clk_base, 0, 3, &periph_l_regs, +				    periph_clk_enb_refcnt); +	clk_register_clkdev(clk, NULL, "tegra20-ac97"); +	clks[ac97] = clk; +  	/* apbdma */  	clk = tegra_clk_register_periph_gate("apbdma", "pclk", 0, clk_base,  				    0, 34, &periph_h_regs, @@ -1234,9 +1242,6 @@ static __initdata struct tegra_clk_init_table init_table[] = {  	{uartc, pll_p, 0, 0},  	{uartd, pll_p, 0, 0},  	{uarte, pll_p, 0, 0}, -	{usbd, clk_max, 12000000, 0}, -	{usb2, clk_max, 12000000, 0}, -	{usb3, clk_max, 12000000, 0},  	{pll_a, clk_max, 56448000, 1},  	{pll_a_out0, clk_max, 11289600, 1},  	{cdev1, clk_max, 0, 1}, diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index 5cf4f4686406..4f45eee9e33b 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c @@ -15,22 +15,29 @@  #include <linux/clk-provider.h>  #include <linux/err.h>  #include <linux/module.h> +#include <linux/platform_data/clk-lpss.h>  #include <linux/platform_device.h>  #define PRV_CLOCK_PARAMS 0x800  static int lpt_clk_probe(struct platform_device *pdev)  { +	struct lpss_clk_data *drvdata;  	struct clk *clk; +	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); +	if (!drvdata) +		return -ENOMEM; +  	/* LPSS free running clock */ -	clk = clk_register_fixed_rate(&pdev->dev, "lpss_clk", NULL, CLK_IS_ROOT, -				      100000000); +	drvdata->name = "lpss_clk"; +	clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, +				      CLK_IS_ROOT, 100000000);  	if (IS_ERR(clk))  		return PTR_ERR(clk); -	/* Shared DMA clock */ -	clk_register_clkdev(clk, "hclk", "INTL9C60.0.auto"); +	drvdata->clk = clk; +	platform_set_drvdata(pdev, drvdata);  	return 0;  } diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index 2b8a8c374548..6bd63d63d356 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 @@ -272,7 +272,7 @@ config X86_LONGHAUL  config X86_E_POWERSAVER  	tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)"  	select CPU_FREQ_TABLE -	depends on X86_32 +	depends on X86_32 && ACPI_PROCESSOR  	help  	  This adds the CPUFreq driver for VIA C7 processors.  However, this driver  	  does not have any safeguards to prevent operating the CPU out of spec diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 173ed059d95f..fd9e3ea6a480 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c @@ -19,70 +19,75 @@  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/cpu.h>  #include <linux/cpufreq.h>  #include <linux/device.h>  #include <linux/export.h>  #include <linux/module.h>  #include <linux/of.h>  #include <linux/opp.h> +#include <linux/platform_device.h>  #include <linux/slab.h>  #include <linux/types.h>  #include "arm_big_little.h" -static int dt_init_opp_table(struct device *cpu_dev) +/* get cpu node with valid operating-points */ +static struct device_node *get_cpu_node_with_valid_op(int cpu)  { -	struct device_node *np, *parent; -	int count = 0, ret; +	struct device_node *np = NULL, *parent; +	int count = 0;  	parent = of_find_node_by_path("/cpus");  	if (!parent) {  		pr_err("failed to find OF /cpus\n"); -		return -ENOENT; +		return NULL;  	}  	for_each_child_of_node(parent, np) { -		if (count++ != cpu_dev->id) +		if (count++ != cpu)  			continue;  		if (!of_get_property(np, "operating-points", NULL)) { -			ret = -ENODATA; -		} else { -			cpu_dev->of_node = np; -			ret = of_init_opp_table(cpu_dev); +			of_node_put(np); +			np = NULL;  		} -		of_node_put(np); -		of_node_put(parent); -		return ret; +		break;  	} -	return -ENODEV; +	of_node_put(parent); +	return np; +} + +static int dt_init_opp_table(struct device *cpu_dev) +{ +	struct device_node *np; +	int ret; + +	np = get_cpu_node_with_valid_op(cpu_dev->id); +	if (!np) +		return -ENODATA; + +	cpu_dev->of_node = np; +	ret = of_init_opp_table(cpu_dev); +	of_node_put(np); + +	return ret;  }  static int dt_get_transition_latency(struct device *cpu_dev)  { -	struct device_node *np, *parent; +	struct device_node *np;  	u32 transition_latency = CPUFREQ_ETERNAL; -	int count = 0; -	parent = of_find_node_by_path("/cpus"); -	if (!parent) { -		pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n"); +	np = get_cpu_node_with_valid_op(cpu_dev->id); +	if (!np)  		return CPUFREQ_ETERNAL; -	} - -	for_each_child_of_node(parent, np) { -		if (count++ != cpu_dev->id) -			continue; -		of_property_read_u32(np, "clock-latency", &transition_latency); -		of_node_put(np); -		of_node_put(parent); +	of_property_read_u32(np, "clock-latency", &transition_latency); +	of_node_put(np); -		return transition_latency; -	} - -	pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n"); -	return CPUFREQ_ETERNAL; +	pr_debug("%s: clock-latency: %d\n", __func__, transition_latency); +	return transition_latency;  }  static struct cpufreq_arm_bL_ops dt_bL_ops = { @@ -91,17 +96,33 @@ static struct cpufreq_arm_bL_ops dt_bL_ops = {  	.init_opp_table = dt_init_opp_table,  }; -static int generic_bL_init(void) +static int generic_bL_probe(struct platform_device *pdev)  { +	struct device_node *np; + +	np = get_cpu_node_with_valid_op(0); +	if (!np) +		return -ENODEV; + +	of_node_put(np);  	return bL_cpufreq_register(&dt_bL_ops);  } -module_init(generic_bL_init); -static void generic_bL_exit(void) +static int generic_bL_remove(struct platform_device *pdev)  { -	return bL_cpufreq_unregister(&dt_bL_ops); +	bL_cpufreq_unregister(&dt_bL_ops); +	return 0;  } -module_exit(generic_bL_exit); + +static struct platform_driver generic_bL_platdrv = { +	.driver = { +		.name	= "arm-bL-cpufreq-dt", +		.owner	= THIS_MODULE, +	}, +	.probe		= generic_bL_probe, +	.remove		= generic_bL_remove, +}; +module_platform_driver(generic_bL_platdrv);  MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");  MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver via DT"); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4b8c7f297d74..2d53f47d1747 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1729,18 +1729,23 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,  			/* end old governor */  			if (data->governor) {  				__cpufreq_governor(data, CPUFREQ_GOV_STOP); +				unlock_policy_rwsem_write(policy->cpu);  				__cpufreq_governor(data,  						CPUFREQ_GOV_POLICY_EXIT); +				lock_policy_rwsem_write(policy->cpu);  			}  			/* start new governor */  			data->governor = policy->governor;  			if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { -				if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) +				if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {  					failed = 0; -				else +				} else { +					unlock_policy_rwsem_write(policy->cpu);  					__cpufreq_governor(data,  							CPUFREQ_GOV_POLICY_EXIT); +					lock_policy_rwsem_write(policy->cpu); +				}  			}  			if (failed) { diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9c36ace92a39..07f2840ad805 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -521,6 +521,7 @@ static void intel_pstate_timer_func(unsigned long __data)  static const struct x86_cpu_id intel_pstate_cpu_ids[] = {  	ICPU(0x2a, default_policy),  	ICPU(0x2d, default_policy), +	ICPU(0x3a, default_policy),  	{}  };  MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index ba6fc62e9651..5a18f82f732a 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -4,7 +4,8 @@   * Based on of-dma.c   *   * Copyright (C) 2013, Intel Corporation - * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + *	    Mika Westerberg <mika.westerberg@linux.intel.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 @@ -16,6 +17,7 @@  #include <linux/list.h>  #include <linux/mutex.h>  #include <linux/slab.h> +#include <linux/ioport.h>  #include <linux/acpi.h>  #include <linux/acpi_dma.h> @@ -23,6 +25,117 @@ static LIST_HEAD(acpi_dma_list);  static DEFINE_MUTEX(acpi_dma_lock);  /** + * acpi_dma_parse_resource_group - match device and parse resource group + * @grp:	CSRT resource group + * @adev:	ACPI device to match with + * @adma:	struct acpi_dma of the given DMA controller + * + * Returns 1 on success, 0 when no information is available, or appropriate + * errno value on error. + * + * In order to match a device from DSDT table to the corresponding CSRT device + * we use MMIO address and IRQ. + */ +static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, +		struct acpi_device *adev, struct acpi_dma *adma) +{ +	const struct acpi_csrt_shared_info *si; +	struct list_head resource_list; +	struct resource_list_entry *rentry; +	resource_size_t mem = 0, irq = 0; +	u32 vendor_id; +	int ret; + +	if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info)) +		return -ENODEV; + +	INIT_LIST_HEAD(&resource_list); +	ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); +	if (ret <= 0) +		return 0; + +	list_for_each_entry(rentry, &resource_list, node) { +		if (resource_type(&rentry->res) == IORESOURCE_MEM) +			mem = rentry->res.start; +		else if (resource_type(&rentry->res) == IORESOURCE_IRQ) +			irq = rentry->res.start; +	} + +	acpi_dev_free_resource_list(&resource_list); + +	/* Consider initial zero values as resource not found */ +	if (mem == 0 && irq == 0) +		return 0; + +	si = (const struct acpi_csrt_shared_info *)&grp[1]; + +	/* Match device by MMIO and IRQ */ +	if (si->mmio_base_low != mem || si->gsi_interrupt != irq) +		return 0; + +	vendor_id = le32_to_cpu(grp->vendor_id); +	dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n", +		(char *)&vendor_id, grp->device_id, grp->revision); + +	/* Check if the request line range is available */ +	if (si->base_request_line == 0 && si->num_handshake_signals == 0) +		return 0; + +	adma->base_request_line = si->base_request_line; +	adma->end_request_line = si->base_request_line + +				 si->num_handshake_signals - 1; + +	dev_dbg(&adev->dev, "request line base: 0x%04x end: 0x%04x\n", +		adma->base_request_line, adma->end_request_line); + +	return 1; +} + +/** + * acpi_dma_parse_csrt - parse CSRT to exctract additional DMA resources + * @adev:	ACPI device to match with + * @adma:	struct acpi_dma of the given DMA controller + * + * CSRT or Core System Resources Table is a proprietary ACPI table + * introduced by Microsoft. This table can contain devices that are not in + * the system DSDT table. In particular DMA controllers might be described + * here. + * + * We are using this table to get the request line range of the specific DMA + * controller to be used later. + * + */ +static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma) +{ +	struct acpi_csrt_group *grp, *end; +	struct acpi_table_csrt *csrt; +	acpi_status status; +	int ret; + +	status = acpi_get_table(ACPI_SIG_CSRT, 0, +				(struct acpi_table_header **)&csrt); +	if (ACPI_FAILURE(status)) { +		if (status != AE_NOT_FOUND) +			dev_warn(&adev->dev, "failed to get the CSRT table\n"); +		return; +	} + +	grp = (struct acpi_csrt_group *)(csrt + 1); +	end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length); + +	while (grp < end) { +		ret = acpi_dma_parse_resource_group(grp, adev, adma); +		if (ret < 0) { +			dev_warn(&adev->dev, +				 "error in parsing resource group\n"); +			return; +		} + +		grp = (struct acpi_csrt_group *)((void *)grp + grp->length); +	} +} + +/**   * acpi_dma_controller_register - Register a DMA controller to ACPI DMA helpers   * @dev:		struct device of DMA controller   * @acpi_dma_xlate:	translation function which converts a dma specifier @@ -61,6 +174,8 @@ int acpi_dma_controller_register(struct device *dev,  	adma->acpi_dma_xlate = acpi_dma_xlate;  	adma->data = data; +	acpi_dma_parse_csrt(adev, adma); +  	/* Now queue acpi_dma controller structure in list */  	mutex_lock(&acpi_dma_lock);  	list_add_tail(&adma->dma_controllers, &acpi_dma_list); @@ -149,6 +264,45 @@ void devm_acpi_dma_controller_free(struct device *dev)  }  EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free); +/** + * acpi_dma_update_dma_spec - prepare dma specifier to pass to translation function + * @adma:	struct acpi_dma of DMA controller + * @dma_spec:	dma specifier to update + * + * Returns 0, if no information is avaiable, -1 on mismatch, and 1 otherwise. + * + * Accordingly to ACPI 5.0 Specification Table 6-170 "Fixed DMA Resource + * Descriptor": + *	DMA Request Line bits is a platform-relative number uniquely + *	identifying the request line assigned. Request line-to-Controller + *	mapping is done in a controller-specific OS driver. + * That's why we can safely adjust slave_id when the appropriate controller is + * found. + */ +static int acpi_dma_update_dma_spec(struct acpi_dma *adma, +		struct acpi_dma_spec *dma_spec) +{ +	/* Set link to the DMA controller device */ +	dma_spec->dev = adma->dev; + +	/* Check if the request line range is available */ +	if (adma->base_request_line == 0 && adma->end_request_line == 0) +		return 0; + +	/* Check if slave_id falls to the range */ +	if (dma_spec->slave_id < adma->base_request_line || +	    dma_spec->slave_id > adma->end_request_line) +		return -1; + +	/* +	 * Here we adjust slave_id. It should be a relative number to the base +	 * request line. +	 */ +	dma_spec->slave_id -= adma->base_request_line; + +	return 1; +} +  struct acpi_dma_parser_data {  	struct acpi_dma_spec dma_spec;  	size_t index; @@ -193,6 +347,7 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,  	struct acpi_device *adev;  	struct acpi_dma *adma;  	struct dma_chan *chan = NULL; +	int found;  	/* Check if the device was enumerated by ACPI */  	if (!dev || !ACPI_HANDLE(dev)) @@ -219,9 +374,20 @@ struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,  	mutex_lock(&acpi_dma_lock);  	list_for_each_entry(adma, &acpi_dma_list, dma_controllers) { -		dma_spec->dev = adma->dev; +		/* +		 * We are not going to call translation function if slave_id +		 * doesn't fall to the request range. +		 */ +		found = acpi_dma_update_dma_spec(adma, dma_spec); +		if (found < 0) +			continue;  		chan = adma->acpi_dma_xlate(dma_spec, adma); -		if (chan) +		/* +		 * Try to get a channel only from the DMA controller that +		 * matches the slave_id. See acpi_dma_update_dma_spec() +		 * description for the details. +		 */ +		if (found > 0 || chan)  			break;  	} diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c index ee14662ed5ce..98cae529373f 100644 --- a/drivers/leds/leds-ot200.c +++ b/drivers/leds/leds-ot200.c @@ -47,37 +47,37 @@ static struct ot200_led leds[] = {  	{  		.name = "led_1",  		.port = 0x49, -		.mask = BIT(7), +		.mask = BIT(6),  	},  	{  		.name = "led_2",  		.port = 0x49, -		.mask = BIT(6), +		.mask = BIT(5),  	},  	{  		.name = "led_3",  		.port = 0x49, -		.mask = BIT(5), +		.mask = BIT(4),  	},  	{  		.name = "led_4",  		.port = 0x49, -		.mask = BIT(4), +		.mask = BIT(3),  	},  	{  		.name = "led_5",  		.port = 0x49, -		.mask = BIT(3), +		.mask = BIT(2),  	},  	{  		.name = "led_6",  		.port = 0x49, -		.mask = BIT(2), +		.mask = BIT(1),  	},  	{  		.name = "led_7",  		.port = 0x49, -		.mask = BIT(1), +		.mask = BIT(0),  	}  }; diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 0d0b5d7d19d0..7b8979c63f48 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -152,6 +152,7 @@ config BATTERY_SBS  config BATTERY_BQ27x00  	tristate "BQ27x00 battery driver" +	depends on I2C || I2C=n  	help  	  Say Y here to enable support for batteries with BQ27x00 (I2C/HDQ) chips. @@ -284,6 +285,7 @@ config CHARGER_LP8788  	tristate "TI LP8788 charger driver"  	depends on MFD_LP8788  	depends on LP8788_ADC +	depends on IIO  	help  	  Say Y to enable support for the LP8788 linear charger. diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index a44175139bbf..fef56e2041b3 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1269,5 +1269,5 @@ module_exit(pm2xxx_charger_exit);  MODULE_LICENSE("GPL v2");  MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); -MODULE_ALIAS("platform:pm2xxx-charger"); +MODULE_ALIAS("i2c:pm2xxx-charger");  MODULE_DESCRIPTION("PM2xxx charger management driver"); diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index 58cbb009b74f..56fb509f4be0 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c @@ -207,7 +207,6 @@ static int wm831x_backup_remove(struct platform_device *pdev)  	struct wm831x_backup *devdata = platform_get_drvdata(pdev);  	power_supply_unregister(&devdata->backup); -	kfree(devdata->backup.name);  	return 0;  } diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index 6194d35ebb97..5ab056494bbe 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig @@ -47,4 +47,24 @@ config RAPIDIO_DEBUG  	  If you are unsure about this, say N here. +choice +	prompt "Enumeration method" +	depends on RAPIDIO +	default RAPIDIO_ENUM_BASIC +	help +	  There are different enumeration and discovery mechanisms offered +	  for RapidIO subsystem. You may select single built-in method or +	  or any number of methods to be built as modules. +	  Selecting a built-in method disables use of loadable methods. + +	  If unsure, select Basic built-in. + +config RAPIDIO_ENUM_BASIC +	tristate "Basic" +	help +	  This option includes basic RapidIO fabric enumeration and discovery +	  mechanism similar to one described in RapidIO specification Annex 1. + +endchoice +  source "drivers/rapidio/switches/Kconfig" diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile index ec3fb8121004..3036702ffe8b 100644 --- a/drivers/rapidio/Makefile +++ b/drivers/rapidio/Makefile @@ -1,7 +1,8 @@  #  # Makefile for RapidIO interconnect services  # -obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o +obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o +obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o  obj-$(CONFIG_RAPIDIO)		+= switches/  obj-$(CONFIG_RAPIDIO)		+= devices/ diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 6faba406b6e9..a8b2c23a7ef4 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -471,6 +471,10 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)  	u32 intval;  	u32 ch_inte; +	/* For MSI mode disable all device-level interrupts */ +	if (priv->flags & TSI721_USING_MSI) +		iowrite32(0, priv->regs + TSI721_DEV_INTE); +  	dev_int = ioread32(priv->regs + TSI721_DEV_INT);  	if (!dev_int)  		return IRQ_NONE; @@ -560,6 +564,14 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr)  		}  	}  #endif + +	/* For MSI mode re-enable device-level interrupts */ +	if (priv->flags & TSI721_USING_MSI) { +		dev_int = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO | +			TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH; +		iowrite32(dev_int, priv->regs + TSI721_DEV_INTE); +	} +  	return IRQ_HANDLED;  } diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 0f4a53bdaa3c..a0c875563d76 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)  	driver_unregister(&rdrv->driver);  } +void rio_attach_device(struct rio_dev *rdev) +{ +	rdev->dev.bus = &rio_bus_type; +	rdev->dev.parent = &rio_bus; +} +EXPORT_SYMBOL_GPL(rio_attach_device); +  /**   *  rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure   *  @dev: the standard device structure to match against @@ -200,6 +207,7 @@ struct bus_type rio_bus_type = {  	.name = "rapidio",  	.match = rio_match_bus,  	.dev_attrs = rio_dev_attrs, +	.bus_attrs = rio_bus_attrs,  	.probe = rio_device_probe,  	.remove = rio_device_remove,  }; diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a965acd3c0e4..4c15dbf81087 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -37,12 +37,8 @@  #include "rio.h" -LIST_HEAD(rio_devices); -  static void rio_init_em(struct rio_dev *rdev); -DEFINE_SPINLOCK(rio_global_list_lock); -  static int next_destid = 0;  static int next_comptag = 1; @@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev)  }  /** - * rio_switch_init - Sets switch operations for a particular vendor switch - * @rdev: RIO device - * @do_enum: Enumeration/Discovery mode flag - * - * Searches the RIO switch ops table for known switch types. If the vid - * and did match a switch table entry, then call switch initialization - * routine to setup switch-specific routines. - */ -static void rio_switch_init(struct rio_dev *rdev, int do_enum) -{ -	struct rio_switch_ops *cur = __start_rio_switch_ops; -	struct rio_switch_ops *end = __end_rio_switch_ops; - -	while (cur < end) { -		if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { -			pr_debug("RIO: calling init routine for %s\n", -				 rio_name(rdev)); -			cur->init_hook(rdev, do_enum); -			break; -		} -		cur++; -	} - -	if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { -		pr_debug("RIO: adding STD routing ops for %s\n", -			rio_name(rdev)); -		rdev->rswitch->add_entry = rio_std_route_add_entry; -		rdev->rswitch->get_entry = rio_std_route_get_entry; -		rdev->rswitch->clr_table = rio_std_route_clr_table; -	} - -	if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) -		printk(KERN_ERR "RIO: missing routing ops for %s\n", -		       rio_name(rdev)); -} - -/** - * rio_add_device- Adds a RIO device to the device model - * @rdev: RIO device - * - * Adds the RIO device to the global device list and adds the RIO - * device to the RIO device list.  Creates the generic sysfs nodes - * for an RIO device. - */ -static int rio_add_device(struct rio_dev *rdev) -{ -	int err; - -	err = device_add(&rdev->dev); -	if (err) -		return err; - -	spin_lock(&rio_global_list_lock); -	list_add_tail(&rdev->global_list, &rio_devices); -	spin_unlock(&rio_global_list_lock); - -	rio_create_sysfs_dev_files(rdev); - -	return 0; -} - -/** - * rio_enable_rx_tx_port - enable input receiver and output transmitter of - * given port - * @port: Master port associated with the RIO network - * @local: local=1 select local port otherwise a far device is reached - * @destid: Destination ID of the device to check host bit - * @hopcount: Number of hops to reach the target - * @port_num: Port (-number on switch) to enable on a far end device - * - * Returns 0 or 1 from on General Control Command and Status Register - * (EXT_PTR+0x3C) - */ -inline int rio_enable_rx_tx_port(struct rio_mport *port, -				 int local, u16 destid, -				 u8 hopcount, u8 port_num) { -#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS -	u32 regval; -	u32 ext_ftr_ptr; - -	/* -	* enable rx input tx output port -	*/ -	pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " -		 "%d, port_num = %d)\n", local, destid, hopcount, port_num); - -	ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); - -	if (local) { -		rio_local_read_config_32(port, ext_ftr_ptr + -				RIO_PORT_N_CTL_CSR(0), -				®val); -	} else { -		if (rio_mport_read_config_32(port, destid, hopcount, -		ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) -			return -EIO; -	} - -	if (regval & RIO_PORT_N_CTL_P_TYP_SER) { -		/* serial */ -		regval = regval | RIO_PORT_N_CTL_EN_RX_SER -				| RIO_PORT_N_CTL_EN_TX_SER; -	} else { -		/* parallel */ -		regval = regval | RIO_PORT_N_CTL_EN_RX_PAR -				| RIO_PORT_N_CTL_EN_TX_PAR; -	} - -	if (local) { -		rio_local_write_config_32(port, ext_ftr_ptr + -					  RIO_PORT_N_CTL_CSR(0), regval); -	} else { -		if (rio_mport_write_config_32(port, destid, hopcount, -		    ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) -			return -EIO; -	} -#endif -	return 0; -} - -/**   * rio_setup_device- Allocates and sets up a RIO device   * @net: RIO network   * @port: Master port to send transactions @@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,  			     rdev->destid);  	} -	rdev->dev.bus = &rio_bus_type; -	rdev->dev.parent = &rio_bus; +	rio_attach_device(rdev);  	device_initialize(&rdev->dev);  	rdev->dev.release = rio_release_dev; @@ -1260,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable)  /**   * rio_enum_mport- Start enumeration through a master port   * @mport: Master port to send transactions + * @flags: Enumeration control flags   *   * Starts the enumeration process. If somebody has enumerated our   * master port device, then give up. If not and we have an active   * link, then start recursive peer enumeration. Returns %0 if   * enumeration succeeds or %-EBUSY if enumeration fails.   */ -int rio_enum_mport(struct rio_mport *mport) +int rio_enum_mport(struct rio_mport *mport, u32 flags)  {  	struct rio_net *net = NULL;  	int rc = 0;  	printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,  	       mport->name); + +	/* +	 * To avoid multiple start requests (repeat enumeration is not supported +	 * by this method) check if enumeration/discovery was performed for this +	 * mport: if mport was added into the list of mports for a net exit +	 * with error. +	 */ +	if (mport->nnode.next || mport->nnode.prev) +		return -EBUSY; +  	/* If somebody else enumerated our master port device, bail. */  	if (rio_enum_host(mport) < 0) {  		printk(KERN_INFO @@ -1362,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net)  /**   * rio_disc_mport- Start discovery through a master port   * @mport: Master port to send transactions + * @flags: discovery control flags   *   * Starts the discovery process. If we have an active link, - * then wait for the signal that enumeration is complete. + * then wait for the signal that enumeration is complete (if wait + * is allowed).   * When enumeration completion is signaled, start recursive   * peer discovery. Returns %0 if discovery succeeds or %-EBUSY   * on failure.   */ -int rio_disc_mport(struct rio_mport *mport) +int rio_disc_mport(struct rio_mport *mport, u32 flags)  {  	struct rio_net *net = NULL;  	unsigned long to_end; @@ -1379,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport)  	/* If master port has an active link, allocate net and discover peers */  	if (rio_mport_is_active(mport)) { +		if (rio_enum_complete(mport)) +			goto enum_done; +		else if (flags & RIO_SCAN_ENUM_NO_WAIT) +			return -EAGAIN; +  		pr_debug("RIO: wait for enumeration to complete...\n");  		to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; @@ -1421,3 +1313,41 @@ enum_done:  bail:  	return -EBUSY;  } + +static struct rio_scan rio_scan_ops = { +	.enumerate = rio_enum_mport, +	.discover = rio_disc_mport, +}; + +static bool scan; +module_param(scan, bool, 0); +MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery " +			"(default = 0)"); + +/** + * rio_basic_attach: + * + * When this enumeration/discovery method is loaded as a module this function + * registers its specific enumeration and discover routines for all available + * RapidIO mport devices. The "scan" command line parameter controls ability of + * the module to start RapidIO enumeration/discovery automatically. + * + * Returns 0 for success or -EIO if unable to register itself. + * + * This enumeration/discovery method cannot be unloaded and therefore does not + * provide a matching cleanup_module routine. + */ + +static int __init rio_basic_attach(void) +{ +	if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops)) +		return -EIO; +	if (scan) +		rio_init_mports(); +	return 0; +} + +late_initcall(rio_basic_attach); + +MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 4dbe360989be..66d4acd5e18f 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev)  			rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);  	}  } + +static ssize_t bus_scan_store(struct bus_type *bus, const char *buf, +				size_t count) +{ +	long val; +	struct rio_mport *port = NULL; +	int rc; + +	if (kstrtol(buf, 0, &val) < 0) +		return -EINVAL; + +	if (val == RIO_MPORT_ANY) { +		rc = rio_init_mports(); +		goto exit; +	} + +	if (val < 0 || val >= RIO_MAX_MPORTS) +		return -EINVAL; + +	port = rio_find_mport((int)val); + +	if (!port) { +		pr_debug("RIO: %s: mport_%d not available\n", +			 __func__, (int)val); +		return -EINVAL; +	} + +	if (!port->nscan) +		return -EINVAL; + +	if (port->host_deviceid >= 0) +		rc = port->nscan->enumerate(port, 0); +	else +		rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT); +exit: +	if (!rc) +		rc = count; + +	return rc; +} + +struct bus_attribute rio_bus_attrs[] = { +	__ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store), +	__ATTR_NULL +}; diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index d553b5d13722..cb1c08996fbb 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -31,7 +31,11 @@  #include "rio.h" +static LIST_HEAD(rio_devices); +static DEFINE_SPINLOCK(rio_global_list_lock); +  static LIST_HEAD(rio_mports); +static DEFINE_MUTEX(rio_mport_list_lock);  static unsigned char next_portid;  static DEFINE_SPINLOCK(rio_mmap_lock); @@ -53,6 +57,32 @@ u16 rio_local_get_device_id(struct rio_mport *port)  }  /** + * rio_add_device- Adds a RIO device to the device model + * @rdev: RIO device + * + * Adds the RIO device to the global device list and adds the RIO + * device to the RIO device list.  Creates the generic sysfs nodes + * for an RIO device. + */ +int rio_add_device(struct rio_dev *rdev) +{ +	int err; + +	err = device_add(&rdev->dev); +	if (err) +		return err; + +	spin_lock(&rio_global_list_lock); +	list_add_tail(&rdev->global_list, &rio_devices); +	spin_unlock(&rio_global_list_lock); + +	rio_create_sysfs_dev_files(rdev); + +	return 0; +} +EXPORT_SYMBOL_GPL(rio_add_device); + +/**   * rio_request_inb_mbox - request inbound mailbox service   * @mport: RIO master port from which to allocate the mailbox resource   * @dev_id: Device specific pointer to pass on event @@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local,  	return ext_ftr_ptr;  } +EXPORT_SYMBOL_GPL(rio_mport_get_physefb);  /**   * rio_get_comptag - Begin or continue searching for a RIO device by component tag @@ -521,6 +552,7 @@ exit:  	spin_unlock(&rio_global_list_lock);  	return rdev;  } +EXPORT_SYMBOL_GPL(rio_get_comptag);  /**   * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. @@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)  				  regval);  	return 0;  } +EXPORT_SYMBOL_GPL(rio_set_port_lockout); + +/** + * rio_switch_init - Sets switch operations for a particular vendor switch + * @rdev: RIO device + * @do_enum: Enumeration/Discovery mode flag + * + * Searches the RIO switch ops table for known switch types. If the vid + * and did match a switch table entry, then call switch initialization + * routine to setup switch-specific routines. + */ +void rio_switch_init(struct rio_dev *rdev, int do_enum) +{ +	struct rio_switch_ops *cur = __start_rio_switch_ops; +	struct rio_switch_ops *end = __end_rio_switch_ops; + +	while (cur < end) { +		if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { +			pr_debug("RIO: calling init routine for %s\n", +				 rio_name(rdev)); +			cur->init_hook(rdev, do_enum); +			break; +		} +		cur++; +	} + +	if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { +		pr_debug("RIO: adding STD routing ops for %s\n", +			rio_name(rdev)); +		rdev->rswitch->add_entry = rio_std_route_add_entry; +		rdev->rswitch->get_entry = rio_std_route_get_entry; +		rdev->rswitch->clr_table = rio_std_route_clr_table; +	} + +	if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) +		printk(KERN_ERR "RIO: missing routing ops for %s\n", +		       rio_name(rdev)); +} +EXPORT_SYMBOL_GPL(rio_switch_init); + +/** + * rio_enable_rx_tx_port - enable input receiver and output transmitter of + * given port + * @port: Master port associated with the RIO network + * @local: local=1 select local port otherwise a far device is reached + * @destid: Destination ID of the device to check host bit + * @hopcount: Number of hops to reach the target + * @port_num: Port (-number on switch) to enable on a far end device + * + * Returns 0 or 1 from on General Control Command and Status Register + * (EXT_PTR+0x3C) + */ +int rio_enable_rx_tx_port(struct rio_mport *port, +			  int local, u16 destid, +			  u8 hopcount, u8 port_num) +{ +#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS +	u32 regval; +	u32 ext_ftr_ptr; + +	/* +	* enable rx input tx output port +	*/ +	pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " +		 "%d, port_num = %d)\n", local, destid, hopcount, port_num); + +	ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); + +	if (local) { +		rio_local_read_config_32(port, ext_ftr_ptr + +				RIO_PORT_N_CTL_CSR(0), +				®val); +	} else { +		if (rio_mport_read_config_32(port, destid, hopcount, +		ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) +			return -EIO; +	} + +	if (regval & RIO_PORT_N_CTL_P_TYP_SER) { +		/* serial */ +		regval = regval | RIO_PORT_N_CTL_EN_RX_SER +				| RIO_PORT_N_CTL_EN_TX_SER; +	} else { +		/* parallel */ +		regval = regval | RIO_PORT_N_CTL_EN_RX_PAR +				| RIO_PORT_N_CTL_EN_TX_PAR; +	} + +	if (local) { +		rio_local_write_config_32(port, ext_ftr_ptr + +					  RIO_PORT_N_CTL_CSR(0), regval); +	} else { +		if (rio_mport_write_config_32(port, destid, hopcount, +		    ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) +			return -EIO; +	} +#endif +	return 0; +} +EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port); +  /**   * rio_chk_dev_route - Validate route to the specified device. @@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)  	return 0;  } +EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access);  /**   * rio_chk_dev_access - Validate access to the specified device. @@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,  		return RIO_GET_BLOCK_ID(reg_val);  	}  } +EXPORT_SYMBOL_GPL(rio_mport_get_efb);  /**   * rio_mport_get_feature - query for devices' extended features @@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,  	return 0;  } +EXPORT_SYMBOL_GPL(rio_mport_get_feature);  /**   * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did @@ -1246,6 +1382,95 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);  #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ +/** + * rio_find_mport - find RIO mport by its ID + * @mport_id: number (ID) of mport device + * + * Given a RIO mport number, the desired mport is located + * in the global list of mports. If the mport is found, a pointer to its + * data structure is returned.  If no mport is found, %NULL is returned. + */ +struct rio_mport *rio_find_mport(int mport_id) +{ +	struct rio_mport *port; + +	mutex_lock(&rio_mport_list_lock); +	list_for_each_entry(port, &rio_mports, node) { +		if (port->id == mport_id) +			goto found; +	} +	port = NULL; +found: +	mutex_unlock(&rio_mport_list_lock); + +	return port; +} + +/** + * rio_register_scan - enumeration/discovery method registration interface + * @mport_id: mport device ID for which fabric scan routine has to be set + *            (RIO_MPORT_ANY = set for all available mports) + * @scan_ops: enumeration/discovery control structure + * + * Assigns enumeration or discovery method to the specified mport device (or all + * available mports if RIO_MPORT_ANY is specified). + * Returns error if the mport already has an enumerator attached to it. + * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns + * an error if was unable to find at least one available mport. + */ +int rio_register_scan(int mport_id, struct rio_scan *scan_ops) +{ +	struct rio_mport *port; +	int rc = -EBUSY; + +	mutex_lock(&rio_mport_list_lock); +	list_for_each_entry(port, &rio_mports, node) { +		if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { +			if (port->nscan && mport_id == RIO_MPORT_ANY) +				continue; +			else if (port->nscan) +				break; + +			port->nscan = scan_ops; +			rc = 0; + +			if (mport_id != RIO_MPORT_ANY) +				break; +		} +	} +	mutex_unlock(&rio_mport_list_lock); + +	return rc; +} +EXPORT_SYMBOL_GPL(rio_register_scan); + +/** + * rio_unregister_scan - removes enumeration/discovery method from mport + * @mport_id: mport device ID for which fabric scan routine has to be + *            unregistered (RIO_MPORT_ANY = set for all available mports) + * + * Removes enumeration or discovery method assigned to the specified mport + * device (or all available mports if RIO_MPORT_ANY is specified). + */ +int rio_unregister_scan(int mport_id) +{ +	struct rio_mport *port; + +	mutex_lock(&rio_mport_list_lock); +	list_for_each_entry(port, &rio_mports, node) { +		if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { +			if (port->nscan) +				port->nscan = NULL; +			if (mport_id != RIO_MPORT_ANY) +				break; +		} +	} +	mutex_unlock(&rio_mport_list_lock); + +	return 0; +} +EXPORT_SYMBOL_GPL(rio_unregister_scan); +  static void rio_fixup_device(struct rio_dev *dev)  {  } @@ -1274,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work)  	work = container_of(_work, struct rio_disc_work, work);  	pr_debug("RIO: discovery work for mport %d %s\n",  		 work->mport->id, work->mport->name); -	rio_disc_mport(work->mport); +	work->mport->nscan->discover(work->mport, 0);  }  int rio_init_mports(void) @@ -1290,12 +1515,15 @@ int rio_init_mports(void)  	 * First, run enumerations and check if we need to perform discovery  	 * on any of the registered mports.  	 */ +	mutex_lock(&rio_mport_list_lock);  	list_for_each_entry(port, &rio_mports, node) { -		if (port->host_deviceid >= 0) -			rio_enum_mport(port); -		else +		if (port->host_deviceid >= 0) { +			if (port->nscan) +				port->nscan->enumerate(port, 0); +		} else  			n++;  	} +	mutex_unlock(&rio_mport_list_lock);  	if (!n)  		goto no_disc; @@ -1322,14 +1550,16 @@ int rio_init_mports(void)  	}  	n = 0; +	mutex_lock(&rio_mport_list_lock);  	list_for_each_entry(port, &rio_mports, node) { -		if (port->host_deviceid < 0) { +		if (port->host_deviceid < 0 && port->nscan) {  			work[n].mport = port;  			INIT_WORK(&work[n].work, disc_work_handler);  			queue_work(rio_wq, &work[n].work);  			n++;  		}  	} +	mutex_unlock(&rio_mport_list_lock);  	flush_workqueue(rio_wq);  	pr_debug("RIO: destroy discovery workqueue\n"); @@ -1342,8 +1572,6 @@ no_disc:  	return 0;  } -device_initcall_sync(rio_init_mports); -  static int hdids[RIO_MAX_MPORTS + 1];  static int rio_get_hdid(int index) @@ -1371,7 +1599,10 @@ int rio_register_mport(struct rio_mport *port)  	port->id = next_portid++;  	port->host_deviceid = rio_get_hdid(port->id); +	port->nscan = NULL; +	mutex_lock(&rio_mport_list_lock);  	list_add_tail(&port->node, &rio_mports); +	mutex_unlock(&rio_mport_list_lock);  	return 0;  } @@ -1386,3 +1617,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);  EXPORT_SYMBOL_GPL(rio_release_inb_mbox);  EXPORT_SYMBOL_GPL(rio_request_outb_mbox);  EXPORT_SYMBOL_GPL(rio_release_outb_mbox); +EXPORT_SYMBOL_GPL(rio_init_mports); diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index b1af414f15e6..c14f864dea5c 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h @@ -15,6 +15,7 @@  #include <linux/rio.h>  #define RIO_MAX_CHK_RETRY	3 +#define RIO_MPORT_ANY		(-1)  /* Functions internal to the RIO core code */ @@ -27,8 +28,6 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,  extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,  				    u8 hopcount);  extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); -extern int rio_enum_mport(struct rio_mport *mport); -extern int rio_disc_mport(struct rio_mport *mport);  extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,  				   u8 hopcount, u16 table, u16 route_destid,  				   u8 route_port); @@ -39,10 +38,18 @@ extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,  				   u8 hopcount, u16 table);  extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock);  extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); +extern int rio_add_device(struct rio_dev *rdev); +extern void rio_switch_init(struct rio_dev *rdev, int do_enum); +extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, +				 u8 hopcount, u8 port_num); +extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); +extern int rio_unregister_scan(int mport_id); +extern void rio_attach_device(struct rio_dev *rdev); +extern struct rio_mport *rio_find_mport(int mport_id);  /* Structures internal to the RIO core code */  extern struct device_attribute rio_dev_attrs[]; -extern spinlock_t rio_global_list_lock; +extern struct bus_attribute rio_bus_attrs[];  extern struct rio_switch_ops __start_rio_switch_ops[];  extern struct rio_switch_ops __end_rio_switch_ops[]; diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index 48b6612fae7f..d5af7baa48b5 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -285,7 +285,7 @@ static int max8998_rtc_probe(struct platform_device *pdev)  			info->irq, ret);  	dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); -	if (pdata->rtc_delay) { +	if (pdata && pdata->rtc_delay) {  		info->lp3974_bug_workaround = true;  		dev_warn(&pdev->dev, "LP3974 with RTC REGERR option."  				" RTC updates will be extremely slow.\n"); diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 8900ea784817..0f0609b1aa2c 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -306,7 +306,7 @@ static int pl031_remove(struct amba_device *adev)  	struct pl031_local *ldata = dev_get_drvdata(&adev->dev);  	amba_set_drvdata(adev, NULL); -	free_irq(adev->irq[0], ldata->rtc); +	free_irq(adev->irq[0], ldata);  	rtc_device_unregister(ldata->rtc);  	iounmap(ldata->base);  	kfree(ldata); diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 30d4f7a783cd..f0b9f6b52b32 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -202,26 +202,6 @@ static int serial_omap_get_context_loss_count(struct uart_omap_port *up)  	return pdata->get_context_loss_count(up->dev);  } -static void serial_omap_set_forceidle(struct uart_omap_port *up) -{ -	struct omap_uart_port_info *pdata = up->dev->platform_data; - -	if (!pdata || !pdata->set_forceidle) -		return; - -	pdata->set_forceidle(up->dev); -} - -static void serial_omap_set_noidle(struct uart_omap_port *up) -{ -	struct omap_uart_port_info *pdata = up->dev->platform_data; - -	if (!pdata || !pdata->set_noidle) -		return; - -	pdata->set_noidle(up->dev); -} -  static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)  {  	struct omap_uart_port_info *pdata = up->dev->platform_data; @@ -298,8 +278,6 @@ static void serial_omap_stop_tx(struct uart_port *port)  		serial_out(up, UART_IER, up->ier);  	} -	serial_omap_set_forceidle(up); -  	pm_runtime_mark_last_busy(up->dev);  	pm_runtime_put_autosuspend(up->dev);  } @@ -364,7 +342,6 @@ static void serial_omap_start_tx(struct uart_port *port)  	pm_runtime_get_sync(up->dev);  	serial_omap_enable_ier_thri(up); -	serial_omap_set_noidle(up);  	pm_runtime_mark_last_busy(up->dev);  	pm_runtime_put_autosuspend(up->dev);  } diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d71d60f94fc1..2e937bdace6f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2199,7 +2199,7 @@ config FB_XILINX  config FB_GOLDFISH  	tristate "Goldfish Framebuffer" -	depends on FB +	depends on FB && HAS_DMA  	select FB_CFB_FILLRECT  	select FB_CFB_COPYAREA  	select FB_CFB_IMAGEBLIT @@ -2453,6 +2453,23 @@ config FB_HYPERV  	help  	  This framebuffer driver supports Microsoft Hyper-V Synthetic Video. +config FB_SIMPLE +	bool "Simple framebuffer support" +	depends on (FB = y) && OF +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  Say Y if you want support for a simple frame-buffer. + +	  This driver assumes that the display hardware has been initialized +	  before the kernel boots, and the kernel will simply render to the +	  pre-allocated frame buffer surface. + +	  Configuration re: surface address, size, and format must be provided +	  through device tree, or potentially plain old platform data in the +	  future. +  source "drivers/video/omap/Kconfig"  source "drivers/video/omap2/Kconfig"  source "drivers/video/exynos/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 7234e4a959e8..e8bae8dd4804 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -166,6 +166,7 @@ obj-$(CONFIG_FB_MX3)		  += mx3fb.o  obj-$(CONFIG_FB_DA8XX)		  += da8xx-fb.o  obj-$(CONFIG_FB_MXS)		  += mxsfb.o  obj-$(CONFIG_FB_SSD1307)	  += ssd1307fb.o +obj-$(CONFIG_FB_SIMPLE)           += simplefb.o  # the test framebuffer is last  obj-$(CONFIG_FB_VIRTUAL)          += vfb.o diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c new file mode 100644 index 000000000000..e2e9e3e61b72 --- /dev/null +++ b/drivers/video/simplefb.c @@ -0,0 +1,234 @@ +/* + * Simplest possible simple frame-buffer driver, as a platform device + * + * Copyright (c) 2013, Stephen Warren + * + * Based on q40fb.c, which was: + * Copyright (C) 2001 Richard Zidlicky <rz@linux-m68k.org> + * + * Also based on offb.c, which was: + * Copyright (C) 1997 Geert Uytterhoeven + * Copyright (C) 1996 Paul Mackerras + * + * 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. + */ + +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +static struct fb_fix_screeninfo simplefb_fix = { +	.id		= "simple", +	.type		= FB_TYPE_PACKED_PIXELS, +	.visual		= FB_VISUAL_TRUECOLOR, +	.accel		= FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo simplefb_var = { +	.height		= -1, +	.width		= -1, +	.activate	= FB_ACTIVATE_NOW, +	.vmode		= FB_VMODE_NONINTERLACED, +}; + +static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, +			      u_int transp, struct fb_info *info) +{ +	u32 *pal = info->pseudo_palette; +	u32 cr = red >> (16 - info->var.red.length); +	u32 cg = green >> (16 - info->var.green.length); +	u32 cb = blue >> (16 - info->var.blue.length); +	u32 value; + +	if (regno >= 16) +		return -EINVAL; + +	value = (cr << info->var.red.offset) | +		(cg << info->var.green.offset) | +		(cb << info->var.blue.offset); +	if (info->var.transp.length > 0) { +		u32 mask = (1 << info->var.transp.length) - 1; +		mask <<= info->var.transp.offset; +		value |= mask; +	} +	pal[regno] = value; + +	return 0; +} + +static struct fb_ops simplefb_ops = { +	.owner		= THIS_MODULE, +	.fb_setcolreg	= simplefb_setcolreg, +	.fb_fillrect	= cfb_fillrect, +	.fb_copyarea	= cfb_copyarea, +	.fb_imageblit	= cfb_imageblit, +}; + +struct simplefb_format { +	const char *name; +	u32 bits_per_pixel; +	struct fb_bitfield red; +	struct fb_bitfield green; +	struct fb_bitfield blue; +	struct fb_bitfield transp; +}; + +static struct simplefb_format simplefb_formats[] = { +	{ "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, +}; + +struct simplefb_params { +	u32 width; +	u32 height; +	u32 stride; +	struct simplefb_format *format; +}; + +static int simplefb_parse_dt(struct platform_device *pdev, +			   struct simplefb_params *params) +{ +	struct device_node *np = pdev->dev.of_node; +	int ret; +	const char *format; +	int i; + +	ret = of_property_read_u32(np, "width", ¶ms->width); +	if (ret) { +		dev_err(&pdev->dev, "Can't parse width property\n"); +		return ret; +	} + +	ret = of_property_read_u32(np, "height", ¶ms->height); +	if (ret) { +		dev_err(&pdev->dev, "Can't parse height property\n"); +		return ret; +	} + +	ret = of_property_read_u32(np, "stride", ¶ms->stride); +	if (ret) { +		dev_err(&pdev->dev, "Can't parse stride property\n"); +		return ret; +	} + +	ret = of_property_read_string(np, "format", &format); +	if (ret) { +		dev_err(&pdev->dev, "Can't parse format property\n"); +		return ret; +	} +	params->format = NULL; +	for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { +		if (strcmp(format, simplefb_formats[i].name)) +			continue; +		params->format = &simplefb_formats[i]; +		break; +	} +	if (!params->format) { +		dev_err(&pdev->dev, "Invalid format value\n"); +		return -EINVAL; +	} + +	return 0; +} + +static int simplefb_probe(struct platform_device *pdev) +{ +	int ret; +	struct simplefb_params params; +	struct fb_info *info; +	struct resource *mem; + +	if (fb_get_options("simplefb", NULL)) +		return -ENODEV; + +	ret = simplefb_parse_dt(pdev, ¶ms); +	if (ret) +		return ret; + +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!mem) { +		dev_err(&pdev->dev, "No memory resource\n"); +		return -EINVAL; +	} + +	info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); +	if (!info) +		return -ENOMEM; +	platform_set_drvdata(pdev, info); + +	info->fix = simplefb_fix; +	info->fix.smem_start = mem->start; +	info->fix.smem_len = resource_size(mem); +	info->fix.line_length = params.stride; + +	info->var = simplefb_var; +	info->var.xres = params.width; +	info->var.yres = params.height; +	info->var.xres_virtual = params.width; +	info->var.yres_virtual = params.height; +	info->var.bits_per_pixel = params.format->bits_per_pixel; +	info->var.red = params.format->red; +	info->var.green = params.format->green; +	info->var.blue = params.format->blue; +	info->var.transp = params.format->transp; + +	info->fbops = &simplefb_ops; +	info->flags = FBINFO_DEFAULT; +	info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, +					 info->fix.smem_len); +	if (!info->screen_base) { +		framebuffer_release(info); +		return -ENODEV; +	} +	info->pseudo_palette = (void *)(info + 1); + +	ret = register_framebuffer(info); +	if (ret < 0) { +		dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); +		framebuffer_release(info); +		return ret; +	} + +	dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); + +	return 0; +} + +static int simplefb_remove(struct platform_device *pdev) +{ +	struct fb_info *info = platform_get_drvdata(pdev); + +	unregister_framebuffer(info); +	framebuffer_release(info); + +	return 0; +} + +static const struct of_device_id simplefb_of_match[] = { +	{ .compatible = "simple-framebuffer", }, +	{ }, +}; +MODULE_DEVICE_TABLE(of, simplefb_of_match); + +static struct platform_driver simplefb_driver = { +	.driver = { +		.name = "simple-framebuffer", +		.owner = THIS_MODULE, +		.of_match_table = simplefb_of_match, +	}, +	.probe = simplefb_probe, +	.remove = simplefb_remove, +}; +module_platform_driver(simplefb_driver); + +MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); +MODULE_DESCRIPTION("Simple framebuffer driver"); +MODULE_LICENSE("GPL v2"); @@ -307,7 +307,9 @@ static void free_ioctx(struct kioctx *ctx)  	kunmap_atomic(ring);  	while (atomic_read(&ctx->reqs_active) > 0) { -		wait_event(ctx->wait, head != ctx->tail); +		wait_event(ctx->wait, +				head != ctx->tail || +				atomic_read(&ctx->reqs_active) <= 0);  		avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head; @@ -1299,8 +1301,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,   *	< min_nr if the timeout specified by timeout has elapsed   *	before sufficient events are available, where timeout == NULL   *	specifies an infinite timeout. Note that the timeout pointed to by - *	timeout is relative and will be updated if not NULL and the - *	operation blocks. Will fail with -ENOSYS if not implemented. + *	timeout is relative.  Will fail with -ENOSYS if not implemented.   */  SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,  		long, min_nr, diff --git a/fs/fat/inode.c b/fs/fat/inode.c index dfce656ddb33..5d4513cb1b3c 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1229,6 +1229,19 @@ static int fat_read_root(struct inode *inode)  	return 0;  } +static unsigned long calc_fat_clusters(struct super_block *sb) +{ +	struct msdos_sb_info *sbi = MSDOS_SB(sb); + +	/* Divide first to avoid overflow */ +	if (sbi->fat_bits != 12) { +		unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits; +		return ent_per_sec * sbi->fat_length; +	} + +	return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; +} +  /*   * Read the super block of an MS-DOS FS.   */ @@ -1434,7 +1447,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,  		sbi->dirty = b->fat16.state & FAT_STATE_DIRTY;  	/* check that FAT table does not overflow */ -	fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; +	fat_clusters = calc_fat_clusters(sb);  	total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);  	if (total_clusters > MAX_FAT(sb)) {  		if (!silent) diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index f3b1a15ccd59..d3fa6bd9503e 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -415,7 +415,11 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num)  	spin_lock(&tree->hash_lock);  	node = hfs_bnode_findhash(tree, num);  	spin_unlock(&tree->hash_lock); -	BUG_ON(node); +	if (node) { +		pr_crit("new node %u already hashed?\n", num); +		WARN_ON(1); +		return node; +	}  	node = __hfs_bnode_create(tree, num);  	if (!node)  		return ERR_PTR(-ENOMEM); diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 689fb608648e..bccfec8343c5 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -219,13 +219,32 @@ static int nilfs_writepage(struct page *page, struct writeback_control *wbc)  static int nilfs_set_page_dirty(struct page *page)  { -	int ret = __set_page_dirty_buffers(page); +	int ret = __set_page_dirty_nobuffers(page); -	if (ret) { +	if (page_has_buffers(page)) {  		struct inode *inode = page->mapping->host; -		unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); +		unsigned nr_dirty = 0; +		struct buffer_head *bh, *head; -		nilfs_set_file_dirty(inode, nr_dirty); +		/* +		 * This page is locked by callers, and no other thread +		 * concurrently marks its buffers dirty since they are +		 * only dirtied through routines in fs/buffer.c in +		 * which call sites of mark_buffer_dirty are protected +		 * by page lock. +		 */ +		bh = head = page_buffers(page); +		do { +			/* Do not mark hole blocks dirty */ +			if (buffer_dirty(bh) || !buffer_mapped(bh)) +				continue; + +			set_buffer_dirty(bh); +			nr_dirty++; +		} while (bh = bh->b_this_page, bh != head); + +		if (nr_dirty) +			nilfs_set_file_dirty(inode, nr_dirty);  	}  	return ret;  } diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 1c39efb71bab..2487116d0d33 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -790,7 +790,7 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,  						 &hole_size, &rec, &is_last);  		if (ret) {  			mlog_errno(ret); -			goto out; +			goto out_unlock;  		}  		if (rec.e_blkno == 0ULL) { diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8a7509f9e6f5..ff54014a24ec 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2288,7 +2288,7 @@ relock:  		ret = ocfs2_inode_lock(inode, NULL, 1);  		if (ret < 0) {  			mlog_errno(ret); -			goto out_sems; +			goto out;  		}  		ocfs2_inode_unlock(inode, 1); diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 2b2691b73428..41a695048be7 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -725,6 +725,25 @@ xfs_convert_page(  			(xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,  			i_size_read(inode)); +	/* +	 * If the current map does not span the entire page we are about to try +	 * to write, then give up. The only way we can write a page that spans +	 * multiple mappings in a single writeback iteration is via the +	 * xfs_vm_writepage() function. Data integrity writeback requires the +	 * entire page to be written in a single attempt, otherwise the part of +	 * the page we don't write here doesn't get written as part of the data +	 * integrity sync. +	 * +	 * For normal writeback, we also don't attempt to write partial pages +	 * here as it simply means that write_cache_pages() will see it under +	 * writeback and ignore the page until some point in the future, at +	 * which time this will be the only page in the file that needs +	 * writeback.  Hence for more optimal IO patterns, we should always +	 * avoid partial page writeback due to multiple mappings on a page here. +	 */ +	if (!xfs_imap_valid(inode, imap, end_offset)) +		goto fail_unlock_page; +  	len = 1 << inode->i_blkbits;  	p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),  					PAGE_CACHE_SIZE); diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 08d5457c948e..0bce1b348580 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -931,20 +931,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)   */  int  xfs_attr_shortform_allfit( -	struct xfs_buf	*bp, -	struct xfs_inode *dp) +	struct xfs_buf		*bp, +	struct xfs_inode	*dp)  { -	xfs_attr_leafblock_t *leaf; -	xfs_attr_leaf_entry_t *entry; +	struct xfs_attr_leafblock *leaf; +	struct xfs_attr_leaf_entry *entry;  	xfs_attr_leaf_name_local_t *name_loc; -	int bytes, i; +	struct xfs_attr3_icleaf_hdr leafhdr; +	int			bytes; +	int			i;  	leaf = bp->b_addr; -	ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); +	xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); +	entry = xfs_attr3_leaf_entryp(leaf); -	entry = &leaf->entries[0];  	bytes = sizeof(struct xfs_attr_sf_hdr); -	for (i = 0; i < be16_to_cpu(leaf->hdr.count); entry++, i++) { +	for (i = 0; i < leafhdr.count; entry++, i++) {  		if (entry->flags & XFS_ATTR_INCOMPLETE)  			continue;		/* don't copy partial entries */  		if (!(entry->flags & XFS_ATTR_LOCAL)) @@ -954,15 +956,15 @@ xfs_attr_shortform_allfit(  			return(0);  		if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)  			return(0); -		bytes += sizeof(struct xfs_attr_sf_entry)-1 +		bytes += sizeof(struct xfs_attr_sf_entry) - 1  				+ name_loc->namelen  				+ be16_to_cpu(name_loc->valuelen);  	}  	if ((dp->i_mount->m_flags & XFS_MOUNT_ATTR2) &&  	    (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&  	    (bytes == sizeof(struct xfs_attr_sf_hdr))) -		return(-1); -	return(xfs_attr_shortform_bytesfit(dp, bytes)); +		return -1; +	return xfs_attr_shortform_bytesfit(dp, bytes);  }  /* @@ -2330,9 +2332,10 @@ xfs_attr3_leaf_lookup_int(  			if (!xfs_attr_namesp_match(args->flags, entry->flags))  				continue;  			args->index = probe; +			args->valuelen = be32_to_cpu(name_rmt->valuelen);  			args->rmtblkno = be32_to_cpu(name_rmt->valueblk);  			args->rmtblkcnt = XFS_B_TO_FSB(args->dp->i_mount, -						   be32_to_cpu(name_rmt->valuelen)); +						       args->valuelen);  			return XFS_ERROR(EEXIST);  		}  	} diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 82b70bda9f47..0d2554299688 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1649,7 +1649,7 @@ xfs_alloc_buftarg(  {  	xfs_buftarg_t		*btp; -	btp = kmem_zalloc(sizeof(*btp), KM_SLEEP); +	btp = kmem_zalloc(sizeof(*btp), KM_SLEEP | KM_NOFS);  	btp->bt_mount = mp;  	btp->bt_dev =  bdev->bd_dev; diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 9b26a99ebfe9..0b8b2a13cd24 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -270,6 +270,7 @@ xfs_da3_node_read_verify(  				break;  			return;  		case XFS_ATTR_LEAF_MAGIC: +		case XFS_ATTR3_LEAF_MAGIC:  			bp->b_ops = &xfs_attr3_leaf_buf_ops;  			bp->b_ops->verify_read(bp);  			return; @@ -2464,7 +2465,8 @@ xfs_buf_map_from_irec(  	ASSERT(nirecs >= 1);  	if (nirecs > 1) { -		map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), KM_SLEEP); +		map = kmem_zalloc(nirecs * sizeof(struct xfs_buf_map), +				  KM_SLEEP | KM_NOFS);  		if (!map)  			return ENOMEM;  		*mapp = map; @@ -2520,7 +2522,8 @@ xfs_dabuf_map(  		 * Optimize the one-block case.  		 */  		if (nfsb != 1) -			irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP); +			irecs = kmem_zalloc(sizeof(irec) * nfsb, +					    KM_SLEEP | KM_NOFS);  		nirecs = nfsb;  		error = xfs_bmapi_read(dp, (xfs_fileoff_t)bno, nfsb, irecs, diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 721ba2fe8e54..da71a1819d78 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c @@ -1336,7 +1336,7 @@ xfs_dir2_leaf_getdents(  				     mp->m_sb.sb_blocksize);  	map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +  				(length * sizeof(struct xfs_bmbt_irec)), -			       KM_SLEEP); +			       KM_SLEEP | KM_NOFS);  	map_info->map_size = length;  	/* diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index c0f375087efc..452920a3f03f 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -305,11 +305,12 @@ xfs_efi_release(xfs_efi_log_item_t	*efip,  {  	ASSERT(atomic_read(&efip->efi_next_extent) >= nextents);  	if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) { -		__xfs_efi_release(efip); -  		/* recovery needs us to drop the EFI reference, too */  		if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))  			__xfs_efi_release(efip); + +		__xfs_efi_release(efip); +		/* efip may now have been freed, do not reference it again. */  	}  } diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index e3d0b85d852b..d0833b54e55d 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -139,7 +139,7 @@ xlog_cil_prepare_log_vecs(  		new_lv = kmem_zalloc(sizeof(*new_lv) +  				niovecs * sizeof(struct xfs_log_iovec), -				KM_SLEEP); +				KM_SLEEP|KM_NOFS);  		/* The allocated iovec region lies beyond the log vector. */  		new_lv->lv_iovecp = (struct xfs_log_iovec *)&new_lv[1]; diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1501f4fa51a6..0176bb21f09a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1453,7 +1453,7 @@ xfs_free_file_space(  	xfs_mount_t		*mp;  	int			nimap;  	uint			resblks; -	uint			rounding; +	xfs_off_t		rounding;  	int			rt;  	xfs_fileoff_t		startoffset_fsb;  	xfs_trans_t		*tp; @@ -1482,7 +1482,7 @@ xfs_free_file_space(  		inode_dio_wait(VFS_I(ip));  	} -	rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); +	rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);  	ioffset = offset & ~(rounding - 1);  	error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,  					      ioffset, -1); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 98db31d9f9b4..636c59f2003a 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -377,7 +377,6 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle,  				       unsigned long long *sta);  int acpi_bus_get_status(struct acpi_device *device); -#ifdef CONFIG_PM  int acpi_bus_set_power(acpi_handle handle, int state);  const char *acpi_power_state_string(int state);  int acpi_device_get_power(struct acpi_device *device, int *state); @@ -385,41 +384,12 @@ int acpi_device_set_power(struct acpi_device *device, int state);  int acpi_bus_init_power(struct acpi_device *device);  int acpi_bus_update_power(acpi_handle handle, int *state_p);  bool acpi_bus_power_manageable(acpi_handle handle); + +#ifdef CONFIG_PM  bool acpi_bus_can_wakeup(acpi_handle handle); -#else /* !CONFIG_PM */ -static inline int acpi_bus_set_power(acpi_handle handle, int state) -{ -	return 0; -} -static inline const char *acpi_power_state_string(int state) -{ -	return "D0"; -} -static inline int acpi_device_get_power(struct acpi_device *device, int *state) -{ -	return 0; -} -static inline int acpi_device_set_power(struct acpi_device *device, int state) -{ -	return 0; -} -static inline int acpi_bus_init_power(struct acpi_device *device) -{ -	return 0; -} -static inline int acpi_bus_update_power(acpi_handle handle, int *state_p) -{ -	return 0; -} -static inline bool acpi_bus_power_manageable(acpi_handle handle) -{ -	return false; -} -static inline bool acpi_bus_can_wakeup(acpi_handle handle) -{ -	return false; -} -#endif /* !CONFIG_PM */ +#else +static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; } +#endif  #ifdef CONFIG_ACPI_PROC_EVENT  int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); diff --git a/include/linux/acpi_dma.h b/include/linux/acpi_dma.h index d09deabc7bf6..fb0298082916 100644 --- a/include/linux/acpi_dma.h +++ b/include/linux/acpi_dma.h @@ -37,6 +37,8 @@ struct acpi_dma_spec {   * @dev:		struct device of this controller   * @acpi_dma_xlate:	callback function to find a suitable channel   * @data:		private data used by a callback function + * @base_request_line:	first supported request line (CSRT) + * @end_request_line:	last supported request line (CSRT)   */  struct acpi_dma {  	struct list_head	dma_controllers; @@ -44,6 +46,8 @@ struct acpi_dma {  	struct dma_chan		*(*acpi_dma_xlate)  				(struct acpi_dma_spec *, struct acpi_dma *);  	void			*data; +	unsigned short		base_request_line; +	unsigned short		end_request_line;  };  /* Used with acpi_dma_simple_xlate() */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e96329ceb28c..e9ef6d6b51d5 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -562,6 +562,9 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...);  extern __printf(2, 3)  int __trace_printk(unsigned long ip, const char *fmt, ...); +extern int __trace_bputs(unsigned long ip, const char *str); +extern int __trace_puts(unsigned long ip, const char *str, int size); +  /**   * trace_puts - write a string into the ftrace buffer   * @str: the string to record @@ -587,8 +590,6 @@ int __trace_printk(unsigned long ip, const char *fmt, ...);   *  (1 when __trace_bputs is used, strlen(str) when __trace_puts is used)   */ -extern int __trace_bputs(unsigned long ip, const char *str); -extern int __trace_puts(unsigned long ip, const char *str, int size);  #define trace_puts(str) ({						\  	static const char *trace_printk_fmt				\  		__attribute__((section("__trace_printk_fmt"))) =	\ diff --git a/include/linux/platform_data/clk-lpss.h b/include/linux/platform_data/clk-lpss.h index 528e73ce46d2..23901992b9dd 100644 --- a/include/linux/platform_data/clk-lpss.h +++ b/include/linux/platform_data/clk-lpss.h @@ -13,6 +13,11 @@  #ifndef __CLK_LPSS_H  #define __CLK_LPSS_H +struct lpss_clk_data { +	const char *name; +	struct clk *clk; +}; +  extern int lpt_clk_init(void);  #endif /* __CLK_LPSS_H */ diff --git a/include/linux/platform_data/serial-omap.h b/include/linux/platform_data/serial-omap.h index ff9b0aab5281..c860c1b314c0 100644 --- a/include/linux/platform_data/serial-omap.h +++ b/include/linux/platform_data/serial-omap.h @@ -43,8 +43,6 @@ struct omap_uart_port_info {  	int			DTR_present;  	int (*get_context_loss_count)(struct device *); -	void (*set_forceidle)(struct device *); -	void (*set_noidle)(struct device *);  	void (*enable_wakeup)(struct device *, bool);  }; diff --git a/include/linux/rio.h b/include/linux/rio.h index a3e784278667..18e099342e6f 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -83,7 +83,6 @@  extern struct bus_type rio_bus_type;  extern struct device rio_bus; -extern struct list_head rio_devices;	/* list of all devices */  struct rio_mport;  struct rio_dev; @@ -237,6 +236,7 @@ enum rio_phy_type {   * @name: Port name string   * @priv: Master port private data   * @dma: DMA device associated with mport + * @nscan: RapidIO network enumeration/discovery operations   */  struct rio_mport {  	struct list_head dbells;	/* list of doorbell events */ @@ -262,8 +262,14 @@ struct rio_mport {  #ifdef CONFIG_RAPIDIO_DMA_ENGINE  	struct dma_device	dma;  #endif +	struct rio_scan *nscan;  }; +/* + * Enumeration/discovery control flags + */ +#define RIO_SCAN_ENUM_NO_WAIT	0x00000001 /* Do not wait for enum completed */ +  struct rio_id_table {  	u16 start;	/* logical minimal id */  	u32 max;	/* max number of IDs in table */ @@ -460,6 +466,16 @@ static inline struct rio_mport *dma_to_mport(struct dma_device *ddev)  }  #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ +/** + * struct rio_scan - RIO enumeration and discovery operations + * @enumerate: Callback to perform RapidIO fabric enumeration. + * @discover: Callback to perform RapidIO fabric discovery. + */ +struct rio_scan { +	int (*enumerate)(struct rio_mport *mport, u32 flags); +	int (*discover)(struct rio_mport *mport, u32 flags); +}; +  /* Architecture and hardware-specific functions */  extern int rio_register_mport(struct rio_mport *);  extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int); diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h index b75c05920ab5..5059994fe297 100644 --- a/include/linux/rio_drv.h +++ b/include/linux/rio_drv.h @@ -433,5 +433,6 @@ extern u16 rio_local_get_device_id(struct rio_mport *port);  extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);  extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,  				   struct rio_dev *from); +extern int rio_init_mports(void);  #endif				/* LINUX_RIO_DRV_H */ diff --git a/include/linux/wait.h b/include/linux/wait.h index ac38be2692d8..1133695eb067 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -217,6 +217,8 @@ do {									\  		if (!ret)						\  			break;						\  	}								\ +	if (!ret && (condition))					\ +		ret = 1;						\  	finish_wait(&wq, &__wait);					\  } while (0) @@ -233,8 +235,9 @@ do {									\   * wake_up() has to be called after changing any variable that could   * change the result of the wait condition.   * - * The function returns 0 if the @timeout elapsed, and the remaining - * jiffies if the condition evaluated to true before the timeout elapsed. + * The function returns 0 if the @timeout elapsed, or the remaining + * jiffies (at least 1) if the @condition evaluated to %true before + * the @timeout elapsed.   */  #define wait_event_timeout(wq, condition, timeout)			\  ({									\ @@ -302,6 +305,8 @@ do {									\  		ret = -ERESTARTSYS;					\  		break;							\  	}								\ +	if (!ret && (condition))					\ +		ret = 1;						\  	finish_wait(&wq, &__wait);					\  } while (0) @@ -318,9 +323,10 @@ do {									\   * wake_up() has to be called after changing any variable that could   * change the result of the wait condition.   * - * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it - * was interrupted by a signal, and the remaining jiffies otherwise - * if the condition evaluated to true before the timeout elapsed. + * Returns: + * 0 if the @timeout elapsed, -%ERESTARTSYS if it was interrupted by + * a signal, or the remaining jiffies (at least 1) if the @condition + * evaluated to %true before the @timeout elapsed.   */  #define wait_event_interruptible_timeout(wq, condition, timeout)	\  ({									\ diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 83a2970295d1..6bd4a90d1991 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1021,9 +1021,6 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re   * @seq: netlink audit message sequence (serial) number   * @data: payload data   * @datasz: size of payload data - * @loginuid: loginuid of sender - * @sessionid: sessionid for netlink audit message - * @sid: SE Linux Security ID of sender   */  int audit_receive_filter(int type, int pid, int seq, void *data, size_t datasz)  { diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 03a89a2f464b..362c329b83fe 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2325,7 +2325,12 @@ static void collapse_huge_page(struct mm_struct *mm,  		pte_unmap(pte);  		spin_lock(&mm->page_table_lock);  		BUG_ON(!pmd_none(*pmd)); -		set_pmd_at(mm, address, pmd, _pmd); +		/* +		 * We can only use set_pmd_at when establishing +		 * hugepmds and never for establishing regular pmds that +		 * points to regular pagetables. Use pmd_populate for that +		 */ +		pmd_populate(mm, pmd, pmd_pgtable(_pmd));  		spin_unlock(&mm->page_table_lock);  		anon_vma_unlock_write(vma->anon_vma);  		goto out; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index cb1c9dedf9b6..010d6c14129a 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4108,8 +4108,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype,  	if (mem_cgroup_disabled())  		return NULL; -	VM_BUG_ON(PageSwapCache(page)); -  	if (PageTransHuge(page)) {  		nr_pages <<= compound_order(page);  		VM_BUG_ON(!PageTransHuge(page)); @@ -4205,6 +4203,18 @@ void mem_cgroup_uncharge_page(struct page *page)  	if (page_mapped(page))  		return;  	VM_BUG_ON(page->mapping && !PageAnon(page)); +	/* +	 * If the page is in swap cache, uncharge should be deferred +	 * to the swap path, which also properly accounts swap usage +	 * and handles memcg lifetime. +	 * +	 * Note that this check is not stable and reclaim may add the +	 * page to swap cache at any time after this.  However, if the +	 * page is not in swap cache by the time page->mapcount hits +	 * 0, there won't be any page table references to the swap +	 * slot, and reclaim will free it and not actually write the +	 * page to disk. +	 */  	if (PageSwapCache(page))  		return;  	__mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_ANON, false); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a221fac1f47d..1ad92b46753e 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -720,9 +720,12 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,  	start = phys_start_pfn << PAGE_SHIFT;  	size = nr_pages * PAGE_SIZE;  	ret = release_mem_region_adjustable(&iomem_resource, start, size); -	if (ret) -		pr_warn("Unable to release resource <%016llx-%016llx> (%d)\n", -				start, start + size - 1, ret); +	if (ret) { +		resource_size_t endres = start + size - 1; + +		pr_warn("Unable to release resource <%pa-%pa> (%d)\n", +				&start, &endres, ret); +	}  	sections_to_remove = nr_pages / PAGES_PER_SECTION;  	for (i = 0; i < sections_to_remove; i++) { diff --git a/mm/migrate.c b/mm/migrate.c index 27ed22579fd9..b1f57501de9c 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -165,7 +165,7 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,  		pte = arch_make_huge_pte(pte, vma, new, 0);  	}  #endif -	flush_cache_page(vma, addr, pte_pfn(pte)); +	flush_dcache_page(new);  	set_pte_at(mm, addr, ptep, pte);  	if (PageHuge(new)) { diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index be04122fb277..6725ff183374 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -40,48 +40,44 @@ void __mmu_notifier_release(struct mm_struct *mm)  	int id;  	/* -	 * srcu_read_lock() here will block synchronize_srcu() in -	 * mmu_notifier_unregister() until all registered -	 * ->release() callouts this function makes have -	 * returned. +	 * SRCU here will block mmu_notifier_unregister until +	 * ->release returns.  	 */  	id = srcu_read_lock(&srcu); +	hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) +		/* +		 * If ->release runs before mmu_notifier_unregister it must be +		 * handled, as it's the only way for the driver to flush all +		 * existing sptes and stop the driver from establishing any more +		 * sptes before all the pages in the mm are freed. +		 */ +		if (mn->ops->release) +			mn->ops->release(mn, mm); +	srcu_read_unlock(&srcu, id); +  	spin_lock(&mm->mmu_notifier_mm->lock);  	while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {  		mn = hlist_entry(mm->mmu_notifier_mm->list.first,  				 struct mmu_notifier,  				 hlist); -  		/* -		 * Unlink.  This will prevent mmu_notifier_unregister() -		 * from also making the ->release() callout. +		 * We arrived before mmu_notifier_unregister so +		 * mmu_notifier_unregister will do nothing other than to wait +		 * for ->release to finish and for mmu_notifier_unregister to +		 * return.  		 */  		hlist_del_init_rcu(&mn->hlist); -		spin_unlock(&mm->mmu_notifier_mm->lock); - -		/* -		 * Clear sptes. (see 'release' description in mmu_notifier.h) -		 */ -		if (mn->ops->release) -			mn->ops->release(mn, mm); - -		spin_lock(&mm->mmu_notifier_mm->lock);  	}  	spin_unlock(&mm->mmu_notifier_mm->lock);  	/* -	 * All callouts to ->release() which we have done are complete. -	 * Allow synchronize_srcu() in mmu_notifier_unregister() to complete -	 */ -	srcu_read_unlock(&srcu, id); - -	/* -	 * mmu_notifier_unregister() may have unlinked a notifier and may -	 * still be calling out to it.	Additionally, other notifiers -	 * may have been active via vmtruncate() et. al. Block here -	 * to ensure that all notifier callouts for this mm have been -	 * completed and the sptes are really cleaned up before returning -	 * to exit_mmap(). +	 * synchronize_srcu here prevents mmu_notifier_release from returning to +	 * exit_mmap (which would proceed with freeing all pages in the mm) +	 * until the ->release method returns, if it was invoked by +	 * mmu_notifier_unregister. +	 * +	 * The mmu_notifier_mm can't go away from under us because one mm_count +	 * is held by exit_mmap.  	 */  	synchronize_srcu(&srcu);  } @@ -292,31 +288,34 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)  {  	BUG_ON(atomic_read(&mm->mm_count) <= 0); -	spin_lock(&mm->mmu_notifier_mm->lock);  	if (!hlist_unhashed(&mn->hlist)) { +		/* +		 * SRCU here will force exit_mmap to wait for ->release to +		 * finish before freeing the pages. +		 */  		int id; +		id = srcu_read_lock(&srcu);  		/* -		 * Ensure we synchronize up with __mmu_notifier_release(). +		 * exit_mmap will block in mmu_notifier_release to guarantee +		 * that ->release is called before freeing the pages.  		 */ -		id = srcu_read_lock(&srcu); - -		hlist_del_rcu(&mn->hlist); -		spin_unlock(&mm->mmu_notifier_mm->lock); -  		if (mn->ops->release)  			mn->ops->release(mn, mm); +		srcu_read_unlock(&srcu, id); +		spin_lock(&mm->mmu_notifier_mm->lock);  		/* -		 * Allow __mmu_notifier_release() to complete. +		 * Can not use list_del_rcu() since __mmu_notifier_release +		 * can delete it before we hold the lock.  		 */ -		srcu_read_unlock(&srcu, id); -	} else +		hlist_del_init_rcu(&mn->hlist);  		spin_unlock(&mm->mmu_notifier_mm->lock); +	}  	/* -	 * Wait for any running method to finish, including ->release() if it -	 * was run by __mmu_notifier_release() instead of us. +	 * Wait for any running method to finish, of course including +	 * ->release if it was run by mmu_notifier_relase instead of us.  	 */  	synchronize_srcu(&srcu); diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 35aa294656cd..5da2cbcfdbb5 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -127,28 +127,7 @@ static int walk_hugetlb_range(struct vm_area_struct *vma,  	return 0;  } -static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk) -{ -	struct vm_area_struct *vma; - -	/* We don't need vma lookup at all. */ -	if (!walk->hugetlb_entry) -		return NULL; - -	VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem)); -	vma = find_vma(walk->mm, addr); -	if (vma && vma->vm_start <= addr && is_vm_hugetlb_page(vma)) -		return vma; - -	return NULL; -} -  #else /* CONFIG_HUGETLB_PAGE */ -static struct vm_area_struct* hugetlb_vma(unsigned long addr, struct mm_walk *walk) -{ -	return NULL; -} -  static int walk_hugetlb_range(struct vm_area_struct *vma,  			      unsigned long addr, unsigned long end,  			      struct mm_walk *walk) @@ -198,30 +177,53 @@ int walk_page_range(unsigned long addr, unsigned long end,  	if (!walk->mm)  		return -EINVAL; +	VM_BUG_ON(!rwsem_is_locked(&walk->mm->mmap_sem)); +  	pgd = pgd_offset(walk->mm, addr);  	do { -		struct vm_area_struct *vma; +		struct vm_area_struct *vma = NULL;  		next = pgd_addr_end(addr, end);  		/* -		 * handle hugetlb vma individually because pagetable walk for -		 * the hugetlb page is dependent on the architecture and -		 * we can't handled it in the same manner as non-huge pages. +		 * This function was not intended to be vma based. +		 * But there are vma special cases to be handled: +		 * - hugetlb vma's +		 * - VM_PFNMAP vma's  		 */ -		vma = hugetlb_vma(addr, walk); +		vma = find_vma(walk->mm, addr);  		if (vma) { -			if (vma->vm_end < next) +			/* +			 * There are no page structures backing a VM_PFNMAP +			 * range, so do not allow split_huge_page_pmd(). +			 */ +			if ((vma->vm_start <= addr) && +			    (vma->vm_flags & VM_PFNMAP)) {  				next = vma->vm_end; +				pgd = pgd_offset(walk->mm, next); +				continue; +			}  			/* -			 * Hugepage is very tightly coupled with vma, so -			 * walk through hugetlb entries within a given vma. +			 * Handle hugetlb vma individually because pagetable +			 * walk for the hugetlb page is dependent on the +			 * architecture and we can't handled it in the same +			 * manner as non-huge pages.  			 */ -			err = walk_hugetlb_range(vma, addr, next, walk); -			if (err) -				break; -			pgd = pgd_offset(walk->mm, next); -			continue; +			if (walk->hugetlb_entry && (vma->vm_start <= addr) && +			    is_vm_hugetlb_page(vma)) { +				if (vma->vm_end < next) +					next = vma->vm_end; +				/* +				 * Hugepage is very tightly coupled with vma, +				 * so walk through hugetlb entries within a +				 * given vma. +				 */ +				err = walk_hugetlb_range(vma, addr, next, walk); +				if (err) +					break; +				pgd = pgd_offset(walk->mm, next); +				continue; +			}  		}  		if (pgd_none_or_clear_bad(pgd)) { diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index d4abc59ce1d9..0a63658065f0 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -6,7 +6,6 @@ TARGETS += memory-hotplug  TARGETS += mqueue  TARGETS += net  TARGETS += ptrace -TARGETS += soft-dirty  TARGETS += vm  all: diff --git a/tools/testing/selftests/soft-dirty/Makefile b/tools/testing/selftests/soft-dirty/Makefile deleted file mode 100644 index a9cdc823d6e0..000000000000 --- a/tools/testing/selftests/soft-dirty/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -CFLAGS += -iquote../../../../include/uapi -Wall -soft-dirty: soft-dirty.c - -all: soft-dirty - -clean: -	rm -f soft-dirty - -run_tests: all -	@./soft-dirty || echo "soft-dirty selftests: [FAIL]" diff --git a/tools/testing/selftests/soft-dirty/soft-dirty.c b/tools/testing/selftests/soft-dirty/soft-dirty.c deleted file mode 100644 index aba4f87f87f0..000000000000 --- a/tools/testing/selftests/soft-dirty/soft-dirty.c +++ /dev/null @@ -1,114 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <sys/mman.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> - -typedef unsigned long long u64; - -#define PME_PRESENT	(1ULL << 63) -#define PME_SOFT_DIRTY	(1Ull << 55) - -#define PAGES_TO_TEST	3 -#ifndef PAGE_SIZE -#define PAGE_SIZE	4096 -#endif - -static void get_pagemap2(char *mem, u64 *map) -{ -	int fd; - -	fd = open("/proc/self/pagemap2", O_RDONLY); -	if (fd < 0) { -		perror("Can't open pagemap2"); -		exit(1); -	} - -	lseek(fd, (unsigned long)mem / PAGE_SIZE * sizeof(u64), SEEK_SET); -	read(fd, map, sizeof(u64) * PAGES_TO_TEST); -	close(fd); -} - -static inline char map_p(u64 map) -{ -	return map & PME_PRESENT ? 'p' : '-'; -} - -static inline char map_sd(u64 map) -{ -	return map & PME_SOFT_DIRTY ? 'd' : '-'; -} - -static int check_pte(int step, int page, u64 *map, u64 want) -{ -	if ((map[page] & want) != want) { -		printf("Step %d Page %d has %c%c, want %c%c\n", -				step, page, -				map_p(map[page]), map_sd(map[page]), -				map_p(want), map_sd(want)); -		return 1; -	} - -	return 0; -} - -static void clear_refs(void) -{ -	int fd; -	char *v = "4"; - -	fd = open("/proc/self/clear_refs", O_WRONLY); -	if (write(fd, v, 3) < 3) { -		perror("Can't clear soft-dirty bit"); -		exit(1); -	} -	close(fd); -} - -int main(void) -{ -	char *mem, x; -	u64 map[PAGES_TO_TEST]; - -	mem = mmap(NULL, PAGES_TO_TEST * PAGE_SIZE, -			PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0); - -	x = mem[0]; -	mem[2 * PAGE_SIZE] = 'c'; -	get_pagemap2(mem, map); - -	if (check_pte(1, 0, map, PME_PRESENT)) -		return 1; -	if (check_pte(1, 1, map, 0)) -		return 1; -	if (check_pte(1, 2, map, PME_PRESENT | PME_SOFT_DIRTY)) -		return 1; - -	clear_refs(); -	get_pagemap2(mem, map); - -	if (check_pte(2, 0, map, PME_PRESENT)) -		return 1; -	if (check_pte(2, 1, map, 0)) -		return 1; -	if (check_pte(2, 2, map, PME_PRESENT)) -		return 1; - -	mem[0] = 'a'; -	mem[PAGE_SIZE] = 'b'; -	x = mem[2 * PAGE_SIZE]; -	get_pagemap2(mem, map); - -	if (check_pte(3, 0, map, PME_PRESENT | PME_SOFT_DIRTY)) -		return 1; -	if (check_pte(3, 1, map, PME_PRESENT | PME_SOFT_DIRTY)) -		return 1; -	if (check_pte(3, 2, map, PME_PRESENT)) -		return 1; - -	(void)x; /* gcc warn */ - -	printf("PASS\n"); -	return 0; -} | 
