@@ -834,6 +834,61 @@ static int uart_get_info_user(struct tty_struct *tty,
834834 return uart_get_info (port , ss ) < 0 ? - EIO : 0 ;
835835}
836836
837+ static int uart_change_port (struct uart_port * uport ,
838+ const struct serial_struct * new_info ,
839+ unsigned long new_port )
840+ {
841+ unsigned long old_iobase , old_mapbase ;
842+ unsigned int old_type , old_iotype , old_hub6 , old_shift ;
843+ int retval ;
844+
845+ old_iobase = uport -> iobase ;
846+ old_mapbase = uport -> mapbase ;
847+ old_type = uport -> type ;
848+ old_hub6 = uport -> hub6 ;
849+ old_iotype = uport -> iotype ;
850+ old_shift = uport -> regshift ;
851+
852+ if (old_type != PORT_UNKNOWN && uport -> ops -> release_port )
853+ uport -> ops -> release_port (uport );
854+
855+ uport -> iobase = new_port ;
856+ uport -> type = new_info -> type ;
857+ uport -> hub6 = new_info -> hub6 ;
858+ uport -> iotype = new_info -> io_type ;
859+ uport -> regshift = new_info -> iomem_reg_shift ;
860+ uport -> mapbase = (unsigned long )new_info -> iomem_base ;
861+
862+ if (uport -> type == PORT_UNKNOWN || !uport -> ops -> request_port )
863+ return 0 ;
864+
865+ retval = uport -> ops -> request_port (uport );
866+ if (retval == 0 )
867+ return 0 ; /* succeeded => done */
868+
869+ /*
870+ * If we fail to request resources for the new port, try to restore the
871+ * old settings.
872+ */
873+ uport -> iobase = old_iobase ;
874+ uport -> type = old_type ;
875+ uport -> hub6 = old_hub6 ;
876+ uport -> iotype = old_iotype ;
877+ uport -> regshift = old_shift ;
878+ uport -> mapbase = old_mapbase ;
879+
880+ if (old_type == PORT_UNKNOWN )
881+ return retval ;
882+
883+ retval = uport -> ops -> request_port (uport );
884+ /* If we failed to restore the old settings, we fail like this. */
885+ if (retval )
886+ uport -> type = PORT_UNKNOWN ;
887+
888+ /* We failed anyway. */
889+ return - EBUSY ;
890+ }
891+
837892static int uart_set_info (struct tty_struct * tty , struct tty_port * port ,
838893 struct uart_state * state ,
839894 struct serial_struct * new_info )
@@ -930,62 +985,9 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
930985 }
931986
932987 if (change_port ) {
933- unsigned long old_iobase , old_mapbase ;
934- unsigned int old_type , old_iotype , old_hub6 , old_shift ;
935-
936- old_iobase = uport -> iobase ;
937- old_mapbase = uport -> mapbase ;
938- old_type = uport -> type ;
939- old_hub6 = uport -> hub6 ;
940- old_iotype = uport -> iotype ;
941- old_shift = uport -> regshift ;
942-
943- /*
944- * Free and release old regions
945- */
946- if (old_type != PORT_UNKNOWN && uport -> ops -> release_port )
947- uport -> ops -> release_port (uport );
948-
949- uport -> iobase = new_port ;
950- uport -> type = new_info -> type ;
951- uport -> hub6 = new_info -> hub6 ;
952- uport -> iotype = new_info -> io_type ;
953- uport -> regshift = new_info -> iomem_reg_shift ;
954- uport -> mapbase = (unsigned long )new_info -> iomem_base ;
955-
956- /*
957- * Claim and map the new regions
958- */
959- if (uport -> type != PORT_UNKNOWN && uport -> ops -> request_port ) {
960- retval = uport -> ops -> request_port (uport );
961- /*
962- * If we fail to request resources for the
963- * new port, try to restore the old settings.
964- */
965- if (retval ) {
966- uport -> iobase = old_iobase ;
967- uport -> type = old_type ;
968- uport -> hub6 = old_hub6 ;
969- uport -> iotype = old_iotype ;
970- uport -> regshift = old_shift ;
971- uport -> mapbase = old_mapbase ;
972-
973- if (old_type != PORT_UNKNOWN ) {
974- retval = uport -> ops -> request_port (uport );
975- /*
976- * If we failed to restore the old
977- * settings, we fail like this.
978- */
979- if (retval )
980- uport -> type = PORT_UNKNOWN ;
981-
982- /* We failed anyway. */
983- return - EBUSY ;
984- }
985-
986- return retval ;
987- }
988- }
988+ retval = uart_change_port (uport , new_info , new_port );
989+ if (retval )
990+ return retval ;
989991 }
990992
991993 if (change_irq )
0 commit comments