mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
TTY/Serial changes for 6.16-rc1
Here is the big set of tty and serial driver changes for 6.16-rc1. A little more churn than normal in this portion of the kernel for this development cycle, Jiri and Nicholas were busy with cleanups and reviews and fixes for the vt unicode handling logic which composed most of the overall work in here. Major changes are: - vt unicode changes/reverts/changes from Nicholas. This should help out a lot with screen readers and others that rely on vt console support - lock guard additions to the core tty/serial code to clean up lots of error handling logic - 8250 driver updates and fixes - device tree conversions to yaml - sh-sci driver updates - other small cleanups and updates for serial drivers and tty core portions All of these have been in linux-next for 2 weeks with no reported issues Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaEKkAA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymRDwCfS4DCUt2naTNf/nE3g29Y77OqHhkAoKqjmpPu G+8PLdjKxW05iQqkngnQ =r8i7 -----END PGP SIGNATURE----- Merge tag 'tty-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty/serial updates from Greg KH: "Here is the big set of tty and serial driver changes for 6.16-rc1. A little more churn than normal in this portion of the kernel for this development cycle, Jiri and Nicholas were busy with cleanups and reviews and fixes for the vt unicode handling logic which composed most of the overall work in here. Major changes are: - vt unicode changes/reverts/changes from Nicholas. This should help out a lot with screen readers and others that rely on vt console support - lock guard additions to the core tty/serial code to clean up lots of error handling logic - 8250 driver updates and fixes - device tree conversions to yaml - sh-sci driver updates - other small cleanups and updates for serial drivers and tty core portions All of these have been in linux-next for 2 weeks with no reported issues" * tag 'tty-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (105 commits) tty: serial: 8250_omap: fix TX with DMA for am33xx vt: add VT_GETCONSIZECSRPOS to retrieve console size and cursor position vt: bracketed paste support vt: remove VT_RESIZE and VT_RESIZEX from vt_compat_ioctl() vt: process the full-width ASCII fallback range programmatically vt: make use of ucs_get_fallback() when glyph is unavailable vt: add ucs_get_fallback() vt: create ucs_fallback_table.h_shipped with gen_ucs_fallback_table.py vt: introduce gen_ucs_fallback_table.py to create ucs_fallback_table.h vt: move glyph determination to a separate function vt: make sure displayed double-width characters are remembered as such vt: ucs.c: fix misappropriate in_range() usage serial: max3100: Replace open-coded parity calculation with parity8() dt-bindings: serial: 8250_omap: Drop redundant properties dt-bindings: serial: Convert socionext,milbeaut-usio-uart to DT schema dt-bindings: serial: Convert microchip,pic32mzda-uart to DT schema dt-bindings: serial: Convert arm,sbsa-uart to DT schema dt-bindings: serial: Convert snps,arc-uart to DT schema dt-bindings: serial: Convert marvell,armada-3700-uart to DT schema dt-bindings: serial: Convert lantiq,asc to DT schema ...
This commit is contained in:
commit
378ec25aec
80 changed files with 6909 additions and 955 deletions
|
@ -135,7 +135,16 @@ properties:
|
|||
clock-frequency: true
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
items:
|
||||
- description: The core function clock
|
||||
- description: An optional bus clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: core
|
||||
- const: bus
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
@ -224,6 +233,25 @@ required:
|
|||
- reg
|
||||
- interrupts
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: spacemit,k1-uart
|
||||
then:
|
||||
required: [clock-names]
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 2
|
||||
clock-names:
|
||||
minItems: 2
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
clock-names:
|
||||
maxItems: 1
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
@ -64,14 +64,7 @@ properties:
|
|||
clock-names:
|
||||
const: fclk
|
||||
|
||||
rts-gpios: true
|
||||
cts-gpios: true
|
||||
dtr-gpios: true
|
||||
dsr-gpios: true
|
||||
rng-gpios: true
|
||||
dcd-gpios: true
|
||||
rs485-rts-active-high: true
|
||||
rts-gpio: true
|
||||
power-domains: true
|
||||
clock-frequency: true
|
||||
current-speed: true
|
||||
|
|
|
@ -56,6 +56,9 @@ properties:
|
|||
items:
|
||||
- enum:
|
||||
- amlogic,a4-uart
|
||||
- amlogic,s6-uart
|
||||
- amlogic,s7-uart
|
||||
- amlogic,s7d-uart
|
||||
- amlogic,t7-uart
|
||||
- const: amlogic,meson-s4-uart
|
||||
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
* Synopsys ARC UART : Non standard UART used in some of the ARC FPGA boards
|
||||
|
||||
Required properties:
|
||||
- compatible : "snps,arc-uart"
|
||||
- reg : offset and length of the register set for the device.
|
||||
- interrupts : device interrupt
|
||||
- clock-frequency : the input clock frequency for the UART
|
||||
- current-speed : baud rate for UART
|
||||
|
||||
e.g.
|
||||
|
||||
arcuart0: serial@c0fc1000 {
|
||||
compatible = "snps,arc-uart";
|
||||
reg = <0xc0fc1000 0x100>;
|
||||
interrupts = <5>;
|
||||
clock-frequency = <80000000>;
|
||||
current-speed = <115200>;
|
||||
};
|
||||
|
||||
Note: Each port should have an alias correctly numbered in "aliases" node.
|
||||
|
||||
e.g.
|
||||
aliases {
|
||||
serial0 = &arcuart0;
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
ARM MPS2 UART
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "arm,mps2-uart"
|
||||
- reg : Address and length of the register set
|
||||
- interrupts : Reference to the UART RX, TX and overrun interrupts
|
||||
|
||||
Required clocking property:
|
||||
- clocks : The input clock of the UART
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
uart0: serial@40004000 {
|
||||
compatible = "arm,mps2-uart";
|
||||
reg = <0x40004000 0x1000>;
|
||||
interrupts = <0 1 12>;
|
||||
clocks = <&sysclk>;
|
||||
};
|
46
Documentation/devicetree/bindings/serial/arm,mps2-uart.yaml
Normal file
46
Documentation/devicetree/bindings/serial/arm,mps2-uart.yaml
Normal file
|
@ -0,0 +1,46 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/arm,mps2-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Arm MPS2 UART
|
||||
|
||||
maintainers:
|
||||
- Vladimir Murzin <vladimir.murzin@arm.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: arm,mps2-uart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: RX interrupt
|
||||
- description: TX interrupt
|
||||
- description: Overrun interrupt
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial@40004000 {
|
||||
compatible = "arm,mps2-uart";
|
||||
reg = <0x40004000 0x1000>;
|
||||
interrupts = <0>, <1>, <12>;
|
||||
clocks = <&sysclk>;
|
||||
};
|
38
Documentation/devicetree/bindings/serial/arm,sbsa-uart.yaml
Normal file
38
Documentation/devicetree/bindings/serial/arm,sbsa-uart.yaml
Normal file
|
@ -0,0 +1,38 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/arm,sbsa-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ARM SBSA UART
|
||||
|
||||
maintainers:
|
||||
- Andre Przywara <andre.przywara@arm.com>
|
||||
|
||||
description:
|
||||
This UART uses a subset of the PL011 registers and consequently lives in the
|
||||
PL011 driver. It's baudrate and other communication parameters cannot be
|
||||
adjusted at runtime, so it lacks a clock specifier here.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: arm,sbsa-uart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
current-speed:
|
||||
description: fixed baud rate set by the firmware
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- current-speed
|
||||
|
||||
unevaluatedProperties: false
|
|
@ -1,10 +0,0 @@
|
|||
* ARM SBSA defined generic UART
|
||||
This UART uses a subset of the PL011 registers and consequently lives
|
||||
in the PL011 driver. It's baudrate and other communication parameters
|
||||
cannot be adjusted at runtime, so it lacks a clock specifier here.
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "arm,sbsa-uart"
|
||||
- reg: exactly one register range
|
||||
- interrupts: exactly one interrupt specifier
|
||||
- current-speed: the (fixed) baud rate set by the firmware
|
|
@ -26,6 +26,7 @@ properties:
|
|||
- enum:
|
||||
- microchip,sam9x60-usart
|
||||
- microchip,sam9x7-usart
|
||||
- microchip,sama7d65-usart
|
||||
- const: atmel,at91sam9260-usart
|
||||
- items:
|
||||
- const: microchip,sam9x60-dbgu
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
* Cirrus Logic CLPS711X Universal Asynchronous Receiver/Transmitter (UART)
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "cirrus,ep7209-uart".
|
||||
- reg: Address and length of the register set for the device.
|
||||
- interrupts: Should contain UART TX and RX interrupt.
|
||||
- clocks: Should contain UART core clock number.
|
||||
- syscon: Phandle to SYSCON node, which contain UART control bits.
|
||||
|
||||
Optional properties:
|
||||
- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
|
||||
line respectively.
|
||||
|
||||
Note: Each UART port should have an alias correctly numbered
|
||||
in "aliases" node.
|
||||
|
||||
Example:
|
||||
aliases {
|
||||
serial0 = &uart1;
|
||||
};
|
||||
|
||||
uart1: uart@80000480 {
|
||||
compatible = "cirrus,ep7312-uart","cirrus,ep7209-uart";
|
||||
reg = <0x80000480 0x80>;
|
||||
interrupts = <12 13>;
|
||||
clocks = <&clks 11>;
|
||||
syscon = <&syscon1>;
|
||||
cts-gpios = <&sysgpio 0 GPIO_ACTIVE_LOW>;
|
||||
dsr-gpios = <&sysgpio 1 GPIO_ACTIVE_LOW>;
|
||||
dcd-gpios = <&sysgpio 2 GPIO_ACTIVE_LOW>;
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/cirrus,ep7209-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Cirrus Logic CLPS711X Universal Asynchronous Receiver/Transmitter (UART)
|
||||
|
||||
maintainers:
|
||||
- Alexander Shiyan <shc_work@mail.ru>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: cirrus,ep7209-uart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: UART TX interrupt
|
||||
- description: UART RX interrupt
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
syscon:
|
||||
description: Phandle to SYSCON node, which contains UART control bits.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- syscon
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
serial@80000480 {
|
||||
compatible = "cirrus,ep7209-uart";
|
||||
reg = <0x80000480 0x80>;
|
||||
interrupts = <12>, <13>;
|
||||
clocks = <&clks 11>;
|
||||
syscon = <&syscon1>;
|
||||
cts-gpios = <&sysgpio 0 GPIO_ACTIVE_LOW>;
|
||||
dsr-gpios = <&sysgpio 1 GPIO_ACTIVE_LOW>;
|
||||
dcd-gpios = <&sysgpio 2 GPIO_ACTIVE_LOW>;
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/cnxt,cx92755-usart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Conexant Digicolor USART
|
||||
|
||||
maintainers:
|
||||
- Baruch Siach <baruch@tkos.co.il>
|
||||
|
||||
description: >
|
||||
Note: this binding is only applicable for using the USART peripheral as UART.
|
||||
USART also support synchronous serial protocols like SPI and I2S.
|
||||
Use the binding that matches the wiring of your system.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: cnxt,cx92755-usart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial@f0000740 {
|
||||
compatible = "cnxt,cx92755-usart";
|
||||
reg = <0xf0000740 0x20>;
|
||||
clocks = <&main_clk>;
|
||||
interrupts = <44>;
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
Binding for Conexant Digicolor USART
|
||||
|
||||
Note: this binding is only applicable for using the USART peripheral as
|
||||
UART. USART also support synchronous serial protocols like SPI and I2S. Use
|
||||
the binding that matches the wiring of your system.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "cnxt,cx92755-usart".
|
||||
- reg: Should contain USART controller registers location and length.
|
||||
- interrupts: Should contain a single USART controller interrupt.
|
||||
- clocks: Must contain phandles to the USART clock
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
|
||||
Note: Each UART port should have an alias correctly numbered
|
||||
in "aliases" node.
|
||||
|
||||
Example:
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
uart0: uart@f0000740 {
|
||||
compatible = "cnxt,cx92755-usart";
|
||||
reg = <0xf0000740 0x20>;
|
||||
clocks = <&main_clk>;
|
||||
interrupts = <44>;
|
||||
};
|
56
Documentation/devicetree/bindings/serial/lantiq,asc.yaml
Normal file
56
Documentation/devicetree/bindings/serial/lantiq,asc.yaml
Normal file
|
@ -0,0 +1,56 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/lantiq,asc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Lantiq SoC ASC serial controller
|
||||
|
||||
maintainers:
|
||||
- John Crispin <john@phrozen.org>
|
||||
- Songjun Wu <songjun.wu@linux.intel.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: lantiq,asc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: TX interrupt
|
||||
- description: RX interrupt
|
||||
- description: Error interrupt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Frequency clock
|
||||
- description: Gate clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: freq
|
||||
- const: asc
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/mips-gic.h>
|
||||
|
||||
serial@16600000 {
|
||||
compatible = "lantiq,asc";
|
||||
reg = <0x16600000 0x100000>;
|
||||
interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
|
@ -1,31 +0,0 @@
|
|||
Lantiq SoC ASC serial controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "lantiq,asc"
|
||||
- reg : Address and length of the register set for the device
|
||||
- interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier
|
||||
depends on the interrupt-parent interrupt controller.
|
||||
|
||||
Optional properties:
|
||||
- clocks: Should contain frequency clock and gate clock
|
||||
- clock-names: Should be "freq" and "asc"
|
||||
|
||||
Example:
|
||||
|
||||
asc0: serial@16600000 {
|
||||
compatible = "lantiq,asc";
|
||||
reg = <0x16600000 0x100000>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cgu CLK_SSX4>, <&cgu GCLK_UART>;
|
||||
clock-names = "freq", "asc";
|
||||
};
|
||||
|
||||
asc1: serial@e100c00 {
|
||||
compatible = "lantiq,asc";
|
||||
reg = <0xE100C00 0x400>;
|
||||
interrupt-parent = <&icu0>;
|
||||
interrupts = <112 113 114>;
|
||||
};
|
|
@ -0,0 +1,102 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/marvell,armada-3700-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell Armada-3700 UART
|
||||
|
||||
maintainers:
|
||||
- Pali Rohár <pali@kernel.org>
|
||||
|
||||
description:
|
||||
Marvell UART is a non standard UART used in some of Marvell EBU SoCs (e.g.
|
||||
Armada-3700).
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,armada-3700-uart
|
||||
- marvell,armada-3700-uart-ext
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description:
|
||||
UART reference clock used to derive the baud rate. If absent, only fixed
|
||||
baud rate from the bootloader is supported.
|
||||
|
||||
interrupts:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: UART sum interrupt
|
||||
- description: UART TX interrupt
|
||||
- description: UART RX interrupt
|
||||
|
||||
interrupt-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: marvell,armada-3700-uart-ext
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: uart-tx
|
||||
- const: uart-rx
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 3
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: uart-sum
|
||||
- const: uart-tx
|
||||
- const: uart-rx
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
serial@12000 {
|
||||
compatible = "marvell,armada-3700-uart";
|
||||
reg = <0x12000 0x18>;
|
||||
clocks = <&uartclk 0>;
|
||||
interrupts =
|
||||
<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uart-sum", "uart-tx", "uart-rx";
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
serial@12200 {
|
||||
compatible = "marvell,armada-3700-uart-ext";
|
||||
reg = <0x12200 0x30>;
|
||||
clocks = <&uartclk 1>;
|
||||
interrupts =
|
||||
<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "uart-tx", "uart-rx";
|
||||
};
|
|
@ -33,6 +33,7 @@ properties:
|
|||
- mediatek,mt6779-uart
|
||||
- mediatek,mt6795-uart
|
||||
- mediatek,mt6797-uart
|
||||
- mediatek,mt6893-uart
|
||||
- mediatek,mt7622-uart
|
||||
- mediatek,mt7623-uart
|
||||
- mediatek,mt7629-uart
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
* Microchip Universal Asynchronous Receiver Transmitter (UART)
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "microchip,pic32mzda-uart"
|
||||
- reg: Should contain registers location and length
|
||||
- interrupts: Should contain interrupt
|
||||
- clocks: Phandle to the clock.
|
||||
See: Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
- pinctrl-names: A pinctrl state names "default" must be defined.
|
||||
- pinctrl-0: Phandle referencing pin configuration of the UART peripheral.
|
||||
See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
|
||||
|
||||
Optional properties:
|
||||
- cts-gpios: CTS pin for UART
|
||||
|
||||
Example:
|
||||
uart1: serial@1f822000 {
|
||||
compatible = "microchip,pic32mzda-uart";
|
||||
reg = <0x1f822000 0x50>;
|
||||
interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<113 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<114 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rootclk PB2CLK>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart1
|
||||
&pinctrl_uart1_cts
|
||||
&pinctrl_uart1_rts>;
|
||||
cts-gpios = <&gpio1 15 0>;
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/microchip,pic32mzda-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip PIC32 UART
|
||||
|
||||
maintainers:
|
||||
- Andrei Pistirica <andrei.pistirica@microchip.com>
|
||||
- Purna Chandra Mandal <purna.mandal@microchip.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: microchip,pic32mzda-uart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Fault
|
||||
- description: RX
|
||||
- description: TX
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/clock/microchip,pic32-clock.h>
|
||||
|
||||
serial@1f822000 {
|
||||
compatible = "microchip,pic32mzda-uart";
|
||||
reg = <0x1f822000 0x50>;
|
||||
interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<113 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<114 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rootclk PB2CLK>;
|
||||
cts-gpios = <&gpio1 15 0>;
|
||||
};
|
|
@ -1,21 +0,0 @@
|
|||
Socionext Milbeaut UART controller
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "socionext,milbeaut-usio-uart".
|
||||
- reg: offset and length of the register set for the device.
|
||||
- interrupts: two interrupts specifier.
|
||||
- interrupt-names: should be "rx", "tx".
|
||||
- clocks: phandle to the input clock.
|
||||
|
||||
Optional properties:
|
||||
- auto-flow-control: flow control enable.
|
||||
|
||||
Example:
|
||||
usio1: usio_uart@1e700010 {
|
||||
compatible = "socionext,milbeaut-usio-uart";
|
||||
reg = <0x1e700010 0x10>;
|
||||
interrupts = <0 141 0x4>, <0 149 0x4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
clocks = <&clk 2>;
|
||||
auto-flow-control;
|
||||
};
|
|
@ -1,56 +0,0 @@
|
|||
* Marvell UART : Non standard UART used in some of Marvell EBU SoCs
|
||||
e.g., Armada-3700.
|
||||
|
||||
Required properties:
|
||||
- compatible:
|
||||
- "marvell,armada-3700-uart" for the standard variant of the UART
|
||||
(32 bytes FIFO, no DMA, level interrupts, 8-bit access to the
|
||||
FIFO), called also UART1.
|
||||
- "marvell,armada-3700-uart-ext" for the extended variant of the
|
||||
UART (128 bytes FIFO, DMA, front interrupts, 8-bit or 32-bit
|
||||
accesses to the FIFO), called also UART2.
|
||||
- reg: offset and length of the register set for the device.
|
||||
- clocks: UART reference clock used to derive the baudrate. If no clock
|
||||
is provided (possible only with the "marvell,armada-3700-uart"
|
||||
compatible string for backward compatibility), it will only work
|
||||
if the baudrate was initialized by the bootloader and no baudrate
|
||||
change will then be possible. When provided it should be UART1-clk
|
||||
for standard variant of UART and UART2-clk for extended variant
|
||||
of UART. TBG clock (with UART TBG divisors d1=d2=1) or xtal clock
|
||||
should not be used and are supported only for backward compatibility.
|
||||
- interrupts:
|
||||
- Must contain three elements for the standard variant of the IP
|
||||
(marvell,armada-3700-uart): "uart-sum", "uart-tx" and "uart-rx",
|
||||
respectively the UART sum interrupt, the UART TX interrupt and
|
||||
UART RX interrupt. A corresponding interrupt-names property must
|
||||
be defined.
|
||||
- Must contain two elements for the extended variant of the IP
|
||||
(marvell,armada-3700-uart-ext): "uart-tx" and "uart-rx",
|
||||
respectively the UART TX interrupt and the UART RX interrupt. A
|
||||
corresponding interrupt-names property must be defined.
|
||||
- For backward compatibility reasons, a single element interrupts
|
||||
property is also supported for the standard variant of the IP,
|
||||
containing only the UART sum interrupt. This form is deprecated
|
||||
and should no longer be used.
|
||||
|
||||
Example:
|
||||
uart0: serial@12000 {
|
||||
compatible = "marvell,armada-3700-uart";
|
||||
reg = <0x12000 0x18>;
|
||||
clocks = <&uartclk 0>;
|
||||
interrupts =
|
||||
<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "uart-sum", "uart-tx", "uart-rx";
|
||||
};
|
||||
|
||||
uart1: serial@12200 {
|
||||
compatible = "marvell,armada-3700-uart-ext";
|
||||
reg = <0x12200 0x30>;
|
||||
clocks = <&uartclk 1>;
|
||||
interrupts =
|
||||
<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "uart-tx", "uart-rx";
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/nxp,lpc3220-hsuart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP LPC32xx SoC High Speed UART
|
||||
|
||||
maintainers:
|
||||
- Vladimir Zapolskiy <vz@mleia.com>
|
||||
- Piotr Wojtaszczyk <piotr.wojtaszczyk@timesys.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: nxp,lpc3220-hsuart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial@40014000 {
|
||||
compatible = "nxp,lpc3220-hsuart";
|
||||
reg = <0x40014000 0x1000>;
|
||||
interrupts = <26 0>;
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
* NXP LPC32xx SoC High Speed UART
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "nxp,lpc3220-hsuart"
|
||||
- reg: Should contain registers location and length
|
||||
- interrupts: Should contain interrupt
|
||||
|
||||
Example:
|
||||
|
||||
uart1: serial@40014000 {
|
||||
compatible = "nxp,lpc3220-hsuart";
|
||||
reg = <0x40014000 0x1000>;
|
||||
interrupts = <26 0>;
|
||||
};
|
78
Documentation/devicetree/bindings/serial/renesas,rsci.yaml
Normal file
78
Documentation/devicetree/bindings/serial/renesas,rsci.yaml
Normal file
|
@ -0,0 +1,78 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/renesas,rsci.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RSCI Serial Communication Interface
|
||||
|
||||
maintainers:
|
||||
- Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
- Thierry Bultel <thierry.bultel.yh@bp.renesas.com>
|
||||
|
||||
allOf:
|
||||
- $ref: serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a09g077-rsci # RZ/T2H
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Error interrupt
|
||||
- description: Receive buffer full interrupt
|
||||
- description: Transmit buffer empty interrupt
|
||||
- description: Transmit end interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: eri
|
||||
- const: rxi
|
||||
- const: txi
|
||||
- const: tei
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: fck # UART functional clock
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
uart-has-rtscts: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/renesas-cpg-mssr.h>
|
||||
|
||||
aliases {
|
||||
serial0 = &sci0;
|
||||
};
|
||||
|
||||
sci0: serial@80005000 {
|
||||
compatible = "renesas,r9a09g077-rsci";
|
||||
reg = <0x80005000 0x400>;
|
||||
interrupts = <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 591 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 592 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "eri", "rxi", "txi", "tei";
|
||||
clocks = <&cpg CPG_MOD 108>;
|
||||
clock-names = "fck";
|
||||
power-domains = <&cpg>;
|
||||
};
|
51
Documentation/devicetree/bindings/serial/snps,arc-uart.yaml
Normal file
51
Documentation/devicetree/bindings/serial/snps,arc-uart.yaml
Normal file
|
@ -0,0 +1,51 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/snps,arc-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Synopsys ARC UART
|
||||
|
||||
maintainers:
|
||||
- Vineet Gupta <vgupta@kernel.org>
|
||||
|
||||
description:
|
||||
Synopsys ARC UART is a non-standard UART used in some of the ARC FPGA boards.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: snps,arc-uart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clock-frequency:
|
||||
description: the input clock frequency for the UART
|
||||
|
||||
current-speed:
|
||||
description: baud rate for UART
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clock-frequency
|
||||
- current-speed
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial@c0fc1000 {
|
||||
compatible = "snps,arc-uart";
|
||||
reg = <0xc0fc1000 0x100>;
|
||||
interrupts = <5>;
|
||||
clock-frequency = <80000000>;
|
||||
current-speed = <115200>;
|
||||
};
|
|
@ -17,7 +17,7 @@ allOf:
|
|||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: renesas,r9a06g032-uart
|
||||
- {}
|
||||
- const: renesas,rzn1-uart
|
||||
- const: snps,dw-apb-uart
|
||||
then:
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/serial/socionext,milbeaut-usio-uart.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Socionext Milbeaut UART controller
|
||||
|
||||
maintainers:
|
||||
- Sugaya Taichi <sugaya.taichi@socionext.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: socionext,milbeaut-usio-uart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: RX interrupt specifier
|
||||
- description: TX interrupt specifier
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
auto-flow-control:
|
||||
description: Enable automatic flow control.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
serial@1e700010 {
|
||||
compatible = "socionext,milbeaut-usio-uart";
|
||||
reg = <0x1e700010 0x10>;
|
||||
interrupts = <0 141 0x4>, <0 149 0x4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
clocks = <&clk 2>;
|
||||
auto-flow-control;
|
||||
};
|
|
@ -14503,7 +14503,7 @@ MARVELL ARMADA 3700 SERIAL DRIVER
|
|||
M: Pali Rohár <pali@kernel.org>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/clock/marvell,armada-3700-uart-clock.yaml
|
||||
F: Documentation/devicetree/bindings/serial/mvebu-uart.txt
|
||||
F: Documentation/devicetree/bindings/serial/marvell,armada-3700-uart.yaml
|
||||
F: drivers/tty/serial/mvebu-uart.c
|
||||
|
||||
MARVELL ARMADA DRM SUPPORT
|
||||
|
|
|
@ -1812,7 +1812,7 @@ static int mxser_probe(struct pci_dev *pdev,
|
|||
|
||||
/* io address */
|
||||
ioaddress = pci_resource_start(pdev, 2);
|
||||
retval = pci_request_region(pdev, 2, "mxser(IO)");
|
||||
retval = pcim_request_region(pdev, 2, "mxser(IO)");
|
||||
if (retval)
|
||||
goto err_zero;
|
||||
|
||||
|
@ -1822,7 +1822,7 @@ static int mxser_probe(struct pci_dev *pdev,
|
|||
|
||||
/* vector */
|
||||
ioaddress = pci_resource_start(pdev, 3);
|
||||
retval = pci_request_region(pdev, 3, "mxser(vector)");
|
||||
retval = pcim_request_region(pdev, 3, "mxser(vector)");
|
||||
if (retval)
|
||||
goto err_zero;
|
||||
brd->vector = ioaddress;
|
||||
|
|
|
@ -118,12 +118,11 @@ int serdev_device_add(struct serdev_device *serdev)
|
|||
|
||||
err = device_add(&serdev->dev);
|
||||
if (err < 0) {
|
||||
dev_err(&serdev->dev, "Can't add %s, status %pe\n",
|
||||
dev_name(&serdev->dev), ERR_PTR(err));
|
||||
dev_err(&serdev->dev, "Failed to add serdev: %d\n", err);
|
||||
goto err_clear_serdev;
|
||||
}
|
||||
|
||||
dev_dbg(&serdev->dev, "device %s registered\n", dev_name(&serdev->dev));
|
||||
dev_dbg(&serdev->dev, "serdev registered successfully\n");
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -783,8 +782,7 @@ int serdev_controller_add(struct serdev_controller *ctrl)
|
|||
goto err_rpm_disable;
|
||||
}
|
||||
|
||||
dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n",
|
||||
ctrl->nr, &ctrl->dev);
|
||||
dev_dbg(&ctrl->dev, "serdev controller registered: dev:%p\n", &ctrl->dev);
|
||||
return 0;
|
||||
|
||||
err_rpm_disable:
|
||||
|
|
|
@ -223,12 +223,6 @@ static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
|
|||
struct uart_8250_port *serial8250_setup_port(int index);
|
||||
struct uart_8250_port *serial8250_get_port(int line);
|
||||
|
||||
void serial8250_rpm_get(struct uart_8250_port *p);
|
||||
void serial8250_rpm_put(struct uart_8250_port *p);
|
||||
|
||||
void serial8250_rpm_get_tx(struct uart_8250_port *p);
|
||||
void serial8250_rpm_put_tx(struct uart_8250_port *p);
|
||||
|
||||
int serial8250_em485_config(struct uart_port *port, struct ktermios *termios,
|
||||
struct serial_rs485 *rs485);
|
||||
void serial8250_em485_start_tx(struct uart_8250_port *p, bool toggle_ier);
|
||||
|
|
|
@ -461,7 +461,7 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
|
|||
char *options)
|
||||
{
|
||||
char match[] = "uart"; /* 8250-specific earlycon name */
|
||||
unsigned char iotype;
|
||||
enum uart_iotype iotype;
|
||||
resource_size_t addr;
|
||||
int i;
|
||||
|
||||
|
|
|
@ -77,6 +77,8 @@ static void serial8250_early_out(struct uart_port *port, int offset, int value)
|
|||
outb(value, port->iobase + offset);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,14 +10,18 @@
|
|||
* Copyright 2012-2023 National Instruments Corporation
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "8250.h"
|
||||
|
||||
|
@ -90,10 +94,10 @@ static int ni16550_disable_transceivers(struct uart_port *port)
|
|||
{
|
||||
u8 pcr;
|
||||
|
||||
pcr = port->serial_in(port, NI16550_PCR_OFFSET);
|
||||
pcr = serial_port_in(port, NI16550_PCR_OFFSET);
|
||||
pcr &= ~NI16550_PCR_TXVR_ENABLE_BIT;
|
||||
dev_dbg(port->dev, "disable transceivers: write pcr: 0x%02x\n", pcr);
|
||||
port->serial_out(port, NI16550_PCR_OFFSET, pcr);
|
||||
serial_port_out(port, NI16550_PCR_OFFSET, pcr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,7 +109,7 @@ static int ni16550_rs485_config(struct uart_port *port,
|
|||
struct uart_8250_port *up = container_of(port, struct uart_8250_port, port);
|
||||
u8 pcr;
|
||||
|
||||
pcr = serial_in(up, NI16550_PCR_OFFSET);
|
||||
pcr = serial_port_in(port, NI16550_PCR_OFFSET);
|
||||
pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
|
||||
|
||||
if ((rs485->flags & SER_RS485_MODE_RS422) ||
|
||||
|
@ -120,7 +124,7 @@ static int ni16550_rs485_config(struct uart_port *port,
|
|||
}
|
||||
|
||||
dev_dbg(port->dev, "config rs485: write pcr: 0x%02x, acr: %02x\n", pcr, up->acr);
|
||||
serial_out(up, NI16550_PCR_OFFSET, pcr);
|
||||
serial_port_out(port, NI16550_PCR_OFFSET, pcr);
|
||||
serial_icr_write(up, UART_ACR, up->acr);
|
||||
|
||||
return 0;
|
||||
|
@ -224,31 +228,26 @@ static int ni16550_get_regs(struct platform_device *pdev,
|
|||
{
|
||||
struct resource *regs;
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
if (regs) {
|
||||
regs = platform_get_mem_or_io(pdev, 0);
|
||||
if (!regs)
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "no registers defined\n");
|
||||
|
||||
switch (resource_type(regs)) {
|
||||
case IORESOURCE_IO:
|
||||
port->iotype = UPIO_PORT;
|
||||
port->iobase = regs->start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (regs) {
|
||||
case IORESOURCE_MEM:
|
||||
port->iotype = UPIO_MEM;
|
||||
port->mapbase = regs->start;
|
||||
port->mapsize = resource_size(regs);
|
||||
port->flags |= UPF_IOREMAP;
|
||||
|
||||
port->membase = devm_ioremap(&pdev->dev, port->mapbase,
|
||||
port->mapsize);
|
||||
if (!port->membase)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_err(&pdev->dev, "no registers defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -280,12 +279,11 @@ static int ni16550_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct uart_8250_port uart = {};
|
||||
unsigned int txfifosz, rxfifosz;
|
||||
unsigned int prescaler = 0;
|
||||
unsigned int prescaler;
|
||||
struct ni16550_data *data;
|
||||
const char *portmode;
|
||||
bool rs232_property;
|
||||
int ret;
|
||||
int irq;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
|
@ -293,10 +291,6 @@ static int ni16550_probe(struct platform_device *pdev)
|
|||
|
||||
spin_lock_init(&uart.port.lock);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = ni16550_get_regs(pdev, &uart.port);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -307,10 +301,7 @@ static int ni16550_probe(struct platform_device *pdev)
|
|||
info = device_get_match_data(dev);
|
||||
|
||||
uart.port.dev = dev;
|
||||
uart.port.irq = irq;
|
||||
uart.port.irqflags = IRQF_SHARED;
|
||||
uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
|
||||
| UPF_FIXED_PORT | UPF_FIXED_TYPE;
|
||||
uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_FIXED_TYPE;
|
||||
uart.port.startup = ni16550_port_startup;
|
||||
uart.port.shutdown = ni16550_port_shutdown;
|
||||
|
||||
|
@ -332,28 +323,26 @@ static int ni16550_probe(struct platform_device *pdev)
|
|||
/*
|
||||
* Declaration of the base clock frequency can come from one of:
|
||||
* - static declaration in this driver (for older ACPI IDs)
|
||||
* - a "clock-frquency" ACPI
|
||||
* - a "clock-frequency" ACPI
|
||||
*/
|
||||
if (info->uartclk)
|
||||
uart.port.uartclk = info->uartclk;
|
||||
if (device_property_read_u32(dev, "clock-frequency",
|
||||
&uart.port.uartclk)) {
|
||||
uart.port.uartclk = info->uartclk;
|
||||
|
||||
ret = uart_read_port_properties(&uart.port);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!uart.port.uartclk) {
|
||||
data->clk = devm_clk_get_enabled(dev, NULL);
|
||||
if (!IS_ERR(data->clk))
|
||||
uart.port.uartclk = clk_get_rate(data->clk);
|
||||
}
|
||||
|
||||
if (!uart.port.uartclk) {
|
||||
dev_err(dev, "unable to determine clock frequency!\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
if (!uart.port.uartclk)
|
||||
return dev_err_probe(dev, -ENODEV, "unable to determine clock frequency!\n");
|
||||
|
||||
if (info->prescaler)
|
||||
prescaler = info->prescaler;
|
||||
prescaler = info->prescaler;
|
||||
device_property_read_u32(dev, "clock-prescaler", &prescaler);
|
||||
|
||||
if (prescaler != 0) {
|
||||
if (prescaler) {
|
||||
uart.port.set_mctrl = ni16550_set_mctrl;
|
||||
ni16550_config_prescaler(&uart, (u8)prescaler);
|
||||
}
|
||||
|
@ -393,14 +382,11 @@ static int ni16550_probe(struct platform_device *pdev)
|
|||
|
||||
ret = serial8250_register_8250_port(&uart);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
return ret;
|
||||
data->line = ret;
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ni16550_remove(struct platform_device *pdev)
|
||||
|
@ -410,7 +396,6 @@ static void ni16550_remove(struct platform_device *pdev)
|
|||
serial8250_unregister_port(data->line);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/* NI 16550 RS-485 Interface */
|
||||
static const struct ni16550_device_info nic7750 = {
|
||||
.uartclk = 33333333,
|
||||
|
@ -435,20 +420,20 @@ static const struct ni16550_device_info nic7a69 = {
|
|||
.uartclk = 29629629,
|
||||
.prescaler = 0x09,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id ni16550_acpi_match[] = {
|
||||
{ "NIC7750", (kernel_ulong_t)&nic7750 },
|
||||
{ "NIC7772", (kernel_ulong_t)&nic7772 },
|
||||
{ "NIC792B", (kernel_ulong_t)&nic792b },
|
||||
{ "NIC7A69", (kernel_ulong_t)&nic7a69 },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, ni16550_acpi_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver ni16550_driver = {
|
||||
.driver = {
|
||||
.name = "ni16550",
|
||||
.acpi_match_table = ACPI_PTR(ni16550_acpi_match),
|
||||
.acpi_match_table = ni16550_acpi_match,
|
||||
},
|
||||
.probe = ni16550_probe,
|
||||
.remove = ni16550_remove,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
struct of_serial_info {
|
||||
struct clk *clk;
|
||||
struct clk *bus_clk;
|
||||
struct reset_control *rst;
|
||||
int type;
|
||||
int line;
|
||||
|
@ -123,12 +124,22 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
|
|||
|
||||
/* Get clk rate through clk driver if present */
|
||||
if (!port->uartclk) {
|
||||
info->clk = devm_clk_get_enabled(dev, NULL);
|
||||
struct clk *bus_clk;
|
||||
|
||||
bus_clk = devm_clk_get_optional_enabled(dev, "bus");
|
||||
if (IS_ERR(bus_clk)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(bus_clk), "failed to get bus clock\n");
|
||||
goto err_pmruntime;
|
||||
}
|
||||
|
||||
/* If the bus clock is required, core clock must be named */
|
||||
info->clk = devm_clk_get_enabled(dev, bus_clk ? "core" : NULL);
|
||||
if (IS_ERR(info->clk)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(info->clk), "failed to get clock\n");
|
||||
goto err_pmruntime;
|
||||
}
|
||||
|
||||
info->bus_clk = bus_clk;
|
||||
port->uartclk = clk_get_rate(info->clk);
|
||||
}
|
||||
/* If current-speed was set, then try not to change it. */
|
||||
|
@ -290,6 +301,7 @@ static int of_serial_suspend(struct device *dev)
|
|||
if (!uart_console(port) || console_suspend_enabled) {
|
||||
pm_runtime_put_sync(dev);
|
||||
clk_disable_unprepare(info->clk);
|
||||
clk_disable_unprepare(info->bus_clk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -302,6 +314,7 @@ static int of_serial_resume(struct device *dev)
|
|||
|
||||
if (!uart_console(port) || console_suspend_enabled) {
|
||||
pm_runtime_get_sync(dev);
|
||||
clk_prepare_enable(info->bus_clk);
|
||||
clk_prepare_enable(info->clk);
|
||||
}
|
||||
|
||||
|
|
|
@ -1173,16 +1173,6 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
sg_init_table(&sg, 1);
|
||||
ret = kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1,
|
||||
UART_XMIT_SIZE, dma->tx_addr);
|
||||
if (ret != 1) {
|
||||
serial8250_clear_THRI(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dma->tx_size = sg_dma_len(&sg);
|
||||
|
||||
if (priv->habit & OMAP_DMA_TX_KICK) {
|
||||
unsigned char c;
|
||||
u8 tx_lvl;
|
||||
|
@ -1207,18 +1197,22 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
|
|||
ret = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
if (dma->tx_size < 4) {
|
||||
if (kfifo_len(&tport->xmit_fifo) < 4) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
if (!kfifo_get(&tport->xmit_fifo, &c)) {
|
||||
if (!uart_fifo_out(&p->port, &c, 1)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
skip_byte = c;
|
||||
/* now we need to recompute due to kfifo_get */
|
||||
kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1,
|
||||
UART_XMIT_SIZE, dma->tx_addr);
|
||||
}
|
||||
|
||||
sg_init_table(&sg, 1);
|
||||
ret = kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1, UART_XMIT_SIZE, dma->tx_addr);
|
||||
if (ret != 1) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
desc = dmaengine_prep_slave_sg(dma->txchan, &sg, 1, DMA_MEM_TO_DEV,
|
||||
|
@ -1228,6 +1222,7 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
|
|||
goto err;
|
||||
}
|
||||
|
||||
dma->tx_size = sg_dma_len(&sg);
|
||||
dma->tx_running = 1;
|
||||
|
||||
desc->callback = omap_8250_dma_tx_complete;
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
|
||||
#define UART_RESET_REG 0x94
|
||||
#define UART_RESET_D3_RESET_DISABLE BIT(16)
|
||||
#define UART_RESET_HOT_RESET_DISABLE BIT(17)
|
||||
|
||||
#define UART_BURST_STATUS_REG 0x9C
|
||||
#define UART_TX_BURST_FIFO 0xA0
|
||||
|
@ -620,6 +621,10 @@ static int pci1xxxx_suspend(struct device *dev)
|
|||
}
|
||||
|
||||
data = readl(p + UART_RESET_REG);
|
||||
|
||||
if (priv->dev_rev >= 0xC0)
|
||||
data |= UART_RESET_HOT_RESET_DISABLE;
|
||||
|
||||
writel(data | UART_RESET_D3_RESET_DISABLE, p + UART_RESET_REG);
|
||||
|
||||
if (wakeup)
|
||||
|
@ -647,7 +652,12 @@ static int pci1xxxx_resume(struct device *dev)
|
|||
}
|
||||
|
||||
data = readl(p + UART_RESET_REG);
|
||||
|
||||
if (priv->dev_rev >= 0xC0)
|
||||
data &= ~UART_RESET_HOT_RESET_DISABLE;
|
||||
|
||||
writel(data & ~UART_RESET_D3_RESET_DISABLE, p + UART_RESET_REG);
|
||||
|
||||
iounmap(p);
|
||||
|
||||
for (i = 0; i < priv->nr; i++) {
|
||||
|
|
|
@ -517,22 +517,20 @@ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
|
||||
|
||||
void serial8250_rpm_get(struct uart_8250_port *p)
|
||||
static void serial8250_rpm_get(struct uart_8250_port *p)
|
||||
{
|
||||
if (!(p->capabilities & UART_CAP_RPM))
|
||||
return;
|
||||
pm_runtime_get_sync(p->port.dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_rpm_get);
|
||||
|
||||
void serial8250_rpm_put(struct uart_8250_port *p)
|
||||
static void serial8250_rpm_put(struct uart_8250_port *p)
|
||||
{
|
||||
if (!(p->capabilities & UART_CAP_RPM))
|
||||
return;
|
||||
pm_runtime_mark_last_busy(p->port.dev);
|
||||
pm_runtime_put_autosuspend(p->port.dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_rpm_put);
|
||||
|
||||
/**
|
||||
* serial8250_em485_init() - put uart_8250_port into rs485 emulating
|
||||
|
@ -647,7 +645,7 @@ EXPORT_SYMBOL_GPL(serial8250_em485_config);
|
|||
* once and disable_runtime_pm_tx() will still disable RPM because the fifo is
|
||||
* empty and the HW can idle again.
|
||||
*/
|
||||
void serial8250_rpm_get_tx(struct uart_8250_port *p)
|
||||
static void serial8250_rpm_get_tx(struct uart_8250_port *p)
|
||||
{
|
||||
unsigned char rpm_active;
|
||||
|
||||
|
@ -659,9 +657,8 @@ void serial8250_rpm_get_tx(struct uart_8250_port *p)
|
|||
return;
|
||||
pm_runtime_get_sync(p->port.dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_rpm_get_tx);
|
||||
|
||||
void serial8250_rpm_put_tx(struct uart_8250_port *p)
|
||||
static void serial8250_rpm_put_tx(struct uart_8250_port *p)
|
||||
{
|
||||
unsigned char rpm_active;
|
||||
|
||||
|
@ -674,7 +671,6 @@ void serial8250_rpm_put_tx(struct uart_8250_port *p)
|
|||
pm_runtime_mark_last_busy(p->port.dev);
|
||||
pm_runtime_put_autosuspend(p->port.dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(serial8250_rpm_put_tx);
|
||||
|
||||
/*
|
||||
* IER sleep support. UARTs which have EFRs need the "extended
|
||||
|
@ -2993,6 +2989,8 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
|
|||
if (!request_region(port->iobase, size, "serial"))
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
case UPIO_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -3025,6 +3023,8 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
|
|||
case UPIO_PORT:
|
||||
release_region(port->iobase, size);
|
||||
break;
|
||||
case UPIO_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ static void rsa8250_release_resource(struct uart_8250_port *up)
|
|||
case UPIO_PORT:
|
||||
release_region(port->iobase + offset, size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -572,7 +572,7 @@ config SERIAL_8250_BCM7271
|
|||
config SERIAL_8250_NI
|
||||
tristate "NI 16550 based serial port"
|
||||
depends on SERIAL_8250
|
||||
depends on (X86 && ACPI) || COMPILE_TEST
|
||||
depends on X86 || COMPILE_TEST
|
||||
help
|
||||
This driver supports the integrated serial ports on National
|
||||
Instruments (NI) controller hardware. This is required for all NI
|
||||
|
|
|
@ -2476,7 +2476,7 @@ static int pl011_console_setup(struct console *co, char *options)
|
|||
static int pl011_console_match(struct console *co, char *name, int idx,
|
||||
char *options)
|
||||
{
|
||||
unsigned char iotype;
|
||||
enum uart_iotype iotype;
|
||||
resource_size_t addr;
|
||||
int i;
|
||||
|
||||
|
|
|
@ -403,6 +403,8 @@ static inline void lpuart32_write(struct uart_port *port, u32 val,
|
|||
case UPIO_MEM32BE:
|
||||
iowrite32be(val, port->membase + off);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,8 +565,9 @@ static dma_addr_t lpuart_dma_datareg_addr(struct lpuart_port *sport)
|
|||
return sport->port.mapbase + UARTDATA;
|
||||
case UPIO_MEM32BE:
|
||||
return sport->port.mapbase + UARTDATA + sizeof(u32) - 1;
|
||||
default:
|
||||
return sport->port.mapbase + UARTDR;
|
||||
}
|
||||
return sport->port.mapbase + UARTDR;
|
||||
}
|
||||
|
||||
static int lpuart_dma_tx_request(struct uart_port *port)
|
||||
|
|
|
@ -451,6 +451,7 @@ int jsm_uart_port_init(struct jsm_board *brd)
|
|||
if (!brd->channels[i])
|
||||
continue;
|
||||
|
||||
brd->channels[i]->uart_port.dev = &brd->pci_dev->dev;
|
||||
brd->channels[i]->uart_port.irq = brd->irq;
|
||||
brd->channels[i]->uart_port.uartclk = 14745600;
|
||||
brd->channels[i]->uart_port.type = PORT_JSM;
|
||||
|
|
|
@ -773,10 +773,8 @@ static int fetch_irq_intel(struct device *dev, struct ltq_uart_port *ltq_port)
|
|||
int ret;
|
||||
|
||||
ret = platform_get_irq(to_platform_device(dev), 0);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to fetch IRQ for serial port\n");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ltq_port->common_irq = ret;
|
||||
port->irq = ret;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
/* 4 MAX3100s should be enough for everyone */
|
||||
#define MAX_MAX3100 4
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
|
@ -133,7 +134,7 @@ static int max3100_do_parity(struct max3100_port *s, u16 c)
|
|||
else
|
||||
c &= 0xff;
|
||||
|
||||
parity = parity ^ (hweight8(c) & 1);
|
||||
parity = parity ^ parity8(c);
|
||||
return parity;
|
||||
}
|
||||
|
||||
|
|
|
@ -1189,13 +1189,16 @@ static int max310x_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
|||
return !!((val >> 4) & (1 << (offset % 4)));
|
||||
}
|
||||
|
||||
static void max310x_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
|
||||
static int max310x_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct max310x_port *s = gpiochip_get_data(chip);
|
||||
struct uart_port *port = &s->p[offset / 4].port;
|
||||
|
||||
max310x_port_update(port, MAX310X_GPIODATA_REG, 1 << (offset % 4),
|
||||
value ? 1 << (offset % 4) : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max310x_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
|
||||
|
@ -1411,7 +1414,7 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty
|
|||
s->gpio.direction_input = max310x_gpio_direction_input;
|
||||
s->gpio.get = max310x_gpio_get;
|
||||
s->gpio.direction_output= max310x_gpio_direction_output;
|
||||
s->gpio.set = max310x_gpio_set;
|
||||
s->gpio.set_rv = max310x_gpio_set;
|
||||
s->gpio.set_config = max310x_gpio_set_config;
|
||||
s->gpio.base = -1;
|
||||
s->gpio.ngpio = devtype->nr * 4;
|
||||
|
|
|
@ -523,7 +523,10 @@ static int mlb_usio_probe(struct platform_device *pdev)
|
|||
}
|
||||
port->membase = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
|
||||
if (!port->membase) {
|
||||
ret = -ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
ret = platform_get_irq_byname(pdev, "rx");
|
||||
mlb_usio_irq[index][RX] = ret;
|
||||
|
||||
|
|
|
@ -98,6 +98,8 @@
|
|||
|
||||
#define DMA_RX_BUF_SIZE 2048
|
||||
|
||||
static DEFINE_IDA(port_ida);
|
||||
|
||||
struct qcom_geni_device_data {
|
||||
bool console;
|
||||
enum geni_se_xfer_mode mode;
|
||||
|
@ -253,10 +255,24 @@ static struct qcom_geni_serial_port *get_port_from_line(int line, bool console)
|
|||
struct qcom_geni_serial_port *port;
|
||||
int nr_ports = console ? GENI_UART_CONS_PORTS : GENI_UART_PORTS;
|
||||
|
||||
if (line < 0 || line >= nr_ports)
|
||||
return ERR_PTR(-ENXIO);
|
||||
if (console) {
|
||||
if (line < 0 || line >= nr_ports)
|
||||
return ERR_PTR(-ENXIO);
|
||||
|
||||
port = console ? &qcom_geni_console_port : &qcom_geni_uart_ports[line];
|
||||
port = &qcom_geni_console_port;
|
||||
} else {
|
||||
int max_alias_num = of_alias_get_highest_id("serial");
|
||||
|
||||
if (line < 0 || line >= nr_ports)
|
||||
line = ida_alloc_range(&port_ida, max_alias_num + 1, nr_ports, GFP_KERNEL);
|
||||
else
|
||||
line = ida_alloc_range(&port_ida, line, nr_ports, GFP_KERNEL);
|
||||
|
||||
if (line < 0)
|
||||
return ERR_PTR(-ENXIO);
|
||||
|
||||
port = &qcom_geni_uart_ports[line];
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
|
@ -1761,6 +1777,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
|||
port->wakeup_irq);
|
||||
if (ret) {
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
ida_free(&port_ida, uport->line);
|
||||
uart_remove_one_port(drv, uport);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1772,10 +1789,12 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
|
|||
static void qcom_geni_serial_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
|
||||
struct uart_port *uport = &port->uport;
|
||||
struct uart_driver *drv = port->private_data.drv;
|
||||
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
ida_free(&port_ida, uport->line);
|
||||
uart_remove_one_port(drv, &port->uport);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define S3C24XX_SERIAL_MINOR 64
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
#define UART_NR 12
|
||||
#define UART_NR 18
|
||||
#else
|
||||
#define UART_NR CONFIG_SERIAL_SAMSUNG_UARTS
|
||||
#endif
|
||||
|
@ -190,6 +190,8 @@ static void wr_reg(const struct uart_port *port, u32 reg, u32 val)
|
|||
case UPIO_MEM32:
|
||||
writel_relaxed(val, portaddr(port, reg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2713,6 +2715,8 @@ static void wr_reg_barrier(const struct uart_port *port, u32 reg, u32 val)
|
|||
case UPIO_MEM32:
|
||||
writel(val, portaddr(port, reg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1333,13 +1333,16 @@ static int sc16is7xx_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|||
return !!(val & BIT(offset));
|
||||
}
|
||||
|
||||
static void sc16is7xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
|
||||
static int sc16is7xx_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int val)
|
||||
{
|
||||
struct sc16is7xx_port *s = gpiochip_get_data(chip);
|
||||
struct uart_port *port = &s->p[0].port;
|
||||
|
||||
sc16is7xx_port_update(port, SC16IS7XX_IOSTATE_REG, BIT(offset),
|
||||
val ? BIT(offset) : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sc16is7xx_gpio_direction_input(struct gpio_chip *chip,
|
||||
|
@ -1422,7 +1425,7 @@ static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s)
|
|||
s->gpio.direction_input = sc16is7xx_gpio_direction_input;
|
||||
s->gpio.get = sc16is7xx_gpio_get;
|
||||
s->gpio.direction_output = sc16is7xx_gpio_direction_output;
|
||||
s->gpio.set = sc16is7xx_gpio_set;
|
||||
s->gpio.set_rv = sc16is7xx_gpio_set;
|
||||
s->gpio.base = -1;
|
||||
s->gpio.ngpio = s->devtype->nr_gpio;
|
||||
s->gpio.can_sleep = 1;
|
||||
|
|
|
@ -75,22 +75,23 @@ static inline void uart_port_deref(struct uart_port *uport)
|
|||
wake_up(&uport->state->remove_wait);
|
||||
}
|
||||
|
||||
#define uart_port_lock(state, flags) \
|
||||
({ \
|
||||
struct uart_port *__uport = uart_port_ref(state); \
|
||||
if (__uport) \
|
||||
uart_port_lock_irqsave(__uport, &flags); \
|
||||
__uport; \
|
||||
})
|
||||
static inline struct uart_port *uart_port_ref_lock(struct uart_state *state, unsigned long *flags)
|
||||
{
|
||||
struct uart_port *uport = uart_port_ref(state);
|
||||
|
||||
#define uart_port_unlock(uport, flags) \
|
||||
({ \
|
||||
struct uart_port *__uport = uport; \
|
||||
if (__uport) { \
|
||||
uart_port_unlock_irqrestore(__uport, flags); \
|
||||
uart_port_deref(__uport); \
|
||||
} \
|
||||
})
|
||||
if (uport)
|
||||
uart_port_lock_irqsave(uport, flags);
|
||||
|
||||
return uport;
|
||||
}
|
||||
|
||||
static inline void uart_port_unlock_deref(struct uart_port *uport, unsigned long flags)
|
||||
{
|
||||
if (uport) {
|
||||
uart_port_unlock_irqrestore(uport, flags);
|
||||
uart_port_deref(uport);
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct uart_port *uart_port_check(struct uart_state *state)
|
||||
{
|
||||
|
@ -127,10 +128,10 @@ static void uart_stop(struct tty_struct *tty)
|
|||
struct uart_port *port;
|
||||
unsigned long flags;
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
if (port)
|
||||
port->ops->stop_tx(port);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
}
|
||||
|
||||
static void __uart_start(struct uart_state *state)
|
||||
|
@ -168,9 +169,9 @@ static void uart_start(struct tty_struct *tty)
|
|||
struct uart_port *port;
|
||||
unsigned long flags;
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
__uart_start(state);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -258,14 +259,14 @@ static int uart_alloc_xmit_buf(struct tty_port *port)
|
|||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
uport = uart_port_lock(state, flags);
|
||||
uport = uart_port_ref_lock(state, &flags);
|
||||
if (!state->port.xmit_buf) {
|
||||
state->port.xmit_buf = (unsigned char *)page;
|
||||
kfifo_init(&state->port.xmit_fifo, state->port.xmit_buf,
|
||||
PAGE_SIZE);
|
||||
uart_port_unlock(uport, flags);
|
||||
uart_port_unlock_deref(uport, flags);
|
||||
} else {
|
||||
uart_port_unlock(uport, flags);
|
||||
uart_port_unlock_deref(uport, flags);
|
||||
/*
|
||||
* Do not free() the page under the port lock, see
|
||||
* uart_free_xmit_buf().
|
||||
|
@ -289,11 +290,11 @@ static void uart_free_xmit_buf(struct tty_port *port)
|
|||
* console driver may need to allocate/free a debug object, which
|
||||
* can end up in printk() recursion.
|
||||
*/
|
||||
uport = uart_port_lock(state, flags);
|
||||
uport = uart_port_ref_lock(state, &flags);
|
||||
xmit_buf = port->xmit_buf;
|
||||
port->xmit_buf = NULL;
|
||||
INIT_KFIFO(port->xmit_fifo);
|
||||
uart_port_unlock(uport, flags);
|
||||
uart_port_unlock_deref(uport, flags);
|
||||
|
||||
free_page((unsigned long)xmit_buf);
|
||||
}
|
||||
|
@ -592,15 +593,15 @@ static int uart_put_char(struct tty_struct *tty, u8 c)
|
|||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
if (!state->port.xmit_buf) {
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (port)
|
||||
ret = kfifo_put(&state->port.xmit_fifo, c);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -623,9 +624,9 @@ static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count)
|
|||
if (WARN_ON(!state))
|
||||
return -EL3HLT;
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
if (!state->port.xmit_buf) {
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -633,7 +634,7 @@ static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count)
|
|||
ret = kfifo_in(&state->port.xmit_fifo, buf, count);
|
||||
|
||||
__uart_start(state);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -644,9 +645,9 @@ static unsigned int uart_write_room(struct tty_struct *tty)
|
|||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
ret = kfifo_avail(&state->port.xmit_fifo);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -657,9 +658,9 @@ static unsigned int uart_chars_in_buffer(struct tty_struct *tty)
|
|||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
ret = kfifo_len(&state->port.xmit_fifo);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -678,13 +679,13 @@ static void uart_flush_buffer(struct tty_struct *tty)
|
|||
|
||||
pr_debug("uart_flush_buffer(%d) called\n", tty->index);
|
||||
|
||||
port = uart_port_lock(state, flags);
|
||||
port = uart_port_ref_lock(state, &flags);
|
||||
if (!port)
|
||||
return;
|
||||
kfifo_reset(&state->port.xmit_fifo);
|
||||
if (port->ops->flush_buffer)
|
||||
port->ops->flush_buffer(port);
|
||||
uart_port_unlock(port, flags);
|
||||
uart_port_unlock_deref(port, flags);
|
||||
tty_port_tty_wakeup(&state->port);
|
||||
}
|
||||
|
||||
|
@ -1275,14 +1276,13 @@ static int uart_get_icount(struct tty_struct *tty,
|
|||
struct uart_state *state = tty->driver_data;
|
||||
struct uart_icount cnow;
|
||||
struct uart_port *uport;
|
||||
unsigned long flags;
|
||||
|
||||
uport = uart_port_ref(state);
|
||||
uport = uart_port_ref_lock(state, &flags);
|
||||
if (!uport)
|
||||
return -EIO;
|
||||
uart_port_lock_irq(uport);
|
||||
memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
|
||||
uart_port_unlock_irq(uport);
|
||||
uart_port_deref(uport);
|
||||
uart_port_unlock_deref(uport, flags);
|
||||
|
||||
icount->cts = cnow.cts;
|
||||
icount->dsr = cnow.dsr;
|
||||
|
@ -1914,9 +1914,10 @@ static bool uart_carrier_raised(struct tty_port *port)
|
|||
{
|
||||
struct uart_state *state = container_of(port, struct uart_state, port);
|
||||
struct uart_port *uport;
|
||||
unsigned long flags;
|
||||
int mctrl;
|
||||
|
||||
uport = uart_port_ref(state);
|
||||
uport = uart_port_ref_lock(state, &flags);
|
||||
/*
|
||||
* Should never observe uport == NULL since checks for hangup should
|
||||
* abort the tty_port_block_til_ready() loop before checking for carrier
|
||||
|
@ -1925,11 +1926,9 @@ static bool uart_carrier_raised(struct tty_port *port)
|
|||
*/
|
||||
if (WARN_ON(!uport))
|
||||
return true;
|
||||
uart_port_lock_irq(uport);
|
||||
uart_enable_ms(uport);
|
||||
mctrl = uport->ops->get_mctrl(uport);
|
||||
uart_port_unlock_irq(uport);
|
||||
uart_port_deref(uport);
|
||||
uart_port_unlock_deref(uport, flags);
|
||||
|
||||
return mctrl & TIOCM_CAR;
|
||||
}
|
||||
|
@ -2178,8 +2177,8 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
|
|||
*
|
||||
* Returns: 0 on success or -%EINVAL on failure
|
||||
*/
|
||||
int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
|
||||
char **options)
|
||||
int uart_parse_earlycon(char *p, enum uart_iotype *iotype,
|
||||
resource_size_t *addr, char **options)
|
||||
{
|
||||
if (strncmp(p, "mmio,", 5) == 0) {
|
||||
*iotype = UPIO_MEM;
|
||||
|
@ -3289,9 +3288,9 @@ bool uart_match_port(const struct uart_port *port1,
|
|||
case UPIO_AU:
|
||||
case UPIO_TSI:
|
||||
return port1->mapbase == port2->mapbase;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(uart_match_port);
|
||||
|
||||
|
|
167
drivers/tty/serial/sh-sci-common.h
Normal file
167
drivers/tty/serial/sh-sci-common.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __SH_SCI_COMMON_H__
|
||||
#define __SH_SCI_COMMON_H__
|
||||
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
enum SCI_CLKS {
|
||||
SCI_FCK, /* Functional Clock */
|
||||
SCI_SCK, /* Optional External Clock */
|
||||
SCI_BRG_INT, /* Optional BRG Internal Clock Source */
|
||||
SCI_SCIF_CLK, /* Optional BRG External Clock Source */
|
||||
SCI_NUM_CLKS
|
||||
};
|
||||
|
||||
/* Offsets into the sci_port->irqs array */
|
||||
enum {
|
||||
SCIx_ERI_IRQ,
|
||||
SCIx_RXI_IRQ,
|
||||
SCIx_TXI_IRQ,
|
||||
SCIx_BRI_IRQ,
|
||||
SCIx_DRI_IRQ,
|
||||
SCIx_TEI_IRQ,
|
||||
SCIx_NR_IRQS,
|
||||
|
||||
SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */
|
||||
};
|
||||
|
||||
/* Bit x set means sampling rate x + 1 is supported */
|
||||
#define SCI_SR(x) BIT((x) - 1)
|
||||
#define SCI_SR_RANGE(x, y) GENMASK((y) - 1, (x) - 1)
|
||||
|
||||
void sci_release_port(struct uart_port *port);
|
||||
int sci_request_port(struct uart_port *port);
|
||||
void sci_config_port(struct uart_port *port, int flags);
|
||||
int sci_verify_port(struct uart_port *port, struct serial_struct *ser);
|
||||
void sci_pm(struct uart_port *port, unsigned int state,
|
||||
unsigned int oldstate);
|
||||
|
||||
struct plat_sci_reg {
|
||||
u8 offset;
|
||||
u8 size;
|
||||
};
|
||||
|
||||
struct sci_port_params_bits {
|
||||
unsigned int rxtx_enable;
|
||||
unsigned int te_clear;
|
||||
unsigned int poll_sent_bits;
|
||||
};
|
||||
|
||||
struct sci_common_regs {
|
||||
unsigned int status;
|
||||
unsigned int control;
|
||||
};
|
||||
|
||||
/* The actual number of needed registers. This is used by sci only */
|
||||
#define SCI_NR_REGS 20
|
||||
|
||||
struct sci_port_params {
|
||||
const struct plat_sci_reg regs[SCI_NR_REGS];
|
||||
const struct sci_common_regs *common_regs;
|
||||
const struct sci_port_params_bits *param_bits;
|
||||
unsigned int fifosize;
|
||||
unsigned int overrun_reg;
|
||||
unsigned int overrun_mask;
|
||||
unsigned int sampling_rate_mask;
|
||||
unsigned int error_mask;
|
||||
unsigned int error_clear;
|
||||
};
|
||||
|
||||
struct sci_port_ops {
|
||||
u32 (*read_reg)(struct uart_port *port, int reg);
|
||||
void (*write_reg)(struct uart_port *port, int reg, int value);
|
||||
void (*clear_SCxSR)(struct uart_port *port, unsigned int mask);
|
||||
|
||||
void (*transmit_chars)(struct uart_port *port);
|
||||
void (*receive_chars)(struct uart_port *port);
|
||||
|
||||
void (*poll_put_char)(struct uart_port *port, unsigned char c);
|
||||
|
||||
int (*set_rtrg)(struct uart_port *port, int rx_trig);
|
||||
int (*rtrg_enabled)(struct uart_port *port);
|
||||
|
||||
void (*shutdown_complete)(struct uart_port *port);
|
||||
|
||||
void (*prepare_console_write)(struct uart_port *port, u32 ctrl);
|
||||
void (*console_save)(struct uart_port *port);
|
||||
void (*console_restore)(struct uart_port *port);
|
||||
size_t (*suspend_regs_size)(void);
|
||||
};
|
||||
|
||||
struct sci_of_data {
|
||||
const struct sci_port_params *params;
|
||||
const struct uart_ops *uart_ops;
|
||||
const struct sci_port_ops *ops;
|
||||
unsigned short regtype;
|
||||
unsigned short type;
|
||||
};
|
||||
|
||||
struct sci_port {
|
||||
struct uart_port port;
|
||||
|
||||
/* Platform configuration */
|
||||
const struct sci_port_params *params;
|
||||
const struct plat_sci_port *cfg;
|
||||
|
||||
unsigned int sampling_rate_mask;
|
||||
resource_size_t reg_size;
|
||||
struct mctrl_gpios *gpios;
|
||||
|
||||
/* Clocks */
|
||||
struct clk *clks[SCI_NUM_CLKS];
|
||||
unsigned long clk_rates[SCI_NUM_CLKS];
|
||||
|
||||
int irqs[SCIx_NR_IRQS];
|
||||
char *irqstr[SCIx_NR_IRQS];
|
||||
|
||||
struct dma_chan *chan_tx;
|
||||
struct dma_chan *chan_rx;
|
||||
|
||||
struct reset_control *rstc;
|
||||
struct sci_suspend_regs *suspend_regs;
|
||||
|
||||
#ifdef CONFIG_SERIAL_SH_SCI_DMA
|
||||
struct dma_chan *chan_tx_saved;
|
||||
struct dma_chan *chan_rx_saved;
|
||||
dma_cookie_t cookie_tx;
|
||||
dma_cookie_t cookie_rx[2];
|
||||
dma_cookie_t active_rx;
|
||||
dma_addr_t tx_dma_addr;
|
||||
unsigned int tx_dma_len;
|
||||
struct scatterlist sg_rx[2];
|
||||
void *rx_buf[2];
|
||||
size_t buf_len_rx;
|
||||
struct work_struct work_tx;
|
||||
struct hrtimer rx_timer;
|
||||
unsigned int rx_timeout; /* microseconds */
|
||||
#endif
|
||||
unsigned int rx_frame;
|
||||
int rx_trigger;
|
||||
struct timer_list rx_fifo_timer;
|
||||
int rx_fifo_timeout;
|
||||
u16 hscif_tot;
|
||||
|
||||
const struct sci_port_ops *ops;
|
||||
|
||||
bool has_rtscts;
|
||||
bool autorts;
|
||||
bool tx_occurred;
|
||||
};
|
||||
|
||||
#define to_sci_port(uart) container_of((uart), struct sci_port, port)
|
||||
|
||||
void sci_port_disable(struct sci_port *sci_port);
|
||||
void sci_port_enable(struct sci_port *sci_port);
|
||||
|
||||
int sci_startup(struct uart_port *port);
|
||||
void sci_shutdown(struct uart_port *port);
|
||||
|
||||
#define min_sr(_port) ffs((_port)->sampling_rate_mask)
|
||||
#define max_sr(_port) fls((_port)->sampling_rate_mask)
|
||||
|
||||
#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
|
||||
int __init scix_early_console_setup(struct earlycon_device *device, const struct sci_of_data *data);
|
||||
#endif
|
||||
|
||||
#endif /* __SH_SCI_COMMON_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -32,8 +32,6 @@ enum {
|
|||
HSRTRGR, /* Rx FIFO Data Count Trigger Register */
|
||||
HSTTRGR, /* Tx FIFO Data Count Trigger Register */
|
||||
SEMR, /* Serial extended mode register */
|
||||
|
||||
SCIx_NR_REGS,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
* @baud_rate: UART serial line rate (e.g., 115200 baud)
|
||||
* @clk: reference to this device's clock
|
||||
* @clk_notifier: clock rate change notifier for upstream clock changes
|
||||
* @console_line_ended: indicate that the console line is fully written
|
||||
*
|
||||
* Configuration data specific to this SiFive UART.
|
||||
*/
|
||||
|
@ -151,6 +152,7 @@ struct sifive_serial_port {
|
|||
unsigned long baud_rate;
|
||||
struct clk *clk;
|
||||
struct notifier_block clk_notifier;
|
||||
bool console_line_ended;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -785,33 +787,88 @@ static void sifive_serial_console_putchar(struct uart_port *port, unsigned char
|
|||
|
||||
__ssp_wait_for_xmitr(ssp);
|
||||
__ssp_transmit_char(ssp, ch);
|
||||
|
||||
ssp->console_line_ended = (ch == '\n');
|
||||
}
|
||||
|
||||
static void sifive_serial_console_write(struct console *co, const char *s,
|
||||
unsigned int count)
|
||||
static void sifive_serial_device_lock(struct console *co, unsigned long *flags)
|
||||
{
|
||||
struct uart_port *up = &sifive_serial_console_ports[co->index]->port;
|
||||
|
||||
__uart_port_lock_irqsave(up, flags);
|
||||
}
|
||||
|
||||
static void sifive_serial_device_unlock(struct console *co, unsigned long flags)
|
||||
{
|
||||
struct uart_port *up = &sifive_serial_console_ports[co->index]->port;
|
||||
|
||||
__uart_port_unlock_irqrestore(up, flags);
|
||||
}
|
||||
|
||||
static void sifive_serial_console_write_atomic(struct console *co,
|
||||
struct nbcon_write_context *wctxt)
|
||||
{
|
||||
struct sifive_serial_port *ssp = sifive_serial_console_ports[co->index];
|
||||
unsigned long flags;
|
||||
struct uart_port *port = &ssp->port;
|
||||
unsigned int ier;
|
||||
int locked = 1;
|
||||
|
||||
if (!ssp)
|
||||
return;
|
||||
|
||||
if (oops_in_progress)
|
||||
locked = uart_port_trylock_irqsave(&ssp->port, &flags);
|
||||
else
|
||||
uart_port_lock_irqsave(&ssp->port, &flags);
|
||||
if (!nbcon_enter_unsafe(wctxt))
|
||||
return;
|
||||
|
||||
ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS);
|
||||
__ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp);
|
||||
|
||||
uart_console_write(&ssp->port, s, count, sifive_serial_console_putchar);
|
||||
if (!ssp->console_line_ended)
|
||||
uart_console_write(port, "\n", 1, sifive_serial_console_putchar);
|
||||
uart_console_write(port, wctxt->outbuf, wctxt->len,
|
||||
sifive_serial_console_putchar);
|
||||
|
||||
__ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp);
|
||||
|
||||
if (locked)
|
||||
uart_port_unlock_irqrestore(&ssp->port, flags);
|
||||
nbcon_exit_unsafe(wctxt);
|
||||
}
|
||||
|
||||
static void sifive_serial_console_write_thread(struct console *co,
|
||||
struct nbcon_write_context *wctxt)
|
||||
{
|
||||
struct sifive_serial_port *ssp = sifive_serial_console_ports[co->index];
|
||||
struct uart_port *port = &ssp->port;
|
||||
unsigned int ier;
|
||||
|
||||
if (!ssp)
|
||||
return;
|
||||
|
||||
if (!nbcon_enter_unsafe(wctxt))
|
||||
return;
|
||||
|
||||
ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS);
|
||||
__ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp);
|
||||
|
||||
if (nbcon_exit_unsafe(wctxt)) {
|
||||
int len = READ_ONCE(wctxt->len);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!nbcon_enter_unsafe(wctxt))
|
||||
break;
|
||||
|
||||
uart_console_write(port, wctxt->outbuf + i, 1,
|
||||
sifive_serial_console_putchar);
|
||||
|
||||
if (!nbcon_exit_unsafe(wctxt))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (!nbcon_enter_unsafe(wctxt))
|
||||
nbcon_reacquire_nobuf(wctxt);
|
||||
|
||||
__ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp);
|
||||
|
||||
nbcon_exit_unsafe(wctxt);
|
||||
}
|
||||
|
||||
static int sifive_serial_console_setup(struct console *co, char *options)
|
||||
|
@ -829,6 +886,8 @@ static int sifive_serial_console_setup(struct console *co, char *options)
|
|||
if (!ssp)
|
||||
return -ENODEV;
|
||||
|
||||
ssp->console_line_ended = true;
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
|
||||
|
@ -839,10 +898,13 @@ static struct uart_driver sifive_serial_uart_driver;
|
|||
|
||||
static struct console sifive_serial_console = {
|
||||
.name = SIFIVE_TTY_PREFIX,
|
||||
.write = sifive_serial_console_write,
|
||||
.write_atomic = sifive_serial_console_write_atomic,
|
||||
.write_thread = sifive_serial_console_write_thread,
|
||||
.device_lock = sifive_serial_device_lock,
|
||||
.device_unlock = sifive_serial_device_unlock,
|
||||
.device = uart_console_device,
|
||||
.setup = sifive_serial_console_setup,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.flags = CON_PRINTBUFFER | CON_NBCON,
|
||||
.index = -1,
|
||||
.data = &sifive_serial_uart_driver,
|
||||
};
|
||||
|
|
|
@ -434,7 +434,7 @@ static void tegra_utc_console_write_atomic(struct console *cons, struct nbcon_wr
|
|||
|
||||
outbuf += burst_size;
|
||||
len -= burst_size;
|
||||
};
|
||||
}
|
||||
|
||||
nbcon_exit_unsafe(wctxt);
|
||||
}
|
||||
|
|
|
@ -880,16 +880,6 @@ of_err:
|
|||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
if (!ulite_uart_driver.state) {
|
||||
dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n");
|
||||
ret = uart_register_driver(&ulite_uart_driver);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register driver\n");
|
||||
clk_disable_unprepare(pdata->clk);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
|
@ -929,16 +919,25 @@ static struct platform_driver ulite_platform_driver = {
|
|||
|
||||
static int __init ulite_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_debug("uartlite: calling uart_register_driver()\n");
|
||||
ret = uart_register_driver(&ulite_uart_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pr_debug("uartlite: calling platform_driver_register()\n");
|
||||
return platform_driver_register(&ulite_platform_driver);
|
||||
ret = platform_driver_register(&ulite_platform_driver);
|
||||
if (ret)
|
||||
uart_unregister_driver(&ulite_uart_driver);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit ulite_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ulite_platform_driver);
|
||||
if (ulite_uart_driver.state)
|
||||
uart_unregister_driver(&ulite_uart_driver);
|
||||
uart_unregister_driver(&ulite_uart_driver);
|
||||
}
|
||||
|
||||
module_init(ulite_init);
|
||||
|
|
|
@ -276,11 +276,10 @@ static void check_tty_count(struct tty_struct *tty, const char *routine)
|
|||
struct list_head *p;
|
||||
int count = 0, kopen_count = 0;
|
||||
|
||||
spin_lock(&tty->files_lock);
|
||||
list_for_each(p, &tty->tty_files) {
|
||||
count++;
|
||||
}
|
||||
spin_unlock(&tty->files_lock);
|
||||
scoped_guard(spinlock, &tty->files_lock)
|
||||
list_for_each(p, &tty->tty_files)
|
||||
count++;
|
||||
|
||||
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|
||||
tty->driver->subtype == PTY_TYPE_SLAVE &&
|
||||
tty->link && tty->link->count)
|
||||
|
@ -378,7 +377,7 @@ EXPORT_SYMBOL_GPL(tty_dev_name_to_number);
|
|||
*/
|
||||
struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
||||
{
|
||||
struct tty_driver *p, *res = NULL;
|
||||
struct tty_driver *p;
|
||||
int tty_line = 0;
|
||||
int len;
|
||||
char *str, *stp;
|
||||
|
@ -392,7 +391,8 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
|||
len = str - name;
|
||||
tty_line = simple_strtoul(str, &str, 10);
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
guard(mutex)(&tty_mutex);
|
||||
|
||||
/* Search through the tty devices to look for a match */
|
||||
list_for_each_entry(p, &tty_drivers, tty_drivers) {
|
||||
if (!len || strncmp(name, p->name, len) != 0)
|
||||
|
@ -405,14 +405,12 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
|||
|
||||
if (tty_line >= 0 && tty_line < p->num && p->ops &&
|
||||
p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
|
||||
res = tty_driver_kref_get(p);
|
||||
*line = tty_line;
|
||||
break;
|
||||
return tty_driver_kref_get(p);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&tty_mutex);
|
||||
|
||||
return res;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tty_find_polling_driver);
|
||||
#endif
|
||||
|
@ -531,16 +529,15 @@ EXPORT_SYMBOL_GPL(tty_wakeup);
|
|||
*/
|
||||
static struct file *tty_release_redirect(struct tty_struct *tty)
|
||||
{
|
||||
struct file *f = NULL;
|
||||
guard(spinlock)(&redirect_lock);
|
||||
|
||||
spin_lock(&redirect_lock);
|
||||
if (redirect && file_tty(redirect) == tty) {
|
||||
f = redirect;
|
||||
struct file *f = redirect;
|
||||
redirect = NULL;
|
||||
return f;
|
||||
}
|
||||
spin_unlock(&redirect_lock);
|
||||
|
||||
return f;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -765,11 +762,8 @@ void __stop_tty(struct tty_struct *tty)
|
|||
*/
|
||||
void stop_tty(struct tty_struct *tty)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tty->flow.lock, flags);
|
||||
guard(spinlock_irqsave)(&tty->flow.lock);
|
||||
__stop_tty(tty);
|
||||
spin_unlock_irqrestore(&tty->flow.lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(stop_tty);
|
||||
|
||||
|
@ -796,11 +790,8 @@ void __start_tty(struct tty_struct *tty)
|
|||
*/
|
||||
void start_tty(struct tty_struct *tty)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tty->flow.lock, flags);
|
||||
guard(spinlock_irqsave)(&tty->flow.lock);
|
||||
__start_tty(tty);
|
||||
spin_unlock_irqrestore(&tty->flow.lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(start_tty);
|
||||
|
||||
|
@ -809,7 +800,8 @@ static void tty_update_time(struct tty_struct *tty, bool mtime)
|
|||
time64_t sec = ktime_get_real_seconds();
|
||||
struct tty_file_private *priv;
|
||||
|
||||
spin_lock(&tty->files_lock);
|
||||
guard(spinlock)(&tty->files_lock);
|
||||
|
||||
list_for_each_entry(priv, &tty->tty_files, list) {
|
||||
struct inode *inode = file_inode(priv->file);
|
||||
struct timespec64 time = mtime ? inode_get_mtime(inode) : inode_get_atime(inode);
|
||||
|
@ -827,7 +819,6 @@ static void tty_update_time(struct tty_struct *tty, bool mtime)
|
|||
inode_set_atime(inode, sec, 0);
|
||||
}
|
||||
}
|
||||
spin_unlock(&tty->files_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2314,13 +2305,12 @@ static int tiocsti(struct tty_struct *tty, u8 __user *p)
|
|||
*/
|
||||
static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
|
||||
{
|
||||
int err;
|
||||
guard(mutex)(&tty->winsize_mutex);
|
||||
|
||||
mutex_lock(&tty->winsize_mutex);
|
||||
err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
|
||||
mutex_unlock(&tty->winsize_mutex);
|
||||
if (copy_to_user(arg, &tty->winsize, sizeof(*arg)))
|
||||
return -EFAULT;
|
||||
|
||||
return err ? -EFAULT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2335,10 +2325,10 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
|
|||
{
|
||||
struct pid *pgrp;
|
||||
|
||||
/* Lock the tty */
|
||||
mutex_lock(&tty->winsize_mutex);
|
||||
guard(mutex)(&tty->winsize_mutex);
|
||||
|
||||
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
|
||||
goto done;
|
||||
return 0;
|
||||
|
||||
/* Signal the foreground process group */
|
||||
pgrp = tty_get_pgrp(tty);
|
||||
|
@ -2347,8 +2337,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
|
|||
put_pid(pgrp);
|
||||
|
||||
tty->winsize = *ws;
|
||||
done:
|
||||
mutex_unlock(&tty->winsize_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tty_do_resize);
|
||||
|
@ -2409,13 +2398,14 @@ static int tioccons(struct file *file)
|
|||
return -EBADF;
|
||||
if (!(file->f_mode & FMODE_CAN_WRITE))
|
||||
return -EINVAL;
|
||||
spin_lock(&redirect_lock);
|
||||
if (redirect) {
|
||||
spin_unlock(&redirect_lock);
|
||||
|
||||
guard(spinlock)(&redirect_lock);
|
||||
|
||||
if (redirect)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
redirect = get_file(file);
|
||||
spin_unlock(&redirect_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3028,11 +3018,9 @@ void __do_SAK(struct tty_struct *tty)
|
|||
struct task_struct *g, *p;
|
||||
struct pid *session;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tty->ctrl.lock, flags);
|
||||
session = get_pid(tty->ctrl.session);
|
||||
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
|
||||
scoped_guard(spinlock_irqsave, &tty->ctrl.lock)
|
||||
session = get_pid(tty->ctrl.session);
|
||||
|
||||
tty_ldisc_flush(tty);
|
||||
|
||||
|
@ -3055,7 +3043,7 @@ void __do_SAK(struct tty_struct *tty)
|
|||
PIDTYPE_SID);
|
||||
continue;
|
||||
}
|
||||
task_lock(p);
|
||||
guard(task_lock)(p);
|
||||
i = iterate_fd(p->files, 0, this_tty, tty);
|
||||
if (i != 0) {
|
||||
tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
|
||||
|
@ -3063,7 +3051,6 @@ void __do_SAK(struct tty_struct *tty)
|
|||
group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p,
|
||||
PIDTYPE_SID);
|
||||
}
|
||||
task_unlock(p);
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
put_pid(session);
|
||||
|
@ -3465,9 +3452,8 @@ int tty_register_driver(struct tty_driver *driver)
|
|||
goto err_unreg_char;
|
||||
}
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
list_add(&driver->tty_drivers, &tty_drivers);
|
||||
mutex_unlock(&tty_mutex);
|
||||
scoped_guard(mutex, &tty_mutex)
|
||||
list_add(&driver->tty_drivers, &tty_drivers);
|
||||
|
||||
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
|
||||
for (i = 0; i < driver->num; i++) {
|
||||
|
@ -3486,9 +3472,8 @@ err_unreg_devs:
|
|||
for (i--; i >= 0; i--)
|
||||
tty_unregister_device(driver, i);
|
||||
|
||||
mutex_lock(&tty_mutex);
|
||||
list_del(&driver->tty_drivers);
|
||||
mutex_unlock(&tty_mutex);
|
||||
scoped_guard(mutex, &tty_mutex)
|
||||
list_del(&driver->tty_drivers);
|
||||
|
||||
err_unreg_char:
|
||||
unregister_chrdev_region(dev, driver->num);
|
||||
|
@ -3507,9 +3492,8 @@ void tty_unregister_driver(struct tty_driver *driver)
|
|||
{
|
||||
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
|
||||
driver->num);
|
||||
mutex_lock(&tty_mutex);
|
||||
list_del(&driver->tty_drivers);
|
||||
mutex_unlock(&tty_mutex);
|
||||
scoped_guard(mutex, &tty_mutex)
|
||||
list_del(&driver->tty_drivers);
|
||||
}
|
||||
EXPORT_SYMBOL(tty_unregister_driver);
|
||||
|
||||
|
|
|
@ -122,21 +122,19 @@ EXPORT_SYMBOL(tty_unthrottle);
|
|||
*/
|
||||
bool tty_throttle_safe(struct tty_struct *tty)
|
||||
{
|
||||
bool ret = true;
|
||||
guard(mutex)(&tty->throttle_mutex);
|
||||
|
||||
mutex_lock(&tty->throttle_mutex);
|
||||
if (!tty_throttled(tty)) {
|
||||
if (tty->flow_change != TTY_THROTTLE_SAFE)
|
||||
ret = false;
|
||||
else {
|
||||
set_bit(TTY_THROTTLED, &tty->flags);
|
||||
if (tty->ops->throttle)
|
||||
tty->ops->throttle(tty);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&tty->throttle_mutex);
|
||||
if (tty_throttled(tty))
|
||||
return true;
|
||||
|
||||
return ret;
|
||||
if (tty->flow_change != TTY_THROTTLE_SAFE)
|
||||
return false;
|
||||
|
||||
set_bit(TTY_THROTTLED, &tty->flags);
|
||||
if (tty->ops->throttle)
|
||||
tty->ops->throttle(tty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,21 +150,19 @@ bool tty_throttle_safe(struct tty_struct *tty)
|
|||
*/
|
||||
bool tty_unthrottle_safe(struct tty_struct *tty)
|
||||
{
|
||||
bool ret = true;
|
||||
guard(mutex)(&tty->throttle_mutex);
|
||||
|
||||
mutex_lock(&tty->throttle_mutex);
|
||||
if (tty_throttled(tty)) {
|
||||
if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
|
||||
ret = false;
|
||||
else {
|
||||
clear_bit(TTY_THROTTLED, &tty->flags);
|
||||
if (tty->ops->unthrottle)
|
||||
tty->ops->unthrottle(tty);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&tty->throttle_mutex);
|
||||
if (!tty_throttled(tty))
|
||||
return true;
|
||||
|
||||
return ret;
|
||||
if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
|
||||
return false;
|
||||
|
||||
clear_bit(TTY_THROTTLED, &tty->flags);
|
||||
if (tty->ops->unthrottle)
|
||||
tty->ops->unthrottle(tty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -199,26 +199,6 @@ struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
|
||||
|
||||
/**
|
||||
* tty_port_register_device_serdev - register tty or serdev device
|
||||
* @port: tty_port of the device
|
||||
* @driver: tty_driver for this device
|
||||
* @index: index of the tty
|
||||
* @host: serial port hardware controller device
|
||||
* @parent: parent if exists, otherwise NULL
|
||||
*
|
||||
* Register a serdev or tty device depending on if the parent device has any
|
||||
* defined serdev clients or not.
|
||||
*/
|
||||
struct device *tty_port_register_device_serdev(struct tty_port *port,
|
||||
struct tty_driver *driver, unsigned index,
|
||||
struct device *host, struct device *parent)
|
||||
{
|
||||
return tty_port_register_device_attr_serdev(port, driver, index,
|
||||
host, parent, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
|
||||
|
||||
/**
|
||||
* tty_port_unregister_device - deregister a tty or serdev device
|
||||
* @port: tty_port of the device
|
||||
|
|
3
drivers/tty/vt/.gitignore
vendored
3
drivers/tty/vt/.gitignore
vendored
|
@ -2,3 +2,6 @@
|
|||
/conmakehash
|
||||
/consolemap_deftbl.c
|
||||
/defkeymap.c
|
||||
/ucs_fallback_table.h
|
||||
/ucs_recompose_table.h
|
||||
/ucs_width_table.h
|
||||
|
|
|
@ -7,10 +7,12 @@ FONTMAPFILE = cp437.uni
|
|||
obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o \
|
||||
selection.o keyboard.o \
|
||||
vt.o defkeymap.o
|
||||
obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o
|
||||
obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o \
|
||||
ucs.o
|
||||
|
||||
# Files generated that shall be removed upon make clean
|
||||
clean-files := consolemap_deftbl.c defkeymap.c
|
||||
clean-files := consolemap_deftbl.c defkeymap.c \
|
||||
ucs_width_table.h ucs_recompose_table.h ucs_fallback_table.h
|
||||
|
||||
hostprogs += conmakehash
|
||||
|
||||
|
@ -33,3 +35,31 @@ $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
|
|||
loadkeys --mktable --unicode $< > $@
|
||||
|
||||
endif
|
||||
|
||||
$(obj)/ucs.o: $(src)/ucs.c $(obj)/ucs_width_table.h \
|
||||
$(obj)/ucs_recompose_table.h $(obj)/ucs_fallback_table.h
|
||||
|
||||
# You may uncomment one of those to have the UCS tables be regenerated
|
||||
# during the build process. By default the _shipped versions are used.
|
||||
#
|
||||
#GENERATE_UCS_TABLES := 1
|
||||
#GENERATE_UCS_TABLES := 2 # invokes gen_ucs_recompose_table.py with --full
|
||||
|
||||
ifdef GENERATE_UCS_TABLES
|
||||
|
||||
$(obj)/ucs_width_table.h: $(src)/gen_ucs_width_table.py
|
||||
$(PYTHON3) $< -o $@
|
||||
|
||||
ifeq ($(GENERATE_UCS_TABLES),2)
|
||||
gen_recomp_arg := --full
|
||||
else
|
||||
gen_recomp_arg :=
|
||||
endif
|
||||
|
||||
$(obj)/ucs_recompose_table.h: $(src)/gen_ucs_recompose_table.py
|
||||
$(PYTHON3) $< -o $@ $(gen_recomp_arg)
|
||||
|
||||
$(obj)/ucs_fallback_table.h: $(src)/gen_ucs_fallback_table.py
|
||||
$(PYTHON3) $< -o $@
|
||||
|
||||
endif
|
||||
|
|
|
@ -870,8 +870,6 @@ int conv_uni_to_pc(struct vc_data *conp, long ucs)
|
|||
return -4; /* Not found */
|
||||
else if (ucs < 0x20)
|
||||
return -1; /* Not a printable character */
|
||||
else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
|
||||
return -2; /* Zero-width space */
|
||||
/*
|
||||
* UNI_DIRECT_BASE indicates the start of the region in the User Zone
|
||||
* which always has a 1:1 mapping to the currently loaded font. The
|
||||
|
|
360
drivers/tty/vt/gen_ucs_fallback_table.py
Executable file
360
drivers/tty/vt/gen_ucs_fallback_table.py
Executable file
|
@ -0,0 +1,360 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Leverage Python's unidecode module to generate ucs_fallback_table.h
|
||||
#
|
||||
# The generated table maps complex characters to their simpler fallback forms
|
||||
# for a terminal display when corresponding glyphs are unavailable.
|
||||
#
|
||||
# Usage:
|
||||
# python3 gen_ucs_fallback_table.py # Generate fallback tables
|
||||
# python3 gen_ucs_fallback_table.py -o FILE # Specify output file
|
||||
|
||||
import unicodedata
|
||||
from unidecode import unidecode
|
||||
import sys
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
|
||||
# Try to get unidecode version
|
||||
try:
|
||||
from importlib.metadata import version
|
||||
unidecode_version = version('unidecode')
|
||||
except:
|
||||
unidecode_version = 'unknown'
|
||||
|
||||
# This script's file name
|
||||
from pathlib import Path
|
||||
this_file = Path(__file__).name
|
||||
|
||||
# Default output file name
|
||||
DEFAULT_OUT_FILE = "ucs_fallback_table.h"
|
||||
|
||||
# Define the range marker value
|
||||
RANGE_MARKER = 0x00
|
||||
|
||||
def generate_fallback_map():
|
||||
"""Generate a fallback map using unidecode for all relevant Unicode points."""
|
||||
fallback_map = {}
|
||||
|
||||
# Process BMP characters (0x0000 - 0xFFFF) to keep table size manageable
|
||||
for cp in range(0x0080, 0x10000): # Skip ASCII range (0x00-0x7F)
|
||||
char = chr(cp)
|
||||
|
||||
# Skip unassigned/control characters
|
||||
try:
|
||||
if not unicodedata.name(char, ''):
|
||||
continue
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
# Get the unidecode transliteration
|
||||
ascii_version = unidecode(char)
|
||||
|
||||
# Only store if it results in a single character mapping
|
||||
if len(ascii_version) == 1:
|
||||
fallback_map[cp] = ord(ascii_version)
|
||||
|
||||
# Apply manual overrides for special cases
|
||||
fallback_map.update(get_special_overrides())
|
||||
|
||||
return fallback_map
|
||||
|
||||
def get_special_overrides():
|
||||
"""Get special case overrides that need different handling than unidecode
|
||||
provides... or doesn't provide at all."""
|
||||
|
||||
overrides = {}
|
||||
|
||||
# Multi-character unidecode output
|
||||
# These map to single chars instead of unidecode's multiple-char mappings
|
||||
# In a terminal fallback context, we need a single character rather than multiple
|
||||
overrides[0x00C6] = ord('E') # Æ LATIN CAPITAL LETTER AE -> E (unidecode: "AE")
|
||||
overrides[0x00E6] = ord('e') # æ LATIN SMALL LETTER AE -> e (unidecode: "ae")
|
||||
overrides[0x0152] = ord('E') # Œ LATIN CAPITAL LIGATURE OE -> E (unidecode: "OE")
|
||||
overrides[0x0153] = ord('e') # œ LATIN SMALL LETTER LIGATURE OE -> e (unidecode: "oe")
|
||||
overrides[0x00DF] = ord('s') # ß LATIN SMALL LETTER SHARP S -> s (unidecode: "ss")
|
||||
|
||||
# Comparison operators that unidecode renders as multiple characters
|
||||
overrides[0x2264] = ord('<') # ≤ LESS-THAN OR EQUAL TO -> < (unidecode: "<=")
|
||||
overrides[0x2265] = ord('>') # ≥ GREATER-THAN OR EQUAL TO -> > (unidecode: ">=")
|
||||
|
||||
# Unidecode returns an empty string for these
|
||||
overrides[0x2260] = ord('#') # ≠ NOT EQUAL TO -> # (unidecode: empty string)
|
||||
|
||||
# Quadrant block characters that unidecode doesn't map
|
||||
for cp in range(0x2596, 0x259F+1):
|
||||
overrides[cp] = ord('#') # ▖ ▗ ▘ ▙ etc. - map to # (unidecode: empty string)
|
||||
|
||||
# Directional arrows
|
||||
# These provide better semantic meaning than unidecode's mappings
|
||||
overrides[0x2192] = ord('>') # → RIGHTWARDS ARROW -> > (unidecode: "-")
|
||||
overrides[0x2190] = ord('<') # ← LEFTWARDS ARROW -> < (unidecode: "-")
|
||||
overrides[0x2191] = ord('^') # ↑ UPWARDS ARROW -> ^ (unidecode: "|")
|
||||
overrides[0x2193] = ord('v') # ↓ DOWNWARDS ARROW -> v (unidecode: "|")
|
||||
|
||||
# Double arrows with their directional semantic mappings
|
||||
overrides[0x21D0] = ord('<') # ⇐ LEFTWARDS DOUBLE ARROW -> <
|
||||
overrides[0x21D1] = ord('^') # ⇑ UPWARDS DOUBLE ARROW -> ^
|
||||
overrides[0x21D2] = ord('>') # ⇒ RIGHTWARDS DOUBLE ARROW -> >
|
||||
overrides[0x21D3] = ord('v') # ⇓ DOWNWARDS DOUBLE ARROW -> v
|
||||
|
||||
# Halfwidth arrows
|
||||
# These need the same treatment as their normal-width counterparts
|
||||
overrides[0xFFE9] = ord('<') # ← HALFWIDTH LEFTWARDS ARROW -> < (unidecode: "-")
|
||||
overrides[0xFFEA] = ord('^') # ↑ HALFWIDTH UPWARDS ARROW -> ^ (unidecode: "|")
|
||||
overrides[0xFFEB] = ord('>') # → HALFWIDTH RIGHTWARDS ARROW -> > (unidecode: "-")
|
||||
overrides[0xFFEC] = ord('v') # ↓ HALFWIDTH DOWNWARDS ARROW -> v (unidecode: "|")
|
||||
|
||||
# Currency symbols - each mapped to a representative letter
|
||||
overrides[0x00A2] = ord('c') # ¢ CENT SIGN -> c
|
||||
overrides[0x00A3] = ord('L') # £ POUND SIGN -> L
|
||||
overrides[0x00A5] = ord('Y') # ¥ YEN SIGN -> Y
|
||||
overrides[0x20AC] = ord('E') # € EURO SIGN -> E
|
||||
|
||||
# Symbols mapped to letters
|
||||
overrides[0x00A7] = ord('S') # § SECTION SIGN -> S
|
||||
overrides[0x00A9] = ord('C') # © COPYRIGHT SIGN -> C
|
||||
overrides[0x00AE] = ord('R') # ® REGISTERED SIGN -> R
|
||||
overrides[0x2122] = ord('T') # ™ TRADE MARK SIGN -> T
|
||||
|
||||
# Degree-related symbols
|
||||
overrides[0x00B0] = ord('o') # ° DEGREE SIGN -> o
|
||||
overrides[0x2103] = ord('C') # ℃ DEGREE CELSIUS -> C
|
||||
overrides[0x2109] = ord('F') # ℉ DEGREE FAHRENHEIT -> F
|
||||
|
||||
# Angle quotation marks
|
||||
overrides[0x00AB] = ord('<') # « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -> <
|
||||
overrides[0x00BB] = ord('>') # » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -> >
|
||||
|
||||
# Operators with circular shape
|
||||
overrides[0x2218] = ord('o') # ∘ RING OPERATOR -> o
|
||||
overrides[0x2219] = ord('.') # ∙ BULLET OPERATOR -> .
|
||||
|
||||
# Negated mathematical symbols (preserving the negation semantics)
|
||||
# Negated symbols mapped to exclamation mark (semantically "not")
|
||||
for cp in (0x2204, 0x2209, 0x220C, 0x2224, 0x2226, 0x226E, 0x226F, 0x2280, 0x2281, 0x2284, 0x2285):
|
||||
overrides[cp] = ord('!') # Negated math symbols -> ! (not)
|
||||
|
||||
# Negated symbols mapped to hash sign (semantically "not equal")
|
||||
for cp in (0x2241, 0x2244, 0x2249, 0x2262, 0x2268, 0x2269, 0x226D, 0x228A, 0x228B):
|
||||
overrides[cp] = ord('#') # Negated equality symbols -> # (not equal)
|
||||
|
||||
# Negated arrows - all mapped to exclamation mark
|
||||
for cp in (0x219A, 0x219B, 0x21AE, 0x21CD, 0x21CE, 0x21CF):
|
||||
overrides[cp] = ord('!') # Negated arrows -> ! (not)
|
||||
|
||||
# Dashes and hyphens
|
||||
for cp in (0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2043, 0x2052):
|
||||
overrides[cp] = ord('-') # Dashes and hyphens -> -
|
||||
|
||||
# Question mark punctuation
|
||||
for cp in (0x203D, 0x2047, 0x2048):
|
||||
overrides[cp] = ord('?') # Question marks -> ?
|
||||
|
||||
# Exclamation mark punctuation
|
||||
for cp in (0x203C, 0x2049):
|
||||
overrides[cp] = ord('!') # Exclamation marks -> !
|
||||
|
||||
# Asterisk-like symbols
|
||||
for cp in (0x2042, 0x2051, 0x2055):
|
||||
overrides[cp] = ord('*')
|
||||
|
||||
# Other specific punctuation with unique mappings
|
||||
overrides[0x201E] = ord('"') # „ DOUBLE LOW-9 QUOTATION MARK
|
||||
overrides[0x2023] = ord('>') # ‣ TRIANGULAR BULLET
|
||||
overrides[0x2026] = ord('.') # … HORIZONTAL ELLIPSIS
|
||||
overrides[0x2033] = ord('"') # ″ DOUBLE PRIME
|
||||
overrides[0x204B] = ord('P') # ⁋ REVERSED PILCROW SIGN
|
||||
overrides[0x204C] = ord('<') # ⁌ BLACK LEFTWARDS BULLET
|
||||
overrides[0x204D] = ord('>') # ⁍ BLACK RIGHTWARDS BULLET
|
||||
overrides[0x204F] = ord(';') # ⁏ REVERSED SEMICOLON
|
||||
overrides[0x205B] = ord(':') # ⁛ FOUR DOT MARK
|
||||
|
||||
# Check marks
|
||||
overrides[0x2713] = ord('v') # ✓ CHECK MARK
|
||||
overrides[0x2714] = ord('V') # ✔ HEAVY CHECK MARK
|
||||
|
||||
# X marks - lowercase for regular, uppercase for heavy
|
||||
for cp in (0x2715, 0x2717):
|
||||
overrides[cp] = ord('x') # Regular X marks -> x
|
||||
for cp in (0x2716, 0x2718):
|
||||
overrides[cp] = ord('X') # Heavy X marks -> X
|
||||
|
||||
# Stars and asterisk-like symbols mapped to '*'
|
||||
for cp in (0x2605, 0x2606, 0x262A, 0x269D, 0x2698):
|
||||
overrides[cp] = ord('*') # All star and asterisk symbols -> *
|
||||
for cp in range(0x2721, 0x2746+1):
|
||||
overrides[cp] = ord('*') # All star and asterisk symbols -> *
|
||||
for cp in range(0x2749, 0x274B+1):
|
||||
overrides[cp] = ord('*') # Last set of asterisk symbols -> *
|
||||
for cp in (0x229B, 0x22C6, 0x235F, 0x2363):
|
||||
overrides[cp] = ord('*') # Star operators -> *
|
||||
|
||||
# Special exclusions with fallback value of 0
|
||||
# These will be filtered out in organize_by_pages()
|
||||
|
||||
# Exclude U+2028 (LINE SEPARATOR)
|
||||
overrides[0x2028] = 0 # LINE SEPARATOR (unidecode: '\n')
|
||||
|
||||
# Full-width to ASCII mapping (covering all printable ASCII 33-126)
|
||||
# 0xFF01 (!) to 0xFF5E (~) -> ASCII 33 (!) to 126 (~)
|
||||
# Those are excluded here to reduce the table size.
|
||||
# It is more efficient to process them programmatically in
|
||||
# ucs.c:ucs_get_fallback().
|
||||
for cp in range(0xFF01, 0xFF5E + 1):
|
||||
overrides[cp] = 0 # Double-width ASCII characters
|
||||
|
||||
return overrides
|
||||
|
||||
def organize_by_pages(fallback_map):
|
||||
"""Organize the fallback mappings by their high byte (page)."""
|
||||
# Group by high byte (page)
|
||||
page_groups = defaultdict(list)
|
||||
for code, fallback in fallback_map.items():
|
||||
# Skip characters with fallback value of 0 (excluded characters)
|
||||
if fallback == 0:
|
||||
continue
|
||||
|
||||
page = code >> 8 # Get the high byte (page)
|
||||
offset = code & 0xFF # Get the low byte (offset within page)
|
||||
page_groups[page].append((offset, fallback))
|
||||
|
||||
# Sort each page's entries by offset
|
||||
for page in page_groups:
|
||||
page_groups[page].sort()
|
||||
|
||||
return page_groups
|
||||
|
||||
def compress_ranges(page_groups):
|
||||
"""Compress consecutive entries with the same fallback character into ranges.
|
||||
A range is only compressed if it contains 3 or more consecutive entries."""
|
||||
|
||||
compressed_pages = {}
|
||||
|
||||
for page, entries in page_groups.items():
|
||||
compressed_entries = []
|
||||
i = 0
|
||||
while i < len(entries):
|
||||
start_offset, fallback = entries[i]
|
||||
|
||||
# Look ahead to find consecutive entries with the same fallback
|
||||
j = i + 1
|
||||
while (j < len(entries) and
|
||||
entries[j][0] == entries[j-1][0] + 1 and # consecutive offsets
|
||||
entries[j][1] == fallback): # same fallback
|
||||
j += 1
|
||||
|
||||
# Calculate the range end
|
||||
end_offset = entries[j-1][0]
|
||||
|
||||
# If we found a range with 3 or more entries (worth compressing)
|
||||
if j - i >= 3:
|
||||
# Add a range entry
|
||||
compressed_entries.append((start_offset, RANGE_MARKER))
|
||||
compressed_entries.append((end_offset, fallback))
|
||||
else:
|
||||
# Add the individual entries as is
|
||||
for k in range(i, j):
|
||||
compressed_entries.append(entries[k])
|
||||
|
||||
i = j
|
||||
|
||||
compressed_pages[page] = compressed_entries
|
||||
|
||||
return compressed_pages
|
||||
|
||||
def cp_name(cp):
|
||||
"""Get the Unicode character name for a code point."""
|
||||
try:
|
||||
return unicodedata.name(chr(cp))
|
||||
except:
|
||||
return f"U+{cp:04X}"
|
||||
|
||||
def generate_fallback_tables(out_file=DEFAULT_OUT_FILE):
|
||||
"""Generate the fallback character tables."""
|
||||
# Generate fallback map using unidecode
|
||||
fallback_map = generate_fallback_map()
|
||||
print(f"Generated {len(fallback_map)} total fallback mappings")
|
||||
|
||||
# Organize by pages
|
||||
page_groups = organize_by_pages(fallback_map)
|
||||
print(f"Organized into {len(page_groups)} pages")
|
||||
|
||||
# Compress ranges
|
||||
compressed_pages = compress_ranges(page_groups)
|
||||
total_compressed_entries = sum(len(entries) for entries in compressed_pages.values())
|
||||
print(f"Total compressed entries: {total_compressed_entries}")
|
||||
|
||||
# Create output file
|
||||
with open(out_file, 'w') as f:
|
||||
f.write(f"""\
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* {out_file} - Unicode character fallback table
|
||||
*
|
||||
* Auto-generated by {this_file}
|
||||
*
|
||||
* Unicode Version: {unicodedata.unidata_version}
|
||||
* Unidecode Version: {unidecode_version}
|
||||
*
|
||||
* This file contains optimized tables that map complex Unicode characters
|
||||
* to simpler fallback characters for terminal display when corresponding
|
||||
* glyphs are unavailable.
|
||||
*/
|
||||
|
||||
static const struct ucs_page_desc ucs_fallback_pages[] = {{
|
||||
""")
|
||||
|
||||
# Convert compressed_pages to a sorted list of (page, entries) tuples
|
||||
sorted_pages = sorted(compressed_pages.items())
|
||||
|
||||
# Track the start index for each page
|
||||
start_index = 0
|
||||
|
||||
# Write page descriptors
|
||||
for page, entries in sorted_pages:
|
||||
count = len(entries)
|
||||
f.write(f"\t{{ 0x{page:02X}, {count}, {start_index} }},\n")
|
||||
start_index += count
|
||||
|
||||
# Write entries array
|
||||
f.write("""\
|
||||
};
|
||||
|
||||
/* Page entries array (referenced by page descriptors) */
|
||||
static const struct ucs_page_entry ucs_fallback_entries[] = {
|
||||
""")
|
||||
|
||||
# Write all entries
|
||||
for page, entries in sorted_pages:
|
||||
page_hex = f"0x{page:02X}"
|
||||
f.write(f"\t/* Entries for page {page_hex} */\n")
|
||||
|
||||
for i, (offset, fallback) in enumerate(entries):
|
||||
# Convert to hex for better readability
|
||||
offset_hex = f"0x{offset:02X}"
|
||||
fallback_hex = f"0x{fallback:02X}"
|
||||
|
||||
# Handle comments
|
||||
codepoint = (page << 8) | offset
|
||||
|
||||
if fallback == RANGE_MARKER:
|
||||
comment = f"{cp_name(codepoint)} -> ..."
|
||||
else:
|
||||
comment = f"{cp_name(codepoint)} -> '{chr(fallback)}'"
|
||||
f.write(f"\t{{ 0x{offset:02X}, 0x{fallback:02X} }}, /* {comment} */\n")
|
||||
|
||||
f.write(f"""\
|
||||
}};
|
||||
|
||||
#define UCS_PAGE_ENTRY_RANGE_MARKER {RANGE_MARKER}
|
||||
""")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate Unicode fallback character tables")
|
||||
parser.add_argument("-o", "--output", dest="output_file", default=DEFAULT_OUT_FILE,
|
||||
help=f"Output file name (default: {DEFAULT_OUT_FILE})")
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_fallback_tables(out_file=args.output_file)
|
257
drivers/tty/vt/gen_ucs_recompose_table.py
Executable file
257
drivers/tty/vt/gen_ucs_recompose_table.py
Executable file
|
@ -0,0 +1,257 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Leverage Python's unicodedata module to generate ucs_recompose_table.h
|
||||
#
|
||||
# The generated table maps base character + combining mark pairs to their
|
||||
# precomposed equivalents.
|
||||
#
|
||||
# Usage:
|
||||
# python3 gen_ucs_recompose_table.py # Generate with common recomposition pairs
|
||||
# python3 gen_ucs_recompose_table.py --full # Generate with all recomposition pairs
|
||||
|
||||
import unicodedata
|
||||
import sys
|
||||
import argparse
|
||||
import textwrap
|
||||
|
||||
# This script's file name
|
||||
from pathlib import Path
|
||||
this_file = Path(__file__).name
|
||||
|
||||
# Default output file name
|
||||
DEFAULT_OUT_FILE = "ucs_recompose_table.h"
|
||||
|
||||
common_recompose_description = "most commonly used Latin, Greek, and Cyrillic recomposition pairs only"
|
||||
COMMON_RECOMPOSITION_PAIRS = [
|
||||
# Latin letters with accents - uppercase
|
||||
(0x0041, 0x0300, 0x00C0), # A + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER A WITH GRAVE
|
||||
(0x0041, 0x0301, 0x00C1), # A + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER A WITH ACUTE
|
||||
(0x0041, 0x0302, 0x00C2), # A + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
(0x0041, 0x0303, 0x00C3), # A + COMBINING TILDE = LATIN CAPITAL LETTER A WITH TILDE
|
||||
(0x0041, 0x0308, 0x00C4), # A + COMBINING DIAERESIS = LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
(0x0041, 0x030A, 0x00C5), # A + COMBINING RING ABOVE = LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||
(0x0043, 0x0327, 0x00C7), # C + COMBINING CEDILLA = LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
(0x0045, 0x0300, 0x00C8), # E + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER E WITH GRAVE
|
||||
(0x0045, 0x0301, 0x00C9), # E + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER E WITH ACUTE
|
||||
(0x0045, 0x0302, 0x00CA), # E + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||
(0x0045, 0x0308, 0x00CB), # E + COMBINING DIAERESIS = LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||
(0x0049, 0x0300, 0x00CC), # I + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER I WITH GRAVE
|
||||
(0x0049, 0x0301, 0x00CD), # I + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER I WITH ACUTE
|
||||
(0x0049, 0x0302, 0x00CE), # I + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
(0x0049, 0x0308, 0x00CF), # I + COMBINING DIAERESIS = LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||
(0x004E, 0x0303, 0x00D1), # N + COMBINING TILDE = LATIN CAPITAL LETTER N WITH TILDE
|
||||
(0x004F, 0x0300, 0x00D2), # O + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER O WITH GRAVE
|
||||
(0x004F, 0x0301, 0x00D3), # O + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER O WITH ACUTE
|
||||
(0x004F, 0x0302, 0x00D4), # O + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
(0x004F, 0x0303, 0x00D5), # O + COMBINING TILDE = LATIN CAPITAL LETTER O WITH TILDE
|
||||
(0x004F, 0x0308, 0x00D6), # O + COMBINING DIAERESIS = LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
(0x0055, 0x0300, 0x00D9), # U + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER U WITH GRAVE
|
||||
(0x0055, 0x0301, 0x00DA), # U + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER U WITH ACUTE
|
||||
(0x0055, 0x0302, 0x00DB), # U + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||
(0x0055, 0x0308, 0x00DC), # U + COMBINING DIAERESIS = LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
(0x0059, 0x0301, 0x00DD), # Y + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER Y WITH ACUTE
|
||||
|
||||
# Latin letters with accents - lowercase
|
||||
(0x0061, 0x0300, 0x00E0), # a + COMBINING GRAVE ACCENT = LATIN SMALL LETTER A WITH GRAVE
|
||||
(0x0061, 0x0301, 0x00E1), # a + COMBINING ACUTE ACCENT = LATIN SMALL LETTER A WITH ACUTE
|
||||
(0x0061, 0x0302, 0x00E2), # a + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
(0x0061, 0x0303, 0x00E3), # a + COMBINING TILDE = LATIN SMALL LETTER A WITH TILDE
|
||||
(0x0061, 0x0308, 0x00E4), # a + COMBINING DIAERESIS = LATIN SMALL LETTER A WITH DIAERESIS
|
||||
(0x0061, 0x030A, 0x00E5), # a + COMBINING RING ABOVE = LATIN SMALL LETTER A WITH RING ABOVE
|
||||
(0x0063, 0x0327, 0x00E7), # c + COMBINING CEDILLA = LATIN SMALL LETTER C WITH CEDILLA
|
||||
(0x0065, 0x0300, 0x00E8), # e + COMBINING GRAVE ACCENT = LATIN SMALL LETTER E WITH GRAVE
|
||||
(0x0065, 0x0301, 0x00E9), # e + COMBINING ACUTE ACCENT = LATIN SMALL LETTER E WITH ACUTE
|
||||
(0x0065, 0x0302, 0x00EA), # e + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||
(0x0065, 0x0308, 0x00EB), # e + COMBINING DIAERESIS = LATIN SMALL LETTER E WITH DIAERESIS
|
||||
(0x0069, 0x0300, 0x00EC), # i + COMBINING GRAVE ACCENT = LATIN SMALL LETTER I WITH GRAVE
|
||||
(0x0069, 0x0301, 0x00ED), # i + COMBINING ACUTE ACCENT = LATIN SMALL LETTER I WITH ACUTE
|
||||
(0x0069, 0x0302, 0x00EE), # i + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
(0x0069, 0x0308, 0x00EF), # i + COMBINING DIAERESIS = LATIN SMALL LETTER I WITH DIAERESIS
|
||||
(0x006E, 0x0303, 0x00F1), # n + COMBINING TILDE = LATIN SMALL LETTER N WITH TILDE
|
||||
(0x006F, 0x0300, 0x00F2), # o + COMBINING GRAVE ACCENT = LATIN SMALL LETTER O WITH GRAVE
|
||||
(0x006F, 0x0301, 0x00F3), # o + COMBINING ACUTE ACCENT = LATIN SMALL LETTER O WITH ACUTE
|
||||
(0x006F, 0x0302, 0x00F4), # o + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
(0x006F, 0x0303, 0x00F5), # o + COMBINING TILDE = LATIN SMALL LETTER O WITH TILDE
|
||||
(0x006F, 0x0308, 0x00F6), # o + COMBINING DIAERESIS = LATIN SMALL LETTER O WITH DIAERESIS
|
||||
(0x0075, 0x0300, 0x00F9), # u + COMBINING GRAVE ACCENT = LATIN SMALL LETTER U WITH GRAVE
|
||||
(0x0075, 0x0301, 0x00FA), # u + COMBINING ACUTE ACCENT = LATIN SMALL LETTER U WITH ACUTE
|
||||
(0x0075, 0x0302, 0x00FB), # u + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||
(0x0075, 0x0308, 0x00FC), # u + COMBINING DIAERESIS = LATIN SMALL LETTER U WITH DIAERESIS
|
||||
(0x0079, 0x0301, 0x00FD), # y + COMBINING ACUTE ACCENT = LATIN SMALL LETTER Y WITH ACUTE
|
||||
(0x0079, 0x0308, 0x00FF), # y + COMBINING DIAERESIS = LATIN SMALL LETTER Y WITH DIAERESIS
|
||||
|
||||
# Common Greek characters
|
||||
(0x0391, 0x0301, 0x0386), # Α + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ALPHA WITH TONOS
|
||||
(0x0395, 0x0301, 0x0388), # Ε + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER EPSILON WITH TONOS
|
||||
(0x0397, 0x0301, 0x0389), # Η + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ETA WITH TONOS
|
||||
(0x0399, 0x0301, 0x038A), # Ι + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER IOTA WITH TONOS
|
||||
(0x039F, 0x0301, 0x038C), # Ο + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMICRON WITH TONOS
|
||||
(0x03A5, 0x0301, 0x038E), # Υ + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER UPSILON WITH TONOS
|
||||
(0x03A9, 0x0301, 0x038F), # Ω + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMEGA WITH TONOS
|
||||
(0x03B1, 0x0301, 0x03AC), # α + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ALPHA WITH TONOS
|
||||
(0x03B5, 0x0301, 0x03AD), # ε + COMBINING ACUTE ACCENT = GREEK SMALL LETTER EPSILON WITH TONOS
|
||||
(0x03B7, 0x0301, 0x03AE), # η + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ETA WITH TONOS
|
||||
(0x03B9, 0x0301, 0x03AF), # ι + COMBINING ACUTE ACCENT = GREEK SMALL LETTER IOTA WITH TONOS
|
||||
(0x03BF, 0x0301, 0x03CC), # ο + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMICRON WITH TONOS
|
||||
(0x03C5, 0x0301, 0x03CD), # υ + COMBINING ACUTE ACCENT = GREEK SMALL LETTER UPSILON WITH TONOS
|
||||
(0x03C9, 0x0301, 0x03CE), # ω + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMEGA WITH TONOS
|
||||
|
||||
# Common Cyrillic characters
|
||||
(0x0418, 0x0306, 0x0419), # И + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT I
|
||||
(0x0438, 0x0306, 0x0439), # и + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT I
|
||||
(0x0423, 0x0306, 0x040E), # У + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT U
|
||||
(0x0443, 0x0306, 0x045E), # у + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT U
|
||||
]
|
||||
|
||||
full_recompose_description = "all possible recomposition pairs from the Unicode BMP"
|
||||
def collect_all_recomposition_pairs():
|
||||
"""Collect all possible recomposition pairs from the Unicode data."""
|
||||
# Map to store recomposition pairs: (base, combining) -> recomposed
|
||||
recompose_map = {}
|
||||
|
||||
# Process all assigned Unicode code points in BMP (Basic Multilingual Plane)
|
||||
# We limit to BMP (0x0000-0xFFFF) to keep our table smaller with uint16_t
|
||||
for cp in range(0, 0x10000):
|
||||
try:
|
||||
char = chr(cp)
|
||||
|
||||
# Skip unassigned or control characters
|
||||
if not unicodedata.name(char, ''):
|
||||
continue
|
||||
|
||||
# Find decomposition
|
||||
decomp = unicodedata.decomposition(char)
|
||||
if not decomp or '<' in decomp: # Skip compatibility decompositions
|
||||
continue
|
||||
|
||||
# Parse the decomposition
|
||||
parts = decomp.split()
|
||||
if len(parts) == 2: # Simple base + combining mark
|
||||
base = int(parts[0], 16)
|
||||
combining = int(parts[1], 16)
|
||||
|
||||
# Only store if both are in BMP
|
||||
if base < 0x10000 and combining < 0x10000:
|
||||
recompose_map[(base, combining)] = cp
|
||||
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
|
||||
# Convert to a list of tuples and sort for binary search
|
||||
recompose_list = [(base, combining, recomposed)
|
||||
for (base, combining), recomposed in recompose_map.items()]
|
||||
recompose_list.sort()
|
||||
|
||||
return recompose_list
|
||||
|
||||
def validate_common_pairs(full_list):
|
||||
"""Validate that all common pairs are in the full list.
|
||||
|
||||
Raises:
|
||||
ValueError: If any common pair is missing or has a different recomposition
|
||||
value than what's in the full table.
|
||||
"""
|
||||
full_pairs = {(base, combining): recomposed for base, combining, recomposed in full_list}
|
||||
for base, combining, recomposed in COMMON_RECOMPOSITION_PAIRS:
|
||||
full_recomposed = full_pairs.get((base, combining))
|
||||
if full_recomposed is None:
|
||||
error_msg = f"Error: Common pair (0x{base:04X}, 0x{combining:04X}) not found in full data"
|
||||
print(error_msg)
|
||||
raise ValueError(error_msg)
|
||||
elif full_recomposed != recomposed:
|
||||
error_msg = (f"Error: Common pair (0x{base:04X}, 0x{combining:04X}) has different recomposition: "
|
||||
f"0x{recomposed:04X} vs 0x{full_recomposed:04X}")
|
||||
print(error_msg)
|
||||
raise ValueError(error_msg)
|
||||
|
||||
def generate_recomposition_table(use_full_list=False, out_file=DEFAULT_OUT_FILE):
|
||||
"""Generate the recomposition C table."""
|
||||
|
||||
# Collect all recomposition pairs for validation
|
||||
full_recompose_list = collect_all_recomposition_pairs()
|
||||
|
||||
# Decide which list to use
|
||||
if use_full_list:
|
||||
print("Using full recomposition list...")
|
||||
recompose_list = full_recompose_list
|
||||
table_description = full_recompose_description
|
||||
alt_list = COMMON_RECOMPOSITION_PAIRS
|
||||
alt_description = common_recompose_description
|
||||
else:
|
||||
print("Using common recomposition list...")
|
||||
# Validate that all common pairs are in the full list
|
||||
validate_common_pairs(full_recompose_list)
|
||||
recompose_list = sorted(COMMON_RECOMPOSITION_PAIRS)
|
||||
table_description = common_recompose_description
|
||||
alt_list = full_recompose_list
|
||||
alt_description = full_recompose_description
|
||||
generation_mode = " --full" if use_full_list else ""
|
||||
alternative_mode = " --full" if not use_full_list else ""
|
||||
table_description_detail = f"{table_description} ({len(recompose_list)} entries)"
|
||||
alt_description_detail = f"{alt_description} ({len(alt_list)} entries)"
|
||||
|
||||
# Calculate min/max values for boundary checks
|
||||
min_base = min(base for base, _, _ in recompose_list)
|
||||
max_base = max(base for base, _, _ in recompose_list)
|
||||
min_combining = min(combining for _, combining, _ in recompose_list)
|
||||
max_combining = max(combining for _, combining, _ in recompose_list)
|
||||
|
||||
# Generate implementation file
|
||||
with open(out_file, 'w') as f:
|
||||
f.write(f"""\
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* {out_file} - Unicode character recomposition
|
||||
*
|
||||
* Auto-generated by {this_file}{generation_mode}
|
||||
*
|
||||
* Unicode Version: {unicodedata.unidata_version}
|
||||
*
|
||||
{textwrap.fill(
|
||||
f"This file contains a table with {table_description_detail}. " +
|
||||
f"To generate a table with {alt_description_detail} instead, run:",
|
||||
width=75, initial_indent=" * ", subsequent_indent=" * ")}
|
||||
*
|
||||
* python3 {this_file}{alternative_mode}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Table of {table_description}
|
||||
* Sorted by base character and then combining mark for binary search
|
||||
*/
|
||||
static const struct ucs_recomposition ucs_recomposition_table[] = {{
|
||||
""")
|
||||
|
||||
for base, combining, recomposed in recompose_list:
|
||||
try:
|
||||
base_name = unicodedata.name(chr(base))
|
||||
combining_name = unicodedata.name(chr(combining))
|
||||
recomposed_name = unicodedata.name(chr(recomposed))
|
||||
comment = f"/* {base_name} + {combining_name} = {recomposed_name} */"
|
||||
except ValueError:
|
||||
comment = f"/* U+{base:04X} + U+{combining:04X} = U+{recomposed:04X} */"
|
||||
f.write(f"\t{{ 0x{base:04X}, 0x{combining:04X}, 0x{recomposed:04X} }}, {comment}\n")
|
||||
|
||||
f.write(f"""\
|
||||
}};
|
||||
|
||||
/*
|
||||
* Boundary values for quick rejection
|
||||
* These are calculated by analyzing the table during generation
|
||||
*/
|
||||
#define UCS_RECOMPOSE_MIN_BASE 0x{min_base:04X}
|
||||
#define UCS_RECOMPOSE_MAX_BASE 0x{max_base:04X}
|
||||
#define UCS_RECOMPOSE_MIN_MARK 0x{min_combining:04X}
|
||||
#define UCS_RECOMPOSE_MAX_MARK 0x{max_combining:04X}
|
||||
""")
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate Unicode recomposition table")
|
||||
parser.add_argument("--full", action="store_true",
|
||||
help="Generate a full recomposition table (default: common pairs only)")
|
||||
parser.add_argument("-o", "--output", dest="output_file", default=DEFAULT_OUT_FILE,
|
||||
help=f"Output file name (default: {DEFAULT_OUT_FILE})")
|
||||
args = parser.parse_args()
|
||||
|
||||
generate_recomposition_table(use_full_list=args.full, out_file=args.output_file)
|
307
drivers/tty/vt/gen_ucs_width_table.py
Executable file
307
drivers/tty/vt/gen_ucs_width_table.py
Executable file
|
@ -0,0 +1,307 @@
|
|||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Leverage Python's unicodedata module to generate ucs_width_table.h
|
||||
|
||||
import unicodedata
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
# This script's file name
|
||||
from pathlib import Path
|
||||
this_file = Path(__file__).name
|
||||
|
||||
# Default output file name
|
||||
DEFAULT_OUT_FILE = "ucs_width_table.h"
|
||||
|
||||
# --- Global Constants for Width Assignments ---
|
||||
|
||||
# Known zero-width characters
|
||||
KNOWN_ZERO_WIDTH = (
|
||||
0x200B, # ZERO WIDTH SPACE
|
||||
0x200C, # ZERO WIDTH NON-JOINER
|
||||
0x200D, # ZERO WIDTH JOINER
|
||||
0x2060, # WORD JOINER
|
||||
0xFEFF # ZERO WIDTH NO-BREAK SPACE (BOM)
|
||||
)
|
||||
|
||||
# Zero-width emoji modifiers and components
|
||||
# NOTE: Some of these characters would normally be single-width according to
|
||||
# East Asian Width properties, but we deliberately override them to be
|
||||
# zero-width because they function as modifiers in emoji sequences.
|
||||
EMOJI_ZERO_WIDTH = [
|
||||
# Skin tone modifiers
|
||||
(0x1F3FB, 0x1F3FF), # Emoji modifiers (skin tones)
|
||||
|
||||
# Variation selectors (note: VS16 is treated specially in vt.c)
|
||||
(0xFE00, 0xFE0F), # Variation Selectors 1-16
|
||||
|
||||
# Gender and hair style modifiers
|
||||
# These would be single-width by Unicode properties, but are zero-width
|
||||
# when part of emoji
|
||||
(0x2640, 0x2640), # Female sign
|
||||
(0x2642, 0x2642), # Male sign
|
||||
(0x26A7, 0x26A7), # Transgender symbol
|
||||
(0x1F9B0, 0x1F9B3), # Hair components (red, curly, white, bald)
|
||||
|
||||
# Tag characters
|
||||
(0xE0020, 0xE007E), # Tags
|
||||
]
|
||||
|
||||
# Regional indicators (flag components)
|
||||
REGIONAL_INDICATORS = (0x1F1E6, 0x1F1FF) # Regional indicator symbols A-Z
|
||||
|
||||
# Double-width emoji ranges
|
||||
#
|
||||
# Many emoji characters are classified as single-width according to Unicode
|
||||
# Standard Annex #11 East Asian Width property (N or Neutral), but we
|
||||
# deliberately override them to be double-width. References:
|
||||
# 1. Unicode Technical Standard #51: Unicode Emoji
|
||||
# (https://www.unicode.org/reports/tr51/)
|
||||
# 2. Principle of "emoji presentation" in WHATWG CSS Text specification
|
||||
# (https://drafts.csswg.org/css-text-3/#character-properties)
|
||||
# 3. Terminal emulator implementations (iTerm2, Windows Terminal, etc.) which
|
||||
# universally render emoji as double-width characters regardless of their
|
||||
# Unicode EAW property
|
||||
# 4. W3C Work Item: Requirements for Japanese Text Layout - Section 3.8.1
|
||||
# Emoji width (https://www.w3.org/TR/jlreq/)
|
||||
EMOJI_RANGES = [
|
||||
(0x1F000, 0x1F02F), # Mahjong Tiles (EAW: N, but displayed as double-width)
|
||||
(0x1F0A0, 0x1F0FF), # Playing Cards (EAW: N, but displayed as double-width)
|
||||
(0x1F300, 0x1F5FF), # Miscellaneous Symbols and Pictographs
|
||||
(0x1F600, 0x1F64F), # Emoticons
|
||||
(0x1F680, 0x1F6FF), # Transport and Map Symbols
|
||||
(0x1F700, 0x1F77F), # Alchemical Symbols
|
||||
(0x1F780, 0x1F7FF), # Geometric Shapes Extended
|
||||
(0x1F800, 0x1F8FF), # Supplemental Arrows-C
|
||||
(0x1F900, 0x1F9FF), # Supplemental Symbols and Pictographs
|
||||
(0x1FA00, 0x1FA6F), # Chess Symbols
|
||||
(0x1FA70, 0x1FAFF), # Symbols and Pictographs Extended-A
|
||||
]
|
||||
|
||||
def create_width_tables():
|
||||
"""
|
||||
Creates Unicode character width tables and returns the data structures.
|
||||
|
||||
Returns:
|
||||
tuple: (zero_width_ranges, double_width_ranges)
|
||||
"""
|
||||
|
||||
# Width data mapping
|
||||
width_map = {} # Maps code points to width (0, 1, 2)
|
||||
|
||||
# Mark emoji modifiers as zero-width
|
||||
for start, end in EMOJI_ZERO_WIDTH:
|
||||
for cp in range(start, end + 1):
|
||||
width_map[cp] = 0
|
||||
|
||||
# Mark all regional indicators as single-width as they are usually paired
|
||||
# providing a combined width of 2 when displayed together.
|
||||
start, end = REGIONAL_INDICATORS
|
||||
for cp in range(start, end + 1):
|
||||
width_map[cp] = 1
|
||||
|
||||
# Process all assigned Unicode code points (Basic Multilingual Plane +
|
||||
# Supplementary Planes) Range 0x0 to 0x10FFFF (the full Unicode range)
|
||||
for block_start in range(0, 0x110000, 0x1000):
|
||||
block_end = block_start + 0x1000
|
||||
for cp in range(block_start, block_end):
|
||||
try:
|
||||
char = chr(cp)
|
||||
|
||||
# Skip if already processed
|
||||
if cp in width_map:
|
||||
continue
|
||||
|
||||
# Check for combining marks and a format characters
|
||||
category = unicodedata.category(char)
|
||||
|
||||
# Combining marks
|
||||
if category.startswith('M'):
|
||||
width_map[cp] = 0
|
||||
continue
|
||||
|
||||
# Format characters
|
||||
# Since we have no support for bidirectional text, all format
|
||||
# characters (category Cf) can be treated with width 0 (zero)
|
||||
# for simplicity, as they don't need to occupy visual space
|
||||
# in a non-bidirectional text environment.
|
||||
if category == 'Cf':
|
||||
width_map[cp] = 0
|
||||
continue
|
||||
|
||||
# Known zero-width characters
|
||||
if cp in KNOWN_ZERO_WIDTH:
|
||||
width_map[cp] = 0
|
||||
continue
|
||||
|
||||
# Use East Asian Width property
|
||||
eaw = unicodedata.east_asian_width(char)
|
||||
if eaw in ('F', 'W'): # Fullwidth or Wide
|
||||
width_map[cp] = 2
|
||||
elif eaw in ('Na', 'H', 'N', 'A'): # Narrow, Halfwidth, Neutral, Ambiguous
|
||||
width_map[cp] = 1
|
||||
else:
|
||||
# Default to single-width for unknown
|
||||
width_map[cp] = 1
|
||||
|
||||
except (ValueError, OverflowError):
|
||||
# Skip invalid code points
|
||||
continue
|
||||
|
||||
# Process Emoji - generally double-width
|
||||
for start, end in EMOJI_RANGES:
|
||||
for cp in range(start, end + 1):
|
||||
if cp not in width_map or width_map[cp] != 0: # Don't override zero-width
|
||||
try:
|
||||
char = chr(cp)
|
||||
width_map[cp] = 2
|
||||
except (ValueError, OverflowError):
|
||||
continue
|
||||
|
||||
# Optimize to create range tables
|
||||
def ranges_optimize(width_data, target_width):
|
||||
points = sorted([cp for cp, width in width_data.items() if width == target_width])
|
||||
if not points:
|
||||
return []
|
||||
|
||||
# Group consecutive code points into ranges
|
||||
ranges = []
|
||||
start = points[0]
|
||||
prev = start
|
||||
|
||||
for cp in points[1:]:
|
||||
if cp > prev + 1:
|
||||
ranges.append((start, prev))
|
||||
start = cp
|
||||
prev = cp
|
||||
|
||||
# Add the last range
|
||||
ranges.append((start, prev))
|
||||
return ranges
|
||||
|
||||
# Extract ranges for each width
|
||||
zero_width_ranges = ranges_optimize(width_map, 0)
|
||||
double_width_ranges = ranges_optimize(width_map, 2)
|
||||
|
||||
return zero_width_ranges, double_width_ranges
|
||||
|
||||
def write_tables(zero_width_ranges, double_width_ranges, out_file=DEFAULT_OUT_FILE):
|
||||
"""
|
||||
Write the generated tables to C header file.
|
||||
|
||||
Args:
|
||||
zero_width_ranges: List of (start, end) ranges for zero-width characters
|
||||
double_width_ranges: List of (start, end) ranges for double-width characters
|
||||
out_file: Output file name (default: DEFAULT_OUT_FILE)
|
||||
"""
|
||||
|
||||
# Function to split ranges into BMP (16-bit) and non-BMP (above 16-bit)
|
||||
def split_ranges_by_size(ranges):
|
||||
bmp_ranges = []
|
||||
non_bmp_ranges = []
|
||||
|
||||
for start, end in ranges:
|
||||
if end <= 0xFFFF:
|
||||
bmp_ranges.append((start, end))
|
||||
elif start > 0xFFFF:
|
||||
non_bmp_ranges.append((start, end))
|
||||
else:
|
||||
# Split the range at 0xFFFF
|
||||
bmp_ranges.append((start, 0xFFFF))
|
||||
non_bmp_ranges.append((0x10000, end))
|
||||
|
||||
return bmp_ranges, non_bmp_ranges
|
||||
|
||||
# Split ranges into BMP and non-BMP
|
||||
zero_width_bmp, zero_width_non_bmp = split_ranges_by_size(zero_width_ranges)
|
||||
double_width_bmp, double_width_non_bmp = split_ranges_by_size(double_width_ranges)
|
||||
|
||||
# Function to generate code point description comments
|
||||
def get_code_point_comment(start, end):
|
||||
try:
|
||||
start_char_desc = unicodedata.name(chr(start))
|
||||
if start == end:
|
||||
return f"/* {start_char_desc} */"
|
||||
else:
|
||||
end_char_desc = unicodedata.name(chr(end))
|
||||
return f"/* {start_char_desc} - {end_char_desc} */"
|
||||
except:
|
||||
if start == end:
|
||||
return f"/* U+{start:04X} */"
|
||||
else:
|
||||
return f"/* U+{start:04X} - U+{end:04X} */"
|
||||
|
||||
# Generate C tables
|
||||
with open(out_file, 'w') as f:
|
||||
f.write(f"""\
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* {out_file} - Unicode character width
|
||||
*
|
||||
* Auto-generated by {this_file}
|
||||
*
|
||||
* Unicode Version: {unicodedata.unidata_version}
|
||||
*/
|
||||
|
||||
/* Zero-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */
|
||||
static const struct ucs_interval16 ucs_zero_width_bmp_ranges[] = {{
|
||||
""")
|
||||
|
||||
for start, end in zero_width_bmp:
|
||||
comment = get_code_point_comment(start, end)
|
||||
f.write(f"\t{{ 0x{start:04X}, 0x{end:04X} }}, {comment}\n")
|
||||
|
||||
f.write("""\
|
||||
};
|
||||
|
||||
/* Zero-width character ranges (non-BMP, U+10000 and above) */
|
||||
static const struct ucs_interval32 ucs_zero_width_non_bmp_ranges[] = {
|
||||
""")
|
||||
|
||||
for start, end in zero_width_non_bmp:
|
||||
comment = get_code_point_comment(start, end)
|
||||
f.write(f"\t{{ 0x{start:05X}, 0x{end:05X} }}, {comment}\n")
|
||||
|
||||
f.write("""\
|
||||
};
|
||||
|
||||
/* Double-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */
|
||||
static const struct ucs_interval16 ucs_double_width_bmp_ranges[] = {
|
||||
""")
|
||||
|
||||
for start, end in double_width_bmp:
|
||||
comment = get_code_point_comment(start, end)
|
||||
f.write(f"\t{{ 0x{start:04X}, 0x{end:04X} }}, {comment}\n")
|
||||
|
||||
f.write("""\
|
||||
};
|
||||
|
||||
/* Double-width character ranges (non-BMP, U+10000 and above) */
|
||||
static const struct ucs_interval32 ucs_double_width_non_bmp_ranges[] = {
|
||||
""")
|
||||
|
||||
for start, end in double_width_non_bmp:
|
||||
comment = get_code_point_comment(start, end)
|
||||
f.write(f"\t{{ 0x{start:05X}, 0x{end:05X} }}, {comment}\n")
|
||||
|
||||
f.write("};\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(description="Generate Unicode width tables")
|
||||
parser.add_argument("-o", "--output", dest="output_file", default=DEFAULT_OUT_FILE,
|
||||
help=f"Output file name (default: {DEFAULT_OUT_FILE})")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Write tables to header file
|
||||
zero_width_ranges, double_width_ranges = create_width_tables()
|
||||
write_tables(zero_width_ranges, double_width_ranges, out_file=args.output_file)
|
||||
|
||||
# Print summary
|
||||
zero_width_count = sum(end - start + 1 for start, end in zero_width_ranges)
|
||||
double_width_count = sum(end - start + 1 for start, end in double_width_ranges)
|
||||
print(f"Generated {args.output_file} with:")
|
||||
print(f"- {len(zero_width_ranges)} zero-width ranges covering ~{zero_width_count} code points")
|
||||
print(f"- {len(double_width_ranges)} double-width ranges covering ~{double_width_count} code points")
|
||||
print(f"- Unicode Version: {unicodedata.unidata_version}")
|
|
@ -376,6 +376,17 @@ static void to_utf8(struct vc_data *vc, uint c)
|
|||
}
|
||||
}
|
||||
|
||||
static void put_queue_utf8(struct vc_data *vc, u32 value)
|
||||
{
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, value);
|
||||
else {
|
||||
int c = conv_uni_to_8bit(value);
|
||||
if (c != -1)
|
||||
put_queue(vc, c);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: review locking for vt.c callers */
|
||||
static void set_leds(void)
|
||||
{
|
||||
|
@ -454,13 +465,7 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
|
|||
if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
|
||||
return d;
|
||||
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, d);
|
||||
else {
|
||||
int c = conv_uni_to_8bit(d);
|
||||
if (c != -1)
|
||||
put_queue(vc, c);
|
||||
}
|
||||
put_queue_utf8(vc, d);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
@ -471,13 +476,7 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
|
|||
static void fn_enter(struct vc_data *vc)
|
||||
{
|
||||
if (diacr) {
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, diacr);
|
||||
else {
|
||||
int c = conv_uni_to_8bit(diacr);
|
||||
if (c != -1)
|
||||
put_queue(vc, c);
|
||||
}
|
||||
put_queue_utf8(vc, diacr);
|
||||
diacr = 0;
|
||||
}
|
||||
|
||||
|
@ -685,13 +684,7 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
|
|||
diacr = value;
|
||||
return;
|
||||
}
|
||||
if (kbd->kbdmode == VC_UNICODE)
|
||||
to_utf8(vc, value);
|
||||
else {
|
||||
int c = conv_uni_to_8bit(value);
|
||||
if (c != -1)
|
||||
put_queue(vc, c);
|
||||
}
|
||||
put_queue_utf8(vc, value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1519,7 +1512,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
|
|||
if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
|
||||
return;
|
||||
|
||||
(*k_handler[type])(vc, keysym & 0xff, !down);
|
||||
(*k_handler[type])(vc, KVAL(keysym), !down);
|
||||
|
||||
param.ledstate = kbd->ledflagstate;
|
||||
atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m);
|
||||
|
|
|
@ -403,6 +403,12 @@ int paste_selection(struct tty_struct *tty)
|
|||
DECLARE_WAITQUEUE(wait, current);
|
||||
int ret = 0;
|
||||
|
||||
bool bp = vc->vc_bracketed_paste;
|
||||
static const char bracketed_paste_start[] = "\033[200~";
|
||||
static const char bracketed_paste_end[] = "\033[201~";
|
||||
const char *bps = bp ? bracketed_paste_start : NULL;
|
||||
const char *bpe = bp ? bracketed_paste_end : NULL;
|
||||
|
||||
console_lock();
|
||||
poke_blanked_console();
|
||||
console_unlock();
|
||||
|
@ -414,7 +420,7 @@ int paste_selection(struct tty_struct *tty)
|
|||
|
||||
add_wait_queue(&vc->paste_wait, &wait);
|
||||
mutex_lock(&vc_sel.lock);
|
||||
while (vc_sel.buffer && vc_sel.buf_len > pasted) {
|
||||
while (vc_sel.buffer && (vc_sel.buf_len > pasted || bpe)) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
|
@ -427,10 +433,27 @@ int paste_selection(struct tty_struct *tty)
|
|||
continue;
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
if (bps) {
|
||||
bps += tty_ldisc_receive_buf(ld, bps, NULL, strlen(bps));
|
||||
if (*bps != '\0')
|
||||
continue;
|
||||
bps = NULL;
|
||||
}
|
||||
|
||||
count = vc_sel.buf_len - pasted;
|
||||
count = tty_ldisc_receive_buf(ld, vc_sel.buffer + pasted, NULL,
|
||||
count);
|
||||
pasted += count;
|
||||
if (count) {
|
||||
pasted += tty_ldisc_receive_buf(ld, vc_sel.buffer + pasted,
|
||||
NULL, count);
|
||||
if (vc_sel.buf_len > pasted)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bpe) {
|
||||
bpe += tty_ldisc_receive_buf(ld, bpe, NULL, strlen(bpe));
|
||||
if (*bpe == '\0')
|
||||
bpe = NULL;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&vc_sel.lock);
|
||||
remove_wait_queue(&vc->paste_wait, &wait);
|
||||
|
|
251
drivers/tty/vt/ucs.c
Normal file
251
drivers/tty/vt/ucs.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ucs.c - Universal Character Set processing
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/bsearch.h>
|
||||
#include <linux/consolemap.h>
|
||||
#include <linux/minmax.h>
|
||||
|
||||
struct ucs_interval16 {
|
||||
u16 first;
|
||||
u16 last;
|
||||
};
|
||||
|
||||
struct ucs_interval32 {
|
||||
u32 first;
|
||||
u32 last;
|
||||
};
|
||||
|
||||
#include "ucs_width_table.h"
|
||||
|
||||
static int interval16_cmp(const void *key, const void *element)
|
||||
{
|
||||
u16 cp = *(u16 *)key;
|
||||
const struct ucs_interval16 *entry = element;
|
||||
|
||||
if (cp < entry->first)
|
||||
return -1;
|
||||
if (cp > entry->last)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int interval32_cmp(const void *key, const void *element)
|
||||
{
|
||||
u32 cp = *(u32 *)key;
|
||||
const struct ucs_interval32 *entry = element;
|
||||
|
||||
if (cp < entry->first)
|
||||
return -1;
|
||||
if (cp > entry->last)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cp_in_range16(u16 cp, const struct ucs_interval16 *ranges, size_t size)
|
||||
{
|
||||
if (cp < ranges[0].first || cp > ranges[size - 1].last)
|
||||
return false;
|
||||
|
||||
return __inline_bsearch(&cp, ranges, size, sizeof(*ranges),
|
||||
interval16_cmp) != NULL;
|
||||
}
|
||||
|
||||
static bool cp_in_range32(u32 cp, const struct ucs_interval32 *ranges, size_t size)
|
||||
{
|
||||
if (cp < ranges[0].first || cp > ranges[size - 1].last)
|
||||
return false;
|
||||
|
||||
return __inline_bsearch(&cp, ranges, size, sizeof(*ranges),
|
||||
interval32_cmp) != NULL;
|
||||
}
|
||||
|
||||
#define UCS_IS_BMP(cp) ((cp) <= 0xffff)
|
||||
|
||||
/**
|
||||
* ucs_is_zero_width() - Determine if a Unicode code point is zero-width.
|
||||
* @cp: Unicode code point (UCS-4)
|
||||
*
|
||||
* Return: true if the character is zero-width, false otherwise
|
||||
*/
|
||||
bool ucs_is_zero_width(u32 cp)
|
||||
{
|
||||
if (UCS_IS_BMP(cp))
|
||||
return cp_in_range16(cp, ucs_zero_width_bmp_ranges,
|
||||
ARRAY_SIZE(ucs_zero_width_bmp_ranges));
|
||||
else
|
||||
return cp_in_range32(cp, ucs_zero_width_non_bmp_ranges,
|
||||
ARRAY_SIZE(ucs_zero_width_non_bmp_ranges));
|
||||
}
|
||||
|
||||
/**
|
||||
* ucs_is_double_width() - Determine if a Unicode code point is double-width.
|
||||
* @cp: Unicode code point (UCS-4)
|
||||
*
|
||||
* Return: true if the character is double-width, false otherwise
|
||||
*/
|
||||
bool ucs_is_double_width(u32 cp)
|
||||
{
|
||||
if (UCS_IS_BMP(cp))
|
||||
return cp_in_range16(cp, ucs_double_width_bmp_ranges,
|
||||
ARRAY_SIZE(ucs_double_width_bmp_ranges));
|
||||
else
|
||||
return cp_in_range32(cp, ucs_double_width_non_bmp_ranges,
|
||||
ARRAY_SIZE(ucs_double_width_non_bmp_ranges));
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure for base with combining mark pairs and resulting recompositions.
|
||||
* Using u16 to save space since all values are within BMP range.
|
||||
*/
|
||||
struct ucs_recomposition {
|
||||
u16 base; /* base character */
|
||||
u16 mark; /* combining mark */
|
||||
u16 recomposed; /* corresponding recomposed character */
|
||||
};
|
||||
|
||||
#include "ucs_recompose_table.h"
|
||||
|
||||
struct compare_key {
|
||||
u16 base;
|
||||
u16 mark;
|
||||
};
|
||||
|
||||
static int recomposition_cmp(const void *key, const void *element)
|
||||
{
|
||||
const struct compare_key *search_key = key;
|
||||
const struct ucs_recomposition *entry = element;
|
||||
|
||||
/* Compare base character first */
|
||||
if (search_key->base < entry->base)
|
||||
return -1;
|
||||
if (search_key->base > entry->base)
|
||||
return 1;
|
||||
|
||||
/* Base characters match, now compare combining character */
|
||||
if (search_key->mark < entry->mark)
|
||||
return -1;
|
||||
if (search_key->mark > entry->mark)
|
||||
return 1;
|
||||
|
||||
/* Both match */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucs_recompose() - Attempt to recompose two Unicode characters into a single character.
|
||||
* @base: Base Unicode code point (UCS-4)
|
||||
* @mark: Combining mark Unicode code point (UCS-4)
|
||||
*
|
||||
* Return: Recomposed Unicode code point, or 0 if no recomposition is possible
|
||||
*/
|
||||
u32 ucs_recompose(u32 base, u32 mark)
|
||||
{
|
||||
/* Check if characters are within the range of our table */
|
||||
if (base < UCS_RECOMPOSE_MIN_BASE || base > UCS_RECOMPOSE_MAX_BASE ||
|
||||
mark < UCS_RECOMPOSE_MIN_MARK || mark > UCS_RECOMPOSE_MAX_MARK)
|
||||
return 0;
|
||||
|
||||
struct compare_key key = { base, mark };
|
||||
struct ucs_recomposition *result =
|
||||
__inline_bsearch(&key, ucs_recomposition_table,
|
||||
ARRAY_SIZE(ucs_recomposition_table),
|
||||
sizeof(*ucs_recomposition_table),
|
||||
recomposition_cmp);
|
||||
|
||||
return result ? result->recomposed : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The fallback table structures implement a 2-level lookup.
|
||||
*/
|
||||
|
||||
struct ucs_page_desc {
|
||||
u8 page; /* Page index (high byte of code points) */
|
||||
u8 count; /* Number of entries in this page */
|
||||
u16 start; /* Start index in entries array */
|
||||
};
|
||||
|
||||
struct ucs_page_entry {
|
||||
u8 offset; /* Offset within page (0-255) */
|
||||
u8 fallback; /* Fallback character or range start marker */
|
||||
};
|
||||
|
||||
#include "ucs_fallback_table.h"
|
||||
|
||||
static int ucs_page_desc_cmp(const void *key, const void *element)
|
||||
{
|
||||
u8 page = *(u8 *)key;
|
||||
const struct ucs_page_desc *entry = element;
|
||||
|
||||
if (page < entry->page)
|
||||
return -1;
|
||||
if (page > entry->page)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ucs_page_entry_cmp(const void *key, const void *element)
|
||||
{
|
||||
u8 offset = *(u8 *)key;
|
||||
const struct ucs_page_entry *entry = element;
|
||||
|
||||
if (offset < entry->offset)
|
||||
return -1;
|
||||
if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER) {
|
||||
if (offset > entry[1].offset)
|
||||
return 1;
|
||||
} else {
|
||||
if (offset > entry->offset)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ucs_get_fallback() - Get a substitution for the provided Unicode character
|
||||
* @base: Base Unicode code point (UCS-4)
|
||||
*
|
||||
* Get a simpler fallback character for the provided Unicode character.
|
||||
* This is used for terminal display when corresponding glyph is unavailable.
|
||||
* The substitution may not be as good as the actual glyph for the original
|
||||
* character but still way more helpful than a squared question mark.
|
||||
*
|
||||
* Return: Fallback Unicode code point, or 0 if none is available
|
||||
*/
|
||||
u32 ucs_get_fallback(u32 cp)
|
||||
{
|
||||
const struct ucs_page_desc *page;
|
||||
const struct ucs_page_entry *entry;
|
||||
u8 page_idx = cp >> 8, offset = cp;
|
||||
|
||||
if (!UCS_IS_BMP(cp))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Full-width to ASCII mapping (covering all printable ASCII 33-126)
|
||||
* 0xFF01 (!) to 0xFF5E (~) -> ASCII 33 (!) to 126 (~)
|
||||
* We process them programmatically to reduce the table size.
|
||||
*/
|
||||
if (cp >= 0xFF01 && cp <= 0xFF5E)
|
||||
return cp - 0xFF01 + 33;
|
||||
|
||||
page = __inline_bsearch(&page_idx, ucs_fallback_pages,
|
||||
ARRAY_SIZE(ucs_fallback_pages),
|
||||
sizeof(*ucs_fallback_pages),
|
||||
ucs_page_desc_cmp);
|
||||
if (!page)
|
||||
return 0;
|
||||
|
||||
entry = __inline_bsearch(&offset, ucs_fallback_entries + page->start,
|
||||
page->count, sizeof(*ucs_fallback_entries),
|
||||
ucs_page_entry_cmp);
|
||||
if (!entry)
|
||||
return 0;
|
||||
|
||||
if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER)
|
||||
entry++;
|
||||
return entry->fallback;
|
||||
}
|
3346
drivers/tty/vt/ucs_fallback_table.h_shipped
Normal file
3346
drivers/tty/vt/ucs_fallback_table.h_shipped
Normal file
File diff suppressed because it is too large
Load diff
102
drivers/tty/vt/ucs_recompose_table.h_shipped
Normal file
102
drivers/tty/vt/ucs_recompose_table.h_shipped
Normal file
|
@ -0,0 +1,102 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* ucs_recompose_table.h - Unicode character recomposition
|
||||
*
|
||||
* Auto-generated by gen_ucs_recompose_table.py
|
||||
*
|
||||
* Unicode Version: 16.0.0
|
||||
*
|
||||
* This file contains a table with most commonly used Latin, Greek, and
|
||||
* Cyrillic recomposition pairs only (71 entries). To generate a table with
|
||||
* all possible recomposition pairs from the Unicode BMP (1000 entries)
|
||||
* instead, run:
|
||||
*
|
||||
* python gen_ucs_recompose_table.py --full
|
||||
*/
|
||||
|
||||
/*
|
||||
* Table of most commonly used Latin, Greek, and Cyrillic recomposition pairs only
|
||||
* Sorted by base character and then combining mark for binary search
|
||||
*/
|
||||
static const struct ucs_recomposition ucs_recomposition_table[] = {
|
||||
{ 0x0041, 0x0300, 0x00C0 }, /* LATIN CAPITAL LETTER A + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER A WITH GRAVE */
|
||||
{ 0x0041, 0x0301, 0x00C1 }, /* LATIN CAPITAL LETTER A + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER A WITH ACUTE */
|
||||
{ 0x0041, 0x0302, 0x00C2 }, /* LATIN CAPITAL LETTER A + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
|
||||
{ 0x0041, 0x0303, 0x00C3 }, /* LATIN CAPITAL LETTER A + COMBINING TILDE = LATIN CAPITAL LETTER A WITH TILDE */
|
||||
{ 0x0041, 0x0308, 0x00C4 }, /* LATIN CAPITAL LETTER A + COMBINING DIAERESIS = LATIN CAPITAL LETTER A WITH DIAERESIS */
|
||||
{ 0x0041, 0x030A, 0x00C5 }, /* LATIN CAPITAL LETTER A + COMBINING RING ABOVE = LATIN CAPITAL LETTER A WITH RING ABOVE */
|
||||
{ 0x0043, 0x0327, 0x00C7 }, /* LATIN CAPITAL LETTER C + COMBINING CEDILLA = LATIN CAPITAL LETTER C WITH CEDILLA */
|
||||
{ 0x0045, 0x0300, 0x00C8 }, /* LATIN CAPITAL LETTER E + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER E WITH GRAVE */
|
||||
{ 0x0045, 0x0301, 0x00C9 }, /* LATIN CAPITAL LETTER E + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER E WITH ACUTE */
|
||||
{ 0x0045, 0x0302, 0x00CA }, /* LATIN CAPITAL LETTER E + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
|
||||
{ 0x0045, 0x0308, 0x00CB }, /* LATIN CAPITAL LETTER E + COMBINING DIAERESIS = LATIN CAPITAL LETTER E WITH DIAERESIS */
|
||||
{ 0x0049, 0x0300, 0x00CC }, /* LATIN CAPITAL LETTER I + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER I WITH GRAVE */
|
||||
{ 0x0049, 0x0301, 0x00CD }, /* LATIN CAPITAL LETTER I + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER I WITH ACUTE */
|
||||
{ 0x0049, 0x0302, 0x00CE }, /* LATIN CAPITAL LETTER I + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
|
||||
{ 0x0049, 0x0308, 0x00CF }, /* LATIN CAPITAL LETTER I + COMBINING DIAERESIS = LATIN CAPITAL LETTER I WITH DIAERESIS */
|
||||
{ 0x004E, 0x0303, 0x00D1 }, /* LATIN CAPITAL LETTER N + COMBINING TILDE = LATIN CAPITAL LETTER N WITH TILDE */
|
||||
{ 0x004F, 0x0300, 0x00D2 }, /* LATIN CAPITAL LETTER O + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER O WITH GRAVE */
|
||||
{ 0x004F, 0x0301, 0x00D3 }, /* LATIN CAPITAL LETTER O + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER O WITH ACUTE */
|
||||
{ 0x004F, 0x0302, 0x00D4 }, /* LATIN CAPITAL LETTER O + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
|
||||
{ 0x004F, 0x0303, 0x00D5 }, /* LATIN CAPITAL LETTER O + COMBINING TILDE = LATIN CAPITAL LETTER O WITH TILDE */
|
||||
{ 0x004F, 0x0308, 0x00D6 }, /* LATIN CAPITAL LETTER O + COMBINING DIAERESIS = LATIN CAPITAL LETTER O WITH DIAERESIS */
|
||||
{ 0x0055, 0x0300, 0x00D9 }, /* LATIN CAPITAL LETTER U + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER U WITH GRAVE */
|
||||
{ 0x0055, 0x0301, 0x00DA }, /* LATIN CAPITAL LETTER U + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER U WITH ACUTE */
|
||||
{ 0x0055, 0x0302, 0x00DB }, /* LATIN CAPITAL LETTER U + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
|
||||
{ 0x0055, 0x0308, 0x00DC }, /* LATIN CAPITAL LETTER U + COMBINING DIAERESIS = LATIN CAPITAL LETTER U WITH DIAERESIS */
|
||||
{ 0x0059, 0x0301, 0x00DD }, /* LATIN CAPITAL LETTER Y + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER Y WITH ACUTE */
|
||||
{ 0x0061, 0x0300, 0x00E0 }, /* LATIN SMALL LETTER A + COMBINING GRAVE ACCENT = LATIN SMALL LETTER A WITH GRAVE */
|
||||
{ 0x0061, 0x0301, 0x00E1 }, /* LATIN SMALL LETTER A + COMBINING ACUTE ACCENT = LATIN SMALL LETTER A WITH ACUTE */
|
||||
{ 0x0061, 0x0302, 0x00E2 }, /* LATIN SMALL LETTER A + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER A WITH CIRCUMFLEX */
|
||||
{ 0x0061, 0x0303, 0x00E3 }, /* LATIN SMALL LETTER A + COMBINING TILDE = LATIN SMALL LETTER A WITH TILDE */
|
||||
{ 0x0061, 0x0308, 0x00E4 }, /* LATIN SMALL LETTER A + COMBINING DIAERESIS = LATIN SMALL LETTER A WITH DIAERESIS */
|
||||
{ 0x0061, 0x030A, 0x00E5 }, /* LATIN SMALL LETTER A + COMBINING RING ABOVE = LATIN SMALL LETTER A WITH RING ABOVE */
|
||||
{ 0x0063, 0x0327, 0x00E7 }, /* LATIN SMALL LETTER C + COMBINING CEDILLA = LATIN SMALL LETTER C WITH CEDILLA */
|
||||
{ 0x0065, 0x0300, 0x00E8 }, /* LATIN SMALL LETTER E + COMBINING GRAVE ACCENT = LATIN SMALL LETTER E WITH GRAVE */
|
||||
{ 0x0065, 0x0301, 0x00E9 }, /* LATIN SMALL LETTER E + COMBINING ACUTE ACCENT = LATIN SMALL LETTER E WITH ACUTE */
|
||||
{ 0x0065, 0x0302, 0x00EA }, /* LATIN SMALL LETTER E + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER E WITH CIRCUMFLEX */
|
||||
{ 0x0065, 0x0308, 0x00EB }, /* LATIN SMALL LETTER E + COMBINING DIAERESIS = LATIN SMALL LETTER E WITH DIAERESIS */
|
||||
{ 0x0069, 0x0300, 0x00EC }, /* LATIN SMALL LETTER I + COMBINING GRAVE ACCENT = LATIN SMALL LETTER I WITH GRAVE */
|
||||
{ 0x0069, 0x0301, 0x00ED }, /* LATIN SMALL LETTER I + COMBINING ACUTE ACCENT = LATIN SMALL LETTER I WITH ACUTE */
|
||||
{ 0x0069, 0x0302, 0x00EE }, /* LATIN SMALL LETTER I + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER I WITH CIRCUMFLEX */
|
||||
{ 0x0069, 0x0308, 0x00EF }, /* LATIN SMALL LETTER I + COMBINING DIAERESIS = LATIN SMALL LETTER I WITH DIAERESIS */
|
||||
{ 0x006E, 0x0303, 0x00F1 }, /* LATIN SMALL LETTER N + COMBINING TILDE = LATIN SMALL LETTER N WITH TILDE */
|
||||
{ 0x006F, 0x0300, 0x00F2 }, /* LATIN SMALL LETTER O + COMBINING GRAVE ACCENT = LATIN SMALL LETTER O WITH GRAVE */
|
||||
{ 0x006F, 0x0301, 0x00F3 }, /* LATIN SMALL LETTER O + COMBINING ACUTE ACCENT = LATIN SMALL LETTER O WITH ACUTE */
|
||||
{ 0x006F, 0x0302, 0x00F4 }, /* LATIN SMALL LETTER O + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER O WITH CIRCUMFLEX */
|
||||
{ 0x006F, 0x0303, 0x00F5 }, /* LATIN SMALL LETTER O + COMBINING TILDE = LATIN SMALL LETTER O WITH TILDE */
|
||||
{ 0x006F, 0x0308, 0x00F6 }, /* LATIN SMALL LETTER O + COMBINING DIAERESIS = LATIN SMALL LETTER O WITH DIAERESIS */
|
||||
{ 0x0075, 0x0300, 0x00F9 }, /* LATIN SMALL LETTER U + COMBINING GRAVE ACCENT = LATIN SMALL LETTER U WITH GRAVE */
|
||||
{ 0x0075, 0x0301, 0x00FA }, /* LATIN SMALL LETTER U + COMBINING ACUTE ACCENT = LATIN SMALL LETTER U WITH ACUTE */
|
||||
{ 0x0075, 0x0302, 0x00FB }, /* LATIN SMALL LETTER U + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER U WITH CIRCUMFLEX */
|
||||
{ 0x0075, 0x0308, 0x00FC }, /* LATIN SMALL LETTER U + COMBINING DIAERESIS = LATIN SMALL LETTER U WITH DIAERESIS */
|
||||
{ 0x0079, 0x0301, 0x00FD }, /* LATIN SMALL LETTER Y + COMBINING ACUTE ACCENT = LATIN SMALL LETTER Y WITH ACUTE */
|
||||
{ 0x0079, 0x0308, 0x00FF }, /* LATIN SMALL LETTER Y + COMBINING DIAERESIS = LATIN SMALL LETTER Y WITH DIAERESIS */
|
||||
{ 0x0391, 0x0301, 0x0386 }, /* GREEK CAPITAL LETTER ALPHA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ALPHA WITH TONOS */
|
||||
{ 0x0395, 0x0301, 0x0388 }, /* GREEK CAPITAL LETTER EPSILON + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER EPSILON WITH TONOS */
|
||||
{ 0x0397, 0x0301, 0x0389 }, /* GREEK CAPITAL LETTER ETA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ETA WITH TONOS */
|
||||
{ 0x0399, 0x0301, 0x038A }, /* GREEK CAPITAL LETTER IOTA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER IOTA WITH TONOS */
|
||||
{ 0x039F, 0x0301, 0x038C }, /* GREEK CAPITAL LETTER OMICRON + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMICRON WITH TONOS */
|
||||
{ 0x03A5, 0x0301, 0x038E }, /* GREEK CAPITAL LETTER UPSILON + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER UPSILON WITH TONOS */
|
||||
{ 0x03A9, 0x0301, 0x038F }, /* GREEK CAPITAL LETTER OMEGA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMEGA WITH TONOS */
|
||||
{ 0x03B1, 0x0301, 0x03AC }, /* GREEK SMALL LETTER ALPHA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ALPHA WITH TONOS */
|
||||
{ 0x03B5, 0x0301, 0x03AD }, /* GREEK SMALL LETTER EPSILON + COMBINING ACUTE ACCENT = GREEK SMALL LETTER EPSILON WITH TONOS */
|
||||
{ 0x03B7, 0x0301, 0x03AE }, /* GREEK SMALL LETTER ETA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ETA WITH TONOS */
|
||||
{ 0x03B9, 0x0301, 0x03AF }, /* GREEK SMALL LETTER IOTA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER IOTA WITH TONOS */
|
||||
{ 0x03BF, 0x0301, 0x03CC }, /* GREEK SMALL LETTER OMICRON + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMICRON WITH TONOS */
|
||||
{ 0x03C5, 0x0301, 0x03CD }, /* GREEK SMALL LETTER UPSILON + COMBINING ACUTE ACCENT = GREEK SMALL LETTER UPSILON WITH TONOS */
|
||||
{ 0x03C9, 0x0301, 0x03CE }, /* GREEK SMALL LETTER OMEGA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMEGA WITH TONOS */
|
||||
{ 0x0418, 0x0306, 0x0419 }, /* CYRILLIC CAPITAL LETTER I + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT I */
|
||||
{ 0x0423, 0x0306, 0x040E }, /* CYRILLIC CAPITAL LETTER U + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT U */
|
||||
{ 0x0438, 0x0306, 0x0439 }, /* CYRILLIC SMALL LETTER I + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT I */
|
||||
{ 0x0443, 0x0306, 0x045E }, /* CYRILLIC SMALL LETTER U + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT U */
|
||||
};
|
||||
|
||||
/*
|
||||
* Boundary values for quick rejection
|
||||
* These are calculated by analyzing the table during generation
|
||||
*/
|
||||
#define UCS_RECOMPOSE_MIN_BASE 0x0041
|
||||
#define UCS_RECOMPOSE_MAX_BASE 0x0443
|
||||
#define UCS_RECOMPOSE_MIN_MARK 0x0300
|
||||
#define UCS_RECOMPOSE_MAX_MARK 0x0327
|
453
drivers/tty/vt/ucs_width_table.h_shipped
Normal file
453
drivers/tty/vt/ucs_width_table.h_shipped
Normal file
|
@ -0,0 +1,453 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* ucs_width_table.h - Unicode character width
|
||||
*
|
||||
* Auto-generated by gen_ucs_width_table.py
|
||||
*
|
||||
* Unicode Version: 16.0.0
|
||||
*/
|
||||
|
||||
/* Zero-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */
|
||||
static const struct ucs_interval16 ucs_zero_width_bmp_ranges[] = {
|
||||
{ 0x00AD, 0x00AD }, /* SOFT HYPHEN */
|
||||
{ 0x0300, 0x036F }, /* COMBINING GRAVE ACCENT - COMBINING LATIN SMALL LETTER X */
|
||||
{ 0x0483, 0x0489 }, /* COMBINING CYRILLIC TITLO - COMBINING CYRILLIC MILLIONS SIGN */
|
||||
{ 0x0591, 0x05BD }, /* HEBREW ACCENT ETNAHTA - HEBREW POINT METEG */
|
||||
{ 0x05BF, 0x05BF }, /* HEBREW POINT RAFE */
|
||||
{ 0x05C1, 0x05C2 }, /* HEBREW POINT SHIN DOT - HEBREW POINT SIN DOT */
|
||||
{ 0x05C4, 0x05C5 }, /* HEBREW MARK UPPER DOT - HEBREW MARK LOWER DOT */
|
||||
{ 0x05C7, 0x05C7 }, /* HEBREW POINT QAMATS QATAN */
|
||||
{ 0x0600, 0x0605 }, /* ARABIC NUMBER SIGN - ARABIC NUMBER MARK ABOVE */
|
||||
{ 0x0610, 0x061A }, /* ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM - ARABIC SMALL KASRA */
|
||||
{ 0x061C, 0x061C }, /* ARABIC LETTER MARK */
|
||||
{ 0x064B, 0x065F }, /* ARABIC FATHATAN - ARABIC WAVY HAMZA BELOW */
|
||||
{ 0x0670, 0x0670 }, /* ARABIC LETTER SUPERSCRIPT ALEF */
|
||||
{ 0x06D6, 0x06DD }, /* ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA - ARABIC END OF AYAH */
|
||||
{ 0x06DF, 0x06E4 }, /* ARABIC SMALL HIGH ROUNDED ZERO - ARABIC SMALL HIGH MADDA */
|
||||
{ 0x06E7, 0x06E8 }, /* ARABIC SMALL HIGH YEH - ARABIC SMALL HIGH NOON */
|
||||
{ 0x06EA, 0x06ED }, /* ARABIC EMPTY CENTRE LOW STOP - ARABIC SMALL LOW MEEM */
|
||||
{ 0x070F, 0x070F }, /* SYRIAC ABBREVIATION MARK */
|
||||
{ 0x0711, 0x0711 }, /* SYRIAC LETTER SUPERSCRIPT ALAPH */
|
||||
{ 0x0730, 0x074A }, /* SYRIAC PTHAHA ABOVE - SYRIAC BARREKH */
|
||||
{ 0x07A6, 0x07B0 }, /* THAANA ABAFILI - THAANA SUKUN */
|
||||
{ 0x07EB, 0x07F3 }, /* NKO COMBINING SHORT HIGH TONE - NKO COMBINING DOUBLE DOT ABOVE */
|
||||
{ 0x07FD, 0x07FD }, /* NKO DANTAYALAN */
|
||||
{ 0x0816, 0x0819 }, /* SAMARITAN MARK IN - SAMARITAN MARK DAGESH */
|
||||
{ 0x081B, 0x0823 }, /* SAMARITAN MARK EPENTHETIC YUT - SAMARITAN VOWEL SIGN A */
|
||||
{ 0x0825, 0x0827 }, /* SAMARITAN VOWEL SIGN SHORT A - SAMARITAN VOWEL SIGN U */
|
||||
{ 0x0829, 0x082D }, /* SAMARITAN VOWEL SIGN LONG I - SAMARITAN MARK NEQUDAA */
|
||||
{ 0x0859, 0x085B }, /* MANDAIC AFFRICATION MARK - MANDAIC GEMINATION MARK */
|
||||
{ 0x0890, 0x0891 }, /* ARABIC POUND MARK ABOVE - ARABIC PIASTRE MARK ABOVE */
|
||||
{ 0x0897, 0x089F }, /* ARABIC PEPET - ARABIC HALF MADDA OVER MADDA */
|
||||
{ 0x08CA, 0x0903 }, /* ARABIC SMALL HIGH FARSI YEH - DEVANAGARI SIGN VISARGA */
|
||||
{ 0x093A, 0x093C }, /* DEVANAGARI VOWEL SIGN OE - DEVANAGARI SIGN NUKTA */
|
||||
{ 0x093E, 0x094F }, /* DEVANAGARI VOWEL SIGN AA - DEVANAGARI VOWEL SIGN AW */
|
||||
{ 0x0951, 0x0957 }, /* DEVANAGARI STRESS SIGN UDATTA - DEVANAGARI VOWEL SIGN UUE */
|
||||
{ 0x0962, 0x0963 }, /* DEVANAGARI VOWEL SIGN VOCALIC L - DEVANAGARI VOWEL SIGN VOCALIC LL */
|
||||
{ 0x0981, 0x0983 }, /* BENGALI SIGN CANDRABINDU - BENGALI SIGN VISARGA */
|
||||
{ 0x09BC, 0x09BC }, /* BENGALI SIGN NUKTA */
|
||||
{ 0x09BE, 0x09C4 }, /* BENGALI VOWEL SIGN AA - BENGALI VOWEL SIGN VOCALIC RR */
|
||||
{ 0x09C7, 0x09C8 }, /* BENGALI VOWEL SIGN E - BENGALI VOWEL SIGN AI */
|
||||
{ 0x09CB, 0x09CD }, /* BENGALI VOWEL SIGN O - BENGALI SIGN VIRAMA */
|
||||
{ 0x09D7, 0x09D7 }, /* BENGALI AU LENGTH MARK */
|
||||
{ 0x09E2, 0x09E3 }, /* BENGALI VOWEL SIGN VOCALIC L - BENGALI VOWEL SIGN VOCALIC LL */
|
||||
{ 0x09FE, 0x09FE }, /* BENGALI SANDHI MARK */
|
||||
{ 0x0A01, 0x0A03 }, /* GURMUKHI SIGN ADAK BINDI - GURMUKHI SIGN VISARGA */
|
||||
{ 0x0A3C, 0x0A3C }, /* GURMUKHI SIGN NUKTA */
|
||||
{ 0x0A3E, 0x0A42 }, /* GURMUKHI VOWEL SIGN AA - GURMUKHI VOWEL SIGN UU */
|
||||
{ 0x0A47, 0x0A48 }, /* GURMUKHI VOWEL SIGN EE - GURMUKHI VOWEL SIGN AI */
|
||||
{ 0x0A4B, 0x0A4D }, /* GURMUKHI VOWEL SIGN OO - GURMUKHI SIGN VIRAMA */
|
||||
{ 0x0A51, 0x0A51 }, /* GURMUKHI SIGN UDAAT */
|
||||
{ 0x0A70, 0x0A71 }, /* GURMUKHI TIPPI - GURMUKHI ADDAK */
|
||||
{ 0x0A75, 0x0A75 }, /* GURMUKHI SIGN YAKASH */
|
||||
{ 0x0A81, 0x0A83 }, /* GUJARATI SIGN CANDRABINDU - GUJARATI SIGN VISARGA */
|
||||
{ 0x0ABC, 0x0ABC }, /* GUJARATI SIGN NUKTA */
|
||||
{ 0x0ABE, 0x0AC5 }, /* GUJARATI VOWEL SIGN AA - GUJARATI VOWEL SIGN CANDRA E */
|
||||
{ 0x0AC7, 0x0AC9 }, /* GUJARATI VOWEL SIGN E - GUJARATI VOWEL SIGN CANDRA O */
|
||||
{ 0x0ACB, 0x0ACD }, /* GUJARATI VOWEL SIGN O - GUJARATI SIGN VIRAMA */
|
||||
{ 0x0AE2, 0x0AE3 }, /* GUJARATI VOWEL SIGN VOCALIC L - GUJARATI VOWEL SIGN VOCALIC LL */
|
||||
{ 0x0AFA, 0x0AFF }, /* GUJARATI SIGN SUKUN - GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE */
|
||||
{ 0x0B01, 0x0B03 }, /* ORIYA SIGN CANDRABINDU - ORIYA SIGN VISARGA */
|
||||
{ 0x0B3C, 0x0B3C }, /* ORIYA SIGN NUKTA */
|
||||
{ 0x0B3E, 0x0B44 }, /* ORIYA VOWEL SIGN AA - ORIYA VOWEL SIGN VOCALIC RR */
|
||||
{ 0x0B47, 0x0B48 }, /* ORIYA VOWEL SIGN E - ORIYA VOWEL SIGN AI */
|
||||
{ 0x0B4B, 0x0B4D }, /* ORIYA VOWEL SIGN O - ORIYA SIGN VIRAMA */
|
||||
{ 0x0B55, 0x0B57 }, /* ORIYA SIGN OVERLINE - ORIYA AU LENGTH MARK */
|
||||
{ 0x0B62, 0x0B63 }, /* ORIYA VOWEL SIGN VOCALIC L - ORIYA VOWEL SIGN VOCALIC LL */
|
||||
{ 0x0B82, 0x0B82 }, /* TAMIL SIGN ANUSVARA */
|
||||
{ 0x0BBE, 0x0BC2 }, /* TAMIL VOWEL SIGN AA - TAMIL VOWEL SIGN UU */
|
||||
{ 0x0BC6, 0x0BC8 }, /* TAMIL VOWEL SIGN E - TAMIL VOWEL SIGN AI */
|
||||
{ 0x0BCA, 0x0BCD }, /* TAMIL VOWEL SIGN O - TAMIL SIGN VIRAMA */
|
||||
{ 0x0BD7, 0x0BD7 }, /* TAMIL AU LENGTH MARK */
|
||||
{ 0x0C00, 0x0C04 }, /* TELUGU SIGN COMBINING CANDRABINDU ABOVE - TELUGU SIGN COMBINING ANUSVARA ABOVE */
|
||||
{ 0x0C3C, 0x0C3C }, /* TELUGU SIGN NUKTA */
|
||||
{ 0x0C3E, 0x0C44 }, /* TELUGU VOWEL SIGN AA - TELUGU VOWEL SIGN VOCALIC RR */
|
||||
{ 0x0C46, 0x0C48 }, /* TELUGU VOWEL SIGN E - TELUGU VOWEL SIGN AI */
|
||||
{ 0x0C4A, 0x0C4D }, /* TELUGU VOWEL SIGN O - TELUGU SIGN VIRAMA */
|
||||
{ 0x0C55, 0x0C56 }, /* TELUGU LENGTH MARK - TELUGU AI LENGTH MARK */
|
||||
{ 0x0C62, 0x0C63 }, /* TELUGU VOWEL SIGN VOCALIC L - TELUGU VOWEL SIGN VOCALIC LL */
|
||||
{ 0x0C81, 0x0C83 }, /* KANNADA SIGN CANDRABINDU - KANNADA SIGN VISARGA */
|
||||
{ 0x0CBC, 0x0CBC }, /* KANNADA SIGN NUKTA */
|
||||
{ 0x0CBE, 0x0CC4 }, /* KANNADA VOWEL SIGN AA - KANNADA VOWEL SIGN VOCALIC RR */
|
||||
{ 0x0CC6, 0x0CC8 }, /* KANNADA VOWEL SIGN E - KANNADA VOWEL SIGN AI */
|
||||
{ 0x0CCA, 0x0CCD }, /* KANNADA VOWEL SIGN O - KANNADA SIGN VIRAMA */
|
||||
{ 0x0CD5, 0x0CD6 }, /* KANNADA LENGTH MARK - KANNADA AI LENGTH MARK */
|
||||
{ 0x0CE2, 0x0CE3 }, /* KANNADA VOWEL SIGN VOCALIC L - KANNADA VOWEL SIGN VOCALIC LL */
|
||||
{ 0x0CF3, 0x0CF3 }, /* KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT */
|
||||
{ 0x0D00, 0x0D03 }, /* MALAYALAM SIGN COMBINING ANUSVARA ABOVE - MALAYALAM SIGN VISARGA */
|
||||
{ 0x0D3B, 0x0D3C }, /* MALAYALAM SIGN VERTICAL BAR VIRAMA - MALAYALAM SIGN CIRCULAR VIRAMA */
|
||||
{ 0x0D3E, 0x0D44 }, /* MALAYALAM VOWEL SIGN AA - MALAYALAM VOWEL SIGN VOCALIC RR */
|
||||
{ 0x0D46, 0x0D48 }, /* MALAYALAM VOWEL SIGN E - MALAYALAM VOWEL SIGN AI */
|
||||
{ 0x0D4A, 0x0D4D }, /* MALAYALAM VOWEL SIGN O - MALAYALAM SIGN VIRAMA */
|
||||
{ 0x0D57, 0x0D57 }, /* MALAYALAM AU LENGTH MARK */
|
||||
{ 0x0D62, 0x0D63 }, /* MALAYALAM VOWEL SIGN VOCALIC L - MALAYALAM VOWEL SIGN VOCALIC LL */
|
||||
{ 0x0D81, 0x0D83 }, /* SINHALA SIGN CANDRABINDU - SINHALA SIGN VISARGAYA */
|
||||
{ 0x0DCA, 0x0DCA }, /* SINHALA SIGN AL-LAKUNA */
|
||||
{ 0x0DCF, 0x0DD4 }, /* SINHALA VOWEL SIGN AELA-PILLA - SINHALA VOWEL SIGN KETTI PAA-PILLA */
|
||||
{ 0x0DD6, 0x0DD6 }, /* SINHALA VOWEL SIGN DIGA PAA-PILLA */
|
||||
{ 0x0DD8, 0x0DDF }, /* SINHALA VOWEL SIGN GAETTA-PILLA - SINHALA VOWEL SIGN GAYANUKITTA */
|
||||
{ 0x0DF2, 0x0DF3 }, /* SINHALA VOWEL SIGN DIGA GAETTA-PILLA - SINHALA VOWEL SIGN DIGA GAYANUKITTA */
|
||||
{ 0x0E31, 0x0E31 }, /* THAI CHARACTER MAI HAN-AKAT */
|
||||
{ 0x0E34, 0x0E3A }, /* THAI CHARACTER SARA I - THAI CHARACTER PHINTHU */
|
||||
{ 0x0E47, 0x0E4E }, /* THAI CHARACTER MAITAIKHU - THAI CHARACTER YAMAKKAN */
|
||||
{ 0x0EB1, 0x0EB1 }, /* LAO VOWEL SIGN MAI KAN */
|
||||
{ 0x0EB4, 0x0EBC }, /* LAO VOWEL SIGN I - LAO SEMIVOWEL SIGN LO */
|
||||
{ 0x0EC8, 0x0ECE }, /* LAO TONE MAI EK - LAO YAMAKKAN */
|
||||
{ 0x0F18, 0x0F19 }, /* TIBETAN ASTROLOGICAL SIGN -KHYUD PA - TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS */
|
||||
{ 0x0F35, 0x0F35 }, /* TIBETAN MARK NGAS BZUNG NYI ZLA */
|
||||
{ 0x0F37, 0x0F37 }, /* TIBETAN MARK NGAS BZUNG SGOR RTAGS */
|
||||
{ 0x0F39, 0x0F39 }, /* TIBETAN MARK TSA -PHRU */
|
||||
{ 0x0F3E, 0x0F3F }, /* TIBETAN SIGN YAR TSHES - TIBETAN SIGN MAR TSHES */
|
||||
{ 0x0F71, 0x0F84 }, /* TIBETAN VOWEL SIGN AA - TIBETAN MARK HALANTA */
|
||||
{ 0x0F86, 0x0F87 }, /* TIBETAN SIGN LCI RTAGS - TIBETAN SIGN YANG RTAGS */
|
||||
{ 0x0F8D, 0x0F97 }, /* TIBETAN SUBJOINED SIGN LCE TSA CAN - TIBETAN SUBJOINED LETTER JA */
|
||||
{ 0x0F99, 0x0FBC }, /* TIBETAN SUBJOINED LETTER NYA - TIBETAN SUBJOINED LETTER FIXED-FORM RA */
|
||||
{ 0x0FC6, 0x0FC6 }, /* TIBETAN SYMBOL PADMA GDAN */
|
||||
{ 0x102B, 0x103E }, /* MYANMAR VOWEL SIGN TALL AA - MYANMAR CONSONANT SIGN MEDIAL HA */
|
||||
{ 0x1056, 0x1059 }, /* MYANMAR VOWEL SIGN VOCALIC R - MYANMAR VOWEL SIGN VOCALIC LL */
|
||||
{ 0x105E, 0x1060 }, /* MYANMAR CONSONANT SIGN MON MEDIAL NA - MYANMAR CONSONANT SIGN MON MEDIAL LA */
|
||||
{ 0x1062, 0x1064 }, /* MYANMAR VOWEL SIGN SGAW KAREN EU - MYANMAR TONE MARK SGAW KAREN KE PHO */
|
||||
{ 0x1067, 0x106D }, /* MYANMAR VOWEL SIGN WESTERN PWO KAREN EU - MYANMAR SIGN WESTERN PWO KAREN TONE-5 */
|
||||
{ 0x1071, 0x1074 }, /* MYANMAR VOWEL SIGN GEBA KAREN I - MYANMAR VOWEL SIGN KAYAH EE */
|
||||
{ 0x1082, 0x108D }, /* MYANMAR CONSONANT SIGN SHAN MEDIAL WA - MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE */
|
||||
{ 0x108F, 0x108F }, /* MYANMAR SIGN RUMAI PALAUNG TONE-5 */
|
||||
{ 0x109A, 0x109D }, /* MYANMAR SIGN KHAMTI TONE-1 - MYANMAR VOWEL SIGN AITON AI */
|
||||
{ 0x135D, 0x135F }, /* ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK - ETHIOPIC COMBINING GEMINATION MARK */
|
||||
{ 0x1712, 0x1715 }, /* TAGALOG VOWEL SIGN I - TAGALOG SIGN PAMUDPOD */
|
||||
{ 0x1732, 0x1734 }, /* HANUNOO VOWEL SIGN I - HANUNOO SIGN PAMUDPOD */
|
||||
{ 0x1752, 0x1753 }, /* BUHID VOWEL SIGN I - BUHID VOWEL SIGN U */
|
||||
{ 0x1772, 0x1773 }, /* TAGBANWA VOWEL SIGN I - TAGBANWA VOWEL SIGN U */
|
||||
{ 0x17B4, 0x17D3 }, /* KHMER VOWEL INHERENT AQ - KHMER SIGN BATHAMASAT */
|
||||
{ 0x17DD, 0x17DD }, /* KHMER SIGN ATTHACAN */
|
||||
{ 0x180B, 0x180F }, /* MONGOLIAN FREE VARIATION SELECTOR ONE - MONGOLIAN FREE VARIATION SELECTOR FOUR */
|
||||
{ 0x1885, 0x1886 }, /* MONGOLIAN LETTER ALI GALI BALUDA - MONGOLIAN LETTER ALI GALI THREE BALUDA */
|
||||
{ 0x18A9, 0x18A9 }, /* MONGOLIAN LETTER ALI GALI DAGALGA */
|
||||
{ 0x1920, 0x192B }, /* LIMBU VOWEL SIGN A - LIMBU SUBJOINED LETTER WA */
|
||||
{ 0x1930, 0x193B }, /* LIMBU SMALL LETTER KA - LIMBU SIGN SA-I */
|
||||
{ 0x1A17, 0x1A1B }, /* BUGINESE VOWEL SIGN I - BUGINESE VOWEL SIGN AE */
|
||||
{ 0x1A55, 0x1A5E }, /* TAI THAM CONSONANT SIGN MEDIAL RA - TAI THAM CONSONANT SIGN SA */
|
||||
{ 0x1A60, 0x1A7C }, /* TAI THAM SIGN SAKOT - TAI THAM SIGN KHUEN-LUE KARAN */
|
||||
{ 0x1A7F, 0x1A7F }, /* TAI THAM COMBINING CRYPTOGRAMMIC DOT */
|
||||
{ 0x1AB0, 0x1ACE }, /* COMBINING DOUBLED CIRCUMFLEX ACCENT - COMBINING LATIN SMALL LETTER INSULAR T */
|
||||
{ 0x1B00, 0x1B04 }, /* BALINESE SIGN ULU RICEM - BALINESE SIGN BISAH */
|
||||
{ 0x1B34, 0x1B44 }, /* BALINESE SIGN REREKAN - BALINESE ADEG ADEG */
|
||||
{ 0x1B6B, 0x1B73 }, /* BALINESE MUSICAL SYMBOL COMBINING TEGEH - BALINESE MUSICAL SYMBOL COMBINING GONG */
|
||||
{ 0x1B80, 0x1B82 }, /* SUNDANESE SIGN PANYECEK - SUNDANESE SIGN PANGWISAD */
|
||||
{ 0x1BA1, 0x1BAD }, /* SUNDANESE CONSONANT SIGN PAMINGKAL - SUNDANESE CONSONANT SIGN PASANGAN WA */
|
||||
{ 0x1BE6, 0x1BF3 }, /* BATAK SIGN TOMPI - BATAK PANONGONAN */
|
||||
{ 0x1C24, 0x1C37 }, /* LEPCHA SUBJOINED LETTER YA - LEPCHA SIGN NUKTA */
|
||||
{ 0x1CD0, 0x1CD2 }, /* VEDIC TONE KARSHANA - VEDIC TONE PRENKHA */
|
||||
{ 0x1CD4, 0x1CE8 }, /* VEDIC SIGN YAJURVEDIC MIDLINE SVARITA - VEDIC SIGN VISARGA ANUDATTA WITH TAIL */
|
||||
{ 0x1CED, 0x1CED }, /* VEDIC SIGN TIRYAK */
|
||||
{ 0x1CF4, 0x1CF4 }, /* VEDIC TONE CANDRA ABOVE */
|
||||
{ 0x1CF7, 0x1CF9 }, /* VEDIC SIGN ATIKRAMA - VEDIC TONE DOUBLE RING ABOVE */
|
||||
{ 0x1DC0, 0x1DFF }, /* COMBINING DOTTED GRAVE ACCENT - COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW */
|
||||
{ 0x200B, 0x200F }, /* ZERO WIDTH SPACE - RIGHT-TO-LEFT MARK */
|
||||
{ 0x202A, 0x202E }, /* LEFT-TO-RIGHT EMBEDDING - RIGHT-TO-LEFT OVERRIDE */
|
||||
{ 0x2060, 0x2064 }, /* WORD JOINER - INVISIBLE PLUS */
|
||||
{ 0x2066, 0x206F }, /* LEFT-TO-RIGHT ISOLATE - NOMINAL DIGIT SHAPES */
|
||||
{ 0x20D0, 0x20F0 }, /* COMBINING LEFT HARPOON ABOVE - COMBINING ASTERISK ABOVE */
|
||||
{ 0x2640, 0x2640 }, /* FEMALE SIGN */
|
||||
{ 0x2642, 0x2642 }, /* MALE SIGN */
|
||||
{ 0x26A7, 0x26A7 }, /* MALE WITH STROKE AND MALE AND FEMALE SIGN */
|
||||
{ 0x2CEF, 0x2CF1 }, /* COPTIC COMBINING NI ABOVE - COPTIC COMBINING SPIRITUS LENIS */
|
||||
{ 0x2D7F, 0x2D7F }, /* TIFINAGH CONSONANT JOINER */
|
||||
{ 0x2DE0, 0x2DFF }, /* COMBINING CYRILLIC LETTER BE - COMBINING CYRILLIC LETTER IOTIFIED BIG YUS */
|
||||
{ 0x302A, 0x302F }, /* IDEOGRAPHIC LEVEL TONE MARK - HANGUL DOUBLE DOT TONE MARK */
|
||||
{ 0x3099, 0x309A }, /* COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK - COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
|
||||
{ 0xA66F, 0xA672 }, /* COMBINING CYRILLIC VZMET - COMBINING CYRILLIC THOUSAND MILLIONS SIGN */
|
||||
{ 0xA674, 0xA67D }, /* COMBINING CYRILLIC LETTER UKRAINIAN IE - COMBINING CYRILLIC PAYEROK */
|
||||
{ 0xA69E, 0xA69F }, /* COMBINING CYRILLIC LETTER EF - COMBINING CYRILLIC LETTER IOTIFIED E */
|
||||
{ 0xA6F0, 0xA6F1 }, /* BAMUM COMBINING MARK KOQNDON - BAMUM COMBINING MARK TUKWENTIS */
|
||||
{ 0xA802, 0xA802 }, /* SYLOTI NAGRI SIGN DVISVARA */
|
||||
{ 0xA806, 0xA806 }, /* SYLOTI NAGRI SIGN HASANTA */
|
||||
{ 0xA80B, 0xA80B }, /* SYLOTI NAGRI SIGN ANUSVARA */
|
||||
{ 0xA823, 0xA827 }, /* SYLOTI NAGRI VOWEL SIGN A - SYLOTI NAGRI VOWEL SIGN OO */
|
||||
{ 0xA82C, 0xA82C }, /* SYLOTI NAGRI SIGN ALTERNATE HASANTA */
|
||||
{ 0xA880, 0xA881 }, /* SAURASHTRA SIGN ANUSVARA - SAURASHTRA SIGN VISARGA */
|
||||
{ 0xA8B4, 0xA8C5 }, /* SAURASHTRA CONSONANT SIGN HAARU - SAURASHTRA SIGN CANDRABINDU */
|
||||
{ 0xA8E0, 0xA8F1 }, /* COMBINING DEVANAGARI DIGIT ZERO - COMBINING DEVANAGARI SIGN AVAGRAHA */
|
||||
{ 0xA8FF, 0xA8FF }, /* DEVANAGARI VOWEL SIGN AY */
|
||||
{ 0xA926, 0xA92D }, /* KAYAH LI VOWEL UE - KAYAH LI TONE CALYA PLOPHU */
|
||||
{ 0xA947, 0xA953 }, /* REJANG VOWEL SIGN I - REJANG VIRAMA */
|
||||
{ 0xA980, 0xA983 }, /* JAVANESE SIGN PANYANGGA - JAVANESE SIGN WIGNYAN */
|
||||
{ 0xA9B3, 0xA9C0 }, /* JAVANESE SIGN CECAK TELU - JAVANESE PANGKON */
|
||||
{ 0xA9E5, 0xA9E5 }, /* MYANMAR SIGN SHAN SAW */
|
||||
{ 0xAA29, 0xAA36 }, /* CHAM VOWEL SIGN AA - CHAM CONSONANT SIGN WA */
|
||||
{ 0xAA43, 0xAA43 }, /* CHAM CONSONANT SIGN FINAL NG */
|
||||
{ 0xAA4C, 0xAA4D }, /* CHAM CONSONANT SIGN FINAL M - CHAM CONSONANT SIGN FINAL H */
|
||||
{ 0xAA7B, 0xAA7D }, /* MYANMAR SIGN PAO KAREN TONE - MYANMAR SIGN TAI LAING TONE-5 */
|
||||
{ 0xAAB0, 0xAAB0 }, /* TAI VIET MAI KANG */
|
||||
{ 0xAAB2, 0xAAB4 }, /* TAI VIET VOWEL I - TAI VIET VOWEL U */
|
||||
{ 0xAAB7, 0xAAB8 }, /* TAI VIET MAI KHIT - TAI VIET VOWEL IA */
|
||||
{ 0xAABE, 0xAABF }, /* TAI VIET VOWEL AM - TAI VIET TONE MAI EK */
|
||||
{ 0xAAC1, 0xAAC1 }, /* TAI VIET TONE MAI THO */
|
||||
{ 0xAAEB, 0xAAEF }, /* MEETEI MAYEK VOWEL SIGN II - MEETEI MAYEK VOWEL SIGN AAU */
|
||||
{ 0xAAF5, 0xAAF6 }, /* MEETEI MAYEK VOWEL SIGN VISARGA - MEETEI MAYEK VIRAMA */
|
||||
{ 0xABE3, 0xABEA }, /* MEETEI MAYEK VOWEL SIGN ONAP - MEETEI MAYEK VOWEL SIGN NUNG */
|
||||
{ 0xABEC, 0xABED }, /* MEETEI MAYEK LUM IYEK - MEETEI MAYEK APUN IYEK */
|
||||
{ 0xFB1E, 0xFB1E }, /* HEBREW POINT JUDEO-SPANISH VARIKA */
|
||||
{ 0xFE00, 0xFE0F }, /* VARIATION SELECTOR-1 - VARIATION SELECTOR-16 */
|
||||
{ 0xFE20, 0xFE2F }, /* COMBINING LIGATURE LEFT HALF - COMBINING CYRILLIC TITLO RIGHT HALF */
|
||||
{ 0xFEFF, 0xFEFF }, /* ZERO WIDTH NO-BREAK SPACE */
|
||||
{ 0xFFF9, 0xFFFB }, /* INTERLINEAR ANNOTATION ANCHOR - INTERLINEAR ANNOTATION TERMINATOR */
|
||||
};
|
||||
|
||||
/* Zero-width character ranges (non-BMP, U+10000 and above) */
|
||||
static const struct ucs_interval32 ucs_zero_width_non_bmp_ranges[] = {
|
||||
{ 0x101FD, 0x101FD }, /* PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE */
|
||||
{ 0x102E0, 0x102E0 }, /* COPTIC EPACT THOUSANDS MARK */
|
||||
{ 0x10376, 0x1037A }, /* COMBINING OLD PERMIC LETTER AN - COMBINING OLD PERMIC LETTER SII */
|
||||
{ 0x10A01, 0x10A03 }, /* KHAROSHTHI VOWEL SIGN I - KHAROSHTHI VOWEL SIGN VOCALIC R */
|
||||
{ 0x10A05, 0x10A06 }, /* KHAROSHTHI VOWEL SIGN E - KHAROSHTHI VOWEL SIGN O */
|
||||
{ 0x10A0C, 0x10A0F }, /* KHAROSHTHI VOWEL LENGTH MARK - KHAROSHTHI SIGN VISARGA */
|
||||
{ 0x10A38, 0x10A3A }, /* KHAROSHTHI SIGN BAR ABOVE - KHAROSHTHI SIGN DOT BELOW */
|
||||
{ 0x10A3F, 0x10A3F }, /* KHAROSHTHI VIRAMA */
|
||||
{ 0x10AE5, 0x10AE6 }, /* MANICHAEAN ABBREVIATION MARK ABOVE - MANICHAEAN ABBREVIATION MARK BELOW */
|
||||
{ 0x10D24, 0x10D27 }, /* HANIFI ROHINGYA SIGN HARBAHAY - HANIFI ROHINGYA SIGN TASSI */
|
||||
{ 0x10D69, 0x10D6D }, /* GARAY VOWEL SIGN E - GARAY CONSONANT NASALIZATION MARK */
|
||||
{ 0x10EAB, 0x10EAC }, /* YEZIDI COMBINING HAMZA MARK - YEZIDI COMBINING MADDA MARK */
|
||||
{ 0x10EFC, 0x10EFF }, /* ARABIC COMBINING ALEF OVERLAY - ARABIC SMALL LOW WORD MADDA */
|
||||
{ 0x10F46, 0x10F50 }, /* SOGDIAN COMBINING DOT BELOW - SOGDIAN COMBINING STROKE BELOW */
|
||||
{ 0x10F82, 0x10F85 }, /* OLD UYGHUR COMBINING DOT ABOVE - OLD UYGHUR COMBINING TWO DOTS BELOW */
|
||||
{ 0x11000, 0x11002 }, /* BRAHMI SIGN CANDRABINDU - BRAHMI SIGN VISARGA */
|
||||
{ 0x11038, 0x11046 }, /* BRAHMI VOWEL SIGN AA - BRAHMI VIRAMA */
|
||||
{ 0x11070, 0x11070 }, /* BRAHMI SIGN OLD TAMIL VIRAMA */
|
||||
{ 0x11073, 0x11074 }, /* BRAHMI VOWEL SIGN OLD TAMIL SHORT E - BRAHMI VOWEL SIGN OLD TAMIL SHORT O */
|
||||
{ 0x1107F, 0x11082 }, /* BRAHMI NUMBER JOINER - KAITHI SIGN VISARGA */
|
||||
{ 0x110B0, 0x110BA }, /* KAITHI VOWEL SIGN AA - KAITHI SIGN NUKTA */
|
||||
{ 0x110BD, 0x110BD }, /* KAITHI NUMBER SIGN */
|
||||
{ 0x110C2, 0x110C2 }, /* KAITHI VOWEL SIGN VOCALIC R */
|
||||
{ 0x110CD, 0x110CD }, /* KAITHI NUMBER SIGN ABOVE */
|
||||
{ 0x11100, 0x11102 }, /* CHAKMA SIGN CANDRABINDU - CHAKMA SIGN VISARGA */
|
||||
{ 0x11127, 0x11134 }, /* CHAKMA VOWEL SIGN A - CHAKMA MAAYYAA */
|
||||
{ 0x11145, 0x11146 }, /* CHAKMA VOWEL SIGN AA - CHAKMA VOWEL SIGN EI */
|
||||
{ 0x11173, 0x11173 }, /* MAHAJANI SIGN NUKTA */
|
||||
{ 0x11180, 0x11182 }, /* SHARADA SIGN CANDRABINDU - SHARADA SIGN VISARGA */
|
||||
{ 0x111B3, 0x111C0 }, /* SHARADA VOWEL SIGN AA - SHARADA SIGN VIRAMA */
|
||||
{ 0x111C9, 0x111CC }, /* SHARADA SANDHI MARK - SHARADA EXTRA SHORT VOWEL MARK */
|
||||
{ 0x111CE, 0x111CF }, /* SHARADA VOWEL SIGN PRISHTHAMATRA E - SHARADA SIGN INVERTED CANDRABINDU */
|
||||
{ 0x1122C, 0x11237 }, /* KHOJKI VOWEL SIGN AA - KHOJKI SIGN SHADDA */
|
||||
{ 0x1123E, 0x1123E }, /* KHOJKI SIGN SUKUN */
|
||||
{ 0x11241, 0x11241 }, /* KHOJKI VOWEL SIGN VOCALIC R */
|
||||
{ 0x112DF, 0x112EA }, /* KHUDAWADI SIGN ANUSVARA - KHUDAWADI SIGN VIRAMA */
|
||||
{ 0x11300, 0x11303 }, /* GRANTHA SIGN COMBINING ANUSVARA ABOVE - GRANTHA SIGN VISARGA */
|
||||
{ 0x1133B, 0x1133C }, /* COMBINING BINDU BELOW - GRANTHA SIGN NUKTA */
|
||||
{ 0x1133E, 0x11344 }, /* GRANTHA VOWEL SIGN AA - GRANTHA VOWEL SIGN VOCALIC RR */
|
||||
{ 0x11347, 0x11348 }, /* GRANTHA VOWEL SIGN EE - GRANTHA VOWEL SIGN AI */
|
||||
{ 0x1134B, 0x1134D }, /* GRANTHA VOWEL SIGN OO - GRANTHA SIGN VIRAMA */
|
||||
{ 0x11357, 0x11357 }, /* GRANTHA AU LENGTH MARK */
|
||||
{ 0x11362, 0x11363 }, /* GRANTHA VOWEL SIGN VOCALIC L - GRANTHA VOWEL SIGN VOCALIC LL */
|
||||
{ 0x11366, 0x1136C }, /* COMBINING GRANTHA DIGIT ZERO - COMBINING GRANTHA DIGIT SIX */
|
||||
{ 0x11370, 0x11374 }, /* COMBINING GRANTHA LETTER A - COMBINING GRANTHA LETTER PA */
|
||||
{ 0x113B8, 0x113C0 }, /* TULU-TIGALARI VOWEL SIGN AA - TULU-TIGALARI VOWEL SIGN VOCALIC LL */
|
||||
{ 0x113C2, 0x113C2 }, /* TULU-TIGALARI VOWEL SIGN EE */
|
||||
{ 0x113C5, 0x113C5 }, /* TULU-TIGALARI VOWEL SIGN AI */
|
||||
{ 0x113C7, 0x113CA }, /* TULU-TIGALARI VOWEL SIGN OO - TULU-TIGALARI SIGN CANDRA ANUNASIKA */
|
||||
{ 0x113CC, 0x113D0 }, /* TULU-TIGALARI SIGN ANUSVARA - TULU-TIGALARI CONJOINER */
|
||||
{ 0x113D2, 0x113D2 }, /* TULU-TIGALARI GEMINATION MARK */
|
||||
{ 0x113E1, 0x113E2 }, /* TULU-TIGALARI VEDIC TONE SVARITA - TULU-TIGALARI VEDIC TONE ANUDATTA */
|
||||
{ 0x11435, 0x11446 }, /* NEWA VOWEL SIGN AA - NEWA SIGN NUKTA */
|
||||
{ 0x1145E, 0x1145E }, /* NEWA SANDHI MARK */
|
||||
{ 0x114B0, 0x114C3 }, /* TIRHUTA VOWEL SIGN AA - TIRHUTA SIGN NUKTA */
|
||||
{ 0x115AF, 0x115B5 }, /* SIDDHAM VOWEL SIGN AA - SIDDHAM VOWEL SIGN VOCALIC RR */
|
||||
{ 0x115B8, 0x115C0 }, /* SIDDHAM VOWEL SIGN E - SIDDHAM SIGN NUKTA */
|
||||
{ 0x115DC, 0x115DD }, /* SIDDHAM VOWEL SIGN ALTERNATE U - SIDDHAM VOWEL SIGN ALTERNATE UU */
|
||||
{ 0x11630, 0x11640 }, /* MODI VOWEL SIGN AA - MODI SIGN ARDHACANDRA */
|
||||
{ 0x116AB, 0x116B7 }, /* TAKRI SIGN ANUSVARA - TAKRI SIGN NUKTA */
|
||||
{ 0x1171D, 0x1172B }, /* AHOM CONSONANT SIGN MEDIAL LA - AHOM SIGN KILLER */
|
||||
{ 0x1182C, 0x1183A }, /* DOGRA VOWEL SIGN AA - DOGRA SIGN NUKTA */
|
||||
{ 0x11930, 0x11935 }, /* DIVES AKURU VOWEL SIGN AA - DIVES AKURU VOWEL SIGN E */
|
||||
{ 0x11937, 0x11938 }, /* DIVES AKURU VOWEL SIGN AI - DIVES AKURU VOWEL SIGN O */
|
||||
{ 0x1193B, 0x1193E }, /* DIVES AKURU SIGN ANUSVARA - DIVES AKURU VIRAMA */
|
||||
{ 0x11940, 0x11940 }, /* DIVES AKURU MEDIAL YA */
|
||||
{ 0x11942, 0x11943 }, /* DIVES AKURU MEDIAL RA - DIVES AKURU SIGN NUKTA */
|
||||
{ 0x119D1, 0x119D7 }, /* NANDINAGARI VOWEL SIGN AA - NANDINAGARI VOWEL SIGN VOCALIC RR */
|
||||
{ 0x119DA, 0x119E0 }, /* NANDINAGARI VOWEL SIGN E - NANDINAGARI SIGN VIRAMA */
|
||||
{ 0x119E4, 0x119E4 }, /* NANDINAGARI VOWEL SIGN PRISHTHAMATRA E */
|
||||
{ 0x11A01, 0x11A0A }, /* ZANABAZAR SQUARE VOWEL SIGN I - ZANABAZAR SQUARE VOWEL LENGTH MARK */
|
||||
{ 0x11A33, 0x11A39 }, /* ZANABAZAR SQUARE FINAL CONSONANT MARK - ZANABAZAR SQUARE SIGN VISARGA */
|
||||
{ 0x11A3B, 0x11A3E }, /* ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA - ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA */
|
||||
{ 0x11A47, 0x11A47 }, /* ZANABAZAR SQUARE SUBJOINER */
|
||||
{ 0x11A51, 0x11A5B }, /* SOYOMBO VOWEL SIGN I - SOYOMBO VOWEL LENGTH MARK */
|
||||
{ 0x11A8A, 0x11A99 }, /* SOYOMBO FINAL CONSONANT SIGN G - SOYOMBO SUBJOINER */
|
||||
{ 0x11C2F, 0x11C36 }, /* BHAIKSUKI VOWEL SIGN AA - BHAIKSUKI VOWEL SIGN VOCALIC L */
|
||||
{ 0x11C38, 0x11C3F }, /* BHAIKSUKI VOWEL SIGN E - BHAIKSUKI SIGN VIRAMA */
|
||||
{ 0x11C92, 0x11CA7 }, /* MARCHEN SUBJOINED LETTER KA - MARCHEN SUBJOINED LETTER ZA */
|
||||
{ 0x11CA9, 0x11CB6 }, /* MARCHEN SUBJOINED LETTER YA - MARCHEN SIGN CANDRABINDU */
|
||||
{ 0x11D31, 0x11D36 }, /* MASARAM GONDI VOWEL SIGN AA - MASARAM GONDI VOWEL SIGN VOCALIC R */
|
||||
{ 0x11D3A, 0x11D3A }, /* MASARAM GONDI VOWEL SIGN E */
|
||||
{ 0x11D3C, 0x11D3D }, /* MASARAM GONDI VOWEL SIGN AI - MASARAM GONDI VOWEL SIGN O */
|
||||
{ 0x11D3F, 0x11D45 }, /* MASARAM GONDI VOWEL SIGN AU - MASARAM GONDI VIRAMA */
|
||||
{ 0x11D47, 0x11D47 }, /* MASARAM GONDI RA-KARA */
|
||||
{ 0x11D8A, 0x11D8E }, /* GUNJALA GONDI VOWEL SIGN AA - GUNJALA GONDI VOWEL SIGN UU */
|
||||
{ 0x11D90, 0x11D91 }, /* GUNJALA GONDI VOWEL SIGN EE - GUNJALA GONDI VOWEL SIGN AI */
|
||||
{ 0x11D93, 0x11D97 }, /* GUNJALA GONDI VOWEL SIGN OO - GUNJALA GONDI VIRAMA */
|
||||
{ 0x11EF3, 0x11EF6 }, /* MAKASAR VOWEL SIGN I - MAKASAR VOWEL SIGN O */
|
||||
{ 0x11F00, 0x11F01 }, /* KAWI SIGN CANDRABINDU - KAWI SIGN ANUSVARA */
|
||||
{ 0x11F03, 0x11F03 }, /* KAWI SIGN VISARGA */
|
||||
{ 0x11F34, 0x11F3A }, /* KAWI VOWEL SIGN AA - KAWI VOWEL SIGN VOCALIC R */
|
||||
{ 0x11F3E, 0x11F42 }, /* KAWI VOWEL SIGN E - KAWI CONJOINER */
|
||||
{ 0x11F5A, 0x11F5A }, /* KAWI SIGN NUKTA */
|
||||
{ 0x13430, 0x13440 }, /* EGYPTIAN HIEROGLYPH VERTICAL JOINER - EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY */
|
||||
{ 0x13447, 0x13455 }, /* EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START - EGYPTIAN HIEROGLYPH MODIFIER DAMAGED */
|
||||
{ 0x1611E, 0x1612F }, /* GURUNG KHEMA VOWEL SIGN AA - GURUNG KHEMA SIGN THOLHOMA */
|
||||
{ 0x16AF0, 0x16AF4 }, /* BASSA VAH COMBINING HIGH TONE - BASSA VAH COMBINING HIGH-LOW TONE */
|
||||
{ 0x16B30, 0x16B36 }, /* PAHAWH HMONG MARK CIM TUB - PAHAWH HMONG MARK CIM TAUM */
|
||||
{ 0x16F4F, 0x16F4F }, /* MIAO SIGN CONSONANT MODIFIER BAR */
|
||||
{ 0x16F51, 0x16F87 }, /* MIAO SIGN ASPIRATION - MIAO VOWEL SIGN UI */
|
||||
{ 0x16F8F, 0x16F92 }, /* MIAO TONE RIGHT - MIAO TONE BELOW */
|
||||
{ 0x16FE4, 0x16FE4 }, /* KHITAN SMALL SCRIPT FILLER */
|
||||
{ 0x16FF0, 0x16FF1 }, /* VIETNAMESE ALTERNATE READING MARK CA - VIETNAMESE ALTERNATE READING MARK NHAY */
|
||||
{ 0x1BC9D, 0x1BC9E }, /* DUPLOYAN THICK LETTER SELECTOR - DUPLOYAN DOUBLE MARK */
|
||||
{ 0x1BCA0, 0x1BCA3 }, /* SHORTHAND FORMAT LETTER OVERLAP - SHORTHAND FORMAT UP STEP */
|
||||
{ 0x1CF00, 0x1CF2D }, /* ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT - ZNAMENNY COMBINING MARK KRYZH ON LEFT */
|
||||
{ 0x1CF30, 0x1CF46 }, /* ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO - ZNAMENNY PRIZNAK MODIFIER ROG */
|
||||
{ 0x1D165, 0x1D169 }, /* MUSICAL SYMBOL COMBINING STEM - MUSICAL SYMBOL COMBINING TREMOLO-3 */
|
||||
{ 0x1D16D, 0x1D182 }, /* MUSICAL SYMBOL COMBINING AUGMENTATION DOT - MUSICAL SYMBOL COMBINING LOURE */
|
||||
{ 0x1D185, 0x1D18B }, /* MUSICAL SYMBOL COMBINING DOIT - MUSICAL SYMBOL COMBINING TRIPLE TONGUE */
|
||||
{ 0x1D1AA, 0x1D1AD }, /* MUSICAL SYMBOL COMBINING DOWN BOW - MUSICAL SYMBOL COMBINING SNAP PIZZICATO */
|
||||
{ 0x1D242, 0x1D244 }, /* COMBINING GREEK MUSICAL TRISEME - COMBINING GREEK MUSICAL PENTASEME */
|
||||
{ 0x1DA00, 0x1DA36 }, /* SIGNWRITING HEAD RIM - SIGNWRITING AIR SUCKING IN */
|
||||
{ 0x1DA3B, 0x1DA6C }, /* SIGNWRITING MOUTH CLOSED NEUTRAL - SIGNWRITING EXCITEMENT */
|
||||
{ 0x1DA75, 0x1DA75 }, /* SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS */
|
||||
{ 0x1DA84, 0x1DA84 }, /* SIGNWRITING LOCATION HEAD NECK */
|
||||
{ 0x1DA9B, 0x1DA9F }, /* SIGNWRITING FILL MODIFIER-2 - SIGNWRITING FILL MODIFIER-6 */
|
||||
{ 0x1DAA1, 0x1DAAF }, /* SIGNWRITING ROTATION MODIFIER-2 - SIGNWRITING ROTATION MODIFIER-16 */
|
||||
{ 0x1E000, 0x1E006 }, /* COMBINING GLAGOLITIC LETTER AZU - COMBINING GLAGOLITIC LETTER ZHIVETE */
|
||||
{ 0x1E008, 0x1E018 }, /* COMBINING GLAGOLITIC LETTER ZEMLJA - COMBINING GLAGOLITIC LETTER HERU */
|
||||
{ 0x1E01B, 0x1E021 }, /* COMBINING GLAGOLITIC LETTER SHTA - COMBINING GLAGOLITIC LETTER YATI */
|
||||
{ 0x1E023, 0x1E024 }, /* COMBINING GLAGOLITIC LETTER YU - COMBINING GLAGOLITIC LETTER SMALL YUS */
|
||||
{ 0x1E026, 0x1E02A }, /* COMBINING GLAGOLITIC LETTER YO - COMBINING GLAGOLITIC LETTER FITA */
|
||||
{ 0x1E08F, 0x1E08F }, /* COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
|
||||
{ 0x1E130, 0x1E136 }, /* NYIAKENG PUACHUE HMONG TONE-B - NYIAKENG PUACHUE HMONG TONE-D */
|
||||
{ 0x1E2AE, 0x1E2AE }, /* TOTO SIGN RISING TONE */
|
||||
{ 0x1E2EC, 0x1E2EF }, /* WANCHO TONE TUP - WANCHO TONE KOINI */
|
||||
{ 0x1E4EC, 0x1E4EF }, /* NAG MUNDARI SIGN MUHOR - NAG MUNDARI SIGN SUTUH */
|
||||
{ 0x1E5EE, 0x1E5EF }, /* OL ONAL SIGN MU - OL ONAL SIGN IKIR */
|
||||
{ 0x1E8D0, 0x1E8D6 }, /* MENDE KIKAKUI COMBINING NUMBER TEENS - MENDE KIKAKUI COMBINING NUMBER MILLIONS */
|
||||
{ 0x1E944, 0x1E94A }, /* ADLAM ALIF LENGTHENER - ADLAM NUKTA */
|
||||
{ 0x1F3FB, 0x1F3FF }, /* EMOJI MODIFIER FITZPATRICK TYPE-1-2 - EMOJI MODIFIER FITZPATRICK TYPE-6 */
|
||||
{ 0x1F9B0, 0x1F9B3 }, /* EMOJI COMPONENT RED HAIR - EMOJI COMPONENT WHITE HAIR */
|
||||
{ 0xE0001, 0xE0001 }, /* LANGUAGE TAG */
|
||||
{ 0xE0020, 0xE007F }, /* TAG SPACE - CANCEL TAG */
|
||||
{ 0xE0100, 0xE01EF }, /* VARIATION SELECTOR-17 - VARIATION SELECTOR-256 */
|
||||
};
|
||||
|
||||
/* Double-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */
|
||||
static const struct ucs_interval16 ucs_double_width_bmp_ranges[] = {
|
||||
{ 0x1100, 0x115F }, /* HANGUL CHOSEONG KIYEOK - HANGUL CHOSEONG FILLER */
|
||||
{ 0x231A, 0x231B }, /* WATCH - HOURGLASS */
|
||||
{ 0x2329, 0x232A }, /* LEFT-POINTING ANGLE BRACKET - RIGHT-POINTING ANGLE BRACKET */
|
||||
{ 0x23E9, 0x23EC }, /* BLACK RIGHT-POINTING DOUBLE TRIANGLE - BLACK DOWN-POINTING DOUBLE TRIANGLE */
|
||||
{ 0x23F0, 0x23F0 }, /* ALARM CLOCK */
|
||||
{ 0x23F3, 0x23F3 }, /* HOURGLASS WITH FLOWING SAND */
|
||||
{ 0x25FD, 0x25FE }, /* WHITE MEDIUM SMALL SQUARE - BLACK MEDIUM SMALL SQUARE */
|
||||
{ 0x2614, 0x2615 }, /* UMBRELLA WITH RAIN DROPS - HOT BEVERAGE */
|
||||
{ 0x2630, 0x2637 }, /* TRIGRAM FOR HEAVEN - TRIGRAM FOR EARTH */
|
||||
{ 0x2648, 0x2653 }, /* ARIES - PISCES */
|
||||
{ 0x267F, 0x267F }, /* WHEELCHAIR SYMBOL */
|
||||
{ 0x268A, 0x268F }, /* MONOGRAM FOR YANG - DIGRAM FOR GREATER YIN */
|
||||
{ 0x2693, 0x2693 }, /* ANCHOR */
|
||||
{ 0x26A1, 0x26A1 }, /* HIGH VOLTAGE SIGN */
|
||||
{ 0x26AA, 0x26AB }, /* MEDIUM WHITE CIRCLE - MEDIUM BLACK CIRCLE */
|
||||
{ 0x26BD, 0x26BE }, /* SOCCER BALL - BASEBALL */
|
||||
{ 0x26C4, 0x26C5 }, /* SNOWMAN WITHOUT SNOW - SUN BEHIND CLOUD */
|
||||
{ 0x26CE, 0x26CE }, /* OPHIUCHUS */
|
||||
{ 0x26D4, 0x26D4 }, /* NO ENTRY */
|
||||
{ 0x26EA, 0x26EA }, /* CHURCH */
|
||||
{ 0x26F2, 0x26F3 }, /* FOUNTAIN - FLAG IN HOLE */
|
||||
{ 0x26F5, 0x26F5 }, /* SAILBOAT */
|
||||
{ 0x26FA, 0x26FA }, /* TENT */
|
||||
{ 0x26FD, 0x26FD }, /* FUEL PUMP */
|
||||
{ 0x2705, 0x2705 }, /* WHITE HEAVY CHECK MARK */
|
||||
{ 0x270A, 0x270B }, /* RAISED FIST - RAISED HAND */
|
||||
{ 0x2728, 0x2728 }, /* SPARKLES */
|
||||
{ 0x274C, 0x274C }, /* CROSS MARK */
|
||||
{ 0x274E, 0x274E }, /* NEGATIVE SQUARED CROSS MARK */
|
||||
{ 0x2753, 0x2755 }, /* BLACK QUESTION MARK ORNAMENT - WHITE EXCLAMATION MARK ORNAMENT */
|
||||
{ 0x2757, 0x2757 }, /* HEAVY EXCLAMATION MARK SYMBOL */
|
||||
{ 0x2795, 0x2797 }, /* HEAVY PLUS SIGN - HEAVY DIVISION SIGN */
|
||||
{ 0x27B0, 0x27B0 }, /* CURLY LOOP */
|
||||
{ 0x27BF, 0x27BF }, /* DOUBLE CURLY LOOP */
|
||||
{ 0x2B1B, 0x2B1C }, /* BLACK LARGE SQUARE - WHITE LARGE SQUARE */
|
||||
{ 0x2B50, 0x2B50 }, /* WHITE MEDIUM STAR */
|
||||
{ 0x2B55, 0x2B55 }, /* HEAVY LARGE CIRCLE */
|
||||
{ 0x2E80, 0x2E99 }, /* CJK RADICAL REPEAT - CJK RADICAL RAP */
|
||||
{ 0x2E9B, 0x2EF3 }, /* CJK RADICAL CHOKE - CJK RADICAL C-SIMPLIFIED TURTLE */
|
||||
{ 0x2F00, 0x2FD5 }, /* KANGXI RADICAL ONE - KANGXI RADICAL FLUTE */
|
||||
{ 0x2FF0, 0x3029 }, /* IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT - HANGZHOU NUMERAL NINE */
|
||||
{ 0x3030, 0x303E }, /* WAVY DASH - IDEOGRAPHIC VARIATION INDICATOR */
|
||||
{ 0x3041, 0x3096 }, /* HIRAGANA LETTER SMALL A - HIRAGANA LETTER SMALL KE */
|
||||
{ 0x309B, 0x30FF }, /* KATAKANA-HIRAGANA VOICED SOUND MARK - KATAKANA DIGRAPH KOTO */
|
||||
{ 0x3105, 0x312F }, /* BOPOMOFO LETTER B - BOPOMOFO LETTER NN */
|
||||
{ 0x3131, 0x318E }, /* HANGUL LETTER KIYEOK - HANGUL LETTER ARAEAE */
|
||||
{ 0x3190, 0x31E5 }, /* IDEOGRAPHIC ANNOTATION LINKING MARK - CJK STROKE SZP */
|
||||
{ 0x31EF, 0x321E }, /* IDEOGRAPHIC DESCRIPTION CHARACTER SUBTRACTION - PARENTHESIZED KOREAN CHARACTER O HU */
|
||||
{ 0x3220, 0x3247 }, /* PARENTHESIZED IDEOGRAPH ONE - CIRCLED IDEOGRAPH KOTO */
|
||||
{ 0x3250, 0xA48C }, /* PARTNERSHIP SIGN - YI SYLLABLE YYR */
|
||||
{ 0xA490, 0xA4C6 }, /* YI RADICAL QOT - YI RADICAL KE */
|
||||
{ 0xA960, 0xA97C }, /* HANGUL CHOSEONG TIKEUT-MIEUM - HANGUL CHOSEONG SSANGYEORINHIEUH */
|
||||
{ 0xAC00, 0xD7A3 }, /* HANGUL SYLLABLE GA - HANGUL SYLLABLE HIH */
|
||||
{ 0xF900, 0xFAFF }, /* U+F900 - U+FAFF */
|
||||
{ 0xFE10, 0xFE19 }, /* PRESENTATION FORM FOR VERTICAL COMMA - PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS */
|
||||
{ 0xFE30, 0xFE52 }, /* PRESENTATION FORM FOR VERTICAL TWO DOT LEADER - SMALL FULL STOP */
|
||||
{ 0xFE54, 0xFE66 }, /* SMALL SEMICOLON - SMALL EQUALS SIGN */
|
||||
{ 0xFE68, 0xFE6B }, /* SMALL REVERSE SOLIDUS - SMALL COMMERCIAL AT */
|
||||
{ 0xFF01, 0xFF60 }, /* FULLWIDTH EXCLAMATION MARK - FULLWIDTH RIGHT WHITE PARENTHESIS */
|
||||
{ 0xFFE0, 0xFFE6 }, /* FULLWIDTH CENT SIGN - FULLWIDTH WON SIGN */
|
||||
};
|
||||
|
||||
/* Double-width character ranges (non-BMP, U+10000 and above) */
|
||||
static const struct ucs_interval32 ucs_double_width_non_bmp_ranges[] = {
|
||||
{ 0x16FE0, 0x16FE3 }, /* TANGUT ITERATION MARK - OLD CHINESE ITERATION MARK */
|
||||
{ 0x17000, 0x187F7 }, /* U+17000 - U+187F7 */
|
||||
{ 0x18800, 0x18CD5 }, /* TANGUT COMPONENT-001 - KHITAN SMALL SCRIPT CHARACTER-18CD5 */
|
||||
{ 0x18CFF, 0x18D08 }, /* U+18CFF - U+18D08 */
|
||||
{ 0x1AFF0, 0x1AFF3 }, /* KATAKANA LETTER MINNAN TONE-2 - KATAKANA LETTER MINNAN TONE-5 */
|
||||
{ 0x1AFF5, 0x1AFFB }, /* KATAKANA LETTER MINNAN TONE-7 - KATAKANA LETTER MINNAN NASALIZED TONE-5 */
|
||||
{ 0x1AFFD, 0x1AFFE }, /* KATAKANA LETTER MINNAN NASALIZED TONE-7 - KATAKANA LETTER MINNAN NASALIZED TONE-8 */
|
||||
{ 0x1B000, 0x1B122 }, /* KATAKANA LETTER ARCHAIC E - KATAKANA LETTER ARCHAIC WU */
|
||||
{ 0x1B132, 0x1B132 }, /* HIRAGANA LETTER SMALL KO */
|
||||
{ 0x1B150, 0x1B152 }, /* HIRAGANA LETTER SMALL WI - HIRAGANA LETTER SMALL WO */
|
||||
{ 0x1B155, 0x1B155 }, /* KATAKANA LETTER SMALL KO */
|
||||
{ 0x1B164, 0x1B167 }, /* KATAKANA LETTER SMALL WI - KATAKANA LETTER SMALL N */
|
||||
{ 0x1B170, 0x1B2FB }, /* NUSHU CHARACTER-1B170 - NUSHU CHARACTER-1B2FB */
|
||||
{ 0x1D300, 0x1D356 }, /* MONOGRAM FOR EARTH - TETRAGRAM FOR FOSTERING */
|
||||
{ 0x1D360, 0x1D376 }, /* COUNTING ROD UNIT DIGIT ONE - IDEOGRAPHIC TALLY MARK FIVE */
|
||||
{ 0x1F000, 0x1F02F }, /* U+1F000 - U+1F02F */
|
||||
{ 0x1F0A0, 0x1F0FF }, /* U+1F0A0 - U+1F0FF */
|
||||
{ 0x1F18E, 0x1F18E }, /* NEGATIVE SQUARED AB */
|
||||
{ 0x1F191, 0x1F19A }, /* SQUARED CL - SQUARED VS */
|
||||
{ 0x1F200, 0x1F202 }, /* SQUARE HIRAGANA HOKA - SQUARED KATAKANA SA */
|
||||
{ 0x1F210, 0x1F23B }, /* SQUARED CJK UNIFIED IDEOGRAPH-624B - SQUARED CJK UNIFIED IDEOGRAPH-914D */
|
||||
{ 0x1F240, 0x1F248 }, /* TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C - TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 */
|
||||
{ 0x1F250, 0x1F251 }, /* CIRCLED IDEOGRAPH ADVANTAGE - CIRCLED IDEOGRAPH ACCEPT */
|
||||
{ 0x1F260, 0x1F265 }, /* ROUNDED SYMBOL FOR FU - ROUNDED SYMBOL FOR CAI */
|
||||
{ 0x1F300, 0x1F3FA }, /* CYCLONE - AMPHORA */
|
||||
{ 0x1F400, 0x1F64F }, /* RAT - PERSON WITH FOLDED HANDS */
|
||||
{ 0x1F680, 0x1F9AF }, /* ROCKET - PROBING CANE */
|
||||
{ 0x1F9B4, 0x1FAFF }, /* U+1F9B4 - U+1FAFF */
|
||||
{ 0x20000, 0x2FFFD }, /* U+20000 - U+2FFFD */
|
||||
{ 0x30000, 0x3FFFD }, /* U+30000 - U+3FFFD */
|
||||
};
|
|
@ -104,7 +104,6 @@
|
|||
#include <linux/uaccess.h>
|
||||
#include <linux/kdb.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/bsearch.h>
|
||||
#include <linux/gcd.h>
|
||||
|
||||
#define MAX_NR_CON_DRIVER 16
|
||||
|
@ -444,6 +443,15 @@ static void vc_uniscr_scroll(struct vc_data *vc, unsigned int top,
|
|||
}
|
||||
}
|
||||
|
||||
static u32 vc_uniscr_getc(struct vc_data *vc, int relative_pos)
|
||||
{
|
||||
int pos = vc->state.x + vc->vc_need_wrap + relative_pos;
|
||||
|
||||
if (vc->vc_uni_lines && in_range(pos, 0, vc->vc_cols))
|
||||
return vc->vc_uni_lines[vc->state.y][pos];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vc_uniscr_copy_area(u32 **dst_lines,
|
||||
unsigned int dst_cols,
|
||||
unsigned int dst_rows,
|
||||
|
@ -1862,6 +1870,14 @@ int mouse_reporting(void)
|
|||
return vc_cons[fg_console].d->vc_report_mouse;
|
||||
}
|
||||
|
||||
/* invoked via ioctl(TIOCLINUX) */
|
||||
static int get_bracketed_paste(struct tty_struct *tty)
|
||||
{
|
||||
struct vc_data *vc = tty->driver_data;
|
||||
|
||||
return vc->vc_bracketed_paste;
|
||||
}
|
||||
|
||||
enum {
|
||||
CSI_DEC_hl_CURSOR_KEYS = 1, /* CKM: cursor keys send ^[Ox/^[[x */
|
||||
CSI_DEC_hl_132_COLUMNS = 3, /* COLM: 80/132 mode switch */
|
||||
|
@ -1872,6 +1888,7 @@ enum {
|
|||
CSI_DEC_hl_MOUSE_X10 = 9,
|
||||
CSI_DEC_hl_SHOW_CURSOR = 25, /* TCEM */
|
||||
CSI_DEC_hl_MOUSE_VT200 = 1000,
|
||||
CSI_DEC_hl_BRACKETED_PASTE = 2004,
|
||||
};
|
||||
|
||||
/* console_lock is held */
|
||||
|
@ -1924,6 +1941,9 @@ static void csi_DEC_hl(struct vc_data *vc, bool on_off)
|
|||
case CSI_DEC_hl_MOUSE_VT200:
|
||||
vc->vc_report_mouse = on_off ? 2 : 0;
|
||||
break;
|
||||
case CSI_DEC_hl_BRACKETED_PASTE:
|
||||
vc->vc_bracketed_paste = on_off;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2149,6 +2169,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
|
|||
vc->state.charset = 0;
|
||||
vc->vc_need_wrap = 0;
|
||||
vc->vc_report_mouse = 0;
|
||||
vc->vc_bracketed_paste = 0;
|
||||
vc->vc_utf = default_utf8;
|
||||
vc->vc_utf_count = 0;
|
||||
|
||||
|
@ -2712,43 +2733,6 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
|
|||
}
|
||||
}
|
||||
|
||||
/* is_double_width() is based on the wcwidth() implementation by
|
||||
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
|
||||
* Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
||||
*/
|
||||
struct interval {
|
||||
uint32_t first;
|
||||
uint32_t last;
|
||||
};
|
||||
|
||||
static int ucs_cmp(const void *key, const void *elt)
|
||||
{
|
||||
uint32_t ucs = *(uint32_t *)key;
|
||||
struct interval e = *(struct interval *) elt;
|
||||
|
||||
if (ucs > e.last)
|
||||
return 1;
|
||||
else if (ucs < e.first)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_double_width(uint32_t ucs)
|
||||
{
|
||||
static const struct interval double_width[] = {
|
||||
{ 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
|
||||
{ 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
|
||||
{ 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 },
|
||||
{ 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
|
||||
};
|
||||
if (ucs < double_width[0].first ||
|
||||
ucs > double_width[ARRAY_SIZE(double_width) - 1].last)
|
||||
return 0;
|
||||
|
||||
return bsearch(&ucs, double_width, ARRAY_SIZE(double_width),
|
||||
sizeof(struct interval), ucs_cmp) != NULL;
|
||||
}
|
||||
|
||||
struct vc_draw_region {
|
||||
unsigned long from, to;
|
||||
int x;
|
||||
|
@ -2817,7 +2801,7 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
|
|||
if ((c & 0xc0) == 0x80) {
|
||||
/* Unexpected continuation byte? */
|
||||
if (!vc->vc_utf_count)
|
||||
return 0xfffd;
|
||||
goto bad_sequence;
|
||||
|
||||
vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
|
||||
vc->vc_npar++;
|
||||
|
@ -2829,17 +2813,17 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
|
|||
/* Reject overlong sequences */
|
||||
if (c <= utf8_length_changes[vc->vc_npar - 1] ||
|
||||
c > utf8_length_changes[vc->vc_npar])
|
||||
return 0xfffd;
|
||||
goto bad_sequence;
|
||||
|
||||
return vc_sanitize_unicode(c);
|
||||
}
|
||||
|
||||
/* Single ASCII byte or first byte of a sequence received */
|
||||
if (vc->vc_utf_count) {
|
||||
/* Continuation byte expected */
|
||||
/* A continuation byte was expected */
|
||||
*rescan = true;
|
||||
vc->vc_utf_count = 0;
|
||||
return 0xfffd;
|
||||
goto bad_sequence;
|
||||
}
|
||||
|
||||
/* Nothing to do if an ASCII byte was received */
|
||||
|
@ -2858,11 +2842,14 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
|
|||
vc->vc_utf_count = 3;
|
||||
vc->vc_utf_char = (c & 0x07);
|
||||
} else {
|
||||
return 0xfffd;
|
||||
goto bad_sequence;
|
||||
}
|
||||
|
||||
need_more_bytes:
|
||||
return -1;
|
||||
|
||||
bad_sequence:
|
||||
return 0xfffd;
|
||||
}
|
||||
|
||||
static int vc_translate(struct vc_data *vc, int *c, bool *rescan)
|
||||
|
@ -2940,54 +2927,143 @@ static bool vc_is_control(struct vc_data *vc, int tc, int c)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void vc_con_rewind(struct vc_data *vc)
|
||||
{
|
||||
if (vc->state.x && !vc->vc_need_wrap) {
|
||||
vc->vc_pos -= 2;
|
||||
vc->state.x--;
|
||||
}
|
||||
vc->vc_need_wrap = 0;
|
||||
}
|
||||
|
||||
#define UCS_ZWS 0x200b /* Zero Width Space */
|
||||
#define UCS_VS16 0xfe0f /* Variation Selector 16 */
|
||||
#define UCS_REPLACEMENT 0xfffd /* Replacement Character */
|
||||
|
||||
static int vc_process_ucs(struct vc_data *vc, int *c, int *tc)
|
||||
{
|
||||
u32 prev_c, curr_c = *c;
|
||||
|
||||
if (ucs_is_double_width(curr_c)) {
|
||||
/*
|
||||
* The Unicode screen memory is allocated only when
|
||||
* required. This is one such case as we need to remember
|
||||
* which displayed characters are double-width.
|
||||
*/
|
||||
vc_uniscr_check(vc);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!ucs_is_zero_width(curr_c))
|
||||
return 1;
|
||||
|
||||
/* From here curr_c is known to be zero-width. */
|
||||
|
||||
if (ucs_is_double_width(vc_uniscr_getc(vc, -2))) {
|
||||
/*
|
||||
* Let's merge this zero-width code point with the preceding
|
||||
* double-width code point by replacing the existing
|
||||
* zero-width space padding. To do so we rewind one column
|
||||
* and pretend this has a width of 1.
|
||||
* We give the legacy display the same initial space padding.
|
||||
*/
|
||||
vc_con_rewind(vc);
|
||||
*tc = ' ';
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* From here the preceding character, if any, must be single-width. */
|
||||
prev_c = vc_uniscr_getc(vc, -1);
|
||||
|
||||
if (curr_c == UCS_VS16 && prev_c != 0) {
|
||||
/*
|
||||
* VS16 (U+FE0F) is special. It typically turns the preceding
|
||||
* single-width character into a double-width one. Let it
|
||||
* have a width of 1 effectively making the combination with
|
||||
* the preceding character double-width.
|
||||
*/
|
||||
*tc = ' ';
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* try recomposition */
|
||||
prev_c = ucs_recompose(prev_c, curr_c);
|
||||
if (prev_c != 0) {
|
||||
vc_con_rewind(vc);
|
||||
*tc = *c = prev_c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Otherwise zero-width code points are ignored. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vc_get_glyph(struct vc_data *vc, int tc)
|
||||
{
|
||||
int glyph = conv_uni_to_pc(vc, tc);
|
||||
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
|
||||
|
||||
if (!(glyph & ~charmask))
|
||||
return glyph;
|
||||
|
||||
if (glyph == -1)
|
||||
return -1; /* nothing to display */
|
||||
|
||||
/* Glyph not found */
|
||||
if ((!vc->vc_utf || vc->vc_disp_ctrl || tc < 128) && !(tc & ~charmask)) {
|
||||
/*
|
||||
* In legacy mode use the glyph we get by a 1:1 mapping.
|
||||
* This would make absolutely no sense with Unicode in mind, but do this for
|
||||
* ASCII characters since a font may lack Unicode mapping info and we don't
|
||||
* want to end up with having question marks only.
|
||||
*/
|
||||
return tc;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Unicode screen memory is allocated only when required.
|
||||
* This is one such case: we're about to "cheat" with the displayed
|
||||
* character meaning the simple screen buffer won't hold the original
|
||||
* information, whereas the Unicode screen buffer always does.
|
||||
*/
|
||||
vc_uniscr_check(vc);
|
||||
|
||||
/* Try getting a simpler fallback character. */
|
||||
tc = ucs_get_fallback(tc);
|
||||
if (tc)
|
||||
return vc_get_glyph(vc, tc);
|
||||
|
||||
/* Display U+FFFD (Unicode Replacement Character). */
|
||||
return conv_uni_to_pc(vc, UCS_REPLACEMENT);
|
||||
}
|
||||
|
||||
static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
|
||||
struct vc_draw_region *draw)
|
||||
{
|
||||
int next_c;
|
||||
unsigned char vc_attr = vc->vc_attr;
|
||||
u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff;
|
||||
u16 himask = vc->vc_hi_font_mask;
|
||||
u8 width = 1;
|
||||
bool inverse = false;
|
||||
|
||||
if (vc->vc_utf && !vc->vc_disp_ctrl) {
|
||||
if (is_double_width(c))
|
||||
width = 2;
|
||||
width = vc_process_ucs(vc, &c, &tc);
|
||||
if (!width)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Now try to find out how to display it */
|
||||
tc = conv_uni_to_pc(vc, tc);
|
||||
if (tc & ~charmask) {
|
||||
if (tc == -1 || tc == -2)
|
||||
return -1; /* nothing to display */
|
||||
tc = vc_get_glyph(vc, tc);
|
||||
if (tc == -1)
|
||||
return -1; /* nothing to display */
|
||||
if (tc < 0) {
|
||||
inverse = true;
|
||||
tc = conv_uni_to_pc(vc, '?');
|
||||
if (tc < 0)
|
||||
tc = '?';
|
||||
|
||||
/* Glyph not found */
|
||||
if ((!vc->vc_utf || vc->vc_disp_ctrl || c < 128) &&
|
||||
!(c & ~charmask)) {
|
||||
/*
|
||||
* In legacy mode use the glyph we get by a 1:1
|
||||
* mapping.
|
||||
* This would make absolutely no sense with Unicode in
|
||||
* mind, but do this for ASCII characters since a font
|
||||
* may lack Unicode mapping info and we don't want to
|
||||
* end up with having question marks only.
|
||||
*/
|
||||
tc = c;
|
||||
} else {
|
||||
/*
|
||||
* Display U+FFFD. If it's not found, display an inverse
|
||||
* question mark.
|
||||
*/
|
||||
tc = conv_uni_to_pc(vc, 0xfffd);
|
||||
if (tc < 0) {
|
||||
inverse = true;
|
||||
tc = conv_uni_to_pc(vc, '?');
|
||||
if (tc < 0)
|
||||
tc = '?';
|
||||
|
||||
vc_attr = vc_invert_attr(vc);
|
||||
con_flush(vc, draw);
|
||||
}
|
||||
}
|
||||
vc_attr = vc_invert_attr(vc);
|
||||
con_flush(vc, draw);
|
||||
}
|
||||
|
||||
next_c = c;
|
||||
|
@ -3028,8 +3104,14 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
|
|||
tc = conv_uni_to_pc(vc, ' ');
|
||||
if (tc < 0)
|
||||
tc = ' ';
|
||||
next_c = ' ';
|
||||
/*
|
||||
* Store a zero-width space in the Unicode screen given that
|
||||
* the previous code point is semantically double width.
|
||||
*/
|
||||
next_c = UCS_ZWS;
|
||||
}
|
||||
|
||||
out:
|
||||
notify_write(vc, c);
|
||||
|
||||
if (inverse)
|
||||
|
@ -3414,6 +3496,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
|
|||
break;
|
||||
case TIOCL_BLANKEDSCREEN:
|
||||
return console_blanked;
|
||||
case TIOCL_GETBRACKETEDPASTE:
|
||||
return get_bracketed_paste(tty);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -951,6 +951,22 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
(unsigned short __user *)arg);
|
||||
case VT_WAITEVENT:
|
||||
return vt_event_wait_ioctl((struct vt_event __user *)arg);
|
||||
|
||||
case VT_GETCONSIZECSRPOS:
|
||||
{
|
||||
struct vt_consizecsrpos concsr;
|
||||
|
||||
console_lock();
|
||||
concsr.con_cols = vc->vc_cols;
|
||||
concsr.con_rows = vc->vc_rows;
|
||||
concsr.csr_col = vc->state.x;
|
||||
concsr.csr_row = vc->state.y;
|
||||
console_unlock();
|
||||
if (copy_to_user(up, &concsr, sizeof(concsr)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
@ -1103,8 +1119,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
|
|||
case VT_WAITACTIVE:
|
||||
case VT_RELDISP:
|
||||
case VT_DISALLOCATE:
|
||||
case VT_RESIZE:
|
||||
case VT_RESIZEX:
|
||||
return vt_ioctl(tty, cmd, arg);
|
||||
|
||||
/*
|
||||
|
|
|
@ -145,6 +145,7 @@ struct vc_data {
|
|||
unsigned int vc_need_wrap : 1;
|
||||
unsigned int vc_can_do_color : 1;
|
||||
unsigned int vc_report_mouse : 2;
|
||||
unsigned int vc_bracketed_paste : 1;
|
||||
unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */
|
||||
unsigned char vc_utf_count;
|
||||
int vc_utf_char;
|
||||
|
|
|
@ -28,6 +28,10 @@ int conv_uni_to_pc(struct vc_data *conp, long ucs);
|
|||
u32 conv_8bit_to_uni(unsigned char c);
|
||||
int conv_uni_to_8bit(u32 uni);
|
||||
void console_map_init(void);
|
||||
bool ucs_is_double_width(uint32_t cp);
|
||||
bool ucs_is_zero_width(uint32_t cp);
|
||||
u32 ucs_recompose(u32 base, u32 mark);
|
||||
u32 ucs_get_fallback(u32 cp);
|
||||
#else
|
||||
static inline u16 inverse_translate(const struct vc_data *conp, u16 glyph,
|
||||
bool use_unicode)
|
||||
|
@ -57,6 +61,26 @@ static inline int conv_uni_to_8bit(u32 uni)
|
|||
}
|
||||
|
||||
static inline void console_map_init(void) { }
|
||||
|
||||
static inline bool ucs_is_double_width(uint32_t cp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool ucs_is_zero_width(uint32_t cp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline u32 ucs_recompose(u32 base, u32 mark)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 ucs_get_fallback(u32 cp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CONSOLE_TRANSLATIONS */
|
||||
|
||||
#endif /* __LINUX_CONSOLEMAP_H__ */
|
||||
|
|
|
@ -427,6 +427,18 @@ struct uart_icount {
|
|||
typedef u64 __bitwise upf_t;
|
||||
typedef unsigned int __bitwise upstat_t;
|
||||
|
||||
enum uart_iotype {
|
||||
UPIO_UNKNOWN = -1,
|
||||
UPIO_PORT = SERIAL_IO_PORT, /* 8b I/O port access */
|
||||
UPIO_HUB6 = SERIAL_IO_HUB6, /* Hub6 ISA card */
|
||||
UPIO_MEM = SERIAL_IO_MEM, /* driver-specific */
|
||||
UPIO_MEM32 = SERIAL_IO_MEM32, /* 32b little endian */
|
||||
UPIO_AU = SERIAL_IO_AU, /* Au1x00 and RT288x type IO */
|
||||
UPIO_TSI = SERIAL_IO_TSI, /* Tsi108/109 type IO */
|
||||
UPIO_MEM32BE = SERIAL_IO_MEM32BE, /* 32b big endian */
|
||||
UPIO_MEM16 = SERIAL_IO_MEM16, /* 16b little endian */
|
||||
};
|
||||
|
||||
struct uart_port {
|
||||
spinlock_t lock; /* port lock */
|
||||
unsigned long iobase; /* in/out[bwl] */
|
||||
|
@ -469,23 +481,13 @@ struct uart_port {
|
|||
unsigned char x_char; /* xon/xoff char */
|
||||
unsigned char regshift; /* reg offset shift */
|
||||
|
||||
unsigned char iotype; /* io access style */
|
||||
|
||||
#define UPIO_UNKNOWN ((unsigned char)~0U) /* UCHAR_MAX */
|
||||
#define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */
|
||||
#define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */
|
||||
#define UPIO_MEM (SERIAL_IO_MEM) /* driver-specific */
|
||||
#define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */
|
||||
#define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */
|
||||
#define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */
|
||||
#define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */
|
||||
#define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */
|
||||
|
||||
unsigned char quirks; /* internal quirks */
|
||||
|
||||
/* internal quirks must be updated while holding port mutex */
|
||||
#define UPQ_NO_TXEN_TEST BIT(0)
|
||||
|
||||
enum uart_iotype iotype; /* io access style */
|
||||
|
||||
unsigned int read_status_mask; /* driver specific */
|
||||
unsigned int ignore_status_mask; /* driver specific */
|
||||
struct uart_state *state; /* pointer to parent state */
|
||||
|
@ -1101,8 +1103,8 @@ static inline bool uart_console_registered(struct uart_port *port)
|
|||
|
||||
struct uart_port *uart_get_console(struct uart_port *ports, int nr,
|
||||
struct console *c);
|
||||
int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
|
||||
char **options);
|
||||
int uart_parse_earlycon(char *p, enum uart_iotype *iotype,
|
||||
resource_size_t *addr, char **options);
|
||||
void uart_parse_options(const char *options, int *baud, int *parity, int *bits,
|
||||
int *flow);
|
||||
int uart_set_options(struct uart_port *port, struct console *co, int baud,
|
||||
|
|
|
@ -147,9 +147,6 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
|
|||
struct tty_driver *driver, unsigned index,
|
||||
struct device *device, void *drvdata,
|
||||
const struct attribute_group **attr_grp);
|
||||
struct device *tty_port_register_device_serdev(struct tty_port *port,
|
||||
struct tty_driver *driver, unsigned index,
|
||||
struct device *host, struct device *parent);
|
||||
struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
|
||||
struct tty_driver *driver, unsigned index,
|
||||
struct device *host, struct device *parent, void *drvdata,
|
||||
|
|
|
@ -36,5 +36,6 @@ struct tiocl_selection {
|
|||
#define TIOCL_BLANKSCREEN 14 /* keep screen blank even if a key is pressed */
|
||||
#define TIOCL_BLANKEDSCREEN 15 /* return which vt was blanked */
|
||||
#define TIOCL_GETKMSGREDIRECT 17 /* get the vt the kernel messages are restricted to */
|
||||
#define TIOCL_GETBRACKETEDPASTE 18 /* get whether paste may be bracketed */
|
||||
|
||||
#endif /* _LINUX_TIOCL_H */
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef _UAPI_LINUX_VT_H
|
||||
#define _UAPI_LINUX_VT_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* These constants are also useful for user-level apps (e.g., VC
|
||||
|
@ -84,4 +86,13 @@ struct vt_setactivate {
|
|||
|
||||
#define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */
|
||||
|
||||
/* get console size and cursor position */
|
||||
struct vt_consizecsrpos {
|
||||
__u16 con_rows; /* number of console rows */
|
||||
__u16 con_cols; /* number of console columns */
|
||||
__u16 csr_row; /* current cursor's row */
|
||||
__u16 csr_col; /* current cursor's column */
|
||||
};
|
||||
#define VT_GETCONSIZECSRPOS _IOR('V', 0x10, struct vt_consizecsrpos)
|
||||
|
||||
#endif /* _UAPI_LINUX_VT_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue