On 11/19/2014 06:43 PM, Lina Iyer wrote:
On Fri, Nov 14 2014 at 08:56 -0700, Daniel Lezcano wrote:
On 10/25/2014 01:40 AM, Lina Iyer wrote:
+/**
+ * spm_set_low_power_mode() - Configure SPM start address for low
power mode
+ * @mode: SPM LPM mode to enter
+ */
+int qcom_spm_set_low_power_mode(enum pm_sleep_mode mode)
+{
+ struct spm_driver_data *drv = this_cpu_ptr(&cpu_spm_drv);
+ u32 start_index;
+ u32 ctl_val;
+
+ if (!drv->available)
+ return -ENXIO;
really weird how this was initialized.
Are you sure 'drv' is not NULL if it is not available ? (see below)
'drv' has some data that I need to decode the register address. Hence
cant have that NULL. Therefore, the available flag.
...
+static int spm_dev_probe(struct platform_device *pdev)
+{
+ struct spm_driver_data *drv;
+ struct resource *res;
+ const struct of_device_id *match_id;
+ void __iomem *addr;
+ const u32 *seq_data;
+ int cpu = -EINVAL;
+ static bool cpuidle_drv_init;
+
+ drv = spm_get_drv(pdev, &cpu);
+ if (!drv)
+ return -EINVAL;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ drv->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(drv->reg_base))
+ return PTR_ERR(drv->reg_base);
+
+ match_id = of_match_node(spm_match_table, pdev->dev.of_node);
+ if (!match_id)
+ return -ENODEV;
+
+ drv->reg_data = match_id->data;
+ if (!drv->reg_data)
+ return -EINVAL;
+
+ /* Write the SPM sequences, first.. */
+ addr = drv->reg_base +
drv->reg_data->reg_offset[SPM_REG_SEQ_ENTRY];
+ seq_data = (const u32 *)drv->reg_data->seq;
+ __iowrite32_copy(addr, seq_data, ARRAY_SIZE(drv->reg_data->seq)/4);
+
+ /* ..and then, the control registers.
+ * On some SoC's if the control registers are written first and
if the
+ * CPU was held in reset, the reset signal could trigger the SPM
state
+ * machine, before the sequences are completely written.
+ */
+ spm_register_write(drv, SPM_REG_CFG, drv->reg_data->spm_cfg);
+ spm_register_write(drv, SPM_REG_DLY, drv->reg_data->spm_dly);
+ spm_register_write(drv, SPM_REG_PMIC_DLY, drv->reg_data->pmic_dly);
+
+ spm_register_write(drv, SPM_REG_PMIC_DATA_0,
+ drv->reg_data->pmic_data[0]);
+ spm_register_write(drv, SPM_REG_PMIC_DATA_1,
+ drv->reg_data->pmic_data[1]);
+
+ /**
+ * Ensure all observers see the above register writes before the
+ * cpuidle driver is allowed to use the SPM.
+ */
+ wmb();
+ drv->available = true;
IMO if you have to do that, that means there is something wrong with
how is initialized the driver.
It should be drv == NULL => not available
drv has the register base that I dont want to pass seprately.
+
+ if ((cpu > -1) && !cpuidle_drv_init) {
+ platform_device_register(&qcom_cpuidle_device);
+ cpuidle_drv_init = true;
+ }
'cpu' is always > -1.
OK. I was hoping to use -1 for not a cpu (i.e, L2) SPM. For now, I will
change.
If the 'spm_get_drv' succeed, cpu is no longer equal to -EINVAL.
Otherwise we do not reach this point because we return right after
spm_get_drv with an error.
Adding the platform_device_register depending in a static variable is
not very nice. Why not add it explicitely in a separate init routine
we know it will be called one time (eg. at the same place than cpufreq
is) ?
We want to register the cpuidle device only if any of the SPM devices
have been probed.
Ideally, Stephen and I would like to register cpuidle device separately
for each CPU SPM, when it is probed, so we would invoke cpuidle driver
and thereby the low power modes only for those cpus. However, the
complexity to do that, AFAICS, is very complex. I would need to change
quite a bit of the framework and in the cpuidle driver, I may have to
stray from the recommended format.
Here I set up cpuidle device, when I know atleast 1 cpu is ready to
allow low power modes.
Yes, instead of using the generic cpuidle_register function, you can use
the low level functions for that.
One call to cpuidle_register_driver in a single place and then
cpuidle_register_device for each spm probe.
Wouldn't make sense ?
-- Daniel
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html