diff options
author | John Garry <john.garry@huawei.com> | 2018-04-27 06:36:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-14 07:48:29 -0400 |
commit | aa95947400edb571c680e89ec008f192b2e6f178 (patch) | |
tree | 897c16d114ccabaa00dc02f9c0383b77bf6b17c2 | |
parent | 9594b5be7ec110ed11acec58fa94f3f293668c85 (diff) |
serial: 8250_of: Add IO space support
Currently the 8250_of driver only supports MEM IO type
accesses.
Some development boards (Huawei D03, specifically) require
IO space access for 8250-compatible OF driver support, so
add it.
The modification is quite simple: just set the port iotype
and associated flags depending on the device address
resource type.
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/serial/8250/8250_of.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 3de8d6a41246..bfb37f0be22f 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c | |||
@@ -92,13 +92,43 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
92 | goto err_unprepare; | 92 | goto err_unprepare; |
93 | } | 93 | } |
94 | 94 | ||
95 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | | ||
96 | UPF_FIXED_TYPE; | ||
95 | spin_lock_init(&port->lock); | 97 | spin_lock_init(&port->lock); |
96 | port->mapbase = resource.start; | ||
97 | port->mapsize = resource_size(&resource); | ||
98 | 98 | ||
99 | /* Check for shifted address mapping */ | 99 | if (resource_type(&resource) == IORESOURCE_IO) { |
100 | if (of_property_read_u32(np, "reg-offset", &prop) == 0) | 100 | port->iotype = UPIO_PORT; |
101 | port->mapbase += prop; | 101 | port->iobase = resource.start; |
102 | } else { | ||
103 | port->mapbase = resource.start; | ||
104 | port->mapsize = resource_size(&resource); | ||
105 | |||
106 | /* Check for shifted address mapping */ | ||
107 | if (of_property_read_u32(np, "reg-offset", &prop) == 0) | ||
108 | port->mapbase += prop; | ||
109 | |||
110 | port->iotype = UPIO_MEM; | ||
111 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { | ||
112 | switch (prop) { | ||
113 | case 1: | ||
114 | port->iotype = UPIO_MEM; | ||
115 | break; | ||
116 | case 2: | ||
117 | port->iotype = UPIO_MEM16; | ||
118 | break; | ||
119 | case 4: | ||
120 | port->iotype = of_device_is_big_endian(np) ? | ||
121 | UPIO_MEM32BE : UPIO_MEM32; | ||
122 | break; | ||
123 | default: | ||
124 | dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", | ||
125 | prop); | ||
126 | ret = -EINVAL; | ||
127 | goto err_dispose; | ||
128 | } | ||
129 | } | ||
130 | port->flags |= UPF_IOREMAP; | ||
131 | } | ||
102 | 132 | ||
103 | /* Check for registers offset within the devices address range */ | 133 | /* Check for registers offset within the devices address range */ |
104 | if (of_property_read_u32(np, "reg-shift", &prop) == 0) | 134 | if (of_property_read_u32(np, "reg-shift", &prop) == 0) |
@@ -114,26 +144,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
114 | port->line = ret; | 144 | port->line = ret; |
115 | 145 | ||
116 | port->irq = irq_of_parse_and_map(np, 0); | 146 | port->irq = irq_of_parse_and_map(np, 0); |
117 | port->iotype = UPIO_MEM; | ||
118 | if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { | ||
119 | switch (prop) { | ||
120 | case 1: | ||
121 | port->iotype = UPIO_MEM; | ||
122 | break; | ||
123 | case 2: | ||
124 | port->iotype = UPIO_MEM16; | ||
125 | break; | ||
126 | case 4: | ||
127 | port->iotype = of_device_is_big_endian(np) ? | ||
128 | UPIO_MEM32BE : UPIO_MEM32; | ||
129 | break; | ||
130 | default: | ||
131 | dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", | ||
132 | prop); | ||
133 | ret = -EINVAL; | ||
134 | goto err_dispose; | ||
135 | } | ||
136 | } | ||
137 | 147 | ||
138 | info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL); | 148 | info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL); |
139 | if (IS_ERR(info->rst)) { | 149 | if (IS_ERR(info->rst)) { |
@@ -147,8 +157,6 @@ static int of_platform_serial_setup(struct platform_device *ofdev, | |||
147 | 157 | ||
148 | port->type = type; | 158 | port->type = type; |
149 | port->uartclk = clk; | 159 | port->uartclk = clk; |
150 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | ||
151 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
152 | port->irqflags |= IRQF_SHARED; | 160 | port->irqflags |= IRQF_SHARED; |
153 | 161 | ||
154 | if (of_property_read_bool(np, "no-loopback-test")) | 162 | if (of_property_read_bool(np, "no-loopback-test")) |