Skip to contentSkip to conversation

ACPI/UART: Add ACPI 5.0 enueration support for UART.

RFC PATCH Superseded Lv Zheng 7 participants 71 messages Dec 3, 2012 – Apr 7, 2013

Subsystems (3)
lore
Share & tools
lore

Lv Zheng

author
#0 lore raw

cover ACPI/UART: Add ACPI 5.0 enueration support for UART.

ACPI 5.0 specification introduces enumeration support for SPB buses. This patch set adds the UART serial bus enumeration support to Linux using such mechanism.

NOTE: The [PATCH 3/3] is only for the demonstration purpose and should not
be merged into any of the published Linux source tree.

Lv Zheng (3):
UART: Add UART subsystem as a bus.
ACPI / UART: Add ACPI enumeration support for UART bus.
UART: Add dummy devices to test the enumeration.

 drivers/acpi/Kconfig                 |    7 +
 drivers/acpi/Makefile                |    1 +
 drivers/acpi/acpi_uart.c             |  255 ++++++++++++++++++++
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |   10 +-
 drivers/tty/serial/8250/8250_dummy.c |  128 ++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/Makefile          |    2 +-
 drivers/tty/serial/serial_bus.c      |  426 ++++++++++++++++++++++++++++++++++
 include/linux/acpi_uart.h            |   40 ++++
 include/linux/mod_devicetable.h      |    5 +
 include/linux/serial_8250.h          |    2 +
 include/linux/serial_core.h          |   59 +++++
 14 files changed, 944 insertions(+), 3 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
 create mode 100644 drivers/tty/serial/serial_bus.c
 create mode 100644 include/linux/acpi_uart.h
Signature · 1 line
1.7.10
author
#1 lore raw

RFC PATCH 1/3 UART: Add UART subsystem as a bus.

Tranditional UARTs are used as communication pipes between the hosts while the modern computing systems equipped with HSU (High Speed UARTs) would connect on-board target devices using the UART ports. The role of the UART controllers are changed from the communication facility to the platform bus.

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART target devices known to the platform vendors.
Thus there is the needs for enumerating the UART target devices:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART target devices.
In order to send uevent, a device need to be a class device or a bus device. This patch introduces a bus_type subsystem to manage the new UART target device type for the purpose of the possible future extensions.
When the UART target devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach). Here is an example of the uevents and exported attributes of the new type of devices:

Test DSDT (dummy UART host adapter INTF000 and target device INTF001):
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

uevent and environments:
KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/INTF001:00 (uart)
ACTION=add
DEVPATH=/devices/platform/INTF000:00/INTF001:00
DEVTYPE=uart_device
MODALIAS=uart:INTF001:00
SEQNUM=1144
SUBSYSTEM=uart

kobject attribute files:

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,

kobject sysfs links:

# ls -l /sys/bus/uart/devices
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0
target_node -> ../../INTF001:00
---
 drivers/tty/serial/Makefile     |    2 +-
 drivers/tty/serial/serial_bus.c |  409 +++++++++++++++++++++++++++++++++++++++
 include/linux/mod_devicetable.h |    5 +
 include/linux/serial_core.h     |   56 ++++++
 4 files changed, 471 insertions(+), 1 deletion(-)
 create mode 100644 drivers/tty/serial/serial_bus.c
drivers/tty/serial/Makefile +1 -1
index 4f694da..4400521 100644
@@ -2,7 +2,7 @@
 # Makefile for the kernel serial device drivers.
 #
 
-obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+obj-$(CONFIG_SERIAL_CORE) += serial_core.o serial_bus.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
 
 # These Sparc drivers have to appear before others such as 8250
drivers/tty/serial/serial_bus.c new file +409 -0

409 lines not on this page · raw message

