diff options
68 files changed, 1398 insertions, 1144 deletions
diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index 936ab5b87324..f5561ac7e17e 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt | |||
@@ -42,6 +42,9 @@ Optional properties: | |||
42 | - auto-flow-control: one way to enable automatic flow control support. The | 42 | - auto-flow-control: one way to enable automatic flow control support. The |
43 | driver is allowed to detect support for the capability even without this | 43 | driver is allowed to detect support for the capability even without this |
44 | property. | 44 | property. |
45 | - {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD | ||
46 | line respectively. It will use specified GPIO instead of the peripheral | ||
47 | function pin for the UART feature. If unsure, don't specify this property. | ||
45 | 48 | ||
46 | Note: | 49 | Note: |
47 | * fsl,ns16550: | 50 | * fsl,ns16550: |
@@ -63,3 +66,19 @@ Example: | |||
63 | interrupts = <10>; | 66 | interrupts = <10>; |
64 | reg-shift = <2>; | 67 | reg-shift = <2>; |
65 | }; | 68 | }; |
69 | |||
70 | Example for OMAP UART using GPIO-based modem control signals: | ||
71 | |||
72 | uart4: serial@49042000 { | ||
73 | compatible = "ti,omap3-uart"; | ||
74 | reg = <0x49042000 0x400>; | ||
75 | interrupts = <80>; | ||
76 | ti,hwmods = "uart4"; | ||
77 | clock-frequency = <48000000>; | ||
78 | cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; | ||
79 | rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; | ||
80 | dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; | ||
81 | dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; | ||
82 | dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; | ||
83 | rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; | ||
84 | }; | ||
diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 528c3b90f23c..1e4000d83aee 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt | |||
@@ -31,6 +31,8 @@ Required properties: | |||
31 | - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. | 31 | - "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART. |
32 | - "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART. | 32 | - "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART. |
33 | - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. | 33 | - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. |
34 | - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. | ||
35 | - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. | ||
34 | - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. | 36 | - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. |
35 | - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. | 37 | - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. |
36 | - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, | 38 | - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, |
@@ -76,6 +78,10 @@ Optional properties: | |||
76 | - dmas: Must contain a list of two references to DMA specifiers, one for | 78 | - dmas: Must contain a list of two references to DMA specifiers, one for |
77 | transmission, and one for reception. | 79 | transmission, and one for reception. |
78 | - dma-names: Must contain a list of two DMA names, "tx" and "rx". | 80 | - dma-names: Must contain a list of two DMA names, "tx" and "rx". |
81 | - {cts,dsr,dcd,rng,rts,dtr}-gpios: Specify GPIOs for modem lines, cfr. the | ||
82 | generic serial DT bindings in serial.txt. | ||
83 | - uart-has-rtscts: Indicates dedicated lines for RTS/CTS hardware flow | ||
84 | control, cfr. the generic serial DT bindings in serial.txt. | ||
79 | 85 | ||
80 | Example: | 86 | Example: |
81 | aliases { | 87 | aliases { |
diff --git a/MAINTAINERS b/MAINTAINERS index 6f77f92efbc2..c891b41e2b58 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -10003,6 +10003,7 @@ SERIAL DRIVERS | |||
10003 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 10003 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
10004 | L: linux-serial@vger.kernel.org | 10004 | L: linux-serial@vger.kernel.org |
10005 | S: Maintained | 10005 | S: Maintained |
10006 | F: Documentation/devicetree/bindings/serial/ | ||
10006 | F: drivers/tty/serial/ | 10007 | F: drivers/tty/serial/ |
10007 | 10008 | ||
10008 | SYNOPSYS DESIGNWARE DMAC DRIVER | 10009 | SYNOPSYS DESIGNWARE DMAC DRIVER |
diff --git a/arch/frv/include/asm/serial.h b/arch/frv/include/asm/serial.h index bce0d0d07e60..614c6d76789a 100644 --- a/arch/frv/include/asm/serial.h +++ b/arch/frv/include/asm/serial.h | |||
@@ -12,7 +12,3 @@ | |||
12 | * the base baud is derived from the clock speed and so is variable | 12 | * the base baud is derived from the clock speed and so is variable |
13 | */ | 13 | */ |
14 | #define BASE_BAUD 0 | 14 | #define BASE_BAUD 0 |
15 | |||
16 | #define STD_COM_FLAGS UPF_BOOT_AUTOCONF | ||
17 | |||
18 | #define SERIAL_PORT_DFNS | ||
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c index 5f4bd71971d6..4904c5c16918 100644 --- a/arch/xtensa/platforms/xt2000/setup.c +++ b/arch/xtensa/platforms/xt2000/setup.c | |||
@@ -113,7 +113,6 @@ void platform_heartbeat(void) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | //#define RS_TABLE_SIZE 2 | 115 | //#define RS_TABLE_SIZE 2 |
116 | //#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF|UPF_SKIP_TEST) | ||
117 | 116 | ||
118 | #define _SERIAL_PORT(_base,_irq) \ | 117 | #define _SERIAL_PORT(_base,_irq) \ |
119 | { \ | 118 | { \ |
diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index f8c5cd53307c..c5f21efd6090 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c | |||
@@ -126,28 +126,33 @@ static void hsu_dma_start_transfer(struct hsu_dma_chan *hsuc) | |||
126 | hsu_dma_start_channel(hsuc); | 126 | hsu_dma_start_channel(hsuc); |
127 | } | 127 | } |
128 | 128 | ||
129 | static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc) | 129 | /* |
130 | { | 130 | * hsu_dma_get_status() - get DMA channel status |
131 | unsigned long flags; | 131 | * @chip: HSUART DMA chip |
132 | u32 sr; | 132 | * @nr: DMA channel number |
133 | 133 | * @status: pointer for DMA Channel Status Register value | |
134 | spin_lock_irqsave(&hsuc->vchan.lock, flags); | 134 | * |
135 | sr = hsu_chan_readl(hsuc, HSU_CH_SR); | 135 | * Description: |
136 | spin_unlock_irqrestore(&hsuc->vchan.lock, flags); | 136 | * The function reads and clears the DMA Channel Status Register, checks |
137 | 137 | * if it was a timeout interrupt and returns a corresponding value. | |
138 | return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY); | 138 | * |
139 | } | 139 | * Caller should provide a valid pointer for the DMA Channel Status |
140 | 140 | * Register value that will be returned in @status. | |
141 | irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) | 141 | * |
142 | * Return: | ||
143 | * 1 for DMA timeout status, 0 for other DMA status, or error code for | ||
144 | * invalid parameters or no interrupt pending. | ||
145 | */ | ||
146 | int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr, | ||
147 | u32 *status) | ||
142 | { | 148 | { |
143 | struct hsu_dma_chan *hsuc; | 149 | struct hsu_dma_chan *hsuc; |
144 | struct hsu_dma_desc *desc; | ||
145 | unsigned long flags; | 150 | unsigned long flags; |
146 | u32 sr; | 151 | u32 sr; |
147 | 152 | ||
148 | /* Sanity check */ | 153 | /* Sanity check */ |
149 | if (nr >= chip->hsu->nr_channels) | 154 | if (nr >= chip->hsu->nr_channels) |
150 | return IRQ_NONE; | 155 | return -EINVAL; |
151 | 156 | ||
152 | hsuc = &chip->hsu->chan[nr]; | 157 | hsuc = &chip->hsu->chan[nr]; |
153 | 158 | ||
@@ -155,22 +160,65 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) | |||
155 | * No matter what situation, need read clear the IRQ status | 160 | * No matter what situation, need read clear the IRQ status |
156 | * There is a bug, see Errata 5, HSD 2900918 | 161 | * There is a bug, see Errata 5, HSD 2900918 |
157 | */ | 162 | */ |
158 | sr = hsu_dma_chan_get_sr(hsuc); | 163 | spin_lock_irqsave(&hsuc->vchan.lock, flags); |
164 | sr = hsu_chan_readl(hsuc, HSU_CH_SR); | ||
165 | spin_unlock_irqrestore(&hsuc->vchan.lock, flags); | ||
166 | |||
167 | /* Check if any interrupt is pending */ | ||
168 | sr &= ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY); | ||
159 | if (!sr) | 169 | if (!sr) |
160 | return IRQ_NONE; | 170 | return -EIO; |
161 | 171 | ||
162 | /* Timeout IRQ, need wait some time, see Errata 2 */ | 172 | /* Timeout IRQ, need wait some time, see Errata 2 */ |
163 | if (sr & HSU_CH_SR_DESCTO_ANY) | 173 | if (sr & HSU_CH_SR_DESCTO_ANY) |
164 | udelay(2); | 174 | udelay(2); |
165 | 175 | ||
176 | /* | ||
177 | * At this point, at least one of Descriptor Time Out, Channel Error | ||
178 | * or Descriptor Done bits must be set. Clear the Descriptor Time Out | ||
179 | * bits and if sr is still non-zero, it must be channel error or | ||
180 | * descriptor done which are higher priority than timeout and handled | ||
181 | * in hsu_dma_do_irq(). Else, it must be a timeout. | ||
182 | */ | ||
166 | sr &= ~HSU_CH_SR_DESCTO_ANY; | 183 | sr &= ~HSU_CH_SR_DESCTO_ANY; |
167 | if (!sr) | 184 | |
168 | return IRQ_HANDLED; | 185 | *status = sr; |
186 | |||
187 | return sr ? 0 : 1; | ||
188 | } | ||
189 | EXPORT_SYMBOL_GPL(hsu_dma_get_status); | ||
190 | |||
191 | /* | ||
192 | * hsu_dma_do_irq() - DMA interrupt handler | ||
193 | * @chip: HSUART DMA chip | ||
194 | * @nr: DMA channel number | ||
195 | * @status: Channel Status Register value | ||
196 | * | ||
197 | * Description: | ||
198 | * This function handles Channel Error and Descriptor Done interrupts. | ||
199 | * This function should be called after determining that the DMA interrupt | ||
200 | * is not a normal timeout interrupt, ie. hsu_dma_get_status() returned 0. | ||
201 | * | ||
202 | * Return: | ||
203 | * IRQ_NONE for invalid channel number, IRQ_HANDLED otherwise. | ||
204 | */ | ||
205 | irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, | ||
206 | u32 status) | ||
207 | { | ||
208 | struct hsu_dma_chan *hsuc; | ||
209 | struct hsu_dma_desc *desc; | ||
210 | unsigned long flags; | ||
211 | |||
212 | /* Sanity check */ | ||
213 | if (nr >= chip->hsu->nr_channels) | ||
214 | return IRQ_NONE; | ||
215 | |||
216 | hsuc = &chip->hsu->chan[nr]; | ||
169 | 217 | ||
170 | spin_lock_irqsave(&hsuc->vchan.lock, flags); | 218 | spin_lock_irqsave(&hsuc->vchan.lock, flags); |
171 | desc = hsuc->desc; | 219 | desc = hsuc->desc; |
172 | if (desc) { | 220 | if (desc) { |
173 | if (sr & HSU_CH_SR_CHE) { | 221 | if (status & HSU_CH_SR_CHE) { |
174 | desc->status = DMA_ERROR; | 222 | desc->status = DMA_ERROR; |
175 | } else if (desc->active < desc->nents) { | 223 | } else if (desc->active < desc->nents) { |
176 | hsu_dma_start_channel(hsuc); | 224 | hsu_dma_start_channel(hsuc); |
@@ -184,7 +232,7 @@ irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr) | |||
184 | 232 | ||
185 | return IRQ_HANDLED; | 233 | return IRQ_HANDLED; |
186 | } | 234 | } |
187 | EXPORT_SYMBOL_GPL(hsu_dma_irq); | 235 | EXPORT_SYMBOL_GPL(hsu_dma_do_irq); |
188 | 236 | ||
189 | static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents) | 237 | static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents) |
190 | { | 238 | { |
diff --git a/drivers/dma/hsu/pci.c b/drivers/dma/hsu/pci.c index e2db76bd56d8..9916058531d9 100644 --- a/drivers/dma/hsu/pci.c +++ b/drivers/dma/hsu/pci.c | |||
@@ -27,13 +27,20 @@ static irqreturn_t hsu_pci_irq(int irq, void *dev) | |||
27 | { | 27 | { |
28 | struct hsu_dma_chip *chip = dev; | 28 | struct hsu_dma_chip *chip = dev; |
29 | u32 dmaisr; | 29 | u32 dmaisr; |
30 | u32 status; | ||
30 | unsigned short i; | 31 | unsigned short i; |
31 | irqreturn_t ret = IRQ_NONE; | 32 | irqreturn_t ret = IRQ_NONE; |
33 | int err; | ||
32 | 34 | ||
33 | dmaisr = readl(chip->regs + HSU_PCI_DMAISR); | 35 | dmaisr = readl(chip->regs + HSU_PCI_DMAISR); |
34 | for (i = 0; i < chip->hsu->nr_channels; i++) { | 36 | for (i = 0; i < chip->hsu->nr_channels; i++) { |
35 | if (dmaisr & 0x1) | 37 | if (dmaisr & 0x1) { |
36 | ret |= hsu_dma_irq(chip, i); | 38 | err = hsu_dma_get_status(chip, i, &status); |
39 | if (err > 0) | ||
40 | ret |= IRQ_HANDLED; | ||
41 | else if (err == 0) | ||
42 | ret |= hsu_dma_do_irq(chip, i, status); | ||
43 | } | ||
37 | dmaisr >>= 1; | 44 | dmaisr >>= 1; |
38 | } | 45 | } |
39 | 46 | ||
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 3840d6b421c4..5e4fa9206861 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -93,8 +93,6 @@ static void cy_send_xchar(struct tty_struct *tty, char ch); | |||
93 | #define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096)) | 93 | #define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096)) |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | #define STD_COM_FLAGS (0) | ||
97 | |||
98 | /* firmware stuff */ | 96 | /* firmware stuff */ |
99 | #define ZL_MAX_BLOCKS 16 | 97 | #define ZL_MAX_BLOCKS 16 |
100 | #define DRIVER_VERSION 0x02010203 | 98 | #define DRIVER_VERSION 0x02010203 |
@@ -2288,7 +2286,6 @@ static int cy_get_serial_info(struct cyclades_port *info, | |||
2288 | .closing_wait = info->port.closing_wait, | 2286 | .closing_wait = info->port.closing_wait, |
2289 | .baud_base = info->baud, | 2287 | .baud_base = info->baud, |
2290 | .custom_divisor = info->custom_divisor, | 2288 | .custom_divisor = info->custom_divisor, |
2291 | .hub6 = 0, /*!!! */ | ||
2292 | }; | 2289 | }; |
2293 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; | 2290 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; |
2294 | } | 2291 | } |
@@ -3084,7 +3081,6 @@ static int cy_init_card(struct cyclades_card *cinfo) | |||
3084 | 3081 | ||
3085 | info->port.closing_wait = CLOSING_WAIT_DELAY; | 3082 | info->port.closing_wait = CLOSING_WAIT_DELAY; |
3086 | info->port.close_delay = 5 * HZ / 10; | 3083 | info->port.close_delay = 5 * HZ / 10; |
3087 | info->port.flags = STD_COM_FLAGS; | ||
3088 | init_completion(&info->shutdown_wait); | 3084 | init_completion(&info->shutdown_wait); |
3089 | 3085 | ||
3090 | if (cy_is_Z(cinfo)) { | 3086 | if (cy_is_Z(cinfo)) { |
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 345cebb07ae7..2685d59d2724 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
@@ -252,20 +252,11 @@ static int ipwireless_get_serial_info(struct ipw_tty *tty, | |||
252 | { | 252 | { |
253 | struct serial_struct tmp; | 253 | struct serial_struct tmp; |
254 | 254 | ||
255 | if (!retinfo) | ||
256 | return (-EFAULT); | ||
257 | |||
258 | memset(&tmp, 0, sizeof(tmp)); | 255 | memset(&tmp, 0, sizeof(tmp)); |
259 | tmp.type = PORT_UNKNOWN; | 256 | tmp.type = PORT_UNKNOWN; |
260 | tmp.line = tty->index; | 257 | tmp.line = tty->index; |
261 | tmp.port = 0; | ||
262 | tmp.irq = 0; | ||
263 | tmp.flags = 0; | ||
264 | tmp.baud_base = 115200; | 258 | tmp.baud_base = 115200; |
265 | tmp.close_delay = 0; | 259 | |
266 | tmp.closing_wait = 0; | ||
267 | tmp.custom_divisor = 0; | ||
268 | tmp.hub6 = 0; | ||
269 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 260 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
270 | return -EFAULT; | 261 | return -EFAULT; |
271 | 262 | ||
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 98d2bd16706d..69294ae154be 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -1219,7 +1219,6 @@ static int mxser_get_serial_info(struct tty_struct *tty, | |||
1219 | .close_delay = info->port.close_delay, | 1219 | .close_delay = info->port.close_delay, |
1220 | .closing_wait = info->port.closing_wait, | 1220 | .closing_wait = info->port.closing_wait, |
1221 | .custom_divisor = info->custom_divisor, | 1221 | .custom_divisor = info->custom_divisor, |
1222 | .hub6 = 0 | ||
1223 | }; | 1222 | }; |
1224 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 1223 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
1225 | return -EFAULT; | 1224 | return -EFAULT; |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 215a99237e95..122e0e4029fe 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/serial_reg.h> | 15 | #include <linux/serial_reg.h> |
16 | #include <linux/dmaengine.h> | 16 | #include <linux/dmaengine.h> |
17 | 17 | ||
18 | #include "../serial_mctrl_gpio.h" | ||
19 | |||
18 | struct uart_8250_dma { | 20 | struct uart_8250_dma { |
19 | int (*tx_dma)(struct uart_8250_port *p); | 21 | int (*tx_dma)(struct uart_8250_port *p); |
20 | int (*rx_dma)(struct uart_8250_port *p); | 22 | int (*rx_dma)(struct uart_8250_port *p); |
@@ -53,11 +55,9 @@ struct old_serial_port { | |||
53 | unsigned int port; | 55 | unsigned int port; |
54 | unsigned int irq; | 56 | unsigned int irq; |
55 | upf_t flags; | 57 | upf_t flags; |
56 | unsigned char hub6; | ||
57 | unsigned char io_type; | 58 | unsigned char io_type; |
58 | unsigned char __iomem *iomem_base; | 59 | unsigned char __iomem *iomem_base; |
59 | unsigned short iomem_reg_shift; | 60 | unsigned short iomem_reg_shift; |
60 | unsigned long irqflags; | ||
61 | }; | 61 | }; |
62 | 62 | ||
63 | struct serial8250_config { | 63 | struct serial8250_config { |
@@ -131,6 +131,47 @@ void serial8250_rpm_put(struct uart_8250_port *p); | |||
131 | int serial8250_em485_init(struct uart_8250_port *p); | 131 | int serial8250_em485_init(struct uart_8250_port *p); |
132 | void serial8250_em485_destroy(struct uart_8250_port *p); | 132 | void serial8250_em485_destroy(struct uart_8250_port *p); |
133 | 133 | ||
134 | static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) | ||
135 | { | ||
136 | int mctrl_gpio = 0; | ||
137 | |||
138 | serial_out(up, UART_MCR, value); | ||
139 | |||
140 | if (value & UART_MCR_RTS) | ||
141 | mctrl_gpio |= TIOCM_RTS; | ||
142 | if (value & UART_MCR_DTR) | ||
143 | mctrl_gpio |= TIOCM_DTR; | ||
144 | |||
145 | mctrl_gpio_set(up->gpios, mctrl_gpio); | ||
146 | } | ||
147 | |||
148 | static inline int serial8250_in_MCR(struct uart_8250_port *up) | ||
149 | { | ||
150 | int mctrl, mctrl_gpio = 0; | ||
151 | |||
152 | mctrl = serial_in(up, UART_MCR); | ||
153 | |||
154 | /* save current MCR values */ | ||
155 | if (mctrl & UART_MCR_RTS) | ||
156 | mctrl_gpio |= TIOCM_RTS; | ||
157 | if (mctrl & UART_MCR_DTR) | ||
158 | mctrl_gpio |= TIOCM_DTR; | ||
159 | |||
160 | mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio); | ||
161 | |||
162 | if (mctrl_gpio & TIOCM_RTS) | ||
163 | mctrl |= UART_MCR_RTS; | ||
164 | else | ||
165 | mctrl &= ~UART_MCR_RTS; | ||
166 | |||
167 | if (mctrl_gpio & TIOCM_DTR) | ||
168 | mctrl |= UART_MCR_DTR; | ||
169 | else | ||
170 | mctrl &= ~UART_MCR_DTR; | ||
171 | |||
172 | return mctrl; | ||
173 | } | ||
174 | |||
134 | #if defined(__alpha__) && !defined(CONFIG_PCI) | 175 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
135 | /* | 176 | /* |
136 | * Digital did something really horribly wrong with the OUT1 and OUT2 | 177 | * Digital did something really horribly wrong with the OUT1 and OUT2 |
@@ -237,9 +278,3 @@ static inline int serial_index(struct uart_port *port) | |||
237 | { | 278 | { |
238 | return port->minor - 64; | 279 | return port->minor - 64; |
239 | } | 280 | } |
240 | |||
241 | #if 0 | ||
242 | #define DEBUG_INTR(fmt...) printk(fmt) | ||
243 | #else | ||
244 | #define DEBUG_INTR(fmt...) do { } while (0) | ||
245 | #endif | ||
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 0fbd7c033a25..13ad5c3d2e68 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -114,7 +114,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
114 | struct list_head *l, *end = NULL; | 114 | struct list_head *l, *end = NULL; |
115 | int pass_counter = 0, handled = 0; | 115 | int pass_counter = 0, handled = 0; |
116 | 116 | ||
117 | DEBUG_INTR("serial8250_interrupt(%d)...", irq); | 117 | pr_debug("%s(%d): start\n", __func__, irq); |
118 | 118 | ||
119 | spin_lock(&i->lock); | 119 | spin_lock(&i->lock); |
120 | 120 | ||
@@ -144,7 +144,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
144 | 144 | ||
145 | spin_unlock(&i->lock); | 145 | spin_unlock(&i->lock); |
146 | 146 | ||
147 | DEBUG_INTR("end.\n"); | 147 | pr_debug("%s(%d): end\n", __func__, irq); |
148 | 148 | ||
149 | return IRQ_RETVAL(handled); | 149 | return IRQ_RETVAL(handled); |
150 | } | 150 | } |
@@ -546,10 +546,10 @@ static void __init serial8250_isa_init_ports(void) | |||
546 | 546 | ||
547 | port->iobase = old_serial_port[i].port; | 547 | port->iobase = old_serial_port[i].port; |
548 | port->irq = irq_canonicalize(old_serial_port[i].irq); | 548 | port->irq = irq_canonicalize(old_serial_port[i].irq); |
549 | port->irqflags = old_serial_port[i].irqflags; | 549 | port->irqflags = 0; |
550 | port->uartclk = old_serial_port[i].baud_base * 16; | 550 | port->uartclk = old_serial_port[i].baud_base * 16; |
551 | port->flags = old_serial_port[i].flags; | 551 | port->flags = old_serial_port[i].flags; |
552 | port->hub6 = old_serial_port[i].hub6; | 552 | port->hub6 = 0; |
553 | port->membase = old_serial_port[i].iomem_base; | 553 | port->membase = old_serial_port[i].iomem_base; |
554 | port->iotype = old_serial_port[i].io_type; | 554 | port->iotype = old_serial_port[i].io_type; |
555 | port->regshift = old_serial_port[i].iomem_reg_shift; | 555 | port->regshift = old_serial_port[i].iomem_reg_shift; |
@@ -675,7 +675,7 @@ static struct console univ8250_console = { | |||
675 | .device = uart_console_device, | 675 | .device = uart_console_device, |
676 | .setup = univ8250_console_setup, | 676 | .setup = univ8250_console_setup, |
677 | .match = univ8250_console_match, | 677 | .match = univ8250_console_match, |
678 | .flags = CON_PRINTBUFFER | CON_ANYTIME, | 678 | .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_CONSDEV, |
679 | .index = -1, | 679 | .index = -1, |
680 | .data = &serial8250_reg, | 680 | .data = &serial8250_reg, |
681 | }; | 681 | }; |
@@ -974,6 +974,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
974 | 974 | ||
975 | uart = serial8250_find_match_or_unused(&up->port); | 975 | uart = serial8250_find_match_or_unused(&up->port); |
976 | if (uart && uart->port.type != PORT_8250_CIR) { | 976 | if (uart && uart->port.type != PORT_8250_CIR) { |
977 | struct mctrl_gpios *gpios; | ||
978 | |||
977 | if (uart->port.dev) | 979 | if (uart->port.dev) |
978 | uart_remove_one_port(&serial8250_reg, &uart->port); | 980 | uart_remove_one_port(&serial8250_reg, &uart->port); |
979 | 981 | ||
@@ -1011,6 +1013,13 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
1011 | if (up->port.flags & UPF_FIXED_TYPE) | 1013 | if (up->port.flags & UPF_FIXED_TYPE) |
1012 | uart->port.type = up->port.type; | 1014 | uart->port.type = up->port.type; |
1013 | 1015 | ||
1016 | gpios = mctrl_gpio_init(&uart->port, 0); | ||
1017 | if (IS_ERR(gpios)) { | ||
1018 | if (PTR_ERR(gpios) != -ENOSYS) | ||
1019 | return PTR_ERR(gpios); | ||
1020 | } else | ||
1021 | uart->gpios = gpios; | ||
1022 | |||
1014 | serial8250_set_defaults(uart); | 1023 | serial8250_set_defaults(uart); |
1015 | 1024 | ||
1016 | /* Possibly override default I/O functions. */ | 1025 | /* Possibly override default I/O functions. */ |
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 7f33d1c8d1a9..3590d012001f 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -145,6 +145,7 @@ void serial8250_rx_dma_flush(struct uart_8250_port *p) | |||
145 | dmaengine_terminate_all(dma->rxchan); | 145 | dmaengine_terminate_all(dma->rxchan); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush); | ||
148 | 149 | ||
149 | int serial8250_request_dma(struct uart_8250_port *p) | 150 | int serial8250_request_dma(struct uart_8250_port *p) |
150 | { | 151 | { |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 8d08ff5c4e34..85a12f032402 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -150,6 +150,7 @@ EARLYCON_DECLARE(uart, early_serial8250_setup); | |||
150 | OF_EARLYCON_DECLARE(ns16550, "ns16550", early_serial8250_setup); | 150 | OF_EARLYCON_DECLARE(ns16550, "ns16550", early_serial8250_setup); |
151 | OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup); | 151 | OF_EARLYCON_DECLARE(ns16550a, "ns16550a", early_serial8250_setup); |
152 | OF_EARLYCON_DECLARE(uart, "nvidia,tegra20-uart", early_serial8250_setup); | 152 | OF_EARLYCON_DECLARE(uart, "nvidia,tegra20-uart", early_serial8250_setup); |
153 | OF_EARLYCON_DECLARE(uart, "snps,dw-apb-uart", early_serial8250_setup); | ||
153 | 154 | ||
154 | #ifdef CONFIG_SERIAL_8250_OMAP | 155 | #ifdef CONFIG_SERIAL_8250_OMAP |
155 | 156 | ||
diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c index 870981dd9e39..737b4b3957b0 100644 --- a/drivers/tty/serial/8250/8250_fintek.c +++ b/drivers/tty/serial/8250/8250_fintek.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/pnp.h> | 13 | #include <linux/pnp.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/serial_core.h> | 15 | #include <linux/serial_core.h> |
16 | #include <linux/irq.h> | ||
16 | #include "8250.h" | 17 | #include "8250.h" |
17 | 18 | ||
18 | #define ADDR_PORT 0 | 19 | #define ADDR_PORT 0 |
@@ -30,6 +31,12 @@ | |||
30 | #define IO_ADDR2 0x60 | 31 | #define IO_ADDR2 0x60 |
31 | #define LDN 0x7 | 32 | #define LDN 0x7 |
32 | 33 | ||
34 | #define IRQ_MODE 0x70 | ||
35 | #define IRQ_SHARE BIT(4) | ||
36 | #define IRQ_MODE_MASK (BIT(6) | BIT(5)) | ||
37 | #define IRQ_LEVEL_LOW 0 | ||
38 | #define IRQ_EDGE_HIGH BIT(5) | ||
39 | |||
33 | #define RS485 0xF0 | 40 | #define RS485 0xF0 |
34 | #define RTS_INVERT BIT(5) | 41 | #define RTS_INVERT BIT(5) |
35 | #define RS485_URA BIT(4) | 42 | #define RS485_URA BIT(4) |
@@ -176,10 +183,37 @@ static int find_base_port(struct fintek_8250 *pdata, u16 io_address) | |||
176 | return -ENODEV; | 183 | return -ENODEV; |
177 | } | 184 | } |
178 | 185 | ||
186 | static int fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool level_mode) | ||
187 | { | ||
188 | int status; | ||
189 | u8 tmp; | ||
190 | |||
191 | status = fintek_8250_enter_key(pdata->base_port, pdata->key); | ||
192 | if (status) | ||
193 | return status; | ||
194 | |||
195 | outb(LDN, pdata->base_port + ADDR_PORT); | ||
196 | outb(pdata->index, pdata->base_port + DATA_PORT); | ||
197 | |||
198 | outb(IRQ_MODE, pdata->base_port + ADDR_PORT); | ||
199 | tmp = inb(pdata->base_port + DATA_PORT); | ||
200 | |||
201 | tmp &= ~IRQ_MODE_MASK; | ||
202 | tmp |= IRQ_SHARE; | ||
203 | if (!level_mode) | ||
204 | tmp |= IRQ_EDGE_HIGH; | ||
205 | |||
206 | outb(tmp, pdata->base_port + DATA_PORT); | ||
207 | fintek_8250_exit_key(pdata->base_port); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
179 | int fintek_8250_probe(struct uart_8250_port *uart) | 211 | int fintek_8250_probe(struct uart_8250_port *uart) |
180 | { | 212 | { |
181 | struct fintek_8250 *pdata; | 213 | struct fintek_8250 *pdata; |
182 | struct fintek_8250 probe_data; | 214 | struct fintek_8250 probe_data; |
215 | struct irq_data *irq_data = irq_get_irq_data(uart->port.irq); | ||
216 | bool level_mode = irqd_is_level_type(irq_data); | ||
183 | 217 | ||
184 | if (find_base_port(&probe_data, uart->port.iobase)) | 218 | if (find_base_port(&probe_data, uart->port.iobase)) |
185 | return -ENODEV; | 219 | return -ENODEV; |
@@ -192,5 +226,5 @@ int fintek_8250_probe(struct uart_8250_port *uart) | |||
192 | uart->port.rs485_config = fintek_8250_rs485_config; | 226 | uart->port.rs485_config = fintek_8250_rs485_config; |
193 | uart->port.private_data = pdata; | 227 | uart->port.private_data = pdata; |
194 | 228 | ||
195 | return 0; | 229 | return fintek_8250_set_irq_mode(pdata, level_mode); |
196 | } | 230 | } |
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index b0677f610863..4d9dc10e265c 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c | |||
@@ -48,7 +48,6 @@ static const struct of_device_id of_match[]; | |||
48 | #define UART_MCR_MDCE BIT(7) | 48 | #define UART_MCR_MDCE BIT(7) |
49 | #define UART_MCR_FCM BIT(6) | 49 | #define UART_MCR_FCM BIT(6) |
50 | 50 | ||
51 | #if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE) | ||
52 | static struct earlycon_device *early_device; | 51 | static struct earlycon_device *early_device; |
53 | 52 | ||
54 | static uint8_t __init early_in(struct uart_port *port, int offset) | 53 | static uint8_t __init early_in(struct uart_port *port, int offset) |
@@ -141,7 +140,6 @@ OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart", | |||
141 | EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup); | 140 | EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup); |
142 | OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart", | 141 | OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart", |
143 | ingenic_early_console_setup); | 142 | ingenic_early_console_setup); |
144 | #endif /* CONFIG_SERIAL_EARLYCON */ | ||
145 | 143 | ||
146 | static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) | 144 | static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value) |
147 | { | 145 | { |
diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c index 86379a79a6a3..339de9cd0866 100644 --- a/drivers/tty/serial/8250/8250_mid.c +++ b/drivers/tty/serial/8250/8250_mid.c | |||
@@ -96,13 +96,27 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p) | |||
96 | static int dnv_handle_irq(struct uart_port *p) | 96 | static int dnv_handle_irq(struct uart_port *p) |
97 | { | 97 | { |
98 | struct mid8250 *mid = p->private_data; | 98 | struct mid8250 *mid = p->private_data; |
99 | struct uart_8250_port *up = up_to_u8250p(p); | ||
99 | unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR); | 100 | unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR); |
101 | u32 status; | ||
100 | int ret = IRQ_NONE; | 102 | int ret = IRQ_NONE; |
101 | 103 | int err; | |
102 | if (fisr & BIT(2)) | 104 | |
103 | ret |= hsu_dma_irq(&mid->dma_chip, 1); | 105 | if (fisr & BIT(2)) { |
104 | if (fisr & BIT(1)) | 106 | err = hsu_dma_get_status(&mid->dma_chip, 1, &status); |
105 | ret |= hsu_dma_irq(&mid->dma_chip, 0); | 107 | if (err > 0) { |
108 | serial8250_rx_dma_flush(up); | ||
109 | ret |= IRQ_HANDLED; | ||
110 | } else if (err == 0) | ||
111 | ret |= hsu_dma_do_irq(&mid->dma_chip, 1, status); | ||
112 | } | ||
113 | if (fisr & BIT(1)) { | ||
114 | err = hsu_dma_get_status(&mid->dma_chip, 0, &status); | ||
115 | if (err > 0) | ||
116 | ret |= IRQ_HANDLED; | ||
117 | else if (err == 0) | ||
118 | ret |= hsu_dma_do_irq(&mid->dma_chip, 0, status); | ||
119 | } | ||
106 | if (fisr & BIT(0)) | 120 | if (fisr & BIT(0)) |
107 | ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); | 121 | ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR)); |
108 | return ret; | 122 | return ret; |
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 3489fbcb7313..3611ec9bb4fa 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c | |||
@@ -301,7 +301,7 @@ static struct platform_driver mtk8250_platform_driver = { | |||
301 | }; | 301 | }; |
302 | module_platform_driver(mtk8250_platform_driver); | 302 | module_platform_driver(mtk8250_platform_driver); |
303 | 303 | ||
304 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && !defined(MODULE) | 304 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
305 | static int __init early_mtk8250_setup(struct earlycon_device *device, | 305 | static int __init early_mtk8250_setup(struct earlycon_device *device, |
306 | const char *options) | 306 | const char *options) |
307 | { | 307 | { |
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 2c44c792d586..e14982f36a04 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c | |||
@@ -134,18 +134,21 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
134 | 134 | ||
135 | serial8250_do_set_mctrl(port, mctrl); | 135 | serial8250_do_set_mctrl(port, mctrl); |
136 | 136 | ||
137 | /* | 137 | if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios, |
138 | * Turn off autoRTS if RTS is lowered and restore autoRTS setting | 138 | UART_GPIO_RTS))) { |
139 | * if RTS is raised | 139 | /* |
140 | */ | 140 | * Turn off autoRTS if RTS is lowered and restore autoRTS |
141 | lcr = serial_in(up, UART_LCR); | 141 | * setting if RTS is raised |
142 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 142 | */ |
143 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) | 143 | lcr = serial_in(up, UART_LCR); |
144 | priv->efr |= UART_EFR_RTS; | 144 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
145 | else | 145 | if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS)) |
146 | priv->efr &= ~UART_EFR_RTS; | 146 | priv->efr |= UART_EFR_RTS; |
147 | serial_out(up, UART_EFR, priv->efr); | 147 | else |
148 | serial_out(up, UART_LCR, lcr); | 148 | priv->efr &= ~UART_EFR_RTS; |
149 | serial_out(up, UART_EFR, priv->efr); | ||
150 | serial_out(up, UART_LCR, lcr); | ||
151 | } | ||
149 | } | 152 | } |
150 | 153 | ||
151 | /* | 154 | /* |
@@ -280,7 +283,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) | |||
280 | serial_out(up, UART_EFR, UART_EFR_ECB); | 283 | serial_out(up, UART_EFR, UART_EFR_ECB); |
281 | 284 | ||
282 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 285 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
283 | serial_out(up, UART_MCR, UART_MCR_TCRTLR); | 286 | serial8250_out_MCR(up, UART_MCR_TCRTLR); |
284 | serial_out(up, UART_FCR, up->fcr); | 287 | serial_out(up, UART_FCR, up->fcr); |
285 | 288 | ||
286 | omap8250_update_scr(up, priv); | 289 | omap8250_update_scr(up, priv); |
@@ -296,7 +299,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) | |||
296 | serial_out(up, UART_LCR, 0); | 299 | serial_out(up, UART_LCR, 0); |
297 | 300 | ||
298 | /* drop TCR + TLR access, we setup XON/XOFF later */ | 301 | /* drop TCR + TLR access, we setup XON/XOFF later */ |
299 | serial_out(up, UART_MCR, up->mcr); | 302 | serial8250_out_MCR(up, up->mcr); |
300 | serial_out(up, UART_IER, up->ier); | 303 | serial_out(up, UART_IER, up->ier); |
301 | 304 | ||
302 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 305 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
@@ -446,7 +449,9 @@ static void omap_8250_set_termios(struct uart_port *port, | |||
446 | priv->efr = 0; | 449 | priv->efr = 0; |
447 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); | 450 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); |
448 | 451 | ||
449 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { | 452 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW |
453 | && IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(up->gpios, | ||
454 | UART_GPIO_RTS))) { | ||
450 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ | 455 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ |
451 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; | 456 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; |
452 | priv->efr |= UART_EFR_CTS; | 457 | priv->efr |= UART_EFR_CTS; |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 8dd250fbd367..20ebaea5c414 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1136,11 +1136,11 @@ static int pci_quatech_rqopr(struct uart_8250_port *port) | |||
1136 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) | 1136 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) |
1137 | { | 1137 | { |
1138 | unsigned long base = port->port.iobase; | 1138 | unsigned long base = port->port.iobase; |
1139 | u8 LCR, val; | 1139 | u8 LCR; |
1140 | 1140 | ||
1141 | LCR = inb(base + UART_LCR); | 1141 | LCR = inb(base + UART_LCR); |
1142 | outb(0xBF, base + UART_LCR); | 1142 | outb(0xBF, base + UART_LCR); |
1143 | val = inb(base + UART_SCR); | 1143 | inb(base + UART_SCR); |
1144 | outb(qopr, base + UART_SCR); | 1144 | outb(qopr, base + UART_SCR); |
1145 | outb(LCR, base + UART_LCR); | 1145 | outb(LCR, base + UART_LCR); |
1146 | } | 1146 | } |
@@ -1865,6 +1865,16 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1865 | } | 1865 | } |
1866 | 1866 | ||
1867 | static int | 1867 | static int |
1868 | pci_wch_ch355_setup(struct serial_private *priv, | ||
1869 | const struct pciserial_board *board, | ||
1870 | struct uart_8250_port *port, int idx) | ||
1871 | { | ||
1872 | port->port.flags |= UPF_FIXED_TYPE; | ||
1873 | port->port.type = PORT_16550A; | ||
1874 | return pci_default_setup(priv, board, port, idx); | ||
1875 | } | ||
1876 | |||
1877 | static int | ||
1868 | pci_wch_ch38x_setup(struct serial_private *priv, | 1878 | pci_wch_ch38x_setup(struct serial_private *priv, |
1869 | const struct pciserial_board *board, | 1879 | const struct pciserial_board *board, |
1870 | struct uart_8250_port *port, int idx) | 1880 | struct uart_8250_port *port, int idx) |
@@ -1915,6 +1925,7 @@ pci_wch_ch38x_setup(struct serial_private *priv, | |||
1915 | #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 | 1925 | #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 |
1916 | #define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 | 1926 | #define PCI_DEVICE_ID_WCH_CH353_1S1P 0x5053 |
1917 | #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 | 1927 | #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 |
1928 | #define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 | ||
1918 | #define PCI_VENDOR_ID_AGESTAR 0x5372 | 1929 | #define PCI_VENDOR_ID_AGESTAR 0x5372 |
1919 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 | 1930 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 |
1920 | #define PCI_VENDOR_ID_ASIX 0x9710 | 1931 | #define PCI_VENDOR_ID_ASIX 0x9710 |
@@ -2618,6 +2629,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
2618 | .subdevice = PCI_ANY_ID, | 2629 | .subdevice = PCI_ANY_ID, |
2619 | .setup = pci_wch_ch353_setup, | 2630 | .setup = pci_wch_ch353_setup, |
2620 | }, | 2631 | }, |
2632 | /* WCH CH355 4S card (16550 clone) */ | ||
2633 | { | ||
2634 | .vendor = PCI_VENDOR_ID_WCH, | ||
2635 | .device = PCI_DEVICE_ID_WCH_CH355_4S, | ||
2636 | .subvendor = PCI_ANY_ID, | ||
2637 | .subdevice = PCI_ANY_ID, | ||
2638 | .setup = pci_wch_ch355_setup, | ||
2639 | }, | ||
2621 | /* WCH CH382 2S card (16850 clone) */ | 2640 | /* WCH CH382 2S card (16850 clone) */ |
2622 | { | 2641 | { |
2623 | .vendor = PCIE_VENDOR_ID_WCH, | 2642 | .vendor = PCIE_VENDOR_ID_WCH, |
@@ -3812,6 +3831,7 @@ static const struct pci_device_id blacklist[] = { | |||
3812 | /* multi-io cards handled by parport_serial */ | 3831 | /* multi-io cards handled by parport_serial */ |
3813 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ | 3832 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ |
3814 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ | 3833 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ |
3834 | { PCI_DEVICE(0x4348, 0x7173), }, /* WCH CH355 4S */ | ||
3815 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ | 3835 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ |
3816 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ | 3836 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ |
3817 | 3837 | ||
@@ -5567,6 +5587,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
5567 | PCI_ANY_ID, PCI_ANY_ID, | 5587 | PCI_ANY_ID, PCI_ANY_ID, |
5568 | 0, 0, pbn_b0_bt_2_115200 }, | 5588 | 0, 0, pbn_b0_bt_2_115200 }, |
5569 | 5589 | ||
5590 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH355_4S, | ||
5591 | PCI_ANY_ID, PCI_ANY_ID, | ||
5592 | 0, 0, pbn_b0_bt_4_115200 }, | ||
5593 | |||
5570 | { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH382_2S, | 5594 | { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH382_2S, |
5571 | PCI_ANY_ID, PCI_ANY_ID, | 5595 | PCI_ANY_ID, PCI_ANY_ID, |
5572 | 0, 0, pbn_wch382_2 }, | 5596 | 0, 0, pbn_wch382_2 }, |
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index d4036038a4dd..7481b95c6d84 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c | |||
@@ -527,13 +527,13 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) | |||
527 | 527 | ||
528 | static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) | 528 | static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) |
529 | { | 529 | { |
530 | unsigned char mcr = serial_in(p, UART_MCR); | 530 | unsigned char mcr = serial8250_in_MCR(p); |
531 | 531 | ||
532 | if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) | 532 | if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) |
533 | mcr |= UART_MCR_RTS; | 533 | mcr |= UART_MCR_RTS; |
534 | else | 534 | else |
535 | mcr &= ~UART_MCR_RTS; | 535 | mcr &= ~UART_MCR_RTS; |
536 | serial_out(p, UART_MCR, mcr); | 536 | serial8250_out_MCR(p, mcr); |
537 | } | 537 | } |
538 | 538 | ||
539 | static void serial8250_em485_handle_start_tx(unsigned long arg); | 539 | static void serial8250_em485_handle_start_tx(unsigned long arg); |
@@ -785,10 +785,10 @@ static int size_fifo(struct uart_8250_port *up) | |||
785 | old_lcr = serial_in(up, UART_LCR); | 785 | old_lcr = serial_in(up, UART_LCR); |
786 | serial_out(up, UART_LCR, 0); | 786 | serial_out(up, UART_LCR, 0); |
787 | old_fcr = serial_in(up, UART_FCR); | 787 | old_fcr = serial_in(up, UART_FCR); |
788 | old_mcr = serial_in(up, UART_MCR); | 788 | old_mcr = serial8250_in_MCR(up); |
789 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | | 789 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | |
790 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 790 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
791 | serial_out(up, UART_MCR, UART_MCR_LOOP); | 791 | serial8250_out_MCR(up, UART_MCR_LOOP); |
792 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 792 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
793 | old_dl = serial_dl_read(up); | 793 | old_dl = serial_dl_read(up); |
794 | serial_dl_write(up, 0x0001); | 794 | serial_dl_write(up, 0x0001); |
@@ -800,7 +800,7 @@ static int size_fifo(struct uart_8250_port *up) | |||
800 | (count < 256); count++) | 800 | (count < 256); count++) |
801 | serial_in(up, UART_RX); | 801 | serial_in(up, UART_RX); |
802 | serial_out(up, UART_FCR, old_fcr); | 802 | serial_out(up, UART_FCR, old_fcr); |
803 | serial_out(up, UART_MCR, old_mcr); | 803 | serial8250_out_MCR(up, old_mcr); |
804 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 804 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
805 | serial_dl_write(up, old_dl); | 805 | serial_dl_write(up, old_dl); |
806 | serial_out(up, UART_LCR, old_lcr); | 806 | serial_out(up, UART_LCR, old_lcr); |
@@ -1040,17 +1040,17 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
1040 | * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 | 1040 | * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 |
1041 | */ | 1041 | */ |
1042 | serial_out(up, UART_LCR, 0); | 1042 | serial_out(up, UART_LCR, 0); |
1043 | status1 = serial_in(up, UART_MCR); | 1043 | status1 = serial8250_in_MCR(up); |
1044 | serial_out(up, UART_LCR, 0xE0); | 1044 | serial_out(up, UART_LCR, 0xE0); |
1045 | status2 = serial_in(up, 0x02); /* EXCR1 */ | 1045 | status2 = serial_in(up, 0x02); /* EXCR1 */ |
1046 | 1046 | ||
1047 | if (!((status2 ^ status1) & UART_MCR_LOOP)) { | 1047 | if (!((status2 ^ status1) & UART_MCR_LOOP)) { |
1048 | serial_out(up, UART_LCR, 0); | 1048 | serial_out(up, UART_LCR, 0); |
1049 | serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); | 1049 | serial8250_out_MCR(up, status1 ^ UART_MCR_LOOP); |
1050 | serial_out(up, UART_LCR, 0xE0); | 1050 | serial_out(up, UART_LCR, 0xE0); |
1051 | status2 = serial_in(up, 0x02); /* EXCR1 */ | 1051 | status2 = serial_in(up, 0x02); /* EXCR1 */ |
1052 | serial_out(up, UART_LCR, 0); | 1052 | serial_out(up, UART_LCR, 0); |
1053 | serial_out(up, UART_MCR, status1); | 1053 | serial8250_out_MCR(up, status1); |
1054 | 1054 | ||
1055 | if ((status2 ^ status1) & UART_MCR_LOOP) { | 1055 | if ((status2 ^ status1) & UART_MCR_LOOP) { |
1056 | unsigned short quot; | 1056 | unsigned short quot; |
@@ -1224,7 +1224,7 @@ static void autoconfig(struct uart_8250_port *up) | |||
1224 | } | 1224 | } |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | save_mcr = serial_in(up, UART_MCR); | 1227 | save_mcr = serial8250_in_MCR(up); |
1228 | save_lcr = serial_in(up, UART_LCR); | 1228 | save_lcr = serial_in(up, UART_LCR); |
1229 | 1229 | ||
1230 | /* | 1230 | /* |
@@ -1237,9 +1237,9 @@ static void autoconfig(struct uart_8250_port *up) | |||
1237 | * that conflicts with COM 1-4 --- we hope! | 1237 | * that conflicts with COM 1-4 --- we hope! |
1238 | */ | 1238 | */ |
1239 | if (!(port->flags & UPF_SKIP_TEST)) { | 1239 | if (!(port->flags & UPF_SKIP_TEST)) { |
1240 | serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); | 1240 | serial8250_out_MCR(up, UART_MCR_LOOP | 0x0A); |
1241 | status1 = serial_in(up, UART_MSR) & 0xF0; | 1241 | status1 = serial_in(up, UART_MSR) & 0xF0; |
1242 | serial_out(up, UART_MCR, save_mcr); | 1242 | serial8250_out_MCR(up, save_mcr); |
1243 | if (status1 != 0x90) { | 1243 | if (status1 != 0x90) { |
1244 | spin_unlock_irqrestore(&port->lock, flags); | 1244 | spin_unlock_irqrestore(&port->lock, flags); |
1245 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", | 1245 | DEBUG_AUTOCONF("LOOP test failed (%02x) ", |
@@ -1305,7 +1305,7 @@ static void autoconfig(struct uart_8250_port *up) | |||
1305 | if (port->type == PORT_RSA) | 1305 | if (port->type == PORT_RSA) |
1306 | serial_out(up, UART_RSA_FRR, 0); | 1306 | serial_out(up, UART_RSA_FRR, 0); |
1307 | #endif | 1307 | #endif |
1308 | serial_out(up, UART_MCR, save_mcr); | 1308 | serial8250_out_MCR(up, save_mcr); |
1309 | serial8250_clear_fifos(up); | 1309 | serial8250_clear_fifos(up); |
1310 | serial_in(up, UART_RX); | 1310 | serial_in(up, UART_RX); |
1311 | if (up->capabilities & UART_CAP_UUE) | 1311 | if (up->capabilities & UART_CAP_UUE) |
@@ -1353,19 +1353,18 @@ static void autoconfig_irq(struct uart_8250_port *up) | |||
1353 | 1353 | ||
1354 | /* forget possible initially masked and pending IRQ */ | 1354 | /* forget possible initially masked and pending IRQ */ |
1355 | probe_irq_off(probe_irq_on()); | 1355 | probe_irq_off(probe_irq_on()); |
1356 | save_mcr = serial_in(up, UART_MCR); | 1356 | save_mcr = serial8250_in_MCR(up); |
1357 | save_ier = serial_in(up, UART_IER); | 1357 | save_ier = serial_in(up, UART_IER); |
1358 | serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); | 1358 | serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); |
1359 | 1359 | ||
1360 | irqs = probe_irq_on(); | 1360 | irqs = probe_irq_on(); |
1361 | serial_out(up, UART_MCR, 0); | 1361 | serial8250_out_MCR(up, 0); |
1362 | udelay(10); | 1362 | udelay(10); |
1363 | if (port->flags & UPF_FOURPORT) { | 1363 | if (port->flags & UPF_FOURPORT) { |
1364 | serial_out(up, UART_MCR, | 1364 | serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); |
1365 | UART_MCR_DTR | UART_MCR_RTS); | ||
1366 | } else { | 1365 | } else { |
1367 | serial_out(up, UART_MCR, | 1366 | serial8250_out_MCR(up, |
1368 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); | 1367 | UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); |
1369 | } | 1368 | } |
1370 | serial_out(up, UART_IER, 0x0f); /* enable all intrs */ | 1369 | serial_out(up, UART_IER, 0x0f); /* enable all intrs */ |
1371 | serial_in(up, UART_LSR); | 1370 | serial_in(up, UART_LSR); |
@@ -1376,7 +1375,7 @@ static void autoconfig_irq(struct uart_8250_port *up) | |||
1376 | udelay(20); | 1375 | udelay(20); |
1377 | irq = probe_irq_off(irqs); | 1376 | irq = probe_irq_off(irqs); |
1378 | 1377 | ||
1379 | serial_out(up, UART_MCR, save_mcr); | 1378 | serial8250_out_MCR(up, save_mcr); |
1380 | serial_out(up, UART_IER, save_ier); | 1379 | serial_out(up, UART_IER, save_ier); |
1381 | 1380 | ||
1382 | if (port->flags & UPF_FOURPORT) | 1381 | if (port->flags & UPF_FOURPORT) |
@@ -1549,14 +1548,14 @@ static inline void start_tx_rs485(struct uart_port *port) | |||
1549 | del_timer(&em485->stop_tx_timer); | 1548 | del_timer(&em485->stop_tx_timer); |
1550 | em485->active_timer = NULL; | 1549 | em485->active_timer = NULL; |
1551 | 1550 | ||
1552 | mcr = serial_in(up, UART_MCR); | 1551 | mcr = serial8250_in_MCR(up); |
1553 | if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != | 1552 | if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != |
1554 | !!(mcr & UART_MCR_RTS)) { | 1553 | !!(mcr & UART_MCR_RTS)) { |
1555 | if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) | 1554 | if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) |
1556 | mcr |= UART_MCR_RTS; | 1555 | mcr |= UART_MCR_RTS; |
1557 | else | 1556 | else |
1558 | mcr &= ~UART_MCR_RTS; | 1557 | mcr &= ~UART_MCR_RTS; |
1559 | serial_out(up, UART_MCR, mcr); | 1558 | serial8250_out_MCR(up, mcr); |
1560 | 1559 | ||
1561 | if (up->port.rs485.delay_rts_before_send > 0) { | 1560 | if (up->port.rs485.delay_rts_before_send > 0) { |
1562 | em485->active_timer = &em485->start_tx_timer; | 1561 | em485->active_timer = &em485->start_tx_timer; |
@@ -1619,6 +1618,8 @@ static void serial8250_disable_ms(struct uart_port *port) | |||
1619 | if (up->bugs & UART_BUG_NOMSR) | 1618 | if (up->bugs & UART_BUG_NOMSR) |
1620 | return; | 1619 | return; |
1621 | 1620 | ||
1621 | mctrl_gpio_disable_ms(up->gpios); | ||
1622 | |||
1622 | up->ier &= ~UART_IER_MSI; | 1623 | up->ier &= ~UART_IER_MSI; |
1623 | serial_port_out(port, UART_IER, up->ier); | 1624 | serial_port_out(port, UART_IER, up->ier); |
1624 | } | 1625 | } |
@@ -1631,6 +1632,8 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1631 | if (up->bugs & UART_BUG_NOMSR) | 1632 | if (up->bugs & UART_BUG_NOMSR) |
1632 | return; | 1633 | return; |
1633 | 1634 | ||
1635 | mctrl_gpio_enable_ms(up->gpios); | ||
1636 | |||
1634 | up->ier |= UART_IER_MSI; | 1637 | up->ier |= UART_IER_MSI; |
1635 | 1638 | ||
1636 | serial8250_rpm_get(up); | 1639 | serial8250_rpm_get(up); |
@@ -1686,7 +1689,7 @@ static void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr) | |||
1686 | lsr &= port->read_status_mask; | 1689 | lsr &= port->read_status_mask; |
1687 | 1690 | ||
1688 | if (lsr & UART_LSR_BI) { | 1691 | if (lsr & UART_LSR_BI) { |
1689 | DEBUG_INTR("handling break...."); | 1692 | pr_debug("%s: handling break\n", __func__); |
1690 | flag = TTY_BREAK; | 1693 | flag = TTY_BREAK; |
1691 | } else if (lsr & UART_LSR_PE) | 1694 | } else if (lsr & UART_LSR_PE) |
1692 | flag = TTY_PARITY; | 1695 | flag = TTY_PARITY; |
@@ -1757,7 +1760,7 @@ void serial8250_tx_chars(struct uart_8250_port *up) | |||
1757 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 1760 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
1758 | uart_write_wakeup(port); | 1761 | uart_write_wakeup(port); |
1759 | 1762 | ||
1760 | DEBUG_INTR("THRE..."); | 1763 | pr_debug("%s: THRE\n", __func__); |
1761 | 1764 | ||
1762 | /* | 1765 | /* |
1763 | * With RPM enabled, we have to wait until the FIFO is empty before the | 1766 | * With RPM enabled, we have to wait until the FIFO is empty before the |
@@ -1823,7 +1826,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1823 | 1826 | ||
1824 | status = serial_port_in(port, UART_LSR); | 1827 | status = serial_port_in(port, UART_LSR); |
1825 | 1828 | ||
1826 | DEBUG_INTR("status = %x...", status); | 1829 | pr_debug("%s: status = %x\n", __func__, status); |
1827 | 1830 | ||
1828 | if (status & (UART_LSR_DR | UART_LSR_BI)) { | 1831 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1829 | if (!up->dma || handle_rx_dma(up, iir)) | 1832 | if (!up->dma || handle_rx_dma(up, iir)) |
@@ -1861,7 +1864,6 @@ static int serial8250_default_handle_irq(struct uart_port *port) | |||
1861 | */ | 1864 | */ |
1862 | static int exar_handle_irq(struct uart_port *port) | 1865 | static int exar_handle_irq(struct uart_port *port) |
1863 | { | 1866 | { |
1864 | unsigned char int0, int1, int2, int3; | ||
1865 | unsigned int iir = serial_port_in(port, UART_IIR); | 1867 | unsigned int iir = serial_port_in(port, UART_IIR); |
1866 | int ret; | 1868 | int ret; |
1867 | 1869 | ||
@@ -1869,10 +1871,10 @@ static int exar_handle_irq(struct uart_port *port) | |||
1869 | 1871 | ||
1870 | if ((port->type == PORT_XR17V35X) || | 1872 | if ((port->type == PORT_XR17V35X) || |
1871 | (port->type == PORT_XR17D15X)) { | 1873 | (port->type == PORT_XR17D15X)) { |
1872 | int0 = serial_port_in(port, 0x80); | 1874 | serial_port_in(port, 0x80); |
1873 | int1 = serial_port_in(port, 0x81); | 1875 | serial_port_in(port, 0x81); |
1874 | int2 = serial_port_in(port, 0x82); | 1876 | serial_port_in(port, 0x82); |
1875 | int3 = serial_port_in(port, 0x83); | 1877 | serial_port_in(port, 0x83); |
1876 | } | 1878 | } |
1877 | 1879 | ||
1878 | return ret; | 1880 | return ret; |
@@ -1915,7 +1917,8 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port) | |||
1915 | ret |= TIOCM_DSR; | 1917 | ret |= TIOCM_DSR; |
1916 | if (status & UART_MSR_CTS) | 1918 | if (status & UART_MSR_CTS) |
1917 | ret |= TIOCM_CTS; | 1919 | ret |= TIOCM_CTS; |
1918 | return ret; | 1920 | |
1921 | return mctrl_gpio_get(up->gpios, &ret); | ||
1919 | } | 1922 | } |
1920 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); | 1923 | EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl); |
1921 | 1924 | ||
@@ -1944,7 +1947,7 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
1944 | 1947 | ||
1945 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; | 1948 | mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; |
1946 | 1949 | ||
1947 | serial_port_out(port, UART_MCR, mcr); | 1950 | serial8250_out_MCR(up, mcr); |
1948 | } | 1951 | } |
1949 | EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); | 1952 | EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); |
1950 | 1953 | ||
@@ -1994,8 +1997,6 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1994 | 1997 | ||
1995 | /* Wait up to 1s for flow control if necessary */ | 1998 | /* Wait up to 1s for flow control if necessary */ |
1996 | if (up->port.flags & UPF_CONS_FLOW) { | 1999 | if (up->port.flags & UPF_CONS_FLOW) { |
1997 | unsigned int tmout; | ||
1998 | |||
1999 | for (tmout = 1000000; tmout; tmout--) { | 2000 | for (tmout = 1000000; tmout; tmout--) { |
2000 | unsigned int msr = serial_in(up, UART_MSR); | 2001 | unsigned int msr = serial_in(up, UART_MSR); |
2001 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | 2002 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; |
@@ -3093,7 +3094,7 @@ static void serial8250_console_restore(struct uart_8250_port *up) | |||
3093 | 3094 | ||
3094 | serial8250_set_divisor(port, baud, quot, frac); | 3095 | serial8250_set_divisor(port, baud, quot, frac); |
3095 | serial_port_out(port, UART_LCR, up->lcr); | 3096 | serial_port_out(port, UART_LCR, up->lcr); |
3096 | serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); | 3097 | serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); |
3097 | } | 3098 | } |
3098 | 3099 | ||
3099 | /* | 3100 | /* |
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index efd1f9c047b1..b8d9c8c9d02a 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c | |||
@@ -35,7 +35,7 @@ struct uniphier8250_priv { | |||
35 | spinlock_t atomic_write_lock; | 35 | spinlock_t atomic_write_lock; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && !defined(MODULE) | 38 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
39 | static int __init uniphier_early_console_setup(struct earlycon_device *device, | 39 | static int __init uniphier_early_console_setup(struct earlycon_device *device, |
40 | const char *options) | 40 | const char *options) |
41 | { | 41 | { |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index e46761d20f7b..c9ec839a5ddf 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -6,6 +6,7 @@ | |||
6 | config SERIAL_8250 | 6 | config SERIAL_8250 |
7 | tristate "8250/16550 and compatible serial support" | 7 | tristate "8250/16550 and compatible serial support" |
8 | select SERIAL_CORE | 8 | select SERIAL_CORE |
9 | select SERIAL_MCTRL_GPIO if GPIOLIB | ||
9 | ---help--- | 10 | ---help--- |
10 | This selects whether you want to include the driver for the standard | 11 | This selects whether you want to include the driver for the standard |
11 | serial ports. The standard answer is Y. People who might say N | 12 | serial ports. The standard answer is Y. People who might say N |
@@ -387,7 +388,8 @@ config SERIAL_8250_MT6577 | |||
387 | 388 | ||
388 | config SERIAL_8250_UNIPHIER | 389 | config SERIAL_8250_UNIPHIER |
389 | tristate "Support for UniPhier on-chip UART" | 390 | tristate "Support for UniPhier on-chip UART" |
390 | depends on SERIAL_8250 && ARCH_UNIPHIER | 391 | depends on SERIAL_8250 |
392 | depends on ARCH_UNIPHIER || COMPILE_TEST | ||
391 | help | 393 | help |
392 | If you have a UniPhier based board and want to use the on-chip | 394 | If you have a UniPhier based board and want to use the on-chip |
393 | serial ports, say Y to this option. If unsure, say N. | 395 | serial ports, say Y to this option. If unsure, say N. |
@@ -395,7 +397,7 @@ config SERIAL_8250_UNIPHIER | |||
395 | config SERIAL_8250_INGENIC | 397 | config SERIAL_8250_INGENIC |
396 | tristate "Support for Ingenic SoC serial ports" | 398 | tristate "Support for Ingenic SoC serial ports" |
397 | depends on SERIAL_8250 | 399 | depends on SERIAL_8250 |
398 | depends on (OF_FLATTREE && SERIAL_8250_CONSOLE) || !SERIAL_EARLYCON | 400 | depends on OF_FLATTREE |
399 | depends on MIPS || COMPILE_TEST | 401 | depends on MIPS || COMPILE_TEST |
400 | help | 402 | help |
401 | If you have a system using an Ingenic SoC and wish to make use of | 403 | If you have a system using an Ingenic SoC and wish to make use of |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 7e3a58c8bb67..518db24a5b36 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -736,6 +736,7 @@ config SERIAL_SH_SCI | |||
736 | tristate "SuperH SCI(F) serial port support" | 736 | tristate "SuperH SCI(F) serial port support" |
737 | depends on SUPERH || ARCH_RENESAS || H8300 || COMPILE_TEST | 737 | depends on SUPERH || ARCH_RENESAS || H8300 || COMPILE_TEST |
738 | select SERIAL_CORE | 738 | select SERIAL_CORE |
739 | select SERIAL_MCTRL_GPIO if GPIOLIB | ||
739 | 740 | ||
740 | config SERIAL_SH_SCI_NR_UARTS | 741 | config SERIAL_SH_SCI_NR_UARTS |
741 | int "Maximum number of SCI(F) serial ports" | 742 | int "Maximum number of SCI(F) serial ports" |
@@ -1477,7 +1478,7 @@ config SERIAL_MPS2_UART_CONSOLE | |||
1477 | 1478 | ||
1478 | config SERIAL_MPS2_UART | 1479 | config SERIAL_MPS2_UART |
1479 | bool "MPS2 UART port" | 1480 | bool "MPS2 UART port" |
1480 | depends on ARM || COMPILE_TEST | 1481 | depends on ARCH_MPS2 || COMPILE_TEST |
1481 | select SERIAL_CORE | 1482 | select SERIAL_CORE |
1482 | help | 1483 | help |
1483 | This driver support the UART ports on ARM MPS2. | 1484 | This driver support the UART ports on ARM MPS2. |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 1b7331e40d79..8a9e213387a7 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -2553,11 +2553,17 @@ static int sbsa_uart_probe(struct platform_device *pdev) | |||
2553 | if (!uap) | 2553 | if (!uap) |
2554 | return -ENOMEM; | 2554 | return -ENOMEM; |
2555 | 2555 | ||
2556 | ret = platform_get_irq(pdev, 0); | ||
2557 | if (ret < 0) { | ||
2558 | dev_err(&pdev->dev, "cannot obtain irq\n"); | ||
2559 | return ret; | ||
2560 | } | ||
2561 | uap->port.irq = ret; | ||
2562 | |||
2556 | uap->reg_offset = vendor_sbsa.reg_offset; | 2563 | uap->reg_offset = vendor_sbsa.reg_offset; |
2557 | uap->vendor = &vendor_sbsa; | 2564 | uap->vendor = &vendor_sbsa; |
2558 | uap->fifosize = 32; | 2565 | uap->fifosize = 32; |
2559 | uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM; | 2566 | uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM; |
2560 | uap->port.irq = platform_get_irq(pdev, 0); | ||
2561 | uap->port.ops = &sbsa_uart_pops; | 2567 | uap->port.ops = &sbsa_uart_pops; |
2562 | uap->fixed_baud = baudrate; | 2568 | uap->fixed_baud = baudrate; |
2563 | 2569 | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 954941dd8124..2eaa18ddef61 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -108,6 +108,12 @@ struct atmel_uart_char { | |||
108 | u16 ch; | 108 | u16 ch; |
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* | ||
112 | * Be careful, the real size of the ring buffer is | ||
113 | * sizeof(atmel_uart_char) * ATMEL_SERIAL_RINGSIZE. It means that ring buffer | ||
114 | * can contain up to 1024 characters in PIO mode and up to 4096 characters in | ||
115 | * DMA mode. | ||
116 | */ | ||
111 | #define ATMEL_SERIAL_RINGSIZE 1024 | 117 | #define ATMEL_SERIAL_RINGSIZE 1024 |
112 | 118 | ||
113 | /* | 119 | /* |
@@ -145,10 +151,10 @@ struct atmel_uart_port { | |||
145 | dma_cookie_t cookie_rx; | 151 | dma_cookie_t cookie_rx; |
146 | struct scatterlist sg_tx; | 152 | struct scatterlist sg_tx; |
147 | struct scatterlist sg_rx; | 153 | struct scatterlist sg_rx; |
148 | struct tasklet_struct tasklet; | 154 | struct tasklet_struct tasklet_rx; |
149 | unsigned int irq_status; | 155 | struct tasklet_struct tasklet_tx; |
156 | atomic_t tasklet_shutdown; | ||
150 | unsigned int irq_status_prev; | 157 | unsigned int irq_status_prev; |
151 | unsigned int status_change; | ||
152 | unsigned int tx_len; | 158 | unsigned int tx_len; |
153 | 159 | ||
154 | struct circ_buf rx_ring; | 160 | struct circ_buf rx_ring; |
@@ -281,6 +287,13 @@ static bool atmel_use_fifo(struct uart_port *port) | |||
281 | return atmel_port->fifo_size; | 287 | return atmel_port->fifo_size; |
282 | } | 288 | } |
283 | 289 | ||
290 | static void atmel_tasklet_schedule(struct atmel_uart_port *atmel_port, | ||
291 | struct tasklet_struct *t) | ||
292 | { | ||
293 | if (!atomic_read(&atmel_port->tasklet_shutdown)) | ||
294 | tasklet_schedule(t); | ||
295 | } | ||
296 | |||
284 | static unsigned int atmel_get_lines_status(struct uart_port *port) | 297 | static unsigned int atmel_get_lines_status(struct uart_port *port) |
285 | { | 298 | { |
286 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 299 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
@@ -482,19 +495,21 @@ static void atmel_start_tx(struct uart_port *port) | |||
482 | { | 495 | { |
483 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 496 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
484 | 497 | ||
485 | if (atmel_use_pdc_tx(port)) { | 498 | if (atmel_use_pdc_tx(port) && (atmel_uart_readl(port, ATMEL_PDC_PTSR) |
486 | if (atmel_uart_readl(port, ATMEL_PDC_PTSR) & ATMEL_PDC_TXTEN) | 499 | & ATMEL_PDC_TXTEN)) |
487 | /* The transmitter is already running. Yes, we | 500 | /* The transmitter is already running. Yes, we |
488 | really need this.*/ | 501 | really need this.*/ |
489 | return; | 502 | return; |
490 | 503 | ||
504 | if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port)) | ||
491 | if ((port->rs485.flags & SER_RS485_ENABLED) && | 505 | if ((port->rs485.flags & SER_RS485_ENABLED) && |
492 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) | 506 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) |
493 | atmel_stop_rx(port); | 507 | atmel_stop_rx(port); |
494 | 508 | ||
509 | if (atmel_use_pdc_tx(port)) | ||
495 | /* re-enable PDC transmit */ | 510 | /* re-enable PDC transmit */ |
496 | atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); | 511 | atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN); |
497 | } | 512 | |
498 | /* Enable interrupts */ | 513 | /* Enable interrupts */ |
499 | atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); | 514 | atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); |
500 | } | 515 | } |
@@ -710,7 +725,7 @@ static void atmel_rx_chars(struct uart_port *port) | |||
710 | status = atmel_uart_readl(port, ATMEL_US_CSR); | 725 | status = atmel_uart_readl(port, ATMEL_US_CSR); |
711 | } | 726 | } |
712 | 727 | ||
713 | tasklet_schedule(&atmel_port->tasklet); | 728 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_rx); |
714 | } | 729 | } |
715 | 730 | ||
716 | /* | 731 | /* |
@@ -781,7 +796,7 @@ static void atmel_complete_tx_dma(void *arg) | |||
781 | * remaining data from the beginning of xmit->buf to xmit->head. | 796 | * remaining data from the beginning of xmit->buf to xmit->head. |
782 | */ | 797 | */ |
783 | if (!uart_circ_empty(xmit)) | 798 | if (!uart_circ_empty(xmit)) |
784 | tasklet_schedule(&atmel_port->tasklet); | 799 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); |
785 | 800 | ||
786 | spin_unlock_irqrestore(&port->lock, flags); | 801 | spin_unlock_irqrestore(&port->lock, flags); |
787 | } | 802 | } |
@@ -966,7 +981,7 @@ static void atmel_complete_rx_dma(void *arg) | |||
966 | struct uart_port *port = arg; | 981 | struct uart_port *port = arg; |
967 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 982 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
968 | 983 | ||
969 | tasklet_schedule(&atmel_port->tasklet); | 984 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_rx); |
970 | } | 985 | } |
971 | 986 | ||
972 | static void atmel_release_rx_dma(struct uart_port *port) | 987 | static void atmel_release_rx_dma(struct uart_port *port) |
@@ -1006,7 +1021,7 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
1006 | if (dmastat == DMA_ERROR) { | 1021 | if (dmastat == DMA_ERROR) { |
1007 | dev_dbg(port->dev, "Get residue error, restart tasklet\n"); | 1022 | dev_dbg(port->dev, "Get residue error, restart tasklet\n"); |
1008 | atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT); | 1023 | atmel_uart_writel(port, ATMEL_US_IER, ATMEL_US_TIMEOUT); |
1009 | tasklet_schedule(&atmel_port->tasklet); | 1024 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_rx); |
1010 | return; | 1025 | return; |
1011 | } | 1026 | } |
1012 | 1027 | ||
@@ -1160,8 +1175,11 @@ static void atmel_uart_timer_callback(unsigned long data) | |||
1160 | struct uart_port *port = (void *)data; | 1175 | struct uart_port *port = (void *)data; |
1161 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1176 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1162 | 1177 | ||
1163 | tasklet_schedule(&atmel_port->tasklet); | 1178 | if (!atomic_read(&atmel_port->tasklet_shutdown)) { |
1164 | mod_timer(&atmel_port->uart_timer, jiffies + uart_poll_timeout(port)); | 1179 | tasklet_schedule(&atmel_port->tasklet_rx); |
1180 | mod_timer(&atmel_port->uart_timer, | ||
1181 | jiffies + uart_poll_timeout(port)); | ||
1182 | } | ||
1165 | } | 1183 | } |
1166 | 1184 | ||
1167 | /* | 1185 | /* |
@@ -1183,7 +1201,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending) | |||
1183 | if (pending & (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)) { | 1201 | if (pending & (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)) { |
1184 | atmel_uart_writel(port, ATMEL_US_IDR, | 1202 | atmel_uart_writel(port, ATMEL_US_IDR, |
1185 | (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)); | 1203 | (ATMEL_US_ENDRX | ATMEL_US_TIMEOUT)); |
1186 | tasklet_schedule(&atmel_port->tasklet); | 1204 | atmel_tasklet_schedule(atmel_port, |
1205 | &atmel_port->tasklet_rx); | ||
1187 | } | 1206 | } |
1188 | 1207 | ||
1189 | if (pending & (ATMEL_US_RXBRK | ATMEL_US_OVRE | | 1208 | if (pending & (ATMEL_US_RXBRK | ATMEL_US_OVRE | |
@@ -1195,7 +1214,8 @@ atmel_handle_receive(struct uart_port *port, unsigned int pending) | |||
1195 | if (pending & ATMEL_US_TIMEOUT) { | 1214 | if (pending & ATMEL_US_TIMEOUT) { |
1196 | atmel_uart_writel(port, ATMEL_US_IDR, | 1215 | atmel_uart_writel(port, ATMEL_US_IDR, |
1197 | ATMEL_US_TIMEOUT); | 1216 | ATMEL_US_TIMEOUT); |
1198 | tasklet_schedule(&atmel_port->tasklet); | 1217 | atmel_tasklet_schedule(atmel_port, |
1218 | &atmel_port->tasklet_rx); | ||
1199 | } | 1219 | } |
1200 | } | 1220 | } |
1201 | 1221 | ||
@@ -1225,7 +1245,7 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) | |||
1225 | /* Either PDC or interrupt transmission */ | 1245 | /* Either PDC or interrupt transmission */ |
1226 | atmel_uart_writel(port, ATMEL_US_IDR, | 1246 | atmel_uart_writel(port, ATMEL_US_IDR, |
1227 | atmel_port->tx_done_mask); | 1247 | atmel_port->tx_done_mask); |
1228 | tasklet_schedule(&atmel_port->tasklet); | 1248 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); |
1229 | } | 1249 | } |
1230 | } | 1250 | } |
1231 | 1251 | ||
@@ -1237,14 +1257,27 @@ atmel_handle_status(struct uart_port *port, unsigned int pending, | |||
1237 | unsigned int status) | 1257 | unsigned int status) |
1238 | { | 1258 | { |
1239 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1259 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1260 | unsigned int status_change; | ||
1240 | 1261 | ||
1241 | if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | 1262 | if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC |
1242 | | ATMEL_US_CTSIC)) { | 1263 | | ATMEL_US_CTSIC)) { |
1243 | atmel_port->irq_status = status; | 1264 | status_change = status ^ atmel_port->irq_status_prev; |
1244 | atmel_port->status_change = atmel_port->irq_status ^ | ||
1245 | atmel_port->irq_status_prev; | ||
1246 | atmel_port->irq_status_prev = status; | 1265 | atmel_port->irq_status_prev = status; |
1247 | tasklet_schedule(&atmel_port->tasklet); | 1266 | |
1267 | if (status_change & (ATMEL_US_RI | ATMEL_US_DSR | ||
1268 | | ATMEL_US_DCD | ATMEL_US_CTS)) { | ||
1269 | /* TODO: All reads to CSR will clear these interrupts! */ | ||
1270 | if (status_change & ATMEL_US_RI) | ||
1271 | port->icount.rng++; | ||
1272 | if (status_change & ATMEL_US_DSR) | ||
1273 | port->icount.dsr++; | ||
1274 | if (status_change & ATMEL_US_DCD) | ||
1275 | uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); | ||
1276 | if (status_change & ATMEL_US_CTS) | ||
1277 | uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); | ||
1278 | |||
1279 | wake_up_interruptible(&port->state->port.delta_msr_wait); | ||
1280 | } | ||
1248 | } | 1281 | } |
1249 | } | 1282 | } |
1250 | 1283 | ||
@@ -1571,37 +1604,25 @@ static int atmel_prepare_rx_pdc(struct uart_port *port) | |||
1571 | /* | 1604 | /* |
1572 | * tasklet handling tty stuff outside the interrupt handler. | 1605 | * tasklet handling tty stuff outside the interrupt handler. |
1573 | */ | 1606 | */ |
1574 | static void atmel_tasklet_func(unsigned long data) | 1607 | static void atmel_tasklet_rx_func(unsigned long data) |
1575 | { | 1608 | { |
1576 | struct uart_port *port = (struct uart_port *)data; | 1609 | struct uart_port *port = (struct uart_port *)data; |
1577 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1610 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1578 | unsigned int status = atmel_port->irq_status; | ||
1579 | unsigned int status_change = atmel_port->status_change; | ||
1580 | 1611 | ||
1581 | /* The interrupt handler does not take the lock */ | 1612 | /* The interrupt handler does not take the lock */ |
1582 | spin_lock(&port->lock); | 1613 | spin_lock(&port->lock); |
1583 | |||
1584 | atmel_port->schedule_tx(port); | ||
1585 | |||
1586 | if (status_change & (ATMEL_US_RI | ATMEL_US_DSR | ||
1587 | | ATMEL_US_DCD | ATMEL_US_CTS)) { | ||
1588 | /* TODO: All reads to CSR will clear these interrupts! */ | ||
1589 | if (status_change & ATMEL_US_RI) | ||
1590 | port->icount.rng++; | ||
1591 | if (status_change & ATMEL_US_DSR) | ||
1592 | port->icount.dsr++; | ||
1593 | if (status_change & ATMEL_US_DCD) | ||
1594 | uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); | ||
1595 | if (status_change & ATMEL_US_CTS) | ||
1596 | uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); | ||
1597 | |||
1598 | wake_up_interruptible(&port->state->port.delta_msr_wait); | ||
1599 | |||
1600 | atmel_port->status_change = 0; | ||
1601 | } | ||
1602 | |||
1603 | atmel_port->schedule_rx(port); | 1614 | atmel_port->schedule_rx(port); |
1615 | spin_unlock(&port->lock); | ||
1616 | } | ||
1617 | |||
1618 | static void atmel_tasklet_tx_func(unsigned long data) | ||
1619 | { | ||
1620 | struct uart_port *port = (struct uart_port *)data; | ||
1621 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | ||
1604 | 1622 | ||
1623 | /* The interrupt handler does not take the lock */ | ||
1624 | spin_lock(&port->lock); | ||
1625 | atmel_port->schedule_tx(port); | ||
1605 | spin_unlock(&port->lock); | 1626 | spin_unlock(&port->lock); |
1606 | } | 1627 | } |
1607 | 1628 | ||
@@ -1785,7 +1806,11 @@ static int atmel_startup(struct uart_port *port) | |||
1785 | return retval; | 1806 | return retval; |
1786 | } | 1807 | } |
1787 | 1808 | ||
1788 | tasklet_enable(&atmel_port->tasklet); | 1809 | atomic_set(&atmel_port->tasklet_shutdown, 0); |
1810 | tasklet_init(&atmel_port->tasklet_rx, atmel_tasklet_rx_func, | ||
1811 | (unsigned long)port); | ||
1812 | tasklet_init(&atmel_port->tasklet_tx, atmel_tasklet_tx_func, | ||
1813 | (unsigned long)port); | ||
1789 | 1814 | ||
1790 | /* | 1815 | /* |
1791 | * Initialize DMA (if necessary) | 1816 | * Initialize DMA (if necessary) |
@@ -1833,7 +1858,6 @@ static int atmel_startup(struct uart_port *port) | |||
1833 | 1858 | ||
1834 | /* Save current CSR for comparison in atmel_tasklet_func() */ | 1859 | /* Save current CSR for comparison in atmel_tasklet_func() */ |
1835 | atmel_port->irq_status_prev = atmel_get_lines_status(port); | 1860 | atmel_port->irq_status_prev = atmel_get_lines_status(port); |
1836 | atmel_port->irq_status = atmel_port->irq_status_prev; | ||
1837 | 1861 | ||
1838 | /* | 1862 | /* |
1839 | * Finally, enable the serial port | 1863 | * Finally, enable the serial port |
@@ -1905,29 +1929,36 @@ static void atmel_shutdown(struct uart_port *port) | |||
1905 | { | 1929 | { |
1906 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1930 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1907 | 1931 | ||
1932 | /* Disable interrupts at device level */ | ||
1933 | atmel_uart_writel(port, ATMEL_US_IDR, -1); | ||
1934 | |||
1935 | /* Prevent spurious interrupts from scheduling the tasklet */ | ||
1936 | atomic_inc(&atmel_port->tasklet_shutdown); | ||
1937 | |||
1908 | /* | 1938 | /* |
1909 | * Prevent any tasklets being scheduled during | 1939 | * Prevent any tasklets being scheduled during |
1910 | * cleanup | 1940 | * cleanup |
1911 | */ | 1941 | */ |
1912 | del_timer_sync(&atmel_port->uart_timer); | 1942 | del_timer_sync(&atmel_port->uart_timer); |
1913 | 1943 | ||
1944 | /* Make sure that no interrupt is on the fly */ | ||
1945 | synchronize_irq(port->irq); | ||
1946 | |||
1914 | /* | 1947 | /* |
1915 | * Clear out any scheduled tasklets before | 1948 | * Clear out any scheduled tasklets before |
1916 | * we destroy the buffers | 1949 | * we destroy the buffers |
1917 | */ | 1950 | */ |
1918 | tasklet_disable(&atmel_port->tasklet); | 1951 | tasklet_kill(&atmel_port->tasklet_rx); |
1919 | tasklet_kill(&atmel_port->tasklet); | 1952 | tasklet_kill(&atmel_port->tasklet_tx); |
1920 | 1953 | ||
1921 | /* | 1954 | /* |
1922 | * Ensure everything is stopped and | 1955 | * Ensure everything is stopped and |
1923 | * disable all interrupts, port and break condition. | 1956 | * disable port and break condition. |
1924 | */ | 1957 | */ |
1925 | atmel_stop_rx(port); | 1958 | atmel_stop_rx(port); |
1926 | atmel_stop_tx(port); | 1959 | atmel_stop_tx(port); |
1927 | 1960 | ||
1928 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA); | 1961 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_RSTSTA); |
1929 | atmel_uart_writel(port, ATMEL_US_IDR, -1); | ||
1930 | |||
1931 | 1962 | ||
1932 | /* | 1963 | /* |
1933 | * Shut-down the DMA. | 1964 | * Shut-down the DMA. |
@@ -2311,10 +2342,6 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, | |||
2311 | port->irq = pdev->resource[1].start; | 2342 | port->irq = pdev->resource[1].start; |
2312 | port->rs485_config = atmel_config_rs485; | 2343 | port->rs485_config = atmel_config_rs485; |
2313 | 2344 | ||
2314 | tasklet_init(&atmel_port->tasklet, atmel_tasklet_func, | ||
2315 | (unsigned long)port); | ||
2316 | tasklet_disable(&atmel_port->tasklet); | ||
2317 | |||
2318 | memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); | 2345 | memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring)); |
2319 | 2346 | ||
2320 | if (pdata && pdata->regs) { | 2347 | if (pdata && pdata->regs) { |
@@ -2699,6 +2726,7 @@ static int atmel_serial_probe(struct platform_device *pdev) | |||
2699 | atmel_port->uart.line = ret; | 2726 | atmel_port->uart.line = ret; |
2700 | atmel_serial_probe_fifos(atmel_port, pdev); | 2727 | atmel_serial_probe_fifos(atmel_port, pdev); |
2701 | 2728 | ||
2729 | atomic_set(&atmel_port->tasklet_shutdown, 0); | ||
2702 | spin_lock_init(&atmel_port->lock_suspended); | 2730 | spin_lock_init(&atmel_port->lock_suspended); |
2703 | 2731 | ||
2704 | ret = atmel_init_port(atmel_port, pdev); | 2732 | ret = atmel_init_port(atmel_port, pdev); |
@@ -2795,7 +2823,8 @@ static int atmel_serial_remove(struct platform_device *pdev) | |||
2795 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 2823 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
2796 | int ret = 0; | 2824 | int ret = 0; |
2797 | 2825 | ||
2798 | tasklet_kill(&atmel_port->tasklet); | 2826 | tasklet_kill(&atmel_port->tasklet_rx); |
2827 | tasklet_kill(&atmel_port->tasklet_tx); | ||
2799 | 2828 | ||
2800 | device_init_wakeup(&pdev->dev, 0); | 2829 | device_init_wakeup(&pdev->dev, 0); |
2801 | 2830 | ||
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index c28e5c24da16..5108fab953aa 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c | |||
@@ -813,8 +813,12 @@ static int bcm_uart_probe(struct platform_device *pdev) | |||
813 | struct clk *clk; | 813 | struct clk *clk; |
814 | int ret; | 814 | int ret; |
815 | 815 | ||
816 | if (pdev->dev.of_node) | 816 | if (pdev->dev.of_node) { |
817 | pdev->id = of_alias_get_id(pdev->dev.of_node, "uart"); | 817 | pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); |
818 | |||
819 | if (pdev->id < 0) | ||
820 | pdev->id = of_alias_get_id(pdev->dev.of_node, "uart"); | ||
821 | } | ||
818 | 822 | ||
819 | if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) | 823 | if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS) |
820 | return -EINVAL; | 824 | return -EINVAL; |
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 3d790033744e..7f95f782a485 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c | |||
@@ -1830,7 +1830,13 @@ static int lpuart_probe(struct platform_device *pdev) | |||
1830 | sport->port.dev = &pdev->dev; | 1830 | sport->port.dev = &pdev->dev; |
1831 | sport->port.type = PORT_LPUART; | 1831 | sport->port.type = PORT_LPUART; |
1832 | sport->port.iotype = UPIO_MEM; | 1832 | sport->port.iotype = UPIO_MEM; |
1833 | sport->port.irq = platform_get_irq(pdev, 0); | 1833 | ret = platform_get_irq(pdev, 0); |
1834 | if (ret < 0) { | ||
1835 | dev_err(&pdev->dev, "cannot obtain irq\n"); | ||
1836 | return ret; | ||
1837 | } | ||
1838 | sport->port.irq = ret; | ||
1839 | |||
1834 | if (sport->lpuart32) | 1840 | if (sport->lpuart32) |
1835 | sport->port.ops = &lpuart32_pops; | 1841 | sport->port.ops = &lpuart32_pops; |
1836 | else | 1842 | else |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 68765f7c2645..218b7118e85d 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #define SUPPORT_SYSRQ | 30 | #define SUPPORT_SYSRQ |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
36 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
@@ -51,9 +50,6 @@ | |||
51 | 50 | ||
52 | #define PASS_LIMIT 256 | 51 | #define PASS_LIMIT 256 |
53 | 52 | ||
54 | /* Standard COM flags */ | ||
55 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) | ||
56 | |||
57 | static const struct { | 53 | static const struct { |
58 | unsigned int port; | 54 | unsigned int port; |
59 | unsigned int irq; | 55 | unsigned int irq; |
@@ -892,7 +888,7 @@ static void __init m32r_sio_init_ports(void) | |||
892 | up->port.iobase = old_serial_port[i].port; | 888 | up->port.iobase = old_serial_port[i].port; |
893 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 889 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |
894 | up->port.uartclk = BAUD_RATE * 16; | 890 | up->port.uartclk = BAUD_RATE * 16; |
895 | up->port.flags = STD_COM_FLAGS; | 891 | up->port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
896 | up->port.membase = 0; | 892 | up->port.membase = 0; |
897 | up->port.iotype = 0; | 893 | up->port.iotype = 0; |
898 | up->port.regshift = 0; | 894 | up->port.regshift = 0; |
@@ -1060,19 +1056,4 @@ static int __init m32r_sio_init(void) | |||
1060 | 1056 | ||
1061 | return ret; | 1057 | return ret; |
1062 | } | 1058 | } |
1063 | 1059 | device_initcall(m32r_sio_init); | |
1064 | static void __exit m32r_sio_exit(void) | ||
1065 | { | ||
1066 | int i; | ||
1067 | |||
1068 | for (i = 0; i < UART_NR; i++) | ||
1069 | uart_remove_one_port(&m32r_sio_reg, &m32r_sio_ports[i].port); | ||
1070 | |||
1071 | uart_unregister_driver(&m32r_sio_reg); | ||
1072 | } | ||
1073 | |||
1074 | module_init(m32r_sio_init); | ||
1075 | module_exit(m32r_sio_exit); | ||
1076 | |||
1077 | MODULE_LICENSE("GPL"); | ||
1078 | MODULE_DESCRIPTION("Generic M32R SIO serial driver"); | ||
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 3f6e0ab725fe..9360801df3c4 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver | 2 | * Maxim (Dallas) MAX3107/8/9, MAX14830 serial driver |
3 | * | 3 | * |
4 | * Copyright (C) 2012-2014 Alexander Shiyan <shc_work@mail.ru> | 4 | * Copyright (C) 2012-2016 Alexander Shiyan <shc_work@mail.ru> |
5 | * | 5 | * |
6 | * Based on max3100.c, by Christian Pellegrin <chripell@evolware.org> | 6 | * Based on max3100.c, by Christian Pellegrin <chripell@evolware.org> |
7 | * Based on max3110.c, by Feng Tang <feng.tang@intel.com> | 7 | * Based on max3110.c, by Feng Tang <feng.tang@intel.com> |
@@ -32,6 +32,7 @@ | |||
32 | #define MAX310X_NAME "max310x" | 32 | #define MAX310X_NAME "max310x" |
33 | #define MAX310X_MAJOR 204 | 33 | #define MAX310X_MAJOR 204 |
34 | #define MAX310X_MINOR 209 | 34 | #define MAX310X_MINOR 209 |
35 | #define MAX310X_UART_NRMAX 16 | ||
35 | 36 | ||
36 | /* MAX310X register definitions */ | 37 | /* MAX310X register definitions */ |
37 | #define MAX310X_RHR_REG (0x00) /* RX FIFO */ | 38 | #define MAX310X_RHR_REG (0x00) /* RX FIFO */ |
@@ -155,10 +156,6 @@ | |||
155 | #define MAX310X_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ | 156 | #define MAX310X_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ |
156 | #define MAX310X_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ | 157 | #define MAX310X_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ |
157 | #define MAX310X_LCR_RTS_BIT (1 << 7) /* RTS pin control */ | 158 | #define MAX310X_LCR_RTS_BIT (1 << 7) /* RTS pin control */ |
158 | #define MAX310X_LCR_WORD_LEN_5 (0x00) | ||
159 | #define MAX310X_LCR_WORD_LEN_6 (0x01) | ||
160 | #define MAX310X_LCR_WORD_LEN_7 (0x02) | ||
161 | #define MAX310X_LCR_WORD_LEN_8 (0x03) | ||
162 | 159 | ||
163 | /* IRDA register bits */ | 160 | /* IRDA register bits */ |
164 | #define MAX310X_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ | 161 | #define MAX310X_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ |
@@ -262,10 +259,10 @@ struct max310x_one { | |||
262 | struct uart_port port; | 259 | struct uart_port port; |
263 | struct work_struct tx_work; | 260 | struct work_struct tx_work; |
264 | struct work_struct md_work; | 261 | struct work_struct md_work; |
262 | struct work_struct rs_work; | ||
265 | }; | 263 | }; |
266 | 264 | ||
267 | struct max310x_port { | 265 | struct max310x_port { |
268 | struct uart_driver uart; | ||
269 | struct max310x_devtype *devtype; | 266 | struct max310x_devtype *devtype; |
270 | struct regmap *regmap; | 267 | struct regmap *regmap; |
271 | struct mutex mutex; | 268 | struct mutex mutex; |
@@ -276,6 +273,17 @@ struct max310x_port { | |||
276 | struct max310x_one p[0]; | 273 | struct max310x_one p[0]; |
277 | }; | 274 | }; |
278 | 275 | ||
276 | static struct uart_driver max310x_uart = { | ||
277 | .owner = THIS_MODULE, | ||
278 | .driver_name = MAX310X_NAME, | ||
279 | .dev_name = "ttyMAX", | ||
280 | .major = MAX310X_MAJOR, | ||
281 | .minor = MAX310X_MINOR, | ||
282 | .nr = MAX310X_UART_NRMAX, | ||
283 | }; | ||
284 | |||
285 | static DECLARE_BITMAP(max310x_lines, MAX310X_UART_NRMAX); | ||
286 | |||
279 | static u8 max310x_port_read(struct uart_port *port, u8 reg) | 287 | static u8 max310x_port_read(struct uart_port *port, u8 reg) |
280 | { | 288 | { |
281 | struct max310x_port *s = dev_get_drvdata(port->dev); | 289 | struct max310x_port *s = dev_get_drvdata(port->dev); |
@@ -594,9 +602,7 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen) | |||
594 | unsigned int sts, ch, flag; | 602 | unsigned int sts, ch, flag; |
595 | 603 | ||
596 | if (unlikely(rxlen >= port->fifosize)) { | 604 | if (unlikely(rxlen >= port->fifosize)) { |
597 | dev_warn_ratelimited(port->dev, | 605 | dev_warn_ratelimited(port->dev, "Possible RX FIFO overrun\n"); |
598 | "Port %i: Possible RX FIFO overrun\n", | ||
599 | port->line); | ||
600 | port->icount.buf_overrun++; | 606 | port->icount.buf_overrun++; |
601 | /* Ensure sanity of RX level */ | 607 | /* Ensure sanity of RX level */ |
602 | rxlen = port->fifosize; | 608 | rxlen = port->fifosize; |
@@ -715,13 +721,13 @@ static irqreturn_t max310x_ist(int irq, void *dev_id) | |||
715 | { | 721 | { |
716 | struct max310x_port *s = (struct max310x_port *)dev_id; | 722 | struct max310x_port *s = (struct max310x_port *)dev_id; |
717 | 723 | ||
718 | if (s->uart.nr > 1) { | 724 | if (s->devtype->nr > 1) { |
719 | do { | 725 | do { |
720 | unsigned int val = ~0; | 726 | unsigned int val = ~0; |
721 | 727 | ||
722 | WARN_ON_ONCE(regmap_read(s->regmap, | 728 | WARN_ON_ONCE(regmap_read(s->regmap, |
723 | MAX310X_GLOBALIRQ_REG, &val)); | 729 | MAX310X_GLOBALIRQ_REG, &val)); |
724 | val = ((1 << s->uart.nr) - 1) & ~val; | 730 | val = ((1 << s->devtype->nr) - 1) & ~val; |
725 | if (!val) | 731 | if (!val) |
726 | break; | 732 | break; |
727 | max310x_port_irq(s, fls(val) - 1); | 733 | max310x_port_irq(s, fls(val) - 1); |
@@ -796,7 +802,7 @@ static void max310x_set_termios(struct uart_port *port, | |||
796 | struct ktermios *termios, | 802 | struct ktermios *termios, |
797 | struct ktermios *old) | 803 | struct ktermios *old) |
798 | { | 804 | { |
799 | unsigned int lcr, flow = 0; | 805 | unsigned int lcr = 0, flow = 0; |
800 | int baud; | 806 | int baud; |
801 | 807 | ||
802 | /* Mask termios capabilities we don't support */ | 808 | /* Mask termios capabilities we don't support */ |
@@ -805,17 +811,16 @@ static void max310x_set_termios(struct uart_port *port, | |||
805 | /* Word size */ | 811 | /* Word size */ |
806 | switch (termios->c_cflag & CSIZE) { | 812 | switch (termios->c_cflag & CSIZE) { |
807 | case CS5: | 813 | case CS5: |
808 | lcr = MAX310X_LCR_WORD_LEN_5; | ||
809 | break; | 814 | break; |
810 | case CS6: | 815 | case CS6: |
811 | lcr = MAX310X_LCR_WORD_LEN_6; | 816 | lcr = MAX310X_LCR_LENGTH0_BIT; |
812 | break; | 817 | break; |
813 | case CS7: | 818 | case CS7: |
814 | lcr = MAX310X_LCR_WORD_LEN_7; | 819 | lcr = MAX310X_LCR_LENGTH1_BIT; |
815 | break; | 820 | break; |
816 | case CS8: | 821 | case CS8: |
817 | default: | 822 | default: |
818 | lcr = MAX310X_LCR_WORD_LEN_8; | 823 | lcr = MAX310X_LCR_LENGTH1_BIT | MAX310X_LCR_LENGTH0_BIT; |
819 | break; | 824 | break; |
820 | } | 825 | } |
821 | 826 | ||
@@ -877,36 +882,45 @@ static void max310x_set_termios(struct uart_port *port, | |||
877 | uart_update_timeout(port, termios->c_cflag, baud); | 882 | uart_update_timeout(port, termios->c_cflag, baud); |
878 | } | 883 | } |
879 | 884 | ||
880 | static int max310x_rs485_config(struct uart_port *port, | 885 | static void max310x_rs_proc(struct work_struct *ws) |
881 | struct serial_rs485 *rs485) | ||
882 | { | 886 | { |
887 | struct max310x_one *one = container_of(ws, struct max310x_one, rs_work); | ||
883 | unsigned int val; | 888 | unsigned int val; |
884 | 889 | ||
885 | if (rs485->delay_rts_before_send > 0x0f || | 890 | val = (one->port.rs485.delay_rts_before_send << 4) | |
886 | rs485->delay_rts_after_send > 0x0f) | 891 | one->port.rs485.delay_rts_after_send; |
887 | return -ERANGE; | 892 | max310x_port_write(&one->port, MAX310X_HDPIXDELAY_REG, val); |
888 | 893 | ||
889 | val = (rs485->delay_rts_before_send << 4) | | 894 | if (one->port.rs485.flags & SER_RS485_ENABLED) { |
890 | rs485->delay_rts_after_send; | 895 | max310x_port_update(&one->port, MAX310X_MODE1_REG, |
891 | max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val); | ||
892 | if (rs485->flags & SER_RS485_ENABLED) { | ||
893 | max310x_port_update(port, MAX310X_MODE1_REG, | ||
894 | MAX310X_MODE1_TRNSCVCTRL_BIT, | 896 | MAX310X_MODE1_TRNSCVCTRL_BIT, |
895 | MAX310X_MODE1_TRNSCVCTRL_BIT); | 897 | MAX310X_MODE1_TRNSCVCTRL_BIT); |
896 | max310x_port_update(port, MAX310X_MODE2_REG, | 898 | max310x_port_update(&one->port, MAX310X_MODE2_REG, |
897 | MAX310X_MODE2_ECHOSUPR_BIT, | 899 | MAX310X_MODE2_ECHOSUPR_BIT, |
898 | MAX310X_MODE2_ECHOSUPR_BIT); | 900 | MAX310X_MODE2_ECHOSUPR_BIT); |
899 | } else { | 901 | } else { |
900 | max310x_port_update(port, MAX310X_MODE1_REG, | 902 | max310x_port_update(&one->port, MAX310X_MODE1_REG, |
901 | MAX310X_MODE1_TRNSCVCTRL_BIT, 0); | 903 | MAX310X_MODE1_TRNSCVCTRL_BIT, 0); |
902 | max310x_port_update(port, MAX310X_MODE2_REG, | 904 | max310x_port_update(&one->port, MAX310X_MODE2_REG, |
903 | MAX310X_MODE2_ECHOSUPR_BIT, 0); | 905 | MAX310X_MODE2_ECHOSUPR_BIT, 0); |
904 | } | 906 | } |
907 | } | ||
908 | |||
909 | static int max310x_rs485_config(struct uart_port *port, | ||
910 | struct serial_rs485 *rs485) | ||
911 | { | ||
912 | struct max310x_one *one = container_of(port, struct max310x_one, port); | ||
913 | |||
914 | if ((rs485->delay_rts_before_send > 0x0f) || | ||
915 | (rs485->delay_rts_after_send > 0x0f)) | ||
916 | return -ERANGE; | ||
905 | 917 | ||
906 | rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_ENABLED; | 918 | rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_ENABLED; |
907 | memset(rs485->padding, 0, sizeof(rs485->padding)); | 919 | memset(rs485->padding, 0, sizeof(rs485->padding)); |
908 | port->rs485 = *rs485; | 920 | port->rs485 = *rs485; |
909 | 921 | ||
922 | schedule_work(&one->rs_work); | ||
923 | |||
910 | return 0; | 924 | return 0; |
911 | } | 925 | } |
912 | 926 | ||
@@ -1009,8 +1023,8 @@ static int __maybe_unused max310x_suspend(struct device *dev) | |||
1009 | struct max310x_port *s = dev_get_drvdata(dev); | 1023 | struct max310x_port *s = dev_get_drvdata(dev); |
1010 | int i; | 1024 | int i; |
1011 | 1025 | ||
1012 | for (i = 0; i < s->uart.nr; i++) { | 1026 | for (i = 0; i < s->devtype->nr; i++) { |
1013 | uart_suspend_port(&s->uart, &s->p[i].port); | 1027 | uart_suspend_port(&max310x_uart, &s->p[i].port); |
1014 | s->devtype->power(&s->p[i].port, 0); | 1028 | s->devtype->power(&s->p[i].port, 0); |
1015 | } | 1029 | } |
1016 | 1030 | ||
@@ -1022,9 +1036,9 @@ static int __maybe_unused max310x_resume(struct device *dev) | |||
1022 | struct max310x_port *s = dev_get_drvdata(dev); | 1036 | struct max310x_port *s = dev_get_drvdata(dev); |
1023 | int i; | 1037 | int i; |
1024 | 1038 | ||
1025 | for (i = 0; i < s->uart.nr; i++) { | 1039 | for (i = 0; i < s->devtype->nr; i++) { |
1026 | s->devtype->power(&s->p[i].port, 1); | 1040 | s->devtype->power(&s->p[i].port, 1); |
1027 | uart_resume_port(&s->uart, &s->p[i].port); | 1041 | uart_resume_port(&max310x_uart, &s->p[i].port); |
1028 | } | 1042 | } |
1029 | 1043 | ||
1030 | return 0; | 1044 | return 0; |
@@ -1159,18 +1173,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1159 | uartclk = max310x_set_ref_clk(s, freq, xtal); | 1173 | uartclk = max310x_set_ref_clk(s, freq, xtal); |
1160 | dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); | 1174 | dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk); |
1161 | 1175 | ||
1162 | /* Register UART driver */ | ||
1163 | s->uart.owner = THIS_MODULE; | ||
1164 | s->uart.dev_name = "ttyMAX"; | ||
1165 | s->uart.major = MAX310X_MAJOR; | ||
1166 | s->uart.minor = MAX310X_MINOR; | ||
1167 | s->uart.nr = devtype->nr; | ||
1168 | ret = uart_register_driver(&s->uart); | ||
1169 | if (ret) { | ||
1170 | dev_err(dev, "Registering UART driver failed\n"); | ||
1171 | goto out_clk; | ||
1172 | } | ||
1173 | |||
1174 | #ifdef CONFIG_GPIOLIB | 1176 | #ifdef CONFIG_GPIOLIB |
1175 | /* Setup GPIO cotroller */ | 1177 | /* Setup GPIO cotroller */ |
1176 | s->gpio.owner = THIS_MODULE; | 1178 | s->gpio.owner = THIS_MODULE; |
@@ -1183,16 +1185,24 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1183 | s->gpio.base = -1; | 1185 | s->gpio.base = -1; |
1184 | s->gpio.ngpio = devtype->nr * 4; | 1186 | s->gpio.ngpio = devtype->nr * 4; |
1185 | s->gpio.can_sleep = 1; | 1187 | s->gpio.can_sleep = 1; |
1186 | ret = gpiochip_add_data(&s->gpio, s); | 1188 | ret = devm_gpiochip_add_data(dev, &s->gpio, s); |
1187 | if (ret) | 1189 | if (ret) |
1188 | goto out_uart; | 1190 | goto out_clk; |
1189 | #endif | 1191 | #endif |
1190 | 1192 | ||
1191 | mutex_init(&s->mutex); | 1193 | mutex_init(&s->mutex); |
1192 | 1194 | ||
1193 | for (i = 0; i < devtype->nr; i++) { | 1195 | for (i = 0; i < devtype->nr; i++) { |
1196 | unsigned int line; | ||
1197 | |||
1198 | line = find_first_zero_bit(max310x_lines, MAX310X_UART_NRMAX); | ||
1199 | if (line == MAX310X_UART_NRMAX) { | ||
1200 | ret = -ERANGE; | ||
1201 | goto out_uart; | ||
1202 | } | ||
1203 | |||
1194 | /* Initialize port data */ | 1204 | /* Initialize port data */ |
1195 | s->p[i].port.line = i; | 1205 | s->p[i].port.line = line; |
1196 | s->p[i].port.dev = dev; | 1206 | s->p[i].port.dev = dev; |
1197 | s->p[i].port.irq = irq; | 1207 | s->p[i].port.irq = irq; |
1198 | s->p[i].port.type = PORT_MAX310X; | 1208 | s->p[i].port.type = PORT_MAX310X; |
@@ -1214,10 +1224,19 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1214 | MAX310X_MODE1_IRQSEL_BIT); | 1224 | MAX310X_MODE1_IRQSEL_BIT); |
1215 | /* Initialize queue for start TX */ | 1225 | /* Initialize queue for start TX */ |
1216 | INIT_WORK(&s->p[i].tx_work, max310x_wq_proc); | 1226 | INIT_WORK(&s->p[i].tx_work, max310x_wq_proc); |
1217 | /* Initialize queue for changing mode */ | 1227 | /* Initialize queue for changing LOOPBACK mode */ |
1218 | INIT_WORK(&s->p[i].md_work, max310x_md_proc); | 1228 | INIT_WORK(&s->p[i].md_work, max310x_md_proc); |
1229 | /* Initialize queue for changing RS485 mode */ | ||
1230 | INIT_WORK(&s->p[i].rs_work, max310x_rs_proc); | ||
1231 | |||
1219 | /* Register port */ | 1232 | /* Register port */ |
1220 | uart_add_one_port(&s->uart, &s->p[i].port); | 1233 | ret = uart_add_one_port(&max310x_uart, &s->p[i].port); |
1234 | if (ret) { | ||
1235 | s->p[i].port.dev = NULL; | ||
1236 | goto out_uart; | ||
1237 | } | ||
1238 | set_bit(line, max310x_lines); | ||
1239 | |||
1221 | /* Go to suspend mode */ | 1240 | /* Go to suspend mode */ |
1222 | devtype->power(&s->p[i].port, 0); | 1241 | devtype->power(&s->p[i].port, 0); |
1223 | } | 1242 | } |
@@ -1230,14 +1249,15 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype, | |||
1230 | 1249 | ||
1231 | dev_err(dev, "Unable to reguest IRQ %i\n", irq); | 1250 | dev_err(dev, "Unable to reguest IRQ %i\n", irq); |
1232 | 1251 | ||
1233 | mutex_destroy(&s->mutex); | ||
1234 | |||
1235 | #ifdef CONFIG_GPIOLIB | ||
1236 | gpiochip_remove(&s->gpio); | ||
1237 | |||
1238 | out_uart: | 1252 | out_uart: |
1239 | #endif | 1253 | for (i = 0; i < devtype->nr; i++) { |
1240 | uart_unregister_driver(&s->uart); | 1254 | if (s->p[i].port.dev) { |
1255 | uart_remove_one_port(&max310x_uart, &s->p[i].port); | ||
1256 | clear_bit(s->p[i].port.line, max310x_lines); | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | mutex_destroy(&s->mutex); | ||
1241 | 1261 | ||
1242 | out_clk: | 1262 | out_clk: |
1243 | clk_disable_unprepare(s->clk); | 1263 | clk_disable_unprepare(s->clk); |
@@ -1250,19 +1270,16 @@ static int max310x_remove(struct device *dev) | |||
1250 | struct max310x_port *s = dev_get_drvdata(dev); | 1270 | struct max310x_port *s = dev_get_drvdata(dev); |
1251 | int i; | 1271 | int i; |
1252 | 1272 | ||
1253 | #ifdef CONFIG_GPIOLIB | 1273 | for (i = 0; i < s->devtype->nr; i++) { |
1254 | gpiochip_remove(&s->gpio); | ||
1255 | #endif | ||
1256 | |||
1257 | for (i = 0; i < s->uart.nr; i++) { | ||
1258 | cancel_work_sync(&s->p[i].tx_work); | 1274 | cancel_work_sync(&s->p[i].tx_work); |
1259 | cancel_work_sync(&s->p[i].md_work); | 1275 | cancel_work_sync(&s->p[i].md_work); |
1260 | uart_remove_one_port(&s->uart, &s->p[i].port); | 1276 | cancel_work_sync(&s->p[i].rs_work); |
1277 | uart_remove_one_port(&max310x_uart, &s->p[i].port); | ||
1278 | clear_bit(s->p[i].port.line, max310x_lines); | ||
1261 | s->devtype->power(&s->p[i].port, 0); | 1279 | s->devtype->power(&s->p[i].port, 0); |
1262 | } | 1280 | } |
1263 | 1281 | ||
1264 | mutex_destroy(&s->mutex); | 1282 | mutex_destroy(&s->mutex); |
1265 | uart_unregister_driver(&s->uart); | ||
1266 | clk_disable_unprepare(s->clk); | 1283 | clk_disable_unprepare(s->clk); |
1267 | 1284 | ||
1268 | return 0; | 1285 | return 0; |
@@ -1335,7 +1352,7 @@ static const struct spi_device_id max310x_id_table[] = { | |||
1335 | }; | 1352 | }; |
1336 | MODULE_DEVICE_TABLE(spi, max310x_id_table); | 1353 | MODULE_DEVICE_TABLE(spi, max310x_id_table); |
1337 | 1354 | ||
1338 | static struct spi_driver max310x_uart_driver = { | 1355 | static struct spi_driver max310x_spi_driver = { |
1339 | .driver = { | 1356 | .driver = { |
1340 | .name = MAX310X_NAME, | 1357 | .name = MAX310X_NAME, |
1341 | .of_match_table = of_match_ptr(max310x_dt_ids), | 1358 | .of_match_table = of_match_ptr(max310x_dt_ids), |
@@ -1345,9 +1362,36 @@ static struct spi_driver max310x_uart_driver = { | |||
1345 | .remove = max310x_spi_remove, | 1362 | .remove = max310x_spi_remove, |
1346 | .id_table = max310x_id_table, | 1363 | .id_table = max310x_id_table, |
1347 | }; | 1364 | }; |
1348 | module_spi_driver(max310x_uart_driver); | ||
1349 | #endif | 1365 | #endif |
1350 | 1366 | ||
1367 | static int __init max310x_uart_init(void) | ||
1368 | { | ||
1369 | int ret; | ||
1370 | |||
1371 | bitmap_zero(max310x_lines, MAX310X_UART_NRMAX); | ||
1372 | |||
1373 | ret = uart_register_driver(&max310x_uart); | ||
1374 | if (ret) | ||
1375 | return ret; | ||
1376 | |||
1377 | #ifdef CONFIG_SPI_MASTER | ||
1378 | spi_register_driver(&max310x_spi_driver); | ||
1379 | #endif | ||
1380 | |||
1381 | return 0; | ||
1382 | } | ||
1383 | module_init(max310x_uart_init); | ||
1384 | |||
1385 | static void __exit max310x_uart_exit(void) | ||
1386 | { | ||
1387 | #ifdef CONFIG_SPI_MASTER | ||
1388 | spi_unregister_driver(&max310x_spi_driver); | ||
1389 | #endif | ||
1390 | |||
1391 | uart_unregister_driver(&max310x_uart); | ||
1392 | } | ||
1393 | module_exit(max310x_uart_exit); | ||
1394 | |||
1351 | MODULE_LICENSE("GPL"); | 1395 | MODULE_LICENSE("GPL"); |
1352 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | 1396 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); |
1353 | MODULE_DESCRIPTION("MAX310X serial driver"); | 1397 | MODULE_DESCRIPTION("MAX310X serial driver"); |
diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index da9e27d3c263..492ec4b375a0 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c | |||
@@ -1,4 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * MPS2 UART driver | ||
3 | * | ||
2 | * Copyright (C) 2015 ARM Limited | 4 | * Copyright (C) 2015 ARM Limited |
3 | * | 5 | * |
4 | * Author: Vladimir Murzin <vladimir.murzin@arm.com> | 6 | * Author: Vladimir Murzin <vladimir.murzin@arm.com> |
@@ -17,7 +19,6 @@ | |||
17 | #include <linux/console.h> | 19 | #include <linux/console.h> |
18 | #include <linux/io.h> | 20 | #include <linux/io.h> |
19 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | ||
21 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
@@ -569,30 +570,20 @@ static int mps2_serial_probe(struct platform_device *pdev) | |||
569 | return 0; | 570 | return 0; |
570 | } | 571 | } |
571 | 572 | ||
572 | static int mps2_serial_remove(struct platform_device *pdev) | ||
573 | { | ||
574 | struct mps2_uart_port *mps_port = platform_get_drvdata(pdev); | ||
575 | |||
576 | uart_remove_one_port(&mps2_uart_driver, &mps_port->port); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | #ifdef CONFIG_OF | 573 | #ifdef CONFIG_OF |
582 | static const struct of_device_id mps2_match[] = { | 574 | static const struct of_device_id mps2_match[] = { |
583 | { .compatible = "arm,mps2-uart", }, | 575 | { .compatible = "arm,mps2-uart", }, |
584 | {}, | 576 | {}, |
585 | }; | 577 | }; |
586 | MODULE_DEVICE_TABLE(of, mps2_match); | ||
587 | #endif | 578 | #endif |
588 | 579 | ||
589 | static struct platform_driver mps2_serial_driver = { | 580 | static struct platform_driver mps2_serial_driver = { |
590 | .probe = mps2_serial_probe, | 581 | .probe = mps2_serial_probe, |
591 | .remove = mps2_serial_remove, | ||
592 | 582 | ||
593 | .driver = { | 583 | .driver = { |
594 | .name = DRIVER_NAME, | 584 | .name = DRIVER_NAME, |
595 | .of_match_table = of_match_ptr(mps2_match), | 585 | .of_match_table = of_match_ptr(mps2_match), |
586 | .suppress_bind_attrs = true, | ||
596 | }, | 587 | }, |
597 | }; | 588 | }; |
598 | 589 | ||
@@ -610,16 +601,4 @@ static int __init mps2_uart_init(void) | |||
610 | 601 | ||
611 | return ret; | 602 | return ret; |
612 | } | 603 | } |
613 | module_init(mps2_uart_init); | 604 | arch_initcall(mps2_uart_init); |
614 | |||
615 | static void __exit mps2_uart_exit(void) | ||
616 | { | ||
617 | platform_driver_unregister(&mps2_serial_driver); | ||
618 | uart_unregister_driver(&mps2_uart_driver); | ||
619 | } | ||
620 | module_exit(mps2_uart_exit); | ||
621 | |||
622 | MODULE_AUTHOR("Vladimir Murzin <vladimir.murzin@arm.com>"); | ||
623 | MODULE_DESCRIPTION("MPS2 UART driver"); | ||
624 | MODULE_LICENSE("GPL v2"); | ||
625 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index b7d80bd57db9..7312e7e01b7e 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -19,33 +19,147 @@ | |||
19 | # define SUPPORT_SYSRQ | 19 | # define SUPPORT_SYSRQ |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #include <linux/kernel.h> | ||
22 | #include <linux/atomic.h> | 23 | #include <linux/atomic.h> |
23 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
24 | #include <linux/dmaengine.h> | 25 | #include <linux/dmaengine.h> |
25 | #include <linux/hrtimer.h> | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/irq.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/console.h> | 31 | #include <linux/console.h> |
32 | #include <linux/tty.h> | 32 | #include <linux/tty.h> |
33 | #include <linux/tty_flip.h> | 33 | #include <linux/tty_flip.h> |
34 | #include <linux/serial_core.h> | 34 | #include <linux/serial_core.h> |
35 | #include <linux/serial.h> | ||
36 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
37 | #include <linux/clk.h> | 36 | #include <linux/clk.h> |
38 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
39 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
40 | #include <linux/of.h> | 39 | #include <linux/of.h> |
41 | #include <linux/of_device.h> | 40 | #include <linux/of_device.h> |
42 | 41 | #include <linux/wait.h> | |
43 | #include "msm_serial.h" | 42 | |
44 | 43 | #define UART_MR1 0x0000 | |
45 | #define UARTDM_BURST_SIZE 16 /* in bytes */ | 44 | |
46 | #define UARTDM_TX_AIGN(x) ((x) & ~0x3) /* valid for > 1p3 */ | 45 | #define UART_MR1_AUTO_RFR_LEVEL0 0x3F |
47 | #define UARTDM_TX_MAX 256 /* in bytes, valid for <= 1p3 */ | 46 | #define UART_MR1_AUTO_RFR_LEVEL1 0x3FF00 |
48 | #define UARTDM_RX_SIZE (UART_XMIT_SIZE / 4) | 47 | #define UART_DM_MR1_AUTO_RFR_LEVEL1 0xFFFFFF00 |
48 | #define UART_MR1_RX_RDY_CTL BIT(7) | ||
49 | #define UART_MR1_CTS_CTL BIT(6) | ||
50 | |||
51 | #define UART_MR2 0x0004 | ||
52 | #define UART_MR2_ERROR_MODE BIT(6) | ||
53 | #define UART_MR2_BITS_PER_CHAR 0x30 | ||
54 | #define UART_MR2_BITS_PER_CHAR_5 (0x0 << 4) | ||
55 | #define UART_MR2_BITS_PER_CHAR_6 (0x1 << 4) | ||
56 | #define UART_MR2_BITS_PER_CHAR_7 (0x2 << 4) | ||
57 | #define UART_MR2_BITS_PER_CHAR_8 (0x3 << 4) | ||
58 | #define UART_MR2_STOP_BIT_LEN_ONE (0x1 << 2) | ||
59 | #define UART_MR2_STOP_BIT_LEN_TWO (0x3 << 2) | ||
60 | #define UART_MR2_PARITY_MODE_NONE 0x0 | ||
61 | #define UART_MR2_PARITY_MODE_ODD 0x1 | ||
62 | #define UART_MR2_PARITY_MODE_EVEN 0x2 | ||
63 | #define UART_MR2_PARITY_MODE_SPACE 0x3 | ||
64 | #define UART_MR2_PARITY_MODE 0x3 | ||
65 | |||
66 | #define UART_CSR 0x0008 | ||
67 | |||
68 | #define UART_TF 0x000C | ||
69 | #define UARTDM_TF 0x0070 | ||
70 | |||
71 | #define UART_CR 0x0010 | ||
72 | #define UART_CR_CMD_NULL (0 << 4) | ||
73 | #define UART_CR_CMD_RESET_RX (1 << 4) | ||
74 | #define UART_CR_CMD_RESET_TX (2 << 4) | ||
75 | #define UART_CR_CMD_RESET_ERR (3 << 4) | ||
76 | #define UART_CR_CMD_RESET_BREAK_INT (4 << 4) | ||
77 | #define UART_CR_CMD_START_BREAK (5 << 4) | ||
78 | #define UART_CR_CMD_STOP_BREAK (6 << 4) | ||
79 | #define UART_CR_CMD_RESET_CTS (7 << 4) | ||
80 | #define UART_CR_CMD_RESET_STALE_INT (8 << 4) | ||
81 | #define UART_CR_CMD_PACKET_MODE (9 << 4) | ||
82 | #define UART_CR_CMD_MODE_RESET (12 << 4) | ||
83 | #define UART_CR_CMD_SET_RFR (13 << 4) | ||
84 | #define UART_CR_CMD_RESET_RFR (14 << 4) | ||
85 | #define UART_CR_CMD_PROTECTION_EN (16 << 4) | ||
86 | #define UART_CR_CMD_STALE_EVENT_DISABLE (6 << 8) | ||
87 | #define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4) | ||
88 | #define UART_CR_CMD_FORCE_STALE (4 << 8) | ||
89 | #define UART_CR_CMD_RESET_TX_READY (3 << 8) | ||
90 | #define UART_CR_TX_DISABLE BIT(3) | ||
91 | #define UART_CR_TX_ENABLE BIT(2) | ||
92 | #define UART_CR_RX_DISABLE BIT(1) | ||
93 | #define UART_CR_RX_ENABLE BIT(0) | ||
94 | #define UART_CR_CMD_RESET_RXBREAK_START ((1 << 11) | (2 << 4)) | ||
95 | |||
96 | #define UART_IMR 0x0014 | ||
97 | #define UART_IMR_TXLEV BIT(0) | ||
98 | #define UART_IMR_RXSTALE BIT(3) | ||
99 | #define UART_IMR_RXLEV BIT(4) | ||
100 | #define UART_IMR_DELTA_CTS BIT(5) | ||
101 | #define UART_IMR_CURRENT_CTS BIT(6) | ||
102 | #define UART_IMR_RXBREAK_START BIT(10) | ||
103 | |||
104 | #define UART_IPR_RXSTALE_LAST 0x20 | ||
105 | #define UART_IPR_STALE_LSB 0x1F | ||
106 | #define UART_IPR_STALE_TIMEOUT_MSB 0x3FF80 | ||
107 | #define UART_DM_IPR_STALE_TIMEOUT_MSB 0xFFFFFF80 | ||
108 | |||
109 | #define UART_IPR 0x0018 | ||
110 | #define UART_TFWR 0x001C | ||
111 | #define UART_RFWR 0x0020 | ||
112 | #define UART_HCR 0x0024 | ||
113 | |||
114 | #define UART_MREG 0x0028 | ||
115 | #define UART_NREG 0x002C | ||
116 | #define UART_DREG 0x0030 | ||
117 | #define UART_MNDREG 0x0034 | ||
118 | #define UART_IRDA 0x0038 | ||
119 | #define UART_MISR_MODE 0x0040 | ||
120 | #define UART_MISR_RESET 0x0044 | ||
121 | #define UART_MISR_EXPORT 0x0048 | ||
122 | #define UART_MISR_VAL 0x004C | ||
123 | #define UART_TEST_CTRL 0x0050 | ||
124 | |||
125 | #define UART_SR 0x0008 | ||
126 | #define UART_SR_HUNT_CHAR BIT(7) | ||
127 | #define UART_SR_RX_BREAK BIT(6) | ||
128 | #define UART_SR_PAR_FRAME_ERR BIT(5) | ||
129 | #define UART_SR_OVERRUN BIT(4) | ||
130 | #define UART_SR_TX_EMPTY BIT(3) | ||
131 | #define UART_SR_TX_READY BIT(2) | ||
132 | #define UART_SR_RX_FULL BIT(1) | ||
133 | #define UART_SR_RX_READY BIT(0) | ||
134 | |||
135 | #define UART_RF 0x000C | ||
136 | #define UARTDM_RF 0x0070 | ||
137 | #define UART_MISR 0x0010 | ||
138 | #define UART_ISR 0x0014 | ||
139 | #define UART_ISR_TX_READY BIT(7) | ||
140 | |||
141 | #define UARTDM_RXFS 0x50 | ||
142 | #define UARTDM_RXFS_BUF_SHIFT 0x7 | ||
143 | #define UARTDM_RXFS_BUF_MASK 0x7 | ||
144 | |||
145 | #define UARTDM_DMEN 0x3C | ||
146 | #define UARTDM_DMEN_RX_SC_ENABLE BIT(5) | ||
147 | #define UARTDM_DMEN_TX_SC_ENABLE BIT(4) | ||
148 | |||
149 | #define UARTDM_DMEN_TX_BAM_ENABLE BIT(2) /* UARTDM_1P4 */ | ||
150 | #define UARTDM_DMEN_TX_DM_ENABLE BIT(0) /* < UARTDM_1P4 */ | ||
151 | |||
152 | #define UARTDM_DMEN_RX_BAM_ENABLE BIT(3) /* UARTDM_1P4 */ | ||
153 | #define UARTDM_DMEN_RX_DM_ENABLE BIT(1) /* < UARTDM_1P4 */ | ||
154 | |||
155 | #define UARTDM_DMRX 0x34 | ||
156 | #define UARTDM_NCF_TX 0x40 | ||
157 | #define UARTDM_RX_TOTAL_SNAP 0x38 | ||
158 | |||
159 | #define UARTDM_BURST_SIZE 16 /* in bytes */ | ||
160 | #define UARTDM_TX_AIGN(x) ((x) & ~0x3) /* valid for > 1p3 */ | ||
161 | #define UARTDM_TX_MAX 256 /* in bytes, valid for <= 1p3 */ | ||
162 | #define UARTDM_RX_SIZE (UART_XMIT_SIZE / 4) | ||
49 | 163 | ||
50 | enum { | 164 | enum { |
51 | UARTDM_1P1 = 1, | 165 | UARTDM_1P1 = 1, |
@@ -78,10 +192,65 @@ struct msm_port { | |||
78 | struct msm_dma rx_dma; | 192 | struct msm_dma rx_dma; |
79 | }; | 193 | }; |
80 | 194 | ||
195 | #define UART_TO_MSM(uart_port) container_of(uart_port, struct msm_port, uart) | ||
196 | |||
197 | static | ||
198 | void msm_write(struct uart_port *port, unsigned int val, unsigned int off) | ||
199 | { | ||
200 | writel_relaxed(val, port->membase + off); | ||
201 | } | ||
202 | |||
203 | static | ||
204 | unsigned int msm_read(struct uart_port *port, unsigned int off) | ||
205 | { | ||
206 | return readl_relaxed(port->membase + off); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Setup the MND registers to use the TCXO clock. | ||
211 | */ | ||
212 | static void msm_serial_set_mnd_regs_tcxo(struct uart_port *port) | ||
213 | { | ||
214 | msm_write(port, 0x06, UART_MREG); | ||
215 | msm_write(port, 0xF1, UART_NREG); | ||
216 | msm_write(port, 0x0F, UART_DREG); | ||
217 | msm_write(port, 0x1A, UART_MNDREG); | ||
218 | port->uartclk = 1843200; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * Setup the MND registers to use the TCXO clock divided by 4. | ||
223 | */ | ||
224 | static void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port) | ||
225 | { | ||
226 | msm_write(port, 0x18, UART_MREG); | ||
227 | msm_write(port, 0xF6, UART_NREG); | ||
228 | msm_write(port, 0x0F, UART_DREG); | ||
229 | msm_write(port, 0x0A, UART_MNDREG); | ||
230 | port->uartclk = 1843200; | ||
231 | } | ||
232 | |||
233 | static void msm_serial_set_mnd_regs(struct uart_port *port) | ||
234 | { | ||
235 | struct msm_port *msm_port = UART_TO_MSM(port); | ||
236 | |||
237 | /* | ||
238 | * These registers don't exist so we change the clk input rate | ||
239 | * on uartdm hardware instead | ||
240 | */ | ||
241 | if (msm_port->is_uartdm) | ||
242 | return; | ||
243 | |||
244 | if (port->uartclk == 19200000) | ||
245 | msm_serial_set_mnd_regs_tcxo(port); | ||
246 | else if (port->uartclk == 4800000) | ||
247 | msm_serial_set_mnd_regs_tcxoby4(port); | ||
248 | } | ||
249 | |||
81 | static void msm_handle_tx(struct uart_port *port); | 250 | static void msm_handle_tx(struct uart_port *port); |
82 | static void msm_start_rx_dma(struct msm_port *msm_port); | 251 | static void msm_start_rx_dma(struct msm_port *msm_port); |
83 | 252 | ||
84 | void msm_stop_dma(struct uart_port *port, struct msm_dma *dma) | 253 | static void msm_stop_dma(struct uart_port *port, struct msm_dma *dma) |
85 | { | 254 | { |
86 | struct device *dev = port->dev; | 255 | struct device *dev = port->dev; |
87 | unsigned int mapped; | 256 | unsigned int mapped; |
@@ -388,10 +557,6 @@ static void msm_complete_rx_dma(void *args) | |||
388 | val &= ~dma->enable_bit; | 557 | val &= ~dma->enable_bit; |
389 | msm_write(port, val, UARTDM_DMEN); | 558 | msm_write(port, val, UARTDM_DMEN); |
390 | 559 | ||
391 | /* Restore interrupts */ | ||
392 | msm_port->imr |= UART_IMR_RXLEV | UART_IMR_RXSTALE; | ||
393 | msm_write(port, msm_port->imr, UART_IMR); | ||
394 | |||
395 | if (msm_read(port, UART_SR) & UART_SR_OVERRUN) { | 560 | if (msm_read(port, UART_SR) & UART_SR_OVERRUN) { |
396 | port->icount.overrun++; | 561 | port->icount.overrun++; |
397 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); | 562 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
@@ -726,7 +891,7 @@ static void msm_handle_tx(struct uart_port *port) | |||
726 | return; | 891 | return; |
727 | } | 892 | } |
728 | 893 | ||
729 | pio_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); | 894 | pio_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); |
730 | dma_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | 895 | dma_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); |
731 | 896 | ||
732 | dma_min = 1; /* Always DMA */ | 897 | dma_min = 1; /* Always DMA */ |
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h deleted file mode 100644 index 178645826f16..000000000000 --- a/drivers/tty/serial/msm_serial.h +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Google, Inc. | ||
3 | * Author: Robert Love <rlove@google.com> | ||
4 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __DRIVERS_SERIAL_MSM_SERIAL_H | ||
17 | #define __DRIVERS_SERIAL_MSM_SERIAL_H | ||
18 | |||
19 | #define UART_MR1 0x0000 | ||
20 | |||
21 | #define UART_MR1_AUTO_RFR_LEVEL0 0x3F | ||
22 | #define UART_MR1_AUTO_RFR_LEVEL1 0x3FF00 | ||
23 | #define UART_DM_MR1_AUTO_RFR_LEVEL1 0xFFFFFF00 | ||
24 | #define UART_MR1_RX_RDY_CTL BIT(7) | ||
25 | #define UART_MR1_CTS_CTL BIT(6) | ||
26 | |||
27 | #define UART_MR2 0x0004 | ||
28 | #define UART_MR2_ERROR_MODE BIT(6) | ||
29 | #define UART_MR2_BITS_PER_CHAR 0x30 | ||
30 | #define UART_MR2_BITS_PER_CHAR_5 (0x0 << 4) | ||
31 | #define UART_MR2_BITS_PER_CHAR_6 (0x1 << 4) | ||
32 | #define UART_MR2_BITS_PER_CHAR_7 (0x2 << 4) | ||
33 | #define UART_MR2_BITS_PER_CHAR_8 (0x3 << 4) | ||
34 | #define UART_MR2_STOP_BIT_LEN_ONE (0x1 << 2) | ||
35 | #define UART_MR2_STOP_BIT_LEN_TWO (0x3 << 2) | ||
36 | #define UART_MR2_PARITY_MODE_NONE 0x0 | ||
37 | #define UART_MR2_PARITY_MODE_ODD 0x1 | ||
38 | #define UART_MR2_PARITY_MODE_EVEN 0x2 | ||
39 | #define UART_MR2_PARITY_MODE_SPACE 0x3 | ||
40 | #define UART_MR2_PARITY_MODE 0x3 | ||
41 | |||
42 | #define UART_CSR 0x0008 | ||
43 | |||
44 | #define UART_TF 0x000C | ||
45 | #define UARTDM_TF 0x0070 | ||
46 | |||
47 | #define UART_CR 0x0010 | ||
48 | #define UART_CR_CMD_NULL (0 << 4) | ||
49 | #define UART_CR_CMD_RESET_RX (1 << 4) | ||
50 | #define UART_CR_CMD_RESET_TX (2 << 4) | ||
51 | #define UART_CR_CMD_RESET_ERR (3 << 4) | ||
52 | #define UART_CR_CMD_RESET_BREAK_INT (4 << 4) | ||
53 | #define UART_CR_CMD_START_BREAK (5 << 4) | ||
54 | #define UART_CR_CMD_STOP_BREAK (6 << 4) | ||
55 | #define UART_CR_CMD_RESET_CTS (7 << 4) | ||
56 | #define UART_CR_CMD_RESET_STALE_INT (8 << 4) | ||
57 | #define UART_CR_CMD_PACKET_MODE (9 << 4) | ||
58 | #define UART_CR_CMD_MODE_RESET (12 << 4) | ||
59 | #define UART_CR_CMD_SET_RFR (13 << 4) | ||
60 | #define UART_CR_CMD_RESET_RFR (14 << 4) | ||
61 | #define UART_CR_CMD_PROTECTION_EN (16 << 4) | ||
62 | #define UART_CR_CMD_STALE_EVENT_DISABLE (6 << 8) | ||
63 | #define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4) | ||
64 | #define UART_CR_CMD_FORCE_STALE (4 << 8) | ||
65 | #define UART_CR_CMD_RESET_TX_READY (3 << 8) | ||
66 | #define UART_CR_TX_DISABLE BIT(3) | ||
67 | #define UART_CR_TX_ENABLE BIT(2) | ||
68 | #define UART_CR_RX_DISABLE BIT(1) | ||
69 | #define UART_CR_RX_ENABLE BIT(0) | ||
70 | #define UART_CR_CMD_RESET_RXBREAK_START ((1 << 11) | (2 << 4)) | ||
71 | |||
72 | #define UART_IMR 0x0014 | ||
73 | #define UART_IMR_TXLEV BIT(0) | ||
74 | #define UART_IMR_RXSTALE BIT(3) | ||
75 | #define UART_IMR_RXLEV BIT(4) | ||
76 | #define UART_IMR_DELTA_CTS BIT(5) | ||
77 | #define UART_IMR_CURRENT_CTS BIT(6) | ||
78 | #define UART_IMR_RXBREAK_START BIT(10) | ||
79 | |||
80 | #define UART_IPR_RXSTALE_LAST 0x20 | ||
81 | #define UART_IPR_STALE_LSB 0x1F | ||
82 | #define UART_IPR_STALE_TIMEOUT_MSB 0x3FF80 | ||
83 | #define UART_DM_IPR_STALE_TIMEOUT_MSB 0xFFFFFF80 | ||
84 | |||
85 | #define UART_IPR 0x0018 | ||
86 | #define UART_TFWR 0x001C | ||
87 | #define UART_RFWR 0x0020 | ||
88 | #define UART_HCR 0x0024 | ||
89 | |||
90 | #define UART_MREG 0x0028 | ||
91 | #define UART_NREG 0x002C | ||
92 | #define UART_DREG 0x0030 | ||
93 | #define UART_MNDREG 0x0034 | ||
94 | #define UART_IRDA 0x0038 | ||
95 | #define UART_MISR_MODE 0x0040 | ||
96 | #define UART_MISR_RESET 0x0044 | ||
97 | #define UART_MISR_EXPORT 0x0048 | ||
98 | #define UART_MISR_VAL 0x004C | ||
99 | #define UART_TEST_CTRL 0x0050 | ||
100 | |||
101 | #define UART_SR 0x0008 | ||
102 | #define UART_SR_HUNT_CHAR BIT(7) | ||
103 | #define UART_SR_RX_BREAK BIT(6) | ||
104 | #define UART_SR_PAR_FRAME_ERR BIT(5) | ||
105 | #define UART_SR_OVERRUN BIT(4) | ||
106 | #define UART_SR_TX_EMPTY BIT(3) | ||
107 | #define UART_SR_TX_READY BIT(2) | ||
108 | #define UART_SR_RX_FULL BIT(1) | ||
109 | #define UART_SR_RX_READY BIT(0) | ||
110 | |||
111 | #define UART_RF 0x000C | ||
112 | #define UARTDM_RF 0x0070 | ||
113 | #define UART_MISR 0x0010 | ||
114 | #define UART_ISR 0x0014 | ||
115 | #define UART_ISR_TX_READY BIT(7) | ||
116 | |||
117 | #define UARTDM_RXFS 0x50 | ||
118 | #define UARTDM_RXFS_BUF_SHIFT 0x7 | ||
119 | #define UARTDM_RXFS_BUF_MASK 0x7 | ||
120 | |||
121 | #define UARTDM_DMEN 0x3C | ||
122 | #define UARTDM_DMEN_RX_SC_ENABLE BIT(5) | ||
123 | #define UARTDM_DMEN_TX_SC_ENABLE BIT(4) | ||
124 | |||
125 | #define UARTDM_DMEN_TX_BAM_ENABLE BIT(2) /* UARTDM_1P4 */ | ||
126 | #define UARTDM_DMEN_TX_DM_ENABLE BIT(0) /* < UARTDM_1P4 */ | ||
127 | |||
128 | #define UARTDM_DMEN_RX_BAM_ENABLE BIT(3) /* UARTDM_1P4 */ | ||
129 | #define UARTDM_DMEN_RX_DM_ENABLE BIT(1) /* < UARTDM_1P4 */ | ||
130 | |||
131 | #define UARTDM_DMRX 0x34 | ||
132 | #define UARTDM_NCF_TX 0x40 | ||
133 | #define UARTDM_RX_TOTAL_SNAP 0x38 | ||
134 | |||
135 | #define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) | ||
136 | |||
137 | static inline | ||
138 | void msm_write(struct uart_port *port, unsigned int val, unsigned int off) | ||
139 | { | ||
140 | writel_relaxed(val, port->membase + off); | ||
141 | } | ||
142 | |||
143 | static inline | ||
144 | unsigned int msm_read(struct uart_port *port, unsigned int off) | ||
145 | { | ||
146 | return readl_relaxed(port->membase + off); | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Setup the MND registers to use the TCXO clock. | ||
151 | */ | ||
152 | static inline void msm_serial_set_mnd_regs_tcxo(struct uart_port *port) | ||
153 | { | ||
154 | msm_write(port, 0x06, UART_MREG); | ||
155 | msm_write(port, 0xF1, UART_NREG); | ||
156 | msm_write(port, 0x0F, UART_DREG); | ||
157 | msm_write(port, 0x1A, UART_MNDREG); | ||
158 | port->uartclk = 1843200; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Setup the MND registers to use the TCXO clock divided by 4. | ||
163 | */ | ||
164 | static inline void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port) | ||
165 | { | ||
166 | msm_write(port, 0x18, UART_MREG); | ||
167 | msm_write(port, 0xF6, UART_NREG); | ||
168 | msm_write(port, 0x0F, UART_DREG); | ||
169 | msm_write(port, 0x0A, UART_MNDREG); | ||
170 | port->uartclk = 1843200; | ||
171 | } | ||
172 | |||
173 | static inline | ||
174 | void msm_serial_set_mnd_regs_from_uartclk(struct uart_port *port) | ||
175 | { | ||
176 | if (port->uartclk == 19200000) | ||
177 | msm_serial_set_mnd_regs_tcxo(port); | ||
178 | else if (port->uartclk == 4800000) | ||
179 | msm_serial_set_mnd_regs_tcxoby4(port); | ||
180 | } | ||
181 | |||
182 | #define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_from_uartclk | ||
183 | |||
184 | #endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */ | ||
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index ce362bd51de7..45b57c294d13 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c | |||
@@ -300,6 +300,8 @@ static int mvebu_uart_startup(struct uart_port *port) | |||
300 | static void mvebu_uart_shutdown(struct uart_port *port) | 300 | static void mvebu_uart_shutdown(struct uart_port *port) |
301 | { | 301 | { |
302 | writel(0, port->membase + UART_CTRL); | 302 | writel(0, port->membase + UART_CTRL); |
303 | |||
304 | free_irq(port->irq, port); | ||
303 | } | 305 | } |
304 | 306 | ||
305 | static void mvebu_uart_set_termios(struct uart_port *port, | 307 | static void mvebu_uart_set_termios(struct uart_port *port, |
diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index 62a43bf5698e..7f8e99bbcb73 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c | |||
@@ -445,7 +445,6 @@ static int pic32_uart_startup(struct uart_port *port) | |||
445 | sport->idx); | 445 | sport->idx); |
446 | if (!sport->irq_rx_name) { | 446 | if (!sport->irq_rx_name) { |
447 | dev_err(port->dev, "%s: kasprintf err!", __func__); | 447 | dev_err(port->dev, "%s: kasprintf err!", __func__); |
448 | kfree(sport->irq_fault_name); | ||
449 | ret = -ENOMEM; | 448 | ret = -ENOMEM; |
450 | goto out_f; | 449 | goto out_f; |
451 | } | 450 | } |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index e156e39d620c..b24b0556f5a8 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -1720,7 +1720,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) | |||
1720 | 1720 | ||
1721 | r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0); | 1721 | r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0); |
1722 | irq = platform_get_irq(uap->pdev, 0); | 1722 | irq = platform_get_irq(uap->pdev, 0); |
1723 | if (!r_ports || !irq) | 1723 | if (!r_ports || irq <= 0) |
1724 | return -ENODEV; | 1724 | return -ENODEV; |
1725 | 1725 | ||
1726 | uap->port.mapbase = r_ports->start; | 1726 | uap->port.mapbase = r_ports->start; |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 41eab75ba2af..cd9d9e878475 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #define SUPPORT_SYSRQ | 27 | #define SUPPORT_SYSRQ |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
32 | #include <linux/init.h> | 31 | #include <linux/init.h> |
33 | #include <linux/console.h> | 32 | #include <linux/console.h> |
@@ -829,7 +828,6 @@ static const struct of_device_id serial_pxa_dt_ids[] = { | |||
829 | { .compatible = "mrvl,mmp-uart", }, | 828 | { .compatible = "mrvl,mmp-uart", }, |
830 | {} | 829 | {} |
831 | }; | 830 | }; |
832 | MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids); | ||
833 | 831 | ||
834 | static int serial_pxa_probe_dt(struct platform_device *pdev, | 832 | static int serial_pxa_probe_dt(struct platform_device *pdev, |
835 | struct uart_pxa_port *sport) | 833 | struct uart_pxa_port *sport) |
@@ -914,28 +912,15 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
914 | return ret; | 912 | return ret; |
915 | } | 913 | } |
916 | 914 | ||
917 | static int serial_pxa_remove(struct platform_device *dev) | ||
918 | { | ||
919 | struct uart_pxa_port *sport = platform_get_drvdata(dev); | ||
920 | |||
921 | uart_remove_one_port(&serial_pxa_reg, &sport->port); | ||
922 | |||
923 | clk_unprepare(sport->clk); | ||
924 | clk_put(sport->clk); | ||
925 | kfree(sport); | ||
926 | |||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | static struct platform_driver serial_pxa_driver = { | 915 | static struct platform_driver serial_pxa_driver = { |
931 | .probe = serial_pxa_probe, | 916 | .probe = serial_pxa_probe, |
932 | .remove = serial_pxa_remove, | ||
933 | 917 | ||
934 | .driver = { | 918 | .driver = { |
935 | .name = "pxa2xx-uart", | 919 | .name = "pxa2xx-uart", |
936 | #ifdef CONFIG_PM | 920 | #ifdef CONFIG_PM |
937 | .pm = &serial_pxa_pm_ops, | 921 | .pm = &serial_pxa_pm_ops, |
938 | #endif | 922 | #endif |
923 | .suppress_bind_attrs = true, | ||
939 | .of_match_table = serial_pxa_dt_ids, | 924 | .of_match_table = serial_pxa_dt_ids, |
940 | }, | 925 | }, |
941 | }; | 926 | }; |
@@ -954,15 +939,4 @@ static int __init serial_pxa_init(void) | |||
954 | 939 | ||
955 | return ret; | 940 | return ret; |
956 | } | 941 | } |
957 | 942 | device_initcall(serial_pxa_init); | |
958 | static void __exit serial_pxa_exit(void) | ||
959 | { | ||
960 | platform_driver_unregister(&serial_pxa_driver); | ||
961 | uart_unregister_driver(&serial_pxa_reg); | ||
962 | } | ||
963 | |||
964 | module_init(serial_pxa_init); | ||
965 | module_exit(serial_pxa_exit); | ||
966 | |||
967 | MODULE_LICENSE("GPL"); | ||
968 | MODULE_ALIAS("platform:pxa2xx-uart"); | ||
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 99bb23161dd6..ae2095a66708 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -169,8 +169,7 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) | |||
169 | return; | 169 | return; |
170 | 170 | ||
171 | if (s3c24xx_serial_has_interrupt_mask(port)) | 171 | if (s3c24xx_serial_has_interrupt_mask(port)) |
172 | __set_bit(S3C64XX_UINTM_TXD, | 172 | s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM); |
173 | portaddrl(port, S3C64XX_UINTM)); | ||
174 | else | 173 | else |
175 | disable_irq_nosync(ourport->tx_irq); | 174 | disable_irq_nosync(ourport->tx_irq); |
176 | 175 | ||
@@ -235,8 +234,7 @@ static void enable_tx_dma(struct s3c24xx_uart_port *ourport) | |||
235 | 234 | ||
236 | /* Mask Tx interrupt */ | 235 | /* Mask Tx interrupt */ |
237 | if (s3c24xx_serial_has_interrupt_mask(port)) | 236 | if (s3c24xx_serial_has_interrupt_mask(port)) |
238 | __set_bit(S3C64XX_UINTM_TXD, | 237 | s3c24xx_set_bit(port, S3C64XX_UINTM_TXD, S3C64XX_UINTM); |
239 | portaddrl(port, S3C64XX_UINTM)); | ||
240 | else | 238 | else |
241 | disable_irq_nosync(ourport->tx_irq); | 239 | disable_irq_nosync(ourport->tx_irq); |
242 | 240 | ||
@@ -269,8 +267,8 @@ static void enable_tx_pio(struct s3c24xx_uart_port *ourport) | |||
269 | 267 | ||
270 | /* Unmask Tx interrupt */ | 268 | /* Unmask Tx interrupt */ |
271 | if (s3c24xx_serial_has_interrupt_mask(port)) | 269 | if (s3c24xx_serial_has_interrupt_mask(port)) |
272 | __clear_bit(S3C64XX_UINTM_TXD, | 270 | s3c24xx_clear_bit(port, S3C64XX_UINTM_TXD, |
273 | portaddrl(port, S3C64XX_UINTM)); | 271 | S3C64XX_UINTM); |
274 | else | 272 | else |
275 | enable_irq(ourport->tx_irq); | 273 | enable_irq(ourport->tx_irq); |
276 | 274 | ||
@@ -397,8 +395,8 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) | |||
397 | if (rx_enabled(port)) { | 395 | if (rx_enabled(port)) { |
398 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); | 396 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); |
399 | if (s3c24xx_serial_has_interrupt_mask(port)) | 397 | if (s3c24xx_serial_has_interrupt_mask(port)) |
400 | __set_bit(S3C64XX_UINTM_RXD, | 398 | s3c24xx_set_bit(port, S3C64XX_UINTM_RXD, |
401 | portaddrl(port, S3C64XX_UINTM)); | 399 | S3C64XX_UINTM); |
402 | else | 400 | else |
403 | disable_irq_nosync(ourport->rx_irq); | 401 | disable_irq_nosync(ourport->rx_irq); |
404 | rx_enabled(port) = 0; | 402 | rx_enabled(port) = 0; |
@@ -1069,7 +1067,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) | |||
1069 | spin_unlock_irqrestore(&port->lock, flags); | 1067 | spin_unlock_irqrestore(&port->lock, flags); |
1070 | 1068 | ||
1071 | /* Enable Rx Interrupt */ | 1069 | /* Enable Rx Interrupt */ |
1072 | __clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM)); | 1070 | s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM); |
1073 | 1071 | ||
1074 | dbg("s3c64xx_serial_startup ok\n"); | 1072 | dbg("s3c64xx_serial_startup ok\n"); |
1075 | return ret; | 1073 | return ret; |
@@ -1684,7 +1682,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1684 | return -ENODEV; | 1682 | return -ENODEV; |
1685 | 1683 | ||
1686 | if (port->mapbase != 0) | 1684 | if (port->mapbase != 0) |
1687 | return 0; | 1685 | return -EINVAL; |
1688 | 1686 | ||
1689 | /* setup info for port */ | 1687 | /* setup info for port */ |
1690 | port->dev = &platdev->dev; | 1688 | port->dev = &platdev->dev; |
@@ -1738,22 +1736,25 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1738 | ourport->dma = devm_kzalloc(port->dev, | 1736 | ourport->dma = devm_kzalloc(port->dev, |
1739 | sizeof(*ourport->dma), | 1737 | sizeof(*ourport->dma), |
1740 | GFP_KERNEL); | 1738 | GFP_KERNEL); |
1741 | if (!ourport->dma) | 1739 | if (!ourport->dma) { |
1742 | return -ENOMEM; | 1740 | ret = -ENOMEM; |
1741 | goto err; | ||
1742 | } | ||
1743 | } | 1743 | } |
1744 | 1744 | ||
1745 | ourport->clk = clk_get(&platdev->dev, "uart"); | 1745 | ourport->clk = clk_get(&platdev->dev, "uart"); |
1746 | if (IS_ERR(ourport->clk)) { | 1746 | if (IS_ERR(ourport->clk)) { |
1747 | pr_err("%s: Controller clock not found\n", | 1747 | pr_err("%s: Controller clock not found\n", |
1748 | dev_name(&platdev->dev)); | 1748 | dev_name(&platdev->dev)); |
1749 | return PTR_ERR(ourport->clk); | 1749 | ret = PTR_ERR(ourport->clk); |
1750 | goto err; | ||
1750 | } | 1751 | } |
1751 | 1752 | ||
1752 | ret = clk_prepare_enable(ourport->clk); | 1753 | ret = clk_prepare_enable(ourport->clk); |
1753 | if (ret) { | 1754 | if (ret) { |
1754 | pr_err("uart: clock failed to prepare+enable: %d\n", ret); | 1755 | pr_err("uart: clock failed to prepare+enable: %d\n", ret); |
1755 | clk_put(ourport->clk); | 1756 | clk_put(ourport->clk); |
1756 | return ret; | 1757 | goto err; |
1757 | } | 1758 | } |
1758 | 1759 | ||
1759 | /* Keep all interrupts masked and cleared */ | 1760 | /* Keep all interrupts masked and cleared */ |
@@ -1769,7 +1770,12 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1769 | 1770 | ||
1770 | /* reset the fifos (and setup the uart) */ | 1771 | /* reset the fifos (and setup the uart) */ |
1771 | s3c24xx_serial_resetport(port, cfg); | 1772 | s3c24xx_serial_resetport(port, cfg); |
1773 | |||
1772 | return 0; | 1774 | return 0; |
1775 | |||
1776 | err: | ||
1777 | port->mapbase = 0; | ||
1778 | return ret; | ||
1773 | } | 1779 | } |
1774 | 1780 | ||
1775 | /* Device driver serial port probe */ | 1781 | /* Device driver serial port probe */ |
@@ -1836,8 +1842,6 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) | |||
1836 | ourport->min_dma_size = max_t(int, ourport->port.fifosize, | 1842 | ourport->min_dma_size = max_t(int, ourport->port.fifosize, |
1837 | dma_get_cache_alignment()); | 1843 | dma_get_cache_alignment()); |
1838 | 1844 | ||
1839 | probe_index++; | ||
1840 | |||
1841 | dbg("%s: initialising port %p...\n", __func__, ourport); | 1845 | dbg("%s: initialising port %p...\n", __func__, ourport); |
1842 | 1846 | ||
1843 | ret = s3c24xx_serial_init_port(ourport, pdev); | 1847 | ret = s3c24xx_serial_init_port(ourport, pdev); |
@@ -1867,6 +1871,8 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) | |||
1867 | if (ret < 0) | 1871 | if (ret < 0) |
1868 | dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); | 1872 | dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); |
1869 | 1873 | ||
1874 | probe_index++; | ||
1875 | |||
1870 | return 0; | 1876 | return 0; |
1871 | } | 1877 | } |
1872 | 1878 | ||
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index fc5deaa4f382..2ae4fcee1814 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h | |||
@@ -117,10 +117,38 @@ struct s3c24xx_uart_port { | |||
117 | #define portaddrl(port, reg) \ | 117 | #define portaddrl(port, reg) \ |
118 | ((unsigned long *)(unsigned long)((port)->membase + (reg))) | 118 | ((unsigned long *)(unsigned long)((port)->membase + (reg))) |
119 | 119 | ||
120 | #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg))) | 120 | #define rd_regb(port, reg) (readb_relaxed(portaddr(port, reg))) |
121 | #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) | 121 | #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg))) |
122 | 122 | ||
123 | #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) | 123 | #define wr_regb(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) |
124 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) | 124 | #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg)) |
125 | |||
126 | /* Byte-order aware bit setting/clearing functions. */ | ||
127 | |||
128 | static inline void s3c24xx_set_bit(struct uart_port *port, int idx, | ||
129 | unsigned int reg) | ||
130 | { | ||
131 | unsigned long flags; | ||
132 | u32 val; | ||
133 | |||
134 | local_irq_save(flags); | ||
135 | val = rd_regl(port, reg); | ||
136 | val |= (1 << idx); | ||
137 | wr_regl(port, reg, val); | ||
138 | local_irq_restore(flags); | ||
139 | } | ||
140 | |||
141 | static inline void s3c24xx_clear_bit(struct uart_port *port, int idx, | ||
142 | unsigned int reg) | ||
143 | { | ||
144 | unsigned long flags; | ||
145 | u32 val; | ||
146 | |||
147 | local_irq_save(flags); | ||
148 | val = rd_regl(port, reg); | ||
149 | val &= ~(1 << idx); | ||
150 | wr_regl(port, reg, val); | ||
151 | local_irq_restore(flags); | ||
152 | } | ||
125 | 153 | ||
126 | #endif | 154 | #endif |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 1dba6719db8d..731ac35acb31 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -1317,7 +1317,12 @@ static int tegra_uart_probe(struct platform_device *pdev) | |||
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | u->iotype = UPIO_MEM32; | 1319 | u->iotype = UPIO_MEM32; |
1320 | u->irq = platform_get_irq(pdev, 0); | 1320 | ret = platform_get_irq(pdev, 0); |
1321 | if (ret < 0) { | ||
1322 | dev_err(&pdev->dev, "Couldn't get IRQ\n"); | ||
1323 | return ret; | ||
1324 | } | ||
1325 | u->irq = ret; | ||
1321 | u->regshift = 2; | 1326 | u->regshift = 2; |
1322 | ret = uart_add_one_port(&tegra_uart_driver, u); | 1327 | ret = uart_add_one_port(&tegra_uart_driver, u); |
1323 | if (ret < 0) { | 1328 | if (ret < 0) { |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a333c59cba2c..9fc15335c8c5 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -887,7 +887,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
887 | /* | 887 | /* |
888 | * Free and release old regions | 888 | * Free and release old regions |
889 | */ | 889 | */ |
890 | if (old_type != PORT_UNKNOWN) | 890 | if (old_type != PORT_UNKNOWN && uport->ops->release_port) |
891 | uport->ops->release_port(uport); | 891 | uport->ops->release_port(uport); |
892 | 892 | ||
893 | uport->iobase = new_port; | 893 | uport->iobase = new_port; |
@@ -900,7 +900,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
900 | /* | 900 | /* |
901 | * Claim and map the new regions | 901 | * Claim and map the new regions |
902 | */ | 902 | */ |
903 | if (uport->type != PORT_UNKNOWN) { | 903 | if (uport->type != PORT_UNKNOWN && uport->ops->request_port) { |
904 | retval = uport->ops->request_port(uport); | 904 | retval = uport->ops->request_port(uport); |
905 | } else { | 905 | } else { |
906 | /* Always success - Jean II */ | 906 | /* Always success - Jean II */ |
@@ -1125,7 +1125,7 @@ static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) | |||
1125 | * If we already have a port type configured, | 1125 | * If we already have a port type configured, |
1126 | * we must release its resources. | 1126 | * we must release its resources. |
1127 | */ | 1127 | */ |
1128 | if (uport->type != PORT_UNKNOWN) | 1128 | if (uport->type != PORT_UNKNOWN && uport->ops->release_port) |
1129 | uport->ops->release_port(uport); | 1129 | uport->ops->release_port(uport); |
1130 | 1130 | ||
1131 | flags = UART_CONFIG_TYPE; | 1131 | flags = UART_CONFIG_TYPE; |
@@ -2897,7 +2897,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2897 | /* | 2897 | /* |
2898 | * Free the port IO and memory resources, if any. | 2898 | * Free the port IO and memory resources, if any. |
2899 | */ | 2899 | */ |
2900 | if (uport->type != PORT_UNKNOWN) | 2900 | if (uport->type != PORT_UNKNOWN && uport->ops->release_port) |
2901 | uport->ops->release_port(uport); | 2901 | uport->ops->release_port(uport); |
2902 | kfree(uport->tty_groups); | 2902 | kfree(uport->tty_groups); |
2903 | 2903 | ||
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index e8dd5097dc56..d2da6aa7f27d 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c | |||
@@ -52,6 +52,9 @@ void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl) | |||
52 | int value_array[UART_GPIO_MAX]; | 52 | int value_array[UART_GPIO_MAX]; |
53 | unsigned int count = 0; | 53 | unsigned int count = 0; |
54 | 54 | ||
55 | if (gpios == NULL) | ||
56 | return; | ||
57 | |||
55 | for (i = 0; i < UART_GPIO_MAX; i++) | 58 | for (i = 0; i < UART_GPIO_MAX; i++) |
56 | if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) { | 59 | if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) { |
57 | desc_array[count] = gpios->gpio[i]; | 60 | desc_array[count] = gpios->gpio[i]; |
@@ -73,6 +76,9 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) | |||
73 | { | 76 | { |
74 | enum mctrl_gpio_idx i; | 77 | enum mctrl_gpio_idx i; |
75 | 78 | ||
79 | if (gpios == NULL) | ||
80 | return *mctrl; | ||
81 | |||
76 | for (i = 0; i < UART_GPIO_MAX; i++) { | 82 | for (i = 0; i < UART_GPIO_MAX; i++) { |
77 | if (gpios->gpio[i] && !mctrl_gpios_desc[i].dir_out) { | 83 | if (gpios->gpio[i] && !mctrl_gpios_desc[i].dir_out) { |
78 | if (gpiod_get_value(gpios->gpio[i])) | 84 | if (gpiod_get_value(gpios->gpio[i])) |
@@ -86,6 +92,27 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) | |||
86 | } | 92 | } |
87 | EXPORT_SYMBOL_GPL(mctrl_gpio_get); | 93 | EXPORT_SYMBOL_GPL(mctrl_gpio_get); |
88 | 94 | ||
95 | unsigned int | ||
96 | mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl) | ||
97 | { | ||
98 | enum mctrl_gpio_idx i; | ||
99 | |||
100 | if (gpios == NULL) | ||
101 | return *mctrl; | ||
102 | |||
103 | for (i = 0; i < UART_GPIO_MAX; i++) { | ||
104 | if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) { | ||
105 | if (gpiod_get_value(gpios->gpio[i])) | ||
106 | *mctrl |= mctrl_gpios_desc[i].mctrl; | ||
107 | else | ||
108 | *mctrl &= ~mctrl_gpios_desc[i].mctrl; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | return *mctrl; | ||
113 | } | ||
114 | EXPORT_SYMBOL_GPL(mctrl_gpio_get_outputs); | ||
115 | |||
89 | struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx) | 116 | struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx) |
90 | { | 117 | { |
91 | struct mctrl_gpios *gpios; | 118 | struct mctrl_gpios *gpios; |
@@ -203,6 +230,9 @@ void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) | |||
203 | { | 230 | { |
204 | enum mctrl_gpio_idx i; | 231 | enum mctrl_gpio_idx i; |
205 | 232 | ||
233 | if (gpios == NULL) | ||
234 | return; | ||
235 | |||
206 | for (i = 0; i < UART_GPIO_MAX; i++) { | 236 | for (i = 0; i < UART_GPIO_MAX; i++) { |
207 | if (gpios->irq[i]) | 237 | if (gpios->irq[i]) |
208 | devm_free_irq(gpios->port->dev, gpios->irq[i], gpios); | 238 | devm_free_irq(gpios->port->dev, gpios->irq[i], gpios); |
@@ -218,6 +248,9 @@ void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios) | |||
218 | { | 248 | { |
219 | enum mctrl_gpio_idx i; | 249 | enum mctrl_gpio_idx i; |
220 | 250 | ||
251 | if (gpios == NULL) | ||
252 | return; | ||
253 | |||
221 | /* .enable_ms may be called multiple times */ | 254 | /* .enable_ms may be called multiple times */ |
222 | if (gpios->mctrl_on) | 255 | if (gpios->mctrl_on) |
223 | return; | 256 | return; |
@@ -240,6 +273,9 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) | |||
240 | { | 273 | { |
241 | enum mctrl_gpio_idx i; | 274 | enum mctrl_gpio_idx i; |
242 | 275 | ||
276 | if (gpios == NULL) | ||
277 | return; | ||
278 | |||
243 | if (!gpios->mctrl_on) | 279 | if (!gpios->mctrl_on) |
244 | return; | 280 | return; |
245 | 281 | ||
diff --git a/drivers/tty/serial/serial_mctrl_gpio.h b/drivers/tty/serial/serial_mctrl_gpio.h index 332a33ab0647..fa000bcff217 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.h +++ b/drivers/tty/serial/serial_mctrl_gpio.h | |||
@@ -48,12 +48,19 @@ struct mctrl_gpios; | |||
48 | void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl); | 48 | void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl); |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Get state of the modem control output lines from GPIOs. | 51 | * Get state of the modem control input lines from GPIOs. |
52 | * The mctrl flags are updated and returned. | 52 | * The mctrl flags are updated and returned. |
53 | */ | 53 | */ |
54 | unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl); | 54 | unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl); |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Get state of the modem control output lines from GPIOs. | ||
58 | * The mctrl flags are updated and returned. | ||
59 | */ | ||
60 | unsigned int | ||
61 | mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl); | ||
62 | |||
63 | /* | ||
57 | * Returns the associated struct gpio_desc to the modem line gidx | 64 | * Returns the associated struct gpio_desc to the modem line gidx |
58 | */ | 65 | */ |
59 | struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, | 66 | struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, |
@@ -107,6 +114,12 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) | |||
107 | return *mctrl; | 114 | return *mctrl; |
108 | } | 115 | } |
109 | 116 | ||
117 | static inline unsigned int | ||
118 | mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl) | ||
119 | { | ||
120 | return *mctrl; | ||
121 | } | ||
122 | |||
110 | static inline | 123 | static inline |
111 | struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, | 124 | struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, |
112 | enum mctrl_gpio_idx gidx) | 125 | enum mctrl_gpio_idx gidx) |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 0130feb069ae..d86eee38aae6 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <asm/sh_bios.h> | 57 | #include <asm/sh_bios.h> |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | #include "serial_mctrl_gpio.h" | ||
60 | #include "sh-sci.h" | 61 | #include "sh-sci.h" |
61 | 62 | ||
62 | /* Offsets into the sci_port->irqs array */ | 63 | /* Offsets into the sci_port->irqs array */ |
@@ -111,6 +112,7 @@ struct sci_port { | |||
111 | unsigned int error_clear; | 112 | unsigned int error_clear; |
112 | unsigned int sampling_rate_mask; | 113 | unsigned int sampling_rate_mask; |
113 | resource_size_t reg_size; | 114 | resource_size_t reg_size; |
115 | struct mctrl_gpios *gpios; | ||
114 | 116 | ||
115 | /* Break timer */ | 117 | /* Break timer */ |
116 | struct timer_list break_timer; | 118 | struct timer_list break_timer; |
@@ -139,6 +141,8 @@ struct sci_port { | |||
139 | struct timer_list rx_timer; | 141 | struct timer_list rx_timer; |
140 | unsigned int rx_timeout; | 142 | unsigned int rx_timeout; |
141 | #endif | 143 | #endif |
144 | |||
145 | bool autorts; | ||
142 | }; | 146 | }; |
143 | 147 | ||
144 | #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS | 148 | #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS |
@@ -701,7 +705,6 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) | |||
701 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) | 705 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
702 | { | 706 | { |
703 | struct sci_port *s = to_sci_port(port); | 707 | struct sci_port *s = to_sci_port(port); |
704 | const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; | ||
705 | 708 | ||
706 | /* | 709 | /* |
707 | * Use port-specific handler if provided. | 710 | * Use port-specific handler if provided. |
@@ -711,21 +714,28 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
711 | return; | 714 | return; |
712 | } | 715 | } |
713 | 716 | ||
714 | /* | 717 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { |
715 | * For the generic path SCSPTR is necessary. Bail out if that's | 718 | u16 ctrl = serial_port_in(port, SCPCR); |
716 | * unavailable, too. | 719 | |
717 | */ | 720 | /* Enable RXD and TXD pin functions */ |
718 | if (!reg->size) | 721 | ctrl &= ~(SCPCR_RXDC | SCPCR_TXDC); |
719 | return; | 722 | if (to_sci_port(port)->cfg->capabilities & SCIx_HAVE_RTSCTS) { |
720 | 723 | /* RTS# is output, driven 1 */ | |
721 | if ((s->cfg->capabilities & SCIx_HAVE_RTSCTS) && | 724 | ctrl |= SCPCR_RTSC; |
722 | ((!(cflag & CRTSCTS)))) { | 725 | serial_port_out(port, SCPDR, |
723 | unsigned short status; | 726 | serial_port_in(port, SCPDR) | SCPDR_RTSD); |
727 | /* Enable CTS# pin function */ | ||
728 | ctrl &= ~SCPCR_CTSC; | ||
729 | } | ||
730 | serial_port_out(port, SCPCR, ctrl); | ||
731 | } else if (sci_getreg(port, SCSPTR)->size) { | ||
732 | u16 status = serial_port_in(port, SCSPTR); | ||
724 | 733 | ||
725 | status = serial_port_in(port, SCSPTR); | 734 | /* RTS# is output, driven 1 */ |
726 | status &= ~SCSPTR_CTSIO; | 735 | status |= SCSPTR_RTSIO | SCSPTR_RTSDT; |
727 | status |= SCSPTR_RTSIO; | 736 | /* CTS# and SCK are inputs */ |
728 | serial_port_out(port, SCSPTR, status); /* Set RTS = 1 */ | 737 | status &= ~(SCSPTR_CTSIO | SCSPTR_SCKIO); |
738 | serial_port_out(port, SCSPTR, status); | ||
729 | } | 739 | } |
730 | } | 740 | } |
731 | 741 | ||
@@ -1803,6 +1813,46 @@ static unsigned int sci_tx_empty(struct uart_port *port) | |||
1803 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; | 1813 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; |
1804 | } | 1814 | } |
1805 | 1815 | ||
1816 | static void sci_set_rts(struct uart_port *port, bool state) | ||
1817 | { | ||
1818 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
1819 | u16 data = serial_port_in(port, SCPDR); | ||
1820 | |||
1821 | /* Active low */ | ||
1822 | if (state) | ||
1823 | data &= ~SCPDR_RTSD; | ||
1824 | else | ||
1825 | data |= SCPDR_RTSD; | ||
1826 | serial_port_out(port, SCPDR, data); | ||
1827 | |||
1828 | /* RTS# is output */ | ||
1829 | serial_port_out(port, SCPCR, | ||
1830 | serial_port_in(port, SCPCR) | SCPCR_RTSC); | ||
1831 | } else if (sci_getreg(port, SCSPTR)->size) { | ||
1832 | u16 ctrl = serial_port_in(port, SCSPTR); | ||
1833 | |||
1834 | /* Active low */ | ||
1835 | if (state) | ||
1836 | ctrl &= ~SCSPTR_RTSDT; | ||
1837 | else | ||
1838 | ctrl |= SCSPTR_RTSDT; | ||
1839 | serial_port_out(port, SCSPTR, ctrl); | ||
1840 | } | ||
1841 | } | ||
1842 | |||
1843 | static bool sci_get_cts(struct uart_port *port) | ||
1844 | { | ||
1845 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
1846 | /* Active low */ | ||
1847 | return !(serial_port_in(port, SCPDR) & SCPDR_CTSD); | ||
1848 | } else if (sci_getreg(port, SCSPTR)->size) { | ||
1849 | /* Active low */ | ||
1850 | return !(serial_port_in(port, SCSPTR) & SCSPTR_CTSDT); | ||
1851 | } | ||
1852 | |||
1853 | return true; | ||
1854 | } | ||
1855 | |||
1806 | /* | 1856 | /* |
1807 | * Modem control is a bit of a mixed bag for SCI(F) ports. Generally | 1857 | * Modem control is a bit of a mixed bag for SCI(F) ports. Generally |
1808 | * CTS/RTS is supported in hardware by at least one port and controlled | 1858 | * CTS/RTS is supported in hardware by at least one port and controlled |
@@ -1817,6 +1867,8 @@ static unsigned int sci_tx_empty(struct uart_port *port) | |||
1817 | */ | 1867 | */ |
1818 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1868 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1819 | { | 1869 | { |
1870 | struct sci_port *s = to_sci_port(port); | ||
1871 | |||
1820 | if (mctrl & TIOCM_LOOP) { | 1872 | if (mctrl & TIOCM_LOOP) { |
1821 | const struct plat_sci_reg *reg; | 1873 | const struct plat_sci_reg *reg; |
1822 | 1874 | ||
@@ -1829,25 +1881,72 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
1829 | serial_port_in(port, SCFCR) | | 1881 | serial_port_in(port, SCFCR) | |
1830 | SCFCR_LOOP); | 1882 | SCFCR_LOOP); |
1831 | } | 1883 | } |
1884 | |||
1885 | mctrl_gpio_set(s->gpios, mctrl); | ||
1886 | |||
1887 | if (!(s->cfg->capabilities & SCIx_HAVE_RTSCTS)) | ||
1888 | return; | ||
1889 | |||
1890 | if (!(mctrl & TIOCM_RTS)) { | ||
1891 | /* Disable Auto RTS */ | ||
1892 | serial_port_out(port, SCFCR, | ||
1893 | serial_port_in(port, SCFCR) & ~SCFCR_MCE); | ||
1894 | |||
1895 | /* Clear RTS */ | ||
1896 | sci_set_rts(port, 0); | ||
1897 | } else if (s->autorts) { | ||
1898 | if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { | ||
1899 | /* Enable RTS# pin function */ | ||
1900 | serial_port_out(port, SCPCR, | ||
1901 | serial_port_in(port, SCPCR) & ~SCPCR_RTSC); | ||
1902 | } | ||
1903 | |||
1904 | /* Enable Auto RTS */ | ||
1905 | serial_port_out(port, SCFCR, | ||
1906 | serial_port_in(port, SCFCR) | SCFCR_MCE); | ||
1907 | } else { | ||
1908 | /* Set RTS */ | ||
1909 | sci_set_rts(port, 1); | ||
1910 | } | ||
1832 | } | 1911 | } |
1833 | 1912 | ||
1834 | static unsigned int sci_get_mctrl(struct uart_port *port) | 1913 | static unsigned int sci_get_mctrl(struct uart_port *port) |
1835 | { | 1914 | { |
1915 | struct sci_port *s = to_sci_port(port); | ||
1916 | struct mctrl_gpios *gpios = s->gpios; | ||
1917 | unsigned int mctrl = 0; | ||
1918 | |||
1919 | mctrl_gpio_get(gpios, &mctrl); | ||
1920 | |||
1836 | /* | 1921 | /* |
1837 | * CTS/RTS is handled in hardware when supported, while nothing | 1922 | * CTS/RTS is handled in hardware when supported, while nothing |
1838 | * else is wired up. Keep it simple and simply assert DSR/CAR. | 1923 | * else is wired up. |
1839 | */ | 1924 | */ |
1840 | return TIOCM_DSR | TIOCM_CAR; | 1925 | if (s->autorts) { |
1926 | if (sci_get_cts(port)) | ||
1927 | mctrl |= TIOCM_CTS; | ||
1928 | } else if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(gpios, UART_GPIO_CTS))) { | ||
1929 | mctrl |= TIOCM_CTS; | ||
1930 | } | ||
1931 | if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(gpios, UART_GPIO_DSR))) | ||
1932 | mctrl |= TIOCM_DSR; | ||
1933 | if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(gpios, UART_GPIO_DCD))) | ||
1934 | mctrl |= TIOCM_CAR; | ||
1935 | |||
1936 | return mctrl; | ||
1937 | } | ||
1938 | |||
1939 | static void sci_enable_ms(struct uart_port *port) | ||
1940 | { | ||
1941 | mctrl_gpio_enable_ms(to_sci_port(port)->gpios); | ||
1841 | } | 1942 | } |
1842 | 1943 | ||
1843 | static void sci_break_ctl(struct uart_port *port, int break_state) | 1944 | static void sci_break_ctl(struct uart_port *port, int break_state) |
1844 | { | 1945 | { |
1845 | struct sci_port *s = to_sci_port(port); | ||
1846 | const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; | ||
1847 | unsigned short scscr, scsptr; | 1946 | unsigned short scscr, scsptr; |
1848 | 1947 | ||
1849 | /* check wheter the port has SCSPTR */ | 1948 | /* check wheter the port has SCSPTR */ |
1850 | if (!reg->size) { | 1949 | if (!sci_getreg(port, SCSPTR)->size) { |
1851 | /* | 1950 | /* |
1852 | * Not supported by hardware. Most parts couple break and rx | 1951 | * Not supported by hardware. Most parts couple break and rx |
1853 | * interrupts together, with break detection always enabled. | 1952 | * interrupts together, with break detection always enabled. |
@@ -1873,7 +1972,6 @@ static void sci_break_ctl(struct uart_port *port, int break_state) | |||
1873 | static int sci_startup(struct uart_port *port) | 1972 | static int sci_startup(struct uart_port *port) |
1874 | { | 1973 | { |
1875 | struct sci_port *s = to_sci_port(port); | 1974 | struct sci_port *s = to_sci_port(port); |
1876 | unsigned long flags; | ||
1877 | int ret; | 1975 | int ret; |
1878 | 1976 | ||
1879 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1977 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
@@ -1884,11 +1982,6 @@ static int sci_startup(struct uart_port *port) | |||
1884 | 1982 | ||
1885 | sci_request_dma(port); | 1983 | sci_request_dma(port); |
1886 | 1984 | ||
1887 | spin_lock_irqsave(&port->lock, flags); | ||
1888 | sci_start_tx(port); | ||
1889 | sci_start_rx(port); | ||
1890 | spin_unlock_irqrestore(&port->lock, flags); | ||
1891 | |||
1892 | return 0; | 1985 | return 0; |
1893 | } | 1986 | } |
1894 | 1987 | ||
@@ -1896,12 +1989,19 @@ static void sci_shutdown(struct uart_port *port) | |||
1896 | { | 1989 | { |
1897 | struct sci_port *s = to_sci_port(port); | 1990 | struct sci_port *s = to_sci_port(port); |
1898 | unsigned long flags; | 1991 | unsigned long flags; |
1992 | u16 scr; | ||
1899 | 1993 | ||
1900 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1994 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
1901 | 1995 | ||
1996 | s->autorts = false; | ||
1997 | mctrl_gpio_disable_ms(to_sci_port(port)->gpios); | ||
1998 | |||
1902 | spin_lock_irqsave(&port->lock, flags); | 1999 | spin_lock_irqsave(&port->lock, flags); |
1903 | sci_stop_rx(port); | 2000 | sci_stop_rx(port); |
1904 | sci_stop_tx(port); | 2001 | sci_stop_tx(port); |
2002 | /* Stop RX and TX, disable related interrupts, keep clock source */ | ||
2003 | scr = serial_port_in(port, SCSCR); | ||
2004 | serial_port_out(port, SCSCR, scr & (SCSCR_CKE1 | SCSCR_CKE0)); | ||
1905 | spin_unlock_irqrestore(&port->lock, flags); | 2005 | spin_unlock_irqrestore(&port->lock, flags); |
1906 | 2006 | ||
1907 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | 2007 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
@@ -2056,6 +2156,15 @@ static void sci_reset(struct uart_port *port) | |||
2056 | reg = sci_getreg(port, SCFCR); | 2156 | reg = sci_getreg(port, SCFCR); |
2057 | if (reg->size) | 2157 | if (reg->size) |
2058 | serial_port_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); | 2158 | serial_port_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); |
2159 | |||
2160 | sci_clear_SCxSR(port, | ||
2161 | SCxSR_RDxF_CLEAR(port) & SCxSR_ERROR_CLEAR(port) & | ||
2162 | SCxSR_BREAK_CLEAR(port)); | ||
2163 | if (sci_getreg(port, SCLSR)->size) { | ||
2164 | status = serial_port_in(port, SCLSR); | ||
2165 | status &= ~(SCLSR_TO | SCLSR_ORER); | ||
2166 | serial_port_out(port, SCLSR, status); | ||
2167 | } | ||
2059 | } | 2168 | } |
2060 | 2169 | ||
2061 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 2170 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
@@ -2218,15 +2327,18 @@ done: | |||
2218 | 2327 | ||
2219 | sci_init_pins(port, termios->c_cflag); | 2328 | sci_init_pins(port, termios->c_cflag); |
2220 | 2329 | ||
2330 | port->status &= ~UPSTAT_AUTOCTS; | ||
2331 | s->autorts = false; | ||
2221 | reg = sci_getreg(port, SCFCR); | 2332 | reg = sci_getreg(port, SCFCR); |
2222 | if (reg->size) { | 2333 | if (reg->size) { |
2223 | unsigned short ctrl = serial_port_in(port, SCFCR); | 2334 | unsigned short ctrl = serial_port_in(port, SCFCR); |
2224 | 2335 | ||
2225 | if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) { | 2336 | if ((port->flags & UPF_HARD_FLOW) && |
2226 | if (termios->c_cflag & CRTSCTS) | 2337 | (termios->c_cflag & CRTSCTS)) { |
2227 | ctrl |= SCFCR_MCE; | 2338 | /* There is no CTS interrupt to restart the hardware */ |
2228 | else | 2339 | port->status |= UPSTAT_AUTOCTS; |
2229 | ctrl &= ~SCFCR_MCE; | 2340 | /* MCE is enabled when RTS is raised */ |
2341 | s->autorts = true; | ||
2230 | } | 2342 | } |
2231 | 2343 | ||
2232 | /* | 2344 | /* |
@@ -2300,6 +2412,9 @@ done: | |||
2300 | sci_start_rx(port); | 2412 | sci_start_rx(port); |
2301 | 2413 | ||
2302 | sci_port_disable(s); | 2414 | sci_port_disable(s); |
2415 | |||
2416 | if (UART_ENABLE_MS(port, termios->c_cflag)) | ||
2417 | sci_enable_ms(port); | ||
2303 | } | 2418 | } |
2304 | 2419 | ||
2305 | static void sci_pm(struct uart_port *port, unsigned int state, | 2420 | static void sci_pm(struct uart_port *port, unsigned int state, |
@@ -2425,6 +2540,7 @@ static struct uart_ops sci_uart_ops = { | |||
2425 | .start_tx = sci_start_tx, | 2540 | .start_tx = sci_start_tx, |
2426 | .stop_tx = sci_stop_tx, | 2541 | .stop_tx = sci_stop_tx, |
2427 | .stop_rx = sci_stop_rx, | 2542 | .stop_rx = sci_stop_rx, |
2543 | .enable_ms = sci_enable_ms, | ||
2428 | .break_ctl = sci_break_ctl, | 2544 | .break_ctl = sci_break_ctl, |
2429 | .startup = sci_startup, | 2545 | .startup = sci_startup, |
2430 | .shutdown = sci_shutdown, | 2546 | .shutdown = sci_shutdown, |
@@ -2890,6 +3006,9 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id) | |||
2890 | p->regtype = SCI_OF_REGTYPE(match->data); | 3006 | p->regtype = SCI_OF_REGTYPE(match->data); |
2891 | p->scscr = SCSCR_RE | SCSCR_TE; | 3007 | p->scscr = SCSCR_RE | SCSCR_TE; |
2892 | 3008 | ||
3009 | if (of_find_property(np, "uart-has-rtscts", NULL)) | ||
3010 | p->capabilities |= SCIx_HAVE_RTSCTS; | ||
3011 | |||
2893 | return p; | 3012 | return p; |
2894 | } | 3013 | } |
2895 | 3014 | ||
@@ -2912,6 +3031,21 @@ static int sci_probe_single(struct platform_device *dev, | |||
2912 | if (ret) | 3031 | if (ret) |
2913 | return ret; | 3032 | return ret; |
2914 | 3033 | ||
3034 | sciport->gpios = mctrl_gpio_init(&sciport->port, 0); | ||
3035 | if (IS_ERR(sciport->gpios) && PTR_ERR(sciport->gpios) != -ENOSYS) | ||
3036 | return PTR_ERR(sciport->gpios); | ||
3037 | |||
3038 | if (p->capabilities & SCIx_HAVE_RTSCTS) { | ||
3039 | if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(sciport->gpios, | ||
3040 | UART_GPIO_CTS)) || | ||
3041 | !IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(sciport->gpios, | ||
3042 | UART_GPIO_RTS))) { | ||
3043 | dev_err(&dev->dev, "Conflicting RTS/CTS config\n"); | ||
3044 | return -EINVAL; | ||
3045 | } | ||
3046 | sciport->port.flags |= UPF_HARD_FLOW; | ||
3047 | } | ||
3048 | |||
2915 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | 3049 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); |
2916 | if (ret) { | 3050 | if (ret) { |
2917 | sci_cleanup_single(sciport); | 3051 | sci_cleanup_single(sciport); |
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 7a4fa185b93e..ffa6d688c335 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
@@ -105,13 +105,16 @@ enum { | |||
105 | #define SCFCR_LOOP BIT(0) /* Loopback Test */ | 105 | #define SCFCR_LOOP BIT(0) /* Loopback Test */ |
106 | 106 | ||
107 | /* SCLSR (Line Status Register) on (H)SCIF */ | 107 | /* SCLSR (Line Status Register) on (H)SCIF */ |
108 | #define SCLSR_TO BIT(2) /* Timeout */ | ||
108 | #define SCLSR_ORER BIT(0) /* Overrun Error */ | 109 | #define SCLSR_ORER BIT(0) /* Overrun Error */ |
109 | 110 | ||
110 | /* SCSPTR (Serial Port Register), optional */ | 111 | /* SCSPTR (Serial Port Register), optional */ |
111 | #define SCSPTR_RTSIO BIT(7) /* Serial Port RTS Pin Input/Output */ | 112 | #define SCSPTR_RTSIO BIT(7) /* Serial Port RTS# Pin Input/Output */ |
112 | #define SCSPTR_RTSDT BIT(6) /* Serial Port RTS Pin Data */ | 113 | #define SCSPTR_RTSDT BIT(6) /* Serial Port RTS# Pin Data */ |
113 | #define SCSPTR_CTSIO BIT(5) /* Serial Port CTS Pin Input/Output */ | 114 | #define SCSPTR_CTSIO BIT(5) /* Serial Port CTS# Pin Input/Output */ |
114 | #define SCSPTR_CTSDT BIT(4) /* Serial Port CTS Pin Data */ | 115 | #define SCSPTR_CTSDT BIT(4) /* Serial Port CTS# Pin Data */ |
116 | #define SCSPTR_SCKIO BIT(3) /* Serial Port Clock Pin Input/Output */ | ||
117 | #define SCSPTR_SCKDT BIT(2) /* Serial Port Clock Pin Data */ | ||
115 | #define SCSPTR_SPB2IO BIT(1) /* Serial Port Break Input/Output */ | 118 | #define SCSPTR_SPB2IO BIT(1) /* Serial Port Break Input/Output */ |
116 | #define SCSPTR_SPB2DT BIT(0) /* Serial Port Break Data */ | 119 | #define SCSPTR_SPB2DT BIT(0) /* Serial Port Break Data */ |
117 | 120 | ||
@@ -119,12 +122,18 @@ enum { | |||
119 | #define HSCIF_SRE BIT(15) /* Sampling Rate Register Enable */ | 122 | #define HSCIF_SRE BIT(15) /* Sampling Rate Register Enable */ |
120 | 123 | ||
121 | /* SCPCR (Serial Port Control Register), SCIFA/SCIFB only */ | 124 | /* SCPCR (Serial Port Control Register), SCIFA/SCIFB only */ |
122 | #define SCPCR_RTSC BIT(4) /* Serial Port RTS Pin / Output Pin */ | 125 | #define SCPCR_RTSC BIT(4) /* Serial Port RTS# Pin / Output Pin */ |
123 | #define SCPCR_CTSC BIT(3) /* Serial Port CTS Pin / Input Pin */ | 126 | #define SCPCR_CTSC BIT(3) /* Serial Port CTS# Pin / Input Pin */ |
127 | #define SCPCR_SCKC BIT(2) /* Serial Port SCK Pin / Output Pin */ | ||
128 | #define SCPCR_RXDC BIT(1) /* Serial Port RXD Pin / Input Pin */ | ||
129 | #define SCPCR_TXDC BIT(0) /* Serial Port TXD Pin / Output Pin */ | ||
124 | 130 | ||
125 | /* SCPDR (Serial Port Data Register), SCIFA/SCIFB only */ | 131 | /* SCPDR (Serial Port Data Register), SCIFA/SCIFB only */ |
126 | #define SCPDR_RTSD BIT(4) /* Serial Port RTS Output Pin Data */ | 132 | #define SCPDR_RTSD BIT(4) /* Serial Port RTS# Output Pin Data */ |
127 | #define SCPDR_CTSD BIT(3) /* Serial Port CTS Input Pin Data */ | 133 | #define SCPDR_CTSD BIT(3) /* Serial Port CTS# Input Pin Data */ |
134 | #define SCPDR_SCKD BIT(2) /* Serial Port SCK Output Pin Data */ | ||
135 | #define SCPDR_RXDD BIT(1) /* Serial Port RXD Input Pin Data */ | ||
136 | #define SCPDR_TXDD BIT(0) /* Serial Port TXD Output Pin Data */ | ||
128 | 137 | ||
129 | /* | 138 | /* |
130 | * BRG Clock Select Register (Some SCIF and HSCIF) | 139 | * BRG Clock Select Register (Some SCIF and HSCIF) |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index c3a885b4d76a..43756bd9111c 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -106,7 +106,7 @@ struct sirfsoc_uart_register { | |||
106 | enum sirfsoc_uart_type uart_type; | 106 | enum sirfsoc_uart_type uart_type; |
107 | }; | 107 | }; |
108 | 108 | ||
109 | u32 uart_usp_ff_full_mask(struct uart_port *port) | 109 | static u32 uart_usp_ff_full_mask(struct uart_port *port) |
110 | { | 110 | { |
111 | u32 full_bit; | 111 | u32 full_bit; |
112 | 112 | ||
@@ -114,7 +114,7 @@ u32 uart_usp_ff_full_mask(struct uart_port *port) | |||
114 | return (1 << full_bit); | 114 | return (1 << full_bit); |
115 | } | 115 | } |
116 | 116 | ||
117 | u32 uart_usp_ff_empty_mask(struct uart_port *port) | 117 | static u32 uart_usp_ff_empty_mask(struct uart_port *port) |
118 | { | 118 | { |
119 | u32 empty_bit; | 119 | u32 empty_bit; |
120 | 120 | ||
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index b384060e3b1f..23cfc5e16b45 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/hrtimer.h> | 22 | #include <linux/hrtimer.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/module.h> | ||
25 | #include <linux/io.h> | 24 | #include <linux/io.h> |
26 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
27 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
@@ -730,22 +729,12 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
730 | return 0; | 729 | return 0; |
731 | } | 730 | } |
732 | 731 | ||
733 | static int vt8500_serial_remove(struct platform_device *pdev) | ||
734 | { | ||
735 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); | ||
736 | |||
737 | clk_disable_unprepare(vt8500_port->clk); | ||
738 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | static struct platform_driver vt8500_platform_driver = { | 732 | static struct platform_driver vt8500_platform_driver = { |
744 | .probe = vt8500_serial_probe, | 733 | .probe = vt8500_serial_probe, |
745 | .remove = vt8500_serial_remove, | ||
746 | .driver = { | 734 | .driver = { |
747 | .name = "vt8500_serial", | 735 | .name = "vt8500_serial", |
748 | .of_match_table = wmt_dt_ids, | 736 | .of_match_table = wmt_dt_ids, |
737 | .suppress_bind_attrs = true, | ||
749 | }, | 738 | }, |
750 | }; | 739 | }; |
751 | 740 | ||
@@ -764,19 +753,4 @@ static int __init vt8500_serial_init(void) | |||
764 | 753 | ||
765 | return ret; | 754 | return ret; |
766 | } | 755 | } |
767 | 756 | device_initcall(vt8500_serial_init); | |
768 | static void __exit vt8500_serial_exit(void) | ||
769 | { | ||
770 | #ifdef CONFIG_SERIAL_VT8500_CONSOLE | ||
771 | unregister_console(&vt8500_console); | ||
772 | #endif | ||
773 | platform_driver_unregister(&vt8500_platform_driver); | ||
774 | uart_unregister_driver(&vt8500_uart_driver); | ||
775 | } | ||
776 | |||
777 | module_init(vt8500_serial_init); | ||
778 | module_exit(vt8500_serial_exit); | ||
779 | |||
780 | MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>"); | ||
781 | MODULE_DESCRIPTION("Driver for vt8500 serial device"); | ||
782 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index cd46e64c4255..9ca1a4d1b66a 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -976,6 +976,23 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c) | |||
976 | } | 976 | } |
977 | #endif | 977 | #endif |
978 | 978 | ||
979 | static void cdns_uart_pm(struct uart_port *port, unsigned int state, | ||
980 | unsigned int oldstate) | ||
981 | { | ||
982 | struct cdns_uart *cdns_uart = port->private_data; | ||
983 | |||
984 | switch (state) { | ||
985 | case UART_PM_STATE_OFF: | ||
986 | clk_disable(cdns_uart->uartclk); | ||
987 | clk_disable(cdns_uart->pclk); | ||
988 | break; | ||
989 | default: | ||
990 | clk_enable(cdns_uart->pclk); | ||
991 | clk_enable(cdns_uart->uartclk); | ||
992 | break; | ||
993 | } | ||
994 | } | ||
995 | |||
979 | static struct uart_ops cdns_uart_ops = { | 996 | static struct uart_ops cdns_uart_ops = { |
980 | .set_mctrl = cdns_uart_set_mctrl, | 997 | .set_mctrl = cdns_uart_set_mctrl, |
981 | .get_mctrl = cdns_uart_get_mctrl, | 998 | .get_mctrl = cdns_uart_get_mctrl, |
@@ -987,6 +1004,7 @@ static struct uart_ops cdns_uart_ops = { | |||
987 | .set_termios = cdns_uart_set_termios, | 1004 | .set_termios = cdns_uart_set_termios, |
988 | .startup = cdns_uart_startup, | 1005 | .startup = cdns_uart_startup, |
989 | .shutdown = cdns_uart_shutdown, | 1006 | .shutdown = cdns_uart_shutdown, |
1007 | .pm = cdns_uart_pm, | ||
990 | .type = cdns_uart_type, | 1008 | .type = cdns_uart_type, |
991 | .verify_port = cdns_uart_verify_port, | 1009 | .verify_port = cdns_uart_verify_port, |
992 | .request_port = cdns_uart_request_port, | 1010 | .request_port = cdns_uart_request_port, |
@@ -1350,12 +1368,12 @@ static int cdns_uart_probe(struct platform_device *pdev) | |||
1350 | return PTR_ERR(cdns_uart_data->uartclk); | 1368 | return PTR_ERR(cdns_uart_data->uartclk); |
1351 | } | 1369 | } |
1352 | 1370 | ||
1353 | rc = clk_prepare_enable(cdns_uart_data->pclk); | 1371 | rc = clk_prepare(cdns_uart_data->pclk); |
1354 | if (rc) { | 1372 | if (rc) { |
1355 | dev_err(&pdev->dev, "Unable to enable pclk clock.\n"); | 1373 | dev_err(&pdev->dev, "Unable to enable pclk clock.\n"); |
1356 | return rc; | 1374 | return rc; |
1357 | } | 1375 | } |
1358 | rc = clk_prepare_enable(cdns_uart_data->uartclk); | 1376 | rc = clk_prepare(cdns_uart_data->uartclk); |
1359 | if (rc) { | 1377 | if (rc) { |
1360 | dev_err(&pdev->dev, "Unable to enable device clock.\n"); | 1378 | dev_err(&pdev->dev, "Unable to enable device clock.\n"); |
1361 | goto err_out_clk_dis_pclk; | 1379 | goto err_out_clk_dis_pclk; |
@@ -1422,9 +1440,9 @@ err_out_notif_unreg: | |||
1422 | &cdns_uart_data->clk_rate_change_nb); | 1440 | &cdns_uart_data->clk_rate_change_nb); |
1423 | #endif | 1441 | #endif |
1424 | err_out_clk_disable: | 1442 | err_out_clk_disable: |
1425 | clk_disable_unprepare(cdns_uart_data->uartclk); | 1443 | clk_unprepare(cdns_uart_data->uartclk); |
1426 | err_out_clk_dis_pclk: | 1444 | err_out_clk_dis_pclk: |
1427 | clk_disable_unprepare(cdns_uart_data->pclk); | 1445 | clk_unprepare(cdns_uart_data->pclk); |
1428 | 1446 | ||
1429 | return rc; | 1447 | return rc; |
1430 | } | 1448 | } |
@@ -1448,8 +1466,8 @@ static int cdns_uart_remove(struct platform_device *pdev) | |||
1448 | #endif | 1466 | #endif |
1449 | rc = uart_remove_one_port(&cdns_uart_uart_driver, port); | 1467 | rc = uart_remove_one_port(&cdns_uart_uart_driver, port); |
1450 | port->mapbase = 0; | 1468 | port->mapbase = 0; |
1451 | clk_disable_unprepare(cdns_uart_data->uartclk); | 1469 | clk_unprepare(cdns_uart_data->uartclk); |
1452 | clk_disable_unprepare(cdns_uart_data->pclk); | 1470 | clk_unprepare(cdns_uart_data->pclk); |
1453 | return rc; | 1471 | return rc; |
1454 | } | 1472 | } |
1455 | 1473 | ||
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index c8c91f0476a2..9d7ab7b66a8a 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
@@ -499,9 +499,8 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) | |||
499 | return 0; | 499 | return 0; |
500 | } | 500 | } |
501 | 501 | ||
502 | /* ui is a leftover from using a hashtable, but might be used again | 502 | /* Caller must hold the lock */ |
503 | Caller must hold the lock */ | 503 | static int con_do_clear_unimap(struct vc_data *vc) |
504 | static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui) | ||
505 | { | 504 | { |
506 | struct uni_pagedir *p, *q; | 505 | struct uni_pagedir *p, *q; |
507 | 506 | ||
@@ -524,11 +523,11 @@ static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui) | |||
524 | return 0; | 523 | return 0; |
525 | } | 524 | } |
526 | 525 | ||
527 | int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui) | 526 | int con_clear_unimap(struct vc_data *vc) |
528 | { | 527 | { |
529 | int ret; | 528 | int ret; |
530 | console_lock(); | 529 | console_lock(); |
531 | ret = con_do_clear_unimap(vc, ui); | 530 | ret = con_do_clear_unimap(vc); |
532 | console_unlock(); | 531 | console_unlock(); |
533 | return ret; | 532 | return ret; |
534 | } | 533 | } |
@@ -556,7 +555,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
556 | int j, k; | 555 | int j, k; |
557 | u16 **p1, *p2, l; | 556 | u16 **p1, *p2, l; |
558 | 557 | ||
559 | err1 = con_do_clear_unimap(vc, NULL); | 558 | err1 = con_do_clear_unimap(vc); |
560 | if (err1) { | 559 | if (err1) { |
561 | console_unlock(); | 560 | console_unlock(); |
562 | return err1; | 561 | return err1; |
@@ -677,7 +676,7 @@ int con_set_default_unimap(struct vc_data *vc) | |||
677 | 676 | ||
678 | /* The default font is always 256 characters */ | 677 | /* The default font is always 256 characters */ |
679 | 678 | ||
680 | err = con_do_clear_unimap(vc, NULL); | 679 | err = con_do_clear_unimap(vc); |
681 | if (err) | 680 | if (err) |
682 | return err; | 681 | return err; |
683 | 682 | ||
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 1e93a37e27f0..0f8caae4267d 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -567,7 +567,7 @@ static void fn_scroll_forw(struct vc_data *vc) | |||
567 | 567 | ||
568 | static void fn_scroll_back(struct vc_data *vc) | 568 | static void fn_scroll_back(struct vc_data *vc) |
569 | { | 569 | { |
570 | scrollback(vc, 0); | 570 | scrollback(vc); |
571 | } | 571 | } |
572 | 572 | ||
573 | static void fn_show_mem(struct vc_data *vc) | 573 | static void fn_show_mem(struct vc_data *vc) |
@@ -1733,16 +1733,10 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) | |||
1733 | return -EINVAL; | 1733 | return -EINVAL; |
1734 | 1734 | ||
1735 | if (ct) { | 1735 | if (ct) { |
1736 | buf = kmalloc(ct * sizeof(struct kbdiacruc), | 1736 | buf = memdup_user(a->kbdiacruc, |
1737 | GFP_KERNEL); | 1737 | ct * sizeof(struct kbdiacruc)); |
1738 | if (buf == NULL) | 1738 | if (IS_ERR(buf)) |
1739 | return -ENOMEM; | 1739 | return PTR_ERR(buf); |
1740 | |||
1741 | if (copy_from_user(buf, a->kbdiacruc, | ||
1742 | ct * sizeof(struct kbdiacruc))) { | ||
1743 | kfree(buf); | ||
1744 | return -EFAULT; | ||
1745 | } | ||
1746 | } | 1740 | } |
1747 | spin_lock_irqsave(&kbd_event_lock, flags); | 1741 | spin_lock_irqsave(&kbd_event_lock, flags); |
1748 | if (ct) | 1742 | if (ct) |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 5b0fe97c46ca..2705ca960e92 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -277,13 +277,15 @@ static void notify_update(struct vc_data *vc) | |||
277 | * Low-Level Functions | 277 | * Low-Level Functions |
278 | */ | 278 | */ |
279 | 279 | ||
280 | #define IS_FG(vc) ((vc)->vc_num == fg_console) | 280 | static inline bool con_is_fg(const struct vc_data *vc) |
281 | { | ||
282 | return vc->vc_num == fg_console; | ||
283 | } | ||
281 | 284 | ||
282 | #ifdef VT_BUF_VRAM_ONLY | 285 | static inline bool con_should_update(const struct vc_data *vc) |
283 | #define DO_UPDATE(vc) 0 | 286 | { |
284 | #else | 287 | return con_is_visible(vc) && !console_blanked; |
285 | #define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked) | 288 | } |
286 | #endif | ||
287 | 289 | ||
288 | static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed) | 290 | static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed) |
289 | { | 291 | { |
@@ -321,7 +323,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
321 | nr = b - t - 1; | 323 | nr = b - t - 1; |
322 | if (b > vc->vc_rows || t >= b || nr < 1) | 324 | if (b > vc->vc_rows || t >= b || nr < 1) |
323 | return; | 325 | return; |
324 | if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr)) | 326 | if (con_is_visible(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr)) |
325 | return; | 327 | return; |
326 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); | 328 | d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
327 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); | 329 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); |
@@ -339,7 +341,7 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
339 | nr = b - t - 1; | 341 | nr = b - t - 1; |
340 | if (b > vc->vc_rows || t >= b || nr < 1) | 342 | if (b > vc->vc_rows || t >= b || nr < 1) |
341 | return; | 343 | return; |
342 | if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr)) | 344 | if (con_is_visible(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr)) |
343 | return; | 345 | return; |
344 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); | 346 | s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); |
345 | step = vc->vc_cols * nr; | 347 | step = vc->vc_cols * nr; |
@@ -349,7 +351,6 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr) | |||
349 | 351 | ||
350 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) | 352 | static void do_update_region(struct vc_data *vc, unsigned long start, int count) |
351 | { | 353 | { |
352 | #ifndef VT_BUF_VRAM_ONLY | ||
353 | unsigned int xx, yy, offset; | 354 | unsigned int xx, yy, offset; |
354 | u16 *p; | 355 | u16 *p; |
355 | 356 | ||
@@ -390,14 +391,13 @@ static void do_update_region(struct vc_data *vc, unsigned long start, int count) | |||
390 | start = vc->vc_sw->con_getxy(vc, start, NULL, NULL); | 391 | start = vc->vc_sw->con_getxy(vc, start, NULL, NULL); |
391 | } | 392 | } |
392 | } | 393 | } |
393 | #endif | ||
394 | } | 394 | } |
395 | 395 | ||
396 | void update_region(struct vc_data *vc, unsigned long start, int count) | 396 | void update_region(struct vc_data *vc, unsigned long start, int count) |
397 | { | 397 | { |
398 | WARN_CONSOLE_UNLOCKED(); | 398 | WARN_CONSOLE_UNLOCKED(); |
399 | 399 | ||
400 | if (DO_UPDATE(vc)) { | 400 | if (con_should_update(vc)) { |
401 | hide_cursor(vc); | 401 | hide_cursor(vc); |
402 | do_update_region(vc, start, count); | 402 | do_update_region(vc, start, count); |
403 | set_cursor(vc); | 403 | set_cursor(vc); |
@@ -413,7 +413,6 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, | |||
413 | return vc->vc_sw->con_build_attr(vc, _color, _intensity, | 413 | return vc->vc_sw->con_build_attr(vc, _color, _intensity, |
414 | _blink, _underline, _reverse, _italic); | 414 | _blink, _underline, _reverse, _italic); |
415 | 415 | ||
416 | #ifndef VT_BUF_VRAM_ONLY | ||
417 | /* | 416 | /* |
418 | * ++roman: I completely changed the attribute format for monochrome | 417 | * ++roman: I completely changed the attribute format for monochrome |
419 | * mode (!can_do_color). The formerly used MDA (monochrome display | 418 | * mode (!can_do_color). The formerly used MDA (monochrome display |
@@ -448,9 +447,6 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, | |||
448 | a <<= 1; | 447 | a <<= 1; |
449 | return a; | 448 | return a; |
450 | } | 449 | } |
451 | #else | ||
452 | return 0; | ||
453 | #endif | ||
454 | } | 450 | } |
455 | 451 | ||
456 | static void update_attr(struct vc_data *vc) | 452 | static void update_attr(struct vc_data *vc) |
@@ -470,10 +466,9 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed) | |||
470 | 466 | ||
471 | count /= 2; | 467 | count /= 2; |
472 | p = screenpos(vc, offset, viewed); | 468 | p = screenpos(vc, offset, viewed); |
473 | if (vc->vc_sw->con_invert_region) | 469 | if (vc->vc_sw->con_invert_region) { |
474 | vc->vc_sw->con_invert_region(vc, p, count); | 470 | vc->vc_sw->con_invert_region(vc, p, count); |
475 | #ifndef VT_BUF_VRAM_ONLY | 471 | } else { |
476 | else { | ||
477 | u16 *q = p; | 472 | u16 *q = p; |
478 | int cnt = count; | 473 | int cnt = count; |
479 | u16 a; | 474 | u16 a; |
@@ -501,8 +496,8 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed) | |||
501 | } | 496 | } |
502 | } | 497 | } |
503 | } | 498 | } |
504 | #endif | 499 | |
505 | if (DO_UPDATE(vc)) | 500 | if (con_should_update(vc)) |
506 | do_update_region(vc, (unsigned long) p, count); | 501 | do_update_region(vc, (unsigned long) p, count); |
507 | notify_update(vc); | 502 | notify_update(vc); |
508 | } | 503 | } |
@@ -519,7 +514,7 @@ void complement_pos(struct vc_data *vc, int offset) | |||
519 | if (old_offset != -1 && old_offset >= 0 && | 514 | if (old_offset != -1 && old_offset >= 0 && |
520 | old_offset < vc->vc_screenbuf_size) { | 515 | old_offset < vc->vc_screenbuf_size) { |
521 | scr_writew(old, screenpos(vc, old_offset, 1)); | 516 | scr_writew(old, screenpos(vc, old_offset, 1)); |
522 | if (DO_UPDATE(vc)) | 517 | if (con_should_update(vc)) |
523 | vc->vc_sw->con_putc(vc, old, oldy, oldx); | 518 | vc->vc_sw->con_putc(vc, old, oldy, oldx); |
524 | notify_update(vc); | 519 | notify_update(vc); |
525 | } | 520 | } |
@@ -534,7 +529,7 @@ void complement_pos(struct vc_data *vc, int offset) | |||
534 | old = scr_readw(p); | 529 | old = scr_readw(p); |
535 | new = old ^ vc->vc_complement_mask; | 530 | new = old ^ vc->vc_complement_mask; |
536 | scr_writew(new, p); | 531 | scr_writew(new, p); |
537 | if (DO_UPDATE(vc)) { | 532 | if (con_should_update(vc)) { |
538 | oldx = (offset >> 1) % vc->vc_cols; | 533 | oldx = (offset >> 1) % vc->vc_cols; |
539 | oldy = (offset >> 1) / vc->vc_cols; | 534 | oldy = (offset >> 1) / vc->vc_cols; |
540 | vc->vc_sw->con_putc(vc, new, oldy, oldx); | 535 | vc->vc_sw->con_putc(vc, new, oldy, oldx); |
@@ -550,7 +545,7 @@ static void insert_char(struct vc_data *vc, unsigned int nr) | |||
550 | scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2); | 545 | scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2); |
551 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); | 546 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); |
552 | vc->vc_need_wrap = 0; | 547 | vc->vc_need_wrap = 0; |
553 | if (DO_UPDATE(vc)) | 548 | if (con_should_update(vc)) |
554 | do_update_region(vc, (unsigned long) p, | 549 | do_update_region(vc, (unsigned long) p, |
555 | vc->vc_cols - vc->vc_x); | 550 | vc->vc_cols - vc->vc_x); |
556 | } | 551 | } |
@@ -563,7 +558,7 @@ static void delete_char(struct vc_data *vc, unsigned int nr) | |||
563 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, | 558 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, |
564 | nr * 2); | 559 | nr * 2); |
565 | vc->vc_need_wrap = 0; | 560 | vc->vc_need_wrap = 0; |
566 | if (DO_UPDATE(vc)) | 561 | if (con_should_update(vc)) |
567 | do_update_region(vc, (unsigned long) p, | 562 | do_update_region(vc, (unsigned long) p, |
568 | vc->vc_cols - vc->vc_x); | 563 | vc->vc_cols - vc->vc_x); |
569 | } | 564 | } |
@@ -583,7 +578,7 @@ static void add_softcursor(struct vc_data *vc) | |||
583 | if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000; | 578 | if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000; |
584 | if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700; | 579 | if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700; |
585 | scr_writew(i, (u16 *) vc->vc_pos); | 580 | scr_writew(i, (u16 *) vc->vc_pos); |
586 | if (DO_UPDATE(vc)) | 581 | if (con_should_update(vc)) |
587 | vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x); | 582 | vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x); |
588 | } | 583 | } |
589 | 584 | ||
@@ -591,7 +586,7 @@ static void hide_softcursor(struct vc_data *vc) | |||
591 | { | 586 | { |
592 | if (softcursor_original != -1) { | 587 | if (softcursor_original != -1) { |
593 | scr_writew(softcursor_original, (u16 *)vc->vc_pos); | 588 | scr_writew(softcursor_original, (u16 *)vc->vc_pos); |
594 | if (DO_UPDATE(vc)) | 589 | if (con_should_update(vc)) |
595 | vc->vc_sw->con_putc(vc, softcursor_original, | 590 | vc->vc_sw->con_putc(vc, softcursor_original, |
596 | vc->vc_y, vc->vc_x); | 591 | vc->vc_y, vc->vc_x); |
597 | softcursor_original = -1; | 592 | softcursor_original = -1; |
@@ -608,8 +603,7 @@ static void hide_cursor(struct vc_data *vc) | |||
608 | 603 | ||
609 | static void set_cursor(struct vc_data *vc) | 604 | static void set_cursor(struct vc_data *vc) |
610 | { | 605 | { |
611 | if (!IS_FG(vc) || console_blanked || | 606 | if (!con_is_fg(vc) || console_blanked || vc->vc_mode == KD_GRAPHICS) |
612 | vc->vc_mode == KD_GRAPHICS) | ||
613 | return; | 607 | return; |
614 | if (vc->vc_deccm) { | 608 | if (vc->vc_deccm) { |
615 | if (vc == sel_cons) | 609 | if (vc == sel_cons) |
@@ -625,7 +619,7 @@ static void set_origin(struct vc_data *vc) | |||
625 | { | 619 | { |
626 | WARN_CONSOLE_UNLOCKED(); | 620 | WARN_CONSOLE_UNLOCKED(); |
627 | 621 | ||
628 | if (!CON_IS_VISIBLE(vc) || | 622 | if (!con_is_visible(vc) || |
629 | !vc->vc_sw->con_set_origin || | 623 | !vc->vc_sw->con_set_origin || |
630 | !vc->vc_sw->con_set_origin(vc)) | 624 | !vc->vc_sw->con_set_origin(vc)) |
631 | vc->vc_origin = (unsigned long)vc->vc_screenbuf; | 625 | vc->vc_origin = (unsigned long)vc->vc_screenbuf; |
@@ -673,12 +667,12 @@ void redraw_screen(struct vc_data *vc, int is_switch) | |||
673 | struct vc_data *old_vc = vc_cons[fg_console].d; | 667 | struct vc_data *old_vc = vc_cons[fg_console].d; |
674 | if (old_vc == vc) | 668 | if (old_vc == vc) |
675 | return; | 669 | return; |
676 | if (!CON_IS_VISIBLE(vc)) | 670 | if (!con_is_visible(vc)) |
677 | redraw = 1; | 671 | redraw = 1; |
678 | *vc->vc_display_fg = vc; | 672 | *vc->vc_display_fg = vc; |
679 | fg_console = vc->vc_num; | 673 | fg_console = vc->vc_num; |
680 | hide_cursor(old_vc); | 674 | hide_cursor(old_vc); |
681 | if (!CON_IS_VISIBLE(old_vc)) { | 675 | if (!con_is_visible(old_vc)) { |
682 | save_screen(old_vc); | 676 | save_screen(old_vc); |
683 | set_origin(old_vc); | 677 | set_origin(old_vc); |
684 | } | 678 | } |
@@ -954,7 +948,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
954 | tty_do_resize(tty, &ws); | 948 | tty_do_resize(tty, &ws); |
955 | } | 949 | } |
956 | 950 | ||
957 | if (CON_IS_VISIBLE(vc)) | 951 | if (con_is_visible(vc)) |
958 | update_screen(vc); | 952 | update_screen(vc); |
959 | vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num); | 953 | vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num); |
960 | return err; | 954 | return err; |
@@ -1103,11 +1097,9 @@ static void gotoxay(struct vc_data *vc, int new_x, int new_y) | |||
1103 | gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y); | 1097 | gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y); |
1104 | } | 1098 | } |
1105 | 1099 | ||
1106 | void scrollback(struct vc_data *vc, int lines) | 1100 | void scrollback(struct vc_data *vc) |
1107 | { | 1101 | { |
1108 | if (!lines) | 1102 | scrolldelta(-(vc->vc_rows / 2)); |
1109 | lines = vc->vc_rows / 2; | ||
1110 | scrolldelta(-lines); | ||
1111 | } | 1103 | } |
1112 | 1104 | ||
1113 | void scrollfront(struct vc_data *vc, int lines) | 1105 | void scrollfront(struct vc_data *vc, int lines) |
@@ -1186,7 +1178,7 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
1186 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, | 1178 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, |
1187 | vc->vc_screenbuf_size >> 1); | 1179 | vc->vc_screenbuf_size >> 1); |
1188 | set_origin(vc); | 1180 | set_origin(vc); |
1189 | if (CON_IS_VISIBLE(vc)) | 1181 | if (con_is_visible(vc)) |
1190 | update_screen(vc); | 1182 | update_screen(vc); |
1191 | /* fall through */ | 1183 | /* fall through */ |
1192 | case 2: /* erase whole display */ | 1184 | case 2: /* erase whole display */ |
@@ -1197,7 +1189,7 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
1197 | return; | 1189 | return; |
1198 | } | 1190 | } |
1199 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1191 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
1200 | if (DO_UPDATE(vc)) | 1192 | if (con_should_update(vc)) |
1201 | do_update_region(vc, (unsigned long) start, count); | 1193 | do_update_region(vc, (unsigned long) start, count); |
1202 | vc->vc_need_wrap = 0; | 1194 | vc->vc_need_wrap = 0; |
1203 | } | 1195 | } |
@@ -1225,7 +1217,7 @@ static void csi_K(struct vc_data *vc, int vpar) | |||
1225 | } | 1217 | } |
1226 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1218 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
1227 | vc->vc_need_wrap = 0; | 1219 | vc->vc_need_wrap = 0; |
1228 | if (DO_UPDATE(vc)) | 1220 | if (con_should_update(vc)) |
1229 | do_update_region(vc, (unsigned long) start, count); | 1221 | do_update_region(vc, (unsigned long) start, count); |
1230 | } | 1222 | } |
1231 | 1223 | ||
@@ -1238,7 +1230,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi | |||
1238 | count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar; | 1230 | count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar; |
1239 | 1231 | ||
1240 | scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count); | 1232 | scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count); |
1241 | if (DO_UPDATE(vc)) | 1233 | if (con_should_update(vc)) |
1242 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count); | 1234 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count); |
1243 | vc->vc_need_wrap = 0; | 1235 | vc->vc_need_wrap = 0; |
1244 | } | 1236 | } |
@@ -1255,48 +1247,87 @@ static void default_attr(struct vc_data *vc) | |||
1255 | 1247 | ||
1256 | struct rgb { u8 r; u8 g; u8 b; }; | 1248 | struct rgb { u8 r; u8 g; u8 b; }; |
1257 | 1249 | ||
1258 | static struct rgb rgb_from_256(int i) | 1250 | static void rgb_from_256(int i, struct rgb *c) |
1259 | { | 1251 | { |
1260 | struct rgb c; | ||
1261 | if (i < 8) { /* Standard colours. */ | 1252 | if (i < 8) { /* Standard colours. */ |
1262 | c.r = i&1 ? 0xaa : 0x00; | 1253 | c->r = i&1 ? 0xaa : 0x00; |
1263 | c.g = i&2 ? 0xaa : 0x00; | 1254 | c->g = i&2 ? 0xaa : 0x00; |
1264 | c.b = i&4 ? 0xaa : 0x00; | 1255 | c->b = i&4 ? 0xaa : 0x00; |
1265 | } else if (i < 16) { | 1256 | } else if (i < 16) { |
1266 | c.r = i&1 ? 0xff : 0x55; | 1257 | c->r = i&1 ? 0xff : 0x55; |
1267 | c.g = i&2 ? 0xff : 0x55; | 1258 | c->g = i&2 ? 0xff : 0x55; |
1268 | c.b = i&4 ? 0xff : 0x55; | 1259 | c->b = i&4 ? 0xff : 0x55; |
1269 | } else if (i < 232) { /* 6x6x6 colour cube. */ | 1260 | } else if (i < 232) { /* 6x6x6 colour cube. */ |
1270 | c.r = (i - 16) / 36 * 85 / 2; | 1261 | c->r = (i - 16) / 36 * 85 / 2; |
1271 | c.g = (i - 16) / 6 % 6 * 85 / 2; | 1262 | c->g = (i - 16) / 6 % 6 * 85 / 2; |
1272 | c.b = (i - 16) % 6 * 85 / 2; | 1263 | c->b = (i - 16) % 6 * 85 / 2; |
1273 | } else /* Grayscale ramp. */ | 1264 | } else /* Grayscale ramp. */ |
1274 | c.r = c.g = c.b = i * 10 - 2312; | 1265 | c->r = c->g = c->b = i * 10 - 2312; |
1275 | return c; | ||
1276 | } | 1266 | } |
1277 | 1267 | ||
1278 | static void rgb_foreground(struct vc_data *vc, struct rgb c) | 1268 | static void rgb_foreground(struct vc_data *vc, const struct rgb *c) |
1279 | { | 1269 | { |
1280 | u8 hue, max = c.r; | 1270 | u8 hue = 0, max = max3(c->r, c->g, c->b); |
1281 | if (c.g > max) | 1271 | |
1282 | max = c.g; | 1272 | if (c->r > max / 2) |
1283 | if (c.b > max) | 1273 | hue |= 4; |
1284 | max = c.b; | 1274 | if (c->g > max / 2) |
1285 | hue = (c.r > max/2 ? 4 : 0) | 1275 | hue |= 2; |
1286 | | (c.g > max/2 ? 2 : 0) | 1276 | if (c->b > max / 2) |
1287 | | (c.b > max/2 ? 1 : 0); | 1277 | hue |= 1; |
1288 | if (hue == 7 && max <= 0x55) | 1278 | |
1289 | hue = 0, vc->vc_intensity = 2; | 1279 | if (hue == 7 && max <= 0x55) { |
1280 | hue = 0; | ||
1281 | vc->vc_intensity = 2; | ||
1282 | } else if (max > 0xaa) | ||
1283 | vc->vc_intensity = 2; | ||
1290 | else | 1284 | else |
1291 | vc->vc_intensity = (max > 0xaa) + 1; | 1285 | vc->vc_intensity = 1; |
1286 | |||
1292 | vc->vc_color = (vc->vc_color & 0xf0) | hue; | 1287 | vc->vc_color = (vc->vc_color & 0xf0) | hue; |
1293 | } | 1288 | } |
1294 | 1289 | ||
1295 | static void rgb_background(struct vc_data *vc, struct rgb c) | 1290 | static void rgb_background(struct vc_data *vc, const struct rgb *c) |
1296 | { | 1291 | { |
1297 | /* For backgrounds, err on the dark side. */ | 1292 | /* For backgrounds, err on the dark side. */ |
1298 | vc->vc_color = (vc->vc_color & 0x0f) | 1293 | vc->vc_color = (vc->vc_color & 0x0f) |
1299 | | (c.r&0x80) >> 1 | (c.g&0x80) >> 2 | (c.b&0x80) >> 3; | 1294 | | (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3; |
1295 | } | ||
1296 | |||
1297 | /* | ||
1298 | * ITU T.416 Higher colour modes. They break the usual properties of SGR codes | ||
1299 | * and thus need to be detected and ignored by hand. Strictly speaking, that | ||
1300 | * standard also wants : rather than ; as separators, contrary to ECMA-48, but | ||
1301 | * no one produces such codes and almost no one accepts them. | ||
1302 | * | ||
1303 | * Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in | ||
1304 | * supporting them. | ||
1305 | */ | ||
1306 | static int vc_t416_color(struct vc_data *vc, int i, | ||
1307 | void(*set_color)(struct vc_data *vc, const struct rgb *c)) | ||
1308 | { | ||
1309 | struct rgb c; | ||
1310 | |||
1311 | i++; | ||
1312 | if (i > vc->vc_npar) | ||
1313 | return i; | ||
1314 | |||
1315 | if (vc->vc_par[i] == 5 && i < vc->vc_npar) { | ||
1316 | /* 256 colours -- ubiquitous */ | ||
1317 | i++; | ||
1318 | rgb_from_256(vc->vc_par[i], &c); | ||
1319 | } else if (vc->vc_par[i] == 2 && i <= vc->vc_npar + 3) { | ||
1320 | /* 24 bit -- extremely rare */ | ||
1321 | c.r = vc->vc_par[i + 1]; | ||
1322 | c.g = vc->vc_par[i + 2]; | ||
1323 | c.b = vc->vc_par[i + 3]; | ||
1324 | i += 3; | ||
1325 | } else | ||
1326 | return i; | ||
1327 | |||
1328 | set_color(vc, &c); | ||
1329 | |||
1330 | return i; | ||
1300 | } | 1331 | } |
1301 | 1332 | ||
1302 | /* console_lock is held */ | 1333 | /* console_lock is held */ |
@@ -1306,135 +1337,91 @@ static void csi_m(struct vc_data *vc) | |||
1306 | 1337 | ||
1307 | for (i = 0; i <= vc->vc_npar; i++) | 1338 | for (i = 0; i <= vc->vc_npar; i++) |
1308 | switch (vc->vc_par[i]) { | 1339 | switch (vc->vc_par[i]) { |
1309 | case 0: /* all attributes off */ | 1340 | case 0: /* all attributes off */ |
1310 | default_attr(vc); | 1341 | default_attr(vc); |
1311 | break; | 1342 | break; |
1312 | case 1: | 1343 | case 1: |
1313 | vc->vc_intensity = 2; | 1344 | vc->vc_intensity = 2; |
1314 | break; | 1345 | break; |
1315 | case 2: | 1346 | case 2: |
1316 | vc->vc_intensity = 0; | 1347 | vc->vc_intensity = 0; |
1317 | break; | 1348 | break; |
1318 | case 3: | 1349 | case 3: |
1319 | vc->vc_italic = 1; | 1350 | vc->vc_italic = 1; |
1320 | break; | 1351 | break; |
1321 | case 4: | 1352 | case 4: |
1322 | vc->vc_underline = 1; | 1353 | vc->vc_underline = 1; |
1323 | break; | 1354 | break; |
1324 | case 5: | 1355 | case 5: |
1325 | vc->vc_blink = 1; | 1356 | vc->vc_blink = 1; |
1326 | break; | 1357 | break; |
1327 | case 7: | 1358 | case 7: |
1328 | vc->vc_reverse = 1; | 1359 | vc->vc_reverse = 1; |
1329 | break; | 1360 | break; |
1330 | case 10: /* ANSI X3.64-1979 (SCO-ish?) | 1361 | case 10: /* ANSI X3.64-1979 (SCO-ish?) |
1331 | * Select primary font, don't display | 1362 | * Select primary font, don't display control chars if |
1332 | * control chars if defined, don't set | 1363 | * defined, don't set bit 8 on output. |
1333 | * bit 8 on output. | 1364 | */ |
1334 | */ | 1365 | vc->vc_translate = set_translate(vc->vc_charset == 0 |
1335 | vc->vc_translate = set_translate(vc->vc_charset == 0 | 1366 | ? vc->vc_G0_charset |
1336 | ? vc->vc_G0_charset | 1367 | : vc->vc_G1_charset, vc); |
1337 | : vc->vc_G1_charset, vc); | 1368 | vc->vc_disp_ctrl = 0; |
1338 | vc->vc_disp_ctrl = 0; | 1369 | vc->vc_toggle_meta = 0; |
1339 | vc->vc_toggle_meta = 0; | 1370 | break; |
1340 | break; | 1371 | case 11: /* ANSI X3.64-1979 (SCO-ish?) |
1341 | case 11: /* ANSI X3.64-1979 (SCO-ish?) | 1372 | * Select first alternate font, lets chars < 32 be |
1342 | * Select first alternate font, lets | 1373 | * displayed as ROM chars. |
1343 | * chars < 32 be displayed as ROM chars. | 1374 | */ |
1344 | */ | 1375 | vc->vc_translate = set_translate(IBMPC_MAP, vc); |
1345 | vc->vc_translate = set_translate(IBMPC_MAP, vc); | 1376 | vc->vc_disp_ctrl = 1; |
1346 | vc->vc_disp_ctrl = 1; | 1377 | vc->vc_toggle_meta = 0; |
1347 | vc->vc_toggle_meta = 0; | 1378 | break; |
1348 | break; | 1379 | case 12: /* ANSI X3.64-1979 (SCO-ish?) |
1349 | case 12: /* ANSI X3.64-1979 (SCO-ish?) | 1380 | * Select second alternate font, toggle high bit |
1350 | * Select second alternate font, toggle | 1381 | * before displaying as ROM char. |
1351 | * high bit before displaying as ROM char. | 1382 | */ |
1352 | */ | 1383 | vc->vc_translate = set_translate(IBMPC_MAP, vc); |
1353 | vc->vc_translate = set_translate(IBMPC_MAP, vc); | 1384 | vc->vc_disp_ctrl = 1; |
1354 | vc->vc_disp_ctrl = 1; | 1385 | vc->vc_toggle_meta = 1; |
1355 | vc->vc_toggle_meta = 1; | 1386 | break; |
1356 | break; | 1387 | case 21: |
1357 | case 21: | 1388 | case 22: |
1358 | case 22: | 1389 | vc->vc_intensity = 1; |
1359 | vc->vc_intensity = 1; | 1390 | break; |
1360 | break; | 1391 | case 23: |
1361 | case 23: | 1392 | vc->vc_italic = 0; |
1362 | vc->vc_italic = 0; | 1393 | break; |
1363 | break; | 1394 | case 24: |
1364 | case 24: | 1395 | vc->vc_underline = 0; |
1365 | vc->vc_underline = 0; | 1396 | break; |
1366 | break; | 1397 | case 25: |
1367 | case 25: | 1398 | vc->vc_blink = 0; |
1368 | vc->vc_blink = 0; | 1399 | break; |
1369 | break; | 1400 | case 27: |
1370 | case 27: | 1401 | vc->vc_reverse = 0; |
1371 | vc->vc_reverse = 0; | 1402 | break; |
1372 | break; | 1403 | case 38: |
1373 | case 38: /* ITU T.416 | 1404 | i = vc_t416_color(vc, i, rgb_foreground); |
1374 | * Higher colour modes. | 1405 | break; |
1375 | * They break the usual properties of SGR codes | 1406 | case 48: |
1376 | * and thus need to be detected and ignored by | 1407 | i = vc_t416_color(vc, i, rgb_background); |
1377 | * hand. Strictly speaking, that standard also | 1408 | break; |
1378 | * wants : rather than ; as separators, contrary | 1409 | case 39: |
1379 | * to ECMA-48, but no one produces such codes | 1410 | vc->vc_color = (vc->vc_def_color & 0x0f) | |
1380 | * and almost no one accepts them. | 1411 | (vc->vc_color & 0xf0); |
1381 | */ | 1412 | break; |
1382 | i++; | 1413 | case 49: |
1383 | if (i > vc->vc_npar) | 1414 | vc->vc_color = (vc->vc_def_color & 0xf0) | |
1384 | break; | 1415 | (vc->vc_color & 0x0f); |
1385 | if (vc->vc_par[i] == 5 && /* 256 colours */ | 1416 | break; |
1386 | i < vc->vc_npar) { /* ubiquitous */ | 1417 | default: |
1387 | i++; | 1418 | if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37) |
1388 | rgb_foreground(vc, | 1419 | vc->vc_color = color_table[vc->vc_par[i] - 30] |
1389 | rgb_from_256(vc->vc_par[i])); | 1420 | | (vc->vc_color & 0xf0); |
1390 | } else if (vc->vc_par[i] == 2 && /* 24 bit */ | 1421 | else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47) |
1391 | i <= vc->vc_npar + 3) {/* extremely rare */ | 1422 | vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4) |
1392 | struct rgb c = { | 1423 | | (vc->vc_color & 0x0f); |
1393 | .r = vc->vc_par[i + 1], | 1424 | break; |
1394 | .g = vc->vc_par[i + 2], | ||
1395 | .b = vc->vc_par[i + 3], | ||
1396 | }; | ||
1397 | rgb_foreground(vc, c); | ||
1398 | i += 3; | ||
1399 | } | ||
1400 | /* Subcommands 3 (CMY) and 4 (CMYK) are so insane | ||
1401 | * there's no point in supporting them. | ||
1402 | */ | ||
1403 | break; | ||
1404 | case 48: | ||
1405 | i++; | ||
1406 | if (i > vc->vc_npar) | ||
1407 | break; | ||
1408 | if (vc->vc_par[i] == 5 && /* 256 colours */ | ||
1409 | i < vc->vc_npar) { | ||
1410 | i++; | ||
1411 | rgb_background(vc, | ||
1412 | rgb_from_256(vc->vc_par[i])); | ||
1413 | } else if (vc->vc_par[i] == 2 && /* 24 bit */ | ||
1414 | i <= vc->vc_npar + 3) { | ||
1415 | struct rgb c = { | ||
1416 | .r = vc->vc_par[i + 1], | ||
1417 | .g = vc->vc_par[i + 2], | ||
1418 | .b = vc->vc_par[i + 3], | ||
1419 | }; | ||
1420 | rgb_background(vc, c); | ||
1421 | i += 3; | ||
1422 | } | ||
1423 | break; | ||
1424 | case 39: | ||
1425 | vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0); | ||
1426 | break; | ||
1427 | case 49: | ||
1428 | vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f); | ||
1429 | break; | ||
1430 | default: | ||
1431 | if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37) | ||
1432 | vc->vc_color = color_table[vc->vc_par[i] - 30] | ||
1433 | | (vc->vc_color & 0xf0); | ||
1434 | else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47) | ||
1435 | vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4) | ||
1436 | | (vc->vc_color & 0x0f); | ||
1437 | break; | ||
1438 | } | 1425 | } |
1439 | update_attr(vc); | 1426 | update_attr(vc); |
1440 | } | 1427 | } |
@@ -1496,7 +1483,6 @@ static void set_mode(struct vc_data *vc, int on_off) | |||
1496 | clr_kbd(vc, decckm); | 1483 | clr_kbd(vc, decckm); |
1497 | break; | 1484 | break; |
1498 | case 3: /* 80/132 mode switch unimplemented */ | 1485 | case 3: /* 80/132 mode switch unimplemented */ |
1499 | vc->vc_deccolm = on_off; | ||
1500 | #if 0 | 1486 | #if 0 |
1501 | vc_resize(deccolm ? 132 : 80, vc->vc_rows); | 1487 | vc_resize(deccolm ? 132 : 80, vc->vc_rows); |
1502 | /* this alone does not suffice; some user mode | 1488 | /* this alone does not suffice; some user mode |
@@ -2178,18 +2164,20 @@ static int is_double_width(uint32_t ucs) | |||
2178 | return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1); | 2164 | return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1); |
2179 | } | 2165 | } |
2180 | 2166 | ||
2167 | static void con_flush(struct vc_data *vc, unsigned long draw_from, | ||
2168 | unsigned long draw_to, int *draw_x) | ||
2169 | { | ||
2170 | if (*draw_x < 0) | ||
2171 | return; | ||
2172 | |||
2173 | vc->vc_sw->con_putcs(vc, (u16 *)draw_from, | ||
2174 | (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, *draw_x); | ||
2175 | *draw_x = -1; | ||
2176 | } | ||
2177 | |||
2181 | /* acquires console_lock */ | 2178 | /* acquires console_lock */ |
2182 | static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) | 2179 | static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) |
2183 | { | 2180 | { |
2184 | #ifdef VT_BUF_VRAM_ONLY | ||
2185 | #define FLUSH do { } while(0); | ||
2186 | #else | ||
2187 | #define FLUSH if (draw_x >= 0) { \ | ||
2188 | vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \ | ||
2189 | draw_x = -1; \ | ||
2190 | } | ||
2191 | #endif | ||
2192 | |||
2193 | int c, tc, ok, n = 0, draw_x = -1; | 2181 | int c, tc, ok, n = 0, draw_x = -1; |
2194 | unsigned int currcons; | 2182 | unsigned int currcons; |
2195 | unsigned long draw_from = 0, draw_to = 0; | 2183 | unsigned long draw_from = 0, draw_to = 0; |
@@ -2226,7 +2214,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2226 | charmask = himask ? 0x1ff : 0xff; | 2214 | charmask = himask ? 0x1ff : 0xff; |
2227 | 2215 | ||
2228 | /* undraw cursor first */ | 2216 | /* undraw cursor first */ |
2229 | if (IS_FG(vc)) | 2217 | if (con_is_fg(vc)) |
2230 | hide_cursor(vc); | 2218 | hide_cursor(vc); |
2231 | 2219 | ||
2232 | param.vc = vc; | 2220 | param.vc = vc; |
@@ -2381,12 +2369,13 @@ rescan_last_byte: | |||
2381 | } else { | 2369 | } else { |
2382 | vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4); | 2370 | vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4); |
2383 | } | 2371 | } |
2384 | FLUSH | 2372 | con_flush(vc, draw_from, draw_to, &draw_x); |
2385 | } | 2373 | } |
2386 | 2374 | ||
2387 | while (1) { | 2375 | while (1) { |
2388 | if (vc->vc_need_wrap || vc->vc_decim) | 2376 | if (vc->vc_need_wrap || vc->vc_decim) |
2389 | FLUSH | 2377 | con_flush(vc, draw_from, draw_to, |
2378 | &draw_x); | ||
2390 | if (vc->vc_need_wrap) { | 2379 | if (vc->vc_need_wrap) { |
2391 | cr(vc); | 2380 | cr(vc); |
2392 | lf(vc); | 2381 | lf(vc); |
@@ -2397,7 +2386,7 @@ rescan_last_byte: | |||
2397 | ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : | 2386 | ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : |
2398 | (vc_attr << 8) + tc, | 2387 | (vc_attr << 8) + tc, |
2399 | (u16 *) vc->vc_pos); | 2388 | (u16 *) vc->vc_pos); |
2400 | if (DO_UPDATE(vc) && draw_x < 0) { | 2389 | if (con_should_update(vc) && draw_x < 0) { |
2401 | draw_x = vc->vc_x; | 2390 | draw_x = vc->vc_x; |
2402 | draw_from = vc->vc_pos; | 2391 | draw_from = vc->vc_pos; |
2403 | } | 2392 | } |
@@ -2416,9 +2405,8 @@ rescan_last_byte: | |||
2416 | } | 2405 | } |
2417 | notify_write(vc, c); | 2406 | notify_write(vc, c); |
2418 | 2407 | ||
2419 | if (inverse) { | 2408 | if (inverse) |
2420 | FLUSH | 2409 | con_flush(vc, draw_from, draw_to, &draw_x); |
2421 | } | ||
2422 | 2410 | ||
2423 | if (rescan) { | 2411 | if (rescan) { |
2424 | rescan = 0; | 2412 | rescan = 0; |
@@ -2429,15 +2417,14 @@ rescan_last_byte: | |||
2429 | } | 2417 | } |
2430 | continue; | 2418 | continue; |
2431 | } | 2419 | } |
2432 | FLUSH | 2420 | con_flush(vc, draw_from, draw_to, &draw_x); |
2433 | do_con_trol(tty, vc, orig); | 2421 | do_con_trol(tty, vc, orig); |
2434 | } | 2422 | } |
2435 | FLUSH | 2423 | con_flush(vc, draw_from, draw_to, &draw_x); |
2436 | console_conditional_schedule(); | 2424 | console_conditional_schedule(); |
2437 | console_unlock(); | 2425 | console_unlock(); |
2438 | notify_update(vc); | 2426 | notify_update(vc); |
2439 | return n; | 2427 | return n; |
2440 | #undef FLUSH | ||
2441 | } | 2428 | } |
2442 | 2429 | ||
2443 | /* | 2430 | /* |
@@ -2471,7 +2458,7 @@ static void console_callback(struct work_struct *ignored) | |||
2471 | if (scrollback_delta) { | 2458 | if (scrollback_delta) { |
2472 | struct vc_data *vc = vc_cons[fg_console].d; | 2459 | struct vc_data *vc = vc_cons[fg_console].d; |
2473 | clear_selection(); | 2460 | clear_selection(); |
2474 | if (vc->vc_mode == KD_TEXT) | 2461 | if (vc->vc_mode == KD_TEXT && vc->vc_sw->con_scrolldelta) |
2475 | vc->vc_sw->con_scrolldelta(vc, scrollback_delta); | 2462 | vc->vc_sw->con_scrolldelta(vc, scrollback_delta); |
2476 | scrollback_delta = 0; | 2463 | scrollback_delta = 0; |
2477 | } | 2464 | } |
@@ -2583,7 +2570,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2583 | goto quit; | 2570 | goto quit; |
2584 | 2571 | ||
2585 | /* undraw cursor first */ | 2572 | /* undraw cursor first */ |
2586 | if (IS_FG(vc)) | 2573 | if (con_is_fg(vc)) |
2587 | hide_cursor(vc); | 2574 | hide_cursor(vc); |
2588 | 2575 | ||
2589 | start = (ushort *)vc->vc_pos; | 2576 | start = (ushort *)vc->vc_pos; |
@@ -2594,7 +2581,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2594 | c = *b++; | 2581 | c = *b++; |
2595 | if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) { | 2582 | if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) { |
2596 | if (cnt > 0) { | 2583 | if (cnt > 0) { |
2597 | if (CON_IS_VISIBLE(vc)) | 2584 | if (con_is_visible(vc)) |
2598 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); | 2585 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); |
2599 | vc->vc_x += cnt; | 2586 | vc->vc_x += cnt; |
2600 | if (vc->vc_need_wrap) | 2587 | if (vc->vc_need_wrap) |
@@ -2626,7 +2613,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2626 | myx++; | 2613 | myx++; |
2627 | } | 2614 | } |
2628 | if (cnt > 0) { | 2615 | if (cnt > 0) { |
2629 | if (CON_IS_VISIBLE(vc)) | 2616 | if (con_is_visible(vc)) |
2630 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); | 2617 | vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x); |
2631 | vc->vc_x += cnt; | 2618 | vc->vc_x += cnt; |
2632 | if (vc->vc_x == vc->vc_cols) { | 2619 | if (vc->vc_x == vc->vc_cols) { |
@@ -3173,7 +3160,7 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last, | |||
3173 | 3160 | ||
3174 | j = i; | 3161 | j = i; |
3175 | 3162 | ||
3176 | if (CON_IS_VISIBLE(vc)) { | 3163 | if (con_is_visible(vc)) { |
3177 | k = i; | 3164 | k = i; |
3178 | save_screen(vc); | 3165 | save_screen(vc); |
3179 | } | 3166 | } |
@@ -3981,7 +3968,7 @@ static void set_palette(struct vc_data *vc) | |||
3981 | { | 3968 | { |
3982 | WARN_CONSOLE_UNLOCKED(); | 3969 | WARN_CONSOLE_UNLOCKED(); |
3983 | 3970 | ||
3984 | if (vc->vc_mode != KD_GRAPHICS) | 3971 | if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_set_palette) |
3985 | vc->vc_sw->con_set_palette(vc, color_table); | 3972 | vc->vc_sw->con_set_palette(vc, color_table); |
3986 | } | 3973 | } |
3987 | 3974 | ||
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 97d5a74558a3..f62c598810ff 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
@@ -1006,16 +1006,10 @@ int vt_ioctl(struct tty_struct *tty, | |||
1006 | break; | 1006 | break; |
1007 | 1007 | ||
1008 | case PIO_UNIMAPCLR: | 1008 | case PIO_UNIMAPCLR: |
1009 | { struct unimapinit ui; | ||
1010 | if (!perm) | 1009 | if (!perm) |
1011 | return -EPERM; | 1010 | return -EPERM; |
1012 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); | 1011 | con_clear_unimap(vc); |
1013 | if (ret) | ||
1014 | ret = -EFAULT; | ||
1015 | else | ||
1016 | con_clear_unimap(vc, &ui); | ||
1017 | break; | 1012 | break; |
1018 | } | ||
1019 | 1013 | ||
1020 | case PIO_UNIMAP: | 1014 | case PIO_UNIMAP: |
1021 | case GIO_UNIMAP: | 1015 | case GIO_UNIMAP: |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 15666ad7c772..02abfcdfbf7b 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -1285,18 +1285,22 @@ int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data) | |||
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, | 1287 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, |
1288 | u32 dest, int length, size_t *bytes_written) | 1288 | u32 dest, int length) |
1289 | { | 1289 | { |
1290 | size_t dummy; | ||
1291 | |||
1290 | return sisusb_write_mem_bulk(sisusb, dest, src, length, | 1292 | return sisusb_write_mem_bulk(sisusb, dest, src, length, |
1291 | NULL, 0, bytes_written); | 1293 | NULL, 0, &dummy); |
1292 | } | 1294 | } |
1293 | 1295 | ||
1294 | #ifdef SISUSBENDIANTEST | 1296 | #ifdef SISUSBENDIANTEST |
1295 | int sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest, | 1297 | static int sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest, |
1296 | u32 src, int length, size_t *bytes_written) | 1298 | u32 src, int length) |
1297 | { | 1299 | { |
1300 | size_t dummy; | ||
1301 | |||
1298 | return sisusb_read_mem_bulk(sisusb, src, dest, length, | 1302 | return sisusb_read_mem_bulk(sisusb, src, dest, length, |
1299 | NULL, bytes_written); | 1303 | NULL, &dummy); |
1300 | } | 1304 | } |
1301 | #endif | 1305 | #endif |
1302 | #endif | 1306 | #endif |
@@ -1306,16 +1310,14 @@ static void sisusb_testreadwrite(struct sisusb_usb_data *sisusb) | |||
1306 | { | 1310 | { |
1307 | static char srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; | 1311 | static char srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; |
1308 | char destbuffer[10]; | 1312 | char destbuffer[10]; |
1309 | size_t dummy; | ||
1310 | int i, j; | 1313 | int i, j; |
1311 | 1314 | ||
1312 | sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy); | 1315 | sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7); |
1313 | 1316 | ||
1314 | for (i = 1; i <= 7; i++) { | 1317 | for (i = 1; i <= 7; i++) { |
1315 | dev_dbg(&sisusb->sisusb_dev->dev, | 1318 | dev_dbg(&sisusb->sisusb_dev->dev, |
1316 | "sisusb: rwtest %d bytes\n", i); | 1319 | "sisusb: rwtest %d bytes\n", i); |
1317 | sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, | 1320 | sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i); |
1318 | i, &dummy); | ||
1319 | for (j = 0; j < i; j++) { | 1321 | for (j = 0; j < i; j++) { |
1320 | dev_dbg(&sisusb->sisusb_dev->dev, | 1322 | dev_dbg(&sisusb->sisusb_dev->dev, |
1321 | "rwtest read[%d] = %x\n", | 1323 | "rwtest read[%d] = %x\n", |
@@ -2276,7 +2278,6 @@ int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
2276 | const struct font_desc *myfont; | 2278 | const struct font_desc *myfont; |
2277 | u8 *tempbuf; | 2279 | u8 *tempbuf; |
2278 | u16 *tempbufb; | 2280 | u16 *tempbufb; |
2279 | size_t written; | ||
2280 | static const char bootstring[] = | 2281 | static const char bootstring[] = |
2281 | "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; | 2282 | "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; |
2282 | static const char bootlogo[] = "(o_ //\\ V_/_"; | 2283 | static const char bootlogo[] = "(o_ //\\ V_/_"; |
@@ -2343,18 +2344,15 @@ int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
2343 | *(tempbufb++) = 0x0700 | bootstring[i++]; | 2344 | *(tempbufb++) = 0x0700 | bootstring[i++]; |
2344 | 2345 | ||
2345 | ret |= sisusb_copy_memory(sisusb, tempbuf, | 2346 | ret |= sisusb_copy_memory(sisusb, tempbuf, |
2346 | sisusb->vrambase, 8192, &written); | 2347 | sisusb->vrambase, 8192); |
2347 | 2348 | ||
2348 | vfree(tempbuf); | 2349 | vfree(tempbuf); |
2349 | 2350 | ||
2350 | } | 2351 | } |
2351 | 2352 | ||
2352 | } else if (sisusb->scrbuf) { | 2353 | } else if (sisusb->scrbuf) { |
2353 | |||
2354 | ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf, | 2354 | ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf, |
2355 | sisusb->vrambase, sisusb->scrbuf_size, | 2355 | sisusb->vrambase, sisusb->scrbuf_size); |
2356 | &written); | ||
2357 | |||
2358 | } | 2356 | } |
2359 | 2357 | ||
2360 | if (sisusb->sisusb_cursor_size_from >= 0 && | 2358 | if (sisusb->sisusb_cursor_size_from >= 0 && |
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index afa853209f1d..460cebf322e3 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -370,7 +370,6 @@ static void | |||
370 | sisusbcon_putc(struct vc_data *c, int ch, int y, int x) | 370 | sisusbcon_putc(struct vc_data *c, int ch, int y, int x) |
371 | { | 371 | { |
372 | struct sisusb_usb_data *sisusb; | 372 | struct sisusb_usb_data *sisusb; |
373 | ssize_t written; | ||
374 | 373 | ||
375 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); | 374 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
376 | if (!sisusb) | 375 | if (!sisusb) |
@@ -384,7 +383,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) | |||
384 | 383 | ||
385 | 384 | ||
386 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), | 385 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), |
387 | (long)SISUSB_HADDR(x, y), 2, &written); | 386 | (long)SISUSB_HADDR(x, y), 2); |
388 | 387 | ||
389 | mutex_unlock(&sisusb->lock); | 388 | mutex_unlock(&sisusb->lock); |
390 | } | 389 | } |
@@ -395,7 +394,6 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, | |||
395 | int count, int y, int x) | 394 | int count, int y, int x) |
396 | { | 395 | { |
397 | struct sisusb_usb_data *sisusb; | 396 | struct sisusb_usb_data *sisusb; |
398 | ssize_t written; | ||
399 | u16 *dest; | 397 | u16 *dest; |
400 | int i; | 398 | int i; |
401 | 399 | ||
@@ -420,7 +418,7 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, | |||
420 | } | 418 | } |
421 | 419 | ||
422 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), | 420 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), |
423 | (long)SISUSB_HADDR(x, y), count * 2, &written); | 421 | (long)SISUSB_HADDR(x, y), count * 2); |
424 | 422 | ||
425 | mutex_unlock(&sisusb->lock); | 423 | mutex_unlock(&sisusb->lock); |
426 | } | 424 | } |
@@ -431,7 +429,6 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) | |||
431 | { | 429 | { |
432 | struct sisusb_usb_data *sisusb; | 430 | struct sisusb_usb_data *sisusb; |
433 | u16 eattr = c->vc_video_erase_char; | 431 | u16 eattr = c->vc_video_erase_char; |
434 | ssize_t written; | ||
435 | int i, length, cols; | 432 | int i, length, cols; |
436 | u16 *dest; | 433 | u16 *dest; |
437 | 434 | ||
@@ -475,41 +472,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) | |||
475 | 472 | ||
476 | 473 | ||
477 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), | 474 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), |
478 | (long)SISUSB_HADDR(x, y), length, &written); | 475 | (long)SISUSB_HADDR(x, y), length); |
479 | |||
480 | mutex_unlock(&sisusb->lock); | ||
481 | } | ||
482 | |||
483 | /* Interface routine */ | ||
484 | static void | ||
485 | sisusbcon_bmove(struct vc_data *c, int sy, int sx, | ||
486 | int dy, int dx, int height, int width) | ||
487 | { | ||
488 | struct sisusb_usb_data *sisusb; | ||
489 | ssize_t written; | ||
490 | int cols, length; | ||
491 | |||
492 | if (width <= 0 || height <= 0) | ||
493 | return; | ||
494 | |||
495 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); | ||
496 | if (!sisusb) | ||
497 | return; | ||
498 | |||
499 | /* sisusb->lock is down */ | ||
500 | |||
501 | cols = sisusb->sisusb_num_columns; | ||
502 | |||
503 | if (sisusb_is_inactive(c, sisusb)) { | ||
504 | mutex_unlock(&sisusb->lock); | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | length = ((height * cols) - dx - (cols - width - dx)) * 2; | ||
509 | |||
510 | |||
511 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy), | ||
512 | (long)SISUSB_HADDR(dx, dy), length, &written); | ||
513 | 476 | ||
514 | mutex_unlock(&sisusb->lock); | 477 | mutex_unlock(&sisusb->lock); |
515 | } | 478 | } |
@@ -519,7 +482,6 @@ static int | |||
519 | sisusbcon_switch(struct vc_data *c) | 482 | sisusbcon_switch(struct vc_data *c) |
520 | { | 483 | { |
521 | struct sisusb_usb_data *sisusb; | 484 | struct sisusb_usb_data *sisusb; |
522 | ssize_t written; | ||
523 | int length; | 485 | int length; |
524 | 486 | ||
525 | /* Returnvalue 0 means we have fully restored screen, | 487 | /* Returnvalue 0 means we have fully restored screen, |
@@ -559,7 +521,7 @@ sisusbcon_switch(struct vc_data *c) | |||
559 | 521 | ||
560 | sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, | 522 | sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, |
561 | (long)SISUSB_HADDR(0, 0), | 523 | (long)SISUSB_HADDR(0, 0), |
562 | length, &written); | 524 | length); |
563 | 525 | ||
564 | mutex_unlock(&sisusb->lock); | 526 | mutex_unlock(&sisusb->lock); |
565 | 527 | ||
@@ -600,7 +562,7 @@ sisusbcon_save_screen(struct vc_data *c) | |||
600 | } | 562 | } |
601 | 563 | ||
602 | /* interface routine */ | 564 | /* interface routine */ |
603 | static int | 565 | static void |
604 | sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) | 566 | sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) |
605 | { | 567 | { |
606 | struct sisusb_usb_data *sisusb; | 568 | struct sisusb_usb_data *sisusb; |
@@ -608,18 +570,18 @@ sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) | |||
608 | 570 | ||
609 | /* Return value not used by vt */ | 571 | /* Return value not used by vt */ |
610 | 572 | ||
611 | if (!CON_IS_VISIBLE(c)) | 573 | if (!con_is_visible(c)) |
612 | return -EINVAL; | 574 | return; |
613 | 575 | ||
614 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); | 576 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
615 | if (!sisusb) | 577 | if (!sisusb) |
616 | return -EINVAL; | 578 | return; |
617 | 579 | ||
618 | /* sisusb->lock is down */ | 580 | /* sisusb->lock is down */ |
619 | 581 | ||
620 | if (sisusb_is_inactive(c, sisusb)) { | 582 | if (sisusb_is_inactive(c, sisusb)) { |
621 | mutex_unlock(&sisusb->lock); | 583 | mutex_unlock(&sisusb->lock); |
622 | return -EINVAL; | 584 | return; |
623 | } | 585 | } |
624 | 586 | ||
625 | for (i = j = 0; i < 16; i++) { | 587 | for (i = j = 0; i < 16; i++) { |
@@ -634,8 +596,6 @@ sisusbcon_set_palette(struct vc_data *c, const unsigned char *table) | |||
634 | } | 596 | } |
635 | 597 | ||
636 | mutex_unlock(&sisusb->lock); | 598 | mutex_unlock(&sisusb->lock); |
637 | |||
638 | return 0; | ||
639 | } | 599 | } |
640 | 600 | ||
641 | /* interface routine */ | 601 | /* interface routine */ |
@@ -644,7 +604,6 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) | |||
644 | { | 604 | { |
645 | struct sisusb_usb_data *sisusb; | 605 | struct sisusb_usb_data *sisusb; |
646 | u8 sr1, cr17, pmreg, cr63; | 606 | u8 sr1, cr17, pmreg, cr63; |
647 | ssize_t written; | ||
648 | int ret = 0; | 607 | int ret = 0; |
649 | 608 | ||
650 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); | 609 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
@@ -672,7 +631,7 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) | |||
672 | (unsigned char *)c->vc_origin, | 631 | (unsigned char *)c->vc_origin, |
673 | (u32)(sisusb->vrambase + | 632 | (u32)(sisusb->vrambase + |
674 | (c->vc_origin - sisusb->scrbuf)), | 633 | (c->vc_origin - sisusb->scrbuf)), |
675 | c->vc_screenbuf_size, &written); | 634 | c->vc_screenbuf_size); |
676 | sisusb->con_blanked = 1; | 635 | sisusb->con_blanked = 1; |
677 | ret = 1; | 636 | ret = 1; |
678 | break; | 637 | break; |
@@ -723,24 +682,22 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) | |||
723 | } | 682 | } |
724 | 683 | ||
725 | /* interface routine */ | 684 | /* interface routine */ |
726 | static int | 685 | static void |
727 | sisusbcon_scrolldelta(struct vc_data *c, int lines) | 686 | sisusbcon_scrolldelta(struct vc_data *c, int lines) |
728 | { | 687 | { |
729 | struct sisusb_usb_data *sisusb; | 688 | struct sisusb_usb_data *sisusb; |
730 | int margin = c->vc_size_row * 4; | 689 | int margin = c->vc_size_row * 4; |
731 | int ul, we, p, st; | 690 | int ul, we, p, st; |
732 | 691 | ||
733 | /* The return value does not seem to be used */ | ||
734 | |||
735 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); | 692 | sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); |
736 | if (!sisusb) | 693 | if (!sisusb) |
737 | return 0; | 694 | return; |
738 | 695 | ||
739 | /* sisusb->lock is down */ | 696 | /* sisusb->lock is down */ |
740 | 697 | ||
741 | if (sisusb_is_inactive(c, sisusb)) { | 698 | if (sisusb_is_inactive(c, sisusb)) { |
742 | mutex_unlock(&sisusb->lock); | 699 | mutex_unlock(&sisusb->lock); |
743 | return 0; | 700 | return; |
744 | } | 701 | } |
745 | 702 | ||
746 | if (!lines) /* Turn scrollback off */ | 703 | if (!lines) /* Turn scrollback off */ |
@@ -780,8 +737,6 @@ sisusbcon_scrolldelta(struct vc_data *c, int lines) | |||
780 | sisusbcon_set_start_address(sisusb, c); | 737 | sisusbcon_set_start_address(sisusb, c); |
781 | 738 | ||
782 | mutex_unlock(&sisusb->lock); | 739 | mutex_unlock(&sisusb->lock); |
783 | |||
784 | return 1; | ||
785 | } | 740 | } |
786 | 741 | ||
787 | /* Interface routine */ | 742 | /* Interface routine */ |
@@ -860,7 +815,6 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, | |||
860 | int cols = sisusb->sisusb_num_columns; | 815 | int cols = sisusb->sisusb_num_columns; |
861 | int length = ((b - t) * cols) * 2; | 816 | int length = ((b - t) * cols) * 2; |
862 | u16 eattr = c->vc_video_erase_char; | 817 | u16 eattr = c->vc_video_erase_char; |
863 | ssize_t written; | ||
864 | 818 | ||
865 | /* sisusb->lock is down */ | 819 | /* sisusb->lock is down */ |
866 | 820 | ||
@@ -890,7 +844,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, | |||
890 | } | 844 | } |
891 | 845 | ||
892 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), | 846 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), |
893 | (long)SISUSB_HADDR(0, t), length, &written); | 847 | (long)SISUSB_HADDR(0, t), length); |
894 | 848 | ||
895 | mutex_unlock(&sisusb->lock); | 849 | mutex_unlock(&sisusb->lock); |
896 | 850 | ||
@@ -903,7 +857,6 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines) | |||
903 | { | 857 | { |
904 | struct sisusb_usb_data *sisusb; | 858 | struct sisusb_usb_data *sisusb; |
905 | u16 eattr = c->vc_video_erase_char; | 859 | u16 eattr = c->vc_video_erase_char; |
906 | ssize_t written; | ||
907 | int copyall = 0; | 860 | int copyall = 0; |
908 | unsigned long oldorigin; | 861 | unsigned long oldorigin; |
909 | unsigned int delta = lines * c->vc_size_row; | 862 | unsigned int delta = lines * c->vc_size_row; |
@@ -996,18 +949,18 @@ sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines) | |||
996 | sisusb_copy_memory(sisusb, | 949 | sisusb_copy_memory(sisusb, |
997 | (char *)c->vc_origin, | 950 | (char *)c->vc_origin, |
998 | (u32)(sisusb->vrambase + originoffset), | 951 | (u32)(sisusb->vrambase + originoffset), |
999 | c->vc_screenbuf_size, &written); | 952 | c->vc_screenbuf_size); |
1000 | else if (dir == SM_UP) | 953 | else if (dir == SM_UP) |
1001 | sisusb_copy_memory(sisusb, | 954 | sisusb_copy_memory(sisusb, |
1002 | (char *)c->vc_origin + c->vc_screenbuf_size - delta, | 955 | (char *)c->vc_origin + c->vc_screenbuf_size - delta, |
1003 | (u32)sisusb->vrambase + originoffset + | 956 | (u32)sisusb->vrambase + originoffset + |
1004 | c->vc_screenbuf_size - delta, | 957 | c->vc_screenbuf_size - delta, |
1005 | delta, &written); | 958 | delta); |
1006 | else | 959 | else |
1007 | sisusb_copy_memory(sisusb, | 960 | sisusb_copy_memory(sisusb, |
1008 | (char *)c->vc_origin, | 961 | (char *)c->vc_origin, |
1009 | (u32)(sisusb->vrambase + originoffset), | 962 | (u32)(sisusb->vrambase + originoffset), |
1010 | delta, &written); | 963 | delta); |
1011 | 964 | ||
1012 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; | 965 | c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; |
1013 | c->vc_visible_origin = c->vc_origin; | 966 | c->vc_visible_origin = c->vc_origin; |
@@ -1273,7 +1226,7 @@ sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, | |||
1273 | struct vc_data *vc = vc_cons[i].d; | 1226 | struct vc_data *vc = vc_cons[i].d; |
1274 | 1227 | ||
1275 | if (vc && vc->vc_sw == &sisusb_con) { | 1228 | if (vc && vc->vc_sw == &sisusb_con) { |
1276 | if (CON_IS_VISIBLE(vc)) { | 1229 | if (con_is_visible(vc)) { |
1277 | vc->vc_sw->con_cursor(vc, CM_DRAW); | 1230 | vc->vc_sw->con_cursor(vc, CM_DRAW); |
1278 | } | 1231 | } |
1279 | vc->vc_font.height = fh; | 1232 | vc->vc_font.height = fh; |
@@ -1385,7 +1338,6 @@ static const struct consw sisusb_con = { | |||
1385 | .con_putcs = sisusbcon_putcs, | 1338 | .con_putcs = sisusbcon_putcs, |
1386 | .con_cursor = sisusbcon_cursor, | 1339 | .con_cursor = sisusbcon_cursor, |
1387 | .con_scroll = sisusbcon_scroll, | 1340 | .con_scroll = sisusbcon_scroll, |
1388 | .con_bmove = sisusbcon_bmove, | ||
1389 | .con_switch = sisusbcon_switch, | 1341 | .con_switch = sisusbcon_switch, |
1390 | .con_blank = sisusbcon_blank, | 1342 | .con_blank = sisusbcon_blank, |
1391 | .con_font_set = sisusbcon_font_set, | 1343 | .con_font_set = sisusbcon_font_set, |
@@ -1433,15 +1385,12 @@ static const struct consw sisusb_dummy_con = { | |||
1433 | .con_putcs = SISUSBCONDUMMY, | 1385 | .con_putcs = SISUSBCONDUMMY, |
1434 | .con_cursor = SISUSBCONDUMMY, | 1386 | .con_cursor = SISUSBCONDUMMY, |
1435 | .con_scroll = SISUSBCONDUMMY, | 1387 | .con_scroll = SISUSBCONDUMMY, |
1436 | .con_bmove = SISUSBCONDUMMY, | ||
1437 | .con_switch = SISUSBCONDUMMY, | 1388 | .con_switch = SISUSBCONDUMMY, |
1438 | .con_blank = SISUSBCONDUMMY, | 1389 | .con_blank = SISUSBCONDUMMY, |
1439 | .con_font_set = SISUSBCONDUMMY, | 1390 | .con_font_set = SISUSBCONDUMMY, |
1440 | .con_font_get = SISUSBCONDUMMY, | 1391 | .con_font_get = SISUSBCONDUMMY, |
1441 | .con_font_default = SISUSBCONDUMMY, | 1392 | .con_font_default = SISUSBCONDUMMY, |
1442 | .con_font_copy = SISUSBCONDUMMY, | 1393 | .con_font_copy = SISUSBCONDUMMY, |
1443 | .con_set_palette = SISUSBCONDUMMY, | ||
1444 | .con_scrolldelta = SISUSBCONDUMMY, | ||
1445 | }; | 1394 | }; |
1446 | 1395 | ||
1447 | int | 1396 | int |
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h index c46ce42d4489..e79a616f0d26 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.h +++ b/drivers/usb/misc/sisusbvga/sisusb_init.h | |||
@@ -828,7 +828,7 @@ void sisusb_delete(struct kref *kref); | |||
828 | int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); | 828 | int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); |
829 | int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data); | 829 | int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data); |
830 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, | 830 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, |
831 | u32 dest, int length, size_t * bytes_written); | 831 | u32 dest, int length); |
832 | int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); | 832 | int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); |
833 | int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, | 833 | int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, |
834 | u8 * arg, int cmapsz, int ch512, int dorecalc, | 834 | u8 * arg, int cmapsz, int ch512, int dorecalc, |
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 0efc52f11ad0..9269d5685239 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c | |||
@@ -64,14 +64,11 @@ const struct consw dummy_con = { | |||
64 | .con_putcs = DUMMY, | 64 | .con_putcs = DUMMY, |
65 | .con_cursor = DUMMY, | 65 | .con_cursor = DUMMY, |
66 | .con_scroll = DUMMY, | 66 | .con_scroll = DUMMY, |
67 | .con_bmove = DUMMY, | ||
68 | .con_switch = DUMMY, | 67 | .con_switch = DUMMY, |
69 | .con_blank = DUMMY, | 68 | .con_blank = DUMMY, |
70 | .con_font_set = DUMMY, | 69 | .con_font_set = DUMMY, |
71 | .con_font_get = DUMMY, | 70 | .con_font_get = DUMMY, |
72 | .con_font_default = DUMMY, | 71 | .con_font_default = DUMMY, |
73 | .con_font_copy = DUMMY, | 72 | .con_font_copy = DUMMY, |
74 | .con_set_palette = DUMMY, | ||
75 | .con_scrolldelta = DUMMY, | ||
76 | }; | 73 | }; |
77 | EXPORT_SYMBOL_GPL(dummy_con); | 74 | EXPORT_SYMBOL_GPL(dummy_con); |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index afd3301ac40c..b87f5cfdaea5 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -170,8 +170,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, | |||
170 | int height, int width); | 170 | int height, int width); |
171 | static int fbcon_switch(struct vc_data *vc); | 171 | static int fbcon_switch(struct vc_data *vc); |
172 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); | 172 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); |
173 | static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table); | 173 | static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table); |
174 | static int fbcon_scrolldelta(struct vc_data *vc, int lines); | ||
175 | 174 | ||
176 | /* | 175 | /* |
177 | * Internal routines | 176 | * Internal routines |
@@ -381,7 +380,7 @@ static void fb_flashcursor(struct work_struct *work) | |||
381 | if (ops && ops->currcon != -1) | 380 | if (ops && ops->currcon != -1) |
382 | vc = vc_cons[ops->currcon].d; | 381 | vc = vc_cons[ops->currcon].d; |
383 | 382 | ||
384 | if (!vc || !CON_IS_VISIBLE(vc) || | 383 | if (!vc || !con_is_visible(vc) || |
385 | registered_fb[con2fb_map[vc->vc_num]] != info || | 384 | registered_fb[con2fb_map[vc->vc_num]] != info || |
386 | vc->vc_deccm != 1) { | 385 | vc->vc_deccm != 1) { |
387 | console_unlock(); | 386 | console_unlock(); |
@@ -619,7 +618,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, | |||
619 | erase, | 618 | erase, |
620 | vc->vc_size_row * logo_lines); | 619 | vc->vc_size_row * logo_lines); |
621 | 620 | ||
622 | if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { | 621 | if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) { |
623 | fbcon_clear_margins(vc, 0); | 622 | fbcon_clear_margins(vc, 0); |
624 | update_screen(vc); | 623 | update_screen(vc); |
625 | } | 624 | } |
@@ -1113,7 +1112,7 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1113 | * | 1112 | * |
1114 | * We need to do it in fbcon_init() to prevent screen corruption. | 1113 | * We need to do it in fbcon_init() to prevent screen corruption. |
1115 | */ | 1114 | */ |
1116 | if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) { | 1115 | if (con_is_visible(vc) && vc->vc_mode == KD_TEXT) { |
1117 | if (info->fbops->fb_set_par && | 1116 | if (info->fbops->fb_set_par && |
1118 | !(ops->flags & FBCON_FLAGS_INIT)) { | 1117 | !(ops->flags & FBCON_FLAGS_INIT)) { |
1119 | ret = info->fbops->fb_set_par(info); | 1118 | ret = info->fbops->fb_set_par(info); |
@@ -1193,7 +1192,7 @@ static void fbcon_deinit(struct vc_data *vc) | |||
1193 | if (!ops) | 1192 | if (!ops) |
1194 | goto finished; | 1193 | goto finished; |
1195 | 1194 | ||
1196 | if (CON_IS_VISIBLE(vc)) | 1195 | if (con_is_visible(vc)) |
1197 | fbcon_del_cursor_timer(info); | 1196 | fbcon_del_cursor_timer(info); |
1198 | 1197 | ||
1199 | ops->flags &= ~FBCON_FLAGS_INIT; | 1198 | ops->flags &= ~FBCON_FLAGS_INIT; |
@@ -1398,7 +1397,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, | |||
1398 | rows /= vc->vc_font.height; | 1397 | rows /= vc->vc_font.height; |
1399 | vc_resize(vc, cols, rows); | 1398 | vc_resize(vc, cols, rows); |
1400 | 1399 | ||
1401 | if (CON_IS_VISIBLE(vc)) { | 1400 | if (con_is_visible(vc)) { |
1402 | update_screen(vc); | 1401 | update_screen(vc); |
1403 | if (softback_buf) | 1402 | if (softback_buf) |
1404 | fbcon_update_softback(vc); | 1403 | fbcon_update_softback(vc); |
@@ -2146,7 +2145,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, | |||
2146 | return -EINVAL; | 2145 | return -EINVAL; |
2147 | 2146 | ||
2148 | DPRINTK("resize now %ix%i\n", var.xres, var.yres); | 2147 | DPRINTK("resize now %ix%i\n", var.xres, var.yres); |
2149 | if (CON_IS_VISIBLE(vc)) { | 2148 | if (con_is_visible(vc)) { |
2150 | var.activate = FB_ACTIVATE_NOW | | 2149 | var.activate = FB_ACTIVATE_NOW | |
2151 | FB_ACTIVATE_FORCE; | 2150 | FB_ACTIVATE_FORCE; |
2152 | fb_set_var(info, &var); | 2151 | fb_set_var(info, &var); |
@@ -2449,7 +2448,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, | |||
2449 | int cnt; | 2448 | int cnt; |
2450 | char *old_data = NULL; | 2449 | char *old_data = NULL; |
2451 | 2450 | ||
2452 | if (CON_IS_VISIBLE(vc) && softback_lines) | 2451 | if (con_is_visible(vc) && softback_lines) |
2453 | fbcon_set_origin(vc); | 2452 | fbcon_set_origin(vc); |
2454 | 2453 | ||
2455 | resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); | 2454 | resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); |
@@ -2530,9 +2529,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, | |||
2530 | cols /= w; | 2529 | cols /= w; |
2531 | rows /= h; | 2530 | rows /= h; |
2532 | vc_resize(vc, cols, rows); | 2531 | vc_resize(vc, cols, rows); |
2533 | if (CON_IS_VISIBLE(vc) && softback_buf) | 2532 | if (con_is_visible(vc) && softback_buf) |
2534 | fbcon_update_softback(vc); | 2533 | fbcon_update_softback(vc); |
2535 | } else if (CON_IS_VISIBLE(vc) | 2534 | } else if (con_is_visible(vc) |
2536 | && vc->vc_mode == KD_TEXT) { | 2535 | && vc->vc_mode == KD_TEXT) { |
2537 | fbcon_clear_margins(vc, 0); | 2536 | fbcon_clear_margins(vc, 0); |
2538 | update_screen(vc); | 2537 | update_screen(vc); |
@@ -2652,17 +2651,17 @@ static struct fb_cmap palette_cmap = { | |||
2652 | 0, 16, palette_red, palette_green, palette_blue, NULL | 2651 | 0, 16, palette_red, palette_green, palette_blue, NULL |
2653 | }; | 2652 | }; |
2654 | 2653 | ||
2655 | static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table) | 2654 | static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table) |
2656 | { | 2655 | { |
2657 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 2656 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
2658 | int i, j, k, depth; | 2657 | int i, j, k, depth; |
2659 | u8 val; | 2658 | u8 val; |
2660 | 2659 | ||
2661 | if (fbcon_is_inactive(vc, info)) | 2660 | if (fbcon_is_inactive(vc, info)) |
2662 | return -EINVAL; | 2661 | return; |
2663 | 2662 | ||
2664 | if (!CON_IS_VISIBLE(vc)) | 2663 | if (!con_is_visible(vc)) |
2665 | return 0; | 2664 | return; |
2666 | 2665 | ||
2667 | depth = fb_get_color_depth(&info->var, &info->fix); | 2666 | depth = fb_get_color_depth(&info->var, &info->fix); |
2668 | if (depth > 3) { | 2667 | if (depth > 3) { |
@@ -2684,7 +2683,7 @@ static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table) | |||
2684 | } else | 2683 | } else |
2685 | fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); | 2684 | fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); |
2686 | 2685 | ||
2687 | return fb_set_cmap(&palette_cmap, info); | 2686 | fb_set_cmap(&palette_cmap, info); |
2688 | } | 2687 | } |
2689 | 2688 | ||
2690 | static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) | 2689 | static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) |
@@ -2765,7 +2764,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt) | |||
2765 | } | 2764 | } |
2766 | } | 2765 | } |
2767 | 2766 | ||
2768 | static int fbcon_scrolldelta(struct vc_data *vc, int lines) | 2767 | static void fbcon_scrolldelta(struct vc_data *vc, int lines) |
2769 | { | 2768 | { |
2770 | struct fb_info *info = registered_fb[con2fb_map[fg_console]]; | 2769 | struct fb_info *info = registered_fb[con2fb_map[fg_console]]; |
2771 | struct fbcon_ops *ops = info->fbcon_par; | 2770 | struct fbcon_ops *ops = info->fbcon_par; |
@@ -2774,9 +2773,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2774 | 2773 | ||
2775 | if (softback_top) { | 2774 | if (softback_top) { |
2776 | if (vc->vc_num != fg_console) | 2775 | if (vc->vc_num != fg_console) |
2777 | return 0; | 2776 | return; |
2778 | if (vc->vc_mode != KD_TEXT || !lines) | 2777 | if (vc->vc_mode != KD_TEXT || !lines) |
2779 | return 0; | 2778 | return; |
2780 | if (logo_shown >= 0) { | 2779 | if (logo_shown >= 0) { |
2781 | struct vc_data *conp2 = vc_cons[logo_shown].d; | 2780 | struct vc_data *conp2 = vc_cons[logo_shown].d; |
2782 | 2781 | ||
@@ -2809,11 +2808,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2809 | fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); | 2808 | fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); |
2810 | fbcon_redraw_softback(vc, disp, lines); | 2809 | fbcon_redraw_softback(vc, disp, lines); |
2811 | fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); | 2810 | fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); |
2812 | return 0; | 2811 | return; |
2813 | } | 2812 | } |
2814 | 2813 | ||
2815 | if (!scrollback_phys_max) | 2814 | if (!scrollback_phys_max) |
2816 | return -ENOSYS; | 2815 | return; |
2817 | 2816 | ||
2818 | scrollback_old = scrollback_current; | 2817 | scrollback_old = scrollback_current; |
2819 | scrollback_current -= lines; | 2818 | scrollback_current -= lines; |
@@ -2822,10 +2821,10 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2822 | else if (scrollback_current > scrollback_max) | 2821 | else if (scrollback_current > scrollback_max) |
2823 | scrollback_current = scrollback_max; | 2822 | scrollback_current = scrollback_max; |
2824 | if (scrollback_current == scrollback_old) | 2823 | if (scrollback_current == scrollback_old) |
2825 | return 0; | 2824 | return; |
2826 | 2825 | ||
2827 | if (fbcon_is_inactive(vc, info)) | 2826 | if (fbcon_is_inactive(vc, info)) |
2828 | return 0; | 2827 | return; |
2829 | 2828 | ||
2830 | fbcon_cursor(vc, CM_ERASE); | 2829 | fbcon_cursor(vc, CM_ERASE); |
2831 | 2830 | ||
@@ -2852,7 +2851,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2852 | 2851 | ||
2853 | if (!scrollback_current) | 2852 | if (!scrollback_current) |
2854 | fbcon_cursor(vc, CM_DRAW); | 2853 | fbcon_cursor(vc, CM_DRAW); |
2855 | return 0; | ||
2856 | } | 2854 | } |
2857 | 2855 | ||
2858 | static int fbcon_set_origin(struct vc_data *vc) | 2856 | static int fbcon_set_origin(struct vc_data *vc) |
@@ -2904,7 +2902,7 @@ static void fbcon_modechanged(struct fb_info *info) | |||
2904 | p = &fb_display[vc->vc_num]; | 2902 | p = &fb_display[vc->vc_num]; |
2905 | set_blitting_type(vc, info); | 2903 | set_blitting_type(vc, info); |
2906 | 2904 | ||
2907 | if (CON_IS_VISIBLE(vc)) { | 2905 | if (con_is_visible(vc)) { |
2908 | var_to_display(p, &info->var, info); | 2906 | var_to_display(p, &info->var, info); |
2909 | cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); | 2907 | cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); |
2910 | rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); | 2908 | rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); |
@@ -2943,7 +2941,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) | |||
2943 | registered_fb[con2fb_map[i]] != info) | 2941 | registered_fb[con2fb_map[i]] != info) |
2944 | continue; | 2942 | continue; |
2945 | 2943 | ||
2946 | if (CON_IS_VISIBLE(vc)) { | 2944 | if (con_is_visible(vc)) { |
2947 | fg = i; | 2945 | fg = i; |
2948 | continue; | 2946 | continue; |
2949 | } | 2947 | } |
@@ -3182,7 +3180,7 @@ static void fbcon_fb_blanked(struct fb_info *info, int blank) | |||
3182 | registered_fb[con2fb_map[ops->currcon]] != info) | 3180 | registered_fb[con2fb_map[ops->currcon]] != info) |
3183 | return; | 3181 | return; |
3184 | 3182 | ||
3185 | if (CON_IS_VISIBLE(vc)) { | 3183 | if (con_is_visible(vc)) { |
3186 | if (blank) | 3184 | if (blank) |
3187 | do_blank_screen(0); | 3185 | do_blank_screen(0); |
3188 | else | 3186 | else |
@@ -3336,7 +3334,6 @@ static const struct consw fb_con = { | |||
3336 | .con_putcs = fbcon_putcs, | 3334 | .con_putcs = fbcon_putcs, |
3337 | .con_cursor = fbcon_cursor, | 3335 | .con_cursor = fbcon_cursor, |
3338 | .con_scroll = fbcon_scroll, | 3336 | .con_scroll = fbcon_scroll, |
3339 | .con_bmove = fbcon_bmove, | ||
3340 | .con_switch = fbcon_switch, | 3337 | .con_switch = fbcon_switch, |
3341 | .con_blank = fbcon_blank, | 3338 | .con_blank = fbcon_blank, |
3342 | .con_font_set = fbcon_set_font, | 3339 | .con_font_set = fbcon_set_font, |
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 8edc062536a8..bacbb044d77c 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c | |||
@@ -444,48 +444,11 @@ static void mdacon_clear(struct vc_data *c, int y, int x, | |||
444 | } | 444 | } |
445 | } | 445 | } |
446 | 446 | ||
447 | static void mdacon_bmove(struct vc_data *c, int sy, int sx, | ||
448 | int dy, int dx, int height, int width) | ||
449 | { | ||
450 | u16 *src, *dest; | ||
451 | |||
452 | if (width <= 0 || height <= 0) | ||
453 | return; | ||
454 | |||
455 | if (sx==0 && dx==0 && width==mda_num_columns) { | ||
456 | scr_memmovew(MDA_ADDR(0,dy), MDA_ADDR(0,sy), height*width*2); | ||
457 | |||
458 | } else if (dy < sy || (dy == sy && dx < sx)) { | ||
459 | src = MDA_ADDR(sx, sy); | ||
460 | dest = MDA_ADDR(dx, dy); | ||
461 | |||
462 | for (; height > 0; height--) { | ||
463 | scr_memmovew(dest, src, width*2); | ||
464 | src += mda_num_columns; | ||
465 | dest += mda_num_columns; | ||
466 | } | ||
467 | } else { | ||
468 | src = MDA_ADDR(sx, sy+height-1); | ||
469 | dest = MDA_ADDR(dx, dy+height-1); | ||
470 | |||
471 | for (; height > 0; height--) { | ||
472 | scr_memmovew(dest, src, width*2); | ||
473 | src -= mda_num_columns; | ||
474 | dest -= mda_num_columns; | ||
475 | } | ||
476 | } | ||
477 | } | ||
478 | |||
479 | static int mdacon_switch(struct vc_data *c) | 447 | static int mdacon_switch(struct vc_data *c) |
480 | { | 448 | { |
481 | return 1; /* redrawing needed */ | 449 | return 1; /* redrawing needed */ |
482 | } | 450 | } |
483 | 451 | ||
484 | static int mdacon_set_palette(struct vc_data *c, const unsigned char *table) | ||
485 | { | ||
486 | return -EINVAL; | ||
487 | } | ||
488 | |||
489 | static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) | 452 | static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) |
490 | { | 453 | { |
491 | if (mda_type == TYPE_MDA) { | 454 | if (mda_type == TYPE_MDA) { |
@@ -505,11 +468,6 @@ static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) | |||
505 | } | 468 | } |
506 | } | 469 | } |
507 | 470 | ||
508 | static int mdacon_scrolldelta(struct vc_data *c, int lines) | ||
509 | { | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static void mdacon_cursor(struct vc_data *c, int mode) | 471 | static void mdacon_cursor(struct vc_data *c, int mode) |
514 | { | 472 | { |
515 | if (mode == CM_ERASE) { | 473 | if (mode == CM_ERASE) { |
@@ -574,11 +532,8 @@ static const struct consw mda_con = { | |||
574 | .con_putcs = mdacon_putcs, | 532 | .con_putcs = mdacon_putcs, |
575 | .con_cursor = mdacon_cursor, | 533 | .con_cursor = mdacon_cursor, |
576 | .con_scroll = mdacon_scroll, | 534 | .con_scroll = mdacon_scroll, |
577 | .con_bmove = mdacon_bmove, | ||
578 | .con_switch = mdacon_switch, | 535 | .con_switch = mdacon_switch, |
579 | .con_blank = mdacon_blank, | 536 | .con_blank = mdacon_blank, |
580 | .con_set_palette = mdacon_set_palette, | ||
581 | .con_scrolldelta = mdacon_scrolldelta, | ||
582 | .con_build_attr = mdacon_build_attr, | 537 | .con_build_attr = mdacon_build_attr, |
583 | .con_invert_region = mdacon_invert_region, | 538 | .con_invert_region = mdacon_invert_region, |
584 | }; | 539 | }; |
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 0553dfe684ef..e3b9521e4ec3 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c | |||
@@ -574,17 +574,6 @@ static int newport_font_set(struct vc_data *vc, struct console_font *font, unsig | |||
574 | return newport_set_font(vc->vc_num, font); | 574 | return newport_set_font(vc->vc_num, font); |
575 | } | 575 | } |
576 | 576 | ||
577 | static int newport_set_palette(struct vc_data *vc, const unsigned char *table) | ||
578 | { | ||
579 | return -EINVAL; | ||
580 | } | ||
581 | |||
582 | static int newport_scrolldelta(struct vc_data *vc, int lines) | ||
583 | { | ||
584 | /* there is (nearly) no off-screen memory, so we can't scroll back */ | ||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | static int newport_scroll(struct vc_data *vc, int t, int b, int dir, | 577 | static int newport_scroll(struct vc_data *vc, int t, int b, int dir, |
589 | int lines) | 578 | int lines) |
590 | { | 579 | { |
@@ -684,34 +673,6 @@ static int newport_scroll(struct vc_data *vc, int t, int b, int dir, | |||
684 | return 1; | 673 | return 1; |
685 | } | 674 | } |
686 | 675 | ||
687 | static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy, | ||
688 | int dx, int h, int w) | ||
689 | { | ||
690 | short xs, ys, xe, ye, xoffs, yoffs; | ||
691 | |||
692 | xs = sx << 3; | ||
693 | xe = ((sx + w) << 3) - 1; | ||
694 | /* | ||
695 | * as bmove is only used to move stuff around in the same line | ||
696 | * (h == 1), we don't care about wrap arounds caused by topscan != 0 | ||
697 | */ | ||
698 | ys = ((sy << 4) + topscan) & 0x3ff; | ||
699 | ye = (((sy + h) << 4) - 1 + topscan) & 0x3ff; | ||
700 | xoffs = (dx - sx) << 3; | ||
701 | yoffs = (dy - sy) << 4; | ||
702 | if (xoffs > 0) { | ||
703 | /* move to the right, exchange starting points */ | ||
704 | swap(xe, xs); | ||
705 | } | ||
706 | newport_wait(npregs); | ||
707 | npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK | | ||
708 | NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX | ||
709 | | NPORT_DMODE0_STOPY); | ||
710 | npregs->set.xystarti = (xs << 16) | ys; | ||
711 | npregs->set.xyendi = (xe << 16) | ye; | ||
712 | npregs->go.xymove = (xoffs << 16) | yoffs; | ||
713 | } | ||
714 | |||
715 | static int newport_dummy(struct vc_data *c) | 676 | static int newport_dummy(struct vc_data *c) |
716 | { | 677 | { |
717 | return 0; | 678 | return 0; |
@@ -729,13 +690,10 @@ const struct consw newport_con = { | |||
729 | .con_putcs = newport_putcs, | 690 | .con_putcs = newport_putcs, |
730 | .con_cursor = newport_cursor, | 691 | .con_cursor = newport_cursor, |
731 | .con_scroll = newport_scroll, | 692 | .con_scroll = newport_scroll, |
732 | .con_bmove = newport_bmove, | ||
733 | .con_switch = newport_switch, | 693 | .con_switch = newport_switch, |
734 | .con_blank = newport_blank, | 694 | .con_blank = newport_blank, |
735 | .con_font_set = newport_font_set, | 695 | .con_font_set = newport_font_set, |
736 | .con_font_default = newport_font_default, | 696 | .con_font_default = newport_font_default, |
737 | .con_set_palette = newport_set_palette, | ||
738 | .con_scrolldelta = newport_scrolldelta, | ||
739 | .con_set_origin = DUMMY, | 697 | .con_set_origin = DUMMY, |
740 | .con_save_screen = DUMMY | 698 | .con_save_screen = DUMMY |
741 | }; | 699 | }; |
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index e440c2d9fe7c..3a10ac19598f 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c | |||
@@ -79,11 +79,6 @@ static const char *sticon_startup(void) | |||
79 | return "STI console"; | 79 | return "STI console"; |
80 | } | 80 | } |
81 | 81 | ||
82 | static int sticon_set_palette(struct vc_data *c, const unsigned char *table) | ||
83 | { | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) | 82 | static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) |
88 | { | 83 | { |
89 | int redraw_cursor = 0; | 84 | int redraw_cursor = 0; |
@@ -182,22 +177,6 @@ static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count) | |||
182 | return 0; | 177 | return 0; |
183 | } | 178 | } |
184 | 179 | ||
185 | static void sticon_bmove(struct vc_data *conp, int sy, int sx, | ||
186 | int dy, int dx, int height, int width) | ||
187 | { | ||
188 | if (!width || !height) | ||
189 | return; | ||
190 | #if 0 | ||
191 | if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) && | ||
192 | (sx <= p->cursor_x) && (p->cursor_x < sx+width)) || | ||
193 | ((dy <= p->cursor_y) && (p->cursor_y < dy+height) && | ||
194 | (dx <= p->cursor_x) && (p->cursor_x < dx+width))) | ||
195 | sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/); | ||
196 | #endif | ||
197 | |||
198 | sti_bmove(sticon_sti, sy, sx, dy, dx, height, width); | ||
199 | } | ||
200 | |||
201 | static void sticon_init(struct vc_data *c, int init) | 180 | static void sticon_init(struct vc_data *c, int init) |
202 | { | 181 | { |
203 | struct sti_struct *sti = sticon_sti; | 182 | struct sti_struct *sti = sticon_sti; |
@@ -256,11 +235,6 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch) | |||
256 | return 1; | 235 | return 1; |
257 | } | 236 | } |
258 | 237 | ||
259 | static int sticon_scrolldelta(struct vc_data *conp, int lines) | ||
260 | { | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static u16 *sticon_screen_pos(struct vc_data *conp, int offset) | 238 | static u16 *sticon_screen_pos(struct vc_data *conp, int offset) |
265 | { | 239 | { |
266 | int line; | 240 | int line; |
@@ -355,11 +329,8 @@ static const struct consw sti_con = { | |||
355 | .con_putcs = sticon_putcs, | 329 | .con_putcs = sticon_putcs, |
356 | .con_cursor = sticon_cursor, | 330 | .con_cursor = sticon_cursor, |
357 | .con_scroll = sticon_scroll, | 331 | .con_scroll = sticon_scroll, |
358 | .con_bmove = sticon_bmove, | ||
359 | .con_switch = sticon_switch, | 332 | .con_switch = sticon_switch, |
360 | .con_blank = sticon_blank, | 333 | .con_blank = sticon_blank, |
361 | .con_set_palette = sticon_set_palette, | ||
362 | .con_scrolldelta = sticon_scrolldelta, | ||
363 | .con_set_origin = sticon_set_origin, | 334 | .con_set_origin = sticon_set_origin, |
364 | .con_save_screen = sticon_save_screen, | 335 | .con_save_screen = sticon_save_screen, |
365 | .con_build_attr = sticon_build_attr, | 336 | .con_build_attr = sticon_build_attr, |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 8bf911002cba..11576611a974 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -80,7 +80,7 @@ static void vgacon_deinit(struct vc_data *c); | |||
80 | static void vgacon_cursor(struct vc_data *c, int mode); | 80 | static void vgacon_cursor(struct vc_data *c, int mode); |
81 | static int vgacon_switch(struct vc_data *c); | 81 | static int vgacon_switch(struct vc_data *c); |
82 | static int vgacon_blank(struct vc_data *c, int blank, int mode_switch); | 82 | static int vgacon_blank(struct vc_data *c, int blank, int mode_switch); |
83 | static int vgacon_scrolldelta(struct vc_data *c, int lines); | 83 | static void vgacon_scrolldelta(struct vc_data *c, int lines); |
84 | static int vgacon_set_origin(struct vc_data *c); | 84 | static int vgacon_set_origin(struct vc_data *c); |
85 | static void vgacon_save_screen(struct vc_data *c); | 85 | static void vgacon_save_screen(struct vc_data *c); |
86 | static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, | 86 | static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, |
@@ -248,18 +248,18 @@ static void vgacon_restore_screen(struct vc_data *c) | |||
248 | } | 248 | } |
249 | } | 249 | } |
250 | 250 | ||
251 | static int vgacon_scrolldelta(struct vc_data *c, int lines) | 251 | static void vgacon_scrolldelta(struct vc_data *c, int lines) |
252 | { | 252 | { |
253 | int start, end, count, soff; | 253 | int start, end, count, soff; |
254 | 254 | ||
255 | if (!lines) { | 255 | if (!lines) { |
256 | c->vc_visible_origin = c->vc_origin; | 256 | c->vc_visible_origin = c->vc_origin; |
257 | vga_set_mem_top(c); | 257 | vga_set_mem_top(c); |
258 | return 1; | 258 | return; |
259 | } | 259 | } |
260 | 260 | ||
261 | if (!vgacon_scrollback) | 261 | if (!vgacon_scrollback) |
262 | return 1; | 262 | return; |
263 | 263 | ||
264 | if (!vgacon_scrollback_save) { | 264 | if (!vgacon_scrollback_save) { |
265 | vgacon_cursor(c, CM_ERASE); | 265 | vgacon_cursor(c, CM_ERASE); |
@@ -320,8 +320,6 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) | |||
320 | scr_memcpyw(d, s, diff * c->vc_size_row); | 320 | scr_memcpyw(d, s, diff * c->vc_size_row); |
321 | } else | 321 | } else |
322 | vgacon_cursor(c, CM_MOVE); | 322 | vgacon_cursor(c, CM_MOVE); |
323 | |||
324 | return 1; | ||
325 | } | 323 | } |
326 | #else | 324 | #else |
327 | #define vgacon_scrollback_startup(...) do { } while (0) | 325 | #define vgacon_scrollback_startup(...) do { } while (0) |
@@ -334,7 +332,7 @@ static void vgacon_restore_screen(struct vc_data *c) | |||
334 | vgacon_scrolldelta(c, 0); | 332 | vgacon_scrolldelta(c, 0); |
335 | } | 333 | } |
336 | 334 | ||
337 | static int vgacon_scrolldelta(struct vc_data *c, int lines) | 335 | static void vgacon_scrolldelta(struct vc_data *c, int lines) |
338 | { | 336 | { |
339 | if (!lines) /* Turn scrollback off */ | 337 | if (!lines) /* Turn scrollback off */ |
340 | c->vc_visible_origin = c->vc_origin; | 338 | c->vc_visible_origin = c->vc_origin; |
@@ -362,7 +360,6 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) | |||
362 | c->vc_visible_origin = vga_vram_base + (p + ul) % we; | 360 | c->vc_visible_origin = vga_vram_base + (p + ul) % we; |
363 | } | 361 | } |
364 | vga_set_mem_top(c); | 362 | vga_set_mem_top(c); |
365 | return 1; | ||
366 | } | 363 | } |
367 | #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ | 364 | #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ |
368 | 365 | ||
@@ -592,7 +589,7 @@ static void vgacon_init(struct vc_data *c, int init) | |||
592 | static void vgacon_deinit(struct vc_data *c) | 589 | static void vgacon_deinit(struct vc_data *c) |
593 | { | 590 | { |
594 | /* When closing the active console, reset video origin */ | 591 | /* When closing the active console, reset video origin */ |
595 | if (CON_IS_VISIBLE(c)) { | 592 | if (con_is_visible(c)) { |
596 | c->vc_visible_origin = vga_vram_base; | 593 | c->vc_visible_origin = vga_vram_base; |
597 | vga_set_mem_top(c); | 594 | vga_set_mem_top(c); |
598 | } | 595 | } |
@@ -859,16 +856,13 @@ static void vga_set_palette(struct vc_data *vc, const unsigned char *table) | |||
859 | } | 856 | } |
860 | } | 857 | } |
861 | 858 | ||
862 | static int vgacon_set_palette(struct vc_data *vc, const unsigned char *table) | 859 | static void vgacon_set_palette(struct vc_data *vc, const unsigned char *table) |
863 | { | 860 | { |
864 | #ifdef CAN_LOAD_PALETTE | 861 | #ifdef CAN_LOAD_PALETTE |
865 | if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked | 862 | if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked |
866 | || !CON_IS_VISIBLE(vc)) | 863 | || !con_is_visible(vc)) |
867 | return -EINVAL; | 864 | return; |
868 | vga_set_palette(vc, table); | 865 | vga_set_palette(vc, table); |
869 | return 0; | ||
870 | #else | ||
871 | return -EINVAL; | ||
872 | #endif | 866 | #endif |
873 | } | 867 | } |
874 | 868 | ||
@@ -1254,7 +1248,7 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight) | |||
1254 | struct vc_data *c = vc_cons[i].d; | 1248 | struct vc_data *c = vc_cons[i].d; |
1255 | 1249 | ||
1256 | if (c && c->vc_sw == &vga_con) { | 1250 | if (c && c->vc_sw == &vga_con) { |
1257 | if (CON_IS_VISIBLE(c)) { | 1251 | if (con_is_visible(c)) { |
1258 | /* void size to cause regs to be rewritten */ | 1252 | /* void size to cause regs to be rewritten */ |
1259 | cursor_size_lastfrom = 0; | 1253 | cursor_size_lastfrom = 0; |
1260 | cursor_size_lastto = 0; | 1254 | cursor_size_lastto = 0; |
@@ -1318,7 +1312,7 @@ static int vgacon_resize(struct vc_data *c, unsigned int width, | |||
1318 | return success */ | 1312 | return success */ |
1319 | return (user) ? 0 : -EINVAL; | 1313 | return (user) ? 0 : -EINVAL; |
1320 | 1314 | ||
1321 | if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */ | 1315 | if (con_is_visible(c) && !vga_is_gfx) /* who knows */ |
1322 | vgacon_doresize(c, width, height); | 1316 | vgacon_doresize(c, width, height); |
1323 | return 0; | 1317 | return 0; |
1324 | } | 1318 | } |
@@ -1427,7 +1421,6 @@ const struct consw vga_con = { | |||
1427 | .con_putcs = DUMMY, | 1421 | .con_putcs = DUMMY, |
1428 | .con_cursor = vgacon_cursor, | 1422 | .con_cursor = vgacon_cursor, |
1429 | .con_scroll = vgacon_scroll, | 1423 | .con_scroll = vgacon_scroll, |
1430 | .con_bmove = DUMMY, | ||
1431 | .con_switch = vgacon_switch, | 1424 | .con_switch = vgacon_switch, |
1432 | .con_blank = vgacon_blank, | 1425 | .con_blank = vgacon_blank, |
1433 | .con_font_set = vgacon_font_set, | 1426 | .con_font_set = vgacon_font_set, |
diff --git a/include/linux/console.h b/include/linux/console.h index 98c8615dc300..d530c4627e54 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
@@ -28,6 +28,13 @@ struct tty_struct; | |||
28 | #define VT100ID "\033[?1;2c" | 28 | #define VT100ID "\033[?1;2c" |
29 | #define VT102ID "\033[?6c" | 29 | #define VT102ID "\033[?6c" |
30 | 30 | ||
31 | /** | ||
32 | * struct consw - callbacks for consoles | ||
33 | * | ||
34 | * @con_set_palette: sets the palette of the console to @table (optional) | ||
35 | * @con_scrolldelta: the contents of the console should be scrolled by @lines. | ||
36 | * Invoked by user. (optional) | ||
37 | */ | ||
31 | struct consw { | 38 | struct consw { |
32 | struct module *owner; | 39 | struct module *owner; |
33 | const char *(*con_startup)(void); | 40 | const char *(*con_startup)(void); |
@@ -38,7 +45,6 @@ struct consw { | |||
38 | void (*con_putcs)(struct vc_data *, const unsigned short *, int, int, int); | 45 | void (*con_putcs)(struct vc_data *, const unsigned short *, int, int, int); |
39 | void (*con_cursor)(struct vc_data *, int); | 46 | void (*con_cursor)(struct vc_data *, int); |
40 | int (*con_scroll)(struct vc_data *, int, int, int, int); | 47 | int (*con_scroll)(struct vc_data *, int, int, int, int); |
41 | void (*con_bmove)(struct vc_data *, int, int, int, int, int, int); | ||
42 | int (*con_switch)(struct vc_data *); | 48 | int (*con_switch)(struct vc_data *); |
43 | int (*con_blank)(struct vc_data *, int, int); | 49 | int (*con_blank)(struct vc_data *, int, int); |
44 | int (*con_font_set)(struct vc_data *, struct console_font *, unsigned); | 50 | int (*con_font_set)(struct vc_data *, struct console_font *, unsigned); |
@@ -47,8 +53,9 @@ struct consw { | |||
47 | int (*con_font_copy)(struct vc_data *, int); | 53 | int (*con_font_copy)(struct vc_data *, int); |
48 | int (*con_resize)(struct vc_data *, unsigned int, unsigned int, | 54 | int (*con_resize)(struct vc_data *, unsigned int, unsigned int, |
49 | unsigned int); | 55 | unsigned int); |
50 | int (*con_set_palette)(struct vc_data *, const unsigned char *); | 56 | void (*con_set_palette)(struct vc_data *, |
51 | int (*con_scrolldelta)(struct vc_data *, int); | 57 | const unsigned char *table); |
58 | void (*con_scrolldelta)(struct vc_data *, int lines); | ||
52 | int (*con_set_origin)(struct vc_data *); | 59 | int (*con_set_origin)(struct vc_data *); |
53 | void (*con_save_screen)(struct vc_data *); | 60 | void (*con_save_screen)(struct vc_data *); |
54 | u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8); | 61 | u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8); |
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index e329ee2667e1..6fd3c908a340 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h | |||
@@ -21,6 +21,38 @@ struct uni_pagedir; | |||
21 | 21 | ||
22 | #define NPAR 16 | 22 | #define NPAR 16 |
23 | 23 | ||
24 | /* | ||
25 | * Example: vc_data of a console that was scrolled 3 lines down. | ||
26 | * | ||
27 | * Console buffer | ||
28 | * vc_screenbuf ---------> +----------------------+-. | ||
29 | * | initializing W | \ | ||
30 | * | initializing X | | | ||
31 | * | initializing Y | > scroll-back area | ||
32 | * | initializing Z | | | ||
33 | * | | / | ||
34 | * vc_visible_origin ---> ^+----------------------+-: | ||
35 | * (changes by scroll) || Welcome to linux | \ | ||
36 | * || | | | ||
37 | * vc_rows --->< | login: root | | visible on console | ||
38 | * || password: | > (vc_screenbuf_size is | ||
39 | * vc_origin -----------> || | | vc_size_row * vc_rows) | ||
40 | * (start when no scroll) || Last login: 12:28 | / | ||
41 | * v+----------------------+-: | ||
42 | * | Have a lot of fun... | \ | ||
43 | * vc_pos -----------------|--------v | > scroll-front area | ||
44 | * | ~ # cat_ | / | ||
45 | * vc_scr_end -----------> +----------------------+-: | ||
46 | * (vc_origin + | | \ EMPTY, to be filled by | ||
47 | * vc_screenbuf_size) | | / vc_video_erase_char | ||
48 | * +----------------------+-' | ||
49 | * <---- 2 * vc_cols -----> | ||
50 | * <---- vc_size_row -----> | ||
51 | * | ||
52 | * Note that every character in the console buffer is accompanied with an | ||
53 | * attribute in the buffer right after the character. This is not depicted | ||
54 | * in the figure. | ||
55 | */ | ||
24 | struct vc_data { | 56 | struct vc_data { |
25 | struct tty_port port; /* Upper level data */ | 57 | struct tty_port port; /* Upper level data */ |
26 | 58 | ||
@@ -74,7 +106,6 @@ struct vc_data { | |||
74 | unsigned int vc_decawm : 1; /* Autowrap Mode */ | 106 | unsigned int vc_decawm : 1; /* Autowrap Mode */ |
75 | unsigned int vc_deccm : 1; /* Cursor Visible */ | 107 | unsigned int vc_deccm : 1; /* Cursor Visible */ |
76 | unsigned int vc_decim : 1; /* Insert Mode */ | 108 | unsigned int vc_decim : 1; /* Insert Mode */ |
77 | unsigned int vc_deccolm : 1; /* 80/132 Column Mode */ | ||
78 | /* attribute flags */ | 109 | /* attribute flags */ |
79 | unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ | 110 | unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ |
80 | unsigned int vc_italic:1; | 111 | unsigned int vc_italic:1; |
@@ -136,6 +167,9 @@ extern void vc_SAK(struct work_struct *work); | |||
136 | 167 | ||
137 | #define CUR_DEFAULT CUR_UNDERLINE | 168 | #define CUR_DEFAULT CUR_UNDERLINE |
138 | 169 | ||
139 | #define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp) | 170 | static inline bool con_is_visible(const struct vc_data *vc) |
171 | { | ||
172 | return *vc->vc_display_fg == vc; | ||
173 | } | ||
140 | 174 | ||
141 | #endif /* _LINUX_CONSOLE_STRUCT_H */ | 175 | #endif /* _LINUX_CONSOLE_STRUCT_H */ |
diff --git a/include/linux/dma/hsu.h b/include/linux/dma/hsu.h index 79df69dc629c..aaff68efba5d 100644 --- a/include/linux/dma/hsu.h +++ b/include/linux/dma/hsu.h | |||
@@ -39,14 +39,22 @@ struct hsu_dma_chip { | |||
39 | 39 | ||
40 | #if IS_ENABLED(CONFIG_HSU_DMA) | 40 | #if IS_ENABLED(CONFIG_HSU_DMA) |
41 | /* Export to the internal users */ | 41 | /* Export to the internal users */ |
42 | irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr); | 42 | int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr, |
43 | u32 *status); | ||
44 | irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr, | ||
45 | u32 status); | ||
43 | 46 | ||
44 | /* Export to the platform drivers */ | 47 | /* Export to the platform drivers */ |
45 | int hsu_dma_probe(struct hsu_dma_chip *chip); | 48 | int hsu_dma_probe(struct hsu_dma_chip *chip); |
46 | int hsu_dma_remove(struct hsu_dma_chip *chip); | 49 | int hsu_dma_remove(struct hsu_dma_chip *chip); |
47 | #else | 50 | #else |
48 | static inline irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, | 51 | static inline int hsu_dma_get_status(struct hsu_dma_chip *chip, |
49 | unsigned short nr) | 52 | unsigned short nr, u32 *status) |
53 | { | ||
54 | return 0; | ||
55 | } | ||
56 | static inline irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, | ||
57 | unsigned short nr, u32 status) | ||
50 | { | 58 | { |
51 | return IRQ_NONE; | 59 | return IRQ_NONE; |
52 | } | 60 | } |
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 48ec7651989b..923266cd294a 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -111,6 +111,7 @@ struct uart_8250_port { | |||
111 | * if no_console_suspend | 111 | * if no_console_suspend |
112 | */ | 112 | */ |
113 | unsigned char probe; | 113 | unsigned char probe; |
114 | struct mctrl_gpios *gpios; | ||
114 | #define UART_PROBE_RSA (1 << 0) | 115 | #define UART_PROBE_RSA (1 << 0) |
115 | 116 | ||
116 | /* | 117 | /* |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index a3d7c0d4a03e..2f44e2013654 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -352,9 +352,15 @@ struct earlycon_id { | |||
352 | extern const struct earlycon_id __earlycon_table[]; | 352 | extern const struct earlycon_id __earlycon_table[]; |
353 | extern const struct earlycon_id __earlycon_table_end[]; | 353 | extern const struct earlycon_id __earlycon_table_end[]; |
354 | 354 | ||
355 | #if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE) | ||
356 | #define EARLYCON_USED_OR_UNUSED __used | ||
357 | #else | ||
358 | #define EARLYCON_USED_OR_UNUSED __maybe_unused | ||
359 | #endif | ||
360 | |||
355 | #define OF_EARLYCON_DECLARE(_name, compat, fn) \ | 361 | #define OF_EARLYCON_DECLARE(_name, compat, fn) \ |
356 | static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \ | 362 | static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \ |
357 | __used __section(__earlycon_table) \ | 363 | EARLYCON_USED_OR_UNUSED __section(__earlycon_table) \ |
358 | = { .name = __stringify(_name), \ | 364 | = { .name = __stringify(_name), \ |
359 | .compatible = compat, \ | 365 | .compatible = compat, \ |
360 | .setup = fn } | 366 | .setup = fn } |
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 8d7634247fb4..6abd24f258bc 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
@@ -45,7 +45,7 @@ void poke_blanked_console(void); | |||
45 | int con_font_op(struct vc_data *vc, struct console_font_op *op); | 45 | int con_font_op(struct vc_data *vc, struct console_font_op *op); |
46 | int con_set_cmap(unsigned char __user *cmap); | 46 | int con_set_cmap(unsigned char __user *cmap); |
47 | int con_get_cmap(unsigned char __user *cmap); | 47 | int con_get_cmap(unsigned char __user *cmap); |
48 | void scrollback(struct vc_data *vc, int lines); | 48 | void scrollback(struct vc_data *vc); |
49 | void scrollfront(struct vc_data *vc, int lines); | 49 | void scrollfront(struct vc_data *vc, int lines); |
50 | void clear_buffer_attributes(struct vc_data *vc); | 50 | void clear_buffer_attributes(struct vc_data *vc); |
51 | void update_region(struct vc_data *vc, unsigned long start, int count); | 51 | void update_region(struct vc_data *vc, unsigned long start, int count); |
@@ -59,14 +59,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg); | |||
59 | #ifdef CONFIG_CONSOLE_TRANSLATIONS | 59 | #ifdef CONFIG_CONSOLE_TRANSLATIONS |
60 | /* consolemap.c */ | 60 | /* consolemap.c */ |
61 | 61 | ||
62 | struct unimapinit; | ||
63 | struct unipair; | 62 | struct unipair; |
64 | 63 | ||
65 | int con_set_trans_old(unsigned char __user * table); | 64 | int con_set_trans_old(unsigned char __user * table); |
66 | int con_get_trans_old(unsigned char __user * table); | 65 | int con_get_trans_old(unsigned char __user * table); |
67 | int con_set_trans_new(unsigned short __user * table); | 66 | int con_set_trans_new(unsigned short __user * table); |
68 | int con_get_trans_new(unsigned short __user * table); | 67 | int con_get_trans_new(unsigned short __user * table); |
69 | int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui); | 68 | int con_clear_unimap(struct vc_data *vc); |
70 | int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list); | 69 | int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list); |
71 | int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list); | 70 | int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list); |
72 | int con_set_default_unimap(struct vc_data *vc); | 71 | int con_set_default_unimap(struct vc_data *vc); |
@@ -92,7 +91,7 @@ static inline int con_get_trans_new(unsigned short __user *table) | |||
92 | { | 91 | { |
93 | return -EINVAL; | 92 | return -EINVAL; |
94 | } | 93 | } |
95 | static inline int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui) | 94 | static inline int con_clear_unimap(struct vc_data *vc) |
96 | { | 95 | { |
97 | return 0; | 96 | return 0; |
98 | } | 97 | } |
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index d4fdf8f7b471..8f5678cb6263 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c | |||
@@ -246,9 +246,6 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self, | |||
246 | { | 246 | { |
247 | struct serial_struct info; | 247 | struct serial_struct info; |
248 | 248 | ||
249 | if (!retinfo) | ||
250 | return -EFAULT; | ||
251 | |||
252 | memset(&info, 0, sizeof(info)); | 249 | memset(&info, 0, sizeof(info)); |
253 | info.line = self->line; | 250 | info.line = self->line; |
254 | info.flags = self->port.flags; | 251 | info.flags = self->port.flags; |
@@ -258,11 +255,6 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self, | |||
258 | 255 | ||
259 | /* For compatibility */ | 256 | /* For compatibility */ |
260 | info.type = PORT_16550A; | 257 | info.type = PORT_16550A; |
261 | info.port = 0; | ||
262 | info.irq = 0; | ||
263 | info.xmit_fifo_size = 0; | ||
264 | info.hub6 = 0; | ||
265 | info.custom_divisor = 0; | ||
266 | 258 | ||
267 | if (copy_to_user(retinfo, &info, sizeof(*retinfo))) | 259 | if (copy_to_user(retinfo, &info, sizeof(*retinfo))) |
268 | return -EFAULT; | 260 | return -EFAULT; |