static int scmi_clock_protocol_init(struct scmi_handle *handle) { u32 version; int clkid, ret; struct clock_info *cinfo; scmi_version_get(handle, SCMI_PROTOCOL_CLOCK, &version); dev_dbg(handle->dev, "Clock Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); cinfo = devm_kzalloc(handle->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) return -ENOMEM; scmi_clock_protocol_attributes_get(handle, cinfo); cinfo->clk = devm_kcalloc(handle->dev, cinfo->num_clocks, sizeof(*cinfo->clk), GFP_KERNEL); if (!cinfo->clk) return -ENOMEM; for (clkid = 0; clkid < cinfo->num_clocks; clkid++) { struct scmi_clock_info *clk = cinfo->clk + clkid; ret = scmi_clock_attributes_get(handle, clkid, clk); if (!ret) scmi_clock_describe_rates_get(handle, clkid, clk); } handle->clk_ops = &clk_ops; handle->clk_priv = cinfo; return 0; }
static int scmi_power_protocol_init(struct scmi_handle *handle) { int domain; u32 version; struct scmi_power_info *pinfo; scmi_version_get(handle, SCMI_PROTOCOL_POWER, &version); dev_dbg(handle->dev, "Power Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL); if (!pinfo) return -ENOMEM; scmi_power_attributes_get(handle, pinfo); pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains, sizeof(*pinfo->dom_info), GFP_KERNEL); if (!pinfo->dom_info) return -ENOMEM; for (domain = 0; domain < pinfo->num_domains; domain++) { struct power_dom_info *dom = pinfo->dom_info + domain; scmi_power_domain_attributes_get(handle, domain, dom); } handle->power_ops = &power_ops; handle->power_priv = pinfo; return 0; }
static int scmi_sensors_protocol_init(struct scmi_handle *handle) { u32 version; struct sensors_info *sinfo; scmi_version_get(handle, SCMI_PROTOCOL_SENSOR, &version); dev_dbg(handle->dev, "Sensor Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); sinfo = devm_kzalloc(handle->dev, sizeof(*sinfo), GFP_KERNEL); if (!sinfo) return -ENOMEM; scmi_sensor_attributes_get(handle, sinfo); sinfo->sensors = devm_kcalloc(handle->dev, sinfo->num_sensors, sizeof(*sinfo->sensors), GFP_KERNEL); if (!sinfo->sensors) return -ENOMEM; scmi_sensor_description_get(handle, sinfo); handle->sensor_ops = &sensor_ops; handle->sensor_priv = sinfo; return 0; }
static ssize_t protocol_version_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev); return sprintf(buf, "%d.%d\n", PROTOCOL_REV_MAJOR(scpi_info->protocol_version), PROTOCOL_REV_MINOR(scpi_info->protocol_version)); }
static int scpi_probe(struct platform_device *pdev) { int count, idx, ret; struct resource res; struct scpi_chan *scpi_chan; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; scpi_info = devm_kzalloc(dev, sizeof(*scpi_info), GFP_KERNEL); if (!scpi_info) { dev_err(dev, "failed to allocate memory for scpi drvinfo\n"); return -ENOMEM; } count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); if (count < 0) { dev_err(dev, "no mboxes property in '%s'\n", np->full_name); return -ENODEV; } scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL); if (!scpi_chan) { dev_err(dev, "failed to allocate memory scpi chaninfo\n"); return -ENOMEM; } for (idx = 0; idx < count; idx++) { resource_size_t size; struct scpi_chan *pchan = scpi_chan + idx; struct mbox_client *cl = &pchan->cl; struct device_node *shmem = of_parse_phandle(np, "shmem", idx); if (of_address_to_resource(shmem, 0, &res)) { dev_err(dev, "failed to get SCPI payload mem resource\n"); ret = -EINVAL; goto err; } size = resource_size(&res); pchan->rx_payload = devm_ioremap(dev, res.start, size); if (!pchan->rx_payload) { dev_err(dev, "failed to ioremap SCPI payload\n"); ret = -EADDRNOTAVAIL; goto err; } pchan->tx_payload = pchan->rx_payload + (size >> 1); cl->dev = dev; cl->rx_callback = scpi_handle_remote_msg; cl->tx_prepare = scpi_tx_prepare; cl->tx_block = true; cl->tx_tout = 50; cl->knows_txdone = false; /* controller can ack */ INIT_LIST_HEAD(&pchan->rx_pending); INIT_LIST_HEAD(&pchan->xfers_list); spin_lock_init(&pchan->rx_lock); mutex_init(&pchan->xfers_lock); ret = scpi_alloc_xfer_list(dev, pchan); if (!ret) { pchan->chan = mbox_request_channel(cl, idx); if (!IS_ERR(pchan->chan)) continue; ret = -EPROBE_DEFER; dev_err(dev, "failed to acquire channel#%d\n", idx); } err: scpi_free_channels(dev, scpi_chan, idx); scpi_info = NULL; return ret; } scpi_info->channels = scpi_chan; scpi_info->num_chans = count; platform_set_drvdata(pdev, scpi_info); ret = scpi_init_versions(scpi_info); if (ret) { dev_err(dev, "incorrect or no SCP firmware found\n"); scpi_remove(pdev); return ret; } _dev_info(dev, "SCP Protocol %d.%d Firmware %d.%d.%d version\n", PROTOCOL_REV_MAJOR(scpi_info->protocol_version), PROTOCOL_REV_MINOR(scpi_info->protocol_version), FW_REV_MAJOR(scpi_info->firmware_version), FW_REV_MINOR(scpi_info->firmware_version), FW_REV_PATCH(scpi_info->firmware_version)); scpi_info->scpi_ops = &scpi_ops; ret = sysfs_create_groups(&dev->kobj, versions_groups); if (ret) dev_err(dev, "unable to create sysfs version group\n"); return of_platform_populate(dev->of_node, NULL, NULL, dev); }