diff --git a/target/linux/ramips/dts/mt7621_mikrotik_rbm11g.dts b/target/linux/ramips/dts/mt7621_mikrotik_rbm11g.dts index 60b6395..d24b805 100644 --- a/target/linux/ramips/dts/mt7621_mikrotik_rbm11g.dts +++ b/target/linux/ramips/dts/mt7621_mikrotik_rbm11g.dts @@ -64,17 +64,25 @@ }; }; - pcie0_vcc_reg { + pcie0_vcc_reg: pcie0_vcc_reg { compatible = "regulator-fixed"; regulator-name = "pcie0_vcc"; - regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; enable-active-high; regulator-boot-on; - regulator-always-on; }; + + card-power-switch { + compatible = "reg-userspace-consumer"; + regulator-name ="card-power-switch"; + regulator-boot-on; + regulator-supplies = "vcc"; + vcc-supply = <&pcie0_vcc_reg>; + comment = "pcie slot vcc switch"; + }; + }; &spi0 { diff --git a/target/linux/ramips/mt7621/config-4.14 b/target/linux/ramips/mt7621/config-4.14 index 2ae6afb..82c7aaf 100644 --- a/target/linux/ramips/mt7621/config-4.14 +++ b/target/linux/ramips/mt7621/config-4.14 @@ -252,6 +252,7 @@ CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SPI=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_USERSPACE_CONSUMER=y CONFIG_RESET_CONTROLLER=y CONFIG_RFS_ACCEL=y CONFIG_RPS=y diff --git a/target/linux/ramips/patches-4.14/9998-userspace-regulator.patch b/target/linux/ramips/patches-4.14/9998-userspace-regulator.patch new file mode 100644 index 0000000..86d7410 --- /dev/null +++ b/target/linux/ramips/patches-4.14/9998-userspace-regulator.patch @@ -0,0 +1,85 @@ +diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c +index 765acc1..91d50a2 100644 +--- a/drivers/regulator/userspace-consumer.c ++++ b/drivers/regulator/userspace-consumer.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + struct userspace_consumer_data { + const char *name; +@@ -105,6 +106,41 @@ static const struct attribute_group attr_group = { + .attrs = attributes, + }; + ++static struct regulator_userspace_consumer_data *get_pdata_from_dt_node( ++ struct platform_device *pdev) ++{ ++ struct regulator_userspace_consumer_data *pdata; ++ struct device_node *np = pdev->dev.of_node; ++ struct property *prop; ++ const char *supply; ++ int num_supplies; ++ int count = 0; ++ ++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); ++ if (!pdata) ++ return ERR_PTR(-ENOMEM); ++ ++ pdata->name = of_get_property(np, "regulator-name", NULL); ++ pdata->init_on = of_property_read_bool(np, "regulator-boot-on"); ++ ++ num_supplies = of_property_count_strings(np, "regulator-supplies"); ++ if (num_supplies < 0) { ++ dev_err(&pdev->dev, ++ "could not parse property regulator-supplies\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ pdata->num_supplies = num_supplies; ++ pdata->supplies = devm_kzalloc(&pdev->dev, num_supplies * ++ sizeof(*pdata->supplies), GFP_KERNEL); ++ if (!pdata->supplies) ++ return ERR_PTR(-ENOMEM); ++ ++ of_property_for_each_string(np, "regulator-supplies", prop, supply) ++ pdata->supplies[count++].supply = supply; ++ ++ return pdata; ++} ++ + static int regulator_userspace_consumer_probe(struct platform_device *pdev) + { + struct regulator_userspace_consumer_data *pdata; +@@ -112,6 +148,11 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) + int ret; + + pdata = dev_get_platdata(&pdev->dev); ++ if (!pdata && pdev->dev.of_node) { ++ pdata = get_pdata_from_dt_node(pdev); ++ if (IS_ERR(pdata)) ++ return PTR_ERR(pdata); ++ } + if (!pdata) + return -EINVAL; + +@@ -171,11 +212,18 @@ static int regulator_userspace_consumer_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id regulator_userspace_consumer_of_match[] = { ++ { .compatible = "reg-userspace-consumer", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, regulator_userspace_consumer_of_match); ++ + static struct platform_driver regulator_userspace_consumer_driver = { + .probe = regulator_userspace_consumer_probe, + .remove = regulator_userspace_consumer_remove, + .driver = { + .name = "reg-userspace-consumer", ++ .of_match_table = regulator_userspace_consumer_of_match, + }, + }; +