Merge tag 'omap-for-v4.8/fixes-rc2' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / firmware / arm_scpi.c
index 7e3e595..ce2bc2a 100644 (file)
@@ -210,10 +210,6 @@ struct dvfs_info {
        } opps[MAX_DVFS_OPPS];
 } __packed;
 
-struct dvfs_get {
-       u8 index;
-} __packed;
-
 struct dvfs_set {
        u8 domain;
        u8 index;
@@ -235,6 +231,11 @@ struct sensor_value {
        __le32 hi_val;
 } __packed;
 
+struct dev_pstate_set {
+       u16 dev_id;
+       u8 pstate;
+} __packed;
+
 static struct scpi_drvinfo *scpi_info;
 
 static int scpi_linux_errmap[SCPI_ERR_MAX] = {
@@ -431,11 +432,11 @@ static int scpi_clk_set_val(u16 clk_id, unsigned long rate)
 static int scpi_dvfs_get_idx(u8 domain)
 {
        int ret;
-       struct dvfs_get dvfs;
+       u8 dvfs_idx;
 
        ret = scpi_send_message(SCPI_CMD_GET_DVFS, &domain, sizeof(domain),
-                               &dvfs, sizeof(dvfs));
-       return ret ? ret : dvfs.index;
+                               &dvfs_idx, sizeof(dvfs_idx));
+       return ret ? ret : dvfs_idx;
 }
 
 static int scpi_dvfs_set_idx(u8 domain, u8 index)
@@ -526,7 +527,7 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info)
        return ret;
 }
 
-int scpi_sensor_get_value(u16 sensor, u64 *val)
+static int scpi_sensor_get_value(u16 sensor, u64 *val)
 {
        __le16 id = cpu_to_le16(sensor);
        struct sensor_value buf;
@@ -541,6 +542,29 @@ int scpi_sensor_get_value(u16 sensor, u64 *val)
        return ret;
 }
 
+static int scpi_device_get_power_state(u16 dev_id)
+{
+       int ret;
+       u8 pstate;
+       __le16 id = cpu_to_le16(dev_id);
+
+       ret = scpi_send_message(SCPI_CMD_GET_DEVICE_PWR_STATE, &id,
+                               sizeof(id), &pstate, sizeof(pstate));
+       return ret ? ret : pstate;
+}
+
+static int scpi_device_set_power_state(u16 dev_id, u8 pstate)
+{
+       int stat;
+       struct dev_pstate_set dev_set = {
+               .dev_id = cpu_to_le16(dev_id),
+               .pstate = pstate,
+       };
+
+       return scpi_send_message(SCPI_CMD_SET_DEVICE_PWR_STATE, &dev_set,
+                                sizeof(dev_set), &stat, sizeof(stat));
+}
+
 static struct scpi_ops scpi_ops = {
        .get_version = scpi_get_version,
        .clk_get_range = scpi_clk_get_range,
@@ -552,6 +576,8 @@ static struct scpi_ops scpi_ops = {
        .sensor_get_capability = scpi_sensor_get_capability,
        .sensor_get_info = scpi_sensor_get_info,
        .sensor_get_value = scpi_sensor_get_value,
+       .device_get_power_state = scpi_device_get_power_state,
+       .device_set_power_state = scpi_device_set_power_state,
 };
 
 struct scpi_ops *get_scpi_ops(void)
@@ -683,9 +709,10 @@ static int scpi_probe(struct platform_device *pdev)
                struct mbox_client *cl = &pchan->cl;
                struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
 
-               if (of_address_to_resource(shmem, 0, &res)) {
+               ret = of_address_to_resource(shmem, 0, &res);
+               of_node_put(shmem);
+               if (ret) {
                        dev_err(dev, "failed to get SCPI payload mem resource\n");
-                       ret = -EINVAL;
                        goto err;
                }