diff options
author | Vineet Gupta <Vineet.Gupta1@synopsys.com> | 2013-01-11 01:20:23 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-16 01:16:05 -0500 |
commit | ea28fd56fcde69af768135e428093f94c5ca6a88 (patch) | |
tree | e9f834f511507ded2c43beaf3d00a0227d77c519 | |
parent | d6c0d06b341803fde45e592df4233579f3afb04e (diff) |
serial/arc-uart: switch to devicetree based probing
* DT binding for arc-uart
* With alll the bits in place we can now use DT probing.
Note that there's a bit of kludge right now because earlyprintk portion
of driver can't use the DT infrastrcuture to get resoures/plat_data.
This requires some infrastructre changes to of_flat_ framework
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Cox <alan@linux.intel.com>
Cc: devicetree-discuss@lists.ozlabs.org
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | Documentation/devicetree/bindings/tty/serial/arc-uart.txt | 26 | ||||
-rw-r--r-- | drivers/tty/serial/arc_uart.c | 43 |
2 files changed, 66 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/tty/serial/arc-uart.txt b/Documentation/devicetree/bindings/tty/serial/arc-uart.txt new file mode 100644 index 000000000000..c3bd8f9c9997 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/arc-uart.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | * Synopsys ARC UART : Non standard UART used in some of the ARC FPGA boards | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "snps,arc-uart" | ||
5 | - reg : offset and length of the register set for the device. | ||
6 | - interrupts : device interrupt | ||
7 | - clock-frequency : the input clock frequency for the UART | ||
8 | - baud : baud rate for UART | ||
9 | |||
10 | e.g. | ||
11 | |||
12 | arcuart0: serial@c0fc1000 { | ||
13 | compatible = "snps,arc-uart"; | ||
14 | reg = <0xc0fc1000 0x100>; | ||
15 | interrupts = <5>; | ||
16 | clock-frequency = <80000000>; | ||
17 | baud = <115200>; | ||
18 | status = "okay"; | ||
19 | }; | ||
20 | |||
21 | Note: Each port should have an alias correctly numbered in "aliases" node. | ||
22 | |||
23 | e.g. | ||
24 | aliases { | ||
25 | serial0 = &arcuart0; | ||
26 | }; | ||
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 2db64105677b..b46860104312 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/tty_flip.h> | 37 | #include <linux/tty_flip.h> |
38 | #include <linux/serial_core.h> | 38 | #include <linux/serial_core.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | #include <linux/of.h> | ||
41 | #include <linux/of_platform.h> | ||
40 | 42 | ||
41 | /************************************* | 43 | /************************************* |
42 | * ARC UART Hardware Specs | 44 | * ARC UART Hardware Specs |
@@ -537,8 +539,26 @@ arc_uart_init_one(struct platform_device *pdev, int dev_id) | |||
537 | return -ENODEV; | 539 | return -ENODEV; |
538 | 540 | ||
539 | uart->is_emulated = !!plat_data[0]; /* workaround ISS bug */ | 541 | uart->is_emulated = !!plat_data[0]; /* workaround ISS bug */ |
540 | uart->port.uartclk = plat_data[1]; | 542 | |
541 | uart->baud = plat_data[2]; | 543 | if (is_early_platform_device(pdev)) { |
544 | uart->port.uartclk = plat_data[1]; | ||
545 | uart->baud = plat_data[2]; | ||
546 | } else { | ||
547 | struct device_node *np = pdev->dev.of_node; | ||
548 | u32 val; | ||
549 | |||
550 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
551 | dev_err(&pdev->dev, "clock-frequency property NOTset\n"); | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | uart->port.uartclk = val; | ||
555 | |||
556 | if (of_property_read_u32(np, "baud", &val)) { | ||
557 | dev_err(&pdev->dev, "baud property NOT set\n"); | ||
558 | return -EINVAL; | ||
559 | } | ||
560 | uart->baud = val; | ||
561 | } | ||
542 | 562 | ||
543 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 563 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
544 | if (!res) | 564 | if (!res) |
@@ -673,8 +693,18 @@ static int __init arc_serial_probe_earlyprintk(struct platform_device *pdev) | |||
673 | static int arc_serial_probe(struct platform_device *pdev) | 693 | static int arc_serial_probe(struct platform_device *pdev) |
674 | { | 694 | { |
675 | int rc, dev_id; | 695 | int rc, dev_id; |
696 | struct device_node *np = pdev->dev.of_node; | ||
697 | |||
698 | /* no device tree device */ | ||
699 | if (!np) | ||
700 | return -ENODEV; | ||
701 | |||
702 | dev_id = of_alias_get_id(np, "serial"); | ||
703 | if (dev_id < 0) { | ||
704 | dev_err(&pdev->dev, "failed to get alias id: %d\n", dev_id); | ||
705 | return dev_id; | ||
706 | } | ||
676 | 707 | ||
677 | dev_id = pdev->id < 0 ? 0 : pdev->id; | ||
678 | rc = arc_uart_init_one(pdev, dev_id); | 708 | rc = arc_uart_init_one(pdev, dev_id); |
679 | if (rc) | 709 | if (rc) |
680 | return rc; | 710 | return rc; |
@@ -689,12 +719,19 @@ static int arc_serial_remove(struct platform_device *pdev) | |||
689 | return 0; | 719 | return 0; |
690 | } | 720 | } |
691 | 721 | ||
722 | static const struct of_device_id arc_uart_dt_ids[] = { | ||
723 | { .compatible = "snps,arc-uart" }, | ||
724 | { /* Sentinel */ } | ||
725 | }; | ||
726 | MODULE_DEVICE_TABLE(of, arc_uart_dt_ids); | ||
727 | |||
692 | static struct platform_driver arc_platform_driver = { | 728 | static struct platform_driver arc_platform_driver = { |
693 | .probe = arc_serial_probe, | 729 | .probe = arc_serial_probe, |
694 | .remove = arc_serial_remove, | 730 | .remove = arc_serial_remove, |
695 | .driver = { | 731 | .driver = { |
696 | .name = DRIVER_NAME, | 732 | .name = DRIVER_NAME, |
697 | .owner = THIS_MODULE, | 733 | .owner = THIS_MODULE, |
734 | .of_match_table = arc_uart_dt_ids, | ||
698 | }, | 735 | }, |
699 | }; | 736 | }; |
700 | 737 | ||