Linux 3.19-rc5
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJUu0x7AAoJEHm+PkMAQRiGH/8H/14SgHC8A+tGEY1Hmgr7Y6ah kAcev/QMIxvtxKK0zdhgSILiBUrbK1CAXFGbueUAHgSaCucry5rpJvhFCIzSaCmm 60yLZKvNrxXX4Zc1SYxxW+2EfDCNd0tO6uZK30kyzYYmw6fCgLMEXL6pFI0wFJRg G41yL7MogjJJP0JFGjwrFTeJ6ZBahErOmMpx1qrHuDN8cbdZvG8w6A0KP7ch6Ct1 qdwcpOK4L9AXG+fbE7AJCSBkVev4KqwknPSWQ+jWX7ftw3q0P1O6dXY94ob3PqVi jsWmraOCd5uJrX9uSiOJCsbwoaHHMTNOsEF71qQKDrQzcGCPJAxd1Mi696JdDAQ= =jNTS -----END PGP SIGNATURE----- Merge tag 'v3.19-rc5' into next Linux 3.19-rc5 Conflicts: drivers/usb/dwc2/gadget.c drivers/usb/gadget/udc/bdc/bdc_ep.c
This commit is contained in:
		
				commit
				
					
						d1fc4440d7
					
				
			
		
					 263 changed files with 2404 additions and 1119 deletions
				
			
		| 
						 | 
					@ -14,3 +14,18 @@ Description:
 | 
				
			||||||
		The /sys/class/mei/meiN directory is created for
 | 
							The /sys/class/mei/meiN directory is created for
 | 
				
			||||||
		each probed mei device
 | 
							each probed mei device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:		/sys/class/mei/meiN/fw_status
 | 
				
			||||||
 | 
					Date:		Nov 2014
 | 
				
			||||||
 | 
					KernelVersion:	3.19
 | 
				
			||||||
 | 
					Contact:	Tomas Winkler <tomas.winkler@intel.com>
 | 
				
			||||||
 | 
					Description:	Display fw status registers content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							The ME FW writes its status information into fw status
 | 
				
			||||||
 | 
							registers for BIOS and OS to monitor fw health.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							The register contains running state, power management
 | 
				
			||||||
 | 
							state, error codes, and others. The way the registers
 | 
				
			||||||
 | 
							are decoded depends on PCH or SoC generation.
 | 
				
			||||||
 | 
							Also number of registers varies between 1 and 6
 | 
				
			||||||
 | 
							depending on generation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,8 @@ fwmark_reflect - BOOLEAN
 | 
				
			||||||
route/max_size - INTEGER
 | 
					route/max_size - INTEGER
 | 
				
			||||||
	Maximum number of routes allowed in the kernel.  Increase
 | 
						Maximum number of routes allowed in the kernel.  Increase
 | 
				
			||||||
	this when using large numbers of interfaces and/or routes.
 | 
						this when using large numbers of interfaces and/or routes.
 | 
				
			||||||
 | 
						From linux kernel 3.6 onwards, this is deprecated for ipv4
 | 
				
			||||||
 | 
						as route cache is no longer used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
neigh/default/gc_thresh1 - INTEGER
 | 
					neigh/default/gc_thresh1 - INTEGER
 | 
				
			||||||
	Minimum number of entries to keep.  Garbage collector will not
 | 
						Minimum number of entries to keep.  Garbage collector will not
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -389,9 +389,6 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 | 
				
			||||||
	buf += "	.release_cmd			= " + fabric_mod_name + "_release_cmd,\n"
 | 
						buf += "	.release_cmd			= " + fabric_mod_name + "_release_cmd,\n"
 | 
				
			||||||
	buf += "	.shutdown_session		= " + fabric_mod_name + "_shutdown_session,\n"
 | 
						buf += "	.shutdown_session		= " + fabric_mod_name + "_shutdown_session,\n"
 | 
				
			||||||
	buf += "	.close_session			= " + fabric_mod_name + "_close_session,\n"
 | 
						buf += "	.close_session			= " + fabric_mod_name + "_close_session,\n"
 | 
				
			||||||
	buf += "	.stop_session			= " + fabric_mod_name + "_stop_session,\n"
 | 
					 | 
				
			||||||
	buf += "	.fall_back_to_erl0		= " + fabric_mod_name + "_reset_nexus,\n"
 | 
					 | 
				
			||||||
	buf += "	.sess_logged_in			= " + fabric_mod_name + "_sess_logged_in,\n"
 | 
					 | 
				
			||||||
	buf += "	.sess_get_index			= " + fabric_mod_name + "_sess_get_index,\n"
 | 
						buf += "	.sess_get_index			= " + fabric_mod_name + "_sess_get_index,\n"
 | 
				
			||||||
	buf += "	.sess_get_initiator_sid		= NULL,\n"
 | 
						buf += "	.sess_get_initiator_sid		= NULL,\n"
 | 
				
			||||||
	buf += "	.write_pending			= " + fabric_mod_name + "_write_pending,\n"
 | 
						buf += "	.write_pending			= " + fabric_mod_name + "_write_pending,\n"
 | 
				
			||||||
| 
						 | 
					@ -402,7 +399,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 | 
				
			||||||
	buf += "	.queue_data_in			= " + fabric_mod_name + "_queue_data_in,\n"
 | 
						buf += "	.queue_data_in			= " + fabric_mod_name + "_queue_data_in,\n"
 | 
				
			||||||
	buf += "	.queue_status			= " + fabric_mod_name + "_queue_status,\n"
 | 
						buf += "	.queue_status			= " + fabric_mod_name + "_queue_status,\n"
 | 
				
			||||||
	buf += "	.queue_tm_rsp			= " + fabric_mod_name + "_queue_tm_rsp,\n"
 | 
						buf += "	.queue_tm_rsp			= " + fabric_mod_name + "_queue_tm_rsp,\n"
 | 
				
			||||||
	buf += "	.is_state_remove		= " + fabric_mod_name + "_is_state_remove,\n"
 | 
						buf += "	.aborted_task			= " + fabric_mod_name + "_aborted_task,\n"
 | 
				
			||||||
	buf += "	/*\n"
 | 
						buf += "	/*\n"
 | 
				
			||||||
	buf += "	 * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
 | 
						buf += "	 * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
 | 
				
			||||||
	buf += "	 */\n"
 | 
						buf += "	 */\n"
 | 
				
			||||||
| 
						 | 
					@ -428,7 +425,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 | 
				
			||||||
	buf += "	/*\n"
 | 
						buf += "	/*\n"
 | 
				
			||||||
	buf += "	 * Register the top level struct config_item_type with TCM core\n"
 | 
						buf += "	 * Register the top level struct config_item_type with TCM core\n"
 | 
				
			||||||
	buf += "	 */\n"
 | 
						buf += "	 */\n"
 | 
				
			||||||
	buf += "	fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name[4:] + "\");\n"
 | 
						buf += "	fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name + "\");\n"
 | 
				
			||||||
	buf += "	if (IS_ERR(fabric)) {\n"
 | 
						buf += "	if (IS_ERR(fabric)) {\n"
 | 
				
			||||||
	buf += "		printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
 | 
						buf += "		printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
 | 
				
			||||||
	buf += "		return PTR_ERR(fabric);\n"
 | 
						buf += "		return PTR_ERR(fabric);\n"
 | 
				
			||||||
| 
						 | 
					@ -595,7 +592,7 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 | 
				
			||||||
		if re.search('get_fabric_name', fo):
 | 
							if re.search('get_fabric_name', fo):
 | 
				
			||||||
			buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
 | 
								buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
 | 
				
			||||||
			buf += "{\n"
 | 
								buf += "{\n"
 | 
				
			||||||
			buf += "	return \"" + fabric_mod_name[4:] + "\";\n"
 | 
								buf += "	return \"" + fabric_mod_name + "\";\n"
 | 
				
			||||||
			buf += "}\n\n"
 | 
								buf += "}\n\n"
 | 
				
			||||||
			bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
 | 
								bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
| 
						 | 
					@ -820,27 +817,6 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 | 
				
			||||||
			buf += "}\n\n"
 | 
								buf += "}\n\n"
 | 
				
			||||||
			bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
 | 
								bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if re.search('stop_session\)\(', fo):
 | 
					 | 
				
			||||||
			buf += "void " + fabric_mod_name + "_stop_session(struct se_session *se_sess, int sess_sleep , int conn_sleep)\n"
 | 
					 | 
				
			||||||
			buf += "{\n"
 | 
					 | 
				
			||||||
			buf += "	return;\n"
 | 
					 | 
				
			||||||
			buf += "}\n\n"
 | 
					 | 
				
			||||||
			bufi += "void " + fabric_mod_name + "_stop_session(struct se_session *, int, int);\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if re.search('fall_back_to_erl0\)\(', fo):
 | 
					 | 
				
			||||||
			buf += "void " + fabric_mod_name + "_reset_nexus(struct se_session *se_sess)\n"
 | 
					 | 
				
			||||||
			buf += "{\n"
 | 
					 | 
				
			||||||
			buf += "	return;\n"
 | 
					 | 
				
			||||||
			buf += "}\n\n"
 | 
					 | 
				
			||||||
			bufi += "void " + fabric_mod_name + "_reset_nexus(struct se_session *);\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if re.search('sess_logged_in\)\(', fo):
 | 
					 | 
				
			||||||
			buf += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *se_sess)\n"
 | 
					 | 
				
			||||||
			buf += "{\n"
 | 
					 | 
				
			||||||
			buf += "	return 0;\n"
 | 
					 | 
				
			||||||
			buf += "}\n\n"
 | 
					 | 
				
			||||||
			bufi += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *);\n"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if re.search('sess_get_index\)\(', fo):
 | 
							if re.search('sess_get_index\)\(', fo):
 | 
				
			||||||
			buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
 | 
								buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
 | 
				
			||||||
			buf += "{\n"
 | 
								buf += "{\n"
 | 
				
			||||||
| 
						 | 
					@ -898,19 +874,18 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 | 
				
			||||||
			bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
 | 
								bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if re.search('queue_tm_rsp\)\(', fo):
 | 
							if re.search('queue_tm_rsp\)\(', fo):
 | 
				
			||||||
			buf += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
 | 
								buf += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
 | 
				
			||||||
			buf += "{\n"
 | 
								buf += "{\n"
 | 
				
			||||||
			buf += "	return 0;\n"
 | 
								buf += "	return;\n"
 | 
				
			||||||
			buf += "}\n\n"
 | 
								buf += "}\n\n"
 | 
				
			||||||
			bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
 | 
								bufi += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if re.search('is_state_remove\)\(', fo):
 | 
							if re.search('aborted_task\)\(', fo):
 | 
				
			||||||
			buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
 | 
								buf += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *se_cmd)\n"
 | 
				
			||||||
			buf += "{\n"
 | 
								buf += "{\n"
 | 
				
			||||||
			buf += "	return 0;\n"
 | 
								buf += "	return;\n"
 | 
				
			||||||
			buf += "}\n\n"
 | 
								buf += "}\n\n"
 | 
				
			||||||
			bufi += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *);\n"
 | 
								bufi += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *);\n"
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = p.write(buf)
 | 
						ret = p.write(buf)
 | 
				
			||||||
	if ret:
 | 
						if ret:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ CPU cooling APIs How To
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Written by Amit Daniel Kachhap <amit.kachhap@linaro.org>
 | 
					Written by Amit Daniel Kachhap <amit.kachhap@linaro.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Updated: 12 May 2012
 | 
					Updated: 6 Jan 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright (c)  2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
 | 
					Copyright (c)  2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,18 @@ the user. The registration APIs returns the cooling device pointer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   clip_cpus: cpumask of cpus where the frequency constraints will happen.
 | 
					   clip_cpus: cpumask of cpus where the frequency constraints will happen.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1.1.2 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 | 
					1.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register(
 | 
				
			||||||
 | 
						struct device_node *np, const struct cpumask *clip_cpus)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This interface function registers the cpufreq cooling device with
 | 
				
			||||||
 | 
					    the name "thermal-cpufreq-%x" linking it with a device tree node, in
 | 
				
			||||||
 | 
					    order to bind it via the thermal DT code. This api can support multiple
 | 
				
			||||||
 | 
					    instances of cpufreq cooling devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    np: pointer to the cooling device device tree node
 | 
				
			||||||
 | 
					    clip_cpus: cpumask of cpus where the frequency constraints will happen.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1.1.3 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This interface function unregisters the "thermal-cpufreq-%x" cooling device.
 | 
					    This interface function unregisters the "thermal-cpufreq-%x" cooling device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								MAINTAINERS
									
										
									
									
									
								
							
							
						
						
									
										19
									
								
								MAINTAINERS
									
										
									
									
									
								
							| 
						 | 
					@ -3183,7 +3183,7 @@ L:	dmaengine@vger.kernel.org
 | 
				
			||||||
Q:	https://patchwork.kernel.org/project/linux-dmaengine/list/
 | 
					Q:	https://patchwork.kernel.org/project/linux-dmaengine/list/
 | 
				
			||||||
S:	Maintained
 | 
					S:	Maintained
 | 
				
			||||||
F:	drivers/dma/
 | 
					F:	drivers/dma/
 | 
				
			||||||
F:	include/linux/dma*
 | 
					F:	include/linux/dmaengine.h
 | 
				
			||||||
F:	Documentation/dmaengine/
 | 
					F:	Documentation/dmaengine/
 | 
				
			||||||
T:	git git://git.infradead.org/users/vkoul/slave-dma.git
 | 
					T:	git git://git.infradead.org/users/vkoul/slave-dma.git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4749,7 +4749,7 @@ S:	Supported
 | 
				
			||||||
F:	drivers/scsi/ipr.*
 | 
					F:	drivers/scsi/ipr.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IBM Power Virtual Ethernet Device Driver
 | 
					IBM Power Virtual Ethernet Device Driver
 | 
				
			||||||
M:	Santiago Leon <santil@linux.vnet.ibm.com>
 | 
					M:	Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
 | 
				
			||||||
L:	netdev@vger.kernel.org
 | 
					L:	netdev@vger.kernel.org
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
F:	drivers/net/ethernet/ibm/ibmveth.*
 | 
					F:	drivers/net/ethernet/ibm/ibmveth.*
 | 
				
			||||||
| 
						 | 
					@ -5280,6 +5280,15 @@ W:	www.open-iscsi.org
 | 
				
			||||||
Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 | 
					Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 | 
				
			||||||
F:	drivers/infiniband/ulp/iser/
 | 
					F:	drivers/infiniband/ulp/iser/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ISCSI EXTENSIONS FOR RDMA (ISER) TARGET
 | 
				
			||||||
 | 
					M:	Sagi Grimberg <sagig@mellanox.com>
 | 
				
			||||||
 | 
					T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
 | 
				
			||||||
 | 
					L:	linux-rdma@vger.kernel.org
 | 
				
			||||||
 | 
					L:	target-devel@vger.kernel.org
 | 
				
			||||||
 | 
					S:	Supported
 | 
				
			||||||
 | 
					W:	http://www.linux-iscsi.org
 | 
				
			||||||
 | 
					F:	drivers/infiniband/ulp/isert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ISDN SUBSYSTEM
 | 
					ISDN SUBSYSTEM
 | 
				
			||||||
M:	Karsten Keil <isdn@linux-pingi.de>
 | 
					M:	Karsten Keil <isdn@linux-pingi.de>
 | 
				
			||||||
L:	isdn4linux@listserv.isdn4linux.de (subscribers-only)
 | 
					L:	isdn4linux@listserv.isdn4linux.de (subscribers-only)
 | 
				
			||||||
| 
						 | 
					@ -7738,8 +7747,7 @@ F:	Documentation/scsi/LICENSE.qla2xxx
 | 
				
			||||||
F:	drivers/scsi/qla2xxx/
 | 
					F:	drivers/scsi/qla2xxx/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QLOGIC QLA4XXX iSCSI DRIVER
 | 
					QLOGIC QLA4XXX iSCSI DRIVER
 | 
				
			||||||
M:	Vikas Chaudhary <vikas.chaudhary@qlogic.com>
 | 
					M:	QLogic-Storage-Upstream@qlogic.com
 | 
				
			||||||
M:	iscsi-driver@qlogic.com
 | 
					 | 
				
			||||||
L:	linux-scsi@vger.kernel.org
 | 
					L:	linux-scsi@vger.kernel.org
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
F:	Documentation/scsi/LICENSE.qla4xxx
 | 
					F:	Documentation/scsi/LICENSE.qla4xxx
 | 
				
			||||||
| 
						 | 
					@ -9534,7 +9542,8 @@ F:	drivers/platform/x86/thinkpad_acpi.c
 | 
				
			||||||
TI BANDGAP AND THERMAL DRIVER
 | 
					TI BANDGAP AND THERMAL DRIVER
 | 
				
			||||||
M:	Eduardo Valentin <edubezval@gmail.com>
 | 
					M:	Eduardo Valentin <edubezval@gmail.com>
 | 
				
			||||||
L:	linux-pm@vger.kernel.org
 | 
					L:	linux-pm@vger.kernel.org
 | 
				
			||||||
S:	Supported
 | 
					L:	linux-omap@vger.kernel.org
 | 
				
			||||||
 | 
					S:	Maintained
 | 
				
			||||||
F:	drivers/thermal/ti-soc-thermal/
 | 
					F:	drivers/thermal/ti-soc-thermal/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TI CLOCK DRIVER
 | 
					TI CLOCK DRIVER
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
VERSION = 3
 | 
					VERSION = 3
 | 
				
			||||||
PATCHLEVEL = 19
 | 
					PATCHLEVEL = 19
 | 
				
			||||||
SUBLEVEL = 0
 | 
					SUBLEVEL = 0
 | 
				
			||||||
EXTRAVERSION = -rc4
 | 
					EXTRAVERSION = -rc5
 | 
				
			||||||
