@@ -315,7 +315,21 @@ static int realtek_smi_read(void *ctx, u32 reg, u32 *val)
return realtek_smi_read_reg(smi, reg, val);
}
-static const struct regmap_config realtek_smi_mdio_regmap_config = {
+static void realtek_smi_lock(void *ctx)
+{
+ struct realtek_smi *smi = ctx;
+
+ mutex_lock(&smi->map_lock);
+}
+
+static void realtek_smi_unlock(void *ctx)
+{
+ struct realtek_smi *smi = ctx;
+
+ mutex_unlock(&smi->map_lock);
+}
+
+static const struct regmap_config realtek_smi_regmap_config = {
.reg_bits = 10, /* A4..A0 R4..R0 */
.val_bits = 16,
.reg_stride = 1,
@@ -325,6 +339,21 @@ static const struct regmap_config realtek_smi_mdio_regmap_config = {
.reg_read = realtek_smi_read,
.reg_write = realtek_smi_write,
.cache_type = REGCACHE_NONE,
+ .lock = realtek_smi_lock,
+ .unlock = realtek_smi_unlock,
+};
+
+static const struct regmap_config realtek_smi_nolock_regmap_config = {
+ .reg_bits = 10, /* A4..A0 R4..R0 */
+ .val_bits = 16,
+ .reg_stride = 1,
+ /* PHY regs are at 0x8000 */
+ .max_register = 0xffff,
+ .reg_format_endian = REGMAP_ENDIAN_BIG,
+ .reg_read = realtek_smi_read,
+ .reg_write = realtek_smi_write,
+ .cache_type = REGCACHE_NONE,
+ .disable_locking = true,
};
static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
@@ -388,6 +417,7 @@ static int realtek_smi_probe(struct platform_device *pdev)
const struct realtek_smi_variant *var;
struct device *dev = &pdev->dev;
struct realtek_smi *smi;
+ struct regmap_config rc;
struct device_node *np;
int ret;
@@ -398,14 +428,26 @@ static int realtek_smi_probe(struct platform_device *pdev)
if (!smi)
return -ENOMEM;
smi->chip_data = (void *)smi + sizeof(*smi);
- smi->map = devm_regmap_init(dev, NULL, smi,
- &realtek_smi_mdio_regmap_config);
+
+ mutex_init(&smi->map_lock);
+
+ rc = realtek_smi_regmap_config;
+ rc.lock_arg = smi;
+ smi->map = devm_regmap_init(dev, NULL, smi, &rc);
if (IS_ERR(smi->map)) {
ret = PTR_ERR(smi->map);
dev_err(dev, "regmap init failed: %d\n", ret);
return ret;
}
+ rc = realtek_smi_nolock_regmap_config;
+ smi->map_nolock = devm_regmap_init(dev, NULL, smi, &rc);
+ if (IS_ERR(smi->map_nolock)) {
+ ret = PTR_ERR(smi->map_nolock);
+ dev_err(dev, "regmap init failed: %d\n", ret);
+ return ret;
+ }
+
/* Link forward and backward */
smi->dev = dev;
smi->clk_delay = var->clk_delay;
@@ -49,6 +49,8 @@ struct realtek_smi {
struct gpio_desc *mdc;
struct gpio_desc *mdio;
struct regmap *map;
+ struct regmap *map_nolock;
+ struct mutex map_lock;
struct mii_bus *slave_mii_bus;
unsigned int clk_delay;