diff options
Diffstat (limited to 'drivers/spmi/spmi.c')
-rw-r--r-- | drivers/spmi/spmi.c | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 6de645eca3f2..466d93eb47b9 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -9,6 +9,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + + #include <linux/kernel.h> #include <linux/errno.h> #include <linux/idr.h> @@ -22,8 +24,6 @@ #include <dt-bindings/spmi/spmi.h> -#define DEBUG 1 - static DEFINE_IDA(ctrl_ida); static void spmi_dev_release(struct device *dev) @@ -49,8 +49,12 @@ static const struct device_type spmi_ctrl_type = { static int spmi_device_match(struct device *dev, struct device_driver *drv) { - if (of_driver_match_device(dev, drv)) + + pr_info("%s: %s vs %s\n", __func__, dev_name(dev), drv->name); + if (of_driver_match_device(dev, drv)) { + pr_err("of_driver_match says hit\n"); return 1; + } if (drv->name) return strncmp(dev_name(dev), drv->name, @@ -66,7 +70,11 @@ static int spmi_device_match(struct device *dev, struct device_driver *drv) int spmi_device_add(struct spmi_device *sdev) { struct spmi_controller *ctrl = sdev->ctrl; + struct device_node *node; + struct platform_device *pdev; int err; + static int index; + char *name; dev_set_name(&sdev->dev, "%d-%02x", ctrl->nr, sdev->usid); @@ -77,6 +85,26 @@ int spmi_device_add(struct spmi_device *sdev) goto err_device_add; } + + for_each_available_child_of_node(sdev->dev.of_node, node) { + name = kzalloc(64, GFP_KERNEL); + sprintf(name, " %s-%d", node->name, index++); + + pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + + pdev->name = name; + pdev->dev.parent = &sdev->dev; + pdev->dev.of_node = node; + pdev->dev.init_name = name; + + err = platform_device_register(pdev); + if (err) { + pr_err("Failed to create device %s: %d\n", name, err); + kfree(pdev); + } else + dev_info(&sdev->dev, "Created %s\n", name); + } + dev_dbg(&sdev->dev, "device %s registered\n", dev_name(&sdev->dev)); err_device_add: @@ -109,6 +137,8 @@ static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type) return -EINVAL; + pr_err("ctrl->read_cmd = %p\n", (void *)ctrl->read_cmd); + return ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len); } @@ -178,7 +208,7 @@ int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf, /* 16-bit register address, up to 8 bytes */ if (len == 0 || len > 8) return -EINVAL; - +pr_err("sdev->ctrl = %p\n", sdev->ctrl); return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READL, sdev->usid, addr, buf, len); } @@ -382,10 +412,23 @@ struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl) sdev->dev.parent = &ctrl->dev; sdev->dev.bus = &spmi_bus_type; sdev->dev.type = &spmi_dev_type; + + dev_set_drvdata(&sdev->dev, sdev); + return sdev; } EXPORT_SYMBOL_GPL(spmi_device_alloc); +struct spmi_device *spmi_from_parent(struct device *dev) +{ + if (!dev->parent) + return NULL; + + return dev_get_drvdata(dev->parent); +} + +EXPORT_SYMBOL_GPL(spmi_from_parent); + /** * spmi_controller_alloc() - Allocate a new SPMI controller * @parent: parent device @@ -439,12 +482,12 @@ static void of_spmi_register_devices(struct spmi_controller *ctrl) if (!ctrl->dev.of_node) return; - +pr_err("%s\n", __func__); for_each_available_child_of_node(ctrl->dev.of_node, node) { struct spmi_device *sdev; u32 reg[2]; - dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name); + dev_info(&ctrl->dev, "adding child %s\n", node->full_name); err = of_property_read_u32_array(node, "reg", reg, 2); if (err) { @@ -468,7 +511,8 @@ static void of_spmi_register_devices(struct spmi_controller *ctrl) continue; } - dev_dbg(&ctrl->dev, "read usid %02x\n", reg[0]); + dev_info(&ctrl->dev, "read usid %02x\n", reg[0]); + sdev = spmi_device_alloc(ctrl); if (!sdev) |