aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-02-24 14:25:14 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-26 13:18:20 -0400
commit403753937020549e4bb0d8ef6e915f00a338a096 (patch)
treefe36c7e398cc3d28c3c7bd7a0bd1245f6d0ddf1c /drivers/tty/serial/8250
parent3b81c26c92414024a8046eb216782f3d599a5d77 (diff)
serial: 8250: Decouple RSA probe
Prepare for 8250 split; separate RSA probe and resource management from base port operations. Override base port operations for the config_port(), request_port() and release_port() methods to implement the optional RSA probe and resource management only in the universal/legacy 8250 driver. Introduce 'probe' flags for 8250 ports, which allows drivers higher up the driver stack to enable optional probes. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r--drivers/tty/serial/8250/8250.h3
-rw-r--r--drivers/tty/serial/8250/8250_core.c112
2 files changed, 76 insertions, 39 deletions
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 23dc9f9b9839..c43f74c53cd9 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -84,9 +84,6 @@ struct serial8250_config {
84#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ 84#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
85#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ 85#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
86 86
87#define PROBE_RSA (1 << 0)
88#define PROBE_ANY (~0)
89
90#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 87#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
91 88
92#ifdef CONFIG_SERIAL_8250_SHARE_IRQ 89#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 257e373bfccd..a4ed84a4f8db 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1105,7 +1105,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
1105 * whether or not this UART is a 16550A or not, since this will 1105 * whether or not this UART is a 16550A or not, since this will
1106 * determine whether or not we can use its FIFO features or not. 1106 * determine whether or not we can use its FIFO features or not.
1107 */ 1107 */
1108static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) 1108static void autoconfig(struct uart_8250_port *up)
1109{ 1109{
1110 unsigned char status1, scratch, scratch2, scratch3; 1110 unsigned char status1, scratch, scratch2, scratch3;
1111 unsigned char save_lcr, save_mcr; 1111 unsigned char save_lcr, save_mcr;
@@ -1228,7 +1228,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
1228 /* 1228 /*
1229 * Only probe for RSA ports if we got the region. 1229 * Only probe for RSA ports if we got the region.
1230 */ 1230 */
1231 if (port->type == PORT_16550A && probeflags & PROBE_RSA && 1231 if (port->type == PORT_16550A && up->probe & UART_PROBE_RSA &&
1232 __enable_rsa(up)) 1232 __enable_rsa(up))
1233 port->type = PORT_RSA; 1233 port->type = PORT_RSA;
1234#endif 1234#endif
@@ -2832,10 +2832,6 @@ static void serial8250_release_port(struct uart_port *port)
2832 struct uart_8250_port *up = up_to_u8250p(port); 2832 struct uart_8250_port *up = up_to_u8250p(port);
2833 2833
2834 serial8250_release_std_resource(up); 2834 serial8250_release_std_resource(up);
2835#ifdef CONFIG_SERIAL_8250_RSA
2836 if (port->type == PORT_RSA)
2837 serial8250_release_rsa_resource(up);
2838#endif
2839} 2835}
2840 2836
2841static int serial8250_request_port(struct uart_port *port) 2837static int serial8250_request_port(struct uart_port *port)
@@ -2847,13 +2843,6 @@ static int serial8250_request_port(struct uart_port *port)
2847 return -ENODEV; 2843 return -ENODEV;
2848 2844
2849 ret = serial8250_request_std_resource(up); 2845 ret = serial8250_request_std_resource(up);
2850#ifdef CONFIG_SERIAL_8250_RSA
2851 if (ret == 0 && port->type == PORT_RSA) {
2852 ret = serial8250_request_rsa_resource(up);
2853 if (ret < 0)
2854 serial8250_release_std_resource(up);
2855 }
2856#endif
2857 2846
2858 return ret; 2847 return ret;
2859} 2848}
@@ -3001,7 +2990,6 @@ static void register_dev_spec_attr_grp(struct uart_8250_port *up)
3001static void serial8250_config_port(struct uart_port *port, int flags) 2990static void serial8250_config_port(struct uart_port *port, int flags)
3002{ 2991{
3003 struct uart_8250_port *up = up_to_u8250p(port); 2992 struct uart_8250_port *up = up_to_u8250p(port);
3004 int probeflags = 0;
3005 int ret; 2993 int ret;
3006 2994
3007 if (port->type == PORT_8250_CIR) 2995 if (port->type == PORT_8250_CIR)
@@ -3015,28 +3003,11 @@ static void serial8250_config_port(struct uart_port *port, int flags)
3015 if (ret < 0) 3003 if (ret < 0)
3016 return; 3004 return;
3017 3005
3018#ifdef CONFIG_SERIAL_8250_RSA
3019 if (port->type == PORT_RSA) {
3020 if (serial8250_request_rsa_resource(up) == 0)
3021 probeflags |= PROBE_RSA;
3022 } else if (flags & UART_CONFIG_TYPE) {
3023 int i;
3024
3025 for (i = 0 ; i < probe_rsa_count; ++i) {
3026 if (probe_rsa[i] == port->iobase) {
3027 if (serial8250_request_rsa_resource(up) == 0)
3028 probeflags |= PROBE_RSA;
3029 break;
3030 }
3031 }
3032 }
3033#endif
3034
3035 if (port->iotype != up->cur_iotype) 3006 if (port->iotype != up->cur_iotype)
3036 set_io_from_upio(port); 3007 set_io_from_upio(port);
3037 3008
3038 if (flags & UART_CONFIG_TYPE) 3009 if (flags & UART_CONFIG_TYPE)
3039 autoconfig(up, probeflags); 3010 autoconfig(up);
3040 3011
3041 /* if access method is AU, it is a 16550 with a quirk */ 3012 /* if access method is AU, it is a 16550 with a quirk */
3042 if (port->type == PORT_16550A && port->iotype == UPIO_AU) 3013 if (port->type == PORT_16550A && port->iotype == UPIO_AU)
@@ -3049,10 +3020,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
3049 if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) 3020 if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
3050 autoconfig_irq(up); 3021 autoconfig_irq(up);
3051 3022
3052#ifdef CONFIG_SERIAL_8250_RSA
3053 if (port->type != PORT_RSA && probeflags & PROBE_RSA)
3054 serial8250_release_rsa_resource(up);
3055#endif
3056 if (port->type == PORT_UNKNOWN) 3023 if (port->type == PORT_UNKNOWN)
3057 serial8250_release_std_resource(up); 3024 serial8250_release_std_resource(up);
3058 3025
@@ -3113,6 +3080,9 @@ static struct uart_ops serial8250_pops = {
3113#endif 3080#endif
3114}; 3081};
3115 3082
3083static const struct uart_ops *base_ops;
3084static struct uart_ops univ8250_port_ops;
3085
3116static const struct uart_8250_ops univ8250_driver_ops = { 3086static const struct uart_8250_ops univ8250_driver_ops = {
3117 .setup_irq = univ8250_setup_irq, 3087 .setup_irq = univ8250_setup_irq,
3118 .release_irq = univ8250_release_irq, 3088 .release_irq = univ8250_release_irq,
@@ -3184,6 +3154,69 @@ static void serial8250_set_defaults(struct uart_8250_port *up)
3184 } 3154 }
3185} 3155}
3186 3156
3157#ifdef CONFIG_SERIAL_8250_RSA
3158
3159static void univ8250_config_port(struct uart_port *port, int flags)
3160{
3161 struct uart_8250_port *up = up_to_u8250p(port);
3162
3163 up->probe &= ~UART_PROBE_RSA;
3164 if (port->type == PORT_RSA) {
3165 if (serial8250_request_rsa_resource(up) == 0)
3166 up->probe |= UART_PROBE_RSA;
3167 } else if (flags & UART_CONFIG_TYPE) {
3168 int i;
3169
3170 for (i = 0; i < probe_rsa_count; i++) {
3171 if (probe_rsa[i] == up->port.iobase) {
3172 if (serial8250_request_rsa_resource(up) == 0)
3173 up->probe |= UART_PROBE_RSA;
3174 break;
3175 }
3176 }
3177 }
3178
3179 base_ops->config_port(port, flags);
3180
3181 if (port->type != PORT_RSA && up->probe & UART_PROBE_RSA)
3182 serial8250_release_rsa_resource(up);
3183}
3184
3185static int univ8250_request_port(struct uart_port *port)
3186{
3187 struct uart_8250_port *up = up_to_u8250p(port);
3188 int ret;
3189
3190 ret = base_ops->request_port(port);
3191 if (ret == 0 && port->type == PORT_RSA) {
3192 ret = serial8250_request_rsa_resource(up);
3193 if (ret < 0)
3194 base_ops->release_port(port);
3195 }
3196
3197 return ret;
3198}
3199
3200static void univ8250_release_port(struct uart_port *port)
3201{
3202 struct uart_8250_port *up = up_to_u8250p(port);
3203
3204 if (port->type == PORT_RSA)
3205 serial8250_release_rsa_resource(up);
3206 base_ops->release_port(port);
3207}
3208
3209static void univ8250_rsa_support(struct uart_ops *ops)
3210{
3211 ops->config_port = univ8250_config_port;
3212 ops->request_port = univ8250_request_port;
3213 ops->release_port = univ8250_release_port;
3214}
3215
3216#else
3217#define univ8250_rsa_support(x) do { } while (0)
3218#endif /* CONFIG_SERIAL_8250_RSA */
3219
3187static void __init serial8250_isa_init_ports(void) 3220static void __init serial8250_isa_init_ports(void)
3188{ 3221{
3189 struct uart_8250_port *up; 3222 struct uart_8250_port *up;
@@ -3203,6 +3236,9 @@ static void __init serial8250_isa_init_ports(void)
3203 3236
3204 port->line = i; 3237 port->line = i;
3205 serial8250_init_port(up); 3238 serial8250_init_port(up);
3239 if (!base_ops)
3240 base_ops = port->ops;
3241 port->ops = &univ8250_port_ops;
3206 3242
3207 init_timer(&up->timer); 3243 init_timer(&up->timer);
3208 up->timer.function = serial8250_timeout; 3244 up->timer.function = serial8250_timeout;
@@ -3216,6 +3252,10 @@ static void __init serial8250_isa_init_ports(void)
3216 up->mcr_force = ALPHA_KLUDGE_MCR; 3252 up->mcr_force = ALPHA_KLUDGE_MCR;
3217 } 3253 }
3218 3254
3255 /* chain base port ops to support Remote Supervisor Adapter */
3256 univ8250_port_ops = *base_ops;
3257 univ8250_rsa_support(&univ8250_port_ops);
3258
3219 if (share_irqs) 3259 if (share_irqs)
3220 irqflag = IRQF_SHARED; 3260 irqflag = IRQF_SHARED;
3221 3261