Re: [PATCH v4 00/13] Add ACPI _DSD and unified device properties support

David Woodhouse
2014-10-15T13:04:38Z

[-- Attachment #1: Type: text/plain, Size: 5881 bytes --]

Here's a completely untested patch to convert of_serial to be usable via
ACPI properties too. The properties themselves were fairly
straightforward; the interesting part is converting to
platform_get_irq() and platform_get_resource() — in the latter case
first trying IORESOURCE_MEM then IORESOURCE_IO if that fails.

Does this look sane? We'll probably want to think about renaming the
module and the config option too, but that can come after the basic
functionality.

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 26cec64..be95a4c 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1094,14 +1094,14 @@ config SERIAL_NETX_CONSOLE
you can make it the console by answering Y to this option.

config SERIAL_OF_PLATFORM
- tristate "Serial port on Open Firmware platform bus"
- depends on OF
+ tristate "Serial port on firmware platform bus"
+ depends on OF || ACPI
depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL
help
- If you have a PowerPC based system that has serial ports
- on a platform specific bus, you should enable this option.
- Currently, only 8250 compatible ports are supported, but
- others can easily be added.
+ If you have a system which advertises its serial ports through
+ devicetree or ACPI, you should enable this option. Currently
+ only 8250 compatible and NWP ports and are supported, but others
+ can easily be added.

config SERIAL_OMAP
tristate "OMAP serial port support"
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index 68d4455..73ee9af 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -57,13 +57,14 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
int type, struct uart_port *port,
struct of_serial_info *info)
{
- struct resource resource;
- struct device_node *np = ofdev->dev.of_node;
+ struct resource *resource;
u32 clk, spd, prop;
+ unsigned char iotype = UPIO_MEM;
+ u32 res_start;
int ret;

memset(port, 0, sizeof *port);
- if (of_property_read_u32(np, "clock-frequency", &clk)) {
+ if (device_property_read_u32(&ofdev->dev, "clock-frequency", &clk)) {

/* Get clk rate through clk driver if present */
info->clk = clk_get(&ofdev->dev, NULL);
@@ -77,40 +78,52 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
clk = clk_get_rate(info->clk);
}
/* If current-speed was set, then try not to change it. */
- if (of_property_read_u32(np, "current-speed", &spd) == 0)
+ if (device_property_read_u32(&ofdev->dev, "current-speed", &spd) == 0)
port->custom_divisor = clk / (16 * spd);

- ret = of_address_to_resource(np, 0, &resource);
- if (ret) {
+ resource = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+ if (!resource) {
+ resource = platform_get_resource(ofdev, IORESOURCE_IO, 0);
+ iotype = UPIO_PORT;
+ }
+ if (!resource) {
dev_warn(&ofdev->dev, "invalid address\n");
goto out;
}

spin_lock_init(&port->lock);
- port->mapbase = resource.start;
+ res_start = resource->start;

/* Check for shifted address mapping */
- if (of_property_read_u32(np, "reg-offset", &prop) == 0)
- port->mapbase += prop;
+ if (device_property_read_u32(&ofdev->dev, "reg-offset", &prop) == 0)
+ res_start += prop;
+
+ if (iotype == UPIO_PORT)
+ port->iobase = res_start;
+ else
+ port->mapbase = res_start;

/* Check for registers offset within the devices address range */
- if (of_property_read_u32(np, "reg-shift", &prop) == 0)
+ if (device_property_read_u32(&ofdev->dev, "reg-shift", &prop) == 0)
port->regshift = prop;

/* Check for fifo size */
- if (of_property_read_u32(np, "fifo-size", &prop) == 0)
+ if (device_property_read_u32(&ofdev->dev, "fifo-size", &prop) == 0)
port->fifosize = prop;

- port->irq = irq_of_parse_and_map(np, 0);
- port->iotype = UPIO_MEM;
- if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
+ port->irq = platform_get_irq(ofdev, 0);
+ port->iotype = iotype;
+ if (device_property_read_u32(&ofdev->dev, "reg-io-width", &prop) == 0) {
switch (prop) {
case 1:
- port->iotype = UPIO_MEM;
+ port->iotype = iotype;
break;
case 4:
- port->iotype = UPIO_MEM32;
- break;
+ if (iotype == UPIO_MEM) {
+ port->iotype = UPIO_MEM32;
+ break;
+ }
+ /* Fall through for non-memory */
default:
dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n",
prop);
@@ -124,7 +137,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
| UPF_FIXED_PORT | UPF_FIXED_TYPE;

- if (of_find_property(np, "no-loopback-test", NULL))
+ if (!device_get_property(&ofdev->dev, "no-loopback-test", NULL))
port->flags |= UPF_SKIP_TEST;

port->dev = &ofdev->dev;
@@ -155,7 +168,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
if (!match)
return -EINVAL;

- if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL))
+ if (!device_get_property(&ofdev->dev, "used-by-rtas", NULL))
return -EBUSY;

info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -179,12 +192,10 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
if (port.fifosize)
port8250.capabilities = UART_CAP_FIFO;

- if (of_property_read_bool(ofdev->dev.of_node,
- "auto-flow-control"))
+ if (!device_get_property(&ofdev->dev, "auto-flow-control", NULL))
port8250.capabilities |= UART_CAP_AFE;

- if (of_property_read_bool(ofdev->dev.of_node,
- "has-hw-flow-control"))
+ if (!device_get_property(&ofdev->dev, "has-hw-flow-control", NULL))
port8250.port.flags |= UPF_HARD_FLOW;

ret = serial8250_register_8250_port(&port8250);

--
dwmw2

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5745 bytes --]