diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 226adeec2aed..ead0071b5969 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -31,7 +31,18 @@ static ssize_t modalias_show(struct device *dev, if (len != -ENODEV) return len; - return of_device_modalias(dev, buf, PAGE_SIZE); + len = of_device_modalias(dev, buf, PAGE_SIZE); + if (len != -ENODEV) + return len; + + if (dev->parent->parent->bus == &platform_bus_type) { + struct platform_device *pdev = + to_platform_device(dev->parent->parent); + + len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); + } + + return len; } static DEVICE_ATTR_RO(modalias); @@ -45,13 +56,18 @@ static int serdev_device_uevent(struct device *dev, struct kobj_uevent_env *env) { int rc; - /* TODO: platform modalias */ - rc = acpi_device_uevent_modalias(dev, env); if (rc != -ENODEV) return rc; - return of_device_uevent_modalias(dev, env); + rc = of_device_uevent_modalias(dev, env); + if (rc != -ENODEV) + return rc; + + if (dev->parent->parent->bus == &platform_bus_type) + rc = dev->parent->parent->bus->uevent(dev, env); + + return rc; } static void serdev_device_release(struct device *dev) @@ -87,11 +103,17 @@ static int serdev_device_match(struct device *dev, struct device_driver *drv) if (!is_serdev_device(dev)) return 0; - /* TODO: platform matching */ if (acpi_driver_match_device(dev, drv)) return 1; - return of_driver_match_device(dev, drv); + if (of_driver_match_device(dev, drv)) + return 1; + + if (dev->parent->parent->bus == &platform_bus_type && + dev->parent->parent->bus->match(dev, drv)) + return 1; + + return 0; } /** @@ -707,6 +729,33 @@ static inline int acpi_serdev_register_devices(struct serdev_controller *ctrl) } #endif /* CONFIG_ACPI */ +static int platform_serdev_register_devices(struct serdev_controller *ctrl) +{ + struct serdev_device *serdev; + int err; + + if (ctrl->dev.parent->bus != &platform_bus_type) + return -ENODEV; + + serdev = serdev_device_alloc(ctrl); + if (!serdev) { + dev_err(&ctrl->dev, "failed to allocate serdev device for %s\n", + dev_name(ctrl->dev.parent)); + return -ENOMEM; + } + + pm_runtime_no_callbacks(&serdev->dev); + + err = serdev_device_add(serdev); + if (err) { + dev_err(&serdev->dev, + "failure adding device. status %d\n", err); + serdev_device_put(serdev); + } + + return err; +} + /** * serdev_controller_add() - Add an serdev controller * @ctrl: controller to be registered. @@ -716,7 +765,7 @@ static inline int acpi_serdev_register_devices(struct serdev_controller *ctrl) */ int serdev_controller_add(struct serdev_controller *ctrl) { - int ret_of, ret_acpi, ret; + int ret_of, ret_acpi, ret_platform, ret; /* Can't register until after driver model init */ if (WARN_ON(!is_registered)) @@ -730,9 +779,11 @@ int serdev_controller_add(struct serdev_controller *ctrl) ret_of = of_serdev_register_devices(ctrl); ret_acpi = acpi_serdev_register_devices(ctrl); - if (ret_of && ret_acpi) { - dev_dbg(&ctrl->dev, "no devices registered: of:%d acpi:%d\n", - ret_of, ret_acpi); + ret_platform = platform_serdev_register_devices(ctrl); + if (ret_of && ret_acpi && ret_platform) { + dev_dbg(&ctrl->dev, "no devices registered: of:%d acpi:%d " + "platform:%d\n", + ret_of, ret_acpi, ret_platform); ret = -ENODEV; goto err_rpm_disable; }