forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/phy/motorola/phy-mapphone-mdm6600.c
....@@ -16,6 +16,7 @@
1616 #include <linux/gpio/consumer.h>
1717 #include <linux/of_platform.h>
1818 #include <linux/phy/phy.h>
19
+#include <linux/pinctrl/consumer.h>
1920
2021 #define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */
2122 #define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */
....@@ -121,11 +122,21 @@
121122 {
122123 struct phy_mdm6600 *ddata = phy_get_drvdata(x);
123124 struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];
125
+ int error;
124126
125127 if (!ddata->enabled)
126128 return -ENODEV;
127129
130
+ error = pinctrl_pm_select_default_state(ddata->dev);
131
+ if (error)
132
+ dev_warn(ddata->dev, "%s: error with default_state: %i\n",
133
+ __func__, error);
134
+
128135 gpiod_set_value_cansleep(enable_gpio, 1);
136
+
137
+ /* Allow aggressive PM for USB, it's only needed for n_gsm port */
138
+ if (pm_runtime_enabled(&x->dev))
139
+ phy_pm_runtime_put(x);
129140
130141 return 0;
131142 }
....@@ -134,11 +145,25 @@
134145 {
135146 struct phy_mdm6600 *ddata = phy_get_drvdata(x);
136147 struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];
148
+ int error;
137149
138150 if (!ddata->enabled)
139151 return -ENODEV;
140152
153
+ /* Paired with phy_pm_runtime_put() in phy_mdm6600_power_on() */
154
+ if (pm_runtime_enabled(&x->dev)) {
155
+ error = phy_pm_runtime_get(x);
156
+ if (error < 0 && error != -EINPROGRESS)
157
+ dev_warn(ddata->dev, "%s: phy_pm_runtime_get: %i\n",
158
+ __func__, error);
159
+ }
160
+
141161 gpiod_set_value_cansleep(enable_gpio, 0);
162
+
163
+ error = pinctrl_pm_select_sleep_state(ddata->dev);
164
+ if (error)
165
+ dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
166
+ __func__, error);
142167
143168 return 0;
144169 }
....@@ -153,52 +178,47 @@
153178 /**
154179 * phy_mdm6600_cmd() - send a command request to mdm6600
155180 * @ddata: device driver data
181
+ * @val: value of cmd to be set
156182 *
157183 * Configures the three command request GPIOs to the specified value.
158184 */
159185 static void phy_mdm6600_cmd(struct phy_mdm6600 *ddata, int val)
160186 {
161
- int values[PHY_MDM6600_NR_CMD_LINES];
162
- int i;
187
+ DECLARE_BITMAP(values, PHY_MDM6600_NR_CMD_LINES);
163188
164
- val &= (1 << PHY_MDM6600_NR_CMD_LINES) - 1;
165
- for (i = 0; i < PHY_MDM6600_NR_CMD_LINES; i++)
166
- values[i] = (val & BIT(i)) >> i;
189
+ values[0] = val;
167190
168191 gpiod_set_array_value_cansleep(PHY_MDM6600_NR_CMD_LINES,
169
- ddata->cmd_gpios->desc, values);
192
+ ddata->cmd_gpios->desc,
193
+ ddata->cmd_gpios->info, values);
170194 }
171195
172196 /**
173197 * phy_mdm6600_status() - read mdm6600 status lines
174
- * @ddata: device driver data
198
+ * @work: work structure
175199 */
176200 static void phy_mdm6600_status(struct work_struct *work)
177201 {
178202 struct phy_mdm6600 *ddata;
179203 struct device *dev;
180
- int values[PHY_MDM6600_NR_STATUS_LINES];
181
- int error, i, val = 0;
204
+ DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES);
205
+ int error;
182206
183207 ddata = container_of(work, struct phy_mdm6600, status_work.work);
184208 dev = ddata->dev;
185209
186210 error = gpiod_get_array_value_cansleep(PHY_MDM6600_NR_STATUS_LINES,
187211 ddata->status_gpios->desc,
212
+ ddata->status_gpios->info,
188213 values);
189214 if (error)
190215 return;
191216
192
- for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) {
193
- val |= values[i] << i;
194
- dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n",
195
- __func__, i, values[i], val);
196
- }
197
- ddata->status = val;
217
+ ddata->status = values[0] & ((1 << PHY_MDM6600_NR_STATUS_LINES) - 1);
198218
199219 dev_info(dev, "modem status: %i %s\n",
200220 ddata->status,
201
- phy_mdm6600_status_name[ddata->status & 7]);
221
+ phy_mdm6600_status_name[ddata->status]);
202222 complete(&ddata->ack);
203223 }
204224
....@@ -551,28 +571,17 @@
551571 ddata->dev = &pdev->dev;
552572 platform_set_drvdata(pdev, ddata);
553573
574
+ /* Active state selected in phy_mdm6600_power_on() */
575
+ error = pinctrl_pm_select_sleep_state(ddata->dev);
576
+ if (error)
577
+ dev_warn(ddata->dev, "%s: error with sleep_state: %i\n",
578
+ __func__, error);
579
+
554580 error = phy_mdm6600_init_lines(ddata);
555581 if (error)
556582 return error;
557583
558584 phy_mdm6600_init_irq(ddata);
559
-
560
- ddata->generic_phy = devm_phy_create(ddata->dev, NULL, &gpio_usb_ops);
561
- if (IS_ERR(ddata->generic_phy)) {
562
- error = PTR_ERR(ddata->generic_phy);
563
- goto cleanup;
564
- }
565
-
566
- phy_set_drvdata(ddata->generic_phy, ddata);
567
-
568
- ddata->phy_provider =
569
- devm_of_phy_provider_register(ddata->dev,
570
- of_phy_simple_xlate);
571
- if (IS_ERR(ddata->phy_provider)) {
572
- error = PTR_ERR(ddata->phy_provider);
573
- goto cleanup;
574
- }
575
-
576585 schedule_delayed_work(&ddata->bootup_work, 0);
577586
578587 /*
....@@ -596,14 +605,32 @@
596605 if (error < 0) {
597606 dev_warn(ddata->dev, "failed to wake modem: %i\n", error);
598607 pm_runtime_put_noidle(ddata->dev);
608
+ goto cleanup;
599609 }
610
+
611
+ ddata->generic_phy = devm_phy_create(ddata->dev, NULL, &gpio_usb_ops);
612
+ if (IS_ERR(ddata->generic_phy)) {
613
+ error = PTR_ERR(ddata->generic_phy);
614
+ goto idle;
615
+ }
616
+
617
+ phy_set_drvdata(ddata->generic_phy, ddata);
618
+
619
+ ddata->phy_provider =
620
+ devm_of_phy_provider_register(ddata->dev,
621
+ of_phy_simple_xlate);
622
+ if (IS_ERR(ddata->phy_provider))
623
+ error = PTR_ERR(ddata->phy_provider);
624
+
625
+idle:
600626 pm_runtime_mark_last_busy(ddata->dev);
601627 pm_runtime_put_autosuspend(ddata->dev);
602628
603
- return 0;
604
-
605629 cleanup:
606
- phy_mdm6600_device_power_off(ddata);
630
+ if (error < 0)
631
+ phy_mdm6600_device_power_off(ddata);
632
+ pm_runtime_disable(ddata->dev);
633
+ pm_runtime_dont_use_autosuspend(ddata->dev);
607634 return error;
608635 }
609636