diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 8ad3724bfe32..4fa59314640a 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -49,14 +50,32 @@ static const struct device_type serdev_ctrl_type = { static int serdev_device_match(struct device *dev, struct device_driver *drv) { - /* TODO: ACPI and platform matching */ - return of_driver_match_device(dev, drv); + /* TODO: ACPI matching */ + + 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; } static int serdev_uevent(struct device *dev, struct kobj_uevent_env *env) { - /* TODO: ACPI and platform modalias */ - return of_device_uevent_modalias(dev, env); + int rc; + + /* TODO: ACPI modalias */ + + 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; } /** @@ -406,6 +425,33 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl) return 0; } +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. @@ -415,7 +461,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl) */ int serdev_controller_add(struct serdev_controller *ctrl) { - int ret; + int ret_of, ret_platform, ret; /* Can't register until after driver model init */ if (WARN_ON(!is_registered)) @@ -425,9 +471,15 @@ int serdev_controller_add(struct serdev_controller *ctrl) if (ret) return ret; - ret = of_serdev_register_devices(ctrl); - if (ret) + ret_platform = platform_serdev_register_devices(ctrl); + ret_of = of_serdev_register_devices(ctrl); + if (ret_of && ret_platform) { + dev_dbg(&ctrl->dev, "no devices registered: of:%d " + "platform:%d\n", + ret_of, ret_platform); + ret = -ENODEV; goto out_dev_del; + } dev_dbg(&ctrl->dev, "serdev%d registered: dev:%p\n", ctrl->nr, &ctrl->dev);