include/linux/mod_devicetable.h +5 -0
index fed3def..28df140 100644
@@ -455,6 +455,11 @@ struct spi_device_id {
 			__attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+/* uart */
+
+#define UART_NAME_SIZE	32
+#define UART_MODULE_PREFIX "uart:"
+
 /* dmi */
 enum dmi_field {
 	DMI_NONE,
include/linux/serial_core.h +56 -0

70 lines not on this page · raw message

Signature · 1 line
1.7.10
#2 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 6 lines

+ * uart_tty_find - find the associated TTY device for the UART target
+ * device
+ * @drv: the low level UART driver
+ * @dev: the parent physical device for the TTY devices
+ * @line: the line number of the UART target device
+ *

Our top level abstraction is struct tty and struct tty_port. There is nothing requiring a serial tty is using the uart helper layer, nor should there be, so your code needs to support devices not using the uart layer. Otherwise it looks quite reasonable.

our 3.7 tty layer has sysfs nodes on the tty which may also help

Alan

author
#3 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

OK, all uart_driver and serial_core.h stuff will be removed from the next revision.

Best regards/Lv Zheng

Quoted 28 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Alan Cox
Sent: Monday, December 03, 2012 7:46 PM
To: Zheng, Lv
Cc: Brown, Len; Wysocki, Rafael J; Greg Kroah-Hartman; [email protected]; [email protected]
Subject: Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 6 lines

+ * uart_tty_find - find the associated TTY device for the UART target
+ * device
+ * @drv: the low level UART driver
+ * @dev: the parent physical device for the TTY devices
+ * @line: the line number of the UART target device
+ *

Our top level abstraction is struct tty and struct tty_port. There is nothing requiring a serial tty is using the uart helper layer, nor should there be, so your code needs to support devices not using the uart layer. Otherwise it looks quite reasonable.

our 3.7 tty layer has sysfs nodes on the tty which may also help

Alan
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to [email protected] More majordomo info at
http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Lv Zheng
Quoted 9 lines · Lv Zheng

kobject attribute files:

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,

What if instead of exporting these to userspace we just set the defaults based on the UartSerialBus() value? This way the user only needs to find the right tty to pass to hciattach.

Quoted 8 lines

kobject sysfs links:

# ls -l /sys/bus/uart/devices
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0
target_node -> ../../INTF001:00

And if we have enumerated the UART controller from ACPI (it is probably attached to the platform bus) we can find the tty device it exports like:

/sys/bus/platform/devices/INTF000:00/tty/ttyS1/dev

Only thing that is missing then is the type of the connected device. That can be extracted by following the firmware_node symlink:

# ls /sys/bus/platform/devices/INTF000\:00/firmware_node/
INTF001:00
...
# cat  /sys/bus/platform/devices/INTF000\:00/firmware_node/INTF001:00/hid
INTF001

This ACPI ID then can be used to find out what device it is.

Well, this is probably not the simplest solution :-) I'm just trying to understand why we need to add a new bus type if only thing it adds is the sysfs files.

Quoted 6 lines
drivers/tty/serial/serial_bus.c new file +6 -0
+/**
+ * uart_unregister_device - unregister a UART device
+ * @device: value returned from uart_register_device()
+ *
+ * Reverse effect of uart_register_device().
+ */

drivers/tty/serial/serial_bus.c line 336

Quoted 10 lines
drivers/tty/serial/serial_bus.c new file +10 -0
+void uart_unregister_device(struct uart_device *udev)
+{
+	if (udev->adap)
+		klist_del(&udev->klist_parent);
+	sysfs_remove_link(&udev->dev.kobj, "host_node");
+	if (udev->tty)
+		sysfs_remove_link(&udev->tty->kobj, "target_node");
+	device_unregister(&udev->dev);
+}
+EXPORT_SYMBOL_GPL(uart_unreigster_device);

Typo in the function name.

#5 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 3 lines

What if instead of exporting these to userspace we just set the defaults based on the UartSerialBus() value? This way the user only needs to find the right tty to pass to hciattach.

We should also make sure the types are generic because there are lots of platforms that can use DT to describe devices usefully this way, and there are types not in the ACPI spec (eg Loconet) that some apps could do with finding.

Quoted 3 lines

And if we have enumerated the UART controller from ACPI (it is probably attached to the platform bus) we can find the tty device it exports like:

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

Alan

#6 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 7 lines · Alan Cox
Quoted 3 lines

And if we have enumerated the UART controller from ACPI (it is probably attached to the platform bus) we can find the tty device it exports like:

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

The only property that comes into mind is _HID/_CID (referring to the ACPI ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

There are other resources as well in addition to the UartSerialBus(). For example we might have two GPIO lines connected to the bluetooth chip and these are represented as GpioIo ACPI resources.

Since the bluetooth is mostly handled by the N_HCI line discipline, should the GPIO handling be done there as well? It can distinguish between DT and ACPI enumerated devices by comparing dev->of_node and ACPI_HANDLE(dev) so it can get the resources from both DT and ACPI but I'm not sure if it really belongs there. Or should this be in a separate driver?

author
#7 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 18 lines · Alan Cox
Quoted 7 lines
Quoted 3 lines

And if we have enumerated the UART controller from ACPI (it is probably attached to the platform bus) we can find the tty device it exports like:

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

The only property that comes into mind is _HID/_CID (referring to the ACPI ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

There are other resources as well in addition to the UartSerialBus(). For example we might have two GPIO lines connected to the bluetooth chip and these are represented as GpioIo ACPI resources.

Quoted 5 lines

Since the bluetooth is mostly handled by the N_HCI line discipline, should the GPIO handling be done there as well? It can distinguish between DT and ACPI enumerated devices by comparing dev->of_node and ACPI_HANDLE(dev) so it can get the resources from both DT and ACPI but I'm not sure if it really belongs there. Or should this be in a separate driver?

IMO,
For ACPI enumerated target devices, ACPI can provide GPIO enumeration API by feeding ACPI_HANDLE(tty->target) to obtain the GPIO resources while OF can offer its own implementation. Then there are 2 possible solutions can be found by calling such APIs:
1. implement GPIO enabling in the kernel side N_HCI proto driver.
2. implement GPIO enabling in the kernel side UART driver on TIOCSETD.

Same issues can be found for the ACPI enumerated SPI/I2C target devices. Thus the GpioIrq and GpioIo is not handled in this patch set.

Best regards/Lv Zheng

#8 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 24 lines · Lv
Quoted 18 lines · Alan Cox
Quoted 7 lines
Quoted 3 lines

And if we have enumerated the UART controller from ACPI (it is probably attached to the platform bus) we can find the tty device it exports like:

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

The only property that comes into mind is _HID/_CID (referring to the ACPI ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

There are other resources as well in addition to the UartSerialBus(). For example we might have two GPIO lines connected to the bluetooth chip and these are represented as GpioIo ACPI resources.

Quoted 5 lines

Since the bluetooth is mostly handled by the N_HCI line discipline, should the GPIO handling be done there as well? It can distinguish between DT and ACPI enumerated devices by comparing dev->of_node and ACPI_HANDLE(dev) so it can get the resources from both DT and ACPI but I'm not sure if it really belongs there. Or should this be in a separate driver?

Quoted 7 lines

IMO,
For ACPI enumerated target devices, ACPI can provide GPIO enumeration API by feeding ACPI_HANDLE(tty->target) to obtain the GPIO resources while OF can offer its own implementation.
Then there are 2 possible solutions can be found by calling such APIs:
1. implement GPIO enabling in the kernel side N_HCI proto driver.
2. implement GPIO enabling in the kernel side UART driver on TIOCSETD.

OK.

Quoted 2 lines

Same issues can be found for the ACPI enumerated SPI/I2C target devices. Thus the GpioIrq and GpioIo is not handled in this patch set.

Yeah, I wasn't expecting that this series addresses that :-) However, this is something we need to solve at some point - we probably don't want that userspace deals with the GPIOs.

#9 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Mika Westerberg
Quoted 8 lines
Quoted 3 lines

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

The only property that comes into mind is _HID/_CID (referring to the ACPI ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Quoted 3 lines

There are other resources as well in addition to the UartSerialBus(). For example we might have two GPIO lines connected to the bluetooth chip and these are represented as GpioIo ACPI resources.

There was some planning on this some time ago. I think we know how to deal with GPIOs

Quoted 5 lines

Since the bluetooth is mostly handled by the N_HCI line discipline, should the GPIO handling be done there as well? It can distinguish between DT and ACPI enumerated devices by comparing dev->of_node and ACPI_HANDLE(dev) so it can get the resources from both DT and ACPI but I'm not sure if it really belongs there. Or should this be in a separate driver?

The plan was that the tty device would know its gpio lines and also support a gpio structure giving mappings for extra control lines. It seems we want that both visible to kernel (N_HCI etc) and visible to user space (userspace custom handling using the gpio userspace interfaces).

Alan

author
#10 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

Quoted 8 lines
Quoted 5 lines

The only property that comes into mind is _HID/_CID (referring to the ACPI
ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Is it a good idea to introduce uart_device driver in the kernel to fill a new 'ldisc' member in the uart_device or to load ldisc by default for the corresponding tty_port?

One more important thing I should mention is about a design decision for this patch set.
My current implementation is for the uart tty devices.
Shall we change the uart_bus to the tty_bus, then introduce tty_host / tty_target for the bus?
In the Linux world, tty is the only language that the "tty physical devices" will use to talk to each other, thus it make sense to have a tty_bus and enable PM ops for the physical devices on the bus. If we do so, the tty_host or tty_port can be the functional devices on top of the host side physical tty devices (ex. platform device / pcmcia device), and the tty_target can be used instead of the uart_device. We could leave tty_host unimplemented in the first step as there is already a tty_port abstraction.

Quoted 13 lines
Quoted 3 lines

There are other resources as well in addition to the UartSerialBus(). For example we might have two GPIO lines connected to the bluetooth chip and these are represented as GpioIo ACPI resources.

There was some planning on this some time ago. I think we know how to deal with GPIOs

Quoted 5 lines

Since the bluetooth is mostly handled by the N_HCI line discipline, should the GPIO handling be done there as well? It can distinguish between DT and ACPI enumerated devices by comparing dev->of_node and ACPI_HANDLE(dev) so it can get the resources from both DT and ACPI but I'm not sure if it really belongs there. Or should this be in a separate driver?

Quoted 4 lines

The plan was that the tty device would know its gpio lines and also support a gpio structure giving mappings for extra control lines. It seems we want that both visible to kernel (N_HCI etc) and visible to user space (userspace custom handling using the gpio userspace interfaces).

When this is ready, someone knowing ACPI GPIO better than me (Heikki or Mathias included) can add additional features on top of this.

Best regards/Lv Zheng

author
#11 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
Quoted 3 lines

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

The only property that comes into mind is _HID/_CID (referring to the ACPI
ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

Quoted 6 lines
Quoted 2 lines

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Is it a good idea to introduce uart_device driver in the kernel to fill a new 'ldisc' member in the uart_device or to load ldisc by default for the corresponding tty_port?

In the ACPI spec, there is no such attribute for the UART devices, OF might easily introduce this. It's hard to add type name or ldisc name directly to the uart_board_info.

We can either add driver support for the uart_device to fill this as I mentioned in the first reply or to add a HID -> type name (or ldisc name) matching table in the acpi_uart.c to extract this information for the ACPI enumerated uart_board_info.

Best regards/Lv Zheng

#12 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Zheng, Lv
Quoted 4 lines
Quoted 2 lines

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Is it a good idea to introduce uart_device driver in the kernel to fill a new 'ldisc' member in the uart_device or to load ldisc by default for the corresponding tty_port?

No but it can provide information to help user space. In many cases the decision isn't about a line discipline but about automatically setting permissions or linking ports to the right driver.

The hints need to be generic - they can come from open firmware, from pci identifiers, from ACPI and so on.

Quoted 1 line

Shall we change the uart_bus to the tty_bus, then introduce tty_host / tty_target for the bus?

We have a tty class - is that not sufficient ?

Alan

author
#13 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Is it a good idea to introduce uart_device driver in the kernel to fill a new

'ldisc' member in the uart_device or to load ldisc by default for the corresponding tty_port?

Quoted 6 lines

No but it can provide information to help user space. In many cases the decision isn't about a line discipline but about automatically setting permissions or linking ports to the right driver.

The hints need to be generic - they can come from open firmware, from pci identifiers, from ACPI and so on.

Userspace need to know more than a simple type name to match the driver.
For example,
Atheros BT will send wrapped HCI packets from their HSU BT adapters, so they need to see "ath3000" rather than "bluetooth" to load a kernel hci protocol module for the device. As we can see, in the i2c/spi world, there is only "type" field filling w/ chip name, not 2 fields - "type" filled w/ generic type and "id" filled w/ chip name. Userspace can figure the generic "type" from the un-generic chip name like "type".
I just wonder will there be issues caused by following this design?

Quoted 4 lines
Quoted 1 line

Shall we change the uart_bus to the tty_bus, then introduce tty_host /

tty_target for the bus?

We have a tty class - is that not sufficient ?

As I mentioned in the previous mail, I'll keep the current naming rule until I see some objections strong enough.

-Lv

author
#14 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 15 lines
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Is it a good idea to introduce uart_device driver in the kernel to fill a new

'ldisc' member in the uart_device or to load ldisc by default for the corresponding tty_port?

Quoted 6 lines

No but it can provide information to help user space. In many cases the decision isn't about a line discipline but about automatically setting permissions or linking ports to the right driver.

The hints need to be generic - they can come from open firmware, from pci identifiers, from ACPI and so on.

Quoted 10 lines

Userspace need to know more than a simple type name to match the driver. For example,
Atheros BT will send wrapped HCI packets from their HSU BT adapters, so they need to see "ath3000" rather than "bluetooth" to load a kernel hci protocol module for the device.
As we can see, in the i2c/spi world, there is only "type" field filling w/ chip name, not 2 fields - "type" filled w/ generic type and "id" filled w/ chip name. Userspace can figure the generic "type" from the un-generic chip name like "type".
I just wonder will there be issues caused by following this design?

Ying has suggested me to include all of the HID/CIDs as a list into board_info. If OF need this feature, I'll split type into a type and an "ID" list.
The module_alias file can export all of the IDs and the device name can be the "type:index". I can make the modifications on this if you think this is better.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Shall we change the uart_bus to the tty_bus, then introduce tty_host /

tty_target for the bus?

We have a tty class - is that not sufficient ?

As I mentioned in the previous mail, I'll keep the current naming rule until I see some objections strong enough.

This statement is confusing in English, let me clarify this.
If the reasons for the uart_bus in the previous email are not correct, I'll change everything named as uart_xxx to tty_xxx, then the tty_bus is probably not needed, and I can use tty class after the decision.

Best regards
-Lv

#15 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Hi, Alan and Lv,

On Thu, 2012-12-06 at 22:41 -0700, Zheng, Lv wrote:
[snip]

Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Shall we change the uart_bus to the tty_bus, then introduce tty_host /

tty_target for the bus?

We have a tty class - is that not sufficient ?

As I mentioned in the previous mail, I'll keep the current naming rule until I see some objections strong enough.

This statement is confusing in English, let me clarify this.
If the reasons for the uart_bus in the previous email are not correct, I'll change everything named as uart_xxx to tty_xxx, then the tty_bus is probably not needed, and I can use tty class after the decision.

If my understanding were correct, the point is not about name it as uart_bus or tty_bus, but why do we need a bus instead of just use tty class for that.

If we use tty class to export tty target device information, it can be something as follow:

$ cd /sys/devices/platform/serial8250/tty/ttyS0
$ ls
slave_type
slave_id
slave_compat_ids
slave_attr
modem_lines

If we use uart or tty bus to export tty target device information, it can be something as follow:

$ cd /sys/devices/platform/serial8250/bluetooth:00
$ ls
type
id
compt_ids
attr
modem_lines
...
$ cd /sys/bus/(uart|tty)/devices
$ ls
bluetooth:00

Both works. But IMHO, the second one appears more natural and consistent, just like other hardware devices in system. And create struct device for each target devices make it easier to do power management etc, for example, user can enable/disable runtime power management via bluetooth:00/power/control, just like other hardware devices.

Best Regards,
Huang Ying

#16 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Zheng, Lv
Quoted 1 line

Ying has suggested me to include all of the HID/CIDs as a list into board_info.

if HID/CID values are also provided by ACPI then that makes sense

Quoted 1 line

If OF need this feature, I'll split type into a type and an "ID" list.

That would be good. Code that wants generic answers can check the type, code that wants identifiers or needs detail can check the ids

Alan

#17 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Zheng, Lv
Quoted 7 lines · Lv
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Is it a good idea to introduce uart_device driver in the kernel to fill a new

'ldisc' member in the uart_device or to load ldisc by default for the corresponding tty_port?

Quoted 8 lines
Quoted 6 lines

No but it can provide information to help user space. In many cases the decision isn't about a line discipline but about automatically setting permissions or linking ports to the right driver.

The hints need to be generic - they can come from open firmware, from pci identifiers, from ACPI and so on.

Userspace need to know more than a simple type name to match the driver.

It's just an enumeration - and unlike numbers names don't usually collide or need hard management

Quoted 2 lines

For example,
Atheros BT will send wrapped HCI packets from their HSU BT adapters, so they need to see "ath3000" rather than "bluetooth" to load a kernel hci protocol module for the device.

Fine so we could use "bluetooth/atheros" or similar. Easily dealt with

Alan

author
#18 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Alan Cox
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

Quoted 8 lines
Quoted 5 lines

The only property that comes into mind is _HID/_CID (referring to the ACPI
ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Hi, Mika

How is this handled in the i2c?
I think for OF, type can be filled as "bluetooth", "ups" and etc.
But for ACPI, the type field of the i2c_board_info is filled as hid in your patches. Is this right?

Maybe I just need to add struct acpi_dev_node to the uart_board_info and let OF guys add of_node to it. What's your opinion?

Best regards
-Lv

#19 lore raw

Re: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

Quoted 10 lines · Lv
Quoted 10 lines
Quoted 9 lines
Quoted 3 lines

The property should not be in any ACPI specific form or space - just attach it directly to the tty from ACPI, DT, driver internal knowledge, PCI id, whatever

The only property that comes into mind is _HID/_CID (referring to the ACPI
ID) that can be used by userspace to find out type of the device behind the UART port. I don't know what name would be generic enough for the property, though.

Quoted 6 lines
Quoted 2 lines

We just need a set of type names for the sysfs node I think "bluetooth", "ups", "loconet", "serial", "modem", "cir" etc...

Hi, Mika

How is this handled in the i2c?

We match the I2C device to the driver using _HID/_CID in the kernel. There is no userpace involved (except maybe loading the correct driver module).

Quoted 3 lines

I think for OF, type can be filled as "bluetooth", "ups" and etc.
But for ACPI, the type field of the i2c_board_info is filled as hid in your patches. Is this right?

Yes.

Quoted 2 lines

Maybe I just need to add struct acpi_dev_node to the uart_board_info and let OF guys add of_node to it. What's your opinion?

Well, in order to use any ACPI functions and PM you need to have ACPI_HANDLE(dev) != NULL. If the best place to pass that handle is uart_board_info (in analogy to i2c_board_info), then yes you should add it there.

author
#20 lore raw

RE: [RFC PATCH 1/3] UART: Add UART subsystem as a bus.

In reply to Mika Westerberg
Quoted 36 lines · Lv Zheng
Quoted 9 lines

kobject attribute files:

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,

What if instead of exporting these to userspace we just set the defaults based on the UartSerialBus() value? This way the user only needs to find the right tty to pass to hciattach.

Quoted 8 lines

kobject sysfs links:

# ls -l /sys/bus/uart/devices
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0
target_node -> ../../INTF001:00

And if we have enumerated the UART controller from ACPI (it is probably attached to the platform bus) we can find the tty device it exports like:

/sys/bus/platform/devices/INTF000:00/tty/ttyS1/dev

Only thing that is missing then is the type of the connected device. That can be extracted by following the firmware_node symlink:

# ls /sys/bus/platform/devices/INTF000\:00/firmware_node/
INTF001:00
...
Quoted 8 lines
# cat
/sys/bus/platform/devices/INTF000\:00/firmware_node/INTF001:00/hid
INTF001

This ACPI ID then can be used to find out what device it is.

Well, this is probably not the simplest solution :-) I'm just trying to understand why we need to add a new bus type if only thing it adds is the sysfs files.

In our team, we've been discussing this solution like your suggestion for some times. ACPI UART enumeration can be done in this way without kernel modifications.

IMO:
1. tty_device is current used as "host" side device, you can find .pm support in most of the serial drivers.
They are always the codes turning off/on the clock of the host controller.
If we want to support PM for a target device, there is no such node in the kernel device hierarchy.
2. firmware_node is based on the "likely deprecated" acpi_device solution, I need to find another one. Maybe this is still a shadow device. Like dmi-id device, a shadow device exporting attributes and generating uevents for the user space drivers may be helpful. It would be better if the PM support of the target devices can benefit from the existence of the shadow uart target devices.

Quoted 9 lines
Quoted 9 lines
drivers/tty/serial/serial_bus.c new file +9 -0
+/**
+ * uart_unregister_device - unregister a UART device
+ * @device: value returned from uart_register_device()
+ *
+ * Reverse effect of uart_register_device().
+ */
+void uart_unregister_device(struct uart_device *udev) {
+	if (udev->adap)
+		klist_del(&udev->klist_parent);
Quoted 8 lines

drivers/tty/serial/serial_bus.c line 336

Quoted 6 lines
drivers/tty/serial/serial_bus.c new file +6 -0
+	sysfs_remove_link(&udev->dev.kobj, "host_node");
+	if (udev->tty)
+		sysfs_remove_link(&udev->tty->kobj, "target_node");
+	device_unregister(&udev->dev);
+}
+EXPORT_SYMBOL_GPL(uart_unreigster_device);

Typo in the function name.

Fixed...

Thanks and best regards/Lv Zheng

author
#21 lore raw

RFC PATCH 2/3 ACPI / UART: Add ACPI enumeration support for UART bus.

In reply to Lv Zheng

ACPI 5.0 specification introduces the methods of enumerating the target devices connected on the serial buses.
This patch follows the specification, implementing such UART enumeration machanism for the Linux.

In order to use this UART device enumeration mechanism, driver writers are required to call the following APIs:
1. APIs called _after_ the creation of the uart ports:
adap = acpi_uart_register_devices(driver, adap, parent, line); Where:
driver: the low level UART driver
parent: the physical device of the UART ports
adap: the management list of the target devices, can be set as NULL
line: the line number of the target device
2. APIs called _before_ the deletion of the uart ports:
acpi_uart_unregister_devices(adap);
Where:
adap: the UART target device manager

NOTE: If the driver writer has already created the management list for
the UART target devices, the adap parameter can be set to the already created non-NULL value.
NOTE: The ACPI 5.0 specification assumes one physical device per-port.
In this situation, the line parameter might be set to 0 when the acpi_uart_register_devices() is called.
This patch set can also support the multi-port UART adapters, where the line should be set as ACPI_UART_LINE_UNKNOWN.

---
 drivers/acpi/Kconfig      |    7 ++
 drivers/acpi/Makefile     |    1 +
 drivers/acpi/acpi_uart.c  |  255 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi_uart.h |   40 +++++++
 4 files changed, 303 insertions(+)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 include/linux/acpi_uart.h
drivers/acpi/Kconfig +7 -0
index 0300bf6..d40203f 100644
@@ -187,6 +187,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate SERIAL_CORE
+	depends on SERIAL_CORE
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
@@ -200,6 +206,7 @@ config ACPI_PROCESSOR
 
 	  To compile this driver as a module, choose M here:
 	  the module will be called processor.
+
 config ACPI_IPMI
 	tristate "IPMI"
 	depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER
drivers/acpi/Makefile +1 -0
index 2a4502b..784f332 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +255 -0

255 lines not on this page · raw message

include/linux/acpi_uart.h new file +40 -0
new file mode 100644
index 0000000..512f047
@@ -0,0 +1,40 @@
+/*
+ * acpi_uart.h - ACPI UART enumeration support
+ *
+ * Copyright (c) 2012, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _LINUX_ACPI_UART_H
+#define _LINUX_ACPI_UART_H
+
+struct uart_driver;
+
+#define ACPI_UART_LINE_UNKNOWN	((unsigned int)-1)
+
+#if IS_ENABLED(CONFIG_ACPI_UART)
+struct klist *acpi_uart_register_devices(struct uart_driver *drv,
+					 struct klist *adap,
+					 struct device *parent,
+					 unsigned int line);
+void acpi_uart_unregister_devices(struct klist *adap);
+#else
+static inline struct klist *acpi_uart_register_devices(struct uart_driver *drv,
+						       struct klist *adap,
+						       struct device *parent,
+						       unsigned int line)
+{
+	return NULL;
+}
+
+static inline void acpi_uart_unregister_devices(struct klist *adap)
+{
+}
+#endif
+
+#endif /* _LINUX_ACPI_UART_H */
Signature · 1 line
1.7.10
author
#22 lore raw

RFC PATCH 3/3 UART: Add dummy devices to test the enumeration.

In reply to Lv Zheng

This is a hidden test patch that would not be sent to the public. There might be some udev add-ons for matching the UART target devices from the user space.

1. The result of the UART dummy target device is as follows:

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/bus/uart/uevent
# echo add > /sys/bus/uart/devices/DUMMY/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/serial8250/DUMMY (uart)
ACTION=add
DEVPATH=/devices/platform/serial8250/DUMMY
DEVTYPE=uart_device
MODALIAS=uart:DUMMY
SEQNUM=1144
SUBSYSTEM=uart

# cat /sys/bus/uart/devices/DUMMY/modalias
uart:DUMMY
# cat /sys/bus/uart/devices/DUMMY/tty_dev
ttyS0
# cat /sys/bus/uart/devices/DUMMY/tty_attrs
115200 8N1 HW SW
# cat /sys/bus/uart/devices/DUMMY/modem_lines
LE:RTS,

2. The result of the UART customized DSDT target device is as follows:

The test result is attached as part of the first patch in this series.

---
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |   10 ++-
 drivers/tty/serial/8250/8250_dummy.c |  128 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +++
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/serial_bus.c      |   17 +++++
 include/linux/serial_8250.h          |    2 +
 include/linux/serial_core.h          |    3 +
 8 files changed, 170 insertions(+), 2 deletions(-)
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
drivers/acpi/scan.c +1 -0
index 67a7fa6..4892015 100644
@@ -36,6 +36,7 @@ static const char *dummy_hid = "device";
 static const struct acpi_device_id acpi_platform_device_ids[] = {
 
 	{ "PNP0D40" },
+	{ "INTF000" },
 
 	{ }
 };
drivers/tty/serial/8250/8250.c +8 -2
index 3ba4234..6f503f4 100644
@@ -56,7 +56,7 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
 static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 
-static struct uart_driver serial8250_reg;
+struct uart_driver serial8250_reg;
 
 static int serial_index(struct uart_port *port)
 {
@@ -2902,7 +2902,7 @@ int serial8250_find_port(struct uart_port *p)
 #define SERIAL8250_CONSOLE	NULL
 #endif
 
-static struct uart_driver serial8250_reg = {
+struct uart_driver serial8250_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "serial",
 	.dev_name		= "ttyS",
@@ -2910,6 +2910,7 @@ static struct uart_driver serial8250_reg = {
 	.minor			= 64,
 	.cons			= SERIAL8250_CONSOLE,
 };
+EXPORT_SYMBOL_GPL(serial8250_reg);
 
 /*
  * early_serial_setup - early registration for 8250 ports
@@ -2987,6 +2988,8 @@ void serial8250_resume_port(int line)
 	uart_resume_port(&serial8250_reg, port);
 }
 
+struct uart_device *uart_dummy;
+
 /*
  * Register a set of serial devices attached to a platform device.  The
  * list is terminated with a zero flags entry, which means we expect
@@ -3032,6 +3035,8 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 				p->irq, ret);
 		}
 	}
+	uart_dummy = uart_register_dummy(&serial8250_reg, &dev->dev, 0);
+
 	return 0;
 }
 
@@ -3042,6 +3047,7 @@ static int __devexit serial8250_remove(struct platform_device *dev)
 {
 	int i;
 
+	uart_unregister_device(uart_dummy);
 	for (i = 0; i < nr_uarts; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
drivers/tty/serial/8250/8250_dummy.c new file +128 -0

128 lines not on this page · raw message

drivers/tty/serial/8250/Kconfig +10 -0
index f3d283f..3ba480a 100644
@@ -270,6 +270,16 @@ config SERIAL_8250_DW
 	  Selecting this option will enable handling of the extra features
 	  present in the Synopsys DesignWare APB UART.
 
+config SERIAL_8250_DUMMY
+	tristate "Support for dummy ACPI 8250"
+	depends on SERIAL_8250 && ACPI
+	help
+	  Selecting this option will enable a test UART target device DUMMY
+	  under the ISA serial8250 and a test UART host adapter INTF000
+	  as an platform device for the purpose of testing the ACPI UART
+	  enumeration support.
+	  If unsure, say "N" here.
+
 config SERIAL_8250_EM
 	tristate "Support for Emma Mobile intergrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
drivers/tty/serial/8250/Makefile +1 -0
index 108fe7f..fb82aa9 100644
@@ -19,3 +19,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6)		+= 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_FSL)		+= 8250_fsl.o
 obj-$(CONFIG_SERIAL_8250_DW)		+= 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
+obj-$(CONFIG_SERIAL_8250_DUMMY)		+= 8250_dummy.o
drivers/tty/serial/serial_bus.c +17 -0
index a6674da..e3d0509 100644
@@ -384,6 +384,23 @@ void uart_del_adapter(struct klist *adap)
 }
 EXPORT_SYMBOL_GPL(uart_del_adapter);
 
+static struct uart_board_info dummy_target = {
+	.type = "DUMMY",
+	.baud = 115200,
+	.cflag = CS8 | CSTOPB | CRTSCTS,
+	.iflag = (IXON | IXOFF),
+	.mctrl = TIOCM_LE | TIOCM_RTS,
+};
+
+struct uart_device *uart_register_dummy(struct uart_driver *drv,
+					struct device *dev,
+					unsigned int line)
+{
+	dummy_target.line = line;
+	return uart_register_device(drv, NULL, dev, &dummy_target);
+}
+EXPORT_SYMBOL_GPL(uart_register_dummy);
+
 struct bus_type uart_bus_type = {
 	.name		= "uart",
 };
include/linux/serial_8250.h +2 -0
index c174c90..3b6c260 100644
@@ -120,4 +120,6 @@ extern void serial8250_set_isa_configurator(void (*v)
 					(int port, struct uart_port *up,
 						unsigned short *capabilities));
 
+extern struct uart_driver serial8250_reg;
+
 #endif
include/linux/serial_core.h +3 -0
index 422f8cc4..a3d1d5d 100644
@@ -418,6 +418,9 @@ struct uart_device *uart_register_device(struct uart_driver *drv,
 					 struct device *dev,
 					 struct uart_board_info const *info);
 void uart_unregister_device(struct uart_device *udev);
+struct uart_device *uart_register_dummy(struct uart_driver *drv,
+					struct device *dev,
+					unsigned int line);
 
 struct device *uart_tty_find(struct uart_driver *drv,
 			     struct device *dev, unsigned int line);
Signature · 1 line
1.7.10
author
#23 lore raw

v2 cover ACPI/UART: Add ACPI 5.0 enueration support for UART.

In reply to Lv Zheng

ACPI 5.0 specification introduces enumeration support for SPB buses. This patch set adds the UART serial bus enumeration support to Linux using such mechanism.

NOTE: The [PATCH 4/4] is only for the demonstration purpose and should not
be merged into any of the published Linux source tree.

Lv Zheng (4):
UART: Add UART subsystem as a bus.
ACPI / UART: Add ACPI enumeration support for UART bus. UART / 8250: Add declearation of serial8250 driver.
UART: Add dummy devices to test the enumeration.

 drivers/acpi/Kconfig                 |    7 +
 drivers/acpi/Makefile                |    1 +
 drivers/acpi/acpi_uart.c             |  262 +++++++++++++++++++++
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |   17 +-
 drivers/tty/serial/8250/8250_dummy.c |  129 ++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/Makefile          |    2 +-
 drivers/tty/serial/serial_bus.c      |  429 ++++++++++++++++++++++++++++++++++
 include/linux/acpi_uart.h            |   40 ++++
 include/linux/mod_devicetable.h      |    5 +
 include/linux/serial_8250.h          |    2 +
 include/linux/serial_bus.h           |   80 +++++++
 14 files changed, 982 insertions(+), 4 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
 create mode 100644 drivers/tty/serial/serial_bus.c
 create mode 100644 include/linux/acpi_uart.h
 create mode 100644 include/linux/serial_bus.h
Signature · 1 line
1.7.10
author
#24 lore raw

PATCH v2 1/4 UART: Add UART subsystem as a bus.

Tranditional UARTs are used as communication pipes between the hosts while the modern computing systems equipped with HSU (High Speed UARTs) would connect on-board target devices using the UART ports. The role of the UART controllers is changed from the communication facility to the platform bus.

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART target devices known to the platform vendors.
Thus there are the needs for enumerating the UART target devices:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART target devices.
In order to send uevent, a device need to be a class device or a bus device. This patch introduces a bus_type subsystem to manage the new UART target device type for the purpose of being ready for the possible future extensions.
When the UART target devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach). Here is an example of the uevents and exported attributes of these new UART target devices:

Test DSDT (dummy UART host adapter INTF000 and target device INTF001):
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

uevent and environments:
KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/INTF001:00 (uart)
ACTION=add
DEVPATH=/devices/platform/INTF000:00/INTF001:00
DEVTYPE=uart_device
MODALIAS=uart:INTF001:00
SEQNUM=1144
SUBSYSTEM=uart

kobject attribute files:

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,

kobject sysfs links:

# ls -l /sys/bus/uart/devices
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0
target_node -> ../../INTF001:00

History:
v1:
1. Add uart bus type subsystem.
2. Add physical uart target device (uart_device).
3. Add logical uart host adapter (klist).
4. Add uart target device attributes.
5. Create tty_device<->uart_device links.
v2.
1. Change uart driver related stuff to tty driver.

---
 drivers/tty/serial/Makefile     |    2 +-
 drivers/tty/serial/serial_bus.c |  412 +++++++++++++++++++++++++++++++++++++++
 include/linux/mod_devicetable.h |    5 +
 include/linux/serial_bus.h      |   75 +++++++
 4 files changed, 493 insertions(+), 1 deletion(-)
 create mode 100644 drivers/tty/serial/serial_bus.c
 create mode 100644 include/linux/serial_bus.h
drivers/tty/serial/Makefile +1 -1
index 4f694da..4400521 100644
@@ -2,7 +2,7 @@
 # Makefile for the kernel serial device drivers.
 #
 
-obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+obj-$(CONFIG_SERIAL_CORE) += serial_core.o serial_bus.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
 
 # These Sparc drivers have to appear before others such as 8250
drivers/tty/serial/serial_bus.c new file +412 -0

412 lines not on this page · raw message

include/linux/mod_devicetable.h +5 -0
index fed3def..28df140 100644
@@ -455,6 +455,11 @@ struct spi_device_id {
 			__attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+/* uart */
+
+#define UART_NAME_SIZE	32
+#define UART_MODULE_PREFIX "uart:"
+
 /* dmi */
 enum dmi_field {
 	DMI_NONE,
include/linux/serial_bus.h new file +75 -0

75 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#25 lore raw

PATCH v2 2/4 ACPI / UART: Add ACPI enumeration support for UART bus.

In reply to Lv Zheng

ACPI 5.0 specification introduces the methods of enumerating the target devices connected on the serial buses.
This patch follows the specification, implementing such UART enumeration machanism for the Linux.

In order to use this UART device enumeration mechanism, driver writers are required to call the following APIs:
1. APIs called _after_ the creation of the uart ports:
adap = acpi_uart_register_devices(driver, adap, parent, line); Where:
driver: the low level UART driver
parent: the physical device of the UART ports
adap: the management list of the target devices, can be set as NULL
line: the line number of the target device
2. APIs called _before_ the deletion of the uart ports:
acpi_uart_unregister_devices(adap);
Where:
adap: the management list of the UART target devices

NOTE: If the driver writer has already created the management list for
the UART target devices, the adap parameter can be set to the already created non-NULL value.
NOTE: The ACPI 5.0 specification assumes one physical device per-port.
In this situation, the line parameter might be set to 0 when the acpi_uart_register_devices() is called.
This patch set can also support the multi-port UART adapters, where the line should be set as ACPI_UART_LINE_UNKNOWN.

---
 drivers/acpi/Kconfig      |    7 ++
 drivers/acpi/Makefile     |    1 +
 drivers/acpi/acpi_uart.c  |  262 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi_uart.h |   40 +++++++
 4 files changed, 310 insertions(+)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 include/linux/acpi_uart.h
drivers/acpi/Kconfig +7 -0
index 0300bf6..d40203f 100644
@@ -187,6 +187,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate SERIAL_CORE
+	depends on SERIAL_CORE
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
@@ -200,6 +206,7 @@ config ACPI_PROCESSOR
 
 	  To compile this driver as a module, choose M here:
 	  the module will be called processor.
+
 config ACPI_IPMI
 	tristate "IPMI"
 	depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER
drivers/acpi/Makefile +1 -0
index 2a4502b..784f332 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +262 -0

262 lines not on this page · raw message

include/linux/acpi_uart.h new file +40 -0
new file mode 100644
index 0000000..a928425
@@ -0,0 +1,40 @@
+/*
+ * acpi_uart.h - ACPI UART enumeration support
+ *
+ * Copyright (c) 2012, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _LINUX_ACPI_UART_H
+#define _LINUX_ACPI_UART_H
+
+struct uart_driver;
+
+#define ACPI_UART_LINE_UNKNOWN	((unsigned int)-1)
+
+#if IS_ENABLED(CONFIG_ACPI_UART)
+struct klist *acpi_uart_register_devices(struct klist *adap,
+					 struct device *parent,
+					 struct tty_driver *drv,
+					 unsigned int line);
+void acpi_uart_unregister_devices(struct klist *adap);
+#else
+static inline struct klist *acpi_uart_register_devices(struct klist *adap,
+						       struct device *parent,
+						       struct tty_driver *drv,
+						       unsigned int line)
+{
+	return NULL;
+}
+
+static inline void acpi_uart_unregister_devices(struct klist *adap)
+{
+}
+#endif
+
+#endif /* _LINUX_ACPI_UART_H */
Signature · 1 line
1.7.10
author
#26 lore raw

PATCH v2 3/4 UART / 8250: Add declearation of serial8250 driver.

In reply to Lv Zheng

Export serial8250 uart driver for uart bus enumerator users.

---
 drivers/tty/serial/8250/8250.c |    5 ++---
 include/linux/serial_8250.h    |    2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/tty/serial/8250/8250.c +2 -3
index 3ba4234..af78374 100644
@@ -56,8 +56,6 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
 static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 
-static struct uart_driver serial8250_reg;
-
 static int serial_index(struct uart_port *port)
 {
 	return (serial8250_reg.minor - 64) + port->line;
@@ -2902,7 +2900,7 @@ int serial8250_find_port(struct uart_port *p)
 #define SERIAL8250_CONSOLE	NULL
 #endif
 
-static struct uart_driver serial8250_reg = {
+struct uart_driver serial8250_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "serial",
 	.dev_name		= "ttyS",
@@ -2910,6 +2908,7 @@ static struct uart_driver serial8250_reg = {
 	.minor			= 64,
 	.cons			= SERIAL8250_CONSOLE,
 };
+EXPORT_SYMBOL_GPL(serial8250_reg);
 
 /*
  * early_serial_setup - early registration for 8250 ports
include/linux/serial_8250.h +2 -0
index c174c90..687af38 100644
@@ -96,6 +96,8 @@ struct uart_8250_port {
 	void			(*dl_write)(struct uart_8250_port *, int);
 };
 
+extern struct uart_driver serial8250_reg;
+
 int serial8250_register_8250_port(struct uart_8250_port *);
 void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
Signature · 1 line
1.7.10
author
#27 lore raw

PATCH v2 4/4 UART: Add dummy devices to test the enumeration.

In reply to Lv Zheng

This is a test patch that should not be merged to any of the published Linux source tree.

1. The result of the UART dummy target device is as follows:

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/bus/uart/uevent
# echo add > /sys/bus/uart/devices/DUMMY/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/serial8250/DUMMY (uart)
ACTION=add
DEVPATH=/devices/platform/serial8250/DUMMY
DEVTYPE=uart_device
MODALIAS=uart:DUMMY
SEQNUM=1144
SUBSYSTEM=uart

# cat /sys/bus/uart/devices/DUMMY/modalias
uart:DUMMY
# cat /sys/bus/uart/devices/DUMMY/tty_dev
ttyS3
# cat /sys/bus/uart/devices/DUMMY/tty_attrs
115200 8N1 HW SW
# cat /sys/bus/uart/devices/DUMMY/modem_lines
LE:RTS,
# ls -l /sys/bus/uart/devices
DUMMY -> ../../../devices/platform/serial8250/DUMMY
# ls -l /sys/devices/platform/serial8250/DUMMY
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS3
# ls -l /sys/devices/platform/serial8250/tty/ttyS3
target_node -> ../../DUMMY

2. The result of the UART customized DSDT target device is as follows:

The test is based on the following customized DSDT (containing the dummy uart host adapter INTF000 and target device INTF001):
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/bus/uart/uevent
# echo add > /sys/bus/uart/devices/INTF001/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/INTF001:00 (uart)
ACTION=add
DEVPATH=/devices/platform/INTF000:00/INTF001:00
DEVTYPE=uart_device
MODALIAS=uart:INTF001:00
SEQNUM=1144
SUBSYSTEM=uart

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,
# ls -l /sys/bus/uart/devices
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0
target_node -> ../../INTF001:00
---
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |   12 ++++
 drivers/tty/serial/8250/8250_dummy.c |  129 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +++
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/serial_bus.c      |   17 +++++
 include/linux/serial_bus.h           |    5 ++
 7 files changed, 175 insertions(+)
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
drivers/acpi/scan.c +1 -0
index 67a7fa6..4892015 100644
@@ -36,6 +36,7 @@ static const char *dummy_hid = "device";
 static const struct acpi_device_id acpi_platform_device_ids[] = {
 
 	{ "PNP0D40" },
+	{ "INTF000" },
 
 	{ }
 };
drivers/tty/serial/8250/8250.c +12 -0
index af78374..745e05d 100644
@@ -35,6 +35,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/serial_bus.h>
 #include <linux/nmi.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -2986,6 +2987,8 @@ void serial8250_resume_port(int line)
 	uart_resume_port(&serial8250_reg, port);
 }
 
+struct uart_device *uart_dummy;
+
 /*
  * Register a set of serial devices attached to a platform device.  The
  * list is terminated with a zero flags entry, which means we expect
@@ -2996,6 +2999,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 	struct plat_serial8250_port *p = dev->dev.platform_data;
 	struct uart_8250_port uart;
 	int ret, i, irqflag = 0;
+	unsigned int dummy_line;
 
 	memset(&uart, 0, sizeof(uart));
 
@@ -3031,6 +3035,13 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 				p->irq, ret);
 		}
 	}
+
+	dummy_line = serial8250_ports[nr_uarts-1].port.line;
+	pr_info("registering DUMMY at line %d.\n", dummy_line);
+	uart_dummy = uart_register_dummy(&dev->dev,
+					 serial8250_reg.tty_driver,
+					 dummy_line);
+
 	return 0;
 }
 
@@ -3041,6 +3052,7 @@ static int __devexit serial8250_remove(struct platform_device *dev)
 {
 	int i;
 
+	uart_unregister_device(uart_dummy);
 	for (i = 0; i < nr_uarts; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
drivers/tty/serial/8250/8250_dummy.c new file +129 -0

129 lines not on this page · raw message

drivers/tty/serial/8250/Kconfig +10 -0
index f3d283f..3ba480a 100644
@@ -270,6 +270,16 @@ config SERIAL_8250_DW
 	  Selecting this option will enable handling of the extra features
 	  present in the Synopsys DesignWare APB UART.
 
+config SERIAL_8250_DUMMY
+	tristate "Support for dummy ACPI 8250"
+	depends on SERIAL_8250 && ACPI
+	help
+	  Selecting this option will enable a test UART target device DUMMY
+	  under the ISA serial8250 and a test UART host adapter INTF000
+	  as an platform device for the purpose of testing the ACPI UART
+	  enumeration support.
+	  If unsure, say "N" here.
+
 config SERIAL_8250_EM
 	tristate "Support for Emma Mobile intergrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
drivers/tty/serial/8250/Makefile +1 -0
index 108fe7f..fb82aa9 100644
@@ -19,3 +19,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6)		+= 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_FSL)		+= 8250_fsl.o
 obj-$(CONFIG_SERIAL_8250_DW)		+= 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
+obj-$(CONFIG_SERIAL_8250_DUMMY)		+= 8250_dummy.o
drivers/tty/serial/serial_bus.c +17 -0
index afbb885..d25058a 100644
@@ -387,6 +387,23 @@ void uart_del_adapter(struct klist *adap)
 }
 EXPORT_SYMBOL_GPL(uart_del_adapter);
 
+static struct uart_board_info dummy_target = {
+	.type = "DUMMY",
+	.baud = 115200,
+	.cflag = CS8 | CSTOPB | CRTSCTS,
+	.iflag = (IXON | IXOFF),
+	.mctrl = TIOCM_LE | TIOCM_RTS,
+};
+
+struct uart_device *uart_register_dummy(struct device *dev,
+					struct tty_driver *drv,
+					unsigned int line)
+{
+	dummy_target.line = line;
+	return uart_register_device(NULL, dev, drv, &dummy_target);
+}
+EXPORT_SYMBOL_GPL(uart_register_dummy);
+
 struct bus_type uart_bus_type = {
 	.name		= "uart",
 };
include/linux/serial_bus.h +5 -0
index 6d66fe2..917bbae 100644
@@ -72,4 +72,9 @@ struct device *uart_tty_find(struct tty_driver *drv, unsigned int line,
 			     struct device *dev);
 void uart_tty_name(struct tty_driver *driver, unsigned int line, char *p);
 
+/* Test dummy device registration */
+struct uart_device *uart_register_dummy(struct device *dev,
+					struct tty_driver *drv,
+					unsigned int line);
+
 #endif /* LINUX_SERIAL_BUS_H */
Signature · 1 line
1.7.10
author
#28 lore raw

v3 cover ACPI/UART: Add ACPI 5.0 enueration support for UART.

In reply to Lv Zheng

ACPI 5.0 specification introduces enumeration support for SPB buses. This patch set adds the UART serial bus enumeration support to Linux using such mechanism.

NOTE: The [PATCH 4/4] is only for the demonstration purpose and should not
be merged into any of the published Linux source tree.

History:
v1:
1. Add uart bus type subsystem (uart_bus).
2. Add physical uart target device and description (uart_device/uart_board_info).
3. Add logical uart host adapter (klist).
4. Add uart target device attributes (tty_dev/tty_attrs/modem_lines).
5. Create tty_device<->uart_device links (host_node/target_node).
v2.
1. Change uart layer related stuff to tty layer.
2. Modify the order of the function parameters.
v3:
1. Add comments for the uart_board_info and the uart_device.
2. Add platform_data/archdata support.
3. Add ACPI binding and test the binding.
4. Add SERIAL_BUS kconfig item.

RFCs:
1. Do we need to rename uart_bus to tty_bus and rename uart_device to tty_target?
2. Do we need a kernel driver for the uart_device?
3. Do we need to split uart_board_info.type into uart_board_info.id and uart_board_info.type? How can ACPI fill the uart_board_info.type?
4. Do we need to set line discipline for the uart_board_info?

Lv Zheng (4):
UART: Add UART subsystem as a bus.
ACPI / UART: Add ACPI enumeration support for UART bus. UART / 8250: Add declearation of serial8250 driver.
UART: Add dummy devices to test the enumeration.

 drivers/acpi/Kconfig                 |    7 +
 drivers/acpi/Makefile                |    1 +
 drivers/acpi/acpi_uart.c             |  263 ++++++++++++++++++++
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |   17 +-
 drivers/tty/serial/8250/8250_dummy.c |  129 ++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/Kconfig           |    8 +
 drivers/tty/serial/Makefile          |    1 +
 drivers/tty/serial/serial_bus.c      |  435 ++++++++++++++++++++++++++++++++++
 include/linux/acpi_uart.h            |   40 ++++
 include/linux/mod_devicetable.h      |    5 +
 include/linux/serial_8250.h          |    2 +
 include/linux/serial_bus.h           |  126 ++++++++++
 15 files changed, 1043 insertions(+), 3 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
 create mode 100644 drivers/tty/serial/serial_bus.c
 create mode 100644 include/linux/acpi_uart.h
 create mode 100644 include/linux/serial_bus.h
Signature · 1 line
1.7.10
author
#29 lore raw

RFC PATCH v3 1/4 UART: Add UART subsystem as a bus.

Tranditional UARTs are used as communication pipes between the hosts while the modern computing systems equipped with HSU (High Speed UARTs) would connect on-board target devices using the UART ports. The role of the UART controllers is changed from the communication facility to the platform bus.

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART target devices known to the platform vendors.
Thus there are the needs for enumerating the UART target devices:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART target devices.
In order to send uevent, a device need to be a class device or a bus device. This patch introduces a bus_type subsystem to manage the new UART target device type for the purpose of being ready for the possible future extensions.
When the UART target devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach). Here is an example of the uevents and exported attributes of these new UART target devices:

Test DSDT (dummy UART host adapter INTF000 and target device INTF001):
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

The test result of hotplug event monitoring:
uevent and environments:
KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/INTF001:00 (uart)
ACTION=add
DEVPATH=/devices/platform/INTF000:00/INTF001:00
DEVTYPE=uart_device
MODALIAS=uart:INTF001:00
SEQNUM=1144
SUBSYSTEM=uart

The test result of the UART target device enumeration:
kobject attribute files:

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,

kobject sysfs links:

# ls -l /sys/bus/uart/devices/
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00/
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0/
target_node -> ../../INTF001:00
---
 drivers/tty/serial/Kconfig      |    8 +
 drivers/tty/serial/Makefile     |    1 +
 drivers/tty/serial/serial_bus.c |  417 +++++++++++++++++++++++++++++++++++++++
 include/linux/mod_devicetable.h |    5 +
 include/linux/serial_bus.h      |  119 +++++++++++
 5 files changed, 550 insertions(+)
 create mode 100644 drivers/tty/serial/serial_bus.c
 create mode 100644 include/linux/serial_bus.h
drivers/tty/serial/Kconfig +8 -0
index 2a53be5..e16b03a 100644
@@ -749,6 +749,14 @@ config SERIAL_HS_LPC32XX_CONSOLE
 	  ports on the LPC32XX as the console, you can do so by answering
 	  Y to this option.
 
+config SERIAL_BUS
+	bool "Enable Serial bus enumerator support"
+	help
+	  If your platform has enumeration support for the serial target
+	  devices, you can enable this option by say Y here. Such
+	  enumeration mechanisms are always provided by the firmwares.
+	  If unsure, say N.
+
 config SERIAL_CORE
 	tristate
 
drivers/tty/serial/Makefile +1 -0
index 4f694da..9a05bbc 100644
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+obj-$(CONFIG_SERIAL_BUS) += serial_bus.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
 
 # These Sparc drivers have to appear before others such as 8250
drivers/tty/serial/serial_bus.c new file +417 -0

417 lines not on this page · raw message

include/linux/mod_devicetable.h +5 -0
index fed3def..28df140 100644
@@ -455,6 +455,11 @@ struct spi_device_id {
 			__attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+/* uart */
+
+#define UART_NAME_SIZE	32
+#define UART_MODULE_PREFIX "uart:"
+
 /* dmi */
 enum dmi_field {
 	DMI_NONE,
include/linux/serial_bus.h new file +119 -0

119 lines not on this page · raw message

Signature · 1 line
1.7.10
#30 lore raw

Re: [RFC PATCH v3 1/4] UART: Add UART subsystem as a bus.

Quoted 3 lines

enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART target devices.

ls /sys/class/tty/

Quoted 2 lines

In order to send uevent, a device need to be a class device or a bus device. This patch introduces a bus_type subsystem to manage the new

I still don't see why the existing tty class interfaces cannot be used, the hints from ACPI (or anywhere else) cannot be attached as properties to the tty driver and device sysfs

Alan

author
#31 lore raw

RE: [RFC PATCH v3 1/4] UART: Add UART subsystem as a bus.

Quoted 5 lines
Quoted 3 lines

enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART target devices.

ls /sys/class/tty/

I'm searching for a target "physical" device while the "tty device" looks more like a "functional" device.

IMO, an ideal driver model is:
Creating a strict IO topology for all of the physical buses w/ physical devices created within this hierarchy, then make the abstract things "class devices", including the "functional devices" and the "filter devices". The examples of the "physical devices": platform device, uart_device, i2c_client, spi_device
The examples of the "functional devices": tty device, i2c_adapter, spi_master
The examples of the "filter devices": ppp device

If this rule is strictly obeyed by all of the subsystems, then:
1. the hardware PM can be added to the physical devices
2. the functional devices will inc/dec the PM reference count for the physical devices <- this can help to add request based runtime PM
3. the other filter devices/drivers can call the APIs provided by the functional devices, some of them may affect the PM ref count. Implementing OS guided power management might be simpler:
1. if a bus offered PM support, it should appear in the bus_type
2. if a platform offered PM support, it should appear as PM_domain
Currently, Linux allows enabling of PM support for device_type, if things are cleaned up, the use of device_type PM can be reduced.

If a device was handling hardware stuff including the PM, it should be a "physical device".
If a device was offering communication means, it should be a "functional device".
If a device was using the communication means, it should be a "filter device".
So how could a tty device be a physical device? If we enable PM for it, dpm_list order will be crushed, issues might occur on system suspending/resuming.

Quoted 6 lines
Quoted 2 lines

In order to send uevent, a device need to be a class device or a bus device. This patch introduces a bus_type subsystem to manage the new

I still don't see why the existing tty class interfaces cannot be used, the hints from ACPI (or anywhere else) cannot be attached as properties to the tty driver and device sysfs

I checked the PM call chain, then found the followings:

On system suspending:
adapter.suspend -> for_each_port(uart_suspend_port) -> uart_change_pm(3) -> uart_ops->pm -> uart_port->pm
On system resuming:
adapter.resume -> for_each_port(uart_resume_port) -> uart_change_pm(0) -> uart_ops->pm -> uart_port->pm
Where the adapter could be platform devices.

On tty file opening:
uart_open -> uart_change_pm(0) -> uart_ops->pm -> uart_port->pm
On tty file closing:
uart_close -> uart_change_pm(3) -> uart_ops->pm -> uart_port->pm

And I checked the PM implementation, most of the drivers will enable/disable the "HOST" side port clock there and only few of them will lower the required terminal lines to tell the target devices to enter a low power state. So I was just thinking if the tty device was used as physical device in the community, it might be used as "host" side physical device, and my patch was trying to enable a "target" side physical device.

Adding driver support for such "target physical uart device" sounds a good idea. But I need an explicit approval for adding the kernel resident driver.

Best regards
-Lv

#32 lore raw

Re: [RFC PATCH v3 1/4] UART: Add UART subsystem as a bus.

Quoted 3 lines
Quoted 1 line

ls /sys/class/tty/

I'm searching for a target "physical" device while the "tty device" looks more like a "functional" device.

We don't currently properly link that up - but we should. It does however provide the place to attach information like modem lines and intended use.

Quoted 2 lines

If this rule is strictly obeyed by all of the subsystems, then:
1. the hardware PM can be added to the physical devices

To get the heirarchy you need to the tty to be in the PCI bus or other bus where it actually sits ? Consider an ACPI enumerated port whose address space is behind a PCI bridge.

Quoted 1 line

1. if a bus offered PM support, it should appear in the bus_type

Which would usually be the PCI bus (and an ACPI enumerated device behind a PCI bus needs to go via PCI to keep all the PCI counts correct)

Quoted 3 lines

If a device was handling hardware stuff including the PM, it should be a "physical device". If a device was offering communication means, it should be a "functional device". If a device was using the communication means, it should be a "filter device".

A tty is all three. We have the physical device (wires and pins), the functional object (an open tty) and filters (line disciplines I guess).

Quoted 1 line

And I checked the PM implementation, most of the drivers will enable/disable the "HOST" side port clock there and only few of them will lower the required terminal lines to tell the target devices to enter a low power state.

Because generally that breaks stuff. For example if you lower the carrier to some UPS devices they conclude the PC has been turned off. This leads to highly undesirable behaviour. As a result it's generally been user space that handles such details.

Quoted 3 lines

So I was just thinking if the tty device was used as physical device in the community, it might be used as "host" side physical device, and my patch was trying to enable a "target" side physical device.

Adding driver support for such "target physical uart device" sounds a good idea. But I need an explicit approval for

adding the kernel resident driver.

Not entirely sure what you mean by kernel resident driver here.

As of 3.7 we have a 'tty_port' for every tty. Not every port corresponds to an actual physical device (eg pty doesn't, nor do mux channels). We could certainly keep a bus driver reference in the tty_port if it helps. If NULL means "none/not set" we can also gradually make drivers set it correctly.

At that point you would be able to find the underlying device from any tty port, and you can find any tty_port from the tty as of 3.7.

author
#33 lore raw

RFC PATCH v3 2/4 ACPI / UART: Add ACPI enumeration support for UART bus.

In reply to Lv Zheng

ACPI 5.0 specification introduces the methods of enumerating the target devices connected on the serial buses.
This patch follows the specification, implementing such UART enumeration machanism for the Linux.

In order to use this UART device enumeration mechanism, driver writers are required to call the following APIs:
1. APIs called _after_ the creation of the uart ports:
adap = acpi_uart_register_devices(adap, parent, driver, line); Where:
driver: the low level UART driver
parent: the physical device of the UART ports
adap: the management list of the target devices, can be set as NULL
line: the line number of the target device
2. APIs called _before_ the deletion of the uart ports:
acpi_uart_unregister_devices(adap);
Where:
adap: the management list of the UART target devices

NOTE: If the driver writer has already created the management list for
the UART target devices, the adap parameter can be set to the already created non-NULL value.
NOTE: The ACPI 5.0 specification assumes one physical device per-port.
In this situation, the line parameter might be set to 0 when the acpi_uart_register_devices() is called.
This patch set can also support the multi-port UART adapters, where the line should be set as ACPI_UART_LINE_UNKNOWN.

The test result of ACPI bindings:
kobject sysfs links:

# ls -l /sys/bus/acpi/INTF001:00/
physical_node -> ../../../../pnp0/00:00
physical_node1 -> ../../../../platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00/
firmware_node -> ../../../LNXSYSTM:00/device:00/INTF000:00/INTF001:00
---
 drivers/acpi/Kconfig            |    7 ++
 drivers/acpi/Makefile           |    1 +
 drivers/acpi/acpi_uart.c        |  263 +++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/serial_bus.c |    1 +
 include/linux/acpi_uart.h       |   40 ++++++
 include/linux/serial_bus.h      |    2 +
 6 files changed, 314 insertions(+)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 include/linux/acpi_uart.h
drivers/acpi/Kconfig +7 -0
index 0300bf6..404df82 100644
@@ -187,6 +187,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate SERIAL_BUS
+	depends on SERIAL_BUS
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
@@ -200,6 +206,7 @@ config ACPI_PROCESSOR
 
 	  To compile this driver as a module, choose M here:
 	  the module will be called processor.
+
 config ACPI_IPMI
 	tristate "IPMI"
 	depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER
drivers/acpi/Makefile +1 -0
index 2a4502b..784f332 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +263 -0

263 lines not on this page · raw message

drivers/tty/serial/serial_bus.c +1 -0
index ddb5341..66c112d 100644
@@ -281,6 +281,7 @@ struct uart_device *uart_register_device(struct klist *adap,
 	udev->dev.parent = dev;
 	udev->dev.bus = &uart_bus_type;
 	udev->dev.type = &uart_device_type;
+	ACPI_HANDLE_SET(&udev->dev, info->acpi_node.handle);
 
 	tty = uart_tty_find(drv, info->line, dev);
 	if (!tty) {
include/linux/acpi_uart.h new file +40 -0
new file mode 100644
index 0000000..a928425
@@ -0,0 +1,40 @@
+/*
+ * acpi_uart.h - ACPI UART enumeration support
+ *
+ * Copyright (c) 2012, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _LINUX_ACPI_UART_H
+#define _LINUX_ACPI_UART_H
+
+struct uart_driver;
+
+#define ACPI_UART_LINE_UNKNOWN	((unsigned int)-1)
+
+#if IS_ENABLED(CONFIG_ACPI_UART)
+struct klist *acpi_uart_register_devices(struct klist *adap,
+					 struct device *parent,
+					 struct tty_driver *drv,
+					 unsigned int line);
+void acpi_uart_unregister_devices(struct klist *adap);
+#else
+static inline struct klist *acpi_uart_register_devices(struct klist *adap,
+						       struct device *parent,
+						       struct tty_driver *drv,
+						       unsigned int line)
+{
+	return NULL;
+}
+
+static inline void acpi_uart_unregister_devices(struct klist *adap)
+{
+}
+#endif
+
+#endif /* _LINUX_ACPI_UART_H */
include/linux/serial_bus.h +2 -0
index d8b56ae..1955d3e 100644
@@ -34,6 +34,7 @@ struct uart_device;
  * @irq: stored in uart_device.irq
  * @platform_data: stored in uart_device.dev.platform_data
  * @archdata: copied into uart_device.dev.archdata
+ * @acpi_node: ACPI device node
  *
  * uart_board_info is used to build tables of information listing UART
  * devices that are present. This information is used to grow the driver
@@ -50,6 +51,7 @@ struct uart_board_info {
 	int irq;
 	void *platform_data;
 	struct dev_archdata *archdata;
+	struct acpi_dev_node acpi_node;
 };
 
 extern struct bus_type uart_bus_type;
Signature · 1 line
1.7.10
author
#34 lore raw

RFC PATCH v3 3/4 UART / 8250: Add declearation of serial8250 driver.

In reply to Lv Zheng

Export serial8250 uart driver for uart bus enumerator users.

---
 drivers/tty/serial/8250/8250.c |    5 ++---
 include/linux/serial_8250.h    |    2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/tty/serial/8250/8250.c +2 -3
index 3ba4234..af78374 100644
@@ -56,8 +56,6 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
 static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 
-static struct uart_driver serial8250_reg;
-
 static int serial_index(struct uart_port *port)
 {
 	return (serial8250_reg.minor - 64) + port->line;
@@ -2902,7 +2900,7 @@ int serial8250_find_port(struct uart_port *p)
 #define SERIAL8250_CONSOLE	NULL
 #endif
 
-static struct uart_driver serial8250_reg = {
+struct uart_driver serial8250_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "serial",
 	.dev_name		= "ttyS",
@@ -2910,6 +2908,7 @@ static struct uart_driver serial8250_reg = {
 	.minor			= 64,
 	.cons			= SERIAL8250_CONSOLE,
 };
+EXPORT_SYMBOL_GPL(serial8250_reg);
 
 /*
  * early_serial_setup - early registration for 8250 ports
include/linux/serial_8250.h +2 -0
index c174c90..687af38 100644
@@ -96,6 +96,8 @@ struct uart_8250_port {
 	void			(*dl_write)(struct uart_8250_port *, int);
 };
 
+extern struct uart_driver serial8250_reg;
+
 int serial8250_register_8250_port(struct uart_8250_port *);
 void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
Signature · 1 line
1.7.10
author
#35 lore raw

RFC PATCH v3 4/4 UART: Add dummy devices to test the enumeration.

In reply to Lv Zheng

This is a test patch that should not be merged to any of the published Linux source tree.

1. The result of the UART dummy target device is as follows:

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/bus/uart/uevent
# echo add > /sys/bus/uart/devices/DUMMY/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/serial8250/DUMMY (uart)
ACTION=add
DEVPATH=/devices/platform/serial8250/DUMMY
DEVTYPE=uart_device
MODALIAS=uart:DUMMY
SEQNUM=1144
SUBSYSTEM=uart

# cat /sys/bus/uart/devices/DUMMY/modalias
uart:DUMMY
# cat /sys/bus/uart/devices/DUMMY/tty_dev
ttyS3
# cat /sys/bus/uart/devices/DUMMY/tty_attrs
115200 8N1 HW SW
# cat /sys/bus/uart/devices/DUMMY/modem_lines
LE:RTS,
# ls -l /sys/bus/uart/devices/
DUMMY -> ../../../devices/platform/serial8250/DUMMY
# ls -l /sys/devices/platform/serial8250/DUMMY/
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS3
# ls -l /sys/devices/platform/serial8250/tty/ttyS3/
target_node -> ../../DUMMY

2. The result of the UART customized DSDT target device is as follows:

The test is based on the following customized DSDT (containing the dummy uart host adapter INTF000 and target device INTF001):
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/bus/uart/uevent
# echo add > /sys/bus/uart/devices/INTF001/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/uart (bus)
ACTION=add
DEVPATH=/bus/uart
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/INTF001:00 (uart)
ACTION=add
DEVPATH=/devices/platform/INTF000:00/INTF001:00
DEVTYPE=uart_device
MODALIAS=uart:INTF001:00
SEQNUM=1144
SUBSYSTEM=uart

# cat /sys/bus/uart/devices/INTF001:00/modalias
uart:INTF001:00
# cat /sys/bus/uart/devices/INTF001:00/tty_dev
ttyS0
# cat /sys/bus/uart/devices/INTF001:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/uart/devices/INTF001:00/modem_lines
LE:RTS,CTS,
# ls -l /sys/bus/uart/devices/
INTF001:00 -> ../../../devices/platform/INTF000:00/INTF001:00
# ls -l /sys/devices/platform/INTF000:00/INTF001:00/
firmware_node -> ../../../LNXSYSTM:00/device:00/INTF000:00/INTF001:00
subsystem -> ../../../../bus/uart
host_node -> ../tty/ttyS0
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0/
target_node -> ../../INTF001:00
# ls -l /sys/bus/acpi/INTF001:00/
physical_node -> ../../../../pnp0/00:00
physical_node1 -> ../../../../platform/INTF000:00/INTF001:00
---
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |   12 ++++
 drivers/tty/serial/8250/8250_dummy.c |  129 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +++
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/serial_bus.c      |   17 +++++
 include/linux/serial_bus.h           |    5 ++
 7 files changed, 175 insertions(+)
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
drivers/acpi/scan.c +1 -0
index 4dd13e4..95c7528 100644
@@ -36,6 +36,7 @@ static const char *dummy_hid = "device";
 static const struct acpi_device_id acpi_platform_device_ids[] = {
 
 	{ "PNP0D40" },
+	{ "INTF000" },
 
 	{ }
 };
drivers/tty/serial/8250/8250.c +12 -0
index af78374..745e05d 100644
@@ -35,6 +35,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/serial_bus.h>
 #include <linux/nmi.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -2986,6 +2987,8 @@ void serial8250_resume_port(int line)
 	uart_resume_port(&serial8250_reg, port);
 }
 
+struct uart_device *uart_dummy;
+
 /*
  * Register a set of serial devices attached to a platform device.  The
  * list is terminated with a zero flags entry, which means we expect
@@ -2996,6 +2999,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 	struct plat_serial8250_port *p = dev->dev.platform_data;
 	struct uart_8250_port uart;
 	int ret, i, irqflag = 0;
+	unsigned int dummy_line;
 
 	memset(&uart, 0, sizeof(uart));
 
@@ -3031,6 +3035,13 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 				p->irq, ret);
 		}
 	}
+
+	dummy_line = serial8250_ports[nr_uarts-1].port.line;
+	pr_info("registering DUMMY at line %d.\n", dummy_line);
+	uart_dummy = uart_register_dummy(&dev->dev,
+					 serial8250_reg.tty_driver,
+					 dummy_line);
+
 	return 0;
 }
 
@@ -3041,6 +3052,7 @@ static int __devexit serial8250_remove(struct platform_device *dev)
 {
 	int i;
 
+	uart_unregister_device(uart_dummy);
 	for (i = 0; i < nr_uarts; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
drivers/tty/serial/8250/8250_dummy.c new file +129 -0

129 lines not on this page · raw message

drivers/tty/serial/8250/Kconfig +10 -0
index f3d283f..3ba480a 100644
@@ -270,6 +270,16 @@ config SERIAL_8250_DW
 	  Selecting this option will enable handling of the extra features
 	  present in the Synopsys DesignWare APB UART.
 
+config SERIAL_8250_DUMMY
+	tristate "Support for dummy ACPI 8250"
+	depends on SERIAL_8250 && ACPI
+	help
+	  Selecting this option will enable a test UART target device DUMMY
+	  under the ISA serial8250 and a test UART host adapter INTF000
+	  as an platform device for the purpose of testing the ACPI UART
+	  enumeration support.
+	  If unsure, say "N" here.
+
 config SERIAL_8250_EM
 	tristate "Support for Emma Mobile intergrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
drivers/tty/serial/8250/Makefile +1 -0
index 108fe7f..fb82aa9 100644
@@ -19,3 +19,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6)		+= 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_FSL)		+= 8250_fsl.o
 obj-$(CONFIG_SERIAL_8250_DW)		+= 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
+obj-$(CONFIG_SERIAL_8250_DUMMY)		+= 8250_dummy.o
drivers/tty/serial/serial_bus.c +17 -0
index 66c112d..033dd37 100644
@@ -393,6 +393,23 @@ void uart_del_adapter(struct klist *adap)
 }
 EXPORT_SYMBOL_GPL(uart_del_adapter);
 
+static struct uart_board_info dummy_target = {
+	.type = "DUMMY",
+	.baud = 115200,
+	.cflag = CS8 | CSTOPB | CRTSCTS,
+	.iflag = (IXON | IXOFF),
+	.mctrl = TIOCM_LE | TIOCM_RTS,
+};
+
+struct uart_device *uart_register_dummy(struct device *dev,
+					struct tty_driver *drv,
+					unsigned int line)
+{
+	dummy_target.line = line;
+	return uart_register_device(NULL, dev, drv, &dummy_target);
+}
+EXPORT_SYMBOL_GPL(uart_register_dummy);
+
 struct bus_type uart_bus_type = {
 	.name		= "uart",
 };
include/linux/serial_bus.h +5 -0
index 1955d3e..7eb74b9 100644
@@ -118,4 +118,9 @@ struct device *uart_tty_find(struct tty_driver *drv, unsigned int line,
 			     struct device *dev);
 void uart_tty_name(struct tty_driver *driver, unsigned int line, char *p);
 
+/* Test dummy device registration */
+struct uart_device *uart_register_dummy(struct device *dev,
+					struct tty_driver *drv,
+					unsigned int line);
+
 #endif /* LINUX_SERIAL_BUS_H */
Signature · 1 line
1.7.10
author
#36 lore raw

v4 cover ACPI/UART: Add ACPI 5.0 enueration support for UART.

In reply to Lv Zheng

ACPI 5.0 specification introduces enumeration support for SPB buses. This patch set adds the UART serial bus enumeration support to Linux using such mechanism.
NOTE: PATCH 3 is a test patch, should not be merged into any published
Linux source tree.
This patch set is based on the tty tree/tty-next branch.

History:
v1:
1. Add "uart" bus subsystem.
2. Add physical UART target device and description (uart_device/uart_board_info).
3. Add logical UART host adapter (klist).
4. Add UART target device attributes (tty_dev/tty_attrs/modem_lines).
5. Create tty_device<->uart_device links (host_node/target_node).
v2.
1. Change UART layer related stuff to non-UART related.
2. Modify the order of the function parameters.
v3:
1. Add comments for the uart_board_info and the uart_device.
2. Add platform_data/archdata support.
3. Add ACPI binding and test the binding.
4. Add SERIAL_BUS kconfig item.
v4
1. Convert "uart" bus into "tty_enum" bus.
2. Convert uart_target_device into tty_slave_device.
3. Convert uart_board_info into tty_board_info.
3. Convert kconfig item SERIAL_BUS into TTY_ENUM.
4. Add automatic device unregister support for slave devices. The new tty_port_unregister_device is for this purpose.
5. Add HID/CID list support.
6. Convert TTY slave device name into ACPI node name.

All of the codes can be tested by the dummy 8250 device.

Lv Zheng (3):
TTY: Add TTY slave enumeration support. ACPI / UART: Add ACPI enumeration support for UART.
UART: Add dummy devices to test the enumeration.

 drivers/acpi/Kconfig                 |    6 +
 drivers/acpi/Makefile                |    1 +
 drivers/acpi/acpi_uart.c             |  215 ++++++++++++++++++++
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/Kconfig                  |    3 +
 drivers/tty/Makefile                 |    1 +
 drivers/tty/serial/8250/8250.c       |    5 +-
 drivers/tty/serial/8250/8250_dummy.c |  103 ++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/Kconfig           |    1 +
 drivers/tty/serial/serial_core.c     |    2 +-
 drivers/tty/tty_enum.c               |  357 ++++++++++++++++++++++++++++++++++
 drivers/tty/tty_port.c               |   42 +++-
 include/linux/mod_devicetable.h      |    6 +
 include/linux/serial_8250.h          |    4 +
 include/linux/serial_core.h          |   12 ++
 include/linux/tty.h                  |  112 +++++++++++
 18 files changed, 875 insertions(+), 7 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
 create mode 100644 drivers/tty/tty_enum.c
Signature · 1 line
1.7.10
author
#37 lore raw

RFC PATCH v4 1/3 TTY: Add TTY slave enumeration support.

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART slave devices known to the platform vendors.
There are the needs in Linux to utilize the benefits:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART slave devices.
In order to send uevent, a device need to be a class device or a bus device. This patch introduces a tty_enum bus since the enumerated slave devices are expected to be physical devices.
When the UART slave devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach), then the device managers can read hardware IDs and the serial configurations from the exported device attributes to match and configure a userspace TTY device driver.
The created slave devices will be automatically unregistered when the associated TTY ports are destructed.

---
 drivers/tty/Kconfig              |    3 +
 drivers/tty/Makefile             |    1 +
 drivers/tty/serial/Kconfig       |    1 +
 drivers/tty/serial/serial_core.c |    2 +-
 drivers/tty/tty_enum.c           |  356 ++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_port.c           |   42 ++++-
 include/linux/mod_devicetable.h  |    6 +
 include/linux/tty.h              |  104 +++++++++++
 8 files changed, 511 insertions(+), 4 deletions(-)
 create mode 100644 drivers/tty/tty_enum.c
drivers/tty/Kconfig +3 -0
index 0ecf22b..e0ef9db 100644
@@ -151,6 +151,9 @@ config LEGACY_PTY_COUNT
 	  When not in use, each legacy PTY occupies 12 bytes on 32-bit
 	  architectures and 24 bytes on 64-bit architectures.
 
+config TTY_ENUM
+	bool
+
 config BFIN_JTAG_COMM
 	tristate "Blackfin JTAG Communication"
 	depends on BLACKFIN
drivers/tty/Makefile +1 -0
index 2953059..f4eb30c 100644
@@ -1,5 +1,6 @@
 obj-y				+= tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
 				   tty_buffer.o tty_port.o tty_mutex.o
+obj-$(CONFIG_TTY_ENUM)		+= tty_enum.o
 obj-$(CONFIG_LEGACY_PTYS)	+= pty.o
 obj-$(CONFIG_UNIX98_PTYS)	+= pty.o
 obj-$(CONFIG_AUDIT)		+= tty_audit.o
drivers/tty/serial/Kconfig +1 -0
index 59c23d0..c3dee46 100644
@@ -751,6 +751,7 @@ config SERIAL_HS_LPC32XX_CONSOLE
 
 config SERIAL_CORE
 	tristate
+	select TTY_ENUM
 
 config SERIAL_CORE_CONSOLE
 	bool
drivers/tty/serial/serial_core.c +1 -1
index 2c7230a..d6cb417 100644
@@ -2662,7 +2662,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 	/*
 	 * Remove the devices from the tty layer
 	 */
-	tty_unregister_device(drv->tty_driver, uport->line);
+	tty_port_unregister_device(port, drv->tty_driver, uport->line);
 
 	if (port->tty)
 		tty_vhangup(port->tty);
drivers/tty/tty_enum.c new file +356 -0

356 lines not on this page · raw message

drivers/tty/tty_port.c +39 -3

65 lines not on this page · raw message

include/linux/mod_devicetable.h +6 -0
index fed3def..f1c4875 100644
@@ -433,6 +433,12 @@ struct rpmsg_device_id {
 	char name[RPMSG_NAME_SIZE];
 };
 
+/* tty */
+
+/* TTY slave name size */
+#define TTY_NAME_SIZE	32
+#define TTY_MODULE_PREFIX "tty:"
+
 /* i2c */
 
 #define I2C_NAME_SIZE	20
include/linux/tty.h +104 -0

134 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#38 lore raw

RFC PATCH v4 1/3 TTY: Add TTY slave enumeration support.

In reply to Lv Zheng

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART slave devices known to the platform vendors.
There are the needs in Linux to utilize the benefits:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART slave devices.
In order to send uevent, a device need to be a class device or a bus device. This patch introduces a tty_enum bus since the enumerated slave devices are expected to be physical devices.
When the UART slave devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach), then the device managers can read hardware IDs and the serial configurations from the exported device attributes to match and configure a userspace TTY device driver.
The created slave devices will be automatically unregistered when the associated TTY ports are destructed.

---
 drivers/tty/Kconfig              |    3 +
 drivers/tty/Makefile             |    1 +
 drivers/tty/serial/Kconfig       |    1 +
 drivers/tty/serial/serial_core.c |    2 +-
 drivers/tty/tty_enum.c           |  356 ++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_port.c           |   42 ++++-
 include/linux/mod_devicetable.h  |    6 +
 include/linux/tty.h              |  104 +++++++++++
 8 files changed, 511 insertions(+), 4 deletions(-)
 create mode 100644 drivers/tty/tty_enum.c
drivers/tty/Kconfig +3 -0
index 0ecf22b..e0ef9db 100644
@@ -151,6 +151,9 @@ config LEGACY_PTY_COUNT
 	  When not in use, each legacy PTY occupies 12 bytes on 32-bit
 	  architectures and 24 bytes on 64-bit architectures.
 
+config TTY_ENUM
+	bool
+
 config BFIN_JTAG_COMM
 	tristate "Blackfin JTAG Communication"
 	depends on BLACKFIN
drivers/tty/Makefile +1 -0
index 2953059..f4eb30c 100644
@@ -1,5 +1,6 @@
 obj-y				+= tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
 				   tty_buffer.o tty_port.o tty_mutex.o
+obj-$(CONFIG_TTY_ENUM)		+= tty_enum.o
 obj-$(CONFIG_LEGACY_PTYS)	+= pty.o
 obj-$(CONFIG_UNIX98_PTYS)	+= pty.o
 obj-$(CONFIG_AUDIT)		+= tty_audit.o
drivers/tty/serial/Kconfig +1 -0
index 59c23d0..c3dee46 100644
@@ -751,6 +751,7 @@ config SERIAL_HS_LPC32XX_CONSOLE
 
 config SERIAL_CORE
 	tristate
+	select TTY_ENUM
 
 config SERIAL_CORE_CONSOLE
 	bool
drivers/tty/serial/serial_core.c +1 -1
index 2c7230a..d6cb417 100644
@@ -2662,7 +2662,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 	/*
 	 * Remove the devices from the tty layer
 	 */
-	tty_unregister_device(drv->tty_driver, uport->line);
+	tty_port_unregister_device(port, drv->tty_driver, uport->line);
 
 	if (port->tty)
 		tty_vhangup(port->tty);
drivers/tty/tty_enum.c new file +356 -0

356 lines not on this page · raw message

drivers/tty/tty_port.c +39 -3

65 lines not on this page · raw message

include/linux/mod_devicetable.h +6 -0
index fed3def..f1c4875 100644
@@ -433,6 +433,12 @@ struct rpmsg_device_id {
 	char name[RPMSG_NAME_SIZE];
 };
 
+/* tty */
+
+/* TTY slave name size */
+#define TTY_NAME_SIZE	32
+#define TTY_MODULE_PREFIX "tty:"
+
 /* i2c */
 
 #define I2C_NAME_SIZE	20
include/linux/tty.h +104 -0

134 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#39 lore raw

RFC PATCH v4 2/3 ACPI / UART: Add ACPI enumeration support for UART.

In reply to Lv Zheng

ACPI 5.0 specification introduces mechanisms of enumerating the slave devices connected on the serial buses.
This patch follows the specification, implementing such UART enumeration machanism for Linux.
In order to use this UART device enumeration mechanism, driver writers are required to call the following API:
Call acpi_tty_register_devices _after_ the creation of the tty ports:
tty_port_register_device(port, driver, i, parent); acpi_uart_register_devices(port);
Where:
port: the registered tty port.
parent: the physical device of the UART ports.
driver and index: required parameters for tty_port_register_device.
In this patch, only SERIAL_CORE drivers are enabled to use this ACPI UART enumeration mechanism. This can be changed if there are needs updated in the future.

---
 drivers/acpi/Kconfig     |    6 ++
 drivers/acpi/Makefile    |    1 +
 drivers/acpi/acpi_uart.c |  215 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_enum.c   |    1 +
 include/linux/tty.h      |    8 ++
 5 files changed, 231 insertions(+)
 create mode 100644 drivers/acpi/acpi_uart.c
drivers/acpi/Kconfig +6 -0
index 38c5078..98e2d4e 100644
@@ -187,6 +187,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate TTY_ENUM
+	depends on TTY_ENUM
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
drivers/acpi/Makefile +1 -0
index 2a4502b..784f332 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +215 -0

215 lines not on this page · raw message

drivers/tty/tty_enum.c +1 -0
index 2e91cb6..5081dff 100644
@@ -260,6 +260,7 @@ struct tty_slave *tty_bus_register_slave(struct tty_port *port,
 	tts->dev.parent = dev;
 	tts->dev.bus = &tty_enum_bus;
 	tts->dev.type = &tty_slave_type;
+	ACPI_HANDLE_SET(&tts->dev, info->acpi_node.handle);
 
 	tts->dev.platform_data = info->platform_data;
 	if (info->archdata)
include/linux/tty.h +8 -0
index 36eb9d1..c32d16c 100644
@@ -172,6 +172,7 @@ struct tty_board_info;
  * @irq: stored in tty_slave.irq
  * @platform_data: stored in tty_slave.dev.platform_data
  * @archdata: copied into tty_slave.dev.archdata
+ * @acpi_node: ACPI device node
  * @nr_ids: number of IDs
  * @ids: ID strings
  *
@@ -189,6 +190,7 @@ struct tty_board_info {
 	int irq;
 	void *platform_data;
 	struct dev_archdata *archdata;
+	struct acpi_dev_node acpi_node;
 
 	int nr_ids;
 	/* This must be the last member of tty_board_info */
@@ -741,4 +743,10 @@ do {									\
 } while (0)
 
 
+#if IS_ENABLED(CONFIG_ACPI_UART)
+void acpi_uart_register_devices(struct tty_port *port);
+#else
+static inline void acpi_uart_register_devices(struct tty_port *port) {}
+#endif
+
 #endif
Signature · 1 line
1.7.10
author
#40 lore raw

RFC PATCH v4 2/3 ACPI / UART: Add ACPI enumeration support for UART.

In reply to Lv Zheng

ACPI 5.0 specification introduces mechanisms of enumerating the slave devices connected on the serial buses.
This patch follows the specification, implementing such UART enumeration machanism for Linux.
In order to use this UART device enumeration mechanism, driver writers are required to call the following API:
Call acpi_tty_register_devices _after_ the creation of the tty ports:
tty_port_register_device(port, driver, i, parent); acpi_uart_register_devices(port);
Where:
port: the registered tty port.
parent: the physical device of the UART ports.
driver and index: required parameters for tty_port_register_device.
In this patch, only SERIAL_CORE drivers are enabled to use this ACPI UART enumeration mechanism. This can be changed if there are needs updated in the future.

---
 drivers/acpi/Kconfig     |    6 ++
 drivers/acpi/Makefile    |    1 +
 drivers/acpi/acpi_uart.c |  215 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_enum.c   |    1 +
 include/linux/tty.h      |    8 ++
 5 files changed, 231 insertions(+)
 create mode 100644 drivers/acpi/acpi_uart.c
drivers/acpi/Kconfig +6 -0
index 38c5078..98e2d4e 100644
@@ -187,6 +187,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate TTY_ENUM
+	depends on TTY_ENUM
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
drivers/acpi/Makefile +1 -0
index 2a4502b..784f332 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +215 -0

215 lines not on this page · raw message

drivers/tty/tty_enum.c +1 -0
index 2e91cb6..5081dff 100644
@@ -260,6 +260,7 @@ struct tty_slave *tty_bus_register_slave(struct tty_port *port,
 	tts->dev.parent = dev;
 	tts->dev.bus = &tty_enum_bus;
 	tts->dev.type = &tty_slave_type;
+	ACPI_HANDLE_SET(&tts->dev, info->acpi_node.handle);
 
 	tts->dev.platform_data = info->platform_data;
 	if (info->archdata)
include/linux/tty.h +8 -0
index 36eb9d1..c32d16c 100644
@@ -172,6 +172,7 @@ struct tty_board_info;
  * @irq: stored in tty_slave.irq
  * @platform_data: stored in tty_slave.dev.platform_data
  * @archdata: copied into tty_slave.dev.archdata
+ * @acpi_node: ACPI device node
  * @nr_ids: number of IDs
  * @ids: ID strings
  *
@@ -189,6 +190,7 @@ struct tty_board_info {
 	int irq;
 	void *platform_data;
 	struct dev_archdata *archdata;
+	struct acpi_dev_node acpi_node;
 
 	int nr_ids;
 	/* This must be the last member of tty_board_info */
@@ -741,4 +743,10 @@ do {									\
 } while (0)
 
 
+#if IS_ENABLED(CONFIG_ACPI_UART)
+void acpi_uart_register_devices(struct tty_port *port);
+#else
+static inline void acpi_uart_register_devices(struct tty_port *port) {}
+#endif
+
 #endif
Signature · 1 line
1.7.10
author
#41 lore raw

RFC PATCH v4 3/3 UART: Add dummy devices to test the enumeration.

In reply to Lv Zheng

This is a test patch that should not be merged into any of the published Linux source tree.

The test is based on the following customized DSDT (containing the dummy uart host adapter INTF000 and target device INTF001):

1. customized DSDT:
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Name (_CID, "PNPF001")  // _CID: Compatible ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

2. uevent monitor:

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/class/tty/uevent
# echo add > /sys/class/tty/devices/BTH0:00/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/tty_enum (bus)
ACTION=add
DEVPATH=/bus/tty_enum
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/tty/ttyS0/BTH0:00 (tty)
ACTION=add DEVPATH=/devices/platform/INTF000:00/tty/ttyS0/BTH0:00 DEVTYPE=tty_slave MODALIAS=tty::INTF001:PNPF001:
SEQNUM=1144
SUBSYSTEM=tty

3. kobjects attributes and links:

# cat /sys/bus/tty_enum/devices/BTH0:00/modalias
tty::INTF001:PNPF001:
# cat /sys/bus/tty_enum/devices/BTH0:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/tty_enum/devices/BTH0:00/modem_lines
LE:RTS,CTS,
# ls -l /sys/bus/tty_enum/devices/
BTH0:00 -> ../../../devices/platform/INTF000:00/tty/ttyS0/tty/BTH0:00
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0/BTH0:00/
firmware_node -> ../../../../../LNXSYSTM:00/device:00/INTF000:00/INTF001:00
subsystem -> ../../../../../../bus/tty_enum
# ls -l /sys/bus/acpi/devices/INTF001:00/
physical_node -> ../../../../pnp0/00:00
physical_node1 -> ../../../../platform/INTF000:00/tty/ttyS0/BTH0:00
---
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |    5 +-
 drivers/tty/serial/8250/8250_dummy.c |  103 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 ++++
 drivers/tty/serial/8250/Makefile     |    1 +
 include/linux/serial_8250.h          |    4 ++
 include/linux/serial_core.h          |   12 ++++
 7 files changed, 133 insertions(+), 3 deletions(-)
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
drivers/acpi/scan.c +1 -0
index 53502d1..56611f3 100644
@@ -36,6 +36,7 @@ static const char *dummy_hid = "device";
 static const struct acpi_device_id acpi_platform_device_ids[] = {
 
 	{ "PNP0D40" },
+	{ "INTF000" },
 
 	/* Haswell LPSS devices */
 	{ "INT33C0", 0 },
drivers/tty/serial/8250/8250.c +2 -3
index d085e3a..32dfad4 100644
@@ -56,8 +56,6 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
 static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 
-static struct uart_driver serial8250_reg;
-
 static int serial_index(struct uart_port *port)
 {
 	return (serial8250_reg.minor - 64) + port->line;
@@ -2978,7 +2976,7 @@ int serial8250_find_port(struct uart_port *p)
 #define SERIAL8250_CONSOLE	NULL
 #endif
 
-static struct uart_driver serial8250_reg = {
+struct uart_driver serial8250_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "serial",
 	.dev_name		= "ttyS",
@@ -2986,6 +2984,7 @@ static struct uart_driver serial8250_reg = {
 	.minor			= 64,
 	.cons			= SERIAL8250_CONSOLE,
 };
+EXPORT_SYMBOL_GPL(serial8250_reg);
 
 /*
  * early_serial_setup - early registration for 8250 ports
drivers/tty/serial/8250/8250_dummy.c new file +103 -0

103 lines not on this page · raw message

drivers/tty/serial/8250/Kconfig +10 -0
index c31133a..3f04247 100644
@@ -270,6 +270,16 @@ config SERIAL_8250_DW
 	  Selecting this option will enable handling of the extra features
 	  present in the Synopsys DesignWare APB UART.
 
+config SERIAL_8250_DUMMY
+	tristate "Support for dummy ACPI 8250"
+	depends on SERIAL_8250 && ACPI
+	help
+	  Selecting this option will enable a test UART target device DUMMY
+	  under the ISA serial8250 and a test UART host adapter INTF000
+	  as an platform device for the purpose of testing the ACPI UART
+	  enumeration support.
+	  If unsure, say "N" here.
+
 config SERIAL_8250_EM
 	tristate "Support for Emma Mobile integrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
drivers/tty/serial/8250/Makefile +1 -0
index 108fe7f..fb82aa9 100644
@@ -19,3 +19,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6)		+= 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_FSL)		+= 8250_fsl.o
 obj-$(CONFIG_SERIAL_8250_DW)		+= 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
+obj-$(CONFIG_SERIAL_8250_DUMMY)		+= 8250_dummy.o
include/linux/serial_8250.h +4 -0
index c490d20..c7aef78 100644
@@ -96,6 +96,10 @@ struct uart_8250_port {
 	void			(*dl_write)(struct uart_8250_port *, int);
 };
 
+extern struct uart_driver serial8250_reg;
+
+#define serial8250_tty_port(line)	uart_tty_port(&serial8250_reg, (line))
+
 int serial8250_register_8250_port(struct uart_8250_port *);
 void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
include/linux/serial_core.h +12 -0
index c6690a2..59f8582 100644
@@ -246,6 +246,18 @@ struct uart_driver {
 	struct tty_driver	*tty_driver;
 };
 
+static inline struct tty_port *uart_tty_port(struct uart_driver *drv,
+					     unsigned int line)
+{
+	struct uart_state *state;
+
+	if (line >= drv->nr)
+		return NULL;
+
+	state = drv->state + line;
+	return &state->port;
+}
+
 void uart_write_wakeup(struct uart_port *port);
 
 /*
Signature · 1 line
1.7.10
author
#42 lore raw

RFC PATCH v4 3/3 UART: Add dummy devices to test the enumeration.

In reply to Lv Zheng

This is a test patch that should not be merged into any of the published Linux source tree.

The test is based on the following customized DSDT (containing the dummy uart host adapter INTF000 and target device INTF001):

1. customized DSDT:
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Name (_CID, "PNPF001")  // _CID: Compatible ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

2. uevent monitor:

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/class/tty/uevent
# echo add > /sys/class/tty/devices/BTH0:00/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/tty_enum (bus)
ACTION=add
DEVPATH=/bus/tty_enum
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/tty/ttyS0/BTH0:00 (tty)
ACTION=add DEVPATH=/devices/platform/INTF000:00/tty/ttyS0/BTH0:00 DEVTYPE=tty_slave MODALIAS=tty::INTF001:PNPF001:
SEQNUM=1144
SUBSYSTEM=tty

3. kobjects attributes and links:

# cat /sys/bus/tty_enum/devices/BTH0:00/modalias
tty::INTF001:PNPF001:
# cat /sys/bus/tty_enum/devices/BTH0:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/tty_enum/devices/BTH0:00/modem_lines
LE:RTS,CTS,
# ls -l /sys/bus/tty_enum/devices/
BTH0:00 -> ../../../devices/platform/INTF000:00/tty/ttyS0/tty/BTH0:00
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0/BTH0:00/
firmware_node -> ../../../../../LNXSYSTM:00/device:00/INTF000:00/INTF001:00
subsystem -> ../../../../../../bus/tty_enum
# ls -l /sys/bus/acpi/devices/INTF001:00/
physical_node -> ../../../../pnp0/00:00
physical_node1 -> ../../../../platform/INTF000:00/tty/ttyS0/BTH0:00
---
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |    5 +-
 drivers/tty/serial/8250/8250_dummy.c |  103 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 ++++
 drivers/tty/serial/8250/Makefile     |    1 +
 include/linux/serial_8250.h          |    4 ++
 include/linux/serial_core.h          |   12 ++++
 7 files changed, 133 insertions(+), 3 deletions(-)
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
drivers/acpi/scan.c +1 -0
index 53502d1..56611f3 100644
@@ -36,6 +36,7 @@ static const char *dummy_hid = "device";
 static const struct acpi_device_id acpi_platform_device_ids[] = {
 
 	{ "PNP0D40" },
+	{ "INTF000" },
 
 	/* Haswell LPSS devices */
 	{ "INT33C0", 0 },
drivers/tty/serial/8250/8250.c +2 -3
index d085e3a..32dfad4 100644
@@ -56,8 +56,6 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
 static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 
-static struct uart_driver serial8250_reg;
-
 static int serial_index(struct uart_port *port)
 {
 	return (serial8250_reg.minor - 64) + port->line;
@@ -2978,7 +2976,7 @@ int serial8250_find_port(struct uart_port *p)
 #define SERIAL8250_CONSOLE	NULL
 #endif
 
-static struct uart_driver serial8250_reg = {
+struct uart_driver serial8250_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "serial",
 	.dev_name		= "ttyS",
@@ -2986,6 +2984,7 @@ static struct uart_driver serial8250_reg = {
 	.minor			= 64,
 	.cons			= SERIAL8250_CONSOLE,
 };
+EXPORT_SYMBOL_GPL(serial8250_reg);
 
 /*
  * early_serial_setup - early registration for 8250 ports
drivers/tty/serial/8250/8250_dummy.c new file +103 -0

103 lines not on this page · raw message

drivers/tty/serial/8250/Kconfig +10 -0
index c31133a..3f04247 100644
@@ -270,6 +270,16 @@ config SERIAL_8250_DW
 	  Selecting this option will enable handling of the extra features
 	  present in the Synopsys DesignWare APB UART.
 
+config SERIAL_8250_DUMMY
+	tristate "Support for dummy ACPI 8250"
+	depends on SERIAL_8250 && ACPI
+	help
+	  Selecting this option will enable a test UART target device DUMMY
+	  under the ISA serial8250 and a test UART host adapter INTF000
+	  as an platform device for the purpose of testing the ACPI UART
+	  enumeration support.
+	  If unsure, say "N" here.
+
 config SERIAL_8250_EM
 	tristate "Support for Emma Mobile integrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
drivers/tty/serial/8250/Makefile +1 -0
index 108fe7f..fb82aa9 100644
@@ -19,3 +19,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6)		+= 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_FSL)		+= 8250_fsl.o
 obj-$(CONFIG_SERIAL_8250_DW)		+= 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
+obj-$(CONFIG_SERIAL_8250_DUMMY)		+= 8250_dummy.o
include/linux/serial_8250.h +4 -0
index c490d20..c7aef78 100644
@@ -96,6 +96,10 @@ struct uart_8250_port {
 	void			(*dl_write)(struct uart_8250_port *, int);
 };
 
+extern struct uart_driver serial8250_reg;
+
+#define serial8250_tty_port(line)	uart_tty_port(&serial8250_reg, (line))
+
 int serial8250_register_8250_port(struct uart_8250_port *);
 void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
include/linux/serial_core.h +12 -0
index c6690a2..59f8582 100644
@@ -246,6 +246,18 @@ struct uart_driver {
 	struct tty_driver	*tty_driver;
 };
 
+static inline struct tty_port *uart_tty_port(struct uart_driver *drv,
+					     unsigned int line)
+{
+	struct uart_state *state;
+
+	if (line >= drv->nr)
+		return NULL;
+
+	state = drv->state + line;
+	return &state->port;
+}
+
 void uart_write_wakeup(struct uart_port *port);
 
 /*
Signature · 1 line
1.7.10
author
#43 lore raw

v4 cover ACPI/UART: Add ACPI 5.0 enueration support for UART.

In reply to Lv Zheng

ACPI 5.0 specification introduces enumeration support for SPB buses. This patch set adds the UART serial bus enumeration support to Linux using such mechanism.
NOTE: PATCH 3 is a test patch, should not be merged into any published
Linux source tree.
This patch set is based on the tty tree/tty-next branch.

History:
v1:
1. Add "uart" bus subsystem.
2. Add physical UART target device and description (uart_device/uart_board_info).
3. Add logical UART host adapter (klist).
4. Add UART target device attributes (tty_dev/tty_attrs/modem_lines).
5. Create tty_device<->uart_device links (host_node/target_node).
v2.
1. Change UART layer related stuff to non-UART related.
2. Modify the order of the function parameters.
v3:
1. Add comments for the uart_board_info and the uart_device.
2. Add platform_data/archdata support.
3. Add ACPI binding and test the binding.
4. Add SERIAL_BUS kconfig item.
v4
1. Convert "uart" bus into "tty_enum" bus.
2. Convert uart_target_device into tty_slave_device.
3. Convert uart_board_info into tty_board_info.
3. Convert kconfig item SERIAL_BUS into TTY_ENUM.
4. Add automatic device unregister support for slave devices. The new tty_port_unregister_device is for this purpose.
5. Add HID/CID list support.
6. Convert TTY slave device name into ACPI node name.

All of the codes can be tested by the dummy 8250 device.

Lv Zheng (3):
TTY: Add TTY slave enumeration support. ACPI / UART: Add ACPI enumeration support for UART.
UART: Add dummy devices to test the enumeration.

 drivers/acpi/Kconfig                 |    6 +
 drivers/acpi/Makefile                |    1 +
 drivers/acpi/acpi_uart.c             |  215 ++++++++++++++++++++
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/Kconfig                  |    3 +
 drivers/tty/Makefile                 |    1 +
 drivers/tty/serial/8250/8250.c       |    5 +-
 drivers/tty/serial/8250/8250_dummy.c |  103 ++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 +
 drivers/tty/serial/8250/Makefile     |    1 +
 drivers/tty/serial/Kconfig           |    1 +
 drivers/tty/serial/serial_core.c     |    2 +-
 drivers/tty/tty_enum.c               |  357 ++++++++++++++++++++++++++++++++++
 drivers/tty/tty_port.c               |   42 +++-
 include/linux/mod_devicetable.h      |    6 +
 include/linux/serial_8250.h          |    4 +
 include/linux/serial_core.h          |   12 ++
 include/linux/tty.h                  |  112 +++++++++++
 18 files changed, 875 insertions(+), 7 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
 create mode 100644 drivers/tty/tty_enum.c
Signature · 1 line
1.7.10
author
#44 lore raw

v5 cover ACPI/UART: Add ACPI 5.0 enumeration support for UART

In reply to Lv Zheng

ACPI 5.0 specification introduces enumeration support for SPB buses. This patch set adds the UART serial bus enumeration support to Linux using such mechanism.
This patch set is based on the tty tree/tty-next branch.

History:
v1:
1. Add "uart" bus subsystem.
2. Add physical UART target device and description (uart_device/uart_board_info).
3. Add logical UART host adapter (klist).
4. Add UART target device attributes (tty_dev/tty_attrs/modem_lines).
5. Create tty_device<->uart_device links (host_node/target_node).
v2.
1. Change UART layer related stuff to non-UART related.
2. Modify the order of the function parameters.
v3:
1. Add comments for the uart_board_info and the uart_device.
2. Add platform_data/archdata support.
3. Add ACPI binding and test the binding (in seperate patch).
4. Add SERIAL_BUS kconfig item.
v4
1. Convert "uart" bus into "tty_enum" bus.
2. Convert uart_target_device into tty_slave_device.
3. Convert uart_board_info into tty_board_info.
3. Convert kconfig item SERIAL_BUS into TTY_ENUM.
4. Add automatic device unregister support for slave devices. The new tty_port_unregister_device is for this purpose.
5. Add HID/CID list support.
6. Convert TTY slave device name into ACPI node name.
v5
1. Add missing static reported by recent kernel build test.

Lv Zheng (2):
TTY: Add TTY slave enumeration support ACPI / UART: Add ACPI enumeration support for UART

 drivers/acpi/Kconfig             |    6 +
 drivers/acpi/Makefile            |    1 +
 drivers/acpi/acpi_uart.c         |  215 +++++++++++++++++++++++
 drivers/tty/Kconfig              |    3 +
 drivers/tty/Makefile             |    1 +
 drivers/tty/serial/Kconfig       |    1 +
 drivers/tty/serial/serial_core.c |    2 +-
 drivers/tty/tty_enum.c           |  357 ++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_port.c           |   42 ++++-
 include/linux/mod_devicetable.h  |    6 +
 include/linux/tty.h              |  112 ++++++++++++
 11 files changed, 742 insertions(+), 4 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
 create mode 100644 drivers/tty/tty_enum.c
Signature · 1 line
1.7.10
author
#45 lore raw

PATCH v5 1/2 TTY: Add TTY slave enumeration support

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART slave devices known to the platform vendors.
There are the needs in Linux to utilize the benefits:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART slave devices.
In order to send uevent, a device need to be a class device or a bus device. This patch introduces a tty_enum bus since the enumerated slave devices are expected to be physical devices.
When the UART slave devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach), then the device managers can read hardware IDs and the serial configurations from the exported device attributes to match and configure a userspace TTY device driver.
The created slave devices will be automatically unregistered when the associated TTY ports are destructed.

---
History:
v5
1. Build/boot test of this patch relies on Fengguang's 0-day kernel tests.

---
 drivers/tty/Kconfig              |    3 +
 drivers/tty/Makefile             |    1 +
 drivers/tty/serial/Kconfig       |    1 +
 drivers/tty/serial/serial_core.c |    2 +-
 drivers/tty/tty_enum.c           |  356 ++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_port.c           |   42 ++++-
 include/linux/mod_devicetable.h  |    6 +
 include/linux/tty.h              |  104 +++++++++++
 8 files changed, 511 insertions(+), 4 deletions(-)
 create mode 100644 drivers/tty/tty_enum.c
drivers/tty/Kconfig +3 -0
index 29dfc24..c0c8dd5 100644
@@ -162,6 +162,9 @@ config LEGACY_PTY_COUNT
 	  When not in use, each legacy PTY occupies 12 bytes on 32-bit
 	  architectures and 24 bytes on 64-bit architectures.
 
+config TTY_ENUM
+	bool
+
 config BFIN_JTAG_COMM
 	tristate "Blackfin JTAG Communication"
 	depends on BLACKFIN
drivers/tty/Makefile +1 -0
index 35649d3..ce7b340 100644
@@ -1,5 +1,6 @@
 obj-$(CONFIG_TTY)		+= tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
 				   tty_buffer.o tty_port.o tty_mutex.o
+obj-$(CONFIG_TTY_ENUM)		+= tty_enum.o
 obj-$(CONFIG_LEGACY_PTYS)	+= pty.o
 obj-$(CONFIG_UNIX98_PTYS)	+= pty.o
 obj-$(CONFIG_AUDIT)		+= tty_audit.o
drivers/tty/serial/Kconfig +1 -0
index e9aeccd..b269dab 100644
@@ -764,6 +764,7 @@ config SERIAL_HS_LPC32XX_CONSOLE
 
 config SERIAL_CORE
 	tristate
+	select TTY_ENUM
 
 config SERIAL_CORE_CONSOLE
 	bool
drivers/tty/serial/serial_core.c +1 -1
index ca98a3f..94ae5e1 100644
@@ -2669,7 +2669,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 	/*
 	 * Remove the devices from the tty layer
 	 */
-	tty_unregister_device(drv->tty_driver, uport->line);
+	tty_port_unregister_device(port, drv->tty_driver, uport->line);
 
 	if (port->tty)
 		tty_vhangup(port->tty);
drivers/tty/tty_enum.c new file +356 -0

356 lines not on this page · raw message

drivers/tty/tty_port.c +39 -3

65 lines not on this page · raw message

include/linux/mod_devicetable.h +6 -0
index fed3def..f1c4875 100644
@@ -433,6 +433,12 @@ struct rpmsg_device_id {
 	char name[RPMSG_NAME_SIZE];
 };
 
+/* tty */
+
+/* TTY slave name size */
+#define TTY_NAME_SIZE	32
+#define TTY_MODULE_PREFIX "tty:"
+
 /* i2c */
 
 #define I2C_NAME_SIZE	20
include/linux/tty.h +104 -0

134 lines not on this page · raw message

Signature · 1 line
1.7.10
#46 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 10 lines · Lv Zheng

In the recent ACPI 5.0 specification updates, firmwares are provided the possibilities to enumerate the UART slave devices known to the platform vendors.
There are the needs in Linux to utilize the benefits:
1. hotplug uevent
2. serial configuration
Currently, only serial cards on the specific bus (ex. PCMCIA) can be enumerated and userspace can obtain the hotplug event of the UART target devices. Linux kernel is lack of an overall enumeration mechanism for UART slave devices.

Huh? That's flat out not true, otherwise how would userspace be creating the proper /dev/tty* nodes for all tty devices?

Quoted 3 lines

In order to send uevent, a device need to be a class device or a bus device. This patch introduces a tty_enum bus since the enumerated slave devices are expected to be physical devices.

Again, tty devices are already class devices, and they send out uevents. You can see this today by watching the uevent stream using a tool like 'udevadmin monitor'.

Quoted 5 lines

When the UART slave devices are created, userspace uevent rules can pass the creation details to the userspace driver managers (ex. hciattach), then the device managers can read hardware IDs and the serial configurations from the exported device attributes to match and configure a userspace TTY device driver.

What? We do that today, no kernel changes needed.

Quoted 2 lines

The created slave devices will be automatically unregistered when the associated TTY ports are destructed.

Again, this happens today.

Or am I missing something big and major here? How have people been seeing and configuring their tty devices for the last 8+ years or so since the 2.6.0 kernel was released with uevent support for tty devices?

lost,

greg k-h

#47 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 4 lines

Or am I missing something big and major here? How have people been seeing and configuring their tty devices for the last 8+ years or so since the 2.6.0 kernel was released with uevent support for tty devices?

Minor more than major. The newer ACPI tries to begin to describe what is on the other end of serial busses being used for internal purposes.

Now there are several good reasons we want to know what is on the end of a port already that are not currently handled, and I have suggested a port "type" attribute would be useful (eg unknown, modem, bluetooth, ax25, dcc, etc) so the kernel can help user space enumerate in user friendly fashion.

Where it gets slightly more tricky is that we are beginning to see systems where the firmware is describing

serial port (and power management)
device behind port (and power management)

so there is a power management hierarchy involved.

But yes - these patches should have been labelled 'RFC' - the concept needs discussion in public not the current code drafts.

Alan

#48 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 5 lines · Alan Cox
Quoted 4 lines

Or am I missing something big and major here? How have people been seeing and configuring their tty devices for the last 8+ years or so since the 2.6.0 kernel was released with uevent support for tty devices?

Quoted 8 lines

Minor more than major. The newer ACPI tries to begin to describe what is on the other end of serial busses being used for internal purposes.

Now there are several good reasons we want to know what is on the end of a port already that are not currently handled, and I have suggested a port "type" attribute would be useful (eg unknown, modem, bluetooth, ax25, dcc, etc) so the kernel can help user space enumerate in user friendly fashion.

That's fine, just add a single attribute to the existing tty class device, not a whole new class, which is what this code does.

Quoted 7 lines

Where it gets slightly more tricky is that we are beginning to see systems where the firmware is describing

serial port (and power management)
device behind port (and power management)

so there is a power management hierarchy involved.

Ick, that's going to get messy fast. There's no hope they would switch to a USB connection instead for these devices, could they? That would fix up most of these issues, and make the devices discoverable.

thanks,

greg k-h

author
#49 lore raw

RE: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

In reply to Greg Kroah-Hartman

Thanks for your suggestions.
All your concerns are against the needs of creating such slave devices. Let me delete all of the others and reply once.

Quoted 7 lines
Quoted 3 lines

In order to send uevent, a device need to be a class device or a bus device. This patch introduces a tty_enum bus since the enumerated slave devices are expected to be physical devices.

Again, tty devices are already class devices, and they send out uevents. You can see this today by watching the uevent stream using a tool like 'udevadmin monitor'.

Please consider the following real scenario when a ttyS0 driver module gets loaded at kernel runtime:
1. the tty controller driver creates ttyS0
2. user gets uevent notified and doesn't know how to use this tty device
3. a slave ACPI node under the ttyS0 gets enumerated and attributes gets appended
4. user need to do user space effort to regenerate the uevent to get a Bluetooth hci user driver matched

If the step 3 can be put ahead of step 2, there might not be weakness without this enhancement. Considering a more complex scenario:
There are two or more target devices under the ttyS0 and can be selected by some external GPIOs. Actually, BIOS will do this putting many test devices under the ttyS0.
The step 3 then can never be put ahead of step 2.
(It might be implemented using some exist kernel mechanisms like the SCSI contribute container devices...)

With this patch:
1. a tty controller driver creates ttyS0
2. user gets the uevent notified and need to do nothing
3. a slave device BTH0:00 gets enumerated and created
4. user gets the uevent notified and uses the attributes exported by this device to do a proper Bluetooth hci user driver matching
The latter is more generic which is equivalent to the exist PCMCIA Bluetooth hci matching. And I just think we could get more benefits when we do PM enabling for such uart slave devices. And I think this patch would not change any currently used user space behavior.
But the user space behavior can be unified if such slave device nodes are there.

Best regards
-Lv

#50 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 8 lines · Lv

Thanks for your suggestions.
All your concerns are against the needs of creating such slave devices. Let me delete all of the others and reply once.

Quoted 4 lines
Quoted 3 lines

In order to send uevent, a device need to be a class device or a bus device. This patch introduces a tty_enum bus since the enumerated slave devices are expected to be physical devices.

Quoted 6 lines
Quoted 3 lines

Again, tty devices are already class devices, and they send out uevents. You can see this today by watching the uevent stream using a tool like 'udevadmin monitor'.

Please consider the following real scenario when a ttyS0 driver module gets loaded at kernel runtime:
1. the tty controller driver creates ttyS0

Fine.

Quoted 1 line

2. user gets uevent notified and doesn't know how to use this tty device

Of course, that's normal.

Quoted 1 line

3. a slave ACPI node under the ttyS0 gets enumerated and attributes gets appended

How will that happen? Who causes that to happen? When would that happen?

Quoted 1 line

4. user need to do user space effort to regenerate the uevent to get a Bluetooth hci user driver matched

Whatever caused step 3 to happen can send a new uevent saying something has changed. That's a one line patch.

Quoted 1 line

If the step 3 can be put ahead of step 2, there might not be weakness without this enhancement.

Yes.

Quoted 5 lines

Considering a more complex scenario:
There are two or more target devices under the ttyS0 and can be selected by some external GPIOs. Actually, BIOS will do this putting many test devices under the ttyS0.
The step 3 then can never be put ahead of step 2.
(It might be implemented using some exist kernel mechanisms like the SCSI contribute container devices...)

No, don't look at SCSI for sysfs ideas or driver core usage, it's a mess and is wrong in places. Look at how USB and PCI do it if you are curious how to implement a bus.

But again, this isn't a bus, this is a TTY class, and again, we already have one, so use it, don't create another one to stack on top of it, that's crazy.

greg k-h

author
#51 lore raw

RE: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Hi, Greg

Thanks for the comments.
How I wished so much that I can have you opinion earlier because I have some design aspects need to be discussed with the driver core and PM core designers.

Quoted 5 lines
Quoted 2 lines

Considering a more complex scenario:
There are two or more target devices under the ttyS0 and can be selected by

some external GPIOs.

Quoted 2 lines

Actually, BIOS will do this putting many test devices under the ttyS0. The step 3 then can never be put ahead of step 2.

What about this DSDT, this is what we actually can obtain from some real BIOS. How can a single ttyS0 attribute file enumerate so many slave devices under single UART:

            Device (UA00)
            {
                Device (BTH0)
                {
                    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                    {
                        Name (UBUF, ResourceTemplate ()
                        {
                            UartSerialBus (...)
                        })
                        Return (UBUF)
                    }
                }

                Device (GPS0)
                {
                    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                    {
                        Name (UBUF, ResourceTemplate ()
                        {
                            UartSerialBus (...)
                        })
                        Return (UBUF)
                    }
                }

                Device (SER0)
                {
                    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                    {
                        Name (UBUF, ResourceTemplate ()
                        {
                            UartSerialBus (...)
                        })
                        Return (UBUF)
                    }
                }

                Device (SER1)
                {
                    Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
                    {
                        Name (UBUF, ResourceTemplate ()
                        {
                            UartSerialBus (...)
                        })
                        Return (UBUF)
                    }
                }
            }

This DSDT is compatible with recent ACPI 5.0 updates on the new functionality - UART serial enumeration.

Quoted 6 lines
Quoted 2 lines

(It might be implemented using some exist kernel mechanisms like the SCSI contribute container devices...)

No, don't look at SCSI for sysfs ideas or driver core usage, it's a mess and is wrong in places. Look at how USB and PCI do it if you are curious how to implement a bus.

Yes, I can see this.
I've completed a driver model investigation prior to authorizing this patch set.
IMO, there are many driver models existed in the kernel:
1. bus driver model: where the subsystem is a bus, IMO, hardware related PM operations should only be enabled on such devices.
2. user driver model: there are devt(s) associated to such devices and the subsystem is a class
3. transport driver model: the SCSI hacks where SCSI happens to be a bus thus ATA has to be a transport class And so on (system driver model, net driver model)...
IMO, a PM friendly device driver hierarchy should:
1. implement hardware related PM operations on bus devices.
2. other devices should call APIs exported by the functionality of the bus to inc/dec PM refcnts where the bus devices resident. Thus, tty class device is not suitable for enabling hardware related PM operations that might appear in the slave devices.

If you've monitored this series of patch set, you'll find the v2 patches. Here is the links:
http://marc.info/?l=linux-serial&m=135467950218063&w=2
http://marc.info/?l=linux-serial&m=135467951018065&w=2
http://marc.info/?l=linux-serial&m=135467951818068&w=2
http://marc.info/?l=linux-serial&m=135467953118073&w=2
http://marc.info/?l=linux-serial&m=135467953218074&w=2

I actually followed the following existing kernel facilities to implement my target: ACPI 5.0 UART enumeration:
1. following the usb-serial-bus, implemented the serial-bus and created target devices below the serial-bus.
2. following the ACPI 5.0 I2C enumeration, implemented the UART enumeration.

According to Alan's comments, implementing tty_enum bus can help to extend this benefit to other serial drivers which do not relies on the serial layer (CONFIG_SERIAL_CORE).

Considering the analogy to the SPI bus layer:
Platform bus device / pci bus device
|
Spi master device (this is also a class device and can be easily converted to a devt device)
|
Spi slave device (spi bus device)
The PM call chains will call the APIs exported by the SPI cores which will:
1. inc/dec PM refcnts implemented in the spi bus device drivers for spi slaves and
2. inc/dec PM refcnts implemented in the pdev/pci bus device drivers for spi masters.

This hierarchy looks reasonable if we convert it into a Windows compatible driver model:
Platform bus device / pci bus device (PDOs)
|
Spi master device (FDOs)
|
Spi slave device (PDOs)

Thus, I accepted the suggestion, moving the uart target device from uart layer.
This has been done in the v3-v4 revisions.
And I don't see any objections in the community, thus I converted the v4 into v5, removing the RFC marks. Now the hierarchy will look like:
Platform bus device / pci bus device (PDOs)
|
Tty communication device (FDOs)
|
tty slave device (PDOs, the new tty_enum bus device)

Which one do you think is better? V2 or V5 (I have completed the test and now I have the V6 ones, I can send them out if you think the tty_enum bus is better than the serial_bus).

Thanks and best regards
-Lv

#52 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 3 lines · Lv

Which one do you think is better? V2 or V5 (I have completed the test and now I have the V6 ones, I can send them out if you think the tty_enum bus is better than the serial_bus).

I don't know, if you have a patch set you want to have reviewed, please send it, I don't have the time to dig through the links you sent me to old patch versions, nor should you ever expect someone to do that.

But whatever you send, it better not contain a duplicate of the existing tty class code, like your last patchset did, that's not going to be acceptable at all for the reasons I said.

Again, take advantage of your Intel internal Linux kernel developers for
the proper review of your code, and test it! Your last patch set
showed that this obviously did not happen, and I'm not going to look at anything further from you until you get a signed-off-by by at least one of them first (preferably more than one.)

greg k-h

#53 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

In reply to Lv Zheng

drivers/tty/tty_enum.c line 210

Quoted 8 lines · Lv Zheng
drivers/tty/tty_enum.c new file +8 -0
+static void tty_slave_release(struct device *dev)
+{
+	struct tty_slave *tts = to_tty_slave(dev);
+
+	kfree(tts);
+	/* Test code to see if slave device get released */
+	BUG();
+}

You send me a patch like this and expect me to apply it when it's obvious you didn't even test it out? That's the most _basic_ test for any dynamic type of device (add it and remove it and make sure the kernel still works.) And obviously you didn't do it.

I need a really good reason why to take you seriously now.

Intel kernel developers who know better, please take this internally and review it a bunch of times, I don't want to see it anytime soon again.

greg k-h

author
#54 lore raw

RE: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 13 lines

drivers/tty/tty_enum.c line 210

Quoted 7 lines
drivers/tty/tty_enum.c new file +7 -0
+static void tty_slave_release(struct device *dev) {
+	struct tty_slave *tts = to_tty_slave(dev);
+
+	kfree(tts);
+	/* Test code to see if slave device get released */
+	BUG();
+}

You send me a patch like this and expect me to apply it when it's obvious you didn't even test it out? That's the most _basic_ test for any dynamic type of device (add it and remove it and make sure the kernel still works.) And obviously you didn't do it.

Quoted 1 line

I need a really good reason why to take you seriously now.

It's actually my fault.
I'm lack of release testability then.
Now I can do this exactly.
According to internal reviewers' comments, it should be RFC patch to see if any objections there in the community. I'll complete the test and refresh the patches if you think the functionality is interesting and useful. Please be noted the device tree guys can also get benefit from such tty target enumeration mechanism.

Thanks
-Lv

#55 lore raw

Re: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Quoted 13 lines · Lv
Quoted 13 lines

drivers/tty/tty_enum.c line 210

Quoted 7 lines
drivers/tty/tty_enum.c new file +7 -0
+static void tty_slave_release(struct device *dev) {
+	struct tty_slave *tts = to_tty_slave(dev);
+
+	kfree(tts);
+	/* Test code to see if slave device get released */
+	BUG();
+}

You send me a patch like this and expect me to apply it when it's obvious you didn't even test it out? That's the most _basic_ test for any dynamic type of device (add it and remove it and make sure the kernel still works.) And obviously you didn't do it.

Quoted 7 lines
Quoted 1 line

I need a really good reason why to take you seriously now.

It's actually my fault.
I'm lack of release testability then.
Now I can do this exactly.
According to internal reviewers' comments, it should be RFC patch to see if any objections there in the community.

Don't put code like this in RFC code either, that shows you didn't even test it out, and want to waste other people's time.

And note, I almost _never_ read RFC patches, so you aren't going to get a review from me for it, sorry, I have too many other things to do.

Quoted 4 lines

I'll complete the test and refresh the patches if you think the functionality is interesting and useful. Please be noted the device tree guys can also get benefit from such tty target enumeration mechanism.

No, they can use what we have today, don't reinvent the wheel.

greg k-h

author
#56 lore raw

RE: [PATCH v5 1/2] TTY: Add TTY slave enumeration support

Hi,

Quoted 11 lines
Quoted 5 lines

It's actually my fault.
I'm lack of release testability then.
Now I can do this exactly.
According to internal reviewers' comments, it should be RFC patch to see if any objections there in the community.

Don't put code like this in RFC code either, that shows you didn't even test it out, and want to waste other people's time.

And note, I almost _never_ read RFC patches, so you aren't going to get a review from me for it, sorry, I have too many other things to do.

It's my great pleasure to have you taking a look at my patches.

Quoted 6 lines
Quoted 4 lines

I'll complete the test and refresh the patches if you think the functionality is interesting and useful. Please be noted the device tree guys can also get benefit from such tty target enumeration mechanism.

No, they can use what we have today, don't reinvent the wheel.

According to my previous reply, I'm not trying to reinvent the wheel but trying to fix some gaps in UART slave device enumeration which is introduced in the recent ACPI 5.0 spec updates.

Thanks and best regards
-Lv

author
#57 lore raw

PATCH v5 2/2 ACPI / UART: Add ACPI enumeration support for UART

In reply to Lv Zheng

ACPI 5.0 specification introduces mechanisms of enumerating the slave devices connected on the serial buses.
This patch follows the specification, implementing such UART enumeration machanism for Linux.
In order to use this UART device enumeration mechanism, driver writers are required to call the following API:
Call acpi_tty_register_devices _after_ the creation of the tty ports:
tty_port_register_device(port, driver, i, parent); acpi_uart_register_devices(port);
Where:
port: the registered tty port.
parent: the physical device of the UART ports.
driver and index: required parameters for tty_port_register_device.
In this patch, only SERIAL_CORE drivers are enabled to use this ACPI UART enumeration mechanism. This can be changed if there are needs updated in the future.

---
 drivers/acpi/Kconfig     |    6 ++
 drivers/acpi/Makefile    |    1 +
 drivers/acpi/acpi_uart.c |  215 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/tty_enum.c   |    1 +
 include/linux/tty.h      |    8 ++
 5 files changed, 231 insertions(+)
 create mode 100644 drivers/acpi/acpi_uart.c
drivers/acpi/Kconfig +6 -0
index 38c5078..98e2d4e 100644
@@ -187,6 +187,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate TTY_ENUM
+	depends on TTY_ENUM
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
drivers/acpi/Makefile +1 -0
index 2a4502b..784f332 100644
@@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +215 -0

215 lines not on this page · raw message

drivers/tty/tty_enum.c +1 -0
index 7947f47..2218629 100644
@@ -260,6 +260,7 @@ struct tty_slave *tty_bus_register_slave(struct tty_port *port,
 	tts->dev.parent = dev;
 	tts->dev.bus = &tty_enum_bus;
 	tts->dev.type = &tty_slave_type;
+	ACPI_HANDLE_SET(&tts->dev, info->acpi_node.handle);
 
 	tts->dev.platform_data = info->platform_data;
 	if (info->archdata)
include/linux/tty.h +8 -0
index b8d5dfb..8b60e47 100644
@@ -172,6 +172,7 @@ struct tty_board_info;
  * @irq: stored in tty_slave.irq
  * @platform_data: stored in tty_slave.dev.platform_data
  * @archdata: copied into tty_slave.dev.archdata
+ * @acpi_node: ACPI device node
  * @nr_ids: number of IDs
  * @ids: ID strings
  *
@@ -189,6 +190,7 @@ struct tty_board_info {
 	int irq;
 	void *platform_data;
 	struct dev_archdata *archdata;
+	struct acpi_dev_node acpi_node;
 
 	int nr_ids;
 	/* This must be the last member of tty_board_info */
@@ -763,4 +765,10 @@ do {									\
 } while (0)
 
 
+#if IS_ENABLED(CONFIG_ACPI_UART)
+void acpi_uart_register_devices(struct tty_port *port);
+#else
+static inline void acpi_uart_register_devices(struct tty_port *port) {}
+#endif
+
 #endif
Signature · 1 line
1.7.10
author
#58 lore raw

RFC PATCH v5 1/1 HACK: UART: Add dummy devices to test the enumeration

In reply to Lv Zheng

This is a test patch that should not be merged into any of the published Linux source tree.
This test is useful on platforms having not ACPI 5.0 UART serial enumerated devices equipped.

The test is based on the following customized DSDT (containing the dummy uart host adapter INTF000 and target device INTF001):

1. customized DSDT:
Device (UA00)

  {
      Name (_HID, "INTF000")  // _HID: Hardware ID
      Name (RBUF, ResourceTemplate ()
      {
          Memory32Fixed (ReadWrite,
              0x00000000,         // Address Base
              0x00001000)         // Address Length
      })
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Return (RBUF)
      }
      Method (_STA, 0, NotSerialized)  // _STA: Status
      {
          Return (0x0F)
      }
      Device (BTH0)
      {
          Name (_HID, "INTF001")  // _HID: Hardware ID
          Name (_CID, "PNPF001")  // _CID: Compatible ID
          Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
          {
              Name (UBUF, ResourceTemplate ()
              {
                  UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                      0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                      0x0020, 0x0020, "\\_SB.PCI0.UA00",
                      0x00, ResourceConsumer, ,
                      )
              })
              Return (UBUF)
          }
          Method (_STA, 0, NotSerialized)  // _STA: Status
          {
              Return (0x0F)
          }
      }

}

2. uevent monitor:

# udevadm monitor --kernel --environment > ~/uart.uevents
# echo add > /sys/class/tty/uevent
# echo add > /sys/class/tty/devices/BTH0:00/uevent
# cat ~/uart.uevents
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[252.443458] add /bus/tty_enum (bus)
ACTION=add
DEVPATH=/bus/tty_enum
SEQNUM=1142
SUBSYSTEM=bus

KERNEL[268.491709] add /devices/platform/INTF000:00/tty/ttyS0/BTH0:00 (tty)
ACTION=add DEVPATH=/devices/platform/INTF000:00/tty/ttyS0/BTH0:00 DEVTYPE=tty_slave MODALIAS=tty::INTF001:PNPF001:
SEQNUM=1144
SUBSYSTEM=tty

3. kobjects attributes and links:

# cat /sys/bus/tty_enum/devices/BTH0:00/modalias
tty::INTF001:PNPF001:
# cat /sys/bus/tty_enum/devices/BTH0:00/tty_attrs
115200 8N0 HW
# cat /sys/bus/tty_enum/devices/BTH0:00/modem_lines
LE:RTS,CTS,
# ls -l /sys/bus/tty_enum/devices/
BTH0:00 -> ../../../devices/platform/INTF000:00/tty/ttyS0/tty/BTH0:00
# ls -l /sys/devices/platform/INTF000:00/tty/ttyS0/BTH0:00/
firmware_node -> ../../../../../LNXSYSTM:00/device:00/INTF000:00/INTF001:00
subsystem -> ../../../../../../bus/tty_enum
# ls -l /sys/bus/acpi/devices/INTF001:00/
physical_node -> ../../../../pnp0/00:00
physical_node1 -> ../../../../platform/INTF000:00/tty/ttyS0/BTH0:00
---
 drivers/acpi/scan.c                  |    1 +
 drivers/tty/serial/8250/8250.c       |    5 +-
 drivers/tty/serial/8250/8250_dummy.c |  103 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig      |   10 ++++
 drivers/tty/serial/8250/Makefile     |    1 +
 include/linux/serial_8250.h          |    4 ++
 include/linux/serial_core.h          |   12 ++++
 7 files changed, 133 insertions(+), 3 deletions(-)
 create mode 100644 drivers/tty/serial/8250/8250_dummy.c
drivers/acpi/scan.c +1 -0
index c88be6c..3a0f259 100644
@@ -36,6 +36,7 @@ static const char *dummy_hid = "device";
 static const struct acpi_device_id acpi_platform_device_ids[] = {
 
 	{ "PNP0D40" },
+	{ "INTF000" },
 
 	/* Haswell LPSS devices */
 	{ "INT33C0", 0 },
drivers/tty/serial/8250/8250.c +2 -3
index cb7db5a..663e077 100644
@@ -56,8 +56,6 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
 static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
 
-static struct uart_driver serial8250_reg;
-
 static int serial_index(struct uart_port *port)
 {
 	return (serial8250_reg.minor - 64) + port->line;
@@ -2938,7 +2936,7 @@ int serial8250_find_port(struct uart_port *p)
 #define SERIAL8250_CONSOLE	NULL
 #endif
 
-static struct uart_driver serial8250_reg = {
+struct uart_driver serial8250_reg = {
 	.owner			= THIS_MODULE,
 	.driver_name		= "serial",
 	.dev_name		= "ttyS",
@@ -2946,6 +2944,7 @@ static struct uart_driver serial8250_reg = {
 	.minor			= 64,
 	.cons			= SERIAL8250_CONSOLE,
 };
+EXPORT_SYMBOL_GPL(serial8250_reg);
 
 /*
  * early_serial_setup - early registration for 8250 ports
drivers/tty/serial/8250/8250_dummy.c new file +103 -0

103 lines not on this page · raw message

drivers/tty/serial/8250/Kconfig +10 -0
index d31f4c6..57ca8a1 100644
@@ -269,6 +269,16 @@ config SERIAL_8250_DW
 	  Selecting this option will enable handling of the extra features
 	  present in the Synopsys DesignWare APB UART.
 
+config SERIAL_8250_DUMMY
+	tristate "Support for dummy ACPI 8250"
+	depends on SERIAL_8250 && ACPI
+	help
+	  Selecting this option will enable a test UART target device DUMMY
+	  under the ISA serial8250 and a test UART host adapter INTF000
+	  as an platform device for the purpose of testing the ACPI UART
+	  enumeration support.
+	  If unsure, say "N" here.
+
 config SERIAL_8250_EM
 	tristate "Support for Emma Mobile integrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
drivers/tty/serial/8250/Makefile +1 -0
index a23838a..39142aa 100644
@@ -20,3 +20,4 @@ obj-$(CONFIG_SERIAL_8250_HUB6)		+= 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_FSL)		+= 8250_fsl.o
 obj-$(CONFIG_SERIAL_8250_DW)		+= 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
+obj-$(CONFIG_SERIAL_8250_DUMMY)		+= 8250_dummy.o
include/linux/serial_8250.h +4 -0
index af47a8a..b61aa6c 100644
@@ -100,6 +100,10 @@ struct uart_8250_port {
 	void			(*dl_write)(struct uart_8250_port *, int);
 };
 
+extern struct uart_driver serial8250_reg;
+
+#define serial8250_tty_port(line)	uart_tty_port(&serial8250_reg, (line))
+
 int serial8250_register_8250_port(struct uart_8250_port *);
 void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
include/linux/serial_core.h +12 -0
index 82aebc8..e620fc1 100644
@@ -257,6 +257,18 @@ struct uart_driver {
 	struct tty_driver	*tty_driver;
 };
 
+static inline struct tty_port *uart_tty_port(struct uart_driver *drv,
+					     unsigned int line)
+{
+	struct uart_state *state;
+
+	if (line >= drv->nr)
+		return NULL;
+
+	state = drv->state + line;
+	return &state->port;
+}
+
 void uart_write_wakeup(struct uart_port *port);
 
 /*
Signature · 1 line
1.7.10
author
#59 lore raw

RFC PATCH 1/1 ACPI / serial: Add UART change_pm support with ACPI power domain

In reply to Lv Zheng

This patch enables ACPI power domain on UART user devices. With this patch, Linux can achieve open/close based ACPI power manageability for UART tty ports.

---
 drivers/acpi/acpi_uart.c         |   40 ++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/serial_core.c |    5 +++++
 include/linux/tty.h              |    4 ++++
 3 files changed, 49 insertions(+)
drivers/acpi/acpi_uart.c +40 -0
index c27fc7c..a6735b1 100644
@@ -163,3 +163,43 @@ void acpi_uart_register_user_device(struct device *parent,
 	}
 }
 EXPORT_SYMBOL_GPL(acpi_uart_register_user_device);
+
+/**
+ * acpi_uart_user_change_pm - change pm for tty port
+ * @port: the tty port
+ * @power_on: whether or not power on the device
+ *
+ * Change PM for tty user device.
+ */
+void acpi_uart_user_change_pm(struct tty_port *port, bool power_on)
+{
+	acpi_handle handle;
+	struct acpi_device *adev;
+	struct acpi_device_physical_node *entry;
+	struct device *ldev;
+
+	BUG_ON(!port);
+	handle = ACPI_NODE_GET(port->acpi_node);
+	if (!handle)
+		return;
+	if (acpi_bus_get_device(handle, &adev))
+		return;
+	if (acpi_bus_get_status(adev) || !adev->status.present)
+		return;
+
+	list_for_each_entry(entry, &adev->physical_node_list, node) {
+		ldev = get_device(entry->dev);
+		if (!ldev)
+			continue;
+		if (ldev->class == tty_class) {
+			if (power_on)
+				acpi_dev_pm_attach(ldev, true);
+			else
+				acpi_dev_pm_detach(ldev, false);
+			put_device(ldev);
+			return;
+		}
+		put_device(ldev);
+	}
+}
+EXPORT_SYMBOL_GPL(acpi_uart_user_change_pm);
drivers/tty/serial/serial_core.c +5 -0
index c10bb4c..6ca4a5c 100644
@@ -1901,10 +1901,15 @@ static void uart_change_pm(struct uart_state *state,
 			   enum uart_pm_state pm_state)
 {
 	struct uart_port *port = state->uart_port;
+	struct tty_port *tport = &state->port;
 
 	if (state->pm_state != pm_state) {
+		if (pm_state == UART_PM_STATE_ON)
+			acpi_uart_user_change_pm(tport, true);
 		if (port->ops->pm)
 			port->ops->pm(port, pm_state, state->pm_state);
+		if (pm_state == UART_PM_STATE_OFF)
+			acpi_uart_user_change_pm(tport, false);
 		state->pm_state = pm_state;
 	}
 }
include/linux/tty.h +4 -0
index 5f17ab5..fbf8def 100644
@@ -687,11 +687,15 @@ void acpi_uart_register_user_device(struct device *parent,
 		struct device *dev,
 		struct tty_driver *driver,
 		unsigned int index);
+extern void acpi_uart_user_change_pm(struct tty_port *port,
+		bool power_on);
 #else
 static inline void acpi_uart_register_user_device(struct device *parent,
 		struct device *dev,
 		struct tty_driver *driver,
 		unsigned int index) {}
+static inline void acpi_uart_user_change_pm(struct tty_port *port,
+		bool power_on) {}
 #endif
 
 #endif
Signature · 1 line
1.7.10
#60 lore raw

Re: [RFC PATCH] ACPI / serial: Add UART change_pm support with ACPI power domain

Quoted 3 lines · Lv Zheng

This patch enables ACPI power domain on UART user devices. With this patch, Linux can achieve open/close based ACPI power manageability for UART tty ports.

So you are going to be sticking acpi_* calls into common core places all over the kernel for stuff like this?

What's wrong with using the existing pm callbacks that are there for all platforms to use?

greg k-h

#61 lore raw

Re: [RFC PATCH] ACPI / serial: Add UART change_pm support with ACPI power domain

Quoted 10 lines · Greg Kroah-Hartman
Quoted 3 lines · Lv Zheng

This patch enables ACPI power domain on UART user devices. With this patch, Linux can achieve open/close based ACPI power manageability for UART tty ports.

So you are going to be sticking acpi_* calls into common core places all over the kernel for stuff like this?

What's wrong with using the existing pm callbacks that are there for all platforms to use?

I think that this just hasn't been thought through sufficiently (again).

Sorry about this noise,
Rafael

Signature · 2 lines
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
#62 lore raw

Re: [RFC PATCH] ACPI / serial: Add UART change_pm support with ACPI power domain

Quoted 6 lines · Rafael J. Wysocki
Quoted 5 lines · Greg Kroah-Hartman
Quoted 3 lines · Lv Zheng

This patch enables ACPI power domain on UART user devices. With this patch, Linux can achieve open/close based ACPI power manageability for UART tty ports.

Quoted 7 lines
Quoted 5 lines

So you are going to be sticking acpi_* calls into common core places all over the kernel for stuff like this?

What's wrong with using the existing pm callbacks that are there for all platforms to use?

I think that this just hasn't been thought through sufficiently (again).

Ugh. Ok, I now am going to just quietly drop all intel.com patches to the tty/serial layer unless they have at least 2 signed-off-by: lines, one of which is by someone who is "well known" to me as being sane.

greg k-h

author
#63 lore raw

RE: [RFC PATCH] ACPI / serial: Add UART change_pm support with ACPI power domain

Quoted 11 lines
Quoted 7 lines
Quoted 5 lines

So you are going to be sticking acpi_* calls into common core places all over the kernel for stuff like this?

What's wrong with using the existing pm callbacks that are there for all platforms to use?

I think that this just hasn't been thought through sufficiently (again).

Ugh. Ok, I now am going to just quietly drop all intel.com patches to the tty/serial layer unless they have at least 2 signed-off-by: lines, one of which is by someone who is "well known" to me as being sane.

Sorry for the noise. Please ignore.
It's sent by wrong typing "gitsendemail acpi-uart" instead of "gitsendemail intel-uart" where gitsendemail is my patch sending script. It should be reviewed internally prior to be sent to the public, collecting advices about where should be the better place to implement an open/close based PM.

Thanks
-Lv

author
#64 lore raw

PATCH v6 1/1 ACPI / serial: Add peripheral PnP IDs enumeration support

In reply to Lv Zheng

ACPI 5.0 specification introduces mechanisms of enumerating the peripherals connected on the serial buses. It will look like:
Device (BTH0)

  {
      Name (_HID, "IBMF001")  // _HID: Hardware ID
      Name (_CID, "PNPF001")  // _CID: Compatible ID
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Name (UBUF, ResourceTemplate ()
          {
              UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                  0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                  0x0020, 0x0020, "\\_SB.PCI0.UA00",
                  0x00, ResourceConsumer, ,
              )
          }
          Return (UBUF)
      }

}
This patch follows the specification, implementing such UART enumeration machanism by exporting current peripheral HID/CIDs for the UART devices. A userspace udev rule may look like:
SUBSYSTEM=tty, ATTR{peripheral_type}=="*:IBMF001:*", RUN+="/bin/userprog --devpath=%p"
Thanks for the internal composers:
Mika Westerberg <[email protected]>
Huang Ying <[email protected]>
Zhang Rui <[email protected]>
Thanks for the internal reviewers:
Alan Cox <[email protected]>
Rafael J. Wysocki <[email protected]>
Heikki Krogerus <[email protected]>
Andriy Shevchenko <[email protected]>
Fengguang Wu <[email protected]>

---
 drivers/acpi/Kconfig             |    6 ++
 drivers/acpi/Makefile            |    1 +
 drivers/acpi/acpi_uart.c         |  135 ++++++++++++++++++++++++++++++++++++++
 drivers/acpi/internal.h          |    2 +
 drivers/acpi/scan.c              |    8 +--
 drivers/tty/serial/serial_core.c |   15 +++++
 include/linux/tty.h              |   11 ++++
 7 files changed, 174 insertions(+), 4 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
drivers/acpi/Kconfig +6 -0
index 92ed969..42233f6 100644
@@ -186,6 +186,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate TTY
+	depends on TTY
+	help
+	  ACPI UART enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
drivers/acpi/Makefile +1 -0
index 474fcfe..4db5470 100644
@@ -72,6 +72,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +135 -0

135 lines not on this page · raw message

drivers/acpi/internal.h +2 -0
index 3c94a73..30d7440 100644
@@ -61,6 +61,8 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
 			     int type, unsigned long long sta);
 void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_ids(struct acpi_device *device);
+int acpi_device_create_modalias(struct acpi_device *acpi_dev,
+				char *modalias, int size);
 
 /* --------------------------------------------------------------------------
                                   Power Resource
drivers/acpi/scan.c +4 -4
index 5e7e991..0d7d49f 100644
@@ -68,8 +68,8 @@ int acpi_scan_add_handler(struct acpi_scan_handler *handler)
  * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
  * char *modalias: "acpi:IBM0001:ACPI0001"
 */
-static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
-			   int size)
+int acpi_device_create_modalias(struct acpi_device *acpi_dev,
+				char *modalias, int size)
 {
 	int len;
 	int count;
@@ -99,7 +99,7 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
 	int len;
 
 	/* Device has no HID and no CID or string is >1024 */
-	len = create_modalias(acpi_dev, buf, 1024);
+	len = acpi_device_create_modalias(acpi_dev, buf, 1024);
 	if (len <= 0)
 		return 0;
 	buf[len++] = '\n';
@@ -567,7 +567,7 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 
 	if (add_uevent_var(env, "MODALIAS="))
 		return -ENOMEM;
-	len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
+	len = acpi_device_create_modalias(acpi_dev, &env->buf[env->buflen - 1],
 			      sizeof(env->buf) - env->buflen);
 	if (len >= (sizeof(env->buf) - env->buflen))
 		return -ENOMEM;
drivers/tty/serial/serial_core.c +15 -0
index a400002..17e104e 100644
@@ -2515,6 +2515,19 @@ static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift);
 }
 
+static ssize_t uart_get_attr_peripheral_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	int len;
+
+	len = acpi_uart_get_peripheral_type(dev, buf, 1024);
+	if (len > 0) {
+		buf[len++] = '\n';
+		return len;
+	}
+	return snprintf(buf, PAGE_SIZE, "uart\n");
+}
+
 static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL);
 static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL);
 static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL);
@@ -2528,6 +2541,7 @@ static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divis
 static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL);
 static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL);
 static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL);
+static DEVICE_ATTR(peripheral_type, S_IRUSR | S_IRGRP, uart_get_attr_peripheral_type, NULL);
 
 static struct attribute *tty_dev_attrs[] = {
 	&dev_attr_type.attr,
@@ -2543,6 +2557,7 @@ static struct attribute *tty_dev_attrs[] = {
 	&dev_attr_io_type.attr,
 	&dev_attr_iomem_base.attr,
 	&dev_attr_iomem_reg_shift.attr,
+	&dev_attr_peripheral_type.attr,
 	NULL,
 	};
 
include/linux/tty.h +11 -0
index 367a9df..723fdd01 100644
@@ -692,4 +692,15 @@ do {									\
 } while (0)
 
 
+#ifdef CONFIG_ACPI_UART
+int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size);
+#else
+static inline int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size)
+{
+	return -ENODEV;
+}
+#endif
+
 #endif
Signature · 1 line
1.7.10
#65 lore raw

Re: [PATCH v6] ACPI / serial: Add peripheral PnP IDs enumeration support

Quoted 18 lines · Lv Zheng

ACPI 5.0 specification introduces mechanisms of enumerating the peripherals connected on the serial buses. It will look like:
Device (BTH0)

  {
      Name (_HID, "IBMF001")  // _HID: Hardware ID
      Name (_CID, "PNPF001")  // _CID: Compatible ID
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Name (UBUF, ResourceTemplate ()
          {
              UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                  0xC0, LittleEndian, ParityTypeNone, FlowControlHardware,
                  0x0020, 0x0020, "\\_SB.PCI0.UA00",
                  0x00, ResourceConsumer, ,
              )
          }
          Return (UBUF)
      }
Quoted 16 lines

}
This patch follows the specification, implementing such UART enumeration machanism by exporting current peripheral HID/CIDs for the UART devices. A userspace udev rule may look like:
SUBSYSTEM=tty, ATTR{peripheral_type}=="*:IBMF001:*", RUN+="/bin/userprog --devpath=%p"
Thanks for the internal composers:
Mika Westerberg <[email protected]>
Huang Ying <[email protected]>
Zhang Rui <[email protected]>
Thanks for the internal reviewers:
Alan Cox <[email protected]>
Rafael J. Wysocki <[email protected]>
Heikki Krogerus <[email protected]>
Andriy Shevchenko <[email protected]>
Fengguang Wu <[email protected]>

Why are these names not on the list below?

Quoted 22 lines
---
 drivers/acpi/Kconfig             |    6 ++
 drivers/acpi/Makefile            |    1 +
 drivers/acpi/acpi_uart.c         |  135 ++++++++++++++++++++++++++++++++++++++
 drivers/acpi/internal.h          |    2 +
 drivers/acpi/scan.c              |    8 +--
 drivers/tty/serial/serial_core.c |   15 +++++
 include/linux/tty.h              |   11 ++++
 7 files changed, 174 insertions(+), 4 deletions(-)
 create mode 100644 drivers/acpi/acpi_uart.c
drivers/acpi/Kconfig +0 -0
index 92ed969..42233f6 100644

drivers/acpi/Kconfig config ACPI_I2C · line 193

Quoted 8 lines
drivers/acpi/Kconfig +5 -0
@@ -186,6 +186,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
+config ACPI_UART
+	def_tristate TTY
+	depends on TTY
+	help
+	  ACPI UART enumeration support.

Please provide more information here.

As this is primarily an ACPI patch, I need an ack from a ACPI maintainer before I can take this.

Quoted 212 lines
drivers/acpi/Kconfig +1 -0
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
drivers/acpi/Makefile +1 -0
index 474fcfe..4db5470 100644
@@ -72,6 +72,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new file +135 -0
new file mode 100644
index 0000000..dd5ac2e
@@ -0,0 +1,135 @@
+/*
+ * acpi_uart.c - ACPI UART enumeration support
+ *
+ * Copyright (c) 2013, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+
+#include "internal.h"
+
+struct acpi_uart_buf {
+	char *buf;
+	size_t size;
+	int *len;
+};
+
+struct acpi_uart_enum {
+	void *context;
+	acpi_status status;
+
+	struct acpi_device *adev;
+};
+
+static acpi_status
+acpi_uart_enum_pnpids(struct acpi_device *adev,
+		      struct acpi_resource_uart_serialbus *sb,
+		      void *context);
+
+static int acpi_uart_enum_resources(struct acpi_resource *ares,
+				    void *context)
+{
+	struct acpi_uart_enum *ctx = context;
+	struct acpi_resource_uart_serialbus *sb;
+
+	if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+		return 1;
+	sb = &ares->data.uart_serial_bus;
+	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_UART)
+		return 1;
+
+	ctx->status = acpi_uart_enum_pnpids(ctx->adev, sb, ctx->context);
+	return 1;
+}
+
+static acpi_status acpi_uart_enum_devices(acpi_handle handle, u32 level,
+					  void *context,
+					  void **return_value)
+{
+	struct acpi_uart_enum *ctx = context;
+	struct acpi_device *adev;
+	struct list_head resource_list;
+
+	if (acpi_bus_get_device(handle, &adev))
+		return AE_OK;
+	if (acpi_bus_get_status(adev) || !adev->status.present)
+		return AE_OK;
+
+	/* Enumerate resources. */
+	ctx->adev = adev;
+	ctx->status = AE_OK;
+	INIT_LIST_HEAD(&resource_list);
+	acpi_dev_get_resources(adev, &resource_list,
+			       acpi_uart_enum_resources, ctx);
+	acpi_dev_free_resource_list(&resource_list);
+
+	return ctx->status;
+}
+
+static int acpi_uart_walk_port(struct device *parent,
+			       void *context)
+{
+	acpi_handle handle;
+	acpi_status status;
+	struct acpi_uart_enum ctx;
+
+	handle = parent ? ACPI_HANDLE(parent) : NULL;
+	if (!handle)
+		return -ENODEV;
+
+	ctx.context = context;
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+				     acpi_uart_enum_devices, NULL,
+				     &ctx, NULL);
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+
+	return 0;
+}
+
+static acpi_status
+acpi_uart_enum_pnpids(struct acpi_device *adev,
+		      struct acpi_resource_uart_serialbus *sb,
+		      void *context)
+{
+	int len;
+	struct acpi_uart_buf *ctx = context;
+
+	len = acpi_device_create_modalias(adev, ctx->buf, ctx->size);
+	*ctx->len = len;
+
+	return len < 0 ? AE_CTRL_DEPTH : AE_OK;
+}
+
+/**
+ * acpi_uart_get_peripheral_type - get peripheral HID/CIDs
+ * @dev: the tty class device
+ * @buf: the string buffer containing HID/CIDs
+ * @size: the size of the string buffer
+ *
+ * Obtain UART peripheral HID/CIDs.  Return buffer size on success,
+ * -errno on failure.
+ */
+int acpi_uart_get_peripheral_type(struct device *dev,
+				  char *buf, size_t size)
+{
+	int ret;
+	int len = 0;
+	struct acpi_uart_buf ctx = { buf, size, &len };
+
+	ret = acpi_uart_walk_port(dev->parent, &ctx);
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+EXPORT_SYMBOL_GPL(acpi_uart_get_peripheral_type);
drivers/acpi/internal.h +2 -0
index 3c94a73..30d7440 100644
@@ -61,6 +61,8 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
 			     int type, unsigned long long sta);
 void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_ids(struct acpi_device *device);
+int acpi_device_create_modalias(struct acpi_device *acpi_dev,
+				char *modalias, int size);
 
 /* --------------------------------------------------------------------------
                                   Power Resource
drivers/acpi/scan.c +4 -4
index 5e7e991..0d7d49f 100644
@@ -68,8 +68,8 @@ int acpi_scan_add_handler(struct acpi_scan_handler *handler)
  * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
  * char *modalias: "acpi:IBM0001:ACPI0001"
 */
-static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
-			   int size)
+int acpi_device_create_modalias(struct acpi_device *acpi_dev,
+				char *modalias, int size)
 {
 	int len;
 	int count;
@@ -99,7 +99,7 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
 	int len;
 
 	/* Device has no HID and no CID or string is >1024 */
-	len = create_modalias(acpi_dev, buf, 1024);
+	len = acpi_device_create_modalias(acpi_dev, buf, 1024);
 	if (len <= 0)
 		return 0;
 	buf[len++] = '\n';
@@ -567,7 +567,7 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 
 	if (add_uevent_var(env, "MODALIAS="))
 		return -ENOMEM;
-	len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
+	len = acpi_device_create_modalias(acpi_dev, &env->buf[env->buflen - 1],
 			      sizeof(env->buf) - env->buflen);
 	if (len >= (sizeof(env->buf) - env->buflen))
 		return -ENOMEM;
drivers/tty/serial/serial_core.c +1 -0
index a400002..17e104e 100644
@@ -2515,6 +2515,19 @@ static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift);
 }
 
+static ssize_t uart_get_attr_peripheral_type(struct device *dev,

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2528

Quoted 10 lines
drivers/tty/serial/serial_core.c +10 -0
+		struct device_attribute *attr, char *buf)
+{
+	int len;
+
+	len = acpi_uart_get_peripheral_type(dev, buf, 1024);
+	if (len > 0) {
+		buf[len++] = '\n';
+		return len;
+	}
+	return snprintf(buf, PAGE_SIZE, "uart\n");

What is the "uart" part for? Isn't that kind of obvious?

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2529

Quoted 1 line
drivers/tty/serial/serial_core.c +1 -0
+}

You are creating a new sysfs file, you must create a new Documentation/ABI entry as well.

Quoted 28 lines
drivers/tty/serial/serial_core.c +3 -0
+
 static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL);
 static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL);
 static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL);
@@ -2528,6 +2541,7 @@ static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divis
 static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL);
 static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL);
 static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL);
+static DEVICE_ATTR(peripheral_type, S_IRUSR | S_IRGRP, uart_get_attr_peripheral_type, NULL);
 
 static struct attribute *tty_dev_attrs[] = {
 	&dev_attr_type.attr,
@@ -2543,6 +2557,7 @@ static struct attribute *tty_dev_attrs[] = {
 	&dev_attr_io_type.attr,
 	&dev_attr_iomem_base.attr,
 	&dev_attr_iomem_reg_shift.attr,
+	&dev_attr_peripheral_type.attr,
 	NULL,
 	};
 
include/linux/tty.h +0 -0
index 367a9df..723fdd01 100644
@@ -692,4 +692,15 @@ do {									\
 } while (0)
 
 

include/linux/tty.h do { \ · line 704

Quoted 10 lines
include/linux/tty.h +10 -0
+#ifdef CONFIG_ACPI_UART
+int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size);
+#else
+static inline int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size)
+{
+	return -ENODEV;
+}
+#endif

I see you never tested this code without the configuration option enabled :(

{sigh}

greg k-h

author
#66 lore raw

RE: [PATCH v6] ACPI / serial: Add peripheral PnP IDs enumeration support

Quoted 37 lines
Quoted 12 lines

ACPI 5.0 specification introduces mechanisms of enumerating the peripherals connected on the serial buses. It will look like:
Device (BTH0)

  {
      Name (_HID, "IBMF001")  // _HID: Hardware ID
      Name (_CID, "PNPF001")  // _CID: Compatible ID
      Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
      {
          Name (UBUF, ResourceTemplate ()
          {
              UartSerialBus (0x0001C200, DataBitsEight, StopBitsOne,
                  0xC0, LittleEndian, ParityTypeNone,

FlowControlHardware,

Quoted 9 lines
                  0x0020, 0x0020, "\\_SB.PCI0.UA00",
                  0x00, ResourceConsumer, ,
              )
          }
          Return (UBUF)
      }

}
This patch follows the specification, implementing such UART enumeration machanism by exporting current peripheral HID/CIDs for the

UART devices.

Quoted 5 lines

A userspace udev rule may look like:
SUBSYSTEM=tty, ATTR{peripheral_type}=="*:IBMF001:*", RUN+="/bin/userprog --devpath=%p"
Thanks for the internal composers:
Mika Westerberg <[email protected]>

Quoted 8 lines

Huang Ying <[email protected]>
Zhang Rui <[email protected]>
Thanks for the internal reviewers:
Alan Cox <[email protected]>
Rafael J. Wysocki <[email protected]>
Heikki Krogerus <[email protected]>
Andriy Shevchenko <[email protected]>
Fengguang Wu <[email protected]>

Quoted 1 line

Why are these names not on the list below?

I obtained help from them on old revisions. Mika is the key person for the acpi serial enumeration. He has implemented the acpi i2c/spi serial enumeration.

Quoted 26 lines
Quoted 10 lines
---
 drivers/acpi/Kconfig             |    6 ++
 drivers/acpi/Makefile            |    1 +
 drivers/acpi/acpi_uart.c         |  135

++++++++++++++++++++++++++++++++++++++

Quoted 15 lines
 drivers/acpi/internal.h          |    2 +
 drivers/acpi/scan.c              |    8 +--
 drivers/tty/serial/serial_core.c |   15 +++++
 include/linux/tty.h              |   11 ++++
 7 files changed, 174 insertions(+), 4 deletions(-)  create mode

100644 drivers/acpi/acpi_uart.c

drivers/acpi/Kconfig index renamed from drivers/acpi/Kconfig +0 -0

92ed969..42233f6 100644

drivers/acpi/Kconfig +0 -0
@@ -186,6 +186,12 @@ config ACPI_I2C
 	help
 	  ACPI I2C enumeration support.
 
Quoted 7 lines

drivers/acpi/Kconfig config ACPI_I2C · line 193

Quoted 5 lines
drivers/acpi/Kconfig +5 -0
+config ACPI_UART
+	def_tristate TTY
+	depends on TTY
+	help
+	  ACPI UART enumeration support.

Please provide more information here.

OK.

Quoted 2 lines

As this is primarily an ACPI patch, I need an ack from a ACPI maintainer before I can take this.

OK, I'll ask for this.

Quoted 217 lines

drivers/acpi/internal.h void acpi_init_device_object(struct acpi_device *device,

Quoted 162 lines
drivers/acpi/Kconfig +1 -0
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
drivers/acpi/Makefile index renamed from drivers/acpi/Makefile +0 -0

474fcfe..4db5470 100644

drivers/acpi/Makefile +1 -0
@@ -72,6 +72,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
+obj-$(CONFIG_ACPI_UART)		+= acpi_uart.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
drivers/acpi/acpi_uart.c new renamed from drivers/acpi/acpi_uart.c +0 -0

file mode 100644 index 0000000..dd5ac2e

drivers/acpi/acpi_uart.c new file +136 -0
@@ -0,0 +1,135 @@
+/*
+ * acpi_uart.c - ACPI UART enumeration support
+ *
+ * Copyright (c) 2013, Intel Corporation
+ * Author: Lv Zheng <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+modify it
+ * under the terms of the GNU General Public License as published by
+the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+
+#include "internal.h"
+
+struct acpi_uart_buf {
+	char *buf;
+	size_t size;
+	int *len;
+};
+
+struct acpi_uart_enum {
+	void *context;
+	acpi_status status;
+
+	struct acpi_device *adev;
+};
+
+static acpi_status
+acpi_uart_enum_pnpids(struct acpi_device *adev,
+		      struct acpi_resource_uart_serialbus *sb,
+		      void *context);
+
+static int acpi_uart_enum_resources(struct acpi_resource *ares,
+				    void *context)
+{
+	struct acpi_uart_enum *ctx = context;
+	struct acpi_resource_uart_serialbus *sb;
+
+	if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+		return 1;
+	sb = &ares->data.uart_serial_bus;
+	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_UART)
+		return 1;
+
+	ctx->status = acpi_uart_enum_pnpids(ctx->adev, sb, ctx->context);
+	return 1;
+}
+
+static acpi_status acpi_uart_enum_devices(acpi_handle handle, u32 level,
+					  void *context,
+					  void **return_value)
+{
+	struct acpi_uart_enum *ctx = context;
+	struct acpi_device *adev;
+	struct list_head resource_list;
+
+	if (acpi_bus_get_device(handle, &adev))
+		return AE_OK;
+	if (acpi_bus_get_status(adev) || !adev->status.present)
+		return AE_OK;
+
+	/* Enumerate resources. */
+	ctx->adev = adev;
+	ctx->status = AE_OK;
+	INIT_LIST_HEAD(&resource_list);
+	acpi_dev_get_resources(adev, &resource_list,
+			       acpi_uart_enum_resources, ctx);
+	acpi_dev_free_resource_list(&resource_list);
+
+	return ctx->status;
+}
+
+static int acpi_uart_walk_port(struct device *parent,
+			       void *context)
+{
+	acpi_handle handle;
+	acpi_status status;
+	struct acpi_uart_enum ctx;
+
+	handle = parent ? ACPI_HANDLE(parent) : NULL;
+	if (!handle)
+		return -ENODEV;
+
+	ctx.context = context;
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+				     acpi_uart_enum_devices, NULL,
+				     &ctx, NULL);
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+
+	return 0;
+}
+
+static acpi_status
+acpi_uart_enum_pnpids(struct acpi_device *adev,
+		      struct acpi_resource_uart_serialbus *sb,
+		      void *context)
+{
+	int len;
+	struct acpi_uart_buf *ctx = context;
+
+	len = acpi_device_create_modalias(adev, ctx->buf, ctx->size);
+	*ctx->len = len;
+
+	return len < 0 ? AE_CTRL_DEPTH : AE_OK; }
+
+/**
+ * acpi_uart_get_peripheral_type - get peripheral HID/CIDs
+ * @dev: the tty class device
+ * @buf: the string buffer containing HID/CIDs
+ * @size: the size of the string buffer
+ *
+ * Obtain UART peripheral HID/CIDs.  Return buffer size on success,
+ * -errno on failure.
+ */
+int acpi_uart_get_peripheral_type(struct device *dev,
+				  char *buf, size_t size)
+{
+	int ret;
+	int len = 0;
+	struct acpi_uart_buf ctx = { buf, size, &len };
+
+	ret = acpi_uart_walk_port(dev->parent, &ctx);
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+EXPORT_SYMBOL_GPL(acpi_uart_get_peripheral_type);
drivers/acpi/internal.h index renamed from drivers/acpi/internal.h +0 -0

3c94a73..30d7440 100644

drivers/acpi/internal.h +0 -0
@@ -61,6 +61,8 @@ void acpi_init_device_object(struct acpi_device *device,

acpi_handle handle,

drivers/acpi/scan.c int acpi_scan_add_handler(struct acpi_scan_handler

Quoted 13 lines
drivers/acpi/internal.h +0 -0
 			     int type, unsigned long long sta);  void

acpi_device_add_finalize(struct acpi_device *device); void acpi_free_ids(struct acpi_device *device);

drivers/acpi/internal.h +2 -0
+int acpi_device_create_modalias(struct acpi_device *acpi_dev,
+				char *modalias, int size);
 
 /* --------------------------------------------------------------------------
                                   Power Resource diff --git

a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5e7e991..0d7d49f 100644

drivers/acpi/scan.c +0 -0
@@ -68,8 +68,8 @@ int acpi_scan_add_handler(struct acpi_scan_handler

*handler)

drivers/acpi/scan.c acpi_device_modalias_show(struct device *dev, struct

Quoted 11 lines
drivers/acpi/scan.c +2 -2
  * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
  * char *modalias: "acpi:IBM0001:ACPI0001"
 */
-static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
-			   int size)
+int acpi_device_create_modalias(struct acpi_device *acpi_dev,
+				char *modalias, int size)
 {
 	int len;
 	int count;
@@ -99,7 +99,7 @@ acpi_device_modalias_show(struct device *dev, struct

device_attribute *attr, cha

drivers/tty/serial/serial_core.c static ssize_t

Quoted 25 lines
drivers/acpi/scan.c +3 -2
 	int len;
 
 	/* Device has no HID and no CID or string is >1024 */
-	len = create_modalias(acpi_dev, buf, 1024);
+	len = acpi_device_create_modalias(acpi_dev, buf, 1024);
 	if (len <= 0)
 		return 0;
 	buf[len++] = '\n';
@@ -567,7 +567,7 @@ static int acpi_device_uevent(struct device *dev,
 struct kobj_uevent_env *env)
 
 	if (add_uevent_var(env, "MODALIAS="))
 		return -ENOMEM;
-	len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
+	len = acpi_device_create_modalias(acpi_dev, &env->buf[env->buflen -
+1],
 			      sizeof(env->buf) - env->buflen);
 	if (len >= (sizeof(env->buf) - env->buflen))
 		return -ENOMEM;
drivers/tty/serial/serial_core.c +0 -0
index a400002..17e104e 100644
@@ -2515,6 +2515,19 @@ static ssize_t

uart_get_attr_iomem_reg_shift(struct device *dev,

Quoted 2 lines
drivers/tty/serial/serial_core.c +0 -0
 	return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift);  }
 
Quoted 12 lines

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2528

Quoted 10 lines
drivers/tty/serial/serial_core.c +10 -0
+static ssize_t uart_get_attr_peripheral_type(struct device *dev,
+		struct device_attribute *attr, char *buf) {
+	int len;
+
+	len = acpi_uart_get_peripheral_type(dev, buf, 1024);
+	if (len > 0) {
+		buf[len++] = '\n';
+		return len;
+	}
+	return snprintf(buf, PAGE_SIZE, "uart\n");

What is the "uart" part for? Isn't that kind of obvious?

It is the default "peripheral_type" content.
Before sending next revision out, let me ask a question here:
Shall I leave this empty as my previous revisions?

Quoted 4 lines

drivers/tty/serial/serial_core.c static ssize_t · line 2527

Quoted 1 line
drivers/tty/serial/serial_core.c +1 -0
+}

You are creating a new sysfs file, you must create a new Documentation/ABI entry as well.

OK.

Quoted 45 lines
Quoted 32 lines
drivers/tty/serial/serial_core.c +1 -0
+
 static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type,
 NULL);  static DEVICE_ATTR(line, S_IRUSR | S_IRGRP,

uart_get_attr_line, NULL); static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL); @@ -2528,6 +2541,7 @@ static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divis static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL); static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL); static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL);

drivers/tty/serial/serial_core.c +3 -0
+static DEVICE_ATTR(peripheral_type, S_IRUSR | S_IRGRP,
+uart_get_attr_peripheral_type, NULL);
 
 static struct attribute *tty_dev_attrs[] = {
 	&dev_attr_type.attr,
@@ -2543,6 +2557,7 @@ static struct attribute *tty_dev_attrs[] = {
 	&dev_attr_io_type.attr,
 	&dev_attr_iomem_base.attr,
 	&dev_attr_iomem_reg_shift.attr,
+	&dev_attr_peripheral_type.attr,
 	NULL,
 	};
 
include/linux/tty.h index renamed from include/linux/tty.h +0 -0

367a9df..723fdd01 100644

include/linux/tty.h +0 -0
@@ -692,4 +692,15 @@ do {									\
 } while (0)
 
 

include/linux/tty.h do { \ · line 704

Quoted 10 lines
include/linux/tty.h +10 -0
+#ifdef CONFIG_ACPI_UART
+int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size);
+#else
+static inline int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size)
+{
+	return -ENODEV;
+}
+#endif

I see you never tested this code without the configuration option enabled :(

Quoted 1 line

{sigh}

Yes, I rely too much on an internal test system as it can do this for me automatically. OK, I'll take care of this next time.
I've a plan and a TODO to offer a complete test framework for this as I've done 10 years ago. Hope you will like it.

Thanks and best regards
-Lv

author
#67 lore raw

RE: [PATCH v6] ACPI / serial: Add peripheral PnP IDs enumeration support

Hi, Greg

I think I may misunderstand what you mean here, let me confirm again. Sorry for doing this.

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
include/linux/tty.h +4 -0
+#ifdef CONFIG_ACPI_UART
+int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size);
+#else
Quoted 8 lines
Quoted 8 lines

include/linux/tty.h do { \ · line 704

Quoted 6 lines
include/linux/tty.h +6 -0
+static inline int acpi_uart_get_peripheral_type(struct device *dev,
+	char *buf, size_t size)
+{
+	return -ENODEV;
+}
+#endif

I see you never tested this code without the configuration option enabled :(

I was thinking you were talking about test plans.
Since I didn't see any issues here and I just didn't want to argue on this topic and replied in this way. :-) The only user - uart_get_attr_peripheral_type with "int" return value check can ensure no issues here.

Quoted 10 lines
Quoted 10 lines

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2528

Quoted 10 lines
drivers/tty/serial/serial_core.c +10 -0
+static ssize_t uart_get_attr_peripheral_type(struct device *dev,
+		struct device_attribute *attr, char *buf) {
+	int len;
+
+	len = acpi_uart_get_peripheral_type(dev, buf, 1024);
+	if (len > 0) {
+		buf[len++] = '\n';
+		return len;
+	}
+	return snprintf(buf, PAGE_SIZE, "uart\n");

Now I realize that you might be talking about the "-NODEV" return value is not a good choice, "0" or something else is better. Shall I return 0 here?

Thanks and best regards
-Lv

author
#68 lore raw

RE: [PATCH v6] ACPI / serial: Add peripheral PnP IDs enumeration support

In reply to Greg Kroah-Hartman

Hi,

Quoted 7 lines
Quoted 3 lines

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2528

Quoted 1 line
drivers/tty/serial/serial_core.c +1 -0
+	return snprintf(buf, PAGE_SIZE, "uart\n");

What is the "uart" part for? Isn't that kind of obvious?

It is the default "peripheral_type" content.
Before sending next revision out, let me ask a question here:
Shall I leave this empty as my previous revisions?

Hmm, if this is empty by default then the udev rules may require additional handlings. Can I use "NONE" here for the user space users?

Thanks and best regards
-Lv

#69 lore raw

Re: [PATCH v6] ACPI / serial: Add peripheral PnP IDs enumeration support

Quoted 6 lines · Lv

Hi,

Quoted 4 lines
Quoted 3 lines

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2528

Quoted 1 line
drivers/tty/serial/serial_core.c +1 -0
+	return snprintf(buf, PAGE_SIZE, "uart\n");

What is the "uart" part for? Isn't that kind of obvious?

Quoted 6 lines
Quoted 3 lines

It is the default "peripheral_type" content.
Before sending next revision out, let me ask a question here:
Shall I leave this empty as my previous revisions?

Hmm, if this is empty by default then the udev rules may require additional handlings. Can I use "NONE" here for the user space users?

No, just don't create the sysfs file at all for that type of device.

greg k-h

author
#70 lore raw

RE: [PATCH v6] ACPI / serial: Add peripheral PnP IDs enumeration support

Quoted 10 lines
Quoted 10 lines

Hi,

Quoted 7 lines
Quoted 3 lines

drivers/tty/serial/serial_core.c static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, · line 2528

Quoted 1 line
drivers/tty/serial/serial_core.c +1 -0
+	return snprintf(buf, PAGE_SIZE, "uart\n");

What is the "uart" part for? Isn't that kind of obvious?

It is the default "peripheral_type" content.
Before sending next revision out, let me ask a question here:
Shall I leave this empty as my previous revisions?

Quoted 5 lines
Quoted 1 line

Hmm, if this is empty by default then the udev rules may require additional

handlings.

Quoted 1 line

Can I use "NONE" here for the user space users?

No, just don't create the sysfs file at all for that type of device.

Sorry for the delayed reply.

I was thinking developers are encouraged to use the default attributes.
In the tty subsystem, the default attributes are owned by the tty drivers, thus I added peripheral_type file in the serial layer.

If we want to have it as a dynamic attribute, we may modify the codes in the tty_register_device_attr, splitting device_register into two parts, and add sysfs addition codes between the device_initialize and device_add. So that the uevents received by the user space can have this attribute set.
Sorry that I need your confirmation before doing such modification.

Thanks and best regards
-Lv