NAME = Diseased Newt
 | 
					NAME = Diseased Newt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# *DOCUMENTATION*
 | 
					# *DOCUMENTATION*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -953,6 +953,8 @@
 | 
				
			||||||
			interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>;
 | 
								interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>;
 | 
				
			||||||
			pinctrl-names = "default";
 | 
								pinctrl-names = "default";
 | 
				
			||||||
			pinctrl-0 = <&pinctrl_fb>;
 | 
								pinctrl-0 = <&pinctrl_fb>;
 | 
				
			||||||
 | 
								clocks = <&lcd_clk>, <&lcd_clk>;
 | 
				
			||||||
 | 
								clock-names = "lcdc_clk", "hclk";
 | 
				
			||||||
			status = "disabled";
 | 
								status = "disabled";
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,8 @@
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
&sdhci2 {
 | 
					&sdhci2 {
 | 
				
			||||||
 | 
						broken-cd;
 | 
				
			||||||
 | 
						bus-width = <8>;
 | 
				
			||||||
	non-removable;
 | 
						non-removable;
 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,8 @@
 | 
				
			||||||
			compatible = "mrvl,pxav3-mmc";
 | 
								compatible = "mrvl,pxav3-mmc";
 | 
				
			||||||
			reg = <0xab1000 0x200>;
 | 
								reg = <0xab1000 0x200>;
 | 
				
			||||||
			interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
 | 
								interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
			clocks = <&chip CLKID_SDIO1XIN>;
 | 
								clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
 | 
				
			||||||
 | 
								clock-names = "io", "core";
 | 
				
			||||||
			status = "disabled";
 | 
								status = "disabled";
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -348,36 +349,6 @@
 | 
				
			||||||
				interrupt-parent = <&gic>;
 | 
									interrupt-parent = <&gic>;
 | 
				
			||||||
				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
 | 
									interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					 | 
				
			||||||
			gpio4: gpio@5000 {
 | 
					 | 
				
			||||||
				compatible = "snps,dw-apb-gpio";
 | 
					 | 
				
			||||||
				reg = <0x5000 0x400>;
 | 
					 | 
				
			||||||
				#address-cells = <1>;
 | 
					 | 
				
			||||||
				#size-cells = <0>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				porte: gpio-port@4 {
 | 
					 | 
				
			||||||
					compatible = "snps,dw-apb-gpio-port";
 | 
					 | 
				
			||||||
					gpio-controller;
 | 
					 | 
				
			||||||
					#gpio-cells = <2>;
 | 
					 | 
				
			||||||
					snps,nr-gpios = <32>;
 | 
					 | 
				
			||||||
					reg = <0>;
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			gpio5: gpio@c000 {
 | 
					 | 
				
			||||||
				compatible = "snps,dw-apb-gpio";
 | 
					 | 
				
			||||||
				reg = <0xc000 0x400>;
 | 
					 | 
				
			||||||
				#address-cells = <1>;
 | 
					 | 
				
			||||||
				#size-cells = <0>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				portf: gpio-port@5 {
 | 
					 | 
				
			||||||
					compatible = "snps,dw-apb-gpio-port";
 | 
					 | 
				
			||||||
					gpio-controller;
 | 
					 | 
				
			||||||
					#gpio-cells = <2>;
 | 
					 | 
				
			||||||
					snps,nr-gpios = <32>;
 | 
					 | 
				
			||||||
					reg = <0>;
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chip: chip-control@ea0000 {
 | 
							chip: chip-control@ea0000 {
 | 
				
			||||||
| 
						 | 
					@ -466,6 +437,21 @@
 | 
				
			||||||
			ranges = <0 0xfc0000 0x10000>;
 | 
								ranges = <0 0xfc0000 0x10000>;
 | 
				
			||||||
			interrupt-parent = <&sic>;
 | 
								interrupt-parent = <&sic>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sm_gpio1: gpio@5000 {
 | 
				
			||||||
 | 
									compatible = "snps,dw-apb-gpio";
 | 
				
			||||||
 | 
									reg = <0x5000 0x400>;
 | 
				
			||||||
 | 
									#address-cells = <1>;
 | 
				
			||||||
 | 
									#size-cells = <0>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									portf: gpio-port@5 {
 | 
				
			||||||
 | 
										compatible = "snps,dw-apb-gpio-port";
 | 
				
			||||||
 | 
										gpio-controller;
 | 
				
			||||||
 | 
										#gpio-cells = <2>;
 | 
				
			||||||
 | 
										snps,nr-gpios = <32>;
 | 
				
			||||||
 | 
										reg = <0>;
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			i2c2: i2c@7000 {
 | 
								i2c2: i2c@7000 {
 | 
				
			||||||
				compatible = "snps,designware-i2c";
 | 
									compatible = "snps,designware-i2c";
 | 
				
			||||||
				#address-cells = <1>;
 | 
									#address-cells = <1>;
 | 
				
			||||||
| 
						 | 
					@ -516,6 +502,21 @@
 | 
				
			||||||
				status = "disabled";
 | 
									status = "disabled";
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sm_gpio0: gpio@c000 {
 | 
				
			||||||
 | 
									compatible = "snps,dw-apb-gpio";
 | 
				
			||||||
 | 
									reg = <0xc000 0x400>;
 | 
				
			||||||
 | 
									#address-cells = <1>;
 | 
				
			||||||
 | 
									#size-cells = <0>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									porte: gpio-port@4 {
 | 
				
			||||||
 | 
										compatible = "snps,dw-apb-gpio-port";
 | 
				
			||||||
 | 
										gpio-controller;
 | 
				
			||||||
 | 
										#gpio-cells = <2>;
 | 
				
			||||||
 | 
										snps,nr-gpios = <32>;
 | 
				
			||||||
 | 
										reg = <0>;
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sysctrl: pin-controller@d000 {
 | 
								sysctrl: pin-controller@d000 {
 | 
				
			||||||
				compatible = "marvell,berlin2q-system-ctrl";
 | 
									compatible = "marvell,berlin2q-system-ctrl";
 | 
				
			||||||
				reg = <0xd000 0x100>;
 | 
									reg = <0xd000 0x100>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -499,23 +499,23 @@
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		partition@5 {
 | 
							partition@5 {
 | 
				
			||||||
			label = "QSPI.u-boot-spl-os";
 | 
								label = "QSPI.u-boot-spl-os";
 | 
				
			||||||
			reg = <0x00140000 0x00010000>;
 | 
								reg = <0x00140000 0x00080000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		partition@6 {
 | 
							partition@6 {
 | 
				
			||||||
			label = "QSPI.u-boot-env";
 | 
								label = "QSPI.u-boot-env";
 | 
				
			||||||
			reg = <0x00150000 0x00010000>;
 | 
								reg = <0x001c0000 0x00010000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		partition@7 {
 | 
							partition@7 {
 | 
				
			||||||
			label = "QSPI.u-boot-env.backup1";
 | 
								label = "QSPI.u-boot-env.backup1";
 | 
				
			||||||
			reg = <0x00160000 0x0010000>;
 | 
								reg = <0x001d0000 0x0010000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		partition@8 {
 | 
							partition@8 {
 | 
				
			||||||
			label = "QSPI.kernel";
 | 
								label = "QSPI.kernel";
 | 
				
			||||||
			reg = <0x00170000 0x0800000>;
 | 
								reg = <0x001e0000 0x0800000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		partition@9 {
 | 
							partition@9 {
 | 
				
			||||||
			label = "QSPI.file-system";
 | 
								label = "QSPI.file-system";
 | 
				
			||||||
			reg = <0x00970000 0x01690000>;
 | 
								reg = <0x009e0000 0x01620000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -736,7 +736,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dp_phy: video-phy@10040720 {
 | 
						dp_phy: video-phy@10040720 {
 | 
				
			||||||
		compatible = "samsung,exynos5250-dp-video-phy";
 | 
							compatible = "samsung,exynos5250-dp-video-phy";
 | 
				
			||||||
		reg = <0x10040720 4>;
 | 
							samsung,pmu-syscon = <&pmu_system_controller>;
 | 
				
			||||||
		#phy-cells = <0>;
 | 
							#phy-cells = <0>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -372,3 +372,7 @@
 | 
				
			||||||
&usbdrd_dwc3_1 {
 | 
					&usbdrd_dwc3_1 {
 | 
				
			||||||
	dr_mode = "host";
 | 
						dr_mode = "host";
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					&cci {
 | 
				
			||||||
 | 
						status = "disabled";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,7 +120,7 @@
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cci@10d20000 {
 | 
						cci: cci@10d20000 {
 | 
				
			||||||
		compatible = "arm,cci-400";
 | 
							compatible = "arm,cci-400";
 | 
				
			||||||
		#address-cells = <1>;
 | 
							#address-cells = <1>;
 | 
				
			||||||
		#size-cells = <1>;
 | 
							#size-cells = <1>;
 | 
				
			||||||
| 
						 | 
					@ -503,8 +503,8 @@
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dp_phy: video-phy@10040728 {
 | 
						dp_phy: video-phy@10040728 {
 | 
				
			||||||
		compatible = "samsung,exynos5250-dp-video-phy";
 | 
							compatible = "samsung,exynos5420-dp-video-phy";
 | 
				
			||||||
		reg = <0x10040728 4>;
 | 
							samsung,pmu-syscon = <&pmu_system_controller>;
 | 
				
			||||||
		#phy-cells = <0>;
 | 
							#phy-cells = <0>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,7 @@
 | 
				
			||||||
				#size-cells = <0>;
 | 
									#size-cells = <0>;
 | 
				
			||||||
				compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
 | 
									compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
 | 
				
			||||||
				reg = <0x43fa4000 0x4000>;
 | 
									reg = <0x43fa4000 0x4000>;
 | 
				
			||||||
				clocks = <&clks 62>, <&clks 62>;
 | 
									clocks = <&clks 78>, <&clks 78>;
 | 
				
			||||||
				clock-names = "ipg", "per";
 | 
									clock-names = "ipg", "per";
 | 
				
			||||||
				interrupts = <14>;
 | 
									interrupts = <14>;
 | 
				
			||||||
				status = "disabled";
 | 
									status = "disabled";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,24 +127,12 @@
 | 
				
			||||||
		#address-cells = <1>;
 | 
							#address-cells = <1>;
 | 
				
			||||||
		#size-cells = <0>;
 | 
							#size-cells = <0>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		reg_usbh1_vbus: regulator@0 {
 | 
							reg_hub_reset: regulator@0 {
 | 
				
			||||||
			compatible = "regulator-fixed";
 | 
					 | 
				
			||||||
			pinctrl-names = "default";
 | 
					 | 
				
			||||||
			pinctrl-0 = <&pinctrl_usbh1reg>;
 | 
					 | 
				
			||||||
			reg = <0>;
 | 
					 | 
				
			||||||
			regulator-name = "usbh1_vbus";
 | 
					 | 
				
			||||||
			regulator-min-microvolt = <5000000>;
 | 
					 | 
				
			||||||
			regulator-max-microvolt = <5000000>;
 | 
					 | 
				
			||||||
			gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>;
 | 
					 | 
				
			||||||
			enable-active-high;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		reg_usbotg_vbus: regulator@1 {
 | 
					 | 
				
			||||||
			compatible = "regulator-fixed";
 | 
								compatible = "regulator-fixed";
 | 
				
			||||||
			pinctrl-names = "default";
 | 
								pinctrl-names = "default";
 | 
				
			||||||
			pinctrl-0 = <&pinctrl_usbotgreg>;
 | 
								pinctrl-0 = <&pinctrl_usbotgreg>;
 | 
				
			||||||
			reg = <1>;
 | 
								reg = <0>;
 | 
				
			||||||
			regulator-name = "usbotg_vbus";
 | 
								regulator-name = "hub_reset";
 | 
				
			||||||
			regulator-min-microvolt = <5000000>;
 | 
								regulator-min-microvolt = <5000000>;
 | 
				
			||||||
			regulator-max-microvolt = <5000000>;
 | 
								regulator-max-microvolt = <5000000>;
 | 
				
			||||||
			gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
 | 
								gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
 | 
				
			||||||
| 
						 | 
					@ -176,6 +164,7 @@
 | 
				
			||||||
			reg = <0>;
 | 
								reg = <0>;
 | 
				
			||||||
			clocks = <&clks IMX5_CLK_DUMMY>;
 | 
								clocks = <&clks IMX5_CLK_DUMMY>;
 | 
				
			||||||
			clock-names = "main_clk";
 | 
								clock-names = "main_clk";
 | 
				
			||||||
 | 
								reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -419,7 +408,7 @@
 | 
				
			||||||
&usbh1 {
 | 
					&usbh1 {
 | 
				
			||||||
	pinctrl-names = "default";
 | 
						pinctrl-names = "default";
 | 
				
			||||||
	pinctrl-0 = <&pinctrl_usbh1>;
 | 
						pinctrl-0 = <&pinctrl_usbh1>;
 | 
				
			||||||
	vbus-supply = <®_usbh1_vbus>;
 | 
						vbus-supply = <®_hub_reset>;
 | 
				
			||||||
	fsl,usbphy = <&usbh1phy>;
 | 
						fsl,usbphy = <&usbh1phy>;
 | 
				
			||||||
	phy_type = "ulpi";
 | 
						phy_type = "ulpi";
 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
| 
						 | 
					@ -429,7 +418,6 @@
 | 
				
			||||||
	dr_mode = "otg";
 | 
						dr_mode = "otg";
 | 
				
			||||||
	disable-over-current;
 | 
						disable-over-current;
 | 
				
			||||||
	phy_type = "utmi_wide";
 | 
						phy_type = "utmi_wide";
 | 
				
			||||||
	vbus-supply = <®_usbotg_vbus>;
 | 
					 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,8 +335,8 @@
 | 
				
			||||||
			vpu: vpu@02040000 {
 | 
								vpu: vpu@02040000 {
 | 
				
			||||||
				compatible = "cnm,coda960";
 | 
									compatible = "cnm,coda960";
 | 
				
			||||||
				reg = <0x02040000 0x3c000>;
 | 
									reg = <0x02040000 0x3c000>;
 | 
				
			||||||
				interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
 | 
									interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>,
 | 
				
			||||||
				             <0 12 IRQ_TYPE_LEVEL_HIGH>;
 | 
										     <0 3 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
				interrupt-names = "bit", "jpeg";
 | 
									interrupt-names = "bit", "jpeg";
 | 
				
			||||||
				clocks = <&clks IMX6QDL_CLK_VPU_AXI>,
 | 
									clocks = <&clks IMX6QDL_CLK_VPU_AXI>,
 | 
				
			||||||
					 <&clks IMX6QDL_CLK_MMDC_CH0_AXI>,
 | 
										 <&clks IMX6QDL_CLK_MMDC_CH0_AXI>,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,13 +159,28 @@
 | 
				
			||||||
	pinctrl-0 = <&pinctrl_enet1>;
 | 
						pinctrl-0 = <&pinctrl_enet1>;
 | 
				
			||||||
	phy-supply = <®_enet_3v3>;
 | 
						phy-supply = <®_enet_3v3>;
 | 
				
			||||||
	phy-mode = "rgmii";
 | 
						phy-mode = "rgmii";
 | 
				
			||||||
 | 
						phy-handle = <ðphy1>;
 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mdio {
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <0>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ethphy1: ethernet-phy@0 {
 | 
				
			||||||
 | 
								reg = <0>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ethphy2: ethernet-phy@1 {
 | 
				
			||||||
 | 
								reg = <1>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
&fec2 {
 | 
					&fec2 {
 | 
				
			||||||
	pinctrl-names = "default";
 | 
						pinctrl-names = "default";
 | 
				
			||||||
	pinctrl-0 = <&pinctrl_enet2>;
 | 
						pinctrl-0 = <&pinctrl_enet2>;
 | 
				
			||||||
	phy-mode = "rgmii";
 | 
						phy-mode = "rgmii";
 | 
				
			||||||
 | 
						phy-handle = <ðphy2>;
 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,7 @@
 | 
				
			||||||
		scfg: scfg@1570000 {
 | 
							scfg: scfg@1570000 {
 | 
				
			||||||
			compatible = "fsl,ls1021a-scfg", "syscon";
 | 
								compatible = "fsl,ls1021a-scfg", "syscon";
 | 
				
			||||||
			reg = <0x0 0x1570000 0x0 0x10000>;
 | 
								reg = <0x0 0x1570000 0x0 0x10000>;
 | 
				
			||||||
 | 
								big-endian;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		clockgen: clocking@1ee1000 {
 | 
							clockgen: clocking@1ee1000 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -700,11 +700,9 @@
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Ethernet is on some early development boards and qemu */
 | 
				
			||||||
	ethernet@gpmc {
 | 
						ethernet@gpmc {
 | 
				
			||||||
		compatible = "smsc,lan91c94";
 | 
							compatible = "smsc,lan91c94";
 | 
				
			||||||
 | 
					 | 
				
			||||||
		status = "disabled";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		interrupt-parent = <&gpio2>;
 | 
							interrupt-parent = <&gpio2>;
 | 
				
			||||||
		interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;	/* gpio54 */
 | 
							interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;	/* gpio54 */
 | 
				
			||||||
		reg = <1 0x300 0xf>;		/* 16 byte IO range at offset 0x300 */
 | 
							reg = <1 0x300 0xf>;		/* 16 byte IO range at offset 0x300 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,6 +155,15 @@
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
&pinctrl {
 | 
					&pinctrl {
 | 
				
			||||||
 | 
						pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
 | 
				
			||||||
 | 
							drive-strength = <8>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
 | 
				
			||||||
 | 
							bias-pull-up;
 | 
				
			||||||
 | 
							drive-strength = <8>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backlight {
 | 
						backlight {
 | 
				
			||||||
		bl_en: bl-en {
 | 
							bl_en: bl-en {
 | 
				
			||||||
			rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
 | 
								rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
 | 
				
			||||||
| 
						 | 
					@ -173,6 +182,27 @@
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sdmmc {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Default drive strength isn't enough to achieve even
 | 
				
			||||||
 | 
							 * high-speed mode on EVB board so bump up to 8ma.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							sdmmc_bus4: sdmmc-bus4 {
 | 
				
			||||||
 | 
								rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
 | 
				
			||||||
 | 
										<6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
 | 
				
			||||||
 | 
										<6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
 | 
				
			||||||
 | 
										<6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sdmmc_clk: sdmmc-clk {
 | 
				
			||||||
 | 
								rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sdmmc_cmd: sdmmc-cmd {
 | 
				
			||||||
 | 
								rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	usb {
 | 
						usb {
 | 
				
			||||||
		host_vbus_drv: host-vbus-drv {
 | 
							host_vbus_drv: host-vbus-drv {
 | 
				
			||||||
			rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
 | 
								rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,7 +176,7 @@
 | 
				
			||||||
			"Headphone Jack", "HPOUTR",
 | 
								"Headphone Jack", "HPOUTR",
 | 
				
			||||||
			"IN2L", "Line In Jack",
 | 
								"IN2L", "Line In Jack",
 | 
				
			||||||
			"IN2R", "Line In Jack",
 | 
								"IN2R", "Line In Jack",
 | 
				
			||||||
			"MICBIAS", "IN1L",
 | 
								"Mic", "MICBIAS",
 | 
				
			||||||
			"IN1L", "Mic";
 | 
								"IN1L", "Mic";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		atmel,ssc-controller = <&ssc0>;
 | 
							atmel,ssc-controller = <&ssc0>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1008,7 +1008,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			pit: timer@fc068630 {
 | 
								pit: timer@fc068630 {
 | 
				
			||||||
				compatible = "atmel,at91sam9260-pit";
 | 
									compatible = "atmel,at91sam9260-pit";
 | 
				
			||||||
				reg = <0xfc068630 0xf>;
 | 
									reg = <0xfc068630 0x10>;
 | 
				
			||||||
				interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
 | 
									interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
 | 
				
			||||||
				clocks = <&h32ck>;
 | 
									clocks = <&h32ck>;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,11 +25,11 @@
 | 
				
			||||||
		stmpe2401_1 {
 | 
							stmpe2401_1 {
 | 
				
			||||||
			stmpe2401_1_nhk_mode: stmpe2401_1_nhk {
 | 
								stmpe2401_1_nhk_mode: stmpe2401_1_nhk {
 | 
				
			||||||
				nhk_cfg1 {
 | 
									nhk_cfg1 {
 | 
				
			||||||
					ste,pins = "GPIO76_B20"; // IRQ line
 | 
										pins = "GPIO76_B20"; // IRQ line
 | 
				
			||||||
					ste,input = <0>;
 | 
										ste,input = <0>;
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				nhk_cfg2 {
 | 
									nhk_cfg2 {
 | 
				
			||||||
					ste,pins = "GPIO77_B8"; // reset line
 | 
										pins = "GPIO77_B8"; // reset line
 | 
				
			||||||
					ste,output = <1>;
 | 
										ste,output = <1>;
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
| 
						 | 
					@ -37,11 +37,11 @@
 | 
				
			||||||
		stmpe2401_2 {
 | 
							stmpe2401_2 {
 | 
				
			||||||
			stmpe2401_2_nhk_mode: stmpe2401_2_nhk {
 | 
								stmpe2401_2_nhk_mode: stmpe2401_2_nhk {
 | 
				
			||||||
				nhk_cfg1 {
 | 
									nhk_cfg1 {
 | 
				
			||||||
					ste,pins = "GPIO78_A8"; // IRQ line
 | 
										pins = "GPIO78_A8"; // IRQ line
 | 
				
			||||||
					ste,input = <0>;
 | 
										ste,input = <0>;
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				nhk_cfg2 {
 | 
									nhk_cfg2 {
 | 
				
			||||||
					ste,pins = "GPIO79_C9"; // reset line
 | 
										pins = "GPIO79_C9"; // reset line
 | 
				
			||||||
					ste,output = <1>;
 | 
										ste,output = <1>;
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,13 +129,28 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
&fec0 {
 | 
					&fec0 {
 | 
				
			||||||
	phy-mode = "rmii";
 | 
						phy-mode = "rmii";
 | 
				
			||||||
 | 
						phy-handle = <ðphy0>;
 | 
				
			||||||
	pinctrl-names = "default";
 | 
						pinctrl-names = "default";
 | 
				
			||||||
	pinctrl-0 = <&pinctrl_fec0>;
 | 
						pinctrl-0 = <&pinctrl_fec0>;
 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mdio {
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <0>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ethphy0: ethernet-phy@0 {
 | 
				
			||||||
 | 
								reg = <0>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ethphy1: ethernet-phy@1 {
 | 
				
			||||||
 | 
								reg = <1>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
&fec1 {
 | 
					&fec1 {
 | 
				
			||||||
	phy-mode = "rmii";
 | 
						phy-mode = "rmii";
 | 
				
			||||||
 | 
						phy-handle = <ðphy1>;
 | 
				
			||||||
	pinctrl-names = "default";
 | 
						pinctrl-names = "default";
 | 
				
			||||||
	pinctrl-0 = <&pinctrl_fec1>;
 | 
						pinctrl-0 = <&pinctrl_fec1>;
 | 
				
			||||||
	status = "okay";
 | 
						status = "okay";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +84,8 @@ CONFIG_DEBUG_GPIO=y
 | 
				
			||||||
CONFIG_POWER_SUPPLY=y
 | 
					CONFIG_POWER_SUPPLY=y
 | 
				
			||||||
CONFIG_BATTERY_SBS=y
 | 
					CONFIG_BATTERY_SBS=y
 | 
				
			||||||
CONFIG_CHARGER_TPS65090=y
 | 
					CONFIG_CHARGER_TPS65090=y
 | 
				
			||||||
# CONFIG_HWMON is not set
 | 
					CONFIG_HWMON=y
 | 
				
			||||||
 | 
					CONFIG_SENSORS_LM90=y
 | 
				
			||||||
CONFIG_THERMAL=y
 | 
					CONFIG_THERMAL=y
 | 
				
			||||||
CONFIG_EXYNOS_THERMAL=y
 | 
					CONFIG_EXYNOS_THERMAL=y
 | 
				
			||||||
CONFIG_EXYNOS_THERMAL_CORE=y
 | 
					CONFIG_EXYNOS_THERMAL_CORE=y
 | 
				
			||||||
| 
						 | 
					@ -109,11 +110,26 @@ CONFIG_REGULATOR_S2MPA01=y
 | 
				
			||||||
CONFIG_REGULATOR_S2MPS11=y
 | 
					CONFIG_REGULATOR_S2MPS11=y
 | 
				
			||||||
CONFIG_REGULATOR_S5M8767=y
 | 
					CONFIG_REGULATOR_S5M8767=y
 | 
				
			||||||
CONFIG_REGULATOR_TPS65090=y
 | 
					CONFIG_REGULATOR_TPS65090=y
 | 
				
			||||||
 | 
					CONFIG_DRM=y
 | 
				
			||||||
 | 
					CONFIG_DRM_BRIDGE=y
 | 
				
			||||||
 | 
					CONFIG_DRM_PTN3460=y
 | 
				
			||||||
 | 
					CONFIG_DRM_PS8622=y
 | 
				
			||||||
 | 
					CONFIG_DRM_EXYNOS=y
 | 
				
			||||||
 | 
					CONFIG_DRM_EXYNOS_FIMD=y
 | 
				
			||||||
 | 
					CONFIG_DRM_EXYNOS_DP=y
 | 
				
			||||||
 | 
					CONFIG_DRM_PANEL=y
 | 
				
			||||||
 | 
					CONFIG_DRM_PANEL_SIMPLE=y
 | 
				
			||||||
CONFIG_FB=y
 | 
					CONFIG_FB=y
 | 
				
			||||||
CONFIG_FB_MODE_HELPERS=y
 | 
					CONFIG_FB_MODE_HELPERS=y
 | 
				
			||||||
CONFIG_FB_SIMPLE=y
 | 
					CONFIG_FB_SIMPLE=y
 | 
				
			||||||
CONFIG_EXYNOS_VIDEO=y
 | 
					CONFIG_EXYNOS_VIDEO=y
 | 
				
			||||||
CONFIG_EXYNOS_MIPI_DSI=y
 | 
					CONFIG_EXYNOS_MIPI_DSI=y
 | 
				
			||||||
 | 
					CONFIG_BACKLIGHT_LCD_SUPPORT=y
 | 
				
			||||||
 | 
					CONFIG_LCD_CLASS_DEVICE=y
 | 
				
			||||||
 | 
					CONFIG_LCD_PLATFORM=y
 | 
				
			||||||
 | 
					CONFIG_BACKLIGHT_CLASS_DEVICE=y
 | 
				
			||||||
 | 
					CONFIG_BACKLIGHT_GENERIC=y
 | 
				
			||||||
 | 
					CONFIG_BACKLIGHT_PWM=y
 | 
				
			||||||
CONFIG_FRAMEBUFFER_CONSOLE=y
 | 
					CONFIG_FRAMEBUFFER_CONSOLE=y
 | 
				
			||||||
CONFIG_FONTS=y
 | 
					CONFIG_FONTS=y
 | 
				
			||||||
CONFIG_FONT_7x14=y
 | 
					CONFIG_FONT_7x14=y
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 | 
				
			||||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 | 
					CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 | 
				
			||||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
 | 
					CONFIG_CPU_FREQ_GOV_USERSPACE=y
 | 
				
			||||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 | 
					CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 | 
				
			||||||
CONFIG_GENERIC_CPUFREQ_CPU0=y
 | 
					CONFIG_CPUFREQ_DT=y
 | 
				
			||||||
# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
 | 
					# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
 | 
				
			||||||
CONFIG_CPU_IDLE=y
 | 
					CONFIG_CPU_IDLE=y
 | 
				
			||||||
CONFIG_BINFMT_MISC=y
 | 
					CONFIG_BINFMT_MISC=y
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
#include <linux/of_platform.h>
 | 
					#include <linux/of_platform.h>
 | 
				
			||||||
#include <linux/phy.h>
 | 
					#include <linux/phy.h>
 | 
				
			||||||
#include <linux/clk-provider.h>
 | 
					#include <linux/clk-provider.h>
 | 
				
			||||||
 | 
					#include <linux/phy.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/setup.h>
 | 
					#include <asm/setup.h>
 | 
				
			||||||
#include <asm/irq.h>
 | 
					#include <asm/irq.h>
 | 
				
			||||||
| 
						 | 
					@ -26,8 +27,25 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "generic.h"
 | 
					#include "generic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ksz8081_phy_fixup(struct phy_device *phy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value = phy_read(phy, 0x16);
 | 
				
			||||||
 | 
						value &= ~0x20;
 | 
				
			||||||
 | 
						phy_write(phy, 0x16, value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __init sama5_dt_device_init(void)
 | 
					static void __init sama5_dt_device_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (of_machine_is_compatible("atmel,sama5d4ek") &&
 | 
				
			||||||
 | 
						   IS_ENABLED(CONFIG_PHYLIB)) {
 | 
				
			||||||
 | 
							phy_register_fixup_for_id("fc028000.etherne:00",
 | 
				
			||||||
 | 
											ksz8081_phy_fixup);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 | 
						of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 | 
				
			||||||
		post_div_table[1].div = 1;
 | 
							post_div_table[1].div = 1;
 | 
				
			||||||
		post_div_table[2].div = 1;
 | 
							post_div_table[2].div = 1;
 | 
				
			||||||
		video_div_table[1].div = 1;
 | 
							video_div_table[1].div = 1;
 | 
				
			||||||
		video_div_table[2].div = 1;
 | 
							video_div_table[3].div = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
 | 
						clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -558,6 +558,9 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 | 
				
			||||||
	clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
 | 
						clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
 | 
				
			||||||
	clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
 | 
						clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
 | 
				
			||||||
 | 
						clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set initial power mode */
 | 
						/* Set initial power mode */
 | 
				
			||||||
	imx6q_set_lpm(WAIT_CLOCKED);
 | 
						imx6q_set_lpm(WAIT_CLOCKED);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,6 +77,24 @@ MACHINE_END
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_ARCH_OMAP3
 | 
					#ifdef CONFIG_ARCH_OMAP3
 | 
				
			||||||
 | 
					/* Some boards need board name for legacy userspace in /proc/cpuinfo */
 | 
				
			||||||
 | 
					static const char *const n900_boards_compat[] __initconst = {
 | 
				
			||||||
 | 
						"nokia,omap3-n900",
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board")
 | 
				
			||||||
 | 
						.reserve	= omap_reserve,
 | 
				
			||||||
 | 
						.map_io		= omap3_map_io,
 | 
				
			||||||
 | 
						.init_early	= omap3430_init_early,
 | 
				
			||||||
 | 
						.init_machine	= omap_generic_init,
 | 
				
			||||||
 | 
						.init_late	= omap3_init_late,
 | 
				
			||||||
 | 
						.init_time	= omap3_sync32k_timer_init,
 | 
				
			||||||
 | 
						.dt_compat	= n900_boards_compat,
 | 
				
			||||||
 | 
						.restart	= omap3xxx_restart,
 | 
				
			||||||
 | 
					MACHINE_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Generic omap3 boards, most boards can use these */
 | 
				
			||||||
static const char *const omap3_boards_compat[] __initconst = {
 | 
					static const char *const omap3_boards_compat[] __initconst = {
 | 
				
			||||||
	"ti,omap3430",
 | 
						"ti,omap3430",
 | 
				
			||||||
	"ti,omap3",
 | 
						"ti,omap3",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -249,6 +249,7 @@ extern void omap4_cpu_die(unsigned int cpu);
 | 
				
			||||||
extern struct smp_operations omap4_smp_ops;
 | 
					extern struct smp_operations omap4_smp_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void omap5_secondary_startup(void);
 | 
					extern void omap5_secondary_startup(void);
 | 
				
			||||||
 | 
					extern void omap5_secondary_hyp_startup(void);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(CONFIG_SMP) && defined(CONFIG_PM)
 | 
					#if defined(CONFIG_SMP) && defined(CONFIG_PM)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -286,6 +286,10 @@
 | 
				
			||||||
#define OMAP5XXX_CONTROL_STATUS                0x134
 | 
					#define OMAP5XXX_CONTROL_STATUS                0x134
 | 
				
			||||||
#define OMAP5_DEVICETYPE_MASK          (0x7 << 6)
 | 
					#define OMAP5_DEVICETYPE_MASK          (0x7 << 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DRA7XX CONTROL CORE BOOTSTRAP */
 | 
				
			||||||
 | 
					#define DRA7_CTRL_CORE_BOOTSTRAP	0x6c4
 | 
				
			||||||
 | 
					#define DRA7_SPEEDSELECT_MASK		(0x3 << 8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * REVISIT: This list of registers is not comprehensive - there are more
 | 
					 * REVISIT: This list of registers is not comprehensive - there are more
 | 
				
			||||||
 * that should be added.
 | 
					 * that should be added.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Physical address needed since MMU not enabled yet on secondary core */
 | 
					/* Physical address needed since MMU not enabled yet on secondary core */
 | 
				
			||||||
#define AUX_CORE_BOOT0_PA			0x48281800
 | 
					#define AUX_CORE_BOOT0_PA			0x48281800
 | 
				
			||||||
 | 
					#define API_HYP_ENTRY				0x102
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * OMAP5 specific entry point for secondary CPU to jump from ROM
 | 
					 * OMAP5 specific entry point for secondary CPU to jump from ROM
 | 
				
			||||||
| 
						 | 
					@ -40,6 +41,26 @@ wait:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
 | 
				
			||||||
	bne	wait
 | 
						bne	wait
 | 
				
			||||||
	b	secondary_startup
 | 
						b	secondary_startup
 | 
				
			||||||
ENDPROC(omap5_secondary_startup)
 | 
					ENDPROC(omap5_secondary_startup)
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Same as omap5_secondary_startup except we call into the ROM to
 | 
				
			||||||
 | 
					 * enable HYP mode first.  This is called instead of
 | 
				
			||||||
 | 
					 * omap5_secondary_startup if the primary CPU was put into HYP mode by
 | 
				
			||||||
 | 
					 * the boot loader.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					ENTRY(omap5_secondary_hyp_startup)
 | 
				
			||||||
 | 
					wait_2:	ldr	r2, =AUX_CORE_BOOT0_PA	@ read from AuxCoreBoot0
 | 
				
			||||||
 | 
						ldr	r0, [r2]
 | 
				
			||||||
 | 
						mov	r0, r0, lsr #5
 | 
				
			||||||
 | 
						mrc	p15, 0, r4, c0, c0, 5
 | 
				
			||||||
 | 
						and	r4, r4, #0x0f
 | 
				
			||||||
 | 
						cmp	r0, r4
 | 
				
			||||||
 | 
						bne	wait_2
 | 
				
			||||||
 | 
						ldr	r12, =API_HYP_ENTRY
 | 
				
			||||||
 | 
						adr	r0, hyp_boot
 | 
				
			||||||
 | 
						smc	#0
 | 
				
			||||||
 | 
					hyp_boot:
 | 
				
			||||||
 | 
						b	secondary_startup
 | 
				
			||||||
 | 
					ENDPROC(omap5_secondary_hyp_startup)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * OMAP4 specific entry point for secondary CPU to jump from ROM
 | 
					 * OMAP4 specific entry point for secondary CPU to jump from ROM
 | 
				
			||||||
 * code.  This routine also provides a holding flag into which
 | 
					 * code.  This routine also provides a holding flag into which
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
#include <linux/irqchip/arm-gic.h>
 | 
					#include <linux/irqchip/arm-gic.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/smp_scu.h>
 | 
					#include <asm/smp_scu.h>
 | 
				
			||||||
 | 
					#include <asm/virt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "omap-secure.h"
 | 
					#include "omap-secure.h"
 | 
				
			||||||
#include "omap-wakeupgen.h"
 | 
					#include "omap-wakeupgen.h"
 | 
				
			||||||
| 
						 | 
					@ -226,6 +227,14 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (omap_secure_apis_support())
 | 
						if (omap_secure_apis_support())
 | 
				
			||||||
		omap_auxcoreboot_addr(virt_to_phys(startup_addr));
 | 
							omap_auxcoreboot_addr(virt_to_phys(startup_addr));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If the boot CPU is in HYP mode then start secondary
 | 
				
			||||||
 | 
							 * CPU in HYP mode as well.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
 | 
				
			||||||
 | 
								writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup),
 | 
				
			||||||
 | 
									       base + OMAP_AUX_CORE_BOOT_1);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			writel_relaxed(virt_to_phys(omap5_secondary_startup),
 | 
								writel_relaxed(virt_to_phys(omap5_secondary_startup),
 | 
				
			||||||
				       base + OMAP_AUX_CORE_BOOT_1);
 | 
									       base + OMAP_AUX_CORE_BOOT_1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "soc.h"
 | 
					#include "soc.h"
 | 
				
			||||||
#include "common.h"
 | 
					#include "common.h"
 | 
				
			||||||
 | 
					#include "control.h"
 | 
				
			||||||
#include "powerdomain.h"
 | 
					#include "powerdomain.h"
 | 
				
			||||||
#include "omap-secure.h"
 | 
					#include "omap-secure.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -496,7 +497,8 @@ static void __init realtime_counter_init(void)
 | 
				
			||||||
	void __iomem *base;
 | 
						void __iomem *base;
 | 
				
			||||||
	static struct clk *sys_clk;
 | 
						static struct clk *sys_clk;
 | 
				
			||||||
	unsigned long rate;
 | 
						unsigned long rate;
 | 
				
			||||||
	unsigned int reg, num, den;
 | 
						unsigned int reg;
 | 
				
			||||||
 | 
						unsigned long long num, den;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
 | 
						base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
 | 
				
			||||||
	if (!base) {
 | 
						if (!base) {
 | 
				
			||||||
| 
						 | 
					@ -511,13 +513,42 @@ static void __init realtime_counter_init(void)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rate = clk_get_rate(sys_clk);
 | 
						rate = clk_get_rate(sys_clk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (soc_is_dra7xx()) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Errata i856 says the 32.768KHz crystal does not start at
 | 
				
			||||||
 | 
							 * power on, so the CPU falls back to an emulated 32KHz clock
 | 
				
			||||||
 | 
							 * based on sysclk / 610 instead. This causes the master counter
 | 
				
			||||||
 | 
							 * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2
 | 
				
			||||||
 | 
							 * (OR sysclk * 75 / 244)
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * This affects at least the DRA7/AM572x 1.0, 1.1 revisions.
 | 
				
			||||||
 | 
							 * Of course any board built without a populated 32.768KHz
 | 
				
			||||||
 | 
							 * crystal would also need this fix even if the CPU is fixed
 | 
				
			||||||
 | 
							 * later.
 | 
				
			||||||
 | 
							 *
 | 
				
			||||||
 | 
							 * Either case can be detected by using the two speedselect bits
 | 
				
			||||||
 | 
							 * If they are not 0, then the 32.768KHz clock driving the
 | 
				
			||||||
 | 
							 * coarse counter that corrects the fine counter every time it
 | 
				
			||||||
 | 
							 * ticks is actually rate/610 rather than 32.768KHz and we
 | 
				
			||||||
 | 
							 * should compensate to avoid the 570ppm (at 20MHz, much worse
 | 
				
			||||||
 | 
							 * at other rates) too fast system time.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP);
 | 
				
			||||||
 | 
							if (reg & DRA7_SPEEDSELECT_MASK) {
 | 
				
			||||||
 | 
								num = 75;
 | 
				
			||||||
 | 
								den = 244;
 | 
				
			||||||
 | 
								goto sysclk1_based;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Numerator/denumerator values refer TRM Realtime Counter section */
 | 
						/* Numerator/denumerator values refer TRM Realtime Counter section */
 | 
				
			||||||
	switch (rate) {
 | 
						switch (rate) {
 | 
				
			||||||
	case 1200000:
 | 
						case 12000000:
 | 
				
			||||||
		num = 64;
 | 
							num = 64;
 | 
				
			||||||
		den = 125;
 | 
							den = 125;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 1300000:
 | 
						case 13000000:
 | 
				
			||||||
		num = 768;
 | 
							num = 768;
 | 
				
			||||||
		den = 1625;
 | 
							den = 1625;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -529,11 +560,11 @@ static void __init realtime_counter_init(void)
 | 
				
			||||||
		num = 192;
 | 
							num = 192;
 | 
				
			||||||
		den = 625;
 | 
							den = 625;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 2600000:
 | 
						case 26000000:
 | 
				
			||||||
		num = 384;
 | 
							num = 384;
 | 
				
			||||||
		den = 1625;
 | 
							den = 1625;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 2700000:
 | 
						case 27000000:
 | 
				
			||||||
		num = 256;
 | 
							num = 256;
 | 
				
			||||||
		den = 1125;
 | 
							den = 1125;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -545,6 +576,7 @@ static void __init realtime_counter_init(void)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sysclk1_based:
 | 
				
			||||||
	/* Program numerator and denumerator registers */
 | 
						/* Program numerator and denumerator registers */
 | 
				
			||||||
	reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) &
 | 
						reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) &
 | 
				
			||||||
			NUMERATOR_DENUMERATOR_MASK;
 | 
								NUMERATOR_DENUMERATOR_MASK;
 | 
				
			||||||
| 
						 | 
					@ -556,7 +588,7 @@ static void __init realtime_counter_init(void)
 | 
				
			||||||
	reg |= den;
 | 
						reg |= den;
 | 
				
			||||||
	writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
 | 
						writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	arch_timer_freq = (rate / den) * num;
 | 
						arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den);
 | 
				
			||||||
	set_cntfreq();
 | 
						set_cntfreq();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	iounmap(base);
 | 
						iounmap(base);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,11 +19,37 @@
 | 
				
			||||||
#include <linux/init.h>
 | 
					#include <linux/init.h>
 | 
				
			||||||
#include <linux/of_platform.h>
 | 
					#include <linux/of_platform.h>
 | 
				
			||||||
#include <linux/irqchip.h>
 | 
					#include <linux/irqchip.h>
 | 
				
			||||||
 | 
					#include <linux/clk-provider.h>
 | 
				
			||||||
 | 
					#include <linux/clocksource.h>
 | 
				
			||||||
 | 
					#include <linux/mfd/syscon.h>
 | 
				
			||||||
 | 
					#include <linux/regmap.h>
 | 
				
			||||||
#include <asm/mach/arch.h>
 | 
					#include <asm/mach/arch.h>
 | 
				
			||||||
#include <asm/mach/map.h>
 | 
					#include <asm/mach/map.h>
 | 
				
			||||||
#include <asm/hardware/cache-l2x0.h>
 | 
					#include <asm/hardware/cache-l2x0.h>
 | 
				
			||||||
#include "core.h"
 | 
					#include "core.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RK3288_GRF_SOC_CON0 0x244
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __init rockchip_timer_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (of_machine_is_compatible("rockchip,rk3288")) {
 | 
				
			||||||
 | 
							struct regmap *grf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Disable auto jtag/sdmmc switching that causes issues
 | 
				
			||||||
 | 
							 * with the mmc controllers making them unreliable
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							grf = syscon_regmap_lookup_by_compatible("rockchip,rk3288-grf");
 | 
				
			||||||
 | 
							if (!IS_ERR(grf))
 | 
				
			||||||
 | 
								regmap_write(grf, RK3288_GRF_SOC_CON0, 0x10000000);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								pr_err("rockchip: could not get grf syscon\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						of_clk_init(NULL);
 | 
				
			||||||
 | 
						clocksource_of_init();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __init rockchip_dt_init(void)
 | 
					static void __init rockchip_dt_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 | 
						of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 | 
				
			||||||
| 
						 | 
					@ -42,6 +68,7 @@ static const char * const rockchip_board_dt_compat[] = {
 | 
				
			||||||
DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
 | 
					DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
 | 
				
			||||||
	.l2c_aux_val	= 0,
 | 
						.l2c_aux_val	= 0,
 | 
				
			||||||
	.l2c_aux_mask	= ~0,
 | 
						.l2c_aux_mask	= ~0,
 | 
				
			||||||
 | 
						.init_time	= rockchip_timer_init,
 | 
				
			||||||
	.dt_compat	= rockchip_board_dt_compat,
 | 
						.dt_compat	= rockchip_board_dt_compat,
 | 
				
			||||||
	.init_machine	= rockchip_dt_init,
 | 
						.init_machine	= rockchip_dt_init,
 | 
				
			||||||
MACHINE_END
 | 
					MACHINE_END
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -800,7 +800,14 @@ void __init r8a7740_init_irq_of(void)
 | 
				
			||||||
	void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10);
 | 
						void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10);
 | 
				
			||||||
	void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4);
 | 
						void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
 | 
				
			||||||
 | 
						void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000);
 | 
				
			||||||
 | 
						void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gic_init(0, 29, gic_dist_base, gic_cpu_base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	irqchip_init();
 | 
						irqchip_init();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* route signals to GIC */
 | 
						/* route signals to GIC */
 | 
				
			||||||
	iowrite32(0x0, pfc_inta_ctrl);
 | 
						iowrite32(0x0, pfc_inta_ctrl);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -595,6 +595,7 @@ static struct platform_device ipmmu_device = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct renesas_intc_irqpin_config irqpin0_platform_data = {
 | 
					static struct renesas_intc_irqpin_config irqpin0_platform_data = {
 | 
				
			||||||
	.irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
 | 
						.irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
 | 
				
			||||||
 | 
						.control_parent = true,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct resource irqpin0_resources[] = {
 | 
					static struct resource irqpin0_resources[] = {
 | 
				
			||||||
| 
						 | 
					@ -656,6 +657,7 @@ static struct platform_device irqpin1_device = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct renesas_intc_irqpin_config irqpin2_platform_data = {
 | 
					static struct renesas_intc_irqpin_config irqpin2_platform_data = {
 | 
				
			||||||
	.irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
 | 
						.irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
 | 
				
			||||||
 | 
						.control_parent = true,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct resource irqpin2_resources[] = {
 | 
					static struct resource irqpin2_resources[] = {
 | 
				
			||||||
| 
						 | 
					@ -686,6 +688,7 @@ static struct platform_device irqpin2_device = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct renesas_intc_irqpin_config irqpin3_platform_data = {
 | 
					static struct renesas_intc_irqpin_config irqpin3_platform_data = {
 | 
				
			||||||
	.irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
 | 
						.irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
 | 
				
			||||||
 | 
						.control_parent = true,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct resource irqpin3_resources[] = {
 | 
					static struct resource irqpin3_resources[] = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,8 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 | 
				
			||||||
static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 | 
					static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
 | 
						vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
 | 
				
			||||||
 | 
						if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
 | 
				
			||||||
 | 
							vcpu->arch.hcr_el2 &= ~HCR_RW;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
 | 
					static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@
 | 
				
			||||||
#define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 | 
					#define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 | 
				
			||||||
#define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 | 
					#define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define __NR_compat_syscalls		387
 | 
					#define __NR_compat_syscalls		388
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define __ARCH_WANT_SYS_CLONE
 | 
					#define __ARCH_WANT_SYS_CLONE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -795,3 +795,5 @@ __SYSCALL(__NR_getrandom, sys_getrandom)
 | 
				
			||||||
__SYSCALL(__NR_memfd_create, sys_memfd_create)
 | 
					__SYSCALL(__NR_memfd_create, sys_memfd_create)
 | 
				
			||||||
#define __NR_bpf 386
 | 
					#define __NR_bpf 386
 | 
				
			||||||
__SYSCALL(__NR_bpf, sys_bpf)
 | 
					__SYSCALL(__NR_bpf, sys_bpf)
 | 
				
			||||||
 | 
					#define __NR_execveat 387
 | 
				
			||||||
 | 
					__SYSCALL(__NR_execveat, compat_sys_execveat)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1014,6 +1014,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa)
 | 
				
			||||||
	 * Instead, we invalidate Stage-2 for this IPA, and the
 | 
						 * Instead, we invalidate Stage-2 for this IPA, and the
 | 
				
			||||||
	 * whole of Stage-1. Weep...
 | 
						 * whole of Stage-1. Weep...
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
						lsr	x1, x1, #12
 | 
				
			||||||
	tlbi	ipas2e1is, x1
 | 
						tlbi	ipas2e1is, x1
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We have to ensure completion of the invalidation at Stage-2,
 | 
						 * We have to ensure completion of the invalidation at Stage-2,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 | 
				
			||||||
			if (!cpu_has_32bit_el1())
 | 
								if (!cpu_has_32bit_el1())
 | 
				
			||||||
				return -EINVAL;
 | 
									return -EINVAL;
 | 
				
			||||||
			cpu_reset = &default_regs_reset32;
 | 
								cpu_reset = &default_regs_reset32;
 | 
				
			||||||
			vcpu->arch.hcr_el2 &= ~HCR_RW;
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			cpu_reset = &default_regs_reset;
 | 
								cpu_reset = &default_regs_reset;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,15 +335,9 @@ static int keep_initrd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void free_initrd_mem(unsigned long start, unsigned long end)
 | 
					void free_initrd_mem(unsigned long start, unsigned long end)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!keep_initrd) {
 | 
						if (!keep_initrd)
 | 
				
			||||||
		if (start == initrd_start)
 | 
					 | 
				
			||||||
			start = round_down(start, PAGE_SIZE);
 | 
					 | 
				
			||||||
		if (end == initrd_end)
 | 
					 | 
				
			||||||
			end = round_up(end, PAGE_SIZE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		free_reserved_area((void *)start, (void *)end, 0, "initrd");
 | 
							free_reserved_area((void *)start, (void *)end, 0, "initrd");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init keepinitrd_setup(char *__unused)
 | 
					static int __init keepinitrd_setup(char *__unused)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
#include <uapi/asm/unistd.h>
 | 
					#include <uapi/asm/unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NR_syscalls		355
 | 
					#define NR_syscalls		356
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define __ARCH_WANT_OLD_READDIR
 | 
					#define __ARCH_WANT_OLD_READDIR
 | 
				
			||||||
#define __ARCH_WANT_OLD_STAT
 | 
					#define __ARCH_WANT_OLD_STAT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -360,5 +360,6 @@
 | 
				
			||||||
#define __NR_getrandom		352
 | 
					#define __NR_getrandom		352
 | 
				
			||||||
#define __NR_memfd_create	353
 | 
					#define __NR_memfd_create	353
 | 
				
			||||||
#define __NR_bpf		354
 | 
					#define __NR_bpf		354
 | 
				
			||||||
 | 
					#define __NR_execveat		355
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _UAPI_ASM_M68K_UNISTD_H_ */
 | 
					#endif /* _UAPI_ASM_M68K_UNISTD_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -375,4 +375,5 @@ ENTRY(sys_call_table)
 | 
				
			||||||
	.long sys_getrandom
 | 
						.long sys_getrandom
 | 
				
			||||||
	.long sys_memfd_create
 | 
						.long sys_memfd_create
 | 
				
			||||||
	.long sys_bpf
 | 
						.long sys_bpf
 | 
				
			||||||
 | 
						.long sys_execveat		/* 355 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,9 +23,9 @@
 | 
				
			||||||
#define THREAD_SIZE		(1 << THREAD_SHIFT)
 | 
					#define THREAD_SIZE		(1 << THREAD_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC64
 | 
					#ifdef CONFIG_PPC64
 | 
				
			||||||
#define CURRENT_THREAD_INFO(dest, sp)	clrrdi dest, sp, THREAD_SHIFT
 | 
					#define CURRENT_THREAD_INFO(dest, sp)	stringify_in_c(clrrdi dest, sp, THREAD_SHIFT)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define CURRENT_THREAD_INFO(dest, sp)	rlwinm dest, sp, 0, 0, 31-THREAD_SHIFT
 | 
					#define CURRENT_THREAD_INFO(dest, sp)	stringify_in_c(rlwinm dest, sp, 0, 0, 31-THREAD_SHIFT)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __ASSEMBLY__
 | 
					#ifndef __ASSEMBLY__
 | 
				
			||||||
| 
						 | 
					@ -71,12 +71,13 @@ struct thread_info {
 | 
				
			||||||
#define THREAD_SIZE_ORDER	(THREAD_SHIFT - PAGE_SHIFT)
 | 
					#define THREAD_SIZE_ORDER	(THREAD_SHIFT - PAGE_SHIFT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* how to get the thread information struct from C */
 | 
					/* how to get the thread information struct from C */
 | 
				
			||||||
register unsigned long __current_r1 asm("r1");
 | 
					 | 
				
			||||||
static inline struct thread_info *current_thread_info(void)
 | 
					static inline struct thread_info *current_thread_info(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* gcc4, at least, is smart enough to turn this into a single
 | 
						unsigned long val;
 | 
				
			||||||
	 * rlwinm for ppc32 and clrrdi for ppc64 */
 | 
					
 | 
				
			||||||
	return (struct thread_info *)(__current_r1 & ~(THREAD_SIZE-1));
 | 
						asm (CURRENT_THREAD_INFO(%0,1) : "=r" (val));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (struct thread_info *)val;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __ASSEMBLY__ */
 | 
					#endif /* __ASSEMBLY__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,6 @@ BEGIN_FTR_SECTION;						\
 | 
				
			||||||
	b	1f;						\
 | 
						b	1f;						\
 | 
				
			||||||
END_FTR_SECTION(0, 1);						\
 | 
					END_FTR_SECTION(0, 1);						\
 | 
				
			||||||
	ld	r12,opal_tracepoint_refcount@toc(r2);		\
 | 
						ld	r12,opal_tracepoint_refcount@toc(r2);		\
 | 
				
			||||||
	std	r12,32(r1);					\
 | 
					 | 
				
			||||||
	cmpdi	r12,0;						\
 | 
						cmpdi	r12,0;						\
 | 
				
			||||||
	bne-	LABEL;						\
 | 
						bne-	LABEL;						\
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -231,7 +231,7 @@ failed:
 | 
				
			||||||
struct dbfs_d2fc_hdr {
 | 
					struct dbfs_d2fc_hdr {
 | 
				
			||||||
	u64	len;		/* Length of d2fc buffer without header */
 | 
						u64	len;		/* Length of d2fc buffer without header */
 | 
				
			||||||
	u16	version;	/* Version of header */
 | 
						u16	version;	/* Version of header */
 | 
				
			||||||
	char	tod_ext[16];	/* TOD clock for d2fc */
 | 
						char	tod_ext[STORE_CLOCK_EXT_SIZE]; /* TOD clock for d2fc */
 | 
				
			||||||
	u64	count;		/* Number of VM guests in d2fc buffer */
 | 
						u64	count;		/* Number of VM guests in d2fc buffer */
 | 
				
			||||||
	char	reserved[30];
 | 
						char	reserved[30];
 | 
				
			||||||
} __attribute__ ((packed));
 | 
					} __attribute__ ((packed));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ static inline notrace void __arch_local_irq_ssm(unsigned long flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline notrace unsigned long arch_local_save_flags(void)
 | 
					static inline notrace unsigned long arch_local_save_flags(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return __arch_local_irq_stosm(0x00);
 | 
						return __arch_local_irq_stnsm(0xff);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline notrace unsigned long arch_local_irq_save(void)
 | 
					static inline notrace unsigned long arch_local_irq_save(void)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,19 +68,21 @@ static inline void local_tick_enable(unsigned long long comp)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CLOCK_TICK_RATE		1193180 /* Underlying HZ */
 | 
					#define CLOCK_TICK_RATE		1193180 /* Underlying HZ */
 | 
				
			||||||
 | 
					#define STORE_CLOCK_EXT_SIZE	16	/* stcke writes 16 bytes */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef unsigned long long cycles_t;
 | 
					typedef unsigned long long cycles_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void get_tod_clock_ext(char clk[16])
 | 
					static inline void get_tod_clock_ext(char *clk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	typedef struct { char _[sizeof(clk)]; } addrtype;
 | 
						typedef struct { char _[STORE_CLOCK_EXT_SIZE]; } addrtype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	asm volatile("stcke %0" : "=Q" (*(addrtype *) clk) : : "cc");
 | 
						asm volatile("stcke %0" : "=Q" (*(addrtype *) clk) : : "cc");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline unsigned long long get_tod_clock(void)
 | 
					static inline unsigned long long get_tod_clock(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned char clk[16];
 | 
						unsigned char clk[STORE_CLOCK_EXT_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	get_tod_clock_ext(clk);
 | 
						get_tod_clock_ext(clk);
 | 
				
			||||||
	return *((unsigned long long *)&clk[1]);
 | 
						return *((unsigned long long *)&clk[1]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -289,7 +289,8 @@
 | 
				
			||||||
#define __NR_bpf		351
 | 
					#define __NR_bpf		351
 | 
				
			||||||
#define __NR_s390_pci_mmio_write	352
 | 
					#define __NR_s390_pci_mmio_write	352
 | 
				
			||||||
#define __NR_s390_pci_mmio_read		353
 | 
					#define __NR_s390_pci_mmio_read		353
 | 
				
			||||||
#define NR_syscalls 354
 | 
					#define __NR_execveat		354
 | 
				
			||||||
 | 
					#define NR_syscalls 355
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
 * There are some system calls that are not present on 64 bit, some
 | 
					 * There are some system calls that are not present on 64 bit, some
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -362,3 +362,4 @@ SYSCALL(sys_memfd_create,sys_memfd_create,compat_sys_memfd_create) /* 350 */
 | 
				
			||||||
SYSCALL(sys_bpf,sys_bpf,compat_sys_bpf)
 | 
					SYSCALL(sys_bpf,sys_bpf,compat_sys_bpf)
 | 
				
			||||||
SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_write,compat_sys_s390_pci_mmio_write)
 | 
					SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_write,compat_sys_s390_pci_mmio_write)
 | 
				
			||||||
SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_read,compat_sys_s390_pci_mmio_read)
 | 
					SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_read,compat_sys_s390_pci_mmio_read)
 | 
				
			||||||
 | 
					SYSCALL(sys_execveat,sys_execveat,compat_sys_execveat)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,30 @@ bool arch_uprobe_xol_was_trapped(struct task_struct *tsk)
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int check_per_event(unsigned short cause, unsigned long control,
 | 
				
			||||||
 | 
								   struct pt_regs *regs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!(regs->psw.mask & PSW_MASK_PER))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						/* user space single step */
 | 
				
			||||||
 | 
						if (control == 0)
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						/* over indication for storage alteration */
 | 
				
			||||||
 | 
						if ((control & 0x20200000) && (cause & 0x2000))
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						if (cause & 0x8000) {
 | 
				
			||||||
 | 
							/* all branches */
 | 
				
			||||||
 | 
							if ((control & 0x80800000) == 0x80000000)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							/* branch into selected range */
 | 
				
			||||||
 | 
							if (((control & 0x80800000) == 0x80800000) &&
 | 
				
			||||||
 | 
							    regs->psw.addr >= current->thread.per_user.start &&
 | 
				
			||||||
 | 
							    regs->psw.addr <= current->thread.per_user.end)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 | 
					int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int fixup = probe_get_fixup_type(auprobe->insn);
 | 
						int fixup = probe_get_fixup_type(auprobe->insn);
 | 
				
			||||||
| 
						 | 
					@ -71,9 +95,13 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 | 
				
			||||||
		if (regs->psw.addr - utask->xol_vaddr == ilen)
 | 
							if (regs->psw.addr - utask->xol_vaddr == ilen)
 | 
				
			||||||
			regs->psw.addr = utask->vaddr + ilen;
 | 
								regs->psw.addr = utask->vaddr + ilen;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	/* If per tracing was active generate trap */
 | 
						if (check_per_event(current->thread.per_event.cause,
 | 
				
			||||||
	if (regs->psw.mask & PSW_MASK_PER)
 | 
								    current->thread.per_user.control, regs)) {
 | 
				
			||||||
		do_per_trap(regs);
 | 
							/* fix per address */
 | 
				
			||||||
 | 
							current->thread.per_event.address = utask->vaddr;
 | 
				
			||||||
 | 
							/* trigger per event */
 | 
				
			||||||
 | 
							set_pt_regs_flag(regs, PIF_PER_TRAP);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,6 +134,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 | 
				
			||||||
	clear_thread_flag(TIF_UPROBE_SINGLESTEP);
 | 
						clear_thread_flag(TIF_UPROBE_SINGLESTEP);
 | 
				
			||||||
	regs->int_code = auprobe->saved_int_code;
 | 
						regs->int_code = auprobe->saved_int_code;
 | 
				
			||||||
	regs->psw.addr = current->utask->vaddr;
 | 
						regs->psw.addr = current->utask->vaddr;
 | 
				
			||||||
 | 
						current->thread.per_event.address = current->utask->vaddr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline,
 | 
					unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline,
 | 
				
			||||||
| 
						 | 
					@ -146,17 +175,20 @@ static void adjust_psw_addr(psw_t *psw, unsigned long len)
 | 
				
			||||||
	__rc;						\
 | 
						__rc;						\
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define emu_store_ril(ptr, input)			\
 | 
					#define emu_store_ril(regs, ptr, input)			\
 | 
				
			||||||
({							\
 | 
					({							\
 | 
				
			||||||
	unsigned int mask = sizeof(*(ptr)) - 1;		\
 | 
						unsigned int mask = sizeof(*(ptr)) - 1;		\
 | 
				
			||||||
 | 
						__typeof__(ptr) __ptr = (ptr);			\
 | 
				
			||||||
	int __rc = 0;					\
 | 
						int __rc = 0;					\
 | 
				
			||||||
							\
 | 
												\
 | 
				
			||||||
	if (!test_facility(34))				\
 | 
						if (!test_facility(34))				\
 | 
				
			||||||
		__rc = EMU_ILLEGAL_OP;			\
 | 
							__rc = EMU_ILLEGAL_OP;			\
 | 
				
			||||||
	else if ((u64 __force)ptr & mask)		\
 | 
						else if ((u64 __force)__ptr & mask)		\
 | 
				
			||||||
		__rc = EMU_SPECIFICATION;		\
 | 
							__rc = EMU_SPECIFICATION;		\
 | 
				
			||||||
	else if (put_user(*(input), ptr))		\
 | 
						else if (put_user(*(input), __ptr))		\
 | 
				
			||||||
		__rc = EMU_ADDRESSING;			\
 | 
							__rc = EMU_ADDRESSING;			\
 | 
				
			||||||
 | 
						if (__rc == 0)					\
 | 
				
			||||||
 | 
							sim_stor_event(regs, __ptr, mask + 1);	\
 | 
				
			||||||
	__rc;						\
 | 
						__rc;						\
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,6 +229,25 @@ union split_register {
 | 
				
			||||||
	s16 s16[4];
 | 
						s16 s16[4];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * If user per registers are setup to trace storage alterations and an
 | 
				
			||||||
 | 
					 * emulated store took place on a fitting address a user trap is generated.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void sim_stor_event(struct pt_regs *regs, void *addr, int len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!(regs->psw.mask & PSW_MASK_PER))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (!(current->thread.per_user.control & PER_EVENT_STORE))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if ((void *)current->thread.per_user.start > (addr + len))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if ((void *)current->thread.per_user.end < addr)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						current->thread.per_event.address = regs->psw.addr;
 | 
				
			||||||
 | 
						current->thread.per_event.cause = PER_EVENT_STORE >> 16;
 | 
				
			||||||
 | 
						set_pt_regs_flag(regs, PIF_PER_TRAP);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * pc relative instructions are emulated, since parameters may not be
 | 
					 * pc relative instructions are emulated, since parameters may not be
 | 
				
			||||||
 * accessible from the xol area due to range limitations.
 | 
					 * accessible from the xol area due to range limitations.
 | 
				
			||||||
| 
						 | 
					@ -249,13 +300,13 @@ static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs)
 | 
				
			||||||
			rc = emu_load_ril((u32 __user *)uptr, &rx->u64);
 | 
								rc = emu_load_ril((u32 __user *)uptr, &rx->u64);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 0x07: /* sthrl */
 | 
							case 0x07: /* sthrl */
 | 
				
			||||||
			rc = emu_store_ril((u16 __user *)uptr, &rx->u16[3]);
 | 
								rc = emu_store_ril(regs, (u16 __user *)uptr, &rx->u16[3]);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 0x0b: /* stgrl */
 | 
							case 0x0b: /* stgrl */
 | 
				
			||||||
			rc = emu_store_ril((u64 __user *)uptr, &rx->u64);
 | 
								rc = emu_store_ril(regs, (u64 __user *)uptr, &rx->u64);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 0x0f: /* strl */
 | 
							case 0x0f: /* strl */
 | 
				
			||||||
			rc = emu_store_ril((u32 __user *)uptr, &rx->u32[1]);
 | 
								rc = emu_store_ril(regs, (u32 __user *)uptr, &rx->u32[1]);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,8 +128,6 @@ void vtime_account_irq_enter(struct task_struct *tsk)
 | 
				
			||||||
	struct thread_info *ti = task_thread_info(tsk);
 | 
						struct thread_info *ti = task_thread_info(tsk);
 | 
				
			||||||
	u64 timer, system;
 | 
						u64 timer, system;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON_ONCE(!irqs_disabled());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	timer = S390_lowcore.last_update_timer;
 | 
						timer = S390_lowcore.last_update_timer;
 | 
				
			||||||
	S390_lowcore.last_update_timer = get_vtimer();
 | 
						S390_lowcore.last_update_timer = get_vtimer();
 | 
				
			||||||
	S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
 | 
						S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -322,11 +322,12 @@ static int gmap_alloc_table(struct gmap *gmap, unsigned long *table,
 | 
				
			||||||
static unsigned long __gmap_segment_gaddr(unsigned long *entry)
 | 
					static unsigned long __gmap_segment_gaddr(unsigned long *entry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct page *page;
 | 
						struct page *page;
 | 
				
			||||||
	unsigned long offset;
 | 
						unsigned long offset, mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	offset = (unsigned long) entry / sizeof(unsigned long);
 | 
						offset = (unsigned long) entry / sizeof(unsigned long);
 | 
				
			||||||
	offset = (offset & (PTRS_PER_PMD - 1)) * PMD_SIZE;
 | 
						offset = (offset & (PTRS_PER_PMD - 1)) * PMD_SIZE;
 | 
				
			||||||
	page = pmd_to_page((pmd_t *) entry);
 | 
						mask = ~(PTRS_PER_PMD * sizeof(pmd_t) - 1);
 | 
				
			||||||
 | 
						page = virt_to_page((void *)((unsigned long) entry & mask));
 | 
				
			||||||
	return page->index + offset;
 | 
						return page->index + offset;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -431,8 +431,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
 | 
				
			||||||
		EMIT4_DISP(0x88500000, K);
 | 
							EMIT4_DISP(0x88500000, K);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BPF_ALU | BPF_NEG: /* A = -A */
 | 
						case BPF_ALU | BPF_NEG: /* A = -A */
 | 
				
			||||||
		/* lnr %r5,%r5 */
 | 
							/* lcr %r5,%r5 */
 | 
				
			||||||
		EMIT2(0x1155);
 | 
							EMIT2(0x1355);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BPF_JMP | BPF_JA: /* ip += K */
 | 
						case BPF_JMP | BPF_JA: /* ip += K */
 | 
				
			||||||
		offset = addrs[i + K] + jit->start - jit->prg;
 | 
							offset = addrs[i + K] + jit->start - jit->prg;
 | 
				
			||||||
| 
						 | 
					@ -502,8 +502,8 @@ branch:		if (filter->jt == filter->jf) {
 | 
				
			||||||
xbranch:	/* Emit compare if the branch targets are different */
 | 
					xbranch:	/* Emit compare if the branch targets are different */
 | 
				
			||||||
		if (filter->jt != filter->jf) {
 | 
							if (filter->jt != filter->jf) {
 | 
				
			||||||
			jit->seen |= SEEN_XREG;
 | 
								jit->seen |= SEEN_XREG;
 | 
				
			||||||
			/* cr %r5,%r12 */
 | 
								/* clr %r5,%r12 */
 | 
				
			||||||
			EMIT2(0x195c);
 | 
								EMIT2(0x155c);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		goto branch;
 | 
							goto branch;
 | 
				
			||||||
	case BPF_JMP | BPF_JSET | BPF_X: /* ip += (A & X) ? jt : jf */
 | 
						case BPF_JMP | BPF_JSET | BPF_X: /* ip += (A & X) ? jt : jf */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -568,8 +568,8 @@ struct event_constraint intel_atom_pebs_event_constraints[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct event_constraint intel_slm_pebs_event_constraints[] = {
 | 
					struct event_constraint intel_slm_pebs_event_constraints[] = {
 | 
				
			||||||
	/* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */
 | 
						/* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */
 | 
				
			||||||
	INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf),
 | 
						INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1),
 | 
				
			||||||
	/* Allow all events as PEBS with no flags */
 | 
						/* Allow all events as PEBS with no flags */
 | 
				
			||||||
	INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
 | 
						INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
 | 
				
			||||||
	EVENT_CONSTRAINT_END
 | 
						EVENT_CONSTRAINT_END
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,6 +103,13 @@ static struct kobj_attribute format_attr_##_var =		\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
 | 
					#define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RAPL_EVENT_ATTR_STR(_name, v, str)				\
 | 
				
			||||||
 | 
					static struct perf_pmu_events_attr event_attr_##v = {			\
 | 
				
			||||||
 | 
						.attr		= __ATTR(_name, 0444, rapl_sysfs_show, NULL),	\
 | 
				
			||||||
 | 
						.id		= 0,						\
 | 
				
			||||||
 | 
						.event_str	= str,						\
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rapl_pmu {
 | 
					struct rapl_pmu {
 | 
				
			||||||
	spinlock_t	 lock;
 | 
						spinlock_t	 lock;
 | 
				
			||||||
	int		 hw_unit;  /* 1/2^hw_unit Joule */
 | 
						int		 hw_unit;  /* 1/2^hw_unit Joule */
 | 
				
			||||||
| 
						 | 
					@ -379,23 +386,36 @@ static struct attribute_group rapl_pmu_attr_group = {
 | 
				
			||||||
	.attrs = rapl_pmu_attrs,
 | 
						.attrs = rapl_pmu_attrs,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
 | 
					static ssize_t rapl_sysfs_show(struct device *dev,
 | 
				
			||||||
EVENT_ATTR_STR(energy-pkg  ,   rapl_pkg, "event=0x02");
 | 
								       struct device_attribute *attr,
 | 
				
			||||||
EVENT_ATTR_STR(energy-ram  ,   rapl_ram, "event=0x03");
 | 
								       char *page)
 | 
				
			||||||
EVENT_ATTR_STR(energy-gpu  ,   rapl_gpu, "event=0x04");
 | 
					{
 | 
				
			||||||
 | 
						struct perf_pmu_events_attr *pmu_attr = \
 | 
				
			||||||
 | 
							container_of(attr, struct perf_pmu_events_attr, attr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
 | 
						if (pmu_attr->event_str)
 | 
				
			||||||
EVENT_ATTR_STR(energy-pkg.unit  ,   rapl_pkg_unit, "Joules");
 | 
							return sprintf(page, "%s", pmu_attr->event_str);
 | 
				
			||||||
EVENT_ATTR_STR(energy-ram.unit  ,   rapl_ram_unit, "Joules");
 | 
					
 | 
				
			||||||
EVENT_ATTR_STR(energy-gpu.unit  ,   rapl_gpu_unit, "Joules");
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-pkg  ,   rapl_pkg, "event=0x02");
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-ram  ,   rapl_ram, "event=0x03");
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-gpu  ,   rapl_gpu, "event=0x04");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-pkg.unit  ,   rapl_pkg_unit, "Joules");
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-ram.unit  ,   rapl_ram_unit, "Joules");
 | 
				
			||||||
 | 
					RAPL_EVENT_ATTR_STR(energy-gpu.unit  ,   rapl_gpu_unit, "Joules");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * we compute in 0.23 nJ increments regardless of MSR
 | 
					 * we compute in 0.23 nJ increments regardless of MSR
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
 | 
					RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10");
 | 
				
			||||||
EVENT_ATTR_STR(energy-pkg.scale,     rapl_pkg_scale, "2.3283064365386962890625e-10");
 | 
					RAPL_EVENT_ATTR_STR(energy-pkg.scale,     rapl_pkg_scale, "2.3283064365386962890625e-10");
 | 
				
			||||||
EVENT_ATTR_STR(energy-ram.scale,     rapl_ram_scale, "2.3283064365386962890625e-10");
 | 
					RAPL_EVENT_ATTR_STR(energy-ram.scale,     rapl_ram_scale, "2.3283064365386962890625e-10");
 | 
				
			||||||
EVENT_ATTR_STR(energy-gpu.scale,     rapl_gpu_scale, "2.3283064365386962890625e-10");
 | 
					RAPL_EVENT_ATTR_STR(energy-gpu.scale,     rapl_gpu_scale, "2.3283064365386962890625e-10");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct attribute *rapl_events_srv_attr[] = {
 | 
					static struct attribute *rapl_events_srv_attr[] = {
 | 
				
			||||||
	EVENT_PTR(rapl_cores),
 | 
						EVENT_PTR(rapl_cores),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1020,6 +1020,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 | 
				
			||||||
	regs->flags &= ~X86_EFLAGS_IF;
 | 
						regs->flags &= ~X86_EFLAGS_IF;
 | 
				
			||||||
	trace_hardirqs_off();
 | 
						trace_hardirqs_off();
 | 
				
			||||||
	regs->ip = (unsigned long)(jp->entry);
 | 
						regs->ip = (unsigned long)(jp->entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * jprobes use jprobe_return() which skips the normal return
 | 
				
			||||||
 | 
						 * path of the function, and this messes up the accounting of the
 | 
				
			||||||
 | 
						 * function graph tracer to get messed up.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Pause function graph tracing while performing the jprobe function.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						pause_graph_tracing();
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
NOKPROBE_SYMBOL(setjmp_pre_handler);
 | 
					NOKPROBE_SYMBOL(setjmp_pre_handler);
 | 
				
			||||||
| 
						 | 
					@ -1048,24 +1057,25 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 | 
				
			||||||
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 | 
						struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 | 
				
			||||||
	u8 *addr = (u8 *) (regs->ip - 1);
 | 
						u8 *addr = (u8 *) (regs->ip - 1);
 | 
				
			||||||
	struct jprobe *jp = container_of(p, struct jprobe, kp);
 | 
						struct jprobe *jp = container_of(p, struct jprobe, kp);
 | 
				
			||||||
 | 
						void *saved_sp = kcb->jprobe_saved_sp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((addr > (u8 *) jprobe_return) &&
 | 
						if ((addr > (u8 *) jprobe_return) &&
 | 
				
			||||||
	    (addr < (u8 *) jprobe_return_end)) {
 | 
						    (addr < (u8 *) jprobe_return_end)) {
 | 
				
			||||||
		if (stack_addr(regs) != kcb->jprobe_saved_sp) {
 | 
							if (stack_addr(regs) != saved_sp) {
 | 
				
			||||||
			struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
 | 
								struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
 | 
				
			||||||
			printk(KERN_ERR
 | 
								printk(KERN_ERR
 | 
				
			||||||
			       "current sp %p does not match saved sp %p\n",
 | 
								       "current sp %p does not match saved sp %p\n",
 | 
				
			||||||
			       stack_addr(regs), kcb->jprobe_saved_sp);
 | 
								       stack_addr(regs), saved_sp);
 | 
				
			||||||
			printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
 | 
								printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
 | 
				
			||||||
			show_regs(saved_regs);
 | 
								show_regs(saved_regs);
 | 
				
			||||||
			printk(KERN_ERR "Current registers\n");
 | 
								printk(KERN_ERR "Current registers\n");
 | 
				
			||||||
			show_regs(regs);
 | 
								show_regs(regs);
 | 
				
			||||||
			BUG();
 | 
								BUG();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							/* It's OK to start function graph tracing again */
 | 
				
			||||||
 | 
							unpause_graph_tracing();
 | 
				
			||||||
		*regs = kcb->jprobe_saved_regs;
 | 
							*regs = kcb->jprobe_saved_regs;
 | 
				
			||||||
		memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp),
 | 
							memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp));
 | 
				
			||||||
		       kcb->jprobes_stack,
 | 
					 | 
				
			||||||
		       MIN_STACK_SIZE(kcb->jprobe_saved_sp));
 | 
					 | 
				
			||||||
		preempt_enable_no_resched();
 | 
							preempt_enable_no_resched();
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,7 @@
 | 
				
			||||||
#include <xen/interface/physdev.h>
 | 
					#include <xen/interface/physdev.h>
 | 
				
			||||||
#include <xen/interface/vcpu.h>
 | 
					#include <xen/interface/vcpu.h>
 | 
				
			||||||
#include <xen/interface/memory.h>
 | 
					#include <xen/interface/memory.h>
 | 
				
			||||||
 | 
					#include <xen/interface/nmi.h>
 | 
				
			||||||
#include <xen/interface/xen-mca.h>
 | 
					#include <xen/interface/xen-mca.h>
 | 
				
			||||||
#include <xen/features.h>
 | 
					#include <xen/features.h>
 | 
				
			||||||
#include <xen/page.h>
 | 
					#include <xen/page.h>
 | 
				
			||||||
| 
						 | 
					@ -66,6 +67,7 @@
 | 
				
			||||||
#include <asm/reboot.h>
 | 
					#include <asm/reboot.h>
 | 
				
			||||||
#include <asm/stackprotector.h>
 | 
					#include <asm/stackprotector.h>
 | 
				
			||||||
#include <asm/hypervisor.h>
 | 
					#include <asm/hypervisor.h>
 | 
				
			||||||
 | 
					#include <asm/mach_traps.h>
 | 
				
			||||||
#include <asm/mwait.h>
 | 
					#include <asm/mwait.h>
 | 
				
			||||||
#include <asm/pci_x86.h>
 | 
					#include <asm/pci_x86.h>
 | 
				
			||||||
#include <asm/pat.h>
 | 
					#include <asm/pat.h>
 | 
				
			||||||
| 
						 | 
					@ -1351,6 +1353,21 @@ static const struct machine_ops xen_machine_ops __initconst = {
 | 
				
			||||||
	.emergency_restart = xen_emergency_restart,
 | 
						.emergency_restart = xen_emergency_restart,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned char xen_get_nmi_reason(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned char reason = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Construct a value which looks like it came from port 0x61. */
 | 
				
			||||||
 | 
						if (test_bit(_XEN_NMIREASON_io_error,
 | 
				
			||||||
 | 
							     &HYPERVISOR_shared_info->arch.nmi_reason))
 | 
				
			||||||
 | 
							reason |= NMI_REASON_IOCHK;
 | 
				
			||||||
 | 
						if (test_bit(_XEN_NMIREASON_pci_serr,
 | 
				
			||||||
 | 
							     &HYPERVISOR_shared_info->arch.nmi_reason))
 | 
				
			||||||
 | 
							reason |= NMI_REASON_SERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return reason;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __init xen_boot_params_init_edd(void)
 | 
					static void __init xen_boot_params_init_edd(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if IS_ENABLED(CONFIG_EDD)
 | 
					#if IS_ENABLED(CONFIG_EDD)
 | 
				
			||||||
| 
						 | 
					@ -1535,9 +1552,12 @@ asmlinkage __visible void __init xen_start_kernel(void)
 | 
				
			||||||
	pv_info = xen_info;
 | 
						pv_info = xen_info;
 | 
				
			||||||
	pv_init_ops = xen_init_ops;
 | 
						pv_init_ops = xen_init_ops;
 | 
				
			||||||
	pv_apic_ops = xen_apic_ops;
 | 
						pv_apic_ops = xen_apic_ops;
 | 
				
			||||||
	if (!xen_pvh_domain())
 | 
						if (!xen_pvh_domain()) {
 | 
				
			||||||
		pv_cpu_ops = xen_cpu_ops;
 | 
							pv_cpu_ops = xen_cpu_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							x86_platform.get_nmi_reason = xen_get_nmi_reason;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (xen_feature(XENFEAT_auto_translated_physmap))
 | 
						if (xen_feature(XENFEAT_auto_translated_physmap))
 | 
				
			||||||
		x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
 | 
							x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,10 +167,13 @@ static void * __ref alloc_p2m_page(void)
 | 
				
			||||||
	return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
 | 
						return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Only to be called in case of a race for a page just allocated! */
 | 
					static void __ref free_p2m_page(void *p)
 | 
				
			||||||
static void free_p2m_page(void *p)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BUG_ON(!slab_is_available());
 | 
						if (unlikely(!slab_is_available())) {
 | 
				
			||||||
 | 
							free_bootmem((unsigned long)p, PAGE_SIZE);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free_page((unsigned long)p);
 | 
						free_page((unsigned long)p);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -375,7 +378,7 @@ static void __init xen_rebuild_p2m_list(unsigned long *p2m)
 | 
				
			||||||
			p2m_missing_pte : p2m_identity_pte;
 | 
								p2m_missing_pte : p2m_identity_pte;
 | 
				
			||||||
		for (i = 0; i < PMDS_PER_MID_PAGE; i++) {
 | 
							for (i = 0; i < PMDS_PER_MID_PAGE; i++) {
 | 
				
			||||||
			pmdp = populate_extra_pmd(
 | 
								pmdp = populate_extra_pmd(
 | 
				
			||||||
				(unsigned long)(p2m + pfn + i * PTRS_PER_PTE));
 | 
									(unsigned long)(p2m + pfn) + i * PMD_SIZE);
 | 
				
			||||||
			set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE));
 | 
								set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -436,10 +439,9 @@ EXPORT_SYMBOL_GPL(get_phys_to_machine);
 | 
				
			||||||
 * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual
 | 
					 * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual
 | 
				
			||||||
 * pmd. In case of PAE/x86-32 there are multiple pmds to allocate!
 | 
					 * pmd. In case of PAE/x86-32 there are multiple pmds to allocate!
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
 | 
					static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pte_t *ptechk;
 | 
						pte_t *ptechk;
 | 
				
			||||||
	pte_t *pteret = ptep;
 | 
					 | 
				
			||||||
	pte_t *pte_newpg[PMDS_PER_MID_PAGE];
 | 
						pte_t *pte_newpg[PMDS_PER_MID_PAGE];
 | 
				
			||||||
	pmd_t *pmdp;
 | 
						pmd_t *pmdp;
 | 
				
			||||||
	unsigned int level;
 | 
						unsigned int level;
 | 
				
			||||||
| 
						 | 
					@ -473,8 +475,6 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
 | 
				
			||||||
		if (ptechk == pte_pg) {
 | 
							if (ptechk == pte_pg) {
 | 
				
			||||||
			set_pmd(pmdp,
 | 
								set_pmd(pmdp,
 | 
				
			||||||
				__pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
 | 
									__pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
 | 
				
			||||||
			if (vaddr == (addr & ~(PMD_SIZE - 1)))
 | 
					 | 
				
			||||||
				pteret = pte_offset_kernel(pmdp, addr);
 | 
					 | 
				
			||||||
			pte_newpg[i] = NULL;
 | 
								pte_newpg[i] = NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -488,7 +488,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg)
 | 
				
			||||||
		vaddr += PMD_SIZE;
 | 
							vaddr += PMD_SIZE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pteret;
 | 
						return lookup_address(addr, &level);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -517,7 +517,7 @@ static bool alloc_p2m(unsigned long pfn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) {
 | 
						if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) {
 | 
				
			||||||
		/* PMD level is missing, allocate a new one */
 | 
							/* PMD level is missing, allocate a new one */
 | 
				
			||||||
		ptep = alloc_p2m_pmd(addr, ptep, pte_pg);
 | 
							ptep = alloc_p2m_pmd(addr, pte_pg);
 | 
				
			||||||
		if (!ptep)
 | 
							if (!ptep)
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,7 +140,7 @@ static void __init xen_del_extra_mem(u64 start, u64 size)
 | 
				
			||||||
unsigned long __ref xen_chk_extra_mem(unsigned long pfn)
 | 
					unsigned long __ref xen_chk_extra_mem(unsigned long pfn)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	unsigned long addr = PFN_PHYS(pfn);
 | 
						phys_addr_t addr = PFN_PHYS(pfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 | 
						for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 | 
				
			||||||
		if (addr >= xen_extra_mem[i].start &&
 | 
							if (addr >= xen_extra_mem[i].start &&
 | 
				
			||||||
| 
						 | 
					@ -160,6 +160,8 @@ void __init xen_inv_extra_mem(void)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 | 
						for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
 | 
				
			||||||
 | 
							if (!xen_extra_mem[i].size)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
		pfn_s = PFN_DOWN(xen_extra_mem[i].start);
 | 
							pfn_s = PFN_DOWN(xen_extra_mem[i].start);
 | 
				
			||||||
		pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size);
 | 
							pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size);
 | 
				
			||||||
		for (pfn = pfn_s; pfn < pfn_e; pfn++)
 | 
							for (pfn = pfn_s; pfn < pfn_e; pfn++)
 | 
				
			||||||
| 
						 | 
					@ -229,15 +231,14 @@ static int __init xen_free_mfn(unsigned long mfn)
 | 
				
			||||||
 * as a fallback if the remapping fails.
 | 
					 * as a fallback if the remapping fails.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
 | 
					static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
 | 
				
			||||||
	unsigned long end_pfn, unsigned long nr_pages, unsigned long *identity,
 | 
						unsigned long end_pfn, unsigned long nr_pages, unsigned long *released)
 | 
				
			||||||
	unsigned long *released)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long len = 0;
 | 
					 | 
				
			||||||
	unsigned long pfn, end;
 | 
						unsigned long pfn, end;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON(start_pfn > end_pfn);
 | 
						WARN_ON(start_pfn > end_pfn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Release pages first. */
 | 
				
			||||||
	end = min(end_pfn, nr_pages);
 | 
						end = min(end_pfn, nr_pages);
 | 
				
			||||||
	for (pfn = start_pfn; pfn < end; pfn++) {
 | 
						for (pfn = start_pfn; pfn < end; pfn++) {
 | 
				
			||||||
		unsigned long mfn = pfn_to_mfn(pfn);
 | 
							unsigned long mfn = pfn_to_mfn(pfn);
 | 
				
			||||||
| 
						 | 
					@ -250,16 +251,14 @@ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
 | 
				
			||||||
		WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
 | 
							WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ret == 1) {
 | 
							if (ret == 1) {
 | 
				
			||||||
 | 
								(*released)++;
 | 
				
			||||||
			if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY))
 | 
								if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY))
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			len++;
 | 
					 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Need to release pages first */
 | 
						set_phys_range_identity(start_pfn, end_pfn);
 | 
				
			||||||
	*released += len;
 | 
					 | 
				
			||||||
	*identity += set_phys_range_identity(start_pfn, end_pfn);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -287,7 +286,7 @@ static void __init xen_update_mem_tables(unsigned long pfn, unsigned long mfn)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update kernel mapping, but not for highmem. */
 | 
						/* Update kernel mapping, but not for highmem. */
 | 
				
			||||||
	if ((pfn << PAGE_SHIFT) >= __pa(high_memory))
 | 
						if (pfn >= PFN_UP(__pa(high_memory - 1)))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT),
 | 
						if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT),
 | 
				
			||||||
| 
						 | 
					@ -318,7 +317,6 @@ static void __init xen_do_set_identity_and_remap_chunk(
 | 
				
			||||||
	unsigned long ident_pfn_iter, remap_pfn_iter;
 | 
						unsigned long ident_pfn_iter, remap_pfn_iter;
 | 
				
			||||||
	unsigned long ident_end_pfn = start_pfn + size;
 | 
						unsigned long ident_end_pfn = start_pfn + size;
 | 
				
			||||||
	unsigned long left = size;
 | 
						unsigned long left = size;
 | 
				
			||||||
	unsigned long ident_cnt = 0;
 | 
					 | 
				
			||||||
	unsigned int i, chunk;
 | 
						unsigned int i, chunk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON(size == 0);
 | 
						WARN_ON(size == 0);
 | 
				
			||||||
| 
						 | 
					@ -347,8 +345,7 @@ static void __init xen_do_set_identity_and_remap_chunk(
 | 
				
			||||||
		xen_remap_mfn = mfn;
 | 
							xen_remap_mfn = mfn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Set identity map */
 | 
							/* Set identity map */
 | 
				
			||||||
		ident_cnt += set_phys_range_identity(ident_pfn_iter,
 | 
							set_phys_range_identity(ident_pfn_iter, ident_pfn_iter + chunk);
 | 
				
			||||||
			ident_pfn_iter + chunk);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		left -= chunk;
 | 
							left -= chunk;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -371,7 +368,7 @@ static void __init xen_do_set_identity_and_remap_chunk(
 | 
				
			||||||
static unsigned long __init xen_set_identity_and_remap_chunk(
 | 
					static unsigned long __init xen_set_identity_and_remap_chunk(
 | 
				
			||||||
        const struct e820entry *list, size_t map_size, unsigned long start_pfn,
 | 
					        const struct e820entry *list, size_t map_size, unsigned long start_pfn,
 | 
				
			||||||
	unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn,
 | 
						unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn,
 | 
				
			||||||
	unsigned long *identity, unsigned long *released)
 | 
						unsigned long *released, unsigned long *remapped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long pfn;
 | 
						unsigned long pfn;
 | 
				
			||||||
	unsigned long i = 0;
 | 
						unsigned long i = 0;
 | 
				
			||||||
| 
						 | 
					@ -386,8 +383,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 | 
				
			||||||
		/* Do not remap pages beyond the current allocation */
 | 
							/* Do not remap pages beyond the current allocation */
 | 
				
			||||||
		if (cur_pfn >= nr_pages) {
 | 
							if (cur_pfn >= nr_pages) {
 | 
				
			||||||
			/* Identity map remaining pages */
 | 
								/* Identity map remaining pages */
 | 
				
			||||||
			*identity += set_phys_range_identity(cur_pfn,
 | 
								set_phys_range_identity(cur_pfn, cur_pfn + size);
 | 
				
			||||||
				cur_pfn + size);
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (cur_pfn + size > nr_pages)
 | 
							if (cur_pfn + size > nr_pages)
 | 
				
			||||||
| 
						 | 
					@ -398,7 +394,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 | 
				
			||||||
		if (!remap_range_size) {
 | 
							if (!remap_range_size) {
 | 
				
			||||||
			pr_warning("Unable to find available pfn range, not remapping identity pages\n");
 | 
								pr_warning("Unable to find available pfn range, not remapping identity pages\n");
 | 
				
			||||||
			xen_set_identity_and_release_chunk(cur_pfn,
 | 
								xen_set_identity_and_release_chunk(cur_pfn,
 | 
				
			||||||
				cur_pfn + left, nr_pages, identity, released);
 | 
									cur_pfn + left, nr_pages, released);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/* Adjust size to fit in current e820 RAM region */
 | 
							/* Adjust size to fit in current e820 RAM region */
 | 
				
			||||||
| 
						 | 
					@ -410,7 +406,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 | 
				
			||||||
		/* Update variables to reflect new mappings. */
 | 
							/* Update variables to reflect new mappings. */
 | 
				
			||||||
		i += size;
 | 
							i += size;
 | 
				
			||||||
		remap_pfn += size;
 | 
							remap_pfn += size;
 | 
				
			||||||
		*identity += size;
 | 
							*remapped += size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -427,13 +423,13 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __init xen_set_identity_and_remap(
 | 
					static void __init xen_set_identity_and_remap(
 | 
				
			||||||
	const struct e820entry *list, size_t map_size, unsigned long nr_pages,
 | 
						const struct e820entry *list, size_t map_size, unsigned long nr_pages,
 | 
				
			||||||
	unsigned long *released)
 | 
						unsigned long *released, unsigned long *remapped)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	phys_addr_t start = 0;
 | 
						phys_addr_t start = 0;
 | 
				
			||||||
	unsigned long identity = 0;
 | 
					 | 
				
			||||||
	unsigned long last_pfn = nr_pages;
 | 
						unsigned long last_pfn = nr_pages;
 | 
				
			||||||
	const struct e820entry *entry;
 | 
						const struct e820entry *entry;
 | 
				
			||||||
	unsigned long num_released = 0;
 | 
						unsigned long num_released = 0;
 | 
				
			||||||
 | 
						unsigned long num_remapped = 0;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -460,14 +456,14 @@ static void __init xen_set_identity_and_remap(
 | 
				
			||||||
				last_pfn = xen_set_identity_and_remap_chunk(
 | 
									last_pfn = xen_set_identity_and_remap_chunk(
 | 
				
			||||||
						list, map_size, start_pfn,
 | 
											list, map_size, start_pfn,
 | 
				
			||||||
						end_pfn, nr_pages, last_pfn,
 | 
											end_pfn, nr_pages, last_pfn,
 | 
				
			||||||
						&identity, &num_released);
 | 
											&num_released, &num_remapped);
 | 
				
			||||||
			start = end;
 | 
								start = end;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*released = num_released;
 | 
						*released = num_released;
 | 
				
			||||||
 | 
						*remapped = num_remapped;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_info("Set %ld page(s) to 1-1 mapping\n", identity);
 | 
					 | 
				
			||||||
	pr_info("Released %ld page(s)\n", num_released);
 | 
						pr_info("Released %ld page(s)\n", num_released);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -586,6 +582,7 @@ char * __init xen_memory_setup(void)
 | 
				
			||||||
	struct xen_memory_map memmap;
 | 
						struct xen_memory_map memmap;
 | 
				
			||||||
	unsigned long max_pages;
 | 
						unsigned long max_pages;
 | 
				
			||||||
	unsigned long extra_pages = 0;
 | 
						unsigned long extra_pages = 0;
 | 
				
			||||||
 | 
						unsigned long remapped_pages;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int op;
 | 
						int op;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -635,9 +632,10 @@ char * __init xen_memory_setup(void)
 | 
				
			||||||
	 * underlying RAM.
 | 
						 * underlying RAM.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn,
 | 
						xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn,
 | 
				
			||||||
				   &xen_released_pages);
 | 
									   &xen_released_pages, &remapped_pages);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extra_pages += xen_released_pages;
 | 
						extra_pages += xen_released_pages;
 | 
				
			||||||
 | 
						extra_pages += remapped_pages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
 | 
						 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -391,7 +391,7 @@ static const struct clock_event_device *xen_clockevent =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct xen_clock_event_device {
 | 
					struct xen_clock_event_device {
 | 
				
			||||||
	struct clock_event_device evt;
 | 
						struct clock_event_device evt;
 | 
				
			||||||
	char *name;
 | 
						char name[16];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 };
 | 
					static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -420,46 +420,38 @@ void xen_teardown_timer(int cpu)
 | 
				
			||||||
	if (evt->irq >= 0) {
 | 
						if (evt->irq >= 0) {
 | 
				
			||||||
		unbind_from_irqhandler(evt->irq, NULL);
 | 
							unbind_from_irqhandler(evt->irq, NULL);
 | 
				
			||||||
		evt->irq = -1;
 | 
							evt->irq = -1;
 | 
				
			||||||
		kfree(per_cpu(xen_clock_events, cpu).name);
 | 
					 | 
				
			||||||
		per_cpu(xen_clock_events, cpu).name = NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void xen_setup_timer(int cpu)
 | 
					void xen_setup_timer(int cpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *name;
 | 
						struct xen_clock_event_device *xevt = &per_cpu(xen_clock_events, cpu);
 | 
				
			||||||
	struct clock_event_device *evt;
 | 
						struct clock_event_device *evt = &xevt->evt;
 | 
				
			||||||
	int irq;
 | 
						int irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	evt = &per_cpu(xen_clock_events, cpu).evt;
 | 
					 | 
				
			||||||
	WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
 | 
						WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
 | 
				
			||||||
	if (evt->irq >= 0)
 | 
						if (evt->irq >= 0)
 | 
				
			||||||
		xen_teardown_timer(cpu);
 | 
							xen_teardown_timer(cpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
 | 
						printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	name = kasprintf(GFP_KERNEL, "timer%d", cpu);
 | 
						snprintf(xevt->name, sizeof(xevt->name), "timer%d", cpu);
 | 
				
			||||||
	if (!name)
 | 
					 | 
				
			||||||
		name = "<timer kasprintf failed>";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
 | 
						irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt,
 | 
				
			||||||
				      IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER|
 | 
									      IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER|
 | 
				
			||||||
				      IRQF_FORCE_RESUME|IRQF_EARLY_RESUME,
 | 
									      IRQF_FORCE_RESUME|IRQF_EARLY_RESUME,
 | 
				
			||||||
				      name, NULL);
 | 
									      xevt->name, NULL);
 | 
				
			||||||
	(void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX);
 | 
						(void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(evt, xen_clockevent, sizeof(*evt));
 | 
						memcpy(evt, xen_clockevent, sizeof(*evt));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	evt->cpumask = cpumask_of(cpu);
 | 
						evt->cpumask = cpumask_of(cpu);
 | 
				
			||||||
	evt->irq = irq;
 | 
						evt->irq = irq;
 | 
				
			||||||
	per_cpu(xen_clock_events, cpu).name = name;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void xen_setup_cpu_clockevents(void)
 | 
					void xen_setup_cpu_clockevents(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BUG_ON(preemptible());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt));
 | 
						clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,6 +473,25 @@ void blk_queue_bypass_end(struct request_queue *q)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(blk_queue_bypass_end);
 | 
					EXPORT_SYMBOL_GPL(blk_queue_bypass_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blk_set_queue_dying(struct request_queue *q)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						queue_flag_set_unlocked(QUEUE_FLAG_DYING, q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (q->mq_ops)
 | 
				
			||||||
 | 
							blk_mq_wake_waiters(q);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							struct request_list *rl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							blk_queue_for_each_rl(rl, q) {
 | 
				
			||||||
 | 
								if (rl->rq_pool) {
 | 
				
			||||||
 | 
									wake_up(&rl->wait[BLK_RW_SYNC]);
 | 
				
			||||||
 | 
									wake_up(&rl->wait[BLK_RW_ASYNC]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(blk_set_queue_dying);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * blk_cleanup_queue - shutdown a request queue
 | 
					 * blk_cleanup_queue - shutdown a request queue
 | 
				
			||||||
 * @q: request queue to shutdown
 | 
					 * @q: request queue to shutdown
 | 
				
			||||||
| 
						 | 
					@ -486,7 +505,7 @@ void blk_cleanup_queue(struct request_queue *q)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* mark @q DYING, no new request or merges will be allowed afterwards */
 | 
						/* mark @q DYING, no new request or merges will be allowed afterwards */
 | 
				
			||||||
	mutex_lock(&q->sysfs_lock);
 | 
						mutex_lock(&q->sysfs_lock);
 | 
				
			||||||
	queue_flag_set_unlocked(QUEUE_FLAG_DYING, q);
 | 
						blk_set_queue_dying(q);
 | 
				
			||||||
	spin_lock_irq(lock);
 | 
						spin_lock_irq(lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,9 +68,9 @@ bool __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Wakeup all potentially sleeping on normal (non-reserved) tags
 | 
					 * Wakeup all potentially sleeping on tags
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags)
 | 
					void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool include_reserve)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct blk_mq_bitmap_tags *bt;
 | 
						struct blk_mq_bitmap_tags *bt;
 | 
				
			||||||
	int i, wake_index;
 | 
						int i, wake_index;
 | 
				
			||||||
| 
						 | 
					@ -85,6 +85,12 @@ static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wake_index = bt_index_inc(wake_index);
 | 
							wake_index = bt_index_inc(wake_index);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (include_reserve) {
 | 
				
			||||||
 | 
							bt = &tags->breserved_tags;
 | 
				
			||||||
 | 
							if (waitqueue_active(&bt->bs[0].wait))
 | 
				
			||||||
 | 
								wake_up(&bt->bs[0].wait);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -100,7 +106,7 @@ void __blk_mq_tag_idle(struct blk_mq_hw_ctx *hctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	atomic_dec(&tags->active_queues);
 | 
						atomic_dec(&tags->active_queues);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	blk_mq_tag_wakeup_all(tags);
 | 
						blk_mq_tag_wakeup_all(tags, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -584,7 +590,7 @@ int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int tdepth)
 | 
				
			||||||
	 * static and should never need resizing.
 | 
						 * static and should never need resizing.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	bt_update_count(&tags->bitmap_tags, tdepth);
 | 
						bt_update_count(&tags->bitmap_tags, tdepth);
 | 
				
			||||||
	blk_mq_tag_wakeup_all(tags);
 | 
						blk_mq_tag_wakeup_all(tags, false);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@ extern bool blk_mq_has_free_tags(struct blk_mq_tags *tags);
 | 
				
			||||||
extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page);
 | 
					extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page);
 | 
				
			||||||
extern void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *last_tag);
 | 
					extern void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *last_tag);
 | 
				
			||||||
extern int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int depth);
 | 
					extern int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int depth);
 | 
				
			||||||
 | 
					extern void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	BLK_MQ_TAG_CACHE_MIN	= 1,
 | 
						BLK_MQ_TAG_CACHE_MIN	= 1,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,7 +107,7 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref)
 | 
				
			||||||
	wake_up_all(&q->mq_freeze_wq);
 | 
						wake_up_all(&q->mq_freeze_wq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void blk_mq_freeze_queue_start(struct request_queue *q)
 | 
					void blk_mq_freeze_queue_start(struct request_queue *q)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool freeze;
 | 
						bool freeze;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,6 +120,7 @@ static void blk_mq_freeze_queue_start(struct request_queue *q)
 | 
				
			||||||
		blk_mq_run_queues(q, false);
 | 
							blk_mq_run_queues(q, false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void blk_mq_freeze_queue_wait(struct request_queue *q)
 | 
					static void blk_mq_freeze_queue_wait(struct request_queue *q)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -136,7 +137,7 @@ void blk_mq_freeze_queue(struct request_queue *q)
 | 
				
			||||||
	blk_mq_freeze_queue_wait(q);
 | 
						blk_mq_freeze_queue_wait(q);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void blk_mq_unfreeze_queue(struct request_queue *q)
 | 
					void blk_mq_unfreeze_queue(struct request_queue *q)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool wake;
 | 
						bool wake;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,6 +150,24 @@ static void blk_mq_unfreeze_queue(struct request_queue *q)
 | 
				
			||||||
		wake_up_all(&q->mq_freeze_wq);
 | 
							wake_up_all(&q->mq_freeze_wq);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blk_mq_wake_waiters(struct request_queue *q)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct blk_mq_hw_ctx *hctx;
 | 
				
			||||||
 | 
						unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						queue_for_each_hw_ctx(q, hctx, i)
 | 
				
			||||||
 | 
							if (blk_mq_hw_queue_mapped(hctx))
 | 
				
			||||||
 | 
								blk_mq_tag_wakeup_all(hctx->tags, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If we are called because the queue has now been marked as
 | 
				
			||||||
 | 
						 * dying, we need to ensure that processes currently waiting on
 | 
				
			||||||
 | 
						 * the queue are notified as well.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						wake_up_all(&q->mq_freeze_wq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
 | 
					bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -258,8 +277,10 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp,
 | 
				
			||||||
		ctx = alloc_data.ctx;
 | 
							ctx = alloc_data.ctx;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	blk_mq_put_ctx(ctx);
 | 
						blk_mq_put_ctx(ctx);
 | 
				
			||||||
	if (!rq)
 | 
						if (!rq) {
 | 
				
			||||||
 | 
							blk_mq_queue_exit(q);
 | 
				
			||||||
		return ERR_PTR(-EWOULDBLOCK);
 | 
							return ERR_PTR(-EWOULDBLOCK);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return rq;
 | 
						return rq;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(blk_mq_alloc_request);
 | 
					EXPORT_SYMBOL(blk_mq_alloc_request);
 | 
				
			||||||
| 
						 | 
					@ -383,6 +404,12 @@ void blk_mq_complete_request(struct request *rq)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(blk_mq_complete_request);
 | 
					EXPORT_SYMBOL(blk_mq_complete_request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int blk_mq_request_started(struct request *rq)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return test_bit(REQ_ATOM_STARTED, &rq->atomic_flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(blk_mq_request_started);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void blk_mq_start_request(struct request *rq)
 | 
					void blk_mq_start_request(struct request *rq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct request_queue *q = rq->q;
 | 
						struct request_queue *q = rq->q;
 | 
				
			||||||
| 
						 | 
					@ -500,12 +527,38 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(blk_mq_add_to_requeue_list);
 | 
					EXPORT_SYMBOL(blk_mq_add_to_requeue_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blk_mq_cancel_requeue_work(struct request_queue *q)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						cancel_work_sync(&q->requeue_work);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(blk_mq_cancel_requeue_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void blk_mq_kick_requeue_list(struct request_queue *q)
 | 
					void blk_mq_kick_requeue_list(struct request_queue *q)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	kblockd_schedule_work(&q->requeue_work);
 | 
						kblockd_schedule_work(&q->requeue_work);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(blk_mq_kick_requeue_list);
 | 
					EXPORT_SYMBOL(blk_mq_kick_requeue_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void blk_mq_abort_requeue_list(struct request_queue *q)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
						LIST_HEAD(rq_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irqsave(&q->requeue_lock, flags);
 | 
				
			||||||
 | 
						list_splice_init(&q->requeue_list, &rq_list);
 | 
				
			||||||
 | 
						spin_unlock_irqrestore(&q->requeue_lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!list_empty(&rq_list)) {
 | 
				
			||||||
 | 
							struct request *rq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rq = list_first_entry(&rq_list, struct request, queuelist);
 | 
				
			||||||
 | 
							list_del_init(&rq->queuelist);
 | 
				
			||||||
 | 
							rq->errors = -EIO;
 | 
				
			||||||
 | 
							blk_mq_end_request(rq, rq->errors);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(blk_mq_abort_requeue_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool is_flush_request(struct request *rq,
 | 
					static inline bool is_flush_request(struct request *rq,
 | 
				
			||||||
		struct blk_flush_queue *fq, unsigned int tag)
 | 
							struct blk_flush_queue *fq, unsigned int tag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -572,7 +625,18 @@ static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct blk_mq_timeout_data *data = priv;
 | 
						struct blk_mq_timeout_data *data = priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags))
 | 
						if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If a request wasn't started before the queue was
 | 
				
			||||||
 | 
							 * marked dying, kill it here or it'll go unnoticed.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (unlikely(blk_queue_dying(rq->q))) {
 | 
				
			||||||
 | 
								rq->errors = -EIO;
 | 
				
			||||||
 | 
								blk_mq_complete_request(rq);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (rq->cmd_flags & REQ_NO_TIMEOUT)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (time_after_eq(jiffies, rq->deadline)) {
 | 
						if (time_after_eq(jiffies, rq->deadline)) {
 | 
				
			||||||
| 
						 | 
					@ -1601,7 +1665,6 @@ static int blk_mq_init_hctx(struct request_queue *q,
 | 
				
			||||||
	hctx->queue = q;
 | 
						hctx->queue = q;
 | 
				
			||||||
	hctx->queue_num = hctx_idx;
 | 
						hctx->queue_num = hctx_idx;
 | 
				
			||||||
	hctx->flags = set->flags;
 | 
						hctx->flags = set->flags;
 | 
				
			||||||
	hctx->cmd_size = set->cmd_size;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	blk_mq_init_cpu_notifier(&hctx->cpu_notifier,
 | 
						blk_mq_init_cpu_notifier(&hctx->cpu_notifier,
 | 
				
			||||||
					blk_mq_hctx_notify, hctx);
 | 
										blk_mq_hctx_notify, hctx);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ void blk_mq_free_queue(struct request_queue *q);
 | 
				
			||||||
void blk_mq_clone_flush_request(struct request *flush_rq,
 | 
					void blk_mq_clone_flush_request(struct request *flush_rq,
 | 
				
			||||||
		struct request *orig_rq);
 | 
							struct request *orig_rq);
 | 
				
			||||||
int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr);
 | 
					int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr);
 | 
				
			||||||
 | 
					void blk_mq_wake_waiters(struct request_queue *q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * CPU hotplug helpers
 | 
					 * CPU hotplug helpers
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,6 +190,9 @@ void blk_add_timer(struct request *req)
 | 
				
			||||||
	struct request_queue *q = req->q;
 | 
						struct request_queue *q = req->q;
 | 
				
			||||||
	unsigned long expiry;
 | 
						unsigned long expiry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (req->cmd_flags & REQ_NO_TIMEOUT)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */
 | 
						/* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */
 | 
				
			||||||
	if (!q->mq_ops && !q->rq_timed_out_fn)
 | 
						if (!q->mq_ops && !q->rq_timed_out_fn)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,10 +14,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "internal.h"
 | 
					#include "internal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DO_ENUMERATION 0x01
 | 
					#define INT3401_DEVICE 0X01
 | 
				
			||||||
static const struct acpi_device_id int340x_thermal_device_ids[] = {
 | 
					static const struct acpi_device_id int340x_thermal_device_ids[] = {
 | 
				
			||||||
	{"INT3400", DO_ENUMERATION },
 | 
						{"INT3400"},
 | 
				
			||||||
	{"INT3401"},
 | 
						{"INT3401", INT3401_DEVICE},
 | 
				
			||||||
	{"INT3402"},
 | 
						{"INT3402"},
 | 
				
			||||||
	{"INT3403"},
 | 
						{"INT3403"},
 | 
				
			||||||
	{"INT3404"},
 | 
						{"INT3404"},
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,10 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev,
 | 
				
			||||||
					const struct acpi_device_id *id)
 | 
										const struct acpi_device_id *id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE)
 | 
					#if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE)
 | 
				
			||||||
	if (id->driver_data == DO_ENUMERATION)
 | 
						acpi_create_platform_device(adev);
 | 
				
			||||||
 | 
					#elif defined(INTEL_SOC_DTS_THERMAL) || defined(INTEL_SOC_DTS_THERMAL_MODULE)
 | 
				
			||||||
 | 
						/* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */
 | 
				
			||||||
 | 
						if (id->driver_data == INT3401_DEVICE)
 | 
				
			||||||
		acpi_create_platform_device(adev);
 | 
							acpi_create_platform_device(adev);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -530,7 +530,7 @@ static int null_add_dev(void)
 | 
				
			||||||
			goto out_cleanup_queues;
 | 
								goto out_cleanup_queues;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		nullb->q = blk_mq_init_queue(&nullb->tag_set);
 | 
							nullb->q = blk_mq_init_queue(&nullb->tag_set);
 | 
				
			||||||
		if (!nullb->q) {
 | 
							if (IS_ERR(nullb->q)) {
 | 
				
			||||||
			rv = -ENOMEM;
 | 
								rv = -ENOMEM;
 | 
				
			||||||
			goto out_cleanup_tags;
 | 
								goto out_cleanup_tags;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,6 +215,7 @@ static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx,
 | 
				
			||||||
	cmd->fn = handler;
 | 
						cmd->fn = handler;
 | 
				
			||||||
	cmd->ctx = ctx;
 | 
						cmd->ctx = ctx;
 | 
				
			||||||
	cmd->aborted = 0;
 | 
						cmd->aborted = 0;
 | 
				
			||||||
 | 
						blk_mq_start_request(blk_mq_rq_from_pdu(cmd));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Special values must be less than 0x1000 */
 | 
					/* Special values must be less than 0x1000 */
 | 
				
			||||||
| 
						 | 
					@ -431,8 +432,13 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx,
 | 
				
			||||||
	if (unlikely(status)) {
 | 
						if (unlikely(status)) {
 | 
				
			||||||
		if (!(status & NVME_SC_DNR || blk_noretry_request(req))
 | 
							if (!(status & NVME_SC_DNR || blk_noretry_request(req))
 | 
				
			||||||
		    && (jiffies - req->start_time) < req->timeout) {
 | 
							    && (jiffies - req->start_time) < req->timeout) {
 | 
				
			||||||
 | 
								unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			blk_mq_requeue_request(req);
 | 
								blk_mq_requeue_request(req);
 | 
				
			||||||
 | 
								spin_lock_irqsave(req->q->queue_lock, flags);
 | 
				
			||||||
 | 
								if (!blk_queue_stopped(req->q))
 | 
				
			||||||
				blk_mq_kick_requeue_list(req->q);
 | 
									blk_mq_kick_requeue_list(req->q);
 | 
				
			||||||
 | 
								spin_unlock_irqrestore(req->q->queue_lock, flags);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		req->errors = nvme_error_status(status);
 | 
							req->errors = nvme_error_status(status);
 | 
				
			||||||
| 
						 | 
					@ -664,8 +670,6 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	blk_mq_start_request(req);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	nvme_set_info(cmd, iod, req_completion);
 | 
						nvme_set_info(cmd, iod, req_completion);
 | 
				
			||||||
	spin_lock_irq(&nvmeq->q_lock);
 | 
						spin_lock_irq(&nvmeq->q_lock);
 | 
				
			||||||
	if (req->cmd_flags & REQ_DISCARD)
 | 
						if (req->cmd_flags & REQ_DISCARD)
 | 
				
			||||||
| 
						 | 
					@ -835,6 +839,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev)
 | 
				
			||||||
	if (IS_ERR(req))
 | 
						if (IS_ERR(req))
 | 
				
			||||||
		return PTR_ERR(req);
 | 
							return PTR_ERR(req);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req->cmd_flags |= REQ_NO_TIMEOUT;
 | 
				
			||||||
	cmd_info = blk_mq_rq_to_pdu(req);
 | 
						cmd_info = blk_mq_rq_to_pdu(req);
 | 
				
			||||||
	nvme_set_info(cmd_info, req, async_req_completion);
 | 
						nvme_set_info(cmd_info, req, async_req_completion);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1016,14 +1021,19 @@ static void nvme_abort_req(struct request *req)
 | 
				
			||||||
	struct nvme_command cmd;
 | 
						struct nvme_command cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!nvmeq->qid || cmd_rq->aborted) {
 | 
						if (!nvmeq->qid || cmd_rq->aborted) {
 | 
				
			||||||
 | 
							unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							spin_lock_irqsave(&dev_list_lock, flags);
 | 
				
			||||||
		if (work_busy(&dev->reset_work))
 | 
							if (work_busy(&dev->reset_work))
 | 
				
			||||||
			return;
 | 
								goto out;
 | 
				
			||||||
		list_del_init(&dev->node);
 | 
							list_del_init(&dev->node);
 | 
				
			||||||
		dev_warn(&dev->pci_dev->dev,
 | 
							dev_warn(&dev->pci_dev->dev,
 | 
				
			||||||
			"I/O %d QID %d timeout, reset controller\n",
 | 
								"I/O %d QID %d timeout, reset controller\n",
 | 
				
			||||||
							req->tag, nvmeq->qid);
 | 
												req->tag, nvmeq->qid);
 | 
				
			||||||
		dev->reset_workfn = nvme_reset_failed_dev;
 | 
							dev->reset_workfn = nvme_reset_failed_dev;
 | 
				
			||||||
		queue_work(nvme_workq, &dev->reset_work);
 | 
							queue_work(nvme_workq, &dev->reset_work);
 | 
				
			||||||
 | 
					 out:
 | 
				
			||||||
 | 
							spin_unlock_irqrestore(&dev_list_lock, flags);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1064,15 +1074,22 @@ static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx,
 | 
				
			||||||
	void *ctx;
 | 
						void *ctx;
 | 
				
			||||||
	nvme_completion_fn fn;
 | 
						nvme_completion_fn fn;
 | 
				
			||||||
	struct nvme_cmd_info *cmd;
 | 
						struct nvme_cmd_info *cmd;
 | 
				
			||||||
	static struct nvme_completion cqe = {
 | 
						struct nvme_completion cqe;
 | 
				
			||||||
		.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1),
 | 
					
 | 
				
			||||||
	};
 | 
						if (!blk_mq_request_started(req))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd = blk_mq_rq_to_pdu(req);
 | 
						cmd = blk_mq_rq_to_pdu(req);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cmd->ctx == CMD_CTX_CANCELLED)
 | 
						if (cmd->ctx == CMD_CTX_CANCELLED)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (blk_queue_dying(req->q))
 | 
				
			||||||
 | 
							cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n",
 | 
						dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n",
 | 
				
			||||||
						req->tag, nvmeq->qid);
 | 
											req->tag, nvmeq->qid);
 | 
				
			||||||
	ctx = cancel_cmd_info(cmd, &fn);
 | 
						ctx = cancel_cmd_info(cmd, &fn);
 | 
				
			||||||
| 
						 | 
					@ -1084,17 +1101,29 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
 | 
				
			||||||
	struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
 | 
						struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req);
 | 
				
			||||||
	struct nvme_queue *nvmeq = cmd->nvmeq;
 | 
						struct nvme_queue *nvmeq = cmd->nvmeq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag,
 | 
					 | 
				
			||||||
							nvmeq->qid);
 | 
					 | 
				
			||||||
	if (nvmeq->dev->initialized)
 | 
					 | 
				
			||||||
		nvme_abort_req(req);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * The aborted req will be completed on receiving the abort req.
 | 
						 * The aborted req will be completed on receiving the abort req.
 | 
				
			||||||
	 * We enable the timer again. If hit twice, it'll cause a device reset,
 | 
						 * We enable the timer again. If hit twice, it'll cause a device reset,
 | 
				
			||||||
	 * as the device then is in a faulty state.
 | 
						 * as the device then is in a faulty state.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	return BLK_EH_RESET_TIMER;
 | 
						int ret = BLK_EH_RESET_TIMER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag,
 | 
				
			||||||
 | 
												nvmeq->qid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irq(&nvmeq->q_lock);
 | 
				
			||||||
 | 
						if (!nvmeq->dev->initialized) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Force cancelled command frees the request, which requires we
 | 
				
			||||||
 | 
							 * return BLK_EH_NOT_HANDLED.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							nvme_cancel_queue_ios(nvmeq->hctx, req, nvmeq, reserved);
 | 
				
			||||||
 | 
							ret = BLK_EH_NOT_HANDLED;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							nvme_abort_req(req);
 | 
				
			||||||
 | 
						spin_unlock_irq(&nvmeq->q_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void nvme_free_queue(struct nvme_queue *nvmeq)
 | 
					static void nvme_free_queue(struct nvme_queue *nvmeq)
 | 
				
			||||||
| 
						 | 
					@ -1131,10 +1160,16 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int nvme_suspend_queue(struct nvme_queue *nvmeq)
 | 
					static int nvme_suspend_queue(struct nvme_queue *nvmeq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector;
 | 
						int vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&nvmeq->q_lock);
 | 
						spin_lock_irq(&nvmeq->q_lock);
 | 
				
			||||||
 | 
						if (nvmeq->cq_vector == -1) {
 | 
				
			||||||
 | 
							spin_unlock_irq(&nvmeq->q_lock);
 | 
				
			||||||
 | 
							return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						vector = nvmeq->dev->entry[nvmeq->cq_vector].vector;
 | 
				
			||||||
	nvmeq->dev->online_queues--;
 | 
						nvmeq->dev->online_queues--;
 | 
				
			||||||
 | 
						nvmeq->cq_vector = -1;
 | 
				
			||||||
	spin_unlock_irq(&nvmeq->q_lock);
 | 
						spin_unlock_irq(&nvmeq->q_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	irq_set_affinity_hint(vector, NULL);
 | 
						irq_set_affinity_hint(vector, NULL);
 | 
				
			||||||
| 
						 | 
					@ -1169,11 +1204,13 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid)
 | 
				
			||||||
		adapter_delete_sq(dev, qid);
 | 
							adapter_delete_sq(dev, qid);
 | 
				
			||||||
		adapter_delete_cq(dev, qid);
 | 
							adapter_delete_cq(dev, qid);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (!qid && dev->admin_q)
 | 
				
			||||||
 | 
							blk_mq_freeze_queue_start(dev->admin_q);
 | 
				
			||||||
	nvme_clear_queue(nvmeq);
 | 
						nvme_clear_queue(nvmeq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
 | 
					static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
 | 
				
			||||||
							int depth, int vector)
 | 
												int depth)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct device *dmadev = &dev->pci_dev->dev;
 | 
						struct device *dmadev = &dev->pci_dev->dev;
 | 
				
			||||||
	struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL);
 | 
						struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL);
 | 
				
			||||||
| 
						 | 
					@ -1199,7 +1236,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
 | 
				
			||||||
	nvmeq->cq_phase = 1;
 | 
						nvmeq->cq_phase = 1;
 | 
				
			||||||
	nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];
 | 
						nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];
 | 
				
			||||||
	nvmeq->q_depth = depth;
 | 
						nvmeq->q_depth = depth;
 | 
				
			||||||
	nvmeq->cq_vector = vector;
 | 
					 | 
				
			||||||
	nvmeq->qid = qid;
 | 
						nvmeq->qid = qid;
 | 
				
			||||||
	dev->queue_count++;
 | 
						dev->queue_count++;
 | 
				
			||||||
	dev->queues[qid] = nvmeq;
 | 
						dev->queues[qid] = nvmeq;
 | 
				
			||||||
| 
						 | 
					@ -1244,6 +1280,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
 | 
				
			||||||
	struct nvme_dev *dev = nvmeq->dev;
 | 
						struct nvme_dev *dev = nvmeq->dev;
 | 
				
			||||||
	int result;
 | 
						int result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nvmeq->cq_vector = qid - 1;
 | 
				
			||||||
	result = adapter_alloc_cq(dev, qid, nvmeq);
 | 
						result = adapter_alloc_cq(dev, qid, nvmeq);
 | 
				
			||||||
	if (result < 0)
 | 
						if (result < 0)
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
| 
						 | 
					@ -1355,6 +1392,14 @@ static struct blk_mq_ops nvme_mq_ops = {
 | 
				
			||||||
	.timeout	= nvme_timeout,
 | 
						.timeout	= nvme_timeout,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nvme_dev_remove_admin(struct nvme_dev *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dev->admin_q && !blk_queue_dying(dev->admin_q)) {
 | 
				
			||||||
 | 
							blk_cleanup_queue(dev->admin_q);
 | 
				
			||||||
 | 
							blk_mq_free_tag_set(&dev->admin_tagset);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int nvme_alloc_admin_tags(struct nvme_dev *dev)
 | 
					static int nvme_alloc_admin_tags(struct nvme_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!dev->admin_q) {
 | 
						if (!dev->admin_q) {
 | 
				
			||||||
| 
						 | 
					@ -1370,21 +1415,20 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dev->admin_q = blk_mq_init_queue(&dev->admin_tagset);
 | 
							dev->admin_q = blk_mq_init_queue(&dev->admin_tagset);
 | 
				
			||||||
		if (!dev->admin_q) {
 | 
							if (IS_ERR(dev->admin_q)) {
 | 
				
			||||||
			blk_mq_free_tag_set(&dev->admin_tagset);
 | 
								blk_mq_free_tag_set(&dev->admin_tagset);
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (!blk_get_queue(dev->admin_q)) {
 | 
				
			||||||
 | 
								nvme_dev_remove_admin(dev);
 | 
				
			||||||
 | 
								return -ENODEV;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							blk_mq_unfreeze_queue(dev->admin_q);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void nvme_free_admin_tags(struct nvme_dev *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (dev->admin_q)
 | 
					 | 
				
			||||||
		blk_mq_free_tag_set(&dev->admin_tagset);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int nvme_configure_admin_queue(struct nvme_dev *dev)
 | 
					static int nvme_configure_admin_queue(struct nvme_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int result;
 | 
						int result;
 | 
				
			||||||
| 
						 | 
					@ -1416,7 +1460,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nvmeq = dev->queues[0];
 | 
						nvmeq = dev->queues[0];
 | 
				
			||||||
	if (!nvmeq) {
 | 
						if (!nvmeq) {
 | 
				
			||||||
		nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0);
 | 
							nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH);
 | 
				
			||||||
		if (!nvmeq)
 | 
							if (!nvmeq)
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1439,18 +1483,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
 | 
				
			||||||
	if (result)
 | 
						if (result)
 | 
				
			||||||
		goto free_nvmeq;
 | 
							goto free_nvmeq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = nvme_alloc_admin_tags(dev);
 | 
						nvmeq->cq_vector = 0;
 | 
				
			||||||
 | 
						result = queue_request_irq(dev, nvmeq, nvmeq->irqname);
 | 
				
			||||||
	if (result)
 | 
						if (result)
 | 
				
			||||||
		goto free_nvmeq;
 | 
							goto free_nvmeq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = queue_request_irq(dev, nvmeq, nvmeq->irqname);
 | 
					 | 
				
			||||||
	if (result)
 | 
					 | 
				
			||||||
		goto free_tags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 free_tags:
 | 
					 | 
				
			||||||
	nvme_free_admin_tags(dev);
 | 
					 | 
				
			||||||
 free_nvmeq:
 | 
					 free_nvmeq:
 | 
				
			||||||
	nvme_free_queues(dev, 0);
 | 
						nvme_free_queues(dev, 0);
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
| 
						 | 
					@ -1944,7 +1983,7 @@ static void nvme_create_io_queues(struct nvme_dev *dev)
 | 
				
			||||||
	unsigned i;
 | 
						unsigned i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = dev->queue_count; i <= dev->max_qid; i++)
 | 
						for (i = dev->queue_count; i <= dev->max_qid; i++)
 | 
				
			||||||
		if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1))
 | 
							if (!nvme_alloc_queue(dev, i, dev->q_depth))
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = dev->online_queues; i <= dev->queue_count - 1; i++)
 | 
						for (i = dev->online_queues; i <= dev->queue_count - 1; i++)
 | 
				
			||||||
| 
						 | 
					@ -2235,13 +2274,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (!schedule_timeout(ADMIN_TIMEOUT) ||
 | 
							if (!schedule_timeout(ADMIN_TIMEOUT) ||
 | 
				
			||||||
					fatal_signal_pending(current)) {
 | 
										fatal_signal_pending(current)) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Disable the controller first since we can't trust it
 | 
				
			||||||
 | 
								 * at this point, but leave the admin queue enabled
 | 
				
			||||||
 | 
								 * until all queue deletion requests are flushed.
 | 
				
			||||||
 | 
								 * FIXME: This may take a while if there are more h/w
 | 
				
			||||||
 | 
								 * queues than admin tags.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
			set_current_state(TASK_RUNNING);
 | 
								set_current_state(TASK_RUNNING);
 | 
				
			||||||
 | 
					 | 
				
			||||||
			nvme_disable_ctrl(dev, readq(&dev->bar->cap));
 | 
								nvme_disable_ctrl(dev, readq(&dev->bar->cap));
 | 
				
			||||||
			nvme_disable_queue(dev, 0);
 | 
								nvme_clear_queue(dev->queues[0]);
 | 
				
			||||||
 | 
					 | 
				
			||||||
			send_sig(SIGKILL, dq->worker->task, 1);
 | 
					 | 
				
			||||||
			flush_kthread_worker(dq->worker);
 | 
								flush_kthread_worker(dq->worker);
 | 
				
			||||||
 | 
								nvme_disable_queue(dev, 0);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2318,7 +2362,6 @@ static void nvme_del_queue_start(struct kthread_work *work)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
 | 
						struct nvme_queue *nvmeq = container_of(work, struct nvme_queue,
 | 
				
			||||||
							cmdinfo.work);
 | 
												cmdinfo.work);
 | 
				
			||||||
	allow_signal(SIGKILL);
 | 
					 | 
				
			||||||
	if (nvme_delete_sq(nvmeq))
 | 
						if (nvme_delete_sq(nvmeq))
 | 
				
			||||||
		nvme_del_queue_end(nvmeq);
 | 
							nvme_del_queue_end(nvmeq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2376,6 +2419,34 @@ static void nvme_dev_list_remove(struct nvme_dev *dev)
 | 
				
			||||||
		kthread_stop(tmp);
 | 
							kthread_stop(tmp);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nvme_freeze_queues(struct nvme_dev *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nvme_ns *ns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(ns, &dev->namespaces, list) {
 | 
				
			||||||
 | 
							blk_mq_freeze_queue_start(ns->queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							spin_lock(ns->queue->queue_lock);
 | 
				
			||||||
 | 
							queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue);
 | 
				
			||||||
 | 
							spin_unlock(ns->queue->queue_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							blk_mq_cancel_requeue_work(ns->queue);
 | 
				
			||||||
 | 
							blk_mq_stop_hw_queues(ns->queue);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nvme_unfreeze_queues(struct nvme_dev *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nvme_ns *ns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry(ns, &dev->namespaces, list) {
 | 
				
			||||||
 | 
							queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue);
 | 
				
			||||||
 | 
							blk_mq_unfreeze_queue(ns->queue);
 | 
				
			||||||
 | 
							blk_mq_start_stopped_hw_queues(ns->queue, true);
 | 
				
			||||||
 | 
							blk_mq_kick_requeue_list(ns->queue);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void nvme_dev_shutdown(struct nvme_dev *dev)
 | 
					static void nvme_dev_shutdown(struct nvme_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -2384,8 +2455,10 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)
 | 
				
			||||||
	dev->initialized = 0;
 | 
						dev->initialized = 0;
 | 
				
			||||||
	nvme_dev_list_remove(dev);
 | 
						nvme_dev_list_remove(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev->bar)
 | 
						if (dev->bar) {
 | 
				
			||||||
 | 
							nvme_freeze_queues(dev);
 | 
				
			||||||
		csts = readl(&dev->bar->csts);
 | 
							csts = readl(&dev->bar->csts);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) {
 | 
						if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) {
 | 
				
			||||||
		for (i = dev->queue_count - 1; i >= 0; i--) {
 | 
							for (i = dev->queue_count - 1; i >= 0; i--) {
 | 
				
			||||||
			struct nvme_queue *nvmeq = dev->queues[i];
 | 
								struct nvme_queue *nvmeq = dev->queues[i];
 | 
				
			||||||
| 
						 | 
					@ -2400,12 +2473,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev)
 | 
				
			||||||
	nvme_dev_unmap(dev);
 | 
						nvme_dev_unmap(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void nvme_dev_remove_admin(struct nvme_dev *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (dev->admin_q && !blk_queue_dying(dev->admin_q))
 | 
					 | 
				
			||||||
		blk_cleanup_queue(dev->admin_q);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void nvme_dev_remove(struct nvme_dev *dev)
 | 
					static void nvme_dev_remove(struct nvme_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nvme_ns *ns;
 | 
						struct nvme_ns *ns;
 | 
				
			||||||
| 
						 | 
					@ -2413,10 +2480,12 @@ static void nvme_dev_remove(struct nvme_dev *dev)
 | 
				
			||||||
	list_for_each_entry(ns, &dev->namespaces, list) {
 | 
						list_for_each_entry(ns, &dev->namespaces, list) {
 | 
				
			||||||
		if (ns->disk->flags & GENHD_FL_UP)
 | 
							if (ns->disk->flags & GENHD_FL_UP)
 | 
				
			||||||
			del_gendisk(ns->disk);
 | 
								del_gendisk(ns->disk);
 | 
				
			||||||
		if (!blk_queue_dying(ns->queue))
 | 
							if (!blk_queue_dying(ns->queue)) {
 | 
				
			||||||
 | 
								blk_mq_abort_requeue_list(ns->queue);
 | 
				
			||||||
			blk_cleanup_queue(ns->queue);
 | 
								blk_cleanup_queue(ns->queue);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int nvme_setup_prp_pools(struct nvme_dev *dev)
 | 
					static int nvme_setup_prp_pools(struct nvme_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2495,6 +2564,7 @@ static void nvme_free_dev(struct kref *kref)
 | 
				
			||||||
	nvme_free_namespaces(dev);
 | 
						nvme_free_namespaces(dev);
 | 
				
			||||||
	nvme_release_instance(dev);
 | 
						nvme_release_instance(dev);
 | 
				
			||||||
	blk_mq_free_tag_set(&dev->tagset);
 | 
						blk_mq_free_tag_set(&dev->tagset);
 | 
				
			||||||
 | 
						blk_put_queue(dev->admin_q);
 | 
				
			||||||
	kfree(dev->queues);
 | 
						kfree(dev->queues);
 | 
				
			||||||
	kfree(dev->entry);
 | 
						kfree(dev->entry);
 | 
				
			||||||
	kfree(dev);
 | 
						kfree(dev);
 | 
				
			||||||
| 
						 | 
					@ -2591,15 +2661,20 @@ static int nvme_dev_start(struct nvme_dev *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nvme_init_queue(dev->queues[0], 0);
 | 
						nvme_init_queue(dev->queues[0], 0);
 | 
				
			||||||
 | 
						result = nvme_alloc_admin_tags(dev);
 | 
				
			||||||
 | 
						if (result)
 | 
				
			||||||
 | 
							goto disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = nvme_setup_io_queues(dev);
 | 
						result = nvme_setup_io_queues(dev);
 | 
				
			||||||
	if (result)
 | 
						if (result)
 | 
				
			||||||
		goto disable;
 | 
							goto free_tags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nvme_set_irq_hints(dev);
 | 
						nvme_set_irq_hints(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 free_tags:
 | 
				
			||||||
 | 
						nvme_dev_remove_admin(dev);
 | 
				
			||||||
 disable:
 | 
					 disable:
 | 
				
			||||||
	nvme_disable_queue(dev, 0);
 | 
						nvme_disable_queue(dev, 0);
 | 
				
			||||||
	nvme_dev_list_remove(dev);
 | 
						nvme_dev_list_remove(dev);
 | 
				
			||||||
| 
						 | 
					@ -2639,6 +2714,9 @@ static int nvme_dev_resume(struct nvme_dev *dev)
 | 
				
			||||||
		dev->reset_workfn = nvme_remove_disks;
 | 
							dev->reset_workfn = nvme_remove_disks;
 | 
				
			||||||
		queue_work(nvme_workq, &dev->reset_work);
 | 
							queue_work(nvme_workq, &dev->reset_work);
 | 
				
			||||||
		spin_unlock(&dev_list_lock);
 | 
							spin_unlock(&dev_list_lock);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							nvme_unfreeze_queues(dev);
 | 
				
			||||||
 | 
							nvme_set_irq_hints(dev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dev->initialized = 1;
 | 
						dev->initialized = 1;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -2776,11 +2854,10 @@ static void nvme_remove(struct pci_dev *pdev)
 | 
				
			||||||
	pci_set_drvdata(pdev, NULL);
 | 
						pci_set_drvdata(pdev, NULL);
 | 
				
			||||||
	flush_work(&dev->reset_work);
 | 
						flush_work(&dev->reset_work);
 | 
				
			||||||
	misc_deregister(&dev->miscdev);
 | 
						misc_deregister(&dev->miscdev);
 | 
				
			||||||
	nvme_dev_remove(dev);
 | 
					 | 
				
			||||||
	nvme_dev_shutdown(dev);
 | 
						nvme_dev_shutdown(dev);
 | 
				
			||||||
 | 
						nvme_dev_remove(dev);
 | 
				
			||||||
	nvme_dev_remove_admin(dev);
 | 
						nvme_dev_remove_admin(dev);
 | 
				
			||||||
	nvme_free_queues(dev, 0);
 | 
						nvme_free_queues(dev, 0);
 | 
				
			||||||
	nvme_free_admin_tags(dev);
 | 
					 | 
				
			||||||
	nvme_release_prp_pools(dev);
 | 
						nvme_release_prp_pools(dev);
 | 
				
			||||||
	kref_put(&dev->kref, nvme_free_dev);
 | 
						kref_put(&dev->kref, nvme_free_dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -638,7 +638,7 @@ static int virtblk_probe(struct virtio_device *vdev)
 | 
				
			||||||
		goto out_put_disk;
 | 
							goto out_put_disk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set);
 | 
						q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set);
 | 
				
			||||||
	if (!q) {
 | 
						if (IS_ERR(q)) {
 | 
				
			||||||
		err = -ENOMEM;
 | 
							err = -ENOMEM;
 | 
				
			||||||
		goto out_free_tags;
 | 
							goto out_free_tags;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1312,6 +1312,9 @@ static int cci_probe(void)
 | 
				
			||||||
	if (!np)
 | 
						if (!np)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!of_device_is_available(np))
 | 
				
			||||||
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cci_config = of_match_node(arm_cci_matches, np)->data;
 | 
						cci_config = of_match_node(arm_cci_matches, np)->data;
 | 
				
			||||||
	if (!cci_config)
 | 
						if (!cci_config)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,7 @@ struct clk_sam9x5_slow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
 | 
					#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct clk *slow_clk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int clk_slow_osc_prepare(struct clk_hw *hw)
 | 
					static int clk_slow_osc_prepare(struct clk_hw *hw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -357,6 +358,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
 | 
				
			||||||
	clk = clk_register(NULL, &slowck->hw);
 | 
						clk = clk_register(NULL, &slowck->hw);
 | 
				
			||||||
	if (IS_ERR(clk))
 | 
						if (IS_ERR(clk))
 | 
				
			||||||
		kfree(slowck);
 | 
							kfree(slowck);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							slow_clk = clk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return clk;
 | 
						return clk;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -433,6 +436,8 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
 | 
				
			||||||
	clk = clk_register(NULL, &slowck->hw);
 | 
						clk = clk_register(NULL, &slowck->hw);
 | 
				
			||||||
	if (IS_ERR(clk))
 | 
						if (IS_ERR(clk))
 | 
				
			||||||
		kfree(slowck);
 | 
							kfree(slowck);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							slow_clk = clk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return clk;
 | 
						return clk;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -465,3 +470,25 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	of_clk_add_provider(np, of_clk_src_simple_get, clk);
 | 
						of_clk_add_provider(np, of_clk_src_simple_get, clk);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * FIXME: All slow clk users are not properly claiming it (get + prepare +
 | 
				
			||||||
 | 
					 * enable) before using it.
 | 
				
			||||||
 | 
					 * If all users properly claiming this clock decide that they don't need it
 | 
				
			||||||
 | 
					 * anymore (or are removed), it is disabled while faulty users are still
 | 
				
			||||||
 | 
					 * requiring it, and the system hangs.
 | 
				
			||||||
 | 
					 * Prevent this clock from being disabled until all users are properly
 | 
				
			||||||
 | 
					 * requesting it.
 | 
				
			||||||
 | 
					 * Once this is done we should remove this function and the slow_clk variable.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int __init of_at91_clk_slow_retain(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!slow_clk)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__clk_get(slow_clk);
 | 
				
			||||||
 | 
						clk_prepare_enable(slow_clk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					arch_initcall(of_at91_clk_slow_retain);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -285,7 +285,6 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = {
 | 
				
			||||||
	{ "pbridge",	"perif",	15, CLK_IGNORE_UNUSED },
 | 
						{ "pbridge",	"perif",	15, CLK_IGNORE_UNUSED },
 | 
				
			||||||
	{ "sdio",	"perif",	16, CLK_IGNORE_UNUSED },
 | 
						{ "sdio",	"perif",	16, CLK_IGNORE_UNUSED },
 | 
				
			||||||
	{ "nfc",	"perif",	18 },
 | 
						{ "nfc",	"perif",	18 },
 | 
				
			||||||
	{ "smemc",	"perif",	19 },
 | 
					 | 
				
			||||||
	{ "pcie",	"perif",	22 },
 | 
						{ "pcie",	"perif",	22 },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,7 +291,7 @@ static const struct of_device_id ppc_clk_ids[] __initconst = {
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct platform_driver ppc_corenet_clk_driver __initdata = {
 | 
					static struct platform_driver ppc_corenet_clk_driver = {
 | 
				
			||||||
	.driver = {
 | 
						.driver = {
 | 
				
			||||||
		.name = "ppc_corenet_clock",
 | 
							.name = "ppc_corenet_clock",
 | 
				
			||||||
		.of_match_table = ppc_clk_ids,
 | 
							.of_match_table = ppc_clk_ids,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1366,7 +1366,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
 | 
				
			||||||
		new_rate = clk->ops->determine_rate(clk->hw, rate,
 | 
							new_rate = clk->ops->determine_rate(clk->hw, rate,
 | 
				
			||||||
						    &best_parent_rate,
 | 
											    &best_parent_rate,
 | 
				
			||||||
						    &parent_hw);
 | 
											    &parent_hw);
 | 
				
			||||||
		parent = parent_hw->clk;
 | 
							parent = parent_hw ? parent_hw->clk : NULL;
 | 
				
			||||||
	} else if (clk->ops->round_rate) {
 | 
						} else if (clk->ops->round_rate) {
 | 
				
			||||||
		new_rate = clk->ops->round_rate(clk->hw, rate,
 | 
							new_rate = clk->ops->round_rate(clk->hw, rate,
 | 
				
			||||||
						&best_parent_rate);
 | 
											&best_parent_rate);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,10 +124,11 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
 | 
						const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
 | 
				
			||||||
	unsigned long alt_prate, alt_div;
 | 
						unsigned long alt_prate, alt_div;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	alt_prate = clk_get_rate(cpuclk->alt_parent);
 | 
						alt_prate = clk_get_rate(cpuclk->alt_parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(cpuclk->lock);
 | 
						spin_lock_irqsave(cpuclk->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If the old parent clock speed is less than the clock speed
 | 
						 * If the old parent clock speed is less than the clock speed
 | 
				
			||||||
| 
						 | 
					@ -164,7 +165,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk,
 | 
				
			||||||
			cpuclk->reg_base + reg_data->core_reg);
 | 
								cpuclk->reg_base + reg_data->core_reg);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock(cpuclk->lock);
 | 
						spin_unlock_irqrestore(cpuclk->lock, flags);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,6 +174,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
 | 
						const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data;
 | 
				
			||||||
	const struct rockchip_cpuclk_rate_table *rate;
 | 
						const struct rockchip_cpuclk_rate_table *rate;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
 | 
						rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate);
 | 
				
			||||||
	if (!rate) {
 | 
						if (!rate) {
 | 
				
			||||||
| 
						 | 
					@ -181,7 +183,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(cpuclk->lock);
 | 
						spin_lock_irqsave(cpuclk->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ndata->old_rate < ndata->new_rate)
 | 
						if (ndata->old_rate < ndata->new_rate)
 | 
				
			||||||
		rockchip_cpuclk_set_dividers(cpuclk, rate);
 | 
							rockchip_cpuclk_set_dividers(cpuclk, rate);
 | 
				
			||||||
| 
						 | 
					@ -201,7 +203,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk,
 | 
				
			||||||
	if (ndata->old_rate > ndata->new_rate)
 | 
						if (ndata->old_rate > ndata->new_rate)
 | 
				
			||||||
		rockchip_cpuclk_set_dividers(cpuclk, rate);
 | 
							rockchip_cpuclk_set_dividers(cpuclk, rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock(cpuclk->lock);
 | 
						spin_unlock_irqrestore(cpuclk->lock, flags);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -210,6 +210,17 @@ PNAME(mux_sclk_hsadc_p)		= { "hsadc_src", "hsadc_frac", "ext_hsadc" };
 | 
				
			||||||
PNAME(mux_mac_p)		= { "gpll", "dpll" };
 | 
					PNAME(mux_mac_p)		= { "gpll", "dpll" };
 | 
				
			||||||
PNAME(mux_sclk_macref_p)	= { "mac_src", "ext_rmii" };
 | 
					PNAME(mux_sclk_macref_p)	= { "mac_src", "ext_rmii" };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct rockchip_pll_clock rk3066_pll_clks[] __initdata = {
 | 
				
			||||||
 | 
						[apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
 | 
				
			||||||
 | 
							     RK2928_MODE_CON, 0, 5, 0, rk3188_pll_rates),
 | 
				
			||||||
 | 
						[dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
 | 
				
			||||||
 | 
							     RK2928_MODE_CON, 4, 4, 0, NULL),
 | 
				
			||||||
 | 
						[cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8),
 | 
				
			||||||
 | 
							     RK2928_MODE_CON, 8, 6, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates),
 | 
				
			||||||
 | 
						[gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
 | 
				
			||||||
 | 
							     RK2928_MODE_CON, 12, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = {
 | 
					static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = {
 | 
				
			||||||
	[apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
 | 
						[apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
 | 
				
			||||||
		     RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates),
 | 
							     RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates),
 | 
				
			||||||
| 
						 | 
					@ -427,11 +438,11 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 | 
				
			||||||
	/* hclk_peri gates */
 | 
						/* hclk_peri gates */
 | 
				
			||||||
	GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
 | 
						GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
 | 
				
			||||||
	GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS),
 | 
						GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS),
 | 
				
			||||||
	GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS),
 | 
						GATE(0, "hclk_emem_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 7, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
 | 
						GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
 | 
						GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
 | 
				
			||||||
	GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS),
 | 
						GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS),
 | 
						GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS),
 | 
						GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS),
 | 
						GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
 | 
						GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
 | 
				
			||||||
| 
						 | 
					@ -592,7 +603,8 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 | 
				
			||||||
	GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
 | 
						GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
 | 
				
			||||||
	GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 | 
						GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
 | 
						GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
 | 
				
			||||||
 | 
								RK2928_CLKGATE_CON(5), 14, GFLAGS),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
 | 
						GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -680,7 +692,8 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
 | 
				
			||||||
	GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 | 
						GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 | 
				
			||||||
	GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
 | 
						GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
 | 
						GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
 | 
				
			||||||
 | 
								RK2928_CLKGATE_CON(7), 3, GFLAGS),
 | 
				
			||||||
	GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
 | 
						GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
 | 
						GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
 | 
				
			||||||
| 
						 | 
					@ -735,8 +748,8 @@ static void __init rk3188_common_clk_init(struct device_node *np)
 | 
				
			||||||
static void __init rk3066a_clk_init(struct device_node *np)
 | 
					static void __init rk3066a_clk_init(struct device_node *np)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	rk3188_common_clk_init(np);
 | 
						rk3188_common_clk_init(np);
 | 
				
			||||||
	rockchip_clk_register_plls(rk3188_pll_clks,
 | 
						rockchip_clk_register_plls(rk3066_pll_clks,
 | 
				
			||||||
				   ARRAY_SIZE(rk3188_pll_clks),
 | 
									   ARRAY_SIZE(rk3066_pll_clks),
 | 
				
			||||||
				   RK3066_GRF_SOC_STATUS);
 | 
									   RK3066_GRF_SOC_STATUS);
 | 
				
			||||||
	rockchip_clk_register_branches(rk3066a_clk_branches,
 | 
						rockchip_clk_register_branches(rk3066a_clk_branches,
 | 
				
			||||||
				  ARRAY_SIZE(rk3066a_clk_branches));
 | 
									  ARRAY_SIZE(rk3066a_clk_branches));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,20 +145,20 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = {
 | 
					static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = {
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
	RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4),
 | 
						RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {
 | 
					static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1505,7 +1505,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
 | 
				
			||||||
	dw->regs = chip->regs;
 | 
						dw->regs = chip->regs;
 | 
				
			||||||
	chip->dw = dw;
 | 
						chip->dw = dw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pm_runtime_enable(chip->dev);
 | 
					 | 
				
			||||||
	pm_runtime_get_sync(chip->dev);
 | 
						pm_runtime_get_sync(chip->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
 | 
						dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
 | 
				
			||||||
| 
						 | 
					@ -1703,7 +1702,6 @@ int dw_dma_remove(struct dw_dma_chip *chip)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pm_runtime_put_sync_suspend(chip->dev);
 | 
						pm_runtime_put_sync_suspend(chip->dev);
 | 
				
			||||||
	pm_runtime_disable(chip->dev);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(dw_dma_remove);
 | 
					EXPORT_SYMBOL_GPL(dw_dma_remove);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/device.h>
 | 
					#include <linux/device.h>
 | 
				
			||||||
#include <linux/clk.h>
 | 
					#include <linux/clk.h>
 | 
				
			||||||
 | 
					#include <linux/pm_runtime.h>
 | 
				
			||||||
#include <linux/platform_device.h>
 | 
					#include <linux/platform_device.h>
 | 
				
			||||||
#include <linux/dmaengine.h>
 | 
					#include <linux/dmaengine.h>
 | 
				
			||||||
#include <linux/dma-mapping.h>
 | 
					#include <linux/dma-mapping.h>
 | 
				
			||||||
| 
						 | 
					@ -185,6 +186,8 @@ static int dw_probe(struct platform_device *pdev)
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pm_runtime_enable(&pdev->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = dw_dma_probe(chip, pdata);
 | 
						err = dw_dma_probe(chip, pdata);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto err_dw_dma_probe;
 | 
							goto err_dw_dma_probe;
 | 
				
			||||||
| 
						 | 
					@ -205,6 +208,7 @@ static int dw_probe(struct platform_device *pdev)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_dw_dma_probe:
 | 
					err_dw_dma_probe:
 | 
				
			||||||
 | 
						pm_runtime_disable(&pdev->dev);
 | 
				
			||||||
	clk_disable_unprepare(chip->clk);
 | 
						clk_disable_unprepare(chip->clk);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -217,6 +221,7 @@ static int dw_remove(struct platform_device *pdev)
 | 
				
			||||||
		of_dma_controller_free(pdev->dev.of_node);
 | 
							of_dma_controller_free(pdev->dev.of_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dw_dma_remove(chip);
 | 
						dw_dma_remove(chip);
 | 
				
			||||||
 | 
						pm_runtime_disable(&pdev->dev);
 | 
				
			||||||
	clk_disable_unprepare(chip->clk);
 | 
						clk_disable_unprepare(chip->clk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,13 +47,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DLN2_GPIO_MAX_PINS 32
 | 
					#define DLN2_GPIO_MAX_PINS 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dln2_irq_work {
 | 
					 | 
				
			||||||
	struct work_struct work;
 | 
					 | 
				
			||||||
	struct dln2_gpio *dln2;
 | 
					 | 
				
			||||||
	int pin;
 | 
					 | 
				
			||||||
	int type;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct dln2_gpio {
 | 
					struct dln2_gpio {
 | 
				
			||||||
	struct platform_device *pdev;
 | 
						struct platform_device *pdev;
 | 
				
			||||||
	struct gpio_chip gpio;
 | 
						struct gpio_chip gpio;
 | 
				
			||||||
| 
						 | 
					@ -64,10 +57,12 @@ struct dln2_gpio {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS);
 | 
						DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS);
 | 
						/* active IRQs - not synced to hardware */
 | 
				
			||||||
	DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS);
 | 
						DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS);
 | 
				
			||||||
	DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS);
 | 
						/* active IRQS - synced to hardware */
 | 
				
			||||||
	struct dln2_irq_work *irq_work;
 | 
						DECLARE_BITMAP(enabled_irqs, DLN2_GPIO_MAX_PINS);
 | 
				
			||||||
 | 
						int irq_type[DLN2_GPIO_MAX_PINS];
 | 
				
			||||||
 | 
						struct mutex irq_lock;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct dln2_gpio_pin {
 | 
					struct dln2_gpio_pin {
 | 
				
			||||||
| 
						 | 
					@ -141,7 +136,7 @@ static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin)
 | 
				
			||||||
	return !!ret;
 | 
						return !!ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2,
 | 
					static int dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2,
 | 
				
			||||||
				     unsigned int pin, int value)
 | 
									     unsigned int pin, int value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dln2_gpio_pin_val req = {
 | 
						struct dln2_gpio_pin_val req = {
 | 
				
			||||||
| 
						 | 
					@ -149,7 +144,7 @@ static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2,
 | 
				
			||||||
		.value = value,
 | 
							.value = value,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req,
 | 
						return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req,
 | 
				
			||||||
				sizeof(req));
 | 
									sizeof(req));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,6 +262,13 @@ static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 | 
				
			||||||
static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 | 
					static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 | 
				
			||||||
				      int value)
 | 
									      int value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio);
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = dln2_gpio_pin_set_out_val(dln2, offset, value);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT);
 | 
						return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -297,36 +299,13 @@ static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin,
 | 
				
			||||||
				&req, sizeof(req));
 | 
									&req, sizeof(req));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dln2_irq_work(struct work_struct *w)
 | 
					static void dln2_irq_unmask(struct irq_data *irqd)
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct dln2_irq_work *iw = container_of(w, struct dln2_irq_work, work);
 | 
					 | 
				
			||||||
	struct dln2_gpio *dln2 = iw->dln2;
 | 
					 | 
				
			||||||
	u8 type = iw->type & DLN2_GPIO_EVENT_MASK;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (test_bit(iw->pin, dln2->irqs_enabled))
 | 
					 | 
				
			||||||
		dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void dln2_irq_enable(struct irq_data *irqd)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 | 
						struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 | 
				
			||||||
	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
						struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
				
			||||||
	int pin = irqd_to_hwirq(irqd);
 | 
						int pin = irqd_to_hwirq(irqd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	set_bit(pin, dln2->irqs_enabled);
 | 
						set_bit(pin, dln2->unmasked_irqs);
 | 
				
			||||||
	schedule_work(&dln2->irq_work[pin].work);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void dln2_irq_disable(struct irq_data *irqd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 | 
					 | 
				
			||||||
	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
					 | 
				
			||||||
	int pin = irqd_to_hwirq(irqd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	clear_bit(pin, dln2->irqs_enabled);
 | 
					 | 
				
			||||||
	schedule_work(&dln2->irq_work[pin].work);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dln2_irq_mask(struct irq_data *irqd)
 | 
					static void dln2_irq_mask(struct irq_data *irqd)
 | 
				
			||||||
| 
						 | 
					@ -335,27 +314,7 @@ static void dln2_irq_mask(struct irq_data *irqd)
 | 
				
			||||||
	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
						struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
				
			||||||
	int pin = irqd_to_hwirq(irqd);
 | 
						int pin = irqd_to_hwirq(irqd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	set_bit(pin, dln2->irqs_masked);
 | 
						clear_bit(pin, dln2->unmasked_irqs);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void dln2_irq_unmask(struct irq_data *irqd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 | 
					 | 
				
			||||||
	struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
					 | 
				
			||||||
	struct device *dev = dln2->gpio.dev;
 | 
					 | 
				
			||||||
	int pin = irqd_to_hwirq(irqd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (test_and_clear_bit(pin, dln2->irqs_pending)) {
 | 
					 | 
				
			||||||
		int irq;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		irq = irq_find_mapping(dln2->gpio.irqdomain, pin);
 | 
					 | 
				
			||||||
		if (!irq) {
 | 
					 | 
				
			||||||
			dev_err(dev, "pin %d not mapped to IRQ\n", pin);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		generic_handle_irq(irq);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 | 
					static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 | 
				
			||||||
| 
						 | 
					@ -366,19 +325,19 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (type) {
 | 
						switch (type) {
 | 
				
			||||||
	case IRQ_TYPE_LEVEL_HIGH:
 | 
						case IRQ_TYPE_LEVEL_HIGH:
 | 
				
			||||||
		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_HIGH;
 | 
							dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_HIGH;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IRQ_TYPE_LEVEL_LOW:
 | 
						case IRQ_TYPE_LEVEL_LOW:
 | 
				
			||||||
		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_LOW;
 | 
							dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_LOW;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IRQ_TYPE_EDGE_BOTH:
 | 
						case IRQ_TYPE_EDGE_BOTH:
 | 
				
			||||||
		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE;
 | 
							dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IRQ_TYPE_EDGE_RISING:
 | 
						case IRQ_TYPE_EDGE_RISING:
 | 
				
			||||||
		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_RISING;
 | 
							dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_RISING;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case IRQ_TYPE_EDGE_FALLING:
 | 
						case IRQ_TYPE_EDGE_FALLING:
 | 
				
			||||||
		dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_FALLING;
 | 
							dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_FALLING;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -387,13 +346,50 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dln2_irq_bus_lock(struct irq_data *irqd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 | 
				
			||||||
 | 
						struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&dln2->irq_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dln2_irq_bus_unlock(struct irq_data *irqd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 | 
				
			||||||
 | 
						struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio);
 | 
				
			||||||
 | 
						int pin = irqd_to_hwirq(irqd);
 | 
				
			||||||
 | 
						int enabled, unmasked;
 | 
				
			||||||
 | 
						unsigned type;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enabled = test_bit(pin, dln2->enabled_irqs);
 | 
				
			||||||
 | 
						unmasked = test_bit(pin, dln2->unmasked_irqs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enabled != unmasked) {
 | 
				
			||||||
 | 
							if (unmasked) {
 | 
				
			||||||
 | 
								type = dln2->irq_type[pin] & DLN2_GPIO_EVENT_MASK;
 | 
				
			||||||
 | 
								set_bit(pin, dln2->enabled_irqs);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								type = DLN2_GPIO_EVENT_NONE;
 | 
				
			||||||
 | 
								clear_bit(pin, dln2->enabled_irqs);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								dev_err(dln2->gpio.dev, "failed to set event\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&dln2->irq_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct irq_chip dln2_gpio_irqchip = {
 | 
					static struct irq_chip dln2_gpio_irqchip = {
 | 
				
			||||||
	.name = "dln2-irq",
 | 
						.name = "dln2-irq",
 | 
				
			||||||
	.irq_enable = dln2_irq_enable,
 | 
					 | 
				
			||||||
	.irq_disable = dln2_irq_disable,
 | 
					 | 
				
			||||||
	.irq_mask = dln2_irq_mask,
 | 
						.irq_mask = dln2_irq_mask,
 | 
				
			||||||
	.irq_unmask = dln2_irq_unmask,
 | 
						.irq_unmask = dln2_irq_unmask,
 | 
				
			||||||
	.irq_set_type = dln2_irq_set_type,
 | 
						.irq_set_type = dln2_irq_set_type,
 | 
				
			||||||
 | 
						.irq_bus_lock = dln2_irq_bus_lock,
 | 
				
			||||||
 | 
						.irq_bus_sync_unlock = dln2_irq_bus_unlock,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 | 
					static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 | 
				
			||||||
| 
						 | 
					@ -425,14 +421,7 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!test_bit(pin, dln2->irqs_enabled))
 | 
						switch (dln2->irq_type[pin]) {
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	if (test_bit(pin, dln2->irqs_masked)) {
 | 
					 | 
				
			||||||
		set_bit(pin, dln2->irqs_pending);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (dln2->irq_work[pin].type) {
 | 
					 | 
				
			||||||
	case DLN2_GPIO_EVENT_CHANGE_RISING:
 | 
						case DLN2_GPIO_EVENT_CHANGE_RISING:
 | 
				
			||||||
		if (event->value)
 | 
							if (event->value)
 | 
				
			||||||
			generic_handle_irq(irq);
 | 
								generic_handle_irq(irq);
 | 
				
			||||||
| 
						 | 
					@ -451,7 +440,7 @@ static int dln2_gpio_probe(struct platform_device *pdev)
 | 
				
			||||||
	struct dln2_gpio *dln2;
 | 
						struct dln2_gpio *dln2;
 | 
				
			||||||
	struct device *dev = &pdev->dev;
 | 
						struct device *dev = &pdev->dev;
 | 
				
			||||||
	int pins;
 | 
						int pins;
 | 
				
			||||||
	int i, ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pins = dln2_gpio_get_pin_count(pdev);
 | 
						pins = dln2_gpio_get_pin_count(pdev);
 | 
				
			||||||
	if (pins < 0) {
 | 
						if (pins < 0) {
 | 
				
			||||||
| 
						 | 
					@ -467,15 +456,7 @@ static int dln2_gpio_probe(struct platform_device *pdev)
 | 
				
			||||||
	if (!dln2)
 | 
						if (!dln2)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dln2->irq_work = devm_kcalloc(&pdev->dev, pins,
 | 
						mutex_init(&dln2->irq_lock);
 | 
				
			||||||
				      sizeof(struct dln2_irq_work), GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (!dln2->irq_work)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
	for (i = 0; i < pins; i++) {
 | 
					 | 
				
			||||||
		INIT_WORK(&dln2->irq_work[i].work, dln2_irq_work);
 | 
					 | 
				
			||||||
		dln2->irq_work[i].pin = i;
 | 
					 | 
				
			||||||
		dln2->irq_work[i].dln2 = dln2;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dln2->pdev = pdev;
 | 
						dln2->pdev = pdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,11 +510,8 @@ out:
 | 
				
			||||||
static int dln2_gpio_remove(struct platform_device *pdev)
 | 
					static int dln2_gpio_remove(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dln2_gpio *dln2 = platform_get_drvdata(pdev);
 | 
						struct dln2_gpio *dln2 = platform_get_drvdata(pdev);
 | 
				
			||||||
	int i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV);
 | 
						dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV);
 | 
				
			||||||
	for (i = 0; i < dln2->gpio.ngpio; i++)
 | 
					 | 
				
			||||||
		flush_work(&dln2->irq_work[i].work);
 | 
					 | 
				
			||||||
	gpiochip_remove(&dln2->gpio);
 | 
						gpiochip_remove(&dln2->gpio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -441,6 +441,7 @@ static int grgpio_probe(struct platform_device *ofdev)
 | 
				
			||||||
	err = gpiochip_add(gc);
 | 
						err = gpiochip_add(gc);
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		dev_err(&ofdev->dev, "Could not add gpiochip\n");
 | 
							dev_err(&ofdev->dev, "Could not add gpiochip\n");
 | 
				
			||||||
 | 
							if (priv->domain)
 | 
				
			||||||
			irq_domain_remove(priv->domain);
 | 
								irq_domain_remove(priv->domain);
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,9 +143,15 @@ static int ad799x_write_config(struct ad799x_state *st, u16 val)
 | 
				
			||||||
	case ad7998:
 | 
						case ad7998:
 | 
				
			||||||
		return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG,
 | 
							return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG,
 | 
				
			||||||
			val);
 | 
								val);
 | 
				
			||||||
	default:
 | 
						case ad7992:
 | 
				
			||||||
 | 
						case ad7993:
 | 
				
			||||||
 | 
						case ad7994:
 | 
				
			||||||
		return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG,
 | 
							return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG,
 | 
				
			||||||
			val);
 | 
								val);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* Will be written when doing a conversion */
 | 
				
			||||||
 | 
							st->config = val;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,8 +161,13 @@ static int ad799x_read_config(struct ad799x_state *st)
 | 
				
			||||||
	case ad7997:
 | 
						case ad7997:
 | 
				
			||||||
	case ad7998:
 | 
						case ad7998:
 | 
				
			||||||
		return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG);
 | 
							return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG);
 | 
				
			||||||
	default:
 | 
						case ad7992:
 | 
				
			||||||
 | 
						case ad7993:
 | 
				
			||||||
 | 
						case ad7994:
 | 
				
			||||||
		return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG);
 | 
							return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG);
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							/* No readback support */
 | 
				
			||||||
 | 
							return st->config;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -449,6 +449,9 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
 | 
				
			||||||
	if (val2 == NULL)
 | 
						if (val2 == NULL)
 | 
				
			||||||
		val2 = &unused;
 | 
							val2 = &unused;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(!iio_channel_has_info(chan->channel, info))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chan->indio_dev->info->read_raw_multi) {
 | 
						if (chan->indio_dev->info->read_raw_multi) {
 | 
				
			||||||
		ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,
 | 
							ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,
 | 
				
			||||||
					chan->channel, INDIO_MAX_RAW_ELEMENTS,
 | 
										chan->channel, INDIO_MAX_RAW_ELEMENTS,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4880,7 +4880,7 @@ static void sig_ind(PLCI *plci)
 | 
				
			||||||
	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
 | 
						byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
 | 
				
			||||||
	byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
 | 
						byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
 | 
				
			||||||
	byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
 | 
						byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
 | 
				
			||||||
	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
 | 
						byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";
 | 
				
			||||||
	byte force_mt_info = false;
 | 
						byte force_mt_info = false;
 | 
				
			||||||
	byte dir;
 | 
						byte dir;
 | 
				
			||||||
	dword d;
 | 
						dword d;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,18 +330,18 @@ create_netxbig_led(struct platform_device *pdev,
 | 
				
			||||||
	led_dat->sata = 0;
 | 
						led_dat->sata = 0;
 | 
				
			||||||
	led_dat->cdev.brightness = LED_OFF;
 | 
						led_dat->cdev.brightness = LED_OFF;
 | 
				
			||||||
	led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 | 
						led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * If available, expose the SATA activity blink capability through
 | 
					 | 
				
			||||||
	 * a "sata" sysfs attribute.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
 | 
					 | 
				
			||||||
		led_dat->cdev.groups = netxbig_led_groups;
 | 
					 | 
				
			||||||
	led_dat->mode_addr = template->mode_addr;
 | 
						led_dat->mode_addr = template->mode_addr;
 | 
				
			||||||
	led_dat->mode_val = template->mode_val;
 | 
						led_dat->mode_val = template->mode_val;
 | 
				
			||||||
	led_dat->bright_addr = template->bright_addr;
 | 
						led_dat->bright_addr = template->bright_addr;
 | 
				
			||||||
	led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
 | 
						led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
 | 
				
			||||||
	led_dat->timer = pdata->timer;
 | 
						led_dat->timer = pdata->timer;
 | 
				
			||||||
	led_dat->num_timer = pdata->num_timer;
 | 
						led_dat->num_timer = pdata->num_timer;
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If available, expose the SATA activity blink capability through
 | 
				
			||||||
 | 
						 * a "sata" sysfs attribute.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
 | 
				
			||||||
 | 
							led_dat->cdev.groups = netxbig_led_groups;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return led_classdev_register(&pdev->dev, &led_dat->cdev);
 | 
						return led_classdev_register(&pdev->dev, &led_dat->cdev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
#define PCI_DEVICE_ID_MEN_CHAMELEON	0x4d45
 | 
					#define PCI_DEVICE_ID_MEN_CHAMELEON	0x4d45
 | 
				
			||||||
#define CHAMELEON_FILENAME_LEN		12
 | 
					#define CHAMELEON_FILENAME_LEN		12
 | 
				
			||||||
#define CHAMELEONV2_MAGIC		0xabce
 | 
					#define CHAMELEONV2_MAGIC		0xabce
 | 
				
			||||||
 | 
					#define CHAM_HEADER_SIZE		0x200
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum chameleon_descriptor_type {
 | 
					enum chameleon_descriptor_type {
 | 
				
			||||||
	CHAMELEON_DTYPE_GENERAL = 0x0,
 | 
						CHAMELEON_DTYPE_GENERAL = 0x0,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct priv {
 | 
					struct priv {
 | 
				
			||||||
	struct mcb_bus *bus;
 | 
						struct mcb_bus *bus;
 | 
				
			||||||
 | 
						phys_addr_t mapbase;
 | 
				
			||||||
	void __iomem *base;
 | 
						void __iomem *base;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,8 +32,8 @@ static int mcb_pci_get_irq(struct mcb_device *mdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 | 
					static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct resource *res;
 | 
				
			||||||
	struct priv *priv;
 | 
						struct priv *priv;
 | 
				
			||||||
	phys_addr_t mapbase;
 | 
					 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	int num_cells;
 | 
						int num_cells;
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
| 
						 | 
					@ -47,19 +48,21 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mapbase = pci_resource_start(pdev, 0);
 | 
						priv->mapbase = pci_resource_start(pdev, 0);
 | 
				
			||||||
	if (!mapbase) {
 | 
						if (!priv->mapbase) {
 | 
				
			||||||
		dev_err(&pdev->dev, "No PCI resource\n");
 | 
							dev_err(&pdev->dev, "No PCI resource\n");
 | 
				
			||||||
		goto err_start;
 | 
							goto err_start;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = pci_request_region(pdev, 0, KBUILD_MODNAME);
 | 
						res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE,
 | 
				
			||||||
	if (ret) {
 | 
									 KBUILD_MODNAME);
 | 
				
			||||||
		dev_err(&pdev->dev, "Failed to request PCI BARs\n");
 | 
						if (IS_ERR(res)) {
 | 
				
			||||||
 | 
							dev_err(&pdev->dev, "Failed to request PCI memory\n");
 | 
				
			||||||
 | 
							ret = PTR_ERR(res);
 | 
				
			||||||
		goto err_start;
 | 
							goto err_start;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->base = pci_iomap(pdev, 0, 0);
 | 
						priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE);
 | 
				
			||||||
	if (!priv->base) {
 | 
						if (!priv->base) {
 | 
				
			||||||
		dev_err(&pdev->dev, "Cannot ioremap\n");
 | 
							dev_err(&pdev->dev, "Cannot ioremap\n");
 | 
				
			||||||
		ret = -ENOMEM;
 | 
							ret = -ENOMEM;
 | 
				
			||||||
| 
						 | 
					@ -84,7 +87,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->bus->get_irq = mcb_pci_get_irq;
 | 
						priv->bus->get_irq = mcb_pci_get_irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = chameleon_parse_cells(priv->bus, mapbase, priv->base);
 | 
						ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		goto err_drvdata;
 | 
							goto err_drvdata;
 | 
				
			||||||
	num_cells = ret;
 | 
						num_cells = ret;
 | 
				
			||||||
| 
						 | 
					@ -93,8 +96,10 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mcb_bus_add_devices(priv->bus);
 | 
						mcb_bus_add_devices(priv->bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_drvdata:
 | 
					err_drvdata:
 | 
				
			||||||
	pci_iounmap(pdev, priv->base);
 | 
						iounmap(priv->base);
 | 
				
			||||||
err_ioremap:
 | 
					err_ioremap:
 | 
				
			||||||
	pci_release_region(pdev, 0);
 | 
						pci_release_region(pdev, 0);
 | 
				
			||||||
err_start:
 | 
					err_start:
 | 
				
			||||||
| 
						 | 
					@ -107,6 +112,10 @@ static void mcb_pci_remove(struct pci_dev *pdev)
 | 
				
			||||||
	struct priv *priv = pci_get_drvdata(pdev);
 | 
						struct priv *priv = pci_get_drvdata(pdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mcb_release_bus(priv->bus);
 | 
						mcb_release_bus(priv->bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iounmap(priv->base);
 | 
				
			||||||
 | 
						release_region(priv->mapbase, CHAM_HEADER_SIZE);
 | 
				
			||||||
 | 
						pci_disable_device(pdev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct pci_device_id mcb_pci_tbl[] = {
 | 
					static const struct pci_device_id mcb_pci_tbl[] = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,6 +100,46 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cxl_context *ctx = vma->vm_file->private_data;
 | 
				
			||||||
 | 
						unsigned long address = (unsigned long)vmf->virtual_address;
 | 
				
			||||||
 | 
						u64 area, offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						offset = vmf->pgoff << PAGE_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n",
 | 
				
			||||||
 | 
								__func__, ctx->pe, address, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
 | 
				
			||||||
 | 
							area = ctx->afu->psn_phys;
 | 
				
			||||||
 | 
							if (offset > ctx->afu->adapter->ps_size)
 | 
				
			||||||
 | 
								return VM_FAULT_SIGBUS;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							area = ctx->psn_phys;
 | 
				
			||||||
 | 
							if (offset > ctx->psn_size)
 | 
				
			||||||
 | 
								return VM_FAULT_SIGBUS;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&ctx->status_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->status != STARTED) {
 | 
				
			||||||
 | 
							mutex_unlock(&ctx->status_mutex);
 | 
				
			||||||
 | 
							pr_devel("%s: Context not started, failing problem state access\n", __func__);
 | 
				
			||||||
 | 
							return VM_FAULT_SIGBUS;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&ctx->status_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return VM_FAULT_NOPAGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct vm_operations_struct cxl_mmap_vmops = {
 | 
				
			||||||
 | 
						.fault = cxl_mmap_fault,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Map a per-context mmio space into the given vma.
 | 
					 * Map a per-context mmio space into the given vma.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -108,11 +148,7 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
 | 
				
			||||||
	u64 len = vma->vm_end - vma->vm_start;
 | 
						u64 len = vma->vm_end - vma->vm_start;
 | 
				
			||||||
	len = min(len, ctx->psn_size);
 | 
						len = min(len, ctx->psn_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
 | 
						if (ctx->afu->current_mode != CXL_MODE_DEDICATED) {
 | 
				
			||||||
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 | 
					 | 
				
			||||||
		return vm_iomap_memory(vma, ctx->afu->psn_phys, ctx->afu->adapter->ps_size);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* make sure there is a valid per process space for this AFU */
 | 
							/* make sure there is a valid per process space for this AFU */
 | 
				
			||||||
		if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) {
 | 
							if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) {
 | 
				
			||||||
			pr_devel("AFU doesn't support mmio space\n");
 | 
								pr_devel("AFU doesn't support mmio space\n");
 | 
				
			||||||
| 
						 | 
					@ -122,12 +158,15 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
 | 
				
			||||||
		/* Can't mmap until the AFU is enabled */
 | 
							/* Can't mmap until the AFU is enabled */
 | 
				
			||||||
		if (!ctx->afu->enabled)
 | 
							if (!ctx->afu->enabled)
 | 
				
			||||||
			return -EBUSY;
 | 
								return -EBUSY;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__,
 | 
						pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__,
 | 
				
			||||||
		 ctx->psn_phys, ctx->pe , ctx->master);
 | 
							 ctx->psn_phys, ctx->pe , ctx->master);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vma->vm_flags |= VM_IO | VM_PFNMAP;
 | 
				
			||||||
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 | 
						vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 | 
				
			||||||
	return vm_iomap_memory(vma, ctx->psn_phys, len);
 | 
						vma->vm_ops = &cxl_mmap_vmops;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -150,12 +189,6 @@ static void __detach_context(struct cxl_context *ctx)
 | 
				
			||||||
	afu_release_irqs(ctx);
 | 
						afu_release_irqs(ctx);
 | 
				
			||||||
	flush_work(&ctx->fault_work); /* Only needed for dedicated process */
 | 
						flush_work(&ctx->fault_work); /* Only needed for dedicated process */
 | 
				
			||||||
	wake_up_all(&ctx->wq);
 | 
						wake_up_all(&ctx->wq);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Release Problem State Area mapping */
 | 
					 | 
				
			||||||
	mutex_lock(&ctx->mapping_lock);
 | 
					 | 
				
			||||||
	if (ctx->mapping)
 | 
					 | 
				
			||||||
		unmap_mapping_range(ctx->mapping, 0, 0, 1);
 | 
					 | 
				
			||||||
	mutex_unlock(&ctx->mapping_lock);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -184,6 +217,17 @@ void cxl_context_detach_all(struct cxl_afu *afu)
 | 
				
			||||||
		 * created and torn down after the IDR removed
 | 
							 * created and torn down after the IDR removed
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		__detach_context(ctx);
 | 
							__detach_context(ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * We are force detaching - remove any active PSA mappings so
 | 
				
			||||||
 | 
							 * userspace cannot interfere with the card if it comes back.
 | 
				
			||||||
 | 
							 * Easiest way to exercise this is to unbind and rebind the
 | 
				
			||||||
 | 
							 * driver via sysfs while it is in use.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							mutex_lock(&ctx->mapping_lock);
 | 
				
			||||||
 | 
							if (ctx->mapping)
 | 
				
			||||||
 | 
								unmap_mapping_range(ctx->mapping, 0, 0, 1);
 | 
				
			||||||
 | 
							mutex_unlock(&ctx->mapping_lock);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&afu->contexts_lock);
 | 
						mutex_unlock(&afu->contexts_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,18 +140,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr_devel("%s: pe: %i\n", __func__, ctx->pe);
 | 
						pr_devel("%s: pe: %i\n", __func__, ctx->pe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&ctx->status_mutex);
 | 
						/* Do this outside the status_mutex to avoid a circular dependency with
 | 
				
			||||||
	if (ctx->status != OPENED) {
 | 
						 * the locking in cxl_mmap_fault() */
 | 
				
			||||||
		rc = -EIO;
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (copy_from_user(&work, uwork,
 | 
						if (copy_from_user(&work, uwork,
 | 
				
			||||||
			   sizeof(struct cxl_ioctl_start_work))) {
 | 
								   sizeof(struct cxl_ioctl_start_work))) {
 | 
				
			||||||
		rc = -EFAULT;
 | 
							rc = -EFAULT;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&ctx->status_mutex);
 | 
				
			||||||
 | 
						if (ctx->status != OPENED) {
 | 
				
			||||||
 | 
							rc = -EIO;
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * if any of the reserved fields are set or any of the unused
 | 
						 * if any of the reserved fields are set or any of the unused
 | 
				
			||||||
	 * flags are set it's invalid
 | 
						 * flags are set it's invalid
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -234,6 +234,18 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
 | 
				
			||||||
	struct mei_me_hw *hw = to_me_hw(dev);
 | 
						struct mei_me_hw *hw = to_me_hw(dev);
 | 
				
			||||||
	u32 hcsr = mei_hcsr_read(hw);
 | 
						u32 hcsr = mei_hcsr_read(hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* H_RST may be found lit before reset is started,
 | 
				
			||||||
 | 
						 * for example if preceding reset flow hasn't completed.
 | 
				
			||||||
 | 
						 * In that case asserting H_RST will be ignored, therefore
 | 
				
			||||||
 | 
						 * we need to clean H_RST bit to start a successful reset sequence.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if ((hcsr & H_RST) == H_RST) {
 | 
				
			||||||
 | 
							dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr);
 | 
				
			||||||
 | 
							hcsr &= ~H_RST;
 | 
				
			||||||
 | 
							mei_me_reg_write(hw, H_CSR, hcsr);
 | 
				
			||||||
 | 
							hcsr = mei_hcsr_read(hw);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hcsr |= H_RST | H_IG | H_IS;
 | 
						hcsr |= H_RST | H_IG | H_IS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (intr_enable)
 | 
						if (intr_enable)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = {
 | 
				
			||||||
	{ "INT33BB"  , "3" , &sdhci_acpi_slot_int_sd },
 | 
						{ "INT33BB"  , "3" , &sdhci_acpi_slot_int_sd },
 | 
				
			||||||
	{ "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
 | 
						{ "INT33C6"  , NULL, &sdhci_acpi_slot_int_sdio },
 | 
				
			||||||
	{ "INT3436"  , NULL, &sdhci_acpi_slot_int_sdio },
 | 
						{ "INT3436"  , NULL, &sdhci_acpi_slot_int_sdio },
 | 
				
			||||||
 | 
						{ "INT344D"  , NULL, &sdhci_acpi_slot_int_sdio },
 | 
				
			||||||
	{ "PNP0D40"  },
 | 
						{ "PNP0D40"  },
 | 
				
			||||||
	{ },
 | 
						{ },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = {
 | 
				
			||||||
	{ "INT33BB"  },
 | 
						{ "INT33BB"  },
 | 
				
			||||||
	{ "INT33C6"  },
 | 
						{ "INT33C6"  },
 | 
				
			||||||
	{ "INT3436"  },
 | 
						{ "INT3436"  },
 | 
				
			||||||
 | 
						{ "INT344D"  },
 | 
				
			||||||
	{ "PNP0D40"  },
 | 
						{ "PNP0D40"  },
 | 
				
			||||||
	{ },
 | 
						{ },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = {
 | 
				
			||||||
		.subdevice	= PCI_ANY_ID,
 | 
							.subdevice	= PCI_ANY_ID,
 | 
				
			||||||
		.driver_data	= (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
 | 
							.driver_data	= (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.vendor		= PCI_VENDOR_ID_INTEL,
 | 
				
			||||||
 | 
							.device		= PCI_DEVICE_ID_INTEL_SPT_EMMC,
 | 
				
			||||||
 | 
							.subvendor	= PCI_ANY_ID,
 | 
				
			||||||
 | 
							.subdevice	= PCI_ANY_ID,
 | 
				
			||||||
 | 
							.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_emmc,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.vendor		= PCI_VENDOR_ID_INTEL,
 | 
				
			||||||
 | 
							.device		= PCI_DEVICE_ID_INTEL_SPT_SDIO,
 | 
				
			||||||
 | 
							.subvendor	= PCI_ANY_ID,
 | 
				
			||||||
 | 
							.subdevice	= PCI_ANY_ID,
 | 
				
			||||||
 | 
							.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sdio,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.vendor		= PCI_VENDOR_ID_INTEL,
 | 
				
			||||||
 | 
							.device		= PCI_DEVICE_ID_INTEL_SPT_SD,
 | 
				
			||||||
 | 
							.subvendor	= PCI_ANY_ID,
 | 
				
			||||||
 | 
							.subdevice	= PCI_ANY_ID,
 | 
				
			||||||
 | 
							.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_sd,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.vendor		= PCI_VENDOR_ID_O2,
 | 
							.vendor		= PCI_VENDOR_ID_O2,
 | 
				
			||||||
		.device		= PCI_DEVICE_ID_O2_8120,
 | 
							.device		= PCI_DEVICE_ID_O2_8120,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,9 @@
 | 
				
			||||||
#define PCI_DEVICE_ID_INTEL_CLV_EMMC0	0x08e5
 | 
					#define PCI_DEVICE_ID_INTEL_CLV_EMMC0	0x08e5
 | 
				
			||||||
#define PCI_DEVICE_ID_INTEL_CLV_EMMC1	0x08e6
 | 
					#define PCI_DEVICE_ID_INTEL_CLV_EMMC1	0x08e6
 | 
				
			||||||
#define PCI_DEVICE_ID_INTEL_QRK_SD	0x08A7
 | 
					#define PCI_DEVICE_ID_INTEL_QRK_SD	0x08A7
 | 
				
			||||||
 | 
					#define PCI_DEVICE_ID_INTEL_SPT_EMMC	0x9d2b
 | 
				
			||||||
 | 
					#define PCI_DEVICE_ID_INTEL_SPT_SDIO	0x9d2c
 | 
				
			||||||
 | 
					#define PCI_DEVICE_ID_INTEL_SPT_SD	0x9d2d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * PCI registers
 | 
					 * PCI registers
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
 | 
				
			||||||
	if (IS_ERR(host))
 | 
						if (IS_ERR(host))
 | 
				
			||||||
		return PTR_ERR(host);
 | 
							return PTR_ERR(host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
 | 
					 | 
				
			||||||
		ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
 | 
					 | 
				
			||||||
		if (ret < 0)
 | 
					 | 
				
			||||||
			goto err_mbus_win;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pltfm_host = sdhci_priv(host);
 | 
						pltfm_host = sdhci_priv(host);
 | 
				
			||||||
	pltfm_host->priv = pxa;
 | 
						pltfm_host->priv = pxa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
 | 
				
			||||||
	if (!IS_ERR(pxa->clk_core))
 | 
						if (!IS_ERR(pxa->clk_core))
 | 
				
			||||||
		clk_prepare_enable(pxa->clk_core);
 | 
							clk_prepare_enable(pxa->clk_core);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
 | 
				
			||||||
 | 
							ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
 | 
				
			||||||
 | 
							if (ret < 0)
 | 
				
			||||||
 | 
								goto err_mbus_win;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* enable 1/8V DDR capable */
 | 
						/* enable 1/8V DDR capable */
 | 
				
			||||||
	host->mmc->caps |= MMC_CAP_1_8V_DDR;
 | 
						host->mmc->caps |= MMC_CAP_1_8V_DDR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -396,11 +395,11 @@ err_add_host:
 | 
				
			||||||
	pm_runtime_disable(&pdev->dev);
 | 
						pm_runtime_disable(&pdev->dev);
 | 
				
			||||||
err_of_parse:
 | 
					err_of_parse:
 | 
				
			||||||
err_cd_req:
 | 
					err_cd_req:
 | 
				
			||||||
 | 
					err_mbus_win:
 | 
				
			||||||
	clk_disable_unprepare(pxa->clk_io);
 | 
						clk_disable_unprepare(pxa->clk_io);
 | 
				
			||||||
	if (!IS_ERR(pxa->clk_core))
 | 
						if (!IS_ERR(pxa->clk_core))
 | 
				
			||||||
		clk_disable_unprepare(pxa->clk_core);
 | 
							clk_disable_unprepare(pxa->clk_core);
 | 
				
			||||||
err_clk_get:
 | 
					err_clk_get:
 | 
				
			||||||
err_mbus_win:
 | 
					 | 
				
			||||||
	sdhci_pltfm_free(pdev);
 | 
						sdhci_pltfm_free(pdev);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue