mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
soc: rockchip: io-domain: rv1126 use separated notify
RV1126 set 3.3V before regulator disable.
Do a fix to rockchip io-domain, follow this orders:
* system running state
-> io-domain vsel to 3.3V (actually is done by event-disable)
-> regulator_enable
-> vsel change according to regulator voltage
* system running state
-> regulator_disable
-> io-domain vsel to 3.3V
The bug only instance on RV1126, and tested on RV1126 EVB DDR3 V10.
Change-Id: Ic9d6b05d07b050c392e415786cf6390cc1c5aa9e
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
This commit is contained in:
@@ -610,6 +610,55 @@ static const struct of_device_id rockchip_iodomain_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_iodomain_match);
|
||||
|
||||
static int rv1126_iodomain_notify(struct notifier_block *nb,
|
||||
unsigned long event,
|
||||
void *data)
|
||||
{
|
||||
struct rockchip_iodomain_supply *supply =
|
||||
container_of(nb, struct rockchip_iodomain_supply, nb);
|
||||
int uV;
|
||||
int ret;
|
||||
|
||||
if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
|
||||
struct pre_voltage_change_data *pvc_data = data;
|
||||
|
||||
uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV);
|
||||
} else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE |
|
||||
REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) {
|
||||
uV = (unsigned long)data;
|
||||
} else if (event & REGULATOR_EVENT_DISABLE) {
|
||||
uV = MAX_VOLTAGE_3_3;
|
||||
} else if (event & REGULATOR_EVENT_ENABLE) {
|
||||
if (!data)
|
||||
return NOTIFY_BAD;
|
||||
|
||||
uV = (unsigned long)data;
|
||||
} else {
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
if (uV <= 0) {
|
||||
dev_err(supply->iod->dev, "Voltage invalid: %d\n", uV);
|
||||
return NOTIFY_BAD;
|
||||
}
|
||||
|
||||
dev_dbg(supply->iod->dev, "Setting to %d\n", uV);
|
||||
|
||||
if (uV > MAX_VOLTAGE_3_3) {
|
||||
dev_err(supply->iod->dev, "Voltage too high: %d\n", uV);
|
||||
|
||||
if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
|
||||
return NOTIFY_BAD;
|
||||
}
|
||||
|
||||
ret = supply->iod->write(supply, uV);
|
||||
if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
|
||||
return NOTIFY_BAD;
|
||||
|
||||
dev_dbg(supply->iod->dev, "Setting to %d done\n", uV);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int rockchip_iodomain_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@@ -695,6 +744,8 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
|
||||
supply->iod = iod;
|
||||
supply->reg = reg;
|
||||
supply->nb.notifier_call = rockchip_iodomain_notify;
|
||||
if (IS_ENABLED(CONFIG_CPU_RV1126))
|
||||
supply->nb.notifier_call = rv1126_iodomain_notify;
|
||||
|
||||
ret = iod->write(supply, uV);
|
||||
if (ret) {
|
||||
|
||||
Reference in New Issue
Block a user