mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-31 16:18:51 +01:00 
			
		
		
		
	Fixed MTP to work with TWRP
This commit is contained in:
		
						commit
						f6dfaef42e
					
				
					 50820 changed files with 20846062 additions and 0 deletions
				
			
		
							
								
								
									
										220
									
								
								arch/ia64/sn/kernel/huberror.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								arch/ia64/sn/kernel/huberror.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,220 @@ | |||
| /*
 | ||||
|  * This file is subject to the terms and conditions of the GNU General Public | ||||
|  * License.  See the file "COPYING" in the main directory of this archive | ||||
|  * for more details. | ||||
|  * | ||||
|  * Copyright (C) 1992 - 1997, 2000,2002-2007 Silicon Graphics, Inc. All rights reserved. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <asm/delay.h> | ||||
| #include <asm/sn/sn_sal.h> | ||||
| #include "ioerror.h" | ||||
| #include <asm/sn/addrs.h> | ||||
| #include <asm/sn/shubio.h> | ||||
| #include <asm/sn/geo.h> | ||||
| #include "xtalk/xwidgetdev.h" | ||||
| #include "xtalk/hubdev.h" | ||||
| #include <asm/sn/bte.h> | ||||
| 
 | ||||
| void hubiio_crb_error_handler(struct hubdev_info *hubdev_info); | ||||
| extern void bte_crb_error_handler(cnodeid_t, int, int, ioerror_t *, | ||||
| 				  int); | ||||
| static irqreturn_t hub_eint_handler(int irq, void *arg) | ||||
| { | ||||
| 	struct hubdev_info *hubdev_info; | ||||
| 	struct ia64_sal_retval ret_stuff; | ||||
| 	nasid_t nasid; | ||||
| 
 | ||||
| 	ret_stuff.status = 0; | ||||
| 	ret_stuff.v0 = 0; | ||||
| 	hubdev_info = (struct hubdev_info *)arg; | ||||
| 	nasid = hubdev_info->hdi_nasid; | ||||
| 
 | ||||
| 	if (is_shub1()) { | ||||
| 		SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT, | ||||
| 			(u64) nasid, 0, 0, 0, 0, 0, 0); | ||||
| 
 | ||||
| 		if ((int)ret_stuff.v0) | ||||
| 			panic("%s: Fatal %s Error", __func__, | ||||
| 				((nasid & 1) ? "TIO" : "HUBII")); | ||||
| 
 | ||||
| 		if (!(nasid & 1)) /* Not a TIO, handle CRB errors */ | ||||
| 			(void)hubiio_crb_error_handler(hubdev_info); | ||||
| 	} else | ||||
| 		if (nasid & 1) {	/* TIO errors */ | ||||
| 			SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT, | ||||
| 				(u64) nasid, 0, 0, 0, 0, 0, 0); | ||||
| 
 | ||||
| 			if ((int)ret_stuff.v0) | ||||
| 				panic("%s: Fatal TIO Error", __func__); | ||||
| 		} else | ||||
| 			bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid))); | ||||
| 
 | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Free the hub CRB "crbnum" which encountered an error. | ||||
|  * Assumption is, error handling was successfully done, | ||||
|  * and we now want to return the CRB back to Hub for normal usage. | ||||
|  * | ||||
|  * In order to free the CRB, all that's needed is to de-allocate it | ||||
|  * | ||||
|  * Assumption: | ||||
|  *      No other processor is mucking around with the hub control register. | ||||
|  *      So, upper layer has to single thread this. | ||||
|  */ | ||||
| void hubiio_crb_free(struct hubdev_info *hubdev_info, int crbnum) | ||||
| { | ||||
| 	ii_icrb0_b_u_t icrbb; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The hardware does NOT clear the mark bit, so it must get cleared | ||||
| 	 * here to be sure the error is not processed twice. | ||||
| 	 */ | ||||
| 	icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(hubdev_info->hdi_nasid, | ||||
| 					       IIO_ICRB_B(crbnum)); | ||||
| 	icrbb.b_mark = 0; | ||||
| 	REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICRB_B(crbnum), | ||||
| 		     icrbb.ii_icrb0_b_regval); | ||||
| 	/*
 | ||||
| 	 * Deallocate the register wait till hub indicates it's done. | ||||
| 	 */ | ||||
| 	REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICDR, (IIO_ICDR_PND | crbnum)); | ||||
| 	while (REMOTE_HUB_L(hubdev_info->hdi_nasid, IIO_ICDR) & IIO_ICDR_PND) | ||||
| 		cpu_relax(); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * hubiio_crb_error_handler | ||||
|  * | ||||
|  *	This routine gets invoked when a hub gets an error  | ||||
|  *	interrupt. So, the routine is running in interrupt context | ||||
|  *	at error interrupt level. | ||||
|  * Action: | ||||
|  *	It's responsible for identifying ALL the CRBs that are marked | ||||
|  *	with error, and process them.  | ||||
|  *	 | ||||
|  * 	If you find the CRB that's marked with error, map this to the | ||||
|  *	reason it caused error, and invoke appropriate error handler. | ||||
|  * | ||||
|  *	XXX Be aware of the information in the context register. | ||||
|  * | ||||
|  * NOTE: | ||||
|  *	Use REMOTE_HUB_* macro instead of LOCAL_HUB_* so that the interrupt | ||||
|  *	handler can be run on any node. (not necessarily the node  | ||||
|  *	corresponding to the hub that encountered error). | ||||
|  */ | ||||
| 
 | ||||
