From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/mfd/max77620.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 97 insertions(+), 11 deletions(-)
diff --git a/kernel/drivers/mfd/max77620.c b/kernel/drivers/mfd/max77620.c
index b1700b5..a6661e0 100644
--- a/kernel/drivers/mfd/max77620.c
+++ b/kernel/drivers/mfd/max77620.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Maxim MAX77620 MFD Driver
*
@@ -7,10 +8,6 @@
* Laxman Dewangan <ldewangan@nvidia.com>
* Chaitanya Bandi <bandik@nvidia.com>
* Mallikarjun Kasoju <mkasoju@nvidia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
/****************** Teminology used in driver ********************
@@ -36,6 +33,8 @@
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
+
+static struct max77620_chip *max77620_scratch;
static const struct resource gpio_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
@@ -111,6 +110,26 @@
},
};
+static const struct mfd_cell max77663_children[] = {
+ { .name = "max77620-pinctrl", },
+ { .name = "max77620-clock", },
+ { .name = "max77663-pmic", },
+ { .name = "max77620-watchdog", },
+ {
+ .name = "max77620-gpio",
+ .resources = gpio_resources,
+ .num_resources = ARRAY_SIZE(gpio_resources),
+ }, {
+ .name = "max77620-rtc",
+ .resources = rtc_resources,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ }, {
+ .name = "max77663-power",
+ .resources = power_resources,
+ .num_resources = ARRAY_SIZE(power_resources),
+ },
+};
+
static const struct regmap_range max77620_readable_ranges[] = {
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
};
@@ -158,6 +177,7 @@
.rd_table = &max77620_readable_table,
.wr_table = &max77620_writable_table,
.volatile_table = &max77620_volatile_table,
+ .use_single_write = true,
};
static const struct regmap_config max20024_regmap_config = {
@@ -168,6 +188,35 @@
.cache_type = REGCACHE_RBTREE,
.rd_table = &max20024_readable_table,
.wr_table = &max77620_writable_table,
+ .volatile_table = &max77620_volatile_table,
+};
+
+static const struct regmap_range max77663_readable_ranges[] = {
+ regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
+};
+
+static const struct regmap_access_table max77663_readable_table = {
+ .yes_ranges = max77663_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(max77663_readable_ranges),
+};
+
+static const struct regmap_range max77663_writable_ranges[] = {
+ regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_CID5),
+};
+
+static const struct regmap_access_table max77663_writable_table = {
+ .yes_ranges = max77663_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(max77663_writable_ranges),
+};
+
+static const struct regmap_config max77663_regmap_config = {
+ .name = "power-slave",
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX77620_REG_CID5 + 1,
+ .cache_type = REGCACHE_RBTREE,
+ .rd_table = &max77663_readable_table,
+ .wr_table = &max77663_writable_table,
.volatile_table = &max77620_volatile_table,
};
@@ -240,6 +289,9 @@
case MAX77620:
fps_min_period = MAX77620_FPS_PERIOD_MIN_US;
break;
+ case MAX77663:
+ fps_min_period = MAX20024_FPS_PERIOD_MIN_US;
+ break;
default:
return -EINVAL;
}
@@ -274,18 +326,21 @@
case MAX77620:
fps_max_period = MAX77620_FPS_PERIOD_MAX_US;
break;
+ case MAX77663:
+ fps_max_period = MAX20024_FPS_PERIOD_MAX_US;
+ break;
default:
return -EINVAL;
}
for (fps_id = 0; fps_id < MAX77620_FPS_COUNT; fps_id++) {
sprintf(fps_name, "fps%d", fps_id);
- if (!strcmp(fps_np->name, fps_name))
+ if (of_node_name_eq(fps_np, fps_name))
break;
}
if (fps_id == MAX77620_FPS_COUNT) {
- dev_err(dev, "FPS node name %s is not valid\n", fps_np->name);
+ dev_err(dev, "FPS node name %pOFn is not valid\n", fps_np);
return -EINVAL;
}
@@ -362,9 +417,13 @@
for_each_child_of_node(fps_np, fps_child) {
ret = max77620_config_fps(chip, fps_child);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(fps_child);
+ of_node_put(fps_np);
return ret;
+ }
}
+ of_node_put(fps_np);
config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0;
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
@@ -375,6 +434,9 @@
}
skip_fps:
+ if (chip->chip_id == MAX77663)
+ return 0;
+
/* Enable wake on EN0 pin */
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
MAX77620_ONOFFCNFG2_WK_EN0,
@@ -423,6 +485,15 @@
return ret;
}
+static void max77620_pm_power_off(void)
+{
+ struct max77620_chip *chip = max77620_scratch;
+
+ regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG1,
+ MAX77620_ONOFFCNFG1_SFT_RST,
+ MAX77620_ONOFFCNFG1_SFT_RST);
+}
+
static int max77620_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -430,6 +501,7 @@
struct max77620_chip *chip;
const struct mfd_cell *mfd_cells;
int n_mfd_cells;
+ bool pm_off;
int ret;
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
@@ -438,7 +510,6 @@
i2c_set_clientdata(client, chip);
chip->dev = &client->dev;
- chip->irq_base = -1;
chip->chip_irq = client->irq;
chip->chip_id = (enum max77620_chip_id)id->driver_data;
@@ -452,6 +523,11 @@
mfd_cells = max20024_children;
n_mfd_cells = ARRAY_SIZE(max20024_children);
rmap_config = &max20024_regmap_config;
+ break;
+ case MAX77663:
+ mfd_cells = max77663_children;
+ n_mfd_cells = ARRAY_SIZE(max77663_children);
+ rmap_config = &max77663_regmap_config;
break;
default:
dev_err(chip->dev, "ChipID is invalid %d\n", chip->chip_id);
@@ -471,8 +547,8 @@
max77620_top_irq_chip.irq_drv_data = chip;
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
- IRQF_ONESHOT | IRQF_SHARED,
- chip->irq_base, &max77620_top_irq_chip,
+ IRQF_ONESHOT | IRQF_SHARED, 0,
+ &max77620_top_irq_chip,
&chip->top_irq_data);
if (ret < 0) {
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
@@ -489,6 +565,12 @@
if (ret < 0) {
dev_err(chip->dev, "Failed to add MFD children: %d\n", ret);
return ret;
+ }
+
+ pm_off = of_device_is_system_power_controller(client->dev.of_node);
+ if (pm_off && !pm_power_off) {
+ max77620_scratch = chip;
+ pm_power_off = max77620_pm_power_off;
}
return 0;
@@ -546,6 +628,9 @@
return ret;
}
+ if (chip->chip_id == MAX77663)
+ goto out;
+
/* Disable WK_EN0 */
ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2,
MAX77620_ONOFFCNFG2_WK_EN0, 0);
@@ -581,7 +666,7 @@
* For MAX20024: No need to configure WKEN0 on resume as
* it is configured on Init.
*/
- if (chip->chip_id == MAX20024)
+ if (chip->chip_id == MAX20024 || chip->chip_id == MAX77663)
goto out;
/* Enable WK_EN0 */
@@ -603,6 +688,7 @@
static const struct i2c_device_id max77620_id[] = {
{"max77620", MAX77620},
{"max20024", MAX20024},
+ {"max77663", MAX77663},
{},
};
--
Gitblit v1.6.2