#include <linux/init.h>
#include <linux/idr.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/slimbus.h>
#include "slimbus.h"
struct slim_device *sbdev = to_slim_device(dev);
struct slim_driver *sbdrv = to_slim_driver(drv);
+ /* Attempt an OF style match first */
+ if (of_driver_match_device(dev, drv))
+ return 1;
+
return !!slim_match(sbdrv->id_table, sbdev);
}
{
struct slim_device *sbdev = to_slim_device(dev);
struct slim_driver *sbdrv = to_slim_driver(dev->driver);
+ int ret;
- return sbdrv->probe(sbdev);
+ ret = sbdrv->probe(sbdev);
+ if (ret)
+ return ret;
+
+ /* try getting the logical address after probe */
+ ret = slim_get_logical_addr(sbdev);
+ if (!ret) {
+ if (sbdrv->device_status)
+ sbdrv->device_status(sbdev, sbdev->status);
+ } else {
+ dev_err(&sbdev->dev, "Failed to get logical address\n");
+ ret = -EPROBE_DEFER;
+ }
+
+ return ret;
}
static int slim_device_remove(struct device *dev)
return 0;
}
+static int slim_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct slim_device *sbdev = to_slim_device(dev);
+ int ret;
+
+ ret = of_device_uevent_modalias(dev, env);
+ if (ret != -ENODEV)
+ return ret;
+
+ return add_uevent_var(env, "MODALIAS=slim:%s", dev_name(&sbdev->dev));
+}
+
struct bus_type slimbus_bus = {
.name = "slimbus",
.match = slim_device_match,
.probe = slim_device_probe,
.remove = slim_device_remove,
+ .uevent = slim_device_uevent,
};
EXPORT_SYMBOL_GPL(slimbus_bus);
int __slim_driver_register(struct slim_driver *drv, struct module *owner)
{
/* ID table and probe are mandatory */
- if (!drv->id_table || !drv->probe)
+ if (!(drv->driver.of_match_table || drv->id_table) || !drv->probe)
return -EINVAL;
drv->driver.bus = &slimbus_bus;