/** * omap_device_build_from_dt - build an omap_device with multiple hwmods * @pdev_name: name of the platform_device driver to use * @pdev_id: this platform_device's connection ID * @oh: ptr to the single omap_hwmod that backs this omap_device * @pdata: platform_data ptr to associate with the platform_device * @pdata_len: amount of memory pointed to by @pdata * * Function for building an omap_device already registered from device-tree * * Returns 0 or PTR_ERR() on error. */ static int omap_device_build_from_dt(struct platform_device *pdev) { struct omap_hwmod **hwmods; struct omap_device *od; struct omap_hwmod *oh; struct device_node *node = pdev->dev.of_node; const char *oh_name; int oh_cnt, i, ret = 0; oh_cnt = of_property_count_strings(node, "ti,hwmods"); if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); if (!hwmods) { ret = -ENOMEM; goto odbfd_exit; } for (i = 0; i < oh_cnt; i++) { of_property_read_string_index(node, "ti,hwmods", i, &oh_name); oh = omap_hwmod_lookup(oh_name); if (!oh) { dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", oh_name); ret = -EINVAL; goto odbfd_exit1; } hwmods[i] = oh; } od = omap_device_alloc(pdev, hwmods, oh_cnt); if (!od) { dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", oh_name); ret = PTR_ERR(od); goto odbfd_exit1; } /* Fix up missing resource names */ for (i = 0; i < pdev->num_resources; i++) { struct resource *r = &pdev->resource[i]; if (r->name == NULL) r->name = dev_name(&pdev->dev); } if (of_get_property(node, "ti,no_idle_on_suspend", NULL)) omap_device_disable_idle_on_suspend(pdev); pdev->dev.pm_domain = &omap_device_pm_domain; odbfd_exit1: kfree(hwmods); odbfd_exit: return ret; }
/* HSI device registration */ static int __init omap_hsi_register(struct omap_hwmod *oh, void *user) { struct platform_device *od; struct hsi_platform_data *pdata = &omap_hsi_platform_data; int i, port, err; if (!oh) { pr_err("Could not look up %s omap_hwmod\n", OMAP_HSI_HWMOD_NAME); return -EEXIST; } omap_hsi_platform_data.errata = omap_hsi_configure_errata(); oh->mux = omap_hsi_fill_default_pads(pdata); for (i = 0; i < pdata->num_ports; i++) { port = pdata->ctx->pctx[i].port_number - 1; err = omap_hwmod_pad_route_irq(oh, i, port); if (err < 0) { pr_err("%s: Could not route the IO PAD wakeup event on IRQ %d for the port %d, error = %d\n", __func__, oh->mpu_irqs[i].irq, port + 1, err); return err; } } od = omap_device_build(OMAP_HSI_PLATFORM_DEVICE_DRIVER_NAME, 0, oh, pdata, sizeof(*pdata), omap_hsi_latency, ARRAY_SIZE(omap_hsi_latency), false); WARN(IS_ERR(od), "Can't build omap_device for %s:%s.\n", OMAP_HSI_PLATFORM_DEVICE_DRIVER_NAME, oh->name); /* DONOT auto-disable me while going to suspend */ omap_device_disable_idle_on_suspend(od); pr_info("HSI: device registered as omap_hwmod: %s\n", oh->name); return 0; }
static int __init sr_dev_init(struct omap_hwmod *oh, void *user) { struct omap_sr_data *sr_data; struct platform_device *pdev; struct omap_volt_data *volt_data; struct omap_smartreflex_dev_attr *sr_dev_attr; char *name = "smartreflex"; static int i; sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); if (!sr_data) { pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n", __func__, oh->name); return -ENOMEM; } sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { pr_err("%s: No voltage domain specified for %s." "Cannot initialize\n", __func__, oh->name); goto exit; } sr_data->name = oh->name; sr_data->lvt_sensor = false; sr_data->ip_type = oh->class->rev; sr_data->senn_mod = 0x1; sr_data->senp_mod = 0x1; sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name); if (IS_ERR(sr_data->voltdm)) { pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", __func__, sr_dev_attr->sensor_voltdm_name); goto exit; } if (cpu_is_omap54xx() && (!strcmp(sr_data->voltdm->name, "mpu") || !strcmp(sr_data->voltdm->name, "mm"))) sr_data->lvt_sensor = true; omap_voltage_get_volttable(sr_data->voltdm, &volt_data); if (!volt_data) { pr_warning("%s: No Voltage table registerd fo VDD%d." "Something really wrong\n\n", __func__, i + 1); goto exit; } sr_set_nvalues(volt_data, sr_data); if (sr_data->lvt_sensor) lvt_sr_set_nvalues(volt_data, sr_data); sr_data->enable_on_init = sr_enable_on_init; sr_data->ops = &omap_sr_ops; pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), NULL, 0, 0); if (IS_ERR(pdev)) pr_warning("%s: Could not build omap_device for %s: %s.\n\n", __func__, name, oh->name); /* DONOT auto-disable me while going to suspend */ omap_device_disable_idle_on_suspend(pdev); exit: i++; kfree(sr_data); return 0; }