| void hubiio_crb_error_handler(struct hubdev_info *hubdev_info) | ||||
| { | ||||
| 	nasid_t nasid; | ||||
| 	ii_icrb0_a_u_t icrba;	/* II CRB Register A */ | ||||
| 	ii_icrb0_b_u_t icrbb;	/* II CRB Register B */ | ||||
| 	ii_icrb0_c_u_t icrbc;	/* II CRB Register C */ | ||||
| 	ii_icrb0_d_u_t icrbd;	/* II CRB Register D */ | ||||
| 	ii_icrb0_e_u_t icrbe;	/* II CRB Register D */ | ||||
| 	int i; | ||||
| 	int num_errors = 0;	/* Num of errors handled */ | ||||
| 	ioerror_t ioerror; | ||||
| 
 | ||||
| 	nasid = hubdev_info->hdi_nasid; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * XXX - Add locking for any recovery actions | ||||
| 	 */ | ||||
| 	/*
 | ||||
| 	 * Scan through all CRBs in the Hub, and handle the errors | ||||
| 	 * in any of the CRBs marked. | ||||
| 	 */ | ||||
| 	for (i = 0; i < IIO_NUM_CRBS; i++) { | ||||
| 		/* Check this crb entry to see if it is in error. */ | ||||
| 		icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i)); | ||||
| 
 | ||||
| 		if (icrbb.b_mark == 0) { | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i)); | ||||
| 
 | ||||
| 		IOERROR_INIT(&ioerror); | ||||
| 
 | ||||
| 		/* read other CRB error registers. */ | ||||
| 		icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i)); | ||||
| 		icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i)); | ||||
| 		icrbe.ii_icrb0_e_regval = REMOTE_HUB_L(nasid, IIO_ICRB_E(i)); | ||||
| 
 | ||||
| 		IOERROR_SETVALUE(&ioerror, errortype, icrbb.b_ecode); | ||||
| 
 | ||||
| 		/* Check if this error is due to BTE operation,
 | ||||
| 		 * and handle it separately. | ||||
| 		 */ | ||||
| 		if (icrbd.d_bteop || | ||||
| 		    ((icrbb.b_initiator == IIO_ICRB_INIT_BTE0 || | ||||
| 		      icrbb.b_initiator == IIO_ICRB_INIT_BTE1) && | ||||
| 		     (icrbb.b_imsgtype == IIO_ICRB_IMSGT_BTE || | ||||
| 		      icrbb.b_imsgtype == IIO_ICRB_IMSGT_SN1NET))) { | ||||
| 
 | ||||
| 			int bte_num; | ||||
| 
 | ||||
| 			if (icrbd.d_bteop) | ||||
| 				bte_num = icrbc.c_btenum; | ||||
| 			else	/* b_initiator bit 2 gives BTE number */ | ||||
| 				bte_num = (icrbb.b_initiator & 0x4) >> 2; | ||||
| 
 | ||||
| 			hubiio_crb_free(hubdev_info, i); | ||||
| 
 | ||||
| 			bte_crb_error_handler(nasid_to_cnodeid(nasid), bte_num, | ||||
| 					      i, &ioerror, icrbd.d_bteop); | ||||
| 			num_errors++; | ||||
| 			continue; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Function	: hub_error_init | ||||
|  * Purpose	: initialize the error handling requirements for a given hub. | ||||
|  * Parameters	: cnode, the compact nodeid. | ||||
|  * Assumptions	: Called only once per hub, either by a local cpu. Or by a | ||||
|  *			remote cpu, when this hub is headless.(cpuless) | ||||
|  * Returns	: None | ||||
|  */ | ||||
| void hub_error_init(struct hubdev_info *hubdev_info) | ||||
| { | ||||
| 
 | ||||
| 	if (request_irq(SGI_II_ERROR, hub_eint_handler, IRQF_SHARED, | ||||
| 			"SN_hub_error", hubdev_info)) { | ||||
| 		printk(KERN_ERR "hub_error_init: Failed to request_irq for 0x%p\n", | ||||
| 		    hubdev_info); | ||||
| 		return; | ||||
| 	} | ||||
| 	irq_set_handler(SGI_II_ERROR, handle_level_irq); | ||||
| 	sn_set_err_irq_affinity(SGI_II_ERROR); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * Function	: ice_error_init | ||||
|  * Purpose	: initialize the error handling requirements for a given tio. | ||||
|  * Parameters	: cnode, the compact nodeid. | ||||
|  * Assumptions	: Called only once per tio. | ||||
|  * Returns	: None | ||||
|  */ | ||||
| void ice_error_init(struct hubdev_info *hubdev_info) | ||||
| { | ||||
| 
 | ||||
|         if (request_irq | ||||
|             (SGI_TIO_ERROR, (void *)hub_eint_handler, IRQF_SHARED, "SN_TIO_error", | ||||
|              (void *)hubdev_info)) { | ||||
|                 printk("ice_error_init: request_irq() error hubdev_info 0x%p\n", | ||||
|                        hubdev_info); | ||||
| 		return; | ||||
| 	} | ||||
| 	irq_set_handler(SGI_TIO_ERROR, handle_level_irq); | ||||
| 	sn_set_err_irq_affinity(SGI_TIO_ERROR); | ||||
| } | ||||
| 
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228